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

@agoric/transform-eventual-send

Package Overview
Dependencies
Maintainers
4
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@agoric/transform-eventual-send - npm Package Compare versions

Comparing version 1.0.3 to 1.1.0

51

dist/transform-eventual-send.cjs.js
'use strict';
var eventualSendBundle = {"source":"function getExport() { 'use strict'; let exports = {}; const module = { exports }; 'use strict';\n\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault$1 (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden = _interopDefault$1(require('@agoric/harden'));\n\n/* global */\n\nconst readOnlyProxy = {\n set(_target, _prop, _value) {\n return false;\n },\n isExtensible(_target) {\n return false;\n },\n setPrototypeOf(_target, _value) {\n return false;\n },\n deleteProperty(_target, _prop) {\n return false;\n },\n};\n\n/**\n * A Proxy handler for E(x).\n *\n * @param {*} x Any value passed to E(x)\n * @returns {ProxyHandler} the Proxy handler\n */\nfunction EProxyHandler(x, HandledPromise) {\n return harden({\n ...readOnlyProxy,\n get(_target, p, _receiver) {\n if (`${p}` !== p) {\n return undefined;\n }\n // Harden this Promise because it's our only opportunity to ensure\n // p1=E(x).foo() is hardened. The Handled Promise API does not (yet)\n // allow the handler to synchronously influence the promise returned\n // by the handled methods, so we must freeze it from the outside. See\n // #95 for details.\n return (...args) => harden(HandledPromise.applyMethod(x, p, args));\n },\n apply(_target, _thisArg, argArray = []) {\n return harden(HandledPromise.applyFunction(x, argArray));\n },\n has(_target, _p) {\n // We just pretend everything exists.\n return true;\n },\n });\n}\n\nfunction makeE(HandledPromise) {\n function E(x) {\n const handler = EProxyHandler(x, HandledPromise);\n return harden(new Proxy(() => {}, handler));\n }\n\n const makeEGetterProxy = x =>\n new Proxy(Object.create(null), {\n ...readOnlyProxy,\n has(_target, _prop) {\n return true;\n },\n get(_target, prop) {\n return HandledPromise.get(x, prop);\n },\n });\n\n E.G = makeEGetterProxy;\n E.resolve = HandledPromise.resolve;\n\n return harden(E);\n}\n\n/* global HandledPromise */\n\nconst { defineProperties, getOwnPropertyDescriptors } = Object;\n\n// 'E' and 'HandledPromise' are exports of the module\n\n// For now:\n// import { HandledPromise, E } from '@agoric/eventual-send';\n// ...\n\nconst hp =\n typeof HandledPromise === 'undefined'\n ? // eslint-disable-next-line no-use-before-define\n makeHandledPromise(Promise)\n : harden(HandledPromise);\nconst E = makeE(hp);\n\n// the following method (makeHandledPromise) is part\n// of the shim, and will not be exported by the module once the feature\n// becomes a part of standard javascript\n\n/**\n * Create a HandledPromise class to have it support eventual send\n * (wavy-dot) operations.\n *\n * Based heavily on nanoq\n * https://github.com/drses/nanoq/blob/master/src/nanoq.js\n *\n * Original spec for the infix-bang (predecessor to wavy-dot) desugaring:\n * https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency\n *\n * @return {typeof HandledPromise} Handled promise\n */\nfunction makeHandledPromise(Promise) {\n // xs doesn't support WeakMap in pre-loaded closures\n // aka \"vetted customization code\"\n let presenceToHandler;\n let presenceToPromise;\n let promiseToHandler;\n function ensureMaps() {\n if (!presenceToHandler) {\n presenceToHandler = new WeakMap();\n presenceToPromise = new WeakMap();\n promiseToHandler = new WeakMap();\n }\n }\n\n // This special handler accepts Promises, and forwards\n // handled Promises to their corresponding fulfilledHandler.\n let forwardingHandler;\n let handle;\n let handledPromiseResolve;\n\n function HandledPromise(executor, unfulfilledHandler = undefined) {\n if (new.target === undefined) {\n throw new Error('must be invoked with \"new\"');\n }\n let handledResolve;\n let handledReject;\n let fulfilled = false;\n const superExecutor = (resolve, reject) => {\n handledResolve = value => {\n fulfilled = true;\n resolve(value);\n };\n handledReject = err => {\n fulfilled = true;\n reject(err);\n };\n };\n const handledP = harden(\n Reflect.construct(Promise, [superExecutor], new.target),\n );\n\n ensureMaps();\n let continueForwarding = () => {};\n\n if (!unfulfilledHandler) {\n // Create a simple unfulfilledHandler that just postpones until the\n // fulfilledHandler is set.\n //\n // This is insufficient for actual remote handled Promises\n // (too many round-trips), but is an easy way to create a\n // local handled Promise.\n const interlockP = new Promise((resolve, reject) => {\n continueForwarding = (err = null, targetP = undefined) => {\n if (err !== null) {\n reject(err);\n return;\n }\n // Box the target promise so that it isn't further resolved.\n resolve([targetP]);\n // Return undefined.\n };\n });\n\n const makePostponed = postponedOperation => {\n // Just wait until the handler is resolved/rejected.\n return function postpone(x, ...args) {\n // console.log(`forwarding ${postponedOperation} ${args[0]}`);\n return new HandledPromise((resolve, reject) => {\n interlockP\n .then(([targetP]) => {\n // If targetP is a handled promise, use it, otherwise x.\n const nextPromise = targetP || x;\n resolve(\n HandledPromise[postponedOperation](nextPromise, ...args),\n );\n })\n .catch(reject);\n });\n };\n };\n\n unfulfilledHandler = {\n get: makePostponed('get'),\n applyMethod: makePostponed('applyMethod'),\n };\n }\n\n const validateHandler = h => {\n if (Object(h) !== h) {\n throw TypeError(`Handler ${h} cannot be a primitive`);\n }\n };\n validateHandler(unfulfilledHandler);\n\n // Until the handled promise is resolved, we use the unfulfilledHandler.\n promiseToHandler.set(handledP, unfulfilledHandler);\n\n const rejectHandled = reason => {\n if (fulfilled) {\n return;\n }\n handledReject(reason);\n continueForwarding(reason);\n };\n\n let resolvedPresence = null;\n const resolveWithPresence = presenceHandler => {\n if (fulfilled) {\n return resolvedPresence;\n }\n try {\n // Sanity checks.\n validateHandler(presenceHandler);\n\n // Validate and install our mapped target (i.e. presence).\n resolvedPresence = Object.create(null);\n\n // Create table entries for the presence mapped to the\n // fulfilledHandler.\n presenceToPromise.set(resolvedPresence, handledP);\n presenceToHandler.set(resolvedPresence, presenceHandler);\n\n // Remove the mapping, as our presenceHandler should be\n // used instead.\n promiseToHandler.delete(handledP);\n\n // We committed to this presence, so resolve.\n handledResolve(resolvedPresence);\n continueForwarding();\n return resolvedPresence;\n } catch (e) {\n handledReject(e);\n continueForwarding();\n throw e;\n }\n };\n\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\n if (fulfilled) {\n return undefined;\n }\n try {\n if (deprecatedPresenceHandler) {\n throw TypeError(\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\n );\n }\n\n // Resolve with the target when it's ready.\n handledResolve(target);\n\n const existingUnfulfilledHandler = promiseToHandler.get(target);\n if (existingUnfulfilledHandler) {\n // Reuse the unfulfilled handler.\n promiseToHandler.set(handledP, existingUnfulfilledHandler);\n return continueForwarding(null, target);\n }\n\n // See if the target is a presence we already know of.\n const presence = await target;\n const existingPresenceHandler = presenceToHandler.get(presence);\n if (existingPresenceHandler) {\n promiseToHandler.set(handledP, existingPresenceHandler);\n return continueForwarding(null, handledP);\n }\n\n // Remove the mapping, as we don't need a handler.\n promiseToHandler.delete(handledP);\n return continueForwarding();\n } catch (e) {\n handledReject(e);\n }\n return continueForwarding();\n };\n\n // Invoke the callback to let the user resolve/reject.\n executor(\n (...args) => {\n resolveHandled(...args);\n },\n rejectHandled,\n resolveWithPresence,\n );\n return handledP;\n }\n\n HandledPromise.prototype = Promise.prototype;\n\n // Uncomment this line if needed for conformance to the proposal.\n // Currently the proposal does not specify this, but we might change\n // our mind.\n // Object.setPrototypeOf(HandledPromise, Promise);\n\n const staticMethods = harden({\n get(target, key) {\n return handle(target, 'get', key);\n },\n getSendOnly(target, key) {\n handle(target, 'get', key);\n },\n applyFunction(target, args) {\n return handle(target, 'applyMethod', undefined, args);\n },\n applyFunctionSendOnly(target, args) {\n handle(target, 'applyMethod', undefined, args);\n },\n applyMethod(target, key, args) {\n return handle(target, 'applyMethod', key, args);\n },\n applyMethodSendOnly(target, key, args) {\n handle(target, 'applyMethod', key, args);\n },\n resolve(value) {\n ensureMaps();\n // Resolving a Presence returns the pre-registered handled promise.\n const handledPromise = presenceToPromise.get(value);\n if (handledPromise) {\n return handledPromise;\n }\n const basePromise = Promise.resolve(value);\n if (basePromise === value) {\n return value;\n }\n return handledPromiseResolve(value);\n },\n });\n\n defineProperties(HandledPromise, getOwnPropertyDescriptors(staticMethods));\n\n function makeForwarder(operation, localImpl) {\n return (o, ...args) => {\n // We are in another turn already, and have the naked object.\n const fulfilledHandler = presenceToHandler.get(o);\n if (\n fulfilledHandler &&\n typeof fulfilledHandler[operation] === 'function'\n ) {\n // The handler was resolved, so use it.\n return fulfilledHandler[operation](o, ...args);\n }\n\n // Not handled, so use the local implementation.\n return localImpl(o, ...args);\n };\n }\n\n // eslint-disable-next-line prefer-const\n forwardingHandler = {\n get: makeForwarder('get', (o, key) => o[key]),\n applyMethod: makeForwarder('applyMethod', (o, optKey, args) => {\n if (optKey === undefined || optKey === null) {\n return o(...args);\n }\n // console.log(`sending`, optKey, o[optKey], o);\n if (typeof o[optKey] !== 'function') {\n throw TypeError(`o[${JSON.stringify(optKey)}] is not a function`);\n }\n return o[optKey](...args);\n }),\n };\n\n handle = (p, operation, ...args) => {\n ensureMaps();\n const unfulfilledHandler = promiseToHandler.get(p);\n let executor;\n if (\n unfulfilledHandler &&\n typeof unfulfilledHandler[operation] === 'function'\n ) {\n executor = (resolve, reject) => {\n // We run in a future turn to prevent synchronous attacks,\n HandledPromise.resolve()\n .then(() =>\n // and resolve to the answer from the specific unfulfilled handler,\n resolve(unfulfilledHandler[operation](p, ...args)),\n )\n .catch(reject);\n };\n } else {\n executor = (resolve, reject) => {\n // We run in a future turn to prevent synchronous attacks,\n HandledPromise.resolve(p)\n .then(o => {\n // We now have the naked object,\n if (typeof forwardingHandler[operation] !== 'function') {\n throw TypeError(\n `forwardingHandler.${operation} is not a function`,\n );\n }\n // and resolve to the forwardingHandler's operation.\n resolve(forwardingHandler[operation](o, ...args));\n })\n .catch(reject);\n };\n }\n\n // We return a handled promise with the default unfulfilled handler.\n // This prevents a race between the above Promise.resolves and\n // pipelining.\n return new HandledPromise(executor);\n };\n\n handledPromiseResolve = Promise.resolve.bind(HandledPromise);\n return harden(HandledPromise);\n}\n\nexports.E = E;\nexports.HandledPromise = hp;\nexports.makeHandledPromise = makeHandledPromise;\n\n\nreturn module.exports;\n}\n","sourceMap":"//# sourceURL=/home/ubuntu/agoric-sdk/packages/eventual-send/dist/eventual-send.cjs.js\n","moduleFormat":"getExport"};
function makeEventualSendTransformer(parser, generate) {
let HandledPromise;
let evaluateProgram;
let myRequire;
let recursive = false;
const transform = {
closeOverSES(s) {
// FIXME: This will go away when we can bundle an @agoric/harden that understands SES.
myRequire = name => {
if (name === '@agoric/harden') {
return s.global.SES.harden;
}
throw Error(`Unrecognized require ${name}`);
};
// FIXME: This should be replaced with ss.evaluateProgram support in SES.
evaluateProgram = (src, endowments = {}) => s.evaluate(src, endowments);
},
rewrite(ss) {
const source = ss.src;
const endowments = ss.endowments || {};
if (!recursive && !('HandledPromise' in endowments)) {
// Use a getter to postpone initialization.
Object.defineProperty(endowments, 'HandledPromise', {
get() {
if (!HandledPromise) {
// Get a HandledPromise endowment for the evaluator.
// It will be hardened in the evaluator's context.
const { source: evSendSrc, moduleFormat } = eventualSendBundle;
if (moduleFormat === 'getExport') {
recursive = true;
try {
const ns = (evaluateProgram || ss.evaluateProgram)(
`(${evSendSrc})()`,
{ require: myRequire || require },
);
HandledPromise = ns.HandledPromise;
} finally {
recursive = false;
}
} else {
throw Error(`Unrecognized moduleFormat ${moduleFormat}`);
}
}
return HandledPromise;
},
});
}
// Parse with eventualSend enabled, rewriting to
// HandledPromise.got/set/apply/applyMethod/delete(...)
const source = ss.src;
// HandledPromise.get/applyFunction/applyMethod(...)
const parseFunc = parser.parse;

@@ -28,2 +74,3 @@ const ast = (parseFunc || parser)(source, {

ast,
endowments,
src: actualSource,

@@ -30,0 +77,0 @@ };

@@ -0,7 +1,53 @@

var eventualSendBundle = {"source":"function getExport() { 'use strict'; let exports = {}; const module = { exports }; 'use strict';\n\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault$1 (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden = _interopDefault$1(require('@agoric/harden'));\n\n/* global */\n\nconst readOnlyProxy = {\n set(_target, _prop, _value) {\n return false;\n },\n isExtensible(_target) {\n return false;\n },\n setPrototypeOf(_target, _value) {\n return false;\n },\n deleteProperty(_target, _prop) {\n return false;\n },\n};\n\n/**\n * A Proxy handler for E(x).\n *\n * @param {*} x Any value passed to E(x)\n * @returns {ProxyHandler} the Proxy handler\n */\nfunction EProxyHandler(x, HandledPromise) {\n return harden({\n ...readOnlyProxy,\n get(_target, p, _receiver) {\n if (`${p}` !== p) {\n return undefined;\n }\n // Harden this Promise because it's our only opportunity to ensure\n // p1=E(x).foo() is hardened. The Handled Promise API does not (yet)\n // allow the handler to synchronously influence the promise returned\n // by the handled methods, so we must freeze it from the outside. See\n // #95 for details.\n return (...args) => harden(HandledPromise.applyMethod(x, p, args));\n },\n apply(_target, _thisArg, argArray = []) {\n return harden(HandledPromise.applyFunction(x, argArray));\n },\n has(_target, _p) {\n // We just pretend everything exists.\n return true;\n },\n });\n}\n\nfunction makeE(HandledPromise) {\n function E(x) {\n const handler = EProxyHandler(x, HandledPromise);\n return harden(new Proxy(() => {}, handler));\n }\n\n const makeEGetterProxy = x =>\n new Proxy(Object.create(null), {\n ...readOnlyProxy,\n has(_target, _prop) {\n return true;\n },\n get(_target, prop) {\n return HandledPromise.get(x, prop);\n },\n });\n\n E.G = makeEGetterProxy;\n E.resolve = HandledPromise.resolve;\n\n return harden(E);\n}\n\n/* global HandledPromise */\n\nconst { defineProperties, getOwnPropertyDescriptors } = Object;\n\n// 'E' and 'HandledPromise' are exports of the module\n\n// For now:\n// import { HandledPromise, E } from '@agoric/eventual-send';\n// ...\n\nconst hp =\n typeof HandledPromise === 'undefined'\n ? // eslint-disable-next-line no-use-before-define\n makeHandledPromise(Promise)\n : harden(HandledPromise);\nconst E = makeE(hp);\n\n// the following method (makeHandledPromise) is part\n// of the shim, and will not be exported by the module once the feature\n// becomes a part of standard javascript\n\n/**\n * Create a HandledPromise class to have it support eventual send\n * (wavy-dot) operations.\n *\n * Based heavily on nanoq\n * https://github.com/drses/nanoq/blob/master/src/nanoq.js\n *\n * Original spec for the infix-bang (predecessor to wavy-dot) desugaring:\n * https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency\n *\n * @return {typeof HandledPromise} Handled promise\n */\nfunction makeHandledPromise(Promise) {\n // xs doesn't support WeakMap in pre-loaded closures\n // aka \"vetted customization code\"\n let presenceToHandler;\n let presenceToPromise;\n let promiseToHandler;\n function ensureMaps() {\n if (!presenceToHandler) {\n presenceToHandler = new WeakMap();\n presenceToPromise = new WeakMap();\n promiseToHandler = new WeakMap();\n }\n }\n\n // This special handler accepts Promises, and forwards\n // handled Promises to their corresponding fulfilledHandler.\n let forwardingHandler;\n let handle;\n let handledPromiseResolve;\n\n function HandledPromise(executor, unfulfilledHandler = undefined) {\n if (new.target === undefined) {\n throw new Error('must be invoked with \"new\"');\n }\n let handledResolve;\n let handledReject;\n let fulfilled = false;\n const superExecutor = (resolve, reject) => {\n handledResolve = value => {\n fulfilled = true;\n resolve(value);\n };\n handledReject = err => {\n fulfilled = true;\n reject(err);\n };\n };\n const handledP = harden(\n Reflect.construct(Promise, [superExecutor], new.target),\n );\n\n ensureMaps();\n let continueForwarding = () => {};\n\n if (!unfulfilledHandler) {\n // Create a simple unfulfilledHandler that just postpones until the\n // fulfilledHandler is set.\n //\n // This is insufficient for actual remote handled Promises\n // (too many round-trips), but is an easy way to create a\n // local handled Promise.\n const interlockP = new Promise((resolve, reject) => {\n continueForwarding = (err = null, targetP = undefined) => {\n if (err !== null) {\n reject(err);\n return;\n }\n // Box the target promise so that it isn't further resolved.\n resolve([targetP]);\n // Return undefined.\n };\n });\n\n const makePostponed = postponedOperation => {\n // Just wait until the handler is resolved/rejected.\n return function postpone(x, ...args) {\n // console.log(`forwarding ${postponedOperation} ${args[0]}`);\n return new HandledPromise((resolve, reject) => {\n interlockP\n .then(([targetP]) => {\n // If targetP is a handled promise, use it, otherwise x.\n const nextPromise = targetP || x;\n resolve(\n HandledPromise[postponedOperation](nextPromise, ...args),\n );\n })\n .catch(reject);\n });\n };\n };\n\n unfulfilledHandler = {\n get: makePostponed('get'),\n applyMethod: makePostponed('applyMethod'),\n };\n }\n\n const validateHandler = h => {\n if (Object(h) !== h) {\n throw TypeError(`Handler ${h} cannot be a primitive`);\n }\n };\n validateHandler(unfulfilledHandler);\n\n // Until the handled promise is resolved, we use the unfulfilledHandler.\n promiseToHandler.set(handledP, unfulfilledHandler);\n\n const rejectHandled = reason => {\n if (fulfilled) {\n return;\n }\n handledReject(reason);\n continueForwarding(reason);\n };\n\n let resolvedPresence = null;\n const resolveWithPresence = presenceHandler => {\n if (fulfilled) {\n return resolvedPresence;\n }\n try {\n // Sanity checks.\n validateHandler(presenceHandler);\n\n // Validate and install our mapped target (i.e. presence).\n resolvedPresence = Object.create(null);\n\n // Create table entries for the presence mapped to the\n // fulfilledHandler.\n presenceToPromise.set(resolvedPresence, handledP);\n presenceToHandler.set(resolvedPresence, presenceHandler);\n\n // Remove the mapping, as our presenceHandler should be\n // used instead.\n promiseToHandler.delete(handledP);\n\n // We committed to this presence, so resolve.\n handledResolve(resolvedPresence);\n continueForwarding();\n return resolvedPresence;\n } catch (e) {\n handledReject(e);\n continueForwarding();\n throw e;\n }\n };\n\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\n if (fulfilled) {\n return undefined;\n }\n try {\n if (deprecatedPresenceHandler) {\n throw TypeError(\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\n );\n }\n\n // Resolve with the target when it's ready.\n handledResolve(target);\n\n const existingUnfulfilledHandler = promiseToHandler.get(target);\n if (existingUnfulfilledHandler) {\n // Reuse the unfulfilled handler.\n promiseToHandler.set(handledP, existingUnfulfilledHandler);\n return continueForwarding(null, target);\n }\n\n // See if the target is a presence we already know of.\n const presence = await target;\n const existingPresenceHandler = presenceToHandler.get(presence);\n if (existingPresenceHandler) {\n promiseToHandler.set(handledP, existingPresenceHandler);\n return continueForwarding(null, handledP);\n }\n\n // Remove the mapping, as we don't need a handler.\n promiseToHandler.delete(handledP);\n return continueForwarding();\n } catch (e) {\n handledReject(e);\n }\n return continueForwarding();\n };\n\n // Invoke the callback to let the user resolve/reject.\n executor(\n (...args) => {\n resolveHandled(...args);\n },\n rejectHandled,\n resolveWithPresence,\n );\n return handledP;\n }\n\n HandledPromise.prototype = Promise.prototype;\n\n // Uncomment this line if needed for conformance to the proposal.\n // Currently the proposal does not specify this, but we might change\n // our mind.\n // Object.setPrototypeOf(HandledPromise, Promise);\n\n const staticMethods = harden({\n get(target, key) {\n return handle(target, 'get', key);\n },\n getSendOnly(target, key) {\n handle(target, 'get', key);\n },\n applyFunction(target, args) {\n return handle(target, 'applyMethod', undefined, args);\n },\n applyFunctionSendOnly(target, args) {\n handle(target, 'applyMethod', undefined, args);\n },\n applyMethod(target, key, args) {\n return handle(target, 'applyMethod', key, args);\n },\n applyMethodSendOnly(target, key, args) {\n handle(target, 'applyMethod', key, args);\n },\n resolve(value) {\n ensureMaps();\n // Resolving a Presence returns the pre-registered handled promise.\n const handledPromise = presenceToPromise.get(value);\n if (handledPromise) {\n return handledPromise;\n }\n const basePromise = Promise.resolve(value);\n if (basePromise === value) {\n return value;\n }\n return handledPromiseResolve(value);\n },\n });\n\n defineProperties(HandledPromise, getOwnPropertyDescriptors(staticMethods));\n\n function makeForwarder(operation, localImpl) {\n return (o, ...args) => {\n // We are in another turn already, and have the naked object.\n const fulfilledHandler = presenceToHandler.get(o);\n if (\n fulfilledHandler &&\n typeof fulfilledHandler[operation] === 'function'\n ) {\n // The handler was resolved, so use it.\n return fulfilledHandler[operation](o, ...args);\n }\n\n // Not handled, so use the local implementation.\n return localImpl(o, ...args);\n };\n }\n\n // eslint-disable-next-line prefer-const\n forwardingHandler = {\n get: makeForwarder('get', (o, key) => o[key]),\n applyMethod: makeForwarder('applyMethod', (o, optKey, args) => {\n if (optKey === undefined || optKey === null) {\n return o(...args);\n }\n // console.log(`sending`, optKey, o[optKey], o);\n if (typeof o[optKey] !== 'function') {\n throw TypeError(`o[${JSON.stringify(optKey)}] is not a function`);\n }\n return o[optKey](...args);\n }),\n };\n\n handle = (p, operation, ...args) => {\n ensureMaps();\n const unfulfilledHandler = promiseToHandler.get(p);\n let executor;\n if (\n unfulfilledHandler &&\n typeof unfulfilledHandler[operation] === 'function'\n ) {\n executor = (resolve, reject) => {\n // We run in a future turn to prevent synchronous attacks,\n HandledPromise.resolve()\n .then(() =>\n // and resolve to the answer from the specific unfulfilled handler,\n resolve(unfulfilledHandler[operation](p, ...args)),\n )\n .catch(reject);\n };\n } else {\n executor = (resolve, reject) => {\n // We run in a future turn to prevent synchronous attacks,\n HandledPromise.resolve(p)\n .then(o => {\n // We now have the naked object,\n if (typeof forwardingHandler[operation] !== 'function') {\n throw TypeError(\n `forwardingHandler.${operation} is not a function`,\n );\n }\n // and resolve to the forwardingHandler's operation.\n resolve(forwardingHandler[operation](o, ...args));\n })\n .catch(reject);\n };\n }\n\n // We return a handled promise with the default unfulfilled handler.\n // This prevents a race between the above Promise.resolves and\n // pipelining.\n return new HandledPromise(executor);\n };\n\n handledPromiseResolve = Promise.resolve.bind(HandledPromise);\n return harden(HandledPromise);\n}\n\nexports.E = E;\nexports.HandledPromise = hp;\nexports.makeHandledPromise = makeHandledPromise;\n\n\nreturn module.exports;\n}\n","sourceMap":"//# sourceURL=/home/ubuntu/agoric-sdk/packages/eventual-send/dist/eventual-send.cjs.js\n","moduleFormat":"getExport"};
function makeEventualSendTransformer(parser, generate) {
let HandledPromise;
let evaluateProgram;
let myRequire;
let recursive = false;
const transform = {
closeOverSES(s) {
// FIXME: This will go away when we can bundle an @agoric/harden that understands SES.
myRequire = name => {
if (name === '@agoric/harden') {
return s.global.SES.harden;
}
throw Error(`Unrecognized require ${name}`);
};
// FIXME: This should be replaced with ss.evaluateProgram support in SES.
evaluateProgram = (src, endowments = {}) => s.evaluate(src, endowments);
},
rewrite(ss) {
const source = ss.src;
const endowments = ss.endowments || {};
if (!recursive && !('HandledPromise' in endowments)) {
// Use a getter to postpone initialization.
Object.defineProperty(endowments, 'HandledPromise', {
get() {
if (!HandledPromise) {
// Get a HandledPromise endowment for the evaluator.
// It will be hardened in the evaluator's context.
const { source: evSendSrc, moduleFormat } = eventualSendBundle;
if (moduleFormat === 'getExport') {
recursive = true;
try {
const ns = (evaluateProgram || ss.evaluateProgram)(
`(${evSendSrc})()`,
{ require: myRequire || require },
);
HandledPromise = ns.HandledPromise;
} finally {
recursive = false;
}
} else {
throw Error(`Unrecognized moduleFormat ${moduleFormat}`);
}
}
return HandledPromise;
},
});
}
// Parse with eventualSend enabled, rewriting to
// HandledPromise.got/set/apply/applyMethod/delete(...)
const source = ss.src;
// HandledPromise.get/applyFunction/applyMethod(...)
const parseFunc = parser.parse;

@@ -26,2 +72,3 @@ const ast = (parseFunc || parser)(source, {

ast,
endowments,
src: actualSource,

@@ -28,0 +75,0 @@ };

@@ -5,10 +5,56 @@ (function (global, factory) {

(global = global || self, global.makeEventalSendTransformer = factory());
}(this, function () { 'use strict';
}(this, (function () { 'use strict';
var eventualSendBundle = {"source":"function getExport() { 'use strict'; let exports = {}; const module = { exports }; 'use strict';\n\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault$1 (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden = _interopDefault$1(require('@agoric/harden'));\n\n/* global */\n\nconst readOnlyProxy = {\n set(_target, _prop, _value) {\n return false;\n },\n isExtensible(_target) {\n return false;\n },\n setPrototypeOf(_target, _value) {\n return false;\n },\n deleteProperty(_target, _prop) {\n return false;\n },\n};\n\n/**\n * A Proxy handler for E(x).\n *\n * @param {*} x Any value passed to E(x)\n * @returns {ProxyHandler} the Proxy handler\n */\nfunction EProxyHandler(x, HandledPromise) {\n return harden({\n ...readOnlyProxy,\n get(_target, p, _receiver) {\n if (`${p}` !== p) {\n return undefined;\n }\n // Harden this Promise because it's our only opportunity to ensure\n // p1=E(x).foo() is hardened. The Handled Promise API does not (yet)\n // allow the handler to synchronously influence the promise returned\n // by the handled methods, so we must freeze it from the outside. See\n // #95 for details.\n return (...args) => harden(HandledPromise.applyMethod(x, p, args));\n },\n apply(_target, _thisArg, argArray = []) {\n return harden(HandledPromise.applyFunction(x, argArray));\n },\n has(_target, _p) {\n // We just pretend everything exists.\n return true;\n },\n });\n}\n\nfunction makeE(HandledPromise) {\n function E(x) {\n const handler = EProxyHandler(x, HandledPromise);\n return harden(new Proxy(() => {}, handler));\n }\n\n const makeEGetterProxy = x =>\n new Proxy(Object.create(null), {\n ...readOnlyProxy,\n has(_target, _prop) {\n return true;\n },\n get(_target, prop) {\n return HandledPromise.get(x, prop);\n },\n });\n\n E.G = makeEGetterProxy;\n E.resolve = HandledPromise.resolve;\n\n return harden(E);\n}\n\n/* global HandledPromise */\n\nconst { defineProperties, getOwnPropertyDescriptors } = Object;\n\n// 'E' and 'HandledPromise' are exports of the module\n\n// For now:\n// import { HandledPromise, E } from '@agoric/eventual-send';\n// ...\n\nconst hp =\n typeof HandledPromise === 'undefined'\n ? // eslint-disable-next-line no-use-before-define\n makeHandledPromise(Promise)\n : harden(HandledPromise);\nconst E = makeE(hp);\n\n// the following method (makeHandledPromise) is part\n// of the shim, and will not be exported by the module once the feature\n// becomes a part of standard javascript\n\n/**\n * Create a HandledPromise class to have it support eventual send\n * (wavy-dot) operations.\n *\n * Based heavily on nanoq\n * https://github.com/drses/nanoq/blob/master/src/nanoq.js\n *\n * Original spec for the infix-bang (predecessor to wavy-dot) desugaring:\n * https://web.archive.org/web/20161026162206/http://wiki.ecmascript.org/doku.php?id=strawman:concurrency\n *\n * @return {typeof HandledPromise} Handled promise\n */\nfunction makeHandledPromise(Promise) {\n // xs doesn't support WeakMap in pre-loaded closures\n // aka \"vetted customization code\"\n let presenceToHandler;\n let presenceToPromise;\n let promiseToHandler;\n function ensureMaps() {\n if (!presenceToHandler) {\n presenceToHandler = new WeakMap();\n presenceToPromise = new WeakMap();\n promiseToHandler = new WeakMap();\n }\n }\n\n // This special handler accepts Promises, and forwards\n // handled Promises to their corresponding fulfilledHandler.\n let forwardingHandler;\n let handle;\n let handledPromiseResolve;\n\n function HandledPromise(executor, unfulfilledHandler = undefined) {\n if (new.target === undefined) {\n throw new Error('must be invoked with \"new\"');\n }\n let handledResolve;\n let handledReject;\n let fulfilled = false;\n const superExecutor = (resolve, reject) => {\n handledResolve = value => {\n fulfilled = true;\n resolve(value);\n };\n handledReject = err => {\n fulfilled = true;\n reject(err);\n };\n };\n const handledP = harden(\n Reflect.construct(Promise, [superExecutor], new.target),\n );\n\n ensureMaps();\n let continueForwarding = () => {};\n\n if (!unfulfilledHandler) {\n // Create a simple unfulfilledHandler that just postpones until the\n // fulfilledHandler is set.\n //\n // This is insufficient for actual remote handled Promises\n // (too many round-trips), but is an easy way to create a\n // local handled Promise.\n const interlockP = new Promise((resolve, reject) => {\n continueForwarding = (err = null, targetP = undefined) => {\n if (err !== null) {\n reject(err);\n return;\n }\n // Box the target promise so that it isn't further resolved.\n resolve([targetP]);\n // Return undefined.\n };\n });\n\n const makePostponed = postponedOperation => {\n // Just wait until the handler is resolved/rejected.\n return function postpone(x, ...args) {\n // console.log(`forwarding ${postponedOperation} ${args[0]}`);\n return new HandledPromise((resolve, reject) => {\n interlockP\n .then(([targetP]) => {\n // If targetP is a handled promise, use it, otherwise x.\n const nextPromise = targetP || x;\n resolve(\n HandledPromise[postponedOperation](nextPromise, ...args),\n );\n })\n .catch(reject);\n });\n };\n };\n\n unfulfilledHandler = {\n get: makePostponed('get'),\n applyMethod: makePostponed('applyMethod'),\n };\n }\n\n const validateHandler = h => {\n if (Object(h) !== h) {\n throw TypeError(`Handler ${h} cannot be a primitive`);\n }\n };\n validateHandler(unfulfilledHandler);\n\n // Until the handled promise is resolved, we use the unfulfilledHandler.\n promiseToHandler.set(handledP, unfulfilledHandler);\n\n const rejectHandled = reason => {\n if (fulfilled) {\n return;\n }\n handledReject(reason);\n continueForwarding(reason);\n };\n\n let resolvedPresence = null;\n const resolveWithPresence = presenceHandler => {\n if (fulfilled) {\n return resolvedPresence;\n }\n try {\n // Sanity checks.\n validateHandler(presenceHandler);\n\n // Validate and install our mapped target (i.e. presence).\n resolvedPresence = Object.create(null);\n\n // Create table entries for the presence mapped to the\n // fulfilledHandler.\n presenceToPromise.set(resolvedPresence, handledP);\n presenceToHandler.set(resolvedPresence, presenceHandler);\n\n // Remove the mapping, as our presenceHandler should be\n // used instead.\n promiseToHandler.delete(handledP);\n\n // We committed to this presence, so resolve.\n handledResolve(resolvedPresence);\n continueForwarding();\n return resolvedPresence;\n } catch (e) {\n handledReject(e);\n continueForwarding();\n throw e;\n }\n };\n\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\n if (fulfilled) {\n return undefined;\n }\n try {\n if (deprecatedPresenceHandler) {\n throw TypeError(\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\n );\n }\n\n // Resolve with the target when it's ready.\n handledResolve(target);\n\n const existingUnfulfilledHandler = promiseToHandler.get(target);\n if (existingUnfulfilledHandler) {\n // Reuse the unfulfilled handler.\n promiseToHandler.set(handledP, existingUnfulfilledHandler);\n return continueForwarding(null, target);\n }\n\n // See if the target is a presence we already know of.\n const presence = await target;\n const existingPresenceHandler = presenceToHandler.get(presence);\n if (existingPresenceHandler) {\n promiseToHandler.set(handledP, existingPresenceHandler);\n return continueForwarding(null, handledP);\n }\n\n // Remove the mapping, as we don't need a handler.\n promiseToHandler.delete(handledP);\n return continueForwarding();\n } catch (e) {\n handledReject(e);\n }\n return continueForwarding();\n };\n\n // Invoke the callback to let the user resolve/reject.\n executor(\n (...args) => {\n resolveHandled(...args);\n },\n rejectHandled,\n resolveWithPresence,\n );\n return handledP;\n }\n\n HandledPromise.prototype = Promise.prototype;\n\n // Uncomment this line if needed for conformance to the proposal.\n // Currently the proposal does not specify this, but we might change\n // our mind.\n // Object.setPrototypeOf(HandledPromise, Promise);\n\n const staticMethods = harden({\n get(target, key) {\n return handle(target, 'get', key);\n },\n getSendOnly(target, key) {\n handle(target, 'get', key);\n },\n applyFunction(target, args) {\n return handle(target, 'applyMethod', undefined, args);\n },\n applyFunctionSendOnly(target, args) {\n handle(target, 'applyMethod', undefined, args);\n },\n applyMethod(target, key, args) {\n return handle(target, 'applyMethod', key, args);\n },\n applyMethodSendOnly(target, key, args) {\n handle(target, 'applyMethod', key, args);\n },\n resolve(value) {\n ensureMaps();\n // Resolving a Presence returns the pre-registered handled promise.\n const handledPromise = presenceToPromise.get(value);\n if (handledPromise) {\n return handledPromise;\n }\n const basePromise = Promise.resolve(value);\n if (basePromise === value) {\n return value;\n }\n return handledPromiseResolve(value);\n },\n });\n\n defineProperties(HandledPromise, getOwnPropertyDescriptors(staticMethods));\n\n function makeForwarder(operation, localImpl) {\n return (o, ...args) => {\n // We are in another turn already, and have the naked object.\n const fulfilledHandler = presenceToHandler.get(o);\n if (\n fulfilledHandler &&\n typeof fulfilledHandler[operation] === 'function'\n ) {\n // The handler was resolved, so use it.\n return fulfilledHandler[operation](o, ...args);\n }\n\n // Not handled, so use the local implementation.\n return localImpl(o, ...args);\n };\n }\n\n // eslint-disable-next-line prefer-const\n forwardingHandler = {\n get: makeForwarder('get', (o, key) => o[key]),\n applyMethod: makeForwarder('applyMethod', (o, optKey, args) => {\n if (optKey === undefined || optKey === null) {\n return o(...args);\n }\n // console.log(`sending`, optKey, o[optKey], o);\n if (typeof o[optKey] !== 'function') {\n throw TypeError(`o[${JSON.stringify(optKey)}] is not a function`);\n }\n return o[optKey](...args);\n }),\n };\n\n handle = (p, operation, ...args) => {\n ensureMaps();\n const unfulfilledHandler = promiseToHandler.get(p);\n let executor;\n if (\n unfulfilledHandler &&\n typeof unfulfilledHandler[operation] === 'function'\n ) {\n executor = (resolve, reject) => {\n // We run in a future turn to prevent synchronous attacks,\n HandledPromise.resolve()\n .then(() =>\n // and resolve to the answer from the specific unfulfilled handler,\n resolve(unfulfilledHandler[operation](p, ...args)),\n )\n .catch(reject);\n };\n } else {\n executor = (resolve, reject) => {\n // We run in a future turn to prevent synchronous attacks,\n HandledPromise.resolve(p)\n .then(o => {\n // We now have the naked object,\n if (typeof forwardingHandler[operation] !== 'function') {\n throw TypeError(\n `forwardingHandler.${operation} is not a function`,\n );\n }\n // and resolve to the forwardingHandler's operation.\n resolve(forwardingHandler[operation](o, ...args));\n })\n .catch(reject);\n };\n }\n\n // We return a handled promise with the default unfulfilled handler.\n // This prevents a race between the above Promise.resolves and\n // pipelining.\n return new HandledPromise(executor);\n };\n\n handledPromiseResolve = Promise.resolve.bind(HandledPromise);\n return harden(HandledPromise);\n}\n\nexports.E = E;\nexports.HandledPromise = hp;\nexports.makeHandledPromise = makeHandledPromise;\n\n\nreturn module.exports;\n}\n","sourceMap":"//# sourceURL=/home/ubuntu/agoric-sdk/packages/eventual-send/dist/eventual-send.cjs.js\n","moduleFormat":"getExport"};
function makeEventualSendTransformer(parser, generate) {
let HandledPromise;
let evaluateProgram;
let myRequire;
let recursive = false;
const transform = {
closeOverSES(s) {
// FIXME: This will go away when we can bundle an @agoric/harden that understands SES.
myRequire = name => {
if (name === '@agoric/harden') {
return s.global.SES.harden;
}
throw Error(`Unrecognized require ${name}`);
};
// FIXME: This should be replaced with ss.evaluateProgram support in SES.
evaluateProgram = (src, endowments = {}) => s.evaluate(src, endowments);
},
rewrite(ss) {
const source = ss.src;
const endowments = ss.endowments || {};
if (!recursive && !('HandledPromise' in endowments)) {
// Use a getter to postpone initialization.
Object.defineProperty(endowments, 'HandledPromise', {
get() {
if (!HandledPromise) {
// Get a HandledPromise endowment for the evaluator.
// It will be hardened in the evaluator's context.
const { source: evSendSrc, moduleFormat } = eventualSendBundle;
if (moduleFormat === 'getExport') {
recursive = true;
try {
const ns = (evaluateProgram || ss.evaluateProgram)(
`(${evSendSrc})()`,
{ require: myRequire || require },
);
HandledPromise = ns.HandledPromise;
} finally {
recursive = false;
}
} else {
throw Error(`Unrecognized moduleFormat ${moduleFormat}`);
}
}
return HandledPromise;
},
});
}
// Parse with eventualSend enabled, rewriting to
// HandledPromise.got/set/apply/applyMethod/delete(...)
const source = ss.src;
// HandledPromise.get/applyFunction/applyMethod(...)
const parseFunc = parser.parse;

@@ -33,2 +79,3 @@ const ast = (parseFunc || parser)(source, {

ast,
endowments,
src: actualSource,

@@ -44,2 +91,2 @@ };

}));
})));

24

package.json
{
"name": "@agoric/transform-eventual-send",
"version": "1.0.3",
"version": "1.1.0",
"description": "transform-eventual-send",

@@ -12,18 +12,13 @@ "main": "dist/transform-eventual-send.cjs.js",

"lint-check": "eslint '**/*.{js,jsx}'",
"build": "rollup -c rollup.config.js"
"build": "node -r esm ./scripts/build-esend.js && rollup -c rollup.config.js"
},
"devDependencies": {
"@agoric/acorn-eventual-send": "^1.0.2",
"@agoric/acorn-eventual-send": "^2.0.0",
"@agoric/babel-parser": "^7.6.4",
"@agoric/eventual-send": "^0.4.4",
"@agoric/bundle-source": "^1.0.4",
"@agoric/eventual-send": "^0.5.0",
"@agoric/harden": "^0.0.4",
"@babel/generator": "^7.5.0",
"astring": "^1.4.0",
"eslint": "^5.11.1",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^3.3.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.12.0",
"prettier": "^1.16.4",
"esm": "^3.2.5",
"rollup": "^1.16.6",

@@ -36,6 +31,3 @@ "rollup-plugin-node-resolve": "^5.2.0",

},
"dependencies": {
"@agoric/harden": "0.0.4",
"esm": "^3.2.5"
},
"dependencies": {},
"keywords": [],

@@ -42,0 +34,0 @@ "files": [

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