// The bundle smoke, as part of the `compat` project: the only check that exercises the BUILT artifacts (lib/client.js) — the packaging glue // (the `window.__ModuleLoader__.load({id, factory})` handoff, the CSS channel's data-plugin style tags, platform-module requires) only // exists after tsdown runs. Skipped cleanly when lib/ is absent (run `pnpm run build` first); the release workflow builds before `pnpm // test`, so it always runs there. Everything here runs against the REAL bundle in its own JSDOM with REAL React and the REAL ui-primitives // — only the harness services (locale/slots/effects) are in-memory implementations of their documented contracts. import assert from 'node:assert/strict' import { readFileSync } from 'node:fs' import { join } from 'node:path' import { beforeAll, describe, test } from 'vitest' import { JSDOM } from 'jsdom' import React from 'react' import ReactDOM from 'react-dom' import * as jsxRuntime from 'react/jsx-runtime' import * as staging from './staging' describe.skipIf(staging.artifactsMissing())('bundle smoke — the built lib/client.js', () => { const dom = new JSDOM('', { pretendToBeVisual: true }) // The bundle evaluates against window-scoped globals; this spec owns its // worker (per-file fork), so the assignment stays file-local. const globals = globalThis as { window?: unknown; document?: unknown } let handoff: { id: string; factory: (require: (spec: string) => unknown) => unknown } | null = null /** Everything the assertions below look at, captured by the setup. */ const state: { plugin?: { name: string; inject: string[]; apply(ctx: unknown): void } dicts: Map>> slots: [string, { name?: string; order?: number; id?: string; label?: () => string; inject?: (sessionId?: string) => unknown }][] sources: { trigger: string }[] disposers: (() => void)[] } = { dicts: new Map(), slots: [], sources: [], disposers: [] } const styleTags = (): HTMLElement[] => [...dom.window.document.head.querySelectorAll('style[data-plugin="dsh-context"]')] beforeAll(() => { globals.window = dom.window globals.document = dom.window.document // The primitives dist ships CSS modules Node cannot parse — the bundle only // references its components as React leaves, so inert stand-ins play the // shell's role here (their real rendering is covered by the vitest jsdom lane). const inert = (name: string) => { const C = (): null => null ;(C as { displayName?: string }).displayName = name return C } const moduleTable = (spec: string): unknown => { if (spec === 'react') return React if (spec === 'react/jsx-runtime') return jsxRuntime if (spec === 'react-dom') return ReactDOM if (spec === '@deepseek-ai/dsh-client-ui-primitives') { return new Proxy({}, { get: (_t, key) => (typeof key === 'string' ? inert(key) : undefined) }) } throw new Error(`bundle required a non-platform module: ${spec}`) } ;(dom.window as { __ModuleLoader__: unknown }).__ModuleLoader__ = { load: (h: typeof handoff) => { handoff = h } } new Function(readFileSync(join(staging.REPO, 'lib', 'client.js'), 'utf8'))() assert.ok(handoff !== null, 'bundle must register through __ModuleLoader__.load') // Faithful harness services (documented contracts, in-memory). const removeFrom = (list: T[]) => (item: T) => () => { const i = list.indexOf(item) if (i >= 0) list.splice(i, 1) } const ctx: Record = { get(name: string) { if (name === 'inputTriggers') return { registerSource: (s: { trigger: string }) => { state.sources.push(s); return removeFrom(state.sources)(s) } } if (name === 'sessions') return { scope: () => undefined } return undefined }, inject(_deps: string[], cb: (c: unknown) => void) { // Cordis fires the callback once every requested service exists; this // fake answers every name it knows up front, so it fires immediately. // The configForms wiring guards on the absent service itself. cb(ctx) }, effect(fn: () => (() => void) | void) { const d = typeof fn === 'function' ? fn() : undefined if (typeof d === 'function') state.disposers.push(d) return d }, locale: { register: (ns: string, d: Record>) => { state.dicts.set(ns, d); return () => state.dicts.delete(ns) }, bind: (ns: string) => (key: string, vars?: Record) => { let s = state.dicts.get(ns)?.zh[key] ?? key if (vars) for (const k in vars) s = s.replace('{' + k + '}', String(vars[k])) return s }, }, slots: { // The registry records every `register()` call and returns its idempotent disposer; an `inject` // callback returns the declaration effect's own disposer (registry.ts `SlotInjectionEffect`), so the // return value is never the registration — one `inject` may declare several. inject: (_name: string, fn: () => unknown) => fn(), register: (opts: (typeof state.slots)[number][1]) => { state.slots.push([opts.name ?? '', opts]) return () => { const i = state.slots.findIndex(entry => entry[1] === opts) if (i >= 0) state.slots.splice(i, 1) } }, }, } state.plugin = handoff.factory(moduleTable) as typeof state.plugin state.plugin.apply(ctx) }) test('handoff: the bundle registers as dsh-context with the factory closure', () => { assert.ok(handoff !== null, 'bundle must register through __ModuleLoader__.load') assert.equal(handoff.id, 'dsh-context', 'handoff id is the package name') assert.equal(typeof handoff.factory, 'function') assert.equal(state.plugin?.name, 'dsh-context') assert.deepEqual(state.plugin?.inject, ['slots', 'locale']) }) test('CSS channel: plugin-owned style tags, one per sheet, minified', () => { assert.ok(styleTags().length > 1, 'plugin-owned