@weiliang0121/capix-records 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 (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -2
  3. package/dist/attempt/helper.d.ts +12 -0
  4. package/dist/attempt/helper.js +2 -0
  5. package/dist/attempt/record.d.ts +15 -0
  6. package/dist/attempt/record.js +2 -0
  7. package/dist/book.d.ts +15 -0
  8. package/dist/book.js +2 -0
  9. package/dist/callable/helper.d.ts +5 -0
  10. package/dist/callable/helper.js +2 -0
  11. package/dist/callable/record.d.ts +18 -0
  12. package/dist/callable/record.js +2 -0
  13. package/dist/composite.d.ts +13 -0
  14. package/dist/composite.js +2 -0
  15. package/dist/construction.d.ts +14 -0
  16. package/dist/construction.js +2 -0
  17. package/dist/error.d.ts +5 -0
  18. package/dist/error.js +2 -0
  19. package/dist/execution/helper.d.ts +16 -0
  20. package/dist/execution/helper.js +2 -0
  21. package/dist/execution/record.d.ts +8 -0
  22. package/dist/execution/record.js +2 -0
  23. package/dist/index.d.ts +30 -0
  24. package/dist/index.js +2 -0
  25. package/dist/invocation/boundary/helper.d.ts +18 -0
  26. package/dist/invocation/boundary/helper.js +2 -0
  27. package/dist/invocation/boundary/record.d.ts +16 -0
  28. package/dist/invocation/boundary/record.js +2 -0
  29. package/dist/invocation/helper.d.ts +5 -0
  30. package/dist/invocation/helper.js +2 -0
  31. package/dist/invocation/record.d.ts +20 -0
  32. package/dist/invocation/record.js +2 -0
  33. package/dist/memory/helper.d.ts +7 -0
  34. package/dist/memory/helper.js +2 -0
  35. package/dist/memory/observe.d.ts +10 -0
  36. package/dist/memory/observe.js +2 -0
  37. package/dist/memory/record.d.ts +21 -0
  38. package/dist/memory/record.js +2 -0
  39. package/dist/operation/helper.d.ts +12 -0
  40. package/dist/operation/helper.js +2 -0
  41. package/dist/operation/record.d.ts +17 -0
  42. package/dist/operation/record.js +2 -0
  43. package/dist/record.d.ts +16 -0
  44. package/dist/record.js +2 -0
  45. package/dist/recorder.d.ts +28 -0
  46. package/dist/recorder.js +2 -0
  47. package/dist/registration.d.ts +10 -0
  48. package/dist/registration.js +2 -0
  49. package/dist/resource/record.d.ts +15 -0
  50. package/dist/resource/record.js +2 -0
  51. package/dist/resource.d.ts +15 -0
  52. package/dist/resource.js +2 -0
  53. package/dist/restoration/access.d.ts +3 -0
  54. package/dist/restoration/access.js +2 -0
  55. package/dist/restoration/check.d.ts +2 -0
  56. package/dist/restoration/check.js +2 -0
  57. package/dist/restoration/entry.d.ts +3 -0
  58. package/dist/restoration/entry.js +2 -0
  59. package/dist/restoration/tree.d.ts +2 -0
  60. package/dist/restoration/tree.js +2 -0
  61. package/dist/root/helper.d.ts +5 -0
  62. package/dist/root/helper.js +2 -0
  63. package/dist/root/record.d.ts +6 -0
  64. package/dist/root/record.js +2 -0
  65. package/dist/runtime/record.d.ts +9 -0
  66. package/dist/runtime/record.js +2 -0
  67. package/dist/source.d.ts +6 -0
  68. package/dist/source.js +1 -0
  69. package/dist/transcript/helper.d.ts +6 -0
  70. package/dist/transcript/helper.js +2 -0
  71. package/dist/transcript/record.d.ts +20 -0
  72. package/dist/transcript/record.js +2 -0
  73. package/dist/tree/access.d.ts +3 -0
  74. package/dist/tree/access.js +2 -0
  75. package/dist/tree/relation.d.ts +4 -0
  76. package/dist/tree/relation.js +2 -0
  77. package/dist/tree/tree.d.ts +17 -0
  78. package/dist/tree/tree.js +2 -0
  79. package/dist/value/check.d.ts +1 -0
  80. package/dist/value/check.js +2 -0
  81. package/dist/value/copy.d.ts +1 -0
  82. package/dist/value/copy.js +2 -0
  83. package/dist/value/freeze.d.ts +1 -0
  84. package/dist/value/freeze.js +2 -0
  85. package/dist/value/snapshot.d.ts +1 -0
  86. package/dist/value/snapshot.js +2 -0
  87. package/package.json +47 -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,20 @@
1
- # Temporary Holding Version
1
+ # @weiliang0121/capix-records
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
+ Optional recording entities and resource contracts 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-records
9
+ ```
10
+
11
+ ## Public entry points
12
+
13
+ - `@weiliang0121/capix-records`
14
+ - `@weiliang0121/capix-records/construction`
15
+
16
+ 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.
17
+
18
+ ## License
19
+
20
+ MIT. Copyright (c) 2026 wei.liang. See [LICENSE](./LICENSE).
@@ -0,0 +1,12 @@
1
+ import type { InvocationFailureFact, RuntimeErrorValue } from '@weiliang0121/capix-contracts';
2
+ import type { Recorder } from '../recorder.js';
3
+ import type { RecordBook } from '../book.js';
4
+ import { AttemptRecord, type AttemptRecordOptions } from './record.js';
5
+ export declare class AttemptRecordHelper {
6
+ static create(recorder: Recorder, options: AttemptRecordOptions, input: unknown): AttemptRecord;
7
+ static get(book: RecordBook, id: string): AttemptRecord;
8
+ static findByOperation(recorder: Recorder, operationId: string): readonly AttemptRecord[];
9
+ static complete(recorder: Recorder, id: string, output: unknown, resultOf?: number): void;
10
+ static fail(recorder: Recorder, id: string, error: RuntimeErrorValue, failure?: InvocationFailureFact): void;
11
+ private static owner;
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{InvocationRecordHelper}from"../invocation/helper.js";import{ExecutionRecord}from"../execution/record.js";import{OperationRecord}from"../operation/record.js";import{AttemptRecord}from"./record.js";class AttemptRecordHelper{static{__name(this,"AttemptRecordHelper")}static create(recorder,options,input){const book=recorder.book,operation=this.owner(book,options.operationId),execution=book.get(operation.executionId);if(!(execution instanceof ExecutionRecord))throw new Error("Execution does not exist");if(execution.status!=="running"||operation.status!=="running")throw new Error("Record has already ended");const record=new AttemptRecord(options,input);return recorder.add(record)}static get(book,id){const record=book.get(id);if(!(record instanceof AttemptRecord))throw new Error("Attempt does not exist");return record}static findByOperation(recorder,operationId){return this.owner(recorder.book,operationId),recorder.tree.children(operationId).filter(record=>record instanceof AttemptRecord)}static complete(recorder,id,output,resultOf){InvocationRecordHelper.finish(recorder,this.get(recorder.book,id),record=>record.complete(output,resultOf))}static fail(recorder,id,error,failure){InvocationRecordHelper.finish(recorder,this.get(recorder.book,id),record=>record.fail(error,failure))}static owner(book,id){const operation=book.get(id);if(!(operation instanceof OperationRecord))throw new Error("Operation does not exist");return operation}}export{AttemptRecordHelper};
@@ -0,0 +1,15 @@
1
+ import type { AttemptRecord as AttemptData, AttemptValue } from '@weiliang0121/capix-protocol';
2
+ import { InvocationRecord } from '../invocation/record.js';
3
+ export type AttemptRecordOptions = Omit<AttemptData, 'id' | 'value' | 'status' | 'parentId' | 'childIds'>;
4
+ export declare class AttemptRecord extends InvocationRecord<AttemptValue> implements AttemptData {
5
+ readonly kind: "attempt";
6
+ readonly contextId: string;
7
+ readonly operationId: string;
8
+ readonly name: string;
9
+ readonly label: string;
10
+ readonly source: string;
11
+ readonly caller: string;
12
+ readonly callee: string;
13
+ constructor(options: AttemptRecordOptions, input: unknown);
14
+ toJSON(): AttemptData;
15
+ }
@@ -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{pick}from"es-toolkit/object";import{InvocationRecord}from"../invocation/record.js";import{snapshotValue}from"../value/snapshot.js";class AttemptRecord extends InvocationRecord{static{__name(this,"AttemptRecord")}kind="attempt";contextId;operationId;name;label;source;caller;callee;constructor(options,input){super(snapshotValue({input,processes:[],relationChanges:[]}),options.operationId),this.contextId=options.contextId,this.operationId=options.operationId,this.name=options.name,this.label=options.label,this.source=options.source,this.caller=options.caller,this.callee=options.callee,Object.freeze(this)}toJSON(){return{...super.toJSON(),status:this.status,...pick(this,["contextId","operationId","name","label","source","caller","callee"])}}}export{AttemptRecord};
package/dist/book.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { BaseRecord } from './record.js';
2
+ import { removeRegistration } from './tree/access.js';
3
+ import type { RecordEntry } from '@weiliang0121/capix-protocol';
4
+ export interface RecordBookState {
5
+ readonly entries: readonly RecordEntry[];
6
+ }
7
+ export declare class RecordBook {
8
+ #private;
9
+ static restore(state: RecordBookState): RecordBook;
10
+ exportState(): RecordBookState;
11
+ add<RecordType extends BaseRecord<unknown>>(record: RecordType): RecordType;
12
+ [removeRegistration](record: BaseRecord<unknown>): void;
13
+ get(id: string): BaseRecord<unknown> | undefined;
14
+ values(): IterableIterator<BaseRecord<unknown>>;
15
+ }
package/dist/book.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{removeRegistration}from"./tree/access.js";import{isPlainObject}from"es-toolkit/predicate";import{snapshotValue}from"./value/snapshot.js";import{restoreEntry}from"./restoration/entry.js";import{checkRestoredTree}from"./restoration/tree.js";import{sealHistorical}from"./restoration/access.js";class RecordBook{static{__name(this,"RecordBook")}#records=new Map;static restore(state){if(!isPlainObject(state)||!Array.isArray(state.entries)||Object.keys(state).length!==1)throw new Error("Invalid stored record book");const captured=snapshotValue(state),book=new RecordBook;for(const entry of captured.entries)book.add(restoreEntry(entry));checkRestoredTree(book);for(const record of book.values())record[sealHistorical]();return book}exportState(){return snapshotValue({entries:[...this.#records.values()].map(record=>({kind:record.kind,data:record.toJSON()}))})}add(record){if(this.#records.has(record.id))throw new Error("Record ID already exists");return this.#records.set(record.id,record),record}[removeRegistration](record){this.#records.get(record.id)===record&&this.#records.delete(record.id)}get(id){return this.#records.get(id)}values(){return this.#records.values()}}export{RecordBook};
@@ -0,0 +1,5 @@
1
+ import type { ExecutionRecordSnapshot } from '@weiliang0121/capix-protocol';
2
+ import type { Recorder } from '../recorder.js';
3
+ export declare class CallableRecordHelper {
4
+ static snapshot(recorder: Recorder, id: string): ExecutionRecordSnapshot;
5
+ }
@@ -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{InvocationBoundaryRecord}from"../invocation/boundary/record.js";import{MemoryRecord}from"../memory/record.js";import{ResourceRecord}from"../resource/record.js";import{TranscriptRecord}from"../transcript/record.js";import{CallableRecord}from"./record.js";class CallableRecordHelper{static{__name(this,"CallableRecordHelper")}static snapshot(recorder,id){const selected=recorder.book.get(id);if(!(selected instanceof CallableRecord))throw new Error("Callable record does not exist");const records=[selected,...recorder.tree.descendants(id)];let root=selected;const ancestry=[],visited=new Set([selected.id]);let parent=root.parentId?recorder.book.get(root.parentId):void 0;for(;parent instanceof CallableRecord;){if(visited.has(parent.id)||!parent.childIds.includes(root.id))throw new Error("Inconsistent callable record ancestry");visited.add(parent.id),ancestry.unshift(parent),root=parent,parent=root.parentId?recorder.book.get(root.parentId):void 0}const ancestorDetails=ancestry.flatMap(ancestor=>recorder.tree.children(ancestor.id)),boundaries=[...ancestorDetails.filter(record=>record instanceof InvocationBoundaryRecord),...records.filter(record=>record instanceof InvocationBoundaryRecord)];return boundaries.sort((left,right)=>left.scopeId===right.scopeId?left.sequence-right.sequence:Date.parse(left.occurredAt)-Date.parse(right.occurredAt)),{execution:selected.toJSON(),calls:records.filter(record=>record instanceof CallableRecord).map(record=>record.toJSON()),...root===selected?{}:{rootCall:root.toJSON()},...ancestry.length>1?{ancestors:ancestry.slice(1).map(record=>record.toJSON())}:{},boundaries:boundaries.map(record=>record.toJSON()),resources:[...ancestorDetails,...records].filter(record=>record instanceof ResourceRecord).map(record=>record.toJSON()),transcripts:records.filter(record=>record instanceof TranscriptRecord).map(record=>record.toJSON()),memories:records.filter(record=>record instanceof MemoryRecord).map(record=>record.toJSON())}}}export{CallableRecordHelper};
@@ -0,0 +1,18 @@
1
+ import type { CallableRecord as CallableRecordData, CallableValue } from '@weiliang0121/capix-protocol';
2
+ import { InvocationRecord } from '../invocation/record.js';
3
+ export type CallableRecordOptions = Omit<CallableRecordData, 'id' | 'value' | 'status' | 'childIds'>;
4
+ export declare class CallableRecord extends InvocationRecord<CallableValue> implements CallableRecordData {
5
+ readonly kind: "invocation";
6
+ readonly contextId: string;
7
+ readonly structureKind: CallableRecordData['structureKind'];
8
+ readonly structureId?: string;
9
+ readonly name?: string;
10
+ readonly label?: string;
11
+ readonly source?: string;
12
+ readonly callee?: string;
13
+ readonly role?: string;
14
+ constructor(options: CallableRecordOptions, value: Omit<CallableValue, 'processes' | 'relationChanges'> & {
15
+ startedAt: string;
16
+ });
17
+ toJSON(): CallableRecordData;
18
+ }
@@ -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{InvocationRecord}from"../invocation/record.js";import{snapshotValue}from"../value/snapshot.js";class CallableRecord extends InvocationRecord{static{__name(this,"CallableRecord")}kind="invocation";contextId;structureKind;structureId;name;label;source;callee;role;constructor(options,value){super(snapshotValue({...value,processes:[],relationChanges:[]}),options.parentId),this.contextId=options.contextId,this.structureKind=options.structureKind,this.structureId=options.structureId,this.name=options.name,this.label=options.label,this.source=options.source,this.callee=options.callee,this.role=options.role,Object.freeze(this)}toJSON(){return{...super.toJSON(),contextId:this.contextId,structureKind:this.structureKind,status:this.status,...this.structureId!==void 0?{structureId:this.structureId}:{},...this.name!==void 0?{name:this.name}:{},...this.label!==void 0?{label:this.label}:{},...this.source!==void 0?{source:this.source}:{},...this.callee!==void 0?{callee:this.callee}:{},...this.role!==void 0?{role:this.role}:{}}}}export{CallableRecord};
@@ -0,0 +1,13 @@
1
+ import { BaseRecord } from './record.js';
2
+ import { replaceChildren } from './tree/access.js';
3
+ export declare abstract class CompositeRecord<Value> extends BaseRecord<Value> {
4
+ #private;
5
+ get childIds(): readonly string[];
6
+ [replaceChildren](ids: readonly string[]): void;
7
+ toJSON(): {
8
+ childIds: readonly string[];
9
+ id: string;
10
+ parentId?: string;
11
+ value: Value;
12
+ };
13
+ }
@@ -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{BaseRecord}from"./record.js";import{replaceChildren}from"./tree/access.js";class CompositeRecord extends BaseRecord{static{__name(this,"CompositeRecord")}#childIds=Object.freeze([]);get childIds(){return this.#childIds}[replaceChildren](ids){this.requireWritable(),this.#childIds=ids}toJSON(){return{...super.toJSON(),childIds:this.childIds}}}export{CompositeRecord};
@@ -0,0 +1,14 @@
1
+ import { ResourceOffer } from '@weiliang0121/capix-resources';
2
+ import type { InvocationBoundaryValue, RecordMutation } from '@weiliang0121/capix-protocol';
3
+ import type { BaseRecord } from './record.js';
4
+ import type { Recorder } from './recorder.js';
5
+ import { InvocationBoundaryRecordHelper } from './invocation/boundary/helper.js';
6
+ import type { InvocationBoundaryRecord } from './invocation/boundary/record.js';
7
+ import type { RecordingRootRecord } from './root/record.js';
8
+ export interface RecordWriter {
9
+ root(): RecordingRootRecord;
10
+ add<RecordType extends BaseRecord<unknown>>(record: RecordType): RecordType;
11
+ update<RecordType extends BaseRecord<unknown>>(record: RecordType, apply: (record: RecordType) => void, describe?: (record: RecordType) => RecordMutation): void;
12
+ boundary(location: Parameters<typeof InvocationBoundaryRecordHelper.create>[1], type: InvocationBoundaryValue['type']): InvocationBoundaryRecord;
13
+ }
14
+ export declare const RecordWriterResource: ResourceOffer<Recorder, RecordWriter, Recorder, never>;
@@ -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{ResourceOffer}from"@weiliang0121/capix-resources";import{InvocationBoundaryRecordHelper}from"./invocation/boundary/helper.js";import{RecordingRootHelper}from"./root/helper.js";const RecordWriterResource=new ResourceOffer({name:"records.construct",expose:__name((recorder,activity)=>Object.freeze({root(){return activity.runSync("root",{output:__name(record=>({id:record.id,kind:record.kind}),"output")},()=>RecordingRootHelper.create(recorder))},add(record){return activity.runSync("add",{input:__name(()=>({id:record.id,kind:record.kind}),"input"),output:__name(added=>({id:added.id,kind:added.kind}),"output")},()=>recorder.add(record))},update(record,apply,describe){activity.runSync("update",{input:__name(()=>({id:record.id,kind:record.kind}),"input")},()=>recorder.update(record,apply,describe))},boundary(location,type){return activity.runSync("boundary",{input:__name(()=>({callId:location.callId,type}),"input"),output:__name(record=>({id:record.id,callId:record.callId,type}),"output")},()=>InvocationBoundaryRecordHelper.create(recorder,location,type))}}),"expose"),timing:"access",describe:__name(recorder=>({recorderId:recorder.id}),"describe")});export{RecordWriterResource};
@@ -0,0 +1,5 @@
1
+ import { RuntimeError } from '@weiliang0121/capix-contracts';
2
+ export declare class RecordingError extends RuntimeError {
3
+ constructor(cause: unknown);
4
+ }
5
+ export declare function writeRecord<Result>(write: () => Result): Result;
package/dist/error.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{RuntimeError}from"@weiliang0121/capix-contracts";class RecordingError extends RuntimeError{static{__name(this,"RecordingError")}constructor(cause){super("RECORDING_FAILED",cause instanceof Error?cause.message:"\u8FD0\u884C\u8BB0\u5F55\u767B\u8BB0\u5931\u8D25\u3002",void 0,{cause})}}function writeRecord(write){try{return write()}catch(error){throw error instanceof RecordingError?error:new RecordingError(error)}}__name(writeRecord,"writeRecord");export{RecordingError,writeRecord};
@@ -0,0 +1,16 @@
1
+ import type { InvocationFailureFact, RuntimeErrorValue } from '@weiliang0121/capix-contracts';
2
+ import type { Recorder } from '../recorder.js';
3
+ import type { ExecutionValue, LegacyExecutionRecordSnapshot } from '@weiliang0121/capix-protocol';
4
+ import type { RecordBook } from '../book.js';
5
+ import { ExecutionRecord } from './record.js';
6
+ export declare class ExecutionRecordHelper {
7
+ static create(recorder: Recorder, options: {
8
+ contextId: string;
9
+ parentId: string;
10
+ }, value: Omit<ExecutionValue, 'startedAt' | 'output' | 'error' | 'processes' | 'relationChanges' | 'resultOf'>): ExecutionRecord;
11
+ static get(book: RecordBook, id: string): ExecutionRecord;
12
+ static complete(recorder: Recorder, id: string, output: unknown, resultOf?: number): void;
13
+ static fail(recorder: Recorder, id: string, error: RuntimeErrorValue, failure?: InvocationFailureFact): void;
14
+ private static prepareFinish;
15
+ static snapshot(recorder: Recorder, id: string): LegacyExecutionRecordSnapshot;
16
+ }
@@ -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{InvocationRecordHelper}from"../invocation/helper.js";import{InvocationBoundaryRecordHelper}from"../invocation/boundary/helper.js";import{OperationRecordHelper}from"../operation/helper.js";import{AttemptRecord}from"../attempt/record.js";import{OperationRecord}from"../operation/record.js";import{ExecutionRecord}from"./record.js";import{RuntimeCallRecord}from"../runtime/record.js";import{ResourceRecord}from"../resource/record.js";class ExecutionRecordHelper{static{__name(this,"ExecutionRecordHelper")}static create(recorder,options,value){return recorder.add(new ExecutionRecord(options.contextId,{...value,startedAt:recorder.clock.now()},options.parentId))}static get(book,id){const record=book.get(id);if(!(record instanceof ExecutionRecord))throw new Error("Execution does not exist");return record}static complete(recorder,id,output,resultOf){const record=this.prepareFinish(recorder,id);InvocationRecordHelper.finish(recorder,record,record2=>record2.complete(output,resultOf))}static fail(recorder,id,error,failure){const record=this.prepareFinish(recorder,id);InvocationRecordHelper.finish(recorder,record,record2=>record2.fail(error,failure))}static prepareFinish(recorder,id){const record=this.get(recorder.book,id);if(record.status!=="running")throw new Error("Record has already ended");if(OperationRecordHelper.findByExecution(recorder,id).some(op=>op.status==="running"))throw new Error("Cannot end a record with active operations");return record}static snapshot(recorder,id){const execution=this.get(recorder.book,id),parent=execution.parentId?recorder.book.get(execution.parentId):void 0;if(!(parent instanceof RuntimeCallRecord))throw new Error("Execution requires its recorded Runtime call");const records=recorder.tree.descendants(id);return{runtimeCall:parent.toJSON(),runtimeEvents:InvocationBoundaryRecordHelper.findByScope(recorder,parent.id).map(event=>event.toJSON()),execution:execution.toJSON(),operations:records.filter(record=>record instanceof OperationRecord).map(record=>record.toJSON()),attempts:records.filter(record=>record instanceof AttemptRecord).map(record=>record.toJSON()),events:InvocationBoundaryRecordHelper.findByExecution(recorder,id).map(event=>event.toJSON()),resources:[...records,...recorder.tree.children(parent.id)].filter(record=>record instanceof ResourceRecord).map(record=>record.toJSON())}}}export{ExecutionRecordHelper};
@@ -0,0 +1,8 @@
1
+ import type { ExecutionRecord as ExecutionData, ExecutionValue } from '@weiliang0121/capix-protocol';
2
+ import { InvocationRecord } from '../invocation/record.js';
3
+ export declare class ExecutionRecord extends InvocationRecord<ExecutionValue> implements ExecutionData {
4
+ readonly contextId: string;
5
+ readonly kind: "execution";
6
+ constructor(contextId: string, value: Omit<ExecutionValue, 'processes' | 'relationChanges'>, parentId: string);
7
+ toJSON(): ExecutionData;
8
+ }
@@ -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{InvocationRecord}from"../invocation/record.js";import{snapshotValue}from"../value/snapshot.js";class ExecutionRecord extends InvocationRecord{static{__name(this,"ExecutionRecord")}contextId;kind="execution";constructor(contextId,value,parentId){super(snapshotValue({...value,processes:[],relationChanges:[]}),parentId),this.contextId=contextId,Object.freeze(this)}toJSON(){return{...super.toJSON(),contextId:this.contextId,status:this.status}}}export{ExecutionRecord};
@@ -0,0 +1,30 @@
1
+ export { CallableRecord, type CallableRecordOptions } from './callable/record.js';
2
+ export { CallableRecordHelper } from './callable/helper.js';
3
+ export { BaseRecord } from './record.js';
4
+ export { CompositeRecord } from './composite.js';
5
+ export { InvocationRecord, type ConcreteInvocationRecord } from './invocation/record.js';
6
+ export { InvocationRecordHelper } from './invocation/helper.js';
7
+ export { RecordingRootRecord } from './root/record.js';
8
+ export { RecordingRootHelper } from './root/helper.js';
9
+ export { ExecutionRecord } from './execution/record.js';
10
+ export { ExecutionRecordHelper } from './execution/helper.js';
11
+ export { OperationRecord, type OperationRecordOptions } from './operation/record.js';
12
+ export { OperationRecordHelper } from './operation/helper.js';
13
+ export { AttemptRecord, type AttemptRecordOptions } from './attempt/record.js';
14
+ export { AttemptRecordHelper } from './attempt/helper.js';
15
+ export { RecordBook, type RecordBookState } from './book.js';
16
+ export { InvocationBoundaryRecord, type InvocationBoundaryRecordOptions } from './invocation/boundary/record.js';
17
+ export { InvocationBoundaryRecordHelper } from './invocation/boundary/helper.js';
18
+ export { MemoryRecord, type MemoryRecordOptions } from './memory/record.js';
19
+ export { MemoryRecordHelper } from './memory/helper.js';
20
+ export { observeMemory } from './memory/observe.js';
21
+ export { TranscriptRecord, type TranscriptRecordOptions } from './transcript/record.js';
22
+ export { TranscriptRecordHelper } from './transcript/helper.js';
23
+ export { RecordTree } from './tree/tree.js';
24
+ export { ResourceRecord, type ResourceRecordOptions } from './resource/record.js';
25
+ export { RuntimeCallRecord } from './runtime/record.js';
26
+ export { Recorder, type RecorderOptions, type RecordClock } from './recorder.js';
27
+ export { snapshotValue } from './value/snapshot.js';
28
+ export type { RecordChangeSource } from './source.js';
29
+ export { RecordingError, writeRecord } from './error.js';
30
+ export { RecordResource, type RecordReader, type RecordCreator } from './resource.js';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ import{CallableRecord}from"./callable/record.js";import{CallableRecordHelper}from"./callable/helper.js";import{BaseRecord}from"./record.js";import{CompositeRecord}from"./composite.js";import{InvocationRecord}from"./invocation/record.js";import{InvocationRecordHelper}from"./invocation/helper.js";import{RecordingRootRecord}from"./root/record.js";import{RecordingRootHelper}from"./root/helper.js";import{ExecutionRecord}from"./execution/record.js";import{ExecutionRecordHelper}from"./execution/helper.js";import{OperationRecord}from"./operation/record.js";import{OperationRecordHelper}from"./operation/helper.js";import{AttemptRecord}from"./attempt/record.js";import{AttemptRecordHelper}from"./attempt/helper.js";import{RecordBook}from"./book.js";import{InvocationBoundaryRecord}from"./invocation/boundary/record.js";import{InvocationBoundaryRecordHelper}from"./invocation/boundary/helper.js";import{MemoryRecord}from"./memory/record.js";import{MemoryRecordHelper}from"./memory/helper.js";import{observeMemory}from"./memory/observe.js";import{TranscriptRecord}from"./transcript/record.js";import{TranscriptRecordHelper}from"./transcript/helper.js";import{RecordTree}from"./tree/tree.js";import{ResourceRecord}from"./resource/record.js";import{RuntimeCallRecord}from"./runtime/record.js";import{Recorder}from"./recorder.js";import{snapshotValue}from"./value/snapshot.js";import{RecordingError,writeRecord}from"./error.js";import{RecordResource}from"./resource.js";export{AttemptRecord,AttemptRecordHelper,BaseRecord,CallableRecord,CallableRecordHelper,CompositeRecord,ExecutionRecord,ExecutionRecordHelper,InvocationBoundaryRecord,InvocationBoundaryRecordHelper,InvocationRecord,InvocationRecordHelper,MemoryRecord,MemoryRecordHelper,OperationRecord,OperationRecordHelper,RecordBook,RecordResource,RecordTree,Recorder,RecordingError,RecordingRootHelper,RecordingRootRecord,ResourceRecord,RuntimeCallRecord,TranscriptRecord,TranscriptRecordHelper,observeMemory,snapshotValue,writeRecord};
@@ -0,0 +1,18 @@
1
+ import type { InvocationBoundaryValue } from '@weiliang0121/capix-protocol';
2
+ import type { Recorder } from '../../recorder.js';
3
+ import type { RecordBook } from '../../book.js';
4
+ import { InvocationBoundaryRecord } from './record.js';
5
+ export declare class InvocationBoundaryRecordHelper {
6
+ static create(recorder: Recorder, location: {
7
+ start: number;
8
+ scopeId?: string;
9
+ executionId?: string;
10
+ callId: string;
11
+ occurredAt?: string;
12
+ offsetMs?: number;
13
+ }, type: InvocationBoundaryValue['type']): InvocationBoundaryRecord;
14
+ static get(book: RecordBook, id: string): InvocationBoundaryRecord;
15
+ static findByExecution(recorder: Recorder, executionId: string): readonly InvocationBoundaryRecord[];
16
+ static findByScope(recorder: Recorder, scopeId: string): readonly InvocationBoundaryRecord[];
17
+ static last(recorder: Recorder, scopeId: string): InvocationBoundaryRecord | undefined;
18
+ }
@@ -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{CallableRecord}from"../../callable/record.js";import{sortBy}from"es-toolkit/array";import{isFinite}from"es-toolkit/compat";import{ExecutionRecord}from"../../execution/record.js";import{RuntimeCallRecord}from"../../runtime/record.js";import{InvocationRecord}from"../record.js";import{InvocationBoundaryRecord}from"./record.js";class InvocationBoundaryRecordHelper{static{__name(this,"InvocationBoundaryRecordHelper")}static create(recorder,location,type){const scopeId=location.scopeId??location.executionId??location.callId,timingRecord=recorder.book.get(scopeId);if(!(timingRecord instanceof CallableRecord||timingRecord instanceof ExecutionRecord||timingRecord instanceof RuntimeCallRecord))throw new Error("Invocation timing scope does not exist");const invocationRecord=recorder.book.get(location.callId);if(!(invocationRecord instanceof InvocationRecord)||invocationRecord!==timingRecord&&!recorder.tree.descendants(timingRecord.id).includes(invocationRecord))throw new Error("Boundary target is outside its timing scope");const expectedStatus=type==="call"?"running":type==="return"?"succeeded":"failed";if(invocationRecord.status!==expectedStatus)throw new Error("Boundary does not match the invocation work state");const previous=this.last(recorder,scopeId),offsetMs=location.offsetMs??recorder.clock.tick()-location.start;if(!isFinite(offsetMs)||offsetMs<(previous?.offsetMs??0))throw new Error("Invalid invocation boundary time");const record=new InvocationBoundaryRecord({scopeId,...timingRecord instanceof ExecutionRecord?{executionId:timingRecord.id}:{},callId:invocationRecord.id,sequence:(previous?.sequence??0)+1,occurredAt:location.occurredAt??recorder.clock.now(),offsetMs},{type});return recorder.add(record)}static get(book,id){const record=book.get(id);if(!(record instanceof InvocationBoundaryRecord))throw new Error("Invocation boundary record does not exist");return record}static findByExecution(recorder,executionId){if(!(recorder.book.get(executionId)instanceof ExecutionRecord))throw new Error("Execution does not exist");return this.findByScope(recorder,executionId)}static findByScope(recorder,scopeId){const timingRecord=recorder.book.get(scopeId);if(!(timingRecord instanceof CallableRecord||timingRecord instanceof ExecutionRecord||timingRecord instanceof RuntimeCallRecord))throw new Error("Invocation timing scope does not exist");return sortBy(recorder.tree.descendants(scopeId).filter(record=>record instanceof InvocationBoundaryRecord&&record.scopeId===scopeId),[boundary=>boundary.sequence])}static last(recorder,scopeId){return this.findByScope(recorder,scopeId).at(-1)}}export{InvocationBoundaryRecordHelper};
@@ -0,0 +1,16 @@
1
+ import type { InvocationBoundaryRecord as BoundaryData, InvocationBoundaryValue } from '@weiliang0121/capix-protocol';
2
+ import { BaseRecord } from '../../record.js';
3
+ export type InvocationBoundaryRecordOptions = Omit<BoundaryData, 'id' | 'value' | 'parentId' | 'scopeId'> & {
4
+ readonly scopeId?: string;
5
+ };
6
+ export declare class InvocationBoundaryRecord extends BaseRecord<InvocationBoundaryValue> implements BoundaryData {
7
+ readonly kind: "invocation-boundary";
8
+ readonly scopeId: string;
9
+ readonly executionId?: string;
10
+ readonly callId: string;
11
+ readonly sequence: number;
12
+ readonly occurredAt: string;
13
+ readonly offsetMs: number;
14
+ constructor(options: InvocationBoundaryRecordOptions, value: Pick<InvocationBoundaryValue, 'type'>);
15
+ toJSON(): BoundaryData;
16
+ }
@@ -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{pick}from"es-toolkit/object";import{BaseRecord}from"../../record.js";class InvocationBoundaryRecord extends BaseRecord{static{__name(this,"InvocationBoundaryRecord")}kind="invocation-boundary";scopeId;executionId;callId;sequence;occurredAt;offsetMs;constructor(options,value){super(Object.freeze({type:value.type,scope:"work"}),options.callId),this.scopeId=options.scopeId??options.executionId??options.callId,this.executionId=options.executionId,this.callId=options.callId,this.sequence=options.sequence,this.occurredAt=options.occurredAt,this.offsetMs=options.offsetMs,Object.freeze(this)}toJSON(){return{...super.toJSON(),...pick(this,["scopeId","callId","sequence","occurredAt","offsetMs"]),...this.executionId?{executionId:this.executionId}:{}}}}export{InvocationBoundaryRecord};
@@ -0,0 +1,5 @@
1
+ import type { Recorder } from '../recorder.js';
2
+ import type { ConcreteInvocationRecord } from './record.js';
3
+ export declare class InvocationRecordHelper {
4
+ static finish(recorder: Pick<Recorder, 'update'>, record: ConcreteInvocationRecord, apply: (record: ConcreteInvocationRecord) => void): void;
5
+ }
@@ -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});class InvocationRecordHelper{static{__name(this,"InvocationRecordHelper")}static finish(recorder,record,apply){recorder.update(record,apply,record2=>({kind:"finished",id:record2.id,status:record2.status,result:{...Object.hasOwn(record2.value,"output")?{output:record2.value.output}:{},...Object.hasOwn(record2.value,"resultOf")?{resultOf:record2.value.resultOf}:{},...record2.value.error?{error:record2.value.error}:{},...record2.value.failure?{failure:record2.value.failure}:{}}}))}}export{InvocationRecordHelper};
@@ -0,0 +1,20 @@
1
+ import type { CallableRecord } from '../callable/record.js';
2
+ import type { RuntimeCallRecord } from '../runtime/record.js';
3
+ import type { ExecutionRecord } from '../execution/record.js';
4
+ import type { OperationRecord } from '../operation/record.js';
5
+ import type { AttemptRecord } from '../attempt/record.js';
6
+ import { type InvocationValue, type ProcessRecord, type RelationChangeRecord } from '@weiliang0121/capix-protocol';
7
+ import type { RuntimeErrorValue, InvocationFailureFact } from '@weiliang0121/capix-contracts';
8
+ import { CompositeRecord } from '../composite.js';
9
+ import { restoreStatus } from '../restoration/access.js';
10
+ export type ConcreteInvocationRecord = CallableRecord | RuntimeCallRecord | ExecutionRecord | OperationRecord | AttemptRecord;
11
+ export declare class InvocationRecord<Value extends InvocationValue> extends CompositeRecord<Value> {
12
+ #private;
13
+ get status(): "running" | "succeeded" | "failed";
14
+ protected requireRunning(): void;
15
+ [restoreStatus](status: 'running' | 'succeeded' | 'failed'): void;
16
+ append(process: ProcessRecord): void;
17
+ appendRelation(relation: RelationChangeRecord): void;
18
+ complete(output: unknown, resultOf?: number): void;
19
+ fail(error: RuntimeErrorValue, failure?: InvocationFailureFact): void;
20
+ }
@@ -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{outputProcess,finalOutputProcess}from"@weiliang0121/capix-protocol";import{CompositeRecord}from"../composite.js";import{isUndefined}from"es-toolkit/predicate";import{snapshotValue}from"../value/snapshot.js";import{restoreStatus}from"../restoration/access.js";class InvocationRecord extends CompositeRecord{static{__name(this,"InvocationRecord")}#status="running";get status(){return this.#status}requireRunning(){if(this.requireWritable(),this.#status!=="running")throw new Error("Record has already ended")}[restoreStatus](status){this.requireWritable(),this.#status=status}append(process){if(this.requireRunning(),process.sequence!==this.value.processes.length+1)throw new Error("Process sequence must advance in order");if("resultOf"in process){if(Object.hasOwn(process,"output"))throw new Error("Output and local result reference are mutually exclusive");const target=outputProcess(this.value,process.resultOf,process.sequence);if(process.stage!=="receive"||target.stage!=="execute"||target.round!==process.round||target.sequence!==process.sequence-1)throw new Error("Receive may only reuse its own execution result")}const captured=snapshotValue(process);this.replaceValue(Object.freeze({...this.value,processes:Object.freeze([...this.value.processes,captured])}))}appendRelation(relation){if(this.requireRunning(),!Number.isSafeInteger(relation.eventSequence)||relation.eventSequence<1)throw new Error("Relation fact requires an event sequence");const last=this.value.relationChanges.at(-1);if(last&&relation.eventSequence<=last.eventSequence)throw new Error("Relation fact sequence must advance");const captured=snapshotValue(relation);this.replaceValue(Object.freeze({...this.value,relationChanges:Object.freeze([...this.value.relationChanges,captured])}))}complete(output,resultOf){this.requireRunning(),isUndefined(resultOf)?this.replaceValue(Object.freeze({...this.value,output:snapshotValue(output)})):(finalOutputProcess(this.value,resultOf),this.replaceValue(Object.freeze({...this.value,resultOf}))),this.#status="succeeded"}fail(error,failure){this.requireRunning(),this.replaceValue(Object.freeze({...this.value,error:snapshotValue(error),...failure?{failure:snapshotValue(failure)}:{}})),this.#status="failed"}}export{InvocationRecord};
@@ -0,0 +1,7 @@
1
+ import type { MemoryRecordValue } from '@weiliang0121/capix-protocol';
2
+ import type { RecordBook } from '../book.js';
3
+ import { MemoryRecord, type MemoryRecordOptions } from './record.js';
4
+ export declare class MemoryRecordHelper {
5
+ static create(options: MemoryRecordOptions, value: MemoryRecordValue): MemoryRecord;
6
+ static find(book: RecordBook, memoryId: string): readonly MemoryRecord[];
7
+ }
@@ -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{MemoryRecord}from"./record.js";class MemoryRecordHelper{static{__name(this,"MemoryRecordHelper")}static create(options,value){return new MemoryRecord(options,value)}static find(book,memoryId){return[...book.values()].filter(record=>record instanceof MemoryRecord&&record.memoryId===memoryId)}}export{MemoryRecordHelper};
@@ -0,0 +1,10 @@
1
+ import type { MemoryContent, MemoryObservation } from '@weiliang0121/capix-protocol';
2
+ import type { RecordBook } from '../book.js';
3
+ export declare function observeMemory(collection: {
4
+ readonly transcript: {
5
+ readonly id: string;
6
+ };
7
+ values(): readonly (MemoryContent & {
8
+ readonly id: string;
9
+ })[];
10
+ }, book: RecordBook): MemoryObservation;
@@ -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{MemoryRecord}from"./record.js";function observeMemory(collection,book){const records=new Map;for(const record of book.values()){if(!(record instanceof MemoryRecord))continue;const own=records.get(record.memoryId);own?own.push(record):records.set(record.memoryId,[record])}return{items:collection.values().map(memory=>({id:memory.id,topic:memory.topic,content:memory.content,sources:memory.sourceIndexes.map(index=>({transcriptId:collection.transcript.id,index})),...memory.sourceResults?{sourceResults:memory.sourceResults}:{},records:(records.get(memory.id)??[]).map(record=>record.toJSON())}))}}__name(observeMemory,"observeMemory");export{observeMemory};
@@ -0,0 +1,21 @@
1
+ import type { MemoryRecord as MemoryRecordData, MemoryRecordValue } from '@weiliang0121/capix-protocol';
2
+ import type { RecordChangeSource } from '../source.js';
3
+ import { BaseRecord } from '../record.js';
4
+ export interface MemoryRecordOptions {
5
+ memoryId: string;
6
+ memoriesId: string;
7
+ sequence: number;
8
+ source?: RecordChangeSource;
9
+ }
10
+ export declare class MemoryRecord extends BaseRecord<MemoryRecordValue> implements MemoryRecordData {
11
+ readonly kind: "memory";
12
+ readonly memoryId: string;
13
+ readonly memoriesId: string;
14
+ readonly sequence: number;
15
+ readonly executionId?: string;
16
+ readonly operationId?: string;
17
+ readonly contextId?: string;
18
+ readonly callId?: string;
19
+ constructor(options: MemoryRecordOptions, value: MemoryRecordValue);
20
+ toJSON(): MemoryRecordData;
21
+ }
@@ -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{isSafeInteger}from"es-toolkit/compat";import{isString,isUndefined}from"es-toolkit/predicate";import{pick,omitBy}from"es-toolkit/object";import{BaseRecord}from"../record.js";import{snapshotValue}from"../value/snapshot.js";class MemoryRecord extends BaseRecord{static{__name(this,"MemoryRecord")}kind="memory";memoryId;memoriesId;sequence;executionId;operationId;contextId;callId;constructor(options,value){if(super(snapshotValue(value),options.source?.callId),!isString(options.memoriesId)||!/\S/u.test(options.memoriesId)||!isSafeInteger(options.sequence)||options.sequence<1)throw new Error("Memory change requires a scope and a positive sequence");this.memoryId=options.memoryId,this.memoriesId=options.memoriesId,this.sequence=options.sequence,this.executionId=options.source?.executionId,this.operationId=options.source?.operationId,this.contextId=options.source?.contextId,this.callId=options.source?.callId,Object.freeze(this)}toJSON(){return{...super.toJSON(),...pick(this,["memoryId","memoriesId","sequence"]),...omitBy(pick(this,["executionId","operationId","contextId","callId"]),isUndefined)}}}export{MemoryRecord};
@@ -0,0 +1,12 @@
1
+ import type { InvocationFailureFact, RuntimeErrorValue } from '@weiliang0121/capix-contracts';
2
+ import type { Recorder } from '../recorder.js';
3
+ import type { RecordBook } from '../book.js';
4
+ import { OperationRecord, type OperationRecordOptions } from './record.js';
5
+ export declare class OperationRecordHelper {
6
+ static create(recorder: Recorder, options: OperationRecordOptions, input: unknown): OperationRecord;
7
+ static get(book: RecordBook, id: string): OperationRecord;
8
+ static findByExecution(recorder: Recorder, executionId: string): readonly OperationRecord[];
9
+ static complete(recorder: Recorder, id: string, output: unknown, resultOf?: number): void;
10
+ static fail(recorder: Recorder, id: string, error: RuntimeErrorValue, failure?: InvocationFailureFact): void;
11
+ private static prepareFinish;
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{InvocationRecordHelper}from"../invocation/helper.js";import{AttemptRecordHelper}from"../attempt/helper.js";import{ExecutionRecord}from"../execution/record.js";import{OperationRecord}from"./record.js";class OperationRecordHelper{static{__name(this,"OperationRecordHelper")}static create(recorder,options,input){const book=recorder.book,execution=book.get(options.executionId);if(!(execution instanceof ExecutionRecord))throw new Error("Execution does not exist");if(execution.status!=="running")throw new Error("Record has already ended");if(options.parentOperationId){const parent=book.get(options.parentOperationId);if(!(parent instanceof OperationRecord)||parent.executionId!==options.executionId)throw new Error("Parent operation belongs to another execution or does not exist");if(parent.status!=="running")throw new Error("Record has already ended")}const record=new OperationRecord(options,input);return recorder.add(record)}static get(book,id){const record=book.get(id);if(!(record instanceof OperationRecord))throw new Error("Operation does not exist");return record}static findByExecution(recorder,executionId){if(!(recorder.book.get(executionId)instanceof ExecutionRecord))throw new Error("Execution does not exist");return recorder.tree.descendants(executionId).filter(record=>record instanceof OperationRecord)}static complete(recorder,id,output,resultOf){const record=this.prepareFinish(recorder,id);InvocationRecordHelper.finish(recorder,record,record2=>record2.complete(output,resultOf))}static fail(recorder,id,error,failure){const record=this.prepareFinish(recorder,id);InvocationRecordHelper.finish(recorder,record,record2=>record2.fail(error,failure))}static prepareFinish(recorder,id){const record=this.get(recorder.book,id);if(record.status!=="running")throw new Error("Record has already ended");if(recorder.tree.children(id).some(op=>op instanceof OperationRecord&&op.status==="running"))throw new Error("Cannot end a record with active operations");if(AttemptRecordHelper.findByOperation(recorder,id).some(attempt=>attempt.status==="running"))throw new Error("Cannot end a record with active attempts");return record}}export{OperationRecordHelper};
@@ -0,0 +1,17 @@
1
+ import type { OperationRecord as OperationData, InvocationValue } from '@weiliang0121/capix-protocol';
2
+ import { InvocationRecord } from '../invocation/record.js';
3
+ export type OperationRecordOptions = Omit<OperationData, 'id' | 'value' | 'status' | 'parentId' | 'childIds'>;
4
+ export declare class OperationRecord extends InvocationRecord<InvocationValue> implements OperationData {
5
+ readonly kind: "operation";
6
+ readonly contextId: string;
7
+ readonly executionId: string;
8
+ readonly operationInstanceId: string;
9
+ readonly parentOperationId?: string;
10
+ readonly operation: string;
11
+ readonly label: string;
12
+ readonly source: string;
13
+ readonly caller: string;
14
+ readonly callee: string;
15
+ constructor(options: OperationRecordOptions, input: unknown);
16
+ toJSON(): OperationData;
17
+ }
@@ -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{pick}from"es-toolkit/object";import{InvocationRecord}from"../invocation/record.js";import{snapshotValue}from"../value/snapshot.js";class OperationRecord extends InvocationRecord{static{__name(this,"OperationRecord")}kind="operation";contextId;executionId;operationInstanceId;parentOperationId;operation;label;source;caller;callee;constructor(options,input){super(snapshotValue({input,processes:[],relationChanges:[]}),options.parentOperationId??options.executionId),this.contextId=options.contextId,this.executionId=options.executionId,this.operationInstanceId=options.operationInstanceId,this.parentOperationId=options.parentOperationId,this.operation=options.operation,this.label=options.label,this.source=options.source,this.caller=options.caller,this.callee=options.callee,Object.freeze(this)}toJSON(){return{...super.toJSON(),status:this.status,...pick(this,["contextId","executionId","operationInstanceId","operation","label","source","caller","callee"]),...this.parentOperationId?{parentOperationId:this.parentOperationId}:{}}}}export{OperationRecord};
@@ -0,0 +1,16 @@
1
+ import type { RecordKind, BaseRecord as RecordData } from '@weiliang0121/capix-protocol';
2
+ import { restoreContent, sealHistorical } from './restoration/access.js';
3
+ export declare abstract class BaseRecord<Value> implements RecordData<Value> {
4
+ #private;
5
+ readonly kind: RecordKind;
6
+ constructor(value: Value, parentId?: string);
7
+ get id(): string;
8
+ get historical(): boolean;
9
+ get parentId(): string | undefined;
10
+ get value(): Value;
11
+ protected replaceValue(value: Value): void;
12
+ protected requireWritable(): void;
13
+ [restoreContent](id: string, value: Value): void;
14
+ [sealHistorical](): void;
15
+ toJSON(): RecordData<Value>;
16
+ }
package/dist/record.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{randomUUID}from"node:crypto";import{restoreContent,sealHistorical}from"./restoration/access.js";class BaseRecord{static{__name(this,"BaseRecord")}kind="custom";#id=randomUUID();#historical=!1;#value;#parentId;constructor(value,parentId){this.#parentId=parentId,this.#value=value}get id(){return this.#id}get historical(){return this.#historical}get parentId(){return this.#parentId}get value(){return this.#value}replaceValue(value){this.requireWritable(),this.#value=value}requireWritable(){if(this.#historical)throw new Error("Historical record is read-only")}[restoreContent](id,value){this.requireWritable(),this.#id=id,this.#value=value}[sealHistorical](){this.#historical=!0,Object.freeze(this)}toJSON(){return{id:this.id,...this.parentId?{parentId:this.parentId}:{},value:this.value}}}export{BaseRecord};
@@ -0,0 +1,28 @@
1
+ import type { RecordChangeEvent, RecordMutation } from '@weiliang0121/capix-protocol';
2
+ import type { ChangeCapture } from '@weiliang0121/capix-changes';
3
+ import { RecordBook } from './book.js';
4
+ import type { BaseRecord } from './record.js';
5
+ import { RecordTree } from './tree/tree.js';
6
+ export interface RecordClock {
7
+ now(): string;
8
+ tick(): number;
9
+ }
10
+ export interface RecorderOptions {
11
+ clock?: RecordClock;
12
+ changes?: ChangeCapture<RecordChangeEvent>;
13
+ }
14
+ export declare class Recorder {
15
+ #private;
16
+ readonly book: RecordBook;
17
+ readonly id: `${string}-${string}-${string}-${string}-${string}`;
18
+ get revision(): number;
19
+ readonly tree: RecordTree;
20
+ readonly clock: RecordClock;
21
+ private readonly changes?;
22
+ constructor(book: RecordBook, options?: RecorderOptions);
23
+ add<RecordType extends BaseRecord<unknown>>(record: RecordType): RecordType;
24
+ update<RecordType extends BaseRecord<unknown>>(record: RecordType, apply: (record: RecordType) => void, describe?: (record: RecordType) => RecordMutation): void;
25
+ private capture;
26
+ subscribe(listener: (record: BaseRecord<unknown>, change: 'add' | 'update', related: readonly BaseRecord<unknown>[]) => void): () => void;
27
+ private notify;
28
+ }
@@ -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{performance}from"node:perf_hooks";import{captureChange}from"@weiliang0121/capix-changes";import{snapshotValue}from"./value/snapshot.js";import"./book.js";import{RecordTree}from"./tree/tree.js";import{RecordRegistration}from"./registration.js";import{writeRecord}from"./error.js";class Recorder{static{__name(this,"Recorder")}book;id=randomUUID();#revision=0;get revision(){return this.#revision}tree;clock;changes;#registering=!1;#listeners=new Set;constructor(book,options={}){this.book=book,this.clock=options.clock??{now:__name(()=>new Date().toISOString(),"now"),tick:__name(()=>performance.now(),"tick")},this.changes=options.changes,this.tree=new RecordTree(book)}add(record){const related=writeRecord(()=>{if(this.#registering)throw new Error("Record registration cannot reenter");this.#registering=!0;try{return new RecordRegistration(this.book,this.tree,record).commit()}finally{this.#registering=!1}});return this.capture({kind:"added",entry:{kind:record.kind,data:record.toJSON()},...related[0]?{parent:{id:related[0].id,childId:record.id}}:{}}),this.notify(record,"add",related),record}update(record,apply,describe){writeRecord(()=>{if(this.#registering)throw new Error("Record registration cannot reenter");if(this.book.get(record.id)!==record)throw new Error("Record is not registered with this Recorder");if(record.historical)throw new Error("Historical record is read-only");apply(record)}),this.capture(describe?describe(record):{kind:"replaced",entry:{kind:record.kind,data:record.toJSON()}}),this.notify(record,"update")}capture(change){const revision=++this.#revision;if(!this.changes)return;const event=snapshotValue({type:"record",recorderId:this.id,revision,occurredAt:this.clock.now(),change});captureChange(this.changes,event)}subscribe(listener){return this.#listeners.add(listener),()=>{this.#listeners.delete(listener)}}notify(record,change,related=[]){for(const listener of this.#listeners)try{listener(record,change,related)}catch{console.error("\u8FD0\u884C\u8BB0\u5F55\u901A\u77E5\u5931\u8D25\uFF1B\u5DF2\u767B\u8BB0\u7684\u4E8B\u5B9E\u4FDD\u6301\u4E0D\u53D8\u3002")}}}export{Recorder};
@@ -0,0 +1,10 @@
1
+ import type { RecordBook } from './book.js';
2
+ import type { BaseRecord } from './record.js';
3
+ import type { RecordTree } from './tree/tree.js';
4
+ export declare class RecordRegistration<RecordType extends BaseRecord<unknown>> {
5
+ private readonly book;
6
+ private readonly record;
7
+ private readonly attachment;
8
+ constructor(book: RecordBook, tree: RecordTree, record: RecordType);
9
+ commit(): readonly BaseRecord<unknown>[];
10
+ }
@@ -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{removeRegistration,prepareAttachment}from"./tree/access.js";class RecordRegistration{static{__name(this,"RecordRegistration")}book;record;attachment;constructor(book,tree,record){this.book=book,this.record=record,this.attachment=tree[prepareAttachment](record)}commit(){try{this.book.add(this.record),this.attachment?.commit()}catch(error){throw this.attachment?.rollback(),this.book.get(this.record.id)===this.record&&this.book[removeRegistration](this.record),error}return Object.freeze(this.attachment?[this.attachment.parent]:[])}}export{RecordRegistration};
@@ -0,0 +1,15 @@
1
+ import type { ResourceRecord as ResourceRecordData } from '@weiliang0121/capix-protocol';
2
+ import { BaseRecord } from '../record.js';
3
+ export type ResourceRecordOptions = Omit<ResourceRecordData, 'id' | 'value'>;
4
+ export declare class ResourceRecord<Detail = unknown> extends BaseRecord<Detail> implements ResourceRecordData<Detail> {
5
+ readonly kind: "resource";
6
+ get parentId(): string;
7
+ readonly access: string;
8
+ readonly supplyId: string;
9
+ readonly sequence: number;
10
+ readonly occurredAt: string;
11
+ readonly phase: ResourceRecordData['phase'];
12
+ readonly interactionId?: string;
13
+ constructor(options: ResourceRecordOptions, detail: Detail);
14
+ toJSON(): ResourceRecordData<Detail>;
15
+ }
@@ -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{BaseRecord}from"../record.js";import{snapshotValue}from"../value/snapshot.js";class ResourceRecord extends BaseRecord{static{__name(this,"ResourceRecord")}kind="resource";get parentId(){return super.parentId}access;supplyId;sequence;occurredAt;phase;interactionId;constructor(options,detail){super(snapshotValue(detail),options.parentId),this.access=options.access,this.supplyId=options.supplyId,this.sequence=options.sequence,this.occurredAt=options.occurredAt,this.phase=options.phase,this.interactionId=options.interactionId,Object.freeze(this)}toJSON(){return{...super.toJSON(),parentId:this.parentId,access:this.access,supplyId:this.supplyId,sequence:this.sequence,occurredAt:this.occurredAt,phase:this.phase,...this.interactionId?{interactionId:this.interactionId}:{}}}}export{ResourceRecord};
@@ -0,0 +1,15 @@
1
+ import { ResourceOffer } from '@weiliang0121/capix-resources';
2
+ import type { RecordEntry } from '@weiliang0121/capix-protocol';
3
+ import type { RecordBookState } from './book.js';
4
+ import type { Recorder } from './recorder.js';
5
+ export interface RecordReader {
6
+ get(id: string): RecordEntry | undefined;
7
+ snapshot(): RecordBookState;
8
+ }
9
+ export interface RecordCreator {
10
+ create(value: unknown): RecordEntry;
11
+ }
12
+ export declare const RecordResource: Readonly<{
13
+ read: ResourceOffer<Recorder, RecordReader, Recorder, never>;
14
+ write: ResourceOffer<Recorder, RecordCreator, Recorder, never>;
15
+ }>;
@@ -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{ResourceOffer}from"@weiliang0121/capix-resources";import{BaseRecord}from"./record.js";import{snapshotValue}from"./value/snapshot.js";class CustomRecord extends BaseRecord{static{__name(this,"CustomRecord")}constructor(value){super(snapshotValue(value)),Object.freeze(this)}}function entrySnapshot(record){return snapshotValue({kind:record.kind,data:record.toJSON()})}__name(entrySnapshot,"entrySnapshot");const RecordResource=Object.freeze({read:new ResourceOffer({name:"records.read",expose:__name((recorder,activity)=>Object.freeze({get(id){return activity.runSync("get",{input:__name(()=>({id}),"input"),output:__name(entry=>({id,found:entry!==void 0}),"output")},()=>{const record=recorder.book.get(id);return record?entrySnapshot(record):void 0})},snapshot(){return activity.runSync("snapshot",{output:__name(state=>({count:state.entries.length}),"output")},()=>recorder.book.exportState())}}),"expose"),timing:"access",describe:__name(recorder=>({recorderId:recorder.id}),"describe")}),write:new ResourceOffer({name:"records.write",expose:__name((recorder,activity)=>Object.freeze({create(value){return activity.runSync("create",{output:__name(entry=>({id:entry.data.id,kind:entry.kind}),"output")},()=>entrySnapshot(recorder.add(new CustomRecord(value))))}}),"expose"),timing:"access",describe:__name(recorder=>({recorderId:recorder.id,kind:"custom"}),"describe")})});export{RecordResource};
@@ -0,0 +1,3 @@
1
+ export declare const restoreContent: unique symbol;
2
+ export declare const restoreStatus: unique symbol;
3
+ export declare const sealHistorical: unique symbol;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ const restoreContent=Symbol("restoreContent"),restoreStatus=Symbol("restoreStatus"),sealHistorical=Symbol("sealHistorical");export{restoreContent,restoreStatus,sealHistorical};
@@ -0,0 +1,2 @@
1
+ import { type RecordEntry } from '@weiliang0121/capix-protocol';
2
+ export declare function checkEntry(entry: RecordEntry): void;
@@ -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{hasOutput,validateInvocationRecordValue}from"@weiliang0121/capix-protocol";import{isPlainObject}from"es-toolkit/predicate";function fail(){throw new Error("Invalid stored record")}__name(fail,"fail");function object(value){return isPlainObject(value)?value:fail()}__name(object,"object");function text(value){(typeof value!="string"||!value.trim())&&fail()}__name(text,"text");function optionalText(value){value!==void 0&&text(value)}__name(optionalText,"optionalText");function integer(value,minimum=0){(typeof value!="number"||!Number.isSafeInteger(value)||value<minimum)&&fail()}__name(integer,"integer");function time(value){text(value),Number.isFinite(Date.parse(value))||fail()}__name(time,"time");function indexes(value,nonempty=!0){(!Array.isArray(value)||nonempty&&!value.length||new Set(value).size!==value.length)&&fail();for(const index of value)integer(index)}__name(indexes,"indexes");function sources(value){if(value===void 0)return;Array.isArray(value)||fail();const ids=new Set;for(const item of value){const source=object(item);text(source.id),(ids.has(source.id)||source.kind!=="file-created")&&fail(),ids.add(source.id),integer(source.answerIndex);const receipt=object(source.receipt);text(receipt.path),integer(receipt.bytes),(typeof receipt.digest!="string"||!/^[a-f0-9]{64}$/u.test(receipt.digest))&&fail()}}__name(sources,"sources");function children(value){(!Array.isArray(value)||new Set(value).size!==value.length)&&fail();for(const id of value)text(id)}__name(children,"children");function checkEntry(entry){const outer=object(entry);(Object.keys(outer).length!==2||!Object.hasOwn(outer,"kind")||!Object.hasOwn(outer,"data"))&&fail();const data=object(outer.data);if(text(data.id),optionalText(data.parentId),Object.hasOwn(data,"value")||fail(),["invocation","runtime","runtime-call","execution","operation","attempt"].includes(entry.kind)&&children(data.childIds),["invocation","runtime-call","execution","operation","attempt"].includes(entry.kind)){text(data.parentId),text(data.contextId),data.contextId===data.id&&fail(),validateInvocationRecordValue(data.value,data.contextId);const output=hasOutput(data.value),error=Object.hasOwn(data.value,"error");(data.status==="running"?output||error:data.status==="succeeded"?!output||error:data.status!=="failed"||!error||output)&&fail()}switch(entry.kind){case"invocation":["scene","group","node"].includes(data.structureKind)||fail();for(const name of["structureId","name","label","callee","role"])optionalText(data[name]);data.source!==void 0&&typeof data.source!="string"&&fail(),time(object(data.value).startedAt);break;case"runtime":time(object(data.value).createdAt);break;case"runtime-call":text(data.runtimeInstanceId),time(object(data.value).startedAt);break;case"execution":time(object(data.value).startedAt);break;case"operation":for(const name of["executionId","operationInstanceId","operation","label","caller","callee"])text(data[name]);typeof data.source!="string"&&fail(),optionalText(data.parentOperationId);break;case"attempt":for(const name of["operationId","name","label","caller","callee"])text(data[name]);typeof data.source!="string"&&fail();break;case"invocation-boundary":{text(data.scopeId),text(data.callId),optionalText(data.executionId),integer(data.sequence,1),time(data.occurredAt),(typeof data.offsetMs!="number"||!Number.isFinite(data.offsetMs)||data.offsetMs<0)&&fail();const value=object(data.value);(value.scope!=="work"||!["call","return","throw"].includes(value.type))&&fail();break}case"resource":for(const name of["parentId","access","supplyId"])text(data[name]);integer(data.sequence,1),time(data.occurredAt),["bound","available","unavailable","started","returned","threw"].includes(data.phase)||fail(),["started","returned","threw"].includes(data.phase)?text(data.interactionId):data.interactionId!==void 0&&fail();break;case"transcript":{text(data.transcriptId),integer(data.revision,1),time(data.occurredAt);const value=object(data.value);integer(value.start),integer(value.end),value.action==="append"?value.end<=value.start&&fail():value.action==="segment"?(integer(value.previousStart),(value.previousStart>=value.start||value.start>=value.end)&&fail()):fail(),checkContentSource(data);break}case"memory":{text(data.memoryId),text(data.memoriesId),integer(data.sequence,1),optionalText(data.operationId),checkContentSource(data);const value=object(data.value);value.action!=="create"&&value.action!=="update"&&fail(),text(value.change),indexes(value.sourceIndexes),sources(value.sourceResults);const result=object(value.result);text(result.topic),text(result.content),indexes(result.sourceIndexes),sources(result.sourceResults);break}case"custom":Object.hasOwn(data,"childIds")&&children(data.childIds);break;default:fail()}}__name(checkEntry,"checkEntry");function checkContentSource(data){optionalText(data.callId),optionalText(data.contextId),optionalText(data.executionId),data.callId===void 0!=(data.contextId===void 0)&&fail()}__name(checkContentSource,"checkContentSource");export{checkEntry};
@@ -0,0 +1,3 @@
1
+ import type { RecordEntry } from '@weiliang0121/capix-protocol';
2
+ import { BaseRecord } from '../record.js';
3
+ export declare function restoreEntry(entry: RecordEntry): BaseRecord<unknown>;
@@ -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{CallableRecord}from"../callable/record.js";import{isEqual}from"es-toolkit/predicate";import{BaseRecord}from"../record.js";import{CompositeRecord}from"../composite.js";import{InvocationRecord}from"../invocation/record.js";import{RecordingRootRecord}from"../root/record.js";import{RuntimeCallRecord}from"../runtime/record.js";import{ExecutionRecord}from"../execution/record.js";import{OperationRecord}from"../operation/record.js";import{AttemptRecord}from"../attempt/record.js";import{InvocationBoundaryRecord}from"../invocation/boundary/record.js";import{TranscriptRecord}from"../transcript/record.js";import{MemoryRecord}from"../memory/record.js";import{ResourceRecord}from"../resource/record.js";import{replaceChildren}from"../tree/access.js";import{restoreContent,restoreStatus}from"./access.js";import{checkEntry}from"./check.js";class HistoricalCustomRecord extends BaseRecord{static{__name(this,"HistoricalCustomRecord")}}class HistoricalCompositeRecord extends CompositeRecord{static{__name(this,"HistoricalCompositeRecord")}}function restoreEntry(entry){checkEntry(entry);const record=construct(entry);if(record[restoreContent](entry.data.id,entry.data.value),record instanceof CompositeRecord&&record[replaceChildren](entry.data.childIds),record instanceof InvocationRecord&&record[restoreStatus](entry.data.status),!isEqual(record.toJSON(),entry.data))throw new Error("Stored record does not match its declared kind");return record}__name(restoreEntry,"restoreEntry");function construct(entry){switch(entry.kind){case"invocation":{const data=entry.data;if(typeof data.value.startedAt!="string")throw new Error("Stored callable has no observed start");return new CallableRecord(data,{...data.value,startedAt:data.value.startedAt})}case"runtime":{const data=entry.data;return new RecordingRootRecord(data.value)}case"runtime-call":{const data=entry.data;return new RuntimeCallRecord(data.contextId,data.runtimeInstanceId,data.value,data.parentId)}case"execution":{const data=entry.data;return new ExecutionRecord(data.contextId,data.value,data.parentId)}case"operation":{const data=entry.data;return new OperationRecord(data,data.value.input)}case"attempt":{const data=entry.data;return new AttemptRecord(data,data.value.input)}case"invocation-boundary":{const data=entry.data;return new InvocationBoundaryRecord(data,data.value)}case"transcript":{const data=entry.data;return new TranscriptRecord({...data,source:data.callId?{callId:data.callId,contextId:data.contextId,executionId:data.executionId}:void 0},data.value)}case"memory":{const data=entry.data;return new MemoryRecord({...data,source:data.callId?{callId:data.callId,contextId:data.contextId,executionId:data.executionId,operationId:data.operationId}:void 0},data.value)}case"resource":{const data=entry.data;return new ResourceRecord(data,data.value)}case"custom":return Object.hasOwn(entry.data,"childIds")?new HistoricalCompositeRecord(entry.data.value,entry.data.parentId):new HistoricalCustomRecord(entry.data.value,entry.data.parentId)}}__name(construct,"construct");export{restoreEntry};
@@ -0,0 +1,2 @@
1
+ import type { RecordBook } from '../book.js';
2
+ export declare function checkRestoredTree(book: RecordBook): void;
@@ -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{CallableRecord}from"../callable/record.js";import{CompositeRecord}from"../composite.js";import{InvocationRecord}from"../invocation/record.js";import{InvocationBoundaryRecord}from"../invocation/boundary/record.js";import{ResourceRecord}from"../resource/record.js";import{checkRelation}from"../tree/relation.js";function checkRestoredTree(book){const contexts=new Set,boundaries=new Map,resources=new Map;for(const record of book.values()){const parent=record.parentId===void 0?void 0:book.get(record.parentId);if(record.parentId!==void 0&&!(parent instanceof CompositeRecord))throw new Error("Stored record parent is missing or cannot contain children");if(parent instanceof CompositeRecord&&!parent.childIds.includes(record.id))throw new Error("Stored record parent does not reference its child");if(record instanceof CompositeRecord)for(const childId of record.childIds){const child=book.get(childId);if(!child||child.parentId!==record.id)throw new Error("Inconsistent stored child reference")}if(checkRelation(record,parent,book,"restore"),record instanceof InvocationRecord&&"contextId"in record){const contextId=record.contextId;if(contexts.has(contextId)||book.get(contextId))throw new Error("Stored invocation context identity conflicts");contexts.add(contextId);for(const relation of record.value.relationChanges){const child=relation.childId===void 0?void 0:book.get(relation.childId);if(child&&(child.parentId!==record.id||!("contextId"in child)||child.contextId!==relation.identity.childContextId))throw new Error("Stored child relation points to another invocation")}}if(record instanceof InvocationBoundaryRecord){const invocation=book.get(record.callId);if(invocation instanceof CallableRecord){let scope2=invocation;const parents=new Set([scope2.id]);let parent2=scope2.parentId?book.get(scope2.parentId):void 0;for(;parent2 instanceof CallableRecord;){if(parents.has(parent2.id))throw new Error("Stored callable ancestry contains a cycle");parents.add(parent2.id),scope2=parent2,parent2=scope2.parentId?book.get(scope2.parentId):void 0}if(record.scopeId!==scope2.id||record.executionId!==void 0)throw new Error("Stored callable boundary has an inconsistent timing scope")}else if(record.scopeId!==(record.executionId??record.callId))throw new Error("Stored boundary has an inconsistent timing scope");const scope=boundaries.get(record.scopeId)??{sequence:0,offsetMs:0,calls:new Map};if(record.sequence!==scope.sequence+1||record.offsetMs<scope.offsetMs)throw new Error("Stored boundary sequence does not advance");const prior=scope.calls.get(record.callId);if(record.value.type==="call"?prior!==void 0:prior!=="call")throw new Error("Stored boundary does not follow its call");const call=book.get(record.callId);if(record.value.type==="call"&&record.callId!==record.scopeId&&scope.calls.get(call.parentId)!=="call")throw new Error("Stored child boundary starts outside its parent work");if(record.value.type==="call"&&record.callId===record.scopeId&&record.sequence!==1)throw new Error("Stored work scope must start before its children");if(record.value.type!=="call"&&[...scope.calls].some(([id,state])=>state==="call"&&book.get(id)?.parentId===record.callId))throw new Error("Stored parent boundary ends before its active child");scope.sequence=record.sequence,scope.offsetMs=record.offsetMs,scope.calls.set(record.callId,record.value.type),boundaries.set(record.scopeId,scope)}if(record instanceof ResourceRecord){const scope=resources.get(record.parentId)??{sequence:0,accesses:new Map,interactions:new Map};if(record.sequence!==scope.sequence+1)throw new Error("Stored resource sequence does not advance");const key=JSON.stringify([record.supplyId,record.access]);if(record.phase==="bound"){if(scope.accesses.has(key))throw new Error("Stored resource access is already bound");scope.accesses.set(key,record.phase)}else if(record.phase==="available"||record.phase==="unavailable"){if(scope.accesses.get(key)!=="bound")throw new Error("Stored resource access is not bound");scope.accesses.set(key,record.phase)}else if(record.phase==="started"){if(scope.accesses.get(key)!=="available"||scope.interactions.has(record.interactionId))throw new Error("Stored resource interaction is not available");scope.interactions.set(record.interactionId,key)}else{if(scope.interactions.get(record.interactionId)!==key)throw new Error("Stored resource interaction has not started");scope.interactions.delete(record.interactionId)}scope.sequence=record.sequence,resources.set(record.parentId,scope)}}}__name(checkRestoredTree,"checkRestoredTree");export{checkRestoredTree};
@@ -0,0 +1,5 @@
1
+ import type { Recorder } from '../recorder.js';
2
+ import { RecordingRootRecord } from './record.js';
3
+ export declare class RecordingRootHelper {
4
+ static create(recorder: Recorder): RecordingRootRecord;
5
+ }
@@ -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{RecordingRootRecord}from"./record.js";class RecordingRootHelper{static{__name(this,"RecordingRootHelper")}static create(recorder){return recorder.add(new RecordingRootRecord({createdAt:recorder.clock.now()}))}}export{RecordingRootHelper};
@@ -0,0 +1,6 @@
1
+ import type { RecordingRootRecord as RecordingRootData, RecordingRootValue } from '@weiliang0121/capix-protocol';
2
+ import { CompositeRecord } from '../composite.js';
3
+ export declare class RecordingRootRecord extends CompositeRecord<RecordingRootValue> implements RecordingRootData {
4
+ readonly kind: "runtime";
5
+ constructor(value: RecordingRootValue);
6
+ }
@@ -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{CompositeRecord}from"../composite.js";import{snapshotValue}from"../value/snapshot.js";class RecordingRootRecord extends CompositeRecord{static{__name(this,"RecordingRootRecord")}kind="runtime";constructor(value){super(snapshotValue(value)),Object.freeze(this)}}export{RecordingRootRecord};
@@ -0,0 +1,9 @@
1
+ import type { RuntimeCallRecord as RuntimeCallData, RuntimeCallValue } from '@weiliang0121/capix-protocol';
2
+ import { InvocationRecord } from '../invocation/record.js';
3
+ export declare class RuntimeCallRecord extends InvocationRecord<RuntimeCallValue> implements RuntimeCallData {
4
+ readonly contextId: string;
5
+ readonly runtimeInstanceId: string;
6
+ readonly kind: "runtime-call";
7
+ constructor(contextId: string, runtimeInstanceId: string, value: Omit<RuntimeCallValue, 'processes' | 'relationChanges'>, parentId: string);
8
+ toJSON(): RuntimeCallData;
9
+ }
@@ -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{InvocationRecord}from"../invocation/record.js";import{snapshotValue}from"../value/snapshot.js";class RuntimeCallRecord extends InvocationRecord{static{__name(this,"RuntimeCallRecord")}contextId;runtimeInstanceId;kind="runtime-call";constructor(contextId,runtimeInstanceId,value,parentId){super(snapshotValue({...value,processes:[],relationChanges:[]}),parentId),this.contextId=contextId,this.runtimeInstanceId=runtimeInstanceId,Object.freeze(this)}toJSON(){return{...super.toJSON(),contextId:this.contextId,runtimeInstanceId:this.runtimeInstanceId,status:this.status}}}export{RuntimeCallRecord};
@@ -0,0 +1,6 @@
1
+ export interface RecordChangeSource {
2
+ readonly contextId: string;
3
+ readonly callId: string;
4
+ readonly executionId?: string;
5
+ readonly operationId?: string;
6
+ }
package/dist/source.js ADDED
@@ -0,0 +1 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
@@ -0,0 +1,6 @@
1
+ import type { TranscriptChange } from '@weiliang0121/capix-protocol';
2
+ import type { RecordClock } from '../recorder.js';
3
+ import { TranscriptRecord, type TranscriptRecordOptions } from './record.js';
4
+ export declare class TranscriptRecordHelper {
5
+ static create(clock: Pick<RecordClock, 'now'>, options: Omit<TranscriptRecordOptions, 'occurredAt'>, value: TranscriptChange): TranscriptRecord;
6
+ }
@@ -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{TranscriptRecord}from"./record.js";class TranscriptRecordHelper{static{__name(this,"TranscriptRecordHelper")}static create(clock,options,value){return new TranscriptRecord({...options,occurredAt:clock.now()},value)}}export{TranscriptRecordHelper};
@@ -0,0 +1,20 @@
1
+ import type { TranscriptChange, TranscriptRecord as RecordData } from '@weiliang0121/capix-protocol';
2
+ import type { RecordChangeSource } from '../source.js';
3
+ import { BaseRecord } from '../record.js';
4
+ export interface TranscriptRecordOptions {
5
+ transcriptId: string;
6
+ revision: number;
7
+ occurredAt: string;
8
+ source?: RecordChangeSource;
9
+ }
10
+ export declare class TranscriptRecord extends BaseRecord<TranscriptChange> implements RecordData {
11
+ readonly kind: "transcript";
12
+ readonly transcriptId: string;
13
+ readonly revision: number;
14
+ readonly occurredAt: string;
15
+ readonly contextId?: string;
16
+ readonly callId?: string;
17
+ readonly executionId?: string;
18
+ constructor(options: TranscriptRecordOptions, value: TranscriptChange);
19
+ toJSON(): RecordData;
20
+ }
@@ -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{BaseRecord}from"../record.js";import{snapshotValue}from"../value/snapshot.js";class TranscriptRecord extends BaseRecord{static{__name(this,"TranscriptRecord")}kind="transcript";transcriptId;revision;occurredAt;contextId;callId;executionId;constructor(options,value){super(snapshotValue(value),options.source?.callId),this.transcriptId=options.transcriptId,this.revision=options.revision,this.occurredAt=options.occurredAt,this.contextId=options.source?.contextId,this.callId=options.source?.callId,this.executionId=options.source?.executionId,Object.freeze(this)}toJSON(){return{...super.toJSON(),transcriptId:this.transcriptId,revision:this.revision,occurredAt:this.occurredAt,...this.contextId?{contextId:this.contextId,callId:this.callId}:{},...this.executionId?{executionId:this.executionId}:{}}}}export{TranscriptRecord};
@@ -0,0 +1,3 @@
1
+ export declare const replaceChildren: unique symbol;
2
+ export declare const removeRegistration: unique symbol;
3
+ export declare const prepareAttachment: unique symbol;
@@ -0,0 +1,2 @@
1
+ /*! MIT License | Copyright (c) 2026 wei.liang | See LICENSE */
2
+ const replaceChildren=Symbol("replaceChildren"),removeRegistration=Symbol("removeRegistration"),prepareAttachment=Symbol("prepareAttachment");export{prepareAttachment,removeRegistration,replaceChildren};
@@ -0,0 +1,4 @@
1
+ import type { RecordBook } from '../book.js';
2
+ import type { BaseRecord } from '../record.js';
3
+ import { CompositeRecord } from '../composite.js';
4
+ export declare function checkRelation(record: BaseRecord<unknown>, parent: CompositeRecord<unknown> | undefined, book: RecordBook, mode?: 'register' | 'restore'): void;
@@ -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{CallableRecord}from"../callable/record.js";import{isUndefined}from"es-toolkit/predicate";import{CompositeRecord}from"../composite.js";import{RuntimeCallRecord}from"../runtime/record.js";import{RecordingRootRecord}from"../root/record.js";import{InvocationRecord}from"../invocation/record.js";import{ExecutionRecord}from"../execution/record.js";import{OperationRecord}from"../operation/record.js";import{AttemptRecord}from"../attempt/record.js";import{InvocationBoundaryRecord}from"../invocation/boundary/record.js";import{MemoryRecord}from"../memory/record.js";import{TranscriptRecord}from"../transcript/record.js";import{ResourceRecord}from"../resource/record.js";function checkRelation(record,parent,book,mode="register"){if(record instanceof CallableRecord&&!(parent instanceof RecordingRootRecord||parent instanceof CallableRecord))throw new Error("Callable record requires its recording root or direct callable parent");if(record instanceof CallableRecord&&parent instanceof CallableRecord&&parent.structureKind==="node")throw new Error("A node record cannot own child calls");if(record instanceof CallableRecord&&parent instanceof CallableRecord&&record.structureKind==="scene")throw new Error("A scene record cannot be a member call");if(record instanceof RecordingRootRecord&&parent)throw new Error("Recording root cannot have a parent record");if(record instanceof RuntimeCallRecord&&!(parent instanceof RecordingRootRecord))throw new Error("Runtime call record requires a recording root parent");if(record instanceof ExecutionRecord&&!(parent instanceof RuntimeCallRecord))throw new Error("Execution record requires a Runtime call record parent");if(record instanceof OperationRecord){if(!(parent instanceof ExecutionRecord||parent instanceof OperationRecord))throw new Error("Operation requires an execution or operation parent");if(record.parentId!==(record.parentOperationId??record.executionId))throw new Error("Inconsistent operation parent")}if(record instanceof AttemptRecord&&(!(parent instanceof OperationRecord)||record.operationId!==parent.id))throw new Error("Attempt requires an operation parent");if(record instanceof InvocationBoundaryRecord&&!(parent instanceof InvocationRecord))throw new Error("Invocation boundary record requires an invocation record parent");if(record instanceof ResourceRecord&&!(parent instanceof InvocationRecord||parent instanceof RecordingRootRecord))throw new Error("Resource record requires a recording root or invocation record parent");if(mode==="register"&&record instanceof ResourceRecord&&parent instanceof InvocationRecord&&parent.status!=="running")throw new Error("Resource access owner has ended");const content=record instanceof MemoryRecord||record instanceof TranscriptRecord;if(!parent){if(content&&(!isUndefined(record.callId)||!isUndefined(record.contextId)||!isUndefined(record.executionId)||record instanceof MemoryRecord&&!isUndefined(record.operationId)))throw new Error("Content source requires a call parent");return}if(content&&!(parent instanceof InvocationRecord))throw new Error("Content source requires a call parent");const ancestors=[],seen=new Set([record.id]);for(let current=parent;current;current=isUndefined(current.parentId)?void 0:book.get(current.parentId)){if(!(current instanceof CompositeRecord)||seen.has(current.id))throw new Error("Invalid record ancestry");if(seen.add(current.id),ancestors.push(current),!isUndefined(current.parentId)&&!book.get(current.parentId))throw new Error("Record ancestor does not exist")}const execution=ancestors.find(ancestor=>ancestor instanceof ExecutionRecord);if((record instanceof OperationRecord||record instanceof InvocationBoundaryRecord||content)&&record.executionId!==execution?.id)throw new Error("Record belongs to another execution");if(record instanceof InvocationBoundaryRecord){const expected=record.value.type==="call"?"running":record.value.type==="return"?"succeeded":"failed";if(!(parent instanceof InvocationRecord)||record.callId!==parent.id||(mode==="register"||record.value.type!=="call")&&parent.status!==expected)throw new Error("Boundary does not match the invocation record state");return}if(mode==="register"&&record instanceof InvocationRecord&&ancestors.some(ancestor=>ancestor instanceof InvocationRecord&&ancestor.status!=="running"))throw new Error("Record has already ended");if(content){if(record.callId!==parent.id||record.contextId!==("contextId"in parent?parent.contextId:void 0))throw new Error("Content source does not match its call");if(record instanceof MemoryRecord){const operation=ancestors.find(ancestor=>ancestor instanceof OperationRecord);if(record.operationId!==operation?.id)throw new Error("Content source does not match its operation")}}}__name(checkRelation,"checkRelation");export{checkRelation};
@@ -0,0 +1,17 @@
1
+ import type { RecordBook } from '../book.js';
2
+ import type { BaseRecord } from '../record.js';
3
+ import { CompositeRecord } from '../composite.js';
4
+ import { prepareAttachment } from './access.js';
5
+ export declare class RecordTree {
6
+ private readonly book;
7
+ constructor(book: RecordBook);
8
+ children(id: string): readonly BaseRecord<unknown>[];
9
+ descendants(id: string): readonly BaseRecord<unknown>[];
10
+ root(id: string): BaseRecord<unknown>;
11
+ [prepareAttachment](record: BaseRecord<unknown>): {
12
+ parent: CompositeRecord<any>;
13
+ commit: () => void;
14
+ rollback: () => void;
15
+ } | undefined;
16
+ private require;
17
+ }
@@ -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{isUndefined}from"es-toolkit/predicate";import{CompositeRecord}from"../composite.js";import{replaceChildren,prepareAttachment}from"./access.js";import{checkRelation}from"./relation.js";class RecordTree{static{__name(this,"RecordTree")}book;constructor(book){this.book=book}children(id){const record=this.require(id);return record instanceof CompositeRecord?record.childIds.map(childId=>{const child=this.require(childId);if(child.parentId!==id)throw new Error("Inconsistent record parent");return child}):[]}descendants(id){const result=[],pending=[...this.children(id)].reverse(),visited=new Set([id]);for(let record=pending.pop();record;record=pending.pop()){if(visited.has(record.id))throw new Error("Cyclic or duplicate record relation");visited.add(record.id),result.push(record),pending.push(...[...this.children(record.id)].reverse())}return result}root(id){let record=this.require(id);const visited=new Set([id]);for(;!isUndefined(record.parentId);){const parent=this.require(record.parentId);if(visited.has(parent.id))throw new Error("Cyclic record relation");if(!(parent instanceof CompositeRecord)||!parent.childIds.includes(record.id))throw new Error("Inconsistent record parent");visited.add(parent.id),record=parent}return record}[prepareAttachment](record){if(record.historical)throw new Error("Historical record cannot be registered again");if(this.book.get(record.id))throw new Error("Record ID already exists");if(record instanceof CompositeRecord&&record.childIds.length)throw new Error("New composite record must have no children");const parent=isUndefined(record.parentId)?void 0:this.require(record.parentId);if(parent?.historical)throw new Error("Historical record is read-only");if(parent&&!(parent instanceof CompositeRecord))throw new Error("Record parent cannot contain children");if(checkRelation(record,parent,this.book),!parent)return;const previous=parent.childIds;if(previous.includes(record.id))throw new Error("Record is already attached");const next=Object.freeze([...previous,record.id]);return{parent,commit:__name(()=>parent[replaceChildren](next),"commit"),rollback:__name(()=>parent[replaceChildren](previous),"rollback")}}require(id){const record=this.book.get(id);if(!record)throw new Error("Record does not exist");return record}}export{RecordTree};
@@ -0,0 +1 @@
1
+ export declare function assertRecordContent(value: unknown): void;
@@ -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{isArray,isFinite,isObject}from"es-toolkit/compat";import{isBoolean,isFunction,isNull,isString}from"es-toolkit/predicate";function assertRecordContent(value){checkContent(value,new Set)}__name(assertRecordContent,"assertRecordContent");function checkContent(value,ancestors){if(!(isNull(value)||isString(value)||isBoolean(value))&&!isFinite(value)){if(!isObject(value)||isFunction(value))throw new TypeError("Unsupported record content");if(ancestors.has(value))throw new TypeError("Record content must not be cyclic");if(!isArray(value)&&Object.getPrototypeOf(value)!==Object.prototype&&!isNull(Object.getPrototypeOf(value)))throw new TypeError("Record content must use plain objects and arrays");ancestors.add(value);try{for(const item of Object.values(value))checkContent(item,ancestors)}finally{ancestors.delete(value)}}}__name(checkContent,"checkContent");export{assertRecordContent};
@@ -0,0 +1 @@
1
+ export declare function copyContent<Content>(value: Content): Content;
@@ -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{isFunction,isNull}from"es-toolkit/predicate";import{isArray,isObject}from"es-toolkit/compat";function copyContent(value){return copyValue(value,new Set)}__name(copyContent,"copyContent");function copyValue(value,ancestors){if(!isObject(value)||isFunction(value))return structuredClone(value);if(ancestors.has(value))throw new TypeError("Record content must not be cyclic");if(!isArray(value)&&Object.getPrototypeOf(value)!==Object.prototype&&!isNull(Object.getPrototypeOf(value)))throw new TypeError("Record content must use plain objects and arrays");ancestors.add(value);try{return isArray(value)?value.map(entry=>copyValue(entry,ancestors)):Object.fromEntries(Object.entries(value).map(([key,entry])=>[key,copyValue(entry,ancestors)]))}finally{ancestors.delete(value)}}__name(copyValue,"copyValue");export{copyContent};
@@ -0,0 +1 @@
1
+ export declare function freezeContent<Content>(value: Content): Content;
@@ -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{isObject}from"es-toolkit/compat";import{isFunction}from"es-toolkit/predicate";function freezeContent(value){if(isObject(value)&&!isFunction(value)){for(const item of Object.values(value))freezeContent(item);Object.freeze(value)}return value}__name(freezeContent,"freezeContent");export{freezeContent};
@@ -0,0 +1 @@
1
+ export declare function snapshotValue<Content>(value: Content): Content;
@@ -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{copyContent}from"./copy.js";import{assertRecordContent}from"./check.js";import{freezeContent}from"./freeze.js";function snapshotValue(value){const copy=copyContent(value);return assertRecordContent(copy),freezeContent(copy)}__name(snapshotValue,"snapshotValue");export{snapshotValue};
package/package.json CHANGED
@@ -1,6 +1,50 @@
1
1
  {
2
2
  "name": "@weiliang0121/capix-records",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/index.js"
10
+ },
11
+ "./construction": {
12
+ "types": "./dist/construction.d.ts",
13
+ "import": "./dist/construction.js"
14
+ }
15
+ },
16
+ "dependencies": {
17
+ "es-toolkit": "1.52.0",
18
+ "@weiliang0121/capix-contracts": "0.1.0",
19
+ "@weiliang0121/capix-resources": "0.1.0",
20
+ "@weiliang0121/capix-protocol": "0.1.0",
21
+ "@weiliang0121/capix-changes": "0.1.0"
22
+ },
23
+ "description": "Optional recording entities and resource contracts for CAPiX.",
24
+ "license": "MIT",
25
+ "author": "wei.liang (https://github.com/weiliang0121)",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/weiliang0121/capix.git",
29
+ "directory": "server/records"
30
+ },
31
+ "engines": {
32
+ "node": ">=22.23.2"
33
+ },
34
+ "main": "./dist/index.js",
35
+ "types": "./dist/index.d.ts",
36
+ "files": [
37
+ "dist/**/*.js",
38
+ "dist/**/*.d.ts",
39
+ "LICENSE",
40
+ "README.md"
41
+ ],
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "registry": "https://registry.npmjs.org"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc -p tsconfig.json",
48
+ "typecheck": "tsc -p tsconfig.json --noEmit"
49
+ }
6
50
  }