Compare commits

...

7 commits

24 changed files with 2145 additions and 3348 deletions

View file

@ -19,8 +19,6 @@
--dark-hl-8: #6A9955; --dark-hl-8: #6A9955;
--light-hl-9: #267F99; --light-hl-9: #267F99;
--dark-hl-9: #4EC9B0; --dark-hl-9: #4EC9B0;
--light-hl-10: #000000;
--dark-hl-10: #C8C8C8;
--light-code-background: #FFFFFF; --light-code-background: #FFFFFF;
--dark-code-background: #1E1E1E; --dark-code-background: #1E1E1E;
} }
@ -36,7 +34,6 @@
--hl-7: var(--light-hl-7); --hl-7: var(--light-hl-7);
--hl-8: var(--light-hl-8); --hl-8: var(--light-hl-8);
--hl-9: var(--light-hl-9); --hl-9: var(--light-hl-9);
--hl-10: var(--light-hl-10);
--code-background: var(--light-code-background); --code-background: var(--light-code-background);
} } } }
@ -51,11 +48,10 @@
--hl-7: var(--dark-hl-7); --hl-7: var(--dark-hl-7);
--hl-8: var(--dark-hl-8); --hl-8: var(--dark-hl-8);
--hl-9: var(--dark-hl-9); --hl-9: var(--dark-hl-9);
--hl-10: var(--dark-hl-10);
--code-background: var(--dark-code-background); --code-background: var(--dark-code-background);
} } } }
body.light { :root[data-theme='light'] {
--hl-0: var(--light-hl-0); --hl-0: var(--light-hl-0);
--hl-1: var(--light-hl-1); --hl-1: var(--light-hl-1);
--hl-2: var(--light-hl-2); --hl-2: var(--light-hl-2);
@ -66,11 +62,10 @@ body.light {
--hl-7: var(--light-hl-7); --hl-7: var(--light-hl-7);
--hl-8: var(--light-hl-8); --hl-8: var(--light-hl-8);
--hl-9: var(--light-hl-9); --hl-9: var(--light-hl-9);
--hl-10: var(--light-hl-10);
--code-background: var(--light-code-background); --code-background: var(--light-code-background);
} }
body.dark { :root[data-theme='dark'] {
--hl-0: var(--dark-hl-0); --hl-0: var(--dark-hl-0);
--hl-1: var(--dark-hl-1); --hl-1: var(--dark-hl-1);
--hl-2: var(--dark-hl-2); --hl-2: var(--dark-hl-2);
@ -81,7 +76,6 @@ body.dark {
--hl-7: var(--dark-hl-7); --hl-7: var(--dark-hl-7);
--hl-8: var(--dark-hl-8); --hl-8: var(--dark-hl-8);
--hl-9: var(--dark-hl-9); --hl-9: var(--dark-hl-9);
--hl-10: var(--dark-hl-10);
--code-background: var(--dark-code-background); --code-background: var(--dark-code-background);
} }
@ -95,5 +89,4 @@ body.dark {
.hl-7 { color: var(--hl-7); } .hl-7 { color: var(--hl-7); }
.hl-8 { color: var(--hl-8); } .hl-8 { color: var(--hl-8); }
.hl-9 { color: var(--hl-9); } .hl-9 { color: var(--hl-9); }
.hl-10 { color: var(--hl-10); }
pre, code { background: var(--code-background); } pre, code { background: var(--code-background); }

File diff suppressed because it is too large Load diff

18
docs/assets/icons.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

1
docs/assets/icons.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAAA43QMQvCMBAF4P9yc7AoIpLNQaRDaXdxONJIgzGNuasI0v8uxUFC2uD83vs47vwG1i8GCaemrA9KaSIQ4JE7kKAsEmkqftmq47sFATfjWpDrzX4UkdD0gef3U/LPukK/DFToc0bpnmhN+z31GEIfUirt5MTa64BseregxXlOCvoxaOK5N18HpyaDiqQUi7vtePkAPGD3pbIBAAA="

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,17 +1,11 @@
<!DOCTYPE html><html class="default"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>node-web-gpio</title><meta name="description" content="Documentation for node-web-gpio"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script async src="assets/search.js" id="search-script"></script></head><body><script>document.body.classList.add(localStorage.getItem("tsd-theme") || "os")</script><header><div class="tsd-page-toolbar"><div class="container"><div class="table-wrap"><div class="table-cell" id="tsd-search" data-base="."><div class="field"><label for="tsd-search-field" class="tsd-widget search no-caption">Search</label><input type="text" id="tsd-search-field"/></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">node-web-gpio</a></div><div class="table-cell" id="tsd-widgets"><div id="tsd-filter"><a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a><div class="tsd-filter-group"><div class="tsd-select" id="tsd-filter-visibility"><span class="tsd-select-label">All</span><ul class="tsd-select-list"><li data-value="public">Public</li><li data-value="protected">Public/Protected</li><li data-value="private" class="selected">All</li></ul></div> <input type="checkbox" id="tsd-filter-inherited" checked/><label class="tsd-widget" for="tsd-filter-inherited">Inherited</label><input type="checkbox" id="tsd-filter-externals" checked/><label class="tsd-widget" for="tsd-filter-externals">Externals</label></div></div><a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a></div></div></div></div><div class="tsd-page-title"><div class="container"><h1>node-web-gpio</h1></div></div></header><div class="container container-main"><div class="row"><div class="col-8 col-content"><div class="tsd-panel tsd-typography"> <!DOCTYPE html><html class="default" lang="en"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>node-web-gpio</title><meta name="description" content="Documentation for node-web-gpio"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="assets/style.css"/><link rel="stylesheet" href="assets/highlight.css"/><script defer src="assets/main.js"></script><script async src="assets/icons.js" id="tsd-icons-script"></script><script async src="assets/search.js" id="tsd-search-script"></script><script async src="assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search" data-base="."><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="index.html" class="title">node-web-gpio</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><h2>node-web-gpio</h2></div><div class="tsd-panel tsd-typography"><a id="md:node-web-gpio" class="tsd-anchor"></a><h1 class="tsd-anchor-link">node-web-gpio<a href="#md:node-web-gpio" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h1><p>GPIO access with Node.js</p>
<a href="#node-web-gpio" id="node-web-gpio" style="color: inherit; text-decoration: none;"> <a id="md:usage" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Usage<a href="#md:usage" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><pre><code class="js"><span class="hl-0">const</span><span class="hl-1"> { </span><span class="hl-2">requestGPIOAccess</span><span class="hl-1"> } = </span><span class="hl-3">require</span><span class="hl-1">(</span><span class="hl-4">&quot;node-web-gpio&quot;</span><span class="hl-1">);</span><br/><span class="hl-0">const</span><span class="hl-1"> { </span><span class="hl-2">promisify</span><span class="hl-1"> } = </span><span class="hl-3">require</span><span class="hl-1">(</span><span class="hl-4">&quot;util&quot;</span><span class="hl-1">);</span><br/><span class="hl-0">const</span><span class="hl-1"> </span><span class="hl-2">sleep</span><span class="hl-1"> = </span><span class="hl-3">promisify</span><span class="hl-1">(</span><span class="hl-5">setTimeout</span><span class="hl-1">);</span><br/><br/><span class="hl-0">async</span><span class="hl-1"> </span><span class="hl-0">function</span><span class="hl-1"> </span><span class="hl-3">main</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">const</span><span class="hl-1"> </span><span class="hl-2">gpioAccess</span><span class="hl-1"> = </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-3">requestGPIOAccess</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-0">const</span><span class="hl-1"> </span><span class="hl-2">port</span><span class="hl-1"> = </span><span class="hl-5">gpioAccess</span><span class="hl-1">.</span><span class="hl-5">ports</span><span class="hl-1">.</span><span class="hl-3">get</span><span class="hl-1">(</span><span class="hl-7">26</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-5">port</span><span class="hl-1">.</span><span class="hl-3">export</span><span class="hl-1">(</span><span class="hl-4">&quot;out&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-6">for</span><span class="hl-1"> (;;) {</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-5">port</span><span class="hl-1">.</span><span class="hl-3">write</span><span class="hl-1">(</span><span class="hl-7">1</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-3">sleep</span><span class="hl-1">(</span><span class="hl-7">1000</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-5">port</span><span class="hl-1">.</span><span class="hl-3">write</span><span class="hl-1">(</span><span class="hl-7">0</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-3">sleep</span><span class="hl-1">(</span><span class="hl-7">1000</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">main</span><span class="hl-1">();</span>
<h1>node-web-gpio</h1> </code><button type="button">Copy</button></pre>
</a>
<p>GPIO access with Node.js</p>
<a href="#usage" id="usage" style="color: inherit; text-decoration: none;"> <a id="md:document" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Document<a href="#md:document" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
<h2>Usage</h2> <li><a href="http://chirimen.org/node-web-gpio/" target="_blank" class="external">TSDoc</a></li>
</a> </ul>
<pre><code class="language-js"><span class="hl-0">const</span><span class="hl-1"> { </span><span class="hl-2">requestGPIOAccess</span><span class="hl-1"> } = </span><span class="hl-3">require</span><span class="hl-1">(</span><span class="hl-4">&quot;node-web-gpio&quot;</span><span class="hl-1">);</span><br/><span class="hl-0">const</span><span class="hl-1"> { </span><span class="hl-2">promisify</span><span class="hl-1"> } = </span><span class="hl-3">require</span><span class="hl-1">(</span><span class="hl-4">&quot;util&quot;</span><span class="hl-1">);</span><br/><span class="hl-0">const</span><span class="hl-1"> </span><span class="hl-2">sleep</span><span class="hl-1"> = </span><span class="hl-3">promisify</span><span class="hl-1">(</span><span class="hl-5">setTimeout</span><span class="hl-1">);</span><br/><br/><span class="hl-0">async</span><span class="hl-1"> </span><span class="hl-0">function</span><span class="hl-1"> </span><span class="hl-3">main</span><span class="hl-1">() {</span><br/><span class="hl-1"> </span><span class="hl-0">const</span><span class="hl-1"> </span><span class="hl-2">gpioAccess</span><span class="hl-1"> = </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-3">requestGPIOAccess</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-0">const</span><span class="hl-1"> </span><span class="hl-2">port</span><span class="hl-1"> = </span><span class="hl-5">gpioAccess</span><span class="hl-1">.</span><span class="hl-5">ports</span><span class="hl-1">.</span><span class="hl-3">get</span><span class="hl-1">(</span><span class="hl-7">26</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-5">port</span><span class="hl-1">.</span><span class="hl-3">export</span><span class="hl-1">(</span><span class="hl-4">&quot;out&quot;</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-6">for</span><span class="hl-1"> (;;) {</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-5">port</span><span class="hl-1">.</span><span class="hl-3">write</span><span class="hl-1">(</span><span class="hl-7">1</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-3">sleep</span><span class="hl-1">(</span><span class="hl-7">1000</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-5">port</span><span class="hl-1">.</span><span class="hl-3">write</span><span class="hl-1">(</span><span class="hl-7">0</span><span class="hl-1">);</span><br/><span class="hl-1"> </span><span class="hl-6">await</span><span class="hl-1"> </span><span class="hl-3">sleep</span><span class="hl-1">(</span><span class="hl-7">1000</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-3">main</span><span class="hl-1">();</span> <a id="md:reference" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Reference<a href="#md:reference" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="assets/icons.svg#icon-anchor"></use></svg></a></h2><ul>
</code></pre> <li><a href="http://browserobo.github.io/WebGPIO" target="_blank" class="external">Web GPIO API for W3C Draft</a></li>
</ul>
<a href="#document" id="document" style="color: inherit; text-decoration: none;"> </div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#md:node-web-gpio"><span>node-<wbr/>web-<wbr/>gpio</span></a><ul><li><a href="#md:usage"><span>Usage</span></a></li><li><a href="#md:document"><span>Document</span></a></li><li><a href="#md:reference"><span>Reference</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="modules.html" class="current"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="assets/icons.svg#icon-1"></use></svg><span>node-web-gpio</span></a><ul class="tsd-small-nested-navigation" id="tsd-nav-container" data-base="."><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
<h2>Document</h2>
</a>
<p><a href="http://browserobo.github.io/WebGPIO">Web GPIO API</a></p>
</div></div><div class="col-4 col-menu menu-sticky-wrap menu-highlight"><nav class="tsd-navigation primary"><ul><li class="current"><a href="modules.html">Exports</a></li></ul></nav><nav class="tsd-navigation secondary menu-sticky"><ul><li class="tsd-kind-class"><a href="classes/GPIOAccess.html" class="tsd-kind-icon">GPIOAccess</a></li><li class="tsd-kind-class"><a href="classes/GPIOPort.html" class="tsd-kind-icon">GPIOPort</a></li><li class="tsd-kind-class"><a href="classes/GPIOPortMap.html" class="tsd-kind-icon">GPIOPort<wbr/>Map</a></li><li class="tsd-kind-class"><a href="classes/InvalidAccessError.html" class="tsd-kind-icon">Invalid<wbr/>Access<wbr/>Error</a></li><li class="tsd-kind-class"><a href="classes/OperationError.html" class="tsd-kind-icon">Operation<wbr/>Error</a></li><li class="tsd-kind-function"><a href="modules.html#requestGPIOAccess" class="tsd-kind-icon">requestGPIOAccess</a></li></ul></nav></div></div></div><footer class="with-border-bottom"><div class="container"><h2>Legend</h2><div class="tsd-legend-group"><ul class="tsd-legend"><li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li><li class="tsd-kind-property tsd-parent-kind-class"><span class="tsd-kind-icon">Property</span></li><li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-constructor tsd-parent-kind-class tsd-is-inherited"><span class="tsd-kind-icon">Inherited constructor</span></li></ul><ul class="tsd-legend"><li class="tsd-kind-property tsd-parent-kind-class tsd-is-private"><span class="tsd-kind-icon">Private property</span></li></ul></div><h2>Settings</h2><p>Theme <select id="theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></p></div></footer><div class="container tsd-generator"><p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></div><div class="overlay"></div><script src="assets/main.js"></script></body></html>

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,7 @@
import { EventEmitter } from 'events'; import { EventEmitter } from 'node:events';
import { promises as fs } from 'fs'; import { promises as fs } from 'node:fs';
import * as path from 'path'; import * as os from 'node:os';
import * as path from 'node:path';
/** /**
* Interval of file system polling, in milliseconds. * Interval of file system polling, in milliseconds.
@ -31,9 +32,19 @@ const Uint16Max = 65535;
function parseUint16(parseString: string) { function parseUint16(parseString: string) {
const n = Number.parseInt(parseString, 10); const n = Number.parseInt(parseString, 10);
if (0 <= n && n <= Uint16Max) return n; if (0 <= n && n <= Uint16Max) return n;
// biome-ignore lint/style/noUselessElse:
else throw new RangeError(`Must be between 0 and ${Uint16Max}.`); else throw new RangeError(`Must be between 0 and ${Uint16Max}.`);
} }
/**
* GPIO0
* @see {@link https://github.com/raspberrypi/linux/issues/6037}
*/
const GpioOffset =
process.platform === 'linux' && 6.6 <= Number(os.release().match(/\d+\.\d+/))
? 512
: 0;
/** ポート番号 */ /** ポート番号 */
type PortNumber = number; type PortNumber = number;
/** ポート名 */ /** ポート名 */
@ -62,6 +73,7 @@ interface GPIOChangeEvent {
*/ */
interface GPIOChangeEventHandler { interface GPIOChangeEventHandler {
/** イベント */ /** イベント */
// biome-ignore lint/style/useShorthandFunctionType:
(event: GPIOChangeEvent): void; (event: GPIOChangeEvent): void;
} }
@ -82,10 +94,11 @@ export class GPIOAccess extends EventEmitter {
super(); super();
this._ports = ports == null ? new GPIOPortMap() : ports; this._ports = ports == null ? new GPIOPortMap() : ports;
// biome-ignore lint/complexity/noForEach:
this._ports.forEach((port) => this._ports.forEach((port) =>
port.on('change', (event) => { port.on('change', (event) => {
this.emit('change', event); this.emit('change', event);
}) }),
); );
this.on('change', (event: GPIOChangeEvent): void => { this.on('change', (event: GPIOChangeEvent): void => {
@ -109,8 +122,8 @@ export class GPIOAccess extends EventEmitter {
async unexportAll(): Promise<void> { async unexportAll(): Promise<void> {
await Promise.all( await Promise.all(
[...this.ports.values()].map((port) => [...this.ports.values()].map((port) =>
port.exported ? port.unexport() : undefined port.exported ? port.unexport() : undefined,
) ),
); );
} }
} }
@ -148,7 +161,7 @@ export class GPIOPort extends EventEmitter {
constructor(portNumber: PortNumber) { constructor(portNumber: PortNumber) {
super(); super();
this._portNumber = parseUint16(portNumber.toString()); this._portNumber = parseUint16(portNumber.toString()) + GpioOffset;
this._pollingInterval = PollingInterval; this._pollingInterval = PollingInterval;
this._direction = new OperationError('Unknown direction.'); this._direction = new OperationError('Unknown direction.');
this._exported = new OperationError('Unknown export.'); this._exported = new OperationError('Unknown export.');
@ -224,22 +237,23 @@ export class GPIOPort extends EventEmitter {
if (!this.exported) { if (!this.exported) {
await fs.writeFile( await fs.writeFile(
path.join(SysfsGPIOPath, 'export'), path.join(SysfsGPIOPath, 'export'),
String(this.portNumber) String(this.portNumber),
); );
} }
await fs.writeFile( await fs.writeFile(
path.join(SysfsGPIOPath, this.portName, 'direction'), path.join(SysfsGPIOPath, this.portName, 'direction'),
direction direction,
); );
if (direction === 'in') { if (direction === 'in') {
this._timeout = setInterval( this._timeout = setInterval(
// eslint-disable-next-line // eslint-disable-next-line
this.read.bind(this), this.read.bind(this),
this._pollingInterval this._pollingInterval,
); );
} }
// biome-ignore lint/suspicious/noExplicitAny:
} catch (error: any) { } catch (error: any) {
if (this._exportRetry == 0) { if (this._exportRetry === 0) {
await sleep(100); await sleep(100);
console.warn('May be the first time port access. Retry..'); console.warn('May be the first time port access. Retry..');
++this._exportRetry; ++this._exportRetry;
@ -264,8 +278,9 @@ export class GPIOPort extends EventEmitter {
try { try {
await fs.writeFile( await fs.writeFile(
path.join(SysfsGPIOPath, 'unexport'), path.join(SysfsGPIOPath, 'unexport'),
String(this.portNumber) String(this.portNumber),
); );
// biome-ignore lint/suspicious/noExplicitAny:
} catch (error: any) { } catch (error: any) {
throw new OperationError(error); throw new OperationError(error);
} }
@ -280,13 +295,13 @@ export class GPIOPort extends EventEmitter {
async read(): Promise<GPIOValue> { async read(): Promise<GPIOValue> {
if (!(this.exported && this.direction === 'in')) { if (!(this.exported && this.direction === 'in')) {
throw new InvalidAccessError( throw new InvalidAccessError(
`The exported must be true and value of direction must be "in".` `The exported must be true and value of direction must be "in".`,
); );
} }
try { try {
const buffer = await fs.readFile( const buffer = await fs.readFile(
path.join(SysfsGPIOPath, this.portName, 'value') path.join(SysfsGPIOPath, this.portName, 'value'),
); );
const value = parseUint16(buffer.toString()) as GPIOValue; const value = parseUint16(buffer.toString()) as GPIOValue;
@ -297,6 +312,7 @@ export class GPIOPort extends EventEmitter {
} }
return value; return value;
// biome-ignore lint/suspicious/noExplicitAny:
} catch (error: any) { } catch (error: any) {
throw new OperationError(error); throw new OperationError(error);
} }
@ -309,15 +325,16 @@ export class GPIOPort extends EventEmitter {
async write(value: GPIOValue): Promise<void> { async write(value: GPIOValue): Promise<void> {
if (!(this.exported && this.direction === 'out')) { if (!(this.exported && this.direction === 'out')) {
throw new InvalidAccessError( throw new InvalidAccessError(
`The exported must be true and value of direction must be "out".` `The exported must be true and value of direction must be "out".`,
); );
} }
try { try {
await fs.writeFile( await fs.writeFile(
path.join(SysfsGPIOPath, this.portName, 'value'), path.join(SysfsGPIOPath, this.portName, 'value'),
parseUint16(value.toString()).toString() parseUint16(value.toString()).toString(),
); );
// biome-ignore lint/suspicious/noExplicitAny:
} catch (error: any) { } catch (error: any) {
throw new OperationError(error); throw new OperationError(error);
} }
@ -359,7 +376,7 @@ export async function requestGPIOAccess(): Promise<GPIOAccess> {
[...Array(GPIOPortMapSizeMax).keys()].map((portNumber) => [ [...Array(GPIOPortMapSizeMax).keys()].map((portNumber) => [
portNumber, portNumber,
new GPIOPort(portNumber), new GPIOPort(portNumber),
]) ]),
); );
return new GPIOAccess(ports); return new GPIOAccess(ports);

View file

@ -1,6 +1,6 @@
{ {
"name": "node-web-gpio", "name": "node-web-gpio",
"version": "1.0.33", "version": "1.1.1",
"description": "GPIO access with Node.js", "description": "GPIO access with Node.js",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
@ -14,19 +14,17 @@
"author": "Kohei Watanabe <kou029w@gmail.com>", "author": "Kohei Watanabe <kou029w@gmail.com>",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node": "^20.0.0", "@biomejs/biome": "^1.9.3",
"@typescript-eslint/eslint-plugin": "^8.0.0", "@types/node": "^22.7.4",
"@typescript-eslint/parser": "^8.0.0", "husky": "^9.1.6",
"eslint": "^9.0.0", "lint-staged": "^15.2.10",
"husky": "^9.0.0", "prettier": "^3.3.3",
"lint-staged": "^15.0.0", "typedoc": "^0.26.7",
"prettier": "^3.0.0", "typescript": "^5.6.2"
"typedoc": "^0.26.0",
"typescript": "^5.0.0"
}, },
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"lint": "eslint index.ts", "lint": "biome lint index.ts",
"prepare": "husky install && rm -rf dist && npm run build", "prepare": "husky install && rm -rf dist && npm run build",
"precommit": "lint-staged", "precommit": "lint-staged",
"docs": "npm run remove:docs && npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./ README.md", "docs": "npm run remove:docs && npm run typedoc -- --options typedoc.json --exclude '**/*.spec.ts' ./ README.md",
@ -46,5 +44,6 @@
"robotics", "robotics",
"robots", "robots",
"rpi" "rpi"
] ],
"packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447"
} }

View file

@ -1,4 +1,4 @@
{ {
"extends": ["config:base", ":preserveSemverRanges"], "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"automerge": true "extends": ["config:best-practices", ":automergeAll", "schedule:monthly"]
} }

1419
yarn.lock

File diff suppressed because it is too large Load diff