@sovereignbase/sequencer 1.1.0 → 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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  # Sequencer
8
8
 
9
- Sequencer provides a deterministic total ordering for distributed data. It allows independently operating actors to make concurrent changes and eventually converge on the same state without relying on network arrival order or perfectly synchronized clocks.
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,21 +15,40 @@ 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 projection = new Projection<string>(1)
18
+ const projectionA = new Projection<string>(1)
19
19
 
20
- const gossip0 = projection.insert(['Hello World'], 0)
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
- projection.destroy()
28
- ```
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
29
38
 
30
- For text stored as UTF-16 code units, `projection.sequence(true)` returns string
31
- Footage. Construction and merge accept either form; `sequence()` keeps array
32
- Footage. See [Projection.sequence](https://sovereignbase.dev/sequencer/classes/Projection.html#sequence).
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()
51
+ ```
33
52
 
34
53
  ### See documentation
35
54
 
@@ -39,18 +58,14 @@ Footage. See [Projection.sequence](https://sovereignbase.dev/sequencer/classes/P
39
58
 
40
59
  ### Errors
41
60
 
42
- Library-reported failures throw `SequencerError`, with a stable `SequencerErrorCode`
43
- and a message prefixed with `{@sovereignbase/sequencer}`. Both are exported from
44
- the package. The constructor accepts standard `ErrorOptions`, including `cause`.
45
-
46
- | Code | Meaning |
47
- | ------------------------- | ---------------------------------------------------------------------------- |
48
- | `PROJECTION_DESTROYED` | An operation was called after the Projection was destroyed. |
49
- | `NATIVE_OPERATION_FAILED` | The native runtime reported an initialization or operation failure. |
50
- | `STRING_ENCODING_FAILED` | Snapshot Footage concatenation failed; `cause` preserves the original error. |
61
+ | Code | Meaning |
62
+ | ------------------------- | ------------------------------------------------------------------- |
63
+ | `PROJECTION_DESTROYED` | An operation was called after the Projection was destroyed. |
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 Gossip or Sequence input to `apply()` or `merge()` returns `undefined`.
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 | 136.19 | 109.61 | 39.20 |
62
- | CommonJS | 136.33 | 110.32 | 39.27 |
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 | 168,473 | 87,171 | 60,658 | 46,603 | 38,343 | 32,658 |
76
- | insert.head | 1,271,814 | 999,755 | 1,074,002 | 1,093,264 | 1,106,172 | 1,105,184 |
77
- | insert.random | 475,390 | 255,768 | 161,979 | 124,466 | 100,709 | 85,015 |
78
- | insert.tail | 1,470,843 | 1,177,272 | 1,266,352 | 1,276,470 | 1,281,022 | 1,280,911 |
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 | 358,067 | 180,092 | 117,059 | 86,936 | 69,330 | 57,290 |
95
+ | remove.random | 341,765 | 165,565 | 113,075 | 83,800 | 67,429 | 55,746 |
81
96
  | remove.tail | — | — | — | — | — | — |
82
- | replace.head | 453,369 | 416,649 | 429,360 | 394,513 | 395,389 | 403,713 |
83
- | replace.random | 298,112 | 160,606 | 108,525 | 80,892 | 65,452 | 54,680 |
84
- | replace.tail | 401,284 | 449,608 | 412,634 | 430,354 | 408,033 | 387,953 |
85
- | value.head | 2,827,881 | 3,525,681 | 3,620,595 | 3,723,069 | 3,810,856 | 3,811,845 |
86
- | value.random | 731,172 | 255,071 | 143,482 | 100,113 | 78,156 | 63,980 |
87
- | value.tail | 5,453,695 | 5,310,238 | 5,096,734 | 5,044,621 | 5,054,127 | 4,915,815 |
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 | 21,832 | 22,291 | 22,406 | 22,966 | 23,864 | 24,211 |
108
+ | apply.random | 20,767 | 21,129 | 21,221 | 21,621 | 22,254 | 22,548 |
94
109
  | insert.head | — | — | — | — | — | — |
95
- | insert.random | 53,637 | 55,767 | 57,227 | 57,796 | 60,536 | 60,616 |
110
+ | insert.random | 49,291 | 50,341 | 51,237 | 51,902 | 53,706 | 53,811 |
96
111
  | insert.tail | — | — | — | — | — | — |
97
- | remove.head | 493,654 | 493,034 | 492,611 | 492,704 | 494,704 | 497,520 |
98
- | remove.random | 37,466 | 39,462 | 41,048 | 43,073 | 45,209 | 45,778 |
99
- | remove.tail | 491,829 | 472,405 | 399,771 | 416,614 | 426,344 | 383,461 |
100
- | replace.head | 380,504 | 371,861 | 365,935 | 312,468 | 315,039 | 271,629 |
101
- | replace.random | 35,794 | 37,986 | 39,619 | 41,464 | 43,674 | 43,633 |
102
- | replace.tail | 198,219 | 176,520 | 166,748 | 150,292 | 149,123 | 140,224 |
103
- | value.head | 1,820,081 | 1,813,320 | 1,792,267 | 1,804,349 | 1,844,976 | 1,872,844 |
104
- | value.random | 41,888 | 43,912 | 45,754 | 48,224 | 51,108 | 52,192 |
105
- | value.tail | 2,154,911 | 2,130,711 | 2,112,616 | 2,133,349 | 2,207,459 | 2,246,004 |
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) | 4,665 | 968 | 614 | 420 | 291 | 244 |
116
- | sequence() | 611 | 102 | 50 | 31 | 21 | 15 |
117
- | values() | 669 | 251 | 84 | 50 | 50 | 31 |
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) | 276 | 420 | 499 | 1,294 | 5,450 | 23,249 |
124
- | sequence() | 15 | 14 | 10 | 12 | 11 | 10 |
125
- | values() | 46 | 45 | 68 | 96 | 258 | 150,052 |
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
 
