@juxtapose/core 0.8.0 → 0.9.0

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 (45) hide show
  1. package/dist/agent/handoff.d.ts +16 -0
  2. package/dist/agent/handoff.js +37 -2
  3. package/dist/agent/handoff.js.map +1 -1
  4. package/dist/analysis/affected.d.ts +17 -0
  5. package/dist/analysis/affected.js +34 -0
  6. package/dist/analysis/affected.js.map +1 -1
  7. package/dist/browser/flags.d.ts +14 -0
  8. package/dist/browser/flags.js +15 -0
  9. package/dist/browser/flags.js.map +1 -1
  10. package/dist/browser/page.d.ts +10 -0
  11. package/dist/browser/page.js +9 -3
  12. package/dist/browser/page.js.map +1 -1
  13. package/dist/capture/capture.d.ts +3 -1
  14. package/dist/capture/capture.js +81 -8
  15. package/dist/capture/capture.js.map +1 -1
  16. package/dist/capture/discover.d.ts +28 -0
  17. package/dist/capture/discover.js +109 -0
  18. package/dist/capture/discover.js.map +1 -0
  19. package/dist/capture/pool.d.ts +2 -0
  20. package/dist/capture/pool.js +1 -0
  21. package/dist/capture/pool.js.map +1 -1
  22. package/dist/capture/variants.d.ts +47 -0
  23. package/dist/capture/variants.js +192 -0
  24. package/dist/capture/variants.js.map +1 -0
  25. package/dist/diff/structural/deltas.d.ts +2 -3
  26. package/dist/diff/structural/deltas.js +3 -3
  27. package/dist/diff/structural/deltas.js.map +1 -1
  28. package/dist/index.d.ts +5 -3
  29. package/dist/index.js +6 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/platform.d.ts +20 -0
  32. package/dist/platforms/urls.js +5 -1
  33. package/dist/platforms/urls.js.map +1 -1
  34. package/dist/report/comment.js +19 -8
  35. package/dist/report/comment.js.map +1 -1
  36. package/dist/report/format.d.ts +17 -0
  37. package/dist/report/format.js +16 -0
  38. package/dist/report/format.js.map +1 -1
  39. package/dist/report/html.js +40 -6
  40. package/dist/report/html.js.map +1 -1
  41. package/dist/run/run.d.ts +2 -0
  42. package/dist/run/run.js +15 -0
  43. package/dist/run/run.js.map +1 -1
  44. package/dist/types.d.ts +47 -1
  45. package/package.json +1 -1
@@ -2,13 +2,18 @@
2
2
  // each step exists. Because pass/fail is a byte-exact hash, every source of
3
3
  // nondeterminism left in this path becomes a false failure somewhere.
4
4
  import sharp from 'sharp';
5
+ import { emulatedMedia } from '../browser/page.js';
5
6
  import { assertCssSelector } from '../browser/selectors.js';
6
7
  import { armSettle, drain, FREEZE_ANIMATIONS_CSS, waitForPaint, waitForSelector, } from './settle.js';
7
8
  import { captureStructure } from './structure.js';
9
+ import { deepEqual, mergeLiveParams, platformStoryId } from './variants.js';
8
10
  const DEFAULT_CAPTURE_TIMEOUT_MS = 2000;
9
11
  /** Per-page memo: skip work that only needs doing once per page. */
10
12
  const styleInjected = new WeakSet();
11
13
  const pageViewport = new WeakMap();
14
+ const pageColorScheme = new WeakMap();
15
+ /** The capture last shown on a page: its key and its platform story id. */
16
+ const pageCapture = new WeakMap();
12
17
  const warmPages = new WeakMap();
