@sovereignbase/sequencer 1.0.2 → 1.1.1
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/INTERNALS.md +3 -3
- package/README.md +69 -54
- package/dist/index.cjs +91 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -6
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/INTERNALS.md
CHANGED
|
@@ -752,9 +752,9 @@ The application must exchange pending history before treating an acknowledgement
|
|
|
752
752
|
|
|
753
753
|
When all active Actors agree on the same frontier for a reducing Session, the acknowledged part can be removed from future retained Sequences.
|
|
754
754
|
|
|
755
|
-
This is whole-Session eligibility: every active Actor must report the same complete Session frontier. A missing claim or a different endpoint blocks that Session.
|
|
755
|
+
This is whole-Session eligibility: every active Actor must report the same complete Session frontier. A missing claim or a different endpoint blocks that Session.
|
|
756
756
|
|
|
757
|
-
Eligible masks must disappear from the exported Sequence. Wholly removed positive Insertions and deleted Footage disappear as well.
|
|
757
|
+
Eligible masks must disappear from the exported Sequence. Wholly removed positive Insertions and deleted Footage disappear as well. Acknowledgments of compacted Sessions are dropped, Actor membership is retained.
|
|
758
758
|
|
|
759
759
|
Suppose history contains:
|
|
760
760
|
|
|
@@ -794,7 +794,7 @@ The running Projection does not need to be rewritten when this happens. Compacti
|
|
|
794
794
|
|
|
795
795
|
The exported Sequence is a retained checkpoint. Its shorter Insertions and translated anchors can use different coordinates from the live graph before export. Continued editors must use compatible retained state; a compacted checkpoint does not preserve a permanent mapping to discarded history.
|
|
796
796
|
|
|
797
|
-
An offline Actor's unacknowledged history blocks compaction only if that Actor was registered.
|
|
797
|
+
An offline Actor's unacknowledged history blocks compaction only if that Actor was registered.
|
|
798
798
|
|
|
799
799
|
## Collapsed historical points
|
|
800
800
|
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
# Sequencer
|
|
8
8
|
|
|
9
|
-
Sequencer provides a
|
|
9
|
+
Sequencer provides a total order guarantee for distributed editing. It allows independently operating actors to make concurrent edits and eventually converge on the same state without relying on network arrival order or perfectly synchronized clocks.
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
@@ -15,16 +15,39 @@ Sequencer provides a deterministic total ordering for distributed data. It allow
|
|
|
15
15
|
```ts
|
|
16
16
|
import { Projection } from '@sovereignbase/sequencer'
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const projectionA = new Projection<string>(1)
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
console.log(projection.value(0)) // "Hello World"
|
|
22
|
-
const gossip1 = projection.replace(['Hello Dude'], 0, 0)
|
|
23
|
-
console.log(projection.value(0)) // "Hello Dude"
|
|
24
|
-
const gossip2 = projection.remove(0, 0)
|
|
25
|
-
console.log(projection.value(0)) // undefined
|
|
20
|
+
const projectionB = new Projection<string>(2)
|
|
26
21
|
|
|
27
|
-
|
|
22
|
+
const insertDelta = projectionA.insert(['Hello World'], 0)
|
|
23
|
+
console.log(projectionA.value(0)) // "Hello World"
|
|
24
|
+
|
|
25
|
+
projectionB.apply(insertDelta)
|
|
26
|
+
console.log(projectionB.value(0)) // "Hello World"
|
|
27
|
+
|
|
28
|
+
const replaceDelta = projectionA.replace(['Hello Dude'], 0, 0)
|
|
29
|
+
console.log(projectionA.value(0)) // "Hello Dude"
|
|
30
|
+
|
|
31
|
+
const replaceAcknowledgement = projectionB.apply(replaceDelta)
|
|
32
|
+
console.log(projectionB.value(0)) // "Hello Dude"
|
|
33
|
+
|
|
34
|
+
projectionA.apply(replaceAcknowledgement)
|
|
35
|
+
|
|
36
|
+
const removeDelta = projectionA.remove(0, 0)
|
|
37
|
+
console.log(projectionA.value(0)) // undefined
|
|
38
|
+
|
|
39
|
+
const removeAcknowledgement = projectionB.apply(removeDelta)
|
|
40
|
+
console.log(projectionB.value(0)) // undefined
|
|
41
|
+
|
|
42
|
+
projectionA.apply(removeAcknowledgement)
|
|
43
|
+
|
|
44
|
+
const serializable = projectionA.sequence()
|
|
45
|
+
|
|
46
|
+
const acknowledgements = projectionB.merge(serializable)
|
|
47
|
+
projectionA.apply(acknowledgements)
|
|
48
|
+
|
|
49
|
+
projectionA.destroy()
|
|
50
|
+
projectionB.destroy()
|
|
28
51
|
```
|
|
29
52
|
|
|
30
53
|
### See documentation
|
|
@@ -33,24 +56,16 @@ projection.destroy()
|
|
|
33
56
|
- [Typescript](https://sovereignbase.dev/sequencer/classes/Projection.html)
|
|
34
57
|
- [C++](https://sovereignbase.dev/sequencer/c++)
|
|
35
58
|
|
|
36
|
-
Register active Actors, including offline Actors, before removals. When every
|
|
37
|
-
active Actor acknowledges the same complete removal Session frontier,
|
|
38
|
-
`sequence()` omits its masks and deleted Footage. Actor membership remains.
|
|
39
|
-
See the [compaction contract](INTERNALS.md#compaction).
|
|
40
|
-
|
|
41
59
|
### Errors
|
|
42
60
|
|
|
43
|
-
Library-reported failures throw `SequencerError`, with a stable `SequencerErrorCode`
|
|
44
|
-
and a message prefixed with `{@sovereignbase/sequencer}`. Both are exported from
|
|
45
|
-
the package. The constructor accepts standard `ErrorOptions`, including `cause`.
|
|
46
|
-
|
|
47
61
|
| Code | Meaning |
|
|
48
62
|
| ------------------------- | ------------------------------------------------------------------- |
|
|
49
63
|
| `PROJECTION_DESTROYED` | An operation was called after the Projection was destroyed. |
|
|
50
64
|
| `NATIVE_OPERATION_FAILED` | The native runtime reported an initialization or operation failure. |
|
|
65
|
+
| `STRING_ENCODING_FAILED` | Snapshot Footage concatenation failed. |
|
|
66
|
+
| `UNKNOWN_ERROR` | All other errors. |
|
|
51
67
|
|
|
52
|
-
Invalid
|
|
53
|
-
Platform errors retain their original types.
|
|
68
|
+
Invalid input to `apply()` or `merge()` returns `undefined` instead of throwing.
|
|
54
69
|
|
|
55
70
|
## Benchmarks
|
|
56
71
|
|
|
@@ -58,8 +73,8 @@ Platform errors retain their original types.
|
|
|
58
73
|
|
|
59
74
|
| Format | Raw (KiB) | Minified (KiB) | Minified + gzip (KiB) |
|
|
60
75
|
| -------- | --------: | -------------: | --------------------: |
|
|
61
|
-
| ESM |
|
|
62
|
-
| CommonJS |
|
|
76
|
+
| ESM | 138.11 | 110.79 | 39.32 |
|
|
77
|
+
| CommonJS | 138.25 | 111.81 | 39.39 |
|
|
63
78
|
|
|
64
79
|
Both bundles include WASM. Terser uses three compression passes; gzip uses level 9.
|
|
65
80
|
|
|
@@ -72,37 +87,37 @@ Strips contain 1–100 Frames (visible entries). Headers show Strip counts and m
|
|
|
72
87
|
|
|
73
88
|
| Method / case | 1,000 Strips<br>50,871 Frames | 5,000 Strips<br>252,214 Frames | 10,000 Strips<br>504,871 Frames | 15,000 Strips<br>758,280 Frames | 20,000 Strips<br>1,010,749 Frames | 25,000 Strips<br>1,264,003 Frames |
|
|
74
89
|
| -------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: |
|
|
75
|
-
| apply.random |
|
|
76
|
-
| insert.head | 1,
|
|
77
|
-
| insert.random |
|
|
78
|
-
| insert.tail | 1,
|
|
90
|
+
| apply.random | 168,988 | 83,955 | 61,650 | 47,049 | 38,583 | 32,071 |
|
|
91
|
+
| insert.head | 1,206,471 | 1,005,683 | 1,120,929 | 1,152,814 | 1,182,905 | 1,200,605 |
|
|
92
|
+
| insert.random | 478,940 | 239,168 | 162,373 | 122,729 | 98,990 | 81,755 |
|
|
93
|
+
| insert.tail | 1,334,433 | 1,104,239 | 1,256,494 | 1,303,969 | 1,339,136 | 1,349,061 |
|
|
79
94
|
| remove.head | — | — | — | — | — | — |
|
|
80
|
-
| remove.random |
|
|
95
|
+
| remove.random | 341,765 | 165,565 | 113,075 | 83,800 | 67,429 | 55,746 |
|
|
81
96
|
| remove.tail | — | — | — | — | — | — |
|
|
82
|
-
| replace.head |
|
|
83
|
-
| replace.random |
|
|
84
|
-
| replace.tail |
|
|
85
|
-
| value.head | 2,
|
|
86
|
-
| value.random |
|
|
87
|
-
| value.tail | 5,
|
|
97
|
+
| replace.head | 434,921 | 413,737 | 437,844 | 440,051 | 452,138 | 445,770 |
|
|
98
|
+
| replace.random | 289,668 | 153,680 | 102,130 | 77,675 | 63,528 | 53,108 |
|
|
99
|
+
| replace.tail | 378,410 | 435,943 | 470,911 | 489,325 | 467,618 | 465,423 |
|
|
100
|
+
| value.head | 2,248,956 | 3,197,040 | 3,540,159 | 3,716,627 | 3,920,698 | 3,991,212 |
|
|
101
|
+
| value.random | 723,289 | 231,174 | 138,597 | 96,795 | 75,674 | 61,147 |
|
|
102
|
+
| value.tail | 5,010,118 | 5,355,455 | 5,275,683 | 5,289,080 | 5,356,586 | 5,294,392 |
|
|
88
103
|
|
|
89
104
|
**↓ Scale down (25,000 → 0 Strips)**
|
|
90
105
|
|
|
91
106
|
| Method / case | 20,000 Strips<br>1,012,742 Frames | 15,000 Strips<br>755,860 Frames | 10,000 Strips<br>504,103 Frames | 5,000 Strips<br>251,203 Frames | 1,000 Strips<br>51,057 Frames | 0 Strips<br>0 Frames |
|
|
92
107
|
| -------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
|
|
93
|
-
| apply.random |
|
|
108
|
+
| apply.random | 20,767 | 21,129 | 21,221 | 21,621 | 22,254 | 22,548 |
|
|
94
109
|
| insert.head | — | — | — | — | — | — |
|
|
95
|
-
| insert.random |
|
|
110
|
+
| insert.random | 49,291 | 50,341 | 51,237 | 51,902 | 53,706 | 53,811 |
|
|
96
111
|
| insert.tail | — | — | — | — | — | — |
|
|
97
|
-
| remove.head |
|
|
98
|
-
| remove.random |
|
|
99
|
-
| remove.tail |
|
|
100
|
-
| replace.head |
|
|
101
|
-
| replace.random |
|
|
102
|
-
| replace.tail |
|
|
103
|
-
| value.head |
|
|
104
|
-
| value.random |
|
|
105
|
-
| value.tail |
|
|
112
|
+
| remove.head | 609,754 | 609,062 | 614,121 | 617,274 | 622,099 | 624,577 |
|
|
113
|
+
| remove.random | 35,772 | 36,882 | 38,342 | 40,067 | 41,973 | 42,560 |
|
|
114
|
+
| remove.tail | 596,805 | 587,004 | 596,862 | 604,122 | 610,763 | 504,986 |
|
|
115
|
+
| replace.head | 423,126 | 383,070 | 388,964 | 374,385 | 371,780 | 311,835 |
|
|
116
|
+
| replace.random | 34,738 | 36,411 | 37,348 | 39,079 | 40,869 | 40,848 |
|
|
117
|
+
| replace.tail | 227,897 | 198,045 | 194,265 | 184,618 | 184,097 | 170,615 |
|
|
118
|
+
| value.head | 2,076,382 | 1,986,100 | 1,933,034 | 1,933,944 | 1,982,144 | 2,003,444 |
|
|
119
|
+
| value.random | 38,599 | 39,752 | 41,093 | 42,883 | 44,849 | 45,853 |
|
|
120
|
+
| value.tail | 2,349,312 | 2,266,890 | 2,232,286 | 2,259,013 | 2,327,296 | 2,364,396 |
|
|
106
121
|
|
|
107
122
|
### API throughput at checkpoint
|
|
108
123
|
|
|
@@ -112,17 +127,17 @@ Checkpoint calls, in ops/s, averaged across runs.
|
|
|
112
127
|
|
|
113
128
|
| Method | 1,000 Strips<br>50,871 Frames | 5,000 Strips<br>252,214 Frames | 10,000 Strips<br>504,871 Frames | 15,000 Strips<br>758,280 Frames | 20,000 Strips<br>1,010,749 Frames | 25,000 Strips<br>1,264,003 Frames |
|
|
114
129
|
| --------------------------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: |
|
|
115
|
-
| new Projection(actorID, sequence) |
|
|
116
|
-
| sequence() |
|
|
117
|
-
| values() |
|
|
130
|
+
| new Projection(actorID, sequence) | 4,586 | 948 | 590 | 417 | 290 | 240 |
|
|
131
|
+
| sequence() | 520 | 96 | 55 | 30 | 24 | 18 |
|
|
132
|
+
| values() | 555 | 226 | 57 | 79 | 29 | 54 |
|
|
118
133
|
|
|
119
134
|
**↓ Scale down (25,000 → 0 Strips)**
|
|
120
135
|
|
|
121
136
|
| Method | 20,000 Strips<br>1,012,742 Frames | 15,000 Strips<br>755,860 Frames | 10,000 Strips<br>504,103 Frames | 5,000 Strips<br>251,203 Frames | 1,000 Strips<br>51,057 Frames | 0 Strips<br>0 Frames |
|
|
122
137
|
| --------------------------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
|
|
123
|
-
| new Projection(actorID, sequence) | 284 |
|
|
124
|
-
| sequence() |
|
|
125
|
-
| values() |
|
|
138
|
+
| new Projection(actorID, sequence) | 284 | 414 | 493 | 1,276 | 5,419 | 21,553 |
|
|
139
|
+
| sequence() | 16 | 14 | 10 | 10 | 9 | 8 |
|
|
140
|
+
| values() | 63 | 34 | 79 | 82 | 209 | 109,439 |
|
|
126
141
|
|
|
127
142
|
### Sequence disk size at checkpoint
|
|
128
143
|
|
|
@@ -133,7 +148,7 @@ Complete exported Sequences, including Footage and acknowledgements. Sizes are i
|
|
|
133
148
|
| Encoding | 1,000 Strips<br>50,871 Frames | 5,000 Strips<br>252,214 Frames | 10,000 Strips<br>504,871 Frames | 15,000 Strips<br>758,280 Frames | 20,000 Strips<br>1,010,749 Frames | 25,000 Strips<br>1,264,003 Frames |
|
|
134
149
|
| ------------------ | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: |
|
|
135
150
|
| JSON | 277.41 | 1,622.78 | 3,264.00 | 4,904.44 | 7,045.81 | 9,168.42 |
|
|
136
|
-
| JSON + gzip | 14.
|
|
151
|
+
| JSON + gzip | 14.60 | 73.84 | 150.39 | 226.88 | 311.17 | 391.65 |
|
|
137
152
|
| MessagePack | 164.81 | 818.88 | 1,639.69 | 3,529.41 | 5,081.04 | 6,483.22 |
|
|
138
153
|
| MessagePack + gzip | 12.38 | 61.62 | 124.91 | 198.59 | 263.54 | 332.77 |
|
|
139
154
|
|
|
@@ -142,7 +157,7 @@ Complete exported Sequences, including Footage and acknowledgements. Sizes are i
|
|
|
142
157
|
| Encoding | 20,000 Strips<br>1,012,742 Frames | 15,000 Strips<br>755,860 Frames | 10,000 Strips<br>504,103 Frames | 5,000 Strips<br>251,203 Frames | 1,000 Strips<br>51,057 Frames | 0 Strips<br>0 Frames |
|
|
143
158
|
| ------------------ | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
|
|
144
159
|
| JSON | 7,451.86 | 5,621.57 | 3,772.57 | 1,886.91 | 383.51 | 0.02 |
|
|
145
|
-
| JSON + gzip | 323.
|
|
160
|
+
| JSON + gzip | 323.17 | 244.37 | 163.86 | 80.61 | 16.34 | 0.03 |
|
|
146
161
|
| MessagePack | 5,237.17 | 3,930.33 | 2,628.38 | 1,312.43 | 266.67 | 0.01 |
|
|
147
162
|
| MessagePack + gzip | 274.96 | 207.78 | 137.38 | 67.41 | 13.67 | 0.03 |
|
|
148
163
|
|
|
@@ -162,7 +177,7 @@ One instance: WASM memory plus retained JS array slots, in KiB (1,024 bytes).
|
|
|
162
177
|
| ---------------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
|
|
163
178
|
| Estimated memory (KiB) | 163,746.93 | 174,034.00 | 202,660.72 | 293,941.85 | 302,158.29 | 304,203.30 |
|
|
164
179
|
|
|
165
|
-
Measured on Node 24.
|
|
180
|
+
Measured on Node 24.21.0, V8 13.6.233.17-node.53,
|
|
166
181
|
linux x64, AMD EPYC 7763 64-Core Processor.
|
|
167
182
|
Peer synchronization, encoding and JS process garbage collection are outside API timings.
|
|
168
183
|
[Full lifecycle results](benchmark/.results/lifecycle.md) · [Throughput results](benchmark/.results/throughput.md).
|
|
@@ -171,7 +186,7 @@ Peer synchronization, encoding and JS process garbage collection are outside API
|
|
|
171
186
|
|
|
172
187
|
### Behaviour guaranteed by excessive tests
|
|
173
188
|
|
|
174
|
-
The latest verification passed
|
|
189
|
+
The latest verification passed 249 Vitest tests and 117 compatibility checks.
|
|
175
190
|
The configured 100% coverage threshold is met (100% statements, 100% branches, 100% functions, 100% lines).
|
|
176
191
|
See the [test suites](test/README.md) and
|
|
177
192
|
[automated test report](https://sovereignbase.dev/sequencer/tests/).
|
package/dist/index.cjs
CHANGED
|
@@ -332,6 +332,11 @@ var Runtime = class {
|
|
|
332
332
|
const heap = module$1.HEAPU32;
|
|
333
333
|
return this.content[id][heap[pointer]]?.[heap[pointer + 1]];
|
|
334
334
|
}
|
|
335
|
+
/** Exports native spans directly, with optional string Footage assembled in JavaScript. */
|
|
336
|
+
sequence(id, stringEncode) {
|
|
337
|
+
if (id < 0) throw new SequencerError("PROJECTION_DESTROYED", "Projection has been destroyed.");
|
|
338
|
+
return this.result(Operation.Sequence, id, module$1._runtime_dispatch(Operation.Sequence, id, 0, 0, 0, 0, 0), stringEncode);
|
|
339
|
+
}
|
|
335
340
|
/** Authors trusted local Frames through the dedicated six-word result path. */
|
|
336
341
|
insert(id, values, at) {
|
|
337
342
|
if (id < 0) throw new SequencerError("PROJECTION_DESTROYED", "Projection has been destroyed.");
|
|
@@ -449,16 +454,16 @@ var Runtime = class {
|
|
|
449
454
|
a0 = value ?? absent;
|
|
450
455
|
a1 = at ?? absent;
|
|
451
456
|
} else if (operation === Operation.Retire) a0 = value;
|
|
452
|
-
else
|
|
457
|
+
else {
|
|
453
458
|
a0 = operation === Operation.Create ? value : 0;
|
|
454
459
|
const sequence = operation === Operation.Create ? at : value;
|
|
455
|
-
const valid = operation === Operation.Create && sequence === void 0 || Array.isArray(sequence) && sequence.length === 2 && (Array.isArray(sequence[0]) || sequence[0] instanceof Uint32Array) && Array.isArray(sequence[1]) && (operation === Operation.Create || sequence[0] instanceof Uint32Array || sequence[0].every((word) => Number.isInteger(word) && word >= 0 && word <= absent));
|
|
460
|
+
const valid = operation === Operation.Create && sequence === void 0 || Array.isArray(sequence) && sequence.length === 2 && (Array.isArray(sequence[0]) || sequence[0] instanceof Uint32Array) && (Array.isArray(sequence[1]) || typeof sequence[1] === "string") && (operation === Operation.Create || sequence[0] instanceof Uint32Array || sequence[0].every((word) => Number.isInteger(word) && word >= 0 && word <= absent));
|
|
456
461
|
a2 = valid ? 1 : 0;
|
|
457
462
|
if (valid && sequence !== void 0) {
|
|
458
463
|
const words = sequence[0];
|
|
459
464
|
heap.set(words, base);
|
|
460
465
|
a1 = contents.length;
|
|
461
|
-
footage = sequence[1];
|
|
466
|
+
footage = typeof sequence[1] === "string" ? sequence[1].split("") : sequence[1];
|
|
462
467
|
}
|
|
463
468
|
}
|
|
464
469
|
const resultPointer = module$1._runtime_dispatch(operation, id, a0, a1, a2, pointer, count);
|
|
@@ -472,7 +477,7 @@ var Runtime = class {
|
|
|
472
477
|
return this.result(operation, id, resultPointer);
|
|
473
478
|
}
|
|
474
479
|
/** Consumes borrowed native output before another call may overwrite its storage. */
|
|
475
|
-
result(operation, id, pointer) {
|
|
480
|
+
result(operation, id, pointer, stringEncode) {
|
|
476
481
|
const heap = module$1.HEAPU32, header = pointer >>> 2, content = this.content[id];
|
|
477
482
|
const kind = heap[header], p0 = heap[header + 3], n0 = heap[header + 4], p1 = heap[header + 5], n1 = heap[header + 6];
|
|
478
483
|
const mutable = this.mutable[id];
|
|
@@ -589,6 +594,22 @@ var Runtime = class {
|
|
|
589
594
|
metadata.length = n0;
|
|
590
595
|
for (let i = 0, at = p0 >>> 2; i < n0; ++i) metadata[i] = heap[at + i];
|
|
591
596
|
} else metadata = words(p0, n0);
|
|
597
|
+
if (stringEncode) {
|
|
598
|
+
let text = "";
|
|
599
|
+
try {
|
|
600
|
+
for (let at = p1 >>> 2, end = at + n1 * 3; at < end; at += 3) {
|
|
601
|
+
const source = content[heap[at]], start = heap[at + 1], count = heap[at + 2];
|
|
602
|
+
for (let i = 0; i < count; ++i) {
|
|
603
|
+
const value = source?.[start + i];
|
|
604
|
+
text += value === void 0 ? "\0" : value;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
} catch (cause) {
|
|
608
|
+
throw new SequencerError("STRING_ENCODING_FAILED", "Sequence Footage could not be encoded as a string.", { cause });
|
|
609
|
+
}
|
|
610
|
+
result = [metadata, text];
|
|
611
|
+
break;
|
|
612
|
+
}
|
|
592
613
|
const span = p1 >>> 2, token = heap[span];
|
|
593
614
|
const shared = n1 === 1 && heap[span + 1] === 0 && content[token]?.length === heap[span + 2] && !!mutable[token];
|
|
594
615
|
if (shared && mutable[token] !== 3) {
|
|
@@ -657,12 +678,16 @@ var Projection = class {
|
|
|
657
678
|
* Prepares to sequence a projection, optionally hydrating from a trusted sequence stored by the application.
|
|
658
679
|
*
|
|
659
680
|
* @param actorID Actor identifier used in acknowledgements.
|
|
660
|
-
* @param trustedSequence Optional trusted Sequence in Structural Order
|
|
681
|
+
* @param trustedSequence Optional trusted Sequence in Structural Order; string Footage is split into UTF-16 code units.
|
|
661
682
|
* @throws {@link SequencerError} if native initialization fails.
|
|
662
683
|
*/
|
|
663
684
|
constructor(actorID, trustedSequence) {
|
|
664
685
|
this.actorID = actorID;
|
|
665
|
-
|
|
686
|
+
try {
|
|
687
|
+
this.id = runtime.create(this, actorID, trustedSequence);
|
|
688
|
+
} catch (cause) {
|
|
689
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.constructor() failed.", { cause });
|
|
690
|
+
}
|
|
666
691
|
}
|
|
667
692
|
/**
|
|
668
693
|
* Applies gossiped Insertions and Acknowledgements.
|
|
@@ -673,7 +698,11 @@ var Projection = class {
|
|
|
673
698
|
* @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
|
|
674
699
|
*/
|
|
675
700
|
apply(gossip) {
|
|
676
|
-
|
|
701
|
+
try {
|
|
702
|
+
return runtime.apply(this.id, gossip);
|
|
703
|
+
} catch (cause) {
|
|
704
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.apply() failed.", { cause });
|
|
705
|
+
}
|
|
677
706
|
}
|
|
678
707
|
/**
|
|
679
708
|
* Inserts values at a Projection position.
|
|
@@ -684,7 +713,11 @@ var Projection = class {
|
|
|
684
713
|
* @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
|
|
685
714
|
*/
|
|
686
715
|
insert(values, at) {
|
|
687
|
-
|
|
716
|
+
try {
|
|
717
|
+
return runtime.insert(this.id, values, at);
|
|
718
|
+
} catch (cause) {
|
|
719
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.insert() failed.", { cause });
|
|
720
|
+
}
|
|
688
721
|
}
|
|
689
722
|
/**
|
|
690
723
|
* Returns the length, A.K.A. amount of entries of this projection.
|
|
@@ -693,7 +726,11 @@ var Projection = class {
|
|
|
693
726
|
* @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
|
|
694
727
|
*/
|
|
695
728
|
length() {
|
|
696
|
-
|
|
729
|
+
try {
|
|
730
|
+
return runtime.length(this.id);
|
|
731
|
+
} catch (cause) {
|
|
732
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.length() failed.", { cause });
|
|
733
|
+
}
|
|
697
734
|
}
|
|
698
735
|
/**
|
|
699
736
|
* Applies relevant acknowledgements and nonduplicate insertions from a replica of the sequence.
|
|
@@ -704,7 +741,11 @@ var Projection = class {
|
|
|
704
741
|
* @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
|
|
705
742
|
*/
|
|
706
743
|
merge(sequence) {
|
|
707
|
-
|
|
744
|
+
try {
|
|
745
|
+
return runtime.call(Operation.Merge, this.id, sequence);
|
|
746
|
+
} catch (cause) {
|
|
747
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.merge() failed.", { cause });
|
|
748
|
+
}
|
|
708
749
|
}
|
|
709
750
|
/**
|
|
710
751
|
* Removes an inclusive range of Projection positions.
|
|
@@ -715,7 +756,11 @@ var Projection = class {
|
|
|
715
756
|
* @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
|
|
716
757
|
*/
|
|
717
758
|
remove(startAt, endWith) {
|
|
718
|
-
|
|
759
|
+
try {
|
|
760
|
+
return runtime.call(Operation.Remove, this.id, startAt, endWith);
|
|
761
|
+
} catch (cause) {
|
|
762
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.remove() failed.", { cause });
|
|
763
|
+
}
|
|
719
764
|
}
|
|
720
765
|
/**
|
|
721
766
|
* Replaces an inclusive range of Projection positions.
|
|
@@ -727,7 +772,11 @@ var Projection = class {
|
|
|
727
772
|
* @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
|
|
728
773
|
*/
|
|
729
774
|
replace(withValues, startAt, endWith) {
|
|
730
|
-
|
|
775
|
+
try {
|
|
776
|
+
return runtime.call(Operation.Replace, this.id, withValues, startAt, endWith);
|
|
777
|
+
} catch (cause) {
|
|
778
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.replace() failed.", { cause });
|
|
779
|
+
}
|
|
731
780
|
}
|
|
732
781
|
/**
|
|
733
782
|
* Retires an Actor from future compaction requirements.
|
|
@@ -740,7 +789,11 @@ var Projection = class {
|
|
|
740
789
|
* @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
|
|
741
790
|
*/
|
|
742
791
|
retire(actorID) {
|
|
743
|
-
|
|
792
|
+
try {
|
|
793
|
+
return runtime.call(Operation.Retire, this.id, actorID);
|
|
794
|
+
} catch (cause) {
|
|
795
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.retire() failed.", { cause });
|
|
796
|
+
}
|
|
744
797
|
}
|
|
745
798
|
/**
|
|
746
799
|
* Sequences state into a compact serializable format.
|
|
@@ -750,11 +803,17 @@ var Projection = class {
|
|
|
750
803
|
* permit masks and deleted Footage to be omitted from the retained checkpoint.
|
|
751
804
|
* Compaction may translate retained anchors without rewriting this instance.
|
|
752
805
|
*
|
|
806
|
+
* @param stringEncode Whether to concatenate Footage into a string; each text Frame must be one UTF-16 code unit. Defaults to `false`.
|
|
753
807
|
* @returns A Sequence with acknowledged removals compacted in the exported state.
|
|
754
808
|
* @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
|
|
809
|
+
* @throws {@link SequencerError} with code `STRING_ENCODING_FAILED` if Footage concatenation fails.
|
|
755
810
|
*/
|
|
756
|
-
sequence() {
|
|
757
|
-
|
|
811
|
+
sequence(stringEncode) {
|
|
812
|
+
try {
|
|
813
|
+
return runtime.sequence(this.id, stringEncode);
|
|
814
|
+
} catch (cause) {
|
|
815
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.sequence() failed.", { cause });
|
|
816
|
+
}
|
|
758
817
|
}
|
|
759
818
|
/**
|
|
760
819
|
* Returns the value at a Projection position.
|
|
@@ -764,7 +823,11 @@ var Projection = class {
|
|
|
764
823
|
* @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
|
|
765
824
|
*/
|
|
766
825
|
value(at) {
|
|
767
|
-
|
|
826
|
+
try {
|
|
827
|
+
return runtime.value(this.id, at);
|
|
828
|
+
} catch (cause) {
|
|
829
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.value() failed.", { cause });
|
|
830
|
+
}
|
|
768
831
|
}
|
|
769
832
|
/**
|
|
770
833
|
* Returns values from an inclusive range of Projection positions.
|
|
@@ -775,13 +838,21 @@ var Projection = class {
|
|
|
775
838
|
* @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
|
|
776
839
|
*/
|
|
777
840
|
values(startAt, endWith) {
|
|
778
|
-
|
|
841
|
+
try {
|
|
842
|
+
return runtime.call(Operation.Values, this.id, startAt, endWith);
|
|
843
|
+
} catch (cause) {
|
|
844
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.values() failed.", { cause });
|
|
845
|
+
}
|
|
779
846
|
}
|
|
780
847
|
/** Destroys the Projection. Repeated calls have no effect. */
|
|
781
848
|
destroy() {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
849
|
+
try {
|
|
850
|
+
if (this.id < 0) return;
|
|
851
|
+
runtime.destroy(this, this.id);
|
|
852
|
+
this.id = -1;
|
|
853
|
+
} catch (cause) {
|
|
854
|
+
throw cause instanceof SequencerError ? cause : new SequencerError("UNKNOWN_ERROR", "Projection.destroy() failed.", { cause });
|
|
855
|
+
}
|
|
785
856
|
}
|
|
786
857
|
};
|
|
787
858
|
//#endregion
|