@opendatalabs/personal-server-ts-lite 0.0.1-canary.00328bf

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 (68) hide show
  1. package/dist/bridge.d.ts +23 -0
  2. package/dist/bridge.d.ts.map +1 -0
  3. package/dist/bridge.js +53 -0
  4. package/dist/bridge.js.map +1 -0
  5. package/dist/browser-runtime.d.ts +58 -0
  6. package/dist/browser-runtime.d.ts.map +1 -0
  7. package/dist/browser-runtime.js +214 -0
  8. package/dist/browser-runtime.js.map +1 -0
  9. package/dist/browser-tls-rustls/browser_tls_rustls.d.ts +49 -0
  10. package/dist/browser-tls-rustls/browser_tls_rustls.js +401 -0
  11. package/dist/browser-tls-rustls/browser_tls_rustls_bg.wasm +0 -0
  12. package/dist/client.d.ts +22 -0
  13. package/dist/client.d.ts.map +1 -0
  14. package/dist/client.js +408 -0
  15. package/dist/client.js.map +1 -0
  16. package/dist/derivatives.d.ts +51 -0
  17. package/dist/derivatives.d.ts.map +1 -0
  18. package/dist/derivatives.js +87 -0
  19. package/dist/derivatives.js.map +1 -0
  20. package/dist/diagnostics.d.ts +166 -0
  21. package/dist/diagnostics.d.ts.map +1 -0
  22. package/dist/diagnostics.js +265 -0
  23. package/dist/diagnostics.js.map +1 -0
  24. package/dist/index.d.ts +18 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +19 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/mcp-store.d.ts +35 -0
  29. package/dist/mcp-store.d.ts.map +1 -0
  30. package/dist/mcp-store.js +208 -0
  31. package/dist/mcp-store.js.map +1 -0
  32. package/dist/owner-binding.d.ts +7 -0
  33. package/dist/owner-binding.d.ts.map +1 -0
  34. package/dist/owner-binding.js +18 -0
  35. package/dist/owner-binding.js.map +1 -0
  36. package/dist/persistence.d.ts +69 -0
  37. package/dist/persistence.d.ts.map +1 -0
  38. package/dist/persistence.js +58 -0
  39. package/dist/persistence.js.map +1 -0
  40. package/dist/relay-tls.d.ts +61 -0
  41. package/dist/relay-tls.d.ts.map +1 -0
  42. package/dist/relay-tls.js +316 -0
  43. package/dist/relay-tls.js.map +1 -0
  44. package/dist/relay.d.ts +149 -0
  45. package/dist/relay.d.ts.map +1 -0
  46. package/dist/relay.js +646 -0
  47. package/dist/relay.js.map +1 -0
  48. package/dist/runtime.d.ts +188 -0
  49. package/dist/runtime.d.ts.map +1 -0
  50. package/dist/runtime.js +1178 -0
  51. package/dist/runtime.js.map +1 -0
  52. package/dist/state.d.ts +72 -0
  53. package/dist/state.d.ts.map +1 -0
  54. package/dist/state.js +366 -0
  55. package/dist/state.js.map +1 -0
  56. package/dist/storage-utils.d.ts +8 -0
  57. package/dist/storage-utils.d.ts.map +1 -0
  58. package/dist/storage-utils.js +67 -0
  59. package/dist/storage-utils.js.map +1 -0
  60. package/dist/storage.d.ts +61 -0
  61. package/dist/storage.d.ts.map +1 -0
  62. package/dist/storage.js +718 -0
  63. package/dist/storage.js.map +1 -0
  64. package/dist/sync.d.ts +58 -0
  65. package/dist/sync.d.ts.map +1 -0
  66. package/dist/sync.js +216 -0
  67. package/dist/sync.js.map +1 -0
  68. package/package.json +40 -0