13
18
  export async function captureStory(page, story, deps, viewport) {
14
19
  const started = Date.now();
@@ -17,30 +22,67 @@ export async function captureStory(page, story, deps, viewport) {
17
22
  const params = { ...story.params };
18
23
  const effectiveViewport = params.viewport ?? viewport;
19
24
  const timeoutMs = params.captureTimeout ?? DEFAULT_CAPTURE_TIMEOUT_MS;
20
- const ctx = { story, params, timeoutMs };
25
+ // Every platform call gets the platform's own id; the variant capture key
26
+ // means nothing to Storybook or Ladle.
27
+ const id = platformStoryId(story);
28
+ const ctx = {
29
+ story: id === story.storyId ? story : { ...story, storyId: id },
30
+ params,
31
+ timeoutMs,
32
+ };
21
33
  // Selector syntax is validated before the page is touched: a Playwright-only
22
34
  // selector (`text=`, `>>`) would otherwise match nothing and the story would
23
35
  // be captured unmasked, or wait its whole timeout, and the baseline would
24
36
  // record the wrong thing. Live params are re-checked below.
25
37
  assertSelectors(params);
26
38
  await ensureViewport(page, effectiveViewport);
39
+ // Only a variant sets a scheme: a default capture resets to light, which is
40
+ // what stops a pooled page carrying a dark variant's scheme into the next
41
+ // story.
42
+ const scheme = story.variant !== undefined ? (params.colorScheme ?? 'light') : 'light';
27
43
  // Arm before triggering the render, or the observer misses the mutations it
28
44
  // exists to watch.
29
45
  //
30
46
  // A story that wants animations running can't reuse a page whose stylesheet
31
- // already froze them, so force the cold path for those.
47
+ // already froze them, so force the cold path for those. Likewise a scheme
48
+ // change: an app that reads matchMedia once at boot keeps the old scheme
49
+ // across a warm switch (measured: card then card__dark captured both light,
50
+ // the reverse both dark). Decided before the scheme is applied, against
51
+ // what the page booted under.
52
+ //
53
+ // And another capture of the same story (default -> mobile): the platform
54
+ // sees its story already rendered and "switches" without re-rendering, so
55
+ // the variant would be captured from the previous capture's layout.
56
+ const previous = pageCapture.get(page);
57
+ const sameStoryOtherCapture = previous !== undefined && previous.base === id && previous.key !== story.storyId;
58
+ const schemeChanged = pageColorScheme.has(page) && pageColorScheme.get(page) !== scheme;
32
59
  const warm = deps.warmSwitch === true &&
33
60
  warmPages.get(page) === deps.baseUrl &&
61
+ !schemeChanged &&
62
+ !sameStoryOtherCapture &&
34
63
  !(params.animations === 'play' && styleInjected.has(page));
64
+ // Before showStory, on every capture, so the story renders in its scheme
65
+ // from the first frame. Memoized, so it costs nothing when unchanged.
66
+ await ensureColorScheme(page, scheme);
67
+ // A variant shares its story's URL, and a URL differing only in its
68
+ // fragment is a same-document navigation: the cold path below would not
69
+ // reload, and an app that read the scheme at boot would keep the old one,
70
+ // or keep the previous capture's render. Blank the page so the story boots
71
+ // fresh.
72
+ if ((schemeChanged || sameStoryOtherCapture) && warmPages.has(page)) {
73
+ await page.goto('about:blank');
74
+ warmPages.delete(page);
75
+ }
76
+ pageCapture.set(page, { key: story.storyId, base: id });
35
77
  if (warm)
36
78
  await armSettle(page);
37
79
  const switched = warm && deps.platform.switchStory
38
- ? await deps.platform.switchStory(page, story.storyId, ctx)
80
+ ? await deps.platform.switchStory(page, id, ctx)
39
81
  : false;
40
82
  if (!switched) {
41
83
  // Delegated rather than built here: not every platform addresses a story
42
84
  // by URL. Playwright galleries render via window.mount() on a fixed page.
43
- await deps.platform.showStory(page, story.storyId, deps.baseUrl);
85
+ await deps.platform.showStory(page, id, deps.baseUrl);
44
86
  // A navigation discards injected style tags, so the freeze must be
45
87
  // re-applied for the next story that wants it.
46
88
  styleInjected.delete(page);
@@ -70,16 +112,25 @@ export async function captureStory(page, story, deps, viewport) {
70
112
  // waitForSelector and skip on that platform.
71
113
  //
72
114
  // Live params override manifest params — the live preview is the story's own
73
- // declaration, and the index is a lossy projection of it.
74
- const live = await deps.platform.readLiveParams?.(page, story.storyId);
115
+ // declaration, and the index is a lossy projection of it — but merge under
116
+ // a variant's own fields, so the mobile variant stays mobile.
117
+ const live = await deps.platform.readLiveParams?.(page, id);
75
118
  if (live) {
76
- Object.assign(params, live);
119
+ Object.assign(params, mergeLiveParams(story, live));
77
120
  assertSelectors(params);
121
+ // A story can opt out of a project variant in params only the live
122
+ // preview carries (Storybook). Honour it as a skip.
123
+ if (story.variant !== undefined && live.variants?.[story.variant] === false) {
124
+ return null;
125
+ }
126
+ if (story.variant !== undefined && liveOverrideDiffers(story, live)) {
127
+ deps.onWarning?.(`jux: ${story.storyId}: the story's live parameters declare variant '${story.variant}' differently from the settings it was captured with. Parameters read after render can't change which variants exist or what they set; declare variants in the story's parameters, where discovery reads them before capture.`);
128
+ }
78
129
  // Viewport is the one param that cannot be applied retroactively — the
79
130
  // story has already laid out. Re-set it and let the platform settle
80
131
  // again, so a story declaring its own viewport is captured at that size
81
132
  // rather than the project default.
82
- const liveViewport = live.viewport;
133
+ const liveViewport = params.viewport;
83
134
  if (liveViewport && !sameViewport(liveViewport, effectiveViewport)) {
84
135
  await ensureViewport(page, liveViewport);
85
136
  await deps.platform.settle(page, { ...ctx, params });
@@ -132,6 +183,8 @@ export async function captureStory(page, story, deps, viewport) {
132
183
  .toBuffer();
133
184
  return {
134
185
  storyId: story.storyId,
186
+ ...(story.baseStoryId !== undefined ? { baseStoryId: story.baseStoryId } : {}),
187
+ ...(story.variant !== undefined ? { variant: story.variant } : {}),
135
188
  image,
136
189
  // The live params may have widened or narrowed this after first render,
137
190
  // so report what we actually captured at — the agent handoff computes
@@ -142,6 +195,16 @@ export async function captureStory(page, story, deps, viewport) {
142
195
  ...(structure ? { structure } : {}),
143
196
  };
144
197
  }
198
+ /** Whether the live preview declares this variant with settings other than
199
+ * the ones it was expanded with: Storybook keeps story-level variants out of
200
+ * index.json, so they only surface here, after the capture set is fixed. */
201
+ function liveOverrideDiffers(story, live) {
202
+ const spec = story.variant !== undefined ? live.variants?.[story.variant] : undefined;
203
+ if (spec === undefined || spec === false || typeof spec !== 'object')
204
+ return false;
205
+ const expanded = story.variantParams ?? {};
206
+ return Object.entries(spec).some(([k, v]) => k !== 'extends' && !deepEqual(v, expanded[k]));
207
+ }
145
208
  const sameViewport = (a, b) => a.width === b.width && a.height === b.height;
146
209
  /** Setting the viewport is a CDP round-trip; skip it when nothing changed. */
147
210
  async function ensureViewport(page, viewport) {
@@ -151,6 +214,16 @@ async function ensureViewport(page, viewport) {
151
214
  await page.setViewportSize(viewport);
152
215
  pageViewport.set(page, key);
153
216
  }
217
+ /** Media emulation is a CDP round-trip too; skip it when nothing changed. */
218
+ async function ensureColorScheme(page, scheme) {
219
+ if (pageColorScheme.get(page) === scheme)
220
+ return;
221
+ if (page.setColorScheme)
222
+ await page.setColorScheme(scheme);
223
+ else
224
+ await page.send('Emulation.setEmulatedMedia', emulatedMedia(scheme));
225
+ pageColorScheme.set(page, scheme);
226
+ }
154
227
  /**
155
228
  * Inject the freeze stylesheet, once per page.
156
229
  *
@@ -1 +1 @@
1
- {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/capture/capture.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/capture/capture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { Browser } from '../browser/browser.js';
2
+ import type { EnumerateTarget, Platform } from '../platform.js';
3
+ import type { StoryManifest, VariantSpec, Viewport } from '../types.js';
4
+ export interface PrepareOptions {
5
+ platform: Platform;
6
+ browser: Browser;
7
+ baseUrl: string;
8
+ viewport: Viewport;
9
+ /** `ProjectConfig.variants`. */
10
+ projectVariants?: Record<string, VariantSpec | false>;
11
+ onWarning?: (message: string) => void;
12
+ timeoutMs?: number;
13
+ /** Keep discovered params on disk, keyed by the platform's
14
+ * `discoveryKey`, so an unchanged build skips the preview load. */
15
+ cache?: {
16
+ dir: string;
17
+ target: EnumerateTarget;
18
+ };
19
+ }
20
+ /**
21
+ * Merge the platform's discovered params over the enumerated ones. Never
22
+ * throws for discovery itself: a preview that can't be read costs the
23
+ * story-level settings the index lacks, which is today's behavior, and must
24
+ * not cost the run. Throws VariantConfigError from expansion.
25
+ */
26
+ export declare function discoverParams(stories: readonly StoryManifest[], opts: Omit<PrepareOptions, 'projectVariants'>): Promise<StoryManifest[]>;
27
+ /** Discover, then expand: one StoryManifest per capture. */
28
+ export declare function prepareCaptures(stories: readonly StoryManifest[], opts: PrepareOptions): Promise<StoryManifest[]>;
@@ -0,0 +1,109 @@
1
+ // Enumeration-time parameter discovery, then variant expansion: the step
2
+ // between "what stories exist" and "what captures to take".
3
+ //
4
+ // Lives in core so every caller that captures (jux run, jux init, the review
5
+ // server) builds the same capture set from the same inputs.
6
+ import { createHash } from 'node:crypto';
7
+ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
8
+ import path from 'node:path';
9
+ import { expandVariants } from './variants.js';
10
+ /** A preview that hasn't produced its parameters in this long is broken, not
11
+ * slow: the example's 17 stories take ~60 ms. */
12
+ const DISCOVER_TIMEOUT_MS = 30_000;
13
+ /** Bumped when the cached shape or what discovery reads changes. */
14
+ const CACHE_SCHEMA = 1;
15
+ const CACHE_FILE = 'discovered-params.json';
16
+ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
17
+ /**
18
+ * Merge the platform's discovered params over the enumerated ones. Never
19
+ * throws for discovery itself: a preview that can't be read costs the
20
+ * story-level settings the index lacks, which is today's behavior, and must
21
+ * not cost the run. Throws VariantConfigError from expansion.
22
+ */
23
+ export async function discoverParams(stories, opts) {
24
+ const discover = opts.platform.discoverParams?.bind(opts.platform);
25
+ if (!discover || stories.length === 0)
26
+ return [...stories];
27
+ const key = await cacheKey(opts);
28
+ const cached = key ? await readCache(opts.cache.dir, key) : undefined;
29
+ const found = cached ?? (await discoverLive(discover, opts));
30
+ if (!found)
31
+ return [...stories];
32
+ if (key && !cached)
33
+ await writeCache(opts.cache.dir, key, found);
34
+ return stories.map((s) => {
35
+ const params = found.get(s.storyId);
36
+ return isRecord(params) ? { ...s, params: { ...s.params, ...params } } : s;
37
+ });
38
+ }
39
+ /** One preview load; undefined (after a warning) when it can't be read. */
40
+ async function discoverLive(discover, opts) {
41
+ let found;
42
+ const context = await opts.browser.newContext({ viewport: opts.viewport });
43
+ let timer;
44
+ try {
45
+ const page = await context.newPage();
46
+ const timeoutMs = opts.timeoutMs ?? DISCOVER_TIMEOUT_MS;
47
+ found = await Promise.race([
48
+ discover(page, opts.baseUrl),
49
+ new Promise((_, reject) => {
50
+ timer = setTimeout(() => reject(new Error(`no answer within ${timeoutMs} ms`)), timeoutMs);
51
+ }),
52
+ ]);
53
+ }
54
+ catch (err) {
55
+ opts.onWarning?.(`jux: could not read story parameters from the ${opts.platform.name} preview (${err instanceof Error ? err.message : String(err)}); story-level settings and variants come from the index only`);
56
+ return undefined;
57
+ }
58
+ finally {
59
+ clearTimeout(timer);
60
+ await context.close().catch(() => { });
61
+ }
62
+ return found;
63
+ }
64
+ /** The platform's fingerprint of what it would discover from, salted with
65
+ * the platform and cache schema; undefined disables the cache. */
66
+ async function cacheKey(opts) {
67
+ if (!opts.cache || !opts.platform.discoveryKey)
68
+ return undefined;
69
+ try {
70
+ const key = await opts.platform.discoveryKey(opts.cache.target);
71
+ if (key === undefined)
72
+ return undefined;
73
+ return createHash('sha256')
74
+ .update(`${CACHE_SCHEMA}\0${opts.platform.name}\0${key}`)
75
+ .digest('hex');
76
+ }
77
+ catch {
78
+ return undefined;
79
+ }
80
+ }
81
+ /** A missing, unreadable or mismatched cache is a miss, never an error. */
82
+ async function readCache(dir, key) {
83
+ try {
84
+ const parsed = JSON.parse(await readFile(path.join(dir, CACHE_FILE), 'utf8'));
85
+ if (!isRecord(parsed) || parsed['key'] !== key || !isRecord(parsed['params']))
86
+ return undefined;
87
+ return new Map(Object.entries(parsed['params']));
88
+ }
89
+ catch {
90
+ return undefined;
91
+ }
92
+ }
93
+ /** Written atomically; a failed write costs the next run a discovery. */
94
+ async function writeCache(dir, key, found) {
95
+ try {
96
+ await mkdir(dir, { recursive: true });
97
+ const tmp = path.join(dir, `${CACHE_FILE}.${process.pid}.tmp`);
98
+ await writeFile(tmp, JSON.stringify({ key, params: Object.fromEntries(found) }) + '\n');
99
+ await rename(tmp, path.join(dir, CACHE_FILE));
100
+ }
101
+ catch {
102
+ // best effort
103
+ }
104
+ }
105
+ /** Discover, then expand: one StoryManifest per capture. */
106
+ export async function prepareCaptures(stories, opts) {
107
+ return expandVariants(await discoverParams(stories, opts), opts.projectVariants);
108
+ }
109
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/capture/discover.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,8 @@ export interface PoolOptions {
23
23
  /** Reuse warm pages and switch stories in place. Faster, but does not
24
24
  * currently reproduce cold-load pixels exactly — see CaptureDeps. */
25
25
  warmSwitch?: boolean;
26
+ /** Non-fatal notices from capture, e.g. an ignored live variant override. */
27
+ onWarning?: (message: string) => void;
26
28
  }
27
29
  export interface CaptureOutcome {
28
30
  story: StoryManifest;
@@ -62,6 +62,7 @@ export async function* capturePool(stories, opts) {
62
62
  platform: opts.platform,
63
63
  baseUrl: opts.baseUrl,
64
64
  warmSwitch: opts.warmSwitch,
65
+ ...(opts.onWarning ? { onWarning: opts.onWarning } : {}),
65
66
  };
66
67
  try {
67
68
  for (;;) {
@@ -1 +1 @@
1
- {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/capture/pool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/capture/pool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { StoryManifest, StoryParams, VariantSpec } from '../types.js';
2
+ /** Underscores are excluded so the `__` key separator can't occur in a name. */
3
+ export declare const VARIANT_NAME: RegExp;
4
+ export declare const VARIANT_SEPARATOR = "__";
5
+ /** A bad variant declaration. The CLI reports it and exits 2. */
6
+ export declare class VariantConfigError extends Error {
7
+ constructor(message: string);
8
+ }
9
+ export declare const captureKey: (baseStoryId: string, variant: string) => string;
10
+ /** The id every platform call receives: the platform's own, never the key. */
11
+ export declare const platformStoryId: (story: {
12
+ storyId: string;
13
+ baseStoryId?: string;
14
+ }) => string;
15
+ /**
16
+ * Expand each story into its default capture plus one entry per variant,
17
+ * sorted by capture key in code-unit order.
18
+ *
19
+ * Throws VariantConfigError on a bad name, a malformed spec, an unknown or
20
+ * cyclic `extends`, or two captures that would share a key.
21
+ */
22
+ export declare function expandVariants(stories: readonly StoryManifest[], projectVariants?: Record<string, VariantSpec | false>): StoryManifest[];
23
+ /**
24
+ * Merge live params (read from the rendered preview) for one capture.
25
+ *
26
+ * Live params override the manifest — the preview is the story's own
27
+ * declaration, the index a lossy projection of it — but they merge UNDER a
28
+ * variant's layer: a story's own live `viewport` must not undo the mobile
29
+ * variant's. `variants` and `colorScheme` in live params are declarations,
30
+ * not settings for this capture, so they are dropped.
31
+ */
32
+ export declare function mergeLiveParams(story: Pick<StoryManifest, 'params' | 'variantParams'>, live: StoryParams | undefined): StoryParams;
33
+ /**
34
+ * Pick items by story id: a base id selects the story and every variant of
35
+ * it, a capture key selects exactly that capture. Ids that match nothing are
36
+ * returned so the caller can report them.
37
+ */
38
+ export declare function selectByStoryId<T extends {
39
+ storyId: string;
40
+ baseStoryId?: string;
41
+ }>(items: readonly T[], ids: readonly string[]): {
42
+ selected: T[];
43
+ unknown: string[];
44
+ };
45
+ /** Structural equality for JSON-shaped values: key order doesn't matter,
46
+ * array order does. */
47
+ export declare function deepEqual(a: unknown, b: unknown): boolean;
@@ -0,0 +1,192 @@
1
+ // Per-story capture variants (spec 2026-10-13-variants-design.md).
2
+ //
3
+ // A variant is just another capture job: expansion happens once, after the
4
+ // platform enumerates, and everything downstream (pool, shuffle, warm browser,
5
+ // baselines, report) sees one StoryManifest per capture key. Pure on purpose:
6
+ // it does not care where a story's `variants` came from (index, meta.json, a
7
+ // url entry, or a preview extract), so a platform can change how it discovers
8
+ // them without touching this.
9
+ import { compareCodeUnits } from '../diff/structural/deltas.js';
10
+ /** Underscores are excluded so the `__` key separator can't occur in a name. */
11
+ export const VARIANT_NAME = /^[a-z0-9][a-z0-9-]{0,31}$/;
12
+ export const VARIANT_SEPARATOR = '__';
13
+ /** A bad variant declaration. The CLI reports it and exits 2. */
14
+ export class VariantConfigError extends Error {
15
+ constructor(message) {
16
+ super(`jux: ${message}`);
17
+ this.name = 'VariantConfigError';
18
+ }
19
+ }
20
+ export const captureKey = (baseStoryId, variant) => `${baseStoryId}${VARIANT_SEPARATOR}${variant}`;
21
+ /** The id every platform call receives: the platform's own, never the key. */
22
+ export const platformStoryId = (story) => story.baseStoryId ?? story.storyId;
23
+ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
24
+ /**
25
+ * Expand each story into its default capture plus one entry per variant,
26
+ * sorted by capture key in code-unit order.
27
+ *
28
+ * Throws VariantConfigError on a bad name, a malformed spec, an unknown or
29
+ * cyclic `extends`, or two captures that would share a key.
30
+ */
31
+ export function expandVariants(stories, projectVariants) {
32
+ const project = checkDeclared(projectVariants, 'project config');
33
+ const out = [];
34
+ for (const story of stories) {
35
+ // `variants` is a declaration, not a capture setting, and `colorScheme`
36
+ // is variant-only: the default capture is always light.
37
+ const { variants: ownRaw, colorScheme: _ignored, ...baseParams } = story.params;
38
+ out.push({ ...story, params: baseParams });
39
+ // A skipped story skips every variant: there is nothing to vary.
40
+ if (baseParams.skip === true)
41
+ continue;
42
+ const own = checkDeclared(ownRaw, `story '${story.storyId}'`);
43
+ // Story wins by name; `false` drops the name entirely.
44
+ const merged = new Map();
45
+ for (const [name, spec] of Object.entries(project)) {
46
+ if (spec !== false)
47
+ merged.set(name, spec);
48
+ }
49
+ for (const [name, spec] of Object.entries(own)) {
50
+ if (spec === false)
51
+ merged.delete(name);
52
+ else
53
+ merged.set(name, spec);
54
+ }
55
+ for (const name of [...merged.keys()].sort(compareCodeUnits)) {
56
+ const layer = resolveChain(story.storyId, name, merged);
57
+ out.push({
58
+ ...story,
59
+ storyId: captureKey(story.storyId, name),
60
+ baseStoryId: story.storyId,
61
+ variant: name,
62
+ variantParams: layer,
63
+ // Base params, then the extends chain, then the variant itself.
64
+ params: { ...baseParams, ...layer },
65
+ });
66
+ }
67
+ }
68
+ out.sort((a, b) => compareCodeUnits(a.storyId, b.storyId));
69
+ for (let i = 1; i < out.length; i++) {
70
+ const prev = out[i - 1];
71
+ const cur = out[i];
72
+ if (prev.storyId === cur.storyId) {
73
+ throw new VariantConfigError(`capture key '${cur.storyId}' is produced by both ${describe(prev)} and ${describe(cur)}; rename the variant or the story`);
74
+ }
75
+ }
76
+ return out;
77
+ }
78
+ const describe = (s) => s.variant === undefined
79
+ ? `story '${s.storyId}'`
80
+ : `story '${s.baseStoryId}' variant '${s.variant}'`;
81
+ /** Validate names and shapes where they are declared, before any merge, so
82
+ * the error names the place the user has to edit. */
83
+ function checkDeclared(raw, where) {
84
+ if (raw === undefined)
85
+ return {};
86
+ if (!isRecord(raw)) {
87
+ throw new VariantConfigError(`${where}: 'variants' must be an object of named variants`);
88
+ }
89
+ for (const [name, spec] of Object.entries(raw)) {
90
+ if (!VARIANT_NAME.test(name)) {
91
+ throw new VariantConfigError(`${where}: variant name '${name}' must match ${VARIANT_NAME.source} (lowercase letters, digits and dashes; no underscores)`);
92
+ }
93
+ if (spec === false)
94
+ continue;
95
+ if (!isRecord(spec)) {
96
+ throw new VariantConfigError(`${where}: variant '${name}' must be an object of capture settings, or false to opt out`);
97
+ }
98
+ if ('skip' in spec) {
99
+ throw new VariantConfigError(`${where}: variant '${name}' sets 'skip'; set the variant to false instead`);
100
+ }
101
+ const scheme = spec['colorScheme'];
102
+ if (scheme !== undefined && scheme !== 'light' && scheme !== 'dark') {
103
+ throw new VariantConfigError(`${where}: variant '${name}' colorScheme must be 'light' or 'dark'`);
104
+ }
105
+ const ext = spec['extends'];
106
+ if (ext !== undefined && typeof ext !== 'string') {
107
+ throw new VariantConfigError(`${where}: variant '${name}' extends must be a variant name`);
108
+ }
109
+ }
110
+ return raw;
111
+ }
112
+ /** The variant's own layer: its extends chain (farthest ancestor first),
113
+ * then the variant itself, with `extends` removed. */
114
+ function resolveChain(storyId, name, merged) {
115
+ const chain = [];
116
+ const seen = [];
117
+ let cur = name;
118
+ while (cur !== undefined) {
119
+ if (seen.includes(cur)) {
120
+ throw new VariantConfigError(`story '${storyId}' variant '${name}': extends cycle ${[...seen, cur].join(' -> ')}`);
121
+ }
122
+ seen.push(cur);
123
+ const spec = merged.get(cur);
124
+ if (!spec) {
125
+ // Only reachable for an ancestor: `name` itself came from `merged`.
126
+ throw new VariantConfigError(`story '${storyId}' variant '${seen[seen.length - 2]}' extends unknown variant '${cur}'`);
127
+ }
128
+ chain.unshift(spec);
129
+ cur = spec.extends;
130
+ }
131
+ const layer = {};
132
+ for (const spec of chain)
133
+ Object.assign(layer, spec);
134
+ delete layer.extends;
135
+ return layer;
136
+ }
137
+ /**
138
+ * Merge live params (read from the rendered preview) for one capture.
139
+ *
140
+ * Live params override the manifest — the preview is the story's own
141
+ * declaration, the index a lossy projection of it — but they merge UNDER a
142
+ * variant's layer: a story's own live `viewport` must not undo the mobile
143
+ * variant's. `variants` and `colorScheme` in live params are declarations,
144
+ * not settings for this capture, so they are dropped.
145
+ */
146
+ export function mergeLiveParams(story, live) {
147
+ const params = { ...story.params };
148
+ if (!live)
149
+ return params;
150
+ const { variants: _v, colorScheme: _c, ...settings } = live;
151
+ Object.assign(params, settings, story.variantParams ?? {});
152
+ return params;
153
+ }
154
+ /**
155
+ * Pick items by story id: a base id selects the story and every variant of
156
+ * it, a capture key selects exactly that capture. Ids that match nothing are
157
+ * returned so the caller can report them.
158
+ */
159
+ export function selectByStoryId(items, ids) {
160
+ const wanted = new Set(ids);
161
+ const hit = new Set();
162
+ const selected = items.filter((s) => {
163
+ if (wanted.has(s.storyId)) {
164
+ hit.add(s.storyId);
165
+ return true;
166
+ }
167
+ if (s.baseStoryId !== undefined && wanted.has(s.baseStoryId)) {
168
+ hit.add(s.baseStoryId);
169
+ return true;
170
+ }
171
+ return false;
172
+ });
173
+ return { selected, unknown: ids.filter((id) => !hit.has(id)) };
174
+ }
175
+ /** Structural equality for JSON-shaped values: key order doesn't matter,
176
+ * array order does. */
177
+ export function deepEqual(a, b) {
178
+ if (a === b)
179
+ return true;
180
+ if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)
181
+ return false;
182
+ if (Array.isArray(a) !== Array.isArray(b))
183
+ return false;
184
+ if (Array.isArray(a) && Array.isArray(b))
185
+ return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
186
+ const ra = a;
187
+ const rb = b;
188
+ const ka = Object.keys(ra);
189
+ return (ka.length === Object.keys(rb).length &&
190
+ ka.every((k) => Object.hasOwn(rb, k) && deepEqual(ra[k], rb[k])));
191
+ }
192
+ //# sourceMappingURL=variants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variants.js","sourceRoot":"","sources":["../../src/capture/variants.ts"],"names":[],"mappings":"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"}