@adobe/data-persistence 0.9.90

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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +258 -0
  3. package/dist/backend/memory-backend.d.ts +6 -0
  4. package/dist/backend/memory-backend.js +92 -0
  5. package/dist/backend/memory-backend.js.map +1 -0
  6. package/dist/backend/memory-backend.test.d.ts +1 -0
  7. package/dist/backend/memory-backend.test.js +7 -0
  8. package/dist/backend/memory-backend.test.js.map +1 -0
  9. package/dist/backend/memory-file.d.ts +7 -0
  10. package/dist/backend/memory-file.js +90 -0
  11. package/dist/backend/memory-file.js.map +1 -0
  12. package/dist/backend/memory-file.test.d.ts +1 -0
  13. package/dist/backend/memory-file.test.js +5 -0
  14. package/dist/backend/memory-file.test.js.map +1 -0
  15. package/dist/backend/persistence-backend.conformance.d.ts +10 -0
  16. package/dist/backend/persistence-backend.conformance.js +104 -0
  17. package/dist/backend/persistence-backend.conformance.js.map +1 -0
  18. package/dist/backend/persistence-backend.d.ts +54 -0
  19. package/dist/backend/persistence-backend.js +3 -0
  20. package/dist/backend/persistence-backend.js.map +1 -0
  21. package/dist/backend/random-access-file.conformance.d.ts +20 -0
  22. package/dist/backend/random-access-file.conformance.js +156 -0
  23. package/dist/backend/random-access-file.conformance.js.map +1 -0
  24. package/dist/backend/random-access-file.d.ts +39 -0
  25. package/dist/backend/random-access-file.js +3 -0
  26. package/dist/backend/random-access-file.js.map +1 -0
  27. package/dist/backend/validate-rel-path.d.ts +14 -0
  28. package/dist/backend/validate-rel-path.js +44 -0
  29. package/dist/backend/validate-rel-path.js.map +1 -0
  30. package/dist/backend/validate-rel-path.test.d.ts +1 -0
  31. package/dist/backend/validate-rel-path.test.js +37 -0
  32. package/dist/backend/validate-rel-path.test.js.map +1 -0
  33. package/dist/browser/browser-worker-bootstrap.d.ts +1 -0
  34. package/dist/browser/browser-worker-bootstrap.js +97 -0
  35. package/dist/browser/browser-worker-bootstrap.js.map +1 -0
  36. package/dist/browser/browser-worker-transport.browser.test.d.ts +1 -0
  37. package/dist/browser/browser-worker-transport.browser.test.js +156 -0
  38. package/dist/browser/browser-worker-transport.browser.test.js.map +1 -0
  39. package/dist/browser/browser-worker-transport.d.ts +33 -0
  40. package/dist/browser/browser-worker-transport.js +120 -0
  41. package/dist/browser/browser-worker-transport.js.map +1 -0
  42. package/dist/browser/create-opfs-provider.d.ts +23 -0
  43. package/dist/browser/create-opfs-provider.js +49 -0
  44. package/dist/browser/create-opfs-provider.js.map +1 -0
  45. package/dist/browser/index.d.ts +6 -0
  46. package/dist/browser/index.js +12 -0
  47. package/dist/browser/index.js.map +1 -0
  48. package/dist/browser/mount-opfs.d.ts +12 -0
  49. package/dist/browser/mount-opfs.js +15 -0
  50. package/dist/browser/mount-opfs.js.map +1 -0
  51. package/dist/browser/opfs-backend-lock.browser.test.d.ts +1 -0
  52. package/dist/browser/opfs-backend-lock.browser.test.js +127 -0
  53. package/dist/browser/opfs-backend-lock.browser.test.js.map +1 -0
  54. package/dist/browser/opfs-backend.d.ts +6 -0
  55. package/dist/browser/opfs-backend.js +162 -0
  56. package/dist/browser/opfs-backend.js.map +1 -0
  57. package/dist/browser/opfs-lock-test-worker.d.ts +1 -0
  58. package/dist/browser/opfs-lock-test-worker.js +50 -0
  59. package/dist/browser/opfs-lock-test-worker.js.map +1 -0
  60. package/dist/browser/opfs-sync-file.d.ts +10 -0
  61. package/dist/browser/opfs-sync-file.js +58 -0
  62. package/dist/browser/opfs-sync-file.js.map +1 -0
  63. package/dist/encoder/create-column-encoder.d.ts +15 -0
  64. package/dist/encoder/create-column-encoder.js +110 -0
  65. package/dist/encoder/create-column-encoder.js.map +1 -0
  66. package/dist/encoder/journal-snapshot-codec.d.ts +21 -0
  67. package/dist/encoder/journal-snapshot-codec.js +103 -0
  68. package/dist/encoder/journal-snapshot-codec.js.map +1 -0
  69. package/dist/encoder/journal-snapshot-codec.test.d.ts +1 -0
  70. package/dist/encoder/journal-snapshot-codec.test.js +96 -0
  71. package/dist/encoder/journal-snapshot-codec.test.js.map +1 -0
  72. package/dist/encoder/types.d.ts +72 -0
  73. package/dist/encoder/types.js +3 -0
  74. package/dist/encoder/types.js.map +1 -0
  75. package/dist/index.d.ts +24 -0
  76. package/dist/index.js +15 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/journal/journal-codec.d.ts +28 -0
  79. package/dist/journal/journal-codec.js +82 -0
  80. package/dist/journal/journal-codec.js.map +1 -0
  81. package/dist/journal/journal-codec.test.d.ts +1 -0
  82. package/dist/journal/journal-codec.test.js +106 -0
  83. package/dist/journal/journal-codec.test.js.map +1 -0
  84. package/dist/journal/journal-entry.d.ts +63 -0
  85. package/dist/journal/journal-entry.js +28 -0
  86. package/dist/journal/journal-entry.js.map +1 -0
  87. package/dist/node/create-node-fs-provider.d.ts +34 -0
  88. package/dist/node/create-node-fs-provider.js +48 -0
  89. package/dist/node/create-node-fs-provider.js.map +1 -0
  90. package/dist/node/index.d.ts +6 -0
  91. package/dist/node/index.js +10 -0
  92. package/dist/node/index.js.map +1 -0
  93. package/dist/node/mount-node-fs.d.ts +12 -0
  94. package/dist/node/mount-node-fs.js +15 -0
  95. package/dist/node/mount-node-fs.js.map +1 -0
  96. package/dist/node/node-fs-backend-lock.node.test.d.ts +1 -0
  97. package/dist/node/node-fs-backend-lock.node.test.js +160 -0
  98. package/dist/node/node-fs-backend-lock.node.test.js.map +1 -0
  99. package/dist/node/node-fs-backend.d.ts +21 -0
  100. package/dist/node/node-fs-backend.js +186 -0
  101. package/dist/node/node-fs-backend.js.map +1 -0
  102. package/dist/node/node-fs-backend.node.test.d.ts +1 -0
  103. package/dist/node/node-fs-backend.node.test.js +17 -0
  104. package/dist/node/node-fs-backend.node.test.js.map +1 -0
  105. package/dist/node/node-fs-file.d.ts +6 -0
  106. package/dist/node/node-fs-file.js +57 -0
  107. package/dist/node/node-fs-file.js.map +1 -0
  108. package/dist/node/node-fs-file.node.test.d.ts +1 -0
  109. package/dist/node/node-fs-file.node.test.js +13 -0
  110. package/dist/node/node-fs-file.node.test.js.map +1 -0
  111. package/dist/node/node-fs-provider.node.test.d.ts +1 -0
  112. package/dist/node/node-fs-provider.node.test.js +119 -0
  113. package/dist/node/node-fs-provider.node.test.js.map +1 -0
  114. package/dist/node/node-worker-bootstrap.d.ts +1 -0
  115. package/dist/node/node-worker-bootstrap.js +104 -0
  116. package/dist/node/node-worker-bootstrap.js.map +1 -0
  117. package/dist/node/node-worker-transport.d.ts +27 -0
  118. package/dist/node/node-worker-transport.js +152 -0
  119. package/dist/node/node-worker-transport.js.map +1 -0
  120. package/dist/node/node-worker-transport.node.test.d.ts +1 -0
  121. package/dist/node/node-worker-transport.node.test.js +147 -0
  122. package/dist/node/node-worker-transport.node.test.js.map +1 -0
  123. package/dist/perftest/perf-harness.d.ts +74 -0
  124. package/dist/perftest/perf-harness.js +147 -0
  125. package/dist/perftest/perf-harness.js.map +1 -0
  126. package/dist/perftest/persistence-perf.d.ts +2 -0
  127. package/dist/perftest/persistence-perf.js +290 -0
  128. package/dist/perftest/persistence-perf.js.map +1 -0
  129. package/dist/perftest/run.d.ts +1 -0
  130. package/dist/perftest/run.js +28 -0
  131. package/dist/perftest/run.js.map +1 -0
  132. package/dist/provider/create-memory-provider.d.ts +16 -0
  133. package/dist/provider/create-memory-provider.js +44 -0
  134. package/dist/provider/create-memory-provider.js.map +1 -0
  135. package/dist/provider/mount.d.ts +20 -0
  136. package/dist/provider/mount.js +20 -0
  137. package/dist/provider/mount.js.map +1 -0
  138. package/dist/provider/persistence-provider.d.ts +63 -0
  139. package/dist/provider/persistence-provider.js +3 -0
  140. package/dist/provider/persistence-provider.js.map +1 -0
  141. package/dist/provider/persistence-provider.test.d.ts +9 -0
  142. package/dist/provider/persistence-provider.test.js +139 -0
  143. package/dist/provider/persistence-provider.test.js.map +1 -0
  144. package/dist/service/component-nonpersistent-durability.test.d.ts +1 -0
  145. package/dist/service/component-nonpersistent-durability.test.js +57 -0
  146. package/dist/service/component-nonpersistent-durability.test.js.map +1 -0
  147. package/dist/service/create-incremental-persistence-service.d.ts +7 -0
  148. package/dist/service/create-incremental-persistence-service.js +960 -0
  149. package/dist/service/create-incremental-persistence-service.js.map +1 -0
  150. package/dist/service/create-worker-persistence-service.d.ts +1 -0
  151. package/dist/service/create-worker-persistence-service.js +7 -0
  152. package/dist/service/create-worker-persistence-service.js.map +1 -0
  153. package/dist/service/create-worker-persistence-service.test.d.ts +1 -0
  154. package/dist/service/create-worker-persistence-service.test.js +291 -0
  155. package/dist/service/create-worker-persistence-service.test.js.map +1 -0
  156. package/dist/service/entity-location-cache.d.ts +15 -0
  157. package/dist/service/entity-location-cache.js +75 -0
  158. package/dist/service/entity-location-cache.js.map +1 -0
  159. package/dist/service/entity-location-density.test.d.ts +1 -0
  160. package/dist/service/entity-location-density.test.js +42 -0
  161. package/dist/service/entity-location-density.test.js.map +1 -0
  162. package/dist/service/incremental-persistence-service.d.ts +57 -0
  163. package/dist/service/incremental-persistence-service.js +3 -0
  164. package/dist/service/incremental-persistence-service.js.map +1 -0
  165. package/dist/service/intermediate-relocation-durability.test.d.ts +1 -0
  166. package/dist/service/intermediate-relocation-durability.test.js +89 -0
  167. package/dist/service/intermediate-relocation-durability.test.js.map +1 -0
  168. package/dist/service/internal-access.d.ts +34 -0
  169. package/dist/service/internal-access.js +43 -0
  170. package/dist/service/internal-access.js.map +1 -0
  171. package/dist/service/journal-replay.test.d.ts +1 -0
  172. package/dist/service/journal-replay.test.js +424 -0
  173. package/dist/service/journal-replay.test.js.map +1 -0
  174. package/dist/service/journal-storage-durability.test.d.ts +1 -0
  175. package/dist/service/journal-storage-durability.test.js +171 -0
  176. package/dist/service/journal-storage-durability.test.js.map +1 -0
  177. package/dist/service/load-roundtrip.test.d.ts +1 -0
  178. package/dist/service/load-roundtrip.test.js +224 -0
  179. package/dist/service/load-roundtrip.test.js.map +1 -0
  180. package/dist/service/persistence-complexity.test.d.ts +1 -0
  181. package/dist/service/persistence-complexity.test.js +275 -0
  182. package/dist/service/persistence-complexity.test.js.map +1 -0
  183. package/dist/service/worker-persistence-service.d.ts +24 -0
  184. package/dist/service/worker-persistence-service.js +8 -0
  185. package/dist/service/worker-persistence-service.js.map +1 -0
  186. package/dist/transport/inprocess-transport.d.ts +15 -0
  187. package/dist/transport/inprocess-transport.js +64 -0
  188. package/dist/transport/inprocess-transport.js.map +1 -0
  189. package/dist/transport/inprocess-transport.test.d.ts +1 -0
  190. package/dist/transport/inprocess-transport.test.js +100 -0
  191. package/dist/transport/inprocess-transport.test.js.map +1 -0
  192. package/dist/transport/router.d.ts +12 -0
  193. package/dist/transport/router.js +146 -0
  194. package/dist/transport/router.js.map +1 -0
  195. package/dist/transport/transport.d.ts +105 -0
  196. package/dist/transport/transport.js +3 -0
  197. package/dist/transport/transport.js.map +1 -0
  198. package/package.json +59 -0
