osra 0.0.1 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/build/index.js +39 -18
- package/package.json +14 -2
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# osra
|
|
2
|
+
what that? https://github.com/GoogleChromeLabs/comlink but nicer to use.
|
|
3
|
+
thats about it
|
|
4
|
+
|
|
5
|
+
how to?
|
|
6
|
+
register your functions in the other context like so
|
|
7
|
+
```ts
|
|
8
|
+
import { makeCallListener, registerListener } from 'osra'
|
|
9
|
+
|
|
10
|
+
const resolvers = {
|
|
11
|
+
'test': makeCallListener(async (myData) => {
|
|
12
|
+
// do work...
|
|
13
|
+
return {
|
|
14
|
+
foo: 1,
|
|
15
|
+
bar: 'bar',
|
|
16
|
+
baz: () => true
|
|
17
|
+
}
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
registerListener({ target: globalThis, resolvers })
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
and on your current context you can call it easily like
|
|
25
|
+
```ts
|
|
26
|
+
import { call } from 'osra'
|
|
27
|
+
|
|
28
|
+
const worker = new Worker('/worker.js', { type: 'module' })
|
|
29
|
+
|
|
30
|
+
call(worker)('test', { theDataThatWillBeSentToTheOtherContext: 1 })
|
|
31
|
+
.then(({ foo, bar, baz }) => {
|
|
32
|
+
// foo === 1
|
|
33
|
+
// bar === 'bar'
|
|
34
|
+
// baz === callable function that will return a promise with its response
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
all types of data supported by osra that will be correctly proxied/sent to the other context in addition of functions:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
export type TransferableObject =
|
|
42
|
+
ArrayBuffer | MessagePort | ReadableStream | WritableStream |
|
|
43
|
+
TransformStream | /* AudioData | */ ImageBitmap /* | VideoFrame | OffscreenCanvas */
|
|
44
|
+
|
|
45
|
+
export interface StructuredCloneObject {
|
|
46
|
+
[key: string | number | symbol]: StructuredCloneType
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type StructuredCloneType =
|
|
50
|
+
boolean | null | undefined | number | BigInt | string | Date | RegExp | Blob | File | FileList | ArrayBuffer | ArrayBufferView |
|
|
51
|
+
ImageBitmap | ImageData | Array<StructuredCloneType> | StructuredCloneObject | Map<StructuredCloneType, StructuredCloneType> | Set<StructuredCloneType>
|
|
52
|
+
|
|
53
|
+
export interface StructruredCloneTransferableObject {
|
|
54
|
+
[key: string | number | symbol]: StructruredCloneTransferableType
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type StructruredCloneTransferableType =
|
|
58
|
+
StructuredCloneType | TransferableObject | Array<StructruredCloneTransferableType> | StructruredCloneTransferableObject |
|
|
59
|
+
Map<StructruredCloneTransferableType, StructruredCloneTransferableType> | Set<StructruredCloneTransferableType>
|
|
60
|
+
```
|
package/build/index.js
CHANGED
|
@@ -6,6 +6,7 @@ var registerListener = ({
|
|
|
6
6
|
target,
|
|
7
7
|
resolvers,
|
|
8
8
|
filter,
|
|
9
|
+
map,
|
|
9
10
|
key = MESSAGE_SOURCE_KEY
|
|
10
11
|
}) => {
|
|
11
12
|
const listener = async (event) => {
|
|
@@ -19,7 +20,10 @@ var registerListener = ({
|
|
|
19
20
|
const resolver = resolvers[type];
|
|
20
21
|
if (!resolver)
|
|
21
22
|
throw new Error(`Osra received a message of type "${type}" but no resolver was found for type.`);
|
|
22
|
-
|
|
23
|
+
if (map)
|
|
24
|
+
resolver(...map(data, { event, type, port }));
|
|
25
|
+
else
|
|
26
|
+
resolver(data, { event, type, port });
|
|
23
27
|
};
|
|
24
28
|
target.addEventListener("message", listener);
|
|
25
29
|
return {
|
|
@@ -29,7 +33,7 @@ var registerListener = ({
|
|
|
29
33
|
};
|
|
30
34
|
|
|
31
35
|
// src/utils.ts
|
|
32
|
-
var isTransferable = (value) => value instanceof ArrayBuffer ? true : value instanceof MessagePort ? true : value instanceof ReadableStream ? true : value instanceof WritableStream ? true : value instanceof TransformStream ? true : value instanceof ImageBitmap ? true : false;
|
|
36
|
+
var isTransferable = (value) => globalThis.ArrayBuffer && value instanceof globalThis.ArrayBuffer ? true : globalThis.MessagePort && value instanceof globalThis.MessagePort ? true : globalThis.ReadableStream && value instanceof globalThis.ReadableStream ? true : globalThis.WritableStream && value instanceof globalThis.WritableStream ? true : globalThis.TransformStream && value instanceof globalThis.TransformStream ? true : globalThis.ImageBitmap && value instanceof globalThis.ImageBitmap ? true : false;
|
|
33
37
|
var getTransferableObjects = (value) => {
|
|
34
38
|
const transferables = [];
|
|
35
39
|
const recurse = (value2) => isTransferable(value2) ? transferables.push(value2) : Array.isArray(value2) ? value2.map(recurse) : value2 && typeof value2 === "object" ? Object.values(value2).map(recurse) : void 0;
|
|
@@ -39,11 +43,15 @@ var getTransferableObjects = (value) => {
|
|
|
39
43
|
var PROXY_FUNCTION_PROPERTY = "__proxyFunctionPort__";
|
|
40
44
|
var makeProxyFunction = (func) => {
|
|
41
45
|
const { port1, port2 } = new MessageChannel();
|
|
42
|
-
port1.addEventListener("message", (ev) => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
port1.addEventListener("message", async (ev) => {
|
|
47
|
+
try {
|
|
48
|
+
const result = await func(...ev.data);
|
|
49
|
+
const proxiedResult = proxyObjectFunctions(result);
|
|
50
|
+
const transferables = getTransferableObjects(proxiedResult);
|
|
51
|
+
port1.postMessage({ result: proxiedResult }, { transfer: transferables });
|
|
52
|
+
} catch (err) {
|
|
53
|
+
port1.postMessage({ error: err });
|
|
54
|
+
}
|
|
47
55
|
});
|
|
48
56
|
port1.start();
|
|
49
57
|
return port2;
|
|
@@ -56,7 +64,10 @@ var makeProxiedFunction = (port) => (...args) => new Promise((resolve, reject) =
|
|
|
56
64
|
const proxiedArguments = proxyObjectFunctions(args);
|
|
57
65
|
const transferables = getTransferableObjects(proxiedArguments);
|
|
58
66
|
port.addEventListener("message", (ev) => {
|
|
59
|
-
|
|
67
|
+
if (ev.data.error)
|
|
68
|
+
reject(ev.data.error);
|
|
69
|
+
else
|
|
70
|
+
resolve(makeObjectProxiedFunctions(ev.data.result));
|
|
60
71
|
});
|
|
61
72
|
port.start();
|
|
62
73
|
port.postMessage(proxiedArguments, { transfer: transferables });
|
|
@@ -67,11 +78,15 @@ var makeObjectProxiedFunctions = (value) => isTransferable(value) ? value : valu
|
|
|
67
78
|
])) : value;
|
|
68
79
|
|
|
69
80
|
// src/call.ts
|
|
70
|
-
var call = (target, { key = MESSAGE_SOURCE_KEY } = { key: MESSAGE_SOURCE_KEY }) => (type, data) => new Promise((resolve) => {
|
|
81
|
+
var call = (target, { key = MESSAGE_SOURCE_KEY } = { key: MESSAGE_SOURCE_KEY }) => (type, data) => new Promise((resolve, reject) => {
|
|
71
82
|
const { port1, port2 } = new MessageChannel();
|
|
72
83
|
port1.addEventListener("message", ({ data: data2 }) => {
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
if (data2.error) {
|
|
85
|
+
reject(data2.error);
|
|
86
|
+
} else {
|
|
87
|
+
const proxiedData2 = makeObjectProxiedFunctions(data2.result);
|
|
88
|
+
resolve(proxiedData2);
|
|
89
|
+
}
|
|
75
90
|
port1.close();
|
|
76
91
|
port2.close();
|
|
77
92
|
}, { once: true });
|
|
@@ -81,7 +96,7 @@ var call = (target, { key = MESSAGE_SOURCE_KEY } = { key: MESSAGE_SOURCE_KEY })
|
|
|
81
96
|
target.postMessage({
|
|
82
97
|
source: key,
|
|
83
98
|
type,
|
|
84
|
-
data,
|
|
99
|
+
data: proxiedData,
|
|
85
100
|
port: port2
|
|
86
101
|
}, {
|
|
87
102
|
targetOrigin: "*",
|
|
@@ -91,12 +106,18 @@ var call = (target, { key = MESSAGE_SOURCE_KEY } = { key: MESSAGE_SOURCE_KEY })
|
|
|
91
106
|
var makeCallListener = (func) => async (data, extra) => {
|
|
92
107
|
const { port } = extra;
|
|
93
108
|
const proxiedData = makeObjectProxiedFunctions(data);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
109
|
+
try {
|
|
110
|
+
const result = await func(proxiedData, extra);
|
|
111
|
+
const proxyData = proxyObjectFunctions(result);
|
|
112
|
+
const transferables = getTransferableObjects(proxyData);
|
|
113
|
+
port.postMessage({ result: proxyData }, { transfer: transferables });
|
|
114
|
+
port.close();
|
|
115
|
+
return result;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
port.postMessage({ error });
|
|
118
|
+
port.close();
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
100
121
|
};
|
|
101
122
|
export {
|
|
102
123
|
call,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "osra",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Easy communication between workers",
|
|
5
5
|
"files": [
|
|
6
6
|
"./build"
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
"type-check-watch": "tsc --watch --incremental",
|
|
12
12
|
"build": "esbuild ./src/index.ts --format=esm --bundle --outfile=build/index.js && npm run type-check",
|
|
13
13
|
"build-watch": "esbuild --watch ./src/index.ts --format=esm --bundle --outfile=build/index.js",
|
|
14
|
-
"dev": "concurrently \"npm run build-watch\" \"npm run type-check-watch\""
|
|
14
|
+
"dev": "concurrently \"npm run build-watch\" \"npm run type-check-watch\"",
|
|
15
|
+
"copy-tests-html": "copyfiles -u 1 ./tests/*/index.html tests/build",
|
|
16
|
+
"build-tests": "npm run copy-tests-html && esbuild ./tests/call/iframe.ts ./tests/event-channel/iframe.ts --format=esm --bundle --outdir=tests/build",
|
|
17
|
+
"build-tests-watch": "npm run copy-tests-html && esbuild --watch ./tests/call/iframe.ts ./tests/event-channel/iframe.ts --format=esm --bundle --outdir=tests/build",
|
|
18
|
+
"test": "epk",
|
|
19
|
+
"test-watch": "epk -w"
|
|
15
20
|
},
|
|
16
21
|
"repository": {
|
|
17
22
|
"type": "git",
|
|
@@ -24,8 +29,15 @@
|
|
|
24
29
|
},
|
|
25
30
|
"homepage": "https://github.com/Banou26/osra#readme",
|
|
26
31
|
"devDependencies": {
|
|
32
|
+
"@types/chai-as-promised": "^7.1.5",
|
|
33
|
+
"@types/node": "^17.0.35",
|
|
34
|
+
"chai": "^4.3.6",
|
|
35
|
+
"chai-as-promised": "^7.1.1",
|
|
27
36
|
"concurrently": "^7.0.0",
|
|
37
|
+
"copyfiles": "^2.4.1",
|
|
38
|
+
"epk": "^0.16.0",
|
|
28
39
|
"esbuild": "^0.14.28",
|
|
40
|
+
"mime": "^3.0.0",
|
|
29
41
|
"typescript": "^4.6.3"
|
|
30
42
|
}
|
|
31
43
|
}
|