Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@agoric/transform-bang

Package Overview
Dependencies
Maintainers
4
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agoric/transform-bang - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

227

dist/transform-bang.cjs.js
'use strict';
/**
* Modify a Promise class to have it support eventual send (infix-bang) operations.
*
* Based heavily on nanoq https://github.com/drses/nanoq/blob/master/src/nanoq.js
*
* Original spec for the infix-bang desugaring:
* https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
*
* @param {typeof Promise} Promise ES6 Promise class to shim
* @return {typeof EPromise} Extended promise
*/
function maybeExtendPromise(Promise) {
// Make idempotent, so we don't layer on top of a BasePromise that is adequate.
if (typeof Promise.makeHandled === 'function') {
return Promise;
}
const presenceToHandler = new WeakMap();
const presenceToPromise = new WeakMap();
const promiseToHandler = new WeakMap();
// This special handler accepts Promises, and forwards
// handled Promises to their corresponding resolvedHandler.
//
// If passed a Promise that is not handled, perform
// the corresponding local operation.
let forwardingHandler;
function handler(p) {
return promiseToHandler.get(p) || forwardingHandler;
}
Object.defineProperties(
Promise.prototype,
Object.getOwnPropertyDescriptors({
get(key) {
return handler(this).GET(this, key);
},
put(key, val) {
return handler(this).PUT(this, key, val);
},
delete(key) {
return handler(this).DELETE(this, key);
},
post(optKey, args) {
return handler(this).POST(this, optKey, args);
},
invoke(optKey, ...args) {
return handler(this).POST(this, optKey, args);
},
fapply(args) {
return handler(this).POST(this, undefined, args);
},
fcall(...args) {
return handler(this).POST(this, undefined, args);
},
}),
);
const baseResolve = Promise.resolve.bind(Promise);
// Add Promise.makeHandled and update Promise.resolve.
Object.defineProperties(
Promise,
Object.getOwnPropertyDescriptors({
resolve(value) {
// Resolving a Presence returns the pre-registered handled promise.
const handledPromise = presenceToPromise.get(value);
if (handledPromise) {
return handledPromise;
}
return baseResolve(value);
},
makeHandled(executor, unresolvedHandler) {
let handledResolve;
let handledReject;
let resolveTheHandler;
const handledP = new Promise((resolve, reject) => {
handledResolve = resolve;
handledReject = reject;
});
if (!unresolvedHandler) {
// Create a simple unresolvedHandler that just postpones until the
// resolvedHandler is set.
//
// This is insufficient for actual remote handled Promises
// (too many round-trips), but is an easy way to create a local handled Promise.
const handlerP = new Promise(resolve => {
resolveTheHandler = resolve;
});
const postpone = forwardedOperation => {
// Just wait until the handler is resolved/rejected.
return async (p, ...args) => {
// console.log(`forwarding ${forwardedOperation}`);
await handlerP;
return p[forwardedOperation](args);
};
};
unresolvedHandler = {
GET: postpone('get'),
PUT: postpone('put'),
DELETE: postpone('delete'),
POST: postpone('post'),
};
}
// Until the handled promise is resolved, we use the unresolvedHandler.
promiseToHandler.set(handledP, unresolvedHandler);
function rejectHandled(reason) {
if (resolveTheHandler) {
resolveTheHandler(null);
}
handledReject(reason);
}
function resolveHandled(presence, resolvedHandler) {
try {
if (resolvedHandler) {
// Sanity checks.
if (Object(resolvedHandler) !== resolvedHandler) {
throw TypeError(
`Resolved handler ${resolvedHandler} cannot be a primitive`,
);
}
for (const method of ['GET', 'PUT', 'DELETE', 'POST']) {
if (typeof resolvedHandler[method] !== 'function') {
throw TypeError(
`Resolved handler ${resolvedHandler} requires a ${method} method`,
);
}
}
if (Object(presence) !== presence) {
throw TypeError(`Presence ${presence} cannot be a primitive`);
}
if (presence === null) {
throw TypeError(`Presence ${presence} cannot be null`);
}
if (presenceToHandler.has(presence)) {
throw TypeError(`Presence ${presence} is already mapped`);
}
if (presence && typeof presence.then === 'function') {
throw TypeError(
`Presence ${presence} cannot be a Promise or other thenable`,
);
}
// Create table entries for the presence mapped to the resolvedHandler.
presenceToPromise.set(presence, handledP);
presenceToHandler.set(presence, resolvedHandler);
}
// Remove the mapping, as our resolvedHandler should be used instead.
promiseToHandler.delete(handledP);
// Resolve with the new presence or other value.
handledResolve(presence);
if (resolveTheHandler) {
// Activate the default unresolvedHandler.
resolveTheHandler(resolvedHandler);
}
} catch (e) {
rejectHandled(e);
}
}
// Invoke the callback to let the user resolve/reject.
executor(resolveHandled, rejectHandled);
// Return a handled Promise, which wil be resolved/rejected
// by the executor.
return handledP;
},
}),
);
function makeForwarder(operation, localImpl) {
return async (ep, ...args) => {
const o = await ep;
const resolvedHandler = presenceToHandler.get(o);
if (resolvedHandler) {
// The handler was resolved, so give it a naked object.
return resolvedHandler[operation](o, ...args);
}
// Not a handled Promise, so use the local implementation on the
// naked object.
return localImpl(o, ...args);
};
}
forwardingHandler = {
GET: makeForwarder('GET', (o, key) => o[key]),
PUT: makeForwarder('PUT', (o, key, val) => (o[key] = val)),
DELETE: makeForwarder('DELETE', (o, key) => delete o[key]),
POST: makeForwarder('POST', (o, optKey, args) => {
if (optKey === undefined || optKey === null) {
return o(...args);
}
return o[optKey](...args);
}),
};
return Promise;
}
const EPromise = maybeExtendPromise(Promise);
// Attempt to patch the platform.
(typeof window === 'undefined' ? global : window).Promise = EPromise;
function makeBangTransformer(parse, generate) {
const transform = {
init(r) {
r.global.Promise = r.evaluate(`(${maybeExtendPromise})`)(
r.global.Promise,
);
},
rewrite(rs) {

@@ -247,2 +21,3 @@ // Parse with infixBang enabled, rewriting to

};
return [transform];

@@ -249,0 +24,0 @@ }

@@ -1,229 +0,3 @@

/**
* Modify a Promise class to have it support eventual send (infix-bang) operations.
*
* Based heavily on nanoq https://github.com/drses/nanoq/blob/master/src/nanoq.js
*
* Original spec for the infix-bang desugaring:
* https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
*
* @param {typeof Promise} Promise ES6 Promise class to shim
* @return {typeof EPromise} Extended promise
*/
function maybeExtendPromise(Promise) {
// Make idempotent, so we don't layer on top of a BasePromise that is adequate.
if (typeof Promise.makeHandled === 'function') {
return Promise;
}
const presenceToHandler = new WeakMap();
const presenceToPromise = new WeakMap();
const promiseToHandler = new WeakMap();
// This special handler accepts Promises, and forwards
// handled Promises to their corresponding resolvedHandler.
//
// If passed a Promise that is not handled, perform
// the corresponding local operation.
let forwardingHandler;
function handler(p) {
return promiseToHandler.get(p) || forwardingHandler;
}
Object.defineProperties(
Promise.prototype,
Object.getOwnPropertyDescriptors({
get(key) {
return handler(this).GET(this, key);
},
put(key, val) {
return handler(this).PUT(this, key, val);
},
delete(key) {
return handler(this).DELETE(this, key);
},
post(optKey, args) {
return handler(this).POST(this, optKey, args);
},
invoke(optKey, ...args) {
return handler(this).POST(this, optKey, args);
},
fapply(args) {
return handler(this).POST(this, undefined, args);
},
fcall(...args) {
return handler(this).POST(this, undefined, args);
},
}),
);
const baseResolve = Promise.resolve.bind(Promise);
// Add Promise.makeHandled and update Promise.resolve.
Object.defineProperties(
Promise,
Object.getOwnPropertyDescriptors({
resolve(value) {
// Resolving a Presence returns the pre-registered handled promise.
const handledPromise = presenceToPromise.get(value);
if (handledPromise) {
return handledPromise;
}
return baseResolve(value);
},
makeHandled(executor, unresolvedHandler) {
let handledResolve;
let handledReject;
let resolveTheHandler;
const handledP = new Promise((resolve, reject) => {
handledResolve = resolve;
handledReject = reject;
});
if (!unresolvedHandler) {
// Create a simple unresolvedHandler that just postpones until the
// resolvedHandler is set.
//
// This is insufficient for actual remote handled Promises
// (too many round-trips), but is an easy way to create a local handled Promise.
const handlerP = new Promise(resolve => {
resolveTheHandler = resolve;
});
const postpone = forwardedOperation => {
// Just wait until the handler is resolved/rejected.
return async (p, ...args) => {
// console.log(`forwarding ${forwardedOperation}`);
await handlerP;
return p[forwardedOperation](args);
};
};
unresolvedHandler = {
GET: postpone('get'),
PUT: postpone('put'),
DELETE: postpone('delete'),
POST: postpone('post'),
};
}
// Until the handled promise is resolved, we use the unresolvedHandler.
promiseToHandler.set(handledP, unresolvedHandler);
function rejectHandled(reason) {
if (resolveTheHandler) {
resolveTheHandler(null);
}
handledReject(reason);
}
function resolveHandled(presence, resolvedHandler) {
try {
if (resolvedHandler) {
// Sanity checks.
if (Object(resolvedHandler) !== resolvedHandler) {
throw TypeError(
`Resolved handler ${resolvedHandler} cannot be a primitive`,
);
}
for (const method of ['GET', 'PUT', 'DELETE', 'POST']) {
if (typeof resolvedHandler[method] !== 'function') {
throw TypeError(
`Resolved handler ${resolvedHandler} requires a ${method} method`,
);
}
}
if (Object(presence) !== presence) {
throw TypeError(`Presence ${presence} cannot be a primitive`);
}
if (presence === null) {
throw TypeError(`Presence ${presence} cannot be null`);
}
if (presenceToHandler.has(presence)) {
throw TypeError(`Presence ${presence} is already mapped`);
}
if (presence && typeof presence.then === 'function') {
throw TypeError(
`Presence ${presence} cannot be a Promise or other thenable`,
);
}
// Create table entries for the presence mapped to the resolvedHandler.
presenceToPromise.set(presence, handledP);
presenceToHandler.set(presence, resolvedHandler);
}
// Remove the mapping, as our resolvedHandler should be used instead.
promiseToHandler.delete(handledP);
// Resolve with the new presence or other value.
handledResolve(presence);
if (resolveTheHandler) {
// Activate the default unresolvedHandler.
resolveTheHandler(resolvedHandler);
}
} catch (e) {
rejectHandled(e);
}
}
// Invoke the callback to let the user resolve/reject.
executor(resolveHandled, rejectHandled);
// Return a handled Promise, which wil be resolved/rejected
// by the executor.
return handledP;
},
}),
);
function makeForwarder(operation, localImpl) {
return async (ep, ...args) => {
const o = await ep;
const resolvedHandler = presenceToHandler.get(o);
if (resolvedHandler) {
// The handler was resolved, so give it a naked object.
return resolvedHandler[operation](o, ...args);
}
// Not a handled Promise, so use the local implementation on the
// naked object.
return localImpl(o, ...args);
};
}
forwardingHandler = {
GET: makeForwarder('GET', (o, key) => o[key]),
PUT: makeForwarder('PUT', (o, key, val) => (o[key] = val)),
DELETE: makeForwarder('DELETE', (o, key) => delete o[key]),
POST: makeForwarder('POST', (o, optKey, args) => {
if (optKey === undefined || optKey === null) {
return o(...args);
}
return o[optKey](...args);
}),
};
return Promise;
}
const EPromise = maybeExtendPromise(Promise);
// Attempt to patch the platform.
(typeof window === 'undefined' ? global : window).Promise = EPromise;
function makeBangTransformer(parse, generate) {
const transform = {
init(r) {
r.global.Promise = r.evaluate(`(${maybeExtendPromise})`)(
r.global.Promise,
);
},
rewrite(rs) {

@@ -245,2 +19,3 @@ // Parse with infixBang enabled, rewriting to

};
return [transform];

@@ -247,0 +22,0 @@ }

@@ -7,230 +7,4 @@ (function (global, factory) {

/**
* Modify a Promise class to have it support eventual send (infix-bang) operations.
*
* Based heavily on nanoq https://github.com/drses/nanoq/blob/master/src/nanoq.js
*
* Original spec for the infix-bang desugaring:
* https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency
*
* @param {typeof Promise} Promise ES6 Promise class to shim
* @return {typeof EPromise} Extended promise
*/
function maybeExtendPromise(Promise) {
// Make idempotent, so we don't layer on top of a BasePromise that is adequate.
if (typeof Promise.makeHandled === 'function') {
return Promise;
}
const presenceToHandler = new WeakMap();
const presenceToPromise = new WeakMap();
const promiseToHandler = new WeakMap();
// This special handler accepts Promises, and forwards
// handled Promises to their corresponding resolvedHandler.
//
// If passed a Promise that is not handled, perform
// the corresponding local operation.
let forwardingHandler;
function handler(p) {
return promiseToHandler.get(p) || forwardingHandler;
}
Object.defineProperties(
Promise.prototype,
Object.getOwnPropertyDescriptors({
get(key) {
return handler(this).GET(this, key);
},
put(key, val) {
return handler(this).PUT(this, key, val);
},
delete(key) {
return handler(this).DELETE(this, key);
},
post(optKey, args) {
return handler(this).POST(this, optKey, args);
},
invoke(optKey, ...args) {
return handler(this).POST(this, optKey, args);
},
fapply(args) {
return handler(this).POST(this, undefined, args);
},
fcall(...args) {
return handler(this).POST(this, undefined, args);
},
}),
);
const baseResolve = Promise.resolve.bind(Promise);
// Add Promise.makeHandled and update Promise.resolve.
Object.defineProperties(
Promise,
Object.getOwnPropertyDescriptors({
resolve(value) {
// Resolving a Presence returns the pre-registered handled promise.
const handledPromise = presenceToPromise.get(value);
if (handledPromise) {
return handledPromise;
}
return baseResolve(value);
},
makeHandled(executor, unresolvedHandler) {
let handledResolve;
let handledReject;
let resolveTheHandler;
const handledP = new Promise((resolve, reject) => {
handledResolve = resolve;
handledReject = reject;
});
if (!unresolvedHandler) {
// Create a simple unresolvedHandler that just postpones until the
// resolvedHandler is set.
//
// This is insufficient for actual remote handled Promises
// (too many round-trips), but is an easy way to create a local handled Promise.
const handlerP = new Promise(resolve => {
resolveTheHandler = resolve;
});
const postpone = forwardedOperation => {
// Just wait until the handler is resolved/rejected.
return async (p, ...args) => {
// console.log(`forwarding ${forwardedOperation}`);
await handlerP;
return p[forwardedOperation](args);
};
};
unresolvedHandler = {
GET: postpone('get'),
PUT: postpone('put'),
DELETE: postpone('delete'),
POST: postpone('post'),
};
}
// Until the handled promise is resolved, we use the unresolvedHandler.
promiseToHandler.set(handledP, unresolvedHandler);
function rejectHandled(reason) {
if (resolveTheHandler) {
resolveTheHandler(null);
}
handledReject(reason);
}
function resolveHandled(presence, resolvedHandler) {
try {
if (resolvedHandler) {
// Sanity checks.
if (Object(resolvedHandler) !== resolvedHandler) {
throw TypeError(
`Resolved handler ${resolvedHandler} cannot be a primitive`,
);
}
for (const method of ['GET', 'PUT', 'DELETE', 'POST']) {
if (typeof resolvedHandler[method] !== 'function') {
throw TypeError(
`Resolved handler ${resolvedHandler} requires a ${method} method`,
);
}
}
if (Object(presence) !== presence) {
throw TypeError(`Presence ${presence} cannot be a primitive`);
}
if (presence === null) {
throw TypeError(`Presence ${presence} cannot be null`);
}
if (presenceToHandler.has(presence)) {
throw TypeError(`Presence ${presence} is already mapped`);
}
if (presence && typeof presence.then === 'function') {
throw TypeError(
`Presence ${presence} cannot be a Promise or other thenable`,
);
}
// Create table entries for the presence mapped to the resolvedHandler.
presenceToPromise.set(presence, handledP);
presenceToHandler.set(presence, resolvedHandler);
}
// Remove the mapping, as our resolvedHandler should be used instead.
promiseToHandler.delete(handledP);
// Resolve with the new presence or other value.
handledResolve(presence);
if (resolveTheHandler) {
// Activate the default unresolvedHandler.
resolveTheHandler(resolvedHandler);
}
} catch (e) {
rejectHandled(e);
}
}
// Invoke the callback to let the user resolve/reject.
executor(resolveHandled, rejectHandled);
// Return a handled Promise, which wil be resolved/rejected
// by the executor.
return handledP;
},
}),
);
function makeForwarder(operation, localImpl) {
return async (ep, ...args) => {
const o = await ep;
const resolvedHandler = presenceToHandler.get(o);
if (resolvedHandler) {
// The handler was resolved, so give it a naked object.
return resolvedHandler[operation](o, ...args);
}
// Not a handled Promise, so use the local implementation on the
// naked object.
return localImpl(o, ...args);
};
}
forwardingHandler = {
GET: makeForwarder('GET', (o, key) => o[key]),
PUT: makeForwarder('PUT', (o, key, val) => (o[key] = val)),
DELETE: makeForwarder('DELETE', (o, key) => delete o[key]),
POST: makeForwarder('POST', (o, optKey, args) => {
if (optKey === undefined || optKey === null) {
return o(...args);
}
return o[optKey](...args);
}),
};
return Promise;
}
const EPromise = maybeExtendPromise(Promise);
// Attempt to patch the platform.
(typeof window === 'undefined' ? global : window).Promise = EPromise;
function makeBangTransformer(parse, generate) {
const transform = {
init(r) {
r.global.Promise = r.evaluate(`(${maybeExtendPromise})`)(
r.global.Promise,
);
},
rewrite(rs) {

@@ -252,2 +26,3 @@ // Parse with infixBang enabled, rewriting to

};
return [transform];

@@ -254,0 +29,0 @@ }

6

package.json
{
"name": "@agoric/transform-bang",
"version": "0.3.0",
"version": "0.3.1",
"description": "transform-bang",

@@ -31,2 +31,3 @@ "main": "dist/transform-bang.cjs.js",

"rollup-plugin-node-resolve": "^5.2.0",
"ses": "^0.5.1",
"tap-spec": "^5.0.0",

@@ -38,4 +39,3 @@ "tape": "^4.9.2",

"@agoric/harden": "0.0.4",
"esm": "^3.2.5",
"ses": "file:ses-0.5.1.tgz"
"esm": "^3.2.5"
},

@@ -42,0 +42,0 @@ "keywords": [],

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