@zlink-systems/framework 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/contracts/Dispatch/ZLinkDispatchOptions.d.ts +1 -0
  3. package/dist/contracts/Streams/IZLinkSession.d.ts +2 -1
  4. package/dist/runtime/actors/actor-context.js +4 -4
  5. package/dist/runtime/actors/actor-join-deferred-scope.d.ts +0 -1
  6. package/dist/runtime/actors/actor-join-deferred-scope.js +0 -18
  7. package/dist/runtime/actors/deferred-join-accepted-journal.js +2 -6
  8. package/dist/runtime/backend/contracts/index.d.ts +2 -0
  9. package/dist/runtime/backend/node/node-raw-mesh-backend.d.ts +4 -0
  10. package/dist/runtime/backend/node/node-raw-mesh-backend.js +24 -8
  11. package/dist/runtime/channels/channel-dispatch-pipeline.js +2 -2
  12. package/dist/runtime/channels/channel-transports.js +3 -9
  13. package/dist/runtime/channels/dispatch-error-reporter.d.ts +1 -0
  14. package/dist/runtime/channels/dispatch-error-reporter.js +6 -38
  15. package/dist/runtime/diagnostics/dispatch-error-details.d.ts +6 -0
  16. package/dist/runtime/diagnostics/dispatch-error-details.js +55 -0
  17. package/dist/runtime/diagnostics/flow-context.d.ts +2 -1
  18. package/dist/runtime/diagnostics/flow-context.js +2 -2
  19. package/dist/runtime/diagnostics/message-flow.js +11 -3
  20. package/dist/runtime/foundation/actor-join-recovery-codec.js +0 -4
  21. package/dist/runtime/foundation/raw-service-mesh-runtime.d.ts +4 -2
  22. package/dist/runtime/foundation/raw-service-mesh-runtime.js +34 -9
  23. package/dist/runtime/foundation/service-session-binding-ingress-port.d.ts +1 -0
  24. package/dist/runtime/foundation/service-stateful-runtime.d.ts +5 -0
  25. package/dist/runtime/foundation/service-stateful-runtime.js +52 -2
  26. package/dist/runtime/foundation/service-topology-registry.d.ts +1 -0
  27. package/dist/runtime/foundation/service-topology-registry.js +12 -4
  28. package/dist/runtime/host/index.js +7 -3
  29. package/dist/runtime/locations/in-memory-location-store.js +5 -0
  30. package/dist/runtime/locations/location-store-repository.js +3 -1
  31. package/dist/runtime/protocol/service_wire_pilot_codec.generated.js +20 -18
  32. package/dist/runtime/spots/index.js +9 -3
  33. package/dist/runtime/spots/spot-actor-packet-dispatch.d.ts +2 -1
  34. package/dist/runtime/spots/spot-actor-packet-dispatch.js +6 -1
  35. package/dist/runtime/spots/spot-actor-packet-drain.js +2 -0
  36. package/dist/runtime/spots/spot-node-runtime-manager.js +5 -1
  37. package/dist/runtime/spots/spot-route-packet-dispatch.js +1 -1
  38. package/dist/runtime/spots/spot-routed-bound-session-dispatch.js +1 -1
  39. package/dist/runtime/spots/spot-subscription-dispatch.js +1 -1
  40. package/dist/runtime/spots/spot-timer.js +1 -1
  41. package/dist/runtime/streams/actor-session-binding-registry.d.ts +21 -8
  42. package/dist/runtime/streams/actor-session-binding-registry.js +71 -42
  43. package/dist/runtime/streams/actor-session-binding-runtime-owner.d.ts +1 -0
  44. package/dist/runtime/streams/bound-actor-relay-sender.js +2 -1
  45. package/dist/runtime/streams/bound-session-response-target.js +8 -1
  46. package/dist/runtime/streams/bound-session-service.d.ts +1 -0
  47. package/dist/runtime/streams/bound-session-service.js +6 -3
  48. package/dist/runtime/streams/index.js +8 -1
  49. package/dist/runtime/streams/managed-stream.d.ts +3 -0
  50. package/dist/runtime/streams/managed-stream.js +20 -1
  51. package/dist/runtime/streams/protocol.d.ts +5 -1
  52. package/dist/runtime/streams/protocol.js +41 -4
  53. package/dist/runtime/streams/session-actor-coordinator.js +3 -4
  54. package/dist/runtime/streams/session-context.d.ts +9 -2
  55. package/dist/runtime/streams/session-context.js +20 -4
  56. package/dist/runtime/streams/session-local-actors.d.ts +3 -1
  57. package/dist/runtime/streams/session-local-actors.js +17 -2
  58. package/dist/runtime/streams/stream-frame-factory.d.ts +1 -1
  59. package/dist/runtime/streams/stream-frame-factory.js +3 -2
  60. package/dist/runtime/streams/stream-session-runtime.js +42 -12
  61. package/package.json +3 -3
  62. package/src/contracts/Dispatch/ZLinkDispatchOptions.ts +1 -0
  63. package/src/contracts/Streams/IZLinkSession.ts +2 -1
  64. package/src/runtime/actors/actor-context.ts +4 -4
  65. package/src/runtime/actors/actor-join-deferred-scope.ts +0 -32
  66. package/src/runtime/actors/deferred-join-accepted-journal.ts +2 -6
  67. package/src/runtime/backend/contracts/index.ts +5 -0
  68. package/src/runtime/backend/node/node-raw-mesh-backend.ts +43 -11
  69. package/src/runtime/channels/channel-dispatch-pipeline.ts +4 -2
  70. package/src/runtime/channels/channel-transports.ts +3 -9
  71. package/src/runtime/channels/dispatch-error-reporter.ts +7 -45
  72. package/src/runtime/diagnostics/dispatch-error-details.ts +62 -0
  73. package/src/runtime/diagnostics/flow-context.ts +6 -4
  74. package/src/runtime/diagnostics/message-flow.ts +12 -3
  75. package/src/runtime/foundation/actor-join-recovery-codec.ts +0 -4
  76. package/src/runtime/foundation/raw-service-mesh-runtime.ts +54 -13
  77. package/src/runtime/foundation/service-session-binding-ingress-port.ts +1 -0
  78. package/src/runtime/foundation/service-stateful-runtime.ts +71 -5
  79. package/src/runtime/foundation/service-topology-registry.ts +18 -5
  80. package/src/runtime/host/index.ts +11 -4
  81. package/src/runtime/locations/in-memory-location-store.ts +7 -0
  82. package/src/runtime/locations/location-store-repository.ts +4 -1
  83. package/src/runtime/protocol/service_wire_pilot_codec.generated.ts +18 -17
  84. package/src/runtime/spots/index.ts +22 -2
  85. package/src/runtime/spots/spot-actor-packet-dispatch.ts +20 -3
  86. package/src/runtime/spots/spot-actor-packet-drain.ts +2 -0
  87. package/src/runtime/spots/spot-node-runtime-manager.ts +5 -1
  88. package/src/runtime/spots/spot-route-packet-dispatch.ts +2 -1
  89. package/src/runtime/spots/spot-routed-bound-session-dispatch.ts +2 -1
  90. package/src/runtime/spots/spot-subscription-dispatch.ts +2 -1
  91. package/src/runtime/spots/spot-timer.ts +6 -1
  92. package/src/runtime/streams/actor-session-binding-registry.ts +150 -63
  93. package/src/runtime/streams/actor-session-binding-runtime-owner.ts +1 -0
  94. package/src/runtime/streams/bound-actor-relay-sender.ts +10 -2
  95. package/src/runtime/streams/bound-session-response-target.ts +10 -1
  96. package/src/runtime/streams/bound-session-service.ts +13 -3
  97. package/src/runtime/streams/index.ts +8 -1
  98. package/src/runtime/streams/managed-stream.ts +34 -12
  99. package/src/runtime/streams/protocol.ts +44 -5
  100. package/src/runtime/streams/session-actor-coordinator.ts +12 -4
  101. package/src/runtime/streams/session-context.ts +31 -4
  102. package/src/runtime/streams/session-local-actors.ts +19 -3
  103. package/src/runtime/streams/stream-frame-factory.ts +4 -2
  104. package/src/runtime/streams/stream-session-runtime.ts +58 -13
