@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 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
- useProp: "useProp",
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
- useProp: "useProp",
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 useProp.",
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", "useProp"].includes(instr.value.callee.name);
19474
- const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps", "prop"].includes(instr.value.callee.name);
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", "prop"].includes(instr.value.callee.name);
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("useProp");
21732
- return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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("useProp");
23933
- return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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 usesUseProp = false;
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 shouldUseProp = !calledIdentifiers.has(value.name);
24476
- if (shouldUseProp) {
24477
- usesUseProp = true;
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
- shouldUseProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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 shouldUseProp = !calledIdentifiers.has(value.left.name);
24499
- if (shouldUseProp) {
24500
- usesUseProp = true;
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 = shouldUseProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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
- usesUseProp,
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.usesUseProp) {
24643
- ctx.helpersUsed.add("useProp");
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 warn = createWarningDispatcher(options.onWarn, suppressions);
25132
- const optionsWithWarnings = { ...options, onWarn: warn };
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
- runWarningPass(path, stateVars, derivedVars, warn, fileName, t2);
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
- useProp: "useProp",
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
- useProp: "useProp",
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 useProp.",
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", "useProp"].includes(instr.value.callee.name);
19462
- const isReactiveObjectCall = instr.value.kind === "CallExpression" && instr.value.callee.kind === "Identifier" && ["mergeProps", "prop"].includes(instr.value.callee.name);
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", "prop"].includes(instr.value.callee.name);
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("useProp");
21720
- return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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("useProp");
23921
- return t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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 usesUseProp = false;
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 shouldUseProp = !calledIdentifiers.has(value.name);
24464
- if (shouldUseProp) {
24465
- usesUseProp = true;
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
- shouldUseProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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 shouldUseProp = !calledIdentifiers.has(value.left.name);
24487
- if (shouldUseProp) {
24488
- usesUseProp = true;
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 = shouldUseProp ? t2.callExpression(t2.identifier(RUNTIME_ALIASES.useProp), [
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
- usesUseProp,
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.usesUseProp) {
24631
- ctx.helpersUsed.add("useProp");
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 warn = createWarningDispatcher(options.onWarn, suppressions);
25120
- const optionsWithWarnings = { ...options, onWarn: warn };
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
- runWarningPass(path, stateVars, derivedVars, warn, fileName, t2);
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.13",
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.13"
48
+ "@fictjs/runtime": "0.0.14"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsup src/index.ts --format cjs,esm --dts",