@econ-v1/rpc 7.3.0 → 7.3.1
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/client.d.ts +24 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/message-port-client.d.ts +18 -4
- package/dist/message-port-client.d.ts.map +1 -1
- package/dist/model-picker-contract.d.ts +12 -4
- package/dist/model-picker-contract.d.ts.map +1 -1
- package/dist/protocol.d.ts +5 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/stage-context.d.ts +3 -1
- package/dist/stage-context.d.ts.map +1 -1
- package/dist/subscription-state.d.ts +35 -0
- package/dist/subscription-state.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/client.js +19 -2
- package/src/index.js +4 -0
- package/src/message-port-client.js +121 -29
- package/src/model-picker-contract.js +10 -4
- package/src/protocol.js +23 -1
- package/src/stage-context.js +3 -1
- package/src/subscription-state.js +74 -0
package/dist/client.d.ts
CHANGED
|
@@ -2,6 +2,28 @@ export type DomainEvent = import("@econ-v1/domain").DomainEvent;
|
|
|
2
2
|
export type KernelEventType = import("@econ-v1/domain").KernelEventType;
|
|
3
3
|
export type QueryName = import("@econ-v1/domain").QueryName;
|
|
4
4
|
export type Unsubscribe = () => void;
|
|
5
|
+
/**
|
|
6
|
+
* Whether an event subscription is live on the home node (ADR-039). `confirmed` is true only
|
|
7
|
+
* when the host itself confirmed it; `generation` rises by one on every `live`, so a holder
|
|
8
|
+
* reads the state it follows once per generation.
|
|
9
|
+
*/
|
|
10
|
+
export type SubscriptionState = import("@econ-v1/ports").AppEventSubscriptionState;
|
|
11
|
+
/**
|
|
12
|
+
* `onState` hears every transition of the subscription, starting with the current state.
|
|
13
|
+
*/
|
|
14
|
+
export type EventSubscribeOptions = {
|
|
15
|
+
readonly onState?: (state: SubscriptionState) => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* What `subscribe` returns: still the unsubscribe function, plus, on a shell that carries
|
|
19
|
+
* subscription state, `ready` (resolves once this subscription is `live`, at once when it
|
|
20
|
+
* already is, and rejects on `refused`) and the current `state`. Both are optional because
|
|
21
|
+
* an older shell returns a bare function; detect with `typeof handle.ready?.then === "function"`.
|
|
22
|
+
*/
|
|
23
|
+
export type EventSubscription = Unsubscribe & {
|
|
24
|
+
readonly ready?: Promise<SubscriptionState>;
|
|
25
|
+
readonly state?: SubscriptionState;
|
|
26
|
+
};
|
|
5
27
|
/**
|
|
6
28
|
* What `prepareStage` hands back for a stage the kernel has committed.
|
|
7
29
|
*
|
|
@@ -42,7 +64,7 @@ export type KernelRpcClient = {
|
|
|
42
64
|
prepareStage(appName: string): Promise<PreparedStage>;
|
|
43
65
|
publish<T extends KernelEventType>(type: T, payload: import("@econ-v1/domain").KernelEventPayload<T>): Promise<void>;
|
|
44
66
|
query<T>(name: QueryName, params: unknown): Promise<T>;
|
|
45
|
-
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
67
|
+
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription;
|
|
46
68
|
};
|
|
47
69
|
export type StageRpcSession = {
|
|
48
70
|
close(): void;
|
|
@@ -51,6 +73,6 @@ export type StageRpcSession = {
|
|
|
51
73
|
liveQuery<T>(name: QueryName, params: unknown, listener: (diff: import("@econ-v1/domain").QueryDiff<T>) => void, onError?: (error: LiveQueryFailure) => void): Unsubscribe;
|
|
52
74
|
publish<T extends KernelEventType>(type: T, payload: import("@econ-v1/domain").KernelEventPayload<T>): Promise<void>;
|
|
53
75
|
query<T>(name: QueryName, params: unknown): Promise<T>;
|
|
54
|
-
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
76
|
+
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription;
|
|
55
77
|
};
|
|
56
78
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.js"],"names":[],"mappings":"0BAEc,OAAO,iBAAiB,EAAE,WAAW;8BACrC,OAAO,iBAAiB,EAAE,eAAe;wBACzC,OAAO,iBAAiB,EAAE,SAAS;0BACnC,MAAM,IAAI;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.js"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { SubscriptionStateCell } from "./subscription-state.js";
|
|
1
2
|
export { CLIENT_SERVICES_RETRY_COMMAND } from "./client-services-contract.js";
|
|
2
3
|
export { DEVTOOLS_GRANT } from "./grants-contract.js";
|
|
3
4
|
export { DEVICE_BOOT_STATE_QUERY } from "./device-boot-contract.js";
|
|
@@ -12,6 +13,9 @@ export type ResponsivenessTracker = import("./node-responsiveness.js").Responsiv
|
|
|
12
13
|
export type PreparedStage = import("./client.js").PreparedStage;
|
|
13
14
|
export type StageRpcSession = import("./client.js").StageRpcSession;
|
|
14
15
|
export type Unsubscribe = import("./client.js").Unsubscribe;
|
|
16
|
+
export type EventSubscribeOptions = import("./client.js").EventSubscribeOptions;
|
|
17
|
+
export type EventSubscription = import("./client.js").EventSubscription;
|
|
18
|
+
export type SubscriptionState = import("./client.js").SubscriptionState;
|
|
15
19
|
export type ClientError = import("@econ-v1/domain").ClientError;
|
|
16
20
|
export type DomainEvent = import("@econ-v1/domain").DomainEvent;
|
|
17
21
|
export type DomainErrorCode = import("@econ-v1/domain").DomainErrorCode;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"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"}
|
|
@@ -73,9 +73,10 @@ export class MessagePortKernelRpcClient implements KernelRpcClient {
|
|
|
73
73
|
* @template {KernelEventType} T
|
|
74
74
|
* @param {T} type
|
|
75
75
|
* @param {(event: import("@econ-v1/domain").KernelEventByType<T>) => void} listener
|
|
76
|
-
* @
|
|
76
|
+
* @param {EventSubscribeOptions} [options]
|
|
77
|
+
* @returns {EventSubscription}
|
|
77
78
|
*/
|
|
78
|
-
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
79
|
+
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription;
|
|
79
80
|
/** @param {string} sessionId */
|
|
80
81
|
closeStageSession(sessionId: string): void;
|
|
81
82
|
/**
|
|
@@ -123,9 +124,10 @@ export class MessagePortKernelRpcClient implements KernelRpcClient {
|
|
|
123
124
|
* @param {string} sessionId
|
|
124
125
|
* @param {T} type
|
|
125
126
|
* @param {(event: import("@econ-v1/domain").KernelEventByType<T>) => void} listener
|
|
126
|
-
* @
|
|
127
|
+
* @param {EventSubscribeOptions} [options]
|
|
128
|
+
* @returns {EventSubscription}
|
|
127
129
|
*/
|
|
128
|
-
subscribeStage<T extends KernelEventType>(sessionId: string, type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
130
|
+
subscribeStage<T extends KernelEventType>(sessionId: string, type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription;
|
|
129
131
|
#private;
|
|
130
132
|
}
|
|
131
133
|
export type DomainEvent = import("@econ-v1/domain").DomainEvent;
|
|
@@ -136,6 +138,9 @@ export type KernelRpcClient = import("./client.js").KernelRpcClient;
|
|
|
136
138
|
export type PreparedStage = import("./client.js").PreparedStage;
|
|
137
139
|
export type StageRpcSession = import("./client.js").StageRpcSession;
|
|
138
140
|
export type Unsubscribe = import("./client.js").Unsubscribe;
|
|
141
|
+
export type EventSubscribeOptions = import("./client.js").EventSubscribeOptions;
|
|
142
|
+
export type EventSubscription = import("./client.js").EventSubscription;
|
|
143
|
+
export type SubscriptionState = import("./client.js").SubscriptionState;
|
|
139
144
|
export type RpcRequest = import("./protocol.js").RpcRequest;
|
|
140
145
|
export type RpcRequestWithoutId = RpcRequest extends infer TRequest ? TRequest extends RpcRequest ? Omit<TRequest, "id"> : never : never;
|
|
141
146
|
export type RpcTransport = import("./transport.js").RpcTransport;
|
|
@@ -148,9 +153,16 @@ export type PendingRequest = {
|
|
|
148
153
|
readonly timeoutId: ReturnType<typeof globalThis.setTimeout>;
|
|
149
154
|
readonly timeoutMs: number;
|
|
150
155
|
};
|
|
156
|
+
/**
|
|
157
|
+
* `cell` counts the group's own generations rather than the kernel's, because a new kernel
|
|
158
|
+
* (a leader-tab failover replays this subscription onto it) starts its count again.
|
|
159
|
+
*/
|
|
151
160
|
export type EventGroup = {
|
|
161
|
+
readonly cell: SubscriptionStateCell;
|
|
152
162
|
readonly eventType: KernelEventType;
|
|
153
163
|
readonly listeners: Set<(event: DomainEvent) => void>;
|
|
164
|
+
readonly pendingReady: Set<(error: TransportError) => void>;
|
|
165
|
+
refusal?: unknown;
|
|
154
166
|
readonly sessionId: string | undefined;
|
|
155
167
|
readonly subscriptionId: string;
|
|
156
168
|
};
|
|
@@ -175,4 +187,6 @@ export type MessagePortKernelRpcClientOptions = {
|
|
|
175
187
|
readonly observer?: RpcResponsivenessObserver;
|
|
176
188
|
readonly requestTimeoutMs?: number;
|
|
177
189
|
};
|
|
190
|
+
import { SubscriptionStateCell } from "./subscription-state.js";
|
|
191
|
+
import { TransportError } from "@econ-v1/domain";
|
|
178
192
|
//# sourceMappingURL=message-port-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-port-client.d.ts","sourceRoot":"","sources":["../src/message-port-client.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"message-port-client.d.ts","sourceRoot":"","sources":["../src/message-port-client.js"],"names":[],"mappings":"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"}
|
|
@@ -41,14 +41,20 @@ export const ROUTE_MODES: readonly ["auto", "public", "private"];
|
|
|
41
41
|
* `peerNodeId` present means the model is bought from that peer (its store),
|
|
42
42
|
* absent means this node runs it on its own key ("My Store"). */
|
|
43
43
|
/** @typedef {{ readonly name: string, readonly peerNodeId?: string }} ModelRef */
|
|
44
|
-
/** What the stage already knows, so the overlay opens on it instead of a default.
|
|
45
|
-
|
|
44
|
+
/** What the stage already knows, so the overlay opens on it instead of a default.
|
|
45
|
+
* `onSelect` hears each Select at once, while the overlay stays open for the chips:
|
|
46
|
+
* the pick carries `model` and the chips as they stand. The promise still resolves
|
|
47
|
+
* when the overlay closes, with the final pick, so a stage that applies both must
|
|
48
|
+
* treat the same model twice as one choice. A host before it ignores `onSelect`. */
|
|
49
|
+
/** @typedef {{ readonly current?: ModelRef, readonly routeMode?: RouteMode, readonly webSearch?: WebSearchChoice, readonly onSelect?: (pick: ModelPick) => void }} ModelPickRequest */
|
|
46
50
|
/** `model` is present only when the owner pressed Select on a row; absent means
|
|
47
51
|
* "keep whatever model the stage already had" — the owner changed only the
|
|
48
52
|
* web-search chip (or nothing but still closed with a chip change). `label` is
|
|
49
53
|
* the catalog's `picker_label ?? name`, so a pill or chip shows the same words
|
|
50
|
-
* the overlay did.
|
|
51
|
-
|
|
54
|
+
* the overlay did. `storeName` is the seller's store as the overlay named it
|
|
55
|
+
* (this node's own `mine.name`, or the peer's), so a chip can say whose store
|
|
56
|
+
* sells the model. */
|
|
57
|
+
/** @typedef {{ readonly model?: ModelRef, readonly label?: string, readonly storeName?: string, readonly routeMode: RouteMode, readonly webSearch: WebSearchChoice }} ModelPick */
|
|
52
58
|
/** Resolves `undefined` when the owner closes without choosing. Rejects with a
|
|
53
59
|
* `DomainError` `conflict` while another `open()` is still pending — the overlay
|
|
54
60
|
* is one surface — and `capability_unavailable` when this host has no design
|
|
@@ -144,10 +150,12 @@ export type ModelPickRequest = {
|
|
|
144
150
|
readonly current?: ModelRef;
|
|
145
151
|
readonly routeMode?: RouteMode;
|
|
146
152
|
readonly webSearch?: WebSearchChoice;
|
|
153
|
+
readonly onSelect?: (pick: ModelPick) => void;
|
|
147
154
|
};
|
|
148
155
|
export type ModelPick = {
|
|
149
156
|
readonly model?: ModelRef;
|
|
150
157
|
readonly label?: string;
|
|
158
|
+
readonly storeName?: string;
|
|
151
159
|
readonly routeMode: RouteMode;
|
|
152
160
|
readonly webSearch: WebSearchChoice;
|
|
153
161
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-picker-contract.d.ts","sourceRoot":"","sources":["../src/model-picker-contract.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-picker-contract.d.ts","sourceRoot":"","sources":["../src/model-picker-contract.js"],"names":[],"mappings":"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"}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -193,6 +193,10 @@ export type RpcEvent = {
|
|
|
193
193
|
readonly event: ProtocolDomainEvent;
|
|
194
194
|
readonly subscriptionId: string;
|
|
195
195
|
readonly type: "kernel.event";
|
|
196
|
+
} | {
|
|
197
|
+
readonly state: SubscriptionState;
|
|
198
|
+
readonly subscriptionId: string;
|
|
199
|
+
readonly type: "subscription.state";
|
|
196
200
|
};
|
|
197
201
|
import type { JsonValue } from '@econ-v1/domain';
|
|
198
202
|
import type { DomainEvent } from '@econ-v1/domain';
|
|
@@ -200,4 +204,5 @@ import type { CoreKernelEventType } from '@econ-v1/domain';
|
|
|
200
204
|
import type { ClientError } from '@econ-v1/domain';
|
|
201
205
|
import type { QueryName } from '@econ-v1/domain';
|
|
202
206
|
import type { QueryDiff } from '@econ-v1/domain';
|
|
207
|
+
import type { SubscriptionState } from './client.js';
|
|
203
208
|
//# sourceMappingURL=protocol.d.ts.map
|
package/dist/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.js"],"names":[],"mappings":"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"}
|
package/dist/stage-context.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type KernelEventType = import("@econ-v1/domain").KernelEventType;
|
|
2
2
|
export type QueryName = import("@econ-v1/domain").QueryName;
|
|
3
3
|
export type Unsubscribe = import("./client.js").Unsubscribe;
|
|
4
|
+
export type EventSubscribeOptions = import("./client.js").EventSubscribeOptions;
|
|
5
|
+
export type EventSubscription = import("./client.js").EventSubscription;
|
|
4
6
|
export type DialogCenter = import("./dialog-contract.js").DialogCenter;
|
|
5
7
|
export type ModelPickerCenter = import("./model-picker-contract.js").ModelPickerCenter;
|
|
6
8
|
export type SystemNoticeCenter = import("./system-notice-contract.js").SystemNoticeCenter;
|
|
@@ -44,7 +46,7 @@ export type StageContextShared = {
|
|
|
44
46
|
};
|
|
45
47
|
readonly events: {
|
|
46
48
|
publish<T extends KernelEventType>(type: T, payload: import("@econ-v1/domain").KernelEventPayload<T>): Promise<void>;
|
|
47
|
-
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
49
|
+
subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription;
|
|
48
50
|
};
|
|
49
51
|
invokeCapability<T>(capability: string, payload: unknown): Promise<T>;
|
|
50
52
|
liveQuery<T>(name: QueryName, params: unknown, listener: (diff: import("@econ-v1/domain").QueryDiff<T>) => void): Unsubscribe;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-context.d.ts","sourceRoot":"","sources":["../src/stage-context.js"],"names":[],"mappings":"8BAEc,OAAO,iBAAiB,EAAE,eAAe;wBACzC,OAAO,iBAAiB,EAAE,SAAS;0BACnC,OAAO,aAAa,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"stage-context.d.ts","sourceRoot":"","sources":["../src/stage-context.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** @typedef {import("./client.js").SubscriptionState} SubscriptionState */
|
|
2
|
+
/** @typedef {{ readonly onState: (state: SubscriptionState) => void, told: boolean }} SubscriptionStateHolder */
|
|
3
|
+
/**
|
|
4
|
+
* One subscription's state and the holders watching it (ADR-039). Every layer that
|
|
5
|
+
* carries a subscription (a carrier, the managed client, the kernel lease, the RPC
|
|
6
|
+
* group) keeps one, so they all fold states the same way.
|
|
7
|
+
*
|
|
8
|
+
* Each `live` is the next generation, and a `live` reported as "subscribed" after an
|
|
9
|
+
* earlier one reads "resubscribed": whatever restarted below (a carrier, a kernel)
|
|
10
|
+
* counts from 1 again, but a holder never sees a generation twice. A repeated state
|
|
11
|
+
* that is not `live` is not re-sent. A holder that joins when there is a state gets
|
|
12
|
+
* it on a microtask, unless a transition reached it first.
|
|
13
|
+
*/
|
|
14
|
+
export class SubscriptionStateCell {
|
|
15
|
+
get state(): import("ports/dist/network.js").AppEventSubscriptionState | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* @param {(state: SubscriptionState) => void} onState
|
|
18
|
+
* @returns {() => void}
|
|
19
|
+
*/
|
|
20
|
+
watch(onState: (state: SubscriptionState) => void): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* @param {SubscriptionState["status"]} status
|
|
23
|
+
* @param {boolean} [confirmed] ignored unless `live`
|
|
24
|
+
* @param {SubscriptionState["reason"]} [reason] ignored unless `live`
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
report(status: SubscriptionState["status"], confirmed?: boolean, reason?: SubscriptionState["reason"]): void;
|
|
28
|
+
#private;
|
|
29
|
+
}
|
|
30
|
+
export type SubscriptionState = import("./client.js").SubscriptionState;
|
|
31
|
+
export type SubscriptionStateHolder = {
|
|
32
|
+
readonly onState: (state: SubscriptionState) => void;
|
|
33
|
+
told: boolean;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=subscription-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription-state.d.ts","sourceRoot":"","sources":["../src/subscription-state.js"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,iHAAiH;AAEjH;;;;;;;;;;GAUG;AACH;IAMI,mFAEC;IACD;;;OAGG;IACH,eAHW,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,GAChC,MAAM,IAAI,CAatB;IACD;;;;;OAKG;IACH,eALW,iBAAiB,CAAC,QAAQ,CAAC,cAC3B,OAAO,WACP,iBAAiB,CAAC,QAAQ,CAAC,GACzB,IAAI,CAgBhB;;CACJ;gCA5Da,OAAO,aAAa,EAAE,iBAAiB;sCACvC;IAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@econ-v1/rpc",
|
|
3
|
-
"version": "7.3.
|
|
3
|
+
"version": "7.3.1",
|
|
4
4
|
"description": "Typed runtime and contracts for Node client stage-to-kernel RPC",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"author": "Node contributors",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@econ-v1/domain": "7.3.
|
|
60
|
-
"@econ-v1/ports": "7.3.
|
|
59
|
+
"@econ-v1/domain": "7.3.1",
|
|
60
|
+
"@econ-v1/ports": "7.3.1"
|
|
61
61
|
}
|
|
62
62
|
}
|
package/src/client.js
CHANGED
|
@@ -4,6 +4,23 @@
|
|
|
4
4
|
/** @typedef {import("@econ-v1/domain").KernelEventType} KernelEventType */
|
|
5
5
|
/** @typedef {import("@econ-v1/domain").QueryName} QueryName */
|
|
6
6
|
/** @typedef {() => void} Unsubscribe */
|
|
7
|
+
/**
|
|
8
|
+
* Whether an event subscription is live on the home node (ADR-039). `confirmed` is true only
|
|
9
|
+
* when the host itself confirmed it; `generation` rises by one on every `live`, so a holder
|
|
10
|
+
* reads the state it follows once per generation.
|
|
11
|
+
* @typedef {import("@econ-v1/ports").AppEventSubscriptionState} SubscriptionState
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* `onState` hears every transition of the subscription, starting with the current state.
|
|
15
|
+
* @typedef {{ readonly onState?: (state: SubscriptionState) => void }} EventSubscribeOptions
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* What `subscribe` returns: still the unsubscribe function, plus, on a shell that carries
|
|
19
|
+
* subscription state, `ready` (resolves once this subscription is `live`, at once when it
|
|
20
|
+
* already is, and rejects on `refused`) and the current `state`. Both are optional because
|
|
21
|
+
* an older shell returns a bare function; detect with `typeof handle.ready?.then === "function"`.
|
|
22
|
+
* @typedef {Unsubscribe & { readonly ready?: Promise<SubscriptionState>, readonly state?: SubscriptionState }} EventSubscription
|
|
23
|
+
*/
|
|
7
24
|
/**
|
|
8
25
|
* What `prepareStage` hands back for a stage the kernel has committed.
|
|
9
26
|
*
|
|
@@ -36,7 +53,7 @@
|
|
|
36
53
|
* prepareStage(appName: string): Promise<PreparedStage>,
|
|
37
54
|
* publish<T extends KernelEventType>(type: T, payload: import("@econ-v1/domain").KernelEventPayload<T>): Promise<void>,
|
|
38
55
|
* query<T>(name: QueryName, params: unknown): Promise<T>,
|
|
39
|
-
* subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
56
|
+
* subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription
|
|
40
57
|
* }} KernelRpcClient */
|
|
41
58
|
/** @typedef {{
|
|
42
59
|
* close(): void,
|
|
@@ -45,7 +62,7 @@
|
|
|
45
62
|
* liveQuery<T>(name: QueryName, params: unknown, listener: (diff: import("@econ-v1/domain").QueryDiff<T>) => void, onError?: (error: LiveQueryFailure) => void): Unsubscribe,
|
|
46
63
|
* publish<T extends KernelEventType>(type: T, payload: import("@econ-v1/domain").KernelEventPayload<T>): Promise<void>,
|
|
47
64
|
* query<T>(name: QueryName, params: unknown): Promise<T>,
|
|
48
|
-
* subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
65
|
+
* subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription
|
|
49
66
|
* }} StageRpcSession */
|
|
50
67
|
|
|
51
68
|
export {};
|
package/src/index.js
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
/** @typedef {import("./client.js").PreparedStage} PreparedStage */
|
|
9
9
|
/** @typedef {import("./client.js").StageRpcSession} StageRpcSession */
|
|
10
10
|
/** @typedef {import("./client.js").Unsubscribe} Unsubscribe */
|
|
11
|
+
/** @typedef {import("./client.js").EventSubscribeOptions} EventSubscribeOptions */
|
|
12
|
+
/** @typedef {import("./client.js").EventSubscription} EventSubscription */
|
|
13
|
+
/** @typedef {import("./client.js").SubscriptionState} SubscriptionState */
|
|
11
14
|
/** @typedef {import("@econ-v1/domain").ClientError} ClientError */
|
|
12
15
|
/** @typedef {import("@econ-v1/domain").DomainEvent} DomainEvent */
|
|
13
16
|
/** @typedef {import("@econ-v1/domain").DomainErrorCode} DomainErrorCode */
|
|
@@ -201,6 +204,7 @@ export {
|
|
|
201
204
|
serializeClientError,
|
|
202
205
|
} from "./errors.js";
|
|
203
206
|
export { DEFAULT_REQUEST_TIMEOUT_MS, KernelRpcTimeoutError, MessagePortKernelRpcClient } from "./message-port-client.js";
|
|
207
|
+
export { SubscriptionStateCell } from "./subscription-state.js";
|
|
204
208
|
export { NODE_APP_LIFECYCLE_COMMAND, NODE_APP_MEMORY_CAPTURE_COMMAND, NODE_APP_MEMORY_DETAIL_QUERY, NODE_APP_MEMORY_DOWNLOAD_COMMAND, NODE_APP_MEMORY_LIST_QUERY, NODE_APP_MEMORY_OVERVIEW_QUERY, NODE_APP_MEMORY_STATUS_COMMAND } from "./node-app-memory-contract.js";
|
|
205
209
|
export { APPS_LIFECYCLE_PIN_COMMAND, APPS_LIFECYCLE_QUERY } from "./apps-lifecycle-contract.js";
|
|
206
210
|
export { CLIENT_SERVICES_RETRY_COMMAND } from "./client-services-contract.js";
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
|
|
8
8
|
import { isJsonValue } from "./errors.js";
|
|
9
9
|
import { EMA_REFERENCE_TIMEOUT_MS, slowBarMs } from "./node-responsiveness.js";
|
|
10
|
+
import { SubscriptionStateCell } from "./subscription-state.js";
|
|
10
11
|
import {
|
|
11
12
|
deserializeRpcEvent,
|
|
12
13
|
deserializeRpcResponse,
|
|
@@ -21,11 +22,18 @@ import {
|
|
|
21
22
|
/** @typedef {import("./client.js").PreparedStage} PreparedStage */
|
|
22
23
|
/** @typedef {import("./client.js").StageRpcSession} StageRpcSession */
|
|
23
24
|
/** @typedef {import("./client.js").Unsubscribe} Unsubscribe */
|
|
25
|
+
/** @typedef {import("./client.js").EventSubscribeOptions} EventSubscribeOptions */
|
|
26
|
+
/** @typedef {import("./client.js").EventSubscription} EventSubscription */
|
|
27
|
+
/** @typedef {import("./client.js").SubscriptionState} SubscriptionState */
|
|
24
28
|
/** @typedef {import("./protocol.js").RpcRequest} RpcRequest */
|
|
25
29
|
/** @typedef {RpcRequest extends infer TRequest ? TRequest extends RpcRequest ? Omit<TRequest, "id"> : never : never} RpcRequestWithoutId */
|
|
26
30
|
/** @typedef {import("./transport.js").RpcTransport} RpcTransport */
|
|
27
31
|
/** @typedef {{ readonly reject: (error: unknown) => void, readonly resolve: (value: JsonValue) => void, readonly sessionId: string | undefined, readonly slowBarId: ReturnType<typeof globalThis.setTimeout>, readonly startedAtMs: number, readonly timeoutId: ReturnType<typeof globalThis.setTimeout>, readonly timeoutMs: number }} PendingRequest */
|
|
28
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* `cell` counts the group's own generations rather than the kernel's, because a new kernel
|
|
34
|
+
* (a leader-tab failover replays this subscription onto it) starts its count again.
|
|
35
|
+
* @typedef {{ readonly cell: SubscriptionStateCell, readonly eventType: KernelEventType, readonly listeners: Set<(event: DomainEvent) => void>, readonly pendingReady: Set<(error: TransportError) => void>, refusal?: unknown, readonly sessionId: string | undefined, readonly subscriptionId: string }} EventGroup
|
|
36
|
+
*/
|
|
29
37
|
/** @typedef {{ readonly errorListeners: Set<(error: { readonly message: string }) => void>, readonly listeners: Set<(diff: import("@econ-v1/domain").QueryDiff<JsonValue>) => void>, readonly name: QueryName, readonly params: JsonValue, retryTimer: ReturnType<typeof globalThis.setTimeout> | undefined, readonly sessionId: string | undefined, subscriptionId: string }} LiveQueryGroup */
|
|
30
38
|
/** @typedef {{ markSlow(id: string): void, settle(id: string, elapsedMs: number, answered: boolean, timeoutMs: number): void }} RpcResponsivenessObserver */
|
|
31
39
|
/** @typedef {{ readonly monotonicNow?: () => number, readonly now?: () => string, readonly observer?: RpcResponsivenessObserver, readonly requestTimeoutMs?: number }} MessagePortKernelRpcClientOptions */
|
|
@@ -291,10 +299,11 @@ export class MessagePortKernelRpcClient {
|
|
|
291
299
|
* @template {KernelEventType} T
|
|
292
300
|
* @param {T} type
|
|
293
301
|
* @param {(event: import("@econ-v1/domain").KernelEventByType<T>) => void} listener
|
|
294
|
-
* @
|
|
302
|
+
* @param {EventSubscribeOptions} [options]
|
|
303
|
+
* @returns {EventSubscription}
|
|
295
304
|
*/
|
|
296
|
-
subscribe(type, listener) {
|
|
297
|
-
return this.#subscribeEvent(undefined, type, listener);
|
|
305
|
+
subscribe(type, listener, options) {
|
|
306
|
+
return this.#subscribeEvent(undefined, type, listener, options);
|
|
298
307
|
}
|
|
299
308
|
|
|
300
309
|
/** @param {string} sessionId */
|
|
@@ -407,10 +416,11 @@ export class MessagePortKernelRpcClient {
|
|
|
407
416
|
* @param {string} sessionId
|
|
408
417
|
* @param {T} type
|
|
409
418
|
* @param {(event: import("@econ-v1/domain").KernelEventByType<T>) => void} listener
|
|
410
|
-
* @
|
|
419
|
+
* @param {EventSubscribeOptions} [options]
|
|
420
|
+
* @returns {EventSubscription}
|
|
411
421
|
*/
|
|
412
|
-
subscribeStage(sessionId, type, listener) {
|
|
413
|
-
return this.#subscribeEvent(sessionId, type, listener);
|
|
422
|
+
subscribeStage(sessionId, type, listener, options) {
|
|
423
|
+
return this.#subscribeEvent(sessionId, type, listener, options);
|
|
414
424
|
}
|
|
415
425
|
|
|
416
426
|
#handleClose() {
|
|
@@ -420,6 +430,11 @@ export class MessagePortKernelRpcClient {
|
|
|
420
430
|
this.#unsubscribeClose();
|
|
421
431
|
const error = new TransportError({ code: "connection_lost", message: "Kernel RPC port closed" });
|
|
422
432
|
for (const requestId of [...this.#pending.keys()]) this.#takePending(requestId, false)?.reject(error);
|
|
433
|
+
// Tell each subscription it went quiet, instead of leaving its listeners silent.
|
|
434
|
+
for (const group of this.#eventGroupsByKey.values()) {
|
|
435
|
+
group.cell.report("lost");
|
|
436
|
+
this.#cancelEventGroupReady(group, error);
|
|
437
|
+
}
|
|
423
438
|
this.#eventGroupsByKey.clear();
|
|
424
439
|
this.#eventGroupsBySubscription.clear();
|
|
425
440
|
// A pending re-subscribe timer must not outlive the port it would retry on — otherwise a
|
|
@@ -491,6 +506,11 @@ export class MessagePortKernelRpcClient {
|
|
|
491
506
|
for (const listener of [...group.errorListeners]) this.#notify(() => listener({ message: failureMessage }));
|
|
492
507
|
return;
|
|
493
508
|
}
|
|
509
|
+
if (event.type === "subscription.state") {
|
|
510
|
+
const group = this.#eventGroupsBySubscription.get(event.subscriptionId);
|
|
511
|
+
if (group !== undefined) group.cell.report(event.state.status, event.state.confirmed, event.state.reason);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
494
514
|
const group = this.#liveGroupsBySubscription.get(event.subscriptionId);
|
|
495
515
|
if (group === undefined) return;
|
|
496
516
|
for (const listener of [...group.listeners]) this.#notify(() => listener(event.diff));
|
|
@@ -538,6 +558,8 @@ export class MessagePortKernelRpcClient {
|
|
|
538
558
|
#removeSessionSubscriptions(sessionId) {
|
|
539
559
|
for (const [key, group] of [...this.#eventGroupsByKey]) {
|
|
540
560
|
if (group.sessionId === sessionId) {
|
|
561
|
+
group.cell.report("lost");
|
|
562
|
+
this.#cancelEventGroupReady(group, new TransportError({ code: "connection_lost", message: "Stage RPC session closed" }));
|
|
541
563
|
this.#eventGroupsByKey.delete(key);
|
|
542
564
|
this.#eventGroupsBySubscription.delete(group.subscriptionId);
|
|
543
565
|
}
|
|
@@ -602,32 +624,53 @@ export class MessagePortKernelRpcClient {
|
|
|
602
624
|
* @param {string | undefined} sessionId
|
|
603
625
|
* @param {T} eventType
|
|
604
626
|
* @param {(event: import("@econ-v1/domain").KernelEventByType<T>) => void} listener
|
|
605
|
-
* @
|
|
627
|
+
* @param {EventSubscribeOptions} [options]
|
|
628
|
+
* @returns {EventSubscription}
|
|
606
629
|
*/
|
|
607
|
-
#subscribeEvent(sessionId, eventType, listener) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const subscriptionId = this.#newSubscriptionId();
|
|
612
|
-
group = { eventType, listeners: new Set(), sessionId, subscriptionId };
|
|
613
|
-
this.#eventGroupsByKey.set(key, group);
|
|
614
|
-
this.#eventGroupsBySubscription.set(subscriptionId, group);
|
|
615
|
-
const request = sessionId === undefined
|
|
616
|
-
? /** @type {const} */ ({ eventType, subscriptionId, type: "event.subscribe" })
|
|
617
|
-
: /** @type {const} */ ({ eventType, sessionId, subscriptionId, type: "stage.event.subscribe" });
|
|
618
|
-
void this.#request(request).catch((error) => {
|
|
619
|
-
this.#dropEventGroup(key, /** @type {EventGroup} */ (group));
|
|
620
|
-
warnSubscriptionRejected("event", eventType, sessionId, error);
|
|
621
|
-
});
|
|
630
|
+
#subscribeEvent(sessionId, eventType, listener, options) {
|
|
631
|
+
if (this.#closed || this.#transport.state !== "open") {
|
|
632
|
+
if (!this.#closed) this.#handleClose();
|
|
633
|
+
return this.#lostEventSubscription(options);
|
|
622
634
|
}
|
|
635
|
+
const key = `${sessionId ?? "host"}:event:${eventType}`;
|
|
636
|
+
const group = this.#eventGroupsByKey.get(key) ?? this.#openEventGroup(key, sessionId, eventType);
|
|
637
|
+
const { cell } = group;
|
|
623
638
|
const storedListener = /** @type {(event: DomainEvent) => void} */ (listener);
|
|
624
639
|
group.listeners.add(storedListener);
|
|
640
|
+
const unwatch = options?.onState && cell.watch(options.onState);
|
|
641
|
+
// This handle's own `ready`: a group that joined while lost or pending must wait for
|
|
642
|
+
// its next `live`, not reuse one from before the gap.
|
|
643
|
+
/** @type {((error: TransportError) => void) | undefined} */
|
|
644
|
+
let cancelReady;
|
|
645
|
+
/** @type {Promise<SubscriptionState>} */
|
|
646
|
+
const ready = new Promise((resolve, reject) => {
|
|
647
|
+
const off = cell.watch((state) => {
|
|
648
|
+
if (state.status === "live") resolve(state);
|
|
649
|
+
else if (state.status === "refused") reject(group.refusal ?? new TransportError({ code: "unavailable", message: "The home node refused this subscription" }));
|
|
650
|
+
else return;
|
|
651
|
+
off();
|
|
652
|
+
group.pendingReady.delete(cancel);
|
|
653
|
+
cancelReady = undefined;
|
|
654
|
+
});
|
|
655
|
+
const cancel = (/** @type {TransportError} */ error) => {
|
|
656
|
+
off();
|
|
657
|
+
group.pendingReady.delete(cancel);
|
|
658
|
+
cancelReady = undefined;
|
|
659
|
+
reject(error);
|
|
660
|
+
};
|
|
661
|
+
group.pendingReady.add(cancel);
|
|
662
|
+
cancelReady = cancel;
|
|
663
|
+
});
|
|
664
|
+
// A holder that never looks at `ready` must not surface a refusal as unhandled.
|
|
665
|
+
ready.catch(() => undefined);
|
|
625
666
|
let active = true;
|
|
626
|
-
|
|
667
|
+
const unsubscribe = () => {
|
|
627
668
|
if (!active) return;
|
|
628
669
|
active = false;
|
|
629
|
-
|
|
630
|
-
|
|
670
|
+
unwatch?.();
|
|
671
|
+
cancelReady?.(new TransportError({ code: "connection_lost", message: "Subscription handle closed" }));
|
|
672
|
+
group.listeners.delete(storedListener);
|
|
673
|
+
if (group.listeners.size === 0) {
|
|
631
674
|
this.#dropEventGroup(key, group);
|
|
632
675
|
const request = sessionId === undefined
|
|
633
676
|
? /** @type {const} */ ({ subscriptionId: group.subscriptionId, type: "event.unsubscribe" })
|
|
@@ -635,6 +678,49 @@ export class MessagePortKernelRpcClient {
|
|
|
635
678
|
void this.#request(request).catch(() => undefined);
|
|
636
679
|
}
|
|
637
680
|
};
|
|
681
|
+
return /** @type {EventSubscription} */ (Object.defineProperty(Object.assign(unsubscribe, { ready }), "state", { get: () => cell.state }));
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/** @param {EventSubscribeOptions | undefined} options @returns {EventSubscription} */
|
|
685
|
+
#lostEventSubscription(options) {
|
|
686
|
+
const cell = new SubscriptionStateCell();
|
|
687
|
+
cell.report("lost");
|
|
688
|
+
const unwatch = options?.onState && cell.watch(options.onState);
|
|
689
|
+
const ready = Promise.reject(new TransportError({ code: "connection_lost", message: "Kernel RPC port is closed" }));
|
|
690
|
+
ready.catch(() => undefined);
|
|
691
|
+
const unsubscribe = () => unwatch?.();
|
|
692
|
+
return /** @type {EventSubscription} */ (Object.defineProperty(Object.assign(unsubscribe, { ready }), "state", { get: () => cell.state }));
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* @param {string} key
|
|
697
|
+
* @param {string | undefined} sessionId
|
|
698
|
+
* @param {KernelEventType} eventType
|
|
699
|
+
* @returns {EventGroup}
|
|
700
|
+
*/
|
|
701
|
+
#openEventGroup(key, sessionId, eventType) {
|
|
702
|
+
const subscriptionId = this.#newSubscriptionId();
|
|
703
|
+
/** @type {EventGroup} */
|
|
704
|
+
const group = { cell: new SubscriptionStateCell(), eventType, listeners: new Set(), pendingReady: new Set(), sessionId, subscriptionId };
|
|
705
|
+
this.#eventGroupsByKey.set(key, group);
|
|
706
|
+
this.#eventGroupsBySubscription.set(subscriptionId, group);
|
|
707
|
+
const request = sessionId === undefined
|
|
708
|
+
? /** @type {const} */ ({ eventType, subscriptionId, type: "event.subscribe" })
|
|
709
|
+
: /** @type {const} */ ({ eventType, sessionId, subscriptionId, type: "stage.event.subscribe" });
|
|
710
|
+
void this.#request(request).then((reply) => {
|
|
711
|
+
if (this.#eventGroupsByKey.get(key) !== group) return;
|
|
712
|
+
// `{ subscriptionState: 1 }` means state events follow, before or after this
|
|
713
|
+
// reply. `null` means none will come for this subscription (an older kernel, or
|
|
714
|
+
// a type a stage session adapter serves): live, but unconfirmed.
|
|
715
|
+
if (reply === null && !group.cell.state) group.cell.report("live");
|
|
716
|
+
}, (error) => {
|
|
717
|
+
if (this.#eventGroupsByKey.get(key) !== group) return;
|
|
718
|
+
group.refusal = error;
|
|
719
|
+
group.cell.report("refused");
|
|
720
|
+
this.#dropEventGroup(key, group);
|
|
721
|
+
warnSubscriptionRejected("event", eventType, sessionId, error);
|
|
722
|
+
});
|
|
723
|
+
return group;
|
|
638
724
|
}
|
|
639
725
|
|
|
640
726
|
/**
|
|
@@ -753,6 +839,11 @@ export class MessagePortKernelRpcClient {
|
|
|
753
839
|
this.#eventGroupsBySubscription.delete(group.subscriptionId);
|
|
754
840
|
}
|
|
755
841
|
|
|
842
|
+
/** @param {EventGroup} group @param {TransportError} error */
|
|
843
|
+
#cancelEventGroupReady(group, error) {
|
|
844
|
+
for (const cancel of [...group.pendingReady]) cancel(error);
|
|
845
|
+
}
|
|
846
|
+
|
|
756
847
|
/**
|
|
757
848
|
* @param {string} key
|
|
758
849
|
* @param {LiveQueryGroup} group
|
|
@@ -851,11 +942,12 @@ class BoundStageRpcSession {
|
|
|
851
942
|
* @template {KernelEventType} T
|
|
852
943
|
* @param {T} type
|
|
853
944
|
* @param {(event: import("@econ-v1/domain").KernelEventByType<T>) => void} listener
|
|
854
|
-
* @
|
|
945
|
+
* @param {EventSubscribeOptions} [options]
|
|
946
|
+
* @returns {EventSubscription}
|
|
855
947
|
*/
|
|
856
|
-
subscribe(type, listener) {
|
|
948
|
+
subscribe(type, listener, options) {
|
|
857
949
|
this.#assertOpen();
|
|
858
|
-
return this.#client.subscribeStage(this.#sessionId, type, listener);
|
|
950
|
+
return this.#client.subscribeStage(this.#sessionId, type, listener, options);
|
|
859
951
|
}
|
|
860
952
|
|
|
861
953
|
#assertOpen() {
|
|
@@ -48,15 +48,21 @@ export const ROUTE_MODES = /** @type {const} */ (["auto", "public", "private"]);
|
|
|
48
48
|
* absent means this node runs it on its own key ("My Store"). */
|
|
49
49
|
/** @typedef {{ readonly name: string, readonly peerNodeId?: string }} ModelRef */
|
|
50
50
|
|
|
51
|
-
/** What the stage already knows, so the overlay opens on it instead of a default.
|
|
52
|
-
|
|
51
|
+
/** What the stage already knows, so the overlay opens on it instead of a default.
|
|
52
|
+
* `onSelect` hears each Select at once, while the overlay stays open for the chips:
|
|
53
|
+
* the pick carries `model` and the chips as they stand. The promise still resolves
|
|
54
|
+
* when the overlay closes, with the final pick, so a stage that applies both must
|
|
55
|
+
* treat the same model twice as one choice. A host before it ignores `onSelect`. */
|
|
56
|
+
/** @typedef {{ readonly current?: ModelRef, readonly routeMode?: RouteMode, readonly webSearch?: WebSearchChoice, readonly onSelect?: (pick: ModelPick) => void }} ModelPickRequest */
|
|
53
57
|
|
|
54
58
|
/** `model` is present only when the owner pressed Select on a row; absent means
|
|
55
59
|
* "keep whatever model the stage already had" — the owner changed only the
|
|
56
60
|
* web-search chip (or nothing but still closed with a chip change). `label` is
|
|
57
61
|
* the catalog's `picker_label ?? name`, so a pill or chip shows the same words
|
|
58
|
-
* the overlay did.
|
|
59
|
-
|
|
62
|
+
* the overlay did. `storeName` is the seller's store as the overlay named it
|
|
63
|
+
* (this node's own `mine.name`, or the peer's), so a chip can say whose store
|
|
64
|
+
* sells the model. */
|
|
65
|
+
/** @typedef {{ readonly model?: ModelRef, readonly label?: string, readonly storeName?: string, readonly routeMode: RouteMode, readonly webSearch: WebSearchChoice }} ModelPick */
|
|
60
66
|
|
|
61
67
|
/** Resolves `undefined` when the owner closes without choosing. Rejects with a
|
|
62
68
|
* `DomainError` `conflict` while another `open()` is still pending — the overlay
|
package/src/protocol.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/** @import { AppEventPayload, AppEventType, ClientError, CoreKernelEventType, DomainEvent, JsonObject, JsonValue, KernelEventPayload, QueryDiff, QueryName } from '@econ-v1/domain' */
|
|
4
4
|
/** @import { NodeReachability } from './transport-contract.js' */
|
|
5
|
+
/** @import { SubscriptionState } from './client.js' */
|
|
5
6
|
/** @typedef {{ readonly occurredAt: string; readonly payload: { readonly state?: string }; readonly type: "device-cleanup.changed" }} DeviceCleanupDomainEvent */
|
|
6
7
|
/** @typedef {DomainEvent | DeviceCleanupDomainEvent} ProtocolDomainEvent */
|
|
7
8
|
/** @typedef {CoreKernelEventType | "device-cleanup.changed"} ProtocolCoreKernelEventType */
|
|
@@ -142,6 +143,8 @@ export function serializeRpcEvent(event) {
|
|
|
142
143
|
return stringify({ diff: projectQueryDiff(event.diff), subscriptionId: event.subscriptionId, type: event.type });
|
|
143
144
|
if (event.type === "live-query.failed")
|
|
144
145
|
return stringify({ message: event.message, subscriptionId: event.subscriptionId, type: event.type });
|
|
146
|
+
if (event.type === "subscription.state")
|
|
147
|
+
return stringify({ state: event.state, subscriptionId: event.subscriptionId, type: event.type });
|
|
145
148
|
return stringify({ event: projectDomainEvent(event.event), subscriptionId: event.subscriptionId, type: event.type });
|
|
146
149
|
}
|
|
147
150
|
/**
|
|
@@ -159,8 +162,26 @@ export function deserializeRpcEvent(serialized) {
|
|
|
159
162
|
return { message: stringField(value, "message"), subscriptionId, type: value.type };
|
|
160
163
|
if (value.type === "kernel.event")
|
|
161
164
|
return { event: domainEventField(value), subscriptionId, type: value.type };
|
|
165
|
+
// Sent to one event subscription only (ADR-039). An older client throws below
|
|
166
|
+
// and drops it, which is the fallback it already had.
|
|
167
|
+
if (value.type === "subscription.state")
|
|
168
|
+
return { state: subscriptionStateField(value), subscriptionId, type: value.type };
|
|
162
169
|
throw new TypeError("Unknown RPC event type");
|
|
163
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* @param {JsonObject} value
|
|
173
|
+
* @returns {SubscriptionState}
|
|
174
|
+
*/
|
|
175
|
+
function subscriptionStateField(value) {
|
|
176
|
+
const { confirmed, generation, reason, status } = objectField(value, "state");
|
|
177
|
+
if (typeof confirmed !== "boolean" || !Number.isSafeInteger(generation) || /** @type {number} */ (generation) < 0 ||
|
|
178
|
+
!["live", "lost", "pending", "refused"].includes(/** @type {string} */ (status)) ||
|
|
179
|
+
!(reason === undefined || ["resubscribed", "source_restarted", "source_unavailable", "subscribed"].includes(/** @type {string} */ (reason)))) {
|
|
180
|
+
throw new TypeError("Expected a subscription state");
|
|
181
|
+
}
|
|
182
|
+
// Every field was checked against the closed vocabulary just above; this drops any other.
|
|
183
|
+
return /** @type {SubscriptionState} */ ({ confirmed, generation, ...(reason === undefined ? {} : { reason }), status });
|
|
184
|
+
}
|
|
164
185
|
/**
|
|
165
186
|
* @param {unknown} value
|
|
166
187
|
* @returns {string}
|
|
@@ -909,5 +930,6 @@ function entityActionField(value) {
|
|
|
909
930
|
* @typedef {| { readonly diff: QueryDiff<JsonValue>; readonly subscriptionId: string; readonly type: "live-query.changed" }
|
|
910
931
|
* | { readonly name: string; readonly payload: JsonValue; readonly requestId: string; readonly type: "ui.request" }
|
|
911
932
|
* | { readonly message: string; readonly subscriptionId: string; readonly type: "live-query.failed" }
|
|
912
|
-
* | { readonly event: ProtocolDomainEvent; readonly subscriptionId: string; readonly type: "kernel.event" }
|
|
933
|
+
* | { readonly event: ProtocolDomainEvent; readonly subscriptionId: string; readonly type: "kernel.event" }
|
|
934
|
+
* | { readonly state: SubscriptionState; readonly subscriptionId: string; readonly type: "subscription.state" }} RpcEvent
|
|
913
935
|
*/
|
package/src/stage-context.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
/** @typedef {import("@econ-v1/domain").KernelEventType} KernelEventType */
|
|
4
4
|
/** @typedef {import("@econ-v1/domain").QueryName} QueryName */
|
|
5
5
|
/** @typedef {import("./client.js").Unsubscribe} Unsubscribe */
|
|
6
|
+
/** @typedef {import("./client.js").EventSubscribeOptions} EventSubscribeOptions */
|
|
7
|
+
/** @typedef {import("./client.js").EventSubscription} EventSubscription */
|
|
6
8
|
/** @typedef {import("./dialog-contract.js").DialogCenter} DialogCenter */
|
|
7
9
|
/** @typedef {import("./model-picker-contract.js").ModelPickerCenter} ModelPickerCenter */
|
|
8
10
|
/** @typedef {import("./system-notice-contract.js").SystemNoticeCenter} SystemNoticeCenter */
|
|
@@ -18,7 +20,7 @@
|
|
|
18
20
|
* readonly app: { readonly name: string, readonly version: string },
|
|
19
21
|
* readonly events: {
|
|
20
22
|
* publish<T extends KernelEventType>(type: T, payload: import("@econ-v1/domain").KernelEventPayload<T>): Promise<void>,
|
|
21
|
-
* subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void):
|
|
23
|
+
* subscribe<T extends KernelEventType>(type: T, listener: (event: import("@econ-v1/domain").KernelEventByType<T>) => void, options?: EventSubscribeOptions): EventSubscription
|
|
22
24
|
* },
|
|
23
25
|
* invokeCapability<T>(capability: string, payload: unknown): Promise<T>,
|
|
24
26
|
* liveQuery<T>(name: QueryName, params: unknown, listener: (diff: import("@econ-v1/domain").QueryDiff<T>) => void): Unsubscribe,
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
/** @typedef {import("./client.js").SubscriptionState} SubscriptionState */
|
|
4
|
+
/** @typedef {{ readonly onState: (state: SubscriptionState) => void, told: boolean }} SubscriptionStateHolder */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* One subscription's state and the holders watching it (ADR-039). Every layer that
|
|
8
|
+
* carries a subscription (a carrier, the managed client, the kernel lease, the RPC
|
|
9
|
+
* group) keeps one, so they all fold states the same way.
|
|
10
|
+
*
|
|
11
|
+
* Each `live` is the next generation, and a `live` reported as "subscribed" after an
|
|
12
|
+
* earlier one reads "resubscribed": whatever restarted below (a carrier, a kernel)
|
|
13
|
+
* counts from 1 again, but a holder never sees a generation twice. A repeated state
|
|
14
|
+
* that is not `live` is not re-sent. A holder that joins when there is a state gets
|
|
15
|
+
* it on a microtask, unless a transition reached it first.
|
|
16
|
+
*/
|
|
17
|
+
export class SubscriptionStateCell {
|
|
18
|
+
#generation = 0;
|
|
19
|
+
/** @type {Set<SubscriptionStateHolder>} */
|
|
20
|
+
#holders = new Set();
|
|
21
|
+
/** @type {SubscriptionState | undefined} */
|
|
22
|
+
#state;
|
|
23
|
+
get state() {
|
|
24
|
+
return this.#state;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* @param {(state: SubscriptionState) => void} onState
|
|
28
|
+
* @returns {() => void}
|
|
29
|
+
*/
|
|
30
|
+
watch(onState) {
|
|
31
|
+
/** @type {SubscriptionStateHolder} */
|
|
32
|
+
const holder = { onState, told: false };
|
|
33
|
+
this.#holders.add(holder);
|
|
34
|
+
void Promise.resolve().then(() => {
|
|
35
|
+
if (this.#holders.has(holder) && !holder.told && this.#state !== undefined)
|
|
36
|
+
tell(holder, this.#state);
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
this.#holders.delete(holder);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* @param {SubscriptionState["status"]} status
|
|
44
|
+
* @param {boolean} [confirmed] ignored unless `live`
|
|
45
|
+
* @param {SubscriptionState["reason"]} [reason] ignored unless `live`
|
|
46
|
+
* @returns {void}
|
|
47
|
+
*/
|
|
48
|
+
report(status, confirmed = false, reason = "subscribed") {
|
|
49
|
+
if (status === "live") {
|
|
50
|
+
if (this.#generation++ > 0 && reason === "subscribed")
|
|
51
|
+
reason = "resubscribed";
|
|
52
|
+
}
|
|
53
|
+
else if (this.#state?.status === status)
|
|
54
|
+
return;
|
|
55
|
+
/** @type {SubscriptionState} */
|
|
56
|
+
const state = status === "live"
|
|
57
|
+
? { confirmed, generation: this.#generation, reason, status }
|
|
58
|
+
: { confirmed: false, generation: this.#generation, status };
|
|
59
|
+
this.#state = state;
|
|
60
|
+
for (const holder of [...this.#holders])
|
|
61
|
+
tell(holder, state);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** @param {SubscriptionStateHolder} holder @param {SubscriptionState} state */
|
|
66
|
+
function tell(holder, state) {
|
|
67
|
+
holder.told = true;
|
|
68
|
+
try {
|
|
69
|
+
holder.onState(state);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// One holder's failure must not starve the others.
|
|
73
|
+
}
|
|
74
|
+
}
|