@nxtedition/shared 1.2.0 → 1.4.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.
Files changed (2) hide show
  1. package/index.js +75 -67
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -31,7 +31,7 @@ async function* _reader({ sharedState, sharedBuffer }, cb) {
31
31
  if (len === END_OF_PACKET) {
32
32
  readPos = 0
33
33
  } else {
34
- const raw = buffer.slice(readPos + 4, readPos + len)
34
+ const raw = buffer.subarray(readPos + 4, readPos + len)
35
35
  readPos += len
36
36
  if (cb) {
37
37
  const thenable = cb(raw)
@@ -68,17 +68,11 @@ export function writer({ sharedState, sharedBuffer }) {
68
68
  let writePos = 0
69
69
  let flushing = null
70
70
 
71
- function acquire(len) {
72
- if (!len) {
73
- return Buffer.alloc(0)
74
- }
75
-
71
+ function tryWrite(maxLen, fn, opaque) {
76
72
  readPos = Atomics.load(state, READ_INDEX)
77
73
 
78
- assert(len < size / 2)
79
-
80
- if (size - writePos < len + 4) {
81
- if (readPos < len + 4) {
74
+ if (size - writePos < maxLen + 4) {
75
+ if (readPos < maxLen + 4) {
82
76
  return false
83
77
  }
84
78
 
@@ -87,71 +81,48 @@ export function writer({ sharedState, sharedBuffer }) {
87
81
  } else {
88
82
  const available = writePos >= readPos ? size - writePos : readPos - writePos
89
83
 
90
- if (available < len + 4) {
84
+ if (available < maxLen + 4) {
91
85
  return false
92
86
  }
93
87
  }
94
88
 
95
- return buffer.subarray(writePos + 4, writePos + 4 + len)
96
- }
97
-
98
- function acquireSync (len) {
99
- while (true) {
100
- const buf = acquire(len)
101
- if (buf) {
102
- return buf
103
- }
104
- Atomics.wait(state, READ_INDEX, readPos)
105
- }
106
- }
89
+ const lenPos = writePos
90
+ writePos += 4
107
91
 
108
- function release(len) {
109
- buffer.writeInt32LE(len, writePos)
110
- writePos += 4 + len
92
+ writePos += fn(buffer.subarray(writePos, writePos + maxLen), opaque)
111
93
 
112
- Atomics.store(state, WRITE_INDEX, writePos)
113
- Atomics.notify(state, WRITE_INDEX)
114
- }
94
+ const len = writePos - lenPos
115
95
 
116
- function tryWrite(...raw) {
117
- if (Array.isArray(raw[0])) {
118
- raw = raw[0]
119
- }
96
+ assert(len <= maxLen)
120
97
 
121
- if (!raw.length) {
122
- return true
123
- }
98
+ buffer.writeInt32LE(len, lenPos)
124
99
 
125
- let maxLen = 4
126
- for (const buf of raw) {
127
- maxLen += buf.byteLength ?? buf.length * 3
128
- }
100
+ Atomics.store(state, WRITE_INDEX, writePos)
101
+ Atomics.notify(state, WRITE_INDEX)
129
102
 
130
- const dst = acquire(maxLen)
131
- if (!dst) {
132
- return false
133
- }
103
+ return true
104
+ }
134
105
 
135
- let pos = 0
136
- for (const buf of raw) {
137
- if (typeof buf === 'string') {
138
- pos += buffer.write(buf, pos)
139
- } else {
140
- buffer.set(buf, pos)
141
- pos += buf.byteLength
142
- }
106
+ function flush() {
107
+ if (queue.length && !flushing) {
108
+ flushing = _flush()
143
109
  }
144
-
145
- assert(pos <= maxLen)
146
-
147
- release(pos)
148
-
149
- return true
110
+ return flushing
150
111
  }
151
112
 
152
- async function flush() {
113
+ async function _flush() {
153
114
  while (queue.length) {
154
- while (!tryWrite(queue[0])) {
115
+ const buf = queue[0]
116
+ while (
117
+ !tryWrite(
118
+ buf.byteLength,
119
+ (dst, buf) => {
120
+ dst.set(buf)
121
+ return buf.byteLength
122
+ },
123
+ queue[0]
124
+ )
125
+ ) {
155
126
  const { async, value } = Atomics.waitAsync(state, READ_INDEX, readPos)
156
127
  if (async) {
157
128
  await value
@@ -163,19 +134,56 @@ export function writer({ sharedState, sharedBuffer }) {
163
134
  flushing = null
164
135
  }
165
136
 
166
- function write(...raw) {
167
- if (!queue.length && tryWrite(...raw)) {
137
+ function write(...args) {
138
+ if (!args.length) {
139
+ return
140
+ }
141
+
142
+ let len
143
+ let fn
144
+ let opaque
145
+
146
+ if (Number.isInteger(args[0])) {
147
+ len = args[0]
148
+ fn = args[1]
149
+ opaque = args[2]
150
+ } else {
151
+ if (Array.isArray(args[0])) {
152
+ args = args[0]
153
+ }
154
+
155
+ len = 4
156
+ for (const buf of args) {
157
+ len += buf.byteLength ?? buf.length * 3
158
+ }
159
+
160
+ fn = (dst, data) => {
161
+ let pos = 0
162
+ for (const buf of data) {
163
+ if (typeof buf === 'string') {
164
+ pos += dst.write(buf, pos)
165
+ } else {
166
+ dst.set(buf, pos)
167
+ pos += buf.byteLength
168
+ }
169
+ }
170
+ return pos
171
+ }
172
+
173
+ opaque = args
174
+ }
175
+
176
+ if (!queue.length && tryWrite(len, fn, opaque)) {
168
177
  return
169
178
  }
170
179
 
171
- queue.push(Buffer.concat(raw))
180
+ const buf = Buffer.allocUnsafe(len)
181
+ queue.push(buf.subarray(0, fn(0, buf)))
172
182
 
173
- return (flushing ??= flush())
183
+ return flush()
174
184
  }
175
185
 
176
- write.acquireSync = acquireSync
177
- write.acquire = acquire
178
- write.release = release
186
+ write.write = write
179
187
  write.flush = flush
180
188
 
181
189
  return write
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/shared",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "Ring Buffer for NodeJS cross Worker communication",
5
5
  "main": "index.js",
6
6
  "repository": {