@econ-v1/domain 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.
Files changed (286) hide show
  1. package/dist/errors/index.d.ts +96 -25
  2. package/dist/errors/index.d.ts.map +1 -1
  3. package/dist/events/index.d.ts +127 -20
  4. package/dist/events/index.d.ts.map +1 -1
  5. package/dist/index.d.ts +250 -47
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/models/agent.d.ts +25 -4
  8. package/dist/models/agent.d.ts.map +1 -1
  9. package/dist/models/app-data.d.ts +84 -0
  10. package/dist/models/app-data.d.ts.map +1 -0
  11. package/dist/models/conversation.d.ts +12 -2
  12. package/dist/models/conversation.d.ts.map +1 -1
  13. package/dist/models/delegation.d.ts +12 -3
  14. package/dist/models/delegation.d.ts.map +1 -1
  15. package/dist/models/device-boot-state.d.ts +12 -0
  16. package/dist/models/device-boot-state.d.ts.map +1 -0
  17. package/dist/models/device-identity.d.ts +11 -3
  18. package/dist/models/device-identity.d.ts.map +1 -1
  19. package/dist/models/graph.d.ts +26 -3
  20. package/dist/models/graph.d.ts.map +1 -1
  21. package/dist/models/index.d.ts +82 -14
  22. package/dist/models/index.d.ts.map +1 -1
  23. package/dist/models/json.d.ts +5 -5
  24. package/dist/models/json.d.ts.map +1 -1
  25. package/dist/models/l402.d.ts +4 -5
  26. package/dist/models/l402.d.ts.map +1 -1
  27. package/dist/models/live-query-definition.d.ts +15 -16
  28. package/dist/models/live-query-definition.d.ts.map +1 -1
  29. package/dist/models/node-app-memory.d.ts +107 -0
  30. package/dist/models/node-app-memory.d.ts.map +1 -0
  31. package/dist/models/outbox-intent.d.ts +3 -3
  32. package/dist/models/outbox-intent.d.ts.map +1 -1
  33. package/dist/models/outbox.d.ts +67 -15
  34. package/dist/models/outbox.d.ts.map +1 -1
  35. package/dist/models/owner-views.d.ts +28 -28
  36. package/dist/models/owner-views.d.ts.map +1 -1
  37. package/dist/models/payment.d.ts +28 -9
  38. package/dist/models/payment.d.ts.map +1 -1
  39. package/dist/models/query-diff.d.ts +2 -2
  40. package/dist/models/query-diff.d.ts.map +1 -1
  41. package/dist/models/release-manifest.d.ts +32 -47
  42. package/dist/models/release-manifest.d.ts.map +1 -1
  43. package/dist/models/repository-write.d.ts +3 -3
  44. package/dist/models/repository-write.d.ts.map +1 -1
  45. package/dist/models/revisioned-commands.d.ts +66 -13
  46. package/dist/models/revisioned-commands.d.ts.map +1 -1
  47. package/dist/models/revisioned.d.ts +50 -10
  48. package/dist/models/revisioned.d.ts.map +1 -1
  49. package/dist/models/settings.d.ts +2 -2
  50. package/dist/models/settings.d.ts.map +1 -1
  51. package/dist/models/sync.d.ts +18 -18
  52. package/dist/models/sync.d.ts.map +1 -1
  53. package/dist/models/wallet.d.ts +16 -16
  54. package/dist/models/wallet.d.ts.map +1 -1
  55. package/dist/queries/certificate-trust.d.ts +13 -0
  56. package/dist/queries/certificate-trust.d.ts.map +1 -0
  57. package/dist/queries/conversations.d.ts +38 -7
  58. package/dist/queries/conversations.d.ts.map +1 -1
  59. package/dist/queries/discovery.d.ts +10 -10
  60. package/dist/queries/discovery.d.ts.map +1 -1
  61. package/dist/queries/notifications.d.ts +24 -4
  62. package/dist/queries/notifications.d.ts.map +1 -1
  63. package/dist/queries/onboarding-flow.d.ts +25 -0
  64. package/dist/queries/onboarding-flow.d.ts.map +1 -0
  65. package/dist/queries/onboarding-lcd-screen.d.ts +56 -0
  66. package/dist/queries/onboarding-lcd-screen.d.ts.map +1 -0
  67. package/dist/queries/onboarding-status.d.ts +10 -10
  68. package/dist/queries/onboarding-status.d.ts.map +1 -1
  69. package/dist/queries/revisioned.d.ts +47 -13
  70. package/dist/queries/revisioned.d.ts.map +1 -1
  71. package/dist/queries/wallet.d.ts +40 -10
  72. package/dist/queries/wallet.d.ts.map +1 -1
  73. package/dist/services/abort-signal.d.ts +54 -0
  74. package/dist/services/abort-signal.d.ts.map +1 -0
  75. package/dist/services/certificate-trust-service.d.ts +42 -0
  76. package/dist/services/certificate-trust-service.d.ts.map +1 -0
  77. package/dist/services/conversation-service.d.ts +103 -15
  78. package/dist/services/conversation-service.d.ts.map +1 -1
  79. package/dist/services/conversation-sync.d.ts +9 -5
  80. package/dist/services/conversation-sync.d.ts.map +1 -1
  81. package/dist/services/device-boot-state-service.d.ts +17 -0
  82. package/dist/services/device-boot-state-service.d.ts.map +1 -0
  83. package/dist/services/device-cleanup-service.d.ts +47 -0
  84. package/dist/services/device-cleanup-service.d.ts.map +1 -0
  85. package/dist/services/discovery-probe-service.d.ts +37 -46
  86. package/dist/services/discovery-probe-service.d.ts.map +1 -1
  87. package/dist/services/gossip-service.d.ts +28 -13
  88. package/dist/services/gossip-service.d.ts.map +1 -1
  89. package/dist/services/invite-redemption-service.d.ts +43 -0
  90. package/dist/services/invite-redemption-service.d.ts.map +1 -0
  91. package/dist/services/lan-candidate-refresh-service.d.ts +22 -7
  92. package/dist/services/lan-candidate-refresh-service.d.ts.map +1 -1
  93. package/dist/services/lcd-decision-service.d.ts +58 -0
  94. package/dist/services/lcd-decision-service.d.ts.map +1 -0
  95. package/dist/services/onboarding-checkpoint-store.d.ts +54 -0
  96. package/dist/services/onboarding-checkpoint-store.d.ts.map +1 -0
  97. package/dist/services/onboarding-flow-service.d.ts +180 -0
  98. package/dist/services/onboarding-flow-service.d.ts.map +1 -0
  99. package/dist/services/onboarding-status-service.d.ts +21 -38
  100. package/dist/services/onboarding-status-service.d.ts.map +1 -1
  101. package/dist/services/outbox-service.d.ts +105 -29
  102. package/dist/services/outbox-service.d.ts.map +1 -1
  103. package/dist/services/owner-claim-service.d.ts +187 -0
  104. package/dist/services/owner-claim-service.d.ts.map +1 -0
  105. package/dist/services/owner-view-refresh-service.d.ts +40 -0
  106. package/dist/services/owner-view-refresh-service.d.ts.map +1 -0
  107. package/dist/services/owner-view-service.d.ts +49 -4
  108. package/dist/services/owner-view-service.d.ts.map +1 -1
  109. package/dist/services/peer-directory-service.d.ts +53 -17
  110. package/dist/services/peer-directory-service.d.ts.map +1 -1
  111. package/dist/services/release-manifest-verifier.d.ts +18 -20
  112. package/dist/services/release-manifest-verifier.d.ts.map +1 -1
  113. package/dist/services/revisioned-domain-service.d.ts +50 -17
  114. package/dist/services/revisioned-domain-service.d.ts.map +1 -1
  115. package/dist/services/runtime-globals.d.ts +39 -0
  116. package/dist/services/runtime-globals.d.ts.map +1 -0
  117. package/dist/services/session-service.d.ts +23 -3
  118. package/dist/services/session-service.d.ts.map +1 -1
  119. package/dist/services/sync/authoritative-mirror.d.ts +88 -15
  120. package/dist/services/sync/authoritative-mirror.d.ts.map +1 -1
  121. package/dist/services/sync/index.d.ts +17 -5
  122. package/dist/services/sync/index.d.ts.map +1 -1
  123. package/dist/services/sync/log-sync.d.ts +42 -8
  124. package/dist/services/sync/log-sync.d.ts.map +1 -1
  125. package/dist/services/sync/revision-merge.d.ts +80 -13
  126. package/dist/services/sync/revision-merge.d.ts.map +1 -1
  127. package/dist/services/sync/strategy.d.ts +11 -1
  128. package/dist/services/sync/strategy.d.ts.map +1 -1
  129. package/dist/services/transport-manager.d.ts +84 -29
  130. package/dist/services/transport-manager.d.ts.map +1 -1
  131. package/dist/services/wallet-mirror-service.d.ts +81 -18
  132. package/dist/services/wallet-mirror-service.d.ts.map +1 -1
  133. package/dist/services/wifi-provisioning-service.d.ts +146 -0
  134. package/dist/services/wifi-provisioning-service.d.ts.map +1 -0
  135. package/package.json +18 -12
  136. package/src/errors/index.js +126 -0
  137. package/src/events/index.js +124 -0
  138. package/src/index.js +566 -0
  139. package/src/models/agent.js +43 -0
  140. package/src/models/app-data.js +122 -0
  141. package/src/models/conversation.js +36 -0
  142. package/{dist → src}/models/delegation.js +18 -1
  143. package/src/models/device-boot-state.js +3 -0
  144. package/{dist → src}/models/device-identity.js +18 -2
  145. package/{dist → src}/models/graph.js +30 -3
  146. package/src/models/index.js +175 -0
  147. package/src/models/json.js +18 -0
  148. package/src/models/l402.js +9 -0
  149. package/src/models/live-query-definition.js +30 -0
  150. package/src/models/node-app-memory.js +130 -0
  151. package/src/models/outbox-intent.js +12 -0
  152. package/{dist → src}/models/outbox.js +102 -3
  153. package/src/models/owner-views.js +59 -0
  154. package/src/models/payment.js +24 -0
  155. package/src/models/query-diff.js +7 -0
  156. package/src/models/release-manifest.js +160 -0
  157. package/src/models/repository-write.js +10 -0
  158. package/src/models/revisioned-commands.js +92 -0
  159. package/src/models/revisioned.js +41 -0
  160. package/src/models/settings.js +16 -0
  161. package/src/models/sync.js +44 -0
  162. package/src/models/wallet.js +40 -0
  163. package/src/queries/certificate-trust.js +31 -0
  164. package/{dist → src}/queries/conversations.js +54 -3
  165. package/src/queries/discovery.js +34 -0
  166. package/{dist → src}/queries/notifications.js +25 -2
  167. package/src/queries/onboarding-flow.js +48 -0
  168. package/src/queries/onboarding-lcd-screen.js +100 -0
  169. package/src/queries/onboarding-status.js +34 -0
  170. package/src/queries/revisioned.js +128 -0
  171. package/{dist → src}/queries/wallet.js +35 -1
  172. package/src/services/abort-signal.js +69 -0
  173. package/src/services/certificate-trust-service.js +119 -0
  174. package/{dist → src}/services/conversation-service.js +108 -1
  175. package/src/services/conversation-sync.js +28 -0
  176. package/src/services/device-boot-state-service.js +45 -0
  177. package/src/services/device-cleanup-service.js +112 -0
  178. package/src/services/discovery-probe-service.js +196 -0
  179. package/{dist → src}/services/gossip-service.js +54 -4
  180. package/src/services/invite-redemption-service.js +64 -0
  181. package/src/services/lan-candidate-refresh-service.js +164 -0
  182. package/src/services/lcd-decision-service.js +93 -0
  183. package/src/services/onboarding-checkpoint-store.js +155 -0
  184. package/src/services/onboarding-flow-service.js +1096 -0
  185. package/src/services/onboarding-status-service.js +64 -0
  186. package/{dist → src}/services/outbox-service.js +132 -1
  187. package/src/services/owner-claim-service.js +347 -0
  188. package/src/services/owner-view-refresh-service.js +208 -0
  189. package/src/services/owner-view-service.js +87 -0
  190. package/{dist → src}/services/peer-directory-service.js +72 -3
  191. package/src/services/release-manifest-verifier.js +108 -0
  192. package/{dist → src}/services/revisioned-domain-service.js +189 -9
  193. package/src/services/runtime-globals.js +174 -0
  194. package/src/services/session-service.js +50 -0
  195. package/{dist → src}/services/sync/authoritative-mirror.js +90 -1
  196. package/src/services/sync/index.js +67 -0
  197. package/src/services/sync/log-sync.js +60 -0
  198. package/src/services/sync/revision-merge.js +119 -0
  199. package/src/services/sync/strategy.js +44 -0
  200. package/src/services/transport-manager.js +478 -0
  201. package/{dist → src}/services/wallet-mirror-service.js +226 -6
  202. package/src/services/wifi-provisioning-service.js +278 -0
  203. package/dist/errors/index.js +0 -45
  204. package/dist/errors/index.js.map +0 -1
  205. package/dist/events/index.js +0 -17
  206. package/dist/events/index.js.map +0 -1
  207. package/dist/index.js +0 -31
  208. package/dist/index.js.map +0 -1
  209. package/dist/models/agent.js +0 -17
  210. package/dist/models/agent.js.map +0 -1
  211. package/dist/models/conversation.js +0 -2
  212. package/dist/models/conversation.js.map +0 -1
  213. package/dist/models/delegation.js.map +0 -1
  214. package/dist/models/device-identity.js.map +0 -1
  215. package/dist/models/graph.js.map +0 -1
  216. package/dist/models/index.js +0 -8
  217. package/dist/models/index.js.map +0 -1
  218. package/dist/models/json.js +0 -2
  219. package/dist/models/json.js.map +0 -1
  220. package/dist/models/l402.js +0 -2
  221. package/dist/models/l402.js.map +0 -1
  222. package/dist/models/live-query-definition.js +0 -2
  223. package/dist/models/live-query-definition.js.map +0 -1
  224. package/dist/models/outbox-intent.js +0 -2
  225. package/dist/models/outbox-intent.js.map +0 -1
  226. package/dist/models/outbox.js.map +0 -1
  227. package/dist/models/owner-views.js +0 -7
  228. package/dist/models/owner-views.js.map +0 -1
  229. package/dist/models/payment.js +0 -3
  230. package/dist/models/payment.js.map +0 -1
  231. package/dist/models/query-diff.js +0 -2
  232. package/dist/models/query-diff.js.map +0 -1
  233. package/dist/models/release-manifest.js +0 -147
  234. package/dist/models/release-manifest.js.map +0 -1
  235. package/dist/models/repository-write.js +0 -2
  236. package/dist/models/repository-write.js.map +0 -1
  237. package/dist/models/revisioned-commands.js +0 -35
  238. package/dist/models/revisioned-commands.js.map +0 -1
  239. package/dist/models/revisioned.js +0 -2
  240. package/dist/models/revisioned.js.map +0 -1
  241. package/dist/models/settings.js +0 -2
  242. package/dist/models/settings.js.map +0 -1
  243. package/dist/models/sync.js +0 -2
  244. package/dist/models/sync.js.map +0 -1
  245. package/dist/models/wallet.js +0 -2
  246. package/dist/models/wallet.js.map +0 -1
  247. package/dist/queries/conversations.js.map +0 -1
  248. package/dist/queries/discovery.js +0 -27
  249. package/dist/queries/discovery.js.map +0 -1
  250. package/dist/queries/notifications.js.map +0 -1
  251. package/dist/queries/onboarding-status.js +0 -27
  252. package/dist/queries/onboarding-status.js.map +0 -1
  253. package/dist/queries/revisioned.js +0 -58
  254. package/dist/queries/revisioned.js.map +0 -1
  255. package/dist/queries/wallet.js.map +0 -1
  256. package/dist/services/conversation-service.js.map +0 -1
  257. package/dist/services/conversation-sync.js +0 -9
  258. package/dist/services/conversation-sync.js.map +0 -1
  259. package/dist/services/discovery-probe-service.js +0 -129
  260. package/dist/services/discovery-probe-service.js.map +0 -1
  261. package/dist/services/gossip-service.js.map +0 -1
  262. package/dist/services/lan-candidate-refresh-service.js +0 -79
  263. package/dist/services/lan-candidate-refresh-service.js.map +0 -1
  264. package/dist/services/onboarding-status-service.js +0 -32
  265. package/dist/services/onboarding-status-service.js.map +0 -1
  266. package/dist/services/outbox-service.js.map +0 -1
  267. package/dist/services/owner-view-service.js +0 -21
  268. package/dist/services/owner-view-service.js.map +0 -1
  269. package/dist/services/peer-directory-service.js.map +0 -1
  270. package/dist/services/release-manifest-verifier.js +0 -84
  271. package/dist/services/release-manifest-verifier.js.map +0 -1
  272. package/dist/services/revisioned-domain-service.js.map +0 -1
  273. package/dist/services/session-service.js +0 -20
  274. package/dist/services/session-service.js.map +0 -1
  275. package/dist/services/sync/authoritative-mirror.js.map +0 -1
  276. package/dist/services/sync/index.js +0 -4
  277. package/dist/services/sync/index.js.map +0 -1
  278. package/dist/services/sync/log-sync.js +0 -20
  279. package/dist/services/sync/log-sync.js.map +0 -1
  280. package/dist/services/sync/revision-merge.js +0 -46
  281. package/dist/services/sync/revision-merge.js.map +0 -1
  282. package/dist/services/sync/strategy.js +0 -2
  283. package/dist/services/sync/strategy.js.map +0 -1
  284. package/dist/services/transport-manager.js +0 -234
  285. package/dist/services/transport-manager.js.map +0 -1
  286. package/dist/services/wallet-mirror-service.js.map +0 -1
