@tasker-systems/tasker 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # @tasker-systems/tasker
2
+
3
+ TypeScript worker for the Tasker workflow orchestration system. Supports Bun (native FFI), Node.js (via koffi), and Deno runtimes.
4
+
5
+ ## Status
6
+
7
+ Production ready. TypeScript worker bindings provide full step handler execution via FFI to the shared Rust `tasker-worker` infrastructure.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ # Bun (recommended - native FFI support)
13
+ bun add @tasker-systems/tasker
14
+
15
+ # Node.js (requires koffi for FFI)
16
+ npm install @tasker-systems/tasker koffi
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```typescript
22
+ import { TaskerWorker } from "@tasker-systems/tasker";
23
+
24
+ const worker = new TaskerWorker({
25
+ workerName: "my-worker",
26
+ namespaces: ["default"],
27
+ });
28
+
29
+ // Register a step handler
30
+ worker.registerHandler("process_payment", async (step) => {
31
+ const result = await processPayment(step.context);
32
+ return { status: "complete", data: result };
33
+ });
34
+
35
+ // Start the worker
36
+ await worker.start();
37
+ ```
38
+
39
+ ## Development
40
+
41
+ ### Prerequisites
42
+
43
+ - Bun 1.0+ (recommended) or Node.js 18+
44
+ - Rust 1.70+ (for building the FFI library)
45
+
46
+ ### Setup
47
+
48
+ ```bash
49
+ # Install dependencies
50
+ bun install
51
+
52
+ # Build TypeScript
53
+ bun run build
54
+
55
+ # Run tests
56
+ bun test
57
+
58
+ # Type checking
59
+ bun run typecheck
60
+
61
+ # Linting
62
+ bun run check
63
+ ```
64
+
65
+ ### Building the FFI Library
66
+
67
+ ```bash
68
+ # Build the Rust FFI shared library
69
+ cargo build --release -p tasker-worker-ts
70
+
71
+ # The library will be at target/release/libtasker_worker_ts.{dylib,so,dll}
72
+ ```
73
+
74
+ ## Project Structure
75
+
76
+ ```
77
+ workers/typescript/
78
+ ├── src/ # TypeScript source
79
+ │ ├── bootstrap/ # Worker initialization
80
+ │ ├── events/ # Event system integration
81
+ │ ├── ffi/ # FFI bindings to Rust
82
+ │ ├── handler/ # Step handler base classes
83
+ │ ├── logging/ # Structured logging (pino)
84
+ │ ├── registry/ # Handler registry
85
+ │ ├── server/ # HTTP/gRPC server
86
+ │ ├── subscriber/ # Queue subscriber
87
+ │ ├── types/ # Type definitions
88
+ │ └── index.ts # Package entry point
89
+ ├── src-rust/ # Rust FFI source
90
+ │ └── lib.rs # Neon/FFI module
91
+ ├── tests/ # Test suite
92
+ ├── Cargo.toml # Rust crate configuration
93
+ ├── package.json # npm package configuration
94
+ ├── tsconfig.json # TypeScript configuration
95
+ └── biome.json # Linting configuration
96
+ ```
97
+
98
+ ## Technology Stack
99
+
100
+ - **FFI Layer**: Bun native FFI / koffi (Node.js)
101
+ - **Build Tool**: tsup
102
+ - **Runtime**: Bun, Node.js 18+, or Deno
103
+ - **Testing**: Bun test runner
104
+ - **Linting**: Biome
105
+ - **Logging**: pino
106
+ - **Events**: eventemitter3
107
+
108
+ ## Runtime Support
109
+
110
+ | Runtime | FFI Mechanism | Status |
111
+ |---------|---------------|--------|
112
+ | Bun | Native `bun:ffi` | Recommended |
113
+ | Node.js | koffi | Supported |
114
+ | Deno | `Deno.dlopen` | Experimental |
115
+
116
+ ## License
117
+
118
+ MIT
@@ -1,3 +1,3 @@
1
- export { y as ErrorCallback, n as EventName, o as EventNames, d as EventPoller, z as EventPollerConfig, f as EventSystem, F as EventSystemConfig, G as EventSystemStats, A as MetricsCallback, p as MetricsEventName, q as MetricsEventNames, M as MetricsPayload, P as PollerCyclePayload, r as PollerEventName, s as PollerEventNames, C as PollerState, g as StepCompletionSentPayload, D as StepEventCallback, t as StepEventName, u as StepEventNames, h as StepExecutionCompletedPayload, i as StepExecutionFailedPayload, j as StepExecutionReceivedPayload, k as StepExecutionStartedPayload, T as TaskerEventEmitter, l as TaskerEventMap, W as WorkerErrorPayload, v as WorkerEventName, w as WorkerEventNames, m as WorkerEventPayload, x as createEventPoller } from '../index-B3BcknlZ.js';
1
+ export { y as ErrorCallback, n as EventName, o as EventNames, d as EventPoller, z as EventPollerConfig, f as EventSystem, F as EventSystemConfig, G as EventSystemStats, A as MetricsCallback, p as MetricsEventName, q as MetricsEventNames, M as MetricsPayload, P as PollerCyclePayload, r as PollerEventName, s as PollerEventNames, C as PollerState, g as StepCompletionSentPayload, D as StepEventCallback, t as StepEventName, u as StepEventNames, h as StepExecutionCompletedPayload, i as StepExecutionFailedPayload, j as StepExecutionReceivedPayload, k as StepExecutionStartedPayload, T as TaskerEventEmitter, l as TaskerEventMap, W as WorkerErrorPayload, v as WorkerEventName, w as WorkerEventNames, m as WorkerEventPayload, x as createEventPoller } from '../index-CTl8lGpU.js';
2
2
  import 'eventemitter3';
