@weiliang0121/capix-runtime 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,8 @@ npm install @weiliang0121/capix-runtime
16
16
 
17
17
  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.
18
18
 
19
+ Runtime composes Invocation progress through `invocation/events` and recording through the public `records/data` contracts. It does not depend on transport or service protocols. Optional content recording uses the domain adapters owned by `records`; it adds no entity lifecycle or direct production dependency on Transcript or Memory.
20
+
19
21
  ## License
20
22
 
21
- MIT. Copyright (c) 2026 wei.liang. See [LICENSE](./LICENSE).
23
+ MIT. Copyright (c) 2026 wei.liang. See [LICENSE](LICENSE).
@@ -1,5 +1,5 @@
1
1
  import type { CheckpointInstallation, Clock } from '@weiliang0121/capix-invocation';
2
- import type { InvocationEvent } from '@weiliang0121/capix-protocol';
2
+ import type { InvocationEvent } from '@weiliang0121/capix-invocation/events';
3
3
  import type { ChangeCapture } from '@weiliang0121/capix-changes';
4
4
  import type { ObservationInstallation } from '../binding/observation.js';
5
5
  export interface InvocationCapabilities {
@@ -1,9 +1,10 @@
1
- import type { CheckpointInstallation, CheckpointFact, InvocationFact, ResourceObservation, BusinessObservation } from '@weiliang0121/capix-invocation';
1
+ import type { CheckpointInstallation, CheckpointFact, InvocationFact, ResourceObservation, ResourceFact, BusinessObservation } from '@weiliang0121/capix-invocation';
2
2
  import { type ProgressReceiver } from '@weiliang0121/capix-changes';
3
3
  import type { ObservationInstallation } from '../binding/observation.js';
4
4
  export interface CallableFeedback {
5
5
  readonly invocation?: ProgressReceiver<InvocationFact>;
6
6
  readonly resource?: ProgressReceiver<ResourceObservation>;
7
+ readonly fact?: ProgressReceiver<ResourceFact>;
7
8
  readonly business?: ProgressReceiver<BusinessObservation>;
8
9
  readonly checkpoint?: ProgressReceiver<CheckpointFact>;
9
10
  }
@@ -1,2 +1,2 @@
1
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{ProgressChannel}from"@weiliang0121/capix-changes";function bindCallableFeedback(feedback){const invocation=fixedReceiver(feedback.invocation),resource=fixedReceiver(feedback.resource),business=fixedReceiver(feedback.business),checkpoint=fixedReceiver(feedback.checkpoint);return Object.freeze({checkpoint,observation:Object.freeze({bindInvocation:__name(()=>{const calls=invocation?new ProgressChannel(invocation):void 0,resources=resource?new ProgressChannel(resource):void 0,annotations=business?new ProgressChannel(business):void 0;return{observe:__name(fact=>calls?.publish(fact),"observe"),resource:__name(fact=>resources?.publish(fact),"resource"),business:__name(fact=>annotations?.publish(fact),"business")}},"bindInvocation")})})}__name(bindCallableFeedback,"bindCallableFeedback");function checkpointFeedback(installation,feedback){if(!installation||!feedback)return installation;const additional=new ProgressChannel(feedback),installed=installation.feedback?new ProgressChannel(installation.feedback):void 0;return Object.freeze({...installation,feedback:Object.freeze({receive(fact){additional.publish(fact),installed?.publish(fact)}})})}__name(checkpointFeedback,"checkpointFeedback");function fixedReceiver(receiver){return receiver?Object.freeze({receive:receiver.receive.bind(receiver),failed:receiver.failed?.bind(receiver)}):void 0}__name(fixedReceiver,"fixedReceiver");export{bindCallableFeedback,checkpointFeedback};
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{ProgressChannel}from"@weiliang0121/capix-changes";function bindCallableFeedback(feedback){const invocation=fixedReceiver(feedback.invocation),resource=fixedReceiver(feedback.resource),fact=fixedReceiver(feedback.fact),business=fixedReceiver(feedback.business),checkpoint=fixedReceiver(feedback.checkpoint);return Object.freeze({checkpoint,observation:Object.freeze({bindInvocation:__name(()=>{const calls=invocation?new ProgressChannel(invocation):void 0,resources=resource?new ProgressChannel(resource):void 0,facts=fact?new ProgressChannel(fact):void 0,annotations=business?new ProgressChannel(business):void 0;return{observe:__name(fact2=>calls?.publish(fact2),"observe"),resource:__name(fact2=>resources?.publish(fact2),"resource"),fact:__name(fact2=>facts?.publish(fact2),"fact"),business:__name(fact2=>annotations?.publish(fact2),"business")}},"bindInvocation")})})}__name(bindCallableFeedback,"bindCallableFeedback");function checkpointFeedback(installation,feedback){if(!installation||!feedback)return installation;const additional=new ProgressChannel(feedback),installed=installation.feedback?new ProgressChannel(installation.feedback):void 0;return Object.freeze({...installation,feedback:Object.freeze({receive(fact){additional.publish(fact),installed?.publish(fact)}})})}__name(checkpointFeedback,"checkpointFeedback");function fixedReceiver(receiver){return receiver?Object.freeze({receive:receiver.receive.bind(receiver),failed:receiver.failed?.bind(receiver)}):void 0}__name(fixedReceiver,"fixedReceiver");export{bindCallableFeedback,checkpointFeedback};
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { invocationContextView, invocationView, childInvocationView, Clock, Invo
14
14
  export type { InvocationContextView, CallableContextView, ContextViewOf, ContextViewResources, ContextFactsOf, InvocationRelationView, InvocationView, ChildInvocationView, InvocationViewSource, InvocationProgress, InvocationResult, InvocationFailure, InvocationPhase } from '@weiliang0121/capix-invocation';
15
15
  export type { InvocationIdentity } from '@weiliang0121/capix-contracts';
16
16
  export { InvocationChangeEmitter, InvocationObservation, ObservationError } from '@weiliang0121/capix-invocation';
17
- export type { InvocationRelationIdentity, InvocationDescription, InvocationRelationChange, InvocationChange, InvocationFact, ResourceObservation, BusinessEvent, BusinessObservation, InvocationObserver } from '@weiliang0121/capix-invocation';
17
+ export type { InvocationRelationIdentity, InvocationDescription, InvocationRelationChange, InvocationChange, InvocationFact, ResourceObservation, ResourceFact, BusinessEvent, BusinessObservation, InvocationObserver } from '@weiliang0121/capix-invocation';
18
18
  export type { EventConsumer } from '@weiliang0121/capix-changes';
19
19
  export type { DriverFact, DriverObserver } from './observation/driver.js';
20
20
  export * from './construction.js';
@@ -1,4 +1,4 @@
1
- import type { InvocationRelationIdentity } from '@weiliang0121/capix-protocol';
1
+ import type { InvocationRelationIdentity } from '@weiliang0121/capix-contracts';
2
2
  import type { InvocationFact } from '@weiliang0121/capix-invocation';
3
3
  import { ResourceOffer } from '@weiliang0121/capix-resources';
4
4
  import type { InvocationRecording } from './invocation.js';
@@ -1,16 +1,16 @@
1
- import type { MemoryEvent, TranscriptEvent } from '@weiliang0121/capix-protocol';
2
1
  import type { InvocationObservationSetup, ObservationInstallation } from '../../binding/observation.js';
3
2
  import type { ObservationDeclarationScope } from '../../definition/observation.js';
4
3
  import { type InvocationObserver } from '@weiliang0121/capix-invocation';
5
4
  import type { EventConsumer } from '@weiliang0121/capix-changes';
6
- import type { Recorder, RecordingRootRecord } from '@weiliang0121/capix-records';
5
+ import { memoryRecord, transcriptRecord, type Recorder, type RecordingRootRecord, type RecordChangeSource } from '@weiliang0121/capix-records';
7
6
  import { type RecordWriter } from '@weiliang0121/capix-records/construction';
8
- import { type ResourceBinding } from '@weiliang0121/capix-resources';
7
+ import { type ResourceBinding, type ResourceFact } from '@weiliang0121/capix-resources';
9
8
  import { type InvocationRecordDescription } from './declaration.js';
10
9
  import type { CallableInput, CallableOutput } from '@weiliang0121/capix-contracts';
11
10
  import { InvocationRecording } from './invocation.js';
12
11
  export interface RecordingOptions {
13
12
  readonly failure?: 'isolate' | 'propagate';
13
+ readonly fact?: (fact: ResourceFact, source: RecordChangeSource, writer: RecordWriter) => void;
14
14
  readonly invalidate?: (error: unknown) => void;
15
15
  }
16
16
  export declare class RecordingInstallation implements ObservationInstallation {
@@ -24,13 +24,14 @@ export declare class RecordingInstallation implements ObservationInstallation {
24
24
  readonly provides: Readonly<{
25
25
  record: import("@weiliang0121/capix-resources").ResourceRequest<import("./declaration.js").InvocationRecordWriter>;
26
26
  }>;
27
- readonly transcript: EventConsumer<TranscriptEvent>;
28
- readonly memory: EventConsumer<MemoryEvent>;
27
+ readonly transcript: EventConsumer<Parameters<typeof transcriptRecord>[0]>;
28
+ readonly memory: EventConsumer<Parameters<typeof memoryRecord>[0]>;
29
29
  readonly failure: 'isolate' | 'propagate';
30
30
  constructor(recorder: Recorder, options?: RecordingOptions);
31
31
  describe<Structure extends ObservationDeclarationScope>(structure: Structure, description: InvocationRecordDescription<CallableInput<Structure>, CallableOutput<Structure>>): this;
32
32
  declarations(structure: ObservationDeclarationScope): import("../../definition/observation.js").ObservationDeclaration<import("@weiliang0121/capix-invocation").InvocationFact>[];
33
33
  bindInvocation(setup: InvocationObservationSetup, parent?: InvocationObserver): InvocationRecording;
34
+ recordFact(fact: ResourceFact, source: RecordChangeSource, writer: RecordWriter): void;
34
35
  invalidate(error: unknown): void;
35
36
  private consumer;
36
37
  }
@@ -1,2 +1,2 @@
1
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{ObservationError}from"@weiliang0121/capix-invocation";import{RecordWriterResource}from"@weiliang0121/capix-records/construction";import{Resource,Resources}from"@weiliang0121/capix-resources";import{InvocationRecordAccess,invocationRecording}from"./declaration.js";import{assertStructureConfigurable}from"@weiliang0121/capix-structure/construction";import{InvocationRecording}from"./invocation.js";import{memoryRecord,transcriptRecord}from"./mapping.js";class RecordingInstallation{static{__name(this,"RecordingInstallation")}recorder;options;#descriptions=new WeakMap;root;records;provides=Object.freeze({record:InvocationRecordAccess.request()});transcript=this.consumer((event,writer)=>writer.add(transcriptRecord(event)));memory=this.consumer((event,writer)=>writer.add(memoryRecord(event)));failure;constructor(recorder,options={}){this.recorder=recorder,this.options=options,this.records=new Resources().register(new Resource(recorder),RecordWriterResource).bind({record:RecordWriterResource.request()});const access=this.records.open();try{this.root=access.endpoints.record.root()}finally{access.close()}this.failure=options.failure??"isolate"}describe(structure,description){if(assertStructureConfigurable(structure),this.#descriptions.has(structure))throw new Error("Recording description is already registered for this structure");return this.#descriptions.set(structure,description),this}declarations(structure){return[invocationRecording(this.#descriptions.get(structure))]}bindInvocation(setup,parent){if(parent&&!(parent instanceof InvocationRecording))throw new Error("Recording parent belongs to another observation capability");return new InvocationRecording(this,setup,parent)}invalidate(error){this.options.invalidate?.(error)}consumer(work){let active=!0;return{publish:__name(event=>{if(active)try{const access=this.records.open();try{work(event,access.endpoints.record)}finally{access.close()}return}catch(cause){active=!1;const error=new ObservationError(cause);return this.invalidate(error),this.failure==="propagate"?error:void 0}},"publish")}}}function bindRecording(recorder,options={}){return new RecordingInstallation(recorder,options)}__name(bindRecording,"bindRecording");export{RecordingInstallation,bindRecording};
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{ObservationError}from"@weiliang0121/capix-invocation";import{memoryRecord,transcriptRecord,recordContentFact}from"@weiliang0121/capix-records";import{RecordWriterResource}from"@weiliang0121/capix-records/construction";import{Resource,Resources}from"@weiliang0121/capix-resources";import{InvocationRecordAccess,invocationRecording}from"./declaration.js";import{assertStructureConfigurable}from"@weiliang0121/capix-structure/construction";import{InvocationRecording}from"./invocation.js";class RecordingInstallation{static{__name(this,"RecordingInstallation")}recorder;options;#fact;#descriptions=new WeakMap;root;records;provides=Object.freeze({record:InvocationRecordAccess.request()});transcript=this.consumer((event,writer)=>writer.add(transcriptRecord(event)));memory=this.consumer((event,writer)=>writer.add(memoryRecord(event)));failure;constructor(recorder,options={}){this.recorder=recorder,this.options=options,this.#fact=options.fact?.bind(options)??recordContentFact,this.records=new Resources().register(new Resource(recorder),RecordWriterResource).bind({record:RecordWriterResource.request()});const access=this.records.open();try{this.root=access.endpoints.record.root()}finally{access.close()}this.failure=options.failure??"isolate"}describe(structure,description){if(assertStructureConfigurable(structure),this.#descriptions.has(structure))throw new Error("Recording description is already registered for this structure");return this.#descriptions.set(structure,description),this}declarations(structure){return[invocationRecording(this.#descriptions.get(structure))]}bindInvocation(setup,parent){if(parent&&!(parent instanceof InvocationRecording))throw new Error("Recording parent belongs to another observation capability");return new InvocationRecording(this,setup,parent)}recordFact(fact,source,writer){const returned=this.#fact(fact,source,writer);if(returned&&typeof returned.then=="function")throw Promise.resolve(returned).catch(()=>{}),new TypeError("Fact recording must complete synchronously")}invalidate(error){this.options.invalidate?.(error)}consumer(work){let active=!0;return{publish:__name(event=>{if(active)try{const access=this.records.open();try{work(event,access.endpoints.record)}finally{access.close()}return}catch(cause){active=!1;const error=new ObservationError(cause);return this.invalidate(error),this.failure==="propagate"?error:void 0}},"publish")}}}function bindRecording(recorder,options={}){return new RecordingInstallation(recorder,options)}__name(bindRecording,"bindRecording");export{RecordingInstallation,bindRecording};
@@ -1,6 +1,6 @@
1
1
  import { InvocationResources, type InvocationFact, type ResourceObservation, type InvocationObserver } from '@weiliang0121/capix-invocation';
2
- import type { MemoryEvent, TranscriptEvent } from '@weiliang0121/capix-protocol';
3
2
  import type { InvocationObservationSetup } from '../../binding/observation.js';
3
+ import { type ResourceFact } from '@weiliang0121/capix-resources';
4
4
  import { CallableRecord } from '@weiliang0121/capix-records';
5
5
  import { type InvocationRecordDescription, type InvocationRecordWriter } from './declaration.js';
6
6
  import type { RecordingInstallation } from './installation.js';
@@ -18,10 +18,8 @@ export declare class InvocationRecording implements InvocationObserver {
18
18
  observe(_fact: InvocationFact): undefined;
19
19
  observeDescribed(fact: InvocationFact, description?: InvocationRecordDescription): void;
20
20
  resource(fact: ResourceObservation): void;
21
- transcript(event: TranscriptEvent): void;
22
- memory(event: MemoryEvent): void;
21
+ fact(fact: ResourceFact): void;
23
22
  private requireRecord;
24
- private checkOrigin;
25
23
  private source;
26
24
  private begin;
27
25
  private process;
@@ -1,2 +1,2 @@
1
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,RuntimeErrorHelper,failureFact}from"@weiliang0121/capix-invocation";import{isUndefined}from"es-toolkit/predicate";import{pick}from"es-toolkit/object";import{ResourceSupply,resourceRequests}from"@weiliang0121/capix-resources";import{CallableRecord,InvocationRecordHelper,ResourceRecord}from"@weiliang0121/capix-records";import{InvocationRecordAccess}from"./declaration.js";import{memoryRecord,recordedResult,transcriptRecord}from"./mapping.js";class InvocationRecording{static{__name(this,"InvocationRecording")}installation;setup;parentRecording;resources;#childRecordings=new Map;#pendingAttachments=[];#record;#startedTick;#failed=!1;#enabled;#recordDescription={};constructor(installation,setup,parentRecording){if(this.installation=installation,this.setup=setup,this.parentRecording=parentRecording,this.#enabled=(setup.declarations??[]).some(declaration=>resourceRequests(declaration.deps).some(request=>request.offer===InvocationRecordAccess.request().offer)),parentRecording&&parentRecording.installation!==installation)throw new Error("Recording parent belongs to another installation");parentRecording&&parentRecording.#childRecordings.set(setup.identity.contextId,this),this.resources=new InvocationResources({record:InvocationRecordAccess.request()},ResourceSupply.capture([InvocationRecordAccess.provide(()=>this)],void 0).entries)}get record(){return this.#record}available(){return this.#enabled&&!this.#failed&&(this.parentRecording?.available()??!0)}observe(_fact){}observeDescribed(fact,description={}){this.protect(writer=>{if(fact.identity.contextId!==this.setup.identity.contextId||fact.identity.kind!==this.setup.identity.kind)throw new Error("Call fact belongs to another local observation");this.#recordDescription=description,fact.kind==="started"?this.begin(fact,writer):fact.kind==="process"?this.process(fact,writer):fact.kind==="relation"?!this.#record&&fact.change.kind==="attached"?this.#pendingAttachments.push({...fact,identity:{...fact.identity},relation:{...fact.relation},change:{kind:"attached"}}):this.relation(fact,writer):this.finish(fact,writer)})}resource(fact){this.protect(writer=>{const record=this.requireRecord();if(fact.contextId!==record.contextId)throw new Error("Resource fact belongs to another call");writer.add(new ResourceRecord({parentId:record.id,access:fact.access,supplyId:fact.supplyId,sequence:fact.sequence,occurredAt:fact.occurredAt,phase:fact.phase,...fact.interactionId?{interactionId:fact.interactionId}:{}},fact.describe()))})}transcript(event){this.protect(writer=>{this.checkOrigin(event.origin),writer.add(transcriptRecord(event,this.source()))})}memory(event){this.protect(writer=>{this.checkOrigin(event.origin),writer.add(memoryRecord(event,this.source()))})}requireRecord(){if(!this.#record)throw new Error("The call recording has not started");return this.#record}checkOrigin(origin){if(origin?.contextId!==this.setup.identity.contextId)throw new Error("Entity fact belongs to another call")}source(){const record=this.requireRecord();return{contextId:record.contextId,callId:record.id}}begin(fact,writer){if(this.#record)throw new Error("A call recording can only start once");const input=this.#recordDescription.input?this.#recordDescription.input(fact.input):fact.input,description=fact.description??this.setup.description??{},parentRecord=this.parentRecording?.requireRecord();if(fact.identity.parentContextId!==void 0!=!!parentRecord||parentRecord&&parentRecord.contextId!==fact.identity.parentContextId)throw new Error("Call recording parent differs from its invocation relationship");this.#record=writer.add(new CallableRecord({contextId:fact.identity.contextId,structureKind:fact.identity.kind,parentId:parentRecord?.id??this.installation.root.id,...description.id!==void 0?{structureId:description.id}:{},...pick(description,["name","label","source"]),...this.#recordDescription.role!==void 0||description.role!==void 0?{role:this.#recordDescription.role??description.role}:{}},{input,startedAt:fact.occurredAt})),this.#startedTick=fact.monotonicTime,this.boundary(fact,"call",writer);for(const attachment of this.#pendingAttachments.splice(0))this.relation(attachment,writer,Math.max(0,this.offset(attachment.monotonicTime)))}process(fact,writer){const record=this.requireRecord(),process=fact.process;let body;"error"in process?body={...process,error:RuntimeErrorHelper.format(process.error),...process.failure?{failure:failureFact(process.failure)}:{}}:"input"in process&&this.#recordDescription.input?body={...process,input:this.#recordDescription.input(process.input)}:"output"in process&&this.#recordDescription.output?body={...process,output:this.#recordDescription.output(process.output)}:body=process;const entry={...body,sequence:fact.processSequence,eventSequence:fact.eventSequence,round:fact.round,occurredAt:fact.occurredAt,offsetMs:this.offset(fact.monotonicTime)};writer.update(record,current=>current.append(entry),current=>({kind:"process-appended",id:current.id,process:current.value.processes.at(-1)}))}relation(fact,writer,offsetMs=this.offset(fact.monotonicTime)){const record=this.requireRecord(),childRecording=this.#childRecordings.get(fact.relation.childContextId);if(fact.relation.parentContextId!==record.contextId)throw new Error("Relation fact belongs to another parent");let change;fact.change.kind==="returned"?change={kind:"returned",result:recordedResult(fact.change.result,childRecording?childRecording.#recordDescription:void 0)}:fact.change.kind==="accepted"&&this.#recordDescription.relationAccepted?change={kind:"accepted",output:this.#recordDescription.relationAccepted(fact.change.output,fact.relation)}:fact.change.kind==="handled"&&this.#recordDescription.relationHandled?change={kind:"handled",output:this.#recordDescription.relationHandled(fact.change.output,fact.relation)}:fact.change.kind==="failed"?change={kind:"failed",source:fact.change.source,error:RuntimeErrorHelper.format(fact.change.error),...fact.change.failure?{failure:failureFact(fact.change.failure)}:{}}:change=fact.change;const relation={identity:fact.relation,eventSequence:fact.eventSequence,occurredAt:fact.occurredAt,offsetMs,...childRecording?.record?{childId:childRecording.record.id}:{},change};writer.update(record,current=>current.appendRelation(relation),current=>({kind:"relation-appended",id:current.id,relation:current.value.relationChanges.at(-1)}))}finish(fact,writer){const state=fact.state;if(!this.#record&&state.status==="failed")return;const record=this.requireRecord();if(state.status==="running")throw new Error("A terminal call fact requires an outcome");if(state.status==="failed")InvocationRecordHelper.finish(writer,record,current=>current.fail(RuntimeErrorHelper.format(state.error),state.failure?failureFact(state.failure):void 0));else{const last=record.value.processes.at(-1),resultOf=last?.type==="return"?"resultOf"in last?last.resultOf:last.sequence:void 0,output=isUndefined(resultOf)?this.#recordDescription.output?this.#recordDescription.output(state.output):state.output:void 0;InvocationRecordHelper.finish(writer,record,current=>current.complete(output,resultOf))}this.boundary(fact,state.status==="succeeded"?"return":"throw",writer)}timingRoot(){let recording=this;for(;recording.parentRecording;)recording=recording.parentRecording;return recording}offset(time){const timingRecording=this.timingRoot();if(isUndefined(timingRecording.#startedTick))throw new Error("Call recording has no timing origin");return time-timingRecording.#startedTick}boundary(fact,type,writer){const timingRecording=this.timingRoot();writer.boundary({start:timingRecording.#startedTick,scopeId:timingRecording.requireRecord().id,callId:this.requireRecord().id,occurredAt:fact.occurredAt,offsetMs:this.offset(fact.monotonicTime)},type)}protect(work){if(this.available())try{const access=this.installation.records.open();try{work(access.endpoints.record)}finally{access.close()}}catch(error){throw this.#failed=!0,this.installation.invalidate(error),error}}}export{InvocationRecording};
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{InvocationResources,RuntimeErrorHelper,failureFact}from"@weiliang0121/capix-invocation";import{isUndefined}from"es-toolkit/predicate";import{pick}from"es-toolkit/object";import{ResourceSupply,resourceRequests}from"@weiliang0121/capix-resources";import{CallableRecord,InvocationRecordHelper,ResourceRecord}from"@weiliang0121/capix-records";import{InvocationRecordAccess}from"./declaration.js";import{recordedResult}from"./mapping.js";class InvocationRecording{static{__name(this,"InvocationRecording")}installation;setup;parentRecording;resources;#childRecordings=new Map;#pendingAttachments=[];#record;#startedTick;#failed=!1;#enabled;#recordDescription={};constructor(installation,setup,parentRecording){if(this.installation=installation,this.setup=setup,this.parentRecording=parentRecording,this.#enabled=(setup.declarations??[]).some(declaration=>resourceRequests(declaration.deps).some(request=>request.offer===InvocationRecordAccess.request().offer)),parentRecording&&parentRecording.installation!==installation)throw new Error("Recording parent belongs to another installation");parentRecording&&parentRecording.#childRecordings.set(setup.identity.contextId,this),this.resources=new InvocationResources({record:InvocationRecordAccess.request()},ResourceSupply.capture([InvocationRecordAccess.provide(()=>this)],void 0).entries)}get record(){return this.#record}available(){return this.#enabled&&!this.#failed&&(this.parentRecording?.available()??!0)}observe(_fact){}observeDescribed(fact,description={}){this.protect(writer=>{if(fact.identity.contextId!==this.setup.identity.contextId||fact.identity.kind!==this.setup.identity.kind)throw new Error("Call fact belongs to another local observation");this.#recordDescription=description,fact.kind==="started"?this.begin(fact,writer):fact.kind==="process"?this.process(fact,writer):fact.kind==="relation"?!this.#record&&fact.change.kind==="attached"?this.#pendingAttachments.push({...fact,identity:{...fact.identity},relation:{...fact.relation},change:{kind:"attached"}}):this.relation(fact,writer):this.finish(fact,writer)})}resource(fact){this.protect(writer=>{const record=this.requireRecord();if(fact.contextId!==record.contextId)throw new Error("Resource fact belongs to another call");writer.add(new ResourceRecord({parentId:record.id,access:fact.access,supplyId:fact.supplyId,sequence:fact.sequence,occurredAt:fact.occurredAt,phase:fact.phase,...fact.interactionId?{interactionId:fact.interactionId}:{}},fact.describe()))})}fact(fact){this.protect(writer=>{if(fact.contextId!==this.setup.identity.contextId)throw new Error("Entity fact belongs to another call");this.installation.recordFact(fact,this.source(),writer)})}requireRecord(){if(!this.#record)throw new Error("The call recording has not started");return this.#record}source(){const record=this.requireRecord();return{contextId:record.contextId,callId:record.id}}begin(fact,writer){if(this.#record)throw new Error("A call recording can only start once");const input=this.#recordDescription.input?this.#recordDescription.input(fact.input):fact.input,description=fact.description??this.setup.description??{},parentRecord=this.parentRecording?.requireRecord();if(fact.identity.parentContextId!==void 0!=!!parentRecord||parentRecord&&parentRecord.contextId!==fact.identity.parentContextId)throw new Error("Call recording parent differs from its invocation relationship");this.#record=writer.add(new CallableRecord({contextId:fact.identity.contextId,structureKind:fact.identity.kind,parentId:parentRecord?.id??this.installation.root.id,...description.id!==void 0?{structureId:description.id}:{},...pick(description,["name","label","source"]),...this.#recordDescription.role!==void 0||description.role!==void 0?{role:this.#recordDescription.role??description.role}:{}},{input,startedAt:fact.occurredAt})),this.#startedTick=fact.monotonicTime,this.boundary(fact,"call",writer);for(const attachment of this.#pendingAttachments.splice(0))this.relation(attachment,writer,Math.max(0,this.offset(attachment.monotonicTime)))}process(fact,writer){const record=this.requireRecord(),process=fact.process;let body;"error"in process?body={...process,error:RuntimeErrorHelper.format(process.error),...process.failure?{failure:failureFact(process.failure)}:{}}:"input"in process&&this.#recordDescription.input?body={...process,input:this.#recordDescription.input(process.input)}:"output"in process&&this.#recordDescription.output?body={...process,output:this.#recordDescription.output(process.output)}:body=process;const entry={...body,sequence:fact.processSequence,eventSequence:fact.eventSequence,round:fact.round,occurredAt:fact.occurredAt,offsetMs:this.offset(fact.monotonicTime)};writer.update(record,current=>current.append(entry),current=>({kind:"process-appended",id:current.id,process:current.value.processes.at(-1)}))}relation(fact,writer,offsetMs=this.offset(fact.monotonicTime)){const record=this.requireRecord(),childRecording=this.#childRecordings.get(fact.relation.childContextId);if(fact.relation.parentContextId!==record.contextId)throw new Error("Relation fact belongs to another parent");let change;fact.change.kind==="returned"?change={kind:"returned",result:recordedResult(fact.change.result,childRecording?childRecording.#recordDescription:void 0)}:fact.change.kind==="accepted"&&this.#recordDescription.relationAccepted?change={kind:"accepted",output:this.#recordDescription.relationAccepted(fact.change.output,fact.relation)}:fact.change.kind==="handled"&&this.#recordDescription.relationHandled?change={kind:"handled",output:this.#recordDescription.relationHandled(fact.change.output,fact.relation)}:fact.change.kind==="failed"?change={kind:"failed",source:fact.change.source,error:RuntimeErrorHelper.format(fact.change.error),...fact.change.failure?{failure:failureFact(fact.change.failure)}:{}}:change=fact.change;const relation={identity:fact.relation,eventSequence:fact.eventSequence,occurredAt:fact.occurredAt,offsetMs,...childRecording?.record?{childId:childRecording.record.id}:{},change};writer.update(record,current=>current.appendRelation(relation),current=>({kind:"relation-appended",id:current.id,relation:current.value.relationChanges.at(-1)}))}finish(fact,writer){const state=fact.state;if(!this.#record&&state.status==="failed")return;const record=this.requireRecord();if(state.status==="running")throw new Error("A terminal call fact requires an outcome");if(state.status==="failed")InvocationRecordHelper.finish(writer,record,current=>current.fail(RuntimeErrorHelper.format(state.error),state.failure?failureFact(state.failure):void 0));else{const last=record.value.processes.at(-1),resultOf=last?.type==="return"?"resultOf"in last?last.resultOf:last.sequence:void 0,output=isUndefined(resultOf)?this.#recordDescription.output?this.#recordDescription.output(state.output):state.output:void 0;InvocationRecordHelper.finish(writer,record,current=>current.complete(output,resultOf))}this.boundary(fact,state.status==="succeeded"?"return":"throw",writer)}timingRoot(){let recording=this;for(;recording.parentRecording;)recording=recording.parentRecording;return recording}offset(time){const timingRecording=this.timingRoot();if(isUndefined(timingRecording.#startedTick))throw new Error("Call recording has no timing origin");return time-timingRecording.#startedTick}boundary(fact,type,writer){const timingRecording=this.timingRoot();writer.boundary({start:timingRecording.#startedTick,scopeId:timingRecording.requireRecord().id,callId:this.requireRecord().id,occurredAt:fact.occurredAt,offsetMs:this.offset(fact.monotonicTime)},type)}protect(work){if(this.available())try{const access=this.installation.records.open();try{work(access.endpoints.record)}finally{access.close()}}catch(error){throw this.#failed=!0,this.installation.invalidate(error),error}}}export{InvocationRecording};
@@ -1,7 +1,4 @@
1
- import type { MemoryEvent, TranscriptEvent, RecordedInvocationResult } from '@weiliang0121/capix-protocol';
1
+ import type { RecordedInvocationResult } from '@weiliang0121/capix-records/data';
2
2
  import { type InvocationResult } from '@weiliang0121/capix-invocation';
3
- import { MemoryRecord, TranscriptRecord, type RecordChangeSource } from '@weiliang0121/capix-records';
4
3
  import type { InvocationRecordDescription } from './declaration.js';
5
4
  export declare function recordedResult(result: InvocationResult<unknown>, description?: InvocationRecordDescription): RecordedInvocationResult;
6
- export declare function transcriptRecord(event: TranscriptEvent, source?: RecordChangeSource): TranscriptRecord;
7
- export declare function memoryRecord(event: MemoryEvent, source?: RecordChangeSource): MemoryRecord;
@@ -1,2 +1,2 @@
1
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{RuntimeErrorHelper,failureFact}from"@weiliang0121/capix-invocation";import{MemoryRecord,TranscriptRecord}from"@weiliang0121/capix-records";function recordedResult(result,description){return result.status==="succeeded"?{status:"succeeded",output:description?.output?description.output(result.output):result.output}:{status:"failed",error:RuntimeErrorHelper.format(result.error),...result.failure?{failure:failureFact(result.failure)}:{}}}__name(recordedResult,"recordedResult");function transcriptRecord(event,source){const change=event.change;return new TranscriptRecord({transcriptId:event.transcriptId,revision:event.revision,occurredAt:event.occurredAt,...source?{source}:{}},change.kind==="messages-appended"?{action:"append",start:change.start,end:change.start+change.messages.length}:{action:"segment",previousStart:change.previousStart,start:change.start,end:change.end})}__name(transcriptRecord,"transcriptRecord");function memoryRecord(event,source){return new MemoryRecord({memoriesId:event.memoriesId,memoryId:event.change.memoryId,sequence:event.sequence,...source?{source}:{}},{action:event.change.action,change:event.change.explanation,sourceIndexes:event.change.sourceIndexes,...event.change.sourceResults?{sourceResults:event.change.sourceResults}:{},result:event.change.result})}__name(memoryRecord,"memoryRecord");export{memoryRecord,recordedResult,transcriptRecord};
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{RuntimeErrorHelper,failureFact}from"@weiliang0121/capix-invocation";function recordedResult(result,description){return result.status==="succeeded"?{status:"succeeded",output:description?.output?description.output(result.output):result.output}:{status:"failed",error:RuntimeErrorHelper.format(result.error),...result.failure?{failure:failureFact(result.failure)}:{}}}__name(recordedResult,"recordedResult");export{recordedResult};
@@ -1,2 +1,2 @@
1
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{ProgressChannel}from"@weiliang0121/capix-changes";import"./observation.js";import{projectInvocation,projectResource,projectBusiness,projectCheckpoint,projectDiagnostic}from"./observation-projection.js";class RunnerEntryFeedback{static{__name(this,"RunnerEntryFeedback")}runnerId;subscriptions;clock;id=randomUUID();#sequence=0;#entries;created;constructor(runnerId,subscriptions,clock){this.runnerId=runnerId,this.subscriptions=subscriptions,this.clock=clock,this.#entries=new ProgressChannel({receive:__name(change=>this.publishEntry(change),"receive")}),this.created=Object.freeze({receive:__name(identity=>{this.#entries.publish({kind:"attached",identity})},"receive")})}requested(mode,requestedContextId){this.#entries.publish({kind:"requested",mode,...requestedContextId!==void 0?{requestedContextId}:{}})}entry(change){change.kind!=="established"&&this.#entries.publish(change)}settled(status,error){this.#entries.publish({kind:"settled",status,error})}receivers(signal){return Object.freeze({invocation:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"invocation",fact:projectInvocation(fact,signal)})},"receive")},resource:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"resource",fact:projectResource(fact)})},"receive")},business:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"business",fact:projectBusiness(fact)})},"receive")},checkpoint:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"checkpoint",fact:projectCheckpoint(fact,signal)})},"receive")}})}publishEntry(change){const sequence=++this.#sequence;if(!this.subscriptions.active)return;const time={sequence,occurredAt:this.clock.now()};let fact;change.kind==="requested"?fact=Object.freeze({...time,...change}):change.kind==="attached"?fact=Object.freeze({...time,kind:"attached",identity:Object.freeze({...change.identity})}):change.kind==="settled"?fact=Object.freeze({...time,kind:"settled",status:change.status,...change.status!=="succeeded"?{diagnostic:projectDiagnostic(change.error)}:{}}):change.kind==="entry-failed"?fact=Object.freeze({...time,kind:"entry-failed",diagnostic:projectDiagnostic(change.error)}):change.kind==="rejected"?fact=Object.freeze({...time,kind:"rejected",reason:change.reason,diagnostic:projectDiagnostic(change.error)}):fact=Object.freeze({...time,kind:change.kind}),this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"entry",fact})}}export{RunnerEntryFeedback};
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{randomUUID}from"node:crypto";import{ProgressChannel}from"@weiliang0121/capix-changes";import"./observation.js";import{projectInvocation,projectResource,projectFact,projectBusiness,projectCheckpoint,projectDiagnostic}from"./observation-projection.js";class RunnerEntryFeedback{static{__name(this,"RunnerEntryFeedback")}runnerId;subscriptions;clock;id=randomUUID();#sequence=0;#entries;created;constructor(runnerId,subscriptions,clock){this.runnerId=runnerId,this.subscriptions=subscriptions,this.clock=clock,this.#entries=new ProgressChannel({receive:__name(change=>this.publishEntry(change),"receive")}),this.created=Object.freeze({receive:__name(identity=>{this.#entries.publish({kind:"attached",identity})},"receive")})}requested(mode,requestedContextId){this.#entries.publish({kind:"requested",mode,...requestedContextId!==void 0?{requestedContextId}:{}})}entry(change){change.kind!=="established"&&this.#entries.publish(change)}settled(status,error){this.#entries.publish({kind:"settled",status,error})}receivers(signal){return Object.freeze({invocation:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"invocation",fact:projectInvocation(fact,signal)})},"receive")},resource:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"resource",fact:projectResource(fact)})},"receive")},fact:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"fact",fact:projectFact(fact)})},"receive")},business:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"business",fact:projectBusiness(fact)})},"receive")},checkpoint:{receive:__name(fact=>{this.subscriptions.active&&this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"checkpoint",fact:projectCheckpoint(fact,signal)})},"receive")}})}publishEntry(change){const sequence=++this.#sequence;if(!this.subscriptions.active)return;const time={sequence,occurredAt:this.clock.now()};let fact;change.kind==="requested"?fact=Object.freeze({...time,...change}):change.kind==="attached"?fact=Object.freeze({...time,kind:"attached",identity:Object.freeze({...change.identity})}):change.kind==="settled"?fact=Object.freeze({...time,kind:"settled",status:change.status,...change.status!=="succeeded"?{diagnostic:projectDiagnostic(change.error)}:{}}):change.kind==="entry-failed"?fact=Object.freeze({...time,kind:"entry-failed",diagnostic:projectDiagnostic(change.error)}):change.kind==="rejected"?fact=Object.freeze({...time,kind:"rejected",reason:change.reason,diagnostic:projectDiagnostic(change.error)}):fact=Object.freeze({...time,kind:change.kind}),this.subscriptions.publish({runnerId:this.runnerId,entryId:this.id,source:"entry",fact})}}export{RunnerEntryFeedback};
@@ -58,18 +58,15 @@ export type RunnerCheckpointChild = Readonly<{
58
58
  state: 'failed';
59
59
  reception?: 'handled';
60
60
  })>;
61
- export interface RunnerTranscriptFact {
62
- readonly transcriptId: string;
63
- readonly revision: number;
64
- readonly change: 'messages-appended' | 'segment-started';
65
- readonly start: number;
66
- readonly end: number;
67
- }
68
- export interface RunnerMemoryFact {
69
- readonly memoriesId: string;
61
+ export interface RunnerFact {
62
+ readonly contextId: string;
63
+ readonly offerId: string;
64
+ readonly access: string;
65
+ readonly supplyId: string;
66
+ readonly operationId: string;
70
67
  readonly sequence: number;
71
- readonly action: 'create' | 'update';
72
- readonly memoryId: string;
68
+ readonly occurredAt: string;
69
+ readonly name?: string;
73
70
  }
74
71
  export type RunnerCheckpointFact = Readonly<{
75
72
  activityId: string;
@@ -102,11 +99,8 @@ export type RunnerCheckpointFact = Readonly<{
102
99
  kind: 'resource';
103
100
  fact: RunnerResourceFact;
104
101
  } | {
105
- kind: 'transcript';
106
- fact: RunnerTranscriptFact;
107
- } | {
108
- kind: 'memory';
109
- fact: RunnerMemoryFact;
102
+ kind: 'fact';
103
+ fact: RunnerFact;
110
104
  } | {
111
105
  kind: 'failed';
112
106
  stage: 'capture' | 'save' | 'restore' | 'finish';
@@ -134,4 +128,7 @@ export type RunnerObservationEvent = Readonly<{
134
128
  } | {
135
129
  source: 'business';
136
130
  fact: RunnerBusinessFact;
131
+ } | {
132
+ source: 'fact';
133
+ fact: RunnerFact;
137
134
  })>;
@@ -1,7 +1,8 @@
1
- import { type InvocationFact, type InvocationProgress, type ResourceObservation, type BusinessObservation, type CheckpointFact } from '@weiliang0121/capix-invocation';
2
- import type { RunnerDiagnostic, RunnerResourceFact, RunnerBusinessFact, RunnerCheckpointFact } from './observation-contract.js';
1
+ import { type InvocationFact, type InvocationProgress, type ResourceObservation, type ResourceFact, type BusinessObservation, type CheckpointFact } from '@weiliang0121/capix-invocation';
2
+ import type { RunnerDiagnostic, RunnerResourceFact, RunnerFact, RunnerBusinessFact, RunnerCheckpointFact } from './observation-contract.js';
3
3
  export declare function projectInvocation(fact: InvocationFact, signal: AbortSignal): InvocationProgress;
4
4
  export declare function projectResource(fact: ResourceObservation): RunnerResourceFact;
5
+ export declare function projectFact(fact: ResourceFact): RunnerFact;
5
6
  export declare function projectBusiness(fact: BusinessObservation): RunnerBusinessFact;
6
7
  export declare function projectDiagnostic(error: unknown): RunnerDiagnostic;
7
8
  export declare function projectCheckpoint(fact: CheckpointFact, signal: AbortSignal): RunnerCheckpointFact;
@@ -1,2 +1,2 @@
1
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{RuntimeErrorHelper}from"@weiliang0121/capix-diagnostics";import{invocationProgress}from"@weiliang0121/capix-invocation";function projectInvocation(fact,signal){return invocationProgress(fact,signal)}__name(projectInvocation,"projectInvocation");function projectResource(fact){return Object.freeze({contextId:fact.contextId,offerId:fact.offerId,access:fact.access,supplyId:fact.supplyId,sequence:fact.sequence,occurredAt:fact.occurredAt,phase:fact.phase,...fact.interactionId!==void 0?{interactionId:fact.interactionId}:{}})}__name(projectResource,"projectResource");function projectBusiness(fact){return Object.freeze({identity:projectIdentity(fact.identity),sequence:fact.sequence,occurredAt:fact.occurredAt,event:fact.event.event})}__name(projectBusiness,"projectBusiness");function projectDiagnostic(error){try{const diagnostic=RuntimeErrorHelper.format(error);return Object.freeze({code:diagnostic.code.slice(0,128),message:diagnostic.message.slice(0,512)})}catch{return Object.freeze({code:"OBSERVATION_DIAGNOSTIC_FAILED",message:"The failure could not be described."})}}__name(projectDiagnostic,"projectDiagnostic");function projectCheckpoint(fact,signal){const base={activityId:fact.activityId,contextId:fact.contextId,owner:projectIdentity(fact.owner),recovering:fact.recovering,sequence:fact.sequence,occurredAt:fact.occurredAt};switch(fact.kind){case"captured":case"saved":case"checking":case"continued":return Object.freeze({...base,kind:fact.kind,checkpointId:fact.checkpointId,point:fact.point});case"installed":return Object.freeze({...base,kind:fact.kind,checkpointId:fact.checkpointId,point:fact.point,baseline:Object.freeze({round:fact.frame.round,nextChildOrder:fact.frame.nextChildOrder,childCount:fact.frame.children.length})});case"child-restored":return Object.freeze({...base,kind:fact.kind,child:projectChild(fact.child),mode:fact.mode});case"activity":return Object.freeze({...base,kind:fact.kind,fact:projectInvocation(fact.fact,signal)});case"resource":return Object.freeze({...base,kind:fact.kind,fact:projectResource(fact.fact)});case"transcript":{const change=fact.fact.change,content=Object.freeze({transcriptId:fact.fact.transcriptId,revision:fact.fact.revision,change:change.kind,start:change.start,end:change.kind==="messages-appended"?change.start+change.messages.length:change.end});return Object.freeze({...base,kind:fact.kind,fact:content})}case"memory":return Object.freeze({...base,kind:fact.kind,fact:Object.freeze({memoriesId:fact.fact.memoriesId,sequence:fact.fact.sequence,action:fact.fact.change.action,memoryId:fact.fact.change.memoryId})});case"failed":return Object.freeze({...base,kind:fact.kind,stage:fact.stage,diagnostic:projectDiagnostic(fact.error),...fact.childContextId!==void 0?{childContextId:fact.childContextId}:{}});case"finishing":case"finished":return Object.freeze({...base,kind:fact.kind,status:fact.status})}}__name(projectCheckpoint,"projectCheckpoint");function projectIdentity(identity){return Object.freeze({contextId:identity.contextId,kind:identity.kind,...identity.parentContextId!==void 0?{parentContextId:identity.parentContextId}:{}})}__name(projectIdentity,"projectIdentity");function projectChild(child){const base={identity:projectIdentity(child.identity),round:child.round,order:child.order,...child.key!==void 0?{key:child.key}:{}};return child.state.kind==="waiting"?Object.freeze({...base,state:child.state.kind}):child.state.kind==="returned"?Object.freeze({...base,state:child.state.kind,reception:child.state.reception.kind}):Object.freeze({...base,state:child.state.kind,...child.state.reception?{reception:child.state.reception.kind}:{}})}__name(projectChild,"projectChild");export{projectBusiness,projectCheckpoint,projectDiagnostic,projectInvocation,projectResource};
2
+ var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{RuntimeErrorHelper}from"@weiliang0121/capix-diagnostics";import{invocationProgress}from"@weiliang0121/capix-invocation";function projectInvocation(fact,signal){return invocationProgress(fact,signal)}__name(projectInvocation,"projectInvocation");function projectResource(fact){return Object.freeze({contextId:fact.contextId,offerId:fact.offerId,access:fact.access,supplyId:fact.supplyId,sequence:fact.sequence,occurredAt:fact.occurredAt,phase:fact.phase,...fact.interactionId!==void 0?{interactionId:fact.interactionId}:{}})}__name(projectResource,"projectResource");function projectFact(fact){return Object.freeze({contextId:fact.contextId,offerId:fact.offerId,access:fact.access,supplyId:fact.supplyId,operationId:fact.operationId,sequence:fact.sequence,occurredAt:fact.occurredAt,...fact.fact.name!==void 0?{name:fact.fact.name}:{}})}__name(projectFact,"projectFact");function projectBusiness(fact){return Object.freeze({identity:projectIdentity(fact.identity),sequence:fact.sequence,occurredAt:fact.occurredAt,event:fact.event.event})}__name(projectBusiness,"projectBusiness");function projectDiagnostic(error){try{const diagnostic=RuntimeErrorHelper.format(error);return Object.freeze({code:diagnostic.code.slice(0,128),message:diagnostic.message.slice(0,512)})}catch{return Object.freeze({code:"OBSERVATION_DIAGNOSTIC_FAILED",message:"The failure could not be described."})}}__name(projectDiagnostic,"projectDiagnostic");function projectCheckpoint(fact,signal){const base={activityId:fact.activityId,contextId:fact.contextId,owner:projectIdentity(fact.owner),recovering:fact.recovering,sequence:fact.sequence,occurredAt:fact.occurredAt};switch(fact.kind){case"captured":case"saved":case"checking":case"continued":return Object.freeze({...base,kind:fact.kind,checkpointId:fact.checkpointId,point:fact.point});case"installed":return Object.freeze({...base,kind:fact.kind,checkpointId:fact.checkpointId,point:fact.point,baseline:Object.freeze({round:fact.frame.round,nextChildOrder:fact.frame.nextChildOrder,childCount:fact.frame.children.length})});case"child-restored":return Object.freeze({...base,kind:fact.kind,child:projectChild(fact.child),mode:fact.mode});case"activity":return Object.freeze({...base,kind:fact.kind,fact:projectInvocation(fact.fact,signal)});case"resource":return Object.freeze({...base,kind:fact.kind,fact:projectResource(fact.fact)});case"fact":return Object.freeze({...base,kind:fact.kind,fact:projectFact(fact.fact)});case"failed":return Object.freeze({...base,kind:fact.kind,stage:fact.stage,diagnostic:projectDiagnostic(fact.error),...fact.childContextId!==void 0?{childContextId:fact.childContextId}:{}});case"finishing":case"finished":return Object.freeze({...base,kind:fact.kind,status:fact.status})}}__name(projectCheckpoint,"projectCheckpoint");function projectIdentity(identity){return Object.freeze({contextId:identity.contextId,kind:identity.kind,...identity.parentContextId!==void 0?{parentContextId:identity.parentContextId}:{}})}__name(projectIdentity,"projectIdentity");function projectChild(child){const base={identity:projectIdentity(child.identity),round:child.round,order:child.order,...child.key!==void 0?{key:child.key}:{}};return child.state.kind==="waiting"?Object.freeze({...base,state:child.state.kind}):child.state.kind==="returned"?Object.freeze({...base,state:child.state.kind,reception:child.state.reception.kind}):Object.freeze({...base,state:child.state.kind,...child.state.reception?{reception:child.state.reception.kind}:{}})}__name(projectChild,"projectChild");export{projectBusiness,projectCheckpoint,projectDiagnostic,projectFact,projectInvocation,projectResource};
@@ -1,6 +1,6 @@
1
1
  import { type ProgressReceiver } from '@weiliang0121/capix-changes';
2
2
  import type { RunnerObservationEvent } from './observation-contract.js';
3
- export type { RunnerDiagnostic, RunnerEntryFact, RunnerResourceFact, RunnerBusinessFact, RunnerCheckpointChild, RunnerCheckpointFact, RunnerObservationEvent } from './observation-contract.js';
3
+ export type { RunnerDiagnostic, RunnerEntryFact, RunnerResourceFact, RunnerFact, RunnerBusinessFact, RunnerCheckpointChild, RunnerCheckpointFact, RunnerObservationEvent } from './observation-contract.js';
4
4
  export type RunnerObservationReceiver = ProgressReceiver<RunnerObservationEvent>;
5
5
  export interface RunnerObservation {
6
6
  subscribe(receiver: RunnerObservationReceiver): () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weiliang0121/capix-runtime",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,16 +19,15 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "es-toolkit": "1.52.0",
22
- "@weiliang0121/capix-protocol": "0.1.0",
23
- "@weiliang0121/capix-structure": "0.1.0",
24
- "@weiliang0121/capix-resources": "0.1.0",
25
- "@weiliang0121/capix-changes": "0.1.0",
26
- "@weiliang0121/capix-contracts": "0.1.0",
27
- "@weiliang0121/capix-records": "0.1.0",
28
- "@weiliang0121/capix-checkpoint": "0.1.0",
29
- "@weiliang0121/capix-invocation": "0.1.0",
30
- "@weiliang0121/capix-diagnostics": "0.1.0",
31
- "@weiliang0121/capix-interaction": "0.1.0"
22
+ "@weiliang0121/capix-resources": "0.3.0",
23
+ "@weiliang0121/capix-contracts": "0.3.0",
24
+ "@weiliang0121/capix-changes": "0.3.0",
25
+ "@weiliang0121/capix-checkpoint": "0.3.0",
26
+ "@weiliang0121/capix-structure": "0.3.0",
27
+ "@weiliang0121/capix-records": "0.3.0",
28
+ "@weiliang0121/capix-invocation": "0.3.0",
29
+ "@weiliang0121/capix-interaction": "0.3.0",
30
+ "@weiliang0121/capix-diagnostics": "0.3.0"
32
31
  },
33
32
  "description": "Structure binding, resource assembly, and Runner for CAPiX.",
34
33
  "license": "MIT",
@@ -36,7 +35,7 @@
36
35
  "repository": {
37
36
  "type": "git",
38
37
  "url": "git+https://github.com/weiliang0121/capix.git",
39
- "directory": "server/runtime"
38
+ "directory": "packages/runtime"
40
39
  },
41
40
  "engines": {
42
41
  "node": ">=22.23.2"
@@ -53,8 +52,17 @@
53
52
  "access": "public",
54
53
  "registry": "https://registry.npmjs.org"
55
54
  },
55
+ "devDependencies": {
56
+ "@weiliang0121/capix-model-exchanges": "0.3.0",
57
+ "@weiliang0121/capix-view": "0.3.0",
58
+ "@weiliang0121/capix-transcript": "0.3.0",
59
+ "@weiliang0121/capix-memory": "0.3.0",
60
+ "@weiliang0121/capix-model-provider": "0.3.0",
61
+ "@weiliang0121/capix-measurement": "0.3.0"
62
+ },
56
63
  "scripts": {
57
64
  "build": "tsc -p tsconfig.json",
58
- "typecheck": "tsc -p tsconfig.json --noEmit"
65
+ "typecheck": "tsc -p tsconfig.json --noEmit",
66
+ "test": "node ../../scripts/test/run.mjs --package ."
59
67
  }
60
68
  }