@jk2908/cxx 0.3.1 → 0.3.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.
@@ -2,13 +2,13 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/build.ts", "../src/config.ts", "../src/lru.ts", "../src/utils.ts", "../src/next/index.ts"],
4
4
  "sourcesContent": [
5
- "import { createHash } from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport { transform } from 'lightningcss'\nimport MagicString, { type SourceMap } from 'magic-string'\n\nimport type { BuildContext, PluginConfig, Tags } from './types.js'\nimport { AUTOGEN_MSG, GENERATED_DIR, PKG_NAME } from './config.js'\nimport { LruCache } from './lru.js'\nimport { pascalise } from './utils.js'\n\n// decode bytes to a string, then stringify into a safe literal. `${bytes}` only\n// works by accident for Buffer; a plain Uint8Array stringifies as `97,123,125`\nconst decoder = new TextDecoder()\n\n/**\n * LRU cache of `collect` results by file id + last seen source + config so watcher and transform\n * can reuse the same parsed template/tags.\n */\nconst collectCache = new LruCache<{\n\tsource: string\n\tconfig: string\n\ttemplate: string\n\ttags: Tags\n\tmap: SourceMap | null\n}>()\n\n/**\n * LRU cache for file content. Stores the last written content per file path so `maybeWrite`\n * can skip disk i/o when nothing has changed.\n */\nconst fileCache = new LruCache<string>()\n\n/**\n * Serialises type file writes inside a single process so overlapping `writeTypes` calls can't\n * interleave or land out of order.\n */\nlet writeChain: Promise<void> = Promise.resolve()\n\n/**\n * Returns whether the error was caused by a missing file or directory.\n */\nexport function isENOENT(err: unknown) {\n\treturn err instanceof Error && 'code' in err && err.code === 'ENOENT'\n}\n\n/**\n * Write a file by first writing to a unique temporary file and then renaming it into place, so\n * concurrent writers (e.g. Turbopack loader workers) never observe a partial file.\n */\nasync function writeFileAtomic(filePath: string, content: string) {\n\tconst tmp = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`\n\n\tawait fs.writeFile(tmp, content)\n\tawait fs.rename(tmp, filePath)\n}\n\n/**\n * Run a write task after all previously queued writes have settled. A rejection doesn't break the\n * chain for later tasks.\n */\nfunction enqueueWrite<T>(task: () => Promise<T>) {\n\t// wait for the previous write to finish, then run this one, even if the previous one failed\n\tconst run = writeChain.then(task, task)\n\n\t// move the queue on to this write, but turn either outcome into success so it never rejects\n\twriteChain = run.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t)\n\n\t// return the real promise, so the caller still sees this write's value or error\n\treturn run\n}\n\n/**\n * Write a file only if the content actually differs from what is already on disk.\n */\nexport async function maybeWrite(filePath: string, content: string) {\n\tconst cached = fileCache.get(filePath)\n\t// fast path: already wrote this exact content in this process\n\tif (cached === content) return false\n\n\t// verify against disk on a cold start (or when the cache is stale) so we\n\t// don't needlessly bump the mtime and invalidate downstream watchers\n\ttry {\n\t\tif ((await fs.readFile(filePath, 'utf-8')) === content) {\n\t\t\tfileCache.set(filePath, content)\n\t\t\treturn false\n\t\t}\n\t} catch (err) {\n\t\tif (!isENOENT(err)) throw err\n\t}\n\n\tawait writeFileAtomic(filePath, content)\n\tfileCache.set(filePath, content)\n\n\treturn true\n}\n\n// matches `[css, classes, href] = cxx\\`...\\`` and `cxx.tag<T>('name')\\`...\\``\n// capture groups: 1 optional `export `, 2-4 assigned variable names, 5 plain\n// css body, 6 quote kind, 7 tag name, 8 tagged css body\nconst regex =\n\t/((?:export\\s+)?)(?:const|var|let)\\s*\\[(\\w*)\\s*,?\\s*(\\w*)\\s*,?\\s*(\\w*)\\s*\\]\\s*=\\s*cxx(?:\\s*`([\\s\\S]*?)`|\\s*\\.\\s*tag(?:\\s*<[^>]+>)?\\s*\\(\\s*(['\"])(.*?)\\6\\s*\\)\\s*`([\\s\\S]*?)`)/gm\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/**\n * Hash transformed CSS into a stable href for style deduplication.\n */\nfunction hashCss(code: Uint8Array) {\n\treturn `cxx-${createHash('sha256').update(code).digest('base64url').slice(0, 12)}`\n}\n\nexport class DuplicateTagError extends Error {\n\tname = 'DuplicateTagError'\n\n\tconstructor(tag: string) {\n\t\tsuper(`Tag ${tag} has already been seen. Tags must be unique across your application`)\n\t}\n}\n\nexport class InvalidTagError extends Error {\n\tname = 'InvalidTagError'\n\n\tconstructor(tag: string) {\n\t\tsuper(\n\t\t\t`Tag \"${tag}\" does not map to a valid TypeScript identifier. ` +\n\t\t\t\t`Use letters, numbers, spaces, \"_\" or \"-\"`,\n\t\t)\n\t}\n}\n\n/**\n * Transform `cxx` templates in one source file and collect any exported tag types.\n */\nexport function collect(source: string, id: string, config: PluginConfig) {\n\tconst configKey = JSON.stringify(config)\n\n\t// reuse the last result when the source and config are unchanged\n\tconst cached = collectCache.get(id)\n\tif (cached?.source === source && cached.config === configKey) return cached\n\n\tconst tags: Tags = new Map()\n\tconst magic = new MagicString(source)\n\tlet matched = false\n\n\t// the regex is global, so reset its cursor before scanning\n\tregex.lastIndex = 0\n\n\tlet match: RegExpExecArray | null\n\n\t// walk every cxx template and replace it in place\n\twhile ((match = regex.exec(source))) {\n\t\tmatched = true\n\n\t\t// capture groups: export, three bindings, plain css, (quote), tag, tagged css\n\t\tconst [, exp, varOne, varTwo, varThree, plainCss, , tag, taggedCss] = match\n\t\tconst css = plainCss ?? taggedCss\n\n\t\t// compile the CSS to minified CSS Modules\n\t\tconst { code, exports = {} } = transform({\n\t\t\tminify: true,\n\t\t\tcssModules: true,\n\t\t\tfilename: id,\n\t\t\tcode: new TextEncoder().encode(css),\n\t\t})\n\n\t\tconst href = hashCss(code)\n\t\t// map each class name to its generated (scoped) name\n\t\tconst styles = Object.fromEntries(\n\t\t\tObject.entries(exports).map(([k, v]) => [k, v.name]),\n\t\t)\n\n\t\tif (tag) {\n\t\t\tconst suffix =\n\t\t\t\ttypeof config.typeSuffix === 'string'\n\t\t\t\t\t? config.typeSuffix\n\t\t\t\t\t: config.typeSuffix === false\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: 'Classes'\n\t\t\tconst tagWithSuffix = pascalise(`${tag}${suffix}`)\n\n\t\t\tif (!IDENTIFIER.test(tagWithSuffix)) throw new InvalidTagError(tag)\n\t\t\tif (tags.has(tagWithSuffix)) throw new DuplicateTagError(tagWithSuffix)\n\n\t\t\t// side effect but necessary\n\t\t\ttags.set(tagWithSuffix, Object.keys(styles))\n\t\t}\n\n\t\tconst statements: string[] = []\n\n\t\tif (varOne) {\n\t\t\tstatements.push(`${exp}const ${varOne} = ${JSON.stringify(decoder.decode(code))}`)\n\t\t}\n\n\t\tif (varTwo) {\n\t\t\tstatements.push(`${exp}const ${varTwo} = ${JSON.stringify(styles)}`)\n\t\t}\n\n\t\tif (varThree) {\n\t\t\tstatements.push(`${exp}const ${varThree} = ${JSON.stringify(href)}`)\n\t\t}\n\n\t\t// swap the template for the generated declarations, keeping the export keyword\n\t\tmagic.overwrite(match.index, match.index + match[0].length, statements.join('\\n'))\n\t}\n\n\tconst template = magic.toString()\n\t// only build a map when something was actually rewritten\n\tconst map = matched\n\t\t? magic.generateMap({ source: id, includeContent: true, hires: true })\n\t\t: null\n\tconst result = { source, config: configKey, template, tags, map }\n\n\tcollectCache.set(id, result)\n\n\treturn result\n}\n\n/**\n * Render the generated declaration file contents for a set of collected tags.\n */\nfunction renderTypes(tags: Tags) {\n\treturn [\n\t\tAUTOGEN_MSG,\n\t\t'',\n\t\t`import '${PKG_NAME}'`,\n\t\t'',\n\t\t`declare module '${PKG_NAME}' {`,\n\t\ttagsToType(tags),\n\t\t'}',\n\t\t'',\n\t].join('\\n')\n}\n\n/**\n * Write (or remove) the generated `index.d.ts` for a full tag surface.\n */\nasync function writeRenderedTypes(tags: Tags) {\n\tconst filePath = path.join(GENERATED_DIR, 'index.d.ts')\n\n\tif (!tags.size) {\n\t\t// `force` makes this a no-op when the file is already absent\n\t\tawait fs.rm(filePath, { force: true })\n\t\tfileCache.delete(filePath)\n\n\t\treturn\n\t}\n\n\tawait fs.mkdir(GENERATED_DIR, { recursive: true })\n\tawait maybeWrite(filePath, renderTypes(tags))\n}\n\n/**\n * Write the generated declaration file for the current set of collected tags.\n */\nexport function writeTypes(tags: Tags) {\n\treturn enqueueWrite(() => writeRenderedTypes(tags))\n}\n\nconst PARTIAL_DIR = path.join(GENERATED_DIR, 'tags')\n\nfunction partialPath(filePath: string) {\n\treturn path.join(\n\t\tPARTIAL_DIR,\n\t\t`${createHash('sha1').update(filePath).digest('hex')}.json`,\n\t)\n}\n\n/**\n * Read every per-file partial written by the Next loader workers and merge them into one tag map.\n * Partials whose source file no longer exists are pruned so deleted files drop out of the types.\n */\nasync function readPartials() {\n\tlet entries: string[]\n\n\ttry {\n\t\tentries = await fs.readdir(PARTIAL_DIR)\n\t} catch (err) {\n\t\tif (isENOENT(err)) return new Map()\n\t\tthrow err\n\t}\n\n\tconst tags: Tags = new Map()\n\n\tfor (const entry of entries) {\n\t\tif (!entry.endsWith('.json')) continue\n\n\t\tconst partial = path.join(PARTIAL_DIR, entry)\n\t\tlet parsed: { file: string; tags: Record<string, string[]> }\n\n\t\ttry {\n\t\t\tparsed = JSON.parse(await fs.readFile(partial, 'utf-8'))\n\t\t} catch {\n\t\t\tcontinue\n\t\t}\n\n\t\ttry {\n\t\t\tawait fs.access(parsed.file)\n\t\t} catch {\n\t\t\tawait fs.rm(partial, { force: true })\n\t\t\tcontinue\n\t\t}\n\n\t\tfor (const [name, classes] of Object.entries(parsed.tags)) {\n\t\t\tif (tags.has(name)) throw new DuplicateTagError(name)\n\t\t\ttags.set(name, classes)\n\t\t}\n\t}\n\n\treturn tags\n}\n\n/**\n * Next-specific write path. Turbopack spreads loaders across worker processes, so each worker\n * persists its own per-file partial and rebuilds the shared declaration file from all of them.\n */\nexport function writeTypesForFile(filePath: string, tags: Tags) {\n\treturn enqueueWrite(async () => {\n\t\tawait fs.mkdir(PARTIAL_DIR, { recursive: true })\n\n\t\tconst partial = partialPath(filePath)\n\n\t\tif (!tags.size) {\n\t\t\tawait fs.rm(partial, { force: true })\n\t\t} else {\n\t\t\tawait writeFileAtomic(\n\t\t\t\tpartial,\n\t\t\t\tJSON.stringify({ file: filePath, tags: Object.fromEntries(tags) }),\n\t\t\t)\n\t\t}\n\n\t\tawait writeRenderedTypes(await readPartials())\n\t})\n}\n\n/**\n * Render collected tags as a module augmentation for the package entrypoint.\n */\nexport function tagsToType(tags: Tags) {\n\treturn [...tags]\n\t\t.map(([tag, classes]) => {\n\t\t\tconst union =\n\t\t\t\tclasses.length > 0\n\t\t\t\t\t? classes\n\t\t\t\t\t\t\t.toSorted((a, b) => a.length - b.length)\n\t\t\t\t\t\t\t.map(c => `'${c}'`)\n\t\t\t\t\t\t\t.join(' | ')\n\t\t\t\t\t: 'never'\n\n\t\t\treturn `\\texport type ${tag} = ${union}`\n\t\t})\n\t\t.join('\\n')\n}\n\n/**\n * Merge per-file tag maps into one application-wide tag map.\n */\nexport function flattenTags(tagsByFile: BuildContext['tagsByFile']) {\n\tconst tags = new Map<string, string[]>()\n\n\tfor (const fileTags of tagsByFile.values()) {\n\t\tfor (const [name, classes] of fileTags) {\n\t\t\tif (tags.has(name)) throw new DuplicateTagError(name)\n\t\t\ttags.set(name, classes)\n\t\t}\n\t}\n\n\treturn tags\n}\n",
5
+ "import { createHash } from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport { transform } from 'lightningcss'\nimport MagicString, { type SourceMap } from 'magic-string'\n\nimport type { PluginConfig, Tags } from './types.js'\nimport { AUTOGEN_MSG, GENERATED_DIR, PKG_NAME } from './config.js'\nimport { LruCache } from './lru.js'\nimport { pascalise } from './utils.js'\n\n// decode bytes to a string, then stringify into a safe literal. `${bytes}` only\n// works by accident for Buffer; a plain Uint8Array stringifies as `97,123,125`\nconst decoder = new TextDecoder()\nconst encoder = new TextEncoder()\n\n/**\n * LRU cache of `collect` results by file id + last seen source + config so watcher and transform\n * can reuse the same parsed template/tags.\n */\nconst collectCache = new LruCache<{\n\tsource: string\n\tconfig: string\n\ttemplate: string\n\ttags: Tags\n\tmap: SourceMap | null\n}>()\n\n/**\n * Serialises type file writes inside a single process so overlapping writes can't interleave or\n * land out of order.\n */\nlet writeChain: Promise<void> = Promise.resolve()\n\n/**\n * Returns whether the error was caused by a missing file or directory.\n */\nexport function isENOENT(err: unknown) {\n\treturn err instanceof Error && 'code' in err && err.code === 'ENOENT'\n}\n\n/**\n * Write a file by writing to a unique temporary file and renaming it into place, so concurrent\n * writers never observe a partial file. The temp file is cleaned up if the rename fails.\n */\nasync function writeFileAtomic(filePath: string, content: string) {\n\tconst tmp = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`\n\n\tawait fs.writeFile(tmp, content)\n\n\ttry {\n\t\tawait fs.rename(tmp, filePath)\n\t} catch (err) {\n\t\tawait fs.rm(tmp, { force: true })\n\t\tthrow err\n\t}\n}\n\n/**\n * Run a write task after all previously queued writes have settled. A rejection doesn't break the\n * chain for later tasks.\n */\nfunction enqueueWrite<T>(task: () => Promise<T>) {\n\t// wait for the previous write to finish, then run this one, even if the previous one failed\n\tconst run = writeChain.then(task, task)\n\n\t// move the queue on to this write, but turn either outcome into success so it never rejects\n\twriteChain = run.then(\n\t\t() => undefined,\n\t\t() => undefined,\n\t)\n\n\t// return the real promise, so the caller still sees this write's value or error\n\treturn run\n}\n\n/**\n * Write a file only if the content differs from what is already on disk, so watchers are not woken\n * by a needless mtime change.\n */\nexport async function maybeWrite(filePath: string, content: string) {\n\ttry {\n\t\tif ((await fs.readFile(filePath, 'utf-8')) === content) return false\n\t} catch (err) {\n\t\tif (!isENOENT(err)) throw err\n\t}\n\n\tawait writeFileAtomic(filePath, content)\n\n\treturn true\n}\n\n// matches `[css, classes, href] = cxx\\`...\\`` and `cxx.tag<T>('name')\\`...\\``\n// capture groups: 1 optional `export `, 2-4 assigned variable names, 5 plain\n// css body, 6 quote kind, 7 tag name, 8 tagged css body\nconst regex =\n\t/((?:export\\s+)?)(?:const|var|let)\\s*\\[(\\w*)\\s*,?\\s*(\\w*)\\s*,?\\s*(\\w*)\\s*\\]\\s*=\\s*cxx(?:\\s*`([\\s\\S]*?)`|\\s*\\.\\s*tag(?:\\s*<[^>]+>)?\\s*\\(\\s*(['\"])(.*?)\\6\\s*\\)\\s*`([\\s\\S]*?)`)/gm\n\nconst IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\n/**\n * Hash transformed CSS into a stable href for style deduplication.\n */\nfunction hashCss(code: Uint8Array) {\n\treturn `cxx-${createHash('sha256').update(code).digest('base64url').slice(0, 12)}`\n}\n\nexport class DuplicateTagError extends Error {\n\tname = 'DuplicateTagError'\n\n\tconstructor(tag: string) {\n\t\tsuper(`Tag ${tag} has already been seen. Tags must be unique across your application`)\n\t}\n}\n\nexport class InvalidTagError extends Error {\n\tname = 'InvalidTagError'\n\n\tconstructor(tag: string) {\n\t\tsuper(\n\t\t\t`Tag \"${tag}\" does not map to a valid TypeScript identifier. ` +\n\t\t\t\t`Use letters, numbers, spaces, \"_\" or \"-\"`,\n\t\t)\n\t}\n}\n\n/**\n * Transform `cxx` templates in one source file and collect any exported tag types.\n */\nexport function collect(source: string, id: string, config: PluginConfig) {\n\tconst configKey = JSON.stringify(config)\n\n\t// reuse the last result when the source and config are unchanged\n\tconst cached = collectCache.get(id)\n\tif (cached?.source === source && cached.config === configKey) return cached\n\n\tconst tags: Tags = new Map()\n\tconst magic = new MagicString(source)\n\tlet matched = false\n\n\t// the regex is global, so reset its cursor before scanning\n\tregex.lastIndex = 0\n\n\tlet match: RegExpExecArray | null\n\n\t// walk every cxx template and replace it in place\n\twhile ((match = regex.exec(source))) {\n\t\tmatched = true\n\n\t\t// capture groups: export, three bindings, plain css, (quote), tag, tagged css\n\t\tconst [, exp, varOne, varTwo, varThree, plainCss, , tag, taggedCss] = match\n\t\tconst css = plainCss ?? taggedCss\n\t\tconst matchIndex = match.index\n\n\t\t// compile the CSS to minified CSS Modules, reporting the source line on failure\n\t\tconst { code, exports: classExports = {} } = (() => {\n\t\t\ttry {\n\t\t\t\treturn transform({\n\t\t\t\t\tminify: true,\n\t\t\t\t\tcssModules: true,\n\t\t\t\t\tfilename: id,\n\t\t\t\t\tcode: encoder.encode(css),\n\t\t\t\t})\n\t\t\t} catch (err) {\n\t\t\t\tconst line = source.slice(0, matchIndex).split('\\n').length\n\t\t\t\tthrow new Error(`Failed to compile cxx CSS at ${id}:${line}`, { cause: err })\n\t\t\t}\n\t\t})()\n\n\t\tconst href = hashCss(code)\n\t\t// map each class name to its generated (scoped) name\n\t\tconst styles = Object.fromEntries(\n\t\t\tObject.entries(classExports).map(([k, v]) => [k, v.name]),\n\t\t)\n\n\t\tif (tag) {\n\t\t\tconst suffix =\n\t\t\t\ttypeof config.typeSuffix === 'string'\n\t\t\t\t\t? config.typeSuffix\n\t\t\t\t\t: config.typeSuffix === false\n\t\t\t\t\t\t? ''\n\t\t\t\t\t\t: 'Classes'\n\t\t\tconst tagWithSuffix = pascalise(`${tag}${suffix}`)\n\n\t\t\tif (!IDENTIFIER.test(tagWithSuffix)) throw new InvalidTagError(tag)\n\t\t\tif (tags.has(tagWithSuffix)) throw new DuplicateTagError(tagWithSuffix)\n\n\t\t\t// side effect but necessary\n\t\t\ttags.set(tagWithSuffix, Object.keys(styles))\n\t\t}\n\n\t\tconst statements: string[] = []\n\n\t\tif (varOne) {\n\t\t\tstatements.push(`${exp}const ${varOne} = ${JSON.stringify(decoder.decode(code))}`)\n\t\t}\n\n\t\tif (varTwo) {\n\t\t\tstatements.push(`${exp}const ${varTwo} = ${JSON.stringify(styles)}`)\n\t\t}\n\n\t\tif (varThree) {\n\t\t\tstatements.push(`${exp}const ${varThree} = ${JSON.stringify(href)}`)\n\t\t}\n\n\t\t// swap the template for the generated declarations, keeping the export keyword\n\t\tmagic.overwrite(matchIndex, matchIndex + match[0].length, statements.join('\\n'))\n\t}\n\n\tconst template = magic.toString()\n\t// only build a map when something was actually rewritten\n\tconst map = matched\n\t\t? magic.generateMap({ source: id, includeContent: true, hires: true })\n\t\t: null\n\tconst result = { source, config: configKey, template, tags, map }\n\n\tcollectCache.set(id, result)\n\n\treturn result\n}\n\n/**\n * Render the generated declaration file contents for a set of collected tags.\n */\nfunction renderTypes(tags: Tags) {\n\treturn [\n\t\tAUTOGEN_MSG,\n\t\t'',\n\t\t`import '${PKG_NAME}'`,\n\t\t'',\n\t\t`declare module '${PKG_NAME}' {`,\n\t\ttagsToType(tags),\n\t\t'}',\n\t\t'',\n\t].join('\\n')\n}\n\n/**\n * Write (or remove) the generated `index.d.ts` for a full tag surface.\n */\nasync function writeRenderedTypes(tags: Tags) {\n\tconst filePath = path.join(GENERATED_DIR, 'index.d.ts')\n\n\tif (!tags.size) {\n\t\tawait fs.rm(filePath, { force: true })\n\t\treturn\n\t}\n\n\tawait fs.mkdir(GENERATED_DIR, { recursive: true })\n\tawait maybeWrite(filePath, renderTypes(tags))\n}\n\nconst PARTIAL_DIR = path.join(GENERATED_DIR, 'tags')\n\n// wait this long after the last file before rebuilding, so a burst of files\n// only re-reads the partials once\nconst REBUILD_WAIT = 100\n\nlet rebuildTimer: ReturnType<typeof setTimeout> | null = null\nlet rebuildError: unknown = null\n\nfunction partialPath(filePath: string) {\n\treturn path.join(\n\t\tPARTIAL_DIR,\n\t\t`${createHash('sha1').update(filePath).digest('hex')}.json`,\n\t)\n}\n\n/**\n * The partial directory changes whenever any process adds, removes or overwrites a partial, so\n * its mtime tells us whether another writer moved while we were rebuilding.\n */\nasync function partialDirMtime() {\n\ttry {\n\t\treturn (await fs.stat(PARTIAL_DIR)).mtimeMs\n\t} catch (err) {\n\t\tif (isENOENT(err)) return 0\n\t\tthrow err\n\t}\n}\n\n/**\n * Read every per-file partial and merge them into one tag map. Partials whose source file no\n * longer exists are pruned so deleted files drop out of the types.\n */\nasync function readPartials() {\n\tlet entries: string[]\n\n\ttry {\n\t\tentries = await fs.readdir(PARTIAL_DIR)\n\t} catch (err) {\n\t\tif (isENOENT(err)) return new Map()\n\t\tthrow err\n\t}\n\n\tconst tags: Tags = new Map()\n\n\tfor (const entry of entries) {\n\t\tif (!entry.endsWith('.json')) continue\n\n\t\tconst partial = path.join(PARTIAL_DIR, entry)\n\t\tlet parsed: { file: string; tags: Record<string, string[]> }\n\n\t\ttry {\n\t\t\tparsed = JSON.parse(await fs.readFile(partial, 'utf-8'))\n\t\t} catch {\n\t\t\tcontinue\n\t\t}\n\n\t\ttry {\n\t\t\tawait fs.access(parsed.file)\n\t\t} catch {\n\t\t\tawait fs.rm(partial, { force: true })\n\t\t\tcontinue\n\t\t}\n\n\t\tfor (const [name, classes] of Object.entries(parsed.tags)) {\n\t\t\tif (tags.has(name)) throw new DuplicateTagError(name)\n\t\t\ttags.set(name, classes)\n\t\t}\n\t}\n\n\treturn tags\n}\n\n/**\n * Persist one file's tags to its own partial, then rebuild the shared types soon. Rebuilding is\n * debounced and serialised, so a large build does not re-read every partial per file.\n */\nexport function writeTypesForFile(filePath: string, tags: Tags) {\n\treturn enqueueWrite(async () => {\n\t\tawait fs.mkdir(PARTIAL_DIR, { recursive: true })\n\n\t\tconst partial = partialPath(filePath)\n\n\t\tif (!tags.size) {\n\t\t\tawait fs.rm(partial, { force: true })\n\t\t} else {\n\t\t\tawait writeFileAtomic(\n\t\t\t\tpartial,\n\t\t\t\tJSON.stringify({ file: filePath, tags: Object.fromEntries(tags) }),\n\t\t\t)\n\t\t}\n\t}).then(() => {\n\t\tscheduleRebuild()\n\t})\n}\n\nfunction scheduleRebuild() {\n\tif (rebuildTimer) clearTimeout(rebuildTimer)\n\n\trebuildTimer = setTimeout(() => {\n\t\trebuildTimer = null\n\t\tflushTypes().catch(err => {\n\t\t\trebuildError = err\n\t\t})\n\t}, REBUILD_WAIT)\n}\n\n/**\n * Rebuild `index.d.ts` from every partial now. If another writer touches a partial mid-rebuild,\n * rebuild once more so the final write reflects every partial. Bounded to avoid spinning.\n */\nexport function flushTypes() {\n\tif (rebuildTimer) {\n\t\tclearTimeout(rebuildTimer)\n\t\trebuildTimer = null\n\t}\n\n\treturn enqueueWrite(async () => {\n\t\tlet before = await partialDirMtime()\n\n\t\tfor (let attempt = 0; attempt < 3; attempt++) {\n\t\t\tawait writeRenderedTypes(await readPartials())\n\n\t\t\tconst after = await partialDirMtime()\n\t\t\tif (after === before) return\n\n\t\t\tbefore = after\n\t\t}\n\t})\n}\n\n/**\n * Return and clear any error from a background rebuild, so a caller can fail loudly.\n */\nexport function takeRebuildError() {\n\tconst err = rebuildError\n\trebuildError = null\n\treturn err\n}\n\n/**\n * Render collected tags as a module augmentation for the package entrypoint.\n */\nexport function tagsToType(tags: Tags) {\n\treturn [...tags]\n\t\t.toSorted(([a], [b]) => a.localeCompare(b))\n\t\t.map(([tag, classes]) => {\n\t\t\tconst union =\n\t\t\t\tclasses.length > 0\n\t\t\t\t\t? classes\n\t\t\t\t\t\t\t.toSorted((a, b) => a.length - b.length)\n\t\t\t\t\t\t\t.map(c => `'${c}'`)\n\t\t\t\t\t\t\t.join(' | ')\n\t\t\t\t\t: 'never'\n\n\t\t\treturn `\\texport type ${tag} = ${union}`\n\t\t})\n\t\t.join('\\n')\n}\n",
6
6
  "export const NAME = 'cxx'\nexport const PKG_NAME = `@jk2908/${NAME}`\nexport const GENERATED_DIR = `.${NAME}`\nexport const AUTOGEN_MSG = `// auto-generated by ${NAME}`\n",
7
7
  "export const CACHE_MAX_SIZE = 100\n\nexport class LruCache<T> {\n\t#cache: Map<string, T> = new Map()\n\t#maxSize: number\n\n\tconstructor(maxSize = CACHE_MAX_SIZE) {\n\t\tthis.#maxSize = maxSize\n\t}\n\n\tget size() {\n\t\treturn this.#cache.size\n\t}\n\n\t/**\n\t * Retrieve a cached value and promote it to most-recently-used so it won't\n\t * be evicted while still actively referenced.\n\t */\n\tget(key: string) {\n\t\tconst cached = this.#cache.get(key)\n\t\tif (this.#cache.has(key)) this.set(key, cached as T)\n\n\t\treturn cached\n\t}\n\n\t/**\n\t * Promote an existing cache entry to most-recently-used by deleting and\n\t * re-inserting it, which moves it to the end of the Map's iteration\n\t * order. If the cache is at capacity, evict the least recently used\n\t * entry (front) before inserting.\n\t */\n\tset(key: string, value: T) {\n\t\t// drop any existing entry\n\t\tthis.#cache.delete(key)\n\n\t\tif (this.#cache.size >= this.#maxSize) {\n\t\t\tconst lru = this.#cache.keys().next().value\n\t\t\tif (lru !== undefined) this.#cache.delete(lru)\n\t\t}\n\n\t\tthis.#cache.set(key, value)\n\t}\n\n\tdelete(key: string) {\n\t\treturn this.#cache.delete(key)\n\t}\n\n\tclear() {\n\t\treturn this.#cache.clear()\n\t}\n}\n",
8
- "export function capitalise(str: string) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport function pascalise(str: string) {\n\treturn str\n\t\t.split(/[ _-]+/)\n\t\t.map(capitalise)\n\t\t.join('')\n}\n\nexport type Batcher<K, V> = {\n\t/**\n\t * Queue a value for a key. Queueing the same key again replaces the previous value.\n\t */\n\tadd: (key: K, value: V) => void\n\t/**\n\t * Run any waiting work now and resolve once it has finished.\n\t */\n\tflush: () => Promise<void>\n}\n\n/**\n * Group bursts of work and run them together. Every key queued within `wait` is\n * included once, and a key queued while a batch is running is handled in the next\n * batch instead of replacing the one in progress.\n */\nexport function createBatcher<K, V>(\n\twait: number,\n\tflush: (batch: Map<K, V>) => void | Promise<void>,\n): Batcher<K, V> {\n\t// work waiting to run, keyed so each key is only queued once\n\tconst pending = new Map<K, V>()\n\t// waits for a burst of changes to settle before running\n\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t// true while a batch is running, so we never start a second one\n\tlet running = false\n\n\tasync function drain() {\n\t\t// a run is already going, so let it pick up the new work\n\t\tif (running) return\n\t\trunning = true\n\n\t\ttry {\n\t\t\t// keep looping while there is work, including work added during a flush\n\t\t\twhile (pending.size > 0) {\n\t\t\t\t// snapshot the queued work\n\t\t\t\tconst batch = new Map(pending)\n\t\t\t\t// empty the queue right away, so anything added during flush waits for the next loop\n\t\t\t\tpending.clear()\n\n\t\t\t\tawait flush(batch)\n\t\t\t}\n\t\t} finally {\n\t\t\t// always allow the next run, even if flush threw\n\t\t\trunning = false\n\t\t}\n\t}\n\n\tfunction schedule() {\n\t\t// cancel the previous wait, so the timer restarts from now\n\t\tif (timer) clearTimeout(timer)\n\n\t\t// run once the calls stop coming for `wait` ms\n\t\ttimer = setTimeout(() => {\n\t\t\t// the timer has fired, so drop the stale handle\n\t\t\ttimer = null\n\t\t\t// start the run without waiting for it (this is a timer callback)\n\t\t\tvoid drain()\n\t\t}, wait)\n\t}\n\n\treturn {\n\t\tadd(key, value) {\n\t\t\t// the newest value for this key wins\n\t\t\tpending.set(key, value)\n\t\t\tschedule()\n\t\t},\n\t\tflush() {\n\t\t\t// run now instead of waiting out the timer\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer)\n\t\t\t\ttimer = null\n\t\t\t}\n\n\t\t\treturn drain()\n\t\t},\n\t}\n}\n",
9
- "import type { AsyncSubscription, Event } from '@parcel/watcher'\nimport type { NextConfig } from 'next'\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { Logger } from '../logger.js'\nimport type { PluginConfig } from '../types.js'\nimport { collect, isENOENT, writeTypesForFile } from '../build.js'\nimport { GENERATED_DIR } from '../config.js'\n\nconst nextDir = path.dirname(fileURLToPath(import.meta.url))\nconst loader = path.join(nextDir, 'cxx-loader.cjs')\n\n// keep the exact file inputs and their config so a single recursive watcher can filter events\nconst watchedFiles = new Map<string, { pluginConfig: PluginConfig; logger: Logger }>()\n\nlet subscription: AsyncSubscription | null = null\nlet subscriptionPromise: Promise<void> | null = null\nlet cleanupRegistered = false\nlet watcherLogger: Logger | null = null\n\n// a single recursive watch avoids overlapping per-directory watchers; ignore the parts of the\n// tree that never contain source we transform\nconst DEFAULT_IGNORE = [\n\t'**/node_modules/**',\n\t'**/.next/**',\n\t`**/${GENERATED_DIR}/**`,\n\t'**/.git/**',\n]\n\nasync function onEvent(event: Event['type'], filePath: string) {\n\tconst watched = watchedFiles.get(filePath)\n\tif (!watched) return\n\n\tconst { pluginConfig, logger } = watched\n\n\tif (event === 'delete') {\n\t\tawait writeTypesForFile(filePath, new Map())\n\t\tlogger.info(`updated types from ${filePath}`)\n\n\t\treturn\n\t}\n\n\tlet source: string\n\n\ttry {\n\t\tsource = await fs.readFile(filePath, 'utf-8')\n\t} catch (err) {\n\t\tif (!isENOENT(err)) throw err\n\n\t\tawait writeTypesForFile(filePath, new Map())\n\t\tlogger.info(`updated types from ${filePath}`)\n\n\t\treturn\n\t}\n\n\tconst { tags } = collect(source, filePath, pluginConfig)\n\n\tawait writeTypesForFile(filePath, tags)\n\tlogger.info(`updated types from ${filePath}`)\n}\n\n/**\n * Start the watcher lazily, on the first file we actually process, so merely importing this module\n * has no side effects.\n */\nfunction ensureWatcher(pluginConfig: PluginConfig, logger: Logger) {\n\twatcherLogger = logger\n\n\tif (subscriptionPromise) return\n\n\tconst root = pluginConfig.watch?.root ?? process.cwd()\n\tconst ignore = [...DEFAULT_IGNORE, ...(pluginConfig.watch?.ignore ?? [])]\n\n\tsubscriptionPromise = (async () => {\n\t\t// lazily imported so the native module is only loaded when watching is needed\n\t\tconst { subscribe } = await import('@parcel/watcher')\n\n\t\tsubscription = await subscribe(\n\t\t\troot,\n\t\t\t(watchErr, events) => {\n\t\t\t\tif (watchErr) {\n\t\t\t\t\twatcherLogger?.error(`failed to watch ${root}`, watchErr)\n\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tfor (const event of events) {\n\t\t\t\t\tconst filePath = path.resolve(event.path)\n\t\t\t\t\tif (!watchedFiles.has(filePath)) continue\n\n\t\t\t\t\tvoid onEvent(event.type, filePath).catch(err => {\n\t\t\t\t\t\twatcherLogger?.error(`failed to update types from ${filePath}`, err)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ ignore },\n\t\t)\n\n\t\tregisterCleanup()\n\t})().catch(err => {\n\t\twatcherLogger?.error('failed to start cxx watcher', err)\n\t\tsubscriptionPromise = null\n\t})\n}\n\n/**\n * Close all active Parcel subscriptions.\n */\nasync function cleanup() {\n\tconst active = subscription\n\n\tsubscription = null\n\tsubscriptionPromise = null\n\twatchedFiles.clear()\n\n\tif (active) await active.unsubscribe()\n}\n\n/**\n * Restore the host process's default signal behaviour instead of forcing an exit from a library.\n */\nasync function shutdown(signal: NodeJS.Signals) {\n\ttry {\n\t\tawait cleanup()\n\t} finally {\n\t\t// our `once` handlers have already been removed, so re-raising lets Node terminate as usual\n\t\tprocess.kill(process.pid, signal)\n\t}\n}\n\nfunction registerCleanup() {\n\tif (cleanupRegistered) return\n\n\tcleanupRegistered = true\n\tprocess.once('SIGINT', () => void shutdown('SIGINT'))\n\tprocess.once('SIGTERM', () => void shutdown('SIGTERM'))\n}\n\n/**\n * Transform one module and, in development, register it with the shared watcher state.\n */\nexport function processFile(\n\tsource: string,\n\tfilePath: string,\n\tpluginConfig: PluginConfig,\n\tlogger: Logger,\n) {\n\tconst resolvedFilePath = path.resolve(filePath)\n\n\tif (process.env['NODE_ENV'] !== 'production') {\n\t\twatchedFiles.set(resolvedFilePath, { pluginConfig, logger })\n\t\tensureWatcher(pluginConfig, logger)\n\t}\n\n\tconst result = collect(source, resolvedFilePath, pluginConfig)\n\n\tvoid writeTypesForFile(resolvedFilePath, result.tags).catch(err => {\n\t\tlogger.error(`failed to write types for ${resolvedFilePath}`, err)\n\t})\n\n\treturn result\n}\n\nconst TURBOPACK_GLOB = '*.{tsx,jsx,ts,js}'\n\nexport function withCxx(nextConfig: NextConfig = {}, pluginConfig: PluginConfig = {}) {\n\tconst watchRoot =\n\t\tpluginConfig.watch?.root ?? nextConfig.turbopack?.root ?? process.cwd()\n\n\tconst loaderItem = {\n\t\tloader,\n\t\toptions: {\n\t\t\tpluginConfig: {\n\t\t\t\t...pluginConfig,\n\t\t\t\twatch: { ...pluginConfig.watch, root: watchRoot },\n\t\t\t},\n\t\t},\n\t}\n\n\tconst currentRule = nextConfig.turbopack?.rules?.[TURBOPACK_GLOB]\n\tconst userWebpack = nextConfig.webpack\n\n\treturn {\n\t\t...nextConfig,\n\t\tturbopack: {\n\t\t\t...nextConfig.turbopack,\n\t\t\trules: {\n\t\t\t\t...nextConfig.turbopack?.rules,\n\t\t\t\t[TURBOPACK_GLOB]: Array.isArray(currentRule)\n\t\t\t\t\t? [...currentRule, loaderItem]\n\t\t\t\t\t: currentRule\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...currentRule,\n\t\t\t\t\t\t\t\tloaders: [...(currentRule.loaders ?? []), loaderItem],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { loaders: [loaderItem] },\n\t\t\t},\n\t\t},\n\t\t// webpack builds (Next without `--turbopack`) would otherwise silently skip the transform\n\t\twebpack(config: unknown, context: unknown) {\n\t\t\tconst next = (\n\t\t\t\tuserWebpack ? userWebpack(config as never, context as never) : config\n\t\t\t) as {\n\t\t\t\tmodule?: { rules?: unknown[] }\n\t\t\t}\n\n\t\t\tnext.module ??= {}\n\t\t\tnext.module.rules ??= []\n\t\t\tnext.module.rules.push({\n\t\t\t\ttest: /\\.[jt]sx?$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\tenforce: 'pre',\n\t\t\t\tuse: [loaderItem],\n\t\t\t})\n\n\t\t\treturn next\n\t\t},\n\t}\n}\n"
8
+ "export function capitalise(str: string) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport function pascalise(str: string) {\n\treturn str\n\t\t.split(/[ _-]+/)\n\t\t.map(capitalise)\n\t\t.join('')\n}\n\nexport type Batcher<K, V> = {\n\t/**\n\t * Queue a value for a key. Queueing the same key again replaces the previous value.\n\t */\n\tadd: (key: K, value: V) => void\n\t/**\n\t * Run any waiting work now and resolve once it has finished.\n\t */\n\tflush: () => Promise<void>\n}\n\n/**\n * Group bursts of work and run them together. Every key queued within `wait` is\n * included once, and a key queued while a batch is running is handled in the next\n * batch instead of replacing the one in progress.\n */\nexport function createBatcher<K, V>(\n\twait: number,\n\tflush: (batch: Map<K, V>) => void | Promise<void>,\n): Batcher<K, V> {\n\t// work waiting to run, keyed so each key is only queued once\n\tconst pending = new Map<K, V>()\n\t// waits for a burst of changes to settle before running\n\tlet timer: ReturnType<typeof setTimeout> | null = null\n\t// the run in progress, so `flush` can wait for it and we never start a second\n\tlet current: Promise<void> | null = null\n\n\tfunction drain() {\n\t\t// a run is already going, so let it pick up the new work\n\t\tif (current) return current\n\n\t\tconst run = (async () => {\n\t\t\t// keep looping while there is work, including work added during a flush\n\t\t\twhile (pending.size > 0) {\n\t\t\t\t// snapshot the queued work\n\t\t\t\tconst batch = new Map(pending)\n\t\t\t\t// empty the queue right away, so anything added during flush waits for the next loop\n\t\t\t\tpending.clear()\n\n\t\t\t\tawait flush(batch)\n\t\t\t}\n\t\t})()\n\n\t\tcurrent = run\n\t\trun.then(\n\t\t\t() => {\n\t\t\t\tif (current === run) current = null\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (current === run) current = null\n\t\t\t},\n\t\t)\n\n\t\treturn run\n\t}\n\n\tfunction schedule() {\n\t\t// cancel the previous wait, so the timer restarts from now\n\t\tif (timer) clearTimeout(timer)\n\n\t\t// run once the calls stop coming for `wait` ms\n\t\ttimer = setTimeout(() => {\n\t\t\t// the timer has fired, so drop the stale handle\n\t\t\ttimer = null\n\t\t\t// the flush callback handles its own errors, so just start the run\n\t\t\tvoid drain().catch(() => {})\n\t\t}, wait)\n\t}\n\n\treturn {\n\t\tadd(key, value) {\n\t\t\t// the newest value for this key wins\n\t\t\tpending.set(key, value)\n\t\t\tschedule()\n\t\t},\n\t\tflush() {\n\t\t\t// run now instead of waiting out the timer\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer)\n\t\t\t\ttimer = null\n\t\t\t}\n\n\t\t\treturn drain()\n\t\t},\n\t}\n}\n",
9
+ "import type { AsyncSubscription, Event } from '@parcel/watcher'\nimport type { NextConfig } from 'next'\n\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nimport type { Logger } from '../logger.js'\nimport type { PluginConfig } from '../types.js'\nimport { collect, isENOENT, takeRebuildError, writeTypesForFile } from '../build.js'\nimport { GENERATED_DIR } from '../config.js'\n\nconst nextDir = path.dirname(fileURLToPath(import.meta.url))\nconst loader = path.join(nextDir, 'cxx-loader.cjs')\n\n// keep the exact file inputs and their config so a single recursive watcher can filter events\nconst watchedFiles = new Map<string, { pluginConfig: PluginConfig; logger: Logger }>()\n\nlet subscription: AsyncSubscription | null = null\nlet subscriptionPromise: Promise<void> | null = null\nlet cleanupRegistered = false\nlet watcherLogger: Logger | null = null\n\n// a single recursive watch avoids overlapping per-directory watchers; ignore the parts of the\n// tree that never contain source we transform\nconst DEFAULT_IGNORE = [\n\t'**/node_modules/**',\n\t'**/.next/**',\n\t`**/${GENERATED_DIR}/**`,\n\t'**/.git/**',\n]\n\nasync function onEvent(event: Event['type'], filePath: string) {\n\tconst watched = watchedFiles.get(filePath)\n\tif (!watched) return\n\n\tconst { pluginConfig, logger } = watched\n\n\tif (event === 'delete') {\n\t\tawait writeTypesForFile(filePath, new Map())\n\t\tlogger.info(`updated types from ${filePath}`)\n\n\t\treturn\n\t}\n\n\tlet source: string\n\n\ttry {\n\t\tsource = await fs.readFile(filePath, 'utf-8')\n\t} catch (err) {\n\t\tif (!isENOENT(err)) throw err\n\n\t\tawait writeTypesForFile(filePath, new Map())\n\t\tlogger.info(`updated types from ${filePath}`)\n\n\t\treturn\n\t}\n\n\tconst tags = source.includes('cxx')\n\t\t? collect(source, filePath, pluginConfig).tags\n\t\t: new Map()\n\n\tawait writeTypesForFile(filePath, tags)\n\tlogger.info(`updated types from ${filePath}`)\n}\n\n/**\n * Start the watcher lazily, on the first file we actually process, so merely importing this module\n * has no side effects.\n */\nfunction ensureWatcher(pluginConfig: PluginConfig, logger: Logger) {\n\twatcherLogger = logger\n\n\tif (subscriptionPromise) return\n\n\tconst root = pluginConfig.watch?.root ?? process.cwd()\n\tconst ignore = [...DEFAULT_IGNORE, ...(pluginConfig.watch?.ignore ?? [])]\n\n\tsubscriptionPromise = (async () => {\n\t\t// lazily imported so the native module is only loaded when watching is needed\n\t\tconst { subscribe } = await import('@parcel/watcher')\n\n\t\tsubscription = await subscribe(\n\t\t\troot,\n\t\t\t(watchErr, events) => {\n\t\t\t\tif (watchErr) {\n\t\t\t\t\twatcherLogger?.error(`failed to watch ${root}`, watchErr)\n\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tfor (const event of events) {\n\t\t\t\t\tconst filePath = path.resolve(event.path)\n\t\t\t\t\tif (!watchedFiles.has(filePath)) continue\n\n\t\t\t\t\tvoid onEvent(event.type, filePath).catch(err => {\n\t\t\t\t\t\twatcherLogger?.error(`failed to update types from ${filePath}`, err)\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ ignore },\n\t\t)\n\n\t\tregisterCleanup()\n\t})().catch(err => {\n\t\twatcherLogger?.error('failed to start cxx watcher', err)\n\t\tsubscriptionPromise = null\n\t})\n}\n\n/**\n * Close all active Parcel subscriptions.\n */\nasync function cleanup() {\n\tconst active = subscription\n\n\tsubscription = null\n\tsubscriptionPromise = null\n\twatchedFiles.clear()\n\n\tif (active) await active.unsubscribe()\n}\n\n/**\n * Restore the host process's default signal behaviour instead of forcing an exit from a library.\n */\nasync function shutdown(signal: NodeJS.Signals) {\n\ttry {\n\t\tawait cleanup()\n\t} finally {\n\t\t// our `once` handlers have already been removed, so re-raising lets Node terminate as usual\n\t\tprocess.kill(process.pid, signal)\n\t}\n}\n\nfunction registerCleanup() {\n\tif (cleanupRegistered) return\n\n\tcleanupRegistered = true\n\tprocess.once('SIGINT', () => void shutdown('SIGINT'))\n\tprocess.once('SIGTERM', () => void shutdown('SIGTERM'))\n}\n\n/**\n * Transform one module and, in development, register it with the shared watcher state.\n */\nexport function processFile(\n\tsource: string,\n\tfilePath: string,\n\tpluginConfig: PluginConfig,\n\tlogger: Logger,\n) {\n\tconst resolvedFilePath = path.resolve(filePath)\n\n\t// skip files that cannot contain a template, including node_modules\n\tif (!source.includes('cxx') || /[\\\\/]node_modules[\\\\/]/.test(resolvedFilePath)) {\n\t\treturn { template: source, tags: new Map(), map: null }\n\t}\n\n\t// surface a duplicate-tag error from a previous background rebuild\n\tconst priorError = takeRebuildError()\n\tif (priorError) throw priorError\n\n\tif (process.env['NODE_ENV'] !== 'production') {\n\t\twatchedFiles.set(resolvedFilePath, { pluginConfig, logger })\n\t\tensureWatcher(pluginConfig, logger)\n\t}\n\n\tconst result = collect(source, resolvedFilePath, pluginConfig)\n\n\tvoid writeTypesForFile(resolvedFilePath, result.tags)\n\n\treturn result\n}\n\nconst TURBOPACK_GLOB = '*.{tsx,jsx,ts,js}'\n\nexport function withCxx(nextConfig: NextConfig = {}, pluginConfig: PluginConfig = {}) {\n\tconst watchRoot =\n\t\tpluginConfig.watch?.root ?? nextConfig.turbopack?.root ?? process.cwd()\n\n\tconst loaderItem = {\n\t\tloader,\n\t\toptions: {\n\t\t\tpluginConfig: {\n\t\t\t\t...pluginConfig,\n\t\t\t\twatch: { ...pluginConfig.watch, root: watchRoot },\n\t\t\t},\n\t\t},\n\t}\n\n\tconst currentRule = nextConfig.turbopack?.rules?.[TURBOPACK_GLOB]\n\tconst userWebpack = nextConfig.webpack\n\n\treturn {\n\t\t...nextConfig,\n\t\tturbopack: {\n\t\t\t...nextConfig.turbopack,\n\t\t\trules: {\n\t\t\t\t...nextConfig.turbopack?.rules,\n\t\t\t\t[TURBOPACK_GLOB]: Array.isArray(currentRule)\n\t\t\t\t\t? [...currentRule, loaderItem]\n\t\t\t\t\t: currentRule\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...currentRule,\n\t\t\t\t\t\t\t\tloaders: [...(currentRule.loaders ?? []), loaderItem],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { loaders: [loaderItem] },\n\t\t\t},\n\t\t},\n\t\t// webpack builds (Next without `--turbopack`) would otherwise silently skip the transform\n\t\twebpack(config: unknown, context: unknown) {\n\t\t\tconst next = (\n\t\t\t\tuserWebpack ? userWebpack(config as never, context as never) : config\n\t\t\t) as {\n\t\t\t\tmodule?: { rules?: unknown[] }\n\t\t\t}\n\n\t\t\tnext.module ??= {}\n\t\t\tnext.module.rules ??= []\n\t\t\tnext.module.rules.push({\n\t\t\t\ttest: /\\.[jt]sx?$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\tenforce: 'pre',\n\t\t\t\tuse: [loaderItem],\n\t\t\t})\n\n\t\t\treturn next\n\t\t},\n\t}\n}\n"
10
10
  ],
