@econ-v1/ports 6.7.0 → 6.10.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/app-data.d.ts +39 -0
- package/dist/app-data.d.ts.map +1 -0
- package/dist/client-ui-preference.d.ts +23 -0
- package/dist/client-ui-preference.d.ts.map +1 -0
- package/dist/clipboard.d.ts +41 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clock.d.ts +8 -8
- package/dist/clock.d.ts.map +1 -1
- package/dist/credential-handoff.d.ts +57 -0
- package/dist/credential-handoff.d.ts.map +1 -0
- package/dist/crypto.d.ts +4 -4
- package/dist/crypto.d.ts.map +1 -1
- package/dist/id.d.ts +2 -2
- package/dist/id.d.ts.map +1 -1
- package/dist/identity.d.ts +31 -25
- package/dist/identity.d.ts.map +1 -1
- package/dist/index.d.ts +226 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/install-environment.d.ts +22 -32
- package/dist/install-environment.d.ts.map +1 -1
- package/dist/lcd-tree-source.d.ts +54 -0
- package/dist/lcd-tree-source.d.ts.map +1 -0
- package/dist/legacy-credential.d.ts +30 -0
- package/dist/legacy-credential.d.ts.map +1 -0
- package/dist/media-preferences.d.ts +2 -44
- package/dist/media-preferences.d.ts.map +1 -1
- package/dist/network/certificate-trust.d.ts +31 -0
- package/dist/network/certificate-trust.d.ts.map +1 -0
- package/dist/network/client-node-origin.d.ts +3 -15
- package/dist/network/client-node-origin.d.ts.map +1 -1
- package/dist/network/home-node-candidate-store.d.ts +4 -32
- package/dist/network/home-node-candidate-store.d.ts.map +1 -1
- package/dist/network/home-node-candidate.d.ts +9 -7
- package/dist/network/home-node-candidate.d.ts.map +1 -1
- package/dist/network/l402-payment.d.ts +11 -28
- package/dist/network/l402-payment.d.ts.map +1 -1
- package/dist/network/node-discovery.d.ts +5 -16
- package/dist/network/node-discovery.d.ts.map +1 -1
- package/dist/network/webrtc-signaling.d.ts +36 -52
- package/dist/network/webrtc-signaling.d.ts.map +1 -1
- package/dist/network.d.ts +65 -40
- package/dist/network.d.ts.map +1 -1
- package/dist/offline-readiness.d.ts +122 -0
- package/dist/offline-readiness.d.ts.map +1 -0
- package/dist/onboarding-access-code.d.ts +30 -0
- package/dist/onboarding-access-code.d.ts.map +1 -0
- package/dist/onboarding-checkpoint.d.ts +26 -0
- package/dist/onboarding-checkpoint.d.ts.map +1 -0
- package/dist/onboarding-presence.d.ts +12 -0
- package/dist/onboarding-presence.d.ts.map +1 -0
- package/dist/owner-claim-session.d.ts +60 -0
- package/dist/owner-claim-session.d.ts.map +1 -0
- package/dist/owner-claim.d.ts +22 -0
- package/dist/owner-claim.d.ts.map +1 -0
- package/dist/repositories/conversation-repository.d.ts +21 -20
- package/dist/repositories/conversation-repository.d.ts.map +1 -1
- package/dist/repositories/durable-event.d.ts +8 -8
- package/dist/repositories/durable-event.d.ts.map +1 -1
- package/dist/repositories/node-app-memory-repository.d.ts +168 -0
- package/dist/repositories/node-app-memory-repository.d.ts.map +1 -0
- package/dist/repositories/outbox.d.ts +33 -20
- package/dist/repositories/outbox.d.ts.map +1 -1
- package/dist/repositories/repository-mutation.d.ts +3 -1
- package/dist/repositories/repository-mutation.d.ts.map +1 -1
- package/dist/repositories/revisioned-repository.d.ts +14 -12
- package/dist/repositories/revisioned-repository.d.ts.map +1 -1
- package/dist/repositories/settings.d.ts +10 -10
- package/dist/repositories/settings.d.ts.map +1 -1
- package/dist/repositories/sync-ledger.d.ts +11 -11
- package/dist/repositories/sync-ledger.d.ts.map +1 -1
- package/dist/repositories/wallet-mirror-repository.d.ts +22 -13
- package/dist/repositories/wallet-mirror-repository.d.ts.map +1 -1
- package/dist/repositories.d.ts +52 -17
- package/dist/repositories.d.ts.map +1 -1
- package/dist/scheduler.d.ts +4 -4
- package/dist/scheduler.d.ts.map +1 -1
- package/dist/session-flag.d.ts +48 -0
- package/dist/session-flag.d.ts.map +1 -0
- package/dist/shell-cache-reset.d.ts +4 -0
- package/dist/shell-cache-reset.d.ts.map +1 -0
- package/dist/shell-version.d.ts +8 -0
- package/dist/shell-version.d.ts.map +1 -0
- package/dist/storage.d.ts +76 -34
- package/dist/storage.d.ts.map +1 -1
- package/dist/theme.d.ts +2 -24
- package/dist/theme.d.ts.map +1 -1
- package/package.json +14 -10
- package/src/app-data.js +42 -0
- package/src/client-ui-preference.js +23 -0
- package/src/clipboard.js +41 -0
- package/src/clock.js +13 -0
- package/src/credential-handoff.js +68 -0
- package/src/crypto.js +9 -0
- package/src/id.js +5 -0
- package/src/identity.js +33 -0
- package/src/index.js +250 -0
- package/src/install-environment.js +44 -0
- package/src/lcd-tree-source.js +56 -0
- package/src/legacy-credential.js +30 -0
- package/src/media-preferences.js +40 -0
- package/src/network/certificate-trust.js +25 -0
- package/src/network/client-node-origin.js +7 -0
- package/src/network/home-node-candidate-store.js +6 -0
- package/src/network/home-node-candidate.js +9 -0
- package/src/network/l402-payment.js +20 -0
- package/src/network/node-discovery.js +13 -0
- package/src/network/webrtc-signaling.js +40 -0
- package/src/network.js +33 -0
- package/src/offline-readiness.js +65 -0
- package/src/onboarding-access-code.js +21 -0
- package/src/onboarding-checkpoint.js +26 -0
- package/src/onboarding-presence.js +15 -0
- package/src/owner-claim-session.js +55 -0
- package/src/owner-claim.js +22 -0
- package/src/repositories/conversation-repository.js +20 -0
- package/src/repositories/durable-event.js +8 -0
- package/src/repositories/node-app-memory-repository.js +221 -0
- package/src/repositories/outbox.js +27 -0
- package/src/repositories/repository-mutation.js +8 -0
- package/src/repositories/revisioned-repository.js +17 -0
- package/src/repositories/settings.js +10 -0
- package/src/repositories/sync-ledger.js +11 -0
- package/src/repositories/wallet-mirror-repository.js +73 -0
- package/src/repositories.js +22 -0
- package/src/scheduler.js +6 -0
- package/src/session-flag.js +48 -0
- package/src/shell-cache-reset.js +3 -0
- package/src/shell-version.js +4 -0
- package/src/storage.js +60 -0
- package/src/theme.js +21 -0
- package/dist/clock.js +0 -2
- package/dist/clock.js.map +0 -1
- package/dist/crypto.js +0 -2
- package/dist/crypto.js.map +0 -1
- package/dist/id.js +0 -2
- package/dist/id.js.map +0 -1
- package/dist/identity.js +0 -2
- package/dist/identity.js.map +0 -1
- package/dist/index.js +0 -9
- package/dist/index.js.map +0 -1
- package/dist/install-environment.js +0 -26
- package/dist/install-environment.js.map +0 -1
- package/dist/media-preferences.js +0 -2
- package/dist/media-preferences.js.map +0 -1
- package/dist/network/client-node-origin.js +0 -18
- package/dist/network/client-node-origin.js.map +0 -1
- package/dist/network/home-node-candidate-store.js +0 -2
- package/dist/network/home-node-candidate-store.js.map +0 -1
- package/dist/network/home-node-candidate.js +0 -2
- package/dist/network/home-node-candidate.js.map +0 -1
- package/dist/network/l402-payment.js +0 -2
- package/dist/network/l402-payment.js.map +0 -1
- package/dist/network/node-discovery.js +0 -13
- package/dist/network/node-discovery.js.map +0 -1
- package/dist/network/webrtc-signaling.js +0 -30
- package/dist/network/webrtc-signaling.js.map +0 -1
- package/dist/network.js +0 -2
- package/dist/network.js.map +0 -1
- package/dist/repositories/conversation-repository.js +0 -2
- package/dist/repositories/conversation-repository.js.map +0 -1
- package/dist/repositories/durable-event.js +0 -2
- package/dist/repositories/durable-event.js.map +0 -1
- package/dist/repositories/outbox.js +0 -9
- package/dist/repositories/outbox.js.map +0 -1
- package/dist/repositories/repository-mutation.js +0 -2
- package/dist/repositories/repository-mutation.js.map +0 -1
- package/dist/repositories/revisioned-repository.js +0 -2
- package/dist/repositories/revisioned-repository.js.map +0 -1
- package/dist/repositories/settings.js +0 -2
- package/dist/repositories/settings.js.map +0 -1
- package/dist/repositories/sync-ledger.js +0 -2
- package/dist/repositories/sync-ledger.js.map +0 -1
- package/dist/repositories/wallet-mirror-repository.js +0 -53
- package/dist/repositories/wallet-mirror-repository.js.map +0 -1
- package/dist/repositories.js +0 -2
- package/dist/repositories.js.map +0 -1
- package/dist/scheduler.js +0 -2
- package/dist/scheduler.js.map +0 -1
- package/dist/storage.js +0 -14
- package/dist/storage.js.map +0 -1
- package/dist/theme.js +0 -2
- package/dist/theme.js.map +0 -1
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
export {};
|
|
3
|
+
/** @typedef {"local" | "registry" | "upload"} NodeAppInstallSource */
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {| "aggregate_shared_host"
|
|
6
|
+
* | "exact_cgroup"
|
|
7
|
+
* | "exact_isolate"
|
|
8
|
+
* | "exact_process"
|
|
9
|
+
* | "mapped_partial"
|
|
10
|
+
* | "self_reported"
|
|
11
|
+
* | "unavailable"} NodeAppMemoryAttribution
|
|
12
|
+
*/
|
|
13
|
+
/** @typedef {"measured" | "stale" | "unavailable"} NodeAppMemoryAvailability */
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {| "bun_heap_self_report"
|
|
16
|
+
* | "cgroup_v2"
|
|
17
|
+
* | "main_pid_smaps_rollup"
|
|
18
|
+
* | "main_pid_status_vm_rss"
|
|
19
|
+
* | "proc_smaps_mappings"
|
|
20
|
+
* | "proc_smaps_rollup"
|
|
21
|
+
* | "shared_host_residual"} NodeAppMemorySource
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* @typedef {| "cgroup_unavailable"
|
|
25
|
+
* | "non_linux"
|
|
26
|
+
* | "not_attributable"
|
|
27
|
+
* | "not_sampled"
|
|
28
|
+
* | "permission_denied"
|
|
29
|
+
* | "proc_unavailable"
|
|
30
|
+
* | "process_not_running"
|
|
31
|
+
* | "systemd_unavailable"} NodeAppMemoryUnavailableReason
|
|
32
|
+
*/
|
|
33
|
+
/** @typedef {"dedicated" | "shared"} NodeAppRuntimeMode */
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {| "active"
|
|
36
|
+
* | "consent_required"
|
|
37
|
+
* | "degraded"
|
|
38
|
+
* | "error"
|
|
39
|
+
* | "installed"
|
|
40
|
+
* | "lazy"
|
|
41
|
+
* | "restarting"
|
|
42
|
+
* | "stopped"} NodeAppStatus
|
|
43
|
+
*/
|
|
44
|
+
/** @typedef {"bun" | "native"} NodeAppType */
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {object} NodeAppMemoryReading
|
|
47
|
+
* @property {NodeAppMemoryAttribution} attribution
|
|
48
|
+
* @property {NodeAppMemoryAvailability} availability
|
|
49
|
+
* @property {string} observedAt
|
|
50
|
+
* @property {NodeAppMemoryUnavailableReason} [reason]
|
|
51
|
+
* @property {NodeAppMemorySource} source
|
|
52
|
+
* @property {number | null} valueKb
|
|
53
|
+
*/
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {object} NodeAppMemorySnapshot
|
|
56
|
+
* @property {NodeAppMemoryReading} heapTotal
|
|
57
|
+
* @property {NodeAppMemoryReading} heapUsed
|
|
58
|
+
* @property {NodeAppMemoryReading} external
|
|
59
|
+
* @property {NodeAppMemoryReading} heapCapacity
|
|
60
|
+
* @property {NodeAppMemoryReading} pss
|
|
61
|
+
* @property {NodeAppMemoryReading} rss
|
|
62
|
+
*/
|
|
63
|
+
/**
|
|
64
|
+
* @typedef {object} NodeAppMemoryApp
|
|
65
|
+
* @property {NodeAppType} appType
|
|
66
|
+
* @property {string} author
|
|
67
|
+
* @property {string} description
|
|
68
|
+
* @property {string} id
|
|
69
|
+
* @property {NodeAppInstallSource} installSource
|
|
70
|
+
* @property {NodeAppMemorySnapshot} [memory]
|
|
71
|
+
* @property {string} name
|
|
72
|
+
* @property {NodeAppRuntimeMode} [runtimeMode]
|
|
73
|
+
* @property {NodeAppStatus} status
|
|
74
|
+
* @property {string} version
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* @typedef {object} NodeAppMemoryRepository
|
|
78
|
+
* @property {() => Promise<readonly NodeAppMemoryApp[]>} listApps
|
|
79
|
+
* @property {(id: string) => Promise<NodeAppMemoryApp | undefined>} readApp
|
|
80
|
+
* @property {() => Promise<NodeAppMemoryOverview>} readOverview
|
|
81
|
+
* @property {(id: string) => Promise<NodeAppHeapSnapshot>} captureMemorySnapshot
|
|
82
|
+
* @property {(id: string) => Promise<NodeAppHeapSnapshot | null>} readMemorySnapshotStatus
|
|
83
|
+
* @property {(id: string, snapshotId: string) => Promise<NodeAppMemoryDownload>} downloadMemorySnapshot
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
/** @typedef {{ arrayBuffer: () => Promise<ArrayBuffer>, readonly size: number, readonly type: string }} NodeAppMemoryDownload */
|
|
87
|
+
|
|
88
|
+
/** @typedef {"capturing" | "complete" | "failed"} NodeAppHeapSnapshotState */
|
|
89
|
+
/**
|
|
90
|
+
* @typedef {object} NodeAppHeapObjectTypeCount
|
|
91
|
+
* @property {number} count
|
|
92
|
+
* @property {string} objectType
|
|
93
|
+
* @property {number} sizeBytes
|
|
94
|
+
*/
|
|
95
|
+
/**
|
|
96
|
+
* @typedef {object} NodeAppHeapSnapshotSummary
|
|
97
|
+
* @property {number} objectCount
|
|
98
|
+
* @property {readonly NodeAppHeapObjectTypeCount[]} objectTypes
|
|
99
|
+
*/
|
|
100
|
+
/**
|
|
101
|
+
* @typedef {object} NodeAppHeapSnapshot
|
|
102
|
+
* @property {string} appId
|
|
103
|
+
* @property {string | null} completedAt
|
|
104
|
+
* @property {string} createdAt
|
|
105
|
+
* @property {string | null} error
|
|
106
|
+
* @property {string} id
|
|
107
|
+
* @property {number | null} sizeBytes
|
|
108
|
+
* @property {NodeAppHeapSnapshotState} state
|
|
109
|
+
* @property {NodeAppHeapSnapshotSummary | null} summary
|
|
110
|
+
*/
|
|
111
|
+
/**
|
|
112
|
+
* @typedef {object} NodeAppLifecycleMemoryObservation
|
|
113
|
+
* @property {string} appId
|
|
114
|
+
* @property {string} observedAt
|
|
115
|
+
* @property {number} releasedKb
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/** @typedef {"heap_used" | "not_attributable" | "pss" | "rss"} NodeAppMemoryBudgetBasis */
|
|
119
|
+
/** @typedef {"flat" | "growing" | "ratcheting" | "sawtooth" | "unknown"} NodeAppMemoryTrendVerdict */
|
|
120
|
+
/**
|
|
121
|
+
* Growth classification over the trailing sample window. `slopeKbPerHour`,
|
|
122
|
+
* `fitQuality`, `ratchetRatio`, `heapFloorSlopeKbPerHour`, and
|
|
123
|
+
* `hoursToBudget` are each omitted (not `null`) when the host did not
|
|
124
|
+
* compute them — mirroring the Rust `#[serde(skip_serializing_if =
|
|
125
|
+
* "Option::is_none")]` wire contract.
|
|
126
|
+
* @typedef {object} NodeAppMemoryTrend
|
|
127
|
+
* @property {boolean} aggregate
|
|
128
|
+
* @property {NodeAppMemoryBudgetBasis} basis
|
|
129
|
+
* @property {string} computedAt
|
|
130
|
+
* @property {number} [fitQuality]
|
|
131
|
+
* @property {number} [heapFloorSlopeKbPerHour]
|
|
132
|
+
* @property {number} [hoursToBudget]
|
|
133
|
+
* @property {number} [ratchetRatio]
|
|
134
|
+
* @property {number} sampleCount
|
|
135
|
+
* @property {number} [slopeKbPerHour]
|
|
136
|
+
* @property {NodeAppMemoryTrendVerdict} verdict
|
|
137
|
+
* @property {number} windowHours
|
|
138
|
+
*/
|
|
139
|
+
/**
|
|
140
|
+
* @typedef {object} NodeAppMemoryCapabilityCallCount
|
|
141
|
+
* @property {string} capability
|
|
142
|
+
* @property {number} invocations
|
|
143
|
+
*/
|
|
144
|
+
/**
|
|
145
|
+
* Capability call load over the same window as {@link NodeAppMemoryTrend}.
|
|
146
|
+
* @typedef {object} NodeAppMemoryActivityRollup
|
|
147
|
+
* @property {number} callsPerMinute
|
|
148
|
+
* @property {string} computedAt
|
|
149
|
+
* @property {number} errors
|
|
150
|
+
* @property {number} invocations
|
|
151
|
+
* @property {readonly NodeAppMemoryCapabilityCallCount[]} topCapabilities
|
|
152
|
+
* @property {number} windowHours
|
|
153
|
+
*/
|
|
154
|
+
/** @typedef {"not_attributable" | "ok" | "over"} NodeAppBudgetState */
|
|
155
|
+
/** @typedef {"evicted" | "idle_countdown" | "running" | "sleeping" | "warm"} NodeAppLaneKind */
|
|
156
|
+
/** @typedef {"idle" | "pressure"} NodeAppTerminationReason */
|
|
157
|
+
/** @typedef {"evicting" | "ok" | "unknown"} NodeAppPressureState */
|
|
158
|
+
/**
|
|
159
|
+
* @typedef {object} NodeAppBudgetVerdict
|
|
160
|
+
* @property {boolean} aggregate
|
|
161
|
+
* @property {NodeAppMemoryBudgetBasis} basis
|
|
162
|
+
* @property {number | null} budgetKb
|
|
163
|
+
* @property {number | null} overByKb
|
|
164
|
+
* @property {NodeAppBudgetState} state
|
|
165
|
+
* @property {number | null} valueKb
|
|
166
|
+
*/
|
|
167
|
+
/**
|
|
168
|
+
* @typedef {object} NodeAppGovernorRow
|
|
169
|
+
* @property {string} appId
|
|
170
|
+
* @property {string} appName
|
|
171
|
+
* @property {string} eligibility
|
|
172
|
+
* @property {number} idleSecs
|
|
173
|
+
* @property {number} inFlight
|
|
174
|
+
* @property {NodeAppLaneKind} lane
|
|
175
|
+
* @property {string} [lastStopAt]
|
|
176
|
+
* @property {NodeAppTerminationReason} [lastStopReason]
|
|
177
|
+
* @property {string} [lastWakeAt]
|
|
178
|
+
* @property {number} [minIdleSecs]
|
|
179
|
+
* @property {number} [secsRemaining]
|
|
180
|
+
* @property {NodeAppTerminationReason} [terminationReason]
|
|
181
|
+
*/
|
|
182
|
+
/**
|
|
183
|
+
* @typedef {object} NodeAppDeviceMemory
|
|
184
|
+
* @property {number} highWaterKb
|
|
185
|
+
* @property {number} lowWaterKb
|
|
186
|
+
* @property {number | null} memAvailableKb
|
|
187
|
+
* @property {number | null} memTotalKb
|
|
188
|
+
* @property {number | null} psiSomeAvg10
|
|
189
|
+
* @property {number | null} platformRssKb
|
|
190
|
+
* @property {NodeAppPressureState} pressureState
|
|
191
|
+
* @property {number | null} swapFreeKb
|
|
192
|
+
* @property {number | null} swapTotalKb
|
|
193
|
+
*/
|
|
194
|
+
/**
|
|
195
|
+
* `swapTotalKb`/`swapFreeKb` keep the same unmeasured-is-not-zero contract as
|
|
196
|
+
* `memAvailableKb`: `0` is a machine with no swap configured, `null` is a
|
|
197
|
+
* machine that could not be asked. A renderer MUST distinguish them — "no
|
|
198
|
+
* swap" and "we don't know" are different things to tell an owner. Swap IN USE
|
|
199
|
+
* is `swapTotalKb - swapFreeKb`, and is only meaningful when both are numbers.
|
|
200
|
+
*/
|
|
201
|
+
/**
|
|
202
|
+
* @typedef {object} NodeAppMemoryOverviewApp
|
|
203
|
+
* @property {NodeAppMemoryActivityRollup} [activity]
|
|
204
|
+
* @property {NodeAppBudgetVerdict} budget
|
|
205
|
+
* @property {NodeAppGovernorRow} [governor]
|
|
206
|
+
* @property {string} id
|
|
207
|
+
* @property {Partial<NodeAppMemorySnapshot>} [memory]
|
|
208
|
+
* @property {NodeAppHeapSnapshot | null} [capture]
|
|
209
|
+
* @property {NodeAppLifecycleMemoryObservation | null} [lifecycleObservation]
|
|
210
|
+
* @property {string} name
|
|
211
|
+
* @property {NodeAppRuntimeMode} [runtimeMode]
|
|
212
|
+
* @property {NodeAppStatus} status
|
|
213
|
+
* @property {NodeAppMemoryTrend} [trend]
|
|
214
|
+
* @property {string} version
|
|
215
|
+
*/
|
|
216
|
+
/**
|
|
217
|
+
* @typedef {object} NodeAppMemoryOverview
|
|
218
|
+
* @property {readonly NodeAppMemoryOverviewApp[]} apps
|
|
219
|
+
* @property {NodeAppDeviceMemory | null} device
|
|
220
|
+
* @property {NodeAppMemoryReading} [sharedHostResidual]
|
|
221
|
+
*/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @template {import("./durable-event.js").DurableEvent} [TEvent=import("./durable-event.js").DurableEvent] @typedef {import("./durable-event.js").RepositoryWriteResult<TEvent>} RepositoryWriteResult */
|
|
4
|
+
/** @typedef {import("./repository-mutation.js").RepositoryJsonValue} RepositoryJsonValue */
|
|
5
|
+
/** @typedef {"acknowledged" | "conflict" | "failed" | "pending" | "replaying"} OutboxRecordState */
|
|
6
|
+
/** @typedef {{ readonly createdAt: string, readonly domain: string, readonly id: string, readonly idempotencyKey: string, readonly payload: RepositoryJsonValue, readonly state: OutboxRecordState, readonly updatedAt: string }} OutboxRecord */
|
|
7
|
+
/** @typedef {OutboxRecord & { readonly attemptCount: number, readonly leaseExpiresAt: string, readonly leaseToken: string, readonly state: "replaying" }} OutboxReplayClaim */
|
|
8
|
+
/** @typedef {{ readonly attemptCount: number, readonly createdAt: string, readonly domain: string, readonly id: string, readonly lastErrorCode?: string, readonly lastErrorMessage?: string, readonly nextAttemptAt?: string, readonly settledAt?: string, readonly state: OutboxRecordState, readonly terminalErrorCode?: string, readonly terminalErrorMessage?: string, readonly updatedAt: string }} OutboxReplayStatus */
|
|
9
|
+
/** @typedef {{ readonly id: string, readonly leaseToken: string, readonly outcome: "acknowledged" } | { readonly error: { readonly code: string, readonly message: string }, readonly id: string, readonly leaseToken: string, readonly outcome: "conflict" | "failed" } | { readonly error: { readonly code: string, readonly message: string }, readonly id: string, readonly leaseToken: string, readonly outcome: "retry", readonly retryAt: string }} OutboxSettleInput */
|
|
10
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: { readonly intent: OutboxRecord }, readonly type: "outbox.state-changed" }} OutboxStateChangedEvent */
|
|
11
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: { readonly action: "deleted", readonly entityId: string, readonly entityType: "outbox-intent" }, readonly type: "domain.entity-changed" }} OutboxDeletedEvent */
|
|
12
|
+
/** @typedef {OutboxDeletedEvent | OutboxStateChangedEvent} OutboxRepositoryEvent */
|
|
13
|
+
/** @typedef {{ readonly domain?: string, readonly state?: OutboxRecordState }} OutboxRepositoryFilter */
|
|
14
|
+
|
|
15
|
+
export class OutboxIdempotencyConflictError extends Error {
|
|
16
|
+
/** @readonly @type {string} */
|
|
17
|
+
idempotencyKey;
|
|
18
|
+
|
|
19
|
+
/** @param {string} idempotencyKey */
|
|
20
|
+
constructor(idempotencyKey) {
|
|
21
|
+
super("Outbox idempotency key belongs to a different command");
|
|
22
|
+
this.name = "OutboxIdempotencyConflictError";
|
|
23
|
+
this.idempotencyKey = idempotencyKey;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** @typedef {{ claimHead?(input: { readonly domain: string, readonly leaseExpiresAt: string, readonly leaseToken: string }): Promise<OutboxReplayClaim | undefined>, create(input: OutboxRecord): Promise<RepositoryWriteResult<OutboxRepositoryEvent>>, delete(id: string): Promise<RepositoryWriteResult<OutboxRepositoryEvent>>, list(filter?: OutboxRepositoryFilter): Promise<readonly OutboxRecord[]>, read(id: string): Promise<OutboxRecord | undefined>, listStatus?(filter?: { readonly domain?: string }): Promise<readonly OutboxReplayStatus[]>, settle?(input: OutboxSettleInput): Promise<RepositoryWriteResult<OutboxRepositoryEvent>>, updateState(id: string, state: OutboxRecordState): Promise<RepositoryWriteResult<OutboxRepositoryEvent>> }} OutboxRepository */
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {boolean | null | number | string} RepositoryJsonPrimitive */
|
|
4
|
+
/** @typedef {RepositoryJsonPrimitive | RepositoryJsonArray | RepositoryJsonObject} RepositoryJsonValue */
|
|
5
|
+
/** @typedef {RepositoryJsonValue[]} RepositoryJsonArray */
|
|
6
|
+
/** @typedef {{ readonly [key: string]: RepositoryJsonValue }} RepositoryJsonObject */
|
|
7
|
+
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {import("./repository-mutation.js").RepositoryJsonValue} RepositoryJsonValue */
|
|
4
|
+
/** @template {import("./durable-event.js").DurableEvent} [TEvent=import("./durable-event.js").DurableEvent] @typedef {import("./durable-event.js").RepositoryWriteResult<TEvent>} RepositoryWriteResult */
|
|
5
|
+
|
|
6
|
+
export const REVISIONED_REPOSITORY_DOMAINS = /** @type {const} */ (["agent", "settings", "graph"]);
|
|
7
|
+
/** @typedef {typeof REVISIONED_REPOSITORY_DOMAINS[number]} RevisionedRepositoryDomain */
|
|
8
|
+
/** @template {RepositoryJsonValue} [TValue=RepositoryJsonValue] @typedef {{ readonly id: string, readonly rev: number, readonly value: TValue }} RevisionedEntity */
|
|
9
|
+
/** @template {RepositoryJsonValue} [TValue=RepositoryJsonValue] @typedef {{ readonly baseRev: number, readonly id: string, readonly idempotencyKey: string, readonly value: TValue }} RevisionCommand */
|
|
10
|
+
/** @template {RepositoryJsonValue} [TValue=RepositoryJsonValue] @typedef {{ readonly entity: RevisionedEntity<TValue>, readonly status: "accepted" } | { readonly status: "conflict", readonly theirs: RevisionedEntity<TValue> }} RevisionCommandResult */
|
|
11
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: { readonly action: "created" | "updated", readonly entityId: string, readonly entityType: "agent" | "graph" | "setting" }, readonly type: "domain.entity-changed" }} RevisionedRepositoryEvent */
|
|
12
|
+
/** @template {RepositoryJsonValue} [TValue=RepositoryJsonValue] @typedef {{ apply(entity: RevisionedEntity<TValue>): Promise<RepositoryWriteResult<RevisionedRepositoryEvent>>, command(input: RevisionCommand<TValue>): Promise<RevisionCommandResult<TValue>>, list(): Promise<readonly RevisionedEntity<TValue>[]>, read(id: string): Promise<RevisionedEntity<TValue> | undefined> }} RevisionedRepository */
|
|
13
|
+
/** @typedef {RevisionedRepository} AgentRepository */
|
|
14
|
+
/** @typedef {RevisionedRepository} RevisionedSettingsRepository */
|
|
15
|
+
/** @typedef {RevisionedRepository} GraphRepository */
|
|
16
|
+
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @template {import("./durable-event.js").DurableEvent} [TEvent=import("./durable-event.js").DurableEvent] @typedef {import("./durable-event.js").RepositoryWriteResult<TEvent>} RepositoryWriteResult */
|
|
4
|
+
/** @typedef {import("./repository-mutation.js").RepositoryJsonValue} RepositoryJsonValue */
|
|
5
|
+
/** @typedef {{ readonly key: string, readonly updatedAt: string, readonly value: RepositoryJsonValue }} SettingRecord */
|
|
6
|
+
/** @typedef {{ readonly key: string, readonly value: RepositoryJsonValue }} SettingInput */
|
|
7
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: { readonly action: "created" | "deleted" | "updated", readonly entityId: string, readonly entityType: "setting" }, readonly type: "domain.entity-changed" }} SettingsRepositoryEvent */
|
|
8
|
+
/** @typedef {{ delete(key: string): Promise<RepositoryWriteResult<SettingsRepositoryEvent>>, list(): Promise<readonly SettingRecord[]>, read(key: string): Promise<SettingRecord | undefined>, set(input: SettingInput): Promise<RepositoryWriteResult<SettingsRepositoryEvent>> }} SettingsRepository */
|
|
9
|
+
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @template {import("./durable-event.js").DurableEvent} [TEvent=import("./durable-event.js").DurableEvent] @typedef {import("./durable-event.js").RepositoryWriteResult<TEvent>} RepositoryWriteResult */
|
|
4
|
+
/** @typedef {{ readonly cursor: string, readonly domain: string }} SyncLedgerInput */
|
|
5
|
+
/** @typedef {SyncLedgerInput & { readonly updatedAt: string }} SyncLedgerRecord */
|
|
6
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: SyncLedgerInput, readonly type: "sync.delta-applied" }} SyncDeltaAppliedEvent */
|
|
7
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: { readonly action: "deleted", readonly entityId: string, readonly entityType: "sync-cursor" }, readonly type: "domain.entity-changed" }} SyncCursorDeletedEvent */
|
|
8
|
+
/** @typedef {SyncCursorDeletedEvent | SyncDeltaAppliedEvent} SyncLedgerRepositoryEvent */
|
|
9
|
+
/** @typedef {{ delete(domain: string): Promise<RepositoryWriteResult<SyncLedgerRepositoryEvent>>, list(): Promise<readonly SyncLedgerRecord[]>, read(domain: string): Promise<SyncLedgerRecord | undefined>, setCursor(input: SyncLedgerInput): Promise<RepositoryWriteResult<SyncLedgerRepositoryEvent>> }} SyncLedgerRepository */
|
|
10
|
+
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {{ readonly amountMsat: number, readonly createdAt: string, readonly direction: "incoming" | "outgoing", readonly failureCode?: string, readonly id: string, readonly paymentHash?: string, readonly status: "pending" | "succeeded" | "failed" | "expired", readonly updatedAt: string }} WalletPaymentRecord */
|
|
4
|
+
/** @typedef {{ readonly amountMsat: number, readonly paidAt: string, readonly paymentHash?: string, readonly receiptId: string, readonly resource: string }} WalletL402Receipt */
|
|
5
|
+
/** @typedef {{ readonly balanceMsat: number, readonly l402: readonly WalletL402Receipt[], readonly payments: readonly WalletPaymentRecord[], readonly spendableMsat: number }} WalletSnapshotValue */
|
|
6
|
+
/** @typedef {{ readonly observedAt: string, readonly staleAt: string, readonly value: WalletSnapshotValue }} WalletAuthoritativeSnapshot */
|
|
7
|
+
/** @typedef {{ readonly amountMsat: number, readonly invoiceId: string, readonly kind: "invoice-created", readonly paymentHash?: string, readonly paymentRequest: string, readonly status: "created" } | { readonly amountMsat: number, readonly kind: "payment-submitted", readonly paymentHash?: string, readonly paymentId: string, readonly status: "pending" | "succeeded" | "failed" }} WalletCommandResult */
|
|
8
|
+
/** @typedef {{ readCommandResult(idempotencyKey: string): Promise<WalletCommandResult | undefined>, readSnapshot(): Promise<WalletAuthoritativeSnapshot | undefined>, writeCommandResult(idempotencyKey: string, result: WalletCommandResult): Promise<void>, writeSnapshot(snapshot: WalletAuthoritativeSnapshot): Promise<void> }} WalletMirrorRepository */
|
|
9
|
+
|
|
10
|
+
/** @param {unknown} value @returns {value is WalletSnapshotValue} */
|
|
11
|
+
export function isWalletSnapshotValue(value) {
|
|
12
|
+
if (!isRecord(value) || !hasOnlyKeys(value, ["balanceMsat", "l402", "payments", "spendableMsat"]) ||
|
|
13
|
+
!isNonNegativeNumber(value.balanceMsat) || !isNonNegativeNumber(value.spendableMsat)) return false;
|
|
14
|
+
return Array.isArray(value.payments) && value.payments.every(isWalletPaymentRecord) &&
|
|
15
|
+
Array.isArray(value.l402) && value.l402.every(isWalletL402Receipt);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** @param {unknown} value @returns {value is WalletAuthoritativeSnapshot} */
|
|
19
|
+
export function isWalletAuthoritativeSnapshot(value) {
|
|
20
|
+
return isRecord(value) && hasOnlyKeys(value, ["observedAt", "staleAt", "value"]) &&
|
|
21
|
+
typeof value.observedAt === "string" && typeof value.staleAt === "string" &&
|
|
22
|
+
isWalletSnapshotValue(value.value);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @param {unknown} value @returns {value is WalletCommandResult} */
|
|
26
|
+
export function isWalletCommandResult(value) {
|
|
27
|
+
if (!isRecord(value) || !isNonNegativeNumber(value.amountMsat)) return false;
|
|
28
|
+
if (value.kind === "invoice-created") {
|
|
29
|
+
return hasOnlyKeys(value, ["amountMsat", "invoiceId", "kind", "paymentHash", "paymentRequest", "status"]) &&
|
|
30
|
+
value.status === "created" && typeof value.invoiceId === "string" && typeof value.paymentRequest === "string" &&
|
|
31
|
+
(value.paymentHash === undefined || typeof value.paymentHash === "string");
|
|
32
|
+
}
|
|
33
|
+
return hasOnlyKeys(value, ["amountMsat", "kind", "paymentHash", "paymentId", "status"]) &&
|
|
34
|
+
value.kind === "payment-submitted" &&
|
|
35
|
+
(value.status === "pending" || value.status === "succeeded" || value.status === "failed") &&
|
|
36
|
+
typeof value.paymentId === "string" &&
|
|
37
|
+
(value.paymentHash === undefined || typeof value.paymentHash === "string");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** @param {unknown} value @returns {value is WalletPaymentRecord} */
|
|
41
|
+
function isWalletPaymentRecord(value) {
|
|
42
|
+
if (!isRecord(value) || !isNonNegativeNumber(value.amountMsat) || typeof value.createdAt !== "string" ||
|
|
43
|
+
typeof value.id !== "string" || typeof value.updatedAt !== "string" ||
|
|
44
|
+
!hasOnlyKeys(value, ["amountMsat", "createdAt", "direction", "failureCode", "id", "paymentHash", "status", "updatedAt"])) return false;
|
|
45
|
+
return (value.direction === "incoming" || value.direction === "outgoing") &&
|
|
46
|
+
(value.status === "pending" || value.status === "succeeded" || value.status === "failed" || value.status === "expired") &&
|
|
47
|
+
(value.failureCode === undefined || typeof value.failureCode === "string") &&
|
|
48
|
+
(value.paymentHash === undefined || typeof value.paymentHash === "string");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @param {unknown} value @returns {value is WalletL402Receipt} */
|
|
52
|
+
function isWalletL402Receipt(value) {
|
|
53
|
+
return isRecord(value) && hasOnlyKeys(value, ["amountMsat", "paidAt", "paymentHash", "receiptId", "resource"]) &&
|
|
54
|
+
isNonNegativeNumber(value.amountMsat) && typeof value.paidAt === "string" &&
|
|
55
|
+
typeof value.receiptId === "string" && typeof value.resource === "string" &&
|
|
56
|
+
(value.paymentHash === undefined || typeof value.paymentHash === "string");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @param {unknown} value @returns {value is number} */
|
|
60
|
+
function isNonNegativeNumber(value) {
|
|
61
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** @param {unknown} value @returns {value is Record<string, unknown>} */
|
|
65
|
+
function isRecord(value) {
|
|
66
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @param {Record<string, unknown>} value @param {readonly string[]} allowed @returns {boolean} */
|
|
70
|
+
function hasOnlyKeys(value, allowed) {
|
|
71
|
+
const allowedKeys = new Set(allowed);
|
|
72
|
+
return Object.keys(value).every((key) => allowedKeys.has(key));
|
|
73
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {{ readonly entry: string, readonly integrity: Readonly<Record<string, string>>, readonly requires: readonly string[], readonly version: string }} StageManifest */
|
|
4
|
+
/** @typedef {"last-known" | "online-only"} AppDataOfflinePolicy */
|
|
5
|
+
/** @typedef {"collection" | "detail" | "snapshot"} AppDataQueryKind */
|
|
6
|
+
/** @typedef {"changes" | "events"} AppDataStreamKind */
|
|
7
|
+
/** @typedef {"cursor" | "snapshot"} AppDataSyncKind */
|
|
8
|
+
/** @typedef {{ readonly cursorTtlSecs?: number, readonly fullRefreshIntervalSecs?: number, readonly kind: AppDataSyncKind, readonly retentionSecs?: number }} AppDataSyncPolicy */
|
|
9
|
+
/** @typedef {{ readonly capability: string, readonly kind: AppDataQueryKind, readonly name: string }} AppDataQueryDeclaration */
|
|
10
|
+
/** @typedef {{ readonly kind: AppDataStreamKind, readonly name: string }} AppDataStreamDeclaration */
|
|
11
|
+
/** @typedef {{ readonly namespace: string, readonly offline: AppDataOfflinePolicy, readonly queries: readonly AppDataQueryDeclaration[], readonly streams: readonly AppDataStreamDeclaration[], readonly sync: AppDataSyncPolicy }} AppDataManifest */
|
|
12
|
+
/** @typedef {"stage" | "widget"} StageUiKind */
|
|
13
|
+
/** @typedef {{ readonly order: number, readonly section: string }} StageUiNav */
|
|
14
|
+
/** @typedef {{ readonly capabilities: readonly string[], readonly queries: readonly string[], readonly streams: readonly string[] }} StageUiRequirements */
|
|
15
|
+
/** @typedef {{ readonly composes: readonly string[], readonly icon?: string, readonly kind: StageUiKind, readonly nav?: StageUiNav, readonly requires?: StageUiRequirements, readonly title: string, readonly uiApi: 1 | 2 }} StageUiMetadata */
|
|
16
|
+
/** @typedef {{ readonly appName: string, readonly assetBase: string, readonly data?: AppDataManifest, readonly description?: string, readonly keywords?: readonly string[], readonly manifest: StageManifest, readonly manifestSha256: string, readonly ui: StageUiMetadata }} StageCatalogEntry */
|
|
17
|
+
/** @typedef {{ readonly entries: readonly StageCatalogEntry[], readonly revision: string }} StageRegistrySnapshot */
|
|
18
|
+
/** @typedef {{ read(): Promise<StageRegistrySnapshot | undefined>, write(snapshot: StageRegistrySnapshot): Promise<void> }} StageRegistryPort */
|
|
19
|
+
/** @typedef {{ readonly appName: string, readonly entryUrl: string, readonly manifestSha256: string, readonly version: string }} PreparedStageAsset */
|
|
20
|
+
/** @typedef {{ prepare(appName: string, manifest: StageManifest): Promise<PreparedStageAsset> }} StageAssetPort */
|
|
21
|
+
|
|
22
|
+
export {};
|
package/src/scheduler.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {{ readonly cadenceMs?: number, readonly dueAt: string, readonly name: string, run(): Promise<void> }} ScheduledJob */
|
|
4
|
+
/** @typedef {{ cancel(name: string): void, register(job: ScheduledJob): void, shutdown(): Promise<void> }} SchedulerPort */
|
|
5
|
+
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
export {};
|
|
3
|
+
/**
|
|
4
|
+
* Boundary port for the one boolean flag `system/pwa/src/main.ts` needs out of
|
|
5
|
+
* `sessionStorage` before the shell exists: the "Continue in browser" escape hatch
|
|
6
|
+
* (`CONTINUE_IN_BROWSER_KEY`, `system/pwa/src/boot-gate.ts`) that the install landing's
|
|
7
|
+
* "Continue in browser" button sets, and that the top-level boot-gate computation reads back
|
|
8
|
+
* on the next navigation this session.
|
|
9
|
+
*
|
|
10
|
+
* The composition root (`system/pwa/src/main.ts`) may not name `sessionStorage` directly
|
|
11
|
+
* (boundary rules B3/B4, `client/scripts/check-boundaries.mjs`) — this is the narrow surface
|
|
12
|
+
* `client/adapters-web`'s `createBrowserSessionFlag()` implements against the real global,
|
|
13
|
+
* constructed and called directly from `main.ts`, mirroring `ClipboardPort`'s and
|
|
14
|
+
* `MediaPreferencesPort`'s seams.
|
|
15
|
+
*
|
|
16
|
+
* Deliberately NOT routed through one of `client/ui`'s `configureX`/`currentX()` module-level
|
|
17
|
+
* slots the way `ClipboardPort`/`MediaPreferencesPort` are: those ports back calls made FROM
|
|
18
|
+
* `client/ui` (an onboarding screen's paste button, the shell's hover/motion checks), so
|
|
19
|
+
* `client/ui` needs somewhere to read an injected implementation from. Both call sites for
|
|
20
|
+
* this flag — `renderInstallLanding()`'s `onContinue` handler and the top-level
|
|
21
|
+
* `bootShellNow` computation — live in `main.ts` itself, before `<node-app-shell>` or
|
|
22
|
+
* `<node-install-landing>` ever mounts, so there is no `client/ui` consumer to inject into;
|
|
23
|
+
* the composition root simply constructs the adapter and calls it directly, the same way it
|
|
24
|
+
* already does for `InstallEnvironmentPort`'s `installEnv.isStandalone()`.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately synchronous: the read backs `bootShellNow`, a top-level, synchronous
|
|
27
|
+
* computation in `main.ts` made before the kernel/RPC bridge exists (see `boot-gate.ts`'s own
|
|
28
|
+
* doc comment on `BootGateInputs`) — turning it async would restructure the whole boot path
|
|
29
|
+
* for a nicer port shape, which is not this port's job. `MediaPreferencesPort`'s two methods
|
|
30
|
+
* are synchronous for the identical reason: both are read before any RPC bridge exists.
|
|
31
|
+
*
|
|
32
|
+
* Both methods degrade to the SAME safe default the pre-extraction inline `try`/`catch`
|
|
33
|
+
* blocks in `main.ts` documented — reading or writing `sessionStorage` can throw under
|
|
34
|
+
* strict privacy modes (Safari private browsing, some content blockers), AND merely
|
|
35
|
+
* accessing the `sessionStorage` property itself can throw a `SecurityError` in other
|
|
36
|
+
* locked-down embedders (Firefox/Chrome "block all cookies", an `<iframe sandbox>` without
|
|
37
|
+
* `allow-same-origin`) — the adapter constructor guards the latter the same way its
|
|
38
|
+
* `getItem`/`setItem` calls guard the former, so losing the flag must never block booting
|
|
39
|
+
* the shell, nor may it ever throw and abort evaluation of the composition root:
|
|
40
|
+
* - `read()` returns `false` both when the flag was never set AND when the read itself
|
|
41
|
+
* failed — the "the flag never stuck" outcome, which simply shows the install landing
|
|
42
|
+
* again next time, exactly the pre-existing behavior.
|
|
43
|
+
* - `set()` swallows a failed write silently; the visitor already asked to continue in the
|
|
44
|
+
* browser and a storage failure must not stand in the way of that.
|
|
45
|
+
* @typedef {object} SessionFlagPort
|
|
46
|
+
* @property {(key: string) => boolean} read
|
|
47
|
+
* @property {(key: string) => void} set
|
|
48
|
+
*/
|
package/src/storage.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {import("./repositories.js").StageRegistryPort} StageRegistryPort */
|
|
4
|
+
/** @typedef {import("./repositories/conversation-repository.js").ConversationRepository} ConversationRepository */
|
|
5
|
+
/** @typedef {import("./repositories/conversation-repository.js").NotificationRepository} NotificationRepository */
|
|
6
|
+
/** @typedef {import("./repositories/conversation-repository.js").RepositoryEvent} RepositoryEvent */
|
|
7
|
+
/** @typedef {import("./repositories/outbox.js").OutboxRepository} OutboxRepository */
|
|
8
|
+
/** @typedef {import("./repositories/outbox.js").OutboxRepositoryEvent} OutboxRepositoryEvent */
|
|
9
|
+
/** @typedef {import("./repositories/settings.js").SettingsRepository} SettingsRepository */
|
|
10
|
+
/** @typedef {import("./repositories/settings.js").SettingsRepositoryEvent} SettingsRepositoryEvent */
|
|
11
|
+
/** @typedef {import("./repositories/sync-ledger.js").SyncLedgerRepository} SyncLedgerRepository */
|
|
12
|
+
/** @typedef {import("./repositories/sync-ledger.js").SyncLedgerRepositoryEvent} SyncLedgerRepositoryEvent */
|
|
13
|
+
/** @typedef {import("./repositories/revisioned-repository.js").AgentRepository} AgentRepository */
|
|
14
|
+
/** @typedef {import("./repositories/revisioned-repository.js").GraphRepository} GraphRepository */
|
|
15
|
+
/** @typedef {import("./repositories/revisioned-repository.js").RevisionedRepositoryEvent} RevisionedRepositoryEvent */
|
|
16
|
+
/** @typedef {import("./repositories/revisioned-repository.js").RevisionedSettingsRepository} RevisionedSettingsRepository */
|
|
17
|
+
/** @typedef {import("./repositories/wallet-mirror-repository.js").WalletMirrorRepository} WalletMirrorRepository */
|
|
18
|
+
/** @typedef {import("./offline-readiness.js").OfflineProjectionRepository} OfflineProjectionRepository */
|
|
19
|
+
/** @typedef {import("./offline-readiness.js").OfflineIdentityScope} OfflineIdentityScope */
|
|
20
|
+
/** @typedef {import("./offline-readiness.js").OfflineStageRepository} OfflineStageRepository */
|
|
21
|
+
|
|
22
|
+
export const RESET_LOCAL_STORAGE_CONFIRMATION = "RESET LOCAL CLIENT DATA";
|
|
23
|
+
/** @typedef {"checksum-drift" | "corrupt" | "diagnostic-failed" | "identity-source-unavailable" | "migration-failed" | "opfs-unavailable" | "quota-exceeded" | "worker-operation-timeout" | "worker-preparation-timeout" | "writer-conflict"} StorageRecoveryCode */
|
|
24
|
+
|
|
25
|
+
/** @satisfies {Readonly<Record<StorageRecoveryCode, string>>} */
|
|
26
|
+
export const STORAGE_RECOVERY_MESSAGES = /** @type {const} */ ({
|
|
27
|
+
"checksum-drift": "Local schema history does not match this client build",
|
|
28
|
+
corrupt: "Local SQLite data failed its integrity check",
|
|
29
|
+
"diagnostic-failed": "Encrypted storage diagnostic creation failed",
|
|
30
|
+
"identity-source-unavailable": "Protected identity metadata is temporarily unavailable",
|
|
31
|
+
"migration-failed": "Local SQLite schema migration failed",
|
|
32
|
+
"opfs-unavailable": "Persistent browser storage is unavailable",
|
|
33
|
+
"quota-exceeded": "Persistent browser storage quota is exhausted",
|
|
34
|
+
"worker-operation-timeout": "Persistent storage operation timed out",
|
|
35
|
+
"worker-preparation-timeout": "Protected storage request preparation timed out",
|
|
36
|
+
"writer-conflict": "Another client-node storage writer is active",
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export class StorageOperationError extends Error {
|
|
40
|
+
/**
|
|
41
|
+
* @param {StorageRecoveryCode} code
|
|
42
|
+
*/
|
|
43
|
+
constructor(code) {
|
|
44
|
+
super("Persistent storage operation failed");
|
|
45
|
+
this.name = "StorageOperationError";
|
|
46
|
+
/** @readonly */
|
|
47
|
+
this.code = code;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @typedef {{ readonly schemaVersion: number, readonly storageGeneration?: number, readonly status: "ready" }} StorageReadyState */
|
|
52
|
+
/** @typedef {{ readonly schemaVersion: number, readonly storageGeneration?: number, readonly status: "starting" }} StorageStartingState */
|
|
53
|
+
/** @typedef {{ readonly actions: { readonly exportDiagnostic: boolean, readonly reset: true, readonly retry: true }, readonly code: StorageRecoveryCode, readonly message: string, readonly schemaVersion: number, readonly storageGeneration?: number, readonly status: "recovery-required" }} StorageRecoveryRequiredState */
|
|
54
|
+
/** @typedef {StorageReadyState | StorageRecoveryRequiredState | StorageStartingState} StorageRecoveryState */
|
|
55
|
+
/** @typedef {{ readonly algorithm: "AES-GCM", readonly ciphertextBase64: string, readonly createdAt: string, readonly format: "node-client-sqlite-diagnostic-v1", readonly ivBase64: string, readonly kdf: { readonly hash: "SHA-256", readonly iterations: 310000, readonly name: "PBKDF2", readonly saltBase64: string } }} EncryptedStorageDiagnostic */
|
|
56
|
+
/** @typedef {{ readonly offlineProjections: OfflineProjectionRepository, readonly offlineStages: OfflineStageRepository, readonly outbox: OutboxRepository, readonly syncLedger: SyncLedgerRepository }} IdentityScopedStorageRepositoryPort */
|
|
57
|
+
/** @typedef {{ readonly repositories: StorageRepositoryPort, clearActiveIdentityProjections(): Promise<void>, clearScope(scope: OfflineIdentityScope): Promise<void>, close(): Promise<void>, exportEncryptedDiagnostic(options: { readonly passphrase: string }): Promise<EncryptedStorageDiagnostic>, initialize(): Promise<StorageRecoveryState>, reactivateEmptyScope(scope: OfflineIdentityScope): Promise<boolean>, referencedAssetRevisions(): Promise<readonly string[]>, refreshIdentityMetadata(): Promise<void>, recoveryState(): Promise<StorageRecoveryState>, reset(options: { readonly confirmation: string }): Promise<StorageRecoveryState>, retry(): Promise<StorageRecoveryState>, scopedRepositories(scope: OfflineIdentityScope): IdentityScopedStorageRepositoryPort, subscribeRecoveryState(listener: (state: StorageRecoveryState) => void): () => void }} StorageDatabasePort */
|
|
58
|
+
/** @typedef {OutboxRepositoryEvent | RepositoryEvent | RevisionedRepositoryEvent | SettingsRepositoryEvent | SyncLedgerRepositoryEvent} StorageRepositoryEvent */
|
|
59
|
+
/** @typedef {{ readonly conversations?: ConversationRepository, readonly events: import("./repositories/durable-event.js").DurableRepositoryEventStore<StorageRepositoryEvent>, readonly notifications?: NotificationRepository, readonly agents?: AgentRepository, readonly graphs?: GraphRepository, readonly outbox: OutboxRepository, readonly revisionedSettings?: RevisionedSettingsRepository, readonly wallet?: WalletMirrorRepository, readonly settings: SettingsRepository, readonly syncLedger: SyncLedgerRepository }} StorageRepositoryPort */
|
|
60
|
+
/** @typedef {StorageDatabasePort & { readonly stages: StageRegistryPort }} StoragePort */
|
package/src/theme.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {"light" | "dark"} ThemePreference */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Boundary port for the shell's dark-mode plumbing (`client/ui/src/shell/theme-init.ts`).
|
|
7
|
+
*
|
|
8
|
+
* `client/ui` may never call `localStorage` or `matchMedia` directly (boundary rules
|
|
9
|
+
* B2/B3, `client/scripts/check-boundaries.mjs`) — this is the narrow surface
|
|
10
|
+
* `client/adapters-web`'s `createBrowserThemeEnvironment()` implements against the real
|
|
11
|
+
* globals, and the composition root (`system/pwa/src/main.ts`) registers it (via
|
|
12
|
+
* `client/ui`'s `configureThemeEnvironment`) before the shell's first paint. Every method is
|
|
13
|
+
* synchronous and side-effect-free beyond the read/write it names — `theme-init.ts`'s
|
|
14
|
+
* anti-FOUC contract requires resolving the initial theme before the shadow tree's first
|
|
15
|
+
* paint, which is before the kernel connection (`KernelRpcClient`, itself an async
|
|
16
|
+
* `SharedWorker`/leader-tab bridge) even exists, so this can never be mediated through
|
|
17
|
+
* `@econ-v1/rpc` the way ordinary UI reads/writes are (rule S4).
|
|
18
|
+
*/
|
|
19
|
+
/** @typedef {{ getStoredTheme(): ThemePreference | undefined, setStoredTheme(preference: ThemePreference): void, prefersDarkColorScheme(): boolean, watchDarkColorScheme(onChange: (matches: boolean) => void): (() => void) | undefined }} ThemeEnvironmentPort */
|
|
20
|
+
|
|
21
|
+
export {};
|
package/dist/clock.js
DELETED
package/dist/clock.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clock.js","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":""}
|
package/dist/crypto.js
DELETED
package/dist/crypto.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":""}
|
package/dist/id.js
DELETED
package/dist/id.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":""}
|
package/dist/identity.js
DELETED
package/dist/identity.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":""}
|
package/dist/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { createNullInstallEnvironment, } from "./install-environment.js";
|
|
2
|
-
export { DEFAULT_CLIENT_NODE_ORIGIN } from "./network/client-node-origin.js";
|
|
3
|
-
export { MAX_CLOSE_REASON_BYTES, MAX_DTLS_FINGERPRINT_BYTES, MAX_ICE_CANDIDATE_BYTES, MAX_ICE_CANDIDATES_PER_OFFER, MAX_OFFER_NONCE_BYTES, MAX_SDP_BYTES, MAX_SDP_MID_BYTES, MAX_WEBRTC_SIGNAL_MESSAGE_BYTES, MIN_OFFER_NONCE_BYTES, WEBRTC_SIGNAL_VERSION, } from "./network/webrtc-signaling.js";
|
|
4
|
-
export { CONVERSATION_MESSAGE_STATES } from "./repositories/conversation-repository.js";
|
|
5
|
-
export { OutboxIdempotencyConflictError } from "./repositories/outbox.js";
|
|
6
|
-
export { REVISIONED_REPOSITORY_DOMAINS, } from "./repositories/revisioned-repository.js";
|
|
7
|
-
export { isWalletAuthoritativeSnapshot, isWalletCommandResult, isWalletSnapshotValue, } from "./repositories/wallet-mirror-repository.js";
|
|
8
|
-
export { RESET_LOCAL_STORAGE_CONFIRMATION, STORAGE_RECOVERY_MESSAGES } from "./storage.js";
|
|
9
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,4BAA4B,GAC7B,MAAM,0BAA0B,CAAC;AAqBlC,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAW7E,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,uBAAuB,EACvB,4BAA4B,EAC5B,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,+BAA+B,EAC/B,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AAsBvC,OAAO,EAAE,2BAA2B,EAAE,MAAM,2CAA2C,CAAC;AAsBxF,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AA+B1E,OAAO,EACL,6BAA6B,GAC9B,MAAM,yCAAyC,CAAC;AAYjD,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,4CAA4C,CAAC;AAYpD,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC"}
|