@zlink-systems/framework 0.30.0 → 0.30.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/LICENSE +150 -68
- package/dist/.tsbuildinfo +1 -1
- package/dist/contracts/Actors/ZLinkActorClient.d.ts +2 -1
- package/dist/contracts/Channels/Calls.d.ts +2 -1
- package/dist/contracts/Common/ZLinkMessageMetadata.js +11 -5
- package/dist/contracts/Handlers/Attributes.d.ts +5 -13
- package/dist/contracts/Handlers/Attributes.js +7 -11
- package/dist/contracts/Handlers/JsonContract.d.ts +2 -46
- package/dist/contracts/Handlers/JsonContract.js +4 -153
- package/dist/contracts/Spots/Contracts.d.ts +2 -1
- package/dist/nest-integration.d.ts +1 -1
- package/dist/nest-integration.js +2 -1
- package/dist/runtime/actors/actor-client.d.ts +1 -1
- package/dist/runtime/actors/actor-client.js +14 -12
- package/dist/runtime/actors/actor-handoff.d.ts +1 -1
- package/dist/runtime/actors/actor-handoff.js +7 -4
- package/dist/runtime/actors/actor-join-relocation.d.ts +1 -0
- package/dist/runtime/actors/actor-local-native-join.js +9 -12
- package/dist/runtime/actors/actor-remote-wire.js +15 -0
- package/dist/runtime/actors/actor-routed-join-transport.d.ts +6 -2
- package/dist/runtime/actors/actor-routed-json-request.d.ts +2 -0
- package/dist/runtime/actors/index.d.ts +2 -1
- package/dist/runtime/actors/index.js +18 -6
- package/dist/runtime/actors/spot-actor-dispatch.js +2 -2
- package/dist/runtime/admission.d.ts +1 -1
- package/dist/runtime/admission.js +15 -5
- package/dist/runtime/application-jobs/application-ingress-record-owner.d.ts +6 -8
- package/dist/runtime/application-jobs/application-ingress-record-owner.js +39 -22
- package/dist/runtime/application-jobs/application-job-queue-scope.d.ts +2 -1
- package/dist/runtime/application-jobs/application-job-queue-scope.js +37 -22
- package/dist/runtime/application-jobs/contracts.d.ts +10 -1
- package/dist/runtime/backend/contracts/index.d.ts +18 -9
- package/dist/runtime/backend/mesh-completion-table.d.ts +9 -1
- package/dist/runtime/backend/mesh-completion-table.js +149 -49
- package/dist/runtime/backend/mesh-dispatch-pump.d.ts +3 -0
- package/dist/runtime/backend/mesh-dispatch-pump.js +32 -11
- package/dist/runtime/backend/node/node-backend-adapter-support.d.ts +2 -2
- package/dist/runtime/backend/node/node-backend-adapter-support.js +16 -9
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.d.ts +1 -1
- package/dist/runtime/backend/node/node-dealer-channel-client-transport.js +5 -2
- package/dist/runtime/backend/node/node-raw-binding-port.js +42 -22
- package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +13 -5
- package/dist/runtime/backend/node/node-raw-mesh-backend.js +69 -51
- package/dist/runtime/backend/node/node-socket-backend-adapter.js +6 -6
- package/dist/runtime/backend/raw-binding-port.d.ts +2 -2
- package/dist/runtime/backend/runtime-message.d.ts +1 -0
- package/dist/runtime/backend/runtime-message.js +5 -0
- package/dist/runtime/backend/runtime-values.d.ts +1 -0
- package/dist/runtime/backend/runtime-values.js +2 -1
- package/dist/runtime/channels/channel-clients.d.ts +1 -0
- package/dist/runtime/channels/channel-clients.js +58 -21
- package/dist/runtime/channels/channel-dispatch-pipeline.d.ts +3 -2
- package/dist/runtime/channels/channel-dispatch-pipeline.js +20 -11
- package/dist/runtime/channels/channel-dispatch-services.d.ts +1 -0
- package/dist/runtime/channels/channel-dispatch-services.js +45 -0
- package/dist/runtime/channels/channel-dispatchers.d.ts +1 -1
- package/dist/runtime/channels/channel-dispatchers.js +27 -26
- package/dist/runtime/channels/channel-envelope-inspection.d.ts +1 -2
- package/dist/runtime/channels/channel-envelope-inspection.js +1 -16
- package/dist/runtime/channels/channel-envelope.d.ts +1 -0
- package/dist/runtime/channels/channel-envelope.js +83 -8
- package/dist/runtime/channels/channel-outbound-operations.d.ts +2 -2
- package/dist/runtime/channels/channel-outbound-operations.js +8 -8
- package/dist/runtime/channels/channel-runtime-manager.d.ts +6 -6
- package/dist/runtime/channels/channel-runtime-manager.js +12 -12
- package/dist/runtime/channels/channel-transports.d.ts +18 -15
- package/dist/runtime/channels/channel-transports.js +48 -31
- package/dist/runtime/channels/local-spot-route-transport.d.ts +1 -1
- package/dist/runtime/channels/local-spot-route-transport.js +2 -1
- package/dist/runtime/channels/router-socket-spot-route-transport.d.ts +2 -2
- package/dist/runtime/channels/router-socket-spot-route-transport.js +4 -4
- package/dist/runtime/channels/source-spot-router.d.ts +2 -2
- package/dist/runtime/channels/source-spot-router.js +4 -4
- package/dist/runtime/channels/spot-node-route-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-node-route-transport.js +4 -4
- package/dist/runtime/channels/spot-route-bridge-transport.d.ts +2 -2
- package/dist/runtime/channels/spot-route-bridge-transport.js +4 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.d.ts +5 -4
- package/dist/runtime/channels/spot-route-dispatch-strategy.js +18 -18
- package/dist/runtime/execution/serial-execution-queue.d.ts +1 -0
- package/dist/runtime/execution/serial-execution-queue.js +1 -0
- package/dist/runtime/foundation/actor-join-recovery-codec.js +2 -2
- package/dist/runtime/foundation/durable-service-request.d.ts +14 -0
- package/dist/runtime/foundation/durable-service-request.js +98 -0
- package/dist/runtime/foundation/operation-identity.d.ts +1 -0
- package/dist/runtime/foundation/operation-identity.js +5 -1
- package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +22 -5
- package/dist/runtime/foundation/raw-service-mesh-runtime.js +356 -232
- package/dist/runtime/foundation/service-relocation-object-owner.d.ts +1 -0
- package/dist/runtime/foundation/service-relocation-object-owner.js +1 -0
- package/dist/runtime/foundation/service-relocation-runtime.d.ts +2 -0
- package/dist/runtime/foundation/service-relocation-runtime.js +13 -1
- package/dist/runtime/foundation/service-runtime-contracts.d.ts +2 -0
- package/dist/runtime/foundation/service-stateful-runtime.d.ts +4 -4
- package/dist/runtime/foundation/service-stateful-runtime.js +44 -103
- package/dist/runtime/foundation/service-stateful-wire-codec.d.ts +0 -5
- package/dist/runtime/foundation/service-topology-registry.d.ts +12 -2
- package/dist/runtime/foundation/service-topology-registry.js +61 -27
- package/dist/runtime/foundation/service-wire-m6a-codec.d.ts +3 -3
- package/dist/runtime/foundation/service-wire-m6a-codec.js +36 -38
- package/dist/runtime/handlers/handler-instance-scope.d.ts +8 -0
- package/dist/runtime/handlers/handler-instance-scope.js +54 -11
- package/dist/runtime/host/actor-runtime-options-factory.js +2 -2
- package/dist/runtime/host/application-job-queue.d.ts +19 -7
- package/dist/runtime/host/application-job-queue.js +150 -42
- package/dist/runtime/host/entry-actor-runtime.d.ts +1 -0
- package/dist/runtime/host/entry-actor-runtime.js +3 -0
- package/dist/runtime/host/index.d.ts +7 -1
- package/dist/runtime/host/index.js +142 -118
- package/dist/runtime/host/remote-bound-session-relay.js +2 -18
- package/dist/runtime/host/route-mesh-runtime.js +1 -1
- package/dist/runtime/host/service-relocation-control.d.ts +1 -0
- package/dist/runtime/host/service-relocation-control.js +10 -4
- package/dist/runtime/host/service-relocation-host-runtime.d.ts +6 -8
- package/dist/runtime/host/service-relocation-host-runtime.js +213 -241
- package/dist/runtime/host/spot-address-transport.js +3 -2
- package/dist/runtime/host/spot-runtime-options-factory.js +1 -0
- package/dist/runtime/locations/actor-location-claims.d.ts +2 -2
- package/dist/runtime/locations/actor-location-claims.js +34 -19
- package/dist/runtime/locations/lifecycle.d.ts +1 -2
- package/dist/runtime/locations/lifecycle.js +2 -5
- package/dist/runtime/locations/runtime.d.ts +1 -1
- package/dist/runtime/locations/runtime.js +24 -23
- package/dist/runtime/messaging/framework-json-v1.d.ts +4 -6
- package/dist/runtime/messaging/framework-json-v1.js +38 -294
- package/dist/runtime/messaging/packet-name.d.ts +1 -1
- package/dist/runtime/messaging/packet-name.js +8 -24
- package/dist/runtime/messaging/request-result.d.ts +2 -0
- package/dist/runtime/messaging/request-result.js +54 -0
- package/dist/runtime/messaging/submission-result.d.ts +1 -0
- package/dist/runtime/messaging/submission-result.js +5 -2
- package/dist/runtime/protocol/service_wire_codec.generated.d.ts +15 -0
- package/dist/runtime/protocol/service_wire_codec.generated.js +144 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.d.ts +9 -0
- package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +14 -1
- package/dist/runtime/spots/formal-remote-actor-admission-registry.d.ts +7 -2
- package/dist/runtime/spots/formal-remote-actor-admission-registry.js +33 -19
- package/dist/runtime/spots/index.d.ts +3 -0
- package/dist/runtime/spots/index.js +9 -2
- package/dist/runtime/spots/spot-activation.d.ts +1 -0
- package/dist/runtime/spots/spot-activation.js +17 -8
- package/dist/runtime/spots/spot-entry-activation.js +6 -2
- package/dist/runtime/spots/spot-handler-registry.d.ts +3 -1
- package/dist/runtime/spots/spot-handler-registry.js +18 -8
- package/dist/runtime/spots/spot-node-autoconnect.js +4 -3
- package/dist/runtime/spots/spot-outbound.d.ts +3 -0
- package/dist/runtime/spots/spot-outbound.js +24 -15
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.d.ts +1 -0
- package/dist/runtime/spots/spot-routed-spot-packet-dispatch.js +1 -1
- package/dist/runtime/spots/spot-runtime-ports.d.ts +1 -0
- package/dist/runtime/spots/spot-subscription-dispatch.js +0 -3
- package/dist/runtime/spots/spot-timer.js +1 -0
- package/dist/runtime/streams/stream-session-runtime.d.ts +1 -1
- package/dist/runtime/streams/stream-session-runtime.js +13 -27
- package/package.json +2 -2
- package/src/contracts/Actors/ZLinkActorClient.ts +2 -1
- package/src/contracts/Channels/Calls.ts +2 -1
- package/src/contracts/Common/ZLinkMessageMetadata.ts +13 -8
- package/src/contracts/Handlers/Attributes.ts +14 -21
- package/src/contracts/Handlers/JsonContract.ts +8 -216
- package/src/contracts/Spots/Contracts.ts +2 -1
- package/src/nest-integration.ts +1 -0
- package/src/runtime/actors/actor-client.ts +40 -16
- package/src/runtime/actors/actor-handoff.ts +9 -4
- package/src/runtime/actors/actor-join-relocation.ts +1 -0
- package/src/runtime/actors/actor-local-native-join.ts +17 -26
- package/src/runtime/actors/actor-remote-wire.ts +17 -0
- package/src/runtime/actors/actor-routed-join-transport.ts +14 -4
- package/src/runtime/actors/actor-routed-json-request.ts +10 -2
- package/src/runtime/actors/index.ts +19 -5
- package/src/runtime/actors/spot-actor-dispatch.ts +4 -2
- package/src/runtime/admission.ts +18 -5
- package/src/runtime/application-jobs/application-ingress-record-owner.ts +41 -25
- package/src/runtime/application-jobs/application-job-queue-scope.ts +51 -22
- package/src/runtime/application-jobs/contracts.ts +14 -1
- package/src/runtime/backend/contracts/index.ts +53 -14
- package/src/runtime/backend/mesh-completion-table.ts +156 -57
- package/src/runtime/backend/mesh-dispatch-pump.ts +40 -10
- package/src/runtime/backend/node/node-backend-adapter-support.ts +17 -8
- package/src/runtime/backend/node/node-dealer-channel-client-transport.ts +12 -2
- package/src/runtime/backend/node/node-raw-binding-port.ts +57 -30
- package/src/runtime/backend/node/node-raw-mesh-backend.ts +128 -65
- package/src/runtime/backend/node/node-socket-backend-adapter.ts +21 -6
- package/src/runtime/backend/raw-binding-port.ts +7 -2
- package/src/runtime/backend/runtime-message.ts +6 -0
- package/src/runtime/backend/runtime-values.ts +1 -0
- package/src/runtime/channels/channel-clients.ts +90 -41
- package/src/runtime/channels/channel-dispatch-pipeline.ts +69 -34
- package/src/runtime/channels/channel-dispatch-services.ts +69 -1
- package/src/runtime/channels/channel-dispatchers.ts +29 -27
- package/src/runtime/channels/channel-envelope-inspection.ts +2 -16
- package/src/runtime/channels/channel-envelope.ts +133 -8
- package/src/runtime/channels/channel-outbound-operations.ts +22 -8
- package/src/runtime/channels/channel-runtime-manager.ts +29 -12
- package/src/runtime/channels/channel-transports.ts +128 -60
- package/src/runtime/channels/local-spot-route-transport.ts +3 -1
- package/src/runtime/channels/router-socket-spot-route-transport.ts +13 -4
- package/src/runtime/channels/source-spot-router.ts +8 -4
- package/src/runtime/channels/spot-node-route-transport.ts +8 -4
- package/src/runtime/channels/spot-route-bridge-transport.ts +6 -4
- package/src/runtime/channels/spot-route-dispatch-strategy.ts +47 -18
- package/src/runtime/execution/serial-execution-queue.ts +2 -0
- package/src/runtime/foundation/actor-join-recovery-codec.ts +2 -2
- package/src/runtime/foundation/durable-service-request.ts +137 -0
- package/src/runtime/foundation/operation-identity.ts +5 -1
- package/src/runtime/foundation/raw-service-mesh-runtime.ts +484 -293
- package/src/runtime/foundation/service-relocation-object-owner.ts +2 -0
- package/src/runtime/foundation/service-relocation-runtime.ts +18 -1
- package/src/runtime/foundation/service-runtime-contracts.ts +7 -1
- package/src/runtime/foundation/service-stateful-runtime.ts +67 -125
- package/src/runtime/foundation/service-stateful-wire-codec.ts +0 -5
- package/src/runtime/foundation/service-topology-registry.ts +91 -36
- package/src/runtime/foundation/service-wire-m6a-codec.ts +57 -38
- package/src/runtime/handlers/handler-instance-scope.ts +67 -16
- package/src/runtime/host/actor-runtime-options-factory.ts +13 -2
- package/src/runtime/host/application-job-queue.ts +175 -41
- package/src/runtime/host/entry-actor-runtime.ts +4 -0
- package/src/runtime/host/index.ts +201 -156
- package/src/runtime/host/remote-bound-session-relay.ts +2 -23
- package/src/runtime/host/route-mesh-runtime.ts +1 -1
- package/src/runtime/host/service-relocation-control.ts +11 -5
- package/src/runtime/host/service-relocation-host-runtime.ts +315 -291
- package/src/runtime/host/spot-address-transport.ts +4 -2
- package/src/runtime/host/spot-runtime-options-factory.ts +2 -0
- package/src/runtime/locations/actor-location-claims.ts +52 -30
- package/src/runtime/locations/lifecycle.ts +8 -26
- package/src/runtime/locations/runtime.ts +28 -24
- package/src/runtime/messaging/framework-json-v1.ts +5 -325
- package/src/runtime/messaging/packet-name.ts +5 -25
- package/src/runtime/messaging/request-result.ts +58 -0
- package/src/runtime/messaging/submission-result.ts +5 -1
- package/src/runtime/protocol/service_wire_codec.generated.ts +131 -1
- package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +4 -4
- package/src/runtime/spots/formal-remote-actor-admission-registry.ts +43 -23
- package/src/runtime/spots/index.ts +14 -2
- package/src/runtime/spots/spot-activation.ts +28 -10
- package/src/runtime/spots/spot-entry-activation.ts +9 -2
- package/src/runtime/spots/spot-handler-registry.ts +41 -8
- package/src/runtime/spots/spot-node-autoconnect.ts +6 -2
- package/src/runtime/spots/spot-outbound.ts +36 -16
- package/src/runtime/spots/spot-routed-spot-packet-dispatch.ts +2 -1
- package/src/runtime/spots/spot-runtime-ports.ts +1 -0
- package/src/runtime/spots/spot-subscription-dispatch.ts +0 -3
- package/src/runtime/spots/spot-timer.ts +5 -1
- package/src/runtime/streams/stream-session-runtime.ts +12 -29
|
@@ -1,216 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
| { readonly type: 'uint32' }
|
|
10
|
-
| { readonly type: 'int64' }
|
|
11
|
-
| { readonly type: 'uint64' }
|
|
12
|
-
| { readonly type: 'bytes' }
|
|
13
|
-
| { readonly type: 'enum'; readonly names: readonly string[] }
|
|
14
|
-
| { readonly type: 'nullable'; readonly value: ZLinkJsonSchema }
|
|
15
|
-
| { readonly type: 'array'; readonly items: ZLinkJsonSchema }
|
|
16
|
-
| { readonly type: 'record'; readonly values: ZLinkJsonSchema }
|
|
17
|
-
| {
|
|
18
|
-
readonly type: 'object';
|
|
19
|
-
readonly properties: Readonly<Record<string, ZLinkJsonSchema>>;
|
|
20
|
-
readonly required: readonly string[];
|
|
21
|
-
/** Unknown properties are ignored during decoding unless this is false. */
|
|
22
|
-
readonly additionalProperties?: boolean;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Describes the request and optional reply fields carried under one packet
|
|
27
|
-
* name by the default JSON serializer.
|
|
28
|
-
*/
|
|
29
|
-
export interface ZLinkPacketJsonContract {
|
|
30
|
-
readonly payload: ZLinkJsonSchema;
|
|
31
|
-
readonly reply?: ZLinkJsonSchema;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const ZLINK_PACKET_JSON_CONTRACTS = Symbol.for('@zlink-systems/framework:packet-json-contracts');
|
|
35
|
-
|
|
36
|
-
export function defineZLinkPacketJsonContract(
|
|
37
|
-
packetName: string,
|
|
38
|
-
contract: ZLinkPacketJsonContract
|
|
39
|
-
): ZLinkPacketJsonContract {
|
|
40
|
-
if (packetName.trim().length === 0) {
|
|
41
|
-
throw new TypeError('ZLink packet name must not be empty.');
|
|
42
|
-
}
|
|
43
|
-
const runtimeContract: unknown = contract;
|
|
44
|
-
if (typeof runtimeContract !== 'object' || runtimeContract === null) {
|
|
45
|
-
throw new TypeError('ZLink packet JSON contract must be an object.');
|
|
46
|
-
}
|
|
47
|
-
const normalizedContract = runtimeContract as ZLinkPacketJsonContract;
|
|
48
|
-
const normalized = Object.freeze({
|
|
49
|
-
payload: normalizeJsonSchema(normalizedContract.payload, new Set(), 0),
|
|
50
|
-
...(normalizedContract.reply === undefined
|
|
51
|
-
? {}
|
|
52
|
-
: { reply: normalizeJsonSchema(normalizedContract.reply, new Set(), 0) })
|
|
53
|
-
});
|
|
54
|
-
const contracts = packetJsonContracts();
|
|
55
|
-
const current = contracts.get(packetName);
|
|
56
|
-
if (current !== undefined && canonicalContract(current) !== canonicalContract(normalized)) {
|
|
57
|
-
throw new TypeError(
|
|
58
|
-
`ZLink packet '${packetName}' has conflicting JSON contracts in one process.`
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
if (current !== undefined) return current;
|
|
62
|
-
contracts.set(packetName, normalized);
|
|
63
|
-
return normalized;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export function readZLinkPacketJsonContract(
|
|
67
|
-
packetName: string
|
|
68
|
-
): ZLinkPacketJsonContract | undefined {
|
|
69
|
-
return packetJsonContracts().get(packetName);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function normalizeJsonSchema(
|
|
73
|
-
schema: ZLinkJsonSchema,
|
|
74
|
-
parents: Set<object>,
|
|
75
|
-
depth: number
|
|
76
|
-
): ZLinkJsonSchema {
|
|
77
|
-
// Keep the runtime boundary defensive for JavaScript callers even though
|
|
78
|
-
// the TypeScript signature describes the accepted shape.
|
|
79
|
-
const runtimeSchema: unknown = schema;
|
|
80
|
-
if (
|
|
81
|
-
typeof runtimeSchema !== 'object' ||
|
|
82
|
-
runtimeSchema === null ||
|
|
83
|
-
depth > MAX_CONTRACT_SCHEMA_DEPTH
|
|
84
|
-
) {
|
|
85
|
-
throw new TypeError(
|
|
86
|
-
`ZLink packet JSON schema must be an acyclic object with at most ${MAX_CONTRACT_SCHEMA_DEPTH} levels.`
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
const normalizedSchema = runtimeSchema as ZLinkJsonSchema;
|
|
90
|
-
if (parents.has(normalizedSchema))
|
|
91
|
-
throw new TypeError('ZLink packet JSON schema must not contain a cycle.');
|
|
92
|
-
const nextParents = new Set(parents).add(normalizedSchema);
|
|
93
|
-
switch (normalizedSchema.type) {
|
|
94
|
-
case 'boolean':
|
|
95
|
-
case 'string':
|
|
96
|
-
case 'number':
|
|
97
|
-
case 'int32':
|
|
98
|
-
case 'uint32':
|
|
99
|
-
case 'int64':
|
|
100
|
-
case 'uint64':
|
|
101
|
-
case 'bytes':
|
|
102
|
-
return Object.freeze({ type: normalizedSchema.type });
|
|
103
|
-
case 'enum': {
|
|
104
|
-
if (
|
|
105
|
-
!Array.isArray(normalizedSchema.names) ||
|
|
106
|
-
normalizedSchema.names.length === 0 ||
|
|
107
|
-
normalizedSchema.names.some((name) => typeof name !== 'string' || name.length === 0)
|
|
108
|
-
) {
|
|
109
|
-
throw new TypeError('ZLink packet enum schema requires non-empty string names.');
|
|
110
|
-
}
|
|
111
|
-
if (new Set(normalizedSchema.names).size !== normalizedSchema.names.length) {
|
|
112
|
-
throw new TypeError('ZLink packet enum schema names must be unique.');
|
|
113
|
-
}
|
|
114
|
-
return Object.freeze({ type: 'enum', names: Object.freeze([...normalizedSchema.names]) });
|
|
115
|
-
}
|
|
116
|
-
case 'nullable':
|
|
117
|
-
return Object.freeze({
|
|
118
|
-
type: 'nullable',
|
|
119
|
-
value: normalizeJsonSchema(normalizedSchema.value, nextParents, depth + 1)
|
|
120
|
-
});
|
|
121
|
-
case 'array':
|
|
122
|
-
return Object.freeze({
|
|
123
|
-
type: 'array',
|
|
124
|
-
items: normalizeJsonSchema(normalizedSchema.items, nextParents, depth + 1)
|
|
125
|
-
});
|
|
126
|
-
case 'record':
|
|
127
|
-
return Object.freeze({
|
|
128
|
-
type: 'record',
|
|
129
|
-
values: normalizeJsonSchema(normalizedSchema.values, nextParents, depth + 1)
|
|
130
|
-
});
|
|
131
|
-
case 'object': {
|
|
132
|
-
const runtimeProperties: unknown = normalizedSchema.properties;
|
|
133
|
-
if (
|
|
134
|
-
typeof runtimeProperties !== 'object' ||
|
|
135
|
-
runtimeProperties === null ||
|
|
136
|
-
Array.isArray(runtimeProperties)
|
|
137
|
-
) {
|
|
138
|
-
throw new TypeError('ZLink packet object schema properties must be an object.');
|
|
139
|
-
}
|
|
140
|
-
if (
|
|
141
|
-
!Array.isArray(normalizedSchema.required) ||
|
|
142
|
-
normalizedSchema.required.some((name) => typeof name !== 'string' || name.length === 0)
|
|
143
|
-
) {
|
|
144
|
-
throw new TypeError('ZLink packet object schema required must contain property names.');
|
|
145
|
-
}
|
|
146
|
-
if (
|
|
147
|
-
normalizedSchema.additionalProperties !== undefined &&
|
|
148
|
-
typeof normalizedSchema.additionalProperties !== 'boolean'
|
|
149
|
-
) {
|
|
150
|
-
throw new TypeError('ZLink packet object schema additionalProperties must be boolean.');
|
|
151
|
-
}
|
|
152
|
-
const properties: Record<string, ZLinkJsonSchema> = {};
|
|
153
|
-
for (const [name, property] of Object.entries(
|
|
154
|
-
runtimeProperties as Record<string, ZLinkJsonSchema>
|
|
155
|
-
)) {
|
|
156
|
-
if (isPrototypeKey(name)) {
|
|
157
|
-
throw new TypeError(`ZLink packet JSON property '${name}' is not allowed.`);
|
|
158
|
-
}
|
|
159
|
-
properties[name] = normalizeJsonSchema(property, nextParents, depth + 1);
|
|
160
|
-
}
|
|
161
|
-
if (new Set(normalizedSchema.required).size !== normalizedSchema.required.length) {
|
|
162
|
-
throw new TypeError('ZLink packet JSON required properties must be unique.');
|
|
163
|
-
}
|
|
164
|
-
for (const name of normalizedSchema.required) {
|
|
165
|
-
if (isPrototypeKey(name)) {
|
|
166
|
-
throw new TypeError(`ZLink packet JSON property '${name}' is not allowed.`);
|
|
167
|
-
}
|
|
168
|
-
if (!Object.prototype.hasOwnProperty.call(properties, name)) {
|
|
169
|
-
throw new TypeError(
|
|
170
|
-
`ZLink packet JSON required property '${name}' has no property schema.`
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return Object.freeze({
|
|
175
|
-
type: 'object',
|
|
176
|
-
properties: Object.freeze(properties),
|
|
177
|
-
required: Object.freeze([...normalizedSchema.required]),
|
|
178
|
-
...(normalizedSchema.additionalProperties === undefined
|
|
179
|
-
? {}
|
|
180
|
-
: { additionalProperties: normalizedSchema.additionalProperties })
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
throw new TypeError(
|
|
185
|
-
`ZLink packet JSON schema type '${String((normalizedSchema as { type?: unknown }).type)}' is not supported.`
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
function packetJsonContracts(): Map<string, ZLinkPacketJsonContract> {
|
|
190
|
-
const root = globalThis as typeof globalThis & Record<symbol, unknown>;
|
|
191
|
-
let contracts = root[ZLINK_PACKET_JSON_CONTRACTS] as
|
|
192
|
-
Map<string, ZLinkPacketJsonContract> | undefined;
|
|
193
|
-
if (contracts === undefined) {
|
|
194
|
-
contracts = new Map();
|
|
195
|
-
Object.defineProperty(root, ZLINK_PACKET_JSON_CONTRACTS, {
|
|
196
|
-
configurable: false,
|
|
197
|
-
enumerable: false,
|
|
198
|
-
value: contracts,
|
|
199
|
-
writable: false
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
return contracts;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function canonicalContract(value: unknown): string {
|
|
206
|
-
if (Array.isArray(value)) return `[${value.map(canonicalContract).join(',')}]`;
|
|
207
|
-
if (typeof value !== 'object' || value === null) return JSON.stringify(value);
|
|
208
|
-
return `{${Object.entries(value as Record<string, unknown>)
|
|
209
|
-
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
210
|
-
.map(([key, item]) => `${JSON.stringify(key)}:${canonicalContract(item)}`)
|
|
211
|
-
.join(',')}}`;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function isPrototypeKey(name: string): boolean {
|
|
215
|
-
return name === '__proto__' || name === 'prototype' || name === 'constructor';
|
|
216
|
-
}
|
|
1
|
+
export {
|
|
2
|
+
defineZLinkPacketJsonContract,
|
|
3
|
+
readZLinkPacketJsonContract
|
|
4
|
+
} from '@zlink-systems/stream-wire/internal/json';
|
|
5
|
+
export type {
|
|
6
|
+
ZLinkJsonSchema,
|
|
7
|
+
ZLinkPacketJsonContract
|
|
8
|
+
} from '@zlink-systems/stream-wire/internal/json';
|
|
@@ -2,6 +2,7 @@ import type { ZLinkActor } from '../Actors';
|
|
|
2
2
|
import type { ZLinkChannelRequestCall, ZLinkPublishCall, ZLinkSendCall } from '../Channels';
|
|
3
3
|
import type { RoutingId, SpotId, Type, ZLinkMessageMetadata } from '../Common';
|
|
4
4
|
import type { ZLinkSpotTimerHandler } from '../Handlers';
|
|
5
|
+
import type { ZLinkRequest } from '../Handlers/Attributes';
|
|
5
6
|
import type { ZLinkTimer, ZLinkTimerOptions } from '../Timers';
|
|
6
7
|
import type {
|
|
7
8
|
ZLinkEntrySpot,
|
|
@@ -106,7 +107,7 @@ export interface ZLinkSpotRequestCall {
|
|
|
106
107
|
instanceSpot(instanceSpotType: string): this;
|
|
107
108
|
inMesh(meshName: string): this;
|
|
108
109
|
timeout(timeoutMs: number): this;
|
|
109
|
-
submit<TReply>(signal?: AbortSignal):
|
|
110
|
+
submit<TReply>(signal?: AbortSignal): ZLinkRequest<TReply>;
|
|
110
111
|
yield<TReply>(signal?: AbortSignal): Promise<TReply>;
|
|
111
112
|
}
|
|
112
113
|
|
package/src/nest-integration.ts
CHANGED
|
@@ -77,6 +77,7 @@ export {
|
|
|
77
77
|
type ZLinkHandlerFilterScopeRunner
|
|
78
78
|
} from './runtime/channels/handler-filter-scope';
|
|
79
79
|
export {
|
|
80
|
+
registerHandlerInstanceScopeFactory as registerIntegrationHandlerInstanceScopeFactory,
|
|
80
81
|
disposeOwnedInstance as disposeIntegrationHandler,
|
|
81
82
|
disposeOwnedInstances as disposeIntegrationHandlers
|
|
82
83
|
} from './runtime/handlers/handler-instance-scope';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ZlinkStreamContentType } from '@zlink-systems/stream-wire';
|
|
2
|
+
import { createZLinkRequest } from '../messaging/request-result';
|
|
3
|
+
import type { ZLinkRequest } from '../../contracts/Handlers/Attributes';
|
|
2
4
|
import {
|
|
3
5
|
type ActorRef,
|
|
4
6
|
type RoutingId,
|
|
@@ -89,7 +91,8 @@ export interface ZLinkActorClientOptions {
|
|
|
89
91
|
parts: readonly Message[],
|
|
90
92
|
returnResponse: boolean,
|
|
91
93
|
actor: ActorRef,
|
|
92
|
-
deadlineUnixMs?: number
|
|
94
|
+
deadlineUnixMs?: number,
|
|
95
|
+
onAdmitted?: () => void
|
|
93
96
|
) => Promise<unknown> | undefined;
|
|
94
97
|
readonly sendErrorReporter?: (error: unknown) => void;
|
|
95
98
|
readonly routeTransport?: ZLinkActorRoutedJoinTransport;
|
|
@@ -118,8 +121,17 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
118
121
|
requestToActor(actorId: string, request: unknown): ZLinkActorRequestCall {
|
|
119
122
|
requireActorId(actorId);
|
|
120
123
|
return new DefaultZLinkActorRequestCall(
|
|
121
|
-
(packetName, timeoutMs, metadata, signal) =>
|
|
122
|
-
this.request(
|
|
124
|
+
(packetName, timeoutMs, metadata, signal, onAdmitted) =>
|
|
125
|
+
this.request(
|
|
126
|
+
actorId,
|
|
127
|
+
packetName,
|
|
128
|
+
request,
|
|
129
|
+
timeoutMs,
|
|
130
|
+
metadata,
|
|
131
|
+
signal,
|
|
132
|
+
'async',
|
|
133
|
+
onAdmitted
|
|
134
|
+
),
|
|
123
135
|
(packetName, timeoutMs, metadata, signal) =>
|
|
124
136
|
this.request(actorId, packetName, request, timeoutMs, metadata, signal, 'yield'),
|
|
125
137
|
actorId,
|
|
@@ -211,7 +223,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
211
223
|
timeoutMs: number | undefined,
|
|
212
224
|
metadata: ReadonlyMap<string, string>,
|
|
213
225
|
signal?: AbortSignal,
|
|
214
|
-
waitPolicy: 'async' | 'yield' = 'async'
|
|
226
|
+
waitPolicy: 'async' | 'yield' = 'async',
|
|
227
|
+
onAdmitted?: () => void
|
|
215
228
|
): Promise<TReply> {
|
|
216
229
|
throwIfAborted(signal);
|
|
217
230
|
const sourceSpotId = currentZLinkActorExecution()?.spotId ?? currentZLinkSpotSerialSourceId();
|
|
@@ -267,7 +280,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
267
280
|
parts,
|
|
268
281
|
true,
|
|
269
282
|
routedActor,
|
|
270
|
-
deadlineUnixMs
|
|
283
|
+
deadlineUnixMs,
|
|
284
|
+
onAdmitted
|
|
271
285
|
);
|
|
272
286
|
if (handoff !== undefined) {
|
|
273
287
|
const submissions = [handoff];
|
|
@@ -278,7 +292,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
278
292
|
parts,
|
|
279
293
|
true,
|
|
280
294
|
routedActor,
|
|
281
|
-
deadlineUnixMs
|
|
295
|
+
deadlineUnixMs,
|
|
296
|
+
onAdmitted
|
|
282
297
|
);
|
|
283
298
|
if (duplicate !== undefined) submissions.push(duplicate);
|
|
284
299
|
}
|
|
@@ -297,7 +312,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
297
312
|
remainingActorRequestTimeout(actorId, deadlineMs),
|
|
298
313
|
signal,
|
|
299
314
|
route,
|
|
300
|
-
messageFollow
|
|
315
|
+
messageFollow,
|
|
316
|
+
onAdmitted
|
|
301
317
|
);
|
|
302
318
|
} catch (error) {
|
|
303
319
|
if (isStaleActorError(error)) {
|
|
@@ -423,7 +439,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
423
439
|
timeoutMs: number | undefined,
|
|
424
440
|
signal?: AbortSignal,
|
|
425
441
|
route?: ZLinkResolvedActorRoute,
|
|
426
|
-
messageFollowContext?: ZLinkActorMessageFollowContext
|
|
442
|
+
messageFollowContext?: ZLinkActorMessageFollowContext,
|
|
443
|
+
onAdmitted?: () => void
|
|
427
444
|
): Promise<TReply> {
|
|
428
445
|
const node = this.requireNode(meshName);
|
|
429
446
|
if (
|
|
@@ -459,7 +476,7 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
459
476
|
this.options.routeTransport,
|
|
460
477
|
remoteActorRouteTarget(route),
|
|
461
478
|
relay,
|
|
462
|
-
{ timeoutMs, signal },
|
|
479
|
+
{ timeoutMs, signal, onAdmitted },
|
|
463
480
|
`Remote Actor request is not available for '${actor.actorId}'.`,
|
|
464
481
|
(replyParts) => JSON.parse(replyParts[0]?.getString('utf8') ?? '{}')
|
|
465
482
|
);
|
|
@@ -481,7 +498,8 @@ export class DefaultZLinkActorClient implements ZLinkActorClient {
|
|
|
481
498
|
() =>
|
|
482
499
|
node.requestToActor(actor, toMessageLikeParts(parts), {
|
|
483
500
|
flags: ZLINK_BACKEND_SEND_NONE,
|
|
484
|
-
timeoutMs
|
|
501
|
+
timeoutMs,
|
|
502
|
+
onAdmitted
|
|
485
503
|
}),
|
|
486
504
|
signal
|
|
487
505
|
);
|
|
@@ -700,7 +718,8 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
|
|
|
700
718
|
packetName: string | undefined,
|
|
701
719
|
timeoutMs: number | undefined,
|
|
702
720
|
metadata: ReadonlyMap<string, string>,
|
|
703
|
-
signal?: AbortSignal
|
|
721
|
+
signal?: AbortSignal,
|
|
722
|
+
onAdmitted?: () => void
|
|
704
723
|
) => Promise<TReply>,
|
|
705
724
|
private readonly yieldSubmitter: <TReply>(
|
|
706
725
|
packetName: string | undefined,
|
|
@@ -728,8 +747,9 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
|
|
|
728
747
|
return this;
|
|
729
748
|
}
|
|
730
749
|
|
|
731
|
-
submit<TReply>(signal?: AbortSignal):
|
|
732
|
-
|
|
750
|
+
submit<TReply>(signal?: AbortSignal): ZLinkRequest<TReply> {
|
|
751
|
+
this.rejectSelfActorRequest();
|
|
752
|
+
return createZLinkRequest((onAdmitted) => this.execute<TReply>('async', signal, onAdmitted));
|
|
733
753
|
}
|
|
734
754
|
|
|
735
755
|
yield<TReply>(signal?: AbortSignal): Promise<TReply> {
|
|
@@ -739,9 +759,12 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
|
|
|
739
759
|
return turn.yieldPromise(pending);
|
|
740
760
|
}
|
|
741
761
|
|
|
742
|
-
private execute<TReply>(
|
|
762
|
+
private execute<TReply>(
|
|
763
|
+
waitPolicy: 'async' | 'yield',
|
|
764
|
+
signal?: AbortSignal,
|
|
765
|
+
onAdmitted?: () => void
|
|
766
|
+
): Promise<TReply> {
|
|
743
767
|
ensureSingleSubmit(this.executed);
|
|
744
|
-
this.rejectSelfActorRequest();
|
|
745
768
|
this.executed = true;
|
|
746
769
|
throwIfAborted(signal);
|
|
747
770
|
const submitter = waitPolicy === 'async' ? this.asyncSubmitter : this.yieldSubmitter;
|
|
@@ -749,7 +772,8 @@ class DefaultZLinkActorRequestCall implements ZLinkActorRequestCall {
|
|
|
749
772
|
this.packet ?? resolveFrameworkPacketName(this.request, undefined, 'Actor'),
|
|
750
773
|
this.timeoutMs ?? this.defaultRequestTimeoutMs,
|
|
751
774
|
this.selectedMetadata,
|
|
752
|
-
signal
|
|
775
|
+
signal,
|
|
776
|
+
onAdmitted
|
|
753
777
|
);
|
|
754
778
|
}
|
|
755
779
|
|
|
@@ -776,7 +776,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
776
776
|
fallbackActorRef?: ActorRef,
|
|
777
777
|
deadlineUnixMs?: number,
|
|
778
778
|
messageFollowOrigin?: ZLinkMessageFollowOrigin,
|
|
779
|
-
provisionalReplay?: ZLinkActorHandoffDispatch
|
|
779
|
+
provisionalReplay?: ZLinkActorHandoffDispatch,
|
|
780
|
+
onAdmitted?: () => void
|
|
780
781
|
): Promise<unknown> | undefined {
|
|
781
782
|
const incomingContext = actorMessageFollowContext(fallbackActorRef);
|
|
782
783
|
const originalDeadlineUnixMs =
|
|
@@ -871,6 +872,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
871
872
|
});
|
|
872
873
|
});
|
|
873
874
|
releaseApplicationJobPermitForDurableHandoff();
|
|
875
|
+
onAdmitted?.();
|
|
874
876
|
if (handoff.prefixRelease !== undefined) {
|
|
875
877
|
try {
|
|
876
878
|
this.admitPendingPrefix(actorId, handoff, handoff.prefixRelease);
|
|
@@ -916,7 +918,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
916
918
|
incomingContext,
|
|
917
919
|
messageFollowOrigin
|
|
918
920
|
);
|
|
919
|
-
return this.enqueueMessageFollow(followRoute, actorId, packet);
|
|
921
|
+
return this.enqueueMessageFollow(followRoute, actorId, packet, onAdmitted);
|
|
920
922
|
}
|
|
921
923
|
this.options.onMarker?.('message_follow_rejected', actorId);
|
|
922
924
|
return Promise.reject(actorLocationStale(actorId));
|
|
@@ -973,7 +975,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
973
975
|
context,
|
|
974
976
|
messageFollowOrigin
|
|
975
977
|
);
|
|
976
|
-
return this.enqueueMessageFollow(followRoute, actorId, packet);
|
|
978
|
+
return this.enqueueMessageFollow(followRoute, actorId, packet, onAdmitted);
|
|
977
979
|
}
|
|
978
980
|
|
|
979
981
|
snapshot(actorId: string): readonly ZLinkActorHandoffPacket[] {
|
|
@@ -1440,7 +1442,8 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1440
1442
|
private enqueueMessageFollow(
|
|
1441
1443
|
entry: MessageFollowRoute,
|
|
1442
1444
|
actorId: string,
|
|
1443
|
-
packet: ZLinkActorHandoffPacket
|
|
1445
|
+
packet: ZLinkActorHandoffPacket,
|
|
1446
|
+
onAdmitted?: () => void
|
|
1444
1447
|
): Promise<unknown> {
|
|
1445
1448
|
const context = packet.messageFollowContext;
|
|
1446
1449
|
const duplicate = entry.operations.get(context.operationId);
|
|
@@ -1453,6 +1456,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1453
1456
|
this.options.onMarker?.('message_follow_rejected', actorId);
|
|
1454
1457
|
return Promise.reject(actorLocationStale(actorId));
|
|
1455
1458
|
}
|
|
1459
|
+
onAdmitted?.();
|
|
1456
1460
|
return duplicate.result;
|
|
1457
1461
|
}
|
|
1458
1462
|
const bytes = packetBytes(packet);
|
|
@@ -1474,6 +1478,7 @@ export class ZLinkActorHandoffCoordinator {
|
|
|
1474
1478
|
replyRouteId: context.replyRouteId,
|
|
1475
1479
|
result
|
|
1476
1480
|
});
|
|
1481
|
+
onAdmitted?.();
|
|
1477
1482
|
entry.tail = entry.tail.then(async () => {
|
|
1478
1483
|
try {
|
|
1479
1484
|
resolve(await this.relayMessageFollow(actorId, entry, packet));
|
|
@@ -30,6 +30,7 @@ export interface ZLinkActorJoinRelocation {
|
|
|
30
30
|
};
|
|
31
31
|
/** Target's advertised relocation state chunk cap from the accepted admission reply. */
|
|
32
32
|
readonly advertisedReceiveChunkLimitBytes?: number;
|
|
33
|
+
readonly deadlineAtMs?: number;
|
|
33
34
|
readonly signal?: AbortSignal;
|
|
34
35
|
}): Promise<{
|
|
35
36
|
readonly actorRef: ZLinkBackendActorRef;
|
|
@@ -199,33 +199,24 @@ export class ZLinkLocalNativeActorJoin {
|
|
|
199
199
|
);
|
|
200
200
|
}
|
|
201
201
|
const membershipEpoch = location.membershipEpoch + 1n;
|
|
202
|
+
const currentActor = toFrameworkActorRef(actorRef, meshName);
|
|
203
|
+
const authorityOwnerGeneration = state.locationGeneration ?? actorRef.generation;
|
|
202
204
|
const commit = async (spot?: ZLinkSpot): Promise<void> => {
|
|
203
205
|
throwIfAborted(signal);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
} else {
|
|
214
|
-
await this.options.locationLifecycle?.notifyActorJoinedSpot(
|
|
215
|
-
actorType,
|
|
216
|
-
actor.context.actorId,
|
|
217
|
-
meshName,
|
|
218
|
-
storeSpotId,
|
|
219
|
-
spotGeneration,
|
|
220
|
-
membershipEpoch,
|
|
221
|
-
node.status().lifecycleGeneration
|
|
222
|
-
);
|
|
223
|
-
}
|
|
206
|
+
await this.options.locationLifecycle?.commitActorMembership(
|
|
207
|
+
actorType,
|
|
208
|
+
currentActor,
|
|
209
|
+
authorityOwnerGeneration,
|
|
210
|
+
storeSpotId,
|
|
211
|
+
spotGeneration,
|
|
212
|
+
target.spotKind === ZLinkSpotKind.Entry ? ZLinkSpotKind.Entry : ZLinkSpotKind.User,
|
|
213
|
+
node.status().lifecycleGeneration
|
|
214
|
+
);
|
|
224
215
|
const committedActor = node.restoreActorAuthority!(
|
|
225
216
|
actor.context.actorId,
|
|
226
217
|
actorType,
|
|
227
218
|
actorRef.generation,
|
|
228
|
-
|
|
219
|
+
authorityOwnerGeneration,
|
|
229
220
|
target.spotKind === ZLinkSpotKind.Entry ? undefined : String(target.spotId),
|
|
230
221
|
spotGeneration,
|
|
231
222
|
membershipEpoch
|
|
@@ -297,6 +288,7 @@ export class ZLinkLocalNativeActorJoin {
|
|
|
297
288
|
completionOperationId: ZLinkActorJoinOperationId | undefined,
|
|
298
289
|
entrySpot: boolean
|
|
299
290
|
): Promise<ZLinkActorJoinRuntimeResult<Message>> {
|
|
291
|
+
const deadlineAtMs = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
|
|
300
292
|
const actorType = state.actorType;
|
|
301
293
|
if (actorType === undefined) {
|
|
302
294
|
throw createInternalFrameworkException(
|
|
@@ -443,6 +435,7 @@ export class ZLinkLocalNativeActorJoin {
|
|
|
443
435
|
target,
|
|
444
436
|
relocationId,
|
|
445
437
|
completionOperationId,
|
|
438
|
+
deadlineAtMs,
|
|
446
439
|
...(control.canonicalHandoffId === undefined || canonicalAdmission === undefined
|
|
447
440
|
? {}
|
|
448
441
|
: {
|
|
@@ -456,11 +449,9 @@ export class ZLinkLocalNativeActorJoin {
|
|
|
456
449
|
},
|
|
457
450
|
requestContentType: canonicalAdmission.request.contentType,
|
|
458
451
|
request: Buffer.from(canonicalAdmission.request.payload),
|
|
459
|
-
...(completionOperationId === undefined
|
|
452
|
+
...(completionOperationId === undefined || control.replyContentType === undefined
|
|
460
453
|
? {}
|
|
461
|
-
: {
|
|
462
|
-
replyContentType: control.replyContentType ?? ZlinkStreamContentType.Raw
|
|
463
|
-
}),
|
|
454
|
+
: { replyContentType: control.replyContentType }),
|
|
464
455
|
reply:
|
|
465
456
|
completionOperationId === undefined
|
|
466
457
|
? Buffer.alloc(0)
|
|
@@ -469,7 +460,7 @@ export class ZLinkLocalNativeActorJoin {
|
|
|
469
460
|
expectedOwnerLeaseGeneration: actorAuthorityFence!.ownerLeaseGeneration,
|
|
470
461
|
targetNodeGeneration: target.targetNodeGeneration!,
|
|
471
462
|
targetSpotGeneration: control.location.spotGeneration,
|
|
472
|
-
targetAuthorityOwnerGeneration: actorAuthorityFence!.authorityOwnerGeneration
|
|
463
|
+
targetAuthorityOwnerGeneration: actorAuthorityFence!.authorityOwnerGeneration,
|
|
473
464
|
targetSpotAuthorityOwnerGeneration: target.authorityOwnerGeneration ?? 1n
|
|
474
465
|
}
|
|
475
466
|
}),
|
|
@@ -21,9 +21,26 @@ export interface ZLinkRemoteActorSourceLeaveTerminal {
|
|
|
21
21
|
readonly succeeded: boolean;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
const JSON_OBJECT_START = '{'.charCodeAt(0);
|
|
25
|
+
const JSON_SPACE = ' '.charCodeAt(0);
|
|
26
|
+
const JSON_TAB = '\t'.charCodeAt(0);
|
|
27
|
+
const JSON_LINE_FEED = '\n'.charCodeAt(0);
|
|
28
|
+
const JSON_CARRIAGE_RETURN = '\r'.charCodeAt(0);
|
|
29
|
+
|
|
24
30
|
export function decodeRemoteActorSourceLeaveTerminal(
|
|
25
31
|
payload: Buffer
|
|
26
32
|
): ZLinkRemoteActorSourceLeaveTerminal | undefined {
|
|
33
|
+
// A SourceLeave terminal is a JSON object. Binary channel frames and JSON
|
|
34
|
+
// primitives cannot be terminals, so do not materialize or parse them.
|
|
35
|
+
let offset = 0;
|
|
36
|
+
while (
|
|
37
|
+
payload[offset] === JSON_SPACE ||
|
|
38
|
+
payload[offset] === JSON_TAB ||
|
|
39
|
+
payload[offset] === JSON_LINE_FEED ||
|
|
40
|
+
payload[offset] === JSON_CARRIAGE_RETURN
|
|
41
|
+
)
|
|
42
|
+
offset++;
|
|
43
|
+
if (payload[offset] !== JSON_OBJECT_START) return undefined;
|
|
27
44
|
let decoded: unknown;
|
|
28
45
|
try {
|
|
29
46
|
decoded = JSON.parse(payload.toString());
|
|
@@ -19,13 +19,13 @@ export interface ZLinkActorRoutedJoinTransport {
|
|
|
19
19
|
targetNodeRid: string,
|
|
20
20
|
packetName: string | undefined,
|
|
21
21
|
message: unknown
|
|
22
|
-
): Promise<ZLinkSubmitResult>;
|
|
22
|
+
): ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
|
|
23
23
|
submitInfrastructure?(
|
|
24
24
|
routerChannelId: string,
|
|
25
25
|
targetNodeRid: string,
|
|
26
26
|
packetName: string | undefined,
|
|
27
27
|
message: unknown
|
|
28
|
-
): Promise<ZLinkSubmitResult>;
|
|
28
|
+
): ZLinkSubmitResult | Promise<ZLinkSubmitResult>;
|
|
29
29
|
sendToSpot(
|
|
30
30
|
spotRouteTarget: ZLinkSpotRouteTarget,
|
|
31
31
|
message: unknown,
|
|
@@ -34,7 +34,11 @@ export interface ZLinkActorRoutedJoinTransport {
|
|
|
34
34
|
requestRawToSpot?(
|
|
35
35
|
spotRouteTarget: ZLinkSpotRouteTarget,
|
|
36
36
|
request: Message,
|
|
37
|
-
options: {
|
|
37
|
+
options: {
|
|
38
|
+
readonly timeoutMs?: number;
|
|
39
|
+
readonly signal?: AbortSignal;
|
|
40
|
+
readonly onAdmitted?: () => void;
|
|
41
|
+
}
|
|
38
42
|
): Promise<readonly Message[]>;
|
|
39
43
|
requestToSpot<TReply = unknown>(
|
|
40
44
|
spotRouteTarget: ZLinkSpotRouteTarget,
|
|
@@ -43,6 +47,7 @@ export interface ZLinkActorRoutedJoinTransport {
|
|
|
43
47
|
readonly packetName?: string;
|
|
44
48
|
readonly timeoutMs?: number;
|
|
45
49
|
readonly signal?: AbortSignal;
|
|
50
|
+
readonly onAdmitted?: () => void;
|
|
46
51
|
}
|
|
47
52
|
): Promise<TReply>;
|
|
48
53
|
requestFromSpotToSpot?<TReply = unknown>(
|
|
@@ -53,12 +58,17 @@ export interface ZLinkActorRoutedJoinTransport {
|
|
|
53
58
|
readonly packetName?: string;
|
|
54
59
|
readonly timeoutMs?: number;
|
|
55
60
|
readonly signal?: AbortSignal;
|
|
61
|
+
readonly onAdmitted?: () => void;
|
|
56
62
|
}
|
|
57
63
|
): Promise<TReply>;
|
|
58
64
|
requestRawFromSpotToSpot?(
|
|
59
65
|
sourceSpot: ZLinkBackendSpot,
|
|
60
66
|
spotRouteTarget: ZLinkSpotRouteTarget,
|
|
61
67
|
request: Message,
|
|
62
|
-
options: {
|
|
68
|
+
options: {
|
|
69
|
+
readonly timeoutMs?: number;
|
|
70
|
+
readonly signal?: AbortSignal;
|
|
71
|
+
readonly onAdmitted?: () => void;
|
|
72
|
+
}
|
|
63
73
|
): Promise<readonly Message[]>;
|
|
64
74
|
}
|
|
@@ -7,7 +7,11 @@ export async function tryRequestRoutedJson(
|
|
|
7
7
|
transport: ZLinkActorRoutedJoinTransport,
|
|
8
8
|
target: ZLinkSpotRouteTarget,
|
|
9
9
|
payload: unknown,
|
|
10
|
-
options: {
|
|
10
|
+
options: {
|
|
11
|
+
readonly timeoutMs?: number;
|
|
12
|
+
readonly signal?: AbortSignal;
|
|
13
|
+
readonly onAdmitted?: () => void;
|
|
14
|
+
}
|
|
11
15
|
): Promise<boolean> {
|
|
12
16
|
const request = transport.requestRawToSpot;
|
|
13
17
|
if (request === undefined) return false;
|
|
@@ -24,7 +28,11 @@ export async function requestRoutedJsonReply<T>(
|
|
|
24
28
|
transport: ZLinkActorRoutedJoinTransport,
|
|
25
29
|
target: ZLinkSpotRouteTarget,
|
|
26
30
|
payload: unknown,
|
|
27
|
-
options: {
|
|
31
|
+
options: {
|
|
32
|
+
readonly timeoutMs?: number;
|
|
33
|
+
readonly signal?: AbortSignal;
|
|
34
|
+
readonly onAdmitted?: () => void;
|
|
35
|
+
},
|
|
28
36
|
unavailableMessage: string,
|
|
29
37
|
decode: (replyParts: readonly Message[]) => T
|
|
30
38
|
): Promise<T> {
|