@wix/web5-core 1.63.21 → 1.63.23

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.
Files changed (47) hide show
  1. package/dist/cjs/components/ui/OptimizedImage.js +12 -30
  2. package/dist/cjs/components/ui/OptimizedImage.js.map +1 -1
  3. package/dist/cjs/entity/entityHref.js +53 -0
  4. package/dist/cjs/entity/entityHref.js.map +1 -0
  5. package/dist/cjs/entity/entityPayload.js +58 -4
  6. package/dist/cjs/entity/entityPayload.js.map +1 -1
  7. package/dist/cjs/entity/index.js +5 -2
  8. package/dist/cjs/entity/index.js.map +1 -1
  9. package/dist/cjs/index.js +5 -16
  10. package/dist/cjs/index.js.map +1 -1
  11. package/dist/cjs/types/dependencies.js.map +1 -1
  12. package/dist/esm/components/ui/OptimizedImage.js +3 -21
  13. package/dist/esm/components/ui/OptimizedImage.js.map +1 -1
  14. package/dist/esm/entity/entityHref.js +49 -0
  15. package/dist/esm/entity/entityHref.js.map +1 -0
  16. package/dist/esm/entity/entityPayload.js +57 -4
  17. package/dist/esm/entity/entityPayload.js.map +1 -1
  18. package/dist/esm/entity/index.js +2 -1
  19. package/dist/esm/entity/index.js.map +1 -1
  20. package/dist/esm/index.js +1 -9
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/types/dependencies.js.map +1 -1
  23. package/dist/types/components/ui/OptimizedImage.d.ts +0 -12
  24. package/dist/types/components/ui/OptimizedImage.d.ts.map +1 -1
  25. package/dist/types/entity/entityHref.d.ts +39 -0
  26. package/dist/types/entity/entityHref.d.ts.map +1 -0
  27. package/dist/types/entity/entityPayload.d.ts +34 -0
  28. package/dist/types/entity/entityPayload.d.ts.map +1 -1
  29. package/dist/types/entity/index.d.ts +2 -1
  30. package/dist/types/entity/index.d.ts.map +1 -1
  31. package/dist/types/index.d.ts +1 -4
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/types/types/dependencies.d.ts +0 -15
  34. package/dist/types/types/dependencies.d.ts.map +1 -1
  35. package/package.json +2 -2
  36. package/dist/cjs/context/ImageSetContext.js +0 -234
  37. package/dist/cjs/context/ImageSetContext.js.map +0 -1
  38. package/dist/cjs/image/imageSetTypes.js +0 -108
  39. package/dist/cjs/image/imageSetTypes.js.map +0 -1
  40. package/dist/esm/context/ImageSetContext.js +0 -221
  41. package/dist/esm/context/ImageSetContext.js.map +0 -1
  42. package/dist/esm/image/imageSetTypes.js +0 -100
  43. package/dist/esm/image/imageSetTypes.js.map +0 -1
  44. package/dist/types/context/ImageSetContext.d.ts +0 -74
  45. package/dist/types/context/ImageSetContext.d.ts.map +0 -1
  46. package/dist/types/image/imageSetTypes.d.ts +0 -185
  47. package/dist/types/image/imageSetTypes.d.ts.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","createContext","useCallback","useContext","useEffect","useMemo","useRef","useState","MAX_IMAGE_SLOTS_PER_SET","IDLE_STATE","status","ImageSetContext","ImageSetProvider","_ref","resolveImageSet","preferredMode","turnId","maxSlots","children","pending","Map","states","listeners","Set","flushed","scheduled","notify","current","forEach","l","lastTurn","started","clear","flush","images","Array","from","values","length","result","bySlotId","slots","s","i","_images$i","id","slotId","set","req","slot","get","mode","register","_states$current$get2","_states$current$get","has","size","queueMicrotask","unregister","delete","stateOf","subscribe","listener","add","value","enabled","Boolean","createElement","Provider","useImageSlot","request","ctx","forceRender","undefined","n","kind","ratio","semantic","entityId","renderWidthPx","useImageSetEnabled","_useContext"],"sources":["../../../src/context/ImageSetContext.tsx"],"sourcesContent":["import React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type FC,\n type PropsWithChildren,\n} from 'react';\nimport {\n MAX_IMAGE_SLOTS_PER_SET,\n type ImageBackground,\n type ImageSlot,\n type ResolveImageSetResult,\n type ResolvedImageSlot,\n} from '../image/imageSetTypes';\n\n/**\n * The page-level image collector (ADR 0221).\n *\n * Sections declare slots; this provider resolves them together. That is the\n * whole point: a per-component call to a set-level endpoint is a one-slot\n * request, which throws away the page-wide assignment, the per-kind mode\n * negotiation and the cohesion that are the only reasons the endpoint takes a\n * list at all.\n *\n * The shape is deliberately one-shot per turn. Slots register during the\n * commit that renders them, the provider flushes once on the next microtask,\n * and a slot that registers after that flush does NOT trigger a second\n * request — it reports `late` and the caller falls back. A page that asks\n * twice cannot be coherent, so asking twice is not offered.\n */\n\ntype SlotStatus =\n /** No resolver available — the host did not supply one. */\n | 'unavailable'\n /** Registered, waiting for the flush or the response. */\n | 'pending'\n /** The response arrived and carried this slot. */\n | 'resolved'\n /** Registered after the set had already been sent; take the old path. */\n | 'late'\n /** The request failed. */\n | 'failed';\n\nexport interface ImageSlotState {\n status: SlotStatus;\n slot?: ResolvedImageSlot;\n /** The mode the whole set settled on, once known. */\n mode?: ImageBackground;\n}\n\ninterface ImageSetContextValue {\n register: (slot: ImageSlot) => void;\n unregister: (id: string) => void;\n stateOf: (id: string) => ImageSlotState;\n subscribe: (listener: () => void) => () => void;\n enabled: boolean;\n}\n\nconst IDLE_STATE: ImageSlotState = { status: 'unavailable' };\n\nconst ImageSetContext = createContext<ImageSetContextValue | null>(null);\n\nexport interface ImageSetProviderProps extends PropsWithChildren {\n /**\n * Resolves one set. Supplied by the host rather than called directly, so core\n * carries no transport: see `ComponentDependencies.resolveImageSet`.\n */\n resolveImageSet?: (input: {\n images: ImageSlot[];\n preferredMode?: ImageBackground;\n }) => Promise<ResolveImageSetResult>;\n /** Passed through as a tie-break term; never a gate (ADR 0197). */\n preferredMode?: ImageBackground;\n /**\n * Identifies the turn. Changing it starts a new set — the previous turn's\n * results are dropped and slots re-register. Without it the provider resolves\n * exactly once for its lifetime.\n */\n turnId?: string;\n /**\n * Slots beyond this many are refused with `late` rather than silently\n * dropped by the server. Defaults to the contract's own cap of 24.\n */\n maxSlots?: number;\n}\n\nexport const ImageSetProvider: FC<ImageSetProviderProps> = ({\n resolveImageSet,\n preferredMode,\n turnId,\n maxSlots = MAX_IMAGE_SLOTS_PER_SET,\n children,\n}) => {\n // Registration is refs, not state: a slot registering must not re-render the\n // whole tree mid-collection. Subscribers are notified explicitly once the\n // answer lands.\n const pending = useRef(new Map<string, ImageSlot>());\n const states = useRef(new Map<string, ImageSlotState>());\n const listeners = useRef(new Set<() => void>());\n const flushed = useRef(false);\n const scheduled = useRef(false);\n\n const notify = useCallback(() => {\n listeners.current.forEach((l) => l());\n }, []);\n\n // A new turn retires the previous set wholesale — and this MUST happen in the\n // render phase, not an effect. Child effects run before the parent's, so a\n // reset in `useEffect` would fire *after* this turn's slots had registered\n // and would wipe them, leaving the flush with nothing to send. The parent\n // renders first, so resetting here lands before any child registers.\n const lastTurn = useRef<string | undefined>(turnId);\n const started = useRef(false);\n if (!started.current) {\n started.current = true;\n } else if (lastTurn.current !== turnId) {\n lastTurn.current = turnId;\n pending.current.clear();\n states.current.clear();\n flushed.current = false;\n scheduled.current = false;\n }\n\n const flush = useCallback(async () => {\n scheduled.current = false;\n if (flushed.current || !resolveImageSet) {\n return;\n }\n const images = Array.from(pending.current.values());\n if (images.length === 0) {\n return;\n }\n // Everything registered before the flush goes in one request; the set is\n // closed the moment it is sent.\n flushed.current = true;\n\n try {\n const result = await resolveImageSet({ images, preferredMode });\n const bySlotId = new Map<string, ResolvedImageSlot>();\n // The contract guarantees same length and order, but keying by the echoed\n // slotId means a server that ever breaks that does not silently\n // mis-attribute someone else's photograph to this slot.\n (result.slots ?? []).forEach((s, i) => {\n const id = s.slotId || images[i]?.id;\n if (id) {\n bySlotId.set(id, s);\n }\n });\n images.forEach((req) => {\n const slot = bySlotId.get(req.id);\n states.current.set(req.id, {\n status: slot ? 'resolved' : 'failed',\n slot,\n mode: result.mode,\n });\n });\n } catch {\n // A failed set is not a broken page: every slot falls back to whatever it\n // rendered before.\n images.forEach((req) => {\n states.current.set(req.id, { status: 'failed' });\n });\n }\n notify();\n }, [resolveImageSet, preferredMode, notify]);\n\n const register = useCallback(\n (slot: ImageSlot) => {\n if (!resolveImageSet) {\n return;\n }\n if (flushed.current) {\n // The set has already gone. Say so rather than open a second one.\n if (states.current.get(slot.id)?.status !== 'resolved') {\n states.current.set(slot.id, { status: 'late' });\n notify();\n }\n return;\n }\n if (!pending.current.has(slot.id) && pending.current.size >= maxSlots) {\n states.current.set(slot.id, { status: 'late' });\n notify();\n return;\n }\n pending.current.set(slot.id, slot);\n if (states.current.get(slot.id)?.status !== 'resolved') {\n states.current.set(slot.id, { status: 'pending' });\n }\n if (!scheduled.current) {\n scheduled.current = true;\n // One microtask after the commit that declared the slots: late enough\n // that every section on the page has registered, early enough that the\n // request is in flight before paint.\n queueMicrotask(() => {\n void flush();\n });\n }\n },\n [resolveImageSet, maxSlots, flush, notify],\n );\n\n const unregister = useCallback((id: string) => {\n // Only meaningful before the flush; afterwards the set is immutable.\n if (!flushed.current) {\n pending.current.delete(id);\n states.current.delete(id);\n }\n }, []);\n\n const stateOf = useCallback(\n (id: string): ImageSlotState =>\n states.current.get(id) ??\n (resolveImageSet ? { status: 'pending' } : IDLE_STATE),\n [resolveImageSet],\n );\n\n const subscribe = useCallback((listener: () => void) => {\n listeners.current.add(listener);\n return () => {\n listeners.current.delete(listener);\n };\n }, []);\n\n const value = useMemo<ImageSetContextValue>(\n () => ({\n register,\n unregister,\n stateOf,\n subscribe,\n enabled: Boolean(resolveImageSet),\n }),\n [register, unregister, stateOf, subscribe, resolveImageSet],\n );\n\n return (\n <ImageSetContext.Provider value={value}>\n {children}\n </ImageSetContext.Provider>\n );\n};\n\n/**\n * Declare one image slot and read back what the page-wide resolution gave it.\n *\n * Returns `{ status: 'unavailable' }` when no provider or no resolver is\n * present — storybook, tests, a host that has not adopted this yet — so a\n * caller can render its existing image path unchanged in that case rather than\n * guard on the provider's existence.\n *\n * `request` is read on every render but only its identity matters for\n * re-registration, so callers should memoise it (or let its fields be stable).\n */\nexport function useImageSlot(request: ImageSlot | undefined): ImageSlotState {\n const ctx = useContext(ImageSetContext);\n const [, forceRender] = useState(0);\n\n const id = request?.id;\n\n // Subscribe BEFORE registering, and keep that order: registering can settle\n // this slot synchronously — a slot arriving after the set was already sent is\n // told `late` inside `register` itself — and a notification fired before this\n // component was listening would be lost, leaving it stuck on `pending`\n // forever. Effects run in declaration order, so this one wins.\n useEffect(() => {\n if (!ctx) {\n return undefined;\n }\n return ctx.subscribe(() => forceRender((n) => n + 1));\n }, [ctx]);\n\n useEffect(() => {\n if (!ctx || !request) {\n return undefined;\n }\n ctx.register(request);\n return () => ctx.unregister(request.id);\n // Registration is keyed on the slot's own content: a section that changes\n // what it is asking for re-declares, one that merely re-renders does not.\n }, [\n ctx,\n request?.id,\n request?.kind,\n request?.ratio,\n request?.semantic,\n request?.entityId,\n request?.renderWidthPx,\n ]);\n\n if (!ctx || !id) {\n return IDLE_STATE;\n }\n return ctx.stateOf(id);\n}\n\n/** True when a host has wired a resolver — i.e. slots will actually resolve. */\nexport function useImageSetEnabled(): boolean {\n return useContext(ImageSetContext)?.enabled ?? false;\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,100 +0,0 @@
1
- /**
2
- * The `ResolveImageSet` contract, as the client sees it.
3
- *
4
- * Mirrors `wix.enterprise.web_five.v1.ImageService/ResolveImageSet` (ADR 0143,
5
- * 0148, 0187, 0197, 0220). Declared here rather than imported from the
6
- * ambassador package so core carries no transport dependency: the host supplies
7
- * `ComponentDependencies.resolveImageSet` and owns the wire mapping, including
8
- * the fact that responses come back `preserving_proto_field_name`.
9
- *
10
- * String unions rather than enums so the values are exactly the wire's and no
11
- * runtime object ships with them.
12
- */
13
-
14
- /** How an image sits on its background. */
15
-
16
- /** What a slot is for, which decides what it may name and how it is scored. */
17
-
18
- /**
19
- * How honestly a slot's image answers what the slot asked for.
20
- *
21
- * Measured, and load-bearing: this is the ONLY field that separates a hit from
22
- * a miss. `score` cannot do it — a FALLBACK has been observed at 0.995 against
23
- * a correct EXACT at 0.86 in the same response — and neither field may be
24
- * compared across responses, because both are properties of the page-wide
25
- * assignment rather than of the slot. The same entity slot resolving to the
26
- * same image with a byte-identical crop has come back DEGRADED in one request
27
- * and EXACT in another, differing only in what else shared the page.
28
- */
29
-
30
- /** A crop in source pixels of the image the slot was given. */
31
-
32
- /** A box in normalised [0,1] coordinates — a fraction of the image's own size. */
33
-
34
- /** A square grid of per-cell values, `edge` on a side. */
35
-
36
- /**
37
- * The feature record the resolver already decoded for its own scoring, returned
38
- * rather than discarded (ADR 0187).
39
- */
40
-
41
- /** One slot a section declares. */
42
-
43
- /** The set's own cap — 24 slots per request, per the proto's `maxSize`. */
44
- export const MAX_IMAGE_SLOTS_PER_SET = 24;
45
-
46
- /** What the server substitutes for an absent or zero `renderWidthPx`. */
47
- export const DEFAULT_RENDER_WIDTH_PX = 800;
48
-
49
- /**
50
- * Above this, `MediaTransformUrl` refuses to compose the crop and returns the
51
- * uncropped original. Callers should clamp rather than let a device-pixel-ratio
52
- * multiplication carry them past it.
53
- */
54
- export const MAX_RENDER_WIDTH_PX = 5000;
55
-
56
- /** True when the slot carries a usable image (as opposed to a hole). */
57
- export function hasSlotImage(slot) {
58
- return Boolean(slot == null ? void 0 : slot.imageUrl);
59
- }
60
-
61
- /**
62
- * True when the slot's image actually depicts what the slot asked for.
63
- *
64
- * FALLBACK means the resolver had nothing for this subject and returned
65
- * something rather than a hole — legitimate for a decorative slot, wrong for
66
- * one captioned as a particular product.
67
- */
68
- export function isSubjectMatch(slot) {
69
- return (slot == null ? void 0 : slot.match) === 'IMAGE_MATCH_QUALITY_EXACT' || (slot == null ? void 0 : slot.match) === 'IMAGE_MATCH_QUALITY_DEGRADED';
70
- }
71
-
72
- /**
73
- * The colour to paint behind a `contain`-fitted image so its own backdrop does
74
- * not read as a rectangle against the surface. `backgroundColor` when the image
75
- * is SOLID, the dominant palette swatch otherwise, and `undefined` when neither
76
- * is known.
77
- */
78
- export function backdropColorOf(slot) {
79
- var _meta$palette;
80
- const meta = slot == null ? void 0 : slot.visualMetadata;
81
- if (!meta) {
82
- return undefined;
83
- }
84
- return meta.backgroundColor || ((_meta$palette = meta.palette) == null ? void 0 : _meta$palette.dominant) || undefined;
85
- }
86
-
87
- /**
88
- * The aspect ratio to render `imageUrl` at. Normally the slot's requested
89
- * ratio, but a contained crop (ADR 0220) deliberately returns another, and the
90
- * URL's own `fill/w_,h_` carries that one — so honouring `crop.ratio` is what
91
- * keeps the picture undistorted.
92
- */
93
- export function renderRatioOf(slot, requestedRatio) {
94
- const crop = slot == null ? void 0 : slot.crop;
95
- if (crop != null && crop.contained && crop.ratio && crop.ratio > 0) {
96
- return crop.ratio;
97
- }
98
- return requestedRatio;
99
- }
100
- //# sourceMappingURL=imageSetTypes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["MAX_IMAGE_SLOTS_PER_SET","DEFAULT_RENDER_WIDTH_PX","MAX_RENDER_WIDTH_PX","hasSlotImage","slot","Boolean","imageUrl","isSubjectMatch","match","backdropColorOf","_meta$palette","meta","visualMetadata","undefined","backgroundColor","palette","dominant","renderRatioOf","requestedRatio","crop","contained","ratio"],"sources":["../../../src/image/imageSetTypes.ts"],"sourcesContent":["/**\n * The `ResolveImageSet` contract, as the client sees it.\n *\n * Mirrors `wix.enterprise.web_five.v1.ImageService/ResolveImageSet` (ADR 0143,\n * 0148, 0187, 0197, 0220). Declared here rather than imported from the\n * ambassador package so core carries no transport dependency: the host supplies\n * `ComponentDependencies.resolveImageSet` and owns the wire mapping, including\n * the fact that responses come back `preserving_proto_field_name`.\n *\n * String unions rather than enums so the values are exactly the wire's and no\n * runtime object ships with them.\n */\n\n/** How an image sits on its background. */\nexport type ImageBackground =\n | 'IMAGE_BACKGROUND_UNSPECIFIED'\n /** Cut out — no background of its own. */\n | 'IMAGE_BACKGROUND_TRANSPARENT'\n /** One flat colour behind the subject; `backgroundColor` is then non-empty. */\n | 'IMAGE_BACKGROUND_SOLID'\n /** A scene: the background is part of the picture, and has no one colour. */\n | 'IMAGE_BACKGROUND_MIXED';\n\n/** What a slot is for, which decides what it may name and how it is scored. */\nexport type ImageSlotKind =\n | 'IMAGE_SLOT_KIND_UNSPECIFIED'\n /** Presents one entity — names it via `entityId`. */\n | 'IMAGE_SLOT_KIND_ENTITY'\n /** Illustrates a section — names what it is about via `semantic`. */\n | 'IMAGE_SLOT_KIND_EDITORIAL';\n\n/**\n * How honestly a slot's image answers what the slot asked for.\n *\n * Measured, and load-bearing: this is the ONLY field that separates a hit from\n * a miss. `score` cannot do it — a FALLBACK has been observed at 0.995 against\n * a correct EXACT at 0.86 in the same response — and neither field may be\n * compared across responses, because both are properties of the page-wide\n * assignment rather than of the slot. The same entity slot resolving to the\n * same image with a byte-identical crop has come back DEGRADED in one request\n * and EXACT in another, differing only in what else shared the page.\n */\nexport type ImageMatchQuality =\n | 'IMAGE_MATCH_QUALITY_UNSPECIFIED'\n /** The slot's own image, and one it would have chosen. */\n | 'IMAGE_MATCH_QUALITY_EXACT'\n /** The slot's own subject, but a compromise on fit, framing or mode. */\n | 'IMAGE_MATCH_QUALITY_DEGRADED'\n /** Not the slot's subject — something rather than a hole. */\n | 'IMAGE_MATCH_QUALITY_FALLBACK';\n\n/** A crop in source pixels of the image the slot was given. */\nexport interface ImageCrop {\n x: number;\n y: number;\n width: number;\n height: number;\n /** Fraction of the detected subject the crop discards, 0..1. */\n subjectLoss: number;\n /**\n * This crop's own aspect ratio. Equal to the slot's requested `ratio` unless\n * `contained` is true.\n */\n ratio?: number;\n /**\n * True when the crop deliberately does not match the requested ratio, to keep\n * the whole subject in frame rather than cut it (ADR 0220). Only possible on\n * a SOLID image, so `backgroundColor` is guaranteed non-empty alongside it.\n * Render at `crop.ratio`, centred, and pad the rest with `backgroundColor`.\n */\n contained?: boolean;\n}\n\n/** A box in normalised [0,1] coordinates — a fraction of the image's own size. */\nexport interface ImageRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nexport interface ImagePalette {\n dominant: string;\n swatches: string[];\n}\n\n/** A square grid of per-cell values, `edge` on a side. */\nexport interface ImageStatGrid {\n edge: number;\n cells: number[];\n}\n\n/**\n * The feature record the resolver already decoded for its own scoring, returned\n * rather than discarded (ADR 0187).\n */\nexport interface ImageVisualMetadata {\n width: number;\n height: number;\n background: ImageBackground;\n /**\n * Flat backdrop colour. Non-empty exactly when `background` is SOLID — a\n * scene has no one backdrop colour, so a MIXED image carries `''` here and a\n * renderer wanting a colour should fall back to `palette.dominant`.\n */\n backgroundColor: string;\n subject?: ImageRect;\n palette?: ImagePalette;\n luma?: ImageStatGrid;\n variance?: ImageStatGrid;\n /** Reserved for the VLM label tier; empty until it ships. */\n labels: string[];\n}\n\n/** One slot a section declares. */\nexport interface ImageSlot {\n /** Caller's name for this slot, echoed back as `slotId`. Unique per request. */\n id: string;\n kind: ImageSlotKind;\n /** Width divided by height of the hole to fill. Must be positive. */\n ratio: number;\n /** EDITORIAL slots name what the section is about. */\n semantic?: string;\n /**\n * ENTITY slots name the entity. This is the row's **bare external id** (e.g.\n * `gid://shopify/Product/123`), never the prefixed `doc_id` (`product:...`) —\n * an image's `parent_id` is stamped with the former. Getting it wrong does\n * not error; the slot silently returns an unrelated image at FALLBACK.\n */\n entityId?: string;\n /**\n * Width the slot renders at. Omitted, the server substitutes 800. A value\n * ABOVE 5000 is the dangerous one: the crop is then dropped from the URL and\n * the uncropped original comes back with a `crop` beside it that nothing\n * applied, with no error.\n */\n renderWidthPx?: number;\n}\n\nexport interface ResolvedImageSlot {\n slotId: string;\n /** Empty when the set could fill no image for this slot. */\n imageUrl?: string;\n /** How to crop `imageUrl` — already composed into the URL by the server. */\n crop?: ImageCrop;\n match?: ImageMatchQuality;\n score?: number;\n visualMetadata?: ImageVisualMetadata;\n}\n\nexport interface ResolveImageSetInput {\n /**\n * The mode the page would prefer. A term, never a gate (ADR 0197): the set\n * settles on whichever mode its best assignment uses. Measured returning\n * MIXED for an explicit SOLID, and SOLID when unset.\n */\n preferredMode?: ImageBackground;\n images: ImageSlot[];\n}\n\nexport interface ResolveImageSetResult {\n mode?: ImageBackground;\n /** Same length and order as the request's `images`; never a hole. */\n slots: ResolvedImageSlot[];\n}\n\n/** The set's own cap — 24 slots per request, per the proto's `maxSize`. */\nexport const MAX_IMAGE_SLOTS_PER_SET = 24;\n\n/** What the server substitutes for an absent or zero `renderWidthPx`. */\nexport const DEFAULT_RENDER_WIDTH_PX = 800;\n\n/**\n * Above this, `MediaTransformUrl` refuses to compose the crop and returns the\n * uncropped original. Callers should clamp rather than let a device-pixel-ratio\n * multiplication carry them past it.\n */\nexport const MAX_RENDER_WIDTH_PX = 5000;\n\n/** True when the slot carries a usable image (as opposed to a hole). */\nexport function hasSlotImage(slot: ResolvedImageSlot | undefined): boolean {\n return Boolean(slot?.imageUrl);\n}\n\n/**\n * True when the slot's image actually depicts what the slot asked for.\n *\n * FALLBACK means the resolver had nothing for this subject and returned\n * something rather than a hole — legitimate for a decorative slot, wrong for\n * one captioned as a particular product.\n */\nexport function isSubjectMatch(slot: ResolvedImageSlot | undefined): boolean {\n return (\n slot?.match === 'IMAGE_MATCH_QUALITY_EXACT' ||\n slot?.match === 'IMAGE_MATCH_QUALITY_DEGRADED'\n );\n}\n\n/**\n * The colour to paint behind a `contain`-fitted image so its own backdrop does\n * not read as a rectangle against the surface. `backgroundColor` when the image\n * is SOLID, the dominant palette swatch otherwise, and `undefined` when neither\n * is known.\n */\nexport function backdropColorOf(\n slot: ResolvedImageSlot | undefined,\n): string | undefined {\n const meta = slot?.visualMetadata;\n if (!meta) {\n return undefined;\n }\n return meta.backgroundColor || meta.palette?.dominant || undefined;\n}\n\n/**\n * The aspect ratio to render `imageUrl` at. Normally the slot's requested\n * ratio, but a contained crop (ADR 0220) deliberately returns another, and the\n * URL's own `fill/w_,h_` carries that one — so honouring `crop.ratio` is what\n * keeps the picture undistorted.\n */\nexport function renderRatioOf(\n slot: ResolvedImageSlot | undefined,\n requestedRatio: number,\n): number {\n const crop = slot?.crop;\n if (crop?.contained && crop.ratio && crop.ratio > 0) {\n return crop.ratio;\n }\n return requestedRatio;\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAUA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA;;AAsBA;;AAaA;;AAMA;AACA;AACA;AACA;;AAmBA;;AAoDA;AACA,OAAO,MAAMA,uBAAuB,GAAG,EAAE;;AAEzC;AACA,OAAO,MAAMC,uBAAuB,GAAG,GAAG;;AAE1C;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,mBAAmB,GAAG,IAAI;;AAEvC;AACA,OAAO,SAASC,YAAYA,CAACC,IAAmC,EAAW;EACzE,OAAOC,OAAO,CAACD,IAAI,oBAAJA,IAAI,CAAEE,QAAQ,CAAC;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,cAAcA,CAACH,IAAmC,EAAW;EAC3E,OACE,CAAAA,IAAI,oBAAJA,IAAI,CAAEI,KAAK,MAAK,2BAA2B,IAC3C,CAAAJ,IAAI,oBAAJA,IAAI,CAAEI,KAAK,MAAK,8BAA8B;AAElD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BL,IAAmC,EACf;EAAA,IAAAM,aAAA;EACpB,MAAMC,IAAI,GAAGP,IAAI,oBAAJA,IAAI,CAAEQ,cAAc;EACjC,IAAI,CAACD,IAAI,EAAE;IACT,OAAOE,SAAS;EAClB;EACA,OAAOF,IAAI,CAACG,eAAe,MAAAJ,aAAA,GAAIC,IAAI,CAACI,OAAO,qBAAZL,aAAA,CAAcM,QAAQ,KAAIH,SAAS;AACpE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASI,aAAaA,CAC3Bb,IAAmC,EACnCc,cAAsB,EACd;EACR,MAAMC,IAAI,GAAGf,IAAI,oBAAJA,IAAI,CAAEe,IAAI;EACvB,IAAIA,IAAI,YAAJA,IAAI,CAAEC,SAAS,IAAID,IAAI,CAACE,KAAK,IAAIF,IAAI,CAACE,KAAK,GAAG,CAAC,EAAE;IACnD,OAAOF,IAAI,CAACE,KAAK;EACnB;EACA,OAAOH,cAAc;AACvB","ignoreList":[]}
@@ -1,74 +0,0 @@
1
- import { type FC, type PropsWithChildren } from 'react';
2
- import { type ImageBackground, type ImageSlot, type ResolveImageSetResult, type ResolvedImageSlot } from '../image/imageSetTypes';
3
- /**
4
- * The page-level image collector (ADR 0221).
5
- *
6
- * Sections declare slots; this provider resolves them together. That is the
7
- * whole point: a per-component call to a set-level endpoint is a one-slot
8
- * request, which throws away the page-wide assignment, the per-kind mode
9
- * negotiation and the cohesion that are the only reasons the endpoint takes a
10
- * list at all.
11
- *
12
- * The shape is deliberately one-shot per turn. Slots register during the
13
- * commit that renders them, the provider flushes once on the next microtask,
14
- * and a slot that registers after that flush does NOT trigger a second
15
- * request — it reports `late` and the caller falls back. A page that asks
16
- * twice cannot be coherent, so asking twice is not offered.
17
- */
18
- type SlotStatus =
19
- /** No resolver available — the host did not supply one. */
20
- 'unavailable'
21
- /** Registered, waiting for the flush or the response. */
22
- | 'pending'
23
- /** The response arrived and carried this slot. */
24
- | 'resolved'
25
- /** Registered after the set had already been sent; take the old path. */
26
- | 'late'
27
- /** The request failed. */
28
- | 'failed';
29
- export interface ImageSlotState {
30
- status: SlotStatus;
31
- slot?: ResolvedImageSlot;
32
- /** The mode the whole set settled on, once known. */
33
- mode?: ImageBackground;
34
- }
35
- export interface ImageSetProviderProps extends PropsWithChildren {
36
- /**
37
- * Resolves one set. Supplied by the host rather than called directly, so core
38
- * carries no transport: see `ComponentDependencies.resolveImageSet`.
39
- */
40
- resolveImageSet?: (input: {
41
- images: ImageSlot[];
42
- preferredMode?: ImageBackground;
43
- }) => Promise<ResolveImageSetResult>;
44
- /** Passed through as a tie-break term; never a gate (ADR 0197). */
45
- preferredMode?: ImageBackground;
46
- /**
47
- * Identifies the turn. Changing it starts a new set — the previous turn's
48
- * results are dropped and slots re-register. Without it the provider resolves
49
- * exactly once for its lifetime.
50
- */
51
- turnId?: string;
52
- /**
53
- * Slots beyond this many are refused with `late` rather than silently
54
- * dropped by the server. Defaults to the contract's own cap of 24.
55
- */
56
- maxSlots?: number;
57
- }
58
- export declare const ImageSetProvider: FC<ImageSetProviderProps>;
59
- /**
60
- * Declare one image slot and read back what the page-wide resolution gave it.
61
- *
62
- * Returns `{ status: 'unavailable' }` when no provider or no resolver is
63
- * present — storybook, tests, a host that has not adopted this yet — so a
64
- * caller can render its existing image path unchanged in that case rather than
65
- * guard on the provider's existence.
66
- *
67
- * `request` is read on every render but only its identity matters for
68
- * re-registration, so callers should memoise it (or let its fields be stable).
69
- */
70
- export declare function useImageSlot(request: ImageSlot | undefined): ImageSlotState;
71
- /** True when a host has wired a resolver — i.e. slots will actually resolve. */
72
- export declare function useImageSetEnabled(): boolean;
73
- export {};
74
- //# sourceMappingURL=ImageSetContext.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ImageSetContext.d.ts","sourceRoot":"","sources":["../../../src/context/ImageSetContext.tsx"],"names":[],"mappings":"AAAA,OAAc,EAQZ,KAAK,EAAE,EACP,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;;;;;;;;;GAcG;AAEH,KAAK,UAAU;AACb,2DAA2D;AACzD,aAAa;AACf,yDAAyD;GACvD,SAAS;AACX,kDAAkD;GAChD,UAAU;AACZ,yEAAyE;GACvE,MAAM;AACR,0BAA0B;GACxB,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,qDAAqD;IACrD,IAAI,CAAC,EAAE,eAAe,CAAC;CACxB;AAcD,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QACxB,MAAM,EAAE,SAAS,EAAE,CAAC;QACpB,aAAa,CAAC,EAAE,eAAe,CAAC;KACjC,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACrC,mEAAmE;IACnE,aAAa,CAAC,EAAE,eAAe,CAAC;IAChC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,gBAAgB,EAAE,EAAE,CAAC,qBAAqB,CAyJtD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,cAAc,CAwC3E;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C"}
@@ -1,185 +0,0 @@
1
- /**
2
- * The `ResolveImageSet` contract, as the client sees it.
3
- *
4
- * Mirrors `wix.enterprise.web_five.v1.ImageService/ResolveImageSet` (ADR 0143,
5
- * 0148, 0187, 0197, 0220). Declared here rather than imported from the
6
- * ambassador package so core carries no transport dependency: the host supplies
7
- * `ComponentDependencies.resolveImageSet` and owns the wire mapping, including
8
- * the fact that responses come back `preserving_proto_field_name`.
9
- *
10
- * String unions rather than enums so the values are exactly the wire's and no
11
- * runtime object ships with them.
12
- */
13
- /** How an image sits on its background. */
14
- export type ImageBackground = 'IMAGE_BACKGROUND_UNSPECIFIED'
15
- /** Cut out — no background of its own. */
16
- | 'IMAGE_BACKGROUND_TRANSPARENT'
17
- /** One flat colour behind the subject; `backgroundColor` is then non-empty. */
18
- | 'IMAGE_BACKGROUND_SOLID'
19
- /** A scene: the background is part of the picture, and has no one colour. */
20
- | 'IMAGE_BACKGROUND_MIXED';
21
- /** What a slot is for, which decides what it may name and how it is scored. */
22
- export type ImageSlotKind = 'IMAGE_SLOT_KIND_UNSPECIFIED'
23
- /** Presents one entity — names it via `entityId`. */
24
- | 'IMAGE_SLOT_KIND_ENTITY'
25
- /** Illustrates a section — names what it is about via `semantic`. */
26
- | 'IMAGE_SLOT_KIND_EDITORIAL';
27
- /**
28
- * How honestly a slot's image answers what the slot asked for.
29
- *
30
- * Measured, and load-bearing: this is the ONLY field that separates a hit from
31
- * a miss. `score` cannot do it — a FALLBACK has been observed at 0.995 against
32
- * a correct EXACT at 0.86 in the same response — and neither field may be
33
- * compared across responses, because both are properties of the page-wide
34
- * assignment rather than of the slot. The same entity slot resolving to the
35
- * same image with a byte-identical crop has come back DEGRADED in one request
36
- * and EXACT in another, differing only in what else shared the page.
37
- */
38
- export type ImageMatchQuality = 'IMAGE_MATCH_QUALITY_UNSPECIFIED'
39
- /** The slot's own image, and one it would have chosen. */
40
- | 'IMAGE_MATCH_QUALITY_EXACT'
41
- /** The slot's own subject, but a compromise on fit, framing or mode. */
42
- | 'IMAGE_MATCH_QUALITY_DEGRADED'
43
- /** Not the slot's subject — something rather than a hole. */
44
- | 'IMAGE_MATCH_QUALITY_FALLBACK';
45
- /** A crop in source pixels of the image the slot was given. */
46
- export interface ImageCrop {
47
- x: number;
48
- y: number;
49
- width: number;
50
- height: number;
51
- /** Fraction of the detected subject the crop discards, 0..1. */
52
- subjectLoss: number;
53
- /**
54
- * This crop's own aspect ratio. Equal to the slot's requested `ratio` unless
55
- * `contained` is true.
56
- */
57
- ratio?: number;
58
- /**
59
- * True when the crop deliberately does not match the requested ratio, to keep
60
- * the whole subject in frame rather than cut it (ADR 0220). Only possible on
61
- * a SOLID image, so `backgroundColor` is guaranteed non-empty alongside it.
62
- * Render at `crop.ratio`, centred, and pad the rest with `backgroundColor`.
63
- */
64
- contained?: boolean;
65
- }
66
- /** A box in normalised [0,1] coordinates — a fraction of the image's own size. */
67
- export interface ImageRect {
68
- x: number;
69
- y: number;
70
- width: number;
71
- height: number;
72
- }
73
- export interface ImagePalette {
74
- dominant: string;
75
- swatches: string[];
76
- }
77
- /** A square grid of per-cell values, `edge` on a side. */
78
- export interface ImageStatGrid {
79
- edge: number;
80
- cells: number[];
81
- }
82
- /**
83
- * The feature record the resolver already decoded for its own scoring, returned
84
- * rather than discarded (ADR 0187).
85
- */
86
- export interface ImageVisualMetadata {
87
- width: number;
88
- height: number;
89
- background: ImageBackground;
90
- /**
91
- * Flat backdrop colour. Non-empty exactly when `background` is SOLID — a
92
- * scene has no one backdrop colour, so a MIXED image carries `''` here and a
93
- * renderer wanting a colour should fall back to `palette.dominant`.
94
- */
95
- backgroundColor: string;
96
- subject?: ImageRect;
97
- palette?: ImagePalette;
98
- luma?: ImageStatGrid;
99
- variance?: ImageStatGrid;
100
- /** Reserved for the VLM label tier; empty until it ships. */
101
- labels: string[];
102
- }
103
- /** One slot a section declares. */
104
- export interface ImageSlot {
105
- /** Caller's name for this slot, echoed back as `slotId`. Unique per request. */
106
- id: string;
107
- kind: ImageSlotKind;
108
- /** Width divided by height of the hole to fill. Must be positive. */
109
- ratio: number;
110
- /** EDITORIAL slots name what the section is about. */
111
- semantic?: string;
112
- /**
113
- * ENTITY slots name the entity. This is the row's **bare external id** (e.g.
114
- * `gid://shopify/Product/123`), never the prefixed `doc_id` (`product:...`) —
115
- * an image's `parent_id` is stamped with the former. Getting it wrong does
116
- * not error; the slot silently returns an unrelated image at FALLBACK.
117
- */
118
- entityId?: string;
119
- /**
120
- * Width the slot renders at. Omitted, the server substitutes 800. A value
121
- * ABOVE 5000 is the dangerous one: the crop is then dropped from the URL and
122
- * the uncropped original comes back with a `crop` beside it that nothing
123
- * applied, with no error.
124
- */
125
- renderWidthPx?: number;
126
- }
127
- export interface ResolvedImageSlot {
128
- slotId: string;
129
- /** Empty when the set could fill no image for this slot. */
130
- imageUrl?: string;
131
- /** How to crop `imageUrl` — already composed into the URL by the server. */
132
- crop?: ImageCrop;
133
- match?: ImageMatchQuality;
134
- score?: number;
135
- visualMetadata?: ImageVisualMetadata;
136
- }
137
- export interface ResolveImageSetInput {
138
- /**
139
- * The mode the page would prefer. A term, never a gate (ADR 0197): the set
140
- * settles on whichever mode its best assignment uses. Measured returning
141
- * MIXED for an explicit SOLID, and SOLID when unset.
142
- */
143
- preferredMode?: ImageBackground;
144
- images: ImageSlot[];
145
- }
146
- export interface ResolveImageSetResult {
147
- mode?: ImageBackground;
148
- /** Same length and order as the request's `images`; never a hole. */
149
- slots: ResolvedImageSlot[];
150
- }
151
- /** The set's own cap — 24 slots per request, per the proto's `maxSize`. */
152
- export declare const MAX_IMAGE_SLOTS_PER_SET = 24;
153
- /** What the server substitutes for an absent or zero `renderWidthPx`. */
154
- export declare const DEFAULT_RENDER_WIDTH_PX = 800;
155
- /**
156
- * Above this, `MediaTransformUrl` refuses to compose the crop and returns the
157
- * uncropped original. Callers should clamp rather than let a device-pixel-ratio
158
- * multiplication carry them past it.
159
- */
160
- export declare const MAX_RENDER_WIDTH_PX = 5000;
161
- /** True when the slot carries a usable image (as opposed to a hole). */
162
- export declare function hasSlotImage(slot: ResolvedImageSlot | undefined): boolean;
163
- /**
164
- * True when the slot's image actually depicts what the slot asked for.
165
- *
166
- * FALLBACK means the resolver had nothing for this subject and returned
167
- * something rather than a hole — legitimate for a decorative slot, wrong for
168
- * one captioned as a particular product.
169
- */
170
- export declare function isSubjectMatch(slot: ResolvedImageSlot | undefined): boolean;
171
- /**
172
- * The colour to paint behind a `contain`-fitted image so its own backdrop does
173
- * not read as a rectangle against the surface. `backgroundColor` when the image
174
- * is SOLID, the dominant palette swatch otherwise, and `undefined` when neither
175
- * is known.
176
- */
177
- export declare function backdropColorOf(slot: ResolvedImageSlot | undefined): string | undefined;
178
- /**
179
- * The aspect ratio to render `imageUrl` at. Normally the slot's requested
180
- * ratio, but a contained crop (ADR 0220) deliberately returns another, and the
181
- * URL's own `fill/w_,h_` carries that one — so honouring `crop.ratio` is what
182
- * keeps the picture undistorted.
183
- */
184
- export declare function renderRatioOf(slot: ResolvedImageSlot | undefined, requestedRatio: number): number;
185
- //# sourceMappingURL=imageSetTypes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"imageSetTypes.d.ts","sourceRoot":"","sources":["../../../src/image/imageSetTypes.ts"],"names":[],"mappings":"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"}