@tamagui/metro-plugin 2.7.7 → 3.0.0-beta.637.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.
Files changed (72) hide show
  1. package/README.md +12 -0
  2. package/dist/cjs/babel.cjs +77 -0
  3. package/dist/cjs/compilerCache.cjs +237 -0
  4. package/dist/cjs/diagnostics.cjs +41 -0
  5. package/dist/cjs/frontend.cjs +870 -0
  6. package/dist/cjs/index.cjs +102 -0
  7. package/dist/cjs/lowering.cjs +109 -0
  8. package/dist/cjs/metroResolver.cjs +197 -0
  9. package/dist/cjs/transformOptions.cjs +35 -0
  10. package/dist/cjs/transformer.cjs +142 -0
  11. package/dist/cjs/zeroRuntime.cjs +140 -0
  12. package/dist/cjs/zeroSerializer.cjs +150 -0
  13. package/dist/esm/babel.mjs +52 -0
  14. package/dist/esm/babel.mjs.map +1 -0
  15. package/dist/esm/compilerCache.mjs +212 -0
  16. package/dist/esm/compilerCache.mjs.map +1 -0
  17. package/dist/esm/diagnostics.mjs +18 -0
  18. package/dist/esm/diagnostics.mjs.map +1 -0
  19. package/dist/esm/frontend.mjs +839 -0
  20. package/dist/esm/frontend.mjs.map +1 -0
  21. package/dist/esm/index.mjs +64 -22
  22. package/dist/esm/index.mjs.map +1 -1
  23. package/dist/esm/lowering.mjs +89 -0
  24. package/dist/esm/lowering.mjs.map +1 -0
  25. package/dist/esm/metroResolver.mjs +173 -0
  26. package/dist/esm/metroResolver.mjs.map +1 -0
  27. package/dist/esm/transformOptions.mjs +14 -0
  28. package/dist/esm/transformOptions.mjs.map +1 -0
  29. package/dist/esm/transformer.mjs +119 -0
  30. package/dist/esm/transformer.mjs.map +1 -0
  31. package/dist/esm/zeroRuntime.mjs +105 -0
  32. package/dist/esm/zeroRuntime.mjs.map +1 -0
  33. package/dist/esm/zeroSerializer.mjs +123 -0
  34. package/dist/esm/zeroSerializer.mjs.map +1 -0
  35. package/package.json +33 -5
  36. package/src/babel.ts +87 -0
  37. package/src/compilerCache.ts +346 -0
  38. package/src/diagnostics.ts +47 -0
  39. package/src/frontend.ts +1178 -0
  40. package/src/index.ts +117 -14
  41. package/src/lowering.ts +136 -0
  42. package/src/metroResolver.ts +209 -0
  43. package/src/transformOptions.ts +36 -0
  44. package/src/transformer.ts +210 -0
  45. package/src/zeroRuntime.ts +212 -0
  46. package/src/zeroSerializer.ts +175 -0
  47. package/types/babel.d.ts +28 -0
  48. package/types/babel.d.ts.map +11 -0
  49. package/types/compilerCache.d.ts +63 -0
  50. package/types/compilerCache.d.ts.map +11 -0
  51. package/types/diagnostics.d.ts +16 -0
  52. package/types/diagnostics.d.ts.map +11 -0
  53. package/types/frontend.d.ts +73 -0
  54. package/types/frontend.d.ts.map +11 -0
  55. package/types/index.d.ts +49 -32
  56. package/types/index.d.ts.map +11 -1
  57. package/types/lowering.d.ts +20 -0
  58. package/types/lowering.d.ts.map +11 -0
  59. package/types/metroResolver.d.ts +21 -0
  60. package/types/metroResolver.d.ts.map +11 -0
  61. package/types/transformOptions.d.ts +13 -0
  62. package/types/transformOptions.d.ts.map +11 -0
  63. package/types/transformer.d.ts +26 -0
  64. package/types/transformer.d.ts.map +11 -0
  65. package/types/zeroRuntime.d.ts +75 -0
  66. package/types/zeroRuntime.d.ts.map +11 -0
  67. package/types/zeroSerializer.d.ts +6 -0
  68. package/types/zeroSerializer.d.ts.map +11 -0
  69. package/dist/cjs/index.js +0 -45
  70. package/dist/cjs/index.js.map +0 -6
  71. package/dist/esm/index.js +0 -25
  72. package/dist/esm/index.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # `@tamagui/metro-plugin`