@@ -0,0 +1,40 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @template TValue
5
+ * @typedef {import("./sync.js").AuthoritativeSnapshot<TValue>} AuthoritativeSnapshot
6
+ */
7
+ /**
8
+ * @typedef {import("./l402.js").L402Receipt} L402Receipt
9
+ */
10
+ /**
11
+ * @typedef {import("./payment.js").PaymentRecord} PaymentRecord
12
+ */
13
+ /**
14
+ * @typedef {import("./payment.js").WalletCommandResult} WalletCommandResult
15
+ */
16
+ /**
17
+ * @typedef {{ readonly balanceMsat: number; readonly l402: readonly L402Receipt[]; readonly payments: readonly PaymentRecord[]; readonly spendableMsat: number; }} WalletSnapshotPayload
18
+ */
19
+ /**
20
+ * @typedef {AuthoritativeSnapshot<WalletSnapshotPayload>} WalletAuthoritativeSnapshot
21
+ */
22
+ /**
23
+ * @typedef {{ readonly balanceMsat?: number; readonly freshness: "fresh" | "stale" | "unavailable"; readonly observedAt?: string; readonly spendableMsat?: number; readonly staleAt?: string; }} WalletBalanceView
24
+ */
25
+ /**
26
+ * @typedef {{ readonly freshness: "fresh" | "stale" | "unavailable"; readonly items: readonly PaymentRecord[]; readonly observedAt?: string; readonly staleAt?: string; }} PaymentHistoryView
27
+ */
28
+ /**
29
+ * @typedef {{ readCommandResult(idempotencyKey: string): Promise<WalletCommandResult | undefined>; readSnapshot(): Promise<WalletAuthoritativeSnapshot | undefined>; writeCommandResult(idempotencyKey: string, result: WalletCommandResult): Promise<void>; writeSnapshot(snapshot: WalletAuthoritativeSnapshot): Promise<void>; }} WalletMirrorRepository
30
+ */
31
+ /**
32
+ * @typedef {{ readonly amountMsat: number; readonly description?: string; readonly idempotencyKey: string; }} CreateInvoiceInput
33
+ */
34
+ /**
35
+ * @typedef {{ readonly amountMsat: number; readonly expiresAt?: string; readonly idempotencyKey: string; readonly invoiceId: string; }} PayInvoiceInput
36
+ */
37
+ /**
38
+ * @typedef {| { readonly amountMsat: number; readonly description?: string; readonly kind: "create-invoice" } | { readonly amountMsat: number; readonly expiresAt?: string; readonly invoiceId: string; readonly kind: "pay-invoice" }} WalletCommand
39
+ */
40
+ export {};
@@ -0,0 +1,31 @@
1
+ // @ts-check
2
+ /** @template TParams @template TRow @typedef {import('../models/live-query-definition.js').LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition */
3
+ /** @typedef {import('../services/certificate-trust-service.js').CertificateTrustService} CertificateTrustService */
4
+ /** @typedef {import('../services/certificate-trust-service.js').CertificateTrustSnapshot} CertificateTrustSnapshot */
5
+ export const CERTIFICATE_TRUST_QUERY = "trust.status.v1";
6
+ /**
7
+ * @param {Pick<CertificateTrustService, "status">} service
8
+ * @returns {LiveQueryDefinition<unknown, CertificateTrustSnapshot>}
9
+ */
10
+ export function createCertificateTrustQuery(service) {
11
+ return {
12
+ invalidateOn: ["transport.state-changed"],
13
+ key: (row) => row.origin,
14
+ name: CERTIFICATE_TRUST_QUERY,
15
+ requiresDurableStorage: false,
16
+ run: async (params) => {
17
+ if (
18
+ params === null ||
19
+ typeof params !== "object" ||
20
+ Array.isArray(params) ||
21
+ Object.keys(params).length !== 0
22
+ ) {
23
+ throw new TypeError(
24
+ "Certificate trust status query does not accept parameters",
25
+ );
26
+ }
27
+ return [service.status()];
28
+ },
29
+ };
30
+ }
31
+ // @ts-check
@@ -1,3 +1,23 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @typedef {import("@econ-v1/ports").ConversationRepository} ConversationRepository
5
+ */
6
+ /**
7
+ * @typedef {import("../models/conversation.js").ConversationListParams} ConversationListParams
8
+ */
9
+ /**
10
+ * @typedef {import("../models/conversation.js").MessageListParams} MessageListParams
11
+ */
12
+ /**
13
+ * @template TParams
14
+ * @template TRow
15
+ * @typedef {import("../models/live-query-definition.js").LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition
16
+ */
17
+ /**
18
+ * @param {Pick<ConversationRepository, "listConversations">} repository
19
+ * @returns {LiveQueryDefinition<ConversationListParams, Awaited<ReturnType<ConversationRepository["listConversations"]>>[number]>}
20
+ */
1
21
  export function createConversationListQuery(repository) {
2
22
  return {
3
23
  invalidateOn: ["domain.entity-changed", "sync.delta-applied"],
@@ -6,6 +26,10 @@ export function createConversationListQuery(repository) {
6
26
  run: async (params) => await repository.listConversations(parseConversationListParams(params)),
7
27
  };
8
28
  }
29
+ /**
30
+ * @param {Pick<ConversationRepository, "listMessages">} repository
31
+ * @returns {LiveQueryDefinition<MessageListParams & { readonly conversationId: string }, Awaited<ReturnType<ConversationRepository["listMessages"]>>[number]>}
32
+ */
9
33
  export function createConversationMessagesQuery(repository) {
10
34
  return {
11
35
  invalidateOn: ["domain.entity-changed", "sync.delta-applied"],
@@ -17,10 +41,18 @@ export function createConversationMessagesQuery(repository) {
17
41
  },
18
42
  };
19
43
  }
44
+ /**
45
+ * @param {unknown} value
46
+ * @returns {ConversationListParams}
47
+ */
20
48
  export function parseConversationListParams(value) {
21
49
  const record = exactRecord(value, ["before", "limit"], "conversation list");
22
50
  return { ...optionalBefore(record.before, "conversation list"), ...optionalLimit(record.limit, "conversation list") };
23
51
  }
52
+ /**
53
+ * @param {unknown} value
54
+ * @returns {MessageListParams & { readonly conversationId: string }}
55
+ */
24
56
  export function parseConversationMessagesParams(value) {
25
57
  const record = exactRecord(value, ["before", "conversationId", "limit"], "conversation messages");
26
58
  if (typeof record.conversationId !== "string" || record.conversationId.trim() === "")
@@ -31,14 +63,25 @@ export function parseConversationMessagesParams(value) {
31
63
  ...optionalLimit(record.limit, "conversation messages"),
32
64
  };
33
65
  }
66
+ /**
67
+ * @param {unknown} value
68
+ * @param {readonly string[]} allowed
69
+ * @param {string} label
70
+ * @returns {Record<string, unknown>}
71
+ */
34
72
  function exactRecord(value, allowed, label) {
35
73
  if (value === null || typeof value !== "object" || Array.isArray(value))
36
74
  throw invalid(label);
37
- const record = value;
75
+ const record = /** @type {Record<string, unknown>} */ (value);
38
76
  if (Object.keys(record).some((key) => !allowed.includes(key)))
39
77
  throw invalid(label);
40
- return record;
78
+ return /** @type {Record<string, unknown>} */ (record);
41
79
  }
80
+ /**
81
+ * @param {unknown} value
82
+ * @param {string} label
83
+ * @returns {{ readonly before?: string }}
84
+ */
42
85
  function optionalBefore(value, label) {
43
86
  if (value === undefined)
44
87
  return {};
@@ -46,6 +89,11 @@ function optionalBefore(value, label) {
46
89
  throw invalid(label);
47
90
  return { before: value };
48
91
  }
92
+ /**
93
+ * @param {unknown} value
94
+ * @param {string} label
95
+ * @returns {{ readonly limit?: number }}
96
+ */
49
97
  function optionalLimit(value, label) {
50
98
  if (value === undefined)
51
99
  return {};
@@ -53,7 +101,10 @@ function optionalLimit(value, label) {
53
101
  throw invalid(label);
54
102
  return { limit: value };
55
103
  }
104
+ /**
105
+ * @param {string} label
106
+ * @returns {TypeError}
107
+ */
56
108
  function invalid(label) {
57
109
  return new TypeError(`Invalid ${label} query parameters`);
58
110
  }
59
- //# sourceMappingURL=conversations.js.map
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+
3
+ /** @template TParams @template TRow @typedef {import("../models/live-query-definition.js").LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition */
4
+ /** @typedef {import("../services/discovery-probe-service.js").DiscoveryCandidateRow} DiscoveryCandidateRow */
5
+ /** @typedef {import("../services/discovery-probe-service.js").DiscoveryProbeService} DiscoveryProbeService */
6
+
7
+ export const DISCOVERY_CANDIDATES_QUERY = "onboarding.discovery.v1";
8
+
9
+ /**
10
+ * @param {Pick<DiscoveryProbeService, "snapshot">} service
11
+ * @returns {LiveQueryDefinition<unknown, DiscoveryCandidateRow>}
12
+ */
13
+ export function createDiscoveryCandidatesQuery(service) {
14
+ return {
15
+ invalidateOn: ["domain.entity-changed"],
16
+ key: (row) => row.address,
17
+ name: DISCOVERY_CANDIDATES_QUERY,
18
+ requiresDurableStorage: false,
19
+ run: async (params) => {
20
+ parseEmptyParams(params);
21
+ return service.snapshot();
22
+ },
23
+ };
24
+ }
25
+
26
+ /**
27
+ * @param {unknown} value
28
+ * @returns {void}
29
+ */
30
+ function parseEmptyParams(value) {
31
+ if (value === null || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== 0) {
32
+ throw new TypeError("Onboarding discovery query does not accept parameters");
33
+ }
34
+ }
@@ -1,3 +1,20 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @typedef {import("@econ-v1/ports").NotificationListParams} NotificationListParams
5
+ */
6
+ /**
7
+ * @typedef {import("@econ-v1/ports").NotificationRepository} NotificationRepository
8
+ */
9
+ /**
10
+ * @template TParams
11
+ * @template TRow
12
+ * @typedef {import("../models/live-query-definition.js").LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition
13
+ */
14
+ /**
15
+ * @param {Pick<NotificationRepository, "listNotifications">} repository
16
+ * @returns {LiveQueryDefinition<NotificationListParams, Awaited<ReturnType<NotificationRepository["listNotifications"]>>[number]>}
17
+ */
1
18
  export function createNotificationsQuery(repository) {
2
19
  return {
3
20
  invalidateOn: ["domain.entity-changed", "sync.delta-applied"],
@@ -6,10 +23,14 @@ export function createNotificationsQuery(repository) {
6
23
  run: async (params) => await repository.listNotifications(parseNotificationListParams(params)),
7
24
  };
8
25
  }
26
+ /**
27
+ * @param {unknown} value
28
+ * @returns {NotificationListParams}
29
+ */
9
30
  export function parseNotificationListParams(value) {
10
31
  if (value === null || typeof value !== "object" || Array.isArray(value))
11
32
  throw invalid();
12
- const record = value;
33
+ const record = /** @type {Record<string, unknown>} */ (value);
13
34
  if (Object.keys(record).some((key) => !["limit", "unreadOnly"].includes(key)))
14
35
  throw invalid();
15
36
  if (record.limit !== undefined && (typeof record.limit !== "number" || !Number.isInteger(record.limit) || record.limit < 1 || record.limit > 100))
@@ -21,7 +42,9 @@ export function parseNotificationListParams(value) {
21
42
  ...(record.unreadOnly === undefined ? {} : { unreadOnly: record.unreadOnly }),
22
43
  };
23
44
  }
45
+ /**
46
+ * @returns {TypeError}
47
+ */
24
48
  function invalid() {
25
49
  return new TypeError("Invalid notifications query parameters");
26
50
  }
27
- //# sourceMappingURL=notifications.js.map
@@ -0,0 +1,48 @@
1
+ // @ts-check
2
+ /** @template TParams @template TRow @typedef {import('../models/live-query-definition.js').LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition */
3
+ /** @typedef {import('../services/onboarding-flow-service.js').OnboardingFlowRow} OnboardingFlowRow */
4
+ /** @typedef {import('../services/onboarding-flow-service.js').OnboardingFlowService} OnboardingFlowService */
5
+ export const ONBOARDING_FLOW_QUERY_NAME = "onboarding.flow.v1";
6
+ /**
7
+ * The live view behind the `onboarding.flow.v1` seam
8
+ * (`client/rpc/src/onboarding/onboarding-contract.ts`).
9
+ *
10
+ * `requiresDurableStorage: false`: `OnboardingFlowService.view()` is an in-memory derivation,
11
+ * never the OPFS-backed local SQLite cache, so this stays queryable before the device is
12
+ * claimed/paired — the same rationale as `onboarding.status.v1` and `onboarding.discovery.v1`.
13
+ *
14
+ * `invalidateOn` names exactly one event, and that is load-bearing: `LiveQueryEngine` fires a
15
+ * subscription ONLY when `definition.invalidateOn.includes(event.type)`, so every transition
16
+ * the service makes must publish `onboarding.flow-changed` or no surface ever re-reads. The
17
+ * single constant key is what turns a changed projection into an `updated` diff rather than a
18
+ * delete/add pair (`diffRows` compares by key, then structurally).
19
+ * @param {Pick<OnboardingFlowService, "view">} service
20
+ * @returns {LiveQueryDefinition<unknown, OnboardingFlowRow>}
21
+ */
22
+ export function createOnboardingFlowQuery(service) {
23
+ return {
24
+ invalidateOn: ["onboarding.flow-changed"],
25
+ key: () => "onboarding-flow",
26
+ name: ONBOARDING_FLOW_QUERY_NAME,
27
+ requiresDurableStorage: false,
28
+ run: async (params) => {
29
+ parseEmptyParams(params);
30
+ return [service.view()];
31
+ },
32
+ };
33
+ }
34
+ /**
35
+ * @param {unknown} value
36
+ * @returns {void}
37
+ */
38
+ function parseEmptyParams(value) {
39
+ if (
40
+ value === null ||
41
+ typeof value !== "object" ||
42
+ Array.isArray(value) ||
43
+ Object.keys(value).length !== 0
44
+ ) {
45
+ throw new TypeError("Onboarding flow query does not accept parameters");
46
+ }
47
+ }
48
+ // @ts-check
@@ -0,0 +1,100 @@
1
+ // @ts-check
2
+ /** @typedef {import('@econ-v1/ports').LcdTreeNode} LcdTreeNode */
3
+ /** @typedef {import('@econ-v1/ports').LcdTreeOutcome} LcdTreeOutcome */
4
+ /** @typedef {import('@econ-v1/ports').LcdTreeSourcePort} LcdTreeSourcePort */
5
+ /** @template TParams @template TRow @typedef {import('../models/live-query-definition.js').LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition */
6
+ /** @typedef {import('../services/onboarding-flow-service.js').OnboardingFlowLcdScreenId} OnboardingFlowLcdScreenId */
7
+ /** @typedef {import('../services/onboarding-flow-service.js').OnboardingFlowService} OnboardingFlowService */
8
+ export const ONBOARDING_LCD_SCREEN_QUERY_NAME = "onboarding.lcd-screen.v1";
9
+ /**
10
+ * Screen ids the node's LCD app has no `build()` for. Empty: `onboard_home_qr` and
11
+ * `onboard_working`, the last two ids that needed this short-circuit, now have native screens
12
+ * in node-app-lcd (`modules/node-app-lcd/src/lcd/app/screens/`), so every onboarding screen
13
+ * goes through the port. Kept as an empty array — rather than deleted — so a future screen
14
+ * shipped without a Rust `build()` has an obvious, already-wired place to land.
15
+ * @type {readonly OnboardingFlowLcdScreenId[]}
16
+ */
17
+ /** @type {readonly OnboardingFlowLcdScreenId[]} */
18
+ const AUTHORED_SCREEN_IDS = [];
19
+ /**
20
+ * The live view behind the `onboarding.lcd-screen.v1` seam
21
+ * (`ONBOARDING_LCD_SCREEN_QUERY`, `client/rpc/src/onboarding/onboarding-contract.ts`).
22
+ *
23
+ * `run()` MUST NOT REJECT. `LiveQueryEngine.#enqueue` does `void run.catch(() => undefined)`,
24
+ * so a rejection never reaches the subscriber: the pane would sit on a stale screen forever
25
+ * with no error and no retry. Every failure is therefore a row. The one deliberate exception is
26
+ * a malformed `params`, which is a programming error at the call site, cannot be recovered from
27
+ * by retrying, and surfaces synchronously through the engine's one-shot `query()` path — the
28
+ * same trade `createOnboardingFlowQuery` already makes.
29
+ *
30
+ * `requiresDurableStorage: false`: this runs on an unclaimed node with no OPFS cache at all,
31
+ * the same rationale as `onboarding.flow.v1`.
32
+ *
33
+ * `invalidateOn` names exactly one event, and it is the SAME event the flow query uses. That is
34
+ * intentional: the screen the LCD shows is a function of the step, so anything that changes the
35
+ * step changes this — including the 1 Hz `tick()` that drives the code screen's countdown ring.
36
+ * @param {Pick<OnboardingFlowService, "lcdScreen">} service
37
+ * @param {LcdTreeSourcePort} source
38
+ * @returns {LiveQueryDefinition<unknown, OnboardingLcdScreenRow>}
39
+ */
40
+ export function createOnboardingLcdScreenQuery(service, source) {
41
+ return {
42
+ invalidateOn: ["onboarding.flow-changed"],
43
+ key: () => "onboarding-lcd-screen",
44
+ name: ONBOARDING_LCD_SCREEN_QUERY_NAME,
45
+ requiresDurableStorage: false,
46
+ run: async (params) => {
47
+ parseEmptyParams(params);
48
+ const screen = service.lcdScreen();
49
+ if (AUTHORED_SCREEN_IDS.includes(screen.screenId)) {
50
+ return [{ ...screen, kind: "authored" }];
51
+ }
52
+ /** @type {LcdTreeOutcome} */
53
+ let outcome;
54
+ try {
55
+ outcome = await source.screen(screen.screenId, screen.state);
56
+ } catch {
57
+ // The port's contract says it cannot throw. Belt and braces: a port that breaks its
58
+ // contract must degrade the PANE, never freeze it, and must not leak its error text.
59
+ return [{ ...screen, kind: "unavailable", reason: "unreachable" }];
60
+ }
61
+ if (outcome.kind === "tree")
62
+ return [{ ...screen, kind: "tree", tree: outcome.tree }];
63
+ return [{ ...screen, kind: "unavailable", reason: outcome.kind }];
64
+ },
65
+ };
66
+ }
67
+ /**
68
+ * @param {unknown} value
69
+ * @returns {void}
70
+ */
71
+ function parseEmptyParams(value) {
72
+ if (
73
+ value === null ||
74
+ typeof value !== "object" ||
75
+ Array.isArray(value) ||
76
+ Object.keys(value).length !== 0
77
+ ) {
78
+ throw new TypeError(
79
+ "Onboarding LCD screen query does not accept parameters",
80
+ );
81
+ }
82
+ }
83
+ /** Structural twin of `client/rpc`'s `OnboardingLcdScreenView`; the arrow cannot be reversed
84
+ * (rpc depends on domain). Assignability is asserted for real in
85
+ * `client/kernel/src/onboarding/onboarding-flow-command-dispatcher.test.ts`.
86
+ * @typedef {| (OnboardingLcdScreenRowBase & { readonly kind: "authored" })
87
+ * | (OnboardingLcdScreenRowBase & { readonly kind: "tree"; readonly tree: LcdTreeNode })
88
+ * | (OnboardingLcdScreenRowBase & {
89
+ * readonly kind: "unavailable";
90
+ * readonly reason: "not-registered" | "unreachable";
91
+ * })} OnboardingLcdScreenRow
92
+ */
93
+ /**
94
+ * @typedef {object} OnboardingLcdScreenRowBase
95
+ * @property {boolean} awaitingNode
96
+ * @property {boolean} physicalTapOnly
97
+ * @property {OnboardingFlowLcdScreenId} screenId
98
+ * @property {Readonly<Record<string, number | string>>} state
99
+ */
100
+ // @ts-check
@@ -0,0 +1,34 @@
1
+ // @ts-check
2
+
3
+ /** @template TParams @template TRow @typedef {import("../models/live-query-definition.js").LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition */
4
+ /** @typedef {import("../services/onboarding-status-service.js").OnboardingLifecycleStatusRow} OnboardingLifecycleStatusRow */
5
+ /** @typedef {import("../services/onboarding-status-service.js").OnboardingStatusService} OnboardingStatusService */
6
+
7
+ export const ONBOARDING_STATUS_QUERY = "onboarding.status.v1";
8
+
9
+ /**
10
+ * @param {Pick<OnboardingStatusService, "status">} service
11
+ * @returns {LiveQueryDefinition<unknown, OnboardingLifecycleStatusRow>}
12
+ */
13
+ export function createOnboardingStatusQuery(service) {
14
+ return {
15
+ invalidateOn: ["domain.entity-changed"],
16
+ key: (row) => row.id,
17
+ name: ONBOARDING_STATUS_QUERY,
18
+ requiresDurableStorage: false,
19
+ run: async (params) => {
20
+ parseEmptyParams(params);
21
+ return [await service.status()];
22
+ },
23
+ };
24
+ }
25
+
26
+ /**
27
+ * @param {unknown} value
28
+ * @returns {void}
29
+ */
30
+ function parseEmptyParams(value) {
31
+ if (value === null || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== 0) {
32
+ throw new TypeError("Onboarding status query does not accept parameters");
33
+ }
34
+ }
@@ -0,0 +1,128 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @typedef {import("../models/json.js").JsonValue} JsonValue
5
+ */
6
+ /**
7
+ * @template TValue
8
+ * @typedef {import("../models/sync.js").RevisionEntity<TValue>} RevisionEntity
9
+ */
10
+ /**
11
+ * @template TParams
12
+ * @template TRow
13
+ * @typedef {import("../models/live-query-definition.js").LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition
14
+ */
15
+ /**
16
+ * @template {JsonValue} [TValue=import("../models/json.js").JsonValue]
17
+ * @typedef {{ list(): Promise<readonly RevisionEntity<TValue>[]>; read(id: string): Promise<RevisionEntity<TValue> | undefined>; }} RevisionedListRepository
18
+ */
19
+ import { DomainError } from "../errors/index.js";
20
+ /**
21
+ * @template {JsonValue} TValue
22
+ * @param {Pick<RevisionedListRepository<TValue>, "list">} repository
23
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
24
+ */
25
+ export function createAgentListQuery(repository) {
26
+ return createListQuery("agents.list.v1", repository);
27
+ }
28
+ /**
29
+ * @template {JsonValue} TValue
30
+ * @param {Pick<RevisionedListRepository<TValue>, "read">} repository
31
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
32
+ */
33
+ export function createAgentDetailQuery(repository) {
34
+ return createDetailQuery("agents.detail.v1", repository);
35
+ }
36
+ /**
37
+ * @template {JsonValue} TValue
38
+ * @param {Pick<RevisionedListRepository<TValue>, "list">} repository
39
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
40
+ */
41
+ export function createSettingsRevisionedListQuery(repository) {
42
+ return createListQuery("settings.revisioned-list.v1", repository);
43
+ }
44
+ /**
45
+ * @template {JsonValue} TValue
46
+ * @param {Pick<RevisionedListRepository<TValue>, "read">} repository
47
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
48
+ */
49
+ export function createSettingDetailQuery(repository) {
50
+ return createDetailQuery("settings.revisioned-detail.v1", repository);
51
+ }
52
+ /**
53
+ * @template {JsonValue} TValue
54
+ * @param {Pick<RevisionedListRepository<TValue>, "list">} repository
55
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
56
+ */
57
+ export function createGraphListQuery(repository) {
58
+ return createListQuery("graphs.list.v1", repository);
59
+ }
60
+ /**
61
+ * @template {JsonValue} TValue
62
+ * @param {Pick<RevisionedListRepository<TValue>, "read">} repository
63
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
64
+ */
65
+ export function createGraphDetailQuery(repository) {
66
+ return createDetailQuery("graphs.detail.v1", repository);
67
+ }
68
+ /**
69
+ * @param {unknown} value
70
+ * @returns {{ readonly id: string }}
71
+ */
72
+ export function parseRevisionDetailParams(value) {
73
+ if (value === null || typeof value !== "object" || Array.isArray(value))
74
+ throw invalid();
75
+ const record = /** @type {Record<string, unknown>} */ (value);
76
+ if (Object.keys(record).length !== 1 || typeof record.id !== "string" || record.id.trim() === "")
77
+ throw invalid();
78
+ return { id: record.id };
79
+ }
80
+ /**
81
+ * @template {JsonValue} TValue
82
+ * @param {`${string}.v${number}`} name
83
+ * @param {Pick<RevisionedListRepository<TValue>, "list">} repository
84
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
85
+ */
86
+ function createListQuery(name, repository) {
87
+ return {
88
+ invalidateOn: ["domain.entity-changed", "outbox.state-changed", "sync.delta-applied"],
89
+ key: (row) => row.id,
90
+ name,
91
+ run: async (params) => {
92
+ parseEmptyParams(params);
93
+ return await repository.list();
94
+ },
95
+ };
96
+ }
97
+ /**
98
+ * @template {JsonValue} TValue
99
+ * @param {`${string}.v${number}`} name
100
+ * @param {Pick<RevisionedListRepository<TValue>, "read">} repository
101
+ * @returns {LiveQueryDefinition<unknown, RevisionEntity<TValue>>}
102
+ */
103
+ function createDetailQuery(name, repository) {
104
+ return {
105
+ invalidateOn: ["domain.entity-changed", "outbox.state-changed", "sync.delta-applied"],
106
+ key: (row) => row.id,
107
+ name,
108
+ run: async (params) => {
109
+ const record = await repository.read(parseRevisionDetailParams(params).id);
110
+ return record === undefined ? [] : [record];
111
+ },
112
+ };
113
+ }
114
+ /**
115
+ * @param {unknown} value
116
+ * @returns {void}
117
+ */
118
+ function parseEmptyParams(value) {
119
+ if (value === null || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== 0) {
120
+ throw new DomainError({ code: "invalid_request", message: "Invalid revision list query parameters" });
121
+ }
122
+ }
123
+ /**
124
+ * @returns {DomainError}
125
+ */
126
+ function invalid() {
127
+ return new DomainError({ code: "invalid_request", message: "Invalid revision detail parameters" });
128
+ }
@@ -1,6 +1,29 @@
1
+ // @ts-check
2
+
3
+ /**
4
+ * @template TParams
5
+ * @template TRow
6
+ * @typedef {import("../models/live-query-definition.js").LiveQueryDefinition<TParams, TRow>} LiveQueryDefinition
7
+ */
8
+ /**
9
+ * @typedef {import("../models/wallet.js").WalletBalanceView} WalletBalanceView
10
+ */
11
+ /**
12
+ * @typedef {import("../models/wallet.js").PaymentHistoryView} PaymentHistoryView
13
+ */
14
+ /**
15
+ * @typedef {import("../models/l402.js").L402HistoryView} L402HistoryView
16
+ */
17
+ /**
18
+ * @typedef {import("../services/wallet-mirror-service.js").WalletMirrorService} WalletMirrorService
19
+ */
1
20
  export const WALLET_BALANCE_QUERY = "wallet.balance.v1";
2
21
  export const PAYMENT_HISTORY_QUERY = "payments.history.v1";
3
22
  export const L402_HISTORY_QUERY = "l402.history.v1";
23
+ /**
24
+ * @param {Pick<WalletMirrorService, "readBalance">} service
25
+ * @returns {LiveQueryDefinition<unknown, WalletBalanceView>}
26
+ */
4
27
  export function createWalletBalanceQuery(service) {
5
28
  return {
6
29
  invalidateOn: ["domain.entity-changed", "outbox.state-changed", "sync.delta-applied"],
@@ -12,6 +35,10 @@ export function createWalletBalanceQuery(service) {
12
35
  },
13
36
  };
14
37
  }
38
+ /**
39
+ * @param {Pick<WalletMirrorService, "listPayments">} service
40
+ * @returns {LiveQueryDefinition<unknown, PaymentHistoryView>}
41
+ */
15
42
  export function createPaymentHistoryQuery(service) {
16
43
  return {
17
44
  invalidateOn: ["domain.entity-changed", "outbox.state-changed", "sync.delta-applied"],
@@ -23,6 +50,10 @@ export function createPaymentHistoryQuery(service) {
23
50
  },
24
51
  };
25
52
  }
53
+ /**
54
+ * @param {Pick<WalletMirrorService, "listL402Receipts">} service
55
+ * @returns {LiveQueryDefinition<unknown, L402HistoryView>}
56
+ */
26
57
  export function createL402HistoryQuery(service) {
27
58
  return {
28
59
  invalidateOn: ["domain.entity-changed", "outbox.state-changed", "sync.delta-applied"],
@@ -34,9 +65,12 @@ export function createL402HistoryQuery(service) {
34
65
  },
35
66
  };
36
67
  }
68
+ /**
69
+ * @param {unknown} value
70
+ * @returns {void}
71
+ */
37
72
  function parseEmptyParams(value) {
38
73
  if (value === null || typeof value !== "object" || Array.isArray(value) || Object.keys(value).length !== 0) {
39
74
  throw new TypeError("Wallet queries do not accept parameters");
40
75
  }
41
76
  }
42
- //# sourceMappingURL=wallet.js.map