@fictjs/compiler 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +739 -81
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +739 -81
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -14135,6 +14135,9 @@ var RUNTIME_HELPERS = {
|
|
|
14135
14135
|
conditional: "createConditional",
|
|
14136
14136
|
keyedList: "createKeyedList",
|
|
14137
14137
|
insert: "insert",
|
|
14138
|
+
insertBetween: "insertBetween",
|
|
14139
|
+
resolvePath: "resolvePath",
|
|
14140
|
+
getSlotEnd: "getSlotEnd",
|
|
14138
14141
|
onDestroy: "onDestroy",
|
|
14139
14142
|
bindText: "bindText",
|
|
14140
14143
|
bindAttribute: "bindAttribute",
|
|
@@ -14146,7 +14149,18 @@ var RUNTIME_HELPERS = {
|
|
|
14146
14149
|
bindRef: "bindRef",
|
|
14147
14150
|
toNodeArray: "toNodeArray",
|
|
14148
14151
|
template: "template",
|
|
14149
|
-
delegateEvents: "delegateEvents"
|
|
14152
|
+
delegateEvents: "delegateEvents",
|
|
14153
|
+
useLexicalScope: "__fictUseLexicalScope",
|
|
14154
|
+
getScopeProps: "__fictGetScopeProps",
|
|
14155
|
+
qrl: "__fictQrl",
|
|
14156
|
+
getSSRScope: "__fictGetSSRScope",
|
|
14157
|
+
ensureScope: "__fictEnsureScope",
|
|
14158
|
+
prepareContext: "__fictPrepareContext",
|
|
14159
|
+
enterHydration: "__fictEnterHydration",
|
|
14160
|
+
exitHydration: "__fictExitHydration",
|
|
14161
|
+
domRender: "render",
|
|
14162
|
+
hydrateComponent: "hydrateComponent",
|
|
14163
|
+
registerResume: "__fictRegisterResume"
|
|
14150
14164
|
};
|
|
14151
14165
|
var RUNTIME_ALIASES = {
|
|
14152
14166
|
signal: "createSignal",
|
|
@@ -14171,6 +14185,9 @@ var RUNTIME_ALIASES = {
|
|
|
14171
14185
|
conditional: "createConditional",
|
|
14172
14186
|
keyedList: "createKeyedList",
|
|
14173
14187
|
insert: "insert",
|
|
14188
|
+
insertBetween: "insertBetween",
|
|
14189
|
+
resolvePath: "resolvePath",
|
|
14190
|
+
getSlotEnd: "getSlotEnd",
|
|
14174
14191
|
onDestroy: "onDestroy",
|
|
14175
14192
|
bindText: "bindText",
|
|
14176
14193
|
bindAttribute: "bindAttribute",
|
|
@@ -14182,7 +14199,18 @@ var RUNTIME_ALIASES = {
|
|
|
14182
14199
|
bindRef: "bindRef",
|
|
14183
14200
|
toNodeArray: "toNodeArray",
|
|
14184
14201
|
template: "template",
|
|
14185
|
-
delegateEvents: "delegateEvents"
|
|
14202
|
+
delegateEvents: "delegateEvents",
|
|
14203
|
+
useLexicalScope: "__fictUseLexicalScope",
|
|
14204
|
+
getScopeProps: "__fictGetScopeProps",
|
|
14205
|
+
qrl: "__fictQrl",
|
|
14206
|
+
getSSRScope: "__fictGetSSRScope",
|
|
14207
|
+
ensureScope: "__fictEnsureScope",
|
|
14208
|
+
prepareContext: "__fictPrepareContext",
|
|
14209
|
+
enterHydration: "__fictEnterHydration",
|
|
14210
|
+
exitHydration: "__fictExitHydration",
|
|
14211
|
+
domRender: "render",
|
|
14212
|
+
hydrateComponent: "hydrateComponent",
|
|
14213
|
+
registerResume: "__fictRegisterResume"
|
|
14186
14214
|
};
|
|
14187
14215
|
var DelegatedEvents = /* @__PURE__ */ new Set([...DelegatedEventNames]);
|
|
14188
14216
|
var SAFE_FUNCTIONS = /* @__PURE__ */ new Set([
|
|
@@ -14533,6 +14561,9 @@ function parseFictReturnAnnotation(node) {
|
|
|
14533
14561
|
if (content === "'memo'" || content === '"memo"') {
|
|
14534
14562
|
return { directAccessor: "memo" };
|
|
14535
14563
|
}
|
|
14564
|
+
if (/^\{\s*\}$/.test(content)) {
|
|
14565
|
+
return { objectProps: /* @__PURE__ */ new Map() };
|
|
14566
|
+
}
|
|
14536
14567
|
const objectMatch = content.match(/^\{([^}]+)\}$/);
|
|
14537
14568
|
if (objectMatch) {
|
|
14538
14569
|
const objectProps = /* @__PURE__ */ new Map();
|
|
@@ -16362,6 +16393,9 @@ function convertJSXMemberExpr(node) {
|
|
|
16362
16393
|
};
|
|
16363
16394
|
}
|
|
16364
16395
|
|
|
16396
|
+
// src/ir/codegen.ts
|
|
16397
|
+
import { pathToFileURL } from "url";
|
|
16398
|
+
|
|
16365
16399
|
// src/fine-grained-dom.ts
|
|
16366
16400
|
function normalizeDependencyKey(name) {
|
|
16367
16401
|
return name.split(".").map((part) => part.replace(/_\d+$/, "")).join(".");
|
|
@@ -21161,9 +21195,14 @@ function instructionToStatement(instr, t4, declaredVars, ctx, _buildMemoCall) {
|
|
|
21161
21195
|
declaredVars.add(baseName2);
|
|
21162
21196
|
if (treatAsTracked && !isDestructuringTemp) {
|
|
21163
21197
|
if (isStateCall2) {
|
|
21164
|
-
|
|
21165
|
-
|
|
21166
|
-
|
|
21198
|
+
ctx.currentAssignmentName = baseName2;
|
|
21199
|
+
try {
|
|
21200
|
+
return t4.variableDeclaration(normalizedDecl, [
|
|
21201
|
+
t4.variableDeclarator(t4.identifier(baseName2), lowerAssignedValue(true))
|
|
21202
|
+
]);
|
|
21203
|
+
} finally {
|
|
21204
|
+
ctx.currentAssignmentName = void 0;
|
|
21205
|
+
}
|
|
21167
21206
|
}
|
|
21168
21207
|
if (dependsOnTracked) {
|
|
21169
21208
|
if (instr.value.kind === "Identifier" && ctx.trackedVars.has(deSSAVarName(instr.value.name)) && !isDestructuringTemp) {
|
|
@@ -22086,7 +22125,17 @@ function createCodegenContext(t4) {
|
|
|
22086
22125
|
hookReturnInfo: /* @__PURE__ */ new Map(),
|
|
22087
22126
|
hoistedTemplates: /* @__PURE__ */ new Map(),
|
|
22088
22127
|
hoistedTemplateStatements: [],
|
|
22089
|
-
|
|
22128
|
+
hoistedResumableStatements: [],
|
|
22129
|
+
resumableHandlerCounter: 0,
|
|
22130
|
+
resumableComponentCounter: 0,
|
|
22131
|
+
resumableComponents: /* @__PURE__ */ new Map(),
|
|
22132
|
+
resumableEnabled: false,
|
|
22133
|
+
autoExtractEnabled: false,
|
|
22134
|
+
autoExtractThreshold: 3,
|
|
22135
|
+
delegatedEventsUsed: /* @__PURE__ */ new Set(),
|
|
22136
|
+
componentFunctionDefs: /* @__PURE__ */ new Map(),
|
|
22137
|
+
hoistedFunctionDepCounter: 0,
|
|
22138
|
+
hoistedFunctionDepNames: /* @__PURE__ */ new Map()
|
|
22090
22139
|
};
|
|
22091
22140
|
}
|
|
22092
22141
|
function withGetterCache(ctx, fn) {
|
|
@@ -22992,6 +23041,51 @@ function computeReactiveAccessors(fn, ctx) {
|
|
|
22992
23041
|
function genTemp(ctx, prefix = "tmp") {
|
|
22993
23042
|
return ctx.t.identifier(`__${prefix}_${ctx.tempCounter++}`);
|
|
22994
23043
|
}
|
|
23044
|
+
function renameIdentifiersInExpr(expr, renames, _t) {
|
|
23045
|
+
const cloned = JSON.parse(JSON.stringify(expr));
|
|
23046
|
+
function visit(node) {
|
|
23047
|
+
if (!node || typeof node !== "object") return;
|
|
23048
|
+
const n = node;
|
|
23049
|
+
if (n.type === "Identifier" && typeof n.name === "string") {
|
|
23050
|
+
const newName = renames.get(n.name);
|
|
23051
|
+
if (newName) {
|
|
23052
|
+
n.name = newName;
|
|
23053
|
+
}
|
|
23054
|
+
}
|
|
23055
|
+
for (const key of Object.keys(n)) {
|
|
23056
|
+
if (key === "loc" || key === "start" || key === "end" || key === "extra" || key === "comments" || key === "leadingComments" || key === "trailingComments") {
|
|
23057
|
+
continue;
|
|
23058
|
+
}
|
|
23059
|
+
const value = n[key];
|
|
23060
|
+
if (Array.isArray(value)) {
|
|
23061
|
+
for (const item of value) {
|
|
23062
|
+
visit(item);
|
|
23063
|
+
}
|
|
23064
|
+
} else if (value && typeof value === "object") {
|
|
23065
|
+
visit(value);
|
|
23066
|
+
}
|
|
23067
|
+
}
|
|
23068
|
+
}
|
|
23069
|
+
visit(cloned);
|
|
23070
|
+
return cloned;
|
|
23071
|
+
}
|
|
23072
|
+
function genModuleUrlExpr(ctx) {
|
|
23073
|
+
const { t: t4 } = ctx;
|
|
23074
|
+
const filename = ctx.options?.filename;
|
|
23075
|
+
if (filename) {
|
|
23076
|
+
let fileUrl;
|
|
23077
|
+
if (filename.startsWith("file://")) {
|
|
23078
|
+
fileUrl = filename;
|
|
23079
|
+
} else {
|
|
23080
|
+
fileUrl = pathToFileURL(filename).href;
|
|
23081
|
+
}
|
|
23082
|
+
return t4.stringLiteral(fileUrl);
|
|
23083
|
+
}
|
|
23084
|
+
return t4.memberExpression(
|
|
23085
|
+
t4.metaProperty(t4.identifier("import"), t4.identifier("meta")),
|
|
23086
|
+
t4.identifier("url")
|
|
23087
|
+
);
|
|
23088
|
+
}
|
|
22995
23089
|
function extractKeyFromAttributes(attributes) {
|
|
22996
23090
|
for (const attr of attributes) {
|
|
22997
23091
|
if (attr.name === "key" && attr.value) {
|
|
@@ -23115,6 +23209,26 @@ function lowerInstruction(instr, ctx) {
|
|
|
23115
23209
|
ctx.memoVars?.add(baseName2);
|
|
23116
23210
|
}
|
|
23117
23211
|
}
|
|
23212
|
+
if (declKind) {
|
|
23213
|
+
const initKind = getReactiveCallKind(instr.value, ctx);
|
|
23214
|
+
if (initKind === "signal") {
|
|
23215
|
+
ctx.signalVars?.add(baseName2);
|
|
23216
|
+
ctx.trackedVars.add(baseName2);
|
|
23217
|
+
ctx.currentAssignmentName = baseName2;
|
|
23218
|
+
const loweredValue = (() => {
|
|
23219
|
+
try {
|
|
23220
|
+
return lowerTrackedExpression(instr.value, ctx);
|
|
23221
|
+
} finally {
|
|
23222
|
+
ctx.currentAssignmentName = void 0;
|
|
23223
|
+
}
|
|
23224
|
+
})();
|
|
23225
|
+
return applyLoc(
|
|
23226
|
+
t4.variableDeclaration(declKind, [
|
|
23227
|
+
t4.variableDeclarator(t4.identifier(baseName2), loweredValue)
|
|
23228
|
+
])
|
|
23229
|
+
);
|
|
23230
|
+
}
|
|
23231
|
+
}
|
|
23118
23232
|
if (ctx.signalVars?.has(baseName2)) {
|
|
23119
23233
|
ctx.currentAssignmentName = baseName2;
|
|
23120
23234
|
const loweredValue = (() => {
|
|
@@ -23840,23 +23954,23 @@ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
|
|
|
23840
23954
|
case "MetaProperty":
|
|
23841
23955
|
return t4.metaProperty(t4.identifier(expr.meta.name), t4.identifier(expr.property.name));
|
|
23842
23956
|
case "CallExpression": {
|
|
23843
|
-
|
|
23957
|
+
const stateCalleeNameRaw = expr.callee.kind === "Identifier" ? expr.callee.name : null;
|
|
23958
|
+
const stateCalleeName = stateCalleeNameRaw ? deSSAVarName(stateCalleeNameRaw) : null;
|
|
23959
|
+
if (stateCalleeName && ctx.stateMacroNames?.has(stateCalleeName)) {
|
|
23844
23960
|
const args = lowerCallArguments(expr.arguments);
|
|
23845
23961
|
const includeDevtools = ctx.options?.dev !== false;
|
|
23846
|
-
|
|
23847
|
-
|
|
23848
|
-
|
|
23849
|
-
|
|
23850
|
-
|
|
23851
|
-
|
|
23852
|
-
|
|
23853
|
-
|
|
23854
|
-
|
|
23855
|
-
|
|
23856
|
-
|
|
23857
|
-
|
|
23858
|
-
args.push(t4.objectExpression(options));
|
|
23859
|
-
}
|
|
23962
|
+
const options = [];
|
|
23963
|
+
if (ctx.currentAssignmentName) {
|
|
23964
|
+
options.push(
|
|
23965
|
+
t4.objectProperty(t4.identifier("name"), t4.stringLiteral(ctx.currentAssignmentName))
|
|
23966
|
+
);
|
|
23967
|
+
}
|
|
23968
|
+
if (includeDevtools && expr.loc) {
|
|
23969
|
+
const source = `${ctx.options?.filename ?? ""}:${expr.loc.start.line}:${expr.loc.start.column}`;
|
|
23970
|
+
options.push(t4.objectProperty(t4.identifier("devToolsSource"), t4.stringLiteral(source)));
|
|
23971
|
+
}
|
|
23972
|
+
if (options.length > 0) {
|
|
23973
|
+
args.push(t4.objectExpression(options));
|
|
23860
23974
|
}
|
|
23861
23975
|
if (ctx.inModule) {
|
|
23862
23976
|
ctx.helpersUsed.add("signal");
|
|
@@ -25010,17 +25124,280 @@ function resolveNamespaceContext(tagName, parentNamespace) {
|
|
|
25010
25124
|
if (tagName === "foreignObject" && parentNamespace === "svg") return null;
|
|
25011
25125
|
return parentNamespace;
|
|
25012
25126
|
}
|
|
25127
|
+
function countExpressionNodes(expr) {
|
|
25128
|
+
if (!expr) return 0;
|
|
25129
|
+
let count = 1;
|
|
25130
|
+
switch (expr.kind) {
|
|
25131
|
+
case "Literal":
|
|
25132
|
+
return 1;
|
|
25133
|
+
case "Identifier":
|
|
25134
|
+
return 1;
|
|
25135
|
+
case "BinaryExpression":
|
|
25136
|
+
case "LogicalExpression":
|
|
25137
|
+
count += countExpressionNodes(expr.left);
|
|
25138
|
+
count += countExpressionNodes(expr.right);
|
|
25139
|
+
return count;
|
|
25140
|
+
case "UnaryExpression":
|
|
25141
|
+
count += countExpressionNodes(expr.argument);
|
|
25142
|
+
return count;
|
|
25143
|
+
case "ConditionalExpression":
|
|
25144
|
+
count += countExpressionNodes(expr.test);
|
|
25145
|
+
count += countExpressionNodes(expr.consequent);
|
|
25146
|
+
count += countExpressionNodes(expr.alternate);
|
|
25147
|
+
return count;
|
|
25148
|
+
case "CallExpression":
|
|
25149
|
+
count += countExpressionNodes(expr.callee);
|
|
25150
|
+
for (const arg of expr.arguments) {
|
|
25151
|
+
count += countExpressionNodes(arg);
|
|
25152
|
+
}
|
|
25153
|
+
return count;
|
|
25154
|
+
case "MemberExpression":
|
|
25155
|
+
count += countExpressionNodes(expr.object);
|
|
25156
|
+
if (expr.computed && expr.property) {
|
|
25157
|
+
count += countExpressionNodes(expr.property);
|
|
25158
|
+
}
|
|
25159
|
+
return count;
|
|
25160
|
+
case "ArrayExpression":
|
|
25161
|
+
for (const elem of expr.elements) {
|
|
25162
|
+
if (elem) count += countExpressionNodes(elem);
|
|
25163
|
+
}
|
|
25164
|
+
return count;
|
|
25165
|
+
case "ObjectExpression":
|
|
25166
|
+
for (const prop of expr.properties) {
|
|
25167
|
+
if (prop.kind === "Property") {
|
|
25168
|
+
count += countExpressionNodes(prop.value);
|
|
25169
|
+
} else if (prop.kind === "SpreadElement") {
|
|
25170
|
+
count += countExpressionNodes(prop.argument);
|
|
25171
|
+
}
|
|
25172
|
+
}
|
|
25173
|
+
return count;
|
|
25174
|
+
case "ArrowFunction":
|
|
25175
|
+
if (expr.isExpression && expr.body && !Array.isArray(expr.body)) {
|
|
25176
|
+
count += countExpressionNodes(expr.body);
|
|
25177
|
+
} else if (Array.isArray(expr.body)) {
|
|
25178
|
+
for (const block of expr.body) {
|
|
25179
|
+
count += countBlockNodes(block);
|
|
25180
|
+
}
|
|
25181
|
+
}
|
|
25182
|
+
return count;
|
|
25183
|
+
case "FunctionExpression":
|
|
25184
|
+
if (expr.body) {
|
|
25185
|
+
for (const block of expr.body) {
|
|
25186
|
+
count += countBlockNodes(block);
|
|
25187
|
+
}
|
|
25188
|
+
}
|
|
25189
|
+
return count;
|
|
25190
|
+
case "AssignmentExpression":
|
|
25191
|
+
count += countExpressionNodes(expr.left);
|
|
25192
|
+
count += countExpressionNodes(expr.right);
|
|
25193
|
+
return count;
|
|
25194
|
+
case "UpdateExpression":
|
|
25195
|
+
count += countExpressionNodes(expr.argument);
|
|
25196
|
+
return count;
|
|
25197
|
+
case "SequenceExpression":
|
|
25198
|
+
for (const e of expr.expressions) {
|
|
25199
|
+
count += countExpressionNodes(e);
|
|
25200
|
+
}
|
|
25201
|
+
return count;
|
|
25202
|
+
case "AwaitExpression":
|
|
25203
|
+
count += countExpressionNodes(expr.argument);
|
|
25204
|
+
return count + 2;
|
|
25205
|
+
// Async adds complexity
|
|
25206
|
+
case "NewExpression":
|
|
25207
|
+
count += countExpressionNodes(expr.callee);
|
|
25208
|
+
for (const arg of expr.arguments) {
|
|
25209
|
+
count += countExpressionNodes(arg);
|
|
25210
|
+
}
|
|
25211
|
+
return count;
|
|
25212
|
+
case "TemplateLiteral":
|
|
25213
|
+
for (const e of expr.expressions) {
|
|
25214
|
+
count += countExpressionNodes(e);
|
|
25215
|
+
}
|
|
25216
|
+
return count;
|
|
25217
|
+
default:
|
|
25218
|
+
return count;
|
|
25219
|
+
}
|
|
25220
|
+
}
|
|
25221
|
+
function countBlockNodes(block) {
|
|
25222
|
+
let count = 1;
|
|
25223
|
+
for (const instr of block.instructions) {
|
|
25224
|
+
count += countInstructionNodes(instr);
|
|
25225
|
+
}
|
|
25226
|
+
return count;
|
|
25227
|
+
}
|
|
25228
|
+
function countInstructionNodes(instr) {
|
|
25229
|
+
switch (instr.kind) {
|
|
25230
|
+
case "Expression":
|
|
25231
|
+
return 1 + countExpressionNodes(instr.value);
|
|
25232
|
+
case "Assign":
|
|
25233
|
+
return 1 + countExpressionNodes(instr.value);
|
|
25234
|
+
case "Phi":
|
|
25235
|
+
return 1;
|
|
25236
|
+
default:
|
|
25237
|
+
return 1;
|
|
25238
|
+
}
|
|
25239
|
+
}
|
|
25240
|
+
function hasExternalCalls(expr) {
|
|
25241
|
+
if (!expr) return false;
|
|
25242
|
+
switch (expr.kind) {
|
|
25243
|
+
case "CallExpression": {
|
|
25244
|
+
if (expr.callee.kind === "Identifier") {
|
|
25245
|
+
const name = expr.callee.name;
|
|
25246
|
+
if (!["console", "Math", "JSON", "Object", "Array"].includes(name)) {
|
|
25247
|
+
return true;
|
|
25248
|
+
}
|
|
25249
|
+
}
|
|
25250
|
+
if (expr.callee.kind === "MemberExpression") {
|
|
25251
|
+
return true;
|
|
25252
|
+
}
|
|
25253
|
+
for (const arg of expr.arguments) {
|
|
25254
|
+
if (hasExternalCalls(arg)) return true;
|
|
25255
|
+
}
|
|
25256
|
+
return false;
|
|
25257
|
+
}
|
|
25258
|
+
case "ArrowFunction":
|
|
25259
|
+
if (expr.isExpression && expr.body && !Array.isArray(expr.body)) {
|
|
25260
|
+
return hasExternalCalls(expr.body);
|
|
25261
|
+
} else if (Array.isArray(expr.body)) {
|
|
25262
|
+
for (const block of expr.body) {
|
|
25263
|
+
if (blockHasExternalCalls(block)) return true;
|
|
25264
|
+
}
|
|
25265
|
+
}
|
|
25266
|
+
return false;
|
|
25267
|
+
case "FunctionExpression":
|
|
25268
|
+
if (expr.body) {
|
|
25269
|
+
for (const block of expr.body) {
|
|
25270
|
+
if (blockHasExternalCalls(block)) return true;
|
|
25271
|
+
}
|
|
25272
|
+
}
|
|
25273
|
+
return false;
|
|
25274
|
+
case "BinaryExpression":
|
|
25275
|
+
case "LogicalExpression":
|
|
25276
|
+
return hasExternalCalls(expr.left) || hasExternalCalls(expr.right);
|
|
25277
|
+
case "UnaryExpression":
|
|
25278
|
+
return hasExternalCalls(expr.argument);
|
|
25279
|
+
case "ConditionalExpression":
|
|
25280
|
+
return hasExternalCalls(expr.test) || hasExternalCalls(expr.consequent) || hasExternalCalls(expr.alternate);
|
|
25281
|
+
case "MemberExpression":
|
|
25282
|
+
return hasExternalCalls(expr.object);
|
|
25283
|
+
case "AssignmentExpression":
|
|
25284
|
+
return hasExternalCalls(expr.right);
|
|
25285
|
+
case "SequenceExpression":
|
|
25286
|
+
return expr.expressions.some((e) => hasExternalCalls(e));
|
|
25287
|
+
case "AwaitExpression":
|
|
25288
|
+
return true;
|
|
25289
|
+
// Await implies async external operation
|
|
25290
|
+
case "NewExpression":
|
|
25291
|
+
return true;
|
|
25292
|
+
// Constructor calls are external
|
|
25293
|
+
default:
|
|
25294
|
+
return false;
|
|
25295
|
+
}
|
|
25296
|
+
}
|
|
25297
|
+
function blockHasExternalCalls(block) {
|
|
25298
|
+
for (const instr of block.instructions) {
|
|
25299
|
+
if (instructionHasExternalCalls(instr)) return true;
|
|
25300
|
+
}
|
|
25301
|
+
return false;
|
|
25302
|
+
}
|
|
25303
|
+
function instructionHasExternalCalls(instr) {
|
|
25304
|
+
switch (instr.kind) {
|
|
25305
|
+
case "Expression":
|
|
25306
|
+
return hasExternalCalls(instr.value);
|
|
25307
|
+
case "Assign":
|
|
25308
|
+
return hasExternalCalls(instr.value);
|
|
25309
|
+
default:
|
|
25310
|
+
return false;
|
|
25311
|
+
}
|
|
25312
|
+
}
|
|
25313
|
+
function hasAsyncAwait(expr) {
|
|
25314
|
+
if (!expr) return false;
|
|
25315
|
+
switch (expr.kind) {
|
|
25316
|
+
case "AwaitExpression":
|
|
25317
|
+
return true;
|
|
25318
|
+
case "ArrowFunction":
|
|
25319
|
+
if (expr.isAsync) return true;
|
|
25320
|
+
if (expr.isExpression && expr.body && !Array.isArray(expr.body)) {
|
|
25321
|
+
return hasAsyncAwait(expr.body);
|
|
25322
|
+
} else if (Array.isArray(expr.body)) {
|
|
25323
|
+
for (const block of expr.body) {
|
|
25324
|
+
if (blockHasAsyncAwait(block)) return true;
|
|
25325
|
+
}
|
|
25326
|
+
}
|
|
25327
|
+
return false;
|
|
25328
|
+
case "FunctionExpression":
|
|
25329
|
+
if (expr.isAsync) return true;
|
|
25330
|
+
if (expr.body) {
|
|
25331
|
+
for (const block of expr.body) {
|
|
25332
|
+
if (blockHasAsyncAwait(block)) return true;
|
|
25333
|
+
}
|
|
25334
|
+
}
|
|
25335
|
+
return false;
|
|
25336
|
+
case "CallExpression":
|
|
25337
|
+
if (hasAsyncAwait(expr.callee)) return true;
|
|
25338
|
+
return expr.arguments.some((arg) => hasAsyncAwait(arg));
|
|
25339
|
+
case "BinaryExpression":
|
|
25340
|
+
case "LogicalExpression":
|
|
25341
|
+
return hasAsyncAwait(expr.left) || hasAsyncAwait(expr.right);
|
|
25342
|
+
case "ConditionalExpression":
|
|
25343
|
+
return hasAsyncAwait(expr.test) || hasAsyncAwait(expr.consequent) || hasAsyncAwait(expr.alternate);
|
|
25344
|
+
case "SequenceExpression":
|
|
25345
|
+
return expr.expressions.some((e) => hasAsyncAwait(e));
|
|
25346
|
+
default:
|
|
25347
|
+
return false;
|
|
25348
|
+
}
|
|
25349
|
+
}
|
|
25350
|
+
function blockHasAsyncAwait(block) {
|
|
25351
|
+
for (const instr of block.instructions) {
|
|
25352
|
+
if (instructionHasAsyncAwait(instr)) return true;
|
|
25353
|
+
}
|
|
25354
|
+
return false;
|
|
25355
|
+
}
|
|
25356
|
+
function instructionHasAsyncAwait(instr) {
|
|
25357
|
+
switch (instr.kind) {
|
|
25358
|
+
case "Expression":
|
|
25359
|
+
return hasAsyncAwait(instr.value);
|
|
25360
|
+
case "Assign":
|
|
25361
|
+
return hasAsyncAwait(instr.value);
|
|
25362
|
+
default:
|
|
25363
|
+
return false;
|
|
25364
|
+
}
|
|
25365
|
+
}
|
|
25366
|
+
function shouldAutoExtract(expr, ctx) {
|
|
25367
|
+
if (!expr) return false;
|
|
25368
|
+
if (!ctx.autoExtractEnabled) return false;
|
|
25369
|
+
const threshold = ctx.autoExtractThreshold ?? 3;
|
|
25370
|
+
if (expr.kind === "Identifier") {
|
|
25371
|
+
return true;
|
|
25372
|
+
}
|
|
25373
|
+
if (expr.kind === "ArrowFunction" || expr.kind === "FunctionExpression") {
|
|
25374
|
+
if (expr.kind === "ArrowFunction" && expr.isAsync || expr.kind === "FunctionExpression" && expr.isAsync || hasAsyncAwait(expr)) {
|
|
25375
|
+
return true;
|
|
25376
|
+
}
|
|
25377
|
+
if (hasExternalCalls(expr)) {
|
|
25378
|
+
return true;
|
|
25379
|
+
}
|
|
25380
|
+
const nodeCount2 = countExpressionNodes(expr);
|
|
25381
|
+
if (nodeCount2 >= threshold) {
|
|
25382
|
+
return true;
|
|
25383
|
+
}
|
|
25384
|
+
return false;
|
|
25385
|
+
}
|
|
25386
|
+
const nodeCount = countExpressionNodes(expr);
|
|
25387
|
+
return nodeCount >= threshold;
|
|
25388
|
+
}
|
|
25013
25389
|
function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
25014
25390
|
if (jsx.isComponent || typeof jsx.tagName !== "string") {
|
|
25015
25391
|
return {
|
|
25016
|
-
html: "
|
|
25392
|
+
html: "<!--fict:slot:start--><!--fict:slot:end-->",
|
|
25017
25393
|
bindings: [
|
|
25018
25394
|
{
|
|
25019
25395
|
type: "child",
|
|
25020
25396
|
path: [...parentPath],
|
|
25021
25397
|
expr: jsx
|
|
25022
25398
|
}
|
|
25023
|
-
]
|
|
25399
|
+
],
|
|
25400
|
+
nodeCount: 1
|
|
25024
25401
|
};
|
|
25025
25402
|
}
|
|
25026
25403
|
const tagName = jsx.tagName;
|
|
@@ -25031,7 +25408,11 @@ function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
|
25031
25408
|
if (attr.isSpread) {
|
|
25032
25409
|
continue;
|
|
25033
25410
|
}
|
|
25034
|
-
|
|
25411
|
+
let name = normalizeHIRAttrName(attr.name);
|
|
25412
|
+
const isResumableEvent = name.endsWith("$");
|
|
25413
|
+
if (isResumableEvent) {
|
|
25414
|
+
name = name.slice(0, -1);
|
|
25415
|
+
}
|
|
25035
25416
|
if (name === "key") {
|
|
25036
25417
|
if (attr.value && !isStaticValue(attr.value)) {
|
|
25037
25418
|
bindings.push({
|
|
@@ -25066,12 +25447,14 @@ function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
|
25066
25447
|
changed = true;
|
|
25067
25448
|
}
|
|
25068
25449
|
}
|
|
25450
|
+
const shouldBeResumable = isResumableEvent && ctx.resumableEnabled || !isResumableEvent && ctx.resumableEnabled && shouldAutoExtract(attr.value ?? void 0, ctx);
|
|
25069
25451
|
bindings.push({
|
|
25070
25452
|
type: "event",
|
|
25071
25453
|
path: [...parentPath],
|
|
25072
25454
|
name: eventName.toLowerCase(),
|
|
25073
25455
|
expr: attr.value ?? void 0,
|
|
25074
|
-
eventOptions: { capture, passive, once }
|
|
25456
|
+
eventOptions: { capture, passive, once },
|
|
25457
|
+
resumable: shouldBeResumable
|
|
25075
25458
|
});
|
|
25076
25459
|
continue;
|
|
25077
25460
|
}
|
|
@@ -25127,7 +25510,7 @@ function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
|
25127
25510
|
const childResult = extractHIRStaticHtml(child.value, ctx, childPath, resolvedNamespace);
|
|
25128
25511
|
html += childResult.html;
|
|
25129
25512
|
bindings.push(...childResult.bindings);
|
|
25130
|
-
childIndex
|
|
25513
|
+
childIndex += childResult.nodeCount;
|
|
25131
25514
|
} else if (child.kind === "expression") {
|
|
25132
25515
|
const inline = hasAdjacentInline(i);
|
|
25133
25516
|
if (!inline && isLikelyTextExpression(child.value, ctx)) {
|
|
@@ -25140,7 +25523,7 @@ function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
|
25140
25523
|
namespace: resolvedNamespace
|
|
25141
25524
|
});
|
|
25142
25525
|
} else {
|
|
25143
|
-
html += "
|
|
25526
|
+
html += "<!--fict:slot:start--><!--fict:slot:end-->";
|
|
25144
25527
|
bindings.push({
|
|
25145
25528
|
type: "child",
|
|
25146
25529
|
path: [...parentPath, childIndex],
|
|
@@ -25148,6 +25531,8 @@ function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
|
25148
25531
|
// Track namespace for dynamic child bindings
|
|
25149
25532
|
namespace: resolvedNamespace
|
|
25150
25533
|
});
|
|
25534
|
+
childIndex++;
|
|
25535
|
+
continue;
|
|
25151
25536
|
}
|
|
25152
25537
|
childIndex++;
|
|
25153
25538
|
}
|
|
@@ -25158,6 +25543,7 @@ function extractHIRStaticHtml(jsx, ctx, parentPath = [], namespace = null) {
|
|
|
25158
25543
|
return {
|
|
25159
25544
|
html,
|
|
25160
25545
|
bindings,
|
|
25546
|
+
nodeCount: 1,
|
|
25161
25547
|
isSVG: needsSVG || void 0,
|
|
25162
25548
|
isMathML: needsMathML || void 0
|
|
25163
25549
|
};
|
|
@@ -25249,6 +25635,17 @@ function lowerIntrinsicElement(jsx, ctx) {
|
|
|
25249
25635
|
const eventName = binding.name;
|
|
25250
25636
|
const hasEventOptions = binding.eventOptions && (binding.eventOptions.capture || binding.eventOptions.passive || binding.eventOptions.once);
|
|
25251
25637
|
const isDelegated = DelegatedEvents.has(eventName) && !hasEventOptions;
|
|
25638
|
+
if (binding.resumable && !hasEventOptions) {
|
|
25639
|
+
emitResumableEventBinding(
|
|
25640
|
+
targetId,
|
|
25641
|
+
eventName,
|
|
25642
|
+
binding.expr,
|
|
25643
|
+
statements,
|
|
25644
|
+
ctx,
|
|
25645
|
+
containingRegion
|
|
25646
|
+
);
|
|
25647
|
+
continue;
|
|
25648
|
+
}
|
|
25252
25649
|
const hirDataBinding = isDelegated && binding.expr ? extractDelegatedEventDataFromHIR(binding.expr, ctx) : null;
|
|
25253
25650
|
if (hirDataBinding) {
|
|
25254
25651
|
ctx.delegatedEventsUsed?.add(eventName);
|
|
@@ -25545,13 +25942,16 @@ function resolveHIRBindingPath(path2, cache, statements, ctx) {
|
|
|
25545
25942
|
ancestorId = cache.get("");
|
|
25546
25943
|
relativePath = path2;
|
|
25547
25944
|
}
|
|
25548
|
-
|
|
25549
|
-
|
|
25550
|
-
|
|
25551
|
-
for (let i = 0; i < index; i++) {
|
|
25552
|
-
currentExpr = t4.memberExpression(currentExpr, t4.identifier("nextSibling"));
|
|
25553
|
-
}
|
|
25945
|
+
if (relativePath.length === 0) {
|
|
25946
|
+
cache.set(key, ancestorId);
|
|
25947
|
+
return ancestorId;
|
|
25554
25948
|
}
|
|
25949
|
+
ctx.helpersUsed.add("resolvePath");
|
|
25950
|
+
const pathExpr = t4.arrayExpression(relativePath.map((index) => t4.numericLiteral(index)));
|
|
25951
|
+
const currentExpr = t4.callExpression(t4.identifier(RUNTIME_ALIASES.resolvePath), [
|
|
25952
|
+
ancestorId,
|
|
25953
|
+
pathExpr
|
|
25954
|
+
]);
|
|
25555
25955
|
const varId = genTemp(ctx, "el");
|
|
25556
25956
|
statements.push(t4.variableDeclaration("const", [t4.variableDeclarator(varId, currentExpr)]));
|
|
25557
25957
|
cache.set(key, varId);
|
|
@@ -25559,7 +25959,16 @@ function resolveHIRBindingPath(path2, cache, statements, ctx) {
|
|
|
25559
25959
|
}
|
|
25560
25960
|
function emitHIRChildBinding(markerId, expr, statements, ctx, containingRegion, namespace) {
|
|
25561
25961
|
const { t: t4 } = ctx;
|
|
25562
|
-
|
|
25962
|
+
ctx.helpersUsed.add("getSlotEnd");
|
|
25963
|
+
const endMarkerId = genTemp(ctx, "end");
|
|
25964
|
+
statements.push(
|
|
25965
|
+
t4.variableDeclaration("const", [
|
|
25966
|
+
t4.variableDeclarator(
|
|
25967
|
+
endMarkerId,
|
|
25968
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.getSlotEnd), [markerId])
|
|
25969
|
+
)
|
|
25970
|
+
])
|
|
25971
|
+
);
|
|
25563
25972
|
if (namespace !== void 0) {
|
|
25564
25973
|
ctx.namespaceContext = namespace;
|
|
25565
25974
|
}
|
|
@@ -25578,26 +25987,26 @@ function emitHIRChildBinding(markerId, expr, statements, ctx, containingRegion,
|
|
|
25578
25987
|
return;
|
|
25579
25988
|
}
|
|
25580
25989
|
if (expr.kind === "ConditionalExpression" || expr.kind === "LogicalExpression" && expr.operator === "&&") {
|
|
25581
|
-
emitConditionalChild(
|
|
25990
|
+
emitConditionalChild(markerId, endMarkerId, expr, statements, ctx);
|
|
25582
25991
|
return;
|
|
25583
25992
|
}
|
|
25584
25993
|
if (expr.kind === "CallExpression" || expr.kind === "OptionalCallExpression") {
|
|
25585
25994
|
const callee = expr.callee;
|
|
25586
25995
|
if ((callee.kind === "MemberExpression" || callee.kind === "OptionalMemberExpression") && callee.property.kind === "Identifier" && callee.property.name === "map") {
|
|
25587
|
-
emitListChild(
|
|
25996
|
+
emitListChild(markerId, endMarkerId, expr, statements, ctx);
|
|
25588
25997
|
return;
|
|
25589
25998
|
}
|
|
25590
25999
|
}
|
|
25591
26000
|
if (expr.kind === "JSXElement") {
|
|
25592
26001
|
const childExpr = lowerJSXElement(expr, ctx);
|
|
25593
|
-
ctx.helpersUsed.add("
|
|
26002
|
+
ctx.helpersUsed.add("insertBetween");
|
|
25594
26003
|
ctx.helpersUsed.add("createElement");
|
|
25595
26004
|
statements.push(
|
|
25596
26005
|
t4.expressionStatement(
|
|
25597
|
-
t4.callExpression(t4.identifier(RUNTIME_ALIASES.
|
|
25598
|
-
parentId,
|
|
25599
|
-
t4.arrowFunctionExpression([], childExpr),
|
|
26006
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.insertBetween), [
|
|
25600
26007
|
markerId,
|
|
26008
|
+
endMarkerId,
|
|
26009
|
+
t4.arrowFunctionExpression([], childExpr),
|
|
25601
26010
|
t4.identifier(RUNTIME_ALIASES.createElement)
|
|
25602
26011
|
])
|
|
25603
26012
|
)
|
|
@@ -25605,20 +26014,280 @@ function emitHIRChildBinding(markerId, expr, statements, ctx, containingRegion,
|
|
|
25605
26014
|
return;
|
|
25606
26015
|
}
|
|
25607
26016
|
const valueExpr = lowerDomExpression(expr, ctx, containingRegion);
|
|
25608
|
-
ctx.helpersUsed.add("
|
|
26017
|
+
ctx.helpersUsed.add("insertBetween");
|
|
25609
26018
|
ctx.helpersUsed.add("createElement");
|
|
25610
26019
|
statements.push(
|
|
25611
26020
|
t4.expressionStatement(
|
|
25612
|
-
t4.callExpression(t4.identifier(RUNTIME_ALIASES.
|
|
25613
|
-
parentId,
|
|
25614
|
-
t4.arrowFunctionExpression([], valueExpr),
|
|
26021
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.insertBetween), [
|
|
25615
26022
|
markerId,
|
|
26023
|
+
endMarkerId,
|
|
26024
|
+
t4.arrowFunctionExpression([], valueExpr),
|
|
25616
26025
|
t4.identifier(RUNTIME_ALIASES.createElement)
|
|
25617
26026
|
])
|
|
25618
26027
|
)
|
|
25619
26028
|
);
|
|
25620
26029
|
}
|
|
25621
|
-
function
|
|
26030
|
+
function emitResumableEventBinding(targetId, eventName, expr, statements, ctx, containingRegion) {
|
|
26031
|
+
const { t: t4 } = ctx;
|
|
26032
|
+
if (!ctx.resumableEnabled) {
|
|
26033
|
+
return;
|
|
26034
|
+
}
|
|
26035
|
+
const prevWrapTracked = ctx.wrapTrackedExpressions;
|
|
26036
|
+
ctx.wrapTrackedExpressions = false;
|
|
26037
|
+
const valueExpr = lowerDomExpression(expr, ctx, containingRegion, {
|
|
26038
|
+
skipHookAccessors: true,
|
|
26039
|
+
skipRegionRootOverride: true
|
|
26040
|
+
});
|
|
26041
|
+
ctx.wrapTrackedExpressions = prevWrapTracked;
|
|
26042
|
+
const eventParam = t4.identifier("event");
|
|
26043
|
+
const elParam = t4.identifier("el");
|
|
26044
|
+
const scopeParam = t4.identifier("scopeId");
|
|
26045
|
+
const ensureHandlerParam = (fn) => {
|
|
26046
|
+
if (t4.isArrowFunctionExpression(fn)) {
|
|
26047
|
+
if (fn.params.length > 0) return fn;
|
|
26048
|
+
return t4.arrowFunctionExpression([eventParam], fn.body, fn.async);
|
|
26049
|
+
}
|
|
26050
|
+
if (t4.isFunctionExpression(fn)) {
|
|
26051
|
+
if (fn.params.length > 0) return fn;
|
|
26052
|
+
return t4.functionExpression(fn.id, [eventParam], fn.body, fn.generator, fn.async);
|
|
26053
|
+
}
|
|
26054
|
+
if (t4.isIdentifier(fn) || t4.isMemberExpression(fn)) {
|
|
26055
|
+
return fn;
|
|
26056
|
+
}
|
|
26057
|
+
if (t4.isCallExpression(fn) && fn.arguments.length === 0 && (t4.isIdentifier(fn.callee) || t4.isMemberExpression(fn.callee))) {
|
|
26058
|
+
return fn.callee;
|
|
26059
|
+
}
|
|
26060
|
+
return t4.functionExpression(
|
|
26061
|
+
null,
|
|
26062
|
+
[eventParam],
|
|
26063
|
+
t4.blockStatement([
|
|
26064
|
+
t4.returnStatement(
|
|
26065
|
+
t4.callExpression(
|
|
26066
|
+
t4.memberExpression(fn, t4.identifier("call")),
|
|
26067
|
+
[t4.thisExpression(), eventParam]
|
|
26068
|
+
)
|
|
26069
|
+
)
|
|
26070
|
+
])
|
|
26071
|
+
);
|
|
26072
|
+
};
|
|
26073
|
+
const handlerExpr = ensureHandlerParam(valueExpr);
|
|
26074
|
+
const handlerId = t4.identifier(`__fict_e${ctx.resumableHandlerCounter ?? 0}`);
|
|
26075
|
+
ctx.resumableHandlerCounter = (ctx.resumableHandlerCounter ?? 0) + 1;
|
|
26076
|
+
const captured = /* @__PURE__ */ new Set();
|
|
26077
|
+
collectExpressionIdentifiersDeep(expr, captured);
|
|
26078
|
+
const lexicalNames = Array.from(captured).filter((name) => ctx.signalVars?.has(name));
|
|
26079
|
+
const propsName = ctx.propsParamName && captured.has(ctx.propsParamName) ? ctx.propsParamName : null;
|
|
26080
|
+
const functionDeps = [];
|
|
26081
|
+
const functionDepRenames = /* @__PURE__ */ new Map();
|
|
26082
|
+
for (const name of captured) {
|
|
26083
|
+
if (ctx.functionVars?.has(name) && !ctx.signalVars?.has(name)) {
|
|
26084
|
+
const hirDef = ctx.componentFunctionDefs?.get(name);
|
|
26085
|
+
if (hirDef) {
|
|
26086
|
+
functionDeps.push(name);
|
|
26087
|
+
let hoistedName = ctx.hoistedFunctionDepNames?.get(name);
|
|
26088
|
+
if (!hoistedName) {
|
|
26089
|
+
hoistedName = `__fict_fn_${name}_${ctx.hoistedFunctionDepCounter ?? 0}`;
|
|
26090
|
+
ctx.hoistedFunctionDepCounter = (ctx.hoistedFunctionDepCounter ?? 0) + 1;
|
|
26091
|
+
ctx.hoistedFunctionDepNames?.set(name, hoistedName);
|
|
26092
|
+
const loweredFn = lowerDomExpression(hirDef, ctx, null, {
|
|
26093
|
+
skipHookAccessors: true,
|
|
26094
|
+
skipRegionRootOverride: true
|
|
26095
|
+
});
|
|
26096
|
+
const hoistedDecl = t4.variableDeclaration("const", [
|
|
26097
|
+
t4.variableDeclarator(t4.identifier(hoistedName), loweredFn)
|
|
26098
|
+
]);
|
|
26099
|
+
const hoistedExport = t4.exportNamedDeclaration(hoistedDecl, []);
|
|
26100
|
+
ctx.hoistedResumableStatements?.push(hoistedExport);
|
|
26101
|
+
}
|
|
26102
|
+
functionDepRenames.set(name, hoistedName);
|
|
26103
|
+
}
|
|
26104
|
+
}
|
|
26105
|
+
}
|
|
26106
|
+
let finalHandlerExpr = handlerExpr;
|
|
26107
|
+
if (functionDepRenames.size > 0) {
|
|
26108
|
+
finalHandlerExpr = renameIdentifiersInExpr(handlerExpr, functionDepRenames, t4);
|
|
26109
|
+
}
|
|
26110
|
+
const bodyStatements = [];
|
|
26111
|
+
if (lexicalNames.length > 0) {
|
|
26112
|
+
ctx.helpersUsed.add("useLexicalScope");
|
|
26113
|
+
bodyStatements.push(
|
|
26114
|
+
t4.variableDeclaration("const", [
|
|
26115
|
+
t4.variableDeclarator(
|
|
26116
|
+
t4.arrayPattern(lexicalNames.map((name) => t4.identifier(name))),
|
|
26117
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.useLexicalScope), [
|
|
26118
|
+
scopeParam,
|
|
26119
|
+
t4.arrayExpression(lexicalNames.map((name) => t4.stringLiteral(name)))
|
|
26120
|
+
])
|
|
26121
|
+
)
|
|
26122
|
+
])
|
|
26123
|
+
);
|
|
26124
|
+
}
|
|
26125
|
+
if (propsName) {
|
|
26126
|
+
ctx.helpersUsed.add("getScopeProps");
|
|
26127
|
+
bodyStatements.push(
|
|
26128
|
+
t4.variableDeclaration("const", [
|
|
26129
|
+
t4.variableDeclarator(
|
|
26130
|
+
t4.identifier(propsName),
|
|
26131
|
+
t4.logicalExpression(
|
|
26132
|
+
"||",
|
|
26133
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.getScopeProps), [scopeParam]),
|
|
26134
|
+
t4.objectExpression([])
|
|
26135
|
+
)
|
|
26136
|
+
)
|
|
26137
|
+
])
|
|
26138
|
+
);
|
|
26139
|
+
}
|
|
26140
|
+
const handlerVar = t4.identifier("__handler");
|
|
26141
|
+
bodyStatements.push(
|
|
26142
|
+
t4.variableDeclaration("const", [t4.variableDeclarator(handlerVar, finalHandlerExpr)])
|
|
26143
|
+
);
|
|
26144
|
+
bodyStatements.push(
|
|
26145
|
+
t4.returnStatement(
|
|
26146
|
+
t4.callExpression(t4.memberExpression(handlerVar, t4.identifier("call")), [elParam, eventParam])
|
|
26147
|
+
)
|
|
26148
|
+
);
|
|
26149
|
+
const exportedHandler = t4.exportNamedDeclaration(
|
|
26150
|
+
t4.variableDeclaration("const", [
|
|
26151
|
+
t4.variableDeclarator(
|
|
26152
|
+
handlerId,
|
|
26153
|
+
t4.arrowFunctionExpression(
|
|
26154
|
+
[scopeParam, eventParam, elParam],
|
|
26155
|
+
t4.blockStatement(bodyStatements)
|
|
26156
|
+
)
|
|
26157
|
+
)
|
|
26158
|
+
]),
|
|
26159
|
+
[]
|
|
26160
|
+
);
|
|
26161
|
+
ctx.hoistedResumableStatements?.push(exportedHandler);
|
|
26162
|
+
ctx.helpersUsed.add("qrl");
|
|
26163
|
+
const qrlExpr = t4.callExpression(t4.identifier(RUNTIME_ALIASES.qrl), [
|
|
26164
|
+
genModuleUrlExpr(ctx),
|
|
26165
|
+
t4.stringLiteral(handlerId.name)
|
|
26166
|
+
]);
|
|
26167
|
+
statements.push(
|
|
26168
|
+
t4.expressionStatement(
|
|
26169
|
+
t4.callExpression(t4.memberExpression(targetId, t4.identifier("setAttribute")), [
|
|
26170
|
+
t4.stringLiteral(`on:${eventName}`),
|
|
26171
|
+
qrlExpr
|
|
26172
|
+
])
|
|
26173
|
+
)
|
|
26174
|
+
);
|
|
26175
|
+
}
|
|
26176
|
+
function registerResumableComponent(componentName, ctx) {
|
|
26177
|
+
if (!ctx.resumableEnabled) return;
|
|
26178
|
+
if (!ctx.hoistedResumableStatements || !ctx.resumableComponents) return;
|
|
26179
|
+
if (ctx.resumableComponents.has(componentName)) return;
|
|
26180
|
+
const { t: t4 } = ctx;
|
|
26181
|
+
const resumeExport = `__fict_r${ctx.resumableComponentCounter ?? 0}`;
|
|
26182
|
+
ctx.resumableComponentCounter = (ctx.resumableComponentCounter ?? 0) + 1;
|
|
26183
|
+
const scopeParam = t4.identifier("scopeId");
|
|
26184
|
+
const hostParam = t4.identifier("host");
|
|
26185
|
+
const snapshotId = t4.identifier("snapshot");
|
|
26186
|
+
const ctxId = t4.identifier("ctx");
|
|
26187
|
+
ctx.helpersUsed.add("getSSRScope");
|
|
26188
|
+
ctx.helpersUsed.add("ensureScope");
|
|
26189
|
+
ctx.helpersUsed.add("prepareContext");
|
|
26190
|
+
ctx.helpersUsed.add("pushContext");
|
|
26191
|
+
ctx.helpersUsed.add("popContext");
|
|
26192
|
+
ctx.helpersUsed.add("hydrateComponent");
|
|
26193
|
+
ctx.helpersUsed.add("qrl");
|
|
26194
|
+
const snapshotDecl = t4.variableDeclaration("const", [
|
|
26195
|
+
t4.variableDeclarator(
|
|
26196
|
+
snapshotId,
|
|
26197
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.getSSRScope), [scopeParam])
|
|
26198
|
+
)
|
|
26199
|
+
]);
|
|
26200
|
+
const earlyReturn = t4.ifStatement(t4.unaryExpression("!", snapshotId), t4.returnStatement());
|
|
26201
|
+
const ensureCtxDecl = t4.variableDeclaration("const", [
|
|
26202
|
+
t4.variableDeclarator(
|
|
26203
|
+
ctxId,
|
|
26204
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.ensureScope), [
|
|
26205
|
+
scopeParam,
|
|
26206
|
+
hostParam,
|
|
26207
|
+
snapshotId
|
|
26208
|
+
])
|
|
26209
|
+
)
|
|
26210
|
+
]);
|
|
26211
|
+
const prepareCtx = t4.expressionStatement(
|
|
26212
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.prepareContext), [ctxId])
|
|
26213
|
+
);
|
|
26214
|
+
const pushCtx = t4.expressionStatement(
|
|
26215
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.pushContext), [])
|
|
26216
|
+
);
|
|
26217
|
+
const hydrateCall = t4.expressionStatement(
|
|
26218
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.hydrateComponent), [
|
|
26219
|
+
t4.arrowFunctionExpression(
|
|
26220
|
+
[],
|
|
26221
|
+
t4.callExpression(t4.identifier(componentName), [
|
|
26222
|
+
t4.logicalExpression(
|
|
26223
|
+
"||",
|
|
26224
|
+
t4.memberExpression(snapshotId, t4.identifier("props")),
|
|
26225
|
+
t4.objectExpression([])
|
|
26226
|
+
)
|
|
26227
|
+
])
|
|
26228
|
+
),
|
|
26229
|
+
hostParam
|
|
26230
|
+
])
|
|
26231
|
+
);
|
|
26232
|
+
const popCtx = t4.expressionStatement(
|
|
26233
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.popContext), [])
|
|
26234
|
+
);
|
|
26235
|
+
const resumeFnId = t4.identifier(resumeExport);
|
|
26236
|
+
const resumeFn = t4.exportNamedDeclaration(
|
|
26237
|
+
t4.variableDeclaration("const", [
|
|
26238
|
+
t4.variableDeclarator(
|
|
26239
|
+
resumeFnId,
|
|
26240
|
+
t4.arrowFunctionExpression(
|
|
26241
|
+
[scopeParam, hostParam],
|
|
26242
|
+
t4.blockStatement([
|
|
26243
|
+
snapshotDecl,
|
|
26244
|
+
earlyReturn,
|
|
26245
|
+
ensureCtxDecl,
|
|
26246
|
+
t4.tryStatement(
|
|
26247
|
+
t4.blockStatement([prepareCtx, pushCtx, hydrateCall]),
|
|
26248
|
+
null,
|
|
26249
|
+
t4.blockStatement([popCtx])
|
|
26250
|
+
)
|
|
26251
|
+
])
|
|
26252
|
+
)
|
|
26253
|
+
)
|
|
26254
|
+
]),
|
|
26255
|
+
[]
|
|
26256
|
+
);
|
|
26257
|
+
ctx.helpersUsed.add("registerResume");
|
|
26258
|
+
const registerCall = t4.expressionStatement(
|
|
26259
|
+
t4.callExpression(t4.identifier(RUNTIME_ALIASES.registerResume), [
|
|
26260
|
+
t4.stringLiteral(resumeExport),
|
|
26261
|
+
resumeFnId
|
|
26262
|
+
])
|
|
26263
|
+
);
|
|
26264
|
+
const metaId = t4.identifier(`__fict_meta_${componentName}`);
|
|
26265
|
+
const moduleUrlExpr = genModuleUrlExpr(ctx);
|
|
26266
|
+
const typeKeyExpr = t4.binaryExpression("+", t4.stringLiteral(`${componentName}@`), moduleUrlExpr);
|
|
26267
|
+
const resumeQrlExpr = t4.callExpression(t4.identifier(RUNTIME_ALIASES.qrl), [
|
|
26268
|
+
genModuleUrlExpr(ctx),
|
|
26269
|
+
t4.stringLiteral(resumeExport)
|
|
26270
|
+
]);
|
|
26271
|
+
const metaDecl = t4.variableDeclaration("const", [
|
|
26272
|
+
t4.variableDeclarator(
|
|
26273
|
+
metaId,
|
|
26274
|
+
t4.objectExpression([
|
|
26275
|
+
t4.objectProperty(t4.identifier("id"), typeKeyExpr),
|
|
26276
|
+
t4.objectProperty(t4.identifier("resume"), resumeQrlExpr)
|
|
26277
|
+
])
|
|
26278
|
+
)
|
|
26279
|
+
]);
|
|
26280
|
+
const assignMeta = t4.expressionStatement(
|
|
26281
|
+
t4.assignmentExpression(
|
|
26282
|
+
"=",
|
|
26283
|
+
t4.memberExpression(t4.identifier(componentName), t4.identifier("__fictMeta")),
|
|
26284
|
+
metaId
|
|
26285
|
+
)
|
|
26286
|
+
);
|
|
26287
|
+
ctx.hoistedResumableStatements.push(resumeFn, registerCall, metaDecl, assignMeta);
|
|
26288
|
+
ctx.resumableComponents.set(componentName, { resumeExport, typeKey: componentName });
|
|
26289
|
+
}
|
|
26290
|
+
function emitConditionalChild(startMarkerId, endMarkerId, expr, statements, ctx) {
|
|
25622
26291
|
const { t: t4 } = ctx;
|
|
25623
26292
|
ctx.helpersUsed.add("conditional");
|
|
25624
26293
|
ctx.helpersUsed.add("createElement");
|
|
@@ -25659,7 +26328,10 @@ function emitConditionalChild(parentId, markerId, expr, statements, ctx) {
|
|
|
25659
26328
|
];
|
|
25660
26329
|
if (alternate) {
|
|
25661
26330
|
args.push(t4.arrowFunctionExpression([], alternate));
|
|
26331
|
+
} else {
|
|
26332
|
+
args.push(t4.identifier("undefined"));
|
|
25662
26333
|
}
|
|
26334
|
+
args.push(startMarkerId, endMarkerId);
|
|
25663
26335
|
statements.push(
|
|
25664
26336
|
t4.variableDeclaration("const", [
|
|
25665
26337
|
t4.variableDeclarator(
|
|
@@ -25668,14 +26340,6 @@ function emitConditionalChild(parentId, markerId, expr, statements, ctx) {
|
|
|
25668
26340
|
)
|
|
25669
26341
|
])
|
|
25670
26342
|
);
|
|
25671
|
-
statements.push(
|
|
25672
|
-
t4.expressionStatement(
|
|
25673
|
-
t4.callExpression(t4.memberExpression(parentId, t4.identifier("insertBefore")), [
|
|
25674
|
-
t4.memberExpression(bindingId, t4.identifier("marker")),
|
|
25675
|
-
markerId
|
|
25676
|
-
])
|
|
25677
|
-
)
|
|
25678
|
-
);
|
|
25679
26343
|
statements.push(
|
|
25680
26344
|
t4.expressionStatement(
|
|
25681
26345
|
t4.optionalCallExpression(
|
|
@@ -26282,40 +26946,16 @@ function buildListCallExpression(expr, statements, ctx) {
|
|
|
26282
26946
|
}
|
|
26283
26947
|
return listCall;
|
|
26284
26948
|
}
|
|
26285
|
-
function emitListChild(
|
|
26949
|
+
function emitListChild(startMarkerId, endMarkerId, expr, statements, ctx) {
|
|
26286
26950
|
const { t: t4 } = ctx;
|
|
26287
26951
|
const listCall = buildListCallExpression(expr, statements, ctx);
|
|
26288
26952
|
if (!listCall) return;
|
|
26953
|
+
if (t4.isCallExpression(listCall)) {
|
|
26954
|
+
listCall.arguments.push(startMarkerId, endMarkerId);
|
|
26955
|
+
}
|
|
26289
26956
|
ctx.helpersUsed.add("onDestroy");
|
|
26290
|
-
ctx.helpersUsed.add("toNodeArray");
|
|
26291
26957
|
const listId = genTemp(ctx, "list");
|
|
26292
26958
|
statements.push(t4.variableDeclaration("const", [t4.variableDeclarator(listId, listCall)]));
|
|
26293
|
-
const markersId = genTemp(ctx, "markers");
|
|
26294
|
-
statements.push(
|
|
26295
|
-
t4.variableDeclaration("const", [
|
|
26296
|
-
t4.variableDeclarator(
|
|
26297
|
-
markersId,
|
|
26298
|
-
t4.callExpression(t4.identifier(RUNTIME_ALIASES.toNodeArray), [
|
|
26299
|
-
t4.memberExpression(listId, t4.identifier("marker"))
|
|
26300
|
-
])
|
|
26301
|
-
)
|
|
26302
|
-
])
|
|
26303
|
-
);
|
|
26304
|
-
const mId = genTemp(ctx, "m");
|
|
26305
|
-
statements.push(
|
|
26306
|
-
t4.forOfStatement(
|
|
26307
|
-
t4.variableDeclaration("const", [t4.variableDeclarator(mId)]),
|
|
26308
|
-
markersId,
|
|
26309
|
-
t4.blockStatement([
|
|
26310
|
-
t4.expressionStatement(
|
|
26311
|
-
t4.callExpression(t4.memberExpression(parentId, t4.identifier("insertBefore")), [
|
|
26312
|
-
mId,
|
|
26313
|
-
markerId
|
|
26314
|
-
])
|
|
26315
|
-
)
|
|
26316
|
-
])
|
|
26317
|
-
)
|
|
26318
|
-
);
|
|
26319
26959
|
statements.push(
|
|
26320
26960
|
t4.expressionStatement(
|
|
26321
26961
|
t4.optionalCallExpression(
|
|
@@ -26352,6 +26992,9 @@ function lowerHIRWithRegions(program, t4, options, macroAliases) {
|
|
|
26352
26992
|
program.functions.filter((fn) => !!fn.name).map((fn) => [fn.name, fn])
|
|
26353
26993
|
);
|
|
26354
26994
|
ctx.options = options;
|
|
26995
|
+
ctx.resumableEnabled = options?.resumable === true;
|
|
26996
|
+
ctx.autoExtractEnabled = options?.autoExtractHandlers ?? options?.resumable === true;
|
|
26997
|
+
ctx.autoExtractThreshold = options?.autoExtractThreshold ?? 3;
|
|
26355
26998
|
const body = [];
|
|
26356
26999
|
const topLevelAliases = /* @__PURE__ */ new Set();
|
|
26357
27000
|
let topLevelCtxInjected = false;
|
|
@@ -26598,6 +27241,9 @@ function lowerHIRWithRegions(program, t4, options, macroAliases) {
|
|
|
26598
27241
|
lowerableBuffer.push(stmt);
|
|
26599
27242
|
}
|
|
26600
27243
|
flushLowerableBuffer();
|
|
27244
|
+
if (ctx.resumableEnabled && ctx.hoistedResumableStatements && ctx.hoistedResumableStatements.length > 0) {
|
|
27245
|
+
body.push(...ctx.hoistedResumableStatements);
|
|
27246
|
+
}
|
|
26601
27247
|
for (const func of generatedFunctions.values()) {
|
|
26602
27248
|
body.push(func.stmt);
|
|
26603
27249
|
if (func.stmt.id?.name) emittedFunctionNames.add(func.stmt.id.name);
|
|
@@ -26638,12 +27284,15 @@ function lowerTopLevelStatementBlock(statements, ctx, t4, name = "__module_segme
|
|
|
26638
27284
|
ctx.storeVars = storeVars;
|
|
26639
27285
|
ctx.memoVars = memoVars;
|
|
26640
27286
|
ctx.mutatedVars = mutatedVars;
|
|
27287
|
+
const componentFunctionDefs = ctx.componentFunctionDefs ?? /* @__PURE__ */ new Map();
|
|
27288
|
+
ctx.componentFunctionDefs = componentFunctionDefs;
|
|
26641
27289
|
for (const block of fn.blocks) {
|
|
26642
27290
|
for (const instr of block.instructions) {
|
|
26643
27291
|
if (instr.kind === "Assign") {
|
|
26644
27292
|
const target = deSSAVarName(instr.target.name);
|
|
26645
27293
|
if (instr.value.kind === "ArrowFunction" || instr.value.kind === "FunctionExpression") {
|
|
26646
27294
|
functionVars.add(target);
|
|
27295
|
+
componentFunctionDefs.set(target, instr.value);
|
|
26647
27296
|
}
|
|
26648
27297
|
if (instr.value.kind === "CallExpression" || instr.value.kind === "OptionalCallExpression") {
|
|
26649
27298
|
const callKind = getReactiveCallKind(instr.value, ctx);
|
|
@@ -26811,6 +27460,8 @@ function lowerFunctionWithRegions(fn, ctx, options) {
|
|
|
26811
27460
|
ctx.mutatedVars = /* @__PURE__ */ new Set();
|
|
26812
27461
|
ctx.noMemo = !!(prevNoMemo || fn.meta?.noMemo);
|
|
26813
27462
|
ctx.hookResultVarMap = /* @__PURE__ */ new Map();
|
|
27463
|
+
const prevComponentFunctionDefs = ctx.componentFunctionDefs;
|
|
27464
|
+
ctx.componentFunctionDefs = /* @__PURE__ */ new Map();
|
|
26814
27465
|
const hookResultVars = /* @__PURE__ */ new Set();
|
|
26815
27466
|
const hookAccessorAliases = /* @__PURE__ */ new Set();
|
|
26816
27467
|
const prevPropsParam = ctx.propsParamName;
|
|
@@ -26827,6 +27478,7 @@ function lowerFunctionWithRegions(fn, ctx, options) {
|
|
|
26827
27478
|
const target = deSSAVarName(instr.target.name);
|
|
26828
27479
|
if (instr.value.kind === "ArrowFunction" || instr.value.kind === "FunctionExpression") {
|
|
26829
27480
|
ctx.functionVars?.add(target);
|
|
27481
|
+
ctx.componentFunctionDefs?.set(target, instr.value);
|
|
26830
27482
|
}
|
|
26831
27483
|
if (instr.value.kind === "CallExpression" || instr.value.kind === "OptionalCallExpression") {
|
|
26832
27484
|
const callKind = getReactiveCallKind(instr.value, ctx);
|
|
@@ -27122,6 +27774,7 @@ function lowerFunctionWithRegions(fn, ctx, options) {
|
|
|
27122
27774
|
ctx.externalTracked = prevExternalTracked;
|
|
27123
27775
|
ctx.signalVars = prevSignalVars;
|
|
27124
27776
|
ctx.functionVars = prevFunctionVars;
|
|
27777
|
+
ctx.componentFunctionDefs = prevComponentFunctionDefs;
|
|
27125
27778
|
ctx.memoVars = prevMemoVars;
|
|
27126
27779
|
ctx.storeVars = prevStoreVars;
|
|
27127
27780
|
ctx.mutatedVars = prevMutatedVars;
|
|
@@ -27139,6 +27792,7 @@ function lowerFunctionWithRegions(fn, ctx, options) {
|
|
|
27139
27792
|
ctx.externalTracked = prevExternalTracked;
|
|
27140
27793
|
ctx.signalVars = prevSignalVars;
|
|
27141
27794
|
ctx.functionVars = prevFunctionVars;
|
|
27795
|
+
ctx.componentFunctionDefs = prevComponentFunctionDefs;
|
|
27142
27796
|
ctx.memoVars = prevMemoVars;
|
|
27143
27797
|
ctx.storeVars = prevStoreVars;
|
|
27144
27798
|
ctx.mutatedVars = prevMutatedVars;
|
|
@@ -27235,6 +27889,9 @@ function lowerFunctionWithRegions(fn, ctx, options) {
|
|
|
27235
27889
|
fn.loc
|
|
27236
27890
|
);
|
|
27237
27891
|
funcDecl.async = isAsync;
|
|
27892
|
+
if (isComponent && fn.name) {
|
|
27893
|
+
registerResumableComponent(fn.name, ctx);
|
|
27894
|
+
}
|
|
27238
27895
|
ctx.needsCtx = prevNeedsCtx;
|
|
27239
27896
|
ctx.shadowedNames = prevShadowed;
|
|
27240
27897
|
ctx.localDeclaredNames = prevLocalDeclared;
|
|
@@ -27242,6 +27899,7 @@ function lowerFunctionWithRegions(fn, ctx, options) {
|
|
|
27242
27899
|
ctx.externalTracked = prevExternalTracked;
|
|
27243
27900
|
ctx.signalVars = prevSignalVars;
|
|
27244
27901
|
ctx.functionVars = prevFunctionVars;
|
|
27902
|
+
ctx.componentFunctionDefs = prevComponentFunctionDefs;
|
|
27245
27903
|
ctx.memoVars = prevMemoVars;
|
|
27246
27904
|
ctx.storeVars = prevStoreVars;
|
|
27247
27905
|
ctx.mutatedVars = prevMutatedVars;
|