@tamagui/metro-plugin 3.0.0-beta.661.1 → 3.0.0-beta.719.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/babel.cjs +0 -1
- package/dist/cjs/compilerCache.cjs +0 -1
- package/dist/cjs/diagnostics.cjs +0 -1
- package/dist/cjs/frontend.cjs +1 -2
- package/dist/cjs/index.cjs +0 -1
- package/dist/cjs/lowering.cjs +0 -1
- package/dist/cjs/metroResolver.cjs +0 -1
- package/dist/cjs/transformOptions.cjs +0 -1
- package/dist/cjs/transformer.cjs +0 -1
- package/dist/cjs/zeroRuntime.cjs +0 -1
- package/dist/cjs/zeroSerializer.cjs +0 -1
- package/dist/esm/babel.mjs.map +1 -1
- package/dist/esm/compilerCache.mjs.map +1 -1
- package/dist/esm/frontend.mjs +2 -2
- package/dist/esm/frontend.mjs.map +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/metroResolver.mjs.map +1 -1
- package/dist/esm/transformer.mjs.map +1 -1
- package/dist/esm/zeroRuntime.mjs.map +1 -1
- package/dist/esm/zeroSerializer.mjs.map +1 -1
- package/package.json +4 -4
- package/src/frontend.ts +2 -2
- package/types/frontend.d.ts.map +2 -2
package/dist/cjs/babel.cjs
CHANGED
package/dist/cjs/diagnostics.cjs
CHANGED
package/dist/cjs/frontend.cjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -770,7 +769,7 @@ var MetroCompilerFrontend = class {
|
|
|
770
769
|
source,
|
|
771
770
|
plan,
|
|
772
771
|
config,
|
|
773
|
-
isTamaguiSpecifier:
|
|
772
|
+
isTamaguiSpecifier: import_compiler_core.isTamaguiSpecifier,
|
|
774
773
|
resolveIslandLoader: (specifier) => {
|
|
775
774
|
const islandId = zero.loaderIds.get((0, import_zeroRuntime.zeroModuleKey)((0, import_node_path.resolve)(id, "..", specifier)));
|
|
776
775
|
return islandId ? { islandId } : null;
|
package/dist/cjs/index.cjs
CHANGED
package/dist/cjs/lowering.cjs
CHANGED
package/dist/cjs/transformer.cjs
CHANGED
package/dist/cjs/zeroRuntime.cjs
CHANGED
package/dist/esm/babel.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"babel.js","names":[],"sources":["esm/babel.js"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport { dirname } from \"node:path\";\nfunction asTransformer(module, path) {\n const transformer = module?.default?.transform ? module.default : module;\n if (!transformer || typeof transformer.transform !== \"function\") {\n throw new Error(`Metro Babel transformer ${path} has no transform function`);\n }\n return transformer;\n}\nfunction loadMetroBabelTransformer(path) {\n return asTransformer(createRequire(path)(path), path);\n}\nasync function compileWithUserBabel(transformerPath, args) {\n const transformer = loadMetroBabelTransformer(transformerPath);\n const result = await transformer.transform(args);\n if (!result?.ast) {\n throw new Error(`Metro Babel transformer ${transformerPath} returned no AST`);\n }\n const requireFromTransformer = createRequire(transformerPath);\n const generatorModule = requireFromTransformer(\"@babel/generator\");\n const generate = generatorModule.default ?? generatorModule;\n const generated = generate(\n result.ast,\n {\n comments: true,\n compact: false,\n retainLines: true,\n sourceFileName: args.filename,\n sourceMaps: true\n },\n args.src\n );\n if (!generated || typeof generated.code !== \"string\") {\n throw new Error(`Babel generator for ${transformerPath} returned no code`);\n }\n if (!generated.map) {\n throw new Error(`Babel generator for ${transformerPath} returned no source map`);\n }\n return { code: generated.code, map: generated.map, result };\n}\nfunction userBabelCacheKey(transformerPath) {\n const transformer = loadMetroBabelTransformer(transformerPath);\n return createHash(\"sha256\").update(transformerPath).update(\"\\0\").update(transformer.getCacheKey?.() ?? \"\").digest(\"hex\");\n}\nfunction transformerDirectory(transformerPath) {\n return dirname(transformerPath);\n}\nexport {\n compileWithUserBabel,\n loadMetroBabelTransformer,\n transformerDirectory,\n userBabelCacheKey\n};\n//# sourceMappingURL=babel.js.map\n"],"mappings":";;;;;AAGA,SAAS,cAAc,QAAQ,MAAM;CACnC,MAAM,cAAc,QAAQ,SAAS,YAAY,OAAO,UAAU;CAClE,IAAI,CAAC,eAAe,OAAO,YAAY,cAAc,YAAY;EAC/D,MAAM,IAAI,MAAM,2BAA2B,KAAK,2BAA2B;CAC7E;CACA,OAAO;AACT;AACA,SAAS,0BAA0B,MAAM;CACvC,OAAO,cAAc,cAAc,IAAI,
|
|
1
|
+
{"version":3,"file":"babel.js","names":[],"sources":["esm/babel.js"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { createRequire } from \"node:module\";\nimport { dirname } from \"node:path\";\nfunction asTransformer(module, path) {\n const transformer = module?.default?.transform ? module.default : module;\n if (!transformer || typeof transformer.transform !== \"function\") {\n throw new Error(`Metro Babel transformer ${path} has no transform function`);\n }\n return transformer;\n}\nfunction loadMetroBabelTransformer(path) {\n return asTransformer(createRequire(path)(path), path);\n}\nasync function compileWithUserBabel(transformerPath, args) {\n const transformer = loadMetroBabelTransformer(transformerPath);\n const result = await transformer.transform(args);\n if (!result?.ast) {\n throw new Error(`Metro Babel transformer ${transformerPath} returned no AST`);\n }\n const requireFromTransformer = createRequire(transformerPath);\n const generatorModule = requireFromTransformer(\"@babel/generator\");\n const generate = generatorModule.default ?? generatorModule;\n const generated = generate(\n result.ast,\n {\n comments: true,\n compact: false,\n retainLines: true,\n sourceFileName: args.filename,\n sourceMaps: true\n },\n args.src\n );\n if (!generated || typeof generated.code !== \"string\") {\n throw new Error(`Babel generator for ${transformerPath} returned no code`);\n }\n if (!generated.map) {\n throw new Error(`Babel generator for ${transformerPath} returned no source map`);\n }\n return { code: generated.code, map: generated.map, result };\n}\nfunction userBabelCacheKey(transformerPath) {\n const transformer = loadMetroBabelTransformer(transformerPath);\n return createHash(\"sha256\").update(transformerPath).update(\"\\0\").update(transformer.getCacheKey?.() ?? \"\").digest(\"hex\");\n}\nfunction transformerDirectory(transformerPath) {\n return dirname(transformerPath);\n}\nexport {\n compileWithUserBabel,\n loadMetroBabelTransformer,\n transformerDirectory,\n userBabelCacheKey\n};\n//# sourceMappingURL=babel.js.map\n"],"mappings":";;;;;AAGA,SAAS,cAAc,QAAQ,MAAM;CACnC,MAAM,cAAc,QAAQ,SAAS,YAAY,OAAO,UAAU;CAClE,IAAI,CAAC,eAAe,OAAO,YAAY,cAAc,YAAY;EAC/D,MAAM,IAAI,MAAM,2BAA2B,KAAK,2BAA2B;CAC7E;CACA,OAAO;AACT;AACA,SAAS,0BAA0B,MAAM;CACvC,OAAO,cAAc,cAAc,IAAI,CAAC,CAAC,IAAI,GAAG,IAAI;AACtD;AACA,eAAe,qBAAqB,iBAAiB,MAAM;CACzD,MAAM,cAAc,0BAA0B,eAAe;CAC7D,MAAM,SAAS,MAAM,YAAY,UAAU,IAAI;CAC/C,IAAI,CAAC,QAAQ,KAAK;EAChB,MAAM,IAAI,MAAM,2BAA2B,gBAAgB,iBAAiB;CAC9E;CACA,MAAM,yBAAyB,cAAc,eAAe;CAC5D,MAAM,kBAAkB,uBAAuB,kBAAkB;CACjE,MAAM,WAAW,gBAAgB,WAAW;CAC5C,MAAM,YAAY,SAChB,OAAO,KACP;EACE,UAAU;EACV,SAAS;EACT,aAAa;EACb,gBAAgB,KAAK;EACrB,YAAY;CACd,GACA,KAAK,GACP;CACA,IAAI,CAAC,aAAa,OAAO,UAAU,SAAS,UAAU;EACpD,MAAM,IAAI,MAAM,uBAAuB,gBAAgB,kBAAkB;CAC3E;CACA,IAAI,CAAC,UAAU,KAAK;EAClB,MAAM,IAAI,MAAM,uBAAuB,gBAAgB,wBAAwB;CACjF;CACA,OAAO;EAAE,MAAM,UAAU;EAAM,KAAK,UAAU;EAAK;CAAO;AAC5D;AACA,SAAS,kBAAkB,iBAAiB;CAC1C,MAAM,cAAc,0BAA0B,eAAe;CAC7D,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,YAAY,cAAc,KAAK,EAAE,CAAC,CAAC,OAAO,KAAK;AACzH;AACA,SAAS,qBAAqB,iBAAiB;CAC7C,OAAO,QAAQ,eAAe;AAChC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compilerCache.js","names":["#blobsDirectory","#manifestPath","#readManifest","#readBlob","#zeroSidecarPath"],"sources":["esm/compilerCache.js"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n LOWERED_MODULE_PLAN_VERSION,\n contentHash,\n stableStringify,\n tamaguiCacheRoot\n} from \"@tamagui/compiler-core\";\nimport { metroDiagnostic } from \"./diagnostics\";\nconst METRO_COMPILER_CACHE_VERSION = 6;\nclass MetroCompilerCacheError extends Error {\n constructor(diagnostic) {\n super(diagnostic.message);\n this.diagnostic = diagnostic;\n this.name = \"MetroCompilerCacheError\";\n }\n diagnostic;\n}\nfunction compareCodeUnits(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nfunction stableEntries(record) {\n return Object.entries(record).sort(([left], [right]) => compareCodeUnits(left, right));\n}\nfunction cacheCorrupt(message, moduleId) {\n return new MetroCompilerCacheError(\n metroDiagnostic(\"metro/cache-corrupt\", message, { moduleId })\n );\n}\nfunction parseJson(source, description, moduleId) {\n try {\n return JSON.parse(source);\n } catch (error) {\n throw cacheCorrupt(\n `${description} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n moduleId\n );\n }\n}\nfunction defaultMetroCompilerCacheRoot(projectRoot) {\n return join(tamaguiCacheRoot(projectRoot), \"metro-compiler\");\n}\nclass MetroCompilerCache {\n constructor(root) {\n this.root = root;\n this.#blobsDirectory = join(root, `v${METRO_COMPILER_CACHE_VERSION}`, \"blobs\");\n this.#manifestPath = join(root, `v${METRO_COMPILER_CACHE_VERSION}`, \"manifest.json\");\n }\n root;\n #blobsDirectory;\n #manifestPath;\n async publish(platform, entries, optionsHash) {\n await mkdir(this.#blobsDirectory, { recursive: true });\n const descriptors = {};\n for (const entry of [...entries].sort(\n (left, right) => compareCodeUnits(left.moduleId, right.moduleId)\n )) {\n if (entry.schemaVersion !== METRO_COMPILER_CACHE_VERSION) {\n throw new Error(`Cannot publish cache schema ${entry.schemaVersion}`);\n }\n const serialized = `${stableStringify(entry)}\n`;\n const blobHash = contentHash(serialized);\n const blobPath = join(this.#blobsDirectory, `${blobHash}.json`);\n try {\n await writeFile(blobPath, serialized, { encoding: \"utf8\", flag: \"wx\" });\n } catch (error) {\n if (error.code !== \"EEXIST\") throw error;\n const existing = await readFile(blobPath, \"utf8\");\n if (contentHash(existing) !== blobHash) {\n const temporaryBlobPath = `${blobPath}.${process.pid}-${randomBytes(6).toString(\"hex\")}.tmp`;\n await writeFile(temporaryBlobPath, serialized, \"utf8\");\n await rename(temporaryBlobPath, blobPath);\n }\n }\n descriptors[entry.moduleId] = {\n blobHash,\n sourceHash: entry.sourceHash\n };\n }\n const generation = contentHash(stableStringify(descriptors));\n const manifest = {\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n generation,\n optionsHash,\n platform,\n entries: descriptors\n };\n const manifestDirectory = join(this.root, `v${METRO_COMPILER_CACHE_VERSION}`);\n const temporaryPath = join(\n manifestDirectory,\n `.manifest-${process.pid}-${randomBytes(6).toString(\"hex\")}.json`\n );\n await writeFile(temporaryPath, `${stableStringify(manifest)}\n`, \"utf8\");\n await rename(temporaryPath, this.#manifestPath);\n return generation;\n }\n async read(moduleId, rawSource, onMiss) {\n const manifest = await this.#readManifest();\n if (!manifest) return null;\n const descriptor = manifest.entries[moduleId];\n if (!descriptor) {\n onMiss?.(\"no-entry\");\n return null;\n }\n const sourceHash = contentHash(rawSource);\n if (sourceHash !== descriptor.sourceHash) {\n onMiss?.(\n \"source-hash-mismatch\",\n `worker ${sourceHash.slice(0, 12)} vs plan ${descriptor.sourceHash.slice(0, 12)}`\n );\n return null;\n }\n return await this.#readBlob(moduleId, descriptor);\n }\n async validate() {\n const diagnostics = [];\n try {\n const manifest = await this.#readManifest();\n if (!manifest) {\n return {\n valid: false,\n diagnostics,\n generation: null,\n moduleIds: [],\n sourceHashes: {},\n optionsHash: null\n };\n }\n const sourceHashes = {};\n for (const [moduleId, descriptor] of stableEntries(manifest.entries)) {\n await this.#readBlob(moduleId, descriptor);\n sourceHashes[moduleId] = descriptor.sourceHash;\n }\n return {\n valid: true,\n diagnostics,\n generation: manifest.generation,\n moduleIds: Object.keys(manifest.entries).sort(compareCodeUnits),\n sourceHashes,\n optionsHash: manifest.optionsHash\n };\n } catch (error) {\n if (error instanceof MetroCompilerCacheError) {\n diagnostics.push(error.diagnostic);\n return {\n valid: false,\n diagnostics,\n generation: null,\n moduleIds: [],\n sourceHashes: {},\n optionsHash: null\n };\n }\n throw error;\n }\n }\n async discardManifest() {\n await rm(this.#manifestPath, { force: true });\n }\n #zeroSidecarPath(generation) {\n return join(\n this.root,\n `v${METRO_COMPILER_CACHE_VERSION}`,\n `zero-${generation.slice(0, 32)}.json`\n );\n }\n async publishZeroCSS(sidecar) {\n await mkdir(join(this.root, `v${METRO_COMPILER_CACHE_VERSION}`), { recursive: true });\n const file = this.#zeroSidecarPath(sidecar.generation);\n const temporaryPath = `${file}.${process.pid}-${randomBytes(6).toString(\"hex\")}.tmp`;\n await writeFile(temporaryPath, `${stableStringify(sidecar)}\n`, \"utf8\");\n await rename(temporaryPath, file);\n }\n /** Null whenever the sidecar is absent or does not describe this generation. */\n async readZeroCSS(generation) {\n let source;\n try {\n source = await readFile(this.#zeroSidecarPath(generation), \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") return null;\n throw error;\n }\n const sidecar = parseJson(source, \"Zero CSS sidecar\");\n if (sidecar.schemaVersion !== METRO_COMPILER_CACHE_VERSION || sidecar.generation !== generation || typeof sidecar.configCSS !== \"string\" || !sidecar.zeroModuleCSS || typeof sidecar.zeroModuleCSS !== \"object\" || !sidecar.bridgeCSS || typeof sidecar.bridgeCSS !== \"object\" || !sidecar.bridges || typeof sidecar.bridges !== \"object\") {\n return null;\n }\n return sidecar;\n }\n async #readManifest() {\n let source;\n try {\n source = await readFile(this.#manifestPath, \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") return null;\n throw error;\n }\n const manifest = parseJson(source, \"Cache manifest\");\n if (manifest.schemaVersion !== METRO_COMPILER_CACHE_VERSION || typeof manifest.generation !== \"string\" || typeof manifest.optionsHash !== \"string\" || !manifest.entries || typeof manifest.entries !== \"object\") {\n throw cacheCorrupt(\"Cache manifest has an unsupported schema\");\n }\n return manifest;\n }\n async #readBlob(moduleId, descriptor) {\n const blobPath = join(this.#blobsDirectory, `${descriptor.blobHash}.json`);\n let source;\n try {\n source = await readFile(blobPath, \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") {\n throw cacheCorrupt(`Cache blob ${descriptor.blobHash} is missing`, moduleId);\n }\n throw error;\n }\n if (contentHash(source) !== descriptor.blobHash) {\n throw cacheCorrupt(`Cache blob ${descriptor.blobHash} failed its hash`, moduleId);\n }\n const entry = parseJson(\n source,\n `Cache blob ${descriptor.blobHash}`,\n moduleId\n );\n if (entry.schemaVersion !== METRO_COMPILER_CACHE_VERSION || entry.moduleId !== moduleId || typeof entry.sourceHash !== \"string\" || entry.sourceHash !== descriptor.sourceHash || !entry.plan || entry.plan.version !== LOWERED_MODULE_PLAN_VERSION || entry.plan.id !== moduleId || entry.plan.sourceHash !== entry.sourceHash || !Array.isArray(entry.plan.edits) || !Array.isArray(entry.plan.diagnostics) || !Array.isArray(entry.diagnostics)) {\n throw cacheCorrupt(\n `Cache blob ${descriptor.blobHash} has invalid contents`,\n moduleId\n );\n }\n return entry;\n }\n}\nexport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError,\n defaultMetroCompilerCacheRoot\n};\n//# sourceMappingURL=compilerCache.js.map\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compilerCache.js","names":["#blobsDirectory","#manifestPath","#readManifest","#readBlob","#zeroSidecarPath"],"sources":["esm/compilerCache.js"],"sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport {\n LOWERED_MODULE_PLAN_VERSION,\n contentHash,\n stableStringify,\n tamaguiCacheRoot\n} from \"@tamagui/compiler-core\";\nimport { metroDiagnostic } from \"./diagnostics\";\nconst METRO_COMPILER_CACHE_VERSION = 6;\nclass MetroCompilerCacheError extends Error {\n constructor(diagnostic) {\n super(diagnostic.message);\n this.diagnostic = diagnostic;\n this.name = \"MetroCompilerCacheError\";\n }\n diagnostic;\n}\nfunction compareCodeUnits(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nfunction stableEntries(record) {\n return Object.entries(record).sort(([left], [right]) => compareCodeUnits(left, right));\n}\nfunction cacheCorrupt(message, moduleId) {\n return new MetroCompilerCacheError(\n metroDiagnostic(\"metro/cache-corrupt\", message, { moduleId })\n );\n}\nfunction parseJson(source, description, moduleId) {\n try {\n return JSON.parse(source);\n } catch (error) {\n throw cacheCorrupt(\n `${description} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n moduleId\n );\n }\n}\nfunction defaultMetroCompilerCacheRoot(projectRoot) {\n return join(tamaguiCacheRoot(projectRoot), \"metro-compiler\");\n}\nclass MetroCompilerCache {\n constructor(root) {\n this.root = root;\n this.#blobsDirectory = join(root, `v${METRO_COMPILER_CACHE_VERSION}`, \"blobs\");\n this.#manifestPath = join(root, `v${METRO_COMPILER_CACHE_VERSION}`, \"manifest.json\");\n }\n root;\n #blobsDirectory;\n #manifestPath;\n async publish(platform, entries, optionsHash) {\n await mkdir(this.#blobsDirectory, { recursive: true });\n const descriptors = {};\n for (const entry of [...entries].sort(\n (left, right) => compareCodeUnits(left.moduleId, right.moduleId)\n )) {\n if (entry.schemaVersion !== METRO_COMPILER_CACHE_VERSION) {\n throw new Error(`Cannot publish cache schema ${entry.schemaVersion}`);\n }\n const serialized = `${stableStringify(entry)}\n`;\n const blobHash = contentHash(serialized);\n const blobPath = join(this.#blobsDirectory, `${blobHash}.json`);\n try {\n await writeFile(blobPath, serialized, { encoding: \"utf8\", flag: \"wx\" });\n } catch (error) {\n if (error.code !== \"EEXIST\") throw error;\n const existing = await readFile(blobPath, \"utf8\");\n if (contentHash(existing) !== blobHash) {\n const temporaryBlobPath = `${blobPath}.${process.pid}-${randomBytes(6).toString(\"hex\")}.tmp`;\n await writeFile(temporaryBlobPath, serialized, \"utf8\");\n await rename(temporaryBlobPath, blobPath);\n }\n }\n descriptors[entry.moduleId] = {\n blobHash,\n sourceHash: entry.sourceHash\n };\n }\n const generation = contentHash(stableStringify(descriptors));\n const manifest = {\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n generation,\n optionsHash,\n platform,\n entries: descriptors\n };\n const manifestDirectory = join(this.root, `v${METRO_COMPILER_CACHE_VERSION}`);\n const temporaryPath = join(\n manifestDirectory,\n `.manifest-${process.pid}-${randomBytes(6).toString(\"hex\")}.json`\n );\n await writeFile(temporaryPath, `${stableStringify(manifest)}\n`, \"utf8\");\n await rename(temporaryPath, this.#manifestPath);\n return generation;\n }\n async read(moduleId, rawSource, onMiss) {\n const manifest = await this.#readManifest();\n if (!manifest) return null;\n const descriptor = manifest.entries[moduleId];\n if (!descriptor) {\n onMiss?.(\"no-entry\");\n return null;\n }\n const sourceHash = contentHash(rawSource);\n if (sourceHash !== descriptor.sourceHash) {\n onMiss?.(\n \"source-hash-mismatch\",\n `worker ${sourceHash.slice(0, 12)} vs plan ${descriptor.sourceHash.slice(0, 12)}`\n );\n return null;\n }\n return await this.#readBlob(moduleId, descriptor);\n }\n async validate() {\n const diagnostics = [];\n try {\n const manifest = await this.#readManifest();\n if (!manifest) {\n return {\n valid: false,\n diagnostics,\n generation: null,\n moduleIds: [],\n sourceHashes: {},\n optionsHash: null\n };\n }\n const sourceHashes = {};\n for (const [moduleId, descriptor] of stableEntries(manifest.entries)) {\n await this.#readBlob(moduleId, descriptor);\n sourceHashes[moduleId] = descriptor.sourceHash;\n }\n return {\n valid: true,\n diagnostics,\n generation: manifest.generation,\n moduleIds: Object.keys(manifest.entries).sort(compareCodeUnits),\n sourceHashes,\n optionsHash: manifest.optionsHash\n };\n } catch (error) {\n if (error instanceof MetroCompilerCacheError) {\n diagnostics.push(error.diagnostic);\n return {\n valid: false,\n diagnostics,\n generation: null,\n moduleIds: [],\n sourceHashes: {},\n optionsHash: null\n };\n }\n throw error;\n }\n }\n async discardManifest() {\n await rm(this.#manifestPath, { force: true });\n }\n #zeroSidecarPath(generation) {\n return join(\n this.root,\n `v${METRO_COMPILER_CACHE_VERSION}`,\n `zero-${generation.slice(0, 32)}.json`\n );\n }\n async publishZeroCSS(sidecar) {\n await mkdir(join(this.root, `v${METRO_COMPILER_CACHE_VERSION}`), { recursive: true });\n const file = this.#zeroSidecarPath(sidecar.generation);\n const temporaryPath = `${file}.${process.pid}-${randomBytes(6).toString(\"hex\")}.tmp`;\n await writeFile(temporaryPath, `${stableStringify(sidecar)}\n`, \"utf8\");\n await rename(temporaryPath, file);\n }\n /** Null whenever the sidecar is absent or does not describe this generation. */\n async readZeroCSS(generation) {\n let source;\n try {\n source = await readFile(this.#zeroSidecarPath(generation), \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") return null;\n throw error;\n }\n const sidecar = parseJson(source, \"Zero CSS sidecar\");\n if (sidecar.schemaVersion !== METRO_COMPILER_CACHE_VERSION || sidecar.generation !== generation || typeof sidecar.configCSS !== \"string\" || !sidecar.zeroModuleCSS || typeof sidecar.zeroModuleCSS !== \"object\" || !sidecar.bridgeCSS || typeof sidecar.bridgeCSS !== \"object\" || !sidecar.bridges || typeof sidecar.bridges !== \"object\") {\n return null;\n }\n return sidecar;\n }\n async #readManifest() {\n let source;\n try {\n source = await readFile(this.#manifestPath, \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") return null;\n throw error;\n }\n const manifest = parseJson(source, \"Cache manifest\");\n if (manifest.schemaVersion !== METRO_COMPILER_CACHE_VERSION || typeof manifest.generation !== \"string\" || typeof manifest.optionsHash !== \"string\" || !manifest.entries || typeof manifest.entries !== \"object\") {\n throw cacheCorrupt(\"Cache manifest has an unsupported schema\");\n }\n return manifest;\n }\n async #readBlob(moduleId, descriptor) {\n const blobPath = join(this.#blobsDirectory, `${descriptor.blobHash}.json`);\n let source;\n try {\n source = await readFile(blobPath, \"utf8\");\n } catch (error) {\n if (error.code === \"ENOENT\") {\n throw cacheCorrupt(`Cache blob ${descriptor.blobHash} is missing`, moduleId);\n }\n throw error;\n }\n if (contentHash(source) !== descriptor.blobHash) {\n throw cacheCorrupt(`Cache blob ${descriptor.blobHash} failed its hash`, moduleId);\n }\n const entry = parseJson(\n source,\n `Cache blob ${descriptor.blobHash}`,\n moduleId\n );\n if (entry.schemaVersion !== METRO_COMPILER_CACHE_VERSION || entry.moduleId !== moduleId || typeof entry.sourceHash !== \"string\" || entry.sourceHash !== descriptor.sourceHash || !entry.plan || entry.plan.version !== LOWERED_MODULE_PLAN_VERSION || entry.plan.id !== moduleId || entry.plan.sourceHash !== entry.sourceHash || !Array.isArray(entry.plan.edits) || !Array.isArray(entry.plan.diagnostics) || !Array.isArray(entry.diagnostics)) {\n throw cacheCorrupt(\n `Cache blob ${descriptor.blobHash} has invalid contents`,\n moduleId\n );\n }\n return entry;\n }\n}\nexport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError,\n defaultMetroCompilerCacheRoot\n};\n//# sourceMappingURL=compilerCache.js.map\n"],"mappings":"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"}
|
package/dist/esm/frontend.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { readFile, readdir, realpath } from "node:fs/promises";
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import ignore from "ignore";
|
|
6
|
-
import { JsonFileCache, ModulePlanCache, PLAN_CACHE_SCHEMA_VERSION, ProjectGraph, contentHash, defaultPlanCacheRoot, lowerModule, materializeModule, moduleClosureDigest, moduleClosureNode, planCacheKey, resolvedModuleId, stableStringify, yukuFactory } from "@tamagui/compiler-core";
|
|
6
|
+
import { JsonFileCache, ModulePlanCache, PLAN_CACHE_SCHEMA_VERSION, ProjectGraph, contentHash, defaultPlanCacheRoot, isTamaguiSpecifier, lowerModule, materializeModule, moduleClosureDigest, moduleClosureNode, planCacheKey, resolvedModuleId, stableStringify, yukuFactory } from "@tamagui/compiler-core";
|
|
7
7
|
import Static, { createTamaguiCompilerHost } from "@tamagui/static";
|
|
8
8
|
import { compileWithUserBabel, userBabelCacheKey } from "./babel.mjs";
|
|
9
9
|
import { zeroModuleKey } from "./zeroRuntime.mjs";
|
|
@@ -736,7 +736,7 @@ var MetroCompilerFrontend = class {
|
|
|
736
736
|
source,
|
|
737
737
|
plan,
|
|
738
738
|
config,
|
|
739
|
-
isTamaguiSpecifier
|
|
739
|
+
isTamaguiSpecifier,
|
|
740
740
|
resolveIslandLoader: (specifier) => {
|
|
741
741
|
const islandId = zero.loaderIds.get(zeroModuleKey(resolve(id, "..", specifier)));
|
|
742
742
|
return islandId ? { islandId } : null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontend.js","names":["#cacheBaseRoot","#resolver","#planCache","#recordCache","#enqueue","#scan","#scanOptions","#publishedGeneration","#loadCompilerProject","#projectGeneration","#scanOptionsHash","#installCaches","#watchers","#records","#compileRecord","#report","#tamaguiConfig","#entries","#restorePlans","#graph","#host","#zeroEntryGraph","#reachableFrom","#refreshEntry","#storePlans","#publish","#installWatchers","#releaseGraph","#ensureValidCache","#sourcesAreFresh","#rehydrateZeroCSS","#addDependency","#watchModule","#operationQueue","#planKeys","#recordCacheIdentity","#babelArgs","#babelOptions","#zeroPlanFor","#entryFor","#planCacheStamp"],"sources":["esm/frontend.js"],"sourcesContent":["import { existsSync, watch } from \"node:fs\";\nimport { readFile, readdir, realpath } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, join, relative, resolve, sep } from \"node:path\";\nimport ignore from \"ignore\";\nimport {\n JsonFileCache,\n ModulePlanCache,\n PLAN_CACHE_SCHEMA_VERSION,\n ProjectGraph,\n contentHash,\n defaultPlanCacheRoot,\n lowerModule,\n materializeModule,\n moduleClosureDigest,\n moduleClosureNode,\n planCacheKey,\n resolvedModuleId,\n stableStringify,\n yukuFactory\n} from \"@tamagui/compiler-core\";\nimport Static, { createTamaguiCompilerHost } from \"@tamagui/static\";\nimport {\n compileWithUserBabel,\n userBabelCacheKey\n} from \"./babel\";\nimport { zeroModuleKey } from \"./zeroRuntime\";\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n defaultMetroCompilerCacheRoot\n} from \"./compilerCache\";\nimport { metroDiagnostic } from \"./diagnostics\";\nimport {\n createMetroCompilerResolver,\n isCompilerSourceFile,\n moduleSpecifiersFromAst\n} from \"./metroResolver\";\nconst METRO_RECORD_CACHE_VERSION = 1;\nfunction compareCodeUnits(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nconst requireFromFrontend = createRequire(\n typeof __filename === \"string\" ? __filename : import.meta.url\n);\nconst compilerImplementationVersions = [\"@tamagui/metro-plugin\", \"@tamagui/static\", \"@tamagui/compiler-core\"].map((packageName) => {\n const { version } = requireFromFrontend(`${packageName}/package.json`);\n return `${packageName}@${version}`;\n});\nfunction scanOptionsHash(options, projectGeneration, projectSourcesHash) {\n return contentHash(JSON.stringify({ options, projectGeneration, projectSourcesHash }));\n}\nconst speculativeWalkExcludedDirs = /* @__PURE__ */ new Set([\n \"__tests__\",\n \"e2e\",\n \"flows\",\n \"plugins\",\n \"screenshots\",\n \"scripts\",\n \"test\",\n \"test-results\",\n \"tests\"\n]);\nasync function walkProjectSources(root) {\n const inherited = [];\n let ancestor = root;\n while (!existsSync(join(ancestor, \".git\"))) {\n const parent = dirname(ancestor);\n if (parent === ancestor) break;\n inherited.unshift(parent);\n ancestor = parent;\n }\n const rootScopes = [];\n for (const dir of inherited) {\n const source = await readFile(join(dir, \".gitignore\"), \"utf8\").catch(() => null);\n if (source) rootScopes.push({ dir, matcher: ignore().add(source) });\n }\n const found = [];\n const stack = [\n { dir: root, scopes: rootScopes }\n ];\n while (stack.length) {\n const { dir, scopes } = stack.pop();\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n let active = scopes;\n if (entries.some((entry) => entry.isFile() && entry.name === \".gitignore\")) {\n const source = await readFile(join(dir, \".gitignore\"), \"utf8\").catch(() => null);\n if (source) active = [...scopes, { dir, matcher: ignore().add(source) }];\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n const isDirectory = entry.isDirectory();\n if (isDirectory && speculativeWalkExcludedDirs.has(entry.name)) continue;\n if (!isDirectory && !(entry.isFile() && isCompilerSourceFile(entry.name))) continue;\n if (!isDirectory && (/(?:^|[-.])(?:probe|run|spec|tests?)(?:[-.]|$)/i.test(entry.name) || /\\.(?:build|config|workspace)\\.[cm]?[jt]sx?$/.test(entry.name))) {\n continue;\n }\n const path = join(dir, entry.name);\n let ignored = false;\n for (const scope of active) {\n const relativePath = relative(scope.dir, path);\n if (!relativePath || relativePath.startsWith(\"..\")) continue;\n const candidate = relativePath.split(sep).join(\"/\") + (isDirectory ? \"/\" : \"\");\n if (scope.matcher.ignores(candidate)) {\n ignored = true;\n break;\n }\n }\n if (ignored) continue;\n if (isDirectory) stack.push({ dir: path, scopes: active });\n else found.push(path);\n }\n }\n return found.sort(compareCodeUnits);\n}\nfunction compilerTarget(platform) {\n return platform === \"web\" ? \"web\" : \"native\";\n}\nfunction retainsLiveGraph(options) {\n return options.dev && options.hot;\n}\nclass MetroCompilerFrontend {\n constructor(config) {\n this.config = config;\n this.#cacheBaseRoot = config.cacheRoot ?? defaultMetroCompilerCacheRoot(config.projectRoot);\n this.#resolver = createMetroCompilerResolver(config);\n }\n config;\n #cacheBaseRoot;\n #entries = /* @__PURE__ */ new Map();\n #records = /* @__PURE__ */ new Map();\n #watchers = /* @__PURE__ */ new Map();\n #resolver;\n #graph = null;\n #host = null;\n #projectGeneration = null;\n #publishedGeneration = null;\n #scanOptions = null;\n #scanOptionsHash = null;\n #operationQueue = Promise.resolve();\n #tamaguiConfig = null;\n #zeroEntryGraph = null;\n #planKeys = /* @__PURE__ */ new Map();\n #recordCache = null;\n #recordCacheIdentity = null;\n #planCache = null;\n #planCacheStamp = null;\n get metroResolverVersion() {\n return this.#resolver.version;\n }\n /**\n * Per-file cache accounting for the last scan. The point of these caches is\n * that one edited module leaves every other module's entry valid, and this is\n * how that is observed rather than assumed.\n */\n get compileCacheStats() {\n const empty = { hits: 0, misses: 0, writes: 0 };\n return {\n plans: this.#planCache?.stats ?? empty,\n records: this.#recordCache?.stats ?? empty\n };\n }\n cacheRootFor(platform) {\n return join(this.#cacheBaseRoot, platform ?? \"default\");\n }\n scan(options) {\n return this.#enqueue(() => this.#scan(options));\n }\n async #scan(options, preparedProject, preparedProjectSources) {\n this.#scanOptions = options;\n this.#publishedGeneration = null;\n const diagnostics = [];\n const entryRoots = (await Promise.all(\n options.entryFiles.map((path) => realpath(resolve(this.config.projectRoot, path)))\n )).sort(compareCodeUnits);\n const compilerProject = preparedProject ?? await this.#loadCompilerProject(options, entryRoots[0], diagnostics);\n this.#projectGeneration = compilerProject.generation;\n const projectSources = preparedProjectSources ?? await walkProjectSources(this.config.projectRoot);\n const projectSourcesHash = contentHash(JSON.stringify(projectSources));\n this.#scanOptionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n projectSourcesHash\n );\n this.#installCaches(options, compilerProject, projectSourcesHash);\n const speculativeRoots = /* @__PURE__ */ new Set();\n for (const file of projectSources) {\n try {\n const id = await realpath(file);\n if (!entryRoots.includes(id)) speculativeRoots.add(id);\n } catch {\n }\n }\n const roots = [.../* @__PURE__ */ new Set([...entryRoots, ...speculativeRoots])].sort(\n compareCodeUnits\n );\n const queue = [...roots];\n const queued = new Set(queue);\n for (const watcher of this.#watchers.values()) watcher.close();\n this.#watchers.clear();\n this.#records.clear();\n while (queue.length) {\n const path = queue.shift();\n try {\n const record = await this.#compileRecord(path, options, diagnostics);\n this.#records.set(record.input.id, record);\n for (const dependency of record.input.imports) {\n if (dependency.external || !isCompilerSourceFile(dependency.resolvedId) || queued.has(dependency.resolvedId)) {\n continue;\n }\n queued.add(dependency.resolvedId);\n queue.push(dependency.resolvedId);\n }\n } catch (error) {\n if (speculativeRoots.has(path)) continue;\n const diagnostic = metroDiagnostic(\n \"metro/transform-failed\",\n `Failed to compile ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n );\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n }\n if (!compilerProject.projectInfo.tamaguiConfig || !compilerProject.projectInfo.components) {\n throw new Error(\"Metro compiler project has no Tamagui config or components\");\n }\n this.#tamaguiConfig = compilerProject.projectInfo.tamaguiConfig;\n this.#entries.clear();\n const unplanned = await this.#restorePlans(options);\n const zero = this.config.zero;\n this.#graph = null;\n this.#host = null;\n if (unplanned.length || retainsLiveGraph(options)) {\n this.#graph = new ProjectGraph(yukuFactory, {\n modules: [...this.#records.values()].map(({ input }) => input)\n });\n this.#host = createTamaguiCompilerHost({\n target: compilerTarget(options.platform),\n tamaguiConfig: compilerProject.projectInfo.tamaguiConfig,\n components: compilerProject.projectInfo.components,\n componentModules: compilerProject.componentModules.map(({ moduleName, id }) => ({\n moduleName,\n resolvedId: id\n })),\n disablePartialExtraction: compilerProject.disablePartialExtraction,\n experimentalNativeFastPath: compilerProject.experimentalNativeFastPath,\n zeroRuntime: compilerProject.zeroRuntime\n });\n if (zero) {\n if (zero.isEnforcing) {\n Static.assertZeroConfigDrivers(compilerProject.projectInfo.tamaguiConfig);\n }\n zero.plansRestoredFromCache = false;\n zero.configCSS = compilerProject.projectInfo.tamaguiConfig.getCSS?.() ?? \"\";\n zero.artifact.clearGraphs();\n zero.bridges.clear();\n zero.violations.length = 0;\n zero.transformed.clear();\n zero.erasedExports.clear();\n this.#zeroEntryGraph = this.#reachableFrom(entryRoots.map(resolvedModuleId));\n }\n for (const id of unplanned) this.#refreshEntry(id);\n await this.#storePlans(unplanned);\n }\n if (zero) {\n Static.writeZeroViolationReport(zero.resolved.outDir, \"metro-zero\", {\n integration: \"metro-web\",\n mode: zero.isEnforcing ? \"enforce\" : \"report\",\n violations: zero.violations\n });\n if (zero.isEnforcing && zero.violations.length) {\n throw new Error(Static.formatZeroViolations(zero.violations));\n }\n }\n const totalFound = [...this.#entries.values()].reduce(\n (sum, entry) => sum + entry.plan.stats.found,\n 0\n );\n if (this.#entries.size > 0 && totalFound === 0) {\n const componentNames = compilerProject.componentModules.map(\n ({ moduleName }) => moduleName\n );\n const cjsComponentImporters = [...this.#records.values()].filter(\n (record) => record.requireSpecifiers.some(\n (specifier) => componentNames.some(\n (name) => specifier === name || specifier.startsWith(`${name}/`)\n )\n )\n ).length;\n if (cjsComponentImporters > 0) {\n const diagnostic = metroDiagnostic(\n \"metro/no-linked-components\",\n `The Tamagui compiler linked 0 components across ${this.#entries.size} modules even though ${cjsComponentImporters} module(s) reference ${componentNames.join(\", \")} through require() calls. Metro compiled modules to CommonJS before the compiler could analyze them, so component imports cannot be linked and nothing will be optimized. Enable experimentalImportSupport in your transformer's getTransformOptions (Expo enables it by default) to restore Tamagui compilation.`\n );\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n }\n const generation = await this.#publish(options.platform);\n const moduleIds = [...this.#records.keys()].sort(compareCodeUnits);\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#installWatchers();\n } else if (!retainsLiveGraph(options)) {\n this.#releaseGraph();\n }\n return {\n generation,\n moduleIds,\n diagnostics\n };\n }\n ensureValidCache(options) {\n return this.#enqueue(() => this.#ensureValidCache(options));\n }\n async #ensureValidCache(options) {\n const diagnostics = [];\n const firstEntry = options.entryFiles[0];\n const importer = firstEntry ? await realpath(resolve(this.config.projectRoot, firstEntry)) : this.config.projectRoot;\n const compilerProject = await this.#loadCompilerProject(\n options,\n importer,\n diagnostics\n );\n const cache = new MetroCompilerCache(this.cacheRootFor(options.platform));\n const validation = await cache.validate();\n const projectSources = await walkProjectSources(this.config.projectRoot);\n const optionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n contentHash(JSON.stringify(projectSources))\n );\n if (validation.valid && validation.generation && validation.optionsHash === optionsHash && await this.#sourcesAreFresh(validation.sourceHashes) && (!retainsLiveGraph(options) && !this.#graph || this.#publishedGeneration && this.#scanOptionsHash === optionsHash) && // A zero build owns the one CSS artifact, and its contents are produced by\n // the scan. Reusing a published plan without restoring the artifact would\n // emit one missing every rule this process never collected, while still\n // deriving TAMAGUI_DID_OUTPUT_CSS from it. The sidecar carries exactly\n // those side effects; without it there is nothing safe to reuse.\n await this.#rehydrateZeroCSS(cache, validation.generation)) {\n this.#publishedGeneration = validation.generation;\n this.#scanOptions = options;\n this.#scanOptionsHash = optionsHash;\n this.#projectGeneration = compilerProject.generation;\n return {\n generation: validation.generation,\n moduleIds: validation.moduleIds,\n diagnostics\n };\n }\n for (const diagnostic of validation.diagnostics) this.#report(diagnostic);\n await cache.discardManifest();\n return await this.#scan(options, compilerProject, projectSources);\n }\n async updateFile(path) {\n let result = {\n changed: false,\n affectedIds: [],\n generation: null\n };\n return this.#enqueue(async () => {\n const graph = this.#graph;\n const options = this.#scanOptions;\n if (!graph || !options) return result;\n let record;\n const diagnostics = [];\n try {\n record = await this.#compileRecord(path, options, diagnostics);\n } catch (error) {\n if (error.code === \"ENOENT\") {\n const id = resolvedModuleId(resolve(path));\n const invalidation2 = graph.removeModule(id);\n this.#watchers.get(id)?.close();\n this.#watchers.delete(id);\n this.#records.delete(id);\n this.#entries.delete(id);\n for (const affected of invalidation2.invalidatedIds) {\n if (affected !== id) this.#refreshEntry(affected);\n }\n const generation2 = await this.#publish(options.platform);\n result = {\n changed: invalidation2.changed,\n affectedIds: invalidation2.invalidatedIds,\n generation: generation2\n };\n return result;\n }\n const diagnostic = metroDiagnostic(\n \"metro/transform-failed\",\n `Failed to update ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n );\n this.#report(diagnostic);\n return result;\n }\n for (const dependency of record.input.imports) {\n if (dependency.external || !isCompilerSourceFile(dependency.resolvedId) || this.#records.has(dependency.resolvedId)) {\n continue;\n }\n await this.#addDependency(dependency.resolvedId, options, diagnostics);\n }\n this.#records.set(record.input.id, record);\n const invalidation = graph.updateModule(record.input);\n for (const affected of invalidation.invalidatedIds) this.#refreshEntry(affected);\n const generation = invalidation.changed ? await this.#publish(options.platform) : null;\n result = {\n changed: invalidation.changed,\n affectedIds: invalidation.invalidatedIds,\n generation\n };\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#watchModule(record.input.id);\n }\n return result;\n });\n }\n /** A published plan only applies while every recorded module source is unchanged. */\n async #sourcesAreFresh(sourceHashes) {\n const checks = Object.entries(sourceHashes).map(async ([moduleId, sourceHash]) => {\n try {\n return contentHash(await readFile(moduleId, \"utf8\")) === sourceHash;\n } catch {\n return false;\n }\n });\n return (await Promise.all(checks)).every(Boolean);\n }\n #enqueue(operation) {\n const queued = this.#operationQueue.then(operation);\n this.#operationQueue = queued.then(\n () => void 0,\n () => void 0\n );\n return queued;\n }\n close() {\n return this.#enqueue(async () => {\n this.#releaseGraph();\n });\n }\n #releaseGraph() {\n for (const watcher of this.#watchers.values()) watcher.close();\n this.#watchers.clear();\n this.#entries.clear();\n this.#records.clear();\n this.#planKeys.clear();\n this.#graph = null;\n this.#host = null;\n this.#projectGeneration = null;\n }\n async #loadCompilerProject(options, importer, diagnostics) {\n const target = compilerTarget(options.platform);\n if (this.config.loadCompilerProject) {\n return await this.config.loadCompilerProject(target, options.platform);\n }\n return Static.loadCompilerProject({\n root: this.config.projectRoot,\n target,\n options: this.config.tamaguiOptions ?? {},\n hostVersions: compilerImplementationVersions,\n missingProjectMessage: \"Unable to load the Tamagui project for Metro compilation\",\n generation: (projectInfo, componentModules, normalizedOptions) => {\n return contentHash(\n JSON.stringify({\n cacheVersion: METRO_COMPILER_CACHE_VERSION,\n compilerImplementationVersions,\n componentModules,\n configCss: projectInfo.tamaguiConfig?.getCSS?.() ?? \"\",\n disablePartialExtraction: !!normalizedOptions.disablePartialExtraction,\n experimentalNativeFastPath: target === \"native\" && normalizedOptions.experimental?.nativeFastPath === true,\n target,\n // the host's diagnostics are mode-aware, so a plan built in one mode is\n // not a plan the other mode may reuse\n zeroRuntime: !!this.config.zero\n })\n );\n },\n resolveComponents: async (moduleNames) => {\n const componentModules = [];\n for (const moduleName of moduleNames) {\n try {\n const resolution = this.#resolver.resolve(\n importer,\n { specifier: moduleName, isESMImport: true },\n options.platform\n );\n if (!resolution) continue;\n componentModules.push({ moduleName, id: resolution.resolvedId });\n } catch (error) {\n const diagnostic = metroDiagnostic(\n \"metro/resolve-failed\",\n `Failed to resolve compiler component ${moduleName}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: importer, dependency: moduleName }\n );\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n }\n return componentModules;\n }\n });\n }\n async #compileRecord(rawPath, options, diagnostics) {\n const path = await realpath(resolve(rawPath));\n const source = await readFile(path, \"utf8\");\n const sourceHash = contentHash(source);\n const id = resolvedModuleId(path);\n const cache = this.#recordCache;\n const identity = this.#recordCacheIdentity;\n const key = cache && identity ? contentHash(`${identity}\\0${sourceHash}`) : null;\n if (cache && key) {\n const cached = await cache.read(key, (value) => {\n const entry = value;\n return entry?.schemaVersion === METRO_RECORD_CACHE_VERSION && entry.sourceHash === sourceHash && Array.isArray(entry.imports) && Array.isArray(entry.requireSpecifiers) && Array.isArray(entry.diagnostics) ? entry : null;\n });\n if (cached) {\n for (const diagnostic of cached.diagnostics) {\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n return {\n input: { id, source, imports: cached.imports },\n sourceHash,\n requireSpecifiers: cached.requireSpecifiers\n };\n }\n }\n const args = this.#babelArgs(path, source, options);\n const compiled = await compileWithUserBabel(\n this.config.originalBabelTransformerPath,\n args\n );\n const imports = [];\n const requireSpecifiers = [];\n const recordDiagnostics = [];\n for (const dependency of moduleSpecifiersFromAst(compiled.result.ast)) {\n if (!dependency.isESMImport) requireSpecifiers.push(dependency.specifier);\n try {\n const resolution = this.#resolver.resolve(path, dependency, options.platform);\n if (!resolution) continue;\n imports.push({\n specifier: resolution.specifier,\n resolvedId: resolvedModuleId(resolution.resolvedId),\n external: resolution.external\n });\n } catch (error) {\n recordDiagnostics.push(\n metroDiagnostic(\n \"metro/resolve-failed\",\n `Failed to resolve ${dependency.specifier} from ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path, dependency: dependency.specifier }\n )\n );\n }\n }\n for (const diagnostic of recordDiagnostics) {\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n if (cache && key) {\n await cache.write(key, {\n schemaVersion: METRO_RECORD_CACHE_VERSION,\n sourceHash,\n imports,\n requireSpecifiers,\n diagnostics: recordDiagnostics\n });\n }\n return {\n // The graph and plans operate on raw source: workers apply plan edits to\n // the raw module before their own Babel pass, so plans never depend on\n // this process's Babel output matching the workers' byte for byte.\n input: { id, source, imports },\n sourceHash,\n requireSpecifiers\n };\n }\n #babelOptions(options) {\n const transformer = this.config.transformer ?? {};\n return {\n ...options.transform,\n dev: options.dev,\n hot: options.hot,\n platform: options.platform,\n projectRoot: this.config.projectRoot,\n enableBabelRCLookup: transformer.enableBabelRCLookup ?? true,\n enableBabelRuntime: transformer.enableBabelRuntime ?? true,\n hermesParser: transformer.hermesParser ?? false,\n publicPath: transformer.publicPath ?? \"/assets\"\n };\n }\n #babelArgs(filename, src, options) {\n return { filename, src, plugins: [], options: this.#babelOptions(options) };\n }\n async #addDependency(id, options, diagnostics, visiting = /* @__PURE__ */ new Set()) {\n if (this.#records.has(id) || visiting.has(id)) return;\n visiting.add(id);\n try {\n const record = await this.#compileRecord(id, options, diagnostics);\n for (const dependency of record.input.imports) {\n if (!dependency.external && isCompilerSourceFile(dependency.resolvedId)) {\n await this.#addDependency(dependency.resolvedId, options, diagnostics, visiting);\n }\n }\n this.#records.set(id, record);\n const invalidation = this.#graph?.updateModule(record.input);\n for (const affected of invalidation?.invalidatedIds ?? [id]) {\n this.#refreshEntry(affected);\n }\n if (this.config.watch !== false && this.#scanOptions && retainsLiveGraph(this.#scanOptions)) {\n this.#watchModule(id);\n }\n } finally {\n visiting.delete(id);\n }\n }\n #refreshEntry(id) {\n const graph = this.#graph;\n const host = this.#host;\n const record = this.#records.get(id);\n if (!graph || !host || !record || !this.#scanOptions || !this.#projectGeneration)\n return;\n const target = compilerTarget(this.#scanOptions.platform);\n const plan = lowerModule({\n module: materializeModule(graph, id),\n source: record.input.source,\n target,\n host,\n options: { projectGeneration: this.#projectGeneration }\n });\n const zeroPlan = this.#zeroPlanFor(id, record.input.source, plan);\n this.#entries.set(id, this.#entryFor(id, record, zeroPlan ?? plan));\n }\n /**\n * One plan becomes one cache entry the same way whether the plan was just\n * lowered or read back off disk, so a restored build reports exactly the\n * diagnostics a fresh one did.\n */\n #entryFor(id, record, plan) {\n return {\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n moduleId: id,\n sourceHash: record.sourceHash,\n plan,\n diagnostics: plan.diagnostics.map(\n ({ code, message, dependencyId, span, component }) => {\n const { line, column } = Static.offsetToLineColumn(\n record.input.source,\n span.start\n );\n return metroDiagnostic(\n code.startsWith(\"linked/\") ? \"metro/resolve-failed\" : \"metro/transform-failed\",\n message,\n { moduleId: id, dependency: dependencyId, span, line, column, component }\n );\n }\n )\n };\n }\n /**\n * Both per-file caches for this scan. A project with no content stamp gets\n * neither: a stamp that cannot see a config change would serve styles built\n * against the old config, so the answer is no cache rather than a partial one.\n *\n * Zero builds opt out of the plan cache because a zero plan is produced\n * alongside side effects that do not travel in the plan - the CSS artifact,\n * the bridge manifest, the violation list - so replaying one module's plan\n * without them would emit an artifact missing its rules.\n */\n #installCaches(options, project, projectSourcesHash) {\n const platform = options.platform ?? \"default\";\n const root = defaultPlanCacheRoot(this.config.projectRoot, platform);\n this.#recordCache = new JsonFileCache(\n join(root, \"records\"),\n METRO_RECORD_CACHE_VERSION\n );\n this.#recordCacheIdentity = contentHash(\n stableStringify({\n schema: METRO_RECORD_CACHE_VERSION,\n resolver: this.#resolver.version,\n babel: userBabelCacheKey(this.config.originalBabelTransformerPath),\n // resolutions depend on which files exist, so the walked source list is\n // part of a record's identity exactly as it is for the plan manifest\n projectSourcesHash,\n platform,\n transform: this.#babelOptions(options)\n })\n );\n const stamp = project.cacheStamp;\n const usePlanCache = typeof stamp === \"string\" && stamp !== \"\" && !this.config.zero;\n this.#planCache = usePlanCache ? new ModulePlanCache(join(root, \"plans\")) : null;\n this.#planCacheStamp = usePlanCache ? stamp : null;\n }\n /**\n * Fills `#entries` from disk for every module whose whole compile input is\n * unchanged, and returns the ids that still have to be compiled. This is the\n * per-file property: one edited module leaves every other module's entry\n * valid, where the plan manifest would have discarded all of them.\n */\n async #restorePlans(options) {\n this.#planKeys.clear();\n const cache = this.#planCache;\n const stamp = this.#planCacheStamp;\n if (!cache || !stamp) return [...this.#records.keys()].sort(compareCodeUnits);\n const target = compilerTarget(options.platform);\n const identity = {\n stamp,\n target,\n structuralPassHash: `${target}-noop-v1`\n };\n const nodes = /* @__PURE__ */ new Map();\n const lookup = (id) => {\n let node = nodes.get(id);\n if (node === void 0) {\n const record = this.#records.get(id);\n node = record ? moduleClosureNode(record.input) : null;\n nodes.set(id, node);\n }\n return node;\n };\n const memo = /* @__PURE__ */ new Map();\n const unplanned = [];\n for (const id of [...this.#records.keys()].sort(compareCodeUnits)) {\n const record = this.#records.get(id);\n const digest = moduleClosureDigest(id, lookup, memo);\n const key = digest && planCacheKey(identity, id, digest);\n const entry = key && digest ? await cache.read(key, id, digest) : null;\n if (entry) {\n this.#entries.set(id, this.#entryFor(id, record, entry.plan));\n continue;\n }\n if (key && digest) this.#planKeys.set(id, { key, digest });\n unplanned.push(id);\n }\n return unplanned;\n }\n async #storePlans(ids) {\n const cache = this.#planCache;\n if (!cache) return;\n const pending = ids.flatMap((id) => {\n const entry = this.#entries.get(id);\n const key = this.#planKeys.get(id);\n return entry && key ? [{ id, entry, key }] : [];\n });\n for (let index = 0; index < pending.length; index += 32) {\n await Promise.all(\n pending.slice(index, index + 32).map(\n ({ id, entry, key }) => cache.write(key.key, {\n schemaVersion: PLAN_CACHE_SCHEMA_VERSION,\n moduleId: id,\n closureDigest: key.digest,\n plan: entry.plan\n })\n )\n );\n }\n }\n /** Modules reachable from the bundle's entry, over the frontend's own graph. */\n #reachableFrom(roots) {\n const reached = /* @__PURE__ */ new Set();\n const queue = [...roots];\n while (queue.length) {\n const id = queue.pop();\n if (reached.has(id)) continue;\n reached.add(id);\n for (const dependency of this.#records.get(id)?.input.imports ?? []) {\n if (!dependency.external) queue.push(dependency.resolvedId);\n }\n }\n return reached;\n }\n /**\n * The zero transform for one module, returning a plan whose edits also carry\n * the static Theme lowering, the island bridge, and reference erasure.\n */\n #zeroPlanFor(id, source, plan) {\n const zero = this.config.zero;\n const config = this.#tamaguiConfig;\n if (!zero || !config) return null;\n if (zero.islandBuild) {\n zero.artifact.setIslandModuleCSS(zero.islandBuild, id, plan.css);\n return null;\n }\n if (this.#zeroEntryGraph && !this.#zeroEntryGraph.has(id)) return null;\n const relativePath = relative(this.config.projectRoot, id);\n if (relativePath === \"\" || relativePath.startsWith(\"..\") || relativePath.split(/[\\\\/]/).includes(\"node_modules\")) {\n return null;\n }\n const result = Static.transformZeroModule({\n mode: zero.isEnforcing ? \"enforce\" : \"report\",\n id,\n root: this.config.projectRoot,\n source,\n plan,\n config,\n isTamaguiSpecifier: (specifier) => specifier === \"tamagui\" || specifier.startsWith(\"@tamagui/\"),\n resolveIslandLoader: (specifier) => {\n const islandId = zero.loaderIds.get(zeroModuleKey(resolve(id, \"..\", specifier)));\n return islandId ? { islandId } : null;\n },\n resolveIslandModule: (specifier) => zero.islandModuleIds.get(zeroModuleKey(resolve(id, \"..\", specifier))) ?? null\n });\n zero.transformed.add(id);\n if (result.erased.exports.length) {\n zero.erasedExports.set(id, result.erased.exports);\n }\n for (const violation of result.violations) {\n const { line, column } = Static.offsetToLineColumn(source, violation.span.start);\n zero.violations.push({\n file: relativePath,\n line,\n column,\n rule: violation.rule,\n code: violation.code,\n component: violation.component,\n message: violation.message\n });\n }\n if (result.violations.length || !zero.isEnforcing) return null;\n Static.mergeIslandBridges(zero.bridges, result.bridges);\n for (const [identifier, rules] of result.bridgeCSS) {\n zero.artifact.setBridgeRules(identifier, rules);\n }\n zero.artifact.setZeroModuleCSS(id, plan.css);\n return { ...plan, edits: [...plan.edits, ...result.edits] };\n }\n async #publish(platform) {\n const cache = new MetroCompilerCache(this.cacheRootFor(platform));\n const generation = await cache.publish(\n platform,\n [...this.#entries.values()],\n this.#scanOptionsHash ?? \"\"\n );\n const zero = this.config.zero;\n if (zero && !zero.islandBuild) {\n await cache.publishZeroCSS({\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n generation,\n configCSS: zero.configCSS,\n zeroModuleCSS: Object.fromEntries(zero.artifact.zeroModuleEntries()),\n bridgeCSS: Object.fromEntries(zero.artifact.bridgeEntries()),\n bridges: Object.fromEntries(zero.bridges)\n });\n }\n this.#publishedGeneration = generation;\n return generation;\n }\n /**\n * Restores the zero build's CSS side effects from the sidecar published with\n * this plan generation. Returns false when there is nothing trustworthy to\n * restore, which sends the caller to a full scan.\n */\n async #rehydrateZeroCSS(cache, generation) {\n const zero = this.config.zero;\n if (!zero || zero.islandBuild) return true;\n const sidecar = await cache.readZeroCSS(generation);\n if (!sidecar) return false;\n zero.artifact.clearGraphs();\n zero.bridges.clear();\n zero.violations.length = 0;\n zero.configCSS = sidecar.configCSS;\n for (const [moduleId, css] of Object.entries(sidecar.zeroModuleCSS)) {\n zero.artifact.setZeroModuleCSS(moduleId, css);\n }\n for (const [bridgeId, css] of Object.entries(sidecar.bridgeCSS)) {\n zero.artifact.setBridgeRules(bridgeId, css);\n }\n for (const [islandId, bridges] of Object.entries(sidecar.bridges)) {\n zero.bridges.set(islandId, bridges);\n }\n zero.plansRestoredFromCache = true;\n return true;\n }\n #installWatchers() {\n for (const id of this.#records.keys()) this.#watchModule(id);\n }\n #watchModule(id) {\n if (this.#watchers.has(id)) return;\n try {\n const watcher = watch(id, { persistent: false }, () => {\n void this.updateFile(id);\n });\n watcher.unref();\n this.#watchers.set(id, watcher);\n } catch {\n }\n }\n #report(diagnostic) {\n this.config.reportDiagnostic?.(diagnostic);\n }\n}\nfunction describeMetroCompilerRoot(projectRoot, moduleId) {\n const path = relative(projectRoot, moduleId);\n return path.startsWith(\"..\") ? basename(moduleId) : path;\n}\nexport {\n METRO_RECORD_CACHE_VERSION,\n MetroCompilerFrontend,\n describeMetroCompilerRoot\n};\n//# sourceMappingURL=frontend.js.map\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"frontend.js","names":["#cacheBaseRoot","#resolver","#planCache","#recordCache","#enqueue","#scan","#scanOptions","#publishedGeneration","#loadCompilerProject","#projectGeneration","#scanOptionsHash","#installCaches","#watchers","#records","#compileRecord","#report","#tamaguiConfig","#entries","#restorePlans","#graph","#host","#zeroEntryGraph","#reachableFrom","#refreshEntry","#storePlans","#publish","#installWatchers","#releaseGraph","#ensureValidCache","#sourcesAreFresh","#rehydrateZeroCSS","#addDependency","#watchModule","#operationQueue","#planKeys","#recordCacheIdentity","#babelArgs","#babelOptions","#zeroPlanFor","#entryFor","#planCacheStamp"],"sources":["esm/frontend.js"],"sourcesContent":["import { existsSync, watch } from \"node:fs\";\nimport { readFile, readdir, realpath } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { basename, dirname, join, relative, resolve, sep } from \"node:path\";\nimport ignore from \"ignore\";\nimport {\n JsonFileCache,\n ModulePlanCache,\n PLAN_CACHE_SCHEMA_VERSION,\n ProjectGraph,\n contentHash,\n defaultPlanCacheRoot,\n isTamaguiSpecifier,\n lowerModule,\n materializeModule,\n moduleClosureDigest,\n moduleClosureNode,\n planCacheKey,\n resolvedModuleId,\n stableStringify,\n yukuFactory\n} from \"@tamagui/compiler-core\";\nimport Static, { createTamaguiCompilerHost } from \"@tamagui/static\";\nimport {\n compileWithUserBabel,\n userBabelCacheKey\n} from \"./babel\";\nimport { zeroModuleKey } from \"./zeroRuntime\";\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n defaultMetroCompilerCacheRoot\n} from \"./compilerCache\";\nimport { metroDiagnostic } from \"./diagnostics\";\nimport {\n createMetroCompilerResolver,\n isCompilerSourceFile,\n moduleSpecifiersFromAst\n} from \"./metroResolver\";\nconst METRO_RECORD_CACHE_VERSION = 1;\nfunction compareCodeUnits(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nconst requireFromFrontend = createRequire(\n typeof __filename === \"string\" ? __filename : import.meta.url\n);\nconst compilerImplementationVersions = [\"@tamagui/metro-plugin\", \"@tamagui/static\", \"@tamagui/compiler-core\"].map((packageName) => {\n const { version } = requireFromFrontend(`${packageName}/package.json`);\n return `${packageName}@${version}`;\n});\nfunction scanOptionsHash(options, projectGeneration, projectSourcesHash) {\n return contentHash(JSON.stringify({ options, projectGeneration, projectSourcesHash }));\n}\nconst speculativeWalkExcludedDirs = /* @__PURE__ */ new Set([\n \"__tests__\",\n \"e2e\",\n \"flows\",\n \"plugins\",\n \"screenshots\",\n \"scripts\",\n \"test\",\n \"test-results\",\n \"tests\"\n]);\nasync function walkProjectSources(root) {\n const inherited = [];\n let ancestor = root;\n while (!existsSync(join(ancestor, \".git\"))) {\n const parent = dirname(ancestor);\n if (parent === ancestor) break;\n inherited.unshift(parent);\n ancestor = parent;\n }\n const rootScopes = [];\n for (const dir of inherited) {\n const source = await readFile(join(dir, \".gitignore\"), \"utf8\").catch(() => null);\n if (source) rootScopes.push({ dir, matcher: ignore().add(source) });\n }\n const found = [];\n const stack = [\n { dir: root, scopes: rootScopes }\n ];\n while (stack.length) {\n const { dir, scopes } = stack.pop();\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n continue;\n }\n let active = scopes;\n if (entries.some((entry) => entry.isFile() && entry.name === \".gitignore\")) {\n const source = await readFile(join(dir, \".gitignore\"), \"utf8\").catch(() => null);\n if (source) active = [...scopes, { dir, matcher: ignore().add(source) }];\n }\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue;\n const isDirectory = entry.isDirectory();\n if (isDirectory && speculativeWalkExcludedDirs.has(entry.name)) continue;\n if (!isDirectory && !(entry.isFile() && isCompilerSourceFile(entry.name))) continue;\n if (!isDirectory && (/(?:^|[-.])(?:probe|run|spec|tests?)(?:[-.]|$)/i.test(entry.name) || /\\.(?:build|config|workspace)\\.[cm]?[jt]sx?$/.test(entry.name))) {\n continue;\n }\n const path = join(dir, entry.name);\n let ignored = false;\n for (const scope of active) {\n const relativePath = relative(scope.dir, path);\n if (!relativePath || relativePath.startsWith(\"..\")) continue;\n const candidate = relativePath.split(sep).join(\"/\") + (isDirectory ? \"/\" : \"\");\n if (scope.matcher.ignores(candidate)) {\n ignored = true;\n break;\n }\n }\n if (ignored) continue;\n if (isDirectory) stack.push({ dir: path, scopes: active });\n else found.push(path);\n }\n }\n return found.sort(compareCodeUnits);\n}\nfunction compilerTarget(platform) {\n return platform === \"web\" ? \"web\" : \"native\";\n}\nfunction retainsLiveGraph(options) {\n return options.dev && options.hot;\n}\nclass MetroCompilerFrontend {\n constructor(config) {\n this.config = config;\n this.#cacheBaseRoot = config.cacheRoot ?? defaultMetroCompilerCacheRoot(config.projectRoot);\n this.#resolver = createMetroCompilerResolver(config);\n }\n config;\n #cacheBaseRoot;\n #entries = /* @__PURE__ */ new Map();\n #records = /* @__PURE__ */ new Map();\n #watchers = /* @__PURE__ */ new Map();\n #resolver;\n #graph = null;\n #host = null;\n #projectGeneration = null;\n #publishedGeneration = null;\n #scanOptions = null;\n #scanOptionsHash = null;\n #operationQueue = Promise.resolve();\n #tamaguiConfig = null;\n #zeroEntryGraph = null;\n #planKeys = /* @__PURE__ */ new Map();\n #recordCache = null;\n #recordCacheIdentity = null;\n #planCache = null;\n #planCacheStamp = null;\n get metroResolverVersion() {\n return this.#resolver.version;\n }\n /**\n * Per-file cache accounting for the last scan. The point of these caches is\n * that one edited module leaves every other module's entry valid, and this is\n * how that is observed rather than assumed.\n */\n get compileCacheStats() {\n const empty = { hits: 0, misses: 0, writes: 0 };\n return {\n plans: this.#planCache?.stats ?? empty,\n records: this.#recordCache?.stats ?? empty\n };\n }\n cacheRootFor(platform) {\n return join(this.#cacheBaseRoot, platform ?? \"default\");\n }\n scan(options) {\n return this.#enqueue(() => this.#scan(options));\n }\n async #scan(options, preparedProject, preparedProjectSources) {\n this.#scanOptions = options;\n this.#publishedGeneration = null;\n const diagnostics = [];\n const entryRoots = (await Promise.all(\n options.entryFiles.map((path) => realpath(resolve(this.config.projectRoot, path)))\n )).sort(compareCodeUnits);\n const compilerProject = preparedProject ?? await this.#loadCompilerProject(options, entryRoots[0], diagnostics);\n this.#projectGeneration = compilerProject.generation;\n const projectSources = preparedProjectSources ?? await walkProjectSources(this.config.projectRoot);\n const projectSourcesHash = contentHash(JSON.stringify(projectSources));\n this.#scanOptionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n projectSourcesHash\n );\n this.#installCaches(options, compilerProject, projectSourcesHash);\n const speculativeRoots = /* @__PURE__ */ new Set();\n for (const file of projectSources) {\n try {\n const id = await realpath(file);\n if (!entryRoots.includes(id)) speculativeRoots.add(id);\n } catch {\n }\n }\n const roots = [.../* @__PURE__ */ new Set([...entryRoots, ...speculativeRoots])].sort(\n compareCodeUnits\n );\n const queue = [...roots];\n const queued = new Set(queue);\n for (const watcher of this.#watchers.values()) watcher.close();\n this.#watchers.clear();\n this.#records.clear();\n while (queue.length) {\n const path = queue.shift();\n try {\n const record = await this.#compileRecord(path, options, diagnostics);\n this.#records.set(record.input.id, record);\n for (const dependency of record.input.imports) {\n if (dependency.external || !isCompilerSourceFile(dependency.resolvedId) || queued.has(dependency.resolvedId)) {\n continue;\n }\n queued.add(dependency.resolvedId);\n queue.push(dependency.resolvedId);\n }\n } catch (error) {\n if (speculativeRoots.has(path)) continue;\n const diagnostic = metroDiagnostic(\n \"metro/transform-failed\",\n `Failed to compile ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n );\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n }\n if (!compilerProject.projectInfo.tamaguiConfig || !compilerProject.projectInfo.components) {\n throw new Error(\"Metro compiler project has no Tamagui config or components\");\n }\n this.#tamaguiConfig = compilerProject.projectInfo.tamaguiConfig;\n this.#entries.clear();\n const unplanned = await this.#restorePlans(options);\n const zero = this.config.zero;\n this.#graph = null;\n this.#host = null;\n if (unplanned.length || retainsLiveGraph(options)) {\n this.#graph = new ProjectGraph(yukuFactory, {\n modules: [...this.#records.values()].map(({ input }) => input)\n });\n this.#host = createTamaguiCompilerHost({\n target: compilerTarget(options.platform),\n tamaguiConfig: compilerProject.projectInfo.tamaguiConfig,\n components: compilerProject.projectInfo.components,\n componentModules: compilerProject.componentModules.map(({ moduleName, id }) => ({\n moduleName,\n resolvedId: id\n })),\n disablePartialExtraction: compilerProject.disablePartialExtraction,\n experimentalNativeFastPath: compilerProject.experimentalNativeFastPath,\n zeroRuntime: compilerProject.zeroRuntime\n });\n if (zero) {\n if (zero.isEnforcing) {\n Static.assertZeroConfigDrivers(compilerProject.projectInfo.tamaguiConfig);\n }\n zero.plansRestoredFromCache = false;\n zero.configCSS = compilerProject.projectInfo.tamaguiConfig.getCSS?.() ?? \"\";\n zero.artifact.clearGraphs();\n zero.bridges.clear();\n zero.violations.length = 0;\n zero.transformed.clear();\n zero.erasedExports.clear();\n this.#zeroEntryGraph = this.#reachableFrom(entryRoots.map(resolvedModuleId));\n }\n for (const id of unplanned) this.#refreshEntry(id);\n await this.#storePlans(unplanned);\n }\n if (zero) {\n Static.writeZeroViolationReport(zero.resolved.outDir, \"metro-zero\", {\n integration: \"metro-web\",\n mode: zero.isEnforcing ? \"enforce\" : \"report\",\n violations: zero.violations\n });\n if (zero.isEnforcing && zero.violations.length) {\n throw new Error(Static.formatZeroViolations(zero.violations));\n }\n }\n const totalFound = [...this.#entries.values()].reduce(\n (sum, entry) => sum + entry.plan.stats.found,\n 0\n );\n if (this.#entries.size > 0 && totalFound === 0) {\n const componentNames = compilerProject.componentModules.map(\n ({ moduleName }) => moduleName\n );\n const cjsComponentImporters = [...this.#records.values()].filter(\n (record) => record.requireSpecifiers.some(\n (specifier) => componentNames.some(\n (name) => specifier === name || specifier.startsWith(`${name}/`)\n )\n )\n ).length;\n if (cjsComponentImporters > 0) {\n const diagnostic = metroDiagnostic(\n \"metro/no-linked-components\",\n `The Tamagui compiler linked 0 components across ${this.#entries.size} modules even though ${cjsComponentImporters} module(s) reference ${componentNames.join(\", \")} through require() calls. Metro compiled modules to CommonJS before the compiler could analyze them, so component imports cannot be linked and nothing will be optimized. Enable experimentalImportSupport in your transformer's getTransformOptions (Expo enables it by default) to restore Tamagui compilation.`\n );\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n }\n const generation = await this.#publish(options.platform);\n const moduleIds = [...this.#records.keys()].sort(compareCodeUnits);\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#installWatchers();\n } else if (!retainsLiveGraph(options)) {\n this.#releaseGraph();\n }\n return {\n generation,\n moduleIds,\n diagnostics\n };\n }\n ensureValidCache(options) {\n return this.#enqueue(() => this.#ensureValidCache(options));\n }\n async #ensureValidCache(options) {\n const diagnostics = [];\n const firstEntry = options.entryFiles[0];\n const importer = firstEntry ? await realpath(resolve(this.config.projectRoot, firstEntry)) : this.config.projectRoot;\n const compilerProject = await this.#loadCompilerProject(\n options,\n importer,\n diagnostics\n );\n const cache = new MetroCompilerCache(this.cacheRootFor(options.platform));\n const validation = await cache.validate();\n const projectSources = await walkProjectSources(this.config.projectRoot);\n const optionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n contentHash(JSON.stringify(projectSources))\n );\n if (validation.valid && validation.generation && validation.optionsHash === optionsHash && await this.#sourcesAreFresh(validation.sourceHashes) && (!retainsLiveGraph(options) && !this.#graph || this.#publishedGeneration && this.#scanOptionsHash === optionsHash) && // A zero build owns the one CSS artifact, and its contents are produced by\n // the scan. Reusing a published plan without restoring the artifact would\n // emit one missing every rule this process never collected, while still\n // deriving TAMAGUI_DID_OUTPUT_CSS from it. The sidecar carries exactly\n // those side effects; without it there is nothing safe to reuse.\n await this.#rehydrateZeroCSS(cache, validation.generation)) {\n this.#publishedGeneration = validation.generation;\n this.#scanOptions = options;\n this.#scanOptionsHash = optionsHash;\n this.#projectGeneration = compilerProject.generation;\n return {\n generation: validation.generation,\n moduleIds: validation.moduleIds,\n diagnostics\n };\n }\n for (const diagnostic of validation.diagnostics) this.#report(diagnostic);\n await cache.discardManifest();\n return await this.#scan(options, compilerProject, projectSources);\n }\n async updateFile(path) {\n let result = {\n changed: false,\n affectedIds: [],\n generation: null\n };\n return this.#enqueue(async () => {\n const graph = this.#graph;\n const options = this.#scanOptions;\n if (!graph || !options) return result;\n let record;\n const diagnostics = [];\n try {\n record = await this.#compileRecord(path, options, diagnostics);\n } catch (error) {\n if (error.code === \"ENOENT\") {\n const id = resolvedModuleId(resolve(path));\n const invalidation2 = graph.removeModule(id);\n this.#watchers.get(id)?.close();\n this.#watchers.delete(id);\n this.#records.delete(id);\n this.#entries.delete(id);\n for (const affected of invalidation2.invalidatedIds) {\n if (affected !== id) this.#refreshEntry(affected);\n }\n const generation2 = await this.#publish(options.platform);\n result = {\n changed: invalidation2.changed,\n affectedIds: invalidation2.invalidatedIds,\n generation: generation2\n };\n return result;\n }\n const diagnostic = metroDiagnostic(\n \"metro/transform-failed\",\n `Failed to update ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n );\n this.#report(diagnostic);\n return result;\n }\n for (const dependency of record.input.imports) {\n if (dependency.external || !isCompilerSourceFile(dependency.resolvedId) || this.#records.has(dependency.resolvedId)) {\n continue;\n }\n await this.#addDependency(dependency.resolvedId, options, diagnostics);\n }\n this.#records.set(record.input.id, record);\n const invalidation = graph.updateModule(record.input);\n for (const affected of invalidation.invalidatedIds) this.#refreshEntry(affected);\n const generation = invalidation.changed ? await this.#publish(options.platform) : null;\n result = {\n changed: invalidation.changed,\n affectedIds: invalidation.invalidatedIds,\n generation\n };\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#watchModule(record.input.id);\n }\n return result;\n });\n }\n /** A published plan only applies while every recorded module source is unchanged. */\n async #sourcesAreFresh(sourceHashes) {\n const checks = Object.entries(sourceHashes).map(async ([moduleId, sourceHash]) => {\n try {\n return contentHash(await readFile(moduleId, \"utf8\")) === sourceHash;\n } catch {\n return false;\n }\n });\n return (await Promise.all(checks)).every(Boolean);\n }\n #enqueue(operation) {\n const queued = this.#operationQueue.then(operation);\n this.#operationQueue = queued.then(\n () => void 0,\n () => void 0\n );\n return queued;\n }\n close() {\n return this.#enqueue(async () => {\n this.#releaseGraph();\n });\n }\n #releaseGraph() {\n for (const watcher of this.#watchers.values()) watcher.close();\n this.#watchers.clear();\n this.#entries.clear();\n this.#records.clear();\n this.#planKeys.clear();\n this.#graph = null;\n this.#host = null;\n this.#projectGeneration = null;\n }\n async #loadCompilerProject(options, importer, diagnostics) {\n const target = compilerTarget(options.platform);\n if (this.config.loadCompilerProject) {\n return await this.config.loadCompilerProject(target, options.platform);\n }\n return Static.loadCompilerProject({\n root: this.config.projectRoot,\n target,\n options: this.config.tamaguiOptions ?? {},\n hostVersions: compilerImplementationVersions,\n missingProjectMessage: \"Unable to load the Tamagui project for Metro compilation\",\n generation: (projectInfo, componentModules, normalizedOptions) => {\n return contentHash(\n JSON.stringify({\n cacheVersion: METRO_COMPILER_CACHE_VERSION,\n compilerImplementationVersions,\n componentModules,\n configCss: projectInfo.tamaguiConfig?.getCSS?.() ?? \"\",\n disablePartialExtraction: !!normalizedOptions.disablePartialExtraction,\n experimentalNativeFastPath: target === \"native\" && normalizedOptions.experimental?.nativeFastPath === true,\n target,\n // the host's diagnostics are mode-aware, so a plan built in one mode is\n // not a plan the other mode may reuse\n zeroRuntime: !!this.config.zero\n })\n );\n },\n resolveComponents: async (moduleNames) => {\n const componentModules = [];\n for (const moduleName of moduleNames) {\n try {\n const resolution = this.#resolver.resolve(\n importer,\n { specifier: moduleName, isESMImport: true },\n options.platform\n );\n if (!resolution) continue;\n componentModules.push({ moduleName, id: resolution.resolvedId });\n } catch (error) {\n const diagnostic = metroDiagnostic(\n \"metro/resolve-failed\",\n `Failed to resolve compiler component ${moduleName}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: importer, dependency: moduleName }\n );\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n }\n return componentModules;\n }\n });\n }\n async #compileRecord(rawPath, options, diagnostics) {\n const path = await realpath(resolve(rawPath));\n const source = await readFile(path, \"utf8\");\n const sourceHash = contentHash(source);\n const id = resolvedModuleId(path);\n const cache = this.#recordCache;\n const identity = this.#recordCacheIdentity;\n const key = cache && identity ? contentHash(`${identity}\\0${sourceHash}`) : null;\n if (cache && key) {\n const cached = await cache.read(key, (value) => {\n const entry = value;\n return entry?.schemaVersion === METRO_RECORD_CACHE_VERSION && entry.sourceHash === sourceHash && Array.isArray(entry.imports) && Array.isArray(entry.requireSpecifiers) && Array.isArray(entry.diagnostics) ? entry : null;\n });\n if (cached) {\n for (const diagnostic of cached.diagnostics) {\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n return {\n input: { id, source, imports: cached.imports },\n sourceHash,\n requireSpecifiers: cached.requireSpecifiers\n };\n }\n }\n const args = this.#babelArgs(path, source, options);\n const compiled = await compileWithUserBabel(\n this.config.originalBabelTransformerPath,\n args\n );\n const imports = [];\n const requireSpecifiers = [];\n const recordDiagnostics = [];\n for (const dependency of moduleSpecifiersFromAst(compiled.result.ast)) {\n if (!dependency.isESMImport) requireSpecifiers.push(dependency.specifier);\n try {\n const resolution = this.#resolver.resolve(path, dependency, options.platform);\n if (!resolution) continue;\n imports.push({\n specifier: resolution.specifier,\n resolvedId: resolvedModuleId(resolution.resolvedId),\n external: resolution.external\n });\n } catch (error) {\n recordDiagnostics.push(\n metroDiagnostic(\n \"metro/resolve-failed\",\n `Failed to resolve ${dependency.specifier} from ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path, dependency: dependency.specifier }\n )\n );\n }\n }\n for (const diagnostic of recordDiagnostics) {\n diagnostics.push(diagnostic);\n this.#report(diagnostic);\n }\n if (cache && key) {\n await cache.write(key, {\n schemaVersion: METRO_RECORD_CACHE_VERSION,\n sourceHash,\n imports,\n requireSpecifiers,\n diagnostics: recordDiagnostics\n });\n }\n return {\n // The graph and plans operate on raw source: workers apply plan edits to\n // the raw module before their own Babel pass, so plans never depend on\n // this process's Babel output matching the workers' byte for byte.\n input: { id, source, imports },\n sourceHash,\n requireSpecifiers\n };\n }\n #babelOptions(options) {\n const transformer = this.config.transformer ?? {};\n return {\n ...options.transform,\n dev: options.dev,\n hot: options.hot,\n platform: options.platform,\n projectRoot: this.config.projectRoot,\n enableBabelRCLookup: transformer.enableBabelRCLookup ?? true,\n enableBabelRuntime: transformer.enableBabelRuntime ?? true,\n hermesParser: transformer.hermesParser ?? false,\n publicPath: transformer.publicPath ?? \"/assets\"\n };\n }\n #babelArgs(filename, src, options) {\n return { filename, src, plugins: [], options: this.#babelOptions(options) };\n }\n async #addDependency(id, options, diagnostics, visiting = /* @__PURE__ */ new Set()) {\n if (this.#records.has(id) || visiting.has(id)) return;\n visiting.add(id);\n try {\n const record = await this.#compileRecord(id, options, diagnostics);\n for (const dependency of record.input.imports) {\n if (!dependency.external && isCompilerSourceFile(dependency.resolvedId)) {\n await this.#addDependency(dependency.resolvedId, options, diagnostics, visiting);\n }\n }\n this.#records.set(id, record);\n const invalidation = this.#graph?.updateModule(record.input);\n for (const affected of invalidation?.invalidatedIds ?? [id]) {\n this.#refreshEntry(affected);\n }\n if (this.config.watch !== false && this.#scanOptions && retainsLiveGraph(this.#scanOptions)) {\n this.#watchModule(id);\n }\n } finally {\n visiting.delete(id);\n }\n }\n #refreshEntry(id) {\n const graph = this.#graph;\n const host = this.#host;\n const record = this.#records.get(id);\n if (!graph || !host || !record || !this.#scanOptions || !this.#projectGeneration)\n return;\n const target = compilerTarget(this.#scanOptions.platform);\n const plan = lowerModule({\n module: materializeModule(graph, id),\n source: record.input.source,\n target,\n host,\n options: { projectGeneration: this.#projectGeneration }\n });\n const zeroPlan = this.#zeroPlanFor(id, record.input.source, plan);\n this.#entries.set(id, this.#entryFor(id, record, zeroPlan ?? plan));\n }\n /**\n * One plan becomes one cache entry the same way whether the plan was just\n * lowered or read back off disk, so a restored build reports exactly the\n * diagnostics a fresh one did.\n */\n #entryFor(id, record, plan) {\n return {\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n moduleId: id,\n sourceHash: record.sourceHash,\n plan,\n diagnostics: plan.diagnostics.map(\n ({ code, message, dependencyId, span, component }) => {\n const { line, column } = Static.offsetToLineColumn(\n record.input.source,\n span.start\n );\n return metroDiagnostic(\n code.startsWith(\"linked/\") ? \"metro/resolve-failed\" : \"metro/transform-failed\",\n message,\n { moduleId: id, dependency: dependencyId, span, line, column, component }\n );\n }\n )\n };\n }\n /**\n * Both per-file caches for this scan. A project with no content stamp gets\n * neither: a stamp that cannot see a config change would serve styles built\n * against the old config, so the answer is no cache rather than a partial one.\n *\n * Zero builds opt out of the plan cache because a zero plan is produced\n * alongside side effects that do not travel in the plan - the CSS artifact,\n * the bridge manifest, the violation list - so replaying one module's plan\n * without them would emit an artifact missing its rules.\n */\n #installCaches(options, project, projectSourcesHash) {\n const platform = options.platform ?? \"default\";\n const root = defaultPlanCacheRoot(this.config.projectRoot, platform);\n this.#recordCache = new JsonFileCache(\n join(root, \"records\"),\n METRO_RECORD_CACHE_VERSION\n );\n this.#recordCacheIdentity = contentHash(\n stableStringify({\n schema: METRO_RECORD_CACHE_VERSION,\n resolver: this.#resolver.version,\n babel: userBabelCacheKey(this.config.originalBabelTransformerPath),\n // resolutions depend on which files exist, so the walked source list is\n // part of a record's identity exactly as it is for the plan manifest\n projectSourcesHash,\n platform,\n transform: this.#babelOptions(options)\n })\n );\n const stamp = project.cacheStamp;\n const usePlanCache = typeof stamp === \"string\" && stamp !== \"\" && !this.config.zero;\n this.#planCache = usePlanCache ? new ModulePlanCache(join(root, \"plans\")) : null;\n this.#planCacheStamp = usePlanCache ? stamp : null;\n }\n /**\n * Fills `#entries` from disk for every module whose whole compile input is\n * unchanged, and returns the ids that still have to be compiled. This is the\n * per-file property: one edited module leaves every other module's entry\n * valid, where the plan manifest would have discarded all of them.\n */\n async #restorePlans(options) {\n this.#planKeys.clear();\n const cache = this.#planCache;\n const stamp = this.#planCacheStamp;\n if (!cache || !stamp) return [...this.#records.keys()].sort(compareCodeUnits);\n const target = compilerTarget(options.platform);\n const identity = {\n stamp,\n target,\n structuralPassHash: `${target}-noop-v1`\n };\n const nodes = /* @__PURE__ */ new Map();\n const lookup = (id) => {\n let node = nodes.get(id);\n if (node === void 0) {\n const record = this.#records.get(id);\n node = record ? moduleClosureNode(record.input) : null;\n nodes.set(id, node);\n }\n return node;\n };\n const memo = /* @__PURE__ */ new Map();\n const unplanned = [];\n for (const id of [...this.#records.keys()].sort(compareCodeUnits)) {\n const record = this.#records.get(id);\n const digest = moduleClosureDigest(id, lookup, memo);\n const key = digest && planCacheKey(identity, id, digest);\n const entry = key && digest ? await cache.read(key, id, digest) : null;\n if (entry) {\n this.#entries.set(id, this.#entryFor(id, record, entry.plan));\n continue;\n }\n if (key && digest) this.#planKeys.set(id, { key, digest });\n unplanned.push(id);\n }\n return unplanned;\n }\n async #storePlans(ids) {\n const cache = this.#planCache;\n if (!cache) return;\n const pending = ids.flatMap((id) => {\n const entry = this.#entries.get(id);\n const key = this.#planKeys.get(id);\n return entry && key ? [{ id, entry, key }] : [];\n });\n for (let index = 0; index < pending.length; index += 32) {\n await Promise.all(\n pending.slice(index, index + 32).map(\n ({ id, entry, key }) => cache.write(key.key, {\n schemaVersion: PLAN_CACHE_SCHEMA_VERSION,\n moduleId: id,\n closureDigest: key.digest,\n plan: entry.plan\n })\n )\n );\n }\n }\n /** Modules reachable from the bundle's entry, over the frontend's own graph. */\n #reachableFrom(roots) {\n const reached = /* @__PURE__ */ new Set();\n const queue = [...roots];\n while (queue.length) {\n const id = queue.pop();\n if (reached.has(id)) continue;\n reached.add(id);\n for (const dependency of this.#records.get(id)?.input.imports ?? []) {\n if (!dependency.external) queue.push(dependency.resolvedId);\n }\n }\n return reached;\n }\n /**\n * The zero transform for one module, returning a plan whose edits also carry\n * the static Theme lowering, the island bridge, and reference erasure.\n */\n #zeroPlanFor(id, source, plan) {\n const zero = this.config.zero;\n const config = this.#tamaguiConfig;\n if (!zero || !config) return null;\n if (zero.islandBuild) {\n zero.artifact.setIslandModuleCSS(zero.islandBuild, id, plan.css);\n return null;\n }\n if (this.#zeroEntryGraph && !this.#zeroEntryGraph.has(id)) return null;\n const relativePath = relative(this.config.projectRoot, id);\n if (relativePath === \"\" || relativePath.startsWith(\"..\") || relativePath.split(/[\\\\/]/).includes(\"node_modules\")) {\n return null;\n }\n const result = Static.transformZeroModule({\n mode: zero.isEnforcing ? \"enforce\" : \"report\",\n id,\n root: this.config.projectRoot,\n source,\n plan,\n config,\n isTamaguiSpecifier,\n resolveIslandLoader: (specifier) => {\n const islandId = zero.loaderIds.get(zeroModuleKey(resolve(id, \"..\", specifier)));\n return islandId ? { islandId } : null;\n },\n resolveIslandModule: (specifier) => zero.islandModuleIds.get(zeroModuleKey(resolve(id, \"..\", specifier))) ?? null\n });\n zero.transformed.add(id);\n if (result.erased.exports.length) {\n zero.erasedExports.set(id, result.erased.exports);\n }\n for (const violation of result.violations) {\n const { line, column } = Static.offsetToLineColumn(source, violation.span.start);\n zero.violations.push({\n file: relativePath,\n line,\n column,\n rule: violation.rule,\n code: violation.code,\n component: violation.component,\n message: violation.message\n });\n }\n if (result.violations.length || !zero.isEnforcing) return null;\n Static.mergeIslandBridges(zero.bridges, result.bridges);\n for (const [identifier, rules] of result.bridgeCSS) {\n zero.artifact.setBridgeRules(identifier, rules);\n }\n zero.artifact.setZeroModuleCSS(id, plan.css);\n return { ...plan, edits: [...plan.edits, ...result.edits] };\n }\n async #publish(platform) {\n const cache = new MetroCompilerCache(this.cacheRootFor(platform));\n const generation = await cache.publish(\n platform,\n [...this.#entries.values()],\n this.#scanOptionsHash ?? \"\"\n );\n const zero = this.config.zero;\n if (zero && !zero.islandBuild) {\n await cache.publishZeroCSS({\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n generation,\n configCSS: zero.configCSS,\n zeroModuleCSS: Object.fromEntries(zero.artifact.zeroModuleEntries()),\n bridgeCSS: Object.fromEntries(zero.artifact.bridgeEntries()),\n bridges: Object.fromEntries(zero.bridges)\n });\n }\n this.#publishedGeneration = generation;\n return generation;\n }\n /**\n * Restores the zero build's CSS side effects from the sidecar published with\n * this plan generation. Returns false when there is nothing trustworthy to\n * restore, which sends the caller to a full scan.\n */\n async #rehydrateZeroCSS(cache, generation) {\n const zero = this.config.zero;\n if (!zero || zero.islandBuild) return true;\n const sidecar = await cache.readZeroCSS(generation);\n if (!sidecar) return false;\n zero.artifact.clearGraphs();\n zero.bridges.clear();\n zero.violations.length = 0;\n zero.configCSS = sidecar.configCSS;\n for (const [moduleId, css] of Object.entries(sidecar.zeroModuleCSS)) {\n zero.artifact.setZeroModuleCSS(moduleId, css);\n }\n for (const [bridgeId, css] of Object.entries(sidecar.bridgeCSS)) {\n zero.artifact.setBridgeRules(bridgeId, css);\n }\n for (const [islandId, bridges] of Object.entries(sidecar.bridges)) {\n zero.bridges.set(islandId, bridges);\n }\n zero.plansRestoredFromCache = true;\n return true;\n }\n #installWatchers() {\n for (const id of this.#records.keys()) this.#watchModule(id);\n }\n #watchModule(id) {\n if (this.#watchers.has(id)) return;\n try {\n const watcher = watch(id, { persistent: false }, () => {\n void this.updateFile(id);\n });\n watcher.unref();\n this.#watchers.set(id, watcher);\n } catch {\n }\n }\n #report(diagnostic) {\n this.config.reportDiagnostic?.(diagnostic);\n }\n}\nfunction describeMetroCompilerRoot(projectRoot, moduleId) {\n const path = relative(projectRoot, moduleId);\n return path.startsWith(\"..\") ? basename(moduleId) : path;\n}\nexport {\n METRO_RECORD_CACHE_VERSION,\n MetroCompilerFrontend,\n describeMetroCompilerRoot\n};\n//# sourceMappingURL=frontend.js.map\n"],"mappings":"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"}
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["esm/index.js"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { isAbsolute, join } from \"node:path\";\nimport Static from \"@tamagui/static\";\nimport { defaultMetroCompilerCacheRoot } from \"./compilerCache\";\nimport { applyMetroZeroRuntime } from \"./zeroSerializer\";\nimport { createMetroZeroController } from \"./zeroRuntime\";\nimport { formatMetroCompilerDiagnostic } from \"./diagnostics\";\nimport { MetroCompilerFrontend } from \"./frontend\";\nimport { writeMetroCompilerTransformerBridge } from \"./transformer\";\nimport { composeMetroGetTransformOptions } from \"./transformOptions\";\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError,\n defaultMetroCompilerCacheRoot as defaultMetroCompilerCacheRoot2\n} from \"./compilerCache\";\nconst frontends = /* @__PURE__ */ new WeakMap();\nconst { loadTamaguiBuildConfigSync } = Static;\nconst requireFromPlugin = createRequire(\n typeof __filename === \"string\" ? __filename : import.meta.url\n);\nfunction getMetroCompilerFrontend(metroConfig) {\n return frontends.get(metroConfig) ?? null;\n}\nfunction withTamagui(metroConfig, optionsIn) {\n const {\n compilerCacheRoot,\n zeroIslandBuild,\n zeroPublicDir = \"public\",\n ...tamaguiOptionsIn\n } = optionsIn || {};\n const options = loadTamaguiBuildConfigSync(tamaguiOptionsIn);\n metroConfig.resolver = {\n ...metroConfig.resolver,\n sourceExts: [.../* @__PURE__ */ new Set([...metroConfig.resolver?.sourceExts || [], \"css\"])]\n };\n metroConfig.transformer = {\n ...metroConfig.transformer,\n tamagui: options\n };\n const zeroProjectRoot = metroConfig.projectRoot ?? process.cwd();\n const zero = createMetroZeroController(\n options,\n zeroProjectRoot,\n zeroIslandBuild ?? null,\n zeroPublicDir\n );\n if (zero?.isEnforcing) {\n applyMetroZeroRuntime(metroConfig, zero);\n }\n if (!options.disable) {\n const projectRoot = metroConfig.projectRoot ?? process.cwd();\n const requireFromProject = createRequire(join(projectRoot, \"package.json\"));\n const configuredBabelTransformerPath = metroConfig.transformer.babelTransformerPath ?? \"metro-babel-transformer\";\n const originalBabelTransformerPath = isAbsolute(configuredBabelTransformerPath) ? configuredBabelTransformerPath : requireFromProject.resolve(configuredBabelTransformerPath);\n const cacheBaseRoot = compilerCacheRoot ?? defaultMetroCompilerCacheRoot(projectRoot);\n const frontend = new MetroCompilerFrontend({\n projectRoot,\n resolver: metroConfig.resolver,\n transformer: metroConfig.transformer,\n tamaguiOptions: options,\n originalBabelTransformerPath,\n cacheRoot: cacheBaseRoot,\n zero,\n reportDiagnostic(diagnostic) {\n console.warn(formatMetroCompilerDiagnostic(diagnostic, projectRoot));\n }\n });\n const transformerFactoryPath = requireFromPlugin.resolve(\n \"@tamagui/metro-plugin/transformer\"\n );\n metroConfig.transformer.babelTransformerPath = writeMetroCompilerTransformerBridge(\n transformerFactoryPath,\n {\n cacheBaseRoot,\n originalBabelTransformerPath,\n projectRoot,\n // an integration-owned literal, never an ambient shell value\n runtimeLiteral: zero?.isEnforcing && !zero.islandBuild ? \"zero\" : \"full\"\n }\n );\n const userGetTransformOptions = metroConfig.transformer.getTransformOptions;\n metroConfig.transformer.getTransformOptions = composeMetroGetTransformOptions(\n frontend,\n userGetTransformOptions\n );\n frontends.set(metroConfig, frontend);\n }\n return metroConfig;\n}\nexport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError,\n defaultMetroCompilerCacheRoot2 as defaultMetroCompilerCacheRoot,\n getMetroCompilerFrontend,\n withTamagui\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAM,4BAA4B,IAAI,QAAQ;AAC9C,MAAM,EAAE,+BAA+B;AACvC,MAAM,oBAAoB,cACxB,OAAO,eAAe,WAAW,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["esm/index.js"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { isAbsolute, join } from \"node:path\";\nimport Static from \"@tamagui/static\";\nimport { defaultMetroCompilerCacheRoot } from \"./compilerCache\";\nimport { applyMetroZeroRuntime } from \"./zeroSerializer\";\nimport { createMetroZeroController } from \"./zeroRuntime\";\nimport { formatMetroCompilerDiagnostic } from \"./diagnostics\";\nimport { MetroCompilerFrontend } from \"./frontend\";\nimport { writeMetroCompilerTransformerBridge } from \"./transformer\";\nimport { composeMetroGetTransformOptions } from \"./transformOptions\";\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError,\n defaultMetroCompilerCacheRoot as defaultMetroCompilerCacheRoot2\n} from \"./compilerCache\";\nconst frontends = /* @__PURE__ */ new WeakMap();\nconst { loadTamaguiBuildConfigSync } = Static;\nconst requireFromPlugin = createRequire(\n typeof __filename === \"string\" ? __filename : import.meta.url\n);\nfunction getMetroCompilerFrontend(metroConfig) {\n return frontends.get(metroConfig) ?? null;\n}\nfunction withTamagui(metroConfig, optionsIn) {\n const {\n compilerCacheRoot,\n zeroIslandBuild,\n zeroPublicDir = \"public\",\n ...tamaguiOptionsIn\n } = optionsIn || {};\n const options = loadTamaguiBuildConfigSync(tamaguiOptionsIn);\n metroConfig.resolver = {\n ...metroConfig.resolver,\n sourceExts: [.../* @__PURE__ */ new Set([...metroConfig.resolver?.sourceExts || [], \"css\"])]\n };\n metroConfig.transformer = {\n ...metroConfig.transformer,\n tamagui: options\n };\n const zeroProjectRoot = metroConfig.projectRoot ?? process.cwd();\n const zero = createMetroZeroController(\n options,\n zeroProjectRoot,\n zeroIslandBuild ?? null,\n zeroPublicDir\n );\n if (zero?.isEnforcing) {\n applyMetroZeroRuntime(metroConfig, zero);\n }\n if (!options.disable) {\n const projectRoot = metroConfig.projectRoot ?? process.cwd();\n const requireFromProject = createRequire(join(projectRoot, \"package.json\"));\n const configuredBabelTransformerPath = metroConfig.transformer.babelTransformerPath ?? \"metro-babel-transformer\";\n const originalBabelTransformerPath = isAbsolute(configuredBabelTransformerPath) ? configuredBabelTransformerPath : requireFromProject.resolve(configuredBabelTransformerPath);\n const cacheBaseRoot = compilerCacheRoot ?? defaultMetroCompilerCacheRoot(projectRoot);\n const frontend = new MetroCompilerFrontend({\n projectRoot,\n resolver: metroConfig.resolver,\n transformer: metroConfig.transformer,\n tamaguiOptions: options,\n originalBabelTransformerPath,\n cacheRoot: cacheBaseRoot,\n zero,\n reportDiagnostic(diagnostic) {\n console.warn(formatMetroCompilerDiagnostic(diagnostic, projectRoot));\n }\n });\n const transformerFactoryPath = requireFromPlugin.resolve(\n \"@tamagui/metro-plugin/transformer\"\n );\n metroConfig.transformer.babelTransformerPath = writeMetroCompilerTransformerBridge(\n transformerFactoryPath,\n {\n cacheBaseRoot,\n originalBabelTransformerPath,\n projectRoot,\n // an integration-owned literal, never an ambient shell value\n runtimeLiteral: zero?.isEnforcing && !zero.islandBuild ? \"zero\" : \"full\"\n }\n );\n const userGetTransformOptions = metroConfig.transformer.getTransformOptions;\n metroConfig.transformer.getTransformOptions = composeMetroGetTransformOptions(\n frontend,\n userGetTransformOptions\n );\n frontends.set(metroConfig, frontend);\n }\n return metroConfig;\n}\nexport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError,\n defaultMetroCompilerCacheRoot2 as defaultMetroCompilerCacheRoot,\n getMetroCompilerFrontend,\n withTamagui\n};\n//# sourceMappingURL=index.js.map\n"],"mappings":";;;;;;;;;;;;AAgBA,MAAM,4BAA4B,IAAI,QAAQ;AAC9C,MAAM,EAAE,+BAA+B;AACvC,MAAM,oBAAoB,cACxB,OAAO,eAAe,WAAW,aAAa,YAAY,GAC5D;AACA,SAAS,yBAAyB,aAAa;CAC7C,OAAO,UAAU,IAAI,WAAW,KAAK;AACvC;AACA,SAAS,YAAY,aAAa,WAAW;CAC3C,MAAM,EACJ,mBACA,iBACA,gBAAgB,UAChB,GAAG,qBACD,aAAa,CAAC;CAClB,MAAM,UAAU,2BAA2B,gBAAgB;CAC3D,YAAY,WAAW;EACrB,GAAG,YAAY;EACf,YAAY,CAAC,mBAAmB,IAAI,IAAI,CAAC,GAAG,YAAY,UAAU,cAAc,CAAC,GAAG,KAAK,CAAC,CAAC;CAC7F;CACA,YAAY,cAAc;EACxB,GAAG,YAAY;EACf,SAAS;CACX;CACA,MAAM,kBAAkB,YAAY,eAAe,QAAQ,IAAI;CAC/D,MAAM,OAAO,0BACX,SACA,iBACA,mBAAmB,MACnB,aACF;CACA,IAAI,MAAM,aAAa;EACrB,sBAAsB,aAAa,IAAI;CACzC;CACA,IAAI,CAAC,QAAQ,SAAS;EACpB,MAAM,cAAc,YAAY,eAAe,QAAQ,IAAI;EAC3D,MAAM,qBAAqB,cAAc,KAAK,aAAa,cAAc,CAAC;EAC1E,MAAM,iCAAiC,YAAY,YAAY,wBAAwB;EACvF,MAAM,+BAA+B,WAAW,8BAA8B,IAAI,iCAAiC,mBAAmB,QAAQ,8BAA8B;EAC5K,MAAM,gBAAgB,qBAAqB,8BAA8B,WAAW;EACpF,MAAM,WAAW,IAAI,sBAAsB;GACzC;GACA,UAAU,YAAY;GACtB,aAAa,YAAY;GACzB,gBAAgB;GAChB;GACA,WAAW;GACX;GACA,iBAAiB,YAAY;IAC3B,QAAQ,KAAK,8BAA8B,YAAY,WAAW,CAAC;GACrE;EACF,CAAC;EACD,MAAM,yBAAyB,kBAAkB,QAC/C,mCACF;EACA,YAAY,YAAY,uBAAuB,oCAC7C,wBACA;GACE;GACA;GACA;GAEA,gBAAgB,MAAM,eAAe,CAAC,KAAK,cAAc,SAAS;EACpE,CACF;EACA,MAAM,0BAA0B,YAAY,YAAY;EACxD,YAAY,YAAY,sBAAsB,gCAC5C,UACA,uBACF;EACA,UAAU,IAAI,aAAa,QAAQ;CACrC;CACA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metroResolver.js","names":[],"sources":["esm/metroResolver.js"],"sourcesContent":["import { existsSync, lstatSync, readFileSync, realpathSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, extname, isAbsolute, join, parse, relative, resolve } from \"node:path\";\nfunction compareCodeUnits(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nfunction findClosestPackage(path) {\n let directory = existsSync(path) && statSync(path).isDirectory() ? path : dirname(path);\n const root = parse(directory).root;\n while (true) {\n const packagePath = join(directory, \"package.json\");\n if (existsSync(packagePath)) {\n try {\n return {\n rootPath: directory,\n packageJson: JSON.parse(readFileSync(packagePath, \"utf8\")),\n packageRelativePath: relative(directory, path)\n };\n } catch {\n return null;\n }\n }\n if (directory === root || directory.endsWith(`${join(\"node_modules\")}`)) {\n return null;\n }\n directory = dirname(directory);\n }\n}\nfunction lookup(projectRoot, path) {\n const absolutePath = isAbsolute(path) ? path : resolve(projectRoot, path);\n try {\n const stat = lstatSync(absolutePath);\n const realPath = realpathSync(absolutePath);\n return {\n exists: true,\n type: stat.isDirectory() ? \"d\" : \"f\",\n realPath\n };\n } catch {\n return { exists: false };\n }\n}\nfunction moduleSpecifiersFromAst(ast) {\n const specifiers = /* @__PURE__ */ new Map();\n const seen = /* @__PURE__ */ new Set();\n function add(value, isESMImport) {\n if (typeof value !== \"string\") return;\n specifiers.set(value, (specifiers.get(value) ?? false) || isESMImport);\n }\n function visit(value) {\n if (!value || typeof value !== \"object\") return;\n if (seen.has(value)) return;\n seen.add(value);\n if (Array.isArray(value)) {\n for (const child of value) visit(child);\n return;\n }\n const node = value;\n if (node.type === \"ImportDeclaration\" || node.type === \"ExportAllDeclaration\" || node.type === \"ExportNamedDeclaration\") {\n add(node.source?.value, true);\n } else if (node.type === \"CallExpression\") {\n const first = node.arguments?.[0];\n if (node.callee?.type === \"Import\") {\n add(first?.value, true);\n } else if (node.callee?.type === \"Identifier\" && node.callee.name === \"require\") {\n add(first?.value, false);\n }\n }\n for (const [key, child] of Object.entries(node)) {\n if (key === \"loc\" || key === \"comments\" || key === \"tokens\") continue;\n visit(child);\n }\n }\n visit(ast);\n return [...specifiers].sort(([left], [right]) => compareCodeUnits(left, right)).map(([specifier, isESMImport]) => ({ specifier, isESMImport }));\n}\nfunction createMetroCompilerResolver(config) {\n const requireFromProject = createRequire(join(config.projectRoot, \"package.json\"));\n const resolverPackage = requireFromProject(\"metro-resolver/package.json\");\n if (!resolverPackage.version.startsWith(\"0.84.\")) {\n throw new Error(\n `@tamagui/metro-plugin requires the Metro 0.84 resolver contract, found ${resolverPackage.version}`\n );\n }\n const resolverModule = requireFromProject(\"metro-resolver\");\n const metroResolve = resolverModule.resolve;\n const createDefaultContextModule = requireFromProject(\n \"metro-resolver/private/createDefaultContext\"\n );\n const createDefaultContext = createDefaultContextModule.default ?? createDefaultContextModule;\n const resolver = config.resolver ?? {};\n const fileSystemLookup = (path) => lookup(config.projectRoot, path);\n const getPackage = (packagePath) => {\n try {\n return JSON.parse(readFileSync(packagePath, \"utf8\"));\n } catch {\n return null;\n }\n };\n return {\n version: resolverPackage.version,\n resolve(importer, dependency, platform) {\n const dependencyDescriptor = {\n name: dependency.specifier,\n data: {\n asyncType: null,\n isESMImport: dependency.isESMImport,\n key: dependency.specifier,\n locs: []\n }\n };\n const context = createDefaultContext(\n {\n allowHaste: false,\n assetExts: new Set(resolver.assetExts ?? []),\n customResolverOptions: {},\n dev: true,\n disableHierarchicalLookup: resolver.disableHierarchicalLookup ?? false,\n doesFileExist: (path) => fileSystemLookup(path).type === \"f\",\n extraNodeModules: resolver.extraNodeModules ?? null,\n fileSystemLookup,\n getPackage,\n getPackageForModule: findClosestPackage,\n isESMImport: dependency.isESMImport,\n mainFields: resolver.resolverMainFields ?? [\"react-native\", \"browser\", \"main\"],\n nodeModulesPaths: resolver.nodeModulesPaths ?? [],\n originModulePath: importer,\n preferNativePlatform: true,\n projectRoot: config.projectRoot,\n resolveAsset: () => null,\n resolveHasteModule: () => null,\n resolveHastePackage: () => null,\n resolveRequest: resolver.resolveRequest ?? null,\n sourceExts: resolver.sourceExts ?? [\"js\", \"jsx\", \"json\", \"ts\", \"tsx\"],\n unstable_conditionNames: resolver.unstable_conditionNames ?? [],\n unstable_conditionsByPlatform: resolver.unstable_conditionsByPlatform ?? {},\n unstable_enablePackageExports: resolver.unstable_enablePackageExports ?? true,\n unstable_logWarning: (message) => config.resolver?.unstable_logWarning?.(message)\n },\n dependencyDescriptor\n );\n const result = metroResolve(context, dependency.specifier, platform);\n if (result.type === \"empty\") return null;\n if (result.type !== \"sourceFile\" || !result.filePath) return null;\n const resolvedId = realpathSync(result.filePath);\n return {\n specifier: dependency.specifier,\n resolvedId,\n external: resolvedId.includes(`${join(\"node_modules\")}`)\n };\n }\n };\n}\nfunction isCompilerSourceFile(path) {\n return [\".js\", \".jsx\", \".mjs\", \".cjs\", \".ts\", \".tsx\"].includes(extname(path));\n}\nexport {\n createMetroCompilerResolver,\n isCompilerSourceFile,\n moduleSpecifiersFromAst\n};\n//# sourceMappingURL=metroResolver.js.map\n"],"mappings":";;;;;AAGA,SAAS,iBAAiB,MAAM,OAAO;CACrC,OAAO,OAAO,QAAQ,CAAC,IAAI,OAAO,QAAQ,IAAI;AAChD;AACA,SAAS,mBAAmB,MAAM;CAChC,IAAI,YAAY,WAAW,IAAI,KAAK,SAAS,IAAI,
|
|
1
|
+
{"version":3,"file":"metroResolver.js","names":[],"sources":["esm/metroResolver.js"],"sourcesContent":["import { existsSync, lstatSync, readFileSync, realpathSync, statSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, extname, isAbsolute, join, parse, relative, resolve } from \"node:path\";\nfunction compareCodeUnits(left, right) {\n return left < right ? -1 : left > right ? 1 : 0;\n}\nfunction findClosestPackage(path) {\n let directory = existsSync(path) && statSync(path).isDirectory() ? path : dirname(path);\n const root = parse(directory).root;\n while (true) {\n const packagePath = join(directory, \"package.json\");\n if (existsSync(packagePath)) {\n try {\n return {\n rootPath: directory,\n packageJson: JSON.parse(readFileSync(packagePath, \"utf8\")),\n packageRelativePath: relative(directory, path)\n };\n } catch {\n return null;\n }\n }\n if (directory === root || directory.endsWith(`${join(\"node_modules\")}`)) {\n return null;\n }\n directory = dirname(directory);\n }\n}\nfunction lookup(projectRoot, path) {\n const absolutePath = isAbsolute(path) ? path : resolve(projectRoot, path);\n try {\n const stat = lstatSync(absolutePath);\n const realPath = realpathSync(absolutePath);\n return {\n exists: true,\n type: stat.isDirectory() ? \"d\" : \"f\",\n realPath\n };\n } catch {\n return { exists: false };\n }\n}\nfunction moduleSpecifiersFromAst(ast) {\n const specifiers = /* @__PURE__ */ new Map();\n const seen = /* @__PURE__ */ new Set();\n function add(value, isESMImport) {\n if (typeof value !== \"string\") return;\n specifiers.set(value, (specifiers.get(value) ?? false) || isESMImport);\n }\n function visit(value) {\n if (!value || typeof value !== \"object\") return;\n if (seen.has(value)) return;\n seen.add(value);\n if (Array.isArray(value)) {\n for (const child of value) visit(child);\n return;\n }\n const node = value;\n if (node.type === \"ImportDeclaration\" || node.type === \"ExportAllDeclaration\" || node.type === \"ExportNamedDeclaration\") {\n add(node.source?.value, true);\n } else if (node.type === \"CallExpression\") {\n const first = node.arguments?.[0];\n if (node.callee?.type === \"Import\") {\n add(first?.value, true);\n } else if (node.callee?.type === \"Identifier\" && node.callee.name === \"require\") {\n add(first?.value, false);\n }\n }\n for (const [key, child] of Object.entries(node)) {\n if (key === \"loc\" || key === \"comments\" || key === \"tokens\") continue;\n visit(child);\n }\n }\n visit(ast);\n return [...specifiers].sort(([left], [right]) => compareCodeUnits(left, right)).map(([specifier, isESMImport]) => ({ specifier, isESMImport }));\n}\nfunction createMetroCompilerResolver(config) {\n const requireFromProject = createRequire(join(config.projectRoot, \"package.json\"));\n const resolverPackage = requireFromProject(\"metro-resolver/package.json\");\n if (!resolverPackage.version.startsWith(\"0.84.\")) {\n throw new Error(\n `@tamagui/metro-plugin requires the Metro 0.84 resolver contract, found ${resolverPackage.version}`\n );\n }\n const resolverModule = requireFromProject(\"metro-resolver\");\n const metroResolve = resolverModule.resolve;\n const createDefaultContextModule = requireFromProject(\n \"metro-resolver/private/createDefaultContext\"\n );\n const createDefaultContext = createDefaultContextModule.default ?? createDefaultContextModule;\n const resolver = config.resolver ?? {};\n const fileSystemLookup = (path) => lookup(config.projectRoot, path);\n const getPackage = (packagePath) => {\n try {\n return JSON.parse(readFileSync(packagePath, \"utf8\"));\n } catch {\n return null;\n }\n };\n return {\n version: resolverPackage.version,\n resolve(importer, dependency, platform) {\n const dependencyDescriptor = {\n name: dependency.specifier,\n data: {\n asyncType: null,\n isESMImport: dependency.isESMImport,\n key: dependency.specifier,\n locs: []\n }\n };\n const context = createDefaultContext(\n {\n allowHaste: false,\n assetExts: new Set(resolver.assetExts ?? []),\n customResolverOptions: {},\n dev: true,\n disableHierarchicalLookup: resolver.disableHierarchicalLookup ?? false,\n doesFileExist: (path) => fileSystemLookup(path).type === \"f\",\n extraNodeModules: resolver.extraNodeModules ?? null,\n fileSystemLookup,\n getPackage,\n getPackageForModule: findClosestPackage,\n isESMImport: dependency.isESMImport,\n mainFields: resolver.resolverMainFields ?? [\"react-native\", \"browser\", \"main\"],\n nodeModulesPaths: resolver.nodeModulesPaths ?? [],\n originModulePath: importer,\n preferNativePlatform: true,\n projectRoot: config.projectRoot,\n resolveAsset: () => null,\n resolveHasteModule: () => null,\n resolveHastePackage: () => null,\n resolveRequest: resolver.resolveRequest ?? null,\n sourceExts: resolver.sourceExts ?? [\"js\", \"jsx\", \"json\", \"ts\", \"tsx\"],\n unstable_conditionNames: resolver.unstable_conditionNames ?? [],\n unstable_conditionsByPlatform: resolver.unstable_conditionsByPlatform ?? {},\n unstable_enablePackageExports: resolver.unstable_enablePackageExports ?? true,\n unstable_logWarning: (message) => config.resolver?.unstable_logWarning?.(message)\n },\n dependencyDescriptor\n );\n const result = metroResolve(context, dependency.specifier, platform);\n if (result.type === \"empty\") return null;\n if (result.type !== \"sourceFile\" || !result.filePath) return null;\n const resolvedId = realpathSync(result.filePath);\n return {\n specifier: dependency.specifier,\n resolvedId,\n external: resolvedId.includes(`${join(\"node_modules\")}`)\n };\n }\n };\n}\nfunction isCompilerSourceFile(path) {\n return [\".js\", \".jsx\", \".mjs\", \".cjs\", \".ts\", \".tsx\"].includes(extname(path));\n}\nexport {\n createMetroCompilerResolver,\n isCompilerSourceFile,\n moduleSpecifiersFromAst\n};\n//# sourceMappingURL=metroResolver.js.map\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformer.js","names":[],"sources":["esm/transformer.js"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, realpathSync, renameSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport {\n compileWithUserBabel,\n userBabelCacheKey\n} from \"./babel\";\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError\n} from \"./compilerCache\";\nimport {\n formatMetroCompilerDiagnostic,\n metroDiagnostic\n} from \"./diagnostics\";\nimport { isCompilerSourceFile } from \"./metroResolver\";\nimport { applyMetroCompilerPlan } from \"./lowering\";\nfunction createMetroCompilerTransformer(config) {\n const moduleIdCache = /* @__PURE__ */ new Map();\n const missWarned = /* @__PURE__ */ new Set();\n function cacheModuleId(filename) {\n let id = moduleIdCache.get(filename);\n if (!id) {\n const absolute = isAbsolute(filename) ? filename : resolve(config.projectRoot, filename);\n try {\n id = realpathSync(absolute);\n } catch {\n id = absolute;\n }\n moduleIdCache.set(filename, id);\n }\n return id;\n }\n function planEligible(moduleId) {\n return isCompilerSourceFile(moduleId) && !moduleId.includes(`${join(\"node_modules\")}`) && existsSync(moduleId);\n }\n const runtimeLiteral = config.runtimeLiteral ?? \"full\";\n const inlineRuntimeLiteral = ({ types }) => ({\n visitor: {\n MemberExpression(nodePath) {\n const node = nodePath.node;\n if (node.computed || !types.isIdentifier(node.property, { name: \"TAMAGUI_RUNTIME\" }) || !types.isMemberExpression(node.object) || node.object.computed || !types.isIdentifier(node.object.object, { name: \"process\" }) || !types.isIdentifier(node.object.property, { name: \"env\" })) {\n return;\n }\n nodePath.replaceWith(types.stringLiteral(runtimeLiteral));\n }\n }\n });\n return {\n async transform(argsIn) {\n const args = {\n ...argsIn,\n plugins: [...argsIn.plugins ?? [], inlineRuntimeLiteral]\n };\n const platform = typeof args.options.platform === \"string\" ? args.options.platform : \"default\";\n const cache = new MetroCompilerCache(join(config.cacheBaseRoot, platform));\n let tamagui = {\n cacheHit: false,\n diagnostics: []\n };\n const moduleId = cacheModuleId(args.filename);\n try {\n const entry = await cache.read(moduleId, args.src, (reason, detail) => {\n if (missWarned.has(moduleId) || !planEligible(moduleId)) return;\n missWarned.add(moduleId);\n const diagnostic = metroDiagnostic(\n \"metro/plan-miss\",\n `Lowering plan lookup missed for ${moduleId} (${reason}${detail ? `: ${detail}` : \"\"}); module ships unlowered`,\n { moduleId }\n );\n tamagui.diagnostics.push(diagnostic);\n console.warn(formatMetroCompilerDiagnostic(diagnostic, config.projectRoot));\n });\n if (entry) {\n try {\n const lowered = await applyMetroCompilerPlan(\n { ...args, filename: moduleId },\n entry.plan,\n config.originalBabelTransformerPath\n );\n return {\n ...lowered.compiled.result,\n metadata: {\n ...lowered.compiled.result.metadata,\n tamagui: {\n cacheHit: true,\n diagnostics: entry.diagnostics,\n lowering: lowered.lowering\n }\n }\n };\n } catch (error) {\n const diagnostic = metroDiagnostic(\n \"metro/cache-corrupt\",\n `Cached lowering plan for ${args.filename} could not be applied: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId }\n );\n tamagui = {\n cacheHit: true,\n diagnostics: [...entry.diagnostics, diagnostic]\n };\n console.warn(formatMetroCompilerDiagnostic(diagnostic, config.projectRoot));\n }\n }\n } catch (error) {\n if (!(error instanceof MetroCompilerCacheError)) throw error;\n tamagui.diagnostics.push(error.diagnostic);\n console.warn(formatMetroCompilerDiagnostic(error.diagnostic, config.projectRoot));\n }\n const compiled = await compileWithUserBabel(\n config.originalBabelTransformerPath,\n args\n );\n return {\n ...compiled.result,\n metadata: {\n ...compiled.result.metadata,\n tamagui\n }\n };\n },\n getCacheKey() {\n return createHash(\"sha256\").update(`tamagui-metro-compiler-v${METRO_COMPILER_CACHE_VERSION}`).update(\"\\0\").update(runtimeLiteral).update(\"\\0\").update(userBabelCacheKey(config.originalBabelTransformerPath)).digest(\"hex\");\n }\n };\n}\nfunction writeMetroCompilerTransformerBridge(transformerFactoryPath, config) {\n const serializedConfig = JSON.stringify(config);\n const bridgeHash = createHash(\"sha256\").update(transformerFactoryPath).update(\"\\0\").update(serializedConfig).digest(\"hex\");\n const directory = join(config.cacheBaseRoot, \"bridge\");\n const bridgePath = join(directory, `${bridgeHash}.cjs`);\n const temporaryPath = `${bridgePath}.${process.pid}.tmp`;\n const source = `'use strict'\nmodule.exports = require(${JSON.stringify(\n transformerFactoryPath\n )}).createMetroCompilerTransformer(${serializedConfig})\n`;\n mkdirSync(directory, { recursive: true });\n writeFileSync(temporaryPath, source, \"utf8\");\n renameSync(temporaryPath, bridgePath);\n return bridgePath;\n}\nexport {\n createMetroCompilerTransformer,\n writeMetroCompilerTransformerBridge\n};\n//# sourceMappingURL=transformer.js.map\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"transformer.js","names":[],"sources":["esm/transformer.js"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, realpathSync, renameSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport {\n compileWithUserBabel,\n userBabelCacheKey\n} from \"./babel\";\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n MetroCompilerCacheError\n} from \"./compilerCache\";\nimport {\n formatMetroCompilerDiagnostic,\n metroDiagnostic\n} from \"./diagnostics\";\nimport { isCompilerSourceFile } from \"./metroResolver\";\nimport { applyMetroCompilerPlan } from \"./lowering\";\nfunction createMetroCompilerTransformer(config) {\n const moduleIdCache = /* @__PURE__ */ new Map();\n const missWarned = /* @__PURE__ */ new Set();\n function cacheModuleId(filename) {\n let id = moduleIdCache.get(filename);\n if (!id) {\n const absolute = isAbsolute(filename) ? filename : resolve(config.projectRoot, filename);\n try {\n id = realpathSync(absolute);\n } catch {\n id = absolute;\n }\n moduleIdCache.set(filename, id);\n }\n return id;\n }\n function planEligible(moduleId) {\n return isCompilerSourceFile(moduleId) && !moduleId.includes(`${join(\"node_modules\")}`) && existsSync(moduleId);\n }\n const runtimeLiteral = config.runtimeLiteral ?? \"full\";\n const inlineRuntimeLiteral = ({ types }) => ({\n visitor: {\n MemberExpression(nodePath) {\n const node = nodePath.node;\n if (node.computed || !types.isIdentifier(node.property, { name: \"TAMAGUI_RUNTIME\" }) || !types.isMemberExpression(node.object) || node.object.computed || !types.isIdentifier(node.object.object, { name: \"process\" }) || !types.isIdentifier(node.object.property, { name: \"env\" })) {\n return;\n }\n nodePath.replaceWith(types.stringLiteral(runtimeLiteral));\n }\n }\n });\n return {\n async transform(argsIn) {\n const args = {\n ...argsIn,\n plugins: [...argsIn.plugins ?? [], inlineRuntimeLiteral]\n };\n const platform = typeof args.options.platform === \"string\" ? args.options.platform : \"default\";\n const cache = new MetroCompilerCache(join(config.cacheBaseRoot, platform));\n let tamagui = {\n cacheHit: false,\n diagnostics: []\n };\n const moduleId = cacheModuleId(args.filename);\n try {\n const entry = await cache.read(moduleId, args.src, (reason, detail) => {\n if (missWarned.has(moduleId) || !planEligible(moduleId)) return;\n missWarned.add(moduleId);\n const diagnostic = metroDiagnostic(\n \"metro/plan-miss\",\n `Lowering plan lookup missed for ${moduleId} (${reason}${detail ? `: ${detail}` : \"\"}); module ships unlowered`,\n { moduleId }\n );\n tamagui.diagnostics.push(diagnostic);\n console.warn(formatMetroCompilerDiagnostic(diagnostic, config.projectRoot));\n });\n if (entry) {\n try {\n const lowered = await applyMetroCompilerPlan(\n { ...args, filename: moduleId },\n entry.plan,\n config.originalBabelTransformerPath\n );\n return {\n ...lowered.compiled.result,\n metadata: {\n ...lowered.compiled.result.metadata,\n tamagui: {\n cacheHit: true,\n diagnostics: entry.diagnostics,\n lowering: lowered.lowering\n }\n }\n };\n } catch (error) {\n const diagnostic = metroDiagnostic(\n \"metro/cache-corrupt\",\n `Cached lowering plan for ${args.filename} could not be applied: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId }\n );\n tamagui = {\n cacheHit: true,\n diagnostics: [...entry.diagnostics, diagnostic]\n };\n console.warn(formatMetroCompilerDiagnostic(diagnostic, config.projectRoot));\n }\n }\n } catch (error) {\n if (!(error instanceof MetroCompilerCacheError)) throw error;\n tamagui.diagnostics.push(error.diagnostic);\n console.warn(formatMetroCompilerDiagnostic(error.diagnostic, config.projectRoot));\n }\n const compiled = await compileWithUserBabel(\n config.originalBabelTransformerPath,\n args\n );\n return {\n ...compiled.result,\n metadata: {\n ...compiled.result.metadata,\n tamagui\n }\n };\n },\n getCacheKey() {\n return createHash(\"sha256\").update(`tamagui-metro-compiler-v${METRO_COMPILER_CACHE_VERSION}`).update(\"\\0\").update(runtimeLiteral).update(\"\\0\").update(userBabelCacheKey(config.originalBabelTransformerPath)).digest(\"hex\");\n }\n };\n}\nfunction writeMetroCompilerTransformerBridge(transformerFactoryPath, config) {\n const serializedConfig = JSON.stringify(config);\n const bridgeHash = createHash(\"sha256\").update(transformerFactoryPath).update(\"\\0\").update(serializedConfig).digest(\"hex\");\n const directory = join(config.cacheBaseRoot, \"bridge\");\n const bridgePath = join(directory, `${bridgeHash}.cjs`);\n const temporaryPath = `${bridgePath}.${process.pid}.tmp`;\n const source = `'use strict'\nmodule.exports = require(${JSON.stringify(\n transformerFactoryPath\n )}).createMetroCompilerTransformer(${serializedConfig})\n`;\n mkdirSync(directory, { recursive: true });\n writeFileSync(temporaryPath, source, \"utf8\");\n renameSync(temporaryPath, bridgePath);\n return bridgePath;\n}\nexport {\n createMetroCompilerTransformer,\n writeMetroCompilerTransformerBridge\n};\n//# sourceMappingURL=transformer.js.map\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zeroRuntime.js","names":[],"sources":["esm/zeroRuntime.js"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport Static from \"@tamagui/static\";\nconst ZERO_CSS_FILENAME = \"tamagui-zero.css\";\nconst ZERO_ISLAND_DIRNAME = \"tamagui-islands\";\nconst normalizePath = (value) => value.replace(/\\\\/g, \"/\");\nconst zeroModuleKey = (value) => normalizePath(value).replace(/\\.(?:js|jsx|ts|tsx|mjs|cjs)$/, \"\");\nfunction islandFragmentPath(outDir, islandId) {\n return path.join(outDir, ZERO_ISLAND_DIRNAME, `${islandId}.css`);\n}\nfunction islandBundleHashPath(outDir, islandId) {\n return path.join(outDir, ZERO_ISLAND_DIRNAME, `${islandId}.hash`);\n}\nfunction createMetroZeroController(options, root, islandBuild, publicDirName) {\n const resolved = Static.resolveZeroRuntimeSync(options, root);\n if (resolved.mode === \"off\") return null;\n Static.assertZeroIntegrationSupport(\"metro-web\", resolved);\n const cssHref = `/${ZERO_CSS_FILENAME}`;\n const artifact = new Static.ZeroCSSArtifact(resolved.cssPath);\n artifact.expectIslands(resolved.islands.map((island) => island.id));\n const configPath = path.isAbsolute(options.config || \"\") ? options.config : path.resolve(root, options.config || \"tamagui.config.ts\");\n for (const island of resolved.islands) {\n Static.writeIslandModules({\n island,\n integration: \"metro-web\",\n configPath,\n scriptUrl: `/${ZERO_ISLAND_DIRNAME}/${island.id}.js`,\n cssHref\n });\n }\n return {\n resolved,\n artifact,\n cssHref,\n root,\n publicDir: path.join(root, publicDirName),\n islandBuild,\n bridges: /* @__PURE__ */ new Map(),\n violations: [],\n transformed: /* @__PURE__ */ new Set(),\n erasedExports: /* @__PURE__ */ new Map(),\n isEnforcing: resolved.mode === \"enforce\",\n loaderIds: new Map(\n resolved.islands.map((island) => [zeroModuleKey(island.loader), island.id])\n ),\n islandModuleIds: new Map(\n resolved.islands.map((island) => [zeroModuleKey(island.module), island.id])\n ),\n configCSS: \"\",\n plansRestoredFromCache: false\n };\n}\nfunction writeIslandRuntimeShims(outDir) {\n const directory = path.join(outDir, \"runtime-shim\");\n mkdirSync(directory, { recursive: true });\n const shims = {};\n for (const [specifier, segments] of Object.entries(\n Static.ISLAND_EXTERNAL_GLOBAL_PATHS\n )) {\n const file = path.join(directory, `${specifier.replace(/[^a-zA-Z0-9]+/g, \"_\")}.js`);\n const source = `// generated by @tamagui/metro-plugin zero-runtime. do not edit.\nmodule.exports = globalThis.${segments.join(\n \".\"\n )}\n`;\n if (!existsSync(file) || readFileSync(file, \"utf8\") !== source) {\n writeFileSync(file, source);\n }\n shims[specifier] = file;\n }\n return shims;\n}\nfunction finalizeMetroZero(input) {\n const { controller } = input;\n const outDir = controller.resolved.outDir;\n if (controller.islandBuild) {\n const fragment = [...controller.artifact.islandCSS(controller.islandBuild)].join(\"\");\n const file = islandFragmentPath(outDir, controller.islandBuild);\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, fragment);\n writeFileSync(\n islandBundleHashPath(outDir, controller.islandBuild),\n createHash(\"sha256\").update(input.bundleCode).digest(\"hex\").slice(0, 16)\n );\n return { cssPath: file, hash: \"\", islandOutputHashes: {} };\n }\n controller.artifact.setConfigCSS(controller.configCSS);\n const islandOutputHashes = {};\n for (const island of controller.resolved.islands) {\n const fragment = islandFragmentPath(outDir, island.id);\n if (!existsSync(fragment)) {\n throw new Error(\n `[tamagui zero-runtime] island \"${island.id}\" has not been built. Build every declared island bundle before the zero entry so the one CSS artifact can be finalized.`\n );\n }\n controller.artifact.setIslandModuleCSS(\n island.id,\n island.module,\n readFileSync(fragment, \"utf8\")\n );\n const hashFile = islandBundleHashPath(outDir, island.id);\n islandOutputHashes[island.id] = existsSync(hashFile) ? readFileSync(hashFile, \"utf8\") : \"\";\n }\n const written = controller.artifact.write();\n if (!written.complete) {\n throw new Error(\n `[tamagui zero-runtime] cannot derive TAMAGUI_DID_OUTPUT_CSS: the generated CSS artifact is missing ${written.missing.join(\n \", \"\n )}`\n );\n }\n return { cssPath: written.path, hash: written.hash, islandOutputHashes };\n}\nexport {\n ZERO_CSS_FILENAME,\n ZERO_ISLAND_DIRNAME,\n createMetroZeroController,\n finalizeMetroZero,\n islandBundleHashPath,\n islandFragmentPath,\n writeIslandRuntimeShims,\n zeroModuleKey\n};\n//# sourceMappingURL=zeroRuntime.js.map\n"],"mappings":";;;;;;AAIA,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB,UAAU,MAAM,QAAQ,OAAO,GAAG;AACzD,MAAM,iBAAiB,UAAU,cAAc,KAAK,
|
|
1
|
+
{"version":3,"file":"zeroRuntime.js","names":[],"sources":["esm/zeroRuntime.js"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport Static from \"@tamagui/static\";\nconst ZERO_CSS_FILENAME = \"tamagui-zero.css\";\nconst ZERO_ISLAND_DIRNAME = \"tamagui-islands\";\nconst normalizePath = (value) => value.replace(/\\\\/g, \"/\");\nconst zeroModuleKey = (value) => normalizePath(value).replace(/\\.(?:js|jsx|ts|tsx|mjs|cjs)$/, \"\");\nfunction islandFragmentPath(outDir, islandId) {\n return path.join(outDir, ZERO_ISLAND_DIRNAME, `${islandId}.css`);\n}\nfunction islandBundleHashPath(outDir, islandId) {\n return path.join(outDir, ZERO_ISLAND_DIRNAME, `${islandId}.hash`);\n}\nfunction createMetroZeroController(options, root, islandBuild, publicDirName) {\n const resolved = Static.resolveZeroRuntimeSync(options, root);\n if (resolved.mode === \"off\") return null;\n Static.assertZeroIntegrationSupport(\"metro-web\", resolved);\n const cssHref = `/${ZERO_CSS_FILENAME}`;\n const artifact = new Static.ZeroCSSArtifact(resolved.cssPath);\n artifact.expectIslands(resolved.islands.map((island) => island.id));\n const configPath = path.isAbsolute(options.config || \"\") ? options.config : path.resolve(root, options.config || \"tamagui.config.ts\");\n for (const island of resolved.islands) {\n Static.writeIslandModules({\n island,\n integration: \"metro-web\",\n configPath,\n scriptUrl: `/${ZERO_ISLAND_DIRNAME}/${island.id}.js`,\n cssHref\n });\n }\n return {\n resolved,\n artifact,\n cssHref,\n root,\n publicDir: path.join(root, publicDirName),\n islandBuild,\n bridges: /* @__PURE__ */ new Map(),\n violations: [],\n transformed: /* @__PURE__ */ new Set(),\n erasedExports: /* @__PURE__ */ new Map(),\n isEnforcing: resolved.mode === \"enforce\",\n loaderIds: new Map(\n resolved.islands.map((island) => [zeroModuleKey(island.loader), island.id])\n ),\n islandModuleIds: new Map(\n resolved.islands.map((island) => [zeroModuleKey(island.module), island.id])\n ),\n configCSS: \"\",\n plansRestoredFromCache: false\n };\n}\nfunction writeIslandRuntimeShims(outDir) {\n const directory = path.join(outDir, \"runtime-shim\");\n mkdirSync(directory, { recursive: true });\n const shims = {};\n for (const [specifier, segments] of Object.entries(\n Static.ISLAND_EXTERNAL_GLOBAL_PATHS\n )) {\n const file = path.join(directory, `${specifier.replace(/[^a-zA-Z0-9]+/g, \"_\")}.js`);\n const source = `// generated by @tamagui/metro-plugin zero-runtime. do not edit.\nmodule.exports = globalThis.${segments.join(\n \".\"\n )}\n`;\n if (!existsSync(file) || readFileSync(file, \"utf8\") !== source) {\n writeFileSync(file, source);\n }\n shims[specifier] = file;\n }\n return shims;\n}\nfunction finalizeMetroZero(input) {\n const { controller } = input;\n const outDir = controller.resolved.outDir;\n if (controller.islandBuild) {\n const fragment = [...controller.artifact.islandCSS(controller.islandBuild)].join(\"\");\n const file = islandFragmentPath(outDir, controller.islandBuild);\n mkdirSync(path.dirname(file), { recursive: true });\n writeFileSync(file, fragment);\n writeFileSync(\n islandBundleHashPath(outDir, controller.islandBuild),\n createHash(\"sha256\").update(input.bundleCode).digest(\"hex\").slice(0, 16)\n );\n return { cssPath: file, hash: \"\", islandOutputHashes: {} };\n }\n controller.artifact.setConfigCSS(controller.configCSS);\n const islandOutputHashes = {};\n for (const island of controller.resolved.islands) {\n const fragment = islandFragmentPath(outDir, island.id);\n if (!existsSync(fragment)) {\n throw new Error(\n `[tamagui zero-runtime] island \"${island.id}\" has not been built. Build every declared island bundle before the zero entry so the one CSS artifact can be finalized.`\n );\n }\n controller.artifact.setIslandModuleCSS(\n island.id,\n island.module,\n readFileSync(fragment, \"utf8\")\n );\n const hashFile = islandBundleHashPath(outDir, island.id);\n islandOutputHashes[island.id] = existsSync(hashFile) ? readFileSync(hashFile, \"utf8\") : \"\";\n }\n const written = controller.artifact.write();\n if (!written.complete) {\n throw new Error(\n `[tamagui zero-runtime] cannot derive TAMAGUI_DID_OUTPUT_CSS: the generated CSS artifact is missing ${written.missing.join(\n \", \"\n )}`\n );\n }\n return { cssPath: written.path, hash: written.hash, islandOutputHashes };\n}\nexport {\n ZERO_CSS_FILENAME,\n ZERO_ISLAND_DIRNAME,\n createMetroZeroController,\n finalizeMetroZero,\n islandBundleHashPath,\n islandFragmentPath,\n writeIslandRuntimeShims,\n zeroModuleKey\n};\n//# sourceMappingURL=zeroRuntime.js.map\n"],"mappings":";;;;;;AAIA,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB,UAAU,MAAM,QAAQ,OAAO,GAAG;AACzD,MAAM,iBAAiB,UAAU,cAAc,KAAK,CAAC,CAAC,QAAQ,gCAAgC,EAAE;AAChG,SAAS,mBAAmB,QAAQ,UAAU;CAC5C,OAAO,KAAK,KAAK,QAAQ,qBAAqB,GAAG,SAAS,KAAK;AACjE;AACA,SAAS,qBAAqB,QAAQ,UAAU;CAC9C,OAAO,KAAK,KAAK,QAAQ,qBAAqB,GAAG,SAAS,MAAM;AAClE;AACA,SAAS,0BAA0B,SAAS,MAAM,aAAa,eAAe;CAC5E,MAAM,WAAW,OAAO,uBAAuB,SAAS,IAAI;CAC5D,IAAI,SAAS,SAAS,OAAO,OAAO;CACpC,OAAO,6BAA6B,aAAa,QAAQ;CACzD,MAAM,UAAU,IAAI;CACpB,MAAM,WAAW,IAAI,OAAO,gBAAgB,SAAS,OAAO;CAC5D,SAAS,cAAc,SAAS,QAAQ,KAAK,WAAW,OAAO,EAAE,CAAC;CAClE,MAAM,aAAa,KAAK,WAAW,QAAQ,UAAU,EAAE,IAAI,QAAQ,SAAS,KAAK,QAAQ,MAAM,QAAQ,UAAU,mBAAmB;CACpI,KAAK,MAAM,UAAU,SAAS,SAAS;EACrC,OAAO,mBAAmB;GACxB;GACA,aAAa;GACb;GACA,WAAW,IAAI,oBAAoB,GAAG,OAAO,GAAG;GAChD;EACF,CAAC;CACH;CACA,OAAO;EACL;EACA;EACA;EACA;EACA,WAAW,KAAK,KAAK,MAAM,aAAa;EACxC;EACA,yBAAyB,IAAI,IAAI;EACjC,YAAY,CAAC;EACb,6BAA6B,IAAI,IAAI;EACrC,+BAA+B,IAAI,IAAI;EACvC,aAAa,SAAS,SAAS;EAC/B,WAAW,IAAI,IACb,SAAS,QAAQ,KAAK,WAAW,CAAC,cAAc,OAAO,MAAM,GAAG,OAAO,EAAE,CAAC,CAC5E;EACA,iBAAiB,IAAI,IACnB,SAAS,QAAQ,KAAK,WAAW,CAAC,cAAc,OAAO,MAAM,GAAG,OAAO,EAAE,CAAC,CAC5E;EACA,WAAW;EACX,wBAAwB;CAC1B;AACF;AACA,SAAS,wBAAwB,QAAQ;CACvC,MAAM,YAAY,KAAK,KAAK,QAAQ,cAAc;CAClD,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;CACxC,MAAM,QAAQ,CAAC;CACf,KAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QACzC,OAAO,4BACT,GAAG;EACD,MAAM,OAAO,KAAK,KAAK,WAAW,GAAG,UAAU,QAAQ,kBAAkB,GAAG,EAAE,IAAI;EAClF,MAAM,SAAS;8BACW,SAAS,KACjC,GACF,EAAE;;EAEF,IAAI,CAAC,WAAW,IAAI,KAAK,aAAa,MAAM,MAAM,MAAM,QAAQ;GAC9D,cAAc,MAAM,MAAM;EAC5B;EACA,MAAM,aAAa;CACrB;CACA,OAAO;AACT;AACA,SAAS,kBAAkB,OAAO;CAChC,MAAM,EAAE,eAAe;CACvB,MAAM,SAAS,WAAW,SAAS;CACnC,IAAI,WAAW,aAAa;EAC1B,MAAM,WAAW,CAAC,GAAG,WAAW,SAAS,UAAU,WAAW,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE;EACnF,MAAM,OAAO,mBAAmB,QAAQ,WAAW,WAAW;EAC9D,UAAU,KAAK,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;EACjD,cAAc,MAAM,QAAQ;EAC5B,cACE,qBAAqB,QAAQ,WAAW,WAAW,GACnD,WAAW,QAAQ,CAAC,CAAC,OAAO,MAAM,UAAU,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE,CACzE;EACA,OAAO;GAAE,SAAS;GAAM,MAAM;GAAI,oBAAoB,CAAC;EAAE;CAC3D;CACA,WAAW,SAAS,aAAa,WAAW,SAAS;CACrD,MAAM,qBAAqB,CAAC;CAC5B,KAAK,MAAM,UAAU,WAAW,SAAS,SAAS;EAChD,MAAM,WAAW,mBAAmB,QAAQ,OAAO,EAAE;EACrD,IAAI,CAAC,WAAW,QAAQ,GAAG;GACzB,MAAM,IAAI,MACR,kCAAkC,OAAO,GAAG,yHAC9C;EACF;EACA,WAAW,SAAS,mBAClB,OAAO,IACP,OAAO,QACP,aAAa,UAAU,MAAM,CAC/B;EACA,MAAM,WAAW,qBAAqB,QAAQ,OAAO,EAAE;EACvD,mBAAmB,OAAO,MAAM,WAAW,QAAQ,IAAI,aAAa,UAAU,MAAM,IAAI;CAC1F;CACA,MAAM,UAAU,WAAW,SAAS,MAAM;CAC1C,IAAI,CAAC,QAAQ,UAAU;EACrB,MAAM,IAAI,MACR,sGAAsG,QAAQ,QAAQ,KACpH,IACF,GACF;CACF;CACA,OAAO;EAAE,SAAS,QAAQ;EAAM,MAAM,QAAQ;EAAM;CAAmB;AACzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zeroSerializer.js","names":[],"sources":["esm/zeroSerializer.js"],"sourcesContent":["import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport Static from \"@tamagui/static\";\nimport {\n finalizeMetroZero,\n writeIslandRuntimeShims,\n ZERO_CSS_FILENAME\n} from \"./zeroRuntime\";\nconst requireFromPlugin = createRequire(\n typeof __filename === \"string\" ? __filename : import.meta.url\n);\nconst baseJSBundle = requireFromPlugin(\n \"metro/private/DeltaBundler/Serializers/baseJSBundle\"\n).default;\nconst bundleToString = requireFromPlugin(\"metro/private/lib/bundleToString\").default;\nfunction applyMetroZeroRuntime(metroConfig, zero) {\n if (zero.islandBuild) {\n const shims = writeIslandRuntimeShims(zero.resolved.outDir);\n const userResolveRequest = metroConfig.resolver?.resolveRequest;\n metroConfig.resolver = {\n ...metroConfig.resolver,\n resolveRequest(context, moduleName, platform) {\n const shim = shims[moduleName];\n if (shim) return { type: \"sourceFile\", filePath: shim };\n return userResolveRequest ? userResolveRequest(context, moduleName, platform) : context.resolveRequest(context, moduleName, platform);\n }\n };\n }\n const userSerializer = metroConfig.serializer?.customSerializer;\n metroConfig.serializer = {\n ...metroConfig.serializer,\n async customSerializer(entryPoint, preModules, graph, opts) {\n const receipt = checkGraph(zero, entryPoint, graph);\n const output = userSerializer ? await userSerializer(entryPoint, preModules, graph, opts) : bundleToString(baseJSBundle(entryPoint, preModules, graph, opts)).code;\n const finalized = finalizeMetroZero({\n controller: zero,\n bundleCode: typeof output === \"string\" ? output : \"\"\n });\n if (!zero.islandBuild) {\n mkdirSync(zero.publicDir, { recursive: true });\n const css = zero.artifact.css();\n const published = path.join(zero.publicDir, ZERO_CSS_FILENAME);\n writeFileSync(published, css);\n const publishFailure = Static.checkGlobalCSSArtifact({\n cssPath: published,\n expectedCSS: css,\n loadedModuleIds: [published],\n importHint: \"\"\n });\n if (publishFailure) throw new Error(publishFailure.message);\n receipt.cssArtifact = { path: zero.cssHref, hash: finalized.hash };\n receipt.gzip = {\n [ZERO_CSS_FILENAME]: gzipSync(Buffer.from(css), { level: 9 }).length,\n bundle: gzipSync(Buffer.from(typeof output === \"string\" ? output : \"\"), {\n level: 9\n }).length\n };\n const bridgeManifest = Static.canonicalizeBridgeManifest(\n Object.fromEntries(\n [...zero.bridges.entries()].sort(([left], [right]) => left < right ? -1 : 1)\n )\n );\n const identityInputs = {\n runtimeLiteral: \"zero\",\n target: \"web\",\n configGeneration: Static.hashBridgeManifest(zero.configCSS),\n cssHash: finalized.hash,\n compilerVersion: Static.ZERO_COMPILER_VERSION,\n islandEntries: zero.resolved.islands.map((island) => island.module),\n bridgeManifestHash: Static.hashBridgeManifest(bridgeManifest),\n islandOutputHashes: finalized.islandOutputHashes\n };\n receipt.identity = Static.hashZeroIdentity(identityInputs);\n receipt.plansRestoredFromCache = zero.plansRestoredFromCache;\n Static.writeZeroGraphReceipt(zero.resolved.outDir, \"metro-zero\", receipt);\n writeFileSync(\n path.join(zero.resolved.outDir, \"metro-zero.bridges.json\"),\n `${JSON.stringify(\n { identity: receipt.identity, identityInputs, bridges: bridgeManifest },\n null,\n 2\n )}\n`\n );\n if (receipt.forbidden.length) {\n throw new Error(Static.formatZeroGraphFailure(receipt));\n }\n console.info(\n ` \\u27A1 [tamagui zero-runtime] ${receipt.moduleCount} modules, 0 forbidden, css ${receipt.gzip[ZERO_CSS_FILENAME]} gzip, islands: ${zero.resolved.islands.map((island) => island.id).join(\", \") || \"none\"}`\n );\n }\n return output;\n }\n };\n}\nfunction checkGraph(zero, entryPoint, graph) {\n const modules = [];\n const importerEdges = /* @__PURE__ */ new Map();\n for (const [id, module] of graph.dependencies) {\n const importers = [...module.inverseDependencies ?? []];\n importerEdges.set(id, importers);\n modules.push({ id, importers });\n }\n const escape = Static.erasedExportEscape({\n integration: \"metro-web\",\n transformed: zero.transformed,\n erasedExports: zero.erasedExports,\n importersOf: importerEdges\n });\n if (escape) throw new Error(escape);\n const checked = Static.checkZeroGraph({\n entries: [entryPoint],\n modules,\n importerEdges,\n root: zero.resolved.root\n });\n return {\n integration: \"metro-web\",\n graph: zero.islandBuild ? \"island\" : \"zero\",\n entries: [entryPoint],\n moduleCount: modules.length,\n tamaguiModules: checked.tamaguiModules,\n forbidden: checked.forbidden,\n cssArtifact: null,\n identity: \"\"\n };\n}\nexport {\n applyMetroZeroRuntime\n};\n//# sourceMappingURL=zeroSerializer.js.map\n"],"mappings":";;;;;;;;AAUA,MAAM,oBAAoB,cACxB,OAAO,eAAe,WAAW,aAAa,
|
|
1
|
+
{"version":3,"file":"zeroSerializer.js","names":[],"sources":["esm/zeroSerializer.js"],"sourcesContent":["import { mkdirSync, writeFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { gzipSync } from \"node:zlib\";\nimport Static from \"@tamagui/static\";\nimport {\n finalizeMetroZero,\n writeIslandRuntimeShims,\n ZERO_CSS_FILENAME\n} from \"./zeroRuntime\";\nconst requireFromPlugin = createRequire(\n typeof __filename === \"string\" ? __filename : import.meta.url\n);\nconst baseJSBundle = requireFromPlugin(\n \"metro/private/DeltaBundler/Serializers/baseJSBundle\"\n).default;\nconst bundleToString = requireFromPlugin(\"metro/private/lib/bundleToString\").default;\nfunction applyMetroZeroRuntime(metroConfig, zero) {\n if (zero.islandBuild) {\n const shims = writeIslandRuntimeShims(zero.resolved.outDir);\n const userResolveRequest = metroConfig.resolver?.resolveRequest;\n metroConfig.resolver = {\n ...metroConfig.resolver,\n resolveRequest(context, moduleName, platform) {\n const shim = shims[moduleName];\n if (shim) return { type: \"sourceFile\", filePath: shim };\n return userResolveRequest ? userResolveRequest(context, moduleName, platform) : context.resolveRequest(context, moduleName, platform);\n }\n };\n }\n const userSerializer = metroConfig.serializer?.customSerializer;\n metroConfig.serializer = {\n ...metroConfig.serializer,\n async customSerializer(entryPoint, preModules, graph, opts) {\n const receipt = checkGraph(zero, entryPoint, graph);\n const output = userSerializer ? await userSerializer(entryPoint, preModules, graph, opts) : bundleToString(baseJSBundle(entryPoint, preModules, graph, opts)).code;\n const finalized = finalizeMetroZero({\n controller: zero,\n bundleCode: typeof output === \"string\" ? output : \"\"\n });\n if (!zero.islandBuild) {\n mkdirSync(zero.publicDir, { recursive: true });\n const css = zero.artifact.css();\n const published = path.join(zero.publicDir, ZERO_CSS_FILENAME);\n writeFileSync(published, css);\n const publishFailure = Static.checkGlobalCSSArtifact({\n cssPath: published,\n expectedCSS: css,\n loadedModuleIds: [published],\n importHint: \"\"\n });\n if (publishFailure) throw new Error(publishFailure.message);\n receipt.cssArtifact = { path: zero.cssHref, hash: finalized.hash };\n receipt.gzip = {\n [ZERO_CSS_FILENAME]: gzipSync(Buffer.from(css), { level: 9 }).length,\n bundle: gzipSync(Buffer.from(typeof output === \"string\" ? output : \"\"), {\n level: 9\n }).length\n };\n const bridgeManifest = Static.canonicalizeBridgeManifest(\n Object.fromEntries(\n [...zero.bridges.entries()].sort(([left], [right]) => left < right ? -1 : 1)\n )\n );\n const identityInputs = {\n runtimeLiteral: \"zero\",\n target: \"web\",\n configGeneration: Static.hashBridgeManifest(zero.configCSS),\n cssHash: finalized.hash,\n compilerVersion: Static.ZERO_COMPILER_VERSION,\n islandEntries: zero.resolved.islands.map((island) => island.module),\n bridgeManifestHash: Static.hashBridgeManifest(bridgeManifest),\n islandOutputHashes: finalized.islandOutputHashes\n };\n receipt.identity = Static.hashZeroIdentity(identityInputs);\n receipt.plansRestoredFromCache = zero.plansRestoredFromCache;\n Static.writeZeroGraphReceipt(zero.resolved.outDir, \"metro-zero\", receipt);\n writeFileSync(\n path.join(zero.resolved.outDir, \"metro-zero.bridges.json\"),\n `${JSON.stringify(\n { identity: receipt.identity, identityInputs, bridges: bridgeManifest },\n null,\n 2\n )}\n`\n );\n if (receipt.forbidden.length) {\n throw new Error(Static.formatZeroGraphFailure(receipt));\n }\n console.info(\n ` \\u27A1 [tamagui zero-runtime] ${receipt.moduleCount} modules, 0 forbidden, css ${receipt.gzip[ZERO_CSS_FILENAME]} gzip, islands: ${zero.resolved.islands.map((island) => island.id).join(\", \") || \"none\"}`\n );\n }\n return output;\n }\n };\n}\nfunction checkGraph(zero, entryPoint, graph) {\n const modules = [];\n const importerEdges = /* @__PURE__ */ new Map();\n for (const [id, module] of graph.dependencies) {\n const importers = [...module.inverseDependencies ?? []];\n importerEdges.set(id, importers);\n modules.push({ id, importers });\n }\n const escape = Static.erasedExportEscape({\n integration: \"metro-web\",\n transformed: zero.transformed,\n erasedExports: zero.erasedExports,\n importersOf: importerEdges\n });\n if (escape) throw new Error(escape);\n const checked = Static.checkZeroGraph({\n entries: [entryPoint],\n modules,\n importerEdges,\n root: zero.resolved.root\n });\n return {\n integration: \"metro-web\",\n graph: zero.islandBuild ? \"island\" : \"zero\",\n entries: [entryPoint],\n moduleCount: modules.length,\n tamaguiModules: checked.tamaguiModules,\n forbidden: checked.forbidden,\n cssArtifact: null,\n identity: \"\"\n };\n}\nexport {\n applyMetroZeroRuntime\n};\n//# sourceMappingURL=zeroSerializer.js.map\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tamagui/metro-plugin",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.719.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"source": "src/index.ts",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
44
|
-
"@tamagui/compiler-core": "3.0.0-beta.
|
|
45
|
-
"@tamagui/static": "3.0.0-beta.
|
|
44
|
+
"@tamagui/compiler-core": "3.0.0-beta.719.1",
|
|
45
|
+
"@tamagui/static": "3.0.0-beta.719.1",
|
|
46
46
|
"ignore": "^5.3.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@tamagui/build": "3.0.0-beta.
|
|
49
|
+
"@tamagui/build": "3.0.0-beta.719.1",
|
|
50
50
|
"metro": "0.84.4",
|
|
51
51
|
"metro-resolver": "0.84.4"
|
|
52
52
|
},
|
package/src/frontend.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
ProjectGraph,
|
|
13
13
|
contentHash,
|
|
14
14
|
defaultPlanCacheRoot,
|
|
15
|
+
isTamaguiSpecifier,
|
|
15
16
|
lowerModule,
|
|
16
17
|
materializeModule,
|
|
17
18
|
moduleClosureDigest,
|
|
@@ -1063,8 +1064,7 @@ export class MetroCompilerFrontend {
|
|
|
1063
1064
|
source,
|
|
1064
1065
|
plan,
|
|
1065
1066
|
config,
|
|
1066
|
-
isTamaguiSpecifier
|
|
1067
|
-
specifier === 'tamagui' || specifier.startsWith('@tamagui/'),
|
|
1067
|
+
isTamaguiSpecifier,
|
|
1068
1068
|
resolveIslandLoader: (specifier) => {
|
|
1069
1069
|
const islandId = zero.loaderIds.get(zeroModuleKey(resolve(id, '..', specifier)))
|
|
1070
1070
|
return islandId ? { islandId } : null
|
package/types/frontend.d.ts.map
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"mappings": "AAOA,
|
|
2
|
+
"mappings": "AAOA,cAiBO,sBAMA;AACP,OAAO,YAA2C;AAClD,cAEE,sBAEK;AAOP,cAA6B,2BAA2B;AAOxD,cAA+B,+BAA+B;AAC9D,cAIO,2BACA;;;;;;;AAeP,OAAO,cAAM,6BAA6B;AAW1C,iBAAiB,oCAAoC,oBAAoB;CACvE;;CAEA,OAAO;CACP;CACA,cAAc;CACd,iBAAiB,QAAQ;CACzB,uBACE,QAAQ,gBACR,4BACG,QAAQ;CACb;CACA,oBAAoB,YAAY;;AAGlC,iBAAiB,6BAA6B,OAAO,gBAAgB;AAErE,iBAAiB,yBAAyB;CACxC;CACA;CACA;CACA;CACA,YAAY;;AAGd,iBAAiB,wBAAwB;CACvC;CACA;CACA,aAAa;;AAGf,iBAAiB,oBAAoB;CACnC;CACA;CACA;;AAuIF,OAAO,cAAM,sBAAsB;;CAqBrB,iBAAiB;CAA7B,YAAY,AAAS,QAAQ;CAM7B,IAAI;;;;;;CASJ,IAAI,qBAAqB;EACvB,OAAO;GAAE;GAAc;GAAgB;;EACvC,SAAS;GAAE;GAAc;GAAgB;;;CAS3C,aAAa;CAIb,KAAK,SAAS,2BAA2B,QAAQ;CAyLjD,iBAAiB,SAAS,2BAA2B,QAAQ;CAsD7D,AAAM,WAAW,eAAe,QAAQ;CA2FxC,SAAS;;AA8hBX,OAAO,iBAAS,0BAA0B,qBAAqB",
|
|
3
3
|
"names": [],
|
|
4
4
|
"sources": [
|
|
5
5
|
"src/frontend.ts"
|
|
6
6
|
],
|
|
7
7
|
"version": 3,
|
|
8
8
|
"sourcesContent": [
|
|
9
|
-
"import { existsSync, watch, type FSWatcher } from 'node:fs'\nimport { readFile, readdir, realpath } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, relative, resolve, sep } from 'node:path'\n\nimport ignore, { type Ignore } from 'ignore'\n\nimport {\n JsonFileCache,\n ModulePlanCache,\n PLAN_CACHE_SCHEMA_VERSION,\n ProjectGraph,\n contentHash,\n defaultPlanCacheRoot,\n lowerModule,\n materializeModule,\n moduleClosureDigest,\n moduleClosureNode,\n planCacheKey,\n resolvedModuleId,\n stableStringify,\n yukuFactory,\n type CompilerLoweringHost,\n type CompilerTarget,\n type HostModuleInput,\n type HostResolvedImport,\n type LoweredModulePlan,\n type ModuleClosureNode,\n type ResolvedModuleId,\n} from '@tamagui/compiler-core'\nimport Static, { createTamaguiCompilerHost } from '@tamagui/static'\nimport type {\n IslandThemeBridge,\n TamaguiOptions,\n TamaguiProjectInfo,\n} from '@tamagui/static'\n\nimport {\n compileWithUserBabel,\n userBabelCacheKey,\n type MetroBabelTransformArgs,\n} from './babel'\nimport { zeroModuleKey, type MetroZeroController } from './zeroRuntime'\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n defaultMetroCompilerCacheRoot,\n type MetroCompilerCacheEntry,\n} from './compilerCache'\nimport { metroDiagnostic, type MetroCompilerDiagnostic } from './diagnostics'\nimport {\n createMetroCompilerResolver,\n isCompilerSourceFile,\n moduleSpecifiersFromAst,\n type MetroResolverConfig,\n} from './metroResolver'\n\ninterface CompiledRecord {\n input: HostModuleInput\n sourceHash: string\n /** Specifiers that reached the compiled output as require() calls instead of imports. */\n requireSpecifiers: string[]\n}\n\n/**\n * Metro runs the user's whole Babel transformer over every project source just\n * to read its import specifiers, which is the single most expensive step of the\n * prepass. The result is a pure function of the module's own bytes plus the\n * resolver and Babel identity, so it caches per file with no closure involved.\n */\nexport const METRO_RECORD_CACHE_VERSION = 1\n\ninterface CachedRecord {\n schemaVersion: typeof METRO_RECORD_CACHE_VERSION\n sourceHash: string\n imports: HostResolvedImport[]\n requireSpecifiers: string[]\n /** Resolve failures replayed on a hit, so a cached record reports what a fresh one did. */\n diagnostics: MetroCompilerDiagnostic[]\n}\n\nexport interface MetroCompilerFrontendConfig extends MetroResolverConfig {\n cacheRoot?: string\n /** Present only for an enforced zero-runtime web build. */\n zero?: MetroZeroController | null\n originalBabelTransformerPath: string\n transformer?: Record<string, any>\n tamaguiOptions?: Partial<TamaguiOptions>\n loadCompilerProject?: (\n target: CompilerTarget,\n platform: string | null\n ) => Promise<MetroCompilerProject>\n watch?: boolean\n reportDiagnostic?: (diagnostic: MetroCompilerDiagnostic) => void\n}\n\nexport interface MetroCompilerProject extends Static.CompilerProject {}\n\nexport interface MetroCompilerScanOptions {\n dev: boolean\n entryFiles: readonly string[]\n hot: boolean\n platform: string | null\n transform?: Record<string, any>\n}\n\nexport interface MetroCompilerGeneration {\n generation: string\n moduleIds: string[]\n diagnostics: MetroCompilerDiagnostic[]\n}\n\nexport interface MetroCompilerUpdate {\n changed: boolean\n affectedIds: string[]\n generation: string | null\n}\n\nfunction compareCodeUnits(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0\n}\n\nconst requireFromFrontend = createRequire(\n typeof __filename === 'string' ? __filename : import.meta.url\n)\n\n// upgrading the compiler must invalidate published plans even when the Tamagui\n// config output is unchanged\nconst compilerImplementationVersions = (\n ['@tamagui/metro-plugin', '@tamagui/static', '@tamagui/compiler-core'] as const\n).map((packageName) => {\n const { version } = requireFromFrontend(`${packageName}/package.json`) as {\n version: string\n }\n return `${packageName}@${version}`\n})\n\nfunction scanOptionsHash(\n options: MetroCompilerScanOptions,\n projectGeneration: string,\n projectSourcesHash: string\n): string {\n return contentHash(JSON.stringify({ options, projectGeneration, projectSourcesHash }))\n}\n\n// Metro entries can live inside node_modules (expo-router's entry reaches app\n// source only through require.context), so reachability from the entry alone\n// discovers nothing there. Project source is walked directly and seeded into\n// the scan alongside the entry; imports then extend the graph outside the\n// project root (workspace packages) exactly as before.\n//\n// The walked list is both the seed set and the plan cache's options hash, so it\n// has to be authored source only. Build output is whatever the project already\n// declares as ignored, read with git's own rules: a directory-name list cannot\n// know that `dist-metro`, `out` or `public/assets` are output, and a sibling\n// bundler's content-hashed filenames then re-key the plan cache on every\n// unrelated rebuild, forcing Metro to rescan a project that never changed.\n// `node_modules` is skipped structurally instead, because that is the same\n// externality boundary the resolver draws and it must hold with or without a\n// declaration.\ninterface IgnoreScope {\n dir: string\n matcher: Ignore\n}\n\nconst speculativeWalkExcludedDirs = new Set([\n '__tests__',\n 'e2e',\n 'flows',\n 'plugins',\n 'screenshots',\n 'scripts',\n 'test',\n 'test-results',\n 'tests',\n])\n\nasync function walkProjectSources(root: string): Promise<string[]> {\n // git reads every .gitignore from the repository root down to the file, so an\n // app nested in a monorepo inherits the declarations made above it\n const inherited: string[] = []\n let ancestor = root\n while (!existsSync(join(ancestor, '.git'))) {\n const parent = dirname(ancestor)\n if (parent === ancestor) break\n inherited.unshift(parent)\n ancestor = parent\n }\n const rootScopes: IgnoreScope[] = []\n for (const dir of inherited) {\n const source = await readFile(join(dir, '.gitignore'), 'utf8').catch(() => null)\n if (source) rootScopes.push({ dir, matcher: ignore().add(source) })\n }\n\n const found: string[] = []\n const stack: { dir: string; scopes: IgnoreScope[] }[] = [\n { dir: root, scopes: rootScopes },\n ]\n while (stack.length) {\n const { dir, scopes } = stack.pop()!\n let entries\n try {\n entries = await readdir(dir, { withFileTypes: true })\n } catch {\n continue\n }\n let active = scopes\n if (entries.some((entry) => entry.isFile() && entry.name === '.gitignore')) {\n const source = await readFile(join(dir, '.gitignore'), 'utf8').catch(() => null)\n if (source) active = [...scopes, { dir, matcher: ignore().add(source) }]\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.') || entry.name === 'node_modules') continue\n const isDirectory = entry.isDirectory()\n if (isDirectory && speculativeWalkExcludedDirs.has(entry.name)) continue\n if (!isDirectory && !(entry.isFile() && isCompilerSourceFile(entry.name))) continue\n if (\n !isDirectory &&\n (/(?:^|[-.])(?:probe|run|spec|tests?)(?:[-.]|$)/i.test(entry.name) ||\n /\\.(?:build|config|workspace)\\.[cm]?[jt]sx?$/.test(entry.name))\n ) {\n continue\n }\n const path = join(dir, entry.name)\n let ignored = false\n for (const scope of active) {\n const relativePath = relative(scope.dir, path)\n if (!relativePath || relativePath.startsWith('..')) continue\n const candidate = relativePath.split(sep).join('/') + (isDirectory ? '/' : '')\n if (scope.matcher.ignores(candidate)) {\n ignored = true\n break\n }\n }\n if (ignored) continue\n if (isDirectory) stack.push({ dir: path, scopes: active })\n else found.push(path)\n }\n }\n return found.sort(compareCodeUnits)\n}\n\nfunction compilerTarget(platform: string | null): CompilerTarget {\n return platform === 'web' ? 'web' : 'native'\n}\n\nfunction retainsLiveGraph(options: MetroCompilerScanOptions): boolean {\n return options.dev && options.hot\n}\n\nexport class MetroCompilerFrontend {\n readonly #cacheBaseRoot: string\n readonly #entries = new Map<ResolvedModuleId, MetroCompilerCacheEntry>()\n readonly #records = new Map<ResolvedModuleId, CompiledRecord>()\n readonly #watchers = new Map<ResolvedModuleId, FSWatcher>()\n readonly #resolver\n #graph: ProjectGraph | null = null\n #host: CompilerLoweringHost | null = null\n #projectGeneration: string | null = null\n #publishedGeneration: string | null = null\n #scanOptions: MetroCompilerScanOptions | null = null\n #scanOptionsHash: string | null = null\n #operationQueue: Promise<void> = Promise.resolve()\n #tamaguiConfig: TamaguiProjectInfo['tamaguiConfig'] | null = null\n #zeroEntryGraph: Set<ResolvedModuleId> | null = null\n readonly #planKeys = new Map<ResolvedModuleId, { key: string; digest: string }>()\n #recordCache: JsonFileCache | null = null\n #recordCacheIdentity: string | null = null\n #planCache: ModulePlanCache | null = null\n #planCacheStamp: string | null = null\n\n constructor(readonly config: MetroCompilerFrontendConfig) {\n this.#cacheBaseRoot =\n config.cacheRoot ?? defaultMetroCompilerCacheRoot(config.projectRoot)\n this.#resolver = createMetroCompilerResolver(config)\n }\n\n get metroResolverVersion(): string {\n return this.#resolver.version\n }\n\n /**\n * Per-file cache accounting for the last scan. The point of these caches is\n * that one edited module leaves every other module's entry valid, and this is\n * how that is observed rather than assumed.\n */\n get compileCacheStats(): {\n plans: { hits: number; misses: number; writes: number }\n records: { hits: number; misses: number; writes: number }\n } {\n const empty = { hits: 0, misses: 0, writes: 0 }\n return {\n plans: this.#planCache?.stats ?? empty,\n records: this.#recordCache?.stats ?? empty,\n }\n }\n\n cacheRootFor(platform: string | null): string {\n return join(this.#cacheBaseRoot, platform ?? 'default')\n }\n\n scan(options: MetroCompilerScanOptions): Promise<MetroCompilerGeneration> {\n return this.#enqueue(() => this.#scan(options))\n }\n\n async #scan(\n options: MetroCompilerScanOptions,\n preparedProject?: MetroCompilerProject,\n preparedProjectSources?: string[]\n ): Promise<MetroCompilerGeneration> {\n this.#scanOptions = options\n this.#publishedGeneration = null\n const diagnostics: MetroCompilerDiagnostic[] = []\n const entryRoots = (\n await Promise.all(\n options.entryFiles.map((path) => realpath(resolve(this.config.projectRoot, path)))\n )\n ).sort(compareCodeUnits)\n const compilerProject =\n preparedProject ??\n (await this.#loadCompilerProject(options, entryRoots[0], diagnostics))\n this.#projectGeneration = compilerProject.generation\n const projectSources =\n preparedProjectSources ?? (await walkProjectSources(this.config.projectRoot))\n const projectSourcesHash = contentHash(JSON.stringify(projectSources))\n this.#scanOptionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n projectSourcesHash\n )\n this.#installCaches(options, compilerProject, projectSourcesHash)\n const speculativeRoots = new Set<string>()\n for (const file of projectSources) {\n try {\n const id = await realpath(file)\n if (!entryRoots.includes(id)) speculativeRoots.add(id)\n } catch {}\n }\n const roots = [...new Set([...entryRoots, ...speculativeRoots])].sort(\n compareCodeUnits\n )\n const queue = [...roots]\n const queued = new Set(queue)\n for (const watcher of this.#watchers.values()) watcher.close()\n this.#watchers.clear()\n this.#records.clear()\n\n while (queue.length) {\n const path = queue.shift()!\n try {\n const record = await this.#compileRecord(path, options, diagnostics)\n this.#records.set(record.input.id, record)\n for (const dependency of record.input.imports) {\n if (\n dependency.external ||\n !isCompilerSourceFile(dependency.resolvedId) ||\n queued.has(dependency.resolvedId)\n ) {\n continue\n }\n queued.add(dependency.resolvedId)\n queue.push(dependency.resolvedId)\n }\n } catch (error) {\n // walk-seeded files are speculative: nothing proved the bundle needs\n // them, so a compile failure is not a build diagnostic. If the bundle\n // does include one, the transformer's plan-miss warning still fires.\n if (speculativeRoots.has(path)) continue\n const diagnostic = metroDiagnostic(\n 'metro/transform-failed',\n `Failed to compile ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n )\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n }\n\n if (\n !compilerProject.projectInfo.tamaguiConfig ||\n !compilerProject.projectInfo.components\n ) {\n throw new Error('Metro compiler project has no Tamagui config or components')\n }\n this.#tamaguiConfig = compilerProject.projectInfo.tamaguiConfig\n this.#entries.clear()\n const unplanned = await this.#restorePlans(options)\n const zero = this.config.zero\n // a scan that restores everything builds no graph, so the previous scan's\n // graph must not survive as this scan's answer\n this.#graph = null\n this.#host = null\n // Nothing left to compile and no live session to serve means the analyzer\n // graph is never read, so it is never built. Parsing and linking every\n // project source is the other half of the prepass cost.\n if (unplanned.length || retainsLiveGraph(options)) {\n this.#graph = new ProjectGraph(yukuFactory, {\n modules: [...this.#records.values()].map(({ input }) => input),\n })\n this.#host = createTamaguiCompilerHost({\n target: compilerTarget(options.platform),\n tamaguiConfig: compilerProject.projectInfo.tamaguiConfig,\n components: compilerProject.projectInfo.components,\n componentModules: compilerProject.componentModules.map(({ moduleName, id }) => ({\n moduleName,\n resolvedId: id,\n })),\n disablePartialExtraction: compilerProject.disablePartialExtraction,\n experimentalNativeFastPath: compilerProject.experimentalNativeFastPath,\n zeroRuntime: compilerProject.zeroRuntime,\n })\n if (zero) {\n if (zero.isEnforcing) {\n Static.assertZeroConfigDrivers(compilerProject.projectInfo.tamaguiConfig)\n }\n zero.plansRestoredFromCache = false\n zero.configCSS = compilerProject.projectInfo.tamaguiConfig.getCSS?.() ?? ''\n zero.artifact.clearGraphs()\n zero.bridges.clear()\n zero.violations.length = 0\n zero.transformed.clear()\n zero.erasedExports.clear()\n // The zero contract applies to an ENTRY GRAPH. Metro's frontend plans\n // every project source by directory walk, so a config module, a control\n // fixture, or another entry's page would otherwise be judged against a\n // contract they are not part of.\n this.#zeroEntryGraph = this.#reachableFrom(entryRoots.map(resolvedModuleId))\n }\n for (const id of unplanned) this.#refreshEntry(id)\n await this.#storePlans(unplanned)\n }\n if (zero) {\n // Written in both modes and before the failure, so `report` and `enforce`\n // emit the identical list and only their exit differs.\n Static.writeZeroViolationReport(zero.resolved.outDir, 'metro-zero', {\n integration: 'metro-web',\n mode: zero.isEnforcing ? 'enforce' : 'report',\n violations: zero.violations,\n })\n if (zero.isEnforcing && zero.violations.length) {\n throw new Error(Static.formatZeroViolations(zero.violations))\n }\n }\n const totalFound = [...this.#entries.values()].reduce(\n (sum, entry) => sum + entry.plan.stats.found,\n 0\n )\n if (this.#entries.size > 0 && totalFound === 0) {\n const componentNames = compilerProject.componentModules.map(\n ({ moduleName }) => moduleName\n )\n const cjsComponentImporters = [...this.#records.values()].filter((record) =>\n record.requireSpecifiers.some((specifier) =>\n componentNames.some(\n (name) => specifier === name || specifier.startsWith(`${name}/`)\n )\n )\n ).length\n if (cjsComponentImporters > 0) {\n const diagnostic = metroDiagnostic(\n 'metro/no-linked-components',\n `The Tamagui compiler linked 0 components across ${this.#entries.size} modules even though ` +\n `${cjsComponentImporters} module(s) reference ${componentNames.join(', ')} through require() calls. ` +\n `Metro compiled modules to CommonJS before the compiler could analyze them, so component ` +\n `imports cannot be linked and nothing will be optimized. Enable experimentalImportSupport ` +\n `in your transformer's getTransformOptions (Expo enables it by default) to restore ` +\n `Tamagui compilation.`\n )\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n }\n const generation = await this.#publish(options.platform)\n const moduleIds = [...this.#records.keys()].sort(compareCodeUnits)\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#installWatchers()\n } else if (!retainsLiveGraph(options)) {\n this.#releaseGraph()\n }\n return {\n generation,\n moduleIds,\n diagnostics,\n }\n }\n\n ensureValidCache(options: MetroCompilerScanOptions): Promise<MetroCompilerGeneration> {\n return this.#enqueue(() => this.#ensureValidCache(options))\n }\n\n async #ensureValidCache(\n options: MetroCompilerScanOptions\n ): Promise<MetroCompilerGeneration> {\n const diagnostics: MetroCompilerDiagnostic[] = []\n const firstEntry = options.entryFiles[0]\n const importer = firstEntry\n ? await realpath(resolve(this.config.projectRoot, firstEntry))\n : this.config.projectRoot\n const compilerProject = await this.#loadCompilerProject(\n options,\n importer,\n diagnostics\n )\n const cache = new MetroCompilerCache(this.cacheRootFor(options.platform))\n const validation = await cache.validate()\n const projectSources = await walkProjectSources(this.config.projectRoot)\n const optionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n contentHash(JSON.stringify(projectSources))\n )\n if (\n validation.valid &&\n validation.generation &&\n validation.optionsHash === optionsHash &&\n (await this.#sourcesAreFresh(validation.sourceHashes)) &&\n ((!retainsLiveGraph(options) && !this.#graph) ||\n (this.#publishedGeneration && this.#scanOptionsHash === optionsHash)) &&\n // A zero build owns the one CSS artifact, and its contents are produced by\n // the scan. Reusing a published plan without restoring the artifact would\n // emit one missing every rule this process never collected, while still\n // deriving TAMAGUI_DID_OUTPUT_CSS from it. The sidecar carries exactly\n // those side effects; without it there is nothing safe to reuse.\n (await this.#rehydrateZeroCSS(cache, validation.generation))\n ) {\n this.#publishedGeneration = validation.generation\n this.#scanOptions = options\n this.#scanOptionsHash = optionsHash\n this.#projectGeneration = compilerProject.generation\n return {\n generation: validation.generation,\n moduleIds: validation.moduleIds,\n diagnostics,\n }\n }\n for (const diagnostic of validation.diagnostics) this.#report(diagnostic)\n await cache.discardManifest()\n return await this.#scan(options, compilerProject, projectSources)\n }\n\n async updateFile(path: string): Promise<MetroCompilerUpdate> {\n let result: MetroCompilerUpdate = {\n changed: false,\n affectedIds: [],\n generation: null,\n }\n return this.#enqueue(async () => {\n const graph = this.#graph\n const options = this.#scanOptions\n if (!graph || !options) return result\n let record: CompiledRecord\n const diagnostics: MetroCompilerDiagnostic[] = []\n try {\n record = await this.#compileRecord(path, options, diagnostics)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n const id = resolvedModuleId(resolve(path))\n const invalidation = graph.removeModule(id)\n this.#watchers.get(id)?.close()\n this.#watchers.delete(id)\n this.#records.delete(id)\n this.#entries.delete(id)\n for (const affected of invalidation.invalidatedIds) {\n if (affected !== id) this.#refreshEntry(affected)\n }\n const generation = await this.#publish(options.platform)\n result = {\n changed: invalidation.changed,\n affectedIds: invalidation.invalidatedIds,\n generation,\n }\n return result\n }\n const diagnostic = metroDiagnostic(\n 'metro/transform-failed',\n `Failed to update ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n )\n this.#report(diagnostic)\n return result\n }\n\n for (const dependency of record.input.imports) {\n if (\n dependency.external ||\n !isCompilerSourceFile(dependency.resolvedId) ||\n this.#records.has(dependency.resolvedId)\n ) {\n continue\n }\n await this.#addDependency(dependency.resolvedId, options, diagnostics)\n }\n this.#records.set(record.input.id, record)\n const invalidation = graph.updateModule(record.input)\n for (const affected of invalidation.invalidatedIds) this.#refreshEntry(affected)\n const generation = invalidation.changed\n ? await this.#publish(options.platform)\n : null\n result = {\n changed: invalidation.changed,\n affectedIds: invalidation.invalidatedIds,\n generation,\n }\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#watchModule(record.input.id)\n }\n return result\n })\n }\n\n /** A published plan only applies while every recorded module source is unchanged. */\n async #sourcesAreFresh(sourceHashes: Record<string, string>): Promise<boolean> {\n const checks = Object.entries(sourceHashes).map(async ([moduleId, sourceHash]) => {\n try {\n return contentHash(await readFile(moduleId, 'utf8')) === sourceHash\n } catch {\n return false\n }\n })\n return (await Promise.all(checks)).every(Boolean)\n }\n\n #enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const queued = this.#operationQueue.then(operation)\n this.#operationQueue = queued.then(\n () => undefined,\n () => undefined\n )\n return queued\n }\n\n close(): Promise<void> {\n return this.#enqueue(async () => {\n this.#releaseGraph()\n })\n }\n\n #releaseGraph(): void {\n for (const watcher of this.#watchers.values()) watcher.close()\n this.#watchers.clear()\n this.#entries.clear()\n this.#records.clear()\n this.#planKeys.clear()\n this.#graph = null\n this.#host = null\n this.#projectGeneration = null\n }\n\n async #loadCompilerProject(\n options: MetroCompilerScanOptions,\n importer: string,\n diagnostics: MetroCompilerDiagnostic[]\n ): Promise<MetroCompilerProject> {\n const target = compilerTarget(options.platform)\n if (this.config.loadCompilerProject) {\n return await this.config.loadCompilerProject(target, options.platform)\n }\n return Static.loadCompilerProject({\n root: this.config.projectRoot,\n target,\n options: this.config.tamaguiOptions ?? {},\n hostVersions: compilerImplementationVersions,\n missingProjectMessage: 'Unable to load the Tamagui project for Metro compilation',\n generation: (projectInfo, componentModules, normalizedOptions) => {\n return contentHash(\n JSON.stringify({\n cacheVersion: METRO_COMPILER_CACHE_VERSION,\n compilerImplementationVersions,\n componentModules,\n configCss: projectInfo.tamaguiConfig?.getCSS?.() ?? '',\n disablePartialExtraction: !!normalizedOptions.disablePartialExtraction,\n experimentalNativeFastPath:\n target === 'native' &&\n normalizedOptions.experimental?.nativeFastPath === true,\n target,\n // the host's diagnostics are mode-aware, so a plan built in one mode is\n // not a plan the other mode may reuse\n zeroRuntime: !!this.config.zero,\n })\n )\n },\n resolveComponents: async (moduleNames) => {\n const componentModules: MetroCompilerProject['componentModules'] = []\n for (const moduleName of moduleNames) {\n try {\n const resolution = this.#resolver.resolve(\n importer,\n { specifier: moduleName, isESMImport: true },\n options.platform\n )\n if (!resolution) continue\n componentModules.push({ moduleName, id: resolution.resolvedId })\n } catch (error) {\n const diagnostic = metroDiagnostic(\n 'metro/resolve-failed',\n `Failed to resolve compiler component ${moduleName}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: importer, dependency: moduleName }\n )\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n }\n return componentModules\n },\n })\n }\n\n async #compileRecord(\n rawPath: string,\n options: MetroCompilerScanOptions,\n diagnostics: MetroCompilerDiagnostic[]\n ): Promise<CompiledRecord> {\n const path = await realpath(resolve(rawPath))\n const source = await readFile(path, 'utf8')\n const sourceHash = contentHash(source)\n const id = resolvedModuleId(path)\n const cache = this.#recordCache\n const identity = this.#recordCacheIdentity\n const key = cache && identity ? contentHash(`${identity}\\0${sourceHash}`) : null\n if (cache && key) {\n const cached = await cache.read(key, (value) => {\n const entry = value as CachedRecord | null\n return entry?.schemaVersion === METRO_RECORD_CACHE_VERSION &&\n entry.sourceHash === sourceHash &&\n Array.isArray(entry.imports) &&\n Array.isArray(entry.requireSpecifiers) &&\n Array.isArray(entry.diagnostics)\n ? entry\n : null\n })\n if (cached) {\n for (const diagnostic of cached.diagnostics) {\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n return {\n input: { id, source, imports: cached.imports },\n sourceHash,\n requireSpecifiers: cached.requireSpecifiers,\n }\n }\n }\n\n const args = this.#babelArgs(path, source, options)\n const compiled = await compileWithUserBabel(\n this.config.originalBabelTransformerPath,\n args\n )\n const imports: HostResolvedImport[] = []\n const requireSpecifiers: string[] = []\n const recordDiagnostics: MetroCompilerDiagnostic[] = []\n for (const dependency of moduleSpecifiersFromAst(compiled.result.ast)) {\n if (!dependency.isESMImport) requireSpecifiers.push(dependency.specifier)\n try {\n const resolution = this.#resolver.resolve(path, dependency, options.platform)\n if (!resolution) continue\n imports.push({\n specifier: resolution.specifier,\n resolvedId: resolvedModuleId(resolution.resolvedId),\n external: resolution.external,\n })\n } catch (error) {\n recordDiagnostics.push(\n metroDiagnostic(\n 'metro/resolve-failed',\n `Failed to resolve ${dependency.specifier} from ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path, dependency: dependency.specifier }\n )\n )\n }\n }\n for (const diagnostic of recordDiagnostics) {\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n if (cache && key) {\n await cache.write(key, {\n schemaVersion: METRO_RECORD_CACHE_VERSION,\n sourceHash,\n imports,\n requireSpecifiers,\n diagnostics: recordDiagnostics,\n } satisfies CachedRecord)\n }\n return {\n // The graph and plans operate on raw source: workers apply plan edits to\n // the raw module before their own Babel pass, so plans never depend on\n // this process's Babel output matching the workers' byte for byte.\n input: { id, source, imports },\n sourceHash,\n requireSpecifiers,\n }\n }\n\n #babelOptions(options: MetroCompilerScanOptions): MetroBabelTransformArgs['options'] {\n const transformer = this.config.transformer ?? {}\n return {\n ...options.transform,\n dev: options.dev,\n hot: options.hot,\n platform: options.platform,\n projectRoot: this.config.projectRoot,\n enableBabelRCLookup: transformer.enableBabelRCLookup ?? true,\n enableBabelRuntime: transformer.enableBabelRuntime ?? true,\n hermesParser: transformer.hermesParser ?? false,\n publicPath: transformer.publicPath ?? '/assets',\n }\n }\n\n #babelArgs(\n filename: string,\n src: string,\n options: MetroCompilerScanOptions\n ): MetroBabelTransformArgs {\n return { filename, src, plugins: [], options: this.#babelOptions(options) }\n }\n\n async #addDependency(\n id: ResolvedModuleId,\n options: MetroCompilerScanOptions,\n diagnostics: MetroCompilerDiagnostic[],\n visiting = new Set<ResolvedModuleId>()\n ): Promise<void> {\n if (this.#records.has(id) || visiting.has(id)) return\n visiting.add(id)\n try {\n const record = await this.#compileRecord(id, options, diagnostics)\n for (const dependency of record.input.imports) {\n if (!dependency.external && isCompilerSourceFile(dependency.resolvedId)) {\n await this.#addDependency(dependency.resolvedId, options, diagnostics, visiting)\n }\n }\n this.#records.set(id, record)\n const invalidation = this.#graph?.updateModule(record.input)\n for (const affected of invalidation?.invalidatedIds ?? [id]) {\n this.#refreshEntry(affected)\n }\n if (\n this.config.watch !== false &&\n this.#scanOptions &&\n retainsLiveGraph(this.#scanOptions)\n ) {\n this.#watchModule(id)\n }\n } finally {\n visiting.delete(id)\n }\n }\n\n #refreshEntry(id: ResolvedModuleId): void {\n const graph = this.#graph\n const host = this.#host\n const record = this.#records.get(id)\n if (!graph || !host || !record || !this.#scanOptions || !this.#projectGeneration)\n return\n const target = compilerTarget(this.#scanOptions.platform)\n const plan = lowerModule({\n module: materializeModule(graph, id),\n source: record.input.source,\n target,\n host,\n options: { projectGeneration: this.#projectGeneration },\n })\n // Zero-mode reference erasure rides the same plan. Metro fixes a module's\n // dependencies at resolution time and does no export-level shaking, so the\n // plan a worker applies before Babel is the only point early enough to\n // remove an import from the graph.\n const zeroPlan = this.#zeroPlanFor(id, record.input.source, plan)\n this.#entries.set(id, this.#entryFor(id, record, zeroPlan ?? plan))\n }\n\n /**\n * One plan becomes one cache entry the same way whether the plan was just\n * lowered or read back off disk, so a restored build reports exactly the\n * diagnostics a fresh one did.\n */\n #entryFor(\n id: ResolvedModuleId,\n record: CompiledRecord,\n plan: LoweredModulePlan\n ): MetroCompilerCacheEntry {\n return {\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n moduleId: id,\n sourceHash: record.sourceHash,\n plan,\n diagnostics: plan.diagnostics.map(\n ({ code, message, dependencyId, span, component }) => {\n const { line, column } = Static.offsetToLineColumn(\n record.input.source,\n span.start\n )\n return metroDiagnostic(\n code.startsWith('linked/')\n ? 'metro/resolve-failed'\n : 'metro/transform-failed',\n message,\n { moduleId: id, dependency: dependencyId, span, line, column, component }\n )\n }\n ),\n }\n }\n\n /**\n * Both per-file caches for this scan. A project with no content stamp gets\n * neither: a stamp that cannot see a config change would serve styles built\n * against the old config, so the answer is no cache rather than a partial one.\n *\n * Zero builds opt out of the plan cache because a zero plan is produced\n * alongside side effects that do not travel in the plan - the CSS artifact,\n * the bridge manifest, the violation list - so replaying one module's plan\n * without them would emit an artifact missing its rules.\n */\n #installCaches(\n options: MetroCompilerScanOptions,\n project: MetroCompilerProject,\n projectSourcesHash: string\n ): void {\n const platform = options.platform ?? 'default'\n const root = defaultPlanCacheRoot(this.config.projectRoot, platform)\n this.#recordCache = new JsonFileCache(\n join(root, 'records'),\n METRO_RECORD_CACHE_VERSION\n )\n this.#recordCacheIdentity = contentHash(\n stableStringify({\n schema: METRO_RECORD_CACHE_VERSION,\n resolver: this.#resolver.version,\n babel: userBabelCacheKey(this.config.originalBabelTransformerPath),\n // resolutions depend on which files exist, so the walked source list is\n // part of a record's identity exactly as it is for the plan manifest\n projectSourcesHash,\n platform,\n transform: this.#babelOptions(options),\n })\n )\n const stamp = project.cacheStamp\n const usePlanCache = typeof stamp === 'string' && stamp !== '' && !this.config.zero\n this.#planCache = usePlanCache ? new ModulePlanCache(join(root, 'plans')) : null\n this.#planCacheStamp = usePlanCache ? stamp : null\n }\n\n /**\n * Fills `#entries` from disk for every module whose whole compile input is\n * unchanged, and returns the ids that still have to be compiled. This is the\n * per-file property: one edited module leaves every other module's entry\n * valid, where the plan manifest would have discarded all of them.\n */\n async #restorePlans(options: MetroCompilerScanOptions): Promise<ResolvedModuleId[]> {\n this.#planKeys.clear()\n const cache = this.#planCache\n const stamp = this.#planCacheStamp\n if (!cache || !stamp) return [...this.#records.keys()].sort(compareCodeUnits)\n const target = compilerTarget(options.platform)\n const identity = {\n stamp,\n target,\n structuralPassHash: `${target}-noop-v1`,\n }\n const nodes = new Map<ResolvedModuleId, ModuleClosureNode | null>()\n const lookup = (id: ResolvedModuleId): ModuleClosureNode | null => {\n let node = nodes.get(id)\n if (node === undefined) {\n const record = this.#records.get(id)\n node = record ? moduleClosureNode(record.input) : null\n nodes.set(id, node)\n }\n return node\n }\n const memo = new Map<ResolvedModuleId, string | null>()\n const unplanned: ResolvedModuleId[] = []\n for (const id of [...this.#records.keys()].sort(compareCodeUnits)) {\n const record = this.#records.get(id)!\n const digest = moduleClosureDigest(id, lookup, memo)\n const key = digest && planCacheKey(identity, id, digest)\n const entry = key && digest ? await cache.read(key, id, digest) : null\n if (entry) {\n this.#entries.set(id, this.#entryFor(id, record, entry.plan))\n continue\n }\n if (key && digest) this.#planKeys.set(id, { key, digest })\n unplanned.push(id)\n }\n return unplanned\n }\n\n async #storePlans(ids: readonly ResolvedModuleId[]): Promise<void> {\n const cache = this.#planCache\n if (!cache) return\n const pending = ids.flatMap((id) => {\n const entry = this.#entries.get(id)\n const key = this.#planKeys.get(id)\n return entry && key ? [{ id, entry, key }] : []\n })\n // a first build writes one file per module, and doing that serially costs\n // seconds on a real project\n for (let index = 0; index < pending.length; index += 32) {\n await Promise.all(\n pending.slice(index, index + 32).map(({ id, entry, key }) =>\n cache.write(key.key, {\n schemaVersion: PLAN_CACHE_SCHEMA_VERSION,\n moduleId: id,\n closureDigest: key.digest,\n plan: entry.plan,\n })\n )\n )\n }\n }\n\n /** Modules reachable from the bundle's entry, over the frontend's own graph. */\n #reachableFrom(roots: readonly ResolvedModuleId[]): Set<ResolvedModuleId> {\n const reached = new Set<ResolvedModuleId>()\n const queue = [...roots]\n while (queue.length) {\n const id = queue.pop()!\n if (reached.has(id)) continue\n reached.add(id)\n for (const dependency of this.#records.get(id)?.input.imports ?? []) {\n if (!dependency.external) queue.push(dependency.resolvedId)\n }\n }\n return reached\n }\n\n /**\n * The zero transform for one module, returning a plan whose edits also carry\n * the static Theme lowering, the island bridge, and reference erasure.\n */\n #zeroPlanFor(\n id: ResolvedModuleId,\n source: string,\n plan: ReturnType<typeof lowerModule>\n ): ReturnType<typeof lowerModule> | null {\n const zero = this.config.zero\n const config = this.#tamaguiConfig\n if (!zero || !config) return null\n\n // An island build is a full-runtime graph: it contributes its compiler\n // atomic CSS to the one artifact and is never erased or judged.\n if (zero.islandBuild) {\n zero.artifact.setIslandModuleCSS(zero.islandBuild, id, plan.css)\n return null\n }\n\n if (this.#zeroEntryGraph && !this.#zeroEntryGraph.has(id)) return null\n // only app-authored modules: a workspace dependency resolves outside\n // node_modules here, and erasing Tamagui's own re-exports would break it\n const relativePath = relative(this.config.projectRoot, id)\n if (\n relativePath === '' ||\n relativePath.startsWith('..') ||\n relativePath.split(/[\\\\/]/).includes('node_modules')\n ) {\n return null\n }\n\n const result = Static.transformZeroModule({\n mode: zero.isEnforcing ? 'enforce' : 'report',\n id,\n root: this.config.projectRoot,\n source,\n plan,\n config,\n isTamaguiSpecifier: (specifier) =>\n specifier === 'tamagui' || specifier.startsWith('@tamagui/'),\n resolveIslandLoader: (specifier) => {\n const islandId = zero.loaderIds.get(zeroModuleKey(resolve(id, '..', specifier)))\n return islandId ? { islandId } : null\n },\n resolveIslandModule: (specifier) =>\n zero.islandModuleIds.get(zeroModuleKey(resolve(id, '..', specifier))) ?? null,\n })\n\n zero.transformed.add(id)\n if (result.erased.exports.length) {\n zero.erasedExports.set(id, result.erased.exports)\n }\n for (const violation of result.violations) {\n const { line, column } = Static.offsetToLineColumn(source, violation.span.start)\n zero.violations.push({\n file: relativePath,\n line,\n column,\n rule: violation.rule,\n code: violation.code,\n component: violation.component,\n message: violation.message,\n })\n }\n if (result.violations.length || !zero.isEnforcing) return null\n\n Static.mergeIslandBridges(zero.bridges, result.bridges)\n for (const [identifier, rules] of result.bridgeCSS) {\n zero.artifact.setBridgeRules(identifier, rules)\n }\n zero.artifact.setZeroModuleCSS(id, plan.css)\n return { ...plan, edits: [...plan.edits, ...result.edits] }\n }\n\n async #publish(platform: string | null): Promise<string> {\n const cache = new MetroCompilerCache(this.cacheRootFor(platform))\n const generation = await cache.publish(\n platform,\n [...this.#entries.values()],\n this.#scanOptionsHash ?? ''\n )\n const zero = this.config.zero\n if (zero && !zero.islandBuild) {\n // the plans and the artifact are the same scan's output, so they are\n // published together or the warm path has nothing safe to reuse\n await cache.publishZeroCSS({\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n generation,\n configCSS: zero.configCSS,\n zeroModuleCSS: Object.fromEntries(zero.artifact.zeroModuleEntries()),\n bridgeCSS: Object.fromEntries(zero.artifact.bridgeEntries()),\n bridges: Object.fromEntries(zero.bridges),\n })\n }\n this.#publishedGeneration = generation\n return generation\n }\n\n /**\n * Restores the zero build's CSS side effects from the sidecar published with\n * this plan generation. Returns false when there is nothing trustworthy to\n * restore, which sends the caller to a full scan.\n */\n async #rehydrateZeroCSS(cache: MetroCompilerCache, generation: string) {\n const zero = this.config.zero\n if (!zero || zero.islandBuild) return true\n const sidecar = await cache.readZeroCSS(generation)\n if (!sidecar) return false\n zero.artifact.clearGraphs()\n zero.bridges.clear()\n zero.violations.length = 0\n zero.configCSS = sidecar.configCSS\n for (const [moduleId, css] of Object.entries(sidecar.zeroModuleCSS)) {\n zero.artifact.setZeroModuleCSS(moduleId, css)\n }\n for (const [bridgeId, css] of Object.entries(sidecar.bridgeCSS)) {\n zero.artifact.setBridgeRules(bridgeId, css)\n }\n for (const [islandId, bridges] of Object.entries(sidecar.bridges)) {\n zero.bridges.set(islandId, bridges as IslandThemeBridge[])\n }\n zero.plansRestoredFromCache = true\n return true\n }\n\n #installWatchers(): void {\n for (const id of this.#records.keys()) this.#watchModule(id)\n }\n\n #watchModule(id: ResolvedModuleId): void {\n if (this.#watchers.has(id)) return\n try {\n const watcher = watch(id, { persistent: false }, () => {\n void this.updateFile(id)\n })\n watcher.unref()\n this.#watchers.set(id, watcher)\n } catch {\n // A concurrent delete is handled by the importer's next invalidation.\n }\n }\n\n #report(diagnostic: MetroCompilerDiagnostic): void {\n this.config.reportDiagnostic?.(diagnostic)\n }\n}\n\nexport function describeMetroCompilerRoot(projectRoot: string, moduleId: string): string {\n const path = relative(projectRoot, moduleId)\n return path.startsWith('..') ? basename(moduleId) : path\n}\n"
|
|
9
|
+
"import { existsSync, watch, type FSWatcher } from 'node:fs'\nimport { readFile, readdir, realpath } from 'node:fs/promises'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, relative, resolve, sep } from 'node:path'\n\nimport ignore, { type Ignore } from 'ignore'\n\nimport {\n JsonFileCache,\n ModulePlanCache,\n PLAN_CACHE_SCHEMA_VERSION,\n ProjectGraph,\n contentHash,\n defaultPlanCacheRoot,\n isTamaguiSpecifier,\n lowerModule,\n materializeModule,\n moduleClosureDigest,\n moduleClosureNode,\n planCacheKey,\n resolvedModuleId,\n stableStringify,\n yukuFactory,\n type CompilerLoweringHost,\n type CompilerTarget,\n type HostModuleInput,\n type HostResolvedImport,\n type LoweredModulePlan,\n type ModuleClosureNode,\n type ResolvedModuleId,\n} from '@tamagui/compiler-core'\nimport Static, { createTamaguiCompilerHost } from '@tamagui/static'\nimport type {\n IslandThemeBridge,\n TamaguiOptions,\n TamaguiProjectInfo,\n} from '@tamagui/static'\n\nimport {\n compileWithUserBabel,\n userBabelCacheKey,\n type MetroBabelTransformArgs,\n} from './babel'\nimport { zeroModuleKey, type MetroZeroController } from './zeroRuntime'\nimport {\n METRO_COMPILER_CACHE_VERSION,\n MetroCompilerCache,\n defaultMetroCompilerCacheRoot,\n type MetroCompilerCacheEntry,\n} from './compilerCache'\nimport { metroDiagnostic, type MetroCompilerDiagnostic } from './diagnostics'\nimport {\n createMetroCompilerResolver,\n isCompilerSourceFile,\n moduleSpecifiersFromAst,\n type MetroResolverConfig,\n} from './metroResolver'\n\ninterface CompiledRecord {\n input: HostModuleInput\n sourceHash: string\n /** Specifiers that reached the compiled output as require() calls instead of imports. */\n requireSpecifiers: string[]\n}\n\n/**\n * Metro runs the user's whole Babel transformer over every project source just\n * to read its import specifiers, which is the single most expensive step of the\n * prepass. The result is a pure function of the module's own bytes plus the\n * resolver and Babel identity, so it caches per file with no closure involved.\n */\nexport const METRO_RECORD_CACHE_VERSION = 1\n\ninterface CachedRecord {\n schemaVersion: typeof METRO_RECORD_CACHE_VERSION\n sourceHash: string\n imports: HostResolvedImport[]\n requireSpecifiers: string[]\n /** Resolve failures replayed on a hit, so a cached record reports what a fresh one did. */\n diagnostics: MetroCompilerDiagnostic[]\n}\n\nexport interface MetroCompilerFrontendConfig extends MetroResolverConfig {\n cacheRoot?: string\n /** Present only for an enforced zero-runtime web build. */\n zero?: MetroZeroController | null\n originalBabelTransformerPath: string\n transformer?: Record<string, any>\n tamaguiOptions?: Partial<TamaguiOptions>\n loadCompilerProject?: (\n target: CompilerTarget,\n platform: string | null\n ) => Promise<MetroCompilerProject>\n watch?: boolean\n reportDiagnostic?: (diagnostic: MetroCompilerDiagnostic) => void\n}\n\nexport interface MetroCompilerProject extends Static.CompilerProject {}\n\nexport interface MetroCompilerScanOptions {\n dev: boolean\n entryFiles: readonly string[]\n hot: boolean\n platform: string | null\n transform?: Record<string, any>\n}\n\nexport interface MetroCompilerGeneration {\n generation: string\n moduleIds: string[]\n diagnostics: MetroCompilerDiagnostic[]\n}\n\nexport interface MetroCompilerUpdate {\n changed: boolean\n affectedIds: string[]\n generation: string | null\n}\n\nfunction compareCodeUnits(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0\n}\n\nconst requireFromFrontend = createRequire(\n typeof __filename === 'string' ? __filename : import.meta.url\n)\n\n// upgrading the compiler must invalidate published plans even when the Tamagui\n// config output is unchanged\nconst compilerImplementationVersions = (\n ['@tamagui/metro-plugin', '@tamagui/static', '@tamagui/compiler-core'] as const\n).map((packageName) => {\n const { version } = requireFromFrontend(`${packageName}/package.json`) as {\n version: string\n }\n return `${packageName}@${version}`\n})\n\nfunction scanOptionsHash(\n options: MetroCompilerScanOptions,\n projectGeneration: string,\n projectSourcesHash: string\n): string {\n return contentHash(JSON.stringify({ options, projectGeneration, projectSourcesHash }))\n}\n\n// Metro entries can live inside node_modules (expo-router's entry reaches app\n// source only through require.context), so reachability from the entry alone\n// discovers nothing there. Project source is walked directly and seeded into\n// the scan alongside the entry; imports then extend the graph outside the\n// project root (workspace packages) exactly as before.\n//\n// The walked list is both the seed set and the plan cache's options hash, so it\n// has to be authored source only. Build output is whatever the project already\n// declares as ignored, read with git's own rules: a directory-name list cannot\n// know that `dist-metro`, `out` or `public/assets` are output, and a sibling\n// bundler's content-hashed filenames then re-key the plan cache on every\n// unrelated rebuild, forcing Metro to rescan a project that never changed.\n// `node_modules` is skipped structurally instead, because that is the same\n// externality boundary the resolver draws and it must hold with or without a\n// declaration.\ninterface IgnoreScope {\n dir: string\n matcher: Ignore\n}\n\nconst speculativeWalkExcludedDirs = new Set([\n '__tests__',\n 'e2e',\n 'flows',\n 'plugins',\n 'screenshots',\n 'scripts',\n 'test',\n 'test-results',\n 'tests',\n])\n\nasync function walkProjectSources(root: string): Promise<string[]> {\n // git reads every .gitignore from the repository root down to the file, so an\n // app nested in a monorepo inherits the declarations made above it\n const inherited: string[] = []\n let ancestor = root\n while (!existsSync(join(ancestor, '.git'))) {\n const parent = dirname(ancestor)\n if (parent === ancestor) break\n inherited.unshift(parent)\n ancestor = parent\n }\n const rootScopes: IgnoreScope[] = []\n for (const dir of inherited) {\n const source = await readFile(join(dir, '.gitignore'), 'utf8').catch(() => null)\n if (source) rootScopes.push({ dir, matcher: ignore().add(source) })\n }\n\n const found: string[] = []\n const stack: { dir: string; scopes: IgnoreScope[] }[] = [\n { dir: root, scopes: rootScopes },\n ]\n while (stack.length) {\n const { dir, scopes } = stack.pop()!\n let entries\n try {\n entries = await readdir(dir, { withFileTypes: true })\n } catch {\n continue\n }\n let active = scopes\n if (entries.some((entry) => entry.isFile() && entry.name === '.gitignore')) {\n const source = await readFile(join(dir, '.gitignore'), 'utf8').catch(() => null)\n if (source) active = [...scopes, { dir, matcher: ignore().add(source) }]\n }\n for (const entry of entries) {\n if (entry.name.startsWith('.') || entry.name === 'node_modules') continue\n const isDirectory = entry.isDirectory()\n if (isDirectory && speculativeWalkExcludedDirs.has(entry.name)) continue\n if (!isDirectory && !(entry.isFile() && isCompilerSourceFile(entry.name))) continue\n if (\n !isDirectory &&\n (/(?:^|[-.])(?:probe|run|spec|tests?)(?:[-.]|$)/i.test(entry.name) ||\n /\\.(?:build|config|workspace)\\.[cm]?[jt]sx?$/.test(entry.name))\n ) {\n continue\n }\n const path = join(dir, entry.name)\n let ignored = false\n for (const scope of active) {\n const relativePath = relative(scope.dir, path)\n if (!relativePath || relativePath.startsWith('..')) continue\n const candidate = relativePath.split(sep).join('/') + (isDirectory ? '/' : '')\n if (scope.matcher.ignores(candidate)) {\n ignored = true\n break\n }\n }\n if (ignored) continue\n if (isDirectory) stack.push({ dir: path, scopes: active })\n else found.push(path)\n }\n }\n return found.sort(compareCodeUnits)\n}\n\nfunction compilerTarget(platform: string | null): CompilerTarget {\n return platform === 'web' ? 'web' : 'native'\n}\n\nfunction retainsLiveGraph(options: MetroCompilerScanOptions): boolean {\n return options.dev && options.hot\n}\n\nexport class MetroCompilerFrontend {\n readonly #cacheBaseRoot: string\n readonly #entries = new Map<ResolvedModuleId, MetroCompilerCacheEntry>()\n readonly #records = new Map<ResolvedModuleId, CompiledRecord>()\n readonly #watchers = new Map<ResolvedModuleId, FSWatcher>()\n readonly #resolver\n #graph: ProjectGraph | null = null\n #host: CompilerLoweringHost | null = null\n #projectGeneration: string | null = null\n #publishedGeneration: string | null = null\n #scanOptions: MetroCompilerScanOptions | null = null\n #scanOptionsHash: string | null = null\n #operationQueue: Promise<void> = Promise.resolve()\n #tamaguiConfig: TamaguiProjectInfo['tamaguiConfig'] | null = null\n #zeroEntryGraph: Set<ResolvedModuleId> | null = null\n readonly #planKeys = new Map<ResolvedModuleId, { key: string; digest: string }>()\n #recordCache: JsonFileCache | null = null\n #recordCacheIdentity: string | null = null\n #planCache: ModulePlanCache | null = null\n #planCacheStamp: string | null = null\n\n constructor(readonly config: MetroCompilerFrontendConfig) {\n this.#cacheBaseRoot =\n config.cacheRoot ?? defaultMetroCompilerCacheRoot(config.projectRoot)\n this.#resolver = createMetroCompilerResolver(config)\n }\n\n get metroResolverVersion(): string {\n return this.#resolver.version\n }\n\n /**\n * Per-file cache accounting for the last scan. The point of these caches is\n * that one edited module leaves every other module's entry valid, and this is\n * how that is observed rather than assumed.\n */\n get compileCacheStats(): {\n plans: { hits: number; misses: number; writes: number }\n records: { hits: number; misses: number; writes: number }\n } {\n const empty = { hits: 0, misses: 0, writes: 0 }\n return {\n plans: this.#planCache?.stats ?? empty,\n records: this.#recordCache?.stats ?? empty,\n }\n }\n\n cacheRootFor(platform: string | null): string {\n return join(this.#cacheBaseRoot, platform ?? 'default')\n }\n\n scan(options: MetroCompilerScanOptions): Promise<MetroCompilerGeneration> {\n return this.#enqueue(() => this.#scan(options))\n }\n\n async #scan(\n options: MetroCompilerScanOptions,\n preparedProject?: MetroCompilerProject,\n preparedProjectSources?: string[]\n ): Promise<MetroCompilerGeneration> {\n this.#scanOptions = options\n this.#publishedGeneration = null\n const diagnostics: MetroCompilerDiagnostic[] = []\n const entryRoots = (\n await Promise.all(\n options.entryFiles.map((path) => realpath(resolve(this.config.projectRoot, path)))\n )\n ).sort(compareCodeUnits)\n const compilerProject =\n preparedProject ??\n (await this.#loadCompilerProject(options, entryRoots[0], diagnostics))\n this.#projectGeneration = compilerProject.generation\n const projectSources =\n preparedProjectSources ?? (await walkProjectSources(this.config.projectRoot))\n const projectSourcesHash = contentHash(JSON.stringify(projectSources))\n this.#scanOptionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n projectSourcesHash\n )\n this.#installCaches(options, compilerProject, projectSourcesHash)\n const speculativeRoots = new Set<string>()\n for (const file of projectSources) {\n try {\n const id = await realpath(file)\n if (!entryRoots.includes(id)) speculativeRoots.add(id)\n } catch {}\n }\n const roots = [...new Set([...entryRoots, ...speculativeRoots])].sort(\n compareCodeUnits\n )\n const queue = [...roots]\n const queued = new Set(queue)\n for (const watcher of this.#watchers.values()) watcher.close()\n this.#watchers.clear()\n this.#records.clear()\n\n while (queue.length) {\n const path = queue.shift()!\n try {\n const record = await this.#compileRecord(path, options, diagnostics)\n this.#records.set(record.input.id, record)\n for (const dependency of record.input.imports) {\n if (\n dependency.external ||\n !isCompilerSourceFile(dependency.resolvedId) ||\n queued.has(dependency.resolvedId)\n ) {\n continue\n }\n queued.add(dependency.resolvedId)\n queue.push(dependency.resolvedId)\n }\n } catch (error) {\n // walk-seeded files are speculative: nothing proved the bundle needs\n // them, so a compile failure is not a build diagnostic. If the bundle\n // does include one, the transformer's plan-miss warning still fires.\n if (speculativeRoots.has(path)) continue\n const diagnostic = metroDiagnostic(\n 'metro/transform-failed',\n `Failed to compile ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n )\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n }\n\n if (\n !compilerProject.projectInfo.tamaguiConfig ||\n !compilerProject.projectInfo.components\n ) {\n throw new Error('Metro compiler project has no Tamagui config or components')\n }\n this.#tamaguiConfig = compilerProject.projectInfo.tamaguiConfig\n this.#entries.clear()\n const unplanned = await this.#restorePlans(options)\n const zero = this.config.zero\n // a scan that restores everything builds no graph, so the previous scan's\n // graph must not survive as this scan's answer\n this.#graph = null\n this.#host = null\n // Nothing left to compile and no live session to serve means the analyzer\n // graph is never read, so it is never built. Parsing and linking every\n // project source is the other half of the prepass cost.\n if (unplanned.length || retainsLiveGraph(options)) {\n this.#graph = new ProjectGraph(yukuFactory, {\n modules: [...this.#records.values()].map(({ input }) => input),\n })\n this.#host = createTamaguiCompilerHost({\n target: compilerTarget(options.platform),\n tamaguiConfig: compilerProject.projectInfo.tamaguiConfig,\n components: compilerProject.projectInfo.components,\n componentModules: compilerProject.componentModules.map(({ moduleName, id }) => ({\n moduleName,\n resolvedId: id,\n })),\n disablePartialExtraction: compilerProject.disablePartialExtraction,\n experimentalNativeFastPath: compilerProject.experimentalNativeFastPath,\n zeroRuntime: compilerProject.zeroRuntime,\n })\n if (zero) {\n if (zero.isEnforcing) {\n Static.assertZeroConfigDrivers(compilerProject.projectInfo.tamaguiConfig)\n }\n zero.plansRestoredFromCache = false\n zero.configCSS = compilerProject.projectInfo.tamaguiConfig.getCSS?.() ?? ''\n zero.artifact.clearGraphs()\n zero.bridges.clear()\n zero.violations.length = 0\n zero.transformed.clear()\n zero.erasedExports.clear()\n // The zero contract applies to an ENTRY GRAPH. Metro's frontend plans\n // every project source by directory walk, so a config module, a control\n // fixture, or another entry's page would otherwise be judged against a\n // contract they are not part of.\n this.#zeroEntryGraph = this.#reachableFrom(entryRoots.map(resolvedModuleId))\n }\n for (const id of unplanned) this.#refreshEntry(id)\n await this.#storePlans(unplanned)\n }\n if (zero) {\n // Written in both modes and before the failure, so `report` and `enforce`\n // emit the identical list and only their exit differs.\n Static.writeZeroViolationReport(zero.resolved.outDir, 'metro-zero', {\n integration: 'metro-web',\n mode: zero.isEnforcing ? 'enforce' : 'report',\n violations: zero.violations,\n })\n if (zero.isEnforcing && zero.violations.length) {\n throw new Error(Static.formatZeroViolations(zero.violations))\n }\n }\n const totalFound = [...this.#entries.values()].reduce(\n (sum, entry) => sum + entry.plan.stats.found,\n 0\n )\n if (this.#entries.size > 0 && totalFound === 0) {\n const componentNames = compilerProject.componentModules.map(\n ({ moduleName }) => moduleName\n )\n const cjsComponentImporters = [...this.#records.values()].filter((record) =>\n record.requireSpecifiers.some((specifier) =>\n componentNames.some(\n (name) => specifier === name || specifier.startsWith(`${name}/`)\n )\n )\n ).length\n if (cjsComponentImporters > 0) {\n const diagnostic = metroDiagnostic(\n 'metro/no-linked-components',\n `The Tamagui compiler linked 0 components across ${this.#entries.size} modules even though ` +\n `${cjsComponentImporters} module(s) reference ${componentNames.join(', ')} through require() calls. ` +\n `Metro compiled modules to CommonJS before the compiler could analyze them, so component ` +\n `imports cannot be linked and nothing will be optimized. Enable experimentalImportSupport ` +\n `in your transformer's getTransformOptions (Expo enables it by default) to restore ` +\n `Tamagui compilation.`\n )\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n }\n const generation = await this.#publish(options.platform)\n const moduleIds = [...this.#records.keys()].sort(compareCodeUnits)\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#installWatchers()\n } else if (!retainsLiveGraph(options)) {\n this.#releaseGraph()\n }\n return {\n generation,\n moduleIds,\n diagnostics,\n }\n }\n\n ensureValidCache(options: MetroCompilerScanOptions): Promise<MetroCompilerGeneration> {\n return this.#enqueue(() => this.#ensureValidCache(options))\n }\n\n async #ensureValidCache(\n options: MetroCompilerScanOptions\n ): Promise<MetroCompilerGeneration> {\n const diagnostics: MetroCompilerDiagnostic[] = []\n const firstEntry = options.entryFiles[0]\n const importer = firstEntry\n ? await realpath(resolve(this.config.projectRoot, firstEntry))\n : this.config.projectRoot\n const compilerProject = await this.#loadCompilerProject(\n options,\n importer,\n diagnostics\n )\n const cache = new MetroCompilerCache(this.cacheRootFor(options.platform))\n const validation = await cache.validate()\n const projectSources = await walkProjectSources(this.config.projectRoot)\n const optionsHash = scanOptionsHash(\n options,\n compilerProject.generation,\n contentHash(JSON.stringify(projectSources))\n )\n if (\n validation.valid &&\n validation.generation &&\n validation.optionsHash === optionsHash &&\n (await this.#sourcesAreFresh(validation.sourceHashes)) &&\n ((!retainsLiveGraph(options) && !this.#graph) ||\n (this.#publishedGeneration && this.#scanOptionsHash === optionsHash)) &&\n // A zero build owns the one CSS artifact, and its contents are produced by\n // the scan. Reusing a published plan without restoring the artifact would\n // emit one missing every rule this process never collected, while still\n // deriving TAMAGUI_DID_OUTPUT_CSS from it. The sidecar carries exactly\n // those side effects; without it there is nothing safe to reuse.\n (await this.#rehydrateZeroCSS(cache, validation.generation))\n ) {\n this.#publishedGeneration = validation.generation\n this.#scanOptions = options\n this.#scanOptionsHash = optionsHash\n this.#projectGeneration = compilerProject.generation\n return {\n generation: validation.generation,\n moduleIds: validation.moduleIds,\n diagnostics,\n }\n }\n for (const diagnostic of validation.diagnostics) this.#report(diagnostic)\n await cache.discardManifest()\n return await this.#scan(options, compilerProject, projectSources)\n }\n\n async updateFile(path: string): Promise<MetroCompilerUpdate> {\n let result: MetroCompilerUpdate = {\n changed: false,\n affectedIds: [],\n generation: null,\n }\n return this.#enqueue(async () => {\n const graph = this.#graph\n const options = this.#scanOptions\n if (!graph || !options) return result\n let record: CompiledRecord\n const diagnostics: MetroCompilerDiagnostic[] = []\n try {\n record = await this.#compileRecord(path, options, diagnostics)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n const id = resolvedModuleId(resolve(path))\n const invalidation = graph.removeModule(id)\n this.#watchers.get(id)?.close()\n this.#watchers.delete(id)\n this.#records.delete(id)\n this.#entries.delete(id)\n for (const affected of invalidation.invalidatedIds) {\n if (affected !== id) this.#refreshEntry(affected)\n }\n const generation = await this.#publish(options.platform)\n result = {\n changed: invalidation.changed,\n affectedIds: invalidation.invalidatedIds,\n generation,\n }\n return result\n }\n const diagnostic = metroDiagnostic(\n 'metro/transform-failed',\n `Failed to update ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path }\n )\n this.#report(diagnostic)\n return result\n }\n\n for (const dependency of record.input.imports) {\n if (\n dependency.external ||\n !isCompilerSourceFile(dependency.resolvedId) ||\n this.#records.has(dependency.resolvedId)\n ) {\n continue\n }\n await this.#addDependency(dependency.resolvedId, options, diagnostics)\n }\n this.#records.set(record.input.id, record)\n const invalidation = graph.updateModule(record.input)\n for (const affected of invalidation.invalidatedIds) this.#refreshEntry(affected)\n const generation = invalidation.changed\n ? await this.#publish(options.platform)\n : null\n result = {\n changed: invalidation.changed,\n affectedIds: invalidation.invalidatedIds,\n generation,\n }\n if (this.config.watch !== false && retainsLiveGraph(options)) {\n this.#watchModule(record.input.id)\n }\n return result\n })\n }\n\n /** A published plan only applies while every recorded module source is unchanged. */\n async #sourcesAreFresh(sourceHashes: Record<string, string>): Promise<boolean> {\n const checks = Object.entries(sourceHashes).map(async ([moduleId, sourceHash]) => {\n try {\n return contentHash(await readFile(moduleId, 'utf8')) === sourceHash\n } catch {\n return false\n }\n })\n return (await Promise.all(checks)).every(Boolean)\n }\n\n #enqueue<T>(operation: () => Promise<T>): Promise<T> {\n const queued = this.#operationQueue.then(operation)\n this.#operationQueue = queued.then(\n () => undefined,\n () => undefined\n )\n return queued\n }\n\n close(): Promise<void> {\n return this.#enqueue(async () => {\n this.#releaseGraph()\n })\n }\n\n #releaseGraph(): void {\n for (const watcher of this.#watchers.values()) watcher.close()\n this.#watchers.clear()\n this.#entries.clear()\n this.#records.clear()\n this.#planKeys.clear()\n this.#graph = null\n this.#host = null\n this.#projectGeneration = null\n }\n\n async #loadCompilerProject(\n options: MetroCompilerScanOptions,\n importer: string,\n diagnostics: MetroCompilerDiagnostic[]\n ): Promise<MetroCompilerProject> {\n const target = compilerTarget(options.platform)\n if (this.config.loadCompilerProject) {\n return await this.config.loadCompilerProject(target, options.platform)\n }\n return Static.loadCompilerProject({\n root: this.config.projectRoot,\n target,\n options: this.config.tamaguiOptions ?? {},\n hostVersions: compilerImplementationVersions,\n missingProjectMessage: 'Unable to load the Tamagui project for Metro compilation',\n generation: (projectInfo, componentModules, normalizedOptions) => {\n return contentHash(\n JSON.stringify({\n cacheVersion: METRO_COMPILER_CACHE_VERSION,\n compilerImplementationVersions,\n componentModules,\n configCss: projectInfo.tamaguiConfig?.getCSS?.() ?? '',\n disablePartialExtraction: !!normalizedOptions.disablePartialExtraction,\n experimentalNativeFastPath:\n target === 'native' &&\n normalizedOptions.experimental?.nativeFastPath === true,\n target,\n // the host's diagnostics are mode-aware, so a plan built in one mode is\n // not a plan the other mode may reuse\n zeroRuntime: !!this.config.zero,\n })\n )\n },\n resolveComponents: async (moduleNames) => {\n const componentModules: MetroCompilerProject['componentModules'] = []\n for (const moduleName of moduleNames) {\n try {\n const resolution = this.#resolver.resolve(\n importer,\n { specifier: moduleName, isESMImport: true },\n options.platform\n )\n if (!resolution) continue\n componentModules.push({ moduleName, id: resolution.resolvedId })\n } catch (error) {\n const diagnostic = metroDiagnostic(\n 'metro/resolve-failed',\n `Failed to resolve compiler component ${moduleName}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: importer, dependency: moduleName }\n )\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n }\n return componentModules\n },\n })\n }\n\n async #compileRecord(\n rawPath: string,\n options: MetroCompilerScanOptions,\n diagnostics: MetroCompilerDiagnostic[]\n ): Promise<CompiledRecord> {\n const path = await realpath(resolve(rawPath))\n const source = await readFile(path, 'utf8')\n const sourceHash = contentHash(source)\n const id = resolvedModuleId(path)\n const cache = this.#recordCache\n const identity = this.#recordCacheIdentity\n const key = cache && identity ? contentHash(`${identity}\\0${sourceHash}`) : null\n if (cache && key) {\n const cached = await cache.read(key, (value) => {\n const entry = value as CachedRecord | null\n return entry?.schemaVersion === METRO_RECORD_CACHE_VERSION &&\n entry.sourceHash === sourceHash &&\n Array.isArray(entry.imports) &&\n Array.isArray(entry.requireSpecifiers) &&\n Array.isArray(entry.diagnostics)\n ? entry\n : null\n })\n if (cached) {\n for (const diagnostic of cached.diagnostics) {\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n return {\n input: { id, source, imports: cached.imports },\n sourceHash,\n requireSpecifiers: cached.requireSpecifiers,\n }\n }\n }\n\n const args = this.#babelArgs(path, source, options)\n const compiled = await compileWithUserBabel(\n this.config.originalBabelTransformerPath,\n args\n )\n const imports: HostResolvedImport[] = []\n const requireSpecifiers: string[] = []\n const recordDiagnostics: MetroCompilerDiagnostic[] = []\n for (const dependency of moduleSpecifiersFromAst(compiled.result.ast)) {\n if (!dependency.isESMImport) requireSpecifiers.push(dependency.specifier)\n try {\n const resolution = this.#resolver.resolve(path, dependency, options.platform)\n if (!resolution) continue\n imports.push({\n specifier: resolution.specifier,\n resolvedId: resolvedModuleId(resolution.resolvedId),\n external: resolution.external,\n })\n } catch (error) {\n recordDiagnostics.push(\n metroDiagnostic(\n 'metro/resolve-failed',\n `Failed to resolve ${dependency.specifier} from ${path}: ${error instanceof Error ? error.message : String(error)}`,\n { moduleId: path, dependency: dependency.specifier }\n )\n )\n }\n }\n for (const diagnostic of recordDiagnostics) {\n diagnostics.push(diagnostic)\n this.#report(diagnostic)\n }\n if (cache && key) {\n await cache.write(key, {\n schemaVersion: METRO_RECORD_CACHE_VERSION,\n sourceHash,\n imports,\n requireSpecifiers,\n diagnostics: recordDiagnostics,\n } satisfies CachedRecord)\n }\n return {\n // The graph and plans operate on raw source: workers apply plan edits to\n // the raw module before their own Babel pass, so plans never depend on\n // this process's Babel output matching the workers' byte for byte.\n input: { id, source, imports },\n sourceHash,\n requireSpecifiers,\n }\n }\n\n #babelOptions(options: MetroCompilerScanOptions): MetroBabelTransformArgs['options'] {\n const transformer = this.config.transformer ?? {}\n return {\n ...options.transform,\n dev: options.dev,\n hot: options.hot,\n platform: options.platform,\n projectRoot: this.config.projectRoot,\n enableBabelRCLookup: transformer.enableBabelRCLookup ?? true,\n enableBabelRuntime: transformer.enableBabelRuntime ?? true,\n hermesParser: transformer.hermesParser ?? false,\n publicPath: transformer.publicPath ?? '/assets',\n }\n }\n\n #babelArgs(\n filename: string,\n src: string,\n options: MetroCompilerScanOptions\n ): MetroBabelTransformArgs {\n return { filename, src, plugins: [], options: this.#babelOptions(options) }\n }\n\n async #addDependency(\n id: ResolvedModuleId,\n options: MetroCompilerScanOptions,\n diagnostics: MetroCompilerDiagnostic[],\n visiting = new Set<ResolvedModuleId>()\n ): Promise<void> {\n if (this.#records.has(id) || visiting.has(id)) return\n visiting.add(id)\n try {\n const record = await this.#compileRecord(id, options, diagnostics)\n for (const dependency of record.input.imports) {\n if (!dependency.external && isCompilerSourceFile(dependency.resolvedId)) {\n await this.#addDependency(dependency.resolvedId, options, diagnostics, visiting)\n }\n }\n this.#records.set(id, record)\n const invalidation = this.#graph?.updateModule(record.input)\n for (const affected of invalidation?.invalidatedIds ?? [id]) {\n this.#refreshEntry(affected)\n }\n if (\n this.config.watch !== false &&\n this.#scanOptions &&\n retainsLiveGraph(this.#scanOptions)\n ) {\n this.#watchModule(id)\n }\n } finally {\n visiting.delete(id)\n }\n }\n\n #refreshEntry(id: ResolvedModuleId): void {\n const graph = this.#graph\n const host = this.#host\n const record = this.#records.get(id)\n if (!graph || !host || !record || !this.#scanOptions || !this.#projectGeneration)\n return\n const target = compilerTarget(this.#scanOptions.platform)\n const plan = lowerModule({\n module: materializeModule(graph, id),\n source: record.input.source,\n target,\n host,\n options: { projectGeneration: this.#projectGeneration },\n })\n // Zero-mode reference erasure rides the same plan. Metro fixes a module's\n // dependencies at resolution time and does no export-level shaking, so the\n // plan a worker applies before Babel is the only point early enough to\n // remove an import from the graph.\n const zeroPlan = this.#zeroPlanFor(id, record.input.source, plan)\n this.#entries.set(id, this.#entryFor(id, record, zeroPlan ?? plan))\n }\n\n /**\n * One plan becomes one cache entry the same way whether the plan was just\n * lowered or read back off disk, so a restored build reports exactly the\n * diagnostics a fresh one did.\n */\n #entryFor(\n id: ResolvedModuleId,\n record: CompiledRecord,\n plan: LoweredModulePlan\n ): MetroCompilerCacheEntry {\n return {\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n moduleId: id,\n sourceHash: record.sourceHash,\n plan,\n diagnostics: plan.diagnostics.map(\n ({ code, message, dependencyId, span, component }) => {\n const { line, column } = Static.offsetToLineColumn(\n record.input.source,\n span.start\n )\n return metroDiagnostic(\n code.startsWith('linked/')\n ? 'metro/resolve-failed'\n : 'metro/transform-failed',\n message,\n { moduleId: id, dependency: dependencyId, span, line, column, component }\n )\n }\n ),\n }\n }\n\n /**\n * Both per-file caches for this scan. A project with no content stamp gets\n * neither: a stamp that cannot see a config change would serve styles built\n * against the old config, so the answer is no cache rather than a partial one.\n *\n * Zero builds opt out of the plan cache because a zero plan is produced\n * alongside side effects that do not travel in the plan - the CSS artifact,\n * the bridge manifest, the violation list - so replaying one module's plan\n * without them would emit an artifact missing its rules.\n */\n #installCaches(\n options: MetroCompilerScanOptions,\n project: MetroCompilerProject,\n projectSourcesHash: string\n ): void {\n const platform = options.platform ?? 'default'\n const root = defaultPlanCacheRoot(this.config.projectRoot, platform)\n this.#recordCache = new JsonFileCache(\n join(root, 'records'),\n METRO_RECORD_CACHE_VERSION\n )\n this.#recordCacheIdentity = contentHash(\n stableStringify({\n schema: METRO_RECORD_CACHE_VERSION,\n resolver: this.#resolver.version,\n babel: userBabelCacheKey(this.config.originalBabelTransformerPath),\n // resolutions depend on which files exist, so the walked source list is\n // part of a record's identity exactly as it is for the plan manifest\n projectSourcesHash,\n platform,\n transform: this.#babelOptions(options),\n })\n )\n const stamp = project.cacheStamp\n const usePlanCache = typeof stamp === 'string' && stamp !== '' && !this.config.zero\n this.#planCache = usePlanCache ? new ModulePlanCache(join(root, 'plans')) : null\n this.#planCacheStamp = usePlanCache ? stamp : null\n }\n\n /**\n * Fills `#entries` from disk for every module whose whole compile input is\n * unchanged, and returns the ids that still have to be compiled. This is the\n * per-file property: one edited module leaves every other module's entry\n * valid, where the plan manifest would have discarded all of them.\n */\n async #restorePlans(options: MetroCompilerScanOptions): Promise<ResolvedModuleId[]> {\n this.#planKeys.clear()\n const cache = this.#planCache\n const stamp = this.#planCacheStamp\n if (!cache || !stamp) return [...this.#records.keys()].sort(compareCodeUnits)\n const target = compilerTarget(options.platform)\n const identity = {\n stamp,\n target,\n structuralPassHash: `${target}-noop-v1`,\n }\n const nodes = new Map<ResolvedModuleId, ModuleClosureNode | null>()\n const lookup = (id: ResolvedModuleId): ModuleClosureNode | null => {\n let node = nodes.get(id)\n if (node === undefined) {\n const record = this.#records.get(id)\n node = record ? moduleClosureNode(record.input) : null\n nodes.set(id, node)\n }\n return node\n }\n const memo = new Map<ResolvedModuleId, string | null>()\n const unplanned: ResolvedModuleId[] = []\n for (const id of [...this.#records.keys()].sort(compareCodeUnits)) {\n const record = this.#records.get(id)!\n const digest = moduleClosureDigest(id, lookup, memo)\n const key = digest && planCacheKey(identity, id, digest)\n const entry = key && digest ? await cache.read(key, id, digest) : null\n if (entry) {\n this.#entries.set(id, this.#entryFor(id, record, entry.plan))\n continue\n }\n if (key && digest) this.#planKeys.set(id, { key, digest })\n unplanned.push(id)\n }\n return unplanned\n }\n\n async #storePlans(ids: readonly ResolvedModuleId[]): Promise<void> {\n const cache = this.#planCache\n if (!cache) return\n const pending = ids.flatMap((id) => {\n const entry = this.#entries.get(id)\n const key = this.#planKeys.get(id)\n return entry && key ? [{ id, entry, key }] : []\n })\n // a first build writes one file per module, and doing that serially costs\n // seconds on a real project\n for (let index = 0; index < pending.length; index += 32) {\n await Promise.all(\n pending.slice(index, index + 32).map(({ id, entry, key }) =>\n cache.write(key.key, {\n schemaVersion: PLAN_CACHE_SCHEMA_VERSION,\n moduleId: id,\n closureDigest: key.digest,\n plan: entry.plan,\n })\n )\n )\n }\n }\n\n /** Modules reachable from the bundle's entry, over the frontend's own graph. */\n #reachableFrom(roots: readonly ResolvedModuleId[]): Set<ResolvedModuleId> {\n const reached = new Set<ResolvedModuleId>()\n const queue = [...roots]\n while (queue.length) {\n const id = queue.pop()!\n if (reached.has(id)) continue\n reached.add(id)\n for (const dependency of this.#records.get(id)?.input.imports ?? []) {\n if (!dependency.external) queue.push(dependency.resolvedId)\n }\n }\n return reached\n }\n\n /**\n * The zero transform for one module, returning a plan whose edits also carry\n * the static Theme lowering, the island bridge, and reference erasure.\n */\n #zeroPlanFor(\n id: ResolvedModuleId,\n source: string,\n plan: ReturnType<typeof lowerModule>\n ): ReturnType<typeof lowerModule> | null {\n const zero = this.config.zero\n const config = this.#tamaguiConfig\n if (!zero || !config) return null\n\n // An island build is a full-runtime graph: it contributes its compiler\n // atomic CSS to the one artifact and is never erased or judged.\n if (zero.islandBuild) {\n zero.artifact.setIslandModuleCSS(zero.islandBuild, id, plan.css)\n return null\n }\n\n if (this.#zeroEntryGraph && !this.#zeroEntryGraph.has(id)) return null\n // only app-authored modules: a workspace dependency resolves outside\n // node_modules here, and erasing Tamagui's own re-exports would break it\n const relativePath = relative(this.config.projectRoot, id)\n if (\n relativePath === '' ||\n relativePath.startsWith('..') ||\n relativePath.split(/[\\\\/]/).includes('node_modules')\n ) {\n return null\n }\n\n const result = Static.transformZeroModule({\n mode: zero.isEnforcing ? 'enforce' : 'report',\n id,\n root: this.config.projectRoot,\n source,\n plan,\n config,\n isTamaguiSpecifier,\n resolveIslandLoader: (specifier) => {\n const islandId = zero.loaderIds.get(zeroModuleKey(resolve(id, '..', specifier)))\n return islandId ? { islandId } : null\n },\n resolveIslandModule: (specifier) =>\n zero.islandModuleIds.get(zeroModuleKey(resolve(id, '..', specifier))) ?? null,\n })\n\n zero.transformed.add(id)\n if (result.erased.exports.length) {\n zero.erasedExports.set(id, result.erased.exports)\n }\n for (const violation of result.violations) {\n const { line, column } = Static.offsetToLineColumn(source, violation.span.start)\n zero.violations.push({\n file: relativePath,\n line,\n column,\n rule: violation.rule,\n code: violation.code,\n component: violation.component,\n message: violation.message,\n })\n }\n if (result.violations.length || !zero.isEnforcing) return null\n\n Static.mergeIslandBridges(zero.bridges, result.bridges)\n for (const [identifier, rules] of result.bridgeCSS) {\n zero.artifact.setBridgeRules(identifier, rules)\n }\n zero.artifact.setZeroModuleCSS(id, plan.css)\n return { ...plan, edits: [...plan.edits, ...result.edits] }\n }\n\n async #publish(platform: string | null): Promise<string> {\n const cache = new MetroCompilerCache(this.cacheRootFor(platform))\n const generation = await cache.publish(\n platform,\n [...this.#entries.values()],\n this.#scanOptionsHash ?? ''\n )\n const zero = this.config.zero\n if (zero && !zero.islandBuild) {\n // the plans and the artifact are the same scan's output, so they are\n // published together or the warm path has nothing safe to reuse\n await cache.publishZeroCSS({\n schemaVersion: METRO_COMPILER_CACHE_VERSION,\n generation,\n configCSS: zero.configCSS,\n zeroModuleCSS: Object.fromEntries(zero.artifact.zeroModuleEntries()),\n bridgeCSS: Object.fromEntries(zero.artifact.bridgeEntries()),\n bridges: Object.fromEntries(zero.bridges),\n })\n }\n this.#publishedGeneration = generation\n return generation\n }\n\n /**\n * Restores the zero build's CSS side effects from the sidecar published with\n * this plan generation. Returns false when there is nothing trustworthy to\n * restore, which sends the caller to a full scan.\n */\n async #rehydrateZeroCSS(cache: MetroCompilerCache, generation: string) {\n const zero = this.config.zero\n if (!zero || zero.islandBuild) return true\n const sidecar = await cache.readZeroCSS(generation)\n if (!sidecar) return false\n zero.artifact.clearGraphs()\n zero.bridges.clear()\n zero.violations.length = 0\n zero.configCSS = sidecar.configCSS\n for (const [moduleId, css] of Object.entries(sidecar.zeroModuleCSS)) {\n zero.artifact.setZeroModuleCSS(moduleId, css)\n }\n for (const [bridgeId, css] of Object.entries(sidecar.bridgeCSS)) {\n zero.artifact.setBridgeRules(bridgeId, css)\n }\n for (const [islandId, bridges] of Object.entries(sidecar.bridges)) {\n zero.bridges.set(islandId, bridges as IslandThemeBridge[])\n }\n zero.plansRestoredFromCache = true\n return true\n }\n\n #installWatchers(): void {\n for (const id of this.#records.keys()) this.#watchModule(id)\n }\n\n #watchModule(id: ResolvedModuleId): void {\n if (this.#watchers.has(id)) return\n try {\n const watcher = watch(id, { persistent: false }, () => {\n void this.updateFile(id)\n })\n watcher.unref()\n this.#watchers.set(id, watcher)\n } catch {\n // A concurrent delete is handled by the importer's next invalidation.\n }\n }\n\n #report(diagnostic: MetroCompilerDiagnostic): void {\n this.config.reportDiagnostic?.(diagnostic)\n }\n}\n\nexport function describeMetroCompilerRoot(projectRoot: string, moduleId: string): string {\n const path = relative(projectRoot, moduleId)\n return path.startsWith('..') ? basename(moduleId) : path\n}\n"
|
|
10
10
|
]
|
|
11
11
|
}
|