diff --git a/packages/store/src/patterns/exo-makers.js b/packages/store/src/patterns/exo-makers.js index 1bedce9cb62..ecae21ed1bb 100644 --- a/packages/store/src/patterns/exo-makers.js +++ b/packages/store/src/patterns/exo-makers.js @@ -67,7 +67,7 @@ export const defineExoClass = ( const contextMap = new WeakMap(); const prototype = defendPrototype( tag, - contextMap, + self => contextMap.get(self), methods, true, interfaceGuard, @@ -113,9 +113,13 @@ export const defineExoClassKit = ( { finish = undefined } = {}, ) => { const contextMapKit = objectMap(methodsKit, () => new WeakMap()); + const getContextKit = objectMap( + methodsKit, + (_v, name) => facet => contextMapKit[name].get(facet), + ); const prototypeKit = defendPrototypeKit( tag, - contextMapKit, + getContextKit, methodsKit, true, interfaceGuardKit, diff --git a/packages/store/src/patterns/exo-tools.js b/packages/store/src/patterns/exo-tools.js index d28efdf63b2..e20a88330e8 100644 --- a/packages/store/src/patterns/exo-tools.js +++ b/packages/store/src/patterns/exo-tools.js @@ -106,17 +106,21 @@ const defendMethod = (method, methodGuard, label) => { } }; +/** + * @typedef { (representative: any) => any } ContextProvider + */ + /** * * @param {string} methodTag - * @param {WeakMap} contextMap + * @param {ContextProvider} contextProvider * @param {CallableFunction} behaviorMethod * @param {boolean} [thisfulMethods] * @param {MethodGuard} [methodGuard] */ const bindMethod = ( methodTag, - contextMap, + contextProvider, behaviorMethod, thisfulMethods = false, methodGuard = undefined, @@ -124,7 +128,7 @@ const bindMethod = ( assert.typeof(behaviorMethod, 'function'); const getContext = self => { - const context = contextMap.get(self); + const context = contextProvider(self); context || Fail`${q(methodTag)} may only be applied to a valid instance: ${self}`; return context; @@ -173,7 +177,7 @@ const bindMethod = ( /** * @template {Record} T * @param {string} tag - * @param {WeakMap} contextMap + * @param {ContextProvider} contextProvider * @param {T} behaviorMethods * @param {boolean} [thisfulMethods] * @param {InterfaceGuard} [interfaceGuard] @@ -181,7 +185,7 @@ const bindMethod = ( */ export const defendPrototype = ( tag, - contextMap, + contextProvider, behaviorMethods, thisfulMethods = false, interfaceGuard = undefined, @@ -218,7 +222,7 @@ export const defendPrototype = ( for (const prop of methodNames) { prototype[prop] = bindMethod( `In ${q(prop)} method of (${tag})`, - contextMap, + contextProvider, behaviorMethods[prop], thisfulMethods, // TODO some tool does not yet understand the `?.[` syntax @@ -232,14 +236,14 @@ harden(defendPrototype); /** * @param {string} tag - * @param {Record} contextMapKit + * @param {Record} contextProviderKit * @param {Record>} behaviorMethodsKit * @param {boolean} [thisfulMethods] * @param {Record} [interfaceGuardKit] */ export const defendPrototypeKit = ( tag, - contextMapKit, + contextProviderKit, behaviorMethodsKit, thisfulMethods = false, interfaceGuardKit = undefined, @@ -255,7 +259,7 @@ export const defendPrototypeKit = ( extraFacetNames.length === 0 || Fail`Facets ${q(extraFacetNames)} of ${q(tag)} not guarded by interfaces`; } - const contextMapNames = ownKeys(contextMapKit); + const contextMapNames = ownKeys(contextProviderKit); const extraContextNames = listDifference(facetNames, contextMapNames); extraContextNames.length === 0 || Fail`Contexts ${q(extraContextNames)} not implemented by ${q(tag)}`; @@ -265,7 +269,7 @@ export const defendPrototypeKit = ( return objectMap(behaviorMethodsKit, (behaviorMethods, facetName) => defendPrototype( `${tag} ${facetName}`, - contextMapKit[facetName], + contextProviderKit[facetName], behaviorMethods, thisfulMethods, interfaceGuardKit && interfaceGuardKit[facetName], diff --git a/packages/swingset-liveslots/src/virtualObjectManager.js b/packages/swingset-liveslots/src/virtualObjectManager.js index 4f28d8de896..b94e9236d6a 100644 --- a/packages/swingset-liveslots/src/virtualObjectManager.js +++ b/packages/swingset-liveslots/src/virtualObjectManager.js @@ -632,6 +632,11 @@ export function makeVirtualObjectManager( }; const facetiousness = assessFacetiousness(behavior); + const getContextKit = objectMap( + behavior, + (_v, name) => facet => contextMapTemplate[name].get(facet), + ); + switch (facetiousness) { case 'one': { assert(!multifaceted); @@ -639,7 +644,7 @@ export function makeVirtualObjectManager( contextMapTemplate = new WeakMap(); prototypeTemplate = defendPrototype( tag, - contextMapTemplate, + self => contextMapTemplate.get(self), behavior, thisfulMethods, interfaceGuard, @@ -652,7 +657,7 @@ export function makeVirtualObjectManager( contextMapTemplate = objectMap(behavior, () => new WeakMap()); prototypeTemplate = defendPrototypeKit( tag, - contextMapTemplate, + getContextKit, behavior, thisfulMethods, interfaceGuard,