@fluixi/compiler 1.0.0-alpha.55 → 1.0.0-alpha.57
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/babel-DZ7BC6T2.mjs +2 -0
- package/dist/frontend/babel/build-ir-lit.cjs +1 -0
- package/dist/frontend/babel/build-ir-lit.d.ts +26 -0
- package/dist/frontend/babel/build-ir-lit.d.ts.map +1 -0
- package/dist/frontend/babel/build-ir-lit.js +9 -0
- package/dist/frontend/babel/build-ir-lit.mjs +1 -0
- package/dist/frontend/babel/build-ir.cjs +1 -1
- package/dist/frontend/babel/build-ir.d.ts +11 -0
- package/dist/frontend/babel/build-ir.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir.js +72 -13
- package/dist/frontend/babel/build-ir.mjs +1 -1
- package/dist/frontend/babel/index.cjs +2 -2
- package/dist/frontend/babel/index.mjs +2 -2
- package/dist/frontend/babel/lower-template.cjs +1 -0
- package/dist/frontend/babel/lower-template.d.ts +21 -0
- package/dist/frontend/babel/lower-template.d.ts.map +1 -0
- package/dist/frontend/babel/lower-template.js +447 -0
- package/dist/frontend/babel/lower-template.mjs +1 -0
- package/dist/frontend/babel/plugin.cjs +2 -2
- package/dist/frontend/babel/plugin.d.ts +21 -0
- package/dist/frontend/babel/plugin.d.ts.map +1 -1
- package/dist/frontend/babel/plugin.js +144 -206
- package/dist/frontend/babel/plugin.mjs +2 -2
- package/dist/integrations.cjs +7 -7
- package/dist/integrations.d.ts +19 -0
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +3 -0
- package/dist/integrations.mjs +4 -4
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/dist/babel-OGRQKOZA.mjs +0 -2
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { declare } from '@babel/helper-plugin-utils';
|
|
14
14
|
import { types as t, template, } from '@babel/core';
|
|
15
15
|
import { buildIR } from './build-ir.js';
|
|
16
|
+
import { buildIRFromLit } from './build-ir-lit.js';
|
|
16
17
|
import { imperativeBackend } from '../../codegen/backends/imperative.js';
|
|
17
18
|
// ============================================================================
|
|
18
19
|
// Constants
|
|
@@ -27,7 +28,16 @@ const CONTROL_FLOW_COMPONENTS = new Set([
|
|
|
27
28
|
'Dynamic',
|
|
28
29
|
'ErrorBoundary',
|
|
29
30
|
'Suspense',
|
|
31
|
+
'Await',
|
|
30
32
|
]);
|
|
33
|
+
// Control-flow components that live in @fluixi/core, NOT @fluixi/dom — they must
|
|
34
|
+
// be auto-imported from core (dom doesn't export them).
|
|
35
|
+
const CORE_ONLY_CONTROL_FLOW = new Set(['Suspense', 'SuspenseList', 'Await']);
|
|
36
|
+
// Router components auto-imported (from routerModule) the same way control flow is:
|
|
37
|
+
// use `<Router>`/`<Outlet>`/… in a template and the import is injected if absent.
|
|
38
|
+
// (`Routes` isn't a component — routing is `<Router routes={…}>`; `lazy` is a function
|
|
39
|
+
// call, not a tag, so neither can be auto-imported this way.)
|
|
40
|
+
const ROUTER_COMPONENTS = new Set(['Router', 'Outlet', 'Redirect', 'Link']);
|
|
31
41
|
// Control-flow components read a single reactive *value* prop inside their own tracking
|
|
32
42
|
// scope. Emit that prop as a getter (like `children`) so reading it re-runs the caller's
|
|
33
43
|
// expression — otherwise `each={items()}` / `when={cond()}` snapshot once and never update.
|
|
@@ -73,7 +83,12 @@ const DELEGATABLE_EVENTS = [
|
|
|
73
83
|
// ============================================================================
|
|
74
84
|
export default declare((api, options = {}) => {
|
|
75
85
|
api.assertVersion(7);
|
|
76
|
-
const { runtime = 'automatic', importSource = '@fluixi/jsx', pragma = 'jsx', pragmaFrag = 'Fragment', development = false, detectReactivity = true, useLitHTML = true, hoistStatics = true, delegateEvents = true, delegatedEvents = DELEGATABLE_EVENTS, optimizeControlFlow = true, sourceMaps = true, signalModule = '@fluixi/dom', controlFlowModule = '@fluixi/dom', reactiveModule = '@fluixi/reactive/signal', autoShowTransform = false, backend = 'imperative', codegen = 'inline',
|
|
86
|
+
const { runtime = 'automatic', importSource = '@fluixi/jsx', pragma = 'jsx', pragmaFrag = 'Fragment', development = false, detectReactivity = true, useLitHTML = true, hoistStatics = true, delegateEvents = true, delegatedEvents = DELEGATABLE_EVENTS, optimizeControlFlow = true, sourceMaps = true, signalModule = '@fluixi/dom', controlFlowModule = '@fluixi/dom', routerModule = '@fluixi/core/router-next', reactiveModule = '@fluixi/reactive/signal', autoShowTransform = false, backend = 'imperative', codegen = 'inline',
|
|
87
|
+
// `both` by default: JSX and html`` are compiled out of the box, so
|
|
88
|
+
// `fluixi()` needs no `format` option. Injected imports are deduped, so a
|
|
89
|
+
// file mixing the two styles won't redeclare a binding.
|
|
90
|
+
format = 'both', litTag = 'html', } = options;
|
|
91
|
+
const compileLit = format === 'lit' || format === 'both';
|
|
77
92
|
const pluginState = {
|
|
78
93
|
backend,
|
|
79
94
|
codegen,
|
|
@@ -118,8 +133,8 @@ export default declare((api, options = {}) => {
|
|
|
118
133
|
hasJSX: false,
|
|
119
134
|
hasReactivity: false,
|
|
120
135
|
hasLitHTML: false,
|
|
136
|
+
hasLitIR: false,
|
|
121
137
|
needsSignalImport: false,
|
|
122
|
-
needsLitrxImport: false,
|
|
123
138
|
needsControlFlowImport: false,
|
|
124
139
|
needsCreateMemo: false,
|
|
125
140
|
controlFlowComponents: new Set(),
|
|
@@ -147,16 +162,12 @@ export default declare((api, options = {}) => {
|
|
|
147
162
|
t.importSpecifier(t.identifier('signal'), t.identifier('signal')),
|
|
148
163
|
], t.stringLiteral(signalModule)));
|
|
149
164
|
}
|
|
150
|
-
if (state.needsLitrxImport && !path.scope.hasBinding('litrx')) {
|
|
151
|
-
imports.push(t.importDeclaration([
|
|
152
|
-
t.importSpecifier(t.identifier('litrx'), t.identifier('litrx')),
|
|
153
|
-
], t.stringLiteral(state.libModule)));
|
|
154
|
-
}
|
|
155
165
|
}
|
|
156
|
-
if (state.hasJSX) {
|
|
157
|
-
if (
|
|
158
|
-
// IR pipeline
|
|
159
|
-
//
|
|
166
|
+
if (state.hasJSX || state.hasLitIR) {
|
|
167
|
+
if (state.irImports.size > 0) {
|
|
168
|
+
// IR pipeline (JSX codegen:'ir' and/or lit templates): import exactly
|
|
169
|
+
// the symbols emit() reported, splitting control-flow components to
|
|
170
|
+
// the control-flow module.
|
|
160
171
|
const CF = new Set([
|
|
161
172
|
'Show', 'For', 'Index', 'Switch', 'Match',
|
|
162
173
|
'Dynamic', 'ErrorBoundary', 'Portal', 'Suspense',
|
|
@@ -182,7 +193,7 @@ export default declare((api, options = {}) => {
|
|
|
182
193
|
imports.push(t.importDeclaration(cf.map(spec), t.stringLiteral(controlFlowModule)));
|
|
183
194
|
}
|
|
184
195
|
}
|
|
185
|
-
|
|
196
|
+
if (state.hasJSX && backend === 'imperative' && codegen !== 'ir') {
|
|
186
197
|
// Compiled imperative output: import only the runtime primitives
|
|
187
198
|
// actually emitted, straight from the dom runtime module.
|
|
188
199
|
const want = [
|
|
@@ -199,7 +210,7 @@ export default declare((api, options = {}) => {
|
|
|
199
210
|
imports.push(t.importDeclaration(specifiers, t.stringLiteral(signalModule)));
|
|
200
211
|
}
|
|
201
212
|
}
|
|
202
|
-
else if (runtime === 'automatic') {
|
|
213
|
+
else if (state.hasJSX && runtime === 'automatic') {
|
|
203
214
|
// Add JSX runtime imports
|
|
204
215
|
const specifiers = [
|
|
205
216
|
t.importSpecifier(t.identifier('jsx'), t.identifier('jsx')),
|
|
@@ -227,10 +238,21 @@ export default declare((api, options = {}) => {
|
|
|
227
238
|
if (state.needsControlFlowImport &&
|
|
228
239
|
state.controlFlowComponents.size > 0) {
|
|
229
240
|
const unbound = Array.from(state.controlFlowComponents).filter((name) => !path.scope.hasBinding(name));
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
241
|
+
// Suspense/SuspenseList live in @fluixi/core, not @fluixi/dom, so
|
|
242
|
+
// they must be auto-imported from core (importing them from the dom
|
|
243
|
+
// controlFlowModule would resolve to nothing). Everything else comes
|
|
244
|
+
// from controlFlowModule.
|
|
245
|
+
const coreModule = state.libModule ?? '@fluixi/core';
|
|
246
|
+
const fromRouter = unbound.filter((n) => ROUTER_COMPONENTS.has(n));
|
|
247
|
+
const fromCore = unbound.filter((n) => CORE_ONLY_CONTROL_FLOW.has(n));
|
|
248
|
+
const fromDom = unbound.filter((n) => !CORE_ONLY_CONTROL_FLOW.has(n) && !ROUTER_COMPONENTS.has(n));
|
|
249
|
+
const declFor = (names, mod) => t.importDeclaration(names.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name))), t.stringLiteral(mod));
|
|
250
|
+
if (fromDom.length > 0)
|
|
251
|
+
imports.push(declFor(fromDom, controlFlowModule));
|
|
252
|
+
if (fromCore.length > 0)
|
|
253
|
+
imports.push(declFor(fromCore, coreModule));
|
|
254
|
+
if (fromRouter.length > 0)
|
|
255
|
+
imports.push(declFor(fromRouter, routerModule));
|
|
234
256
|
}
|
|
235
257
|
// Add event delegation setup if needed
|
|
236
258
|
if (delegateEvents && state.delegatedEvents.size > 0) {
|
|
@@ -253,11 +275,12 @@ export default declare((api, options = {}) => {
|
|
|
253
275
|
path.node.body.unshift(...hoisted);
|
|
254
276
|
}
|
|
255
277
|
}
|
|
256
|
-
// Add all imports at the top
|
|
278
|
+
// Add all imports at the top, deduped. When a file mixes inline JSX
|
|
279
|
+
// and html`` (format 'both'), the two injection paths can each emit an
|
|
280
|
+
// import for the same module/name — merge per-module and drop repeated
|
|
281
|
+
// specifiers so we never redeclare a binding.
|
|
257
282
|
if (imports.length > 0) {
|
|
258
|
-
|
|
259
|
-
// console.log('imports', imports);
|
|
260
|
-
path.node.body.unshift(...imports);
|
|
283
|
+
path.node.body.unshift(...dedupeImports(imports));
|
|
261
284
|
}
|
|
262
285
|
},
|
|
263
286
|
},
|
|
@@ -271,6 +294,13 @@ export default declare((api, options = {}) => {
|
|
|
271
294
|
}
|
|
272
295
|
const element = path.node;
|
|
273
296
|
const openingElement = element.openingElement;
|
|
297
|
+
// Router components auto-import like control flow, but aren't optimized —
|
|
298
|
+
// just register the name so the import gets injected if it isn't bound.
|
|
299
|
+
if (t.isJSXIdentifier(openingElement.name) &&
|
|
300
|
+
ROUTER_COMPONENTS.has(openingElement.name.name)) {
|
|
301
|
+
state.controlFlowComponents.add(openingElement.name.name);
|
|
302
|
+
state.needsControlFlowImport = true;
|
|
303
|
+
}
|
|
274
304
|
// Check if it's a control flow component
|
|
275
305
|
if (t.isJSXIdentifier(openingElement.name) &&
|
|
276
306
|
CONTROL_FLOW_COMPONENTS.has(openingElement.name.name)) {
|
|
@@ -345,194 +375,20 @@ export default declare((api, options = {}) => {
|
|
|
345
375
|
// no-op
|
|
346
376
|
},
|
|
347
377
|
TaggedTemplateExpression(path, state) {
|
|
348
|
-
//
|
|
349
|
-
//
|
|
350
|
-
//
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
.get('quasi')
|
|
359
|
-
.get('expressions')
|
|
360
|
-
.forEach((expPath, index) => {
|
|
361
|
-
const node = expPath.node;
|
|
362
|
-
// 2. Attribute Check: Look at the string part right before the expression
|
|
363
|
-
// Lit attributes look like: name="${exp}" or @click="${exp}"
|
|
364
|
-
const prevStringPart = quasi.quasis[index].value.raw;
|
|
365
|
-
const isAttribute = prevStringPart.trim().endsWith('=') ||
|
|
366
|
-
prevStringPart.match(/@[\w-]+$/);
|
|
367
|
-
if (isAttribute)
|
|
368
|
-
return; // Skip wrapping event listeners or attributes
|
|
369
|
-
// 3. Narrowing for Signal Calls: count()
|
|
370
|
-
// const isSignalCall = t.isCallExpression(node);
|
|
371
|
-
const isSignalCall = false;
|
|
372
|
-
// 4. Narrowing for Member Access: item.$name
|
|
373
|
-
let isReactiveMember = false;
|
|
374
|
-
if (t.isMemberExpression(node)) {
|
|
375
|
-
const property = node.property;
|
|
376
|
-
// Use Type Guard to narrow from Expression | PrivateName to Identifier
|
|
377
|
-
if (t.isIdentifier(property)) {
|
|
378
|
-
// console.log('exp', node);
|
|
379
|
-
property.name = property.name.replace('$', '');
|
|
380
|
-
state.needsLitrxImport = true;
|
|
381
|
-
isReactiveMember = true;
|
|
382
|
-
// if (property.name.startsWith('$')) {
|
|
383
|
-
// }
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
if (isSignalCall || isReactiveMember) {
|
|
387
|
-
// Transform: ${exp} -> ${watch(() => exp)}
|
|
388
|
-
expPath.replaceWith(
|
|
389
|
-
//t.identifier('litrx')
|
|
390
|
-
// t.identifier('(window as any).Fluixi.litrx')
|
|
391
|
-
t.callExpression(t.identifier('((window as any).Fluixi.litrx || litrx)'), [t.arrowFunctionExpression([], node)]));
|
|
392
|
-
}
|
|
393
|
-
});
|
|
378
|
+
// Compile `html`...`` (and `svg`...``) templates through the shared IR
|
|
379
|
+
// pipeline: same IR the JSX front-end builds, same imperative backend,
|
|
380
|
+
// same runtime calls.
|
|
381
|
+
if (compileLit &&
|
|
382
|
+
backend === 'imperative' &&
|
|
383
|
+
t.isIdentifier(path.node.tag) &&
|
|
384
|
+
(path.node.tag.name === litTag || path.node.tag.name === 'svg')) {
|
|
385
|
+
path.replaceWith(emitLitViaIR(path.node, state));
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
394
388
|
},
|
|
395
|
-
// 'JSXExpressionContainer|TaggedTemplateExpression'(path, state) {
|
|
396
|
-
// const expressions = t.isTaggedTemplateExpression(path.node)
|
|
397
|
-
// ? (path as NodePath<t.TemplateLiteral>).get('expressions')
|
|
398
|
-
// : [(path as NodePath<t.JSXExpressionContainer>).get('expression')];
|
|
399
|
-
// if (t.isJSXExpressionContainer(path.node)) {
|
|
400
|
-
// console.log('is jsx');
|
|
401
|
-
// }
|
|
402
|
-
// console.log('exp', expressions);
|
|
403
|
-
// // const { tag, quasi } = path.node;
|
|
404
|
-
// // 1. Only target html`...`
|
|
405
|
-
// // if (!t.isIdentifier(tag) || tag.name !== 'html') return;
|
|
406
|
-
// // path
|
|
407
|
-
// // .get('quasi')
|
|
408
|
-
// // .get('expressions')
|
|
409
|
-
// // .forEach((expPath, index) => {
|
|
410
|
-
// // const node = expPath.node;
|
|
411
|
-
// // // 2. Attribute Check: Look at the string part right before the expression
|
|
412
|
-
// // // Lit attributes look like: name="${exp}" or @click="${exp}"
|
|
413
|
-
// // const prevStringPart = quasi.quasis[index].value.raw;
|
|
414
|
-
// // const isAttribute =
|
|
415
|
-
// // prevStringPart.trim().endsWith('=') ||
|
|
416
|
-
// // prevStringPart.match(/@[\w-]+$/);
|
|
417
|
-
// // if (isAttribute) return; // Skip wrapping event listeners or attributes
|
|
418
|
-
// // // 3. Narrowing for Signal Calls: count()
|
|
419
|
-
// // // const isSignalCall = t.isCallExpression(node);
|
|
420
|
-
// // const isSignalCall = false;
|
|
421
|
-
// // // 4. Narrowing for Member Access: item.$name
|
|
422
|
-
// // let isReactiveMember = false;
|
|
423
|
-
// // if (t.isMemberExpression(node)) {
|
|
424
|
-
// // const property = node.property;
|
|
425
|
-
// // // Use Type Guard to narrow from Expression | PrivateName to Identifier
|
|
426
|
-
// // if (t.isIdentifier(property)) {
|
|
427
|
-
// // if (property.name.startsWith('$')) {
|
|
428
|
-
// // (property as any).name = property.name.replace('$', '');
|
|
429
|
-
// // console.log('node', node);
|
|
430
|
-
// // state.needsLitrxImport = true;
|
|
431
|
-
// // isReactiveMember = true;
|
|
432
|
-
// // }
|
|
433
|
-
// // }
|
|
434
|
-
// // }
|
|
435
|
-
// // if (isSignalCall || isReactiveMember) {
|
|
436
|
-
// // // Transform: ${exp} -> ${watch(() => exp)}
|
|
437
|
-
// // expPath.replaceWith(
|
|
438
|
-
// // t.callExpression(t.identifier('litrx'), [
|
|
439
|
-
// // t.arrowFunctionExpression([], node as t.Expression),
|
|
440
|
-
// // ])
|
|
441
|
-
// // );
|
|
442
|
-
// // }
|
|
443
|
-
// // });
|
|
444
|
-
// // path
|
|
445
|
-
// // .get('quasi')
|
|
446
|
-
// // .get('expressions')
|
|
447
|
-
// if (t.isTaggedTemplateExpression(path.node)) {
|
|
448
|
-
// expressions.forEach((expPath, index) => {
|
|
449
|
-
// const node = expPath.node;
|
|
450
|
-
// if (!node || t.isJSXEmptyExpression(node)) return;
|
|
451
|
-
// // 1. Skip Attributes (@click, id=, etc)
|
|
452
|
-
// if (t.isTaggedTemplateExpression(path.node)) {
|
|
453
|
-
// const { tag, quasi } = path.node;
|
|
454
|
-
// const prevString = quasi.quasis[index].value.raw;
|
|
455
|
-
// if (
|
|
456
|
-
// prevString.trim().endsWith('=') ||
|
|
457
|
-
// prevString.match(/@[\w-]+$/)
|
|
458
|
-
// ) {
|
|
459
|
-
// return;
|
|
460
|
-
// }
|
|
461
|
-
// }
|
|
462
|
-
// let shouldWrap = false;
|
|
463
|
-
// let newNode: t.Expression = node as t.Expression;
|
|
464
|
-
// let property: t.Expression;
|
|
465
|
-
// // 2. Handle Member Expressions (e.g., user.$name)
|
|
466
|
-
// if (t.isMemberExpression(node) && t.isIdentifier(node.property)) {
|
|
467
|
-
// const propName = node.property.name;
|
|
468
|
-
// property = node.property;
|
|
469
|
-
// // Check where the object (e.g., 'user') came from
|
|
470
|
-
// const objectName = t.isIdentifier(node.object)
|
|
471
|
-
// ? node.object.name
|
|
472
|
-
// : null;
|
|
473
|
-
// const binding = objectName
|
|
474
|
-
// ? expPath.scope.getBinding(objectName)
|
|
475
|
-
// : null;
|
|
476
|
-
// // Identify if the source is one of our reactive hooks
|
|
477
|
-
// const isReactiveSource =
|
|
478
|
-
// binding &&
|
|
479
|
-
// t.isVariableDeclarator(binding.path.node) &&
|
|
480
|
-
// t.isCallExpression(binding.path.node.init) &&
|
|
481
|
-
// t.isIdentifier(binding.path.node.init.callee) &&
|
|
482
|
-
// ['useReducer', 'createStore', 'useContext'].includes(
|
|
483
|
-
// binding.path.node.init.callee.name
|
|
484
|
-
// );
|
|
485
|
-
// if (isReactiveSource || propName.startsWith('$')) {
|
|
486
|
-
// shouldWrap = true;
|
|
487
|
-
// state.needsLitrxImport = true;
|
|
488
|
-
// console.log('nnedd wrap');
|
|
489
|
-
// // TRANSFORM: Strip the '$' for the runtime Proxy access
|
|
490
|
-
// // user.$name -> user.name
|
|
491
|
-
// }
|
|
492
|
-
// if (propName.startsWith('$')) {
|
|
493
|
-
// if (property) {
|
|
494
|
-
// (property as any).name = propName.replace('$', '');
|
|
495
|
-
// newNode = t.memberExpression(node.object, property);
|
|
496
|
-
// }
|
|
497
|
-
// }
|
|
498
|
-
// }
|
|
499
|
-
// // // 3. Handle Signal Calls: count()
|
|
500
|
-
// // if (t.isCallExpression(node)) {
|
|
501
|
-
// // shouldWrap = true;
|
|
502
|
-
// // }
|
|
503
|
-
// if (shouldWrap) {
|
|
504
|
-
// state.needsLitrxImport = true;
|
|
505
|
-
// expPath.replaceWith(
|
|
506
|
-
// t.callExpression(t.identifier('litrx'), [
|
|
507
|
-
// t.arrowFunctionExpression([], newNode),
|
|
508
|
-
// ])
|
|
509
|
-
// );
|
|
510
|
-
// }
|
|
511
|
-
// });
|
|
512
|
-
// } else {
|
|
513
|
-
// console.log('jsx', expressions);
|
|
514
|
-
// }
|
|
515
|
-
// },
|
|
516
389
|
},
|
|
517
390
|
};
|
|
518
391
|
});
|
|
519
|
-
function needReativeTransform(node, expPath) {
|
|
520
|
-
if (t.isMemberExpression(node) && t.isIdentifier(node.property)) {
|
|
521
|
-
// const propName = node.property.name;
|
|
522
|
-
// property = node.property;
|
|
523
|
-
// Check where the object (e.g., 'user') came from
|
|
524
|
-
const objectName = t.isIdentifier(node.object) ? node.object.name : null;
|
|
525
|
-
const binding = objectName ? expPath.scope.getBinding(objectName) : null;
|
|
526
|
-
// Identify if the source is one of our reactive hooks
|
|
527
|
-
const isReactiveSource = binding &&
|
|
528
|
-
t.isVariableDeclarator(binding.path.node) &&
|
|
529
|
-
t.isCallExpression(binding.path.node.init) &&
|
|
530
|
-
t.isIdentifier(binding.path.node.init.callee) &&
|
|
531
|
-
['useReducer', 'createStore', 'useContext', 'useLocation'].includes(binding.path.node.init.callee.name);
|
|
532
|
-
return isReactiveSource || false;
|
|
533
|
-
}
|
|
534
|
-
return false;
|
|
535
|
-
}
|
|
536
392
|
// ============================================================================
|
|
537
393
|
// JSX Transformation
|
|
538
394
|
// ============================================================================
|
|
@@ -638,6 +494,13 @@ function emitImperativeElement(tag, isNative, props, spreads, children, state) {
|
|
|
638
494
|
* produces for components, so it stays reactive when used as a child.
|
|
639
495
|
*/
|
|
640
496
|
function emitComponentCall(comp, propsObj, state) {
|
|
497
|
+
// Router components (Router/Outlet/…) auto-import like control flow — register the
|
|
498
|
+
// name here (the nested lowering chokepoint) so `<Outlet/>` inside markup is caught,
|
|
499
|
+
// not only a top-level router tag. Unbound names are injected at Program.exit.
|
|
500
|
+
if (t.isIdentifier(comp) && ROUTER_COMPONENTS.has(comp.name)) {
|
|
501
|
+
state.controlFlowComponents.add(comp.name);
|
|
502
|
+
state.needsControlFlowImport = true;
|
|
503
|
+
}
|
|
641
504
|
if (state.backend === 'imperative') {
|
|
642
505
|
state.needsCreateComponent = true;
|
|
643
506
|
state.needsCreateMemo = true;
|
|
@@ -664,7 +527,82 @@ function emitViaIR(node, state) {
|
|
|
664
527
|
used.add(s);
|
|
665
528
|
for (const s of used)
|
|
666
529
|
state.irImports.add(s);
|
|
667
|
-
return template.expression(code, { placeholderPattern: false })();
|
|
530
|
+
return template.expression(code, { placeholderPattern: false, plugins: ['typescript'] })();
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Merge injected import declarations so no module/name pair is imported twice.
|
|
534
|
+
* Named imports from the same module collapse into one declaration with unique
|
|
535
|
+
* specifiers; anything non-trivial (default/namespace/side-effect) passes through
|
|
536
|
+
* untouched. Order is preserved by first appearance.
|
|
537
|
+
*/
|
|
538
|
+
function dedupeImports(imports) {
|
|
539
|
+
const byModule = new Map();
|
|
540
|
+
const out = [];
|
|
541
|
+
for (const decl of imports) {
|
|
542
|
+
const source = decl.source.value;
|
|
543
|
+
const allNamed = decl.specifiers.every((s) => t.isImportSpecifier(s));
|
|
544
|
+
if (!allNamed) {
|
|
545
|
+
out.push(decl);
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
const existing = byModule.get(source);
|
|
549
|
+
if (!existing) {
|
|
550
|
+
const names = new Set(decl.specifiers.map((s) => (s.local.name)));
|
|
551
|
+
byModule.set(source, { decl, names });
|
|
552
|
+
out.push(decl);
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
for (const s of decl.specifiers) {
|
|
556
|
+
if (!existing.names.has(s.local.name)) {
|
|
557
|
+
existing.names.add(s.local.name);
|
|
558
|
+
existing.decl.specifiers.push(s);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return out;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Lit-pipeline path: build IR from a `` html`...` `` template, emit through the
|
|
566
|
+
* imperative backend, reparse. Mirrors emitViaIR — the whole point is that lit
|
|
567
|
+
* and JSX share one IR + one backend. Collects runtime imports and the delegated
|
|
568
|
+
* events used so Program.exit wires them.
|
|
569
|
+
*/
|
|
570
|
+
function emitLitViaIR(node, state) {
|
|
571
|
+
const used = new Set();
|
|
572
|
+
const svg = t.isIdentifier(node.tag) && node.tag.name === 'svg';
|
|
573
|
+
const ir = buildIRFromLit(node, used, { svg });
|
|
574
|
+
const { code, imports } = imperativeBackend.emit(ir, {});
|
|
575
|
+
for (const s of imports)
|
|
576
|
+
used.add(s);
|
|
577
|
+
for (const s of used)
|
|
578
|
+
state.irImports.add(s);
|
|
579
|
+
collectRuntimeNeeds(ir, state);
|
|
580
|
+
state.hasLitIR = true;
|
|
581
|
+
return template.expression(code, { placeholderPattern: false, plugins: ['typescript'] })();
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Walk the lit IR for things Program.exit wires: delegated events (-> the
|
|
585
|
+
* delegateEvents([...]) call) and control-flow component names used as tags
|
|
586
|
+
* (-> auto-import from the control-flow module, like the inline JSX path).
|
|
587
|
+
*/
|
|
588
|
+
function collectRuntimeNeeds(node, state) {
|
|
589
|
+
if (node.kind === 'component' &&
|
|
590
|
+
(CONTROL_FLOW_COMPONENTS.has(node.name) || ROUTER_COMPONENTS.has(node.name))) {
|
|
591
|
+
state.controlFlowComponents.add(node.name);
|
|
592
|
+
state.needsControlFlowImport = true;
|
|
593
|
+
}
|
|
594
|
+
if (node.kind === 'element' || node.kind === 'component' || node.kind === 'control') {
|
|
595
|
+
if ('props' in node) {
|
|
596
|
+
for (const p of node.props) {
|
|
597
|
+
if (p.kind === 'event' && p.event?.delegated)
|
|
598
|
+
state.delegatedEvents.add(p.event.name);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if ('children' in node && node.children) {
|
|
603
|
+
for (const c of node.children)
|
|
604
|
+
collectRuntimeNeeds(c, state);
|
|
605
|
+
}
|
|
668
606
|
}
|
|
669
607
|
//This method will convert props to lazy props like
|
|
670
608
|
function lazyProps(properties) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{declare as Me}from"@babel/helper-plugin-utils";import{types as e,template as Ne}from"@babel/core";import{types as u,traverse as be,template as ye}from"@babel/core";import K from"@babel/generator";var z={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},Ye={version:2,module:"@fluixi/dom",symbols:[...z.symbols,"template","cloneTemplate","walk"]};var Ee={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function ge(t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)}function H(t){return ge(t)?t:JSON.stringify(t)}function xe(t){return t.expr!==void 0?t.reactive?`() => (${t.expr})`:`(${t.expr})`:JSON.stringify(t.literal??!0)}function Se(t){return t.expr!==void 0?`(${t.expr})`:JSON.stringify(t.literal??!0)}function he(t,n,r){let i=t.filter(l=>l.kind==="spread"),o=t.filter(l=>l.kind!=="spread").map(l=>`${H(l.name)}: ${xe(l)}`);n!=null&&o.push(`children: ${n}`);let a=`{ ${o.join(", ")} }`;return i.length>0?(r.add("mergeProps"),`mergeProps(${i.map(l=>l.expr).join(", ")}, ${a})`):a}function U(t,n){return t.length===1?$(t[0],n):`[${t.map(r=>$(r,n)).join(", ")}]`}function Z(t,n,r,i){i.add("createMemo"),i.add("createComponent");let s=n.filter(p=>p.kind==="spread"),a=n.filter(p=>p.kind!=="spread").map(p=>`get ${H(p.name)}() { return ${Se(p)}; }`);r.length>0&&a.push(`get children() { return ${U(r,i)}; }`);let l=`{ ${a.join(", ")} }`;return s.length>0&&(i.add("mergeProps"),l=`mergeProps(${s.map(p=>p.expr).join(", ")}, ${l})`),`createMemo(() => createComponent(${t}, ${l}))`}function $(t,n){switch(t.kind){case"text":return JSON.stringify(t.value);case"expr":return t.reactive?`() => (${t.code})`:`(${t.code})`;case"fragment":return t.children.length===0?"null":U(t.children,n);case"component":return Z(t.name,t.props,t.children,n);case"control":{let r=Ee[t.control]??t.control;return n.add(r),Z(r,t.props,t.children,n)}case"element":{n.add("createNativeElement");let r=JSON.stringify(t.tag),i="_el$",s=[],o=t.svg?`${r}, true`:r;if(s.push(`const ${i} = createNativeElement(${o});`),t.props.length>0){n.add("spread");let a=t.svg?", isSVG: true":"";s.push(`spread({ element: ${i}, props: ${he(t.props,null,n)}${a} });`)}for(let a of t.children){n.add("insert");let l=$(a,n),p=a.kind==="expr"&&a.reactive||a.kind==="component"||a.kind==="control";s.push(p?`insert(${i}, ${l}, null);`:`insert(${i}, ${l});`)}return s.push(`return ${i};`),`(() => { ${s.join(" ")} })()`}}}var T={name:"imperative",contract:z,emit(t,n){let r=new Set;return{code:$(t,r),imports:Array.from(r)}}};var Je=K.default??K;function Y(t){return Je(t,{concise:!0}).code}function Ce(t,n){let r=u.cloneNode(t,!0),i=u.file(u.program([u.expressionStatement(r)])),s=!1;return be(i,{"JSXElement|JSXFragment"(o){let a=o.node,{code:l,imports:p}=T.emit(A(a,n),{});for(let b of p)n.add(b);let E=ye.expression(l,{placeholderPattern:!1})();o.replaceWith(E),o.skip(),s=!0}}),s?i.program.body[0].expression:t}function D(t,n){return Y(Ce(t,n))}var Xe=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),we=/^on[A-Z]/,ve=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function Fe(t){if(u.isJSXIdentifier(t)){let n=t.name[0]!==t.name[0].toLowerCase();return{tag:t.name,component:n}}return u.isJSXMemberExpression(t)?{tag:Y(t),component:!0}:u.isJSXNamespacedName(t)?{tag:`${t.namespace.name}:${t.name.name}`,component:!1}:{tag:"div",component:!1}}function je(t){return u.isJSXIdentifier(t)?t.name==="class"?"className":t.name:u.isJSXNamespacedName(t)?`${t.namespace.name}:${t.name.name}`:"unknown"}function F(t){return u.isCallExpression(t)||u.isOptionalCallExpression(t)?!0:u.isMemberExpression(t)||u.isOptionalMemberExpression(t)?!(!t.computed&&u.isIdentifier(t.property,{name:"children"})):u.isConditionalExpression(t)?F(t.test)||F(t.consequent)||F(t.alternate):u.isLogicalExpression(t)||u.isBinaryExpression(t)?F(t.left)||F(t.right):u.isTemplateLiteral(t)?t.expressions.some(n=>F(n)):!1}function Ie(t,n){let r=je(t.name),i=we.test(r),o={name:r,kind:i?"event":"attr"};i&&(o.event={name:r.slice(2).toLowerCase(),delegated:ve.has(r.slice(2).toLowerCase())});let a=t.value;if(a==null)return o.literal=!0,o;if(u.isStringLiteral(a))return o.literal=a.value,o;if(u.isJSXExpressionContainer(a)&&!u.isJSXEmptyExpression(a.expression)){let l=a.expression;return u.isStringLiteral(l)||u.isNumericLiteral(l)||u.isBooleanLiteral(l)?(o.literal=l.value,o):(o.expr=D(l,n),o.reactive=i?!1:F(l),(u.isJSXElement(l)||u.isJSXFragment(l))&&(o.jsxElement=!0),o)}return o.literal=!0,o}function Pe(t,n){let r=[];for(let i of t)u.isJSXSpreadAttribute(i)?r.push({name:"",kind:"spread",expr:D(i.argument,n)}):u.isJSXAttribute(i)&&r.push(Ie(i,n));return r}function Le(t){let n=t.split(/\r\n|\n|\r/),r=0;for(let s=0;s<n.length;s++)/[^ \t]/.test(n[s])&&(r=s);let i="";for(let s=0;s<n.length;s++){let o=n[s].replace(/\t/g," ");s!==0&&(o=o.replace(/^ +/,"")),s!==n.length-1&&(o=o.replace(/ +$/,"")),o&&(s!==r&&(o+=" "),i+=o)}return i}function Q(t,n){let r=[];for(let i of t)if(u.isJSXText(i)){let s=Le(i.value);s&&r.push({kind:"text",value:s})}else if(u.isJSXExpressionContainer(i)){if(!u.isJSXEmptyExpression(i.expression)){let s=i.expression;r.push({kind:"expr",code:D(s,n),reactive:F(s)})}}else u.isJSXElement(i)||u.isJSXFragment(i)?r.push(A(i,n)):u.isJSXSpreadChild(i)&&r.push({kind:"expr",code:D(i.expression,n),reactive:!1});return r}function A(t,n=new Set){if(u.isJSXFragment(t))return{kind:"fragment",children:Q(t.children,n)};let{tag:r,component:i}=Fe(t.openingElement.name),s=Pe(t.openingElement.attributes,n),o=Q(t.children,n);return i?{kind:"component",name:r,props:s,children:o}:{kind:"element",tag:r,svg:Xe.has(r),props:s,children:o,static:!1}}var re=new Set(["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary","Suspense"]),Ae={Show:"when",For:"each",Index:"each",Match:"when"};var ie=/^on[A-Z]/,se=["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup","mouseover","mouseout","mouseenter","mouseleave"],ft=Me((t,n={})=>{t.assertVersion(7);let{runtime:r="automatic",importSource:i="@fluixi/jsx",pragma:s="jsx",pragmaFrag:o="Fragment",development:a=!1,detectReactivity:l=!0,useLitHTML:p=!0,hoistStatics:E=!0,delegateEvents:b=!0,delegatedEvents:m=se,optimizeControlFlow:y=!0,sourceMaps:I=!0,signalModule:J="@fluixi/dom",controlFlowModule:v="@fluixi/dom",reactiveModule:L="@fluixi/reactive/signal",autoShowTransform:G=!1,backend:X="imperative",codegen:M="inline"}=n,de={backend:X,codegen:M,irImports:new Set,libModule:"@fluixi/core",hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,needsSignalImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,delegatedEvents:new Set,staticElements:new Map,staticCounter:0};return{name:"@fluixi/babel-plugin-jsx",manipulateOptions(f,c){c.plugins.push("jsx","typescript")},pre(f){Object.assign(f,de)},visitor:{ImportDeclaration(f,c){f.node.source.value==="@fluixi/core/rx"&&(f.node.source=e.stringLiteral("@fluixi/reactive"))},Program:{enter(f,c){Object.assign(c,{hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,needsSignalImport:!1,needsLitrxImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,delegatedEvents:new Set,staticElements:new Map,autoShow:G,staticCounter:0,libModule:"@fluixi/core",backend:X,codegen:M,irImports:new Set,needsCreateNativeElement:!1,needsInsert:!1,needsSpread:!1,needsCreateComponent:!1,needsMergeProps:!1})},exit(f,c){let d=[];if(c.hasJSX||(c.needsSignalImport&&d.push(e.importDeclaration([e.importSpecifier(e.identifier("signal"),e.identifier("signal"))],e.stringLiteral(J))),c.needsLitrxImport&&!f.scope.hasBinding("litrx")&&d.push(e.importDeclaration([e.importSpecifier(e.identifier("litrx"),e.identifier("litrx"))],e.stringLiteral(c.libModule)))),c.hasJSX){if(X==="imperative"&&M==="ir"){let x=new Set(["Show","For","Index","Switch","Match","Dynamic","ErrorBoundary","Portal","Suspense"]),S=new Set(["createMemo","createEffect","createRenderEffect","createRoot","createSignal","onCleanup","batch","untrack"]),g=Array.from(c.irImports),w=h=>e.importSpecifier(e.identifier(h),e.identifier(h)),P=h=>!f.scope.hasBinding(h),_=g.filter(h=>S.has(h)&&P(h)),k=g.filter(h=>!x.has(h)&&!S.has(h)&&P(h)),N=g.filter(h=>x.has(h)&&P(h));_.length>0&&d.push(e.importDeclaration(_.map(w),e.stringLiteral(L))),k.length>0&&d.push(e.importDeclaration(k.map(w),e.stringLiteral(J))),N.length>0&&d.push(e.importDeclaration(N.map(w),e.stringLiteral(v)))}else if(X==="imperative"){let S=[[!!c.needsCreateNativeElement,"createNativeElement"],[!!c.needsSpread,"spread"],[!!c.needsInsert,"insert"],[!!c.needsCreateComponent,"createComponent"],[!!c.needsMergeProps,"mergeProps"]].filter(([g,w])=>g&&!f.scope.hasBinding(w)).map(([,g])=>e.importSpecifier(e.identifier(g),e.identifier(g)));S.length>0&&d.push(e.importDeclaration(S,e.stringLiteral(J)))}else if(r==="automatic"){let x=[e.importSpecifier(e.identifier("jsx"),e.identifier("jsx")),e.importSpecifier(e.identifier("jsxs"),e.identifier("jsxs")),e.importSpecifier(e.identifier("Fragment"),e.identifier("Fragment"))];a&&x.push(e.importSpecifier(e.identifier("jsxDEV"),e.identifier("jsxDEV"))),c.needsMergeProps&&x.push(e.importSpecifier(e.identifier("mergeProps"),e.identifier("mergeProps"))),d.push(e.importDeclaration(x,e.stringLiteral(i)))}if(c.needsCreateMemo&&!f.scope.hasBinding("createMemo")&&d.push(e.importDeclaration([e.importSpecifier(e.identifier("createMemo"),e.identifier("createMemo"))],e.stringLiteral(X==="imperative"?L:c.libModule??"@fluixi/core"))),c.needsControlFlowImport&&c.controlFlowComponents.size>0){let x=Array.from(c.controlFlowComponents).filter(S=>!f.scope.hasBinding(S));if(x.length>0){let S=x.map(g=>e.importSpecifier(e.identifier(g),e.identifier(g)));d.push(e.importDeclaration(S,e.stringLiteral(v)))}}if(b&&c.delegatedEvents.size>0){d.push(e.importDeclaration([e.importSpecifier(e.identifier("delegateEvents"),e.identifier("delegateEvents"))],e.stringLiteral(X==="imperative"?J:"@fluixi/jsx")));let x=e.arrayExpression(Array.from(c.delegatedEvents).map(g=>e.stringLiteral(g))),S=e.expressionStatement(e.callExpression(e.identifier("delegateEvents"),[x]));f.node.body.unshift(S)}if(E&&c.staticElements.size>0){let x=[];c.staticElements.forEach((S,g)=>{x.push(e.variableDeclaration("const",[e.variableDeclarator(e.identifier(g),S)]))}),f.node.body.unshift(...x)}}d.length>0&&f.node.body.unshift(...d)}},JSXElement(f,c){if(c.hasJSX=!0,X==="imperative"&&M==="ir"){f.replaceWith(te(f.node,c));return}let d=f.node,x=d.openingElement;if(e.isJSXIdentifier(x.name)&&re.has(x.name.name)&&(c.controlFlowComponents.add(x.name.name),y)){let g=Ue(d,c);if(g){f.replaceWith(g);return}}if(E&&X!=="imperative"&&me(d,c)){let g=He(d,c);if(g){f.replaceWith(g);return}}let S=Re(d,c,{runtime:r,pragma:s,development:a,detectReactivity:l,useLitHTML:p,autoShow:G});f.replaceWith(S)},JSXFragment(f,c){if(c.hasJSX=!0,X==="imperative"&&M==="ir"){f.replaceWith(te(f.node,c));return}let d=V(f.node,c,{runtime:r,pragmaFrag:o,development:a});f.replaceWith(d)},CallExpression(f,c){if(!l)return;let d=f.node.callee;d.name,e.isIdentifier(d)&&(d.name==="createSignal"||d.name==="createStore"||d.name==="useContext"||d.name==="useLocation")&&(c.hasReactivity=!0)},JSXExpressionContainer(f){},TaggedTemplateExpression(f,c){let{tag:d,quasi:x}=f.node;f.get("quasi").get("expressions").forEach((S,g)=>{let w=S.node,P=x.quasis[g].value.raw;if(P.trim().endsWith("=")||P.match(/@[\w-]+$/))return;let k=!1,N=!1;if(e.isMemberExpression(w)){let h=w.property;e.isIdentifier(h)&&(h.name=h.name.replace("$",""),c.needsLitrxImport=!0,N=!0)}(k||N)&&S.replaceWith(e.callExpression(e.identifier("((window as any).Fluixi.litrx || litrx)"),[e.arrowFunctionExpression([],w)]))})}}}});function Re(t,n,r){let{runtime:i,pragma:s,development:o,autoShow:a=!0}=r;return i==="automatic"?O(t,n,o,a):Te(t,n,s)}var Oe=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]);function ee(t,n,r){return n.length>0?(r.needsMergeProps=!0,e.callExpression(e.identifier("mergeProps"),[...n,e.objectExpression(t)])):e.objectExpression(t)}function oe(t){return t.length===1?t[0]:e.arrayExpression(t)}function ke(t,n,r,i,s,o){if(!n){let m=[...r];return s.length>0&&m.push(e.objectMethod("get",e.identifier("children"),[],e.blockStatement([e.returnStatement(oe(s))]))),ae(t,ee(m,i,o),o)}let a=t.value,l=Oe.has(a),p=e.identifier("_el$"),E=[];o.needsCreateNativeElement=!0;let b=[t];if(l&&b.push(e.booleanLiteral(!0)),E.push(e.variableDeclaration("const",[e.variableDeclarator(p,e.callExpression(e.identifier("createNativeElement"),b))])),r.length>0||i.length>0){o.needsSpread=!0;let m=[e.objectProperty(e.identifier("element"),p),e.objectProperty(e.identifier("props"),ee(r,i,o))];l&&m.push(e.objectProperty(e.identifier("isSVG"),e.booleanLiteral(!0))),E.push(e.expressionStatement(e.callExpression(e.identifier("spread"),[e.objectExpression(m)])))}if(s.length>0){o.needsInsert=!0;for(let m of s){let I=e.isArrowFunctionExpression(m)||e.isFunctionExpression(m)||e.isCallExpression(m)&&e.isIdentifier(m.callee)&&m.callee.name==="createMemo"?[e.cloneNode(p),m,e.nullLiteral()]:[e.cloneNode(p),m];E.push(e.expressionStatement(e.callExpression(e.identifier("insert"),I)))}}return E.push(e.returnStatement(p)),e.callExpression(e.arrowFunctionExpression([],e.blockStatement(E)),[])}function ae(t,n,r){return r.backend==="imperative"?(r.needsCreateComponent=!0,r.needsCreateMemo=!0,e.callExpression(e.identifier("createMemo"),[e.arrowFunctionExpression([],e.callExpression(e.identifier("createComponent"),[t,n]))])):e.callExpression(e.identifier("jsx"),[t,n])}function te(t,n){let r=new Set,i=A(t,r),{code:s,imports:o}=T.emit(i,{});for(let a of o)r.add(a);for(let a of r)n.irImports.add(a);return Ne.expression(s,{placeholderPattern:!1})()}function $e(t){return t.map(n=>{if(e.isObjectProperty(n)){let r=n.key,i=n.computed,s=n.value;return e.objectMethod("get",r,[],e.blockStatement([e.returnStatement(s)]),i)}return n})}function O(t,n,r,i=!0){let s=t.openingElement,o=t.children,a=le(s.name),l=e.isJSXIdentifier(s.name)&&/^[a-z]/.test(s.name.name),p=pe(s.attributes,n,l,e.isJSXIdentifier(s.name)?s.name.name:""),E=p.props,b=p.spreads;l||(E=$e(E));let m=W(o,n,i);if(n.backend==="imperative")return ke(a,l,E,b,m,n);if(m.length>0){let v=m.length===1?m[0]:e.arrayExpression(m);E.push(e.objectProperty(e.identifier("children"),v))}let y;if(b.length>0){let v=E.length>0?e.objectExpression(E):e.objectExpression([]);n.needsMergeProps=!0,y=e.callExpression(e.identifier("mergeProps"),[...b,v])}else y=e.objectExpression(E);let I=r?"jsxDEV":m.length>1?"jsxs":"jsx",J=[a,y];return r&&J.push(e.identifier("undefined"),e.booleanLiteral(!1),e.identifier("undefined"),e.identifier("undefined")),e.callExpression(e.identifier(I),J)}function Te(t,n,r){let i=t.openingElement,s=t.children,o=le(i.name),a=e.isJSXIdentifier(i.name)&&/^[a-z]/.test(i.name.name),{props:l,spreads:p}=pe(i.attributes,n,a,e.isJSXIdentifier(i.name)?i.name.name:""),E=W(s,n,n.autoShow??!0),b;if(p.length>0){let y=l.length>0?e.objectExpression(l):e.objectExpression([]);n.needsMergeProps=!0,b=e.callExpression(e.identifier("mergeProps"),[...p,y])}else b=l.length>0?e.objectExpression(l):e.nullLiteral();let m=[o,b,...E];return e.callExpression(e.identifier(r),m)}function V(t,n,r){let{runtime:i,pragmaFrag:s,development:o}=r,a=W(t.children,n,n.autoShow??!0);if(n.backend==="imperative")return a.length===0?e.nullLiteral():oe(a);if(i==="automatic"){let l=o?"jsxDEV":a.length>1?"jsxs":"jsx",p=e.objectExpression([e.objectProperty(e.identifier("children"),a.length===1?a[0]:e.arrayExpression(a))]),E=[e.identifier("Fragment"),p];return o&&E.push(e.identifier("undefined"),e.booleanLiteral(!1),e.identifier("undefined"),e.identifier("undefined")),e.callExpression(e.identifier(l),E)}else return e.callExpression(e.identifier(s),a)}function le(t){if(e.isJSXIdentifier(t)){let n=t.name;return n[0]===n[0].toLowerCase()?e.stringLiteral(n):e.identifier(n)}return e.isJSXMemberExpression(t)?ce(t):e.isJSXNamespacedName(t)?e.stringLiteral(`${t.namespace.name}:${t.name.name}`):e.stringLiteral("div")}function ce(t){let n;return e.isJSXIdentifier(t.object)?n=e.identifier(t.object.name):n=ce(t.object),e.memberExpression(n,e.identifier(t.property.name))}function De(t){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(t)}function pe(t,n,r=!0,i=""){let s=[],o=[],a=Ae[i];for(let l of t)if(e.isJSXSpreadAttribute(l))o.push(l.argument);else if(e.isJSXAttribute(l)){let p=Ve(l.name),E=_e(l.value,n,p,r);if(ie.test(p)){let L=p.slice(2).toLowerCase();se.includes(L)&&n.delegatedEvents.add(L)}let b=De(p)?e.identifier(p):e.stringLiteral(p),m=l.value,y=e.isJSXElement(m)||e.isJSXFragment(m)||e.isJSXExpressionContainer(m)&&(e.isJSXElement(m.expression)||e.isJSXFragment(m.expression)),I=!r&&p===a,J=e.isJSXExpressionContainer(m)&&!e.isJSXEmptyExpression(m.expression)?m.expression:null,v=!r&&!!J&&ue(J,p);!r&&y||I||v?s.push(e.objectMethod("get",b,[],e.blockStatement([e.returnStatement(E)]))):s.push(e.objectProperty(b,E))}return{props:s,spreads:o}}function Ve(t){return e.isJSXIdentifier(t)?t.name==="class"?"className":t.name:e.isJSXNamespacedName(t)?`${t.namespace.name}:${t.name.name}`:"unknown"}function _e(t,n,r="",i=!0){if(t===null)return e.booleanLiteral(!0);if(e.isStringLiteral(t))return t.value.includes(`
|
|
2
|
-
`)?
|
|
1
|
+
import{declare as Qe}from"@babel/helper-plugin-utils";import{types as t,template as Ee}from"@babel/core";import{types as m,traverse as _e,template as Ve}from"@babel/core";import ce from"@babel/generator";var G={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},vt={version:2,module:"@fluixi/dom",symbols:[...G.symbols,"template","cloneTemplate","walk"]};var Le={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function je(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function re(e){return je(e)?e:JSON.stringify(e)}function Fe(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function Ae(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function Me(e,n,r){let i=e.filter(c=>c.kind==="spread"),o=e.filter(c=>c.kind!=="spread").map(c=>`${re(c.name)}: ${Fe(c)}`);n!=null&&o.push(`children: ${n}`);let a=`{ ${o.join(", ")} }`;return i.length>0?(r.add("mergeProps"),`mergeProps(${i.map(c=>c.expr).join(", ")}, ${a})`):a}function ie(e,n){return e.length===1?_(e[0],n):`[${e.map(r=>_(r,n)).join(", ")}]`}function ne(e,n,r,i){i.add("createMemo"),i.add("createComponent");let s=n.filter(l=>l.kind==="spread"),a=n.filter(l=>l.kind!=="spread").map(l=>`get ${re(l.name)}() { return ${Ae(l)}; }`);r.length>0&&a.push(`get children() { return ${ie(r,i)}; }`);let c=`{ ${a.join(", ")} }`;return s.length>0&&(i.add("mergeProps"),c=`mergeProps(${s.map(l=>l.expr).join(", ")}, ${c})`),`createMemo(() => createComponent(${e}, ${c}))`}function _(e,n){switch(e.kind){case"text":return JSON.stringify(e.value);case"expr":return e.reactive?`() => (${e.code})`:`(${e.code})`;case"fragment":return e.children.length===0?"null":ie(e.children,n);case"component":return ne(e.name,e.props,e.children,n);case"control":{let r=Le[e.control]??e.control;return n.add(r),ne(r,e.props,e.children,n)}case"element":{n.add("createNativeElement");let r=JSON.stringify(e.tag),i="_el$",s=[],o=e.svg?`${r}, true`:r;if(s.push(`const ${i} = createNativeElement(${o});`),e.props.length>0){n.add("spread");let a=e.svg?", isSVG: true":"";s.push(`spread({ element: ${i}, props: ${Me(e.props,null,n)}${a} });`)}for(let a of e.children){n.add("insert");let c=_(a,n),l=a.kind==="expr"&&a.reactive||a.kind==="component"||a.kind==="control";s.push(l?`insert(${i}, ${c}, null);`:`insert(${i}, ${c});`)}return s.push(`return ${i};`),`(() => { ${s.join(" ")} })()`}}}var X={name:"imperative",contract:G,emit(e,n){let r=new Set;return{code:_(e,r),imports:Array.from(r)}}};import{types as V}from"@babel/core";import se from"@babel/generator";import{parseTemplate as $e}from"@fluixi/template-parser";var Te=se.default??se;function Oe(e){return Te(e,{concise:!0}).code}var oe=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function De(e){return e.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function ae(e){return e.charAt(0).toUpperCase()+e.slice(1)}var q=class{constructor(n,r){this.holes=n;this.used=r}hole(n){return this.holes[n]??{node:V.identifier("undefined"),code:"undefined",reactive:!1}}emit(n){let{code:r,imports:i}=X.emit(n,{});for(let s of i)this.used.add(s);return r}lowerRoot(n){let r=this.lowerChildren(n);return r.length===1?r[0]:{kind:"fragment",children:r}}lowerChildren(n){let r=[];for(let i=0;i<n.length;i++){let s=n[i];if(s.kind==="Element"||s.kind==="Component"){let a=s.attributes.find(c=>c.kind==="IfDirective");if(a&&a.kind==="IfDirective"){let c=i+1;c<n.length&&this.isBlankText(n[c])&&c++;let l=n[c],p=l&&(l.kind==="Element"||l.kind==="Component")&&l.attributes.some(E=>E.kind==="ElseDirective");r.push(this.lowerIf(s,a.hole,p?l:null)),p&&(i=c);continue}if(s.attributes.some(c=>c.kind==="EachDirective")){r.push(this.lowerEach(s));continue}}let o=this.lowerNode(s);o&&r.push(o)}return r}isBlankText(n){return n.kind==="Text"&&!n.raw&&z(n.value)===""}lowerNode(n){switch(n.kind){case"Text":{if(n.raw)return{kind:"text",value:n.value};let r=z(n.value);return r?{kind:"text",value:r}:null}case"Comment":return null;case"Expression":{let r=this.hole(n.hole);return{kind:"expr",code:r.code,reactive:r.reactive}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(n.children)};case"Element":return this.lowerElement(n);case"Component":return this.lowerComponent(n);default:return null}}lowerElement(n){let r=n.attributes.find(i=>i.kind==="Attribute"&&i.name==="is");if(n.tag==="component"&&r&&r.value&&r.value.kind==="hole"){let i=n.attributes.filter(o=>o!==r),s=this.lowerComponent({...n,kind:"Component",tag:"Dynamic",tagHole:null,attributes:i});return s.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(r.value.hole).code})`}),s}return{kind:"element",tag:n.tag,svg:n.namespace==="svg",props:this.lowerAttributes(n.attributes),children:this.lowerChildren(n.children),static:!1}}lowerComponent(n){let r=n.tagHole!=null?this.hole(n.tagHole).code:n.tag,i=this.lowerAttributes(n.attributes),{slots:s,rest:o}=this.partitionSlots(n.children);for(let[a,c]of s){let l=c.length===1?c[0]:{kind:"fragment",children:c};i.push({name:a,kind:"attr",expr:this.emit(l),jsxElement:!0})}return{kind:"component",name:r,props:i,children:this.lowerChildren(o)}}partitionSlots(n){let r=new Map,i=[];for(let s of n){if(s.kind==="Element"||s.kind==="Component"){let o=s.attributes.find(a=>a.kind==="Attribute"&&a.name==="slot");if(o&&o.value&&o.value.kind==="static"){let a={...s,attributes:s.attributes.filter(p=>p!==o)},c=a.kind==="Element"?this.lowerElement(a):this.lowerComponent(a),l=r.get(o.value.value)??[];l.push(c),r.set(o.value.value,l);continue}}i.push(s)}return{slots:r,rest:i}}lowerIf(n,r,i){let s=this.hole(r),o=[{name:"when",kind:"attr",expr:s.code,reactive:s.reactive}];if(i){let c=this.stripAndLower(i,l=>l.kind==="ElseDirective");o.push({name:"fallback",kind:"attr",expr:this.emit(c),jsxElement:!0})}let a=this.stripAndLower(n,c=>c.kind==="IfDirective");return{kind:"component",name:"Show",props:o,children:[a]}}lowerEach(n){let r=n.attributes.find(l=>l.kind==="EachDirective");if(!r||r.kind!=="EachDirective")return this.lowerNode(n);let i=this.hole(r.hole),s=[{name:"each",kind:"attr",expr:i.code,reactive:i.reactive}];if(r.key){let l="static"in r.key?`(item) => item[${JSON.stringify(r.key.static)}]`:this.hole(r.key.hole).code;s.push({name:"by",kind:"attr",expr:l})}let o=this.itemArrow(n),a;if(o){let l=o.body,p={kind:"expr",code:R(l,this.used),reactive:y(l)},E=this.rebuildWithChildren(n,[p]);a=`(${o.params.map(f=>Oe(f)).join(", ")}) => (${this.emit(E)})`}else{let l=this.stripAndLower(n,p=>p.kind==="EachDirective");a=`() => (${this.emit(l)})`}return{kind:"component",name:"For",props:s,children:[{kind:"expr",code:a,reactive:!1}]}}itemArrow(n){let r=n.children.filter(s=>!this.isBlankText(s));if(r.length!==1||r[0].kind!=="Expression")return null;let i=this.hole(r[0].hole).node;return V.isArrowFunctionExpression(i)&&!V.isBlockStatement(i.body)?i:null}stripAndLower(n,r){let i={...n,attributes:n.attributes.filter(s=>!r(s))};return i.kind==="Element"?this.lowerElement(i):this.lowerComponent(i)}rebuildWithChildren(n,r){let i=this.lowerAttributes(n.attributes.filter(s=>s.kind!=="EachDirective"));return n.kind==="Element"?{kind:"element",tag:n.tag,svg:n.namespace==="svg",props:i,children:r,static:!1}:{kind:"component",name:n.tag,props:i,children:r}}lowerAttributes(n){let r=[],i=[],s=!1,o=[],a=!1,c=[];for(let l of n)switch(l.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":r.push(this.plainAttr(l));break;case"PropertyBinding":r.push({name:l.name,kind:"prop",expr:this.hole(l.hole).code,reactive:this.hole(l.hole).reactive});break;case"EventBinding":r.push(this.eventProp(l));break;case"RefBinding":r.push({name:"ref",kind:"ref",expr:this.hole(l.hole).code,reactive:this.hole(l.hole).reactive});break;case"Spread":r.push({name:"",kind:"spread",expr:this.hole(l.hole).code});break;case"ClassDirective":{let p=this.hole(l.hole);i.push(`${JSON.stringify(l.name)}: ${p.code}`),s=s||p.reactive;break}case"StyleDirective":{let p=this.hole(l.hole);o.push(`${JSON.stringify(l.name)}: ${p.code}`),a=a||p.reactive;break}case"BindDirective":r.push(...this.bindProps(l.name,this.hole(l.hole).code));break;case"UseDirective":{let p=l.name??(l.hole!=null?this.hole(l.hole).code:null);if(!p)break;c.push(l.name!=null&&l.hole!=null?`[${p}, () => (${this.hole(l.hole).code})]`:`[${p}]`);break}}return i.length>0&&r.push({name:"classList",kind:"attr",expr:`{ ${i.join(", ")} }`,reactive:s}),o.length>0&&r.push({name:"style",kind:"attr",expr:`{ ${o.join(", ")} }`,reactive:a}),c.length>0&&r.push({name:"use",kind:"attr",expr:`[${c.join(", ")}]`}),r}eventProp(n){let r=n.name.toLowerCase(),i=this.hole(n.hole).code;if(!(n.syntax==="colon"||n.modifiers.length>0))return{name:"on"+ae(n.name),kind:"event",event:{name:r,delegated:oe.has(r)},expr:i};let o=this.wrapHandler(i,n.modifiers),a=this.eventOptions(n.modifiers),c=a?`[${o}, ${a}]`:o;return{name:"on:"+r,kind:"attr",expr:c}}wrapHandler(n,r){let i=r.includes("self")?"if (e.target !== e.currentTarget) return; ":"",s=[];return r.includes("prevent")&&s.push("e.preventDefault();"),r.includes("stop")&&s.push("e.stopPropagation();"),!i&&s.length===0?n:`(e) => { ${i}${s.join(" ")} return (${n})(e); }`}eventOptions(n){let r=[];return n.includes("capture")&&r.push("capture: true"),n.includes("once")&&r.push("once: true"),n.includes("passive")&&r.push("passive: true"),r.length?`{ ${r.join(", ")} }`:null}bindProps(n,r){let i=n==="checked",s=i?"change":"input",o=i?"checked":"value",a=`(${r})`;return[{name:n,kind:"attr",expr:`${a}[0]()`,reactive:!0},{name:"on"+ae(s),kind:"event",event:{name:s,delegated:oe.has(s)},expr:`(e) => ${a}[1](e.target.${o})`}]}plainAttr(n){let r=n.value,i=n.name;n.name==="class"?i=r&&r.kind==="hole"&&V.isObjectExpression(this.hole(r.hole).node)?"classList":"className":n.name==="html"&&(i="innerHTML");let o={name:i,kind:"attr"};if(r==null)return o.literal=!0,o;if(r.kind==="static")return o.literal=r.value,o;if(r.kind==="hole"){let l=this.hole(r.hole);return o.expr=l.code,o.reactive=l.reactive,o}let a=!1,c=r.parts.map(l=>{if("text"in l)return De(l.text);let p=this.hole(l.hole);return a=a||p.reactive,"${"+p.code+"}"}).join("");return o.expr="`"+c+"`",o.reactive=a,o}};function le(e,n,r={}){let i=e.quasi,s=i.expressions.map(c=>{let l=c;return{node:l,code:R(l,n),reactive:y(l)}}),o=Be(i),{root:a}=$e(o,{svg:r.svg});return new q(s,n).lowerRoot(a.children)}function Be(e){let n=[];return e.quasis.forEach((r,i)=>{let s=r.value.cooked??r.value.raw;if(n.push({kind:"static",text:s,start:r.start??0}),i<e.expressions.length){let o=e.expressions[i];n.push({kind:"hole",index:i,start:o.start??0,end:o.end??0})}}),n}function W(e,n=new Set,r={}){return le(e,n,r)}var ze=ce.default??ce;function me(e){return ze(e,{concise:!0}).code}function We(e,n){let r=m.cloneNode(e,!0),i=m.file(m.program([m.expressionStatement(r)])),s=!1,o=(a,c,l)=>{for(let p of l)n.add(p);a.replaceWith(Ve.expression(c,{placeholderPattern:!1,plugins:["typescript"]})()),a.skip(),s=!0};return _e(i,{"JSXElement|JSXFragment"(a){let c=a.node,{code:l,imports:p}=X.emit(M(c,n),{});o(a,l,p)},TaggedTemplateExpression(a){let c=a.node.tag;if(!m.isIdentifier(c)||c.name!=="html"&&c.name!=="svg")return;let l=W(a.node,n,{svg:c.name==="svg"}),{code:p,imports:E}=X.emit(l,{});o(a,p,E)}}),s?i.program.body[0].expression:e}function R(e,n){return me(We(e,n))}var He=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),Ge=/^on[A-Z]/,qe=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function Ue(e){if(m.isJSXIdentifier(e)){let n=e.name[0]!==e.name[0].toLowerCase();return{tag:e.name,component:n}}return m.isJSXMemberExpression(e)?{tag:me(e),component:!0}:m.isJSXNamespacedName(e)?{tag:`${e.namespace.name}:${e.name.name}`,component:!1}:{tag:"div",component:!1}}function Ze(e){return m.isJSXIdentifier(e)?e.name==="class"?"className":e.name:m.isJSXNamespacedName(e)?`${e.namespace.name}:${e.name.name}`:"unknown"}function y(e){return m.isCallExpression(e)||m.isOptionalCallExpression(e)?!0:m.isMemberExpression(e)||m.isOptionalMemberExpression(e)?!(!e.computed&&m.isIdentifier(e.property,{name:"children"})):m.isConditionalExpression(e)?y(e.test)||y(e.consequent)||y(e.alternate):m.isLogicalExpression(e)||m.isBinaryExpression(e)?y(e.left)||y(e.right):m.isTemplateLiteral(e)?e.expressions.some(n=>y(n)):m.isObjectExpression(e)?e.properties.some(n=>m.isObjectProperty(n)&&!n.computed&&y(n.value)):m.isArrayExpression(e)?e.elements.some(n=>n!=null&&!m.isSpreadElement(n)&&y(n)):!1}function Ke(e,n){let r=Ze(e.name),i=Ge.test(r),s=i||r.startsWith("on:"),a={name:r,kind:i?"event":"attr"};i&&(a.event={name:r.slice(2).toLowerCase(),delegated:qe.has(r.slice(2).toLowerCase())});let c=e.value;if(c==null)return a.literal=!0,a;if(m.isStringLiteral(c))return a.literal=c.value,a;if(m.isJSXExpressionContainer(c)&&!m.isJSXEmptyExpression(c.expression)){let l=c.expression;return m.isStringLiteral(l)||m.isNumericLiteral(l)||m.isBooleanLiteral(l)?(a.literal=l.value,a):(a.expr=R(l,n),a.reactive=s?!1:y(l),(m.isJSXElement(l)||m.isJSXFragment(l))&&(a.jsxElement=!0),a)}return a.literal=!0,a}function pe(e,n){let r=e.value;return r==null?null:m.isStringLiteral(r)?JSON.stringify(r.value):m.isJSXExpressionContainer(r)&&!m.isJSXEmptyExpression(r.expression)?R(r.expression,n):null}function Ye(e,n){let r=[],i=[];for(let s of e){if(m.isJSXSpreadAttribute(s)){r.push({name:"",kind:"spread",expr:R(s.argument,n)});continue}if(!m.isJSXAttribute(s))continue;let o=m.isJSXNamespacedName(s.name)?s.name.namespace.name:null;if(o==="use"){let a=s.name.name.name;n.add(a);let c=pe(s,n);i.push(c!=null?`[${a}, () => (${c})]`:`[${a}]`);continue}if(o==="oncapture"){let a=s.name.name.name.toLowerCase(),c=pe(s,n)??"undefined";r.push({name:"on:"+a,kind:"attr",expr:`[${c}, { capture: true }]`});continue}r.push(Ke(s,n))}return i.length>0&&r.push({name:"use",kind:"attr",expr:`[${i.join(", ")}]`}),r}function z(e){let n=e.split(/\r\n|\n|\r/),r=0;for(let s=0;s<n.length;s++)/[^ \t]/.test(n[s])&&(r=s);let i="";for(let s=0;s<n.length;s++){let o=n[s].replace(/\t/g," ");s!==0&&(o=o.replace(/^ +/,"")),s!==n.length-1&&(o=o.replace(/ +$/,"")),o&&(s!==r&&(o+=" "),i+=o)}return i}function ue(e,n){let r=[];for(let i of e)if(m.isJSXText(i)){let s=z(i.value);s&&r.push({kind:"text",value:s})}else if(m.isJSXExpressionContainer(i)){if(!m.isJSXEmptyExpression(i.expression)){let s=i.expression;r.push({kind:"expr",code:R(s,n),reactive:y(s)})}}else m.isJSXElement(i)||m.isJSXFragment(i)?r.push(M(i,n)):m.isJSXSpreadChild(i)&&r.push({kind:"expr",code:R(i.expression,n),reactive:!1});return r}function M(e,n=new Set){if(m.isJSXFragment(e))return{kind:"fragment",children:ue(e.children,n)};let{tag:r,component:i}=Ue(e.openingElement.name),s=Ye(e.openingElement.attributes,n),o=ue(e.children,n);return i?{kind:"component",name:r,props:s,children:o}:{kind:"element",tag:r,svg:He.has(r),props:s,children:o,static:!1}}var Z=new Set(["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary","Suspense","Await"]),de=new Set(["Suspense","SuspenseList","Await"]),$=new Set(["Router","Outlet","Redirect","Link"]),et={Show:"when",For:"each",Index:"each",Match:"when"};var xe=/^on[A-Z]/,Se=["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup","mouseover","mouseout","mouseenter","mouseleave"],Vt=Qe((e,n={})=>{e.assertVersion(7);let{runtime:r="automatic",importSource:i="@fluixi/jsx",pragma:s="jsx",pragmaFrag:o="Fragment",development:a=!1,detectReactivity:c=!0,useLitHTML:l=!0,hoistStatics:p=!0,delegateEvents:E=!0,delegatedEvents:f=Se,optimizeControlFlow:w=!0,sourceMaps:L=!0,signalModule:C="@fluixi/dom",controlFlowModule:J="@fluixi/dom",routerModule:D="@fluixi/core/router-next",reactiveModule:Q="@fluixi/reactive/signal",autoShowTransform:ee=!1,backend:N="imperative",codegen:A="inline",format:te="both",litTag:Xe="html"}=n,Re=te==="lit"||te==="both",Pe={backend:N,codegen:A,irImports:new Set,libModule:"@fluixi/core",hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,needsSignalImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,delegatedEvents:new Set,staticElements:new Map,staticCounter:0};return{name:"@fluixi/babel-plugin-jsx",manipulateOptions(d,u){u.plugins.push("jsx","typescript")},pre(d){Object.assign(d,Pe)},visitor:{ImportDeclaration(d,u){d.node.source.value==="@fluixi/core/rx"&&(d.node.source=t.stringLiteral("@fluixi/reactive"))},Program:{enter(d,u){Object.assign(u,{hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,hasLitIR:!1,needsSignalImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,delegatedEvents:new Set,staticElements:new Map,autoShow:ee,staticCounter:0,libModule:"@fluixi/core",backend:N,codegen:A,irImports:new Set,needsCreateNativeElement:!1,needsInsert:!1,needsSpread:!1,needsCreateComponent:!1,needsMergeProps:!1})},exit(d,u){let g=[];if(u.hasJSX||u.needsSignalImport&&g.push(t.importDeclaration([t.importSpecifier(t.identifier("signal"),t.identifier("signal"))],t.stringLiteral(C))),u.hasJSX||u.hasLitIR){if(u.irImports.size>0){let h=new Set(["Show","For","Index","Switch","Match","Dynamic","ErrorBoundary","Portal","Suspense"]),b=new Set(["createMemo","createEffect","createRenderEffect","createRoot","createSignal","onCleanup","batch","untrack"]),x=Array.from(u.irImports),I=S=>t.importSpecifier(t.identifier(S),t.identifier(S)),j=S=>!d.scope.hasBinding(S),F=x.filter(S=>b.has(S)&&j(S)),v=x.filter(S=>!h.has(S)&&!b.has(S)&&j(S)),B=x.filter(S=>h.has(S)&&j(S));F.length>0&&g.push(t.importDeclaration(F.map(I),t.stringLiteral(Q))),v.length>0&&g.push(t.importDeclaration(v.map(I),t.stringLiteral(C))),B.length>0&&g.push(t.importDeclaration(B.map(I),t.stringLiteral(J)))}if(u.hasJSX&&N==="imperative"&&A!=="ir"){let b=[[!!u.needsCreateNativeElement,"createNativeElement"],[!!u.needsSpread,"spread"],[!!u.needsInsert,"insert"],[!!u.needsCreateComponent,"createComponent"],[!!u.needsMergeProps,"mergeProps"]].filter(([x,I])=>x&&!d.scope.hasBinding(I)).map(([,x])=>t.importSpecifier(t.identifier(x),t.identifier(x)));b.length>0&&g.push(t.importDeclaration(b,t.stringLiteral(C)))}else if(u.hasJSX&&r==="automatic"){let h=[t.importSpecifier(t.identifier("jsx"),t.identifier("jsx")),t.importSpecifier(t.identifier("jsxs"),t.identifier("jsxs")),t.importSpecifier(t.identifier("Fragment"),t.identifier("Fragment"))];a&&h.push(t.importSpecifier(t.identifier("jsxDEV"),t.identifier("jsxDEV"))),u.needsMergeProps&&h.push(t.importSpecifier(t.identifier("mergeProps"),t.identifier("mergeProps"))),g.push(t.importDeclaration(h,t.stringLiteral(i)))}if(u.needsCreateMemo&&!d.scope.hasBinding("createMemo")&&g.push(t.importDeclaration([t.importSpecifier(t.identifier("createMemo"),t.identifier("createMemo"))],t.stringLiteral(N==="imperative"?Q:u.libModule??"@fluixi/core"))),u.needsControlFlowImport&&u.controlFlowComponents.size>0){let h=Array.from(u.controlFlowComponents).filter(v=>!d.scope.hasBinding(v)),b=u.libModule??"@fluixi/core",x=h.filter(v=>$.has(v)),I=h.filter(v=>de.has(v)),j=h.filter(v=>!de.has(v)&&!$.has(v)),F=(v,B)=>t.importDeclaration(v.map(S=>t.importSpecifier(t.identifier(S),t.identifier(S))),t.stringLiteral(B));j.length>0&&g.push(F(j,J)),I.length>0&&g.push(F(I,b)),x.length>0&&g.push(F(x,D))}if(E&&u.delegatedEvents.size>0){g.push(t.importDeclaration([t.importSpecifier(t.identifier("delegateEvents"),t.identifier("delegateEvents"))],t.stringLiteral(N==="imperative"?C:"@fluixi/jsx")));let h=t.arrayExpression(Array.from(u.delegatedEvents).map(x=>t.stringLiteral(x))),b=t.expressionStatement(t.callExpression(t.identifier("delegateEvents"),[h]));d.node.body.unshift(b)}if(p&&u.staticElements.size>0){let h=[];u.staticElements.forEach((b,x)=>{h.push(t.variableDeclaration("const",[t.variableDeclarator(t.identifier(x),b)]))}),d.node.body.unshift(...h)}}g.length>0&&d.node.body.unshift(...it(g))}},JSXElement(d,u){if(u.hasJSX=!0,N==="imperative"&&A==="ir"){d.replaceWith(ge(d.node,u));return}let g=d.node,h=g.openingElement;if(t.isJSXIdentifier(h.name)&&$.has(h.name.name)&&(u.controlFlowComponents.add(h.name.name),u.needsControlFlowImport=!0),t.isJSXIdentifier(h.name)&&Z.has(h.name.name)&&(u.controlFlowComponents.add(h.name.name),w)){let x=xt(g,u);if(x){d.replaceWith(x);return}}if(p&&N!=="imperative"&&Ie(g,u)){let x=Et(g,u);if(x){d.replaceWith(x);return}}let b=tt(g,u,{runtime:r,pragma:s,development:a,detectReactivity:c,useLitHTML:l,autoShow:ee});d.replaceWith(b)},JSXFragment(d,u){if(u.hasJSX=!0,N==="imperative"&&A==="ir"){d.replaceWith(ge(d.node,u));return}let g=H(d.node,u,{runtime:r,pragmaFrag:o,development:a});d.replaceWith(g)},CallExpression(d,u){if(!c)return;let g=d.node.callee;g.name,t.isIdentifier(g)&&(g.name==="createSignal"||g.name==="createStore"||g.name==="useContext"||g.name==="useLocation")&&(u.hasReactivity=!0)},JSXExpressionContainer(d){},TaggedTemplateExpression(d,u){if(Re&&N==="imperative"&&t.isIdentifier(d.node.tag)&&(d.node.tag.name===Xe||d.node.tag.name==="svg")){d.replaceWith(st(d.node,u));return}}}}});function tt(e,n,r){let{runtime:i,pragma:s,development:o,autoShow:a=!0}=r;return i==="automatic"?O(e,n,o,a):at(e,n,s)}var nt=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]);function fe(e,n,r){return n.length>0?(r.needsMergeProps=!0,t.callExpression(t.identifier("mergeProps"),[...n,t.objectExpression(e)])):t.objectExpression(e)}function be(e){return e.length===1?e[0]:t.arrayExpression(e)}function rt(e,n,r,i,s,o){if(!n){let f=[...r];return s.length>0&&f.push(t.objectMethod("get",t.identifier("children"),[],t.blockStatement([t.returnStatement(be(s))]))),ve(e,fe(f,i,o),o)}let a=e.value,c=nt.has(a),l=t.identifier("_el$"),p=[];o.needsCreateNativeElement=!0;let E=[e];if(c&&E.push(t.booleanLiteral(!0)),p.push(t.variableDeclaration("const",[t.variableDeclarator(l,t.callExpression(t.identifier("createNativeElement"),E))])),r.length>0||i.length>0){o.needsSpread=!0;let f=[t.objectProperty(t.identifier("element"),l),t.objectProperty(t.identifier("props"),fe(r,i,o))];c&&f.push(t.objectProperty(t.identifier("isSVG"),t.booleanLiteral(!0))),p.push(t.expressionStatement(t.callExpression(t.identifier("spread"),[t.objectExpression(f)])))}if(s.length>0){o.needsInsert=!0;for(let f of s){let L=t.isArrowFunctionExpression(f)||t.isFunctionExpression(f)||t.isCallExpression(f)&&t.isIdentifier(f.callee)&&f.callee.name==="createMemo"?[t.cloneNode(l),f,t.nullLiteral()]:[t.cloneNode(l),f];p.push(t.expressionStatement(t.callExpression(t.identifier("insert"),L)))}}return p.push(t.returnStatement(l)),t.callExpression(t.arrowFunctionExpression([],t.blockStatement(p)),[])}function ve(e,n,r){return t.isIdentifier(e)&&$.has(e.name)&&(r.controlFlowComponents.add(e.name),r.needsControlFlowImport=!0),r.backend==="imperative"?(r.needsCreateComponent=!0,r.needsCreateMemo=!0,t.callExpression(t.identifier("createMemo"),[t.arrowFunctionExpression([],t.callExpression(t.identifier("createComponent"),[e,n]))])):t.callExpression(t.identifier("jsx"),[e,n])}function ge(e,n){let r=new Set,i=M(e,r),{code:s,imports:o}=X.emit(i,{});for(let a of o)r.add(a);for(let a of r)n.irImports.add(a);return Ee.expression(s,{placeholderPattern:!1,plugins:["typescript"]})()}function it(e){let n=new Map,r=[];for(let i of e){let s=i.source.value;if(!i.specifiers.every(c=>t.isImportSpecifier(c))){r.push(i);continue}let a=n.get(s);if(!a){let c=new Set(i.specifiers.map(l=>l.local.name));n.set(s,{decl:i,names:c}),r.push(i);continue}for(let c of i.specifiers)a.names.has(c.local.name)||(a.names.add(c.local.name),a.decl.specifiers.push(c))}return r}function st(e,n){let r=new Set,i=t.isIdentifier(e.tag)&&e.tag.name==="svg",s=W(e,r,{svg:i}),{code:o,imports:a}=X.emit(s,{});for(let c of a)r.add(c);for(let c of r)n.irImports.add(c);return ye(s,n),n.hasLitIR=!0,Ee.expression(o,{placeholderPattern:!1,plugins:["typescript"]})()}function ye(e,n){if(e.kind==="component"&&(Z.has(e.name)||$.has(e.name))&&(n.controlFlowComponents.add(e.name),n.needsControlFlowImport=!0),(e.kind==="element"||e.kind==="component"||e.kind==="control")&&"props"in e)for(let r of e.props)r.kind==="event"&&r.event?.delegated&&n.delegatedEvents.add(r.event.name);if("children"in e&&e.children)for(let r of e.children)ye(r,n)}function ot(e){return e.map(n=>{if(t.isObjectProperty(n)){let r=n.key,i=n.computed,s=n.value;return t.objectMethod("get",r,[],t.blockStatement([t.returnStatement(s)]),i)}return n})}function O(e,n,r,i=!0){let s=e.openingElement,o=e.children,a=we(s.name),c=t.isJSXIdentifier(s.name)&&/^[a-z]/.test(s.name.name),l=ke(s.attributes,n,c,t.isJSXIdentifier(s.name)?s.name.name:""),p=l.props,E=l.spreads;c||(p=ot(p));let f=K(o,n,i);if(n.backend==="imperative")return rt(a,c,p,E,f,n);if(f.length>0){let J=f.length===1?f[0]:t.arrayExpression(f);p.push(t.objectProperty(t.identifier("children"),J))}let w;if(E.length>0){let J=p.length>0?t.objectExpression(p):t.objectExpression([]);n.needsMergeProps=!0,w=t.callExpression(t.identifier("mergeProps"),[...E,J])}else w=t.objectExpression(p);let L=r?"jsxDEV":f.length>1?"jsxs":"jsx",C=[a,w];return r&&C.push(t.identifier("undefined"),t.booleanLiteral(!1),t.identifier("undefined"),t.identifier("undefined")),t.callExpression(t.identifier(L),C)}function at(e,n,r){let i=e.openingElement,s=e.children,o=we(i.name),a=t.isJSXIdentifier(i.name)&&/^[a-z]/.test(i.name.name),{props:c,spreads:l}=ke(i.attributes,n,a,t.isJSXIdentifier(i.name)?i.name.name:""),p=K(s,n,n.autoShow??!0),E;if(l.length>0){let w=c.length>0?t.objectExpression(c):t.objectExpression([]);n.needsMergeProps=!0,E=t.callExpression(t.identifier("mergeProps"),[...l,w])}else E=c.length>0?t.objectExpression(c):t.nullLiteral();let f=[o,E,...p];return t.callExpression(t.identifier(r),f)}function H(e,n,r){let{runtime:i,pragmaFrag:s,development:o}=r,a=K(e.children,n,n.autoShow??!0);if(n.backend==="imperative")return a.length===0?t.nullLiteral():be(a);if(i==="automatic"){let c=o?"jsxDEV":a.length>1?"jsxs":"jsx",l=t.objectExpression([t.objectProperty(t.identifier("children"),a.length===1?a[0]:t.arrayExpression(a))]),p=[t.identifier("Fragment"),l];return o&&p.push(t.identifier("undefined"),t.booleanLiteral(!1),t.identifier("undefined"),t.identifier("undefined")),t.callExpression(t.identifier(c),p)}else return t.callExpression(t.identifier(s),a)}function we(e){if(t.isJSXIdentifier(e)){let n=e.name;return n[0]===n[0].toLowerCase()?t.stringLiteral(n):t.identifier(n)}return t.isJSXMemberExpression(e)?Ce(e):t.isJSXNamespacedName(e)?t.stringLiteral(`${e.namespace.name}:${e.name.name}`):t.stringLiteral("div")}function Ce(e){let n;return t.isJSXIdentifier(e.object)?n=t.identifier(e.object.name):n=Ce(e.object),t.memberExpression(n,t.identifier(e.property.name))}function lt(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)}function ke(e,n,r=!0,i=""){let s=[],o=[],a=et[i];for(let c of e)if(t.isJSXSpreadAttribute(c))o.push(c.argument);else if(t.isJSXAttribute(c)){let l=ct(c.name),p=pt(c.value,n,l,r);if(xe.test(l)){let D=l.slice(2).toLowerCase();Se.includes(D)&&n.delegatedEvents.add(D)}let E=lt(l)?t.identifier(l):t.stringLiteral(l),f=c.value,w=t.isJSXElement(f)||t.isJSXFragment(f)||t.isJSXExpressionContainer(f)&&(t.isJSXElement(f.expression)||t.isJSXFragment(f.expression)),L=!r&&l===a,C=t.isJSXExpressionContainer(f)&&!t.isJSXEmptyExpression(f.expression)?f.expression:null,J=!r&&!!C&&Ne(C,l);!r&&w||L||J?s.push(t.objectMethod("get",E,[],t.blockStatement([t.returnStatement(p)]))):s.push(t.objectProperty(E,p))}return{props:s,spreads:o}}function ct(e){return t.isJSXIdentifier(e)?e.name==="class"?"className":e.name:t.isJSXNamespacedName(e)?`${e.namespace.name}:${e.name.name}`:"unknown"}function pt(e,n,r="",i=!0){if(e===null)return t.booleanLiteral(!0);if(t.isStringLiteral(e))return e.value.includes(`
|
|
2
|
+
`)?t.stringLiteral(e.value.replace(/\s+/g," ").trim()):e;if(t.isJSXExpressionContainer(e)){if(t.isJSXEmptyExpression(e.expression))return t.booleanLiteral(!0);let s=e.expression;return i&&Ne(s,r)?t.arrowFunctionExpression([],s):s}return t.isJSXElement(e)?O(e,n,!1,n.autoShow??!0):t.isJSXFragment(e)?H(e,n,{runtime:"automatic",pragmaFrag:"Fragment",development:!1}):t.booleanLiteral(!0)}function Ne(e,n){return xe.test(n)||n.startsWith("on:")||n==="ref"||n.startsWith("use:")||t.isArrowFunctionExpression(e)||t.isFunctionExpression(e)||t.isIdentifier(e)||t.isStringLiteral(e)||t.isNumericLiteral(e)||t.isBooleanLiteral(e)||t.isNullLiteral(e)?!1:!!(t.isCallExpression(e)||t.isOptionalCallExpression(e)||t.isMemberExpression(e)||t.isOptionalMemberExpression(e)||t.isLogicalExpression(e)||t.isConditionalExpression(e)||t.isBinaryExpression(e)||t.isUnaryExpression(e)||t.isTemplateLiteral(e)||t.isObjectExpression(e)||t.isArrayExpression(e))}function ut(e){let n=e.split(/\r\n|\n|\r/),r=0;for(let s=0;s<n.length;s++)/[^ \t]/.test(n[s])&&(r=s);let i="";for(let s=0;s<n.length;s++){let o=n[s].replace(/\t/g," ");s!==0&&(o=o.replace(/^ +/,"")),s!==n.length-1&&(o=o.replace(/ +$/,"")),o&&(s!==r&&(o+=" "),i+=o)}return i}function K(e,n,r=!0){let i=[];for(let s of e)if(t.isJSXText(s)){let o=ut(s.value);o&&i.push(t.stringLiteral(o))}else if(t.isJSXExpressionContainer(s)){if(!t.isJSXEmptyExpression(s.expression)){let o=s.expression;if(r){let a=mt(o,n)??dt(o,n);if(a){i.push(a);continue}}else{let a=ft(o,n);if(a){i.push(a);continue}}ht(o)?i.push(t.arrowFunctionExpression([],o)):i.push(o)}}else t.isJSXElement(s)?i.push(O(s,n,!1,n.autoShow??!0)):t.isJSXFragment(s)?i.push(H(s,n,{runtime:"automatic",pragmaFrag:"Fragment",development:!1})):t.isJSXSpreadChild(s)&&i.push(s.expression);return i}function mt(e,n){if(!t.isArrowFunctionExpression(e)||e.params.length!==0||e.async)return null;let r=e.body;if(t.isLogicalExpression(r)&&r.operator==="&&"){let i=k(r.right);if(i)return T(P(r.left),i,null,n)}if(t.isConditionalExpression(r)){let i=k(r.consequent);if(i){let s=Y(r.alternate,n);return T(P(r.test),i,s,n,!0)}}return null}function dt(e,n){if(t.isLogicalExpression(e)&&e.operator==="&&"){let r=k(e.right);if(r)return T(P(e.left),r,null,n)}if(t.isConditionalExpression(e)){let r=k(e.consequent);if(r){let i=Y(e.alternate,n);return T(P(e.test),r,i,n)}}return null}function ft(e,n){let r=t.isArrowFunctionExpression(e)&&e.params.length===0&&!e.async&&t.isExpression(e.body)?e.body:e;if(t.isConditionalExpression(r)){let i=P(r.test),o=k(r.consequent)??r.consequent,c=k(r.alternate)??r.alternate,l=t.conditionalExpression(i,o,c);return U(r.consequent)||U(r.alternate)?null:(n.needsCreateMemo=!0,t.callExpression(t.identifier("createMemo"),[t.arrowFunctionExpression([],l)]))}if(t.isLogicalExpression(r)&&r.operator==="&&"){let i=P(r.left),o=k(r.right)??r.right,a=t.logicalExpression("&&",i,o);return U(r.right)?null:(n.needsCreateMemo=!0,t.callExpression(t.identifier("createMemo"),[t.arrowFunctionExpression([],a)]))}return null}function Y(e,n){if(gt(e))return null;let r=k(e);if(r)return Je(r,n);if(t.isConditionalExpression(e)){let i=e,s=k(i.consequent);if(s){let o=Y(i.alternate,n);return T(P(i.test),s,o,n)}}return e}function he(e){return t.isJSXElement(e)||t.isJSXFragment(e)}function U(e){let n=k(e);if(!n||!t.isJSXElement(n))return!1;let r=n.openingElement.name;return t.isJSXIdentifier(r)&&Z.has(r.name)}function k(e){return he(e)?e:t.isArrowFunctionExpression(e)&&e.params.length===0&&!e.async&&he(e.body)?e.body:null}function P(e){return t.isArrowFunctionExpression(e)&&e.params.length===0&&!e.async&&t.isExpression(e.body)?e.body:e}function gt(e){return t.isNullLiteral(e)||t.isIdentifier(e)&&e.name==="undefined"||t.isBooleanLiteral(e)&&e.value===!1}function Je(e,n){return t.isJSXElement(e)?O(e,n,!1,n.autoShow??!0):H(e,n,{runtime:"automatic",pragmaFrag:"Fragment",development:!1})}function T(e,n,r,i,s=!1){i.controlFlowComponents.add("Show"),i.needsControlFlowImport=!0;let o=Je(n,i),a=[t.objectProperty(t.identifier("when"),t.arrowFunctionExpression([],e)),t.objectProperty(t.identifier("children"),o)];return r&&a.push(t.objectProperty(t.identifier("fallback"),r)),ve(t.identifier("Show"),t.objectExpression(a),i)}function ht(e){return t.isMemberExpression(e)||t.isOptionalMemberExpression(e)?!(!e.computed&&t.isIdentifier(e.property,{name:"children"})):t.isCallExpression(e)||t.isOptionalCallExpression(e)?!0:t.isIdentifier(e)?!1:!!(t.isLogicalExpression(e)||t.isConditionalExpression(e)||t.isBinaryExpression(e)||t.isUnaryExpression(e)||t.isTemplateLiteral(e))}function Ie(e,n){let r=e.openingElement;if(!t.isJSXIdentifier(r.name))return!1;let i=r.name.name;if(i[0]!==i[0].toLowerCase())return!1;for(let s of r.attributes){if(t.isJSXSpreadAttribute(s))return!1;if(t.isJSXAttribute(s)){let o=s.value;if(t.isJSXExpressionContainer(o)&&!t.isStringLiteral(o.expression)&&!t.isNumericLiteral(o.expression))return!1}}for(let s of e.children)if(t.isJSXElement(s)&&!Ie(s,n)||t.isJSXExpressionContainer(s))return!1;return!0}function Et(e,n){let r=`_$static${n.staticCounter++}`,i=O(e,n,!1);return n.staticElements.set(r,i),t.identifier(r)}function xt(e,n){let r=e.openingElement.name.name;return r==="Show"?St(e,n):r==="For"?bt(e,n):null}function St(e,n){return null}function bt(e,n){return null}export{Vt as default};
|