gesso-vite-plugin 0.6.1 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +43 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# gesso-vite-plugin
|
|
2
2
|
|
|
3
|
+
## 0.6.3
|
|
4
|
+
|
|
5
|
+
## 0.6.2
|
|
6
|
+
|
|
7
|
+
### Patch Changes
|
|
8
|
+
|
|
9
|
+
- e3615bf: The first start of a dev server no longer fails its first page load. Vite's dependency scan never saw the workers the shell constructs or the overlay and agent bridge it loads lazily, so an app with Gesso installed from npm found those packages only when the page asked for them: Vite re-optimized, answered "504 (Outdated Optimize Dep)" for modules already served, and reloaded. The plugin now shows the scan the shell as the dev server serves it and imports each worker entry for it, so everything is pre-bundled up front.
|
|
10
|
+
|
|
3
11
|
## 0.6.1
|
|
4
12
|
|
|
5
13
|
## 0.6.0
|
package/dist/index.js
CHANGED
|
@@ -1185,9 +1185,10 @@ function gesso(options = {}) {
|
|
|
1185
1185
|
return {
|
|
1186
1186
|
name: "gesso",
|
|
1187
1187
|
enforce: "pre",
|
|
1188
|
-
config(config) {
|
|
1188
|
+
config(config, env) {
|
|
1189
1189
|
return {
|
|
1190
1190
|
...options.workerConditions === false ? {} : { resolve: { conditions: [...workerConditions] } },
|
|
1191
|
+
...env.command === "serve" ? { optimizeDeps: { rolldownOptions: { plugins: [scanShell(options)] } } } : {},
|
|
1191
1192
|
worker: {
|
|
1192
1193
|
...config.worker?.format === void 0 ? { format: "es" } : {},
|
|
1193
1194
|
...options.channelSchemas === false ? {} : { plugins: () => [workerContracts] }
|
|
@@ -1290,6 +1291,47 @@ function gesso(options = {}) {
|
|
|
1290
1291
|
}
|
|
1291
1292
|
};
|
|
1292
1293
|
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Shows Vite's dependency scan what the dev server will actually load.
|
|
1296
|
+
*
|
|
1297
|
+
* Vite pre-bundles a dev server's dependencies from a scan that starts
|
|
1298
|
+
* at the HTML and follows imports. It runs none of the plugin's
|
|
1299
|
+
* transforms, so it never sees the workers the shell constructs, nor
|
|
1300
|
+
* the `gesso-devtools` overlay and `gesso-framework/agent` bridge the
|
|
1301
|
+
* shell loads lazily. Every Gesso package a worker imports was found
|
|
1302
|
+
* only when the page asked for it, which re-optimized, invalidated the
|
|
1303
|
+
* modules already served, and reloaded the page: on the first start of
|
|
1304
|
+
* any app installed from the registry, the first page load failed with
|
|
1305
|
+
* "504 (Outdated Optimize Dep)" and the overlay that would have
|
|
1306
|
+
* reported it failed the same way. A workspace that links Gesso from
|
|
1307
|
+
* source never met it, because linked packages are not pre-bundled.
|
|
1308
|
+
*
|
|
1309
|
+
* So the scan gets the shell as the dev server serves it, plus a plain
|
|
1310
|
+
* import of each worker entry, which is enough for it to walk into the
|
|
1311
|
+
* workers. Nothing here reaches the served code.
|
|
1312
|
+
*/
|
|
1313
|
+
function scanShell(options) {
|
|
1314
|
+
return {
|
|
1315
|
+
name: "gesso:scan-shell",
|
|
1316
|
+
async transform(code, id) {
|
|
1317
|
+
if (!SOURCE.test(id) || id.includes("/node_modules/")) return null;
|
|
1318
|
+
const call = findShellCall(code);
|
|
1319
|
+
if (call === null) return null;
|
|
1320
|
+
const entries = call.needsWorkers ? await resolveEntries({ resolve: async (source, importer) => {
|
|
1321
|
+
const resolved = await this.resolve(source, importer);
|
|
1322
|
+
return resolved === null || resolved.external === true ? null : resolved;
|
|
1323
|
+
} }, id, options).catch(() => null) : null;
|
|
1324
|
+
return {
|
|
1325
|
+
code: `${transformShell(code, {
|
|
1326
|
+
entries,
|
|
1327
|
+
overlay: options.overlay !== false,
|
|
1328
|
+
agent: options.agent !== false
|
|
1329
|
+
}) ?? code}\n${[entries?.renderWorker, entries?.appLogicWorker].filter((entry) => typeof entry === "string").map((entry) => `import ${JSON.stringify(entry)};`).join("\n")}\n`,
|
|
1330
|
+
map: null
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1293
1335
|
/** A name for the MCP server: the project's directory, which is what a person calls the app. */
|
|
1294
1336
|
function agentName(root) {
|
|
1295
1337
|
return (root.split("/").filter(Boolean).pop() ?? "gesso").replace(/[^A-Za-z0-9_-]/g, "-");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["MARKER"],"sources":["../src/agent.ts","../src/source.ts","../src/contracts.ts","../src/render.ts","../src/shell.ts","../src/index.ts"],"sourcesContent":["/**\n * The dev server's half of the agent bridge: MCP at `/__gesso/mcp`.\n *\n * An agent such as Claude Code connects to an MCP server by URL, and\n * the dev server already has one. But the channels it should offer live\n * in the page's workers, and a server cannot reach a worker. The page\n * can, and it holds a socket to the server already, Vite's HMR\n * connection. So this relays: each JSON-RPC message an agent posts goes\n * down that socket to the page, `connectDevAgent` in `gesso-framework/agent`\n * answers it against the render worker, and the answer comes back up\n * and out as the HTTP response.\n *\n * MCP is spoken in the page rather than here, so this file imports\n * nothing from the framework and parses nothing but enough JSON to\n * know a request from a notification.\n *\n * Several tabs may be open. The newest to announce itself answers,\n * which is the one a person most likely means, and a tab that closes\n * hands back to the one before it.\n */\n\n/** The path an agent is pointed at. */\nexport const AGENT_PATH = '/__gesso/mcp';\n\n/** The HMR events, as `connectDevAgent` names them. */\nexport const EVENTS = {\n ready: 'gesso:agent:ready',\n request: 'gesso:agent:request',\n response: 'gesso:agent:response'\n} as const;\n\n/** The part of a Vite HMR client this uses. */\nexport interface BridgeClient {\n send(event: string, payload?: unknown): void;\n}\n\n/** The part of `server.ws` this uses. */\nexport interface BridgeSocket {\n on(event: string, listener: (data: never, client: BridgeClient) => void): void;\n}\n\n/** A request as Connect hands it over, read without Node's types. */\nexport interface BridgeRequest {\n readonly method?: string;\n readonly url?: string;\n readonly headers: Readonly<Record<string, string | readonly string[] | undefined>>;\n on(event: 'data', listener: (chunk: { toString(): string }) => void): unknown;\n on(event: 'end' | 'error', listener: () => void): unknown;\n}\n\n/** A response as Connect hands it over. */\nexport interface BridgeResponse {\n statusCode: number;\n setHeader(name: string, value: string): unknown;\n end(body?: string): unknown;\n}\n\nexport interface AgentBridgeOptions {\n /**\n * How long a call may take before the agent is told it timed out, in\n * milliseconds (default 130 000): a command marked `@confirm` waits\n * for a person, and people are slow.\n */\n timeoutMs?: number;\n}\n\nexport interface AgentBridge {\n /** Connect middleware: answers `AGENT_PATH`, passes everything else on. */\n middleware(request: BridgeRequest, response: BridgeResponse, next: () => void): void;\n /** Whether a page has announced itself. */\n readonly connected: boolean;\n}\n\nexport function createAgentBridge(socket: BridgeSocket, options: AgentBridgeOptions = {}): AgentBridge {\n const timeoutMs = options.timeoutMs ?? 130_000;\n /** Pages that announced themselves, newest last. */\n const pages: BridgeClient[] = [];\n const pending = new Map<number, (response: unknown) => void>();\n let next = 1;\n\n socket.on(EVENTS.ready, (_data, client) => {\n const at = pages.indexOf(client);\n if (at >= 0) {\n pages.splice(at, 1);\n }\n pages.push(client);\n });\n socket.on('vite:ws:disconnect', (_data, client) => {\n const at = pages.indexOf(client);\n if (at >= 0) {\n pages.splice(at, 1);\n }\n });\n socket.on(EVENTS.response, (data: { id: number; response: unknown }) => {\n const resolve = pending.get(data.id);\n if (resolve !== undefined) {\n pending.delete(data.id);\n resolve(data.response);\n }\n });\n\n const relay = (message: unknown): Promise<unknown> => {\n const page = pages[pages.length - 1];\n const id = next++;\n return new Promise(resolve => {\n const timer = setTimeout(() => {\n pending.delete(id);\n resolve(rpcError(message, -32001, `The page did not answer within ${Math.round(timeoutMs / 1000)} seconds.`));\n }, timeoutMs);\n pending.set(id, response => {\n clearTimeout(timer);\n resolve(response);\n });\n page.send(EVENTS.request, { id, message });\n });\n };\n\n return {\n get connected() {\n return pages.length > 0;\n },\n middleware(request, response, next) {\n if (request.url?.split('?')[0] !== AGENT_PATH) {\n next();\n return;\n }\n // An agent is not a browser and sends no Origin. A page that does\n // could be any site the person has open, reaching for a server on\n // their own machine; the transport says to refuse it.\n if (request.headers.origin !== undefined) {\n send(response, 403, 'text/plain', 'The agent endpoint does not take requests from browser pages.');\n return;\n }\n if (request.method !== 'POST') {\n response.setHeader('allow', 'POST');\n send(response, 405, 'text/plain', 'POST JSON-RPC messages here.');\n return;\n }\n let body = '';\n request.on('data', chunk => {\n body += chunk.toString();\n });\n request.on('end', () => {\n let message: unknown;\n try {\n message = JSON.parse(body);\n } catch {\n send(response, 400, 'application/json', JSON.stringify(rpcError(null, -32700, 'The body is not JSON.')));\n return;\n }\n const notification = typeof message === 'object' && message !== null && !('id' in message);\n if (pages.length === 0) {\n if (notification) {\n send(response, 202);\n return;\n }\n send(\n response,\n 200,\n 'application/json',\n JSON.stringify(\n rpcError(\n message,\n -32000,\n 'No page is running the application. Open it in a browser from this dev server; the agent bridge ' +\n 'runs in the page, because that is where the channels are.'\n )\n )\n );\n return;\n }\n void relay(message).then(answer => {\n if (answer === null || answer === undefined) {\n send(response, 202);\n } else {\n send(response, 200, 'application/json', JSON.stringify(answer));\n }\n });\n });\n }\n };\n}\n\nfunction send(response: BridgeResponse, status: number, type?: string, body?: string): void {\n response.statusCode = status;\n if (type !== undefined) {\n response.setHeader('content-type', type);\n }\n response.end(body);\n}\n\nfunction rpcError(message: unknown, code: number, text: string): unknown {\n const id = (message as { id?: unknown } | null)?.id;\n return {\n jsonrpc: '2.0',\n id: typeof id === 'string' || typeof id === 'number' ? id : null,\n error: { code, message: text }\n };\n}\n\n/**\n * What the shell module gets in a dev server: the app, handed to the\n * page's half of the bridge once `gesso-framework/agent` has loaded.\n * Loaded on demand, so the page pays for it only in development.\n */\nexport const SHELL_BRIDGE = `function __gessoAgent(app) {\n if (typeof app.useWebMcp === 'function') {\n // A single-thread builder: on by default here, as \\`webmcp: true\\`\n // is for createApp, and a later useWebMcp(false) still decides.\n app.useWebMcp(true);\n }\n if (import.meta.hot) {\n void import('gesso-framework/agent').then(({ connectDevAgent }) => connectDevAgent(app, import.meta.hot));\n }\n return app;\n}\n`;\n","/**\n * Just enough of a JavaScript scanner to find a call and to say which\n * module a name was imported from.\n *\n * Written here rather than taken from npm for the reason the rest of\n * this repository's tooling gives (`packages/devtools/src/sourceMap.ts`,\n * `scripts/gen-layout-fixtures.ts`): the whole of what the plugin needs\n * is \"where does `createApp(` open and close\" and \"where did `SegueApp`\n * come from\", and a parser is a dependency, a TypeScript dialect\n * question and a version to keep in step, in exchange for two\n * questions a scanner answers.\n *\n * The trick that makes it safe is `blankLiterals`: every string,\n * template and comment is replaced by spaces of the same length, so the\n * positions found in the blanked copy are positions in the original,\n * and no brace inside a string can be mistaken for code. Everything\n * below searches the blank copy and slices the original.\n *\n * What it does not do is understand scope. A `createApp` that a module\n * defined for itself would be found the same way an imported one is,\n * which is why the plugin checks the imports first and only then looks\n * for the call.\n */\n\n/** Where a call expression starts, where its arguments are, where it ends. */\nexport interface CallSite {\n /** Index of the first character of the callee name. */\n readonly start: number;\n /** Index just after the opening parenthesis. */\n readonly argsStart: number;\n /** Index of the closing parenthesis. */\n readonly argsEnd: number;\n /** Index just after the closing parenthesis. */\n readonly end: number;\n}\n\nconst IDENTIFIER = /[A-Za-z0-9_$]/;\n\n/**\n * A copy of `code` in which every string, template literal, regular\n * expression body and comment is spaces, and everything else is\n * untouched.\n *\n * Same length as the input, and newlines are kept, so an index into\n * the result is an index into the original and a line number is still\n * a line number. String and template delimiters are kept as well, so a\n * specifier can be found by its quotes here and read from there.\n */\nexport function blankLiterals(code: string): string {\n const out = code.split('');\n let index = 0;\n // What may legally precede a regular expression: an operator, an\n // opening bracket, or the start of the file. After a name, a number\n // or a closing bracket, a slash is division.\n let regexAllowed = true;\n\n const blank = (from: number, to: number): void => {\n for (let i = from; i < to; i++) {\n if (out[i] !== '\\n') {\n out[i] = ' ';\n }\n }\n };\n\n while (index < code.length) {\n const char = code[index];\n if (char === '/' && code[index + 1] === '/') {\n const end = code.indexOf('\\n', index);\n blank(index, end === -1 ? code.length : end);\n index = end === -1 ? code.length : end;\n continue;\n }\n if (char === '/' && code[index + 1] === '*') {\n const end = code.indexOf('*/', index + 2);\n const stop = end === -1 ? code.length : end + 2;\n blank(index, stop);\n index = stop;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n const end = closingQuote(code, index, char);\n blank(index + 1, end);\n index = end + 1;\n regexAllowed = false;\n continue;\n }\n if (char === '`') {\n const end = closingQuote(code, index, '`');\n blank(index + 1, end);\n index = end + 1;\n regexAllowed = false;\n continue;\n }\n if (char === '/' && regexAllowed) {\n const end = closingRegex(code, index);\n if (end !== -1) {\n blank(index + 1, end);\n index = end + 1;\n regexAllowed = false;\n continue;\n }\n }\n if (!/\\s/.test(char)) {\n regexAllowed = !IDENTIFIER.test(char) && char !== ')' && char !== ']';\n }\n index++;\n }\n return out.join('');\n}\n\n/** The index of the quote that closes the one at `open`, or the end. */\nfunction closingQuote(code: string, open: number, quote: string): number {\n for (let i = open + 1; i < code.length; i++) {\n if (code[i] === '\\\\') {\n i++;\n continue;\n }\n if (code[i] === quote) {\n return i;\n }\n }\n return code.length;\n}\n\n/**\n * The index of the slash closing a regular expression, or -1 when the\n * slash was division after all.\n *\n * A newline inside means it was not a regular expression, which is the\n * cheap test that keeps `a / b` and `c / d` on one line from swallowing\n * everything between them.\n */\nfunction closingRegex(code: string, open: number): number {\n let inClass = false;\n for (let i = open + 1; i < code.length; i++) {\n const char = code[i];\n if (char === '\\\\') {\n i++;\n continue;\n }\n if (char === '\\n') {\n return -1;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']') {\n inClass = false;\n continue;\n }\n if (char === '/' && !inClass) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Every call of `name` in the module, in source order.\n *\n * A bare name has to stand alone: `renderRoot(` matches, `myRenderRoot(`\n * and `thing.renderRoot(` do not, because a method of that name on some\n * other object is not the framework's function. A name written with a\n * leading dot is the opposite and matches only the method call:\n * `.useService(` is how a builder chain reads and the only way it is\n * ever written.\n */\nexport function findCalls(code: string, name: string, blank = blankLiterals(code)): CallSite[] {\n const member = name.startsWith('.');\n const bare = member ? name.slice(1) : name;\n const sites: CallSite[] = [];\n let from = 0;\n for (;;) {\n const at = blank.indexOf(bare, from);\n if (at === -1) {\n return sites;\n }\n from = at + bare.length;\n const before = at === 0 ? '' : blank[at - 1];\n if (member ? before !== '.' : before !== '' && (IDENTIFIER.test(before) || before === '.')) {\n continue;\n }\n let cursor = from;\n while (cursor < blank.length && /\\s/.test(blank[cursor])) {\n cursor++;\n }\n if (blank[cursor] !== '(') {\n continue;\n }\n const argsEnd = matchingBracket(blank, cursor);\n if (argsEnd === -1) {\n continue;\n }\n sites.push({ start: at, argsStart: cursor + 1, argsEnd, end: argsEnd + 1 });\n from = argsEnd + 1;\n }\n}\n\n/** The first call of `name`, or null. */\nexport function findCall(code: string, name: string, blank = blankLiterals(code)): CallSite | null {\n return findCalls(code, name, blank)[0] ?? null;\n}\n\n/** The index of the bracket closing the one at `open`, or -1. */\nexport function matchingBracket(blank: string, open: number): number {\n const stack: string[] = [];\n for (let i = open; i < blank.length; i++) {\n const char = blank[i];\n if (char === '(' || char === '[' || char === '{') {\n stack.push(char);\n continue;\n }\n if (char === ')' || char === ']' || char === '}') {\n stack.pop();\n if (stack.length === 0) {\n return i;\n }\n }\n }\n return -1;\n}\n\n/**\n * The identifier a call's first argument is, or null when the argument\n * is anything more complicated than a name.\n *\n * `renderRoot(SegueApp)` is the shape every entry in this repository\n * writes and the only one that can be hot-replaced, because a\n * replacement has to be looked up by name in the module that changed.\n * `renderRoot(<App x={1} />)` is legal and gets no HMR wiring, which\n * the plugin says rather than guessing.\n */\nexport function firstArgumentName(code: string, call: CallSite, blank = blankLiterals(code)): string | null {\n const first = (splitTopLevel(blank.slice(call.argsStart, call.argsEnd))[0] ?? '').trim();\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(first) ? first : null;\n}\n\n/** Splits an argument list on its top-level commas. */\nfunction splitTopLevel(text: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === '(' || char === '[' || char === '{') {\n depth++;\n } else if (char === ')' || char === ']' || char === '}') {\n depth--;\n } else if (char === ',' && depth === 0) {\n parts.push(text.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(text.slice(start));\n return parts;\n}\n\n/**\n * Which module each imported name came from: local name to specifier,\n * exactly as the import wrote it.\n *\n * Default and namespace imports are recorded under their local names\n * too, so `import App from './App'` and `import * as app from './App'`\n * both answer. What the map does not carry is whether the binding is a\n * type, because `import type` is stripped before this runs in every\n * configuration that matters and a type never reaches a call.\n */\nexport function importSources(code: string, blank = blankLiterals(code)): Map<string, string> {\n const sources = new Map<string, string>();\n const statement = /\\bimport\\b([\\s\\S]*?)\\bfrom\\b\\s*(['\"])/g;\n for (;;) {\n const match = statement.exec(blank);\n if (match === null) {\n return sources;\n }\n const quote = match[2];\n const open = match.index + match[0].length;\n const close = code.indexOf(quote, open);\n if (close === -1) {\n continue;\n }\n const specifier = code.slice(open, close);\n for (const local of importedNames(match[1])) {\n sources.set(local, specifier);\n }\n statement.lastIndex = close + 1;\n }\n}\n\n/** The local names an import clause binds. */\nfunction importedNames(clause: string): string[] {\n const names: string[] = [];\n const braces = clause.indexOf('{');\n const head = (braces === -1 ? clause : clause.slice(0, braces)).replace(/\\btype\\b/g, '');\n for (const part of head.split(',')) {\n const named = /^\\s*(?:\\*\\s*as\\s*)?([A-Za-z_$][A-Za-z0-9_$]*)\\s*$/.exec(part);\n if (named !== null) {\n names.push(named[1]);\n }\n }\n if (braces !== -1) {\n const close = clause.lastIndexOf('}');\n const list = clause.slice(braces + 1, close === -1 ? clause.length : close);\n for (const part of list.split(',')) {\n const aliased = /^\\s*(?:type\\s+)?[A-Za-z_$][A-Za-z0-9_$]*\\s+as\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*$/.exec(part);\n const plain = /^\\s*(?:type\\s+)?([A-Za-z_$][A-Za-z0-9_$]*)\\s*$/.exec(part);\n const name = aliased?.[1] ?? plain?.[1];\n if (name !== undefined) {\n names.push(name);\n }\n }\n }\n return names;\n}\n","import type * as TsApi from 'typescript/unstable/sync';\n\nimport { blankLiterals, findCalls, importSources } from './source.ts';\n\n/**\n * Channel contracts, read by the type checker and written back as JSON\n * Schema.\n *\n * A contract module already says everything an agent driving the\n * application would need to know: the view's keys and their types, each\n * command's parameters and their types, and, where the author wrote\n * them, what each one is for. All of it is types and comments, and\n * both are gone by the time the module runs. This puts them back, as a\n * `describeChannel(token, schema)` call appended to the module, so the\n * token carries its own description wherever it is imported.\n *\n * The checker rather than the syntax, because a contract names its\n * types where it likes: `ProductRow` from another file, a status union\n * behind an alias, a view written as an object literal whose type is\n * inferred. Only the checker resolves all of those the way the compiler\n * that checked the application did. TypeScript 7's checker runs in a\n * separate process behind an API its package calls unstable, so all of\n * it is in this file, and the rest of the plugin sees one function.\n *\n * What the comments carry:\n *\n * - The JSDoc on the exported token is the channel's description, on\n * a view key is that key's, and on a command is the command's.\n * - `@param name text` describes a parameter.\n * - `@destructive`, `@idempotent`, `@confirm` and `@hidden` on a\n * command are its annotations; `CommandSchema` says what each means.\n *\n * And what it will not describe: a value that is not plain data, which\n * cannot cross a channel anyway. A function, a `Date`, a `Map`, a class\n * instance. Each is reported, by its path in the contract, and\n * described as `{}` so the rest of the schema still stands.\n */\n\n/** The parts of `typescript/unstable/sync` this file uses, values included. */\nexport type TypeScriptApi = typeof TsApi;\n\n/** A channel's description, in the shape `describeChannel` takes. */\nexport interface ChannelSchemaOut {\n description?: string;\n view: JsonSchema;\n commands: Record<string, CommandSchemaOut>;\n}\n\ninterface CommandSchemaOut {\n description?: string;\n parameters: string[];\n rest?: true;\n input: JsonSchema;\n destructive?: true;\n idempotent?: true;\n confirm?: true;\n hidden?: true;\n}\n\ntype JsonSchema = Record<string, unknown>;\n\n/** Every channel a module exports, and what could not be described. */\nexport interface ContractReading {\n /** Export name to schema, in declaration order. */\n readonly channels: ReadonlyMap<string, ChannelSchemaOut>;\n /** One sentence per value that could not be described, naming where it is. */\n readonly warnings: readonly string[];\n}\n\n/** The functions that declare a channel. */\nconst DECLARATIONS = ['channel', 'defineChannel'];\n\n/**\n * Whether a module declares a channel, without asking the checker.\n *\n * The checker is a process round trip per question, and every module\n * the application has passes through `transform`, so this is the gate:\n * a call to `channel` or `defineChannel` imported from\n * `gesso-framework`. A module that re-exports a token someone else\n * declared is not a contract, and the module that declared it is the\n * one described.\n */\nexport function declaresChannel(code: string): boolean {\n if (!code.includes('gesso-framework')) {\n return false;\n }\n const blank = blankLiterals(code);\n const imports = importSources(code, blank);\n // `channel<View, Commands>(...)` has type arguments between the name\n // and the parenthesis, which `findCalls` does not look past, and type\n // arguments are the form `channel` is usually written in.\n return DECLARATIONS.some(\n name =>\n imports.get(name) === 'gesso-framework' &&\n (findCalls(code, name, blank).length > 0 || new RegExp(`(?<![\\\\w$.])${name}\\\\s*<`).test(blank))\n );\n}\n\n/**\n * The code appended to a contract module.\n *\n * An import at the bottom is still hoisted, and appending rather than\n * rewriting leaves every line the author wrote where they wrote it, so\n * the module's source map needs nothing.\n */\nexport function describeCalls(channels: ReadonlyMap<string, ChannelSchemaOut>): string {\n const lines = [\"import { describeChannel as __gessoDescribeChannel } from 'gesso-framework';\"];\n for (const [name, schema] of channels) {\n lines.push(`__gessoDescribeChannel(${name}, ${JSON.stringify(schema)});`);\n }\n return `\\n${lines.join('\\n')}\\n`;\n}\n\n/**\n * A module that describes channels when it is imported, for a bundle\n * this plugin never sees.\n *\n * The plugin describes a contract by appending to it as Vite bundles\n * it. An Electrobun main process is bundled by Electrobun's own build,\n * which takes no plugins, so there the description is written ahead of\n * time instead: `gesso-channels` reads the contracts with the same\n * checker and writes this module, and the main process imports it once.\n * A token is imported from its contract, so the schema lands on the\n * same object the application serves.\n *\n * `outFile` and every `file` are absolute POSIX paths.\n */\nexport function describedModule(\n contracts: readonly { readonly file: string; readonly channels: ReadonlyMap<string, ChannelSchemaOut> }[],\n outFile: string\n): string {\n const lines = [\n '// Written by gesso-channels from the channel contracts it names below.',\n '// Run it again after changing a contract rather than editing this file.',\n \"import { describeChannel } from 'gesso-framework';\"\n ];\n const from = outFile.slice(0, outFile.lastIndexOf('/'));\n for (const contract of contracts) {\n if (contract.channels.size > 0) {\n const names = [...contract.channels.keys()].join(', ');\n lines.push(`import { ${names} } from '${importPath(from, contract.file)}';`);\n }\n }\n for (const contract of contracts) {\n for (const [name, schema] of contract.channels) {\n lines.push('', `describeChannel(${name}, ${JSON.stringify(schema, null, 2)});`);\n }\n }\n return `${lines.join('\\n')}\\n`;\n}\n\n/** `./Counter` from `/app/src/shared` to `/app/src/shared/Counter.ts`, without the extension. */\nfunction importPath(fromDir: string, file: string): string {\n const from = fromDir.split('/').filter(Boolean);\n const to = file\n .replace(/\\.[cm]?[jt]sx?$/, '')\n .split('/')\n .filter(Boolean);\n let shared = 0;\n while (shared < from.length && shared < to.length - 1 && from[shared] === to[shared]) {\n shared++;\n }\n const up = from.length - shared;\n const rest = to.slice(shared).join('/');\n return up === 0 ? `./${rest}` : `${'../'.repeat(up)}${rest}`;\n}\n\n/**\n * The checker, held open across reads.\n *\n * Spawning it and loading a project costs about a hundred\n * milliseconds; a question after that costs well under one. So one\n * reader lives as long as the dev server or the build, is told which\n * files changed between reads, and is closed at the end, because the\n * process it holds would otherwise keep the build from exiting.\n */\nexport class ContractReader {\n private api: TsApi.API | null = null;\n private readonly changed = new Set<string>();\n /** Each contract's tsconfig, found once. */\n private readonly configs = new Map<string, string>();\n\n /**\n * @param fs Callbacks the checker reads through before the disk, for\n * a spec that keeps its project in memory.\n */\n private readonly ts: TypeScriptApi;\n private readonly cwd: string;\n private readonly fs: TsApi.APIOptions['fs'];\n\n // Fields assigned by hand rather than parameter properties: the\n // plugin is loaded by Node's type stripping, which rejects those.\n constructor(ts: TypeScriptApi, cwd: string, fs?: TsApi.APIOptions['fs']) {\n this.ts = ts;\n this.cwd = cwd;\n this.fs = fs;\n }\n\n /** A file changed on disk since the last read. */\n invalidate(file: string): void {\n this.changed.add(file);\n }\n\n /** Every channel `file` exports, described. */\n read(file: string): ContractReading {\n const api = (this.api ??= new this.ts.API({ cwd: this.cwd, ...(this.fs === undefined ? {} : { fs: this.fs }) }));\n this.changed.add(file);\n let snapshot = api.updateSnapshot({ fileChanges: { changed: [...this.changed] } });\n this.changed.clear();\n let config = this.configs.get(file);\n if (config === undefined) {\n // A file opened through the API is an editor's buffer: the server\n // stops reading it from disk, and an edit the next save makes is\n // never seen. So the file is opened only long enough to learn\n // which project it belongs to, and the project is what stays open.\n config = api.updateSnapshot({ openFiles: [file] }).getDefaultProjectForFile(file)?.configFileName;\n snapshot = api.updateSnapshot({\n ...(config === undefined ? {} : { openProjects: [config] }),\n closeFiles: [file]\n });\n if (config !== undefined) {\n this.configs.set(file, config);\n }\n }\n const project = config === undefined ? undefined : snapshot.getProject(config);\n const source = project?.program.getSourceFile(file);\n if (project === undefined || source === undefined) {\n return { channels: new Map(), warnings: [`TypeScript has no project that includes ${file}.`] };\n }\n const checker = project.checker;\n const module = checker.getSymbolAtLocation(source);\n const describer = new Describer(this.ts, checker);\n const channels = new Map<string, ChannelSchemaOut>();\n for (const exported of module === undefined ? [] : checker.getExportsOfModule(module)) {\n const type = checker.getTypeOfSymbol(exported);\n if (type === undefined || type.getSymbol()?.name !== 'ChannelToken') {\n continue;\n }\n const [view, commands] = checker.getTypeArguments(type as TsApi.TypeReference);\n channels.set(exported.name, describer.channel(exported, view, commands));\n }\n return { channels, warnings: describer.warnings };\n }\n\n close(): void {\n this.api?.close();\n this.api = null;\n }\n}\n\n/**\n * Library types that are objects to the checker and not plain data to\n * a channel. They compare by reference, so `provide` rejects them on\n * their first value; describing their methods as properties would be\n * describing something that never arrives.\n */\nconst NOT_PLAIN = new Set([\n 'Date',\n 'Map',\n 'ReadonlyMap',\n 'Set',\n 'ReadonlySet',\n 'WeakMap',\n 'WeakSet',\n 'Promise',\n 'RegExp',\n 'Error',\n 'ArrayBuffer',\n 'SharedArrayBuffer',\n 'DataView',\n 'Blob',\n 'File',\n 'URL',\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array',\n 'BigInt64Array',\n 'BigUint64Array'\n]);\n\n/**\n * Bytes, which a command may carry and a view key may not.\n *\n * A command's argument is structured-cloned onto the owning thread, and\n * a typed array or an `ArrayBuffer` clones as itself: a file a person\n * dropped crosses as its bytes, with no encoding pass on the render\n * thread. A view key is diffed, and a differ that compares bytes by\n * reference reports a change on every emission, so there they stay\n * unplain. In a command's schema they are a base64 string, which is\n * what an agent can write, tagged with the type the command expects so\n * the agent surface can turn the string back into it.\n */\nexport const BINARY = new Set([\n 'ArrayBuffer',\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array',\n 'BigInt64Array',\n 'BigUint64Array'\n]);\n\n/** Turns checker types into JSON Schema for one module's channels. */\nclass Describer {\n readonly warnings: string[] = [];\n private readonly flags: TypeScriptApi['TypeFlags'];\n /** Describing a command's parameters, where bytes are allowed; see `BINARY`. */\n private inCommand = false;\n /** Types being described right now, to notice a type that contains itself. */\n private readonly inProgress = new Set<number>();\n /** Types found to contain themselves, which are described once in `$defs`. */\n private readonly recursive = new Set<number>();\n /** `$defs` for the schema being built. Reset per root, so each schema stands alone. */\n private defs = new Map<string, JsonSchema>();\n private readonly defNames = new Map<number, string>();\n\n private readonly ts: TypeScriptApi;\n private readonly checker: TsApi.Checker;\n\n constructor(ts: TypeScriptApi, checker: TsApi.Checker) {\n this.ts = ts;\n this.checker = checker;\n this.flags = ts.TypeFlags;\n }\n\n channel(token: TsApi.Symbol, view: TsApi.Type, commands: TsApi.Type | undefined): ChannelSchemaOut {\n const out: ChannelSchemaOut = { view: this.root(view, `${token.name}.view`), commands: {} };\n const description = this.checker.getDocumentationCommentOfSymbol(token);\n if (description !== '') {\n out.description = description;\n }\n if (commands !== undefined) {\n for (const command of this.checker.getPropertiesOfType(commands)) {\n const described = this.command(command, `${token.name}.commands.${command.name}`);\n if (described !== null) {\n out.commands[command.name] = described;\n }\n }\n }\n return out;\n }\n\n /** A schema that stands alone: its own `$defs`, if anything in it recurs. */\n private root(type: TsApi.Type, path: string): JsonSchema {\n this.defs = new Map();\n const schema = this.describe(type, path);\n if (this.defs.size > 0) {\n return { ...schema, $defs: Object.fromEntries(this.defs) };\n }\n return schema;\n }\n\n private command(symbol: TsApi.Symbol, path: string): CommandSchemaOut | null {\n const type = this.checker.getTypeOfSymbol(symbol);\n const signatures = type === undefined ? [] : this.checker.getSignaturesOfType(type, this.ts.SignatureKind.Call);\n if (signatures.length === 0) {\n this.warnings.push(`${path} is not a function, so it is not a command an agent can send.`);\n return null;\n }\n if (signatures.length > 1) {\n this.warnings.push(`${path} is overloaded; only its first signature is described.`);\n }\n const signature = signatures[0];\n const tags = this.checker.getJsDocTagsOfSymbol(symbol);\n const parameters = signature.getParameters();\n\n this.defs = new Map();\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n this.inCommand = true;\n parameters.forEach((parameter, index) => {\n const parameterType = this.checker.getTypeOfSymbol(parameter);\n const optional = parameterType !== undefined && this.includesUndefined(parameterType);\n const schema = parameterType === undefined ? {} : this.describe(parameterType, `${path}(${parameter.name})`);\n const description = this.parameterDescription(parameter, tags);\n properties[parameter.name] = description === '' ? schema : { ...schema, description };\n const rest = signature.hasRestParameter && index === parameters.length - 1;\n if (!optional && !rest) {\n required.push(parameter.name);\n }\n });\n this.inCommand = false;\n const input: JsonSchema = { type: 'object', properties, additionalProperties: false };\n if (required.length > 0) {\n input.required = required;\n }\n if (this.defs.size > 0) {\n input.$defs = Object.fromEntries(this.defs);\n }\n\n const out: CommandSchemaOut = { parameters: parameters.map(parameter => parameter.name), input };\n const description = this.checker.getDocumentationCommentOfSymbol(symbol);\n if (description !== '') {\n out.description = description;\n }\n if (signature.hasRestParameter) {\n out.rest = true;\n }\n for (const annotation of ['destructive', 'idempotent', 'confirm', 'hidden'] as const) {\n if (tags.some(tag => tag.name === annotation)) {\n out[annotation] = true;\n }\n }\n return out;\n }\n\n /**\n * A parameter's own comment, or failing that its `@param` line.\n *\n * The checker attaches `@param` text to the parameter of a method\n * signature. A command written as a property, `move: (from: number)\n * => void`, keeps its comment on the property, so the tag is read\n * from there instead.\n */\n private parameterDescription(parameter: TsApi.Symbol, tags: readonly TsApi.JSDocTagInfo[]): string {\n const own = this.checker.getDocumentationCommentOfSymbol(parameter);\n if (own !== '') {\n return own;\n }\n for (const tag of tags) {\n const match = tag.name === 'param' ? /^\\s*(\\S+)\\s*(?:-\\s*)?([\\s\\S]*)$/.exec(tag.text ?? '') : null;\n if (match !== null && match[1] === parameter.name) {\n return match[2].trim();\n }\n }\n return '';\n }\n\n private includesUndefined(type: TsApi.Type): boolean {\n const { Undefined, Void } = this.flags;\n if (type.isUnionType()) {\n return (type.getTypes() ?? []).some(member => (member.flags & (Undefined | Void)) !== 0);\n }\n return (type.flags & (Undefined | Void)) !== 0;\n }\n\n private describe(type: TsApi.Type, path: string): JsonSchema {\n const f = this.flags;\n const flags = type.flags;\n\n if (flags & (f.Any | f.Unknown)) {\n return {};\n }\n if (flags & f.Never) {\n this.warnings.push(\n `${path} is never, which describes no value. An empty array literal is never[] unless it says what it holds: write \\`[] as Row[]\\`.`\n );\n return { not: {} };\n }\n if (flags & (f.String | f.TemplateLiteral | f.StringMapping)) {\n return { type: 'string' };\n }\n if (flags & f.Number) {\n return { type: 'number' };\n }\n if (flags & f.Boolean) {\n return { type: 'boolean' };\n }\n if (flags & f.Null) {\n return { type: 'null' };\n }\n if (flags & (f.Undefined | f.Void)) {\n return {};\n }\n if (flags & f.BooleanLiteral) {\n return { const: (type as TsApi.IntrinsicType).intrinsicName === 'true' };\n }\n if (flags & (f.StringLiteral | f.NumberLiteral)) {\n return { const: (type as TsApi.LiteralType).value };\n }\n if (flags & (f.BigInt | f.BigIntLiteral | f.ESSymbol | f.UniqueESSymbol)) {\n return this.unplain(path, flags & f.BigIntLike ? 'a bigint' : 'a symbol');\n }\n if (type.isUnionType()) {\n return this.union(type, path);\n }\n if (flags & f.TypeParameter) {\n return {};\n }\n if (flags & (f.Object | f.Intersection)) {\n // An array is a container rather than a type that can contain\n // itself: `readonly Row[]` in a view and in `Row.children` is one\n // type, and treating it as named would put the array in `$defs`\n // instead of the row.\n if (this.checker.isArrayType(type)) {\n const [element] = this.checker.getTypeArguments(type as TsApi.TypeReference);\n return { type: 'array', items: element === undefined ? {} : this.describe(element, `${path}[]`) };\n }\n if (this.checker.isTupleType(type)) {\n return this.tuple(type as TsApi.TypeReference, path);\n }\n return this.named(type, path);\n }\n this.warnings.push(`${path} has a type this reader does not describe, so it is left open.`);\n return {};\n }\n\n /**\n * A union, with `undefined` taken out (optionality is said by\n * `required`), `true | false` folded back into `boolean`, and a union\n * of nothing but literals written as an `enum`.\n */\n private union(type: TsApi.UnionType, path: string): JsonSchema {\n const f = this.flags;\n let members = (type.getTypes() ?? []).filter(member => (member.flags & (f.Undefined | f.Void)) === 0);\n const booleans = members.filter(member => member.flags & f.BooleanLiteral);\n const schemas: JsonSchema[] = [];\n if (booleans.length === 2) {\n members = members.filter(member => !(member.flags & f.BooleanLiteral));\n schemas.push({ type: 'boolean' });\n }\n if (\n members.length > 0 &&\n schemas.length === 0 &&\n members.every(member => member.flags & (f.StringLiteral | f.NumberLiteral))\n ) {\n return { enum: members.map(member => (member as TsApi.LiteralType).value) };\n }\n // `null` last, so `string | null` reads as a string that may be absent.\n members.sort((a, b) => Number((a.flags & f.Null) !== 0) - Number((b.flags & f.Null) !== 0));\n schemas.push(...members.map(member => this.describe(member, path)));\n return schemas.length === 1 ? schemas[0] : { anyOf: schemas };\n }\n\n /**\n * An object type, described once however often it appears, and by\n * reference when it contains itself.\n */\n private named(type: TsApi.Type, path: string): JsonSchema {\n const id = type.id;\n if (this.inProgress.has(id)) {\n this.recursive.add(id);\n return { $ref: `#/$defs/${this.defName(type)}` };\n }\n this.inProgress.add(id);\n const schema = this.object(type, path);\n this.inProgress.delete(id);\n if (this.recursive.has(id)) {\n const name = this.defName(type);\n this.defs.set(name, schema);\n return { $ref: `#/$defs/${name}` };\n }\n return schema;\n }\n\n private defName(type: TsApi.Type): string {\n let name = this.defNames.get(type.id);\n if (name === undefined) {\n const base = (type.getAliasSymbol() ?? type.getSymbol())?.name ?? 'Type';\n const taken = new Set(this.defNames.values());\n name = taken.has(base) ? `${base}${type.id}` : base;\n this.defNames.set(type.id, name);\n }\n return name;\n }\n\n private object(type: TsApi.Type, path: string): JsonSchema {\n const checker = this.checker;\n const symbolName = type.getSymbol()?.name;\n if (symbolName !== undefined && this.inCommand && BINARY.has(symbolName)) {\n return { type: 'string', contentEncoding: 'base64', 'x-gesso-binary': symbolName };\n }\n if (symbolName !== undefined && NOT_PLAIN.has(symbolName)) {\n return this.unplain(path, `a ${symbolName}`);\n }\n if ((type as TsApi.ObjectType).objectFlags & this.ts.ObjectFlags.Class) {\n return this.unplain(path, `an instance of ${symbolName ?? 'a class'}`);\n }\n if (checker.getSignaturesOfType(type, this.ts.SignatureKind.Call).length > 0) {\n return this.unplain(path, 'a function');\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n for (const property of checker.getPropertiesOfType(type)) {\n const propertyType = checker.getTypeOfSymbol(property);\n const at = `${path}.${property.name}`;\n if (propertyType === undefined) {\n properties[property.name] = {};\n continue;\n }\n const schema = this.describe(propertyType, at);\n const description = checker.getDocumentationCommentOfSymbol(property);\n properties[property.name] = description === '' ? schema : { ...schema, description };\n const optional = (property.flags & this.ts.SymbolFlags.Optional) !== 0 || this.includesUndefined(propertyType);\n if (!optional) {\n required.push(property.name);\n }\n }\n const schema: JsonSchema = { type: 'object', properties };\n if (required.length > 0) {\n schema.required = required;\n }\n const index = checker.getIndexInfosOfType(type).find(info => info.keyType.flags & this.flags.String);\n if (index !== undefined) {\n schema.additionalProperties = this.describe(index.valueType, `${path}[key]`);\n }\n return schema;\n }\n\n private tuple(type: TsApi.TypeReference, path: string): JsonSchema {\n const elements = this.checker.getTypeArguments(type);\n const elementFlags = (type.getTarget() as TsApi.TupleType).elementFlags ?? [];\n const { Required, Rest } = this.ts.ElementFlags;\n const prefixItems: JsonSchema[] = [];\n let items: JsonSchema | false = false;\n let minItems = 0;\n elements.forEach((element, index) => {\n const schema = this.describe(element, `${path}[${index}]`);\n if (elementFlags[index] & Rest) {\n items = schema;\n } else {\n prefixItems.push(schema);\n if (elementFlags[index] & Required) {\n minItems = index + 1;\n }\n }\n });\n return { type: 'array', prefixItems, items, minItems };\n }\n\n private unplain(path: string, what: string): JsonSchema {\n this.warnings.push(`${path} is ${what}, which is not plain data and cannot cross a channel.`);\n return {};\n }\n}\n","import { blankLiterals, findCall, findCalls, firstArgumentName, importSources } from './source.ts';\n\n/** What the plugin found in a render worker entry, and could wire. */\nexport interface RenderWiring {\n /** The rewritten module, or null when there was nothing to wire. */\n readonly code: string | null;\n /**\n * Why nothing was wired, when nothing was. A sentence for the\n * developer, not an error: an entry the plugin cannot wire still\n * runs, it just full-reloads on a save.\n */\n readonly skipped: string | null;\n}\n\nconst MARKER = '/* gesso-vite-plugin: hot replacement */';\n\n/**\n * Writes the two lines an author would otherwise write by hand.\n *\n * The example below is the specification:\n *\n * const app = renderRoot(LiveApp).useService(LiveFeed);\n * import.meta.hot?.accept('./LiveExampleApp', module => {\n * app.reload(module.LiveApp, [module.LiveFeed]);\n * });\n *\n * Three things have to be found for that to be written mechanically:\n * the handle the chain returns, the module the root component came\n * from, and the modules the services came from. The handle is taken by\n * routing the call through a wrapper of the plugin's own, which keeps\n * the chain that follows it intact whether or not the author assigned\n * it. The modules come from the entry's own import statements, which is\n * exactly the question `importSources` answers.\n *\n * A service declared in a module of its own is accepted alongside the\n * root, because a registry keyed by class object cannot tell a\n * replacement from a stranger and `reload` is where that is repaired.\n * What is deliberately *not* wired is `useRoutes`: routes are read once\n * when the runtime is built, so a change to the route table is a full\n * reload and saying so is better than replacing a tree that still\n * resolves the old routes.\n */\nexport function transformRenderWorker(code: string): RenderWiring {\n if (code.includes(MARKER)) {\n return { code: null, skipped: null };\n }\n const blank = blankLiterals(code);\n const imports = importSources(code, blank);\n if (imports.get('renderRoot') !== 'gesso-framework') {\n return { code: null, skipped: null };\n }\n const call = findCall(code, 'renderRoot', blank);\n if (call === null) {\n return { code: null, skipped: null };\n }\n\n const root = firstArgumentName(code, call, blank);\n if (root === null) {\n return {\n code: null,\n skipped:\n 'renderRoot() is not called with the name of a component, so there is nothing to look up in a replaced module.'\n };\n }\n const rootSource = imports.get(root);\n if (rootSource === undefined) {\n return {\n code: null,\n skipped: `${root} is declared in the worker entry itself rather than imported, so replacing it would replace the entry and reload the page.`\n };\n }\n\n // Every service the chain registers, paired with the module it came\n // from. One declared beside the root is the common case and needs no\n // second dependency; one in a module of its own adds one.\n const services: { name: string; source: string }[] = [];\n for (const site of findCalls(code, '.useService', blank)) {\n const name = firstArgumentName(code, site, blank);\n const source = name === null ? undefined : imports.get(name);\n if (name !== null && source !== undefined) {\n services.push({ name, source });\n }\n }\n\n const sources = [rootSource, ...services.map(service => service.source)].filter(\n (source, index, all) => all.indexOf(source) === index\n );\n const namespace = (source: string): string => `__gessoModule${sources.indexOf(source)}`;\n const rewritten = `${code.slice(0, call.start)}__gessoRenderRoot${code.slice(call.start + 'renderRoot'.length)}`;\n\n const lines = [\n MARKER,\n ...sources.map((source, index) => `import * as __gessoImported${index} from ${JSON.stringify(source)};`),\n 'function __gessoRenderRoot(root) {',\n ' __gessoRenderRoot.app = renderRoot(root);',\n ' return __gessoRenderRoot.app;',\n '}',\n `const __gessoLatest = [${sources.map((_, index) => `__gessoImported${index}`).join(', ')}];`,\n 'if (import.meta.hot) {',\n ` import.meta.hot.accept([${sources.map(source => JSON.stringify(source)).join(', ')}], replaced => {`,\n ' replaced.forEach((module, index) => {',\n ' if (module !== undefined) {',\n ' __gessoLatest[index] = module;',\n ' }',\n ' });',\n ` __gessoRenderRoot.app.reload(${namespaceRead(namespace(rootSource), root)}, [${services\n .map(service => namespaceRead(namespace(service.source), service.name))\n .join(', ')}]);`,\n ' });',\n '}'\n ];\n return { code: `${rewritten}\\n${lines.join('\\n')}\\n`, skipped: null };\n}\n\n/** `__gessoLatest[n].Name`, written through the array so a replacement wins. */\nfunction namespaceRead(namespaceName: string, exported: string): string {\n const index = namespaceName.slice('__gessoModule'.length);\n return `__gessoLatest[${index}].${exported}`;\n}\n","import { SHELL_BRIDGE } from './agent.ts';\nimport { blankLiterals, findCall, importSources, type CallSite } from './source.ts';\n\n/** Where the plugin found the two worker entries, as the shell imports them. */\nexport interface WorkerEntries {\n /** A specifier relative to the shell module, e.g. `./RenderWorker.ts`. */\n readonly renderWorker: string;\n /** The same for the application worker, or null when there is none. */\n readonly appLogicWorker: string | null;\n}\n\n/** A `createApp` call the plugin could write for, and what it still needs. */\nexport interface ShellCall {\n readonly call: CallSite;\n /**\n * False when the author wrote `renderWorker` themselves, which is the\n * documented fallback and the case where the plugin has no worker to\n * find. It still wires the overlay in.\n */\n readonly needsWorkers: boolean;\n}\n\nexport interface ShellTransformOptions {\n /** The entries to construct, or null when the author named them. */\n readonly entries: WorkerEntries | null;\n /**\n * Whether to wire the error overlay in as well. True while the dev\n * server is running and never in a build, so a production bundle\n * carries no reference to `gesso-devtools`.\n */\n readonly overlay: boolean;\n /**\n * Hand the app to the development agent bridge once it is created\n * (default false). A dev server only.\n */\n readonly agent?: boolean;\n}\n\n/** Marks a module the plugin has already rewritten, so it is not done twice. */\nconst MARKER = '/* gesso-vite-plugin */';\n\n/**\n * The `createApp` call in a module, when the module has one that came\n * from the framework.\n *\n * Separate from the transform because finding the worker entries is an\n * asynchronous resolution against the bundler and worth doing only for\n * a module that turns out to be a shell, which is one module in an\n * application.\n */\nexport function findShellCall(code: string, blank = blankLiterals(code)): ShellCall | null {\n if (code.includes(MARKER)) {\n return null;\n }\n if (importSources(code, blank).get('createApp') !== 'gesso-framework') {\n return null;\n }\n const call = findCall(code, 'createApp', blank);\n if (call === null) {\n return null;\n }\n return { call, needsWorkers: !blank.slice(call.argsStart, call.argsEnd).includes('renderWorker') };\n}\n\n/**\n * Rewrites the shell module so that it names no worker.\n *\n * The one edit inside the author's own code is the call itself:\n * `createApp(...)` becomes `createApp(__gessoOptions(...))`, on the\n * same line, so every line number in the module is the one it was.\n * Everything else is appended below, as function declarations, which\n * hoist and are therefore usable from the line above them.\n *\n * The merge order is what keeps the promise that the\n * literal construction stays the documented fallback: the plugin's\n * factories go in first and the author's options spread over them, so\n * a `renderWorker` written by hand still wins.\n *\n * Returns null when there is nothing to do, which is the common case:\n * most modules do not call `createApp`.\n */\nexport function transformShell(code: string, options: ShellTransformOptions): string | null {\n const blank = blankLiterals(code);\n const shell = findShellCall(code, blank);\n if (shell === null) {\n return null;\n }\n if (options.entries === null && !options.overlay && options.agent !== true) {\n return null;\n }\n const { call } = shell;\n const args = code.slice(call.argsStart, call.argsEnd).trim();\n const created = `${code.slice(call.start, call.argsStart)}__gessoOptions(${args === '' ? '{}' : args})${code.slice(call.argsEnd, call.end)}`;\n // The whole call wrapped, so the bridge gets the app whatever the\n // shell then does with it: a variable, a chained mount, or nothing.\n const wrapped = options.agent === true ? `__gessoAgent(${created})` : created;\n const rewritten = `${code.slice(0, call.start)}${wrapped}${code.slice(call.end)}`;\n return `${rewritten}\\n${prelude(options)}${options.agent === true ? SHELL_BRIDGE : ''}`;\n}\n\n/**\n * The appended half: the worker construction, and in development the\n * error overlay.\n *\n * `new Worker(new URL(...), { type: 'module', ... })` is written out\n * literally because that is the only shape a bundler splits a worker\n * out of, which is the whole reason this text has to be emitted into\n * the author's module rather than living inside the framework. `name`\n * is passed as a member whose value may be undefined, which a\n * dictionary conversion treats as absent, so one construction serves\n * both the named and the unnamed case.\n */\nfunction prelude(options: ShellTransformOptions): string {\n const entries = options.entries;\n const lines = [\n MARKER,\n 'function __gessoOptions(options = {}) {',\n ' return {',\n ...(entries === null\n ? []\n : [\n ` renderWorker: () => new Worker(new URL(${JSON.stringify(entries.renderWorker)}, import.meta.url), { type: 'module', name: options.workerName }),`\n ]),\n ...(entries?.appLogicWorker == null\n ? []\n : [\n ` appLogicWorker: () => new Worker(new URL(${JSON.stringify(entries.appLogicWorker)}, import.meta.url), { type: 'module', name: options.workerName }),`\n ]),\n ...(options.overlay ? [' onError: __gessoReportError,'] : []),\n // In a dev server the channels are offered to an agent in the\n // browser too, where the browser has WebMCP; the app's own\n // `webmcp`, spread below, still decides.\n ...(options.agent === true ? [' webmcp: true,'] : []),\n ' ...options',\n ' };',\n '}'\n ];\n return options.overlay ? `${lines.join('\\n')}\\n${OVERLAY}` : `${lines.join('\\n')}\\n`;\n}\n\n/**\n * The development error overlay, loaded the first time something\n * throws and not before.\n *\n * Lazy because it costs nothing until it is needed: a page that never\n * throws never fetches `gesso-devtools`, and a page that does gets\n * the overlay within a network round trip of the error rather than\n * paying for the package on every start.\n *\n * The host is the canvas's parent, which is the element the\n * application was mounted into: the overlay covers the application it\n * is reporting on rather than the viewport, and a Gesso app is not\n * necessarily the whole page. `document.body` is the fallback for an\n * error thrown before there is a canvas at all.\n *\n * State is kept on the function object rather than in module-level\n * `let` bindings, because this block is appended below the code that\n * calls it and a `let` read from above it would be in its temporal\n * dead zone.\n */\nconst OVERLAY = `function __gessoReportError(message, stack, source) {\n const state = (__gessoReportError.state ??= { pending: [], overlay: null, loading: false });\n state.pending.push([message, stack, source]);\n if (state.overlay !== null) {\n __gessoFlushErrors();\n return;\n }\n if (state.loading) {\n return;\n }\n state.loading = true;\n void import('gesso-devtools').then(({ mountErrorOverlay }) => {\n const canvas = document.querySelector('canvas');\n state.overlay = mountErrorOverlay(canvas?.parentElement ?? document.body);\n __gessoFlushErrors();\n });\n}\nfunction __gessoFlushErrors() {\n const state = __gessoReportError.state;\n for (const [message, stack, source] of state.pending.splice(0)) {\n state.overlay.report(message, stack, source);\n }\n}\naddEventListener('error', event => {\n const error = event.error;\n __gessoReportError(error?.message ?? event.message, error?.stack, 'window');\n});\naddEventListener('unhandledrejection', event => {\n const reason = event.reason;\n __gessoReportError(reason?.message ?? String(reason), reason?.stack, 'window');\n});\n`;\n\n/**\n * The single-thread shell in a dev server: `createSyncApp(Root)`\n * wrapped so the agent bridge gets the builder, which answers an agent\n * port from the page itself. There are no workers to write and no\n * overlay to wire here, so this is all the plugin does to such a shell.\n */\nexport function transformSyncShell(code: string): string | null {\n if (code.includes(MARKER)) {\n return null;\n }\n const blank = blankLiterals(code);\n if (importSources(code, blank).get('createSyncApp') !== 'gesso-framework') {\n return null;\n }\n const call = findCall(code, 'createSyncApp', blank);\n if (call === null) {\n return null;\n }\n const wrapped = `__gessoAgent(${code.slice(call.start, call.end)})`;\n return `${code.slice(0, call.start)}${wrapped}${code.slice(call.end)}\\n${MARKER}\\n${SHELL_BRIDGE}`;\n}\n","import {\n defaultClientConditions,\n type EnvironmentModuleGraph,\n type EnvironmentModuleNode,\n type Plugin,\n type UserConfig\n} from 'vite';\n\nimport { AGENT_PATH, createAgentBridge, type BridgeRequest, type BridgeResponse, type BridgeSocket } from './agent.ts';\nimport { ContractReader, declaresChannel, describeCalls, type TypeScriptApi } from './contracts.ts';\nimport { transformRenderWorker } from './render.ts';\nimport { findShellCall, transformShell, transformSyncShell, type WorkerEntries } from './shell.ts';\n\nexport { ContractReader, describedModule, type ContractReading } from './contracts.ts';\nexport { transformRenderWorker, type RenderWiring } from './render.ts';\nexport {\n findShellCall,\n transformShell,\n transformSyncShell,\n type ShellCall,\n type ShellTransformOptions,\n type WorkerEntries\n} from './shell.ts';\nexport { blankLiterals, findCall, findCalls, firstArgumentName, importSources, type CallSite } from './source.ts';\n\n/**\n * `gesso-vite-plugin` — the plumbing between saving a file and seeing\n * the result.\n *\n * A Gesso application is three files either side of a thread barrier\n *, and until now the barrier cost the author four\n * incantations: `new Worker(new URL('./RenderWorker.ts',\n * import.meta.url), { type: 'module' })` twice, because only a literal\n * gets a chunk; `import.meta.hot.accept` with the root module named by\n * hand; and `mountErrorOverlay` wired to `onError`, without which a\n * worker exception reaches a console nobody has selected. None of them\n * is a decision. All of them are written the same way in every\n * application, and getting one wrong fails silently.\n *\n * The three-file shape stays. What this removes is the incantations,\n * and what it adds is the one diagnostic that cannot be read off the\n * screen: a save that reloads the page rather than replacing a module,\n * which traces to the root module having a\n * main-thread importer and which otherwise looks like HMR simply not\n * working.\n *\n * // vite.config.ts\n * import { gesso } from 'gesso-vite-plugin';\n * export default defineConfig({ plugins: [gesso()] });\n *\n * // main.ts\n * createApp({ history: { mode: 'path' } }).mount('#app');\n *\n * The literal construction stays supported and stays documented: the\n * plugin merges its factories *under* the options the author wrote, so\n * a hand-written `renderWorker` wins and an application that would\n * rather say it out loud can.\n */\nexport interface GessoPluginOptions {\n /**\n * The render worker entry, as a specifier the shell module could\n * import. By default the plugin tries the names below, in order, and\n * uses the first that resolves beside the shell.\n */\n readonly renderWorker?: string;\n /**\n * The application worker entry, or false for an application that has\n * none. By default the plugin looks for it and leaves it out when\n * there is nothing to find, which is the single-worker shape the\n * scaffold produces.\n */\n readonly appLogicWorker?: string | false;\n /**\n * Wire `gesso-devtools`'s error overlay into `onError` (default\n * true). Only ever in a dev server: a build carries no reference to\n * the package.\n */\n readonly overlay?: boolean;\n /** Emit the `import.meta.hot.accept` wiring (default true). */\n readonly hmr?: boolean;\n /**\n * Report a save that will reload the page instead of replacing a\n * module (default true).\n */\n readonly diagnostics?: boolean;\n /**\n * Resolve a dependency's `worker` export ahead of its `browser` one\n * (default true). See {@link workerConditions}.\n */\n readonly workerConditions?: boolean;\n /**\n * Describe every channel the application declares as JSON Schema,\n * read from the contract's types and JSDoc, and attach it to the\n * token with `describeChannel` (default true). It is what lets an AI\n * agent, or anything else that meets the application only at run\n * time, ask a channel what it holds and what its commands take.\n *\n * Needs TypeScript 7, whose checker does the reading. Without it the\n * plugin says so once and carries on undescribed.\n */\n readonly channelSchemas?: boolean;\n /**\n * Serve MCP at `/__gesso/mcp` while the dev server runs, so an AI\n * agent can read the open page's channels and send their commands\n * (default true). Development only: a build carries none of it.\n */\n readonly agent?: boolean;\n}\n\n/**\n * The export conditions a Gesso application resolves its dependencies\n * with: `worker` ahead of Vite's defaults.\n *\n * A Gesso application's code runs in workers, and Vite resolves every\n * dependency with the `browser` condition, which is the right call for\n * a page and the wrong one for a worker: a package's browser build may\n * reach for `document`. `decode-named-character-reference`, which every\n * markdown parser built on micromark imports, does exactly that, and a\n * render worker that imported one died on start with \"document is not\n * defined\". The same package publishes a `worker` build, as packages\n * with a DOM-only browser build tend to. A package's own export order\n * decides between the two, and those list `worker` first.\n *\n * The main thread resolves the same way. A worker build runs in a page\n * as well, and the shell imports little beyond Gesso itself.\n */\nexport const workerConditions: readonly string[] = ['worker', ...defaultClientConditions];\n\n/**\n * Where a render worker entry is looked for, beside the shell.\n *\n * Ordered so that a name that says what the file is beats the generic\n * one: an application with both `RenderWorker.ts` and `worker.ts` means\n * the first, and the scaffold, which has only `worker.ts`, still\n * resolves.\n */\nconst RENDER_WORKER_NAMES = [\n './RenderWorker.ts',\n './RenderWorker.tsx',\n './render.worker.ts',\n './app.render.worker.ts',\n './worker.ts'\n];\n\n/** Where an application worker entry is looked for, beside the shell. */\nconst APP_WORKER_NAMES = ['./AppWorker.ts', './AppWorker.tsx', './app.worker.ts', './app.logic.worker.ts'];\n\n/** Modules the plugin will read: the application's own source, not its dependencies. */\nconst SOURCE = /\\.(?:[cm]?[jt]sx?)(?:$|\\?)/;\n\nexport function gesso(options: GessoPluginOptions = {}): Plugin {\n let serving = false;\n /** The shell module, once one has been transformed. */\n let shellId: string | null = null;\n /** The render worker entry, once the shell has named it. */\n let renderWorkerId: string | null = null;\n /** Files already reported as reloading, so a save is not a stream of warnings. */\n const reported = new Set<string>();\n /** The checker, started by the first contract, or null once it is known to be unavailable. */\n let contracts: Promise<ContractReader | null> | undefined;\n let root = '';\n const readerFor = (warn: (message: string) => void): Promise<ContractReader | null> =>\n (contracts ??= import('typescript/unstable/sync').then(\n ts => new ContractReader(ts as TypeScriptApi, root),\n () => {\n warn(\n 'Channels are not described, because TypeScript 7 is not installed. Add `typescript` (7 or later) to ' +\n 'devDependencies, or pass `channelSchemas: false` to stop this message.'\n );\n return null;\n }\n ));\n const closeContracts = async () => {\n const reader = await contracts;\n reader?.close();\n contracts = undefined;\n };\n /** The module with its channels described, or null when it declares none. */\n const describeContract = async (code: string, id: string, warn: (message: string) => void) => {\n if (\n options.channelSchemas === false ||\n !SOURCE.test(id) ||\n id.includes('/node_modules/') ||\n !declaresChannel(code)\n ) {\n return null;\n }\n const reader = await readerFor(warn);\n if (reader === null) {\n return null;\n }\n const reading = reader.read(id.replace(/\\?.*$/, ''));\n reading.warnings.forEach(warn);\n return reading.channels.size > 0 ? code + describeCalls(reading.channels) : null;\n };\n /**\n * The same description, for a worker's bundle.\n *\n * A build bundles each worker with `worker.plugins` rather than with\n * the plugins of the page, and a contract is imported by workers far\n * more often than by the page, so without this a build would describe\n * almost nothing. A dev server runs every module through the main\n * plugins and does not need it. Each worker bundle closes the checker\n * when it is done, because nothing guarantees another bundle follows\n * to close it; the next contract starts it again.\n */\n const workerContracts: Plugin = {\n name: 'gesso:channel-schemas',\n enforce: 'pre',\n async transform(code, id) {\n const described = await describeContract(code, id, message => this.warn(message));\n return described === null ? null : { code: described, map: null };\n },\n async closeBundle() {\n await closeContracts();\n }\n };\n\n return {\n name: 'gesso',\n // Before Vite's own worker and asset plugins, which are what turn\n // the emitted `new Worker(new URL(...))` into a chunk, and before\n // the TypeScript transform, so the module still reads as it was\n // written.\n enforce: 'pre',\n\n config(config): UserConfig {\n return {\n ...(options.workerConditions === false ? {} : { resolve: { conditions: [...workerConditions] } }),\n // Module workers, which is what the plugin constructs, so a worker\n // can load a chunk on demand. Vite builds workers as IIFE unless\n // told otherwise, and an IIFE cannot split: a dynamic import in\n // the render worker was inlined, and a markdown editor's HTML\n // parser, loaded only on a paste, went into every page load.\n worker: {\n ...(config.worker?.format === undefined ? { format: 'es' as const } : {}),\n // Vite concatenates this with the application's own.\n ...(options.channelSchemas === false ? {} : { plugins: () => [workerContracts] })\n }\n };\n },\n\n configResolved(config) {\n serving = config.command === 'serve';\n root = config.root;\n },\n\n /**\n * The agent endpoint, and a line saying where it is once the server\n * is listening, because an endpoint nobody knows the address of is\n * one nobody connects to.\n */\n configureServer(server) {\n if (options.agent === false) {\n return;\n }\n const bridge = createAgentBridge(server.ws as unknown as BridgeSocket);\n server.middlewares.use((request, response, next) =>\n bridge.middleware(request as unknown as BridgeRequest, response as unknown as BridgeResponse, next)\n );\n server.httpServer?.once('listening', () => {\n const base = server.resolvedUrls?.local[0];\n if (base !== undefined) {\n const url = new URL(AGENT_PATH, base).href;\n server.config.logger.info(\n ` ➜ Agents: ${url}\\n claude mcp add --transport http ${agentName(server.config.root)} ${url}`\n );\n }\n });\n },\n\n watchChange(id) {\n void contracts?.then(reader => reader?.invalidate(id));\n },\n\n /**\n * The checker is a child process, and a build that left it running\n * would never exit. A dev server calls this when it closes, so the\n * one hook covers both.\n */\n async closeBundle() {\n await closeContracts();\n },\n\n async transform(source, id) {\n if (!SOURCE.test(id) || id.includes('/node_modules/')) {\n return null;\n }\n\n const described = await describeContract(source, id, message => this.warn(message));\n const code = described ?? source;\n\n if (serving && options.hmr !== false) {\n const wiring = transformRenderWorker(code);\n if (wiring.skipped !== null) {\n this.warn(`${wiring.skipped} Saving it will reload the page rather than replace the tree.`);\n }\n if (wiring.code !== null) {\n renderWorkerId = id;\n return { code: wiring.code, map: null };\n }\n }\n\n const call = findShellCall(code);\n if (call === null) {\n const sync = serving && options.agent !== false ? transformSyncShell(code) : null;\n if (sync !== null) {\n return { code: sync, map: null };\n }\n return described === null ? null : { code, map: null };\n }\n shellId = id;\n const entries = call.needsWorkers ? await resolveEntries(this, id, options) : null;\n const shell = transformShell(code, {\n entries,\n overlay: serving && options.overlay !== false,\n agent: serving && options.agent !== false\n });\n return shell === null ? (described === null ? null : { code, map: null }) : { code: shell, map: null };\n },\n\n /**\n * The failure that looks like a bug in the framework.\n *\n * A module reached from the main thread as well\n * as from the render worker cannot be hot-replaced, because Vite\n * propagates the invalidation to a main-thread importer that does\n * not accept and reloads the page. The screen blinks, the app\n * restarts, and nothing anywhere says why. Both ends of the module\n * graph are known here, so the answer is one walk of the importers.\n */\n hotUpdate({ modules, server, timestamp }) {\n if (renderWorkerId !== null) {\n refreshAcceptedImports(this.environment.moduleGraph, renderWorkerId, modules, timestamp);\n }\n if (options.diagnostics === false || shellId === null || renderWorkerId === null) {\n return;\n }\n for (const module of modules) {\n if (module.id === null || reported.has(module.id)) {\n continue;\n }\n const importers = importerClosure(module);\n if (!importers.has(shellId) || !importers.has(renderWorkerId)) {\n continue;\n }\n reported.add(module.id);\n server.config.logger.warn(\n `[gesso] ${short(module.id, server.config.root)} is imported by the main thread as well as by the render ` +\n 'worker, so saving it reloads the page instead of replacing the tree. Reach it only from the render ' +\n \"worker's own graph to get hot replacement back.\"\n );\n }\n }\n };\n}\n\nexport default gesso;\n\n/** A name for the MCP server: the project's directory, which is what a person calls the app. */\nfunction agentName(root: string): string {\n return (root.split('/').filter(Boolean).pop() ?? 'gesso').replace(/[^A-Za-z0-9_-]/g, '-');\n}\n\n/**\n * Keeps the render worker importing what it accepted at the version\n * the rest of the graph imports.\n *\n * Vite marks every importer of a saved module stale, so its next\n * request re-imports the module at the save's timestamp, except an\n * importer that accepts it: that one was handed the new module in the\n * update and its served code still names the old timestamp. The render\n * worker accepts its root's and its services' modules (the wiring\n * above), so a page reloaded after a save imported a service at one\n * timestamp from the worker and another from the screens: two modules,\n * two classes, and an `inject` that found neither. Only a restart of\n * the dev server got out of it.\n *\n * Marked stale softly, which redoes only the import timestamps.\n */\nfunction refreshAcceptedImports(\n graph: EnvironmentModuleGraph,\n workerId: string,\n modules: readonly EnvironmentModuleNode[],\n timestamp: number\n): void {\n const worker = graph.getModuleById(workerId);\n if (worker !== undefined && modules.some(module => worker.acceptedHmrDeps.has(module))) {\n graph.invalidateModule(worker, new Set(), timestamp, false, true);\n }\n}\n\n/** Every module that transitively imports this one, plus this one. */\nfunction importerClosure(module: EnvironmentModuleNode): Set<string> {\n const seen = new Set<string>();\n const queue = [module];\n while (queue.length > 0) {\n const next = queue.pop()!;\n if (next.id === null || seen.has(next.id)) {\n continue;\n }\n seen.add(next.id);\n queue.push(...next.importers);\n }\n return seen;\n}\n\n/** A path relative to the project, for a message a person reads. */\nfunction short(id: string, root: string): string {\n return id.startsWith(root) ? id.slice(root.length + 1) : id;\n}\n\n/** What the plugin resolves against, so a spec can hand it a fake. */\ninterface Resolver {\n resolve(source: string, importer: string): Promise<{ id: string } | null>;\n}\n\n/**\n * Finds the worker entries beside a shell module.\n *\n * The names are tried against the bundler's own resolver rather than\n * read off the disk: it already has the answer cached, it applies the\n * project's aliases and extensions, and it is the only thing that can\n * say whether the specifier the plugin is about to write would have\n * resolved. Nothing here touches the filesystem, which is also why the\n * package needs no node types.\n */\nasync function resolveEntries(context: Resolver, id: string, options: GessoPluginOptions): Promise<WorkerEntries> {\n const renderWorker = await firstResolved(\n context,\n id,\n options.renderWorker === undefined ? RENDER_WORKER_NAMES : [options.renderWorker]\n );\n if (renderWorker === null) {\n throw new Error(\n `gesso-vite-plugin found no render worker beside ${id}. It looked for ${RENDER_WORKER_NAMES.join(', ')}. ` +\n \"Name it with the plugin's `renderWorker` option, or write `renderWorker` in createApp() yourself.\"\n );\n }\n const appLogicWorker =\n options.appLogicWorker === false\n ? null\n : await firstResolved(\n context,\n id,\n options.appLogicWorker === undefined ? APP_WORKER_NAMES : [options.appLogicWorker]\n );\n return { renderWorker, appLogicWorker };\n}\n\n/** The first specifier that resolves beside `importer`, as written. */\nasync function firstResolved(context: Resolver, importer: string, names: readonly string[]): Promise<string | null> {\n for (const name of names) {\n if ((await context.resolve(name, importer)) !== null) {\n return name;\n }\n }\n return null;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["MARKER"],"sources":["../src/agent.ts","../src/source.ts","../src/contracts.ts","../src/render.ts","../src/shell.ts","../src/index.ts"],"sourcesContent":["/**\n * The dev server's half of the agent bridge: MCP at `/__gesso/mcp`.\n *\n * An agent such as Claude Code connects to an MCP server by URL, and\n * the dev server already has one. But the channels it should offer live\n * in the page's workers, and a server cannot reach a worker. The page\n * can, and it holds a socket to the server already, Vite's HMR\n * connection. So this relays: each JSON-RPC message an agent posts goes\n * down that socket to the page, `connectDevAgent` in `gesso-framework/agent`\n * answers it against the render worker, and the answer comes back up\n * and out as the HTTP response.\n *\n * MCP is spoken in the page rather than here, so this file imports\n * nothing from the framework and parses nothing but enough JSON to\n * know a request from a notification.\n *\n * Several tabs may be open. The newest to announce itself answers,\n * which is the one a person most likely means, and a tab that closes\n * hands back to the one before it.\n */\n\n/** The path an agent is pointed at. */\nexport const AGENT_PATH = '/__gesso/mcp';\n\n/** The HMR events, as `connectDevAgent` names them. */\nexport const EVENTS = {\n ready: 'gesso:agent:ready',\n request: 'gesso:agent:request',\n response: 'gesso:agent:response'\n} as const;\n\n/** The part of a Vite HMR client this uses. */\nexport interface BridgeClient {\n send(event: string, payload?: unknown): void;\n}\n\n/** The part of `server.ws` this uses. */\nexport interface BridgeSocket {\n on(event: string, listener: (data: never, client: BridgeClient) => void): void;\n}\n\n/** A request as Connect hands it over, read without Node's types. */\nexport interface BridgeRequest {\n readonly method?: string;\n readonly url?: string;\n readonly headers: Readonly<Record<string, string | readonly string[] | undefined>>;\n on(event: 'data', listener: (chunk: { toString(): string }) => void): unknown;\n on(event: 'end' | 'error', listener: () => void): unknown;\n}\n\n/** A response as Connect hands it over. */\nexport interface BridgeResponse {\n statusCode: number;\n setHeader(name: string, value: string): unknown;\n end(body?: string): unknown;\n}\n\nexport interface AgentBridgeOptions {\n /**\n * How long a call may take before the agent is told it timed out, in\n * milliseconds (default 130 000): a command marked `@confirm` waits\n * for a person, and people are slow.\n */\n timeoutMs?: number;\n}\n\nexport interface AgentBridge {\n /** Connect middleware: answers `AGENT_PATH`, passes everything else on. */\n middleware(request: BridgeRequest, response: BridgeResponse, next: () => void): void;\n /** Whether a page has announced itself. */\n readonly connected: boolean;\n}\n\nexport function createAgentBridge(socket: BridgeSocket, options: AgentBridgeOptions = {}): AgentBridge {\n const timeoutMs = options.timeoutMs ?? 130_000;\n /** Pages that announced themselves, newest last. */\n const pages: BridgeClient[] = [];\n const pending = new Map<number, (response: unknown) => void>();\n let next = 1;\n\n socket.on(EVENTS.ready, (_data, client) => {\n const at = pages.indexOf(client);\n if (at >= 0) {\n pages.splice(at, 1);\n }\n pages.push(client);\n });\n socket.on('vite:ws:disconnect', (_data, client) => {\n const at = pages.indexOf(client);\n if (at >= 0) {\n pages.splice(at, 1);\n }\n });\n socket.on(EVENTS.response, (data: { id: number; response: unknown }) => {\n const resolve = pending.get(data.id);\n if (resolve !== undefined) {\n pending.delete(data.id);\n resolve(data.response);\n }\n });\n\n const relay = (message: unknown): Promise<unknown> => {\n const page = pages[pages.length - 1];\n const id = next++;\n return new Promise(resolve => {\n const timer = setTimeout(() => {\n pending.delete(id);\n resolve(rpcError(message, -32001, `The page did not answer within ${Math.round(timeoutMs / 1000)} seconds.`));\n }, timeoutMs);\n pending.set(id, response => {\n clearTimeout(timer);\n resolve(response);\n });\n page.send(EVENTS.request, { id, message });\n });\n };\n\n return {\n get connected() {\n return pages.length > 0;\n },\n middleware(request, response, next) {\n if (request.url?.split('?')[0] !== AGENT_PATH) {\n next();\n return;\n }\n // An agent is not a browser and sends no Origin. A page that does\n // could be any site the person has open, reaching for a server on\n // their own machine; the transport says to refuse it.\n if (request.headers.origin !== undefined) {\n send(response, 403, 'text/plain', 'The agent endpoint does not take requests from browser pages.');\n return;\n }\n if (request.method !== 'POST') {\n response.setHeader('allow', 'POST');\n send(response, 405, 'text/plain', 'POST JSON-RPC messages here.');\n return;\n }\n let body = '';\n request.on('data', chunk => {\n body += chunk.toString();\n });\n request.on('end', () => {\n let message: unknown;\n try {\n message = JSON.parse(body);\n } catch {\n send(response, 400, 'application/json', JSON.stringify(rpcError(null, -32700, 'The body is not JSON.')));\n return;\n }\n const notification = typeof message === 'object' && message !== null && !('id' in message);\n if (pages.length === 0) {\n if (notification) {\n send(response, 202);\n return;\n }\n send(\n response,\n 200,\n 'application/json',\n JSON.stringify(\n rpcError(\n message,\n -32000,\n 'No page is running the application. Open it in a browser from this dev server; the agent bridge ' +\n 'runs in the page, because that is where the channels are.'\n )\n )\n );\n return;\n }\n void relay(message).then(answer => {\n if (answer === null || answer === undefined) {\n send(response, 202);\n } else {\n send(response, 200, 'application/json', JSON.stringify(answer));\n }\n });\n });\n }\n };\n}\n\nfunction send(response: BridgeResponse, status: number, type?: string, body?: string): void {\n response.statusCode = status;\n if (type !== undefined) {\n response.setHeader('content-type', type);\n }\n response.end(body);\n}\n\nfunction rpcError(message: unknown, code: number, text: string): unknown {\n const id = (message as { id?: unknown } | null)?.id;\n return {\n jsonrpc: '2.0',\n id: typeof id === 'string' || typeof id === 'number' ? id : null,\n error: { code, message: text }\n };\n}\n\n/**\n * What the shell module gets in a dev server: the app, handed to the\n * page's half of the bridge once `gesso-framework/agent` has loaded.\n * Loaded on demand, so the page pays for it only in development.\n */\nexport const SHELL_BRIDGE = `function __gessoAgent(app) {\n if (typeof app.useWebMcp === 'function') {\n // A single-thread builder: on by default here, as \\`webmcp: true\\`\n // is for createApp, and a later useWebMcp(false) still decides.\n app.useWebMcp(true);\n }\n if (import.meta.hot) {\n void import('gesso-framework/agent').then(({ connectDevAgent }) => connectDevAgent(app, import.meta.hot));\n }\n return app;\n}\n`;\n","/**\n * Just enough of a JavaScript scanner to find a call and to say which\n * module a name was imported from.\n *\n * Written here rather than taken from npm for the reason the rest of\n * this repository's tooling gives (`packages/devtools/src/sourceMap.ts`,\n * `scripts/gen-layout-fixtures.ts`): the whole of what the plugin needs\n * is \"where does `createApp(` open and close\" and \"where did `SegueApp`\n * come from\", and a parser is a dependency, a TypeScript dialect\n * question and a version to keep in step, in exchange for two\n * questions a scanner answers.\n *\n * The trick that makes it safe is `blankLiterals`: every string,\n * template and comment is replaced by spaces of the same length, so the\n * positions found in the blanked copy are positions in the original,\n * and no brace inside a string can be mistaken for code. Everything\n * below searches the blank copy and slices the original.\n *\n * What it does not do is understand scope. A `createApp` that a module\n * defined for itself would be found the same way an imported one is,\n * which is why the plugin checks the imports first and only then looks\n * for the call.\n */\n\n/** Where a call expression starts, where its arguments are, where it ends. */\nexport interface CallSite {\n /** Index of the first character of the callee name. */\n readonly start: number;\n /** Index just after the opening parenthesis. */\n readonly argsStart: number;\n /** Index of the closing parenthesis. */\n readonly argsEnd: number;\n /** Index just after the closing parenthesis. */\n readonly end: number;\n}\n\nconst IDENTIFIER = /[A-Za-z0-9_$]/;\n\n/**\n * A copy of `code` in which every string, template literal, regular\n * expression body and comment is spaces, and everything else is\n * untouched.\n *\n * Same length as the input, and newlines are kept, so an index into\n * the result is an index into the original and a line number is still\n * a line number. String and template delimiters are kept as well, so a\n * specifier can be found by its quotes here and read from there.\n */\nexport function blankLiterals(code: string): string {\n const out = code.split('');\n let index = 0;\n // What may legally precede a regular expression: an operator, an\n // opening bracket, or the start of the file. After a name, a number\n // or a closing bracket, a slash is division.\n let regexAllowed = true;\n\n const blank = (from: number, to: number): void => {\n for (let i = from; i < to; i++) {\n if (out[i] !== '\\n') {\n out[i] = ' ';\n }\n }\n };\n\n while (index < code.length) {\n const char = code[index];\n if (char === '/' && code[index + 1] === '/') {\n const end = code.indexOf('\\n', index);\n blank(index, end === -1 ? code.length : end);\n index = end === -1 ? code.length : end;\n continue;\n }\n if (char === '/' && code[index + 1] === '*') {\n const end = code.indexOf('*/', index + 2);\n const stop = end === -1 ? code.length : end + 2;\n blank(index, stop);\n index = stop;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n const end = closingQuote(code, index, char);\n blank(index + 1, end);\n index = end + 1;\n regexAllowed = false;\n continue;\n }\n if (char === '`') {\n const end = closingQuote(code, index, '`');\n blank(index + 1, end);\n index = end + 1;\n regexAllowed = false;\n continue;\n }\n if (char === '/' && regexAllowed) {\n const end = closingRegex(code, index);\n if (end !== -1) {\n blank(index + 1, end);\n index = end + 1;\n regexAllowed = false;\n continue;\n }\n }\n if (!/\\s/.test(char)) {\n regexAllowed = !IDENTIFIER.test(char) && char !== ')' && char !== ']';\n }\n index++;\n }\n return out.join('');\n}\n\n/** The index of the quote that closes the one at `open`, or the end. */\nfunction closingQuote(code: string, open: number, quote: string): number {\n for (let i = open + 1; i < code.length; i++) {\n if (code[i] === '\\\\') {\n i++;\n continue;\n }\n if (code[i] === quote) {\n return i;\n }\n }\n return code.length;\n}\n\n/**\n * The index of the slash closing a regular expression, or -1 when the\n * slash was division after all.\n *\n * A newline inside means it was not a regular expression, which is the\n * cheap test that keeps `a / b` and `c / d` on one line from swallowing\n * everything between them.\n */\nfunction closingRegex(code: string, open: number): number {\n let inClass = false;\n for (let i = open + 1; i < code.length; i++) {\n const char = code[i];\n if (char === '\\\\') {\n i++;\n continue;\n }\n if (char === '\\n') {\n return -1;\n }\n if (char === '[') {\n inClass = true;\n continue;\n }\n if (char === ']') {\n inClass = false;\n continue;\n }\n if (char === '/' && !inClass) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Every call of `name` in the module, in source order.\n *\n * A bare name has to stand alone: `renderRoot(` matches, `myRenderRoot(`\n * and `thing.renderRoot(` do not, because a method of that name on some\n * other object is not the framework's function. A name written with a\n * leading dot is the opposite and matches only the method call:\n * `.useService(` is how a builder chain reads and the only way it is\n * ever written.\n */\nexport function findCalls(code: string, name: string, blank = blankLiterals(code)): CallSite[] {\n const member = name.startsWith('.');\n const bare = member ? name.slice(1) : name;\n const sites: CallSite[] = [];\n let from = 0;\n for (;;) {\n const at = blank.indexOf(bare, from);\n if (at === -1) {\n return sites;\n }\n from = at + bare.length;\n const before = at === 0 ? '' : blank[at - 1];\n if (member ? before !== '.' : before !== '' && (IDENTIFIER.test(before) || before === '.')) {\n continue;\n }\n let cursor = from;\n while (cursor < blank.length && /\\s/.test(blank[cursor])) {\n cursor++;\n }\n if (blank[cursor] !== '(') {\n continue;\n }\n const argsEnd = matchingBracket(blank, cursor);\n if (argsEnd === -1) {\n continue;\n }\n sites.push({ start: at, argsStart: cursor + 1, argsEnd, end: argsEnd + 1 });\n from = argsEnd + 1;\n }\n}\n\n/** The first call of `name`, or null. */\nexport function findCall(code: string, name: string, blank = blankLiterals(code)): CallSite | null {\n return findCalls(code, name, blank)[0] ?? null;\n}\n\n/** The index of the bracket closing the one at `open`, or -1. */\nexport function matchingBracket(blank: string, open: number): number {\n const stack: string[] = [];\n for (let i = open; i < blank.length; i++) {\n const char = blank[i];\n if (char === '(' || char === '[' || char === '{') {\n stack.push(char);\n continue;\n }\n if (char === ')' || char === ']' || char === '}') {\n stack.pop();\n if (stack.length === 0) {\n return i;\n }\n }\n }\n return -1;\n}\n\n/**\n * The identifier a call's first argument is, or null when the argument\n * is anything more complicated than a name.\n *\n * `renderRoot(SegueApp)` is the shape every entry in this repository\n * writes and the only one that can be hot-replaced, because a\n * replacement has to be looked up by name in the module that changed.\n * `renderRoot(<App x={1} />)` is legal and gets no HMR wiring, which\n * the plugin says rather than guessing.\n */\nexport function firstArgumentName(code: string, call: CallSite, blank = blankLiterals(code)): string | null {\n const first = (splitTopLevel(blank.slice(call.argsStart, call.argsEnd))[0] ?? '').trim();\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(first) ? first : null;\n}\n\n/** Splits an argument list on its top-level commas. */\nfunction splitTopLevel(text: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < text.length; i++) {\n const char = text[i];\n if (char === '(' || char === '[' || char === '{') {\n depth++;\n } else if (char === ')' || char === ']' || char === '}') {\n depth--;\n } else if (char === ',' && depth === 0) {\n parts.push(text.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(text.slice(start));\n return parts;\n}\n\n/**\n * Which module each imported name came from: local name to specifier,\n * exactly as the import wrote it.\n *\n * Default and namespace imports are recorded under their local names\n * too, so `import App from './App'` and `import * as app from './App'`\n * both answer. What the map does not carry is whether the binding is a\n * type, because `import type` is stripped before this runs in every\n * configuration that matters and a type never reaches a call.\n */\nexport function importSources(code: string, blank = blankLiterals(code)): Map<string, string> {\n const sources = new Map<string, string>();\n const statement = /\\bimport\\b([\\s\\S]*?)\\bfrom\\b\\s*(['\"])/g;\n for (;;) {\n const match = statement.exec(blank);\n if (match === null) {\n return sources;\n }\n const quote = match[2];\n const open = match.index + match[0].length;\n const close = code.indexOf(quote, open);\n if (close === -1) {\n continue;\n }\n const specifier = code.slice(open, close);\n for (const local of importedNames(match[1])) {\n sources.set(local, specifier);\n }\n statement.lastIndex = close + 1;\n }\n}\n\n/** The local names an import clause binds. */\nfunction importedNames(clause: string): string[] {\n const names: string[] = [];\n const braces = clause.indexOf('{');\n const head = (braces === -1 ? clause : clause.slice(0, braces)).replace(/\\btype\\b/g, '');\n for (const part of head.split(',')) {\n const named = /^\\s*(?:\\*\\s*as\\s*)?([A-Za-z_$][A-Za-z0-9_$]*)\\s*$/.exec(part);\n if (named !== null) {\n names.push(named[1]);\n }\n }\n if (braces !== -1) {\n const close = clause.lastIndexOf('}');\n const list = clause.slice(braces + 1, close === -1 ? clause.length : close);\n for (const part of list.split(',')) {\n const aliased = /^\\s*(?:type\\s+)?[A-Za-z_$][A-Za-z0-9_$]*\\s+as\\s+([A-Za-z_$][A-Za-z0-9_$]*)\\s*$/.exec(part);\n const plain = /^\\s*(?:type\\s+)?([A-Za-z_$][A-Za-z0-9_$]*)\\s*$/.exec(part);\n const name = aliased?.[1] ?? plain?.[1];\n if (name !== undefined) {\n names.push(name);\n }\n }\n }\n return names;\n}\n","import type * as TsApi from 'typescript/unstable/sync';\n\nimport { blankLiterals, findCalls, importSources } from './source.ts';\n\n/**\n * Channel contracts, read by the type checker and written back as JSON\n * Schema.\n *\n * A contract module already says everything an agent driving the\n * application would need to know: the view's keys and their types, each\n * command's parameters and their types, and, where the author wrote\n * them, what each one is for. All of it is types and comments, and\n * both are gone by the time the module runs. This puts them back, as a\n * `describeChannel(token, schema)` call appended to the module, so the\n * token carries its own description wherever it is imported.\n *\n * The checker rather than the syntax, because a contract names its\n * types where it likes: `ProductRow` from another file, a status union\n * behind an alias, a view written as an object literal whose type is\n * inferred. Only the checker resolves all of those the way the compiler\n * that checked the application did. TypeScript 7's checker runs in a\n * separate process behind an API its package calls unstable, so all of\n * it is in this file, and the rest of the plugin sees one function.\n *\n * What the comments carry:\n *\n * - The JSDoc on the exported token is the channel's description, on\n * a view key is that key's, and on a command is the command's.\n * - `@param name text` describes a parameter.\n * - `@destructive`, `@idempotent`, `@confirm` and `@hidden` on a\n * command are its annotations; `CommandSchema` says what each means.\n *\n * And what it will not describe: a value that is not plain data, which\n * cannot cross a channel anyway. A function, a `Date`, a `Map`, a class\n * instance. Each is reported, by its path in the contract, and\n * described as `{}` so the rest of the schema still stands.\n */\n\n/** The parts of `typescript/unstable/sync` this file uses, values included. */\nexport type TypeScriptApi = typeof TsApi;\n\n/** A channel's description, in the shape `describeChannel` takes. */\nexport interface ChannelSchemaOut {\n description?: string;\n view: JsonSchema;\n commands: Record<string, CommandSchemaOut>;\n}\n\ninterface CommandSchemaOut {\n description?: string;\n parameters: string[];\n rest?: true;\n input: JsonSchema;\n destructive?: true;\n idempotent?: true;\n confirm?: true;\n hidden?: true;\n}\n\ntype JsonSchema = Record<string, unknown>;\n\n/** Every channel a module exports, and what could not be described. */\nexport interface ContractReading {\n /** Export name to schema, in declaration order. */\n readonly channels: ReadonlyMap<string, ChannelSchemaOut>;\n /** One sentence per value that could not be described, naming where it is. */\n readonly warnings: readonly string[];\n}\n\n/** The functions that declare a channel. */\nconst DECLARATIONS = ['channel', 'defineChannel'];\n\n/**\n * Whether a module declares a channel, without asking the checker.\n *\n * The checker is a process round trip per question, and every module\n * the application has passes through `transform`, so this is the gate:\n * a call to `channel` or `defineChannel` imported from\n * `gesso-framework`. A module that re-exports a token someone else\n * declared is not a contract, and the module that declared it is the\n * one described.\n */\nexport function declaresChannel(code: string): boolean {\n if (!code.includes('gesso-framework')) {\n return false;\n }\n const blank = blankLiterals(code);\n const imports = importSources(code, blank);\n // `channel<View, Commands>(...)` has type arguments between the name\n // and the parenthesis, which `findCalls` does not look past, and type\n // arguments are the form `channel` is usually written in.\n return DECLARATIONS.some(\n name =>\n imports.get(name) === 'gesso-framework' &&\n (findCalls(code, name, blank).length > 0 || new RegExp(`(?<![\\\\w$.])${name}\\\\s*<`).test(blank))\n );\n}\n\n/**\n * The code appended to a contract module.\n *\n * An import at the bottom is still hoisted, and appending rather than\n * rewriting leaves every line the author wrote where they wrote it, so\n * the module's source map needs nothing.\n */\nexport function describeCalls(channels: ReadonlyMap<string, ChannelSchemaOut>): string {\n const lines = [\"import { describeChannel as __gessoDescribeChannel } from 'gesso-framework';\"];\n for (const [name, schema] of channels) {\n lines.push(`__gessoDescribeChannel(${name}, ${JSON.stringify(schema)});`);\n }\n return `\\n${lines.join('\\n')}\\n`;\n}\n\n/**\n * A module that describes channels when it is imported, for a bundle\n * this plugin never sees.\n *\n * The plugin describes a contract by appending to it as Vite bundles\n * it. An Electrobun main process is bundled by Electrobun's own build,\n * which takes no plugins, so there the description is written ahead of\n * time instead: `gesso-channels` reads the contracts with the same\n * checker and writes this module, and the main process imports it once.\n * A token is imported from its contract, so the schema lands on the\n * same object the application serves.\n *\n * `outFile` and every `file` are absolute POSIX paths.\n */\nexport function describedModule(\n contracts: readonly { readonly file: string; readonly channels: ReadonlyMap<string, ChannelSchemaOut> }[],\n outFile: string\n): string {\n const lines = [\n '// Written by gesso-channels from the channel contracts it names below.',\n '// Run it again after changing a contract rather than editing this file.',\n \"import { describeChannel } from 'gesso-framework';\"\n ];\n const from = outFile.slice(0, outFile.lastIndexOf('/'));\n for (const contract of contracts) {\n if (contract.channels.size > 0) {\n const names = [...contract.channels.keys()].join(', ');\n lines.push(`import { ${names} } from '${importPath(from, contract.file)}';`);\n }\n }\n for (const contract of contracts) {\n for (const [name, schema] of contract.channels) {\n lines.push('', `describeChannel(${name}, ${JSON.stringify(schema, null, 2)});`);\n }\n }\n return `${lines.join('\\n')}\\n`;\n}\n\n/** `./Counter` from `/app/src/shared` to `/app/src/shared/Counter.ts`, without the extension. */\nfunction importPath(fromDir: string, file: string): string {\n const from = fromDir.split('/').filter(Boolean);\n const to = file\n .replace(/\\.[cm]?[jt]sx?$/, '')\n .split('/')\n .filter(Boolean);\n let shared = 0;\n while (shared < from.length && shared < to.length - 1 && from[shared] === to[shared]) {\n shared++;\n }\n const up = from.length - shared;\n const rest = to.slice(shared).join('/');\n return up === 0 ? `./${rest}` : `${'../'.repeat(up)}${rest}`;\n}\n\n/**\n * The checker, held open across reads.\n *\n * Spawning it and loading a project costs about a hundred\n * milliseconds; a question after that costs well under one. So one\n * reader lives as long as the dev server or the build, is told which\n * files changed between reads, and is closed at the end, because the\n * process it holds would otherwise keep the build from exiting.\n */\nexport class ContractReader {\n private api: TsApi.API | null = null;\n private readonly changed = new Set<string>();\n /** Each contract's tsconfig, found once. */\n private readonly configs = new Map<string, string>();\n\n /**\n * @param fs Callbacks the checker reads through before the disk, for\n * a spec that keeps its project in memory.\n */\n private readonly ts: TypeScriptApi;\n private readonly cwd: string;\n private readonly fs: TsApi.APIOptions['fs'];\n\n // Fields assigned by hand rather than parameter properties: the\n // plugin is loaded by Node's type stripping, which rejects those.\n constructor(ts: TypeScriptApi, cwd: string, fs?: TsApi.APIOptions['fs']) {\n this.ts = ts;\n this.cwd = cwd;\n this.fs = fs;\n }\n\n /** A file changed on disk since the last read. */\n invalidate(file: string): void {\n this.changed.add(file);\n }\n\n /** Every channel `file` exports, described. */\n read(file: string): ContractReading {\n const api = (this.api ??= new this.ts.API({ cwd: this.cwd, ...(this.fs === undefined ? {} : { fs: this.fs }) }));\n this.changed.add(file);\n let snapshot = api.updateSnapshot({ fileChanges: { changed: [...this.changed] } });\n this.changed.clear();\n let config = this.configs.get(file);\n if (config === undefined) {\n // A file opened through the API is an editor's buffer: the server\n // stops reading it from disk, and an edit the next save makes is\n // never seen. So the file is opened only long enough to learn\n // which project it belongs to, and the project is what stays open.\n config = api.updateSnapshot({ openFiles: [file] }).getDefaultProjectForFile(file)?.configFileName;\n snapshot = api.updateSnapshot({\n ...(config === undefined ? {} : { openProjects: [config] }),\n closeFiles: [file]\n });\n if (config !== undefined) {\n this.configs.set(file, config);\n }\n }\n const project = config === undefined ? undefined : snapshot.getProject(config);\n const source = project?.program.getSourceFile(file);\n if (project === undefined || source === undefined) {\n return { channels: new Map(), warnings: [`TypeScript has no project that includes ${file}.`] };\n }\n const checker = project.checker;\n const module = checker.getSymbolAtLocation(source);\n const describer = new Describer(this.ts, checker);\n const channels = new Map<string, ChannelSchemaOut>();\n for (const exported of module === undefined ? [] : checker.getExportsOfModule(module)) {\n const type = checker.getTypeOfSymbol(exported);\n if (type === undefined || type.getSymbol()?.name !== 'ChannelToken') {\n continue;\n }\n const [view, commands] = checker.getTypeArguments(type as TsApi.TypeReference);\n channels.set(exported.name, describer.channel(exported, view, commands));\n }\n return { channels, warnings: describer.warnings };\n }\n\n close(): void {\n this.api?.close();\n this.api = null;\n }\n}\n\n/**\n * Library types that are objects to the checker and not plain data to\n * a channel. They compare by reference, so `provide` rejects them on\n * their first value; describing their methods as properties would be\n * describing something that never arrives.\n */\nconst NOT_PLAIN = new Set([\n 'Date',\n 'Map',\n 'ReadonlyMap',\n 'Set',\n 'ReadonlySet',\n 'WeakMap',\n 'WeakSet',\n 'Promise',\n 'RegExp',\n 'Error',\n 'ArrayBuffer',\n 'SharedArrayBuffer',\n 'DataView',\n 'Blob',\n 'File',\n 'URL',\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array',\n 'BigInt64Array',\n 'BigUint64Array'\n]);\n\n/**\n * Bytes, which a command may carry and a view key may not.\n *\n * A command's argument is structured-cloned onto the owning thread, and\n * a typed array or an `ArrayBuffer` clones as itself: a file a person\n * dropped crosses as its bytes, with no encoding pass on the render\n * thread. A view key is diffed, and a differ that compares bytes by\n * reference reports a change on every emission, so there they stay\n * unplain. In a command's schema they are a base64 string, which is\n * what an agent can write, tagged with the type the command expects so\n * the agent surface can turn the string back into it.\n */\nexport const BINARY = new Set([\n 'ArrayBuffer',\n 'Int8Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'Int16Array',\n 'Uint16Array',\n 'Int32Array',\n 'Uint32Array',\n 'Float32Array',\n 'Float64Array',\n 'BigInt64Array',\n 'BigUint64Array'\n]);\n\n/** Turns checker types into JSON Schema for one module's channels. */\nclass Describer {\n readonly warnings: string[] = [];\n private readonly flags: TypeScriptApi['TypeFlags'];\n /** Describing a command's parameters, where bytes are allowed; see `BINARY`. */\n private inCommand = false;\n /** Types being described right now, to notice a type that contains itself. */\n private readonly inProgress = new Set<number>();\n /** Types found to contain themselves, which are described once in `$defs`. */\n private readonly recursive = new Set<number>();\n /** `$defs` for the schema being built. Reset per root, so each schema stands alone. */\n private defs = new Map<string, JsonSchema>();\n private readonly defNames = new Map<number, string>();\n\n private readonly ts: TypeScriptApi;\n private readonly checker: TsApi.Checker;\n\n constructor(ts: TypeScriptApi, checker: TsApi.Checker) {\n this.ts = ts;\n this.checker = checker;\n this.flags = ts.TypeFlags;\n }\n\n channel(token: TsApi.Symbol, view: TsApi.Type, commands: TsApi.Type | undefined): ChannelSchemaOut {\n const out: ChannelSchemaOut = { view: this.root(view, `${token.name}.view`), commands: {} };\n const description = this.checker.getDocumentationCommentOfSymbol(token);\n if (description !== '') {\n out.description = description;\n }\n if (commands !== undefined) {\n for (const command of this.checker.getPropertiesOfType(commands)) {\n const described = this.command(command, `${token.name}.commands.${command.name}`);\n if (described !== null) {\n out.commands[command.name] = described;\n }\n }\n }\n return out;\n }\n\n /** A schema that stands alone: its own `$defs`, if anything in it recurs. */\n private root(type: TsApi.Type, path: string): JsonSchema {\n this.defs = new Map();\n const schema = this.describe(type, path);\n if (this.defs.size > 0) {\n return { ...schema, $defs: Object.fromEntries(this.defs) };\n }\n return schema;\n }\n\n private command(symbol: TsApi.Symbol, path: string): CommandSchemaOut | null {\n const type = this.checker.getTypeOfSymbol(symbol);\n const signatures = type === undefined ? [] : this.checker.getSignaturesOfType(type, this.ts.SignatureKind.Call);\n if (signatures.length === 0) {\n this.warnings.push(`${path} is not a function, so it is not a command an agent can send.`);\n return null;\n }\n if (signatures.length > 1) {\n this.warnings.push(`${path} is overloaded; only its first signature is described.`);\n }\n const signature = signatures[0];\n const tags = this.checker.getJsDocTagsOfSymbol(symbol);\n const parameters = signature.getParameters();\n\n this.defs = new Map();\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n this.inCommand = true;\n parameters.forEach((parameter, index) => {\n const parameterType = this.checker.getTypeOfSymbol(parameter);\n const optional = parameterType !== undefined && this.includesUndefined(parameterType);\n const schema = parameterType === undefined ? {} : this.describe(parameterType, `${path}(${parameter.name})`);\n const description = this.parameterDescription(parameter, tags);\n properties[parameter.name] = description === '' ? schema : { ...schema, description };\n const rest = signature.hasRestParameter && index === parameters.length - 1;\n if (!optional && !rest) {\n required.push(parameter.name);\n }\n });\n this.inCommand = false;\n const input: JsonSchema = { type: 'object', properties, additionalProperties: false };\n if (required.length > 0) {\n input.required = required;\n }\n if (this.defs.size > 0) {\n input.$defs = Object.fromEntries(this.defs);\n }\n\n const out: CommandSchemaOut = { parameters: parameters.map(parameter => parameter.name), input };\n const description = this.checker.getDocumentationCommentOfSymbol(symbol);\n if (description !== '') {\n out.description = description;\n }\n if (signature.hasRestParameter) {\n out.rest = true;\n }\n for (const annotation of ['destructive', 'idempotent', 'confirm', 'hidden'] as const) {\n if (tags.some(tag => tag.name === annotation)) {\n out[annotation] = true;\n }\n }\n return out;\n }\n\n /**\n * A parameter's own comment, or failing that its `@param` line.\n *\n * The checker attaches `@param` text to the parameter of a method\n * signature. A command written as a property, `move: (from: number)\n * => void`, keeps its comment on the property, so the tag is read\n * from there instead.\n */\n private parameterDescription(parameter: TsApi.Symbol, tags: readonly TsApi.JSDocTagInfo[]): string {\n const own = this.checker.getDocumentationCommentOfSymbol(parameter);\n if (own !== '') {\n return own;\n }\n for (const tag of tags) {\n const match = tag.name === 'param' ? /^\\s*(\\S+)\\s*(?:-\\s*)?([\\s\\S]*)$/.exec(tag.text ?? '') : null;\n if (match !== null && match[1] === parameter.name) {\n return match[2].trim();\n }\n }\n return '';\n }\n\n private includesUndefined(type: TsApi.Type): boolean {\n const { Undefined, Void } = this.flags;\n if (type.isUnionType()) {\n return (type.getTypes() ?? []).some(member => (member.flags & (Undefined | Void)) !== 0);\n }\n return (type.flags & (Undefined | Void)) !== 0;\n }\n\n private describe(type: TsApi.Type, path: string): JsonSchema {\n const f = this.flags;\n const flags = type.flags;\n\n if (flags & (f.Any | f.Unknown)) {\n return {};\n }\n if (flags & f.Never) {\n this.warnings.push(\n `${path} is never, which describes no value. An empty array literal is never[] unless it says what it holds: write \\`[] as Row[]\\`.`\n );\n return { not: {} };\n }\n if (flags & (f.String | f.TemplateLiteral | f.StringMapping)) {\n return { type: 'string' };\n }\n if (flags & f.Number) {\n return { type: 'number' };\n }\n if (flags & f.Boolean) {\n return { type: 'boolean' };\n }\n if (flags & f.Null) {\n return { type: 'null' };\n }\n if (flags & (f.Undefined | f.Void)) {\n return {};\n }\n if (flags & f.BooleanLiteral) {\n return { const: (type as TsApi.IntrinsicType).intrinsicName === 'true' };\n }\n if (flags & (f.StringLiteral | f.NumberLiteral)) {\n return { const: (type as TsApi.LiteralType).value };\n }\n if (flags & (f.BigInt | f.BigIntLiteral | f.ESSymbol | f.UniqueESSymbol)) {\n return this.unplain(path, flags & f.BigIntLike ? 'a bigint' : 'a symbol');\n }\n if (type.isUnionType()) {\n return this.union(type, path);\n }\n if (flags & f.TypeParameter) {\n return {};\n }\n if (flags & (f.Object | f.Intersection)) {\n // An array is a container rather than a type that can contain\n // itself: `readonly Row[]` in a view and in `Row.children` is one\n // type, and treating it as named would put the array in `$defs`\n // instead of the row.\n if (this.checker.isArrayType(type)) {\n const [element] = this.checker.getTypeArguments(type as TsApi.TypeReference);\n return { type: 'array', items: element === undefined ? {} : this.describe(element, `${path}[]`) };\n }\n if (this.checker.isTupleType(type)) {\n return this.tuple(type as TsApi.TypeReference, path);\n }\n return this.named(type, path);\n }\n this.warnings.push(`${path} has a type this reader does not describe, so it is left open.`);\n return {};\n }\n\n /**\n * A union, with `undefined` taken out (optionality is said by\n * `required`), `true | false` folded back into `boolean`, and a union\n * of nothing but literals written as an `enum`.\n */\n private union(type: TsApi.UnionType, path: string): JsonSchema {\n const f = this.flags;\n let members = (type.getTypes() ?? []).filter(member => (member.flags & (f.Undefined | f.Void)) === 0);\n const booleans = members.filter(member => member.flags & f.BooleanLiteral);\n const schemas: JsonSchema[] = [];\n if (booleans.length === 2) {\n members = members.filter(member => !(member.flags & f.BooleanLiteral));\n schemas.push({ type: 'boolean' });\n }\n if (\n members.length > 0 &&\n schemas.length === 0 &&\n members.every(member => member.flags & (f.StringLiteral | f.NumberLiteral))\n ) {\n return { enum: members.map(member => (member as TsApi.LiteralType).value) };\n }\n // `null` last, so `string | null` reads as a string that may be absent.\n members.sort((a, b) => Number((a.flags & f.Null) !== 0) - Number((b.flags & f.Null) !== 0));\n schemas.push(...members.map(member => this.describe(member, path)));\n return schemas.length === 1 ? schemas[0] : { anyOf: schemas };\n }\n\n /**\n * An object type, described once however often it appears, and by\n * reference when it contains itself.\n */\n private named(type: TsApi.Type, path: string): JsonSchema {\n const id = type.id;\n if (this.inProgress.has(id)) {\n this.recursive.add(id);\n return { $ref: `#/$defs/${this.defName(type)}` };\n }\n this.inProgress.add(id);\n const schema = this.object(type, path);\n this.inProgress.delete(id);\n if (this.recursive.has(id)) {\n const name = this.defName(type);\n this.defs.set(name, schema);\n return { $ref: `#/$defs/${name}` };\n }\n return schema;\n }\n\n private defName(type: TsApi.Type): string {\n let name = this.defNames.get(type.id);\n if (name === undefined) {\n const base = (type.getAliasSymbol() ?? type.getSymbol())?.name ?? 'Type';\n const taken = new Set(this.defNames.values());\n name = taken.has(base) ? `${base}${type.id}` : base;\n this.defNames.set(type.id, name);\n }\n return name;\n }\n\n private object(type: TsApi.Type, path: string): JsonSchema {\n const checker = this.checker;\n const symbolName = type.getSymbol()?.name;\n if (symbolName !== undefined && this.inCommand && BINARY.has(symbolName)) {\n return { type: 'string', contentEncoding: 'base64', 'x-gesso-binary': symbolName };\n }\n if (symbolName !== undefined && NOT_PLAIN.has(symbolName)) {\n return this.unplain(path, `a ${symbolName}`);\n }\n if ((type as TsApi.ObjectType).objectFlags & this.ts.ObjectFlags.Class) {\n return this.unplain(path, `an instance of ${symbolName ?? 'a class'}`);\n }\n if (checker.getSignaturesOfType(type, this.ts.SignatureKind.Call).length > 0) {\n return this.unplain(path, 'a function');\n }\n\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n for (const property of checker.getPropertiesOfType(type)) {\n const propertyType = checker.getTypeOfSymbol(property);\n const at = `${path}.${property.name}`;\n if (propertyType === undefined) {\n properties[property.name] = {};\n continue;\n }\n const schema = this.describe(propertyType, at);\n const description = checker.getDocumentationCommentOfSymbol(property);\n properties[property.name] = description === '' ? schema : { ...schema, description };\n const optional = (property.flags & this.ts.SymbolFlags.Optional) !== 0 || this.includesUndefined(propertyType);\n if (!optional) {\n required.push(property.name);\n }\n }\n const schema: JsonSchema = { type: 'object', properties };\n if (required.length > 0) {\n schema.required = required;\n }\n const index = checker.getIndexInfosOfType(type).find(info => info.keyType.flags & this.flags.String);\n if (index !== undefined) {\n schema.additionalProperties = this.describe(index.valueType, `${path}[key]`);\n }\n return schema;\n }\n\n private tuple(type: TsApi.TypeReference, path: string): JsonSchema {\n const elements = this.checker.getTypeArguments(type);\n const elementFlags = (type.getTarget() as TsApi.TupleType).elementFlags ?? [];\n const { Required, Rest } = this.ts.ElementFlags;\n const prefixItems: JsonSchema[] = [];\n let items: JsonSchema | false = false;\n let minItems = 0;\n elements.forEach((element, index) => {\n const schema = this.describe(element, `${path}[${index}]`);\n if (elementFlags[index] & Rest) {\n items = schema;\n } else {\n prefixItems.push(schema);\n if (elementFlags[index] & Required) {\n minItems = index + 1;\n }\n }\n });\n return { type: 'array', prefixItems, items, minItems };\n }\n\n private unplain(path: string, what: string): JsonSchema {\n this.warnings.push(`${path} is ${what}, which is not plain data and cannot cross a channel.`);\n return {};\n }\n}\n","import { blankLiterals, findCall, findCalls, firstArgumentName, importSources } from './source.ts';\n\n/** What the plugin found in a render worker entry, and could wire. */\nexport interface RenderWiring {\n /** The rewritten module, or null when there was nothing to wire. */\n readonly code: string | null;\n /**\n * Why nothing was wired, when nothing was. A sentence for the\n * developer, not an error: an entry the plugin cannot wire still\n * runs, it just full-reloads on a save.\n */\n readonly skipped: string | null;\n}\n\nconst MARKER = '/* gesso-vite-plugin: hot replacement */';\n\n/**\n * Writes the two lines an author would otherwise write by hand.\n *\n * The example below is the specification:\n *\n * const app = renderRoot(LiveApp).useService(LiveFeed);\n * import.meta.hot?.accept('./LiveExampleApp', module => {\n * app.reload(module.LiveApp, [module.LiveFeed]);\n * });\n *\n * Three things have to be found for that to be written mechanically:\n * the handle the chain returns, the module the root component came\n * from, and the modules the services came from. The handle is taken by\n * routing the call through a wrapper of the plugin's own, which keeps\n * the chain that follows it intact whether or not the author assigned\n * it. The modules come from the entry's own import statements, which is\n * exactly the question `importSources` answers.\n *\n * A service declared in a module of its own is accepted alongside the\n * root, because a registry keyed by class object cannot tell a\n * replacement from a stranger and `reload` is where that is repaired.\n * What is deliberately *not* wired is `useRoutes`: routes are read once\n * when the runtime is built, so a change to the route table is a full\n * reload and saying so is better than replacing a tree that still\n * resolves the old routes.\n */\nexport function transformRenderWorker(code: string): RenderWiring {\n if (code.includes(MARKER)) {\n return { code: null, skipped: null };\n }\n const blank = blankLiterals(code);\n const imports = importSources(code, blank);\n if (imports.get('renderRoot') !== 'gesso-framework') {\n return { code: null, skipped: null };\n }\n const call = findCall(code, 'renderRoot', blank);\n if (call === null) {\n return { code: null, skipped: null };\n }\n\n const root = firstArgumentName(code, call, blank);\n if (root === null) {\n return {\n code: null,\n skipped:\n 'renderRoot() is not called with the name of a component, so there is nothing to look up in a replaced module.'\n };\n }\n const rootSource = imports.get(root);\n if (rootSource === undefined) {\n return {\n code: null,\n skipped: `${root} is declared in the worker entry itself rather than imported, so replacing it would replace the entry and reload the page.`\n };\n }\n\n // Every service the chain registers, paired with the module it came\n // from. One declared beside the root is the common case and needs no\n // second dependency; one in a module of its own adds one.\n const services: { name: string; source: string }[] = [];\n for (const site of findCalls(code, '.useService', blank)) {\n const name = firstArgumentName(code, site, blank);\n const source = name === null ? undefined : imports.get(name);\n if (name !== null && source !== undefined) {\n services.push({ name, source });\n }\n }\n\n const sources = [rootSource, ...services.map(service => service.source)].filter(\n (source, index, all) => all.indexOf(source) === index\n );\n const namespace = (source: string): string => `__gessoModule${sources.indexOf(source)}`;\n const rewritten = `${code.slice(0, call.start)}__gessoRenderRoot${code.slice(call.start + 'renderRoot'.length)}`;\n\n const lines = [\n MARKER,\n ...sources.map((source, index) => `import * as __gessoImported${index} from ${JSON.stringify(source)};`),\n 'function __gessoRenderRoot(root) {',\n ' __gessoRenderRoot.app = renderRoot(root);',\n ' return __gessoRenderRoot.app;',\n '}',\n `const __gessoLatest = [${sources.map((_, index) => `__gessoImported${index}`).join(', ')}];`,\n 'if (import.meta.hot) {',\n ` import.meta.hot.accept([${sources.map(source => JSON.stringify(source)).join(', ')}], replaced => {`,\n ' replaced.forEach((module, index) => {',\n ' if (module !== undefined) {',\n ' __gessoLatest[index] = module;',\n ' }',\n ' });',\n ` __gessoRenderRoot.app.reload(${namespaceRead(namespace(rootSource), root)}, [${services\n .map(service => namespaceRead(namespace(service.source), service.name))\n .join(', ')}]);`,\n ' });',\n '}'\n ];\n return { code: `${rewritten}\\n${lines.join('\\n')}\\n`, skipped: null };\n}\n\n/** `__gessoLatest[n].Name`, written through the array so a replacement wins. */\nfunction namespaceRead(namespaceName: string, exported: string): string {\n const index = namespaceName.slice('__gessoModule'.length);\n return `__gessoLatest[${index}].${exported}`;\n}\n","import { SHELL_BRIDGE } from './agent.ts';\nimport { blankLiterals, findCall, importSources, type CallSite } from './source.ts';\n\n/** Where the plugin found the two worker entries, as the shell imports them. */\nexport interface WorkerEntries {\n /** A specifier relative to the shell module, e.g. `./RenderWorker.ts`. */\n readonly renderWorker: string;\n /** The same for the application worker, or null when there is none. */\n readonly appLogicWorker: string | null;\n}\n\n/** A `createApp` call the plugin could write for, and what it still needs. */\nexport interface ShellCall {\n readonly call: CallSite;\n /**\n * False when the author wrote `renderWorker` themselves, which is the\n * documented fallback and the case where the plugin has no worker to\n * find. It still wires the overlay in.\n */\n readonly needsWorkers: boolean;\n}\n\nexport interface ShellTransformOptions {\n /** The entries to construct, or null when the author named them. */\n readonly entries: WorkerEntries | null;\n /**\n * Whether to wire the error overlay in as well. True while the dev\n * server is running and never in a build, so a production bundle\n * carries no reference to `gesso-devtools`.\n */\n readonly overlay: boolean;\n /**\n * Hand the app to the development agent bridge once it is created\n * (default false). A dev server only.\n */\n readonly agent?: boolean;\n}\n\n/** Marks a module the plugin has already rewritten, so it is not done twice. */\nconst MARKER = '/* gesso-vite-plugin */';\n\n/**\n * The `createApp` call in a module, when the module has one that came\n * from the framework.\n *\n * Separate from the transform because finding the worker entries is an\n * asynchronous resolution against the bundler and worth doing only for\n * a module that turns out to be a shell, which is one module in an\n * application.\n */\nexport function findShellCall(code: string, blank = blankLiterals(code)): ShellCall | null {\n if (code.includes(MARKER)) {\n return null;\n }\n if (importSources(code, blank).get('createApp') !== 'gesso-framework') {\n return null;\n }\n const call = findCall(code, 'createApp', blank);\n if (call === null) {\n return null;\n }\n return { call, needsWorkers: !blank.slice(call.argsStart, call.argsEnd).includes('renderWorker') };\n}\n\n/**\n * Rewrites the shell module so that it names no worker.\n *\n * The one edit inside the author's own code is the call itself:\n * `createApp(...)` becomes `createApp(__gessoOptions(...))`, on the\n * same line, so every line number in the module is the one it was.\n * Everything else is appended below, as function declarations, which\n * hoist and are therefore usable from the line above them.\n *\n * The merge order is what keeps the promise that the\n * literal construction stays the documented fallback: the plugin's\n * factories go in first and the author's options spread over them, so\n * a `renderWorker` written by hand still wins.\n *\n * Returns null when there is nothing to do, which is the common case:\n * most modules do not call `createApp`.\n */\nexport function transformShell(code: string, options: ShellTransformOptions): string | null {\n const blank = blankLiterals(code);\n const shell = findShellCall(code, blank);\n if (shell === null) {\n return null;\n }\n if (options.entries === null && !options.overlay && options.agent !== true) {\n return null;\n }\n const { call } = shell;\n const args = code.slice(call.argsStart, call.argsEnd).trim();\n const created = `${code.slice(call.start, call.argsStart)}__gessoOptions(${args === '' ? '{}' : args})${code.slice(call.argsEnd, call.end)}`;\n // The whole call wrapped, so the bridge gets the app whatever the\n // shell then does with it: a variable, a chained mount, or nothing.\n const wrapped = options.agent === true ? `__gessoAgent(${created})` : created;\n const rewritten = `${code.slice(0, call.start)}${wrapped}${code.slice(call.end)}`;\n return `${rewritten}\\n${prelude(options)}${options.agent === true ? SHELL_BRIDGE : ''}`;\n}\n\n/**\n * The appended half: the worker construction, and in development the\n * error overlay.\n *\n * `new Worker(new URL(...), { type: 'module', ... })` is written out\n * literally because that is the only shape a bundler splits a worker\n * out of, which is the whole reason this text has to be emitted into\n * the author's module rather than living inside the framework. `name`\n * is passed as a member whose value may be undefined, which a\n * dictionary conversion treats as absent, so one construction serves\n * both the named and the unnamed case.\n */\nfunction prelude(options: ShellTransformOptions): string {\n const entries = options.entries;\n const lines = [\n MARKER,\n 'function __gessoOptions(options = {}) {',\n ' return {',\n ...(entries === null\n ? []\n : [\n ` renderWorker: () => new Worker(new URL(${JSON.stringify(entries.renderWorker)}, import.meta.url), { type: 'module', name: options.workerName }),`\n ]),\n ...(entries?.appLogicWorker == null\n ? []\n : [\n ` appLogicWorker: () => new Worker(new URL(${JSON.stringify(entries.appLogicWorker)}, import.meta.url), { type: 'module', name: options.workerName }),`\n ]),\n ...(options.overlay ? [' onError: __gessoReportError,'] : []),\n // In a dev server the channels are offered to an agent in the\n // browser too, where the browser has WebMCP; the app's own\n // `webmcp`, spread below, still decides.\n ...(options.agent === true ? [' webmcp: true,'] : []),\n ' ...options',\n ' };',\n '}'\n ];\n return options.overlay ? `${lines.join('\\n')}\\n${OVERLAY}` : `${lines.join('\\n')}\\n`;\n}\n\n/**\n * The development error overlay, loaded the first time something\n * throws and not before.\n *\n * Lazy because it costs nothing until it is needed: a page that never\n * throws never fetches `gesso-devtools`, and a page that does gets\n * the overlay within a network round trip of the error rather than\n * paying for the package on every start.\n *\n * The host is the canvas's parent, which is the element the\n * application was mounted into: the overlay covers the application it\n * is reporting on rather than the viewport, and a Gesso app is not\n * necessarily the whole page. `document.body` is the fallback for an\n * error thrown before there is a canvas at all.\n *\n * State is kept on the function object rather than in module-level\n * `let` bindings, because this block is appended below the code that\n * calls it and a `let` read from above it would be in its temporal\n * dead zone.\n */\nconst OVERLAY = `function __gessoReportError(message, stack, source) {\n const state = (__gessoReportError.state ??= { pending: [], overlay: null, loading: false });\n state.pending.push([message, stack, source]);\n if (state.overlay !== null) {\n __gessoFlushErrors();\n return;\n }\n if (state.loading) {\n return;\n }\n state.loading = true;\n void import('gesso-devtools').then(({ mountErrorOverlay }) => {\n const canvas = document.querySelector('canvas');\n state.overlay = mountErrorOverlay(canvas?.parentElement ?? document.body);\n __gessoFlushErrors();\n });\n}\nfunction __gessoFlushErrors() {\n const state = __gessoReportError.state;\n for (const [message, stack, source] of state.pending.splice(0)) {\n state.overlay.report(message, stack, source);\n }\n}\naddEventListener('error', event => {\n const error = event.error;\n __gessoReportError(error?.message ?? event.message, error?.stack, 'window');\n});\naddEventListener('unhandledrejection', event => {\n const reason = event.reason;\n __gessoReportError(reason?.message ?? String(reason), reason?.stack, 'window');\n});\n`;\n\n/**\n * The single-thread shell in a dev server: `createSyncApp(Root)`\n * wrapped so the agent bridge gets the builder, which answers an agent\n * port from the page itself. There are no workers to write and no\n * overlay to wire here, so this is all the plugin does to such a shell.\n */\nexport function transformSyncShell(code: string): string | null {\n if (code.includes(MARKER)) {\n return null;\n }\n const blank = blankLiterals(code);\n if (importSources(code, blank).get('createSyncApp') !== 'gesso-framework') {\n return null;\n }\n const call = findCall(code, 'createSyncApp', blank);\n if (call === null) {\n return null;\n }\n const wrapped = `__gessoAgent(${code.slice(call.start, call.end)})`;\n return `${code.slice(0, call.start)}${wrapped}${code.slice(call.end)}\\n${MARKER}\\n${SHELL_BRIDGE}`;\n}\n","import {\n defaultClientConditions,\n type EnvironmentModuleGraph,\n type EnvironmentModuleNode,\n type Plugin,\n type UserConfig\n} from 'vite';\n\nimport { AGENT_PATH, createAgentBridge, type BridgeRequest, type BridgeResponse, type BridgeSocket } from './agent.ts';\nimport { ContractReader, declaresChannel, describeCalls, type TypeScriptApi } from './contracts.ts';\nimport { transformRenderWorker } from './render.ts';\nimport { findShellCall, transformShell, transformSyncShell, type WorkerEntries } from './shell.ts';\n\nexport { ContractReader, describedModule, type ContractReading } from './contracts.ts';\nexport { transformRenderWorker, type RenderWiring } from './render.ts';\nexport {\n findShellCall,\n transformShell,\n transformSyncShell,\n type ShellCall,\n type ShellTransformOptions,\n type WorkerEntries\n} from './shell.ts';\nexport { blankLiterals, findCall, findCalls, firstArgumentName, importSources, type CallSite } from './source.ts';\n\n/**\n * `gesso-vite-plugin` — the plumbing between saving a file and seeing\n * the result.\n *\n * A Gesso application is three files either side of a thread barrier\n *, and until now the barrier cost the author four\n * incantations: `new Worker(new URL('./RenderWorker.ts',\n * import.meta.url), { type: 'module' })` twice, because only a literal\n * gets a chunk; `import.meta.hot.accept` with the root module named by\n * hand; and `mountErrorOverlay` wired to `onError`, without which a\n * worker exception reaches a console nobody has selected. None of them\n * is a decision. All of them are written the same way in every\n * application, and getting one wrong fails silently.\n *\n * The three-file shape stays. What this removes is the incantations,\n * and what it adds is the one diagnostic that cannot be read off the\n * screen: a save that reloads the page rather than replacing a module,\n * which traces to the root module having a\n * main-thread importer and which otherwise looks like HMR simply not\n * working.\n *\n * // vite.config.ts\n * import { gesso } from 'gesso-vite-plugin';\n * export default defineConfig({ plugins: [gesso()] });\n *\n * // main.ts\n * createApp({ history: { mode: 'path' } }).mount('#app');\n *\n * The literal construction stays supported and stays documented: the\n * plugin merges its factories *under* the options the author wrote, so\n * a hand-written `renderWorker` wins and an application that would\n * rather say it out loud can.\n */\nexport interface GessoPluginOptions {\n /**\n * The render worker entry, as a specifier the shell module could\n * import. By default the plugin tries the names below, in order, and\n * uses the first that resolves beside the shell.\n */\n readonly renderWorker?: string;\n /**\n * The application worker entry, or false for an application that has\n * none. By default the plugin looks for it and leaves it out when\n * there is nothing to find, which is the single-worker shape the\n * scaffold produces.\n */\n readonly appLogicWorker?: string | false;\n /**\n * Wire `gesso-devtools`'s error overlay into `onError` (default\n * true). Only ever in a dev server: a build carries no reference to\n * the package.\n */\n readonly overlay?: boolean;\n /** Emit the `import.meta.hot.accept` wiring (default true). */\n readonly hmr?: boolean;\n /**\n * Report a save that will reload the page instead of replacing a\n * module (default true).\n */\n readonly diagnostics?: boolean;\n /**\n * Resolve a dependency's `worker` export ahead of its `browser` one\n * (default true). See {@link workerConditions}.\n */\n readonly workerConditions?: boolean;\n /**\n * Describe every channel the application declares as JSON Schema,\n * read from the contract's types and JSDoc, and attach it to the\n * token with `describeChannel` (default true). It is what lets an AI\n * agent, or anything else that meets the application only at run\n * time, ask a channel what it holds and what its commands take.\n *\n * Needs TypeScript 7, whose checker does the reading. Without it the\n * plugin says so once and carries on undescribed.\n */\n readonly channelSchemas?: boolean;\n /**\n * Serve MCP at `/__gesso/mcp` while the dev server runs, so an AI\n * agent can read the open page's channels and send their commands\n * (default true). Development only: a build carries none of it.\n */\n readonly agent?: boolean;\n}\n\n/**\n * The export conditions a Gesso application resolves its dependencies\n * with: `worker` ahead of Vite's defaults.\n *\n * A Gesso application's code runs in workers, and Vite resolves every\n * dependency with the `browser` condition, which is the right call for\n * a page and the wrong one for a worker: a package's browser build may\n * reach for `document`. `decode-named-character-reference`, which every\n * markdown parser built on micromark imports, does exactly that, and a\n * render worker that imported one died on start with \"document is not\n * defined\". The same package publishes a `worker` build, as packages\n * with a DOM-only browser build tend to. A package's own export order\n * decides between the two, and those list `worker` first.\n *\n * The main thread resolves the same way. A worker build runs in a page\n * as well, and the shell imports little beyond Gesso itself.\n */\nexport const workerConditions: readonly string[] = ['worker', ...defaultClientConditions];\n\n/**\n * Where a render worker entry is looked for, beside the shell.\n *\n * Ordered so that a name that says what the file is beats the generic\n * one: an application with both `RenderWorker.ts` and `worker.ts` means\n * the first, and the scaffold, which has only `worker.ts`, still\n * resolves.\n */\nconst RENDER_WORKER_NAMES = [\n './RenderWorker.ts',\n './RenderWorker.tsx',\n './render.worker.ts',\n './app.render.worker.ts',\n './worker.ts'\n];\n\n/** Where an application worker entry is looked for, beside the shell. */\nconst APP_WORKER_NAMES = ['./AppWorker.ts', './AppWorker.tsx', './app.worker.ts', './app.logic.worker.ts'];\n\n/** Modules the plugin will read: the application's own source, not its dependencies. */\nconst SOURCE = /\\.(?:[cm]?[jt]sx?)(?:$|\\?)/;\n\nexport function gesso(options: GessoPluginOptions = {}): Plugin {\n let serving = false;\n /** The shell module, once one has been transformed. */\n let shellId: string | null = null;\n /** The render worker entry, once the shell has named it. */\n let renderWorkerId: string | null = null;\n /** Files already reported as reloading, so a save is not a stream of warnings. */\n const reported = new Set<string>();\n /** The checker, started by the first contract, or null once it is known to be unavailable. */\n let contracts: Promise<ContractReader | null> | undefined;\n let root = '';\n const readerFor = (warn: (message: string) => void): Promise<ContractReader | null> =>\n (contracts ??= import('typescript/unstable/sync').then(\n ts => new ContractReader(ts as TypeScriptApi, root),\n () => {\n warn(\n 'Channels are not described, because TypeScript 7 is not installed. Add `typescript` (7 or later) to ' +\n 'devDependencies, or pass `channelSchemas: false` to stop this message.'\n );\n return null;\n }\n ));\n const closeContracts = async () => {\n const reader = await contracts;\n reader?.close();\n contracts = undefined;\n };\n /** The module with its channels described, or null when it declares none. */\n const describeContract = async (code: string, id: string, warn: (message: string) => void) => {\n if (\n options.channelSchemas === false ||\n !SOURCE.test(id) ||\n id.includes('/node_modules/') ||\n !declaresChannel(code)\n ) {\n return null;\n }\n const reader = await readerFor(warn);\n if (reader === null) {\n return null;\n }\n const reading = reader.read(id.replace(/\\?.*$/, ''));\n reading.warnings.forEach(warn);\n return reading.channels.size > 0 ? code + describeCalls(reading.channels) : null;\n };\n /**\n * The same description, for a worker's bundle.\n *\n * A build bundles each worker with `worker.plugins` rather than with\n * the plugins of the page, and a contract is imported by workers far\n * more often than by the page, so without this a build would describe\n * almost nothing. A dev server runs every module through the main\n * plugins and does not need it. Each worker bundle closes the checker\n * when it is done, because nothing guarantees another bundle follows\n * to close it; the next contract starts it again.\n */\n const workerContracts: Plugin = {\n name: 'gesso:channel-schemas',\n enforce: 'pre',\n async transform(code, id) {\n const described = await describeContract(code, id, message => this.warn(message));\n return described === null ? null : { code: described, map: null };\n },\n async closeBundle() {\n await closeContracts();\n }\n };\n\n return {\n name: 'gesso',\n // Before Vite's own worker and asset plugins, which are what turn\n // the emitted `new Worker(new URL(...))` into a chunk, and before\n // the TypeScript transform, so the module still reads as it was\n // written.\n enforce: 'pre',\n\n config(config, env): UserConfig {\n return {\n ...(options.workerConditions === false ? {} : { resolve: { conditions: [...workerConditions] } }),\n ...(env.command === 'serve' ? { optimizeDeps: { rolldownOptions: { plugins: [scanShell(options)] } } } : {}),\n // Module workers, which is what the plugin constructs, so a worker\n // can load a chunk on demand. Vite builds workers as IIFE unless\n // told otherwise, and an IIFE cannot split: a dynamic import in\n // the render worker was inlined, and a markdown editor's HTML\n // parser, loaded only on a paste, went into every page load.\n worker: {\n ...(config.worker?.format === undefined ? { format: 'es' as const } : {}),\n // Vite concatenates this with the application's own.\n ...(options.channelSchemas === false ? {} : { plugins: () => [workerContracts] })\n }\n };\n },\n\n configResolved(config) {\n serving = config.command === 'serve';\n root = config.root;\n },\n\n /**\n * The agent endpoint, and a line saying where it is once the server\n * is listening, because an endpoint nobody knows the address of is\n * one nobody connects to.\n */\n configureServer(server) {\n if (options.agent === false) {\n return;\n }\n const bridge = createAgentBridge(server.ws as unknown as BridgeSocket);\n server.middlewares.use((request, response, next) =>\n bridge.middleware(request as unknown as BridgeRequest, response as unknown as BridgeResponse, next)\n );\n server.httpServer?.once('listening', () => {\n const base = server.resolvedUrls?.local[0];\n if (base !== undefined) {\n const url = new URL(AGENT_PATH, base).href;\n server.config.logger.info(\n ` ➜ Agents: ${url}\\n claude mcp add --transport http ${agentName(server.config.root)} ${url}`\n );\n }\n });\n },\n\n watchChange(id) {\n void contracts?.then(reader => reader?.invalidate(id));\n },\n\n /**\n * The checker is a child process, and a build that left it running\n * would never exit. A dev server calls this when it closes, so the\n * one hook covers both.\n */\n async closeBundle() {\n await closeContracts();\n },\n\n async transform(source, id) {\n if (!SOURCE.test(id) || id.includes('/node_modules/')) {\n return null;\n }\n\n const described = await describeContract(source, id, message => this.warn(message));\n const code = described ?? source;\n\n if (serving && options.hmr !== false) {\n const wiring = transformRenderWorker(code);\n if (wiring.skipped !== null) {\n this.warn(`${wiring.skipped} Saving it will reload the page rather than replace the tree.`);\n }\n if (wiring.code !== null) {\n renderWorkerId = id;\n return { code: wiring.code, map: null };\n }\n }\n\n const call = findShellCall(code);\n if (call === null) {\n const sync = serving && options.agent !== false ? transformSyncShell(code) : null;\n if (sync !== null) {\n return { code: sync, map: null };\n }\n return described === null ? null : { code, map: null };\n }\n shellId = id;\n const entries = call.needsWorkers ? await resolveEntries(this, id, options) : null;\n const shell = transformShell(code, {\n entries,\n overlay: serving && options.overlay !== false,\n agent: serving && options.agent !== false\n });\n return shell === null ? (described === null ? null : { code, map: null }) : { code: shell, map: null };\n },\n\n /**\n * The failure that looks like a bug in the framework.\n *\n * A module reached from the main thread as well\n * as from the render worker cannot be hot-replaced, because Vite\n * propagates the invalidation to a main-thread importer that does\n * not accept and reloads the page. The screen blinks, the app\n * restarts, and nothing anywhere says why. Both ends of the module\n * graph are known here, so the answer is one walk of the importers.\n */\n hotUpdate({ modules, server, timestamp }) {\n if (renderWorkerId !== null) {\n refreshAcceptedImports(this.environment.moduleGraph, renderWorkerId, modules, timestamp);\n }\n if (options.diagnostics === false || shellId === null || renderWorkerId === null) {\n return;\n }\n for (const module of modules) {\n if (module.id === null || reported.has(module.id)) {\n continue;\n }\n const importers = importerClosure(module);\n if (!importers.has(shellId) || !importers.has(renderWorkerId)) {\n continue;\n }\n reported.add(module.id);\n server.config.logger.warn(\n `[gesso] ${short(module.id, server.config.root)} is imported by the main thread as well as by the render ` +\n 'worker, so saving it reloads the page instead of replacing the tree. Reach it only from the render ' +\n \"worker's own graph to get hot replacement back.\"\n );\n }\n }\n };\n}\n\nexport default gesso;\n\n/**\n * Shows Vite's dependency scan what the dev server will actually load.\n *\n * Vite pre-bundles a dev server's dependencies from a scan that starts\n * at the HTML and follows imports. It runs none of the plugin's\n * transforms, so it never sees the workers the shell constructs, nor\n * the `gesso-devtools` overlay and `gesso-framework/agent` bridge the\n * shell loads lazily. Every Gesso package a worker imports was found\n * only when the page asked for it, which re-optimized, invalidated the\n * modules already served, and reloaded the page: on the first start of\n * any app installed from the registry, the first page load failed with\n * \"504 (Outdated Optimize Dep)\" and the overlay that would have\n * reported it failed the same way. A workspace that links Gesso from\n * source never met it, because linked packages are not pre-bundled.\n *\n * So the scan gets the shell as the dev server serves it, plus a plain\n * import of each worker entry, which is enough for it to walk into the\n * workers. Nothing here reaches the served code.\n */\nfunction scanShell(options: GessoPluginOptions) {\n return {\n name: 'gesso:scan-shell',\n async transform(this: ScanResolver, code: string, id: string) {\n if (!SOURCE.test(id) || id.includes('/node_modules/')) {\n return null;\n }\n const call = findShellCall(code);\n if (call === null) {\n return null;\n }\n // The scan resolves a file that does not exist to an external id\n // rather than to null, so as it stands every candidate name would\n // \"resolve\" and the first, `./RenderWorker.ts`, would win over the\n // `./worker.ts` that is actually there.\n const resolver: Resolver = {\n resolve: async (source, importer) => {\n const resolved = await this.resolve(source, importer);\n return resolved === null || resolved.external === true ? null : resolved;\n }\n };\n const entries = call.needsWorkers ? await resolveEntries(resolver, id, options).catch(() => null) : null;\n const shell =\n transformShell(code, { entries, overlay: options.overlay !== false, agent: options.agent !== false }) ?? code;\n const workers = [entries?.renderWorker, entries?.appLogicWorker].filter(entry => typeof entry === 'string');\n return { code: `${shell}\\n${workers.map(entry => `import ${JSON.stringify(entry)};`).join('\\n')}\\n`, map: null };\n }\n };\n}\n\n/** A name for the MCP server: the project's directory, which is what a person calls the app. */\nfunction agentName(root: string): string {\n return (root.split('/').filter(Boolean).pop() ?? 'gesso').replace(/[^A-Za-z0-9_-]/g, '-');\n}\n\n/**\n * Keeps the render worker importing what it accepted at the version\n * the rest of the graph imports.\n *\n * Vite marks every importer of a saved module stale, so its next\n * request re-imports the module at the save's timestamp, except an\n * importer that accepts it: that one was handed the new module in the\n * update and its served code still names the old timestamp. The render\n * worker accepts its root's and its services' modules (the wiring\n * above), so a page reloaded after a save imported a service at one\n * timestamp from the worker and another from the screens: two modules,\n * two classes, and an `inject` that found neither. Only a restart of\n * the dev server got out of it.\n *\n * Marked stale softly, which redoes only the import timestamps.\n */\nfunction refreshAcceptedImports(\n graph: EnvironmentModuleGraph,\n workerId: string,\n modules: readonly EnvironmentModuleNode[],\n timestamp: number\n): void {\n const worker = graph.getModuleById(workerId);\n if (worker !== undefined && modules.some(module => worker.acceptedHmrDeps.has(module))) {\n graph.invalidateModule(worker, new Set(), timestamp, false, true);\n }\n}\n\n/** Every module that transitively imports this one, plus this one. */\nfunction importerClosure(module: EnvironmentModuleNode): Set<string> {\n const seen = new Set<string>();\n const queue = [module];\n while (queue.length > 0) {\n const next = queue.pop()!;\n if (next.id === null || seen.has(next.id)) {\n continue;\n }\n seen.add(next.id);\n queue.push(...next.importers);\n }\n return seen;\n}\n\n/** A path relative to the project, for a message a person reads. */\nfunction short(id: string, root: string): string {\n return id.startsWith(root) ? id.slice(root.length + 1) : id;\n}\n\n/** What the plugin resolves against, so a spec can hand it a fake. */\ninterface Resolver {\n resolve(source: string, importer: string): Promise<{ id: string } | null>;\n}\n\n/** The dependency scan's resolver, which can answer with an external id. */\ninterface ScanResolver {\n resolve(source: string, importer: string): Promise<{ id: string; external?: boolean | string } | null>;\n}\n\n/**\n * Finds the worker entries beside a shell module.\n *\n * The names are tried against the bundler's own resolver rather than\n * read off the disk: it already has the answer cached, it applies the\n * project's aliases and extensions, and it is the only thing that can\n * say whether the specifier the plugin is about to write would have\n * resolved. Nothing here touches the filesystem, which is also why the\n * package needs no node types.\n */\nasync function resolveEntries(context: Resolver, id: string, options: GessoPluginOptions): Promise<WorkerEntries> {\n const renderWorker = await firstResolved(\n context,\n id,\n options.renderWorker === undefined ? RENDER_WORKER_NAMES : [options.renderWorker]\n );\n if (renderWorker === null) {\n throw new Error(\n `gesso-vite-plugin found no render worker beside ${id}. It looked for ${RENDER_WORKER_NAMES.join(', ')}. ` +\n \"Name it with the plugin's `renderWorker` option, or write `renderWorker` in createApp() yourself.\"\n );\n }\n const appLogicWorker =\n options.appLogicWorker === false\n ? null\n : await firstResolved(\n context,\n id,\n options.appLogicWorker === undefined ? APP_WORKER_NAMES : [options.appLogicWorker]\n );\n return { renderWorker, appLogicWorker };\n}\n\n/** The first specifier that resolves beside `importer`, as written. */\nasync function firstResolved(context: Resolver, importer: string, names: readonly string[]): Promise<string | null> {\n for (const name of names) {\n if ((await context.resolve(name, importer)) !== null) {\n return name;\n }\n }\n return null;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gesso-vite-plugin",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "Finds a Gesso application's worker entries, writes the constructions and the hot-replacement wiring, and says when a save will reload the page.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Kevin Baker",
|