@opendatalabs/personal-server-ts-server 1.34.2 → 1.35.0

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 (180) hide show
  1. package/dist/api-auth.d.ts +1 -0
  2. package/dist/api-auth.d.ts.map +1 -1
  3. package/dist/api-auth.js.map +1 -1
  4. package/dist/api.d.ts +3 -0
  5. package/dist/api.d.ts.map +1 -1
  6. package/dist/api.js +3 -0
  7. package/dist/api.js.map +1 -1
  8. package/dist/app.d.ts +14 -2
  9. package/dist/app.d.ts.map +1 -1
  10. package/dist/app.js +64 -8
  11. package/dist/app.js.map +1 -1
  12. package/dist/bootstrap.d.ts +19 -0
  13. package/dist/bootstrap.d.ts.map +1 -1
  14. package/dist/bootstrap.js +87 -4
  15. package/dist/bootstrap.js.map +1 -1
  16. package/dist/client.d.ts +1 -1
  17. package/dist/client.d.ts.map +1 -1
  18. package/dist/client.js +7 -0
  19. package/dist/client.js.map +1 -1
  20. package/dist/enclave-main.d.ts.map +1 -1
  21. package/dist/enclave-main.js +0 -2
  22. package/dist/enclave-main.js.map +1 -1
  23. package/dist/mcp/durable-state.d.ts +2 -1
  24. package/dist/mcp/durable-state.d.ts.map +1 -1
  25. package/dist/mcp/durable-state.js +35 -1
  26. package/dist/mcp/durable-state.js.map +1 -1
  27. package/dist/pdpp/bootstrap.d.ts.map +1 -1
  28. package/dist/pdpp/bootstrap.js +1 -0
  29. package/dist/pdpp/bootstrap.js.map +1 -1
  30. package/dist/pdpp/records-bootstrap.d.ts +47 -1
  31. package/dist/pdpp/records-bootstrap.d.ts.map +1 -1
  32. package/dist/pdpp/records-bootstrap.js +78 -2
  33. package/dist/pdpp/records-bootstrap.js.map +1 -1
  34. package/dist/pdpp/replica-authorization.d.ts +35 -0
  35. package/dist/pdpp/replica-authorization.d.ts.map +1 -0
  36. package/dist/pdpp/replica-authorization.js +234 -0
  37. package/dist/pdpp/replica-authorization.js.map +1 -0
  38. package/dist/pending-blob-deletions.d.ts +1 -0
  39. package/dist/pending-blob-deletions.d.ts.map +1 -1
  40. package/dist/pending-blob-deletions.js +8 -4
  41. package/dist/pending-blob-deletions.js.map +1 -1
  42. package/dist/routes/mcp.d.ts +18 -2
  43. package/dist/routes/mcp.d.ts.map +1 -1
  44. package/dist/routes/mcp.js +111 -11
  45. package/dist/routes/mcp.js.map +1 -1
  46. package/dist/routes/oura.d.ts +6 -0
  47. package/dist/routes/oura.d.ts.map +1 -0
  48. package/dist/routes/oura.js +272 -0
  49. package/dist/routes/oura.js.map +1 -0
  50. package/dist/routes/pdpp-auth-query-keys.d.ts +7 -0
  51. package/dist/routes/pdpp-auth-query-keys.d.ts.map +1 -0
  52. package/dist/routes/pdpp-auth-query-keys.js +25 -0
  53. package/dist/routes/pdpp-auth-query-keys.js.map +1 -0
  54. package/dist/routes/pdpp-auth.d.ts +3 -1
  55. package/dist/routes/pdpp-auth.d.ts.map +1 -1
  56. package/dist/routes/pdpp-auth.js +126 -45
  57. package/dist/routes/pdpp-auth.js.map +1 -1
  58. package/dist/routes/pdpp-blobs.d.ts +13 -1
  59. package/dist/routes/pdpp-blobs.d.ts.map +1 -1
  60. package/dist/routes/pdpp-blobs.js +100 -65
  61. package/dist/routes/pdpp-blobs.js.map +1 -1
  62. package/dist/routes/pdpp-connections.d.ts.map +1 -1
  63. package/dist/routes/pdpp-connections.js +24 -1
  64. package/dist/routes/pdpp-connections.js.map +1 -1
  65. package/dist/routes/pdpp-instance-bindings.d.ts +3 -0
  66. package/dist/routes/pdpp-instance-bindings.d.ts.map +1 -1
  67. package/dist/routes/pdpp-instance-bindings.js +63 -0
  68. package/dist/routes/pdpp-instance-bindings.js.map +1 -1
  69. package/dist/routes/pdpp-record-query.d.ts +19 -0
  70. package/dist/routes/pdpp-record-query.d.ts.map +1 -0
  71. package/dist/routes/pdpp-record-query.js +51 -0
  72. package/dist/routes/pdpp-record-query.js.map +1 -0
  73. package/dist/routes/pdpp-records.d.ts +12 -1
  74. package/dist/routes/pdpp-records.d.ts.map +1 -1
  75. package/dist/routes/pdpp-records.js +120 -233
  76. package/dist/routes/pdpp-records.js.map +1 -1
  77. package/dist/routes/pdpp-replica-quarantine-fixture.d.ts +65 -0
  78. package/dist/routes/pdpp-replica-quarantine-fixture.d.ts.map +1 -0
  79. package/dist/routes/pdpp-replica-quarantine-fixture.js +389 -0
  80. package/dist/routes/pdpp-replica-quarantine-fixture.js.map +1 -0
  81. package/dist/storage/claude-method-transition.d.ts +12 -0
  82. package/dist/storage/claude-method-transition.d.ts.map +1 -0
  83. package/dist/storage/claude-method-transition.js +139 -0
  84. package/dist/storage/claude-method-transition.js.map +1 -0
  85. package/dist/storage/import-operations.d.ts +16 -0
  86. package/dist/storage/import-operations.d.ts.map +1 -1
  87. package/dist/storage/import-operations.js +54 -1
  88. package/dist/storage/import-operations.js.map +1 -1
  89. package/dist/storage/index-schema.d.ts +1 -1
  90. package/dist/storage/index-schema.d.ts.map +1 -1
  91. package/dist/storage/index-schema.js +22 -5
  92. package/dist/storage/index-schema.js.map +1 -1
  93. package/dist/storage/legacy-scope-authority.d.ts.map +1 -1
  94. package/dist/storage/legacy-scope-authority.js +83 -11
  95. package/dist/storage/legacy-scope-authority.js.map +1 -1
  96. package/dist/storage/node-data-storage.d.ts.map +1 -1
  97. package/dist/storage/node-data-storage.js +58 -2
  98. package/dist/storage/node-data-storage.js.map +1 -1
  99. package/dist/storage/pdpp-binary-chunks.d.ts +120 -0
  100. package/dist/storage/pdpp-binary-chunks.d.ts.map +1 -0
  101. package/dist/storage/pdpp-binary-chunks.js +480 -0
  102. package/dist/storage/pdpp-binary-chunks.js.map +1 -0
  103. package/dist/storage/pdpp-records-sqlite-store.d.ts +96 -15
  104. package/dist/storage/pdpp-records-sqlite-store.d.ts.map +1 -1
  105. package/dist/storage/pdpp-records-sqlite-store.js +616 -211
  106. package/dist/storage/pdpp-records-sqlite-store.js.map +1 -1
  107. package/dist/storage/pdpp-replica-canonical-port.d.ts +202 -0
  108. package/dist/storage/pdpp-replica-canonical-port.d.ts.map +1 -0
  109. package/dist/storage/pdpp-replica-canonical-port.js +451 -0
  110. package/dist/storage/pdpp-replica-canonical-port.js.map +1 -0
  111. package/dist/storage/pdpp-replica-coordinator-state.d.ts +16 -0
  112. package/dist/storage/pdpp-replica-coordinator-state.d.ts.map +1 -0
  113. package/dist/storage/pdpp-replica-coordinator-state.js +25 -0
  114. package/dist/storage/pdpp-replica-coordinator-state.js.map +1 -0
  115. package/dist/storage/pdpp-replica-copies.d.ts +81 -0
  116. package/dist/storage/pdpp-replica-copies.d.ts.map +1 -0
  117. package/dist/storage/pdpp-replica-copies.js +59 -0
  118. package/dist/storage/pdpp-replica-copies.js.map +1 -0
  119. package/dist/storage/pdpp-replica-reconciler.d.ts +96 -0
  120. package/dist/storage/pdpp-replica-reconciler.d.ts.map +1 -0
  121. package/dist/storage/pdpp-replica-reconciler.js +710 -0
  122. package/dist/storage/pdpp-replica-reconciler.js.map +1 -0
  123. package/dist/storage/pdpp-replica-sql.d.ts +13 -0
  124. package/dist/storage/pdpp-replica-sql.d.ts.map +1 -0
  125. package/dist/storage/pdpp-replica-sql.js +43 -0
  126. package/dist/storage/pdpp-replica-sql.js.map +1 -0
  127. package/dist/storage/pdpp-replica-staging.d.ts +36 -0
  128. package/dist/storage/pdpp-replica-staging.d.ts.map +1 -0
  129. package/dist/storage/pdpp-replica-staging.js +202 -0
  130. package/dist/storage/pdpp-replica-staging.js.map +1 -0
  131. package/dist/storage/pdpp-replica-visibility-view.d.ts +64 -0
  132. package/dist/storage/pdpp-replica-visibility-view.d.ts.map +1 -0
  133. package/dist/storage/pdpp-replica-visibility-view.js +1397 -0
  134. package/dist/storage/pdpp-replica-visibility-view.js.map +1 -0
  135. package/dist/storage/pdpp-replica-writer-identity.d.ts +64 -0
  136. package/dist/storage/pdpp-replica-writer-identity.d.ts.map +1 -0
  137. package/dist/storage/pdpp-replica-writer-identity.js +81 -0
  138. package/dist/storage/pdpp-replica-writer-identity.js.map +1 -0
  139. package/dist/storage/pdpp-replication-door.d.ts +60 -0
  140. package/dist/storage/pdpp-replication-door.d.ts.map +1 -0
  141. package/dist/storage/pdpp-replication-door.js +203 -0
  142. package/dist/storage/pdpp-replication-door.js.map +1 -0
  143. package/dist/storage/pdpp-replication-host.d.ts +67 -0
  144. package/dist/storage/pdpp-replication-host.d.ts.map +1 -0
  145. package/dist/storage/pdpp-replication-host.js +159 -0
  146. package/dist/storage/pdpp-replication-host.js.map +1 -0
  147. package/dist/storage/pdpp-replication-memory.fixture.d.ts +2 -0
  148. package/dist/storage/pdpp-replication-memory.fixture.d.ts.map +1 -0
  149. package/dist/storage/pdpp-replication-memory.fixture.js +267 -0
  150. package/dist/storage/pdpp-replication-memory.fixture.js.map +1 -0
  151. package/dist/storage/pdpp-replication-preparation.d.ts +3 -0
  152. package/dist/storage/pdpp-replication-preparation.d.ts.map +1 -0
  153. package/dist/storage/pdpp-replication-preparation.js +3 -0
  154. package/dist/storage/pdpp-replication-preparation.js.map +1 -0
  155. package/dist/storage/pdpp-replication-promotion-memory.fixture.d.ts +2 -0
  156. package/dist/storage/pdpp-replication-promotion-memory.fixture.d.ts.map +1 -0
  157. package/dist/storage/pdpp-replication-promotion-memory.fixture.js +65 -0
  158. package/dist/storage/pdpp-replication-promotion-memory.fixture.js.map +1 -0
  159. package/dist/storage/pdpp-replication-receiver.d.ts +230 -0
  160. package/dist/storage/pdpp-replication-receiver.d.ts.map +1 -0
  161. package/dist/storage/pdpp-replication-receiver.js +950 -0
  162. package/dist/storage/pdpp-replication-receiver.js.map +1 -0
  163. package/dist/storage/pdpp-replication-sqlite.d.ts +95 -0
  164. package/dist/storage/pdpp-replication-sqlite.d.ts.map +1 -0
  165. package/dist/storage/pdpp-replication-sqlite.js +615 -0
  166. package/dist/storage/pdpp-replication-sqlite.js.map +1 -0
  167. package/dist/storage/pdpp-replication-transport.d.ts +39 -0
  168. package/dist/storage/pdpp-replication-transport.d.ts.map +1 -0
  169. package/dist/storage/pdpp-replication-transport.js +196 -0
  170. package/dist/storage/pdpp-replication-transport.js.map +1 -0
  171. package/dist/storage/schema-versions.d.ts +5 -0
  172. package/dist/storage/schema-versions.d.ts.map +1 -0
  173. package/dist/storage/schema-versions.js +26 -0
  174. package/dist/storage/schema-versions.js.map +1 -0
  175. package/dist/storage/strava-method-transition.d.ts +18 -0
  176. package/dist/storage/strava-method-transition.d.ts.map +1 -0
  177. package/dist/storage/strava-method-transition.js +209 -0
  178. package/dist/storage/strava-method-transition.js.map +1 -0
  179. package/dist/ui/ps-lite-debug.js +154938 -124896
  180. package/package.json +3 -3
