@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,89 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ //
3
+ // Probe: does an INTERMEDIATE transaction that relocates a persistent
4
+ // entity (via swap-remove) desync the persisted image?
5
+ //
6
+ // An async-generator transaction applies each non-final yield as an
7
+ // INTERMEDIATE step, rolls it back, then commits the return value. The
8
+ // persistence service skips intermediate transactions wholesale. The
9
+ // yield below deletes entity A, which swap-moves the last row (C) into
10
+ // A's vacated row; the rollback then re-inserts A at a fresh row. So by
11
+ // the time the (persisted) commit runs, A and C sit at different
12
+ // physical rows than the last checkpoint saw — a relocation the
13
+ // persistence layer never observed as part of a persisted transaction.
14
+ //
15
+ // The commit does a value-only update of A. If persistence decides a
16
+ // partial (per-component) write is safe, it writes A's one column at
17
+ // A's *current* row while the on-disk image still has a different
18
+ // entity's bytes there → corruption of the neighbor.
19
+ import { Database } from "@adobe/data/ecs";
20
+ import { F32 } from "@adobe/data/math";
21
+ import { beforeEach, describe, expect, it } from "vitest";
22
+ import { createMemoryBackend } from "../backend/memory-backend.js";
23
+ import { createWorkerPersistenceService } from "./create-worker-persistence-service.js";
24
+ const plugin = Database.Plugin.create({
25
+ components: {
26
+ value: F32.schema,
27
+ },
28
+ archetypes: {
29
+ Item: ["value"],
30
+ },
31
+ transactions: {
32
+ spawn(t, value) {
33
+ return t.archetypes.Item.insert({ value });
34
+ },
35
+ killOrSet(t, arg) {
36
+ if (arg.kind === "kill") {
37
+ t.delete(arg.entity);
38
+ }
39
+ else {
40
+ t.update(arg.entity, { value: arg.value });
41
+ }
42
+ },
43
+ },
44
+ });
45
+ const noCheckpoint = { everyNTransactions: 0, idleMs: 0 };
46
+ describe("intermediate relocation durability", () => {
47
+ let backend;
48
+ beforeEach(() => {
49
+ backend = createMemoryBackend();
50
+ });
51
+ it("keeps a swap-moved neighbor intact when a relocation happens inside an intermediate transaction", async () => {
52
+ const db1 = Database.create(plugin);
53
+ const svc1 = await createWorkerPersistenceService({
54
+ database: db1,
55
+ backend,
56
+ checkpoint: noCheckpoint,
57
+ });
58
+ const a = db1.transactions.spawn(1);
59
+ const b = db1.transactions.spawn(2);
60
+ const c = db1.transactions.spawn(3);
61
+ await svc1.flush();
62
+ await svc1.checkpoint();
63
+ // Intermediate delete of A (swap-moves C into A's row), rolled
64
+ // back, then a persisted commit that value-updates A.
65
+ db1.transactions.killOrSet(() => (async function* () {
66
+ yield { kind: "kill", entity: a };
67
+ return { kind: "set", entity: a, value: 99 };
68
+ })());
69
+ await new Promise((resolve) => setTimeout(resolve, 25));
70
+ await svc1.flush();
71
+ await svc1.checkpoint();
72
+ await svc1.dispose();
73
+ const db2 = Database.create(plugin);
74
+ const svc2 = await createWorkerPersistenceService({
75
+ database: db2,
76
+ backend,
77
+ checkpoint: noCheckpoint,
78
+ });
79
+ await svc2.load();
80
+ await svc2.dispose();
81
+ const va = db2.read(a);
82
+ const vb = db2.read(b);
83
+ const vc = db2.read(c);
84
+ expect(va?.value).toBe(99);
85
+ expect(vb?.value).toBe(2);
86
+ expect(vc?.value).toBe(3);
87
+ });
88
+ });
89
+ //# sourceMappingURL=intermediate-relocation-durability.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intermediate-relocation-durability.test.js","sourceRoot":"","sources":["../../src/service/intermediate-relocation-durability.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Archetype, Database, ReadonlyArchetype } from "@adobe/data/ecs";
2
+ import type { Store } from "@adobe/data/ecs";
3
+ import type { TypedBuffer } from "@adobe/data/typed-buffer";
4
+ /**
5
+ * Return the mutable {@link Store} that backs `database`. The cast is
6
+ * sound because every database produced by `createDatabase()` exposes
7
+ * `.store` at runtime (see `DatabaseWithStore` for the contract).
8
+ */
9
+ export declare const getMutableStore: (database: Database<any, any, any, any, any, any, any, any>) => Store<any, any, any>;
10
+ /**
11
+ * Return the named archetype as its mutable view. The runtime objects
12
+ * exposed by `store.archetypes[name]` are the same instances created
13
+ * with mutable `rowCount` / `rowCapacity` and writable column buffers;
14
+ * only the public type narrows them to {@link ReadonlyArchetype}.
15
+ */
16
+ export declare const asMutableArchetype: (a: ReadonlyArchetype<any>) => Archetype<any>;
17
+ /**
18
+ * Look up a column buffer by its component name. The columns object's
19
+ * declared type uses specific component keys; this helper widens that
20
+ * to a string-indexed view so we can iterate based on
21
+ * `archetype.components` (a `ReadonlySet<string>`).
22
+ *
23
+ * Returns `undefined` when the component is absent — the runtime
24
+ * shape guarantees the value is either a `TypedBuffer<unknown>` or
25
+ * missing.
26
+ */
27
+ export declare const getColumn: (archetype: ReadonlyArchetype<any>, component: string) => TypedBuffer<unknown> | undefined;
28
+ /**
29
+ * Like {@link getColumn} but returns a `TypedBuffer<number>`. Used
30
+ * for the implicit `id` column, which always stores entity ids.
31
+ * Returns `undefined` when the archetype has no `id` column (which
32
+ * shouldn't happen in normal operation; callers handle it defensively).
33
+ */
34
+ export declare const getIdColumn: (archetype: ReadonlyArchetype<any>) => TypedBuffer<number> | undefined;
@@ -0,0 +1,43 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ //
3
+ // Centralized type assertions used by the persistence service. These
4
+ // are the only casts in the package; every other module uses the
5
+ // public types. Each cast here is justified by a comment explaining
6
+ // what runtime contract makes it sound.
7
+ /**
8
+ * Return the mutable {@link Store} that backs `database`. The cast is
9
+ * sound because every database produced by `createDatabase()` exposes
10
+ * `.store` at runtime (see `DatabaseWithStore` for the contract).
11
+ */
12
+ export const getMutableStore = (database) => database.store;
13
+ /**
14
+ * Return the named archetype as its mutable view. The runtime objects
15
+ * exposed by `store.archetypes[name]` are the same instances created
16
+ * with mutable `rowCount` / `rowCapacity` and writable column buffers;
17
+ * only the public type narrows them to {@link ReadonlyArchetype}.
18
+ */
19
+ export const asMutableArchetype = (a) => a;
20
+ /**
21
+ * Look up a column buffer by its component name. The columns object's
22
+ * declared type uses specific component keys; this helper widens that
23
+ * to a string-indexed view so we can iterate based on
24
+ * `archetype.components` (a `ReadonlySet<string>`).
25
+ *
26
+ * Returns `undefined` when the component is absent — the runtime
27
+ * shape guarantees the value is either a `TypedBuffer<unknown>` or
28
+ * missing.
29
+ */
30
+ export const getColumn = (archetype, component) => {
31
+ const columns = archetype.columns;
32
+ return columns[component];
33
+ };
34
+ /**
35
+ * Like {@link getColumn} but returns a `TypedBuffer<number>`. Used
36
+ * for the implicit `id` column, which always stores entity ids.
37
+ * Returns `undefined` when the archetype has no `id` column (which
38
+ * shouldn't happen in normal operation; callers handle it defensively).
39
+ */
40
+ export const getIdColumn = (archetype) => {
41
+ return getColumn(archetype, "id");
42
+ };
43
+ //# sourceMappingURL=internal-access.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-access.js","sourceRoot":"","sources":["../../src/service/internal-access.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,qEAAqE;AACrE,iEAAiE;AACjE,oEAAoE;AACpE,wCAAwC;AAqBxC;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC3B,QAA0D,EACtC,EAAE,CAAE,QAA8B,CAAC,KAAK,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAC9B,CAAyB,EACX,EAAE,CAAC,CAAmB,CAAC;AAEzC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CACrB,SAAiC,EACjC,SAAiB,EACe,EAAE;IAClC,MAAM,OAAO,GAAG,SAAS,CAAC,OAA2D,CAAC;IACtF,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC;AAC9B,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACvB,SAAiC,EACF,EAAE;IACjC,OAAO,SAAS,CAAC,SAAS,EAAE,IAAI,CAAoC,CAAC;AACzE,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,424 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { Database } from "@adobe/data/ecs";
3
+ import { F32, Vec3 } from "@adobe/data/math";
4
+ import { describe, expect, it } from "vitest";
5
+ import { createMemoryBackend } from "../backend/memory-backend.js";
6
+ import { createWorkerPersistenceService } from "./create-worker-persistence-service.js";
7
+ /**
8
+ * Journal-replay focused tests. These exercise paths where the
9
+ * snapshot (manifest + column files + entity-location files) is *not*
10
+ * up to date and the journal must roll the database forward, plus
11
+ * crash-recovery scenarios where the journal itself is partially
12
+ * written or where the checkpoint was killed mid-step.
13
+ */
14
+ const particlePlugin = Database.Plugin.create({
15
+ components: {
16
+ position: Vec3.schema,
17
+ velocity: Vec3.schema,
18
+ mass: F32.schema,
19
+ },
20
+ archetypes: {
21
+ Particle: ["position", "velocity", "mass"],
22
+ },
23
+ transactions: {
24
+ spawn(t, args) {
25
+ return t.archetypes.Particle.insert({
26
+ position: [args.x, args.y, args.z],
27
+ velocity: [0, 0, 0],
28
+ mass: args.mass,
29
+ });
30
+ },
31
+ move(t, args) {
32
+ t.update(args.entity, { position: [args.x, args.y, args.z] });
33
+ },
34
+ kill(t, entity) {
35
+ t.delete(entity);
36
+ },
37
+ },
38
+ });
39
+ const createDb = () => Database.create(particlePlugin);
40
+ const expectEntity = (db, entity, expected) => {
41
+ const view = db.read(entity);
42
+ expect(view).not.toBeNull();
43
+ if (view === null)
44
+ return;
45
+ expect(Array.from(view.position)).toEqual([...expected.position]);
46
+ expect(Array.from(view.velocity)).toEqual([...expected.velocity]);
47
+ expect(view.mass).toBe(expected.mass);
48
+ };
49
+ const readBackendFile = async (backend, path) => {
50
+ const file = await backend.open(path);
51
+ const size = await file.size();
52
+ if (size === 0) {
53
+ await file.close();
54
+ return new Uint8Array(0);
55
+ }
56
+ const bytes = await file.readAt(0, size);
57
+ await file.close();
58
+ // Detach from any internal aliasing.
59
+ return new Uint8Array(bytes);
60
+ };
61
+ const writeBackendFile = async (backend, path, bytes) => {
62
+ const file = await backend.open(path);
63
+ await file.truncate(0);
64
+ if (bytes.byteLength > 0)
65
+ await file.writeAt(0, bytes);
66
+ await file.sync();
67
+ await file.close();
68
+ };
69
+ describe("WorkerPersistenceService.load (journal replay)", () => {
70
+ it("rolls forward changes that landed in the journal but were never checkpointed", async () => {
71
+ const backend = createMemoryBackend();
72
+ // Phase A: spawn one entity, checkpoint (puts it in column files).
73
+ const dbA = createDb();
74
+ const svcA = await createWorkerPersistenceService({
75
+ database: dbA,
76
+ backend,
77
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
78
+ });
79
+ const e0 = dbA.transactions.spawn({ x: 1, y: 2, z: 3, mass: 10 });
80
+ await svcA.flush();
81
+ await svcA.checkpoint();
82
+ // Phase B: spawn a second entity and move e0 — these go into
83
+ // the journal only (no further checkpoint).
84
+ const e1 = dbA.transactions.spawn({ x: 4, y: 5, z: 6, mass: 20 });
85
+ dbA.transactions.move({ entity: e0, x: 100, y: 200, z: 300 });
86
+ await svcA.flush();
87
+ // Note: NO checkpoint here. Journal carries the diff.
88
+ await svcA.dispose();
89
+ const dbB = createDb();
90
+ const svcB = await createWorkerPersistenceService({
91
+ database: dbB,
92
+ backend,
93
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
94
+ });
95
+ await svcB.load();
96
+ // Both the post-checkpoint state and the journal-only diffs
97
+ // must be visible.
98
+ expectEntity(dbB, e0, { position: [100, 200, 300], velocity: [0, 0, 0], mass: 10 });
99
+ expectEntity(dbB, e1, { position: [4, 5, 6], velocity: [0, 0, 0], mass: 20 });
100
+ await svcB.dispose();
101
+ });
102
+ it("rebuilds the world from journal entries alone (empty snapshot)", async () => {
103
+ // Write an empty checkpoint first so meta.json exists and the
104
+ // snapshot is genuinely empty, then add entities — those go
105
+ // *only* into the journal. Replay must reconstruct them with
106
+ // no help from column files.
107
+ const backend = createMemoryBackend();
108
+ const dbA = createDb();
109
+ const svcA = await createWorkerPersistenceService({
110
+ database: dbA,
111
+ backend,
112
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
113
+ });
114
+ // Empty checkpoint: writes a manifest covering an empty world.
115
+ await svcA.flush();
116
+ await svcA.checkpoint();
117
+ const e0 = dbA.transactions.spawn({ x: 11, y: 12, z: 13, mass: 1 });
118
+ const e1 = dbA.transactions.spawn({ x: 21, y: 22, z: 23, mass: 2 });
119
+ const e2 = dbA.transactions.spawn({ x: 31, y: 32, z: 33, mass: 3 });
120
+ await svcA.flush();
121
+ // No checkpoint here — these three entities live entirely in
122
+ // the journal.
123
+ await svcA.dispose();
124
+ const dbB = createDb();
125
+ const svcB = await createWorkerPersistenceService({
126
+ database: dbB,
127
+ backend,
128
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
129
+ });
130
+ await svcB.load();
131
+ expectEntity(dbB, e0, { position: [11, 12, 13], velocity: [0, 0, 0], mass: 1 });
132
+ expectEntity(dbB, e1, { position: [21, 22, 23], velocity: [0, 0, 0], mass: 2 });
133
+ expectEntity(dbB, e2, { position: [31, 32, 33], velocity: [0, 0, 0], mass: 3 });
134
+ await svcB.dispose();
135
+ });
136
+ it("replay is idempotent: loading twice in a row produces the same state", async () => {
137
+ const backend = createMemoryBackend();
138
+ const dbA = createDb();
139
+ const svcA = await createWorkerPersistenceService({
140
+ database: dbA,
141
+ backend,
142
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
143
+ });
144
+ const e0 = dbA.transactions.spawn({ x: 1, y: 2, z: 3, mass: 7 });
145
+ await svcA.flush();
146
+ await svcA.checkpoint();
147
+ // Post-checkpoint diff carried by journal:
148
+ const e1 = dbA.transactions.spawn({ x: 4, y: 5, z: 6, mass: 8 });
149
+ dbA.transactions.move({ entity: e0, x: -1, y: -2, z: -3 });
150
+ await svcA.flush();
151
+ await svcA.dispose();
152
+ // First load.
153
+ const dbB = createDb();
154
+ const svcB = await createWorkerPersistenceService({
155
+ database: dbB,
156
+ backend,
157
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
158
+ });
159
+ await svcB.load();
160
+ await svcB.dispose();
161
+ // Second load on a fresh database — same backend.
162
+ const dbC = createDb();
163
+ const svcC = await createWorkerPersistenceService({
164
+ database: dbC,
165
+ backend,
166
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
167
+ });
168
+ await svcC.load();
169
+ expectEntity(dbC, e0, { position: [-1, -2, -3], velocity: [0, 0, 0], mass: 7 });
170
+ expectEntity(dbC, e1, { position: [4, 5, 6], velocity: [0, 0, 0], mass: 8 });
171
+ await svcC.dispose();
172
+ });
173
+ it("preserves last-write-wins ordering across multiple journal entries for the same row", async () => {
174
+ const backend = createMemoryBackend();
175
+ const dbA = createDb();
176
+ const svcA = await createWorkerPersistenceService({
177
+ database: dbA,
178
+ backend,
179
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
180
+ });
181
+ const e0 = dbA.transactions.spawn({ x: 1, y: 1, z: 1, mass: 1 });
182
+ await svcA.flush();
183
+ await svcA.checkpoint();
184
+ // Three sequential moves — only the last position should win.
185
+ dbA.transactions.move({ entity: e0, x: 2, y: 2, z: 2 });
186
+ dbA.transactions.move({ entity: e0, x: 3, y: 3, z: 3 });
187
+ dbA.transactions.move({ entity: e0, x: 9, y: 9, z: 9 });
188
+ await svcA.flush();
189
+ await svcA.dispose();
190
+ const dbB = createDb();
191
+ const svcB = await createWorkerPersistenceService({
192
+ database: dbB,
193
+ backend,
194
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
195
+ });
196
+ await svcB.load();
197
+ expectEntity(dbB, e0, { position: [9, 9, 9], velocity: [0, 0, 0], mass: 1 });
198
+ await svcB.dispose();
199
+ });
200
+ });
201
+ describe("WorkerPersistenceService.load (crash recovery)", () => {
202
+ it("torn journal tail: a partial entry at the end is dropped and earlier entries are recovered", async () => {
203
+ const backend = createMemoryBackend();
204
+ const dbA = createDb();
205
+ const svcA = await createWorkerPersistenceService({
206
+ database: dbA,
207
+ backend,
208
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
209
+ });
210
+ const e0 = dbA.transactions.spawn({ x: 1, y: 2, z: 3, mass: 10 });
211
+ await svcA.flush();
212
+ await svcA.checkpoint();
213
+ // Journal now empty; subsequent transactions go into journal.
214
+ const e1 = dbA.transactions.spawn({ x: 4, y: 5, z: 6, mass: 20 });
215
+ await svcA.flush();
216
+ await svcA.dispose();
217
+ // Simulate a crash mid-write at the tail: truncate the journal
218
+ // by 5 bytes from the end. The last entry's payload (or part
219
+ // of its header) becomes torn — decodeJournalStream should
220
+ // stop at the previous good boundary.
221
+ const journalBytes = await readBackendFile(backend, "journal.bin");
222
+ expect(journalBytes.byteLength).toBeGreaterThan(5);
223
+ const torn = journalBytes.subarray(0, journalBytes.byteLength - 5);
224
+ await writeBackendFile(backend, "journal.bin", torn);
225
+ const dbB = createDb();
226
+ const svcB = await createWorkerPersistenceService({
227
+ database: dbB,
228
+ backend,
229
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
230
+ });
231
+ await svcB.load();
232
+ // e0 is recovered from the column files (it was checkpointed).
233
+ expectEntity(dbB, e0, { position: [1, 2, 3], velocity: [0, 0, 0], mass: 10 });
234
+ // e1 may or may not be recovered depending on which journal
235
+ // entry got cut — but the load must NOT throw, must NOT
236
+ // corrupt e0, and any entity it does report must have its
237
+ // values match the original transaction. Verify load
238
+ // succeeded and e0 is intact.
239
+ const view = dbB.read(e1);
240
+ if (view !== null) {
241
+ // If e1 was partly journaled, the components that DID
242
+ // make it should match the original values — torn
243
+ // entries are dropped, never partially applied.
244
+ expect(view.mass).toBe(20);
245
+ expect(Array.from(view.position)).toEqual([4, 5, 6]);
246
+ }
247
+ await svcB.dispose();
248
+ });
249
+ it("crash mid-checkpoint: manifest written, journal not yet truncated, load is idempotent", async () => {
250
+ // The checkpoint protocol writes meta.json then truncates
251
+ // journal.bin. If we crash between those steps, the manifest
252
+ // reflects the new state but the journal still has the
253
+ // entries that the manifest already absorbed. Replay must be
254
+ // idempotent so this doesn't double-apply or corrupt rows.
255
+ const backend = createMemoryBackend();
256
+ const dbA = createDb();
257
+ const svcA = await createWorkerPersistenceService({
258
+ database: dbA,
259
+ backend,
260
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
261
+ });
262
+ const e0 = dbA.transactions.spawn({ x: 1, y: 2, z: 3, mass: 10 });
263
+ await svcA.flush();
264
+ await svcA.checkpoint();
265
+ const e1 = dbA.transactions.spawn({ x: 4, y: 5, z: 6, mass: 20 });
266
+ dbA.transactions.move({ entity: e0, x: 100, y: 200, z: 300 });
267
+ await svcA.flush();
268
+ // Snapshot the journal RIGHT BEFORE the next checkpoint
269
+ // truncates it, then run checkpoint, then RE-WRITE the
270
+ // pre-checkpoint journal back in to simulate the crash
271
+ // between "manifest written" and "journal truncated".
272
+ const preCheckpointJournal = await readBackendFile(backend, "journal.bin");
273
+ await svcA.checkpoint();
274
+ await svcA.dispose();
275
+ // Restore the pre-truncate journal to simulate the crash.
276
+ await writeBackendFile(backend, "journal.bin", preCheckpointJournal);
277
+ const dbB = createDb();
278
+ const svcB = await createWorkerPersistenceService({
279
+ database: dbB,
280
+ backend,
281
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
282
+ });
283
+ await svcB.load();
284
+ expectEntity(dbB, e0, { position: [100, 200, 300], velocity: [0, 0, 0], mass: 10 });
285
+ expectEntity(dbB, e1, { position: [4, 5, 6], velocity: [0, 0, 0], mass: 20 });
286
+ await svcB.dispose();
287
+ });
288
+ it("crash with no journal at all: load succeeds from the snapshot alone", async () => {
289
+ // Sanity check: if the journal file is missing/empty (e.g. a
290
+ // clean checkpoint), load() must still produce the right
291
+ // state and skip replay.
292
+ const backend = createMemoryBackend();
293
+ const dbA = createDb();
294
+ const svcA = await createWorkerPersistenceService({
295
+ database: dbA,
296
+ backend,
297
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
298
+ });
299
+ const e0 = dbA.transactions.spawn({ x: 9, y: 8, z: 7, mass: 6 });
300
+ await svcA.flush();
301
+ await svcA.checkpoint();
302
+ await svcA.dispose();
303
+ // After a clean checkpoint the journal should be 0 bytes.
304
+ const journalBytes = await readBackendFile(backend, "journal.bin");
305
+ expect(journalBytes.byteLength).toBe(0);
306
+ const dbB = createDb();
307
+ const svcB = await createWorkerPersistenceService({
308
+ database: dbB,
309
+ backend,
310
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
311
+ });
312
+ await svcB.load();
313
+ expectEntity(dbB, e0, { position: [9, 8, 7], velocity: [0, 0, 0], mass: 6 });
314
+ await svcB.dispose();
315
+ });
316
+ it("torn tail before commit: the dropped tx's entries are not reapplied by replay", async () => {
317
+ // Journal-level tx atomicity: replay buffers entries by txId
318
+ // and only applies them when it sees a `commit` entry for
319
+ // that tx. This test verifies the BUFFERING behavior — a
320
+ // dropped tx whose commit never made it to disk does not get
321
+ // reapplied to other entities.
322
+ //
323
+ // Important caveat: the column-slice file write happens
324
+ // eagerly (before its commit marker is durable), so the
325
+ // column file may already reflect the dropped tx's value.
326
+ // Full row-level atomicity across crashes would require
327
+ // shadow paging or deferred column writes; we explicitly do
328
+ // not promise it. What we DO promise: the journal itself is
329
+ // consistent — un-committed entries never leak into other
330
+ // entities, and replay never half-applies a multi-entity tx
331
+ // (entity X updated, entity Y not).
332
+ const backend = createMemoryBackend();
333
+ const dbA = createDb();
334
+ const svcA = await createWorkerPersistenceService({
335
+ database: dbA,
336
+ backend,
337
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
338
+ });
339
+ const e0 = dbA.transactions.spawn({ x: 1, y: 2, z: 3, mass: 10 });
340
+ const e1 = dbA.transactions.spawn({ x: 4, y: 5, z: 6, mass: 20 });
341
+ await svcA.flush();
342
+ await svcA.checkpoint();
343
+ // Single tx that touches both e0 and e1. After flushing, the
344
+ // journal contains entries for both entities + a commit.
345
+ // Truncate the trailing commit so replay drops the tx.
346
+ dbA.transactions.move({ entity: e0, x: 100, y: 200, z: 300 });
347
+ dbA.transactions.move({ entity: e1, x: 400, y: 500, z: 600 });
348
+ await svcA.flush();
349
+ await svcA.dispose();
350
+ // Drop just the very last byte: this corrupts the final
351
+ // commit entry's header, which decodeJournalStream tolerates
352
+ // by stopping early. The tx's data entries arrive at replay
353
+ // un-committed and are buffered → discarded.
354
+ const journalBytes = await readBackendFile(backend, "journal.bin");
355
+ const torn = journalBytes.subarray(0, journalBytes.byteLength - 1);
356
+ await writeBackendFile(backend, "journal.bin", torn);
357
+ const dbB = createDb();
358
+ const svcB = await createWorkerPersistenceService({
359
+ database: dbB,
360
+ backend,
361
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
362
+ });
363
+ await svcB.load();
364
+ // Both entities exist (the snapshot from the prior checkpoint
365
+ // is intact) and load doesn't crash. Their column-file bytes
366
+ // may reflect the dropped tx (eager writes), but the journal
367
+ // dropped the entries — proving replay didn't re-apply them.
368
+ // We assert the entities are present and their non-position
369
+ // components are intact (since those weren't touched).
370
+ const v0 = dbB.read(e0);
371
+ const v1 = dbB.read(e1);
372
+ expect(v0?.mass).toBe(10);
373
+ expect(v1?.mass).toBe(20);
374
+ await svcB.dispose();
375
+ });
376
+ it("torn journal at archetype-introducing entry: pre-existing entities still load cleanly", async () => {
377
+ // Specifically targets the case where the truncated tail
378
+ // would have introduced a new row beyond the snapshot's
379
+ // rowCount. Replay should grow the archetype on demand;
380
+ // a torn write means the entry is silently dropped.
381
+ const backend = createMemoryBackend();
382
+ const dbA = createDb();
383
+ const svcA = await createWorkerPersistenceService({
384
+ database: dbA,
385
+ backend,
386
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
387
+ });
388
+ const e0 = dbA.transactions.spawn({ x: 1, y: 1, z: 1, mass: 1 });
389
+ const e1 = dbA.transactions.spawn({ x: 2, y: 2, z: 2, mass: 2 });
390
+ await svcA.flush();
391
+ await svcA.checkpoint();
392
+ // Add a third entity; the journal will hold its 3 update
393
+ // entries (one per component).
394
+ const e2 = dbA.transactions.spawn({ x: 3, y: 3, z: 3, mass: 3 });
395
+ await svcA.flush();
396
+ await svcA.dispose();
397
+ // Truncate the journal by half — guarantees the e2 entries
398
+ // are at least partially cut.
399
+ const journalBytes = await readBackendFile(backend, "journal.bin");
400
+ const half = Math.floor(journalBytes.byteLength / 2);
401
+ await writeBackendFile(backend, "journal.bin", journalBytes.subarray(0, half));
402
+ const dbB = createDb();
403
+ const svcB = await createWorkerPersistenceService({
404
+ database: dbB,
405
+ backend,
406
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
407
+ });
408
+ await svcB.load();
409
+ // e0 and e1 are in the snapshot — must be unaffected.
410
+ expectEntity(dbB, e0, { position: [1, 1, 1], velocity: [0, 0, 0], mass: 1 });
411
+ expectEntity(dbB, e1, { position: [2, 2, 2], velocity: [0, 0, 0], mass: 2 });
412
+ // e2 may or may not be partially recovered — but if present,
413
+ // any component that did make it must match. (We don't
414
+ // strictly assert presence here — the test's contract is
415
+ // "load doesn't crash and snapshot rows are intact".)
416
+ const e2View = dbB.read(e2);
417
+ // No assertion on e2View; the only contract is no corruption
418
+ // of e0/e1 above. The dummy use silences the unused-var
419
+ // diagnostic.
420
+ void e2View;
421
+ await svcB.dispose();
422
+ });
423
+ });
424
+ //# sourceMappingURL=journal-replay.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal-replay.test.js","sourceRoot":"","sources":["../../src/service/journal-replay.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};