@@ -6,14 +6,15 @@ export interface ServiceWireRouteFence { readonly id: string; readonly generatio
6
6
  function u64(out: number[], value: bigint): void { if (value < 0n || value > 0xffffffffffffffffn) throw new RangeError("u64"); for (let i=7;i>=0;i--) out.push(Number((value >> BigInt(i*8)) & 255n)); }
7
7
  function read64(bytes: Uint8Array, at: { value: number }): bigint { if (at.value + 8 > bytes.length) throw new RangeError("truncated u64"); let r=0n; for(let i=0;i<8;i++) r=(r<<8n)|BigInt(bytes[at.value++]); return r; }
8
8
  function u32(out: number[], value: number): void { if(!Number.isInteger(value)||value<0||value>0xffffffff)throw new RangeError("u32");out.push(value>>>24,(value>>>16)&255,(value>>>8)&255,value&255); }
9
+ function appendBytes(out: number[], bytes: Uint8Array | readonly number[]): void { for (const byte of bytes) out.push(byte); }
9
10
  function read32(bytes: Uint8Array, at: { value: number }): number { if(at.value+4>bytes.length)throw new RangeError("truncated u32");return ((bytes[at.value++]<<24)|(bytes[at.value++]<<16)|(bytes[at.value++]<<8)|bytes[at.value++])>>>0; }
10
- function text8(out: number[], value: string): void { const b=text.encode(value); if(b.length===0 || b.length>255 || b.includes(0)) throw new RangeError("text8"); out.push(b.length,...b); }
11
+ function text8(out: number[], value: string): void { const b=text.encode(value); if(b.length===0 || b.length>255 || b.includes(0)) throw new RangeError("text8"); out.push(b.length); appendBytes(out,b); }
11
12
  function readText8(bytes: Uint8Array, at: { value: number }): string { const n=bytes[at.value++]; if(n===0 || at.value+n>bytes.length) throw new RangeError("truncated text8"); const b=bytes.slice(at.value,at.value+n); at.value+=n; if(b.includes(0))throw new RangeError("text8 NUL"); return decodeText.decode(b); }
12
- function rid(out: number[], value: Uint8Array): void { if(value.length===0 || value.length>255) throw new RangeError("rid"); out.push(value.length,...value); }
13
+ function rid(out: number[], value: Uint8Array): void { if(value.length===0 || value.length>255) throw new RangeError("rid"); out.push(value.length); appendBytes(out,value); }
13
14
  function readRid(bytes: Uint8Array, at: { value: number }): Uint8Array { const n=bytes[at.value++]; if(n===0 || at.value+n>bytes.length) throw new RangeError("truncated rid"); const r=bytes.slice(at.value,at.value+n); at.value+=n; return r; }
14
15
  function fence(out: number[], value: ServiceWireRouteFence): void { if(value.generation===0n||value.targetNodeGeneration===0n||value.expectedAuthorityOwnerGeneration===0n||value.expectedOwnerLeaseGeneration===0n)throw new RangeError("invalid fence");text8(out,value.id); u64(out,value.generation); rid(out,value.targetNodeRid); u64(out,value.targetNodeGeneration); u64(out,value.expectedAuthorityOwnerGeneration); u64(out,value.expectedOwnerLeaseGeneration); }
15
16
  function readFence(bytes: Uint8Array, at: { value: number }): ServiceWireRouteFence { const value={ id:readText8(bytes,at), generation:read64(bytes,at), targetNodeRid:readRid(bytes,at), targetNodeGeneration:read64(bytes,at), expectedAuthorityOwnerGeneration:read64(bytes,at), expectedOwnerLeaseGeneration:read64(bytes,at) };if(value.generation===0n||value.targetNodeGeneration===0n||value.expectedAuthorityOwnerGeneration===0n||value.expectedOwnerLeaseGeneration===0n)throw new RangeError("invalid fence");return value; }
16
- function encodePayload(value: ApplicationPayloadEnvelopeV1): Uint8Array { const body:number[]=[];text8(body,value.packetName);text8(body,value.contentType);u32(body,value.payload.length);body.push(...value.payload);const out=[1];u32(out,body.length);out.push(...body);return Uint8Array.from(out); }
17
+ function encodePayload(value: ApplicationPayloadEnvelopeV1): Uint8Array { const body:number[]=[];text8(body,value.packetName);text8(body,value.contentType);u32(body,value.payload.length);appendBytes(body,value.payload);const out=[1];u32(out,body.length);appendBytes(out,body);return Uint8Array.from(out); }
17
18
  function decodePayload(bytes: Uint8Array): ApplicationPayloadEnvelopeV1 { const at={value:0};if(bytes[at.value++]!==1)throw new RangeError("payload version");const length=read32(bytes,at);if(length!==bytes.length-at.value)throw new RangeError("payload length");const end=bytes.length;const packetName=readText8(bytes,at);const contentType=readText8(bytes,at);const length2=read32(bytes,at);if(length2!==end-at.value)throw new RangeError("payload bytes");const payload=bytes.slice(at.value);at.value=end;if(at.value!==end)throw new RangeError("payload trailing");return {packetName,contentType,payload}; }
18
19
  export function encodeActorJoin28(value: ActorJoin28): readonly Uint8Array[] { const out=[90,77,1,28,0]; if(value.correlation===0n) throw new RangeError("correlation"); u64(out,value.correlation); fence(out,value.actor); out.push(value.entry?1:0); fence(out,value.targetSpot); return value.payload===undefined?[Uint8Array.from(out)]:[Uint8Array.from(out),encodePayload(value.payload)]; }
19
20
  export function decodeActorJoin28(frames: readonly Uint8Array[]): ActorJoin28 { if(frames.length<1||frames.length>2)throw new RangeError("actorJoin frames");const bytes=frames[0]!; const at={value:0}; if(bytes.length<5 || bytes[at.value++]!==90 || bytes[at.value++]!==77 || bytes[at.value++]!==1 || bytes[at.value++]!==28 || bytes[at.value++]!==0) throw new RangeError("actorJoin header"); const correlation=read64(bytes,at); const actor=readFence(bytes,at); const entry=bytes[at.value++]; const targetSpot=readFence(bytes,at); if(correlation===0n || entry>1 || at.value!==bytes.length) throw new RangeError("actorJoin body"); const payload=frames.length===2?decodePayload(frames[1]!):undefined; return payload===undefined?{ correlation, actor, entry:entry===1, targetSpot }:{ correlation, actor, entry:entry===1, targetSpot,payload }; }
@@ -22,16 +23,16 @@ export interface RelocationEnvelopeV1 { readonly relocationHigh: bigint; readonl
22
23
  export interface RelocationDataChunkV1 { readonly order:number;readonly data:Uint8Array; }
23
24
  export interface RelocationChunkEntryV1 { readonly order:number;readonly reference:string;readonly length:bigint;readonly checksumCrc32c:number; }
24
25
  export interface RelocationManifestV1 { readonly logicalFormatVersion:1;readonly totalLength:bigint;readonly totalChecksumCrc32c:number;readonly inventoryDigestSha256:Uint8Array;readonly chunks:readonly RelocationChunkEntryV1[]; }
25
- function bytes64(out:number[],v:Uint8Array):void{u64(out,BigInt(v.length));out.push(...v);}
26
- function body16(out:number[],write:(b:number[])=>void):void{const b:number[]=[];write(b);if(b.length>65535)throw new RangeError("body16");out.push(b.length>>>8,b.length&255,...b);}
27
- function body64(out:number[],write:(b:number[])=>void):void{const b:number[]=[];write(b);u64(out,BigInt(b.length));out.push(...b);}
26
+ function bytes64(out:number[],v:Uint8Array):void{u64(out,BigInt(v.length));appendBytes(out,v);}
27
+ function body16(out:number[],write:(b:number[])=>void):void{const b:number[]=[];write(b);if(b.length>65535)throw new RangeError("body16");out.push(b.length>>>8,b.length&255);appendBytes(out,b);}
28
+ function body64(out:number[],write:(b:number[])=>void):void{const b:number[]=[];write(b);u64(out,BigInt(b.length));appendBytes(out,b);}
28
29
  function sorted<T>(v:readonly T[],compare:(a:T,b:T)=>number,name:string):void{for(let i=1;i<v.length;i++)if(compare(v[i-1],v[i])>=0)throw new RangeError(name);}
29
30
  function read8(bytes:Uint8Array,at:{value:number}):number{if(at.value>=bytes.length)throw new RangeError("truncated u8");return bytes[at.value++]!;}
30
31
  function read16(bytes:Uint8Array,at:{value:number}):number{if(at.value+2>bytes.length)throw new RangeError("truncated u16");return (bytes[at.value++]!<<8)|bytes[at.value++]!;}
31
32
  function take(bytes:Uint8Array,at:{value:number},n:number,name:string):Uint8Array<ArrayBuffer>{if(!Number.isSafeInteger(n)||n<0||at.value+n>bytes.length)throw new RangeError("truncated "+name);const v=Uint8Array.from(bytes.subarray(at.value,at.value+n));at.value+=n;return v;}
32
33
  function nonzero64(bytes:Uint8Array,at:{value:number},name:string):bigint{const v=read64(bytes,at);if(v===0n)throw new RangeError(name);return v;}
33
34
  function readText16(bytes:Uint8Array,at:{value:number},minimum:number,maximum:number,name:string):string{const n=read16(bytes,at);if(n<minimum||n>maximum)throw new RangeError(name);const b=take(bytes,at,n,name);if(b.includes(0))throw new RangeError(name+" NUL");return decodeText.decode(b);}
34
- function writeText16(out:number[],value:string,minimum:number,maximum:number,name:string):void{const b=text.encode(value);if(b.length<minimum||b.length>maximum||b.includes(0))throw new RangeError(name);out.push(b.length>>>8,b.length&255,...b);}
35
+ function writeText16(out:number[],value:string,minimum:number,maximum:number,name:string):void{const b=text.encode(value);if(b.length<minimum||b.length>maximum||b.includes(0))throw new RangeError(name);out.push(b.length>>>8,b.length&255);appendBytes(out,b);}
35
36
  function boundedEnd(bytes:Uint8Array,at:{value:number},length:number,name:string):number{if(at.value+length>bytes.length)throw new RangeError("truncated "+name);return at.value+length;}
36
37
  function exactEnd(at:{value:number},end:number,name:string):void{if(at.value!==end)throw new RangeError(name+" trailing");}
37
38
  function skipRid(bytes:Uint8Array,at:{value:number}):void{const n=read8(bytes,at);if(n===0)throw new RangeError("rid minimumBytes");take(bytes,at,n,"rid");}
@@ -50,14 +51,14 @@ function skipFrozenRecord(bytes:Uint8Array,at:{value:number}):void{const kind=re
50
51
  function compareUtf8(a:string,b:string):number{const x=text.encode(a),y=text.encode(b),n=Math.min(x.length,y.length);for(let i=0;i<n;i++)if(x[i]!==y[i])return x[i]!-y[i]!;return x.length-y.length;}
51
52
  function writeRelocationObject(out:number[],value:RelocationObjectIdentity):void{const kind=value.objectKind==="actor"?1:value.objectKind==="userSpot"?2:3;out.push(kind);body16(out,b=>{if(value.objectKind==="actor"){text8(b,value.actorId);if(value.objectGeneration===0n||value.expectedAuthorityOwnerGeneration===0n)throw new RangeError("object");u64(b,value.objectGeneration);u64(b,value.expectedAuthorityOwnerGeneration);}else if(value.objectKind==="userSpot"){text8(b,value.spotId);if(value.objectGeneration===0n||value.expectedAuthorityOwnerGeneration===0n)throw new RangeError("object");u64(b,value.objectGeneration);u64(b,value.expectedAuthorityOwnerGeneration);}else{text8(b,value.instanceType);text8(b,value.spotId);if(value.objectGeneration===0n)throw new RangeError("object");u64(b,value.objectGeneration);}});}
52
53
  function readRelocationObject(bytes:Uint8Array,at:{value:number}):RelocationObjectIdentity{const kind=read8(bytes,at),end=boundedEnd(bytes,at,read16(bytes,at),"relocation object");let value:RelocationObjectIdentity;if(kind===1)value={objectKind:"actor",actorId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation"),expectedAuthorityOwnerGeneration:nonzero64(bytes,at,"authority generation")};else if(kind===2)value={objectKind:"userSpot",spotId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation"),expectedAuthorityOwnerGeneration:nonzero64(bytes,at,"authority generation")};else if(kind===3)value={objectKind:"instanceSpot",instanceType:readText8(bytes,at),spotId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation")};else throw new RangeError("object kind");exactEnd(at,end,"relocation object");return value;}
53
- export function encodeRelocationEnvelopeV1(value:RelocationEnvelopeV1):Uint8Array{const out:number[]=[];if(value.relocationHigh===0n&&value.relocationLow===0n)throw new RangeError("relocation");u64(out,value.relocationHigh);u64(out,value.relocationLow);writeRelocationObject(out,value.object);if(value.applicationVersion<0n||value.applicationVersion>9223372036854775807n)throw new RangeError("application version");u64(out,value.applicationVersion);sorted(value.applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");if(value.applicationStates.length===0)throw new RangeError("applicationStates");u32(out,value.applicationStates.length);for(const s of value.applicationStates){if(s.participantId===0n)throw new RangeError("participant");u64(out,s.participantId);out.push(s.hasState?1:0);body64(out,b=>{if(s.hasState)bytes64(b,s.payload);else if(s.payload.length!==0)throw new RangeError("absent state payload");});}sorted(value.savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");u32(out,value.savedWork.length);for(const w of value.savedWork){if(w.participantId===0n||w.order===0n)throw new RangeError("saved work");const at={value:0};skipFrozenRecord(w.frozenRecord,at);exactEnd(at,w.frozenRecord.length,"frozen record");u64(out,w.participantId);u64(out,w.order);out.push(...w.frozenRecord);}sorted(value.timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");u32(out,value.timerRegistrations.length);for(const t of value.timerRegistrations){if(t.participantId===0n||t.periodMilliseconds===0n||t.maxCatchUpTicks===0n||t.overrunPolicy<1||t.overrunPolicy>3)throw new RangeError("timer");u64(out,t.participantId);text8(out,t.name);text8(out,t.handlerType);u64(out,t.periodMilliseconds);out.push(t.overrunPolicy);u64(out,t.maxCatchUpTicks);out.push(t.stopOnUnhandledException?1:0);u64(out,t.lastCompletedDeliveryIndex);u64(out,t.lastCompletedScheduledIndex);u64(out,t.nextScheduledAtUnixMilliseconds);}sorted(value.pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");u32(out,value.pendingTimerTicks.length);for(const p of value.pendingTimerTicks){if(p.participantId===0n||p.order===0n||p.deliveryIndex===0n||p.scheduledIndex===0n)throw new RangeError("pending timer");u64(out,p.participantId);u64(out,p.order);text8(out,p.timerName);u64(out,p.deliveryIndex);u64(out,p.scheduledIndex);u64(out,p.scheduledAtUnixMilliseconds);u64(out,p.skippedTicks);}if(out.length>274877906944)throw new RangeError("relocation logical bytes");return Uint8Array.from(out);}
54
+ export function encodeRelocationEnvelopeV1(value:RelocationEnvelopeV1):Uint8Array{const out:number[]=[];if(value.relocationHigh===0n&&value.relocationLow===0n)throw new RangeError("relocation");u64(out,value.relocationHigh);u64(out,value.relocationLow);writeRelocationObject(out,value.object);if(value.applicationVersion<0n||value.applicationVersion>9223372036854775807n)throw new RangeError("application version");u64(out,value.applicationVersion);sorted(value.applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");if(value.applicationStates.length===0)throw new RangeError("applicationStates");u32(out,value.applicationStates.length);for(const s of value.applicationStates){if(s.participantId===0n)throw new RangeError("participant");u64(out,s.participantId);out.push(s.hasState?1:0);body64(out,b=>{if(s.hasState)bytes64(b,s.payload);else if(s.payload.length!==0)throw new RangeError("absent state payload");});}sorted(value.savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");u32(out,value.savedWork.length);for(const w of value.savedWork){if(w.participantId===0n||w.order===0n)throw new RangeError("saved work");const at={value:0};skipFrozenRecord(w.frozenRecord,at);exactEnd(at,w.frozenRecord.length,"frozen record");u64(out,w.participantId);u64(out,w.order);appendBytes(out,w.frozenRecord);}sorted(value.timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");u32(out,value.timerRegistrations.length);for(const t of value.timerRegistrations){if(t.participantId===0n||t.periodMilliseconds===0n||t.maxCatchUpTicks===0n||t.overrunPolicy<1||t.overrunPolicy>3)throw new RangeError("timer");u64(out,t.participantId);text8(out,t.name);text8(out,t.handlerType);u64(out,t.periodMilliseconds);out.push(t.overrunPolicy);u64(out,t.maxCatchUpTicks);out.push(t.stopOnUnhandledException?1:0);u64(out,t.lastCompletedDeliveryIndex);u64(out,t.lastCompletedScheduledIndex);u64(out,t.nextScheduledAtUnixMilliseconds);}sorted(value.pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");u32(out,value.pendingTimerTicks.length);for(const p of value.pendingTimerTicks){if(p.participantId===0n||p.order===0n||p.deliveryIndex===0n||p.scheduledIndex===0n)throw new RangeError("pending timer");u64(out,p.participantId);u64(out,p.order);text8(out,p.timerName);u64(out,p.deliveryIndex);u64(out,p.scheduledIndex);u64(out,p.scheduledAtUnixMilliseconds);u64(out,p.skippedTicks);}if(out.length>274877906944)throw new RangeError("relocation logical bytes");return Uint8Array.from(out);}
54
55
  export function decodeRelocationEnvelopeV1(chunks:readonly Uint8Array[]):RelocationEnvelopeV1{const n=chunks.reduce((s,c)=>s+c.length,0);if(n>274877906944)throw new RangeError("relocation logical bytes");const bytes=new Uint8Array(n);let offset=0;for(const c of chunks){bytes.set(c,offset);offset+=c.length;}const at={value:0},relocationHigh=read64(bytes,at),relocationLow=read64(bytes,at);if(relocationHigh===0n&&relocationLow===0n)throw new RangeError("relocation");const object=readRelocationObject(bytes,at),applicationVersion=read64(bytes,at);if(applicationVersion>9223372036854775807n)throw new RangeError("application version");const applicationStates:RelocationEnvelopeV1["applicationStates"][number][]=[];const stateCount=read32(bytes,at);if(stateCount===0)throw new RangeError("applicationStates");for(let i=0,count=stateCount;i<count;i++){const participantId=nonzero64(bytes,at,"participant"),has=read8(bytes,at),end=boundedEnd(bytes,at,Number(read64(bytes,at)),"application state");if(has>1)throw new RangeError("application state");let payload=new Uint8Array();if(has===1)payload=take(bytes,at,Number(read64(bytes,at)),"state payload");exactEnd(at,end,"application state");applicationStates.push({participantId,hasState:has===1,payload});}const participants=new Set(applicationStates.map((s)=>s.participantId));const savedWork:RelocationEnvelopeV1["savedWork"][number][]=[];for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("saved work participant");const order=nonzero64(bytes,at,"order"),start=at.value;skipFrozenRecord(bytes,at);savedWork.push({participantId,order,frozenRecord:bytes.slice(start,at.value)});}const timerRegistrations:RelocationEnvelopeV1["timerRegistrations"][number][]=[],registeredTimerNames=new Map<bigint,Set<string>>();for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("timer participant");const name=readText8(bytes,at),handlerType=readText8(bytes,at),periodMilliseconds=nonzero64(bytes,at,"period"),overrunPolicy=read8(bytes,at);if(overrunPolicy<1||overrunPolicy>3)throw new RangeError("overrun policy");const maxCatchUpTicks=nonzero64(bytes,at,"catch-up"),stop=read8(bytes,at);if(stop>1)throw new RangeError("stop flag");let names=registeredTimerNames.get(participantId);if(names===undefined){names=new Set<string>();registeredTimerNames.set(participantId,names);}names.add(name);timerRegistrations.push({participantId,name,handlerType,periodMilliseconds,overrunPolicy:overrunPolicy as 1|2|3,maxCatchUpTicks,stopOnUnhandledException:stop===1,lastCompletedDeliveryIndex:read64(bytes,at),lastCompletedScheduledIndex:read64(bytes,at),nextScheduledAtUnixMilliseconds:read64(bytes,at)});}const pendingTimerTicks:RelocationEnvelopeV1["pendingTimerTicks"][number][]=[];for(let i=0,count=read32(bytes,at);i<count;i++){const participantId=nonzero64(bytes,at,"participant");if(!participants.has(participantId))throw new RangeError("pending timer participant");const order=nonzero64(bytes,at,"order"),timerName=readText8(bytes,at);if(registeredTimerNames.get(participantId)?.has(timerName)!==true)throw new RangeError("pending timer registration");pendingTimerTicks.push({participantId,order,timerName,deliveryIndex:nonzero64(bytes,at,"delivery"),scheduledIndex:nonzero64(bytes,at,"scheduled"),scheduledAtUnixMilliseconds:read64(bytes,at),skippedTicks:read64(bytes,at)});}exactEnd(at,bytes.length,"relocation envelope");sorted(applicationStates,(a,b)=>a.participantId<b.participantId?-1:a.participantId>b.participantId?1:0,"applicationStates");sorted(savedWork,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"savedWork");sorted(timerRegistrations,(a,b)=>a.participantId===b.participantId?compareUtf8(a.name,b.name):a.participantId<b.participantId?-1:1,"timerRegistrations");sorted(pendingTimerTicks,(a,b)=>a.participantId===b.participantId?(a.order<b.order?-1:a.order>b.order?1:0):(a.participantId<b.participantId?-1:1),"pendingTimerTicks");return{relocationHigh,relocationLow,object,applicationVersion,applicationStates,savedWork,timerRegistrations,pendingTimerTicks};}
55
56
  function crc32c(bytes:Uint8Array):number{let crc=0xffffffff;for(const octet of bytes){crc^=octet;for(let bit=0;bit<8;bit++)crc=(crc>>>1)^((crc&1)!==0?0x82f63b78:0);}return(~crc)>>>0;}
56
- function encodeDurable(magic:readonly number[],body:readonly number[],maximum:number):Uint8Array{const out=[...magic,1,0,0];u32(out,body.length);out.push(...body);if(out.length+4>maximum)throw new RangeError("durable format bytes");u32(out,crc32c(Uint8Array.from(out)));return Uint8Array.from(out);}
57
+ function encodeDurable(magic:readonly number[],body:readonly number[],maximum:number):Uint8Array{const out=[...magic,1,0,0];u32(out,body.length);appendBytes(out,body);if(out.length+4>maximum)throw new RangeError("durable format bytes");u32(out,crc32c(Uint8Array.from(out)));return Uint8Array.from(out);}
57
58
  function decodeDurable(bytes:Uint8Array,magic:readonly number[],maximum:number):Uint8Array{if(bytes.length>maximum||bytes.length<15||magic.some((v,i)=>bytes[i]!==v)||bytes[4]!==1||bytes[5]!==0||bytes[6]!==0)throw new RangeError("durable header");const at={value:7},length=read32(bytes,at),end=boundedEnd(bytes,at,length,"durable body");if(end+4!==bytes.length)throw new RangeError("durable length");const body=bytes.slice(at.value,end);at.value=end;const expected=read32(bytes,at);if(crc32c(bytes.slice(0,end))!==expected)throw new RangeError("durable checksum");return body;}
58
- export function encodeRelocationDataChunkV1(value:RelocationDataChunkV1):Uint8Array{const body:number[]=[];u32(body,value.order);if(value.data.length>67108864)throw new RangeError("chunk data");u32(body,value.data.length);body.push(...value.data);return encodeDurable([90,76,84,67],body,67108886);}
59
+ export function encodeRelocationDataChunkV1(value:RelocationDataChunkV1):Uint8Array{const body:number[]=[];u32(body,value.order);if(value.data.length>67108864)throw new RangeError("chunk data");u32(body,value.data.length);appendBytes(body,value.data);return encodeDurable([90,76,84,67],body,67108886);}
59
60
  export function decodeRelocationDataChunkV1(bytes:Uint8Array):RelocationDataChunkV1{const body=decodeDurable(bytes,[90,76,84,67],67108886),at={value:0},order=read32(body,at),data=take(body,at,read32(body,at),"chunk data");exactEnd(at,body.length,"chunk");return{order,data};}
60
- export function encodeRelocationManifestV1(value:RelocationManifestV1):Uint8Array{if(Number(value.logicalFormatVersion)!==1||value.totalLength>274877906944n||value.inventoryDigestSha256.length!==32||value.chunks.length>4096)throw new RangeError("manifest");sorted(value.chunks,(a,b)=>a.order-b.order,"manifest chunks");const body:number[]=[1];u64(body,value.totalLength);u32(body,value.totalChecksumCrc32c);body.push(32,...value.inventoryDigestSha256);u32(body,value.chunks.length);for(const chunk of value.chunks){if(chunk.length===0n)throw new RangeError("chunk length");u32(body,chunk.order);writeText16(body,chunk.reference,1,4096,"chunk reference");u64(body,chunk.length);u32(body,chunk.checksumCrc32c);}return encodeDurable([90,76,84,77],body,33554432);}
61
+ export function encodeRelocationManifestV1(value:RelocationManifestV1):Uint8Array{if(Number(value.logicalFormatVersion)!==1||value.totalLength>274877906944n||value.inventoryDigestSha256.length!==32||value.chunks.length>4096)throw new RangeError("manifest");sorted(value.chunks,(a,b)=>a.order-b.order,"manifest chunks");const body:number[]=[1];u64(body,value.totalLength);u32(body,value.totalChecksumCrc32c);body.push(32);appendBytes(body,value.inventoryDigestSha256);u32(body,value.chunks.length);for(const chunk of value.chunks){if(chunk.length===0n)throw new RangeError("chunk length");u32(body,chunk.order);writeText16(body,chunk.reference,1,4096,"chunk reference");u64(body,chunk.length);u32(body,chunk.checksumCrc32c);}return encodeDurable([90,76,84,77],body,33554432);}
61
62
  export function decodeRelocationManifestV1(bytes:Uint8Array):RelocationManifestV1{const body=decodeDurable(bytes,[90,76,84,77],33554432),at={value:0};if(read8(body,at)!==1)throw new RangeError("logical format version");const totalLength=read64(body,at);if(totalLength>274877906944n)throw new RangeError("logical length");const totalChecksumCrc32c=read32(body,at),digestLength=read8(body,at);if(digestLength!==32)throw new RangeError("inventory digest minimumBytes");const inventoryDigestSha256=take(body,at,digestLength,"inventory digest"),count=read32(body,at);if(count>4096)throw new RangeError("chunk count");const chunks:RelocationChunkEntryV1[]=[];for(let i=0;i<count;i++)chunks.push({order:read32(body,at),reference:readText16(body,at,1,4096,"chunk reference"),length:nonzero64(body,at,"chunk length"),checksumCrc32c:read32(body,at)});exactEnd(at,body.length,"manifest");sorted(chunks,(a,b)=>a.order-b.order,"manifest chunks");return{logicalFormatVersion:1,totalLength,totalChecksumCrc32c,inventoryDigestSha256,chunks};}
62
63
  export interface LivenessProbe5 { readonly probeId: bigint; }
63
64
  export function encodeLivenessProbe5(value: LivenessProbe5): Uint8Array { const out=[90,77,1,5,0]; if(value.probeId===0n) throw new RangeError("probeId"); u64(out,value.probeId); return Uint8Array.from(out); }
@@ -144,11 +145,11 @@ export function encodeRelocationFailed53(v:RelocationFailed53):Uint8Array{const
144
145
  export function decodeRelocationFailed53(bytes:Uint8Array):RelocationFailed53{const at=b3ReadHeader(bytes,53,"relocationFailed"),v=b3ReadReadyBase(bytes,at),failureCode=read32(bytes,at);if(!b3FailureResults.has(failureCode))throw new RangeError("failure code");b3Finish(at,bytes,"relocationFailed");return{...v,failureCode};}
145
146
  function b3WriteSourceBase(o:number[],v:RelocationData31|RelocationCutover34|RelocationState52):void{b3WriteId(o,v.relocation,"relocation");if(v.targetAttemptGeneration===0n)throw new RangeError("target attempt");u64(o,v.targetAttemptGeneration);b3WriteCoordinator(o,v.coordinator);b3WriteRole(o,v.senderRole);if(v.senderRole!=="source")throw new RangeError("sender role");writeRelocationObject(o,v.object);}
146
147
  function b3ReadSourceBase(bytes:Uint8Array,at:{value:number}){const relocation=b3ReadId(bytes,at,"relocation"),targetAttemptGeneration=nonzero64(bytes,at,"target attempt"),coordinator=b3ReadCoordinator(bytes,at),senderRole=b3ReadRole(bytes,at);if(senderRole!=="source")throw new RangeError("sender role");return{relocation,targetAttemptGeneration,coordinator,senderRole,object:readRelocationObject(bytes,at)};}
147
- export function encodeRelocationData31(v:RelocationData31):Uint8Array{const o=b3Header(31);b3WriteSourceBase(o,v);const at={value:0};skipFrozenRecord(v.record,at);exactEnd(at,v.record.length,"frozen record");o.push(...v.record);return Uint8Array.from(o);}
148
+ export function encodeRelocationData31(v:RelocationData31):Uint8Array{const o=b3Header(31);b3WriteSourceBase(o,v);const at={value:0};skipFrozenRecord(v.record,at);exactEnd(at,v.record.length,"frozen record");appendBytes(o,v.record);return Uint8Array.from(o);}
148
149
  export function decodeRelocationData31(bytes:Uint8Array):RelocationData31{const at=b3ReadHeader(bytes,31,"relocationData"),v=b3ReadSourceBase(bytes,at),start=at.value;skipFrozenRecord(bytes,at);const record=bytes.slice(start,at.value);b3Finish(at,bytes,"relocationData");return{...v,record};}
149
150
  export function encodeRelocationCutover34(v:RelocationCutover34):Uint8Array{const o=b3Header(34);b3WriteSourceBase(o,v);if(v.boundaryRecordCount<0n||v.boundaryRecordCount>9223372036854775807n)throw new RangeError("boundary count");u64(o,v.boundaryRecordCount);u32(o,v.boundaryChecksumCrc32c);return Uint8Array.from(o);}
150
151
  export function decodeRelocationCutover34(bytes:Uint8Array):RelocationCutover34{const at=b3ReadHeader(bytes,34,"relocationCutover"),v=b3ReadSourceBase(bytes,at),boundaryRecordCount=read64(bytes,at);if(boundaryRecordCount>9223372036854775807n)throw new RangeError("boundary count");const boundaryChecksumCrc32c=read32(bytes,at);b3Finish(at,bytes,"relocationCutover");return{...v,boundaryRecordCount,boundaryChecksumCrc32c};}
151
- export function encodeRelocationState52(v:RelocationState52):Uint8Array{const o=b3Header(52);b3WriteSourceBase(o,v);if(v.chunkData.length>67108864)throw new RangeError("chunk data");u32(o,v.chunkOrdinal);u32(o,v.chunkData.length);o.push(...v.chunkData);return Uint8Array.from(o);}
152
+ export function encodeRelocationState52(v:RelocationState52):Uint8Array{const o=b3Header(52);b3WriteSourceBase(o,v);if(v.chunkData.length>67108864)throw new RangeError("chunk data");u32(o,v.chunkOrdinal);u32(o,v.chunkData.length);appendBytes(o,v.chunkData);return Uint8Array.from(o);}
152
153
  export function decodeRelocationState52(bytes:Uint8Array):RelocationState52{const at=b3ReadHeader(bytes,52,"relocationState"),v=b3ReadSourceBase(bytes,at),chunkOrdinal=read32(bytes,at),length=read32(bytes,at);if(length>67108864)throw new RangeError("chunk data");const chunkData=take(bytes,at,length,"chunk data");b3Finish(at,bytes,"relocationState");return{...v,chunkOrdinal,chunkData};}
153
154
  export function encodeRelocationPrepare40(v:RelocationPrepare40):Uint8Array{const o=b3Header(40);b3WriteId(o,v.relocation,"relocation");if(v.targetAttemptGeneration===0n||v.sourceNodeGeneration===0n)throw new RangeError("prepare");u64(o,v.targetAttemptGeneration);b3WriteCoordinator(o,v.coordinator);b3WriteTarget(o,v.target);b3WriteRole(o,v.initiatorRole);if(v.initiatorRole!=="source")throw new RangeError("initiator role");writeRelocationObject(o,v.object);rid(o,v.sourceNodeRid);u64(o,v.sourceNodeGeneration);if(v.payloadTotalLength<0n||v.payloadTotalLength>274877906944n||v.payloadChunkCount>4096||v.applicationVersion<0n||v.applicationVersion>9223372036854775807n)throw new RangeError("prepare bounds");u64(o,v.payloadTotalLength);u32(o,v.payloadChunkCount);u32(o,v.payloadChecksumCrc32c);u64(o,v.applicationVersion);return Uint8Array.from(o);}
154
155
  export function decodeRelocationPrepare40(bytes:Uint8Array):RelocationPrepare40{const at=b3ReadHeader(bytes,40,"relocationPrepare"),relocation=b3ReadId(bytes,at,"relocation"),targetAttemptGeneration=nonzero64(bytes,at,"target attempt"),coordinator=b3ReadCoordinator(bytes,at),target=b3ReadTarget(bytes,at),initiatorRole=b3ReadRole(bytes,at);if(initiatorRole!=="source")throw new RangeError("initiator role");const object=readRelocationObject(bytes,at),sourceNodeRid=readRid(bytes,at),sourceNodeGeneration=nonzero64(bytes,at,"source node"),payloadTotalLength=read64(bytes,at),payloadChunkCount=read32(bytes,at),payloadChecksumCrc32c=read32(bytes,at),applicationVersion=read64(bytes,at);if(payloadTotalLength>274877906944n||payloadChunkCount>4096||applicationVersion>9223372036854775807n)throw new RangeError("prepare bounds");b3Finish(at,bytes,"relocationPrepare");return{relocation,targetAttemptGeneration,coordinator,target,initiatorRole,object,sourceNodeRid,sourceNodeGeneration,payloadTotalLength,payloadChunkCount,payloadChecksumCrc32c,applicationVersion};}
@@ -173,7 +174,7 @@ function b4ReadHeader(bytes:Uint8Array,id:number,name:string):{value:number}{con
173
174
  function b4Finish(at:{value:number},bytes:Uint8Array,name:string):void{if(at.value!==bytes.length)throw new RangeError(name+" trailing");}
174
175
  function b4Reservation(out:number[],v:ServiceWireObjectReservationFence):void{text8(out,v.reservationId);writeText16(out,v.expectedStoreVersion,1,4096,"store version");if(v.objectGeneration===0n||v.authorityOwnerGeneration===0n||v.targetNodeGeneration===0n||v.targetOwnerLeaseGeneration===0n||!Number.isInteger(v.pendingCapacityDelta)||v.pendingCapacityDelta<1||v.pendingCapacityDelta>0xffffffff)throw new RangeError("reservation");u64(out,v.objectGeneration);u64(out,v.authorityOwnerGeneration);rid(out,v.targetNodeRid);u64(out,v.targetNodeGeneration);text8(out,v.targetOwnerId);u64(out,v.targetOwnerLeaseGeneration);u32(out,v.pendingCapacityDelta);}
175
176
  function b4ReadReservation(bytes:Uint8Array,at:{value:number}):ServiceWireObjectReservationFence{return{reservationId:readText8(bytes,at),expectedStoreVersion:readText16(bytes,at,1,4096,"store version"),objectGeneration:nonzero64(bytes,at,"object generation"),authorityOwnerGeneration:nonzero64(bytes,at,"authority generation"),targetNodeRid:readRid(bytes,at),targetNodeGeneration:nonzero64(bytes,at,"target node generation"),targetOwnerId:readText8(bytes,at),targetOwnerLeaseGeneration:nonzero64(bytes,at,"target lease generation"),pendingCapacityDelta:(()=>{const v=read32(bytes,at);if(v===0)throw new RangeError("pending capacity");return v;})()};}
176
- function b4Close(out:number[],v:ServiceWireUserSpotCloseFenceV1):void{const body:number[]=[];text8(body,v.spotId);if(v.objectGeneration===0n||v.targetNodeGeneration===0n||v.expectedAuthorityOwnerGeneration===0n)throw new RangeError("close fence");u64(body,v.objectGeneration);rid(body,v.targetNodeRid);u64(body,v.targetNodeGeneration);u64(body,v.expectedAuthorityOwnerGeneration);writeText16(body,v.expectedStoreVersion,1,4096,"store version");out.push(1);if(body.length>65535)throw new RangeError("close fence");out.push(body.length>>>8,body.length&255,...body);}
177
+ function b4Close(out:number[],v:ServiceWireUserSpotCloseFenceV1):void{const body:number[]=[];text8(body,v.spotId);if(v.objectGeneration===0n||v.targetNodeGeneration===0n||v.expectedAuthorityOwnerGeneration===0n)throw new RangeError("close fence");u64(body,v.objectGeneration);rid(body,v.targetNodeRid);u64(body,v.targetNodeGeneration);u64(body,v.expectedAuthorityOwnerGeneration);writeText16(body,v.expectedStoreVersion,1,4096,"store version");out.push(1);if(body.length>65535)throw new RangeError("close fence");out.push(body.length>>>8,body.length&255);appendBytes(out,body);}
177
178
  function b4ReadClose(bytes:Uint8Array,at:{value:number}):ServiceWireUserSpotCloseFenceV1{if(read8(bytes,at)!==1)throw new RangeError("close fence version");const end=boundedEnd(bytes,at,read16(bytes,at),"close fence");const value={spotId:readText8(bytes,at),objectGeneration:nonzero64(bytes,at,"object generation"),targetNodeRid:readRid(bytes,at),targetNodeGeneration:nonzero64(bytes,at,"target node generation"),expectedAuthorityOwnerGeneration:nonzero64(bytes,at,"authority generation"),expectedStoreVersion:readText16(bytes,at,1,4096,"store version")};exactEnd(at,end,"close fence");return value;}
178
179
  function b4CommandBase(out:number[],v:{correlation:bigint;operation:ServiceWireOperationId;sourceNodeRid:Uint8Array;sourceNodeGeneration:bigint}):void{if(v.correlation===0n||v.sourceNodeGeneration===0n)throw new RangeError("command base");u64(out,v.correlation);b3WriteId(out,v.operation,"operation");rid(out,v.sourceNodeRid);u64(out,v.sourceNodeGeneration);}
179
180
  function b4ReadCommandBase(bytes:Uint8Array,at:{value:number}):{correlation:bigint;operation:ServiceWireOperationId;sourceNodeRid:Uint8Array;sourceNodeGeneration:bigint}{return{correlation:nonzero64(bytes,at,"correlation"),operation:b3ReadId(bytes,at,"operation"),sourceNodeRid:readRid(bytes,at),sourceNodeGeneration:nonzero64(bytes,at,"source node generation")};}
@@ -183,7 +184,7 @@ export function encodeUserSpotClose48(v:UserSpotClose48):Uint8Array{const out=b4
183
184
  export function decodeUserSpotClose48(bytes:Uint8Array):UserSpotClose48{const at=b4ReadHeader(bytes,48,"userSpotClose"),base=b4ReadCommandBase(bytes,at),target=b4ReadClose(bytes,at),deadlineUnixMs=nonzero64(bytes,at,"deadline");b4Finish(at,bytes,"userSpotClose");return{...base,target,deadlineUnixMs};}
184
185
  export function encodeActorCreate49(v:ActorCreate49):Uint8Array{const out=b4Header(49);b4CommandBase(out,v);text8(out,v.actorId);text8(out,v.stableType);b4Reservation(out,v.reservation);if(v.deadlineUnixMs===0n)throw new RangeError("deadline");u64(out,v.deadlineUnixMs);return Uint8Array.from(out);}
185
186
  export function decodeActorCreate49(bytes:Uint8Array):ActorCreate49{const at=b4ReadHeader(bytes,49,"actorCreate"),base=b4ReadCommandBase(bytes,at),actorId=readText8(bytes,at),stableType=readText8(bytes,at),reservation=b4ReadReservation(bytes,at),deadlineUnixMs=nonzero64(bytes,at,"deadline");b4Finish(at,bytes,"actorCreate");return{...base,actorId,stableType,reservation,deadlineUnixMs};}
186
- function b4ZljrPayload(v:ZljrRecordV1):Uint8Array{if(v.metadata.length>262144||v.request.length>1048576||v.reply.length>1048576)throw new RangeError("ZLJR length");const out=[90,76,74,82,1];u32(out,v.metadata.length);u32(out,v.request.length);u32(out,v.reply.length);out.push(...v.metadata,...v.request,...v.reply);return Uint8Array.from(out);}
187
- function b4ReadZljrPayload(bytes:Uint8Array):{metadata:Uint8Array;request:Uint8Array;reply:Uint8Array}{const at={value:0};if(read32(bytes,at)!==0x5a4c4a52||read8(bytes,at)!==1)throw new RangeError("ZLJR header");const metadataLength=read32(bytes,at),requestLength=read32(bytes,at),replyLength=read32(bytes,at);if(metadataLength>262144||requestLength>1048576||replyLength>1048576)throw new RangeError("ZLJR length");const metadata=take(bytes,at,metadataLength,"ZLJR metadata"),request=take(bytes,at,requestLength,"ZLJR request"),reply=take(bytes,at,replyLength,"ZLJR reply");b4Finish(at,bytes,"ZLJR");return{metadata,request,reply};}
188
- export function encodeZljrRecordV1(v:ZljrRecordV1):Uint8Array{if(v.source.nodeGeneration===0n||v.source.ownerLeaseGeneration===0n)throw new RangeError("ZLJR record");const source:number[]=[];rid(source,v.source.nodeRid);u64(source,v.source.nodeGeneration);text8(source,v.source.ownerId);u64(source,v.source.ownerLeaseGeneration);if(source.length>65535)throw new RangeError("ZLJR source");const payload=b4ZljrPayload(v),body:number[]=[];text8(body,"__zlink.actor.routed_join.recovery");text8(body,"application/x-zlink-actor-routed-join-recovery-v1");u32(body,payload.length);body.push(...payload);const out=[1,1,source.length>>>8,source.length&255,...source,0];u64(out,v.operation.high);u64(out,v.operation.low);u32(out,0);out.push(0,0,1);u32(out,body.length);out.push(...body);return Uint8Array.from(out);}
187
+ function b4ZljrPayload(v:ZljrRecordV1):Uint8Array{if(v.metadata.length>262144)throw new RangeError("ZLJR length");const out=[90,76,74,82,1];u32(out,v.metadata.length);u32(out,v.request.length);u32(out,v.reply.length);appendBytes(out,v.metadata);appendBytes(out,v.request);appendBytes(out,v.reply);return Uint8Array.from(out);}
188
+ function b4ReadZljrPayload(bytes:Uint8Array):{metadata:Uint8Array;request:Uint8Array;reply:Uint8Array}{const at={value:0};if(read32(bytes,at)!==0x5a4c4a52||read8(bytes,at)!==1)throw new RangeError("ZLJR header");const metadataLength=read32(bytes,at),requestLength=read32(bytes,at),replyLength=read32(bytes,at);if(metadataLength>262144)throw new RangeError("ZLJR length");const metadata=take(bytes,at,metadataLength,"ZLJR metadata"),request=take(bytes,at,requestLength,"ZLJR request"),reply=take(bytes,at,replyLength,"ZLJR reply");b4Finish(at,bytes,"ZLJR");return{metadata,request,reply};}
189
+ export function encodeZljrRecordV1(v:ZljrRecordV1):Uint8Array{if(v.source.nodeGeneration===0n||v.source.ownerLeaseGeneration===0n)throw new RangeError("ZLJR record");const source:number[]=[];rid(source,v.source.nodeRid);u64(source,v.source.nodeGeneration);text8(source,v.source.ownerId);u64(source,v.source.ownerLeaseGeneration);if(source.length>65535)throw new RangeError("ZLJR source");const payload=b4ZljrPayload(v),body:number[]=[];text8(body,"__zlink.actor.routed_join.recovery");text8(body,"application/x-zlink-actor-routed-join-recovery-v1");u32(body,payload.length);appendBytes(body,payload);const out=[1,1,source.length>>>8,source.length&255,...source,0];u64(out,v.operation.high);u64(out,v.operation.low);u32(out,0);out.push(0,0,1);u32(out,body.length);appendBytes(out,body);return Uint8Array.from(out);}
189
190
  export function decodeZljrRecordV1(bytes:Uint8Array):ZljrRecordV1{const at={value:0};if(read8(bytes,at)!==1||read8(bytes,at)!==1)throw new RangeError("ZLJR frozen record");const sourceEnd=boundedEnd(bytes,at,read16(bytes,at),"ZLJR source"),nodeRid=readRid(bytes,at),nodeGeneration=nonzero64(bytes,at,"source node generation"),ownerId=readText8(bytes,at),ownerLeaseGeneration=nonzero64(bytes,at,"source owner lease");exactEnd(at,sourceEnd,"ZLJR source");if(read8(bytes,at)!==0)throw new RangeError("ZLJR metadata flag");const operation={high:read64(bytes,at),low:read64(bytes,at)};if(read32(bytes,at)!==0||read16(bytes,at)!==0||read8(bytes,at)!==1)throw new RangeError("ZLJR frozen record");const payloadEnd=boundedEnd(bytes,at,read32(bytes,at),"ZLJR payload"),packetName=readText8(bytes,at),contentType=readText8(bytes,at),payloadLength=read32(bytes,at);if(packetName!=="__zlink.actor.routed_join.recovery"||contentType!=="application/x-zlink-actor-routed-join-recovery-v1"||payloadLength!==payloadEnd-at.value)throw new RangeError("ZLJR payload");const payload=take(bytes,at,payloadLength,"ZLJR payload");exactEnd(at,payloadEnd,"ZLJR payload");b4Finish(at,bytes,"ZLJR record");return{source:{nodeRid,nodeGeneration,ownerId,ownerLeaseGeneration},operation,...b4ReadZljrPayload(payload)};}
@@ -540,6 +540,7 @@ export class DefaultZLinkSpotManager {
540
540
  objectGeneration: bigint,
541
541
  signal?: AbortSignal
542
542
  ): Promise<void> {
543
+ const readyTarget = this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId);
543
544
  const existing = this.pendingInstanceMaterializations.get(
544
545
  instanceMaterializationKey(meshName, spotId, objectGeneration)
545
546
  );
@@ -549,7 +550,14 @@ export class DefaultZLinkSpotManager {
549
550
  }
550
551
  const release = await this.acquireInstanceActivation(meshName, signal);
551
552
  try {
552
- await this.materializeInstanceCore(meshName, instanceType, spotId, objectGeneration, signal);
553
+ await this.materializeInstanceCore(
554
+ meshName,
555
+ instanceType,
556
+ spotId,
557
+ objectGeneration,
558
+ readyTarget?.objectGeneration === objectGeneration,
559
+ signal
560
+ );
553
561
  } finally {
554
562
  release();
555
563
  }
@@ -560,6 +568,7 @@ export class DefaultZLinkSpotManager {
560
568
  instanceType: string,
561
569
  spotId: RoutingId,
562
570
  objectGeneration: bigint,
571
+ requiresReadyTarget: boolean,
563
572
  signal?: AbortSignal
564
573
  ): Promise<void> {
565
574
  const factory = this.requireInstanceFactory(meshName, instanceType);
@@ -567,6 +576,16 @@ export class DefaultZLinkSpotManager {
567
576
  const materializationKey = instanceMaterializationKey(meshName, spotId, objectGeneration);
568
577
  const materializationPrefix = instanceMaterializationPrefix(meshName, spotId);
569
578
  for (;;) {
579
+ if (
580
+ requiresReadyTarget &&
581
+ this.options.instanceSpotApplicationTargetProvider?.(meshName, spotId)?.objectGeneration !==
582
+ objectGeneration
583
+ ) {
584
+ throw createInternalFrameworkException(
585
+ ZLinkFrameworkInternalErrorKind.SpotGenerationStale,
586
+ `Instance Spot '${String(spotId)}' no longer has its Ready application target.`
587
+ );
588
+ }
570
589
  // A close seals admission before cleanup removes the activation. An
571
590
  // explicit Instance intent arriving at that boundary must wait for the
572
591
  // old resources to be released before materializing the replacement.
@@ -1600,7 +1619,8 @@ export class DefaultZLinkSpotManager {
1600
1619
  const inboundFlow = createInboundFlow(
1601
1620
  envelope.header.flowId,
1602
1621
  envelope.header.flowOrigin,
1603
- this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
1622
+ this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true,
1623
+ undefined
1604
1624
  );
1605
1625
  await runWithFlow(inboundFlow, async () => {
1606
1626
  const request = record.operationKind === OperationKind.InstanceSpotRequest;
@@ -3,7 +3,13 @@ import {
3
3
  createInternalFrameworkException,
4
4
  internalFrameworkErrorKind
5
5
  } from '../framework-errors-internal';
6
- import type { ActorRef, ZLinkActor, ZLinkMessageSerializer, ZLinkSpot } from '../../contracts';
6
+ import type {
7
+ ActorRef,
8
+ RoutingId,
9
+ ZLinkActor,
10
+ ZLinkMessageSerializer,
11
+ ZLinkSpot
12
+ } from '../../contracts';
7
13
  import type { Message } from '../../contracts/Common/Message';
8
14
  import { ZLinkFrameworkException, zlinkMessageMetadata } from '../../contracts';
9
15
  import {
@@ -14,7 +20,8 @@ import {
14
20
  ZLinkDispatchMessageKind
15
21
  } from '../../contracts/Dispatch/ZLinkDispatchOptions';
16
22
  import { flowIfEnabled } from '../diagnostics';
17
- import { createInboundFlow, runWithFlow } from '../diagnostics/flow-context';
23
+ import { createInboundFlow, currentFlowContext, runWithFlow } from '../diagnostics/flow-context';
24
+ import { streamSessionIdFromRoutingId } from '../streams/managed-stream';
18
25
  import type { ZLinkRemoteBoundSessionTarget } from '../actors';
19
26
  import {
20
27
  actorMessageFollowContext,
@@ -58,6 +65,7 @@ export interface ZLinkActorPacketDelivery {
58
65
  readonly fallbackActorRef?: ActorRef;
59
66
  readonly requestTerminal?: ZLinkActorRequestTerminal;
60
67
  readonly messageFollowOrigin?: ZLinkMessageFollowOrigin;
68
+ readonly sourceSessionRid?: RoutingId;
61
69
  }
62
70
 
63
71
  /**
@@ -176,7 +184,16 @@ export class ZLinkSpotActorPacketDispatch {
176
184
  throw error;
177
185
  }
178
186
  return runWithFlow(
179
- createInboundFlow(header.flowId, header.flowOrigin, flowEnabled),
187
+ createInboundFlow(
188
+ header.flowId,
189
+ header.flowOrigin,
190
+ flowEnabled,
191
+ !flowEnabled
192
+ ? undefined
193
+ : delivery.sourceSessionRid === undefined
194
+ ? currentFlowContext()?.streamSessionId
195
+ : streamSessionIdFromRoutingId(delivery.sourceSessionRid)
196
+ ),
180
197
  async () => {
181
198
  const messageKind =
182
199
  header.kind === ZLinkStreamMessageKind.Request
@@ -138,6 +138,7 @@ export class ZLinkSpotActorPacketDrain {
138
138
  actorId,
139
139
  parts,
140
140
  returnResponse: false,
141
+ sourceSessionRid,
141
142
  fallbackActorRef: actorRef as unknown as ActorRef | undefined
142
143
  });
143
144
  }
@@ -200,6 +201,7 @@ export class ZLinkSpotActorPacketDrain {
200
201
  actorId,
201
202
  parts,
202
203
  returnResponse: true,
204
+ sourceSessionRid: info.sourceSessionRid,
203
205
  fallbackActorRef: actorRef as unknown as ActorRef | undefined
204
206
  });
205
207
  this.options.replyActorNoBind?.(
@@ -272,6 +272,9 @@ export class ZLinkSpotNodeRuntimeManager {
272
272
  applicationJobReceiveFlowFailureSink: this.options.applicationJobReceiveFlowFailureSink,
273
273
  peerAdmissionSealed: () => this.options.peerAdmissionSealed?.(spotNodeName) ?? false
274
274
  });
275
+ if (this.options.dispatchErrors !== undefined) {
276
+ node.setDispatchErrorReporter?.(this.options.dispatchErrors, spotNodeName);
277
+ }
275
278
  node.setMailboxRecordDroppedHandler?.((record) =>
276
279
  this.options.dispatchErrors?.report({
277
280
  surface: ZLinkDispatchErrorSurface.RouteMeshChannel,
@@ -1183,7 +1186,8 @@ export class ZLinkSpotNodeRuntimeManager {
1183
1186
  )
1184
1187
  );
1185
1188
  try {
1186
- publisher.publish(channelName, topic, parts, { flags });
1189
+ const processing = publisher.publish(channelName, topic, parts, { flags });
1190
+ void Promise.resolve(processing).catch(() => undefined);
1187
1191
  return { status: ZLinkSubmitStatus.Submitted };
1188
1192
  } catch (error) {
1189
1193
  if (isZLinkBackendResultError(error) && error.operation === 'submit') {
@@ -156,7 +156,8 @@ export class ZLinkSpotRoutePacketDispatch {
156
156
  createInboundFlow(
157
157
  envelope.header.flowId,
158
158
  envelope.header.flowOrigin,
159
- this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
159
+ this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true,
160
+ undefined
160
161
  ),
161
162
  () =>
162
163
  this.options.serial.execute(
@@ -57,7 +57,8 @@ export class ZLinkSpotRoutedBoundSessionDispatch {
57
57
  createInboundFlow(
58
58
  boundSessionSend.flowId ?? boundSessionSend.envelope?.header.flowId,
59
59
  boundSessionSend.flowOrigin ?? boundSessionSend.envelope?.header.flowOrigin,
60
- this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
60
+ this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true,
61
+ undefined
61
62
  ),
62
63
  () =>
63
64
  this.options.routedBoundSessionReceiver?.(
@@ -187,7 +187,8 @@ export class ZLinkSpotSubscriptionDispatch {
187
187
  const inboundFlow = createInboundFlow(
188
188
  envelope.header.flowId,
189
189
  envelope.header.flowOrigin,
190
- this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true
190
+ this.options.dispatchErrors?.flow.flowCreationEnabled() ?? true,
191
+ undefined
191
192
  );
192
193
  try {
193
194
  await this.options.serial.execute(
@@ -152,7 +152,12 @@ export class ZLinkSpotTimerRegistry {
152
152
  normalizeTimerOptions(options),
153
153
  async (tick) => {
154
154
  callbackStarted = false;
155
- const timerFlow = createInboundFlow(undefined, 'Timer', this.flowCreationEnabled());
155
+ const timerFlow = createInboundFlow(
156
+ undefined,
157
+ 'Timer',
158
+ this.flowCreationEnabled(),
159
+ undefined
160
+ );
156
161
  const operation = () => {
157
162
  const current = this.timers.get(name);
158
163
  if (