Skip to content

Commit

Permalink
Experimental type hint + JSDoc support.
Browse files Browse the repository at this point in the history
  • Loading branch information
PoneyClairDeLune committed Nov 3, 2024
1 parent cc58d04 commit 20631fe
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 3 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,9 @@
build
*.map
dist/*.js
dist/*.css
dist/*.css
dist/*.ts
dist/*.mts

!dist/*.mjs.map
!dist/*.d.mts
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ltgc/rochelle",
"version": "0.2.1",
"version": "0.2.2",
"exports": {
"./textEmit": "./dist/textEmit.mjs",
"./textRead": "./dist/textRead.mjs",
Expand Down
1 change: 1 addition & 0 deletions dist/textEmit.mjs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
"use strict";let w=["utf-8","utf-16","utf-16be"],g=class extends EventTarget{static SPLIT_UTF_8=0;static SPLIT_UTF_16_LE=1;static SPLIT_UTF_16_BE=2;#t;#e;constructor(d,l=0){if(super(),l?.constructor!=Number||l<0||l>=w.length)throw new TypeError("Invalid split mode");if(l)throw new Error("UTF-16LE/BE currently not implemented");if(!d||d?.constructor!=ReadableStream)throw new TypeError("Not a readable stream");this.#t=d;let o=d.getReader();this.#e=new TextDecoder(w[l],{fatal:!0});let h=!0,f=!0,e;(async()=>{for(o.closed.then(()=>{e&&(this.dispatchEvent(new MessageEvent("raw",{data:e})),e=void 0),this.dispatchEvent(new Event("close")),f=!1}).catch(s=>{e&&(this.dispatchEvent(new MessageEvent("raw",{data:e})),e=void 0),this.dispatchEvent(new ErrorEvent("error",{message:s.message,error:s})),this.dispatchEvent(new Event("close")),f=!1});h&&f;)try{let s=await o.read();if(h=!s.done,h){let t=s.value;if(this.dispatchEvent(new MessageEvent("chunk",{data:t})),t.constructor!=Uint8Array&&t.constructor!=Uint8ClampedArray)this.dispatchEvent(new MessageEvent("fail",{data:t}));else{let n=0,E=0,u=0,i=!1;for(let a=0;a<t.length;a++){switch(t[a]){case 10:{u==13?n++:(i=!0,E=a);break}case 13:{i=!0,E=a;break}default:i=!1}if(i){let r=t.subarray(n,E),c=r;e&&(c=new Uint8Array(e.length+r.length),c.set(e),c.set(r,e.length),e=void 0),this.dispatchEvent(new MessageEvent("raw",{data:c}));try{let v=this.#e.decode(c);this.dispatchEvent(new MessageEvent("text",{data:v}))}catch{this.dispatchEvent(new MessageEvent("fail",{data:c}))}n=a+1,i=!1}u=t[a]}if(!i)if(e){let a=t.subarray(n),r=new Uint8Array(e.length+a.length);r.set(e),r.set(a,e.length),e=r}else n<t.length&&(e=t.subarray(n))}}else e&&(this.dispatchEvent(new MessageEvent("raw",{data:e})),e=void 0),this.dispatchEvent(new Event("close"))}catch(s){e&&(this.dispatchEvent(new MessageEvent("raw",{data:e})),e=void 0),this.dispatchEvent(new ErrorEvent("error",{message:s.message,error:s})),this.dispatchEvent(new Event("close"))}})()}},p=g;export{p as default};
//# sourceMappingURL=textEmit.mjs.map
7 changes: 7 additions & 0 deletions dist/textEmit.mjs.map
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../src/textEmit/index.mjs"],
"sourcesContent": ["// Copyright 2024 (C) Lightingale Community\n// Licensed under GNU LGPL 3.0\n\n// Takes a stream, and emit decoded text\n\n// TextEmit is now deprecated, as it has the potential to overwhelm the stream consumer.\n\n\"use strict\";\n\nconst encodings = [\"utf-8\", \"utf-16\", \"utf-16be\"];\n\n/*\nontext: When a line of text is available, returns the decoded string\nonfail: When a line of text is available but decoding failed, returns the raw bytes\nonchunk: When a chunk is received, returns the raw bytes\nonraw: When a line of text is available, returns the raw bytes\nonclose\n*/\n\nlet TextEmitter = class extends EventTarget {\n\tstatic SPLIT_UTF_8 = 0;\n\tstatic SPLIT_UTF_16_LE = 1;\n\tstatic SPLIT_UTF_16_BE = 2;\n\t#stream;\n\t#decoder;\n\tconstructor(stream, splitMode = 0) {\n\t\tsuper();\n\t\tif (splitMode?.constructor != Number ||\n\t\t\tsplitMode < 0 ||\n\t\t\tsplitMode >= encodings.length) {\n\t\t\tthrow(new TypeError(\"Invalid split mode\"));\n\t\t};\n\t\tif (splitMode) {\n\t\t\tthrow(new Error(\"UTF-16LE/BE currently not implemented\"));\n\t\t};\n\t\tif (!stream || stream?.constructor != ReadableStream) {\n\t\t\tthrow(new TypeError(\"Not a readable stream\"));\n\t\t};\n\t\tthis.#stream = stream;\n\t\tlet reader = stream.getReader();\n\t\tthis.#decoder = new TextDecoder(encodings[splitMode], {fatal: true});\n\t\tlet streamAlive = true, notClosed = true;\n\t\tlet buffer;\n\t\t(async () => {\n\t\t\treader.closed.then(() => {\n\t\t\t\tif (buffer) {\n\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"raw\", {\n\t\t\t\t\t\t\"data\": buffer\n\t\t\t\t\t}));\n\t\t\t\t\tbuffer = undefined;\n\t\t\t\t};\n\t\t\t\tthis.dispatchEvent(new Event(\"close\"));\n\t\t\t\tnotClosed = false;\n\t\t\t}).catch((err) => {\n\t\t\t\tif (buffer) {\n\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"raw\", {\n\t\t\t\t\t\t\"data\": buffer\n\t\t\t\t\t}));\n\t\t\t\t\tbuffer = undefined;\n\t\t\t\t};\n\t\t\t\tthis.dispatchEvent(new ErrorEvent(\"error\", {\n\t\t\t\t\tmessage: err.message,\n\t\t\t\t\terror: err\n\t\t\t\t}));\n\t\t\t\tthis.dispatchEvent(new Event(\"close\"));\n\t\t\t\tnotClosed = false;\n\t\t\t});\n\t\t\twhile (streamAlive && notClosed) {\n\t\t\t\ttry {\n\t\t\t\t\tlet chunk = await reader.read();\n\t\t\t\t\tstreamAlive = !chunk.done;\n\t\t\t\t\tif (streamAlive) {\n\t\t\t\t\t\tlet byteArray = chunk.value;\n\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"chunk\", {\n\t\t\t\t\t\t\t\"data\": byteArray\n\t\t\t\t\t\t}));\n\t\t\t\t\t\tif (byteArray.constructor != Uint8Array &&\n\t\t\t\t\t\t\tbyteArray.constructor != Uint8ClampedArray) {\n\t\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"fail\", {\n\t\t\t\t\t\t\t\t\"data\": byteArray\n\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Splitter!\n\t\t\t\t\t\t\tlet startIdx = 0;\n\t\t\t\t\t\t\tlet endIdx = 0;\n\t\t\t\t\t\t\tlet lastChar = 0;\n\t\t\t\t\t\t\tlet isBroken = false;\n\t\t\t\t\t\t\tfor (let i = 0; i < byteArray.length; i ++) {\n\t\t\t\t\t\t\t\tswitch (byteArray[i]) {\n\t\t\t\t\t\t\t\t\tcase 10: {\n\t\t\t\t\t\t\t\t\t\tif (lastChar == 13) {\n\t\t\t\t\t\t\t\t\t\t\tstartIdx ++;\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tisBroken = true;\n\t\t\t\t\t\t\t\t\t\t\tendIdx = i;\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tcase 13: {\n\t\t\t\t\t\t\t\t\t\tisBroken = true;\n\t\t\t\t\t\t\t\t\t\tendIdx = i;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\t\t\t\tisBroken = false;\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tif (isBroken) {\n\t\t\t\t\t\t\t\t\tlet sliceBuffer = byteArray.subarray(startIdx, endIdx);\n\t\t\t\t\t\t\t\t\tlet commitBuffer = sliceBuffer;\n\t\t\t\t\t\t\t\t\tif (buffer) {\n\t\t\t\t\t\t\t\t\t\tcommitBuffer = new Uint8Array(buffer.length + sliceBuffer.length);\n\t\t\t\t\t\t\t\t\t\tcommitBuffer.set(buffer);\n\t\t\t\t\t\t\t\t\t\tcommitBuffer.set(sliceBuffer, buffer.length);\n\t\t\t\t\t\t\t\t\t\tbuffer = undefined;\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"raw\", {\n\t\t\t\t\t\t\t\t\t\t\"data\": commitBuffer\n\t\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tlet text = this.#decoder.decode(commitBuffer);\n\t\t\t\t\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"text\", {\n\t\t\t\t\t\t\t\t\t\t\t\"data\": text\n\t\t\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"fail\", {\n\t\t\t\t\t\t\t\t\t\t\t\"data\": commitBuffer\n\t\t\t\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\tstartIdx = i + 1;\n\t\t\t\t\t\t\t\t\tisBroken = false;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tlastChar = byteArray[i];\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tif (!isBroken) {\n\t\t\t\t\t\t\t\t// Commit unfinished text to buffer\n\t\t\t\t\t\t\t\tif (buffer) {\n\t\t\t\t\t\t\t\t\tlet sliceBuffer = byteArray.subarray(startIdx);\n\t\t\t\t\t\t\t\t\tlet commitBuffer = new Uint8Array(buffer.length + sliceBuffer.length);\n\t\t\t\t\t\t\t\t\tcommitBuffer.set(buffer);\n\t\t\t\t\t\t\t\t\tcommitBuffer.set(sliceBuffer, buffer.length);\n\t\t\t\t\t\t\t\t\tbuffer = commitBuffer;\n\t\t\t\t\t\t\t\t} else if (startIdx < byteArray.length) {\n\t\t\t\t\t\t\t\t\tbuffer = byteArray.subarray(startIdx);\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (buffer) {\n\t\t\t\t\t\t\t// Empty the buffer\n\t\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"raw\", {\n\t\t\t\t\t\t\t\t\"data\": buffer\n\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t\tbuffer = undefined;\n\t\t\t\t\t\t};\n\t\t\t\t\t\tthis.dispatchEvent(new Event(\"close\"));\n\t\t\t\t\t};\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (buffer) {\n\t\t\t\t\t\t// Empty the buffer\n\t\t\t\t\t\tthis.dispatchEvent(new MessageEvent(\"raw\", {\n\t\t\t\t\t\t\t\"data\": buffer\n\t\t\t\t\t\t}));\n\t\t\t\t\t\tbuffer = undefined;\n\t\t\t\t\t};\n\t\t\t\t\tthis.dispatchEvent(new ErrorEvent(\"error\", {\n\t\t\t\t\t\tmessage: err.message,\n\t\t\t\t\t\terror: err\n\t\t\t\t\t}));\n\t\t\t\t\tthis.dispatchEvent(new Event(\"close\"));\n\t\t\t\t};\n\t\t\t};\n\t\t})();\n\t};\n};\n\nexport default TextEmitter;\n"],
"mappings": "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",
"names": ["encodings", "TextEmitter", "#stream", "#decoder", "stream", "splitMode", "reader", "streamAlive", "notClosed", "buffer", "err", "chunk", "byteArray", "startIdx", "endIdx", "lastChar", "isBroken", "i", "sliceBuffer", "commitBuffer", "text", "textEmit_default"]
}
9 changes: 9 additions & 0 deletions dist/textRead.d.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2024 (C) Lightingale Community
// Licensed under GNU LGPL 3.0

