@reckona/mreact-compiler 0.0.144 → 0.0.145

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.
@@ -34,6 +34,9 @@ function emitModuleStatements(statements) {
34
34
  function collectComponentImportSpecifiers(ir, dev) {
35
35
  const specifiers = new Set();
36
36
  for (const component of ir.components) {
37
+ if (collectDirectTextBindings(component).length > 0) {
38
+ specifiers.add("REACTIVE_TEXT_BINDING_META");
39
+ }
37
40
  visit(component.root, (node) => {
38
41
  if (node.kind === "fragment") {
39
42
  specifiers.add("Fragment");
@@ -56,6 +59,10 @@ function allocateHelperNames(ir, specifiers) {
56
59
  helperNames.Fragment = allocator("_Fragment");
57
60
  continue;
58
61
  }
62
+ if (specifier === "REACTIVE_TEXT_BINDING_META") {
63
+ helperNames.REACTIVE_TEXT_BINDING_META = allocator("_REACTIVE_TEXT_BINDING_META");
64
+ continue;
65
+ }
59
66
  if (specifier === "jsx") {
60
67
  helperNames.jsx = allocator("_jsx");
61
68
  continue;
@@ -115,7 +122,7 @@ function parseCompatRuntimeImportLine(line) {
115
122
  }
116
123
  return specifierText.split(",").flatMap((rawSpecifier) => {
117
124
  const specifier = rawSpecifier.trim();
118
- const aliasMatch = specifier.match(/^(?<importedName>Fragment|jsx|jsxDEV|jsxs)\s+as\s+(?<localName>[A-Za-z_$][\w$]*)$/);
125
+ const aliasMatch = specifier.match(/^(?<importedName>Fragment|REACTIVE_TEXT_BINDING_META|jsx|jsxDEV|jsxs)\s+as\s+(?<localName>[A-Za-z_$][\w$]*)$/);
119
126
  if (aliasMatch?.groups !== undefined) {
120
127
  const { importedName, localName } = aliasMatch.groups;
121
128
  if (importedName === undefined || localName === undefined) {
@@ -127,7 +134,7 @@ function parseCompatRuntimeImportLine(line) {
127
134
  source,
128
135
  }];
129
136
  }
130
- return /^(Fragment|jsx|jsxDEV|jsxs)$/.test(specifier)
137
+ return /^(Fragment|REACTIVE_TEXT_BINDING_META|jsx|jsxDEV|jsxs)$/.test(specifier)
131
138
  ? [{ importedName: specifier, localName: specifier, source }]
132
139
  : [];
133
140
  });
@@ -143,6 +150,11 @@ function createImportGroups(componentSpecifiers, helperNames, moduleImportSpecif
143
150
  addImportSpecifier(groups, componentImportSource, "Fragment", localName);
144
151
  continue;
145
152
  }
153
+ if (specifier === "REACTIVE_TEXT_BINDING_META") {
154
+ const localName = helperNames.REACTIVE_TEXT_BINDING_META ?? "_REACTIVE_TEXT_BINDING_META";
155
+ addImportSpecifier(groups, componentImportSource, "REACTIVE_TEXT_BINDING_META", localName);
156
+ continue;
157
+ }
146
158
  const localName = helperNames[specifier] ?? `_${specifier}`;
147
159
  addImportSpecifier(groups, componentImportSource, specifier, localName);
148
160
  }
@@ -168,16 +180,18 @@ function emitImportLines(groups) {
168
180
  .join("\n");
169
181
  }
170
182
  function emitComponent(component, helperNames, dev) {
171
- const body = component.bodyStatements.map((statement) => ` ${statement}`);
183
+ const directTextBindings = collectDirectTextBindings(component);
184
+ const body = component.bodyStatements.map((statement) => ` ${rewriteDirectTextBindingStatement(statement, directTextBindings, helperNames)}`);
172
185
  const parameters = component.parameters.join(", ");
186
+ const functionKeyword = `${component.exportDefault === true ? "export default " : component.exported === false ? "" : "export "}${component.async === true ? "async " : ""}function`;
173
187
  return [
174
- `${component.exportDefault === true ? "export default " : component.exported === false ? "" : "export "}function ${component.name}(${parameters}) {`,
188
+ `${functionKeyword} ${component.name}(${parameters}) {`,
175
189
  ...body,
176
- ` return ${emitJsxNode(component.root, helperNames, dev)};`,
190
+ ` return ${emitJsxNode(component.root, helperNames, dev, directTextBindings)};`,
177
191
  `}`,
178
192
  ].join("\n");
179
193
  }
180
- function emitJsxNode(node, helperNames, dev) {
194
+ function emitJsxNode(node, helperNames, dev, directTextBindings = []) {
181
195
  if (node.kind === "text") {
182
196
  return JSON.stringify(node.value);
183
197
  }
@@ -185,22 +199,22 @@ function emitJsxNode(node, helperNames, dev) {
185
199
  return `(${node.code})`;
186
200
  }
187
201
  if (node.kind === "conditional") {
188
- const whenTrue = emitCompatChildren(node.whenTrue, helperNames, dev);
189
- const whenFalse = emitCompatChildren(node.whenFalse, helperNames, dev);
202
+ const whenTrue = emitCompatChildren(node.whenTrue, helperNames, dev, directTextBindings);
203
+ const whenFalse = emitCompatChildren(node.whenFalse, helperNames, dev, directTextBindings);
190
204
  return node.conditionValueName === undefined
191
205
  ? `(${node.conditionCode}) ? ${whenTrue} : ${whenFalse}`
192
206
  : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;
193
207
  }
194
208
  if (node.kind === "list") {
195
209
  const parameters = emitListParameters(node);
196
- return `(${node.itemsCode}).map(${emitListRenderer(node, parameters, helperNames, dev)})`;
210
+ return `(${node.itemsCode}).map(${emitListRenderer(node, parameters, helperNames, dev, directTextBindings)})`;
197
211
  }
198
212
  if (node.kind === "fragment") {
199
213
  return emitJsxCall(helperNames.Fragment ?? "_Fragment", node, helperNames, dev);
200
214
  }
201
215
  if (node.kind === "component") {
202
216
  const keyArgument = node.keyCode === undefined ? undefined : `(${node.keyCode})`;
203
- const props = emitComponentProps(node.props, node.children, helperNames, dev);
217
+ const props = emitComponentProps(node.props, node.children, helperNames, dev, directTextBindings);
204
218
  return dev
205
219
  ? emitJsxDevCall(helperNames.jsxDEV ?? "_jsxDEV", node.name, props, keyArgument, node.children.length > 1)
206
220
  : `${helperNames.jsx ?? "_jsx"}(${node.name}, ${props}${keyArgument === undefined ? "" : `, ${keyArgument}`})`;
@@ -208,19 +222,19 @@ function emitJsxNode(node, helperNames, dev) {
208
222
  if (node.kind === "async-boundary") {
209
223
  return "null";
210
224
  }
211
- return emitJsxCall(JSON.stringify(node.tagName), node, helperNames, dev);
225
+ return emitJsxCall(JSON.stringify(node.tagName), node, helperNames, dev, directTextBindings);
212
226
  }
213
- function emitCompatChildren(children, helperNames, dev) {
227
+ function emitCompatChildren(children, helperNames, dev, directTextBindings = []) {
214
228
  if (children.length === 0) {
215
229
  return "null";
216
230
  }
217
231
  if (children.length === 1) {
218
- return emitJsxNode(children[0], helperNames, dev);
232
+ return emitJsxNode(children[0], helperNames, dev, directTextBindings);
219
233
  }
220
- return `[${children.map((child) => emitJsxNode(child, helperNames, dev)).join(", ")}]`;
234
+ return `[${children.map((child) => emitJsxNode(child, helperNames, dev, directTextBindings)).join(", ")}]`;
221
235
  }
222
- function emitListRenderer(node, parameters, helperNames, dev) {
223
- const valueExpression = emitCompatChildren(node.children, helperNames, dev);
236
+ function emitListRenderer(node, parameters, helperNames, dev, directTextBindings = []) {
237
+ const valueExpression = emitCompatChildren(node.children, helperNames, dev, directTextBindings);
224
238
  if (node.bodyStatements === undefined || node.bodyStatements.length === 0) {
225
239
  return `(${parameters}) => ${valueExpression}`;
226
240
  }
@@ -231,12 +245,12 @@ function emitListParameters(node) {
231
245
  .filter((name) => name !== undefined)
232
246
  .join(", ");
233
247
  }
234
- function emitJsxCall(typeExpression, node, helperNames, dev) {
248
+ function emitJsxCall(typeExpression, node, helperNames, dev, directTextBindings = []) {
235
249
  if (dev) {
236
250
  const keyArgument = node.kind === "element" && node.keyCode !== undefined
237
251
  ? `(${node.keyCode})`
238
252
  : undefined;
239
- return emitJsxDevCall(helperNames.jsxDEV ?? "_jsxDEV", typeExpression, emitProps(node, helperNames, dev), keyArgument, node.children.length > 1);
253
+ return emitJsxDevCall(helperNames.jsxDEV ?? "_jsxDEV", typeExpression, emitProps(node, helperNames, dev, directTextBindings), keyArgument, node.children.length > 1);
240
254
  }
241
255
  const callee = node.children.length > 1
242
256
  ? (helperNames.jsxs ?? "_jsxs")
@@ -244,27 +258,33 @@ function emitJsxCall(typeExpression, node, helperNames, dev) {
244
258
  const keyArgument = node.kind === "element" && node.keyCode !== undefined
245
259
  ? `, (${node.keyCode})`
246
260
  : "";
247
- return `${callee}(${typeExpression}, ${emitProps(node, helperNames, dev)}${keyArgument})`;
261
+ return `${callee}(${typeExpression}, ${emitProps(node, helperNames, dev, directTextBindings)}${keyArgument})`;
248
262
  }
249
263
  function emitJsxDevCall(callee, typeExpression, props, keyArgument, isStaticChildren) {
250
264
  return `${callee}(${typeExpression}, ${props}, ${keyArgument ?? "undefined"}, ${isStaticChildren}, undefined, undefined)`;
251
265
  }
252
- function emitProps(node, helperNames, dev) {
266
+ function emitProps(node, helperNames, dev, directTextBindings = []) {
253
267
  const entries = node.kind === "element" ? node.attributes.map(emitAttribute) : [];
254
- const children = emitChildren(node.children, helperNames, dev);
268
+ const children = emitChildren(node.children, helperNames, dev, directTextBindings);
269
+ const directTextBinding = node.kind === "element"
270
+ ? findDirectTextBindingForChildren(node.children, directTextBindings)
271
+ : undefined;
255
272
  if (children !== undefined) {
256
273
  entries.push(`children: ${children}`);
257
274
  }
275
+ if (directTextBinding !== undefined) {
276
+ entries.push(`[${helperNames.REACTIVE_TEXT_BINDING_META ?? "_REACTIVE_TEXT_BINDING_META"}]: ${directTextBinding.bindingName}`);
277
+ }
258
278
  return `{ ${entries.join(", ")} }`;
259
279
  }
260
- function emitChildren(children, helperNames, dev) {
280
+ function emitChildren(children, helperNames, dev, directTextBindings = []) {
261
281
  if (children.length === 0) {
262
282
  return undefined;
263
283
  }
264
284
  if (children.length === 1) {
265
- return emitJsxNode(children[0], helperNames, dev);
285
+ return emitJsxNode(children[0], helperNames, dev, directTextBindings);
266
286
  }
267
- return `[${children.map((child) => emitJsxNode(child, helperNames, dev)).join(", ")}]`;
287
+ return `[${children.map((child) => emitJsxNode(child, helperNames, dev, directTextBindings)).join(", ")}]`;
268
288
  }
269
289
  function emitAttribute(attr) {
270
290
  if (attr.kind === "spread-attr") {
@@ -278,14 +298,14 @@ function emitAttribute(attr) {
278
298
  }
279
299
  return `${emitPropName(attr.name)}: ${attr.code}`;
280
300
  }
281
- function emitComponentProps(props, children, helperNames, dev) {
301
+ function emitComponentProps(props, children, helperNames, dev, directTextBindings = []) {
282
302
  const entries = props
283
303
  .map((prop) => {
284
304
  if (prop.kind === "spread-prop") {
285
305
  return `...(${prop.code})`;
286
306
  }
287
307
  if (prop.kind === "render-prop") {
288
- const renderedChildren = emitChildren(prop.children, helperNames, dev) ?? "null";
308
+ const renderedChildren = emitChildren(prop.children, helperNames, dev, directTextBindings) ?? "null";
289
309
  return prop.valueName === undefined
290
310
  ? `${emitPropName(prop.name)}: ${renderedChildren}`
291
311
  : `${emitPropName(prop.name)}: (${prop.valueName}) => ${renderedChildren}`;
@@ -294,10 +314,100 @@ function emitComponentProps(props, children, helperNames, dev) {
294
314
  })
295
315
  .filter(Boolean);
296
316
  if (children.length > 0) {
297
- entries.push(`children: ${emitChildren(children, helperNames, dev) ?? "null"}`);
317
+ entries.push(`children: ${emitChildren(children, helperNames, dev, directTextBindings) ?? "null"}`);
298
318
  }
299
319
  return `{ ${entries.join(", ")} }`;
300
320
  }
321
+ function collectDirectTextBindings(component) {
322
+ const candidates = [];
323
+ for (const statement of component.bodyStatements) {
324
+ const match = statement.match(/^\s*const\s+\[\s*(?<stateName>[A-Za-z_$][\w$]*)\s*,\s*[A-Za-z_$][\w$]*\s*\]\s*=\s*useState\(.+\);\s*$/);
325
+ const stateName = match?.groups?.stateName;
326
+ if (stateName === undefined) {
327
+ continue;
328
+ }
329
+ candidates.push({
330
+ stateName,
331
+ tupleName: `_${stateName}StateTuple`,
332
+ bindingName: `_${stateName}TextBinding`,
333
+ });
334
+ }
335
+ return candidates.filter((candidate) => directTextBindingIsSafe(component, candidate));
336
+ }
337
+ function directTextBindingIsSafe(component, candidate) {
338
+ let directTextUses = 0;
339
+ let unsafe = false;
340
+ visit(component.root, (node) => {
341
+ if (node.kind === "expr" && node.code === candidate.stateName) {
342
+ directTextUses += 1;
343
+ return;
344
+ }
345
+ if (node.kind === "expr" && containsIdentifier(node.code, candidate.stateName)) {
346
+ unsafe = true;
347
+ return;
348
+ }
349
+ if (node.kind === "element") {
350
+ for (const attr of node.attributes) {
351
+ if (attr.kind === "static-attr") {
352
+ continue;
353
+ }
354
+ if (containsIdentifier(attr.code, candidate.stateName)) {
355
+ unsafe = true;
356
+ }
357
+ }
358
+ }
359
+ });
360
+ for (const statement of component.bodyStatements) {
361
+ if (isDirectTextBindingDeclaration(statement, candidate.stateName)) {
362
+ continue;
363
+ }
364
+ if (containsIdentifier(statement, candidate.stateName)) {
365
+ unsafe = true;
366
+ }
367
+ }
368
+ return directTextUses === 1 && !unsafe && hasDirectTextBindingHost(component.root, candidate);
369
+ }
370
+ function isDirectTextBindingDeclaration(statement, stateName) {
371
+ return new RegExp(`^\\s*const\\s+\\[\\s*${stateName}\\s*,\\s*[A-Za-z_$][\\w$]*\\s*\\]\\s*=\\s*useState\\(.+\\);\\s*$`).test(statement);
372
+ }
373
+ function hasDirectTextBindingHost(node, candidate) {
374
+ let found = false;
375
+ visit(node, (current) => {
376
+ if (current.kind === "element" &&
377
+ findDirectTextBindingForChildren(current.children, [candidate]) !== undefined) {
378
+ found = true;
379
+ }
380
+ });
381
+ return found;
382
+ }
383
+ function rewriteDirectTextBindingStatement(statement, directTextBindings, helperNames) {
384
+ for (const binding of directTextBindings) {
385
+ const match = statement.match(/^\s*const\s+\[\s*(?<stateName>[A-Za-z_$][\w$]*)\s*,\s*(?<setterName>[A-Za-z_$][\w$]*)\s*\]\s*=\s*(?<initializer>useState\(.+\));\s*$/);
386
+ if (match?.groups?.stateName !== binding.stateName) {
387
+ continue;
388
+ }
389
+ const metadataName = helperNames.REACTIVE_TEXT_BINDING_META ?? "_REACTIVE_TEXT_BINDING_META";
390
+ return [
391
+ `const ${binding.tupleName} = ${match.groups.initializer};`,
392
+ ` const [${binding.stateName}, ${match.groups.setterName}] = ${binding.tupleName};`,
393
+ ` const ${binding.bindingName} = ${binding.tupleName}[${metadataName}];`,
394
+ ].join("\n");
395
+ }
396
+ return statement;
397
+ }
398
+ function findDirectTextBindingForChildren(children, directTextBindings) {
399
+ if (children.length !== 1) {
400
+ return undefined;
401
+ }
402
+ const child = children[0];
403
+ if (child?.kind !== "expr") {
404
+ return undefined;
405
+ }
406
+ return directTextBindings.find((binding) => binding.stateName === child.code);
407
+ }
408
+ function containsIdentifier(code, name) {
409
+ return new RegExp(`(^|[^A-Za-z_$\\d])${name}([^A-Za-z_$\\d]|$)`).test(code);
410
+ }
301
411
  function emitPropName(name) {
302
412
  return /^[A-Za-z_$][\w$]*$/.test(name) ? name : JSON.stringify(name);
303
413
  }
@@ -1 +1 @@
1
- {"version":3,"file":"emit-compat.js","sourceRoot":"","sources":["../src/emit-compat.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AttributeIr,\n ComponentPropIr,\n ComponentIr,\n JsxElementIr,\n JsxFragmentIr,\n JsxNodeIr,\n ModuleIr,\n} from \"./ir.js\";\nimport type { RuntimeImport } from \"./types.js\";\n\nexport interface EmitCompatResult {\n code: string;\n imports: RuntimeImport[];\n}\n\nexport interface EmitCompatOptions {\n dev?: boolean;\n}\n\nconst JSX_RUNTIME_SOURCE = \"@reckona/mreact-compat/jsx-runtime\";\nconst JSX_DEV_RUNTIME_SOURCE = \"@reckona/mreact-compat/jsx-dev-runtime\";\n\nexport function emitCompat(\n ir: ModuleIr,\n options: EmitCompatOptions = {},\n): EmitCompatResult {\n if (ir.components.length === 0 && ir.moduleStatements.length === 0) {\n return {\n code: \"\",\n imports: [],\n };\n }\n\n const normalizedModuleStatements = normalizeCompatModuleStatements(ir.moduleStatements);\n const dev = options.dev === true;\n const componentImportSource = dev ? JSX_DEV_RUNTIME_SOURCE : JSX_RUNTIME_SOURCE;\n const componentSpecifiers = collectComponentImportSpecifiers(ir, dev);\n const helperNames = allocateHelperNames(ir, componentSpecifiers);\n const importGroups = createImportGroups(\n componentSpecifiers,\n helperNames,\n normalizedModuleStatements.importSpecifiers,\n componentImportSource,\n );\n const imports = collectImports(importGroups);\n const importLine = emitImportLines(importGroups);\n const userImports = emitUserImports(ir);\n const moduleStatements = emitModuleStatements(normalizedModuleStatements.statements);\n const components = ir.components\n .map((component) => emitComponent(component, helperNames, dev))\n .join(\"\\n\\n\");\n\n return {\n code: `${[importLine, userImports, moduleStatements].filter(Boolean).join(\"\\n\")}\\n\\n${components}\\n`,\n imports,\n };\n}\n\nfunction emitUserImports(ir: ModuleIr): string {\n return ir.userImports.join(\"\\n\");\n}\n\nfunction emitModuleStatements(statements: readonly string[]): string {\n return statements.join(\"\\n\");\n}\n\nfunction collectComponentImportSpecifiers(ir: ModuleIr, dev: boolean): string[] {\n const specifiers = new Set<string>();\n\n for (const component of ir.components) {\n visit(component.root, (node) => {\n if (node.kind === \"fragment\") {\n specifiers.add(\"Fragment\");\n }\n\n if (node.kind === \"component\") {\n specifiers.add(dev ? \"jsxDEV\" : \"jsx\");\n }\n\n if (node.kind === \"element\" || node.kind === \"fragment\") {\n specifiers.add(dev ? \"jsxDEV\" : node.children.length > 1 ? \"jsxs\" : \"jsx\");\n }\n });\n }\n\n return Array.from(specifiers).sort();\n}\n\ninterface CompatHelperNames {\n Fragment?: string;\n jsx?: string;\n jsxDEV?: string;\n jsxs?: string;\n}\n\nfunction allocateHelperNames(\n ir: ModuleIr,\n specifiers: readonly string[],\n): CompatHelperNames {\n const allocator = createNameAllocator(collectReservedHelperNames(ir));\n const helperNames: CompatHelperNames = {};\n\n for (const specifier of specifiers) {\n if (specifier === \"Fragment\") {\n helperNames.Fragment = allocator(\"_Fragment\");\n continue;\n }\n\n if (specifier === \"jsx\") {\n helperNames.jsx = allocator(\"_jsx\");\n continue;\n }\n\n if (specifier === \"jsxDEV\") {\n helperNames.jsxDEV = allocator(\"_jsxDEV\");\n continue;\n }\n\n if (specifier === \"jsxs\") {\n helperNames.jsxs = allocator(\"_jsxs\");\n }\n }\n\n return helperNames;\n}\n\nfunction collectReservedHelperNames(ir: ModuleIr): string[] {\n return [\n ...ir.moduleBindingNames,\n ...ir.components.flatMap((component) => [\n component.name,\n component.exportName,\n ...component.bindingNames,\n ]),\n ];\n}\n\ninterface CompatRuntimeImportSpecifier {\n importedName: string;\n localName: string;\n source: string;\n}\n\ninterface CompatImportGroup {\n source: string;\n specifiers: Map<string, string>;\n}\n\ninterface NormalizedModuleStatements {\n statements: string[];\n importSpecifiers: CompatRuntimeImportSpecifier[];\n}\n\nfunction normalizeCompatModuleStatements(statements: readonly string[]): NormalizedModuleStatements {\n const importSpecifiers = new Map<string, CompatRuntimeImportSpecifier>();\n const normalizedStatements = statements.map((statement) =>\n stripCompatRuntimeImports(statement, importSpecifiers)\n );\n\n return {\n statements: normalizedStatements,\n importSpecifiers: Array.from(importSpecifiers.values()),\n };\n}\n\nfunction stripCompatRuntimeImports(\n statement: string,\n importSpecifiers: Map<string, CompatRuntimeImportSpecifier>,\n): string {\n return statement\n .split(\"\\n\")\n .filter((line) => {\n const parsed = parseCompatRuntimeImportLine(line);\n\n if (parsed === undefined) {\n return true;\n }\n\n for (const specifier of parsed) {\n importSpecifiers.set(`${specifier.importedName}:${specifier.localName}`, specifier);\n }\n\n return false;\n })\n .join(\"\\n\");\n}\n\nfunction parseCompatRuntimeImportLine(\n line: string,\n): CompatRuntimeImportSpecifier[] | undefined {\n const match = line.match(\n /^\\s*import\\s+\\{\\s*(?<specifiers>[^}]*)\\s*\\}\\s+from\\s+[\"@'](?<source>@reckona\\/mreact-compat\\/jsx(?:-dev)?-runtime)(?:\\.js)?[\"@'];?\\s*$/,\n );\n const specifierText = match?.groups?.specifiers;\n const source = match?.groups?.source;\n\n if (specifierText === undefined || source === undefined) {\n return undefined;\n }\n\n if (specifierText.trim() === \"\") {\n return [];\n }\n\n return specifierText.split(\",\").flatMap((rawSpecifier): CompatRuntimeImportSpecifier[] => {\n const specifier = rawSpecifier.trim();\n const aliasMatch = specifier.match(\n /^(?<importedName>Fragment|jsx|jsxDEV|jsxs)\\s+as\\s+(?<localName>[A-Za-z_$][\\w$]*)$/,\n );\n\n if (aliasMatch?.groups !== undefined) {\n const { importedName, localName } = aliasMatch.groups;\n\n if (importedName === undefined || localName === undefined) {\n return [];\n }\n\n return [{\n importedName,\n localName,\n source,\n }];\n }\n\n return /^(Fragment|jsx|jsxDEV|jsxs)$/.test(specifier)\n ? [{ importedName: specifier, localName: specifier, source }]\n : [];\n });\n}\n\nfunction createImportGroups(\n componentSpecifiers: readonly string[],\n helperNames: CompatHelperNames,\n moduleImportSpecifiers: readonly CompatRuntimeImportSpecifier[],\n componentImportSource: string,\n): CompatImportGroup[] {\n const groups = new Map<string, CompatImportGroup>();\n\n for (const moduleSpecifier of moduleImportSpecifiers) {\n addImportSpecifier(\n groups,\n moduleSpecifier.source,\n moduleSpecifier.importedName,\n moduleSpecifier.localName,\n );\n }\n\n for (const specifier of componentSpecifiers) {\n if (specifier === \"Fragment\") {\n const localName = helperNames.Fragment ?? \"_Fragment\";\n addImportSpecifier(groups, componentImportSource, \"Fragment\", localName);\n continue;\n }\n\n const localName = helperNames[specifier as \"jsx\" | \"jsxDEV\" | \"jsxs\"] ?? `_${specifier}`;\n addImportSpecifier(groups, componentImportSource, specifier, localName);\n }\n\n return Array.from(groups.values());\n}\n\nfunction addImportSpecifier(\n groups: Map<string, CompatImportGroup>,\n source: string,\n importedName: string,\n localName: string,\n): void {\n const group = groups.get(source) ?? {\n source,\n specifiers: new Map<string, string>(),\n };\n\n group.specifiers.set(\n `${importedName}:${localName}`,\n importedName === localName ? importedName : `${importedName} as ${localName}`,\n );\n groups.set(source, group);\n}\n\nfunction collectImports(groups: readonly CompatImportGroup[]): RuntimeImport[] {\n return groups.map((group) => ({\n source: group.source,\n specifiers: Array.from(\n new Set(Array.from(group.specifiers.keys(), (key) => key.split(\":\")[0] as string)),\n ).sort(),\n }));\n}\n\nfunction emitImportLines(groups: readonly CompatImportGroup[]): string {\n return groups\n .map((group) =>\n `import { ${Array.from(group.specifiers.values()).join(\", \")} } from \"${group.source}\";`\n )\n .join(\"\\n\");\n}\n\nfunction emitComponent(\n component: ComponentIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n const body = component.bodyStatements.map((statement) => ` ${statement}`);\n const parameters = component.parameters.join(\", \");\n\n return [\n `${component.exportDefault === true ? \"export default \" : component.exported === false ? \"\" : \"export \"}function ${component.name}(${parameters}) {`,\n ...body,\n ` return ${emitJsxNode(component.root, helperNames, dev)};`,\n `}`,\n ].join(\"\\n\");\n}\n\nfunction emitJsxNode(\n node: JsxNodeIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n if (node.kind === \"text\") {\n return JSON.stringify(node.value);\n }\n\n if (node.kind === \"expr\") {\n return `(${node.code})`;\n }\n\n if (node.kind === \"conditional\") {\n const whenTrue = emitCompatChildren(node.whenTrue, helperNames, dev);\n const whenFalse = emitCompatChildren(node.whenFalse, helperNames, dev);\n\n return node.conditionValueName === undefined\n ? `(${node.conditionCode}) ? ${whenTrue} : ${whenFalse}`\n : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;\n }\n\n if (node.kind === \"list\") {\n const parameters = emitListParameters(node);\n return `(${node.itemsCode}).map(${emitListRenderer(node, parameters, helperNames, dev)})`;\n }\n\n if (node.kind === \"fragment\") {\n return emitJsxCall(helperNames.Fragment ?? \"_Fragment\", node, helperNames, dev);\n }\n\n if (node.kind === \"component\") {\n const keyArgument =\n node.keyCode === undefined ? undefined : `(${node.keyCode})`;\n const props = emitComponentProps(node.props, node.children, helperNames, dev);\n return dev\n ? emitJsxDevCall(helperNames.jsxDEV ?? \"_jsxDEV\", node.name, props, keyArgument, node.children.length > 1)\n : `${helperNames.jsx ?? \"_jsx\"}(${node.name}, ${props}${keyArgument === undefined ? \"\" : `, ${keyArgument}`})`;\n }\n\n if (node.kind === \"async-boundary\") {\n return \"null\";\n }\n\n return emitJsxCall(JSON.stringify(node.tagName), node, helperNames, dev);\n}\n\nfunction emitCompatChildren(\n children: JsxNodeIr[],\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n if (children.length === 0) {\n return \"null\";\n }\n\n if (children.length === 1) {\n return emitJsxNode(children[0] as JsxNodeIr, helperNames, dev);\n }\n\n return `[${children.map((child) => emitJsxNode(child, helperNames, dev)).join(\", \")}]`;\n}\n\nfunction emitListRenderer(\n node: Extract<JsxNodeIr, { kind: \"list\" }>,\n parameters: string,\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n const valueExpression = emitCompatChildren(node.children, helperNames, dev);\n\n if (node.bodyStatements === undefined || node.bodyStatements.length === 0) {\n return `(${parameters}) => ${valueExpression}`;\n }\n\n return `(${parameters}) => {\\n${node.bodyStatements.map((statement) => ` ${statement}`).join(\"\\n\")}\\n return ${valueExpression};\\n }`;\n}\n\nfunction emitListParameters(node: Extract<JsxNodeIr, { kind: \"list\" }>): string {\n return [node.itemName, node.indexName, node.arrayName]\n .filter((name): name is string => name !== undefined)\n .join(\", \");\n}\n\nfunction emitJsxCall(\n typeExpression: string,\n node: JsxElementIr | JsxFragmentIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n if (dev) {\n const keyArgument =\n node.kind === \"element\" && node.keyCode !== undefined\n ? `(${node.keyCode})`\n : undefined;\n return emitJsxDevCall(\n helperNames.jsxDEV ?? \"_jsxDEV\",\n typeExpression,\n emitProps(node, helperNames, dev),\n keyArgument,\n node.children.length > 1,\n );\n }\n\n const callee =\n node.children.length > 1\n ? (helperNames.jsxs ?? \"_jsxs\")\n : (helperNames.jsx ?? \"_jsx\");\n const keyArgument =\n node.kind === \"element\" && node.keyCode !== undefined\n ? `, (${node.keyCode})`\n : \"\";\n\n return `${callee}(${typeExpression}, ${emitProps(node, helperNames, dev)}${keyArgument})`;\n}\n\nfunction emitJsxDevCall(\n callee: string,\n typeExpression: string,\n props: string,\n keyArgument: string | undefined,\n isStaticChildren: boolean,\n): string {\n return `${callee}(${typeExpression}, ${props}, ${keyArgument ?? \"undefined\"}, ${isStaticChildren}, undefined, undefined)`;\n}\n\nfunction emitProps(\n node: JsxElementIr | JsxFragmentIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n const entries =\n node.kind === \"element\" ? node.attributes.map(emitAttribute) : [];\n const children = emitChildren(node.children, helperNames, dev);\n\n if (children !== undefined) {\n entries.push(`children: ${children}`);\n }\n\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction emitChildren(\n children: JsxNodeIr[],\n helperNames: CompatHelperNames,\n dev: boolean,\n): string | undefined {\n if (children.length === 0) {\n return undefined;\n }\n\n if (children.length === 1) {\n return emitJsxNode(children[0] as JsxNodeIr, helperNames, dev);\n }\n\n return `[${children.map((child) => emitJsxNode(child, helperNames, dev)).join(\", \")}]`;\n}\n\nfunction emitAttribute(attr: AttributeIr): string {\n if (attr.kind === \"spread-attr\") {\n return `...(${attr.code})`;\n }\n\n if (attr.kind === \"static-attr\") {\n return `${emitPropName(attr.name)}: ${JSON.stringify(attr.value)}`;\n }\n\n if (attr.kind === \"dynamic-attr\") {\n return `${emitPropName(attr.name)}: (${attr.code})`;\n }\n\n return `${emitPropName(attr.name)}: ${attr.code}`;\n}\n\nfunction emitComponentProps(\n props: ComponentPropIr[],\n children: JsxNodeIr[],\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n const entries = props\n .map((prop) => {\n if (prop.kind === \"spread-prop\") {\n return `...(${prop.code})`;\n }\n\n if (prop.kind === \"render-prop\") {\n const renderedChildren = emitChildren(prop.children, helperNames, dev) ?? \"null\";\n return prop.valueName === undefined\n ? `${emitPropName(prop.name)}: ${renderedChildren}`\n : `${emitPropName(prop.name)}: (${prop.valueName}) => ${renderedChildren}`;\n }\n\n return `${emitPropName(prop.name)}: (${prop.code})`;\n })\n .filter(Boolean);\n\n if (children.length > 0) {\n entries.push(`children: ${emitChildren(children, helperNames, dev) ?? \"null\"}`);\n }\n\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction emitPropName(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction createNameAllocator(\n reservedNames: readonly string[],\n): (baseName: string) => string {\n const usedNames = new Set(reservedNames);\n\n return (baseName: string): string => {\n let name = baseName;\n let index = 1;\n\n while (usedNames.has(name)) {\n name = `${baseName}$${index}`;\n index += 1;\n }\n\n usedNames.add(name);\n return name;\n };\n}\n\nfunction visit(node: JsxNodeIr, fn: (node: JsxNodeIr) => void): void {\n fn(node);\n\n if (node.kind === \"conditional\") {\n for (const child of [...node.whenTrue, ...node.whenFalse]) {\n visit(child, fn);\n }\n }\n\n if (node.kind === \"list\") {\n for (const child of node.children) {\n visit(child, fn);\n }\n }\n\n if (node.kind === \"component\") {\n for (const prop of node.props) {\n if (prop.kind === \"render-prop\") {\n for (const child of prop.children) {\n visit(child, fn);\n }\n }\n }\n\n for (const child of node.children) {\n visit(child, fn);\n }\n }\n\n if (node.kind === \"element\" || node.kind === \"fragment\") {\n for (const child of node.children) {\n visit(child, fn);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"emit-compat.js","sourceRoot":"","sources":["../src/emit-compat.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n AttributeIr,\n ComponentPropIr,\n ComponentIr,\n JsxElementIr,\n JsxFragmentIr,\n JsxNodeIr,\n ModuleIr,\n} from \"./ir.js\";\nimport type { RuntimeImport } from \"./types.js\";\n\nexport interface EmitCompatResult {\n code: string;\n imports: RuntimeImport[];\n}\n\nexport interface EmitCompatOptions {\n dev?: boolean;\n}\n\nconst JSX_RUNTIME_SOURCE = \"@reckona/mreact-compat/jsx-runtime\";\nconst JSX_DEV_RUNTIME_SOURCE = \"@reckona/mreact-compat/jsx-dev-runtime\";\n\nexport function emitCompat(\n ir: ModuleIr,\n options: EmitCompatOptions = {},\n): EmitCompatResult {\n if (ir.components.length === 0 && ir.moduleStatements.length === 0) {\n return {\n code: \"\",\n imports: [],\n };\n }\n\n const normalizedModuleStatements = normalizeCompatModuleStatements(ir.moduleStatements);\n const dev = options.dev === true;\n const componentImportSource = dev ? JSX_DEV_RUNTIME_SOURCE : JSX_RUNTIME_SOURCE;\n const componentSpecifiers = collectComponentImportSpecifiers(ir, dev);\n const helperNames = allocateHelperNames(ir, componentSpecifiers);\n const importGroups = createImportGroups(\n componentSpecifiers,\n helperNames,\n normalizedModuleStatements.importSpecifiers,\n componentImportSource,\n );\n const imports = collectImports(importGroups);\n const importLine = emitImportLines(importGroups);\n const userImports = emitUserImports(ir);\n const moduleStatements = emitModuleStatements(normalizedModuleStatements.statements);\n const components = ir.components\n .map((component) => emitComponent(component, helperNames, dev))\n .join(\"\\n\\n\");\n\n return {\n code: `${[importLine, userImports, moduleStatements].filter(Boolean).join(\"\\n\")}\\n\\n${components}\\n`,\n imports,\n };\n}\n\nfunction emitUserImports(ir: ModuleIr): string {\n return ir.userImports.join(\"\\n\");\n}\n\nfunction emitModuleStatements(statements: readonly string[]): string {\n return statements.join(\"\\n\");\n}\n\nfunction collectComponentImportSpecifiers(ir: ModuleIr, dev: boolean): string[] {\n const specifiers = new Set<string>();\n\n for (const component of ir.components) {\n if (collectDirectTextBindings(component).length > 0) {\n specifiers.add(\"REACTIVE_TEXT_BINDING_META\");\n }\n\n visit(component.root, (node) => {\n if (node.kind === \"fragment\") {\n specifiers.add(\"Fragment\");\n }\n\n if (node.kind === \"component\") {\n specifiers.add(dev ? \"jsxDEV\" : \"jsx\");\n }\n\n if (node.kind === \"element\" || node.kind === \"fragment\") {\n specifiers.add(dev ? \"jsxDEV\" : node.children.length > 1 ? \"jsxs\" : \"jsx\");\n }\n });\n }\n\n return Array.from(specifiers).sort();\n}\n\ninterface CompatHelperNames {\n Fragment?: string;\n REACTIVE_TEXT_BINDING_META?: string;\n jsx?: string;\n jsxDEV?: string;\n jsxs?: string;\n}\n\ninterface DirectTextBinding {\n stateName: string;\n tupleName: string;\n bindingName: string;\n}\n\nfunction allocateHelperNames(\n ir: ModuleIr,\n specifiers: readonly string[],\n): CompatHelperNames {\n const allocator = createNameAllocator(collectReservedHelperNames(ir));\n const helperNames: CompatHelperNames = {};\n\n for (const specifier of specifiers) {\n if (specifier === \"Fragment\") {\n helperNames.Fragment = allocator(\"_Fragment\");\n continue;\n }\n\n if (specifier === \"REACTIVE_TEXT_BINDING_META\") {\n helperNames.REACTIVE_TEXT_BINDING_META = allocator(\"_REACTIVE_TEXT_BINDING_META\");\n continue;\n }\n\n if (specifier === \"jsx\") {\n helperNames.jsx = allocator(\"_jsx\");\n continue;\n }\n\n if (specifier === \"jsxDEV\") {\n helperNames.jsxDEV = allocator(\"_jsxDEV\");\n continue;\n }\n\n if (specifier === \"jsxs\") {\n helperNames.jsxs = allocator(\"_jsxs\");\n }\n }\n\n return helperNames;\n}\n\nfunction collectReservedHelperNames(ir: ModuleIr): string[] {\n return [\n ...ir.moduleBindingNames,\n ...ir.components.flatMap((component) => [\n component.name,\n component.exportName,\n ...component.bindingNames,\n ]),\n ];\n}\n\ninterface CompatRuntimeImportSpecifier {\n importedName: string;\n localName: string;\n source: string;\n}\n\ninterface CompatImportGroup {\n source: string;\n specifiers: Map<string, string>;\n}\n\ninterface NormalizedModuleStatements {\n statements: string[];\n importSpecifiers: CompatRuntimeImportSpecifier[];\n}\n\nfunction normalizeCompatModuleStatements(statements: readonly string[]): NormalizedModuleStatements {\n const importSpecifiers = new Map<string, CompatRuntimeImportSpecifier>();\n const normalizedStatements = statements.map((statement) =>\n stripCompatRuntimeImports(statement, importSpecifiers)\n );\n\n return {\n statements: normalizedStatements,\n importSpecifiers: Array.from(importSpecifiers.values()),\n };\n}\n\nfunction stripCompatRuntimeImports(\n statement: string,\n importSpecifiers: Map<string, CompatRuntimeImportSpecifier>,\n): string {\n return statement\n .split(\"\\n\")\n .filter((line) => {\n const parsed = parseCompatRuntimeImportLine(line);\n\n if (parsed === undefined) {\n return true;\n }\n\n for (const specifier of parsed) {\n importSpecifiers.set(`${specifier.importedName}:${specifier.localName}`, specifier);\n }\n\n return false;\n })\n .join(\"\\n\");\n}\n\nfunction parseCompatRuntimeImportLine(\n line: string,\n): CompatRuntimeImportSpecifier[] | undefined {\n const match = line.match(\n /^\\s*import\\s+\\{\\s*(?<specifiers>[^}]*)\\s*\\}\\s+from\\s+[\"@'](?<source>@reckona\\/mreact-compat\\/jsx(?:-dev)?-runtime)(?:\\.js)?[\"@'];?\\s*$/,\n );\n const specifierText = match?.groups?.specifiers;\n const source = match?.groups?.source;\n\n if (specifierText === undefined || source === undefined) {\n return undefined;\n }\n\n if (specifierText.trim() === \"\") {\n return [];\n }\n\n return specifierText.split(\",\").flatMap((rawSpecifier): CompatRuntimeImportSpecifier[] => {\n const specifier = rawSpecifier.trim();\n const aliasMatch = specifier.match(\n /^(?<importedName>Fragment|REACTIVE_TEXT_BINDING_META|jsx|jsxDEV|jsxs)\\s+as\\s+(?<localName>[A-Za-z_$][\\w$]*)$/,\n );\n\n if (aliasMatch?.groups !== undefined) {\n const { importedName, localName } = aliasMatch.groups;\n\n if (importedName === undefined || localName === undefined) {\n return [];\n }\n\n return [{\n importedName,\n localName,\n source,\n }];\n }\n\n return /^(Fragment|REACTIVE_TEXT_BINDING_META|jsx|jsxDEV|jsxs)$/.test(specifier)\n ? [{ importedName: specifier, localName: specifier, source }]\n : [];\n });\n}\n\nfunction createImportGroups(\n componentSpecifiers: readonly string[],\n helperNames: CompatHelperNames,\n moduleImportSpecifiers: readonly CompatRuntimeImportSpecifier[],\n componentImportSource: string,\n): CompatImportGroup[] {\n const groups = new Map<string, CompatImportGroup>();\n\n for (const moduleSpecifier of moduleImportSpecifiers) {\n addImportSpecifier(\n groups,\n moduleSpecifier.source,\n moduleSpecifier.importedName,\n moduleSpecifier.localName,\n );\n }\n\n for (const specifier of componentSpecifiers) {\n if (specifier === \"Fragment\") {\n const localName = helperNames.Fragment ?? \"_Fragment\";\n addImportSpecifier(groups, componentImportSource, \"Fragment\", localName);\n continue;\n }\n\n if (specifier === \"REACTIVE_TEXT_BINDING_META\") {\n const localName = helperNames.REACTIVE_TEXT_BINDING_META ?? \"_REACTIVE_TEXT_BINDING_META\";\n addImportSpecifier(groups, componentImportSource, \"REACTIVE_TEXT_BINDING_META\", localName);\n continue;\n }\n\n const localName = helperNames[specifier as \"jsx\" | \"jsxDEV\" | \"jsxs\"] ?? `_${specifier}`;\n addImportSpecifier(groups, componentImportSource, specifier, localName);\n }\n\n return Array.from(groups.values());\n}\n\nfunction addImportSpecifier(\n groups: Map<string, CompatImportGroup>,\n source: string,\n importedName: string,\n localName: string,\n): void {\n const group = groups.get(source) ?? {\n source,\n specifiers: new Map<string, string>(),\n };\n\n group.specifiers.set(\n `${importedName}:${localName}`,\n importedName === localName ? importedName : `${importedName} as ${localName}`,\n );\n groups.set(source, group);\n}\n\nfunction collectImports(groups: readonly CompatImportGroup[]): RuntimeImport[] {\n return groups.map((group) => ({\n source: group.source,\n specifiers: Array.from(\n new Set(Array.from(group.specifiers.keys(), (key) => key.split(\":\")[0] as string)),\n ).sort(),\n }));\n}\n\nfunction emitImportLines(groups: readonly CompatImportGroup[]): string {\n return groups\n .map((group) =>\n `import { ${Array.from(group.specifiers.values()).join(\", \")} } from \"${group.source}\";`\n )\n .join(\"\\n\");\n}\n\nfunction emitComponent(\n component: ComponentIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n): string {\n const directTextBindings = collectDirectTextBindings(component);\n const body = component.bodyStatements.map((statement) =>\n ` ${rewriteDirectTextBindingStatement(statement, directTextBindings, helperNames)}`\n );\n const parameters = component.parameters.join(\", \");\n const functionKeyword = `${component.exportDefault === true ? \"export default \" : component.exported === false ? \"\" : \"export \"}${\n component.async === true ? \"async \" : \"\"\n }function`;\n\n return [\n `${functionKeyword} ${component.name}(${parameters}) {`,\n ...body,\n ` return ${emitJsxNode(component.root, helperNames, dev, directTextBindings)};`,\n `}`,\n ].join(\"\\n\");\n}\n\nfunction emitJsxNode(\n node: JsxNodeIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string {\n if (node.kind === \"text\") {\n return JSON.stringify(node.value);\n }\n\n if (node.kind === \"expr\") {\n return `(${node.code})`;\n }\n\n if (node.kind === \"conditional\") {\n const whenTrue = emitCompatChildren(node.whenTrue, helperNames, dev, directTextBindings);\n const whenFalse = emitCompatChildren(node.whenFalse, helperNames, dev, directTextBindings);\n\n return node.conditionValueName === undefined\n ? `(${node.conditionCode}) ? ${whenTrue} : ${whenFalse}`\n : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;\n }\n\n if (node.kind === \"list\") {\n const parameters = emitListParameters(node);\n return `(${node.itemsCode}).map(${emitListRenderer(node, parameters, helperNames, dev, directTextBindings)})`;\n }\n\n if (node.kind === \"fragment\") {\n return emitJsxCall(helperNames.Fragment ?? \"_Fragment\", node, helperNames, dev);\n }\n\n if (node.kind === \"component\") {\n const keyArgument =\n node.keyCode === undefined ? undefined : `(${node.keyCode})`;\n const props = emitComponentProps(node.props, node.children, helperNames, dev, directTextBindings);\n return dev\n ? emitJsxDevCall(helperNames.jsxDEV ?? \"_jsxDEV\", node.name, props, keyArgument, node.children.length > 1)\n : `${helperNames.jsx ?? \"_jsx\"}(${node.name}, ${props}${keyArgument === undefined ? \"\" : `, ${keyArgument}`})`;\n }\n\n if (node.kind === \"async-boundary\") {\n return \"null\";\n }\n\n return emitJsxCall(JSON.stringify(node.tagName), node, helperNames, dev, directTextBindings);\n}\n\nfunction emitCompatChildren(\n children: JsxNodeIr[],\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string {\n if (children.length === 0) {\n return \"null\";\n }\n\n if (children.length === 1) {\n return emitJsxNode(children[0] as JsxNodeIr, helperNames, dev, directTextBindings);\n }\n\n return `[${children.map((child) => emitJsxNode(child, helperNames, dev, directTextBindings)).join(\", \")}]`;\n}\n\nfunction emitListRenderer(\n node: Extract<JsxNodeIr, { kind: \"list\" }>,\n parameters: string,\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string {\n const valueExpression = emitCompatChildren(node.children, helperNames, dev, directTextBindings);\n\n if (node.bodyStatements === undefined || node.bodyStatements.length === 0) {\n return `(${parameters}) => ${valueExpression}`;\n }\n\n return `(${parameters}) => {\\n${node.bodyStatements.map((statement) => ` ${statement}`).join(\"\\n\")}\\n return ${valueExpression};\\n }`;\n}\n\nfunction emitListParameters(node: Extract<JsxNodeIr, { kind: \"list\" }>): string {\n return [node.itemName, node.indexName, node.arrayName]\n .filter((name): name is string => name !== undefined)\n .join(\", \");\n}\n\nfunction emitJsxCall(\n typeExpression: string,\n node: JsxElementIr | JsxFragmentIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string {\n if (dev) {\n const keyArgument =\n node.kind === \"element\" && node.keyCode !== undefined\n ? `(${node.keyCode})`\n : undefined;\n return emitJsxDevCall(\n helperNames.jsxDEV ?? \"_jsxDEV\",\n typeExpression,\n emitProps(node, helperNames, dev, directTextBindings),\n keyArgument,\n node.children.length > 1,\n );\n }\n\n const callee =\n node.children.length > 1\n ? (helperNames.jsxs ?? \"_jsxs\")\n : (helperNames.jsx ?? \"_jsx\");\n const keyArgument =\n node.kind === \"element\" && node.keyCode !== undefined\n ? `, (${node.keyCode})`\n : \"\";\n\n return `${callee}(${typeExpression}, ${emitProps(node, helperNames, dev, directTextBindings)}${keyArgument})`;\n}\n\nfunction emitJsxDevCall(\n callee: string,\n typeExpression: string,\n props: string,\n keyArgument: string | undefined,\n isStaticChildren: boolean,\n): string {\n return `${callee}(${typeExpression}, ${props}, ${keyArgument ?? \"undefined\"}, ${isStaticChildren}, undefined, undefined)`;\n}\n\nfunction emitProps(\n node: JsxElementIr | JsxFragmentIr,\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string {\n const entries =\n node.kind === \"element\" ? node.attributes.map(emitAttribute) : [];\n const children = emitChildren(node.children, helperNames, dev, directTextBindings);\n const directTextBinding = node.kind === \"element\"\n ? findDirectTextBindingForChildren(node.children, directTextBindings)\n : undefined;\n\n if (children !== undefined) {\n entries.push(`children: ${children}`);\n }\n\n if (directTextBinding !== undefined) {\n entries.push(\n `[${helperNames.REACTIVE_TEXT_BINDING_META ?? \"_REACTIVE_TEXT_BINDING_META\"}]: ${directTextBinding.bindingName}`,\n );\n }\n\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction emitChildren(\n children: JsxNodeIr[],\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string | undefined {\n if (children.length === 0) {\n return undefined;\n }\n\n if (children.length === 1) {\n return emitJsxNode(children[0] as JsxNodeIr, helperNames, dev, directTextBindings);\n }\n\n return `[${children.map((child) => emitJsxNode(child, helperNames, dev, directTextBindings)).join(\", \")}]`;\n}\n\nfunction emitAttribute(attr: AttributeIr): string {\n if (attr.kind === \"spread-attr\") {\n return `...(${attr.code})`;\n }\n\n if (attr.kind === \"static-attr\") {\n return `${emitPropName(attr.name)}: ${JSON.stringify(attr.value)}`;\n }\n\n if (attr.kind === \"dynamic-attr\") {\n return `${emitPropName(attr.name)}: (${attr.code})`;\n }\n\n return `${emitPropName(attr.name)}: ${attr.code}`;\n}\n\nfunction emitComponentProps(\n props: ComponentPropIr[],\n children: JsxNodeIr[],\n helperNames: CompatHelperNames,\n dev: boolean,\n directTextBindings: readonly DirectTextBinding[] = [],\n): string {\n const entries = props\n .map((prop) => {\n if (prop.kind === \"spread-prop\") {\n return `...(${prop.code})`;\n }\n\n if (prop.kind === \"render-prop\") {\n const renderedChildren =\n emitChildren(prop.children, helperNames, dev, directTextBindings) ?? \"null\";\n return prop.valueName === undefined\n ? `${emitPropName(prop.name)}: ${renderedChildren}`\n : `${emitPropName(prop.name)}: (${prop.valueName}) => ${renderedChildren}`;\n }\n\n return `${emitPropName(prop.name)}: (${prop.code})`;\n })\n .filter(Boolean);\n\n if (children.length > 0) {\n entries.push(`children: ${emitChildren(children, helperNames, dev, directTextBindings) ?? \"null\"}`);\n }\n\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction collectDirectTextBindings(component: ComponentIr): DirectTextBinding[] {\n const candidates: DirectTextBinding[] = [];\n\n for (const statement of component.bodyStatements) {\n const match = statement.match(\n /^\\s*const\\s+\\[\\s*(?<stateName>[A-Za-z_$][\\w$]*)\\s*,\\s*[A-Za-z_$][\\w$]*\\s*\\]\\s*=\\s*useState\\(.+\\);\\s*$/,\n );\n const stateName = match?.groups?.stateName;\n\n if (stateName === undefined) {\n continue;\n }\n\n candidates.push({\n stateName,\n tupleName: `_${stateName}StateTuple`,\n bindingName: `_${stateName}TextBinding`,\n });\n }\n\n return candidates.filter((candidate) => directTextBindingIsSafe(component, candidate));\n}\n\nfunction directTextBindingIsSafe(\n component: ComponentIr,\n candidate: DirectTextBinding,\n): boolean {\n let directTextUses = 0;\n let unsafe = false;\n\n visit(component.root, (node) => {\n if (node.kind === \"expr\" && node.code === candidate.stateName) {\n directTextUses += 1;\n return;\n }\n\n if (node.kind === \"expr\" && containsIdentifier(node.code, candidate.stateName)) {\n unsafe = true;\n return;\n }\n\n if (node.kind === \"element\") {\n for (const attr of node.attributes) {\n if (attr.kind === \"static-attr\") {\n continue;\n }\n\n if (containsIdentifier(attr.code, candidate.stateName)) {\n unsafe = true;\n }\n }\n }\n });\n\n for (const statement of component.bodyStatements) {\n if (isDirectTextBindingDeclaration(statement, candidate.stateName)) {\n continue;\n }\n\n if (containsIdentifier(statement, candidate.stateName)) {\n unsafe = true;\n }\n }\n\n return directTextUses === 1 && !unsafe && hasDirectTextBindingHost(component.root, candidate);\n}\n\nfunction isDirectTextBindingDeclaration(statement: string, stateName: string): boolean {\n return new RegExp(\n `^\\\\s*const\\\\s+\\\\[\\\\s*${stateName}\\\\s*,\\\\s*[A-Za-z_$][\\\\w$]*\\\\s*\\\\]\\\\s*=\\\\s*useState\\\\(.+\\\\);\\\\s*$`,\n ).test(statement);\n}\n\nfunction hasDirectTextBindingHost(\n node: JsxNodeIr,\n candidate: DirectTextBinding,\n): boolean {\n let found = false;\n\n visit(node, (current) => {\n if (\n current.kind === \"element\" &&\n findDirectTextBindingForChildren(current.children, [candidate]) !== undefined\n ) {\n found = true;\n }\n });\n\n return found;\n}\n\nfunction rewriteDirectTextBindingStatement(\n statement: string,\n directTextBindings: readonly DirectTextBinding[],\n helperNames: CompatHelperNames,\n): string {\n for (const binding of directTextBindings) {\n const match = statement.match(\n /^\\s*const\\s+\\[\\s*(?<stateName>[A-Za-z_$][\\w$]*)\\s*,\\s*(?<setterName>[A-Za-z_$][\\w$]*)\\s*\\]\\s*=\\s*(?<initializer>useState\\(.+\\));\\s*$/,\n );\n\n if (match?.groups?.stateName !== binding.stateName) {\n continue;\n }\n\n const metadataName = helperNames.REACTIVE_TEXT_BINDING_META ?? \"_REACTIVE_TEXT_BINDING_META\";\n return [\n `const ${binding.tupleName} = ${match.groups.initializer};`,\n ` const [${binding.stateName}, ${match.groups.setterName}] = ${binding.tupleName};`,\n ` const ${binding.bindingName} = ${binding.tupleName}[${metadataName}];`,\n ].join(\"\\n\");\n }\n\n return statement;\n}\n\nfunction findDirectTextBindingForChildren(\n children: readonly JsxNodeIr[],\n directTextBindings: readonly DirectTextBinding[],\n): DirectTextBinding | undefined {\n if (children.length !== 1) {\n return undefined;\n }\n\n const child = children[0];\n\n if (child?.kind !== \"expr\") {\n return undefined;\n }\n\n return directTextBindings.find((binding) => binding.stateName === child.code);\n}\n\nfunction containsIdentifier(code: string, name: string): boolean {\n return new RegExp(`(^|[^A-Za-z_$\\\\d])${name}([^A-Za-z_$\\\\d]|$)`).test(code);\n}\n\nfunction emitPropName(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction createNameAllocator(\n reservedNames: readonly string[],\n): (baseName: string) => string {\n const usedNames = new Set(reservedNames);\n\n return (baseName: string): string => {\n let name = baseName;\n let index = 1;\n\n while (usedNames.has(name)) {\n name = `${baseName}$${index}`;\n index += 1;\n }\n\n usedNames.add(name);\n return name;\n };\n}\n\nfunction visit(node: JsxNodeIr, fn: (node: JsxNodeIr) => void): void {\n fn(node);\n\n if (node.kind === \"conditional\") {\n for (const child of [...node.whenTrue, ...node.whenFalse]) {\n visit(child, fn);\n }\n }\n\n if (node.kind === \"list\") {\n for (const child of node.children) {\n visit(child, fn);\n }\n }\n\n if (node.kind === \"component\") {\n for (const prop of node.props) {\n if (prop.kind === \"render-prop\") {\n for (const child of prop.children) {\n visit(child, fn);\n }\n }\n }\n\n for (const child of node.children) {\n visit(child, fn);\n }\n }\n\n if (node.kind === \"element\" || node.kind === \"fragment\") {\n for (const child of node.children) {\n visit(child, fn);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAuC,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEhG,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAShE;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,cAAc,GAAG;IAAE,aAAa,EAAE,qBAAqB,CAAA;CAAE,GAC/D,eAAe,CAWjB"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAuC,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEhG,OAAO,KAAK,EAIV,cAAc,EACd,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,eAAe,CAShE;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,cAAc,GAAG;IAAE,aAAa,EAAE,qBAAqB,CAAA;CAAE,GAC/D,eAAe,CAWjB"}
package/dist/transform.js CHANGED
@@ -3,6 +3,7 @@ import { emitCompat } from "./emit-compat.js";
3
3
  import { emitServer } from "./emit-server.js";
4
4
  import { emitServerStream } from "./emit-server-stream.js";
5
5
  import { analyzeCompilerModuleContextWithOxc, analyzeWithOxc } from "./oxc.js";
6
+ import { unsupportedClientAsyncComponentDiagnostic } from "./diagnostics.js";
6
7
  export function transform(input) {
7
8
  return transformWithAnalyzer(input, (analyzeTarget, analyzeOptions) => analyzeWithOxc({
8
9
  code: input.code,
@@ -48,6 +49,9 @@ function transformWithAnalyzer(input, analyze) {
48
49
  };
49
50
  const analyzed = analyze(analyzeTarget, analyzeOptions);
50
51
  const diagnostics = [...analyzed.diagnostics];
52
+ if (input.target === "client") {
53
+ diagnostics.push(...collectClientAsyncComponentDiagnostics(analyzed.ir.components));
54
+ }
51
55
  const emitted = mode === "compat" && input.target === "client"
52
56
  ? emitCompat(analyzed.ir, { dev: input.dev })
53
57
  : input.target === "server"
@@ -119,6 +123,11 @@ function transformWithAnalyzer(input, analyze) {
119
123
  metadata,
120
124
  };
121
125
  }
126
+ function collectClientAsyncComponentDiagnostics(components) {
127
+ return components
128
+ .filter((component) => component.async === true)
129
+ .map((component) => unsupportedClientAsyncComponentDiagnostic(component.name));
130
+ }
122
131
  function createSourceMap(input, outputCode) {
123
132
  const generatedMap = createSegmentMappings(outputCode, input.code);
124
133
  return JSON.stringify({