@asaidimu/utils-pipeline 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.mts +40 -2
- package/index.d.ts +40 -2
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -524,6 +524,13 @@ interface DataStore<T extends object> {
|
|
|
524
524
|
* @returns The current state T.
|
|
525
525
|
*/
|
|
526
526
|
get(clone?: boolean): T;
|
|
527
|
+
/**
|
|
528
|
+
* Gets a subset of the store.
|
|
529
|
+
* @param paths The paths which to include in the returned object.
|
|
530
|
+
* @param separator Optional separator for paths. Defaults to `.` .
|
|
531
|
+
* @returns An object of the shape K mapping paths to their current values.
|
|
532
|
+
*/
|
|
533
|
+
subset<K extends Record<string, any> = Record<string, any>>(paths: Array<string>, separator?: string): K;
|
|
527
534
|
/**
|
|
528
535
|
* Registers a named action function that can modify the state.
|
|
529
536
|
* @param action The action configuration object.
|
|
@@ -993,6 +1000,24 @@ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends R
|
|
|
993
1000
|
paramKey?: (params: Record<string, unknown>) => string;
|
|
994
1001
|
virtual?: true;
|
|
995
1002
|
}
|
|
1003
|
+
interface ExportedArtifact {
|
|
1004
|
+
key: string;
|
|
1005
|
+
instance: any;
|
|
1006
|
+
state: {
|
|
1007
|
+
groups: Array<{
|
|
1008
|
+
paths: string[];
|
|
1009
|
+
options?: SubscribeOptions;
|
|
1010
|
+
}>;
|
|
1011
|
+
hash: string;
|
|
1012
|
+
};
|
|
1013
|
+
dependencies: string[];
|
|
1014
|
+
}
|
|
1015
|
+
interface ExportedContainerState {
|
|
1016
|
+
version: string;
|
|
1017
|
+
timestamp: number;
|
|
1018
|
+
artifacts: ExportedArtifact[];
|
|
1019
|
+
checksum: string;
|
|
1020
|
+
}
|
|
996
1021
|
|
|
997
1022
|
/**
|
|
998
1023
|
* A dependency injection container for managing the lifecycle, dependencies,
|
|
@@ -1019,7 +1044,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
|
|
|
1019
1044
|
* Creates a new ArtifactContainer instance.
|
|
1020
1045
|
* @param store An object providing functions to interact with a global data store
|
|
1021
1046
|
*/
|
|
1022
|
-
constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set">);
|
|
1047
|
+
constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">);
|
|
1023
1048
|
/**
|
|
1024
1049
|
* Provides debug information about all artifacts currently registered in this container.
|
|
1025
1050
|
*
|
|
@@ -1136,6 +1161,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
|
|
|
1136
1161
|
* Callers should await this method to guarantee full resource release.
|
|
1137
1162
|
*/
|
|
1138
1163
|
dispose(): Promise<void>;
|
|
1164
|
+
export(): Promise<ExportedContainerState>;
|
|
1165
|
+
private restore;
|
|
1166
|
+
static from<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any>(options: {
|
|
1167
|
+
store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">;
|
|
1168
|
+
bundle?: ExportedContainerState;
|
|
1169
|
+
templates: ArtifactTemplate<TState, any, TRegistry>[];
|
|
1170
|
+
}): Promise<ArtifactContainer<TRegistry, TState>>;
|
|
1139
1171
|
}
|
|
1140
1172
|
|
|
1141
1173
|
/**
|
|
@@ -1155,6 +1187,11 @@ interface State {
|
|
|
1155
1187
|
*/
|
|
1156
1188
|
interface PauseInstruction {
|
|
1157
1189
|
readonly pause: string;
|
|
1190
|
+
/**
|
|
1191
|
+
* If true, the engine will snapshot the entire ArtifactContainer
|
|
1192
|
+
* and store the bundle in the checkpoint. Defaults to false.
|
|
1193
|
+
*/
|
|
1194
|
+
readonly persist?: boolean;
|
|
1158
1195
|
}
|
|
1159
1196
|
/**
|
|
1160
1197
|
* All possible outcomes of a router:
|
|
@@ -1191,6 +1228,7 @@ interface PipelineCheckpoint {
|
|
|
1191
1228
|
readonly pausedAtStageId: string;
|
|
1192
1229
|
readonly pausedAtStageLabel: string;
|
|
1193
1230
|
readonly pausedOn: string;
|
|
1231
|
+
readonly containerBundle?: ExportedContainerState;
|
|
1194
1232
|
}
|
|
1195
1233
|
/** Engine‑internal namespace for all checkpoint data. */
|
|
1196
1234
|
declare const PIPELINE_DATA_KEY: "__pipeline_data__";
|
|
@@ -1601,7 +1639,7 @@ declare class PipelineEngine<S extends object> {
|
|
|
1601
1639
|
* @param container - Shared container (created once at root; passed down to sub-pipelines).
|
|
1602
1640
|
* @param keyPrefix - Namespacing prefix for artifact keys within the shared container.
|
|
1603
1641
|
*/
|
|
1604
|
-
buildRunContext(runId: string, pipeline: RoutingPipelineDefinition<S>, entry: EntryAddress | undefined, store: DataStore<S>, parentBus: ScopedEventBus<S> | undefined, parentPath: EventPath, container?: ArtifactContainer<Record<string, DeepPartial<S>>, S>, keyPrefix?: string): RunContext<S
|
|
1642
|
+
buildRunContext(runId: string, pipeline: RoutingPipelineDefinition<S>, entry: EntryAddress | undefined, store: DataStore<S>, parentBus: ScopedEventBus<S> | undefined, parentPath: EventPath, container?: ArtifactContainer<Record<string, DeepPartial<S>>, S>, keyPrefix?: string, artifactBundle?: ExportedContainerState): Promise<RunContext<S>>;
|
|
1605
1643
|
}
|
|
1606
1644
|
|
|
1607
1645
|
export { type EngineLogger, type EntryAddress, type EventPath, PIPELINE_DATA_KEY, type PathNode, type PauseInstruction, Pipeline, type PipelineCheckpoint, type PipelineContext, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, type PipelineEventMap, type PipelineRunResult, type PipelineStageRouter, type PipelineStep, type PipelineStepDefinition, Result, type RoutingInstruction, type RoutingPipelineDefinition, type RunContext, type RunEventHandler, type RunEventMap, SequentialExecutionContext, type Stage, type StageCarry, type State, type Step, type StepStageRouter, type SubPipelineAddress, isPauseInstruction };
|
package/index.d.ts
CHANGED
|
@@ -524,6 +524,13 @@ interface DataStore<T extends object> {
|
|
|
524
524
|
* @returns The current state T.
|
|
525
525
|
*/
|
|
526
526
|
get(clone?: boolean): T;
|
|
527
|
+
/**
|
|
528
|
+
* Gets a subset of the store.
|
|
529
|
+
* @param paths The paths which to include in the returned object.
|
|
530
|
+
* @param separator Optional separator for paths. Defaults to `.` .
|
|
531
|
+
* @returns An object of the shape K mapping paths to their current values.
|
|
532
|
+
*/
|
|
533
|
+
subset<K extends Record<string, any> = Record<string, any>>(paths: Array<string>, separator?: string): K;
|
|
527
534
|
/**
|
|
528
535
|
* Registers a named action function that can modify the state.
|
|
529
536
|
* @param action The action configuration object.
|
|
@@ -993,6 +1000,24 @@ interface ArtifactTemplate<TState extends object, TArtifact, TRegistry extends R
|
|
|
993
1000
|
paramKey?: (params: Record<string, unknown>) => string;
|
|
994
1001
|
virtual?: true;
|
|
995
1002
|
}
|
|
1003
|
+
interface ExportedArtifact {
|
|
1004
|
+
key: string;
|
|
1005
|
+
instance: any;
|
|
1006
|
+
state: {
|
|
1007
|
+
groups: Array<{
|
|
1008
|
+
paths: string[];
|
|
1009
|
+
options?: SubscribeOptions;
|
|
1010
|
+
}>;
|
|
1011
|
+
hash: string;
|
|
1012
|
+
};
|
|
1013
|
+
dependencies: string[];
|
|
1014
|
+
}
|
|
1015
|
+
interface ExportedContainerState {
|
|
1016
|
+
version: string;
|
|
1017
|
+
timestamp: number;
|
|
1018
|
+
artifacts: ExportedArtifact[];
|
|
1019
|
+
checksum: string;
|
|
1020
|
+
}
|
|
996
1021
|
|
|
997
1022
|
/**
|
|
998
1023
|
* A dependency injection container for managing the lifecycle, dependencies,
|
|
@@ -1019,7 +1044,7 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
|
|
|
1019
1044
|
* Creates a new ArtifactContainer instance.
|
|
1020
1045
|
* @param store An object providing functions to interact with a global data store
|
|
1021
1046
|
*/
|
|
1022
|
-
constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set">);
|
|
1047
|
+
constructor(store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">);
|
|
1023
1048
|
/**
|
|
1024
1049
|
* Provides debug information about all artifacts currently registered in this container.
|
|
1025
1050
|
*
|
|
@@ -1136,6 +1161,13 @@ declare class ArtifactContainer<TRegistry extends Record<string, any> = Record<s
|
|
|
1136
1161
|
* Callers should await this method to guarantee full resource release.
|
|
1137
1162
|
*/
|
|
1138
1163
|
dispose(): Promise<void>;
|
|
1164
|
+
export(): Promise<ExportedContainerState>;
|
|
1165
|
+
private restore;
|
|
1166
|
+
static from<TRegistry extends Record<string, any> = Record<string, any>, TState extends object = any>(options: {
|
|
1167
|
+
store: Pick<DataStore<TState>, "watch" | "get" | "set" | "subset">;
|
|
1168
|
+
bundle?: ExportedContainerState;
|
|
1169
|
+
templates: ArtifactTemplate<TState, any, TRegistry>[];
|
|
1170
|
+
}): Promise<ArtifactContainer<TRegistry, TState>>;
|
|
1139
1171
|
}
|
|
1140
1172
|
|
|
1141
1173
|
/**
|
|
@@ -1155,6 +1187,11 @@ interface State {
|
|
|
1155
1187
|
*/
|
|
1156
1188
|
interface PauseInstruction {
|
|
1157
1189
|
readonly pause: string;
|
|
1190
|
+
/**
|
|
1191
|
+
* If true, the engine will snapshot the entire ArtifactContainer
|
|
1192
|
+
* and store the bundle in the checkpoint. Defaults to false.
|
|
1193
|
+
*/
|
|
1194
|
+
readonly persist?: boolean;
|
|
1158
1195
|
}
|
|
1159
1196
|
/**
|
|
1160
1197
|
* All possible outcomes of a router:
|
|
@@ -1191,6 +1228,7 @@ interface PipelineCheckpoint {
|
|
|
1191
1228
|
readonly pausedAtStageId: string;
|
|
1192
1229
|
readonly pausedAtStageLabel: string;
|
|
1193
1230
|
readonly pausedOn: string;
|
|
1231
|
+
readonly containerBundle?: ExportedContainerState;
|
|
1194
1232
|
}
|
|
1195
1233
|
/** Engine‑internal namespace for all checkpoint data. */
|
|
1196
1234
|
declare const PIPELINE_DATA_KEY: "__pipeline_data__";
|
|
@@ -1601,7 +1639,7 @@ declare class PipelineEngine<S extends object> {
|
|
|
1601
1639
|
* @param container - Shared container (created once at root; passed down to sub-pipelines).
|
|
1602
1640
|
* @param keyPrefix - Namespacing prefix for artifact keys within the shared container.
|
|
1603
1641
|
*/
|
|
1604
|
-
buildRunContext(runId: string, pipeline: RoutingPipelineDefinition<S>, entry: EntryAddress | undefined, store: DataStore<S>, parentBus: ScopedEventBus<S> | undefined, parentPath: EventPath, container?: ArtifactContainer<Record<string, DeepPartial<S>>, S>, keyPrefix?: string): RunContext<S
|
|
1642
|
+
buildRunContext(runId: string, pipeline: RoutingPipelineDefinition<S>, entry: EntryAddress | undefined, store: DataStore<S>, parentBus: ScopedEventBus<S> | undefined, parentPath: EventPath, container?: ArtifactContainer<Record<string, DeepPartial<S>>, S>, keyPrefix?: string, artifactBundle?: ExportedContainerState): Promise<RunContext<S>>;
|
|
1605
1643
|
}
|
|
1606
1644
|
|
|
1607
1645
|
export { type EngineLogger, type EntryAddress, type EventPath, PIPELINE_DATA_KEY, type PathNode, type PauseInstruction, Pipeline, type PipelineCheckpoint, type PipelineContext, type PipelineDefinition, PipelineEngine, type PipelineEngineOptions, type PipelineEventMap, type PipelineRunResult, type PipelineStageRouter, type PipelineStep, type PipelineStepDefinition, Result, type RoutingInstruction, type RoutingPipelineDefinition, type RunContext, type RunEventHandler, type RunEventMap, SequentialExecutionContext, type Stage, type StageCarry, type State, type Step, type StepStageRouter, type SubPipelineAddress, isPauseInstruction };
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=require("@asaidimu/utils-events"),t=require("uuid"),s={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},i=new Map;var r=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const r={...function(e){const t=Object.values(s).find((t=>t.code===e));if(t)return t;return i.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??r.description),this.name="SystemError",this.code=t.code,this.codeMetadata=r,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},n="SYS-001",a=(e,t)=>new r({code:n,message:t,cause:e}),o=e=>({ok:!0,value:e}),c=e=>({ok:!1,error:e}),h=class e extends r{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},d=class e extends h{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},u=class e extends h{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},l=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let i;await Promise.race([s.then((()=>clearTimeout(i))),new Promise(((s,r)=>{i=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new d("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},p=class{mutex=new l({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let i;return Promise.race([e.then((e=>(clearTimeout(i),e))),new Promise(((e,r)=>{i=setTimeout((()=>r(new d(s))),t)}))])}},g=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new l({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new u};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,i=null;try{if(this._done)throw new u;i=await e(),this._lastValue=i,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:i,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},f=class{constructor(t,s,i,r,n){this.pipeline=t,this.stepKey=s,this.params=i,r&&(r.aborted&&this.controller.abort(),r.addEventListener("abort",(()=>this.controller.abort()))),this.localBus=n??e.createEventBus()}id=Math.random().toString(36).substring(2,9);localBus;controller=new AbortController;once=new p({retry:!1,throws:!1});get signal(){return this.controller.signal}on(e,t){return this.localBus.subscribe(e,t)}abort(){this.controller.abort()}async run(){const{value:e,error:t}=await this.once.do((()=>this._run()));return t?c(t):e}async _run(){const e=this.pipeline.getSteps().get(this.stepKey);if(!e)return{ok:!1,error:new r({code:s.INVALID_COMMAND.code,message:`No step registered with key "${this.stepKey}"`,operation:this.stepKey})};if(this.signal.aborted)return this.failCancelled("Pipeline execution aborted before initialization",this.stepKey);const t=this.pipeline.groupByOrder(),i=Array.from(t.entries()).sort((([e],[t])=>e-t)),n=e.order;this.emit("start",{stepKey:this.stepKey,executionId:this.id});let a={[this.stepKey]:this.params},o=a,c=!0;for(const[e,t]of i){if(e<n)continue;if(this.signal.aborted)return this.failCancelled(`Pipeline runtime aborted at stage ${e}`,this.stepKey);const s=c?t.filter((e=>e.key===this.stepKey)):t;if(c=!1,0===s.length)continue;const i=await this.runStage(s,a);if(!i.ok)return i;o=i.value,a={...a,...o},this.emit("stage:success",{order:e,executionId:this.id,carry:o})}return this.emit("terminate",{carry:o,executionId:this.id}),{ok:!0,value:o}}async runStage(e,t){const s=await Promise.all(e.map((async e=>{try{if(this.signal.aborted)return{step:e,result:this.failCancelled("Aborted mid-flight execution sequence",e.key)};const s=await e.action(t,this.signal);return{step:e,result:s}}catch(t){return{step:e,result:{ok:!1,error:t instanceof r?t:a(t,t instanceof Error?t.message:"Unexpected exception raised during step run")}}}}))),i={};let n=null;for(const{step:e,result:t}of s)if(t.ok)this.emit("step:success",{stepKey:e.key,executionId:this.id,result:t.value}),i[e.key]=t.value;else{const s=t.error.withOperation(e.key);this.emit("step:failure",{stepKey:e.key,executionId:this.id,error:s}),n||(n={ok:!1,error:s},this.emit("failure",{stepKey:e.key,executionId:this.id,error:s}))}return n||{ok:!0,value:i}}emit(e,t){this.localBus.emit({name:e,payload:t})}failCancelled(e,t){return{ok:!1,error:new r({code:"CANCELLED",message:e,operation:t})}}},y=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new p({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function m(e,t){if(!e.length)return;const s=e.slice(),i=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${i} Cleanup error at index ${e}:`,t)}}}async function w(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function v(e){return`${e}__watched`}var b=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function S(e,t){let s;const i=new Promise(((e,i)=>{s=setTimeout((()=>i(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,i])}finally{clearTimeout(s)}}var k=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t,s){const i=this.get(e);if(!i)return b;if(i.package)return i.package;const r=e,n=m(i.cleanupFunctions,r),a="singleton"!==i.scope||void 0!==i.instance,o={instance:i.instance,error:i.error,ready:a,[s||e]:i.instance,cleanup:n,invalidate:t};return i.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const i=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new p({retry:!0,throws:!0}),t||(s.streamSerializer=new g,s.controller=new AbortController)),await w(s.cleanupFunctions,i),await w(s.disposeFunctions,i),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new p({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},I=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??A}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),i=new Set(t);for(const t of s)i.has(t)||this.removeDependency(e,t);for(const t of i)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],i=new Set([t]),r=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let i=e;for(;void 0!==i&&(s.push(i),i!==t);)i=r.get(i);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)i.has(e)||(i.add(e),r.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,i]of e)0===i&&s.push(t);const i=[];for(;s.length>0;){const t=s.shift();i.push(t);const r=this.dependents.get(t);if(r)for(const t of r){const i=(e.get(t)||0)-1;e.set(t,i),0===i&&s.push(t)}}if(i.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return i}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const i=new Set,r=new Set,n=[e];r.add(e),s&&i.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)r.has(e)||(r.add(e),i.add(e),n.push(e))}return i}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},A=new Set,E=class{graph;constructor(){this.graph=new I}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),i=e.indexOf(t),r=e.slice(i);return r.push(t),r}const i=this.graph.wouldCreateCycle(e,t);return i||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},_=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var x=class e extends Error{category;constructor(t,s,i){super(t,{cause:i}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},O=class extends x{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},$=class extends x{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},D=(new AbortController).signal,C=class{constructor(e,t,s,i,r){this.registry=e,this.cache=t,this.graph=s,this.store=i,this.observer=r}async build(e,t,s){const i=this.cache.get(e);if("singleton"===i?.scope&&i.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const r=this.registry.getByString(e);if(!r)throw new O(e);const n=t??[];if(n.includes(e))throw new x(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=i;a||(a=this.createCachedArtifact(r),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(r,a,n);const i=a;try{await i.buildOnce.do((()=>this.executeBuild(r,i,n)))}catch(i){if(i instanceof $)return this.build(e,t,s);throw i}return i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const i=e.key,r=String(i),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,r,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(i,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[i]:e,cleanup:m(a.cleanupFunctions,r),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${r}"`)}}}buildContext(e,t,s,i,r){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=r,l=async(e,t)=>{const r=t?this.computeParamKey(e,t):e;if(r===n)throw new x(`Artifact "${i}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,r);if(a)throw new x(`Adding dependency "${String(r)}" to "${i}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(r);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(r);return c&&d.set(r,c.version),o},p="singleton"===t.scope?t.controller.signal:D,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},f=(e,t)=>{const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const n=new Proxy((()=>{}),{get:(i,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(_.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),r(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return i.set(e,n),n};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:f}),stream:e=>{if(a)throw new x(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=t,r=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(i))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await r(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const i=t.signal,r=(e.retries??0)+1;let n=0;for(;n<r;)try{if(i.aborted)throw new $;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await S(a,e.timeout):await a:a,i.aborted)throw new $;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<r)continue;return{ok:!1,error:new x(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(i.aborted||e instanceof $)throw new $;if(e instanceof x)throw e;if(n++,n>=r)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,i,r){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=r;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a),i.ok?(t.instance=i.value,t.error=void 0):(t.instance=void 0,t.error=i.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const i=this.cache.get(e);if(!i)return;if("singleton"!==i.scope)return this.executeInvalidation(e,t,s);const r=i;return r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),!t&&r.activeDebounceMs>0?new Promise(((i,n)=>{r.debounceTimer=setTimeout((()=>{r.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(i).catch(n)}),r.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const i=this.cache.get(e);i&&"singleton"===i.scope&&await i.invalidationSerializer.do((async()=>{i.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const r=this.registry.get(e),n=r&&(t||!r.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof $||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const i=this.cache.get(e);if(!i||"singleton"!==i.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),i.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)i.stateDependencies.add(t);if(i.stateUnsubscribe&&(i.stateUnsubscribe(),i.stateUnsubscribe=void 0),0===s.length)return;const r=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let i=n.get(s);i||(i={options:t,paths:new Set},n.set(s,i));for(const t of e)i.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,r)):a.push(this.store.watch(s,r,e))}0===a.length?i.stateUnsubscribe=void 0:1===a.length?i.stateUnsubscribe=a[0]:i.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new p({retry:!0,throws:!0}),streamOnce:new p({retry:!0,throws:!0}),streamSerializer:new g({yieldMode:"microtask"}),invalidationSerializer:new g({yieldMode:"macrotask"})}}resolveStatic(e){if(!this.registry.has(e))throw new O(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new O(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new x(`Artifact "${String(e)}" is not parameterized.`,"external");const i=s.paramKey(t),r=this.registry.getByString(i);if(r&&!r.paramKey&&!r.virtual)throw new x(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${i}" which is already registered as a static artifact.`,"system");return this.registry.hasString(i)||this.registry.setVirtual(i,{key:i,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(i,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},R=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const i=this.registry.get(e);if(!i.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const r=i.paramKey(t);return this.watchForKey(r,i,s,t)}watchForKey(e,t,s,i){const r="transient"===t.scope,n=r?v(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new y((async()=>{!r&&void 0===i||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:r?t.factory:e=>t.factory({...e,params:i}),scope:r?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{r||void 0!==i?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:r&&void 0===i?"sync":s});let c;const h={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):b,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(h.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:h}),h}evictWatcher(e){[e,v(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(v(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(v(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},N=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...i}){const{scope:r,...n}=i,a={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new O(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},P=class{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t)},this.registry=new N,this.cache=new k,this.graph=new E,this.observer=new R(this.registry,this.cache,this),this.manager=new C(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,i=this.registry.get(s),r=this.cache.get(s);if(!i)return;let n="idle";r&&("singleton"===r.scope&&void 0!==r.debounceTimer?n="debouncing":"singleton"===r.scope&&r.buildOnce.running()?n="building":r.error?n="error":void 0!==r.instance&&(n="active")),e.push({id:s,scope:i.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===r?.scope?Array.from(r.stateDependencies):[],buildCount:r?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const i=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==i||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,i=t?.replace??!1,r=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(r,i)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}};function M(e){return"object"==typeof e&&null!==e&&"pause"in e}var T="__pipeline_data__";var L={info:()=>{},error:()=>{}},K=class{constructor(e,t,s,i,r,n,a,o,c,h,d,u,l,p){this.pipeline=t,this.entry=s,this.store=i,this.container=r,this.keyPrefix=n,this.bus=a,this.parentPath=o,this.controller=c,this.once=h,this.logger=d,this.definitionId=u,this.index=l,this.factory=p,this.id=e}id;on(e,t){return this.bus.on(e,t)}abort(){this.controller.abort()}async run(){const e=await this.once.do((()=>this.execute()));return void 0!==e.error?c(new r({code:s.INTERNAL_ERROR.code,message:`Unexpected throw escaped run(): ${V(e.error)}`,operation:`pipeline:${this.pipeline.id}`,cause:e.error})):e.value}async execute(){this.bus.emit("pipeline:start",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id}),this.logger.info(`Pipeline start: ${this.pipeline.id} [${this.id}]`);const e=this.resolveEntryStage();if(!e.ok)return this.failPipeline(e.error);const{stageMap:t,orderedStages:i,stageOrderIndex:n}=this.index;let a=e.value,c=!0;for(;;){if(this.controller.signal.aborted){const e=new r({code:s.OPERATION_ABORTED.code,message:`Run aborted before stage "${a.label}".`,operation:`stage:${a.id}`});return this.failPipeline(e)}const e=c?this.entry:void 0;c=!1;const h=await this.executeStage(a,e);if(!h.ok)return this.failPipeline(h.error);const d=h.value,u="pause"===d.kind?void 0:d.nextInstruction,l=n.get(a.id)??-1,p=void 0!==i[l+1],g="pause"===d.kind?"pause":null===u?"terminate":"string"==typeof u?"jump":p?"advance":"natural-end";if(this.bus.emit("router:evaluated",{path:this.parentPath,stageId:a.id,stageLabel:a.label,runId:this.id,instruction:u,interpretation:g}),"pause"===d.kind){const{checkpoint:e}=d,t=this.store.get(!0);return this.logger.info(`Pipeline paused: ${this.pipeline.id} [${this.id}] at stage "${e.pausedAtStageId}"`),this.bus.emit("pipeline:paused",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,checkpoint:e,finalState:t}),o({status:"paused",runId:this.id,finalState:t,checkpoint:e})}if(null===u)break;if("string"==typeof u){const e=t.get(u);if(!e){const e=new r({code:s.INVALID_COMMAND.code,message:`Router on stage "${a.label}" returned unknown stageId: "${u}"`,operation:`stage:${a.id}`});return this.failPipeline(e)}a=e;continue}const f=i[l+1];if(!f)break;a=f}const h=this.store.get(!0);return this.logger.info(`Pipeline succeeded: ${this.pipeline.id} [${this.id}]`),this.bus.emit("pipeline:success",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,finalState:h}),o({status:"succeeded",runId:this.id,finalState:h})}resolveEntryStage(){const{stageMap:e,orderedStages:t}=this.index;if(this.entry?.stage){const t=e.get(this.entry.stage);return t?o(t):c(new r({code:s.INVALID_COMMAND.code,message:`Entry stage "${this.entry.stage}" not found.`,operation:`pipeline:${this.pipeline.id}`}))}const i=t[0];return i?o(i):c(new r({code:s.INVALID_COMMAND.code,message:"Pipeline has no stages.",operation:`pipeline:${this.pipeline.id}`}))}async executeStage(e,t){const s=e.pipelines&&e.pipelines.length>0?"pipelines":"steps",i=[...this.parentPath,{kind:"stage",id:e.id,label:e.label}];this.bus.emit("stage:start",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,mode:s});const r="pipelines"===s?await this.executePipelinesStage(e,i,t):await this.executeStepsStage(e,i,t);return r.ok?"pause"===r.value.kind?this.bus.emit("stage:paused",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,checkpoint:r.value.checkpoint}):this.bus.emit("stage:success",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,nextInstruction:r.value.nextInstruction}):this.bus.emit("stage:failure",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,error:r.error}),r}async executeStepsStage(e,t,i){const n=Object.values(e.steps??{});if(0===n.length){this.logger.info(`Stage "${e.label}" has no steps — skipping.`);const t=B(e.router,this.store.get(!0),{});return o(U(t))}if(this.controller.signal.aborted)return c(new r({code:s.OPERATION_ABORTED.code,message:`Aborted before resolving steps in stage "${e.label}".`,operation:`stage:${e.id}`}));const a=void 0!==i?.step?n.filter((e=>e.id===i.step)):n;if(void 0!==i?.step&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry step "${i.step}" not found in stage "${e.label}".`,operation:`stage:${e.id}`}));for(const e of a)this.bus.emit("step:start",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id});const h=await Promise.all(a.map((async t=>({step:t,result:await this.container.resolve(z(this.keyPrefix,e.id,t.id))})))),d={};for(const{step:e,result:i}of h)i.ready?(this.bus.emit("step:success",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id}),d[e.id]=o(i.instance)):(this.bus.emit("step:failure",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id,error:i.error}),d[e.id]=c(new r({code:s.BACKEND_ERROR.code,message:V(i.error)})));const u=h.find((({result:e})=>!e.ready));if(u){const e=u.result.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Step "${u.step.label}" failed: ${V(e)}`,operation:`step:${u.step.id}`,cause:e}))}const l=h.map((({result:e})=>e.instance)).filter((e=>null!=e));let p;try{await this.store.transaction((async()=>{for(const e of l)await this.store.set(e);const t=B(e.router,this.store.get(!0),d);if(M(t)){const s={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};await j(this.store,s),p={kind:"pause",checkpoint:s}}else p=U(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed during stage "${e.label}": ${V(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}async executePipelinesStage(e,t,i){const n=e.pipelines,a=void 0!==i?.pipeline?(()=>{const{index:e}=i.pipeline,t=n[e];return t?[{subPipeline:t,originalIndex:e}]:[]})():n.map(((e,t)=>({subPipeline:e,originalIndex:t})));if(void 0!==i?.pipeline&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry sub‑pipeline index ${i.pipeline.index} out of bounds.`,operation:`stage:${e.id}`}));this.bus.emit("subpipeline:fork",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,subPipelineIds:a.map((({subPipeline:e})=>e.id))});const h=a.map((({subPipeline:s,originalIndex:r})=>{const n=void 0!==i?.pipeline?{stage:i.pipeline.stage,step:i.pipeline.step}:void 0,a=function(e,t,s){const i=`${t}:pipeline-${s}`;return e?`${e}:${i}`:i}(this.keyPrefix,e.id,r);return{subPipeline:s,originalIndex:r,ctx:this.factory.buildRunContext(this.id,s,n,this.store,this.bus,t,this.container,a)}})),d=()=>{h.forEach((({ctx:e})=>e.abort()))};this.controller.signal.addEventListener("abort",d,{once:!0});try{if(this.controller.signal.aborted)return d(),c(new r({code:s.OPERATION_ABORTED.code,message:this.controller.signal.reason,operation:`stage:${e.id}`}));const i=await Promise.all(h.map((({ctx:e})=>e.run()))),n={};for(let e=0;e<a.length;e++)n[a[e].subPipeline.id]=i[e];this.bus.emit("subpipeline:join",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,results:n});const u=i.findIndex((e=>!e.ok||"failed"===e.value.status));if(-1!==u){const t=a[u].subPipeline.id,n=i[u],o=n.ok?n.value.error:n.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Sub‑pipeline "${t}" failed: ${V(o)}`,operation:`stage:${e.id}`,cause:o}))}const l=i.findIndex((e=>e.ok&&"paused"===e.value.status));if(-1!==l){const t=i[l].value,{checkpoint:n}=t,h={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:e.id,pipeline:{index:a[l].originalIndex,stage:n.resumeAt.stage,step:n.resumeAt.step}},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};try{await this.store.transaction((async()=>{await j(this.store,h)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Failed to write parent pause checkpoint for stage "${e.label}".`,operation:`stage:${e.id}`,cause:t}))}return o({kind:"pause",checkpoint:h})}let p;try{await this.store.transaction((async()=>{const t=B(e.pipelinesRouter,this.store.get(!0),n);if(M(t)){const s={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};await j(this.store,s),p={kind:"pause",checkpoint:s}}else p=U(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed evaluating router for stage "${e.label}": ${V(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}finally{this.controller.signal.removeEventListener("abort",d)}}failPipeline(e){return this.bus.emit("pipeline:failure",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,error:e}),c(e)}};function F(e){const t=[...e.stages].sort(((e,t)=>e.order-t.order)),s=new Map,i=new Map;for(let e=0;e<t.length;e++){const r=t[e];s.set(r.id,r),i.set(r.id,e)}return{stageMap:s,orderedStages:t,stageOrderIndex:i}}function z(e,t,s){return e?`${e}:${t}:${s}`:`${t}:${s}`}function B(e,t,s){return e?e(t,s):void 0}function U(e){return{kind:"advance",nextInstruction:e}}function V(e){return e instanceof Error?e.message:String(e)}async function j(e,t){const s=e,i=t.pipelineId,r=t.runId,n=s.get(!0)[T]??{},a={...n,[i]:{...n[i]??{},[r]:t}};await s.set({[T]:a})}exports.PIPELINE_DATA_KEY=T,exports.Pipeline=class{steps=new Map;globalBus=e.createEventBus();serializer=new g;executions=new Map;constructor(e){e&&e.forEach(((e,t)=>{(Array.isArray(e)?e:[e]).forEach((e=>this.steps.set(e.key,{...e,order:t})))}))}getSteps(){return this.steps}step(e){return this.steps.set(e.key,e),this}on(e,t){return this.globalBus.subscribe(e,t)}prepare(e,t,s,i){return new f(this,e,t,s?.signal,i)}async execute(e,t,s){const i=s?.disableDeduplication?`${e}:${Date.now()}:${Math.random()}`:this.getDedupeKey(e,t);let r=this.executions.get(i);r||(r=new p({retry:!0,throws:!1}),this.executions.set(i,r));const n=await r.do((async()=>{const i=await this.serializer.do((async()=>{const i=this.prepare(e,t,{signal:s?.signal},this.globalBus);return await i.run()}));if(i.error)throw i.error;return i.value})).finally((()=>{setTimeout((()=>this.executions.delete(i)),0)}));return n.error?c(n.error):n.value}getRegisteredSteps(){return Array.from(this.steps.keys())}validate(){const e=[];return 0===this.steps.size&&e.push("Pipeline has no registered steps"),e}destroy(){this.steps.clear(),this.globalBus.clear(),this.executions.clear()}groupByOrder(){const e=new Map;for(const t of this.steps.values()){const s=e.get(t.order)??[];s.push(t),e.set(t.order,s)}return e}getDedupeKey(e,t){try{return`${e}:${JSON.stringify(this.sortObjectKeys(t))}`}catch{return`${e}:${Date.now()}:${Math.random()}`}}sortObjectKeys(e){if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map((e=>this.sortObjectKeys(e)));const t={};return Object.keys(e).sort().forEach((s=>{t[s]=this.sortObjectKeys(e[s])})),t}},exports.PipelineEngine=class{constructor(e,t){this.definition=e,this.logger=t.logger??L,this.storeFactory=t.storeFactory,this.initialStateFactory=t.initialStateFactory,this.index=F(e)}logger;storeFactory;initialStateFactory;index;async prepare(e,s){const i=s??t.v7(),r=await this.storeFactory(i);await r.ready();const n=this.initialStateFactory?.()??{};return await r.set(n),this.logger.info(`Prepared new run "${i}" for pipeline "${this.definition.id}"`),this.buildRunContext(i,this.definition,e,r,void 0,[])}async resume(e){const t=await this.storeFactory(e),i=function(e,t,s){const i=e,r=i.get(!0)[T],n=r?.[t]?.[s];return n??null}(t,this.definition.id,e);return i?i.pipelineId!==this.definition.id?c(new r({code:s.INVALID_COMMAND.code,message:`Checkpoint runId "${e}" belongs to pipeline "${i.pipelineId}", not "${this.definition.id}".`,operation:"resume"})):(this.logger.info(`Resuming pipeline "${this.definition.id}" [${e}] from stage "${i.pausedAtStageId}"`),o(this.buildRunContext(e,this.definition,i.resumeAt,t,void 0,[]))):c(new r({code:s.NOT_FOUND.code,message:`No checkpoint found for runId "${e}".`,operation:"resume"}))}buildRunContext(t,s,i,r,n,a,o,c){const h=void 0===o,d=h?new P(r):o,u=c??"",l=new AbortController;!function(e,t,s,i){for(const r of t.stages)if(r.steps)for(const t of Object.values(r.steps)){const n={runId:i.runId,pipelineId:i.pipelineId,stageId:r.id,stepId:t.id,signal:i.signal};e.register({key:z(s,r.id,t.id),factory:e=>t.action(e,n),scope:t.scope,...void 0!==t.timeout&&{timeout:t.timeout},...void 0!==t.retries&&{retries:t.retries}})}}(d,s,u,{runId:t,pipelineId:s.id,signal:l.signal});const g=function(e,t){return{emit(s,i){e.emit({name:s,payload:i}),t?.emit(s,i)},on:(t,s)=>e.subscribe(t,s)}}(e.createEventBus(),n),f=new p({retry:!1,throws:!1}),y=h?this.index:F(s);return new K(t,s,i,r,d,u,g,a,l,f,this.logger,this.definition.id,y,this)}},exports.SequentialExecutionContext=f,exports.isPauseInstruction=M;
|
|
1
|
+
"use strict";var e=require("@asaidimu/utils-events"),t=require("uuid"),s={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},i=new Map;var r=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const r={...function(e){const t=Object.values(s).find((t=>t.code===e));if(t)return t;return i.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??r.description),this.name="SystemError",this.code=t.code,this.codeMetadata=r,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},n="SYS-001",a=(e,t)=>new r({code:n,message:t,cause:e}),o=e=>({ok:!0,value:e}),c=e=>({ok:!1,error:e}),h=class e extends r{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},d=class e extends h{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},u=class e extends h{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},l=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let i;await Promise.race([s.then((()=>clearTimeout(i))),new Promise(((s,r)=>{i=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new d("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},p=class{mutex=new l({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}resolve(e){if(this._done)throw new Error("Cannot resolve: operation is already completed.");if(this.running())throw new Error("Cannot resolve: operation is currently running.");this._value=e,this._done=!0}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let i;return Promise.race([e.then((e=>(clearTimeout(i),e))),new Promise(((e,r)=>{i=setTimeout((()=>r(new d(s))),t)}))])}},g=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new l({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new u};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,i=null;try{if(this._done)throw new u;i=await e(),this._lastValue=i,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:i,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},f=class{constructor(t,s,i,r,n){this.pipeline=t,this.stepKey=s,this.params=i,r&&(r.aborted&&this.controller.abort(),r.addEventListener("abort",(()=>this.controller.abort()))),this.localBus=n??e.createEventBus()}id=Math.random().toString(36).substring(2,9);localBus;controller=new AbortController;once=new p({retry:!1,throws:!1});get signal(){return this.controller.signal}on(e,t){return this.localBus.subscribe(e,t)}abort(){this.controller.abort()}async run(){const{value:e,error:t}=await this.once.do((()=>this._run()));return t?c(t):e}async _run(){const e=this.pipeline.getSteps().get(this.stepKey);if(!e)return{ok:!1,error:new r({code:s.INVALID_COMMAND.code,message:`No step registered with key "${this.stepKey}"`,operation:this.stepKey})};if(this.signal.aborted)return this.failCancelled("Pipeline execution aborted before initialization",this.stepKey);const t=this.pipeline.groupByOrder(),i=Array.from(t.entries()).sort((([e],[t])=>e-t)),n=e.order;this.emit("start",{stepKey:this.stepKey,executionId:this.id});let a={[this.stepKey]:this.params},o=a,c=!0;for(const[e,t]of i){if(e<n)continue;if(this.signal.aborted)return this.failCancelled(`Pipeline runtime aborted at stage ${e}`,this.stepKey);const s=c?t.filter((e=>e.key===this.stepKey)):t;if(c=!1,0===s.length)continue;const i=await this.runStage(s,a);if(!i.ok)return i;o=i.value,a={...a,...o},this.emit("stage:success",{order:e,executionId:this.id,carry:o})}return this.emit("terminate",{carry:o,executionId:this.id}),{ok:!0,value:o}}async runStage(e,t){const s=await Promise.all(e.map((async e=>{try{if(this.signal.aborted)return{step:e,result:this.failCancelled("Aborted mid-flight execution sequence",e.key)};const s=await e.action(t,this.signal);return{step:e,result:s}}catch(t){return{step:e,result:{ok:!1,error:t instanceof r?t:a(t,t instanceof Error?t.message:"Unexpected exception raised during step run")}}}}))),i={};let n=null;for(const{step:e,result:t}of s)if(t.ok)this.emit("step:success",{stepKey:e.key,executionId:this.id,result:t.value}),i[e.key]=t.value;else{const s=t.error.withOperation(e.key);this.emit("step:failure",{stepKey:e.key,executionId:this.id,error:s}),n||(n={ok:!1,error:s},this.emit("failure",{stepKey:e.key,executionId:this.id,error:s}))}return n||{ok:!0,value:i}}emit(e,t){this.localBus.emit({name:e,payload:t})}failCancelled(e,t){return{ok:!1,error:new r({code:"CANCELLED",message:e,operation:t})}}},y=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new p({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function m(e,t){if(!e.length)return;const s=e.slice(),i=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${i} Cleanup error at index ${e}:`,t)}}}async function w(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function v(e){return`${e}__watched`}var b=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function S(e,t){let s;const i=new Promise(((e,i)=>{s=setTimeout((()=>i(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,i])}finally{clearTimeout(s)}}async function k(e){const t=(new TextEncoder).encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var I=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t,s){const i=this.get(e);if(!i)return b;if(i.package)return i.package;const r=e,n=m(i.cleanupFunctions,r),a="singleton"!==i.scope||void 0!==i.instance,o={instance:i.instance,error:i.error,ready:a,[s||e]:i.instance,cleanup:n,invalidate:t};return i.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const i=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new p({retry:!0,throws:!0}),t||(s.streamSerializer=new g,s.controller=new AbortController)),await w(s.cleanupFunctions,i),await w(s.disposeFunctions,i),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new p({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},A=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??E}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),i=new Set(t);for(const t of s)i.has(t)||this.removeDependency(e,t);for(const t of i)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],i=new Set([t]),r=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let i=e;for(;void 0!==i&&(s.push(i),i!==t);)i=r.get(i);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)i.has(e)||(i.add(e),r.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,i]of e)0===i&&s.push(t);const i=[];for(;s.length>0;){const t=s.shift();i.push(t);const r=this.dependents.get(t);if(r)for(const t of r){const i=(e.get(t)||0)-1;e.set(t,i),0===i&&s.push(t)}}if(i.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return i}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const i=new Set,r=new Set,n=[e];r.add(e),s&&i.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)r.has(e)||(r.add(e),i.add(e),n.push(e))}return i}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},E=new Set,O=class{graph;constructor(){this.graph=new A}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),i=e.indexOf(t),r=e.slice(i);return r.push(t),r}const i=this.graph.wouldCreateCycle(e,t);return i||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},_=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var x=class e extends Error{category;constructor(t,s,i){super(t,{cause:i}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},D=class extends x{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},$=class extends x{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},C=class extends x{constructor(e){super(e,"system"),this.name="InvalidImportError"}},R=class extends x{constructor(e){super(`Artifact "${e}" instance is not JSON-serializable (POJO are required for persistence)`,"system"),this.name="InvalidExportOperationError"}},N=(new AbortController).signal,P=class{constructor(e,t,s,i,r){this.registry=e,this.cache=t,this.graph=s,this.store=i,this.observer=r}async build(e,t,s){const i=this.cache.get(e);if("singleton"===i?.scope&&i.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const r=this.registry.getByString(e);if(!r)throw new D(e);const n=t??[];if(n.includes(e))throw new x(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=i;a||(a=this.createCachedArtifact(r),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(r,a,n);const i=a;try{await i.buildOnce.do((()=>this.executeBuild(r,i,n)))}catch(i){if(i instanceof $)return this.build(e,t,s);throw i}return i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const i=e.key,r=String(i),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,r,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(i,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[i]:e,cleanup:m(a.cleanupFunctions,r),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${r}"`)}}}buildContext(e,t,s,i,r){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=r,l=async(e,t)=>{const r=t?this.computeParamKey(e,t):e;if(r===n)throw new x(`Artifact "${i}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,r);if(a)throw new x(`Adding dependency "${String(r)}" to "${i}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(r);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(r);return c&&d.set(r,c.version),o},p="singleton"===t.scope?t.controller.signal:N,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},f=(e,t)=>{const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const n=new Proxy((()=>{}),{get:(i,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(_.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),r(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return i.set(e,n),n};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:f}),stream:e=>{if(a)throw new x(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=t,r=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(i))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await r(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const i=t.signal,r=(e.retries??0)+1;let n=0;for(;n<r;)try{if(i.aborted)throw new $;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await S(a,e.timeout):await a:a,i.aborted)throw new $;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<r)continue;return{ok:!1,error:new x(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(i.aborted||e instanceof $)throw new $;if(e instanceof x)throw e;if(n++,n>=r)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,i,r){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=r;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a,t.artifactDependencies=new Set(o),t.stateGroups=c.map((({paths:e,options:t})=>({paths:e,options:t})))),i.ok?(t.instance=i.value,t.error=void 0):(t.instance=void 0,t.error=i.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const i=this.cache.get(e);if(!i)return;if("singleton"!==i.scope)return this.executeInvalidation(e,t,s);const r=i;return r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),!t&&r.activeDebounceMs>0?new Promise(((i,n)=>{r.debounceTimer=setTimeout((()=>{r.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(i).catch(n)}),r.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const i=this.cache.get(e);i&&"singleton"===i.scope&&await i.invalidationSerializer.do((async()=>{i.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const r=this.registry.get(e),n=r&&(t||!r.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof $||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const i=this.cache.get(e);if(!i||"singleton"!==i.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),i.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)i.stateDependencies.add(t);if(i.stateUnsubscribe&&(i.stateUnsubscribe(),i.stateUnsubscribe=void 0),0===s.length)return;const r=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let i=n.get(s);i||(i={options:t,paths:new Set},n.set(s,i));for(const t of e)i.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,r)):a.push(this.store.watch(s,r,e))}0===a.length?i.stateUnsubscribe=void 0:1===a.length?i.stateUnsubscribe=a[0]:i.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new p({retry:!0,throws:!0}),streamOnce:new p({retry:!0,throws:!0}),streamSerializer:new g({yieldMode:"microtask"}),invalidationSerializer:new g({yieldMode:"macrotask"}),stateGroups:[],artifactDependencies:new Set}}resolveStatic(e){if(!this.registry.has(e))throw new D(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new D(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new x(`Artifact "${String(e)}" is not parameterized.`,"external");const i=s.paramKey(t),r=this.registry.getByString(i);if(r&&!r.paramKey&&!r.virtual)throw new x(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${i}" which is already registered as a static artifact.`,"system");return this.registry.hasString(i)||this.registry.setVirtual(i,{key:i,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(i,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},M=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const i=this.registry.get(e);if(!i.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const r=i.paramKey(t);return this.watchForKey(r,i,s,t)}watchForKey(e,t,s,i){const r="transient"===t.scope,n=r?v(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new y((async()=>{!r&&void 0===i||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:r?t.factory:e=>t.factory({...e,params:i}),scope:r?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{r||void 0!==i?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:r&&void 0===i?"sync":s});let c;const h={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):b,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(h.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:h}),h}evictWatcher(e){[e,v(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(v(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(v(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},T=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...i}){const{scope:r,...n}=i,a={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new D(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},L=class e{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t),subset:(...t)=>e.subset(...t)},this.registry=new T,this.cache=new I,this.graph=new O,this.observer=new M(this.registry,this.cache,this),this.manager=new P(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,i=this.registry.get(s),r=this.cache.get(s);if(!i)return;let n="idle";r&&("singleton"===r.scope&&void 0!==r.debounceTimer?n="debouncing":"singleton"===r.scope&&r.buildOnce.running()?n="building":r.error?n="error":void 0!==r.instance&&(n="active")),e.push({id:s,scope:i.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===r?.scope?Array.from(r.stateDependencies):[],buildCount:r?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const i=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==i||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,i=t?.replace??!1,r=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(r,i)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}async export(){const e=[];for(const t of this.cache.keys()){const s=this.cache.get(t);if(!s||"singleton"!==s.scope)continue;if(void 0===s.instance)continue;const i=new Set;for(const e of s.stateGroups)for(const t of e.paths)i.add(t);const r=Array.from(i).sort(),n=this.store.subset(r),a=await k(JSON.stringify(n,Object.keys(n).sort()));let o;try{o=structuredClone(s.instance)}catch(e){throw new R(t)}e.push({key:t,instance:o,state:{groups:s.stateGroups.map((e=>({paths:e.paths,options:e.options}))),hash:a},dependencies:Array.from(s.artifactDependencies)})}const t={...{version:"1.0",timestamp:Date.now(),artifacts:e}},s=JSON.stringify(t),i=await k(s);return{...t,checksum:i}}async restore(e){const{checksum:t,...s}=e;if(await k(JSON.stringify(s))!==t)throw new C("Bundle checksum mismatch – data corrupted");if("1.0"!==e.version)throw new C(`Unsupported bundle version: ${e.version}`);const i=new Map;for(const t of e.artifacts)i.set(t.key,t);const r=new Set,n=new Map;for(const t of e.artifacts)for(const e of t.dependencies)n.has(e)||n.set(e,new Set),n.get(e).add(t.key);const a=async e=>{const t=new Set;for(const s of e.state.groups)for(const e of s.paths)t.add(e);const s=Array.from(t).sort(),i=this.store.subset(s);return k(JSON.stringify(i,Object.keys(i).sort()))};for(const t of e.artifacts){await a(t)!==t.state.hash&&r.add(t.key)}const o=Array.from(r);for(;o.length;){const e=o.shift(),t=n.get(e);if(t)for(const e of t)r.has(e)||(r.add(e),o.push(e))}for(const t of e.artifacts){if(r.has(t.key))continue;this.cache.get(t.key)&&await this.cache.invalidateInstance(t.key,!1);const e={scope:"singleton",instance:t.instance,error:void 0,version:1,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set(t.state.groups.flatMap((e=>e.paths))),activeDebounceMs:0,buildOnce:new p({retry:!0,throws:!0}),streamSerializer:new g({yieldMode:"microtask"}),invalidationSerializer:new g({yieldMode:"macrotask"}),stateUnsubscribe:void 0,debounceTimer:void 0,controller:new AbortController,streamOnce:new p({retry:!0,throws:!0}),stream:void 0,stateGroups:t.state.groups,artifactDependencies:new Set(t.dependencies)};e.buildOnce.resolve(t.instance),this.cache.set(t.key,e);const s=[];for(const e of t.state.groups){const i=this.store.watch(e.paths,(()=>this.invalidate(t.key)),e.options);s.push(i)}e.stateUnsubscribe=()=>{for(const e of s)e()},this.graph.setDependencies(t.key,t.dependencies)}}static async from(t){const s=new e(t.store);if(t.bundle){if("object"!=typeof t.bundle||!t.bundle.version||!Array.isArray(t.bundle.artifacts))throw new C("Invalid bundle: missing version or artifacts array");await s.restore(t.bundle)}for(const e of t.templates)s.register(e);return s}};function F(e){return"object"==typeof e&&null!==e&&"pause"in e}var K="__pipeline_data__";var B={info:()=>{},error:()=>{}},z=class{constructor(e,t,s,i,r,n,a,o,c,h,d,u,l,p){this.pipeline=t,this.entry=s,this.store=i,this.container=r,this.keyPrefix=n,this.bus=a,this.parentPath=o,this.controller=c,this.once=h,this.logger=d,this.definitionId=u,this.index=l,this.factory=p,this.id=e}id;on(e,t){return this.bus.on(e,t)}abort(){this.controller.abort()}async run(){const e=await this.once.do((()=>this.execute()));return void 0!==e.error?c(new r({code:s.INTERNAL_ERROR.code,message:`Unexpected throw escaped run(): ${Y(e.error)}`,operation:`pipeline:${this.pipeline.id}`,cause:e.error})):e.value}async execute(){this.bus.emit("pipeline:start",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id}),this.logger.info(`Pipeline start: ${this.pipeline.id} [${this.id}]`);const e=this.resolveEntryStage();if(!e.ok)return this.failPipeline(e.error);const{stageMap:t,orderedStages:i,stageOrderIndex:n}=this.index;let a=e.value,c=!0;for(;;){if(this.controller.signal.aborted){const e=new r({code:s.OPERATION_ABORTED.code,message:`Run aborted before stage "${a.label}".`,operation:`stage:${a.id}`});return this.failPipeline(e)}const e=c?this.entry:void 0;c=!1;const h=await this.executeStage(a,e);if(!h.ok)return this.failPipeline(h.error);const d=h.value,u="pause"===d.kind?void 0:d.nextInstruction,l=n.get(a.id)??-1,p=void 0!==i[l+1],g="pause"===d.kind?"pause":null===u?"terminate":"string"==typeof u?"jump":p?"advance":"natural-end";if(this.bus.emit("router:evaluated",{path:this.parentPath,stageId:a.id,stageLabel:a.label,runId:this.id,instruction:u,interpretation:g}),"pause"===d.kind){const{checkpoint:e}=d,t=this.store.get(!0);return this.logger.info(`Pipeline paused: ${this.pipeline.id} [${this.id}] at stage "${e.pausedAtStageId}"`),this.bus.emit("pipeline:paused",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,checkpoint:e,finalState:t}),o({status:"paused",runId:this.id,finalState:t,checkpoint:e})}if(null===u)break;if("string"==typeof u){const e=t.get(u);if(!e){const e=new r({code:s.INVALID_COMMAND.code,message:`Router on stage "${a.label}" returned unknown stageId: "${u}"`,operation:`stage:${a.id}`});return this.failPipeline(e)}a=e;continue}const f=i[l+1];if(!f)break;a=f}const h=this.store.get(!0);return this.logger.info(`Pipeline succeeded: ${this.pipeline.id} [${this.id}]`),this.bus.emit("pipeline:success",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,finalState:h}),o({status:"succeeded",runId:this.id,finalState:h})}resolveEntryStage(){const{stageMap:e,orderedStages:t}=this.index;if(this.entry?.stage){const t=e.get(this.entry.stage);return t?o(t):c(new r({code:s.INVALID_COMMAND.code,message:`Entry stage "${this.entry.stage}" not found.`,operation:`pipeline:${this.pipeline.id}`}))}const i=t[0];return i?o(i):c(new r({code:s.INVALID_COMMAND.code,message:"Pipeline has no stages.",operation:`pipeline:${this.pipeline.id}`}))}async executeStage(e,t){const s=e.pipelines&&e.pipelines.length>0?"pipelines":"steps",i=[...this.parentPath,{kind:"stage",id:e.id,label:e.label}];this.bus.emit("stage:start",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,mode:s});const r="pipelines"===s?await this.executePipelinesStage(e,i,t):await this.executeStepsStage(e,i,t);return r.ok?"pause"===r.value.kind?this.bus.emit("stage:paused",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,checkpoint:r.value.checkpoint}):this.bus.emit("stage:success",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,nextInstruction:r.value.nextInstruction}):this.bus.emit("stage:failure",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,error:r.error}),r}async executeStepsStage(e,t,i){const n=Object.values(e.steps??{});if(0===n.length){this.logger.info(`Stage "${e.label}" has no steps — skipping.`);const t=q(e.router,this.store.get(!0),{});return o(W(t))}if(this.controller.signal.aborted)return c(new r({code:s.OPERATION_ABORTED.code,message:`Aborted before resolving steps in stage "${e.label}".`,operation:`stage:${e.id}`}));const a=void 0!==i?.step?n.filter((e=>e.id===i.step)):n;if(void 0!==i?.step&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry step "${i.step}" not found in stage "${e.label}".`,operation:`stage:${e.id}`}));for(const e of a)this.bus.emit("step:start",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id});const h=await Promise.all(a.map((async t=>({step:t,result:await this.container.resolve(V(this.keyPrefix,e.id,t.id))})))),d={};for(const{step:e,result:i}of h)i.ready?(this.bus.emit("step:success",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id}),d[e.id]=o(i.instance)):(this.bus.emit("step:failure",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id,error:i.error}),d[e.id]=c(new r({code:s.BACKEND_ERROR.code,message:Y(i.error)})));const u=h.find((({result:e})=>!e.ready));if(u){const e=u.result.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Step "${u.step.label}" failed: ${Y(e)}`,operation:`step:${u.step.id}`,cause:e}))}const l=h.map((({result:e})=>e.instance)).filter((e=>null!=e));let p;try{await this.store.transaction((async()=>{for(const e of l)await this.store.set(e);const t=q(e.router,this.store.get(!0),d);if(F(t)){let i;if(!0===t.persist)try{i=await this.container.export()}catch(t){throw this.logger.error("Container export failed during pause",t),new r({code:s.BACKEND_ERROR.code,message:`Failed to export container for pause: ${Y(t)}`,operation:`stage:${e.id}`,cause:t})}const n={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString(),containerBundle:i};await G(this.store,n),p={kind:"pause",checkpoint:n}}else p=W(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed during stage "${e.label}": ${Y(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}async executePipelinesStage(e,t,i){const n=e.pipelines,a=void 0!==i?.pipeline?(()=>{const{index:e}=i.pipeline,t=n[e];return t?[{subPipeline:t,originalIndex:e}]:[]})():n.map(((e,t)=>({subPipeline:e,originalIndex:t})));if(void 0!==i?.pipeline&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry sub‑pipeline index ${i.pipeline.index} out of bounds.`,operation:`stage:${e.id}`}));this.bus.emit("subpipeline:fork",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,subPipelineIds:a.map((({subPipeline:e})=>e.id))});const h=await Promise.all(a.map((async({subPipeline:s,originalIndex:r})=>{const n=void 0!==i?.pipeline?{stage:i.pipeline.stage,step:i.pipeline.step}:void 0,a=function(e,t,s){const i=`${t}:pipeline-${s}`;return e?`${e}:${i}`:i}(this.keyPrefix,e.id,r);return{subPipeline:s,originalIndex:r,ctx:await this.factory.buildRunContext(this.id,s,n,this.store,this.bus,t,this.container,a)}}))),d=()=>{h.forEach((({ctx:e})=>e.abort()))};this.controller.signal.addEventListener("abort",d,{once:!0});try{if(this.controller.signal.aborted)return d(),c(new r({code:s.OPERATION_ABORTED.code,message:this.controller.signal.reason,operation:`stage:${e.id}`}));const i=await Promise.all(h.map((({ctx:e})=>e.run()))),n={};for(let e=0;e<a.length;e++)n[a[e].subPipeline.id]=i[e];this.bus.emit("subpipeline:join",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,results:n});const u=i.findIndex((e=>!e.ok||"failed"===e.value.status));if(-1!==u){const t=a[u].subPipeline.id,n=i[u],o=n.ok?n.value.error:n.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Sub‑pipeline "${t}" failed: ${Y(o)}`,operation:`stage:${e.id}`,cause:o}))}const l=i.findIndex((e=>e.ok&&"paused"===e.value.status));if(-1!==l){const t=i[l].value,{checkpoint:n}=t,h={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:e.id,pipeline:{index:a[l].originalIndex,stage:n.resumeAt.stage,step:n.resumeAt.step}},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};try{await this.store.transaction((async()=>{await G(this.store,h)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Failed to write parent pause checkpoint for stage "${e.label}".`,operation:`stage:${e.id}`,cause:t}))}return o({kind:"pause",checkpoint:h})}let p;try{await this.store.transaction((async()=>{const t=q(e.pipelinesRouter,this.store.get(!0),n);if(F(t)){let i;if(!0===t.persist)try{i=await this.container.export()}catch(t){throw this.logger.error("Container export failed during pause",t),new r({code:s.BACKEND_ERROR.code,message:`Failed to export container for pause: ${Y(t)}`,operation:`stage:${e.id}`,cause:t})}const n={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString(),containerBundle:i};await G(this.store,n),p={kind:"pause",checkpoint:n}}else p=W(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed evaluating router for stage "${e.label}": ${Y(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}finally{this.controller.signal.removeEventListener("abort",d)}}failPipeline(e){return this.bus.emit("pipeline:failure",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,error:e}),c(e)}};function U(e){const t=[...e.stages].sort(((e,t)=>e.order-t.order)),s=new Map,i=new Map;for(let e=0;e<t.length;e++){const r=t[e];s.set(r.id,r),i.set(r.id,e)}return{stageMap:s,orderedStages:t,stageOrderIndex:i}}function j(e,t,s){const i=[];for(const r of e.stages)if(r.steps)for(const e of Object.values(r.steps)){const n={runId:s.runId,pipelineId:s.pipelineId,stageId:r.id,stepId:e.id,signal:s.signal};i.push({key:V(t,r.id,e.id),factory:t=>e.action(t,n),scope:e.scope,...void 0!==e.timeout&&{timeout:e.timeout},...void 0!==e.retries&&{retries:e.retries}})}return i}function V(e,t,s){return e?`${e}:${t}:${s}`:`${t}:${s}`}function q(e,t,s){return e?e(t,s):void 0}function W(e){return{kind:"advance",nextInstruction:e}}function Y(e){return e instanceof Error?e.message:String(e)}async function G(e,t){const s=e,i=t.pipelineId,r=t.runId,n=s.get(!0)[K]??{},a={...n,[i]:{...n[i]??{},[r]:t}};await s.set({[K]:a})}exports.PIPELINE_DATA_KEY=K,exports.Pipeline=class{steps=new Map;globalBus=e.createEventBus();serializer=new g;executions=new Map;constructor(e){e&&e.forEach(((e,t)=>{(Array.isArray(e)?e:[e]).forEach((e=>this.steps.set(e.key,{...e,order:t})))}))}getSteps(){return this.steps}step(e){return this.steps.set(e.key,e),this}on(e,t){return this.globalBus.subscribe(e,t)}prepare(e,t,s,i){return new f(this,e,t,s?.signal,i)}async execute(e,t,s){const i=s?.disableDeduplication?`${e}:${Date.now()}:${Math.random()}`:this.getDedupeKey(e,t);let r=this.executions.get(i);r||(r=new p({retry:!0,throws:!1}),this.executions.set(i,r));const n=await r.do((async()=>{const i=await this.serializer.do((async()=>{const i=this.prepare(e,t,{signal:s?.signal},this.globalBus);return await i.run()}));if(i.error)throw i.error;return i.value})).finally((()=>{setTimeout((()=>this.executions.delete(i)),0)}));return n.error?c(n.error):n.value}getRegisteredSteps(){return Array.from(this.steps.keys())}validate(){const e=[];return 0===this.steps.size&&e.push("Pipeline has no registered steps"),e}destroy(){this.steps.clear(),this.globalBus.clear(),this.executions.clear()}groupByOrder(){const e=new Map;for(const t of this.steps.values()){const s=e.get(t.order)??[];s.push(t),e.set(t.order,s)}return e}getDedupeKey(e,t){try{return`${e}:${JSON.stringify(this.sortObjectKeys(t))}`}catch{return`${e}:${Date.now()}:${Math.random()}`}}sortObjectKeys(e){if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map((e=>this.sortObjectKeys(e)));const t={};return Object.keys(e).sort().forEach((s=>{t[s]=this.sortObjectKeys(e[s])})),t}},exports.PipelineEngine=class{constructor(e,t){this.definition=e,this.logger=t.logger??B,this.storeFactory=t.storeFactory,this.initialStateFactory=t.initialStateFactory,this.index=U(e)}logger;storeFactory;initialStateFactory;index;async prepare(e,s){const i=s??t.v7(),r=await this.storeFactory(i);await r.ready();const n=this.initialStateFactory?.()??{};return await r.set(n),this.logger.info(`Prepared new run "${i}" for pipeline "${this.definition.id}"`),this.buildRunContext(i,this.definition,e,r,void 0,[])}async resume(e){const t=await this.storeFactory(e),i=function(e,t,s){const i=e,r=i.get(!0)[K],n=r?.[t]?.[s];return n??null}(t,this.definition.id,e);return i?i.pipelineId!==this.definition.id?c(new r({code:s.INVALID_COMMAND.code,message:`Checkpoint runId "${e}" belongs to pipeline "${i.pipelineId}", not "${this.definition.id}".`,operation:"resume"})):(this.logger.info(`Resuming pipeline "${this.definition.id}" [${e}] from stage "${i.pausedAtStageId}"`),o(await this.buildRunContext(e,this.definition,i.resumeAt,t,void 0,[],void 0,void 0,i.containerBundle))):c(new r({code:s.NOT_FOUND.code,message:`No checkpoint found for runId "${e}".`,operation:"resume"}))}async buildRunContext(t,s,i,r,n,a,o,c,h){const d=void 0===o,u=c??"",l=new AbortController,g={runId:t,pipelineId:s.id,signal:l.signal};let f;h?f=await L.from({store:r,bundle:h,templates:j(s,u,g)}):(f=d?new L(r):o,function(e,t,s,i){for(const r of t.stages)if(r.steps)for(const t of Object.values(r.steps)){const n={runId:i.runId,pipelineId:i.pipelineId,stageId:r.id,stepId:t.id,signal:i.signal};e.register({key:V(s,r.id,t.id),factory:e=>t.action(e,n),scope:t.scope,...void 0!==t.timeout&&{timeout:t.timeout},...void 0!==t.retries&&{retries:t.retries}})}}(f,s,u,g));const y=function(e,t){return{emit(s,i){e.emit({name:s,payload:i}),t?.emit(s,i)},on:(t,s)=>e.subscribe(t,s)}}(e.createEventBus(),n),m=new p({retry:!1,throws:!1}),w=d?this.index:U(s);return new z(t,s,i,r,f,u,y,a,l,m,this.logger,this.definition.id,w,this)}},exports.SequentialExecutionContext=f,exports.isPauseInstruction=F;
|
package/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEventBus as e}from"@asaidimu/utils-events";import{v7 as t}from"uuid";var s={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},i=new Map;var r=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const r={...function(e){const t=Object.values(s).find((t=>t.code===e));if(t)return t;return i.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??r.description),this.name="SystemError",this.code=t.code,this.codeMetadata=r,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},n="SYS-001",a=(e,t)=>new r({code:n,message:t,cause:e}),o=e=>({ok:!0,value:e}),c=e=>({ok:!1,error:e}),h=class e extends r{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},d=class e extends h{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},u=class e extends h{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},l=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let i;await Promise.race([s.then((()=>clearTimeout(i))),new Promise(((s,r)=>{i=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new d("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},p=class{mutex=new l({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let i;return Promise.race([e.then((e=>(clearTimeout(i),e))),new Promise(((e,r)=>{i=setTimeout((()=>r(new d(s))),t)}))])}},g=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new l({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new u};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,i=null;try{if(this._done)throw new u;i=await e(),this._lastValue=i,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:i,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},f=class{constructor(t,s,i,r,n){this.pipeline=t,this.stepKey=s,this.params=i,r&&(r.aborted&&this.controller.abort(),r.addEventListener("abort",(()=>this.controller.abort()))),this.localBus=n??e()}id=Math.random().toString(36).substring(2,9);localBus;controller=new AbortController;once=new p({retry:!1,throws:!1});get signal(){return this.controller.signal}on(e,t){return this.localBus.subscribe(e,t)}abort(){this.controller.abort()}async run(){const{value:e,error:t}=await this.once.do((()=>this._run()));return t?c(t):e}async _run(){const e=this.pipeline.getSteps().get(this.stepKey);if(!e)return{ok:!1,error:new r({code:s.INVALID_COMMAND.code,message:`No step registered with key "${this.stepKey}"`,operation:this.stepKey})};if(this.signal.aborted)return this.failCancelled("Pipeline execution aborted before initialization",this.stepKey);const t=this.pipeline.groupByOrder(),i=Array.from(t.entries()).sort((([e],[t])=>e-t)),n=e.order;this.emit("start",{stepKey:this.stepKey,executionId:this.id});let a={[this.stepKey]:this.params},o=a,c=!0;for(const[e,t]of i){if(e<n)continue;if(this.signal.aborted)return this.failCancelled(`Pipeline runtime aborted at stage ${e}`,this.stepKey);const s=c?t.filter((e=>e.key===this.stepKey)):t;if(c=!1,0===s.length)continue;const i=await this.runStage(s,a);if(!i.ok)return i;o=i.value,a={...a,...o},this.emit("stage:success",{order:e,executionId:this.id,carry:o})}return this.emit("terminate",{carry:o,executionId:this.id}),{ok:!0,value:o}}async runStage(e,t){const s=await Promise.all(e.map((async e=>{try{if(this.signal.aborted)return{step:e,result:this.failCancelled("Aborted mid-flight execution sequence",e.key)};const s=await e.action(t,this.signal);return{step:e,result:s}}catch(t){return{step:e,result:{ok:!1,error:t instanceof r?t:a(t,t instanceof Error?t.message:"Unexpected exception raised during step run")}}}}))),i={};let n=null;for(const{step:e,result:t}of s)if(t.ok)this.emit("step:success",{stepKey:e.key,executionId:this.id,result:t.value}),i[e.key]=t.value;else{const s=t.error.withOperation(e.key);this.emit("step:failure",{stepKey:e.key,executionId:this.id,error:s}),n||(n={ok:!1,error:s},this.emit("failure",{stepKey:e.key,executionId:this.id,error:s}))}return n||{ok:!0,value:i}}emit(e,t){this.localBus.emit({name:e,payload:t})}failCancelled(e,t){return{ok:!1,error:new r({code:"CANCELLED",message:e,operation:t})}}},y=class{steps=new Map;globalBus=e();serializer=new g;executions=new Map;constructor(e){e&&e.forEach(((e,t)=>{(Array.isArray(e)?e:[e]).forEach((e=>this.steps.set(e.key,{...e,order:t})))}))}getSteps(){return this.steps}step(e){return this.steps.set(e.key,e),this}on(e,t){return this.globalBus.subscribe(e,t)}prepare(e,t,s,i){return new f(this,e,t,s?.signal,i)}async execute(e,t,s){const i=s?.disableDeduplication?`${e}:${Date.now()}:${Math.random()}`:this.getDedupeKey(e,t);let r=this.executions.get(i);r||(r=new p({retry:!0,throws:!1}),this.executions.set(i,r));const n=await r.do((async()=>{const i=await this.serializer.do((async()=>{const i=this.prepare(e,t,{signal:s?.signal},this.globalBus);return await i.run()}));if(i.error)throw i.error;return i.value})).finally((()=>{setTimeout((()=>this.executions.delete(i)),0)}));return n.error?c(n.error):n.value}getRegisteredSteps(){return Array.from(this.steps.keys())}validate(){const e=[];return 0===this.steps.size&&e.push("Pipeline has no registered steps"),e}destroy(){this.steps.clear(),this.globalBus.clear(),this.executions.clear()}groupByOrder(){const e=new Map;for(const t of this.steps.values()){const s=e.get(t.order)??[];s.push(t),e.set(t.order,s)}return e}getDedupeKey(e,t){try{return`${e}:${JSON.stringify(this.sortObjectKeys(t))}`}catch{return`${e}:${Date.now()}:${Math.random()}`}}sortObjectKeys(e){if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map((e=>this.sortObjectKeys(e)));const t={};return Object.keys(e).sort().forEach((s=>{t[s]=this.sortObjectKeys(e[s])})),t}},m=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new p({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function w(e,t){if(!e.length)return;const s=e.slice(),i=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${i} Cleanup error at index ${e}:`,t)}}}async function v(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function b(e){return`${e}__watched`}var S=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function k(e,t){let s;const i=new Promise(((e,i)=>{s=setTimeout((()=>i(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,i])}finally{clearTimeout(s)}}var I=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t,s){const i=this.get(e);if(!i)return S;if(i.package)return i.package;const r=e,n=w(i.cleanupFunctions,r),a="singleton"!==i.scope||void 0!==i.instance,o={instance:i.instance,error:i.error,ready:a,[s||e]:i.instance,cleanup:n,invalidate:t};return i.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const i=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new p({retry:!0,throws:!0}),t||(s.streamSerializer=new g,s.controller=new AbortController)),await v(s.cleanupFunctions,i),await v(s.disposeFunctions,i),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new p({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},A=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??_}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),i=new Set(t);for(const t of s)i.has(t)||this.removeDependency(e,t);for(const t of i)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],i=new Set([t]),r=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let i=e;for(;void 0!==i&&(s.push(i),i!==t);)i=r.get(i);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)i.has(e)||(i.add(e),r.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,i]of e)0===i&&s.push(t);const i=[];for(;s.length>0;){const t=s.shift();i.push(t);const r=this.dependents.get(t);if(r)for(const t of r){const i=(e.get(t)||0)-1;e.set(t,i),0===i&&s.push(t)}}if(i.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return i}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const i=new Set,r=new Set,n=[e];r.add(e),s&&i.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)r.has(e)||(r.add(e),i.add(e),n.push(e))}return i}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},_=new Set,E=class{graph;constructor(){this.graph=new A}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),i=e.indexOf(t),r=e.slice(i);return r.push(t),r}const i=this.graph.wouldCreateCycle(e,t);return i||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},O=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var $=class e extends Error{category;constructor(t,s,i){super(t,{cause:i}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},x=class extends ${constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},D=class extends ${constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},C=(new AbortController).signal,R=class{constructor(e,t,s,i,r){this.registry=e,this.cache=t,this.graph=s,this.store=i,this.observer=r}async build(e,t,s){const i=this.cache.get(e);if("singleton"===i?.scope&&i.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const r=this.registry.getByString(e);if(!r)throw new x(e);const n=t??[];if(n.includes(e))throw new $(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=i;a||(a=this.createCachedArtifact(r),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(r,a,n);const i=a;try{await i.buildOnce.do((()=>this.executeBuild(r,i,n)))}catch(i){if(i instanceof D)return this.build(e,t,s);throw i}return i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const i=e.key,r=String(i),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,r,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(i,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[i]:e,cleanup:w(a.cleanupFunctions,r),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${r}"`)}}}buildContext(e,t,s,i,r){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=r,l=async(e,t)=>{const r=t?this.computeParamKey(e,t):e;if(r===n)throw new $(`Artifact "${i}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,r);if(a)throw new $(`Adding dependency "${String(r)}" to "${i}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(r);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(r);return c&&d.set(r,c.version),o},p="singleton"===t.scope?t.controller.signal:C,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},f=(e,t)=>{const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const n=new Proxy((()=>{}),{get:(i,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(O.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),r(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return i.set(e,n),n};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:f}),stream:e=>{if(a)throw new $(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=t,r=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(i))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await r(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const i=t.signal,r=(e.retries??0)+1;let n=0;for(;n<r;)try{if(i.aborted)throw new D;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await k(a,e.timeout):await a:a,i.aborted)throw new D;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<r)continue;return{ok:!1,error:new $(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(i.aborted||e instanceof D)throw new D;if(e instanceof $)throw e;if(n++,n>=r)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,i,r){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=r;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a),i.ok?(t.instance=i.value,t.error=void 0):(t.instance=void 0,t.error=i.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const i=this.cache.get(e);if(!i)return;if("singleton"!==i.scope)return this.executeInvalidation(e,t,s);const r=i;return r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),!t&&r.activeDebounceMs>0?new Promise(((i,n)=>{r.debounceTimer=setTimeout((()=>{r.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(i).catch(n)}),r.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const i=this.cache.get(e);i&&"singleton"===i.scope&&await i.invalidationSerializer.do((async()=>{i.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const r=this.registry.get(e),n=r&&(t||!r.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof D||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const i=this.cache.get(e);if(!i||"singleton"!==i.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),i.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)i.stateDependencies.add(t);if(i.stateUnsubscribe&&(i.stateUnsubscribe(),i.stateUnsubscribe=void 0),0===s.length)return;const r=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let i=n.get(s);i||(i={options:t,paths:new Set},n.set(s,i));for(const t of e)i.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,r)):a.push(this.store.watch(s,r,e))}0===a.length?i.stateUnsubscribe=void 0:1===a.length?i.stateUnsubscribe=a[0]:i.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new p({retry:!0,throws:!0}),streamOnce:new p({retry:!0,throws:!0}),streamSerializer:new g({yieldMode:"microtask"}),invalidationSerializer:new g({yieldMode:"macrotask"})}}resolveStatic(e){if(!this.registry.has(e))throw new x(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new x(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new $(`Artifact "${String(e)}" is not parameterized.`,"external");const i=s.paramKey(t),r=this.registry.getByString(i);if(r&&!r.paramKey&&!r.virtual)throw new $(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${i}" which is already registered as a static artifact.`,"system");return this.registry.hasString(i)||this.registry.setVirtual(i,{key:i,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(i,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},N=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const i=this.registry.get(e);if(!i.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const r=i.paramKey(t);return this.watchForKey(r,i,s,t)}watchForKey(e,t,s,i){const r="transient"===t.scope,n=r?b(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new m((async()=>{!r&&void 0===i||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:r?t.factory:e=>t.factory({...e,params:i}),scope:r?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{r||void 0!==i?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:r&&void 0===i?"sync":s});let c;const h={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):S,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(h.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:h}),h}evictWatcher(e){[e,b(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(b(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(b(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},P=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...i}){const{scope:r,...n}=i,a={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new x(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},M=class{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t)},this.registry=new P,this.cache=new I,this.graph=new E,this.observer=new N(this.registry,this.cache,this),this.manager=new R(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,i=this.registry.get(s),r=this.cache.get(s);if(!i)return;let n="idle";r&&("singleton"===r.scope&&void 0!==r.debounceTimer?n="debouncing":"singleton"===r.scope&&r.buildOnce.running()?n="building":r.error?n="error":void 0!==r.instance&&(n="active")),e.push({id:s,scope:i.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===r?.scope?Array.from(r.stateDependencies):[],buildCount:r?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const i=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==i||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,i=t?.replace??!1,r=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(r,i)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}};function T(e){return"object"==typeof e&&null!==e&&"pause"in e}var L="__pipeline_data__";var F={info:()=>{},error:()=>{}},K=class{constructor(e,t){this.definition=e,this.logger=t.logger??F,this.storeFactory=t.storeFactory,this.initialStateFactory=t.initialStateFactory,this.index=B(e)}logger;storeFactory;initialStateFactory;index;async prepare(e,s){const i=s??t(),r=await this.storeFactory(i);await r.ready();const n=this.initialStateFactory?.()??{};return await r.set(n),this.logger.info(`Prepared new run "${i}" for pipeline "${this.definition.id}"`),this.buildRunContext(i,this.definition,e,r,void 0,[])}async resume(e){const t=await this.storeFactory(e),i=function(e,t,s){const i=e,r=i.get(!0)[L],n=r?.[t]?.[s];return n??null}(t,this.definition.id,e);return i?i.pipelineId!==this.definition.id?c(new r({code:s.INVALID_COMMAND.code,message:`Checkpoint runId "${e}" belongs to pipeline "${i.pipelineId}", not "${this.definition.id}".`,operation:"resume"})):(this.logger.info(`Resuming pipeline "${this.definition.id}" [${e}] from stage "${i.pausedAtStageId}"`),o(this.buildRunContext(e,this.definition,i.resumeAt,t,void 0,[]))):c(new r({code:s.NOT_FOUND.code,message:`No checkpoint found for runId "${e}".`,operation:"resume"}))}buildRunContext(t,s,i,r,n,a,o,c){const h=void 0===o,d=h?new M(r):o,u=c??"",l=new AbortController;!function(e,t,s,i){for(const r of t.stages)if(r.steps)for(const t of Object.values(r.steps)){const n={runId:i.runId,pipelineId:i.pipelineId,stageId:r.id,stepId:t.id,signal:i.signal};e.register({key:U(s,r.id,t.id),factory:e=>t.action(e,n),scope:t.scope,...void 0!==t.timeout&&{timeout:t.timeout},...void 0!==t.retries&&{retries:t.retries}})}}(d,s,u,{runId:t,pipelineId:s.id,signal:l.signal});const g=function(e,t){return{emit(s,i){e.emit({name:s,payload:i}),t?.emit(s,i)},on:(t,s)=>e.subscribe(t,s)}}(e(),n),f=new p({retry:!1,throws:!1}),y=h?this.index:B(s);return new z(t,s,i,r,d,u,g,a,l,f,this.logger,this.definition.id,y,this)}},z=class{constructor(e,t,s,i,r,n,a,o,c,h,d,u,l,p){this.pipeline=t,this.entry=s,this.store=i,this.container=r,this.keyPrefix=n,this.bus=a,this.parentPath=o,this.controller=c,this.once=h,this.logger=d,this.definitionId=u,this.index=l,this.factory=p,this.id=e}id;on(e,t){return this.bus.on(e,t)}abort(){this.controller.abort()}async run(){const e=await this.once.do((()=>this.execute()));return void 0!==e.error?c(new r({code:s.INTERNAL_ERROR.code,message:`Unexpected throw escaped run(): ${q(e.error)}`,operation:`pipeline:${this.pipeline.id}`,cause:e.error})):e.value}async execute(){this.bus.emit("pipeline:start",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id}),this.logger.info(`Pipeline start: ${this.pipeline.id} [${this.id}]`);const e=this.resolveEntryStage();if(!e.ok)return this.failPipeline(e.error);const{stageMap:t,orderedStages:i,stageOrderIndex:n}=this.index;let a=e.value,c=!0;for(;;){if(this.controller.signal.aborted){const e=new r({code:s.OPERATION_ABORTED.code,message:`Run aborted before stage "${a.label}".`,operation:`stage:${a.id}`});return this.failPipeline(e)}const e=c?this.entry:void 0;c=!1;const h=await this.executeStage(a,e);if(!h.ok)return this.failPipeline(h.error);const d=h.value,u="pause"===d.kind?void 0:d.nextInstruction,l=n.get(a.id)??-1,p=void 0!==i[l+1],g="pause"===d.kind?"pause":null===u?"terminate":"string"==typeof u?"jump":p?"advance":"natural-end";if(this.bus.emit("router:evaluated",{path:this.parentPath,stageId:a.id,stageLabel:a.label,runId:this.id,instruction:u,interpretation:g}),"pause"===d.kind){const{checkpoint:e}=d,t=this.store.get(!0);return this.logger.info(`Pipeline paused: ${this.pipeline.id} [${this.id}] at stage "${e.pausedAtStageId}"`),this.bus.emit("pipeline:paused",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,checkpoint:e,finalState:t}),o({status:"paused",runId:this.id,finalState:t,checkpoint:e})}if(null===u)break;if("string"==typeof u){const e=t.get(u);if(!e){const e=new r({code:s.INVALID_COMMAND.code,message:`Router on stage "${a.label}" returned unknown stageId: "${u}"`,operation:`stage:${a.id}`});return this.failPipeline(e)}a=e;continue}const f=i[l+1];if(!f)break;a=f}const h=this.store.get(!0);return this.logger.info(`Pipeline succeeded: ${this.pipeline.id} [${this.id}]`),this.bus.emit("pipeline:success",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,finalState:h}),o({status:"succeeded",runId:this.id,finalState:h})}resolveEntryStage(){const{stageMap:e,orderedStages:t}=this.index;if(this.entry?.stage){const t=e.get(this.entry.stage);return t?o(t):c(new r({code:s.INVALID_COMMAND.code,message:`Entry stage "${this.entry.stage}" not found.`,operation:`pipeline:${this.pipeline.id}`}))}const i=t[0];return i?o(i):c(new r({code:s.INVALID_COMMAND.code,message:"Pipeline has no stages.",operation:`pipeline:${this.pipeline.id}`}))}async executeStage(e,t){const s=e.pipelines&&e.pipelines.length>0?"pipelines":"steps",i=[...this.parentPath,{kind:"stage",id:e.id,label:e.label}];this.bus.emit("stage:start",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,mode:s});const r="pipelines"===s?await this.executePipelinesStage(e,i,t):await this.executeStepsStage(e,i,t);return r.ok?"pause"===r.value.kind?this.bus.emit("stage:paused",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,checkpoint:r.value.checkpoint}):this.bus.emit("stage:success",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,nextInstruction:r.value.nextInstruction}):this.bus.emit("stage:failure",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,error:r.error}),r}async executeStepsStage(e,t,i){const n=Object.values(e.steps??{});if(0===n.length){this.logger.info(`Stage "${e.label}" has no steps — skipping.`);const t=V(e.router,this.store.get(!0),{});return o(j(t))}if(this.controller.signal.aborted)return c(new r({code:s.OPERATION_ABORTED.code,message:`Aborted before resolving steps in stage "${e.label}".`,operation:`stage:${e.id}`}));const a=void 0!==i?.step?n.filter((e=>e.id===i.step)):n;if(void 0!==i?.step&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry step "${i.step}" not found in stage "${e.label}".`,operation:`stage:${e.id}`}));for(const e of a)this.bus.emit("step:start",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id});const h=await Promise.all(a.map((async t=>({step:t,result:await this.container.resolve(U(this.keyPrefix,e.id,t.id))})))),d={};for(const{step:e,result:i}of h)i.ready?(this.bus.emit("step:success",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id}),d[e.id]=o(i.instance)):(this.bus.emit("step:failure",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id,error:i.error}),d[e.id]=c(new r({code:s.BACKEND_ERROR.code,message:q(i.error)})));const u=h.find((({result:e})=>!e.ready));if(u){const e=u.result.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Step "${u.step.label}" failed: ${q(e)}`,operation:`step:${u.step.id}`,cause:e}))}const l=h.map((({result:e})=>e.instance)).filter((e=>null!=e));let p;try{await this.store.transaction((async()=>{for(const e of l)await this.store.set(e);const t=V(e.router,this.store.get(!0),d);if(T(t)){const s={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};await W(this.store,s),p={kind:"pause",checkpoint:s}}else p=j(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed during stage "${e.label}": ${q(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}async executePipelinesStage(e,t,i){const n=e.pipelines,a=void 0!==i?.pipeline?(()=>{const{index:e}=i.pipeline,t=n[e];return t?[{subPipeline:t,originalIndex:e}]:[]})():n.map(((e,t)=>({subPipeline:e,originalIndex:t})));if(void 0!==i?.pipeline&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry sub‑pipeline index ${i.pipeline.index} out of bounds.`,operation:`stage:${e.id}`}));this.bus.emit("subpipeline:fork",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,subPipelineIds:a.map((({subPipeline:e})=>e.id))});const h=a.map((({subPipeline:s,originalIndex:r})=>{const n=void 0!==i?.pipeline?{stage:i.pipeline.stage,step:i.pipeline.step}:void 0,a=function(e,t,s){const i=`${t}:pipeline-${s}`;return e?`${e}:${i}`:i}(this.keyPrefix,e.id,r);return{subPipeline:s,originalIndex:r,ctx:this.factory.buildRunContext(this.id,s,n,this.store,this.bus,t,this.container,a)}})),d=()=>{h.forEach((({ctx:e})=>e.abort()))};this.controller.signal.addEventListener("abort",d,{once:!0});try{if(this.controller.signal.aborted)return d(),c(new r({code:s.OPERATION_ABORTED.code,message:this.controller.signal.reason,operation:`stage:${e.id}`}));const i=await Promise.all(h.map((({ctx:e})=>e.run()))),n={};for(let e=0;e<a.length;e++)n[a[e].subPipeline.id]=i[e];this.bus.emit("subpipeline:join",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,results:n});const u=i.findIndex((e=>!e.ok||"failed"===e.value.status));if(-1!==u){const t=a[u].subPipeline.id,n=i[u],o=n.ok?n.value.error:n.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Sub‑pipeline "${t}" failed: ${q(o)}`,operation:`stage:${e.id}`,cause:o}))}const l=i.findIndex((e=>e.ok&&"paused"===e.value.status));if(-1!==l){const t=i[l].value,{checkpoint:n}=t,h={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:e.id,pipeline:{index:a[l].originalIndex,stage:n.resumeAt.stage,step:n.resumeAt.step}},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};try{await this.store.transaction((async()=>{await W(this.store,h)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Failed to write parent pause checkpoint for stage "${e.label}".`,operation:`stage:${e.id}`,cause:t}))}return o({kind:"pause",checkpoint:h})}let p;try{await this.store.transaction((async()=>{const t=V(e.pipelinesRouter,this.store.get(!0),n);if(T(t)){const s={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};await W(this.store,s),p={kind:"pause",checkpoint:s}}else p=j(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed evaluating router for stage "${e.label}": ${q(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}finally{this.controller.signal.removeEventListener("abort",d)}}failPipeline(e){return this.bus.emit("pipeline:failure",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,error:e}),c(e)}};function B(e){const t=[...e.stages].sort(((e,t)=>e.order-t.order)),s=new Map,i=new Map;for(let e=0;e<t.length;e++){const r=t[e];s.set(r.id,r),i.set(r.id,e)}return{stageMap:s,orderedStages:t,stageOrderIndex:i}}function U(e,t,s){return e?`${e}:${t}:${s}`:`${t}:${s}`}function V(e,t,s){return e?e(t,s):void 0}function j(e){return{kind:"advance",nextInstruction:e}}function q(e){return e instanceof Error?e.message:String(e)}async function W(e,t){const s=e,i=t.pipelineId,r=t.runId,n=s.get(!0)[L]??{},a={...n,[i]:{...n[i]??{},[r]:t}};await s.set({[L]:a})}export{L as PIPELINE_DATA_KEY,y as Pipeline,K as PipelineEngine,f as SequentialExecutionContext,T as isPauseInstruction};
|
|
1
|
+
import{createEventBus as e}from"@asaidimu/utils-events";import{v7 as t}from"uuid";var s={VALIDATION_FAILED:{code:"VAL-001",name:"VALIDATION_FAILED",description:"Input validation failed due to one or more invalid fields",category:"validation",httpStatus:400,logLevel:"warn"},REQUIRED_FIELD_MISSING:{code:"VAL-002",name:"REQUIRED_FIELD_MISSING",description:"A required field was not provided in the request",category:"validation",httpStatus:400,logLevel:"warn"},INVALID_FORMAT:{code:"VAL-003",name:"INVALID_FORMAT",description:"Field value does not match expected format",category:"validation",httpStatus:400,logLevel:"warn"},NOT_FOUND:{code:"DB-001-NF",name:"NOT_FOUND",description:"The requested resource could not be found",category:"database",httpStatus:404,logLevel:"info",action:"Verify the resource identifier exists before accessing"},DUPLICATE_KEY:{code:"DB-002-DUP",name:"DUPLICATE_KEY",description:"A unique constraint violation occurred",category:"database",httpStatus:409,logLevel:"warn",action:"Check if the resource already exists before creation"},RESOURCE_LOCKED:{code:"DB-003-LOCK",name:"RESOURCE_LOCKED",description:"The resource is currently locked by another operation",category:"database",httpStatus:409,logLevel:"warn",action:"Retry the operation after a brief delay"},PERMISSION_DENIED:{code:"AUTH-001-DENIED",name:"PERMISSION_DENIED",description:"The authenticated user lacks permission for this operation",category:"auth",httpStatus:403,logLevel:"warn",action:"Check user roles and permissions"},UNAUTHENTICATED:{code:"AUTH-002-UNAUTH",name:"UNAUTHENTICATED",description:"Authentication is required for this operation",category:"auth",httpStatus:401,logLevel:"info",action:"Provide valid authentication credentials"},INVALID_COMMAND:{code:"BUS-001",name:"INVALID_COMMAND",description:"The command or operation is invalid for the current state",category:"business",httpStatus:400,logLevel:"warn"},OPERATION_ABORTED:{code:"BUS-002-ABORT",name:"OPERATION_ABORTED",description:"The operation was explicitly aborted",category:"business",httpStatus:409,logLevel:"info"},INTERNAL_ERROR:{code:"SYS-001",name:"INTERNAL_ERROR",description:"An unexpected internal error occurred",category:"system",httpStatus:500,logLevel:"error",action:"Check system logs for stack traces and diagnostic information"},BACKEND_ERROR:{code:"SYS-002",name:"BACKEND_ERROR",description:"An error occurred in a backend service",category:"system",httpStatus:502,logLevel:"error"},CONCURRENCY_ERROR:{code:"CON-001",name:"CONCURRENCY_ERROR",description:"A concurrency conflict occurred during the operation",category:"concurrency",httpStatus:409,logLevel:"warn",action:"Retry the operation with updated data"}},i=new Map;var r=class e extends Error{code;codeMetadata;severity;path;operation;issues;cause;constructor(t){const r={...function(e){const t=Object.values(s).find((t=>t.code===e));if(t)return t;return i.get(e)||{code:e,name:e.replace(/-/g,"_"),description:`Unknown error: ${e}`,category:"custom",httpStatus:500,logLevel:"error",action:"Check if this error code is properly registered or handle as unknown error"}}(t.code),...t.metadata,code:t.code};super(t.message??r.description),this.name="SystemError",this.code=t.code,this.codeMetadata=r,this.severity=t.severity??"error",this.path=t.path,this.operation=t.operation,this.issues=t.issues??[],this.cause=t.cause,Object.setPrototypeOf(this,e.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,e)}withPath(t){return new e({code:this.code,message:this.message,severity:this.severity,path:t,operation:this.operation,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withOperation(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:t,issues:this.issues,cause:this.cause,metadata:this.codeMetadata})}withIssue(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,t],cause:this.cause,metadata:this.codeMetadata})}withIssues(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:[...this.issues,...t],cause:this.cause,metadata:this.codeMetadata})}withCause(t){return new e({code:this.code,message:this.message,severity:this.severity,path:this.path,operation:this.operation,issues:this.issues,cause:t,metadata:this.codeMetadata})}getHttpStatus(){return this.codeMetadata.httpStatus}toLogEntry(){return{name:this.name,code:this.code,category:this.codeMetadata.category,message:this.message,path:this.path,operation:this.operation,issues:this.issues,cause:this.cause instanceof Error?this.cause.message:this.cause,stack:this.stack,timestamp:(new Date).toISOString()}}toString(){let e=`[${this.code}] ${this.message} (${this.codeMetadata.category})`;return this.path&&(e+=` at '${this.path}'`),this.operation&&(e+=` during '${this.operation}'`),this.issues.length>0&&(e+="\nIssues:\n"+this.issues.map(((e,t)=>` ${t+1}. ${e.message} [${e.code}]`)).join("\n")),this.cause&&(e+=`\nCause: ${this.cause instanceof Error?this.cause.message:String(this.cause)}`),e}},n="SYS-001",a=(e,t)=>new r({code:n,message:t,cause:e}),o=e=>({ok:!0,value:e}),c=e=>({ok:!1,error:e}),h=class e extends r{constructor(t,s){super({code:"SYNC_ERROR",message:t,cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},d=class e extends h{constructor(t){super(`[ArtifactContainer] Operation timed out: ${t}`),this.name="TimeoutError",Object.setPrototypeOf(this,e.prototype)}},u=class e extends h{constructor(t){super("[Serializer] The serializer has been marked as done!",t),this.name="SerializerExecutionDone",Object.setPrototypeOf(this,e.prototype)}},l=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));if(this.waiters.push(t),null==e)return void await s;let i;await Promise.race([s.then((()=>clearTimeout(i))),new Promise(((s,r)=>{i=setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new d("Mutex lock timed out"))}),e)}))])}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},p=class{mutex=new l({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}resolve(e){if(this._done)throw new Error("Cannot resolve: operation is already completed.");if(this.running())throw new Error("Cannot resolve: operation is currently running.");this._value=e,this._done=!0}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{this._value=await e(),this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.retry&&!this._done&&(this.promise=null)}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}running(){return null!==this.promise&&!this.done()}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){if(this.running())throw new Error("Cannot reset Once while an operation is in progress.");this._done=!1,this.promise=null,this._value=null,this._error=void 0}done(){return this._done}current(){return this.promise}_awaitWithTimeout(e,t,s="Operation timed out"){if(null==t)return e;let i;return Promise.race([e.then((e=>(clearTimeout(i),e))),new Promise(((e,r)=>{i=setTimeout((()=>r(new d(s))),t)}))])}},g=class{mutex;_done=!1;_lastValue=null;_lastError=void 0;_hasRun=!1;constructor(e){this.mutex=new l({capacity:e?.capacity??1e3,yieldMode:e?.yieldMode??"macrotask"})}async do(e,t){if(this._done)return{value:null,error:new u};try{await this.mutex.lock(t)}catch(e){return{value:null,error:e}}let s,i=null;try{if(this._done)throw new u;i=await e(),this._lastValue=i,this._lastError=void 0,this._hasRun=!0}catch(e){s=e,this._lastError=e,this._hasRun=!0}finally{this.mutex.unlock()}return{value:i,error:s}}peek(){return{value:this._lastValue,error:this._lastError}}hasRun(){return this._hasRun}close(){this._done=!0}pending(){return this.mutex.pending()}running(){return this.mutex.locked()}},f=class{constructor(t,s,i,r,n){this.pipeline=t,this.stepKey=s,this.params=i,r&&(r.aborted&&this.controller.abort(),r.addEventListener("abort",(()=>this.controller.abort()))),this.localBus=n??e()}id=Math.random().toString(36).substring(2,9);localBus;controller=new AbortController;once=new p({retry:!1,throws:!1});get signal(){return this.controller.signal}on(e,t){return this.localBus.subscribe(e,t)}abort(){this.controller.abort()}async run(){const{value:e,error:t}=await this.once.do((()=>this._run()));return t?c(t):e}async _run(){const e=this.pipeline.getSteps().get(this.stepKey);if(!e)return{ok:!1,error:new r({code:s.INVALID_COMMAND.code,message:`No step registered with key "${this.stepKey}"`,operation:this.stepKey})};if(this.signal.aborted)return this.failCancelled("Pipeline execution aborted before initialization",this.stepKey);const t=this.pipeline.groupByOrder(),i=Array.from(t.entries()).sort((([e],[t])=>e-t)),n=e.order;this.emit("start",{stepKey:this.stepKey,executionId:this.id});let a={[this.stepKey]:this.params},o=a,c=!0;for(const[e,t]of i){if(e<n)continue;if(this.signal.aborted)return this.failCancelled(`Pipeline runtime aborted at stage ${e}`,this.stepKey);const s=c?t.filter((e=>e.key===this.stepKey)):t;if(c=!1,0===s.length)continue;const i=await this.runStage(s,a);if(!i.ok)return i;o=i.value,a={...a,...o},this.emit("stage:success",{order:e,executionId:this.id,carry:o})}return this.emit("terminate",{carry:o,executionId:this.id}),{ok:!0,value:o}}async runStage(e,t){const s=await Promise.all(e.map((async e=>{try{if(this.signal.aborted)return{step:e,result:this.failCancelled("Aborted mid-flight execution sequence",e.key)};const s=await e.action(t,this.signal);return{step:e,result:s}}catch(t){return{step:e,result:{ok:!1,error:t instanceof r?t:a(t,t instanceof Error?t.message:"Unexpected exception raised during step run")}}}}))),i={};let n=null;for(const{step:e,result:t}of s)if(t.ok)this.emit("step:success",{stepKey:e.key,executionId:this.id,result:t.value}),i[e.key]=t.value;else{const s=t.error.withOperation(e.key);this.emit("step:failure",{stepKey:e.key,executionId:this.id,error:s}),n||(n={ok:!1,error:s},this.emit("failure",{stepKey:e.key,executionId:this.id,error:s}))}return n||{ok:!0,value:i}}emit(e,t){this.localBus.emit({name:e,payload:t})}failCancelled(e,t){return{ok:!1,error:new r({code:"CANCELLED",message:e,operation:t})}}},y=class{steps=new Map;globalBus=e();serializer=new g;executions=new Map;constructor(e){e&&e.forEach(((e,t)=>{(Array.isArray(e)?e:[e]).forEach((e=>this.steps.set(e.key,{...e,order:t})))}))}getSteps(){return this.steps}step(e){return this.steps.set(e.key,e),this}on(e,t){return this.globalBus.subscribe(e,t)}prepare(e,t,s,i){return new f(this,e,t,s?.signal,i)}async execute(e,t,s){const i=s?.disableDeduplication?`${e}:${Date.now()}:${Math.random()}`:this.getDedupeKey(e,t);let r=this.executions.get(i);r||(r=new p({retry:!0,throws:!1}),this.executions.set(i,r));const n=await r.do((async()=>{const i=await this.serializer.do((async()=>{const i=this.prepare(e,t,{signal:s?.signal},this.globalBus);return await i.run()}));if(i.error)throw i.error;return i.value})).finally((()=>{setTimeout((()=>this.executions.delete(i)),0)}));return n.error?c(n.error):n.value}getRegisteredSteps(){return Array.from(this.steps.keys())}validate(){const e=[];return 0===this.steps.size&&e.push("Pipeline has no registered steps"),e}destroy(){this.steps.clear(),this.globalBus.clear(),this.executions.clear()}groupByOrder(){const e=new Map;for(const t of this.steps.values()){const s=e.get(t.order)??[];s.push(t),e.set(t.order,s)}return e}getDedupeKey(e,t){try{return`${e}:${JSON.stringify(this.sortObjectKeys(t))}`}catch{return`${e}:${Date.now()}:${Math.random()}`}}sortObjectKeys(e){if(null===e||"object"!=typeof e)return e;if(Array.isArray(e))return e.map((e=>this.sortObjectKeys(e)));const t={};return Object.keys(e).sort().forEach((s=>{t[s]=this.sortObjectKeys(e[s])})),t}},m=class{constructor(e,t,s={}){this.factory=e,this.onCleanup=t,this.options=s}_count=0;init=new p({retry:!1,throws:!1});pendingMicrotask=!1;cleanupTimer;get subscribers(){return this._count}async acquire(){this.cancelPendingCleanup(),this._count++;const e=await this.init.do(this.factory);if(e.error)throw e.error;return e.value}release(){this._count<=0?console.warn("SharedResource.release() called, but count is already 0."):(this._count--,0===this._count&&this.scheduleCleanup())}peek(){const e=this.init.peek();return e.error?null:e.value}forceCleanup(){this.cancelPendingCleanup(),this._count=0,this.executeCleanup()}cancelPendingCleanup(){this.pendingMicrotask=!1,void 0!==this.cleanupTimer&&(clearTimeout(this.cleanupTimer),this.cleanupTimer=void 0)}scheduleCleanup(){const e=this.options.gracePeriod??"microtask";if("sync"!==e)return"microtask"===e?(this.pendingMicrotask=!0,void queueMicrotask((()=>{!this.pendingMicrotask||this._count>0||(this.pendingMicrotask=!1,this.executeCleanup())}))):void(this.cleanupTimer=setTimeout((()=>{this.cleanupTimer=void 0,this._count>0||this.executeCleanup()}),e));this.executeCleanup()}executeCleanup(){const e=this.init.peek();try{this.onCleanup(e.value)}catch(e){console.error("[SharedResource] Error during cleanup callback:",e)}this.init.running()||this.init.reset()}};function w(e,t){if(!e.length)return;const s=e.slice(),i=t?`[${t}]`:"[ArtifactCleanup]";return async()=>{for(let e=s.length-1;e>=0;e--)try{await s[e]()}catch(t){console.error(`${i} Cleanup error at index ${e}:`,t)}}}async function v(e,t){const s=t?`[${t}]`:"[ArtifactCleanup]";for(let t=e.length-1;t>=0;t--)try{await e[t]()}catch(e){console.error(`${s} Cleanup error at index ${t}:`,e)}}function b(e){return`${e}__watched`}var S=Object.freeze({instance:void 0,error:void 0,ready:!1,cleanup:void 0,invalidate:async(e,t)=>{}});function k(e,t){let s;const i=new Promise(((e,i)=>{s=setTimeout((()=>i(new Error(`Timeout: ${t}ms`))),t)}));try{return Promise.race([e,i])}finally{clearTimeout(s)}}async function I(e){const t=(new TextEncoder).encode(e),s=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(s)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var A=class{cache=new Map;get(e){return this.cache.get(e)}set(e,t){this.cache.set(e,t)}delete(e){this.cache.delete(e)}has(e){return this.cache.has(e)}clear(){this.cache.clear()}size(){return this.cache.size}keys(){return Array.from(this.cache.keys())}package(e,t,s){const i=this.get(e);if(!i)return S;if(i.package)return i.package;const r=e,n=w(i.cleanupFunctions,r),a="singleton"!==i.scope||void 0!==i.instance,o={instance:i.instance,error:i.error,ready:a,[s||e]:i.instance,cleanup:n,invalidate:t};return i.package=o,o}invalidatePackage(e){const t=this.get(e);t&&(t.package=void 0)}async invalidateInstance(e,t=!1){const s=this.get(e);if(!s)return;const i=e;"singleton"===s.scope&&(s.stateUnsubscribe&&(s.stateUnsubscribe(),s.stateUnsubscribe=void 0),s.debounceTimer&&(clearTimeout(s.debounceTimer),s.debounceTimer=void 0),s.controller.abort(),await s.streamOnce.current(),s.streamSerializer.close(),s.stream=void 0,s.streamOnce=new p({retry:!0,throws:!0}),t||(s.streamSerializer=new g,s.controller=new AbortController)),await v(s.cleanupFunctions,i),await v(s.disposeFunctions,i),s.cleanupFunctions=[],s.disposeFunctions=[],"singleton"===s.scope&&(s.buildOnce=new p({retry:!0,throws:!0})),s.instance=void 0,s.error=void 0}},O=class{dependencies=new Map;dependents=new Map;registerNode(e){this.dependencies.has(e)||this.dependencies.set(e,new Set),this.dependents.has(e)||this.dependents.set(e,new Set)}removeNode(e){if(!this.hasNode(e))return;const t=this.dependencies.get(e);if(t)for(const s of t)this.dependents.get(s)?.delete(e);const s=this.dependents.get(e);if(s)for(const t of s)this.dependencies.get(t)?.delete(e);this.dependencies.delete(e),this.dependents.delete(e)}hasNode(e){return this.dependencies.has(e)}addDependency(e,t){this.registerNode(e),this.registerNode(t),this.dependencies.get(e).add(t),this.dependents.get(t).add(e)}removeDependency(e,t){this.dependencies.get(e)?.delete(t),this.dependents.get(t)?.delete(e)}getDependencies(e){const t=this.dependencies.get(e);return t?new Set(t):new Set}getDependents(e){const t=this.dependents.get(e);return t?new Set(t):new Set}iterDependents(e){return this.dependents.get(e)??E}setDependencies(e,t){this.registerNode(e);const s=this.dependencies.get(e),i=new Set(t);for(const t of s)i.has(t)||this.removeDependency(e,t);for(const t of i)s.has(t)||this.addDependency(e,t)}wouldCreateCycle(e,t){if(e===t)return[e,t];const s=[t],i=new Set([t]),r=new Map;for(;s.length>0;){const n=s.shift();if(n===e){const s=[];let i=e;for(;void 0!==i&&(s.push(i),i!==t);)i=r.get(i);return s.reverse(),s.unshift(e),s}const a=this.dependencies.get(n);if(a)for(const e of a)i.has(e)||(i.add(e),r.set(e,n),s.push(e))}return null}topologicalSort(){const e=new Map,t=Array.from(this.dependencies.keys());for(const s of t)e.set(s,this.dependencies.get(s)?.size??0);const s=[];for(const[t,i]of e)0===i&&s.push(t);const i=[];for(;s.length>0;){const t=s.shift();i.push(t);const r=this.dependents.get(t);if(r)for(const t of r){const i=(e.get(t)||0)-1;e.set(t,i),0===i&&s.push(t)}}if(i.length!==t.length)throw new Error("Cycle detected in graph; topological sort impossible.");return i}getTransitiveDependencies(e,t=!1){return this.bfs(e,"dependencies",t)}getTransitiveDependents(e,t=!1){return this.bfs(e,"dependents",t)}bfs(e,t,s){const i=new Set,r=new Set,n=[e];r.add(e),s&&i.add(e);const a="dependencies"===t?this.dependencies:this.dependents;for(;n.length>0;){const e=n.shift(),t=a.get(e);if(t)for(const e of t)r.has(e)||(r.add(e),i.add(e),n.push(e))}return i}getAllNodes(){return Array.from(this.dependencies.keys())}size(){return this.dependencies.size}clear(){this.dependencies.clear(),this.dependents.clear()}toDebugString(){return Array.from(this.dependencies.entries()).map((([e,t])=>{const s=Array.from(t).join(", ");return`${String(e)} → [${s||"∅"}]`})).join("\n")}},E=new Set,_=class{graph;constructor(){this.graph=new O}registerNode(e){this.graph.registerNode(e)}removeNode(e){this.graph.removeNode(e)}addDependency(e,t){this.graph.addDependency(e,t)}removeDependency(e,t){this.graph.removeDependency(e,t)}getDependents(e){return Array.from(this.graph.getDependents(e))}iterDependents(e){return this.graph.iterDependents(e)}getDependencies(e){return Array.from(this.graph.getDependencies(e))}getTransitiveDependents(e){return new Set(Array.from(this.graph.getTransitiveDependents(e,!1)))}setDependencies(e,t){const s=Array.from(t).map((e=>e));this.graph.setDependencies(e,s)}wouldCreateCycle(e,t,s){if(s?.has(t)){const e=Array.from(s),i=e.indexOf(t),r=e.slice(i);return r.push(t),r}const i=this.graph.wouldCreateCycle(e,t);return i||null}hasNode(e){return this.graph.hasNode(e)}getAllNodes(){return this.graph.getAllNodes()}clear(){this.graph.clear()}size(){return this.graph.size()}toDebugString(){return this.graph.toDebugString()}},x=["map","filter","reduce","forEach","find","findIndex","some","every","includes","flatMap","flat","slice","splice"];var D=class e extends Error{category;constructor(t,s,i){super(t,{cause:i}),this.name="ArtifactError",this.category=s,Object.setPrototypeOf(this,e.prototype)}},$=class extends D{constructor(e){super(`[ArtifactContainer] Artifact "${e}" not found.`,"system"),this.name="ArtifactNotFoundError"}},C=class extends D{constructor(){super("Build superseded by invalidation","system"),this.name="SupersededBuildError"}},R=class extends D{constructor(e){super(e,"system"),this.name="InvalidImportError"}},N=class extends D{constructor(e){super(`Artifact "${e}" instance is not JSON-serializable (POJO are required for persistence)`,"system"),this.name="InvalidExportOperationError"}},M=(new AbortController).signal,P=class{constructor(e,t,s,i,r){this.registry=e,this.cache=t,this.graph=s,this.store=i,this.observer=r}async build(e,t,s){const i=this.cache.get(e);if("singleton"===i?.scope&&i.buildOnce.done())return this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s);const r=this.registry.getByString(e);if(!r)throw new $(e);const n=t??[];if(n.includes(e))throw new D(`Cycle detected: Artifact "${String(e)}" depends on itself via path: ${[...n,e].join(" -> ")}`,"system");n.push(e);let a=i;a||(a=this.createCachedArtifact(r),this.cache.set(e,a));try{if("transient"===a.scope)return this.executeBuild(r,a,n);const i=a;try{await i.buildOnce.do((()=>this.executeBuild(r,i,n)))}catch(i){if(i instanceof C)return this.build(e,t,s);throw i}return i.stream&&i.streamOnce.do(i.stream),this.cache.package(e,((t,s)=>this.invalidate(e,t,s)),s)}finally{n.pop()}}async executeBuild(e,t,s){const i=e.key,r=String(i),n="transient"===t.scope;t.buildCount++,"singleton"===t.scope&&(t.activeDebounceMs=e.debounce??0);const a={cleanupFunctions:[],disposeFunctions:[],capturedArtifactDeps:new Set,capturedStateSelectors:[],dependencyVersions:new Map},o=this.buildContext(e,t,s,r,a),c=await this.runWithRetries(e,o,a.dependencyVersions);if(this.commitResult(i,t,n,c,a),n){const e=c.ok?c.value:void 0;return{instance:e,error:c.ok?void 0:c.error,ready:c.ok,[i]:e,cleanup:w(a.cleanupFunctions,r),invalidate:async()=>console.warn(`[ArtifactManager] Cannot invalidate transient "${r}"`)}}}buildContext(e,t,s,i,r){const n=e.key,a="transient"===t.scope,{cleanupFunctions:o,disposeFunctions:c,capturedArtifactDeps:h,dependencyVersions:d,capturedStateSelectors:u}=r,l=async(e,t)=>{const r=t?this.computeParamKey(e,t):e;if(r===n)throw new D(`Artifact "${i}" depends on itself.`,"system");const a=this.graph.wouldCreateCycle(n,r);if(a)throw new D(`Adding dependency "${String(r)}" to "${i}" would create a cycle: ${a.join(" -> ")}`,"system");h.add(r);const o=await(t?this.resolveParameterized(e,t):this.build(e,s)),c=this.cache.get(r);return c&&d.set(r,c.version),o},p="singleton"===t.scope?t.controller.signal:M,g=async(e,t)=>{const s=await l(e,t);if(s.error)throw s.error;return s.instance},f=(e,t)=>{const s=function(e,t="."){const s=new Set,i=new Map,r=(e="")=>{if(i.has(e))return i.get(e);const n=new Proxy((()=>{}),{get:(i,n)=>{if("symbol"==typeof n||"then"===n)return;if("valueOf"===n||"toString"===n)throw new Error("Cannot perform logic, arithmetic, or string operations inside a selector.");if(x.includes(n))throw new Error(`Array method .${n}() is not allowed in selectors.`);const a=e?`${e}${t}${n}`:n;return e&&s.delete(e),s.add(a),r(a)},has:()=>{throw new Error("The 'in' operator is not allowed in selectors.")},apply:()=>{throw new Error("Selectors cannot call functions or methods.")}});return i.set(e,n),n};try{e(r())}catch(e){throw new Error(`Selector failed during path analysis. Selectors must be simple property accessors only. Error: ${e instanceof Error?e.message:String(e)}`)}return Array.from(s)}(e);return u.push({paths:s,options:t}),e(this.store.get(!0))};return{state:()=>this.store.get(!0),previous:t.instance,signal:p,onCleanup:e=>o.push(e),onDispose:e=>c.push(e),use:e=>e({resolve:l,require:g,select:f}),stream:e=>{if(a)throw new D(`[ArtifactManager] Illegal stream on transient artifact "${i}"`,"system");const s=t,r=async(e,t=void 0)=>{await s.streamSerializer.do((async()=>{void 0!==s.stream&&(s.instance=e,s.error=t,s.version++,this.cache.invalidatePackage(n),await this.processStream(i))}))},o={value:()=>s.instance,get signal(){return s.controller.signal},set:(...e)=>this.store.set(...e),emit:e=>r(e)};s.stream=async()=>{try{const t=await e(o);t&&s.cleanupFunctions.push(t)}catch(e){await r(void 0,e),await this.invalidate(n,!1,!0)}}}}}async runWithRetries(e,t,s){const i=t.signal,r=(e.retries??0)+1;let n=0;for(;n<r;)try{if(i.aborted)throw new C;const a=e.factory(t);let o;if(o=a instanceof Promise?e.timeout?await k(a,e.timeout):await a:a,i.aborted)throw new C;const c=this.detectStaleness(s);if(c){if(n++,s.clear(),n<r)continue;return{ok:!1,error:new D(`Build stale after all retries: dependency "${String(c)}" changed during build.`,"system")}}return{ok:!0,value:o}}catch(e){if(i.aborted||e instanceof C)throw new C;if(e instanceof D)throw e;if(n++,n>=r)return{ok:!1,error:e}}return{ok:!1,error:new Error("Build exhausted retry budget unexpectedly.")}}commitResult(e,t,s,i,r){const{cleanupFunctions:n,disposeFunctions:a,capturedArtifactDeps:o,capturedStateSelectors:c}=r;s||(this.updateDependencyGraph(e,o,c),t.cleanupFunctions=n,t.disposeFunctions=a,t.artifactDependencies=new Set(o),t.stateGroups=c.map((({paths:e,options:t})=>({paths:e,options:t})))),i.ok?(t.instance=i.value,t.error=void 0):(t.instance=void 0,t.error=i.error),t.version++,this.cache.invalidatePackage(e)}detectStaleness(e){for(const[t,s]of e){const e=this.cache.get(t);if(e&&e.version!==s)return t}return null}async invalidate(e,t=!1,s=!1){const i=this.cache.get(e);if(!i)return;if("singleton"!==i.scope)return this.executeInvalidation(e,t,s);const r=i;return r.debounceTimer&&(clearTimeout(r.debounceTimer),r.debounceTimer=void 0),!t&&r.activeDebounceMs>0?new Promise(((i,n)=>{r.debounceTimer=setTimeout((()=>{r.debounceTimer=void 0,this.executeInvalidation(e,t,s).then(i).catch(n)}),r.activeDebounceMs)})):this.executeInvalidation(e,t,s)}async executeInvalidation(e,t,s=!1){const i=this.cache.get(e);i&&"singleton"===i.scope&&await i.invalidationSerializer.do((async()=>{i.version++,await this.cache.invalidateInstance(e),await this.cascadeInvalidation(this.graph.iterDependents(e));const r=this.registry.get(e),n=r&&(t||!r.lazy||this.observer.hasWatchers(e))&&!s;n&&await this.build(e).catch((t=>{t instanceof C||console.error(`[ArtifactManager] Rebuild failed for "${String(e)}":`,t)})),(n||s)&&this.observer.notify(e)}))}async dispose(e){this.cache.get(e)&&(await this.cache.invalidateInstance(e,!0),this.graph.removeNode(e),this.cache.delete(e))}async processStream(e){await this.cascadeInvalidation(this.graph.iterDependents(e)),this.observer.notify(e)}async cascadeInvalidation(e){if(0===e.size)return;const t=[];for(const s of e)t.push(this.invalidate(s).catch((e=>{console.error(`[ArtifactManager] Cascade failed for "${String(s)}":`,e)})));await Promise.all(t)}updateDependencyGraph(e,t,s){const i=this.cache.get(e);if(!i||"singleton"!==i.scope)return;this.graph.registerNode(e),this.graph.setDependencies(e,t),i.stateDependencies=new Set;for(const{paths:e}of s)for(const t of e)i.stateDependencies.add(t);if(i.stateUnsubscribe&&(i.stateUnsubscribe(),i.stateUnsubscribe=void 0),0===s.length)return;const r=()=>this.invalidate(e),n=new Map;for(const{paths:e,options:t}of s){const s=void 0===t?"undefined":JSON.stringify(t);let i=n.get(s);i||(i={options:t,paths:new Set},n.set(s,i));for(const t of e)i.paths.add(t)}const a=[];for(const{options:e,paths:t}of n.values()){if(0===t.size)continue;const s=Array.from(t);void 0===e?a.push(this.store.watch(s,r)):a.push(this.store.watch(s,r,e))}0===a.length?i.stateUnsubscribe=void 0:1===a.length?i.stateUnsubscribe=a[0]:i.stateUnsubscribe=()=>{for(const e of a)e()}}createCachedArtifact(e){return"transient"===e.scope?{scope:"transient",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0}:{scope:"singleton",instance:void 0,error:void 0,version:0,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set,activeDebounceMs:e.debounce?e.debounce:0,controller:new AbortController,buildOnce:new p({retry:!0,throws:!0}),streamOnce:new p({retry:!0,throws:!0}),streamSerializer:new g({yieldMode:"microtask"}),invalidationSerializer:new g({yieldMode:"macrotask"}),stateGroups:[],artifactDependencies:new Set}}resolveStatic(e){if(!this.registry.has(e))throw new $(e);return this.build(e)}async resolveParameterized(e,t){if(!this.registry.has(e))throw new $(String(e));const s=this.registry.get(e);if(!s.paramKey)throw new D(`Artifact "${String(e)}" is not parameterized.`,"external");const i=s.paramKey(t),r=this.registry.getByString(i);if(r&&!r.paramKey&&!r.virtual)throw new D(`Parameterized artifact "${String(e)}" with params ${JSON.stringify(t)} resolves to key "${i}" which is already registered as a static artifact.`,"system");return this.registry.hasString(i)||this.registry.setVirtual(i,{key:i,factory:e=>s.factory({...e,params:t}),scope:s.scope,lazy:s.lazy,timeout:s.timeout,retries:s.retries,debounce:s.debounce,virtual:!0}),this.build(i,void 0,e)}computeParamKey(e,t){const s=this.registry.get(e);if(!s.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);return s.paramKey(t)}},T=class{constructor(e,t,s){this.registry=e,this.cache=t,this.container=s}listeners=new Map;watchers=new Map;watch(e,t=6e4){return this.watchForKey(e,this.registry.get(e),t)}watchParameterized(e,t,s=6e4){const i=this.registry.get(e);if(!i.paramKey)throw new Error(`Artifact "${String(e)}" is not parameterized.`);const r=i.paramKey(t);return this.watchForKey(r,i,s,t)}watchForKey(e,t,s,i){const r="transient"===t.scope,n=r?b(e):e,a=this.watchers.get(n);if(a)return a.observer;const o=new m((async()=>{!r&&void 0===i||this.registry.hasString(e)||this.registry.setVirtual(e,{key:e,factory:r?t.factory:e=>t.factory({...e,params:i}),scope:r?"singleton":t.scope,lazy:t.lazy,timeout:t.timeout,retries:t.retries,debounce:t.debounce,paramKey:t.paramKey,virtual:!0})}),(async()=>{r||void 0!==i?(await this.registry.unregister(n).catch((()=>{})),this.cache.delete(n),this.watchers.delete(n)):this.cache.invalidatePackage(n),this.listeners.delete(n)}),{gracePeriod:r&&void 0===i?"sync":s});let c;const h={id:n,get count(){return o.subscribers},get:(t=!1)=>0!==o.subscribers||t?this.cache.package(n,((e,t)=>this.container.invalidate(n,e,t)),e):S,resolve:()=>c||(c=(async()=>{await o.acquire();try{return await this.container.resolve(n)}finally{o.release(),c=void 0}})(),c),subscribe:(e,t=!0)=>{const s=()=>e(h.get());return o.acquire().then((()=>{this.container.resolve(n).then((()=>{this.listeners.has(n)||this.listeners.set(n,new Set),t&&s(),this.listeners.get(n).add(s)}))})).catch((e=>{console.error(`[ArtifactObserver] Resolution failed for "${n}":`,e),this.listeners.get(n)?.add(s)})),()=>{this.listeners.get(n)?.delete(s),o.release()}}};return this.watchers.set(n,{resource:o,observer:h}),h}evictWatcher(e){[e,b(e)].forEach((e=>{const t=this.watchers.get(e);t&&(t.resource.forceCleanup(),this.watchers.delete(e))}))}notify(e){const t=this.listeners.get(e);if(t&&0!==t.size)for(const s of t)try{s()}catch(t){console.error(`[ArtifactObserver] Listener error for "${e}":`,t)}}hasWatchers(e){return this.watchers.has(e)||this.watchers.has(b(e))}getWatcherCount(e){const t=this.watchers.get(e)||this.watchers.get(b(e));return t?.resource.subscribers??0}clear(){this.watchers.clear(),this.listeners.clear()}},L=class{artifacts=new Map;register({key:e,factory:t,lazy:s,...i}){const{scope:r,...n}=i,a={key:e,factory:t,scope:i.scope??"singleton",lazy:void 0===s||s,...n};return this.artifacts.set(e,a),()=>this.unregister(e)}setVirtual(e,t){this.artifacts.set(e,t)}get(e){if(!this.has(e))throw new $(String(e));return this.artifacts.get(e)}getByString(e){return this.artifacts.get(e)}has(e){return this.artifacts.has(e)}hasString(e){return this.artifacts.has(e)}async unregister(e){this.artifacts.has(e)&&this.artifacts.delete(e)}size(){return this.artifacts.size}keys(){return Array.from(this.artifacts.keys())}clear(){this.artifacts.clear()}},F=class e{registry;cache;graph;manager;observer;store;constructor(e){this.store={watch:(...t)=>e.watch(...t),get:()=>e.get(!0),set:(...t)=>e.set(...t),subset:(...t)=>e.subset(...t)},this.registry=new L,this.cache=new A,this.graph=new _,this.observer=new T(this.registry,this.cache,this),this.manager=new P(this.registry,this.cache,this.graph,this.store,this.observer)}debugInfo(){const e=[];return this.registry.keys().forEach((t=>{const s=t,i=this.registry.get(s),r=this.cache.get(s);if(!i)return;let n="idle";r&&("singleton"===r.scope&&void 0!==r.debounceTimer?n="debouncing":"singleton"===r.scope&&r.buildOnce.running()?n="building":r.error?n="error":void 0!==r.instance&&(n="active")),e.push({id:s,scope:i.scope??"singleton",status:n,dependencies:this.graph.getDependencies(s).map((e=>String(e))),dependents:this.graph.getDependents(s).map((e=>String(e))),stateDependencies:"singleton"===r?.scope?Array.from(r.stateDependencies):[],buildCount:r?.buildCount??0})})),e}register(e){const{key:t}=e,s=t;this.registry.has(t)&&(console.warn(`[ArtifactContainer] Overwriting "${s}".`),this.manager.dispose(t).catch((e=>{console.error(`[ArtifactContainer] Failed to dispose existing artifact "${s}":`,e)}))),this.registry.register(e),this.graph.registerNode(t);const i=e.scope??"singleton";return(e.lazy??!0)||"singleton"!==i||this.resolve(t).catch((e=>{console.error(`[ArtifactContainer] Eager load failed for "${s}":`,e)})),()=>this.unregister(t)}has(e){return this.registry.has(e)}async unregister(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;await this.manager.dispose(s),await this.registry.unregister(s),this.observer.evictWatcher(s)}async resolve(e,t){return void 0===t?this.manager.resolveStatic(e):this.manager.resolveParameterized(e,t)}async require(e,t){const s=await this.resolve(e,t);if(s.error)throw s.error;return s.instance}watch(e,t,s){return void 0===t?this.observer.watch(e,s):this.observer.watchParameterized(e,t,s)}peek(e,t){const s=void 0!==t?this.manager.computeParamKey(e,t):e;return this.cache.get(s)?.instance}async invalidate(e,t){const s=t?.params,i=t?.replace??!1,r=void 0!==s?this.manager.computeParamKey(e,s):e;return this.manager.invalidate(r,i)}notifyObservers(e){this.observer.notify(e)}hasWatchers(e){return this.observer.hasWatchers(e)}async dispose(){const e=this.registry.keys();await Promise.allSettled(e.map((e=>this.manager.dispose(e).catch((t=>{console.error(`[ArtifactContainer] Failed to dispose artifact "${String(e)}":`,t)}))))),this.registry.clear(),this.cache.clear(),this.graph.clear(),this.observer.clear()}async export(){const e=[];for(const t of this.cache.keys()){const s=this.cache.get(t);if(!s||"singleton"!==s.scope)continue;if(void 0===s.instance)continue;const i=new Set;for(const e of s.stateGroups)for(const t of e.paths)i.add(t);const r=Array.from(i).sort(),n=this.store.subset(r),a=await I(JSON.stringify(n,Object.keys(n).sort()));let o;try{o=structuredClone(s.instance)}catch(e){throw new N(t)}e.push({key:t,instance:o,state:{groups:s.stateGroups.map((e=>({paths:e.paths,options:e.options}))),hash:a},dependencies:Array.from(s.artifactDependencies)})}const t={...{version:"1.0",timestamp:Date.now(),artifacts:e}},s=JSON.stringify(t),i=await I(s);return{...t,checksum:i}}async restore(e){const{checksum:t,...s}=e;if(await I(JSON.stringify(s))!==t)throw new R("Bundle checksum mismatch – data corrupted");if("1.0"!==e.version)throw new R(`Unsupported bundle version: ${e.version}`);const i=new Map;for(const t of e.artifacts)i.set(t.key,t);const r=new Set,n=new Map;for(const t of e.artifacts)for(const e of t.dependencies)n.has(e)||n.set(e,new Set),n.get(e).add(t.key);const a=async e=>{const t=new Set;for(const s of e.state.groups)for(const e of s.paths)t.add(e);const s=Array.from(t).sort(),i=this.store.subset(s);return I(JSON.stringify(i,Object.keys(i).sort()))};for(const t of e.artifacts){await a(t)!==t.state.hash&&r.add(t.key)}const o=Array.from(r);for(;o.length;){const e=o.shift(),t=n.get(e);if(t)for(const e of t)r.has(e)||(r.add(e),o.push(e))}for(const t of e.artifacts){if(r.has(t.key))continue;this.cache.get(t.key)&&await this.cache.invalidateInstance(t.key,!1);const e={scope:"singleton",instance:t.instance,error:void 0,version:1,cleanupFunctions:[],disposeFunctions:[],buildCount:0,stateDependencies:new Set(t.state.groups.flatMap((e=>e.paths))),activeDebounceMs:0,buildOnce:new p({retry:!0,throws:!0}),streamSerializer:new g({yieldMode:"microtask"}),invalidationSerializer:new g({yieldMode:"macrotask"}),stateUnsubscribe:void 0,debounceTimer:void 0,controller:new AbortController,streamOnce:new p({retry:!0,throws:!0}),stream:void 0,stateGroups:t.state.groups,artifactDependencies:new Set(t.dependencies)};e.buildOnce.resolve(t.instance),this.cache.set(t.key,e);const s=[];for(const e of t.state.groups){const i=this.store.watch(e.paths,(()=>this.invalidate(t.key)),e.options);s.push(i)}e.stateUnsubscribe=()=>{for(const e of s)e()},this.graph.setDependencies(t.key,t.dependencies)}}static async from(t){const s=new e(t.store);if(t.bundle){if("object"!=typeof t.bundle||!t.bundle.version||!Array.isArray(t.bundle.artifacts))throw new R("Invalid bundle: missing version or artifacts array");await s.restore(t.bundle)}for(const e of t.templates)s.register(e);return s}};function K(e){return"object"==typeof e&&null!==e&&"pause"in e}var z="__pipeline_data__";var B={info:()=>{},error:()=>{}},U=class{constructor(e,t){this.definition=e,this.logger=t.logger??B,this.storeFactory=t.storeFactory,this.initialStateFactory=t.initialStateFactory,this.index=V(e)}logger;storeFactory;initialStateFactory;index;async prepare(e,s){const i=s??t(),r=await this.storeFactory(i);await r.ready();const n=this.initialStateFactory?.()??{};return await r.set(n),this.logger.info(`Prepared new run "${i}" for pipeline "${this.definition.id}"`),this.buildRunContext(i,this.definition,e,r,void 0,[])}async resume(e){const t=await this.storeFactory(e),i=function(e,t,s){const i=e,r=i.get(!0)[z],n=r?.[t]?.[s];return n??null}(t,this.definition.id,e);return i?i.pipelineId!==this.definition.id?c(new r({code:s.INVALID_COMMAND.code,message:`Checkpoint runId "${e}" belongs to pipeline "${i.pipelineId}", not "${this.definition.id}".`,operation:"resume"})):(this.logger.info(`Resuming pipeline "${this.definition.id}" [${e}] from stage "${i.pausedAtStageId}"`),o(await this.buildRunContext(e,this.definition,i.resumeAt,t,void 0,[],void 0,void 0,i.containerBundle))):c(new r({code:s.NOT_FOUND.code,message:`No checkpoint found for runId "${e}".`,operation:"resume"}))}async buildRunContext(t,s,i,r,n,a,o,c,h){const d=void 0===o,u=c??"",l=new AbortController,g={runId:t,pipelineId:s.id,signal:l.signal};let f;h?f=await F.from({store:r,bundle:h,templates:q(s,u,g)}):(f=d?new F(r):o,function(e,t,s,i){for(const r of t.stages)if(r.steps)for(const t of Object.values(r.steps)){const n={runId:i.runId,pipelineId:i.pipelineId,stageId:r.id,stepId:t.id,signal:i.signal};e.register({key:W(s,r.id,t.id),factory:e=>t.action(e,n),scope:t.scope,...void 0!==t.timeout&&{timeout:t.timeout},...void 0!==t.retries&&{retries:t.retries}})}}(f,s,u,g));const y=function(e,t){return{emit(s,i){e.emit({name:s,payload:i}),t?.emit(s,i)},on:(t,s)=>e.subscribe(t,s)}}(e(),n),m=new p({retry:!1,throws:!1}),w=d?this.index:V(s);return new j(t,s,i,r,f,u,y,a,l,m,this.logger,this.definition.id,w,this)}},j=class{constructor(e,t,s,i,r,n,a,o,c,h,d,u,l,p){this.pipeline=t,this.entry=s,this.store=i,this.container=r,this.keyPrefix=n,this.bus=a,this.parentPath=o,this.controller=c,this.once=h,this.logger=d,this.definitionId=u,this.index=l,this.factory=p,this.id=e}id;on(e,t){return this.bus.on(e,t)}abort(){this.controller.abort()}async run(){const e=await this.once.do((()=>this.execute()));return void 0!==e.error?c(new r({code:s.INTERNAL_ERROR.code,message:`Unexpected throw escaped run(): ${J(e.error)}`,operation:`pipeline:${this.pipeline.id}`,cause:e.error})):e.value}async execute(){this.bus.emit("pipeline:start",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id}),this.logger.info(`Pipeline start: ${this.pipeline.id} [${this.id}]`);const e=this.resolveEntryStage();if(!e.ok)return this.failPipeline(e.error);const{stageMap:t,orderedStages:i,stageOrderIndex:n}=this.index;let a=e.value,c=!0;for(;;){if(this.controller.signal.aborted){const e=new r({code:s.OPERATION_ABORTED.code,message:`Run aborted before stage "${a.label}".`,operation:`stage:${a.id}`});return this.failPipeline(e)}const e=c?this.entry:void 0;c=!1;const h=await this.executeStage(a,e);if(!h.ok)return this.failPipeline(h.error);const d=h.value,u="pause"===d.kind?void 0:d.nextInstruction,l=n.get(a.id)??-1,p=void 0!==i[l+1],g="pause"===d.kind?"pause":null===u?"terminate":"string"==typeof u?"jump":p?"advance":"natural-end";if(this.bus.emit("router:evaluated",{path:this.parentPath,stageId:a.id,stageLabel:a.label,runId:this.id,instruction:u,interpretation:g}),"pause"===d.kind){const{checkpoint:e}=d,t=this.store.get(!0);return this.logger.info(`Pipeline paused: ${this.pipeline.id} [${this.id}] at stage "${e.pausedAtStageId}"`),this.bus.emit("pipeline:paused",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,checkpoint:e,finalState:t}),o({status:"paused",runId:this.id,finalState:t,checkpoint:e})}if(null===u)break;if("string"==typeof u){const e=t.get(u);if(!e){const e=new r({code:s.INVALID_COMMAND.code,message:`Router on stage "${a.label}" returned unknown stageId: "${u}"`,operation:`stage:${a.id}`});return this.failPipeline(e)}a=e;continue}const f=i[l+1];if(!f)break;a=f}const h=this.store.get(!0);return this.logger.info(`Pipeline succeeded: ${this.pipeline.id} [${this.id}]`),this.bus.emit("pipeline:success",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,finalState:h}),o({status:"succeeded",runId:this.id,finalState:h})}resolveEntryStage(){const{stageMap:e,orderedStages:t}=this.index;if(this.entry?.stage){const t=e.get(this.entry.stage);return t?o(t):c(new r({code:s.INVALID_COMMAND.code,message:`Entry stage "${this.entry.stage}" not found.`,operation:`pipeline:${this.pipeline.id}`}))}const i=t[0];return i?o(i):c(new r({code:s.INVALID_COMMAND.code,message:"Pipeline has no stages.",operation:`pipeline:${this.pipeline.id}`}))}async executeStage(e,t){const s=e.pipelines&&e.pipelines.length>0?"pipelines":"steps",i=[...this.parentPath,{kind:"stage",id:e.id,label:e.label}];this.bus.emit("stage:start",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,mode:s});const r="pipelines"===s?await this.executePipelinesStage(e,i,t):await this.executeStepsStage(e,i,t);return r.ok?"pause"===r.value.kind?this.bus.emit("stage:paused",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,checkpoint:r.value.checkpoint}):this.bus.emit("stage:success",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,nextInstruction:r.value.nextInstruction}):this.bus.emit("stage:failure",{path:this.parentPath,stageId:e.id,stageLabel:e.label,runId:this.id,error:r.error}),r}async executeStepsStage(e,t,i){const n=Object.values(e.steps??{});if(0===n.length){this.logger.info(`Stage "${e.label}" has no steps — skipping.`);const t=Y(e.router,this.store.get(!0),{});return o(G(t))}if(this.controller.signal.aborted)return c(new r({code:s.OPERATION_ABORTED.code,message:`Aborted before resolving steps in stage "${e.label}".`,operation:`stage:${e.id}`}));const a=void 0!==i?.step?n.filter((e=>e.id===i.step)):n;if(void 0!==i?.step&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry step "${i.step}" not found in stage "${e.label}".`,operation:`stage:${e.id}`}));for(const e of a)this.bus.emit("step:start",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id});const h=await Promise.all(a.map((async t=>({step:t,result:await this.container.resolve(W(this.keyPrefix,e.id,t.id))})))),d={};for(const{step:e,result:i}of h)i.ready?(this.bus.emit("step:success",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id}),d[e.id]=o(i.instance)):(this.bus.emit("step:failure",{path:t,stepId:e.id,stepLabel:e.label,runId:this.id,error:i.error}),d[e.id]=c(new r({code:s.BACKEND_ERROR.code,message:J(i.error)})));const u=h.find((({result:e})=>!e.ready));if(u){const e=u.result.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Step "${u.step.label}" failed: ${J(e)}`,operation:`step:${u.step.id}`,cause:e}))}const l=h.map((({result:e})=>e.instance)).filter((e=>null!=e));let p;try{await this.store.transaction((async()=>{for(const e of l)await this.store.set(e);const t=Y(e.router,this.store.get(!0),d);if(K(t)){let i;if(!0===t.persist)try{i=await this.container.export()}catch(t){throw this.logger.error("Container export failed during pause",t),new r({code:s.BACKEND_ERROR.code,message:`Failed to export container for pause: ${J(t)}`,operation:`stage:${e.id}`,cause:t})}const n={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString(),containerBundle:i};await H(this.store,n),p={kind:"pause",checkpoint:n}}else p=G(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed during stage "${e.label}": ${J(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}async executePipelinesStage(e,t,i){const n=e.pipelines,a=void 0!==i?.pipeline?(()=>{const{index:e}=i.pipeline,t=n[e];return t?[{subPipeline:t,originalIndex:e}]:[]})():n.map(((e,t)=>({subPipeline:e,originalIndex:t})));if(void 0!==i?.pipeline&&0===a.length)return c(new r({code:s.INVALID_COMMAND.code,message:`Entry sub‑pipeline index ${i.pipeline.index} out of bounds.`,operation:`stage:${e.id}`}));this.bus.emit("subpipeline:fork",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,subPipelineIds:a.map((({subPipeline:e})=>e.id))});const h=await Promise.all(a.map((async({subPipeline:s,originalIndex:r})=>{const n=void 0!==i?.pipeline?{stage:i.pipeline.stage,step:i.pipeline.step}:void 0,a=function(e,t,s){const i=`${t}:pipeline-${s}`;return e?`${e}:${i}`:i}(this.keyPrefix,e.id,r);return{subPipeline:s,originalIndex:r,ctx:await this.factory.buildRunContext(this.id,s,n,this.store,this.bus,t,this.container,a)}}))),d=()=>{h.forEach((({ctx:e})=>e.abort()))};this.controller.signal.addEventListener("abort",d,{once:!0});try{if(this.controller.signal.aborted)return d(),c(new r({code:s.OPERATION_ABORTED.code,message:this.controller.signal.reason,operation:`stage:${e.id}`}));const i=await Promise.all(h.map((({ctx:e})=>e.run()))),n={};for(let e=0;e<a.length;e++)n[a[e].subPipeline.id]=i[e];this.bus.emit("subpipeline:join",{path:t,stageId:e.id,stageLabel:e.label,runId:this.id,results:n});const u=i.findIndex((e=>!e.ok||"failed"===e.value.status));if(-1!==u){const t=a[u].subPipeline.id,n=i[u],o=n.ok?n.value.error:n.error;return c(new r({code:s.BACKEND_ERROR.code,message:`Sub‑pipeline "${t}" failed: ${J(o)}`,operation:`stage:${e.id}`,cause:o}))}const l=i.findIndex((e=>e.ok&&"paused"===e.value.status));if(-1!==l){const t=i[l].value,{checkpoint:n}=t,h={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:e.id,pipeline:{index:a[l].originalIndex,stage:n.resumeAt.stage,step:n.resumeAt.step}},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString()};try{await this.store.transaction((async()=>{await H(this.store,h)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Failed to write parent pause checkpoint for stage "${e.label}".`,operation:`stage:${e.id}`,cause:t}))}return o({kind:"pause",checkpoint:h})}let p;try{await this.store.transaction((async()=>{const t=Y(e.pipelinesRouter,this.store.get(!0),n);if(K(t)){let i;if(!0===t.persist)try{i=await this.container.export()}catch(t){throw this.logger.error("Container export failed during pause",t),new r({code:s.BACKEND_ERROR.code,message:`Failed to export container for pause: ${J(t)}`,operation:`stage:${e.id}`,cause:t})}const n={runId:this.id,pipelineId:this.definitionId,resumeAt:{stage:t.pause},pausedAtStageId:e.id,pausedAtStageLabel:e.label,pausedOn:(new Date).toISOString(),containerBundle:i};await H(this.store,n),p={kind:"pause",checkpoint:n}}else p=G(t)}),{flush:!0})}catch(t){return c(new r({code:s.CONCURRENCY_ERROR.code,message:`Transaction failed evaluating router for stage "${e.label}": ${J(t)}`,operation:`stage:${e.id}`,cause:t}))}return o(p)}finally{this.controller.signal.removeEventListener("abort",d)}}failPipeline(e){return this.bus.emit("pipeline:failure",{path:this.parentPath,pipelineId:this.pipeline.id,pipelineLabel:this.pipeline.label,runId:this.id,error:e}),c(e)}};function V(e){const t=[...e.stages].sort(((e,t)=>e.order-t.order)),s=new Map,i=new Map;for(let e=0;e<t.length;e++){const r=t[e];s.set(r.id,r),i.set(r.id,e)}return{stageMap:s,orderedStages:t,stageOrderIndex:i}}function q(e,t,s){const i=[];for(const r of e.stages)if(r.steps)for(const e of Object.values(r.steps)){const n={runId:s.runId,pipelineId:s.pipelineId,stageId:r.id,stepId:e.id,signal:s.signal};i.push({key:W(t,r.id,e.id),factory:t=>e.action(t,n),scope:e.scope,...void 0!==e.timeout&&{timeout:e.timeout},...void 0!==e.retries&&{retries:e.retries}})}return i}function W(e,t,s){return e?`${e}:${t}:${s}`:`${t}:${s}`}function Y(e,t,s){return e?e(t,s):void 0}function G(e){return{kind:"advance",nextInstruction:e}}function J(e){return e instanceof Error?e.message:String(e)}async function H(e,t){const s=e,i=t.pipelineId,r=t.runId,n=s.get(!0)[z]??{},a={...n,[i]:{...n[i]??{},[r]:t}};await s.set({[z]:a})}export{z as PIPELINE_DATA_KEY,y as Pipeline,U as PipelineEngine,f as SequentialExecutionContext,K as isPauseInstruction};
|