2
+
3
+ The E4 frontend runs the configured user Babel transformer first, resolves the
4
+ compiled module graph with Metro's resolver contract in the main process, and
5
+ publishes versioned content-addressed `LoweredModulePlan` values for isolated Metro
6
+ workers.
7
+
8
+ The cache, invalidation, diagnostics, and worker handoff are production-owned. Workers
9
+ apply the same compiler-core plan used by Vite to the post-user-Babel source, parse the
10
+ lowered output back into a Babel AST, and compose locations through both compiler maps.
11
+ Uncertain candidates remain byte-identical runtime work. The deleted Babel/static Metro
12
+ extractor is never invoked as a fallback.
@@ -0,0 +1,77 @@
1
+
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all) __defProp(target, name, {
8
+ get: all[name],
9
+ enumerable: true
10
+ });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: () => from[key],
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var babel_exports = {};
23
+ __export(babel_exports, {
24
+ compileWithUserBabel: () => compileWithUserBabel,
25
+ loadMetroBabelTransformer: () => loadMetroBabelTransformer,
26
+ transformerDirectory: () => transformerDirectory,
27
+ userBabelCacheKey: () => userBabelCacheKey
28
+ });
29
+ module.exports = __toCommonJS(babel_exports);
30
+ var import_node_crypto = require("node:crypto");
31
+ var import_node_module = require("node:module");
32
+ var import_node_path = require("node:path");
33
+ function asTransformer(module2, path) {
34
+ const transformer = module2?.default?.transform ? module2.default : module2;
35
+ if (!transformer || typeof transformer.transform !== "function") {
36
+ throw new Error(`Metro Babel transformer ${path} has no transform function`);
37
+ }
38
+ return transformer;
39
+ }
40
+ function loadMetroBabelTransformer(path) {
41
+ return asTransformer((0, import_node_module.createRequire)(path)(path), path);
42
+ }
43
+ async function compileWithUserBabel(transformerPath, args) {
44
+ const transformer = loadMetroBabelTransformer(transformerPath);
45
+ const result = await transformer.transform(args);
46
+ if (!result?.ast) {
47
+ throw new Error(`Metro Babel transformer ${transformerPath} returned no AST`);
48
+ }
49
+ const requireFromTransformer = (0, import_node_module.createRequire)(transformerPath);
50
+ const generatorModule = requireFromTransformer("@babel/generator");
51
+ const generate = generatorModule.default ?? generatorModule;
52
+ const generated = generate(result.ast, {
53
+ comments: true,
54
+ compact: false,
55
+ retainLines: true,
56
+ sourceFileName: args.filename,
57
+ sourceMaps: true
58
+ }, args.src);
59
+ if (!generated || typeof generated.code !== "string") {
60
+ throw new Error(`Babel generator for ${transformerPath} returned no code`);
61
+ }
62
+ if (!generated.map) {
63
+ throw new Error(`Babel generator for ${transformerPath} returned no source map`);
64
+ }
65
+ return {
66
+ code: generated.code,
67
+ map: generated.map,
68
+ result
69
+ };
70
+ }
71
+ function userBabelCacheKey(transformerPath) {
72
+ const transformer = loadMetroBabelTransformer(transformerPath);
73
+ return (0, import_node_crypto.createHash)("sha256").update(transformerPath).update("\0").update(transformer.getCacheKey?.() ?? "").digest("hex");
74
+ }
75
+ function transformerDirectory(transformerPath) {
76
+ return (0, import_node_path.dirname)(transformerPath);
77
+ }
@@ -0,0 +1,237 @@
1
+
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all) __defProp(target, name, {
8
+ get: all[name],
9
+ enumerable: true
10
+ });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: () => from[key],
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var compilerCache_exports = {};
23
+ __export(compilerCache_exports, {
24
+ METRO_COMPILER_CACHE_VERSION: () => METRO_COMPILER_CACHE_VERSION,
25
+ MetroCompilerCache: () => MetroCompilerCache,
26
+ MetroCompilerCacheError: () => MetroCompilerCacheError,
27
+ defaultMetroCompilerCacheRoot: () => defaultMetroCompilerCacheRoot
28
+ });
29
+ module.exports = __toCommonJS(compilerCache_exports);
30
+ var import_node_crypto = require("node:crypto");
31
+ var import_promises = require("node:fs/promises");
32
+ var import_node_path = require("node:path");
33
+ var import_compiler_core = require("@tamagui/compiler-core");
34
+ var import_diagnostics = require("./diagnostics.cjs");
35
+ const METRO_COMPILER_CACHE_VERSION = 6;
36
+ var MetroCompilerCacheError = class extends Error {
37
+ constructor(diagnostic) {
38
+ super(diagnostic.message);
39
+ this.diagnostic = diagnostic;
40
+ this.name = "MetroCompilerCacheError";
41
+ }
42
+ diagnostic;
43
+ };
44
+ function compareCodeUnits(left, right) {
45
+ return left < right ? -1 : left > right ? 1 : 0;
46
+ }
47
+ function stableEntries(record) {
48
+ return Object.entries(record).sort(([left], [right]) => compareCodeUnits(left, right));
49
+ }
50
+ function cacheCorrupt(message, moduleId) {
51
+ return new MetroCompilerCacheError((0, import_diagnostics.metroDiagnostic)("metro/cache-corrupt", message, { moduleId }));
52
+ }
53
+ function parseJson(source, description, moduleId) {
54
+ try {
55
+ return JSON.parse(source);
56
+ } catch (error) {
57
+ throw cacheCorrupt(`${description} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`, moduleId);
58
+ }
59
+ }
60
+ function defaultMetroCompilerCacheRoot(projectRoot) {
61
+ return (0, import_node_path.join)((0, import_compiler_core.tamaguiCacheRoot)(projectRoot), "metro-compiler");
62
+ }
63
+ var MetroCompilerCache = class {
64
+ constructor(root) {
65
+ this.root = root;
66
+ this.#blobsDirectory = (0, import_node_path.join)(root, `v${METRO_COMPILER_CACHE_VERSION}`, "blobs");
67
+ this.#manifestPath = (0, import_node_path.join)(root, `v${METRO_COMPILER_CACHE_VERSION}`, "manifest.json");
68
+ }
69
+ root;
70
+ #blobsDirectory;
71
+ #manifestPath;
72
+ async publish(platform, entries, optionsHash) {
73
+ await (0, import_promises.mkdir)(this.#blobsDirectory, { recursive: true });
74
+ const descriptors = {};
75
+ for (const entry of [...entries].sort((left, right) => compareCodeUnits(left.moduleId, right.moduleId))) {
76
+ if (entry.schemaVersion !== METRO_COMPILER_CACHE_VERSION) {
77
+ throw new Error(`Cannot publish cache schema ${entry.schemaVersion}`);
78
+ }
79
+ const serialized = `${(0, import_compiler_core.stableStringify)(entry)}
80
+ `;
81
+ const blobHash = (0, import_compiler_core.contentHash)(serialized);
82
+ const blobPath = (0, import_node_path.join)(this.#blobsDirectory, `${blobHash}.json`);
83
+ try {
84
+ await (0, import_promises.writeFile)(blobPath, serialized, {
85
+ encoding: "utf8",
86
+ flag: "wx"
87
+ });
88
+ } catch (error) {
89
+ if (error.code !== "EEXIST") throw error;
90
+ const existing = await (0, import_promises.readFile)(blobPath, "utf8");
91
+ if ((0, import_compiler_core.contentHash)(existing) !== blobHash) {
92
+ const temporaryBlobPath = `${blobPath}.${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}.tmp`;
93
+ await (0, import_promises.writeFile)(temporaryBlobPath, serialized, "utf8");
94
+ await (0, import_promises.rename)(temporaryBlobPath, blobPath);
95
+ }
96
+ }
97
+ descriptors[entry.moduleId] = {
98
+ blobHash,
99
+ sourceHash: entry.sourceHash
100
+ };
101
+ }
102
+ const generation = (0, import_compiler_core.contentHash)((0, import_compiler_core.stableStringify)(descriptors));
103
+ const manifest = {
104
+ schemaVersion: METRO_COMPILER_CACHE_VERSION,
105
+ generation,
106
+ optionsHash,
107
+ platform,
108
+ entries: descriptors
109
+ };
110
+ const manifestDirectory = (0, import_node_path.join)(this.root, `v${METRO_COMPILER_CACHE_VERSION}`);
111
+ const temporaryPath = (0, import_node_path.join)(manifestDirectory, `.manifest-${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}.json`);
112
+ await (0, import_promises.writeFile)(temporaryPath, `${(0, import_compiler_core.stableStringify)(manifest)}
113
+ `, "utf8");
114
+ await (0, import_promises.rename)(temporaryPath, this.#manifestPath);
115
+ return generation;
116
+ }
117
+ async read(moduleId, rawSource, onMiss) {
118
+ const manifest = await this.#readManifest();
119
+ if (!manifest) return null;
120
+ const descriptor = manifest.entries[moduleId];
121
+ if (!descriptor) {
122
+ onMiss?.("no-entry");
123
+ return null;
124
+ }
125
+ const sourceHash = (0, import_compiler_core.contentHash)(rawSource);
126
+ if (sourceHash !== descriptor.sourceHash) {
127
+ onMiss?.("source-hash-mismatch", `worker ${sourceHash.slice(0, 12)} vs plan ${descriptor.sourceHash.slice(0, 12)}`);
128
+ return null;
129
+ }
130
+ return await this.#readBlob(moduleId, descriptor);
131
+ }
132
+ async validate() {
133
+ const diagnostics = [];
134
+ try {
135
+ const manifest = await this.#readManifest();
136
+ if (!manifest) {
137
+ return {
138
+ valid: false,
139
+ diagnostics,
140
+ generation: null,
141
+ moduleIds: [],
142
+ sourceHashes: {},
143
+ optionsHash: null
144
+ };
145
+ }
146
+ const sourceHashes = {};
147
+ for (const [moduleId, descriptor] of stableEntries(manifest.entries)) {
148
+ await this.#readBlob(moduleId, descriptor);
149
+ sourceHashes[moduleId] = descriptor.sourceHash;
150
+ }
151
+ return {
152
+ valid: true,
153
+ diagnostics,
154
+ generation: manifest.generation,
155
+ moduleIds: Object.keys(manifest.entries).sort(compareCodeUnits),
156
+ sourceHashes,
157
+ optionsHash: manifest.optionsHash
158
+ };
159
+ } catch (error) {
160
+ if (error instanceof MetroCompilerCacheError) {
161
+ diagnostics.push(error.diagnostic);
162
+ return {
163
+ valid: false,
164
+ diagnostics,
165
+ generation: null,
166
+ moduleIds: [],
167
+ sourceHashes: {},
168
+ optionsHash: null
169
+ };
170
+ }
171
+ throw error;
172
+ }
173
+ }
174
+ async discardManifest() {
175
+ await (0, import_promises.rm)(this.#manifestPath, { force: true });
176
+ }
177
+ #zeroSidecarPath(generation) {
178
+ return (0, import_node_path.join)(this.root, `v${METRO_COMPILER_CACHE_VERSION}`, `zero-${generation.slice(0, 32)}.json`);
179
+ }
180
+ async publishZeroCSS(sidecar) {
181
+ await (0, import_promises.mkdir)((0, import_node_path.join)(this.root, `v${METRO_COMPILER_CACHE_VERSION}`), { recursive: true });
182
+ const file = this.#zeroSidecarPath(sidecar.generation);
183
+ const temporaryPath = `${file}.${process.pid}-${(0, import_node_crypto.randomBytes)(6).toString("hex")}.tmp`;
184
+ await (0, import_promises.writeFile)(temporaryPath, `${(0, import_compiler_core.stableStringify)(sidecar)}
185
+ `, "utf8");
186
+ await (0, import_promises.rename)(temporaryPath, file);
187
+ }
188
+ /** Null whenever the sidecar is absent or does not describe this generation. */
189
+ async readZeroCSS(generation) {
190
+ let source;
191
+ try {
192
+ source = await (0, import_promises.readFile)(this.#zeroSidecarPath(generation), "utf8");
193
+ } catch (error) {
194
+ if (error.code === "ENOENT") return null;
195
+ throw error;
196
+ }
197
+ const sidecar = parseJson(source, "Zero CSS sidecar");
198
+ 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") {
199
+ return null;
200
+ }
201
+ return sidecar;
202
+ }
203
+ async #readManifest() {
204
+ let source;
205
+ try {
206
+ source = await (0, import_promises.readFile)(this.#manifestPath, "utf8");
207
+ } catch (error) {
208
+ if (error.code === "ENOENT") return null;
209
+ throw error;
210
+ }
211
+ const manifest = parseJson(source, "Cache manifest");
212
+ if (manifest.schemaVersion !== METRO_COMPILER_CACHE_VERSION || typeof manifest.generation !== "string" || typeof manifest.optionsHash !== "string" || !manifest.entries || typeof manifest.entries !== "object") {
213
+ throw cacheCorrupt("Cache manifest has an unsupported schema");
214
+ }
215
+ return manifest;
216
+ }
217
+ async #readBlob(moduleId, descriptor) {
218
+ const blobPath = (0, import_node_path.join)(this.#blobsDirectory, `${descriptor.blobHash}.json`);
219
+ let source;
220
+ try {
221
+ source = await (0, import_promises.readFile)(blobPath, "utf8");
222
+ } catch (error) {
223
+ if (error.code === "ENOENT") {
224
+ throw cacheCorrupt(`Cache blob ${descriptor.blobHash} is missing`, moduleId);
225
+ }
226
+ throw error;
227
+ }
228
+ if ((0, import_compiler_core.contentHash)(source) !== descriptor.blobHash) {
229
+ throw cacheCorrupt(`Cache blob ${descriptor.blobHash} failed its hash`, moduleId);
230
+ }
231
+ const entry = parseJson(source, `Cache blob ${descriptor.blobHash}`, moduleId);
232
+ if (entry.schemaVersion !== METRO_COMPILER_CACHE_VERSION || entry.moduleId !== moduleId || typeof entry.sourceHash !== "string" || entry.sourceHash !== descriptor.sourceHash || !entry.plan || entry.plan.version !== import_compiler_core.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)) {
233
+ throw cacheCorrupt(`Cache blob ${descriptor.blobHash} has invalid contents`, moduleId);
234
+ }
235
+ return entry;
236
+ }
237
+ };
@@ -0,0 +1,41 @@
1
+
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all) __defProp(target, name, {
8
+ get: all[name],
9
+ enumerable: true
10
+ });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
15
+ get: () => from[key],
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ return to;
20
+ };
21
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
22
+ var diagnostics_exports = {};
23
+ __export(diagnostics_exports, {
24
+ formatMetroCompilerDiagnostic: () => formatMetroCompilerDiagnostic,
25
+ metroDiagnostic: () => metroDiagnostic
26
+ });
27
+ module.exports = __toCommonJS(diagnostics_exports);
28
+ var import_node_path = require("node:path");
29
+ function metroDiagnostic(code, message, details = {}) {
30
+ return {
31
+ code,
32
+ message,
33
+ ...details
34
+ };
35
+ }
36
+ function formatMetroCompilerDiagnostic(diagnostic, projectRoot) {
37
+ const sourceId = diagnostic.span?.id ?? diagnostic.moduleId;
38
+ const file = sourceId ? (0, import_node_path.isAbsolute)(sourceId) ? (0, import_node_path.relative)(projectRoot, sourceId) || "." : sourceId : null;
39
+ const location = file && diagnostic.line != null && diagnostic.column != null ? `${file}:${diagnostic.line}:${diagnostic.column}: ` : "";
40
+ return `[@tamagui/metro-plugin] ${location}${diagnostic.code}: ${diagnostic.message}`;
41
+ }