@kiwa-test/nextjs 1.2.0 → 1.3.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/invoke-server-action.ts","../src/invoke-middleware.ts","../src/render-server-component.ts","../src/invoke-parallel-routes.ts","../src/setup-next-rsc-env.ts","../src/semantics/types.ts","../src/semantics/server-action-advanced.ts","../src/semantics/partial-prerendering.ts","../src/semantics/interception-routes.ts","../src/semantics/parallel-routes-advanced.ts","../src/semantics/fidelity.ts","../src/real-driver.ts"],"sourcesContent":["export {\n invokeServerAction,\n type ServerActionFunction,\n type ServerActionResult,\n type ServerActionInvocation,\n type ServerActionEnv,\n type CookieJar,\n REDIRECT_SYMBOL,\n type RedirectSignal,\n} from './invoke-server-action.js';\n\nexport {\n invokeMiddleware,\n middlewareActions,\n MIDDLEWARE_ACTION_SYMBOL,\n type InvokeMiddlewareOptions,\n type InvokeMiddlewareResult,\n type MiddlewareFunction,\n type MiddlewareRequest,\n type MiddlewareEnv,\n type MiddlewareAction,\n type MiddlewareActionKind,\n} from './invoke-middleware.js';\n\nexport {\n renderServerComponent,\n findAll,\n textContent,\n NOT_FOUND_SYMBOL,\n FORBIDDEN_SYMBOL,\n RSC_REDIRECT_SYMBOL,\n type RenderServerComponentOptions,\n type RenderServerComponentResult,\n type RscElement,\n type RscNode,\n type RscSignal,\n type NotFoundSignal,\n type ForbiddenSignal,\n type RscRedirectSignal,\n} from './render-server-component.js';\n\nexport {\n invokeParallelRoutes,\n PARALLEL_INTERCEPTION_SYMBOL,\n type InvokeParallelRoutesOptions,\n type InvokeParallelRoutesResult,\n type ParallelLayoutFunction,\n type ParallelLayoutChildren,\n type SlotComponent,\n type SlotInput,\n type SlotRenderResult,\n type DefaultFallbackComponent,\n type InterceptionMatch,\n} from './invoke-parallel-routes.js';\n\nexport {\n setupNextRscEnv,\n RSC_ERROR_BOUNDARY_SYMBOL,\n type SetupNextRscEnvOptions,\n type SetupNextRscEnvResult,\n type RscStreamSource,\n type RscErrorBoundarySignal,\n} from './setup-next-rsc-env.js';\n\nexport * from './semantics/index.js';\nexport {\n assertMode,\n resolveAllModes,\n resolveMode,\n type KiwaTestMode,\n type ResolvedMode,\n} from './real-driver.js';\n","// Next.js Server Action invocation helper for kiwa tests.\n//\n// Wraps an `'use server'` async function and captures Next.js side-effects\n// (redirect / revalidatePath / cookies set) without requiring a real Next.js\n// runtime. The test calls `invokeServerAction({ action, formData, ... })`\n// and asserts on the returned `ServerActionResult` instead of relying on\n// integration-level behavior.\n//\n// Out of scope on purpose:\n// - real `next/server` middleware semantics (use #495 helper instead)\n// - RSC payload format (use #494 helper instead)\n// - rendering a page after the action (use Playwright + `/kiwa-e2e` for that)\n\nexport const REDIRECT_SYMBOL = Symbol.for('kiwa.next.redirect');\n\nexport interface RedirectSignal {\n readonly [REDIRECT_SYMBOL]: true;\n readonly url: string;\n readonly type: 'replace' | 'push';\n}\n\nexport interface CookieJar {\n get(name: string): string | undefined;\n set(name: string, value: string, options?: Record<string, unknown>): void;\n delete(name: string): void;\n entries(): Array<[string, string]>;\n}\n\nexport interface ServerActionEnv {\n readonly cookies: CookieJar;\n readonly headers: Map<string, string>;\n readonly revalidated: { paths: string[]; tags: string[] };\n readonly redirect: RedirectSignal | null;\n}\n\n// We deliberately accept `any[]` here so callers can pass typed actions like\n// `(fd: FormData) => Promise<T>` or `(prev: State, fd: FormData) => Promise<T>`\n// without contortions. The runtime always invokes `action(formData, ...args)`.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ServerActionFunction<TResult> = (...args: any[]) => Promise<TResult> | TResult;\n\nexport interface ServerActionInvocation<TResult> {\n /** The `'use server'` async function under test. */\n readonly action: ServerActionFunction<TResult>;\n /** Optional FormData first argument (default empty). */\n readonly formData?: FormData;\n /** Extra positional args appended after FormData (e.g. previous state for useFormState). */\n readonly args?: unknown[];\n /** Initial cookie jar entries (name → value). */\n readonly cookies?: Record<string, string>;\n /** Initial request headers (case-insensitive). */\n readonly headers?: Record<string, string>;\n}\n\nexport interface ServerActionResult<TResult> {\n /** Resolved return value (or `undefined` if the action threw a redirect signal). */\n readonly result: TResult | undefined;\n /** Error thrown by the action (excluding redirect signals which are normalized). */\n readonly error: unknown;\n /** Side-effects captured during the invocation. */\n readonly env: ServerActionEnv;\n}\n\nfunction createCookieJar(initial: Record<string, string>): CookieJar {\n const store = new Map<string, string>(Object.entries(initial));\n return {\n get(name) {\n return store.get(name);\n },\n set(name, value) {\n store.set(name, value);\n },\n delete(name) {\n store.delete(name);\n },\n entries() {\n return Array.from(store.entries());\n },\n };\n}\n\nfunction isRedirectSignal(value: unknown): value is RedirectSignal {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { [REDIRECT_SYMBOL]?: true })[REDIRECT_SYMBOL] === true\n );\n}\n\n/**\n * Invoke a Next.js Server Action in isolation and capture its side-effects.\n *\n * The action is called as `await action(formData, ...args)`. The kiwa helper\n * does NOT monkey-patch global `next/navigation` / `next/headers` / `next/cache`\n * imports. Instead the action under test should accept its dependencies via\n * an injectable seam (a parameter or a module-level setter) so tests stay\n * deterministic. See `examples/nextjs-server-actions-poc/` for the pattern.\n */\nexport async function invokeServerAction<TResult>(\n opts: ServerActionInvocation<TResult>,\n): Promise<ServerActionResult<TResult>> {\n const headers = new Map<string, string>();\n for (const [name, value] of Object.entries(opts.headers ?? {})) {\n headers.set(name.toLowerCase(), value);\n }\n const env: ServerActionEnv = {\n cookies: createCookieJar(opts.cookies ?? {}),\n headers,\n revalidated: { paths: [], tags: [] },\n redirect: null,\n };\n const callArgs: unknown[] = [opts.formData ?? new FormData(), ...(opts.args ?? [])];\n let result: TResult | undefined;\n let error: unknown;\n try {\n result = await opts.action(...callArgs);\n } catch (caught) {\n if (isRedirectSignal(caught)) {\n (env as { redirect: RedirectSignal | null }).redirect = caught;\n } else {\n error = caught;\n }\n }\n return { result, error, env };\n}\n","// Next.js middleware.ts invocation helper for kiwa tests (Issue #495).\n//\n// Middleware in App Router is `(req: NextRequest) => NextResponse | Response | void`.\n// It can set response headers / cookies, throw redirect via NextResponse.redirect(),\n// rewrite via NextResponse.rewrite(), short-circuit with NextResponse.json(), or\n// pass through with NextResponse.next(). kiwa wraps the call so unit tests can\n// assert on the captured action + outgoing headers/cookies without a running\n// Next.js server.\n//\n// Out of scope on purpose:\n// - matcher config evaluation (the test already knows which middleware to call)\n// - revalidate / cache header semantics\n// - Edge runtime polyfill (use Node test environment + the helper's simulated request)\n\nexport const MIDDLEWARE_ACTION_SYMBOL = Symbol.for('kiwa.next.middleware.action');\n\nexport type MiddlewareActionKind = 'next' | 'redirect' | 'rewrite' | 'json' | 'noop';\n\nexport interface MiddlewareAction {\n readonly [MIDDLEWARE_ACTION_SYMBOL]: true;\n readonly kind: MiddlewareActionKind;\n readonly url?: string;\n readonly body?: unknown;\n readonly status?: number;\n}\n\nexport interface MiddlewareRequest {\n readonly url: string;\n readonly method: string;\n readonly headers: ReadonlyMap<string, string>;\n readonly cookies: ReadonlyMap<string, string>;\n readonly nextUrl: {\n readonly pathname: string;\n readonly search: string;\n readonly searchParams: URLSearchParams;\n };\n readonly geo: {\n readonly country?: string;\n readonly region?: string;\n readonly city?: string;\n };\n}\n\nexport interface MiddlewareEnv {\n readonly responseHeaders: Map<string, string>;\n readonly responseCookies: Map<string, string>;\n readonly action: MiddlewareAction;\n}\n\nexport type MiddlewareFunction = (\n req: MiddlewareRequest,\n env: { setHeader: (name: string, value: string) => void; setCookie: (name: string, value: string) => void },\n) => MiddlewareAction | Promise<MiddlewareAction>;\n\nexport interface InvokeMiddlewareOptions {\n readonly middleware: MiddlewareFunction;\n readonly url: string;\n readonly method?: string;\n readonly headers?: Record<string, string>;\n readonly cookies?: Record<string, string>;\n readonly geo?: {\n readonly country?: string;\n readonly region?: string;\n readonly city?: string;\n };\n}\n\nexport interface InvokeMiddlewareResult {\n readonly env: MiddlewareEnv;\n readonly error: unknown;\n}\n\nfunction buildRequest(opts: InvokeMiddlewareOptions): MiddlewareRequest {\n const url = new URL(opts.url);\n const headers = new Map<string, string>();\n for (const [name, value] of Object.entries(opts.headers ?? {})) {\n headers.set(name.toLowerCase(), value);\n }\n const cookies = new Map<string, string>(Object.entries(opts.cookies ?? {}));\n return {\n url: opts.url,\n method: opts.method ?? 'GET',\n headers,\n cookies,\n nextUrl: {\n pathname: url.pathname,\n search: url.search,\n searchParams: url.searchParams,\n },\n geo: opts.geo ?? {},\n };\n}\n\n/**\n * Helpers your `middleware.ts` returns instead of constructing NextResponse\n * directly. Keep the production code shape close by re-exporting these from\n * a shared module; the helper expects the returned value to be a\n * MiddlewareAction shaped object.\n */\nexport const middlewareActions = {\n next(): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'next' };\n },\n redirect(url: string, status = 307): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'redirect', url, status };\n },\n rewrite(url: string): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'rewrite', url };\n },\n json(body: unknown, status = 200): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'json', body, status };\n },\n};\n\n/**\n * Invoke a middleware function in isolation and capture its outgoing\n * response shape + headers + cookies. Mirrors the kiwa style of\n * invokeServerAction: no globals, no real Next.js runtime.\n */\nexport async function invokeMiddleware(opts: InvokeMiddlewareOptions): Promise<InvokeMiddlewareResult> {\n const req = buildRequest(opts);\n const responseHeaders = new Map<string, string>();\n const responseCookies = new Map<string, string>();\n const seam = {\n setHeader(name: string, value: string) {\n responseHeaders.set(name.toLowerCase(), value);\n },\n setCookie(name: string, value: string) {\n responseCookies.set(name, value);\n },\n };\n let action: MiddlewareAction = middlewareActions.next();\n let error: unknown;\n try {\n const result = await opts.middleware(req, seam);\n action = result;\n } catch (caught) {\n error = caught;\n action = { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'noop' };\n }\n return {\n env: {\n responseHeaders,\n responseCookies,\n action,\n },\n error,\n };\n}\n","// Next.js async React Server Component (RSC) test helper for kiwa (Issue #494).\n//\n// Real RSC rendering involves a streaming runtime + a flight payload format\n// that requires `vitest-environment-rsc` or a Next.js dev server. kiwa takes\n// a lighter approach: treat the async server component as `async (props) =>\n// JSX.Element` and await it directly. The returned React element tree is\n// inspected with a small finder API instead of a full DOM.\n//\n// Out of scope:\n// - flight payload serialization\n// - client component boundary (`'use client'`)\n// - suspense streaming (synchronous resolution only)\n// - dangerous HTML rendering — tests assert on element shape, not strings\n\nexport const NOT_FOUND_SYMBOL = Symbol.for('kiwa.next.rsc.notFound');\nexport const FORBIDDEN_SYMBOL = Symbol.for('kiwa.next.rsc.forbidden');\nexport const RSC_REDIRECT_SYMBOL = Symbol.for('kiwa.next.rsc.redirect');\n\nexport interface NotFoundSignal {\n readonly [NOT_FOUND_SYMBOL]: true;\n}\nexport interface ForbiddenSignal {\n readonly [FORBIDDEN_SYMBOL]: true;\n}\nexport interface RscRedirectSignal {\n readonly [RSC_REDIRECT_SYMBOL]: true;\n readonly url: string;\n readonly type: 'replace' | 'push';\n}\n\nexport type RscSignal = NotFoundSignal | ForbiddenSignal | RscRedirectSignal;\n\nexport interface RscElement {\n readonly type: string | symbol | ((props: Record<string, unknown>) => unknown);\n readonly props: Record<string, unknown>;\n readonly key: string | null;\n}\n\nexport type RscNode = RscElement | string | number | boolean | null | undefined | RscNode[];\n\nexport interface RenderServerComponentOptions<TProps> {\n readonly component: (props: TProps) => Promise<RscNode> | RscNode;\n readonly props?: TProps;\n}\n\nexport interface RenderServerComponentResult {\n readonly tree: RscNode;\n readonly signal: RscSignal | null;\n readonly error: unknown;\n}\n\nfunction isRscElement(node: unknown): node is RscElement {\n if (typeof node !== 'object' || node === null) return false;\n const candidate = node as { type?: unknown; props?: unknown };\n return (\n typeof candidate.type !== 'undefined' &&\n typeof candidate.props === 'object' &&\n candidate.props !== null\n );\n}\n\nfunction isNotFound(value: unknown): value is NotFoundSignal {\n return typeof value === 'object' && value !== null && (value as { [NOT_FOUND_SYMBOL]?: true })[NOT_FOUND_SYMBOL] === true;\n}\nfunction isForbidden(value: unknown): value is ForbiddenSignal {\n return typeof value === 'object' && value !== null && (value as { [FORBIDDEN_SYMBOL]?: true })[FORBIDDEN_SYMBOL] === true;\n}\nfunction isRscRedirect(value: unknown): value is RscRedirectSignal {\n return typeof value === 'object' && value !== null && (value as { [RSC_REDIRECT_SYMBOL]?: true })[RSC_REDIRECT_SYMBOL] === true;\n}\n\n/**\n * Recursively walk an RSC tree and collect every node that satisfies the\n * predicate. Children are read from `props.children` and are normalized to a\n * flat array regardless of how the component spelled them.\n */\nexport function findAll(tree: RscNode, predicate: (node: RscElement) => boolean): RscElement[] {\n const out: RscElement[] = [];\n function visit(node: RscNode): void {\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (!isRscElement(node)) return;\n if (predicate(node)) out.push(node);\n const children = node.props.children;\n if (typeof children !== 'undefined') {\n visit(children as RscNode);\n }\n }\n visit(tree);\n return out;\n}\n\n/**\n * Concatenate every string/number leaf of an RSC tree, joined by a single\n * space. Useful for `expect(textContent(tree)).toContain('hello')` style\n * assertions where the exact element structure does not matter.\n */\nexport function textContent(tree: RscNode): string {\n const parts: string[] = [];\n function visit(node: RscNode): void {\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (typeof node === 'string' || typeof node === 'number') {\n parts.push(String(node));\n return;\n }\n if (isRscElement(node)) {\n const children = node.props.children;\n if (typeof children !== 'undefined') visit(children as RscNode);\n }\n }\n visit(tree);\n return parts.filter((p) => p.length > 0).join(' ');\n}\n\n/**\n * Invoke an async server component in isolation and capture its return tree.\n * Throws of `notFound() / forbidden() / redirect()` from `next/navigation`\n * should be replaced with the kiwa signals below (Pattern A from the\n * server-action seam doc); the helper normalizes them into `result.signal`\n * instead of leaving them as `result.error`.\n */\nexport async function renderServerComponent<TProps = Record<string, unknown>>(\n opts: RenderServerComponentOptions<TProps>,\n): Promise<RenderServerComponentResult> {\n let tree: RscNode = null;\n let signal: RscSignal | null = null;\n let error: unknown;\n const props = (opts.props ?? ({} as TProps)) as TProps;\n try {\n const result = await opts.component(props);\n tree = result;\n } catch (caught) {\n if (isNotFound(caught) || isForbidden(caught) || isRscRedirect(caught)) {\n signal = caught;\n } else {\n error = caught;\n }\n }\n return { tree, signal, error };\n}\n","// Next.js App Router Parallel Routes test helper for kiwa (Issue #523).\n//\n// Parallel Routes let an App Router layout render multiple async components in\n// named slots: `layout({ children, @modal, @sidebar })`. Each slot may also\n// provide a `default.tsx` fallback when no matching segment is present, and\n// the URL pattern `(.)`/`(..)`/`(...)` enables Intercepting Routes that swap\n// the slot rendering based on soft-vs-hard navigation.\n//\n// kiwa renders the layout in isolation with synthetic slot trees. The helper\n// awaits all slot promises in parallel (mirroring the React parallel-render\n// semantics), supplies optional Intercepting-Route resolution, and captures\n// errors per slot so a single failing slot does not collapse the whole tree.\n//\n// Out of scope on purpose:\n// - real flight payload / React renderer (use `renderServerComponent` for\n// leaf-level RSC introspection)\n// - matcher / `loading.tsx` / `error.tsx` evaluation\n// - client component boundary (`'use client'`)\n\nexport const PARALLEL_INTERCEPTION_SYMBOL = Symbol.for('kiwa.next.parallel.interception');\n\nexport interface InterceptionMatch<TSlot extends string> {\n readonly [PARALLEL_INTERCEPTION_SYMBOL]: true;\n readonly slot: TSlot;\n readonly variant: 'intercepted' | 'default';\n readonly url: string;\n readonly distance: 'sibling' | 'parent' | 'root';\n}\n\nexport type SlotComponent<TProps = Record<string, unknown>, TNode = unknown> = (\n props: TProps,\n) => Promise<TNode> | TNode;\n\nexport type DefaultFallbackComponent<TNode = unknown> = () => Promise<TNode> | TNode;\n\nexport interface ParallelLayoutChildren<TSlots extends string, TNode = unknown> {\n readonly children: TNode;\n readonly slots: Readonly<Record<TSlots, TNode>>;\n}\n\nexport type ParallelLayoutFunction<TSlots extends string, TLayoutProps, TNode = unknown> = (\n props: TLayoutProps & ParallelLayoutChildren<TSlots, TNode>,\n) => Promise<TNode> | TNode;\n\nexport interface SlotInput<TSlots extends string, TNode = unknown> {\n readonly slot: TSlots;\n readonly component: SlotComponent<Record<string, unknown>, TNode> | null;\n readonly props?: Record<string, unknown>;\n readonly defaultFallback?: DefaultFallbackComponent<TNode>;\n readonly intercepting?: {\n readonly variant: 'intercepted' | 'default';\n readonly url: string;\n readonly distance?: 'sibling' | 'parent' | 'root';\n };\n}\n\nexport interface InvokeParallelRoutesOptions<TSlots extends string, TLayoutProps, TNode = unknown> {\n readonly layout: ParallelLayoutFunction<TSlots, TLayoutProps, TNode>;\n readonly children: SlotComponent<Record<string, unknown>, TNode>;\n readonly childrenProps?: Record<string, unknown>;\n readonly slots: ReadonlyArray<SlotInput<TSlots, TNode>>;\n readonly layoutProps?: TLayoutProps;\n}\n\nexport interface SlotRenderResult<TSlots extends string, TNode = unknown> {\n readonly slot: TSlots;\n readonly tree: TNode | null;\n readonly usedDefault: boolean;\n readonly interception: InterceptionMatch<TSlots> | null;\n readonly error: unknown;\n}\n\nexport interface InvokeParallelRoutesResult<TSlots extends string, TNode = unknown> {\n readonly tree: TNode | null;\n readonly slotResults: ReadonlyArray<SlotRenderResult<TSlots, TNode>>;\n readonly childrenError: unknown;\n readonly layoutError: unknown;\n}\n\nasync function renderSlot<TSlots extends string, TNode>(\n input: SlotInput<TSlots, TNode>,\n): Promise<SlotRenderResult<TSlots, TNode>> {\n let tree: TNode | null = null;\n let usedDefault = false;\n let error: unknown;\n const interception: InterceptionMatch<TSlots> | null = input.intercepting\n ? {\n [PARALLEL_INTERCEPTION_SYMBOL]: true,\n slot: input.slot,\n variant: input.intercepting.variant,\n url: input.intercepting.url,\n distance: input.intercepting.distance ?? 'sibling',\n }\n : null;\n const useDefault =\n input.component === null ||\n interception?.variant === 'default';\n try {\n if (useDefault) {\n if (typeof input.defaultFallback !== 'function') {\n throw new Error(`slot ${input.slot}: no default.tsx fallback supplied`);\n }\n tree = await input.defaultFallback();\n usedDefault = true;\n } else if (input.component !== null) {\n tree = await input.component(input.props ?? {});\n }\n } catch (caught) {\n error = caught;\n }\n return { slot: input.slot, tree, usedDefault, interception, error };\n}\n\n/**\n * Invoke an App Router parallel-routes layout in isolation. All slot\n * components are rendered in parallel (Promise.all) so a slow slot cannot\n * block fast siblings; per-slot errors are captured into `slotResults`\n * without aborting the layout render.\n */\nexport async function invokeParallelRoutes<\n TSlots extends string,\n TLayoutProps = Record<string, unknown>,\n TNode = unknown,\n>(\n opts: InvokeParallelRoutesOptions<TSlots, TLayoutProps, TNode>,\n): Promise<InvokeParallelRoutesResult<TSlots, TNode>> {\n let childrenTree: TNode | null = null;\n let childrenError: unknown;\n let layoutError: unknown;\n try {\n childrenTree = await opts.children(opts.childrenProps ?? {});\n } catch (caught) {\n childrenError = caught;\n }\n const slotResults = await Promise.all(opts.slots.map((input) => renderSlot(input)));\n const slotMap: Record<string, TNode | null> = {};\n for (const result of slotResults) {\n slotMap[result.slot] = result.tree;\n }\n let tree: TNode | null = null;\n try {\n const props = {\n ...((opts.layoutProps ?? {}) as TLayoutProps),\n children: childrenTree as TNode,\n slots: slotMap as Readonly<Record<TSlots, TNode>>,\n } as TLayoutProps & ParallelLayoutChildren<TSlots, TNode>;\n tree = await opts.layout(props);\n } catch (caught) {\n layoutError = caught;\n }\n return { tree, slotResults, childrenError, layoutError };\n}\n","// Next.js React Server Components (RSC) streaming + Suspense boundary test\n// helper for kiwa (Issue #558, v1.3-1).\n//\n// Why this is a separate helper:\n//\n// `renderServerComponent` (Issue #494) handles the leaf-level \"await an async\n// server component and inspect the returned tree\" case. It does not model\n// streaming chunks (RSC payload arrives over multiple network frames) or\n// Suspense boundaries (a `<Suspense fallback={...}>` shows the fallback\n// first, then swaps to the resolved subtree once the data promise settles).\n//\n// `setupNextRscEnv` extends the testing seam to those two dimensions while\n// staying in the same \"no real React renderer / no Next.js dev server\"\n// philosophy: streaming is simulated as a flat array of chunks the component\n// yields in order, and Suspense is simulated as a two-phase\n// (fallback → resolved) transition that the helper drives deterministically.\n//\n// Out of scope (still):\n// - flight payload byte format / `react-server-dom-webpack` wire protocol\n// - actual React `renderToReadableStream` rendering\n// - client-side hydration after a chunk arrives\n// - concurrent multi-Suspense interleaving (one boundary per call)\n\nimport type { RscNode } from './render-server-component.js';\n\nexport const RSC_ERROR_BOUNDARY_SYMBOL = Symbol.for('kiwa.next.rsc.errorBoundary');\n\nexport interface RscErrorBoundarySignal {\n readonly [RSC_ERROR_BOUNDARY_SYMBOL]: true;\n readonly error: unknown;\n}\n\n/**\n * An async source the helper consumes chunk-by-chunk. Each yielded value is\n * one streaming frame; the helper appends it to `env.chunks` in arrival order\n * and uses the last chunk as `env.resolved` once the source completes.\n *\n * Use a plain async generator for most cases:\n *\n * async function* source() {\n * yield <Spinner />; // initial chunk\n * yield <Skeleton rows={3} />; // partial data\n * yield <Items list={data} />; // final resolved chunk\n * }\n */\nexport type RscStreamSource = AsyncIterable<RscNode>;\n\nexport interface SetupNextRscEnvOptions {\n /**\n * The async server component under test. If `dataSource` is omitted, the\n * helper awaits this function once and treats its return value as the only\n * (resolved) chunk — equivalent to a synchronous resolution.\n *\n * The component may throw to trigger the error boundary path. See\n * `injectError` for the test-side variant.\n */\n readonly component?: (props: Record<string, unknown>) => Promise<RscNode> | RscNode;\n /**\n * Optional props forwarded to `component`. Defaults to `{}`.\n */\n readonly props?: Record<string, unknown>;\n /**\n * Explicit streaming source. When provided, the helper iterates this and\n * ignores `component`. Useful when the production code already produces a\n * stream and the test wants to feed a deterministic sequence.\n */\n readonly dataSource?: RscStreamSource;\n /**\n * Markup shown while the (first) chunk is pending. Captured as\n * `env.fallback` so tests can assert that `<Suspense fallback={...}>`\n * surfaces the right loading state before the data arrives.\n */\n readonly suspenseFallback?: RscNode;\n /**\n * Hard timeout (ms) for the whole stream. If the source has not completed\n * by this deadline, the helper resolves with `env.timedOut = true` and the\n * chunks collected so far. Default 5000ms.\n */\n readonly streamingTimeout?: number;\n /**\n * Test-side error injection. When set, the helper short-circuits before\n * iterating the source and routes the error into `env.errorBoundary` —\n * the same shape a production `error.tsx` boundary would see.\n */\n readonly injectError?: unknown;\n}\n\nexport interface SetupNextRscEnvResult {\n /**\n * Streaming chunks in arrival order. For a Suspense boundary, the first\n * chunk is typically the fallback markup and the last chunk is the\n * resolved subtree.\n */\n readonly chunks: RscNode[];\n /**\n * The fallback markup captured before the source produced its first\n * non-fallback chunk. `null` when the test did not pass `suspenseFallback`\n * or when the source resolved synchronously without an explicit fallback.\n */\n readonly fallback: RscNode | null;\n /**\n * The last chunk yielded by the source — the markup a real Next.js page\n * would settle on after streaming finishes. `null` when the source threw\n * or timed out before producing any chunk.\n */\n readonly resolved: RscNode | null;\n /**\n * Set when the component or source threw, or when `injectError` was\n * provided. Mirrors the value a production `error.tsx` boundary receives.\n * `null` for happy-path streams.\n */\n readonly errorBoundary: RscErrorBoundarySignal | null;\n /**\n * `true` when `streamingTimeout` elapsed before the source completed.\n * `chunks` still contains any chunks that arrived before the deadline.\n */\n readonly timedOut: boolean;\n}\n\nconst DEFAULT_STREAMING_TIMEOUT_MS = 5000;\n\nfunction buildErrorBoundary(error: unknown): RscErrorBoundarySignal {\n return { [RSC_ERROR_BOUNDARY_SYMBOL]: true, error };\n}\n\nasync function runWithTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n): Promise<{ value: T | null; timedOut: boolean }> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<{ value: null; timedOut: true }>((resolve) => {\n timer = setTimeout(() => resolve({ value: null, timedOut: true }), timeoutMs);\n });\n try {\n const value = await Promise.race([\n promise.then((v) => ({ value: v, timedOut: false as const })),\n timeout,\n ]);\n return value;\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nasync function collectStream(\n source: RscStreamSource,\n fallback: RscNode | null,\n): Promise<{ chunks: RscNode[]; resolved: RscNode | null; thrown: unknown }> {\n const chunks: RscNode[] = [];\n // The fallback is the visible markup before the first real chunk arrives —\n // we record it as chunk 0 so tests can `expect(chunks[0]).toBe(fallback)`.\n if (typeof fallback !== 'undefined' && fallback !== null) {\n chunks.push(fallback);\n }\n try {\n for await (const chunk of source) {\n chunks.push(chunk);\n }\n } catch (err) {\n return { chunks, resolved: null, thrown: err };\n }\n const resolved = chunks.length > 0 ? (chunks[chunks.length - 1] ?? null) : null;\n // If the only chunk we have is the fallback, the source produced nothing —\n // resolved is null so tests can distinguish \"fallback shown forever\" from\n // \"fallback then resolved subtree\".\n const fallbackOnly =\n chunks.length === 1 && fallback !== null && Object.is(chunks[0], fallback);\n return { chunks, resolved: fallbackOnly ? null : resolved, thrown: undefined };\n}\n\nasync function* singleChunkSource(\n component: NonNullable<SetupNextRscEnvOptions['component']>,\n props: Record<string, unknown>,\n): AsyncGenerator<RscNode, void, unknown> {\n const result = await component(props);\n yield result;\n}\n\n/**\n * Drive an async RSC stream through a single Suspense boundary and capture\n * every chunk + the fallback + the resolved subtree + any error-boundary\n * trigger. The helper is deterministic — chunks arrive in the order the\n * source yields them, and the timeout is wall-clock-bounded so tests cannot\n * hang on a stuck stream.\n *\n * Typical usage:\n *\n * const env = await setupNextRscEnv({\n * dataSource: streamItems(),\n * suspenseFallback: <Skeleton />,\n * streamingTimeout: 1000,\n * });\n * expect(env.fallback).toEqual(<Skeleton />);\n * expect(env.chunks).toHaveLength(3);\n * expect(env.resolved).toEqual(<ItemList items={items} />);\n * expect(env.errorBoundary).toBeNull();\n * expect(env.timedOut).toBe(false);\n */\nexport async function setupNextRscEnv(\n opts: SetupNextRscEnvOptions = {},\n): Promise<SetupNextRscEnvResult> {\n const timeoutMs = opts.streamingTimeout ?? DEFAULT_STREAMING_TIMEOUT_MS;\n const fallback = opts.suspenseFallback ?? null;\n\n // streamingTimeout: 0 (or negative) means \"fail fast\" — used by tests that\n // want to assert the helper does not hang when a deadline is set to zero.\n // A microtask-resolved source would otherwise beat a 0ms setTimeout in\n // Promise.race, hiding the timeout path.\n if (timeoutMs <= 0 && (opts.dataSource || opts.component)) {\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: null,\n timedOut: true,\n };\n }\n\n // Test-side error injection short-circuits everything — no chunks, no\n // resolved tree, just the boundary signal.\n if (typeof opts.injectError !== 'undefined') {\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: buildErrorBoundary(opts.injectError),\n timedOut: false,\n };\n }\n\n if (!opts.dataSource && !opts.component) {\n // Nothing to render — return an empty env so the caller can assert on it.\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: null,\n timedOut: false,\n };\n }\n\n const source: RscStreamSource = opts.dataSource\n ? opts.dataSource\n : singleChunkSource(opts.component!, opts.props ?? {});\n\n const { value, timedOut } = await runWithTimeout(collectStream(source, fallback), timeoutMs);\n\n if (timedOut || value === null) {\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: null,\n timedOut: true,\n };\n }\n\n const { chunks, resolved, thrown } = value;\n\n if (typeof thrown !== 'undefined') {\n return {\n chunks,\n fallback,\n resolved: null,\n errorBoundary: buildErrorBoundary(thrown),\n timedOut: false,\n };\n }\n\n return {\n chunks,\n fallback,\n resolved,\n errorBoundary: null,\n timedOut: false,\n };\n}\n","/**\n * Advanced Next.js semantics — target-neutral axis SSOT.\n *\n * The helpers model App Router, Pages Router, and Edge Runtime behavior as\n * pure state machines. Tests can assert the neutral event while still seeing\n * a target-specific dialect through providerEventName.\n */\nexport type NextTarget = 'app-router' | 'pages-router' | 'edge-runtime';\n\nexport type NextAxis =\n | 'server-action-advanced'\n | 'partial-prerendering'\n | 'interception-routes'\n | 'parallel-routes-advanced';\n\nexport type NeutralEventName =\n | 'action.form_submitted'\n | 'action.revalidate_path'\n | 'action.revalidate_tag'\n | 'action.redirected'\n | 'ppr.static_shell_rendered'\n | 'ppr.dynamic_hole_opened'\n | 'ppr.streaming_boundary_flushed'\n | 'ppr.completed'\n | 'intercept.current_segment'\n | 'intercept.parent_segment'\n | 'intercept.root_catchall'\n | 'intercept.modal_opened'\n | 'parallel.default_rendered'\n | 'parallel.loading_rendered'\n | 'parallel.error_boundary_captured'\n | 'parallel.slot_navigated';\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<NextTarget, Partial<Record<NeutralEventName, string>>> = {\n 'app-router': {\n 'action.form_submitted': 'app.server-action.form.submit',\n 'action.revalidate_path': 'app.cache.revalidatePath',\n 'action.revalidate_tag': 'app.cache.revalidateTag',\n 'action.redirected': 'app.navigation.redirect',\n 'ppr.static_shell_rendered': 'app.ppr.static-shell',\n 'ppr.dynamic_hole_opened': 'app.ppr.dynamic-hole',\n 'ppr.streaming_boundary_flushed': 'app.ppr.stream-boundary',\n 'ppr.completed': 'app.ppr.complete',\n 'intercept.current_segment': 'app.intercept.current',\n 'intercept.parent_segment': 'app.intercept.parent',\n 'intercept.root_catchall': 'app.intercept.root',\n 'intercept.modal_opened': 'app.intercept.modal',\n 'parallel.default_rendered': 'app.parallel.default',\n 'parallel.loading_rendered': 'app.parallel.loading',\n 'parallel.error_boundary_captured': 'app.parallel.error',\n 'parallel.slot_navigated': 'app.parallel.navigate',\n },\n 'pages-router': {\n 'action.form_submitted': 'pages.api.form.submit',\n 'action.revalidate_path': 'pages.isr.revalidate',\n 'action.revalidate_tag': 'pages.cache.tag.noop',\n 'action.redirected': 'pages.router.redirect',\n 'ppr.static_shell_rendered': 'pages.ssg.shell',\n 'ppr.dynamic_hole_opened': 'pages.ssr.dynamic-hole',\n 'ppr.streaming_boundary_flushed': 'pages.stream.boundary',\n 'ppr.completed': 'pages.render.complete',\n 'intercept.current_segment': 'pages.intercept.current',\n 'intercept.parent_segment': 'pages.intercept.parent',\n 'intercept.root_catchall': 'pages.intercept.root',\n 'intercept.modal_opened': 'pages.modal.open',\n 'parallel.default_rendered': 'pages.slot.default',\n 'parallel.loading_rendered': 'pages.slot.loading',\n 'parallel.error_boundary_captured': 'pages.slot.error',\n 'parallel.slot_navigated': 'pages.slot.navigate',\n },\n 'edge-runtime': {\n 'action.form_submitted': 'edge.action.form.submit',\n 'action.revalidate_path': 'edge.cache.revalidatePath',\n 'action.revalidate_tag': 'edge.cache.revalidateTag',\n 'action.redirected': 'edge.response.redirect',\n 'ppr.static_shell_rendered': 'edge.ppr.static-shell',\n 'ppr.dynamic_hole_opened': 'edge.ppr.dynamic-hole',\n 'ppr.streaming_boundary_flushed': 'edge.stream.boundary',\n 'ppr.completed': 'edge.ppr.complete',\n 'intercept.current_segment': 'edge.intercept.current',\n 'intercept.parent_segment': 'edge.intercept.parent',\n 'intercept.root_catchall': 'edge.intercept.root',\n 'intercept.modal_opened': 'edge.modal.open',\n 'parallel.default_rendered': 'edge.parallel.default',\n 'parallel.loading_rendered': 'edge.parallel.loading',\n 'parallel.error_boundary_captured': 'edge.parallel.error',\n 'parallel.slot_navigated': 'edge.parallel.navigate',\n },\n};\n\nexport function providerEventName(target: NextTarget, neutral: NeutralEventName): string {\n return dialect[target][neutral] ?? neutral;\n}\n","import { providerEventName, type AxisStep, type NextTarget } from './types.js';\n\nexport type ServerActionAdvancedState =\n | 'idle'\n | 'submitted'\n | 'path-revalidated'\n | 'tag-revalidated'\n | 'redirected';\n\nexport interface ServerActionAdvancedSession {\n target: NextTarget;\n actionId: string;\n state: ServerActionAdvancedState;\n form: Record<string, string>;\n revalidatedPaths: string[];\n revalidatedTags: string[];\n redirectUrl: string | null;\n history: AxisStep<ServerActionAdvancedState>[];\n}\n\nexport function startServerActionAdvanced(input: {\n target: NextTarget;\n actionId: string;\n}): ServerActionAdvancedSession {\n if (input.actionId.length === 0) {\n throw new Error('startServerActionAdvanced: actionId must not be empty');\n }\n return {\n target: input.target,\n actionId: input.actionId,\n state: 'idle',\n form: {},\n revalidatedPaths: [],\n revalidatedTags: [],\n redirectUrl: null,\n history: [],\n };\n}\n\nexport function submitFormAction(\n session: ServerActionAdvancedSession,\n form: Record<string, string>,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state !== 'idle') {\n throw new Error(`submitFormAction: session is ${session.state}, not idle`);\n }\n session.state = 'submitted';\n session.form = { ...form };\n return emit(session, 'action.form_submitted', {\n fields: Object.keys(form).join(','),\n fieldCount: Object.keys(form).length,\n });\n}\n\nexport function revalidateActionPath(\n session: ServerActionAdvancedSession,\n path: string,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state === 'idle') {\n throw new Error('revalidateActionPath: form action was not submitted');\n }\n if (!path.startsWith('/')) {\n throw new Error('revalidateActionPath: path must start with /');\n }\n session.state = 'path-revalidated';\n session.revalidatedPaths.push(path);\n return emit(session, 'action.revalidate_path', { path, count: session.revalidatedPaths.length });\n}\n\nexport function revalidateActionTag(\n session: ServerActionAdvancedSession,\n tag: string,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state === 'idle') {\n throw new Error('revalidateActionTag: form action was not submitted');\n }\n if (tag.length === 0) {\n throw new Error('revalidateActionTag: tag must not be empty');\n }\n session.state = 'tag-revalidated';\n session.revalidatedTags.push(tag);\n return emit(session, 'action.revalidate_tag', { tag, count: session.revalidatedTags.length });\n}\n\nexport function redirectAction(\n session: ServerActionAdvancedSession,\n url: string,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state === 'idle') {\n throw new Error('redirectAction: form action was not submitted');\n }\n if (url.length === 0) {\n throw new Error('redirectAction: url must not be empty');\n }\n session.state = 'redirected';\n session.redirectUrl = url;\n return emit(session, 'action.redirected', { url });\n}\n\nfunction emit(\n session: ServerActionAdvancedSession,\n neutralEvent: AxisStep<ServerActionAdvancedState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ServerActionAdvancedState> {\n const step: AxisStep<ServerActionAdvancedState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, actionId: session.actionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type NextTarget } from './types.js';\n\nexport type PartialPrerenderingState = 'idle' | 'static-shell' | 'dynamic-hole' | 'streaming' | 'completed';\n\nexport interface PartialPrerenderingSession {\n target: NextTarget;\n routeId: string;\n state: PartialPrerenderingState;\n shellHtml: string | null;\n dynamicHoles: Map<string, string>;\n streamedBoundaries: string[];\n history: AxisStep<PartialPrerenderingState>[];\n}\n\nexport function startPartialPrerendering(input: {\n target: NextTarget;\n routeId: string;\n}): PartialPrerenderingSession {\n if (input.routeId.length === 0) {\n throw new Error('startPartialPrerendering: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n state: 'idle',\n shellHtml: null,\n dynamicHoles: new Map(),\n streamedBoundaries: [],\n history: [],\n };\n}\n\nexport function renderStaticShell(\n session: PartialPrerenderingSession,\n html: string,\n): AxisStep<PartialPrerenderingState> {\n if (session.state !== 'idle') {\n throw new Error(`renderStaticShell: session is ${session.state}, not idle`);\n }\n if (html.length === 0) {\n throw new Error('renderStaticShell: html must not be empty');\n }\n session.state = 'static-shell';\n session.shellHtml = html;\n return emit(session, 'ppr.static_shell_rendered', { bytes: html.length });\n}\n\nexport function openDynamicHole(\n session: PartialPrerenderingSession,\n input: { holeId: string; fallback: string },\n): AxisStep<PartialPrerenderingState> {\n if (session.shellHtml === null) {\n throw new Error('openDynamicHole: static shell must be rendered first');\n }\n if (input.holeId.length === 0) {\n throw new Error('openDynamicHole: holeId must not be empty');\n }\n session.state = 'dynamic-hole';\n session.dynamicHoles.set(input.holeId, input.fallback);\n return emit(session, 'ppr.dynamic_hole_opened', {\n holeId: input.holeId,\n fallback: input.fallback,\n holeCount: session.dynamicHoles.size,\n });\n}\n\nexport function flushStreamingBoundary(\n session: PartialPrerenderingSession,\n input: { holeId: string; html: string },\n): AxisStep<PartialPrerenderingState> {\n if (!session.dynamicHoles.has(input.holeId)) {\n throw new Error(`flushStreamingBoundary: ${input.holeId} is not an open dynamic hole`);\n }\n if (input.html.length === 0) {\n throw new Error('flushStreamingBoundary: html must not be empty');\n }\n session.state = 'streaming';\n session.streamedBoundaries.push(input.holeId);\n session.dynamicHoles.set(input.holeId, input.html);\n return emit(session, 'ppr.streaming_boundary_flushed', {\n holeId: input.holeId,\n bytes: input.html.length,\n });\n}\n\nexport function completePartialPrerendering(\n session: PartialPrerenderingSession,\n): AxisStep<PartialPrerenderingState> {\n if (session.shellHtml === null) {\n throw new Error('completePartialPrerendering: static shell was not rendered');\n }\n session.state = 'completed';\n return emit(session, 'ppr.completed', {\n holeCount: session.dynamicHoles.size,\n streamedCount: session.streamedBoundaries.length,\n });\n}\n\nfunction emit(\n session: PartialPrerenderingSession,\n neutralEvent: AxisStep<PartialPrerenderingState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<PartialPrerenderingState> {\n const step: AxisStep<PartialPrerenderingState> = {\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 NextTarget } from './types.js';\n\nexport type InterceptionRoutesState = 'idle' | 'current' | 'parent' | 'root' | 'modal-open';\nexport type InterceptionMatcher = '(.)' | '(..)' | '(...)';\n\nexport interface InterceptionRoutesSession {\n target: NextTarget;\n routeId: string;\n state: InterceptionRoutesState;\n matches: Array<{ matcher: InterceptionMatcher; from: string; to: string }>;\n modalRoute: string | null;\n history: AxisStep<InterceptionRoutesState>[];\n}\n\nexport function startInterceptionRoutes(input: {\n target: NextTarget;\n routeId: string;\n}): InterceptionRoutesSession {\n if (input.routeId.length === 0) {\n throw new Error('startInterceptionRoutes: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n state: 'idle',\n matches: [],\n modalRoute: null,\n history: [],\n };\n}\n\nexport function interceptCurrentSegment(\n session: InterceptionRoutesSession,\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n return intercept(session, '(.)', 'current', 'intercept.current_segment', from, to);\n}\n\nexport function interceptParentSegment(\n session: InterceptionRoutesSession,\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n return intercept(session, '(..)', 'parent', 'intercept.parent_segment', from, to);\n}\n\nexport function interceptRootCatchall(\n session: InterceptionRoutesSession,\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n return intercept(session, '(...)', 'root', 'intercept.root_catchall', from, to);\n}\n\nexport function openInterceptedModal(\n session: InterceptionRoutesSession,\n modalRoute: string,\n): AxisStep<InterceptionRoutesState> {\n if (modalRoute.length === 0) {\n throw new Error('openInterceptedModal: modalRoute must not be empty');\n }\n if (session.matches.length === 0) {\n throw new Error('openInterceptedModal: an interception match is required first');\n }\n session.state = 'modal-open';\n session.modalRoute = modalRoute;\n return emit(session, 'intercept.modal_opened', {\n modalRoute,\n matchCount: session.matches.length,\n });\n}\n\nfunction intercept(\n session: InterceptionRoutesSession,\n matcher: InterceptionMatcher,\n state: InterceptionRoutesState,\n neutralEvent: AxisStep<InterceptionRoutesState>['neutralEvent'],\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n if (!from.startsWith('/') || !to.startsWith('/')) {\n throw new Error('intercept: from and to must start with /');\n }\n session.state = state;\n session.matches.push({ matcher, from, to });\n return emit(session, neutralEvent, { matcher, from, to });\n}\n\nfunction emit(\n session: InterceptionRoutesSession,\n neutralEvent: AxisStep<InterceptionRoutesState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<InterceptionRoutesState> {\n const step: AxisStep<InterceptionRoutesState> = {\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 NextTarget } from './types.js';\n\nexport type ParallelRoutesAdvancedState =\n | 'idle'\n | 'default-rendered'\n | 'loading-rendered'\n | 'error-captured'\n | 'slot-navigated';\n\nexport interface ParallelRoutesAdvancedSession {\n target: NextTarget;\n layoutId: string;\n state: ParallelRoutesAdvancedState;\n slots: Map<string, string>;\n loadingSlots: Set<string>;\n errors: Array<{ slot: string; message: string }>;\n history: AxisStep<ParallelRoutesAdvancedState>[];\n}\n\nexport function startParallelRoutesAdvanced(input: {\n target: NextTarget;\n layoutId: string;\n}): ParallelRoutesAdvancedSession {\n if (input.layoutId.length === 0) {\n throw new Error('startParallelRoutesAdvanced: layoutId must not be empty');\n }\n return {\n target: input.target,\n layoutId: input.layoutId,\n state: 'idle',\n slots: new Map(),\n loadingSlots: new Set(),\n errors: [],\n history: [],\n };\n}\n\nexport function renderDefaultSlot(\n session: ParallelRoutesAdvancedSession,\n slot: string,\n html: string,\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(slot);\n session.state = 'default-rendered';\n session.slots.set(slot, html);\n return emit(session, 'parallel.default_rendered', { slot, html });\n}\n\nexport function renderLoadingState(\n session: ParallelRoutesAdvancedSession,\n slot: string,\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(slot);\n session.state = 'loading-rendered';\n session.loadingSlots.add(slot);\n return emit(session, 'parallel.loading_rendered', {\n slot,\n loadingCount: session.loadingSlots.size,\n });\n}\n\nexport function captureParallelError(\n session: ParallelRoutesAdvancedSession,\n input: { slot: string; error: Error | string },\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(input.slot);\n const message = typeof input.error === 'string' ? input.error : input.error.message;\n session.state = 'error-captured';\n session.errors.push({ slot: input.slot, message });\n return emit(session, 'parallel.error_boundary_captured', {\n slot: input.slot,\n message,\n errorCount: session.errors.length,\n });\n}\n\nexport function navigateSlot(\n session: ParallelRoutesAdvancedSession,\n input: { slot: string; from: string; to: string },\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(input.slot);\n if (!input.from.startsWith('/') || !input.to.startsWith('/')) {\n throw new Error('navigateSlot: from and to must start with /');\n }\n session.state = 'slot-navigated';\n session.loadingSlots.delete(input.slot);\n return emit(session, 'parallel.slot_navigated', input);\n}\n\nfunction assertSlot(slot: string): void {\n if (slot.length === 0) {\n throw new Error('slot must not be empty');\n }\n}\n\nfunction emit(\n session: ParallelRoutesAdvancedSession,\n neutralEvent: AxisStep<ParallelRoutesAdvancedState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ParallelRoutesAdvancedState> {\n const step: AxisStep<ParallelRoutesAdvancedState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, layoutId: session.layoutId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type NeutralEventName, type NextAxis, type NextTarget } from './types.js';\n\nexport interface FidelityRow {\n provider: NextTarget;\n axis: NextAxis;\n neutralEvents: NeutralEventName[];\n providerEvents: string[];\n}\n\nexport interface FidelityCoverage {\n providers: NextTarget[];\n axes: NextAxis[];\n rows: FidelityRow[];\n}\n\nexport const NEXT_AXIS_TO_EVENTS: Record<NextAxis, NeutralEventName[]> = {\n 'server-action-advanced': [\n 'action.form_submitted',\n 'action.revalidate_path',\n 'action.revalidate_tag',\n 'action.redirected',\n ],\n 'partial-prerendering': [\n 'ppr.static_shell_rendered',\n 'ppr.dynamic_hole_opened',\n 'ppr.streaming_boundary_flushed',\n 'ppr.completed',\n ],\n 'interception-routes': [\n 'intercept.current_segment',\n 'intercept.parent_segment',\n 'intercept.root_catchall',\n 'intercept.modal_opened',\n ],\n 'parallel-routes-advanced': [\n 'parallel.default_rendered',\n 'parallel.loading_rendered',\n 'parallel.error_boundary_captured',\n 'parallel.slot_navigated',\n ],\n};\n\nexport function collectFidelityCoverage(\n providers: NextTarget[] = ['app-router', 'pages-router', 'edge-runtime'],\n): FidelityCoverage {\n const axes = Object.keys(NEXT_AXIS_TO_EVENTS) as NextAxis[];\n const rows: FidelityRow[] = [];\n for (const provider of providers) {\n for (const axis of axes) {\n const neutralEvents = NEXT_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 { NextTarget } from './semantics/types.js';\n\nexport type KiwaTestMode = 'mock' | 'real';\n\nexport interface ResolvedMode {\n mode: KiwaTestMode;\n provider: NextTarget;\n reason: 'default-mock' | 'kiwa-mode-real' | 'missing-key' | 'invalid-mode';\n}\n\nconst TARGET_KEY_ENV: Record<NextTarget, string> = {\n 'app-router': 'NEXT_APP_URL',\n 'pages-router': 'NEXT_PAGES_URL',\n 'edge-runtime': 'EDGE_RUNTIME_URL',\n};\n\nexport function resolveMode(\n provider: NextTarget,\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: NextTarget[] = ['app-router', 'pages-router', 'edge-runtime'];\n return providers.map((provider) => resolveMode(provider, env));\n}\n\nexport function assertMode(\n provider: NextTarget,\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":["emit","emit","emit"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/invoke-server-action.ts","../src/invoke-middleware.ts","../src/render-server-component.ts","../src/invoke-parallel-routes.ts","../src/setup-next-rsc-env.ts","../src/semantics/types.ts","../src/semantics/server-action-advanced.ts","../src/semantics/partial-prerendering.ts","../src/semantics/interception-routes.ts","../src/semantics/parallel-routes-advanced.ts","../src/semantics/fidelity.ts","../src/semantics/turbopack-hmr.ts","../src/semantics/concurrent-transitions.ts","../src/real-driver.ts"],"sourcesContent":["export {\n invokeServerAction,\n type ServerActionFunction,\n type ServerActionResult,\n type ServerActionInvocation,\n type ServerActionEnv,\n type CookieJar,\n REDIRECT_SYMBOL,\n type RedirectSignal,\n} from './invoke-server-action.js';\n\nexport {\n invokeMiddleware,\n middlewareActions,\n MIDDLEWARE_ACTION_SYMBOL,\n type InvokeMiddlewareOptions,\n type InvokeMiddlewareResult,\n type MiddlewareFunction,\n type MiddlewareRequest,\n type MiddlewareEnv,\n type MiddlewareAction,\n type MiddlewareActionKind,\n} from './invoke-middleware.js';\n\nexport {\n renderServerComponent,\n findAll,\n textContent,\n NOT_FOUND_SYMBOL,\n FORBIDDEN_SYMBOL,\n RSC_REDIRECT_SYMBOL,\n type RenderServerComponentOptions,\n type RenderServerComponentResult,\n type RscElement,\n type RscNode,\n type RscSignal,\n type NotFoundSignal,\n type ForbiddenSignal,\n type RscRedirectSignal,\n} from './render-server-component.js';\n\nexport {\n invokeParallelRoutes,\n PARALLEL_INTERCEPTION_SYMBOL,\n type InvokeParallelRoutesOptions,\n type InvokeParallelRoutesResult,\n type ParallelLayoutFunction,\n type ParallelLayoutChildren,\n type SlotComponent,\n type SlotInput,\n type SlotRenderResult,\n type DefaultFallbackComponent,\n type InterceptionMatch,\n} from './invoke-parallel-routes.js';\n\nexport {\n setupNextRscEnv,\n RSC_ERROR_BOUNDARY_SYMBOL,\n type SetupNextRscEnvOptions,\n type SetupNextRscEnvResult,\n type RscStreamSource,\n type RscErrorBoundarySignal,\n} from './setup-next-rsc-env.js';\n\nexport * from './semantics/index.js';\nexport {\n assertMode,\n resolveAllModes,\n resolveMode,\n type KiwaTestMode,\n type ResolvedMode,\n} from './real-driver.js';\n","// Next.js Server Action invocation helper for kiwa tests.\n//\n// Wraps an `'use server'` async function and captures Next.js side-effects\n// (redirect / revalidatePath / cookies set) without requiring a real Next.js\n// runtime. The test calls `invokeServerAction({ action, formData, ... })`\n// and asserts on the returned `ServerActionResult` instead of relying on\n// integration-level behavior.\n//\n// Out of scope on purpose:\n// - real `next/server` middleware semantics (use #495 helper instead)\n// - RSC payload format (use #494 helper instead)\n// - rendering a page after the action (use Playwright + `/kiwa-e2e` for that)\n\nexport const REDIRECT_SYMBOL = Symbol.for('kiwa.next.redirect');\n\nexport interface RedirectSignal {\n readonly [REDIRECT_SYMBOL]: true;\n readonly url: string;\n readonly type: 'replace' | 'push';\n}\n\nexport interface CookieJar {\n get(name: string): string | undefined;\n set(name: string, value: string, options?: Record<string, unknown>): void;\n delete(name: string): void;\n entries(): Array<[string, string]>;\n}\n\nexport interface ServerActionEnv {\n readonly cookies: CookieJar;\n readonly headers: Map<string, string>;\n readonly revalidated: { paths: string[]; tags: string[] };\n readonly redirect: RedirectSignal | null;\n}\n\n// We deliberately accept `any[]` here so callers can pass typed actions like\n// `(fd: FormData) => Promise<T>` or `(prev: State, fd: FormData) => Promise<T>`\n// without contortions. The runtime always invokes `action(formData, ...args)`.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type ServerActionFunction<TResult> = (...args: any[]) => Promise<TResult> | TResult;\n\nexport interface ServerActionInvocation<TResult> {\n /** The `'use server'` async function under test. */\n readonly action: ServerActionFunction<TResult>;\n /** Optional FormData first argument (default empty). */\n readonly formData?: FormData;\n /** Extra positional args appended after FormData (e.g. previous state for useFormState). */\n readonly args?: unknown[];\n /** Initial cookie jar entries (name → value). */\n readonly cookies?: Record<string, string>;\n /** Initial request headers (case-insensitive). */\n readonly headers?: Record<string, string>;\n}\n\nexport interface ServerActionResult<TResult> {\n /** Resolved return value (or `undefined` if the action threw a redirect signal). */\n readonly result: TResult | undefined;\n /** Error thrown by the action (excluding redirect signals which are normalized). */\n readonly error: unknown;\n /** Side-effects captured during the invocation. */\n readonly env: ServerActionEnv;\n}\n\nfunction createCookieJar(initial: Record<string, string>): CookieJar {\n const store = new Map<string, string>(Object.entries(initial));\n return {\n get(name) {\n return store.get(name);\n },\n set(name, value) {\n store.set(name, value);\n },\n delete(name) {\n store.delete(name);\n },\n entries() {\n return Array.from(store.entries());\n },\n };\n}\n\nfunction isRedirectSignal(value: unknown): value is RedirectSignal {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { [REDIRECT_SYMBOL]?: true })[REDIRECT_SYMBOL] === true\n );\n}\n\n/**\n * Invoke a Next.js Server Action in isolation and capture its side-effects.\n *\n * The action is called as `await action(formData, ...args)`. The kiwa helper\n * does NOT monkey-patch global `next/navigation` / `next/headers` / `next/cache`\n * imports. Instead the action under test should accept its dependencies via\n * an injectable seam (a parameter or a module-level setter) so tests stay\n * deterministic. See `examples/nextjs-server-actions-poc/` for the pattern.\n */\nexport async function invokeServerAction<TResult>(\n opts: ServerActionInvocation<TResult>,\n): Promise<ServerActionResult<TResult>> {\n const headers = new Map<string, string>();\n for (const [name, value] of Object.entries(opts.headers ?? {})) {\n headers.set(name.toLowerCase(), value);\n }\n const env: ServerActionEnv = {\n cookies: createCookieJar(opts.cookies ?? {}),\n headers,\n revalidated: { paths: [], tags: [] },\n redirect: null,\n };\n const callArgs: unknown[] = [opts.formData ?? new FormData(), ...(opts.args ?? [])];\n let result: TResult | undefined;\n let error: unknown;\n try {\n result = await opts.action(...callArgs);\n } catch (caught) {\n if (isRedirectSignal(caught)) {\n (env as { redirect: RedirectSignal | null }).redirect = caught;\n } else {\n error = caught;\n }\n }\n return { result, error, env };\n}\n","// Next.js middleware.ts invocation helper for kiwa tests (Issue #495).\n//\n// Middleware in App Router is `(req: NextRequest) => NextResponse | Response | void`.\n// It can set response headers / cookies, throw redirect via NextResponse.redirect(),\n// rewrite via NextResponse.rewrite(), short-circuit with NextResponse.json(), or\n// pass through with NextResponse.next(). kiwa wraps the call so unit tests can\n// assert on the captured action + outgoing headers/cookies without a running\n// Next.js server.\n//\n// Out of scope on purpose:\n// - matcher config evaluation (the test already knows which middleware to call)\n// - revalidate / cache header semantics\n// - Edge runtime polyfill (use Node test environment + the helper's simulated request)\n\nexport const MIDDLEWARE_ACTION_SYMBOL = Symbol.for('kiwa.next.middleware.action');\n\nexport type MiddlewareActionKind = 'next' | 'redirect' | 'rewrite' | 'json' | 'noop';\n\nexport interface MiddlewareAction {\n readonly [MIDDLEWARE_ACTION_SYMBOL]: true;\n readonly kind: MiddlewareActionKind;\n readonly url?: string;\n readonly body?: unknown;\n readonly status?: number;\n}\n\nexport interface MiddlewareRequest {\n readonly url: string;\n readonly method: string;\n readonly headers: ReadonlyMap<string, string>;\n readonly cookies: ReadonlyMap<string, string>;\n readonly nextUrl: {\n readonly pathname: string;\n readonly search: string;\n readonly searchParams: URLSearchParams;\n };\n readonly geo: {\n readonly country?: string;\n readonly region?: string;\n readonly city?: string;\n };\n}\n\nexport interface MiddlewareEnv {\n readonly responseHeaders: Map<string, string>;\n readonly responseCookies: Map<string, string>;\n readonly action: MiddlewareAction;\n}\n\nexport type MiddlewareFunction = (\n req: MiddlewareRequest,\n env: { setHeader: (name: string, value: string) => void; setCookie: (name: string, value: string) => void },\n) => MiddlewareAction | Promise<MiddlewareAction>;\n\nexport interface InvokeMiddlewareOptions {\n readonly middleware: MiddlewareFunction;\n readonly url: string;\n readonly method?: string;\n readonly headers?: Record<string, string>;\n readonly cookies?: Record<string, string>;\n readonly geo?: {\n readonly country?: string;\n readonly region?: string;\n readonly city?: string;\n };\n}\n\nexport interface InvokeMiddlewareResult {\n readonly env: MiddlewareEnv;\n readonly error: unknown;\n}\n\nfunction buildRequest(opts: InvokeMiddlewareOptions): MiddlewareRequest {\n const url = new URL(opts.url);\n const headers = new Map<string, string>();\n for (const [name, value] of Object.entries(opts.headers ?? {})) {\n headers.set(name.toLowerCase(), value);\n }\n const cookies = new Map<string, string>(Object.entries(opts.cookies ?? {}));\n return {\n url: opts.url,\n method: opts.method ?? 'GET',\n headers,\n cookies,\n nextUrl: {\n pathname: url.pathname,\n search: url.search,\n searchParams: url.searchParams,\n },\n geo: opts.geo ?? {},\n };\n}\n\n/**\n * Helpers your `middleware.ts` returns instead of constructing NextResponse\n * directly. Keep the production code shape close by re-exporting these from\n * a shared module; the helper expects the returned value to be a\n * MiddlewareAction shaped object.\n */\nexport const middlewareActions = {\n next(): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'next' };\n },\n redirect(url: string, status = 307): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'redirect', url, status };\n },\n rewrite(url: string): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'rewrite', url };\n },\n json(body: unknown, status = 200): MiddlewareAction {\n return { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'json', body, status };\n },\n};\n\n/**\n * Invoke a middleware function in isolation and capture its outgoing\n * response shape + headers + cookies. Mirrors the kiwa style of\n * invokeServerAction: no globals, no real Next.js runtime.\n */\nexport async function invokeMiddleware(opts: InvokeMiddlewareOptions): Promise<InvokeMiddlewareResult> {\n const req = buildRequest(opts);\n const responseHeaders = new Map<string, string>();\n const responseCookies = new Map<string, string>();\n const seam = {\n setHeader(name: string, value: string) {\n responseHeaders.set(name.toLowerCase(), value);\n },\n setCookie(name: string, value: string) {\n responseCookies.set(name, value);\n },\n };\n let action: MiddlewareAction = middlewareActions.next();\n let error: unknown;\n try {\n const result = await opts.middleware(req, seam);\n action = result;\n } catch (caught) {\n error = caught;\n action = { [MIDDLEWARE_ACTION_SYMBOL]: true, kind: 'noop' };\n }\n return {\n env: {\n responseHeaders,\n responseCookies,\n action,\n },\n error,\n };\n}\n","// Next.js async React Server Component (RSC) test helper for kiwa (Issue #494).\n//\n// Real RSC rendering involves a streaming runtime + a flight payload format\n// that requires `vitest-environment-rsc` or a Next.js dev server. kiwa takes\n// a lighter approach: treat the async server component as `async (props) =>\n// JSX.Element` and await it directly. The returned React element tree is\n// inspected with a small finder API instead of a full DOM.\n//\n// Out of scope:\n// - flight payload serialization\n// - client component boundary (`'use client'`)\n// - suspense streaming (synchronous resolution only)\n// - dangerous HTML rendering — tests assert on element shape, not strings\n\nexport const NOT_FOUND_SYMBOL = Symbol.for('kiwa.next.rsc.notFound');\nexport const FORBIDDEN_SYMBOL = Symbol.for('kiwa.next.rsc.forbidden');\nexport const RSC_REDIRECT_SYMBOL = Symbol.for('kiwa.next.rsc.redirect');\n\nexport interface NotFoundSignal {\n readonly [NOT_FOUND_SYMBOL]: true;\n}\nexport interface ForbiddenSignal {\n readonly [FORBIDDEN_SYMBOL]: true;\n}\nexport interface RscRedirectSignal {\n readonly [RSC_REDIRECT_SYMBOL]: true;\n readonly url: string;\n readonly type: 'replace' | 'push';\n}\n\nexport type RscSignal = NotFoundSignal | ForbiddenSignal | RscRedirectSignal;\n\nexport interface RscElement {\n readonly type: string | symbol | ((props: Record<string, unknown>) => unknown);\n readonly props: Record<string, unknown>;\n readonly key: string | null;\n}\n\nexport type RscNode = RscElement | string | number | boolean | null | undefined | RscNode[];\n\nexport interface RenderServerComponentOptions<TProps> {\n readonly component: (props: TProps) => Promise<RscNode> | RscNode;\n readonly props?: TProps;\n}\n\nexport interface RenderServerComponentResult {\n readonly tree: RscNode;\n readonly signal: RscSignal | null;\n readonly error: unknown;\n}\n\nfunction isRscElement(node: unknown): node is RscElement {\n if (typeof node !== 'object' || node === null) return false;\n const candidate = node as { type?: unknown; props?: unknown };\n return (\n typeof candidate.type !== 'undefined' &&\n typeof candidate.props === 'object' &&\n candidate.props !== null\n );\n}\n\nfunction isNotFound(value: unknown): value is NotFoundSignal {\n return typeof value === 'object' && value !== null && (value as { [NOT_FOUND_SYMBOL]?: true })[NOT_FOUND_SYMBOL] === true;\n}\nfunction isForbidden(value: unknown): value is ForbiddenSignal {\n return typeof value === 'object' && value !== null && (value as { [FORBIDDEN_SYMBOL]?: true })[FORBIDDEN_SYMBOL] === true;\n}\nfunction isRscRedirect(value: unknown): value is RscRedirectSignal {\n return typeof value === 'object' && value !== null && (value as { [RSC_REDIRECT_SYMBOL]?: true })[RSC_REDIRECT_SYMBOL] === true;\n}\n\n/**\n * Recursively walk an RSC tree and collect every node that satisfies the\n * predicate. Children are read from `props.children` and are normalized to a\n * flat array regardless of how the component spelled them.\n */\nexport function findAll(tree: RscNode, predicate: (node: RscElement) => boolean): RscElement[] {\n const out: RscElement[] = [];\n function visit(node: RscNode): void {\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (!isRscElement(node)) return;\n if (predicate(node)) out.push(node);\n const children = node.props.children;\n if (typeof children !== 'undefined') {\n visit(children as RscNode);\n }\n }\n visit(tree);\n return out;\n}\n\n/**\n * Concatenate every string/number leaf of an RSC tree, joined by a single\n * space. Useful for `expect(textContent(tree)).toContain('hello')` style\n * assertions where the exact element structure does not matter.\n */\nexport function textContent(tree: RscNode): string {\n const parts: string[] = [];\n function visit(node: RscNode): void {\n if (Array.isArray(node)) {\n node.forEach(visit);\n return;\n }\n if (typeof node === 'string' || typeof node === 'number') {\n parts.push(String(node));\n return;\n }\n if (isRscElement(node)) {\n const children = node.props.children;\n if (typeof children !== 'undefined') visit(children as RscNode);\n }\n }\n visit(tree);\n return parts.filter((p) => p.length > 0).join(' ');\n}\n\n/**\n * Invoke an async server component in isolation and capture its return tree.\n * Throws of `notFound() / forbidden() / redirect()` from `next/navigation`\n * should be replaced with the kiwa signals below (Pattern A from the\n * server-action seam doc); the helper normalizes them into `result.signal`\n * instead of leaving them as `result.error`.\n */\nexport async function renderServerComponent<TProps = Record<string, unknown>>(\n opts: RenderServerComponentOptions<TProps>,\n): Promise<RenderServerComponentResult> {\n let tree: RscNode = null;\n let signal: RscSignal | null = null;\n let error: unknown;\n const props = (opts.props ?? ({} as TProps)) as TProps;\n try {\n const result = await opts.component(props);\n tree = result;\n } catch (caught) {\n if (isNotFound(caught) || isForbidden(caught) || isRscRedirect(caught)) {\n signal = caught;\n } else {\n error = caught;\n }\n }\n return { tree, signal, error };\n}\n","// Next.js App Router Parallel Routes test helper for kiwa (Issue #523).\n//\n// Parallel Routes let an App Router layout render multiple async components in\n// named slots: `layout({ children, @modal, @sidebar })`. Each slot may also\n// provide a `default.tsx` fallback when no matching segment is present, and\n// the URL pattern `(.)`/`(..)`/`(...)` enables Intercepting Routes that swap\n// the slot rendering based on soft-vs-hard navigation.\n//\n// kiwa renders the layout in isolation with synthetic slot trees. The helper\n// awaits all slot promises in parallel (mirroring the React parallel-render\n// semantics), supplies optional Intercepting-Route resolution, and captures\n// errors per slot so a single failing slot does not collapse the whole tree.\n//\n// Out of scope on purpose:\n// - real flight payload / React renderer (use `renderServerComponent` for\n// leaf-level RSC introspection)\n// - matcher / `loading.tsx` / `error.tsx` evaluation\n// - client component boundary (`'use client'`)\n\nexport const PARALLEL_INTERCEPTION_SYMBOL = Symbol.for('kiwa.next.parallel.interception');\n\nexport interface InterceptionMatch<TSlot extends string> {\n readonly [PARALLEL_INTERCEPTION_SYMBOL]: true;\n readonly slot: TSlot;\n readonly variant: 'intercepted' | 'default';\n readonly url: string;\n readonly distance: 'sibling' | 'parent' | 'root';\n}\n\nexport type SlotComponent<TProps = Record<string, unknown>, TNode = unknown> = (\n props: TProps,\n) => Promise<TNode> | TNode;\n\nexport type DefaultFallbackComponent<TNode = unknown> = () => Promise<TNode> | TNode;\n\nexport interface ParallelLayoutChildren<TSlots extends string, TNode = unknown> {\n readonly children: TNode;\n readonly slots: Readonly<Record<TSlots, TNode>>;\n}\n\nexport type ParallelLayoutFunction<TSlots extends string, TLayoutProps, TNode = unknown> = (\n props: TLayoutProps & ParallelLayoutChildren<TSlots, TNode>,\n) => Promise<TNode> | TNode;\n\nexport interface SlotInput<TSlots extends string, TNode = unknown> {\n readonly slot: TSlots;\n readonly component: SlotComponent<Record<string, unknown>, TNode> | null;\n readonly props?: Record<string, unknown>;\n readonly defaultFallback?: DefaultFallbackComponent<TNode>;\n readonly intercepting?: {\n readonly variant: 'intercepted' | 'default';\n readonly url: string;\n readonly distance?: 'sibling' | 'parent' | 'root';\n };\n}\n\nexport interface InvokeParallelRoutesOptions<TSlots extends string, TLayoutProps, TNode = unknown> {\n readonly layout: ParallelLayoutFunction<TSlots, TLayoutProps, TNode>;\n readonly children: SlotComponent<Record<string, unknown>, TNode>;\n readonly childrenProps?: Record<string, unknown>;\n readonly slots: ReadonlyArray<SlotInput<TSlots, TNode>>;\n readonly layoutProps?: TLayoutProps;\n}\n\nexport interface SlotRenderResult<TSlots extends string, TNode = unknown> {\n readonly slot: TSlots;\n readonly tree: TNode | null;\n readonly usedDefault: boolean;\n readonly interception: InterceptionMatch<TSlots> | null;\n readonly error: unknown;\n}\n\nexport interface InvokeParallelRoutesResult<TSlots extends string, TNode = unknown> {\n readonly tree: TNode | null;\n readonly slotResults: ReadonlyArray<SlotRenderResult<TSlots, TNode>>;\n readonly childrenError: unknown;\n readonly layoutError: unknown;\n}\n\nasync function renderSlot<TSlots extends string, TNode>(\n input: SlotInput<TSlots, TNode>,\n): Promise<SlotRenderResult<TSlots, TNode>> {\n let tree: TNode | null = null;\n let usedDefault = false;\n let error: unknown;\n const interception: InterceptionMatch<TSlots> | null = input.intercepting\n ? {\n [PARALLEL_INTERCEPTION_SYMBOL]: true,\n slot: input.slot,\n variant: input.intercepting.variant,\n url: input.intercepting.url,\n distance: input.intercepting.distance ?? 'sibling',\n }\n : null;\n const useDefault =\n input.component === null ||\n interception?.variant === 'default';\n try {\n if (useDefault) {\n if (typeof input.defaultFallback !== 'function') {\n throw new Error(`slot ${input.slot}: no default.tsx fallback supplied`);\n }\n tree = await input.defaultFallback();\n usedDefault = true;\n } else if (input.component !== null) {\n tree = await input.component(input.props ?? {});\n }\n } catch (caught) {\n error = caught;\n }\n return { slot: input.slot, tree, usedDefault, interception, error };\n}\n\n/**\n * Invoke an App Router parallel-routes layout in isolation. All slot\n * components are rendered in parallel (Promise.all) so a slow slot cannot\n * block fast siblings; per-slot errors are captured into `slotResults`\n * without aborting the layout render.\n */\nexport async function invokeParallelRoutes<\n TSlots extends string,\n TLayoutProps = Record<string, unknown>,\n TNode = unknown,\n>(\n opts: InvokeParallelRoutesOptions<TSlots, TLayoutProps, TNode>,\n): Promise<InvokeParallelRoutesResult<TSlots, TNode>> {\n let childrenTree: TNode | null = null;\n let childrenError: unknown;\n let layoutError: unknown;\n try {\n childrenTree = await opts.children(opts.childrenProps ?? {});\n } catch (caught) {\n childrenError = caught;\n }\n const slotResults = await Promise.all(opts.slots.map((input) => renderSlot(input)));\n const slotMap: Record<string, TNode | null> = {};\n for (const result of slotResults) {\n slotMap[result.slot] = result.tree;\n }\n let tree: TNode | null = null;\n try {\n const props = {\n ...((opts.layoutProps ?? {}) as TLayoutProps),\n children: childrenTree as TNode,\n slots: slotMap as Readonly<Record<TSlots, TNode>>,\n } as TLayoutProps & ParallelLayoutChildren<TSlots, TNode>;\n tree = await opts.layout(props);\n } catch (caught) {\n layoutError = caught;\n }\n return { tree, slotResults, childrenError, layoutError };\n}\n","// Next.js React Server Components (RSC) streaming + Suspense boundary test\n// helper for kiwa (Issue #558, v1.3-1).\n//\n// Why this is a separate helper:\n//\n// `renderServerComponent` (Issue #494) handles the leaf-level \"await an async\n// server component and inspect the returned tree\" case. It does not model\n// streaming chunks (RSC payload arrives over multiple network frames) or\n// Suspense boundaries (a `<Suspense fallback={...}>` shows the fallback\n// first, then swaps to the resolved subtree once the data promise settles).\n//\n// `setupNextRscEnv` extends the testing seam to those two dimensions while\n// staying in the same \"no real React renderer / no Next.js dev server\"\n// philosophy: streaming is simulated as a flat array of chunks the component\n// yields in order, and Suspense is simulated as a two-phase\n// (fallback → resolved) transition that the helper drives deterministically.\n//\n// Out of scope (still):\n// - flight payload byte format / `react-server-dom-webpack` wire protocol\n// - actual React `renderToReadableStream` rendering\n// - client-side hydration after a chunk arrives\n// - concurrent multi-Suspense interleaving (one boundary per call)\n\nimport type { RscNode } from './render-server-component.js';\n\nexport const RSC_ERROR_BOUNDARY_SYMBOL = Symbol.for('kiwa.next.rsc.errorBoundary');\n\nexport interface RscErrorBoundarySignal {\n readonly [RSC_ERROR_BOUNDARY_SYMBOL]: true;\n readonly error: unknown;\n}\n\n/**\n * An async source the helper consumes chunk-by-chunk. Each yielded value is\n * one streaming frame; the helper appends it to `env.chunks` in arrival order\n * and uses the last chunk as `env.resolved` once the source completes.\n *\n * Use a plain async generator for most cases:\n *\n * async function* source() {\n * yield <Spinner />; // initial chunk\n * yield <Skeleton rows={3} />; // partial data\n * yield <Items list={data} />; // final resolved chunk\n * }\n */\nexport type RscStreamSource = AsyncIterable<RscNode>;\n\nexport interface SetupNextRscEnvOptions {\n /**\n * The async server component under test. If `dataSource` is omitted, the\n * helper awaits this function once and treats its return value as the only\n * (resolved) chunk — equivalent to a synchronous resolution.\n *\n * The component may throw to trigger the error boundary path. See\n * `injectError` for the test-side variant.\n */\n readonly component?: (props: Record<string, unknown>) => Promise<RscNode> | RscNode;\n /**\n * Optional props forwarded to `component`. Defaults to `{}`.\n */\n readonly props?: Record<string, unknown>;\n /**\n * Explicit streaming source. When provided, the helper iterates this and\n * ignores `component`. Useful when the production code already produces a\n * stream and the test wants to feed a deterministic sequence.\n */\n readonly dataSource?: RscStreamSource;\n /**\n * Markup shown while the (first) chunk is pending. Captured as\n * `env.fallback` so tests can assert that `<Suspense fallback={...}>`\n * surfaces the right loading state before the data arrives.\n */\n readonly suspenseFallback?: RscNode;\n /**\n * Hard timeout (ms) for the whole stream. If the source has not completed\n * by this deadline, the helper resolves with `env.timedOut = true` and the\n * chunks collected so far. Default 5000ms.\n */\n readonly streamingTimeout?: number;\n /**\n * Test-side error injection. When set, the helper short-circuits before\n * iterating the source and routes the error into `env.errorBoundary` —\n * the same shape a production `error.tsx` boundary would see.\n */\n readonly injectError?: unknown;\n}\n\nexport interface SetupNextRscEnvResult {\n /**\n * Streaming chunks in arrival order. For a Suspense boundary, the first\n * chunk is typically the fallback markup and the last chunk is the\n * resolved subtree.\n */\n readonly chunks: RscNode[];\n /**\n * The fallback markup captured before the source produced its first\n * non-fallback chunk. `null` when the test did not pass `suspenseFallback`\n * or when the source resolved synchronously without an explicit fallback.\n */\n readonly fallback: RscNode | null;\n /**\n * The last chunk yielded by the source — the markup a real Next.js page\n * would settle on after streaming finishes. `null` when the source threw\n * or timed out before producing any chunk.\n */\n readonly resolved: RscNode | null;\n /**\n * Set when the component or source threw, or when `injectError` was\n * provided. Mirrors the value a production `error.tsx` boundary receives.\n * `null` for happy-path streams.\n */\n readonly errorBoundary: RscErrorBoundarySignal | null;\n /**\n * `true` when `streamingTimeout` elapsed before the source completed.\n * `chunks` still contains any chunks that arrived before the deadline.\n */\n readonly timedOut: boolean;\n}\n\nconst DEFAULT_STREAMING_TIMEOUT_MS = 5000;\n\nfunction buildErrorBoundary(error: unknown): RscErrorBoundarySignal {\n return { [RSC_ERROR_BOUNDARY_SYMBOL]: true, error };\n}\n\nasync function runWithTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n): Promise<{ value: T | null; timedOut: boolean }> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<{ value: null; timedOut: true }>((resolve) => {\n timer = setTimeout(() => resolve({ value: null, timedOut: true }), timeoutMs);\n });\n try {\n const value = await Promise.race([\n promise.then((v) => ({ value: v, timedOut: false as const })),\n timeout,\n ]);\n return value;\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nasync function collectStream(\n source: RscStreamSource,\n fallback: RscNode | null,\n): Promise<{ chunks: RscNode[]; resolved: RscNode | null; thrown: unknown }> {\n const chunks: RscNode[] = [];\n // The fallback is the visible markup before the first real chunk arrives —\n // we record it as chunk 0 so tests can `expect(chunks[0]).toBe(fallback)`.\n if (typeof fallback !== 'undefined' && fallback !== null) {\n chunks.push(fallback);\n }\n try {\n for await (const chunk of source) {\n chunks.push(chunk);\n }\n } catch (err) {\n return { chunks, resolved: null, thrown: err };\n }\n const resolved = chunks.length > 0 ? (chunks[chunks.length - 1] ?? null) : null;\n // If the only chunk we have is the fallback, the source produced nothing —\n // resolved is null so tests can distinguish \"fallback shown forever\" from\n // \"fallback then resolved subtree\".\n const fallbackOnly =\n chunks.length === 1 && fallback !== null && Object.is(chunks[0], fallback);\n return { chunks, resolved: fallbackOnly ? null : resolved, thrown: undefined };\n}\n\nasync function* singleChunkSource(\n component: NonNullable<SetupNextRscEnvOptions['component']>,\n props: Record<string, unknown>,\n): AsyncGenerator<RscNode, void, unknown> {\n const result = await component(props);\n yield result;\n}\n\n/**\n * Drive an async RSC stream through a single Suspense boundary and capture\n * every chunk + the fallback + the resolved subtree + any error-boundary\n * trigger. The helper is deterministic — chunks arrive in the order the\n * source yields them, and the timeout is wall-clock-bounded so tests cannot\n * hang on a stuck stream.\n *\n * Typical usage:\n *\n * const env = await setupNextRscEnv({\n * dataSource: streamItems(),\n * suspenseFallback: <Skeleton />,\n * streamingTimeout: 1000,\n * });\n * expect(env.fallback).toEqual(<Skeleton />);\n * expect(env.chunks).toHaveLength(3);\n * expect(env.resolved).toEqual(<ItemList items={items} />);\n * expect(env.errorBoundary).toBeNull();\n * expect(env.timedOut).toBe(false);\n */\nexport async function setupNextRscEnv(\n opts: SetupNextRscEnvOptions = {},\n): Promise<SetupNextRscEnvResult> {\n const timeoutMs = opts.streamingTimeout ?? DEFAULT_STREAMING_TIMEOUT_MS;\n const fallback = opts.suspenseFallback ?? null;\n\n // streamingTimeout: 0 (or negative) means \"fail fast\" — used by tests that\n // want to assert the helper does not hang when a deadline is set to zero.\n // A microtask-resolved source would otherwise beat a 0ms setTimeout in\n // Promise.race, hiding the timeout path.\n if (timeoutMs <= 0 && (opts.dataSource || opts.component)) {\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: null,\n timedOut: true,\n };\n }\n\n // Test-side error injection short-circuits everything — no chunks, no\n // resolved tree, just the boundary signal.\n if (typeof opts.injectError !== 'undefined') {\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: buildErrorBoundary(opts.injectError),\n timedOut: false,\n };\n }\n\n if (!opts.dataSource && !opts.component) {\n // Nothing to render — return an empty env so the caller can assert on it.\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: null,\n timedOut: false,\n };\n }\n\n const source: RscStreamSource = opts.dataSource\n ? opts.dataSource\n : singleChunkSource(opts.component!, opts.props ?? {});\n\n const { value, timedOut } = await runWithTimeout(collectStream(source, fallback), timeoutMs);\n\n if (timedOut || value === null) {\n return {\n chunks: fallback !== null ? [fallback] : [],\n fallback,\n resolved: null,\n errorBoundary: null,\n timedOut: true,\n };\n }\n\n const { chunks, resolved, thrown } = value;\n\n if (typeof thrown !== 'undefined') {\n return {\n chunks,\n fallback,\n resolved: null,\n errorBoundary: buildErrorBoundary(thrown),\n timedOut: false,\n };\n }\n\n return {\n chunks,\n fallback,\n resolved,\n errorBoundary: null,\n timedOut: false,\n };\n}\n","/**\n * Advanced Next.js semantics — target-neutral axis SSOT.\n *\n * The helpers model App Router, Pages Router, and Edge Runtime behavior as\n * pure state machines. Tests can assert the neutral event while still seeing\n * a target-specific dialect through providerEventName.\n */\nexport type NextTarget = 'app-router' | 'pages-router' | 'edge-runtime';\n\nexport type NextAxis =\n | 'server-action-advanced'\n | 'partial-prerendering'\n | 'interception-routes'\n | 'parallel-routes-advanced'\n // v1.49 advanced III (pair 第 6 pair 3 段拡張)\n | 'turbopack-hmr'\n | 'concurrent-transitions';\n\nexport type NeutralEventName =\n | 'action.form_submitted'\n | 'action.revalidate_path'\n | 'action.revalidate_tag'\n | 'action.redirected'\n | 'ppr.static_shell_rendered'\n | 'ppr.dynamic_hole_opened'\n | 'ppr.streaming_boundary_flushed'\n | 'ppr.completed'\n | 'intercept.current_segment'\n | 'intercept.parent_segment'\n | 'intercept.root_catchall'\n | 'intercept.modal_opened'\n | 'parallel.default_rendered'\n | 'parallel.loading_rendered'\n | 'parallel.error_boundary_captured'\n | 'parallel.slot_navigated'\n // v1.49 turbopack-hmr\n | 'turbopack.module_updated'\n | 'turbopack.hmr_boundary_found'\n | 'turbopack.hmr_applied'\n | 'turbopack.fast_refresh_completed'\n // v1.49 concurrent-transitions\n | 'transition.started'\n | 'transition.pending'\n | 'transition.interrupted'\n | 'transition.committed';\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<NextTarget, Partial<Record<NeutralEventName, string>>> = {\n 'app-router': {\n 'action.form_submitted': 'app.server-action.form.submit',\n 'action.revalidate_path': 'app.cache.revalidatePath',\n 'action.revalidate_tag': 'app.cache.revalidateTag',\n 'action.redirected': 'app.navigation.redirect',\n 'ppr.static_shell_rendered': 'app.ppr.static-shell',\n 'ppr.dynamic_hole_opened': 'app.ppr.dynamic-hole',\n 'ppr.streaming_boundary_flushed': 'app.ppr.stream-boundary',\n 'ppr.completed': 'app.ppr.complete',\n 'intercept.current_segment': 'app.intercept.current',\n 'intercept.parent_segment': 'app.intercept.parent',\n 'intercept.root_catchall': 'app.intercept.root',\n 'intercept.modal_opened': 'app.intercept.modal',\n 'parallel.default_rendered': 'app.parallel.default',\n 'parallel.loading_rendered': 'app.parallel.loading',\n 'parallel.error_boundary_captured': 'app.parallel.error',\n 'parallel.slot_navigated': 'app.parallel.navigate',\n 'turbopack.module_updated': 'app.turbopack.module.update',\n 'turbopack.hmr_boundary_found': 'app.turbopack.hmr.boundary',\n 'turbopack.hmr_applied': 'app.turbopack.hmr.apply',\n 'turbopack.fast_refresh_completed': 'app.turbopack.fast-refresh',\n 'transition.started': 'app.transition.start',\n 'transition.pending': 'app.transition.pending',\n 'transition.interrupted': 'app.transition.interrupt',\n 'transition.committed': 'app.transition.commit',\n },\n 'pages-router': {\n 'action.form_submitted': 'pages.api.form.submit',\n 'action.revalidate_path': 'pages.isr.revalidate',\n 'action.revalidate_tag': 'pages.cache.tag.noop',\n 'action.redirected': 'pages.router.redirect',\n 'ppr.static_shell_rendered': 'pages.ssg.shell',\n 'ppr.dynamic_hole_opened': 'pages.ssr.dynamic-hole',\n 'ppr.streaming_boundary_flushed': 'pages.stream.boundary',\n 'ppr.completed': 'pages.render.complete',\n 'intercept.current_segment': 'pages.intercept.current',\n 'intercept.parent_segment': 'pages.intercept.parent',\n 'intercept.root_catchall': 'pages.intercept.root',\n 'intercept.modal_opened': 'pages.modal.open',\n 'parallel.default_rendered': 'pages.slot.default',\n 'parallel.loading_rendered': 'pages.slot.loading',\n 'parallel.error_boundary_captured': 'pages.slot.error',\n 'parallel.slot_navigated': 'pages.slot.navigate',\n 'turbopack.module_updated': 'pages.webpack.module.update',\n 'turbopack.hmr_boundary_found': 'pages.webpack.hmr.boundary',\n 'turbopack.hmr_applied': 'pages.webpack.hmr.apply',\n 'turbopack.fast_refresh_completed': 'pages.webpack.fast-refresh',\n 'transition.started': 'pages.transition.start',\n 'transition.pending': 'pages.transition.pending',\n 'transition.interrupted': 'pages.transition.interrupt',\n 'transition.committed': 'pages.transition.commit',\n },\n 'edge-runtime': {\n 'action.form_submitted': 'edge.action.form.submit',\n 'action.revalidate_path': 'edge.cache.revalidatePath',\n 'action.revalidate_tag': 'edge.cache.revalidateTag',\n 'action.redirected': 'edge.response.redirect',\n 'ppr.static_shell_rendered': 'edge.ppr.static-shell',\n 'ppr.dynamic_hole_opened': 'edge.ppr.dynamic-hole',\n 'ppr.streaming_boundary_flushed': 'edge.stream.boundary',\n 'ppr.completed': 'edge.ppr.complete',\n 'intercept.current_segment': 'edge.intercept.current',\n 'intercept.parent_segment': 'edge.intercept.parent',\n 'intercept.root_catchall': 'edge.intercept.root',\n 'intercept.modal_opened': 'edge.modal.open',\n 'parallel.default_rendered': 'edge.parallel.default',\n 'parallel.loading_rendered': 'edge.parallel.loading',\n 'parallel.error_boundary_captured': 'edge.parallel.error',\n 'parallel.slot_navigated': 'edge.parallel.navigate',\n 'turbopack.module_updated': 'edge.esbuild.module.update',\n 'turbopack.hmr_boundary_found': 'edge.esbuild.hmr.boundary',\n 'turbopack.hmr_applied': 'edge.esbuild.hmr.apply',\n 'turbopack.fast_refresh_completed': 'edge.esbuild.fast-refresh',\n 'transition.started': 'edge.transition.start',\n 'transition.pending': 'edge.transition.pending',\n 'transition.interrupted': 'edge.transition.interrupt',\n 'transition.committed': 'edge.transition.commit',\n },\n};\n\nexport function providerEventName(target: NextTarget, neutral: NeutralEventName): string {\n return dialect[target][neutral] ?? neutral;\n}\n","import { providerEventName, type AxisStep, type NextTarget } from './types.js';\n\nexport type ServerActionAdvancedState =\n | 'idle'\n | 'submitted'\n | 'path-revalidated'\n | 'tag-revalidated'\n | 'redirected';\n\nexport interface ServerActionAdvancedSession {\n target: NextTarget;\n actionId: string;\n state: ServerActionAdvancedState;\n form: Record<string, string>;\n revalidatedPaths: string[];\n revalidatedTags: string[];\n redirectUrl: string | null;\n history: AxisStep<ServerActionAdvancedState>[];\n}\n\nexport function startServerActionAdvanced(input: {\n target: NextTarget;\n actionId: string;\n}): ServerActionAdvancedSession {\n if (input.actionId.length === 0) {\n throw new Error('startServerActionAdvanced: actionId must not be empty');\n }\n return {\n target: input.target,\n actionId: input.actionId,\n state: 'idle',\n form: {},\n revalidatedPaths: [],\n revalidatedTags: [],\n redirectUrl: null,\n history: [],\n };\n}\n\nexport function submitFormAction(\n session: ServerActionAdvancedSession,\n form: Record<string, string>,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state !== 'idle') {\n throw new Error(`submitFormAction: session is ${session.state}, not idle`);\n }\n session.state = 'submitted';\n session.form = { ...form };\n return emit(session, 'action.form_submitted', {\n fields: Object.keys(form).join(','),\n fieldCount: Object.keys(form).length,\n });\n}\n\nexport function revalidateActionPath(\n session: ServerActionAdvancedSession,\n path: string,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state === 'idle') {\n throw new Error('revalidateActionPath: form action was not submitted');\n }\n if (!path.startsWith('/')) {\n throw new Error('revalidateActionPath: path must start with /');\n }\n session.state = 'path-revalidated';\n session.revalidatedPaths.push(path);\n return emit(session, 'action.revalidate_path', { path, count: session.revalidatedPaths.length });\n}\n\nexport function revalidateActionTag(\n session: ServerActionAdvancedSession,\n tag: string,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state === 'idle') {\n throw new Error('revalidateActionTag: form action was not submitted');\n }\n if (tag.length === 0) {\n throw new Error('revalidateActionTag: tag must not be empty');\n }\n session.state = 'tag-revalidated';\n session.revalidatedTags.push(tag);\n return emit(session, 'action.revalidate_tag', { tag, count: session.revalidatedTags.length });\n}\n\nexport function redirectAction(\n session: ServerActionAdvancedSession,\n url: string,\n): AxisStep<ServerActionAdvancedState> {\n if (session.state === 'idle') {\n throw new Error('redirectAction: form action was not submitted');\n }\n if (url.length === 0) {\n throw new Error('redirectAction: url must not be empty');\n }\n session.state = 'redirected';\n session.redirectUrl = url;\n return emit(session, 'action.redirected', { url });\n}\n\nfunction emit(\n session: ServerActionAdvancedSession,\n neutralEvent: AxisStep<ServerActionAdvancedState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ServerActionAdvancedState> {\n const step: AxisStep<ServerActionAdvancedState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, actionId: session.actionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type AxisStep, type NextTarget } from './types.js';\n\nexport type PartialPrerenderingState = 'idle' | 'static-shell' | 'dynamic-hole' | 'streaming' | 'completed';\n\nexport interface PartialPrerenderingSession {\n target: NextTarget;\n routeId: string;\n state: PartialPrerenderingState;\n shellHtml: string | null;\n dynamicHoles: Map<string, string>;\n streamedBoundaries: string[];\n history: AxisStep<PartialPrerenderingState>[];\n}\n\nexport function startPartialPrerendering(input: {\n target: NextTarget;\n routeId: string;\n}): PartialPrerenderingSession {\n if (input.routeId.length === 0) {\n throw new Error('startPartialPrerendering: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n state: 'idle',\n shellHtml: null,\n dynamicHoles: new Map(),\n streamedBoundaries: [],\n history: [],\n };\n}\n\nexport function renderStaticShell(\n session: PartialPrerenderingSession,\n html: string,\n): AxisStep<PartialPrerenderingState> {\n if (session.state !== 'idle') {\n throw new Error(`renderStaticShell: session is ${session.state}, not idle`);\n }\n if (html.length === 0) {\n throw new Error('renderStaticShell: html must not be empty');\n }\n session.state = 'static-shell';\n session.shellHtml = html;\n return emit(session, 'ppr.static_shell_rendered', { bytes: html.length });\n}\n\nexport function openDynamicHole(\n session: PartialPrerenderingSession,\n input: { holeId: string; fallback: string },\n): AxisStep<PartialPrerenderingState> {\n if (session.shellHtml === null) {\n throw new Error('openDynamicHole: static shell must be rendered first');\n }\n if (input.holeId.length === 0) {\n throw new Error('openDynamicHole: holeId must not be empty');\n }\n session.state = 'dynamic-hole';\n session.dynamicHoles.set(input.holeId, input.fallback);\n return emit(session, 'ppr.dynamic_hole_opened', {\n holeId: input.holeId,\n fallback: input.fallback,\n holeCount: session.dynamicHoles.size,\n });\n}\n\nexport function flushStreamingBoundary(\n session: PartialPrerenderingSession,\n input: { holeId: string; html: string },\n): AxisStep<PartialPrerenderingState> {\n if (!session.dynamicHoles.has(input.holeId)) {\n throw new Error(`flushStreamingBoundary: ${input.holeId} is not an open dynamic hole`);\n }\n if (input.html.length === 0) {\n throw new Error('flushStreamingBoundary: html must not be empty');\n }\n session.state = 'streaming';\n session.streamedBoundaries.push(input.holeId);\n session.dynamicHoles.set(input.holeId, input.html);\n return emit(session, 'ppr.streaming_boundary_flushed', {\n holeId: input.holeId,\n bytes: input.html.length,\n });\n}\n\nexport function completePartialPrerendering(\n session: PartialPrerenderingSession,\n): AxisStep<PartialPrerenderingState> {\n if (session.shellHtml === null) {\n throw new Error('completePartialPrerendering: static shell was not rendered');\n }\n session.state = 'completed';\n return emit(session, 'ppr.completed', {\n holeCount: session.dynamicHoles.size,\n streamedCount: session.streamedBoundaries.length,\n });\n}\n\nfunction emit(\n session: PartialPrerenderingSession,\n neutralEvent: AxisStep<PartialPrerenderingState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<PartialPrerenderingState> {\n const step: AxisStep<PartialPrerenderingState> = {\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 NextTarget } from './types.js';\n\nexport type InterceptionRoutesState = 'idle' | 'current' | 'parent' | 'root' | 'modal-open';\nexport type InterceptionMatcher = '(.)' | '(..)' | '(...)';\n\nexport interface InterceptionRoutesSession {\n target: NextTarget;\n routeId: string;\n state: InterceptionRoutesState;\n matches: Array<{ matcher: InterceptionMatcher; from: string; to: string }>;\n modalRoute: string | null;\n history: AxisStep<InterceptionRoutesState>[];\n}\n\nexport function startInterceptionRoutes(input: {\n target: NextTarget;\n routeId: string;\n}): InterceptionRoutesSession {\n if (input.routeId.length === 0) {\n throw new Error('startInterceptionRoutes: routeId must not be empty');\n }\n return {\n target: input.target,\n routeId: input.routeId,\n state: 'idle',\n matches: [],\n modalRoute: null,\n history: [],\n };\n}\n\nexport function interceptCurrentSegment(\n session: InterceptionRoutesSession,\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n return intercept(session, '(.)', 'current', 'intercept.current_segment', from, to);\n}\n\nexport function interceptParentSegment(\n session: InterceptionRoutesSession,\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n return intercept(session, '(..)', 'parent', 'intercept.parent_segment', from, to);\n}\n\nexport function interceptRootCatchall(\n session: InterceptionRoutesSession,\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n return intercept(session, '(...)', 'root', 'intercept.root_catchall', from, to);\n}\n\nexport function openInterceptedModal(\n session: InterceptionRoutesSession,\n modalRoute: string,\n): AxisStep<InterceptionRoutesState> {\n if (modalRoute.length === 0) {\n throw new Error('openInterceptedModal: modalRoute must not be empty');\n }\n if (session.matches.length === 0) {\n throw new Error('openInterceptedModal: an interception match is required first');\n }\n session.state = 'modal-open';\n session.modalRoute = modalRoute;\n return emit(session, 'intercept.modal_opened', {\n modalRoute,\n matchCount: session.matches.length,\n });\n}\n\nfunction intercept(\n session: InterceptionRoutesSession,\n matcher: InterceptionMatcher,\n state: InterceptionRoutesState,\n neutralEvent: AxisStep<InterceptionRoutesState>['neutralEvent'],\n from: string,\n to: string,\n): AxisStep<InterceptionRoutesState> {\n if (!from.startsWith('/') || !to.startsWith('/')) {\n throw new Error('intercept: from and to must start with /');\n }\n session.state = state;\n session.matches.push({ matcher, from, to });\n return emit(session, neutralEvent, { matcher, from, to });\n}\n\nfunction emit(\n session: InterceptionRoutesSession,\n neutralEvent: AxisStep<InterceptionRoutesState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<InterceptionRoutesState> {\n const step: AxisStep<InterceptionRoutesState> = {\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 NextTarget } from './types.js';\n\nexport type ParallelRoutesAdvancedState =\n | 'idle'\n | 'default-rendered'\n | 'loading-rendered'\n | 'error-captured'\n | 'slot-navigated';\n\nexport interface ParallelRoutesAdvancedSession {\n target: NextTarget;\n layoutId: string;\n state: ParallelRoutesAdvancedState;\n slots: Map<string, string>;\n loadingSlots: Set<string>;\n errors: Array<{ slot: string; message: string }>;\n history: AxisStep<ParallelRoutesAdvancedState>[];\n}\n\nexport function startParallelRoutesAdvanced(input: {\n target: NextTarget;\n layoutId: string;\n}): ParallelRoutesAdvancedSession {\n if (input.layoutId.length === 0) {\n throw new Error('startParallelRoutesAdvanced: layoutId must not be empty');\n }\n return {\n target: input.target,\n layoutId: input.layoutId,\n state: 'idle',\n slots: new Map(),\n loadingSlots: new Set(),\n errors: [],\n history: [],\n };\n}\n\nexport function renderDefaultSlot(\n session: ParallelRoutesAdvancedSession,\n slot: string,\n html: string,\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(slot);\n session.state = 'default-rendered';\n session.slots.set(slot, html);\n return emit(session, 'parallel.default_rendered', { slot, html });\n}\n\nexport function renderLoadingState(\n session: ParallelRoutesAdvancedSession,\n slot: string,\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(slot);\n session.state = 'loading-rendered';\n session.loadingSlots.add(slot);\n return emit(session, 'parallel.loading_rendered', {\n slot,\n loadingCount: session.loadingSlots.size,\n });\n}\n\nexport function captureParallelError(\n session: ParallelRoutesAdvancedSession,\n input: { slot: string; error: Error | string },\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(input.slot);\n const message = typeof input.error === 'string' ? input.error : input.error.message;\n session.state = 'error-captured';\n session.errors.push({ slot: input.slot, message });\n return emit(session, 'parallel.error_boundary_captured', {\n slot: input.slot,\n message,\n errorCount: session.errors.length,\n });\n}\n\nexport function navigateSlot(\n session: ParallelRoutesAdvancedSession,\n input: { slot: string; from: string; to: string },\n): AxisStep<ParallelRoutesAdvancedState> {\n assertSlot(input.slot);\n if (!input.from.startsWith('/') || !input.to.startsWith('/')) {\n throw new Error('navigateSlot: from and to must start with /');\n }\n session.state = 'slot-navigated';\n session.loadingSlots.delete(input.slot);\n return emit(session, 'parallel.slot_navigated', input);\n}\n\nfunction assertSlot(slot: string): void {\n if (slot.length === 0) {\n throw new Error('slot must not be empty');\n }\n}\n\nfunction emit(\n session: ParallelRoutesAdvancedSession,\n neutralEvent: AxisStep<ParallelRoutesAdvancedState>['neutralEvent'],\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ParallelRoutesAdvancedState> {\n const step: AxisStep<ParallelRoutesAdvancedState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { target: session.target, layoutId: session.layoutId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n","import { providerEventName, type NeutralEventName, type NextAxis, type NextTarget } from './types.js';\n\nexport interface FidelityRow {\n provider: NextTarget;\n axis: NextAxis;\n neutralEvents: NeutralEventName[];\n providerEvents: string[];\n}\n\nexport interface FidelityCoverage {\n providers: NextTarget[];\n axes: NextAxis[];\n rows: FidelityRow[];\n}\n\nexport const NEXT_AXIS_TO_EVENTS: Record<NextAxis, NeutralEventName[]> = {\n 'server-action-advanced': [\n 'action.form_submitted',\n 'action.revalidate_path',\n 'action.revalidate_tag',\n 'action.redirected',\n ],\n 'partial-prerendering': [\n 'ppr.static_shell_rendered',\n 'ppr.dynamic_hole_opened',\n 'ppr.streaming_boundary_flushed',\n 'ppr.completed',\n ],\n 'interception-routes': [\n 'intercept.current_segment',\n 'intercept.parent_segment',\n 'intercept.root_catchall',\n 'intercept.modal_opened',\n ],\n 'parallel-routes-advanced': [\n 'parallel.default_rendered',\n 'parallel.loading_rendered',\n 'parallel.error_boundary_captured',\n 'parallel.slot_navigated',\n ],\n // v1.49 advanced III\n 'turbopack-hmr': [\n 'turbopack.module_updated',\n 'turbopack.hmr_boundary_found',\n 'turbopack.hmr_applied',\n 'turbopack.fast_refresh_completed',\n ],\n 'concurrent-transitions': [\n 'transition.started',\n 'transition.pending',\n 'transition.interrupted',\n 'transition.committed',\n ],\n};\n\nexport function collectFidelityCoverage(\n providers: NextTarget[] = ['app-router', 'pages-router', 'edge-runtime'],\n): FidelityCoverage {\n const axes = Object.keys(NEXT_AXIS_TO_EVENTS) as NextAxis[];\n const rows: FidelityRow[] = [];\n for (const provider of providers) {\n for (const axis of axes) {\n const neutralEvents = NEXT_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 NextTarget } from './types.js';\n\n/**\n * v1.49 turbopack-hmr axis — Next.js 15 Turbopack HMR + fast refresh を\n * target-neutral に扱う state machine。 pages-router では webpack HMR、\n * edge-runtime では esbuild HMR に mapping。\n */\nexport type TurbopackHmrState = 'idle' | 'updating' | 'boundary-found' | 'applied' | 'refresh-completed';\n\nexport interface TurbopackHmrSession {\n target: NextTarget;\n sessionId: string;\n updatedModuleIds: string[];\n boundaryModuleId: string | null;\n state: TurbopackHmrState;\n history: AxisStep<TurbopackHmrState>[];\n}\n\nfunction emit(\n session: TurbopackHmrSession,\n neutralEvent:\n | 'turbopack.module_updated'\n | 'turbopack.hmr_boundary_found'\n | 'turbopack.hmr_applied'\n | 'turbopack.fast_refresh_completed',\n metadata: Record<string, string | number | boolean>,\n): AxisStep<TurbopackHmrState> {\n const step: AxisStep<TurbopackHmrState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { sessionId: session.sessionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n\nexport function startTurbopackHmr(input: {\n target: NextTarget;\n sessionId: string;\n}): TurbopackHmrSession {\n if (input.sessionId.length === 0) {\n throw new Error('startTurbopackHmr: sessionId must not be empty');\n }\n return {\n target: input.target,\n sessionId: input.sessionId,\n updatedModuleIds: [],\n boundaryModuleId: null,\n state: 'idle',\n history: [],\n };\n}\n\nexport function markModuleUpdated(\n session: TurbopackHmrSession,\n moduleId: string,\n): AxisStep<TurbopackHmrState> {\n session.updatedModuleIds.push(moduleId);\n session.state = 'updating';\n return emit(session, 'turbopack.module_updated', {\n moduleId,\n updateCount: session.updatedModuleIds.length,\n });\n}\n\nexport function findHmrBoundary(\n session: TurbopackHmrSession,\n boundaryModuleId: string,\n): AxisStep<TurbopackHmrState> {\n if (session.state !== 'updating') {\n throw new Error(`findHmrBoundary: session is ${session.state}`);\n }\n session.boundaryModuleId = boundaryModuleId;\n session.state = 'boundary-found';\n return emit(session, 'turbopack.hmr_boundary_found', { boundaryModuleId });\n}\n\nexport function applyHmrPatch(\n session: TurbopackHmrSession,\n): AxisStep<TurbopackHmrState> {\n if (session.state !== 'boundary-found') {\n throw new Error(`applyHmrPatch: session is ${session.state}`);\n }\n session.state = 'applied';\n return emit(session, 'turbopack.hmr_applied', {\n updatedModuleCount: session.updatedModuleIds.length,\n });\n}\n\nexport function completeFastRefresh(\n session: TurbopackHmrSession,\n): AxisStep<TurbopackHmrState> {\n if (session.state !== 'applied') {\n throw new Error(`completeFastRefresh: session is ${session.state}`);\n }\n session.state = 'refresh-completed';\n return emit(session, 'turbopack.fast_refresh_completed', {\n updatedModuleCount: session.updatedModuleIds.length,\n });\n}\n","import { providerEventName, type AxisStep, type NextTarget } from './types.js';\n\n/**\n * v1.49 concurrent-transitions axis — React 18/19 concurrent features\n * (startTransition + useTransition + useDeferredValue) を target-neutral に\n * 扱う state machine。 interrupt-and-restart semantics も含む。\n */\nexport type ConcurrentTransitionState =\n | 'idle'\n | 'started'\n | 'pending'\n | 'interrupted'\n | 'committed';\n\nexport interface ConcurrentTransitionSession {\n target: NextTarget;\n transitionId: string;\n interruptions: number;\n pendingCount: number;\n state: ConcurrentTransitionState;\n committedValue: string | null;\n history: AxisStep<ConcurrentTransitionState>[];\n}\n\nfunction emit(\n session: ConcurrentTransitionSession,\n neutralEvent:\n | 'transition.started'\n | 'transition.pending'\n | 'transition.interrupted'\n | 'transition.committed',\n metadata: Record<string, string | number | boolean>,\n): AxisStep<ConcurrentTransitionState> {\n const step: AxisStep<ConcurrentTransitionState> = {\n neutralEvent,\n providerEvent: providerEventName(session.target, neutralEvent),\n state: session.state,\n amountCents: 0,\n metadata: { transitionId: session.transitionId, ...metadata },\n };\n session.history.push(step);\n return step;\n}\n\nexport function startConcurrentTransition(input: {\n target: NextTarget;\n transitionId: string;\n}): ConcurrentTransitionSession {\n if (input.transitionId.length === 0) {\n throw new Error('startConcurrentTransition: transitionId must not be empty');\n }\n const session: ConcurrentTransitionSession = {\n target: input.target,\n transitionId: input.transitionId,\n interruptions: 0,\n pendingCount: 0,\n state: 'started',\n committedValue: null,\n history: [],\n };\n emit(session, 'transition.started', { interruptions: 0 });\n return session;\n}\n\nexport function markTransitionPending(\n session: ConcurrentTransitionSession,\n): AxisStep<ConcurrentTransitionState> {\n if (session.state !== 'started' && session.state !== 'interrupted') {\n throw new Error(`markTransitionPending: session is ${session.state}`);\n }\n session.state = 'pending';\n session.pendingCount += 1;\n return emit(session, 'transition.pending', {\n pendingCount: session.pendingCount,\n });\n}\n\nexport function interruptTransition(\n session: ConcurrentTransitionSession,\n): AxisStep<ConcurrentTransitionState> {\n if (session.state !== 'pending') {\n throw new Error(`interruptTransition: session is ${session.state}`);\n }\n session.state = 'interrupted';\n session.interruptions += 1;\n return emit(session, 'transition.interrupted', {\n interruptions: session.interruptions,\n });\n}\n\nexport function commitTransition(\n session: ConcurrentTransitionSession,\n committedValue: string,\n): AxisStep<ConcurrentTransitionState> {\n if (session.state !== 'pending' && session.state !== 'started') {\n throw new Error(`commitTransition: session is ${session.state}`);\n }\n session.state = 'committed';\n session.committedValue = committedValue;\n return emit(session, 'transition.committed', {\n committedValue,\n totalInterruptions: session.interruptions,\n totalPending: session.pendingCount,\n });\n}\n","import type { NextTarget } from './semantics/types.js';\n\nexport type KiwaTestMode = 'mock' | 'real';\n\nexport interface ResolvedMode {\n mode: KiwaTestMode;\n provider: NextTarget;\n reason: 'default-mock' | 'kiwa-mode-real' | 'missing-key' | 'invalid-mode';\n}\n\nconst TARGET_KEY_ENV: Record<NextTarget, string> = {\n 'app-router': 'NEXT_APP_URL',\n 'pages-router': 'NEXT_PAGES_URL',\n 'edge-runtime': 'EDGE_RUNTIME_URL',\n};\n\nexport function resolveMode(\n provider: NextTarget,\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: NextTarget[] = ['app-router', 'pages-router', 'edge-runtime'];\n return providers.map((provider) => resolveMode(provider, env));\n}\n\nexport function assertMode(\n provider: NextTarget,\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":["emit","emit","emit","emit","emit"]}
package/dist/index.d.cts CHANGED
@@ -344,8 +344,8 @@ declare function setupNextRscEnv(opts?: SetupNextRscEnvOptions): Promise<SetupNe
344
344
  * a target-specific dialect through providerEventName.
