@alexgyver/serial 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,11 @@
5
5
  - Буферизация отправки
6
6
  - Буферизация приёма, разделение текста по разделителю
7
7
 
8
- > npm i @alexgyver/serial
8
+ [demo](https://gyverlibs.github.io/Serial.js/test/)
9
+
10
+ > **Browser**: https://gyverlibs.github.io/Serial.js/Serial.min.js
11
+
12
+ > **Node**: npm i @alexgyver/serial
9
13
 
10
14
  ## Дока
11
15
  ```js
@@ -13,6 +17,7 @@ constructor(params = {});
13
17
  config(params = {});
14
18
  // eol: /\r?\n/
15
19
  // baud: 115200
20
+ // auto_open: false
16
21
  // reconnect: 1000
17
22
 
18
23
  onbin(b);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexgyver/serial",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Web Serial API wrapper",
5
5
  "main": "./serial.js",
6
6
  "module": "./serial.js",
@@ -14,13 +14,14 @@
14
14
  "url": "git+https://github.com/GyverLibs/Serial.js.git"
15
15
  },
16
16
  "devDependencies": {
17
- "webpack": "^5.103.0",
17
+ "webpack": "^5.105.1",
18
18
  "webpack-cli": "^6.0.1",
19
- "webpack-dev-server": "^5.2.2",
20
- "html-webpack-plugin": "^5.6.5"
19
+ "webpack-dev-server": "^5.2.3",
20
+ "style-loader": "^4.0.0",
21
+ "css-loader": "^7.1.3"
21
22
  },
22
23
  "dependencies": {
23
- "@alexgyver/utils": "^1.2.3"
24
+ "@alexgyver/utils": "^1.2.4"
24
25
  },
25
26
  "author": "AlexGyver <alex@alexgyver.ru>",
26
27
  "license": "MIT"
package/serial.js CHANGED
@@ -23,6 +23,7 @@ export default class SerialJS {
23
23
  const def = {
24
24
  eol: /\r?\n/,
25
25
  baud: 115200,
26
+ auto_open: false,
26
27
  reconnect: 1000,
27
28
  };
28
29
  this.cfg = { ...def, ...params };
@@ -77,10 +78,14 @@ export default class SerialJS {
77
78
  this._error(e);
78
79
  }
79
80
  this.onselect(this.getName());
81
+ if (this.cfg.auto_open) this.open();
80
82
  return this.selected();
81
83
  }
82
84
 
83
85
  async open() {
86
+ const ports = await navigator.serial.getPorts();
87
+ if (!ports.length) return;
88
+
84
89
  if (this.cfg.reconnect) this.retry = true;
85
90
  await this._open();
86
91
  }
@@ -165,10 +170,10 @@ export default class SerialJS {
165
170
  async _send() {
166
171
  if (this._busy) return;
167
172
  this._busy = true;
168
- while (this._buffer.length) {
173
+ while (this._buffer.length && this.writer) {
169
174
  let d = this._buffer.shiftAll();
170
175
  try {
171
- if (this.writer) await this.writer.write(d);
176
+ await this.writer.write(d);
172
177
  } catch (e) { }
173
178
  }
174
179
  this._busy = false;
package/serial.min.js CHANGED
@@ -1 +1 @@
1
- const t=t=>new Promise(e=>setTimeout(e,t));class e{ontext=null;constructor(t=/\r?\n/,e=!1){this.eol=t,this.skip=e}reset(){this._buf=""}write(t){if(!this.ontext)return;if(!this.eol)return void this.ontext(t);this._buf+=t;let e=this._buf.split(this.eol);1!=e.length&&(e[e.length-1].length?this._buf=e.pop():(this._buf="",e.pop()),this.skip&&(e.shift(),this.skip=!1),e.forEach(t=>this.ontext(t)))}_buf=""}class s{constructor(){this.chunks=[],this.length=0}clear(){this.chunks=[]}push(t){return this.chunks.push(t),this.length+=t.length,!0}shift(t){t>this.length&&(t=this.length);const e=new Uint8Array(t);let s=0;for(;t>0;){const i=this.chunks[0];t>=i.length?(e.set(i,s),s+=i.length,t-=i.length,this.chunks.shift(),this.length-=i.length):(e.set(i.subarray(0,t),s),this.chunks[0]=i.subarray(t),this.length-=t,t=0)}return e}shiftAll(){return this.shift(this.length)}}class i{static State={Closed:"closed",Opening:"opening",Open:"open",Closing:"closing"};onbin=null;ontext=null;onopen(){}onclose(){}onchange(t){}onselect(t){}onerror(t){}constructor(t={}){this.cfg={eol:/\r?\n/,baud:115200,reconnect:1e3,...t},this._setLastPort().then(()=>this.onselect(this.getName())),this.splitter=new e(this.cfg.eol),this.splitter.ontext=t=>this.ontext(t)}config(t={}){this.cfg={...this.cfg,...t},this.splitter.eol=this.cfg.eol}static supported(){return"serial"in navigator}opened(){return this._state==i.State.Open}selected(){return!!this._port}getName(){if(!this._port)return null;switch(this._port.getInfo().usbProductId){case 21971:return"CH343";case 30084:return"CH340S";case 29986:case 29987:return"CH340";case 21778:case 21795:case 21892:return"CH341";case 1026:case 1027:case 1028:case 1029:case 24577:case 1538:case 24592:return"FT232";case 38144:case 258:case 1281:case 32937:case 6e4:case 60001:case 60003:return"CP210x"}return"Unknown"}async select(){try{await this.close(),this._port=null;let e=await navigator.serial.getPorts();for(let t of e)await t.forget();await t(50),await navigator.serial.requestPort(),await this._setLastPort()}catch(t){this._error(t)}return this.onselect(this.getName()),this.selected()}async open(){this.cfg.reconnect&&(this.retry=!0),await this._open()}async _open(){if(!this.opened()){this._change(i.State.Opening);try{for(await this._close(),await this._setLastPort(),await this._port.open({baudRate:this.cfg.baud}),this.writer=this._port.writable.getWriter(),this.reader=this._port.readable.getReader(),this._buffer.clear(),this._change(i.State.Open);this._state==i.State.Open;){const{value:t,done:e}=await this.reader.read();if(e)break;t&&(this.onbin&&this.onbin(t),this.ontext&&this.splitter.write(this._decoder.decode(t,{stream:!0})))}}catch(t){this._error(t),this._change(i.State.Closed),this.retry&&setTimeout(()=>this._open(),this.cfg.reconnect)}this.reader&&this.reader.releaseLock(),this.writer&&this.writer.releaseLock(),this.reader=null,this.writer=null;try{await this._port.close(),this._change(i.State.Closed)}catch(t){}}}async close(){this.retry=!1,await this._close()}async _close(){switch(this._state){case i.State.Closed:return;case i.State.Open:this.reader&&await this.reader.cancel(),this._change(i.State.Closing)}let e=0;for(;this._state==i.State.Closing;)if(await t(10),++e>200){this._error("Close timeout"),this._change(i.State.Closed);break}}async sendText(t){await this.sendBin((new TextEncoder).encode(t))}async sendBin(t){this._buffer.push(t),this._send()}_port=null;_state=i.State.Closed;_buffer=new s;_decoder=new TextDecoder;async _send(){if(!this._busy){for(this._busy=!0;this._buffer.length;){let t=this._buffer.shiftAll();try{this.writer&&await this.writer.write(t)}catch(t){}}this._busy=!1}}async _setLastPort(){let t=await navigator.serial.getPorts();this._port=t.length?t[0]:null}_error(t){this.onerror("[SerialJS] "+t)}_change(t){switch(this._state=t,this.onchange(t),t){case i.State.Open:this.onopen();break;case i.State.Closed:this.onclose()}}}export{i as default};
1
+ const t=t=>new Promise(e=>setTimeout(e,t));class e{ontext=null;constructor(t=/\r?\n/,e=!1){this.eol=t,this.skip=e}reset(){this._buf=""}write(t){if(!this.ontext)return;if(!this.eol)return void this.ontext(t);this._buf+=t;let e=this._buf.split(this.eol);1!=e.length&&(e[e.length-1].length?this._buf=e.pop():(this._buf="",e.pop()),this.skip&&(e.shift(),this.skip=!1),e.forEach(t=>this.ontext(t)))}_buf=""}class s{constructor(){this.chunks=[],this.length=0}clear(){this.chunks=[],this.length=0}push(t){return!(!t||0===t.length||(this.chunks.push(t),this.length+=t.length,0))}shift(t){if(!this.length||!t)return new Uint8Array(0);t>this.length&&(t=this.length);const e=new Uint8Array(t);let s=0;for(;s<t&&this.chunks.length>0;){const i=this.chunks[0];if(!i||0===i.length){this.chunks.shift();continue}const r=Math.min(i.length,t-s);e.set(i.subarray(0,r),s),s+=r,r===i.length?this.chunks.shift():this.chunks[0]=i.subarray(r),this.length-=r}return e}shiftAll(){return this.shift(this.length)}}class i{static State={Closed:"closed",Opening:"opening",Open:"open",Closing:"closing"};onbin=null;ontext=null;onopen(){}onclose(){}onchange(t){}onselect(t){}onerror(t){}constructor(t={}){this.cfg={eol:/\r?\n/,baud:115200,auto_open:!1,reconnect:1e3,...t},this._setLastPort().then(()=>this.onselect(this.getName())),this.splitter=new e(this.cfg.eol),this.splitter.ontext=t=>this.ontext(t)}config(t={}){this.cfg={...this.cfg,...t},this.splitter.eol=this.cfg.eol}static supported(){return"serial"in navigator}opened(){return this._state==i.State.Open}selected(){return!!this._port}getName(){if(!this._port)return null;switch(this._port.getInfo().usbProductId){case 21971:return"CH343";case 30084:return"CH340S";case 29986:case 29987:return"CH340";case 21778:case 21795:case 21892:return"CH341";case 1026:case 1027:case 1028:case 1029:case 24577:case 1538:case 24592:return"FT232";case 38144:case 258:case 1281:case 32937:case 6e4:case 60001:case 60003:return"CP210x"}return"Unknown"}async select(){try{await this.close(),this._port=null;let e=await navigator.serial.getPorts();for(let t of e)await t.forget();await t(50),await navigator.serial.requestPort(),await this._setLastPort()}catch(t){this._error(t)}return this.onselect(this.getName()),this.cfg.auto_open&&this.open(),this.selected()}async open(){this.cfg.reconnect&&(this.retry=!0),await this._open()}async _open(){if(!this.opened()){this._change(i.State.Opening);try{for(await this._close(),await this._setLastPort(),await this._port.open({baudRate:this.cfg.baud}),this.writer=this._port.writable.getWriter(),this.reader=this._port.readable.getReader(),this._buffer.clear(),this._change(i.State.Open);this._state==i.State.Open;){const{value:t,done:e}=await this.reader.read();if(e)break;t&&(this.onbin&&this.onbin(t),this.ontext&&this.splitter.write(this._decoder.decode(t,{stream:!0})))}}catch(t){this._error(t),this._change(i.State.Closed),this.retry&&setTimeout(()=>this._open(),this.cfg.reconnect)}this.reader&&this.reader.releaseLock(),this.writer&&this.writer.releaseLock(),this.reader=null,this.writer=null;try{await this._port.close(),this._change(i.State.Closed)}catch(t){}}}async close(){this.retry=!1,await this._close()}async _close(){switch(this._state){case i.State.Closed:return;case i.State.Open:this.reader&&await this.reader.cancel(),this._change(i.State.Closing)}let e=0;for(;this._state==i.State.Closing;)if(await t(10),++e>200){this._error("Close timeout"),this._change(i.State.Closed);break}}async sendText(t){await this.sendBin((new TextEncoder).encode(t))}async sendBin(t){this._buffer.push(t),this._send()}_port=null;_state=i.State.Closed;_buffer=new s;_decoder=new TextDecoder;async _send(){if(!this._busy){for(this._busy=!0;this._buffer.length&&this.writer;){let t=this._buffer.shiftAll();try{await this.writer.write(t)}catch(t){}}this._busy=!1}}async _setLastPort(){let t=await navigator.serial.getPorts();this._port=t.length?t[0]:null}_error(t){this.onerror("[SerialJS] "+t)}_change(t){switch(this._state=t,this.onchange(t),t){case i.State.Open:this.onopen();break;case i.State.Closed:this.onclose()}}}export{i as default};
package/test/index.html CHANGED
@@ -3,8 +3,7 @@
3
3
 
4
4
  <head>
5
5
  <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
7
- <script src="script.js" type="module" defer="defer"></script>
6
+ <script src="./script.js" type="module"></script>
8
7
  <title>Serial test</title>
9
8
  </head>
10
9
 
package/test/script.js CHANGED
@@ -1,4 +1,5 @@
1
- import SerialJS from "https://gyverlibs.github.io/Serial.js/serial.min.js";
1
+ import SerialJS from 'https://gyverlibs.github.io/Serial.js/Serial.min.js'
2
+ // import SerialJS from "../serial";
2
3
 
3
4
  let i = 0;
4
5
  let ser = new SerialJS();
@@ -1,39 +1,24 @@
1
1
  const path = require('path');
2
- const PACKAGE = require('./package.json');
3
- const HtmlWebpackPlugin = require('html-webpack-plugin');
4
2
 
5
3
  module.exports = {
6
- entry: {
7
- index: './test_dev/script.js',
8
- },
9
-
4
+ entry: './test/script.js',
10
5
  output: {
11
6
  filename: 'script.js',
12
- path: path.resolve(__dirname, 'dev'),
13
- clean: true,
7
+ path: path.resolve(__dirname, 'test'),
8
+ clean: false,
9
+ },
10
+ module: {
11
+ rules: [
12
+ {
13
+ test: /\.css$/,
14
+ use: ['style-loader', 'css-loader'],
15
+ }
16
+ ]
14
17
  },
15
-
16
- plugins: [
17
- new HtmlWebpackPlugin({
18
- template: `./test_dev/index.html`,
19
- filename: `index.html`,
20
- inject: true,
21
- minify: false,
22
- version: PACKAGE.version,
23
- title: PACKAGE.title,
24
- }),
25
- ],
26
-
27
18
  devServer: {
28
- watchFiles: ['test_dev/*.html'],
29
- static: path.resolve(__dirname, './dev'),
19
+ static: path.resolve(__dirname, 'test'),
30
20
  hot: true,
31
21
  open: true,
32
22
  },
33
-
34
- watchOptions: {
35
- poll: 1000,
36
- },
37
-
38
23
  mode: 'development',
39
24
  };
@@ -1,18 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
-
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
7
- <script src="script.js" type="module" defer="defer"></script>
8
- <title>Serial test</title>
9
- </head>
10
-
11
- <body>
12
- <button id="select_b">select</button>
13
- <button id="open_b">open</button>
14
- <button id="close_b">close</button>
15
- <button id="send_b">send</button>
16
- </body>
17
-
18
- </html>
@@ -1,31 +0,0 @@
1
- import SerialJS from "../serial";
2
-
3
- let i = 0;
4
- let ser = new SerialJS();
5
-
6
- // control
7
- select_b.onclick = () => ser.select();
8
- open_b.onclick = () => ser.open();
9
- close_b.onclick = () => ser.close();
10
- send_b.onclick = () => ser.sendText('Hello ' + i++);
11
-
12
- // read
13
- // ser.onbin = b => console.log(b);
14
- ser.ontext = t => console.log(t);
15
-
16
- // state
17
- // ser.onopen = () => {
18
- // console.log('Opened', ser.getName());
19
- // }
20
- // ser.onclose = () => {
21
- // console.log('Closed');
22
- // }
23
- ser.onchange = s => {
24
- console.log(s);
25
- }
26
- ser.onerror = e => {
27
- console.log(e);
28
- }
29
- ser.onselect = (port) => {
30
- console.log('select', port);
31
- }