@nxtedition/shared 4.0.2 → 4.0.4
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 +14 -17
- package/lib/index.d.ts +10 -9
- package/lib/index.js +22 -36
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -23,10 +23,10 @@ npm install @nxtedition/shared
|
|
|
23
23
|
## Usage
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
|
-
import {
|
|
26
|
+
import { SharedStateBuffer, Reader, Writer } from '@nxtedition/shared'
|
|
27
27
|
|
|
28
|
-
// Allocate shared memory (pass state
|
|
29
|
-
const state = new
|
|
28
|
+
// Allocate shared memory (pass state to a worker thread)
|
|
29
|
+
const state = new SharedStateBuffer(1024 * 1024) // 1 MB ring buffer
|
|
30
30
|
|
|
31
31
|
// --- Writer side (e.g. main thread) ---
|
|
32
32
|
const w = new Writer(state)
|
|
@@ -87,12 +87,12 @@ if (!ok) {
|
|
|
87
87
|
|
|
88
88
|
```js
|
|
89
89
|
// main.js
|
|
90
|
-
import {
|
|
90
|
+
import { SharedStateBuffer, Writer } from '@nxtedition/shared'
|
|
91
91
|
import { Worker } from 'node:worker_threads'
|
|
92
92
|
|
|
93
|
-
const state = new
|
|
93
|
+
const state = new SharedStateBuffer(1024 * 1024)
|
|
94
94
|
const worker = new Worker('./reader-worker.js', {
|
|
95
|
-
workerData: state
|
|
95
|
+
workerData: state,
|
|
96
96
|
})
|
|
97
97
|
|
|
98
98
|
const w = new Writer(state)
|
|
@@ -117,20 +117,17 @@ poll()
|
|
|
117
117
|
|
|
118
118
|
## API
|
|
119
119
|
|
|
120
|
-
### `new
|
|
120
|
+
### `new SharedStateBuffer(size: number)`
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
Extends `SharedArrayBuffer`. Allocates a shared memory buffer for the ring buffer. The first 128 bytes are reserved for state (read/write pointers); the rest is the data region. Overhead (length header + alignment + next-header slot) is added automatically so that a single write of `size` bytes is always guaranteed to fit.
|
|
123
123
|
|
|
124
|
-
- **size** —
|
|
125
|
-
- **buffer** — An existing `SharedArrayBuffer` to wrap
|
|
124
|
+
- **size** — Maximum payload size in bytes for a single write (must be a positive integer, max ~2 GB)
|
|
126
125
|
|
|
127
|
-
|
|
126
|
+
Since `SharedStateBuffer` extends `SharedArrayBuffer`, pass it directly to a worker thread.
|
|
128
127
|
|
|
129
|
-
|
|
128
|
+
### `new Reader(sharedBuffer: SharedArrayBuffer)`
|
|
130
129
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
Creates a reader for the ring buffer. Accepts a `State` instance or a `SharedArrayBuffer` directly (shorthand for `new Reader(new State(buf))`).
|
|
130
|
+
Creates a reader for the ring buffer.
|
|
134
131
|
|
|
135
132
|
#### `reader.readSome(next, opaque?)`
|
|
136
133
|
|
|
@@ -147,9 +144,9 @@ Return `false` from the callback to stop reading early. Returns the number of me
|
|
|
147
144
|
|
|
148
145
|
Messages are batched: up to 1024 items or 256 KiB per call.
|
|
149
146
|
|
|
150
|
-
### `new Writer(
|
|
147
|
+
### `new Writer(sharedBuffer: SharedArrayBuffer, options?)`
|
|
151
148
|
|
|
152
|
-
Creates a writer for the ring buffer.
|
|
149
|
+
Creates a writer for the ring buffer.
|
|
153
150
|
|
|
154
151
|
**Options:**
|
|
155
152
|
|
package/lib/index.d.ts
CHANGED
|
@@ -11,29 +11,30 @@ export interface WriterOptions {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* Shared ring buffer state.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Shared ring buffer state. Extends SharedArrayBuffer where the first 128
|
|
15
|
+
* bytes are reserved for read/write pointers and the rest is the data region.
|
|
16
|
+
*
|
|
17
|
+
* The `size` parameter is the guaranteed max payload for a single write.
|
|
18
|
+
* Overhead (length header + alignment + next-header slot) is added automatically.
|
|
17
19
|
*/
|
|
18
|
-
export declare class
|
|
19
|
-
readonly buffer: SharedArrayBuffer;
|
|
20
|
+
export declare class SharedStateBuffer extends SharedArrayBuffer {
|
|
20
21
|
constructor(size: number);
|
|
21
|
-
constructor(buffer: SharedArrayBuffer);
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Reader for the ring buffer.
|
|
25
25
|
*/
|
|
26
26
|
export declare class Reader {
|
|
27
27
|
#private;
|
|
28
|
-
constructor(
|
|
29
|
-
readSome
|
|
28
|
+
constructor(sharedBuffer: SharedArrayBuffer);
|
|
29
|
+
readSome(next: (data: BufferRegion) => void | boolean): number;
|
|
30
|
+
readSome<U>(next: (data: BufferRegion, opaque: U) => void | boolean, opaque: U): number;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Writer for the ring buffer.
|
|
33
34
|
*/
|
|
34
35
|
export declare class Writer {
|
|
35
36
|
#private;
|
|
36
|
-
constructor(
|
|
37
|
+
constructor(sharedBuffer: SharedArrayBuffer, { yield: onYield, logger }?: WriterOptions);
|
|
37
38
|
/**
|
|
38
39
|
* Synchronously writes a message. Blocks (via `Atomics.wait`) until buffer space is available.
|
|
39
40
|
* Writing more than "len" bytes in the callback will cause undefined behavior.
|
package/lib/index.js
CHANGED
|
@@ -29,38 +29,25 @@ const HWM_COUNT = 1024 // 1024 items
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Shared ring buffer state.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Shared ring buffer state. Extends SharedArrayBuffer where the first 128
|
|
33
|
+
* bytes are reserved for read/write pointers and the rest is the data region.
|
|
34
|
+
*
|
|
35
|
+
* The `size` parameter is the guaranteed max payload for a single write.
|
|
36
|
+
* Overhead (length header + alignment + next-header slot) is added automatically.
|
|
35
37
|
*/
|
|
36
|
-
export class
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (sizeOrBuffer.byteLength < STATE_BYTES + 8) {
|
|
44
|
-
throw new RangeError('SharedArrayBuffer too small for ring buffer state')
|
|
45
|
-
}
|
|
46
|
-
if (sizeOrBuffer.byteLength >= 2 ** 31) {
|
|
47
|
-
throw new RangeError('Shared buffer size exceeds maximum of 2GB')
|
|
48
|
-
}
|
|
49
|
-
this.buffer = sizeOrBuffer
|
|
50
|
-
} else {
|
|
51
|
-
const size = sizeOrBuffer
|
|
52
|
-
if (!Number.isInteger(size)) {
|
|
53
|
-
throw new TypeError('size must be a positive integer')
|
|
54
|
-
}
|
|
55
|
-
if (size <= 0) {
|
|
56
|
-
throw new RangeError('size must be a positive integer')
|
|
57
|
-
}
|
|
58
|
-
if (size >= 2 ** 31 - 11) {
|
|
59
|
-
throw new RangeError('size exceeds maximum of 2GB minus header size')
|
|
60
|
-
}
|
|
61
|
-
// 128 bytes for state + data region (rounded up to 4-byte boundary for Int32Array).
|
|
62
|
-
this.buffer = new SharedArrayBuffer(STATE_BYTES + ((size + 8 + 3) & ~3))
|
|
38
|
+
export class SharedStateBuffer extends SharedArrayBuffer {
|
|
39
|
+
constructor(size ) {
|
|
40
|
+
if (!Number.isInteger(size)) {
|
|
41
|
+
throw new TypeError('size must be a positive integer')
|
|
42
|
+
}
|
|
43
|
+
if (size <= 0) {
|
|
44
|
+
throw new RangeError('size must be a positive integer')
|
|
63
45
|
}
|
|
46
|
+
if (size >= 2 ** 31) {
|
|
47
|
+
throw new RangeError('size exceeds maximum of 2GB')
|
|
48
|
+
}
|
|
49
|
+
// Data region: aligned payload + 4-byte length header + 4-byte next-header slot.
|
|
50
|
+
super(STATE_BYTES + ((size + 3) & ~3) + 8)
|
|
64
51
|
}
|
|
65
52
|
}
|
|
66
53
|
|
|
@@ -74,8 +61,7 @@ export class Reader {
|
|
|
74
61
|
#data
|
|
75
62
|
#readPos
|
|
76
63
|
|
|
77
|
-
constructor(
|
|
78
|
-
const sharedBuffer = state instanceof SharedArrayBuffer ? state : state.buffer
|
|
64
|
+
constructor(sharedBuffer ) {
|
|
79
65
|
const size = sharedBuffer.byteLength - STATE_BYTES
|
|
80
66
|
|
|
81
67
|
this.#state = new Int32Array(sharedBuffer, 0, STATE_BYTES >> 2)
|
|
@@ -97,7 +83,9 @@ export class Reader {
|
|
|
97
83
|
this.#readPos = Atomics.load(this.#state, READ_INDEX) | 0
|
|
98
84
|
}
|
|
99
85
|
|
|
100
|
-
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
readSome (next , opaque ) {
|
|
101
89
|
let count = 0
|
|
102
90
|
let bytes = 0
|
|
103
91
|
|
|
@@ -183,9 +171,7 @@ export class Writer {
|
|
|
183
171
|
#logger
|
|
184
172
|
#uncorkBound
|
|
185
173
|
|
|
186
|
-
constructor(
|
|
187
|
-
const sharedBuffer = state instanceof SharedArrayBuffer ? state : state.buffer
|
|
188
|
-
|
|
174
|
+
constructor(sharedBuffer , { yield: onYield, logger } = {}) {
|
|
189
175
|
if (onYield != null && typeof onYield !== 'function') {
|
|
190
176
|
throw new TypeError('onYield must be a function')
|
|
191
177
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/shared",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"rimraf": "^6.1.3",
|
|
28
28
|
"typescript": "^5.9.3"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "6c260546e469c6cb70b5d35a20d3b0efcbf9629b"
|
|
31
31
|
}
|