@weiliang0121/capix-invocation 0.0.0-stage → 0.1.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 (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -2
  3. package/dist/checkpoint/children.d.ts +16 -0
  4. package/dist/checkpoint/children.js +2 -0
  5. package/dist/checkpoint/continuation.d.ts +10 -0
  6. package/dist/checkpoint/continuation.js +2 -0
  7. package/dist/checkpoint/contract.d.ts +76 -0
  8. package/dist/checkpoint/contract.js +1 -0
  9. package/dist/checkpoint/data.d.ts +5 -0
  10. package/dist/checkpoint/data.js +2 -0
  11. package/dist/checkpoint/facts.d.ts +49 -0
  12. package/dist/checkpoint/facts.js +2 -0
  13. package/dist/checkpoint/invocation.d.ts +36 -0
  14. package/dist/checkpoint/invocation.js +2 -0
  15. package/dist/checkpoint/observation.d.ts +32 -0
  16. package/dist/checkpoint/observation.js +2 -0
  17. package/dist/checkpoint/publication.d.ts +20 -0
  18. package/dist/checkpoint/publication.js +2 -0
  19. package/dist/checkpoint/restoration.d.ts +4 -0
  20. package/dist/checkpoint/restoration.js +2 -0
  21. package/dist/checkpoint/selection.d.ts +22 -0
  22. package/dist/checkpoint/selection.js +2 -0
  23. package/dist/checkpoint/target.d.ts +4 -0
  24. package/dist/checkpoint/target.js +2 -0
  25. package/dist/checkpoint/work.d.ts +27 -0
  26. package/dist/checkpoint/work.js +1 -0
  27. package/dist/clock.d.ts +4 -0
  28. package/dist/clock.js +2 -0
  29. package/dist/context/callable.d.ts +12 -0
  30. package/dist/context/callable.js +2 -0
  31. package/dist/context/context.d.ts +58 -0
  32. package/dist/context/context.js +2 -0
  33. package/dist/context/view.d.ts +34 -0
  34. package/dist/context/view.js +2 -0
  35. package/dist/exception/contract.d.ts +11 -0
  36. package/dist/exception/contract.js +2 -0
  37. package/dist/index.d.ts +37 -0
  38. package/dist/index.js +2 -0
  39. package/dist/invocation/cancellation.d.ts +8 -0
  40. package/dist/invocation/cancellation.js +2 -0
  41. package/dist/invocation/changes.d.ts +13 -0
  42. package/dist/invocation/changes.js +2 -0
  43. package/dist/invocation/children.d.ts +72 -0
  44. package/dist/invocation/children.js +2 -0
  45. package/dist/invocation/control.d.ts +8 -0
  46. package/dist/invocation/control.js +2 -0
  47. package/dist/invocation/execution.d.ts +35 -0
  48. package/dist/invocation/execution.js +2 -0
  49. package/dist/invocation/facts.d.ts +5 -0
  50. package/dist/invocation/facts.js +2 -0
  51. package/dist/invocation/failure.d.ts +11 -0
  52. package/dist/invocation/failure.js +2 -0
  53. package/dist/invocation/invocation.d.ts +83 -0
  54. package/dist/invocation/invocation.js +2 -0
  55. package/dist/invocation/progress.d.ts +33 -0
  56. package/dist/invocation/progress.js +1 -0
  57. package/dist/invocation/provenance.d.ts +38 -0
  58. package/dist/invocation/provenance.js +2 -0
  59. package/dist/invocation/reception.d.ts +7 -0
  60. package/dist/invocation/reception.js +1 -0
  61. package/dist/invocation/relation.d.ts +93 -0
  62. package/dist/invocation/relation.js +2 -0
  63. package/dist/invocation/resource-access.d.ts +31 -0
  64. package/dist/invocation/resource-access.js +2 -0
  65. package/dist/invocation/resources.d.ts +8 -0
  66. package/dist/invocation/resources.js +2 -0
  67. package/dist/invocation/result.d.ts +12 -0
  68. package/dist/invocation/result.js +2 -0
  69. package/dist/invocation/stop.d.ts +3 -0
  70. package/dist/invocation/stop.js +2 -0
  71. package/dist/invocation/view.d.ts +30 -0
  72. package/dist/invocation/view.js +2 -0
  73. package/dist/invocation/work.d.ts +31 -0
  74. package/dist/invocation/work.js +2 -0
  75. package/dist/observation/error.d.ts +4 -0
  76. package/dist/observation/error.js +2 -0
  77. package/dist/observation/facts.d.ts +64 -0
  78. package/dist/observation/facts.js +1 -0
  79. package/dist/observation/invocation.d.ts +17 -0
  80. package/dist/observation/invocation.js +2 -0
  81. package/dist/observation/observer.d.ts +13 -0
  82. package/dist/observation/observer.js +2 -0
  83. package/dist/observation/session.d.ts +17 -0
  84. package/dist/observation/session.js +2 -0
  85. package/dist/operation/failure.d.ts +1 -0
  86. package/dist/operation/failure.js +2 -0
  87. package/dist/output/delivery.d.ts +2 -0
  88. package/dist/output/delivery.js +2 -0
  89. package/dist/output/section.d.ts +21 -0
  90. package/dist/output/section.js +2 -0
  91. package/dist/value/array.d.ts +2 -0
  92. package/dist/value/array.js +2 -0
  93. package/dist/value/object.d.ts +2 -0
  94. package/dist/value/object.js +2 -0
  95. package/dist/value/string.d.ts +2 -0
  96. package/dist/value/string.js +2 -0
  97. package/package.json +45 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wei.liang (https://github.com/weiliang0121)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,19 @@
1
- # Temporary Holding Version
1
+ # @weiliang0121/capix-invocation
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Invocation lifecycle, child relations, reception, output, and checkpoint activity for CAPiX.
4
+
5
+ ES modules and TypeScript declarations. Requires Node.js 22.23.2 or newer.
6
+
7
+ ```sh
8
+ npm install @weiliang0121/capix-invocation
9
+ ```
10
+
11
+ ## Public entry points
12
+
13
+ - `@weiliang0121/capix-invocation`
14
+
15
+ This package is part of CAPiX. The npm distribution contains compiled JavaScript, type declarations, and this package's MIT license. Reference services and client applications are not included in this package or the initial npm release.
16
+
17
+ ## License
18
+
19
+ MIT. Copyright (c) 2026 wei.liang. See [LICENSE](./LICENSE).
@@ -0,0 +1,16 @@
1
+ import type { CheckpointChild, CheckpointHead, InvocationCheckpointFrame } from '@weiliang0121/capix-checkpoint';
2
+ import type { CheckpointBinding } from './work.js';
3
+ import type { InvocationContext } from '../context/context.js';
4
+ import type { InvocationChildren, InvocationChildBaseline } from '../invocation/children.js';
5
+ import type { InvocationRelation } from '../invocation/relation.js';
6
+ import type { InvocationReceptionBinding } from '../invocation/reception.js';
7
+ import type { CheckpointCodec } from '@weiliang0121/capix-contracts';
8
+ export declare function resolveCheckpointChild(saved: CheckpointChild, value?: CheckpointHead): {
9
+ readonly kind: 'continuation';
10
+ } | {
11
+ readonly kind: 'delivery';
12
+ readonly child: CheckpointChild;
13
+ };
14
+ export declare function decodeCheckpointChild(child: CheckpointChild, binding: CheckpointBinding | undefined, signal: AbortSignal, receptions?: readonly InvocationReceptionBinding[]): InvocationChildBaseline;
15
+ export declare function captureCheckpointChildren(context: InvocationContext, relations: InvocationChildren, savedChildren: ReadonlyMap<string, CheckpointChild>): Pick<InvocationCheckpointFrame, 'nextChildOrder' | 'children'>;
16
+ export declare function captureCheckpointChild(context: InvocationContext, relation: InvocationRelation, saved?: CheckpointChild, encode?: (role: string, value: unknown, codec?: CheckpointCodec<any>) => import('@weiliang0121/capix-contracts').CheckpointValue): CheckpointChild;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{isEqual}from"es-toolkit";import{cloneCheckpointHead,cloneCheckpointValue}from"@weiliang0121/capix-checkpoint";import{checkpointTarget}from"./target.js";import{RuntimeErrorHelper}from"@weiliang0121/capix-diagnostics";import{checkpointReceptionBinding,decodeCheckpointDiagnostic,decodeCheckpointReception,decodeCheckpointHandledReception}from"./facts.js";import{failureFact}from"../invocation/failure.js";import{checkpointDataEqual,encodeCheckpointData}from"./data.js";import{InvocationCancelled}from"../invocation/cancellation.js";function resolveCheckpointChild(saved,value){if(saved.state.kind==="failed")throw new Error("Historical failed child cannot be resumed");if(saved.state.kind==="returned"&&saved.state.reception.kind==="failed")throw new Error("Historical failed child reception cannot be resumed");if(saved.state.kind!=="waiting")return{kind:"delivery",child:saved};if(!value)throw new Error("Waiting child has no durable continuation; execution is unknown");const head=cloneCheckpointHead(value);if(!isEqual(head.image.frame.owner,saved.identity)||!checkpointDataEqual(head.image.frame.input,saved.input)||!isEqual(head.image.contract,saved.contract))throw new Error("Child checkpoint differs from parent-owned identity");if(!head.delivery)return{kind:"continuation"};if(head.delivery.status!=="succeeded")throw new Error("Failed or cancelled child cannot be resumed");return{kind:"delivery",child:{...saved,state:{kind:"returned",output:head.delivery.output,progress:head.delivery.progress,reception:{kind:"pending"}}}}}__name(resolveCheckpointChild,"resolveCheckpointChild");function decodeCheckpointChild(child,binding,signal,receptions=[]){const receptionBinding=checkpointReceptionBinding(child,receptions),target=checkpointTarget(child,binding,signal),identity={target,round:child.round,order:child.order,key:child.key,declarationPosition:child.target.position},state=target.context.state;if(child.state.kind==="waiting")return{...identity,state:{reception:{status:"pending"}}};if(child.state.kind==="failed"){const returned2={status:"failed",error:child.state.error,diagnostic:decodeCheckpointDiagnostic(child.state.error),failure:Object.freeze({...child.state.failure,error:child.state.error})},handled=decodeCheckpointHandledReception(child,receptionBinding),reception2=handled?{status:"handled",output:handled.output,...receptionBinding?{contract:receptionBinding}:{}}:{status:"pending"};return{...identity,state:{returned:returned2,reception:reception2}}}if(state.status!=="succeeded")throw new Error("Saved delivery did not produce a successful target");const returned={status:"succeeded",output:state.output},savedReception=decodeCheckpointReception(child,receptionBinding),contract=receptionBinding?{contract:receptionBinding}:{},reception=savedReception.kind==="accepted"?{status:"accepted",output:savedReception.output,...contract}:savedReception.kind==="failed"?{status:"failed",error:savedReception.error,diagnostic:decodeCheckpointDiagnostic(savedReception.error),failure:Object.freeze({...savedReception.failure,error:savedReception.error}),...contract}:{status:savedReception.kind,...contract};return{...identity,state:{returned,reception}}}__name(decodeCheckpointChild,"decodeCheckpointChild");function captureCheckpointChildren(context,relations,savedChildren){return{nextChildOrder:relations.nextOrder,children:relations.values().map(relation=>captureCheckpointChild(context,relation,savedChildren.get(relation.invocation.context.id)))}}__name(captureCheckpointChildren,"captureCheckpointChildren");function captureCheckpointChild(context,relation,saved,encode=(_role,value,codec)=>codec?cloneCheckpointValue(codec.encode(value)):encodeCheckpointData(value)){const target=relation.invocation,binding=target.checkpointBinding,identity=target.identity;if(!identity)throw new Error("Checkpoint child has no explicit callable identity");const position=relation.declarationPosition??saved?.target.position;if(position===void 0)throw new Error("Checkpoint child has no fixed declaration position");const base={identity,target:{position},...binding?{contract:{key:binding.key,version:binding.version}}:saved?.contract?{contract:saved.contract}:{},round:relation.round,order:relation.order,...relation.key?{key:relation.key}:{},input:encode("input",target.context.input,binding?.input)};if(!relation.returned){if(!base.contract)throw new Error("Waiting child has no checkpoint declaration");return{...base,state:{kind:"waiting"}}}if(relation.returned.status==="failed"){const failure=relation.returned.failure,reception2=relation.reception;if(reception2.status==="handled"){if(!failure||!failure.contextId||!["execute","receive","handling"].includes(failure.phase)||relation.returned.error instanceof InvocationCancelled)throw new Error("Only a completed non-cancelled business-stage failure can have checkpointed handling");if(reception2.contract&&reception2.contract.childPosition!==position)throw new Error("Checkpoint handling targets a different child declaration");const output2=reception2.contract?{output:encode("reception",reception2.output,reception2.contract.codec)}:reception2.output!==void 0?{output:encode("reception",reception2.output)}:{};return{...base,state:{kind:"failed",error:saved?.state.kind==="failed"?saved.state.error:encode("failure",relation.returned.diagnostic??RuntimeErrorHelper.format(relation.returned.error),{encode:cloneCheckpointValue,decode:__name(value=>value,"decode")}),failure:failureFact(failure),progress:captureChildProgress(target,encode),reception:{kind:"handled",...reception2.contract?{contract:{position:reception2.contract.position}}:{},...output2}}}}if(relation.round>=context.progress.round||failure?.kind!=="exception"||!failure.contract||failure.contextId!==target.context.id)throw new Error("Only a prior round declared child exception can be checkpointed as history");return saved?.state.kind==="failed"?{...base,state:saved.state}:{...base,state:{kind:"failed",error:encode("failure",relation.returned.diagnostic??RuntimeErrorHelper.format(relation.returned.error),{encode:cloneCheckpointValue,decode:__name(value=>value,"decode")}),failure:{kind:"exception",phase:failure.phase,contextId:failure.contextId,contract:failure.contract},progress:captureChildProgress(target,encode)}}}const output=encode("output",relation.returned.output,binding?.output),reception=relation.reception;if(reception.status==="handled")throw new Error("A successful child cannot have a handled failure reception");const receptionContract=reception.status!=="pending"&&reception.contract?{contract:{position:reception.contract.position}}:{};if(reception.status!=="pending"&&reception.contract&&reception.contract.childPosition!==position)throw new Error("Checkpoint reception targets a different child declaration");if(reception.status==="failed"){const failure=reception.failure,continuation=context.continuation,origin=continuation?.origin;if(context.progress.round!==2||relation.round!==1||continuation?.stage!=="handling"||origin?.kind!=="child-reception"||origin.child.parentContextId!==context.id||origin.child.childContextId!==identity.contextId||origin.child.parentRound!==relation.round||origin.child.order!==relation.order||failure?.kind!=="exception"||!failure.contract||failure.contextId!==context.id||failure.phase==="handling")throw new Error("Only the prior handled declared reception exception can be checkpointed as history");return saved?.state.kind==="returned"&&saved.state.reception.kind==="failed"?{...base,state:{kind:"returned",output,progress:captureChildProgress(target,encode),reception:saved.state.reception}}:{...base,state:{kind:"returned",output,progress:captureChildProgress(target,encode),reception:{kind:"failed",...receptionContract,error:encode("receptionFailure",reception.diagnostic??RuntimeErrorHelper.format(reception.error),{encode:cloneCheckpointValue,decode:__name(value=>value,"decode")}),failure:{kind:"exception",phase:failure.phase,contextId:failure.contextId,contract:failure.contract}}}}}return{...base,state:{kind:"returned",output,progress:captureChildProgress(target,encode),reception:reception.status==="accepted"?{kind:"accepted",...receptionContract,...reception.contract?{output:encode("reception",reception.output,reception.contract.codec)}:reception.output!==void 0?{output:encode("reception",reception.output)}:{}}:{kind:reception.status,...receptionContract}}}}__name(captureCheckpointChild,"captureCheckpointChild");function captureChildProgress(target,encode){const context=target.context,currentInput=encode("currentInput",context.currentInput,target.checkpointBinding?.input);return{round:context.progress.round,phase:context.progress.phase,currentInput}}__name(captureChildProgress,"captureChildProgress");export{captureCheckpointChild,captureCheckpointChildren,decodeCheckpointChild,resolveCheckpointChild};
@@ -0,0 +1,10 @@
1
+ import type { InvocationExceptionOrigin } from '../invocation/provenance.js';
2
+ import type { CheckpointChild, CheckpointContinuation, InvocationCheckpointFrame } from '@weiliang0121/capix-checkpoint';
3
+ export interface CheckpointContinuationFact {
4
+ readonly fromRound: 1;
5
+ readonly stage: 'accept' | 'handling';
6
+ readonly reason: string;
7
+ readonly origin?: InvocationExceptionOrigin;
8
+ }
9
+ export declare function captureCheckpointContinuation(continuation: CheckpointContinuationFact | undefined, children: readonly CheckpointChild[]): CheckpointContinuation | undefined;
10
+ export declare function restoreCheckpointContinuation(frame: InvocationCheckpointFrame): CheckpointContinuationFact | undefined;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{checkpointReference,checkpointReferenceChild}from"@weiliang0121/capix-checkpoint";function captureCheckpointContinuation(continuation,children){if(!continuation)return;const{origin,...accepted}=continuation;if(!origin||origin.kind==="self")return Object.freeze({...accepted,...origin?{origin}:{}});const child=children.find(child2=>child2.identity.contextId===origin.child.childContextId);if(!child||child.identity.parentContextId!==origin.child.parentContextId||child.round!==origin.child.parentRound||child.order!==origin.child.order)throw new Error("Continuation source is not the saved direct child relationship");return Object.freeze({...continuation,origin:Object.freeze({kind:origin.kind,child:checkpointReference(child)})})}__name(captureCheckpointContinuation,"captureCheckpointContinuation");function restoreCheckpointContinuation(frame){const continuation=frame.continuation;if(!continuation)return;const{origin,...accepted}=continuation;if(!origin||origin.kind==="self")return Object.freeze({...accepted,...origin?{origin}:{}});const child=checkpointReferenceChild(origin.child,frame.children);return Object.freeze({...continuation,origin:Object.freeze({kind:origin.kind,child:Object.freeze({parentContextId:frame.owner.contextId,childContextId:child.identity.contextId,parentRound:child.round,order:child.order})})})}__name(restoreCheckpointContinuation,"restoreCheckpointContinuation");export{captureCheckpointContinuation,restoreCheckpointContinuation};
@@ -0,0 +1,76 @@
1
+ import type { InvocationIdentity } from '@weiliang0121/capix-contracts';
2
+ import type { ProgressReceiver } from '@weiliang0121/capix-changes';
3
+ import type { CheckpointChild, CheckpointDelivery, CheckpointHead, CheckpointSaveReceipt, CheckpointReference, CheckpointStore, InvocationCheckpointFrame } from '@weiliang0121/capix-checkpoint';
4
+ export type CheckpointFact = Readonly<{
5
+ activityId: string;
6
+ contextId: string;
7
+ owner: InvocationIdentity;
8
+ recovering: boolean;
9
+ sequence: number;
10
+ occurredAt: string;
11
+ } & ({
12
+ kind: 'captured' | 'saved';
13
+ checkpointId: string;
14
+ point: string;
15
+ } | {
16
+ kind: 'checking' | 'continued';
17
+ checkpointId: string;
18
+ point: string;
19
+ } | {
20
+ kind: 'installed';
21
+ checkpointId: string;
22
+ point: string;
23
+ frame: InvocationCheckpointFrame;
24
+ } | {
25
+ kind: 'child-restored';
26
+ child: CheckpointChild;
27
+ mode: 'continuation' | 'delivery';
28
+ } | {
29
+ kind: 'activity';
30
+ fact: import('../observation/facts.js').InvocationFact;
31
+ } | {
32
+ kind: 'resource';
33
+ fact: import('../observation/facts.js').ResourceObservation;
34
+ } | {
35
+ kind: 'transcript';
36
+ fact: import('@weiliang0121/capix-protocol').TranscriptEvent;
37
+ } | {
38
+ kind: 'memory';
39
+ fact: import('@weiliang0121/capix-protocol').MemoryEvent;
40
+ } | {
41
+ kind: 'failed';
42
+ stage: 'capture' | 'save' | 'restore' | 'finish';
43
+ error: unknown;
44
+ childContextId?: string;
45
+ } | {
46
+ kind: 'finishing' | 'finished';
47
+ status: CheckpointDelivery['status'];
48
+ })>;
49
+ export interface CheckpointInstallation {
50
+ readonly store: CheckpointStore;
51
+ readonly observation?: {
52
+ observe(fact: CheckpointFact): void;
53
+ readonly failure?: 'isolate' | 'propagate';
54
+ };
55
+ readonly feedback?: ProgressReceiver<CheckpointFact>;
56
+ }
57
+ export interface CheckpointWriter {
58
+ select(position: number, initial?: readonly CheckpointReference[]): InvocationCheckpointSelection;
59
+ save(point: string, state: unknown, references?: CheckpointSaveReferences): CheckpointSaveReceipt;
60
+ }
61
+ declare const occurrence: unique symbol;
62
+ export interface InvocationCheckpointOccurrence {
63
+ readonly [occurrence]: true;
64
+ }
65
+ export interface InvocationCheckpointSelection extends Iterable<CheckpointReference> {
66
+ readonly length: number;
67
+ at(index: number): CheckpointReference | undefined;
68
+ occurrenceAt(index: number): InvocationCheckpointOccurrence | undefined;
69
+ add(reference: CheckpointReference): InvocationCheckpointOccurrence;
70
+ remove(occurrence: InvocationCheckpointOccurrence): void;
71
+ }
72
+ export type CheckpointSaveReferences = Readonly<Record<string, CheckpointReference | readonly CheckpointReference[] | InvocationCheckpointSelection>>;
73
+ export interface CheckpointRestoration {
74
+ readonly head: CheckpointHead;
75
+ }
76
+ export {};
@@ -0,0 +1 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
@@ -0,0 +1,5 @@
1
+ import { type CheckpointValue } from '@weiliang0121/capix-contracts';
2
+ export declare function encodeCheckpointData(value: unknown): CheckpointValue;
3
+ export declare function decodeCheckpointData(value: CheckpointValue): unknown;
4
+ export declare function runCheckpointCheck(check: () => unknown): void;
5
+ export declare function checkpointDataEqual(left: unknown, right: unknown): boolean;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{stableValue}from"@weiliang0121/capix-contracts";import{cloneCheckpointValue}from"@weiliang0121/capix-checkpoint";function encodeCheckpointData(value){const fixed=stableValue(value);let tagged=fixed!==null&&typeof fixed=="object"&&!Array.isArray(fixed)&&Reflect.get(fixed,"format")==="capix.invocation.data@1";const encode=__name(entry=>entry===void 0?(tagged=!0,"~u"):typeof entry=="number"&&Object.is(entry,-0)?"~0":typeof entry=="string"?entry.startsWith("~")?`~${entry}`:entry:Array.isArray(entry)?entry.map(encode):entry!==null&&typeof entry=="object"?Object.fromEntries(Object.entries(entry).map(([key,child])=>[key,encode(child)])):entry,"encode"),encoded=encode(fixed);return cloneCheckpointValue(tagged?{format:"capix.invocation.data@1",value:encoded}:fixed)}__name(encodeCheckpointData,"encodeCheckpointData");function decodeCheckpointData(value){const record=value;if(!value||typeof value!="object"||Array.isArray(value)||record.format!=="capix.invocation.data@1"||!Object.hasOwn(value,"value")||Object.keys(value).length!==2)return stableValue(value);const decode=__name(entry=>{if(entry!=="~u"){if(entry==="~0")return-0;if(typeof entry=="string"&&entry.startsWith("~~"))return entry.slice(1);if(typeof entry=="string"&&entry.startsWith("~"))throw new Error("Invalid invocation data escape");return Array.isArray(entry)?entry.map(decode):entry!==null&&typeof entry=="object"?Object.fromEntries(Object.entries(entry).map(([key,child])=>[key,decode(child)])):entry}},"decode");return stableValue(decode(record.value))}__name(decodeCheckpointData,"decodeCheckpointData");function runCheckpointCheck(check){const result=check();if(result!==null&&(typeof result=="object"||typeof result=="function")&&typeof result.then=="function")throw Promise.resolve(result).catch(()=>{}),new Error("Checkpoint check must complete synchronously")}__name(runCheckpointCheck,"runCheckpointCheck");function checkpointDataEqual(left,right){const pairs=new WeakMap,equal=__name((a,b)=>{if(Object.is(a,b))return!0;if(a===null||b===null||typeof a!="object"||typeof b!="object"||Array.isArray(a)!==Array.isArray(b))return!1;let seen=pairs.get(a);if(seen?.has(b))return!0;seen??=new WeakSet,pairs.set(a,seen),seen.add(b);const ak=Object.keys(a),bk=Object.keys(b);return ak.length===bk.length&&ak.every(key=>Object.hasOwn(b,key)&&equal(Reflect.get(a,key),Reflect.get(b,key)))},"equal");return equal(left,right)}__name(checkpointDataEqual,"checkpointDataEqual");export{checkpointDataEqual,decodeCheckpointData,encodeCheckpointData,runCheckpointCheck};
@@ -0,0 +1,49 @@
1
+ import type { RuntimeErrorValue, CheckpointValue } from '@weiliang0121/capix-contracts';
2
+ import type { CheckpointChild, CheckpointChildReception, CheckpointHandledReception, CheckpointReferences, InvocationCheckpointFrame } from '@weiliang0121/capix-checkpoint';
3
+ import type { CheckpointBinding, CheckpointChildBinding, CheckpointReferenceSlot } from './work.js';
4
+ import type { InvocationReceptionBinding } from '../invocation/reception.js';
5
+ type ChildProgress = {
6
+ readonly round: number;
7
+ readonly currentInput: unknown;
8
+ readonly phase: 'execute' | 'receive' | 'handling';
9
+ };
10
+ export type DecodedCheckpointReception = Exclude<CheckpointChildReception, {
11
+ readonly kind: 'accepted';
12
+ }> | (Omit<Extract<CheckpointChildReception, {
13
+ readonly kind: 'accepted';
14
+ }>, 'output'> & {
15
+ readonly output?: unknown;
16
+ });
17
+ export type DecodedCheckpointHandledReception = Omit<CheckpointHandledReception, 'output'> & {
18
+ readonly output?: unknown;
19
+ };
20
+ export type DecodedCheckpointChild = Omit<CheckpointChild, 'input' | 'state'> & {
21
+ readonly input: unknown;
22
+ readonly state: {
23
+ readonly kind: 'waiting';
24
+ } | {
25
+ readonly kind: 'returned';
26
+ readonly output: unknown;
27
+ readonly progress: ChildProgress;
28
+ readonly reception: DecodedCheckpointReception;
29
+ } | (Omit<Extract<CheckpointChild['state'], {
30
+ kind: 'failed';
31
+ }>, 'progress' | 'reception'> & {
32
+ readonly progress: ChildProgress;
33
+ readonly reception?: DecodedCheckpointHandledReception;
34
+ });
35
+ };
36
+ export type DecodedCheckpointFrame = Omit<InvocationCheckpointFrame, 'input' | 'currentInput' | 'children'> & {
37
+ readonly input: unknown;
38
+ readonly currentInput: unknown;
39
+ readonly children: readonly DecodedCheckpointChild[];
40
+ readonly child?: (contextId: string) => DecodedCheckpointChild | undefined;
41
+ };
42
+ export declare function checkpointChildBinding(child: CheckpointChild, children?: readonly CheckpointChildBinding[]): CheckpointBinding | undefined;
43
+ export declare function checkpointReceptionBinding(child: CheckpointChild, receptions?: readonly InvocationReceptionBinding[]): InvocationReceptionBinding | undefined;
44
+ export declare function decodeCheckpointReception(child: CheckpointChild, binding: InvocationReceptionBinding | undefined): DecodedCheckpointReception;
45
+ export declare function decodeCheckpointHandledReception(child: CheckpointChild, binding: InvocationReceptionBinding | undefined): DecodedCheckpointHandledReception | undefined;
46
+ export declare function checkCheckpointReferences(frame: InvocationCheckpointFrame, references: CheckpointReferences, slots?: Readonly<Record<string, CheckpointReferenceSlot>>, lookup?: (id: string) => CheckpointChild | undefined): void;
47
+ export declare function decodeCheckpointFrame(frame: InvocationCheckpointFrame, binding: CheckpointBinding, children?: readonly CheckpointChildBinding[], receptions?: readonly InvocationReceptionBinding[]): DecodedCheckpointFrame;
48
+ export declare function decodeCheckpointDiagnostic(value: CheckpointValue): RuntimeErrorValue;
49
+ export {};
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{stableValue}from"@weiliang0121/capix-contracts";import{decodeCheckpointData,runCheckpointCheck}from"./data.js";import{checkpointReferenceChild}from"@weiliang0121/capix-checkpoint";function checkpointChildBinding(child,children=[]){const target=children[child.target.position];if(!target||target.kind!==child.identity.kind||target.binding?.key!==child.contract?.key||target.binding?.version!==child.contract?.version)throw new Error("Checkpoint child declaration position or contract is incompatible");return target.binding}__name(checkpointChildBinding,"checkpointChildBinding");function checkpointReceptionBinding(child,receptions=[]){const reception=child.state.kind==="waiting"?void 0:child.state.reception;if(!reception||reception.kind==="pending"||reception.contract===void 0)return;const position=reception.contract.position,binding=receptions[position];if(!binding||binding.position!==position||binding.childPosition!==child.target.position)throw new Error("Checkpoint reception contract position or child declaration is incompatible");return binding}__name(checkpointReceptionBinding,"checkpointReceptionBinding");function decodeCheckpointReception(child,binding){if(child.state.kind!=="returned")throw new Error("Only returned children have saved reception facts");const saved=child.state.reception;if(saved.kind!=="accepted")return saved;if(!binding)return Object.freeze({...saved,...Object.hasOwn(saved,"output")?{output:decodeCheckpointData(saved.output)}:{}});if(!Object.hasOwn(saved,"output"))throw new Error("Contracted checkpoint reception requires encoded output");const output=stableValue(binding.codec.decode(saved.output));return runCheckpointCheck(()=>binding.check(output)),Object.freeze({...saved,output})}__name(decodeCheckpointReception,"decodeCheckpointReception");function decodeCheckpointHandledReception(child,binding){if(child.state.kind!=="failed")throw new Error("Only failed children have handled reception facts");const saved=child.state.reception;if(!saved)return saved;if(!binding)return Object.freeze({...saved,...Object.hasOwn(saved,"output")?{output:decodeCheckpointData(saved.output)}:{}});if(!Object.hasOwn(saved,"output"))throw new Error("Contracted checkpoint handling requires encoded output");const output=stableValue(binding.codec.decode(saved.output));return runCheckpointCheck(()=>binding.check(output)),Object.freeze({...saved,output})}__name(decodeCheckpointHandledReception,"decodeCheckpointHandledReception");function checkCheckpointReferences(frame,references,slots={},lookup){if(Object.keys(references).length!==Object.keys(slots).length||Object.keys(references).some(name=>!Object.hasOwn(slots,name)))throw new Error("Checkpoint reference slots differ from the registered point");let index;const find=lookup??(id=>(index??=new Map(frame.children.map(child=>[child.identity.contextId,child])),index.get(id)));for(const[name,slot]of Object.entries(slots)){const saved=references[name];if(!saved||slot.cardinality==="many"!==Array.isArray(saved))throw new Error("Checkpoint reference cardinality differs from the registered point");const values=Array.isArray(saved)?saved:[saved];for(const reference of values){const child=find(reference.contextId);if(!child||checkpointReferenceChild(reference,[child]).target.position!==slot.position)throw new Error("Checkpoint reference targets a different child declaration")}}}__name(checkCheckpointReferences,"checkCheckpointReferences");function decodeCheckpointFrame(frame,binding,children=[],receptions=[]){const decoded=frame.children.map(child=>{const target=checkpointChildBinding(child,children),input=target?stableValue(target.input.decode(child.input)):decodeCheckpointData(child.input),saved=child.state;if(saved.kind==="waiting")return Object.freeze({...child,input,state:saved});const progress=Object.freeze({...saved.progress,currentInput:target?stableValue(target.input.decode(saved.progress.currentInput)):decodeCheckpointData(saved.progress.currentInput)});if(saved.kind==="failed"){const reception2=decodeCheckpointHandledReception(child,checkpointReceptionBinding(child,receptions));return Object.freeze({...child,input,state:Object.freeze({...saved,progress,...reception2?{reception:reception2}:{}})})}const reception=decodeCheckpointReception(child,checkpointReceptionBinding(child,receptions));return Object.freeze({...child,input,state:Object.freeze({...saved,progress,reception,output:target?stableValue(target.output.decode(saved.output)):decodeCheckpointData(saved.output)})})});return Object.freeze({...frame,input:stableValue(binding.input.decode(frame.input)),currentInput:stableValue(binding.input.decode(frame.currentInput)),children:Object.freeze(decoded)})}__name(decodeCheckpointFrame,"decodeCheckpointFrame");function decodeCheckpointDiagnostic(value){if(!value||typeof value!="object"||Array.isArray(value))throw new Error("Invalid saved diagnostic");const data=value;if(typeof data.code!="string"||typeof data.message!="string")throw new Error("Invalid saved diagnostic code/message");if(data.name!==void 0&&typeof data.name!="string")throw new Error("Invalid saved diagnostic name");if(data.stack!==void 0&&typeof data.stack!="string")throw new Error("Invalid saved diagnostic stack");if(data.errors!==void 0&&!Array.isArray(data.errors))throw new Error("Invalid saved diagnostic errors");const errors=Array.isArray(data.errors)?data.errors.map(decodeCheckpointDiagnostic):void 0;return errors&&Object.freeze(errors),Object.freeze({code:data.code,message:data.message,...data.name!==void 0?{name:data.name}:{},...data.stack!==void 0?{stack:data.stack}:{},...data.detail!==void 0?{detail:data.detail}:{},...data.cause!==void 0?{cause:decodeCheckpointDiagnostic(data.cause)}:{},...errors?{errors}:{}})}__name(decodeCheckpointDiagnostic,"decodeCheckpointDiagnostic");export{checkCheckpointReferences,checkpointChildBinding,checkpointReceptionBinding,decodeCheckpointDiagnostic,decodeCheckpointFrame,decodeCheckpointHandledReception,decodeCheckpointReception};
@@ -0,0 +1,36 @@
1
+ import { type Stable } from '@weiliang0121/capix-contracts';
2
+ import type { Invocation } from '../invocation/invocation.js';
3
+ import type { InvocationContext } from '../context/context.js';
4
+ import type { InvocationObservation } from '../observation/invocation.js';
5
+ import type { CheckpointInstallation, CheckpointRestoration, CheckpointWriter } from './contract.js';
6
+ import type { InvocationCheckpointWork } from './work.js';
7
+ import type { InvocationTarget } from '../invocation/relation.js';
8
+ export declare class InvocationCheckpoint<Input, Output, Context extends InvocationContext<Input, Output>> {
9
+ #private;
10
+ private readonly invocation;
11
+ private readonly installation;
12
+ private readonly work;
13
+ private readonly signal;
14
+ readonly activityId: `${string}-${string}-${string}-${string}-${string}`;
15
+ readonly observation: InvocationObservation;
16
+ constructor(invocation: Invocation<Input, Output, Context>, installation: CheckpointInstallation, work: InvocationCheckpointWork<Input, Output, Context> | undefined, signal: AbortSignal, restore?: CheckpointRestoration);
17
+ private emit;
18
+ begin(): void;
19
+ reportFailure(stage: 'restore' | 'finish', error: unknown, childContextId?: string): void;
20
+ private install;
21
+ release(): void;
22
+ private selectionAccess;
23
+ private authenticateSelectionReference;
24
+ private createSelection;
25
+ private captureReferences;
26
+ writer(): CheckpointWriter | undefined;
27
+ resume(): Output | Stable<Output> | Promise<Output | Stable<Output>>;
28
+ restoreChild(position: number, contextId: string, create: () => InvocationTarget): InvocationTarget;
29
+ finish(result: {
30
+ status: 'succeeded';
31
+ output: Stable<Output>;
32
+ } | {
33
+ status: 'failed' | 'cancelled';
34
+ }): void;
35
+ private finalize;
36
+ }
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{stableValue}from"@weiliang0121/capix-contracts";import{randomUUID}from"node:crypto";import{isEqual}from"es-toolkit";import{ProgressChannel}from"@weiliang0121/capix-changes";import{ObserverSession}from"../observation/session.js";import{cloneCheckpointHead,cloneCheckpointDelivery,cloneCheckpointValue,checkCheckpointFinishReceipt,checkpointHeadCommit,createCheckpointValueBlock,checkCheckpointCommitReceipt,checkpointReferenceChild}from"@weiliang0121/capix-checkpoint";import{publishCheckpointChild,publishCheckpointValue,encodeCheckpointFact,restoredCheckpointChild}from"./publication.js";import{checkpointDataEqual,runCheckpointCheck}from"./data.js";import{decodeCheckpointChild,resolveCheckpointChild}from"./children.js";import{checkpointChildBinding,checkCheckpointReferences,decodeCheckpointFrame}from"./facts.js";import{restoreCheckpointContinuation}from"./continuation.js";import{CheckpointObservation}from"./observation.js";import{CheckpointSelectionState}from"./selection.js";const active=new WeakMap;class InvocationCheckpoint{static{__name(this,"InvocationCheckpoint")}invocation;installation;work;signal;activityId=randomUUID();observation;#sequence=0;#revision=0;#checkpointId;#saving=!1;#commitUncertain=!1;#claimed=!1;#ready=!1;#terminal=!1;#restore;#restoredSelectionBasis;#input;#currentInput;#published=new Map;#savedChildren=new Map;#resumedChildren=new Map;#selections=new WeakMap;#restoredSelections=new WeakMap;#arraySelections=new Map;#observer;#feedback;constructor(invocation,installation,work,signal,restore){if(this.invocation=invocation,this.installation=installation,this.work=work,this.signal=signal,this.#observer=installation.observation?new ObserverSession({observe:__name(fact=>installation.observation.observe(fact),"observe"),available:__name(()=>!0,"available")},installation.observation.failure??"isolate"):void 0,this.#feedback=installation.feedback?new ProgressChannel(installation.feedback):void 0,this.observation=new CheckpointObservation(event=>this.emit(event)),restore){this.#restore=cloneCheckpointHead(restore.head),this.#revision=this.#restore.revision,this.#checkpointId=this.#restore.image.id;const image=this.#restore.image;if(!work||image.formatVersion!==6||this.#restore.delivery||image.contract.key!==work.key||image.contract.version!==work.version||!isEqual(image.frame.owner,invocation.identity)||image.frame.round!==1||image.frame.continuation!==void 0||!work.points[image.point])throw new Error("Incompatible checkpoint continuation");if(invocation.context.progress.round!==image.frame.round||!checkpointDataEqual(cloneCheckpointValue(work.input.encode(invocation.context.currentInput)),image.frame.currentInput)||!checkpointDataEqual(cloneCheckpointValue(work.input.encode(invocation.context.input)),image.frame.input))throw new Error("Checkpoint input changed during binding");if(!isEqual(invocation.context.continuation,restoreCheckpointContinuation(image.frame)))throw new Error("Checkpoint continuation changed during binding");checkCheckpointReferences(image.frame,image.references,work.points[image.point].references);const children=image.frame.children.map(child=>decodeCheckpointChild(child,checkpointChildBinding(child,work.children),signal,work.receptions));invocation.children.install(image.frame.nextChildOrder,children);let basis=checkpointHeadCommit(this.#restore);if(!basis){const current=installation.store.read(invocation.context.id);if(!current||current.revision!==this.#restore.revision||!checkpointDataEqual(current.image,image)||current.delivery)throw new Error("Checkpoint publication differs from the supplied head");basis=checkpointHeadCommit(current)}if(!basis)throw new Error("Checkpoint has no authenticated publication basis");this.#input=Object.freeze({source:invocation.context.input,encoded:image.frame.input,reference:basis.frame.input}),this.#currentInput=Object.freeze({source:invocation.context.currentInput,encoded:image.frame.currentInput,reference:basis.frame.currentInput});const decoded=decodeCheckpointFrame(image.frame,work,work.children,work.receptions),records=new Map(basis.children.map(child=>[child.identity.contextId,child]));for(let index=0;index<image.frame.children.length;index++){const child=image.frame.children[index],relation=invocation.children.byContextId(child.identity.contextId),record=records.get(child.identity.contextId);if(!record)throw new Error("Checkpoint child publication basis is missing");this.#savedChildren.set(child.identity.contextId,child),this.#published.set(child.identity.contextId,restoredCheckpointChild(child,decoded.children[index],record,relation))}if("kind"in basis.references&&basis.references.kind==="slots"){this.#restoredSelectionBasis=Object.freeze({references:basis.references,snapshots:basis.selectedSelections??Object.freeze([])});const snapshots=new Map(basis.selectedSelections?.map(selection=>[selection.id,selection])),restored=new Map;for(const[name,slot]of Object.entries(basis.references.slots)){if(slot.kind!=="many")continue;const source=image.references[name],snapshot=snapshots.get(slot.selection.id);if(!Array.isArray(source)||!snapshot||snapshot.owner!==invocation.context.id||snapshot.revision!==slot.selection.revision||snapshot.target.position!==slot.selection.target.position)throw new Error("Checkpoint selection publication basis is missing");let selection=restored.get(snapshot.id);selection||(selection=this.createSelection(snapshot.target.position,snapshot),restored.set(snapshot.id,selection)),this.#restoredSelections.set(source,selection)}}}work&&(invocation.children.trackFacts(),restore&&invocation.children.acknowledgeFacts(invocation.children.factRevision))}emit(event){const fact=Object.freeze({...event,activityId:this.activityId,contextId:this.invocation.context.id,owner:this.invocation.identity,recovering:this.invocation.recovering,sequence:++this.#sequence,occurredAt:new Date().toISOString()});this.#feedback?.publish(fact);const error=this.#observer?.publish(observer=>observer.observe(fact));if(error!==void 0)throw error}begin(){try{this.install()}catch(error){throw this.reportFailure("restore",error),error}}reportFailure(stage,error,childContextId){try{this.emit({kind:"failed",stage,error,...childContextId?{childContextId}:{}})}catch{}}install(){let owners=active.get(this.installation.store);if(owners||(owners=new Set,active.set(this.installation.store,owners)),owners.has(this.invocation.context.id))throw new Error("Checkpoint work is already active in this host");if(owners.add(this.invocation.context.id),this.#claimed=!0,!this.#restore){this.#ready=!0;return}const image=this.#restore.image;this.emit({kind:"checking",checkpointId:image.id,point:image.point});const current=this.installation.store.read(this.invocation.context.id);if(!current||current.delivery||current.revision!==this.#restore.revision||!checkpointDataEqual(current.image,image))throw new Error("Checkpoint head changed before continuation");if(this.#restoredSelectionBasis){const actual=checkpointHeadCommit(cloneCheckpointHead(current));if(!actual||!checkpointDataEqual(actual.references,this.#restoredSelectionBasis.references)||!checkpointDataEqual(actual.selectedSelections??[],this.#restoredSelectionBasis.snapshots))throw new Error("Checkpoint selection publication changed before continuation")}const point=this.work.points[image.point],decoded=decodeCheckpointFrame(image.frame,this.work,this.work.children,this.work.receptions);checkCheckpointReferences(image.frame,image.references,point.references),this.invocation.children.readFacts(()=>runCheckpointCheck(()=>point.check?.(image.frame,stableValue(point.state.decode(image.state)),image.references,decoded))),this.emit({kind:"installed",checkpointId:image.id,point:image.point,frame:image.frame}),this.#ready=!0}release(){this.#claimed&&active.get(this.installation.store)?.delete(this.invocation.context.id),this.#claimed=!1}selectionAccess(mutating){try{if(this.invocation.requireActive(),!this.#claimed||!this.#ready||this.#terminal||this.#commitUncertain||this.invocation.context.progress.phase!=="execute")throw new Error("Checkpoint selection is outside its executing invocation");if(mutating&&this.#saving)throw new Error("Checkpoint selection cannot change during a save")}catch(error){throw this.invocation.reject(error),error}}authenticateSelectionReference(reference,position){try{const fixed=cloneCheckpointValue(reference),relation=this.invocation.children.byContextId(fixed.contextId);if(!relation||relation.declarationPosition!==position||!relation.invocation.identity)throw new Error("Checkpoint selection reference is not a direct child of its declaration");return checkpointReferenceChild(fixed,[{identity:relation.invocation.identity,target:{position},round:relation.round,order:relation.order,input:null,state:{kind:"waiting"}}]),fixed}catch(error){throw this.invocation.reject(error),error}}createSelection(position,saved,reset=!1){const selection=new CheckpointSelectionState(position,mutating=>this.selectionAccess(mutating),(reference,target)=>this.authenticateSelectionReference(reference,target),error=>this.invocation.reject(error),saved,reset);return this.#selections.set(selection.handle,selection),selection}captureReferences(point,references,blocks,requireCut){if(!references||typeof references!="object"||Array.isArray(references)||![Object.prototype,null].includes(Object.getPrototypeOf(references)))throw new Error("Invalid checkpoint reference slots");const fields=Object.getOwnPropertyDescriptors(references);if(Reflect.ownKeys(fields).some(key=>typeof key!="string")||Object.values(fields).some(field=>!("value"in field)||!field.enumerable))throw new Error("Checkpoint reference slots require own data properties");const declarations=this.work.points[point].references??{},names=Object.keys(fields);if(names.length!==Object.keys(declarations).length||names.some(name=>!Object.hasOwn(declarations,name)))throw new Error("Checkpoint reference slots differ from the registered point");if(!names.some(name=>fields[name].value&&this.#selections.has(fields[name].value))){const block=createCheckpointValueBlock(randomUUID(),references);blocks.push(block);const logical2=block.value;return{logical:logical2,physical:Object.freeze({id:block.id,digest:block.digest}),changes:Object.freeze([]),check:__name((frame,lookup)=>checkCheckpointReferences(frame,logical2,declarations,lookup),"check"),acknowledge(){}}}const slots=Object.create(null),logical=Object.create(null),selected=new Map,arrays=[],singles=[];for(const name of names){const declaration=declarations[name],value=fields[name].value;let selection=value&&typeof value=="object"?this.#selections.get(value):void 0;if(selection||Array.isArray(value)){if(declaration.cardinality!=="many")throw new Error("Checkpoint reference cardinality differs from the registered point");if(!selection){const key=JSON.stringify([point,name]);selection=this.createSelection(declaration.position,this.#arraySelections.get(key),!0),selection.import(value),arrays.push([key,selection.pending().reference])}if(selection.position!==declaration.position)throw new Error("Checkpoint selection targets a different child declaration");let pending=selected.get(selection);pending||(pending=selection.pending(),selected.set(selection,pending)),slots[name]=Object.freeze({kind:"many",selection:pending.reference}),logical[name]=selection.view(requireCut)}else{if(declaration.cardinality!=="one")throw new Error("Checkpoint reference cardinality differs from the registered point");const reference=cloneCheckpointValue(value);singles.push({reference,position:declaration.position}),slots[name]=Object.freeze({kind:"one",reference}),logical[name]=reference}}const changes=Object.freeze(Array.from(selected.values()).flatMap(pending=>pending.change?[pending.change]:[]));return{logical:Object.freeze(logical),physical:Object.freeze({kind:"slots",slots:Object.freeze(slots)}),changes,check:__name((_frame,lookup)=>{const check=__name((reference,position)=>{const child=lookup(reference.contextId);if(!child||checkpointReferenceChild(reference,[child]).target.position!==position)throw new Error("Checkpoint reference targets a different child declaration")},"check");for(const single of singles)check(single.reference,single.position);for(const[selection,pending]of selected)for(const entry of pending.change?.append??[])check(entry.reference,selection.position)},"check"),acknowledge:__name(()=>{for(const pending of selected.values())pending.acknowledge();for(const[key,reference]of arrays)this.#arraySelections.set(key,reference)},"acknowledge")}}writer(){if(!this.work)return;const round=this.invocation.context.progress.round;return Object.freeze({select:__name((position,initial)=>{try{if(this.selectionAccess(!0),!Number.isSafeInteger(position)||position<0||!this.work.children?.[position])throw new Error("Checkpoint selection child declaration is not registered");if(initial!==void 0&&!Array.isArray(initial))throw new Error("Checkpoint selection initial references must be an array");const restored=initial&&this.#restoredSelections.get(initial);if(restored){if(restored.position!==position)throw new Error("Checkpoint selection targets a different child declaration");return restored.handle}const selection=this.createSelection(position);return initial&&selection.import(initial),selection.handle}catch(error){throw this.invocation.reject(error),error}},"select"),save:__name((point,state,references={})=>{let stage="capture",entered=!1;try{if(this.#saving)throw new Error("Checkpoint save cannot reenter the same invocation");this.#saving=!0,entered=!0;const revision=this.#revision;this.invocation.requireActive();const context=this.invocation.context;if(!this.#claimed||this.#terminal||this.#commitUncertain||context.progress.phase!=="execute"||context.progress.round!==round)throw new Error("Checkpoint writer is outside its executing round");const definition=this.work.points[point];if(!definition)throw new Error("Checkpoint point is not declared");return this.invocation.children.readFacts(()=>{let activeCut=!0;try{const factRevision=this.invocation.children.factRevision,blocks=[];this.#input??=publishCheckpointValue(context.input,this.work.input,blocks);const input=this.#input;this.#currentInput??=Object.is(input.source,context.currentInput)?input:publishCheckpointValue(context.currentInput,this.work.input,blocks);const currentInput=this.#currentInput;if(!Object.is(input.source,context.input)||!Object.is(currentInput.source,context.currentInput))throw new Error("Checkpoint fixed input changed");const changes=new Map;for(const relation of this.invocation.children.changedFacts()){const id=relation.invocation.context.id,publication=publishCheckpointChild(context,relation,this.#savedChildren.get(id),this.#published.get(id),blocks);checkpointChildBinding(publication.encoded,this.work.children),changes.set(id,publication)}const lookup=__name(id=>{if(!activeCut)throw new Error("Checkpoint frame query is outside its save");return changes.get(id)??this.#published.get(id)},"lookup"),all=__name(()=>{if(!activeCut)throw new Error("Checkpoint frame query is outside its save");const children=Array.from(this.#published,([id,child])=>changes.get(id)??child);for(const[id,child]of changes)this.#published.has(id)||children.push(child);return children},"all"),savedState=cloneCheckpointValue(definition.state.encode(state)),decodedState=stableValue(definition.state.decode(savedState)),stateBlock=createCheckpointValueBlock(randomUUID(),savedState);blocks.push(stateBlock);const selected=this.captureReferences(point,references,blocks,()=>{if(!activeCut)throw new Error("Checkpoint references query is outside its save")}),fixedReferences=selected.logical,frame=Object.freeze({owner:this.invocation.identity,phase:"execute",round,input:input.encoded,currentInput:currentInput.encoded,nextChildOrder:this.invocation.children.nextOrder,get children(){return Object.freeze(all().map(child=>child.encoded))}}),decoded=Object.freeze({owner:this.invocation.identity,phase:"execute",round,input:context.input,currentInput:context.currentInput,nextChildOrder:frame.nextChildOrder,child:__name(id=>lookup(id)?.decoded,"child"),get children(){return Object.freeze(all().map(child=>child.decoded))}});selected.check(frame,id=>lookup(id)?.encoded),runCheckpointCheck(()=>definition.check?.(frame,decodedState,fixedReferences,decoded));const commit=Object.freeze({kind:"commit",formatVersion:6,id:randomUUID(),contract:Object.freeze({key:this.work.key,version:this.work.version}),point,frame:Object.freeze({owner:this.invocation.identity,phase:"execute",round,input:input.reference,currentInput:currentInput.reference,nextChildOrder:frame.nextChildOrder}),state:Object.freeze({id:stateBlock.id,digest:stateBlock.digest}),references:selected.physical,...selected.changes.length?{selectionChanges:selected.changes}:{},values:Object.freeze(blocks),children:Object.freeze(Array.from(changes.values(),child=>child.record))});if(this.emit({kind:"captured",checkpointId:commit.id,point}),stage="save",this.invocation.requireActive(),!this.#claimed||this.#terminal||context.progress.phase!=="execute"||context.progress.round!==round||this.#revision!==revision||this.invocation.children.factRevision!==factRevision)throw new Error("Checkpoint save baseline changed before commit");this.#commitUncertain=!0;const receipt=checkCheckpointCommitReceipt(this.installation.store.save(commit,revision),commit,revision);this.#revision=receipt.revision,this.#checkpointId=receipt.checkpointId;for(const[id,child]of changes)this.#published.set(id,child);return this.invocation.children.acknowledgeFacts(factRevision),selected.acknowledge(),this.#commitUncertain=!1,this.emit({kind:"saved",checkpointId:commit.id,point}),receipt}finally{activeCut=!1}})}catch(error){this.invocation.reject(error);try{this.emit({kind:"failed",stage,error})}catch{}throw error}finally{entered&&(this.#saving=!1)}},"save")})}resume(){if(!this.#restore||!this.work)throw new Error("Invocation has no continuation");const image=this.#restore.image,point=this.work.points[image.point];return this.emit({kind:"continued",checkpointId:image.id,point:image.point}),point.execute(this.invocation.context,this.invocation,point.state.decode(image.state),image.references)}restoreChild(position,contextId,create){if(!this.#restore)throw new Error("Child continuation requires a restored parent");const saved=this.#savedChildren.get(contextId),resumed=this.#resumedChildren.get(contextId);if(resumed){if(this.invocation.children.get(resumed).declarationPosition!==position)throw new Error("Child continuation declaration position or ownership mismatch");return resumed}if(!saved)throw new Error("Child continuation basis is unavailable");if(saved.target.position!==position)throw new Error("Child continuation declaration position or ownership mismatch");const binding=checkpointChildBinding(saved,this.work?.children),restored=resolveCheckpointChild(saved,saved.state.kind==="waiting"?this.installation.store.read(contextId):void 0);if(restored.kind==="continuation"){const target=create(),relation=this.invocation.children.get(target);if(target.context.id!==contextId||relation.round!==saved.round||relation.order!==saved.order||relation.declarationPosition!==saved.target.position)throw new Error("Child continuation did not adopt the saved relationship");const published2=this.#published.get(contextId);return published2&&this.#published.set(contextId,restoredCheckpointChild(published2.encoded,published2.decoded,published2.record,relation)),this.#savedChildren.delete(contextId),this.#resumedChildren.set(contextId,target),this.emit({kind:"child-restored",child:saved,mode:"continuation"}),target}const child=restored.child,decoded=decodeCheckpointChild(child,binding,this.signal,this.work?.receptions);this.invocation.children.replaceSaved(contextId,decoded.target,decoded.state);const published=this.#published.get(contextId);return published&&this.#published.set(contextId,restoredCheckpointChild(published.encoded,published.decoded,published.record,this.invocation.children.get(decoded.target))),this.#savedChildren.set(contextId,child),this.#resumedChildren.set(contextId,decoded.target),this.emit({kind:"child-restored",child,mode:"delivery"}),decoded.target}finish(result){try{this.finalize(result)}catch(error){throw this.reportFailure("finish",error),error}}finalize(result){if(!this.#checkpointId||this.#terminal||this.#commitUncertain||!this.#claimed||!this.#ready)return;const revision=this.#revision,checkpointId=this.#checkpointId,delivery=cloneCheckpointDelivery(result.status==="succeeded"?{status:"succeeded",output:encodeCheckpointFact(result.output,this.work.output).encoded,progress:{round:this.invocation.context.progress.round,phase:this.invocation.context.progress.phase,currentInput:this.#currentInput.encoded}}:result);this.emit({kind:"finishing",status:delivery.status}),this.#commitUncertain=!0;const receipt=checkCheckpointFinishReceipt(this.installation.store.finish(this.invocation.context.id,revision,delivery),this.invocation.context.id,checkpointId,delivery,revision);this.#revision=receipt.revision,this.#commitUncertain=!1,this.#terminal=!0;try{this.emit({kind:"finished",status:delivery.status})}catch{}}}export{InvocationCheckpoint};
@@ -0,0 +1,32 @@
1
+ import type { MemoryEvent, TranscriptEvent } from '@weiliang0121/capix-protocol';
2
+ import type { InvocationFact, ResourceObservation } from '../observation/facts.js';
3
+ import { InvocationObservation } from '../observation/invocation.js';
4
+ type CheckpointActivityEvent = {
5
+ kind: 'activity';
6
+ fact: InvocationFact;
7
+ } | {
8
+ kind: 'resource';
9
+ fact: ResourceObservation;
10
+ } | {
11
+ kind: 'transcript';
12
+ fact: TranscriptEvent;
13
+ } | {
14
+ kind: 'memory';
15
+ fact: MemoryEvent;
16
+ };
17
+ export declare class CheckpointObservation extends InvocationObservation {
18
+ private readonly emit;
19
+ constructor(emit: (event: CheckpointActivityEvent) => void);
20
+ publish(fact: InvocationFact): unknown | undefined;
21
+ readonly resource: {
22
+ publish: (fact: ResourceObservation) => unknown | undefined;
23
+ };
24
+ readonly transcript: {
25
+ publish: (fact: TranscriptEvent) => unknown | undefined;
26
+ };
27
+ readonly memory: {
28
+ publish: (fact: MemoryEvent) => unknown | undefined;
29
+ };
30
+ private forward;
31
+ }
32
+ export {};
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{InvocationObservation}from"../observation/invocation.js";import{ObservationError}from"../observation/error.js";class CheckpointObservation extends InvocationObservation{static{__name(this,"CheckpointObservation")}emit;constructor(emit){super([],new Map),this.emit=emit}publish(fact){return this.forward({kind:"activity",fact})}resource={publish:__name(fact=>this.forward({kind:"resource",fact}),"publish")};transcript={publish:__name(fact=>this.forward({kind:"transcript",fact}),"publish")};memory={publish:__name(fact=>this.forward({kind:"memory",fact}),"publish")};forward(event){try{this.emit(event);return}catch(cause){return new ObservationError(cause)}}}export{CheckpointObservation};
@@ -0,0 +1,20 @@
1
+ import { type CheckpointCodec, type CheckpointValue } from '@weiliang0121/capix-contracts';
2
+ import { type CheckpointValueBlock, type CheckpointValueReference, type CheckpointChild, type CheckpointChildRecord } from '@weiliang0121/capix-checkpoint';
3
+ import type { InvocationContext } from '../context/context.js';
4
+ import type { InvocationRelation } from '../invocation/relation.js';
5
+ import type { DecodedCheckpointChild } from './facts.js';
6
+ export interface PublishedCheckpointValue {
7
+ readonly source: unknown;
8
+ readonly encoded: CheckpointValue;
9
+ readonly reference: CheckpointValueReference;
10
+ }
11
+ export interface PublishedCheckpointChild {
12
+ readonly values: Map<string, PublishedCheckpointValue>;
13
+ readonly encoded: CheckpointChild;
14
+ readonly decoded: DecodedCheckpointChild;
15
+ readonly record: CheckpointChildRecord;
16
+ }
17
+ export declare function encodeCheckpointFact(value: unknown, codec: CheckpointCodec<any> | undefined, check?: (value: unknown) => void): Pick<PublishedCheckpointValue, 'source' | 'encoded'>;
18
+ export declare function publishCheckpointValue(value: unknown, codec: CheckpointCodec<any> | undefined, blocks: CheckpointValueBlock[], check?: (value: unknown) => void): PublishedCheckpointValue;
19
+ export declare function publishCheckpointChild(context: InvocationContext<any, any>, relation: InvocationRelation, saved: CheckpointChild | undefined, previous: PublishedCheckpointChild | undefined, blocks: CheckpointValueBlock[]): PublishedCheckpointChild;
20
+ export declare function restoredCheckpointChild(encoded: CheckpointChild, decoded: DecodedCheckpointChild, record: CheckpointChildRecord, relation: InvocationRelation): PublishedCheckpointChild;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{randomUUID}from"node:crypto";import{stableValue}from"@weiliang0121/capix-contracts";import{cloneCheckpointValue,createCheckpointValueBlock}from"@weiliang0121/capix-checkpoint";import{captureCheckpointChild}from"./children.js";import{decodeCheckpointData,encodeCheckpointData,runCheckpointCheck,checkpointDataEqual}from"./data.js";function encodeCheckpointFact(value,codec,check){const source=stableValue(value),encoded=codec?cloneCheckpointValue(codec.encode(source)):encodeCheckpointData(source),decoded=codec?stableValue(codec.decode(encoded)):decodeCheckpointData(encoded);if(!checkpointDataEqual(source,decoded))throw new Error("Checkpoint codec must preserve the established value");return check&&runCheckpointCheck(()=>check(decoded)),Object.freeze({source,encoded})}__name(encodeCheckpointFact,"encodeCheckpointFact");function publishCheckpointValue(value,codec,blocks,check){const{source,encoded}=encodeCheckpointFact(value,codec,check),block=createCheckpointValueBlock(randomUUID(),encoded);return blocks.push(block),Object.freeze({source,encoded,reference:Object.freeze({id:block.id,digest:block.digest})})}__name(publishCheckpointValue,"publishCheckpointValue");function publishCheckpointChild(context,relation,saved,previous,blocks){const values=new Map(previous?.values),encoded=freezeCheckpointChildMetadata(captureCheckpointChild(context,relation,saved,__name((role,source,codec)=>{const established=values.get(role);if(established){if(!Object.is(established.source,source))throw new Error(`Established child ${role} changed`);return established.encoded}const input=values.get("input");if(role==="currentInput"&&input&&Object.is(input.source,source))return values.set(role,input),input.encoded;const reception2=relation.reception,value2=publishCheckpointValue(source,codec,blocks,role==="reception"&&reception2.status!=="pending"?reception2.contract?.check:void 0);return values.set(role,value2),value2.encoded},"encode"))),value=__name(role=>{const found=values.get(role);if(!found)throw new Error(`Checkpoint child ${role} has no publication`);return found},"value"),state=encoded.state,reception=state.kind==="waiting"?void 0:state.reception,decodedReception=reception&&(reception.kind==="accepted"||reception.kind==="handled")&&Object.hasOwn(reception,"output")?Object.freeze({...reception,output:value("reception").source}):reception,recordReception=reception&&(reception.kind==="accepted"||reception.kind==="handled")&&Object.hasOwn(reception,"output")?Object.freeze({...reception,output:value("reception").reference}):reception?.kind==="failed"?Object.freeze({...reception,error:value("receptionFailure").reference}):reception,decodedState=state.kind==="waiting"?state:Object.freeze({...state,...state.kind==="returned"?{output:value("output").source}:{},progress:Object.freeze({...state.progress,currentInput:value("currentInput").source}),...decodedReception?{reception:decodedReception}:{}}),recordState=state.kind==="waiting"?state:Object.freeze({...state,...state.kind==="returned"?{output:value("output").reference}:{error:value("failure").reference},progress:Object.freeze({...state.progress,currentInput:value("currentInput").reference}),...recordReception?{reception:recordReception}:{}});return Object.freeze({values,encoded:Object.freeze(encoded),decoded:Object.freeze({...encoded,input:value("input").source,state:decodedState}),record:Object.freeze({...encoded,input:value("input").reference,state:recordState})})}__name(publishCheckpointChild,"publishCheckpointChild");function restoredCheckpointChild(encoded,decoded,record,relation){const values=new Map,add=__name((role,source,wire,reference)=>values.set(role,Object.freeze({source,encoded:wire,reference})),"add");if(add("input",relation.invocation.context.input,encoded.input,record.input),encoded.state.kind!=="waiting"&&decoded.state.kind!=="waiting"&&record.state.kind!=="waiting"){add("currentInput",relation.invocation.context.currentInput,encoded.state.progress.currentInput,record.state.progress.currentInput),encoded.state.kind==="returned"&&decoded.state.kind==="returned"&&record.state.kind==="returned"&&add("output",relation.returned?.status==="succeeded"?relation.returned.output:decoded.state.output,encoded.state.output,record.state.output),encoded.state.kind==="failed"&&record.state.kind==="failed"&&add("failure",relation.returned?.status==="failed"?relation.returned.diagnostic:void 0,encoded.state.error,record.state.error);const a=encoded.state.reception,b=decoded.state.reception,c=record.state.reception;a&&b&&c&&(a.kind==="accepted"||a.kind==="handled")&&(b.kind==="accepted"||b.kind==="handled")&&(c.kind==="accepted"||c.kind==="handled")&&Object.hasOwn(a,"output")&&add("reception",relation.reception.status==="accepted"||relation.reception.status==="handled"?relation.reception.output:b.output,a.output,c.output)}return Object.freeze({values,encoded,decoded,record})}__name(restoredCheckpointChild,"restoredCheckpointChild");function freezeCheckpointChildMetadata(child){const base={...child,identity:Object.freeze({...child.identity}),target:Object.freeze({...child.target}),...child.contract?{contract:Object.freeze({...child.contract})}:{}},state=child.state;if(state.kind==="waiting")return Object.freeze({...base,state:Object.freeze({...state})});const reception=state.reception,fixedReception=reception?Object.freeze({...reception,..."contract"in reception&&reception.contract?{contract:Object.freeze({...reception.contract})}:{},..."failure"in reception?{failure:Object.freeze({...reception.failure})}:{}}):void 0;return Object.freeze({...base,state:Object.freeze({...state,progress:Object.freeze({...state.progress}),...state.kind==="failed"?{failure:Object.freeze({...state.failure})}:{},...fixedReception?{reception:fixedReception}:{}})})}__name(freezeCheckpointChildMetadata,"freezeCheckpointChildMetadata");export{encodeCheckpointFact,publishCheckpointChild,publishCheckpointValue,restoredCheckpointChild};
@@ -0,0 +1,4 @@
1
+ import type { CheckpointInstallation, CheckpointRestoration } from './contract.js';
2
+ import type { CheckpointContract } from '@weiliang0121/capix-contracts';
3
+ import type { InvocationIdentity } from '@weiliang0121/capix-contracts';
4
+ export declare function prepareCheckpointRestoration<Value = never>(installation: CheckpointInstallation | undefined, contract: CheckpointContract | undefined, contextId: string, owner: Omit<InvocationIdentity, 'contextId'>, construct?: (restoration: CheckpointRestoration) => Value): Value | CheckpointRestoration;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{randomUUID}from"node:crypto";import{cloneCheckpointHead}from"@weiliang0121/capix-checkpoint";import{ObserverSession}from"../observation/session.js";import{ProgressChannel}from"@weiliang0121/capix-changes";function prepareCheckpointRestoration(installation,contract,contextId,owner,construct){try{const restoration=readCheckpoint(installation,contract,contextId,owner);return construct?construct(restoration):restoration}catch(error){const observation=installation?.observation,feedback=installation?.feedback;if(observation||feedback){const fact=Object.freeze({kind:"failed",stage:"restore",contextId,owner:Object.freeze({...owner,contextId}),recovering:!0,activityId:randomUUID(),sequence:1,occurredAt:new Date().toISOString(),error});feedback&&new ProgressChannel(feedback).publish(fact);const fault=(observation?new ObserverSession({observe:__name(fact2=>observation.observe(fact2),"observe"),available:__name(()=>!0,"available")},observation.failure??"isolate"):void 0)?.publish(observer=>observer.observe(fact));if(fault!==void 0)throw new AggregateError([error,fault],"Checkpoint construction and its observation both failed",{cause:error})}throw error}}__name(prepareCheckpointRestoration,"prepareCheckpointRestoration");function readCheckpoint(installation,contract,contextId,owner){if(!installation)throw new Error("Checkpoint persistence is not installed");if(!contract)throw new Error("This declaration does not support checkpoints");const saved=installation.store.read(contextId);if(!saved)throw new Error("Checkpoint work is unavailable");const head=cloneCheckpointHead(saved),image=head.image;if(image.formatVersion!==6)throw new Error("Checkpoint uses the retired live-reference format; start a new invocation");if(image.contract.key!==contract.key||image.contract.version!==contract.version)throw new Error("Checkpoint declaration is incompatible");if(image.frame.owner.contextId!==contextId||image.frame.owner.kind!==owner.kind||image.frame.owner.parentContextId!==owner.parentContextId)throw new Error("Checkpoint work belongs to another scope");if(head.delivery)throw new Error("A terminal checkpoint work cannot execute again");if(image.frame.round!==1||image.frame.continuation!==void 0)throw new Error("Checkpoint belongs to the retired multi-round execution model");return Object.freeze({head})}__name(readCheckpoint,"readCheckpoint");export{prepareCheckpointRestoration};
@@ -0,0 +1,22 @@
1
+ import type { CheckpointReference, CheckpointSelectionChange, CheckpointSelectionReference, CheckpointSelectionSnapshot } from '@weiliang0121/capix-checkpoint';
2
+ import type { InvocationCheckpointSelection } from './contract.js';
3
+ export declare class CheckpointSelectionState {
4
+ #private;
5
+ private readonly access;
6
+ private readonly authenticate;
7
+ private readonly reject;
8
+ readonly handle: InvocationCheckpointSelection;
9
+ readonly id: string;
10
+ readonly position: number;
11
+ constructor(position: number, access: (mutating: boolean) => void, authenticate: (reference: CheckpointReference, position: number) => CheckpointReference, reject: (error: unknown) => void, saved?: CheckpointSelectionSnapshot | CheckpointSelectionReference, reset?: boolean);
12
+ import(references: readonly CheckpointReference[]): void;
13
+ private append;
14
+ private appendEntry;
15
+ private entryAt;
16
+ pending(): Readonly<{
17
+ reference: CheckpointSelectionReference;
18
+ change?: CheckpointSelectionChange;
19
+ acknowledge(): void;
20
+ }>;
21
+ view(requireCut: () => void): readonly CheckpointReference[];
22
+ }
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{randomUUID}from"node:crypto";class CheckpointSelectionState{static{__name(this,"CheckpointSelectionState")}access;authenticate;reject;handle;id;position;#revision;#nextOrder;#length=0;#first;#last;#cursor;#tokens=new WeakMap;#appended=new Map;#removed=new Map;#reset;constructor(position,access,authenticate,reject,saved,reset=!1){if(this.access=access,this.authenticate=authenticate,this.reject=reject,this.position=position,this.id=saved?.id??randomUUID(),this.#revision=saved?.revision??0,this.#nextOrder=saved&&"nextOrder"in saved?saved.nextOrder:0,this.#reset=reset,saved&&"occurrences"in saved&&!reset)for(const occurrence of saved.occurrences)this.appendEntry(occurrence.id,occurrence.reference).order=occurrence.order;const self=this;this.handle=Object.freeze({get length(){return access(!1),self.#length},at(index){return access(!1),self.entryAt(index)?.reference},occurrenceAt(index){return access(!1),self.entryAt(index)?.token},add(reference){access(!0);const fixed=authenticate(reference,position);return self.append(fixed)},remove(token){access(!0);const entry=token&&typeof token=="object"?self.#tokens.get(token):void 0;if(!entry||!entry.present){const error=new Error("Checkpoint occurrence does not belong to this active selection");throw self.reject(error),error}self.#appended.delete(entry.id)||self.#removed.set(entry.id,entry),entry.before?entry.before.after=entry.after:self.#first=entry.after,entry.after?entry.after.before=entry.before:self.#last=entry.before,entry.present=!1,entry.before=void 0,entry.after=void 0,self.#length--,self.#cursor=void 0},*[Symbol.iterator](){access(!1);for(let entry=self.#first;entry;entry=entry.after)access(!1),yield entry.reference}})}import(references){for(const reference of references)this.append(this.authenticate(reference,this.position))}append(reference){const entry=this.appendEntry(randomUUID(),reference);return this.#appended.set(entry.id,entry),entry.token}appendEntry(id,reference){const token=Object.freeze({}),entry={id,reference,token,present:!0,before:this.#last};return this.#last?this.#last.after=entry:this.#first=entry,this.#last=entry,this.#tokens.set(token,entry),this.#length++,entry}entryAt(index){if(index=Number(index),Number.isNaN(index)&&(index=0),index=Math.trunc(index),index<0&&(index+=this.#length),!Number.isSafeInteger(index)||index<0||index>=this.#length)return;let current=index<=this.#length-1-index?{index:0,entry:this.#first}:{index:this.#length-1,entry:this.#last};this.#cursor&&Math.abs(this.#cursor.index-index)<Math.abs(current.index-index)&&(current=this.#cursor);let entry=current.entry,at=current.index;for(;at<index;)entry=entry.after,at++;for(;at>index;)entry=entry.before,at--;return this.#cursor={index,entry},entry}pending(){const changed=this.#revision===0||this.#reset||this.#appended.size!==0||this.#removed.size!==0,revision=this.#revision+(changed?1:0),target=Object.freeze({position:this.position}),reference=Object.freeze({id:this.id,revision,target}),appended=[...this.#appended.values()],change=changed?Object.freeze({id:this.id,target,expectedRevision:this.#revision,...this.#reset?{reset:!0}:{},append:Object.freeze(appended.map(entry=>Object.freeze({id:entry.id,reference:entry.reference}))),remove:Object.freeze(Array.from(this.#removed.values(),entry=>Object.freeze({id:entry.id,order:entry.order,reference:entry.reference})))}):void 0;return Object.freeze({reference,...change?{change}:{},acknowledge:__name(()=>{this.#revision=revision,this.#reset=!1;for(const entry of appended)entry.order=this.#nextOrder++;this.#appended.clear(),this.#removed.clear()},"acknowledge")})}view(requireCut){const target=[],immutable=__name(()=>{throw new TypeError("Checkpoint references are readonly")},"immutable"),index=__name(key=>typeof key=="string"&&/^(0|[1-9]\d*)$/.test(key)?Number(key):void 0,"index");return new Proxy(target,{get:__name((_target,key,receiver)=>{requireCut();const at=index(key);return at!==void 0?this.entryAt(at)?.reference:key==="length"?this.#length:key===Symbol.iterator?function*(){for(let entry=this.#first;entry;entry=entry.after)requireCut(),yield entry.reference}.bind(this):Reflect.get(target,key,receiver)},"get"),has:__name((_target,key)=>{requireCut();const at=index(key);return at===void 0?Reflect.has(target,key):at<this.#length},"has"),ownKeys:__name(()=>(requireCut(),[...Array.from({length:this.#length},(_,i)=>String(i)),"length"]),"ownKeys"),getOwnPropertyDescriptor:__name((_target,key)=>{if(requireCut(),key==="length")return{...Reflect.getOwnPropertyDescriptor(target,"length"),value:this.#length};const at=index(key);if(at===void 0)return Reflect.getOwnPropertyDescriptor(target,key);const entry=this.entryAt(at);return entry?{value:entry.reference,enumerable:!0,configurable:!0,writable:!1}:void 0},"getOwnPropertyDescriptor"),set:immutable,defineProperty:immutable,deleteProperty:immutable,setPrototypeOf:immutable,preventExtensions:immutable})}}export{CheckpointSelectionState};
@@ -0,0 +1,4 @@
1
+ import type { InvocationTarget } from '../invocation/relation.js';
2
+ import type { CheckpointChild } from '@weiliang0121/capix-checkpoint';
3
+ import type { CheckpointBinding } from './work.js';
4
+ export declare function checkpointTarget(child: CheckpointChild, binding?: CheckpointBinding, signal?: AbortSignal): InvocationTarget;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{stableValue}from"@weiliang0121/capix-contracts";import{decodeCheckpointData}from"./data.js";import{decodeCheckpointDiagnostic}from"./facts.js";import{InvocationContext}from"../context/context.js";import{invocationContextView}from"../context/view.js";function checkpointTarget(child,binding,signal=new AbortController().signal){const input=binding?stableValue(binding.input.decode(child.input)):decodeCheckpointData(child.input),context=new InvocationContext(input),output=child.state.kind==="returned"?binding?stableValue(binding.output.decode(child.state.output)):decodeCheckpointData(child.state.output):void 0,failure=child.state.kind==="failed"?Object.freeze({...child.state.failure,error:child.state.error}):void 0;if(child.state.kind==="returned"){const progress=child.state.progress;context.installDelivery({id:child.identity.contextId,round:progress.round,currentInput:binding?stableValue(binding.input.decode(progress.currentInput)):decodeCheckpointData(progress.currentInput),phase:progress.phase},output)}else if(child.state.kind==="failed"){const progress=child.state.progress,diagnostic=decodeCheckpointDiagnostic(child.state.error);context.installFailure({id:child.identity.contextId,round:progress.round,currentInput:binding?stableValue(binding.input.decode(progress.currentInput)):decodeCheckpointData(progress.currentInput),phase:progress.phase},failure,diagnostic)}else context.installIdentity(child.identity.contextId);const run=__name(async()=>{if(child.state.kind==="failed")throw new Error("Historical failed child cannot execute or deliver again");if(child.state.kind!=="returned")throw new Error("Saved child has no final delivery; explicitly resume its declared checkpoint");if(child.state.reception.kind==="failed")throw new Error("Historical failed reception cannot execute or deliver again");return output},"run"),view=Object.freeze({context:Object.freeze({...invocationContextView(context),kind:child.identity.kind,signal}),origin:Object.freeze({contextId:context.id}),sequence:0,...failure?{failure}:{},children:Object.freeze({get:__name(()=>{throw new Error("Saved child descendants require their own checkpoint")},"get"),values:__name(()=>{throw new Error("Saved child descendants require their own checkpoint")},"values")})});return Object.freeze({context,run,view,callView:Object.freeze({...view,run}),identity:child.identity,checkpointBinding:binding})}__name(checkpointTarget,"checkpointTarget");export{checkpointTarget};
@@ -0,0 +1,27 @@
1
+ import type { Invocation } from '../invocation/invocation.js';
2
+ import type { InvocationContext } from '../context/context.js';
3
+ import type { CheckpointReferences, InvocationCheckpointFrame } from '@weiliang0121/capix-checkpoint';
4
+ import type { CheckpointCodec, CheckpointContract, CallableKind, Stable } from '@weiliang0121/capix-contracts';
5
+ import type { DecodedCheckpointFrame } from './facts.js';
6
+ import type { InvocationReceptionBinding } from '../invocation/reception.js';
7
+ export interface CheckpointChildBinding {
8
+ readonly kind: CallableKind;
9
+ readonly binding?: CheckpointBinding;
10
+ }
11
+ export interface CheckpointReferenceSlot {
12
+ readonly cardinality: 'one' | 'many';
13
+ readonly position: number;
14
+ }
15
+ export interface InvocationCheckpointWork<Input, Output, Context extends InvocationContext<Input, Output>> extends CheckpointContract {
16
+ readonly input: CheckpointCodec<Input>;
17
+ readonly output: CheckpointCodec<Output>;
18
+ readonly children?: readonly CheckpointChildBinding[];
19
+ readonly receptions?: readonly InvocationReceptionBinding[];
20
+ readonly points: Readonly<Record<string, {
21
+ readonly state: CheckpointCodec<any>;
22
+ readonly references?: Readonly<Record<string, CheckpointReferenceSlot>>;
23
+ check?(frame: InvocationCheckpointFrame, state: any, references: CheckpointReferences, decoded: DecodedCheckpointFrame): void;
24
+ execute(context: Context, invocation: Invocation<Input, Output, Context>, state: any, references: CheckpointReferences): Output | Stable<Output> | Promise<Output | Stable<Output>>;
25
+ }>>;
26
+ }
27
+ export type CheckpointBinding = Pick<InvocationCheckpointWork<any, any, any>, 'key' | 'version' | 'input' | 'output'>;
@@ -0,0 +1 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
@@ -0,0 +1,4 @@
1
+ export declare class Clock {
2
+ now(): string;
3
+ tick(): number;
4
+ }
package/dist/clock.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{performance}from"node:perf_hooks";class Clock{static{__name(this,"Clock")}now(){return new Date().toISOString()}tick(){return performance.now()}}export{Clock};
@@ -0,0 +1,12 @@
1
+ import { InvocationResources } from '../invocation/resource-access.js';
2
+ import type { CallableKind, Stable } from '@weiliang0121/capix-contracts';
3
+ import { InvocationContext, type InvocationControls } from './context.js';
4
+ export declare class CallableContext<Input = unknown, Output = unknown, Resources extends object = object> extends InvocationContext<Input, Output> {
5
+ #private;
6
+ readonly kind: CallableKind;
7
+ readonly resources: InvocationResources<Resources>;
8
+ readonly signal: AbortSignal;
9
+ constructor(input: Input | Stable<Input>, kind: CallableKind, controls?: InvocationControls, resources?: InvocationResources<Resources>, owner?: object);
10
+ belongsTo(owner: object): boolean;
11
+ requireActive(): void;
12
+ }
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{InvocationResources}from"../invocation/resource-access.js";import{InvocationContext}from"./context.js";import"@weiliang0121/capix-resources";import{requireNotCancelled}from"../invocation/cancellation.js";class CallableContext extends InvocationContext{static{__name(this,"CallableContext")}kind;resources;signal;#owner;constructor(input,kind,controls={},resources=new InvocationResources({}),owner){super(input),this.kind=kind,this.resources=resources,this.signal=controls.signal??new AbortController().signal,this.#owner=owner,Object.freeze(this)}belongsTo(owner){return this.#owner===void 0||this.#owner===owner}requireActive(){this.requireRunning(),requireNotCancelled(this.signal)}}export{CallableContext};