3
- import '../runtime-interface-CE4viUt7.js';
3
+ import '../runtime-interface-D940vUzy.js';
@@ -1,139 +1,5 @@
1
- import { B as BaseTaskerRuntime, a as BootstrapConfig, b as BootstrapResult, W as WorkerStatus, q as StopResult, l as FfiStepEvent, F as FfiDomainEvent, p as StepExecutionResult, t as CheckpointYieldData, k as FfiDispatchMetrics, L as LogFields, d as ClientResult, T as TaskerRuntime } from '../runtime-interface-CE4viUt7.js';
2
- export { D as DependencyResult, u as FfiDomainEventMetadata, m as HandlerDefinition, O as OrchestrationMetadata, R as RetryConfiguration, S as StepDefinition, n as StepExecutionError, o as StepExecutionMetadata, r as Task, s as WorkflowStep } from '../runtime-interface-CE4viUt7.js';
3
-
4
- /**
5
- * Node.js FFI runtime adapter using koffi.
6
- *
7
- * This adapter uses the koffi package to interface with the Rust native library.
8
- * Koffi is a modern, actively maintained FFI library with prebuilt binaries.
9
- *
10
- * Install: npm install koffi
11
- */
12
-
13
- /**
14
- * Node.js FFI runtime implementation using koffi
15
- */
16
- declare class NodeRuntime extends BaseTaskerRuntime {
17
- readonly name: string;
18
- private lib;
19
- private koffi;
20
- get isLoaded(): boolean;
21
- load(libraryPath: string): Promise<void>;
22
- unload(): void;
23
- private ensureLoaded;
24
- /**
25
- * Read a C string from a pointer and free the Rust-allocated memory.
26
- *
27
- * Uses koffi.decode with 'char' type and -1 length for null-terminated strings.
28
- */
29
- private readAndFreeRustString;
30
- getVersion(): string;
31
- getRustVersion(): string;
32
- healthCheck(): boolean;
33
- bootstrapWorker(config?: BootstrapConfig): BootstrapResult;
34
- isWorkerRunning(): boolean;
35
- getWorkerStatus(): WorkerStatus;
36
- stopWorker(): StopResult;
37
- transitionToGracefulShutdown(): StopResult;
38
- pollStepEvents(): FfiStepEvent | null;
39
- pollInProcessEvents(): FfiDomainEvent | null;
40
- completeStepEvent(eventId: string, result: StepExecutionResult): boolean;
41
- checkpointYieldStepEvent(eventId: string, checkpointData: CheckpointYieldData): boolean;
42
- getFfiDispatchMetrics(): FfiDispatchMetrics;
43
- checkStarvationWarnings(): void;
44
- cleanupTimeouts(): void;
45
- logError(message: string, fields?: LogFields): void;
46
- logWarn(message: string, fields?: LogFields): void;
47
- logInfo(message: string, fields?: LogFields): void;
48
- logDebug(message: string, fields?: LogFields): void;
49
- logTrace(message: string, fields?: LogFields): void;
50
- private parseClientResult;
51
- clientCreateTask(requestJson: string): ClientResult;
52
- clientGetTask(taskUuid: string): ClientResult;
53
- clientListTasks(paramsJson: string): ClientResult;
54
- clientCancelTask(taskUuid: string): ClientResult;
55
- clientListTaskSteps(taskUuid: string): ClientResult;
56
- clientGetStep(taskUuid: string, stepUuid: string): ClientResult;
57
- clientGetStepAuditHistory(taskUuid: string, stepUuid: string): ClientResult;
58
- clientHealthCheck(): ClientResult;
59
- }
60
-
61
- /**
62
- * Bun FFI runtime adapter using koffi (via Node-API).
63
- *
64
- * Bun supports Node-API modules natively, so we use koffi (the same FFI
65
- * library as NodeRuntime) rather than bun:ffi. This gives us:
66
- * - Stable, well-tested string/pointer handling
67
- * - Identical behavior across Node.js and Bun
68
- * - No manual Buffer→pointer conversion bugs
69
- *
70
- * See: https://bun.sh/docs/runtime/node-api
71
- */
72
-
73
- /**
74
- * Bun FFI runtime implementation using koffi (Node-API).
75
- *
76
- * Extends NodeRuntime since both use koffi for FFI. The only difference
77
- * is the runtime name identifier used for logging and diagnostics.
78
- */
79
- declare class BunRuntime extends NodeRuntime {
80
- readonly name = "bun";
81
- }
82
-
83
- /**
84
- * Deno FFI runtime adapter using Deno.dlopen.
85
- *
86
- * This adapter uses Deno's built-in FFI to interface with the Rust native library.
87
- * It requires --unstable-ffi and --allow-ffi flags.
88
- */
89
-
90
- /**
91
- * Deno FFI runtime implementation using Deno.dlopen
92
- */
93
- declare class DenoRuntime extends BaseTaskerRuntime {
94
- readonly name = "deno";
95
- private lib;
96
- private encoder;
97
- get isLoaded(): boolean;
98
- load(libraryPath: string): Promise<void>;
99
- unload(): void;
100
- private ensureLoaded;
101
- /**
102
- * Creates a null-terminated C string buffer.
103
- * With 'buffer' FFI type, we return Uint8Array directly.
104
- */
105
- private toCString;
106
- private fromCString;
107
- getVersion(): string;
108
- getRustVersion(): string;
109
- healthCheck(): boolean;
110
- bootstrapWorker(config?: BootstrapConfig): BootstrapResult;
111
- isWorkerRunning(): boolean;
112
- getWorkerStatus(): WorkerStatus;
113
- stopWorker(): StopResult;
114
- transitionToGracefulShutdown(): StopResult;
115
- pollStepEvents(): FfiStepEvent | null;
116
- pollInProcessEvents(): FfiDomainEvent | null;
117
- completeStepEvent(eventId: string, result: StepExecutionResult): boolean;
118
- checkpointYieldStepEvent(eventId: string, checkpointData: CheckpointYieldData): boolean;
119
- getFfiDispatchMetrics(): FfiDispatchMetrics;
120
- checkStarvationWarnings(): void;
121
- cleanupTimeouts(): void;
122
- logError(message: string, fields?: LogFields): void;
123
- logWarn(message: string, fields?: LogFields): void;
124
- logInfo(message: string, fields?: LogFields): void;
125
- logDebug(message: string, fields?: LogFields): void;
126
- logTrace(message: string, fields?: LogFields): void;
127
- private parseClientResult;
128
- clientCreateTask(requestJson: string): ClientResult;
129
- clientGetTask(taskUuid: string): ClientResult;
130
- clientListTasks(paramsJson: string): ClientResult;
131
- clientCancelTask(taskUuid: string): ClientResult;
132
- clientListTaskSteps(taskUuid: string): ClientResult;
133
- clientGetStep(taskUuid: string, stepUuid: string): ClientResult;
134
- clientGetStepAuditHistory(taskUuid: string, stepUuid: string): ClientResult;
135
- clientHealthCheck(): ClientResult;
136
- }
1
+ import { T as TaskerRuntime, B as BaseTaskerRuntime, e as BootstrapConfig, f as BootstrapResult, W as WorkerStatus, q as StopResult, l as FfiStepEvent, F as FfiDomainEvent, p as StepExecutionResult, t as CheckpointYieldData, k as FfiDispatchMetrics, L as LogFields, h as ClientResult } from '../runtime-interface-D940vUzy.js';
2
+ export { D as DependencyResult, u as FfiDomainEventMetadata, m as HandlerDefinition, O as OrchestrationMetadata, R as RetryConfiguration, S as StepDefinition, n as StepExecutionError, o as StepExecutionMetadata, r as Task, s as WorkflowStep } from '../runtime-interface-D940vUzy.js';
137
3
 
