@sovereignbase/sequencer 1.0.0 → 1.0.2

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
@@ -2,7 +2,7 @@
2
2
  [![JSR](https://jsr.io/badges/@sovereignbase/sequencer)](https://jsr.io/@sovereignbase/sequencer)
3
3
  [![CI](https://github.com/sovereignbase/sequencer/actions/workflows/ci.yaml/badge.svg?branch=master)](https://github.com/sovereignbase/sequencer/actions/workflows/ci.yaml)
4
4
  [![codecov](https://codecov.io/gh/sovereignbase/sequencer/branch/master/graph/badge.svg)](https://codecov.io/gh/sovereignbase/sequencer)
5
- [![license](https://img.shields.io/npm/l/@sovereignbase/sequencer)](LICENSE)
5
+ [![license](https://img.shields.io/npm/l/@sovereignbase/sequencer)](https://github.com/sovereignbase/sequencer/blob/master/LICENSE)
6
6
 
7
7
  # Sequencer
8
8
 
@@ -29,18 +29,37 @@ projection.destroy()
29
29
 
30
30
  ### See documentation
31
31
 
32
- - [How sequencer works?](/INTERNALS.md)
33
- - [Typescript](https://sovereignbase.dev/sequencer/)
32
+ - [How sequencer works?](INTERNALS.md)
33
+ - [Typescript](https://sovereignbase.dev/sequencer/classes/Projection.html)
34
34
  - [C++](https://sovereignbase.dev/sequencer/c++)
35
35
 
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
+ ### Errors
42
+
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
+ | Code | Meaning |
48
+ | ------------------------- | ------------------------------------------------------------------- |
49
+ | `PROJECTION_DESTROYED` | An operation was called after the Projection was destroyed. |
50
+ | `NATIVE_OPERATION_FAILED` | The native runtime reported an initialization or operation failure. |
51
+
52
+ Invalid Gossip or Sequence input to `apply()` or `merge()` returns `undefined`.
53
+ Platform errors retain their original types.
54
+
36
55
  ## Benchmarks
37
56
 
38
57
  ### Moderate bundle size
39
58
 
40
59
  | Format | Raw (KiB) | Minified (KiB) | Minified + gzip (KiB) |
41
60
  | -------- | --------: | -------------: | --------------------: |
42
- | ESM | 123.83 | 100.04 | 36.07 |
43
- | CommonJS | 123.94 | 100.86 | 36.28 |
61
+ | ESM | 135.00 | 109.15 | 39.03 |
62
+ | CommonJS | 135.14 | 109.84 | 39.11 |
44
63
 
45
64
  Both bundles include WASM. Terser uses three compression passes; gzip uses level 9.
46
65
 
@@ -53,37 +72,37 @@ Strips contain 1–100 Frames (visible entries). Headers show Strip counts and m
53
72
 
54
73
  | 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 |
55
74
  | -------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: |
56
- | apply.random | 146,512 | 50,162 | 35,425 | 25,372 | 17,992 | 13,401 |
57
- | insert.head | 1,103,240 | 627,952 | 723,841 | 741,193 | 692,500 | 629,581 |
58
- | insert.random | 423,106 | 138,442 | 91,906 | 64,213 | 44,063 | 33,092 |
59
- | insert.tail | 1,247,342 | 779,594 | 895,027 | 892,070 | 830,660 | 765,706 |
75
+ | apply.random | 152,481 | 82,407 | 54,972 | 41,327 | 33,404 | 28,087 |
76
+ | insert.head | 1,125,803 | 917,202 | 989,477 | 1,002,460 | 1,008,049 | 1,005,481 |
77
+ | insert.random | 459,801 | 233,221 | 141,139 | 106,743 | 85,552 | 71,705 |
78
+ | insert.tail | 1,235,888 | 1,046,362 | 1,129,451 | 1,163,582 | 1,164,652 | 963,762 |
60
79
  | remove.head | — | — | — | — | — | — |
61
- | remove.random | 258,681 | 95,210 | 65,861 | 46,668 | 31,655 | 23,556 |
80
+ | remove.random | 318,832 | 161,201 | 103,195 | 76,208 | 61,027 | 50,419 |
62
81
  | remove.tail | — | — | — | — | — | — |
63
- | replace.head | 380,869 | 309,212 | 303,788 | 291,544 | 270,032 | 245,792 |
64
- | replace.random | 253,774 | 94,640 | 63,352 | 45,272 | 31,633 | 23,736 |
65
- | replace.tail | 392,296 | 315,718 | 313,645 | 310,052 | 268,791 | 247,351 |
66
- | value.head | 2,283,059 | 2,095,440 | 1,999,974 | 2,016,602 | 1,907,994 | 1,721,581 |
67
- | value.random | 569,971 | 133,693 | 78,867 | 51,725 | 34,540 | 25,316 |
68
- | value.tail | 4,749,438 | 3,636,984 | 3,461,656 | 3,227,876 | 2,914,996 | 2,408,625 |
82
+ | replace.head | 371,269 | 378,358 | 390,442 | 381,650 | 374,659 | 380,819 |
83
+ | replace.random | 257,863 | 147,949 | 96,725 | 71,868 | 58,024 | 48,412 |
84
+ | replace.tail | 316,736 | 369,208 | 364,734 | 383,559 | 366,881 | 350,473 |
85
+ | value.head | 2,529,757 | 3,200,174 | 3,231,484 | 3,365,642 | 3,481,984 | 3,549,918 |
86
+ | value.random | 644,467 | 230,616 | 126,832 | 88,155 | 68,446 | 55,752 |
87
+ | value.tail | 5,503,982 | 5,458,159 | 5,069,620 | 4,982,739 | 4,949,590 | 4,829,221 |
69
88
 
70
89
  **↓ Scale down (25,000 → 0 Strips)**
71
90
 
72
91
  | 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 |
73
92
  | -------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
74
- | apply.random | 7,268 | 7,592 | 8,263 | 8,783 | 9,083 | 9,219 |
93
+ | apply.random | 17,289 | 17,067 | 17,078 | 17,347 | 17,927 | 18,214 |
75
94
  | insert.head | — | — | — | — | — | — |
76
- | insert.random | 17,296 | 18,458 | 20,290 | 21,279 | 22,052 | 22,459 |
95
+ | insert.random | 42,405 | 41,938 | 42,228 | 42,440 | 44,086 | 44,230 |
77
96
  | insert.tail | — | — | — | — | — | — |
78
- | remove.head | 157,981 | 165,917 | 180,514 | 178,894 | 181,826 | 183,709 |
79
- | remove.random | 13,036 | 13,992 | 15,527 | 16,535 | 17,163 | 17,459 |
80
- | remove.tail | 192,199 | 192,220 | 203,528 | 209,615 | 209,694 | 210,394 |
81
- | replace.head | 176,953 | 178,240 | 186,921 | 185,389 | 181,259 | 161,071 |
82
- | replace.random | 13,038 | 14,084 | 15,647 | 16,708 | 17,397 | 17,697 |
83
- | replace.tail | 190,938 | 184,284 | 193,773 | 187,715 | 182,304 | 182,496 |
84
- | value.head | 794,128 | 838,606 | 885,880 | 922,502 | 940,112 | 948,944 |
85
- | value.random | 13,677 | 14,768 | 16,600 | 18,037 | 18,894 | 19,271 |
86
- | value.tail | 1,070,897 | 1,038,948 | 1,093,604 | 1,140,368 | 1,178,006 | 1,192,164 |
97
+ | remove.head | 449,484 | 439,424 | 439,835 | 443,041 | 448,352 | 451,829 |
98
+ | remove.random | 31,440 | 31,670 | 32,353 | 33,471 | 35,064 | 35,635 |
99
+ | remove.tail | 447,064 | 423,868 | 431,746 | 378,400 | 389,534 | 351,739 |
100
+ | replace.head | 342,862 | 287,099 | 291,717 | 258,805 | 263,535 | 236,146 |
101
+ | replace.random | 30,799 | 30,980 | 31,637 | 32,586 | 34,069 | 34,091 |
102
+ | replace.tail | 188,491 | 164,510 | 155,028 | 137,842 | 134,383 | 126,497 |
103
+ | value.head | 1,613,774 | 1,552,830 | 1,534,695 | 1,545,267 | 1,574,964 | 1,598,674 |
104
+ | value.random | 34,644 | 34,727 | 35,474 | 36,721 | 38,524 | 39,415 |
105
+ | value.tail | 1,908,571 | 1,799,032 | 1,759,746 | 1,768,794 | 1,828,720 | 1,863,802 |
87
106
 
88
107
  ### API throughput at checkpoint
89
108
 
@@ -93,17 +112,17 @@ Checkpoint calls, in ops/s, averaged across runs.
93
112
 
94
113
  | 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 |
95
114
  | --------------------------------- | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: |
96
- | new Projection(actorID, sequence) | 2,513 | 795 | 408 | 215 | 154 | 107 |
97
- | sequence() | 375 | 66 | 33 | 18 | 11 | 6 |
98
- | values() | 480 | 163 | 108 | 70 | 49 | 32 |
115
+ | new Projection(actorID, sequence) | 3,734 | 1,016 | 594 | 409 | 287 | 237 |
116
+ | sequence() | 479 | 85 | 42 | 26 | 17 | 12 |
117
+ | values() | 480 | 205 | 63 | 55 | 34 | 37 |
99
118
 
100
119
  **↓ Scale down (25,000 → 0 Strips)**
101
120
 
102
121
  | 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 |
103
122
  | --------------------------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
104
- | new Projection(actorID, sequence) | 116 | 212 | 273 | 586 | 1,881 | 16,098 |
105
- | sequence() | 7 | 6 | 5 | 4 | 4 | 38,383 |
106
- | values() | 44 | 51 | 58 | 62 | 199 | 68,912 |
123
+ | new Projection(actorID, sequence) | 284 | 410 | 505 | 1,271 | 5,357 | 22,172 |
124
+ | sequence() | 12 | 11 | 8 | 9 | 9 | 7 |
125
+ | values() | 52 | 52 | 53 | 81 | 209 | 140,305 |
107
126
 
108
127
  ### Sequence disk size at checkpoint
109
128
 
@@ -113,8 +132,8 @@ Complete exported Sequences, including Footage and acknowledgements. Sizes are i
113
132
 
114
133
  | 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 |
115
134
  | ------------------ | ----------------------------: | -----------------------------: | ------------------------------: | ------------------------------: | --------------------------------: | --------------------------------: |
116
- | JSON | 277.17 | 1,621.65 | 3,261.72 | 4,901.02 | 7,041.25 | 9,162.75 |
117
- | JSON + gzip | 14.59 | 73.84 | 150.38 | 226.94 | 311.22 | 391.69 |
135
+ | JSON | 277.41 | 1,622.78 | 3,264.00 | 4,904.44 | 7,045.81 | 9,168.42 |
136
+ | JSON + gzip | 14.59 | 73.83 | 150.35 | 226.86 | 311.12 | 391.57 |
118
137
  | MessagePack | 164.81 | 818.88 | 1,639.69 | 3,529.41 | 5,081.04 | 6,483.22 |
119
138
  | MessagePack + gzip | 12.38 | 61.62 | 124.91 | 198.59 | 263.54 | 332.77 |
120
139
 
@@ -122,8 +141,8 @@ Complete exported Sequences, including Footage and acknowledgements. Sizes are i
122
141
 
123
142
  | 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 |
124
143
  | ------------------ | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
125
- | JSON | 7,446.44 | 5,617.36 | 3,769.76 | 1,885.51 | 383.23 | 0.02 |
126
- | JSON + gzip | 323.23 | 244.45 | 163.91 | 80.61 | 16.33 | 0.03 |
144
+ | JSON | 7,451.86 | 5,621.57 | 3,772.57 | 1,886.91 | 383.51 | 0.02 |
145
+ | JSON + gzip | 323.11 | 244.34 | 163.82 | 80.59 | 16.33 | 0.03 |
127
146
  | MessagePack | 5,237.17 | 3,930.33 | 2,628.38 | 1,312.43 | 266.67 | 0.01 |
128
147
  | MessagePack + gzip | 274.96 | 207.78 | 137.38 | 67.41 | 13.67 | 0.03 |
129
148
 
@@ -143,8 +162,8 @@ One instance: WASM memory plus retained JS array slots, in KiB (1,024 bytes).
143
162
  | ---------------------- | --------------------------------: | ------------------------------: | ------------------------------: | -----------------------------: | ----------------------------: | -------------------: |
144
163
  | Estimated memory (KiB) | 163,746.93 | 174,034.00 | 202,660.72 | 293,941.85 | 302,158.29 | 304,203.30 |
145
164
 
146
- Measured on Node 24.16.0, V8 13.6.233.17-node.49,
147
- win32 x64, Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz.
165
+ Measured on Node 24.22.0, V8 13.6.233.17-node.57,
166
+ linux x64, AMD EPYC 7763 64-Core Processor.
148
167
  Peer synchronization, encoding and JS process garbage collection are outside API timings.
149
168
  [Full lifecycle results](benchmark/.results/lifecycle.md) · [Throughput results](benchmark/.results/throughput.md).
150
169
 
@@ -152,7 +171,7 @@ Peer synchronization, encoding and JS process garbage collection are outside API
152
171
 
153
172
  ### Behaviour guaranteed by excessive tests
154
173
 
155
- The latest verification passed 178 Vitest tests and 88 compatibility checks (1 failed).
174
+ The latest verification passed 212 Vitest tests and 108 compatibility checks.
156
175
  The configured 100% coverage threshold is met (100% statements, 100% branches, 100% functions, 100% lines).
157
176
  See the [test suites](test/README.md) and
158
177
  [automated test report](https://sovereignbase.dev/sequencer/tests/).
@@ -168,7 +187,7 @@ Runtimes covered by the latest compatibility verification:
168
187
  - Edge Runtime: passed
169
188
  - Cloudflare Workers through workerd: passed
170
189
  - Chromium browser windows: passed
171
- - Firefox browser windows: failed (matching Playwright browser binary unavailable)
190
+ - Firefox browser windows: passed
172
191
  - WebKit browser windows: passed
173
192
 
174
193
  ### Tested realtime and offline text editing behaviour examples