@opendatalabs/personal-server-ts-lite 1.34.1 → 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 (97) hide show
  1. package/dist/additions-crypto.d.ts +1 -1
  2. package/dist/additions-crypto.d.ts.map +1 -1
  3. package/dist/additions-crypto.js +16 -6
  4. package/dist/additions-crypto.js.map +1 -1
  5. package/dist/additions-protocol.d.ts +9 -1
  6. package/dist/additions-protocol.d.ts.map +1 -1
  7. package/dist/additions-protocol.js.map +1 -1
  8. package/dist/additions-session.d.ts +2 -0
  9. package/dist/additions-session.d.ts.map +1 -1
  10. package/dist/additions-session.js +29 -4
  11. package/dist/additions-session.js.map +1 -1
  12. package/dist/additions-transport.d.ts +10 -2
  13. package/dist/additions-transport.d.ts.map +1 -1
  14. package/dist/additions-transport.js +143 -48
  15. package/dist/additions-transport.js.map +1 -1
  16. package/dist/additions-worker.bundle.js +538 -101
  17. package/dist/additions-worker.js +45 -24
  18. package/dist/additions-worker.js.map +1 -1
  19. package/dist/browser-runtime.d.ts +23 -0
  20. package/dist/browser-runtime.d.ts.map +1 -1
  21. package/dist/browser-runtime.js +38 -1
  22. package/dist/browser-runtime.js.map +1 -1
  23. package/dist/canonical-persistence.d.ts +53 -0
  24. package/dist/canonical-persistence.d.ts.map +1 -0
  25. package/dist/canonical-persistence.js +13 -0
  26. package/dist/canonical-persistence.js.map +1 -0
  27. package/dist/canonical-store.d.ts +395 -0
  28. package/dist/canonical-store.d.ts.map +1 -0
  29. package/dist/canonical-store.js +1807 -0
  30. package/dist/canonical-store.js.map +1 -0
  31. package/dist/client.d.ts.map +1 -1
  32. package/dist/client.js +154 -1
  33. package/dist/client.js.map +1 -1
  34. package/dist/diagnostics.d.ts +3 -0
  35. package/dist/diagnostics.d.ts.map +1 -1
  36. package/dist/diagnostics.js +9 -1
  37. package/dist/diagnostics.js.map +1 -1
  38. package/dist/history-probe-worker.bundle.js +31216 -0
  39. package/dist/history-probe.worker.d.ts +35 -0
  40. package/dist/history-probe.worker.d.ts.map +1 -0
  41. package/dist/history-probe.worker.js +160 -0
  42. package/dist/history-probe.worker.js.map +1 -0
  43. package/dist/index.d.ts +10 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +10 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/mcp-store.d.ts.map +1 -1
  48. package/dist/mcp-store.js +109 -19
  49. package/dist/mcp-store.js.map +1 -1
  50. package/dist/oura-import.d.ts +2 -0
  51. package/dist/oura-import.d.ts.map +1 -0
  52. package/dist/oura-import.js +3 -0
  53. package/dist/oura-import.js.map +1 -0
  54. package/dist/replication-coordinator-state.d.ts +19 -0
  55. package/dist/replication-coordinator-state.d.ts.map +1 -0
  56. package/dist/replication-coordinator-state.js +20 -0
  57. package/dist/replication-coordinator-state.js.map +1 -0
  58. package/dist/replication-door.d.ts +17 -0
  59. package/dist/replication-door.d.ts.map +1 -0
  60. package/dist/replication-door.js +23 -0
  61. package/dist/replication-door.js.map +1 -0
  62. package/dist/replication-engine.d.ts +49 -0
  63. package/dist/replication-engine.d.ts.map +1 -0
  64. package/dist/replication-engine.js +589 -0
  65. package/dist/replication-engine.js.map +1 -0
  66. package/dist/replication-host.d.ts +92 -0
  67. package/dist/replication-host.d.ts.map +1 -0
  68. package/dist/replication-host.js +135 -0
  69. package/dist/replication-host.js.map +1 -0
  70. package/dist/replication-ports.d.ts +194 -0
  71. package/dist/replication-ports.d.ts.map +1 -0
  72. package/dist/replication-ports.js +58 -0
  73. package/dist/replication-ports.js.map +1 -0
  74. package/dist/replication-runtime.d.ts +64 -0
  75. package/dist/replication-runtime.d.ts.map +1 -0
  76. package/dist/replication-runtime.js +79 -0
  77. package/dist/replication-runtime.js.map +1 -0
  78. package/dist/replication-storage.d.ts +42 -0
  79. package/dist/replication-storage.d.ts.map +1 -0
  80. package/dist/replication-storage.js +173 -0
  81. package/dist/replication-storage.js.map +1 -0
  82. package/dist/runtime.d.ts +20 -2
  83. package/dist/runtime.d.ts.map +1 -1
  84. package/dist/runtime.js +80 -1
  85. package/dist/runtime.js.map +1 -1
  86. package/dist/state.d.ts +1 -1
  87. package/dist/state.d.ts.map +1 -1
  88. package/dist/state.js.map +1 -1
  89. package/dist/storage.d.ts +17 -0
  90. package/dist/storage.d.ts.map +1 -1
  91. package/dist/storage.js +367 -142
  92. package/dist/storage.js.map +1 -1
  93. package/dist/sync.d.ts +8 -0
  94. package/dist/sync.d.ts.map +1 -1
  95. package/dist/sync.js +25 -7
  96. package/dist/sync.js.map +1 -1
  97. package/package.json +8 -4
