diff --git a/packages/exo/src/exo-makers.js b/packages/exo/src/exo-makers.js index 3117072f17..5836defa8f 100644 --- a/packages/exo/src/exo-makers.js +++ b/packages/exo/src/exo-makers.js @@ -5,7 +5,7 @@ import { objectMap } from '@endo/patterns'; import { defendPrototype, defendPrototypeKit } from './exo-tools.js'; -const { create, seal, freeze, defineProperty } = Object; +const { create, seal, freeze, defineProperty, values } = Object; const { getEnvironmentOption } = makeEnvironmentCaptor(globalThis); const DEBUG = getEnvironmentOption('DEBUG', ''); @@ -68,13 +68,9 @@ export const initEmpty = () => emptyRecord; * @returns {boolean} */ -/** - * @typedef {Record} RevokerKit - */ - /** * @callback GetRevoker - * @param {Revoker | RevokerKit} revoke + * @param {Revoker} revoke * @returns {void} */ @@ -96,7 +92,13 @@ export const initEmpty = () => emptyRecord; * @param {FarClassOptions, M>>} [options] * @returns {(...args: Parameters) => (M & import('@endo/eventual-send').RemotableBrand<{}, M>)} */ -export const defineExoClass = (tag, interfaceGuard, init, methods, options = {}) => { +export const defineExoClass = ( + tag, + interfaceGuard, + init, + methods, + options = {}, +) => { harden(methods); const { finish = undefined, getRevoker = undefined } = options; /** @type {WeakMap, M>>} */ @@ -108,11 +110,6 @@ export const defineExoClass = (tag, interfaceGuard, init, methods, options = {}) true, interfaceGuard, ); - if (getRevoker) { - const revoke = self => contextMap.delete(self); - harden(revoke); - getRevoker(revoke); - } let instanceCount = 0; /** * @param {Parameters} args @@ -135,6 +132,13 @@ export const defineExoClass = (tag, interfaceGuard, init, methods, options = {}) self ); }; + + if (getRevoker) { + const revoke = self => contextMap.delete(self); + harden(revoke); + getRevoker(revoke); + } + return harden(makeInstance); }; harden(defineExoClass); @@ -170,13 +174,6 @@ export const defineExoClassKit = ( true, interfaceGuardKit, ); - if (getRevoker) { - const revokerKit = objectMap( - contextMapKit, - contextMap => facet => contextMap.delete(facet), - ); - getRevoker(revokerKit); - } let instanceCount = 0; /** * @param {Parameters} args @@ -201,6 +198,14 @@ export const defineExoClassKit = ( } return context.facets; }; + + if (getRevoker) { + const revoke = facet => + values(contextMapKit).some(contextMap => contextMap.delete(facet)); + harden(revoke); + getRevoker(revoke); + } + return harden(makeInstanceKit); }; harden(defineExoClassKit); diff --git a/packages/exo/test/test-revoke-heap-classes.js b/packages/exo/test/test-revoke-heap-classes.js index 8ef00e02de..233bd84b4f 100644 --- a/packages/exo/test/test-revoke-heap-classes.js +++ b/packages/exo/test/test-revoke-heap-classes.js @@ -51,7 +51,7 @@ test('test revoke defineExoClass', t => { }); test('test revoke defineExoClassKit', t => { - let revokerKit; + let revoke; const makeCounterKit = defineExoClassKit( 'Counter', { up: UpCounterI, down: DownCounterI }, @@ -75,19 +75,26 @@ test('test revoke defineExoClassKit', t => { }, { getRevoker(r) { - revokerKit = r; + revoke = r; }, }, ); const { up: upCounter, down: downCounter } = makeCounterKit(3); t.is(upCounter.incr(5), 8); t.is(downCounter.decr(), 7); - t.is(revokerKit.up(upCounter), true); + t.is(revoke(upCounter), true); t.throws(() => upCounter.incr(3), { message: '"In \\"incr\\" method of (Counter up)" may only be applied to a valid instance: "[Alleged: Counter up]"', }); t.is(downCounter.decr(), 6); + t.is(revoke(upCounter), false); + t.is(revoke(downCounter), true); + t.is(revoke(downCounter), false); + t.throws(() => downCounter.decr(), { + message: + '"In \\"decr\\" method of (Counter down)" may only be applied to a valid instance: "[Alleged: Counter down]"', + }); }); test('test facet cross-talk', t => { @@ -115,6 +122,7 @@ test('test facet cross-talk', t => { ); const { up: upCounter, down: downCounter } = makeCounterKit(3); t.throws(() => apply(upCounter.incr, downCounter, [2]), { - message: '"In \\"incr\\" method of (Counter up)" may only be applied to a valid instance: "[Alleged: Counter down]"', + message: + '"In \\"incr\\" method of (Counter up)" may only be applied to a valid instance: "[Alleged: Counter down]"', }); });