11
- "mappings": "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",
12
- "debugId": "A4FD970DD20B088B64756E2164756E21",
11
+ "mappings": "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",
12
+ "debugId": "89C0BE13A5C5F77E64756E2164756E21",
13
13
  "names": []
14
14
  }
package/dist/types.d.ts CHANGED
@@ -7,13 +7,12 @@ export type Tags = Map<string, string[]>;
7
7
  export type PluginConfig = {
8
8
  typeSuffix?: string | false;
9
9
  watch?: {
10
+ /** Root used for type-regeneration watching. Defaults to the Vite root or Next Turbopack root. */
10
11
  root?: string;
12
+ /** Extra globs to ignore on top of the defaults. */
11
13
  ignore?: string[];
12
14
  };
13
15
  };
14
- export type BuildContext = {
15
- tagsByFile: Map<string, Tags>;
16
- };
17
16
  export type Tag = <ClassName extends string = string>(name: string) => (_: TemplateStringsArray) => Result<ClassName>;
18
17
  export type Cxx = ((_: TemplateStringsArray) => Result) & {
19
18
  tag: Tag;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,IAAI,SAAS;IAChE,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM;CACZ,CAAA;AAED,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAExC,MAAM,MAAM,YAAY,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC3B,KAAK,CAAC,EAAE;QAEP,IAAI,CAAC,EAAE,MAAM,CAAA;QAEb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KACjB,CAAA;CACD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IAC1B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;CAC7B,CAAA;AAED,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EACnD,IAAI,EAAE,MAAM,KACR,CAAC,CAAC,EAAE,oBAAoB,KAAK,MAAM,CAAC,SAAS,CAAC,CAAA;AAEnD,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,oBAAoB,KAAK,MAAM,CAAC,GAAG;IACzD,GAAG,EAAE,GAAG,CAAA;CACR,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,IAAI,SAAS;IAChE,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,EAAE,MAAM;CACZ,CAAA;AAED,MAAM,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAExC,MAAM,MAAM,YAAY,GAAG;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC3B,KAAK,CAAC,EAAE;QACP,kGAAkG;QAClG,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,oDAAoD;QACpD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KACjB,CAAA;CACD,CAAA;AAED,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,EACnD,IAAI,EAAE,MAAM,KACR,CAAC,CAAC,EAAE,oBAAoB,KAAK,MAAM,CAAC,SAAS,CAAC,CAAA;AAEnD,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,oBAAoB,KAAK,MAAM,CAAC,GAAG;IACzD,GAAG,EAAE,GAAG,CAAA;CACR,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,UAKpC;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI;IAC3B;;OAEG;IACH,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;IAC/B;;OAEG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC/C,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CA0Df"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,UAKpC;AAED,MAAM,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI;IAC3B;;OAEG;IACH,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAA;IAC/B;;OAEG;IACH,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC/C,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAkEf"}