@@ -0,0 +1,79 @@
1
+ import { createReplicationDriver, } from "@opendatalabs/personal-server-ts-core/replication/host-driver";
2
+ import { replicationBootConfigProblem, } from "./replication-ports.js";
3
+ /** How long a pause waits for an aborted step before reporting it stuck. */
4
+ export const LITE_REPLICATION_PAUSE_GRACE_MS = 2_000;
5
+ /**
6
+ * Build the runtime for one boot. With the door anything but `on`, or no
7
+ * boot config or `enabled: false`, it is inert: no engine runs and `status`
8
+ * says why.
9
+ */
10
+ export function createLiteReplicationRuntime(input) {
11
+ const inert = (status) => ({
12
+ status: () => status,
13
+ trigger: async () => undefined,
14
+ wake: () => { },
15
+ localWrite: () => { },
16
+ resume: () => { },
17
+ pause: async () => { },
18
+ stop: async () => true,
19
+ });
20
+ if (input.door.state === "refused")
21
+ return inert({ state: "refused", refusal: input.door.refusal });
22
+ if (input.door.state !== "on" || !input.config?.enabled)
23
+ return inert({ state: "off" });
24
+ const problem = replicationBootConfigProblem(input.config);
25
+ if (problem)
26
+ return inert({ state: "blocked", reason: problem });
27
+ if (!input.engine)
28
+ return inert({ state: "blocked", reason: "no_engine" });
29
+ const { step } = input.config.limits;
30
+ const driver = createReplicationDriver({
31
+ stepper: input.engine,
32
+ budget: { units: step.units, bytes: step.bytes },
33
+ deadlineMs: step.deadlineMs,
34
+ timers: input.timers,
35
+ onReport: input.onReport,
36
+ onError: input.onError,
37
+ });
38
+ // Every stop still settling. A queued resume waits for all of them: an
39
+ // older, longer stop would otherwise stop the driver the resume restarted.
40
+ const pausing = new Set();
41
+ // Bumped synchronously by every resume, pause and stop. A resume queued
42
+ // behind a pause starts only if no later call has superseded it.
43
+ let lifecycle = 0;
44
+ return {
45
+ status() {
46
+ const { state, ...rest } = driver.status();
47
+ return { state: state === "running" ? "on" : "paused", ...rest };
48
+ },
49
+ trigger: () => driver.trigger(),
50
+ wake: (dependency) => driver.wake(dependency),
51
+ localWrite: () => driver.localWrite(),
52
+ resume() {
53
+ const mine = ++lifecycle;
54
+ // A resume during a pause waits for it, so the old step settles first.
55
+ if (pausing.size)
56
+ void Promise.allSettled([...pausing]).then(() => {
57
+ if (mine === lifecycle)
58
+ driver.start();
59
+ });
60
+ else
61
+ driver.start();
62
+ },
63
+ async pause() {
64
+ await this.stop(LITE_REPLICATION_PAUSE_GRACE_MS);
65
+ },
66
+ async stop(graceMs) {
67
+ lifecycle++;
68
+ const stopping = driver.stop(graceMs);
69
+ pausing.add(stopping);
70
+ try {
71
+ return await stopping;
72
+ }
73
+ finally {
74
+ pausing.delete(stopping);
75
+ }
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=replication-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replication-runtime.js","sourceRoot":"","sources":["../src/replication-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type BoundedStorageAdapter } from "@opendatalabs/personal-server-ts-core/storage/adapters";
2
+ import { type LiteReplicaObjectTransfers, type LiteReplicaPersistence, type LiteReplicaTransaction } from "./replication-ports.js";
3
+ /** Deadline of one transfer when the caller's budget sets none. */
4
+ export declare const LITE_REPLICA_TRANSFER_DEADLINE_MS = 60000;
5
+ /**
6
+ * Replica bytes this adapter attached and has not released yet. A row
7
+ * commits with the attach and leaves with the release, so bytes a crash
8
+ * left attached between them stay listed until the engine reclaims them
9
+ * (`reclaimLiteTransientBytes`).
10
+ */
11
+ export declare const LITE_REPLICA_TRANSIENT_MIGRATION = "CREATE TABLE IF NOT EXISTS pdpp_lite_replica_transient (id TEXT PRIMARY KEY)";
12
+ /**
13
+ * Attached replica byte ids whose transfer this process still runs. A
14
+ * cancelled step stops waiting for its transfer before the native call
15
+ * settles, so the next step can start while the bytes are still in use; the
16
+ * transfer releases them itself when it settles.
17
+ */
18
+ export type LiteTransientBytesInUse = Set<string>;
19
+ /**
20
+ * Release every transient replica byte left attached, in the caller's
21
+ * transaction, except those `inUse`. The engine calls it under its writer
22
+ * lock, before a step's first transfer.
23
+ */
24
+ export declare function reclaimLiteTransientBytes(tx: LiteReplicaTransaction, inUse?: ReadonlySet<string>): Promise<number>;
25
+ /** Headers for one upload, computed over its exact body before it is staged. */
26
+ export type LiteReplicaUploadHeaders = (request: {
27
+ method: "PUT";
28
+ url: string;
29
+ body: Uint8Array;
30
+ }) => Record<string, string> | Promise<Record<string, string>>;
31
+ export declare function createLiteReplicaStorage(input: {
32
+ persistence: LiteReplicaPersistence;
33
+ transfers: LiteReplicaObjectTransfers;
34
+ /** The object URL of a storage key (the inverse of the storage layout). */
35
+ urlForKey(key: string): string;
36
+ /** Upload headers, e.g. storage authorization over the exact body. */
37
+ headers?: LiteReplicaUploadHeaders;
38
+ deadlineMs?: number;
39
+ /** Shared with the engine's reclaim (`reclaimLiteTransientBytes`). */
40
+ inUse?: LiteTransientBytesInUse;
41
+ }): BoundedStorageAdapter;
42
+ //# sourceMappingURL=replication-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replication-storage.d.ts","sourceRoot":"","sources":["../src/replication-storage.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,wDAAwD,CAAC;AAChE,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAGhC,mEAAmE;AACnE,eAAO,MAAM,iCAAiC,QAAS,CAAC;AAQxD;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,iFACmC,CAAC;AAEjF;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;AAElD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,EAAE,EAAE,sBAAsB,EAC1B,KAAK,GAAE,WAAW,CAAC,MAAM,CAAa,mBAkBvC;AAED,gFAAgF;AAChF,MAAM,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,KAAK,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,UAAU,CAAC;CAClB,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAQ/D,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,WAAW,EAAE,sBAAsB,CAAC;IACpC,SAAS,EAAE,0BAA0B,CAAC;IACtC,2EAA2E;IAC3E,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,sEAAsE;IACtE,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC,GAAG,qBAAqB,CAoIxB"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Replica object storage over the native transfers (host contract §4.2), as
3
+ * the storage adapter core's DPv2 replica transport (`replication/dpv2.ts`)
4
+ * takes. Bulk bytes move natively and land in replica byte storage; JS sees
5
+ * only what one fragment or manifest read needs. Gateway calls (register,
6
+ * evidence, owner feed) stay in PS JS core over Lite's HTTP client.
7
+ */
8
+ import { sha256 } from "viem";
9
+ import { AdditionsBudgetExceeded, } from "@opendatalabs/personal-server-ts-core/additions";
10
+ import { StoredBlobConflictError, } from "@opendatalabs/personal-server-ts-core/storage/adapters";
11
+ import { LiteReplicaTransferError, } from "./replication-ports.js";
12
+ const FRAME_BYTES = 128 * 1024;
13
+ /** Deadline of one transfer when the caller's budget sets none. */
14
+ export const LITE_REPLICA_TRANSFER_DEADLINE_MS = 60_000;
15
+ function* frames(bytes) {
16
+ if (bytes.length === 0)
17
+ yield new Uint8Array(0);
18
+ for (let i = 0; i < bytes.length; i += FRAME_BYTES)
19
+ yield bytes.subarray(i, i + FRAME_BYTES);
20
+ }
21
+ /**
22
+ * Replica bytes this adapter attached and has not released yet. A row
23
+ * commits with the attach and leaves with the release, so bytes a crash
24
+ * left attached between them stay listed until the engine reclaims them
25
+ * (`reclaimLiteTransientBytes`).
26
+ */
27
+ export const LITE_REPLICA_TRANSIENT_MIGRATION = "CREATE TABLE IF NOT EXISTS pdpp_lite_replica_transient (id TEXT PRIMARY KEY)";
28
+ /**
29
+ * Release every transient replica byte left attached, in the caller's
30
+ * transaction, except those `inUse`. The engine calls it under its writer
31
+ * lock, before a step's first transfer.
32
+ */
33
+ export async function reclaimLiteTransientBytes(tx, inUse = new Set()) {
34
+ await tx.sql.exec(LITE_REPLICA_TRANSIENT_MIGRATION);
35
+ const rows = await tx.sql.all("SELECT id FROM pdpp_lite_replica_transient", []);
36
+ let released = 0;
37
+ for (const row of rows) {
38
+ const id = row.id;
39
+ if (inUse.has(id))
40
+ continue;
41
+ await tx.releaseBytes(id);
42
+ await tx.sql.run("DELETE FROM pdpp_lite_replica_transient WHERE id=?", [
43
+ id,
44
+ ]);
45
+ released += 1;
46
+ }
47
+ return released;
48
+ }
49
+ /** A storage failure the DPv2 transport reads as definitive absence. */
50
+ const notFound = (url) => Object.assign(new Error(`replica object not found: ${url}`), {
51
+ status: 404,
52
+ });
53
+ export function createLiteReplicaStorage(input) {
54
+ const { persistence, transfers } = input;
55
+ const inUse = input.inUse ?? new Set();
56
+ const deadline = (budget) => Math.max(1, Math.min(input.deadlineMs ?? LITE_REPLICA_TRANSFER_DEADLINE_MS, budget?.remainingMilliseconds ?? Infinity));
57
+ /** Marks `id` in use until `release`, so no reclaim takes it meanwhile. */
58
+ const attach = async (id, length, digest) => {
59
+ inUse.add(id);
60
+ try {
61
+ await persistence.transaction(async (tx) => {
62
+ await tx.sql.exec(LITE_REPLICA_TRANSIENT_MIGRATION);
63
+ await tx.attachBytes(id, { length, sha256: digest });
64
+ await tx.sql.run("INSERT OR IGNORE INTO pdpp_lite_replica_transient (id) VALUES (?)", [id]);
65
+ });
66
+ }
67
+ catch (error) {
68
+ inUse.delete(id);
69
+ throw error;
70
+ }
71
+ };
72
+ const release = async (id) => {
73
+ try {
74
+ await persistence.transaction(async (tx) => {
75
+ await tx.releaseBytes(id);
76
+ await tx.sql.run("DELETE FROM pdpp_lite_replica_transient WHERE id=?", [
77
+ id,
78
+ ]);
79
+ });
80
+ }
81
+ finally {
82
+ inUse.delete(id);
83
+ }
84
+ };
85
+ async function read(id) {
86
+ const parts = [];
87
+ let size = 0;
88
+ for await (const part of persistence.readBytes(id)) {
89
+ parts.push(part);
90
+ size += part.length;
91
+ }
92
+ const bytes = new Uint8Array(size);
93
+ let offset = 0;
94
+ for (const part of parts) {
95
+ bytes.set(part, offset);
96
+ offset += part.length;
97
+ }
98
+ return bytes;
99
+ }
100
+ const unsupported = () => {
101
+ throw new Error("Lite replica storage supports bounded reads only");
102
+ };
103
+ return {
104
+ urlForKey: (key) => input.urlForKey(key),
105
+ /**
106
+ * Write-once: the native upload of different bytes to a stored key
107
+ * fails with HTTP 409, which is `StoredBlobConflictError`.
108
+ */
109
+ async upload(key, data, signal) {
110
+ const url = input.urlForKey(key);
111
+ const headers = (await input.headers?.({ method: "PUT", url, body: data })) ?? {};
112
+ const id = await persistence.stageBytes((async function* () {
113
+ yield* frames(data);
114
+ })());
115
+ await attach(id, data.length, sha256(data).slice(2));
116
+ try {
117
+ await transfers.upload({ url, method: "PUT", headers, bytesId: id }, {
118
+ signal: signal ?? new AbortController().signal,
119
+ deadlineMs: deadline(),
120
+ });
121
+ }
122
+ catch (error) {
123
+ if (error instanceof LiteReplicaTransferError &&
124
+ error.code === "http-status" &&
125
+ /\b409\b/.test(error.message))
126
+ throw new StoredBlobConflictError(key);
127
+ throw error;
128
+ }
129
+ finally {
130
+ await release(id);
131
+ }
132
+ return url;
133
+ },
134
+ /**
135
+ * At most `budget.remaining` bytes. A spent budget only probes: a present
136
+ * object is over budget, a missing one is not found.
137
+ */
138
+ async downloadBounded(url, budget) {
139
+ const signal = budget.signal ?? new AbortController().signal;
140
+ const call = { signal, deadlineMs: deadline(budget) };
141
+ if (budget.remaining <= 0) {
142
+ if (!(await transfers.probe({ url }, call)))
143
+ throw notFound(url);
144
+ throw new AdditionsBudgetExceeded("replica object exceeds budget");
145
+ }
146
+ let staged;
147
+ try {
148
+ staged = await transfers.download({ url, maxBytes: budget.remaining }, call);
149
+ }
150
+ catch (error) {
151
+ if (error instanceof LiteReplicaTransferError) {
152
+ if (error.code === "not-found")
153
+ throw notFound(url);
154
+ if (error.code === "too-large")
155
+ throw new AdditionsBudgetExceeded("replica object exceeds budget");
156
+ }
157
+ throw error;
158
+ }
159
+ budget.recordSpent(staged.length);
160
+ await attach(staged.stagingId, staged.length, staged.sha256);
161
+ try {
162
+ return await read(staged.stagingId);
163
+ }
164
+ finally {
165
+ await release(staged.stagingId);
166
+ }
167
+ },
168
+ download: unsupported,
169
+ delete: unsupported,
170
+ exists: unsupported,
171
+ };
172
+ }
173
+ //# sourceMappingURL=replication-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replication-storage.js","sourceRoot":"","sources":["../src/replication-storage.ts"],"names":[],"mappings":"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"}
package/dist/runtime.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { DurableAdditionsService } from "@opendatalabs/personal-server-ts-core/additions";
2
2
  import { type LegacyProjectionIssue } from "@opendatalabs/personal-server-ts-core/storage/legacy-projection";
3
3
  import { type SessionTokenVerifierPort } from "@opendatalabs/personal-server-ts-core/auth";
4
- import { type PersonalServerApiAuthPort, type PersonalServerReadAuthInput, type PersonalServerReadAuthResult, type PersonalServerReadFulfillmentReporter } from "@opendatalabs/personal-server-ts-core/api";
4
+ import { type PersonalServerApiAuthPort, type PersonalServerApiLogger, type PersonalServerReadAuthInput, type PersonalServerReadAuthResult, type PersonalServerReadFulfillmentReporter, type PreparedScopeUploadBatch } from "@opendatalabs/personal-server-ts-core/api";
5
5
  import { type QuestionStore, type RecomputeScheduler } from "@opendatalabs/personal-server-ts-core/derivatives";
6
6
  import type { LineageGatewayPort } from "@opendatalabs/personal-server-ts-core/lineage";
7
7
  import { type DataListPolicyPorts, type DataWritePolicyPorts } from "@opendatalabs/personal-server-ts-core/policy";
@@ -14,13 +14,21 @@ import type { AccessLogReader } from "@opendatalabs/personal-server-ts-core/logg
14
14
  import type { ServerSigner } from "@opendatalabs/personal-server-ts-core/signing";
15
15
  import type { SyncManager } from "@opendatalabs/personal-server-ts-core/sync";
16
16
  import { type McpConnectionStore, type McpOAuthAuthorizationStore, type McpScopeRequestApprovalUrlHook } from "@opendatalabs/personal-server-ts-core/mcp";
17
+ import type { LiteReplicationRuntime } from "./replication-runtime.js";
17
18
  import { DiagnosticsRecorder } from "./diagnostics.js";
18
19
  export interface PsLiteStorageAdapter {
19
20
  kind: "indexeddb" | "opfs" | "custom";
20
21
  }
21
22
  export type PsLiteReadAuthInput = PersonalServerReadAuthInput;
22
23
  export type PsLiteReadAuthResult = PersonalServerReadAuthResult;
23
- export type PsLiteAuthAdapter = PersonalServerApiAuthPort;
24
+ export interface PsLiteAuthAdapter extends PersonalServerApiAuthPort {
25
+ /**
26
+ * Opt in only when owner authorization does not interpret application body
27
+ * fields. Direct uploads authenticate a digest commitment instead of items.
28
+ * Existing/custom adapters without this flag retain their HTTP body contract.
29
+ */
30
+ supportsScopeUploadCommitments?: true;
31
+ }
24
32
  export interface PsLiteRuntimeOptions {
25
33
  storage: PsLiteStorageAdapter | DataStoragePort;
26
34
  auth?: PsLiteAuthAdapter;
@@ -53,6 +61,8 @@ export interface PsLiteRuntimeOptions {
53
61
  * alongside the sync manager, which keeps it current.
54
62
  */
55
63
  scopeDeletions?: ScopeDeletionTracker;
64
+ /** Receives the cause of every 500 the runtime answers. */
65
+ logger?: PersonalServerApiLogger;
56
66
  additions?: DurableAdditionsService;
57
67
  accessLogReader?: AccessLogReader;
58
68
  accessLogWriter?: AccessLogWriter;
@@ -125,6 +135,12 @@ export interface PsLiteRuntimeOptions {
125
135
  * returns a structured snapshot useful for debugging stuck approval pages.
126
136
  */
127
137
  diagnostics?: DiagnosticsRecorder;
138
+ /**
139
+ * Record replication (host contract §4.4). `activate` resumes it and
140
+ * `deactivate` pauses it; owner-only `GET /v1/replication/status` and
141
+ * `POST /v1/replication/sync` expose it. Absent means off.
142
+ */
143
+ replication?: LiteReplicationRuntime;
128
144
  /**
129
145
  * Called when a legacy scope cannot be projected from stored PDPP records
130
146
  * (the stored body is then served) or is projected with rows left out.
@@ -151,6 +167,8 @@ export interface PsLiteRuntime extends RuntimeAvailabilityPort {
151
167
  activate(): void;
152
168
  deactivate(): void;
153
169
  fetch(request: Request): Promise<Response>;
170
+ /** Optional direct bulk transport; older/custom runtimes keep HTTP. */
171
+ appendScopeUpload?(request: Request, batch: PreparedScopeUploadBatch): Promise<Response>;
154
172
  }
155
173
  /**
156
174
  * Delegated-write (Write API) wiring for a PS-Lite auth adapter.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,iEAAiE,CAAC;AASzE,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,4CAA4C,CAAC;AAUpD,OAAO,EAOL,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,qCAAqC,EAC3C,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAIL,KAAK,qBAAqB,EAE1B,KAAK,iBAAiB,EACvB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,eAAe,EACf,uBAAuB,EACxB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AACnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAC9E,OAAO,EAkCL,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACpC,MAAM,2CAA2C,CAAC;AAOnD,OAAO,EAEL,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;CACvC;AAED,MAAM,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAEhE,MAAM,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CAAC;IAChD,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7B,OAAO,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,GAAG;YAAE,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnE,oEAAoE;QACpE,OAAO,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KACjC,CAAC;IACF,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC;IAChE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAK5B,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC,GACxD,OAAO,CACL,IAAI,CACF,YAAY,EACZ,qBAAqB,GAAG,sBAAsB,GAAG,SAAS,CAC3D,CACF,CAAC;IACJ,WAAW,CAAC,EACR,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,GAC/D,IAAI,CAAC;IACT;;;;OAIG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,uBAAuB,CAAC,EAAE,qCAAqC,CAAC;IAChE;;;OAGG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,aAAa,CAAC;QAAC,SAAS,EAAE,kBAAkB,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC5D;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD,mBAAmB,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAC9C;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,8BAA8B,CAAC;IAC5D;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAClE;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAU,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC9C,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CACN,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;KAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAMD,MAAM,WAAW,aAAc,SAAQ,uBAAuB;IAC5D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CAAC;IACzD,QAAQ,IAAI,IAAI,CAAC;IACjB,UAAU,IAAI,IAAI,CAAC;IACnB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC5C;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,6BAA6B;IAC5C,4DAA4D;IAC5D,KAAK,EAAE,iBAAiB,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC;;;OAGG;IACH,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAED,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,6BAA6B,GAAG;QAC9C,YAAY,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;QACtC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;KAC5B,CAAC;CACH;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAChC,YAAY,EAAE,KAAK,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,6BAA6B,CAAC;CAC/C;AA2MD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,iBAAiB,CAoCnB;AAkCD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,2BAA2B,GACnC,iBAAiB,CAmEnB;AA6FD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAqkBf"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAC/F,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,iEAAiE,CAAC;AASzE,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,4CAA4C,CAAC;AAUpD,OAAO,EAUL,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,qCAAqC,EAC1C,KAAK,wBAAwB,EAC9B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAIL,KAAK,qBAAqB,EAE1B,KAAK,iBAAiB,EACvB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,eAAe,EACf,uBAAuB,EACxB,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AACvF,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AACnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAC9E,OAAO,EAkCL,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACpC,MAAM,2CAA2C,CAAC;AAEnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAMvE,OAAO,EAEL,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;CACvC;AAED,MAAM,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG,4BAA4B,CAAC;AAEhE,MAAM,WAAW,iBAAkB,SAAQ,yBAAyB;IAClE;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CAAC;IAChD,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7B,OAAO,CAAC,EAAE,OAAO,CAAC,4BAA4B,CAAC,GAAG;YAAE,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnE,oEAAoE;QACpE,OAAO,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KACjC,CAAC;IACF,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC;IAChE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAK5B,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,uBAAuB,CAAC,GACxD,OAAO,CACL,IAAI,CACF,YAAY,EACZ,qBAAqB,GAAG,sBAAsB,GAAG,SAAS,CAC3D,CACF,CAAC;IACJ,WAAW,CAAC,EACR,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,WAAW,CAAC,GACzC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,GAC/D,IAAI,CAAC;IACT;;;;OAIG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,uBAAuB,CAAC,EAAE,qCAAqC,CAAC;IAChE;;;OAGG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE;QAAE,KAAK,EAAE,aAAa,CAAC;QAAC,SAAS,EAAE,kBAAkB,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACvC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC5D;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,0BAA0B,CAAC,EAAE,0BAA0B,CAAC;IACxD,mBAAmB,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAC9C;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,8BAA8B,CAAC;IAC5D;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAClE;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1C,UAAU,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC9C,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,QAAQ,CACN,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;KAAE,GAC7C,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAMD,MAAM,WAAW,aAAc,SAAQ,uBAAuB;IAC5D,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,eAAe,CAAC;IACzD,QAAQ,IAAI,IAAI,CAAC;IACjB,UAAU,IAAI,IAAI,CAAC;IACnB,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC3C,uEAAuE;IACvE,iBAAiB,CAAC,CAChB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,QAAQ,CAAC,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,6BAA6B;IAC5C,4DAA4D;IAC5D,KAAK,EAAE,iBAAiB,CAAC;IACzB;;;;OAIG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC;;;OAGG;IACH,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAED,MAAM,WAAW,4BAA4B;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,6BAA6B,GAAG;QAC9C,YAAY,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;QACtC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;KAC5B,CAAC;CACH;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAChC,YAAY,EAAE,KAAK,MAAM,EAAE,CAAC;IAC5B,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,wBAAwB,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,6BAA6B,CAAC;CAC/C;AA2MD,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,iBAAiB,CAqCnB;AAkCD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,2BAA2B,GACnC,iBAAiB,CAoEnB;AA6FD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAurBf"}
package/dist/runtime.js CHANGED
@@ -1,8 +1,9 @@
1
+ import { importOuraBrowserRecords } from "./oura-import.js";
1
2
  import { withLegacyProjection, } from "@opendatalabs/personal-server-ts-core/storage/legacy-projection";
2
3
  import { GrantRequiredError, InvalidSignatureError, MissingAuthError, NotOwnerError, ProtocolError, PsUnavailableError, } from "@opendatalabs/personal-server-ts-core/errors";
3
4
  import { authenticateRequest, } from "@opendatalabs/personal-server-ts-core/auth";
4
5
  import { approveDeviceSessionContract, createMemoryDeviceSessionStore, initiateDeviceSessionContract, pollDeviceSessionContract, provisionDeviceTokenContract, revokeDeviceTokenContract, } from "@opendatalabs/personal-server-ts-core/contracts";
5
- import { handlePersonalServerAccessLogsRequest, handlePersonalServerConfigRequest, handlePersonalServerDataRequest, handlePersonalServerGrantsRequest, handlePersonalServerOauthTokenRequest, handlePersonalServerSyncRequest, } from "@opendatalabs/personal-server-ts-core/api";
6
+ import { handlePersonalServerAccessLogsRequest, handlePersonalServerConfigRequest, handlePersonalServerDataRequest, handlePersonalServerScopeUploadAppend, createScopeUploadRegistry, handleOuraCollectionRequirementsRequest, handlePersonalServerGrantsRequest, handlePersonalServerOauthTokenRequest, handlePersonalServerSyncRequest, } from "@opendatalabs/personal-server-ts-core/api";
6
7
  import { handlePersonalServerDerivativesRequest, } from "@opendatalabs/personal-server-ts-core/derivatives";
7
8
  import { resolveDataListGrantScopes, verifyDataReadPolicy, } from "@opendatalabs/personal-server-ts-core/policy";
8
9
  import { createInMemoryWriteProofReplayStore, createWriteSessionAuthorization, handleWriteSessionRequest, } from "@opendatalabs/personal-server-ts-core/write";
@@ -164,6 +165,7 @@ export function createBearerTokenPsLiteAuth(options) {
164
165
  assertBearerToken(request, options.ownerToken, true);
165
166
  };
166
167
  return {
168
+ supportsScopeUploadCommitments: true,
167
169
  authorizeOwner,
168
170
  ...(options.writeSessions
169
171
  ? writeSessionAuthMethods(options.writeSessions, authorizeOwner)
@@ -226,6 +228,7 @@ export function createWeb3SignedPsLiteAuth(options) {
226
228
  }
227
229
  };
228
230
  return {
231
+ supportsScopeUploadCommitments: true,
229
232
  authorizeOwner,
230
233
  ...(options.writeSessions
231
234
  ? writeSessionAuthMethods({
@@ -344,6 +347,11 @@ export function createPsLiteRuntime(options) {
344
347
  const dataStorage = withLegacyProjection(toDataStoragePort(options.storage), {
345
348
  onIssue: options.onLegacyProjectionIssue ?? warnLegacyProjectionIssue,
346
349
  });
350
+ // Streamed scope writes need a file store that can append to an unindexed
351
+ // file; without one the upload routes answer 501.
352
+ const scopeUploads = dataStorage.openVersionWriter
353
+ ? createScopeUploadRegistry()
354
+ : undefined;
347
355
  // Wire diagnostics by default so GET /v1/diagnostics is always available.
348
356
  const diagnostics = options.diagnostics ?? new DiagnosticsRecorder();
349
357
  options = { ...options, diagnostics };
@@ -395,6 +403,12 @@ export function createPsLiteRuntime(options) {
395
403
  if (err instanceof ProtocolError) {
396
404
  return protocolErrorResponse(err);
397
405
  }
406
+ options.logger?.error?.({
407
+ errorCode: "INTERNAL_ERROR",
408
+ err: err instanceof Error
409
+ ? { name: err.name, message: err.message, stack: err.stack }
410
+ : { message: String(err) },
411
+ }, "Unhandled error in PS Lite runtime");
398
412
  return errorResponse(500, "INTERNAL_ERROR", "Internal server error");
399
413
  }
400
414
  }
@@ -512,15 +526,26 @@ export function createPsLiteRuntime(options) {
512
526
  active = true;
513
527
  options.syncManager?.start?.();
514
528
  options.derivatives?.scheduler.start();
529
+ options.replication?.resume();
515
530
  },
516
531
  deactivate() {
517
532
  active = false;
518
533
  void options.syncManager?.stop?.();
519
534
  options.derivatives?.scheduler.stop();
535
+ void options.replication?.pause();
520
536
  },
521
537
  isAvailable() {
522
538
  return active;
523
539
  },
540
+ ...(auth.supportsScopeUploadCommitments
541
+ ? {
542
+ async appendScopeUpload(request, batch) {
543
+ if (!active)
544
+ return unavailableResponse();
545
+ return handlePersonalServerScopeUploadAppend(request, { storage: dataStorage, auth, accessLogWriter, scopeUploads }, batch);
546
+ },
547
+ }
548
+ : {}),
524
549
  async fetch(request) {
525
550
  return withProtocolErrors(async () => {
526
551
  const url = new URL(request.url);
@@ -601,9 +626,61 @@ export function createPsLiteRuntime(options) {
601
626
  });
602
627
  return jsonResponse(snapshot);
603
628
  }
629
+ if (url.pathname === "/v1/replication/status") {
630
+ if (request.method !== "GET")
631
+ return errorResponse(405, "METHOD_NOT_ALLOWED", "Method not allowed");
632
+ await auth.authorizeOwner(request);
633
+ return jsonResponse(options.replication?.status() ?? { state: "off" });
634
+ }
604
635
  if (!active) {
605
636
  return unavailableResponse();
606
637
  }
638
+ if (url.pathname === "/v1/replication/sync") {
639
+ if (request.method !== "POST")
640
+ return errorResponse(405, "METHOD_NOT_ALLOWED", "Method not allowed");
641
+ await auth.authorizeOwner(request);
642
+ const status = options.replication?.status() ?? { state: "off" };
643
+ if (status.state !== "on")
644
+ return jsonResponse({
645
+ error: {
646
+ code: 409,
647
+ errorCode: "REPLICATION_NOT_RUNNING",
648
+ message: "Replication is not running",
649
+ },
650
+ status,
651
+ }, { status: 409 });
652
+ // "Sync now" starts a step and answers at once; the step may run
653
+ // up to its deadline. Its outcome shows in the status.
654
+ void options.replication.trigger("sync_now");
655
+ return jsonResponse({ accepted: true, status }, { status: 202 });
656
+ }
657
+ if (url.pathname === "/v1/import/oura-browser/requirements") {
658
+ return handleOuraCollectionRequirementsRequest(request, {
659
+ auth,
660
+ storage: toDataStoragePort(options.storage),
661
+ });
662
+ }
663
+ if (url.pathname === "/v1/import/oura-browser") {
664
+ await auth.authorizeOwner(request);
665
+ if (request.method !== "POST")
666
+ return errorResponse(405, "METHOD_NOT_ALLOWED", "Method not allowed");
667
+ let body;
668
+ try {
669
+ body = await request.json();
670
+ }
671
+ catch {
672
+ return errorResponse(400, "INVALID_BODY", "Body must be JSON");
673
+ }
674
+ const result = await importOuraBrowserRecords(toDataStoragePort(options.storage), body, {
675
+ additions: options.additions,
676
+ scopeDeletions: options.scopeDeletions,
677
+ syncManager: options.syncManager ?? null,
678
+ onDataWritten: options.derivatives
679
+ ? (event) => options.derivatives?.scheduler.markSourceChanged(event.scope, { lineageSources: event.lineageSources })
680
+ : undefined,
681
+ });
682
+ return jsonResponse(result, { status: result.ok ? 200 : 409 });
683
+ }
607
684
  const dataPrefix = "/v1/data";
608
685
  if (url.pathname === dataPrefix ||
609
686
  url.pathname.startsWith(`${dataPrefix}/`)) {
@@ -611,11 +688,13 @@ export function createPsLiteRuntime(options) {
611
688
  return handlePersonalServerDataRequest(request, {
612
689
  storage: dataStorage,
613
690
  auth,
691
+ logger: options.logger,
614
692
  accessLogWriter,
615
693
  readFulfillmentReporter: options.readFulfillmentReporter,
616
694
  additions: options.additions,
617
695
  syncManager: options.syncManager ?? null,
618
696
  scopeDeletions: options.scopeDeletions,
697
+ scopeUploads,
619
698
  now,
620
699
  createLogId,
621
700
  // x402 payment enforcement for builder reads. Only engages with a