achi-rpc 1.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License Copyright (c) 2026 Kimbugwe Mark
2
+
3
+ Permission is hereby granted, free
4
+ of charge, to any person obtaining a copy of this software and associated
5
+ documentation files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use, copy, modify, merge,
7
+ publish, distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to the
9
+ following conditions:
10
+
11
+ The above copyright notice and this permission notice
12
+ (including the next paragraph) shall be included in all copies or substantial
13
+ portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
16
+ ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
18
+ EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,374 @@
1
+ # Achi RPC
2
+
3
+ An RPC library for TypeScript and JavaScript that turns Web Workers, Shared Workers, iframes, and `postMessage`-based threads into plain `async` function calls — no manual message-passing boilerplate required.
4
+
5
+ It supports the browser as well as other runtimes like Node.js, Bun, Deno, and Cloudflare Workers.
6
+
7
+ ![Chrome 80+](https://img.shields.io/badge/Chrome-80+-green.svg?style=flat-square)
8
+ ![Edge 80+](https://img.shields.io/badge/Edge-80+-green.svg?style=flat-square)
9
+ ![Firefox 74+](https://img.shields.io/badge/Firefox-74+-green.svg?style=flat-square)
10
+ ![Opera 67+](https://img.shields.io/badge/Opera-67+-green.svg?style=flat-square)
11
+ ![Safari 13.1+](https://img.shields.io/badge/Safari-13.1+-green.svg?style=flat-square)
12
+ ![Samsung Internet 13.0+](https://img.shields.io/badge/Samsung_Internet-13.0+-green.svg?style=flat-square)
13
+ ![Node.js 15+](https://img.shields.io/badge/Node.js-22+-green.svg?style=flat-square)
14
+ ![Deno 1.12+](https://img.shields.io/badge/Deno-1.12+-green.svg?style=flat-square)
15
+ ![Bun 1.0+](https://img.shields.io/badge/Bun-1.0+-green.svg?style=flat-square)
16
+
17
+ ## Table of contents
18
+
19
+ - [Why Achi RPC?](#why-achi-rpc)
20
+ - [Features](#features)
21
+ - [Install](#install)
22
+ - [Runtime support](#runtime-support)
23
+ - [Functions](#functions)
24
+ - [Classes](#classes)
25
+ - [Shared worker](#shared-worker)
26
+ - [Iframes](#iframes)
27
+ - [Usage](#usage)
28
+ - [API](#api)
29
+ - [How it works](#how-it-works)
30
+ - [License](#license)
31
+
32
+ ## Why Achi RPC?
33
+
34
+ Moving work off the main thread keeps your UI responsive and lets CPU-heavy tasks (parsing, image processing, big computations) run in parallel instead of blocking the page. The problem is that talking to a worker normally means:
35
+
36
+ - Manually calling `postMessage` and listening for `onmessage`
37
+ - Inventing your own way to match a response back to the request that triggered it
38
+ - Re-declaring types for whatever you exported, since the worker and the main thread don't share scope
39
+ - Writing this all over again for every worker, shared worker, or iframe you add
40
+
41
+ Achi RPC removes that boilerplate. You export your functions or classes on one side, and call them like normal local functions — `async` — on the other. Autocomplete and types carry over automatically in TypeScript.
42
+
43
+ **Before** — calling a function directly:
44
+
45
+ ```ts
46
+ import { sum, fibonacci } from "./fun";
47
+
48
+ console.log(fibonacci(56));
49
+ console.log(sum(3, 4, 5, 7, 8, 2, 1));
50
+ ```
51
+
52
+ **After** — the exact same functions, now running in a worker:
53
+
54
+ ```ts
55
+ import { RPCInstance, type Asyncify } from "achi-rpc";
56
+
57
+ type fun = Asyncify<typeof import("./fun")>;
58
+ const rpc = new RPCInstance(
59
+ new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
60
+ ) as fun & Worker;
61
+
62
+ console.log(await rpc.fibonacci(56));
63
+ console.log(await rpc.sum(3, 4, 5, 7, 8, 2, 1));
64
+ ```
65
+
66
+ That's the whole migration: swap the import for `RPCInstance`, wrap it around a `Worker`, and `await` the calls you already had. Everything else — argument passing, return values, error propagation — behaves the way it already did.
67
+
68
+ ## Features
69
+
70
+ - 🧵 First-class support for Web Workers, Shared Workers, and iframes
71
+ - 🪶 Minimal API — most of your existing code stays untouched; you mostly just add `await`
72
+ - 🔒 Explicit `targetOrigin` support for secure cross-origin iframe messaging
73
+ - 📦 Ships for `npm`/bundlers and as an IIFE build you can load straight from jsDelivr or unpkg — no build step required
74
+ - 🌐 Works in the browser, Node.js, Deno, Bun, and Cloudflare Workers
75
+ - 🎯 Full TypeScript inference for exported functions and classes via `Asyncify`
76
+ - 🚚 Transferable objects (e.g. streams) are detected and transferred automatically
77
+ - 🪝 Class instances are wrapped in a proxy — native methods (e.g. `.close()`, `.terminate()`) stay accessible alongside the ones you exported
78
+
79
+ ## Install
80
+
81
+ ```bash
82
+ npm install achi-rpc
83
+ ```
84
+
85
+ ### CDN / IIFE (no bundler required)
86
+
87
+ Achi RPC also ships an IIFE build, so you can drop it straight into a `<script>` tag via jsDelivr or unpkg:
88
+
89
+ ```html
90
+ <!-- jsDelivr -->
91
+ <script src="https://cdn.jsdelivr.net/npm/achi-rpc"></script>
92
+
93
+ <!-- unpkg -->
94
+ <script src="https://unpkg.com/achi-rpc"></script>
95
+
96
+ <script>
97
+ // global name depends on how your build is configured — check dist/ if this differs
98
+ const rpc = new AchiRPC.RPCInstance(new Worker("./worker.js"));
99
+ rpc.fibonacci(56).then(console.log);
100
+ </script>
101
+ ```
102
+
103
+ Pin a version in production, e.g. `https://cdn.jsdelivr.net/npm/achi-rpc@1`, instead of tracking `latest`.
104
+
105
+ ## Runtime support
106
+
107
+ | Runtime | How to use it |
108
+ | --------------------- | ---------------------------------------------------------------------------------------------- |
109
+ | Browser (main thread) | `RPC` / `RPCInstance` as shown above |
110
+ | Web Worker | `RPCServer` / `RPCInstanceServer` inside the worker, using `self` |
111
+ | Shared Worker | Same as a Worker, but pass the connected `MessagePort` instead of `Worker`/`self` |
112
+ | iframe | Pass `window` and a `targetOrigin` — see [Iframes](#iframes) |
113
+ | Node.js | Use `worker_threads` and `parentPort` in place of `Worker` and `self` |
114
+ | Deno | Same API as the browser — `new Worker(url, { type: "module" })` |
115
+ | Bun | Same API as the browser — `new Worker(url)` |
116
+ | Cloudflare Workers | Works over any `postMessage`-compatible transport (e.g. a Durable Object WebSocket connection) |
117
+
118
+ ## Functions
119
+
120
+ ### Main thread
121
+
122
+ The main thread can also be a worker.
123
+ `RPCInstance` only exposes exported functions.
124
+
125
+ #### Typescript
126
+
127
+ ```ts
128
+ import { RPCInstance, type Asyncify } from "achi-rpc";
129
+
130
+ try {
131
+ //get types of imported functions
132
+ type fun = Asyncify<typeof import("./fun")>;
133
+ // as fun applies imported types to rpc for autocompletion and removes Typescript errors
134
+ const rpc = new RPCInstance(
135
+ new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
136
+ ) as fun & Worker;
137
+ console.log(await rpc.fibonacci(56));
138
+ console.log(await rpc.sum(3, 4, 5, 7, 8, 2, 1));
139
+ //transferable objects like streams are transferred by default
140
+ console.log(await rpc.readStream(readable));
141
+ //worker properties can still be accessed
142
+ rpc.terminate();
143
+ } catch (e) {
144
+ console.log(e);
145
+ }
146
+ ```
147
+
148
+ #### Javascript
149
+
150
+ ```ts
151
+ import { RPCInstance } from "achi-rpc";
152
+
153
+ try {
154
+ const rpc = new RPCInstance(
155
+ new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
156
+ );
157
+ console.log(await rpc.fibonacci(56));
158
+ console.log(await rpc.sum(3, 4, 5, 7, 8, 2, 1));
159
+ rpc.terminate();
160
+ } catch (e) {
161
+ console.log(e);
162
+ }
163
+ ```
164
+
165
+ ### Worker thread
166
+
167
+ #### Typescript and Javascript
168
+
169
+ ```ts
170
+ //worker
171
+ import { RPCInstanceServer } from "achi-rpc";
172
+ import { fibonacci, sum, readStream } from "./fun";
173
+
174
+ const server = new RPCInstanceServer(self);
175
+ //exposes functions to the main thread
176
+ server.export([fibonacci, sum, readStream]);
177
+ ```
178
+
179
+ ## Classes
180
+
181
+ ### Main thread
182
+
183
+ The main thread can also act as a worker thread to enable duplex communication. RPC exposes only exported class constructors through `getConstructor`, and functions are exposed through the `RPCInstance` interface returned by `getRPC`.
184
+
185
+ ```ts
186
+ import { RPC, type Asyncify } from "achi-rpc";
187
+
188
+ try {
189
+ //get class type of exported class
190
+ type RectangleType = Asyncify<(typeof import("./classes"))["Rectangle"]>;
191
+ //get types of exported functions
192
+ type fun = Asyncify<typeof import("./fun")>;
193
+ const rpc = new RPC(
194
+ new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
195
+ );
196
+ const Rectangle = rpc.getConstructor("Rectangle") as RectangleType &
197
+ MessagePort;
198
+ const rect = await new Rectangle(5, 58);
199
+ console.log(await rect.getHeight());
200
+ console.log(await rect.getWidth());
201
+ console.log(await rect.getArea());
202
+ // closes the message port for the class and removes the class instance,
203
+ // it can also be called automatically if your runtime supports the FinalizationRegistry api
204
+ rect.close();
205
+ //returns an rpc instance for functions
206
+ const rpc1 = rpc.getRPC() as fun & Worker;
207
+ console.log(await rpc1.fibonacci(56));
208
+ console.log(await rpc1.sum(3, 4, 5, 7, 8, 2, 1));
209
+ //terminates the worker
210
+ rpc1.terminate();
211
+ } catch (error) {
212
+ console.log(error);
213
+ }
214
+ ```
215
+
216
+ #### Javascript
217
+
218
+ ```js
219
+ import { RPC } from "achi-rpc";
220
+ import { Rectangle } from "./rectangle";
221
+ try {
222
+ const rpc = new RPC(
223
+ new Worker(new URL("./worker.ts", import.meta.url), { type: "module" }),
224
+ );
225
+ type WorkerRectangleType = Asyncify<typeof Rectangle>;
226
+ const Rectangle = rpc.getConstructor(Rectangle) as WorkerRectangleType;
227
+ //or
228
+ //const Rectangle = rpc.getConstructor("Rectangle");
229
+ const rect = await new Rectangle(5, 58);
230
+ console.log(await rect.getHeight());
231
+ console.log(await rect.getWidth());
232
+ console.log(await rect.getArea());
233
+ // closes the message port for the class and removes the class instance,
234
+ //it can also be called automatically if your runtime supports the FinalizationRegistry api
235
+ rect.close();
236
+ //returns an rpc instance for functions
237
+ const rpc1 = rpc.getRPC();
238
+ console.log(await rpc1.fibonacci(56));
239
+ console.log(await rpc1.sum(3, 4, 5, 7, 8, 2, 1));
240
+ //terminates the worker
241
+ rpc1.terminate();
242
+ } catch (error) {
243
+ console.log(error);
244
+ }
245
+ ```
246
+
247
+ ### Child thread
248
+
249
+ The child thread can also spawn other threads/workers.
250
+
251
+ #### Typescript and Javascript
252
+
253
+ ```ts
254
+ //worker
255
+ import { RPCServer } from "achi-rpc";
256
+ import { Rectangle } from "./classes";
257
+ import { fibonacci, readStream, sum } from "./fun";
258
+
259
+ const server = new RPCServer(self);
260
+ server.export([Rectangle, sum, readStream, fibonacci]);
261
+ ```
262
+
263
+ ## Shared worker
264
+
265
+ ```ts
266
+ //rpc client
267
+ const rpc = new RPC(sharedWorker.port);
268
+ //worker thread
269
+ declare const self: SharedWorkerGlobalScope;
270
+ self.addEventListener("connect", (event) => {
271
+ const port = event.ports[0];
272
+ const rpc = new RPCServer(port);
273
+ server.export([Rectangle, sum, readStream, fibonacci]);
274
+ });
275
+ ```
276
+
277
+ ## Iframes
278
+
279
+ Unlike a `Worker`, a `window` has no dedicated message channel of its own, and cross-origin `postMessage` calls require a `targetOrigin` so the browser only delivers the message to the origin you intend. Achi RPC exposes this as an extra, optional argument on every constructor.
280
+
281
+ **Parent page (embeds the iframe):**
282
+
283
+ ```ts
284
+ import { RPC, RPCInstance } from "achi-rpc";
285
+
286
+ // helper: resolve once the iframe has finished loading
287
+ function getIframe(url: string): Promise<Window> {
288
+ return new Promise((resolve) => {
289
+ const iframe = document.createElement("iframe");
290
+ iframe.src = url;
291
+ iframe.onload = () => resolve(iframe.contentWindow!);
292
+ document.body.appendChild(iframe);
293
+ });
294
+ }
295
+
296
+ // classes and functions — pass the iframe's window and the child's origin
297
+ const rpc = new RPC(await getIframe(url), "*");
298
+
299
+ // functions only
300
+ const rpcInstance = new RPCInstance(await getIframe(url), "*");
301
+ ```
302
+
303
+ **Iframe (child) page:**
304
+
305
+ ```ts
306
+ import { RPCServer, RPCInstanceServer } from "achi-rpc";
307
+
308
+ // classes and functions — pass window and the parent's origin
309
+ const server = new RPCServer(window, "*");
310
+ server.export([Rectangle, sum, fibonacci]);
311
+
312
+ // functions only
313
+ const instanceServer = new RPCInstanceServer(window, "*");
314
+ instanceServer.export([sum, fibonacci]);
315
+ ```
316
+
317
+ > **Security note:** `"*"` above matches any origin and is fine for local development, but it also means any page can send or read these messages. In production, replace it with the exact origin you expect on each side (e.g. `"https://app.example.com"`) rather than the wildcard.
318
+
319
+ ## Usage
320
+
321
+ Achi RPC can be used for both functions and classes using two different classes: `RPCInstance` and `RPC`.
322
+
323
+ - **Node.js** — use `worker_threads` and `parentPort` instead of `Worker` and `self` respectively.
324
+ - **Deno** and **Bun** — the standard `Worker`/`self` API works the same as in the browser; no changes needed.
325
+ - **Cloudflare Workers** — works over any transport that exposes a `postMessage`/`onmessage`-compatible interface, such as a Durable Object's WebSocket connection.
326
+ - **Shared workers** — use `SharedWorker.port` and `self.onconnect` → `event.ports[0]` instead of `Worker` and `self`.
327
+ - **iframes** — use `window` on both ends, and always pass a `targetOrigin` (see [Iframes](#iframes)).
328
+
329
+ Transferable objects are transferred by default, so you can pass them without explicitly listing them. Only use objects that support structured cloning or transferring, since every call passes through `postMessage`.
330
+
331
+ ## API
332
+
333
+ ### `Asyncify`
334
+
335
+ A TypeScript-only utility type that converts the types of exported functions and classes to their `async` equivalents, since every RPC call resolves asynchronously.
336
+
337
+ ### `export`
338
+
339
+ A method on `RPCServer`/`RPCInstanceServer` instances that exposes the given functions and/or classes to the calling side — the main thread, a parent window, or another worker.
340
+
341
+ ### `RPC`
342
+
343
+ A class used to create RPC instances that work for both classes and functions. Pairs with `RPCServer` on the other side.
344
+
345
+ ### `RPCInstance`
346
+
347
+ A class used to create RPC instances for functions only; it has no methods of its own. Pairs with `RPCInstanceServer` on the other side.
348
+
349
+ ### `RPCServer`
350
+
351
+ Runs on the callee side (a worker, iframe, or child thread) and exposes both classes and functions to whatever created it with `RPC`.
352
+
353
+ ### `RPCInstanceServer`
354
+
355
+ Runs on the callee side and exposes functions only to whatever created it with `RPCInstance`.
356
+
357
+ ### `getRPC`
358
+
359
+ A method of the `RPC` class used to get an RPC instance for functions.
360
+
361
+ ### `getConstructor`
362
+
363
+ A method of the `RPC` class used to get RPC constructors for exported classes.
364
+
365
+ ## How it works
366
+
367
+ - Transferable objects are detected and handled automatically.
368
+ - Function calls are sent over `postMessage`.
369
+ - Classes are backed by the Channel Messaging API, so each instance gets its own `MessagePort`.
370
+ - Every client is wrapped in a Proxy, so native methods (e.g. `.terminate()` on a `Worker`, `.close()` on a `MessagePort`) stay accessible. Avoid naming your own exported members the same as these native ones, since class instances always communicate through their `MessagePort`.
371
+
372
+ ## License
373
+
374
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,71 @@
1
+ import { MessagePort as MessagePort$1, Worker as Worker$1 } from "worker_threads";
2
+ //#region src/browser/function.browser.d.ts
3
+ declare class RPCInstance {
4
+ /**
5
+ * @param context {Worker | DedicatedWorkerGlobalScope | MessagePort | Window} used to setup an rpc client that calls functions
6
+ * @param targetOrigin {string} Required only if context is a Window or iframe
7
+ */
8
+ constructor(context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window, targetOrigin?: string);
9
+ }
10
+ declare class RPCInstanceServer {
11
+ protected customConstructors: Map<string, Function>;
12
+ protected context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window;
13
+ protected targetOrigin?: string;
14
+ /**
15
+ * @param context {Worker | DedicatedWorkerGlobalScope | MessagePort | Window} used to setup an rpc endpoint for functions
16
+ * @param targetOrigin {string} Required only if context is a Window or iframe
17
+ */
18
+ constructor(context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window, targetOrigin?: string);
19
+ /**
20
+ * Exports functions to the rpc client
21
+ * @param {Array<Function> | Function} constructors
22
+ */
23
+ export(constructors: Array<Function> | Function): void;
24
+ protected postMessage(context: Worker | DedicatedWorkerGlobalScope | MessagePort, CompletedTask: RPCResponse): void;
25
+ protected postMessageWindow(context: Window, CompletedTask: RPCResponse): void;
26
+ protected processPromise(CompletedTask: RPCResponse): Promise<RPCResponse>;
27
+ protected processTask(task: RPCRequest): RPCResponse;
28
+ protected queueTask(event: MessageEvent): Promise<void>;
29
+ protected queueTaskWindow(event: MessageEvent): Promise<void>;
30
+ }
31
+ //#endregion
32
+ //#region src/shared/shared.class.d.ts
33
+ declare class RPC {
34
+ rpc: RPCInstance;
35
+ targetOrigin?: string;
36
+ /**
37
+ * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions
38
+ * @param targetOrigin {string} Required only if context is a Window or iframe
39
+ */
40
+ constructor(context: Worker | DedicatedWorkerGlobalScope | Worker$1 | MessagePort, targetOrigin?: string);
41
+ /**
42
+ * returns an rpc client that calls functions
43
+ */
44
+ getRPC(): RPCInstance;
45
+ /**
46
+ * returns a class that is a proxy to the remote class
47
+ *
48
+ * @param {string | Function} customConstructor - the remote class or the name of the remote class
49
+ *
50
+ * @returns {new (...any: any) => ReturnType<any>}
51
+ */
52
+ getConstructor(customConstructor: string | Function): new (...any: any) => ReturnType<any>;
53
+ }
54
+ declare class RPCServer extends RPCInstanceServer {
55
+ isWindow: boolean;
56
+ /**
57
+ * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions
58
+ * @param targetOrigin {string} Required only if context is a Window or iframe
59
+ */
60
+ constructor(context: MessagePort | Worker | DedicatedWorkerGlobalScope | Worker$1 | MessagePort$1 | Window, targetOrigin?: string);
61
+ protected startRPCServer(requestId: number, port: MessagePort, customConstructor: string, args: any[]): Promise<void>;
62
+ protected processPortTask(port: MessagePort, task: RPCRequest, instance: Object): Promise<void>;
63
+ protected queueTask(event: MessageEvent & RPCRequest): Promise<void>;
64
+ protected queueTaskWindow(event: MessageEvent & RPCRequest): Promise<void>;
65
+ }
66
+ //#endregion
67
+ //#region src/asyncify.d.ts
68
+ type Asyncify<T> = T extends (new (...any: infer Args) => infer Return) ? new (...any: Args) => Promise<{ [K in keyof InstanceType<T>]: InstanceType<T>[K] extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : InstanceType<T>[K]; }> : T extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : T extends Object ? { [K in keyof T]: T[K] extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : T[K]; } : never;
69
+ //#endregion
70
+ export { type Asyncify, RPC, RPCInstance, RPCInstanceServer, RPCServer };
71
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,2 @@
1
+ var AchiRPC=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){return typeof e==`object`&&!!e&&typeof e.postMessage==`function`&&typeof e.start==`function`&&typeof e.close==`function`}function n(e){throw e}let r=new Set([`ArrayBuffer`,`MessagePort`,`ReadableStream`,`WritableStream`,`TransformStream`,`WebTransportReceiveStream`,`WebTransportSendStream`,`AudioData`,`ImageBitmap`,`VideoFrame`,`OffscreenCanvas`,`RTCDataChannel`,`MediaSourceHandle`,`MIDIAccess`,`MediaStreamTrack`,`FileHandle`]);function i(e){let t=[],n=[];for(t.push(e);t.length;){let e=t.shift();if(typeof e==`object`){if(!e)continue;let i=e.constructor.name;if(r.has(i)){n.push(e);continue}let a=Object.values(e);a.length&&t.push(...a)}}return n}function a(e){return typeof e==`object`&&!!e&&e.window===e}function o(e){"@babel/helpers - typeof";return o=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},o(e)}function s(e,t){if(o(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(o(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function c(e){var t=s(e,`string`);return o(t)==`symbol`?t:t+``}function l(e,t,n){return(t=c(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}let u=new Map,d=0;var f=class{constructor(e,r){if(e.addEventListener(`error`,n),e.addEventListener(`messageerror`,n),a(e)){if(r==null)throw Error(`target origin is required`);e.addEventListener(`message`,t);function t(e){(e.origin==r||r==`*`)&&m(e)}return new Proxy(e,{get(e,t){return(...n)=>{if(t!=`then`&&t!=`catch`&&typeof t==`string`)return e[t]==null?new Promise((a,o)=>{u.set(d,{resolve:a,reject:o});let s={requestId:d,args:n,property:t};try{e.postMessage(s,r,i(s.args)),d++}catch(e){u.delete(d),o(e)}}):e[t](...n)}}})}return e.addEventListener(`message`,m),t(e)&&e.start(),new Proxy(e,{get(e,t){if(t!=`then`&&t!=`catch`&&typeof t==`string`)return(...n)=>e[t]==null?new Promise((r,a)=>{u.set(d,{resolve:r,reject:a});let o={requestId:d,args:n,property:t};try{e.postMessage(o,i(o.args)),d++}catch(e){u.delete(d),a(e)}}):e[t](...n)}})}},p=class{constructor(e,r){if(l(this,`customConstructors`,void 0),l(this,`context`,void 0),l(this,`targetOrigin`,void 0),e.addEventListener(`error`,n),e.addEventListener(`messageerror`,n),this.customConstructors=new Map,this.context=e,a(this.context)){if(r==null)throw Error(`target origin is required`);this.targetOrigin=r,this.context.addEventListener(`message`,this.queueTaskWindow.bind(this))}else this.context.addEventListener(`message`,this.queueTask.bind(this)),t(this.context)&&this.context.start()}export(e){if(Array.isArray(e)){let t=e.length;for(;t--;)this.customConstructors.set(e[t].name,e[t])}else this.customConstructors.set(e.name,e)}postMessage(e,t){try{e.postMessage(t,i(t.value))}catch(n){t.value=n,t.isError=!0,e.postMessage(t,i(n))}}postMessageWindow(e,t){try{e.postMessage(t,this.targetOrigin,i(t.value))}catch(n){t.value=n,t.isError=!0,e.postMessage(t,this.targetOrigin,i(n))}}async processPromise(e){try{return e.value=await e.value,e}catch(t){return e.isError=!0,e.value=t,t instanceof Promise?this.processPromise(e):e}}processTask(e){let t=this.customConstructors.get(e.property);if(!t)return{requestId:e.requestId,isError:!0,value:Error(`${e.property} is not present in the rpc server`)};try{return{requestId:e.requestId,isError:!1,value:t(...e.args)}}catch(t){return{requestId:e.requestId,isError:!0,value:t}}}async queueTask(e){let t=e.data;if(t.property!=null){e.stopImmediatePropagation();let n=this.processTask(t);n.value instanceof Promise&&(n=await this.processPromise(n)),this.context=this.context,this.postMessage(this.context,n)}}async queueTaskWindow(e){if(e.origin==this.targetOrigin||this.targetOrigin==`*`){let t=e.data;if(t.property!=null){e.stopImmediatePropagation();let n=this.processTask(t);n.value instanceof Promise&&(n=await this.processPromise(n)),this.postMessageWindow(this.context,n)}}}};function m(e){let t=e.data;if(t.isError!=null){e.stopImmediatePropagation();let n=u.get(t.requestId);u.delete(t.requestId),t.isError?n.reject(t.value):n.resolve(t.value)}}let h=typeof FinalizationRegistry==`function`?new FinalizationRegistry(g):void 0;function g(e){e.onmessage=null,e.onmessageerror=null,e.postMessage({args:[],property:`close`,requestId:1}),e.close()}let _=new Map,v=0;var y=class{constructor(e,t){if(l(this,`rpc`,void 0),l(this,`targetOrigin`,void 0),a(e)){if(t==null)throw Error(`target origin is required`);this.targetOrigin=t,this.rpc=new f(e,t)}else this.rpc=new f(e)}getRPC(){return this.rpc}getConstructor(e){let t=class{},r=this.rpc;return typeof e==`function`&&(e=e.name),Object.defineProperty(t,"name",{value:e}),new Proxy(t,{async construct(e,t){let{port1:a,port2:o}=new MessageChannel;try{await r.startRPCServer(o,e.name,t)}catch(e){throw e}a.onmessage=x,a.onmessageerror=n,Object.defineProperty(a,"name",{value:e.name});let s=new Proxy(a,{get(e,n,r){if(n!=`then`&&n!=`catch`&&typeof n==`string`){if(e[n]){if(typeof e[n]==`function`){if(n==`close`){e.onmessage=null,e.onmessageerror=null;let i={args:t,property:n,requestId:1};e.postMessage(i),h?.unregister(r)}return(...t)=>{e[n](...t)}}return e[n]}return(...t)=>new Promise((r,a)=>{_.set(v,{resolve:r,reject:a});let o={requestId:v,property:n,args:t};try{e.postMessage(o,i(t)),v++}catch(e){_.delete(v),a(e)}})}}});return h?.register(s,a,s),s}})}},b=class extends p{constructor(e,t){var n=(...e)=>(super(...e),l(this,`isWindow`,!1),this);a(e)?(n(e,t),this.isWindow=!0):n(e)}async startRPCServer(e,t,r,i){let a=this.customConstructors.get(r),o=this.isWindow?this.postMessageWindow.bind(this):this.postMessage.bind(this);if(a)try{let r=new a(...i);t.onmessageerror=n,t.onmessage=e=>{if(e.data.property==`close`){t.onmessage=null,t.onmessageerror=null,r=null;return}this.processPortTask(t,e.data,r)};let s={requestId:e,value:void 0,isError:!1};o(this.context,s)}catch(t){let n={requestId:e,value:t,isError:!0};o(this.context,n)}else{let t={requestId:e,isError:!0,value:Error(`${r} is not present in the rpc server`)};o(this.context,t)}}async processPortTask(e,t,n){let r;try{r={requestId:t.requestId,value:n[t.property](...t.args),isError:!1}}catch(e){r={requestId:t.requestId,value:e,isError:!0}}r.value instanceof Promise&&(r=await this.processPromise(r)),this.postMessage(e,r)}async queueTask(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?this.startRPCServer(t.requestId,...t.args):super.queueTask(e)}}async queueTaskWindow(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?(this.targetOrigin==e.origin||this.targetOrigin==`*`)&&this.startRPCServer(t.requestId,...t.args):super.queueTaskWindow(e)}}};function x(e){let t=e.data;if(!t.isError!=null){e.stopImmediatePropagation();let n=_.get(t.requestId);_.delete(t.requestId),t.isError?n.reject(t.value):n.resolve(t.value)}}return e.RPC=y,e.RPCInstance=f,e.RPCInstanceServer=p,e.RPCServer=b,e})({});
2
+ //# sourceMappingURL=index.iife.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.iife.js","names":["ActiveTasks","requestId","PromisedTask"],"sources":["../../src/utilities/isMessagePort.ts","../../src/utilities/handleerror.ts","../../src/utilities/transferable.ts","../../src/utilities/isWindow.ts","../../src/browser/function.browser.ts","../../src/shared/gc.ts","../../src/shared/shared.class.ts"],"sourcesContent":["export function isMessagePort(target: unknown): target is MessagePort {\n return (\n typeof target === \"object\" &&\n target !== null &&\n typeof (target as MessagePort).postMessage === \"function\" &&\n typeof (target as MessagePort).start === \"function\" &&\n typeof (target as MessagePort).close === \"function\"\n );\n}","export function handleError(event:ErrorEvent|Event) {\n throw event;\n}","const transferableSet = new Set(['ArrayBuffer',\n 'MessagePort',\n 'ReadableStream',\n 'WritableStream',\n 'TransformStream',\n 'WebTransportReceiveStream',\n 'WebTransportSendStream',\n 'AudioData',\n 'ImageBitmap',\n 'VideoFrame',\n 'OffscreenCanvas',\n 'RTCDataChannel',\n 'MediaSourceHandle',\n 'MIDIAccess',\n 'MediaStreamTrack',\n 'FileHandle'])\nexport function transferableBFS(args:any[]):Transferable[] {\n const queue = [], transferable = [];\n queue.push(args)\n while (queue.length) {\n const value:any = queue.shift()\n if (typeof value == 'object') {\n if (!value) {\n continue\n }\n let constructor = value.constructor.name\n if (transferableSet.has(constructor)) {\n transferable.push(value)\n continue\n }\n let iterator = Object.values(value)\n if (iterator.length)\n queue.push(...iterator)\n }\n }\n return transferable\n}","export function isWindow(target: unknown): target is Window {\n return (\n typeof target === \"object\" &&\n target !== null &&\n (target as Window).window === target\n );\n}","import { isMessagePort } from \"../utilities/isMessagePort\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { isWindow } from \"../utilities/isWindow\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPCInstance {\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | MessagePort | Window} used to setup an rpc client that calls functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window,\n targetOrigin?: string,\n ) {\n context.addEventListener(\"error\", handleError);\n context.addEventListener(\"messageerror\", handleError);\n if (isWindow(context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n context.addEventListener(\"message\", PromisedTaskWindow as EventListener);\n function PromisedTaskWindow(event: MessageEvent) {\n if (event.origin == targetOrigin || targetOrigin == \"*\") {\n PromisedTask(event);\n }\n }\n return new Proxy(context, {\n get(target, property) {\n return (...args: any[]) => {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n if ((target as any)[property] != undefined) {\n return (target as any)[property](...args);\n }\n return new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n let task: RPCRequest = {\n requestId,\n args,\n property: property as string,\n };\n try {\n target.postMessage(\n task,\n targetOrigin,\n transferableBFS(task.args) as Transferable[],\n );\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n };\n },\n });\n } else {\n context.addEventListener(\"message\", PromisedTask as EventListener);\n if (isMessagePort(context)) {\n context.start();\n }\n return new Proxy(context, {\n get(\n target: Worker | DedicatedWorkerGlobalScope | MessagePort,\n property,\n ) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n return (...args: any[]) => {\n if ((target as any)[property] != undefined) {\n return (target as any)[property](...args);\n }\n return new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n let task: RPCRequest = {\n requestId,\n args,\n property: property as string,\n };\n try {\n target.postMessage(\n task,\n transferableBFS(task.args) as Transferable[],\n );\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n };\n },\n });\n }\n }\n}\n\nclass RPCInstanceServer {\n protected customConstructors: Map<string, Function>;\n protected context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window;\n protected targetOrigin?: string;\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | MessagePort | Window} used to setup an rpc endpoint for functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window,\n targetOrigin?: string,\n ) {\n context.addEventListener(\"error\", handleError);\n context.addEventListener(\"messageerror\", handleError);\n this.customConstructors = new Map();\n this.context = context;\n if (isWindow(this.context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n this.targetOrigin = targetOrigin;\n this.context.addEventListener(\n \"message\",\n this.queueTaskWindow.bind(this) as unknown as EventListener,\n );\n } else {\n this.context.addEventListener(\n \"message\",\n this.queueTask.bind(this) as unknown as EventListener,\n );\n if (isMessagePort(this.context)) {\n this.context.start();\n }\n }\n }\n\n /**\n * Exports functions to the rpc client\n * @param {Array<Function> | Function} constructors\n */\n public export(constructors: Array<Function> | Function) {\n if (Array.isArray(constructors)) {\n let index = constructors.length;\n while (index--) {\n this.customConstructors.set(\n constructors[index].name,\n constructors[index],\n );\n }\n } else {\n this.customConstructors.set(constructors.name, constructors);\n }\n }\n protected postMessage(\n context: Worker | DedicatedWorkerGlobalScope | MessagePort,\n CompletedTask: RPCResponse,\n ) {\n try {\n context.postMessage(\n CompletedTask,\n transferableBFS(CompletedTask.value) as Transferable[],\n );\n } catch (error: any) {\n CompletedTask.value = error;\n CompletedTask.isError = true;\n context.postMessage(\n CompletedTask,\n transferableBFS(error) as Transferable[],\n );\n }\n }\n protected postMessageWindow(context: Window, CompletedTask: RPCResponse) {\n try {\n context.postMessage(\n CompletedTask,\n this.targetOrigin as string,\n transferableBFS(CompletedTask.value) as Transferable[],\n );\n } catch (error: any) {\n CompletedTask.value = error;\n CompletedTask.isError = true;\n context.postMessage(\n CompletedTask,\n this.targetOrigin as string,\n transferableBFS(error) as Transferable[],\n );\n }\n }\n protected async processPromise(\n CompletedTask: RPCResponse,\n ): Promise<RPCResponse> {\n try {\n CompletedTask.value = await CompletedTask.value;\n return CompletedTask;\n } catch (error) {\n CompletedTask.isError = true;\n CompletedTask.value = error;\n if (error instanceof Promise) {\n return this.processPromise(CompletedTask);\n } else {\n return CompletedTask;\n }\n }\n }\n protected processTask(task: RPCRequest): RPCResponse {\n let userConstructor = this.customConstructors.get(task.property);\n if (!userConstructor) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: new Error(`${task.property} is not present in the rpc server`),\n };\n return CompletedTask;\n }\n try {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: false,\n value: userConstructor(...task.args),\n };\n return CompletedTask;\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: error,\n };\n return CompletedTask;\n }\n }\n protected async queueTask(event: MessageEvent) {\n let task: RPCRequest = event.data;\n if (task.property != undefined) {\n event.stopImmediatePropagation();\n let CompletedTask = this.processTask(task);\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.context = this.context as Exclude<typeof this.context, Window>;\n this.postMessage(this.context, CompletedTask);\n }\n }\n protected async queueTaskWindow(event: MessageEvent) {\n if (event.origin == this.targetOrigin || this.targetOrigin == \"*\") {\n let task: RPCRequest = event.data;\n if (task.property != undefined) {\n event.stopImmediatePropagation();\n let CompletedTask = this.processTask(task);\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessageWindow(this.context as Window, CompletedTask);\n }\n }\n }\n}\nfunction PromisedTask(event: MessageEvent) {\n let resolvedTask: RPCRequest & RPCResponse = event.data;\n if (resolvedTask.isError != undefined) {\n event.stopImmediatePropagation();\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPCInstance, RPCInstanceServer };\n","const objectRegistry: undefined | FinalizationRegistry<MessagePort> =\n typeof FinalizationRegistry == \"function\"\n ? new FinalizationRegistry(garbageCollector)\n : undefined;\n//clean up values for garbage collection\nfunction garbageCollector(port: MessagePort) {\n port.onmessage = null;\n port.onmessageerror = null;\n let task: RPCRequest = {\n args: [],\n property: \"close\",\n requestId: 1,\n };\n port.postMessage(task);\n port.close();\n}\nexport { objectRegistry };\n","import { RPCInstance, RPCInstanceServer } from \"@RPCInstance\";\nimport type {\n MessagePort as NodeMessagePort,\n Worker as NodeWorker,\n} from \"worker_threads\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { objectRegistry } from \"./gc\";\nimport { isWindow } from \"../utilities/isWindow\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPC {\n rpc: RPCInstance;\n targetOrigin?: string;\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n this.targetOrigin = targetOrigin;\n this.rpc = new RPCInstance(context as any, targetOrigin);\n } else {\n this.rpc = new RPCInstance(context as any);\n }\n }\n\n /**\n * returns an rpc client that calls functions\n */\n public getRPC() {\n return this.rpc;\n }\n\n /**\n * returns a class that is a proxy to the remote class\n *\n * @param {string | Function} customConstructor - the remote class or the name of the remote class\n *\n * @returns {new (...any: any) => ReturnType<any>}\n */\n public getConstructor(\n customConstructor: string | Function,\n ): new (...any: any) => ReturnType<any> {\n let constructor = class {},\n rpc = this.rpc;\n if (typeof customConstructor == \"function\") {\n customConstructor = customConstructor.name;\n }\n Object.defineProperty(constructor, \"name\", { value: customConstructor });\n return new Proxy(constructor, {\n async construct(target, args) {\n const { port1, port2 } = new MessageChannel();\n try {\n await (rpc as any).startRPCServer(port2, target.name, args);\n } catch (error) {\n throw error;\n }\n port1.onmessage = PromisedTask;\n port1.onmessageerror = handleError;\n Object.defineProperty(port1, \"name\", { value: target.name });\n const prox = new Proxy(port1, {\n get(target, property, receiver) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n if ((target as any)[property]) {\n if (typeof (target as any)[property] == \"function\") {\n if (property == \"close\") {\n target.onmessage = null;\n target.onmessageerror = null;\n let task: RPCRequest = {\n args,\n property,\n requestId: 1,\n };\n target.postMessage(task);\n objectRegistry?.unregister(receiver);\n }\n return (...args: any[]) => {\n (target as any)[property](...args);\n };\n } else {\n return (target as any)[property];\n }\n }\n return (...args: any[]) =>\n new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n const task: RPCRequest = {\n requestId,\n property: property as string,\n args,\n };\n try {\n target.postMessage(task, transferableBFS(args));\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n },\n });\n objectRegistry?.register(prox, port1, prox);\n return prox;\n },\n });\n }\n}\n\nclass RPCServer extends RPCInstanceServer {\n isWindow: boolean = false;\n /**\n * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context:\n | MessagePort\n | Worker\n | DedicatedWorkerGlobalScope\n | NodeWorker\n | NodeMessagePort\n | Window,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n super(context, targetOrigin);\n this.isWindow = true;\n } else {\n super(context as any);\n }\n }\n protected async startRPCServer(\n requestId: number,\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ) {\n const constructor = this.customConstructors.get(\n customConstructor,\n ) as FunctionConstructor;\n const postMessage = this.isWindow\n ? this.postMessageWindow.bind(this)\n : this.postMessage.bind(this);\n if (!constructor) {\n let CompletedTask: RPCResponse = {\n requestId: requestId,\n isError: true,\n value: new Error(\n `${customConstructor} is not present in the rpc server`,\n ),\n };\n postMessage(this.context as any, CompletedTask);\n } else {\n try {\n let instance = new constructor(...args);\n port.onmessageerror = handleError;\n port.onmessage = (event) => {\n if (event.data.property == \"close\") {\n port.onmessage = null;\n port.onmessageerror = null;\n instance = null as any;\n return;\n }\n this.processPortTask(port, event.data, instance);\n };\n let CompletedTask: RPCResponse = {\n requestId,\n value: undefined,\n isError: false,\n };\n postMessage(this.context as any, CompletedTask);\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId,\n value: error,\n isError: true,\n };\n postMessage(this.context as any, CompletedTask);\n }\n }\n }\n protected async processPortTask(\n port: MessagePort,\n task: RPCRequest,\n instance: Object,\n ) {\n let CompletedTask: RPCResponse;\n try {\n CompletedTask = {\n requestId: task.requestId,\n value: (instance as any)[task.property](...task.args),\n isError: false,\n };\n } catch (error) {\n CompletedTask = {\n requestId: task.requestId,\n value: error,\n isError: true,\n };\n }\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessage(port, CompletedTask);\n }\n protected async queueTask(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n } else {\n super.queueTask(event);\n }\n }\n }\n protected async queueTaskWindow(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n if (this.targetOrigin == event.origin || this.targetOrigin == \"*\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n }\n } else {\n super.queueTaskWindow(event);\n }\n }\n }\n}\nfunction PromisedTask(event: MessageEvent) {\n let resolvedTask: RPCRequest & RPCResponse = event.data;\n if (!resolvedTask.isError != undefined) {\n event.stopImmediatePropagation();\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPC, RPCServer };\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ function e(e){return typeof e==`object`&&!!e&&typeof e.postMessage==`function`&&typeof e.start==`function`&&typeof e.close==`function`}function t(e){throw e}const n=new Set([`ArrayBuffer`,`MessagePort`,`ReadableStream`,`WritableStream`,`TransformStream`,`WebTransportReceiveStream`,`WebTransportSendStream`,`AudioData`,`ImageBitmap`,`VideoFrame`,`OffscreenCanvas`,`RTCDataChannel`,`MediaSourceHandle`,`MIDIAccess`,`MediaStreamTrack`,`FileHandle`]);function r(e){let t=[],r=[];for(t.push(e);t.length;){let e=t.shift();if(typeof e==`object`){if(!e)continue;let i=e.constructor.name;if(n.has(i)){r.push(e);continue}let a=Object.values(e);a.length&&t.push(...a)}}return r}function i(e){return typeof e==`object`&&!!e&&e.window===e}function a(e){"@babel/helpers - typeof";return a=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},a(e)}function o(e,t){if(a(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(a(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function s(e){var t=o(e,`string`);return a(t)==`symbol`?t:t+``}function c(e,t,n){return(t=s(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}const l=new Map;let u=0;var d=class{constructor(n,a){if(n.addEventListener(`error`,t),n.addEventListener(`messageerror`,t),i(n)){if(a==null)throw Error(`target origin is required`);n.addEventListener(`message`,e);function e(e){(e.origin==a||a==`*`)&&p(e)}return new Proxy(n,{get(e,t){return(...n)=>{if(t!=`then`&&t!=`catch`&&typeof t==`string`)return e[t]==null?new Promise((i,o)=>{l.set(u,{resolve:i,reject:o});let s={requestId:u,args:n,property:t};try{e.postMessage(s,a,r(s.args)),u++}catch(e){l.delete(u),o(e)}}):e[t](...n)}}})}return n.addEventListener(`message`,p),e(n)&&n.start(),new Proxy(n,{get(e,t){if(t!=`then`&&t!=`catch`&&typeof t==`string`)return(...n)=>e[t]==null?new Promise((i,a)=>{l.set(u,{resolve:i,reject:a});let o={requestId:u,args:n,property:t};try{e.postMessage(o,r(o.args)),u++}catch(e){l.delete(u),a(e)}}):e[t](...n)}})}},f=class{constructor(n,r){if(c(this,`customConstructors`,void 0),c(this,`context`,void 0),c(this,`targetOrigin`,void 0),n.addEventListener(`error`,t),n.addEventListener(`messageerror`,t),this.customConstructors=new Map,this.context=n,i(this.context)){if(r==null)throw Error(`target origin is required`);this.targetOrigin=r,this.context.addEventListener(`message`,this.queueTaskWindow.bind(this))}else this.context.addEventListener(`message`,this.queueTask.bind(this)),e(this.context)&&this.context.start()}export(e){if(Array.isArray(e)){let t=e.length;for(;t--;)this.customConstructors.set(e[t].name,e[t])}else this.customConstructors.set(e.name,e)}postMessage(e,t){try{e.postMessage(t,r(t.value))}catch(n){t.value=n,t.isError=!0,e.postMessage(t,r(n))}}postMessageWindow(e,t){try{e.postMessage(t,this.targetOrigin,r(t.value))}catch(n){t.value=n,t.isError=!0,e.postMessage(t,this.targetOrigin,r(n))}}async processPromise(e){try{return e.value=await e.value,e}catch(t){return e.isError=!0,e.value=t,t instanceof Promise?this.processPromise(e):e}}processTask(e){let t=this.customConstructors.get(e.property);if(!t)return{requestId:e.requestId,isError:!0,value:Error(`${e.property} is not present in the rpc server`)};try{return{requestId:e.requestId,isError:!1,value:t(...e.args)}}catch(t){return{requestId:e.requestId,isError:!0,value:t}}}async queueTask(e){let t=e.data;if(t.property!=null){e.stopImmediatePropagation();let n=this.processTask(t);n.value instanceof Promise&&(n=await this.processPromise(n)),this.context=this.context,this.postMessage(this.context,n)}}async queueTaskWindow(e){if(e.origin==this.targetOrigin||this.targetOrigin==`*`){let t=e.data;if(t.property!=null){e.stopImmediatePropagation();let n=this.processTask(t);n.value instanceof Promise&&(n=await this.processPromise(n)),this.postMessageWindow(this.context,n)}}}};function p(e){let t=e.data;if(t.isError!=null){e.stopImmediatePropagation();let n=l.get(t.requestId);l.delete(t.requestId),t.isError?n.reject(t.value):n.resolve(t.value)}}const m=typeof FinalizationRegistry==`function`?new FinalizationRegistry(h):void 0;function h(e){e.onmessage=null,e.onmessageerror=null,e.postMessage({args:[],property:`close`,requestId:1}),e.close()}const g=new Map;let _=0;var v=class{constructor(e,t){if(c(this,`rpc`,void 0),c(this,`targetOrigin`,void 0),i(e)){if(t==null)throw Error(`target origin is required`);this.targetOrigin=t,this.rpc=new d(e,t)}else this.rpc=new d(e)}getRPC(){return this.rpc}getConstructor(e){let n=class{},i=this.rpc;return typeof e==`function`&&(e=e.name),Object.defineProperty(n,"name",{value:e}),new Proxy(n,{async construct(e,n){let{port1:a,port2:o}=new MessageChannel;try{await i.startRPCServer(o,e.name,n)}catch(e){throw e}a.onmessage=b,a.onmessageerror=t,Object.defineProperty(a,"name",{value:e.name});let s=new Proxy(a,{get(e,t,i){if(t!=`then`&&t!=`catch`&&typeof t==`string`){if(e[t]){if(typeof e[t]==`function`){if(t==`close`){e.onmessage=null,e.onmessageerror=null;let r={args:n,property:t,requestId:1};e.postMessage(r),m?.unregister(i)}return(...n)=>{e[t](...n)}}return e[t]}return(...n)=>new Promise((i,a)=>{g.set(_,{resolve:i,reject:a});let o={requestId:_,property:t,args:n};try{e.postMessage(o,r(n)),_++}catch(e){g.delete(_),a(e)}})}}});return m?.register(s,a,s),s}})}},y=class extends f{constructor(e,t){var n=(...e)=>(super(...e),c(this,`isWindow`,!1),this);i(e)?(n(e,t),this.isWindow=!0):n(e)}async startRPCServer(e,n,r,i){let a=this.customConstructors.get(r),o=this.isWindow?this.postMessageWindow.bind(this):this.postMessage.bind(this);if(a)try{let r=new a(...i);n.onmessageerror=t,n.onmessage=e=>{if(e.data.property==`close`){n.onmessage=null,n.onmessageerror=null,r=null;return}this.processPortTask(n,e.data,r)};let s={requestId:e,value:void 0,isError:!1};o(this.context,s)}catch(t){let n={requestId:e,value:t,isError:!0};o(this.context,n)}else{let t={requestId:e,isError:!0,value:Error(`${r} is not present in the rpc server`)};o(this.context,t)}}async processPortTask(e,t,n){let r;try{r={requestId:t.requestId,value:n[t.property](...t.args),isError:!1}}catch(e){r={requestId:t.requestId,value:e,isError:!0}}r.value instanceof Promise&&(r=await this.processPromise(r)),this.postMessage(e,r)}async queueTask(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?this.startRPCServer(t.requestId,...t.args):super.queueTask(e)}}async queueTaskWindow(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?(this.targetOrigin==e.origin||this.targetOrigin==`*`)&&this.startRPCServer(t.requestId,...t.args):super.queueTaskWindow(e)}}};function b(e){let t=e.data;if(!t.isError!=null){e.stopImmediatePropagation();let n=g.get(t.requestId);g.delete(t.requestId),t.isError?n.reject(t.value):n.resolve(t.value)}}export{v as RPC,d as RPCInstance,f as RPCInstanceServer,y as RPCServer};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["ActiveTasks","requestId","PromisedTask"],"sources":["../../src/utilities/isMessagePort.ts","../../src/utilities/handleerror.ts","../../src/utilities/transferable.ts","../../src/utilities/isWindow.ts","../../src/browser/function.browser.ts","../../src/shared/gc.ts","../../src/shared/shared.class.ts"],"sourcesContent":["export function isMessagePort(target: unknown): target is MessagePort {\n return (\n typeof target === \"object\" &&\n target !== null &&\n typeof (target as MessagePort).postMessage === \"function\" &&\n typeof (target as MessagePort).start === \"function\" &&\n typeof (target as MessagePort).close === \"function\"\n );\n}","export function handleError(event:ErrorEvent|Event) {\n throw event;\n}","const transferableSet = new Set(['ArrayBuffer',\n 'MessagePort',\n 'ReadableStream',\n 'WritableStream',\n 'TransformStream',\n 'WebTransportReceiveStream',\n 'WebTransportSendStream',\n 'AudioData',\n 'ImageBitmap',\n 'VideoFrame',\n 'OffscreenCanvas',\n 'RTCDataChannel',\n 'MediaSourceHandle',\n 'MIDIAccess',\n 'MediaStreamTrack',\n 'FileHandle'])\nexport function transferableBFS(args:any[]):Transferable[] {\n const queue = [], transferable = [];\n queue.push(args)\n while (queue.length) {\n const value:any = queue.shift()\n if (typeof value == 'object') {\n if (!value) {\n continue\n }\n let constructor = value.constructor.name\n if (transferableSet.has(constructor)) {\n transferable.push(value)\n continue\n }\n let iterator = Object.values(value)\n if (iterator.length)\n queue.push(...iterator)\n }\n }\n return transferable\n}","export function isWindow(target: unknown): target is Window {\n return (\n typeof target === \"object\" &&\n target !== null &&\n (target as Window).window === target\n );\n}","import { isMessagePort } from \"../utilities/isMessagePort\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { isWindow } from \"../utilities/isWindow\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPCInstance {\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | MessagePort | Window} used to setup an rpc client that calls functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window,\n targetOrigin?: string,\n ) {\n context.addEventListener(\"error\", handleError);\n context.addEventListener(\"messageerror\", handleError);\n if (isWindow(context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n context.addEventListener(\"message\", PromisedTaskWindow as EventListener);\n function PromisedTaskWindow(event: MessageEvent) {\n if (event.origin == targetOrigin || targetOrigin == \"*\") {\n PromisedTask(event);\n }\n }\n return new Proxy(context, {\n get(target, property) {\n return (...args: any[]) => {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n if ((target as any)[property] != undefined) {\n return (target as any)[property](...args);\n }\n return new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n let task: RPCRequest = {\n requestId,\n args,\n property: property as string,\n };\n try {\n target.postMessage(\n task,\n targetOrigin,\n transferableBFS(task.args) as Transferable[],\n );\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n };\n },\n });\n } else {\n context.addEventListener(\"message\", PromisedTask as EventListener);\n if (isMessagePort(context)) {\n context.start();\n }\n return new Proxy(context, {\n get(\n target: Worker | DedicatedWorkerGlobalScope | MessagePort,\n property,\n ) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n return (...args: any[]) => {\n if ((target as any)[property] != undefined) {\n return (target as any)[property](...args);\n }\n return new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n let task: RPCRequest = {\n requestId,\n args,\n property: property as string,\n };\n try {\n target.postMessage(\n task,\n transferableBFS(task.args) as Transferable[],\n );\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n };\n },\n });\n }\n }\n}\n\nclass RPCInstanceServer {\n protected customConstructors: Map<string, Function>;\n protected context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window;\n protected targetOrigin?: string;\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | MessagePort | Window} used to setup an rpc endpoint for functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | MessagePort | Window,\n targetOrigin?: string,\n ) {\n context.addEventListener(\"error\", handleError);\n context.addEventListener(\"messageerror\", handleError);\n this.customConstructors = new Map();\n this.context = context;\n if (isWindow(this.context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n this.targetOrigin = targetOrigin;\n this.context.addEventListener(\n \"message\",\n this.queueTaskWindow.bind(this) as unknown as EventListener,\n );\n } else {\n this.context.addEventListener(\n \"message\",\n this.queueTask.bind(this) as unknown as EventListener,\n );\n if (isMessagePort(this.context)) {\n this.context.start();\n }\n }\n }\n\n /**\n * Exports functions to the rpc client\n * @param {Array<Function> | Function} constructors\n */\n public export(constructors: Array<Function> | Function) {\n if (Array.isArray(constructors)) {\n let index = constructors.length;\n while (index--) {\n this.customConstructors.set(\n constructors[index].name,\n constructors[index],\n );\n }\n } else {\n this.customConstructors.set(constructors.name, constructors);\n }\n }\n protected postMessage(\n context: Worker | DedicatedWorkerGlobalScope | MessagePort,\n CompletedTask: RPCResponse,\n ) {\n try {\n context.postMessage(\n CompletedTask,\n transferableBFS(CompletedTask.value) as Transferable[],\n );\n } catch (error: any) {\n CompletedTask.value = error;\n CompletedTask.isError = true;\n context.postMessage(\n CompletedTask,\n transferableBFS(error) as Transferable[],\n );\n }\n }\n protected postMessageWindow(context: Window, CompletedTask: RPCResponse) {\n try {\n context.postMessage(\n CompletedTask,\n this.targetOrigin as string,\n transferableBFS(CompletedTask.value) as Transferable[],\n );\n } catch (error: any) {\n CompletedTask.value = error;\n CompletedTask.isError = true;\n context.postMessage(\n CompletedTask,\n this.targetOrigin as string,\n transferableBFS(error) as Transferable[],\n );\n }\n }\n protected async processPromise(\n CompletedTask: RPCResponse,\n ): Promise<RPCResponse> {\n try {\n CompletedTask.value = await CompletedTask.value;\n return CompletedTask;\n } catch (error) {\n CompletedTask.isError = true;\n CompletedTask.value = error;\n if (error instanceof Promise) {\n return this.processPromise(CompletedTask);\n } else {\n return CompletedTask;\n }\n }\n }\n protected processTask(task: RPCRequest): RPCResponse {\n let userConstructor = this.customConstructors.get(task.property);\n if (!userConstructor) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: new Error(`${task.property} is not present in the rpc server`),\n };\n return CompletedTask;\n }\n try {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: false,\n value: userConstructor(...task.args),\n };\n return CompletedTask;\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: error,\n };\n return CompletedTask;\n }\n }\n protected async queueTask(event: MessageEvent) {\n let task: RPCRequest = event.data;\n if (task.property != undefined) {\n event.stopImmediatePropagation();\n let CompletedTask = this.processTask(task);\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.context = this.context as Exclude<typeof this.context, Window>;\n this.postMessage(this.context, CompletedTask);\n }\n }\n protected async queueTaskWindow(event: MessageEvent) {\n if (event.origin == this.targetOrigin || this.targetOrigin == \"*\") {\n let task: RPCRequest = event.data;\n if (task.property != undefined) {\n event.stopImmediatePropagation();\n let CompletedTask = this.processTask(task);\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessageWindow(this.context as Window, CompletedTask);\n }\n }\n }\n}\nfunction PromisedTask(event: MessageEvent) {\n let resolvedTask: RPCRequest & RPCResponse = event.data;\n if (resolvedTask.isError != undefined) {\n event.stopImmediatePropagation();\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPCInstance, RPCInstanceServer };\n","const objectRegistry: undefined | FinalizationRegistry<MessagePort> =\n typeof FinalizationRegistry == \"function\"\n ? new FinalizationRegistry(garbageCollector)\n : undefined;\n//clean up values for garbage collection\nfunction garbageCollector(port: MessagePort) {\n port.onmessage = null;\n port.onmessageerror = null;\n let task: RPCRequest = {\n args: [],\n property: \"close\",\n requestId: 1,\n };\n port.postMessage(task);\n port.close();\n}\nexport { objectRegistry };\n","import { RPCInstance, RPCInstanceServer } from \"@RPCInstance\";\nimport type {\n MessagePort as NodeMessagePort,\n Worker as NodeWorker,\n} from \"worker_threads\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { objectRegistry } from \"./gc\";\nimport { isWindow } from \"../utilities/isWindow\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPC {\n rpc: RPCInstance;\n targetOrigin?: string;\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n this.targetOrigin = targetOrigin;\n this.rpc = new RPCInstance(context as any, targetOrigin);\n } else {\n this.rpc = new RPCInstance(context as any);\n }\n }\n\n /**\n * returns an rpc client that calls functions\n */\n public getRPC() {\n return this.rpc;\n }\n\n /**\n * returns a class that is a proxy to the remote class\n *\n * @param {string | Function} customConstructor - the remote class or the name of the remote class\n *\n * @returns {new (...any: any) => ReturnType<any>}\n */\n public getConstructor(\n customConstructor: string | Function,\n ): new (...any: any) => ReturnType<any> {\n let constructor = class {},\n rpc = this.rpc;\n if (typeof customConstructor == \"function\") {\n customConstructor = customConstructor.name;\n }\n Object.defineProperty(constructor, \"name\", { value: customConstructor });\n return new Proxy(constructor, {\n async construct(target, args) {\n const { port1, port2 } = new MessageChannel();\n try {\n await (rpc as any).startRPCServer(port2, target.name, args);\n } catch (error) {\n throw error;\n }\n port1.onmessage = PromisedTask;\n port1.onmessageerror = handleError;\n Object.defineProperty(port1, \"name\", { value: target.name });\n const prox = new Proxy(port1, {\n get(target, property, receiver) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n if ((target as any)[property]) {\n if (typeof (target as any)[property] == \"function\") {\n if (property == \"close\") {\n target.onmessage = null;\n target.onmessageerror = null;\n let task: RPCRequest = {\n args,\n property,\n requestId: 1,\n };\n target.postMessage(task);\n objectRegistry?.unregister(receiver);\n }\n return (...args: any[]) => {\n (target as any)[property](...args);\n };\n } else {\n return (target as any)[property];\n }\n }\n return (...args: any[]) =>\n new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n const task: RPCRequest = {\n requestId,\n property: property as string,\n args,\n };\n try {\n target.postMessage(task, transferableBFS(args));\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n },\n });\n objectRegistry?.register(prox, port1, prox);\n return prox;\n },\n });\n }\n}\n\nclass RPCServer extends RPCInstanceServer {\n isWindow: boolean = false;\n /**\n * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context:\n | MessagePort\n | Worker\n | DedicatedWorkerGlobalScope\n | NodeWorker\n | NodeMessagePort\n | Window,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n super(context, targetOrigin);\n this.isWindow = true;\n } else {\n super(context as any);\n }\n }\n protected async startRPCServer(\n requestId: number,\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ) {\n const constructor = this.customConstructors.get(\n customConstructor,\n ) as FunctionConstructor;\n const postMessage = this.isWindow\n ? this.postMessageWindow.bind(this)\n : this.postMessage.bind(this);\n if (!constructor) {\n let CompletedTask: RPCResponse = {\n requestId: requestId,\n isError: true,\n value: new Error(\n `${customConstructor} is not present in the rpc server`,\n ),\n };\n postMessage(this.context as any, CompletedTask);\n } else {\n try {\n let instance = new constructor(...args);\n port.onmessageerror = handleError;\n port.onmessage = (event) => {\n if (event.data.property == \"close\") {\n port.onmessage = null;\n port.onmessageerror = null;\n instance = null as any;\n return;\n }\n this.processPortTask(port, event.data, instance);\n };\n let CompletedTask: RPCResponse = {\n requestId,\n value: undefined,\n isError: false,\n };\n postMessage(this.context as any, CompletedTask);\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId,\n value: error,\n isError: true,\n };\n postMessage(this.context as any, CompletedTask);\n }\n }\n }\n protected async processPortTask(\n port: MessagePort,\n task: RPCRequest,\n instance: Object,\n ) {\n let CompletedTask: RPCResponse;\n try {\n CompletedTask = {\n requestId: task.requestId,\n value: (instance as any)[task.property](...task.args),\n isError: false,\n };\n } catch (error) {\n CompletedTask = {\n requestId: task.requestId,\n value: error,\n isError: true,\n };\n }\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessage(port, CompletedTask);\n }\n protected async queueTask(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n } else {\n super.queueTask(event);\n }\n }\n }\n protected async queueTaskWindow(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n if (this.targetOrigin == event.origin || this.targetOrigin == \"*\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n }\n } else {\n super.queueTaskWindow(event);\n }\n }\n }\n}\nfunction PromisedTask(event: MessageEvent) {\n let resolvedTask: RPCRequest & RPCResponse = event.data;\n if (!resolvedTask.isError != undefined) {\n event.stopImmediatePropagation();\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPC, RPCServer };\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){throw e}const t=new Set([`ArrayBuffer`,`MessagePort`,`ReadableStream`,`WritableStream`,`TransformStream`,`WebTransportReceiveStream`,`WebTransportSendStream`,`AudioData`,`ImageBitmap`,`VideoFrame`,`OffscreenCanvas`,`RTCDataChannel`,`MediaSourceHandle`,`MIDIAccess`,`MediaStreamTrack`,`FileHandle`]);function n(e){let n=[],r=[];for(n.push(e);n.length;){let e=n.shift();if(typeof e==`object`){if(!e)continue;let i=e.constructor.name;if(t.has(i)){r.push(e);continue}let a=Object.values(e);a.length&&n.push(...a)}}return r}function r(e){return typeof e==`object`&&!!e&&typeof e.postMessage==`function`&&typeof e.start==`function`&&typeof e.close==`function`}const i=new Map;let a=0;var o=class{constructor(t){return t.addListener(`error`,e),t.addListener(`messageerror`,e),t.addListener(`exit`,e),t.addListener(`message`,c),new Proxy(t,{get(e,t){if(t!=`then`&&t!=`catch`&&typeof t==`string`)return(...r)=>e[t]==null?new Promise((o,s)=>{i.set(a,{resolve:o,reject:s});let c={requestId:a,args:r,property:t};try{e.postMessage(c,n(r)),a++}catch(e){i.delete(a),s(e)}}):e[t](...r)}})}},s=class{customConstructors;context;constructor(t){t.addListener(`error`,e),t.addListener(`messageerror`,e),this.customConstructors=new Map,this.context=t,this.context.addListener(`message`,this.queueTask.bind(this)),r(this.context)&&this.context.start()}export(e){if(Array.isArray(e)){let t=e.length;for(;t--;)this.customConstructors.set(e[t].name,e[t])}else this.customConstructors.set(e.name,e)}postMessage(e,t){try{e.postMessage(t,n(t.value))}catch(r){t.value=r,t.isError=!0,e.postMessage(t,n(r))}}async processPromise(e){try{return e.value=await e.value,e}catch(t){return e.isError=!0,e.value=t,t instanceof Promise?this.processPromise(e):e}}processTask(e){let t=this.customConstructors.get(e.property);if(!t)return{requestId:e.requestId,isError:!0,value:Error(`${e.property} is not present in the rpc server`)};try{return{requestId:e.requestId,isError:!1,value:t(...e.args)}}catch(t){return{requestId:e.requestId,isError:!0,value:t}}}async queueTask(e){let t=e;if(t.property!=null){let e=this.processTask(t);e.value instanceof Promise&&(e=await this.processPromise(e)),this.postMessage(this.context,e)}}};function c(e){if(e&&typeof e==`object`&&`watch:import`in e)return;let t=e;if(t.isError!=null){let e=i.get(t.requestId);i.delete(t.requestId),t.isError?e.reject(t.value):e.resolve(t.value)}}const l=typeof FinalizationRegistry==`function`?new FinalizationRegistry(u):void 0;function u(e){e.onmessage=null,e.onmessageerror=null,e.postMessage({args:[],property:`close`,requestId:1}),e.close()}function d(e){return typeof e==`object`&&!!e&&e.window===e}const f=new Map;let p=0;var m=class{rpc;targetOrigin;constructor(e,t){if(d(e)){if(t==null)throw Error(`target origin is required`);this.targetOrigin=t,this.rpc=new o(e,t)}else this.rpc=new o(e)}getRPC(){return this.rpc}getConstructor(t){let r=class{},i=this.rpc;return typeof t==`function`&&(t=t.name),Object.defineProperty(r,"name",{value:t}),new Proxy(r,{async construct(t,r){let{port1:a,port2:o}=new MessageChannel;try{await i.startRPCServer(o,t.name,r)}catch(e){throw e}a.onmessage=g,a.onmessageerror=e,Object.defineProperty(a,"name",{value:t.name});let s=new Proxy(a,{get(e,t,i){if(t!=`then`&&t!=`catch`&&typeof t==`string`){if(e[t]){if(typeof e[t]==`function`){if(t==`close`){e.onmessage=null,e.onmessageerror=null;let n={args:r,property:t,requestId:1};e.postMessage(n),l?.unregister(i)}return(...n)=>{e[t](...n)}}return e[t]}return(...r)=>new Promise((i,a)=>{f.set(p,{resolve:i,reject:a});let o={requestId:p,property:t,args:r};try{e.postMessage(o,n(r)),p++}catch(e){f.delete(p),a(e)}})}}});return l?.register(s,a,s),s}})}},h=class extends s{isWindow=!1;constructor(e,t){d(e)?(super(e,t),this.isWindow=!0):super(e)}async startRPCServer(t,n,r,i){let a=this.customConstructors.get(r),o=this.isWindow?this.postMessageWindow.bind(this):this.postMessage.bind(this);if(a)try{let r=new a(...i);n.onmessageerror=e,n.onmessage=e=>{if(e.data.property==`close`){n.onmessage=null,n.onmessageerror=null,r=null;return}this.processPortTask(n,e.data,r)};let s={requestId:t,value:void 0,isError:!1};o(this.context,s)}catch(e){let n={requestId:t,value:e,isError:!0};o(this.context,n)}else{let e={requestId:t,isError:!0,value:Error(`${r} is not present in the rpc server`)};o(this.context,e)}}async processPortTask(e,t,n){let r;try{r={requestId:t.requestId,value:n[t.property](...t.args),isError:!1}}catch(e){r={requestId:t.requestId,value:e,isError:!0}}r.value instanceof Promise&&(r=await this.processPromise(r)),this.postMessage(e,r)}async queueTask(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?this.startRPCServer(t.requestId,...t.args):super.queueTask(e)}}async queueTaskWindow(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?(this.targetOrigin==e.origin||this.targetOrigin==`*`)&&this.startRPCServer(t.requestId,...t.args):super.queueTaskWindow(e)}}};function g(e){let t=e.data;if(!t.isError!=null){e.stopImmediatePropagation();let n=f.get(t.requestId);f.delete(t.requestId),t.isError?n.reject(t.value):n.resolve(t.value)}}exports.RPC=m,exports.RPCInstance=o,exports.RPCInstanceServer=s,exports.RPCServer=h;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["ActiveTasks","requestId","PromisedTask"],"sources":["../../src/utilities/handleerror.ts","../../src/utilities/transferable.ts","../../src/utilities/isMessagePort.ts","../../src/node/function.node.ts","../../src/shared/gc.ts","../../src/utilities/isWindow.ts","../../src/shared/shared.class.ts"],"sourcesContent":["export function handleError(event:ErrorEvent|Event) {\n throw event;\n}","const transferableSet = new Set(['ArrayBuffer',\n 'MessagePort',\n 'ReadableStream',\n 'WritableStream',\n 'TransformStream',\n 'WebTransportReceiveStream',\n 'WebTransportSendStream',\n 'AudioData',\n 'ImageBitmap',\n 'VideoFrame',\n 'OffscreenCanvas',\n 'RTCDataChannel',\n 'MediaSourceHandle',\n 'MIDIAccess',\n 'MediaStreamTrack',\n 'FileHandle'])\nexport function transferableBFS(args:any[]):Transferable[] {\n const queue = [], transferable = [];\n queue.push(args)\n while (queue.length) {\n const value:any = queue.shift()\n if (typeof value == 'object') {\n if (!value) {\n continue\n }\n let constructor = value.constructor.name\n if (transferableSet.has(constructor)) {\n transferable.push(value)\n continue\n }\n let iterator = Object.values(value)\n if (iterator.length)\n queue.push(...iterator)\n }\n }\n return transferable\n}","export function isMessagePort(target: unknown): target is MessagePort {\n return (\n typeof target === \"object\" &&\n target !== null &&\n typeof (target as MessagePort).postMessage === \"function\" &&\n typeof (target as MessagePort).start === \"function\" &&\n typeof (target as MessagePort).close === \"function\"\n );\n}","import type { MessagePort, Transferable, Worker } from \"node:worker_threads\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { isMessagePort } from \"../utilities/isMessagePort\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPCInstance {\n /**\n * @param context {MessagePort | Worker} used to setup an rpc client that calls functions\n */\n constructor(context: MessagePort | Worker) {\n context.addListener(\"error\", handleError);\n context.addListener(\"messageerror\", handleError);\n context.addListener(\"exit\", handleError);\n context.addListener(\"message\", PromisedTask);\n return new Proxy(context, {\n get(target, property) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n return (...args: any[]) => {\n if ((target as any)[property] != undefined) {\n return (target as any)[property](...args);\n }\n return new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n let task: RPCRequest = {\n requestId,\n args,\n property: property as string,\n };\n try {\n target.postMessage(task, transferableBFS(args) as Transferable[]);\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n };\n },\n });\n }\n}\n\nclass RPCInstanceServer {\n protected customConstructors: Map<string, Function>;\n protected context: Worker | MessagePort;\n /**\n * @param context {Worker | MessagePort} used to setup an rpc endpoint for functions\n */\n constructor(context: Worker | MessagePort) {\n context.addListener(\"error\", handleError);\n context.addListener(\"messageerror\", handleError);\n this.customConstructors = new Map();\n this.context = context;\n this.context.addListener(\n \"message\",\n this.queueTask.bind(this) as unknown as EventListener,\n );\n if (isMessagePort(this.context)) {\n this.context.start();\n }\n }\n /**\n * Exports functions to the rpc client\n * @param {Array<Function> | Function} constructors\n */\n public export(constructors: Array<Function> | Function) {\n if (Array.isArray(constructors)) {\n let index = constructors.length;\n while (index--) {\n this.customConstructors.set(\n constructors[index].name,\n constructors[index],\n );\n }\n } else {\n this.customConstructors.set(constructors.name, constructors);\n }\n }\n protected postMessage(\n context: Worker | MessagePort,\n CompletedTask: RPCResponse,\n ) {\n try {\n context.postMessage(\n CompletedTask,\n transferableBFS(CompletedTask.value) as Transferable[],\n );\n } catch (error: any) {\n CompletedTask.value = error;\n CompletedTask.isError = true;\n context.postMessage(\n CompletedTask,\n transferableBFS(error) as Transferable[],\n );\n }\n }\n protected async processPromise(\n CompletedTask: RPCResponse,\n ): Promise<RPCResponse> {\n try {\n CompletedTask.value = await CompletedTask.value;\n return CompletedTask;\n } catch (error) {\n CompletedTask.isError = true;\n CompletedTask.value = error;\n if (error instanceof Promise) {\n return this.processPromise(CompletedTask);\n } else {\n return CompletedTask;\n }\n }\n }\n protected processTask(task: RPCRequest): RPCResponse {\n let userConstructor = this.customConstructors.get(task.property);\n if (!userConstructor) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: new Error(`${task.property} is not present in the rpc server`),\n };\n return CompletedTask;\n }\n try {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: false,\n value: userConstructor(...task.args),\n };\n return CompletedTask;\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: error,\n };\n return CompletedTask;\n }\n }\n protected async queueTask(event: RPCRequest) {\n let task: RPCRequest = event;\n if (task.property != undefined) {\n let CompletedTask = this.processTask(task);\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessage(this.context, CompletedTask);\n }\n }\n}\nfunction PromisedTask(event: any) {\n if (event && typeof event === \"object\" && \"watch:import\" in event) {\n return; // internal watch-mode bookkeeping, ignore it\n }\n let resolvedTask: RPCRequest & RPCResponse = event;\n if (resolvedTask.isError != undefined) {\n //event.stopImmediatePropagation()\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPCInstance, RPCInstanceServer };\n","const objectRegistry: undefined | FinalizationRegistry<MessagePort> =\n typeof FinalizationRegistry == \"function\"\n ? new FinalizationRegistry(garbageCollector)\n : undefined;\n//clean up values for garbage collection\nfunction garbageCollector(port: MessagePort) {\n port.onmessage = null;\n port.onmessageerror = null;\n let task: RPCRequest = {\n args: [],\n property: \"close\",\n requestId: 1,\n };\n port.postMessage(task);\n port.close();\n}\nexport { objectRegistry };\n","export function isWindow(target: unknown): target is Window {\n return (\n typeof target === \"object\" &&\n target !== null &&\n (target as Window).window === target\n );\n}","import { RPCInstance, RPCInstanceServer } from \"@RPCInstance\";\nimport type {\n MessagePort as NodeMessagePort,\n Worker as NodeWorker,\n} from \"worker_threads\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { objectRegistry } from \"./gc\";\nimport { isWindow } from \"../utilities/isWindow\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPC {\n rpc: RPCInstance;\n targetOrigin?: string;\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n this.targetOrigin = targetOrigin;\n this.rpc = new RPCInstance(context as any, targetOrigin);\n } else {\n this.rpc = new RPCInstance(context as any);\n }\n }\n\n /**\n * returns an rpc client that calls functions\n */\n public getRPC() {\n return this.rpc;\n }\n\n /**\n * returns a class that is a proxy to the remote class\n *\n * @param {string | Function} customConstructor - the remote class or the name of the remote class\n *\n * @returns {new (...any: any) => ReturnType<any>}\n */\n public getConstructor(\n customConstructor: string | Function,\n ): new (...any: any) => ReturnType<any> {\n let constructor = class {},\n rpc = this.rpc;\n if (typeof customConstructor == \"function\") {\n customConstructor = customConstructor.name;\n }\n Object.defineProperty(constructor, \"name\", { value: customConstructor });\n return new Proxy(constructor, {\n async construct(target, args) {\n const { port1, port2 } = new MessageChannel();\n try {\n await (rpc as any).startRPCServer(port2, target.name, args);\n } catch (error) {\n throw error;\n }\n port1.onmessage = PromisedTask;\n port1.onmessageerror = handleError;\n Object.defineProperty(port1, \"name\", { value: target.name });\n const prox = new Proxy(port1, {\n get(target, property, receiver) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n if ((target as any)[property]) {\n if (typeof (target as any)[property] == \"function\") {\n if (property == \"close\") {\n target.onmessage = null;\n target.onmessageerror = null;\n let task: RPCRequest = {\n args,\n property,\n requestId: 1,\n };\n target.postMessage(task);\n objectRegistry?.unregister(receiver);\n }\n return (...args: any[]) => {\n (target as any)[property](...args);\n };\n } else {\n return (target as any)[property];\n }\n }\n return (...args: any[]) =>\n new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n const task: RPCRequest = {\n requestId,\n property: property as string,\n args,\n };\n try {\n target.postMessage(task, transferableBFS(args));\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n },\n });\n objectRegistry?.register(prox, port1, prox);\n return prox;\n },\n });\n }\n}\n\nclass RPCServer extends RPCInstanceServer {\n isWindow: boolean = false;\n /**\n * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context:\n | MessagePort\n | Worker\n | DedicatedWorkerGlobalScope\n | NodeWorker\n | NodeMessagePort\n | Window,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n super(context, targetOrigin);\n this.isWindow = true;\n } else {\n super(context as any);\n }\n }\n protected async startRPCServer(\n requestId: number,\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ) {\n const constructor = this.customConstructors.get(\n customConstructor,\n ) as FunctionConstructor;\n const postMessage = this.isWindow\n ? this.postMessageWindow.bind(this)\n : this.postMessage.bind(this);\n if (!constructor) {\n let CompletedTask: RPCResponse = {\n requestId: requestId,\n isError: true,\n value: new Error(\n `${customConstructor} is not present in the rpc server`,\n ),\n };\n postMessage(this.context as any, CompletedTask);\n } else {\n try {\n let instance = new constructor(...args);\n port.onmessageerror = handleError;\n port.onmessage = (event) => {\n if (event.data.property == \"close\") {\n port.onmessage = null;\n port.onmessageerror = null;\n instance = null as any;\n return;\n }\n this.processPortTask(port, event.data, instance);\n };\n let CompletedTask: RPCResponse = {\n requestId,\n value: undefined,\n isError: false,\n };\n postMessage(this.context as any, CompletedTask);\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId,\n value: error,\n isError: true,\n };\n postMessage(this.context as any, CompletedTask);\n }\n }\n }\n protected async processPortTask(\n port: MessagePort,\n task: RPCRequest,\n instance: Object,\n ) {\n let CompletedTask: RPCResponse;\n try {\n CompletedTask = {\n requestId: task.requestId,\n value: (instance as any)[task.property](...task.args),\n isError: false,\n };\n } catch (error) {\n CompletedTask = {\n requestId: task.requestId,\n value: error,\n isError: true,\n };\n }\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessage(port, CompletedTask);\n }\n protected async queueTask(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n } else {\n super.queueTask(event);\n }\n }\n }\n protected async queueTaskWindow(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n if (this.targetOrigin == event.origin || this.targetOrigin == \"*\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n }\n } else {\n super.queueTaskWindow(event);\n }\n }\n }\n}\nfunction PromisedTask(event: MessageEvent) {\n let resolvedTask: RPCRequest & RPCResponse = event.data;\n if (!resolvedTask.isError != undefined) {\n event.stopImmediatePropagation();\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPC, RPCServer };\n"],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { MessagePort as MessagePort$1, Worker as Worker$1 } from "node:worker_threads";
2
+ import { MessagePort as MessagePort$2, Worker as Worker$2 } from "worker_threads";
3
+ //#region src/node/function.node.d.ts
4
+ declare class RPCInstance {
5
+ /**
6
+ * @param context {MessagePort | Worker} used to setup an rpc client that calls functions
7
+ */
8
+ constructor(context: MessagePort$1 | Worker$1);
9
+ }
10
+ declare class RPCInstanceServer {
11
+ protected customConstructors: Map<string, Function>;
12
+ protected context: Worker$1 | MessagePort$1;
13
+ /**
14
+ * @param context {Worker | MessagePort} used to setup an rpc endpoint for functions
15
+ */
16
+ constructor(context: Worker$1 | MessagePort$1);
17
+ /**
18
+ * Exports functions to the rpc client
19
+ * @param {Array<Function> | Function} constructors
20
+ */
21
+ export(constructors: Array<Function> | Function): void;
22
+ protected postMessage(context: Worker$1 | MessagePort$1, CompletedTask: RPCResponse): void;
23
+ protected processPromise(CompletedTask: RPCResponse): Promise<RPCResponse>;
24
+ protected processTask(task: RPCRequest): RPCResponse;
25
+ protected queueTask(event: RPCRequest): Promise<void>;
26
+ }
27
+ //#endregion
28
+ //#region src/shared/shared.class.d.ts
29
+ declare class RPC {
30
+ rpc: RPCInstance;
31
+ targetOrigin?: string;
32
+ /**
33
+ * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions
34
+ * @param targetOrigin {string} Required only if context is a Window or iframe
35
+ */
36
+ constructor(context: Worker | DedicatedWorkerGlobalScope | Worker$2 | MessagePort, targetOrigin?: string);
37
+ /**
38
+ * returns an rpc client that calls functions
39
+ */
40
+ getRPC(): RPCInstance;
41
+ /**
42
+ * returns a class that is a proxy to the remote class
43
+ *
44
+ * @param {string | Function} customConstructor - the remote class or the name of the remote class
45
+ *
46
+ * @returns {new (...any: any) => ReturnType<any>}
47
+ */
48
+ getConstructor(customConstructor: string | Function): new (...any: any) => ReturnType<any>;
49
+ }
50
+ declare class RPCServer extends RPCInstanceServer {
51
+ isWindow: boolean;
52
+ /**
53
+ * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions
54
+ * @param targetOrigin {string} Required only if context is a Window or iframe
55
+ */
56
+ constructor(context: MessagePort | Worker | DedicatedWorkerGlobalScope | Worker$2 | MessagePort$2 | Window, targetOrigin?: string);
57
+ protected startRPCServer(requestId: number, port: MessagePort, customConstructor: string, args: any[]): Promise<void>;
58
+ protected processPortTask(port: MessagePort, task: RPCRequest, instance: Object): Promise<void>;
59
+ protected queueTask(event: MessageEvent & RPCRequest): Promise<void>;
60
+ protected queueTaskWindow(event: MessageEvent & RPCRequest): Promise<void>;
61
+ }
62
+ //#endregion
63
+ //#region src/asyncify.d.ts
64
+ type Asyncify<T> = T extends (new (...any: infer Args) => infer Return) ? new (...any: Args) => Promise<{ [K in keyof InstanceType<T>]: InstanceType<T>[K] extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : InstanceType<T>[K]; }> : T extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : T extends Object ? { [K in keyof T]: T[K] extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : T[K]; } : never;
65
+ //#endregion
66
+ export { type Asyncify, RPC, RPCInstance, RPCInstanceServer, RPCServer };
67
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1,67 @@
1
+ import { MessagePort as MessagePort$1, Worker as Worker$1 } from "node:worker_threads";
2
+ import { MessagePort as MessagePort$2, Worker as Worker$2 } from "worker_threads";
3
+ //#region src/node/function.node.d.ts
4
+ declare class RPCInstance {
5
+ /**
6
+ * @param context {MessagePort | Worker} used to setup an rpc client that calls functions
7
+ */
8
+ constructor(context: MessagePort$1 | Worker$1);
9
+ }
10
+ declare class RPCInstanceServer {
11
+ protected customConstructors: Map<string, Function>;
12
+ protected context: Worker$1 | MessagePort$1;
13
+ /**
14
+ * @param context {Worker | MessagePort} used to setup an rpc endpoint for functions
15
+ */
16
+ constructor(context: Worker$1 | MessagePort$1);
17
+ /**
18
+ * Exports functions to the rpc client
19
+ * @param {Array<Function> | Function} constructors
20
+ */
21
+ export(constructors: Array<Function> | Function): void;
22
+ protected postMessage(context: Worker$1 | MessagePort$1, CompletedTask: RPCResponse): void;
23
+ protected processPromise(CompletedTask: RPCResponse): Promise<RPCResponse>;
24
+ protected processTask(task: RPCRequest): RPCResponse;
25
+ protected queueTask(event: RPCRequest): Promise<void>;
26
+ }
27
+ //#endregion
28
+ //#region src/shared/shared.class.d.ts
29
+ declare class RPC {
30
+ rpc: RPCInstance;
31
+ targetOrigin?: string;
32
+ /**
33
+ * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions
34
+ * @param targetOrigin {string} Required only if context is a Window or iframe
35
+ */
36
+ constructor(context: Worker | DedicatedWorkerGlobalScope | Worker$2 | MessagePort, targetOrigin?: string);
37
+ /**
38
+ * returns an rpc client that calls functions
39
+ */
40
+ getRPC(): RPCInstance;
41
+ /**
42
+ * returns a class that is a proxy to the remote class
43
+ *
44
+ * @param {string | Function} customConstructor - the remote class or the name of the remote class
45
+ *
46
+ * @returns {new (...any: any) => ReturnType<any>}
47
+ */
48
+ getConstructor(customConstructor: string | Function): new (...any: any) => ReturnType<any>;
49
+ }
50
+ declare class RPCServer extends RPCInstanceServer {
51
+ isWindow: boolean;
52
+ /**
53
+ * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions
54
+ * @param targetOrigin {string} Required only if context is a Window or iframe
55
+ */
56
+ constructor(context: MessagePort | Worker | DedicatedWorkerGlobalScope | Worker$2 | MessagePort$2 | Window, targetOrigin?: string);
57
+ protected startRPCServer(requestId: number, port: MessagePort, customConstructor: string, args: any[]): Promise<void>;
58
+ protected processPortTask(port: MessagePort, task: RPCRequest, instance: Object): Promise<void>;
59
+ protected queueTask(event: MessageEvent & RPCRequest): Promise<void>;
60
+ protected queueTaskWindow(event: MessageEvent & RPCRequest): Promise<void>;
61
+ }
62
+ //#endregion
63
+ //#region src/asyncify.d.ts
64
+ type Asyncify<T> = T extends (new (...any: infer Args) => infer Return) ? new (...any: Args) => Promise<{ [K in keyof InstanceType<T>]: InstanceType<T>[K] extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : InstanceType<T>[K]; }> : T extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : T extends Object ? { [K in keyof T]: T[K] extends ((...any: infer Args) => infer Return) ? (...any: Args) => Promise<Awaited<Return>> : T[K]; } : never;
65
+ //#endregion
66
+ export { type Asyncify, RPC, RPCInstance, RPCInstanceServer, RPCServer };
67
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,2 @@
1
+ function e(e){throw e}const t=new Set([`ArrayBuffer`,`MessagePort`,`ReadableStream`,`WritableStream`,`TransformStream`,`WebTransportReceiveStream`,`WebTransportSendStream`,`AudioData`,`ImageBitmap`,`VideoFrame`,`OffscreenCanvas`,`RTCDataChannel`,`MediaSourceHandle`,`MIDIAccess`,`MediaStreamTrack`,`FileHandle`]);function n(e){let n=[],r=[];for(n.push(e);n.length;){let e=n.shift();if(typeof e==`object`){if(!e)continue;let i=e.constructor.name;if(t.has(i)){r.push(e);continue}let a=Object.values(e);a.length&&n.push(...a)}}return r}function r(e){return typeof e==`object`&&!!e&&typeof e.postMessage==`function`&&typeof e.start==`function`&&typeof e.close==`function`}const i=new Map;let a=0;var o=class{constructor(t){return t.addListener(`error`,e),t.addListener(`messageerror`,e),t.addListener(`exit`,e),t.addListener(`message`,c),new Proxy(t,{get(e,t){if(t!=`then`&&t!=`catch`&&typeof t==`string`)return(...r)=>e[t]==null?new Promise((o,s)=>{i.set(a,{resolve:o,reject:s});let c={requestId:a,args:r,property:t};try{e.postMessage(c,n(r)),a++}catch(e){i.delete(a),s(e)}}):e[t](...r)}})}},s=class{customConstructors;context;constructor(t){t.addListener(`error`,e),t.addListener(`messageerror`,e),this.customConstructors=new Map,this.context=t,this.context.addListener(`message`,this.queueTask.bind(this)),r(this.context)&&this.context.start()}export(e){if(Array.isArray(e)){let t=e.length;for(;t--;)this.customConstructors.set(e[t].name,e[t])}else this.customConstructors.set(e.name,e)}postMessage(e,t){try{e.postMessage(t,n(t.value))}catch(r){t.value=r,t.isError=!0,e.postMessage(t,n(r))}}async processPromise(e){try{return e.value=await e.value,e}catch(t){return e.isError=!0,e.value=t,t instanceof Promise?this.processPromise(e):e}}processTask(e){let t=this.customConstructors.get(e.property);if(!t)return{requestId:e.requestId,isError:!0,value:Error(`${e.property} is not present in the rpc server`)};try{return{requestId:e.requestId,isError:!1,value:t(...e.args)}}catch(t){return{requestId:e.requestId,isError:!0,value:t}}}async queueTask(e){let t=e;if(t.property!=null){let e=this.processTask(t);e.value instanceof Promise&&(e=await this.processPromise(e)),this.postMessage(this.context,e)}}};function c(e){if(e&&typeof e==`object`&&`watch:import`in e)return;let t=e;if(t.isError!=null){let e=i.get(t.requestId);i.delete(t.requestId),t.isError?e.reject(t.value):e.resolve(t.value)}}const l=typeof FinalizationRegistry==`function`?new FinalizationRegistry(u):void 0;function u(e){e.onmessage=null,e.onmessageerror=null,e.postMessage({args:[],property:`close`,requestId:1}),e.close()}function d(e){return typeof e==`object`&&!!e&&e.window===e}const f=new Map;let p=0;var m=class{rpc;targetOrigin;constructor(e,t){if(d(e)){if(t==null)throw Error(`target origin is required`);this.targetOrigin=t,this.rpc=new o(e,t)}else this.rpc=new o(e)}getRPC(){return this.rpc}getConstructor(t){let r=class{},i=this.rpc;return typeof t==`function`&&(t=t.name),Object.defineProperty(r,"name",{value:t}),new Proxy(r,{async construct(t,r){let{port1:a,port2:o}=new MessageChannel;try{await i.startRPCServer(o,t.name,r)}catch(e){throw e}a.onmessage=g,a.onmessageerror=e,Object.defineProperty(a,"name",{value:t.name});let s=new Proxy(a,{get(e,t,i){if(t!=`then`&&t!=`catch`&&typeof t==`string`){if(e[t]){if(typeof e[t]==`function`){if(t==`close`){e.onmessage=null,e.onmessageerror=null;let n={args:r,property:t,requestId:1};e.postMessage(n),l?.unregister(i)}return(...n)=>{e[t](...n)}}return e[t]}return(...r)=>new Promise((i,a)=>{f.set(p,{resolve:i,reject:a});let o={requestId:p,property:t,args:r};try{e.postMessage(o,n(r)),p++}catch(e){f.delete(p),a(e)}})}}});return l?.register(s,a,s),s}})}},h=class extends s{isWindow=!1;constructor(e,t){d(e)?(super(e,t),this.isWindow=!0):super(e)}async startRPCServer(t,n,r,i){let a=this.customConstructors.get(r),o=this.isWindow?this.postMessageWindow.bind(this):this.postMessage.bind(this);if(a)try{let r=new a(...i);n.onmessageerror=e,n.onmessage=e=>{if(e.data.property==`close`){n.onmessage=null,n.onmessageerror=null,r=null;return}this.processPortTask(n,e.data,r)};let s={requestId:t,value:void 0,isError:!1};o(this.context,s)}catch(e){let n={requestId:t,value:e,isError:!0};o(this.context,n)}else{let e={requestId:t,isError:!0,value:Error(`${r} is not present in the rpc server`)};o(this.context,e)}}async processPortTask(e,t,n){let r;try{r={requestId:t.requestId,value:n[t.property](...t.args),isError:!1}}catch(e){r={requestId:t.requestId,value:e,isError:!0}}r.value instanceof Promise&&(r=await this.processPromise(r)),this.postMessage(e,r)}async queueTask(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?this.startRPCServer(t.requestId,...t.args):super.queueTask(e)}}async queueTaskWindow(e){if(e?.data?.property!=null||e?.property!=null){let t;e?.data?.property?(t=e.data,e.stopImmediatePropagation()):t=e,t.property==`startRPCServer`?(this.targetOrigin==e.origin||this.targetOrigin==`*`)&&this.startRPCServer(t.requestId,...t.args):super.queueTaskWindow(e)}}};function g(e){let t=e.data;if(!t.isError!=null){e.stopImmediatePropagation();let n=f.get(t.requestId);f.delete(t.requestId),t.isError?n.reject(t.value):n.resolve(t.value)}}export{m as RPC,o as RPCInstance,s as RPCInstanceServer,h as RPCServer};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["ActiveTasks","requestId","PromisedTask"],"sources":["../../src/utilities/handleerror.ts","../../src/utilities/transferable.ts","../../src/utilities/isMessagePort.ts","../../src/node/function.node.ts","../../src/shared/gc.ts","../../src/utilities/isWindow.ts","../../src/shared/shared.class.ts"],"sourcesContent":["export function handleError(event:ErrorEvent|Event) {\n throw event;\n}","const transferableSet = new Set(['ArrayBuffer',\n 'MessagePort',\n 'ReadableStream',\n 'WritableStream',\n 'TransformStream',\n 'WebTransportReceiveStream',\n 'WebTransportSendStream',\n 'AudioData',\n 'ImageBitmap',\n 'VideoFrame',\n 'OffscreenCanvas',\n 'RTCDataChannel',\n 'MediaSourceHandle',\n 'MIDIAccess',\n 'MediaStreamTrack',\n 'FileHandle'])\nexport function transferableBFS(args:any[]):Transferable[] {\n const queue = [], transferable = [];\n queue.push(args)\n while (queue.length) {\n const value:any = queue.shift()\n if (typeof value == 'object') {\n if (!value) {\n continue\n }\n let constructor = value.constructor.name\n if (transferableSet.has(constructor)) {\n transferable.push(value)\n continue\n }\n let iterator = Object.values(value)\n if (iterator.length)\n queue.push(...iterator)\n }\n }\n return transferable\n}","export function isMessagePort(target: unknown): target is MessagePort {\n return (\n typeof target === \"object\" &&\n target !== null &&\n typeof (target as MessagePort).postMessage === \"function\" &&\n typeof (target as MessagePort).start === \"function\" &&\n typeof (target as MessagePort).close === \"function\"\n );\n}","import type { MessagePort, Transferable, Worker } from \"node:worker_threads\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { isMessagePort } from \"../utilities/isMessagePort\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPCInstance {\n /**\n * @param context {MessagePort | Worker} used to setup an rpc client that calls functions\n */\n constructor(context: MessagePort | Worker) {\n context.addListener(\"error\", handleError);\n context.addListener(\"messageerror\", handleError);\n context.addListener(\"exit\", handleError);\n context.addListener(\"message\", PromisedTask);\n return new Proxy(context, {\n get(target, property) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n return (...args: any[]) => {\n if ((target as any)[property] != undefined) {\n return (target as any)[property](...args);\n }\n return new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n let task: RPCRequest = {\n requestId,\n args,\n property: property as string,\n };\n try {\n target.postMessage(task, transferableBFS(args) as Transferable[]);\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n };\n },\n });\n }\n}\n\nclass RPCInstanceServer {\n protected customConstructors: Map<string, Function>;\n protected context: Worker | MessagePort;\n /**\n * @param context {Worker | MessagePort} used to setup an rpc endpoint for functions\n */\n constructor(context: Worker | MessagePort) {\n context.addListener(\"error\", handleError);\n context.addListener(\"messageerror\", handleError);\n this.customConstructors = new Map();\n this.context = context;\n this.context.addListener(\n \"message\",\n this.queueTask.bind(this) as unknown as EventListener,\n );\n if (isMessagePort(this.context)) {\n this.context.start();\n }\n }\n /**\n * Exports functions to the rpc client\n * @param {Array<Function> | Function} constructors\n */\n public export(constructors: Array<Function> | Function) {\n if (Array.isArray(constructors)) {\n let index = constructors.length;\n while (index--) {\n this.customConstructors.set(\n constructors[index].name,\n constructors[index],\n );\n }\n } else {\n this.customConstructors.set(constructors.name, constructors);\n }\n }\n protected postMessage(\n context: Worker | MessagePort,\n CompletedTask: RPCResponse,\n ) {\n try {\n context.postMessage(\n CompletedTask,\n transferableBFS(CompletedTask.value) as Transferable[],\n );\n } catch (error: any) {\n CompletedTask.value = error;\n CompletedTask.isError = true;\n context.postMessage(\n CompletedTask,\n transferableBFS(error) as Transferable[],\n );\n }\n }\n protected async processPromise(\n CompletedTask: RPCResponse,\n ): Promise<RPCResponse> {\n try {\n CompletedTask.value = await CompletedTask.value;\n return CompletedTask;\n } catch (error) {\n CompletedTask.isError = true;\n CompletedTask.value = error;\n if (error instanceof Promise) {\n return this.processPromise(CompletedTask);\n } else {\n return CompletedTask;\n }\n }\n }\n protected processTask(task: RPCRequest): RPCResponse {\n let userConstructor = this.customConstructors.get(task.property);\n if (!userConstructor) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: new Error(`${task.property} is not present in the rpc server`),\n };\n return CompletedTask;\n }\n try {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: false,\n value: userConstructor(...task.args),\n };\n return CompletedTask;\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId: task.requestId,\n isError: true,\n value: error,\n };\n return CompletedTask;\n }\n }\n protected async queueTask(event: RPCRequest) {\n let task: RPCRequest = event;\n if (task.property != undefined) {\n let CompletedTask = this.processTask(task);\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessage(this.context, CompletedTask);\n }\n }\n}\nfunction PromisedTask(event: any) {\n if (event && typeof event === \"object\" && \"watch:import\" in event) {\n return; // internal watch-mode bookkeeping, ignore it\n }\n let resolvedTask: RPCRequest & RPCResponse = event;\n if (resolvedTask.isError != undefined) {\n //event.stopImmediatePropagation()\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPCInstance, RPCInstanceServer };\n","const objectRegistry: undefined | FinalizationRegistry<MessagePort> =\n typeof FinalizationRegistry == \"function\"\n ? new FinalizationRegistry(garbageCollector)\n : undefined;\n//clean up values for garbage collection\nfunction garbageCollector(port: MessagePort) {\n port.onmessage = null;\n port.onmessageerror = null;\n let task: RPCRequest = {\n args: [],\n property: \"close\",\n requestId: 1,\n };\n port.postMessage(task);\n port.close();\n}\nexport { objectRegistry };\n","export function isWindow(target: unknown): target is Window {\n return (\n typeof target === \"object\" &&\n target !== null &&\n (target as Window).window === target\n );\n}","import { RPCInstance, RPCInstanceServer } from \"@RPCInstance\";\nimport type {\n MessagePort as NodeMessagePort,\n Worker as NodeWorker,\n} from \"worker_threads\";\nimport { handleError } from \"../utilities/handleerror\";\nimport { transferableBFS } from \"../utilities/transferable\";\nimport { objectRegistry } from \"./gc\";\nimport { isWindow } from \"../utilities/isWindow\";\n\nconst ActiveTasks: Map<number, any> = new Map();\nlet requestId = 0;\n\nclass RPC {\n rpc: RPCInstance;\n targetOrigin?: string;\n /**\n * @param context {Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort} used to setup an rpc client for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context: Worker | DedicatedWorkerGlobalScope | NodeWorker | MessagePort,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n if (targetOrigin == undefined) {\n throw new Error(\"target origin is required\");\n }\n this.targetOrigin = targetOrigin;\n this.rpc = new RPCInstance(context as any, targetOrigin);\n } else {\n this.rpc = new RPCInstance(context as any);\n }\n }\n\n /**\n * returns an rpc client that calls functions\n */\n public getRPC() {\n return this.rpc;\n }\n\n /**\n * returns a class that is a proxy to the remote class\n *\n * @param {string | Function} customConstructor - the remote class or the name of the remote class\n *\n * @returns {new (...any: any) => ReturnType<any>}\n */\n public getConstructor(\n customConstructor: string | Function,\n ): new (...any: any) => ReturnType<any> {\n let constructor = class {},\n rpc = this.rpc;\n if (typeof customConstructor == \"function\") {\n customConstructor = customConstructor.name;\n }\n Object.defineProperty(constructor, \"name\", { value: customConstructor });\n return new Proxy(constructor, {\n async construct(target, args) {\n const { port1, port2 } = new MessageChannel();\n try {\n await (rpc as any).startRPCServer(port2, target.name, args);\n } catch (error) {\n throw error;\n }\n port1.onmessage = PromisedTask;\n port1.onmessageerror = handleError;\n Object.defineProperty(port1, \"name\", { value: target.name });\n const prox = new Proxy(port1, {\n get(target, property, receiver) {\n if (\n property == \"then\" ||\n property == \"catch\" ||\n typeof property != \"string\"\n ) {\n return;\n }\n if ((target as any)[property]) {\n if (typeof (target as any)[property] == \"function\") {\n if (property == \"close\") {\n target.onmessage = null;\n target.onmessageerror = null;\n let task: RPCRequest = {\n args,\n property,\n requestId: 1,\n };\n target.postMessage(task);\n objectRegistry?.unregister(receiver);\n }\n return (...args: any[]) => {\n (target as any)[property](...args);\n };\n } else {\n return (target as any)[property];\n }\n }\n return (...args: any[]) =>\n new Promise((resolve, reject) => {\n ActiveTasks.set(requestId, { resolve, reject });\n const task: RPCRequest = {\n requestId,\n property: property as string,\n args,\n };\n try {\n target.postMessage(task, transferableBFS(args));\n requestId++;\n } catch (error) {\n ActiveTasks.delete(requestId);\n reject(error);\n }\n });\n },\n });\n objectRegistry?.register(prox, port1, prox);\n return prox;\n },\n });\n }\n}\n\nclass RPCServer extends RPCInstanceServer {\n isWindow: boolean = false;\n /**\n * @param context {MessagePort | Worker | DedicatedWorkerGlobalScope | NodeWorker | NodeMessagePort | Window} used to setup an rpc endpoint for both classes and functions\n * @param targetOrigin {string} Required only if context is a Window or iframe\n */\n constructor(\n context:\n | MessagePort\n | Worker\n | DedicatedWorkerGlobalScope\n | NodeWorker\n | NodeMessagePort\n | Window,\n targetOrigin?: string,\n ) {\n if (isWindow(context)) {\n super(context, targetOrigin);\n this.isWindow = true;\n } else {\n super(context as any);\n }\n }\n protected async startRPCServer(\n requestId: number,\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ) {\n const constructor = this.customConstructors.get(\n customConstructor,\n ) as FunctionConstructor;\n const postMessage = this.isWindow\n ? this.postMessageWindow.bind(this)\n : this.postMessage.bind(this);\n if (!constructor) {\n let CompletedTask: RPCResponse = {\n requestId: requestId,\n isError: true,\n value: new Error(\n `${customConstructor} is not present in the rpc server`,\n ),\n };\n postMessage(this.context as any, CompletedTask);\n } else {\n try {\n let instance = new constructor(...args);\n port.onmessageerror = handleError;\n port.onmessage = (event) => {\n if (event.data.property == \"close\") {\n port.onmessage = null;\n port.onmessageerror = null;\n instance = null as any;\n return;\n }\n this.processPortTask(port, event.data, instance);\n };\n let CompletedTask: RPCResponse = {\n requestId,\n value: undefined,\n isError: false,\n };\n postMessage(this.context as any, CompletedTask);\n } catch (error) {\n let CompletedTask: RPCResponse = {\n requestId,\n value: error,\n isError: true,\n };\n postMessage(this.context as any, CompletedTask);\n }\n }\n }\n protected async processPortTask(\n port: MessagePort,\n task: RPCRequest,\n instance: Object,\n ) {\n let CompletedTask: RPCResponse;\n try {\n CompletedTask = {\n requestId: task.requestId,\n value: (instance as any)[task.property](...task.args),\n isError: false,\n };\n } catch (error) {\n CompletedTask = {\n requestId: task.requestId,\n value: error,\n isError: true,\n };\n }\n if (CompletedTask.value instanceof Promise) {\n CompletedTask = await this.processPromise(CompletedTask);\n }\n this.postMessage(port, CompletedTask);\n }\n protected async queueTask(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n } else {\n super.queueTask(event);\n }\n }\n }\n protected async queueTaskWindow(event: MessageEvent & RPCRequest) {\n if (event?.data?.property != undefined || event?.property != undefined) {\n let task: RPCRequest;\n if (event?.data?.property) {\n task = event.data;\n event.stopImmediatePropagation();\n } else {\n task = event;\n }\n if (task.property == \"startRPCServer\") {\n if (this.targetOrigin == event.origin || this.targetOrigin == \"*\") {\n this.startRPCServer(\n task.requestId,\n ...(task.args as [\n port: MessagePort,\n customConstructor: string,\n args: any[],\n ]),\n );\n }\n } else {\n super.queueTaskWindow(event);\n }\n }\n }\n}\nfunction PromisedTask(event: MessageEvent) {\n let resolvedTask: RPCRequest & RPCResponse = event.data;\n if (!resolvedTask.isError != undefined) {\n event.stopImmediatePropagation();\n let pendingPromise = ActiveTasks.get(resolvedTask.requestId);\n ActiveTasks.delete(resolvedTask.requestId);\n if (resolvedTask.isError) {\n pendingPromise.reject(resolvedTask.value);\n } else {\n pendingPromise.resolve(resolvedTask.value);\n }\n }\n}\n\nexport { RPC, RPCServer };\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "achi-rpc",
3
+ "type": "module",
4
+ "version": "1.0.1",
5
+ "description": "An RPC library for Typescript and Javascript",
6
+ "author": {
7
+ "name": "Kimbugwe Mark",
8
+ "email": "markkimbugwe@gmail.com"
9
+ },
10
+ "license": "MIT",
11
+ "homepage": "https://github.com/kimbugwe-mark/achi-rpc#readme",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/kimbugwe-mark/achi-rpc.git"
15
+ },
16
+ "keywords": [
17
+ "worker threads",
18
+ "web worker",
19
+ "shared worker",
20
+ "remote procedure call",
21
+ "performance",
22
+ "rpc"
23
+ ],
24
+ "bugs": {
25
+ "url": "https://github.com/kimbugwe-mark/achi-rpc/issues"
26
+ },
27
+ "types": "./dist/node/index.d.mts",
28
+ "unpkg": "./dist/browser/index.iife.js",
29
+ "jsdelivr": "./dist/browser/index.iife.js",
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/node/index.d.mts",
33
+ "node": {
34
+ "import": "./dist/node/index.mjs",
35
+ "require": "./dist/node/index.cjs",
36
+ "types": "./dist/node/index.d.mts"
37
+ },
38
+ "bun": {
39
+ "import": "./dist/browser/index.mjs",
40
+ "types": "./dist/browser/index.d.mts"
41
+ },
42
+ "deno": {
43
+ "import": "./dist/browser/index.mjs",
44
+ "types": "./dist/browser/index.d.mts"
45
+ },
46
+ "browser": {
47
+ "import": "./dist/browser/index.mjs",
48
+ "types": "./dist/browser/index.d.mts"
49
+ },
50
+ "default": "./dist/node/index.mjs"
51
+ },
52
+ "./node": {
53
+ "import": "./dist/node/index.mjs",
54
+ "require": "./dist/node/index.cjs",
55
+ "types": "./dist/node/index.d.mts"
56
+ },
57
+ "./browser": {
58
+ "import": "./dist/browser/index.mjs",
59
+ "types": "./dist/browser/index.d.mts"
60
+ },
61
+ "./package.json": "./package.json"
62
+ },
63
+ "files": [
64
+ "dist"
65
+ ],
66
+ "devDependencies": {
67
+ "@types/node": "^26.1.1",
68
+ "@vitest/browser-playwright": "^4.1.11",
69
+ "bumpp": "^11.1.0",
70
+ "es-check": "^9.7.1",
71
+ "es-check-min": "^1.0.11",
72
+ "happy-dom": "^9.0.0",
73
+ "tsdown": "^0.22.5",
74
+ "typescript": "^7.0.2",
75
+ "vitest": "^4.1.10"
76
+ },
77
+ "scripts": {
78
+ "build": "tsdown",
79
+ "dev": "tsdown --watch",
80
+ "test": "vitest",
81
+ "typecheck": "tsc --noEmit",
82
+ "release": "bumpp",
83
+ "test:browser": "vitest --config=vitest.config.ts"
84
+ }
85
+ }