@@ -3,13 +3,6 @@ import type { PluginConfig } from '../types.js';
3
3
  export default function cxx(pluginConfig?: PluginConfig): {
4
4
  name: string;
5
5
  enforce: "pre";
6
- config(this: import("vite").ConfigPluginContext): {
7
- server: {
8
- watch: {
9
- ignored: string[];
10
- };
11
- };
12
- } | null;
13
6
  configResolved(this: import("vite").MinimalPluginContextWithoutEnvironment, config: ResolvedConfig): void;
14
7
  transform(this: import("rolldown").TransformPluginContext, code: string, id: string): {
15
8
  code: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAA;AAE3E,OAAO,KAAK,EAAgB,YAAY,EAAE,MAAM,aAAa,CAAA;AAc7D,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,YAAY,GAAE,YAAiB;;;;;;;;;;wFAgHlC,cAAc;;;;;yFAiCb,aAAa;;EAqBtC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,MAAM,CAAA;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA+B/C,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,YAAY,GAAE,YAAiB;;;wFA+GlC,cAAc;;;;;yFA8Bb,aAAa;;EA6BtC"}
@@ -59,27 +59,33 @@ function pascalise(str) {
59
59
  function createBatcher(wait, flush) {
60
60
  const pending = new Map;
61
61
  let timer = null;
62
- let running = false;
63
- async function drain() {
64
- if (running)
65
- return;
66
- running = true;
67
- try {
62
+ let current = null;
63
+ function drain() {
64
+ if (current)
65
+ return current;
66
+ const run = (async () => {
68
67
  while (pending.size > 0) {
69
68
  const batch = new Map(pending);
70
69
  pending.clear();
71
70
  await flush(batch);
72
71
  }
73
- } finally {
74
- running = false;
75
- }
72
+ })();
73
+ current = run;
74
+ run.then(() => {
75
+ if (current === run)
76
+ current = null;
77
+ }, () => {
78
+ if (current === run)
79
+ current = null;
80
+ });
81
+ return run;
76
82
  }
77
83
  function schedule() {
78
84
  if (timer)
79
85
  clearTimeout(timer);
80
86
  timer = setTimeout(() => {
81
87
  timer = null;
82
- drain();
88
+ drain().catch(() => {});
83
89
  }, wait);
84
90
  }
85
91
  return {
@@ -99,8 +105,8 @@ function createBatcher(wait, flush) {
99
105
 
100
106
  // src/build.ts
101
107
  var decoder = new TextDecoder;
108
+ var encoder = new TextEncoder;
102
109
  var collectCache = new LruCache;
103
- var fileCache = new LruCache;
104
110
  var writeChain = Promise.resolve();
105
111
  function isENOENT(err) {
106
112
  return err instanceof Error && "code" in err && err.code === "ENOENT";
@@ -108,7 +114,12 @@ function isENOENT(err) {
108
114
  async function writeFileAtomic(filePath, content) {
109
115
  const tmp = `${filePath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
110
116
  await fs.writeFile(tmp, content);
111
- await fs.rename(tmp, filePath);
117
+ try {
118
+ await fs.rename(tmp, filePath);
119
+ } catch (err) {
120
+ await fs.rm(tmp, { force: true });
121
+ throw err;
122
+ }
112
123
  }
113
124
  function enqueueWrite(task) {
114
125
  const run = writeChain.then(task, task);
@@ -120,20 +131,14 @@ function enqueueWrite(task) {
120
131
  return run;
121
132
  }
122
133
  async function maybeWrite(filePath, content) {
123
- const cached = fileCache.get(filePath);
124
- if (cached === content)
125
- return false;
126
134
  try {
127
- if (await fs.readFile(filePath, "utf-8") === content) {
128
- fileCache.set(filePath, content);
135
+ if (await fs.readFile(filePath, "utf-8") === content)
129
136
  return false;
130
- }
131
137
  } catch (err) {
132
138
  if (!isENOENT(err))
133
139
  throw err;
134
140
  }
135
141
  await writeFileAtomic(filePath, content);
136
- fileCache.set(filePath, content);
137
142
  return true;
138
143
  }
139
144
  var regex = /((?:export\s+)?)(?:const|var|let)\s*\[(\w*)\s*,?\s*(\w*)\s*,?\s*(\w*)\s*\]\s*=\s*cxx(?:\s*`([\s\S]*?)`|\s*\.\s*tag(?:\s*<[^>]+>)?\s*\(\s*(['"])(.*?)\6\s*\)\s*`([\s\S]*?)`)/gm;
@@ -169,14 +174,23 @@ function collect(source, id, config) {
169
174
  matched = true;
170
175
  const [, exp, varOne, varTwo, varThree, plainCss, , tag, taggedCss] = match;
171
176
  const css = plainCss ?? taggedCss;
172
- const { code, exports = {} } = transform({
173
- minify: true,
174
- cssModules: true,
175
- filename: id,
176
- code: new TextEncoder().encode(css)
177
- });
177
+ const matchIndex = match.index;
178
+ const { code, exports: classExports = {} } = (() => {
179
+ try {
180
+ return transform({
181
+ minify: true,
182
+ cssModules: true,
183
+ filename: id,
184
+ code: encoder.encode(css)
185
+ });
186
+ } catch (err) {
187
+ const line = source.slice(0, matchIndex).split(`
188
+ `).length;
189
+ throw new Error(`Failed to compile cxx CSS at ${id}:${line}`, { cause: err });
190
+ }
191
+ })();
178
192
  const href = hashCss(code);
179
- const styles = Object.fromEntries(Object.entries(exports).map(([k, v]) => [k, v.name]));
193
+ const styles = Object.fromEntries(Object.entries(classExports).map(([k, v]) => [k, v.name]));
180
194
  if (tag) {
181
195
  const suffix = typeof config.typeSuffix === "string" ? config.typeSuffix : config.typeSuffix === false ? "" : "Classes";
182
196
  const tagWithSuffix = pascalise(`${tag}${suffix}`);
@@ -196,7 +210,7 @@ function collect(source, id, config) {
196
210
  if (varThree) {
197
211
  statements.push(`${exp}const ${varThree} = ${JSON.stringify(href)}`);
198
212
  }
199
- magic.overwrite(match.index, match.index + match[0].length, statements.join(`
213
+ magic.overwrite(matchIndex, matchIndex + match[0].length, statements.join(`
200
214
  `));
201
215
  }
202
216
  const template = magic.toString();
@@ -222,19 +236,27 @@ async function writeRenderedTypes(tags) {
222
236
  const filePath = path.join(GENERATED_DIR, "index.d.ts");
223
237
  if (!tags.size) {
224
238
  await fs.rm(filePath, { force: true });
225
- fileCache.delete(filePath);
226
239
  return;
227
240
  }
228
241
  await fs.mkdir(GENERATED_DIR, { recursive: true });
229
242
  await maybeWrite(filePath, renderTypes(tags));
230
243
  }
231
- function writeTypes(tags) {
232
- return enqueueWrite(() => writeRenderedTypes(tags));
233
- }
234
244
  var PARTIAL_DIR = path.join(GENERATED_DIR, "tags");
245
+ var REBUILD_WAIT = 100;
246
+ var rebuildTimer = null;
247
+ var rebuildError = null;
235
248
  function partialPath(filePath) {
236
249
  return path.join(PARTIAL_DIR, `${createHash("sha1").update(filePath).digest("hex")}.json`);
237
250
  }
251
+ async function partialDirMtime() {
252
+ try {
253
+ return (await fs.stat(PARTIAL_DIR)).mtimeMs;
254
+ } catch (err) {
255
+ if (isENOENT(err))
256
+ return 0;
257
+ throw err;
258
+ }
259
+ }
238
260
  async function readPartials() {
239
261
  let entries;
240
262
  try {
@@ -278,27 +300,48 @@ function writeTypesForFile(filePath, tags) {
278
300
  } else {
279
301
  await writeFileAtomic(partial, JSON.stringify({ file: filePath, tags: Object.fromEntries(tags) }));
280
302
  }
281
- await writeRenderedTypes(await readPartials());
303
+ }).then(() => {
304
+ scheduleRebuild();
282
305
  });
283
306
  }
307
+ function scheduleRebuild() {
308
+ if (rebuildTimer)
309
+ clearTimeout(rebuildTimer);
310
+ rebuildTimer = setTimeout(() => {
311
+ rebuildTimer = null;
312
+ flushTypes().catch((err) => {
313
+ rebuildError = err;
314
+ });
315
+ }, REBUILD_WAIT);
316
+ }
317
+ function flushTypes() {
318
+ if (rebuildTimer) {
319
+ clearTimeout(rebuildTimer);
320
+ rebuildTimer = null;
321
+ }
322
+ return enqueueWrite(async () => {
323
+ let before = await partialDirMtime();
324
+ for (let attempt = 0;attempt < 3; attempt++) {
325
+ await writeRenderedTypes(await readPartials());
326
+ const after = await partialDirMtime();
327
+ if (after === before)
328
+ return;
329
+ before = after;
330
+ }
331
+ });
332
+ }
333
+ function takeRebuildError() {
334
+ const err = rebuildError;
335
+ rebuildError = null;
336
+ return err;
337
+ }
284
338
  function tagsToType(tags) {
285
- return [...tags].map(([tag, classes]) => {
339
+ return [...tags].toSorted(([a], [b]) => a.localeCompare(b)).map(([tag, classes]) => {
286
340
  const union = classes.length > 0 ? classes.toSorted((a, b) => a.length - b.length).map((c) => `'${c}'`).join(" | ") : "never";
287
341
  return ` export type ${tag} = ${union}`;
288
342
  }).join(`
289
343
  `);
290
344
  }
291
- function flattenTags(tagsByFile) {
292
- const tags = new Map;
293
- for (const fileTags of tagsByFile.values()) {
294
- for (const [name, classes] of fileTags) {
295
- if (tags.has(name))
296
- throw new DuplicateTagError(name);
297
- tags.set(name, classes);
298
- }
299
- }
300
- return tags;
301
- }
302
345
 
303
346
  // src/vite/index.ts
304
347
  import { realpathSync } from "node:fs";
@@ -391,12 +434,14 @@ var ACCEPTED_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx"]);
391
434
  function normaliseWatchPath(p) {
392
435
  return p.replace(/\\/g, "/");
393
436
  }
437
+ function globToRegExp(glob) {
438
+ const pattern = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*(\/|$)/g, ".*$1").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
439
+ return new RegExp(`^${pattern}$`);
440
+ }
394
441
  function cxx(pluginConfig = {}) {
395
- const buildContext = {
396
- tagsByFile: new Map
397
- };
398
442
  const logger = new Logger;
399
443
  let watchRoot = normaliseWatchPath(process.cwd());
444
+ const ignored = (pluginConfig.watch?.ignore ?? []).map(globToRegExp);
400
445
  function resolveWatchFile(filePath) {
401
446
  const absolutePath = path2.resolve(watchRoot, filePath);
402
447
  const parentPath = path2.dirname(absolutePath);
@@ -409,50 +454,56 @@ function cxx(pluginConfig = {}) {
409
454
  }
410
455
  function watchedFile(filePath) {
411
456
  const resolvedPath = resolveWatchFile(filePath);
412
- if (resolvedPath.startsWith(`${watchRoot}/`) && !resolvedPath.includes(`/${GENERATED_DIR}/`) && ACCEPTED_EXTENSIONS.has(path2.extname(resolvedPath))) {
457
+ if (resolvedPath.startsWith(`${watchRoot}/`) && !resolvedPath.includes(`/${GENERATED_DIR}/`) && ACCEPTED_EXTENSIONS.has(path2.extname(resolvedPath)) && !ignored.some((regexp) => regexp.test(resolvedPath))) {
413
458
  return resolvedPath;
414
459
  }
415
460
  return null;
416
461
  }
417
- async function onEvent(event, file) {
418
- const hadTags = buildContext.tagsByFile.has(file);
419
- if (event === "unlink") {
420
- if (!hadTags)
421
- return;
422
- buildContext.tagsByFile.delete(file);
423
- await writeTypes(flattenTags(buildContext.tagsByFile));
424
- logger.info(`updated types from ${file}`);
425
- return;
426
- }
462
+ async function recordFile(file) {
427
463
  let source;
428
464
  try {
429
465
  source = await fs2.readFile(file, "utf-8");
430
466
  } catch (err) {
431
467
  if (!isENOENT(err))
432
468
  throw err;
433
- if (!hadTags)
434
- return;
435
- buildContext.tagsByFile.delete(file);
436
- await writeTypes(flattenTags(buildContext.tagsByFile));
437
- logger.info(`updated types from ${file}`);
469
+ await writeTypesForFile(file, new Map);
438
470
  return;
439
471
  }
440
- const { tags } = collect(source, file, pluginConfig);
441
- const hasTags = tags.size > 0;
442
- if (hasTags) {
443
- buildContext.tagsByFile.set(file, tags);
444
- } else {
445
- buildContext.tagsByFile.delete(file);
446
- }
447
- if (!hadTags && !hasTags)
472
+ const tags = source.includes("cxx") ? collect(source, file, pluginConfig).tags : new Map;
473
+ await writeTypesForFile(file, tags);
474
+ }
475
+ async function scan(dir) {
476
+ let entries;
477
+ try {
478
+ entries = await fs2.readdir(dir, { withFileTypes: true });
479
+ } catch {
448
480
  return;
449
- await writeTypes(flattenTags(buildContext.tagsByFile));
450
- logger.info(`updated types from ${file}`);
481
+ }
482
+ await Promise.all(entries.map(async (entry) => {
483
+ if (entry.name.startsWith(".") || entry.name === "node_modules")
484
+ return;
485
+ const full = path2.join(dir, entry.name);
486
+ if (entry.isDirectory()) {
487
+ await scan(full);
488
+ return;
489
+ }
490
+ if (!ACCEPTED_EXTENSIONS.has(path2.extname(entry.name)))
491
+ return;
492
+ const resolved = resolveWatchFile(full);
493
+ if (ignored.some((regexp) => regexp.test(resolved)))
494
+ return;
495
+ await recordFile(resolved);
496
+ }));
451
497
  }
452
498
  const queue = createBatcher(75, async (batch) => {
453
499
  for (const [file, event] of batch) {
454
500
  try {
455
- await onEvent(event, file);
501
+ if (event === "unlink") {
502
+ await writeTypesForFile(file, new Map);
503
+ } else {
504
+ await recordFile(file);
505
+ }
506
+ logger.info(`updated types from ${file}`);
456
507
  } catch (err) {
457
508
  logger.error(`failed to update types from ${file}`, err);
458
509
  }
@@ -461,18 +512,6 @@ function cxx(pluginConfig = {}) {
461
512
  return {
462
513
  name: "cxx",
463
514
  enforce: "pre",
464
- config() {
465
- const ignore = pluginConfig.watch?.ignore;
466
- if (!ignore?.length)
467
- return null;
468
- return {
469
- server: {
470
- watch: {
471
- ignored: ignore
472
- }
473
- }
474
- };
475
- },
476
515
  configResolved(config) {
477
516
  const root = pluginConfig.watch?.root ?? config.root;
478
517
  try {
@@ -492,12 +531,7 @@ function cxx(pluginConfig = {}) {
492
531
  const { template, tags, map } = collect(code, cleanId, pluginConfig);
493
532
  if (template === code)
494
533
  return null;
495
- const resolved = resolveWatchFile(cleanId);
496
- if (tags.size) {
497
- buildContext.tagsByFile.set(resolved, tags);
498
- } else {
499
- buildContext.tagsByFile.delete(resolved);
500
- }
534
+ writeTypesForFile(resolveWatchFile(cleanId), tags);
501
535
  return {
502
536
  code: template,
503
537
  map
@@ -518,9 +552,14 @@ function cxx(pluginConfig = {}) {
518
552
  if (file)
519
553
  queue.add(file, "unlink");
520
554
  });
555
+ scan(watchRoot).then(() => flushTypes()).then(() => {
556
+ const err = takeRebuildError();
557
+ if (err)
558
+ logger.error("failed to generate types", err);
559
+ }).catch((err) => logger.error("failed to scan for cxx templates", err));
521
560
  },
522
561
  async writeBundle() {
523
- await writeTypes(flattenTags(buildContext.tagsByFile));
562
+ await flushTypes();
524
563
  }
525
564
  };
526
565
  }
@@ -528,4 +567,4 @@ export {
528
567
  cxx as default
529
568
  };
530
569
 
531
- //# debugId=8BACD1ACA42BF59D64756E2164756E21
570
+ //# debugId=7C0503EFBFB9E21F64756E2164756E21