Skip to content

Commit a2d473c

Browse files
ef4claude
andcommitted
Give a class the same identity object each time it is identified
identify() built a new object from a class's tag on every call, where the loader's record it replaced handed back one object per class. Callers compared identities by reference: the new-card menu's de-duplication of recent card types listed a type twice and dropped the next one. identify() now returns one object per class for as long as its module canonicalizes the same way, and the menu compares types by module and name. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent cb46718 commit a2d473c

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

‎packages/host/app/components/operator-mode/interact-submode.gts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,14 @@ export default class InteractSubmode extends Component {
673673
let ref = identifyCard(card.constructor);
674674
let name = cardTypeDisplayName(card);
675675
if (isResolvedCodeRef(ref)) {
676-
if (items.find((item) => item.ref === ref && item.name === name)) {
676+
if (
677+
items.find(
678+
(item) =>
679+
item.ref.module === ref.module &&
680+
item.ref.name === ref.name &&
681+
item.name === name,
682+
)
683+
) {
677684
// do not add duplicate of the same card type
678685
return;
679686
}

‎packages/runtime-common/loader.ts‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,12 @@ const identityTagKey = Symbol.for(exportIdentitySymbolKey);
249249
// records its module as compiled — a realm module by its URL — and the module
250250
// is canonicalized when the tag is read: the realm prefix that spells it may be
251251
// registered after the module was compiled.
252+
//
253+
// A class is given the same identity object each time it is identified, for as
254+
// long as its module canonicalizes the same way, so callers can compare
255+
// identities by reference.
256+
const identities = new WeakMap<Function, { module: string; name: string }>();
257+
252258
function identityFromTag(
253259
value: Function,
254260
virtualNetwork: VirtualNetwork | undefined,
@@ -259,11 +265,17 @@ function identityFromTag(
259265
if (!tag) {
260266
return undefined;
261267
}
262-
let [module, name] = tag;
263-
return {
264-
module: virtualNetwork ? virtualNetwork.unresolveURL(module) : module,
265-
name,
266-
};
268+
let [taggedModule, name] = tag;
269+
let module = virtualNetwork
270+
? virtualNetwork.unresolveURL(taggedModule)
271+
: taggedModule;
272+
let known = identities.get(value);
273+
if (known?.module === module && known.name === name) {
274+
return known;
275+
}
276+
let identity = { module, name };
277+
identities.set(value, identity);
278+
return identity;
267279
}
268280

269281
export class Loader {

0 commit comments

Comments
 (0)