@opendatalabs/personal-server-ts-server 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.
- package/dist/api-auth.d.ts +1 -0
- package/dist/api-auth.d.ts.map +1 -1
- package/dist/api-auth.js.map +1 -1
- package/dist/api.d.ts +3 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +3 -0
- package/dist/api.js.map +1 -1
- package/dist/app.d.ts +14 -2
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +64 -8
- package/dist/app.js.map +1 -1
- package/dist/bootstrap.d.ts +19 -0
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +87 -4
- package/dist/bootstrap.js.map +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +7 -0
- package/dist/client.js.map +1 -1
- package/dist/enclave-main.d.ts.map +1 -1
- package/dist/enclave-main.js +0 -2
- package/dist/enclave-main.js.map +1 -1
- package/dist/mcp/durable-state.d.ts +2 -1
- package/dist/mcp/durable-state.d.ts.map +1 -1
- package/dist/mcp/durable-state.js +35 -1
- package/dist/mcp/durable-state.js.map +1 -1
- package/dist/pdpp/bootstrap.d.ts.map +1 -1
- package/dist/pdpp/bootstrap.js +1 -0
- package/dist/pdpp/bootstrap.js.map +1 -1
- package/dist/pdpp/records-bootstrap.d.ts +47 -1
- package/dist/pdpp/records-bootstrap.d.ts.map +1 -1
- package/dist/pdpp/records-bootstrap.js +78 -2
- package/dist/pdpp/records-bootstrap.js.map +1 -1
- package/dist/pdpp/replica-authorization.d.ts +35 -0
- package/dist/pdpp/replica-authorization.d.ts.map +1 -0
- package/dist/pdpp/replica-authorization.js +234 -0
- package/dist/pdpp/replica-authorization.js.map +1 -0
- package/dist/pending-blob-deletions.d.ts +1 -0
- package/dist/pending-blob-deletions.d.ts.map +1 -1
- package/dist/pending-blob-deletions.js +8 -4
- package/dist/pending-blob-deletions.js.map +1 -1
- package/dist/routes/mcp.d.ts +18 -2
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +111 -11
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/oura.d.ts +6 -0
- package/dist/routes/oura.d.ts.map +1 -0
- package/dist/routes/oura.js +272 -0
- package/dist/routes/oura.js.map +1 -0
- package/dist/routes/pdpp-auth-query-keys.d.ts +7 -0
- package/dist/routes/pdpp-auth-query-keys.d.ts.map +1 -0
- package/dist/routes/pdpp-auth-query-keys.js +25 -0
- package/dist/routes/pdpp-auth-query-keys.js.map +1 -0
- package/dist/routes/pdpp-auth.d.ts +3 -1
- package/dist/routes/pdpp-auth.d.ts.map +1 -1
- package/dist/routes/pdpp-auth.js +126 -45
- package/dist/routes/pdpp-auth.js.map +1 -1
- package/dist/routes/pdpp-blobs.d.ts +13 -1
- package/dist/routes/pdpp-blobs.d.ts.map +1 -1
- package/dist/routes/pdpp-blobs.js +100 -65
- package/dist/routes/pdpp-blobs.js.map +1 -1
- package/dist/routes/pdpp-connections.d.ts.map +1 -1
- package/dist/routes/pdpp-connections.js +24 -1
- package/dist/routes/pdpp-connections.js.map +1 -1
- package/dist/routes/pdpp-instance-bindings.d.ts +3 -0
- package/dist/routes/pdpp-instance-bindings.d.ts.map +1 -1
- package/dist/routes/pdpp-instance-bindings.js +63 -0
- package/dist/routes/pdpp-instance-bindings.js.map +1 -1
- package/dist/routes/pdpp-record-query.d.ts +19 -0
- package/dist/routes/pdpp-record-query.d.ts.map +1 -0
- package/dist/routes/pdpp-record-query.js +51 -0
- package/dist/routes/pdpp-record-query.js.map +1 -0
- package/dist/routes/pdpp-records.d.ts +12 -1
- package/dist/routes/pdpp-records.d.ts.map +1 -1
- package/dist/routes/pdpp-records.js +120 -233
- package/dist/routes/pdpp-records.js.map +1 -1
- package/dist/routes/pdpp-replica-quarantine-fixture.d.ts +65 -0
- package/dist/routes/pdpp-replica-quarantine-fixture.d.ts.map +1 -0
- package/dist/routes/pdpp-replica-quarantine-fixture.js +389 -0
- package/dist/routes/pdpp-replica-quarantine-fixture.js.map +1 -0
- package/dist/storage/claude-method-transition.d.ts +12 -0
- package/dist/storage/claude-method-transition.d.ts.map +1 -0
- package/dist/storage/claude-method-transition.js +139 -0
- package/dist/storage/claude-method-transition.js.map +1 -0
- package/dist/storage/import-operations.d.ts +16 -0
- package/dist/storage/import-operations.d.ts.map +1 -1
- package/dist/storage/import-operations.js +54 -1
- package/dist/storage/import-operations.js.map +1 -1
- package/dist/storage/index-schema.d.ts +1 -1
- package/dist/storage/index-schema.d.ts.map +1 -1
- package/dist/storage/index-schema.js +22 -5
- package/dist/storage/index-schema.js.map +1 -1
- package/dist/storage/legacy-scope-authority.d.ts.map +1 -1
- package/dist/storage/legacy-scope-authority.js +83 -11
- package/dist/storage/legacy-scope-authority.js.map +1 -1
- package/dist/storage/node-data-storage.d.ts.map +1 -1
- package/dist/storage/node-data-storage.js +58 -2
- package/dist/storage/node-data-storage.js.map +1 -1
- package/dist/storage/pdpp-binary-chunks.d.ts +120 -0
- package/dist/storage/pdpp-binary-chunks.d.ts.map +1 -0
- package/dist/storage/pdpp-binary-chunks.js +480 -0
- package/dist/storage/pdpp-binary-chunks.js.map +1 -0
- package/dist/storage/pdpp-records-sqlite-store.d.ts +96 -15
- package/dist/storage/pdpp-records-sqlite-store.d.ts.map +1 -1
- package/dist/storage/pdpp-records-sqlite-store.js +616 -211
- package/dist/storage/pdpp-records-sqlite-store.js.map +1 -1
- package/dist/storage/pdpp-replica-canonical-port.d.ts +202 -0
- package/dist/storage/pdpp-replica-canonical-port.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-canonical-port.js +451 -0
- package/dist/storage/pdpp-replica-canonical-port.js.map +1 -0
- package/dist/storage/pdpp-replica-coordinator-state.d.ts +16 -0
- package/dist/storage/pdpp-replica-coordinator-state.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-coordinator-state.js +25 -0
- package/dist/storage/pdpp-replica-coordinator-state.js.map +1 -0
- package/dist/storage/pdpp-replica-copies.d.ts +81 -0
- package/dist/storage/pdpp-replica-copies.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-copies.js +59 -0
- package/dist/storage/pdpp-replica-copies.js.map +1 -0
- package/dist/storage/pdpp-replica-reconciler.d.ts +96 -0
- package/dist/storage/pdpp-replica-reconciler.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-reconciler.js +710 -0
- package/dist/storage/pdpp-replica-reconciler.js.map +1 -0
- package/dist/storage/pdpp-replica-sql.d.ts +13 -0
- package/dist/storage/pdpp-replica-sql.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-sql.js +43 -0
- package/dist/storage/pdpp-replica-sql.js.map +1 -0
- package/dist/storage/pdpp-replica-staging.d.ts +36 -0
- package/dist/storage/pdpp-replica-staging.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-staging.js +202 -0
- package/dist/storage/pdpp-replica-staging.js.map +1 -0
- package/dist/storage/pdpp-replica-visibility-view.d.ts +64 -0
- package/dist/storage/pdpp-replica-visibility-view.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-visibility-view.js +1397 -0
- package/dist/storage/pdpp-replica-visibility-view.js.map +1 -0
- package/dist/storage/pdpp-replica-writer-identity.d.ts +64 -0
- package/dist/storage/pdpp-replica-writer-identity.d.ts.map +1 -0
- package/dist/storage/pdpp-replica-writer-identity.js +81 -0
- package/dist/storage/pdpp-replica-writer-identity.js.map +1 -0
- package/dist/storage/pdpp-replication-door.d.ts +60 -0
- package/dist/storage/pdpp-replication-door.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-door.js +203 -0
- package/dist/storage/pdpp-replication-door.js.map +1 -0
- package/dist/storage/pdpp-replication-host.d.ts +67 -0
- package/dist/storage/pdpp-replication-host.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-host.js +159 -0
- package/dist/storage/pdpp-replication-host.js.map +1 -0
- package/dist/storage/pdpp-replication-memory.fixture.d.ts +2 -0
- package/dist/storage/pdpp-replication-memory.fixture.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-memory.fixture.js +267 -0
- package/dist/storage/pdpp-replication-memory.fixture.js.map +1 -0
- package/dist/storage/pdpp-replication-preparation.d.ts +3 -0
- package/dist/storage/pdpp-replication-preparation.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-preparation.js +3 -0
- package/dist/storage/pdpp-replication-preparation.js.map +1 -0
- package/dist/storage/pdpp-replication-promotion-memory.fixture.d.ts +2 -0
- package/dist/storage/pdpp-replication-promotion-memory.fixture.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-promotion-memory.fixture.js +65 -0
- package/dist/storage/pdpp-replication-promotion-memory.fixture.js.map +1 -0
- package/dist/storage/pdpp-replication-receiver.d.ts +230 -0
- package/dist/storage/pdpp-replication-receiver.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-receiver.js +950 -0
- package/dist/storage/pdpp-replication-receiver.js.map +1 -0
- package/dist/storage/pdpp-replication-sqlite.d.ts +95 -0
- package/dist/storage/pdpp-replication-sqlite.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-sqlite.js +615 -0
- package/dist/storage/pdpp-replication-sqlite.js.map +1 -0
- package/dist/storage/pdpp-replication-transport.d.ts +39 -0
- package/dist/storage/pdpp-replication-transport.d.ts.map +1 -0
- package/dist/storage/pdpp-replication-transport.js +196 -0
- package/dist/storage/pdpp-replication-transport.js.map +1 -0
- package/dist/storage/schema-versions.d.ts +5 -0
- package/dist/storage/schema-versions.d.ts.map +1 -0
- package/dist/storage/schema-versions.js +26 -0
- package/dist/storage/schema-versions.js.map +1 -0
- package/dist/storage/strava-method-transition.d.ts +18 -0
- package/dist/storage/strava-method-transition.d.ts.map +1 -0
- package/dist/storage/strava-method-transition.js +209 -0
- package/dist/storage/strava-method-transition.js.map +1 -0
- package/dist/ui/ps-lite-debug.js +137018 -106931
- package/package.json +3 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node host for the replica transport engine (core `replication/engine.ts`).
|
|
3
|
+
* The phase logic lives in core and is shared with PS-Lite; this file binds
|
|
4
|
+
* it to one better-sqlite3 connection: synchronous transactions, the
|
|
5
|
+
* process writer lock, the replication door, chunked staging and the
|
|
6
|
+
* receiver's atomic boundary.
|
|
7
|
+
*/
|
|
8
|
+
import type { Database } from "better-sqlite3";
|
|
9
|
+
import { type ReplicaEngineConfig } from "@opendatalabs/personal-server-ts-core/replication/engine";
|
|
10
|
+
import type { ReplicationExport } from "./pdpp-replication-sqlite.js";
|
|
11
|
+
import type { createReplicaReceiver } from "./pdpp-replication-receiver.js";
|
|
12
|
+
import { createReplicaStagingStore } from "./pdpp-replica-staging.js";
|
|
13
|
+
export { REPLICA_BATCH_BYTES, REPLICA_BATCH_OPERATIONS, REPLICA_RECONCILE_PAGE, REPLICA_REGISTRATION_INTENT_TIMEOUT_MS, REPLICA_VERSION_SQUAT_ATTEMPTS, REPLICA_VERSION_SQUAT_WINDOW_MS, ReplicaAuthorityError, ReplicaCarrierMismatchError, } from "@opendatalabs/personal-server-ts-core/replication/engine";
|
|
14
|
+
/** Unattached stages expire after one hour; cleanup deletes at most this many. */
|
|
15
|
+
export declare const REPLICA_STAGED_OBJECT_LEASE_MS: number;
|
|
16
|
+
export declare const REPLICA_STAGED_OBJECT_CLEANUP_BATCH = 100;
|
|
17
|
+
export declare function createReplicaTransportWorker(deps: ReplicaEngineConfig & {
|
|
18
|
+
db: Database;
|
|
19
|
+
exporter: ReplicationExport;
|
|
20
|
+
receiver: ReturnType<typeof createReplicaReceiver>;
|
|
21
|
+
/** Narrow deterministic seam for failures at the staging-store boundary. */
|
|
22
|
+
createStagingStore?: typeof createReplicaStagingStore;
|
|
23
|
+
}): {
|
|
24
|
+
step: (input?: {
|
|
25
|
+
now?: number;
|
|
26
|
+
budget?: import("@opendatalabs/personal-server-ts-core/replication/coordinator").ReplicaBudget;
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}) => Promise<import("@opendatalabs/personal-server-ts-core/replication/coordinator").ProgressReport>;
|
|
29
|
+
cycle: () => Promise<void>;
|
|
30
|
+
/** Owner acknowledgement resumes an exhausted writer after its wait and recovery window. */
|
|
31
|
+
retryVersionSquats: () => number;
|
|
32
|
+
/** See the engine: re-admit Unsupported batches after a capability change. */
|
|
33
|
+
readmitUnsupported: () => number;
|
|
34
|
+
/** See the engine: fetch again slots quarantined for missing fragments. */
|
|
35
|
+
readmitFragments: () => number;
|
|
36
|
+
/** A host-observed dependency change (e.g. `mapping:<connection>`). Idempotent. */
|
|
37
|
+
onDependencyChanged: (key: string) => number;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=pdpp-replication-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdpp-replication-transport.d.ts","sourceRoot":"","sources":["../../src/storage/pdpp-replication-transport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAEL,KAAK,mBAAmB,EAGzB,MAAM,0DAA0D,CAAC;AAkBlE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAKtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EACL,yBAAyB,EAG1B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,EACtB,sCAAsC,EACtC,8BAA8B,EAC9B,+BAA+B,EAC/B,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,0DAA0D,CAAC;AAMlE,kFAAkF;AAClF,eAAO,MAAM,8BAA8B,QAAyB,CAAC;AACrE,eAAO,MAAM,mCAAmC,MAA8B,CAAC;AAa/E,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,mBAAmB,GAAG;IAC1B,EAAE,EAAE,QAAQ,CAAC;IACb,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;IACnD,4EAA4E;IAC5E,kBAAkB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CACvD;;WA4Mm/Q,CAAC;cAAwB,CAAC;cAA+B,CAAC;;;IAX5iR,4FAA4F;8BACpE,MAAM;IAC9B,8EAA8E;8BACtD,MAAM;IAC9B,2EAA2E;4BACrD,MAAM;IAC5B,mFAAmF;+BACxD,MAAM,KAAG,MAAM;EAG7C"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { createReplicaEngine, } from "@opendatalabs/personal-server-ts-core/replication/engine";
|
|
3
|
+
import { perform, runEffectSync, } from "@opendatalabs/personal-server-ts-core/replication/effects";
|
|
4
|
+
import { ReplicaCoordinatorConflict } from "@opendatalabs/personal-server-ts-core/replication/coordinator";
|
|
5
|
+
import { deleteBinary, createBinaryCompactor } from "./pdpp-binary-chunks.js";
|
|
6
|
+
import { createSqliteReplicaCoordinatorState } from "./pdpp-replica-coordinator-state.js";
|
|
7
|
+
import { nodeReplicaContext } from "./pdpp-replica-sql.js";
|
|
8
|
+
import { assertReplicationStepOpen, assertReplicationTransactionOpen, beginReplicationStep, captureWrites, replicationAdmitted, } from "./pdpp-replication-door.js";
|
|
9
|
+
import { currentReplicaWriterIdentity, enableReplicaWriterIdentity, } from "./pdpp-replica-writer-identity.js";
|
|
10
|
+
import { createReplicaStagingStore, STAGED_OBJECT_CLEANUP_BATCH, STAGED_OBJECT_LEASE_MS, } from "./pdpp-replica-staging.js";
|
|
11
|
+
export { REPLICA_BATCH_BYTES, REPLICA_BATCH_OPERATIONS, REPLICA_RECONCILE_PAGE, REPLICA_REGISTRATION_INTENT_TIMEOUT_MS, REPLICA_VERSION_SQUAT_ATTEMPTS, REPLICA_VERSION_SQUAT_WINDOW_MS, ReplicaAuthorityError, ReplicaCarrierMismatchError, } from "@opendatalabs/personal-server-ts-core/replication/engine";
|
|
12
|
+
// One process owns a transport writer per database; other local instances serialize cycles.
|
|
13
|
+
const activeDatabases = new Set();
|
|
14
|
+
const ownedTokens = new Set();
|
|
15
|
+
/** Unattached stages expire after one hour; cleanup deletes at most this many. */
|
|
16
|
+
export const REPLICA_STAGED_OBJECT_LEASE_MS = STAGED_OBJECT_LEASE_MS;
|
|
17
|
+
export const REPLICA_STAGED_OBJECT_CLEANUP_BATCH = STAGED_OBJECT_CLEANUP_BATCH;
|
|
18
|
+
/** Node answers every storage call synchronously; a promise here is a bug. */
|
|
19
|
+
function settled(value) {
|
|
20
|
+
if (typeof value === "object" &&
|
|
21
|
+
value !== null &&
|
|
22
|
+
typeof value.then === "function")
|
|
23
|
+
throw new Error("replica engine returned a promise on Node");
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
export function createReplicaTransportWorker(deps) {
|
|
27
|
+
const { db, exporter, receiver } = deps;
|
|
28
|
+
const context = nodeReplicaContext(db);
|
|
29
|
+
const run = (effect) => runEffectSync(effect, context);
|
|
30
|
+
/** A synchronous Node call, as one effect operation. */
|
|
31
|
+
const sync = (call) => perform(call);
|
|
32
|
+
const databaseKey = db.name && db.name !== ":memory:" ? db.name : db;
|
|
33
|
+
function acquireWriter(token) {
|
|
34
|
+
db.transaction(() => {
|
|
35
|
+
const holder = db
|
|
36
|
+
.prepare("SELECT pid,token FROM pdpp_transport_lock WHERE id=1")
|
|
37
|
+
.get();
|
|
38
|
+
if (holder?.pid === process.pid && !ownedTokens.has(holder.token)) {
|
|
39
|
+
db.prepare("DELETE FROM pdpp_transport_lock WHERE id=1").run();
|
|
40
|
+
}
|
|
41
|
+
else if (holder) {
|
|
42
|
+
try {
|
|
43
|
+
process.kill(holder.pid, 0);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error.code === "ESRCH") {
|
|
47
|
+
db.prepare("DELETE FROM pdpp_transport_lock WHERE id=1").run();
|
|
48
|
+
}
|
|
49
|
+
else
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
if (db.prepare("SELECT 1 FROM pdpp_transport_lock WHERE id=1").get())
|
|
53
|
+
throw Object.assign(new Error("replica database worker already active"), { code: "replica_worker_active" });
|
|
54
|
+
}
|
|
55
|
+
db.prepare("INSERT INTO pdpp_transport_lock VALUES (1,?,?)").run(process.pid, token);
|
|
56
|
+
}).immediate();
|
|
57
|
+
ownedTokens.add(token);
|
|
58
|
+
}
|
|
59
|
+
const compactor = createBinaryCompactor(db);
|
|
60
|
+
const host = {
|
|
61
|
+
compactCanonical: (bytes) => sync(() => {
|
|
62
|
+
compactor.step(bytes);
|
|
63
|
+
}),
|
|
64
|
+
run,
|
|
65
|
+
immediate: (effect) => sync(() => db.transaction(() => run(effect)).immediate()),
|
|
66
|
+
transaction: (effect) => sync(() => db.transaction(() => run(effect))()),
|
|
67
|
+
commit(effect, _context, signal) {
|
|
68
|
+
// The receiver's own boundary: its plans read and write derived state,
|
|
69
|
+
// which a transaction opened on the raw connection would not refresh.
|
|
70
|
+
if (db.inTransaction)
|
|
71
|
+
assertReplicationTransactionOpen(db, signal);
|
|
72
|
+
else
|
|
73
|
+
assertReplicationStepOpen(db, signal);
|
|
74
|
+
return receiver.atomically(() => run(effect));
|
|
75
|
+
},
|
|
76
|
+
cleanup: (effect) => {
|
|
77
|
+
run(effect);
|
|
78
|
+
},
|
|
79
|
+
captureWrites: (effect) => sync(() => captureWrites(db, () => run(effect))),
|
|
80
|
+
randomId: () => randomUUID(),
|
|
81
|
+
door: {
|
|
82
|
+
admitted: () => replicationAdmitted(db),
|
|
83
|
+
beginStep: (signal) => beginReplicationStep(db, signal),
|
|
84
|
+
assertStepOpen: (signal) => assertReplicationStepOpen(db, signal),
|
|
85
|
+
assertTransactionOpen: (signal) => assertReplicationTransactionOpen(db, signal),
|
|
86
|
+
},
|
|
87
|
+
lock: {
|
|
88
|
+
busy: () => activeDatabases.has(databaseKey),
|
|
89
|
+
acquire(token) {
|
|
90
|
+
acquireWriter(token);
|
|
91
|
+
activeDatabases.add(databaseKey);
|
|
92
|
+
},
|
|
93
|
+
release(token) {
|
|
94
|
+
activeDatabases.delete(databaseKey);
|
|
95
|
+
try {
|
|
96
|
+
db.prepare("DELETE FROM pdpp_transport_lock WHERE id=1 AND token=?").run(token);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
ownedTokens.delete(token);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
identity: {
|
|
104
|
+
current: () => sync(() => currentReplicaWriterIdentity(db)),
|
|
105
|
+
enable: (input) => enableReplicaWriterIdentity({ db, ...input }),
|
|
106
|
+
},
|
|
107
|
+
coordinatorState: ({ owner, signal: stepSignal, enabled: isEnabled }) => createSqliteReplicaCoordinatorState({
|
|
108
|
+
db,
|
|
109
|
+
owner,
|
|
110
|
+
atomically: (attempt) => {
|
|
111
|
+
const signal = stepSignal();
|
|
112
|
+
if (!signal || !isEnabled())
|
|
113
|
+
throw new ReplicaCoordinatorConflict();
|
|
114
|
+
assertReplicationStepOpen(db, signal);
|
|
115
|
+
return receiver.atomically(() => {
|
|
116
|
+
const result = attempt();
|
|
117
|
+
assertReplicationTransactionOpen(db, signal);
|
|
118
|
+
return result;
|
|
119
|
+
});
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
staging({ injected, ...input }) {
|
|
123
|
+
const create = injected
|
|
124
|
+
? (deps.createStagingStore ?? createReplicaStagingStore)
|
|
125
|
+
: createReplicaStagingStore;
|
|
126
|
+
const store = create({ db, ...input });
|
|
127
|
+
return {
|
|
128
|
+
begin: (admission) => store.begin(admission),
|
|
129
|
+
verify: (handle, expected) => store.verify(handle, expected),
|
|
130
|
+
attach: (handle, expected) => sync(() => store.attach(handle, expected)),
|
|
131
|
+
abort: (admission) => store.abort(admission),
|
|
132
|
+
reclaimAdmission: (admission) => store.reclaimAdmission(admission),
|
|
133
|
+
cleanup: () => store.cleanup(),
|
|
134
|
+
cleanupAttachedTemporaryBytes: () => store.cleanupAttachedTemporaryBytes(),
|
|
135
|
+
};
|
|
136
|
+
},
|
|
137
|
+
sweepStages: () => sync(() => {
|
|
138
|
+
const untrackedStages = db
|
|
139
|
+
.prepare(`SELECT m.blob_id FROM pdpp_binary_manifests m
|
|
140
|
+
WHERE m.namespace='staging'
|
|
141
|
+
AND NOT EXISTS (
|
|
142
|
+
SELECT 1 FROM pdpp_transport_staged_objects s
|
|
143
|
+
WHERE s.namespace_key=m.blob_id
|
|
144
|
+
)
|
|
145
|
+
ORDER BY m.blob_id LIMIT ?`)
|
|
146
|
+
.all(STAGED_OBJECT_CLEANUP_BATCH);
|
|
147
|
+
for (const row of untrackedStages)
|
|
148
|
+
deleteBinary(db, "staging", row.blob_id);
|
|
149
|
+
}),
|
|
150
|
+
exporter: {
|
|
151
|
+
readBaselinePage: (options) => sync(() => exporter.readBaselinePage(options)),
|
|
152
|
+
readTailPage: (options) => sync(() => exporter.readTailPage(options)),
|
|
153
|
+
getBaselineCheckpoint: () => sync(() => exporter.getBaselineCheckpoint()),
|
|
154
|
+
acknowledgeBaselinePage: (expected, next) => sync(() => exporter.acknowledgeBaselinePage(expected, next)),
|
|
155
|
+
// The receiver's merge chose these operations for current state; the
|
|
156
|
+
// baseline copies only what this device's trust accepted.
|
|
157
|
+
rebaseline: () => sync(() => exporter.rebaseline(receiver.explainState({ credential: deps.credential }))),
|
|
158
|
+
declarationHistory: () => sync(() => exporter.declarationHistory()),
|
|
159
|
+
// Node's journal is append-only and stays: rebaseline and completion
|
|
160
|
+
// dependencies read it (`pdpp-replication-sqlite.ts`).
|
|
161
|
+
acknowledgePublished: () => sync(() => undefined),
|
|
162
|
+
readPinnedBlobChunks: (blobId) => exporter.readPinnedBlobChunks(blobId),
|
|
163
|
+
},
|
|
164
|
+
receiver: {
|
|
165
|
+
setPendingEnabled: (value) => receiver.setPendingEnabled(value),
|
|
166
|
+
quarantine: (input) => sync(() => receiver.quarantine(input)),
|
|
167
|
+
reconcileStep: (input) => sync(() => receiver.reconcileStep(input)),
|
|
168
|
+
reconcileQueued: () => sync(() => receiver.reconcileQueued()),
|
|
169
|
+
copies: {
|
|
170
|
+
list: (id) => sync(() => receiver.copies.list(id)),
|
|
171
|
+
decide: (id, refetch) => sync(() => receiver.copies.decide(id, refetch)),
|
|
172
|
+
apply: (input) => sync(() => receiver.copies.apply(input)),
|
|
173
|
+
stage: (input) => sync(() => receiver.copies.stage(input)),
|
|
174
|
+
recordFact: (input) => sync(() => receiver.copies.recordFact(input)),
|
|
175
|
+
promote: (input) => sync(() => receiver.copies.promote(input)),
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
bindings: () => sync(() => db
|
|
179
|
+
.prepare("SELECT instance,source_id,method,generation,deleted_at FROM pdpp_instance_binding ORDER BY instance")
|
|
180
|
+
.all()),
|
|
181
|
+
};
|
|
182
|
+
const engine = createReplicaEngine(host, deps);
|
|
183
|
+
return {
|
|
184
|
+
step: engine.step,
|
|
185
|
+
cycle: engine.cycle,
|
|
186
|
+
/** Owner acknowledgement resumes an exhausted writer after its wait and recovery window. */
|
|
187
|
+
retryVersionSquats: () => settled(engine.retryVersionSquats()),
|
|
188
|
+
/** See the engine: re-admit Unsupported batches after a capability change. */
|
|
189
|
+
readmitUnsupported: () => settled(engine.readmitUnsupported()),
|
|
190
|
+
/** See the engine: fetch again slots quarantined for missing fragments. */
|
|
191
|
+
readmitFragments: () => settled(engine.readmitFragments()),
|
|
192
|
+
/** A host-observed dependency change (e.g. `mapping:<connection>`). Idempotent. */
|
|
193
|
+
onDependencyChanged: (key) => settled(engine.onDependencyChanged(key)),
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=pdpp-replication-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdpp-replication-transport.js","sourceRoot":"","sources":["../../src/storage/pdpp-replication-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
export declare const INDEX_SCHEMA_VERSION = 17;
|
|
3
|
+
/** Read both counters before either opener changes the shared database. */
|
|
4
|
+
export declare function assertSupportedSchemaVersions(db: Database.Database, supportedRecordSchemaVersion: number): number;
|
|
5
|
+
//# sourceMappingURL=schema-versions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-versions.d.ts","sourceRoot":"","sources":["../../src/storage/schema-versions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAO3C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAEvC,2EAA2E;AAC3E,wBAAgB,6BAA6B,CAC3C,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,4BAA4B,EAAE,MAAM,GACnC,MAAM,CAwBR"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// v17 is a compatibility fence for the converged runtime. Slots 15 and 16
|
|
2
|
+
// were also used by the conformance line for other additive columns.
|
|
3
|
+
// Older Desktop builds must refuse this database even when PDPP is disabled:
|
|
4
|
+
// they lack retained-history blob protection and the current MCP ingress policy.
|
|
5
|
+
// The table change remains v15's additive replacement_cursor migration.
|
|
6
|
+
export const INDEX_SCHEMA_VERSION = 17;
|
|
7
|
+
/** Read both counters before either opener changes the shared database. */
|
|
8
|
+
export function assertSupportedSchemaVersions(db, supportedRecordSchemaVersion) {
|
|
9
|
+
const currentVersion = db.pragma("user_version", { simple: true });
|
|
10
|
+
if (currentVersion > INDEX_SCHEMA_VERSION) {
|
|
11
|
+
throw new Error(`Unsupported index.db schema version ${currentVersion}; runtime supports ${INDEX_SCHEMA_VERSION}`);
|
|
12
|
+
}
|
|
13
|
+
const hasRecordsVersion = db
|
|
14
|
+
.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'pdpp_schema_version'")
|
|
15
|
+
.get() !== undefined;
|
|
16
|
+
if (hasRecordsVersion) {
|
|
17
|
+
const records = db
|
|
18
|
+
.prepare("SELECT version FROM pdpp_schema_version WHERE id = 1")
|
|
19
|
+
.get();
|
|
20
|
+
if (records && records.version > supportedRecordSchemaVersion) {
|
|
21
|
+
throw new Error(`Unsupported index.db PDPP schema version ${records.version}; runtime supports ${supportedRecordSchemaVersion}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return currentVersion;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=schema-versions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-versions.js","sourceRoot":"","sources":["../../src/storage/schema-versions.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAC1E,qEAAqE;AACrE,6EAA6E;AAC7E,iFAAiF;AACjF,wEAAwE;AACxE,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,2EAA2E;AAC3E,MAAM,UAAU,6BAA6B,CAC3C,EAAqB,EACrB,4BAAoC;IAEpC,MAAM,cAAc,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAW,CAAC;IAC7E,IAAI,cAAc,GAAG,oBAAoB,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CACb,uCAAuC,cAAc,sBAAsB,oBAAoB,EAAE,CAClG,CAAC;IACJ,CAAC;IACD,MAAM,iBAAiB,GACrB,EAAE;SACC,OAAO,CACN,mFAAmF,CACpF;SACA,GAAG,EAAE,KAAK,SAAS,CAAC;IACzB,IAAI,iBAAiB,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,EAAE;aACf,OAAO,CAAC,sDAAsD,CAAC;aAC/D,GAAG,EAAqC,CAAC;QAC5C,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,GAAG,4BAA4B,EAAE,CAAC;YAC9D,MAAM,IAAI,KAAK,CACb,4CAA4C,OAAO,CAAC,OAAO,sBAAsB,4BAA4B,EAAE,CAChH,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DataStoragePort } from "@opendatalabs/personal-server-ts-core/ports";
|
|
2
|
+
import type { LegacyScopeViewPort } from "@opendatalabs/personal-server-ts-core/storage/legacy-scope-view";
|
|
3
|
+
import { type createSqliteRecordStore } from "./pdpp-records-sqlite-store.js";
|
|
4
|
+
/** Runtime contract a host checks before it requests the transition. */
|
|
5
|
+
export declare const STRAVA_BROWSER_TRANSITION_CONTRACT = "strava-browser-transition-v1";
|
|
6
|
+
/**
|
|
7
|
+
* `none`: no transition. `pending`: no completed browser run is evaluated yet.
|
|
8
|
+
* `account_mismatch`: a completed run lacks saved ids. `covered`: handed over.
|
|
9
|
+
*/
|
|
10
|
+
export type StravaTransitionStatus = "none" | "pending" | "account_mismatch" | "covered";
|
|
11
|
+
type Store = ReturnType<typeof createSqliteRecordStore>;
|
|
12
|
+
export declare function createStravaMethodTransition(store: Store, base: LegacyScopeViewPort, files: DataStoragePort): {
|
|
13
|
+
transition: (instance: string, expectedGeneration: number) => Promise<import("./pdpp-records-sqlite-store.js").PdppInstanceBinding>;
|
|
14
|
+
status: (instance: string) => Promise<StravaTransitionStatus>;
|
|
15
|
+
view: LegacyScopeViewPort;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=strava-method-transition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strava-method-transition.d.ts","sourceRoot":"","sources":["../../src/storage/strava-method-transition.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,iEAAiE,CAAC;AAEzE,OAAO,EAEL,KAAK,uBAAuB,EAG7B,MAAM,gCAAgC,CAAC;AAmBxC,wEAAwE;AACxE,eAAO,MAAM,kCAAkC,iCACf,CAAC;AASjC;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAChC,MAAM,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAAC;AAEtD,KAAK,KAAK,GAAG,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAwBxD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,mBAAmB,EACzB,KAAK,EAAE,eAAe;2BA4Bc,MAAM,sBAAsB,MAAM;uBA8FtC,MAAM,KAAG,OAAO,CAAC,sBAAsB,CAAC;;EA8DzE"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { PdppBindingError, } from "./pdpp-records-sqlite-store.js";
|
|
3
|
+
/*
|
|
4
|
+
* Strava export → browser transition.
|
|
5
|
+
*
|
|
6
|
+
* owner POST transition-strava-browser
|
|
7
|
+
* │ snapshot readable export bodies, archive rows, bind strava-browser
|
|
8
|
+
* ▼
|
|
9
|
+
* strava.activities ── saved export body ──┐ until a COMPLETED browser run
|
|
10
|
+
* │ holds every saved activity id
|
|
11
|
+
* ▼
|
|
12
|
+
* browser rows (normal legacy view from then on)
|
|
13
|
+
* strava.coverage_diagnostics ── saved export body, frozen
|
|
14
|
+
*
|
|
15
|
+
* Strava browser records carry no athlete id, so id coverage is the only
|
|
16
|
+
* evidence that the browser signed in to the same account. A completed run
|
|
17
|
+
* that misses saved ids keeps the export and reports `account_mismatch`.
|
|
18
|
+
*/
|
|
19
|
+
/** Runtime contract a host checks before it requests the transition. */
|
|
20
|
+
export const STRAVA_BROWSER_TRANSITION_CONTRACT = "strava-browser-transition-v1";
|
|
21
|
+
const ACTIVITIES = "strava.activities";
|
|
22
|
+
const DIAGNOSTICS = "strava.coverage_diagnostics";
|
|
23
|
+
const SCOPES = [ACTIVITIES, DIAGNOSTICS];
|
|
24
|
+
const SOURCE = "https://registry.pdpp.dev/sources/strava";
|
|
25
|
+
const BROWSER_METHOD = "strava-browser";
|
|
26
|
+
const ACTIVITIES_STREAM = "activities";
|
|
27
|
+
function isStravaScope(scope) {
|
|
28
|
+
return SCOPES.includes(scope);
|
|
29
|
+
}
|
|
30
|
+
function activityIds(data) {
|
|
31
|
+
const rows = data?.activities;
|
|
32
|
+
if (!Array.isArray(rows))
|
|
33
|
+
return null;
|
|
34
|
+
const ids = new Set();
|
|
35
|
+
for (const row of rows) {
|
|
36
|
+
const id = row?.id;
|
|
37
|
+
if (typeof id !== "string")
|
|
38
|
+
return null;
|
|
39
|
+
ids.add(id);
|
|
40
|
+
}
|
|
41
|
+
return ids;
|
|
42
|
+
}
|
|
43
|
+
export function createStravaMethodTransition(store, base, files) {
|
|
44
|
+
/** The export bodies an owner could read before the switch. */
|
|
45
|
+
async function snapshots(instance) {
|
|
46
|
+
const saved = {};
|
|
47
|
+
for (const scope of SCOPES) {
|
|
48
|
+
const read = await base.readLatest(scope);
|
|
49
|
+
if (read.kind === "canonical") {
|
|
50
|
+
saved[scope] = read.envelope;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (read.kind === "file") {
|
|
54
|
+
const head = files.findEntry({ scope });
|
|
55
|
+
if (head)
|
|
56
|
+
saved[scope] = await files.readEnvelope(scope, head.collectedAt);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Diagnostics are informational. Unreadable activities would be lost.
|
|
60
|
+
if (scope === ACTIVITIES && !store.getInstanceBinding(instance).empty)
|
|
61
|
+
throw new PdppBindingError("strava_previous_data_not_readable");
|
|
62
|
+
}
|
|
63
|
+
// Coverage needs every saved id; without them no run could hand over.
|
|
64
|
+
const activities = saved[ACTIVITIES];
|
|
65
|
+
if (activities && activityIds(activities.data) === null)
|
|
66
|
+
throw new PdppBindingError("strava_previous_data_not_readable");
|
|
67
|
+
return saved;
|
|
68
|
+
}
|
|
69
|
+
async function transition(instance, expectedGeneration) {
|
|
70
|
+
if (store.stravaTransition(instance))
|
|
71
|
+
return store.transitionStravaToBrowser({
|
|
72
|
+
instance,
|
|
73
|
+
expectedGeneration,
|
|
74
|
+
expectedWriteClock: 0,
|
|
75
|
+
snapshots: {},
|
|
76
|
+
});
|
|
77
|
+
const clock = store.transitionWriteClock();
|
|
78
|
+
const heads = SCOPES.map((scope) => JSON.stringify(files.findEntry({ scope })));
|
|
79
|
+
const saved = await snapshots(instance);
|
|
80
|
+
return store.readSnapshot(() => {
|
|
81
|
+
// Legacy files have their own index clock; recheck it with the rows.
|
|
82
|
+
const moved = SCOPES.some((scope, index) => JSON.stringify(files.findEntry({ scope })) !== heads[index]);
|
|
83
|
+
if (moved)
|
|
84
|
+
throw new PdppBindingError("binding_generation_mismatch");
|
|
85
|
+
return store.transitionStravaToBrowser({
|
|
86
|
+
instance,
|
|
87
|
+
expectedGeneration,
|
|
88
|
+
expectedWriteClock: clock,
|
|
89
|
+
snapshots: saved,
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** The current transition and saved body of `scope`, while still valid. */
|
|
94
|
+
function saved(scope) {
|
|
95
|
+
if (!isStravaScope(scope) || base.isReset(scope))
|
|
96
|
+
return null;
|
|
97
|
+
const transitions = store.listStravaTransitions();
|
|
98
|
+
if (transitions.length !== 1)
|
|
99
|
+
return null;
|
|
100
|
+
const [current] = transitions;
|
|
101
|
+
const binding = store.getInstanceBinding(current.instance);
|
|
102
|
+
if (binding.deletedAt !== null ||
|
|
103
|
+
binding.method !== BROWSER_METHOD ||
|
|
104
|
+
binding.generation !== current.generation ||
|
|
105
|
+
store.listConnections(SOURCE).length !== 1)
|
|
106
|
+
return null;
|
|
107
|
+
const envelope = current.snapshots[scope];
|
|
108
|
+
if (!envelope)
|
|
109
|
+
return null;
|
|
110
|
+
const digest = createHash("sha256")
|
|
111
|
+
.update(JSON.stringify(envelope))
|
|
112
|
+
.digest("hex");
|
|
113
|
+
return {
|
|
114
|
+
transition: current,
|
|
115
|
+
envelope,
|
|
116
|
+
revision: `strava-transition:${current.generation}:${digest}`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function completedBrowserRun(transition) {
|
|
120
|
+
return store
|
|
121
|
+
.listStreamCompletions(transition.instance)
|
|
122
|
+
.some((receipt) => receipt.stream === ACTIVITIES_STREAM &&
|
|
123
|
+
receipt.method === BROWSER_METHOD &&
|
|
124
|
+
receipt.generation === transition.generation);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Judge the browser rows against the saved activities. Only a completed
|
|
128
|
+
* run counts; a covering one records the handover.
|
|
129
|
+
*/
|
|
130
|
+
async function evaluate(before) {
|
|
131
|
+
const current = await base.readLatest(ACTIVITIES);
|
|
132
|
+
if (before.transition.activitiesCovered)
|
|
133
|
+
return { status: "covered", current };
|
|
134
|
+
if (!completedBrowserRun(before.transition) || current.kind !== "canonical")
|
|
135
|
+
return { status: "pending", current };
|
|
136
|
+
// Unreadable saved ids fail closed: nothing proves the same account.
|
|
137
|
+
const savedIds = activityIds(before.envelope.data);
|
|
138
|
+
const browserIds = activityIds(current.envelope.data);
|
|
139
|
+
const covers = savedIds !== null &&
|
|
140
|
+
browserIds !== null &&
|
|
141
|
+
[...savedIds].every((id) => browserIds.has(id));
|
|
142
|
+
if (!covers)
|
|
143
|
+
return { status: "account_mismatch", current };
|
|
144
|
+
store.confirmStravaTransition(before.transition.instance, before.transition.generation);
|
|
145
|
+
return { status: "covered", current };
|
|
146
|
+
}
|
|
147
|
+
async function status(instance) {
|
|
148
|
+
const before = saved(ACTIVITIES);
|
|
149
|
+
if (before?.transition.instance === instance)
|
|
150
|
+
return (await evaluate(before)).status;
|
|
151
|
+
const transition = store.stravaTransition(instance);
|
|
152
|
+
return transition?.activitiesCovered ? "covered" : "none";
|
|
153
|
+
}
|
|
154
|
+
function savedBody(before) {
|
|
155
|
+
return {
|
|
156
|
+
kind: "canonical",
|
|
157
|
+
envelope: before.envelope,
|
|
158
|
+
revision: before.revision,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/** Listed as the saved body until browser rows have taken over. */
|
|
162
|
+
function listedSaved(scope) {
|
|
163
|
+
const before = saved(scope);
|
|
164
|
+
if (!before)
|
|
165
|
+
return null;
|
|
166
|
+
if (scope === ACTIVITIES && before.transition.activitiesCovered)
|
|
167
|
+
return null;
|
|
168
|
+
return before;
|
|
169
|
+
}
|
|
170
|
+
const view = {
|
|
171
|
+
...base,
|
|
172
|
+
async readLatest(scope) {
|
|
173
|
+
const before = saved(scope);
|
|
174
|
+
if (!before)
|
|
175
|
+
return base.readLatest(scope);
|
|
176
|
+
// Diagnostics stay frozen at the export's last body.
|
|
177
|
+
if (scope === DIAGNOSTICS)
|
|
178
|
+
return savedBody(before);
|
|
179
|
+
const { status: verdict, current } = await evaluate(before);
|
|
180
|
+
// A reset, deletion or replacement during the read invalidates it.
|
|
181
|
+
if (saved(scope)?.revision !== before.revision)
|
|
182
|
+
return base.readLatest(scope);
|
|
183
|
+
return verdict === "covered" ? current : savedBody(before);
|
|
184
|
+
},
|
|
185
|
+
listingFor(scope) {
|
|
186
|
+
const before = listedSaved(scope);
|
|
187
|
+
return before
|
|
188
|
+
? { kind: "canonical", collectedAt: before.envelope.collectedAt }
|
|
189
|
+
: base.listingFor(scope);
|
|
190
|
+
},
|
|
191
|
+
listCanonicalScopes(prefix) {
|
|
192
|
+
const listed = new Map(base.listCanonicalScopes(prefix).map((item) => [item.scope, item]));
|
|
193
|
+
for (const scope of SCOPES) {
|
|
194
|
+
const before = listedSaved(scope);
|
|
195
|
+
if (!before || (prefix && !scope.startsWith(prefix)))
|
|
196
|
+
continue;
|
|
197
|
+
listed.set(scope, { scope, collectedAt: before.envelope.collectedAt });
|
|
198
|
+
}
|
|
199
|
+
return [...listed.values()];
|
|
200
|
+
},
|
|
201
|
+
resetTakeover(scope) {
|
|
202
|
+
base.resetTakeover(scope);
|
|
203
|
+
store.clearStravaTransitionScope(scope);
|
|
204
|
+
},
|
|
205
|
+
ownsScope: (scope) => saved(scope) !== null || base.ownsScope(scope),
|
|
206
|
+
};
|
|
207
|
+
return { transition, status, view };
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=strava-method-transition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strava-method-transition.js","sourceRoot":"","sources":["../../src/storage/strava-method-transition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC,OAAO,EACL,gBAAgB,GAIjB,MAAM,gCAAgC,CAAC;AAExC;;;;;;;;;;;;;;;GAeG;AAEH,wEAAwE;AACxE,MAAM,CAAC,MAAM,kCAAkC,GAC7C,8BAA8B,CAAC;AAEjC,MAAM,UAAU,GAAG,mBAAmB,CAAC;AACvC,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAClD,MAAM,MAAM,GAAqC,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAC3E,MAAM,MAAM,GAAG,0CAA0C,CAAC;AAC1D,MAAM,cAAc,GAAG,gBAAgB,CAAC;AACxC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAiBvC,SAAS,aAAa,CAAC,KAAa;IAClC,OAAQ,MAA4B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,WAAW,CAAC,IAAa;IAChC,MAAM,IAAI,GAAI,IAAwC,EAAE,UAAU,CAAC;IACnE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAU,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,EAAE,GAAI,GAA+B,EAAE,EAAE,CAAC;QAChD,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACxC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,4BAA4B,CAC1C,KAAY,EACZ,IAAyB,EACzB,KAAsB;IAEtB,+DAA+D;IAC/D,KAAK,UAAU,SAAS,CAAC,QAAgB;QACvC,MAAM,KAAK,GAAkC,EAAE,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC9B,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAC7B,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;gBACxC,IAAI,IAAI;oBACN,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;gBACnE,SAAS;YACX,CAAC;YACD,sEAAsE;YACtE,IAAI,KAAK,KAAK,UAAU,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,KAAK;gBACnE,MAAM,IAAI,gBAAgB,CAAC,mCAAmC,CAAC,CAAC;QACpE,CAAC;QACD,sEAAsE;QACtE,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QACrC,IAAI,UAAU,IAAI,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI;YACrD,MAAM,IAAI,gBAAgB,CAAC,mCAAmC,CAAC,CAAC;QAClE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,KAAK,UAAU,UAAU,CAAC,QAAgB,EAAE,kBAA0B;QACpE,IAAI,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC;YAClC,OAAO,KAAK,CAAC,yBAAyB,CAAC;gBACrC,QAAQ;gBACR,kBAAkB;gBAClB,kBAAkB,EAAE,CAAC;gBACrB,SAAS,EAAE,EAAE;aACd,CAAC,CAAC;QACL,MAAM,KAAK,GAAG,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACjC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAC3C,CAAC;QACF,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;YAC7B,qEAAqE;YACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CACvB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACf,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAC9D,CAAC;YACF,IAAI,KAAK;gBAAE,MAAM,IAAI,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;YACrE,OAAO,KAAK,CAAC,yBAAyB,CAAC;gBACrC,QAAQ;gBACR,kBAAkB;gBAClB,kBAAkB,EAAE,KAAK;gBACzB,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IAC3E,SAAS,KAAK,CAAC,KAAa;QAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC9D,MAAM,WAAW,GAAG,KAAK,CAAC,qBAAqB,EAAE,CAAC;QAClD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3D,IACE,OAAO,CAAC,SAAS,KAAK,IAAI;YAC1B,OAAO,CAAC,MAAM,KAAK,cAAc;YACjC,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;YACzC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,MAAM,KAAK,CAAC;YAE1C,OAAO,IAAI,CAAC;QACd,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;aAChC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;aAChC,MAAM,CAAC,KAAK,CAAC,CAAC;QACjB,OAAO;YACL,UAAU,EAAE,OAAO;YACnB,QAAQ;YACR,QAAQ,EAAE,qBAAqB,OAAO,CAAC,UAAU,IAAI,MAAM,EAAE;SAC9D,CAAC;IACJ,CAAC;IAED,SAAS,mBAAmB,CAAC,UAA4B;QACvD,OAAO,KAAK;aACT,qBAAqB,CAAC,UAAU,CAAC,QAAQ,CAAC;aAC1C,IAAI,CACH,CAAC,OAAO,EAAE,EAAE,CACV,OAAO,CAAC,MAAM,KAAK,iBAAiB;YACpC,OAAO,CAAC,MAAM,KAAK,cAAc;YACjC,OAAO,CAAC,UAAU,KAAK,UAAU,CAAC,UAAU,CAC/C,CAAC;IACN,CAAC;IAED;;;OAGG;IACH,KAAK,UAAU,QAAQ,CAAC,MAAa;QAInC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,MAAM,CAAC,UAAU,CAAC,iBAAiB;YACrC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QACxC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW;YACzE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;QACxC,qEAAqE;QACrE,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,MAAM,GACV,QAAQ,KAAK,IAAI;YACjB,UAAU,KAAK,IAAI;YACnB,CAAC,GAAG,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC;QAC5D,KAAK,CAAC,uBAAuB,CAC3B,MAAM,CAAC,UAAU,CAAC,QAAQ,EAC1B,MAAM,CAAC,UAAU,CAAC,UAAU,CAC7B,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IACxC,CAAC;IAED,KAAK,UAAU,MAAM,CAAC,QAAgB;QACpC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;QACjC,IAAI,MAAM,EAAE,UAAU,CAAC,QAAQ,KAAK,QAAQ;YAC1C,OAAO,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACzC,MAAM,UAAU,GAAG,KAAK,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QACpD,OAAO,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5D,CAAC;IAED,SAAS,SAAS,CAAC,MAAa;QAC9B,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;SAC1B,CAAC;IACJ,CAAC;IAED,mEAAmE;IACnE,SAAS,WAAW,CAAC,KAAa;QAChC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,IAAI,KAAK,KAAK,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,iBAAiB;YAC7D,OAAO,IAAI,CAAC;QACd,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,GAAwB;QAChC,GAAG,IAAI;QACP,KAAK,CAAC,UAAU,CAAC,KAAK;YACpB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAC3C,qDAAqD;YACrD,IAAI,KAAK,KAAK,WAAW;gBAAE,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;YACpD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC5D,mEAAmE;YACnE,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,QAAQ,KAAK,MAAM,CAAC,QAAQ;gBAC5C,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QACD,UAAU,CAAC,KAAK;YACd,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;YAClC,OAAO,MAAM;gBACX,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE;gBACjE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QACD,mBAAmB,CAAC,MAAM;YACxB,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CACnE,CAAC;YACF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;oBAAE,SAAS;gBAC/D,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;YACzE,CAAC;YACD,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9B,CAAC;QACD,aAAa,CAAC,KAAK;YACjB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC1B,KAAK,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;KACrE,CAAC;IACF,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACtC,CAAC"}
|