@gjsify/buffer 0.0.4 → 0.1.0

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
@@ -1,7 +1,31 @@
1
1
  # @gjsify/buffer
2
2
 
3
- Node.js buffer module for Gjs
3
+ GJS implementation of the Node.js `buffer` module using Blob, File, atob, and btoa.
4
+
5
+ Part of the [gjsify](https://github.com/gjsify/gjsify) project — Node.js and Web APIs for GJS (GNOME JavaScript).
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @gjsify/buffer
11
+ # or
12
+ yarn add @gjsify/buffer
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { Buffer } from '@gjsify/buffer';
19
+
20
+ const buf = Buffer.from('hello world', 'utf-8');
21
+ console.log(buf.toString('base64'));
22
+ ```
4
23
 
5
24
  ## Inspirations and credits
25
+
6
26
  - https://deno.land/std/node/buffer.ts
7
27
  - https://github.com/feross/buffer
28
+
29
+ ## License
30
+
31
+ MIT
@@ -0,0 +1,66 @@
1
+ const _encoder = new TextEncoder();
2
+ class BlobPolyfill {
3
+ _parts;
4
+ size;
5
+ type;
6
+ constructor(parts, options) {
7
+ this._parts = parts || [];
8
+ this.type = options?.type || "";
9
+ this.size = this._parts.reduce((acc, part) => {
10
+ if (typeof part === "string") return acc + _encoder.encode(part).byteLength;
11
+ if (part instanceof ArrayBuffer) return acc + part.byteLength;
12
+ if (ArrayBuffer.isView(part)) return acc + part.byteLength;
13
+ if (part && typeof part.size === "number") return acc + part.size;
14
+ return acc;
15
+ }, 0);
16
+ }
17
+ async bytes() {
18
+ const ab = await this.arrayBuffer();
19
+ return new Uint8Array(ab);
20
+ }
21
+ async text() {
22
+ return new TextDecoder().decode(await this.arrayBuffer());
23
+ }
24
+ async arrayBuffer() {
25
+ const chunks = [];
26
+ for (const part of this._parts) {
27
+ if (typeof part === "string") chunks.push(_encoder.encode(part));
28
+ else if (part instanceof ArrayBuffer) chunks.push(new Uint8Array(part));
29
+ else if (ArrayBuffer.isView(part)) chunks.push(new Uint8Array(part.buffer, part.byteOffset, part.byteLength));
30
+ else if (part && typeof part.arrayBuffer === "function") {
31
+ const ab = await part.arrayBuffer();
32
+ chunks.push(new Uint8Array(ab));
33
+ }
34
+ }
35
+ const total = chunks.reduce((a, c) => a + c.byteLength, 0);
36
+ const result = new Uint8Array(total);
37
+ let offset = 0;
38
+ for (const c of chunks) {
39
+ result.set(c, offset);
40
+ offset += c.byteLength;
41
+ }
42
+ return result.buffer;
43
+ }
44
+ slice(start, end, type) {
45
+ return new BlobPolyfill([], { type });
46
+ }
47
+ stream() {
48
+ throw new Error("Blob.stream() not implemented");
49
+ }
50
+ }
51
+ class FilePolyfill extends BlobPolyfill {
52
+ name;
53
+ lastModified;
54
+ webkitRelativePath = "";
55
+ constructor(parts, name, options) {
56
+ super(parts, options);
57
+ this.name = name;
58
+ this.lastModified = options?.lastModified ?? Date.now();
59
+ }
60
+ }
61
+ const Blob = globalThis.Blob ?? BlobPolyfill;
62
+ const File = globalThis.File ?? FilePolyfill;
63
+ export {
64
+ Blob,
65
+ File
66
+ };