@@ -0,0 +1,208 @@
1
+ /**
2
+ * IndexedDB-backed `McpConnectionStore` for Web PS Lite.
3
+ *
4
+ * Phase 1 trade-off: persists the per-connection grantee private key in
5
+ * PLAINTEXT in IndexedDB. The owner-derived AES-GCM wrap used for the PS Lite
6
+ * server identity is not yet applied to grantee keys — that's the Phase 2
7
+ * "encrypt grantee private keys at rest" task in
8
+ * `260604-PLAN-vana-mcp-personal-server.md`. The risk is bounded by:
9
+ *
10
+ * 1. The browser same-origin policy — only code running on the PS Lite tab's
11
+ * origin (e.g. app-dev.vana.org) can read this store.
12
+ * 2. Grantee keys are scoped per-connection and revocable. A leaked key only
13
+ * lets the holder read the grants that connection already approved; any
14
+ * revoke removes both the grant and the connection's lookup record.
15
+ * 3. There are no write tools — leaked grantee keys cannot mutate user data.
16
+ *
17
+ * Persistent storage is strongly preferred over in-memory because:
18
+ * - app-dev page reloads are routine in a browser app;
19
+ * - Claude's MCP URL is meant to live in the Claude config across sessions;
20
+ * - the alternative (re-create on every boot) would silently invalidate every
21
+ * prior Claude connection on every reload, indistinguishable from a real
22
+ * revoke from the user's perspective.
23
+ */
24
+ import { isMcpTokenExpired, matchesMcpRefreshHash, } from "@opendatalabs/personal-server-ts-core/mcp";
25
+ const DEFAULT_DB_NAME = "personal-server-lite";
26
+ const DEFAULT_STORE_NAME = "mcpConnections";
27
+ const DEFAULT_AUTHORIZATION_STORE_NAME = "mcpOAuthAuthorizations";
28
+ const TOKEN_HASH_INDEX = "tokenHash";
29
+ const AUTHORIZATION_CODE_HASH_INDEX = "authorizationCodeHash";
30
+ const DB_VERSION = 2;
31
+ const CONNECTION_INDEXES = [
32
+ { name: TOKEN_HASH_INDEX, keyPath: "tokenHash", unique: true },
33
+ ];
34
+ const AUTHORIZATION_INDEXES = [
35
+ {
36
+ name: AUTHORIZATION_CODE_HASH_INDEX,
37
+ keyPath: "authorizationCodeHash",
38
+ unique: true,
39
+ },
40
+ ];
41
+ const DEFAULT_CONNECTION_OPTIONS = {
42
+ dbName: DEFAULT_DB_NAME,
43
+ storeName: DEFAULT_STORE_NAME,
44
+ };
45
+ const DEFAULT_AUTHORIZATION_OPTIONS = {
46
+ dbName: DEFAULT_DB_NAME,
47
+ storeName: DEFAULT_AUTHORIZATION_STORE_NAME,
48
+ };
49
+ function ensureObjectStore(db, transaction, opts, indexes) {
50
+ const store = db.objectStoreNames.contains(opts.storeName)
51
+ ? transaction?.objectStore(opts.storeName)
52
+ : db.createObjectStore(opts.storeName, { keyPath: "id" });
53
+ if (!store)
54
+ return;
55
+ for (const index of indexes) {
56
+ if (!store.indexNames.contains(index.name)) {
57
+ store.createIndex(index.name, index.keyPath, { unique: index.unique });
58
+ }
59
+ }
60
+ }
61
+ function openDb(opts, indexes) {
62
+ if (typeof indexedDB === "undefined") {
63
+ throw new Error("IndexedDB is not available in this runtime");
64
+ }
65
+ return new Promise((resolve, reject) => {
66
+ const request = indexedDB.open(opts.dbName, DB_VERSION);
67
+ request.onupgradeneeded = () => {
68
+ const db = request.result;
69
+ ensureObjectStore(db, request.transaction, opts, indexes);
70
+ ensureObjectStore(db, request.transaction, DEFAULT_CONNECTION_OPTIONS, CONNECTION_INDEXES);
71
+ ensureObjectStore(db, request.transaction, DEFAULT_AUTHORIZATION_OPTIONS, AUTHORIZATION_INDEXES);
72
+ };
73
+ request.onsuccess = () => resolve(request.result);
74
+ request.onerror = () => reject(request.error);
75
+ });
76
+ }
77
+ function runTx(opts, mode, indexes, fn) {
78
+ return openDb(opts, indexes).then((db) => new Promise((resolve, reject) => {
79
+ const transaction = db.transaction(opts.storeName, mode);
80
+ const store = transaction.objectStore(opts.storeName);
81
+ const request = fn(store);
82
+ request.onsuccess = () => resolve(request.result);
83
+ request.onerror = () => reject(request.error);
84
+ transaction.oncomplete = () => db.close();
85
+ transaction.onerror = () => {
86
+ db.close();
87
+ reject(transaction.error);
88
+ };
89
+ }));
90
+ }
91
+ function runIndexQuery(opts, indexName, indexes, fn) {
92
+ return openDb(opts, indexes).then((db) => new Promise((resolve, reject) => {
93
+ const transaction = db.transaction(opts.storeName, "readonly");
94
+ const store = transaction.objectStore(opts.storeName);
95
+ const request = fn(store.index(indexName));
96
+ request.onsuccess = () => resolve(request.result);
97
+ request.onerror = () => reject(request.error);
98
+ transaction.oncomplete = () => db.close();
99
+ transaction.onerror = () => {
100
+ db.close();
101
+ reject(transaction.error);
102
+ };
103
+ }));
104
+ }
105
+ function mutateConnectionRecord(opts, id, update) {
106
+ return openDb(opts, CONNECTION_INDEXES).then((db) => new Promise((resolve, reject) => {
107
+ const transaction = db.transaction(opts.storeName, "readwrite");
108
+ const store = transaction.objectStore(opts.storeName);
109
+ const request = store.get(id);
110
+ let result = null;
111
+ request.onsuccess = () => {
112
+ if (!request.result)
113
+ return;
114
+ result = update(structuredClone(request.result));
115
+ store.put(result);
116
+ };
117
+ request.onerror = () => reject(request.error);
118
+ transaction.oncomplete = () => {
119
+ db.close();
120
+ resolve(result ? structuredClone(result) : null);
121
+ };
122
+ transaction.onerror = () => {
123
+ db.close();
124
+ reject(transaction.error);
125
+ };
126
+ }));
127
+ }
128
+ export function createIndexedDbMcpConnectionStore(options = {}) {
129
+ const resolved = {
130
+ dbName: options.dbName ?? DEFAULT_DB_NAME,
131
+ storeName: options.storeName ?? DEFAULT_STORE_NAME,
132
+ };
133
+ return {
134
+ async create(record) {
135
+ const existing = await runTx(resolved, "readonly", CONNECTION_INDEXES, (store) => store.get(record.id));
136
+ if (existing) {
137
+ throw new Error(`mcp connection ${record.id} already exists`);
138
+ }
139
+ await runTx(resolved, "readwrite", CONNECTION_INDEXES, (store) => store.put({ ...record }));
140
+ },
141
+ async list() {
142
+ const all = await runTx(resolved, "readonly", CONNECTION_INDEXES, (store) => store.getAll());
143
+ return all.map((r) => ({ ...r }));
144
+ },
145
+ async getById(id) {
146
+ const record = await runTx(resolved, "readonly", CONNECTION_INDEXES, (store) => store.get(id));
147
+ return record ? { ...record } : null;
148
+ },
149
+ async getByTokenHash(tokenHash) {
150
+ const record = await runIndexQuery(resolved, TOKEN_HASH_INDEX, CONNECTION_INDEXES, (index) => index.get(tokenHash));
151
+ if (!record)
152
+ return null;
153
+ if (record.status !== "approved")
154
+ return null;
155
+ if (isMcpTokenExpired(record))
156
+ return null;
157
+ return { ...record };
158
+ },
159
+ async getByRefreshTokenHash(refreshTokenHash) {
160
+ // No IndexedDB index: a presented token may match either the current or
161
+ // the rotated-out hash, and the store holds a handful of connections.
162
+ const all = await runTx(resolved, "readonly", CONNECTION_INDEXES, (store) => store.getAll());
163
+ const record = all.find((candidate) => matchesMcpRefreshHash(candidate, refreshTokenHash));
164
+ return record ? { ...record } : null;
165
+ },
166
+ mutate(id, update) {
167
+ return mutateConnectionRecord(resolved, id, update);
168
+ },
169
+ async update(id, patch) {
170
+ return mutateConnectionRecord(resolved, id, (existing) => ({ ...existing, ...patch }));
171
+ },
172
+ };
173
+ }
174
+ export function createIndexedDbMcpOAuthAuthorizationStore(options = {}) {
175
+ const resolved = {
176
+ dbName: options.dbName ?? DEFAULT_DB_NAME,
177
+ storeName: options.storeName ?? DEFAULT_AUTHORIZATION_STORE_NAME,
178
+ };
179
+ return {
180
+ async create(record) {
181
+ const existing = await runTx(resolved, "readonly", AUTHORIZATION_INDEXES, (store) => store.get(record.id));
182
+ if (existing) {
183
+ throw new Error(`mcp oauth authorization ${record.id} already exists`);
184
+ }
185
+ await runTx(resolved, "readwrite", AUTHORIZATION_INDEXES, (store) => store.put({ ...record }));
186
+ },
187
+ async getById(id) {
188
+ const record = await runTx(resolved, "readonly", AUTHORIZATION_INDEXES, (store) => store.get(id));
189
+ return record ? { ...record } : null;
190
+ },
191
+ async getByCodeHash(authorizationCodeHash) {
192
+ const record = await runIndexQuery(resolved, AUTHORIZATION_CODE_HASH_INDEX, AUTHORIZATION_INDEXES, (index) => index.get(authorizationCodeHash));
193
+ return record ? { ...record } : null;
194
+ },
195
+ async update(id, patch) {
196
+ const existing = await runTx(resolved, "readonly", AUTHORIZATION_INDEXES, (store) => store.get(id));
197
+ if (!existing)
198
+ return null;
199
+ const updated = { ...existing, ...patch };
200
+ await runTx(resolved, "readwrite", AUTHORIZATION_INDEXES, (store) => store.put(updated));
201
+ return { ...updated };
202
+ },
203
+ async delete(id) {
204
+ await runTx(resolved, "readwrite", AUTHORIZATION_INDEXES, (store) => store.delete(id));
205
+ },
206
+ };
207
+ }
208
+ //# sourceMappingURL=mcp-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-store.js","sourceRoot":"","sources":["../src/mcp-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type Address } from "viem";
2
+ export interface PsLiteOwnerBindingInput {
3
+ ownerAddress?: Address;
4
+ ownerSignature: `0x${string}`;
5
+ }
6
+ export declare function resolvePsLiteOwner(input: PsLiteOwnerBindingInput): Promise<Address>;
7
+ //# sourceMappingURL=owner-binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-binding.d.ts","sourceRoot":"","sources":["../src/owner-binding.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqC,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAEvE,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,KAAK,MAAM,EAAE,CAAC;CAC/B;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAclB"}
@@ -0,0 +1,18 @@
1
+ import { recoverServerOwner } from "@opendatalabs/vana-sdk/browser";
2
+ import { buildPersonalServerLiteOwnerBindingMessage } from "@opendatalabs/vana-sdk/protocol/personal-server-lite-owner-binding";
3
+ import { getAddress, recoverMessageAddress } from "viem";
4
+ export async function resolvePsLiteOwner(input) {
5
+ if (!input.ownerAddress) {
6
+ return recoverServerOwner(input.ownerSignature);
7
+ }
8
+ const expected = getAddress(input.ownerAddress);
9
+ const recovered = await recoverMessageAddress({
10
+ message: buildPersonalServerLiteOwnerBindingMessage(expected),
11
+ signature: input.ownerSignature,
12
+ });
13
+ if (recovered.toLowerCase() !== expected.toLowerCase()) {
14
+ throw new Error("PS Lite owner signature does not match ownerAddress");
15
+ }
16
+ return expected;
17
+ }
18
+ //# sourceMappingURL=owner-binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-binding.js","sourceRoot":"","sources":["../src/owner-binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,0CAA0C,EAAE,MAAM,oEAAoE,CAAC;AAChI,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAgB,MAAM,MAAM,CAAC;AAOvE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAA8B;IAE9B,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QACxB,OAAO,kBAAkB,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,MAAM,qBAAqB,CAAC;QAC5C,OAAO,EAAE,0CAA0C,CAAC,QAAQ,CAAC;QAC7D,SAAS,EAAE,KAAK,CAAC,cAAc;KAChC,CAAC,CAAC;IACH,IAAI,SAAS,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,69 @@
1
+ import type { DataStoragePort } from "@opendatalabs/personal-server-ts-core/ports";
2
+ import type { ServerConfig } from "@opendatalabs/personal-server-ts-core/schemas";
3
+ import type { AccessLogReader } from "@opendatalabs/personal-server-ts-core/logging/access-reader";
4
+ import type { AccessLogWriter } from "@opendatalabs/personal-server-ts-core/logging/access-log";
5
+ import type { McpConnectionStore, McpOAuthAuthorizationStore } from "@opendatalabs/personal-server-ts-core/mcp";
6
+ import type { PsLiteRuntimeOptions, PsLiteTokenStore } from "./runtime.js";
7
+ import { type PsLiteStateStore } from "./state.js";
8
+ import type { PsLiteRelayTlsIdentityStore } from "./relay-tls.js";
9
+ /**
10
+ * The complete set of PS Lite persistence ports, named as one composition
11
+ * contract for a host (Mobile) that backs them all with a single durable store.
12
+ *
13
+ * This is a struct of the EXISTING narrow contracts — it deliberately does not
14
+ * collapse them into one catch-all domain API. A host may implement each port
15
+ * over one SQLite database, but PS Lite keeps addressing them by their narrow
16
+ * responsibilities (data storage, key/value state, tokens, access logs, MCP
17
+ * connection/authorization records, relay TLS identity).
18
+ *
19
+ * `relayTlsIdentity` is consumed by the relay TLS factory
20
+ * (`createRustlsPsLiteRelayTlsFactory`), not the HTTP runtime. The start
21
+ * factory forwards it to the relay automatically. A supplied bundle is all or
22
+ * nothing: hosts must not accidentally combine native and browser persistence.
23
+ */
24
+ export interface PsLitePersistenceBundle {
25
+ /** Data envelopes + index metadata. */
26
+ storage: DataStoragePort;
27
+ /** Key/value runtime state: config, encrypted server identity, relay, cursor. */
28
+ state: PsLiteStateStore;
29
+ /** Session/device access tokens. */
30
+ tokens: PsLiteTokenStore;
31
+ /** Access-log read + write. */
32
+ accessLog: AccessLogReader & AccessLogWriter;
33
+ /** Per-connection MCP records (grantee key, token hash, grants). */
34
+ mcpConnections: McpConnectionStore;
35
+ /** In-flight MCP OAuth authorization records. */
36
+ mcpOAuthAuthorizations: McpOAuthAuthorizationStore;
37
+ /** Issued relay TLS identity cache. Consumed by the relay TLS factory. */
38
+ relayTlsIdentity: PsLiteRelayTlsIdentityStore;
39
+ }
40
+ /**
41
+ * The subset of {@link PsLiteRuntimeOptions} that a persistence bundle supplies.
42
+ * Everything a caller still owns (auth, identity, gateway, signer, config
43
+ * values, sync manager) stays out of the bundle.
44
+ */
45
+ export type PsLitePersistenceRuntimeOptions = Pick<PsLiteRuntimeOptions, "storage" | "tokenStore" | "accessLogReader" | "accessLogWriter" | "saveConfig" | "mcpConnectionStore" | "mcpOAuthAuthorizationStore"> & Required<Pick<PsLiteRuntimeOptions, "config">>;
46
+ /**
47
+ * Map a {@link PsLitePersistenceBundle} onto the runtime option subset it backs,
48
+ * so a host can construct PS Lite with no direct browser storage dependency:
49
+ *
50
+ * ```ts
51
+ * const runtime = createPsLiteRuntime({
52
+ * ...(await psLitePersistenceRuntimeOptions(bundle, configDefaults)),
53
+ * auth,
54
+ * identity,
55
+ * serverOwner,
56
+ * active: true,
57
+ * });
58
+ * ```
59
+ *
60
+ * `saveConfig` is derived from the injected state store via the existing
61
+ * `savePsLiteConfig` contract, so config writes land in the host's store.
62
+ */
63
+ export declare function psLitePersistenceRuntimeOptions(bundle: PsLitePersistenceBundle, configDefaults?: Partial<ServerConfig>): Promise<PsLitePersistenceRuntimeOptions>;
64
+ /**
65
+ * Defends the all-or-nothing bundle contract at the JavaScript boundary, where
66
+ * TypeScript's required properties are not enforced.
67
+ */
68
+ export declare function assertCompletePsLitePersistenceBundle(bundle: PsLitePersistenceBundle | null | undefined): void;
69
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6DAA6D,CAAC;AACnG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0DAA0D,CAAC;AAChG,OAAO,KAAK,EACV,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,uBAAuB;IACtC,uCAAuC;IACvC,OAAO,EAAE,eAAe,CAAC;IACzB,iFAAiF;IACjF,KAAK,EAAE,gBAAgB,CAAC;IACxB,oCAAoC;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,+BAA+B;IAC/B,SAAS,EAAE,eAAe,GAAG,eAAe,CAAC;IAC7C,oEAAoE;IACpE,cAAc,EAAE,kBAAkB,CAAC;IACnC,iDAAiD;IACjD,sBAAsB,EAAE,0BAA0B,CAAC;IACnD,0EAA0E;IAC1E,gBAAgB,EAAE,2BAA2B,CAAC;CAC/C;AAED;;;;GAIG;AACH,MAAM,MAAM,+BAA+B,GAAG,IAAI,CAChD,oBAAoB,EAClB,SAAS,GACT,YAAY,GACZ,iBAAiB,GACjB,iBAAiB,GACjB,YAAY,GACZ,oBAAoB,GACpB,4BAA4B,CAC/B,GACC,QAAQ,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,uBAAuB,EAC/B,cAAc,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GACrC,OAAO,CAAC,+BAA+B,CAAC,CAgB1C;AAED;;;GAGG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,GACjD,IAAI,CAmBN"}
@@ -0,0 +1,58 @@
1
+ import { loadOrCreatePsLiteConfig, savePsLiteConfig, } from "./state.js";
2
+ /**
3
+ * Map a {@link PsLitePersistenceBundle} onto the runtime option subset it backs,
4
+ * so a host can construct PS Lite with no direct browser storage dependency:
5
+ *
6
+ * ```ts
7
+ * const runtime = createPsLiteRuntime({
8
+ * ...(await psLitePersistenceRuntimeOptions(bundle, configDefaults)),
9
+ * auth,
10
+ * identity,
11
+ * serverOwner,
12
+ * active: true,
13
+ * });
14
+ * ```
15
+ *
16
+ * `saveConfig` is derived from the injected state store via the existing
17
+ * `savePsLiteConfig` contract, so config writes land in the host's store.
18
+ */
19
+ export async function psLitePersistenceRuntimeOptions(bundle, configDefaults) {
20
+ assertCompletePsLitePersistenceBundle(bundle);
21
+ const config = await loadOrCreatePsLiteConfig(bundle.state, configDefaults);
22
+ return {
23
+ storage: bundle.storage,
24
+ config,
25
+ tokenStore: bundle.tokens,
26
+ accessLogReader: bundle.accessLog,
27
+ accessLogWriter: bundle.accessLog,
28
+ saveConfig: async (nextConfig) => {
29
+ const saved = await savePsLiteConfig(bundle.state, nextConfig);
30
+ Object.assign(config, saved);
31
+ },
32
+ mcpConnectionStore: bundle.mcpConnections,
33
+ mcpOAuthAuthorizationStore: bundle.mcpOAuthAuthorizations,
34
+ };
35
+ }
36
+ /**
37
+ * Defends the all-or-nothing bundle contract at the JavaScript boundary, where
38
+ * TypeScript's required properties are not enforced.
39
+ */
40
+ export function assertCompletePsLitePersistenceBundle(bundle) {
41
+ if (!bundle || typeof bundle !== "object") {
42
+ throw new Error("PS Lite persistence bundle must be a complete object");
43
+ }
44
+ const required = [
45
+ "storage",
46
+ "state",
47
+ "tokens",
48
+ "accessLog",
49
+ "mcpConnections",
50
+ "mcpOAuthAuthorizations",
51
+ "relayTlsIdentity",
52
+ ];
53
+ const missing = required.filter((key) => bundle[key] == null);
54
+ if (missing.length > 0) {
55
+ throw new Error(`PS Lite persistence bundle must be complete; missing ${missing.join(", ")}`);
56
+ }
57
+ }
58
+ //# sourceMappingURL=persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AASA,OAAO,EACL,wBAAwB,EACxB,gBAAgB,GAEjB,MAAM,YAAY,CAAC;AAoDpB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,MAA+B,EAC/B,cAAsC;IAEtC,qCAAqC,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAC5E,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM;QACN,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,eAAe,EAAE,MAAM,CAAC,SAAS;QACjC,eAAe,EAAE,MAAM,CAAC,SAAS;QACjC,UAAU,EAAE,KAAK,EAAE,UAAmB,EAAE,EAAE;YACxC,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YAC/D,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,kBAAkB,EAAE,MAAM,CAAC,cAAc;QACzC,0BAA0B,EAAE,MAAM,CAAC,sBAAsB;KAC1D,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qCAAqC,CACnD,MAAkD;IAElD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,QAAQ,GAAsC;QAClD,SAAS;QACT,OAAO;QACP,QAAQ;QACR,WAAW;QACX,gBAAgB;QAChB,wBAAwB;QACxB,kBAAkB;KACnB,CAAC;IACF,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;IAC9D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,wDAAwD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7E,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { PsLiteRelayTlsFactory } from "./relay.js";
2
+ /**
3
+ * Persistence port for the relay's issued TLS identity. PS Lite runtime code
4
+ * resolves the cached cert through this injected store instead of reaching for
5
+ * `globalThis.localStorage` directly, so a non-browser host (Mobile) can back
6
+ * it with app-private storage. Browser callers get the localStorage-backed
7
+ * default via {@link createLocalStoragePsLiteRelayTlsIdentityStore}.
8
+ */
9
+ export interface PsLiteRelayTlsIdentityStore {
10
+ read(hostname: string): Promise<PsLiteRelayTlsIdentity | null> | PsLiteRelayTlsIdentity | null;
11
+ write(identity: PsLiteRelayTlsIdentity): Promise<void> | void;
12
+ }
13
+ export interface RustlsPsLiteRelayTlsOptions {
14
+ controlUrl: string;
15
+ publicSuffix?: string;
16
+ certIssuerUrl?: string;
17
+ /**
18
+ * Injected persistence for the issued relay TLS identity. Omit to fall back
19
+ * to {@link storage} (or, if that is also omitted, the browser localStorage
20
+ * default). Non-browser hosts pass their own store to keep runtime code free
21
+ * of hidden `globalThis` access.
22
+ */
23
+ identityStore?: PsLiteRelayTlsIdentityStore;
24
+ /**
25
+ * @deprecated Prefer {@link identityStore}. A raw `Storage` is wrapped by
26
+ * {@link createLocalStoragePsLiteRelayTlsIdentityStore}. Retained so existing
27
+ * browser callers keep their exact localStorage behavior.
28
+ */
29
+ storage?: Storage;
30
+ logger?: (line: string) => void;
31
+ /**
32
+ * Max time to wait on the relay's certificate endpoint before treating this
33
+ * attempt as failed and serving the self-signed fallback. A hung issuer
34
+ * (observed live, BUI-666: the endpoint accepts the POST and never responds)
35
+ * would otherwise leave the identity promise pending forever — and every
36
+ * incoming TLS handshake awaits that promise, so the public endpoint serves
37
+ * zero bytes while the control session looks healthy.
38
+ *
39
+ * Default 60s. This preserves the old per-session ACME margin and is still
40
+ * bounded for a truly wedged relay endpoint.
41
+ */
42
+ issueCertTimeoutMs?: number;
43
+ }
44
+ export interface PsLiteRelayTlsIdentity {
45
+ certPem: string;
46
+ keyPem: string;
47
+ hostname: string;
48
+ source: "acme" | "self-signed" | "cached-acme";
49
+ trusted: boolean;
50
+ }
51
+ export declare function createRustlsPsLiteRelayTlsFactory(options: RustlsPsLiteRelayTlsOptions): PsLiteRelayTlsFactory;
52
+ export declare function psLiteRelayPublicHost(sessionId: string, publicSuffix?: string): string;
53
+ export declare function psLiteRelayPublicUrl(sessionId: string, publicSuffix?: string): string;
54
+ /**
55
+ * Browser default relay TLS identity store: persists the issued cert in
56
+ * `localStorage`, matching PS Lite's pre-injection behavior byte for byte. This
57
+ * is the one place the relay TLS path is allowed to touch a browser global; the
58
+ * resolution logic above goes through the injected {@link PsLiteRelayTlsIdentityStore}.
59
+ */
60
+ export declare function createLocalStoragePsLiteRelayTlsIdentityStore(storage?: Storage): PsLiteRelayTlsIdentityStore;
61
+ //# sourceMappingURL=relay-tls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-tls.d.ts","sourceRoot":"","sources":["../src/relay-tls.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,qBAAqB,EAKtB,MAAM,YAAY,CAAC;AAMpB;;;;;;GAMG;AACH,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CACF,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,GAAG,sBAAsB,GAAG,IAAI,CAAC;IAC1E,KAAK,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,2BAA2B,CAAC;IAC5C;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa,CAAC;IAC/C,OAAO,EAAE,OAAO,CAAC;CAClB;AAID,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,2BAA2B,GACnC,qBAAqB,CA4EvB;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,YAAY,SAAwB,GACnC,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,YAAY,SAAwB,GACnC,MAAM,CAER;AA2PD;;;;;GAKG;AACH,wBAAgB,6CAA6C,CAC3D,OAAO,GAAE,OAAiC,GACzC,2BAA2B,CAa7B"}