sabcom 0.0.25 → 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/build/index.cjs CHANGED
@@ -46,7 +46,6 @@ _export(exports, {
46
46
  return writeSync;
47
47
  }
48
48
  });
49
- const _nodev8 = require("node:v8");
50
49
  const SEMAPHORE = 0;
51
50
  var Semaphore = /*#__PURE__*/ function(Semaphore) {
52
51
  Semaphore[Semaphore["READY"] = 0] = "READY";
@@ -68,9 +67,8 @@ var Header = /*#__PURE__*/ function(Header) {
68
67
  const HEADER_VALUES = 1 + Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;
69
68
  const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;
70
69
  function* writeGenerator(data, buffer, { timeout = 5000 } = {}) {
71
- const serialized = (0, _nodev8.serialize)(data);
72
70
  const chunkSize = buffer.byteLength - HEADER_SIZE;
73
- const totalSize = serialized.length;
71
+ const totalSize = data.length;
74
72
  const totalChunks = Math.ceil(totalSize / chunkSize);
75
73
  const header = new Int32Array(buffer);
76
74
  header[1] = totalSize;
@@ -84,15 +82,15 @@ function* writeGenerator(data, buffer, { timeout = 5000 } = {}) {
84
82
  value: 1,
85
83
  timeout
86
84
  };
87
- if (handshakeResult === "timed-out") {
88
- throw new Error("Reader handshake timeout");
85
+ if (handshakeResult === 'timed-out') {
86
+ throw new Error('Reader handshake timeout');
89
87
  }
90
88
  const payload = new Uint8Array(buffer, HEADER_SIZE);
91
89
  for(let i = 0; i < totalChunks; i++){
92
90
  const start = i * chunkSize;
93
91
  const end = Math.min(start + chunkSize, totalSize);
94
92
  const size = end - start;
95
- payload.set(serialized.subarray(start, end), 0);
93
+ payload.set(data.subarray(start, end), 0);
96
94
  header[1] = i;
97
95
  header[2] = start;
98
96
  header[3] = size;
@@ -104,7 +102,7 @@ function* writeGenerator(data, buffer, { timeout = 5000 } = {}) {
104
102
  value: 2,
105
103
  timeout
106
104
  };
107
- if (chunkResult === "timed-out") {
105
+ if (chunkResult === 'timed-out') {
108
106
  throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);
109
107
  }
110
108
  }
@@ -120,11 +118,11 @@ function* readGenerator(buffer, { timeout = 5000 } = {}) {
120
118
  value: 0,
121
119
  timeout
122
120
  };
123
- if (handshakeResult === "timed-out") {
124
- throw new Error("Handshake timeout");
121
+ if (handshakeResult === 'timed-out') {
122
+ throw new Error('Handshake timeout');
125
123
  }
126
124
  if (header[SEMAPHORE] !== 1) {
127
- throw new Error("Invalid handshake state");
125
+ throw new Error('Invalid handshake state');
128
126
  }
129
127
  const totalSize = header[1];
130
128
  const totalChunks = header[2];
@@ -139,7 +137,7 @@ function* readGenerator(buffer, { timeout = 5000 } = {}) {
139
137
  value: 0,
140
138
  timeout
141
139
  };
142
- if (chunkResult === "timed-out") {
140
+ if (chunkResult === 'timed-out') {
143
141
  throw new Error(`Writer timeout waiting for chunk ${i}`);
144
142
  }
145
143
  if (header[SEMAPHORE] !== 2) {
@@ -155,7 +153,7 @@ function* readGenerator(buffer, { timeout = 5000 } = {}) {
155
153
  Atomics.store(header, SEMAPHORE, 0);
156
154
  Atomics.notify(header, SEMAPHORE);
157
155
  }
158
- return (0, _nodev8.deserialize)(data);
156
+ return data;
159
157
  }
160
158
  const writeSync = (data, buffer, options)=>{
161
159
  const gen = writeGenerator(data, buffer, options);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { serialize, deserialize } from \"node:v8\";\n\nexport const SEMAPHORE = 0;\n\nexport enum Semaphore {\n READY,\n HANDSHAKE,\n PAYLOAD,\n}\n\nexport enum Handshake {\n TOTAL_SIZE = 1,\n TOTAL_CHUNKS,\n}\n\nexport enum Header {\n CHUNK_INDEX = 1,\n CHUNK_OFFSET,\n CHUNK_SIZE,\n}\n\nexport const HEADER_VALUES =\n 1 +\n Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;\nexport const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;\n\nexport interface Options {\n timeout?: number;\n}\n\nexport interface WaitRequest {\n target: Int32Array;\n index: number;\n value: number;\n timeout?: number;\n}\n\nexport type WaitResponse = ReturnType<typeof Atomics.wait>;\n\nexport function* writeGenerator(\n data: unknown,\n buffer: SharedArrayBuffer,\n { timeout = 5000 }: Options = {},\n): Generator<WaitRequest, void, WaitResponse> {\n const serialized = serialize(data);\n const chunkSize = buffer.byteLength - HEADER_SIZE;\n const totalSize = serialized.length;\n const totalChunks = Math.ceil(totalSize / chunkSize);\n const header = new Int32Array(buffer);\n\n header[Handshake.TOTAL_SIZE] = totalSize;\n header[Handshake.TOTAL_CHUNKS] = totalChunks;\n Atomics.store(header, SEMAPHORE, Semaphore.HANDSHAKE);\n Atomics.notify(header, SEMAPHORE);\n\n try {\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.HANDSHAKE,\n timeout,\n };\n if (handshakeResult === \"timed-out\") {\n throw new Error(\"Reader handshake timeout\");\n }\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, totalSize);\n const size = end - start;\n payload.set(serialized.subarray(start, end), 0);\n header[Header.CHUNK_INDEX] = i;\n header[Header.CHUNK_OFFSET] = start;\n header[Header.CHUNK_SIZE] = size;\n Atomics.store(header, SEMAPHORE, Semaphore.PAYLOAD);\n Atomics.notify(header, SEMAPHORE);\n\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.PAYLOAD,\n timeout,\n };\n if (chunkResult === \"timed-out\") {\n throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);\n }\n }\n } finally {\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n }\n}\n\nexport function* readGenerator(\n buffer: SharedArrayBuffer,\n { timeout = 5000 }: Options = {},\n): Generator<WaitRequest, unknown, WaitResponse> {\n const header = new Int32Array(buffer);\n\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (handshakeResult === \"timed-out\") {\n throw new Error(\"Handshake timeout\");\n }\n if (header[SEMAPHORE] !== Semaphore.HANDSHAKE) {\n throw new Error(\"Invalid handshake state\");\n }\n\n const totalSize = header[Handshake.TOTAL_SIZE];\n const totalChunks = header[Handshake.TOTAL_CHUNKS];\n const data = new Uint8Array(totalSize);\n\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (chunkResult === \"timed-out\") {\n throw new Error(`Writer timeout waiting for chunk ${i}`);\n }\n // @ts-expect-error does not infer number\n if (header[SEMAPHORE] !== Semaphore.PAYLOAD) {\n throw new Error(\n `Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`,\n );\n }\n const chunkIndex = header[Header.CHUNK_INDEX];\n if (i !== chunkIndex) {\n throw new Error(\n `Reader integrity failure for chunk ${chunkIndex} expected ${i}`,\n );\n }\n const offset = header[Header.CHUNK_OFFSET];\n const size = header[Header.CHUNK_SIZE];\n data.set(payload.subarray(0, size), offset);\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n }\n return deserialize(data) as unknown;\n}\n\nexport const writeSync = (\n data: unknown,\n buffer: SharedArrayBuffer,\n options?: Options,\n) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(\n result.value.target,\n result.value.index,\n result.value.value,\n result.value.timeout,\n );\n result = gen.next(waitResult);\n }\n};\n\nexport const write = async (\n data: unknown,\n buffer: SharedArrayBuffer,\n options?: Options,\n) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(\n request.target,\n request.index,\n request.value,\n request.timeout,\n ).value;\n result = gen.next(waitResult);\n }\n};\n\nexport const readSync = (\n buffer: SharedArrayBuffer,\n options?: Options,\n): unknown => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(\n result.value.target,\n result.value.index,\n result.value.value,\n result.value.timeout,\n );\n result = gen.next(waitResult);\n }\n return result.value;\n};\n\nexport const read = async (\n buffer: SharedArrayBuffer,\n options?: Options,\n): Promise<unknown> => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(\n request.target,\n request.index,\n request.value,\n request.timeout,\n ).value;\n result = gen.next(waitResult);\n }\n return result.value;\n};\n"],"names":["HEADER_SIZE","HEADER_VALUES","Handshake","Header","SEMAPHORE","Semaphore","read","readGenerator","readSync","write","writeGenerator","writeSync","Math","max","Object","values","length","Uint32Array","BYTES_PER_ELEMENT","data","buffer","timeout","serialized","serialize","chunkSize","byteLength","totalSize","totalChunks","ceil","header","Int32Array","Atomics","store","notify","handshakeResult","target","index","value","Error","payload","Uint8Array","i","start","end","min","size","set","subarray","chunkResult","chunkIndex","offset","deserialize","options","gen","result","next","done","waitResult","wait","request","waitAsync"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export const SEMAPHORE = 0;\n\nexport enum Semaphore {\n READY,\n HANDSHAKE,\n PAYLOAD,\n}\n\nexport enum Handshake {\n TOTAL_SIZE = 1,\n TOTAL_CHUNKS,\n}\n\nexport enum Header {\n CHUNK_INDEX = 1,\n CHUNK_OFFSET,\n CHUNK_SIZE,\n}\n\nexport const HEADER_VALUES = 1 + Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;\nexport const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;\n\nexport interface Options {\n timeout?: number;\n}\n\nexport interface WaitRequest {\n target: Int32Array;\n index: number;\n value: number;\n timeout?: number;\n}\n\nexport type WaitResponse = ReturnType<typeof Atomics.wait>;\n\nexport function* writeGenerator(data: Uint8Array, buffer: SharedArrayBuffer, { timeout = 5000 }: Options = {}): Generator<WaitRequest, void, WaitResponse> {\n const chunkSize = buffer.byteLength - HEADER_SIZE;\n const totalSize = data.length;\n const totalChunks = Math.ceil(totalSize / chunkSize);\n const header = new Int32Array(buffer);\n\n header[Handshake.TOTAL_SIZE] = totalSize;\n header[Handshake.TOTAL_CHUNKS] = totalChunks;\n Atomics.store(header, SEMAPHORE, Semaphore.HANDSHAKE);\n Atomics.notify(header, SEMAPHORE);\n\n try {\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.HANDSHAKE,\n timeout,\n };\n if (handshakeResult === 'timed-out') {\n throw new Error('Reader handshake timeout');\n }\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, totalSize);\n const size = end - start;\n payload.set(data.subarray(start, end), 0);\n header[Header.CHUNK_INDEX] = i;\n header[Header.CHUNK_OFFSET] = start;\n header[Header.CHUNK_SIZE] = size;\n Atomics.store(header, SEMAPHORE, Semaphore.PAYLOAD);\n Atomics.notify(header, SEMAPHORE);\n\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.PAYLOAD,\n timeout,\n };\n if (chunkResult === 'timed-out') {\n throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);\n }\n }\n } finally {\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n }\n}\n\nexport function* readGenerator(buffer: SharedArrayBuffer, { timeout = 5000 }: Options = {}): Generator<WaitRequest, Uint8Array, WaitResponse> {\n const header = new Int32Array(buffer);\n\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (handshakeResult === 'timed-out') {\n throw new Error('Handshake timeout');\n }\n if (header[SEMAPHORE] !== Semaphore.HANDSHAKE) {\n throw new Error('Invalid handshake state');\n }\n\n const totalSize = header[Handshake.TOTAL_SIZE];\n const totalChunks = header[Handshake.TOTAL_CHUNKS];\n const data = new Uint8Array(totalSize);\n\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (chunkResult === 'timed-out') {\n throw new Error(`Writer timeout waiting for chunk ${i}`);\n }\n // @ts-expect-error does not infer number\n if (header[SEMAPHORE] !== Semaphore.PAYLOAD) {\n throw new Error(`Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`);\n }\n const chunkIndex = header[Header.CHUNK_INDEX];\n if (i !== chunkIndex) {\n throw new Error(`Reader integrity failure for chunk ${chunkIndex} expected ${i}`);\n }\n const offset = header[Header.CHUNK_OFFSET];\n const size = header[Header.CHUNK_SIZE];\n data.set(payload.subarray(0, size), offset);\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n }\n return data;\n}\n\nexport const writeSync = (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(result.value.target, result.value.index, result.value.value, result.value.timeout);\n result = gen.next(waitResult);\n }\n};\n\nexport const write = async (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(request.target, request.index, request.value, request.timeout).value;\n result = gen.next(waitResult);\n }\n};\n\nexport const readSync = (buffer: SharedArrayBuffer, options?: Options): Uint8Array => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(result.value.target, result.value.index, result.value.value, result.value.timeout);\n result = gen.next(waitResult);\n }\n return result.value;\n};\n\nexport const read = async (buffer: SharedArrayBuffer, options?: Options): Promise<Uint8Array> => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(request.target, request.index, request.value, request.timeout).value;\n result = gen.next(waitResult);\n }\n return result.value;\n};\n"],"names":["HEADER_SIZE","HEADER_VALUES","Handshake","Header","SEMAPHORE","Semaphore","read","readGenerator","readSync","write","writeGenerator","writeSync","Math","max","Object","values","length","Uint32Array","BYTES_PER_ELEMENT","data","buffer","timeout","chunkSize","byteLength","totalSize","totalChunks","ceil","header","Int32Array","Atomics","store","notify","handshakeResult","target","index","value","Error","payload","Uint8Array","i","start","end","min","size","set","subarray","chunkResult","chunkIndex","offset","options","gen","result","next","done","waitResult","wait","request","waitAsync"],"mappings":"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"}
package/build/index.d.ts CHANGED
@@ -25,9 +25,9 @@ export interface WaitRequest {
25
25
  timeout?: number;
26
26
  }
27
27
  export type WaitResponse = ReturnType<typeof Atomics.wait>;
28
- export declare function writeGenerator(data: unknown, buffer: SharedArrayBuffer, { timeout }?: Options): Generator<WaitRequest, void, WaitResponse>;
29
- export declare function readGenerator(buffer: SharedArrayBuffer, { timeout }?: Options): Generator<WaitRequest, unknown, WaitResponse>;
30
- export declare const writeSync: (data: unknown, buffer: SharedArrayBuffer, options?: Options) => void;
31
- export declare const write: (data: unknown, buffer: SharedArrayBuffer, options?: Options) => Promise<void>;
32
- export declare const readSync: (buffer: SharedArrayBuffer, options?: Options) => unknown;
33
- export declare const read: (buffer: SharedArrayBuffer, options?: Options) => Promise<unknown>;
28
+ export declare function writeGenerator(data: Uint8Array, buffer: SharedArrayBuffer, { timeout }?: Options): Generator<WaitRequest, void, WaitResponse>;
29
+ export declare function readGenerator(buffer: SharedArrayBuffer, { timeout }?: Options): Generator<WaitRequest, Uint8Array, WaitResponse>;
30
+ export declare const writeSync: (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => void;
31
+ export declare const write: (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => Promise<void>;
32
+ export declare const readSync: (buffer: SharedArrayBuffer, options?: Options) => Uint8Array;
33
+ export declare const read: (buffer: SharedArrayBuffer, options?: Options) => Promise<Uint8Array>;
package/build/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import { serialize, deserialize } from "node:v8";
2
1
  export const SEMAPHORE = 0;
3
2
  export var Semaphore = /*#__PURE__*/ function(Semaphore) {
4
3
  Semaphore[Semaphore["READY"] = 0] = "READY";
@@ -20,9 +19,8 @@ export var Header = /*#__PURE__*/ function(Header) {
20
19
  export const HEADER_VALUES = 1 + Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;
21
20
  export const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;
22
21
  export function* writeGenerator(data, buffer, { timeout = 5000 } = {}) {
23
- const serialized = serialize(data);
24
22
  const chunkSize = buffer.byteLength - HEADER_SIZE;
25
- const totalSize = serialized.length;
23
+ const totalSize = data.length;
26
24
  const totalChunks = Math.ceil(totalSize / chunkSize);
27
25
  const header = new Int32Array(buffer);
28
26
  header[1] = totalSize;
@@ -36,15 +34,15 @@ export function* writeGenerator(data, buffer, { timeout = 5000 } = {}) {
36
34
  value: 1,
37
35
  timeout
38
36
  };
39
- if (handshakeResult === "timed-out") {
40
- throw new Error("Reader handshake timeout");
37
+ if (handshakeResult === 'timed-out') {
38
+ throw new Error('Reader handshake timeout');
41
39
  }
42
40
  const payload = new Uint8Array(buffer, HEADER_SIZE);
43
41
  for(let i = 0; i < totalChunks; i++){
44
42
  const start = i * chunkSize;
45
43
  const end = Math.min(start + chunkSize, totalSize);
46
44
  const size = end - start;
47
- payload.set(serialized.subarray(start, end), 0);
45
+ payload.set(data.subarray(start, end), 0);
48
46
  header[1] = i;
49
47
  header[2] = start;
50
48
  header[3] = size;
@@ -56,7 +54,7 @@ export function* writeGenerator(data, buffer, { timeout = 5000 } = {}) {
56
54
  value: 2,
57
55
  timeout
58
56
  };
59
- if (chunkResult === "timed-out") {
57
+ if (chunkResult === 'timed-out') {
60
58
  throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);
61
59
  }
62
60
  }
@@ -72,11 +70,11 @@ export function* readGenerator(buffer, { timeout = 5000 } = {}) {
72
70
  value: 0,
73
71
  timeout
74
72
  };
75
- if (handshakeResult === "timed-out") {
76
- throw new Error("Handshake timeout");
73
+ if (handshakeResult === 'timed-out') {
74
+ throw new Error('Handshake timeout');
77
75
  }
78
76
  if (header[SEMAPHORE] !== 1) {
79
- throw new Error("Invalid handshake state");
77
+ throw new Error('Invalid handshake state');
80
78
  }
81
79
  const totalSize = header[1];
82
80
  const totalChunks = header[2];
@@ -91,7 +89,7 @@ export function* readGenerator(buffer, { timeout = 5000 } = {}) {
91
89
  value: 0,
92
90
  timeout
93
91
  };
94
- if (chunkResult === "timed-out") {
92
+ if (chunkResult === 'timed-out') {
95
93
  throw new Error(`Writer timeout waiting for chunk ${i}`);
96
94
  }
97
95
  if (header[SEMAPHORE] !== 2) {
@@ -107,7 +105,7 @@ export function* readGenerator(buffer, { timeout = 5000 } = {}) {
107
105
  Atomics.store(header, SEMAPHORE, 0);
108
106
  Atomics.notify(header, SEMAPHORE);
109
107
  }
110
- return deserialize(data);
108
+ return data;
111
109
  }
112
110
  export const writeSync = (data, buffer, options)=>{
113
111
  const gen = writeGenerator(data, buffer, options);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { serialize, deserialize } from \"node:v8\";\n\nexport const SEMAPHORE = 0;\n\nexport enum Semaphore {\n READY,\n HANDSHAKE,\n PAYLOAD,\n}\n\nexport enum Handshake {\n TOTAL_SIZE = 1,\n TOTAL_CHUNKS,\n}\n\nexport enum Header {\n CHUNK_INDEX = 1,\n CHUNK_OFFSET,\n CHUNK_SIZE,\n}\n\nexport const HEADER_VALUES =\n 1 +\n Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;\nexport const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;\n\nexport interface Options {\n timeout?: number;\n}\n\nexport interface WaitRequest {\n target: Int32Array;\n index: number;\n value: number;\n timeout?: number;\n}\n\nexport type WaitResponse = ReturnType<typeof Atomics.wait>;\n\nexport function* writeGenerator(\n data: unknown,\n buffer: SharedArrayBuffer,\n { timeout = 5000 }: Options = {},\n): Generator<WaitRequest, void, WaitResponse> {\n const serialized = serialize(data);\n const chunkSize = buffer.byteLength - HEADER_SIZE;\n const totalSize = serialized.length;\n const totalChunks = Math.ceil(totalSize / chunkSize);\n const header = new Int32Array(buffer);\n\n header[Handshake.TOTAL_SIZE] = totalSize;\n header[Handshake.TOTAL_CHUNKS] = totalChunks;\n Atomics.store(header, SEMAPHORE, Semaphore.HANDSHAKE);\n Atomics.notify(header, SEMAPHORE);\n\n try {\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.HANDSHAKE,\n timeout,\n };\n if (handshakeResult === \"timed-out\") {\n throw new Error(\"Reader handshake timeout\");\n }\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, totalSize);\n const size = end - start;\n payload.set(serialized.subarray(start, end), 0);\n header[Header.CHUNK_INDEX] = i;\n header[Header.CHUNK_OFFSET] = start;\n header[Header.CHUNK_SIZE] = size;\n Atomics.store(header, SEMAPHORE, Semaphore.PAYLOAD);\n Atomics.notify(header, SEMAPHORE);\n\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.PAYLOAD,\n timeout,\n };\n if (chunkResult === \"timed-out\") {\n throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);\n }\n }\n } finally {\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n }\n}\n\nexport function* readGenerator(\n buffer: SharedArrayBuffer,\n { timeout = 5000 }: Options = {},\n): Generator<WaitRequest, unknown, WaitResponse> {\n const header = new Int32Array(buffer);\n\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (handshakeResult === \"timed-out\") {\n throw new Error(\"Handshake timeout\");\n }\n if (header[SEMAPHORE] !== Semaphore.HANDSHAKE) {\n throw new Error(\"Invalid handshake state\");\n }\n\n const totalSize = header[Handshake.TOTAL_SIZE];\n const totalChunks = header[Handshake.TOTAL_CHUNKS];\n const data = new Uint8Array(totalSize);\n\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (chunkResult === \"timed-out\") {\n throw new Error(`Writer timeout waiting for chunk ${i}`);\n }\n // @ts-expect-error does not infer number\n if (header[SEMAPHORE] !== Semaphore.PAYLOAD) {\n throw new Error(\n `Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`,\n );\n }\n const chunkIndex = header[Header.CHUNK_INDEX];\n if (i !== chunkIndex) {\n throw new Error(\n `Reader integrity failure for chunk ${chunkIndex} expected ${i}`,\n );\n }\n const offset = header[Header.CHUNK_OFFSET];\n const size = header[Header.CHUNK_SIZE];\n data.set(payload.subarray(0, size), offset);\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n }\n return deserialize(data) as unknown;\n}\n\nexport const writeSync = (\n data: unknown,\n buffer: SharedArrayBuffer,\n options?: Options,\n) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(\n result.value.target,\n result.value.index,\n result.value.value,\n result.value.timeout,\n );\n result = gen.next(waitResult);\n }\n};\n\nexport const write = async (\n data: unknown,\n buffer: SharedArrayBuffer,\n options?: Options,\n) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(\n request.target,\n request.index,\n request.value,\n request.timeout,\n ).value;\n result = gen.next(waitResult);\n }\n};\n\nexport const readSync = (\n buffer: SharedArrayBuffer,\n options?: Options,\n): unknown => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(\n result.value.target,\n result.value.index,\n result.value.value,\n result.value.timeout,\n );\n result = gen.next(waitResult);\n }\n return result.value;\n};\n\nexport const read = async (\n buffer: SharedArrayBuffer,\n options?: Options,\n): Promise<unknown> => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(\n request.target,\n request.index,\n request.value,\n request.timeout,\n ).value;\n result = gen.next(waitResult);\n }\n return result.value;\n};\n"],"names":["serialize","deserialize","SEMAPHORE","Semaphore","Handshake","Header","HEADER_VALUES","Math","max","Object","values","length","HEADER_SIZE","Uint32Array","BYTES_PER_ELEMENT","writeGenerator","data","buffer","timeout","serialized","chunkSize","byteLength","totalSize","totalChunks","ceil","header","Int32Array","Atomics","store","notify","handshakeResult","target","index","value","Error","payload","Uint8Array","i","start","end","min","size","set","subarray","chunkResult","readGenerator","chunkIndex","offset","writeSync","options","gen","result","next","done","waitResult","wait","write","request","waitAsync","readSync","read"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export const SEMAPHORE = 0;\n\nexport enum Semaphore {\n READY,\n HANDSHAKE,\n PAYLOAD,\n}\n\nexport enum Handshake {\n TOTAL_SIZE = 1,\n TOTAL_CHUNKS,\n}\n\nexport enum Header {\n CHUNK_INDEX = 1,\n CHUNK_OFFSET,\n CHUNK_SIZE,\n}\n\nexport const HEADER_VALUES = 1 + Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;\nexport const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;\n\nexport interface Options {\n timeout?: number;\n}\n\nexport interface WaitRequest {\n target: Int32Array;\n index: number;\n value: number;\n timeout?: number;\n}\n\nexport type WaitResponse = ReturnType<typeof Atomics.wait>;\n\nexport function* writeGenerator(data: Uint8Array, buffer: SharedArrayBuffer, { timeout = 5000 }: Options = {}): Generator<WaitRequest, void, WaitResponse> {\n const chunkSize = buffer.byteLength - HEADER_SIZE;\n const totalSize = data.length;\n const totalChunks = Math.ceil(totalSize / chunkSize);\n const header = new Int32Array(buffer);\n\n header[Handshake.TOTAL_SIZE] = totalSize;\n header[Handshake.TOTAL_CHUNKS] = totalChunks;\n Atomics.store(header, SEMAPHORE, Semaphore.HANDSHAKE);\n Atomics.notify(header, SEMAPHORE);\n\n try {\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.HANDSHAKE,\n timeout,\n };\n if (handshakeResult === 'timed-out') {\n throw new Error('Reader handshake timeout');\n }\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, totalSize);\n const size = end - start;\n payload.set(data.subarray(start, end), 0);\n header[Header.CHUNK_INDEX] = i;\n header[Header.CHUNK_OFFSET] = start;\n header[Header.CHUNK_SIZE] = size;\n Atomics.store(header, SEMAPHORE, Semaphore.PAYLOAD);\n Atomics.notify(header, SEMAPHORE);\n\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.PAYLOAD,\n timeout,\n };\n if (chunkResult === 'timed-out') {\n throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);\n }\n }\n } finally {\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n }\n}\n\nexport function* readGenerator(buffer: SharedArrayBuffer, { timeout = 5000 }: Options = {}): Generator<WaitRequest, Uint8Array, WaitResponse> {\n const header = new Int32Array(buffer);\n\n const handshakeResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (handshakeResult === 'timed-out') {\n throw new Error('Handshake timeout');\n }\n if (header[SEMAPHORE] !== Semaphore.HANDSHAKE) {\n throw new Error('Invalid handshake state');\n }\n\n const totalSize = header[Handshake.TOTAL_SIZE];\n const totalChunks = header[Handshake.TOTAL_CHUNKS];\n const data = new Uint8Array(totalSize);\n\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n\n const payload = new Uint8Array(buffer, HEADER_SIZE);\n for (let i = 0; i < totalChunks; i++) {\n const chunkResult: WaitResponse = yield {\n target: header,\n index: SEMAPHORE,\n value: Semaphore.READY,\n timeout,\n };\n if (chunkResult === 'timed-out') {\n throw new Error(`Writer timeout waiting for chunk ${i}`);\n }\n // @ts-expect-error does not infer number\n if (header[SEMAPHORE] !== Semaphore.PAYLOAD) {\n throw new Error(`Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`);\n }\n const chunkIndex = header[Header.CHUNK_INDEX];\n if (i !== chunkIndex) {\n throw new Error(`Reader integrity failure for chunk ${chunkIndex} expected ${i}`);\n }\n const offset = header[Header.CHUNK_OFFSET];\n const size = header[Header.CHUNK_SIZE];\n data.set(payload.subarray(0, size), offset);\n Atomics.store(header, SEMAPHORE, Semaphore.READY);\n Atomics.notify(header, SEMAPHORE);\n }\n return data;\n}\n\nexport const writeSync = (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(result.value.target, result.value.index, result.value.value, result.value.timeout);\n result = gen.next(waitResult);\n }\n};\n\nexport const write = async (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => {\n const gen = writeGenerator(data, buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(request.target, request.index, request.value, request.timeout).value;\n result = gen.next(waitResult);\n }\n};\n\nexport const readSync = (buffer: SharedArrayBuffer, options?: Options): Uint8Array => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const waitResult = Atomics.wait(result.value.target, result.value.index, result.value.value, result.value.timeout);\n result = gen.next(waitResult);\n }\n return result.value;\n};\n\nexport const read = async (buffer: SharedArrayBuffer, options?: Options): Promise<Uint8Array> => {\n const gen = readGenerator(buffer, options);\n let result = gen.next();\n while (!result.done) {\n const request = result.value;\n const waitResult = await Atomics.waitAsync(request.target, request.index, request.value, request.timeout).value;\n result = gen.next(waitResult);\n }\n return result.value;\n};\n"],"names":["SEMAPHORE","Semaphore","Handshake","Header","HEADER_VALUES","Math","max","Object","values","length","HEADER_SIZE","Uint32Array","BYTES_PER_ELEMENT","writeGenerator","data","buffer","timeout","chunkSize","byteLength","totalSize","totalChunks","ceil","header","Int32Array","Atomics","store","notify","handshakeResult","target","index","value","Error","payload","Uint8Array","i","start","end","min","size","set","subarray","chunkResult","readGenerator","chunkIndex","offset","writeSync","options","gen","result","next","done","waitResult","wait","write","request","waitAsync","readSync","read"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sabcom",
3
- "version": "0.0.25",
4
- "description": "A TypeScript/Node.js library for inter-thread communication using SharedArrayBuffer with atomic operations and V8 serialization",
3
+ "version": "0.1.0",
4
+ "description": "A TypeScript/Node.js library for inter-thread communication using SharedArrayBuffer with atomic operations for raw buffer data transfer",
5
5
  "type": "module",
6
6
  "types": "build/index.d.ts",
7
7
  "main": "build/index.cjs",
@@ -31,8 +31,6 @@
31
31
  "multithreading",
32
32
  "ipc",
33
33
  "inter-process",
34
- "v8",
35
- "serialization",
36
34
  "synchronization",
37
35
  "memory"
38
36
  ],
package/src/index.ts CHANGED
@@ -1,5 +1,3 @@
1
- import { serialize, deserialize } from "node:v8";
2
-
3
1
  export const SEMAPHORE = 0;
4
2
 
5
3
  export enum Semaphore {
@@ -19,9 +17,7 @@ export enum Header {
19
17
  CHUNK_SIZE,
20
18
  }
21
19
 
22
- export const HEADER_VALUES =
23
- 1 +
24
- Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;
20
+ export const HEADER_VALUES = 1 + Math.max(Object.values(Handshake).length, Object.values(Header).length) / 2;
25
21
  export const HEADER_SIZE = Uint32Array.BYTES_PER_ELEMENT * HEADER_VALUES;
26
22
 
27
23
  export interface Options {
@@ -37,14 +33,9 @@ export interface WaitRequest {
37
33
 
38
34
  export type WaitResponse = ReturnType<typeof Atomics.wait>;
39
35
 
40
- export function* writeGenerator(
41
- data: unknown,
42
- buffer: SharedArrayBuffer,
43
- { timeout = 5000 }: Options = {},
44
- ): Generator<WaitRequest, void, WaitResponse> {
45
- const serialized = serialize(data);
36
+ export function* writeGenerator(data: Uint8Array, buffer: SharedArrayBuffer, { timeout = 5000 }: Options = {}): Generator<WaitRequest, void, WaitResponse> {
46
37
  const chunkSize = buffer.byteLength - HEADER_SIZE;
47
- const totalSize = serialized.length;
38
+ const totalSize = data.length;
48
39
  const totalChunks = Math.ceil(totalSize / chunkSize);
49
40
  const header = new Int32Array(buffer);
50
41
 
@@ -60,8 +51,8 @@ export function* writeGenerator(
60
51
  value: Semaphore.HANDSHAKE,
61
52
  timeout,
62
53
  };
63
- if (handshakeResult === "timed-out") {
64
- throw new Error("Reader handshake timeout");
54
+ if (handshakeResult === 'timed-out') {
55
+ throw new Error('Reader handshake timeout');
65
56
  }
66
57
 
67
58
  const payload = new Uint8Array(buffer, HEADER_SIZE);
@@ -69,7 +60,7 @@ export function* writeGenerator(
69
60
  const start = i * chunkSize;
70
61
  const end = Math.min(start + chunkSize, totalSize);
71
62
  const size = end - start;
72
- payload.set(serialized.subarray(start, end), 0);
63
+ payload.set(data.subarray(start, end), 0);
73
64
  header[Header.CHUNK_INDEX] = i;
74
65
  header[Header.CHUNK_OFFSET] = start;
75
66
  header[Header.CHUNK_SIZE] = size;
@@ -82,7 +73,7 @@ export function* writeGenerator(
82
73
  value: Semaphore.PAYLOAD,
83
74
  timeout,
84
75
  };
85
- if (chunkResult === "timed-out") {
76
+ if (chunkResult === 'timed-out') {
86
77
  throw new Error(`Reader timeout on chunk ${i}/${totalChunks - 1}`);
87
78
  }
88
79
  }
@@ -91,10 +82,7 @@ export function* writeGenerator(
91
82
  }
92
83
  }
93
84
 
94
- export function* readGenerator(
95
- buffer: SharedArrayBuffer,
96
- { timeout = 5000 }: Options = {},
97
- ): Generator<WaitRequest, unknown, WaitResponse> {
85
+ export function* readGenerator(buffer: SharedArrayBuffer, { timeout = 5000 }: Options = {}): Generator<WaitRequest, Uint8Array, WaitResponse> {
98
86
  const header = new Int32Array(buffer);
99
87
 
100
88
  const handshakeResult: WaitResponse = yield {
@@ -103,11 +91,11 @@ export function* readGenerator(
103
91
  value: Semaphore.READY,
104
92
  timeout,
105
93
  };
106
- if (handshakeResult === "timed-out") {
107
- throw new Error("Handshake timeout");
94
+ if (handshakeResult === 'timed-out') {
95
+ throw new Error('Handshake timeout');
108
96
  }
109
97
  if (header[SEMAPHORE] !== Semaphore.HANDSHAKE) {
110
- throw new Error("Invalid handshake state");
98
+ throw new Error('Invalid handshake state');
111
99
  }
112
100
 
113
101
  const totalSize = header[Handshake.TOTAL_SIZE];
@@ -125,20 +113,16 @@ export function* readGenerator(
125
113
  value: Semaphore.READY,
126
114
  timeout,
127
115
  };
128
- if (chunkResult === "timed-out") {
116
+ if (chunkResult === 'timed-out') {
129
117
  throw new Error(`Writer timeout waiting for chunk ${i}`);
130
118
  }
131
119
  // @ts-expect-error does not infer number
132
120
  if (header[SEMAPHORE] !== Semaphore.PAYLOAD) {
133
- throw new Error(
134
- `Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`,
135
- );
121
+ throw new Error(`Expected payload header, received ${Semaphore[header[SEMAPHORE]]}`);
136
122
  }
137
123
  const chunkIndex = header[Header.CHUNK_INDEX];
138
124
  if (i !== chunkIndex) {
139
- throw new Error(
140
- `Reader integrity failure for chunk ${chunkIndex} expected ${i}`,
141
- );
125
+ throw new Error(`Reader integrity failure for chunk ${chunkIndex} expected ${i}`);
142
126
  }
143
127
  const offset = header[Header.CHUNK_OFFSET];
144
128
  const size = header[Header.CHUNK_SIZE];
@@ -146,78 +130,44 @@ export function* readGenerator(
146
130
  Atomics.store(header, SEMAPHORE, Semaphore.READY);
147
131
  Atomics.notify(header, SEMAPHORE);
148
132
  }
149
- return deserialize(data) as unknown;
133
+ return data;
150
134
  }
151
135
 
152
- export const writeSync = (
153
- data: unknown,
154
- buffer: SharedArrayBuffer,
155
- options?: Options,
156
- ) => {
136
+ export const writeSync = (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => {
157
137
  const gen = writeGenerator(data, buffer, options);
158
138
  let result = gen.next();
159
139
  while (!result.done) {
160
- const waitResult = Atomics.wait(
161
- result.value.target,
162
- result.value.index,
163
- result.value.value,
164
- result.value.timeout,
165
- );
140
+ const waitResult = Atomics.wait(result.value.target, result.value.index, result.value.value, result.value.timeout);
166
141
  result = gen.next(waitResult);
167
142
  }
168
143
  };
169
144
 
170
- export const write = async (
171
- data: unknown,
172
- buffer: SharedArrayBuffer,
173
- options?: Options,
174
- ) => {
145
+ export const write = async (data: Uint8Array, buffer: SharedArrayBuffer, options?: Options) => {
175
146
  const gen = writeGenerator(data, buffer, options);
176
147
  let result = gen.next();
177
148
  while (!result.done) {
178
149
  const request = result.value;
179
- const waitResult = await Atomics.waitAsync(
180
- request.target,
181
- request.index,
182
- request.value,
183
- request.timeout,
184
- ).value;
150
+ const waitResult = await Atomics.waitAsync(request.target, request.index, request.value, request.timeout).value;
185
151
  result = gen.next(waitResult);
186
152
  }
187
153
  };
188
154
 
189
- export const readSync = (
190
- buffer: SharedArrayBuffer,
191
- options?: Options,
192
- ): unknown => {
155
+ export const readSync = (buffer: SharedArrayBuffer, options?: Options): Uint8Array => {
193
156
  const gen = readGenerator(buffer, options);
194
157
  let result = gen.next();
195
158
  while (!result.done) {
196
- const waitResult = Atomics.wait(
197
- result.value.target,
198
- result.value.index,
199
- result.value.value,
200
- result.value.timeout,
201
- );
159
+ const waitResult = Atomics.wait(result.value.target, result.value.index, result.value.value, result.value.timeout);
202
160
  result = gen.next(waitResult);
203
161
  }
204
162
  return result.value;
205
163
  };
206
164
 
207
- export const read = async (
208
- buffer: SharedArrayBuffer,
209
- options?: Options,
210
- ): Promise<unknown> => {
165
+ export const read = async (buffer: SharedArrayBuffer, options?: Options): Promise<Uint8Array> => {
211
166
  const gen = readGenerator(buffer, options);
212
167
  let result = gen.next();
213
168
  while (!result.done) {
214
169
  const request = result.value;
215
- const waitResult = await Atomics.waitAsync(
216
- request.target,
217
- request.index,
218
- request.value,
219
- request.timeout,
220
- ).value;
170
+ const waitResult = await Atomics.waitAsync(request.target, request.index, request.value, request.timeout).value;
221
171
  result = gen.next(waitResult);
222
172
  }
223
173
  return result.value;