@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,74 @@
1
+ /**
2
+ * Minimal async-aware performance harness for the persistence layer.
3
+ *
4
+ * Differs from `packages/data/src/perftest/perf-test.ts` in two ways:
5
+ *
6
+ * 1. `run` is `async` because every persistence operation drains
7
+ * through a transport whose acks resolve on a microtask. A
8
+ * sync-only harness would either record zero (work hasn't
9
+ * finished) or include only the synchronous `send()` push,
10
+ * which would be misleading.
11
+ *
12
+ * 2. There's a `setupBatch` hook called once per measurement loop
13
+ * iteration. Some scenarios (e.g. "steady delete") consume an
14
+ * entity per iteration; this lets the scenario refill its
15
+ * working set without that cost being attributed to `run()`.
16
+ *
17
+ * The harness is intentionally tiny — it owns warmup, auto-tuning,
18
+ * the measurement window, and printing. Scenarios own everything
19
+ * else (database, transport, backend, scoring).
20
+ */
21
+ export interface PerfScenario {
22
+ /**
23
+ * Friendly name shown in the results table.
24
+ */
25
+ readonly name: string;
26
+ /**
27
+ * One-time setup (database creation, populating N entities, etc).
28
+ * Called once per `n` choice during auto-tune; the measurement
29
+ * window itself reuses the resulting state.
30
+ */
31
+ setup(n: number): Promise<void>;
32
+ /**
33
+ * Optional per-iteration setup. Returns a cost-free reference
34
+ * (entity ids, indices, etc) that `run()` can use without
35
+ * computing it during measurement. Called once per `run()` call.
36
+ */
37
+ setupBatch?(): Promise<unknown>;
38
+ /**
39
+ * The measured operation. Must perform exactly ONE logical
40
+ * persistence operation (one transaction, one checkpoint, one
41
+ * load — whatever the scenario says it measures). Returns when
42
+ * the operation has fully drained on the persistence side.
43
+ */
44
+ run(batch: unknown): Promise<void>;
45
+ /**
46
+ * Tear down the database, dispose the service, close the
47
+ * transport. Called once per scenario.
48
+ */
49
+ cleanup(): Promise<void>;
50
+ /**
51
+ * Auto-tune seed. Scenarios with high per-op cost should set
52
+ * this lower than the default (1000) so the first probe doesn't
53
+ * waste the budget.
54
+ */
55
+ readonly startN?: number;
56
+ }
57
+ export interface PerfResult {
58
+ readonly name: string;
59
+ readonly n: number;
60
+ readonly samples: number;
61
+ readonly meanUs: number;
62
+ readonly minUs: number;
63
+ readonly p50Us: number;
64
+ readonly p99Us: number;
65
+ readonly opsPerSec: number;
66
+ }
67
+ /**
68
+ * Run a single scenario through the warmup + measurement pipeline.
69
+ */
70
+ export declare const runScenario: (scenario: PerfScenario) => Promise<PerfResult>;
71
+ /**
72
+ * Run all scenarios sequentially and print a results table.
73
+ */
74
+ export declare const runAll: (scenarios: readonly PerfScenario[]) => Promise<readonly PerfResult[]>;
@@ -0,0 +1,147 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ const DEFAULT_START_N = 1000;
3
+ // Target per-iteration time: 0.5–150 ms. Below 0.5 ms timing
4
+ // resolution dominates; above 150 ms we get too few samples in the
5
+ // 1-second budget for stable percentiles. The wide upper bound is
6
+ // deliberate — scenarios whose cold probe drifts to ~70 ms because
7
+ // of GC noise should NOT trigger auto-tune to halve N, because the
8
+ // halved version is then evaluated under DIFFERENT per-tx overhead
9
+ // proportions and produces non-comparable numbers across runs.
10
+ const TARGET_MIN_MS = 0.5;
11
+ const TARGET_MAX_MS = 150;
12
+ const MIN_AUTO_N = 1;
13
+ const MAX_AUTO_N = 100_000;
14
+ const WARMUP_MS = 100;
15
+ const MEASURE_BUDGET_MS = 1000;
16
+ const now = () => performance.now();
17
+ const percentile = (sortedAsc, p) => {
18
+ if (sortedAsc.length === 0)
19
+ return 0;
20
+ const idx = Math.min(sortedAsc.length - 1, Math.floor((p / 100) * sortedAsc.length));
21
+ return sortedAsc[idx];
22
+ };
23
+ /**
24
+ * Auto-tune `n` so a single `run()` lands in TARGET_MIN_MS..TARGET_MAX_MS.
25
+ * Returns the chosen n and (re-)leaves the scenario set up at that n.
26
+ */
27
+ const tuneN = async (scenario) => {
28
+ let n = scenario.startN ?? DEFAULT_START_N;
29
+ for (let attempt = 0; attempt < 4; attempt++) {
30
+ await scenario.cleanup().catch(() => undefined);
31
+ await scenario.setup(n);
32
+ const batch = scenario.setupBatch ? await scenario.setupBatch() : undefined;
33
+ const start = now();
34
+ await scenario.run(batch);
35
+ const elapsed = Math.max(now() - start, 0.001);
36
+ if (elapsed >= TARGET_MIN_MS && elapsed <= TARGET_MAX_MS)
37
+ return n;
38
+ const target = (TARGET_MIN_MS + TARGET_MAX_MS) / 2;
39
+ const ratio = target / elapsed;
40
+ const next = Math.max(MIN_AUTO_N, Math.min(MAX_AUTO_N, Math.round(n * ratio)));
41
+ if (next === n)
42
+ return n;
43
+ n = next;
44
+ }
45
+ return n;
46
+ };
47
+ /**
48
+ * Run a single scenario through the warmup + measurement pipeline.
49
+ */
50
+ export const runScenario = async (scenario) => {
51
+ const n = await tuneN(scenario);
52
+ // Warmup: keep calling run() (re-batching as needed) for ~100ms so
53
+ // V8 fully optimizes hot functions before any sample is recorded.
54
+ const warmupEnd = now() + WARMUP_MS;
55
+ while (now() < warmupEnd) {
56
+ const batch = scenario.setupBatch ? await scenario.setupBatch() : undefined;
57
+ await scenario.run(batch);
58
+ }
59
+ // Measurement window. We sample as many runs as fit into the
60
+ // budget. Each sample is ms-per-run-of-N-ops; we convert to
61
+ // μs-per-op by dividing by n at report time.
62
+ const samplesMs = [];
63
+ const budgetEnd = now() + MEASURE_BUDGET_MS;
64
+ while (now() < budgetEnd) {
65
+ const batch = scenario.setupBatch ? await scenario.setupBatch() : undefined;
66
+ const start = now();
67
+ await scenario.run(batch);
68
+ const elapsed = now() - start;
69
+ samplesMs.push(elapsed);
70
+ }
71
+ await scenario.cleanup().catch(() => undefined);
72
+ if (samplesMs.length === 0) {
73
+ // Pathological: even a single run blew the budget. Report
74
+ // a single sample so callers can still see SOMETHING.
75
+ return {
76
+ name: scenario.name,
77
+ n,
78
+ samples: 0,
79
+ meanUs: NaN,
80
+ minUs: NaN,
81
+ p50Us: NaN,
82
+ p99Us: NaN,
83
+ opsPerSec: NaN,
84
+ };
85
+ }
86
+ const samplesUs = samplesMs.map(ms => (ms * 1000) / n);
87
+ const sorted = [...samplesUs].sort((a, b) => a - b);
88
+ const mean = samplesUs.reduce((a, b) => a + b, 0) / samplesUs.length;
89
+ const min = sorted[0];
90
+ const p50 = percentile(sorted, 50);
91
+ const p99 = percentile(sorted, 99);
92
+ const opsPerSec = mean > 0 ? 1_000_000 / mean : Infinity;
93
+ return {
94
+ name: scenario.name,
95
+ n,
96
+ samples: samplesMs.length,
97
+ meanUs: mean,
98
+ minUs: min,
99
+ p50Us: p50,
100
+ p99Us: p99,
101
+ opsPerSec,
102
+ };
103
+ };
104
+ /**
105
+ * Run all scenarios sequentially and print a results table.
106
+ */
107
+ export const runAll = async (scenarios) => {
108
+ const results = [];
109
+ for (const scenario of scenarios) {
110
+ process.stdout.write(` ${scenario.name} ... `);
111
+ const start = now();
112
+ try {
113
+ const result = await runScenario(scenario);
114
+ results.push(result);
115
+ const wall = ((now() - start) / 1000).toFixed(1);
116
+ process.stdout.write(`${result.meanUs.toFixed(2)} μs/op (${result.samples} samples, ${wall}s wall)\n`);
117
+ }
118
+ catch (err) {
119
+ process.stdout.write(`FAILED: ${err.message}\n`);
120
+ throw err;
121
+ }
122
+ }
123
+ printTable(results);
124
+ return results;
125
+ };
126
+ const printTable = (results) => {
127
+ if (results.length === 0)
128
+ return;
129
+ const rows = results.map(r => ({
130
+ scenario: r.name,
131
+ N: r.n,
132
+ samples: r.samples,
133
+ "μs/op (mean)": r.meanUs.toFixed(2),
134
+ "μs/op (min)": r.minUs.toFixed(2),
135
+ "μs/op (p50)": r.p50Us.toFixed(2),
136
+ "μs/op (p99)": r.p99Us.toFixed(2),
137
+ "ops/sec": Math.round(r.opsPerSec).toLocaleString(),
138
+ }));
139
+ if (typeof console.table === "function") {
140
+ console.table(rows);
141
+ }
142
+ else {
143
+ for (const row of rows)
144
+ console.log(row);
145
+ }
146
+ };
147
+ //# sourceMappingURL=perf-harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf-harness.js","sourceRoot":"","sources":["../../src/perftest/perf-harness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { PerfScenario } from "./perf-harness.js";
2
+ export declare const persistenceScenarios: readonly PerfScenario[];
@@ -0,0 +1,290 @@
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 { createMemoryBackend } from "../backend/memory-backend.js";
5
+ import { createWorkerPersistenceService } from "../service/create-worker-persistence-service.js";
6
+ // All scenarios share this database shape so wall-time numbers
7
+ // are directly comparable across scenarios. Three components, one
8
+ // archetype — small enough that per-tx work is dominated by the
9
+ // persistence layer itself, not the schema's encoder cost.
10
+ const createTestDb = () => {
11
+ const plugin = Database.Plugin.create({
12
+ components: {
13
+ position: Vec3.schema,
14
+ velocity: Vec3.schema,
15
+ mass: F32.schema,
16
+ },
17
+ archetypes: {
18
+ Particle: ["position", "velocity", "mass"],
19
+ },
20
+ transactions: {
21
+ spawn(t, args) {
22
+ return t.archetypes.Particle.insert({
23
+ position: [args.x, args.y, args.z],
24
+ velocity: [0, 0, 0],
25
+ mass: args.mass,
26
+ });
27
+ },
28
+ move(t, args) {
29
+ t.update(args.entity, { position: [args.x, args.y, args.z] });
30
+ },
31
+ updateAll(t, args) {
32
+ t.update(args.entity, {
33
+ position: [args.x, args.y, args.z],
34
+ velocity: [args.vx, args.vy, args.vz],
35
+ mass: args.mass,
36
+ });
37
+ },
38
+ kill(t, entity) {
39
+ t.delete(entity);
40
+ },
41
+ },
42
+ });
43
+ return Database.create(plugin);
44
+ };
45
+ const setupPopulated = async (n) => {
46
+ const db = createTestDb();
47
+ const backend = createMemoryBackend();
48
+ const service = await createWorkerPersistenceService({
49
+ database: db,
50
+ backend,
51
+ // Disable both checkpoint paths so they never fire during a
52
+ // measurement window and skew numbers. Each scenario that
53
+ // wants to measure checkpoint cost calls it explicitly.
54
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
55
+ });
56
+ const ids = [];
57
+ for (let i = 0; i < n; i++) {
58
+ const id = db.transactions.spawn({ x: i, y: i, z: i, mass: 1 });
59
+ ids.push(id);
60
+ }
61
+ await service.flush();
62
+ return { db, service, ids };
63
+ };
64
+ /**
65
+ * Steady-state per-tx update touching ONE component on ONE entity.
66
+ *
67
+ * This is the dominant case in real workloads: gameplay tick that
68
+ * moves a few entities per frame. The per-component-write
69
+ * optimization (architectural review #4) targets this case
70
+ * specifically — its win shows up here as a 3× drop vs writing all
71
+ * three columns per tx.
72
+ */
73
+ const moveOneComponent = () => {
74
+ let state = null;
75
+ let cursor = 0;
76
+ return {
77
+ name: "tx: update 1 component on 1 entity (steady)",
78
+ startN: 200,
79
+ async setup(n) {
80
+ state = await setupPopulated(1000);
81
+ cursor = 0;
82
+ void n; // n here is iterations per measurement, not world size
83
+ },
84
+ async run() {
85
+ const s = state;
86
+ for (let i = 0; i < 200; i++) {
87
+ const e = s.ids[cursor];
88
+ cursor = (cursor + 1) % s.ids.length;
89
+ s.db.transactions.move({ entity: e, x: i, y: i, z: i });
90
+ }
91
+ await s.service.flush();
92
+ },
93
+ async cleanup() {
94
+ await state?.service.dispose();
95
+ state = null;
96
+ },
97
+ };
98
+ };
99
+ const moveAllComponents = () => {
100
+ let state = null;
101
+ let cursor = 0;
102
+ return {
103
+ name: "tx: update 3 components on 1 entity",
104
+ startN: 200,
105
+ async setup() {
106
+ state = await setupPopulated(1000);
107
+ cursor = 0;
108
+ },
109
+ async run() {
110
+ const s = state;
111
+ for (let i = 0; i < 200; i++) {
112
+ const e = s.ids[cursor];
113
+ cursor = (cursor + 1) % s.ids.length;
114
+ s.db.transactions.updateAll({
115
+ entity: e,
116
+ x: i, y: i, z: i,
117
+ vx: -i, vy: -i, vz: -i,
118
+ mass: i + 1,
119
+ });
120
+ }
121
+ await s.service.flush();
122
+ },
123
+ async cleanup() {
124
+ await state?.service.dispose();
125
+ state = null;
126
+ },
127
+ };
128
+ };
129
+ const insertSteady = () => {
130
+ let state = null;
131
+ return {
132
+ name: "tx: insert (3 columns)",
133
+ startN: 200,
134
+ async setup() {
135
+ state = await setupPopulated(1000);
136
+ },
137
+ async run() {
138
+ const s = state;
139
+ for (let i = 0; i < 200; i++) {
140
+ s.db.transactions.spawn({ x: i, y: i, z: i, mass: 1 });
141
+ }
142
+ await s.service.flush();
143
+ },
144
+ async cleanup() {
145
+ await state?.service.dispose();
146
+ state = null;
147
+ },
148
+ };
149
+ };
150
+ /**
151
+ * Steady-state delete with the swap-remove side effect: the
152
+ * persistence service detects the moved entity and emits a synthetic
153
+ * full-row update for it. This scenario refills the working set in
154
+ * setupBatch so the iteration count is pinned.
155
+ */
156
+ const deleteWithSwap = () => {
157
+ let state = null;
158
+ let killCount = 0;
159
+ return {
160
+ name: "tx: delete + swap-remove side effect",
161
+ startN: 100,
162
+ async setup() {
163
+ state = await setupPopulated(2000);
164
+ killCount = 0;
165
+ },
166
+ async setupBatch() {
167
+ // Refill the working set so each measurement iteration
168
+ // has a known number of victims to kill. Done OUTSIDE
169
+ // run() so its cost isn't attributed to delete.
170
+ const s = state;
171
+ while (s.ids.length < 1000) {
172
+ const id = s.db.transactions.spawn({ x: 0, y: 0, z: 0, mass: 1 });
173
+ s.ids.push(id);
174
+ }
175
+ await s.service.flush();
176
+ },
177
+ async run() {
178
+ const s = state;
179
+ for (let i = 0; i < 100; i++) {
180
+ // Always delete from the middle so swap-remove
181
+ // actually triggers (deleting the LAST row would not).
182
+ const idx = Math.floor(s.ids.length / 2);
183
+ const e = s.ids[idx];
184
+ s.ids.splice(idx, 1);
185
+ s.db.transactions.kill(e);
186
+ killCount += 1;
187
+ }
188
+ await s.service.flush();
189
+ },
190
+ async cleanup() {
191
+ void killCount;
192
+ await state?.service.dispose();
193
+ state = null;
194
+ },
195
+ };
196
+ };
197
+ const checkpointAfterUpdates = () => {
198
+ let state = null;
199
+ let cursor = 0;
200
+ return {
201
+ name: "checkpoint: after 1k updates",
202
+ startN: 1,
203
+ async setup() {
204
+ state = await setupPopulated(1000);
205
+ cursor = 0;
206
+ },
207
+ async setupBatch() {
208
+ // Dirty 1k rows since the last checkpoint so the
209
+ // checkpoint actually has work to do (write a full
210
+ // manifest, then truncate the journal).
211
+ const s = state;
212
+ for (let i = 0; i < 1000; i++) {
213
+ const e = s.ids[cursor];
214
+ cursor = (cursor + 1) % s.ids.length;
215
+ s.db.transactions.move({ entity: e, x: i, y: i, z: i });
216
+ }
217
+ await s.service.flush();
218
+ },
219
+ async run() {
220
+ await state.service.checkpoint();
221
+ },
222
+ async cleanup() {
223
+ await state?.service.dispose();
224
+ state = null;
225
+ },
226
+ };
227
+ };
228
+ /**
229
+ * Cold-start load(): populate, checkpoint, dispose, then create a
230
+ * fresh service with a fresh database against the SAME backend and
231
+ * measure load() time. This is the single-shot recovery path users
232
+ * see at app startup.
233
+ */
234
+ const loadCold = () => {
235
+ let backend = null;
236
+ let svc = null;
237
+ let db = null;
238
+ return {
239
+ name: "load: 1k entities, single-shot",
240
+ startN: 1,
241
+ async setup() {
242
+ // One-time prep: build a fully-checkpointed snapshot in
243
+ // the backend that we'll re-load each iteration.
244
+ const seedDb = createTestDb();
245
+ backend = createMemoryBackend();
246
+ const seedSvc = await createWorkerPersistenceService({
247
+ database: seedDb,
248
+ backend,
249
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
250
+ });
251
+ for (let i = 0; i < 1000; i++) {
252
+ seedDb.transactions.spawn({ x: i, y: i, z: i, mass: 1 });
253
+ }
254
+ await seedSvc.flush();
255
+ await seedSvc.checkpoint();
256
+ await seedSvc.dispose();
257
+ },
258
+ async setupBatch() {
259
+ // A fresh database + service per iteration — load() is a
260
+ // one-shot operation and reusing the same service would
261
+ // make replay no-op after the first iteration.
262
+ if (svc !== null)
263
+ await svc.dispose();
264
+ db = createTestDb();
265
+ svc = await createWorkerPersistenceService({
266
+ database: db,
267
+ backend: backend,
268
+ checkpoint: { everyNTransactions: 0, idleMs: 0 },
269
+ });
270
+ },
271
+ async run() {
272
+ await svc.load();
273
+ },
274
+ async cleanup() {
275
+ await svc?.dispose();
276
+ svc = null;
277
+ db = null;
278
+ backend = null;
279
+ },
280
+ };
281
+ };
282
+ export const persistenceScenarios = [
283
+ moveOneComponent(),
284
+ moveAllComponents(),
285
+ insertSteady(),
286
+ deleteWithSwap(),
287
+ checkpointAfterUpdates(),
288
+ loadCold(),
289
+ ];
290
+ //# sourceMappingURL=persistence-perf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence-perf.js","sourceRoot":"","sources":["../../src/perftest/persistence-perf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { runAll } from "./perf-harness.js";
3
+ import { persistenceScenarios } from "./persistence-perf.js";
4
+ /**
5
+ * Persistence perftest entry point.
6
+ *
7
+ * Run with:
8
+ *
9
+ * pnpm --filter @adobe/data-persistence run perf
10
+ *
11
+ * The runner uses the in-process transport so wall-time numbers
12
+ * exclude postMessage overhead and isolate the persistence
13
+ * service's own per-tx cost. Worker-thread / web-worker numbers
14
+ * will add 1–10 μs of postMessage round-trip per op on top of
15
+ * what's reported here.
16
+ */
17
+ const main = async () => {
18
+ console.log("@adobe/data-persistence perftest");
19
+ console.log("================================");
20
+ console.log("(in-process transport; reported numbers exclude postMessage overhead)");
21
+ console.log("");
22
+ await runAll(persistenceScenarios);
23
+ };
24
+ main().catch((err) => {
25
+ console.error(err);
26
+ process.exit(1);
27
+ });
28
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/perftest/run.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;;;;;;GAYG;AACH,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IACnC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;AACvC,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { PersistenceProvider } from "./persistence-provider.js";
2
+ /**
3
+ * Creates an in-memory persistence provider. All data is lost when the
4
+ * mount is disposed.
5
+ *
6
+ * Primarily useful for tests and for prototyping without configuring a
7
+ * real storage backend.
8
+ *
9
+ * ```ts
10
+ * import { mount } from "@adobe/data-persistence";
11
+ * import { createMemoryProvider } from "@adobe/data-persistence";
12
+ *
13
+ * const m = await mount(createMemoryProvider(), database);
14
+ * ```
15
+ */
16
+ export declare const createMemoryProvider: () => PersistenceProvider;
@@ -0,0 +1,44 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { createMemoryBackend } from "../backend/memory-backend.js";
3
+ import { createInprocessTransport } from "../transport/inprocess-transport.js";
4
+ import { createIncrementalPersistenceService } from "../service/create-incremental-persistence-service.js";
5
+ /**
6
+ * Creates an in-memory persistence provider. All data is lost when the
7
+ * mount is disposed.
8
+ *
9
+ * Primarily useful for tests and for prototyping without configuring a
10
+ * real storage backend.
11
+ *
12
+ * ```ts
13
+ * import { mount } from "@adobe/data-persistence";
14
+ * import { createMemoryProvider } from "@adobe/data-persistence";
15
+ *
16
+ * const m = await mount(createMemoryProvider(), database);
17
+ * ```
18
+ */
19
+ export const createMemoryProvider = () => {
20
+ // A single backend shared across all mounts from this provider instance,
21
+ // so that a second mount can load data written by a previous mount.
22
+ const backend = createMemoryBackend();
23
+ return {
24
+ providerName: "MemoryProvider",
25
+ async mount(database, mountOptions) {
26
+ const transport = createInprocessTransport(backend);
27
+ const service = await createIncrementalPersistenceService({
28
+ database,
29
+ backend,
30
+ transport,
31
+ autoPersist: mountOptions?.autoPersist,
32
+ checkpoint: mountOptions?.checkpoint,
33
+ });
34
+ return {
35
+ service,
36
+ async dispose() {
37
+ await service.dispose();
38
+ await transport.close();
39
+ },
40
+ };
41
+ },
42
+ };
43
+ };
44
+ //# sourceMappingURL=create-memory-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-memory-provider.js","sourceRoot":"","sources":["../../src/provider/create-memory-provider.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,mCAAmC,EAAE,MAAM,sDAAsD,CAAC;AAG3G;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAwB,EAAE;IAC1D,yEAAyE;IACzE,oEAAoE;IACpE,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;IAEtC,OAAO;QACP,YAAY,EAAE,gBAAgB;QAE9B,KAAK,CAAC,KAAK,CACP,QAA0D,EAC1D,YAAmC;YAEnC,MAAM,SAAS,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;YACpD,MAAM,OAAO,GAAG,MAAM,mCAAmC,CAAC;gBACtD,QAAQ;gBACR,OAAO;gBACP,SAAS;gBACT,WAAW,EAAE,YAAY,EAAE,WAAW;gBACtC,UAAU,EAAE,YAAY,EAAE,UAAU;aACvC,CAAC,CAAC;YAEH,OAAO;gBACH,OAAO;gBACP,KAAK,CAAC,OAAO;oBACT,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;oBACxB,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;gBAC5B,CAAC;aACJ,CAAC;QACN,CAAC;KACA,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Database } from "@adobe/data/ecs";
2
+ import type { PersistenceMount, PersistenceProvider, ProviderMountOptions } from "./persistence-provider.js";
3
+ /**
4
+ * Mount a persistence session using the supplied provider.
5
+ *
6
+ * This is the single entry point for all persistence. The provider
7
+ * encapsulates the storage strategy — Node.js `fs`, OPFS, in-memory, or
8
+ * a custom cloud implementation.
9
+ *
10
+ * ```ts
11
+ * import { mount } from "@adobe/data-persistence";
12
+ * import { createNodeFsProvider } from "@adobe/data-persistence/node";
13
+ *
14
+ * const m = await mount(createNodeFsProvider("/tmp/my-db"), database);
15
+ * await m.service.load();
16
+ * // ...run app...
17
+ * await m.dispose();
18
+ * ```
19
+ */
20
+ export declare const mount: (provider: PersistenceProvider, database: Database<any, any, any, any, any, any, any, any>, options?: ProviderMountOptions) => Promise<PersistenceMount>;