@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.
- package/dist/errors/index.d.ts +96 -25
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/events/index.d.ts +127 -20
- package/dist/events/index.d.ts.map +1 -1
- package/dist/index.d.ts +250 -47
- package/dist/index.d.ts.map +1 -1
- package/dist/models/agent.d.ts +25 -4
- package/dist/models/agent.d.ts.map +1 -1
- package/dist/models/app-data.d.ts +84 -0
- package/dist/models/app-data.d.ts.map +1 -0
- package/dist/models/conversation.d.ts +12 -2
- package/dist/models/conversation.d.ts.map +1 -1
- package/dist/models/delegation.d.ts +12 -3
- package/dist/models/delegation.d.ts.map +1 -1
- package/dist/models/device-boot-state.d.ts +12 -0
- package/dist/models/device-boot-state.d.ts.map +1 -0
- package/dist/models/device-identity.d.ts +11 -3
- package/dist/models/device-identity.d.ts.map +1 -1
- package/dist/models/graph.d.ts +26 -3
- package/dist/models/graph.d.ts.map +1 -1
- package/dist/models/index.d.ts +82 -14
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/json.d.ts +5 -5
- package/dist/models/json.d.ts.map +1 -1
- package/dist/models/l402.d.ts +4 -5
- package/dist/models/l402.d.ts.map +1 -1
- package/dist/models/live-query-definition.d.ts +15 -16
- package/dist/models/live-query-definition.d.ts.map +1 -1
- package/dist/models/node-app-memory.d.ts +107 -0
- package/dist/models/node-app-memory.d.ts.map +1 -0
- package/dist/models/outbox-intent.d.ts +3 -3
- package/dist/models/outbox-intent.d.ts.map +1 -1
- package/dist/models/outbox.d.ts +67 -15
- package/dist/models/outbox.d.ts.map +1 -1
- package/dist/models/owner-views.d.ts +28 -28
- package/dist/models/owner-views.d.ts.map +1 -1
- package/dist/models/payment.d.ts +28 -9
- package/dist/models/payment.d.ts.map +1 -1
- package/dist/models/query-diff.d.ts +2 -2
- package/dist/models/query-diff.d.ts.map +1 -1
- package/dist/models/release-manifest.d.ts +32 -47
- package/dist/models/release-manifest.d.ts.map +1 -1
- package/dist/models/repository-write.d.ts +3 -3
- package/dist/models/repository-write.d.ts.map +1 -1
- package/dist/models/revisioned-commands.d.ts +66 -13
- package/dist/models/revisioned-commands.d.ts.map +1 -1
- package/dist/models/revisioned.d.ts +50 -10
- package/dist/models/revisioned.d.ts.map +1 -1
- package/dist/models/settings.d.ts +2 -2
- package/dist/models/settings.d.ts.map +1 -1
- package/dist/models/sync.d.ts +18 -18
- package/dist/models/sync.d.ts.map +1 -1
- package/dist/models/wallet.d.ts +16 -16
- package/dist/models/wallet.d.ts.map +1 -1
- package/dist/queries/certificate-trust.d.ts +13 -0
- package/dist/queries/certificate-trust.d.ts.map +1 -0
- package/dist/queries/conversations.d.ts +38 -7
- package/dist/queries/conversations.d.ts.map +1 -1
- package/dist/queries/discovery.d.ts +10 -10
- package/dist/queries/discovery.d.ts.map +1 -1
- package/dist/queries/notifications.d.ts +24 -4
- package/dist/queries/notifications.d.ts.map +1 -1
- package/dist/queries/onboarding-flow.d.ts +25 -0
- package/dist/queries/onboarding-flow.d.ts.map +1 -0
- package/dist/queries/onboarding-lcd-screen.d.ts +56 -0
- package/dist/queries/onboarding-lcd-screen.d.ts.map +1 -0
- package/dist/queries/onboarding-status.d.ts +10 -10
- package/dist/queries/onboarding-status.d.ts.map +1 -1
- package/dist/queries/revisioned.d.ts +47 -13
- package/dist/queries/revisioned.d.ts.map +1 -1
- package/dist/queries/wallet.d.ts +40 -10
- package/dist/queries/wallet.d.ts.map +1 -1
- package/dist/services/abort-signal.d.ts +54 -0
- package/dist/services/abort-signal.d.ts.map +1 -0
- package/dist/services/certificate-trust-service.d.ts +42 -0
- package/dist/services/certificate-trust-service.d.ts.map +1 -0
- package/dist/services/conversation-service.d.ts +103 -15
- package/dist/services/conversation-service.d.ts.map +1 -1
- package/dist/services/conversation-sync.d.ts +9 -5
- package/dist/services/conversation-sync.d.ts.map +1 -1
- package/dist/services/device-boot-state-service.d.ts +17 -0
- package/dist/services/device-boot-state-service.d.ts.map +1 -0
- package/dist/services/device-cleanup-service.d.ts +47 -0
- package/dist/services/device-cleanup-service.d.ts.map +1 -0
- package/dist/services/discovery-probe-service.d.ts +37 -46
- package/dist/services/discovery-probe-service.d.ts.map +1 -1
- package/dist/services/gossip-service.d.ts +28 -13
- package/dist/services/gossip-service.d.ts.map +1 -1
- package/dist/services/invite-redemption-service.d.ts +43 -0
- package/dist/services/invite-redemption-service.d.ts.map +1 -0
- package/dist/services/lan-candidate-refresh-service.d.ts +22 -7
- package/dist/services/lan-candidate-refresh-service.d.ts.map +1 -1
- package/dist/services/lcd-decision-service.d.ts +58 -0
- package/dist/services/lcd-decision-service.d.ts.map +1 -0
- package/dist/services/onboarding-checkpoint-store.d.ts +54 -0
- package/dist/services/onboarding-checkpoint-store.d.ts.map +1 -0
- package/dist/services/onboarding-flow-service.d.ts +180 -0
- package/dist/services/onboarding-flow-service.d.ts.map +1 -0
- package/dist/services/onboarding-status-service.d.ts +21 -38
- package/dist/services/onboarding-status-service.d.ts.map +1 -1
- package/dist/services/outbox-service.d.ts +105 -29
- package/dist/services/outbox-service.d.ts.map +1 -1
- package/dist/services/owner-claim-service.d.ts +187 -0
- package/dist/services/owner-claim-service.d.ts.map +1 -0
- package/dist/services/owner-view-refresh-service.d.ts +40 -0
- package/dist/services/owner-view-refresh-service.d.ts.map +1 -0
- package/dist/services/owner-view-service.d.ts +49 -4
- package/dist/services/owner-view-service.d.ts.map +1 -1
- package/dist/services/peer-directory-service.d.ts +53 -17
- package/dist/services/peer-directory-service.d.ts.map +1 -1
- package/dist/services/release-manifest-verifier.d.ts +18 -20
- package/dist/services/release-manifest-verifier.d.ts.map +1 -1
- package/dist/services/revisioned-domain-service.d.ts +50 -17
- package/dist/services/revisioned-domain-service.d.ts.map +1 -1
- package/dist/services/runtime-globals.d.ts +39 -0
- package/dist/services/runtime-globals.d.ts.map +1 -0
- package/dist/services/session-service.d.ts +23 -3
- package/dist/services/session-service.d.ts.map +1 -1
- package/dist/services/sync/authoritative-mirror.d.ts +88 -15
- package/dist/services/sync/authoritative-mirror.d.ts.map +1 -1
- package/dist/services/sync/index.d.ts +17 -5
- package/dist/services/sync/index.d.ts.map +1 -1
- package/dist/services/sync/log-sync.d.ts +42 -8
- package/dist/services/sync/log-sync.d.ts.map +1 -1
- package/dist/services/sync/revision-merge.d.ts +80 -13
- package/dist/services/sync/revision-merge.d.ts.map +1 -1
- package/dist/services/sync/strategy.d.ts +11 -1
- package/dist/services/sync/strategy.d.ts.map +1 -1
- package/dist/services/transport-manager.d.ts +84 -29
- package/dist/services/transport-manager.d.ts.map +1 -1
- package/dist/services/wallet-mirror-service.d.ts +81 -18
- package/dist/services/wallet-mirror-service.d.ts.map +1 -1
- package/dist/services/wifi-provisioning-service.d.ts +146 -0
- package/dist/services/wifi-provisioning-service.d.ts.map +1 -0
- package/package.json +18 -12
- package/src/errors/index.js +126 -0
- package/src/events/index.js +124 -0
- package/src/index.js +566 -0
- package/src/models/agent.js +43 -0
- package/src/models/app-data.js +122 -0
- package/src/models/conversation.js +36 -0
- package/{dist → src}/models/delegation.js +18 -1
- package/src/models/device-boot-state.js +3 -0
- package/{dist → src}/models/device-identity.js +18 -2
- package/{dist → src}/models/graph.js +30 -3
- package/src/models/index.js +175 -0
- package/src/models/json.js +18 -0
- package/src/models/l402.js +9 -0
- package/src/models/live-query-definition.js +30 -0
- package/src/models/node-app-memory.js +130 -0
- package/src/models/outbox-intent.js +12 -0
- package/{dist → src}/models/outbox.js +102 -3
- package/src/models/owner-views.js +59 -0
- package/src/models/payment.js +24 -0
- package/src/models/query-diff.js +7 -0
- package/src/models/release-manifest.js +160 -0
- package/src/models/repository-write.js +10 -0
- package/src/models/revisioned-commands.js +92 -0
- package/src/models/revisioned.js +41 -0
- package/src/models/settings.js +16 -0
- package/src/models/sync.js +44 -0
- package/src/models/wallet.js +40 -0
- package/src/queries/certificate-trust.js +31 -0
- package/{dist → src}/queries/conversations.js +54 -3
- package/src/queries/discovery.js +34 -0
- package/{dist → src}/queries/notifications.js +25 -2
- package/src/queries/onboarding-flow.js +48 -0
- package/src/queries/onboarding-lcd-screen.js +100 -0
- package/src/queries/onboarding-status.js +34 -0
- package/src/queries/revisioned.js +128 -0
- package/{dist → src}/queries/wallet.js +35 -1
- package/src/services/abort-signal.js +69 -0
- package/src/services/certificate-trust-service.js +119 -0
- package/{dist → src}/services/conversation-service.js +108 -1
- package/src/services/conversation-sync.js +28 -0
- package/src/services/device-boot-state-service.js +45 -0
- package/src/services/device-cleanup-service.js +112 -0
- package/src/services/discovery-probe-service.js +196 -0
- package/{dist → src}/services/gossip-service.js +54 -4
- package/src/services/invite-redemption-service.js +64 -0
- package/src/services/lan-candidate-refresh-service.js +164 -0
- package/src/services/lcd-decision-service.js +93 -0
- package/src/services/onboarding-checkpoint-store.js +155 -0
- package/src/services/onboarding-flow-service.js +1096 -0
- package/src/services/onboarding-status-service.js +64 -0
- package/{dist → src}/services/outbox-service.js +132 -1
- package/src/services/owner-claim-service.js +347 -0
- package/src/services/owner-view-refresh-service.js +208 -0
- package/src/services/owner-view-service.js +87 -0
- package/{dist → src}/services/peer-directory-service.js +72 -3
- package/src/services/release-manifest-verifier.js +108 -0
- package/{dist → src}/services/revisioned-domain-service.js +189 -9
- package/src/services/runtime-globals.js +174 -0
- package/src/services/session-service.js +50 -0
- package/{dist → src}/services/sync/authoritative-mirror.js +90 -1
- package/src/services/sync/index.js +67 -0
- package/src/services/sync/log-sync.js +60 -0
- package/src/services/sync/revision-merge.js +119 -0
- package/src/services/sync/strategy.js +44 -0
- package/src/services/transport-manager.js +478 -0
- package/{dist → src}/services/wallet-mirror-service.js +226 -6
- package/src/services/wifi-provisioning-service.js +278 -0
- package/dist/errors/index.js +0 -45
- package/dist/errors/index.js.map +0 -1
- package/dist/events/index.js +0 -17
- package/dist/events/index.js.map +0 -1
- package/dist/index.js +0 -31
- package/dist/index.js.map +0 -1
- package/dist/models/agent.js +0 -17
- package/dist/models/agent.js.map +0 -1
- package/dist/models/conversation.js +0 -2
- package/dist/models/conversation.js.map +0 -1
- package/dist/models/delegation.js.map +0 -1
- package/dist/models/device-identity.js.map +0 -1
- package/dist/models/graph.js.map +0 -1
- package/dist/models/index.js +0 -8
- package/dist/models/index.js.map +0 -1
- package/dist/models/json.js +0 -2
- package/dist/models/json.js.map +0 -1
- package/dist/models/l402.js +0 -2
- package/dist/models/l402.js.map +0 -1
- package/dist/models/live-query-definition.js +0 -2
- package/dist/models/live-query-definition.js.map +0 -1
- package/dist/models/outbox-intent.js +0 -2
- package/dist/models/outbox-intent.js.map +0 -1
- package/dist/models/outbox.js.map +0 -1
- package/dist/models/owner-views.js +0 -7
- package/dist/models/owner-views.js.map +0 -1
- package/dist/models/payment.js +0 -3
- package/dist/models/payment.js.map +0 -1
- package/dist/models/query-diff.js +0 -2
- package/dist/models/query-diff.js.map +0 -1
- package/dist/models/release-manifest.js +0 -147
- package/dist/models/release-manifest.js.map +0 -1
- package/dist/models/repository-write.js +0 -2
- package/dist/models/repository-write.js.map +0 -1
- package/dist/models/revisioned-commands.js +0 -35
- package/dist/models/revisioned-commands.js.map +0 -1
- package/dist/models/revisioned.js +0 -2
- package/dist/models/revisioned.js.map +0 -1
- package/dist/models/settings.js +0 -2
- package/dist/models/settings.js.map +0 -1
- package/dist/models/sync.js +0 -2
- package/dist/models/sync.js.map +0 -1
- package/dist/models/wallet.js +0 -2
- package/dist/models/wallet.js.map +0 -1
- package/dist/queries/conversations.js.map +0 -1
- package/dist/queries/discovery.js +0 -27
- package/dist/queries/discovery.js.map +0 -1
- package/dist/queries/notifications.js.map +0 -1
- package/dist/queries/onboarding-status.js +0 -27
- package/dist/queries/onboarding-status.js.map +0 -1
- package/dist/queries/revisioned.js +0 -58
- package/dist/queries/revisioned.js.map +0 -1
- package/dist/queries/wallet.js.map +0 -1
- package/dist/services/conversation-service.js.map +0 -1
- package/dist/services/conversation-sync.js +0 -9
- package/dist/services/conversation-sync.js.map +0 -1
- package/dist/services/discovery-probe-service.js +0 -129
- package/dist/services/discovery-probe-service.js.map +0 -1
- package/dist/services/gossip-service.js.map +0 -1
- package/dist/services/lan-candidate-refresh-service.js +0 -79
- package/dist/services/lan-candidate-refresh-service.js.map +0 -1
- package/dist/services/onboarding-status-service.js +0 -32
- package/dist/services/onboarding-status-service.js.map +0 -1
- package/dist/services/outbox-service.js.map +0 -1
- package/dist/services/owner-view-service.js +0 -21
- package/dist/services/owner-view-service.js.map +0 -1
- package/dist/services/peer-directory-service.js.map +0 -1
- package/dist/services/release-manifest-verifier.js +0 -84
- package/dist/services/release-manifest-verifier.js.map +0 -1
- package/dist/services/revisioned-domain-service.js.map +0 -1
- package/dist/services/session-service.js +0 -20
- package/dist/services/session-service.js.map +0 -1
- package/dist/services/sync/authoritative-mirror.js.map +0 -1
- package/dist/services/sync/index.js +0 -4
- package/dist/services/sync/index.js.map +0 -1
- package/dist/services/sync/log-sync.js +0 -20
- package/dist/services/sync/log-sync.js.map +0 -1
- package/dist/services/sync/revision-merge.js +0 -46
- package/dist/services/sync/revision-merge.js.map +0 -1
- package/dist/services/sync/strategy.js +0 -2
- package/dist/services/sync/strategy.js.map +0 -1
- package/dist/services/transport-manager.js +0 -234
- package/dist/services/transport-manager.js.map +0 -1
- package/dist/services/wallet-mirror-service.js.map +0 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
export class WifiProvisioningService {
|
|
2
|
+
/**
|
|
3
|
+
* @param {WifiProvisioningServiceOptions} options
|
|
4
|
+
*/
|
|
5
|
+
constructor(options: WifiProvisioningServiceOptions);
|
|
6
|
+
/**
|
|
7
|
+
* @param {() => boolean} [shouldContinue]
|
|
8
|
+
* @returns {Promise<WifiReconnectOutcome>}
|
|
9
|
+
*/
|
|
10
|
+
awaitReconnect(shouldContinue?: () => boolean): Promise<WifiReconnectOutcome>;
|
|
11
|
+
/**
|
|
12
|
+
* Whether the node is ALREADY joined to a home network. Asked once at flow entry so a person
|
|
13
|
+
* who configured Wi-Fi on the node's own captive portal is never marched through the
|
|
14
|
+
* credential steps a second time — resubmitting working credentials is not idempotent on the
|
|
15
|
+
* node side (the join tears down and re-adds the connection) and a handshake flake in that
|
|
16
|
+
* window strands the node back in setup AP mode. The wire values are node-server's
|
|
17
|
+
* `http_status` PascalCase strings; only an explicit `"Connected"` counts.
|
|
18
|
+
* @returns {Promise<WifiStatusOutcome>}
|
|
19
|
+
*/
|
|
20
|
+
status(): Promise<WifiStatusOutcome>;
|
|
21
|
+
/** Lists what the node's radio can currently see. A failure is a first-class outcome, not a
|
|
22
|
+
* throw: step 4 stays on screen and offers "Scan again".
|
|
23
|
+
* @returns {Promise<WifiScanOutcome>}
|
|
24
|
+
*/
|
|
25
|
+
scan(): Promise<WifiScanOutcome>;
|
|
26
|
+
/**
|
|
27
|
+
* Hands the credentials to the node exactly once. `secret === undefined` means an open
|
|
28
|
+
* network, in which case the `password` key is omitted rather than sent as an empty string —
|
|
29
|
+
* the node validates length 8-63 whenever the field is present.
|
|
30
|
+
* @param {string} ssid
|
|
31
|
+
* @param {string | undefined} secret
|
|
32
|
+
* @returns {Promise<WifiConfigureOutcome>}
|
|
33
|
+
*/
|
|
34
|
+
configure(ssid: string, secret: string | undefined): Promise<WifiConfigureOutcome>;
|
|
35
|
+
/**
|
|
36
|
+
* Watches one configure operation across the network handoff. See the class comment: a
|
|
37
|
+
* thrown poll is EXPECTED and means "keep waiting".
|
|
38
|
+
*
|
|
39
|
+
* `deadline` is an absolute epoch-millisecond value from the same clock as `now`, supplied by
|
|
40
|
+
* the caller so a resumed flow can keep the ORIGINAL deadline rather than restarting it.
|
|
41
|
+
* @param {string} operationId
|
|
42
|
+
* @param {number} deadline
|
|
43
|
+
* @param {() => void} [onTransportLost]
|
|
44
|
+
* @returns {Promise<WifiHandoffOutcome>}
|
|
45
|
+
*/
|
|
46
|
+
awaitHandoff(operationId: string, deadline: number, onTransportLost?: () => void): Promise<WifiHandoffOutcome>;
|
|
47
|
+
#private;
|
|
48
|
+
}
|
|
49
|
+
export type DelayPort = import("@econ-v1/ports").DelayPort;
|
|
50
|
+
export type HomeNodeClient = import("@econ-v1/ports").HomeNodeClient;
|
|
51
|
+
/**
|
|
52
|
+
* The node's Wi-Fi provisioning surface, expressed as three operations with CLOSED outcome
|
|
53
|
+
* unions (design §10). Nothing here throws at its caller and nothing here returns node text:
|
|
54
|
+
* `OnboardingFlowService` turns these outcomes into `OnboardingReasonCode`s, and the UI turns
|
|
55
|
+
* those into copy. A raw `DomainError.message` reaching a subscriber would be both a leak and
|
|
56
|
+
* an unreviewable string in the product.
|
|
57
|
+
*
|
|
58
|
+
* THE CENTRAL DIFFICULTY is `awaitHandoff()`. Between `configure()` and the node reporting
|
|
59
|
+
* `Connected`, the node LEAVES its own access point and joins the home network — the browser
|
|
60
|
+
* that issued the request is on that access point, so the poll *is expected to fail*, possibly
|
|
61
|
+
* for the entire operation. A thrown request here therefore means "keep waiting", not "it
|
|
62
|
+
* broke"; only three things end the wait:
|
|
63
|
+
*
|
|
64
|
+
* - the node answering `Connected` -> "connected" (it came back, on the LAN)
|
|
65
|
+
* - the node answering `Failed` -> "credentials-rejected" (it came back to say no)
|
|
66
|
+
* - the deadline passing -> "unreachable" (step 7's manual way back)
|
|
67
|
+
*
|
|
68
|
+
* `Failed` is the ONLY signal that distinguishes a wrong password from a normal handoff, which
|
|
69
|
+
* is why it must not be collapsed into the generic failure branch: collapsing it would send a
|
|
70
|
+
* person who mistyped their password to "walk back to your node" instead of to the keyboard.
|
|
71
|
+
*
|
|
72
|
+
* The status strings are the node's, verified against
|
|
73
|
+
* `core/adapters-network/src/http/server/wifi.rs::http_operation_status`, which maps its
|
|
74
|
+
* internal states onto exactly `"Connected"` / `"Failed"` / `"Connecting"` / `"Pending"`.
|
|
75
|
+
* (The design doc's "Completed" is wrong; the wire value is "Connected".)
|
|
76
|
+
*
|
|
77
|
+
* SECURITY: `configure()` takes the secret as an argument and forwards it in a single request.
|
|
78
|
+
* It is never assigned to a field, never returned, never logged, and never included in an
|
|
79
|
+
* outcome — `WifiConfigureOutcome` has no field it could occupy.
|
|
80
|
+
*/
|
|
81
|
+
export type WifiProvisioningSecurity = "open" | "wep" | "wpa2" | "wpa3";
|
|
82
|
+
export type WifiScanOutcome = {
|
|
83
|
+
readonly kind: "scanned";
|
|
84
|
+
readonly networks: readonly WifiProvisioningNetwork[];
|
|
85
|
+
} | {
|
|
86
|
+
readonly kind: "scan-failed";
|
|
87
|
+
};
|
|
88
|
+
export type WifiConfigureOutcome = {
|
|
89
|
+
readonly kind: "accepted";
|
|
90
|
+
readonly operationId: string;
|
|
91
|
+
} | {
|
|
92
|
+
readonly kind: "credentials-rejected";
|
|
93
|
+
} | {
|
|
94
|
+
readonly kind: "unreachable";
|
|
95
|
+
};
|
|
96
|
+
export type WifiHandoffOutcome = "connected" | "credentials-rejected" | "unreachable";
|
|
97
|
+
export type WifiReconnectOutcome = "connected" | "superseded";
|
|
98
|
+
/**
|
|
99
|
+
* What the node's radio is doing RIGHT NOW, asked once at flow entry. `connected` carries the
|
|
100
|
+
* joined SSID so the flow can show which network needs no credentials. `unreachable` collapses
|
|
101
|
+
* every failure — a flow that cannot ask simply walks the ordinary Wi-Fi steps.
|
|
102
|
+
*/
|
|
103
|
+
export type WifiStatusOutcome = {
|
|
104
|
+
readonly kind: "connected";
|
|
105
|
+
readonly ssid: string;
|
|
106
|
+
} | {
|
|
107
|
+
readonly kind: "not-connected";
|
|
108
|
+
} | {
|
|
109
|
+
readonly kind: "unreachable";
|
|
110
|
+
};
|
|
111
|
+
export type WifiProvisioningNetwork = {
|
|
112
|
+
security: WifiProvisioningSecurity;
|
|
113
|
+
/**
|
|
114
|
+
* 0-100 signal quality. dBm never crosses this boundary.
|
|
115
|
+
*/
|
|
116
|
+
signal: number;
|
|
117
|
+
ssid: string;
|
|
118
|
+
};
|
|
119
|
+
export type WifiProvisioningServiceOptions = {
|
|
120
|
+
delay: Pick<DelayPort, "wait">;
|
|
121
|
+
node: Pick<HomeNodeClient, "invoke">;
|
|
122
|
+
/**
|
|
123
|
+
* Epoch milliseconds. Injected so the deadline is testable and domain owns no clock.
|
|
124
|
+
*/
|
|
125
|
+
now: () => number;
|
|
126
|
+
};
|
|
127
|
+
export type WifiScanRowWire = {
|
|
128
|
+
security?: unknown;
|
|
129
|
+
signal_quality_percent?: unknown;
|
|
130
|
+
ssid?: unknown;
|
|
131
|
+
};
|
|
132
|
+
export type WifiScanWire = {
|
|
133
|
+
networks?: readonly WifiScanRowWire[];
|
|
134
|
+
};
|
|
135
|
+
export type WifiConfigureWire = {
|
|
136
|
+
operation_id?: unknown;
|
|
137
|
+
success?: unknown;
|
|
138
|
+
};
|
|
139
|
+
export type WifiOperationStatusWire = {
|
|
140
|
+
status?: unknown;
|
|
141
|
+
};
|
|
142
|
+
export type WifiStatusWire = {
|
|
143
|
+
connection_status?: unknown;
|
|
144
|
+
current_ssid?: unknown;
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=wifi-provisioning-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wifi-provisioning-service.d.ts","sourceRoot":"","sources":["../../src/services/wifi-provisioning-service.js"],"names":[],"mappings":"AAOA;IAyBE;;OAEG;IACH,qBAFW,8BAA8B,EAMxC;IA/BD;;;OAGG;IACH,gCAHW,MAAM,OAAO,GACX,OAAO,CAAC,oBAAoB,CAAC,CASzC;IAqBD;;;;;;;;OAQG;IACH,UAFa,OAAO,CAAC,iBAAiB,CAAC,CAiBtC;IACD;;;OAGG;IACH,QAFa,OAAO,CAAC,eAAe,CAAC,CAwBpC;IACD;;;;;;;OAOG;IACH,gBAJW,MAAM,UACN,MAAM,GAAG,SAAS,GAChB,OAAO,CAAC,oBAAoB,CAAC,CA+BzC;IACD;;;;;;;;;;OAUG;IACH,0BALW,MAAM,YACN,MAAM,oBACN,MAAM,IAAI,GACR,OAAO,CAAC,kBAAkB,CAAC,CA2BvC;;CACF;wBAtKa,OAAO,gBAAgB,EAAE,SAAS;6BAClC,OAAO,gBAAgB,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uCA2NxC,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM;8BAG9B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAA;CAAE,GAC3F;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;mCAGxB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACnE;IAAE,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,GACzC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;iCAEzB,WAAW,GAAG,sBAAsB,GAAG,aAAa;mCACpD,WAAW,GAAG,YAAY;;;;;;gCAIzB;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAE,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;;cAIzB,wBAAwB;;;;YACxB,MAAM;UACN,MAAM;;;WAIN,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC;UACvB,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC;;;;SAC9B,MAAM,MAAM;;;eAIZ,OAAO;6BACP,OAAO;WACP,OAAO;;;eAIP,SAAS,eAAe,EAAE;;;mBAI1B,OAAO;cACP,OAAO;;;aAIP,OAAO;;;wBAIP,OAAO;mBACP,OAAO"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@econ-v1/domain",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.10.0",
|
|
4
4
|
"description": "Platform-neutral domain contracts and errors for Node clients",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "Node contributors",
|
|
@@ -17,31 +17,37 @@
|
|
|
17
17
|
"node-client",
|
|
18
18
|
"domain",
|
|
19
19
|
"contracts",
|
|
20
|
-
"
|
|
20
|
+
"javascript",
|
|
21
|
+
"jsdoc"
|
|
21
22
|
],
|
|
22
23
|
"type": "module",
|
|
23
|
-
"main": "./
|
|
24
|
+
"main": "./src/index.js",
|
|
24
25
|
"types": "./dist/index.d.ts",
|
|
25
26
|
"scripts": {
|
|
26
|
-
"build": "rm -rf dist && tsc -
|
|
27
|
+
"build": "rm -rf dist && tsc -p tsconfig.publish.json --pretty false",
|
|
28
|
+
"check": "node ../scripts/check-negative-type-contracts.mjs --config jsconfig.json",
|
|
29
|
+
"check:declarations": "node ../scripts/check-package-api-parity.mjs && node ../scripts/check-domain-declaration-shape.mjs",
|
|
27
30
|
"lint": "eslint src",
|
|
28
|
-
"prepack": "npm run build",
|
|
31
|
+
"prepack": "npm run build && node ../scripts/check-public-package.mjs .",
|
|
29
32
|
"test": "vitest run --passWithNoTests",
|
|
30
|
-
"
|
|
33
|
+
"check:consumer": "node ../scripts/check-negative-type-contracts.mjs --config jsconfig.consumer.json",
|
|
34
|
+
"type-check": "yarn run check && yarn check:declarations && yarn check:consumer"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"typescript": "~5.8.3"
|
|
31
38
|
},
|
|
32
39
|
"exports": {
|
|
33
40
|
".": {
|
|
34
41
|
"types": "./dist/index.d.ts",
|
|
35
|
-
"import": "./
|
|
36
|
-
"default": "./
|
|
42
|
+
"import": "./src/index.js",
|
|
43
|
+
"default": "./src/index.js"
|
|
37
44
|
}
|
|
38
45
|
},
|
|
39
46
|
"files": [
|
|
47
|
+
"src/**/*.js",
|
|
40
48
|
"dist/**/*.d.ts",
|
|
41
49
|
"dist/**/*.d.ts.map",
|
|
42
|
-
"
|
|
43
|
-
"dist/**/*.js.map",
|
|
44
|
-
"!dist/**/*.test.*"
|
|
50
|
+
"!src/**/*.test.js"
|
|
45
51
|
],
|
|
46
52
|
"sideEffects": false,
|
|
47
53
|
"engines": {
|
|
@@ -51,6 +57,6 @@
|
|
|
51
57
|
"access": "public"
|
|
52
58
|
},
|
|
53
59
|
"dependencies": {
|
|
54
|
-
"@econ-v1/ports": "6.
|
|
60
|
+
"@econ-v1/ports": "6.10.0"
|
|
55
61
|
}
|
|
56
62
|
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("../models/index.js").JsonObject} JsonObject
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {(typeof DOMAIN_ERROR_CODES)[number]} DomainErrorCode
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {(typeof SYNC_ERROR_CODES)[number]} SyncErrorCode
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {(typeof TRANSPORT_ERROR_CODES)[number]} TransportErrorCode
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @template {string} TCode
|
|
17
|
+
* @typedef {{ readonly code: TCode; readonly details?: JsonObject; readonly message: string; }} ErrorOptions
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* @template {string} TKind
|
|
21
|
+
* @template {string} TCode
|
|
22
|
+
* @typedef {{ readonly code: TCode; readonly details?: JsonObject; readonly kind: TKind; readonly message: string; }} SerializableError
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {DomainError | SyncError | TransportError} ClientError
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {| SerializableError<"domain", DomainErrorCode> | SerializableError<"sync", SyncErrorCode> | SerializableError<"transport", TransportErrorCode>} SerializableClientError
|
|
29
|
+
*/
|
|
30
|
+
/** @type {readonly ["access-code-invalid", "capability_not_declared", "code-already-bound", "conflict", "invalid_request", "not_found", "stage_composition_not_enabled", "unauthorized", "unsupported_query", "validation_failed"]} */
|
|
31
|
+
export const DOMAIN_ERROR_CODES = [
|
|
32
|
+
// Onboarding access-code rail (2026-08-10 design): the two envelope codes
|
|
33
|
+
// `onboarding-prepare` refuses with when a code-active node rejects a device's claim
|
|
34
|
+
// attempt — see `client/adapters-web/src/network/envelope-error-mapping.js`'s
|
|
35
|
+
// `CODE_ALREADY_BOUND`/`ACCESS_CODE_INVALID`/`ACCESS_CODE_REQUIRED` mapping and
|
|
36
|
+
// `OnboardingFlowService`'s matching `OnboardingFlowReasonCode` members.
|
|
37
|
+
"access-code-invalid",
|
|
38
|
+
"capability_not_declared",
|
|
39
|
+
"code-already-bound",
|
|
40
|
+
"conflict",
|
|
41
|
+
"invalid_request",
|
|
42
|
+
"not_found",
|
|
43
|
+
"stage_composition_not_enabled",
|
|
44
|
+
"unauthorized",
|
|
45
|
+
"unsupported_query",
|
|
46
|
+
"validation_failed",
|
|
47
|
+
];
|
|
48
|
+
/** @type {readonly ["outbox_delivery_failed", "sync_conflict", "sync_terminal_failure"]} */
|
|
49
|
+
export const SYNC_ERROR_CODES = ["outbox_delivery_failed", "sync_conflict", "sync_terminal_failure"];
|
|
50
|
+
/** @type {readonly ["connection_lost", "offline", "unavailable"]} */
|
|
51
|
+
export const TRANSPORT_ERROR_CODES = ["connection_lost", "offline", "unavailable"];
|
|
52
|
+
/**
|
|
53
|
+
* @abstract
|
|
54
|
+
* @template {string} TKind
|
|
55
|
+
* @template {string} TCode
|
|
56
|
+
* @extends {Error}
|
|
57
|
+
*/
|
|
58
|
+
class SerializableClientErrorBase extends Error {
|
|
59
|
+
/**
|
|
60
|
+
* @readonly
|
|
61
|
+
* @type {TKind}
|
|
62
|
+
*/
|
|
63
|
+
kind;
|
|
64
|
+
/**
|
|
65
|
+
* @readonly
|
|
66
|
+
* @type {TCode}
|
|
67
|
+
*/
|
|
68
|
+
code;
|
|
69
|
+
/**
|
|
70
|
+
* @readonly
|
|
71
|
+
* @type {JsonObject | undefined}
|
|
72
|
+
*/
|
|
73
|
+
details;
|
|
74
|
+
/**
|
|
75
|
+
* @protected
|
|
76
|
+
* @param {TKind} kind
|
|
77
|
+
* @param {ErrorOptions<TCode>} options
|
|
78
|
+
*/
|
|
79
|
+
constructor(kind, options) {
|
|
80
|
+
super(options.message);
|
|
81
|
+
this.kind = kind;
|
|
82
|
+
this.code = options.code;
|
|
83
|
+
this.details = options.details;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* @returns {SerializableError<TKind, TCode>}
|
|
87
|
+
*/
|
|
88
|
+
toJSON() {
|
|
89
|
+
return this.details === undefined
|
|
90
|
+
? { code: this.code, kind: this.kind, message: this.message }
|
|
91
|
+
: { code: this.code, details: this.details, kind: this.kind, message: this.message };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* @extends {SerializableClientErrorBase<"domain", DomainErrorCode>}
|
|
96
|
+
*/
|
|
97
|
+
export class DomainError extends SerializableClientErrorBase {
|
|
98
|
+
/**
|
|
99
|
+
* @param {ErrorOptions<DomainErrorCode>} options
|
|
100
|
+
*/
|
|
101
|
+
constructor(options) {
|
|
102
|
+
super("domain", options);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* @extends {SerializableClientErrorBase<"sync", SyncErrorCode>}
|
|
107
|
+
*/
|
|
108
|
+
export class SyncError extends SerializableClientErrorBase {
|
|
109
|
+
/**
|
|
110
|
+
* @param {ErrorOptions<SyncErrorCode>} options
|
|
111
|
+
*/
|
|
112
|
+
constructor(options) {
|
|
113
|
+
super("sync", options);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* @extends {SerializableClientErrorBase<"transport", TransportErrorCode>}
|
|
118
|
+
*/
|
|
119
|
+
export class TransportError extends SerializableClientErrorBase {
|
|
120
|
+
/**
|
|
121
|
+
* @param {ErrorOptions<TransportErrorCode>} options
|
|
122
|
+
*/
|
|
123
|
+
constructor(options) {
|
|
124
|
+
super("transport", options);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {import("@econ-v1/ports").TransportState} TransportState */
|
|
4
|
+
/** @typedef {import("@econ-v1/ports").OfflineIdentityScope} OfflineIdentityScope */
|
|
5
|
+
/** @typedef {import("@econ-v1/ports").OfflineStageReadiness} OfflineStageReadiness */
|
|
6
|
+
/** @typedef {import("../models/json.js").JsonObject} JsonObject */
|
|
7
|
+
/** @typedef {import("../models/outbox.js").OutboxIntent} OutboxIntent */
|
|
8
|
+
/** @typedef {`${string}.v${number}`} QueryName */
|
|
9
|
+
/** @typedef {`app.${string}`} AppEventType */
|
|
10
|
+
/** @typedef {{ readonly data: JsonObject, readonly instance?: string, readonly resource: string, readonly type: string }} AppEventPayload */
|
|
11
|
+
/** @typedef {{ readonly anchorSession: string, readonly argsDelta?: string, readonly callId?: string, readonly callIndex?: number, readonly agentName?: string, readonly kind: "room.turn_started" | "turn.completed" | "turn.delta" | "turn.failed" | "turn.tool_delta" | "work.delta", readonly runId?: string, readonly reason?: string, readonly responderName?: string, readonly responderSlug?: string, readonly roomId: string, readonly text?: string, readonly toolName?: string }} RoomTurnStreamPayload */
|
|
12
|
+
/** @typedef {{ readonly closedAt?: string, readonly jobId: string, readonly openedAt: string, readonly openedBySeq?: number, readonly origin: "scheduled" | "user", readonly pendingArrivals: number, readonly queueCount: number, readonly roomId: string, readonly status: "aborted" | "capped" | "done" | "open", readonly stepCount: number, readonly turnsUsed: number }} RoomJobSummary */
|
|
13
|
+
/** @typedef {{ readonly actor: { readonly kind: "orchestrator" | "specialist", readonly name?: string, readonly slug?: string }, readonly detail: string, readonly kind: string, readonly outcome?: string, readonly runId?: string, readonly seq?: number, readonly stepId: string, readonly ts: string }} RoomJobStep */
|
|
14
|
+
/** @typedef {{ readonly job: RoomJobSummary, readonly kind: "job" | "job_step", readonly roomId: string, readonly step?: RoomJobStep }} RoomJobStreamPayload */
|
|
15
|
+
|
|
16
|
+
const APP_EVENT_RESOURCE_PATTERN = /^[a-z][a-z0-9_]*(?:-[a-z0-9_]+)*$/u;
|
|
17
|
+
const APP_EVENT_INSTANCE_PATTERN = /^[^#\s]+$/u;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} value
|
|
21
|
+
* @returns {{ instance?: string, resource: string } | undefined}
|
|
22
|
+
*/
|
|
23
|
+
function parseAppEventType(value) {
|
|
24
|
+
if (!value.startsWith("app.")) return undefined;
|
|
25
|
+
const rest = value.slice("app.".length);
|
|
26
|
+
const separator = rest.indexOf("#");
|
|
27
|
+
if (separator === -1) {
|
|
28
|
+
return APP_EVENT_RESOURCE_PATTERN.test(rest)
|
|
29
|
+
? { resource: rest }
|
|
30
|
+
: undefined;
|
|
31
|
+
}
|
|
32
|
+
const resource = rest.slice(0, separator);
|
|
33
|
+
const instance = rest.slice(separator + 1);
|
|
34
|
+
if (
|
|
35
|
+
!APP_EVENT_RESOURCE_PATTERN.test(resource) ||
|
|
36
|
+
!APP_EVENT_INSTANCE_PATTERN.test(instance)
|
|
37
|
+
) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return { instance, resource };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** @type {readonly ["transport.state-changed", "stage.catalog-invalidated", "stage.registry-changed", "query.invalidated", "outbox.state-changed", "domain.entity-changed", "sync.delta-applied", "client-storage.state-changed", "offline.stage-readiness-changed", "offline.identity-invalidated", "app.data.changed", "app.data.committed", "onboarding.flow-changed", "device-cleanup.changed", "room.turn-stream", "room.job-stream"]} */
|
|
44
|
+
export const KERNEL_EVENT_TYPES = [
|
|
45
|
+
"transport.state-changed",
|
|
46
|
+
"stage.catalog-invalidated",
|
|
47
|
+
"stage.registry-changed",
|
|
48
|
+
"query.invalidated",
|
|
49
|
+
"outbox.state-changed",
|
|
50
|
+
"domain.entity-changed",
|
|
51
|
+
"sync.delta-applied",
|
|
52
|
+
"client-storage.state-changed",
|
|
53
|
+
"offline.stage-readiness-changed",
|
|
54
|
+
"offline.identity-invalidated",
|
|
55
|
+
"app.data.changed",
|
|
56
|
+
"app.data.committed",
|
|
57
|
+
"onboarding.flow-changed",
|
|
58
|
+
"device-cleanup.changed",
|
|
59
|
+
"room.turn-stream",
|
|
60
|
+
"room.job-stream",
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/** @typedef {(typeof KERNEL_EVENT_TYPES)[number]} CoreKernelEventType */
|
|
64
|
+
/** @typedef {AppEventType | CoreKernelEventType} KernelEventType */
|
|
65
|
+
/** @typedef {{ readonly "client-storage.state-changed": { readonly code?: string, readonly message?: string, readonly status: "ready" | "recovery-required" | "starting" }, readonly "offline.stage-readiness-changed": { readonly readiness: OfflineStageReadiness }, readonly "offline.identity-invalidated": { readonly scope: OfflineIdentityScope }, readonly "app.data.changed": { readonly appName: string, readonly cursor: string, readonly revision: string, readonly stream: string }, readonly "app.data.committed": { readonly appName: string, readonly cursor: string, readonly revision: string, readonly stream: string }, readonly "device-cleanup.changed": { readonly state?: string }, readonly "domain.entity-changed": { readonly action: "created" | "deleted" | "updated", readonly entityId: string, readonly entityType: string }, readonly "onboarding.flow-changed": { readonly stepId: string }, readonly "outbox.state-changed": { readonly intent: OutboxIntent }, readonly "room.job-stream": RoomJobStreamPayload, readonly "room.turn-stream": RoomTurnStreamPayload, readonly "stage.catalog-invalidated": { readonly reason: string }, readonly "query.invalidated": { readonly name: QueryName }, readonly "stage.registry-changed": { readonly appNames: readonly string[] }, readonly "sync.delta-applied": { readonly domain: string, readonly cursor: string }, readonly "transport.state-changed": { readonly state: TransportState } }} KernelEventPayloads */
|
|
66
|
+
/** @template {KernelEventType} T @typedef {T extends CoreKernelEventType ? KernelEventPayloads[T] : AppEventPayload} KernelEventPayload */
|
|
67
|
+
/** @template {KernelEventType} T @typedef {{ readonly occurredAt: string, readonly payload: KernelEventPayload<T>, readonly type: T }} KernelEventByType */
|
|
68
|
+
/** @typedef {{ readonly occurredAt: string, readonly payload: AppEventPayload, readonly type: AppEventType }} AppDomainEvent */
|
|
69
|
+
/** @typedef {{ [T in CoreKernelEventType]: KernelEventByType<T> }[CoreKernelEventType] | AppDomainEvent} DomainEvent */
|
|
70
|
+
|
|
71
|
+
/** @template {CoreKernelEventType} T @param {DomainEvent} event @param {T} type @returns {event is Extract<DomainEvent, { readonly type: T }>} */
|
|
72
|
+
export function isCoreKernelEvent(event, type) {
|
|
73
|
+
return event.type === type;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** @param {string} value @returns {value is CoreKernelEventType} */
|
|
77
|
+
export function isCoreKernelEventType(value) {
|
|
78
|
+
return KERNEL_EVENT_TYPES.includes(
|
|
79
|
+
/** @type {CoreKernelEventType} */ (value),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** @param {string} value @returns {value is AppEventType} */
|
|
84
|
+
export function isAppEventType(value) {
|
|
85
|
+
return parseAppEventType(value) !== undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** @param {string} value @returns {value is KernelEventType} */
|
|
89
|
+
export function isKernelEventType(value) {
|
|
90
|
+
return isCoreKernelEventType(value) || isAppEventType(value);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** @param {string} value @returns {string | undefined} */
|
|
94
|
+
export function appEventResource(value) {
|
|
95
|
+
return parseAppEventType(value)?.resource;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** @param {string} value @returns {string | undefined} */
|
|
99
|
+
export function appEventInstance(value) {
|
|
100
|
+
return parseAppEventType(value)?.instance;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** @param {string} value @returns {AppEventType | undefined} */
|
|
104
|
+
export function appEventScope(value) {
|
|
105
|
+
const parsed = parseAppEventType(value);
|
|
106
|
+
return parsed === undefined ? undefined : `app.${parsed.resource}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** @param {string} resource @param {string} [instance] @returns {AppEventType} */
|
|
110
|
+
export function appEventType(resource, instance) {
|
|
111
|
+
if (!APP_EVENT_RESOURCE_PATTERN.test(resource)) {
|
|
112
|
+
throw new TypeError(`Invalid app event resource: ${resource}`);
|
|
113
|
+
}
|
|
114
|
+
if (instance === undefined) return `app.${resource}`;
|
|
115
|
+
if (!APP_EVENT_INSTANCE_PATTERN.test(instance)) {
|
|
116
|
+
throw new TypeError(`Invalid app event instance: ${instance}`);
|
|
117
|
+
}
|
|
118
|
+
return `app.${resource}#${instance}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** @param {string} value @returns {value is QueryName} */
|
|
122
|
+
export function isQueryName(value) {
|
|
123
|
+
return /^.+\.v\d+$/u.test(value);
|
|
124
|
+
}
|