@nxtedition/lib 28.0.3 → 28.0.6

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 (3) hide show
  1. package/package.json +2 -2
  2. package/sequence.js +102 -13
  3. package/slice.js +16 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "28.0.3",
3
+ "version": "28.0.6",
4
4
  "license": "UNLICENSED",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
@@ -92,5 +92,5 @@
92
92
  "pino": ">=7.0.0",
93
93
  "rxjs": "^7.0.0"
94
94
  },
95
- "gitHead": "15f4fd00f86a558ae56672b1efa3e909b23feb3f"
95
+ "gitHead": "008526f8d31968edaa2e642998deaa3880a34bb8"
96
96
  }
package/sequence.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import assert from 'node:assert'
2
+ import util from 'node:util'
2
3
 
3
4
  export const ID_SEP = '~'
4
5
 
@@ -25,14 +26,14 @@ export class Sequence {
25
26
  #identity
26
27
  #count = 0
27
28
 
28
- // TODO (perf): Optimize
29
29
  /**
30
30
  *
31
31
  * @param {string|Sequence|null|undefined} a
32
32
  * @param {string|Sequence|null|undefined} b
33
33
  * @param {boolean} [strict=true]
34
- * @returns
34
+ * @returns {-1|0|1}
35
35
  */
36
+ /** @deprecated */
36
37
  static compare(a, b, strict) {
37
38
  if (!a && !b) {
38
39
  return 0
@@ -46,17 +47,28 @@ export class Sequence {
46
47
  return -1
47
48
  }
48
49
 
49
- if (a && typeof a === 'string') {
50
- a = new Sequence(a)
50
+ if (a === b) {
51
+ return 0
51
52
  }
52
53
 
53
- if (typeof b === 'string') {
54
- b = new Sequence(b)
54
+ if (typeof a === 'string') {
55
+ a = new Sequence(a)
55
56
  }
56
57
 
57
58
  return a.compare(b, strict)
58
59
  }
59
60
 
61
+ /**
62
+ *
63
+ * @param {string|Sequence|null|undefined} a
64
+ * @param {string|Sequence|null|undefined} b
65
+ * @param {boolean} [strict=true]
66
+ * @returns {boolean}
67
+ */
68
+ static has(a, b, strict) {
69
+ return Sequence.compare(a, b, strict) >= 0
70
+ }
71
+
60
72
  /**
61
73
  *
62
74
  * @param {string} seq
@@ -74,6 +86,10 @@ export class Sequence {
74
86
  }
75
87
  }
76
88
 
89
+ /**
90
+ * @param {null|undefined|string|Sequence|Array<string|number|{id:string,sequence:number}>>} value
91
+ * @param {null|undefined|number|Array<string|{id:string}>>} [identity]
92
+ */
77
93
  constructor(value, identity) {
78
94
  try {
79
95
  if (!value) {
@@ -173,6 +189,9 @@ export class Sequence {
173
189
  }
174
190
  }
175
191
 
192
+ /**
193
+ * @returns {number}
194
+ */
176
195
  get identity() {
177
196
  if (this.#identity == null) {
178
197
  if (this.#parts.length === 0) {
@@ -189,6 +208,9 @@ export class Sequence {
189
208
  return this.#identity
190
209
  }
191
210
 
211
+ /**
212
+ * @returns {number}
213
+ */
192
214
  get count() {
193
215
  if (this.#count == null) {
194
216
  let count = 0
@@ -200,18 +222,45 @@ export class Sequence {
200
222
  return this.#count
201
223
  }
202
224
 
225
+ /**
226
+ * @returns {number}
227
+ */
203
228
  get length() {
204
229
  return this.#parts.length / 2
205
230
  }
206
231
 
232
+ /**
233
+ * @param {number} index
234
+ * @returns {number}
235
+ */
207
236
  at(index) {
208
- assert(Number.isFinite(index) && index >= 0 && index * 2 < this.#parts.length)
237
+ if (!Number.isInteger(index)) {
238
+ throw new TypeError('index must be an integer')
239
+ }
240
+ if (index < 0 || index >= this.#parts.length / 2) {
241
+ throw new RangeError('index out of range')
242
+ }
243
+
209
244
  return this.#parts[index * 2 + 1]
210
245
  }
211
246
 
247
+ /**
248
+ * @param {number} index
249
+ * @param {number} sequence
250
+ */
212
251
  set(index, sequence) {
213
- assert(Number.isFinite(index) && index >= 0 && index < this.#parts.length)
214
- assert(Number.isFinite(sequence) && sequence >= 0)
252
+ if (!Number.isInteger(index)) {
253
+ throw new TypeError('index must be an integer')
254
+ }
255
+ if (index < 0 || index >= this.#parts.length / 2) {
256
+ throw new RangeError('index out of range')
257
+ }
258
+ if (!Number.isInteger(sequence)) {
259
+ throw new TypeError('sequence must be an integer')
260
+ }
261
+ if (sequence < 0) {
262
+ throw new RangeError('sequence must be non-negative')
263
+ }
215
264
  if (this.#parts[index * 2 + 1] !== sequence) {
216
265
  this.#parts[index * 2 + 1] = sequence
217
266
  this.#value = ''
@@ -219,16 +268,29 @@ export class Sequence {
219
268
  }
220
269
  }
221
270
 
271
+ /** @deprecated */
222
272
  compare(other, strict) {
223
273
  if (strict === undefined) {
224
274
  strict = true
225
275
  }
226
276
 
227
- assert(other instanceof Sequence)
228
- assert(typeof strict === 'boolean')
277
+ if (typeof other === 'string') {
278
+ if (this.#value && this.#value === other) {
279
+ return 0
280
+ }
281
+ other = new Sequence(other)
282
+ }
229
283
 
230
- if (strict && other.identity && this.identity) {
231
- assert.strictEqual(other.identity, this.identity)
284
+ if (!(other instanceof Sequence)) {
285
+ throw new TypeError('Can only compare with another Sequence')
286
+ }
287
+
288
+ if (typeof strict !== 'boolean') {
289
+ throw new TypeError('strict must be a boolean')
290
+ }
291
+
292
+ if (strict && (other.identity || this.identity) && other.identity !== this.identity) {
293
+ throw new Error('Cannot compare sequences with different identities')
232
294
  }
233
295
 
234
296
  if (this.#parts.length !== other.#parts.length) {
@@ -244,6 +306,19 @@ export class Sequence {
244
306
  return 0
245
307
  }
246
308
 
309
+ /**
310
+ *
311
+ * @param {string|Sequence|null|undefined} other
312
+ * @param {boolean} [strict=true]
313
+ * @returns {boolean}
314
+ */
315
+ has(other, strict = true) {
316
+ return this.compare(other, strict) >= 0
317
+ }
318
+
319
+ /**
320
+ * @returns {string}
321
+ */
247
322
  toString() {
248
323
  if (!this.#value) {
249
324
  let count = 0
@@ -256,4 +331,18 @@ export class Sequence {
256
331
  }
257
332
  return this.#value
258
333
  }
334
+
335
+ /**
336
+ * @returns {string}
337
+ */
338
+ [Symbol.toStringTag]() {
339
+ return this.toString()
340
+ }
341
+
342
+ /**
343
+ * @returns {string}
344
+ */
345
+ [util.inspect.custom](depth, options, inspect) {
346
+ return `Sequence: "${this.toString()}"`
347
+ }
259
348
  }
package/slice.js CHANGED
@@ -60,6 +60,22 @@ export class Slice {
60
60
  maxByteLength = byteLength
61
61
  }
62
62
 
63
+ if (byteOffset < 0) {
64
+ throw new RangeError('byteOffset must be non-negative')
65
+ }
66
+
67
+ if (byteLength < 0) {
68
+ throw new RangeError('byteLength must be non-negative')
69
+ }
70
+
71
+ if (byteLength > maxByteLength) {
72
+ throw new RangeError('byteLength cannot be greater than maxByteLength')
73
+ }
74
+
75
+ if (byteOffset + maxByteLength > buffer.byteLength) {
76
+ throw new RangeError('Slice exceeds buffer length')
77
+ }
78
+
63
79
  const slice = POOL.pop()
64
80
 
65
81
  if (slice) {