Socket
Socket
Sign inDemoInstall

comlink

Package Overview
Dependencies
Maintainers
3
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

comlink - npm Package Compare versions

Comparing version 4.3.1 to 4.4.0

.husky/pre-commit

42

dist/esm/comlink.d.ts
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { Endpoint, EventSource, PostMessageWithOrigin } from "./protocol";
export { Endpoint };
export type { Endpoint };
export declare const proxyMarker: unique symbol;
export declare const createEndpoint: unique symbol;
export declare const releaseProxy: unique symbol;
export declare const finalizer: unique symbol;
/**

@@ -31,3 +25,3 @@ * Interface of values that were marked to be proxied with `comlink.proxy()`.

*/
declare type Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;
type Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;
/**

@@ -39,3 +33,3 @@ * Takes a type that may be Promise and unwraps the Promise type.

*/
declare type Unpromisify<P> = P extends Promise<infer T> ? T : P;
type Unpromisify<P> = P extends Promise<infer T> ? T : P;
/**

@@ -47,3 +41,3 @@ * Takes the raw type of a remote property and returns the type that is visible to the local thread on the proxy.

*/
declare type RemoteProperty<T> = T extends Function | ProxyMarked ? Remote<T> : Promisify<T>;
type RemoteProperty<T> = T extends Function | ProxyMarked ? Remote<T> : Promisify<T>;
/**

@@ -58,11 +52,11 @@ * Takes the raw type of a property as a remote thread would see it through a proxy (e.g. when passed in as a function

*/
declare type LocalProperty<T> = T extends Function | ProxyMarked ? Local<T> : Unpromisify<T>;
type LocalProperty<T> = T extends Function | ProxyMarked ? Local<T> : Unpromisify<T>;
/**
* Proxies `T` if it is a `ProxyMarked`, clones it otherwise (as handled by structured cloning and transfer handlers).
*/
export declare type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;
export type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;
/**
* Inverse of `ProxyOrClone<T>`.
*/
export declare type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked> ? Local<T> : T;
export type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked> ? Local<T> : T;
/**

@@ -76,3 +70,3 @@ * Takes the raw type of a remote object in the other thread and returns the type as it is visible to the local thread

*/
export declare type RemoteObject<T> = {
export type RemoteObject<T> = {
[P in keyof T]: RemoteProperty<T[P]>;

@@ -90,3 +84,3 @@ };

*/
export declare type LocalObject<T> = {
export type LocalObject<T> = {
[P in keyof T]: LocalProperty<T[P]>;

@@ -105,3 +99,3 @@ };

*/
export declare type Remote<T> = RemoteObject<T> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
export type Remote<T> = RemoteObject<T> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
[I in keyof TArguments]: UnproxyOrClone<TArguments[I]>;

@@ -118,3 +112,3 @@ }) => Promisify<ProxyOrClone<Unpromisify<TReturn>>> : unknown) & (T extends {

*/
declare type MaybePromise<T> = Promise<T> | T;
type MaybePromise<T> = Promise<T> | T;
/**

@@ -126,3 +120,3 @@ * Takes the raw type of a remote object, function or class as a remote thread would see it through a proxy (e.g. when

*/
export declare type Local<T> = Omit<LocalObject<T>, keyof ProxyMethods> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
export type Local<T> = Omit<LocalObject<T>, keyof ProxyMethods> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
[I in keyof TArguments]: ProxyOrClone<TArguments[I]>;

@@ -166,6 +160,6 @@ }) => MaybePromise<UnproxyOrClone<Unpromisify<TReturn>>> : unknown) & (T extends {

export declare const transferHandlers: Map<string, TransferHandler<unknown, unknown>>;
export declare function expose(obj: any, ep?: Endpoint): void;
export declare function expose(obj: any, ep?: Endpoint, allowedOrigins?: (string | RegExp)[]): void;
export declare function wrap<T>(ep: Endpoint, target?: any): Remote<T>;
export declare function transfer<T>(obj: T, transfers: Transferable[]): T;
export declare function proxy<T>(obj: T): T & ProxyMarked;
export declare function proxy<T extends {}>(obj: T): T & ProxyMarked;
export declare function windowEndpoint(w: PostMessageWithOrigin, context?: EventSource, targetOrigin?: string): Endpoint;
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -16,2 +9,3 @@ const proxyMarker = Symbol("Comlink.proxy");

const releaseProxy = Symbol("Comlink.releaseProxy");
const finalizer = Symbol("Comlink.finalizer");
const throwMarker = Symbol("Comlink.thrown");

@@ -70,3 +64,14 @@ const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function";

]);
function expose(obj, ep = self) {
function isAllowedOrigin(allowedOrigins, origin) {
for (const allowedOrigin of allowedOrigins) {
if (origin === allowedOrigin || allowedOrigin === "*") {
return true;
}
if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
return true;
}
}
return false;
}
function expose(obj, ep = self, allowedOrigins = ["*"]) {
ep.addEventListener("message", function callback(ev) {

@@ -76,2 +81,6 @@ if (!ev || !ev.data) {

}
if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);
return;
}
const { id, type, path } = Object.assign({ path: [] }, ev.data);

@@ -84,3 +93,3 @@ const argumentList = (ev.data.argumentList || []).map(fromWireValue);

switch (type) {
case "GET" /* GET */:
case "GET" /* MessageType.GET */:
{

@@ -90,3 +99,3 @@ returnValue = rawValue;

break;
case "SET" /* SET */:
case "SET" /* MessageType.SET */:
{

@@ -97,3 +106,3 @@ parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);

break;
case "APPLY" /* APPLY */:
case "APPLY" /* MessageType.APPLY */:
{

@@ -103,3 +112,3 @@ returnValue = rawValue.apply(parent, argumentList);

break;
case "CONSTRUCT" /* CONSTRUCT */:
case "CONSTRUCT" /* MessageType.CONSTRUCT */:
{

@@ -110,3 +119,3 @@ const value = new rawValue(...argumentList);

break;
case "ENDPOINT" /* ENDPOINT */:
case "ENDPOINT" /* MessageType.ENDPOINT */:
{

@@ -118,3 +127,3 @@ const { port1, port2 } = new MessageChannel();

break;
case "RELEASE" /* RELEASE */:
case "RELEASE" /* MessageType.RELEASE */:
{

@@ -138,7 +147,18 @@ returnValue = undefined;

ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
if (type === "RELEASE" /* RELEASE */) {
if (type === "RELEASE" /* MessageType.RELEASE */) {
// detach and deactive after sending release response above.
ep.removeEventListener("message", callback);
closeEndPoint(ep);
if (finalizer in obj && typeof obj[finalizer] === "function") {
obj[finalizer]();
}
}
})
.catch((error) => {
// Send Serialization Error To Caller
const [wireValue, transferables] = toWireValue({
value: new TypeError("Unserializable return value"),
[throwMarker]: 0,
});
ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
});

@@ -165,2 +185,30 @@ });

}
function releaseEndpoint(ep) {
return requestResponseMessage(ep, {
type: "RELEASE" /* MessageType.RELEASE */,
}).then(() => {
closeEndPoint(ep);
});
}
const proxyCounter = new WeakMap();
const proxyFinalizers = "FinalizationRegistry" in self &&
new FinalizationRegistry((ep) => {
const newCount = (proxyCounter.get(ep) || 0) - 1;
proxyCounter.set(ep, newCount);
if (newCount === 0) {
releaseEndpoint(ep);
}
});
function registerProxy(proxy, ep) {
const newCount = (proxyCounter.get(ep) || 0) + 1;
proxyCounter.set(ep, newCount);
if (proxyFinalizers) {
proxyFinalizers.register(proxy, ep, proxy);
}
}
function unregisterProxy(proxy) {
if (proxyFinalizers) {
proxyFinalizers.unregister(proxy);
}
}
function createProxy(ep, path = [], target = function () { }) {

@@ -173,9 +221,5 @@ let isProxyReleased = false;

return () => {
return requestResponseMessage(ep, {
type: "RELEASE" /* RELEASE */,
path: path.map((p) => p.toString()),
}).then(() => {
closeEndPoint(ep);
isProxyReleased = true;
});
unregisterProxy(proxy);
releaseEndpoint(ep);
isProxyReleased = true;
};

@@ -188,3 +232,3 @@ }

const r = requestResponseMessage(ep, {
type: "GET" /* GET */,
type: "GET" /* MessageType.GET */,
path: path.map((p) => p.toString()),

@@ -202,3 +246,3 @@ }).then(fromWireValue);

return requestResponseMessage(ep, {
type: "SET" /* SET */,
type: "SET" /* MessageType.SET */,
path: [...path, prop].map((p) => p.toString()),

@@ -213,3 +257,3 @@ value,

return requestResponseMessage(ep, {
type: "ENDPOINT" /* ENDPOINT */,
type: "ENDPOINT" /* MessageType.ENDPOINT */,
}).then(fromWireValue);

@@ -223,3 +267,3 @@ }

return requestResponseMessage(ep, {
type: "APPLY" /* APPLY */,
type: "APPLY" /* MessageType.APPLY */,
path: path.map((p) => p.toString()),

@@ -233,3 +277,3 @@ argumentList,

return requestResponseMessage(ep, {
type: "CONSTRUCT" /* CONSTRUCT */,
type: "CONSTRUCT" /* MessageType.CONSTRUCT */,
path: path.map((p) => p.toString()),

@@ -240,2 +284,3 @@ argumentList,

});
registerProxy(proxy, ep);
return proxy;

@@ -271,3 +316,3 @@ }

{
type: "HANDLER" /* HANDLER */,
type: "HANDLER" /* WireValueType.HANDLER */,
name,

@@ -282,3 +327,3 @@ value: serializedValue,

{
type: "RAW" /* RAW */,
type: "RAW" /* WireValueType.RAW */,
value,

@@ -291,5 +336,5 @@ },

switch (value.type) {
case "HANDLER" /* HANDLER */:
case "HANDLER" /* WireValueType.HANDLER */:
return transferHandlers.get(value.name).deserialize(value.value);
case "RAW" /* RAW */:
case "RAW" /* WireValueType.RAW */:
return value.value;

@@ -321,3 +366,3 @@ }

export { createEndpoint, expose, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };
export { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };
//# sourceMappingURL=comlink.js.map

@@ -1,2 +0,7 @@

const e=Symbol("Comlink.proxy"),t=Symbol("Comlink.endpoint"),n=Symbol("Comlink.releaseProxy"),r=Symbol("Comlink.thrown"),a=e=>"object"==typeof e&&null!==e||"function"==typeof e,s=new Map([["proxy",{canHandle:t=>a(t)&&t[e],serialize(e){const{port1:t,port2:n}=new MessageChannel;return o(e,t),[n,[n]]},deserialize:e=>(e.start(),c(e))}],["throw",{canHandle:e=>a(e)&&r in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function o(e,t=self){t.addEventListener("message",(function n(a){if(!a||!a.data)return;const{id:s,type:c,path:u}=Object.assign({path:[]},a.data),l=(a.data.argumentList||[]).map(E);let p;try{const t=u.slice(0,-1).reduce((e,t)=>e[t],e),n=u.reduce((e,t)=>e[t],e);switch(c){case"GET":p=n;break;case"SET":t[u.slice(-1)[0]]=E(a.data.value),p=!0;break;case"APPLY":p=n.apply(t,l);break;case"CONSTRUCT":p=d(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;o(e,n),p=m(t,[t])}break;case"RELEASE":p=void 0;break;default:return}}catch(e){p={value:e,[r]:0}}Promise.resolve(p).catch(e=>({value:e,[r]:0})).then(e=>{const[r,a]=g(e);t.postMessage(Object.assign(Object.assign({},r),{id:s}),a),"RELEASE"===c&&(t.removeEventListener("message",n),i(t))})})),t.start&&t.start()}function i(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function c(e,r){return function e(r,a=[],s=function(){}){let o=!1;const c=new Proxy(s,{get(t,s){if(u(o),s===n)return()=>h(r,{type:"RELEASE",path:a.map(e=>e.toString())}).then(()=>{i(r),o=!0});if("then"===s){if(0===a.length)return{then:()=>c};const e=h(r,{type:"GET",path:a.map(e=>e.toString())}).then(E);return e.then.bind(e)}return e(r,[...a,s])},set(e,t,n){u(o);const[s,i]=g(n);return h(r,{type:"SET",path:[...a,t].map(e=>e.toString()),value:s},i).then(E)},apply(n,s,i){u(o);const c=a[a.length-1];if(c===t)return h(r,{type:"ENDPOINT"}).then(E);if("bind"===c)return e(r,a.slice(0,-1));const[p,m]=l(i);return h(r,{type:"APPLY",path:a.map(e=>e.toString()),argumentList:p},m).then(E)},construct(e,t){u(o);const[n,s]=l(t);return h(r,{type:"CONSTRUCT",path:a.map(e=>e.toString()),argumentList:n},s).then(E)}});return c}(e,[],r)}function u(e){if(e)throw new Error("Proxy has been released and is not useable")}function l(e){const t=e.map(g);return[t.map(e=>e[0]),(n=t.map(e=>e[1]),Array.prototype.concat.apply([],n))];var n}const p=new WeakMap;function m(e,t){return p.set(e,t),e}function d(t){return Object.assign(t,{[e]:!0})}function f(e,t=self,n="*"){return{postMessage:(t,r)=>e.postMessage(t,n,r),addEventListener:t.addEventListener.bind(t),removeEventListener:t.removeEventListener.bind(t)}}function g(e){for(const[t,n]of s)if(n.canHandle(e)){const[r,a]=n.serialize(e);return[{type:"HANDLER",name:t,value:r},a]}return[{type:"RAW",value:e},p.get(e)||[]]}function E(e){switch(e.type){case"HANDLER":return s.get(e.name).deserialize(e.value);case"RAW":return e.value}}function h(e,t,n){return new Promise(r=>{const a=new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-");e.addEventListener("message",(function t(n){n.data&&n.data.id&&n.data.id===a&&(e.removeEventListener("message",t),r(n.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:a},t),n)})}export{t as createEndpoint,o as expose,d as proxy,e as proxyMarker,n as releaseProxy,m as transfer,s as transferHandlers,f as windowEndpoint,c as wrap};
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
const e=Symbol("Comlink.proxy"),t=Symbol("Comlink.endpoint"),n=Symbol("Comlink.releaseProxy"),r=Symbol("Comlink.finalizer"),a=Symbol("Comlink.thrown"),s=e=>"object"==typeof e&&null!==e||"function"==typeof e,o=new Map([["proxy",{canHandle:t=>s(t)&&t[e],serialize(e){const{port1:t,port2:n}=new MessageChannel;return i(e,t),[n,[n]]},deserialize:e=>(e.start(),u(e))}],["throw",{canHandle:e=>s(e)&&a in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function i(e,t=self,n=["*"]){t.addEventListener("message",(function s(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:u,type:l,path:p}=Object.assign({path:[]},o.data),f=(o.data.argumentList||[]).map(w);let g;try{const t=p.slice(0,-1).reduce(((e,t)=>e[t]),e),n=p.reduce(((e,t)=>e[t]),e);switch(l){case"GET":g=n;break;case"SET":t[p.slice(-1)[0]]=w(o.data.value),g=!0;break;case"APPLY":g=n.apply(t,f);break;case"CONSTRUCT":g=h(new n(...f));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;i(e,n),g=y(t,[t])}break;case"RELEASE":g=void 0;break;default:return}}catch(e){g={value:e,[a]:0}}Promise.resolve(g).catch((e=>({value:e,[a]:0}))).then((n=>{const[a,o]=b(n);t.postMessage(Object.assign(Object.assign({},a),{id:u}),o),"RELEASE"===l&&(t.removeEventListener("message",s),c(t),r in e&&"function"==typeof e[r]&&e[r]())})).catch((e=>{const[n,r]=b({value:new TypeError("Unserializable return value"),[a]:0});t.postMessage(Object.assign(Object.assign({},n),{id:u}),r)}))})),t.start&&t.start()}function c(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function u(e,t){return m(e,[],t)}function l(e){if(e)throw new Error("Proxy has been released and is not useable")}function p(e){return L(e,{type:"RELEASE"}).then((()=>{c(e)}))}const f=new WeakMap,g="FinalizationRegistry"in self&&new FinalizationRegistry((e=>{const t=(f.get(e)||0)-1;f.set(e,t),0===t&&p(e)}));function m(e,r=[],a=function(){}){let s=!1;const o=new Proxy(a,{get(t,a){if(l(s),a===n)return()=>{!function(e){g&&g.unregister(e)}(o),p(e),s=!0};if("then"===a){if(0===r.length)return{then:()=>o};const t=L(e,{type:"GET",path:r.map((e=>e.toString()))}).then(w);return t.then.bind(t)}return m(e,[...r,a])},set(t,n,a){l(s);const[o,i]=b(a);return L(e,{type:"SET",path:[...r,n].map((e=>e.toString())),value:o},i).then(w)},apply(n,a,o){l(s);const i=r[r.length-1];if(i===t)return L(e,{type:"ENDPOINT"}).then(w);if("bind"===i)return m(e,r.slice(0,-1));const[c,u]=d(o);return L(e,{type:"APPLY",path:r.map((e=>e.toString())),argumentList:c},u).then(w)},construct(t,n){l(s);const[a,o]=d(n);return L(e,{type:"CONSTRUCT",path:r.map((e=>e.toString())),argumentList:a},o).then(w)}});return function(e,t){const n=(f.get(t)||0)+1;f.set(t,n),g&&g.register(e,t,e)}(o,e),o}function d(e){const t=e.map(b);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const E=new WeakMap;function y(e,t){return E.set(e,t),e}function h(t){return Object.assign(t,{[e]:!0})}function v(e,t=self,n="*"){return{postMessage:(t,r)=>e.postMessage(t,n,r),addEventListener:t.addEventListener.bind(t),removeEventListener:t.removeEventListener.bind(t)}}function b(e){for(const[t,n]of o)if(n.canHandle(e)){const[r,a]=n.serialize(e);return[{type:"HANDLER",name:t,value:r},a]}return[{type:"RAW",value:e},E.get(e)||[]]}function w(e){switch(e.type){case"HANDLER":return o.get(e.name).deserialize(e.value);case"RAW":return e.value}}function L(e,t,n){return new Promise((r=>{const a=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");e.addEventListener("message",(function t(n){n.data&&n.data.id&&n.data.id===a&&(e.removeEventListener("message",t),r(n.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:a},t),n)}))}export{t as createEndpoint,i as expose,r as finalizer,h as proxy,e as proxyMarker,n as releaseProxy,y as transfer,o as transferHandlers,v as windowEndpoint,u as wrap};
//# sourceMappingURL=comlink.min.js.map
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -13,0 +6,0 @@ import { Endpoint } from "./protocol";

/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -41,4 +34,4 @@ export interface EventSource {

}
export declare type WireValue = RawWireValue | HandlerWireValue;
export declare type MessageID = string;
export type WireValue = RawWireValue | HandlerWireValue;
export type MessageID = string;
export declare const enum MessageType {

@@ -82,4 +75,3 @@ GET = "GET",

type: MessageType.RELEASE;
path: string[];
}
export declare type Message = GetMessage | SetMessage | ApplyMessage | ConstructMessage | EndpointMessage | ReleaseMessage;
export type Message = GetMessage | SetMessage | ApplyMessage | ConstructMessage | EndpointMessage | ReleaseMessage;
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { Endpoint, EventSource, PostMessageWithOrigin } from "./protocol";
export { Endpoint };
export type { Endpoint };
export declare const proxyMarker: unique symbol;
export declare const createEndpoint: unique symbol;
export declare const releaseProxy: unique symbol;
export declare const finalizer: unique symbol;
/**

@@ -31,3 +25,3 @@ * Interface of values that were marked to be proxied with `comlink.proxy()`.

*/
declare type Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;
type Promisify<T> = T extends Promise<unknown> ? T : Promise<T>;
/**

@@ -39,3 +33,3 @@ * Takes a type that may be Promise and unwraps the Promise type.

*/
declare type Unpromisify<P> = P extends Promise<infer T> ? T : P;
type Unpromisify<P> = P extends Promise<infer T> ? T : P;
/**

@@ -47,3 +41,3 @@ * Takes the raw type of a remote property and returns the type that is visible to the local thread on the proxy.

*/
declare type RemoteProperty<T> = T extends Function | ProxyMarked ? Remote<T> : Promisify<T>;
type RemoteProperty<T> = T extends Function | ProxyMarked ? Remote<T> : Promisify<T>;
/**

@@ -58,11 +52,11 @@ * Takes the raw type of a property as a remote thread would see it through a proxy (e.g. when passed in as a function

*/
declare type LocalProperty<T> = T extends Function | ProxyMarked ? Local<T> : Unpromisify<T>;
type LocalProperty<T> = T extends Function | ProxyMarked ? Local<T> : Unpromisify<T>;
/**
* Proxies `T` if it is a `ProxyMarked`, clones it otherwise (as handled by structured cloning and transfer handlers).
*/
export declare type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;
export type ProxyOrClone<T> = T extends ProxyMarked ? Remote<T> : T;
/**
* Inverse of `ProxyOrClone<T>`.
*/
export declare type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked> ? Local<T> : T;
export type UnproxyOrClone<T> = T extends RemoteObject<ProxyMarked> ? Local<T> : T;
/**

@@ -76,3 +70,3 @@ * Takes the raw type of a remote object in the other thread and returns the type as it is visible to the local thread

*/
export declare type RemoteObject<T> = {
export type RemoteObject<T> = {
[P in keyof T]: RemoteProperty<T[P]>;

@@ -90,3 +84,3 @@ };

*/
export declare type LocalObject<T> = {
export type LocalObject<T> = {
[P in keyof T]: LocalProperty<T[P]>;

@@ -105,3 +99,3 @@ };

*/
export declare type Remote<T> = RemoteObject<T> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
export type Remote<T> = RemoteObject<T> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
[I in keyof TArguments]: UnproxyOrClone<TArguments[I]>;

@@ -118,3 +112,3 @@ }) => Promisify<ProxyOrClone<Unpromisify<TReturn>>> : unknown) & (T extends {

*/
declare type MaybePromise<T> = Promise<T> | T;
type MaybePromise<T> = Promise<T> | T;
/**

@@ -126,3 +120,3 @@ * Takes the raw type of a remote object, function or class as a remote thread would see it through a proxy (e.g. when

*/
export declare type Local<T> = Omit<LocalObject<T>, keyof ProxyMethods> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
export type Local<T> = Omit<LocalObject<T>, keyof ProxyMethods> & (T extends (...args: infer TArguments) => infer TReturn ? (...args: {
[I in keyof TArguments]: ProxyOrClone<TArguments[I]>;

@@ -166,6 +160,6 @@ }) => MaybePromise<UnproxyOrClone<Unpromisify<TReturn>>> : unknown) & (T extends {

export declare const transferHandlers: Map<string, TransferHandler<unknown, unknown>>;
export declare function expose(obj: any, ep?: Endpoint): void;
export declare function expose(obj: any, ep?: Endpoint, allowedOrigins?: (string | RegExp)[]): void;
export declare function wrap<T>(ep: Endpoint, target?: any): Remote<T>;
export declare function transfer<T>(obj: T, transfers: Transferable[]): T;
export declare function proxy<T>(obj: T): T & ProxyMarked;
export declare function proxy<T extends {}>(obj: T): T & ProxyMarked;
export declare function windowEndpoint(w: PostMessageWithOrigin, context?: EventSource, targetOrigin?: string): Endpoint;
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.Comlink = {}));
}(this, (function (exports) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Comlink = {}));
})(this, (function (exports) { 'use strict';
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const proxyMarker = Symbol("Comlink.proxy");
const createEndpoint = Symbol("Comlink.endpoint");
const releaseProxy = Symbol("Comlink.releaseProxy");
const throwMarker = Symbol("Comlink.thrown");
const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function";
/**
* Internal transfer handle to handle objects marked to proxy.
*/
const proxyTransferHandler = {
canHandle: (val) => isObject(val) && val[proxyMarker],
serialize(obj) {
const { port1, port2 } = new MessageChannel();
expose(obj, port1);
return [port2, [port2]];
},
deserialize(port) {
port.start();
return wrap(port);
},
};
/**
* Internal transfer handler to handle thrown exceptions.
*/
const throwTransferHandler = {
canHandle: (value) => isObject(value) && throwMarker in value,
serialize({ value }) {
let serialized;
if (value instanceof Error) {
serialized = {
isError: true,
value: {
message: value.message,
name: value.name,
stack: value.stack,
},
};
}
else {
serialized = { isError: false, value };
}
return [serialized, []];
},
deserialize(serialized) {
if (serialized.isError) {
throw Object.assign(new Error(serialized.value.message), serialized.value);
}
throw serialized.value;
},
};
/**
* Allows customizing the serialization of certain values.
*/
const transferHandlers = new Map([
["proxy", proxyTransferHandler],
["throw", throwTransferHandler],
]);
function expose(obj, ep = self) {
ep.addEventListener("message", function callback(ev) {
if (!ev || !ev.data) {
return;
}
const { id, type, path } = Object.assign({ path: [] }, ev.data);
const argumentList = (ev.data.argumentList || []).map(fromWireValue);
let returnValue;
try {
const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);
const rawValue = path.reduce((obj, prop) => obj[prop], obj);
switch (type) {
case "GET" /* GET */:
{
returnValue = rawValue;
}
break;
case "SET" /* SET */:
{
parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
returnValue = true;
}
break;
case "APPLY" /* APPLY */:
{
returnValue = rawValue.apply(parent, argumentList);
}
break;
case "CONSTRUCT" /* CONSTRUCT */:
{
const value = new rawValue(...argumentList);
returnValue = proxy(value);
}
break;
case "ENDPOINT" /* ENDPOINT */:
{
const { port1, port2 } = new MessageChannel();
expose(obj, port2);
returnValue = transfer(port1, [port1]);
}
break;
case "RELEASE" /* RELEASE */:
{
returnValue = undefined;
}
break;
default:
return;
}
}
catch (value) {
returnValue = { value, [throwMarker]: 0 };
}
Promise.resolve(returnValue)
.catch((value) => {
return { value, [throwMarker]: 0 };
})
.then((returnValue) => {
const [wireValue, transferables] = toWireValue(returnValue);
ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
if (type === "RELEASE" /* RELEASE */) {
// detach and deactive after sending release response above.
ep.removeEventListener("message", callback);
closeEndPoint(ep);
}
});
});
if (ep.start) {
ep.start();
}
}
function isMessagePort(endpoint) {
return endpoint.constructor.name === "MessagePort";
}
function closeEndPoint(endpoint) {
if (isMessagePort(endpoint))
endpoint.close();
}
function wrap(ep, target) {
return createProxy(ep, [], target);
}
function throwIfProxyReleased(isReleased) {
if (isReleased) {
throw new Error("Proxy has been released and is not useable");
}
}
function createProxy(ep, path = [], target = function () { }) {
let isProxyReleased = false;
const proxy = new Proxy(target, {
get(_target, prop) {
throwIfProxyReleased(isProxyReleased);
if (prop === releaseProxy) {
return () => {
return requestResponseMessage(ep, {
type: "RELEASE" /* RELEASE */,
path: path.map((p) => p.toString()),
}).then(() => {
closeEndPoint(ep);
isProxyReleased = true;
});
};
}
if (prop === "then") {
if (path.length === 0) {
return { then: () => proxy };
}
const r = requestResponseMessage(ep, {
type: "GET" /* GET */,
path: path.map((p) => p.toString()),
}).then(fromWireValue);
return r.then.bind(r);
}
return createProxy(ep, [...path, prop]);
},
set(_target, prop, rawValue) {
throwIfProxyReleased(isProxyReleased);
// FIXME: ES6 Proxy Handler `set` methods are supposed to return a
// boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
const [value, transferables] = toWireValue(rawValue);
return requestResponseMessage(ep, {
type: "SET" /* SET */,
path: [...path, prop].map((p) => p.toString()),
value,
}, transferables).then(fromWireValue);
},
apply(_target, _thisArg, rawArgumentList) {
throwIfProxyReleased(isProxyReleased);
const last = path[path.length - 1];
if (last === createEndpoint) {
return requestResponseMessage(ep, {
type: "ENDPOINT" /* ENDPOINT */,
}).then(fromWireValue);
}
// We just pretend that `bind()` didn’t happen.
if (last === "bind") {
return createProxy(ep, path.slice(0, -1));
}
const [argumentList, transferables] = processArguments(rawArgumentList);
return requestResponseMessage(ep, {
type: "APPLY" /* APPLY */,
path: path.map((p) => p.toString()),
argumentList,
}, transferables).then(fromWireValue);
},
construct(_target, rawArgumentList) {
throwIfProxyReleased(isProxyReleased);
const [argumentList, transferables] = processArguments(rawArgumentList);
return requestResponseMessage(ep, {
type: "CONSTRUCT" /* CONSTRUCT */,
path: path.map((p) => p.toString()),
argumentList,
}, transferables).then(fromWireValue);
},
});
return proxy;
}
function myFlat(arr) {
return Array.prototype.concat.apply([], arr);
}
function processArguments(argumentList) {
const processed = argumentList.map(toWireValue);
return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
}
const transferCache = new WeakMap();
function transfer(obj, transfers) {
transferCache.set(obj, transfers);
return obj;
}
function proxy(obj) {
return Object.assign(obj, { [proxyMarker]: true });
}
function windowEndpoint(w, context = self, targetOrigin = "*") {
return {
postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),
addEventListener: context.addEventListener.bind(context),
removeEventListener: context.removeEventListener.bind(context),
};
}
function toWireValue(value) {
for (const [name, handler] of transferHandlers) {
if (handler.canHandle(value)) {
const [serializedValue, transferables] = handler.serialize(value);
return [
{
type: "HANDLER" /* HANDLER */,
name,
value: serializedValue,
},
transferables,
];
}
}
return [
{
type: "RAW" /* RAW */,
value,
},
transferCache.get(value) || [],
];
}
function fromWireValue(value) {
switch (value.type) {
case "HANDLER" /* HANDLER */:
return transferHandlers.get(value.name).deserialize(value.value);
case "RAW" /* RAW */:
return value.value;
}
}
function requestResponseMessage(ep, msg, transfers) {
return new Promise((resolve) => {
const id = generateUUID();
ep.addEventListener("message", function l(ev) {
if (!ev.data || !ev.data.id || ev.data.id !== id) {
return;
}
ep.removeEventListener("message", l);
resolve(ev.data);
});
if (ep.start) {
ep.start();
}
ep.postMessage(Object.assign({ id }, msg), transfers);
});
}
function generateUUID() {
return new Array(4)
.fill(0)
.map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))
.join("-");
}
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
const proxyMarker = Symbol("Comlink.proxy");
const createEndpoint = Symbol("Comlink.endpoint");
const releaseProxy = Symbol("Comlink.releaseProxy");
const finalizer = Symbol("Comlink.finalizer");
const throwMarker = Symbol("Comlink.thrown");
const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function";
/**
* Internal transfer handle to handle objects marked to proxy.
*/
const proxyTransferHandler = {
canHandle: (val) => isObject(val) && val[proxyMarker],
serialize(obj) {
const { port1, port2 } = new MessageChannel();
expose(obj, port1);
return [port2, [port2]];
},
deserialize(port) {
port.start();
return wrap(port);
},
};
/**
* Internal transfer handler to handle thrown exceptions.
*/
const throwTransferHandler = {
canHandle: (value) => isObject(value) && throwMarker in value,
serialize({ value }) {
let serialized;
if (value instanceof Error) {
serialized = {
isError: true,
value: {
message: value.message,
name: value.name,
stack: value.stack,
},
};
}
else {
serialized = { isError: false, value };
}
return [serialized, []];
},
deserialize(serialized) {
if (serialized.isError) {
throw Object.assign(new Error(serialized.value.message), serialized.value);
}
throw serialized.value;
},
};
/**
* Allows customizing the serialization of certain values.
*/
const transferHandlers = new Map([
["proxy", proxyTransferHandler],
["throw", throwTransferHandler],
]);
function isAllowedOrigin(allowedOrigins, origin) {
for (const allowedOrigin of allowedOrigins) {
if (origin === allowedOrigin || allowedOrigin === "*") {
return true;
}
if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
return true;
}
}
return false;
}
function expose(obj, ep = self, allowedOrigins = ["*"]) {
ep.addEventListener("message", function callback(ev) {
if (!ev || !ev.data) {
return;
}
if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);
return;
}
const { id, type, path } = Object.assign({ path: [] }, ev.data);
const argumentList = (ev.data.argumentList || []).map(fromWireValue);
let returnValue;
try {
const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);
const rawValue = path.reduce((obj, prop) => obj[prop], obj);
switch (type) {
case "GET" /* MessageType.GET */:
{
returnValue = rawValue;
}
break;
case "SET" /* MessageType.SET */:
{
parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
returnValue = true;
}
break;
case "APPLY" /* MessageType.APPLY */:
{
returnValue = rawValue.apply(parent, argumentList);
}
break;
case "CONSTRUCT" /* MessageType.CONSTRUCT */:
{
const value = new rawValue(...argumentList);
returnValue = proxy(value);
}
break;
case "ENDPOINT" /* MessageType.ENDPOINT */:
{
const { port1, port2 } = new MessageChannel();
expose(obj, port2);
returnValue = transfer(port1, [port1]);
}
break;
case "RELEASE" /* MessageType.RELEASE */:
{
returnValue = undefined;
}
break;
default:
return;
}
}
catch (value) {
returnValue = { value, [throwMarker]: 0 };
}
Promise.resolve(returnValue)
.catch((value) => {
return { value, [throwMarker]: 0 };
})
.then((returnValue) => {
const [wireValue, transferables] = toWireValue(returnValue);
ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
if (type === "RELEASE" /* MessageType.RELEASE */) {
// detach and deactive after sending release response above.
ep.removeEventListener("message", callback);
closeEndPoint(ep);
if (finalizer in obj && typeof obj[finalizer] === "function") {
obj[finalizer]();
}
}
})
.catch((error) => {
// Send Serialization Error To Caller
const [wireValue, transferables] = toWireValue({
value: new TypeError("Unserializable return value"),
[throwMarker]: 0,
});
ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
});
});
if (ep.start) {
ep.start();
}
}
function isMessagePort(endpoint) {
return endpoint.constructor.name === "MessagePort";
}
function closeEndPoint(endpoint) {
if (isMessagePort(endpoint))
endpoint.close();
}
function wrap(ep, target) {
return createProxy(ep, [], target);
}
function throwIfProxyReleased(isReleased) {
if (isReleased) {
throw new Error("Proxy has been released and is not useable");
}
}
function releaseEndpoint(ep) {
return requestResponseMessage(ep, {
type: "RELEASE" /* MessageType.RELEASE */,
}).then(() => {
closeEndPoint(ep);
});
}
const proxyCounter = new WeakMap();
const proxyFinalizers = "FinalizationRegistry" in self &&
new FinalizationRegistry((ep) => {
const newCount = (proxyCounter.get(ep) || 0) - 1;
proxyCounter.set(ep, newCount);
if (newCount === 0) {
releaseEndpoint(ep);
}
});
function registerProxy(proxy, ep) {
const newCount = (proxyCounter.get(ep) || 0) + 1;
proxyCounter.set(ep, newCount);
if (proxyFinalizers) {
proxyFinalizers.register(proxy, ep, proxy);
}
}
function unregisterProxy(proxy) {
if (proxyFinalizers) {
proxyFinalizers.unregister(proxy);
}
}
function createProxy(ep, path = [], target = function () { }) {
let isProxyReleased = false;
const proxy = new Proxy(target, {
get(_target, prop) {
throwIfProxyReleased(isProxyReleased);
if (prop === releaseProxy) {
return () => {
unregisterProxy(proxy);
releaseEndpoint(ep);
isProxyReleased = true;
};
}
if (prop === "then") {
if (path.length === 0) {
return { then: () => proxy };
}
const r = requestResponseMessage(ep, {
type: "GET" /* MessageType.GET */,
path: path.map((p) => p.toString()),
}).then(fromWireValue);
return r.then.bind(r);
}
return createProxy(ep, [...path, prop]);
},
set(_target, prop, rawValue) {
throwIfProxyReleased(isProxyReleased);
// FIXME: ES6 Proxy Handler `set` methods are supposed to return a
// boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
const [value, transferables] = toWireValue(rawValue);
return requestResponseMessage(ep, {
type: "SET" /* MessageType.SET */,
path: [...path, prop].map((p) => p.toString()),
value,
}, transferables).then(fromWireValue);
},
apply(_target, _thisArg, rawArgumentList) {
throwIfProxyReleased(isProxyReleased);
const last = path[path.length - 1];
if (last === createEndpoint) {
return requestResponseMessage(ep, {
type: "ENDPOINT" /* MessageType.ENDPOINT */,
}).then(fromWireValue);
}
// We just pretend that `bind()` didn’t happen.
if (last === "bind") {
return createProxy(ep, path.slice(0, -1));
}
const [argumentList, transferables] = processArguments(rawArgumentList);
return requestResponseMessage(ep, {
type: "APPLY" /* MessageType.APPLY */,
path: path.map((p) => p.toString()),
argumentList,
}, transferables).then(fromWireValue);
},
construct(_target, rawArgumentList) {
throwIfProxyReleased(isProxyReleased);
const [argumentList, transferables] = processArguments(rawArgumentList);
return requestResponseMessage(ep, {
type: "CONSTRUCT" /* MessageType.CONSTRUCT */,
path: path.map((p) => p.toString()),
argumentList,
}, transferables).then(fromWireValue);
},
});
registerProxy(proxy, ep);
return proxy;
}
function myFlat(arr) {
return Array.prototype.concat.apply([], arr);
}
function processArguments(argumentList) {
const processed = argumentList.map(toWireValue);
return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
}
const transferCache = new WeakMap();
function transfer(obj, transfers) {
transferCache.set(obj, transfers);
return obj;
}
function proxy(obj) {
return Object.assign(obj, { [proxyMarker]: true });
}
function windowEndpoint(w, context = self, targetOrigin = "*") {
return {
postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),
addEventListener: context.addEventListener.bind(context),
removeEventListener: context.removeEventListener.bind(context),
};
}
function toWireValue(value) {
for (const [name, handler] of transferHandlers) {
if (handler.canHandle(value)) {
const [serializedValue, transferables] = handler.serialize(value);
return [
{
type: "HANDLER" /* WireValueType.HANDLER */,
name,
value: serializedValue,
},
transferables,
];
}
}
return [
{
type: "RAW" /* WireValueType.RAW */,
value,
},
transferCache.get(value) || [],
];
}
function fromWireValue(value) {
switch (value.type) {
case "HANDLER" /* WireValueType.HANDLER */:
return transferHandlers.get(value.name).deserialize(value.value);
case "RAW" /* WireValueType.RAW */:
return value.value;
}
}
function requestResponseMessage(ep, msg, transfers) {
return new Promise((resolve) => {
const id = generateUUID();
ep.addEventListener("message", function l(ev) {
if (!ev.data || !ev.data.id || ev.data.id !== id) {
return;
}
ep.removeEventListener("message", l);
resolve(ev.data);
});
if (ep.start) {
ep.start();
}
ep.postMessage(Object.assign({ id }, msg), transfers);
});
}
function generateUUID() {
return new Array(4)
.fill(0)
.map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))
.join("-");
}
exports.createEndpoint = createEndpoint;
exports.expose = expose;
exports.proxy = proxy;
exports.proxyMarker = proxyMarker;
exports.releaseProxy = releaseProxy;
exports.transfer = transfer;
exports.transferHandlers = transferHandlers;
exports.windowEndpoint = windowEndpoint;
exports.wrap = wrap;
exports.createEndpoint = createEndpoint;
exports.expose = expose;
exports.finalizer = finalizer;
exports.proxy = proxy;
exports.proxyMarker = proxyMarker;
exports.releaseProxy = releaseProxy;
exports.transfer = transfer;
exports.transferHandlers = transferHandlers;
exports.windowEndpoint = windowEndpoint;
exports.wrap = wrap;
Object.defineProperty(exports, '__esModule', { value: true });
})));
}));
//# sourceMappingURL=comlink.js.map

@@ -1,2 +0,7 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).Comlink={})}(this,(function(e){"use strict";const t=Symbol("Comlink.proxy"),n=Symbol("Comlink.endpoint"),r=Symbol("Comlink.releaseProxy"),a=Symbol("Comlink.thrown"),s=e=>"object"==typeof e&&null!==e||"function"==typeof e,o=new Map([["proxy",{canHandle:e=>s(e)&&e[t],serialize(e){const{port1:t,port2:n}=new MessageChannel;return i(e,t),[n,[n]]},deserialize:e=>(e.start(),u(e))}],["throw",{canHandle:e=>s(e)&&a in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function i(e,t=self){t.addEventListener("message",(function n(r){if(!r||!r.data)return;const{id:s,type:o,path:u}=Object.assign({path:[]},r.data),l=(r.data.argumentList||[]).map(y);let p;try{const t=u.slice(0,-1).reduce((e,t)=>e[t],e),n=u.reduce((e,t)=>e[t],e);switch(o){case"GET":p=n;break;case"SET":t[u.slice(-1)[0]]=y(r.data.value),p=!0;break;case"APPLY":p=n.apply(t,l);break;case"CONSTRUCT":p=m(new n(...l));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;i(e,n),p=f(t,[t])}break;case"RELEASE":p=void 0;break;default:return}}catch(e){p={value:e,[a]:0}}Promise.resolve(p).catch(e=>({value:e,[a]:0})).then(e=>{const[r,a]=E(e);t.postMessage(Object.assign(Object.assign({},r),{id:s}),a),"RELEASE"===o&&(t.removeEventListener("message",n),c(t))})})),t.start&&t.start()}function c(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function u(e,t){return function e(t,a=[],s=function(){}){let o=!1;const i=new Proxy(s,{get(n,s){if(l(o),s===r)return()=>g(t,{type:"RELEASE",path:a.map(e=>e.toString())}).then(()=>{c(t),o=!0});if("then"===s){if(0===a.length)return{then:()=>i};const e=g(t,{type:"GET",path:a.map(e=>e.toString())}).then(y);return e.then.bind(e)}return e(t,[...a,s])},set(e,n,r){l(o);const[s,i]=E(r);return g(t,{type:"SET",path:[...a,n].map(e=>e.toString()),value:s},i).then(y)},apply(r,s,i){l(o);const c=a[a.length-1];if(c===n)return g(t,{type:"ENDPOINT"}).then(y);if("bind"===c)return e(t,a.slice(0,-1));const[u,d]=p(i);return g(t,{type:"APPLY",path:a.map(e=>e.toString()),argumentList:u},d).then(y)},construct(e,n){l(o);const[r,s]=p(n);return g(t,{type:"CONSTRUCT",path:a.map(e=>e.toString()),argumentList:r},s).then(y)}});return i}(e,[],t)}function l(e){if(e)throw new Error("Proxy has been released and is not useable")}function p(e){const t=e.map(E);return[t.map(e=>e[0]),(n=t.map(e=>e[1]),Array.prototype.concat.apply([],n))];var n}const d=new WeakMap;function f(e,t){return d.set(e,t),e}function m(e){return Object.assign(e,{[t]:!0})}function E(e){for(const[t,n]of o)if(n.canHandle(e)){const[r,a]=n.serialize(e);return[{type:"HANDLER",name:t,value:r},a]}return[{type:"RAW",value:e},d.get(e)||[]]}function y(e){switch(e.type){case"HANDLER":return o.get(e.name).deserialize(e.value);case"RAW":return e.value}}function g(e,t,n){return new Promise(r=>{const a=new Array(4).fill(0).map(()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16)).join("-");e.addEventListener("message",(function t(n){n.data&&n.data.id&&n.data.id===a&&(e.removeEventListener("message",t),r(n.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:a},t),n)})}e.createEndpoint=n,e.expose=i,e.proxy=m,e.proxyMarker=t,e.releaseProxy=r,e.transfer=f,e.transferHandlers=o,e.windowEndpoint=function(e,t=self,n="*"){return{postMessage:(t,r)=>e.postMessage(t,n,r),addEventListener:t.addEventListener.bind(t),removeEventListener:t.removeEventListener.bind(t)}},e.wrap=u,Object.defineProperty(e,"__esModule",{value:!0})}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Comlink={})}(this,(function(e){"use strict";
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/const t=Symbol("Comlink.proxy"),n=Symbol("Comlink.endpoint"),r=Symbol("Comlink.releaseProxy"),a=Symbol("Comlink.finalizer"),s=Symbol("Comlink.thrown"),o=e=>"object"==typeof e&&null!==e||"function"==typeof e,i=new Map([["proxy",{canHandle:e=>o(e)&&e[t],serialize(e){const{port1:t,port2:n}=new MessageChannel;return c(e,t),[n,[n]]},deserialize:e=>(e.start(),l(e))}],["throw",{canHandle:e=>o(e)&&s in e,serialize({value:e}){let t;return t=e instanceof Error?{isError:!0,value:{message:e.message,name:e.name,stack:e.stack}}:{isError:!1,value:e},[t,[]]},deserialize(e){if(e.isError)throw Object.assign(new Error(e.value.message),e.value);throw e.value}}]]);function c(e,t=self,n=["*"]){t.addEventListener("message",(function r(o){if(!o||!o.data)return;if(!function(e,t){for(const n of e){if(t===n||"*"===n)return!0;if(n instanceof RegExp&&n.test(t))return!0}return!1}(n,o.origin))return void console.warn(`Invalid origin '${o.origin}' for comlink proxy`);const{id:i,type:l,path:f}=Object.assign({path:[]},o.data),p=(o.data.argumentList||[]).map(w);let d;try{const t=f.slice(0,-1).reduce(((e,t)=>e[t]),e),n=f.reduce(((e,t)=>e[t]),e);switch(l){case"GET":d=n;break;case"SET":t[f.slice(-1)[0]]=w(o.data.value),d=!0;break;case"APPLY":d=n.apply(t,p);break;case"CONSTRUCT":d=v(new n(...p));break;case"ENDPOINT":{const{port1:t,port2:n}=new MessageChannel;c(e,n),d=h(t,[t])}break;case"RELEASE":d=void 0;break;default:return}}catch(e){d={value:e,[s]:0}}Promise.resolve(d).catch((e=>({value:e,[s]:0}))).then((n=>{const[s,o]=b(n);t.postMessage(Object.assign(Object.assign({},s),{id:i}),o),"RELEASE"===l&&(t.removeEventListener("message",r),u(t),a in e&&"function"==typeof e[a]&&e[a]())})).catch((e=>{const[n,r]=b({value:new TypeError("Unserializable return value"),[s]:0});t.postMessage(Object.assign(Object.assign({},n),{id:i}),r)}))})),t.start&&t.start()}function u(e){(function(e){return"MessagePort"===e.constructor.name})(e)&&e.close()}function l(e,t){return m(e,[],t)}function f(e){if(e)throw new Error("Proxy has been released and is not useable")}function p(e){return k(e,{type:"RELEASE"}).then((()=>{u(e)}))}const d=new WeakMap,g="FinalizationRegistry"in self&&new FinalizationRegistry((e=>{const t=(d.get(e)||0)-1;d.set(e,t),0===t&&p(e)}));function m(e,t=[],a=function(){}){let s=!1;const o=new Proxy(a,{get(n,a){if(f(s),a===r)return()=>{!function(e){g&&g.unregister(e)}(o),p(e),s=!0};if("then"===a){if(0===t.length)return{then:()=>o};const n=k(e,{type:"GET",path:t.map((e=>e.toString()))}).then(w);return n.then.bind(n)}return m(e,[...t,a])},set(n,r,a){f(s);const[o,i]=b(a);return k(e,{type:"SET",path:[...t,r].map((e=>e.toString())),value:o},i).then(w)},apply(r,a,o){f(s);const i=t[t.length-1];if(i===n)return k(e,{type:"ENDPOINT"}).then(w);if("bind"===i)return m(e,t.slice(0,-1));const[c,u]=y(o);return k(e,{type:"APPLY",path:t.map((e=>e.toString())),argumentList:c},u).then(w)},construct(n,r){f(s);const[a,o]=y(r);return k(e,{type:"CONSTRUCT",path:t.map((e=>e.toString())),argumentList:a},o).then(w)}});return function(e,t){const n=(d.get(t)||0)+1;d.set(t,n),g&&g.register(e,t,e)}(o,e),o}function y(e){const t=e.map(b);return[t.map((e=>e[0])),(n=t.map((e=>e[1])),Array.prototype.concat.apply([],n))];var n}const E=new WeakMap;function h(e,t){return E.set(e,t),e}function v(e){return Object.assign(e,{[t]:!0})}function b(e){for(const[t,n]of i)if(n.canHandle(e)){const[r,a]=n.serialize(e);return[{type:"HANDLER",name:t,value:r},a]}return[{type:"RAW",value:e},E.get(e)||[]]}function w(e){switch(e.type){case"HANDLER":return i.get(e.name).deserialize(e.value);case"RAW":return e.value}}function k(e,t,n){return new Promise((r=>{const a=new Array(4).fill(0).map((()=>Math.floor(Math.random()*Number.MAX_SAFE_INTEGER).toString(16))).join("-");e.addEventListener("message",(function t(n){n.data&&n.data.id&&n.data.id===a&&(e.removeEventListener("message",t),r(n.data))})),e.start&&e.start(),e.postMessage(Object.assign({id:a},t),n)}))}e.createEndpoint=n,e.expose=c,e.finalizer=a,e.proxy=v,e.proxyMarker=t,e.releaseProxy=r,e.transfer=h,e.transferHandlers=i,e.windowEndpoint=function(e,t=self,n="*"){return{postMessage:(t,r)=>e.postMessage(t,n,r),addEventListener:t.addEventListener.bind(t),removeEventListener:t.removeEventListener.bind(t)}},e.wrap=l}));
//# sourceMappingURL=comlink.min.js.map
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -13,0 +6,0 @@ import { Endpoint } from "./protocol";

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.Comlink = factory());
}(this, (function () { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Comlink = factory());
})(this, (function () { 'use strict';
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function nodeEndpoint(nep) {
const listeners = new WeakMap();
return {
postMessage: nep.postMessage.bind(nep),
addEventListener: (_, eh) => {
const l = (data) => {
if ("handleEvent" in eh) {
eh.handleEvent({ data });
}
else {
eh({ data });
}
};
nep.on("message", l);
listeners.set(eh, l);
},
removeEventListener: (_, eh) => {
const l = listeners.get(eh);
if (!l) {
return;
}
nep.off("message", l);
listeners.delete(eh);
},
start: nep.start && nep.start.bind(nep),
};
}
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
function nodeEndpoint(nep) {
const listeners = new WeakMap();
return {
postMessage: nep.postMessage.bind(nep),
addEventListener: (_, eh) => {
const l = (data) => {
if ("handleEvent" in eh) {
eh.handleEvent({ data });
}
else {
eh({ data });
}
};
nep.on("message", l);
listeners.set(eh, l);
},
removeEventListener: (_, eh) => {
const l = listeners.get(eh);
if (!l) {
return;
}
nep.off("message", l);
listeners.delete(eh);
},
start: nep.start && nep.start.bind(nep),
};
}
return nodeEndpoint;
return nodeEndpoint;
})));
}));
//# sourceMappingURL=node-adapter.js.map

@@ -1,2 +0,7 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Comlink=t()}(this,(function(){"use strict";return function(e){const t=new WeakMap;return{postMessage:e.postMessage.bind(e),addEventListener:(n,s)=>{const o=e=>{"handleEvent"in s?s.handleEvent({data:e}):s({data:e})};e.on("message",o),t.set(s,o)},removeEventListener:(n,s)=>{const o=t.get(s);o&&(e.off("message",o),t.delete(s))},start:e.start&&e.start.bind(e)}}}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Comlink=t()}(this,(function(){"use strict";
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/return function(e){const t=new WeakMap;return{postMessage:e.postMessage.bind(e),addEventListener:(n,s)=>{const o=e=>{"handleEvent"in s?s.handleEvent({data:e}):s({data:e})};e.on("message",o),t.set(s,o)},removeEventListener:(n,s)=>{const o=t.get(s);o&&(e.off("message",o),t.delete(s))},start:e.start&&e.start.bind(e)}}}));
//# sourceMappingURL=node-adapter.min.js.map
/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -41,4 +34,4 @@ export interface EventSource {

}
export declare type WireValue = RawWireValue | HandlerWireValue;
export declare type MessageID = string;
export type WireValue = RawWireValue | HandlerWireValue;
export type MessageID = string;
export declare const enum MessageType {

@@ -82,4 +75,3 @@ GET = "GET",

type: MessageType.RELEASE;
path: string[];
}
export declare type Message = GetMessage | SetMessage | ApplyMessage | ConstructMessage | EndpointMessage | ReleaseMessage;
export type Message = GetMessage | SetMessage | ApplyMessage | ConstructMessage | EndpointMessage | ReleaseMessage;

@@ -14,3 +14,3 @@ /**

importScripts("https://unpkg.com/comlink@alpha/dist/umd/comlink.js");
importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
// importScripts("../../../dist/umd/comlink.js");

@@ -17,0 +17,0 @@

@@ -14,3 +14,3 @@ /**

importScripts("https://unpkg.com/comlink@alpha/dist/umd/comlink.js");
importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
// importScripts("../../../dist/umd/comlink.js");

@@ -17,0 +17,0 @@

@@ -14,3 +14,3 @@ /**

importScripts("https://unpkg.com/comlink@alpha/dist/umd/comlink.js");
importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
// importScripts("../../../dist/umd/comlink.js");

@@ -17,0 +17,0 @@

@@ -14,3 +14,3 @@ /**

importScripts("https://unpkg.com/comlink@alpha/dist/umd/comlink.js");
importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
// importScripts("../../../dist/umd/comlink.js");

@@ -17,0 +17,0 @@ importScripts("event.transferhandler.js");

@@ -14,3 +14,3 @@ /**

importScripts("https://unpkg.com/comlink@alpha/dist/umd/comlink.js");
importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
// importScripts("../../../dist/umd/comlink.js");

@@ -17,0 +17,0 @@

@@ -14,3 +14,3 @@ /**

importScripts("https://unpkg.com/comlink@alpha/dist/umd/comlink.js");
importScripts("https://unpkg.com/comlink/dist/umd/comlink.js");
// importScripts("../../../dist/umd/comlink.js");

@@ -17,0 +17,0 @@

{
"name": "comlink",
"version": "4.3.1",
"version": "4.4.0",
"description": "Comlink makes WebWorkers enjoyable",

@@ -19,7 +19,2 @@ "main": "dist/umd/comlink.js",

},
"husky": {
"hooks": {
"pre-commit": "npm test"
}
},
"author": {

@@ -35,22 +30,22 @@ "name": "Surma",

"devDependencies": {
"chai": "4.2.0",
"conditional-type-checks": "1.0.5",
"husky": "4.2.5",
"karma": "^5.0.9",
"@rollup/plugin-terser": "0.4.0",
"@rollup/plugin-typescript": "11.0.0",
"chai": "4.3.7",
"conditional-type-checks": "1.0.6",
"husky": "8.0.3",
"karma": "6.4.1",
"karma-chai": "0.1.0",
"karma-chrome-launcher": "3.1.0",
"karma-chrome-launcher": "3.1.1",
"karma-detect-browsers": "2.3.3",
"karma-firefox-launcher": "1.3.0",
"karma-mocha": "^2.0.1",
"karma-firefox-launcher": "2.1.2",
"karma-mocha": "2.0.1",
"karma-safari-launcher": "1.0.0",
"karma-safaritechpreview-launcher": "2.0.2",
"mocha": "^7.2.0",
"prettier": "2.0.5",
"rimraf": "3.0.2",
"rollup": "^2.11.2",
"rollup-plugin-terser": "^6.1.0",
"rollup-plugin-typescript2": "^0.27.1",
"typescript": "^3.9.3"
},
"dependencies": {}
"mocha": "10.2.0",
"prettier": "2.8.3",
"rimraf": "4.1.2",
"rollup": "3.10.1",
"tslib": "2.4.1",
"typescript": "4.9.4"
}
}

@@ -34,3 +34,3 @@ # Comlink

### [Running a simple function](https://github.com/GoogleChromeLabs/comlink/tree/master/docs/examples/01-simple-example)
### [Running a simple function](./docs/examples/01-simple-example)

@@ -68,3 +68,3 @@ **main.js**

### [Callbacks](https://github.com/torch2424/comlink/tree/master/docs/examples/02-callback-example)
### [Callbacks](./docs/examples/02-callback-example)

@@ -157,5 +157,6 @@ **main.js**

### `Comlink.wrap(endpoint)` and `Comlink.expose(value, endpoint?)`
### `Comlink.wrap(endpoint)` and `Comlink.expose(value, endpoint?, allowedOrigins?)`
Comlink’s goal is to make _exposed_ values from one thread available in the other. `expose` exposes `value` on `endpoint`, where `endpoint` is a [`postMessage`-like interface][endpoint].
Comlink’s goal is to make _exposed_ values from one thread available in the other. `expose` exposes `value` on `endpoint`, where `endpoint` is a [`postMessage`-like interface][endpoint] and `allowedOrigins` is an array of
RegExp or strings defining which origins should be allowed access (defaults to special case of `['*']` for all origins).

@@ -217,3 +218,3 @@ `wrap` wraps the _other_ end of the message channel and returns a proxy. The proxy will have all properties and functions of the exposed value, but access and invocations are inherently asynchronous. This means that a function that returns a number will now return _a promise_ for a number. **As a rule of thumb: If you are using the proxy, put `await` in front of it.** Exceptions will be caught and re-thrown on the other side.

Every proxy created by Comlink has the `[releaseProxy]` method.
Every proxy created by Comlink has the `[releaseProxy]()` method.
Calling it will detach the proxy and the exposed object from the message channel, allowing both ends to be garbage collected.

@@ -227,6 +228,12 @@

If the browser supports the [WeakRef proposal], `[releaseProxy]()` will be called automatically when the proxy created by `wrap()` gets garbage collected.
### `Comlink.finalizer`
If an exposed object has a property `[Comlink.finalizer]`, the property will be invoked as a function when the proxy is being released. This can happen either through a manual invocation of `[releaseProxy]()` or automatically during garbage collection if the runtime supports the [WeakRef proposal] (see `Comlink.releaseProxy` above). Note that when the finalizer function is invoked, the endpoint is closed and no more communication can happen.
### `Comlink.createEndpoint`
Every proxy created by Comlink has the `[createEndpoint]` method.
Calling it will return a new `MessagePort`, that has been hooked up to the same object as the proxy that `[createEndpoint]` has been called on.
Every proxy created by Comlink has the `[createEndpoint]()` method.
Calling it will return a new `MessagePort`, that has been hooked up to the same object as the proxy that `[createEndpoint]()` has been called on.

@@ -256,3 +263,3 @@ ```js

[umd]: https://github.com/umdjs/umd
[transferable]: https://developer.mozilla.org/en-US/docs/Web/API/Transferable
[transferable]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects
[messageport]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort

@@ -269,2 +276,3 @@ [examples]: https://github.com/GoogleChromeLabs/comlink/tree/master/docs/examples

[worker_threads]: https://nodejs.org/api/worker_threads.html
[weakref proposal]: https://github.com/tc39/proposal-weakrefs

@@ -271,0 +279,0 @@ ## Additional Resources

/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -23,3 +16,3 @@

} from "./protocol";
export { Endpoint };
export type { Endpoint };

@@ -29,2 +22,3 @@ export const proxyMarker = Symbol("Comlink.proxy");

export const releaseProxy = Symbol("Comlink.releaseProxy");
export const finalizer = Symbol("Comlink.finalizer");

@@ -286,3 +280,22 @@ const throwMarker = Symbol("Comlink.thrown");

export function expose(obj: any, ep: Endpoint = self as any) {
function isAllowedOrigin(
allowedOrigins: (string | RegExp)[],
origin: string
): boolean {
for (const allowedOrigin of allowedOrigins) {
if (origin === allowedOrigin || allowedOrigin === "*") {
return true;
}
if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
return true;
}
}
return false;
}
export function expose(
obj: any,
ep: Endpoint = self as any,
allowedOrigins: (string | RegExp)[] = ["*"]
) {
ep.addEventListener("message", function callback(ev: MessageEvent) {

@@ -292,2 +305,6 @@ if (!ev || !ev.data) {

}
if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);
return;
}
const { id, type, path } = {

@@ -354,3 +371,14 @@ path: [] as string[],

closeEndPoint(ep);
if (finalizer in obj && typeof obj[finalizer] === "function") {
obj[finalizer]();
}
}
})
.catch((error) => {
// Send Serialization Error To Caller
const [wireValue, transferables] = toWireValue({
value: new TypeError("Unserializable return value"),
[throwMarker]: 0,
});
ep.postMessage({ ...wireValue, id }, transferables);
});

@@ -381,2 +409,46 @@ } as any);

function releaseEndpoint(ep: Endpoint) {
return requestResponseMessage(ep, {
type: MessageType.RELEASE,
}).then(() => {
closeEndPoint(ep);
});
}
interface FinalizationRegistry<T> {
new (cb: (heldValue: T) => void): FinalizationRegistry<T>;
register(
weakItem: object,
heldValue: T,
unregisterToken?: object | undefined
): void;
unregister(unregisterToken: object): void;
}
declare var FinalizationRegistry: FinalizationRegistry<Endpoint>;
const proxyCounter = new WeakMap<Endpoint, number>();
const proxyFinalizers =
"FinalizationRegistry" in self &&
new FinalizationRegistry((ep: Endpoint) => {
const newCount = (proxyCounter.get(ep) || 0) - 1;
proxyCounter.set(ep, newCount);
if (newCount === 0) {
releaseEndpoint(ep);
}
});
function registerProxy(proxy: object, ep: Endpoint) {
const newCount = (proxyCounter.get(ep) || 0) + 1;
proxyCounter.set(ep, newCount);
if (proxyFinalizers) {
proxyFinalizers.register(proxy, ep, proxy);
}
}
function unregisterProxy(proxy: object) {
if (proxyFinalizers) {
proxyFinalizers.unregister(proxy);
}
}
function createProxy<T>(

@@ -393,9 +465,5 @@ ep: Endpoint,

return () => {
return requestResponseMessage(ep, {
type: MessageType.RELEASE,
path: path.map((p) => p.toString()),
}).then(() => {
closeEndPoint(ep);
isProxyReleased = true;
});
unregisterProxy(proxy);
releaseEndpoint(ep);
isProxyReleased = true;
};

@@ -467,2 +535,3 @@ }

});
registerProxy(proxy, ep);
return proxy as any;

@@ -486,3 +555,3 @@ }

export function proxy<T>(obj: T): T & ProxyMarked {
export function proxy<T extends {}>(obj: T): T & ProxyMarked {
return Object.assign(obj, { [proxyMarker]: true }) as any;

@@ -489,0 +558,0 @@ }

/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -13,0 +6,0 @@

/**
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

@@ -110,3 +103,2 @@

type: MessageType.RELEASE;
path: string[];
}

@@ -113,0 +105,0 @@

@@ -478,3 +478,3 @@ /**

xit("will proxy deeply nested values", async function () {
it("will proxy deeply nested values", async function () {
const thing = Comlink.wrap(this.port1);

@@ -497,2 +497,6 @@ const obj = {

await (b.v = 9);
// Workaround for a weird scheduling inconsistency in Firefox.
// This test failed, but not when run in isolation, and only
// in Firefox. I think there might be problem with task ordering.
await new Promise((resolve) => setTimeout(resolve, 1));
expect(await thing.a.v).to.equal(4);

@@ -580,2 +584,55 @@ expect(await thing.b.v).to.equal(9);

it("released proxy should invoke finalizer", async function () {
let finalized = false;
Comlink.expose(
{
a: "thing",
[Comlink.finalizer]: () => {
finalized = true;
},
},
this.port2
);
const instance = Comlink.wrap(this.port1);
expect(await instance.a).to.equal("thing");
await instance[Comlink.releaseProxy]();
// wait a beat to let the events process
await new Promise((resolve) => setTimeout(resolve, 1));
expect(finalized).to.be.true;
});
// commented out this test as it could be unreliable in various browsers as
// it has to wait for GC to kick in which could happen at any timing
// this does seem to work when testing locally
it.skip("released proxy via GC should invoke finalizer", async function () {
let finalized = false;
Comlink.expose(
{
a: "thing",
[Comlink.finalizer]: () => {
finalized = true;
},
},
this.port2
);
let registry;
// set a long enough timeout to wait for a garbage collection
this.timeout(10000);
// promise will resolve when the proxy is garbage collected
await new Promise(async (resolve, reject) => {
registry = new FinalizationRegistry((heldValue) => {
heldValue();
});
const instance = Comlink.wrap(this.port1);
registry.register(instance, resolve);
expect(await instance.a).to.equal("thing");
});
// wait a beat to let the events process
await new Promise((resolve) => setTimeout(resolve, 1));
expect(finalized).to.be.true;
});
it("can proxy with a given target", async function () {

@@ -586,2 +643,13 @@ const thing = Comlink.wrap(this.port1, { value: {} });

});
it("can handle unserializable types", async function () {
const thing = Comlink.wrap(this.port1, { value: {} });
Comlink.expose({ value: () => "boom" }, this.port2);
try {
await thing.value;
} catch (err) {
expect(err.message).to.equal("Unserializable return value");
}
});
});

@@ -588,0 +656,0 @@

@@ -57,3 +57,4 @@ {

},
"include": ["src/**/*.ts"]
"include": ["src/**/*.ts"],
"exclude": ["dist"]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc