@fluixi/compiler 1.0.0-alpha.92 → 1.0.0-alpha.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/analyze/intrinsics.cjs +31 -1
  2. package/dist/analyze/intrinsics.d.cts +14 -0
  3. package/dist/analyze/intrinsics.d.ts +14 -0
  4. package/dist/analyze/intrinsics.d.ts.map +1 -1
  5. package/dist/analyze/intrinsics.js +35 -0
  6. package/dist/analyze/intrinsics.mjs +31 -1
  7. package/dist/analyze/reactive-bindings.cjs +18 -0
  8. package/dist/analyze/reactive-bindings.mjs +18 -0
  9. package/dist/analyze/static-graph.cjs +22 -4
  10. package/dist/analyze/static-graph.d.ts.map +1 -1
  11. package/dist/analyze/static-graph.js +6 -4
  12. package/dist/analyze/static-graph.mjs +22 -4
  13. package/dist/{babel-GI375YZ2.mjs → babel-RJFQVFJW.mjs} +4 -4
  14. package/dist/{chunk-QZ4CJPYP.mjs → chunk-DP2QDWWH.mjs} +1 -1
  15. package/dist/{chunk-DWNWN5RH.mjs → chunk-E2RWTIYE.mjs} +21 -15
  16. package/dist/{chunk-XJ5H2MXY.mjs → chunk-HCCBEJEZ.mjs} +31 -1
  17. package/dist/{chunk-VOUI6XPV.mjs → chunk-HIZU7WI2.mjs} +1 -1
  18. package/dist/{chunk-VC6X44FS.mjs → chunk-ZR2QHTEX.mjs} +505 -68
  19. package/dist/codegen/backends/imperative.cjs +24 -6
  20. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  21. package/dist/codegen/backends/imperative.js +20 -4
  22. package/dist/codegen/backends/imperative.mjs +24 -6
  23. package/dist/frontend/babel/build-ir-lit.cjs +470 -63
  24. package/dist/frontend/babel/build-ir-lit.mjs +470 -63
  25. package/dist/frontend/babel/build-ir.cjs +470 -63
  26. package/dist/frontend/babel/build-ir.mjs +470 -63
  27. package/dist/frontend/babel/index.cjs +471 -64
  28. package/dist/frontend/babel/index.mjs +471 -64
  29. package/dist/frontend/babel/lower-template.cjs +470 -63
  30. package/dist/frontend/babel/lower-template.mjs +470 -63
  31. package/dist/frontend/babel/plugin.cjs +470 -63
  32. package/dist/frontend/babel/plugin.mjs +470 -63
  33. package/dist/index.cjs +360 -58
  34. package/dist/index.mjs +372 -58
  35. package/dist/integrations.cjs +1347 -98
  36. package/dist/integrations.d.ts.map +1 -1
  37. package/dist/integrations.js +44 -2
  38. package/dist/integrations.mjs +205 -19
  39. package/dist/lower/compile-template.cjs +354 -57
  40. package/dist/lower/compile-template.d.cts +13 -0
  41. package/dist/lower/compile-template.d.ts +13 -0
  42. package/dist/lower/compile-template.d.ts.map +1 -1
  43. package/dist/lower/compile-template.js +3 -0
  44. package/dist/lower/compile-template.mjs +366 -57
  45. package/dist/lower/entities.cjs +288 -0
  46. package/dist/lower/entities.d.cts +1 -0
  47. package/dist/lower/entities.d.ts +2 -0
  48. package/dist/lower/entities.d.ts.map +1 -0
  49. package/dist/lower/entities.js +54 -0
  50. package/dist/lower/entities.mjs +267 -0
  51. package/dist/lower/jsx.cjs +567 -7
  52. package/dist/lower/jsx.d.cts +8 -0
  53. package/dist/lower/jsx.d.ts +8 -0
  54. package/dist/lower/jsx.d.ts.map +1 -1
  55. package/dist/lower/jsx.js +205 -7
  56. package/dist/lower/jsx.mjs +567 -7
  57. package/dist/lower/template.cjs +332 -56
  58. package/dist/lower/template.d.ts.map +1 -1
  59. package/dist/lower/template.js +57 -49
  60. package/dist/lower/template.mjs +332 -56
  61. package/dist/resolve/builtins.cjs +1 -1
  62. package/dist/resolve/builtins.mjs +1 -1
  63. package/dist/resolve/component-globals.cjs +20 -1
  64. package/dist/resolve/component-globals.js +2 -2
  65. package/dist/resolve/component-globals.mjs +20 -1
  66. package/dist/resolve/write-globals.cjs +20 -1
  67. package/dist/resolve/write-globals.mjs +20 -1
  68. package/dist/{server-fns-BBZRZUPP.mjs → server-fns-JLSTKWPS.mjs} +4 -4
  69. package/dist/{server-functions-VEGLIFCE.mjs → server-functions-BGY3RD4R.mjs} +3 -3
  70. package/dist/transform/index.cjs +1123 -77
  71. package/dist/transform/index.mjs +1141 -91
  72. package/dist/transform/intrinsics.cjs +18 -0
  73. package/dist/transform/intrinsics.mjs +18 -0
  74. package/dist/transform/props.mjs +19 -14
  75. package/dist/transform/server-fns.mjs +19 -14
  76. package/dist/transform/source-locations.cjs +64 -3
  77. package/dist/transform/source-locations.d.cts +7 -2
  78. package/dist/transform/source-locations.d.ts +7 -2
  79. package/dist/transform/source-locations.d.ts.map +1 -1
  80. package/dist/transform/source-locations.js +68 -3
  81. package/dist/transform/source-locations.mjs +64 -3
  82. package/dist/transform/styles.cjs +588 -0
  83. package/dist/transform/styles.d.cts +211 -0
  84. package/dist/transform/styles.d.ts +212 -0
  85. package/dist/transform/styles.d.ts.map +1 -0
  86. package/dist/transform/styles.js +714 -0
  87. package/dist/transform/styles.mjs +653 -0
  88. package/dist/transform/templates.cjs +1122 -76
  89. package/dist/transform/templates.d.cts +13 -0
  90. package/dist/transform/templates.d.ts +13 -0
  91. package/dist/transform/templates.d.ts.map +1 -1
  92. package/dist/transform/templates.js +51 -14
  93. package/dist/transform/templates.mjs +1140 -90
  94. package/dist/{transform-UWZ7ZGJ2.mjs → transform-GBP6Y4UI.mjs} +603 -19
  95. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  96. package/dist/vite-styles.cjs +180 -0
  97. package/dist/vite-styles.d.cts +59 -0
  98. package/dist/vite-styles.d.ts +60 -0
  99. package/dist/vite-styles.d.ts.map +1 -0
  100. package/dist/vite-styles.js +198 -0
  101. package/dist/vite-styles.mjs +159 -0
  102. package/package.json +10 -3
@@ -34,6 +34,7 @@ var INTRINSICS = {
34
34
  $effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
35
35
  $store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
36
36
  $resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
37
+ $cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
37
38
  // No short runtime form for these yet, so the intrinsic stands for the `create*`
38
39
  // name. Still worth having: no import to write, and when a shorter form is
39
40
  // designed, the change is this line rather than a compiler pass.
@@ -44,6 +45,19 @@ var INTRINSICS = {
44
45
  // dependency analysis must not guess at.
45
46
  $untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
46
47
  $untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
48
+ // Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
49
+ // no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
50
+ $batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
51
+ $cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
52
+ $root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
53
+ $context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
54
+ $renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
55
+ $computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
56
+ // Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
57
+ // handle as far as reads go: the same accessor with `set` on it.
58
+ $storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
59
+ $asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
60
+ $persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
47
61
  // An environment variable, public or server-only; the browser build refuses a secret.
48
62
  $env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
49
63
  };
@@ -56,8 +70,11 @@ var RUNTIME_PRIMITIVES = {
56
70
  createMemo: "memo-accessor",
57
71
  createEffect: "effect",
58
72
  createRenderEffect: "effect",
73
+ renderEffect: "effect",
74
+ computed: "effect",
59
75
  createStore: "reactive-object",
60
76
  resource: "resource-handle",
77
+ cachedResource: "resource-handle",
61
78
  createResource: "reactive-object",
62
79
  createSelector: "memo-accessor",
63
80
  createDeferred: "memo-accessor"
@@ -66,6 +83,7 @@ var PRIMITIVE_MODULES = [
66
83
  "@fluixi/reactive",
67
84
  "@fluixi/reactive/signal",
68
85
  "@fluixi/reactive/store",
86
+ "@fluixi/reactive/cached-resource",
69
87
  "@fluixi/core"
70
88
  ];
71
89
  var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
@@ -6,6 +6,7 @@ var INTRINSICS = {
6
6
  $effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
7
7
  $store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
8
8
  $resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
9
+ $cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
9
10
  // No short runtime form for these yet, so the intrinsic stands for the `create*`
10
11
  // name. Still worth having: no import to write, and when a shorter form is
11
12
  // designed, the change is this line rather than a compiler pass.
@@ -16,6 +17,19 @@ var INTRINSICS = {
16
17
  // dependency analysis must not guess at.
17
18
  $untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
18
19
  $untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
20
+ // Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
21
+ // no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
22
+ $batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
23
+ $cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
24
+ $root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
25
+ $context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
26
+ $renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
27
+ $computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
28
+ // Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
29
+ // handle as far as reads go: the same accessor with `set` on it.
30
+ $storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
31
+ $asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
32
+ $persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
19
33
  // An environment variable, public or server-only; the browser build refuses a secret.
20
34
  $env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
21
35
  };
@@ -28,8 +42,11 @@ var RUNTIME_PRIMITIVES = {
28
42
  createMemo: "memo-accessor",
29
43
  createEffect: "effect",
30
44
  createRenderEffect: "effect",
45
+ renderEffect: "effect",
46
+ computed: "effect",
31
47
  createStore: "reactive-object",
32
48
  resource: "resource-handle",
49
+ cachedResource: "resource-handle",
33
50
  createResource: "reactive-object",
34
51
  createSelector: "memo-accessor",
35
52
  createDeferred: "memo-accessor"
@@ -38,6 +55,7 @@ var PRIMITIVE_MODULES = [
38
55
  "@fluixi/reactive",
39
56
  "@fluixi/reactive/signal",
40
57
  "@fluixi/reactive/store",
58
+ "@fluixi/reactive/cached-resource",
41
59
  "@fluixi/core"
42
60
  ];
43
61
  var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
@@ -1,7 +1,7 @@
1
1
  // src/transform/props.ts
2
2
  import { parse } from "@babel/parser";
3
3
 
4
- // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
4
+ // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
5
5
  var comma = ",".charCodeAt(0);
6
6
  var semicolon = ";".charCodeAt(0);
7
7
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -12,16 +12,16 @@ for (let i = 0; i < chars.length; i++) {
12
12
  intToChar[i] = c;
13
13
  charToInt[c] = i;
14
14
  }
15
- function encodeInteger(builder, num, relative) {
16
- let delta = num - relative;
17
- delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
15
+ function encodeInteger(builder, num) {
18
16
  do {
19
- let clamped = delta & 31;
20
- delta >>>= 5;
21
- if (delta > 0) clamped |= 32;
17
+ let clamped = num & 31;
18
+ num >>>= 5;
19
+ if (num > 0) clamped |= 32;
22
20
  builder.write(intToChar[clamped]);
23
- } while (delta > 0);
24
- return num;
21
+ } while (num > 0);
22
+ }
23
+ function encodeSign(num) {
24
+ return num < 0 ? -num << 1 | 1 : num << 1;
25
25
  }
26
26
  var bufLength = 1024 * 16;
27
27
  var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
@@ -71,13 +71,18 @@ function encode(decoded) {
71
71
  for (let j = 0; j < line.length; j++) {
72
72
  const segment = line[j];
73
73
  if (j > 0) writer.write(comma);
74
- genColumn = encodeInteger(writer, segment[0], genColumn);
74
+ encodeInteger(writer, encodeSign(segment[0] - genColumn));
75
+ genColumn = segment[0];
75
76
  if (segment.length === 1) continue;
76
- sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
77
- sourceLine = encodeInteger(writer, segment[2], sourceLine);
78
- sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
77
+ encodeInteger(writer, encodeSign(segment[1] - sourcesIndex));
78
+ encodeInteger(writer, encodeSign(segment[2] - sourceLine));
79
+ encodeInteger(writer, encodeSign(segment[3] - sourceColumn));
80
+ sourcesIndex = segment[1];
81
+ sourceLine = segment[2];
82
+ sourceColumn = segment[3];
79
83
  if (segment.length === 4) continue;
80
- namesIndex = encodeInteger(writer, segment[4], namesIndex);
84
+ encodeInteger(writer, encodeSign(segment[4] - namesIndex));
85
+ namesIndex = segment[4];
81
86
  }
82
87
  }
83
88
  return writer.flush();
@@ -1,7 +1,7 @@
1
1
  // src/transform/server-fns.ts
2
2
  import { parse } from "@babel/parser";
3
3
 
4
- // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
4
+ // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
5
5
  var comma = ",".charCodeAt(0);
6
6
  var semicolon = ";".charCodeAt(0);
7
7
  var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
@@ -12,16 +12,16 @@ for (let i = 0; i < chars.length; i++) {
12
12
  intToChar[i] = c;
13
13
  charToInt[c] = i;
14
14
  }
15
- function encodeInteger(builder, num, relative) {
16
- let delta = num - relative;
17
- delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
15
+ function encodeInteger(builder, num) {
18
16
  do {
19
- let clamped = delta & 31;
20
- delta >>>= 5;
21
- if (delta > 0) clamped |= 32;
17
+ let clamped = num & 31;
18
+ num >>>= 5;
19
+ if (num > 0) clamped |= 32;
22
20
  builder.write(intToChar[clamped]);
23
- } while (delta > 0);
24
- return num;
21
+ } while (num > 0);
22
+ }
23
+ function encodeSign(num) {
24
+ return num < 0 ? -num << 1 | 1 : num << 1;
25
25
  }
26
26
  var bufLength = 1024 * 16;
27
27
  var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
@@ -71,13 +71,18 @@ function encode(decoded) {
71
71
  for (let j = 0; j < line.length; j++) {
72
72
  const segment = line[j];
73
73
  if (j > 0) writer.write(comma);
74
- genColumn = encodeInteger(writer, segment[0], genColumn);
74
+ encodeInteger(writer, encodeSign(segment[0] - genColumn));
75
+ genColumn = segment[0];
75
76
  if (segment.length === 1) continue;
76
- sourcesIndex = encodeInteger(writer, segment[1], sourcesIndex);
77
- sourceLine = encodeInteger(writer, segment[2], sourceLine);
78
- sourceColumn = encodeInteger(writer, segment[3], sourceColumn);
77
+ encodeInteger(writer, encodeSign(segment[1] - sourcesIndex));
78
+ encodeInteger(writer, encodeSign(segment[2] - sourceLine));
79
+ encodeInteger(writer, encodeSign(segment[3] - sourceColumn));
80
+ sourcesIndex = segment[1];
81
+ sourceLine = segment[2];
82
+ sourceColumn = segment[3];
79
83
  if (segment.length === 4) continue;
80
- namesIndex = encodeInteger(writer, segment[4], namesIndex);
84
+ encodeInteger(writer, encodeSign(segment[4] - namesIndex));
85
+ namesIndex = segment[4];
81
86
  }
82
87
  }
83
88
  return writer.flush();
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/transform/source-locations.ts
21
21
  var source_locations_exports = {};
22
22
  __export(source_locations_exports, {
23
+ CLASS_MARKER: () => CLASS_MARKER,
23
24
  COMPONENT_MARKER: () => COMPONENT_MARKER,
24
25
  HOLE_MARKER: () => HOLE_MARKER,
25
26
  PROPS_MARKER: () => PROPS_MARKER,
@@ -27,7 +28,7 @@ __export(source_locations_exports, {
27
28
  collectSourceEdits: () => collectSourceEdits,
28
29
  markHole: () => markHole,
29
30
  markProps: () => markProps,
30
- mayHaveReactiveCall: () => mayHaveReactiveCall
31
+ mayHaveSourceMarks: () => mayHaveSourceMarks
31
32
  });
32
33
  module.exports = __toCommonJS(source_locations_exports);
33
34
 
@@ -39,6 +40,7 @@ var INTRINSICS = {
39
40
  $effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
40
41
  $store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
41
42
  $resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
43
+ $cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
42
44
  // No short runtime form for these yet, so the intrinsic stands for the `create*`
43
45
  // name. Still worth having: no import to write, and when a shorter form is
44
46
  // designed, the change is this line rather than a compiler pass.
@@ -49,6 +51,19 @@ var INTRINSICS = {
49
51
  // dependency analysis must not guess at.
50
52
  $untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
51
53
  $untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
54
+ // Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
55
+ // no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
56
+ $batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
57
+ $cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
58
+ $root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
59
+ $context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
60
+ $renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
61
+ $computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
62
+ // Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
63
+ // handle as far as reads go: the same accessor with `set` on it.
64
+ $storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
65
+ $asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
66
+ $persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
52
67
  // An environment variable, public or server-only; the browser build refuses a secret.
53
68
  $env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
54
69
  };
@@ -61,8 +76,11 @@ var RUNTIME_PRIMITIVES = {
61
76
  createMemo: "memo-accessor",
62
77
  createEffect: "effect",
63
78
  createRenderEffect: "effect",
79
+ renderEffect: "effect",
80
+ computed: "effect",
64
81
  createStore: "reactive-object",
65
82
  resource: "resource-handle",
83
+ cachedResource: "resource-handle",
66
84
  createResource: "reactive-object",
67
85
  createSelector: "memo-accessor",
68
86
  createDeferred: "memo-accessor"
@@ -71,6 +89,7 @@ var PRIMITIVE_MODULES = [
71
89
  "@fluixi/reactive",
72
90
  "@fluixi/reactive/signal",
73
91
  "@fluixi/reactive/store",
92
+ "@fluixi/reactive/cached-resource",
74
93
  "@fluixi/core"
75
94
  ];
76
95
  var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
@@ -174,6 +193,7 @@ function resolveReactiveBindings(program) {
174
193
  // src/transform/source-locations.ts
175
194
  var SOURCE_MARKER = "__fx_source";
176
195
  var COMPONENT_MARKER = "__fx_component";
196
+ var CLASS_MARKER = "__fx_class";
177
197
  var HOLE_MARKER = "__fx_hole";
178
198
  var markHole = (accessor, line, column, name) => `(globalThis.${HOLE_MARKER} ?? ((f) => f))(${accessor},${line},${column}${name === void 0 ? "" : `,${JSON.stringify(name)}`})`;
179
199
  var PROPS_MARKER = "__fx_props";
@@ -191,11 +211,12 @@ var RUNTIME_PRIMITIVES2 = /* @__PURE__ */ new Set([
191
211
  "createStore",
192
212
  "createResource"
193
213
  ]);
194
- function mayHaveReactiveCall(code) {
214
+ function mayHaveSourceMarks(code) {
195
215
  for (const name of RUNTIME_PRIMITIVES2) {
196
216
  if (code.includes(name)) return true;
197
217
  }
198
- return code.includes("$signal") || code.includes("$memo") || code.includes("$effect") || code.includes("$store");
218
+ if (code.includes("$signal") || code.includes("$memo") || code.includes("$effect") || code.includes("$store")) return true;
219
+ return /\bclass\b[^{;]*\bextends\b/.test(code);
199
220
  }
200
221
  var SINGLE_STATEMENT_PARENTS = /* @__PURE__ */ new Set([
201
222
  "IfStatement",
@@ -214,6 +235,7 @@ function isLoneBranch(statement, parent) {
214
235
  function isExport(node) {
215
236
  return node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration";
216
237
  }
238
+ var CLASS_FIELDS = /* @__PURE__ */ new Set(["PropertyDefinition", "ClassProperty", "ClassPrivateProperty", "AccessorProperty"]);
217
239
  function isStatement(node) {
218
240
  return node.type.endsWith("Statement") || node.type === "VariableDeclaration";
219
241
  }
@@ -234,6 +256,14 @@ function walk2(node, visit, stack = []) {
234
256
  }
235
257
  function nameFor(stack) {
236
258
  const declarator = stack[stack.length - 1];
259
+ if (declarator && CLASS_FIELDS.has(declarator.type)) {
260
+ const key = declarator.key;
261
+ if (key?.type === "Identifier" || key?.type === "PrivateIdentifier" || key?.type === "PrivateName") {
262
+ const name = key.name ?? key.id?.name;
263
+ return name;
264
+ }
265
+ return void 0;
266
+ }
237
267
  if (declarator?.type !== "VariableDeclarator") return void 0;
238
268
  const id = declarator.id;
239
269
  if (id?.type === "Identifier") return id.name;
@@ -282,6 +312,17 @@ function collectSourceEdits(program, filename) {
282
312
  });
283
313
  }
284
314
  }
315
+ if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.superClass && !node.declare) {
316
+ const at = node.loc?.start;
317
+ const body = node.body;
318
+ if (at && body) {
319
+ edits.push({
320
+ start: body.start + 1,
321
+ end: body.start + 1,
322
+ code: `static{globalThis.${CLASS_MARKER}?.(this,${JSON.stringify(filename)},${at.line},${at.column});}`
323
+ });
324
+ }
325
+ }
285
326
  if (node.type !== "CallExpression") return;
286
327
  const callee = node.callee;
287
328
  if (callee?.type !== "Identifier") return;
@@ -291,6 +332,26 @@ function collectSourceEdits(program, filename) {
291
332
  if (!intrinsic && !imported) return;
292
333
  const position = node.loc?.start;
293
334
  if (!position) return;
335
+ for (let i = stack.length - 1; i >= 0; i--) {
336
+ const up = stack[i];
337
+ if (isStatement(up)) break;
338
+ if (CLASS_FIELDS.has(up.type)) {
339
+ if (claimed.has(node.start)) return;
340
+ claimed.add(node.start);
341
+ const label2 = nameFor(stack);
342
+ const own = !up.static;
343
+ const args2 = [
344
+ JSON.stringify(filename),
345
+ String(position.line),
346
+ String(position.column),
347
+ label2 ? JSON.stringify(label2) : own ? "undefined" : void 0,
348
+ own ? "this" : void 0
349
+ ].filter((a) => a !== void 0).join(",");
350
+ edits.push({ start: node.start, end: node.start, code: `(globalThis.${SOURCE_MARKER}?.(${args2}),` });
351
+ edits.push({ start: node.end, end: node.end, code: ")" });
352
+ return;
353
+ }
354
+ }
294
355
  let statement;
295
356
  let parent;
296
357
  let index = -1;
@@ -12,6 +12,11 @@ export interface SourceLocationsResult {
12
12
  export declare const SOURCE_MARKER = "__fx_source";
13
13
  /** Where a component was declared. Keyed by name, since that is all the runtime carries. */
14
14
  export declare const COMPONENT_MARKER = "__fx_component";
15
+ /**
16
+ * Where a class that extends another was declared, keyed by the class itself: a custom
17
+ * element's definition, which the runtime can only reach through `element.constructor`.
18
+ */
19
+ export declare const CLASS_MARKER = "__fx_class";
15
20
  /**
16
21
  * Where one reactive hole was written. This one wraps: the position has to travel with the
17
22
  * accessor to wherever the dom wires it up. A template is emitted as one overwrite, so the
@@ -38,6 +43,6 @@ export declare const markHole: (accessor: string, line: number, column: number,
38
43
  export declare const PROPS_MARKER = "__fx_props";
39
44
  /** `_({ get a() {…} }, {"a":[9,25]})`, or the object untouched when nothing is watching. */
40
45
  export declare const markProps: (object: string, at: Record<string, [number, number]>) => string;
41
- /** Cheap enough to run before parsing. */
42
- export declare function mayHaveReactiveCall(code: string): boolean;
46
+ /** Whether a module has anything to mark: a primitive call or a subclass. Cheap enough to run before parsing. */
47
+ export declare function mayHaveSourceMarks(code: string): boolean;
43
48
  export declare function collectSourceEdits(program: unknown, filename: string): SourceLocationsResult;
@@ -12,6 +12,11 @@ export interface SourceLocationsResult {
12
12
  export declare const SOURCE_MARKER = "__fx_source";
13
13
  /** Where a component was declared. Keyed by name, since that is all the runtime carries. */
14
14
  export declare const COMPONENT_MARKER = "__fx_component";
15
+ /**
16
+ * Where a class that extends another was declared, keyed by the class itself: a custom
17
+ * element's definition, which the runtime can only reach through `element.constructor`.
18
+ */
19
+ export declare const CLASS_MARKER = "__fx_class";
15
20
  /**
16
21
  * Where one reactive hole was written. This one wraps: the position has to travel with the
17
22
  * accessor to wherever the dom wires it up. A template is emitted as one overwrite, so the
@@ -38,7 +43,7 @@ export declare const markHole: (accessor: string, line: number, column: number,
38
43
  export declare const PROPS_MARKER = "__fx_props";
39
44
  /** `_({ get a() {…} }, {"a":[9,25]})`, or the object untouched when nothing is watching. */
40
45
  export declare const markProps: (object: string, at: Record<string, [number, number]>) => string;
41
- /** Cheap enough to run before parsing. */
42
- export declare function mayHaveReactiveCall(code: string): boolean;
46
+ /** Whether a module has anything to mark: a primitive call or a subclass. Cheap enough to run before parsing. */
47
+ export declare function mayHaveSourceMarks(code: string): boolean;
43
48
  export declare function collectSourceEdits(program: unknown, filename: string): SourceLocationsResult;
44
49
  //# sourceMappingURL=source-locations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"source-locations.d.ts","sourceRoot":"","sources":["../../src/transform/source-locations.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAE3C,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GACnB,UAAU,MAAM,EAChB,MAAM,MAAM,EACZ,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,MAGE,CAAC;AAEN;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC,4FAA4F;AAC5F,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,MACF,CAAC;AAQhF,0CAA0C;AAC1C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKzD;AAuED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CA+G5F"}
1
+ {"version":3,"file":"source-locations.d.ts","sourceRoot":"","sources":["../../src/transform/source-locations.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,eAAO,MAAM,aAAa,gBAAgB,CAAC;AAE3C,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GACnB,UAAU,MAAM,EAChB,MAAM,MAAM,EACZ,QAAQ,MAAM,EACd,OAAO,MAAM,KACZ,MAGE,CAAC;AAEN;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,eAAe,CAAC;AAEzC,4FAA4F;AAC5F,eAAO,MAAM,SAAS,GAAI,QAAQ,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,KAAG,MACF,CAAC;AAQhF,iHAAiH;AACjH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOxD;AAmFD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB,CA6J5F"}
@@ -22,6 +22,11 @@ import { resolveReactiveBindings } from '../analyze/reactive-bindings.js';
22
22
  export const SOURCE_MARKER = '__fx_source';
23
23
  /** Where a component was declared. Keyed by name, since that is all the runtime carries. */
24
24
  export const COMPONENT_MARKER = '__fx_component';
25
+ /**
26
+ * Where a class that extends another was declared, keyed by the class itself: a custom
27
+ * element's definition, which the runtime can only reach through `element.constructor`.
28
+ */
29
+ export const CLASS_MARKER = '__fx_class';
25
30
  /**
26
31
  * Where one reactive hole was written. This one wraps: the position has to travel with the
27
32
  * accessor to wherever the dom wires it up. A template is emitted as one overwrite, so the
@@ -53,13 +58,16 @@ const RUNTIME_PRIMITIVES = new Set([
53
58
  'signal', 'memo', 'effect', 'store', 'resource', 'watch',
54
59
  'createSignal', 'createMemo', 'createEffect', 'createStore', 'createResource',
55
60
  ]);
56
- /** Cheap enough to run before parsing. */
57
- export function mayHaveReactiveCall(code) {
61
+ /** Whether a module has anything to mark: a primitive call or a subclass. Cheap enough to run before parsing. */
62
+ export function mayHaveSourceMarks(code) {
58
63
  for (const name of RUNTIME_PRIMITIVES) {
59
64
  if (code.includes(name))
60
65
  return true;
61
66
  }
62
- return code.includes('$signal') || code.includes('$memo') || code.includes('$effect') || code.includes('$store');
67
+ if (code.includes('$signal') || code.includes('$memo') || code.includes('$effect') || code.includes('$store'))
68
+ return true;
69
+ // A subclass gets a declaration mark, so an element with no signal of its own is still found.
70
+ return /\bclass\b[^{;]*\bextends\b/.test(code);
63
71
  }
64
72
  /** Positions where the grammar allows exactly one statement, so a second one changes it. */
65
73
  const SINGLE_STATEMENT_PARENTS = new Set([
@@ -74,6 +82,8 @@ function isLoneBranch(statement, parent) {
74
82
  function isExport(node) {
75
83
  return node.type === 'ExportNamedDeclaration' || node.type === 'ExportDefaultDeclaration';
76
84
  }
85
+ /** Where a class holds a per-instance initializer: the value of a field. */
86
+ const CLASS_FIELDS = new Set(['PropertyDefinition', 'ClassProperty', 'ClassPrivateProperty', 'AccessorProperty']);
77
87
  function isStatement(node) {
78
88
  return node.type.endsWith('Statement') || node.type === 'VariableDeclaration';
79
89
  }
@@ -103,6 +113,15 @@ function walk(node, visit, stack = []) {
103
113
  */
104
114
  function nameFor(stack) {
105
115
  const declarator = stack[stack.length - 1];
116
+ // `#count = signal(0)` and `count = signal(0)`: the field's name, without the `#`.
117
+ if (declarator && CLASS_FIELDS.has(declarator.type)) {
118
+ const key = declarator.key;
119
+ if (key?.type === 'Identifier' || key?.type === 'PrivateIdentifier' || key?.type === 'PrivateName') {
120
+ const name = (key.name ?? key.id?.name);
121
+ return name;
122
+ }
123
+ return undefined;
124
+ }
106
125
  if (declarator?.type !== 'VariableDeclarator')
107
126
  return undefined;
108
127
  const id = declarator.id;
@@ -170,6 +189,20 @@ export function collectSourceEdits(program, filename) {
170
189
  });
171
190
  }
172
191
  }
192
+ // A static block at the top of the body runs once, when the class is defined, with `this`
193
+ // bound to the class. Only a subclass: that covers every custom element and keeps the mark
194
+ // off plain classes. An ambient `declare class` has no body to run.
195
+ if ((node.type === 'ClassDeclaration' || node.type === 'ClassExpression') && node.superClass && !node.declare) {
196
+ const at = node.loc?.start;
197
+ const body = node.body;
198
+ if (at && body) {
199
+ edits.push({
200
+ start: body.start + 1,
201
+ end: body.start + 1,
202
+ code: `static{globalThis.${CLASS_MARKER}?.(this,${JSON.stringify(filename)},${at.line},${at.column});}`,
203
+ });
204
+ }
205
+ }
173
206
  if (node.type !== 'CallExpression')
174
207
  return;
175
208
  const callee = node.callee;
@@ -186,6 +219,38 @@ export function collectSourceEdits(program, filename) {
186
219
  const position = node.loc?.start;
187
220
  if (!position)
188
221
  return;
222
+ // A class field (`#count = signal(0)`) runs once per instance, and the class body has no
223
+ // statement to put the mark in front of. Hoisting it before the class runs it once, at
224
+ // definition, and the next node created anywhere took its name and line; inside a function
225
+ // (a mixin) the nearest statement was the function's body block, and the mark landed in
226
+ // front of the `{`. The call itself carries the mark instead, so it runs right before the
227
+ // node it describes.
228
+ for (let i = stack.length - 1; i >= 0; i--) {
229
+ const up = stack[i];
230
+ if (isStatement(up))
231
+ break;
232
+ if (CLASS_FIELDS.has(up.type)) {
233
+ if (claimed.has(node.start))
234
+ return;
235
+ claimed.add(node.start);
236
+ const label = nameFor(stack);
237
+ // An instance field also hands over `this`: the constructor runs before a custom
238
+ // element opens its scope, and the instance is what ties the node to it later.
239
+ const own = !up.static;
240
+ const args = [
241
+ JSON.stringify(filename),
242
+ String(position.line),
243
+ String(position.column),
244
+ label ? JSON.stringify(label) : own ? 'undefined' : undefined,
245
+ own ? 'this' : undefined,
246
+ ]
247
+ .filter((a) => a !== undefined)
248
+ .join(',');
249
+ edits.push({ start: node.start, end: node.start, code: `(globalThis.${SOURCE_MARKER}?.(${args}),` });
250
+ edits.push({ start: node.end, end: node.end, code: ')' });
251
+ return;
252
+ }
253
+ }
189
254
  // The mark goes in front of the statement, clear of any span another pass rewrites.
190
255
  let statement;
191
256
  let parent;