@@ -132,8 +147,8 @@ Complete exported Sequences, including Footage and acknowledgements. Sizes are i
132
147
 
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
- | JSON | 277.29 | 1,622.20 | 3,262.86 | 4,902.77 | 7,043.50 | 9,165.60 |
136
- | JSON + gzip | 14.60 | 73.83 | 150.38 | 226.92 | 311.16 | 391.60 |
150
+ | JSON | 277.41 | 1,622.78 | 3,264.00 | 4,904.44 | 7,045.81 | 9,168.42 |
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
 
@@ -141,8 +156,8 @@ Complete exported Sequences, including Footage and acknowledgements. Sizes are i
141
156
 
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
- | JSON | 7,449.19 | 5,619.45 | 3,771.17 | 1,886.19 | 383.37 | 0.02 |
145
- | JSON + gzip | 323.17 | 244.42 | 163.89 | 80.61 | 16.33 | 0.03 |
159
+ | JSON | 7,451.86 | 5,621.57 | 3,772.57 | 1,886.91 | 383.51 | 0.02 |
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.22.0, V8 13.6.233.17-node.57,
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 221 Vitest tests and 117 compatibility checks.
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
@@ -683,7 +683,11 @@ var Projection = class {
683
683
  */
684
684
  constructor(actorID, trustedSequence) {
685
685
  this.actorID = actorID;
686
- this.id = runtime.create(this, actorID, trustedSequence);
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
+ }
687
691
  }
688
692
  /**
689
693
  * Applies gossiped Insertions and Acknowledgements.
@@ -694,7 +698,11 @@ var Projection = class {
694
698
  * @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
695
699
  */
696
700
  apply(gossip) {
697
- return runtime.apply(this.id, gossip);
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
+ }
698
706
  }
699
707
  /**
700
708
  * Inserts values at a Projection position.
@@ -705,7 +713,11 @@ var Projection = class {
705
713
  * @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
706
714
  */
707
715
  insert(values, at) {
708
- return runtime.insert(this.id, values, at);
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
+ }
709
721
  }
710
722
  /**
711
723
  * Returns the length, A.K.A. amount of entries of this projection.
@@ -714,7 +726,11 @@ var Projection = class {
714
726
  * @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
715
727
  */
716
728
  length() {
717
- return runtime.length(this.id);
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
+ }
718
734
  }
719
735
  /**
720
736
  * Applies relevant acknowledgements and nonduplicate insertions from a replica of the sequence.
@@ -725,7 +741,11 @@ var Projection = class {
725
741
  * @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
726
742
  */
727
743
  merge(sequence) {
728
- return runtime.call(Operation.Merge, this.id, sequence);
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
+ }
729
749
  }
730
750
  /**
731
751
  * Removes an inclusive range of Projection positions.
@@ -736,7 +756,11 @@ var Projection = class {
736
756
  * @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
737
757
  */
738
758
  remove(startAt, endWith) {
739
- return runtime.call(Operation.Remove, this.id, startAt, endWith);
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
+ }
740
764
  }
741
765
  /**
742
766
  * Replaces an inclusive range of Projection positions.
@@ -748,7 +772,11 @@ var Projection = class {
748
772
  * @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
749
773
  */
750
774
  replace(withValues, startAt, endWith) {
751
- return runtime.call(Operation.Replace, this.id, withValues, startAt, endWith);
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
+ }
752
780
  }
753
781
  /**
754
782
  * Retires an Actor from future compaction requirements.
@@ -761,7 +789,11 @@ var Projection = class {
761
789
  * @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
762
790
  */
763
791
  retire(actorID) {
764
- return runtime.call(Operation.Retire, this.id, actorID);
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
+ }
765
797
  }
766
798
  /**
767
799
  * Sequences state into a compact serializable format.
@@ -777,7 +809,11 @@ var Projection = class {
777
809
  * @throws {@link SequencerError} with code `STRING_ENCODING_FAILED` if Footage concatenation fails.
778
810
  */
779
811
  sequence(stringEncode) {
780
- return runtime.sequence(this.id, 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
+ }
781
817
  }
782
818
  /**
783
819
  * Returns the value at a Projection position.
@@ -787,7 +823,11 @@ var Projection = class {
787
823
  * @throws {@link SequencerError} with code `PROJECTION_DESTROYED` after destruction.
788
824
  */
789
825
  value(at) {
790
- return runtime.value(this.id, at);
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
+ }
791
831
  }
792
832
  /**
793
833
  * Returns values from an inclusive range of Projection positions.
@@ -798,13 +838,21 @@ var Projection = class {
798
838
  * @throws {@link SequencerError} if destroyed or the native runtime reports an operation failure.
799
839
  */
800
840
  values(startAt, endWith) {
801
- return runtime.call(Operation.Values, this.id, startAt, endWith);
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
+ }
802
846
  }
803
847
  /** Destroys the Projection. Repeated calls have no effect. */
804
848
  destroy() {
805
- if (this.id < 0) return;
806
- runtime.destroy(this, this.id);
807
- this.id = -1;
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
+ }
808
856
  }
809
857
  };
810
858
  //#endregion