New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

clooneyjs

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

clooneyjs - npm Package Compare versions

Comparing version 0.6.2 to 0.6.3

828

clooney.bundle.js

@@ -16,447 +16,449 @@ /**

var Clooney = (function (exports) {
'use strict';
'use strict';
/**
* Copyright 2017 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 Comlink = (function () {
const TRANSFERABLE_TYPES = [ArrayBuffer, MessagePort];
const uid = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
const proxyValueSymbol = Symbol('proxyValue');
const throwSymbol = Symbol('throw');
const proxyTransferHandler = {
canHandle: (obj) => obj && obj[proxyValueSymbol],
serialize: (obj) => {
const { port1, port2 } = new MessageChannel();
expose(obj, port1);
return port2;
},
deserialize: (obj) => {
return proxy(obj);
},
};
const throwTransferHandler = {
canHandle: (obj) => obj && obj[throwSymbol],
serialize: (obj) => obj.toString() + '\n' + obj.stack,
deserialize: (obj) => {
throw Error(obj);
},
};
/* export */ const transferHandlers = new Map([
['PROXY', proxyTransferHandler],
['THROW', throwTransferHandler],
]);
let pingPongMessageCounter = 0;
/* export */ function proxy(endpoint) {
if (isWindow(endpoint))
endpoint = windowEndpoint(endpoint);
if (!isEndpoint(endpoint))
throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');
activateEndpoint(endpoint);
return cbProxy(async (irequest) => {
let args = [];
if (irequest.type === 'APPLY' || irequest.type === 'CONSTRUCT')
args = irequest.argumentsList.map(wrapValue);
const response = await pingPongMessage(endpoint, Object.assign({}, irequest, { argumentsList: args }), transferableProperties(args));
const result = response.data;
return unwrapValue(result.value);
});
}
/* export */ function proxyValue(obj) {
obj[proxyValueSymbol] = true;
return obj;
}
/* export */ function expose(rootObj, endpoint) {
if (isWindow(endpoint))
endpoint = windowEndpoint(endpoint);
if (!isEndpoint(endpoint))
throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');
activateEndpoint(endpoint);
attachMessageHandler(endpoint, async function (event) {
if (!event.data.id)
return;
const irequest = event.data;
let that = await irequest.callPath.slice(0, -1).reduce((obj, propName) => obj[propName], rootObj);
let obj = await irequest.callPath.reduce((obj, propName) => obj[propName], rootObj);
let iresult = obj;
let args = [];
if (irequest.type === 'APPLY' || irequest.type === 'CONSTRUCT')
args = irequest.argumentsList.map(unwrapValue);
if (irequest.type === 'APPLY') {
try {
iresult = await obj.apply(that, args);
/**
* Copyright 2017 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 Comlink = (function () {
const TRANSFERABLE_TYPES = [ArrayBuffer, MessagePort];
const uid = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
const proxyValueSymbol = Symbol('proxyValue');
const throwSymbol = Symbol('throw');
const proxyTransferHandler = {
canHandle: (obj) => obj && obj[proxyValueSymbol],
serialize: (obj) => {
const { port1, port2 } = new MessageChannel();
expose(obj, port1);
return port2;
},
deserialize: (obj) => {
return proxy(obj);
},
};
const throwTransferHandler = {
canHandle: (obj) => obj && obj[throwSymbol],
serialize: (obj) => obj.toString() + '\n' + obj.stack,
deserialize: (obj) => {
throw Error(obj);
},
};
/* export */ const transferHandlers = new Map([
['PROXY', proxyTransferHandler],
['THROW', throwTransferHandler],
]);
let pingPongMessageCounter = 0;
/* export */ function proxy(endpoint) {
if (isWindow(endpoint))
endpoint = windowEndpoint(endpoint);
if (!isEndpoint(endpoint))
throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');
activateEndpoint(endpoint);
return cbProxy(async (irequest) => {
let args = [];
if (irequest.type === 'APPLY' || irequest.type === 'CONSTRUCT')
args = irequest.argumentsList.map(wrapValue);
const response = await pingPongMessage(endpoint, Object.assign({}, irequest, { argumentsList: args }), transferableProperties(args));
const result = response.data;
return unwrapValue(result.value);
});
}
/* export */ function proxyValue(obj) {
obj[proxyValueSymbol] = true;
return obj;
}
/* export */ function expose(rootObj, endpoint) {
if (isWindow(endpoint))
endpoint = windowEndpoint(endpoint);
if (!isEndpoint(endpoint))
throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');
activateEndpoint(endpoint);
attachMessageHandler(endpoint, async function (event) {
if (!event.data.id)
return;
const irequest = event.data;
let that = await irequest.callPath.slice(0, -1).reduce((obj, propName) => obj[propName], rootObj);
let obj = await irequest.callPath.reduce((obj, propName) => obj[propName], rootObj);
let iresult = obj;
let args = [];
if (irequest.type === 'APPLY' || irequest.type === 'CONSTRUCT')
args = irequest.argumentsList.map(unwrapValue);
if (irequest.type === 'APPLY') {
try {
iresult = await obj.apply(that, args);
}
catch (e) {
iresult = e;
iresult[throwSymbol] = true;
}
}
catch (e) {
iresult = e;
iresult[throwSymbol] = true;
if (irequest.type === 'CONSTRUCT') {
try {
iresult = new obj(...args); // eslint-disable-line new-cap
iresult = proxyValue(iresult);
}
catch (e) {
iresult = e;
iresult[throwSymbol] = true;
}
}
}
if (irequest.type === 'CONSTRUCT') {
try {
iresult = new obj(...args); // eslint-disable-line new-cap
iresult = proxyValue(iresult);
if (irequest.type === 'SET') {
obj[irequest.property] = irequest.value;
// FIXME: ES6 Proxy Handler `set` methods are supposed to return a
// boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
iresult = true;
}
catch (e) {
iresult = e;
iresult[throwSymbol] = true;
iresult = makeInvocationResult(iresult);
iresult.id = irequest.id;
return endpoint.postMessage(iresult, transferableProperties([iresult]));
});
}
function wrapValue(arg) {
// Is arg itself handled by a TransferHandler?
for (const [key, transferHandler] of transferHandlers.entries()) {
if (transferHandler.canHandle(arg)) {
return {
type: key,
value: transferHandler.serialize(arg),
};
}
}
if (irequest.type === 'SET') {
obj[irequest.property] = irequest.value;
// FIXME: ES6 Proxy Handler `set` methods are supposed to return a
// boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
iresult = true;
// If not, traverse the entire object and find handled values.
let wrappedChildren = [];
for (const item of iterateAllProperties(arg)) {
for (const [key, transferHandler] of transferHandlers.entries()) {
if (transferHandler.canHandle(item.value)) {
wrappedChildren.push({
path: item.path,
wrappedValue: {
type: key,
value: transferHandler.serialize(item.value),
},
});
}
}
}
iresult = makeInvocationResult(iresult);
iresult.id = irequest.id;
return endpoint.postMessage(iresult, transferableProperties([iresult]));
});
}
function wrapValue(arg) {
// Is arg itself handled by a TransferHandler?
for (const [key, transferHandler] of transferHandlers.entries()) {
if (transferHandler.canHandle(arg)) {
return {
type: key,
value: transferHandler.serialize(arg),
};
for (const wrappedChild of wrappedChildren) {
const container = wrappedChild.path.slice(0, -1).reduce((obj, key) => obj[key], arg);
container[wrappedChild.path[wrappedChild.path.length - 1]] = null;
}
return {
type: 'RAW',
value: arg,
wrappedChildren,
};
}
// If not, traverse the entire object and find handled values.
let wrappedChildren = [];
for (const item of iterateAllProperties(arg)) {
for (const [key, transferHandler] of transferHandlers.entries()) {
if (transferHandler.canHandle(item.value)) {
wrappedChildren.push({
path: item.path,
wrappedValue: {
type: key,
value: transferHandler.serialize(item.value),
},
});
function unwrapValue(arg) {
if (transferHandlers.has(arg.type)) {
const transferHandler = transferHandlers.get(arg.type);
return transferHandler.deserialize(arg.value);
}
else if (isRawWrappedValue(arg)) {
for (const wrappedChildValue of (arg.wrappedChildren || [])) {
if (!transferHandlers.has(wrappedChildValue.wrappedValue.type))
throw Error(`Unknown value type "${arg.type}" at ${wrappedChildValue.path.join('.')}`);
const transferHandler = transferHandlers.get(wrappedChildValue.wrappedValue.type);
const newValue = transferHandler.deserialize(wrappedChildValue.wrappedValue.value);
replaceValueInObjectAtPath(arg.value, wrappedChildValue.path, newValue);
}
return arg.value;
}
else {
throw Error(`Unknown value type "${arg.type}"`);
}
}
for (const wrappedChild of wrappedChildren) {
const container = wrappedChild.path.slice(0, -1).reduce((obj, key) => obj[key], arg);
container[wrappedChild.path[wrappedChild.path.length - 1]] = null;
function replaceValueInObjectAtPath(obj, path, newVal) {
const lastKey = path.slice(-1)[0];
const lastObj = path.slice(0, -1).reduce((obj, key) => obj[key], obj);
lastObj[lastKey] = newVal;
}
return {
type: 'RAW',
value: arg,
wrappedChildren,
};
}
function unwrapValue(arg) {
if (transferHandlers.has(arg.type)) {
const transferHandler = transferHandlers.get(arg.type);
return transferHandler.deserialize(arg.value);
function isRawWrappedValue(arg) {
return arg.type === 'RAW';
}
else if (isRawWrappedValue(arg)) {
for (const wrappedChildValue of (arg.wrappedChildren || [])) {
if (!transferHandlers.has(wrappedChildValue.wrappedValue.type))
throw Error(`Unknown value type "${arg.type}" at ${wrappedChildValue.path.join('.')}`);
const transferHandler = transferHandlers.get(wrappedChildValue.wrappedValue.type);
const newValue = transferHandler.deserialize(wrappedChildValue.wrappedValue.value);
replaceValueInObjectAtPath(arg.value, wrappedChildValue.path, newValue);
}
return arg.value;
function windowEndpoint(w) {
if (self.constructor.name !== 'Window')
throw Error('self is not a window');
return {
addEventListener: self.addEventListener.bind(self),
removeEventListener: self.removeEventListener.bind(self),
postMessage: (msg, transfer) => w.postMessage(msg, '*', transfer),
};
}
else {
throw Error(`Unknown value type "${arg.type}"`);
function isEndpoint(endpoint) {
return 'addEventListener' in endpoint && 'removeEventListener' in endpoint && 'postMessage' in endpoint;
}
}
function replaceValueInObjectAtPath(obj, path, newVal) {
const lastKey = path.slice(-1)[0];
const lastObj = path.slice(0, -1).reduce((obj, key) => obj[key], obj);
lastObj[lastKey] = newVal;
}
function isRawWrappedValue(arg) {
return arg.type === 'RAW';
}
function windowEndpoint(w) {
if (self.constructor.name !== 'Window')
throw Error('self is not a window');
return {
addEventListener: self.addEventListener.bind(self),
removeEventListener: self.removeEventListener.bind(self),
postMessage: (msg, transfer) => w.postMessage(msg, '*', transfer),
};
}
function isEndpoint(endpoint) {
return 'addEventListener' in endpoint && 'removeEventListener' in endpoint && 'postMessage' in endpoint;
}
function activateEndpoint(endpoint) {
if (isMessagePort(endpoint))
endpoint.start();
}
function attachMessageHandler(endpoint, f) {
// Checking all possible types of `endpoint` manually satisfies TypeScript’s
// type checker. Not sure why the inference is failing here. Since it’s
// unnecessary code I’m going to resort to `any` for now.
// if(isWorker(endpoint))
// endpoint.addEventListener('message', f);
// if(isMessagePort(endpoint))
// endpoint.addEventListener('message', f);
// if(isOtherWindow(endpoint))
// endpoint.addEventListener('message', f);
endpoint.addEventListener('message', f);
}
function detachMessageHandler(endpoint, f) {
// Same as above.
endpoint.removeEventListener('message', f);
}
function isMessagePort(endpoint) {
return endpoint.constructor.name === 'MessagePort';
}
function isWindow(endpoint) {
// TODO: This doesn’t work on cross-origin iframes.
// return endpoint.constructor.name === 'Window';
return ['window', 'length', 'location', 'parent', 'opener'].every(prop => prop in endpoint);
}
/**
* `pingPongMessage` sends a `postMessage` and waits for a reply. Replies are
* identified by a unique id that is attached to the payload.
*/
function pingPongMessage(endpoint, msg, transferables) {
const id = `${uid}-${pingPongMessageCounter++}`;
return new Promise(resolve => {
attachMessageHandler(endpoint, function handler(event) {
if (event.data.id !== id)
return;
detachMessageHandler(endpoint, handler);
resolve(event);
function activateEndpoint(endpoint) {
if (isMessagePort(endpoint))
endpoint.start();
}
function attachMessageHandler(endpoint, f) {
// Checking all possible types of `endpoint` manually satisfies TypeScript’s
// type checker. Not sure why the inference is failing here. Since it’s
// unnecessary code I’m going to resort to `any` for now.
// if(isWorker(endpoint))
// endpoint.addEventListener('message', f);
// if(isMessagePort(endpoint))
// endpoint.addEventListener('message', f);
// if(isOtherWindow(endpoint))
// endpoint.addEventListener('message', f);
endpoint.addEventListener('message', f);
}
function detachMessageHandler(endpoint, f) {
// Same as above.
endpoint.removeEventListener('message', f);
}
function isMessagePort(endpoint) {
return endpoint.constructor.name === 'MessagePort';
}
function isWindow(endpoint) {
// TODO: This doesn’t work on cross-origin iframes.
// return endpoint.constructor.name === 'Window';
return ['window', 'length', 'location', 'parent', 'opener'].every(prop => prop in endpoint);
}
/**
* `pingPongMessage` sends a `postMessage` and waits for a reply. Replies are
* identified by a unique id that is attached to the payload.
*/
function pingPongMessage(endpoint, msg, transferables) {
const id = `${uid}-${pingPongMessageCounter++}`;
return new Promise(resolve => {
attachMessageHandler(endpoint, function handler(event) {
if (event.data.id !== id)
return;
detachMessageHandler(endpoint, handler);
resolve(event);
});
// Copy msg and add `id` property
msg = Object.assign({}, msg, { id });
endpoint.postMessage(msg, transferables);
});
// Copy msg and add `id` property
msg = Object.assign({}, msg, { id });
endpoint.postMessage(msg, transferables);
});
}
function cbProxy(cb, callPath = []) {
return new Proxy(function () { }, {
construct(_target, argumentsList, proxy) {
return cb({
type: 'CONSTRUCT',
callPath,
argumentsList,
});
},
apply(_target, _thisArg, argumentsList) {
// We use `bind` as an indicator to have a remote function bound locally.
// The actual target for `bind()` is currently ignored.
if (callPath[callPath.length - 1] === 'bind')
return cbProxy(cb, callPath.slice(0, -1));
return cb({
type: 'APPLY',
callPath,
argumentsList,
});
},
get(_target, property, proxy) {
if (property === 'then' && callPath.length === 0) {
return { then: () => proxy };
}
else if (property === 'then') {
const r = cb({
type: 'GET',
}
function cbProxy(cb, callPath = []) {
return new Proxy(function () { }, {
construct(_target, argumentsList, proxy) {
return cb({
type: 'CONSTRUCT',
callPath,
argumentsList,
});
return Promise.resolve(r).then.bind(r);
}
else {
return cbProxy(cb, callPath.concat(property));
}
},
set(_target, property, value, _proxy) {
return cb({
type: 'SET',
callPath,
property,
value,
});
},
});
}
function isTransferable(thing) {
return TRANSFERABLE_TYPES.some(type => thing instanceof type);
}
function* iterateAllProperties(value, path = [], visited = null) {
if (!value)
return;
if (!visited)
visited = new WeakSet();
if (visited.has(value))
return;
if (typeof value === 'string')
return;
if (typeof value === 'object')
visited.add(value);
yield { value, path };
let keys = Object.keys(value);
for (const key of keys)
yield* iterateAllProperties(value[key], [...path, key], visited);
}
function transferableProperties(obj) {
const r = [];
for (const prop of iterateAllProperties(obj)) {
if (isTransferable(prop.value))
r.push(prop.value);
},
apply(_target, _thisArg, argumentsList) {
// We use `bind` as an indicator to have a remote function bound locally.
// The actual target for `bind()` is currently ignored.
if (callPath[callPath.length - 1] === 'bind')
return cbProxy(cb, callPath.slice(0, -1));
return cb({
type: 'APPLY',
callPath,
argumentsList,
});
},
get(_target, property, proxy) {
if (property === 'then' && callPath.length === 0) {
return { then: () => proxy };
}
else if (property === 'then') {
const r = cb({
type: 'GET',
callPath,
});
return Promise.resolve(r).then.bind(r);
}
else {
return cbProxy(cb, callPath.concat(property));
}
},
set(_target, property, value, _proxy) {
return cb({
type: 'SET',
callPath,
property,
value,
});
},
});
}
return r;
}
function makeInvocationResult(obj) {
for (const [type, transferHandler] of transferHandlers.entries()) {
if (transferHandler.canHandle(obj)) {
const value = transferHandler.serialize(obj);
return {
value: { type, value },
};
function isTransferable(thing) {
return TRANSFERABLE_TYPES.some(type => thing instanceof type);
}
function* iterateAllProperties(value, path = [], visited = null) {
if (!value)
return;
if (!visited)
visited = new WeakSet();
if (visited.has(value))
return;
if (typeof value === 'string')
return;
if (typeof value === 'object')
visited.add(value);
if (ArrayBuffer.isView(value))
return;
yield { value, path };
const keys = Object.keys(value);
for (const key of keys)
yield* iterateAllProperties(value[key], [...path, key], visited);
}
function transferableProperties(obj) {
const r = [];
for (const prop of iterateAllProperties(obj)) {
if (isTransferable(prop.value))
r.push(prop.value);
}
return r;
}
return {
value: {
type: 'RAW',
value: obj,
},
};
}
return { proxy, proxyValue, transferHandlers, expose };
})();
function makeInvocationResult(obj) {
for (const [type, transferHandler] of transferHandlers.entries()) {
if (transferHandler.canHandle(obj)) {
const value = transferHandler.serialize(obj);
return {
value: { type, value },
};
}
}
return {
value: {
type: 'RAW',
value: obj,
},
};
}
return { proxy, proxyValue, transferHandlers, expose };
})();
/**
* Copyright 2018 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.
*/
// Automatically proxy functions
Comlink.transferHandlers.set('FUNCTION', {
canHandle(obj) {
return obj instanceof Function;
},
serialize(obj) {
const { port1, port2 } = new MessageChannel();
Comlink.expose(obj, port1);
return port2;
},
deserialize(obj) {
return Comlink.proxy(obj);
},
});
// Automatically proxy events
Comlink.transferHandlers.set('EVENT', {
canHandle(obj) {
return obj instanceof Event;
},
serialize(obj) {
return {
targetId: obj && obj.target && obj.target.id,
targetClassList: obj && obj.target && obj.target.classList && [...obj.target.classList],
detail: obj && obj.detail,
data: obj && obj.data,
};
},
deserialize(obj) {
return obj;
},
});
/**
* `asRemoteValue` marks a value. If a marked value is used as an parameter or return value, it will not be transferred but instead proxied.
*/
const asRemoteValue = Comlink.proxyValue;
/**
* `defaultWorkerSrc` is the path passed to the `new Worker()` call. It’s recommended to not change this variable but instead overload `newWorkerFunc`.
*/
let defaultWorkerSrc = 'document' in self ? document.currentScript && document.currentScript.src : '';
const defaultOpts = {
maxNumContainers: 1,
newWorkerFunc: async () => new Worker(defaultWorkerSrc),
};
/**
* `RoundRobingStrategy` creates up to n containers and cycles through the containers with every `spawn` call.
*/
class RoundRobinStrategy {
constructor(opts = {}) {
this._nextIndex = 0;
this._options = Object.assign({}, defaultOpts, opts);
this._containers = new Array(this._options.maxNumContainers).fill(null);
}
async _initOrGetContainer(i) {
if (i >= this._containers.length)
throw Error('No worker available');
if (!this._containers[i]) {
const worker = await this._options.newWorkerFunc();
const remote = Comlink.proxy(worker);
this._containers[i] = {
spawn: remote.spawn.bind(spawn),
terminate: worker.terminate.bind(worker),
/**
* Copyright 2018 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.
*/
// Automatically proxy functions
Comlink.transferHandlers.set('FUNCTION', {
canHandle(obj) {
return obj instanceof Function;
},
serialize(obj) {
const { port1, port2 } = new MessageChannel();
Comlink.expose(obj, port1);
return port2;
},
deserialize(obj) {
return Comlink.proxy(obj);
},
});
// Automatically proxy events
Comlink.transferHandlers.set('EVENT', {
canHandle(obj) {
return obj instanceof Event;
},
serialize(obj) {
return {
targetId: obj && obj.target && obj.target.id,
targetClassList: obj && obj.target && obj.target.classList && [...obj.target.classList],
detail: obj && obj.detail,
data: obj && obj.data,
};
},
deserialize(obj) {
return obj;
},
});
/**
* `asRemoteValue` marks a value. If a marked value is used as an parameter or return value, it will not be transferred but instead proxied.
*/
const asRemoteValue = Comlink.proxyValue;
/**
* `defaultWorkerSrc` is the path passed to the `new Worker()` call. It’s recommended to not change this variable but instead overload `newWorkerFunc`.
*/
let defaultWorkerSrc = 'document' in self ? document.currentScript && document.currentScript.src : '';
const defaultOpts = {
maxNumContainers: 1,
newWorkerFunc: async () => new Worker(defaultWorkerSrc),
};
/**
* `RoundRobingStrategy` creates up to n containers and cycles through the containers with every `spawn` call.
*/
class RoundRobinStrategy {
constructor(opts = {}) {
this._nextIndex = 0;
this._options = Object.assign({}, defaultOpts, opts);
this._containers = new Array(this._options.maxNumContainers).fill(null);
}
return this._containers[i];
async _initOrGetContainer(i) {
if (i >= this._containers.length)
throw Error('No worker available');
if (!this._containers[i]) {
const worker = await this._options.newWorkerFunc();
const remote = Comlink.proxy(worker);
this._containers[i] = {
spawn: remote.spawn.bind(spawn),
terminate: worker.terminate.bind(worker),
};
}
return this._containers[i];
}
async _getNextContainer(opts) {
const w = await this._initOrGetContainer(this._nextIndex);
this._nextIndex = (this._nextIndex + 1) % this._options.maxNumContainers;
return w;
}
async spawn(actor, constructorArgs = [], opts = {}) {
const container = await this._getNextContainer(opts);
return await container.spawn(actor.toString(), constructorArgs);
}
async terminate() {
this._containers.filter(c => c).forEach(container => container.terminate());
this._containers.length = 0;
}
get terminated() {
return this._containers.length <= 0;
}
}
async _getNextContainer(opts) {
const w = await this._initOrGetContainer(this._nextIndex);
this._nextIndex = (this._nextIndex + 1) % this._options.maxNumContainers;
return w;
let defaultStrategy = new RoundRobinStrategy();
async function spawn(actor, constructorArgs = [], opts = {}) {
return defaultStrategy.spawn(actor, constructorArgs, opts);
}
async spawn(actor, constructorArgs = [], opts = {}) {
const container = await this._getNextContainer(opts);
return await container.spawn(actor.toString(), constructorArgs);
function makeContainer(endpoint = self) {
Comlink.expose({
async spawn(actorCode, constructorArgs) {
const actor = (new Function(`return ${actorCode};`))();
return Comlink.proxyValue(new actor(...constructorArgs)); // eslint-disable-line new-cap
},
}, endpoint);
}
async terminate() {
this._containers.filter(c => c).forEach(container => container.terminate());
this._containers.length = 0;
function isWorker() {
// I’d have to import lib.webworker.d.ts to have access to
// WorkerGlobalScope, but I can’t because it conflicts with lib.dom.d.ts.
const wgs = self['WorkerGlobalScope'];
return wgs && self instanceof wgs;
}
get terminated() {
return this._containers.length <= 0;
}
}
let defaultStrategy = new RoundRobinStrategy();
async function spawn(actor, constructorArgs = [], opts = {}) {
return defaultStrategy.spawn(actor, constructorArgs, opts);
}
function makeContainer(endpoint = self) {
Comlink.expose({
async spawn(actorCode, constructorArgs) {
const actor = (new Function(`return ${actorCode};`))();
return Comlink.proxyValue(new actor(...constructorArgs)); // eslint-disable-line new-cap
},
}, endpoint);
}
function isWorker() {
// I’d have to import lib.webworker.d.ts to have access to
// WorkerGlobalScope, but I can’t because it conflicts with lib.dom.d.ts.
const wgs = self['WorkerGlobalScope'];
return wgs && self instanceof wgs;
}
// TODO: Find a way to opt-out of autostart
if (isWorker())
makeContainer();
// TODO: Find a way to opt-out of autostart
if (isWorker())
makeContainer();
exports.asRemoteValue = asRemoteValue;
exports.defaultWorkerSrc = defaultWorkerSrc;
exports.defaultOpts = defaultOpts;
exports.RoundRobinStrategy = RoundRobinStrategy;
exports.defaultStrategy = defaultStrategy;
exports.spawn = spawn;
exports.makeContainer = makeContainer;
exports.Comlink = Comlink;
exports.asRemoteValue = asRemoteValue;
exports.defaultWorkerSrc = defaultWorkerSrc;
exports.defaultOpts = defaultOpts;
exports.RoundRobinStrategy = RoundRobinStrategy;
exports.defaultStrategy = defaultStrategy;
exports.spawn = spawn;
exports.makeContainer = makeContainer;
exports.Comlink = Comlink;
return exports;
return exports;
}({}));

@@ -14,2 +14,2 @@ /**

*/
var Clooney=function(a){'use strict';async function b(a,b=[],c={}){return i.spawn(a,b,c)}function c(a=self){d.expose({async spawn(a,b){const c=new Function(`return ${a};`)();return d.proxyValue(new c(...b))}},a)}const d=function(){function a(a){if(n(a)&&(a=h(a)),!i(a))throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');return j(a),p(async(b)=>{let c=[];('APPLY'===b.type||'CONSTRUCT'===b.type)&&(c=b.argumentsList.map(d));const f=await o(a,Object.assign({},b,{argumentsList:c}),r(c)),g=f.data;return e(g.value)})}function b(a){return a[w]=!0,a}function c(a,c){if(n(c)&&(c=h(c)),!i(c))throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');j(c),k(c,async function(d){if(!d.data.id)return;const f=d.data;let g=await f.callPath.slice(0,-1).reduce((a,b)=>a[b],a),h=await f.callPath.reduce((a,b)=>a[b],a),i=h,j=[];if(('APPLY'===f.type||'CONSTRUCT'===f.type)&&(j=f.argumentsList.map(e)),'APPLY'===f.type)try{i=await h.apply(g,j)}catch(a){i=a,i[x]=!0}if('CONSTRUCT'===f.type)try{i=new h(...j),i=b(i)}catch(a){i=a,i[x]=!0}return'SET'===f.type&&(h[f.property]=f.value,i=!0),i=t(i),i.id=f.id,c.postMessage(i,r([i]))})}function d(a){for(const[b,c]of y.entries())if(c.canHandle(a))return{type:b,value:c.serialize(a)};let b=[];for(const c of s(a))for(const[a,d]of y.entries())d.canHandle(c.value)&&b.push({path:c.path,wrappedValue:{type:a,value:d.serialize(c.value)}});for(const c of b){const b=c.path.slice(0,-1).reduce((a,b)=>a[b],a);b[c.path[c.path.length-1]]=null}return{type:'RAW',value:a,wrappedChildren:b}}function e(a){if(y.has(a.type)){const b=y.get(a.type);return b.deserialize(a.value)}if(g(a)){for(const b of a.wrappedChildren||[]){if(!y.has(b.wrappedValue.type))throw Error(`Unknown value type "${a.type}" at ${b.path.join('.')}`);const c=y.get(b.wrappedValue.type),d=c.deserialize(b.wrappedValue.value);f(a.value,b.path,d)}return a.value}throw Error(`Unknown value type "${a.type}"`)}function f(a,b,c){const d=b.slice(-1)[0],e=b.slice(0,-1).reduce((a,b)=>a[b],a);e[d]=c}function g(a){return'RAW'===a.type}function h(a){if('Window'!==self.constructor.name)throw Error('self is not a window');return{addEventListener:self.addEventListener.bind(self),removeEventListener:self.removeEventListener.bind(self),postMessage:(b,c)=>a.postMessage(b,'*',c)}}function i(a){return'addEventListener'in a&&'removeEventListener'in a&&'postMessage'in a}function j(a){m(a)&&a.start()}function k(a,b){a.addEventListener('message',b)}function l(a,b){a.removeEventListener('message',b)}function m(a){return'MessagePort'===a.constructor.name}function n(a){return['window','length','location','parent','opener'].every((b)=>b in a)}function o(a,b,c){const d=`${v}-${z++}`;return new Promise((e)=>{k(a,function b(c){c.data.id!==d||(l(a,b),e(c))}),b=Object.assign({},b,{id:d}),a.postMessage(b,c)})}function p(a,b=[]){return new Proxy(function(){},{construct(c,d){return a({type:'CONSTRUCT',callPath:b,argumentsList:d})},apply(c,d,e){return'bind'===b[b.length-1]?p(a,b.slice(0,-1)):a({type:'APPLY',callPath:b,argumentsList:e})},get(c,d,e){if('then'===d&&0===b.length)return{then:()=>e};if('then'===d){const c=a({type:'GET',callPath:b});return Promise.resolve(c).then.bind(c)}return p(a,b.concat(d))},set(c,d,e){return a({type:'SET',callPath:b,property:d,value:e})}})}function q(a){return u.some((b)=>a instanceof b)}function*s(a,b=[],c=null){if(a&&(c||(c=new WeakSet),!c.has(a))&&'string'!=typeof a){'object'==typeof a&&c.add(a),yield{value:a,path:b};let d=Object.keys(a);for(const e of d)yield*s(a[e],[...b,e],c)}}function r(a){const b=[];for(const c of s(a))q(c.value)&&b.push(c.value);return b}function t(a){for(const[b,c]of y.entries())if(c.canHandle(a)){const d=c.serialize(a);return{value:{type:b,value:d}}}return{value:{type:'RAW',value:a}}}const u=[ArrayBuffer,MessagePort],v=Math.floor(Math.random()*Number.MAX_SAFE_INTEGER),w=Symbol('proxyValue'),x=Symbol('throw'),y=new Map([['PROXY',{canHandle:(a)=>a&&a[w],serialize:(a)=>{const{port1:b,port2:d}=new MessageChannel;return c(a,b),d},deserialize:(b)=>a(b)}],['THROW',{canHandle:(a)=>a&&a[x],serialize:(a)=>a.toString()+'\n'+a.stack,deserialize:(a)=>{throw Error(a)}}]]);let z=0;return{proxy:a,proxyValue:b,transferHandlers:y,expose:c}}();d.transferHandlers.set('FUNCTION',{canHandle(a){return a instanceof Function},serialize(a){const{port1:b,port2:c}=new MessageChannel;return d.expose(a,b),c},deserialize(a){return d.proxy(a)}}),d.transferHandlers.set('EVENT',{canHandle(a){return a instanceof Event},serialize(a){return{targetId:a&&a.target&&a.target.id,targetClassList:a&&a.target&&a.target.classList&&[...a.target.classList],detail:a&&a.detail,data:a&&a.data}},deserialize(a){return a}});const e=d.proxyValue;let f='document'in self?document.currentScript&&document.currentScript.src:'';const g={maxNumContainers:1,newWorkerFunc:async()=>new Worker(f)};class h{constructor(a={}){this._nextIndex=0,this._options=Object.assign({},g,a),this._containers=Array(this._options.maxNumContainers).fill(null)}async _initOrGetContainer(a){if(a>=this._containers.length)throw Error('No worker available');if(!this._containers[a]){const c=await this._options.newWorkerFunc(),e=d.proxy(c);this._containers[a]={spawn:e.spawn.bind(b),terminate:c.terminate.bind(c)}}return this._containers[a]}async _getNextContainer(){const a=await this._initOrGetContainer(this._nextIndex);return this._nextIndex=(this._nextIndex+1)%this._options.maxNumContainers,a}async spawn(a,b=[],c={}){const d=await this._getNextContainer(c);return await d.spawn(a.toString(),b)}async terminate(){this._containers.filter((a)=>a).forEach((a)=>a.terminate()),this._containers.length=0}get terminated(){return 0>=this._containers.length}}let i=new h;return function(){const a=self.WorkerGlobalScope;return a&&self instanceof a}()&&c(),a.asRemoteValue=e,a.defaultWorkerSrc=f,a.defaultOpts=g,a.RoundRobinStrategy=h,a.defaultStrategy=i,a.spawn=b,a.makeContainer=c,a.Comlink=d,a}({});
var Clooney=function(a){'use strict';async function b(a,b=[],c={}){return i.spawn(a,b,c)}function c(a=self){d.expose({async spawn(a,b){const c=new Function(`return ${a};`)();return d.proxyValue(new c(...b))}},a)}const d=function(){function a(a){if(n(a)&&(a=h(a)),!i(a))throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');return j(a),p(async(b)=>{let c=[];('APPLY'===b.type||'CONSTRUCT'===b.type)&&(c=b.argumentsList.map(d));const f=await o(a,Object.assign({},b,{argumentsList:c}),r(c)),g=f.data;return e(g.value)})}function b(a){return a[w]=!0,a}function c(a,c){if(n(c)&&(c=h(c)),!i(c))throw Error('endpoint does not have all of addEventListener, removeEventListener and postMessage defined');j(c),k(c,async function(d){if(!d.data.id)return;const f=d.data;let g=await f.callPath.slice(0,-1).reduce((a,b)=>a[b],a),h=await f.callPath.reduce((a,b)=>a[b],a),i=h,j=[];if(('APPLY'===f.type||'CONSTRUCT'===f.type)&&(j=f.argumentsList.map(e)),'APPLY'===f.type)try{i=await h.apply(g,j)}catch(a){i=a,i[x]=!0}if('CONSTRUCT'===f.type)try{i=new h(...j),i=b(i)}catch(a){i=a,i[x]=!0}return'SET'===f.type&&(h[f.property]=f.value,i=!0),i=t(i),i.id=f.id,c.postMessage(i,r([i]))})}function d(a){for(const[b,c]of y.entries())if(c.canHandle(a))return{type:b,value:c.serialize(a)};let b=[];for(const c of s(a))for(const[a,d]of y.entries())d.canHandle(c.value)&&b.push({path:c.path,wrappedValue:{type:a,value:d.serialize(c.value)}});for(const c of b){const b=c.path.slice(0,-1).reduce((a,b)=>a[b],a);b[c.path[c.path.length-1]]=null}return{type:'RAW',value:a,wrappedChildren:b}}function e(a){if(y.has(a.type)){const b=y.get(a.type);return b.deserialize(a.value)}if(g(a)){for(const b of a.wrappedChildren||[]){if(!y.has(b.wrappedValue.type))throw Error(`Unknown value type "${a.type}" at ${b.path.join('.')}`);const c=y.get(b.wrappedValue.type),d=c.deserialize(b.wrappedValue.value);f(a.value,b.path,d)}return a.value}throw Error(`Unknown value type "${a.type}"`)}function f(a,b,c){const d=b.slice(-1)[0],e=b.slice(0,-1).reduce((a,b)=>a[b],a);e[d]=c}function g(a){return'RAW'===a.type}function h(a){if('Window'!==self.constructor.name)throw Error('self is not a window');return{addEventListener:self.addEventListener.bind(self),removeEventListener:self.removeEventListener.bind(self),postMessage:(b,c)=>a.postMessage(b,'*',c)}}function i(a){return'addEventListener'in a&&'removeEventListener'in a&&'postMessage'in a}function j(a){m(a)&&a.start()}function k(a,b){a.addEventListener('message',b)}function l(a,b){a.removeEventListener('message',b)}function m(a){return'MessagePort'===a.constructor.name}function n(a){return['window','length','location','parent','opener'].every((b)=>b in a)}function o(a,b,c){const d=`${v}-${z++}`;return new Promise((e)=>{k(a,function b(c){c.data.id!==d||(l(a,b),e(c))}),b=Object.assign({},b,{id:d}),a.postMessage(b,c)})}function p(a,b=[]){return new Proxy(function(){},{construct(c,d){return a({type:'CONSTRUCT',callPath:b,argumentsList:d})},apply(c,d,e){return'bind'===b[b.length-1]?p(a,b.slice(0,-1)):a({type:'APPLY',callPath:b,argumentsList:e})},get(c,d,e){if('then'===d&&0===b.length)return{then:()=>e};if('then'===d){const c=a({type:'GET',callPath:b});return Promise.resolve(c).then.bind(c)}return p(a,b.concat(d))},set(c,d,e){return a({type:'SET',callPath:b,property:d,value:e})}})}function q(a){return u.some((b)=>a instanceof b)}function*s(a,b=[],c=null){if(a&&(c||(c=new WeakSet),!c.has(a))&&'string'!=typeof a&&('object'==typeof a&&c.add(a),!ArrayBuffer.isView(a))){yield{value:a,path:b};const d=Object.keys(a);for(const e of d)yield*s(a[e],[...b,e],c)}}function r(a){const b=[];for(const c of s(a))q(c.value)&&b.push(c.value);return b}function t(a){for(const[b,c]of y.entries())if(c.canHandle(a)){const d=c.serialize(a);return{value:{type:b,value:d}}}return{value:{type:'RAW',value:a}}}const u=[ArrayBuffer,MessagePort],v=Math.floor(Math.random()*Number.MAX_SAFE_INTEGER),w=Symbol('proxyValue'),x=Symbol('throw'),y=new Map([['PROXY',{canHandle:(a)=>a&&a[w],serialize:(a)=>{const{port1:b,port2:d}=new MessageChannel;return c(a,b),d},deserialize:(b)=>a(b)}],['THROW',{canHandle:(a)=>a&&a[x],serialize:(a)=>a.toString()+'\n'+a.stack,deserialize:(a)=>{throw Error(a)}}]]);let z=0;return{proxy:a,proxyValue:b,transferHandlers:y,expose:c}}();d.transferHandlers.set('FUNCTION',{canHandle(a){return a instanceof Function},serialize(a){const{port1:b,port2:c}=new MessageChannel;return d.expose(a,b),c},deserialize(a){return d.proxy(a)}}),d.transferHandlers.set('EVENT',{canHandle(a){return a instanceof Event},serialize(a){return{targetId:a&&a.target&&a.target.id,targetClassList:a&&a.target&&a.target.classList&&[...a.target.classList],detail:a&&a.detail,data:a&&a.data}},deserialize(a){return a}});const e=d.proxyValue;let f='document'in self?document.currentScript&&document.currentScript.src:'';const g={maxNumContainers:1,newWorkerFunc:async()=>new Worker(f)};class h{constructor(a={}){this._nextIndex=0,this._options=Object.assign({},g,a),this._containers=Array(this._options.maxNumContainers).fill(null)}async _initOrGetContainer(a){if(a>=this._containers.length)throw Error('No worker available');if(!this._containers[a]){const c=await this._options.newWorkerFunc(),e=d.proxy(c);this._containers[a]={spawn:e.spawn.bind(b),terminate:c.terminate.bind(c)}}return this._containers[a]}async _getNextContainer(){const a=await this._initOrGetContainer(this._nextIndex);return this._nextIndex=(this._nextIndex+1)%this._options.maxNumContainers,a}async spawn(a,b=[],c={}){const d=await this._getNextContainer(c);return await d.spawn(a.toString(),b)}async terminate(){this._containers.filter((a)=>a).forEach((a)=>a.terminate()),this._containers.length=0}get terminated(){return 0>=this._containers.length}}let i=new h;return function(){const a=self.WorkerGlobalScope;return a&&self instanceof a}()&&c(),a.asRemoteValue=e,a.defaultWorkerSrc=f,a.defaultOpts=g,a.RoundRobinStrategy=h,a.defaultStrategy=i,a.spawn=b,a.makeContainer=c,a.Comlink=d,a}({});

@@ -13,4 +13,4 @@ /**

*/
import { Endpoint } from 'comlink';
export { Comlink } from 'comlink';
import { Endpoint } from 'comlinkjs';
export { Comlink } from 'comlinkjs';
/**

@@ -17,0 +17,0 @@ * `asRemoteValue` marks a value. If a marked value is used as an parameter or return value, it will not be transferred but instead proxied.

@@ -13,3 +13,3 @@ /**

*/
import { Comlink } from 'comlink'; // eslint-disable-line no-unused-vars
import { Comlink } from 'comlinkjs'; // eslint-disable-line no-unused-vars
// Automatically proxy functions

@@ -46,3 +46,3 @@ Comlink.transferHandlers.set('FUNCTION', {

});
export { Comlink } from 'comlink';
export { Comlink } from 'comlinkjs';
/**

@@ -49,0 +49,0 @@ * `asRemoteValue` marks a value. If a marked value is used as an parameter or return value, it will not be transferred but instead proxied.

@@ -14,2 +14,2 @@ /**

*/
import{Comlink}from'comlink';Comlink.transferHandlers.set('FUNCTION',{canHandle(a){return a instanceof Function},serialize(a){const{port1:b,port2:c}=new MessageChannel;return Comlink.expose(a,b),c},deserialize(a){return Comlink.proxy(a)}}),Comlink.transferHandlers.set('EVENT',{canHandle(a){return a instanceof Event},serialize(a){return{targetId:a&&a.target&&a.target.id,targetClassList:a&&a.target&&a.target.classList&&[...a.target.classList],detail:a&&a.detail,data:a&&a.data}},deserialize(a){return a}});export{Comlink}from'comlink';export const asRemoteValue=Comlink.proxyValue;export let defaultWorkerSrc='document'in self?document.currentScript&&document.currentScript.src:'';export const defaultOpts={maxNumContainers:1,newWorkerFunc:async()=>new Worker(defaultWorkerSrc)};export class RoundRobinStrategy{constructor(a={}){this._nextIndex=0,this._options=Object.assign({},defaultOpts,a),this._containers=Array(this._options.maxNumContainers).fill(null)}async _initOrGetContainer(a){if(a>=this._containers.length)throw Error('No worker available');if(!this._containers[a]){const b=await this._options.newWorkerFunc(),c=Comlink.proxy(b);this._containers[a]={spawn:c.spawn.bind(spawn),terminate:b.terminate.bind(b)}}return this._containers[a]}async _getNextContainer(){const a=await this._initOrGetContainer(this._nextIndex);return this._nextIndex=(this._nextIndex+1)%this._options.maxNumContainers,a}async spawn(a,b=[],c={}){const d=await this._getNextContainer(c);return await d.spawn(a.toString(),b)}async terminate(){this._containers.filter((a)=>a).forEach((a)=>a.terminate()),this._containers.length=0}get terminated(){return 0>=this._containers.length}}export let defaultStrategy=new RoundRobinStrategy;export async function spawn(a,b=[],c={}){return defaultStrategy.spawn(a,b,c)}export function makeContainer(a=self){Comlink.expose({async spawn(a,b){const c=new Function(`return ${a};`)();return Comlink.proxyValue(new c(...b))}},a)}function isWorker(){const a=self.WorkerGlobalScope;return a&&self instanceof a}isWorker()&&makeContainer();
import{Comlink}from'comlinkjs';Comlink.transferHandlers.set('FUNCTION',{canHandle(a){return a instanceof Function},serialize(a){const{port1:b,port2:c}=new MessageChannel;return Comlink.expose(a,b),c},deserialize(a){return Comlink.proxy(a)}}),Comlink.transferHandlers.set('EVENT',{canHandle(a){return a instanceof Event},serialize(a){return{targetId:a&&a.target&&a.target.id,targetClassList:a&&a.target&&a.target.classList&&[...a.target.classList],detail:a&&a.detail,data:a&&a.data}},deserialize(a){return a}});export{Comlink}from'comlinkjs';export const asRemoteValue=Comlink.proxyValue;export let defaultWorkerSrc='document'in self?document.currentScript&&document.currentScript.src:'';export const defaultOpts={maxNumContainers:1,newWorkerFunc:async()=>new Worker(defaultWorkerSrc)};export class RoundRobinStrategy{constructor(a={}){this._nextIndex=0,this._options=Object.assign({},defaultOpts,a),this._containers=Array(this._options.maxNumContainers).fill(null)}async _initOrGetContainer(a){if(a>=this._containers.length)throw Error('No worker available');if(!this._containers[a]){const b=await this._options.newWorkerFunc(),c=Comlink.proxy(b);this._containers[a]={spawn:c.spawn.bind(spawn),terminate:b.terminate.bind(b)}}return this._containers[a]}async _getNextContainer(){const a=await this._initOrGetContainer(this._nextIndex);return this._nextIndex=(this._nextIndex+1)%this._options.maxNumContainers,a}async spawn(a,b=[],c={}){const d=await this._getNextContainer(c);return await d.spawn(a.toString(),b)}async terminate(){this._containers.filter((a)=>a).forEach((a)=>a.terminate()),this._containers.length=0}get terminated(){return 0>=this._containers.length}}export let defaultStrategy=new RoundRobinStrategy;export async function spawn(a,b=[],c={}){return defaultStrategy.spawn(a,b,c)}export function makeContainer(a=self){Comlink.expose({async spawn(a,b){const c=new Function(`return ${a};`)();return Comlink.proxyValue(new c(...b))}},a)}function isWorker(){const a=self.WorkerGlobalScope;return a&&self instanceof a}isWorker()&&makeContainer();
{
"name": "clooneyjs",
"version": "0.6.2",
"version": "0.6.3",
"description": "Clooney is an actor library for the web",

@@ -34,3 +34,3 @@ "main": "clooney.js",

"chai": "4.1.2",
"comlinkjs": "2.3.4",
"comlinkjs": "^2.3.5",
"eslint": "4.19.0",

@@ -37,0 +37,0 @@ "eslint-config-google": "0.9.1",

@@ -106,3 +106,3 @@ # Clooney

```html
<script src="https://cdn.jsdelivr.net/npm/clooneyjs@0.6.2/clooney.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clooneyjs@0.6.3/clooney.bundle.min.js"></script>
<script>

@@ -109,0 +109,0 @@ async function newWorkerFunc() {

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