138
4
  /**
139
5
  * Runtime detection for TypeScript/JavaScript workers.
@@ -280,9 +146,9 @@ declare class FfiLayer {
280
146
  * Static method for finding the library path without creating an instance.
281
147
  * Useful for test utilities and pre-flight checks.
282
148
  *
283
- * REQUIRES: TASKER_FFI_LIBRARY_PATH environment variable to be set.
284
- * This explicit requirement prevents confusion from automatic debug/release
285
- * library discovery and ensures intentional configuration at build/runtime.
149
+ * Resolution order:
150
+ * 1. TASKER_FFI_LIBRARY_PATH environment variable (explicit override)
151
+ * 2. Bundled native library in the package's native/ directory
286
152
  *
287
153
  * @param _callerDir Deprecated parameter, kept for API compatibility
288
154
  * @returns Path to the library if found and exists, null otherwise
@@ -305,4 +171,138 @@ declare class FfiLayer {
305
171
  private createRuntime;
306
172
  }
307
173
 
174
+ /**
175
+ * Node.js FFI runtime adapter using koffi.
176
+ *
177
+ * This adapter uses the koffi package to interface with the Rust native library.
178
+ * Koffi is a modern, actively maintained FFI library with prebuilt binaries.
179
+ *
180
+ * Install: npm install koffi
181
+ */
182
+
183
+ /**
184
+ * Node.js FFI runtime implementation using koffi
185
+ */
186
+ declare class NodeRuntime extends BaseTaskerRuntime {
187
+ readonly name: string;
188
+ private lib;
189
+ private koffi;
190
+ get isLoaded(): boolean;
191
+ load(libraryPath: string): Promise<void>;
192
+ unload(): void;
193
+ private ensureLoaded;
194
+ /**
195
+ * Read a C string from a pointer and free the Rust-allocated memory.
196
+ *
197
+ * Uses koffi.decode with 'char' type and -1 length for null-terminated strings.
198
+ */
199
+ private readAndFreeRustString;
200
+ getVersion(): string;
201
+ getRustVersion(): string;
202
+ healthCheck(): boolean;
203
+ bootstrapWorker(config?: BootstrapConfig): BootstrapResult;
204
+ isWorkerRunning(): boolean;
205
+ getWorkerStatus(): WorkerStatus;
206
+ stopWorker(): StopResult;
207
+ transitionToGracefulShutdown(): StopResult;
208
+ pollStepEvents(): FfiStepEvent | null;
209
+ pollInProcessEvents(): FfiDomainEvent | null;
210
+ completeStepEvent(eventId: string, result: StepExecutionResult): boolean;
211
+ checkpointYieldStepEvent(eventId: string, checkpointData: CheckpointYieldData): boolean;
212
+ getFfiDispatchMetrics(): FfiDispatchMetrics;
213
+ checkStarvationWarnings(): void;
214
+ cleanupTimeouts(): void;
215
+ logError(message: string, fields?: LogFields): void;
216
+ logWarn(message: string, fields?: LogFields): void;
217
+ logInfo(message: string, fields?: LogFields): void;
218
+ logDebug(message: string, fields?: LogFields): void;
219
+ logTrace(message: string, fields?: LogFields): void;
220
+ private parseClientResult;
221
+ clientCreateTask(requestJson: string): ClientResult;
222
+ clientGetTask(taskUuid: string): ClientResult;
223
+ clientListTasks(paramsJson: string): ClientResult;
224
+ clientCancelTask(taskUuid: string): ClientResult;
225
+ clientListTaskSteps(taskUuid: string): ClientResult;
226
+ clientGetStep(taskUuid: string, stepUuid: string): ClientResult;
227
+ clientGetStepAuditHistory(taskUuid: string, stepUuid: string): ClientResult;
228
+ clientHealthCheck(): ClientResult;
229
+ }
230
+
231
+ /**
232
+ * Bun FFI runtime adapter using koffi (via Node-API).
233
+ *
234
+ * Bun supports Node-API modules natively, so we use koffi (the same FFI
235
+ * library as NodeRuntime) rather than bun:ffi. This gives us:
236
+ * - Stable, well-tested string/pointer handling
237
+ * - Identical behavior across Node.js and Bun
238
+ * - No manual Buffer→pointer conversion bugs
239
+ *
240
+ * See: https://bun.sh/docs/runtime/node-api
241
+ */
242
+
243
+ /**
244
+ * Bun FFI runtime implementation using koffi (Node-API).
245
+ *
246
+ * Extends NodeRuntime since both use koffi for FFI. The only difference
247
+ * is the runtime name identifier used for logging and diagnostics.
248
+ */
249
+ declare class BunRuntime extends NodeRuntime {
250
+ readonly name = "bun";
251
+ }
252
+
253
+ /**
254
+ * Deno FFI runtime adapter using Deno.dlopen.
255
+ *
256
+ * This adapter uses Deno's built-in FFI to interface with the Rust native library.
257
+ * It requires --unstable-ffi and --allow-ffi flags.
258
+ */
259
+
260
+ /**
261
+ * Deno FFI runtime implementation using Deno.dlopen
262
+ */
263
+ declare class DenoRuntime extends BaseTaskerRuntime {
264
+ readonly name = "deno";
265
+ private lib;
266
+ private encoder;
267
+ get isLoaded(): boolean;
268
+ load(libraryPath: string): Promise<void>;
269
+ unload(): void;
270
+ private ensureLoaded;
271
+ /**
272
+ * Creates a null-terminated C string buffer.
273
+ * With 'buffer' FFI type, we return Uint8Array directly.
274
+ */
275
+ private toCString;
276
+ private fromCString;
277
+ getVersion(): string;
278
+ getRustVersion(): string;
279
+ healthCheck(): boolean;
280
+ bootstrapWorker(config?: BootstrapConfig): BootstrapResult;
281
+ isWorkerRunning(): boolean;
282
+ getWorkerStatus(): WorkerStatus;
283
+ stopWorker(): StopResult;
284
+ transitionToGracefulShutdown(): StopResult;
285
+ pollStepEvents(): FfiStepEvent | null;
286
+ pollInProcessEvents(): FfiDomainEvent | null;
287
+ completeStepEvent(eventId: string, result: StepExecutionResult): boolean;
288
+ checkpointYieldStepEvent(eventId: string, checkpointData: CheckpointYieldData): boolean;
289
+ getFfiDispatchMetrics(): FfiDispatchMetrics;
290
+ checkStarvationWarnings(): void;
291
+ cleanupTimeouts(): void;
292
+ logError(message: string, fields?: LogFields): void;
293
+ logWarn(message: string, fields?: LogFields): void;
294
+ logInfo(message: string, fields?: LogFields): void;
295
+ logDebug(message: string, fields?: LogFields): void;
296
+ logTrace(message: string, fields?: LogFields): void;
297
+ private parseClientResult;
298
+ clientCreateTask(requestJson: string): ClientResult;
299
+ clientGetTask(taskUuid: string): ClientResult;
300
+ clientListTasks(paramsJson: string): ClientResult;
301
+ clientCancelTask(taskUuid: string): ClientResult;
302
+ clientListTaskSteps(taskUuid: string): ClientResult;
303
+ clientGetStep(taskUuid: string, stepUuid: string): ClientResult;
304
+ clientGetStepAuditHistory(taskUuid: string, stepUuid: string): ClientResult;
305
+ clientHealthCheck(): ClientResult;
306
+ }
307
+
308
308
  export { BaseTaskerRuntime, BootstrapConfig, BootstrapResult, BunRuntime, DenoRuntime, FfiDispatchMetrics, FfiDomainEvent, FfiLayer, type FfiLayerConfig, FfiStepEvent, LogFields, NodeRuntime, type RuntimeInfo, type RuntimeType, StepExecutionResult, StopResult, TaskerRuntime, WorkerStatus, detectRuntime, getLibraryPath, getRuntimeInfo, isBun, isDeno, isNode };