"use strict";

export default class TextReader {
static lineRaw(stream: ReadableStream, splitMode: number = 0): ReadableStream<Uint8Array>;
static line(stream: ReadableStream, splitMode: number = 0, label: string): ReadableStream<string>;
};
1 change: 1 addition & 0 deletions dist/textRead.mjs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
"use strict";let y=["utf-8","utf-16","utf-16be"],c=(i,l)=>{i.unsent=!1,i.enqueue(l)},T=class{static SPLIT_UTF_8=0;static SPLIT_UTF_16_LE=1;static SPLIT_UTF_16_BE=2;static lineRaw(i,l=0){if(l?.constructor!=Number||l<0||l>=y.length)throw new TypeError("Invalid split mode");if(l)throw new Error("UTF-16LE/BE currently not implemented");if(!i||i?.constructor!=ReadableStream)throw new TypeError("Not a readable stream");let w=i.getReader(),a,d=!1,e=[],t=0,r=0,m=0;return new ReadableStream({pull:async f=>{for(f.unsent=!0;f.unsent;){if(!a||t>=a.length){t>r&&(e.push(a.subarray(r)),r=0);let{value:h,done:s}=await w.read();a=h,d=s,t=0}if(a){let h=a[t],s=!1;switch(h){case 10:{m==13?r++:s=!0;break}case 13:{s=!0;break}}if(s){if(e.length){e.push(a.subarray(r,t));let g=0;for(let u=0;u<e.length;u++)g+=e[u].length;let n=new Uint8Array(g),b=0;for(let u=0;u<e.length;u++)n.set(e[u],b),b+=e[u].length;c(f,n),e=[]}else c(f,a.subarray(r,t));r=t+1}m=h}if(d){if(r!=t&&e.push(a.subarray(r,t)),e.length){let h=0;for(let n=0;n<e.length;n++)h+=e[n].length;let s=new Uint8Array(h),g=0;for(let n=0;n<e.length;n++)s.set(e[n],g),g+=e[n].length;c(f,s)}f.unsent=!1,f.close()}t++}}},new ByteLengthQueuingStrategy({highWaterMark:256}))}static line(i,l=0,w){let a=this.lineRaw(i,l).getReader(),d=new TextDecoder(w||y[l]);return new ReadableStream({pull:async e=>{let{value:t,done:r}=await a.read();t&&e.enqueue(d.decode(t)),r&&e.close()}})}},L=T;export{L as default};
//# sourceMappingURL=textRead.mjs.map
Loading

0 comments on commit 20631fe

Please sign in to comment.