@wix/web5-core 1.63.22 → 1.63.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/entity/entityHref.js +53 -0
- package/dist/cjs/entity/entityHref.js.map +1 -0
- package/dist/cjs/entity/entityPayload.js +58 -4
- package/dist/cjs/entity/entityPayload.js.map +1 -1
- package/dist/cjs/entity/index.js +5 -2
- package/dist/cjs/entity/index.js.map +1 -1
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/registry/ComponentRegistry.js +35 -8
- package/dist/cjs/registry/ComponentRegistry.js.map +1 -1
- package/dist/esm/entity/entityHref.js +49 -0
- package/dist/esm/entity/entityHref.js.map +1 -0
- package/dist/esm/entity/entityPayload.js +57 -4
- package/dist/esm/entity/entityPayload.js.map +1 -1
- package/dist/esm/entity/index.js +2 -1
- package/dist/esm/entity/index.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/registry/ComponentRegistry.js +35 -8
- package/dist/esm/registry/ComponentRegistry.js.map +1 -1
- package/dist/types/entity/entityHref.d.ts +39 -0
- package/dist/types/entity/entityHref.d.ts.map +1 -0
- package/dist/types/entity/entityPayload.d.ts +34 -0
- package/dist/types/entity/entityPayload.d.ts.map +1 -1
- package/dist/types/entity/index.d.ts +2 -1
- package/dist/types/entity/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/registry/ComponentRegistry.d.ts +4 -0
- package/dist/types/registry/ComponentRegistry.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -25,6 +25,27 @@ function normalizeResolveOptions(intentOrOptions, semantic) {
|
|
|
25
25
|
}
|
|
26
26
|
return intentOrOptions;
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Intent keys are matched case-insensitively.
|
|
31
|
+
*
|
|
32
|
+
* The intent that reaches resolution has already been through
|
|
33
|
+
* `intent.trim().toUpperCase()` — in this package's `intentExtractor`, and
|
|
34
|
+
* again in `web50-server-ui`'s own copy of it, which calls it with no
|
|
35
|
+
* `validIntents` and passes the result as `providedIntent`, bypassing the
|
|
36
|
+
* validated path here. A client that registers its variants in the lowercase
|
|
37
|
+
* spelling its own taxonomy doc uses therefore matched nothing, and every
|
|
38
|
+
* intent-scoped variant silently fell through to the section default.
|
|
39
|
+
*
|
|
40
|
+
* That is not hypothetical: it was true of the whole seed registry. Measured
|
|
41
|
+
* across 11 live answers, 10 rendered the same hero whatever the intent, and
|
|
42
|
+
* one registered hero component never rendered at all. Nothing errors, nothing
|
|
43
|
+
* logs, and the page looks plausible — which is why this belongs at the Map
|
|
44
|
+
* rather than in either extractor.
|
|
45
|
+
*
|
|
46
|
+
* Normalizing on write AND on read makes the spelling a client's own business.
|
|
47
|
+
*/
|
|
48
|
+
const normalizeIntentKey = intent => intent.trim().toUpperCase();
|
|
28
49
|
class ComponentRegistry {
|
|
29
50
|
constructor(fallback) {
|
|
30
51
|
this.fallback = fallback;
|
|
@@ -151,14 +172,14 @@ class ComponentRegistry {
|
|
|
151
172
|
}
|
|
152
173
|
if (intent && semantic) {
|
|
153
174
|
var _node$byIntent;
|
|
154
|
-
const found = (_node$byIntent = node.byIntent) == null || (_node$byIntent = _node$byIntent.get(intent)) == null || (_node$byIntent = _node$byIntent.bySemantic) == null ? void 0 : _node$byIntent.get(semantic);
|
|
175
|
+
const found = (_node$byIntent = node.byIntent) == null || (_node$byIntent = _node$byIntent.get(normalizeIntentKey(intent))) == null || (_node$byIntent = _node$byIntent.bySemantic) == null ? void 0 : _node$byIntent.get(semantic);
|
|
155
176
|
if (found) {
|
|
156
177
|
return found;
|
|
157
178
|
}
|
|
158
179
|
}
|
|
159
180
|
if (intent) {
|
|
160
181
|
var _node$byIntent2;
|
|
161
|
-
const found = (_node$byIntent2 = node.byIntent) == null || (_node$byIntent2 = _node$byIntent2.get(intent)) == null ? void 0 : _node$byIntent2.default;
|
|
182
|
+
const found = (_node$byIntent2 = node.byIntent) == null || (_node$byIntent2 = _node$byIntent2.get(normalizeIntentKey(intent))) == null ? void 0 : _node$byIntent2.default;
|
|
162
183
|
if (found) {
|
|
163
184
|
return found;
|
|
164
185
|
}
|
|
@@ -229,14 +250,14 @@ class ComponentRegistry {
|
|
|
229
250
|
}
|
|
230
251
|
if (intent && semantic) {
|
|
231
252
|
var _node$byIntent3;
|
|
232
|
-
const found = (_node$byIntent3 = node.byIntent) == null || (_node$byIntent3 = _node$byIntent3.get(intent)) == null || (_node$byIntent3 = _node$byIntent3.bySemantic) == null ? void 0 : _node$byIntent3.get(semantic);
|
|
253
|
+
const found = (_node$byIntent3 = node.byIntent) == null || (_node$byIntent3 = _node$byIntent3.get(normalizeIntentKey(intent))) == null || (_node$byIntent3 = _node$byIntent3.bySemantic) == null ? void 0 : _node$byIntent3.get(semantic);
|
|
233
254
|
if (found) {
|
|
234
255
|
return found;
|
|
235
256
|
}
|
|
236
257
|
}
|
|
237
258
|
if (intent) {
|
|
238
259
|
var _node$byIntent4;
|
|
239
|
-
const found = (_node$byIntent4 = node.byIntent) == null || (_node$byIntent4 = _node$byIntent4.get(intent)) == null ? void 0 : _node$byIntent4.default;
|
|
260
|
+
const found = (_node$byIntent4 = node.byIntent) == null || (_node$byIntent4 = _node$byIntent4.get(normalizeIntentKey(intent))) == null ? void 0 : _node$byIntent4.default;
|
|
240
261
|
if (found) {
|
|
241
262
|
return found;
|
|
242
263
|
}
|
|
@@ -268,6 +289,10 @@ class ComponentRegistry {
|
|
|
268
289
|
* registered. Assembly uses this to validate an incoming intent before it
|
|
269
290
|
* becomes a resolution key, falling back to core's `DEFAULT_INTENTS` only
|
|
270
291
|
* when a client registers no intent variants at all.
|
|
292
|
+
*
|
|
293
|
+
* Returned NORMALIZED (upper case), whatever spelling the client registered,
|
|
294
|
+
* because these are the map keys. Both consumers compare case-insensitively,
|
|
295
|
+
* so the only visible difference is in a debug view.
|
|
271
296
|
*/
|
|
272
297
|
getKnownIntents() {
|
|
273
298
|
const intents = new Set();
|
|
@@ -435,10 +460,11 @@ class ComponentRegistry {
|
|
|
435
460
|
if (!node.byIntent) {
|
|
436
461
|
node.byIntent = new Map();
|
|
437
462
|
}
|
|
438
|
-
|
|
463
|
+
const key = normalizeIntentKey(intent);
|
|
464
|
+
let intentNode = node.byIntent.get(key);
|
|
439
465
|
if (!intentNode) {
|
|
440
466
|
intentNode = {};
|
|
441
|
-
node.byIntent.set(
|
|
467
|
+
node.byIntent.set(key, intentNode);
|
|
442
468
|
}
|
|
443
469
|
return intentNode;
|
|
444
470
|
}
|
|
@@ -446,10 +472,11 @@ class ComponentRegistry {
|
|
|
446
472
|
if (!node.byIntent) {
|
|
447
473
|
node.byIntent = new Map();
|
|
448
474
|
}
|
|
449
|
-
|
|
475
|
+
const key = normalizeIntentKey(intent);
|
|
476
|
+
let intentNode = node.byIntent.get(key);
|
|
450
477
|
if (!intentNode) {
|
|
451
478
|
intentNode = {};
|
|
452
|
-
node.byIntent.set(
|
|
479
|
+
node.byIntent.set(key, intentNode);
|
|
453
480
|
}
|
|
454
481
|
return intentNode;
|
|
455
482
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["normalizeResolveOptions","intentOrOptions","semantic","intent","ComponentRegistry","constructor","fallback","_defineProperty2","default","Map","registerSlot","name","component","options","node","slots","get","set","intentNode","ensureSlotIntent","bySemantic","register","definition","variants","console","warn","definitions","sectionType","registration","sections","placement","placementId","forPlacementById","forPlacement","ensureSectionIntent","registerAction","handler","actions","resolveSlot","_node$byIntent","found","byIntent","_node$byIntent2","_node$bySemantic","resolveSection","resolveSectionRegistration","resolveSectionOptions","_this$resolveSectionR","undefined","_node$forPlacementByI","byId","_node$byIntent3","_node$byIntent4","_node$bySemantic2","getAllSlots","Array","from","keys","getAllSections","getKnownIntents","intents","Set","values","_node$byIntent5","forEach","_variant","key","add","_node$byIntent6","getAllDefinitions","entries","map","getDefinition","isPlacementOnly","_node$forPlacementByI2","_node$byIntent7","_node$bySemantic3","hasPlacement","size","hasNonPlacement","getSlotVariants","push","getSectionVariants","hasAction","has","executeAction","params","success","message","getRegisteredActions","getCatalog","exports"],"sources":["../../../src/registry/ComponentRegistry.ts"],"sourcesContent":["import type { SectionDefinition } from '../component/componentDefinitions';\nimport type {\n SlotOptions,\n SectionOptions,\n SectionRegistration,\n SlotNode,\n SlotIntentNode,\n SectionNode,\n SectionIntentNode,\n SlotVariant,\n SectionVariant,\n RegistryCatalog,\n ResolveSectionOptions,\n ActionHandler,\n ActionResult,\n} from './types';\n\n/**\n * Accept the legacy positional form `(intent, semantic)` and the new\n * options-object form `({ intent, semantic, placement })`. Returns a\n * normalized `ResolveSectionOptions`.\n */\nfunction normalizeResolveOptions(\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n): ResolveSectionOptions {\n if (intentOrOptions == null) {\n return semantic ? { semantic } : {};\n }\n if (typeof intentOrOptions === 'string') {\n return semantic ? { intent: intentOrOptions, semantic } : { intent: intentOrOptions };\n }\n return intentOrOptions;\n}\n\nexport class ComponentRegistry<C> {\n private slots = new Map<string, SlotNode<C>>();\n private sections = new Map<string, SectionNode<C>>();\n private definitions = new Map<string, SectionDefinition>();\n private actions = new Map<string, ActionHandler>();\n\n constructor(private fallback: C) {}\n\n // ---------------------------------------------------------------------------\n // Registration\n // ---------------------------------------------------------------------------\n\n registerSlot(name: string, component: C, options?: SlotOptions): this {\n let node = this.slots.get(name);\n if (!node) {\n node = {};\n this.slots.set(name, node);\n }\n\n const { intent, semantic } = options ?? {};\n\n if (intent && semantic) {\n const intentNode = this.ensureSlotIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, component);\n } else if (intent) {\n const intentNode = this.ensureSlotIntent(node, intent);\n intentNode.default = component;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, component);\n } else {\n node.default = component;\n }\n\n return this;\n }\n\n register(\n definition: SectionDefinition,\n variants?: SectionRegistration<C>[],\n ): this {\n // Tolerate missing definitions instead of crashing app init. This\n // happens when a client UMD references a `SectionDefinition` symbol\n // that doesn't exist on the consuming bundle's `Web5Core` global\n // (e.g. UMD built against newer `web5-core` than the app bundle).\n // Without this guard a single missing export breaks every other\n // section the client tries to register.\n if (definition == null) {\n // eslint-disable-next-line no-console\n console.warn(\n '[ComponentRegistry] register() called with a null/undefined SectionDefinition — ' +\n 'likely a version skew between the client UMD and web5-core ' +\n '(an exported definition the UMD imports does not exist on this Web5Core). Skipping.',\n );\n return this;\n }\n this.definitions.set(definition.sectionType, definition);\n\n if (variants) {\n const sectionType = definition.sectionType;\n for (const registration of variants) {\n let node = this.sections.get(sectionType);\n if (!node) {\n node = {};\n this.sections.set(sectionType, node);\n }\n const { intent, semantic, placement, placementId } =\n registration.options ?? {};\n\n // Placement variants are stored on their own slot — no further\n // intent/semantic sub-variants (DL #088 D3.1). If a developer also\n // supplies intent/semantic alongside placement, those are ignored for\n // the placement registration. To register both a placement variant AND\n // an intent variant, register them as separate entries.\n if (placement) {\n // Scoped to a specific placement slot id — keyed so one section type\n // can render differently per placement. An id-less placement variant\n // remains the generic fallback.\n if (placementId) {\n if (!node.forPlacementById) {\n node.forPlacementById = new Map();\n }\n node.forPlacementById.set(placementId, registration);\n } else {\n node.forPlacement = registration;\n }\n continue;\n }\n\n if (intent && semantic) {\n const intentNode = this.ensureSectionIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, registration);\n } else if (intent) {\n const intentNode = this.ensureSectionIntent(node, intent);\n intentNode.default = registration;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, registration);\n } else {\n node.default = registration;\n }\n }\n }\n\n return this;\n }\n\n registerAction(name: string, handler: ActionHandler): this {\n this.actions.set(name, handler);\n return this;\n }\n\n // ---------------------------------------------------------------------------\n // Resolution\n // ---------------------------------------------------------------------------\n\n resolveSlot(name: string, intent?: string, semantic?: string): C {\n const node = this.slots.get(name);\n if (!node) {\n return this.fallback;\n }\n\n if (intent && semantic) {\n const found = node.byIntent?.get(intent)?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(intent)?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default ?? this.fallback;\n }\n\n /**\n * Resolve a section component by type, optionally narrowed by intent /\n * semantic / placement.\n *\n * Accepts both call forms for backward compatibility:\n * resolveSection('hero') — default\n * resolveSection('hero', 'DISCOVERY') — intent (legacy positional)\n * resolveSection('hero', 'DISCOVERY', 'compact') — intent + semantic (legacy)\n * resolveSection('hero', { intent: 'DISCOVERY' }) — options object\n * resolveSection('hero', { placement: true }) — placement variant (DL #088 D3.1)\n * resolveSection('hero', { intent: 'X', placement: true }) — placement wins\n */\n resolveSection(sectionType: string, intent?: string, semantic?: string): C;\n resolveSection(sectionType: string, options: ResolveSectionOptions): C;\n resolveSection(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): C {\n const registration = this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n );\n return registration?.component ?? this.fallback;\n }\n\n /**\n * Resolve the options bundle associated with the matched registration.\n * Same overload semantics as `resolveSection`.\n */\n resolveSectionOptions(\n sectionType: string,\n intent?: string,\n semantic?: string,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): SectionOptions | undefined {\n return this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n )?.options;\n }\n\n private resolveSectionRegistration(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionRegistration<C> | undefined {\n const node = this.sections.get(sectionType);\n if (!node) {\n return undefined;\n }\n\n const { intent, semantic, placement, placementId } = options;\n\n // Placement wins over intent / semantic when requested AND a placement\n // variant is registered for this section (DL #088 D3.1). Cascade:\n // id-scoped variant → generic placement variant → regular chain.\n if (placement) {\n if (placementId) {\n const byId = node.forPlacementById?.get(placementId);\n if (byId) {\n return byId;\n }\n }\n if (node.forPlacement) {\n return node.forPlacement;\n }\n }\n\n if (intent && semantic) {\n const found = node.byIntent?.get(intent as string)?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(intent as string)?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default;\n }\n\n // ---------------------------------------------------------------------------\n // Introspection\n // ---------------------------------------------------------------------------\n\n getAllSlots(): string[] {\n return Array.from(this.slots.keys());\n }\n\n getAllSections(): string[] {\n return Array.from(this.sections.keys());\n }\n\n /**\n * Every intent that has at least one registered slot or section variant —\n * i.e. the client's own intent list, derived from what it actually\n * registered. Assembly uses this to validate an incoming intent before it\n * becomes a resolution key, falling back to core's `DEFAULT_INTENTS` only\n * when a client registers no intent variants at all.\n */\n getKnownIntents(): string[] {\n const intents = new Set<string>();\n for (const node of this.slots.values()) {\n node.byIntent?.forEach((_variant, key) => intents.add(key));\n }\n for (const node of this.sections.values()) {\n node.byIntent?.forEach((_variant, key) => intents.add(key));\n }\n return Array.from(intents);\n }\n\n getAllDefinitions(): {\n sectionType: string;\n definition: SectionDefinition;\n }[] {\n return Array.from(this.definitions.entries()).map(\n ([sectionType, definition]) => ({\n sectionType,\n definition,\n }),\n );\n }\n\n getDefinition(sectionType: string): SectionDefinition | undefined {\n return this.definitions.get(sectionType);\n }\n\n /**\n * True when a section type was registered with placement variant(s) only —\n * a `{ placement: true }` (or `placementId`) registration and NO\n * non-placement variant (default / intent / semantic). Such a section is\n * meaningful only inside a placement render; the parser skips its definition\n * when matching in a non-placement context (the main app), so its markdown\n * falls through to the generic sections there.\n *\n * A definition registered with no variants at all (structural defs like\n * `skipNodes` / `htmlComment`) is NOT placement-only — it still matches\n * everywhere.\n */\n isPlacementOnly(sectionType: string): boolean {\n const node = this.sections.get(sectionType);\n if (!node) {\n return false;\n }\n const hasPlacement =\n node.forPlacement != null || (node.forPlacementById?.size ?? 0) > 0;\n const hasNonPlacement =\n node.default != null ||\n (node.byIntent?.size ?? 0) > 0 ||\n (node.bySemantic?.size ?? 0) > 0;\n return hasPlacement && !hasNonPlacement;\n }\n\n getSlotVariants(name: string): SlotVariant[] {\n const node = this.slots.get(name);\n if (!node) {\n return [];\n }\n\n const variants: SlotVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n return variants;\n }\n\n getSectionVariants(sectionType: string): SectionVariant[] {\n const node = this.sections.get(sectionType);\n if (!node) {\n return [];\n }\n\n const variants: SectionVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n if (node.forPlacement) {\n variants.push({ placement: true });\n }\n\n if (node.forPlacementById) {\n for (const placementId of node.forPlacementById.keys()) {\n variants.push({ placement: true, placementId });\n }\n }\n\n return variants;\n }\n\n hasAction(name: string): boolean {\n return this.actions.has(name);\n }\n\n async executeAction(\n name: string,\n params: Record<string, string>,\n ): Promise<ActionResult> {\n const handler = this.actions.get(name);\n if (!handler) {\n console.warn(`[Action] No handler for: \"${name}\"`);\n return { success: false, message: `Unknown action: ${name}` };\n }\n return handler(params);\n }\n\n getRegisteredActions(): string[] {\n return Array.from(this.actions.keys());\n }\n\n getCatalog(): RegistryCatalog {\n return {\n slots: this.getAllSlots().map((name) => ({\n name,\n variants: this.getSlotVariants(name),\n })),\n sections: this.getAllSections().map((sectionType) => ({\n name: sectionType,\n variants: this.getSectionVariants(sectionType),\n })),\n definitions: this.getAllDefinitions(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private ensureSectionIntent(\n node: SectionNode<C>,\n intent: string,\n ): SectionIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n let intentNode = node.byIntent.get(intent);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(intent, intentNode);\n }\n return intentNode;\n }\n\n private ensureSlotIntent(\n node: SlotNode<C>,\n intent: string,\n ): SlotIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n let intentNode = node.byIntent.get(intent);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(intent, intentNode);\n }\n return intentNode;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["normalizeResolveOptions","intentOrOptions","semantic","intent","normalizeIntentKey","trim","toUpperCase","ComponentRegistry","constructor","fallback","_defineProperty2","default","Map","registerSlot","name","component","options","node","slots","get","set","intentNode","ensureSlotIntent","bySemantic","register","definition","variants","console","warn","definitions","sectionType","registration","sections","placement","placementId","forPlacementById","forPlacement","ensureSectionIntent","registerAction","handler","actions","resolveSlot","_node$byIntent","found","byIntent","_node$byIntent2","_node$bySemantic","resolveSection","resolveSectionRegistration","resolveSectionOptions","_this$resolveSectionR","undefined","_node$forPlacementByI","byId","_node$byIntent3","_node$byIntent4","_node$bySemantic2","getAllSlots","Array","from","keys","getAllSections","getKnownIntents","intents","Set","values","_node$byIntent5","forEach","_variant","key","add","_node$byIntent6","getAllDefinitions","entries","map","getDefinition","isPlacementOnly","_node$forPlacementByI2","_node$byIntent7","_node$bySemantic3","hasPlacement","size","hasNonPlacement","getSlotVariants","push","getSectionVariants","hasAction","has","executeAction","params","success","message","getRegisteredActions","getCatalog","exports"],"sources":["../../../src/registry/ComponentRegistry.ts"],"sourcesContent":["import type { SectionDefinition } from '../component/componentDefinitions';\nimport type {\n SlotOptions,\n SectionOptions,\n SectionRegistration,\n SlotNode,\n SlotIntentNode,\n SectionNode,\n SectionIntentNode,\n SlotVariant,\n SectionVariant,\n RegistryCatalog,\n ResolveSectionOptions,\n ActionHandler,\n ActionResult,\n} from './types';\n\n/**\n * Accept the legacy positional form `(intent, semantic)` and the new\n * options-object form `({ intent, semantic, placement })`. Returns a\n * normalized `ResolveSectionOptions`.\n */\nfunction normalizeResolveOptions(\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n): ResolveSectionOptions {\n if (intentOrOptions == null) {\n return semantic ? { semantic } : {};\n }\n if (typeof intentOrOptions === 'string') {\n return semantic ? { intent: intentOrOptions, semantic } : { intent: intentOrOptions };\n }\n return intentOrOptions;\n}\n\n/**\n * Intent keys are matched case-insensitively.\n *\n * The intent that reaches resolution has already been through\n * `intent.trim().toUpperCase()` — in this package's `intentExtractor`, and\n * again in `web50-server-ui`'s own copy of it, which calls it with no\n * `validIntents` and passes the result as `providedIntent`, bypassing the\n * validated path here. A client that registers its variants in the lowercase\n * spelling its own taxonomy doc uses therefore matched nothing, and every\n * intent-scoped variant silently fell through to the section default.\n *\n * That is not hypothetical: it was true of the whole seed registry. Measured\n * across 11 live answers, 10 rendered the same hero whatever the intent, and\n * one registered hero component never rendered at all. Nothing errors, nothing\n * logs, and the page looks plausible — which is why this belongs at the Map\n * rather than in either extractor.\n *\n * Normalizing on write AND on read makes the spelling a client's own business.\n */\nconst normalizeIntentKey = (intent: string): string =>\n intent.trim().toUpperCase();\n\nexport class ComponentRegistry<C> {\n private slots = new Map<string, SlotNode<C>>();\n private sections = new Map<string, SectionNode<C>>();\n private definitions = new Map<string, SectionDefinition>();\n private actions = new Map<string, ActionHandler>();\n\n constructor(private fallback: C) {}\n\n // ---------------------------------------------------------------------------\n // Registration\n // ---------------------------------------------------------------------------\n\n registerSlot(name: string, component: C, options?: SlotOptions): this {\n let node = this.slots.get(name);\n if (!node) {\n node = {};\n this.slots.set(name, node);\n }\n\n const { intent, semantic } = options ?? {};\n\n if (intent && semantic) {\n const intentNode = this.ensureSlotIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, component);\n } else if (intent) {\n const intentNode = this.ensureSlotIntent(node, intent);\n intentNode.default = component;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, component);\n } else {\n node.default = component;\n }\n\n return this;\n }\n\n register(\n definition: SectionDefinition,\n variants?: SectionRegistration<C>[],\n ): this {\n // Tolerate missing definitions instead of crashing app init. This\n // happens when a client UMD references a `SectionDefinition` symbol\n // that doesn't exist on the consuming bundle's `Web5Core` global\n // (e.g. UMD built against newer `web5-core` than the app bundle).\n // Without this guard a single missing export breaks every other\n // section the client tries to register.\n if (definition == null) {\n // eslint-disable-next-line no-console\n console.warn(\n '[ComponentRegistry] register() called with a null/undefined SectionDefinition — ' +\n 'likely a version skew between the client UMD and web5-core ' +\n '(an exported definition the UMD imports does not exist on this Web5Core). Skipping.',\n );\n return this;\n }\n this.definitions.set(definition.sectionType, definition);\n\n if (variants) {\n const sectionType = definition.sectionType;\n for (const registration of variants) {\n let node = this.sections.get(sectionType);\n if (!node) {\n node = {};\n this.sections.set(sectionType, node);\n }\n const { intent, semantic, placement, placementId } =\n registration.options ?? {};\n\n // Placement variants are stored on their own slot — no further\n // intent/semantic sub-variants (DL #088 D3.1). If a developer also\n // supplies intent/semantic alongside placement, those are ignored for\n // the placement registration. To register both a placement variant AND\n // an intent variant, register them as separate entries.\n if (placement) {\n // Scoped to a specific placement slot id — keyed so one section type\n // can render differently per placement. An id-less placement variant\n // remains the generic fallback.\n if (placementId) {\n if (!node.forPlacementById) {\n node.forPlacementById = new Map();\n }\n node.forPlacementById.set(placementId, registration);\n } else {\n node.forPlacement = registration;\n }\n continue;\n }\n\n if (intent && semantic) {\n const intentNode = this.ensureSectionIntent(node, intent);\n if (!intentNode.bySemantic) {\n intentNode.bySemantic = new Map();\n }\n intentNode.bySemantic.set(semantic, registration);\n } else if (intent) {\n const intentNode = this.ensureSectionIntent(node, intent);\n intentNode.default = registration;\n } else if (semantic) {\n if (!node.bySemantic) {\n node.bySemantic = new Map();\n }\n node.bySemantic.set(semantic, registration);\n } else {\n node.default = registration;\n }\n }\n }\n\n return this;\n }\n\n registerAction(name: string, handler: ActionHandler): this {\n this.actions.set(name, handler);\n return this;\n }\n\n // ---------------------------------------------------------------------------\n // Resolution\n // ---------------------------------------------------------------------------\n\n resolveSlot(name: string, intent?: string, semantic?: string): C {\n const node = this.slots.get(name);\n if (!node) {\n return this.fallback;\n }\n\n if (intent && semantic) {\n const found = node.byIntent\n ?.get(normalizeIntentKey(intent))\n ?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(normalizeIntentKey(intent))?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default ?? this.fallback;\n }\n\n /**\n * Resolve a section component by type, optionally narrowed by intent /\n * semantic / placement.\n *\n * Accepts both call forms for backward compatibility:\n * resolveSection('hero') — default\n * resolveSection('hero', 'DISCOVERY') — intent (legacy positional)\n * resolveSection('hero', 'DISCOVERY', 'compact') — intent + semantic (legacy)\n * resolveSection('hero', { intent: 'DISCOVERY' }) — options object\n * resolveSection('hero', { placement: true }) — placement variant (DL #088 D3.1)\n * resolveSection('hero', { intent: 'X', placement: true }) — placement wins\n */\n resolveSection(sectionType: string, intent?: string, semantic?: string): C;\n resolveSection(sectionType: string, options: ResolveSectionOptions): C;\n resolveSection(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): C {\n const registration = this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n );\n return registration?.component ?? this.fallback;\n }\n\n /**\n * Resolve the options bundle associated with the matched registration.\n * Same overload semantics as `resolveSection`.\n */\n resolveSectionOptions(\n sectionType: string,\n intent?: string,\n semantic?: string,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionOptions | undefined;\n resolveSectionOptions(\n sectionType: string,\n intentOrOptions?: string | ResolveSectionOptions,\n semantic?: string,\n ): SectionOptions | undefined {\n return this.resolveSectionRegistration(\n sectionType,\n normalizeResolveOptions(intentOrOptions, semantic),\n )?.options;\n }\n\n private resolveSectionRegistration(\n sectionType: string,\n options: ResolveSectionOptions,\n ): SectionRegistration<C> | undefined {\n const node = this.sections.get(sectionType);\n if (!node) {\n return undefined;\n }\n\n const { intent, semantic, placement, placementId } = options;\n\n // Placement wins over intent / semantic when requested AND a placement\n // variant is registered for this section (DL #088 D3.1). Cascade:\n // id-scoped variant → generic placement variant → regular chain.\n if (placement) {\n if (placementId) {\n const byId = node.forPlacementById?.get(placementId);\n if (byId) {\n return byId;\n }\n }\n if (node.forPlacement) {\n return node.forPlacement;\n }\n }\n\n if (intent && semantic) {\n const found = node.byIntent\n ?.get(normalizeIntentKey(intent as string))\n ?.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n if (intent) {\n const found = node.byIntent?.get(normalizeIntentKey(intent as string))\n ?.default;\n if (found) {\n return found;\n }\n }\n if (semantic) {\n const found = node.bySemantic?.get(semantic);\n if (found) {\n return found;\n }\n }\n\n return node.default;\n }\n\n // ---------------------------------------------------------------------------\n // Introspection\n // ---------------------------------------------------------------------------\n\n getAllSlots(): string[] {\n return Array.from(this.slots.keys());\n }\n\n getAllSections(): string[] {\n return Array.from(this.sections.keys());\n }\n\n /**\n * Every intent that has at least one registered slot or section variant —\n * i.e. the client's own intent list, derived from what it actually\n * registered. Assembly uses this to validate an incoming intent before it\n * becomes a resolution key, falling back to core's `DEFAULT_INTENTS` only\n * when a client registers no intent variants at all.\n *\n * Returned NORMALIZED (upper case), whatever spelling the client registered,\n * because these are the map keys. Both consumers compare case-insensitively,\n * so the only visible difference is in a debug view.\n */\n getKnownIntents(): string[] {\n const intents = new Set<string>();\n for (const node of this.slots.values()) {\n node.byIntent?.forEach((_variant, key) => intents.add(key));\n }\n for (const node of this.sections.values()) {\n node.byIntent?.forEach((_variant, key) => intents.add(key));\n }\n return Array.from(intents);\n }\n\n getAllDefinitions(): {\n sectionType: string;\n definition: SectionDefinition;\n }[] {\n return Array.from(this.definitions.entries()).map(\n ([sectionType, definition]) => ({\n sectionType,\n definition,\n }),\n );\n }\n\n getDefinition(sectionType: string): SectionDefinition | undefined {\n return this.definitions.get(sectionType);\n }\n\n /**\n * True when a section type was registered with placement variant(s) only —\n * a `{ placement: true }` (or `placementId`) registration and NO\n * non-placement variant (default / intent / semantic). Such a section is\n * meaningful only inside a placement render; the parser skips its definition\n * when matching in a non-placement context (the main app), so its markdown\n * falls through to the generic sections there.\n *\n * A definition registered with no variants at all (structural defs like\n * `skipNodes` / `htmlComment`) is NOT placement-only — it still matches\n * everywhere.\n */\n isPlacementOnly(sectionType: string): boolean {\n const node = this.sections.get(sectionType);\n if (!node) {\n return false;\n }\n const hasPlacement =\n node.forPlacement != null || (node.forPlacementById?.size ?? 0) > 0;\n const hasNonPlacement =\n node.default != null ||\n (node.byIntent?.size ?? 0) > 0 ||\n (node.bySemantic?.size ?? 0) > 0;\n return hasPlacement && !hasNonPlacement;\n }\n\n getSlotVariants(name: string): SlotVariant[] {\n const node = this.slots.get(name);\n if (!node) {\n return [];\n }\n\n const variants: SlotVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n return variants;\n }\n\n getSectionVariants(sectionType: string): SectionVariant[] {\n const node = this.sections.get(sectionType);\n if (!node) {\n return [];\n }\n\n const variants: SectionVariant[] = [];\n if (node.default) {\n variants.push({});\n }\n\n if (node.bySemantic) {\n for (const semantic of node.bySemantic.keys()) {\n variants.push({ semantic });\n }\n }\n\n if (node.byIntent) {\n for (const [intent, intentNode] of node.byIntent) {\n if (intentNode.default) {\n variants.push({ intent });\n }\n if (intentNode.bySemantic) {\n for (const semantic of intentNode.bySemantic.keys()) {\n variants.push({ intent, semantic });\n }\n }\n }\n }\n\n if (node.forPlacement) {\n variants.push({ placement: true });\n }\n\n if (node.forPlacementById) {\n for (const placementId of node.forPlacementById.keys()) {\n variants.push({ placement: true, placementId });\n }\n }\n\n return variants;\n }\n\n hasAction(name: string): boolean {\n return this.actions.has(name);\n }\n\n async executeAction(\n name: string,\n params: Record<string, string>,\n ): Promise<ActionResult> {\n const handler = this.actions.get(name);\n if (!handler) {\n console.warn(`[Action] No handler for: \"${name}\"`);\n return { success: false, message: `Unknown action: ${name}` };\n }\n return handler(params);\n }\n\n getRegisteredActions(): string[] {\n return Array.from(this.actions.keys());\n }\n\n getCatalog(): RegistryCatalog {\n return {\n slots: this.getAllSlots().map((name) => ({\n name,\n variants: this.getSlotVariants(name),\n })),\n sections: this.getAllSections().map((sectionType) => ({\n name: sectionType,\n variants: this.getSectionVariants(sectionType),\n })),\n definitions: this.getAllDefinitions(),\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private helpers\n // ---------------------------------------------------------------------------\n\n private ensureSectionIntent(\n node: SectionNode<C>,\n intent: string,\n ): SectionIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n const key = normalizeIntentKey(intent);\n let intentNode = node.byIntent.get(key);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(key, intentNode);\n }\n return intentNode;\n }\n\n private ensureSlotIntent(\n node: SlotNode<C>,\n intent: string,\n ): SlotIntentNode<C> {\n if (!node.byIntent) {\n node.byIntent = new Map();\n }\n const key = normalizeIntentKey(intent);\n let intentNode = node.byIntent.get(key);\n if (!intentNode) {\n intentNode = {};\n node.byIntent.set(key, intentNode);\n }\n return intentNode;\n }\n}\n"],"mappings":";;;;;;AAiBA;AACA;AACA;AACA;AACA;AACA,SAASA,uBAAuBA,CAC9BC,eAAgD,EAChDC,QAAiB,EACM;EACvB,IAAID,eAAe,IAAI,IAAI,EAAE;IAC3B,OAAOC,QAAQ,GAAG;MAAEA;IAAS,CAAC,GAAG,CAAC,CAAC;EACrC;EACA,IAAI,OAAOD,eAAe,KAAK,QAAQ,EAAE;IACvC,OAAOC,QAAQ,GAAG;MAAEC,MAAM,EAAEF,eAAe;MAAEC;IAAS,CAAC,GAAG;MAAEC,MAAM,EAAEF;IAAgB,CAAC;EACvF;EACA,OAAOA,eAAe;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMG,kBAAkB,GAAID,MAAc,IACxCA,MAAM,CAACE,IAAI,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;AAEtB,MAAMC,iBAAiB,CAAI;EAMhCC,WAAWA,CAASC,QAAW,EAAE;IAAA,KAAbA,QAAW,GAAXA,QAAW;IAAA,IAAAC,gBAAA,CAAAC,OAAA,iBALf,IAAIC,GAAG,CAAsB,CAAC;IAAA,IAAAF,gBAAA,CAAAC,OAAA,oBAC3B,IAAIC,GAAG,CAAyB,CAAC;IAAA,IAAAF,gBAAA,CAAAC,OAAA,uBAC9B,IAAIC,GAAG,CAA4B,CAAC;IAAA,IAAAF,gBAAA,CAAAC,OAAA,mBACxC,IAAIC,GAAG,CAAwB,CAAC;EAEhB;;EAElC;EACA;EACA;;EAEAC,YAAYA,CAACC,IAAY,EAAEC,SAAY,EAAEC,OAAqB,EAAQ;IACpE,IAAIC,IAAI,GAAG,IAAI,CAACC,KAAK,CAACC,GAAG,CAACL,IAAI,CAAC;IAC/B,IAAI,CAACG,IAAI,EAAE;MACTA,IAAI,GAAG,CAAC,CAAC;MACT,IAAI,CAACC,KAAK,CAACE,GAAG,CAACN,IAAI,EAAEG,IAAI,CAAC;IAC5B;IAEA,MAAM;MAAEd,MAAM;MAAED;IAAS,CAAC,GAAGc,OAAO,IAAI,CAAC,CAAC;IAE1C,IAAIb,MAAM,IAAID,QAAQ,EAAE;MACtB,MAAMmB,UAAU,GAAG,IAAI,CAACC,gBAAgB,CAACL,IAAI,EAAEd,MAAM,CAAC;MACtD,IAAI,CAACkB,UAAU,CAACE,UAAU,EAAE;QAC1BF,UAAU,CAACE,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;MACnC;MACAS,UAAU,CAACE,UAAU,CAACH,GAAG,CAAClB,QAAQ,EAAEa,SAAS,CAAC;IAChD,CAAC,MAAM,IAAIZ,MAAM,EAAE;MACjB,MAAMkB,UAAU,GAAG,IAAI,CAACC,gBAAgB,CAACL,IAAI,EAAEd,MAAM,CAAC;MACtDkB,UAAU,CAACV,OAAO,GAAGI,SAAS;IAChC,CAAC,MAAM,IAAIb,QAAQ,EAAE;MACnB,IAAI,CAACe,IAAI,CAACM,UAAU,EAAE;QACpBN,IAAI,CAACM,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;MAC7B;MACAK,IAAI,CAACM,UAAU,CAACH,GAAG,CAAClB,QAAQ,EAAEa,SAAS,CAAC;IAC1C,CAAC,MAAM;MACLE,IAAI,CAACN,OAAO,GAAGI,SAAS;IAC1B;IAEA,OAAO,IAAI;EACb;EAEAS,QAAQA,CACNC,UAA6B,EAC7BC,QAAmC,EAC7B;IACN;IACA;IACA;IACA;IACA;IACA;IACA,IAAID,UAAU,IAAI,IAAI,EAAE;MACtB;MACAE,OAAO,CAACC,IAAI,CACV,kFAAkF,GAChF,6DAA6D,GAC7D,qFACJ,CAAC;MACD,OAAO,IAAI;IACb;IACA,IAAI,CAACC,WAAW,CAACT,GAAG,CAACK,UAAU,CAACK,WAAW,EAAEL,UAAU,CAAC;IAExD,IAAIC,QAAQ,EAAE;MACZ,MAAMI,WAAW,GAAGL,UAAU,CAACK,WAAW;MAC1C,KAAK,MAAMC,YAAY,IAAIL,QAAQ,EAAE;QACnC,IAAIT,IAAI,GAAG,IAAI,CAACe,QAAQ,CAACb,GAAG,CAACW,WAAW,CAAC;QACzC,IAAI,CAACb,IAAI,EAAE;UACTA,IAAI,GAAG,CAAC,CAAC;UACT,IAAI,CAACe,QAAQ,CAACZ,GAAG,CAACU,WAAW,EAAEb,IAAI,CAAC;QACtC;QACA,MAAM;UAAEd,MAAM;UAAED,QAAQ;UAAE+B,SAAS;UAAEC;QAAY,CAAC,GAChDH,YAAY,CAACf,OAAO,IAAI,CAAC,CAAC;;QAE5B;QACA;QACA;QACA;QACA;QACA,IAAIiB,SAAS,EAAE;UACb;UACA;UACA;UACA,IAAIC,WAAW,EAAE;YACf,IAAI,CAACjB,IAAI,CAACkB,gBAAgB,EAAE;cAC1BlB,IAAI,CAACkB,gBAAgB,GAAG,IAAIvB,GAAG,CAAC,CAAC;YACnC;YACAK,IAAI,CAACkB,gBAAgB,CAACf,GAAG,CAACc,WAAW,EAAEH,YAAY,CAAC;UACtD,CAAC,MAAM;YACLd,IAAI,CAACmB,YAAY,GAAGL,YAAY;UAClC;UACA;QACF;QAEA,IAAI5B,MAAM,IAAID,QAAQ,EAAE;UACtB,MAAMmB,UAAU,GAAG,IAAI,CAACgB,mBAAmB,CAACpB,IAAI,EAAEd,MAAM,CAAC;UACzD,IAAI,CAACkB,UAAU,CAACE,UAAU,EAAE;YAC1BF,UAAU,CAACE,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;UACnC;UACAS,UAAU,CAACE,UAAU,CAACH,GAAG,CAAClB,QAAQ,EAAE6B,YAAY,CAAC;QACnD,CAAC,MAAM,IAAI5B,MAAM,EAAE;UACjB,MAAMkB,UAAU,GAAG,IAAI,CAACgB,mBAAmB,CAACpB,IAAI,EAAEd,MAAM,CAAC;UACzDkB,UAAU,CAACV,OAAO,GAAGoB,YAAY;QACnC,CAAC,MAAM,IAAI7B,QAAQ,EAAE;UACnB,IAAI,CAACe,IAAI,CAACM,UAAU,EAAE;YACpBN,IAAI,CAACM,UAAU,GAAG,IAAIX,GAAG,CAAC,CAAC;UAC7B;UACAK,IAAI,CAACM,UAAU,CAACH,GAAG,CAAClB,QAAQ,EAAE6B,YAAY,CAAC;QAC7C,CAAC,MAAM;UACLd,IAAI,CAACN,OAAO,GAAGoB,YAAY;QAC7B;MACF;IACF;IAEA,OAAO,IAAI;EACb;EAEAO,cAAcA,CAACxB,IAAY,EAAEyB,OAAsB,EAAQ;IACzD,IAAI,CAACC,OAAO,CAACpB,GAAG,CAACN,IAAI,EAAEyB,OAAO,CAAC;IAC/B,OAAO,IAAI;EACb;;EAEA;EACA;EACA;;EAEAE,WAAWA,CAAC3B,IAAY,EAAEX,MAAe,EAAED,QAAiB,EAAK;IAC/D,MAAMe,IAAI,GAAG,IAAI,CAACC,KAAK,CAACC,GAAG,CAACL,IAAI,CAAC;IACjC,IAAI,CAACG,IAAI,EAAE;MACT,OAAO,IAAI,CAACR,QAAQ;IACtB;IAEA,IAAIN,MAAM,IAAID,QAAQ,EAAE;MAAA,IAAAwC,cAAA;MACtB,MAAMC,KAAK,IAAAD,cAAA,GAAGzB,IAAI,CAAC2B,QAAQ,cAAAF,cAAA,GAAbA,cAAA,CACVvB,GAAG,CAACf,kBAAkB,CAACD,MAAM,CAAC,CAAC,cAAAuC,cAAA,GADrBA,cAAA,CAEVnB,UAAU,qBAFAmB,cAAA,CAEEvB,GAAG,CAACjB,QAAQ,CAAC;MAC7B,IAAIyC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAIxC,MAAM,EAAE;MAAA,IAAA0C,eAAA;MACV,MAAMF,KAAK,IAAAE,eAAA,GAAG5B,IAAI,CAAC2B,QAAQ,cAAAC,eAAA,GAAbA,eAAA,CAAe1B,GAAG,CAACf,kBAAkB,CAACD,MAAM,CAAC,CAAC,qBAA9C0C,eAAA,CAAgDlC,OAAO;MACrE,IAAIgC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAIzC,QAAQ,EAAE;MAAA,IAAA4C,gBAAA;MACZ,MAAMH,KAAK,IAAAG,gBAAA,GAAG7B,IAAI,CAACM,UAAU,qBAAfuB,gBAAA,CAAiB3B,GAAG,CAACjB,QAAQ,CAAC;MAC5C,IAAIyC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IAEA,OAAO1B,IAAI,CAACN,OAAO,IAAI,IAAI,CAACF,QAAQ;EACtC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGEsC,cAAcA,CACZjB,WAAmB,EACnB7B,eAAgD,EAChDC,QAAiB,EACd;IACH,MAAM6B,YAAY,GAAG,IAAI,CAACiB,0BAA0B,CAClDlB,WAAW,EACX9B,uBAAuB,CAACC,eAAe,EAAEC,QAAQ,CACnD,CAAC;IACD,OAAO,CAAA6B,YAAY,oBAAZA,YAAY,CAAEhB,SAAS,KAAI,IAAI,CAACN,QAAQ;EACjD;;EAEA;AACF;AACA;AACA;;EAUEwC,qBAAqBA,CACnBnB,WAAmB,EACnB7B,eAAgD,EAChDC,QAAiB,EACW;IAAA,IAAAgD,qBAAA;IAC5B,QAAAA,qBAAA,GAAO,IAAI,CAACF,0BAA0B,CACpClB,WAAW,EACX9B,uBAAuB,CAACC,eAAe,EAAEC,QAAQ,CACnD,CAAC,qBAHMgD,qBAAA,CAGJlC,OAAO;EACZ;EAEQgC,0BAA0BA,CAChClB,WAAmB,EACnBd,OAA8B,EACM;IACpC,MAAMC,IAAI,GAAG,IAAI,CAACe,QAAQ,CAACb,GAAG,CAACW,WAAW,CAAC;IAC3C,IAAI,CAACb,IAAI,EAAE;MACT,OAAOkC,SAAS;IAClB;IAEA,MAAM;MAAEhD,MAAM;MAAED,QAAQ;MAAE+B,SAAS;MAAEC;IAAY,CAAC,GAAGlB,OAAO;;IAE5D;IACA;IACA;IACA,IAAIiB,SAAS,EAAE;MACb,IAAIC,WAAW,EAAE;QAAA,IAAAkB,qBAAA;QACf,MAAMC,IAAI,IAAAD,qBAAA,GAAGnC,IAAI,CAACkB,gBAAgB,qBAArBiB,qBAAA,CAAuBjC,GAAG,CAACe,WAAW,CAAC;QACpD,IAAImB,IAAI,EAAE;UACR,OAAOA,IAAI;QACb;MACF;MACA,IAAIpC,IAAI,CAACmB,YAAY,EAAE;QACrB,OAAOnB,IAAI,CAACmB,YAAY;MAC1B;IACF;IAEA,IAAIjC,MAAM,IAAID,QAAQ,EAAE;MAAA,IAAAoD,eAAA;MACtB,MAAMX,KAAK,IAAAW,eAAA,GAAGrC,IAAI,CAAC2B,QAAQ,cAAAU,eAAA,GAAbA,eAAA,CACVnC,GAAG,CAACf,kBAAkB,CAACD,MAAgB,CAAC,CAAC,cAAAmD,eAAA,GAD/BA,eAAA,CAEV/B,UAAU,qBAFA+B,eAAA,CAEEnC,GAAG,CAACjB,QAAQ,CAAC;MAC7B,IAAIyC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAIxC,MAAM,EAAE;MAAA,IAAAoD,eAAA;MACV,MAAMZ,KAAK,IAAAY,eAAA,GAAGtC,IAAI,CAAC2B,QAAQ,cAAAW,eAAA,GAAbA,eAAA,CAAepC,GAAG,CAACf,kBAAkB,CAACD,MAAgB,CAAC,CAAC,qBAAxDoD,eAAA,CACV5C,OAAO;MACX,IAAIgC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IACA,IAAIzC,QAAQ,EAAE;MAAA,IAAAsD,iBAAA;MACZ,MAAMb,KAAK,IAAAa,iBAAA,GAAGvC,IAAI,CAACM,UAAU,qBAAfiC,iBAAA,CAAiBrC,GAAG,CAACjB,QAAQ,CAAC;MAC5C,IAAIyC,KAAK,EAAE;QACT,OAAOA,KAAK;MACd;IACF;IAEA,OAAO1B,IAAI,CAACN,OAAO;EACrB;;EAEA;EACA;EACA;;EAEA8C,WAAWA,CAAA,EAAa;IACtB,OAAOC,KAAK,CAACC,IAAI,CAAC,IAAI,CAACzC,KAAK,CAAC0C,IAAI,CAAC,CAAC,CAAC;EACtC;EAEAC,cAAcA,CAAA,EAAa;IACzB,OAAOH,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC3B,QAAQ,CAAC4B,IAAI,CAAC,CAAC,CAAC;EACzC;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACEE,eAAeA,CAAA,EAAa;IAC1B,MAAMC,OAAO,GAAG,IAAIC,GAAG,CAAS,CAAC;IACjC,KAAK,MAAM/C,IAAI,IAAI,IAAI,CAACC,KAAK,CAAC+C,MAAM,CAAC,CAAC,EAAE;MAAA,IAAAC,eAAA;MACtC,CAAAA,eAAA,GAAAjD,IAAI,CAAC2B,QAAQ,aAAbsB,eAAA,CAAeC,OAAO,CAAC,CAACC,QAAQ,EAAEC,GAAG,KAAKN,OAAO,CAACO,GAAG,CAACD,GAAG,CAAC,CAAC;IAC7D;IACA,KAAK,MAAMpD,IAAI,IAAI,IAAI,CAACe,QAAQ,CAACiC,MAAM,CAAC,CAAC,EAAE;MAAA,IAAAM,eAAA;MACzC,CAAAA,eAAA,GAAAtD,IAAI,CAAC2B,QAAQ,aAAb2B,eAAA,CAAeJ,OAAO,CAAC,CAACC,QAAQ,EAAEC,GAAG,KAAKN,OAAO,CAACO,GAAG,CAACD,GAAG,CAAC,CAAC;IAC7D;IACA,OAAOX,KAAK,CAACC,IAAI,CAACI,OAAO,CAAC;EAC5B;EAEAS,iBAAiBA,CAAA,EAGb;IACF,OAAOd,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC9B,WAAW,CAAC4C,OAAO,CAAC,CAAC,CAAC,CAACC,GAAG,CAC/C,CAAC,CAAC5C,WAAW,EAAEL,UAAU,CAAC,MAAM;MAC9BK,WAAW;MACXL;IACF,CAAC,CACH,CAAC;EACH;EAEAkD,aAAaA,CAAC7C,WAAmB,EAAiC;IAChE,OAAO,IAAI,CAACD,WAAW,CAACV,GAAG,CAACW,WAAW,CAAC;EAC1C;;EAEA;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE8C,eAAeA,CAAC9C,WAAmB,EAAW;IAAA,IAAA+C,sBAAA,EAAAC,eAAA,EAAAC,iBAAA;IAC5C,MAAM9D,IAAI,GAAG,IAAI,CAACe,QAAQ,CAACb,GAAG,CAACW,WAAW,CAAC;IAC3C,IAAI,CAACb,IAAI,EAAE;MACT,OAAO,KAAK;IACd;IACA,MAAM+D,YAAY,GAChB/D,IAAI,CAACmB,YAAY,IAAI,IAAI,IAAI,CAAC,EAAAyC,sBAAA,GAAA5D,IAAI,CAACkB,gBAAgB,qBAArB0C,sBAAA,CAAuBI,IAAI,KAAI,CAAC,IAAI,CAAC;IACrE,MAAMC,eAAe,GACnBjE,IAAI,CAACN,OAAO,IAAI,IAAI,IACpB,CAAC,EAAAmE,eAAA,GAAA7D,IAAI,CAAC2B,QAAQ,qBAAbkC,eAAA,CAAeG,IAAI,KAAI,CAAC,IAAI,CAAC,IAC9B,CAAC,EAAAF,iBAAA,GAAA9D,IAAI,CAACM,UAAU,qBAAfwD,iBAAA,CAAiBE,IAAI,KAAI,CAAC,IAAI,CAAC;IAClC,OAAOD,YAAY,IAAI,CAACE,eAAe;EACzC;EAEAC,eAAeA,CAACrE,IAAY,EAAiB;IAC3C,MAAMG,IAAI,GAAG,IAAI,CAACC,KAAK,CAACC,GAAG,CAACL,IAAI,CAAC;IACjC,IAAI,CAACG,IAAI,EAAE;MACT,OAAO,EAAE;IACX;IAEA,MAAMS,QAAuB,GAAG,EAAE;IAClC,IAAIT,IAAI,CAACN,OAAO,EAAE;MAChBe,QAAQ,CAAC0D,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB;IAEA,IAAInE,IAAI,CAACM,UAAU,EAAE;MACnB,KAAK,MAAMrB,QAAQ,IAAIe,IAAI,CAACM,UAAU,CAACqC,IAAI,CAAC,CAAC,EAAE;QAC7ClC,QAAQ,CAAC0D,IAAI,CAAC;UAAElF;QAAS,CAAC,CAAC;MAC7B;IACF;IAEA,IAAIe,IAAI,CAAC2B,QAAQ,EAAE;MACjB,KAAK,MAAM,CAACzC,MAAM,EAAEkB,UAAU,CAAC,IAAIJ,IAAI,CAAC2B,QAAQ,EAAE;QAChD,IAAIvB,UAAU,CAACV,OAAO,EAAE;UACtBe,QAAQ,CAAC0D,IAAI,CAAC;YAAEjF;UAAO,CAAC,CAAC;QAC3B;QACA,IAAIkB,UAAU,CAACE,UAAU,EAAE;UACzB,KAAK,MAAMrB,QAAQ,IAAImB,UAAU,CAACE,UAAU,CAACqC,IAAI,CAAC,CAAC,EAAE;YACnDlC,QAAQ,CAAC0D,IAAI,CAAC;cAAEjF,MAAM;cAAED;YAAS,CAAC,CAAC;UACrC;QACF;MACF;IACF;IAEA,OAAOwB,QAAQ;EACjB;EAEA2D,kBAAkBA,CAACvD,WAAmB,EAAoB;IACxD,MAAMb,IAAI,GAAG,IAAI,CAACe,QAAQ,CAACb,GAAG,CAACW,WAAW,CAAC;IAC3C,IAAI,CAACb,IAAI,EAAE;MACT,OAAO,EAAE;IACX;IAEA,MAAMS,QAA0B,GAAG,EAAE;IACrC,IAAIT,IAAI,CAACN,OAAO,EAAE;MAChBe,QAAQ,CAAC0D,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB;IAEA,IAAInE,IAAI,CAACM,UAAU,EAAE;MACnB,KAAK,MAAMrB,QAAQ,IAAIe,IAAI,CAACM,UAAU,CAACqC,IAAI,CAAC,CAAC,EAAE;QAC7ClC,QAAQ,CAAC0D,IAAI,CAAC;UAAElF;QAAS,CAAC,CAAC;MAC7B;IACF;IAEA,IAAIe,IAAI,CAAC2B,QAAQ,EAAE;MACjB,KAAK,MAAM,CAACzC,MAAM,EAAEkB,UAAU,CAAC,IAAIJ,IAAI,CAAC2B,QAAQ,EAAE;QAChD,IAAIvB,UAAU,CAACV,OAAO,EAAE;UACtBe,QAAQ,CAAC0D,IAAI,CAAC;YAAEjF;UAAO,CAAC,CAAC;QAC3B;QACA,IAAIkB,UAAU,CAACE,UAAU,EAAE;UACzB,KAAK,MAAMrB,QAAQ,IAAImB,UAAU,CAACE,UAAU,CAACqC,IAAI,CAAC,CAAC,EAAE;YACnDlC,QAAQ,CAAC0D,IAAI,CAAC;cAAEjF,MAAM;cAAED;YAAS,CAAC,CAAC;UACrC;QACF;MACF;IACF;IAEA,IAAIe,IAAI,CAACmB,YAAY,EAAE;MACrBV,QAAQ,CAAC0D,IAAI,CAAC;QAAEnD,SAAS,EAAE;MAAK,CAAC,CAAC;IACpC;IAEA,IAAIhB,IAAI,CAACkB,gBAAgB,EAAE;MACzB,KAAK,MAAMD,WAAW,IAAIjB,IAAI,CAACkB,gBAAgB,CAACyB,IAAI,CAAC,CAAC,EAAE;QACtDlC,QAAQ,CAAC0D,IAAI,CAAC;UAAEnD,SAAS,EAAE,IAAI;UAAEC;QAAY,CAAC,CAAC;MACjD;IACF;IAEA,OAAOR,QAAQ;EACjB;EAEA4D,SAASA,CAACxE,IAAY,EAAW;IAC/B,OAAO,IAAI,CAAC0B,OAAO,CAAC+C,GAAG,CAACzE,IAAI,CAAC;EAC/B;EAEA,MAAM0E,aAAaA,CACjB1E,IAAY,EACZ2E,MAA8B,EACP;IACvB,MAAMlD,OAAO,GAAG,IAAI,CAACC,OAAO,CAACrB,GAAG,CAACL,IAAI,CAAC;IACtC,IAAI,CAACyB,OAAO,EAAE;MACZZ,OAAO,CAACC,IAAI,CAAC,6BAA6Bd,IAAI,GAAG,CAAC;MAClD,OAAO;QAAE4E,OAAO,EAAE,KAAK;QAAEC,OAAO,EAAE,mBAAmB7E,IAAI;MAAG,CAAC;IAC/D;IACA,OAAOyB,OAAO,CAACkD,MAAM,CAAC;EACxB;EAEAG,oBAAoBA,CAAA,EAAa;IAC/B,OAAOlC,KAAK,CAACC,IAAI,CAAC,IAAI,CAACnB,OAAO,CAACoB,IAAI,CAAC,CAAC,CAAC;EACxC;EAEAiC,UAAUA,CAAA,EAAoB;IAC5B,OAAO;MACL3E,KAAK,EAAE,IAAI,CAACuC,WAAW,CAAC,CAAC,CAACiB,GAAG,CAAE5D,IAAI,KAAM;QACvCA,IAAI;QACJY,QAAQ,EAAE,IAAI,CAACyD,eAAe,CAACrE,IAAI;MACrC,CAAC,CAAC,CAAC;MACHkB,QAAQ,EAAE,IAAI,CAAC6B,cAAc,CAAC,CAAC,CAACa,GAAG,CAAE5C,WAAW,KAAM;QACpDhB,IAAI,EAAEgB,WAAW;QACjBJ,QAAQ,EAAE,IAAI,CAAC2D,kBAAkB,CAACvD,WAAW;MAC/C,CAAC,CAAC,CAAC;MACHD,WAAW,EAAE,IAAI,CAAC2C,iBAAiB,CAAC;IACtC,CAAC;EACH;;EAEA;EACA;EACA;;EAEQnC,mBAAmBA,CACzBpB,IAAoB,EACpBd,MAAc,EACQ;IACtB,IAAI,CAACc,IAAI,CAAC2B,QAAQ,EAAE;MAClB3B,IAAI,CAAC2B,QAAQ,GAAG,IAAIhC,GAAG,CAAC,CAAC;IAC3B;IACA,MAAMyD,GAAG,GAAGjE,kBAAkB,CAACD,MAAM,CAAC;IACtC,IAAIkB,UAAU,GAAGJ,IAAI,CAAC2B,QAAQ,CAACzB,GAAG,CAACkD,GAAG,CAAC;IACvC,IAAI,CAAChD,UAAU,EAAE;MACfA,UAAU,GAAG,CAAC,CAAC;MACfJ,IAAI,CAAC2B,QAAQ,CAACxB,GAAG,CAACiD,GAAG,EAAEhD,UAAU,CAAC;IACpC;IACA,OAAOA,UAAU;EACnB;EAEQC,gBAAgBA,CACtBL,IAAiB,EACjBd,MAAc,EACK;IACnB,IAAI,CAACc,IAAI,CAAC2B,QAAQ,EAAE;MAClB3B,IAAI,CAAC2B,QAAQ,GAAG,IAAIhC,GAAG,CAAC,CAAC;IAC3B;IACA,MAAMyD,GAAG,GAAGjE,kBAAkB,CAACD,MAAM,CAAC;IACtC,IAAIkB,UAAU,GAAGJ,IAAI,CAAC2B,QAAQ,CAACzB,GAAG,CAACkD,GAAG,CAAC;IACvC,IAAI,CAAChD,UAAU,EAAE;MACfA,UAAU,GAAG,CAAC,CAAC;MACfJ,IAAI,CAAC2B,QAAQ,CAACxB,GAAG,CAACiD,GAAG,EAAEhD,UAAU,CAAC;IACpC;IACA,OAAOA,UAAU;EACnB;AACF;AAACyE,OAAA,CAAAvF,iBAAA,GAAAA,iBAAA","ignoreList":[]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The url an entity card links to.
|
|
3
|
+
*
|
|
4
|
+
* Every entity surface was carrying its own copy of this rule — three of them
|
|
5
|
+
* byte-identical (`EntityProductListSection`, `EntityCollectionSection`,
|
|
6
|
+
* `ComparisonSection`), two more spelled inline (`EntityArticleListSection`,
|
|
7
|
+
* `HeroEntityImageSection`) — in every client bundle. It lives here for the
|
|
8
|
+
* same reason `formatProductPriceLabel` does (DL #218): every seed template
|
|
9
|
+
* externalizes `@wix/web5-core`, so the card, the hero and the comparison
|
|
10
|
+
* surface all get one implementation and no template needs a change.
|
|
11
|
+
*
|
|
12
|
+
* ## It picks; it does not rewrite
|
|
13
|
+
*
|
|
14
|
+
* Deciding WHICH url an item links to is a property of the item, and this
|
|
15
|
+
* knows the item. Deciding what ORIGIN that url should be on is a property of
|
|
16
|
+
* the surface — it needs the storefront the shopper is standing on and the set
|
|
17
|
+
* of origins that count as this site's — and this knows neither. That belongs
|
|
18
|
+
* to the link layer (`useWeb5Link().resolveUrl`), which has both.
|
|
19
|
+
*
|
|
20
|
+
* So the contract is one line: `resolveUrl(entityHref(item))`. One picker, one
|
|
21
|
+
* resolver, nothing in between. A second rewriter sitting between them is how
|
|
22
|
+
* you get two authorities on the same href fighting over it.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** An entity reference that never resolved — linking it navigates nowhere. */
|
|
26
|
+
const UNRESOLVED_SCHEME = 'web5://';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The url an entity links to, or `undefined` when it has none worth linking.
|
|
30
|
+
*
|
|
31
|
+
* `data.url` is the resolved catalog url and wins: it is the row the turn sent,
|
|
32
|
+
* so on a variant question it is the matched child's url — the one carrying
|
|
33
|
+
* `?variant=` (DL #216). `entityUrl` is what parsing recovered from the
|
|
34
|
+
* markdown link and is the fallback for an item resolution never reached.
|
|
35
|
+
*
|
|
36
|
+
* A `web5://` url means the entity resolved to nothing. The caller renders the
|
|
37
|
+
* card unlinked rather than linking a scheme the browser cannot follow — which
|
|
38
|
+
* is what every copy of this rule already did, and worth keeping central so it
|
|
39
|
+
* cannot drift on one surface.
|
|
40
|
+
*/
|
|
41
|
+
export function entityHref(item) {
|
|
42
|
+
var _item$data;
|
|
43
|
+
const url = ((_item$data = item.data) == null ? void 0 : _item$data.url) || item.entityUrl || undefined;
|
|
44
|
+
if (!url || url.startsWith(UNRESOLVED_SCHEME)) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=entityHref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["UNRESOLVED_SCHEME","entityHref","item","_item$data","url","data","entityUrl","undefined","startsWith"],"sources":["../../../src/entity/entityHref.ts"],"sourcesContent":["/**\n * The url an entity card links to.\n *\n * Every entity surface was carrying its own copy of this rule — three of them\n * byte-identical (`EntityProductListSection`, `EntityCollectionSection`,\n * `ComparisonSection`), two more spelled inline (`EntityArticleListSection`,\n * `HeroEntityImageSection`) — in every client bundle. It lives here for the\n * same reason `formatProductPriceLabel` does (DL #218): every seed template\n * externalizes `@wix/web5-core`, so the card, the hero and the comparison\n * surface all get one implementation and no template needs a change.\n *\n * ## It picks; it does not rewrite\n *\n * Deciding WHICH url an item links to is a property of the item, and this\n * knows the item. Deciding what ORIGIN that url should be on is a property of\n * the surface — it needs the storefront the shopper is standing on and the set\n * of origins that count as this site's — and this knows neither. That belongs\n * to the link layer (`useWeb5Link().resolveUrl`), which has both.\n *\n * So the contract is one line: `resolveUrl(entityHref(item))`. One picker, one\n * resolver, nothing in between. A second rewriter sitting between them is how\n * you get two authorities on the same href fighting over it.\n */\nimport type { EntityItem } from '../component/types';\n\n/** An entity reference that never resolved — linking it navigates nowhere. */\nconst UNRESOLVED_SCHEME = 'web5://';\n\n/**\n * The url an entity links to, or `undefined` when it has none worth linking.\n *\n * `data.url` is the resolved catalog url and wins: it is the row the turn sent,\n * so on a variant question it is the matched child's url — the one carrying\n * `?variant=` (DL #216). `entityUrl` is what parsing recovered from the\n * markdown link and is the fallback for an item resolution never reached.\n *\n * A `web5://` url means the entity resolved to nothing. The caller renders the\n * card unlinked rather than linking a scheme the browser cannot follow — which\n * is what every copy of this rule already did, and worth keeping central so it\n * cannot drift on one surface.\n */\nexport function entityHref(item: EntityItem): string | undefined {\n const url = item.data?.url || item.entityUrl || undefined;\n if (!url || url.startsWith(UNRESOLVED_SCHEME)) {\n return undefined;\n }\n return url;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA,MAAMA,iBAAiB,GAAG,SAAS;;AAEnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,UAAUA,CAACC,IAAgB,EAAsB;EAAA,IAAAC,UAAA;EAC/D,MAAMC,GAAG,GAAG,EAAAD,UAAA,GAAAD,IAAI,CAACG,IAAI,qBAATF,UAAA,CAAWC,GAAG,KAAIF,IAAI,CAACI,SAAS,IAAIC,SAAS;EACzD,IAAI,CAACH,GAAG,IAAIA,GAAG,CAACI,UAAU,CAACR,iBAAiB,CAAC,EAAE;IAC7C,OAAOO,SAAS;EAClB;EACA,OAAOH,GAAG;AACZ","ignoreList":[]}
|
|
@@ -1,3 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A catalog url reduced to `path + query + hash`, so it resolves against the
|
|
3
|
+
* storefront the shopper is actually on.
|
|
4
|
+
*
|
|
5
|
+
* A site's index stores each entity's url from the mapping schema's
|
|
6
|
+
* `payload.url` template, and a live site writes that template ABSOLUTE —
|
|
7
|
+
* `https://www.smallflower.com/products/{handle}`. A demo, staging or clone
|
|
8
|
+
* store serves the same catalog from a different origin, so rendered as
|
|
9
|
+
* indexed, every product link in an answer walks the shopper off the store
|
|
10
|
+
* they are on and onto the canonical one — a different cart, a different
|
|
11
|
+
* inventory, a different checkout.
|
|
12
|
+
*
|
|
13
|
+
* The quieter half is worse. `useWeb5Link.appendWeb5Id` classifies such a url
|
|
14
|
+
* as external and, by design, refuses to stamp `?web5_id=` on an external
|
|
15
|
+
* link, so the destination page never learns which conversation sent the
|
|
16
|
+
* shopper there and every warm-guarded placement on it stays inert.
|
|
17
|
+
*
|
|
18
|
+
* The origin is the one thing in the row the index cannot know and the client
|
|
19
|
+
* can: an entity url names a resource in THIS site's catalog, and the catalog
|
|
20
|
+
* is served by the storefront the page is running on. So the path is
|
|
21
|
+
* authoritative and the origin is advisory. `linkConfig.baseUrl` remains the
|
|
22
|
+
* escape hatch — a client that means its links to leave the current origin
|
|
23
|
+
* says so there, and `resolveRelativeUrl` puts that base back on.
|
|
24
|
+
*
|
|
25
|
+
* Only `url` is reduced. Images legitimately live on another origin
|
|
26
|
+
* (`cdn.shopify.com`), and `img` is left exactly as indexed.
|
|
27
|
+
*
|
|
28
|
+
* This is the client's half. The mapping schema is where it should be
|
|
29
|
+
* corrected — the reference schema in `web5-collection-mapping/schema/
|
|
30
|
+
* examples/ecom-site.schema.json` already ships the right shape
|
|
31
|
+
* (`{"template": "/products/{handle}"}`) — and a site whose schema is already
|
|
32
|
+
* relative passes through here untouched, so the two do not fight.
|
|
33
|
+
*/
|
|
34
|
+
export function toCatalogPath(url) {
|
|
35
|
+
// Not absolute http(s): a root-relative path is already right, and a
|
|
36
|
+
// `mailto:`/`web5://`/protocol-relative url is not a catalog path at all.
|
|
37
|
+
if (!/^https?:\/\//i.test(url)) {
|
|
38
|
+
return url;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const parsed = new URL(url);
|
|
42
|
+
// `?variant=…` is exactly how a resolved variant travels (DL #216), and
|
|
43
|
+
// the hash can carry an anchor the answer meant — both survive.
|
|
44
|
+
return parsed.pathname + parsed.search + parsed.hash;
|
|
45
|
+
} catch {
|
|
46
|
+
return url;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
1
50
|
/**
|
|
2
51
|
* One entity row, normalized onto the `ApiPayloadItem` shape both resolution
|
|
3
52
|
* paths key off.
|
|
@@ -28,15 +77,19 @@ export function normalizeEntityItem(raw) {
|
|
|
28
77
|
}
|
|
29
78
|
|
|
30
79
|
// Rows travel as-is apart from the `doc_id` → `id` alias every consumer keys
|
|
31
|
-
// off, and the image alias
|
|
80
|
+
// off, the origin reduction below, and the image alias after it.
|
|
32
81
|
//
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
82
|
+
// The url is never REBUILT — rebuilding the path from `handle` would throw
|
|
83
|
+
// away the `?variant=…` that is exactly how a resolved variant travels.
|
|
84
|
+
// `toCatalogPath` only drops the origin the index stamped; path, query and
|
|
85
|
+
// hash are carried over verbatim.
|
|
36
86
|
const normalized = {
|
|
37
87
|
...rec,
|
|
38
88
|
id
|
|
39
89
|
};
|
|
90
|
+
if (typeof rec.url === 'string' && rec.url) {
|
|
91
|
+
normalized.url = toCatalogPath(rec.url);
|
|
92
|
+
}
|
|
40
93
|
|
|
41
94
|
// Product rows carry the image as `thumbnail` / `images[]` (the Vespa doc
|
|
42
95
|
// shape), but the shared transform (`transformToGenericEntityData`) reads
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["normalizeEntityItem","raw","Array","isArray","rec","docId","doc_id","ownId","id","normalized","img","thumbnail","images","entityPayloadFromItems","container","items","payload","item","push"],"sources":["../../../src/entity/entityPayload.ts"],"sourcesContent":["import type { ApiPayloadItem } from '../types/entity';\n\n/**\n * One entity row, normalized onto the `ApiPayloadItem` shape both resolution\n * paths key off.\n *\n * Two producers, one document. `list-items` answers with the raw retrieval\n * document; the turn answers with the engine's allowlisted projection of the\n * SAME document — same field names, plus the keys only a card reads (`type`,\n * `variantId`, and the matched child's `url`/`img`/`price` already overlaid).\n * Normalizing both here is what lets `findEntityInPayload` resolve a reference\n * without caring which one answered.\n *\n * `id` is what a `web5://entity/<type>/<id>` reference resolves against, and\n * the reference carries the DOCUMENT id — so `doc_id` becomes `id`, exactly as\n * the `list-items` path has always done. The fallback to a row's own `id` is\n * for the day a store publishes one (none does today); a row with neither has\n * nothing to be keyed by and is dropped.\n */\nexport function normalizeEntityItem(raw: unknown): ApiPayloadItem | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return null;\n }\n const rec = raw as Record<string, unknown>;\n const docId = typeof rec.doc_id === 'string' ? rec.doc_id : '';\n const ownId = typeof rec.id === 'string' ? rec.id : '';\n const id = docId || ownId;\n if (!id) {\n return null;\n }\n\n // Rows travel as-is apart from the `doc_id` → `id` alias every consumer keys\n // off, and the image alias
|
|
1
|
+
{"version":3,"names":["toCatalogPath","url","test","parsed","URL","pathname","search","hash","normalizeEntityItem","raw","Array","isArray","rec","docId","doc_id","ownId","id","normalized","img","thumbnail","images","entityPayloadFromItems","container","items","payload","item","push"],"sources":["../../../src/entity/entityPayload.ts"],"sourcesContent":["import type { ApiPayloadItem } from '../types/entity';\n\n/**\n * A catalog url reduced to `path + query + hash`, so it resolves against the\n * storefront the shopper is actually on.\n *\n * A site's index stores each entity's url from the mapping schema's\n * `payload.url` template, and a live site writes that template ABSOLUTE —\n * `https://www.smallflower.com/products/{handle}`. A demo, staging or clone\n * store serves the same catalog from a different origin, so rendered as\n * indexed, every product link in an answer walks the shopper off the store\n * they are on and onto the canonical one — a different cart, a different\n * inventory, a different checkout.\n *\n * The quieter half is worse. `useWeb5Link.appendWeb5Id` classifies such a url\n * as external and, by design, refuses to stamp `?web5_id=` on an external\n * link, so the destination page never learns which conversation sent the\n * shopper there and every warm-guarded placement on it stays inert.\n *\n * The origin is the one thing in the row the index cannot know and the client\n * can: an entity url names a resource in THIS site's catalog, and the catalog\n * is served by the storefront the page is running on. So the path is\n * authoritative and the origin is advisory. `linkConfig.baseUrl` remains the\n * escape hatch — a client that means its links to leave the current origin\n * says so there, and `resolveRelativeUrl` puts that base back on.\n *\n * Only `url` is reduced. Images legitimately live on another origin\n * (`cdn.shopify.com`), and `img` is left exactly as indexed.\n *\n * This is the client's half. The mapping schema is where it should be\n * corrected — the reference schema in `web5-collection-mapping/schema/\n * examples/ecom-site.schema.json` already ships the right shape\n * (`{\"template\": \"/products/{handle}\"}`) — and a site whose schema is already\n * relative passes through here untouched, so the two do not fight.\n */\nexport function toCatalogPath(url: string): string {\n // Not absolute http(s): a root-relative path is already right, and a\n // `mailto:`/`web5://`/protocol-relative url is not a catalog path at all.\n if (!/^https?:\\/\\//i.test(url)) {\n return url;\n }\n try {\n const parsed = new URL(url);\n // `?variant=…` is exactly how a resolved variant travels (DL #216), and\n // the hash can carry an anchor the answer meant — both survive.\n return parsed.pathname + parsed.search + parsed.hash;\n } catch {\n return url;\n }\n}\n\n/**\n * One entity row, normalized onto the `ApiPayloadItem` shape both resolution\n * paths key off.\n *\n * Two producers, one document. `list-items` answers with the raw retrieval\n * document; the turn answers with the engine's allowlisted projection of the\n * SAME document — same field names, plus the keys only a card reads (`type`,\n * `variantId`, and the matched child's `url`/`img`/`price` already overlaid).\n * Normalizing both here is what lets `findEntityInPayload` resolve a reference\n * without caring which one answered.\n *\n * `id` is what a `web5://entity/<type>/<id>` reference resolves against, and\n * the reference carries the DOCUMENT id — so `doc_id` becomes `id`, exactly as\n * the `list-items` path has always done. The fallback to a row's own `id` is\n * for the day a store publishes one (none does today); a row with neither has\n * nothing to be keyed by and is dropped.\n */\nexport function normalizeEntityItem(raw: unknown): ApiPayloadItem | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return null;\n }\n const rec = raw as Record<string, unknown>;\n const docId = typeof rec.doc_id === 'string' ? rec.doc_id : '';\n const ownId = typeof rec.id === 'string' ? rec.id : '';\n const id = docId || ownId;\n if (!id) {\n return null;\n }\n\n // Rows travel as-is apart from the `doc_id` → `id` alias every consumer keys\n // off, the origin reduction below, and the image alias after it.\n //\n // The url is never REBUILT — rebuilding the path from `handle` would throw\n // away the `?variant=…` that is exactly how a resolved variant travels.\n // `toCatalogPath` only drops the origin the index stamped; path, query and\n // hash are carried over verbatim.\n const normalized: Record<string, unknown> = { ...rec, id };\n\n if (typeof rec.url === 'string' && rec.url) {\n normalized.url = toCatalogPath(rec.url);\n }\n\n // Product rows carry the image as `thumbnail` / `images[]` (the Vespa doc\n // shape), but the shared transform (`transformToGenericEntityData`) reads\n // `img`. Alias it so product cards keep their image.\n //\n // A bridge, not a contract: a row that already carries `img` — a CMS doc, or\n // one where retrieval overlaid a matched child's presentation fields — passes\n // through untouched. Drop the alias once every producer emits `img`.\n if (normalized.img == null) {\n if (typeof rec.thumbnail === 'string' && rec.thumbnail) {\n normalized.img = rec.thumbnail;\n } else if (\n Array.isArray(rec.images) &&\n typeof rec.images[0] === 'string' &&\n rec.images[0]\n ) {\n normalized.img = rec.images[0];\n }\n }\n\n return normalized as unknown as ApiPayloadItem;\n}\n\n/**\n * Read an `{ items: [...] }` container into a normalized payload.\n *\n * Both carriers of the turn's resolved entities use that shape: the live\n * stream's `entities` frame (`TurnEntities.items`) and the persisted\n * `additional_data[\"documents\"]` the reload path reads back. A bare array is\n * accepted too, so a caller that already unwrapped one can pass it straight in.\n *\n * Anything that isn't a keyable row is dropped rather than passed on — a\n * payload entry with no id can only ever fail to match.\n */\nexport function entityPayloadFromItems(container: unknown): ApiPayloadItem[] {\n let items: unknown;\n if (Array.isArray(container)) {\n items = container;\n } else if (container && typeof container === 'object') {\n items = (container as { items?: unknown }).items;\n }\n if (!Array.isArray(items)) {\n return [];\n }\n\n const payload: ApiPayloadItem[] = [];\n for (const item of items) {\n const normalized = normalizeEntityItem(item);\n if (normalized) {\n payload.push(normalized);\n }\n }\n return payload;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/esm/entity/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { defaultExtractor } from './defaultExtractor.js';
|
|
2
2
|
export { defaultExtractor, transformToSolutionEntityData, transformToBlogPostEntityData, transformToGenericEntityData } from './defaultExtractor.js';
|
|
3
3
|
export { enrichEntitiesFromPayload } from './enrichEntitiesFromPayload.js';
|
|
4
|
-
export {
|
|
4
|
+
export { entityHref } from './entityHref.js';
|
|
5
|
+
export { normalizeEntityItem, entityPayloadFromItems, toCatalogPath } from './entityPayload.js';
|
|
5
6
|
export { isProductFamilyEntityType } from './entityFamily.js';
|
|
6
7
|
export { mergeEntityData } from './mergeEntityData.js';
|
|
7
8
|
export { toMatchedOptions, formatMoney, readCurrencyCode, formatPriceField, formatProductPriceLabel } from './matchedVariant.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["defaultExtractor","transformToSolutionEntityData","transformToBlogPostEntityData","transformToGenericEntityData","enrichEntitiesFromPayload","normalizeEntityItem","entityPayloadFromItems","isProductFamilyEntityType","mergeEntityData","toMatchedOptions","formatMoney","readCurrencyCode","formatPriceField","formatProductPriceLabel","fetchEntityListData","listEntityItems","LIST_ITEMS_ENDPOINT","extractorRegistry","getEntityExtractor","clientId","registerEntityExtractor","extractor"],"sources":["../../../src/entity/index.ts"],"sourcesContent":["import type { EntityExtractor } from './types';\nimport { defaultExtractor } from './defaultExtractor';\n\nexport {\n defaultExtractor,\n transformToSolutionEntityData,\n transformToBlogPostEntityData,\n transformToGenericEntityData,\n} from './defaultExtractor';\n\nexport { enrichEntitiesFromPayload } from './enrichEntitiesFromPayload';\nexport { normalizeEntityItem
|
|
1
|
+
{"version":3,"names":["defaultExtractor","transformToSolutionEntityData","transformToBlogPostEntityData","transformToGenericEntityData","enrichEntitiesFromPayload","entityHref","normalizeEntityItem","entityPayloadFromItems","toCatalogPath","isProductFamilyEntityType","mergeEntityData","toMatchedOptions","formatMoney","readCurrencyCode","formatPriceField","formatProductPriceLabel","fetchEntityListData","listEntityItems","LIST_ITEMS_ENDPOINT","extractorRegistry","getEntityExtractor","clientId","registerEntityExtractor","extractor"],"sources":["../../../src/entity/index.ts"],"sourcesContent":["import type { EntityExtractor } from './types';\nimport { defaultExtractor } from './defaultExtractor';\n\nexport {\n defaultExtractor,\n transformToSolutionEntityData,\n transformToBlogPostEntityData,\n transformToGenericEntityData,\n} from './defaultExtractor';\n\nexport { enrichEntitiesFromPayload } from './enrichEntitiesFromPayload';\nexport { entityHref } from './entityHref';\nexport {\n normalizeEntityItem,\n entityPayloadFromItems,\n toCatalogPath,\n} from './entityPayload';\nexport { isProductFamilyEntityType } from './entityFamily';\nexport { mergeEntityData } from './mergeEntityData';\nexport {\n toMatchedOptions,\n formatMoney,\n readCurrencyCode,\n formatPriceField,\n formatProductPriceLabel,\n type MatchedOption,\n type ProductPriceFields,\n} from './matchedVariant';\nexport {\n fetchEntityListData,\n type FetchEntityListDataOptions,\n} from './fetchEntityListData';\nexport {\n listEntityItems,\n LIST_ITEMS_ENDPOINT,\n type ListEntityItemsOptions,\n} from './listEntityItems';\n\nexport type { EntityExtractor } from './types';\n\n/**\n * Registry of client-specific entity extractors.\n * Only needed if a client requires custom extraction logic beyond the config-driven default.\n */\nconst extractorRegistry: Record<string, EntityExtractor> = {};\n\n/**\n * Get the entity extractor for a specific client.\n * The default extractor is config-driven and works for any client with entityConfig.\n */\nexport function getEntityExtractor(clientId?: string): EntityExtractor {\n if (clientId && extractorRegistry[clientId]) {\n return extractorRegistry[clientId];\n }\n return defaultExtractor;\n}\n\n/**\n * Register a custom entity extractor for a client\n * Useful for runtime registration or testing\n */\nexport function registerEntityExtractor(\n clientId: string,\n extractor: EntityExtractor,\n): void {\n extractorRegistry[clientId] = extractor;\n}\n"],"mappings":"AACA,SAASA,gBAAgB,QAAQ,oBAAoB;AAErD,SACEA,gBAAgB,EAChBC,6BAA6B,EAC7BC,6BAA6B,EAC7BC,4BAA4B,QACvB,oBAAoB;AAE3B,SAASC,yBAAyB,QAAQ,6BAA6B;AACvE,SAASC,UAAU,QAAQ,cAAc;AACzC,SACEC,mBAAmB,EACnBC,sBAAsB,EACtBC,aAAa,QACR,iBAAiB;AACxB,SAASC,yBAAyB,QAAQ,gBAAgB;AAC1D,SAASC,eAAe,QAAQ,mBAAmB;AACnD,SACEC,gBAAgB,EAChBC,WAAW,EACXC,gBAAgB,EAChBC,gBAAgB,EAChBC,uBAAuB,QAGlB,kBAAkB;AACzB,SACEC,mBAAmB,QAEd,uBAAuB;AAC9B,SACEC,eAAe,EACfC,mBAAmB,QAEd,mBAAmB;AAI1B;AACA;AACA;AACA;AACA,MAAMC,iBAAkD,GAAG,CAAC,CAAC;;AAE7D;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAACC,QAAiB,EAAmB;EACrE,IAAIA,QAAQ,IAAIF,iBAAiB,CAACE,QAAQ,CAAC,EAAE;IAC3C,OAAOF,iBAAiB,CAACE,QAAQ,CAAC;EACpC;EACA,OAAOrB,gBAAgB;AACzB;;AAEA;AACA;AACA;AACA;AACA,OAAO,SAASsB,uBAAuBA,CACrCD,QAAgB,EAChBE,SAA0B,EACpB;EACNJ,iBAAiB,CAACE,QAAQ,CAAC,GAAGE,SAAS;AACzC","ignoreList":[]}
|
package/dist/esm/index.js
CHANGED
|
@@ -59,7 +59,7 @@ export { ChipsProvider, useChips } from './context/ChipsContext.js';
|
|
|
59
59
|
|
|
60
60
|
// DI types
|
|
61
61
|
|
|
62
|
-
export { defaultExtractor, enrichEntitiesFromPayload, normalizeEntityItem, entityPayloadFromItems, mergeEntityData, fetchEntityListData, listEntityItems, LIST_ITEMS_ENDPOINT, getEntityExtractor, registerEntityExtractor, transformToSolutionEntityData, transformToBlogPostEntityData, transformToGenericEntityData, toMatchedOptions, formatMoney, readCurrencyCode, formatPriceField, formatProductPriceLabel, isProductFamilyEntityType } from './entity/index.js';
|
|
62
|
+
export { defaultExtractor, enrichEntitiesFromPayload, entityHref, normalizeEntityItem, toCatalogPath, entityPayloadFromItems, mergeEntityData, fetchEntityListData, listEntityItems, LIST_ITEMS_ENDPOINT, getEntityExtractor, registerEntityExtractor, transformToSolutionEntityData, transformToBlogPostEntityData, transformToGenericEntityData, toMatchedOptions, formatMoney, readCurrencyCode, formatPriceField, formatProductPriceLabel, isProductFamilyEntityType } from './entity/index.js';
|
|
63
63
|
export { CALLOUT_KINDS, CALLOUT_SEMANTICS } from './types/callout.js';
|
|
64
64
|
|
|
65
65
|
// Wrapper hooks
|