package/dist/ffi/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { existsSync } from 'fs';
2
+ import { dirname, join } from 'path';
3
+ import { fileURLToPath } from 'url';
2
4
 
3
5
  var __create = Object.create;
4
6
  var __defProp = Object.defineProperty;
@@ -517,8 +519,8 @@ var require_koffi19 = __commonJS2({
517
519
  data = data.subarray(0, header.size);
518
520
  if (header.type == "0" || header.type == "7") {
519
521
  let filename3 = dest_dir + "/" + header.filename;
520
- let dirname = path2.dirname(filename3);
521
- fs2.mkdirSync(dirname, { recursive: true, mode: 493 });
522
+ let dirname2 = path2.dirname(filename3);
523
+ fs2.mkdirSync(dirname2, { recursive: true, mode: 493 });
522
524
  fs2.writeFileSync(filename3, data, { mode: header.mode });
523
525
  } else if (header.type == "5") {
524
526
  let filename3 = dest_dir + "/" + header.filename;
@@ -1829,7 +1831,10 @@ var FfiLayer = class _FfiLayer {
1829
1831
  const path2 = customPath ?? this.configuredLibraryPath ?? this.discoverLibraryPath();
1830
1832
  if (!path2) {
1831
1833
  throw new Error(
1832
- "FFI library not found. TASKER_FFI_LIBRARY_PATH environment variable must be set to the path of the compiled library.\nExample: export TASKER_FFI_LIBRARY_PATH=/path/to/target/debug/libtasker_ts.dylib\nBuild the library with: cargo build -p tasker-ts"
1834
+ `FFI library not found. No bundled native library matches this platform, and TASKER_FFI_LIBRARY_PATH is not set.
1835
+ Current platform: ${process.platform}-${process.arch}
1836
+ Supported: linux-x64, linux-arm64, darwin-arm64
1837
+ Override: export TASKER_FFI_LIBRARY_PATH=/path/to/libtasker_ts.dylib`
1833
1838
  );
1834
1839
  }
1835
1840
  this.runtime = await this.createRuntime();
@@ -1883,23 +1888,27 @@ var FfiLayer = class _FfiLayer {
1883
1888
  * Static method for finding the library path without creating an instance.
1884
1889
  * Useful for test utilities and pre-flight checks.
1885
1890
  *
1886
- * REQUIRES: TASKER_FFI_LIBRARY_PATH environment variable to be set.
1887
- * This explicit requirement prevents confusion from automatic debug/release
1888
- * library discovery and ensures intentional configuration at build/runtime.
1891
+ * Resolution order:
1892
+ * 1. TASKER_FFI_LIBRARY_PATH environment variable (explicit override)
1893
+ * 2. Bundled native library in the package's native/ directory
1889
1894
  *
1890
1895
  * @param _callerDir Deprecated parameter, kept for API compatibility
1891
1896
  * @returns Path to the library if found and exists, null otherwise
1892
1897
  */
1893
1898
  static findLibraryPath(_callerDir) {
1894
1899
  const envPath = process.env.TASKER_FFI_LIBRARY_PATH;
1895
- if (!envPath) {
1896
- return null;
1900
+ if (envPath) {
1901
+ if (!existsSync(envPath)) {
1902
+ console.warn(`TASKER_FFI_LIBRARY_PATH is set to "${envPath}" but the file does not exist`);
1903
+ return null;
1904
+ }
1905
+ return envPath;
1897
1906
  }
1898
- if (!existsSync(envPath)) {
1899
- console.warn(`TASKER_FFI_LIBRARY_PATH is set to "${envPath}" but the file does not exist`);
1900
- return null;
1907
+ const bundledPath = findBundledNativeLibrary();
1908
+ if (bundledPath && existsSync(bundledPath)) {
1909
+ return bundledPath;
1901
1910
  }
1902
- return envPath;
1911
+ return null;
1903
1912
  }
1904
1913
  /**
1905
1914
  * Discover the FFI library path.
@@ -1935,6 +1944,21 @@ var FfiLayer = class _FfiLayer {
1935
1944
  }
1936
1945
  }
1937
1946
  };
1947
+ var BUNDLED_LIBRARIES = {
1948
+ "linux-x64": "libtasker_ts-linux-x64.so",
1949
+ "linux-arm64": "libtasker_ts-linux-arm64.so",
1950
+ "darwin-arm64": "libtasker_ts-darwin-arm64.dylib"
1951
+ };
1952
+ function findBundledNativeLibrary() {
1953
+ const key = `${process.platform}-${process.arch}`;
1954
+ const filename2 = BUNDLED_LIBRARIES[key];
1955
+ if (!filename2) {
1956
+ return null;
1957
+ }
1958
+ const thisDir = dirname(fileURLToPath(import.meta.url));
1959
+ const packageRoot = join(thisDir, "..", "..");
1960
+ return join(packageRoot, "native", filename2);
1961
+ }
1938
1962
 
1939
1963
  // src/ffi/index.ts
1940
1964
  init_node_runtime();