@kiwa-test/component 0.3.0 → 0.4.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.
- package/dist/index.cjs +172 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +55 -4
- package/dist/index.d.ts +55 -4
- package/dist/index.js +163 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dom.ts","../src/storybook.ts","../src/playwright-ct.ts","../src/chromatic.ts","../src/fixture.ts","../src/semantics/types.ts","../src/semantics/rsc-harness.ts","../src/semantics/streaming-ssr.ts","../src/semantics/view-transitions.ts","../src/semantics/form-action-advanced.ts","../src/semantics/fidelity.ts","../src/real-driver.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { CanvasElement, MockEvent, MockNode } from './types.js';\n\n/**\n * MockNode + CanvasElement の生成 / traversal / event 発火 helper 群。\n *\n * 実 DOM (jsdom / happy-dom) を使わない理由 = (1) Storybook 8 / Playwright CT /\n * Chromatic の 3 統合 mock で共通の抽象を提供したい、 (2) framework agnostic\n * (React / Vue / Svelte / Solid) にする、 (3) test 速度と決定性を最優先する。\n *\n * MockNode tree は tag / attrs / text / children で表現、 実 DOM の subset を\n * 網羅する (querySelector 相当の tag / .class / #id / attr selector、 getByText、\n * getByRole)。 fill / click は event handler を synchronously 呼ぶ。\n */\n\n/** node factory — attrs / children / text / value を任意で与える。 */\nexport function createNode(tag: string, options: NodeOptions = {}): MockNode {\n const node: MockNode = {\n tag,\n attrs: options.attrs ?? {},\n children: [],\n handlers: {},\n parent: null,\n ...(options.text !== undefined ? { text: options.text } : {}),\n ...(options.value !== undefined ? { value: options.value } : {}),\n };\n for (const child of options.children ?? []) {\n appendChild(node, child);\n }\n if (options.on) {\n for (const [event, handler] of Object.entries(options.on)) {\n addHandler(node, event, handler);\n }\n }\n return node;\n}\n\nexport interface NodeOptions {\n attrs?: Record<string, string>;\n text?: string;\n value?: string;\n children?: MockNode[];\n on?: Record<string, (event: MockEvent) => void>;\n}\n\n/** node に child を追加、 parent back reference も更新する。 */\nexport function appendChild(parent: MockNode, child: MockNode): void {\n parent.children.push(child);\n child.parent = parent;\n}\n\n/** event handler を登録、 同一 event に複数 handler を許容する。 */\nexport function addHandler(node: MockNode, event: string, handler: (event: MockEvent) => void): void {\n if (!node.handlers[event]) {\n node.handlers[event] = [];\n }\n node.handlers[event].push(handler);\n}\n\n/**\n * event を発火する。 実 DOM のような bubble はせず target 単発、 mock harness\n * では component 側で bubble 相当を実装する。 fill 相当は input event を発火。\n */\nexport function fireEvent(node: MockNode, event: MockEvent): void {\n const handlers = node.handlers[event.type];\n if (!handlers) return;\n for (const handler of handlers) {\n handler(event);\n }\n}\n\n/**\n * CanvasElement 生成 — root node と lookup helpers を wrap する。 mount 完了後\n * story / component test / visual capture の全経路で使う。\n */\nexport function createCanvas(root: MockNode): CanvasElement {\n return {\n root,\n getByText: (text: string) => {\n const found = findByText(root, text);\n if (!found) {\n throw new Error(`Canvas.getByText — no node with text ${JSON.stringify(text)}`);\n }\n return found;\n },\n getByRole: (role: string, options?: { name?: string }) => {\n const found = findByRole(root, role, options?.name);\n if (!found) {\n const nameSuffix = options?.name ? ` name=${JSON.stringify(options.name)}` : '';\n throw new Error(`Canvas.getByRole — no node with role=${role}${nameSuffix}`);\n }\n return found;\n },\n querySelector: (selector: string) => query(root, selector, false)[0] ?? null,\n querySelectorAll: (selector: string) => query(root, selector, true),\n toMarkup: () => renderMarkup(root),\n };\n}\n\n/**\n * MockNode subtree を deterministic な pseudo-HTML 文字列に変換する。\n * event handler は含めず、 tag / attrs / text / children のみ。\n * Chromatic の hash / markup 保存に使う。\n */\nexport function renderMarkup(node: MockNode): string {\n const attrs = Object.entries(node.attrs)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => ` ${k}=${JSON.stringify(v)}`)\n .join('');\n const valueAttr =\n node.value !== undefined ? ` value=${JSON.stringify(node.value)}` : '';\n const openTag = `<${node.tag}${attrs}${valueAttr}>`;\n const inner = [\n node.text ?? '',\n ...node.children.map(renderMarkup),\n ].join('');\n return `${openTag}${inner}</${node.tag}>`;\n}\n\n/** markup 文字列を deterministic SHA-256 hex substring (先頭 16) に変換。 */\nexport function hashMarkup(markup: string): string {\n return createHash('sha256').update(markup).digest('hex').slice(0, 16);\n}\n\n/**\n * text 一致で最初に見つかった node を返す。 深い node を優先する — root 側の\n * aggregated text ではなく、 実際に text を持つ leaf 相当の node を先に返す\n * (Storybook / Testing Library の getByText 挙動と揃える)。\n */\nexport function findByText(node: MockNode, text: string): MockNode | null {\n for (const child of node.children) {\n const found = findByText(child, text);\n if (found) return found;\n }\n if (nodeText(node) === text) return node;\n return null;\n}\n\n/**\n * role 属性 (`role=\"button\"`) or implicit role (button tag) と、 aria-label /\n * text で一致する node を返す。 mock は最小 subset (button / link / heading /\n * textbox / checkbox) のみ。\n */\nexport function findByRole(node: MockNode, role: string, accessibleName?: string): MockNode | null {\n const implicit = implicitRole(node);\n const nodeRole = node.attrs['role'] ?? implicit;\n if (nodeRole === role) {\n if (accessibleName === undefined) return node;\n const name = accessibleNameOf(node);\n if (name === accessibleName) return node;\n }\n for (const child of node.children) {\n const found = findByRole(child, role, accessibleName);\n if (found) return found;\n }\n return null;\n}\n\n/** node の direct text (子 element を含まず、 空白 trim 済)。 */\nfunction nodeText(node: MockNode): string {\n if (node.text !== undefined) return node.text.trim();\n return node.children\n .map((c) => c.text ?? '')\n .join('')\n .trim();\n}\n\n/** button / a / h1-h6 / input タグから ARIA implicit role を返す。 */\nfunction implicitRole(node: MockNode): string | null {\n switch (node.tag) {\n case 'button':\n return 'button';\n case 'a':\n return node.attrs['href'] ? 'link' : null;\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return 'heading';\n case 'input': {\n const type = node.attrs['type'] ?? 'text';\n if (type === 'checkbox') return 'checkbox';\n if (type === 'radio') return 'radio';\n if (type === 'submit' || type === 'button') return 'button';\n return 'textbox';\n }\n case 'textarea':\n return 'textbox';\n case 'nav':\n return 'navigation';\n case 'main':\n return 'main';\n default:\n return null;\n }\n}\n\n/** aria-label > text content の順で accessible name を決める。 */\nfunction accessibleNameOf(node: MockNode): string {\n const label = node.attrs['aria-label'];\n if (label) return label;\n return nodeText(node);\n}\n\n/**\n * querySelector の最小 subset。 tag / .class / #id / [attr=value] / 子孫 (space)\n * 結合子を support する。 実 CSS selector 全対応ではないが、 mock 用途では十分。\n *\n * MockNode tree では canvas.root が component 自体を指すため、 root も検査対象\n * に含める (実 DOM の `document.querySelector` は container を除くが、 mock は\n * component rendering root = 検索対象という semantics に揃える)。\n */\nexport function query(root: MockNode, selector: string, all: boolean): MockNode[] {\n const parts = selector.trim().split(/\\s+/);\n let candidates: MockNode[] = collectTree(root);\n for (const part of parts) {\n candidates = candidates.filter((n) => matchesSimple(n, part));\n if (!all && candidates.length > 0) {\n return [candidates[0]!];\n }\n }\n return all ? candidates : candidates.length > 0 ? [candidates[0]!] : [];\n}\n\nfunction collectTree(root: MockNode): MockNode[] {\n const out: MockNode[] = [root];\n for (const child of root.children) {\n out.push(...collectTree(child));\n }\n return out;\n}\n\nfunction matchesSimple(node: MockNode, selector: string): boolean {\n // selector = tag | .class | #id | [attr=value] | tag.class#id[attr] chain。\n // 先頭に tag が来る場合は先に消費し、 残りの primitive を順に検査する。\n let rest = selector;\n const tagMatch = rest.match(/^([a-zA-Z][a-zA-Z0-9_-]*)/);\n if (tagMatch) {\n if (node.tag !== tagMatch[1]) return false;\n rest = rest.slice(tagMatch[0].length);\n }\n // primitive を .class / #id / [attr=value] / [attr] の 4 種に分解して順次 AND\n while (rest.length > 0) {\n const attr = rest.match(/^\\[([a-zA-Z0-9_-]+)(=(\\\"[^\\\"]*\\\"|'[^']*'|[^\\]]+))?\\]/);\n if (attr) {\n const name = attr[1]!;\n const raw = attr[3];\n if (raw === undefined) {\n if (node.attrs[name] === undefined) return false;\n } else {\n const unquoted = raw.replace(/^[\"']|[\"']$/g, '');\n if (node.attrs[name] !== unquoted) return false;\n }\n rest = rest.slice(attr[0].length);\n continue;\n }\n const cls = rest.match(/^\\.([a-zA-Z0-9_-]+)/);\n if (cls) {\n const nodeClasses = (node.attrs['class'] ?? '').split(/\\s+/).filter(Boolean);\n if (!nodeClasses.includes(cls[1]!)) return false;\n rest = rest.slice(cls[0].length);\n continue;\n }\n const id = rest.match(/^#([a-zA-Z0-9_-]+)/);\n if (id) {\n if (node.attrs['id'] !== id[1]) return false;\n rest = rest.slice(id[0].length);\n continue;\n }\n // 未知の syntax は不一致にする\n return false;\n }\n return true;\n}\n","import { createCanvas } from './dom.js';\nimport type {\n A11yViolation,\n CanvasElement,\n ComponentRender,\n MockNode,\n PlayContext,\n StoryEntry,\n StoryObj,\n StoryParameters,\n} from './types.js';\n\n/**\n * Storybook 8 の CSF3 と互換な最小 mock。 real Storybook (SB8) は Meta +\n * StoryObj 単位で `.stories.tsx` を書き、 storybook が collect して registry\n * を作る。 mock はその registry 相当を in-memory Map で表現する。\n *\n * 使い方 ...\n * ```ts\n * const registry = createStoryRegistry();\n * registry.register({\n * title: 'Button',\n * render: (args) => createNode('button', { text: args.label }),\n * stories: {\n * Primary: { args: { label: 'Click me' } },\n * Disabled: { args: { label: 'nope', disabled: true } },\n * },\n * });\n * const canvas = await registry.mount('Button', 'Primary');\n * await registry.play('Button', 'Primary', canvas);\n * ```\n *\n * SB8 の実 API 互換で意識するのは (1) StoryObj.args の merge (2) play の\n * step wrapper (3) parameters.chromatic / parameters.a11y の透過保持\n * の 3 点。 実 SB8 の docs mode / decorators / loaders / addons は mock 対象外\n * (テストが吸収する semantic は絞る)。\n */\n\nexport interface StoryMeta<TArgs = Record<string, unknown>> {\n /** Storybook の title (e.g. 'Components/Button')。 */\n title: string;\n /** args → MockNode の render 関数、 framework agnostic。 */\n render: ComponentRender<TArgs>;\n /** meta 単位の default args (story 単位で override 可)。 */\n args?: Partial<TArgs>;\n /** meta 単位の default parameters (story 単位で shallow merge)。 */\n parameters?: StoryParameters;\n /** 登録する story 群、 key が story 名になる。 */\n stories: Record<string, StoryObj<TArgs>>;\n}\n\nexport interface StoryMountResult {\n canvas: CanvasElement;\n entry: StoryEntry<Record<string, unknown>>;\n}\n\nexport interface StoryPlayResult {\n steps: Array<{ label: string; ok: boolean; error?: string }>;\n ok: boolean;\n}\n\nexport interface StoryRegistry {\n register<TArgs>(meta: StoryMeta<TArgs>): void;\n list(): StoryEntry[];\n get(title: string, storyName: string): StoryEntry;\n mount(title: string, storyName: string, overrideArgs?: Record<string, unknown>): StoryMountResult;\n play(title: string, storyName: string, canvas: CanvasElement, args?: Record<string, unknown>): Promise<StoryPlayResult>;\n runA11y(title: string, storyName: string, canvas: CanvasElement): { violations: A11yViolation[] };\n}\n\n/**\n * Registry を新規作成する。 内部は `Map<storyId, StoryEntry>`、 story id は\n * `title--storyName` (Storybook 8 の SB URL param 互換 lowercase / kebab-case)。\n */\nexport function createStoryRegistry(): StoryRegistry {\n const registry = new Map<string, StoryEntry>();\n\n const buildId = (title: string, storyName: string): string => {\n const norm = (s: string) =>\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n return `${norm(title)}--${norm(storyName)}`;\n };\n\n const requireEntry = (title: string, storyName: string): StoryEntry => {\n const id = buildId(title, storyName);\n const entry = registry.get(id);\n if (!entry) {\n throw new Error(`StoryRegistry — no entry for ${id}`);\n }\n return entry;\n };\n\n return {\n register<TArgs>(meta: StoryMeta<TArgs>): void {\n for (const [storyName, story] of Object.entries(meta.stories)) {\n const id = buildId(meta.title, storyName);\n const mergedArgs = { ...(meta.args ?? {}), ...(story.args ?? {}) } as TArgs;\n const mergedParams: StoryParameters = {\n ...(meta.parameters ?? {}),\n ...(story.parameters ?? {}),\n ...(meta.parameters?.chromatic || story.parameters?.chromatic\n ? {\n chromatic: {\n ...(meta.parameters?.chromatic ?? {}),\n ...(story.parameters?.chromatic ?? {}),\n },\n }\n : {}),\n ...(meta.parameters?.a11y || story.parameters?.a11y\n ? {\n a11y: {\n ...(meta.parameters?.a11y ?? {}),\n ...(story.parameters?.a11y ?? {}),\n },\n }\n : {}),\n };\n const entry: StoryEntry = {\n id,\n title: meta.title,\n storyName,\n args: mergedArgs as Record<string, unknown>,\n render: meta.render as ComponentRender<Record<string, unknown>>,\n parameters: mergedParams,\n ...(story.play\n ? {\n play: story.play as (\n context: PlayContext<Record<string, unknown>>,\n ) => Promise<void> | void,\n }\n : {}),\n };\n registry.set(id, entry);\n }\n },\n list(): StoryEntry[] {\n return Array.from(registry.values());\n },\n get(title, storyName): StoryEntry {\n return requireEntry(title, storyName);\n },\n mount(title, storyName, overrideArgs): StoryMountResult {\n const entry = requireEntry(title, storyName);\n const args = { ...entry.args, ...(overrideArgs ?? {}) };\n const root: MockNode = entry.render(args);\n const canvas = createCanvas(root);\n return { canvas, entry: { ...entry, args } };\n },\n async play(title, storyName, canvas, args): Promise<StoryPlayResult> {\n const entry = requireEntry(title, storyName);\n const mergedArgs = { ...entry.args, ...(args ?? {}) };\n const steps: StoryPlayResult['steps'] = [];\n const context: PlayContext<Record<string, unknown>> = {\n canvasElement: canvas,\n args: mergedArgs,\n step: async (label, fn) => {\n try {\n await fn();\n steps.push({ label, ok: true });\n } catch (error) {\n steps.push({ label, ok: false, error: (error as Error).message });\n throw error;\n }\n },\n };\n if (!entry.play) {\n return { steps: [], ok: true };\n }\n try {\n await entry.play(context);\n return { steps, ok: steps.every((s) => s.ok) };\n } catch {\n return { steps, ok: false };\n }\n },\n runA11y(title, storyName, canvas): { violations: A11yViolation[] } {\n const entry = requireEntry(title, storyName);\n if (entry.parameters.a11y?.disable) {\n return { violations: [] };\n }\n const injected = entry.parameters.a11y?.injectViolations ?? [];\n const detected = detectHeuristicViolations(canvas);\n return { violations: [...injected, ...detected] };\n },\n };\n}\n\n/**\n * 最小の a11y heuristic — 実 axe-core の代替として、 mock harness で意味のある\n * 3 rule だけ検出する。 (1) button に accessible name なし (2) img に alt なし\n * (3) form input に label なし。 テストで「a11y violations が検出される」 事を\n * assert できるようにする。\n */\nfunction detectHeuristicViolations(canvas: CanvasElement): A11yViolation[] {\n const violations: A11yViolation[] = [];\n const buttons = canvas.querySelectorAll('button');\n for (const btn of buttons) {\n if (!hasAccessibleName(btn)) {\n violations.push({\n id: 'button-name',\n impact: 'critical',\n description: 'Buttons must have discernible text',\n nodes: [{ target: ['button'], html: '<button></button>' }],\n });\n }\n }\n const imgs = canvas.querySelectorAll('img');\n for (const img of imgs) {\n if (img.attrs['alt'] === undefined) {\n violations.push({\n id: 'image-alt',\n impact: 'serious',\n description: 'Images must have alternate text',\n nodes: [{ target: ['img'], html: '<img />' }],\n });\n }\n }\n const inputs = canvas.querySelectorAll('input');\n for (const input of inputs) {\n const type = input.attrs['type'] ?? 'text';\n if (type === 'hidden' || type === 'submit' || type === 'button') continue;\n if (!input.attrs['aria-label'] && !input.attrs['aria-labelledby'] && !hasAssociatedLabel(input, canvas)) {\n violations.push({\n id: 'label',\n impact: 'critical',\n description: 'Form elements must have labels',\n nodes: [{ target: ['input'], html: '<input />' }],\n });\n }\n }\n return violations;\n}\n\nfunction hasAccessibleName(node: MockNode): boolean {\n if (node.attrs['aria-label']) return true;\n const text = collectText(node).trim();\n return text.length > 0;\n}\n\nfunction collectText(node: MockNode): string {\n const parts: string[] = [];\n if (node.text) parts.push(node.text);\n for (const child of node.children) {\n parts.push(collectText(child));\n }\n return parts.join('');\n}\n\nfunction hasAssociatedLabel(input: MockNode, canvas: CanvasElement): boolean {\n const id = input.attrs['id'];\n if (!id) return false;\n const labels = canvas.querySelectorAll(`label[for=${JSON.stringify(id)}]`);\n return labels.length > 0;\n}\n","import { createCanvas, fireEvent } from './dom.js';\nimport type {\n CanvasElement,\n ComponentLocator,\n ComponentRender,\n MockEvent,\n MockNode,\n NodeLocator,\n} from './types.js';\n\n/**\n * Playwright Component Testing (CT) 互換の最小 mock。 real Playwright CT は\n * `mount(component)` → `Locator` を返し、 `page.getByText().click()` 等で\n * interact する。 mock は同じ API 表面 (mount / getByText / getByRole / click /\n * fill / textContent / count) を持ち、 real vs mock で同じ test を回せる。\n *\n * 実 Playwright CT との差分 = (1) browser process を起動しない (in-memory)、\n * (2) network request の intercept / route は非 support (別の kiwa mock で\n * 対応)、 (3) screenshot は Chromatic 経路に一本化する。\n *\n * 使い方 ...\n * ```ts\n * const ct = createPlaywrightCTMock();\n * const button = ct.mount((args) => createNode('button', { text: args.label, on: { click: args.onClick } }), { label: 'ok', onClick: () => hits++ });\n * await button.getByRole('button', { name: 'ok' }).click();\n * expect(hits).toBe(1);\n * ```\n */\n\nexport interface PlaywrightCTMock {\n mount<TArgs>(\n render: ComponentRender<TArgs>,\n args: TArgs,\n ): ComponentLocator;\n /** mount 済 locator 一覧 (test teardown で全 unmount する時使う)。 */\n activeMounts(): number;\n /** 全 mount を解放する — vitest afterEach 相当の cleanup。 */\n unmountAll(): void;\n}\n\n/**\n * PlaywrightCTMock を新規作成する。 mount 毎に in-memory canvas を組み、\n * ComponentLocator に wrap して返す。 activeMounts count は resource leak\n * 検出用 (test で unmount 忘れを assert できる)。\n */\nexport function createPlaywrightCTMock(): PlaywrightCTMock {\n const active = new Set<MountRecord>();\n\n return {\n mount<TArgs>(\n render: ComponentRender<TArgs>,\n args: TArgs,\n ): ComponentLocator {\n const root = render(args);\n const canvas = createCanvas(root);\n const record: MountRecord = { root, canvas };\n active.add(record);\n return buildLocator(record, () => active.delete(record));\n },\n activeMounts(): number {\n return active.size;\n },\n unmountAll(): void {\n active.clear();\n },\n };\n}\n\ninterface MountRecord {\n root: MockNode;\n canvas: CanvasElement;\n}\n\nfunction buildLocator(record: MountRecord, dispose: () => void): ComponentLocator {\n return {\n canvas: record.canvas,\n root: record.root,\n getByText: (text: string) => createTextLocator(record.canvas, text),\n getByRole: (role: string, options?: { name?: string }) =>\n createRoleLocator(record.canvas, role, options?.name),\n unmount: () => {\n // event handler を全 clear して leak を防ぐ\n clearHandlers(record.root);\n dispose();\n },\n };\n}\n\nfunction createTextLocator(canvas: CanvasElement, text: string): NodeLocator {\n return {\n click: async () => {\n const node = canvas.getByText(text);\n fireEvent(node, buildEvent('click', node));\n },\n fill: async (value: string) => {\n const node = canvas.getByText(text);\n node.value = value;\n fireEvent(node, buildEvent('input', node, value));\n },\n textContent: async () => {\n const node = tryFind(() => canvas.getByText(text));\n return node ? nodeText(node) : null;\n },\n count: async () => {\n return tryFind(() => canvas.getByText(text)) ? 1 : 0;\n },\n node: () => tryFind(() => canvas.getByText(text)),\n };\n}\n\nfunction createRoleLocator(canvas: CanvasElement, role: string, name?: string): NodeLocator {\n return {\n click: async () => {\n const node = canvas.getByRole(role, name !== undefined ? { name } : undefined);\n fireEvent(node, buildEvent('click', node));\n },\n fill: async (value: string) => {\n const node = canvas.getByRole(role, name !== undefined ? { name } : undefined);\n node.value = value;\n fireEvent(node, buildEvent('input', node, value));\n },\n textContent: async () => {\n const node = tryFind(() => canvas.getByRole(role, name !== undefined ? { name } : undefined));\n return node ? nodeText(node) : null;\n },\n count: async () => {\n return tryFind(() => canvas.getByRole(role, name !== undefined ? { name } : undefined)) ? 1 : 0;\n },\n node: () => tryFind(() => canvas.getByRole(role, name !== undefined ? { name } : undefined)),\n };\n}\n\nfunction buildEvent(type: string, target: MockNode, value?: string): MockEvent {\n return {\n type,\n target,\n ...(value !== undefined ? { value } : {}),\n };\n}\n\nfunction tryFind(fn: () => MockNode): MockNode | null {\n try {\n return fn();\n } catch {\n return null;\n }\n}\n\nfunction nodeText(node: MockNode): string {\n const parts: string[] = [];\n if (node.text) parts.push(node.text);\n for (const child of node.children) {\n parts.push(nodeText(child));\n }\n return parts.join('').trim();\n}\n\nfunction clearHandlers(node: MockNode): void {\n node.handlers = {};\n for (const child of node.children) {\n clearHandlers(child);\n }\n}\n","import { hashMarkup } from './dom.js';\nimport type {\n CanvasElement,\n StoryEntry,\n VisualBaseline,\n VisualDiff,\n VisualReviewAction,\n VisualReviewEntry,\n} from './types.js';\n\n/**\n * Chromatic 型の visual regression mock。 real Chromatic は Storybook 8 を\n * headless で snapshot 撮り、 baseline JSON を server 側に置いて diff を\n * pixel single で計算する。 mock harness は browser を起動せず、 mount 後の\n * MockNode を `renderMarkup` で pseudo-HTML 化 → SHA-256 hash → hash 比較で\n * changed 判定を行う (pixel diff は hash 完全一致 = 0、 不一致 = 1、\n * partial diff の連続値は mock 対象外)。\n *\n * mock で意味のある semantic は 4 つ ...\n * (1) baseline capture (未登録なら status='new'、 hash を保存)\n * (2) current capture + diff (hash 一致で passed、 不一致で failed / changed)\n * (3) diffThreshold の適用 (StoryEntry.parameters.chromatic.diffThreshold)\n * (4) accept / reject workflow (accept で baseline を current で置換)\n *\n * multi viewport support = parameters.chromatic.viewports に列挙された viewport\n * 名を 1 回ずつ capture し、 viewport × storyId 単位で baseline / diff を管理。\n */\n\nexport interface ChromaticVisualMock {\n /** baseline / current 群を全 clear。 test 間の isolation 用。 */\n reset(): void;\n /** baseline を明示 seed (test setup で初期状態を作る時使う)。 */\n seedBaseline(input: {\n storyId: string;\n viewport: string;\n markup: string;\n capturedAt?: number;\n }): VisualBaseline;\n /** 1 story × 1 viewport を capture、 baseline 不在なら status='new'。 */\n capture(input: {\n entry: StoryEntry;\n canvas: CanvasElement;\n viewport?: string;\n now?: number;\n }): VisualDiff;\n /**\n * 1 story を parameters.chromatic.viewports 全 viewport で一括 capture。\n * viewports 未指定 or 空なら 'default' viewport 1 件のみ。 disabled story は\n * skip (空配列を返す)。\n */\n captureAll(input: {\n entry: StoryEntry;\n canvas: CanvasElement;\n now?: number;\n }): VisualDiff[];\n /** accept / reject 1 件。 accept は baseline を current 相当で置換する。 */\n review(input: {\n storyId: string;\n viewport: string;\n action: VisualReviewAction;\n reviewedAt?: number;\n }): VisualReviewEntry;\n /** review 履歴一覧 (test で workflow を assert する時使う)。 */\n reviewHistory(): VisualReviewEntry[];\n /** baseline 一覧 (test 用 introspection)。 */\n baselines(): VisualBaseline[];\n}\n\n/**\n * ChromaticVisualMock を新規作成する。 baseline / current / review を全て\n * in-memory Map で保持し、 reset() で全 clear できる (test isolation 用)。\n */\nexport function createChromaticVisualMock(config: ChromaticConfig = {}): ChromaticVisualMock {\n const baselines = new Map<string, VisualBaseline>();\n const currents = new Map<string, VisualBaseline>();\n const reviews: VisualReviewEntry[] = [];\n const defaultViewport = config.defaultViewport ?? 'default';\n const defaultThreshold = config.defaultDiffThreshold ?? 0;\n const nowFn = config.now ?? (() => Date.now());\n\n const keyOf = (storyId: string, viewport: string): string => `${storyId}::${viewport}`;\n\n return {\n reset(): void {\n baselines.clear();\n currents.clear();\n reviews.length = 0;\n },\n seedBaseline(input): VisualBaseline {\n const baseline: VisualBaseline = {\n storyId: input.storyId,\n viewport: input.viewport,\n markup: input.markup,\n hash: hashMarkup(input.markup),\n capturedAt: input.capturedAt ?? nowFn(),\n };\n baselines.set(keyOf(input.storyId, input.viewport), baseline);\n return baseline;\n },\n capture(input): VisualDiff {\n const viewport = input.viewport ?? defaultViewport;\n if (input.entry.parameters.chromatic?.disable) {\n return {\n storyId: input.entry.id,\n viewport,\n baselineHash: '',\n currentHash: '',\n changed: false,\n pixelDiffRatio: 0,\n status: 'passed',\n threshold: defaultThreshold,\n };\n }\n const markup = input.canvas.toMarkup();\n const current: VisualBaseline = {\n storyId: input.entry.id,\n viewport,\n markup,\n hash: hashMarkup(markup),\n capturedAt: input.now ?? nowFn(),\n };\n currents.set(keyOf(input.entry.id, viewport), current);\n const baseline = baselines.get(keyOf(input.entry.id, viewport));\n const threshold = input.entry.parameters.chromatic?.diffThreshold ?? defaultThreshold;\n if (!baseline) {\n // 初回 capture — baseline として登録、 status='new' で返す\n baselines.set(keyOf(input.entry.id, viewport), current);\n return {\n storyId: input.entry.id,\n viewport,\n baselineHash: '',\n currentHash: current.hash,\n changed: false,\n pixelDiffRatio: 0,\n status: 'new',\n threshold,\n };\n }\n const changed = baseline.hash !== current.hash;\n const pixelDiffRatio = changed ? 1 : 0;\n const status: VisualDiff['status'] = pixelDiffRatio > threshold ? 'failed' : 'passed';\n return {\n storyId: input.entry.id,\n viewport,\n baselineHash: baseline.hash,\n currentHash: current.hash,\n changed,\n pixelDiffRatio,\n status,\n threshold,\n };\n },\n captureAll(input): VisualDiff[] {\n if (input.entry.parameters.chromatic?.disable) {\n return [];\n }\n const viewports = input.entry.parameters.chromatic?.viewports?.length\n ? input.entry.parameters.chromatic.viewports\n : [defaultViewport];\n const now = input.now ?? nowFn();\n return viewports.map((viewport) =>\n this.capture({\n entry: input.entry,\n canvas: input.canvas,\n viewport,\n now,\n }),\n );\n },\n review(input): VisualReviewEntry {\n const key = keyOf(input.storyId, input.viewport);\n const entry: VisualReviewEntry = {\n storyId: input.storyId,\n viewport: input.viewport,\n action: input.action,\n reviewedAt: input.reviewedAt ?? nowFn(),\n };\n reviews.push(entry);\n if (input.action === 'accept') {\n const current = currents.get(key);\n if (!current) {\n throw new Error(\n `ChromaticVisualMock.review — cannot accept ${key}, no current capture found. Run capture() first.`,\n );\n }\n baselines.set(key, { ...current, capturedAt: entry.reviewedAt });\n }\n // reject は baseline を保持したまま、 review 履歴だけ残す\n return entry;\n },\n reviewHistory(): VisualReviewEntry[] {\n return [...reviews];\n },\n baselines(): VisualBaseline[] {\n return Array.from(baselines.values());\n },\n };\n}\n\nexport interface ChromaticConfig {\n /** viewport 名の default (未指定 story の 1 件 capture 時に使う)。 */\n defaultViewport?: string;\n /** parameters.chromatic.diffThreshold 未指定時の default。 default = 0 (完全一致で pass)。 */\n defaultDiffThreshold?: number;\n /** capturedAt / reviewedAt 用の deterministic time source (test 決定性)。 */\n now?: () => number;\n}\n","import { appendChild, createNode } from './dom.js';\nimport type { ComponentRender, MockEvent, MockNode } from './types.js';\n\n/**\n * 5 pattern の共通 component fixture。 Storybook story / Playwright CT mount /\n * Chromatic capture の 3 経路で共有できる framework agnostic renderer。 実 SB /\n * PW CT / Chromatic に持込む時は各 framework (React / Vue / Svelte / Solid) の\n * component として書換えるが、 test だけ回す用途はこの fixture で完結する。\n *\n * 5 pattern の選定理由 = SaaS frontend で頻出する 5 primitive を全 cover する。\n * - Button (interactive、 click event、 disabled state)\n * - Input (controlled、 input event、 label association)\n * - Form (submit event、 field 集約、 validation)\n * - Modal (open/close state、 backdrop click、 escape close)\n * - Card (content wrapping、 title + body、 optional footer)\n */\n\n// ---- Button ----\n\nexport interface ButtonArgs {\n label: string;\n disabled?: boolean;\n variant?: 'primary' | 'secondary' | 'danger';\n onClick?: (event: MockEvent) => void;\n}\n\n/**\n * Button — text label + optional click handler + disabled state。\n * variant は class 属性に反映 (chromatic diff で variant 別 baseline を持てる)。\n */\nexport const buildButton: ComponentRender<ButtonArgs> = (args) => {\n const variant = args.variant ?? 'primary';\n const attrs: Record<string, string> = {\n class: `btn btn-${variant}`,\n type: 'button',\n };\n if (args.disabled) {\n attrs['disabled'] = 'true';\n attrs['aria-disabled'] = 'true';\n }\n return createNode('button', {\n attrs,\n text: args.label,\n ...(args.onClick && !args.disabled\n ? { on: { click: args.onClick } }\n : {}),\n });\n};\n\n// ---- Input ----\n\nexport interface InputArgs {\n id: string;\n label: string;\n value?: string;\n type?: 'text' | 'email' | 'password' | 'number';\n required?: boolean;\n placeholder?: string;\n onChange?: (event: MockEvent) => void;\n}\n\n/**\n * Input — label + input の pair、 label[for] で id を関連付ける (a11y label\n * rule を pass する)。 onChange は input event で発火。\n */\nexport const buildInput: ComponentRender<InputArgs> = (args) => {\n const wrapper = createNode('div', { attrs: { class: 'input-group' } });\n const label = createNode('label', {\n attrs: { for: args.id, class: 'input-label' },\n text: args.label,\n });\n const inputAttrs: Record<string, string> = {\n id: args.id,\n name: args.id,\n type: args.type ?? 'text',\n class: 'input-field',\n };\n if (args.required) inputAttrs['required'] = 'true';\n if (args.placeholder) inputAttrs['placeholder'] = args.placeholder;\n const input = createNode('input', {\n attrs: inputAttrs,\n value: args.value ?? '',\n ...(args.onChange ? { on: { input: args.onChange } } : {}),\n });\n appendChild(wrapper, label);\n appendChild(wrapper, input);\n return wrapper;\n};\n\n// ---- Form ----\n\nexport interface FormField {\n id: string;\n label: string;\n type?: InputArgs['type'];\n required?: boolean;\n value?: string;\n}\n\nexport interface FormArgs {\n title: string;\n fields: FormField[];\n submitLabel?: string;\n onSubmit?: (data: Record<string, string>) => void;\n}\n\n/**\n * Form — title + 複数 input + submit button。 submit 時に全 field の value を\n * 集めて onSubmit に渡す。 required field 未入力なら submit を発火しない\n * (validation)、 UI 側で「必須」 表示を出す責務。\n */\nexport const buildForm: ComponentRender<FormArgs> = (args) => {\n const form = createNode('form', {\n attrs: { class: 'form', role: 'form' },\n });\n const heading = createNode('h2', {\n attrs: { class: 'form-title' },\n text: args.title,\n });\n appendChild(form, heading);\n\n const fieldValues = new Map<string, string>();\n for (const field of args.fields) {\n fieldValues.set(field.id, field.value ?? '');\n const wrapper = buildInput({\n id: field.id,\n label: field.label,\n ...(field.type !== undefined ? { type: field.type } : {}),\n ...(field.required !== undefined ? { required: field.required } : {}),\n value: field.value ?? '',\n onChange: (event) => {\n if (event.value !== undefined) {\n fieldValues.set(field.id, event.value);\n }\n },\n });\n appendChild(form, wrapper);\n }\n\n const submit = createNode('button', {\n attrs: {\n type: 'submit',\n class: 'form-submit btn btn-primary',\n },\n text: args.submitLabel ?? 'Submit',\n on: {\n click: () => {\n // required field を確認\n for (const field of args.fields) {\n if (field.required && !fieldValues.get(field.id)) {\n return; // validation fail、 submit 発火せず\n }\n }\n args.onSubmit?.(Object.fromEntries(fieldValues));\n },\n },\n });\n appendChild(form, submit);\n return form;\n};\n\n// ---- Modal ----\n\nexport interface ModalArgs {\n open: boolean;\n title: string;\n body: string;\n onClose?: () => void;\n closeOnBackdrop?: boolean;\n}\n\n/**\n * Modal — open=false なら空 div を返す (closed 状態を表現)。 open=true で\n * backdrop + dialog を組む。 backdrop click / close button click で\n * onClose を発火。\n */\nexport const buildModal: ComponentRender<ModalArgs> = (args) => {\n if (!args.open) {\n return createNode('div', {\n attrs: { class: 'modal modal-closed', 'aria-hidden': 'true' },\n });\n }\n const backdrop = createNode('div', {\n attrs: { class: 'modal-backdrop', role: 'presentation' },\n ...(args.closeOnBackdrop !== false && args.onClose\n ? { on: { click: () => args.onClose?.() } }\n : {}),\n });\n const dialog = createNode('div', {\n attrs: {\n class: 'modal-dialog',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-labelledby': 'modal-title',\n },\n });\n const heading = createNode('h2', {\n attrs: { id: 'modal-title', class: 'modal-title' },\n text: args.title,\n });\n const body = createNode('p', {\n attrs: { class: 'modal-body' },\n text: args.body,\n });\n const closeBtn = createNode('button', {\n attrs: {\n type: 'button',\n class: 'modal-close',\n 'aria-label': 'Close',\n },\n text: 'x',\n ...(args.onClose ? { on: { click: () => args.onClose?.() } } : {}),\n });\n appendChild(dialog, heading);\n appendChild(dialog, body);\n appendChild(dialog, closeBtn);\n appendChild(backdrop, dialog);\n return backdrop;\n};\n\n// ---- Card ----\n\nexport interface CardArgs {\n title: string;\n body: string;\n footer?: string;\n variant?: 'default' | 'outlined' | 'elevated';\n}\n\n/**\n * Card — title / body / optional footer の 3 slot。 chromatic diff で variant\n * 別 baseline を持つ用途の代表 pattern。\n */\nexport const buildCard: ComponentRender<CardArgs> = (args) => {\n const variant = args.variant ?? 'default';\n const card = createNode('article', {\n attrs: { class: `card card-${variant}` },\n });\n const heading = createNode('h3', {\n attrs: { class: 'card-title' },\n text: args.title,\n });\n const body = createNode('p', {\n attrs: { class: 'card-body' },\n text: args.body,\n });\n appendChild(card, heading);\n appendChild(card, body);\n if (args.footer) {\n const footer = createNode('footer', {\n attrs: { class: 'card-footer' },\n text: args.footer,\n });\n appendChild(card, footer);\n }\n return card;\n};\n\n/** 全 component の render function を 1 record にまとめる (test 一括登録用)。 */\nexport const componentFixtures: Record<string, ComponentRender<Record<string, unknown>>> = {\n Button: buildButton as unknown as ComponentRender<Record<string, unknown>>,\n Input: buildInput as unknown as ComponentRender<Record<string, unknown>>,\n Form: buildForm as unknown as ComponentRender<Record<string, unknown>>,\n Modal: buildModal as unknown as ComponentRender<Record<string, unknown>>,\n Card: buildCard as unknown as ComponentRender<Record<string, unknown>>,\n};\n\n/** primitive DOM helper の re-export (test / dogfood app 側から直接使う)。 */\nexport { createNode, appendChild } from './dom.js';\nexport type { MockNode };\n","/**\n * Advanced component semantics — target-neutral axis SSOT.\n *\n * The component package spans Storybook 8, Playwright Component Testing, and\n * Chromatic. These helpers model the observable semantics without importing\n * any of those runtimes, so the same axis can be replayed against each target.\n */\nexport type ComponentTarget = 'storybook8' | 'playwright-ct' | 'chromatic';\n\nexport type ComponentAxis =\n | 'rsc-harness'\n | 'streaming-ssr'\n | 'view-transitions'\n | 'form-action-advanced';\n\nexport type NeutralEventName =\n | 'rsc.render_started'\n | 'rsc.suspense_boundary'\n | 'rsc.html_chunk_streamed'\n | 'rsc.render_completed'\n | 'ssr.suspense_pending'\n | 'ssr.error_boundary_captured'\n | 'ssr.progressive_hydration_started'\n | 'ssr.selective_hydration_completed'\n | 'transition.element_started'\n | 'transition.element_finished'\n | 'transition.document_started'\n | 'transition.animation_asserted'\n | 'form.status_pending'\n | 'form.optimistic_applied'\n | 'form.progressive_enhanced'\n | 'form.action_resolved';\n\nexport interface AxisStep<TState extends string> {\n neutralEvent: NeutralEventName;\n providerEvent: string;\n state: TState;\n amountCents: number;\n metadata: Record<string, string | number | boolean>;\n}\n\nconst dialect: Record<ComponentTarget, Partial<Record<NeutralEventName, string>>> = {\n storybook8: {\n 'rsc.render_started': 'storybook.play.start',\n 'rsc.suspense_boundary': 'storybook.suspense.fallback',\n 'rsc.html_chunk_streamed': 'storybook.stream.chunk',\n 'rsc.render_completed': 'storybook.play.done',\n 'ssr.suspense_pending': 'storybook.suspense.pending',\n 'ssr.error_boundary_captured': 'storybook.error.boundary',\n 'ssr.progressive_hydration_started': 'storybook.hydration.progressive',\n 'ssr.selective_hydration_completed': 'storybook.hydration.selective',\n 'transition.element_started': 'storybook.transition.element.start',\n 'transition.element_finished': 'storybook.transition.element.finish',\n 'transition.document_started': 'storybook.transition.document.start',\n 'transition.animation_asserted': 'storybook.animation.assert',\n 'form.status_pending': 'storybook.form.pending',\n 'form.optimistic_applied': 'storybook.form.optimistic',\n 'form.progressive_enhanced': 'storybook.form.enhanced',\n 'form.action_resolved': 'storybook.form.resolved',\n },\n 'playwright-ct': {\n 'rsc.render_started': 'pwct.mount.rsc.start',\n 'rsc.suspense_boundary': 'pwct.locator.suspense.fallback',\n 'rsc.html_chunk_streamed': 'pwct.response.chunk',\n 'rsc.render_completed': 'pwct.mount.rsc.done',\n 'ssr.suspense_pending': 'pwct.suspense.pending',\n 'ssr.error_boundary_captured': 'pwct.error.boundary',\n 'ssr.progressive_hydration_started': 'pwct.hydration.progressive',\n 'ssr.selective_hydration_completed': 'pwct.hydration.selective',\n 'transition.element_started': 'pwct.transition.element.start',\n 'transition.element_finished': 'pwct.transition.element.finish',\n 'transition.document_started': 'pwct.transition.document.start',\n 'transition.animation_asserted': 'pwct.animation.assert',\n 'form.status_pending': 'pwct.form.pending',\n 'form.optimistic_applied': 'pwct.form.optimistic',\n 'form.progressive_enhanced': 'pwct.form.enhanced',\n 'form.action_resolved': 'pwct.form.resolved',\n },\n chromatic: {\n 'rsc.render_started': 'chromatic.capture.rsc.start',\n 'rsc.suspense_boundary': 'chromatic.capture.suspense',\n 'rsc.html_chunk_streamed': 'chromatic.capture.chunk',\n 'rsc.render_completed': 'chromatic.capture.rsc.done',\n 'ssr.suspense_pending': 'chromatic.suspense.pending',\n 'ssr.error_boundary_captured': 'chromatic.error.snapshot',\n 'ssr.progressive_hydration_started': 'chromatic.hydration.progressive',\n 'ssr.selective_hydration_completed': 'chromatic.hydration.selective',\n 'transition.element_started': 'chromatic.transition.element.start',\n 'transition.element_finished': 'chromatic.transition.element.finish',\n 'transition.document_started': 'chromatic.transition.document.start',\n 'transition.animation_asserted': 'chromatic.animation.assert',\n 'form.status_pending': 'chromatic.form.pending',\n 'form.optimistic_applied': 'chromatic.form.optimistic',\n 'form.progressive_enhanced': 'chromatic.form.enhanced',\n 'form.action_resolved': 'chromatic.form.resolved',\n },\n};\n\nexport function providerEventName(target: ComponentTarget, neutral: NeutralEventName): string {\n return dialect[target][neutral] ?? neutral;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type RscHarnessState = 'idle' | 'rendering' | 'suspended' | 'streaming' | 'completed' | 'errored';\n\nexport interface RscHarnessSession {\n target: ComponentTarget;\n componentId: string;\n state: RscHarnessState;\n chunks: string[];\n suspenseFallback: string | null;\n history: AxisStep<RscHarnessState>[];\n error: string | null;\n}\n\nexport function startRscHarness(input: {\n target: ComponentTarget;\n componentId: string;\n suspenseFallback?: string;\n}): RscHarnessSession {\n if (input.componentId.length === 0) {\n throw new Error('startRscHarness: componentId must not be empty');\n }\n return {\n target: input.target,\n componentId: input.componentId,\n state: 'idle',\n chunks: [],\n suspenseFallback: input.suspenseFallback ?? null,\n history: [],\n error: null,\n };\n}\n\nexport function beginRscRender(session: RscHarnessSession): AxisStep<RscHarnessState> {\n if (session.state !== 'idle') {\n throw new Error(`beginRscRender: session is ${session.state}, not idle`);\n }\n session.state = 'rendering';\n return emit(session, 'rsc.render_started', { componentId: session.componentId });\n}\n\nexport function enterSuspenseBoundary(\n session: RscHarnessSession,\n fallback: string = session.suspenseFallback ?? '<template data-suspense=\"pending\"></template>',\n): AxisStep<RscHarnessState> {\n if (session.state !== 'rendering') {\n throw new Error(`enterSuspenseBoundary: session is ${session.state}, not rendering`);\n }\n session.state = 'suspended';\n session.suspenseFallback = fallback;\n return emit(session, 'rsc.suspense_boundary', { fallback });\n}\n\nexport function streamHtmlChunk(\n session: RscHarnessSession,\n chunk: string,\n): AxisStep<RscHarnessState> {\n if (session.state !== 'rendering' && session.state !== 'suspended' && session.state !== 'streaming') {\n throw new Error(`streamHtmlChunk: session is ${session.state}, cannot stream`);\n }\n if (chunk.length === 0) {\n throw new Error('streamHtmlChunk: chunk must not be empty');\n }\n session.state = 'streaming';\n session.chunks.push(chunk);\n return emit(session, 'rsc.html_chunk_streamed', {\n chunk,\n chunkIndex: session.chunks.length - 1,\n bytes: chunk.length,\n });\n}\n\nexport function completeRscRender(session: RscHarnessSession): AxisStep<RscHarnessState> {\n if (session.state !== 'rendering' && session.state !== 'suspended' && session.state !== 'streaming') {\n throw new Error(`completeRscRender: session is ${session.state}, cannot complete`);\n }\n session.state = 'completed';\n return emit(session, 'rsc.render_completed', {\n chunkCount: session.chunks.length,\n html: session.chunks.join(''),\n });\n}\n\nexport function failRscRender(\n session: RscHarnessSession,\n error: Error | string,\n): AxisStep<RscHarnessState> {\n if (session.state === 'completed') {\n throw new Error('failRscRender: completed session cannot fail');\n }\n session.state = 'errored';\n session.error = typeof error === 'string' ? error : error.message;\n return emit(session, 'ssr.error_boundary_captured', {\n componentId: session.componentId,\n error: session.error,\n });\n}\n\nfunction emit(\n session: RscHarnessSession,\n neutralEvent: AxisStep<RscHarnessState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<RscHarnessState> {\n const step: AxisStep<RscHarnessState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type StreamingSsrState =\n | 'idle'\n | 'suspense-pending'\n | 'error-captured'\n | 'progressive-hydrating'\n | 'selective-hydrated';\n\nexport interface StreamingSsrSession {\n target: ComponentTarget;\n routeId: string;\n state: StreamingSsrState;\n pendingBoundaries: Set<string>;\n hydratedBoundaries: Set<string>;\n errors: Array<{ boundaryId: string; message: string }>;\n history: AxisStep<StreamingSsrState>[];\n}\n\nexport function startStreamingSsr(input: {\n target: ComponentTarget;\n routeId: string;\n}): StreamingSsrSession {\n if (input.routeId.length === 0) {\n throw new Error('startStreamingSsr: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n state: 'idle',\n pendingBoundaries: new Set(),\n hydratedBoundaries: new Set(),\n errors: [],\n history: [],\n };\n}\n\nexport function markSuspensePending(\n session: StreamingSsrSession,\n boundaryId: string,\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(boundaryId);\n session.state = 'suspense-pending';\n session.pendingBoundaries.add(boundaryId);\n return emit(session, 'ssr.suspense_pending', { boundaryId, pendingCount: session.pendingBoundaries.size });\n}\n\nexport function captureErrorBoundary(\n session: StreamingSsrSession,\n input: { boundaryId: string; error: Error | string; recoverable?: boolean },\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(input.boundaryId);\n const message = typeof input.error === 'string' ? input.error : input.error.message;\n session.state = 'error-captured';\n session.errors.push({ boundaryId: input.boundaryId, message });\n if (input.recoverable === false) {\n session.pendingBoundaries.delete(input.boundaryId);\n }\n return emit(session, 'ssr.error_boundary_captured', {\n boundaryId: input.boundaryId,\n message,\n recoverable: input.recoverable ?? true,\n });\n}\n\nexport function startProgressiveHydration(\n session: StreamingSsrSession,\n boundaryId: string,\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(boundaryId);\n if (!session.pendingBoundaries.has(boundaryId)) {\n throw new Error(`startProgressiveHydration: ${boundaryId} is not pending`);\n }\n session.state = 'progressive-hydrating';\n return emit(session, 'ssr.progressive_hydration_started', { boundaryId });\n}\n\nexport function completeSelectiveHydration(\n session: StreamingSsrSession,\n boundaryId: string,\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(boundaryId);\n if (!session.pendingBoundaries.has(boundaryId)) {\n throw new Error(`completeSelectiveHydration: ${boundaryId} is not pending`);\n }\n session.pendingBoundaries.delete(boundaryId);\n session.hydratedBoundaries.add(boundaryId);\n session.state = 'selective-hydrated';\n return emit(session, 'ssr.selective_hydration_completed', {\n boundaryId,\n hydratedCount: session.hydratedBoundaries.size,\n remainingPending: session.pendingBoundaries.size,\n });\n}\n\nfunction assertBoundaryId(boundaryId: string): void {\n if (boundaryId.length === 0) {\n throw new Error('boundaryId must not be empty');\n }\n}\n\nfunction emit(\n session: StreamingSsrSession,\n neutralEvent: AxisStep<StreamingSsrState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<StreamingSsrState> {\n const step: AxisStep<StreamingSsrState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, routeId: session.routeId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type ViewTransitionState =\n | 'idle'\n | 'element-transitioning'\n | 'document-transitioning'\n | 'asserted'\n | 'finished';\n\nexport interface ViewTransitionSession {\n target: ComponentTarget;\n transitionId: string;\n state: ViewTransitionState;\n activeElements: Set<string>;\n documentTransition: string | null;\n assertions: string[];\n history: AxisStep<ViewTransitionState>[];\n}\n\nexport function startViewTransitionSession(input: {\n target: ComponentTarget;\n transitionId: string;\n}): ViewTransitionSession {\n if (input.transitionId.length === 0) {\n throw new Error('startViewTransitionSession: transitionId must not be empty');\n }\n return {\n target: input.target,\n transitionId: input.transitionId,\n state: 'idle',\n activeElements: new Set(),\n documentTransition: null,\n assertions: [],\n history: [],\n };\n}\n\nexport function startElementTransition(\n session: ViewTransitionSession,\n input: { elementId: string; from: string; to: string },\n): AxisStep<ViewTransitionState> {\n if (input.elementId.length === 0) {\n throw new Error('startElementTransition: elementId must not be empty');\n }\n session.state = 'element-transitioning';\n session.activeElements.add(input.elementId);\n return emit(session, 'transition.element_started', input);\n}\n\nexport function finishElementTransition(\n session: ViewTransitionSession,\n elementId: string,\n): AxisStep<ViewTransitionState> {\n if (!session.activeElements.has(elementId)) {\n throw new Error(`finishElementTransition: ${elementId} is not active`);\n }\n session.activeElements.delete(elementId);\n session.state = session.activeElements.size === 0 ? 'finished' : 'element-transitioning';\n return emit(session, 'transition.element_finished', {\n elementId,\n remaining: session.activeElements.size,\n });\n}\n\nexport function startDocumentTransition(\n session: ViewTransitionSession,\n input: { name: string; fromUrl: string; toUrl: string },\n): AxisStep<ViewTransitionState> {\n if (input.name.length === 0) {\n throw new Error('startDocumentTransition: name must not be empty');\n }\n session.state = 'document-transitioning';\n session.documentTransition = input.name;\n return emit(session, 'transition.document_started', input);\n}\n\nexport function assertAnimation(\n session: ViewTransitionSession,\n input: { assertionId: string; durationMs: number; easing?: string },\n): AxisStep<ViewTransitionState> {\n if (input.durationMs < 0) {\n throw new Error('assertAnimation: durationMs must be >= 0');\n }\n session.state = 'asserted';\n session.assertions.push(input.assertionId);\n return emit(session, 'transition.animation_asserted', {\n assertionId: input.assertionId,\n durationMs: input.durationMs,\n easing: input.easing ?? 'linear',\n });\n}\n\nfunction emit(\n session: ViewTransitionSession,\n neutralEvent: AxisStep<ViewTransitionState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ViewTransitionState> {\n const step: AxisStep<ViewTransitionState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, transitionId: session.transitionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type FormActionState = 'idle' | 'pending' | 'optimistic' | 'enhanced' | 'resolved' | 'rejected';\n\nexport interface FormActionSession<TForm extends Record<string, unknown> = Record<string, unknown>> {\n target: ComponentTarget;\n formId: string;\n state: FormActionState;\n form: TForm;\n optimisticPatches: Array<Partial<TForm>>;\n enhanced: boolean;\n history: AxisStep<FormActionState>[];\n error: string | null;\n}\n\nexport function startFormActionSession<TForm extends Record<string, unknown>>(input: {\n target: ComponentTarget;\n formId: string;\n initial: TForm;\n}): FormActionSession<TForm> {\n if (input.formId.length === 0) {\n throw new Error('startFormActionSession: formId must not be empty');\n }\n return {\n target: input.target,\n formId: input.formId,\n state: 'idle',\n form: { ...input.initial },\n optimisticPatches: [],\n enhanced: false,\n history: [],\n error: null,\n };\n}\n\nexport function markFormStatusPending<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n submitter: string,\n): AxisStep<FormActionState> {\n if (session.state === 'pending') {\n throw new Error('markFormStatusPending: form is already pending');\n }\n session.state = 'pending';\n return emit(session, 'form.status_pending', { submitter });\n}\n\nexport function applyOptimisticUpdate<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n patch: Partial<TForm>,\n): AxisStep<FormActionState> {\n if (session.state !== 'pending' && session.state !== 'optimistic') {\n throw new Error(`applyOptimisticUpdate: session is ${session.state}, not pending`);\n }\n session.state = 'optimistic';\n session.optimisticPatches.push(patch);\n session.form = { ...session.form, ...patch };\n return emit(session, 'form.optimistic_applied', {\n patchKeys: Object.keys(patch).join(','),\n patchCount: session.optimisticPatches.length,\n });\n}\n\nexport function enableProgressiveEnhancement<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n input: { method?: 'post' | 'get'; actionUrl: string },\n): AxisStep<FormActionState> {\n if (input.actionUrl.length === 0) {\n throw new Error('enableProgressiveEnhancement: actionUrl must not be empty');\n }\n session.enhanced = true;\n session.state = 'enhanced';\n return emit(session, 'form.progressive_enhanced', {\n method: input.method ?? 'post',\n actionUrl: input.actionUrl,\n });\n}\n\nexport function resolveFormAction<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n result: Partial<TForm>,\n): AxisStep<FormActionState> {\n if (session.state === 'idle') {\n throw new Error('resolveFormAction: action was not submitted');\n }\n session.state = 'resolved';\n session.form = { ...session.form, ...result };\n return emit(session, 'form.action_resolved', {\n resultKeys: Object.keys(result).join(','),\n enhanced: session.enhanced,\n });\n}\n\nexport function rejectFormAction<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n error: Error | string,\n): AxisStep<FormActionState> {\n if (session.state === 'resolved') {\n throw new Error('rejectFormAction: resolved action cannot reject');\n }\n session.state = 'rejected';\n session.error = typeof error === 'string' ? error : error.message;\n return emit(session, 'form.action_resolved', {\n rejected: true,\n error: session.error,\n });\n}\n\nfunction emit<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n neutralEvent: AxisStep<FormActionState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<FormActionState> {\n const step: AxisStep<FormActionState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, formId: session.formId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type ComponentAxis, type ComponentTarget, type NeutralEventName } from './types.js';\n\nexport interface FidelityRow {\n provider: ComponentTarget;\n axis: ComponentAxis;\n neutralEvents: NeutralEventName[];\n providerEvents: string[];\n}\n\nexport interface FidelityCoverage {\n providers: ComponentTarget[];\n axes: ComponentAxis[];\n rows: FidelityRow[];\n}\n\nexport const COMPONENT_AXIS_TO_EVENTS: Record<ComponentAxis, NeutralEventName[]> = {\n 'rsc-harness': [\n 'rsc.render_started',\n 'rsc.suspense_boundary',\n 'rsc.html_chunk_streamed',\n 'rsc.render_completed',\n ],\n 'streaming-ssr': [\n 'ssr.suspense_pending',\n 'ssr.error_boundary_captured',\n 'ssr.progressive_hydration_started',\n 'ssr.selective_hydration_completed',\n ],\n 'view-transitions': [\n 'transition.element_started',\n 'transition.element_finished',\n 'transition.document_started',\n 'transition.animation_asserted',\n ],\n 'form-action-advanced': [\n 'form.status_pending',\n 'form.optimistic_applied',\n 'form.progressive_enhanced',\n 'form.action_resolved',\n ],\n};\n\nexport function collectFidelityCoverage(\n providers: ComponentTarget[] = ['storybook8', 'playwright-ct', 'chromatic'],\n): FidelityCoverage {\n const axes = Object.keys(COMPONENT_AXIS_TO_EVENTS) as ComponentAxis[];\n const rows: FidelityRow[] = [];\n for (const provider of providers) {\n for (const axis of axes) {\n const neutralEvents = COMPONENT_AXIS_TO_EVENTS[axis];\n rows.push({\n provider,\n axis,\n neutralEvents,\n providerEvents: neutralEvents.map((event) => providerEventName(provider, event)),\n });\n }\n }\n return { providers, axes, rows };\n}\n","import type { ComponentTarget } from './semantics/types.js';\n\nexport type KiwaTestMode = 'mock' | 'real';\n\nexport interface ResolvedMode {\n mode: KiwaTestMode;\n provider: ComponentTarget;\n reason: 'default-mock' | 'kiwa-mode-real' | 'missing-key' | 'invalid-mode';\n}\n\nconst TARGET_KEY_ENV: Record<ComponentTarget, string> = {\n storybook8: 'STORYBOOK_URL',\n 'playwright-ct': 'PLAYWRIGHT_CT_URL',\n chromatic: 'CHROMATIC_TOKEN',\n};\n\nexport function resolveMode(\n provider: ComponentTarget,\n env: Record<string, string | undefined> = process.env,\n): ResolvedMode {\n const rawMode = env.KIWA_MODE?.toLowerCase();\n if (rawMode !== undefined && rawMode !== 'real' && rawMode !== 'mock') {\n return { provider, mode: 'mock', reason: 'invalid-mode' };\n }\n if (rawMode !== 'real') {\n return { provider, mode: 'mock', reason: 'default-mock' };\n }\n const keyValue = env[TARGET_KEY_ENV[provider]];\n if (typeof keyValue !== 'string' || keyValue.length === 0) {\n return { provider, mode: 'mock', reason: 'missing-key' };\n }\n return { provider, mode: 'real', reason: 'kiwa-mode-real' };\n}\n\nexport function resolveAllModes(\n env: Record<string, string | undefined> = process.env,\n): ResolvedMode[] {\n const providers: ComponentTarget[] = ['storybook8', 'playwright-ct', 'chromatic'];\n return providers.map((provider) => resolveMode(provider, env));\n}\n\nexport function assertMode(\n provider: ComponentTarget,\n expected: KiwaTestMode,\n env: Record<string, string | undefined> = process.env,\n): void {\n const resolved = resolveMode(provider, env);\n if (resolved.mode !== expected) {\n throw new Error(\n `expected ${provider} in ${expected} mode but resolved ${resolved.mode} (${resolved.reason})`,\n );\n }\n}\n"],"mappings":"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","names":["nodeText","emit","emit","emit"]}
|
|
1
|
+
{"version":3,"sources":["../src/dom.ts","../src/storybook.ts","../src/playwright-ct.ts","../src/chromatic.ts","../src/fixture.ts","../src/semantics/types.ts","../src/semantics/rsc-harness.ts","../src/semantics/streaming-ssr.ts","../src/semantics/view-transitions.ts","../src/semantics/form-action-advanced.ts","../src/semantics/fidelity.ts","../src/semantics/react-19-actions.ts","../src/semantics/islands-architecture.ts","../src/real-driver.ts"],"sourcesContent":["import { createHash } from 'node:crypto';\nimport type { CanvasElement, MockEvent, MockNode } from './types.js';\n\n/**\n * MockNode + CanvasElement の生成 / traversal / event 発火 helper 群。\n *\n * 実 DOM (jsdom / happy-dom) を使わない理由 = (1) Storybook 8 / Playwright CT /\n * Chromatic の 3 統合 mock で共通の抽象を提供したい、 (2) framework agnostic\n * (React / Vue / Svelte / Solid) にする、 (3) test 速度と決定性を最優先する。\n *\n * MockNode tree は tag / attrs / text / children で表現、 実 DOM の subset を\n * 網羅する (querySelector 相当の tag / .class / #id / attr selector、 getByText、\n * getByRole)。 fill / click は event handler を synchronously 呼ぶ。\n */\n\n/** node factory — attrs / children / text / value を任意で与える。 */\nexport function createNode(tag: string, options: NodeOptions = {}): MockNode {\n const node: MockNode = {\n tag,\n attrs: options.attrs ?? {},\n children: [],\n handlers: {},\n parent: null,\n ...(options.text !== undefined ? { text: options.text } : {}),\n ...(options.value !== undefined ? { value: options.value } : {}),\n };\n for (const child of options.children ?? []) {\n appendChild(node, child);\n }\n if (options.on) {\n for (const [event, handler] of Object.entries(options.on)) {\n addHandler(node, event, handler);\n }\n }\n return node;\n}\n\nexport interface NodeOptions {\n attrs?: Record<string, string>;\n text?: string;\n value?: string;\n children?: MockNode[];\n on?: Record<string, (event: MockEvent) => void>;\n}\n\n/** node に child を追加、 parent back reference も更新する。 */\nexport function appendChild(parent: MockNode, child: MockNode): void {\n parent.children.push(child);\n child.parent = parent;\n}\n\n/** event handler を登録、 同一 event に複数 handler を許容する。 */\nexport function addHandler(node: MockNode, event: string, handler: (event: MockEvent) => void): void {\n if (!node.handlers[event]) {\n node.handlers[event] = [];\n }\n node.handlers[event].push(handler);\n}\n\n/**\n * event を発火する。 実 DOM のような bubble はせず target 単発、 mock harness\n * では component 側で bubble 相当を実装する。 fill 相当は input event を発火。\n */\nexport function fireEvent(node: MockNode, event: MockEvent): void {\n const handlers = node.handlers[event.type];\n if (!handlers) return;\n for (const handler of handlers) {\n handler(event);\n }\n}\n\n/**\n * CanvasElement 生成 — root node と lookup helpers を wrap する。 mount 完了後\n * story / component test / visual capture の全経路で使う。\n */\nexport function createCanvas(root: MockNode): CanvasElement {\n return {\n root,\n getByText: (text: string) => {\n const found = findByText(root, text);\n if (!found) {\n throw new Error(`Canvas.getByText — no node with text ${JSON.stringify(text)}`);\n }\n return found;\n },\n getByRole: (role: string, options?: { name?: string }) => {\n const found = findByRole(root, role, options?.name);\n if (!found) {\n const nameSuffix = options?.name ? ` name=${JSON.stringify(options.name)}` : '';\n throw new Error(`Canvas.getByRole — no node with role=${role}${nameSuffix}`);\n }\n return found;\n },\n querySelector: (selector: string) => query(root, selector, false)[0] ?? null,\n querySelectorAll: (selector: string) => query(root, selector, true),\n toMarkup: () => renderMarkup(root),\n };\n}\n\n/**\n * MockNode subtree を deterministic な pseudo-HTML 文字列に変換する。\n * event handler は含めず、 tag / attrs / text / children のみ。\n * Chromatic の hash / markup 保存に使う。\n */\nexport function renderMarkup(node: MockNode): string {\n const attrs = Object.entries(node.attrs)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => ` ${k}=${JSON.stringify(v)}`)\n .join('');\n const valueAttr =\n node.value !== undefined ? ` value=${JSON.stringify(node.value)}` : '';\n const openTag = `<${node.tag}${attrs}${valueAttr}>`;\n const inner = [\n node.text ?? '',\n ...node.children.map(renderMarkup),\n ].join('');\n return `${openTag}${inner}</${node.tag}>`;\n}\n\n/** markup 文字列を deterministic SHA-256 hex substring (先頭 16) に変換。 */\nexport function hashMarkup(markup: string): string {\n return createHash('sha256').update(markup).digest('hex').slice(0, 16);\n}\n\n/**\n * text 一致で最初に見つかった node を返す。 深い node を優先する — root 側の\n * aggregated text ではなく、 実際に text を持つ leaf 相当の node を先に返す\n * (Storybook / Testing Library の getByText 挙動と揃える)。\n */\nexport function findByText(node: MockNode, text: string): MockNode | null {\n for (const child of node.children) {\n const found = findByText(child, text);\n if (found) return found;\n }\n if (nodeText(node) === text) return node;\n return null;\n}\n\n/**\n * role 属性 (`role=\"button\"`) or implicit role (button tag) と、 aria-label /\n * text で一致する node を返す。 mock は最小 subset (button / link / heading /\n * textbox / checkbox) のみ。\n */\nexport function findByRole(node: MockNode, role: string, accessibleName?: string): MockNode | null {\n const implicit = implicitRole(node);\n const nodeRole = node.attrs['role'] ?? implicit;\n if (nodeRole === role) {\n if (accessibleName === undefined) return node;\n const name = accessibleNameOf(node);\n if (name === accessibleName) return node;\n }\n for (const child of node.children) {\n const found = findByRole(child, role, accessibleName);\n if (found) return found;\n }\n return null;\n}\n\n/** node の direct text (子 element を含まず、 空白 trim 済)。 */\nfunction nodeText(node: MockNode): string {\n if (node.text !== undefined) return node.text.trim();\n return node.children\n .map((c) => c.text ?? '')\n .join('')\n .trim();\n}\n\n/** button / a / h1-h6 / input タグから ARIA implicit role を返す。 */\nfunction implicitRole(node: MockNode): string | null {\n switch (node.tag) {\n case 'button':\n return 'button';\n case 'a':\n return node.attrs['href'] ? 'link' : null;\n case 'h1':\n case 'h2':\n case 'h3':\n case 'h4':\n case 'h5':\n case 'h6':\n return 'heading';\n case 'input': {\n const type = node.attrs['type'] ?? 'text';\n if (type === 'checkbox') return 'checkbox';\n if (type === 'radio') return 'radio';\n if (type === 'submit' || type === 'button') return 'button';\n return 'textbox';\n }\n case 'textarea':\n return 'textbox';\n case 'nav':\n return 'navigation';\n case 'main':\n return 'main';\n default:\n return null;\n }\n}\n\n/** aria-label > text content の順で accessible name を決める。 */\nfunction accessibleNameOf(node: MockNode): string {\n const label = node.attrs['aria-label'];\n if (label) return label;\n return nodeText(node);\n}\n\n/**\n * querySelector の最小 subset。 tag / .class / #id / [attr=value] / 子孫 (space)\n * 結合子を support する。 実 CSS selector 全対応ではないが、 mock 用途では十分。\n *\n * MockNode tree では canvas.root が component 自体を指すため、 root も検査対象\n * に含める (実 DOM の `document.querySelector` は container を除くが、 mock は\n * component rendering root = 検索対象という semantics に揃える)。\n */\nexport function query(root: MockNode, selector: string, all: boolean): MockNode[] {\n const parts = selector.trim().split(/\\s+/);\n let candidates: MockNode[] = collectTree(root);\n for (const part of parts) {\n candidates = candidates.filter((n) => matchesSimple(n, part));\n if (!all && candidates.length > 0) {\n return [candidates[0]!];\n }\n }\n return all ? candidates : candidates.length > 0 ? [candidates[0]!] : [];\n}\n\nfunction collectTree(root: MockNode): MockNode[] {\n const out: MockNode[] = [root];\n for (const child of root.children) {\n out.push(...collectTree(child));\n }\n return out;\n}\n\nfunction matchesSimple(node: MockNode, selector: string): boolean {\n // selector = tag | .class | #id | [attr=value] | tag.class#id[attr] chain。\n // 先頭に tag が来る場合は先に消費し、 残りの primitive を順に検査する。\n let rest = selector;\n const tagMatch = rest.match(/^([a-zA-Z][a-zA-Z0-9_-]*)/);\n if (tagMatch) {\n if (node.tag !== tagMatch[1]) return false;\n rest = rest.slice(tagMatch[0].length);\n }\n // primitive を .class / #id / [attr=value] / [attr] の 4 種に分解して順次 AND\n while (rest.length > 0) {\n const attr = rest.match(/^\\[([a-zA-Z0-9_-]+)(=(\\\"[^\\\"]*\\\"|'[^']*'|[^\\]]+))?\\]/);\n if (attr) {\n const name = attr[1]!;\n const raw = attr[3];\n if (raw === undefined) {\n if (node.attrs[name] === undefined) return false;\n } else {\n const unquoted = raw.replace(/^[\"']|[\"']$/g, '');\n if (node.attrs[name] !== unquoted) return false;\n }\n rest = rest.slice(attr[0].length);\n continue;\n }\n const cls = rest.match(/^\\.([a-zA-Z0-9_-]+)/);\n if (cls) {\n const nodeClasses = (node.attrs['class'] ?? '').split(/\\s+/).filter(Boolean);\n if (!nodeClasses.includes(cls[1]!)) return false;\n rest = rest.slice(cls[0].length);\n continue;\n }\n const id = rest.match(/^#([a-zA-Z0-9_-]+)/);\n if (id) {\n if (node.attrs['id'] !== id[1]) return false;\n rest = rest.slice(id[0].length);\n continue;\n }\n // 未知の syntax は不一致にする\n return false;\n }\n return true;\n}\n","import { createCanvas } from './dom.js';\nimport type {\n A11yViolation,\n CanvasElement,\n ComponentRender,\n MockNode,\n PlayContext,\n StoryEntry,\n StoryObj,\n StoryParameters,\n} from './types.js';\n\n/**\n * Storybook 8 の CSF3 と互換な最小 mock。 real Storybook (SB8) は Meta +\n * StoryObj 単位で `.stories.tsx` を書き、 storybook が collect して registry\n * を作る。 mock はその registry 相当を in-memory Map で表現する。\n *\n * 使い方 ...\n * ```ts\n * const registry = createStoryRegistry();\n * registry.register({\n * title: 'Button',\n * render: (args) => createNode('button', { text: args.label }),\n * stories: {\n * Primary: { args: { label: 'Click me' } },\n * Disabled: { args: { label: 'nope', disabled: true } },\n * },\n * });\n * const canvas = await registry.mount('Button', 'Primary');\n * await registry.play('Button', 'Primary', canvas);\n * ```\n *\n * SB8 の実 API 互換で意識するのは (1) StoryObj.args の merge (2) play の\n * step wrapper (3) parameters.chromatic / parameters.a11y の透過保持\n * の 3 点。 実 SB8 の docs mode / decorators / loaders / addons は mock 対象外\n * (テストが吸収する semantic は絞る)。\n */\n\nexport interface StoryMeta<TArgs = Record<string, unknown>> {\n /** Storybook の title (e.g. 'Components/Button')。 */\n title: string;\n /** args → MockNode の render 関数、 framework agnostic。 */\n render: ComponentRender<TArgs>;\n /** meta 単位の default args (story 単位で override 可)。 */\n args?: Partial<TArgs>;\n /** meta 単位の default parameters (story 単位で shallow merge)。 */\n parameters?: StoryParameters;\n /** 登録する story 群、 key が story 名になる。 */\n stories: Record<string, StoryObj<TArgs>>;\n}\n\nexport interface StoryMountResult {\n canvas: CanvasElement;\n entry: StoryEntry<Record<string, unknown>>;\n}\n\nexport interface StoryPlayResult {\n steps: Array<{ label: string; ok: boolean; error?: string }>;\n ok: boolean;\n}\n\nexport interface StoryRegistry {\n register<TArgs>(meta: StoryMeta<TArgs>): void;\n list(): StoryEntry[];\n get(title: string, storyName: string): StoryEntry;\n mount(title: string, storyName: string, overrideArgs?: Record<string, unknown>): StoryMountResult;\n play(title: string, storyName: string, canvas: CanvasElement, args?: Record<string, unknown>): Promise<StoryPlayResult>;\n runA11y(title: string, storyName: string, canvas: CanvasElement): { violations: A11yViolation[] };\n}\n\n/**\n * Registry を新規作成する。 内部は `Map<storyId, StoryEntry>`、 story id は\n * `title--storyName` (Storybook 8 の SB URL param 互換 lowercase / kebab-case)。\n */\nexport function createStoryRegistry(): StoryRegistry {\n const registry = new Map<string, StoryEntry>();\n\n const buildId = (title: string, storyName: string): string => {\n const norm = (s: string) =>\n s\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n return `${norm(title)}--${norm(storyName)}`;\n };\n\n const requireEntry = (title: string, storyName: string): StoryEntry => {\n const id = buildId(title, storyName);\n const entry = registry.get(id);\n if (!entry) {\n throw new Error(`StoryRegistry — no entry for ${id}`);\n }\n return entry;\n };\n\n return {\n register<TArgs>(meta: StoryMeta<TArgs>): void {\n for (const [storyName, story] of Object.entries(meta.stories)) {\n const id = buildId(meta.title, storyName);\n const mergedArgs = { ...(meta.args ?? {}), ...(story.args ?? {}) } as TArgs;\n const mergedParams: StoryParameters = {\n ...(meta.parameters ?? {}),\n ...(story.parameters ?? {}),\n ...(meta.parameters?.chromatic || story.parameters?.chromatic\n ? {\n chromatic: {\n ...(meta.parameters?.chromatic ?? {}),\n ...(story.parameters?.chromatic ?? {}),\n },\n }\n : {}),\n ...(meta.parameters?.a11y || story.parameters?.a11y\n ? {\n a11y: {\n ...(meta.parameters?.a11y ?? {}),\n ...(story.parameters?.a11y ?? {}),\n },\n }\n : {}),\n };\n const entry: StoryEntry = {\n id,\n title: meta.title,\n storyName,\n args: mergedArgs as Record<string, unknown>,\n render: meta.render as ComponentRender<Record<string, unknown>>,\n parameters: mergedParams,\n ...(story.play\n ? {\n play: story.play as (\n context: PlayContext<Record<string, unknown>>,\n ) => Promise<void> | void,\n }\n : {}),\n };\n registry.set(id, entry);\n }\n },\n list(): StoryEntry[] {\n return Array.from(registry.values());\n },\n get(title, storyName): StoryEntry {\n return requireEntry(title, storyName);\n },\n mount(title, storyName, overrideArgs): StoryMountResult {\n const entry = requireEntry(title, storyName);\n const args = { ...entry.args, ...(overrideArgs ?? {}) };\n const root: MockNode = entry.render(args);\n const canvas = createCanvas(root);\n return { canvas, entry: { ...entry, args } };\n },\n async play(title, storyName, canvas, args): Promise<StoryPlayResult> {\n const entry = requireEntry(title, storyName);\n const mergedArgs = { ...entry.args, ...(args ?? {}) };\n const steps: StoryPlayResult['steps'] = [];\n const context: PlayContext<Record<string, unknown>> = {\n canvasElement: canvas,\n args: mergedArgs,\n step: async (label, fn) => {\n try {\n await fn();\n steps.push({ label, ok: true });\n } catch (error) {\n steps.push({ label, ok: false, error: (error as Error).message });\n throw error;\n }\n },\n };\n if (!entry.play) {\n return { steps: [], ok: true };\n }\n try {\n await entry.play(context);\n return { steps, ok: steps.every((s) => s.ok) };\n } catch {\n return { steps, ok: false };\n }\n },\n runA11y(title, storyName, canvas): { violations: A11yViolation[] } {\n const entry = requireEntry(title, storyName);\n if (entry.parameters.a11y?.disable) {\n return { violations: [] };\n }\n const injected = entry.parameters.a11y?.injectViolations ?? [];\n const detected = detectHeuristicViolations(canvas);\n return { violations: [...injected, ...detected] };\n },\n };\n}\n\n/**\n * 最小の a11y heuristic — 実 axe-core の代替として、 mock harness で意味のある\n * 3 rule だけ検出する。 (1) button に accessible name なし (2) img に alt なし\n * (3) form input に label なし。 テストで「a11y violations が検出される」 事を\n * assert できるようにする。\n */\nfunction detectHeuristicViolations(canvas: CanvasElement): A11yViolation[] {\n const violations: A11yViolation[] = [];\n const buttons = canvas.querySelectorAll('button');\n for (const btn of buttons) {\n if (!hasAccessibleName(btn)) {\n violations.push({\n id: 'button-name',\n impact: 'critical',\n description: 'Buttons must have discernible text',\n nodes: [{ target: ['button'], html: '<button></button>' }],\n });\n }\n }\n const imgs = canvas.querySelectorAll('img');\n for (const img of imgs) {\n if (img.attrs['alt'] === undefined) {\n violations.push({\n id: 'image-alt',\n impact: 'serious',\n description: 'Images must have alternate text',\n nodes: [{ target: ['img'], html: '<img />' }],\n });\n }\n }\n const inputs = canvas.querySelectorAll('input');\n for (const input of inputs) {\n const type = input.attrs['type'] ?? 'text';\n if (type === 'hidden' || type === 'submit' || type === 'button') continue;\n if (!input.attrs['aria-label'] && !input.attrs['aria-labelledby'] && !hasAssociatedLabel(input, canvas)) {\n violations.push({\n id: 'label',\n impact: 'critical',\n description: 'Form elements must have labels',\n nodes: [{ target: ['input'], html: '<input />' }],\n });\n }\n }\n return violations;\n}\n\nfunction hasAccessibleName(node: MockNode): boolean {\n if (node.attrs['aria-label']) return true;\n const text = collectText(node).trim();\n return text.length > 0;\n}\n\nfunction collectText(node: MockNode): string {\n const parts: string[] = [];\n if (node.text) parts.push(node.text);\n for (const child of node.children) {\n parts.push(collectText(child));\n }\n return parts.join('');\n}\n\nfunction hasAssociatedLabel(input: MockNode, canvas: CanvasElement): boolean {\n const id = input.attrs['id'];\n if (!id) return false;\n const labels = canvas.querySelectorAll(`label[for=${JSON.stringify(id)}]`);\n return labels.length > 0;\n}\n","import { createCanvas, fireEvent } from './dom.js';\nimport type {\n CanvasElement,\n ComponentLocator,\n ComponentRender,\n MockEvent,\n MockNode,\n NodeLocator,\n} from './types.js';\n\n/**\n * Playwright Component Testing (CT) 互換の最小 mock。 real Playwright CT は\n * `mount(component)` → `Locator` を返し、 `page.getByText().click()` 等で\n * interact する。 mock は同じ API 表面 (mount / getByText / getByRole / click /\n * fill / textContent / count) を持ち、 real vs mock で同じ test を回せる。\n *\n * 実 Playwright CT との差分 = (1) browser process を起動しない (in-memory)、\n * (2) network request の intercept / route は非 support (別の kiwa mock で\n * 対応)、 (3) screenshot は Chromatic 経路に一本化する。\n *\n * 使い方 ...\n * ```ts\n * const ct = createPlaywrightCTMock();\n * const button = ct.mount((args) => createNode('button', { text: args.label, on: { click: args.onClick } }), { label: 'ok', onClick: () => hits++ });\n * await button.getByRole('button', { name: 'ok' }).click();\n * expect(hits).toBe(1);\n * ```\n */\n\nexport interface PlaywrightCTMock {\n mount<TArgs>(\n render: ComponentRender<TArgs>,\n args: TArgs,\n ): ComponentLocator;\n /** mount 済 locator 一覧 (test teardown で全 unmount する時使う)。 */\n activeMounts(): number;\n /** 全 mount を解放する — vitest afterEach 相当の cleanup。 */\n unmountAll(): void;\n}\n\n/**\n * PlaywrightCTMock を新規作成する。 mount 毎に in-memory canvas を組み、\n * ComponentLocator に wrap して返す。 activeMounts count は resource leak\n * 検出用 (test で unmount 忘れを assert できる)。\n */\nexport function createPlaywrightCTMock(): PlaywrightCTMock {\n const active = new Set<MountRecord>();\n\n return {\n mount<TArgs>(\n render: ComponentRender<TArgs>,\n args: TArgs,\n ): ComponentLocator {\n const root = render(args);\n const canvas = createCanvas(root);\n const record: MountRecord = { root, canvas };\n active.add(record);\n return buildLocator(record, () => active.delete(record));\n },\n activeMounts(): number {\n return active.size;\n },\n unmountAll(): void {\n active.clear();\n },\n };\n}\n\ninterface MountRecord {\n root: MockNode;\n canvas: CanvasElement;\n}\n\nfunction buildLocator(record: MountRecord, dispose: () => void): ComponentLocator {\n return {\n canvas: record.canvas,\n root: record.root,\n getByText: (text: string) => createTextLocator(record.canvas, text),\n getByRole: (role: string, options?: { name?: string }) =>\n createRoleLocator(record.canvas, role, options?.name),\n unmount: () => {\n // event handler を全 clear して leak を防ぐ\n clearHandlers(record.root);\n dispose();\n },\n };\n}\n\nfunction createTextLocator(canvas: CanvasElement, text: string): NodeLocator {\n return {\n click: async () => {\n const node = canvas.getByText(text);\n fireEvent(node, buildEvent('click', node));\n },\n fill: async (value: string) => {\n const node = canvas.getByText(text);\n node.value = value;\n fireEvent(node, buildEvent('input', node, value));\n },\n textContent: async () => {\n const node = tryFind(() => canvas.getByText(text));\n return node ? nodeText(node) : null;\n },\n count: async () => {\n return tryFind(() => canvas.getByText(text)) ? 1 : 0;\n },\n node: () => tryFind(() => canvas.getByText(text)),\n };\n}\n\nfunction createRoleLocator(canvas: CanvasElement, role: string, name?: string): NodeLocator {\n return {\n click: async () => {\n const node = canvas.getByRole(role, name !== undefined ? { name } : undefined);\n fireEvent(node, buildEvent('click', node));\n },\n fill: async (value: string) => {\n const node = canvas.getByRole(role, name !== undefined ? { name } : undefined);\n node.value = value;\n fireEvent(node, buildEvent('input', node, value));\n },\n textContent: async () => {\n const node = tryFind(() => canvas.getByRole(role, name !== undefined ? { name } : undefined));\n return node ? nodeText(node) : null;\n },\n count: async () => {\n return tryFind(() => canvas.getByRole(role, name !== undefined ? { name } : undefined)) ? 1 : 0;\n },\n node: () => tryFind(() => canvas.getByRole(role, name !== undefined ? { name } : undefined)),\n };\n}\n\nfunction buildEvent(type: string, target: MockNode, value?: string): MockEvent {\n return {\n type,\n target,\n ...(value !== undefined ? { value } : {}),\n };\n}\n\nfunction tryFind(fn: () => MockNode): MockNode | null {\n try {\n return fn();\n } catch {\n return null;\n }\n}\n\nfunction nodeText(node: MockNode): string {\n const parts: string[] = [];\n if (node.text) parts.push(node.text);\n for (const child of node.children) {\n parts.push(nodeText(child));\n }\n return parts.join('').trim();\n}\n\nfunction clearHandlers(node: MockNode): void {\n node.handlers = {};\n for (const child of node.children) {\n clearHandlers(child);\n }\n}\n","import { hashMarkup } from './dom.js';\nimport type {\n CanvasElement,\n StoryEntry,\n VisualBaseline,\n VisualDiff,\n VisualReviewAction,\n VisualReviewEntry,\n} from './types.js';\n\n/**\n * Chromatic 型の visual regression mock。 real Chromatic は Storybook 8 を\n * headless で snapshot 撮り、 baseline JSON を server 側に置いて diff を\n * pixel single で計算する。 mock harness は browser を起動せず、 mount 後の\n * MockNode を `renderMarkup` で pseudo-HTML 化 → SHA-256 hash → hash 比較で\n * changed 判定を行う (pixel diff は hash 完全一致 = 0、 不一致 = 1、\n * partial diff の連続値は mock 対象外)。\n *\n * mock で意味のある semantic は 4 つ ...\n * (1) baseline capture (未登録なら status='new'、 hash を保存)\n * (2) current capture + diff (hash 一致で passed、 不一致で failed / changed)\n * (3) diffThreshold の適用 (StoryEntry.parameters.chromatic.diffThreshold)\n * (4) accept / reject workflow (accept で baseline を current で置換)\n *\n * multi viewport support = parameters.chromatic.viewports に列挙された viewport\n * 名を 1 回ずつ capture し、 viewport × storyId 単位で baseline / diff を管理。\n */\n\nexport interface ChromaticVisualMock {\n /** baseline / current 群を全 clear。 test 間の isolation 用。 */\n reset(): void;\n /** baseline を明示 seed (test setup で初期状態を作る時使う)。 */\n seedBaseline(input: {\n storyId: string;\n viewport: string;\n markup: string;\n capturedAt?: number;\n }): VisualBaseline;\n /** 1 story × 1 viewport を capture、 baseline 不在なら status='new'。 */\n capture(input: {\n entry: StoryEntry;\n canvas: CanvasElement;\n viewport?: string;\n now?: number;\n }): VisualDiff;\n /**\n * 1 story を parameters.chromatic.viewports 全 viewport で一括 capture。\n * viewports 未指定 or 空なら 'default' viewport 1 件のみ。 disabled story は\n * skip (空配列を返す)。\n */\n captureAll(input: {\n entry: StoryEntry;\n canvas: CanvasElement;\n now?: number;\n }): VisualDiff[];\n /** accept / reject 1 件。 accept は baseline を current 相当で置換する。 */\n review(input: {\n storyId: string;\n viewport: string;\n action: VisualReviewAction;\n reviewedAt?: number;\n }): VisualReviewEntry;\n /** review 履歴一覧 (test で workflow を assert する時使う)。 */\n reviewHistory(): VisualReviewEntry[];\n /** baseline 一覧 (test 用 introspection)。 */\n baselines(): VisualBaseline[];\n}\n\n/**\n * ChromaticVisualMock を新規作成する。 baseline / current / review を全て\n * in-memory Map で保持し、 reset() で全 clear できる (test isolation 用)。\n */\nexport function createChromaticVisualMock(config: ChromaticConfig = {}): ChromaticVisualMock {\n const baselines = new Map<string, VisualBaseline>();\n const currents = new Map<string, VisualBaseline>();\n const reviews: VisualReviewEntry[] = [];\n const defaultViewport = config.defaultViewport ?? 'default';\n const defaultThreshold = config.defaultDiffThreshold ?? 0;\n const nowFn = config.now ?? (() => Date.now());\n\n const keyOf = (storyId: string, viewport: string): string => `${storyId}::${viewport}`;\n\n return {\n reset(): void {\n baselines.clear();\n currents.clear();\n reviews.length = 0;\n },\n seedBaseline(input): VisualBaseline {\n const baseline: VisualBaseline = {\n storyId: input.storyId,\n viewport: input.viewport,\n markup: input.markup,\n hash: hashMarkup(input.markup),\n capturedAt: input.capturedAt ?? nowFn(),\n };\n baselines.set(keyOf(input.storyId, input.viewport), baseline);\n return baseline;\n },\n capture(input): VisualDiff {\n const viewport = input.viewport ?? defaultViewport;\n if (input.entry.parameters.chromatic?.disable) {\n return {\n storyId: input.entry.id,\n viewport,\n baselineHash: '',\n currentHash: '',\n changed: false,\n pixelDiffRatio: 0,\n status: 'passed',\n threshold: defaultThreshold,\n };\n }\n const markup = input.canvas.toMarkup();\n const current: VisualBaseline = {\n storyId: input.entry.id,\n viewport,\n markup,\n hash: hashMarkup(markup),\n capturedAt: input.now ?? nowFn(),\n };\n currents.set(keyOf(input.entry.id, viewport), current);\n const baseline = baselines.get(keyOf(input.entry.id, viewport));\n const threshold = input.entry.parameters.chromatic?.diffThreshold ?? defaultThreshold;\n if (!baseline) {\n // 初回 capture — baseline として登録、 status='new' で返す\n baselines.set(keyOf(input.entry.id, viewport), current);\n return {\n storyId: input.entry.id,\n viewport,\n baselineHash: '',\n currentHash: current.hash,\n changed: false,\n pixelDiffRatio: 0,\n status: 'new',\n threshold,\n };\n }\n const changed = baseline.hash !== current.hash;\n const pixelDiffRatio = changed ? 1 : 0;\n const status: VisualDiff['status'] = pixelDiffRatio > threshold ? 'failed' : 'passed';\n return {\n storyId: input.entry.id,\n viewport,\n baselineHash: baseline.hash,\n currentHash: current.hash,\n changed,\n pixelDiffRatio,\n status,\n threshold,\n };\n },\n captureAll(input): VisualDiff[] {\n if (input.entry.parameters.chromatic?.disable) {\n return [];\n }\n const viewports = input.entry.parameters.chromatic?.viewports?.length\n ? input.entry.parameters.chromatic.viewports\n : [defaultViewport];\n const now = input.now ?? nowFn();\n return viewports.map((viewport) =>\n this.capture({\n entry: input.entry,\n canvas: input.canvas,\n viewport,\n now,\n }),\n );\n },\n review(input): VisualReviewEntry {\n const key = keyOf(input.storyId, input.viewport);\n const entry: VisualReviewEntry = {\n storyId: input.storyId,\n viewport: input.viewport,\n action: input.action,\n reviewedAt: input.reviewedAt ?? nowFn(),\n };\n reviews.push(entry);\n if (input.action === 'accept') {\n const current = currents.get(key);\n if (!current) {\n throw new Error(\n `ChromaticVisualMock.review — cannot accept ${key}, no current capture found. Run capture() first.`,\n );\n }\n baselines.set(key, { ...current, capturedAt: entry.reviewedAt });\n }\n // reject は baseline を保持したまま、 review 履歴だけ残す\n return entry;\n },\n reviewHistory(): VisualReviewEntry[] {\n return [...reviews];\n },\n baselines(): VisualBaseline[] {\n return Array.from(baselines.values());\n },\n };\n}\n\nexport interface ChromaticConfig {\n /** viewport 名の default (未指定 story の 1 件 capture 時に使う)。 */\n defaultViewport?: string;\n /** parameters.chromatic.diffThreshold 未指定時の default。 default = 0 (完全一致で pass)。 */\n defaultDiffThreshold?: number;\n /** capturedAt / reviewedAt 用の deterministic time source (test 決定性)。 */\n now?: () => number;\n}\n","import { appendChild, createNode } from './dom.js';\nimport type { ComponentRender, MockEvent, MockNode } from './types.js';\n\n/**\n * 5 pattern の共通 component fixture。 Storybook story / Playwright CT mount /\n * Chromatic capture の 3 経路で共有できる framework agnostic renderer。 実 SB /\n * PW CT / Chromatic に持込む時は各 framework (React / Vue / Svelte / Solid) の\n * component として書換えるが、 test だけ回す用途はこの fixture で完結する。\n *\n * 5 pattern の選定理由 = SaaS frontend で頻出する 5 primitive を全 cover する。\n * - Button (interactive、 click event、 disabled state)\n * - Input (controlled、 input event、 label association)\n * - Form (submit event、 field 集約、 validation)\n * - Modal (open/close state、 backdrop click、 escape close)\n * - Card (content wrapping、 title + body、 optional footer)\n */\n\n// ---- Button ----\n\nexport interface ButtonArgs {\n label: string;\n disabled?: boolean;\n variant?: 'primary' | 'secondary' | 'danger';\n onClick?: (event: MockEvent) => void;\n}\n\n/**\n * Button — text label + optional click handler + disabled state。\n * variant は class 属性に反映 (chromatic diff で variant 別 baseline を持てる)。\n */\nexport const buildButton: ComponentRender<ButtonArgs> = (args) => {\n const variant = args.variant ?? 'primary';\n const attrs: Record<string, string> = {\n class: `btn btn-${variant}`,\n type: 'button',\n };\n if (args.disabled) {\n attrs['disabled'] = 'true';\n attrs['aria-disabled'] = 'true';\n }\n return createNode('button', {\n attrs,\n text: args.label,\n ...(args.onClick && !args.disabled\n ? { on: { click: args.onClick } }\n : {}),\n });\n};\n\n// ---- Input ----\n\nexport interface InputArgs {\n id: string;\n label: string;\n value?: string;\n type?: 'text' | 'email' | 'password' | 'number';\n required?: boolean;\n placeholder?: string;\n onChange?: (event: MockEvent) => void;\n}\n\n/**\n * Input — label + input の pair、 label[for] で id を関連付ける (a11y label\n * rule を pass する)。 onChange は input event で発火。\n */\nexport const buildInput: ComponentRender<InputArgs> = (args) => {\n const wrapper = createNode('div', { attrs: { class: 'input-group' } });\n const label = createNode('label', {\n attrs: { for: args.id, class: 'input-label' },\n text: args.label,\n });\n const inputAttrs: Record<string, string> = {\n id: args.id,\n name: args.id,\n type: args.type ?? 'text',\n class: 'input-field',\n };\n if (args.required) inputAttrs['required'] = 'true';\n if (args.placeholder) inputAttrs['placeholder'] = args.placeholder;\n const input = createNode('input', {\n attrs: inputAttrs,\n value: args.value ?? '',\n ...(args.onChange ? { on: { input: args.onChange } } : {}),\n });\n appendChild(wrapper, label);\n appendChild(wrapper, input);\n return wrapper;\n};\n\n// ---- Form ----\n\nexport interface FormField {\n id: string;\n label: string;\n type?: InputArgs['type'];\n required?: boolean;\n value?: string;\n}\n\nexport interface FormArgs {\n title: string;\n fields: FormField[];\n submitLabel?: string;\n onSubmit?: (data: Record<string, string>) => void;\n}\n\n/**\n * Form — title + 複数 input + submit button。 submit 時に全 field の value を\n * 集めて onSubmit に渡す。 required field 未入力なら submit を発火しない\n * (validation)、 UI 側で「必須」 表示を出す責務。\n */\nexport const buildForm: ComponentRender<FormArgs> = (args) => {\n const form = createNode('form', {\n attrs: { class: 'form', role: 'form' },\n });\n const heading = createNode('h2', {\n attrs: { class: 'form-title' },\n text: args.title,\n });\n appendChild(form, heading);\n\n const fieldValues = new Map<string, string>();\n for (const field of args.fields) {\n fieldValues.set(field.id, field.value ?? '');\n const wrapper = buildInput({\n id: field.id,\n label: field.label,\n ...(field.type !== undefined ? { type: field.type } : {}),\n ...(field.required !== undefined ? { required: field.required } : {}),\n value: field.value ?? '',\n onChange: (event) => {\n if (event.value !== undefined) {\n fieldValues.set(field.id, event.value);\n }\n },\n });\n appendChild(form, wrapper);\n }\n\n const submit = createNode('button', {\n attrs: {\n type: 'submit',\n class: 'form-submit btn btn-primary',\n },\n text: args.submitLabel ?? 'Submit',\n on: {\n click: () => {\n // required field を確認\n for (const field of args.fields) {\n if (field.required && !fieldValues.get(field.id)) {\n return; // validation fail、 submit 発火せず\n }\n }\n args.onSubmit?.(Object.fromEntries(fieldValues));\n },\n },\n });\n appendChild(form, submit);\n return form;\n};\n\n// ---- Modal ----\n\nexport interface ModalArgs {\n open: boolean;\n title: string;\n body: string;\n onClose?: () => void;\n closeOnBackdrop?: boolean;\n}\n\n/**\n * Modal — open=false なら空 div を返す (closed 状態を表現)。 open=true で\n * backdrop + dialog を組む。 backdrop click / close button click で\n * onClose を発火。\n */\nexport const buildModal: ComponentRender<ModalArgs> = (args) => {\n if (!args.open) {\n return createNode('div', {\n attrs: { class: 'modal modal-closed', 'aria-hidden': 'true' },\n });\n }\n const backdrop = createNode('div', {\n attrs: { class: 'modal-backdrop', role: 'presentation' },\n ...(args.closeOnBackdrop !== false && args.onClose\n ? { on: { click: () => args.onClose?.() } }\n : {}),\n });\n const dialog = createNode('div', {\n attrs: {\n class: 'modal-dialog',\n role: 'dialog',\n 'aria-modal': 'true',\n 'aria-labelledby': 'modal-title',\n },\n });\n const heading = createNode('h2', {\n attrs: { id: 'modal-title', class: 'modal-title' },\n text: args.title,\n });\n const body = createNode('p', {\n attrs: { class: 'modal-body' },\n text: args.body,\n });\n const closeBtn = createNode('button', {\n attrs: {\n type: 'button',\n class: 'modal-close',\n 'aria-label': 'Close',\n },\n text: 'x',\n ...(args.onClose ? { on: { click: () => args.onClose?.() } } : {}),\n });\n appendChild(dialog, heading);\n appendChild(dialog, body);\n appendChild(dialog, closeBtn);\n appendChild(backdrop, dialog);\n return backdrop;\n};\n\n// ---- Card ----\n\nexport interface CardArgs {\n title: string;\n body: string;\n footer?: string;\n variant?: 'default' | 'outlined' | 'elevated';\n}\n\n/**\n * Card — title / body / optional footer の 3 slot。 chromatic diff で variant\n * 別 baseline を持つ用途の代表 pattern。\n */\nexport const buildCard: ComponentRender<CardArgs> = (args) => {\n const variant = args.variant ?? 'default';\n const card = createNode('article', {\n attrs: { class: `card card-${variant}` },\n });\n const heading = createNode('h3', {\n attrs: { class: 'card-title' },\n text: args.title,\n });\n const body = createNode('p', {\n attrs: { class: 'card-body' },\n text: args.body,\n });\n appendChild(card, heading);\n appendChild(card, body);\n if (args.footer) {\n const footer = createNode('footer', {\n attrs: { class: 'card-footer' },\n text: args.footer,\n });\n appendChild(card, footer);\n }\n return card;\n};\n\n/** 全 component の render function を 1 record にまとめる (test 一括登録用)。 */\nexport const componentFixtures: Record<string, ComponentRender<Record<string, unknown>>> = {\n Button: buildButton as unknown as ComponentRender<Record<string, unknown>>,\n Input: buildInput as unknown as ComponentRender<Record<string, unknown>>,\n Form: buildForm as unknown as ComponentRender<Record<string, unknown>>,\n Modal: buildModal as unknown as ComponentRender<Record<string, unknown>>,\n Card: buildCard as unknown as ComponentRender<Record<string, unknown>>,\n};\n\n/** primitive DOM helper の re-export (test / dogfood app 側から直接使う)。 */\nexport { createNode, appendChild } from './dom.js';\nexport type { MockNode };\n","/**\n * Advanced component semantics — target-neutral axis SSOT.\n *\n * The component package spans Storybook 8, Playwright Component Testing, and\n * Chromatic. These helpers model the observable semantics without importing\n * any of those runtimes, so the same axis can be replayed against each target.\n */\nexport type ComponentTarget = 'storybook8' | 'playwright-ct' | 'chromatic';\n\nexport type ComponentAxis =\n | 'rsc-harness'\n | 'streaming-ssr'\n | 'view-transitions'\n | 'form-action-advanced'\n // v1.49 advanced III (pair 第 6 pair 3 段拡張)\n | 'react-19-actions'\n | 'islands-architecture';\n\nexport type NeutralEventName =\n | 'rsc.render_started'\n | 'rsc.suspense_boundary'\n | 'rsc.html_chunk_streamed'\n | 'rsc.render_completed'\n | 'ssr.suspense_pending'\n | 'ssr.error_boundary_captured'\n | 'ssr.progressive_hydration_started'\n | 'ssr.selective_hydration_completed'\n | 'transition.element_started'\n | 'transition.element_finished'\n | 'transition.document_started'\n | 'transition.animation_asserted'\n | 'form.status_pending'\n | 'form.optimistic_applied'\n | 'form.progressive_enhanced'\n | 'form.action_resolved'\n // v1.49 react-19-actions (useActionState + useOptimistic + useFormStatus 統合)\n | 'action.state_initialized'\n | 'action.transition_pending'\n | 'action.optimistic_committed'\n | 'action.resolved'\n // v1.49 islands-architecture (partial hydration + selective interactivity)\n | 'islands.registered'\n | 'islands.hydration_started'\n | 'islands.interactive_ready'\n | 'islands.static_boundary_asserted';\n\nexport interface AxisStep<TState extends string> {\n neutralEvent: NeutralEventName;\n providerEvent: string;\n state: TState;\n amountCents: number;\n metadata: Record<string, string | number | boolean>;\n}\n\nconst dialect: Record<ComponentTarget, Partial<Record<NeutralEventName, string>>> = {\n storybook8: {\n 'rsc.render_started': 'storybook.play.start',\n 'rsc.suspense_boundary': 'storybook.suspense.fallback',\n 'rsc.html_chunk_streamed': 'storybook.stream.chunk',\n 'rsc.render_completed': 'storybook.play.done',\n 'ssr.suspense_pending': 'storybook.suspense.pending',\n 'ssr.error_boundary_captured': 'storybook.error.boundary',\n 'ssr.progressive_hydration_started': 'storybook.hydration.progressive',\n 'ssr.selective_hydration_completed': 'storybook.hydration.selective',\n 'transition.element_started': 'storybook.transition.element.start',\n 'transition.element_finished': 'storybook.transition.element.finish',\n 'transition.document_started': 'storybook.transition.document.start',\n 'transition.animation_asserted': 'storybook.animation.assert',\n 'form.status_pending': 'storybook.form.pending',\n 'form.optimistic_applied': 'storybook.form.optimistic',\n 'form.progressive_enhanced': 'storybook.form.enhanced',\n 'form.action_resolved': 'storybook.form.resolved',\n },\n 'playwright-ct': {\n 'rsc.render_started': 'pwct.mount.rsc.start',\n 'rsc.suspense_boundary': 'pwct.locator.suspense.fallback',\n 'rsc.html_chunk_streamed': 'pwct.response.chunk',\n 'rsc.render_completed': 'pwct.mount.rsc.done',\n 'ssr.suspense_pending': 'pwct.suspense.pending',\n 'ssr.error_boundary_captured': 'pwct.error.boundary',\n 'ssr.progressive_hydration_started': 'pwct.hydration.progressive',\n 'ssr.selective_hydration_completed': 'pwct.hydration.selective',\n 'transition.element_started': 'pwct.transition.element.start',\n 'transition.element_finished': 'pwct.transition.element.finish',\n 'transition.document_started': 'pwct.transition.document.start',\n 'transition.animation_asserted': 'pwct.animation.assert',\n 'form.status_pending': 'pwct.form.pending',\n 'form.optimistic_applied': 'pwct.form.optimistic',\n 'form.progressive_enhanced': 'pwct.form.enhanced',\n 'form.action_resolved': 'pwct.form.resolved',\n },\n chromatic: {\n 'rsc.render_started': 'chromatic.capture.rsc.start',\n 'rsc.suspense_boundary': 'chromatic.capture.suspense',\n 'rsc.html_chunk_streamed': 'chromatic.capture.chunk',\n 'rsc.render_completed': 'chromatic.capture.rsc.done',\n 'ssr.suspense_pending': 'chromatic.suspense.pending',\n 'ssr.error_boundary_captured': 'chromatic.error.snapshot',\n 'ssr.progressive_hydration_started': 'chromatic.hydration.progressive',\n 'ssr.selective_hydration_completed': 'chromatic.hydration.selective',\n 'transition.element_started': 'chromatic.transition.element.start',\n 'transition.element_finished': 'chromatic.transition.element.finish',\n 'transition.document_started': 'chromatic.transition.document.start',\n 'transition.animation_asserted': 'chromatic.animation.assert',\n 'form.status_pending': 'chromatic.form.pending',\n 'form.optimistic_applied': 'chromatic.form.optimistic',\n 'form.progressive_enhanced': 'chromatic.form.enhanced',\n 'form.action_resolved': 'chromatic.form.resolved',\n },\n};\n\nexport function providerEventName(target: ComponentTarget, neutral: NeutralEventName): string {\n return dialect[target][neutral] ?? neutral;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type RscHarnessState = 'idle' | 'rendering' | 'suspended' | 'streaming' | 'completed' | 'errored';\n\nexport interface RscHarnessSession {\n target: ComponentTarget;\n componentId: string;\n state: RscHarnessState;\n chunks: string[];\n suspenseFallback: string | null;\n history: AxisStep<RscHarnessState>[];\n error: string | null;\n}\n\nexport function startRscHarness(input: {\n target: ComponentTarget;\n componentId: string;\n suspenseFallback?: string;\n}): RscHarnessSession {\n if (input.componentId.length === 0) {\n throw new Error('startRscHarness: componentId must not be empty');\n }\n return {\n target: input.target,\n componentId: input.componentId,\n state: 'idle',\n chunks: [],\n suspenseFallback: input.suspenseFallback ?? null,\n history: [],\n error: null,\n };\n}\n\nexport function beginRscRender(session: RscHarnessSession): AxisStep<RscHarnessState> {\n if (session.state !== 'idle') {\n throw new Error(`beginRscRender: session is ${session.state}, not idle`);\n }\n session.state = 'rendering';\n return emit(session, 'rsc.render_started', { componentId: session.componentId });\n}\n\nexport function enterSuspenseBoundary(\n session: RscHarnessSession,\n fallback: string = session.suspenseFallback ?? '<template data-suspense=\"pending\"></template>',\n): AxisStep<RscHarnessState> {\n if (session.state !== 'rendering') {\n throw new Error(`enterSuspenseBoundary: session is ${session.state}, not rendering`);\n }\n session.state = 'suspended';\n session.suspenseFallback = fallback;\n return emit(session, 'rsc.suspense_boundary', { fallback });\n}\n\nexport function streamHtmlChunk(\n session: RscHarnessSession,\n chunk: string,\n): AxisStep<RscHarnessState> {\n if (session.state !== 'rendering' && session.state !== 'suspended' && session.state !== 'streaming') {\n throw new Error(`streamHtmlChunk: session is ${session.state}, cannot stream`);\n }\n if (chunk.length === 0) {\n throw new Error('streamHtmlChunk: chunk must not be empty');\n }\n session.state = 'streaming';\n session.chunks.push(chunk);\n return emit(session, 'rsc.html_chunk_streamed', {\n chunk,\n chunkIndex: session.chunks.length - 1,\n bytes: chunk.length,\n });\n}\n\nexport function completeRscRender(session: RscHarnessSession): AxisStep<RscHarnessState> {\n if (session.state !== 'rendering' && session.state !== 'suspended' && session.state !== 'streaming') {\n throw new Error(`completeRscRender: session is ${session.state}, cannot complete`);\n }\n session.state = 'completed';\n return emit(session, 'rsc.render_completed', {\n chunkCount: session.chunks.length,\n html: session.chunks.join(''),\n });\n}\n\nexport function failRscRender(\n session: RscHarnessSession,\n error: Error | string,\n): AxisStep<RscHarnessState> {\n if (session.state === 'completed') {\n throw new Error('failRscRender: completed session cannot fail');\n }\n session.state = 'errored';\n session.error = typeof error === 'string' ? error : error.message;\n return emit(session, 'ssr.error_boundary_captured', {\n componentId: session.componentId,\n error: session.error,\n });\n}\n\nfunction emit(\n session: RscHarnessSession,\n neutralEvent: AxisStep<RscHarnessState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<RscHarnessState> {\n const step: AxisStep<RscHarnessState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type StreamingSsrState =\n | 'idle'\n | 'suspense-pending'\n | 'error-captured'\n | 'progressive-hydrating'\n | 'selective-hydrated';\n\nexport interface StreamingSsrSession {\n target: ComponentTarget;\n routeId: string;\n state: StreamingSsrState;\n pendingBoundaries: Set<string>;\n hydratedBoundaries: Set<string>;\n errors: Array<{ boundaryId: string; message: string }>;\n history: AxisStep<StreamingSsrState>[];\n}\n\nexport function startStreamingSsr(input: {\n target: ComponentTarget;\n routeId: string;\n}): StreamingSsrSession {\n if (input.routeId.length === 0) {\n throw new Error('startStreamingSsr: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n state: 'idle',\n pendingBoundaries: new Set(),\n hydratedBoundaries: new Set(),\n errors: [],\n history: [],\n };\n}\n\nexport function markSuspensePending(\n session: StreamingSsrSession,\n boundaryId: string,\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(boundaryId);\n session.state = 'suspense-pending';\n session.pendingBoundaries.add(boundaryId);\n return emit(session, 'ssr.suspense_pending', { boundaryId, pendingCount: session.pendingBoundaries.size });\n}\n\nexport function captureErrorBoundary(\n session: StreamingSsrSession,\n input: { boundaryId: string; error: Error | string; recoverable?: boolean },\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(input.boundaryId);\n const message = typeof input.error === 'string' ? input.error : input.error.message;\n session.state = 'error-captured';\n session.errors.push({ boundaryId: input.boundaryId, message });\n if (input.recoverable === false) {\n session.pendingBoundaries.delete(input.boundaryId);\n }\n return emit(session, 'ssr.error_boundary_captured', {\n boundaryId: input.boundaryId,\n message,\n recoverable: input.recoverable ?? true,\n });\n}\n\nexport function startProgressiveHydration(\n session: StreamingSsrSession,\n boundaryId: string,\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(boundaryId);\n if (!session.pendingBoundaries.has(boundaryId)) {\n throw new Error(`startProgressiveHydration: ${boundaryId} is not pending`);\n }\n session.state = 'progressive-hydrating';\n return emit(session, 'ssr.progressive_hydration_started', { boundaryId });\n}\n\nexport function completeSelectiveHydration(\n session: StreamingSsrSession,\n boundaryId: string,\n): AxisStep<StreamingSsrState> {\n assertBoundaryId(boundaryId);\n if (!session.pendingBoundaries.has(boundaryId)) {\n throw new Error(`completeSelectiveHydration: ${boundaryId} is not pending`);\n }\n session.pendingBoundaries.delete(boundaryId);\n session.hydratedBoundaries.add(boundaryId);\n session.state = 'selective-hydrated';\n return emit(session, 'ssr.selective_hydration_completed', {\n boundaryId,\n hydratedCount: session.hydratedBoundaries.size,\n remainingPending: session.pendingBoundaries.size,\n });\n}\n\nfunction assertBoundaryId(boundaryId: string): void {\n if (boundaryId.length === 0) {\n throw new Error('boundaryId must not be empty');\n }\n}\n\nfunction emit(\n session: StreamingSsrSession,\n neutralEvent: AxisStep<StreamingSsrState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<StreamingSsrState> {\n const step: AxisStep<StreamingSsrState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, routeId: session.routeId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type ViewTransitionState =\n | 'idle'\n | 'element-transitioning'\n | 'document-transitioning'\n | 'asserted'\n | 'finished';\n\nexport interface ViewTransitionSession {\n target: ComponentTarget;\n transitionId: string;\n state: ViewTransitionState;\n activeElements: Set<string>;\n documentTransition: string | null;\n assertions: string[];\n history: AxisStep<ViewTransitionState>[];\n}\n\nexport function startViewTransitionSession(input: {\n target: ComponentTarget;\n transitionId: string;\n}): ViewTransitionSession {\n if (input.transitionId.length === 0) {\n throw new Error('startViewTransitionSession: transitionId must not be empty');\n }\n return {\n target: input.target,\n transitionId: input.transitionId,\n state: 'idle',\n activeElements: new Set(),\n documentTransition: null,\n assertions: [],\n history: [],\n };\n}\n\nexport function startElementTransition(\n session: ViewTransitionSession,\n input: { elementId: string; from: string; to: string },\n): AxisStep<ViewTransitionState> {\n if (input.elementId.length === 0) {\n throw new Error('startElementTransition: elementId must not be empty');\n }\n session.state = 'element-transitioning';\n session.activeElements.add(input.elementId);\n return emit(session, 'transition.element_started', input);\n}\n\nexport function finishElementTransition(\n session: ViewTransitionSession,\n elementId: string,\n): AxisStep<ViewTransitionState> {\n if (!session.activeElements.has(elementId)) {\n throw new Error(`finishElementTransition: ${elementId} is not active`);\n }\n session.activeElements.delete(elementId);\n session.state = session.activeElements.size === 0 ? 'finished' : 'element-transitioning';\n return emit(session, 'transition.element_finished', {\n elementId,\n remaining: session.activeElements.size,\n });\n}\n\nexport function startDocumentTransition(\n session: ViewTransitionSession,\n input: { name: string; fromUrl: string; toUrl: string },\n): AxisStep<ViewTransitionState> {\n if (input.name.length === 0) {\n throw new Error('startDocumentTransition: name must not be empty');\n }\n session.state = 'document-transitioning';\n session.documentTransition = input.name;\n return emit(session, 'transition.document_started', input);\n}\n\nexport function assertAnimation(\n session: ViewTransitionSession,\n input: { assertionId: string; durationMs: number; easing?: string },\n): AxisStep<ViewTransitionState> {\n if (input.durationMs < 0) {\n throw new Error('assertAnimation: durationMs must be >= 0');\n }\n session.state = 'asserted';\n session.assertions.push(input.assertionId);\n return emit(session, 'transition.animation_asserted', {\n assertionId: input.assertionId,\n durationMs: input.durationMs,\n easing: input.easing ?? 'linear',\n });\n}\n\nfunction emit(\n session: ViewTransitionSession,\n neutralEvent: AxisStep<ViewTransitionState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ViewTransitionState> {\n const step: AxisStep<ViewTransitionState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, transitionId: session.transitionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\nexport type FormActionState = 'idle' | 'pending' | 'optimistic' | 'enhanced' | 'resolved' | 'rejected';\n\nexport interface FormActionSession<TForm extends Record<string, unknown> = Record<string, unknown>> {\n target: ComponentTarget;\n formId: string;\n state: FormActionState;\n form: TForm;\n optimisticPatches: Array<Partial<TForm>>;\n enhanced: boolean;\n history: AxisStep<FormActionState>[];\n error: string | null;\n}\n\nexport function startFormActionSession<TForm extends Record<string, unknown>>(input: {\n target: ComponentTarget;\n formId: string;\n initial: TForm;\n}): FormActionSession<TForm> {\n if (input.formId.length === 0) {\n throw new Error('startFormActionSession: formId must not be empty');\n }\n return {\n target: input.target,\n formId: input.formId,\n state: 'idle',\n form: { ...input.initial },\n optimisticPatches: [],\n enhanced: false,\n history: [],\n error: null,\n };\n}\n\nexport function markFormStatusPending<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n submitter: string,\n): AxisStep<FormActionState> {\n if (session.state === 'pending') {\n throw new Error('markFormStatusPending: form is already pending');\n }\n session.state = 'pending';\n return emit(session, 'form.status_pending', { submitter });\n}\n\nexport function applyOptimisticUpdate<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n patch: Partial<TForm>,\n): AxisStep<FormActionState> {\n if (session.state !== 'pending' && session.state !== 'optimistic') {\n throw new Error(`applyOptimisticUpdate: session is ${session.state}, not pending`);\n }\n session.state = 'optimistic';\n session.optimisticPatches.push(patch);\n session.form = { ...session.form, ...patch };\n return emit(session, 'form.optimistic_applied', {\n patchKeys: Object.keys(patch).join(','),\n patchCount: session.optimisticPatches.length,\n });\n}\n\nexport function enableProgressiveEnhancement<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n input: { method?: 'post' | 'get'; actionUrl: string },\n): AxisStep<FormActionState> {\n if (input.actionUrl.length === 0) {\n throw new Error('enableProgressiveEnhancement: actionUrl must not be empty');\n }\n session.enhanced = true;\n session.state = 'enhanced';\n return emit(session, 'form.progressive_enhanced', {\n method: input.method ?? 'post',\n actionUrl: input.actionUrl,\n });\n}\n\nexport function resolveFormAction<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n result: Partial<TForm>,\n): AxisStep<FormActionState> {\n if (session.state === 'idle') {\n throw new Error('resolveFormAction: action was not submitted');\n }\n session.state = 'resolved';\n session.form = { ...session.form, ...result };\n return emit(session, 'form.action_resolved', {\n resultKeys: Object.keys(result).join(','),\n enhanced: session.enhanced,\n });\n}\n\nexport function rejectFormAction<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n error: Error | string,\n): AxisStep<FormActionState> {\n if (session.state === 'resolved') {\n throw new Error('rejectFormAction: resolved action cannot reject');\n }\n session.state = 'rejected';\n session.error = typeof error === 'string' ? error : error.message;\n return emit(session, 'form.action_resolved', {\n rejected: true,\n error: session.error,\n });\n}\n\nfunction emit<TForm extends Record<string, unknown>>(\n session: FormActionSession<TForm>,\n neutralEvent: AxisStep<FormActionState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<FormActionState> {\n const step: AxisStep<FormActionState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, formId: session.formId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type ComponentAxis, type ComponentTarget, type NeutralEventName } from './types.js';\n\nexport interface FidelityRow {\n provider: ComponentTarget;\n axis: ComponentAxis;\n neutralEvents: NeutralEventName[];\n providerEvents: string[];\n}\n\nexport interface FidelityCoverage {\n providers: ComponentTarget[];\n axes: ComponentAxis[];\n rows: FidelityRow[];\n}\n\nexport const COMPONENT_AXIS_TO_EVENTS: Record<ComponentAxis, NeutralEventName[]> = {\n 'rsc-harness': [\n 'rsc.render_started',\n 'rsc.suspense_boundary',\n 'rsc.html_chunk_streamed',\n 'rsc.render_completed',\n ],\n 'streaming-ssr': [\n 'ssr.suspense_pending',\n 'ssr.error_boundary_captured',\n 'ssr.progressive_hydration_started',\n 'ssr.selective_hydration_completed',\n ],\n 'view-transitions': [\n 'transition.element_started',\n 'transition.element_finished',\n 'transition.document_started',\n 'transition.animation_asserted',\n ],\n 'form-action-advanced': [\n 'form.status_pending',\n 'form.optimistic_applied',\n 'form.progressive_enhanced',\n 'form.action_resolved',\n ],\n // v1.49 advanced III\n 'react-19-actions': [\n 'action.state_initialized',\n 'action.transition_pending',\n 'action.optimistic_committed',\n 'action.resolved',\n ],\n 'islands-architecture': [\n 'islands.registered',\n 'islands.hydration_started',\n 'islands.interactive_ready',\n 'islands.static_boundary_asserted',\n ],\n};\n\nexport function collectFidelityCoverage(\n providers: ComponentTarget[] = ['storybook8', 'playwright-ct', 'chromatic'],\n): FidelityCoverage {\n const axes = Object.keys(COMPONENT_AXIS_TO_EVENTS) as ComponentAxis[];\n const rows: FidelityRow[] = [];\n for (const provider of providers) {\n for (const axis of axes) {\n const neutralEvents = COMPONENT_AXIS_TO_EVENTS[axis];\n rows.push({\n provider,\n axis,\n neutralEvents,\n providerEvents: neutralEvents.map((event) => providerEventName(provider, event)),\n });\n }\n }\n return { providers, axes, rows };\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\n/**\n * v1.49 react-19-actions axis — useActionState + useOptimistic + useFormStatus\n * を統合した React 19 Actions API の deterministic state machine。\n */\nexport type ReactActionsState =\n | 'idle'\n | 'transition-pending'\n | 'optimistic-committed'\n | 'resolved';\n\nexport interface ReactActionsSession {\n target: ComponentTarget;\n actionId: string;\n state: ReactActionsState;\n pendingCount: number;\n optimisticValues: string[];\n resolvedValue: string | null;\n history: AxisStep<ReactActionsState>[];\n}\n\nfunction emit(\n session: ReactActionsSession,\n neutralEvent:\n | 'action.state_initialized'\n | 'action.transition_pending'\n | 'action.optimistic_committed'\n | 'action.resolved',\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ReactActionsState> {\n const step: AxisStep<ReactActionsState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { actionId: session.actionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n\nexport function initializeReactActions(input: {\n target: ComponentTarget;\n actionId: string;\n}): ReactActionsSession {\n if (input.actionId.length === 0) {\n throw new Error('initializeReactActions: actionId must not be empty');\n }\n const session: ReactActionsSession = {\n target: input.target,\n actionId: input.actionId,\n state: 'idle',\n pendingCount: 0,\n optimisticValues: [],\n resolvedValue: null,\n history: [],\n };\n emit(session, 'action.state_initialized', { pendingCount: 0 });\n return session;\n}\n\nexport function beginActionTransition(\n session: ReactActionsSession,\n): AxisStep<ReactActionsState> {\n if (session.state !== 'idle' && session.state !== 'resolved') {\n throw new Error(`beginActionTransition: session is ${session.state}`);\n }\n session.state = 'transition-pending';\n session.pendingCount += 1;\n return emit(session, 'action.transition_pending', {\n pendingCount: session.pendingCount,\n });\n}\n\nexport function applyOptimisticUpdate(\n session: ReactActionsSession,\n optimisticValue: string,\n): AxisStep<ReactActionsState> {\n if (session.state !== 'transition-pending') {\n throw new Error(`applyOptimisticUpdate: session is ${session.state}`);\n }\n session.state = 'optimistic-committed';\n session.optimisticValues.push(optimisticValue);\n return emit(session, 'action.optimistic_committed', { optimisticValue });\n}\n\nexport function resolveAction(\n session: ReactActionsSession,\n resolvedValue: string,\n): AxisStep<ReactActionsState> {\n if (session.state !== 'transition-pending' && session.state !== 'optimistic-committed') {\n throw new Error(`resolveAction: session is ${session.state}`);\n }\n session.state = 'resolved';\n session.resolvedValue = resolvedValue;\n session.pendingCount = Math.max(0, session.pendingCount - 1);\n return emit(session, 'action.resolved', {\n resolvedValue,\n pendingCount: session.pendingCount,\n optimisticCount: session.optimisticValues.length,\n });\n}\n","import { providerEventName, type AxisStep, type ComponentTarget } from './types.js';\n\n/**\n * v1.49 islands-architecture axis — Astro / Deno Fresh / Solid Start の\n * Islands architecture (partial hydration + selective interactivity) を\n * target-neutral に扱う state machine。\n */\nexport type IslandsState =\n | 'idle'\n | 'registered'\n | 'hydrating'\n | 'interactive'\n | 'static-verified';\n\nexport interface IslandSpec {\n islandId: string;\n loadStrategy: 'load' | 'idle' | 'visible' | 'media' | 'only';\n interactiveBoundary: boolean;\n}\n\nexport interface IslandsSession {\n target: ComponentTarget;\n routeId: string;\n islands: IslandSpec[];\n state: IslandsState;\n hydratedIslandIds: string[];\n staticBoundaryIds: string[];\n history: AxisStep<IslandsState>[];\n}\n\nfunction emit(\n session: IslandsSession,\n neutralEvent:\n | 'islands.registered'\n | 'islands.hydration_started'\n | 'islands.interactive_ready'\n | 'islands.static_boundary_asserted',\n metadata: Record<string, string | number | boolean>,\n): AxisStep<IslandsState> {\n const step: AxisStep<IslandsState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { routeId: session.routeId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n\nexport function bootstrapIslandsRoute(input: {\n target: ComponentTarget;\n routeId: string;\n}): IslandsSession {\n if (input.routeId.length === 0) {\n throw new Error('bootstrapIslandsRoute: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n islands: [],\n state: 'idle',\n hydratedIslandIds: [],\n staticBoundaryIds: [],\n history: [],\n };\n}\n\nexport function registerIsland(\n session: IslandsSession,\n island: IslandSpec,\n): AxisStep<IslandsState> {\n session.islands.push(island);\n session.state = 'registered';\n return emit(session, 'islands.registered', {\n islandId: island.islandId,\n loadStrategy: island.loadStrategy,\n interactiveBoundary: island.interactiveBoundary,\n });\n}\n\nexport function beginIslandHydration(\n session: IslandsSession,\n islandId: string,\n): AxisStep<IslandsState> {\n const island = session.islands.find((i) => i.islandId === islandId);\n if (!island) {\n throw new Error(`beginIslandHydration: island ${islandId} not registered`);\n }\n if (session.state !== 'registered' && session.state !== 'hydrating') {\n throw new Error(`beginIslandHydration: session is ${session.state}`);\n }\n session.state = 'hydrating';\n return emit(session, 'islands.hydration_started', {\n islandId,\n loadStrategy: island.loadStrategy,\n });\n}\n\nexport function markIslandInteractive(\n session: IslandsSession,\n islandId: string,\n): AxisStep<IslandsState> {\n if (session.state !== 'hydrating') {\n throw new Error(`markIslandInteractive: session is ${session.state}`);\n }\n if (session.hydratedIslandIds.includes(islandId)) {\n throw new Error(`markIslandInteractive: island ${islandId} already interactive`);\n }\n session.hydratedIslandIds.push(islandId);\n const allHydrated = session.hydratedIslandIds.length === session.islands.filter((i) => i.interactiveBoundary).length;\n if (allHydrated) {\n session.state = 'interactive';\n }\n return emit(session, 'islands.interactive_ready', {\n islandId,\n hydratedCount: session.hydratedIslandIds.length,\n allInteractiveReady: allHydrated,\n });\n}\n\nexport function assertStaticBoundary(\n session: IslandsSession,\n boundaryId: string,\n): AxisStep<IslandsState> {\n if (session.staticBoundaryIds.includes(boundaryId)) {\n throw new Error(`assertStaticBoundary: boundary ${boundaryId} already asserted`);\n }\n session.staticBoundaryIds.push(boundaryId);\n if (session.state === 'interactive') {\n session.state = 'static-verified';\n }\n return emit(session, 'islands.static_boundary_asserted', {\n boundaryId,\n staticBoundaryCount: session.staticBoundaryIds.length,\n });\n}\n","import type { ComponentTarget } from './semantics/types.js';\n\nexport type KiwaTestMode = 'mock' | 'real';\n\nexport interface ResolvedMode {\n mode: KiwaTestMode;\n provider: ComponentTarget;\n reason: 'default-mock' | 'kiwa-mode-real' | 'missing-key' | 'invalid-mode';\n}\n\nconst TARGET_KEY_ENV: Record<ComponentTarget, string> = {\n storybook8: 'STORYBOOK_URL',\n 'playwright-ct': 'PLAYWRIGHT_CT_URL',\n chromatic: 'CHROMATIC_TOKEN',\n};\n\nexport function resolveMode(\n provider: ComponentTarget,\n env: Record<string, string | undefined> = process.env,\n): ResolvedMode {\n const rawMode = env.KIWA_MODE?.toLowerCase();\n if (rawMode !== undefined && rawMode !== 'real' && rawMode !== 'mock') {\n return { provider, mode: 'mock', reason: 'invalid-mode' };\n }\n if (rawMode !== 'real') {\n return { provider, mode: 'mock', reason: 'default-mock' };\n }\n const keyValue = env[TARGET_KEY_ENV[provider]];\n if (typeof keyValue !== 'string' || keyValue.length === 0) {\n return { provider, mode: 'mock', reason: 'missing-key' };\n }\n return { provider, mode: 'real', reason: 'kiwa-mode-real' };\n}\n\nexport function resolveAllModes(\n env: Record<string, string | undefined> = process.env,\n): ResolvedMode[] {\n const providers: ComponentTarget[] = ['storybook8', 'playwright-ct', 'chromatic'];\n return providers.map((provider) => resolveMode(provider, env));\n}\n\nexport function assertMode(\n provider: ComponentTarget,\n expected: KiwaTestMode,\n env: Record<string, string | undefined> = process.env,\n): void {\n const resolved = resolveMode(provider, env);\n if (resolved.mode !== expected) {\n throw new Error(\n `expected ${provider} in ${expected} mode but resolved ${resolved.mode} (${resolved.reason})`,\n );\n }\n}\n"],"mappings":"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","names":["nodeText","emit","emit","emit","emit","applyOptimisticUpdate","emit"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kiwa-test/component",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Component test mock harness for kiwa — unified Storybook 8 + Playwright Component Testing + Chromatic mocks with story registration, args resolution, play function runner, mount + interact API, and visual regression baseline/diff/accept workflow.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@kiwa-test/core": "1.0.1",
|
|
59
|
-
"@kiwa-test/quality-metrics": "0.
|
|
59
|
+
"@kiwa-test/quality-metrics": "0.4.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@stryker-mutator/core": "^8.7.1",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"tsup": "^8.3.0",
|
|
66
66
|
"typescript": "^5.6.0",
|
|
67
67
|
"vitest": "^2.1.0",
|
|
68
|
-
"@kiwa-test/perf-harness": "0.
|
|
68
|
+
"@kiwa-test/perf-harness": "0.3.0"
|
|
69
69
|
},
|
|
70
70
|
"scripts": {
|
|
71
71
|
"build": "tsup",
|