345
345
  */
346
346
  type NextTarget = 'app-router' | 'pages-router' | 'edge-runtime';
347
- type NextAxis = 'server-action-advanced' | 'partial-prerendering' | 'interception-routes' | 'parallel-routes-advanced';
348
- type NeutralEventName = 'action.form_submitted' | 'action.revalidate_path' | 'action.revalidate_tag' | 'action.redirected' | 'ppr.static_shell_rendered' | 'ppr.dynamic_hole_opened' | 'ppr.streaming_boundary_flushed' | 'ppr.completed' | 'intercept.current_segment' | 'intercept.parent_segment' | 'intercept.root_catchall' | 'intercept.modal_opened' | 'parallel.default_rendered' | 'parallel.loading_rendered' | 'parallel.error_boundary_captured' | 'parallel.slot_navigated';
347
+ type NextAxis = 'server-action-advanced' | 'partial-prerendering' | 'interception-routes' | 'parallel-routes-advanced' | 'turbopack-hmr' | 'concurrent-transitions';
348
+ type NeutralEventName = 'action.form_submitted' | 'action.revalidate_path' | 'action.revalidate_tag' | 'action.redirected' | 'ppr.static_shell_rendered' | 'ppr.dynamic_hole_opened' | 'ppr.streaming_boundary_flushed' | 'ppr.completed' | 'intercept.current_segment' | 'intercept.parent_segment' | 'intercept.root_catchall' | 'intercept.modal_opened' | 'parallel.default_rendered' | 'parallel.loading_rendered' | 'parallel.error_boundary_captured' | 'parallel.slot_navigated' | 'turbopack.module_updated' | 'turbopack.hmr_boundary_found' | 'turbopack.hmr_applied' | 'turbopack.fast_refresh_completed' | 'transition.started' | 'transition.pending' | 'transition.interrupted' | 'transition.committed';
349
349
  interface AxisStep<TState extends string> {
350
350
  neutralEvent: NeutralEventName;
351
351
  providerEvent: string;
@@ -466,6 +466,52 @@ interface FidelityCoverage {
466
466
  declare const NEXT_AXIS_TO_EVENTS: Record<NextAxis, NeutralEventName[]>;
467
467
  declare function collectFidelityCoverage(providers?: NextTarget[]): FidelityCoverage;
468
468
 
469
+ /**
470
+ * v1.49 turbopack-hmr axis — Next.js 15 Turbopack HMR + fast refresh を
471
+ * target-neutral に扱う state machine。 pages-router では webpack HMR、
472
+ * edge-runtime では esbuild HMR に mapping。
473
+ */
474
+ type TurbopackHmrState = 'idle' | 'updating' | 'boundary-found' | 'applied' | 'refresh-completed';
475
+ interface TurbopackHmrSession {
476
+ target: NextTarget;
477
+ sessionId: string;
478
+ updatedModuleIds: string[];
479
+ boundaryModuleId: string | null;
480
+ state: TurbopackHmrState;
481
+ history: AxisStep<TurbopackHmrState>[];
482
+ }
483
+ declare function startTurbopackHmr(input: {
484
+ target: NextTarget;
485
+ sessionId: string;
486
+ }): TurbopackHmrSession;
487
+ declare function markModuleUpdated(session: TurbopackHmrSession, moduleId: string): AxisStep<TurbopackHmrState>;
488
+ declare function findHmrBoundary(session: TurbopackHmrSession, boundaryModuleId: string): AxisStep<TurbopackHmrState>;
489
+ declare function applyHmrPatch(session: TurbopackHmrSession): AxisStep<TurbopackHmrState>;
490
+ declare function completeFastRefresh(session: TurbopackHmrSession): AxisStep<TurbopackHmrState>;
491
+
492
+ /**
493
+ * v1.49 concurrent-transitions axis — React 18/19 concurrent features
494
+ * (startTransition + useTransition + useDeferredValue) を target-neutral に
495
+ * 扱う state machine。 interrupt-and-restart semantics も含む。
496
+ */
497
+ type ConcurrentTransitionState = 'idle' | 'started' | 'pending' | 'interrupted' | 'committed';
498
+ interface ConcurrentTransitionSession {
499
+ target: NextTarget;
500
+ transitionId: string;
501
+ interruptions: number;
502
+ pendingCount: number;
503
+ state: ConcurrentTransitionState;
504
+ committedValue: string | null;
505
+ history: AxisStep<ConcurrentTransitionState>[];
506
+ }
507
+ declare function startConcurrentTransition(input: {
508
+ target: NextTarget;
509
+ transitionId: string;
510
+ }): ConcurrentTransitionSession;
511
+ declare function markTransitionPending(session: ConcurrentTransitionSession): AxisStep<ConcurrentTransitionState>;
512
+ declare function interruptTransition(session: ConcurrentTransitionSession): AxisStep<ConcurrentTransitionState>;
513
+ declare function commitTransition(session: ConcurrentTransitionSession, committedValue: string): AxisStep<ConcurrentTransitionState>;
514
+
469
515
  type KiwaTestMode = 'mock' | 'real';
470
516
  interface ResolvedMode {
471
517
  mode: KiwaTestMode;
@@ -476,4 +522,4 @@ declare function resolveMode(provider: NextTarget, env?: Record<string, string |
476
522
  declare function resolveAllModes(env?: Record<string, string | undefined>): ResolvedMode[];
477
523
  declare function assertMode(provider: NextTarget, expected: KiwaTestMode, env?: Record<string, string | undefined>): void;
478
524
 
479
- export { type AxisStep, type CookieJar, type DefaultFallbackComponent, FORBIDDEN_SYMBOL, type FidelityCoverage, type FidelityRow, type ForbiddenSignal, type InterceptionMatch, type InterceptionMatcher, type InterceptionRoutesSession, type InterceptionRoutesState, type InvokeMiddlewareOptions, type InvokeMiddlewareResult, type InvokeParallelRoutesOptions, type InvokeParallelRoutesResult, type KiwaTestMode, MIDDLEWARE_ACTION_SYMBOL, type MiddlewareAction, type MiddlewareActionKind, type MiddlewareEnv, type MiddlewareFunction, type MiddlewareRequest, NEXT_AXIS_TO_EVENTS, NOT_FOUND_SYMBOL, type NeutralEventName, type NextAxis, type NextTarget, type NotFoundSignal, PARALLEL_INTERCEPTION_SYMBOL, type ParallelLayoutChildren, type ParallelLayoutFunction, type ParallelRoutesAdvancedSession, type ParallelRoutesAdvancedState, type PartialPrerenderingSession, type PartialPrerenderingState, REDIRECT_SYMBOL, RSC_ERROR_BOUNDARY_SYMBOL, RSC_REDIRECT_SYMBOL, type RedirectSignal, type RenderServerComponentOptions, type RenderServerComponentResult, type ResolvedMode, type RscElement, type RscErrorBoundarySignal, type RscNode, type RscRedirectSignal, type RscSignal, type RscStreamSource, type ServerActionAdvancedSession, type ServerActionAdvancedState, type ServerActionEnv, type ServerActionFunction, type ServerActionInvocation, type ServerActionResult, type SetupNextRscEnvOptions, type SetupNextRscEnvResult, type SlotComponent, type SlotInput, type SlotRenderResult, assertMode, captureParallelError, collectFidelityCoverage, completePartialPrerendering, findAll, flushStreamingBoundary, interceptCurrentSegment, interceptParentSegment, interceptRootCatchall, invokeMiddleware, invokeParallelRoutes, invokeServerAction, middlewareActions, navigateSlot, openDynamicHole, openInterceptedModal, providerEventName, redirectAction, renderDefaultSlot, renderLoadingState, renderServerComponent, renderStaticShell, resolveAllModes, resolveMode, revalidateActionPath, revalidateActionTag, setupNextRscEnv, startInterceptionRoutes, startParallelRoutesAdvanced, startPartialPrerendering, startServerActionAdvanced, submitFormAction, textContent };
525
+ export { type AxisStep, type ConcurrentTransitionSession, type ConcurrentTransitionState, type CookieJar, type DefaultFallbackComponent, FORBIDDEN_SYMBOL, type FidelityCoverage, type FidelityRow, type ForbiddenSignal, type InterceptionMatch, type InterceptionMatcher, type InterceptionRoutesSession, type InterceptionRoutesState, type InvokeMiddlewareOptions, type InvokeMiddlewareResult, type InvokeParallelRoutesOptions, type InvokeParallelRoutesResult, type KiwaTestMode, MIDDLEWARE_ACTION_SYMBOL, type MiddlewareAction, type MiddlewareActionKind, type MiddlewareEnv, type MiddlewareFunction, type MiddlewareRequest, NEXT_AXIS_TO_EVENTS, NOT_FOUND_SYMBOL, type NeutralEventName, type NextAxis, type NextTarget, type NotFoundSignal, PARALLEL_INTERCEPTION_SYMBOL, type ParallelLayoutChildren, type ParallelLayoutFunction, type ParallelRoutesAdvancedSession, type ParallelRoutesAdvancedState, type PartialPrerenderingSession, type PartialPrerenderingState, REDIRECT_SYMBOL, RSC_ERROR_BOUNDARY_SYMBOL, RSC_REDIRECT_SYMBOL, type RedirectSignal, type RenderServerComponentOptions, type RenderServerComponentResult, type ResolvedMode, type RscElement, type RscErrorBoundarySignal, type RscNode, type RscRedirectSignal, type RscSignal, type RscStreamSource, type ServerActionAdvancedSession, type ServerActionAdvancedState, type ServerActionEnv, type ServerActionFunction, type ServerActionInvocation, type ServerActionResult, type SetupNextRscEnvOptions, type SetupNextRscEnvResult, type SlotComponent, type SlotInput, type SlotRenderResult, type TurbopackHmrSession, type TurbopackHmrState, applyHmrPatch, assertMode, captureParallelError, collectFidelityCoverage, commitTransition, completeFastRefresh, completePartialPrerendering, findAll, findHmrBoundary, flushStreamingBoundary, interceptCurrentSegment, interceptParentSegment, interceptRootCatchall, interruptTransition, invokeMiddleware, invokeParallelRoutes, invokeServerAction, markModuleUpdated, markTransitionPending, middlewareActions, navigateSlot, openDynamicHole, openInterceptedModal, providerEventName, redirectAction, renderDefaultSlot, renderLoadingState, renderServerComponent, renderStaticShell, resolveAllModes, resolveMode, revalidateActionPath, revalidateActionTag, setupNextRscEnv, startConcurrentTransition, startInterceptionRoutes, startParallelRoutesAdvanced, startPartialPrerendering, startServerActionAdvanced, startTurbopackHmr, submitFormAction, textContent };
package/dist/index.d.ts CHANGED
@@ -344,8 +344,8 @@ declare function setupNextRscEnv(opts?: SetupNextRscEnvOptions): Promise<SetupNe
344
344
  * a target-specific dialect through providerEventName.
345
345
  */
346
346
  type NextTarget = 'app-router' | 'pages-router' | 'edge-runtime';
347
- type NextAxis = 'server-action-advanced' | 'partial-prerendering' | 'interception-routes' | 'parallel-routes-advanced';
348
- type NeutralEventName = 'action.form_submitted' | 'action.revalidate_path' | 'action.revalidate_tag' | 'action.redirected' | 'ppr.static_shell_rendered' | 'ppr.dynamic_hole_opened' | 'ppr.streaming_boundary_flushed' | 'ppr.completed' | 'intercept.current_segment' | 'intercept.parent_segment' | 'intercept.root_catchall' | 'intercept.modal_opened' | 'parallel.default_rendered' | 'parallel.loading_rendered' | 'parallel.error_boundary_captured' | 'parallel.slot_navigated';
347
+ type NextAxis = 'server-action-advanced' | 'partial-prerendering' | 'interception-routes' | 'parallel-routes-advanced' | 'turbopack-hmr' | 'concurrent-transitions';
348
+ type NeutralEventName = 'action.form_submitted' | 'action.revalidate_path' | 'action.revalidate_tag' | 'action.redirected' | 'ppr.static_shell_rendered' | 'ppr.dynamic_hole_opened' | 'ppr.streaming_boundary_flushed' | 'ppr.completed' | 'intercept.current_segment' | 'intercept.parent_segment' | 'intercept.root_catchall' | 'intercept.modal_opened' | 'parallel.default_rendered' | 'parallel.loading_rendered' | 'parallel.error_boundary_captured' | 'parallel.slot_navigated' | 'turbopack.module_updated' | 'turbopack.hmr_boundary_found' | 'turbopack.hmr_applied' | 'turbopack.fast_refresh_completed' | 'transition.started' | 'transition.pending' | 'transition.interrupted' | 'transition.committed';
349
349
  interface AxisStep<TState extends string> {
350
350
  neutralEvent: NeutralEventName;
351
351
  providerEvent: string;
@@ -466,6 +466,52 @@ interface FidelityCoverage {
466
466
  declare const NEXT_AXIS_TO_EVENTS: Record<NextAxis, NeutralEventName[]>;
467
467
  declare function collectFidelityCoverage(providers?: NextTarget[]): FidelityCoverage;
468
468
 
469
+ /**
470
+ * v1.49 turbopack-hmr axis — Next.js 15 Turbopack HMR + fast refresh を
471
+ * target-neutral に扱う state machine。 pages-router では webpack HMR、
472
+ * edge-runtime では esbuild HMR に mapping。
473
+ */
474
+ type TurbopackHmrState = 'idle' | 'updating' | 'boundary-found' | 'applied' | 'refresh-completed';
475
+ interface TurbopackHmrSession {
476
+ target: NextTarget;
477
+ sessionId: string;
478
+ updatedModuleIds: string[];
479
+ boundaryModuleId: string | null;
480
+ state: TurbopackHmrState;
481
+ history: AxisStep<TurbopackHmrState>[];
482
+ }
483
+ declare function startTurbopackHmr(input: {
484
+ target: NextTarget;
485
+ sessionId: string;
486
+ }): TurbopackHmrSession;
487
+ declare function markModuleUpdated(session: TurbopackHmrSession, moduleId: string): AxisStep<TurbopackHmrState>;
488
+ declare function findHmrBoundary(session: TurbopackHmrSession, boundaryModuleId: string): AxisStep<TurbopackHmrState>;
489
+ declare function applyHmrPatch(session: TurbopackHmrSession): AxisStep<TurbopackHmrState>;
490
+ declare function completeFastRefresh(session: TurbopackHmrSession): AxisStep<TurbopackHmrState>;
491
+
492
+ /**
493
+ * v1.49 concurrent-transitions axis — React 18/19 concurrent features
494
+ * (startTransition + useTransition + useDeferredValue) を target-neutral に
495
+ * 扱う state machine。 interrupt-and-restart semantics も含む。
496
+ */
497
+ type ConcurrentTransitionState = 'idle' | 'started' | 'pending' | 'interrupted' | 'committed';
498
+ interface ConcurrentTransitionSession {
499
+ target: NextTarget;
500
+ transitionId: string;
501
+ interruptions: number;
502
+ pendingCount: number;
503
+ state: ConcurrentTransitionState;
504
+ committedValue: string | null;
505
+ history: AxisStep<ConcurrentTransitionState>[];
506
+ }
507
+ declare function startConcurrentTransition(input: {
508
+ target: NextTarget;
509
+ transitionId: string;
510
+ }): ConcurrentTransitionSession;
511
+ declare function markTransitionPending(session: ConcurrentTransitionSession): AxisStep<ConcurrentTransitionState>;
512
+ declare function interruptTransition(session: ConcurrentTransitionSession): AxisStep<ConcurrentTransitionState>;
513
+ declare function commitTransition(session: ConcurrentTransitionSession, committedValue: string): AxisStep<ConcurrentTransitionState>;
514
+
469
515
  type KiwaTestMode = 'mock' | 'real';
470
516
  interface ResolvedMode {
471
517
  mode: KiwaTestMode;
@@ -476,4 +522,4 @@ declare function resolveMode(provider: NextTarget, env?: Record<string, string |
476
522
  declare function resolveAllModes(env?: Record<string, string | undefined>): ResolvedMode[];
477
523
  declare function assertMode(provider: NextTarget, expected: KiwaTestMode, env?: Record<string, string | undefined>): void;
478
524
 
479
- export { type AxisStep, type CookieJar, type DefaultFallbackComponent, FORBIDDEN_SYMBOL, type FidelityCoverage, type FidelityRow, type ForbiddenSignal, type InterceptionMatch, type InterceptionMatcher, type InterceptionRoutesSession, type InterceptionRoutesState, type InvokeMiddlewareOptions, type InvokeMiddlewareResult, type InvokeParallelRoutesOptions, type InvokeParallelRoutesResult, type KiwaTestMode, MIDDLEWARE_ACTION_SYMBOL, type MiddlewareAction, type MiddlewareActionKind, type MiddlewareEnv, type MiddlewareFunction, type MiddlewareRequest, NEXT_AXIS_TO_EVENTS, NOT_FOUND_SYMBOL, type NeutralEventName, type NextAxis, type NextTarget, type NotFoundSignal, PARALLEL_INTERCEPTION_SYMBOL, type ParallelLayoutChildren, type ParallelLayoutFunction, type ParallelRoutesAdvancedSession, type ParallelRoutesAdvancedState, type PartialPrerenderingSession, type PartialPrerenderingState, REDIRECT_SYMBOL, RSC_ERROR_BOUNDARY_SYMBOL, RSC_REDIRECT_SYMBOL, type RedirectSignal, type RenderServerComponentOptions, type RenderServerComponentResult, type ResolvedMode, type RscElement, type RscErrorBoundarySignal, type RscNode, type RscRedirectSignal, type RscSignal, type RscStreamSource, type ServerActionAdvancedSession, type ServerActionAdvancedState, type ServerActionEnv, type ServerActionFunction, type ServerActionInvocation, type ServerActionResult, type SetupNextRscEnvOptions, type SetupNextRscEnvResult, type SlotComponent, type SlotInput, type SlotRenderResult, assertMode, captureParallelError, collectFidelityCoverage, completePartialPrerendering, findAll, flushStreamingBoundary, interceptCurrentSegment, interceptParentSegment, interceptRootCatchall, invokeMiddleware, invokeParallelRoutes, invokeServerAction, middlewareActions, navigateSlot, openDynamicHole, openInterceptedModal, providerEventName, redirectAction, renderDefaultSlot, renderLoadingState, renderServerComponent, renderStaticShell, resolveAllModes, resolveMode, revalidateActionPath, revalidateActionTag, setupNextRscEnv, startInterceptionRoutes, startParallelRoutesAdvanced, startPartialPrerendering, startServerActionAdvanced, submitFormAction, textContent };
525
+ export { type AxisStep, type ConcurrentTransitionSession, type ConcurrentTransitionState, type CookieJar, type DefaultFallbackComponent, FORBIDDEN_SYMBOL, type FidelityCoverage, type FidelityRow, type ForbiddenSignal, type InterceptionMatch, type InterceptionMatcher, type InterceptionRoutesSession, type InterceptionRoutesState, type InvokeMiddlewareOptions, type InvokeMiddlewareResult, type InvokeParallelRoutesOptions, type InvokeParallelRoutesResult, type KiwaTestMode, MIDDLEWARE_ACTION_SYMBOL, type MiddlewareAction, type MiddlewareActionKind, type MiddlewareEnv, type MiddlewareFunction, type MiddlewareRequest, NEXT_AXIS_TO_EVENTS, NOT_FOUND_SYMBOL, type NeutralEventName, type NextAxis, type NextTarget, type NotFoundSignal, PARALLEL_INTERCEPTION_SYMBOL, type ParallelLayoutChildren, type ParallelLayoutFunction, type ParallelRoutesAdvancedSession, type ParallelRoutesAdvancedState, type PartialPrerenderingSession, type PartialPrerenderingState, REDIRECT_SYMBOL, RSC_ERROR_BOUNDARY_SYMBOL, RSC_REDIRECT_SYMBOL, type RedirectSignal, type RenderServerComponentOptions, type RenderServerComponentResult, type ResolvedMode, type RscElement, type RscErrorBoundarySignal, type RscNode, type RscRedirectSignal, type RscSignal, type RscStreamSource, type ServerActionAdvancedSession, type ServerActionAdvancedState, type ServerActionEnv, type ServerActionFunction, type ServerActionInvocation, type ServerActionResult, type SetupNextRscEnvOptions, type SetupNextRscEnvResult, type SlotComponent, type SlotInput, type SlotRenderResult, type TurbopackHmrSession, type TurbopackHmrState, applyHmrPatch, assertMode, captureParallelError, collectFidelityCoverage, commitTransition, completeFastRefresh, completePartialPrerendering, findAll, findHmrBoundary, flushStreamingBoundary, interceptCurrentSegment, interceptParentSegment, interceptRootCatchall, interruptTransition, invokeMiddleware, invokeParallelRoutes, invokeServerAction, markModuleUpdated, markTransitionPending, middlewareActions, navigateSlot, openDynamicHole, openInterceptedModal, providerEventName, redirectAction, renderDefaultSlot, renderLoadingState, renderServerComponent, renderStaticShell, resolveAllModes, resolveMode, revalidateActionPath, revalidateActionTag, setupNextRscEnv, startConcurrentTransition, startInterceptionRoutes, startParallelRoutesAdvanced, startPartialPrerendering, startServerActionAdvanced, startTurbopackHmr, submitFormAction, textContent };