@tasker-systems/tasker 0.1.4 → 0.1.6

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.
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from 'eventemitter3';
2
- import { l as FfiStepEvent, p as StepExecutionResult, k as FfiDispatchMetrics, T as TaskerRuntime } from './runtime-interface-D940vUzy.js';
2
+ import { FfiStepEvent, StepExecutionResult, FfiDispatchMetrics, NapiModule, NapiOrchestrationMetadata } from './ffi/index.js';
3
3
 
4
4
  /**
5
5
  * Event emitter for TypeScript workers.
@@ -288,6 +288,8 @@ type MetricsEventName = (typeof MetricsEventNames)[keyof typeof MetricsEventName
288
288
  * Provides a polling loop that retrieves step events from the Rust FFI layer
289
289
  * and dispatches them to registered handlers. Uses a 10ms polling interval
290
290
  * matching other language workers.
291
+ *
292
+ * TAS-290: Uses NapiModule directly instead of TaskerRuntime.
291
293
  */
292
294
 
293
295
  /**
@@ -332,7 +334,7 @@ type PollerState = 'stopped' | 'running' | 'stopping';
332
334
  * 5. Emits metrics for monitoring
333
335
  */
334
336
  declare class EventPoller {
335
- private readonly runtime;
337
+ private readonly module;
336
338
  private readonly config;
337
339
  private readonly emitter;
338
340
  private state;
@@ -345,11 +347,11 @@ declare class EventPoller {
345
347
  /**
346
348
  * Create a new EventPoller.
347
349
  *
348
- * @param runtime - The FFI runtime for polling events
350
+ * @param module - The napi-rs module for polling events
349
351
  * @param emitter - The event emitter to dispatch events to (required, no fallback)
350
352
  * @param config - Optional configuration for polling behavior
351
353
  */
352
- constructor(runtime: TaskerRuntime, emitter: TaskerEventEmitter, config?: EventPollerConfig$1);
354
+ constructor(module: NapiModule, emitter: TaskerEventEmitter, config?: EventPollerConfig$1);
353
355
  /**
354
356
  * Get the current poller state
355
357
  */
@@ -408,9 +410,9 @@ declare class EventPoller {
408
410
  private handleError;
409
411
  }
410
412
  /**
411
- * Create an event poller with the given runtime, emitter, and configuration
413
+ * Create an event poller with the given module, emitter, and configuration
412
414
  */
413
- declare function createEventPoller(runtime: TaskerRuntime, emitter: TaskerEventEmitter, config?: EventPollerConfig$1): EventPoller;
415
+ declare function createEventPoller(module: NapiModule, emitter: TaskerEventEmitter, config?: EventPollerConfig$1): EventPoller;
414
416
 
415
417
  /**
416
418
  * Standard error types for cross-language consistency.
@@ -521,9 +523,9 @@ declare class StepContext {
521
523
  readonly inputData: Record<string, unknown>;
522
524
  /** Results from dependent steps */
523
525
  readonly dependencyResults: Record<string, unknown>;
524
- /** Handler-specific configuration (from step_definition.handler.initialization) */
526
+ /** Handler-specific configuration (from stepDefinition.handlerInitialization) */
525
527
  readonly stepConfig: Record<string, unknown>;
526
- /** Step-specific inputs (from workflow_step.inputs, used for batch cursor config) */
528
+ /** Step-specific inputs (from workflowStep.inputs, used for batch cursor config) */
527
529
  readonly stepInputs: Record<string, unknown>;
528
530
  /** Current retry attempt number */
529
531
  readonly retryCount: number;
@@ -533,16 +535,15 @@ declare class StepContext {
533
535
  /**
534
536
  * Create a StepContext from an FFI event.
535
537
  *
536
- * Extracts input data, dependency results, and configuration from
537
- * the task_sequence_step payload.
538
+ * TAS-290: All field access uses camelCase (napi-rs auto-converts).
538
539
  *
539
540
  * The FFI data structure mirrors the Ruby TaskSequenceStepWrapper:
540
541
  * - task.context -> inputData (task context with user inputs)
541
- * - dependency_results -> results from parent steps
542
- * - step_definition.handler.initialization -> stepConfig
543
- * - workflow_step.attempts -> retryCount
544
- * - workflow_step.max_attempts -> maxRetries
545
- * - workflow_step.inputs -> stepInputs
542
+ * - dependencyResults -> results from parent steps
543
+ * - stepDefinition.handlerInitialization -> stepConfig
544
+ * - workflowStep.attempts -> retryCount
545
+ * - workflowStep.maxAttempts -> maxRetries
546
+ * - workflowStep.inputs -> stepInputs
546
547
  *
547
548
  * @param event - The FFI step event
548
549
  * @param handlerName - Name of the handler to execute
@@ -634,6 +635,10 @@ declare class StepContext {
634
635
  /**
635
636
  * Get the raw checkpoint data from the workflow step.
636
637
  *
638
+ * Note: Checkpoint data from the database uses snake_case keys
639
+ * (cursor, items_processed, accumulated_results) because it's stored
640
+ * as a serde_json::Value that passes through napi-rs as-is.
641
+ *
637
642
  * @returns The checkpoint data object or null if not set
638
643
  */
639
644
  get checkpoint(): Record<string, unknown> | null;
@@ -745,6 +750,7 @@ interface StepHandlerResultParams {
745
750
  errorCode?: string | null;
746
751
  retryable?: boolean;
747
752
  metadata?: Record<string, unknown>;
753
+ orchestrationMetadata?: NapiOrchestrationMetadata | null;
748
754
  }
749
755
  /**
750
756
  * Result from a step handler execution.
@@ -794,6 +800,8 @@ declare class StepHandlerResult {
794
800
  readonly retryable: boolean;
795
801
  /** Additional execution metadata */
796
802
  readonly metadata: Record<string, unknown>;
803
+ /** Orchestration metadata for workflow coordination hints (e.g., backoff, headers) */
804
+ readonly orchestrationMetadata: NapiOrchestrationMetadata | null;
797
805
  constructor(params: StepHandlerResultParams);
798
806
  /**
799
807
  * Create a successful handler result.
@@ -940,6 +948,10 @@ declare abstract class StepHandler {
940
948
  /**
941
949
  * Version string for the handler.
942
950
  * Default: "1.0.0"
951
+ *
952
+ * Currently a no-op — not yet wired through FFI bridges to
953
+ * StepExecutionMetadata. Reserved for future observability
954
+ * and compatibility tracking.
943
955
  */
944
956
  static handlerVersion: string;
945
957
  /**
@@ -1046,6 +1058,9 @@ declare abstract class StepHandler {
1046
1058
  * Subscribes to step execution events from the EventPoller and dispatches
1047
1059
  * them to the appropriate handlers via the HandlerRegistry.
1048
1060
  *
1061
+ * TAS-290: Uses NapiModule directly instead of TaskerRuntime.
1062
+ * All field access uses camelCase (napi-rs auto-converts from Rust snake_case).
1063
+ *
1049
1064
  * Matches Python's StepExecutionSubscriber pattern (TAS-92 aligned).
1050
1065
  */
1051
1066
 
@@ -1086,7 +1101,7 @@ interface StepExecutionSubscriberConfig {
1086
1101
  * const subscriber = new StepExecutionSubscriber(
1087
1102
  * eventEmitter,
1088
1103
  * handlerRegistry,
1089
- * runtime,
1104
+ * module,
1090
1105
  * { workerId: 'worker-1' }
1091
1106
  * );
1092
1107
  *
@@ -1099,7 +1114,7 @@ interface StepExecutionSubscriberConfig {
1099
1114
  declare class StepExecutionSubscriber {
1100
1115
  private readonly emitter;
1101
1116
  private readonly registry;
1102
- private readonly runtime;
1117
+ private readonly module;
1103
1118
  private readonly workerId;
1104
1119
  private readonly maxConcurrent;
1105
1120
  private readonly handlerTimeoutMs;
@@ -1112,10 +1127,10 @@ declare class StepExecutionSubscriber {
1112
1127
  *
1113
1128
  * @param emitter - The event emitter to subscribe to (required, no fallback)
1114
1129
  * @param registry - The handler registry for resolving step handlers
1115
- * @param runtime - The FFI runtime for submitting results (required, no fallback)
1130
+ * @param module - The napi-rs module for submitting results (required, no fallback)
1116
1131
  * @param config - Optional configuration for execution behavior
1117
1132
  */
1118
- constructor(emitter: TaskerEventEmitter, registry: HandlerRegistryInterface, runtime: TaskerRuntime, config?: StepExecutionSubscriberConfig);
1133
+ constructor(emitter: TaskerEventEmitter, registry: HandlerRegistryInterface, module: NapiModule, config?: StepExecutionSubscriberConfig);
1119
1134
  /**
1120
1135
  * Start subscribing to step execution events.
1121
1136
  */
@@ -1156,8 +1171,35 @@ declare class StepExecutionSubscriber {
1156
1171
  private handleEvent;
1157
1172
  /**
1158
1173
  * Process a step execution event.
1174
+ *
1175
+ * All paths produce a StepHandlerResult — the handler's result or a
1176
+ * system-level failure. This mirrors Python's pattern where system errors
1177
+ * (handler not found, timeout, uncaught exception) become
1178
+ * StepHandlerResult.failure() with appropriate error_type and retryable.
1159
1179
  */
1160
1180
  private processEvent;
1181
+ /**
1182
+ * Resolve handler from registry and execute it, returning a StepHandlerResult.
1183
+ *
1184
+ * System-level failures (no handler name, handler not found, uncaught exception)
1185
+ * are converted to StepHandlerResult.failure() with appropriate error_type and
1186
+ * retryable — the caller always gets a result, never an exception.
1187
+ */
1188
+ private resolveAndExecuteHandler;
1189
+ /**
1190
+ * Create context and invoke the handler, returning its result.
1191
+ *
1192
+ * handlerWasInvoked is true only if the handler returned (not threw).
1193
+ */
1194
+ private invokeHandler;
1195
+ /**
1196
+ * Update counters and emit observability events after step completion.
1197
+ *
1198
+ * A handler returning failure() is still "processed" — the handler ran and
1199
+ * gave a definitive answer. Only system-level errors (handler not found,
1200
+ * timeout, uncaught exception) count as "errors".
1201
+ */
1202
+ private emitCompletionEvents;
1161
1203
  /**
1162
1204
  * Execute a function with a timeout.
1163
1205
  */
@@ -1165,7 +1207,7 @@ declare class StepExecutionSubscriber {
1165
1207
  /**
1166
1208
  * Extract handler name from FFI event.
1167
1209
  *
1168
- * The handler name is in step_definition.handler.callable
1210
+ * TAS-290: With napi-rs, handler callable is flattened to stepDefinition.handlerCallable
1169
1211
  */
1170
1212
  private extractHandlerName;
1171
1213
  /**
@@ -1183,21 +1225,22 @@ declare class StepExecutionSubscriber {
1183
1225
  */
1184
1226
  private submitCheckpointYield;
1185
1227
  /**
1186
- * Submit an error result via FFI (for handler resolution/execution failures).
1187
- */
1188
- private submitErrorResult;
1189
- /**
1190
- * Build a StepExecutionResult from a handler result.
1228
+ * Build a NapiStepExecutionResult from a StepHandlerResult.
1191
1229
  *
1192
- * IMPORTANT: metadata.retryable must be set for Rust's is_retryable() to work correctly.
1193
- */
1194
- private buildExecutionResult;
1195
- /**
1196
- * Build an error StepExecutionResult for handler resolution/execution failures.
1230
+ * The subscriber's only job here is to WRAP the handler result with
1231
+ * execution metadata (timing, worker_id, step_uuid). All handler decisions
1232
+ * (success, retryable, errorType, errorCode, orchestrationMetadata) are
1233
+ * passed through faithfully — the subscriber does not re-interpret them.
1197
1234
  *
1198
- * IMPORTANT: metadata.retryable must be set for Rust's is_retryable() to work correctly.
1235
+ * This mirrors Python's _submit_result() which calls
1236
+ * StepExecutionResult.success_result() or .failure_result() passing
1237
+ * handler fields straight through.
1238
+ *
1239
+ * napi-rs #[napi(object)] maps Option<T> to `?: T`. With
1240
+ * exactOptionalPropertyTypes, optional props must be OMITTED (not null
1241
+ * or undefined) — hence the conditional spread pattern.
1199
1242
  */
1200
- private buildErrorExecutionResult;
1243
+ private buildStepExecutionResult;
1201
1244
  /**
1202
1245
  * Send a completion result to Rust via FFI and handle the response.
1203
1246
  *
@@ -1229,6 +1272,8 @@ declare class StepExecutionSubscriber {
1229
1272
  * By owning all three components, EventSystem guarantees they share the
1230
1273
  * same emitter instance, eliminating reference sharing bugs.
1231
1274
  *
1275
+ * TAS-290: Uses NapiModule directly instead of TaskerRuntime.
1276
+ *
1232
1277
  * Design principles:
1233
1278
  * - Explicit construction: All dependencies injected via constructor
1234
1279
  * - Clear ownership: This class owns the emitter lifecycle
@@ -1288,12 +1333,12 @@ interface EventSystemStats {
1288
1333
  /**
1289
1334
  * Unified event processing system.
1290
1335
  *
1291
- * Owns the complete event flow: emitter poller subscriber.
1336
+ * Owns the complete event flow: emitter -> poller -> subscriber.
1292
1337
  * Guarantees all components share the same emitter instance.
1293
1338
  *
1294
1339
  * @example
1295
1340
  * ```typescript
1296
- * const eventSystem = new EventSystem(runtime, registry, {
1341
+ * const eventSystem = new EventSystem(module, registry, {
1297
1342
  * poller: { pollIntervalMs: 10 },
1298
1343
  * subscriber: { workerId: 'worker-1', maxConcurrent: 10 },
1299
1344
  * });
@@ -1311,11 +1356,11 @@ declare class EventSystem {
1311
1356
  /**
1312
1357
  * Create a new EventSystem.
1313
1358
  *
1314
- * @param runtime - The FFI runtime for polling events and submitting results
1359
+ * @param module - The napi-rs module for polling events and submitting results
1315
1360
  * @param registry - The handler registry for resolving step handlers
1316
1361
  * @param config - Optional configuration for poller and subscriber
1317
1362
  */
1318
- constructor(runtime: TaskerRuntime, registry: HandlerRegistryInterface, config?: EventSystemConfig);
1363
+ constructor(module: NapiModule, registry: HandlerRegistryInterface, config?: EventSystemConfig);
1319
1364
  /**
1320
1365
  * Start the event system.
1321
1366
  *