@agoric/transform-eventual-send
Advanced tools
Comparing version 1.2.2 to 1.2.3
@@ -6,2 +6,14 @@ # Change Log | ||
## [1.2.3](https://github.com/Agoric/agoric-sdk/compare/@agoric/transform-eventual-send@1.2.2...@agoric/transform-eventual-send@1.2.3) (2020-05-04) | ||
### Bug Fixes | ||
* implement nestedEvaluate where it was missing ([8f7d17f](https://github.com/Agoric/agoric-sdk/commit/8f7d17fe6a0c452df8c701c708d73cc79144071c)) | ||
* use the new (typed) harden package ([2eb1af0](https://github.com/Agoric/agoric-sdk/commit/2eb1af08fe3967629a3ce165752fd501a5c85a96)) | ||
## [1.2.2](https://github.com/Agoric/agoric-sdk/compare/@agoric/transform-eventual-send@1.2.2-alpha.0...@agoric/transform-eventual-send@1.2.2) (2020-04-13) | ||
@@ -8,0 +20,0 @@ |
'use strict'; | ||
var eventualSendBundle = {"source":"function getExport() { 'use strict'; let exports = {}; const module = { exports }; 'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden = _interopDefault(require('@agoric/harden'));\n\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\nfunction commonjsRequire () {\n\tthrow new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');\n}\n\nfunction unwrapExports (x) {\n\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\n}\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nfunction getCjsExportFromNamespace (n) {\n\treturn n && n['default'] || n;\n}\n\nvar eventualSend_cjs = createCommonjsModule(function (module, exports) {\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden$1 = _interopDefault(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$1({\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$1(HandledPromise.applyMethod(x, p, args));\n },\n apply(_target, _thisArg, argArray = []) {\n return harden$1(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$1(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 harden$1(HandledPromise.get(x, prop));\n },\n });\n\n E.G = makeEGetterProxy;\n E.resolve = HandledPromise.resolve;\n E.unwrap = HandledPromise.unwrap;\n\n E.when = (x, onfulfilled = undefined, onrejected = undefined) =>\n HandledPromise.resolve(x).then(onfulfilled, onrejected);\n\n return harden$1(E);\n}\n\n/* global HandledPromise */\n\nconst {\n defineProperties,\n getOwnPropertyDescriptors,\n getOwnPropertyDescriptor: gopd,\n getPrototypeOf,\n isFrozen,\n} = Object;\n\nconst { prototype: promiseProto } = Promise;\nconst { then: originalThen } = promiseProto;\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$1(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 promiseToUnsettledHandler;\n let promiseToPresence; // only for HandledPromise.unwrap\n let forwardedPromiseToPromise; // forwarding, union-find-ish\n function ensureMaps() {\n if (!presenceToHandler) {\n presenceToHandler = new WeakMap();\n presenceToPromise = new WeakMap();\n promiseToUnsettledHandler = new WeakMap();\n promiseToPresence = new WeakMap();\n forwardedPromiseToPromise = new WeakMap();\n }\n }\n\n /**\n * You can imagine a forest of trees in which the roots of each tree is an\n * unresolved HandledPromise or a non-Promise, and each node's parent is the\n * HandledPromise to which it was forwarded. We maintain that mapping of\n * forwarded HandledPromise to its resolution in forwardedPromiseToPromise.\n *\n * We use something like the description of \"Find\" with \"Path splitting\"\n * to propagate changes down to the children efficiently:\n * https://en.wikipedia.org/wiki/Disjoint-set_data_structure\n *\n * @param {*} target Any value.\n * @returns {*} If the target was a HandledPromise, the most-resolved parent of it, otherwise the target.\n */\n function shorten(target) {\n let p = target;\n // Find the most-resolved value for p.\n while (forwardedPromiseToPromise.has(p)) {\n p = forwardedPromiseToPromise.get(p);\n }\n const presence = promiseToPresence.get(p);\n if (presence) {\n // Presences are final, so it is ok to propagate\n // this upstream.\n while (target !== p) {\n const parent = forwardedPromiseToPromise.get(target);\n forwardedPromiseToPromise.delete(target);\n promiseToUnsettledHandler.delete(target);\n promiseToPresence.set(target, presence);\n target = parent;\n }\n } else {\n // We propagate p and remove all other unsettled handlers\n // upstream.\n // Note that everything except presences is covered here.\n while (target !== p) {\n const parent = forwardedPromiseToPromise.get(target);\n forwardedPromiseToPromise.set(target, p);\n promiseToUnsettledHandler.delete(target);\n target = parent;\n }\n }\n return target;\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 promiseResolve;\n\n function HandledPromise(executor, unsettledHandler = undefined) {\n if (new.target === undefined) {\n throw new Error('must be invoked with \"new\"');\n }\n let handledResolve;\n let handledReject;\n let resolved = false;\n let resolvedTarget = null;\n let handledP;\n let continueForwarding = () => {};\n const superExecutor = (superResolve, superReject) => {\n handledResolve = value => {\n if (resolved) {\n return resolvedTarget;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n value = shorten(value);\n let targetP;\n if (\n promiseToUnsettledHandler.has(value) ||\n promiseToPresence.has(value)\n ) {\n targetP = value;\n } else {\n // We're resolving to a non-promise, so remove our handler.\n promiseToUnsettledHandler.delete(handledP);\n targetP = presenceToPromise.get(value);\n }\n // Ensure our data structure is a propert tree (avoid cycles).\n if (targetP && targetP !== handledP) {\n forwardedPromiseToPromise.set(handledP, targetP);\n } else {\n forwardedPromiseToPromise.delete(handledP);\n }\n\n // Remove stale unsettled handlers, set to canonical form.\n shorten(handledP);\n\n // Ensure our unsettledHandler is cleaned up if not already.\n if (promiseToUnsettledHandler.has(handledP)) {\n handledP.then(_ => promiseToUnsettledHandler.delete(handledP));\n }\n\n // Finish the resolution.\n superResolve(value);\n resolved = true;\n resolvedTarget = value;\n\n // We're resolved, so forward any postponed operations to us.\n continueForwarding();\n return resolvedTarget;\n };\n handledReject = err => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n promiseToUnsettledHandler.delete(handledP);\n resolved = true;\n superReject(err);\n continueForwarding();\n };\n };\n handledP = harden$1(Reflect.construct(Promise, [superExecutor], new.target));\n\n ensureMaps();\n\n const makePostponedHandler = () => {\n // Create a simple postponedHandler that just postpones until the\n // fulfilledHandler is set.\n let donePostponing;\n const interlockP = new Promise(resolve => {\n donePostponing = () => resolve();\n });\n\n const makePostponedOperation = 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(_ => {\n // If targetP is a handled promise, use it, otherwise x.\n resolve(HandledPromise[postponedOperation](x, ...args));\n })\n .catch(reject);\n });\n };\n };\n\n const postponedHandler = {\n get: makePostponedOperation('get'),\n applyMethod: makePostponedOperation('applyMethod'),\n };\n return [postponedHandler, donePostponing];\n };\n\n if (!unsettledHandler) {\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 [unsettledHandler, continueForwarding] = makePostponedHandler();\n }\n\n const validateHandler = h => {\n if (Object(h) !== h) {\n throw TypeError(`Handler ${h} cannot be a primitive`);\n }\n };\n validateHandler(unsettledHandler);\n\n // Until the handled promise is resolved, we use the unsettledHandler.\n promiseToUnsettledHandler.set(handledP, unsettledHandler);\n\n const rejectHandled = reason => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n handledReject(reason);\n };\n\n const resolveWithPresence = presenceHandler => {\n if (resolved) {\n return resolvedTarget;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n try {\n // Sanity checks.\n validateHandler(presenceHandler);\n\n // Validate and install our mapped target (i.e. presence).\n resolvedTarget = Object.create(null);\n\n // Create table entries for the presence mapped to the\n // fulfilledHandler.\n presenceToPromise.set(resolvedTarget, handledP);\n promiseToPresence.set(handledP, resolvedTarget);\n presenceToHandler.set(resolvedTarget, presenceHandler);\n\n // We committed to this presence, so resolve.\n handledResolve(resolvedTarget);\n return resolvedTarget;\n } catch (e) {\n handledReject(e);\n throw e;\n }\n };\n\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n try {\n if (deprecatedPresenceHandler) {\n throw TypeError(\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\n );\n }\n\n // Resolve the target.\n handledResolve(target);\n } catch (e) {\n handledReject(e);\n }\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 = promiseProto;\n Object.setPrototypeOf(HandledPromise, Promise);\n\n function isFrozenPromiseThen(p) {\n return (\n isFrozen(p) &&\n getPrototypeOf(p) === promiseProto &&\n promiseResolve(p) === p &&\n gopd(p, 'then') === undefined &&\n gopd(promiseProto, 'then').value === originalThen // unnecessary under SES\n );\n }\n\n const staticMethods = harden$1({\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 let resolvedPromise = presenceToPromise.get(value);\n if (!resolvedPromise) {\n resolvedPromise = promiseResolve(value);\n }\n // Prevent any proxy trickery.\n harden$1(resolvedPromise);\n if (isFrozenPromiseThen(resolvedPromise)) {\n return resolvedPromise;\n }\n // Assimilate the thenable.\n const executeThen = (resolve, reject) =>\n resolvedPromise.then(resolve, reject);\n return harden$1(\n promiseResolve().then(_ => new HandledPromise(executeThen)),\n );\n },\n // TODO verify that this is safe to provide universally, i.e.,\n // that by itself it doesn't provide access to mutable state in\n // ways that violate normal ocap module purity rules. The claim\n // that it does not rests on the handled promise itself being\n // necessary to perceive this mutable state. In that sense, we\n // can think of the right to perceive it, and of access to the\n // target, as being in the handled promise. Note that a .then on\n // the handled promise will already provide async access to the\n // target, so the only additional authorities are: 1)\n // synchronous access for handled promises only, and thus 2) the\n // ability to tell, from the client side, whether a promise is\n // handled. Or, at least, the ability to tell given that the\n // promise is already fulfilled.\n unwrap(value) {\n // This check for Thenable is safe, since in a remote-object\n // environment, our comms system will defend against remote\n // objects being represented as a tricky local Proxy, otherwise\n // it is guaranteed to be local and therefore synchronous enough.\n if (Object(value) !== value || !('then' in value)) {\n // Not a Thenable, so return it.\n // This means that local objects will pass through without error.\n return value;\n }\n\n // Try to look up the HandledPromise.\n ensureMaps();\n const pr = presenceToPromise.get(value) || value;\n\n // Find the fulfilled presence for that HandledPromise.\n const presence = promiseToPresence.get(pr);\n if (!presence) {\n throw TypeError(\n `Value is a Thenble but not a HandledPromise fulfilled to a presence`,\n );\n }\n return presence;\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, ...opArgs) => {\n ensureMaps();\n p = shorten(p);\n const unsettledHandler = promiseToUnsettledHandler.get(p);\n let executor;\n if (unsettledHandler && typeof unsettledHandler[operation] === 'function') {\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 unsettled handler,\n // opArgs are something like [prop] or [method, args],\n // so we don't risk the user's args leaking into this expansion.\n // eslint-disable-next-line no-use-before-define\n resolve(unsettledHandler[operation](p, ...opArgs, returnedP)),\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 // opArgs are something like [prop] or [method, args],\n // so we don't risk the user's args leaking into this expansion.\n // eslint-disable-next-line no-use-before-define\n resolve(forwardingHandler[operation](o, ...opArgs, returnedP));\n })\n .catch(reject);\n };\n }\n\n // We return a handled promise with the default unsettled handler.\n // This prevents a race between the above Promise.resolves and\n // pipelining.\n const returnedP = new HandledPromise(executor);\n return returnedP;\n };\n\n promiseResolve = Promise.resolve.bind(Promise);\n return harden$1(HandledPromise);\n}\n\nexports.E = E;\nexports.HandledPromise = hp;\nexports.makeHandledPromise = makeHandledPromise;\n});\n\nvar eventualSend_cjs$1 = unwrapExports(eventualSend_cjs);\nvar eventualSend_cjs_1 = eventualSend_cjs.E;\nvar eventualSend_cjs_2 = eventualSend_cjs.HandledPromise;\nvar eventualSend_cjs_3 = eventualSend_cjs.makeHandledPromise;\n\nexports.E = eventualSend_cjs_1;\nexports.HandledPromise = eventualSend_cjs_2;\nexports.default = eventualSend_cjs$1;\nexports.makeHandledPromise = eventualSend_cjs_3;\n\n\nreturn module.exports;\n}\n","sourceMap":"//# sourceURL=/Users/michael/agoric/agoric-sdk/packages/eventual-send/dist/eventual-send.cjs.js\n","moduleFormat":"getExport"}; | ||
var eventualSendBundle = {"source":"function getExportWithNestedEvaluate(filePrefix) {\n 'use strict';\n // Serialised sources.\n if (filePrefix === undefined) {\n filePrefix = \"/bundled-source\";\n }\n const moduleFormat = \"nestedEvaluate\";\n const entrypoint = \"eventual-send.cjs.js\";\n const sourceBundle = {\n \"eventual-send.cjs.js\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nvar _commonjsHelpers = require('./_virtual/_commonjsHelpers.js');\\nrequire('@agoric/harden');\\nvar harden_commonjsExternal = require('./_virtual/harden_commonjs-external');\\n\\nvar eventualSend_cjs = _commonjsHelpers.createCommonjsModule(function (module, exports) {\\n'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\\n\\nvar harden = _interopDefault(harden_commonjsExternal.default);\\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 harden(HandledPromise.get(x, prop));\\n },\\n });\\n\\n E.G = makeEGetterProxy;\\n E.resolve = HandledPromise.resolve;\\n E.unwrap = HandledPromise.unwrap;\\n\\n E.when = (x, onfulfilled = undefined, onrejected = undefined) =>\\n HandledPromise.resolve(x).then(onfulfilled, onrejected);\\n\\n return harden(E);\\n}\\n\\n/* global HandledPromise */\\n\\nconst {\\n defineProperties,\\n getOwnPropertyDescriptors,\\n getOwnPropertyDescriptor: gopd,\\n getPrototypeOf,\\n isFrozen,\\n} = Object;\\n\\nconst { prototype: promiseProto } = Promise;\\nconst { then: originalThen } = promiseProto;\\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 promiseToUnsettledHandler;\\n let promiseToPresence; // only for HandledPromise.unwrap\\n let forwardedPromiseToPromise; // forwarding, union-find-ish\\n function ensureMaps() {\\n if (!presenceToHandler) {\\n presenceToHandler = new WeakMap();\\n presenceToPromise = new WeakMap();\\n promiseToUnsettledHandler = new WeakMap();\\n promiseToPresence = new WeakMap();\\n forwardedPromiseToPromise = new WeakMap();\\n }\\n }\\n\\n /**\\n * You can imagine a forest of trees in which the roots of each tree is an\\n * unresolved HandledPromise or a non-Promise, and each node's parent is the\\n * HandledPromise to which it was forwarded. We maintain that mapping of\\n * forwarded HandledPromise to its resolution in forwardedPromiseToPromise.\\n *\\n * We use something like the description of \\\"Find\\\" with \\\"Path splitting\\\"\\n * to propagate changes down to the children efficiently:\\n * https://en.wikipedia.org/wiki/Disjoint-set_data_structure\\n *\\n * @param {*} target Any value.\\n * @returns {*} If the target was a HandledPromise, the most-resolved parent of it, otherwise the target.\\n */\\n function shorten(target) {\\n let p = target;\\n // Find the most-resolved value for p.\\n while (forwardedPromiseToPromise.has(p)) {\\n p = forwardedPromiseToPromise.get(p);\\n }\\n const presence = promiseToPresence.get(p);\\n if (presence) {\\n // Presences are final, so it is ok to propagate\\n // this upstream.\\n while (target !== p) {\\n const parent = forwardedPromiseToPromise.get(target);\\n forwardedPromiseToPromise.delete(target);\\n promiseToUnsettledHandler.delete(target);\\n promiseToPresence.set(target, presence);\\n target = parent;\\n }\\n } else {\\n // We propagate p and remove all other unsettled handlers\\n // upstream.\\n // Note that everything except presences is covered here.\\n while (target !== p) {\\n const parent = forwardedPromiseToPromise.get(target);\\n forwardedPromiseToPromise.set(target, p);\\n promiseToUnsettledHandler.delete(target);\\n target = parent;\\n }\\n }\\n return target;\\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 promiseResolve;\\n\\n function HandledPromise(executor, unsettledHandler = undefined) {\\n if (new.target === undefined) {\\n throw new Error('must be invoked with \\\"new\\\"');\\n }\\n let handledResolve;\\n let handledReject;\\n let resolved = false;\\n let resolvedTarget = null;\\n let handledP;\\n let continueForwarding = () => {};\\n const superExecutor = (superResolve, superReject) => {\\n handledResolve = value => {\\n if (resolved) {\\n return resolvedTarget;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n value = shorten(value);\\n let targetP;\\n if (\\n promiseToUnsettledHandler.has(value) ||\\n promiseToPresence.has(value)\\n ) {\\n targetP = value;\\n } else {\\n // We're resolving to a non-promise, so remove our handler.\\n promiseToUnsettledHandler.delete(handledP);\\n targetP = presenceToPromise.get(value);\\n }\\n // Ensure our data structure is a propert tree (avoid cycles).\\n if (targetP && targetP !== handledP) {\\n forwardedPromiseToPromise.set(handledP, targetP);\\n } else {\\n forwardedPromiseToPromise.delete(handledP);\\n }\\n\\n // Remove stale unsettled handlers, set to canonical form.\\n shorten(handledP);\\n\\n // Ensure our unsettledHandler is cleaned up if not already.\\n if (promiseToUnsettledHandler.has(handledP)) {\\n handledP.then(_ => promiseToUnsettledHandler.delete(handledP));\\n }\\n\\n // Finish the resolution.\\n superResolve(value);\\n resolved = true;\\n resolvedTarget = value;\\n\\n // We're resolved, so forward any postponed operations to us.\\n continueForwarding();\\n return resolvedTarget;\\n };\\n handledReject = err => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n promiseToUnsettledHandler.delete(handledP);\\n resolved = true;\\n superReject(err);\\n continueForwarding();\\n };\\n };\\n handledP = harden(Reflect.construct(Promise, [superExecutor], new.target));\\n\\n ensureMaps();\\n\\n const makePostponedHandler = () => {\\n // Create a simple postponedHandler that just postpones until the\\n // fulfilledHandler is set.\\n let donePostponing;\\n const interlockP = new Promise(resolve => {\\n donePostponing = () => resolve();\\n });\\n\\n const makePostponedOperation = 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(_ => {\\n // If targetP is a handled promise, use it, otherwise x.\\n resolve(HandledPromise[postponedOperation](x, ...args));\\n })\\n .catch(reject);\\n });\\n };\\n };\\n\\n const postponedHandler = {\\n get: makePostponedOperation('get'),\\n applyMethod: makePostponedOperation('applyMethod'),\\n };\\n return [postponedHandler, donePostponing];\\n };\\n\\n if (!unsettledHandler) {\\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 [unsettledHandler, continueForwarding] = makePostponedHandler();\\n }\\n\\n const validateHandler = h => {\\n if (Object(h) !== h) {\\n throw TypeError(`Handler ${h} cannot be a primitive`);\\n }\\n };\\n validateHandler(unsettledHandler);\\n\\n // Until the handled promise is resolved, we use the unsettledHandler.\\n promiseToUnsettledHandler.set(handledP, unsettledHandler);\\n\\n const rejectHandled = reason => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n handledReject(reason);\\n };\\n\\n const resolveWithPresence = presenceHandler => {\\n if (resolved) {\\n return resolvedTarget;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n try {\\n // Sanity checks.\\n validateHandler(presenceHandler);\\n\\n // Validate and install our mapped target (i.e. presence).\\n resolvedTarget = Object.create(null);\\n\\n // Create table entries for the presence mapped to the\\n // fulfilledHandler.\\n presenceToPromise.set(resolvedTarget, handledP);\\n promiseToPresence.set(handledP, resolvedTarget);\\n presenceToHandler.set(resolvedTarget, presenceHandler);\\n\\n // We committed to this presence, so resolve.\\n handledResolve(resolvedTarget);\\n return resolvedTarget;\\n } catch (e) {\\n handledReject(e);\\n throw e;\\n }\\n };\\n\\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n try {\\n if (deprecatedPresenceHandler) {\\n throw TypeError(\\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\\n );\\n }\\n\\n // Resolve the target.\\n handledResolve(target);\\n } catch (e) {\\n handledReject(e);\\n }\\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 = promiseProto;\\n Object.setPrototypeOf(HandledPromise, Promise);\\n\\n function isFrozenPromiseThen(p) {\\n return (\\n isFrozen(p) &&\\n getPrototypeOf(p) === promiseProto &&\\n promiseResolve(p) === p &&\\n gopd(p, 'then') === undefined &&\\n gopd(promiseProto, 'then').value === originalThen // unnecessary under SES\\n );\\n }\\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 let resolvedPromise = presenceToPromise.get(value);\\n if (!resolvedPromise) {\\n resolvedPromise = promiseResolve(value);\\n }\\n // Prevent any proxy trickery.\\n harden(resolvedPromise);\\n if (isFrozenPromiseThen(resolvedPromise)) {\\n return resolvedPromise;\\n }\\n // Assimilate the thenable.\\n const executeThen = (resolve, reject) =>\\n resolvedPromise.then(resolve, reject);\\n return harden(\\n promiseResolve().then(_ => new HandledPromise(executeThen)),\\n );\\n },\\n // TODO verify that this is safe to provide universally, i.e.,\\n // that by itself it doesn't provide access to mutable state in\\n // ways that violate normal ocap module purity rules. The claim\\n // that it does not rests on the handled promise itself being\\n // necessary to perceive this mutable state. In that sense, we\\n // can think of the right to perceive it, and of access to the\\n // target, as being in the handled promise. Note that a .then on\\n // the handled promise will already provide async access to the\\n // target, so the only additional authorities are: 1)\\n // synchronous access for handled promises only, and thus 2) the\\n // ability to tell, from the client side, whether a promise is\\n // handled. Or, at least, the ability to tell given that the\\n // promise is already fulfilled.\\n unwrap(value) {\\n // This check for Thenable is safe, since in a remote-object\\n // environment, our comms system will defend against remote\\n // objects being represented as a tricky local Proxy, otherwise\\n // it is guaranteed to be local and therefore synchronous enough.\\n if (Object(value) !== value || !('then' in value)) {\\n // Not a Thenable, so return it.\\n // This means that local objects will pass through without error.\\n return value;\\n }\\n\\n // Try to look up the HandledPromise.\\n ensureMaps();\\n const pr = presenceToPromise.get(value) || value;\\n\\n // Find the fulfilled presence for that HandledPromise.\\n const presence = promiseToPresence.get(pr);\\n if (!presence) {\\n throw TypeError(\\n `Value is a Thenble but not a HandledPromise fulfilled to a presence`,\\n );\\n }\\n return presence;\\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, ...opArgs) => {\\n ensureMaps();\\n p = shorten(p);\\n const unsettledHandler = promiseToUnsettledHandler.get(p);\\n let executor;\\n if (unsettledHandler && typeof unsettledHandler[operation] === 'function') {\\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 unsettled handler,\\n // opArgs are something like [prop] or [method, args],\\n // so we don't risk the user's args leaking into this expansion.\\n // eslint-disable-next-line no-use-before-define\\n resolve(unsettledHandler[operation](p, ...opArgs, returnedP)),\\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 // opArgs are something like [prop] or [method, args],\\n // so we don't risk the user's args leaking into this expansion.\\n // eslint-disable-next-line no-use-before-define\\n resolve(forwardingHandler[operation](o, ...opArgs, returnedP));\\n })\\n .catch(reject);\\n };\\n }\\n\\n // We return a handled promise with the default unsettled handler.\\n // This prevents a race between the above Promise.resolves and\\n // pipelining.\\n const returnedP = new HandledPromise(executor);\\n return returnedP;\\n };\\n\\n promiseResolve = Promise.resolve.bind(Promise);\\n return harden(HandledPromise);\\n}\\n\\nexports.E = E;\\nexports.HandledPromise = hp;\\nexports.makeHandledPromise = makeHandledPromise;\\n});\\n\\nvar eventualSend_cjs$1 = _commonjsHelpers.unwrapExports(eventualSend_cjs);\\nvar eventualSend_cjs_1 = eventualSend_cjs.E;\\nvar eventualSend_cjs_2 = eventualSend_cjs.HandledPromise;\\nvar eventualSend_cjs_3 = eventualSend_cjs.makeHandledPromise;\\n\\nexports.E = eventualSend_cjs_1;\\nexports.HandledPromise = eventualSend_cjs_2;\\nexports.default = eventualSend_cjs$1;\\nexports.makeHandledPromise = eventualSend_cjs_3;\\n\",\n \"_virtual/_commonjsHelpers.js\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\\n\\nfunction commonjsRequire () {\\n\\tthrow new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');\\n}\\n\\nfunction unwrapExports (x) {\\n\\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\\n}\\n\\nfunction createCommonjsModule(fn, module) {\\n\\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\\n}\\n\\nfunction getCjsExportFromNamespace (n) {\\n\\treturn n && n['default'] || n;\\n}\\n\\nexports.commonjsGlobal = commonjsGlobal;\\nexports.commonjsRequire = commonjsRequire;\\nexports.createCommonjsModule = createCommonjsModule;\\nexports.getCjsExportFromNamespace = getCjsExportFromNamespace;\\nexports.unwrapExports = unwrapExports;\\n\",\n \"_virtual/harden_commonjs-external\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\\n\\nvar harden = _interopDefault(require('@agoric/harden'));\\n\\n\\n\\nexports.default = harden;\\n\"\n};\n const nsBundle = {};\n\n function createEvalString(filename) {\n const code = sourceBundle[filename];\n if (!code) {\n return undefined;\n }\n return `\\\n(function getExport(require) { \\\n 'use strict'; \\\n let exports = {}; \\\n const module = { exports }; \\\n \\\n ${code}\n return module.exports;\n})\n//# sourceURL=${filePrefix}/${filename}\n`;\n }\n\n function computeExports(filename, exportPowers) {\n const { require: systemRequire, _log } = exportPowers;\n // This captures the endowed require.\n const match = filename.match(/^(.*)\\/[^/]+$/);\n const thisdir = match ? match[1] : '.';\n const contextRequire = mod => {\n // Do path algebra to find the actual source.\n const els = mod.split('/');\n let prefix;\n if (els[0][0] === '@') {\n // Scoped name.\n prefix = els.splice(0, 2).join('/');\n } else if (els[0][0] === '.') {\n // Relative.\n els.unshift(...thisdir.split('/'));\n } else {\n // Bare or absolute.\n prefix = els.splice(0, 1);\n }\n\n const suffix = [];\n for (const el of els) {\n if (el === '.' || el === '') {\n // Do nothing.\n } else if (el === '..') {\n // Traverse upwards.\n suffix.pop();\n } else {\n suffix.push(el);\n }\n }\n\n // log(mod, prefix, suffix);\n if (prefix !== undefined) {\n suffix.unshift(prefix);\n }\n let modPath = suffix.join('/');\n if (modPath.startsWith('./')) {\n modPath = modPath.slice(2);\n }\n // log('requiring', modPath);\n if (!(modPath in nsBundle)) {\n // log('evaluating', modPath);\n nsBundle[modPath] = computeExports(modPath, exportPowers);\n }\n\n // log('returning', nsBundle[modPath]);\n return nsBundle[modPath];\n };\n\n const code = createEvalString(filename);\n if (!code) {\n // log('missing code for', filename, sourceBundle);\n if (systemRequire) {\n return systemRequire(filename);\n }\n throw Error(\n `require(${JSON.stringify(\n filename,\n )}) failed; no toplevel require endowment`,\n );\n }\n\n // log('evaluating', typeof nestedEvaluate, code);\n return nestedEvaluate(code)(contextRequire);\n }\n\n // Evaluate the entrypoint recursively.\n return computeExports(entrypoint, { require, log(...args) { return console.log(...args); } });\n}\n//# sourceURL=/bundled-source-preamble.js\n","sourceMap":"//# sourceURL=/bundled-source-preamble.js\n","moduleFormat":"nestedEvaluate"}; | ||
@@ -32,9 +32,19 @@ function makeEventualSendTransformer(parser, generate) { | ||
// It will be hardened in the evaluator's context. | ||
const { source: evSendSrc, moduleFormat } = eventualSendBundle; | ||
if (moduleFormat === 'getExport') { | ||
const nestedEvaluate = src => | ||
(evaluateProgram || ss.evaluateProgram)(src, { | ||
require: myRequire || require, | ||
nestedEvaluate, | ||
}); | ||
const { | ||
source: evSendSrc, | ||
moduleFormat, | ||
sourceMap, | ||
} = eventualSendBundle; | ||
if ( | ||
moduleFormat === 'getExport' || | ||
moduleFormat === 'nestedEvaluate' | ||
) { | ||
recursive = true; | ||
try { | ||
const ns = ( | ||
evaluateProgram || ss.evaluateProgram | ||
)(`(${evSendSrc})()`, { require: myRequire || require }); | ||
const ns = nestedEvaluate(`(${evSendSrc}\n${sourceMap})`)(); | ||
HandledPromise = ns.HandledPromise; | ||
@@ -41,0 +51,0 @@ } finally { |
@@ -1,2 +0,2 @@ | ||
var eventualSendBundle = {"source":"function getExport() { 'use strict'; let exports = {}; const module = { exports }; 'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden = _interopDefault(require('@agoric/harden'));\n\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\nfunction commonjsRequire () {\n\tthrow new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');\n}\n\nfunction unwrapExports (x) {\n\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\n}\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nfunction getCjsExportFromNamespace (n) {\n\treturn n && n['default'] || n;\n}\n\nvar eventualSend_cjs = createCommonjsModule(function (module, exports) {\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden$1 = _interopDefault(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$1({\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$1(HandledPromise.applyMethod(x, p, args));\n },\n apply(_target, _thisArg, argArray = []) {\n return harden$1(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$1(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 harden$1(HandledPromise.get(x, prop));\n },\n });\n\n E.G = makeEGetterProxy;\n E.resolve = HandledPromise.resolve;\n E.unwrap = HandledPromise.unwrap;\n\n E.when = (x, onfulfilled = undefined, onrejected = undefined) =>\n HandledPromise.resolve(x).then(onfulfilled, onrejected);\n\n return harden$1(E);\n}\n\n/* global HandledPromise */\n\nconst {\n defineProperties,\n getOwnPropertyDescriptors,\n getOwnPropertyDescriptor: gopd,\n getPrototypeOf,\n isFrozen,\n} = Object;\n\nconst { prototype: promiseProto } = Promise;\nconst { then: originalThen } = promiseProto;\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$1(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 promiseToUnsettledHandler;\n let promiseToPresence; // only for HandledPromise.unwrap\n let forwardedPromiseToPromise; // forwarding, union-find-ish\n function ensureMaps() {\n if (!presenceToHandler) {\n presenceToHandler = new WeakMap();\n presenceToPromise = new WeakMap();\n promiseToUnsettledHandler = new WeakMap();\n promiseToPresence = new WeakMap();\n forwardedPromiseToPromise = new WeakMap();\n }\n }\n\n /**\n * You can imagine a forest of trees in which the roots of each tree is an\n * unresolved HandledPromise or a non-Promise, and each node's parent is the\n * HandledPromise to which it was forwarded. We maintain that mapping of\n * forwarded HandledPromise to its resolution in forwardedPromiseToPromise.\n *\n * We use something like the description of \"Find\" with \"Path splitting\"\n * to propagate changes down to the children efficiently:\n * https://en.wikipedia.org/wiki/Disjoint-set_data_structure\n *\n * @param {*} target Any value.\n * @returns {*} If the target was a HandledPromise, the most-resolved parent of it, otherwise the target.\n */\n function shorten(target) {\n let p = target;\n // Find the most-resolved value for p.\n while (forwardedPromiseToPromise.has(p)) {\n p = forwardedPromiseToPromise.get(p);\n }\n const presence = promiseToPresence.get(p);\n if (presence) {\n // Presences are final, so it is ok to propagate\n // this upstream.\n while (target !== p) {\n const parent = forwardedPromiseToPromise.get(target);\n forwardedPromiseToPromise.delete(target);\n promiseToUnsettledHandler.delete(target);\n promiseToPresence.set(target, presence);\n target = parent;\n }\n } else {\n // We propagate p and remove all other unsettled handlers\n // upstream.\n // Note that everything except presences is covered here.\n while (target !== p) {\n const parent = forwardedPromiseToPromise.get(target);\n forwardedPromiseToPromise.set(target, p);\n promiseToUnsettledHandler.delete(target);\n target = parent;\n }\n }\n return target;\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 promiseResolve;\n\n function HandledPromise(executor, unsettledHandler = undefined) {\n if (new.target === undefined) {\n throw new Error('must be invoked with \"new\"');\n }\n let handledResolve;\n let handledReject;\n let resolved = false;\n let resolvedTarget = null;\n let handledP;\n let continueForwarding = () => {};\n const superExecutor = (superResolve, superReject) => {\n handledResolve = value => {\n if (resolved) {\n return resolvedTarget;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n value = shorten(value);\n let targetP;\n if (\n promiseToUnsettledHandler.has(value) ||\n promiseToPresence.has(value)\n ) {\n targetP = value;\n } else {\n // We're resolving to a non-promise, so remove our handler.\n promiseToUnsettledHandler.delete(handledP);\n targetP = presenceToPromise.get(value);\n }\n // Ensure our data structure is a propert tree (avoid cycles).\n if (targetP && targetP !== handledP) {\n forwardedPromiseToPromise.set(handledP, targetP);\n } else {\n forwardedPromiseToPromise.delete(handledP);\n }\n\n // Remove stale unsettled handlers, set to canonical form.\n shorten(handledP);\n\n // Ensure our unsettledHandler is cleaned up if not already.\n if (promiseToUnsettledHandler.has(handledP)) {\n handledP.then(_ => promiseToUnsettledHandler.delete(handledP));\n }\n\n // Finish the resolution.\n superResolve(value);\n resolved = true;\n resolvedTarget = value;\n\n // We're resolved, so forward any postponed operations to us.\n continueForwarding();\n return resolvedTarget;\n };\n handledReject = err => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n promiseToUnsettledHandler.delete(handledP);\n resolved = true;\n superReject(err);\n continueForwarding();\n };\n };\n handledP = harden$1(Reflect.construct(Promise, [superExecutor], new.target));\n\n ensureMaps();\n\n const makePostponedHandler = () => {\n // Create a simple postponedHandler that just postpones until the\n // fulfilledHandler is set.\n let donePostponing;\n const interlockP = new Promise(resolve => {\n donePostponing = () => resolve();\n });\n\n const makePostponedOperation = 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(_ => {\n // If targetP is a handled promise, use it, otherwise x.\n resolve(HandledPromise[postponedOperation](x, ...args));\n })\n .catch(reject);\n });\n };\n };\n\n const postponedHandler = {\n get: makePostponedOperation('get'),\n applyMethod: makePostponedOperation('applyMethod'),\n };\n return [postponedHandler, donePostponing];\n };\n\n if (!unsettledHandler) {\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 [unsettledHandler, continueForwarding] = makePostponedHandler();\n }\n\n const validateHandler = h => {\n if (Object(h) !== h) {\n throw TypeError(`Handler ${h} cannot be a primitive`);\n }\n };\n validateHandler(unsettledHandler);\n\n // Until the handled promise is resolved, we use the unsettledHandler.\n promiseToUnsettledHandler.set(handledP, unsettledHandler);\n\n const rejectHandled = reason => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n handledReject(reason);\n };\n\n const resolveWithPresence = presenceHandler => {\n if (resolved) {\n return resolvedTarget;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n try {\n // Sanity checks.\n validateHandler(presenceHandler);\n\n // Validate and install our mapped target (i.e. presence).\n resolvedTarget = Object.create(null);\n\n // Create table entries for the presence mapped to the\n // fulfilledHandler.\n presenceToPromise.set(resolvedTarget, handledP);\n promiseToPresence.set(handledP, resolvedTarget);\n presenceToHandler.set(resolvedTarget, presenceHandler);\n\n // We committed to this presence, so resolve.\n handledResolve(resolvedTarget);\n return resolvedTarget;\n } catch (e) {\n handledReject(e);\n throw e;\n }\n };\n\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n try {\n if (deprecatedPresenceHandler) {\n throw TypeError(\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\n );\n }\n\n // Resolve the target.\n handledResolve(target);\n } catch (e) {\n handledReject(e);\n }\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 = promiseProto;\n Object.setPrototypeOf(HandledPromise, Promise);\n\n function isFrozenPromiseThen(p) {\n return (\n isFrozen(p) &&\n getPrototypeOf(p) === promiseProto &&\n promiseResolve(p) === p &&\n gopd(p, 'then') === undefined &&\n gopd(promiseProto, 'then').value === originalThen // unnecessary under SES\n );\n }\n\n const staticMethods = harden$1({\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 let resolvedPromise = presenceToPromise.get(value);\n if (!resolvedPromise) {\n resolvedPromise = promiseResolve(value);\n }\n // Prevent any proxy trickery.\n harden$1(resolvedPromise);\n if (isFrozenPromiseThen(resolvedPromise)) {\n return resolvedPromise;\n }\n // Assimilate the thenable.\n const executeThen = (resolve, reject) =>\n resolvedPromise.then(resolve, reject);\n return harden$1(\n promiseResolve().then(_ => new HandledPromise(executeThen)),\n );\n },\n // TODO verify that this is safe to provide universally, i.e.,\n // that by itself it doesn't provide access to mutable state in\n // ways that violate normal ocap module purity rules. The claim\n // that it does not rests on the handled promise itself being\n // necessary to perceive this mutable state. In that sense, we\n // can think of the right to perceive it, and of access to the\n // target, as being in the handled promise. Note that a .then on\n // the handled promise will already provide async access to the\n // target, so the only additional authorities are: 1)\n // synchronous access for handled promises only, and thus 2) the\n // ability to tell, from the client side, whether a promise is\n // handled. Or, at least, the ability to tell given that the\n // promise is already fulfilled.\n unwrap(value) {\n // This check for Thenable is safe, since in a remote-object\n // environment, our comms system will defend against remote\n // objects being represented as a tricky local Proxy, otherwise\n // it is guaranteed to be local and therefore synchronous enough.\n if (Object(value) !== value || !('then' in value)) {\n // Not a Thenable, so return it.\n // This means that local objects will pass through without error.\n return value;\n }\n\n // Try to look up the HandledPromise.\n ensureMaps();\n const pr = presenceToPromise.get(value) || value;\n\n // Find the fulfilled presence for that HandledPromise.\n const presence = promiseToPresence.get(pr);\n if (!presence) {\n throw TypeError(\n `Value is a Thenble but not a HandledPromise fulfilled to a presence`,\n );\n }\n return presence;\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, ...opArgs) => {\n ensureMaps();\n p = shorten(p);\n const unsettledHandler = promiseToUnsettledHandler.get(p);\n let executor;\n if (unsettledHandler && typeof unsettledHandler[operation] === 'function') {\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 unsettled handler,\n // opArgs are something like [prop] or [method, args],\n // so we don't risk the user's args leaking into this expansion.\n // eslint-disable-next-line no-use-before-define\n resolve(unsettledHandler[operation](p, ...opArgs, returnedP)),\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 // opArgs are something like [prop] or [method, args],\n // so we don't risk the user's args leaking into this expansion.\n // eslint-disable-next-line no-use-before-define\n resolve(forwardingHandler[operation](o, ...opArgs, returnedP));\n })\n .catch(reject);\n };\n }\n\n // We return a handled promise with the default unsettled handler.\n // This prevents a race between the above Promise.resolves and\n // pipelining.\n const returnedP = new HandledPromise(executor);\n return returnedP;\n };\n\n promiseResolve = Promise.resolve.bind(Promise);\n return harden$1(HandledPromise);\n}\n\nexports.E = E;\nexports.HandledPromise = hp;\nexports.makeHandledPromise = makeHandledPromise;\n});\n\nvar eventualSend_cjs$1 = unwrapExports(eventualSend_cjs);\nvar eventualSend_cjs_1 = eventualSend_cjs.E;\nvar eventualSend_cjs_2 = eventualSend_cjs.HandledPromise;\nvar eventualSend_cjs_3 = eventualSend_cjs.makeHandledPromise;\n\nexports.E = eventualSend_cjs_1;\nexports.HandledPromise = eventualSend_cjs_2;\nexports.default = eventualSend_cjs$1;\nexports.makeHandledPromise = eventualSend_cjs_3;\n\n\nreturn module.exports;\n}\n","sourceMap":"//# sourceURL=/Users/michael/agoric/agoric-sdk/packages/eventual-send/dist/eventual-send.cjs.js\n","moduleFormat":"getExport"}; | ||
var eventualSendBundle = {"source":"function getExportWithNestedEvaluate(filePrefix) {\n 'use strict';\n // Serialised sources.\n if (filePrefix === undefined) {\n filePrefix = \"/bundled-source\";\n }\n const moduleFormat = \"nestedEvaluate\";\n const entrypoint = \"eventual-send.cjs.js\";\n const sourceBundle = {\n \"eventual-send.cjs.js\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nvar _commonjsHelpers = require('./_virtual/_commonjsHelpers.js');\\nrequire('@agoric/harden');\\nvar harden_commonjsExternal = require('./_virtual/harden_commonjs-external');\\n\\nvar eventualSend_cjs = _commonjsHelpers.createCommonjsModule(function (module, exports) {\\n'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\\n\\nvar harden = _interopDefault(harden_commonjsExternal.default);\\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 harden(HandledPromise.get(x, prop));\\n },\\n });\\n\\n E.G = makeEGetterProxy;\\n E.resolve = HandledPromise.resolve;\\n E.unwrap = HandledPromise.unwrap;\\n\\n E.when = (x, onfulfilled = undefined, onrejected = undefined) =>\\n HandledPromise.resolve(x).then(onfulfilled, onrejected);\\n\\n return harden(E);\\n}\\n\\n/* global HandledPromise */\\n\\nconst {\\n defineProperties,\\n getOwnPropertyDescriptors,\\n getOwnPropertyDescriptor: gopd,\\n getPrototypeOf,\\n isFrozen,\\n} = Object;\\n\\nconst { prototype: promiseProto } = Promise;\\nconst { then: originalThen } = promiseProto;\\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 promiseToUnsettledHandler;\\n let promiseToPresence; // only for HandledPromise.unwrap\\n let forwardedPromiseToPromise; // forwarding, union-find-ish\\n function ensureMaps() {\\n if (!presenceToHandler) {\\n presenceToHandler = new WeakMap();\\n presenceToPromise = new WeakMap();\\n promiseToUnsettledHandler = new WeakMap();\\n promiseToPresence = new WeakMap();\\n forwardedPromiseToPromise = new WeakMap();\\n }\\n }\\n\\n /**\\n * You can imagine a forest of trees in which the roots of each tree is an\\n * unresolved HandledPromise or a non-Promise, and each node's parent is the\\n * HandledPromise to which it was forwarded. We maintain that mapping of\\n * forwarded HandledPromise to its resolution in forwardedPromiseToPromise.\\n *\\n * We use something like the description of \\\"Find\\\" with \\\"Path splitting\\\"\\n * to propagate changes down to the children efficiently:\\n * https://en.wikipedia.org/wiki/Disjoint-set_data_structure\\n *\\n * @param {*} target Any value.\\n * @returns {*} If the target was a HandledPromise, the most-resolved parent of it, otherwise the target.\\n */\\n function shorten(target) {\\n let p = target;\\n // Find the most-resolved value for p.\\n while (forwardedPromiseToPromise.has(p)) {\\n p = forwardedPromiseToPromise.get(p);\\n }\\n const presence = promiseToPresence.get(p);\\n if (presence) {\\n // Presences are final, so it is ok to propagate\\n // this upstream.\\n while (target !== p) {\\n const parent = forwardedPromiseToPromise.get(target);\\n forwardedPromiseToPromise.delete(target);\\n promiseToUnsettledHandler.delete(target);\\n promiseToPresence.set(target, presence);\\n target = parent;\\n }\\n } else {\\n // We propagate p and remove all other unsettled handlers\\n // upstream.\\n // Note that everything except presences is covered here.\\n while (target !== p) {\\n const parent = forwardedPromiseToPromise.get(target);\\n forwardedPromiseToPromise.set(target, p);\\n promiseToUnsettledHandler.delete(target);\\n target = parent;\\n }\\n }\\n return target;\\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 promiseResolve;\\n\\n function HandledPromise(executor, unsettledHandler = undefined) {\\n if (new.target === undefined) {\\n throw new Error('must be invoked with \\\"new\\\"');\\n }\\n let handledResolve;\\n let handledReject;\\n let resolved = false;\\n let resolvedTarget = null;\\n let handledP;\\n let continueForwarding = () => {};\\n const superExecutor = (superResolve, superReject) => {\\n handledResolve = value => {\\n if (resolved) {\\n return resolvedTarget;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n value = shorten(value);\\n let targetP;\\n if (\\n promiseToUnsettledHandler.has(value) ||\\n promiseToPresence.has(value)\\n ) {\\n targetP = value;\\n } else {\\n // We're resolving to a non-promise, so remove our handler.\\n promiseToUnsettledHandler.delete(handledP);\\n targetP = presenceToPromise.get(value);\\n }\\n // Ensure our data structure is a propert tree (avoid cycles).\\n if (targetP && targetP !== handledP) {\\n forwardedPromiseToPromise.set(handledP, targetP);\\n } else {\\n forwardedPromiseToPromise.delete(handledP);\\n }\\n\\n // Remove stale unsettled handlers, set to canonical form.\\n shorten(handledP);\\n\\n // Ensure our unsettledHandler is cleaned up if not already.\\n if (promiseToUnsettledHandler.has(handledP)) {\\n handledP.then(_ => promiseToUnsettledHandler.delete(handledP));\\n }\\n\\n // Finish the resolution.\\n superResolve(value);\\n resolved = true;\\n resolvedTarget = value;\\n\\n // We're resolved, so forward any postponed operations to us.\\n continueForwarding();\\n return resolvedTarget;\\n };\\n handledReject = err => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n promiseToUnsettledHandler.delete(handledP);\\n resolved = true;\\n superReject(err);\\n continueForwarding();\\n };\\n };\\n handledP = harden(Reflect.construct(Promise, [superExecutor], new.target));\\n\\n ensureMaps();\\n\\n const makePostponedHandler = () => {\\n // Create a simple postponedHandler that just postpones until the\\n // fulfilledHandler is set.\\n let donePostponing;\\n const interlockP = new Promise(resolve => {\\n donePostponing = () => resolve();\\n });\\n\\n const makePostponedOperation = 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(_ => {\\n // If targetP is a handled promise, use it, otherwise x.\\n resolve(HandledPromise[postponedOperation](x, ...args));\\n })\\n .catch(reject);\\n });\\n };\\n };\\n\\n const postponedHandler = {\\n get: makePostponedOperation('get'),\\n applyMethod: makePostponedOperation('applyMethod'),\\n };\\n return [postponedHandler, donePostponing];\\n };\\n\\n if (!unsettledHandler) {\\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 [unsettledHandler, continueForwarding] = makePostponedHandler();\\n }\\n\\n const validateHandler = h => {\\n if (Object(h) !== h) {\\n throw TypeError(`Handler ${h} cannot be a primitive`);\\n }\\n };\\n validateHandler(unsettledHandler);\\n\\n // Until the handled promise is resolved, we use the unsettledHandler.\\n promiseToUnsettledHandler.set(handledP, unsettledHandler);\\n\\n const rejectHandled = reason => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n handledReject(reason);\\n };\\n\\n const resolveWithPresence = presenceHandler => {\\n if (resolved) {\\n return resolvedTarget;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n try {\\n // Sanity checks.\\n validateHandler(presenceHandler);\\n\\n // Validate and install our mapped target (i.e. presence).\\n resolvedTarget = Object.create(null);\\n\\n // Create table entries for the presence mapped to the\\n // fulfilledHandler.\\n presenceToPromise.set(resolvedTarget, handledP);\\n promiseToPresence.set(handledP, resolvedTarget);\\n presenceToHandler.set(resolvedTarget, presenceHandler);\\n\\n // We committed to this presence, so resolve.\\n handledResolve(resolvedTarget);\\n return resolvedTarget;\\n } catch (e) {\\n handledReject(e);\\n throw e;\\n }\\n };\\n\\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n try {\\n if (deprecatedPresenceHandler) {\\n throw TypeError(\\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\\n );\\n }\\n\\n // Resolve the target.\\n handledResolve(target);\\n } catch (e) {\\n handledReject(e);\\n }\\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 = promiseProto;\\n Object.setPrototypeOf(HandledPromise, Promise);\\n\\n function isFrozenPromiseThen(p) {\\n return (\\n isFrozen(p) &&\\n getPrototypeOf(p) === promiseProto &&\\n promiseResolve(p) === p &&\\n gopd(p, 'then') === undefined &&\\n gopd(promiseProto, 'then').value === originalThen // unnecessary under SES\\n );\\n }\\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 let resolvedPromise = presenceToPromise.get(value);\\n if (!resolvedPromise) {\\n resolvedPromise = promiseResolve(value);\\n }\\n // Prevent any proxy trickery.\\n harden(resolvedPromise);\\n if (isFrozenPromiseThen(resolvedPromise)) {\\n return resolvedPromise;\\n }\\n // Assimilate the thenable.\\n const executeThen = (resolve, reject) =>\\n resolvedPromise.then(resolve, reject);\\n return harden(\\n promiseResolve().then(_ => new HandledPromise(executeThen)),\\n );\\n },\\n // TODO verify that this is safe to provide universally, i.e.,\\n // that by itself it doesn't provide access to mutable state in\\n // ways that violate normal ocap module purity rules. The claim\\n // that it does not rests on the handled promise itself being\\n // necessary to perceive this mutable state. In that sense, we\\n // can think of the right to perceive it, and of access to the\\n // target, as being in the handled promise. Note that a .then on\\n // the handled promise will already provide async access to the\\n // target, so the only additional authorities are: 1)\\n // synchronous access for handled promises only, and thus 2) the\\n // ability to tell, from the client side, whether a promise is\\n // handled. Or, at least, the ability to tell given that the\\n // promise is already fulfilled.\\n unwrap(value) {\\n // This check for Thenable is safe, since in a remote-object\\n // environment, our comms system will defend against remote\\n // objects being represented as a tricky local Proxy, otherwise\\n // it is guaranteed to be local and therefore synchronous enough.\\n if (Object(value) !== value || !('then' in value)) {\\n // Not a Thenable, so return it.\\n // This means that local objects will pass through without error.\\n return value;\\n }\\n\\n // Try to look up the HandledPromise.\\n ensureMaps();\\n const pr = presenceToPromise.get(value) || value;\\n\\n // Find the fulfilled presence for that HandledPromise.\\n const presence = promiseToPresence.get(pr);\\n if (!presence) {\\n throw TypeError(\\n `Value is a Thenble but not a HandledPromise fulfilled to a presence`,\\n );\\n }\\n return presence;\\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, ...opArgs) => {\\n ensureMaps();\\n p = shorten(p);\\n const unsettledHandler = promiseToUnsettledHandler.get(p);\\n let executor;\\n if (unsettledHandler && typeof unsettledHandler[operation] === 'function') {\\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 unsettled handler,\\n // opArgs are something like [prop] or [method, args],\\n // so we don't risk the user's args leaking into this expansion.\\n // eslint-disable-next-line no-use-before-define\\n resolve(unsettledHandler[operation](p, ...opArgs, returnedP)),\\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 // opArgs are something like [prop] or [method, args],\\n // so we don't risk the user's args leaking into this expansion.\\n // eslint-disable-next-line no-use-before-define\\n resolve(forwardingHandler[operation](o, ...opArgs, returnedP));\\n })\\n .catch(reject);\\n };\\n }\\n\\n // We return a handled promise with the default unsettled handler.\\n // This prevents a race between the above Promise.resolves and\\n // pipelining.\\n const returnedP = new HandledPromise(executor);\\n return returnedP;\\n };\\n\\n promiseResolve = Promise.resolve.bind(Promise);\\n return harden(HandledPromise);\\n}\\n\\nexports.E = E;\\nexports.HandledPromise = hp;\\nexports.makeHandledPromise = makeHandledPromise;\\n});\\n\\nvar eventualSend_cjs$1 = _commonjsHelpers.unwrapExports(eventualSend_cjs);\\nvar eventualSend_cjs_1 = eventualSend_cjs.E;\\nvar eventualSend_cjs_2 = eventualSend_cjs.HandledPromise;\\nvar eventualSend_cjs_3 = eventualSend_cjs.makeHandledPromise;\\n\\nexports.E = eventualSend_cjs_1;\\nexports.HandledPromise = eventualSend_cjs_2;\\nexports.default = eventualSend_cjs$1;\\nexports.makeHandledPromise = eventualSend_cjs_3;\\n\",\n \"_virtual/_commonjsHelpers.js\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\\n\\nfunction commonjsRequire () {\\n\\tthrow new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');\\n}\\n\\nfunction unwrapExports (x) {\\n\\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\\n}\\n\\nfunction createCommonjsModule(fn, module) {\\n\\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\\n}\\n\\nfunction getCjsExportFromNamespace (n) {\\n\\treturn n && n['default'] || n;\\n}\\n\\nexports.commonjsGlobal = commonjsGlobal;\\nexports.commonjsRequire = commonjsRequire;\\nexports.createCommonjsModule = createCommonjsModule;\\nexports.getCjsExportFromNamespace = getCjsExportFromNamespace;\\nexports.unwrapExports = unwrapExports;\\n\",\n \"_virtual/harden_commonjs-external\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\\n\\nvar harden = _interopDefault(require('@agoric/harden'));\\n\\n\\n\\nexports.default = harden;\\n\"\n};\n const nsBundle = {};\n\n function createEvalString(filename) {\n const code = sourceBundle[filename];\n if (!code) {\n return undefined;\n }\n return `\\\n(function getExport(require) { \\\n 'use strict'; \\\n let exports = {}; \\\n const module = { exports }; \\\n \\\n ${code}\n return module.exports;\n})\n//# sourceURL=${filePrefix}/${filename}\n`;\n }\n\n function computeExports(filename, exportPowers) {\n const { require: systemRequire, _log } = exportPowers;\n // This captures the endowed require.\n const match = filename.match(/^(.*)\\/[^/]+$/);\n const thisdir = match ? match[1] : '.';\n const contextRequire = mod => {\n // Do path algebra to find the actual source.\n const els = mod.split('/');\n let prefix;\n if (els[0][0] === '@') {\n // Scoped name.\n prefix = els.splice(0, 2).join('/');\n } else if (els[0][0] === '.') {\n // Relative.\n els.unshift(...thisdir.split('/'));\n } else {\n // Bare or absolute.\n prefix = els.splice(0, 1);\n }\n\n const suffix = [];\n for (const el of els) {\n if (el === '.' || el === '') {\n // Do nothing.\n } else if (el === '..') {\n // Traverse upwards.\n suffix.pop();\n } else {\n suffix.push(el);\n }\n }\n\n // log(mod, prefix, suffix);\n if (prefix !== undefined) {\n suffix.unshift(prefix);\n }\n let modPath = suffix.join('/');\n if (modPath.startsWith('./')) {\n modPath = modPath.slice(2);\n }\n // log('requiring', modPath);\n if (!(modPath in nsBundle)) {\n // log('evaluating', modPath);\n nsBundle[modPath] = computeExports(modPath, exportPowers);\n }\n\n // log('returning', nsBundle[modPath]);\n return nsBundle[modPath];\n };\n\n const code = createEvalString(filename);\n if (!code) {\n // log('missing code for', filename, sourceBundle);\n if (systemRequire) {\n return systemRequire(filename);\n }\n throw Error(\n `require(${JSON.stringify(\n filename,\n )}) failed; no toplevel require endowment`,\n );\n }\n\n // log('evaluating', typeof nestedEvaluate, code);\n return nestedEvaluate(code)(contextRequire);\n }\n\n // Evaluate the entrypoint recursively.\n return computeExports(entrypoint, { require, log(...args) { return console.log(...args); } });\n}\n//# sourceURL=/bundled-source-preamble.js\n","sourceMap":"//# sourceURL=/bundled-source-preamble.js\n","moduleFormat":"nestedEvaluate"}; | ||
@@ -30,9 +30,19 @@ function makeEventualSendTransformer(parser, generate) { | ||
// It will be hardened in the evaluator's context. | ||
const { source: evSendSrc, moduleFormat } = eventualSendBundle; | ||
if (moduleFormat === 'getExport') { | ||
const nestedEvaluate = src => | ||
(evaluateProgram || ss.evaluateProgram)(src, { | ||
require: myRequire || require, | ||
nestedEvaluate, | ||
}); | ||
const { | ||
source: evSendSrc, | ||
moduleFormat, | ||
sourceMap, | ||
} = eventualSendBundle; | ||
if ( | ||
moduleFormat === 'getExport' || | ||
moduleFormat === 'nestedEvaluate' | ||
) { | ||
recursive = true; | ||
try { | ||
const ns = ( | ||
evaluateProgram || ss.evaluateProgram | ||
)(`(${evSendSrc})()`, { require: myRequire || require }); | ||
const ns = nestedEvaluate(`(${evSendSrc}\n${sourceMap})`)(); | ||
HandledPromise = ns.HandledPromise; | ||
@@ -39,0 +49,0 @@ } finally { |
@@ -7,3 +7,3 @@ (function (global, factory) { | ||
var eventualSendBundle = {"source":"function getExport() { 'use strict'; let exports = {}; const module = { exports }; 'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden = _interopDefault(require('@agoric/harden'));\n\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\nfunction commonjsRequire () {\n\tthrow new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');\n}\n\nfunction unwrapExports (x) {\n\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\n}\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nfunction getCjsExportFromNamespace (n) {\n\treturn n && n['default'] || n;\n}\n\nvar eventualSend_cjs = createCommonjsModule(function (module, exports) {\n'use strict';\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\n\nvar harden$1 = _interopDefault(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$1({\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$1(HandledPromise.applyMethod(x, p, args));\n },\n apply(_target, _thisArg, argArray = []) {\n return harden$1(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$1(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 harden$1(HandledPromise.get(x, prop));\n },\n });\n\n E.G = makeEGetterProxy;\n E.resolve = HandledPromise.resolve;\n E.unwrap = HandledPromise.unwrap;\n\n E.when = (x, onfulfilled = undefined, onrejected = undefined) =>\n HandledPromise.resolve(x).then(onfulfilled, onrejected);\n\n return harden$1(E);\n}\n\n/* global HandledPromise */\n\nconst {\n defineProperties,\n getOwnPropertyDescriptors,\n getOwnPropertyDescriptor: gopd,\n getPrototypeOf,\n isFrozen,\n} = Object;\n\nconst { prototype: promiseProto } = Promise;\nconst { then: originalThen } = promiseProto;\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$1(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 promiseToUnsettledHandler;\n let promiseToPresence; // only for HandledPromise.unwrap\n let forwardedPromiseToPromise; // forwarding, union-find-ish\n function ensureMaps() {\n if (!presenceToHandler) {\n presenceToHandler = new WeakMap();\n presenceToPromise = new WeakMap();\n promiseToUnsettledHandler = new WeakMap();\n promiseToPresence = new WeakMap();\n forwardedPromiseToPromise = new WeakMap();\n }\n }\n\n /**\n * You can imagine a forest of trees in which the roots of each tree is an\n * unresolved HandledPromise or a non-Promise, and each node's parent is the\n * HandledPromise to which it was forwarded. We maintain that mapping of\n * forwarded HandledPromise to its resolution in forwardedPromiseToPromise.\n *\n * We use something like the description of \"Find\" with \"Path splitting\"\n * to propagate changes down to the children efficiently:\n * https://en.wikipedia.org/wiki/Disjoint-set_data_structure\n *\n * @param {*} target Any value.\n * @returns {*} If the target was a HandledPromise, the most-resolved parent of it, otherwise the target.\n */\n function shorten(target) {\n let p = target;\n // Find the most-resolved value for p.\n while (forwardedPromiseToPromise.has(p)) {\n p = forwardedPromiseToPromise.get(p);\n }\n const presence = promiseToPresence.get(p);\n if (presence) {\n // Presences are final, so it is ok to propagate\n // this upstream.\n while (target !== p) {\n const parent = forwardedPromiseToPromise.get(target);\n forwardedPromiseToPromise.delete(target);\n promiseToUnsettledHandler.delete(target);\n promiseToPresence.set(target, presence);\n target = parent;\n }\n } else {\n // We propagate p and remove all other unsettled handlers\n // upstream.\n // Note that everything except presences is covered here.\n while (target !== p) {\n const parent = forwardedPromiseToPromise.get(target);\n forwardedPromiseToPromise.set(target, p);\n promiseToUnsettledHandler.delete(target);\n target = parent;\n }\n }\n return target;\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 promiseResolve;\n\n function HandledPromise(executor, unsettledHandler = undefined) {\n if (new.target === undefined) {\n throw new Error('must be invoked with \"new\"');\n }\n let handledResolve;\n let handledReject;\n let resolved = false;\n let resolvedTarget = null;\n let handledP;\n let continueForwarding = () => {};\n const superExecutor = (superResolve, superReject) => {\n handledResolve = value => {\n if (resolved) {\n return resolvedTarget;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n value = shorten(value);\n let targetP;\n if (\n promiseToUnsettledHandler.has(value) ||\n promiseToPresence.has(value)\n ) {\n targetP = value;\n } else {\n // We're resolving to a non-promise, so remove our handler.\n promiseToUnsettledHandler.delete(handledP);\n targetP = presenceToPromise.get(value);\n }\n // Ensure our data structure is a propert tree (avoid cycles).\n if (targetP && targetP !== handledP) {\n forwardedPromiseToPromise.set(handledP, targetP);\n } else {\n forwardedPromiseToPromise.delete(handledP);\n }\n\n // Remove stale unsettled handlers, set to canonical form.\n shorten(handledP);\n\n // Ensure our unsettledHandler is cleaned up if not already.\n if (promiseToUnsettledHandler.has(handledP)) {\n handledP.then(_ => promiseToUnsettledHandler.delete(handledP));\n }\n\n // Finish the resolution.\n superResolve(value);\n resolved = true;\n resolvedTarget = value;\n\n // We're resolved, so forward any postponed operations to us.\n continueForwarding();\n return resolvedTarget;\n };\n handledReject = err => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n promiseToUnsettledHandler.delete(handledP);\n resolved = true;\n superReject(err);\n continueForwarding();\n };\n };\n handledP = harden$1(Reflect.construct(Promise, [superExecutor], new.target));\n\n ensureMaps();\n\n const makePostponedHandler = () => {\n // Create a simple postponedHandler that just postpones until the\n // fulfilledHandler is set.\n let donePostponing;\n const interlockP = new Promise(resolve => {\n donePostponing = () => resolve();\n });\n\n const makePostponedOperation = 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(_ => {\n // If targetP is a handled promise, use it, otherwise x.\n resolve(HandledPromise[postponedOperation](x, ...args));\n })\n .catch(reject);\n });\n };\n };\n\n const postponedHandler = {\n get: makePostponedOperation('get'),\n applyMethod: makePostponedOperation('applyMethod'),\n };\n return [postponedHandler, donePostponing];\n };\n\n if (!unsettledHandler) {\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 [unsettledHandler, continueForwarding] = makePostponedHandler();\n }\n\n const validateHandler = h => {\n if (Object(h) !== h) {\n throw TypeError(`Handler ${h} cannot be a primitive`);\n }\n };\n validateHandler(unsettledHandler);\n\n // Until the handled promise is resolved, we use the unsettledHandler.\n promiseToUnsettledHandler.set(handledP, unsettledHandler);\n\n const rejectHandled = reason => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n handledReject(reason);\n };\n\n const resolveWithPresence = presenceHandler => {\n if (resolved) {\n return resolvedTarget;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n try {\n // Sanity checks.\n validateHandler(presenceHandler);\n\n // Validate and install our mapped target (i.e. presence).\n resolvedTarget = Object.create(null);\n\n // Create table entries for the presence mapped to the\n // fulfilledHandler.\n presenceToPromise.set(resolvedTarget, handledP);\n promiseToPresence.set(handledP, resolvedTarget);\n presenceToHandler.set(resolvedTarget, presenceHandler);\n\n // We committed to this presence, so resolve.\n handledResolve(resolvedTarget);\n return resolvedTarget;\n } catch (e) {\n handledReject(e);\n throw e;\n }\n };\n\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\n if (resolved) {\n return;\n }\n if (forwardedPromiseToPromise.has(handledP)) {\n throw new TypeError('internal: already forwarded');\n }\n try {\n if (deprecatedPresenceHandler) {\n throw TypeError(\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\n );\n }\n\n // Resolve the target.\n handledResolve(target);\n } catch (e) {\n handledReject(e);\n }\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 = promiseProto;\n Object.setPrototypeOf(HandledPromise, Promise);\n\n function isFrozenPromiseThen(p) {\n return (\n isFrozen(p) &&\n getPrototypeOf(p) === promiseProto &&\n promiseResolve(p) === p &&\n gopd(p, 'then') === undefined &&\n gopd(promiseProto, 'then').value === originalThen // unnecessary under SES\n );\n }\n\n const staticMethods = harden$1({\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 let resolvedPromise = presenceToPromise.get(value);\n if (!resolvedPromise) {\n resolvedPromise = promiseResolve(value);\n }\n // Prevent any proxy trickery.\n harden$1(resolvedPromise);\n if (isFrozenPromiseThen(resolvedPromise)) {\n return resolvedPromise;\n }\n // Assimilate the thenable.\n const executeThen = (resolve, reject) =>\n resolvedPromise.then(resolve, reject);\n return harden$1(\n promiseResolve().then(_ => new HandledPromise(executeThen)),\n );\n },\n // TODO verify that this is safe to provide universally, i.e.,\n // that by itself it doesn't provide access to mutable state in\n // ways that violate normal ocap module purity rules. The claim\n // that it does not rests on the handled promise itself being\n // necessary to perceive this mutable state. In that sense, we\n // can think of the right to perceive it, and of access to the\n // target, as being in the handled promise. Note that a .then on\n // the handled promise will already provide async access to the\n // target, so the only additional authorities are: 1)\n // synchronous access for handled promises only, and thus 2) the\n // ability to tell, from the client side, whether a promise is\n // handled. Or, at least, the ability to tell given that the\n // promise is already fulfilled.\n unwrap(value) {\n // This check for Thenable is safe, since in a remote-object\n // environment, our comms system will defend against remote\n // objects being represented as a tricky local Proxy, otherwise\n // it is guaranteed to be local and therefore synchronous enough.\n if (Object(value) !== value || !('then' in value)) {\n // Not a Thenable, so return it.\n // This means that local objects will pass through without error.\n return value;\n }\n\n // Try to look up the HandledPromise.\n ensureMaps();\n const pr = presenceToPromise.get(value) || value;\n\n // Find the fulfilled presence for that HandledPromise.\n const presence = promiseToPresence.get(pr);\n if (!presence) {\n throw TypeError(\n `Value is a Thenble but not a HandledPromise fulfilled to a presence`,\n );\n }\n return presence;\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, ...opArgs) => {\n ensureMaps();\n p = shorten(p);\n const unsettledHandler = promiseToUnsettledHandler.get(p);\n let executor;\n if (unsettledHandler && typeof unsettledHandler[operation] === 'function') {\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 unsettled handler,\n // opArgs are something like [prop] or [method, args],\n // so we don't risk the user's args leaking into this expansion.\n // eslint-disable-next-line no-use-before-define\n resolve(unsettledHandler[operation](p, ...opArgs, returnedP)),\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 // opArgs are something like [prop] or [method, args],\n // so we don't risk the user's args leaking into this expansion.\n // eslint-disable-next-line no-use-before-define\n resolve(forwardingHandler[operation](o, ...opArgs, returnedP));\n })\n .catch(reject);\n };\n }\n\n // We return a handled promise with the default unsettled handler.\n // This prevents a race between the above Promise.resolves and\n // pipelining.\n const returnedP = new HandledPromise(executor);\n return returnedP;\n };\n\n promiseResolve = Promise.resolve.bind(Promise);\n return harden$1(HandledPromise);\n}\n\nexports.E = E;\nexports.HandledPromise = hp;\nexports.makeHandledPromise = makeHandledPromise;\n});\n\nvar eventualSend_cjs$1 = unwrapExports(eventualSend_cjs);\nvar eventualSend_cjs_1 = eventualSend_cjs.E;\nvar eventualSend_cjs_2 = eventualSend_cjs.HandledPromise;\nvar eventualSend_cjs_3 = eventualSend_cjs.makeHandledPromise;\n\nexports.E = eventualSend_cjs_1;\nexports.HandledPromise = eventualSend_cjs_2;\nexports.default = eventualSend_cjs$1;\nexports.makeHandledPromise = eventualSend_cjs_3;\n\n\nreturn module.exports;\n}\n","sourceMap":"//# sourceURL=/Users/michael/agoric/agoric-sdk/packages/eventual-send/dist/eventual-send.cjs.js\n","moduleFormat":"getExport"}; | ||
var eventualSendBundle = {"source":"function getExportWithNestedEvaluate(filePrefix) {\n 'use strict';\n // Serialised sources.\n if (filePrefix === undefined) {\n filePrefix = \"/bundled-source\";\n }\n const moduleFormat = \"nestedEvaluate\";\n const entrypoint = \"eventual-send.cjs.js\";\n const sourceBundle = {\n \"eventual-send.cjs.js\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nvar _commonjsHelpers = require('./_virtual/_commonjsHelpers.js');\\nrequire('@agoric/harden');\\nvar harden_commonjsExternal = require('./_virtual/harden_commonjs-external');\\n\\nvar eventualSend_cjs = _commonjsHelpers.createCommonjsModule(function (module, exports) {\\n'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\\n\\nvar harden = _interopDefault(harden_commonjsExternal.default);\\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 harden(HandledPromise.get(x, prop));\\n },\\n });\\n\\n E.G = makeEGetterProxy;\\n E.resolve = HandledPromise.resolve;\\n E.unwrap = HandledPromise.unwrap;\\n\\n E.when = (x, onfulfilled = undefined, onrejected = undefined) =>\\n HandledPromise.resolve(x).then(onfulfilled, onrejected);\\n\\n return harden(E);\\n}\\n\\n/* global HandledPromise */\\n\\nconst {\\n defineProperties,\\n getOwnPropertyDescriptors,\\n getOwnPropertyDescriptor: gopd,\\n getPrototypeOf,\\n isFrozen,\\n} = Object;\\n\\nconst { prototype: promiseProto } = Promise;\\nconst { then: originalThen } = promiseProto;\\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 promiseToUnsettledHandler;\\n let promiseToPresence; // only for HandledPromise.unwrap\\n let forwardedPromiseToPromise; // forwarding, union-find-ish\\n function ensureMaps() {\\n if (!presenceToHandler) {\\n presenceToHandler = new WeakMap();\\n presenceToPromise = new WeakMap();\\n promiseToUnsettledHandler = new WeakMap();\\n promiseToPresence = new WeakMap();\\n forwardedPromiseToPromise = new WeakMap();\\n }\\n }\\n\\n /**\\n * You can imagine a forest of trees in which the roots of each tree is an\\n * unresolved HandledPromise or a non-Promise, and each node's parent is the\\n * HandledPromise to which it was forwarded. We maintain that mapping of\\n * forwarded HandledPromise to its resolution in forwardedPromiseToPromise.\\n *\\n * We use something like the description of \\\"Find\\\" with \\\"Path splitting\\\"\\n * to propagate changes down to the children efficiently:\\n * https://en.wikipedia.org/wiki/Disjoint-set_data_structure\\n *\\n * @param {*} target Any value.\\n * @returns {*} If the target was a HandledPromise, the most-resolved parent of it, otherwise the target.\\n */\\n function shorten(target) {\\n let p = target;\\n // Find the most-resolved value for p.\\n while (forwardedPromiseToPromise.has(p)) {\\n p = forwardedPromiseToPromise.get(p);\\n }\\n const presence = promiseToPresence.get(p);\\n if (presence) {\\n // Presences are final, so it is ok to propagate\\n // this upstream.\\n while (target !== p) {\\n const parent = forwardedPromiseToPromise.get(target);\\n forwardedPromiseToPromise.delete(target);\\n promiseToUnsettledHandler.delete(target);\\n promiseToPresence.set(target, presence);\\n target = parent;\\n }\\n } else {\\n // We propagate p and remove all other unsettled handlers\\n // upstream.\\n // Note that everything except presences is covered here.\\n while (target !== p) {\\n const parent = forwardedPromiseToPromise.get(target);\\n forwardedPromiseToPromise.set(target, p);\\n promiseToUnsettledHandler.delete(target);\\n target = parent;\\n }\\n }\\n return target;\\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 promiseResolve;\\n\\n function HandledPromise(executor, unsettledHandler = undefined) {\\n if (new.target === undefined) {\\n throw new Error('must be invoked with \\\"new\\\"');\\n }\\n let handledResolve;\\n let handledReject;\\n let resolved = false;\\n let resolvedTarget = null;\\n let handledP;\\n let continueForwarding = () => {};\\n const superExecutor = (superResolve, superReject) => {\\n handledResolve = value => {\\n if (resolved) {\\n return resolvedTarget;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n value = shorten(value);\\n let targetP;\\n if (\\n promiseToUnsettledHandler.has(value) ||\\n promiseToPresence.has(value)\\n ) {\\n targetP = value;\\n } else {\\n // We're resolving to a non-promise, so remove our handler.\\n promiseToUnsettledHandler.delete(handledP);\\n targetP = presenceToPromise.get(value);\\n }\\n // Ensure our data structure is a propert tree (avoid cycles).\\n if (targetP && targetP !== handledP) {\\n forwardedPromiseToPromise.set(handledP, targetP);\\n } else {\\n forwardedPromiseToPromise.delete(handledP);\\n }\\n\\n // Remove stale unsettled handlers, set to canonical form.\\n shorten(handledP);\\n\\n // Ensure our unsettledHandler is cleaned up if not already.\\n if (promiseToUnsettledHandler.has(handledP)) {\\n handledP.then(_ => promiseToUnsettledHandler.delete(handledP));\\n }\\n\\n // Finish the resolution.\\n superResolve(value);\\n resolved = true;\\n resolvedTarget = value;\\n\\n // We're resolved, so forward any postponed operations to us.\\n continueForwarding();\\n return resolvedTarget;\\n };\\n handledReject = err => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n promiseToUnsettledHandler.delete(handledP);\\n resolved = true;\\n superReject(err);\\n continueForwarding();\\n };\\n };\\n handledP = harden(Reflect.construct(Promise, [superExecutor], new.target));\\n\\n ensureMaps();\\n\\n const makePostponedHandler = () => {\\n // Create a simple postponedHandler that just postpones until the\\n // fulfilledHandler is set.\\n let donePostponing;\\n const interlockP = new Promise(resolve => {\\n donePostponing = () => resolve();\\n });\\n\\n const makePostponedOperation = 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(_ => {\\n // If targetP is a handled promise, use it, otherwise x.\\n resolve(HandledPromise[postponedOperation](x, ...args));\\n })\\n .catch(reject);\\n });\\n };\\n };\\n\\n const postponedHandler = {\\n get: makePostponedOperation('get'),\\n applyMethod: makePostponedOperation('applyMethod'),\\n };\\n return [postponedHandler, donePostponing];\\n };\\n\\n if (!unsettledHandler) {\\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 [unsettledHandler, continueForwarding] = makePostponedHandler();\\n }\\n\\n const validateHandler = h => {\\n if (Object(h) !== h) {\\n throw TypeError(`Handler ${h} cannot be a primitive`);\\n }\\n };\\n validateHandler(unsettledHandler);\\n\\n // Until the handled promise is resolved, we use the unsettledHandler.\\n promiseToUnsettledHandler.set(handledP, unsettledHandler);\\n\\n const rejectHandled = reason => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n handledReject(reason);\\n };\\n\\n const resolveWithPresence = presenceHandler => {\\n if (resolved) {\\n return resolvedTarget;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n try {\\n // Sanity checks.\\n validateHandler(presenceHandler);\\n\\n // Validate and install our mapped target (i.e. presence).\\n resolvedTarget = Object.create(null);\\n\\n // Create table entries for the presence mapped to the\\n // fulfilledHandler.\\n presenceToPromise.set(resolvedTarget, handledP);\\n promiseToPresence.set(handledP, resolvedTarget);\\n presenceToHandler.set(resolvedTarget, presenceHandler);\\n\\n // We committed to this presence, so resolve.\\n handledResolve(resolvedTarget);\\n return resolvedTarget;\\n } catch (e) {\\n handledReject(e);\\n throw e;\\n }\\n };\\n\\n const resolveHandled = async (target, deprecatedPresenceHandler) => {\\n if (resolved) {\\n return;\\n }\\n if (forwardedPromiseToPromise.has(handledP)) {\\n throw new TypeError('internal: already forwarded');\\n }\\n try {\\n if (deprecatedPresenceHandler) {\\n throw TypeError(\\n `resolveHandled no longer accepts a handler; use resolveWithPresence`,\\n );\\n }\\n\\n // Resolve the target.\\n handledResolve(target);\\n } catch (e) {\\n handledReject(e);\\n }\\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 = promiseProto;\\n Object.setPrototypeOf(HandledPromise, Promise);\\n\\n function isFrozenPromiseThen(p) {\\n return (\\n isFrozen(p) &&\\n getPrototypeOf(p) === promiseProto &&\\n promiseResolve(p) === p &&\\n gopd(p, 'then') === undefined &&\\n gopd(promiseProto, 'then').value === originalThen // unnecessary under SES\\n );\\n }\\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 let resolvedPromise = presenceToPromise.get(value);\\n if (!resolvedPromise) {\\n resolvedPromise = promiseResolve(value);\\n }\\n // Prevent any proxy trickery.\\n harden(resolvedPromise);\\n if (isFrozenPromiseThen(resolvedPromise)) {\\n return resolvedPromise;\\n }\\n // Assimilate the thenable.\\n const executeThen = (resolve, reject) =>\\n resolvedPromise.then(resolve, reject);\\n return harden(\\n promiseResolve().then(_ => new HandledPromise(executeThen)),\\n );\\n },\\n // TODO verify that this is safe to provide universally, i.e.,\\n // that by itself it doesn't provide access to mutable state in\\n // ways that violate normal ocap module purity rules. The claim\\n // that it does not rests on the handled promise itself being\\n // necessary to perceive this mutable state. In that sense, we\\n // can think of the right to perceive it, and of access to the\\n // target, as being in the handled promise. Note that a .then on\\n // the handled promise will already provide async access to the\\n // target, so the only additional authorities are: 1)\\n // synchronous access for handled promises only, and thus 2) the\\n // ability to tell, from the client side, whether a promise is\\n // handled. Or, at least, the ability to tell given that the\\n // promise is already fulfilled.\\n unwrap(value) {\\n // This check for Thenable is safe, since in a remote-object\\n // environment, our comms system will defend against remote\\n // objects being represented as a tricky local Proxy, otherwise\\n // it is guaranteed to be local and therefore synchronous enough.\\n if (Object(value) !== value || !('then' in value)) {\\n // Not a Thenable, so return it.\\n // This means that local objects will pass through without error.\\n return value;\\n }\\n\\n // Try to look up the HandledPromise.\\n ensureMaps();\\n const pr = presenceToPromise.get(value) || value;\\n\\n // Find the fulfilled presence for that HandledPromise.\\n const presence = promiseToPresence.get(pr);\\n if (!presence) {\\n throw TypeError(\\n `Value is a Thenble but not a HandledPromise fulfilled to a presence`,\\n );\\n }\\n return presence;\\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, ...opArgs) => {\\n ensureMaps();\\n p = shorten(p);\\n const unsettledHandler = promiseToUnsettledHandler.get(p);\\n let executor;\\n if (unsettledHandler && typeof unsettledHandler[operation] === 'function') {\\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 unsettled handler,\\n // opArgs are something like [prop] or [method, args],\\n // so we don't risk the user's args leaking into this expansion.\\n // eslint-disable-next-line no-use-before-define\\n resolve(unsettledHandler[operation](p, ...opArgs, returnedP)),\\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 // opArgs are something like [prop] or [method, args],\\n // so we don't risk the user's args leaking into this expansion.\\n // eslint-disable-next-line no-use-before-define\\n resolve(forwardingHandler[operation](o, ...opArgs, returnedP));\\n })\\n .catch(reject);\\n };\\n }\\n\\n // We return a handled promise with the default unsettled handler.\\n // This prevents a race between the above Promise.resolves and\\n // pipelining.\\n const returnedP = new HandledPromise(executor);\\n return returnedP;\\n };\\n\\n promiseResolve = Promise.resolve.bind(Promise);\\n return harden(HandledPromise);\\n}\\n\\nexports.E = E;\\nexports.HandledPromise = hp;\\nexports.makeHandledPromise = makeHandledPromise;\\n});\\n\\nvar eventualSend_cjs$1 = _commonjsHelpers.unwrapExports(eventualSend_cjs);\\nvar eventualSend_cjs_1 = eventualSend_cjs.E;\\nvar eventualSend_cjs_2 = eventualSend_cjs.HandledPromise;\\nvar eventualSend_cjs_3 = eventualSend_cjs.makeHandledPromise;\\n\\nexports.E = eventualSend_cjs_1;\\nexports.HandledPromise = eventualSend_cjs_2;\\nexports.default = eventualSend_cjs$1;\\nexports.makeHandledPromise = eventualSend_cjs_3;\\n\",\n \"_virtual/_commonjsHelpers.js\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\\n\\nfunction commonjsRequire () {\\n\\tthrow new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');\\n}\\n\\nfunction unwrapExports (x) {\\n\\treturn x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;\\n}\\n\\nfunction createCommonjsModule(fn, module) {\\n\\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\\n}\\n\\nfunction getCjsExportFromNamespace (n) {\\n\\treturn n && n['default'] || n;\\n}\\n\\nexports.commonjsGlobal = commonjsGlobal;\\nexports.commonjsRequire = commonjsRequire;\\nexports.createCommonjsModule = createCommonjsModule;\\nexports.getCjsExportFromNamespace = getCjsExportFromNamespace;\\nexports.unwrapExports = unwrapExports;\\n\",\n \"_virtual/harden_commonjs-external\": \"'use strict';\\n\\nObject.defineProperty(exports, '__esModule', { value: true });\\n\\nfunction _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }\\n\\nvar harden = _interopDefault(require('@agoric/harden'));\\n\\n\\n\\nexports.default = harden;\\n\"\n};\n const nsBundle = {};\n\n function createEvalString(filename) {\n const code = sourceBundle[filename];\n if (!code) {\n return undefined;\n }\n return `\\\n(function getExport(require) { \\\n 'use strict'; \\\n let exports = {}; \\\n const module = { exports }; \\\n \\\n ${code}\n return module.exports;\n})\n//# sourceURL=${filePrefix}/${filename}\n`;\n }\n\n function computeExports(filename, exportPowers) {\n const { require: systemRequire, _log } = exportPowers;\n // This captures the endowed require.\n const match = filename.match(/^(.*)\\/[^/]+$/);\n const thisdir = match ? match[1] : '.';\n const contextRequire = mod => {\n // Do path algebra to find the actual source.\n const els = mod.split('/');\n let prefix;\n if (els[0][0] === '@') {\n // Scoped name.\n prefix = els.splice(0, 2).join('/');\n } else if (els[0][0] === '.') {\n // Relative.\n els.unshift(...thisdir.split('/'));\n } else {\n // Bare or absolute.\n prefix = els.splice(0, 1);\n }\n\n const suffix = [];\n for (const el of els) {\n if (el === '.' || el === '') {\n // Do nothing.\n } else if (el === '..') {\n // Traverse upwards.\n suffix.pop();\n } else {\n suffix.push(el);\n }\n }\n\n // log(mod, prefix, suffix);\n if (prefix !== undefined) {\n suffix.unshift(prefix);\n }\n let modPath = suffix.join('/');\n if (modPath.startsWith('./')) {\n modPath = modPath.slice(2);\n }\n // log('requiring', modPath);\n if (!(modPath in nsBundle)) {\n // log('evaluating', modPath);\n nsBundle[modPath] = computeExports(modPath, exportPowers);\n }\n\n // log('returning', nsBundle[modPath]);\n return nsBundle[modPath];\n };\n\n const code = createEvalString(filename);\n if (!code) {\n // log('missing code for', filename, sourceBundle);\n if (systemRequire) {\n return systemRequire(filename);\n }\n throw Error(\n `require(${JSON.stringify(\n filename,\n )}) failed; no toplevel require endowment`,\n );\n }\n\n // log('evaluating', typeof nestedEvaluate, code);\n return nestedEvaluate(code)(contextRequire);\n }\n\n // Evaluate the entrypoint recursively.\n return computeExports(entrypoint, { require, log(...args) { return console.log(...args); } });\n}\n//# sourceURL=/bundled-source-preamble.js\n","sourceMap":"//# sourceURL=/bundled-source-preamble.js\n","moduleFormat":"nestedEvaluate"}; | ||
@@ -37,9 +37,19 @@ function makeEventualSendTransformer(parser, generate) { | ||
// It will be hardened in the evaluator's context. | ||
const { source: evSendSrc, moduleFormat } = eventualSendBundle; | ||
if (moduleFormat === 'getExport') { | ||
const nestedEvaluate = src => | ||
(evaluateProgram || ss.evaluateProgram)(src, { | ||
require: myRequire || require, | ||
nestedEvaluate, | ||
}); | ||
const { | ||
source: evSendSrc, | ||
moduleFormat, | ||
sourceMap, | ||
} = eventualSendBundle; | ||
if ( | ||
moduleFormat === 'getExport' || | ||
moduleFormat === 'nestedEvaluate' | ||
) { | ||
recursive = true; | ||
try { | ||
const ns = ( | ||
evaluateProgram || ss.evaluateProgram | ||
)(`(${evSendSrc})()`, { require: myRequire || require }); | ||
const ns = nestedEvaluate(`(${evSendSrc}\n${sourceMap})`)(); | ||
HandledPromise = ns.HandledPromise; | ||
@@ -46,0 +56,0 @@ } finally { |
{ | ||
"name": "@agoric/transform-eventual-send", | ||
"version": "1.2.2", | ||
"version": "1.2.3", | ||
"description": "transform-eventual-send", | ||
@@ -15,7 +15,7 @@ "main": "dist/transform-eventual-send.cjs.js", | ||
"devDependencies": { | ||
"@agoric/acorn-eventual-send": "^2.0.2", | ||
"@agoric/acorn-eventual-send": "^2.0.3", | ||
"@agoric/babel-parser": "^7.6.4", | ||
"@agoric/bundle-source": "^1.1.2", | ||
"@agoric/eventual-send": "^0.8.0", | ||
"@agoric/harden": "^0.0.4", | ||
"@agoric/bundle-source": "^1.1.3", | ||
"@agoric/eventual-send": "^0.9.0", | ||
"@agoric/harden": "^0.0.8", | ||
"@babel/generator": "^7.5.0", | ||
@@ -49,3 +49,3 @@ "astring": "^1.4.0", | ||
}, | ||
"gitHead": "a5fe2624fedcf3b8adf46ed6c157c29fd459b2ed" | ||
"gitHead": "534d1a65d79f9dd176cc670f374c9de2cd081a7e" | ||
} |
@@ -30,9 +30,19 @@ import eventualSendBundle from './bundles/eventual-send'; | ||
// It will be hardened in the evaluator's context. | ||
const { source: evSendSrc, moduleFormat } = eventualSendBundle; | ||
if (moduleFormat === 'getExport') { | ||
const nestedEvaluate = src => | ||
(evaluateProgram || ss.evaluateProgram)(src, { | ||
require: myRequire || require, | ||
nestedEvaluate, | ||
}); | ||
const { | ||
source: evSendSrc, | ||
moduleFormat, | ||
sourceMap, | ||
} = eventualSendBundle; | ||
if ( | ||
moduleFormat === 'getExport' || | ||
moduleFormat === 'nestedEvaluate' | ||
) { | ||
recursive = true; | ||
try { | ||
const ns = ( | ||
evaluateProgram || ss.evaluateProgram | ||
)(`(${evSendSrc})()`, { require: myRequire || require }); | ||
const ns = nestedEvaluate(`(${evSendSrc}\n${sourceMap})`)(); | ||
HandledPromise = ns.HandledPromise; | ||
@@ -39,0 +49,0 @@ } finally { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
101020
571
1