@contentful/experiences-sdk-core 0.8.4 → 0.8.5

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.8.5 (2026-09-22)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **live-preview:** accept payloads without viewports [SPA-5272] ([6db6fa7](https://github.com/contentful/experiences/commit/6db6fa7))
6
+
1
7
  ## 0.8.4 (2026-09-21)
2
8
 
3
9
  ### 🚀 Features
package/dist/types.d.ts CHANGED
@@ -27,6 +27,10 @@ interface ExperienceContext {
27
27
  * crosses server/client boundaries.
28
28
  */
29
29
  metadata: Record<string, unknown>;
30
+ /**
31
+ * @deprecated Viewports are being removed from the Experiences APIs. Design
32
+ * property values arrive flat. Will not be removed before 2026-10-06.
33
+ */
30
34
  viewports: ViewportDef[];
31
35
  }
32
36
  /**
@@ -36,9 +40,20 @@ interface ExperienceContext {
36
40
  * this same type and a field added here reaches all three at once.
37
41
  */
38
42
  interface RenderContext extends ExperienceContext {
43
+ /**
44
+ * @deprecated Viewport state is being removed from the Experiences APIs.
45
+ * Will not be removed before 2026-10-06.
46
+ */
39
47
  activeViewport: ViewportDef;
48
+ /**
49
+ * @deprecated Viewport state is being removed from the Experiences APIs.
50
+ * Will not be removed before 2026-10-06.
51
+ */
40
52
  activeViewportIndex: number;
41
- /** Mirrors `PortableRenderPlan.fallbackViewportIndex`. */
53
+ /**
54
+ * @deprecated Viewport state is being removed from the Experiences APIs.
55
+ * Will not be removed before 2026-10-06.
56
+ */
42
57
  fallbackViewportIndex: number;
43
58
  }
44
59
  /**
@@ -198,7 +213,7 @@ interface ExperienceSourceMap {
198
213
  interface ExperiencePayload {
199
214
  /**
200
215
  * @deprecated Absent once the API stops sending `viewports`. `resolveExperience`
201
- * defaults to `[]` when this is missing.
216
+ * defaults to `[]` when this is missing. Will not be removed before 2026-10-06.
202
217
  */
203
218
  viewports?: ViewportDef[];
204
219
  nodes: ExperienceNode[];
@@ -265,7 +280,10 @@ interface PortableRenderNode {
265
280
  /** Flat, viewport-cascaded, token-resolved design values (server-side). */
266
281
  design: Record<string, unknown>;
267
282
  resolved?: Record<string, unknown>;
268
- /** Raw per-viewport design, for client re-resolution on viewport change. */
283
+ /**
284
+ * @deprecated Design property values are becoming flat. Will not be
285
+ * removed before 2026-10-06.
286
+ */
269
287
  designRaw: Record<string, DesignPropValue>;
270
288
  };
271
289
  /**
@@ -286,12 +304,15 @@ interface PortableRenderNode {
286
304
  * is no plan-level template concept — see `PortableRegistration`.
287
305
  */
288
306
  interface PortableRenderPlan {
307
+ /**
308
+ * @deprecated Viewports are being removed from the Experiences APIs. Design
309
+ * property values arrive flat. Will not be removed before 2026-10-06.
310
+ */
289
311
  viewports: ViewportDef[];
290
312
  nodes: PortableRenderNode[];
291
313
  /**
292
- * Viewport index the server pre-resolved design against (viewport[0] by
293
- * default). Adapters use `props.design` as-is when their active viewport
294
- * matches this, and recompute from `props.designRaw` otherwise.
314
+ * @deprecated Viewport state is being removed from the Experiences APIs.
315
+ * Will not be removed before 2026-10-06.
295
316
  */
296
317
  fallbackViewportIndex: number;
297
318
  /**
@@ -18,7 +18,14 @@ declare function getViewportIndex(viewports: ViewportDef[], viewportId?: string)
18
18
  * 2026-10-06.
19
19
  */
20
20
  declare function getValueForViewport(prop: DesignPropValue | undefined, viewports: ViewportDef[], activeViewportIndex: number): string | number | boolean | DesignToken | undefined;
21
- /** Resolve every design property on a node into a flat record keyed by name. */
21
+ /**
22
+ * Resolve every design property on a node into a flat record keyed by name.
23
+ *
24
+ * NOTE: once viewports are removed from the Experiences APIs, every design
25
+ * property value arrives already flat, so the `viewports` and
26
+ * `activeViewportIndex` parameters will be dropped. Will not happen before
27
+ * 2026-10-06.
28
+ */
22
29
  declare function resolveDesignProperties(designProperties: Record<string, DesignPropValue> | undefined, viewports: ViewportDef[], activeViewportIndex: number): Record<string, string | number | boolean | DesignToken>;
23
30
  /**
24
31
  * Resolve `DesignToken` values via `resolveToken`; scalars pass through.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/viewport.ts"],"sourcesContent":["/*\n * Viewport math + design-property resolution. Lives in core (not design) so the\n * resolve pipeline can pre-resolve design props server-side; the design package\n * re-exports these, so its public API is unchanged.\n *\n * Viewport order encodes cascade direction (desktop-first descends by width,\n * mobile-first ascends). The \"active viewport\" is the last-matching media query;\n * `getValueForViewport` walks backwards from it to viewport[0] and returns the\n * first defined value, matching CSS cascade behavior.\n */\n\nimport type {\n DesignPropValue,\n DesignToken,\n ManualDesignValue,\n ResolveToken,\n ValuesByViewport,\n ViewportDef,\n} from './types.js';\n\n/**\n * Viewport id → index. Returns 0 (the wildcard viewport) when unknown.\n *\n * @deprecated Viewports are being removed from the Experiences APIs. No\n * customer action is needed: design property values arrive flat, so this\n * resolution step is skipped automatically. Will not be removed before\n * 2026-10-06.\n */\nexport function getViewportIndex(viewports: ViewportDef[], viewportId?: string): number {\n if (!viewportId) return 0;\n const index = viewports.findIndex((v) => v.id === viewportId);\n return index === -1 ? 0 : index;\n}\n\n// ManualDesignValue → its scalar; DesignToken → passed through (resolved later).\nfunction unwrapInner(\n inner: ManualDesignValue | DesignToken | undefined\n): string | number | boolean | DesignToken | undefined {\n if (!inner) return undefined;\n if (inner.type === 'ManualDesignValue') return inner.value;\n return inner;\n}\n\n// Cascade-lookup: walk back from activeViewportIndex to viewport[0], first defined wins.\nfunction resolveValuesByViewport(\n valuesByViewport: ValuesByViewport,\n viewports: ViewportDef[],\n activeViewportIndex: number\n): ManualDesignValue | DesignToken | undefined {\n for (let i = activeViewportIndex; i >= 0; i--) {\n const viewport = viewports[i];\n if (!viewport) continue;\n const candidate = valuesByViewport.values[viewport.id];\n if (candidate !== undefined && candidate !== null) return candidate;\n }\n return undefined;\n}\n\n/**\n * Resolve one design property to its render-time value (cascade + unwrap).\n *\n * @deprecated Viewports are being removed from the Experiences APIs. No\n * customer action is needed: flat values already return early here, so this\n * cascade step is skipped automatically. Will not be removed before\n * 2026-10-06.\n */\nexport function getValueForViewport(\n prop: DesignPropValue | undefined,\n viewports: ViewportDef[],\n activeViewportIndex: number\n): string | number | boolean | DesignToken | undefined {\n if (!prop) return undefined;\n if (prop.type === 'ManualDesignValue') return prop.value;\n if (prop.type === 'DesignToken') return prop;\n return unwrapInner(resolveValuesByViewport(prop, viewports, activeViewportIndex));\n}\n\n/** Resolve every design property on a node into a flat record keyed by name. */\nexport function resolveDesignProperties(\n designProperties: Record<string, DesignPropValue> | undefined,\n viewports: ViewportDef[],\n activeViewportIndex: number\n): Record<string, string | number | boolean | DesignToken> {\n const out: Record<string, string | number | boolean | DesignToken> = {};\n if (!designProperties) return out;\n for (const [key, prop] of Object.entries(designProperties)) {\n const value = getValueForViewport(prop, viewports, activeViewportIndex);\n if (value !== undefined) out[key] = value;\n }\n return out;\n}\n\n/**\n * Resolve `DesignToken` values via `resolveToken`; scalars pass through.\n * Keys that don't resolve — no `resolveToken` configured, or the resolver\n * returns `undefined` for that particular token — pass through as the raw\n * `DesignToken` and their id is collected in `unresolved` for the caller to\n * warn/diagnose (see `warnUnresolvedTokens` in `resolve-experience.ts`, which\n * already dedupes per `resolveExperience()` call, so this function carries\n * no warn-once state of its own).\n */\nexport function applyTokenResolver(\n props: Record<string, string | number | boolean | DesignToken>,\n resolveToken?: ResolveToken\n): { props: Record<string, unknown>; unresolved: string[] } {\n const out: Record<string, unknown> = {};\n const unresolved: string[] = [];\n for (const [key, value] of Object.entries(props)) {\n if (typeof value === 'object' && value !== null && value.type === 'DesignToken') {\n const resolved = resolveToken?.(value);\n if (resolved === undefined) {\n out[key] = value;\n unresolved.push(value.value);\n continue;\n }\n out[key] = resolved;\n continue;\n }\n out[key] = value;\n }\n return { props: out, unresolved };\n}\n"],"mappings":"AA4BO,SAAS,iBAAiB,WAA0B,YAA6B;AACtF,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,QAAQ,UAAU,UAAU,CAAC,MAAM,EAAE,OAAO,UAAU;AAC5D,SAAO,UAAU,KAAK,IAAI;AAC5B;AAGA,SAAS,YACP,OACqD;AACrD,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,SAAS,oBAAqB,QAAO,MAAM;AACrD,SAAO;AACT;AAGA,SAAS,wBACP,kBACA,WACA,qBAC6C;AAC7C,WAAS,IAAI,qBAAqB,KAAK,GAAG,KAAK;AAC7C,UAAM,WAAW,UAAU,CAAC;AAC5B,QAAI,CAAC,SAAU;AACf,UAAM,YAAY,iBAAiB,OAAO,SAAS,EAAE;AACrD,QAAI,cAAc,UAAa,cAAc,KAAM,QAAO;AAAA,EAC5D;AACA,SAAO;AACT;AAUO,SAAS,oBACd,MACA,WACA,qBACqD;AACrD,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,KAAK,SAAS,oBAAqB,QAAO,KAAK;AACnD,MAAI,KAAK,SAAS,cAAe,QAAO;AACxC,SAAO,YAAY,wBAAwB,MAAM,WAAW,mBAAmB,CAAC;AAClF;AAGO,SAAS,wBACd,kBACA,WACA,qBACyD;AACzD,QAAM,MAA+D,CAAC;AACtE,MAAI,CAAC,iBAAkB,QAAO;AAC9B,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,gBAAgB,GAAG;AAC1D,UAAM,QAAQ,oBAAoB,MAAM,WAAW,mBAAmB;AACtE,QAAI,UAAU,OAAW,KAAI,GAAG,IAAI;AAAA,EACtC;AACA,SAAO;AACT;AAWO,SAAS,mBACd,OACA,cAC0D;AAC1D,QAAM,MAA+B,CAAC;AACtC,QAAM,aAAuB,CAAC;AAC9B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,SAAS,eAAe;AAC/E,YAAM,WAAW,eAAe,KAAK;AACrC,UAAI,aAAa,QAAW;AAC1B,YAAI,GAAG,IAAI;AACX,mBAAW,KAAK,MAAM,KAAK;AAC3B;AAAA,MACF;AACA,UAAI,GAAG,IAAI;AACX;AAAA,IACF;AACA,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO,EAAE,OAAO,KAAK,WAAW;AAClC;","names":[]}
1
+ {"version":3,"sources":["../src/viewport.ts"],"sourcesContent":["/*\n * Viewport math + design-property resolution. Lives in core (not design) so the\n * resolve pipeline can pre-resolve design props server-side; the design package\n * re-exports these, so its public API is unchanged.\n *\n * Viewport order encodes cascade direction (desktop-first descends by width,\n * mobile-first ascends). The \"active viewport\" is the last-matching media query;\n * `getValueForViewport` walks backwards from it to viewport[0] and returns the\n * first defined value, matching CSS cascade behavior.\n */\n\nimport type {\n DesignPropValue,\n DesignToken,\n ManualDesignValue,\n ResolveToken,\n ValuesByViewport,\n ViewportDef,\n} from './types.js';\n\n/**\n * Viewport id → index. Returns 0 (the wildcard viewport) when unknown.\n *\n * @deprecated Viewports are being removed from the Experiences APIs. No\n * customer action is needed: design property values arrive flat, so this\n * resolution step is skipped automatically. Will not be removed before\n * 2026-10-06.\n */\nexport function getViewportIndex(viewports: ViewportDef[], viewportId?: string): number {\n if (!viewportId) return 0;\n const index = viewports.findIndex((v) => v.id === viewportId);\n return index === -1 ? 0 : index;\n}\n\n// ManualDesignValue → its scalar; DesignToken → passed through (resolved later).\nfunction unwrapInner(\n inner: ManualDesignValue | DesignToken | undefined\n): string | number | boolean | DesignToken | undefined {\n if (!inner) return undefined;\n if (inner.type === 'ManualDesignValue') return inner.value;\n return inner;\n}\n\n// Cascade-lookup: walk back from activeViewportIndex to viewport[0], first defined wins.\nfunction resolveValuesByViewport(\n valuesByViewport: ValuesByViewport,\n viewports: ViewportDef[],\n activeViewportIndex: number\n): ManualDesignValue | DesignToken | undefined {\n for (let i = activeViewportIndex; i >= 0; i--) {\n const viewport = viewports[i];\n if (!viewport) continue;\n const candidate = valuesByViewport.values[viewport.id];\n if (candidate !== undefined && candidate !== null) return candidate;\n }\n return undefined;\n}\n\n/**\n * Resolve one design property to its render-time value (cascade + unwrap).\n *\n * @deprecated Viewports are being removed from the Experiences APIs. No\n * customer action is needed: flat values already return early here, so this\n * cascade step is skipped automatically. Will not be removed before\n * 2026-10-06.\n */\nexport function getValueForViewport(\n prop: DesignPropValue | undefined,\n viewports: ViewportDef[],\n activeViewportIndex: number\n): string | number | boolean | DesignToken | undefined {\n if (!prop) return undefined;\n if (prop.type === 'ManualDesignValue') return prop.value;\n if (prop.type === 'DesignToken') return prop;\n return unwrapInner(resolveValuesByViewport(prop, viewports, activeViewportIndex));\n}\n\n/**\n * Resolve every design property on a node into a flat record keyed by name.\n *\n * NOTE: once viewports are removed from the Experiences APIs, every design\n * property value arrives already flat, so the `viewports` and\n * `activeViewportIndex` parameters will be dropped. Will not happen before\n * 2026-10-06.\n */\nexport function resolveDesignProperties(\n designProperties: Record<string, DesignPropValue> | undefined,\n viewports: ViewportDef[],\n activeViewportIndex: number\n): Record<string, string | number | boolean | DesignToken> {\n const out: Record<string, string | number | boolean | DesignToken> = {};\n if (!designProperties) return out;\n for (const [key, prop] of Object.entries(designProperties)) {\n const value = getValueForViewport(prop, viewports, activeViewportIndex);\n if (value !== undefined) out[key] = value;\n }\n return out;\n}\n\n/**\n * Resolve `DesignToken` values via `resolveToken`; scalars pass through.\n * Keys that don't resolve — no `resolveToken` configured, or the resolver\n * returns `undefined` for that particular token — pass through as the raw\n * `DesignToken` and their id is collected in `unresolved` for the caller to\n * warn/diagnose (see `warnUnresolvedTokens` in `resolve-experience.ts`, which\n * already dedupes per `resolveExperience()` call, so this function carries\n * no warn-once state of its own).\n */\nexport function applyTokenResolver(\n props: Record<string, string | number | boolean | DesignToken>,\n resolveToken?: ResolveToken\n): { props: Record<string, unknown>; unresolved: string[] } {\n const out: Record<string, unknown> = {};\n const unresolved: string[] = [];\n for (const [key, value] of Object.entries(props)) {\n if (typeof value === 'object' && value !== null && value.type === 'DesignToken') {\n const resolved = resolveToken?.(value);\n if (resolved === undefined) {\n out[key] = value;\n unresolved.push(value.value);\n continue;\n }\n out[key] = resolved;\n continue;\n }\n out[key] = value;\n }\n return { props: out, unresolved };\n}\n"],"mappings":"AA4BO,SAAS,iBAAiB,WAA0B,YAA6B;AACtF,MAAI,CAAC,WAAY,QAAO;AACxB,QAAM,QAAQ,UAAU,UAAU,CAAC,MAAM,EAAE,OAAO,UAAU;AAC5D,SAAO,UAAU,KAAK,IAAI;AAC5B;AAGA,SAAS,YACP,OACqD;AACrD,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,SAAS,oBAAqB,QAAO,MAAM;AACrD,SAAO;AACT;AAGA,SAAS,wBACP,kBACA,WACA,qBAC6C;AAC7C,WAAS,IAAI,qBAAqB,KAAK,GAAG,KAAK;AAC7C,UAAM,WAAW,UAAU,CAAC;AAC5B,QAAI,CAAC,SAAU;AACf,UAAM,YAAY,iBAAiB,OAAO,SAAS,EAAE;AACrD,QAAI,cAAc,UAAa,cAAc,KAAM,QAAO;AAAA,EAC5D;AACA,SAAO;AACT;AAUO,SAAS,oBACd,MACA,WACA,qBACqD;AACrD,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,KAAK,SAAS,oBAAqB,QAAO,KAAK;AACnD,MAAI,KAAK,SAAS,cAAe,QAAO;AACxC,SAAO,YAAY,wBAAwB,MAAM,WAAW,mBAAmB,CAAC;AAClF;AAUO,SAAS,wBACd,kBACA,WACA,qBACyD;AACzD,QAAM,MAA+D,CAAC;AACtE,MAAI,CAAC,iBAAkB,QAAO;AAC9B,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,gBAAgB,GAAG;AAC1D,UAAM,QAAQ,oBAAoB,MAAM,WAAW,mBAAmB;AACtE,QAAI,UAAU,OAAW,KAAI,GAAG,IAAI;AAAA,EACtC;AACA,SAAO;AACT;AAWO,SAAS,mBACd,OACA,cAC0D;AAC1D,QAAM,MAA+B,CAAC;AACtC,QAAM,aAAuB,CAAC;AAC9B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,SAAS,eAAe;AAC/E,YAAM,WAAW,eAAe,KAAK;AACrC,UAAI,aAAa,QAAW;AAC1B,YAAI,GAAG,IAAI;AACX,mBAAW,KAAK,MAAM,KAAK;AAC3B;AAAA,MACF;AACA,UAAI,GAAG,IAAI;AACX;AAAA,IACF;AACA,QAAI,GAAG,IAAI;AAAA,EACb;AACA,SAAO,EAAE,OAAO,KAAK,WAAW;AAClC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experiences-sdk-core",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Runtime-neutral types + experience resolution for Contentful Experiences",
5
5
  "license": "MIT",
6
6
  "type": "module",