@@ -0,0 +1,159 @@
1
+ import { REPLICA_WAIT_FALLBACK_MS } from "@opendatalabs/personal-server-ts-core/replication/schedule";
2
+ import { replicaDeclarationContext } from "@opendatalabs/personal-server-ts-core/replication/host-config";
3
+ import { planReplicationHost, } from "@opendatalabs/personal-server-ts-core/replication/host-ports";
4
+ import { createReplicationDriver, } from "@opendatalabs/personal-server-ts-core/replication/host-driver";
5
+ import { createReplicaRecordStore, } from "./pdpp-replica-canonical-port.js";
6
+ import { createReplicaReceiver } from "./pdpp-replication-receiver.js";
7
+ import { createReplicaTransportWorker } from "./pdpp-replication-transport.js";
8
+ import { enableReplicaWriterIdentity } from "./pdpp-replica-writer-identity.js";
9
+ /**
10
+ * Desktop step bound (host contract §6): 50 units, 64 MiB. Bytes stay
11
+ * omitted so the coordinator's 64 MiB default applies, under which a batch
12
+ * larger than the whole step still runs alone; an explicit 64 MiB would
13
+ * defer it forever.
14
+ */
15
+ export const NODE_REPLICATION_BUDGET = { units: 50 };
16
+ /** How long shutdown waits for an aborted step before closing storage. */
17
+ export const NODE_REPLICATION_STOP_GRACE_MS = 5_000;
18
+ /**
19
+ * Build the replication runtime for one owner's database. Does not step:
20
+ * the caller starts the returned driver once the server is serving.
21
+ *
22
+ * The returned store and reads replace the resource server's own: the
23
+ * receiver's local-write and visibility observers live on one store instance,
24
+ * and a host with a receiver reads through `receiver.readStore`.
25
+ */
26
+ export function createNodeReplication(input) {
27
+ const plan = planReplicationHost(input);
28
+ if (plan.state === "blocked")
29
+ return plan;
30
+ const { owner, environment } = plan;
31
+ let context = plan.context;
32
+ let ports;
33
+ const store = createReplicaRecordStore(input.db);
34
+ // After a baseline or rebinding, trust every binding the database retained
35
+ // (host contract §4.5): own operations in flight and peers that have not
36
+ // upgraded yet still name the older ones.
37
+ const baseline = () => {
38
+ store.replication.beginBaseline({ owner, declarations: context.current });
39
+ context = replicaDeclarationContext(owner, input.declarations, store.replication.declarationHistory());
40
+ };
41
+ const baselined = () => input.db
42
+ .prepare("SELECT 1 FROM pdpp_replica_settings WHERE id = 1")
43
+ .get() !== undefined;
44
+ try {
45
+ ports = input.ports(owner);
46
+ // An existing baseline takes this boot's bindings now: idempotent for the
47
+ // same set, a new binding generation for an upgraded or added
48
+ // declaration, refused for a changed stream shape. A first baseline waits
49
+ // for the writer identity (see `stepper`).
50
+ if (baselined())
51
+ baseline();
52
+ }
53
+ catch (error) {
54
+ return {
55
+ state: "blocked",
56
+ reason: error instanceof Error ? error.message : String(error),
57
+ };
58
+ }
59
+ // A private capability: only this worker can hand batches to this receiver.
60
+ const credential = Symbol("node-replication-worker");
61
+ const receiver = createReplicaReceiver({
62
+ db: input.db,
63
+ store,
64
+ owner,
65
+ authenticate: (presented) => (presented === credential ? owner : undefined),
66
+ declarations: () => context.declarations,
67
+ });
68
+ const worker = createReplicaTransportWorker({
69
+ db: input.db,
70
+ enabled: true,
71
+ expected: () => context.expected,
72
+ exporter: store.replication,
73
+ receiver,
74
+ credential,
75
+ transport: ports.transport,
76
+ authority: {
77
+ signer: {
78
+ address: input.serverAccount.address,
79
+ signTypedData: (params) => input.serverAccount.signTypedData(params),
80
+ },
81
+ roster: ports.roster,
82
+ chainId: input.chainId,
83
+ environment,
84
+ },
85
+ ...input.worker,
86
+ });
87
+ // The first enable: the writer identity must exist before the baseline
88
+ // journals anything, and establishing it needs the roster (network). So the
89
+ // first steps establish it, then baseline, then hand over to the worker.
90
+ let ready = baselined();
91
+ const now = input.worker?.now ?? (() => Date.now());
92
+ const idle = () => ({
93
+ receipts: [],
94
+ waits: [],
95
+ problems: [],
96
+ quarantines: [],
97
+ unsupported: [],
98
+ nextWake: undefined,
99
+ });
100
+ const stepper = {
101
+ async step(step) {
102
+ if (!ready) {
103
+ const own = await enableReplicaWriterIdentity({
104
+ db: input.db,
105
+ owner,
106
+ server: input.serverAccount.address,
107
+ roster: ports.roster,
108
+ signal: step.signal,
109
+ timers: input.timers,
110
+ });
111
+ if (step.signal.aborted || own.tag === "refused")
112
+ return idle();
113
+ if (own.tag === "waiting")
114
+ return {
115
+ ...idle(),
116
+ waits: [
117
+ {
118
+ id: "writer-identity",
119
+ phase: "retain",
120
+ dependency: {
121
+ kind: "roster",
122
+ key: input.serverAccount.address.toLowerCase(),
123
+ },
124
+ },
125
+ ],
126
+ nextWake: now() + REPLICA_WAIT_FALLBACK_MS,
127
+ };
128
+ baseline();
129
+ ready = true;
130
+ }
131
+ return worker.step(step);
132
+ },
133
+ onDependencyChanged: (key) => worker.onDependencyChanged(key),
134
+ };
135
+ const driver = createReplicationDriver({
136
+ stepper,
137
+ budget: input.budget ?? NODE_REPLICATION_BUDGET,
138
+ timers: input.timers,
139
+ onReport: (report) => {
140
+ if (report.problems.length || report.quarantines.length)
141
+ input.logger.warn({
142
+ problems: report.problems.length,
143
+ quarantines: report.quarantines.length,
144
+ unsupported: report.unsupported.length,
145
+ }, "Replication step reported problems");
146
+ },
147
+ onError: (error) => input.logger.warn({ err: error }, "Replication step failed"),
148
+ });
149
+ // A committed own write schedules a step soon, not at the next wake.
150
+ store.setReplicaJournalObserver(() => driver.localWrite());
151
+ return {
152
+ state: "started",
153
+ store,
154
+ reads: (reader) => receiver.readStore({ reader }),
155
+ driver,
156
+ worker,
157
+ };
158
+ }
159
+ //# sourceMappingURL=pdpp-replication-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-host.js","sourceRoot":"","sources":["../../src/storage/pdpp-replication-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pdpp-replication-memory.fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-memory.fixture.d.ts","sourceRoot":"","sources":["../../src/storage/pdpp-replication-memory.fixture.ts"],"names":[],"mappings":""}
@@ -0,0 +1,267 @@
1
+ import { readBinaryChunks } from "./pdpp-binary-chunks.js";
2
+ /** Isolated real-worker memory probe. Loopback-free, disk-backed transport; no accounts. */
3
+ import Database from "better-sqlite3";
4
+ import { createHash } from "node:crypto";
5
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { createReplicaRecordStore } from "./pdpp-replica-canonical-port.js";
8
+ import { createReplicaReceiver } from "./pdpp-replication-receiver.js";
9
+ import { createReplicaTransportWorker } from "./pdpp-replication-transport.js";
10
+ import { replicaChainCommitment, } from "@opendatalabs/personal-server-ts-core/replication/dpv2";
11
+ import { createTestReplicaRoster, createTestReplicaSigner, } from "@opendatalabs/personal-server-ts-core/replication/writer-identity.test-utils";
12
+ import { establishReplicaWriterIdentity } from "./pdpp-replica-writer-identity.js";
13
+ const [mode, directory, sizeArg] = process.argv.slice(2);
14
+ // Peak RSS only rises, so each marker bounds everything that ran before it.
15
+ const maxRssKiB = () => process.resourceUsage().maxRSS;
16
+ if (!directory)
17
+ throw new Error("probe directory required");
18
+ const size = Number(sizeArg);
19
+ const owner = "0x0000000000000000000000000000000000000001";
20
+ const sourceId = "https://memory.invalid/declaration";
21
+ const binding = {
22
+ digest: `sha256:${"a".repeat(64)}`,
23
+ version: "1",
24
+ stream: "messages",
25
+ semantics: "mutable_state",
26
+ primaryKey: ["id"],
27
+ schemaDigest: `sha256:${"b".repeat(64)}`,
28
+ };
29
+ const expected = { owner, declarations: [{ sourceId, binding }] };
30
+ // Fixed server keys and registration ids, so seed and measure runs agree.
31
+ const roster = createTestReplicaRoster();
32
+ const authorityOf = (role) => {
33
+ const signer = createTestReplicaSigner(role);
34
+ const id = `0x${createHash("sha256").update(role).digest("hex")}`;
35
+ roster.register(signer.address, owner, id);
36
+ return {
37
+ signer,
38
+ id,
39
+ roster: roster.port,
40
+ chainId: 14800,
41
+ environment: "dev",
42
+ };
43
+ };
44
+ const open = (role) => {
45
+ const db = new Database(join(directory, `${role}.sqlite`));
46
+ db.pragma("cache_size=-2048");
47
+ const store = createReplicaRecordStore(db);
48
+ const authority = authorityOf(role);
49
+ establishReplicaWriterIdentity(db, {
50
+ owner,
51
+ server: authority.signer.address,
52
+ record: { owner, id: authority.id, revokedAt: null },
53
+ });
54
+ store.registerConnection({
55
+ instance: "conn",
56
+ sourceId,
57
+ method: "export",
58
+ label: "memory",
59
+ });
60
+ store.replication.beginBaseline(expected);
61
+ return { db, store, authority };
62
+ };
63
+ if (mode === "seed") {
64
+ const { store } = open("source");
65
+ const blob = store.storeBlobBytesForInstance({
66
+ instance: "conn",
67
+ method: "export",
68
+ generation: 1,
69
+ bytes: Buffer.alloc(size, 31),
70
+ mimeType: "application/octet-stream",
71
+ });
72
+ store.ingestBatch([
73
+ {
74
+ instance: "conn",
75
+ stream: "messages",
76
+ key: "large",
77
+ data: {
78
+ id: "large",
79
+ blob_ref: {
80
+ blob_id: blob.blobId,
81
+ mime_type: blob.mimeType,
82
+ size_bytes: size,
83
+ },
84
+ },
85
+ emitted_at: "2026-10-20T00:00:00.000Z",
86
+ },
87
+ ], () => "mutable_state", () => ["id"], { method: "export", generation: 1 });
88
+ writeFileSync(join(directory, "blob-id"), blob.blobId);
89
+ store.close();
90
+ }
91
+ else if (mode === "measure" || mode === "probe") {
92
+ const startKiB = maxRssKiB();
93
+ const source = open("source"), destination = open("destination");
94
+ // Every registered version of each scope, in order: versions append.
95
+ const slots = new Map();
96
+ let published = 0;
97
+ const file = (key) => join(directory, createHash("sha256").update(key).digest("hex"));
98
+ const transport = {
99
+ // Crypto scratch is bounded by fragment size. The worker still validates every fragment and commitment.
100
+ encryptedByteLength: (bytes) => bytes,
101
+ encrypt: async (_scope, bytes) => new Uint8Array(bytes),
102
+ decrypt: async (_scope, bytes) => new Uint8Array(bytes),
103
+ async evidence(scope, version) {
104
+ const rows = slots.get(scope) ?? [];
105
+ const row = rows[version - 1];
106
+ return {
107
+ head: rows.at(-1) ?? null,
108
+ pending: false,
109
+ chain: {
110
+ owner,
111
+ scope,
112
+ version: String(version),
113
+ currentVersion: String(rows.length),
114
+ status: rows.length ? "Active" : "None",
115
+ commitment: row
116
+ ? replicaChainCommitment(row.dataHash, row.metadataHash)
117
+ : `0x${"0".repeat(64)}`,
118
+ chainId: 14800,
119
+ registry: `0x${"2".repeat(40)}`,
120
+ blockNumber: 123n,
121
+ blockHash: `0x${"3".repeat(64)}`,
122
+ blockTimestamp: 1000n,
123
+ },
124
+ };
125
+ },
126
+ async putFragment(fragment) {
127
+ writeFileSync(file(`${fragment.scope}#${fragment.digest}`), fragment.encrypted);
128
+ },
129
+ async getFragment(scope, digest) {
130
+ return readFileSync(file(`${scope}#${digest}`));
131
+ },
132
+ async hasFragment(scope, digest) {
133
+ return existsSync(file(`${scope}#${digest}`));
134
+ },
135
+ async put(manifest) {
136
+ writeFileSync(file(`${manifest.scope}/${manifest.version}`), manifest.encrypted);
137
+ },
138
+ async register(manifest) {
139
+ const rows = slots.get(manifest.scope) ?? [];
140
+ if (manifest.version !== rows.length + 1)
141
+ throw new Error("409 stale expectedVersion");
142
+ rows.push({
143
+ owner,
144
+ scope: manifest.scope,
145
+ version: String(manifest.version),
146
+ dataHash: manifest.dataHash,
147
+ metadataHash: manifest.metadataHash,
148
+ deleted: false,
149
+ });
150
+ slots.set(manifest.scope, rows);
151
+ published++;
152
+ },
153
+ async get(scope, version) {
154
+ return readFileSync(file(`${scope}/${version}`));
155
+ },
156
+ async list() {
157
+ return {
158
+ points: [...slots].map(([scope, rows]) => ({
159
+ scope,
160
+ version: String(rows.length),
161
+ })),
162
+ cursor: null,
163
+ };
164
+ },
165
+ };
166
+ const worker = (device) => createReplicaTransportWorker({
167
+ ...device,
168
+ enabled: true,
169
+ exporter: device.store.replication,
170
+ expected: () => expected,
171
+ receiver: createReplicaReceiver({
172
+ ...device,
173
+ owner,
174
+ authenticate: () => owner,
175
+ declarations: () => [
176
+ {
177
+ sourceId,
178
+ binding,
179
+ validateData: (data) => typeof data.id === "string",
180
+ },
181
+ ],
182
+ }),
183
+ credential: "memory",
184
+ transport,
185
+ targetChunkBytes: 3 * 1024 * 1024,
186
+ });
187
+ if (process.env.REPLICA_PAUSE_DIR) {
188
+ const read = source.store.replication.readPinnedBlobChunks;
189
+ source.store.replication.readPinnedBlobChunks = function* (id) {
190
+ let paused = false;
191
+ for (const chunk of read(id)) {
192
+ yield chunk;
193
+ if (!paused) {
194
+ paused = true;
195
+ writeFileSync(join(process.env.REPLICA_PAUSE_DIR, "paused"), "ready");
196
+ const sleep = new Int32Array(new SharedArrayBuffer(4));
197
+ while (!existsSync(join(process.env.REPLICA_PAUSE_DIR, "resume")))
198
+ Atomics.wait(sleep, 0, 0, 20);
199
+ }
200
+ }
201
+ };
202
+ }
203
+ const a = worker(source), b = worker(destination);
204
+ // Phase markers live in the fixture, not the worker. Materialization runs
205
+ // INSERT OR IGNORE INTO pdpp_blobs before the canonical promotion and
206
+ // INSERT INTO pdpp_blob_claims after it, so the two prepares bracket it.
207
+ let beforePromotionKiB;
208
+ let afterPromotionKiB;
209
+ const prepareStatement = destination.db.prepare.bind(destination.db);
210
+ destination.db.prepare = ((sql) => {
211
+ if (sql.startsWith("INSERT OR IGNORE INTO pdpp_blobs"))
212
+ beforePromotionKiB ??= maxRssKiB();
213
+ if (sql.startsWith("INSERT INTO pdpp_blob_claims"))
214
+ afterPromotionKiB ??= maxRssKiB();
215
+ return prepareStatement(sql);
216
+ });
217
+ if (mode === "probe") {
218
+ try {
219
+ await a.cycle();
220
+ }
221
+ catch (error) {
222
+ if (error &&
223
+ typeof error === "object" &&
224
+ "code" in error &&
225
+ error.code === "replica_worker_active")
226
+ process.exit(2);
227
+ throw error;
228
+ }
229
+ console.log(JSON.stringify({ probe: true }));
230
+ source.store.close();
231
+ destination.store.close();
232
+ process.exit(0);
233
+ }
234
+ // cycle() steps with the finite default byte budget (64 MiB), so a
235
+ // 128 MiB blob takes more steps than the old unbounded cycle did.
236
+ for (let cycle = 0; cycle < 48; cycle++) {
237
+ await a.cycle();
238
+ await b.cycle();
239
+ if (destination.store.getRecord("conn", "messages", "large"))
240
+ break;
241
+ }
242
+ if (!destination.store.getRecord("conn", "messages", "large"))
243
+ throw new Error("worker failed to import");
244
+ const blobId = readFileSync(join(directory, "blob-id"), "utf8");
245
+ const hash = createHash("sha256");
246
+ // Verify destination bytes without adding an object-sized test allocation to the peak.
247
+ let length = 0;
248
+ for (const chunk of readBinaryChunks(destination.db, "canonical", blobId)) {
249
+ hash.update(chunk);
250
+ length += chunk.length;
251
+ }
252
+ if (`sha256:${hash.digest("hex")}` !== blobId || length !== size)
253
+ throw new Error("imported bytes changed");
254
+ console.log(JSON.stringify({
255
+ size,
256
+ published,
257
+ startKiB,
258
+ workerPeakKiB: beforePromotionKiB,
259
+ afterPromotionKiB,
260
+ peakRssKiB: maxRssKiB(),
261
+ }));
262
+ source.store.close();
263
+ destination.store.close();
264
+ }
265
+ else
266
+ throw new Error("unknown probe mode");
267
+ //# sourceMappingURL=pdpp-replication-memory.fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-memory.fixture.js","sourceRoot":"","sources":["../../src/storage/pdpp-replication-memory.fixture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Sender preparation state now lives with the shared engine in core. */
2
+ export * from "@opendatalabs/personal-server-ts-core/replication/preparation";
3
+ //# sourceMappingURL=pdpp-replication-preparation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-preparation.d.ts","sourceRoot":"","sources":["../../src/storage/pdpp-replication-preparation.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,cAAc,+DAA+D,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Sender preparation state now lives with the shared engine in core. */
2
+ export * from "@opendatalabs/personal-server-ts-core/replication/preparation";
3
+ //# sourceMappingURL=pdpp-replication-preparation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-preparation.js","sourceRoot":"","sources":["../../src/storage/pdpp-replication-preparation.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,cAAc,+DAA+D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pdpp-replication-promotion-memory.fixture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-promotion-memory.fixture.d.ts","sourceRoot":"","sources":["../../src/storage/pdpp-replication-promotion-memory.fixture.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Isolated canonical-promotion probe for pdpp-replication-memory.test.ts.
3
+ * Each mode runs in its own process, so its peak is attributable to one step.
4
+ */
5
+ import Database from "better-sqlite3";
6
+ import { join } from "node:path";
7
+ import { BINARY_CHUNK_BYTES, binaryWriter, copyBinaryToCanonical, } from "./pdpp-binary-chunks.js";
8
+ import { createReplicaRecordStore } from "./pdpp-replica-canonical-port.js";
9
+ import { createSqliteRecordStore } from "./pdpp-records-sqlite-store.js";
10
+ const [mode, directory, sizeArg] = process.argv.slice(2);
11
+ if (!directory)
12
+ throw new Error("probe directory required");
13
+ const size = Number(sizeArg);
14
+ const maxRssKiB = () => process.resourceUsage().maxRSS;
15
+ const sourceId = "https://memory.invalid/declaration";
16
+ const report = (before, after) => console.log(JSON.stringify({
17
+ size,
18
+ beforeKiB: before,
19
+ afterKiB: after,
20
+ deltaKiB: Math.max(0, after - before),
21
+ }));
22
+ if (mode === "promote") {
23
+ // Replicated canonical promotion alone, from chunks already staged as
24
+ // `received`. Staging streams 64 KiB pieces, so no whole blob exists before
25
+ // the marker. Promotion copies them to canonical chunks the same way.
26
+ const db = new Database(join(directory, "destination.sqlite"));
27
+ const store = createReplicaRecordStore(db);
28
+ const id = "promote-blob";
29
+ // The receiver writes the blob's metadata row before promotion; the byte row references it.
30
+ db.prepare("INSERT OR IGNORE INTO pdpp_blobs VALUES (?, ?, ?, ?)").run(id, "application/octet-stream", size, "0".repeat(64));
31
+ const writer = binaryWriter(db, "received", id);
32
+ const piece = Buffer.alloc(BINARY_CHUNK_BYTES, 31);
33
+ for (let written = 0; written < size; written += piece.length)
34
+ writer.write(piece.subarray(0, Math.min(piece.length, size - written)));
35
+ writer.finish();
36
+ const before = maxRssKiB();
37
+ copyBinaryToCanonical(db, "received", id);
38
+ report(before, maxRssKiB());
39
+ store.close();
40
+ }
41
+ else if (mode === "plain") {
42
+ // Main's ordinary blob write: the caller materializes the whole blob, then
43
+ // storeBlobBytesForInstance writes it as one pdpp_blob_bytes row.
44
+ const db = new Database(join(directory, "plain.sqlite"));
45
+ const store = createSqliteRecordStore(db);
46
+ store.registerConnection({
47
+ instance: "conn",
48
+ sourceId,
49
+ method: "export",
50
+ label: "memory",
51
+ });
52
+ const before = maxRssKiB();
53
+ store.storeBlobBytesForInstance({
54
+ instance: "conn",
55
+ method: "export",
56
+ generation: 1,
57
+ bytes: Buffer.alloc(size, 31),
58
+ mimeType: "application/octet-stream",
59
+ });
60
+ report(before, maxRssKiB());
61
+ store.close();
62
+ }
63
+ else
64
+ throw new Error("unknown promotion probe mode");
65
+ //# sourceMappingURL=pdpp-replication-promotion-memory.fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdpp-replication-promotion-memory.fixture.js","sourceRoot":"","sources":["../../src/storage/pdpp-replication-promotion-memory.fixture.ts"],"names":[],"mappings":"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"}