@fictjs/compiler 0.0.13 → 0.0.14
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/README.md +14 -0
- package/dist/index.cjs +71 -51
- package/dist/index.js +71 -51
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,3 +15,17 @@ yarn add -D @fictjs/compiler
|
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
You can visit [Fict](https://github.com/fictjs/fict) for more documentation.
|
|
18
|
+
|
|
19
|
+
## Options
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
createFictPlugin({
|
|
23
|
+
dev: true,
|
|
24
|
+
onWarn(warning) {
|
|
25
|
+
console.warn(warning)
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
- `dev` (default: `NODE_ENV !== 'production' && NODE_ENV !== 'test'`): enables compiler warnings/diagnostics. Set to `false` to silence warnings.
|
|
31
|
+
- `onWarn`: custom warning handler (only called when `dev` is enabled).
|
package/dist/index.cjs
CHANGED
|
@@ -14121,8 +14121,34 @@ __export(index_exports, {
|
|
|
14121
14121
|
module.exports = __toCommonJS(index_exports);
|
|
14122
14122
|
var import_helper_plugin_utils = require("@babel/helper-plugin-utils");
|
|
14123
14123
|
|
|
14124
|
+
// ../runtime/src/delegated-events.ts
|
|
14125
|
+
var DelegatedEventNames = [
|
|
14126
|
+
"beforeinput",
|
|
14127
|
+
"click",
|
|
14128
|
+
"dblclick",
|
|
14129
|
+
"contextmenu",
|
|
14130
|
+
"focusin",
|
|
14131
|
+
"focusout",
|
|
14132
|
+
"input",
|
|
14133
|
+
"keydown",
|
|
14134
|
+
"keyup",
|
|
14135
|
+
"mousedown",
|
|
14136
|
+
"mousemove",
|
|
14137
|
+
"mouseout",
|
|
14138
|
+
"mouseover",
|
|
14139
|
+
"mouseup",
|
|
14140
|
+
"pointerdown",
|
|
14141
|
+
"pointermove",
|
|
14142
|
+
"pointerout",
|
|
14143
|
+
"pointerover",
|
|
14144
|
+
"pointerup",
|
|
14145
|
+
"touchend",
|
|
14146
|
+
"touchmove",
|
|
14147
|
+
"touchstart"
|
|
14148
|
+
];
|
|
14149
|
+
|
|
14124
14150
|
// src/constants.ts
|
|
14125
|
-
var RUNTIME_MODULE = "@fictjs/runtime";
|
|
14151
|
+
var RUNTIME_MODULE = "@fictjs/runtime/internal";
|
|
14126
14152
|
var RUNTIME_HELPERS = {
|
|
14127
14153
|
signal: "createSignal",
|
|
14128
14154
|
createSelector: "createSelector",
|
|
@@ -14139,7 +14165,7 @@ var RUNTIME_HELPERS = {
|
|
|
14139
14165
|
propGetter: "__fictProp",
|
|
14140
14166
|
propsRest: "__fictPropsRest",
|
|
14141
14167
|
mergeProps: "mergeProps",
|
|
14142
|
-
|
|
14168
|
+
prop: "prop",
|
|
14143
14169
|
runInScope: "runInScope",
|
|
14144
14170
|
createElement: "createElement",
|
|
14145
14171
|
conditional: "createConditional",
|
|
@@ -14173,7 +14199,7 @@ var RUNTIME_ALIASES = {
|
|
|
14173
14199
|
fragment: "Fragment",
|
|
14174
14200
|
propGetter: "__fictProp",
|
|
14175
14201
|
propsRest: "__fictPropsRest",
|
|
14176
|
-
|
|
14202
|
+
prop: "prop",
|
|
14177
14203
|
mergeProps: "mergeProps",
|
|
14178
14204
|
runInScope: "runInScope",
|
|
14179
14205
|
createElement: "createElement",
|
|
@@ -14193,30 +14219,7 @@ var RUNTIME_ALIASES = {
|
|
|
14193
14219
|
template: "template",
|
|
14194
14220
|
delegateEvents: "delegateEvents"
|
|
14195
14221
|
};
|
|
14196
|
-
var DelegatedEvents = /* @__PURE__ */ new Set([
|
|
14197
|
-
"beforeinput",
|
|
14198
|
-
"click",
|
|
14199
|
-
"dblclick",
|
|
14200
|
-
"contextmenu",
|
|
14201
|
-
"focusin",
|
|
14202
|
-
"focusout",
|
|
14203
|
-
"input",
|
|
14204
|
-
"keydown",
|
|
14205
|
-
"keyup",
|
|
14206
|
-
"mousedown",
|
|
14207
|
-
"mousemove",
|
|
14208
|
-
"mouseout",
|
|
14209
|
-
"mouseover",
|
|
14210
|
-
"mouseup",
|
|
14211
|
-
"pointerdown",
|
|
14212
|
-
"pointermove",
|
|
14213
|
-
"pointerout",
|
|
14214
|
-
"pointerover",
|
|
14215
|
-
"pointerup",
|
|
14216
|
-
"touchend",
|
|
14217
|
-
"touchmove",
|
|
14218
|
-
"touchstart"
|
|
14219
|
-
]);
|
|
14222
|
+
var DelegatedEvents = /* @__PURE__ */ new Set([...DelegatedEventNames]);
|
|
14220
14223
|
var SAFE_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
14221
14224
|
// Console methods
|
|
14222
14225
|
"console.log",
|
|
@@ -16075,7 +16078,7 @@ var DiagnosticMessages = {
|
|
|
16075
16078
|
["FICT-P001" /* FICT_P001 */]: "Props destructuring falls back to non-reactive binding.",
|
|
16076
16079
|
["FICT-P002" /* FICT_P002 */]: "Array rest in props destructuring falls back to non-reactive binding.",
|
|
16077
16080
|
["FICT-P003" /* FICT_P003 */]: "Computed property in props pattern cannot be made reactive.",
|
|
16078
|
-
["FICT-P004" /* FICT_P004 */]: "Nested props destructuring falls back to non-reactive binding; access props directly or use
|
|
16081
|
+
["FICT-P004" /* FICT_P004 */]: "Nested props destructuring falls back to non-reactive binding; access props directly or use prop.",
|
|
16079
16082
|
["FICT-S001" /* FICT_S001 */]: "State variable mutation detected outside component scope.",
|
|
16080
16083
|
["FICT-S002" /* FICT_S002 */]: "State variable escaped to external scope, may cause memory leaks.",
|
|
16081
16084
|
["FICT-E001" /* FICT_E001 */]: "Effect without reactive dependencies will run only once; consider adding state reads or removing the effect.",
|
|
@@ -19470,8 +19473,8 @@ function instructionToStatement(instr, t2, declaredVars, ctx, _buildMemoCall) {
|
|
|
19470
19473
|
const isStateCall2 = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && instr.value.callee.name === "$state";
|
|
19471
19474
|
const inRegionMemo = ctx.inRegionMemo ?? false;
|
|
19472
19475
|
const isFunctionValue = instr.value.kind === "ArrowFunction" || instr.value.kind === "FunctionExpression";
|
|
19473
|
-
const isAccessorReturningCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["$memo", "createMemo", "
|
|
19474
|
-
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"
|
|
19476
|
+
const isAccessorReturningCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["$memo", "createMemo", "prop"].includes(instr.value.callee.name);
|
|
19477
|
+
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"].includes(instr.value.callee.name);
|
|
19475
19478
|
const isMemoReturningCall = isAccessorReturningCall || isReactiveObjectCall;
|
|
19476
19479
|
const lowerAssignedValue = (forceAssigned = false) => lowerExpressionWithDeSSA(instr.value, ctx, forceAssigned || isFunctionValue);
|
|
19477
19480
|
const buildMemoCall = (expr) => {
|
|
@@ -21105,7 +21108,7 @@ function computeReactiveAccessors(fn, ctx) {
|
|
|
21105
21108
|
tracked.add(target);
|
|
21106
21109
|
changed = true;
|
|
21107
21110
|
}
|
|
21108
|
-
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"
|
|
21111
|
+
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"].includes(instr.value.callee.name);
|
|
21109
21112
|
if (hasDataDep && !isSignal(target) && !isStore(target) && !isReactiveObjectCall) {
|
|
21110
21113
|
memo.add(target);
|
|
21111
21114
|
}
|
|
@@ -21728,8 +21731,8 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21728
21731
|
const shouldMemoProp = usesTracked && !t2.isIdentifier(valueExprRaw) && !t2.isMemberExpression(valueExprRaw) && !t2.isLiteral(valueExprRaw);
|
|
21729
21732
|
const valueExpr = usesTracked && ctx.t.isExpression(valueExprRaw) ? (() => {
|
|
21730
21733
|
if (shouldMemoProp) {
|
|
21731
|
-
ctx.helpersUsed.add("
|
|
21732
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.
|
|
21734
|
+
ctx.helpersUsed.add("prop");
|
|
21735
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
21733
21736
|
t2.arrowFunctionExpression([], valueExprRaw)
|
|
21734
21737
|
]);
|
|
21735
21738
|
}
|
|
@@ -23929,8 +23932,8 @@ function buildPropsObject(attributes, ctx) {
|
|
|
23929
23932
|
]);
|
|
23930
23933
|
})() : usesTracked && t2.isExpression(lowered) ? (() => {
|
|
23931
23934
|
if (useMemoProp) {
|
|
23932
|
-
ctx.helpersUsed.add("
|
|
23933
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.
|
|
23935
|
+
ctx.helpersUsed.add("prop");
|
|
23936
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
23934
23937
|
t2.arrowFunctionExpression(
|
|
23935
23938
|
[],
|
|
23936
23939
|
trackedExpr ?? lowered
|
|
@@ -24452,7 +24455,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24452
24455
|
const stmts = [];
|
|
24453
24456
|
const excludeKeys = [];
|
|
24454
24457
|
let supported = true;
|
|
24455
|
-
let
|
|
24458
|
+
let usesProp = false;
|
|
24456
24459
|
let usesPropsRest = false;
|
|
24457
24460
|
let warnedNested = false;
|
|
24458
24461
|
const memberExprForKey = (base, key) => t2.memberExpression(base, t2.identifier(key), false);
|
|
@@ -24472,16 +24475,16 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24472
24475
|
const member = memberExprForKey(baseExpr, keyName);
|
|
24473
24476
|
const value = prop.value;
|
|
24474
24477
|
if (t2.isIdentifier(value)) {
|
|
24475
|
-
const
|
|
24476
|
-
if (
|
|
24477
|
-
|
|
24478
|
+
const shouldWrapProp = !calledIdentifiers.has(value.name);
|
|
24479
|
+
if (shouldWrapProp) {
|
|
24480
|
+
usesProp = true;
|
|
24478
24481
|
propsPlanAliases.add(value.name);
|
|
24479
24482
|
}
|
|
24480
24483
|
stmts.push(
|
|
24481
24484
|
t2.variableDeclaration("const", [
|
|
24482
24485
|
t2.variableDeclarator(
|
|
24483
24486
|
t2.identifier(value.name),
|
|
24484
|
-
|
|
24487
|
+
shouldWrapProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
24485
24488
|
t2.arrowFunctionExpression([], member)
|
|
24486
24489
|
]) : member
|
|
24487
24490
|
)
|
|
@@ -24495,13 +24498,13 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24495
24498
|
continue;
|
|
24496
24499
|
}
|
|
24497
24500
|
if (t2.isAssignmentPattern(value) && t2.isIdentifier(value.left)) {
|
|
24498
|
-
const
|
|
24499
|
-
if (
|
|
24500
|
-
|
|
24501
|
+
const shouldWrapProp = !calledIdentifiers.has(value.left.name);
|
|
24502
|
+
if (shouldWrapProp) {
|
|
24503
|
+
usesProp = true;
|
|
24501
24504
|
propsPlanAliases.add(value.left.name);
|
|
24502
24505
|
}
|
|
24503
24506
|
const baseInit = t2.logicalExpression("??", member, value.right);
|
|
24504
|
-
const init =
|
|
24507
|
+
const init = shouldWrapProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
24505
24508
|
t2.arrowFunctionExpression([], baseInit)
|
|
24506
24509
|
]) : baseInit;
|
|
24507
24510
|
stmts.push(
|
|
@@ -24545,7 +24548,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24545
24548
|
if (supported) {
|
|
24546
24549
|
propsDestructurePlan = {
|
|
24547
24550
|
statements: stmts,
|
|
24548
|
-
|
|
24551
|
+
usesProp,
|
|
24549
24552
|
usesPropsRest
|
|
24550
24553
|
};
|
|
24551
24554
|
propsPlanAliases.forEach((name) => {
|
|
@@ -24639,8 +24642,8 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24639
24642
|
finalParams = [t2.identifier("__props")];
|
|
24640
24643
|
const pattern = rawParam.type === "AssignmentPattern" ? rawParam.left : rawParam;
|
|
24641
24644
|
if (propsDestructurePlan) {
|
|
24642
|
-
if (propsDestructurePlan.
|
|
24643
|
-
ctx.helpersUsed.add("
|
|
24645
|
+
if (propsDestructurePlan.usesProp) {
|
|
24646
|
+
ctx.helpersUsed.add("prop");
|
|
24644
24647
|
}
|
|
24645
24648
|
if (propsDestructurePlan.usesPropsRest) {
|
|
24646
24649
|
ctx.helpersUsed.add("propsRest");
|
|
@@ -25128,8 +25131,10 @@ function createHIREntrypointVisitor(t2, options) {
|
|
|
25128
25131
|
const fileName = path.hub?.file?.opts?.filename || "<unknown>";
|
|
25129
25132
|
const comments = path.hub?.file?.ast?.comments || [];
|
|
25130
25133
|
const suppressions = parseSuppressions(comments);
|
|
25131
|
-
const
|
|
25132
|
-
const
|
|
25134
|
+
const dev = options.dev !== false;
|
|
25135
|
+
const warn = dev ? createWarningDispatcher(options.onWarn, suppressions) : () => {
|
|
25136
|
+
};
|
|
25137
|
+
const optionsWithWarnings = dev ? { ...options, onWarn: warn } : { ...options, onWarn: void 0 };
|
|
25133
25138
|
const isHookName2 = (name) => !!name && /^use[A-Z]/.test(name);
|
|
25134
25139
|
const getFunctionName = (fnPath) => {
|
|
25135
25140
|
return fnPath.isFunctionDeclaration() && fnPath.node.id ? fnPath.node.id.name : fnPath.isFunctionExpression() && fnPath.node.id ? fnPath.node.id.name : fnPath.parentPath.isVariableDeclarator() && t2.isIdentifier(fnPath.parentPath.node.id) && fnPath.parentPath.node.init === fnPath.node ? fnPath.parentPath.node.id.name : void 0;
|
|
@@ -25385,6 +25390,18 @@ function createHIREntrypointVisitor(t2, options) {
|
|
|
25385
25390
|
},
|
|
25386
25391
|
CallExpression(callPath) {
|
|
25387
25392
|
if (isStateCall(callPath.node, t2)) {
|
|
25393
|
+
const parentPath = callPath.parentPath;
|
|
25394
|
+
const isVariableDeclarator = parentPath?.isVariableDeclarator() && parentPath.node.init === callPath.node;
|
|
25395
|
+
if (!isVariableDeclarator) {
|
|
25396
|
+
throw callPath.buildCodeFrameError(
|
|
25397
|
+
"$state() must be assigned directly to a variable (e.g. let count = $state(0)). For object state, consider using $store from fict/plus."
|
|
25398
|
+
);
|
|
25399
|
+
}
|
|
25400
|
+
if (!t2.isIdentifier(parentPath.node.id)) {
|
|
25401
|
+
throw callPath.buildCodeFrameError(
|
|
25402
|
+
"Destructuring $state is not supported. Use a simple identifier."
|
|
25403
|
+
);
|
|
25404
|
+
}
|
|
25388
25405
|
const ownerComponent = callPath.getFunctionParent();
|
|
25389
25406
|
if (!ownerComponent || !isComponentOrHookDefinition(ownerComponent)) {
|
|
25390
25407
|
throw callPath.buildCodeFrameError(
|
|
@@ -25577,7 +25594,9 @@ function createHIREntrypointVisitor(t2, options) {
|
|
|
25577
25594
|
}
|
|
25578
25595
|
});
|
|
25579
25596
|
}
|
|
25580
|
-
|
|
25597
|
+
if (dev) {
|
|
25598
|
+
runWarningPass(path, stateVars, derivedVars, warn, fileName, t2);
|
|
25599
|
+
}
|
|
25581
25600
|
const fileAst = t2.file(path.node);
|
|
25582
25601
|
const hir = buildHIR(fileAst);
|
|
25583
25602
|
const lowered = lowerHIRWithRegions(hir, t2, optionsWithWarnings);
|
|
@@ -25597,7 +25616,8 @@ var createFictPlugin = (0, import_helper_plugin_utils.declare)(
|
|
|
25597
25616
|
const t2 = api.types;
|
|
25598
25617
|
const normalizedOptions = {
|
|
25599
25618
|
...options,
|
|
25600
|
-
fineGrainedDom: options.fineGrainedDom ?? true
|
|
25619
|
+
fineGrainedDom: options.fineGrainedDom ?? true,
|
|
25620
|
+
dev: options.dev ?? (process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test")
|
|
25601
25621
|
};
|
|
25602
25622
|
return {
|
|
25603
25623
|
name: "fict-compiler-hir",
|
package/dist/index.js
CHANGED
|
@@ -14109,8 +14109,34 @@ var require_lib3 = __commonJS({
|
|
|
14109
14109
|
// src/index.ts
|
|
14110
14110
|
import { declare } from "@babel/helper-plugin-utils";
|
|
14111
14111
|
|
|
14112
|
+
// ../runtime/src/delegated-events.ts
|
|
14113
|
+
var DelegatedEventNames = [
|
|
14114
|
+
"beforeinput",
|
|
14115
|
+
"click",
|
|
14116
|
+
"dblclick",
|
|
14117
|
+
"contextmenu",
|
|
14118
|
+
"focusin",
|
|
14119
|
+
"focusout",
|
|
14120
|
+
"input",
|
|
14121
|
+
"keydown",
|
|
14122
|
+
"keyup",
|
|
14123
|
+
"mousedown",
|
|
14124
|
+
"mousemove",
|
|
14125
|
+
"mouseout",
|
|
14126
|
+
"mouseover",
|
|
14127
|
+
"mouseup",
|
|
14128
|
+
"pointerdown",
|
|
14129
|
+
"pointermove",
|
|
14130
|
+
"pointerout",
|
|
14131
|
+
"pointerover",
|
|
14132
|
+
"pointerup",
|
|
14133
|
+
"touchend",
|
|
14134
|
+
"touchmove",
|
|
14135
|
+
"touchstart"
|
|
14136
|
+
];
|
|
14137
|
+
|
|
14112
14138
|
// src/constants.ts
|
|
14113
|
-
var RUNTIME_MODULE = "@fictjs/runtime";
|
|
14139
|
+
var RUNTIME_MODULE = "@fictjs/runtime/internal";
|
|
14114
14140
|
var RUNTIME_HELPERS = {
|
|
14115
14141
|
signal: "createSignal",
|
|
14116
14142
|
createSelector: "createSelector",
|
|
@@ -14127,7 +14153,7 @@ var RUNTIME_HELPERS = {
|
|
|
14127
14153
|
propGetter: "__fictProp",
|
|
14128
14154
|
propsRest: "__fictPropsRest",
|
|
14129
14155
|
mergeProps: "mergeProps",
|
|
14130
|
-
|
|
14156
|
+
prop: "prop",
|
|
14131
14157
|
runInScope: "runInScope",
|
|
14132
14158
|
createElement: "createElement",
|
|
14133
14159
|
conditional: "createConditional",
|
|
@@ -14161,7 +14187,7 @@ var RUNTIME_ALIASES = {
|
|
|
14161
14187
|
fragment: "Fragment",
|
|
14162
14188
|
propGetter: "__fictProp",
|
|
14163
14189
|
propsRest: "__fictPropsRest",
|
|
14164
|
-
|
|
14190
|
+
prop: "prop",
|
|
14165
14191
|
mergeProps: "mergeProps",
|
|
14166
14192
|
runInScope: "runInScope",
|
|
14167
14193
|
createElement: "createElement",
|
|
@@ -14181,30 +14207,7 @@ var RUNTIME_ALIASES = {
|
|
|
14181
14207
|
template: "template",
|
|
14182
14208
|
delegateEvents: "delegateEvents"
|
|
14183
14209
|
};
|
|
14184
|
-
var DelegatedEvents = /* @__PURE__ */ new Set([
|
|
14185
|
-
"beforeinput",
|
|
14186
|
-
"click",
|
|
14187
|
-
"dblclick",
|
|
14188
|
-
"contextmenu",
|
|
14189
|
-
"focusin",
|
|
14190
|
-
"focusout",
|
|
14191
|
-
"input",
|
|
14192
|
-
"keydown",
|
|
14193
|
-
"keyup",
|
|
14194
|
-
"mousedown",
|
|
14195
|
-
"mousemove",
|
|
14196
|
-
"mouseout",
|
|
14197
|
-
"mouseover",
|
|
14198
|
-
"mouseup",
|
|
14199
|
-
"pointerdown",
|
|
14200
|
-
"pointermove",
|
|
14201
|
-
"pointerout",
|
|
14202
|
-
"pointerover",
|
|
14203
|
-
"pointerup",
|
|
14204
|
-
"touchend",
|
|
14205
|
-
"touchmove",
|
|
14206
|
-
"touchstart"
|
|
14207
|
-
]);
|
|
14210
|
+
var DelegatedEvents = /* @__PURE__ */ new Set([...DelegatedEventNames]);
|
|
14208
14211
|
var SAFE_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
14209
14212
|
// Console methods
|
|
14210
14213
|
"console.log",
|
|
@@ -16063,7 +16066,7 @@ var DiagnosticMessages = {
|
|
|
16063
16066
|
["FICT-P001" /* FICT_P001 */]: "Props destructuring falls back to non-reactive binding.",
|
|
16064
16067
|
["FICT-P002" /* FICT_P002 */]: "Array rest in props destructuring falls back to non-reactive binding.",
|
|
16065
16068
|
["FICT-P003" /* FICT_P003 */]: "Computed property in props pattern cannot be made reactive.",
|
|
16066
|
-
["FICT-P004" /* FICT_P004 */]: "Nested props destructuring falls back to non-reactive binding; access props directly or use
|
|
16069
|
+
["FICT-P004" /* FICT_P004 */]: "Nested props destructuring falls back to non-reactive binding; access props directly or use prop.",
|
|
16067
16070
|
["FICT-S001" /* FICT_S001 */]: "State variable mutation detected outside component scope.",
|
|
16068
16071
|
["FICT-S002" /* FICT_S002 */]: "State variable escaped to external scope, may cause memory leaks.",
|
|
16069
16072
|
["FICT-E001" /* FICT_E001 */]: "Effect without reactive dependencies will run only once; consider adding state reads or removing the effect.",
|
|
@@ -19458,8 +19461,8 @@ function instructionToStatement(instr, t2, declaredVars, ctx, _buildMemoCall) {
|
|
|
19458
19461
|
const isStateCall2 = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && instr.value.callee.name === "$state";
|
|
19459
19462
|
const inRegionMemo = ctx.inRegionMemo ?? false;
|
|
19460
19463
|
const isFunctionValue = instr.value.kind === "ArrowFunction" || instr.value.kind === "FunctionExpression";
|
|
19461
|
-
const isAccessorReturningCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["$memo", "createMemo", "
|
|
19462
|
-
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"
|
|
19464
|
+
const isAccessorReturningCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["$memo", "createMemo", "prop"].includes(instr.value.callee.name);
|
|
19465
|
+
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"].includes(instr.value.callee.name);
|
|
19463
19466
|
const isMemoReturningCall = isAccessorReturningCall || isReactiveObjectCall;
|
|
19464
19467
|
const lowerAssignedValue = (forceAssigned = false) => lowerExpressionWithDeSSA(instr.value, ctx, forceAssigned || isFunctionValue);
|
|
19465
19468
|
const buildMemoCall = (expr) => {
|
|
@@ -21093,7 +21096,7 @@ function computeReactiveAccessors(fn, ctx) {
|
|
|
21093
21096
|
tracked.add(target);
|
|
21094
21097
|
changed = true;
|
|
21095
21098
|
}
|
|
21096
|
-
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"
|
|
21099
|
+
const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps"].includes(instr.value.callee.name);
|
|
21097
21100
|
if (hasDataDep && !isSignal(target) && !isStore(target) && !isReactiveObjectCall) {
|
|
21098
21101
|
memo.add(target);
|
|
21099
21102
|
}
|
|
@@ -21716,8 +21719,8 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
21716
21719
|
const shouldMemoProp = usesTracked && !t2.isIdentifier(valueExprRaw) && !t2.isMemberExpression(valueExprRaw) && !t2.isLiteral(valueExprRaw);
|
|
21717
21720
|
const valueExpr = usesTracked && ctx.t.isExpression(valueExprRaw) ? (() => {
|
|
21718
21721
|
if (shouldMemoProp) {
|
|
21719
|
-
ctx.helpersUsed.add("
|
|
21720
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.
|
|
21722
|
+
ctx.helpersUsed.add("prop");
|
|
21723
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
21721
21724
|
t2.arrowFunctionExpression([], valueExprRaw)
|
|
21722
21725
|
]);
|
|
21723
21726
|
}
|
|
@@ -23917,8 +23920,8 @@ function buildPropsObject(attributes, ctx) {
|
|
|
23917
23920
|
]);
|
|
23918
23921
|
})() : usesTracked && t2.isExpression(lowered) ? (() => {
|
|
23919
23922
|
if (useMemoProp) {
|
|
23920
|
-
ctx.helpersUsed.add("
|
|
23921
|
-
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.
|
|
23923
|
+
ctx.helpersUsed.add("prop");
|
|
23924
|
+
return t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
23922
23925
|
t2.arrowFunctionExpression(
|
|
23923
23926
|
[],
|
|
23924
23927
|
trackedExpr ?? lowered
|
|
@@ -24440,7 +24443,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24440
24443
|
const stmts = [];
|
|
24441
24444
|
const excludeKeys = [];
|
|
24442
24445
|
let supported = true;
|
|
24443
|
-
let
|
|
24446
|
+
let usesProp = false;
|
|
24444
24447
|
let usesPropsRest = false;
|
|
24445
24448
|
let warnedNested = false;
|
|
24446
24449
|
const memberExprForKey = (base, key) => t2.memberExpression(base, t2.identifier(key), false);
|
|
@@ -24460,16 +24463,16 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24460
24463
|
const member = memberExprForKey(baseExpr, keyName);
|
|
24461
24464
|
const value = prop.value;
|
|
24462
24465
|
if (t2.isIdentifier(value)) {
|
|
24463
|
-
const
|
|
24464
|
-
if (
|
|
24465
|
-
|
|
24466
|
+
const shouldWrapProp = !calledIdentifiers.has(value.name);
|
|
24467
|
+
if (shouldWrapProp) {
|
|
24468
|
+
usesProp = true;
|
|
24466
24469
|
propsPlanAliases.add(value.name);
|
|
24467
24470
|
}
|
|
24468
24471
|
stmts.push(
|
|
24469
24472
|
t2.variableDeclaration("const", [
|
|
24470
24473
|
t2.variableDeclarator(
|
|
24471
24474
|
t2.identifier(value.name),
|
|
24472
|
-
|
|
24475
|
+
shouldWrapProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
24473
24476
|
t2.arrowFunctionExpression([], member)
|
|
24474
24477
|
]) : member
|
|
24475
24478
|
)
|
|
@@ -24483,13 +24486,13 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24483
24486
|
continue;
|
|
24484
24487
|
}
|
|
24485
24488
|
if (t2.isAssignmentPattern(value) && t2.isIdentifier(value.left)) {
|
|
24486
|
-
const
|
|
24487
|
-
if (
|
|
24488
|
-
|
|
24489
|
+
const shouldWrapProp = !calledIdentifiers.has(value.left.name);
|
|
24490
|
+
if (shouldWrapProp) {
|
|
24491
|
+
usesProp = true;
|
|
24489
24492
|
propsPlanAliases.add(value.left.name);
|
|
24490
24493
|
}
|
|
24491
24494
|
const baseInit = t2.logicalExpression("??", member, value.right);
|
|
24492
|
-
const init =
|
|
24495
|
+
const init = shouldWrapProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.prop), [
|
|
24493
24496
|
t2.arrowFunctionExpression([], baseInit)
|
|
24494
24497
|
]) : baseInit;
|
|
24495
24498
|
stmts.push(
|
|
@@ -24533,7 +24536,7 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24533
24536
|
if (supported) {
|
|
24534
24537
|
propsDestructurePlan = {
|
|
24535
24538
|
statements: stmts,
|
|
24536
|
-
|
|
24539
|
+
usesProp,
|
|
24537
24540
|
usesPropsRest
|
|
24538
24541
|
};
|
|
24539
24542
|
propsPlanAliases.forEach((name) => {
|
|
@@ -24627,8 +24630,8 @@ function lowerFunctionWithRegions(fn, ctx) {
|
|
|
24627
24630
|
finalParams = [t2.identifier("__props")];
|
|
24628
24631
|
const pattern = rawParam.type === "AssignmentPattern" ? rawParam.left : rawParam;
|
|
24629
24632
|
if (propsDestructurePlan) {
|
|
24630
|
-
if (propsDestructurePlan.
|
|
24631
|
-
ctx.helpersUsed.add("
|
|
24633
|
+
if (propsDestructurePlan.usesProp) {
|
|
24634
|
+
ctx.helpersUsed.add("prop");
|
|
24632
24635
|
}
|
|
24633
24636
|
if (propsDestructurePlan.usesPropsRest) {
|
|
24634
24637
|
ctx.helpersUsed.add("propsRest");
|
|
@@ -25116,8 +25119,10 @@ function createHIREntrypointVisitor(t2, options) {
|
|
|
25116
25119
|
const fileName = path.hub?.file?.opts?.filename || "<unknown>";
|
|
25117
25120
|
const comments = path.hub?.file?.ast?.comments || [];
|
|
25118
25121
|
const suppressions = parseSuppressions(comments);
|
|
25119
|
-
const
|
|
25120
|
-
const
|
|
25122
|
+
const dev = options.dev !== false;
|
|
25123
|
+
const warn = dev ? createWarningDispatcher(options.onWarn, suppressions) : () => {
|
|
25124
|
+
};
|
|
25125
|
+
const optionsWithWarnings = dev ? { ...options, onWarn: warn } : { ...options, onWarn: void 0 };
|
|
25121
25126
|
const isHookName2 = (name) => !!name && /^use[A-Z]/.test(name);
|
|
25122
25127
|
const getFunctionName = (fnPath) => {
|
|
25123
25128
|
return fnPath.isFunctionDeclaration() && fnPath.node.id ? fnPath.node.id.name : fnPath.isFunctionExpression() && fnPath.node.id ? fnPath.node.id.name : fnPath.parentPath.isVariableDeclarator() && t2.isIdentifier(fnPath.parentPath.node.id) && fnPath.parentPath.node.init === fnPath.node ? fnPath.parentPath.node.id.name : void 0;
|
|
@@ -25373,6 +25378,18 @@ function createHIREntrypointVisitor(t2, options) {
|
|
|
25373
25378
|
},
|
|
25374
25379
|
CallExpression(callPath) {
|
|
25375
25380
|
if (isStateCall(callPath.node, t2)) {
|
|
25381
|
+
const parentPath = callPath.parentPath;
|
|
25382
|
+
const isVariableDeclarator = parentPath?.isVariableDeclarator() && parentPath.node.init === callPath.node;
|
|
25383
|
+
if (!isVariableDeclarator) {
|
|
25384
|
+
throw callPath.buildCodeFrameError(
|
|
25385
|
+
"$state() must be assigned directly to a variable (e.g. let count = $state(0)). For object state, consider using $store from fict/plus."
|
|
25386
|
+
);
|
|
25387
|
+
}
|
|
25388
|
+
if (!t2.isIdentifier(parentPath.node.id)) {
|
|
25389
|
+
throw callPath.buildCodeFrameError(
|
|
25390
|
+
"Destructuring $state is not supported. Use a simple identifier."
|
|
25391
|
+
);
|
|
25392
|
+
}
|
|
25376
25393
|
const ownerComponent = callPath.getFunctionParent();
|
|
25377
25394
|
if (!ownerComponent || !isComponentOrHookDefinition(ownerComponent)) {
|
|
25378
25395
|
throw callPath.buildCodeFrameError(
|
|
@@ -25565,7 +25582,9 @@ function createHIREntrypointVisitor(t2, options) {
|
|
|
25565
25582
|
}
|
|
25566
25583
|
});
|
|
25567
25584
|
}
|
|
25568
|
-
|
|
25585
|
+
if (dev) {
|
|
25586
|
+
runWarningPass(path, stateVars, derivedVars, warn, fileName, t2);
|
|
25587
|
+
}
|
|
25569
25588
|
const fileAst = t2.file(path.node);
|
|
25570
25589
|
const hir = buildHIR(fileAst);
|
|
25571
25590
|
const lowered = lowerHIRWithRegions(hir, t2, optionsWithWarnings);
|
|
@@ -25585,7 +25604,8 @@ var createFictPlugin = declare(
|
|
|
25585
25604
|
const t2 = api.types;
|
|
25586
25605
|
const normalizedOptions = {
|
|
25587
25606
|
...options,
|
|
25588
|
-
fineGrainedDom: options.fineGrainedDom ?? true
|
|
25607
|
+
fineGrainedDom: options.fineGrainedDom ?? true,
|
|
25608
|
+
dev: options.dev ?? (process.env.NODE_ENV !== "production" && process.env.NODE_ENV !== "test")
|
|
25589
25609
|
};
|
|
25590
25610
|
return {
|
|
25591
25611
|
name: "fict-compiler-hir",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fictjs/compiler",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "Babel plugin for Fict Compiler",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@types/babel__helper-plugin-utils": "^7.10.3",
|
|
46
46
|
"@types/babel__traverse": "^7.28.0",
|
|
47
47
|
"tsup": "^8.5.1",
|
|
48
|
-
"@fictjs/runtime": "0.0.
|
|
48
|
+
"@fictjs/runtime": "0.0.14"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|