@opendatalabs/personal-server-ts-lite 0.0.1-canary.01ca694 → 0.0.1-canary.052d47e

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 (44) hide show
  1. package/dist/browser-runtime.d.ts +26 -1
  2. package/dist/browser-runtime.d.ts.map +1 -1
  3. package/dist/browser-runtime.js +130 -26
  4. package/dist/browser-runtime.js.map +1 -1
  5. package/dist/client.d.ts.map +1 -1
  6. package/dist/client.js +40 -8
  7. package/dist/client.js.map +1 -1
  8. package/dist/derivatives.d.ts +51 -0
  9. package/dist/derivatives.d.ts.map +1 -0
  10. package/dist/derivatives.js +85 -0
  11. package/dist/derivatives.js.map +1 -0
  12. package/dist/index.d.ts +8 -5
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +8 -3
  15. package/dist/index.js.map +1 -1
  16. package/dist/persistence.d.ts +69 -0
  17. package/dist/persistence.d.ts.map +1 -0
  18. package/dist/persistence.js +58 -0
  19. package/dist/persistence.js.map +1 -0
  20. package/dist/relay-tls.d.ts +42 -0
  21. package/dist/relay-tls.d.ts.map +1 -1
  22. package/dist/relay-tls.js +176 -86
  23. package/dist/relay-tls.js.map +1 -1
  24. package/dist/relay.d.ts +83 -4
  25. package/dist/relay.d.ts.map +1 -1
  26. package/dist/relay.js +299 -21
  27. package/dist/relay.js.map +1 -1
  28. package/dist/runtime.d.ts +97 -4
  29. package/dist/runtime.d.ts.map +1 -1
  30. package/dist/runtime.js +208 -44
  31. package/dist/runtime.js.map +1 -1
  32. package/dist/state.d.ts +11 -1
  33. package/dist/state.d.ts.map +1 -1
  34. package/dist/state.js +77 -7
  35. package/dist/state.js.map +1 -1
  36. package/dist/storage.d.ts +6 -2
  37. package/dist/storage.d.ts.map +1 -1
  38. package/dist/storage.js +182 -39
  39. package/dist/storage.js.map +1 -1
  40. package/dist/sync.d.ts +23 -0
  41. package/dist/sync.d.ts.map +1 -1
  42. package/dist/sync.js +56 -6
  43. package/dist/sync.js.map +1 -1
  44. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"derivatives.js","sourceRoot":"","sources":["../src/derivatives.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,13 +3,16 @@ export { startPersonalServer, type StartPersonalServerLiteOptions, type StartPer
3
3
  export type { PersonalServerHandle, PersonalServerClientErrorBody, PersonalServerDataVersion, PersonalServerHealthRegistration, PersonalServerIdentity, PersonalServerInfo, PersonalServerAuthRequestOptions, PersonalServerListDataOptions, PersonalServerListDataResult, PersonalServerListVersionsOptions, PersonalServerListVersionsResult, PersonalServerReadDataOptions, PersonalServerRegistrationRequest, PersonalServerStatus, PersonalServerSyncTriggerResult, PersonalServerUrls, } from "@opendatalabs/personal-server-ts-core/client";
4
4
  export { PersonalServerClientError, dataListPath, dataReadPath, dataVersionsPath, parsePersonalServerJsonResponse, } from "@opendatalabs/personal-server-ts-core/client";
5
5
  export { handlePsLiteBridgeRequest, type PsLiteBridgeRequest, type PsLiteBridgeResponse, } from "./bridge.js";
6
- export { createIndexedDbPsLitePersistence, createOpfsPsLiteDataFileStore, createPersistentPsLiteStorage, isOpfsAvailable, type IndexedDbPsLitePersistenceOptions, type PsLiteDataFileStore, type PsLiteFileStorageKind, type PsLitePersistedStorageState, type PsLitePersistenceAdapter, } from "./storage.js";
6
+ export { createIndexedDbPsLitePersistence, createOpfsPsLiteDataFileStore, createPersistentPsLiteStorage, isOpfsAvailable, type IndexedDbPsLitePersistenceOptions, type PsLiteDataFileStore, type PsLiteFileStorageKind, type PsLitePersistedStorageState, type PsLitePersistenceAdapter, type PsLiteStorageCapabilities, type PsLiteStoragePort, } from "./storage.js";
7
7
  export { createIndexedDbPsLiteAccessLogStore, createIndexedDbPsLiteStateStore, createIndexedDbPsLiteTokenStore, loadOrCreatePsLiteConfig, loadOrCreatePsLiteServerIdentity, loadPsLiteRelayState, savePsLiteConfig, savePsLiteRelayState, type IndexedDbPsLiteAccessLogStoreOptions, type IndexedDbPsLiteStateStoreOptions, type IndexedDbPsLiteTokenStoreOptions, type PsLiteEncryptedPrivateKey, type PsLiteEncryptedServerIdentity, type PsLiteRelayState, type PsLiteStateKey, type PsLiteStateStore, type PsLiteUnlockedServerIdentity, } from "./state.js";
8
- export { createPsLiteSyncCursor, createPsLiteSyncManager, type PsLiteSyncOptions, } from "./sync.js";
8
+ export { createPsLitePendingBlobDeletionStore, createPsLiteSyncCursor, createPsLiteSyncManager, type PsLiteSyncOptions, } from "./sync.js";
9
9
  export { resolvePsLiteOwner, type PsLiteOwnerBindingInput, } from "./owner-binding.js";
10
- export { createBearerTokenPsLiteAuth, createPsLiteRuntime, createWeb3SignedPsLiteAuth, type BearerTokenPsLiteAuthOptions, type PsLiteAuthAdapter, type PsLiteReadAuthInput, type PsLiteRuntime, type PsLiteRuntimeOptions, type PsLiteStorageAdapter, type PsLiteTokenStore, type Web3SignedPsLiteAuthOptions, } from "./runtime.js";
10
+ export { createPsLiteDerivativeCompute, createPsLiteQuestionStore, psLiteInferenceConfigured, type PsLiteDerivativeCompute, type PsLiteDerivativeComputeOptions, } from "./derivatives.js";
11
+ export { createBearerTokenPsLiteAuth, createPsLiteRuntime, createWeb3SignedPsLiteAuth, type BearerTokenPsLiteAuthOptions, type PsLiteAuthAdapter, type PsLiteReadAuthInput, type PsLiteRuntime, type PsLiteRuntimeOptions, type PsLiteStorageAdapter, type PsLiteTokenStore, type PsLiteWriteSessionAuthOptions, type Web3SignedPsLiteAuthOptions, } from "./runtime.js";
12
+ export { createInMemoryWriteProofReplayStore, createInMemoryWriteSessionStore, hashWriteSessionToken, verifyStoredWriterAttribution, WRITE_SIGNATURE_HEADER, WRITER_ATTRIBUTION_KEY, type WriteProofReplayStore, type WriteSessionRecord, type WriteSessionStore, } from "@opendatalabs/personal-server-ts-core/write";
11
13
  export { createIndexedDbMcpConnectionStore, createIndexedDbMcpOAuthAuthorizationStore, type IndexedDbMcpConnectionStoreOptions, type IndexedDbMcpOAuthAuthorizationStoreOptions, } from "./mcp-store.js";
12
14
  export { DiagnosticsRecorder, collectDiagnosticsWithTimeout, DIAGNOSTICS_VERSION, type ActiveOperation, type DiagnosticsEvent, type DiagnosticsPhase, type LastNetworkOperation, type PsLiteDiagnosticsSnapshot, type RecordEventOptions, type ScopeDiagnostics, type ScopeReadinessStatus, type StorageHealthSummary, type SyncDiagnostics, } from "./diagnostics.js";
13
- export { decodeDataFrame, encodeDataFrame, psLiteRelayControlUrl, psLiteRelayPublicUrl, startPsLiteRelayClient, type PsLiteRelayClient, type PsLiteRelayClientOptions, type PsLiteRelayStatus, type PsLiteRelayTlsFactory, type PsLiteRelayTlsPrepareInput, type PsLiteRelayTlsStep, type PsLiteRelayTlsStream, type PsLiteRelayTlsStreamInput, type PsLiteRelayWebSocket, type PsLiteRelayWebSocketFactory, } from "./relay.js";
14
- export { createRustlsPsLiteRelayTlsFactory, psLiteRelayPublicHost, psLiteRelayPublicUrl as psLiteRelayTlsPublicUrl, type PsLiteRelayTlsIdentity, type RustlsPsLiteRelayTlsOptions, } from "./relay-tls.js";
15
+ export { decodeDataFrame, encodeDataFrame, psLiteRelayControlUrl, psLiteRelayPublicUrl, RELAY_CLOSE_SESSION_REPLACED, startPsLiteRelayClient, type PsLiteRelayClient, type PsLiteRelayClientOptions, type PsLiteRelayCloseEvent, type PsLiteRelayStatus, type PsLiteRelayTlsFactory, type PsLiteRelayTlsPrepareInput, type PsLiteRelayTlsStep, type PsLiteRelayTlsStream, type PsLiteRelayTlsStreamInput, type PsLiteRelayWebSocket, type PsLiteRelayWebSocketFactory, } from "./relay.js";
16
+ export { createLocalStoragePsLiteRelayTlsIdentityStore, createRustlsPsLiteRelayTlsFactory, psLiteRelayPublicHost, psLiteRelayPublicUrl as psLiteRelayTlsPublicUrl, type PsLiteRelayTlsIdentity, type PsLiteRelayTlsIdentityStore, type RustlsPsLiteRelayTlsOptions, } from "./relay-tls.js";
17
+ export { assertCompletePsLitePersistenceBundle, psLitePersistenceRuntimeOptions, type PsLitePersistenceBundle, type PsLitePersistenceRuntimeOptions, } from "./persistence.js";
15
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,11 +4,16 @@ export { PersonalServerClientError, dataListPath, dataReadPath, dataVersionsPath
4
4
  export { handlePsLiteBridgeRequest, } from "./bridge.js";
5
5
  export { createIndexedDbPsLitePersistence, createOpfsPsLiteDataFileStore, createPersistentPsLiteStorage, isOpfsAvailable, } from "./storage.js";
6
6
  export { createIndexedDbPsLiteAccessLogStore, createIndexedDbPsLiteStateStore, createIndexedDbPsLiteTokenStore, loadOrCreatePsLiteConfig, loadOrCreatePsLiteServerIdentity, loadPsLiteRelayState, savePsLiteConfig, savePsLiteRelayState, } from "./state.js";
7
- export { createPsLiteSyncCursor, createPsLiteSyncManager, } from "./sync.js";
7
+ export { createPsLitePendingBlobDeletionStore, createPsLiteSyncCursor, createPsLiteSyncManager, } from "./sync.js";
8
8
  export { resolvePsLiteOwner, } from "./owner-binding.js";
9
+ export { createPsLiteDerivativeCompute, createPsLiteQuestionStore, psLiteInferenceConfigured, } from "./derivatives.js";
9
10
  export { createBearerTokenPsLiteAuth, createPsLiteRuntime, createWeb3SignedPsLiteAuth, } from "./runtime.js";
11
+ // Delegated builder writes: hosts that build their own auth adapter (or want
12
+ // one store shared across several runtimes) wire these themselves.
13
+ export { createInMemoryWriteProofReplayStore, createInMemoryWriteSessionStore, hashWriteSessionToken, verifyStoredWriterAttribution, WRITE_SIGNATURE_HEADER, WRITER_ATTRIBUTION_KEY, } from "@opendatalabs/personal-server-ts-core/write";
10
14
  export { createIndexedDbMcpConnectionStore, createIndexedDbMcpOAuthAuthorizationStore, } from "./mcp-store.js";
11
15
  export { DiagnosticsRecorder, collectDiagnosticsWithTimeout, DIAGNOSTICS_VERSION, } from "./diagnostics.js";
12
- export { decodeDataFrame, encodeDataFrame, psLiteRelayControlUrl, psLiteRelayPublicUrl, startPsLiteRelayClient, } from "./relay.js";
13
- export { createRustlsPsLiteRelayTlsFactory, psLiteRelayPublicHost, psLiteRelayPublicUrl as psLiteRelayTlsPublicUrl, } from "./relay-tls.js";
16
+ export { decodeDataFrame, encodeDataFrame, psLiteRelayControlUrl, psLiteRelayPublicUrl, RELAY_CLOSE_SESSION_REPLACED, startPsLiteRelayClient, } from "./relay.js";
17
+ export { createLocalStoragePsLiteRelayTlsIdentityStore, createRustlsPsLiteRelayTlsFactory, psLiteRelayPublicHost, psLiteRelayPublicUrl as psLiteRelayTlsPublicUrl, } from "./relay-tls.js";
18
+ export { assertCompletePsLitePersistenceBundle, psLitePersistenceRuntimeOptions, } from "./persistence.js";
14
19
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,GAG7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAmBrB,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,yBAAyB,GAG1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,6BAA6B,EAC7B,eAAe,GAMhB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mCAAmC,EACnC,+BAA+B,EAC/B,+BAA+B,EAC/B,wBAAwB,EACxB,gCAAgC,EAChC,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,GAUrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,sBAAsB,EACtB,uBAAuB,GAExB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,GAS3B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,iCAAiC,EACjC,yCAAyC,GAG1C,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,GAWpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,GAWvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iCAAiC,EACjC,qBAAqB,EACrB,oBAAoB,IAAI,uBAAuB,GAGhD,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,GAG7B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAmBrB,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,8CAA8C,CAAC;AAEtD,OAAO,EACL,yBAAyB,GAG1B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gCAAgC,EAChC,6BAA6B,EAC7B,6BAA6B,EAC7B,eAAe,GAQhB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mCAAmC,EACnC,+BAA+B,EAC/B,+BAA+B,EAC/B,wBAAwB,EACxB,gCAAgC,EAChC,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,GAUrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,oCAAoC,EACpC,sBAAsB,EACtB,uBAAuB,GAExB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,kBAAkB,GAEnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,GAG1B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,EACnB,0BAA0B,GAU3B,MAAM,cAAc,CAAC;AAEtB,6EAA6E;AAC7E,mEAAmE;AACnE,OAAO,EACL,mCAAmC,EACnC,+BAA+B,EAC/B,qBAAqB,EACrB,6BAA6B,EAC7B,sBAAsB,EACtB,sBAAsB,GAIvB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACL,iCAAiC,EACjC,yCAAyC,GAG1C,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,GAWpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,GAYvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,6CAA6C,EAC7C,iCAAiC,EACjC,qBAAqB,EACrB,oBAAoB,IAAI,uBAAuB,GAIhD,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,qCAAqC,EACrC,+BAA+B,GAGhC,MAAM,kBAAkB,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"}
@@ -1,10 +1,45 @@
1
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
+ }
2
13
  export interface RustlsPsLiteRelayTlsOptions {
3
14
  controlUrl: string;
4
15
  publicSuffix?: string;
5
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
+ */
6
29
  storage?: Storage;
7
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;
8
43
  }
9
44
  export interface PsLiteRelayTlsIdentity {
10
45
  certPem: string;
@@ -16,4 +51,11 @@ export interface PsLiteRelayTlsIdentity {
16
51
  export declare function createRustlsPsLiteRelayTlsFactory(options: RustlsPsLiteRelayTlsOptions): PsLiteRelayTlsFactory;
17
52
  export declare function psLiteRelayPublicHost(sessionId: string, publicSuffix?: string): string;
18
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;
19
61
  //# sourceMappingURL=relay-tls.d.ts.map
@@ -1 +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;AAKpB,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;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,CAgBvB;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"}
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"}
package/dist/relay-tls.js CHANGED
@@ -2,18 +2,71 @@ import forge from "node-forge";
2
2
  import initRustls, { TlsServer as RustlsServer, } from "./browser-tls-rustls/browser_tls_rustls.js";
3
3
  const TLS_IDENTITY_CACHE_KEY = "personal-server-lite-tls-identity-v1";
4
4
  const DEFAULT_PUBLIC_SUFFIX = "34.16.49.200.sslip.io";
5
+ const DEFAULT_ISSUE_CERT_TIMEOUT_MS = 60_000;
5
6
  let rustlsInitPromise;
6
7
  export function createRustlsPsLiteRelayTlsFactory(options) {
7
- let identityPromise;
8
+ // Only a trusted relay identity is memoized for the factory's lifetime. A
9
+ // self-signed fallback must NOT be: it means issuance failed on this attempt
10
+ // (no issueToken yet, certificate endpoint error/timeout), and locking it in
11
+ // would strand the tab on an untrusted cert forever — even after a reconnect
12
+ // delivers a fresh issueToken (BUI-664). The relay factory outlives every
13
+ // reconnect, so a first-attempt fallback used to pin the whole session to
14
+ // self-signed. Leaving it unmemoized lets the next prepare/createStream retry
15
+ // issuance (or hit the persisted certificate cache once it succeeds).
16
+ let trustedIdentity;
17
+ let inFlight;
18
+ let inFlightToken;
19
+ // Do not create the browser default here: merely composing a relay factory
20
+ // must remain safe in a native/SSR host that has not injected localStorage.
21
+ // The default adapter is resolved only when a relay actually prepares TLS.
22
+ const identityStore = options.identityStore ??
23
+ (options.storage
24
+ ? createLocalStoragePsLiteRelayTlsIdentityStore(options.storage)
25
+ : undefined);
26
+ async function resolveIdentity(input) {
27
+ if (trustedIdentity) {
28
+ return trustedIdentity;
29
+ }
30
+ // Coalesce concurrent callers onto one attempt, but clear on settle so a
31
+ // failed (self-signed) attempt doesn't block the next retry. A caller that
32
+ // brings a fresh issueToken must NOT join an in-flight attempt made with
33
+ // different (or no) credentials: that attempt can settle self-signed even
34
+ // though this caller could mint a trusted cert, and the first strict-TLS
35
+ // stream after recovery would still get the untrusted identity. Such a
36
+ // caller starts its own attempt; the superseded one settles harmlessly.
37
+ const token = input.issueToken ?? "";
38
+ if (!inFlight || (token && token !== inFlightToken)) {
39
+ const attempt = createTlsIdentity(input, options, identityStore ?? createLocalStoragePsLiteRelayTlsIdentityStore()).finally(() => {
40
+ if (inFlight === attempt) {
41
+ inFlight = undefined;
42
+ inFlightToken = undefined;
43
+ }
44
+ });
45
+ inFlight = attempt;
46
+ inFlightToken = token;
47
+ }
48
+ const identity = await inFlight;
49
+ if (identity.trusted) {
50
+ trustedIdentity = identity;
51
+ }
52
+ else if (trustedIdentity) {
53
+ // A concurrent tokened attempt settled trusted while this caller was
54
+ // awaiting a fallback attempt — serve the trusted identity instead of
55
+ // handing one last stream a self-signed cert.
56
+ return trustedIdentity;
57
+ }
58
+ else {
59
+ options.logger?.(`serving self-signed cert for ${identity.hostname}; relay certificate unavailable this attempt, will retry on the next stream/reconnect`);
60
+ }
61
+ return identity;
62
+ }
8
63
  return {
9
64
  async prepare(input) {
10
- identityPromise ??= createTlsIdentity(input, options);
11
- await identityPromise;
65
+ await resolveIdentity(input);
12
66
  },
13
67
  async createStream(input) {
14
68
  await ensureRustls();
15
- identityPromise ??= createTlsIdentity(input, options);
16
- const identity = await identityPromise;
69
+ const identity = await resolveIdentity(input);
17
70
  const tls = new RustlsServer(identity.certPem, identity.keyPem);
18
71
  return createRustlsStream(tls);
19
72
  },
@@ -50,28 +103,33 @@ function normalizeTlsStep(value) {
50
103
  handshaking: Boolean(step.handshaking),
51
104
  };
52
105
  }
53
- async function createTlsIdentity(input, options) {
106
+ async function createTlsIdentity(input, options, identityStore) {
54
107
  const hostname = psLiteRelayPublicHost(input.sessionId, options.publicSuffix);
55
- const cached = readCachedTlsIdentity(hostname, options.storage);
108
+ const cached = await readCachedTlsIdentity(hostname, identityStore);
56
109
  if (cached) {
57
110
  return cached;
58
111
  }
59
- const keys = await generateKeyPair();
60
- const keyPem = forge.pki.privateKeyToPem(keys.privateKey);
61
- const csrPem = createCsrPem(hostname, keys);
62
- const issued = await requestAcmeCertificate({
63
- issuerUrl: resolveCertIssuerUrl(options),
112
+ // Fetch the relay's shared wildcard cert+key for this session (POST
113
+ // /session-cert). This replaces per-session ACME: the relay issues one
114
+ // `*.<suffix>` cert and hands it to every session, so there is no per-session
115
+ // DNS-01 challenge, no TXT-propagation race, and no Let's Encrypt rate-limit
116
+ // exposure. The wildcard SAN covers our `<sessionId>.<suffix>` hostname.
117
+ const wildcard = await requestSessionCertificate({
118
+ issuerUrl: resolveSessionCertUrl(options),
64
119
  sessionId: input.sessionId,
65
- csrPem,
66
- keyPem,
67
120
  issueToken: input.issueToken ?? "",
68
121
  hostname,
69
- storage: options.storage,
122
+ identityStore,
70
123
  logger: options.logger,
124
+ timeoutMs: options.issueCertTimeoutMs ?? DEFAULT_ISSUE_CERT_TIMEOUT_MS,
71
125
  });
72
- if (issued) {
73
- return issued;
126
+ if (wildcard) {
127
+ return wildcard;
74
128
  }
129
+ // Unmemoized self-signed fallback (BUI-664): the relay was unreachable or the
130
+ // wildcard was unavailable this attempt; retry issuance on the next stream.
131
+ const keys = await generateKeyPair();
132
+ const keyPem = forge.pki.privateKeyToPem(keys.privateKey);
75
133
  return createSelfSignedIdentity(hostname, keyPem, keys);
76
134
  }
77
135
  function generateKeyPair() {
@@ -85,24 +143,6 @@ function generateKeyPair() {
85
143
  });
86
144
  });
87
145
  }
88
- function createCsrPem(hostname, keys) {
89
- const csr = forge.pki.createCertificationRequest();
90
- csr.publicKey = keys.publicKey;
91
- csr.setSubject([{ name: "commonName", value: hostname }]);
92
- csr.setAttributes([
93
- {
94
- name: "extensionRequest",
95
- extensions: [
96
- {
97
- name: "subjectAltName",
98
- altNames: [{ type: 2, value: hostname }],
99
- },
100
- ],
101
- },
102
- ]);
103
- csr.sign(keys.privateKey, forge.md.sha256.create());
104
- return forge.pki.certificationRequestToPem(csr);
105
- }
106
146
  function createSelfSignedIdentity(hostname, keyPem, keys) {
107
147
  const cert = forge.pki.createCertificate();
108
148
  cert.publicKey = keys.publicKey;
@@ -130,67 +170,117 @@ function createSelfSignedIdentity(hostname, keyPem, keys) {
130
170
  trusted: false,
131
171
  };
132
172
  }
133
- async function requestAcmeCertificate(input) {
173
+ function issueCertAbortSignal(timeoutMs) {
174
+ return typeof AbortSignal !== "undefined" &&
175
+ typeof AbortSignal.timeout === "function"
176
+ ? AbortSignal.timeout(timeoutMs)
177
+ : undefined;
178
+ }
179
+ function withIssueCertTimeout(promise, timeoutMs) {
180
+ return new Promise((resolve, reject) => {
181
+ const timer = setTimeout(() => {
182
+ reject(new Error(`certificate issuer did not respond within ${timeoutMs}ms`));
183
+ }, timeoutMs);
184
+ promise.then((value) => {
185
+ clearTimeout(timer);
186
+ resolve(value);
187
+ }, (error) => {
188
+ clearTimeout(timer);
189
+ reject(error);
190
+ });
191
+ });
192
+ }
193
+ function resolveSessionCertUrl(options) {
194
+ const base = options.certIssuerUrl
195
+ ? options.certIssuerUrl.replace(/\/+$/, "").replace(/\/issue-cert$/, "")
196
+ : (() => {
197
+ const url = new URL(options.controlUrl);
198
+ url.protocol = url.protocol === "wss:" ? "https:" : "http:";
199
+ url.pathname = "";
200
+ url.search = "";
201
+ url.hash = "";
202
+ return url.toString().replace(/\/+$/, "");
203
+ })();
204
+ return `${base}/session-cert`;
205
+ }
206
+ /**
207
+ * Fetch the relay's shared wildcard cert+key for this browser session. Unlike
208
+ * the per-session ACME path, the relay already holds the cert, so this is a
209
+ * fast lookup with no DNS challenge. Returns undefined (self-signed fallback)
210
+ * on any failure.
211
+ */
212
+ async function requestSessionCertificate(input) {
134
213
  if (!input.issueToken) {
135
- input.logger?.("ACME issuer token unavailable; using self-signed certificate");
214
+ input.logger?.("session issue token unavailable; using self-signed certificate");
136
215
  return undefined;
137
216
  }
138
217
  try {
139
- const response = await fetch(input.issuerUrl, {
140
- method: "POST",
141
- headers: { "content-type": "application/json" },
142
- body: JSON.stringify({
143
- sessionId: input.sessionId,
144
- csrPem: input.csrPem,
145
- issueToken: input.issueToken,
146
- }),
147
- });
148
- if (!response.ok) {
149
- const detail = await response.text();
150
- input.logger?.(`ACME issuer unavailable (${response.status}); using self-signed certificate`);
151
- input.logger?.(detail.slice(0, 240));
152
- return undefined;
153
- }
154
- const payload = (await response.json());
155
- if (!payload.certPem) {
156
- input.logger?.("ACME issuer returned no certificate; using self-signed certificate");
157
- return undefined;
158
- }
159
- const identity = {
160
- certPem: payload.certPem,
161
- keyPem: input.keyPem,
162
- hostname: input.hostname,
163
- source: "acme",
164
- trusted: true,
165
- };
166
- cacheTlsIdentity(identity, input.storage);
167
- return identity;
218
+ return await withIssueCertTimeout(fetchSessionCert(input), input.timeoutMs);
168
219
  }
169
220
  catch (error) {
170
221
  input.logger?.(error instanceof Error ? error.message : String(error));
171
- input.logger?.("ACME certificate request failed; using self-signed certificate");
222
+ input.logger?.("session certificate request failed; using self-signed certificate");
172
223
  return undefined;
173
224
  }
174
225
  }
175
- function resolveCertIssuerUrl(options) {
176
- if (options.certIssuerUrl) {
177
- return options.certIssuerUrl.replace(/\/+$/, "");
226
+ async function fetchSessionCert(input) {
227
+ const response = await fetch(input.issuerUrl, {
228
+ method: "POST",
229
+ headers: { "content-type": "application/json" },
230
+ body: JSON.stringify({
231
+ sessionId: input.sessionId,
232
+ issueToken: input.issueToken,
233
+ }),
234
+ signal: issueCertAbortSignal(input.timeoutMs),
235
+ });
236
+ if (!response.ok) {
237
+ const detail = await response.text();
238
+ input.logger?.(`session-cert unavailable (${response.status}); using self-signed certificate`);
239
+ input.logger?.(detail.slice(0, 240));
240
+ return undefined;
241
+ }
242
+ const payload = (await response.json());
243
+ if (!payload.certPem || !payload.keyPem) {
244
+ input.logger?.("session-cert returned no certificate; using self-signed certificate");
245
+ return undefined;
178
246
  }
179
- const url = new URL(options.controlUrl);
180
- url.protocol = url.protocol === "wss:" ? "https:" : "http:";
181
- url.pathname = "/issue-cert";
182
- url.search = "";
183
- url.hash = "";
184
- return url.toString();
185
- }
186
- function readCachedTlsIdentity(hostname, storage = globalThis.localStorage) {
247
+ const identity = {
248
+ certPem: payload.certPem,
249
+ keyPem: payload.keyPem,
250
+ hostname: input.hostname,
251
+ source: "acme",
252
+ trusted: true,
253
+ };
187
254
  try {
188
- const raw = storage.getItem(`${TLS_IDENTITY_CACHE_KEY}:${hostname}`);
189
- if (!raw) {
190
- return undefined;
191
- }
192
- const identity = JSON.parse(raw);
193
- if (identity.hostname !== hostname ||
255
+ await cacheTlsIdentity(identity, input.identityStore);
256
+ }
257
+ catch (error) {
258
+ input.logger?.(`failed to persist session certificate (${error instanceof Error ? error.message : String(error)}); continuing with the in-memory identity`);
259
+ }
260
+ return identity;
261
+ }
262
+ /**
263
+ * Browser default relay TLS identity store: persists the issued cert in
264
+ * `localStorage`, matching PS Lite's pre-injection behavior byte for byte. This
265
+ * is the one place the relay TLS path is allowed to touch a browser global; the
266
+ * resolution logic above goes through the injected {@link PsLiteRelayTlsIdentityStore}.
267
+ */
268
+ export function createLocalStoragePsLiteRelayTlsIdentityStore(storage = globalThis.localStorage) {
269
+ return {
270
+ read(hostname) {
271
+ const raw = storage.getItem(`${TLS_IDENTITY_CACHE_KEY}:${hostname}`);
272
+ return raw ? JSON.parse(raw) : null;
273
+ },
274
+ write(identity) {
275
+ storage.setItem(`${TLS_IDENTITY_CACHE_KEY}:${identity.hostname}`, JSON.stringify(identity));
276
+ },
277
+ };
278
+ }
279
+ async function readCachedTlsIdentity(hostname, identityStore) {
280
+ try {
281
+ const identity = await identityStore.read(hostname);
282
+ if (!identity ||
283
+ identity.hostname !== hostname ||
194
284
  !identity.certPem ||
195
285
  !identity.keyPem ||
196
286
  identity.source !== "acme") {
@@ -210,11 +300,11 @@ function readCachedTlsIdentity(hostname, storage = globalThis.localStorage) {
210
300
  return undefined;
211
301
  }
212
302
  }
213
- function cacheTlsIdentity(identity, storage = globalThis.localStorage) {
303
+ async function cacheTlsIdentity(identity, identityStore) {
214
304
  if (identity.source !== "acme") {
215
305
  return;
216
306
  }
217
- storage.setItem(`${TLS_IDENTITY_CACHE_KEY}:${identity.hostname}`, JSON.stringify(identity));
307
+ await identityStore.write(identity);
218
308
  }
219
309
  function firstCertificateNotAfter(certPem) {
220
310
  const match = certPem.match(/-----BEGIN CERTIFICATE-----[\s\S]+?-----END CERTIFICATE-----/);