@wordpress/worker-threads 1.0.1-next.v.202602200903.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENSE.md +788 -0
- package/README.md +132 -0
- package/build/index.cjs +37 -0
- package/build/index.cjs.map +7 -0
- package/build/main-thread.cjs +76 -0
- package/build/main-thread.cjs.map +7 -0
- package/build/types.cjs +31 -0
- package/build/types.cjs.map +7 -0
- package/build/worker-thread.cjs +49 -0
- package/build/worker-thread.cjs.map +7 -0
- package/build-module/index.mjs +10 -0
- package/build-module/index.mjs.map +7 -0
- package/build-module/main-thread.mjs +52 -0
- package/build-module/main-thread.mjs.map +7 -0
- package/build-module/types.mjs +6 -0
- package/build-module/types.mjs.map +7 -0
- package/build-module/worker-thread.mjs +26 -0
- package/build-module/worker-thread.mjs.map +7 -0
- package/build-types/index.d.ts +54 -0
- package/build-types/index.d.ts.map +1 -0
- package/build-types/main-thread.d.ts +41 -0
- package/build-types/main-thread.d.ts.map +1 -0
- package/build-types/types.d.ts +20 -0
- package/build-types/types.d.ts.map +1 -0
- package/build-types/worker-thread.d.ts +33 -0
- package/build-types/worker-thread.d.ts.map +1 -0
- package/package.json +58 -0
- package/src/index.ts +57 -0
- package/src/main-thread.ts +123 -0
- package/src/test/main-thread.test.ts +131 -0
- package/src/test/worker-thread.test.ts +118 -0
- package/src/types.ts +23 -0
- package/src/worker-thread.ts +67 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Worker Threads
|
|
2
|
+
|
|
3
|
+
Utilities for type-safe Web Worker communication with RPC (Remote Procedure Call).
|
|
4
|
+
|
|
5
|
+
This package provides a simple and efficient way to communicate between the main thread and Web Workers, automatically handling:
|
|
6
|
+
|
|
7
|
+
- Promise-based async method calls
|
|
8
|
+
- Automatic transferable detection (ArrayBuffer, etc.)
|
|
9
|
+
- Type-safe API with full TypeScript support
|
|
10
|
+
- Error propagation from worker to main thread
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
Install the module:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @wordpress/worker-threads
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Worker Thread
|
|
23
|
+
|
|
24
|
+
Create a worker file that exposes methods to the main thread:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// worker.ts
|
|
28
|
+
import { expose } from '@wordpress/worker-threads/worker';
|
|
29
|
+
|
|
30
|
+
const api = {
|
|
31
|
+
async processImage( buffer: ArrayBuffer, quality: number ): Promise<ArrayBuffer> {
|
|
32
|
+
// ... image processing logic
|
|
33
|
+
return resultBuffer;
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
async calculateSum( a: number, b: number ): Promise<number> {
|
|
37
|
+
return a + b;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
expose( api );
|
|
42
|
+
|
|
43
|
+
// Export the type for use with wrap() on the main thread
|
|
44
|
+
export type WorkerAPI = typeof api;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Main Thread
|
|
48
|
+
|
|
49
|
+
Wrap the worker to get a type-safe proxy:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// main.ts
|
|
53
|
+
import { wrap, terminate } from '@wordpress/worker-threads';
|
|
54
|
+
import type { WorkerAPI } from './worker';
|
|
55
|
+
|
|
56
|
+
// Create the worker
|
|
57
|
+
const worker = new Worker( new URL( './worker.js', import.meta.url ), {
|
|
58
|
+
type: 'module',
|
|
59
|
+
} );
|
|
60
|
+
|
|
61
|
+
// Wrap it to get the RPC proxy
|
|
62
|
+
const api = wrap<WorkerAPI>( worker );
|
|
63
|
+
|
|
64
|
+
// Call methods as async functions
|
|
65
|
+
const result = await api.processImage( imageBuffer, 0.82 );
|
|
66
|
+
const sum = await api.calculateSum( 1, 2 );
|
|
67
|
+
|
|
68
|
+
// Clean up when done
|
|
69
|
+
terminate( api );
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API Reference
|
|
73
|
+
|
|
74
|
+
### Main Thread API
|
|
75
|
+
|
|
76
|
+
#### `wrap<T>( worker: Worker ): Remote<T>`
|
|
77
|
+
|
|
78
|
+
Wraps a Worker to provide a type-safe RPC interface. The returned proxy object allows calling methods on the worker as if they were local async functions.
|
|
79
|
+
|
|
80
|
+
#### `terminate( remote: Remote<unknown> ): void`
|
|
81
|
+
|
|
82
|
+
Terminates a wrapped worker and cleans up resources. Any pending calls will be rejected.
|
|
83
|
+
|
|
84
|
+
### Worker Thread API
|
|
85
|
+
|
|
86
|
+
#### `expose<T>( target: T ): void`
|
|
87
|
+
|
|
88
|
+
Exposes an object's methods to be called from the main thread. Should be called once in the worker script.
|
|
89
|
+
|
|
90
|
+
### Types
|
|
91
|
+
|
|
92
|
+
#### `Remote<T>`
|
|
93
|
+
|
|
94
|
+
A type that converts all methods of `T` to their async versions. Each method returns `Promise<Awaited<ReturnType>>`.
|
|
95
|
+
|
|
96
|
+
## Features
|
|
97
|
+
|
|
98
|
+
### Automatic Transferable Detection
|
|
99
|
+
|
|
100
|
+
The package automatically detects and transfers `ArrayBuffer` and other transferable objects, providing zero-copy performance for large data:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// ArrayBuffers are automatically transferred, not copied
|
|
104
|
+
const result = await api.processImage( largeImageBuffer );
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Error Handling
|
|
108
|
+
|
|
109
|
+
Errors thrown in the worker are properly propagated to the main thread:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
try {
|
|
113
|
+
await api.riskyOperation();
|
|
114
|
+
} catch ( error ) {
|
|
115
|
+
console.error( 'Worker error:', error.message );
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### TypeScript Support
|
|
120
|
+
|
|
121
|
+
Full type inference for method signatures:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// TypeScript knows the return type and parameter types
|
|
125
|
+
const result: ArrayBuffer = await api.processImage( buffer, 0.82 );
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Contributing to this package
|
|
129
|
+
|
|
130
|
+
This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.
|
|
131
|
+
|
|
132
|
+
To find out more about contributing to this package or Gutenberg as a whole, please read the project's main [contributor guide](https://github.com/WordPress/gutenberg/tree/HEAD/CONTRIBUTING.md).
|
package/build/index.cjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// packages/worker-threads/src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
expose: () => import_worker_thread.expose,
|
|
24
|
+
terminate: () => import_main_thread2.terminate,
|
|
25
|
+
wrap: () => import_main_thread.wrap
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
var import_main_thread = require("./main-thread.cjs");
|
|
29
|
+
var import_main_thread2 = require("./main-thread.cjs");
|
|
30
|
+
var import_worker_thread = require("./worker-thread.cjs");
|
|
31
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
32
|
+
0 && (module.exports = {
|
|
33
|
+
expose,
|
|
34
|
+
terminate,
|
|
35
|
+
wrap
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Main entry point for @wordpress/worker-threads.\n *\n * This module provides utilities for type-safe Web Worker communication\n * using an RPC (Remote Procedure Call) pattern. It allows you to call\n * methods on a worker as if they were local async functions.\n *\n * @example\n * Main thread usage:\n * ```typescript\n * import { wrap, terminate } from '@wordpress/worker-threads';\n * import type { WorkerAPI } from './worker';\n *\n * const worker = new Worker(new URL('./worker.js', import.meta.url));\n * const api = wrap<WorkerAPI>(worker);\n *\n * const result = await api.processData(data);\n *\n * terminate(api);\n * ```\n *\n * Worker thread usage:\n * ```typescript\n * import { expose } from '@wordpress/worker-threads';\n *\n * const api = {\n * async processData(data: ArrayBuffer): Promise<ArrayBuffer> {\n * // ... processing\n * return result;\n * }\n * };\n *\n * expose(api);\n * export type WorkerAPI = typeof api;\n * ```\n */\n\n/**\n * Wraps a Worker to provide a type-safe RPC interface.\n */\nexport { wrap } from './main-thread';\n\n/**\n * Terminates a wrapped worker and cleans up resources.\n */\nexport { terminate } from './main-thread';\n\n/**\n * Exposes an object's methods to be called from the main thread.\n * This should be called in the worker script.\n */\nexport { expose } from './worker-thread';\n\n/**\n * Type that converts all methods to async versions.\n */\nexport type { Remote } from './types';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCA,yBAAqB;AAKrB,IAAAA,sBAA0B;AAM1B,2BAAuB;",
|
|
6
|
+
"names": ["import_main_thread"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// packages/worker-threads/src/main-thread.ts
|
|
21
|
+
var main_thread_exports = {};
|
|
22
|
+
__export(main_thread_exports, {
|
|
23
|
+
terminate: () => terminate,
|
|
24
|
+
wrap: () => wrap
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(main_thread_exports);
|
|
27
|
+
var import_comctx = require("comctx");
|
|
28
|
+
var import_types = require("./types.cjs");
|
|
29
|
+
var WorkerInjectAdapter = class {
|
|
30
|
+
worker;
|
|
31
|
+
constructor(worker) {
|
|
32
|
+
this.worker = worker;
|
|
33
|
+
}
|
|
34
|
+
sendMessage = (message, transfer) => {
|
|
35
|
+
this.worker.postMessage(message, transfer);
|
|
36
|
+
};
|
|
37
|
+
onMessage = (callback) => {
|
|
38
|
+
const handler = (event) => callback(event.data);
|
|
39
|
+
this.worker.addEventListener("message", handler);
|
|
40
|
+
return () => this.worker.removeEventListener("message", handler);
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
var remoteWorkers = /* @__PURE__ */ new WeakMap();
|
|
44
|
+
function wrap(worker) {
|
|
45
|
+
const [, inject] = (0, import_comctx.defineProxy)(() => ({}), {
|
|
46
|
+
namespace: "__wordpress_worker__",
|
|
47
|
+
heartbeatCheck: false,
|
|
48
|
+
transfer: true
|
|
49
|
+
});
|
|
50
|
+
const comctxRemote = inject(new WorkerInjectAdapter(worker));
|
|
51
|
+
remoteWorkers.set(comctxRemote, worker);
|
|
52
|
+
const proxy = new Proxy(comctxRemote, {
|
|
53
|
+
get(target, prop) {
|
|
54
|
+
if (prop === import_types.WORKER_SYMBOL) {
|
|
55
|
+
return worker;
|
|
56
|
+
}
|
|
57
|
+
return Reflect.get(target, prop);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
remoteWorkers.set(proxy, worker);
|
|
61
|
+
return proxy;
|
|
62
|
+
}
|
|
63
|
+
function terminate(remote) {
|
|
64
|
+
const worker = remote[import_types.WORKER_SYMBOL];
|
|
65
|
+
if (!worker) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
remoteWorkers.delete(remote);
|
|
69
|
+
worker.terminate();
|
|
70
|
+
}
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
terminate,
|
|
74
|
+
wrap
|
|
75
|
+
});
|
|
76
|
+
//# sourceMappingURL=main-thread.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/main-thread.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tdefineProxy,\n\ttype Adapter,\n\ttype SendMessage,\n\ttype OnMessage,\n} from 'comctx';\n\n/**\n * Internal dependencies\n */\nimport { WORKER_SYMBOL, type Remote, type WithWorker } from './types';\n\n/**\n * Adapter for injecting (main thread calling worker).\n */\nclass WorkerInjectAdapter implements Adapter {\n\tprivate worker: Worker;\n\n\tconstructor( worker: Worker ) {\n\t\tthis.worker = worker;\n\t}\n\n\tsendMessage: SendMessage = ( message, transfer ) => {\n\t\tthis.worker.postMessage( message, transfer );\n\t};\n\n\tonMessage: OnMessage = ( callback ) => {\n\t\tconst handler = ( event: MessageEvent ) => callback( event.data );\n\t\tthis.worker.addEventListener( 'message', handler );\n\t\treturn () => this.worker.removeEventListener( 'message', handler );\n\t};\n}\n\n/**\n * WeakMap to store workers for each remote proxy.\n */\nconst remoteWorkers = new WeakMap< object, Worker >();\n\n/**\n * Wraps a Worker to provide a type-safe RPC interface.\n *\n * The returned proxy object allows calling methods on the worker as if they\n * were local async functions. Each method call is automatically serialized,\n * sent to the worker, and the result is returned as a Promise.\n *\n * @example\n * ```typescript\n * const worker = new Worker(new URL('./worker.js', import.meta.url));\n * const api = wrap<MyWorkerAPI>(worker);\n *\n * // Call worker methods as async functions\n * const result = await api.processData(data);\n * ```\n *\n * @param worker - The Worker instance to wrap.\n * @return A proxy object with all exposed methods as async functions.\n */\nexport function wrap< T extends object >( worker: Worker ): Remote< T > {\n\t// Create the inject function using defineProxy with an empty object\n\t// (the actual implementation is on the worker side).\n\tconst [ , inject ] = defineProxy( () => ( {} ) as T, {\n\t\tnamespace: '__wordpress_worker__',\n\t\theartbeatCheck: false,\n\t\ttransfer: true,\n\t} );\n\n\t// Create the proxy using the injector.\n\tconst comctxRemote = inject( new WorkerInjectAdapter( worker ) );\n\n\t// Store the worker reference.\n\tremoteWorkers.set( comctxRemote as object, worker );\n\n\t// Create a wrapper proxy that adds WORKER_SYMBOL support.\n\tconst proxy = new Proxy( comctxRemote as Remote< T > & WithWorker, {\n\t\tget( target, prop: string | symbol ) {\n\t\t\t// Return the worker for the WORKER_SYMBOL.\n\t\t\tif ( prop === WORKER_SYMBOL ) {\n\t\t\t\treturn worker;\n\t\t\t}\n\n\t\t\t// Delegate all other property access to the comctx remote.\n\t\t\treturn Reflect.get( target, prop );\n\t\t},\n\t} );\n\n\t// Store the worker for the proxy as well.\n\tremoteWorkers.set( proxy, worker );\n\n\treturn proxy;\n}\n\n/**\n * Terminates a wrapped worker and cleans up resources.\n *\n * After calling terminate, any pending calls will be rejected and the\n * worker will be stopped.\n *\n * @example\n * ```typescript\n * const api = wrap<MyWorkerAPI>(worker);\n * // ... use the API ...\n * terminate(api); // Clean up when done\n * ```\n *\n * @param remote - The wrapped worker proxy returned by wrap().\n */\nexport function terminate( remote: Remote< unknown > ): void {\n\t// Get the worker from the proxy.\n\tconst worker = ( remote as unknown as WithWorker )[ WORKER_SYMBOL ];\n\n\tif ( ! worker ) {\n\t\treturn;\n\t}\n\n\t// Clean up the worker reference.\n\tremoteWorkers.delete( remote as object );\n\n\t// Terminate the worker.\n\tworker.terminate();\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAKO;AAKP,mBAA4D;AAK5D,IAAM,sBAAN,MAA6C;AAAA,EACpC;AAAA,EAER,YAAa,QAAiB;AAC7B,SAAK,SAAS;AAAA,EACf;AAAA,EAEA,cAA2B,CAAE,SAAS,aAAc;AACnD,SAAK,OAAO,YAAa,SAAS,QAAS;AAAA,EAC5C;AAAA,EAEA,YAAuB,CAAE,aAAc;AACtC,UAAM,UAAU,CAAE,UAAyB,SAAU,MAAM,IAAK;AAChE,SAAK,OAAO,iBAAkB,WAAW,OAAQ;AACjD,WAAO,MAAM,KAAK,OAAO,oBAAqB,WAAW,OAAQ;AAAA,EAClE;AACD;AAKA,IAAM,gBAAgB,oBAAI,QAA0B;AAqB7C,SAAS,KAA0B,QAA8B;AAGvE,QAAM,CAAE,EAAE,MAAO,QAAI,2BAAa,OAAQ,CAAC,IAAU;AAAA,IACpD,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,UAAU;AAAA,EACX,CAAE;AAGF,QAAM,eAAe,OAAQ,IAAI,oBAAqB,MAAO,CAAE;AAG/D,gBAAc,IAAK,cAAwB,MAAO;AAGlD,QAAM,QAAQ,IAAI,MAAO,cAA0C;AAAA,IAClE,IAAK,QAAQ,MAAwB;AAEpC,UAAK,SAAS,4BAAgB;AAC7B,eAAO;AAAA,MACR;AAGA,aAAO,QAAQ,IAAK,QAAQ,IAAK;AAAA,IAClC;AAAA,EACD,CAAE;AAGF,gBAAc,IAAK,OAAO,MAAO;AAEjC,SAAO;AACR;AAiBO,SAAS,UAAW,QAAkC;AAE5D,QAAM,SAAW,OAAmC,0BAAc;AAElE,MAAK,CAAE,QAAS;AACf;AAAA,EACD;AAGA,gBAAc,OAAQ,MAAiB;AAGvC,SAAO,UAAU;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/build/types.cjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// packages/worker-threads/src/types.ts
|
|
21
|
+
var types_exports = {};
|
|
22
|
+
__export(types_exports, {
|
|
23
|
+
WORKER_SYMBOL: () => WORKER_SYMBOL
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(types_exports);
|
|
26
|
+
var WORKER_SYMBOL = /* @__PURE__ */ Symbol("worker");
|
|
27
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
28
|
+
0 && (module.exports = {
|
|
29
|
+
WORKER_SYMBOL
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=types.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/types.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Converts a type to its \"remote\" version where all methods become async.\n *\n * This type transformation ensures that when calling methods on a wrapped\n * worker, the return types are properly wrapped in Promises.\n */\nexport type Remote< T > = {\n\t[ K in keyof T ]: T[ K ] extends ( ...args: infer A ) => infer R\n\t\t? ( ...args: A ) => Promise< Awaited< R > >\n\t\t: never;\n};\n\n/**\n * Internal symbol used to store the worker reference on the proxy.\n */\nexport const WORKER_SYMBOL = Symbol( 'worker' );\n\n/**\n * Interface for objects that have an associated worker.\n */\nexport interface WithWorker {\n\t[ WORKER_SYMBOL ]: Worker;\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAeO,IAAM,gBAAgB,uBAAQ,QAAS;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// packages/worker-threads/src/worker-thread.ts
|
|
21
|
+
var worker_thread_exports = {};
|
|
22
|
+
__export(worker_thread_exports, {
|
|
23
|
+
expose: () => expose
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(worker_thread_exports);
|
|
26
|
+
var import_comctx = require("comctx");
|
|
27
|
+
var WorkerProvideAdapter = class {
|
|
28
|
+
sendMessage = (message, transfer) => {
|
|
29
|
+
self.postMessage(message, { transfer });
|
|
30
|
+
};
|
|
31
|
+
onMessage = (callback) => {
|
|
32
|
+
const handler = (event) => callback(event.data);
|
|
33
|
+
self.addEventListener("message", handler);
|
|
34
|
+
return () => self.removeEventListener("message", handler);
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
function expose(target) {
|
|
38
|
+
const [provide] = (0, import_comctx.defineProxy)(() => target, {
|
|
39
|
+
namespace: "__wordpress_worker__",
|
|
40
|
+
heartbeatCheck: false,
|
|
41
|
+
transfer: true
|
|
42
|
+
});
|
|
43
|
+
provide(new WorkerProvideAdapter());
|
|
44
|
+
}
|
|
45
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
+
0 && (module.exports = {
|
|
47
|
+
expose
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=worker-thread.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/worker-thread.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tdefineProxy,\n\ttype Adapter,\n\ttype SendMessage,\n\ttype OnMessage,\n} from 'comctx';\n\n/**\n * Adapter for providing (worker exposing methods to main thread).\n */\nclass WorkerProvideAdapter implements Adapter {\n\tsendMessage: SendMessage = ( message, transfer ) => {\n\t\tself.postMessage( message, { transfer } );\n\t};\n\n\tonMessage: OnMessage = ( callback ) => {\n\t\tconst handler = ( event: MessageEvent ) => callback( event.data );\n\t\tself.addEventListener( 'message', handler );\n\t\treturn () => self.removeEventListener( 'message', handler );\n\t};\n}\n\n/**\n * Exposes an object's methods to be called from the main thread.\n *\n * This function should be called in the worker script to make methods\n * available for RPC calls. Only methods (functions) on the object will\n * be exposed; other properties are ignored.\n *\n * @example\n * ```typescript\n * // worker.ts\n * import { expose } from '@wordpress/worker-threads/worker';\n *\n * const api = {\n * async processImage(buffer: ArrayBuffer): Promise<ArrayBuffer> {\n * // ... processing logic\n * return resultBuffer;\n * },\n *\n * async calculateSum(a: number, b: number): Promise<number> {\n * return a + b;\n * }\n * };\n *\n * expose(api);\n *\n * // Export the type for use with wrap() on main thread\n * export type WorkerAPI = typeof api;\n * ```\n *\n * @param target - Object containing methods to expose to the main thread.\n */\nexport function expose< T extends object >( target: T ): void {\n\t// Create the provide function using defineProxy with the target.\n\tconst [ provide ] = defineProxy( () => target, {\n\t\tnamespace: '__wordpress_worker__',\n\t\theartbeatCheck: false,\n\t\ttransfer: true,\n\t} );\n\n\t// Start providing the target through the adapter.\n\tprovide( new WorkerProvideAdapter() );\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,oBAKO;AAKP,IAAM,uBAAN,MAA8C;AAAA,EAC7C,cAA2B,CAAE,SAAS,aAAc;AACnD,SAAK,YAAa,SAAS,EAAE,SAAS,CAAE;AAAA,EACzC;AAAA,EAEA,YAAuB,CAAE,aAAc;AACtC,UAAM,UAAU,CAAE,UAAyB,SAAU,MAAM,IAAK;AAChE,SAAK,iBAAkB,WAAW,OAAQ;AAC1C,WAAO,MAAM,KAAK,oBAAqB,WAAW,OAAQ;AAAA,EAC3D;AACD;AAiCO,SAAS,OAA4B,QAAkB;AAE7D,QAAM,CAAE,OAAQ,QAAI,2BAAa,MAAM,QAAQ;AAAA,IAC9C,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,UAAU;AAAA,EACX,CAAE;AAGF,UAAS,IAAI,qBAAqB,CAAE;AACrC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// packages/worker-threads/src/index.ts
|
|
2
|
+
import { wrap } from "./main-thread.mjs";
|
|
3
|
+
import { terminate } from "./main-thread.mjs";
|
|
4
|
+
import { expose } from "./worker-thread.mjs";
|
|
5
|
+
export {
|
|
6
|
+
expose,
|
|
7
|
+
terminate,
|
|
8
|
+
wrap
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Main entry point for @wordpress/worker-threads.\n *\n * This module provides utilities for type-safe Web Worker communication\n * using an RPC (Remote Procedure Call) pattern. It allows you to call\n * methods on a worker as if they were local async functions.\n *\n * @example\n * Main thread usage:\n * ```typescript\n * import { wrap, terminate } from '@wordpress/worker-threads';\n * import type { WorkerAPI } from './worker';\n *\n * const worker = new Worker(new URL('./worker.js', import.meta.url));\n * const api = wrap<WorkerAPI>(worker);\n *\n * const result = await api.processData(data);\n *\n * terminate(api);\n * ```\n *\n * Worker thread usage:\n * ```typescript\n * import { expose } from '@wordpress/worker-threads';\n *\n * const api = {\n * async processData(data: ArrayBuffer): Promise<ArrayBuffer> {\n * // ... processing\n * return result;\n * }\n * };\n *\n * expose(api);\n * export type WorkerAPI = typeof api;\n * ```\n */\n\n/**\n * Wraps a Worker to provide a type-safe RPC interface.\n */\nexport { wrap } from './main-thread';\n\n/**\n * Terminates a wrapped worker and cleans up resources.\n */\nexport { terminate } from './main-thread';\n\n/**\n * Exposes an object's methods to be called from the main thread.\n * This should be called in the worker script.\n */\nexport { expose } from './worker-thread';\n\n/**\n * Type that converts all methods to async versions.\n */\nexport type { Remote } from './types';\n"],
|
|
5
|
+
"mappings": ";AAwCA,SAAS,YAAY;AAKrB,SAAS,iBAAiB;AAM1B,SAAS,cAAc;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// packages/worker-threads/src/main-thread.ts
|
|
2
|
+
import {
|
|
3
|
+
defineProxy
|
|
4
|
+
} from "comctx";
|
|
5
|
+
import { WORKER_SYMBOL } from "./types.mjs";
|
|
6
|
+
var WorkerInjectAdapter = class {
|
|
7
|
+
worker;
|
|
8
|
+
constructor(worker) {
|
|
9
|
+
this.worker = worker;
|
|
10
|
+
}
|
|
11
|
+
sendMessage = (message, transfer) => {
|
|
12
|
+
this.worker.postMessage(message, transfer);
|
|
13
|
+
};
|
|
14
|
+
onMessage = (callback) => {
|
|
15
|
+
const handler = (event) => callback(event.data);
|
|
16
|
+
this.worker.addEventListener("message", handler);
|
|
17
|
+
return () => this.worker.removeEventListener("message", handler);
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
var remoteWorkers = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
function wrap(worker) {
|
|
22
|
+
const [, inject] = defineProxy(() => ({}), {
|
|
23
|
+
namespace: "__wordpress_worker__",
|
|
24
|
+
heartbeatCheck: false,
|
|
25
|
+
transfer: true
|
|
26
|
+
});
|
|
27
|
+
const comctxRemote = inject(new WorkerInjectAdapter(worker));
|
|
28
|
+
remoteWorkers.set(comctxRemote, worker);
|
|
29
|
+
const proxy = new Proxy(comctxRemote, {
|
|
30
|
+
get(target, prop) {
|
|
31
|
+
if (prop === WORKER_SYMBOL) {
|
|
32
|
+
return worker;
|
|
33
|
+
}
|
|
34
|
+
return Reflect.get(target, prop);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
remoteWorkers.set(proxy, worker);
|
|
38
|
+
return proxy;
|
|
39
|
+
}
|
|
40
|
+
function terminate(remote) {
|
|
41
|
+
const worker = remote[WORKER_SYMBOL];
|
|
42
|
+
if (!worker) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
remoteWorkers.delete(remote);
|
|
46
|
+
worker.terminate();
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
terminate,
|
|
50
|
+
wrap
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=main-thread.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/main-thread.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tdefineProxy,\n\ttype Adapter,\n\ttype SendMessage,\n\ttype OnMessage,\n} from 'comctx';\n\n/**\n * Internal dependencies\n */\nimport { WORKER_SYMBOL, type Remote, type WithWorker } from './types';\n\n/**\n * Adapter for injecting (main thread calling worker).\n */\nclass WorkerInjectAdapter implements Adapter {\n\tprivate worker: Worker;\n\n\tconstructor( worker: Worker ) {\n\t\tthis.worker = worker;\n\t}\n\n\tsendMessage: SendMessage = ( message, transfer ) => {\n\t\tthis.worker.postMessage( message, transfer );\n\t};\n\n\tonMessage: OnMessage = ( callback ) => {\n\t\tconst handler = ( event: MessageEvent ) => callback( event.data );\n\t\tthis.worker.addEventListener( 'message', handler );\n\t\treturn () => this.worker.removeEventListener( 'message', handler );\n\t};\n}\n\n/**\n * WeakMap to store workers for each remote proxy.\n */\nconst remoteWorkers = new WeakMap< object, Worker >();\n\n/**\n * Wraps a Worker to provide a type-safe RPC interface.\n *\n * The returned proxy object allows calling methods on the worker as if they\n * were local async functions. Each method call is automatically serialized,\n * sent to the worker, and the result is returned as a Promise.\n *\n * @example\n * ```typescript\n * const worker = new Worker(new URL('./worker.js', import.meta.url));\n * const api = wrap<MyWorkerAPI>(worker);\n *\n * // Call worker methods as async functions\n * const result = await api.processData(data);\n * ```\n *\n * @param worker - The Worker instance to wrap.\n * @return A proxy object with all exposed methods as async functions.\n */\nexport function wrap< T extends object >( worker: Worker ): Remote< T > {\n\t// Create the inject function using defineProxy with an empty object\n\t// (the actual implementation is on the worker side).\n\tconst [ , inject ] = defineProxy( () => ( {} ) as T, {\n\t\tnamespace: '__wordpress_worker__',\n\t\theartbeatCheck: false,\n\t\ttransfer: true,\n\t} );\n\n\t// Create the proxy using the injector.\n\tconst comctxRemote = inject( new WorkerInjectAdapter( worker ) );\n\n\t// Store the worker reference.\n\tremoteWorkers.set( comctxRemote as object, worker );\n\n\t// Create a wrapper proxy that adds WORKER_SYMBOL support.\n\tconst proxy = new Proxy( comctxRemote as Remote< T > & WithWorker, {\n\t\tget( target, prop: string | symbol ) {\n\t\t\t// Return the worker for the WORKER_SYMBOL.\n\t\t\tif ( prop === WORKER_SYMBOL ) {\n\t\t\t\treturn worker;\n\t\t\t}\n\n\t\t\t// Delegate all other property access to the comctx remote.\n\t\t\treturn Reflect.get( target, prop );\n\t\t},\n\t} );\n\n\t// Store the worker for the proxy as well.\n\tremoteWorkers.set( proxy, worker );\n\n\treturn proxy;\n}\n\n/**\n * Terminates a wrapped worker and cleans up resources.\n *\n * After calling terminate, any pending calls will be rejected and the\n * worker will be stopped.\n *\n * @example\n * ```typescript\n * const api = wrap<MyWorkerAPI>(worker);\n * // ... use the API ...\n * terminate(api); // Clean up when done\n * ```\n *\n * @param remote - The wrapped worker proxy returned by wrap().\n */\nexport function terminate( remote: Remote< unknown > ): void {\n\t// Get the worker from the proxy.\n\tconst worker = ( remote as unknown as WithWorker )[ WORKER_SYMBOL ];\n\n\tif ( ! worker ) {\n\t\treturn;\n\t}\n\n\t// Clean up the worker reference.\n\tremoteWorkers.delete( remote as object );\n\n\t// Terminate the worker.\n\tworker.terminate();\n}\n"],
|
|
5
|
+
"mappings": ";AAGA;AAAA,EACC;AAAA,OAIM;AAKP,SAAS,qBAAmD;AAK5D,IAAM,sBAAN,MAA6C;AAAA,EACpC;AAAA,EAER,YAAa,QAAiB;AAC7B,SAAK,SAAS;AAAA,EACf;AAAA,EAEA,cAA2B,CAAE,SAAS,aAAc;AACnD,SAAK,OAAO,YAAa,SAAS,QAAS;AAAA,EAC5C;AAAA,EAEA,YAAuB,CAAE,aAAc;AACtC,UAAM,UAAU,CAAE,UAAyB,SAAU,MAAM,IAAK;AAChE,SAAK,OAAO,iBAAkB,WAAW,OAAQ;AACjD,WAAO,MAAM,KAAK,OAAO,oBAAqB,WAAW,OAAQ;AAAA,EAClE;AACD;AAKA,IAAM,gBAAgB,oBAAI,QAA0B;AAqB7C,SAAS,KAA0B,QAA8B;AAGvE,QAAM,CAAE,EAAE,MAAO,IAAI,YAAa,OAAQ,CAAC,IAAU;AAAA,IACpD,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,UAAU;AAAA,EACX,CAAE;AAGF,QAAM,eAAe,OAAQ,IAAI,oBAAqB,MAAO,CAAE;AAG/D,gBAAc,IAAK,cAAwB,MAAO;AAGlD,QAAM,QAAQ,IAAI,MAAO,cAA0C;AAAA,IAClE,IAAK,QAAQ,MAAwB;AAEpC,UAAK,SAAS,eAAgB;AAC7B,eAAO;AAAA,MACR;AAGA,aAAO,QAAQ,IAAK,QAAQ,IAAK;AAAA,IAClC;AAAA,EACD,CAAE;AAGF,gBAAc,IAAK,OAAO,MAAO;AAEjC,SAAO;AACR;AAiBO,SAAS,UAAW,QAAkC;AAE5D,QAAM,SAAW,OAAmC,aAAc;AAElE,MAAK,CAAE,QAAS;AACf;AAAA,EACD;AAGA,gBAAc,OAAQ,MAAiB;AAGvC,SAAO,UAAU;AAClB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/types.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Converts a type to its \"remote\" version where all methods become async.\n *\n * This type transformation ensures that when calling methods on a wrapped\n * worker, the return types are properly wrapped in Promises.\n */\nexport type Remote< T > = {\n\t[ K in keyof T ]: T[ K ] extends ( ...args: infer A ) => infer R\n\t\t? ( ...args: A ) => Promise< Awaited< R > >\n\t\t: never;\n};\n\n/**\n * Internal symbol used to store the worker reference on the proxy.\n */\nexport const WORKER_SYMBOL = Symbol( 'worker' );\n\n/**\n * Interface for objects that have an associated worker.\n */\nexport interface WithWorker {\n\t[ WORKER_SYMBOL ]: Worker;\n}\n"],
|
|
5
|
+
"mappings": ";AAeO,IAAM,gBAAgB,uBAAQ,QAAS;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// packages/worker-threads/src/worker-thread.ts
|
|
2
|
+
import {
|
|
3
|
+
defineProxy
|
|
4
|
+
} from "comctx";
|
|
5
|
+
var WorkerProvideAdapter = class {
|
|
6
|
+
sendMessage = (message, transfer) => {
|
|
7
|
+
self.postMessage(message, { transfer });
|
|
8
|
+
};
|
|
9
|
+
onMessage = (callback) => {
|
|
10
|
+
const handler = (event) => callback(event.data);
|
|
11
|
+
self.addEventListener("message", handler);
|
|
12
|
+
return () => self.removeEventListener("message", handler);
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
function expose(target) {
|
|
16
|
+
const [provide] = defineProxy(() => target, {
|
|
17
|
+
namespace: "__wordpress_worker__",
|
|
18
|
+
heartbeatCheck: false,
|
|
19
|
+
transfer: true
|
|
20
|
+
});
|
|
21
|
+
provide(new WorkerProvideAdapter());
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
expose
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=worker-thread.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/worker-thread.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport {\n\tdefineProxy,\n\ttype Adapter,\n\ttype SendMessage,\n\ttype OnMessage,\n} from 'comctx';\n\n/**\n * Adapter for providing (worker exposing methods to main thread).\n */\nclass WorkerProvideAdapter implements Adapter {\n\tsendMessage: SendMessage = ( message, transfer ) => {\n\t\tself.postMessage( message, { transfer } );\n\t};\n\n\tonMessage: OnMessage = ( callback ) => {\n\t\tconst handler = ( event: MessageEvent ) => callback( event.data );\n\t\tself.addEventListener( 'message', handler );\n\t\treturn () => self.removeEventListener( 'message', handler );\n\t};\n}\n\n/**\n * Exposes an object's methods to be called from the main thread.\n *\n * This function should be called in the worker script to make methods\n * available for RPC calls. Only methods (functions) on the object will\n * be exposed; other properties are ignored.\n *\n * @example\n * ```typescript\n * // worker.ts\n * import { expose } from '@wordpress/worker-threads/worker';\n *\n * const api = {\n * async processImage(buffer: ArrayBuffer): Promise<ArrayBuffer> {\n * // ... processing logic\n * return resultBuffer;\n * },\n *\n * async calculateSum(a: number, b: number): Promise<number> {\n * return a + b;\n * }\n * };\n *\n * expose(api);\n *\n * // Export the type for use with wrap() on main thread\n * export type WorkerAPI = typeof api;\n * ```\n *\n * @param target - Object containing methods to expose to the main thread.\n */\nexport function expose< T extends object >( target: T ): void {\n\t// Create the provide function using defineProxy with the target.\n\tconst [ provide ] = defineProxy( () => target, {\n\t\tnamespace: '__wordpress_worker__',\n\t\theartbeatCheck: false,\n\t\ttransfer: true,\n\t} );\n\n\t// Start providing the target through the adapter.\n\tprovide( new WorkerProvideAdapter() );\n}\n"],
|
|
5
|
+
"mappings": ";AAGA;AAAA,EACC;AAAA,OAIM;AAKP,IAAM,uBAAN,MAA8C;AAAA,EAC7C,cAA2B,CAAE,SAAS,aAAc;AACnD,SAAK,YAAa,SAAS,EAAE,SAAS,CAAE;AAAA,EACzC;AAAA,EAEA,YAAuB,CAAE,aAAc;AACtC,UAAM,UAAU,CAAE,UAAyB,SAAU,MAAM,IAAK;AAChE,SAAK,iBAAkB,WAAW,OAAQ;AAC1C,WAAO,MAAM,KAAK,oBAAqB,WAAW,OAAQ;AAAA,EAC3D;AACD;AAiCO,SAAS,OAA4B,QAAkB;AAE7D,QAAM,CAAE,OAAQ,IAAI,YAAa,MAAM,QAAQ;AAAA,IAC9C,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,UAAU;AAAA,EACX,CAAE;AAGF,UAAS,IAAI,qBAAqB,CAAE;AACrC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for @wordpress/worker-threads.
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for type-safe Web Worker communication
|
|
5
|
+
* using an RPC (Remote Procedure Call) pattern. It allows you to call
|
|
6
|
+
* methods on a worker as if they were local async functions.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* Main thread usage:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { wrap, terminate } from '@wordpress/worker-threads';
|
|
12
|
+
* import type { WorkerAPI } from './worker';
|
|
13
|
+
*
|
|
14
|
+
* const worker = new Worker(new URL('./worker.js', import.meta.url));
|
|
15
|
+
* const api = wrap<WorkerAPI>(worker);
|
|
16
|
+
*
|
|
17
|
+
* const result = await api.processData(data);
|
|
18
|
+
*
|
|
19
|
+
* terminate(api);
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* Worker thread usage:
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { expose } from '@wordpress/worker-threads';
|
|
25
|
+
*
|
|
26
|
+
* const api = {
|
|
27
|
+
* async processData(data: ArrayBuffer): Promise<ArrayBuffer> {
|
|
28
|
+
* // ... processing
|
|
29
|
+
* return result;
|
|
30
|
+
* }
|
|
31
|
+
* };
|
|
32
|
+
*
|
|
33
|
+
* expose(api);
|
|
34
|
+
* export type WorkerAPI = typeof api;
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Wraps a Worker to provide a type-safe RPC interface.
|
|
39
|
+
*/
|
|
40
|
+
export { wrap } from './main-thread';
|
|
41
|
+
/**
|
|
42
|
+
* Terminates a wrapped worker and cleans up resources.
|
|
43
|
+
*/
|
|
44
|
+
export { terminate } from './main-thread';
|
|
45
|
+
/**
|
|
46
|
+
* Exposes an object's methods to be called from the main thread.
|
|
47
|
+
* This should be called in the worker script.
|
|
48
|
+
*/
|
|
49
|
+
export { expose } from './worker-thread';
|
|
50
|
+
/**
|
|
51
|
+
* Type that converts all methods to async versions.
|
|
52
|
+
*/
|
|
53
|
+
export type { Remote } from './types';
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;GAEG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC;;GAEG;AACH,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { type Remote } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Wraps a Worker to provide a type-safe RPC interface.
|
|
7
|
+
*
|
|
8
|
+
* The returned proxy object allows calling methods on the worker as if they
|
|
9
|
+
* were local async functions. Each method call is automatically serialized,
|
|
10
|
+
* sent to the worker, and the result is returned as a Promise.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const worker = new Worker(new URL('./worker.js', import.meta.url));
|
|
15
|
+
* const api = wrap<MyWorkerAPI>(worker);
|
|
16
|
+
*
|
|
17
|
+
* // Call worker methods as async functions
|
|
18
|
+
* const result = await api.processData(data);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @param worker - The Worker instance to wrap.
|
|
22
|
+
* @return A proxy object with all exposed methods as async functions.
|
|
23
|
+
*/
|
|
24
|
+
export declare function wrap<T extends object>(worker: Worker): Remote<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Terminates a wrapped worker and cleans up resources.
|
|
27
|
+
*
|
|
28
|
+
* After calling terminate, any pending calls will be rejected and the
|
|
29
|
+
* worker will be stopped.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const api = wrap<MyWorkerAPI>(worker);
|
|
34
|
+
* // ... use the API ...
|
|
35
|
+
* terminate(api); // Clean up when done
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @param remote - The wrapped worker proxy returned by wrap().
|
|
39
|
+
*/
|
|
40
|
+
export declare function terminate(remote: Remote<unknown>): void;
|
|
41
|
+
//# sourceMappingURL=main-thread.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main-thread.d.ts","sourceRoot":"","sources":["../src/main-thread.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,OAAO,EAAiB,KAAK,MAAM,EAAmB,MAAM,SAAS,CAAC;AA4BtE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,IAAI,CAAE,CAAC,SAAS,MAAM,EAAI,MAAM,EAAE,MAAM,GAAI,MAAM,CAAE,CAAC,CAAE,CAgCtE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAE,MAAM,EAAE,MAAM,CAAE,OAAO,CAAE,GAAI,IAAI,CAa3D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a type to its "remote" version where all methods become async.
|
|
3
|
+
*
|
|
4
|
+
* This type transformation ensures that when calling methods on a wrapped
|
|
5
|
+
* worker, the return types are properly wrapped in Promises.
|
|
6
|
+
*/
|
|
7
|
+
export type Remote<T> = {
|
|
8
|
+
[K in keyof T]: T[K] extends (...args: infer A) => infer R ? (...args: A) => Promise<Awaited<R>> : never;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Internal symbol used to store the worker reference on the proxy.
|
|
12
|
+
*/
|
|
13
|
+
export declare const WORKER_SYMBOL: unique symbol;
|
|
14
|
+
/**
|
|
15
|
+
* Interface for objects that have an associated worker.
|
|
16
|
+
*/
|
|
17
|
+
export interface WithWorker {
|
|
18
|
+
[WORKER_SYMBOL]: Worker;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,MAAM,CAAE,CAAC,IAAK;KACvB,CAAC,IAAI,MAAM,CAAC,GAAI,CAAC,CAAE,CAAC,CAAE,SAAS,CAAE,GAAG,IAAI,EAAE,MAAM,CAAC,KAAM,MAAM,CAAC,GAC7D,CAAE,GAAG,IAAI,EAAE,CAAC,KAAM,OAAO,CAAE,OAAO,CAAE,CAAC,CAAE,CAAE,GACzC,KAAK;CACR,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,eAAqB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,CAAE,aAAa,CAAE,EAAE,MAAM,CAAC;CAC1B"}
|