@nxtedition/lib 19.3.6 → 19.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/package.json +2 -1
  2. package/sequence.js +71 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxtedition/lib",
3
- "version": "19.3.6",
3
+ "version": "19.4.0",
4
4
  "license": "MIT",
5
5
  "author": "Robert Nagy <robert.nagy@boffins.se>",
6
6
  "type": "module",
@@ -18,6 +18,7 @@
18
18
  "http.js",
19
19
  "s3.js",
20
20
  "deepstream.js",
21
+ "sequence.js",
21
22
  "logger.js",
22
23
  "mime.js",
23
24
  "proxy.js",
package/sequence.js ADDED
@@ -0,0 +1,71 @@
1
+ import assert from 'node:assert'
2
+
3
+ export const ID_SEP = '~'
4
+
5
+ export class Sequence {
6
+ #value
7
+ #parts = []
8
+
9
+ constructor(value) {
10
+ try {
11
+ if (Array.isArray(value)) {
12
+ for (const part of value) {
13
+ if (typeof part === 'string') {
14
+ const [sequenceStr, id] = part.split(ID_SEP)
15
+ const sequence = parseInt(sequenceStr)
16
+ assert(Number.isFinite(sequence) && sequence >= 0)
17
+ this.#parts.push(id, sequence)
18
+ } else {
19
+ assert(Number.isFinite(part.sequence) && part.sequence >= 0)
20
+ assert(typeof part.id === 'string' && part.id.length > 0)
21
+ this.#parts.push(part.id, part.sequence)
22
+ }
23
+ }
24
+ } else if (typeof value === 'string') {
25
+ const [countStr, token] = value.split('-')
26
+ const count = parseInt(countStr)
27
+ assert(Number.isFinite(count) && count >= 0)
28
+ for (const str of token.split('_')) {
29
+ const [sequenceStr, id] = str.split(ID_SEP)
30
+ const sequence = parseInt(sequenceStr)
31
+ assert(Number.isFinite(sequence) && sequence >= 0)
32
+ this.#parts.push(id, sequence)
33
+ }
34
+ this.#value = value
35
+ } else {
36
+ assert(false)
37
+ }
38
+ } catch (err) {
39
+ throw Object.assign(new Error('Invalid sequence value'), { cause: err, data: value })
40
+ }
41
+ }
42
+
43
+ get length() {
44
+ return this.#parts.length / 2
45
+ }
46
+
47
+ at(index) {
48
+ assert(Number.isFinite(index) && index >= 0 && index * 2 < this.#parts.length)
49
+ return this.#parts[index * 2 + 1]
50
+ }
51
+
52
+ set(index, sequence) {
53
+ assert(Number.isFinite(index) && index >= 0 && index < this.#parts.length)
54
+ assert(Number.isFinite(sequence) && sequence >= 0)
55
+ this.#parts[index * 2 + 1] = sequence
56
+ this.#value = undefined
57
+ }
58
+
59
+ toString() {
60
+ if (!this.#value) {
61
+ let count = 0
62
+ let token = ''
63
+ for (let n = 0; n < this.#parts.length; n += 2) {
64
+ count += this.#parts[n + 1]
65
+ token += (n === 0 ? '-' : '_') + this.#parts[n + 1] + ID_SEP + this.#parts[n]
66
+ }
67
+ this.#value = String(count) + token
68
+ }
69
+ return this.#value
70
+ }
71
+ }