@@ -0,0 +1,275 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ //
3
+ // Persistence complexity contract.
4
+ //
5
+ // The promise the design makes:
6
+ //
7
+ // The cost of persisting a transaction T is O(changes), where
8
+ // "changes" means the number of (entity, component) pairs that T
9
+ // actually touched — plus a small constant per affected entity
10
+ // (entity-location update, commit marker, etc).
11
+ //
12
+ // Crucially, it must NOT depend on:
13
+ //
14
+ // - the total number of entities in the world
15
+ // - the row capacity of the affected archetype
16
+ // - the number of archetypes registered
17
+ //
18
+ // We assert this by counting the PersistOp messages emitted per
19
+ // transaction across worlds of widely varying size and confirming the
20
+ // op count is identical (and small).
21
+ //
22
+ // We assert OP COUNT, not wall time, because:
23
+ //
24
+ // - wall time fluctuates with GC, JIT warmup, and OS scheduling
25
+ // - op count is the closed-form algorithmic invariant — if op count
26
+ // is flat, time-per-op is bounded by per-op work (which is itself
27
+ // O(stride) per write, not O(world))
28
+ //
29
+ // World sizes deliberately stay small (10 / 100 / 500) — larger numbers
30
+ // don't add confidence to the invariant (which is binary: flat or not)
31
+ // but do add seconds of test time with no benefit.
32
+ import { Database } from "@adobe/data/ecs";
33
+ import { F32, Vec3 } from "@adobe/data/math";
34
+ import { describe, expect, it } from "vitest";
35
+ import { createMemoryBackend } from "../backend/memory-backend.js";
36
+ import { createInprocessTransport } from "../transport/inprocess-transport.js";
37
+ import { createWorkerPersistenceService } from "./create-worker-persistence-service.js";
38
+ const createTestDb = () => {
39
+ const plugin = Database.Plugin.create({
40
+ components: {
41
+ position: Vec3.schema,
42
+ velocity: Vec3.schema,
43
+ mass: F32.schema,
44
+ },
45
+ archetypes: {
46
+ Particle: ["position", "velocity", "mass"],
47
+ },
48
+ transactions: {
49
+ spawn(t, args) {
50
+ return t.archetypes.Particle.insert({
51
+ position: [args.x, args.y, args.z],
52
+ velocity: [0, 0, 0],
53
+ mass: args.mass,
54
+ });
55
+ },
56
+ move(t, args) {
57
+ t.update(args.entity, { position: [args.x, args.y, args.z] });
58
+ },
59
+ kill(t, entity) {
60
+ t.delete(entity);
61
+ },
62
+ updateAll(t, args) {
63
+ t.update(args.entity, {
64
+ position: [args.x, args.y, args.z],
65
+ velocity: [args.vx, args.vy, args.vz],
66
+ mass: args.mass,
67
+ });
68
+ },
69
+ },
70
+ });
71
+ return Database.create(plugin);
72
+ };
73
+ /**
74
+ * Wrap an in-process transport so every PersistOp issued through
75
+ * `send()` and `request()` is recorded into `ops`. Returns the spy
76
+ * transport plus the recording array.
77
+ */
78
+ const spyTransport = (inner) => {
79
+ const ops = [];
80
+ const transport = {
81
+ send(op, transfer) {
82
+ ops.push(op);
83
+ inner.send(op, transfer);
84
+ },
85
+ request(op, transfer) {
86
+ ops.push(op);
87
+ return inner.request(op, transfer);
88
+ },
89
+ onMessage: inner.onMessage.bind(inner),
90
+ flush: inner.flush.bind(inner),
91
+ close: inner.close.bind(inner),
92
+ };
93
+ return { transport, ops };
94
+ };
95
+ describe("persistence complexity contract: O(changes), not O(world)", () => {
96
+ /**
97
+ * For each world size N, populate N entities, then run an
98
+ * identical small transaction and count the PersistOps it emitted.
99
+ * The count must be equal across N.
100
+ */
101
+ const measureOpsForOneMove = async (N) => {
102
+ const db = createTestDb();
103
+ const backend = createMemoryBackend();
104
+ const inner = createInprocessTransport(backend);
105
+ const { transport, ops } = spyTransport(inner);
106
+ const service = await createWorkerPersistenceService({
107
+ database: db,
108
+ backend,
109
+ transport,
110
+ // Disable auto-checkpoint so it never sneaks an extra op
111
+ // burst into our measurement window.
112
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
113
+ });
114
+ // Populate N entities.
115
+ const ids = [];
116
+ for (let i = 0; i < N; i++) {
117
+ const id = db.transactions.spawn({ x: i, y: i, z: i, mass: 1 });
118
+ ids.push(id);
119
+ }
120
+ await service.flush();
121
+ // Snapshot op count, then run a single tiny tx that updates
122
+ // one component on one entity in the middle of the world.
123
+ const opsBefore = ops.length;
124
+ db.transactions.move({ entity: ids[Math.floor(N / 2)], x: 1, y: 2, z: 3 });
125
+ await service.flush();
126
+ const opsForOneMove = ops.length - opsBefore;
127
+ await service.dispose();
128
+ await transport.close();
129
+ return opsForOneMove;
130
+ };
131
+ it("a single-component update emits the same op count regardless of world size", async () => {
132
+ const counts = [
133
+ await measureOpsForOneMove(10),
134
+ await measureOpsForOneMove(100),
135
+ await measureOpsForOneMove(500),
136
+ ];
137
+ // All three must be identical: the per-tx op count is a
138
+ // function of the diff (1 entity × 1 component touched), not N.
139
+ expect(counts[0]).toBe(counts[1]);
140
+ expect(counts[1]).toBe(counts[2]);
141
+ // And it should be tiny — concretely:
142
+ // 1 journal entry (position update)
143
+ // + 1 column slice (position bytes)
144
+ // + 1 ELT update (entity location)
145
+ // + 1 commit entry
146
+ // = 4 ops per single-component, single-entity transaction.
147
+ expect(counts[0]).toBe(4);
148
+ });
149
+ it("a multi-component update on one entity emits ops proportional to touched columns, not world size", async () => {
150
+ const measure = async (N) => {
151
+ const db = createTestDb();
152
+ const backend = createMemoryBackend();
153
+ const inner = createInprocessTransport(backend);
154
+ const { transport, ops } = spyTransport(inner);
155
+ const service = await createWorkerPersistenceService({
156
+ database: db,
157
+ backend,
158
+ transport,
159
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
160
+ });
161
+ const ids = [];
162
+ for (let i = 0; i < N; i++) {
163
+ ids.push(db.transactions.spawn({ x: i, y: i, z: i, mass: 1 }));
164
+ }
165
+ await service.flush();
166
+ const opsBefore = ops.length;
167
+ db.transactions.updateAll({
168
+ entity: ids[Math.floor(N / 2)],
169
+ x: 1, y: 2, z: 3,
170
+ vx: 4, vy: 5, vz: 6,
171
+ mass: 7,
172
+ });
173
+ await service.flush();
174
+ const out = ops.length - opsBefore;
175
+ await service.dispose();
176
+ await transport.close();
177
+ return out;
178
+ };
179
+ const counts = [
180
+ await measure(10),
181
+ await measure(100),
182
+ await measure(500),
183
+ ];
184
+ expect(counts[0]).toBe(counts[1]);
185
+ expect(counts[1]).toBe(counts[2]);
186
+ // 3 columns touched (position, velocity, mass) → 3 journal entries
187
+ // + 3 column slices + 1 ELT update + 1 commit = 8 ops.
188
+ expect(counts[0]).toBe(8);
189
+ });
190
+ it("an insert emits ops proportional to columns in the destination archetype, not world size", async () => {
191
+ const measure = async (N) => {
192
+ const db = createTestDb();
193
+ const backend = createMemoryBackend();
194
+ const inner = createInprocessTransport(backend);
195
+ const { transport, ops } = spyTransport(inner);
196
+ const service = await createWorkerPersistenceService({
197
+ database: db,
198
+ backend,
199
+ transport,
200
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
201
+ });
202
+ for (let i = 0; i < N; i++) {
203
+ db.transactions.spawn({ x: i, y: i, z: i, mass: 1 });
204
+ }
205
+ await service.flush();
206
+ const opsBefore = ops.length;
207
+ db.transactions.spawn({ x: 0, y: 0, z: 0, mass: 0 });
208
+ await service.flush();
209
+ const out = ops.length - opsBefore;
210
+ await service.dispose();
211
+ await transport.close();
212
+ return out;
213
+ };
214
+ const counts = [
215
+ await measure(10),
216
+ await measure(100),
217
+ await measure(500),
218
+ ];
219
+ expect(counts[0]).toBe(counts[1]);
220
+ expect(counts[1]).toBe(counts[2]);
221
+ // Insert writes all destination columns + ELT + commit:
222
+ // 3 journal entries + 3 column slices + 1 ELT + 1 commit = 8 ops.
223
+ expect(counts[0]).toBe(8);
224
+ });
225
+ it("a delete emits ops proportional to (1 + swap-remove side effects), not world size", async () => {
226
+ // Important: this measures the steady-state delete cost, where
227
+ // an entity's removal causes ONE swap-move side effect (the
228
+ // last row backfills the vacated row). We want the cost to
229
+ // depend on that constant, not on N.
230
+ const measure = async (N) => {
231
+ const db = createTestDb();
232
+ const backend = createMemoryBackend();
233
+ const inner = createInprocessTransport(backend);
234
+ const { transport, ops } = spyTransport(inner);
235
+ const service = await createWorkerPersistenceService({
236
+ database: db,
237
+ backend,
238
+ transport,
239
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
240
+ });
241
+ const ids = [];
242
+ for (let i = 0; i < N; i++) {
243
+ ids.push(db.transactions.spawn({ x: i, y: i, z: i, mass: 1 }));
244
+ }
245
+ await service.flush();
246
+ const opsBefore = ops.length;
247
+ // Delete an entity in the middle: the table swap-removes
248
+ // by moving the LAST row into the vacated row. The
249
+ // persistence service detects that move and emits a
250
+ // synthetic "all columns" update for the swapped-in entity.
251
+ db.transactions.kill(ids[Math.floor(N / 2)]);
252
+ await service.flush();
253
+ const out = ops.length - opsBefore;
254
+ await service.dispose();
255
+ await transport.close();
256
+ return out;
257
+ };
258
+ const counts = [
259
+ await measure(10),
260
+ await measure(100),
261
+ await measure(500),
262
+ ];
263
+ expect(counts[0]).toBe(counts[1]);
264
+ expect(counts[1]).toBe(counts[2]);
265
+ // Delete cost:
266
+ // 1 journal "delete" entry
267
+ // + 1 ELT delete
268
+ // + (swap-remove of last row → 3 journal entries + 3 column
269
+ // slices + 1 ELT update for the moved entity)
270
+ // + 1 commit
271
+ // = 10 ops.
272
+ expect(counts[0]).toBe(10);
273
+ });
274
+ });
275
+ //# sourceMappingURL=persistence-complexity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence-complexity.test.js","sourceRoot":"","sources":["../../src/service/persistence-complexity.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export type { IncrementalPersistenceService, IncrementalPersistenceServiceOptions, } from "./incremental-persistence-service.js";
2
+ export type { ProviderMountOptions as _ProviderMountOptions } from "../provider/persistence-provider.js";
3
+ import type { IncrementalPersistenceService, IncrementalPersistenceServiceOptions } from "./incremental-persistence-service.js";
4
+ import type { PersistenceMount, ProviderMountOptions } from "../provider/persistence-provider.js";
5
+ import type { Database } from "@adobe/data/ecs";
6
+ /**
7
+ * @deprecated Use `IncrementalPersistenceService` instead.
8
+ */
9
+ export type WorkerPersistenceService = IncrementalPersistenceService;
10
+ /**
11
+ * @deprecated Use `IncrementalPersistenceServiceOptions` instead.
12
+ */
13
+ export type WorkerPersistenceServiceOptions = IncrementalPersistenceServiceOptions;
14
+ /**
15
+ * @deprecated Use `PersistenceMount` from `@adobe/data-persistence` instead.
16
+ */
17
+ export type { PersistenceMount };
18
+ /**
19
+ * @deprecated Use `ProviderMountOptions` instead.
20
+ */
21
+ export interface MountOptions<R extends string | FileSystemDirectoryHandle> extends ProviderMountOptions {
22
+ readonly root: R;
23
+ readonly database: Database<any, any, any, any, any, any, any, any>;
24
+ }
@@ -0,0 +1,8 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ //
3
+ // Backwards-compatibility shim. New code should import from
4
+ // `./incremental-persistence-service.js` or from `@adobe/data-persistence`
5
+ // directly. The names below are deprecated and will be removed in a future
6
+ // release.
7
+ export {};
8
+ //# sourceMappingURL=worker-persistence-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-persistence-service.js","sourceRoot":"","sources":["../../src/service/worker-persistence-service.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,4DAA4D;AAC5D,2EAA2E;AAC3E,2EAA2E;AAC3E,WAAW"}
@@ -0,0 +1,15 @@
1
+ import type { PersistenceBackend } from "../backend/persistence-backend.js";
2
+ import type { Transport } from "./transport.js";
3
+ /**
4
+ * In-process transport. Delegates directly to a {@link PersistRouter}
5
+ * created from the given backend. Intended for:
6
+ *
7
+ * - tests (no worker startup, no message-channel overhead)
8
+ * - Node servers that already absorb fs I/O on libuv and do not need
9
+ * a dedicated thread
10
+ *
11
+ * No `Transferable` semantics — the same ArrayBuffer reference is
12
+ * shared with the router. Callers that wish to enforce
13
+ * transfer-style hand-off should use the worker transports instead.
14
+ */
15
+ export declare const createInprocessTransport: (backend: PersistenceBackend) => Transport;
@@ -0,0 +1,64 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { createPersistRouter } from "./router.js";
3
+ /**
4
+ * In-process transport. Delegates directly to a {@link PersistRouter}
5
+ * created from the given backend. Intended for:
6
+ *
7
+ * - tests (no worker startup, no message-channel overhead)
8
+ * - Node servers that already absorb fs I/O on libuv and do not need
9
+ * a dedicated thread
10
+ *
11
+ * No `Transferable` semantics — the same ArrayBuffer reference is
12
+ * shared with the router. Callers that wish to enforce
13
+ * transfer-style hand-off should use the worker transports instead.
14
+ */
15
+ export const createInprocessTransport = (backend) => {
16
+ const router = createPersistRouter(backend);
17
+ const handlers = new Set();
18
+ // Track in-flight router operations so flush() can drain them
19
+ // without a polling loop. Each op is added on dispatch and removed
20
+ // on settle.
21
+ const pending = new Set();
22
+ let closed = false;
23
+ const dispatchAck = (ack) => {
24
+ for (const h of handlers)
25
+ h(ack);
26
+ };
27
+ const track = (p) => {
28
+ pending.add(p);
29
+ const remove = () => { pending.delete(p); };
30
+ p.then(remove, remove);
31
+ return p;
32
+ };
33
+ return {
34
+ send(op) {
35
+ if (closed)
36
+ throw new Error("Transport is closed");
37
+ // Fire-and-forget; surface errors as ack messages.
38
+ track(router.handle(op).then((value) => dispatchAck({ kind: "ack", id: op.id, value }), (err) => dispatchAck({ kind: "ack", id: op.id, error: String(err instanceof Error ? err.message : err) })));
39
+ },
40
+ async request(op) {
41
+ if (closed)
42
+ throw new Error("Transport is closed");
43
+ return track(router.handle(op));
44
+ },
45
+ onMessage(handler) {
46
+ handlers.add(handler);
47
+ return () => handlers.delete(handler);
48
+ },
49
+ async flush() {
50
+ // Loop because settling a pending op may itself enqueue another
51
+ // (e.g. an ack handler that triggers a follow-up write).
52
+ while (pending.size > 0) {
53
+ await Promise.allSettled([...pending]);
54
+ }
55
+ },
56
+ async close() {
57
+ closed = true;
58
+ await this.flush();
59
+ handlers.clear();
60
+ await router.close();
61
+ },
62
+ };
63
+ };
64
+ //# sourceMappingURL=inprocess-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inprocess-transport.js","sourceRoot":"","sources":["../../src/transport/inprocess-transport.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAGvD,OAAO,EAAE,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAGtE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACpC,OAA2B,EAClB,EAAE;IACX,MAAM,MAAM,GAAkB,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiC,CAAC;IAC1D,8DAA8D;IAC9D,mEAAmE;IACnE,aAAa;IACb,MAAM,OAAO,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC5C,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,MAAM,WAAW,GAAG,CAAC,GAAe,EAAQ,EAAE;QAC1C,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAI,CAAa,EAAc,EAAE;QAC3C,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACf,MAAM,MAAM,GAAG,GAAS,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACb,CAAC,CAAC;IAEF,OAAO;QACH,IAAI,CAAC,EAAa;YACd,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACnD,mDAAmD;YACnD,KAAK,CACD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAClB,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EACzD,CAAC,GAAY,EAAE,EAAE,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CACrH,CACJ,CAAC;QACN,CAAC;QACD,KAAK,CAAC,OAAO,CAAc,EAAa;YACpC,IAAI,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACnD,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAe,CAAC;QAClD,CAAC;QACD,SAAS,CAAC,OAAO;YACb,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,KAAK;YACP,gEAAgE;YAChE,yDAAyD;YACzD,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;YAC3C,CAAC;QACL,CAAC;QACD,KAAK,CAAC,KAAK;YACP,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,QAAQ,CAAC,KAAK,EAAE,CAAC;YACjB,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;KACJ,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,100 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { describe, expect, it } from "vitest";
3
+ import { createMemoryBackend } from "../backend/memory-backend.js";
4
+ import { createInprocessTransport } from "./inprocess-transport.js";
5
+ describe("createInprocessTransport", () => {
6
+ it("routes writeColumnSlice to the backend", async () => {
7
+ const backend = createMemoryBackend();
8
+ const transport = createInprocessTransport(backend);
9
+ try {
10
+ const bytes = new Uint8Array([1, 2, 3, 4]).buffer.slice(0);
11
+ await transport.request({
12
+ id: 1,
13
+ kind: "writeColumnSlice",
14
+ archetypeId: 7,
15
+ component: "position",
16
+ rowOffset: 0,
17
+ bytes,
18
+ });
19
+ const file = await backend.open("archetypes/7/position.bin");
20
+ const read = await file.readAt(0, 4);
21
+ expect(Array.from(read)).toEqual([1, 2, 3, 4]);
22
+ await file.close();
23
+ }
24
+ finally {
25
+ await transport.close();
26
+ }
27
+ });
28
+ it("appends to the journal and returns the new size", async () => {
29
+ const backend = createMemoryBackend();
30
+ const transport = createInprocessTransport(backend);
31
+ try {
32
+ const a = new Uint8Array([1, 2, 3]).buffer.slice(0);
33
+ const b = new Uint8Array([4, 5]).buffer.slice(0);
34
+ const sizeAfterA = await transport.request({ id: 1, kind: "appendJournal", bytes: a });
35
+ const sizeAfterB = await transport.request({ id: 2, kind: "appendJournal", bytes: b });
36
+ expect(sizeAfterA).toBe(3);
37
+ expect(sizeAfterB).toBe(5);
38
+ }
39
+ finally {
40
+ await transport.close();
41
+ }
42
+ });
43
+ it("delivers ack messages for fire-and-forget sends", async () => {
44
+ const backend = createMemoryBackend();
45
+ const transport = createInprocessTransport(backend);
46
+ try {
47
+ const acks = [];
48
+ const off = transport.onMessage(msg => {
49
+ if (msg.kind === "ack")
50
+ acks.push({ id: msg.id, error: msg.error });
51
+ });
52
+ // entity 4 is persistent (quadrant 0); a non-persistent id would be rejected.
53
+ transport.send({ id: 42, kind: "writeEntityLocation", entity: 4, archetypeId: 5, rowIndex: 3 });
54
+ await new Promise(resolve => setTimeout(resolve, 0));
55
+ expect(acks).toEqual([{ id: 42, error: undefined }]);
56
+ off();
57
+ }
58
+ finally {
59
+ await transport.close();
60
+ }
61
+ });
62
+ it("delivers error acks when the router rejects", async () => {
63
+ const backend = createMemoryBackend();
64
+ const transport = createInprocessTransport(backend);
65
+ try {
66
+ const acks = [];
67
+ transport.onMessage(msg => {
68
+ if (msg.kind === "ack")
69
+ acks.push({ id: msg.id, error: msg.error });
70
+ });
71
+ // writeEntityLocation rejects negative ("ephemeral")
72
+ // entities by design. Use it as the trigger to verify the
73
+ // router surfaces the rejection as an ack message with
74
+ // `error` populated rather than an unhandled rejection.
75
+ transport.send({
76
+ id: 7,
77
+ kind: "writeEntityLocation",
78
+ entity: -1,
79
+ archetypeId: 0,
80
+ rowIndex: 0,
81
+ });
82
+ // Wait one microtask + one macrotask to let the async
83
+ // dispatch settle.
84
+ await new Promise(resolve => setTimeout(resolve, 0));
85
+ expect(acks.length).toBe(1);
86
+ expect(acks[0].id).toBe(7);
87
+ expect(acks[0].error).toBeDefined();
88
+ }
89
+ finally {
90
+ await transport.close();
91
+ }
92
+ });
93
+ it("rejects sends after close", async () => {
94
+ const backend = createMemoryBackend();
95
+ const transport = createInprocessTransport(backend);
96
+ await transport.close();
97
+ expect(() => transport.send({ id: 1, kind: "writeEntityLocation", entity: 1, archetypeId: 0, rowIndex: 0 })).toThrow();
98
+ });
99
+ });
100
+ //# sourceMappingURL=inprocess-transport.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inprocess-transport.test.js","sourceRoot":"","sources":["../../src/transport/inprocess-transport.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { PersistenceBackend } from "../backend/persistence-backend.js";
2
+ import type { PersistOp } from "./transport.js";
3
+ /**
4
+ * Worker-side router that translates {@link PersistOp} messages into
5
+ * {@link PersistenceBackend} operations. Owns a small handle cache so
6
+ * repeated writes to the same column reuse one open file.
7
+ */
8
+ export interface PersistRouter {
9
+ handle(op: PersistOp): Promise<unknown>;
10
+ close(): Promise<void>;
11
+ }
12
+ export declare const createPersistRouter: (backend: PersistenceBackend) => PersistRouter;