svelte-effect-runtime 1.0.4 → 1.1.1
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/chunks/{magic-string.es-dQ3Qnajt.js → magic-string.es-5gRBdMgP.js} +1 -1
- package/dist/chunks/{magic-string.es-dQ3Qnajt.js.map → magic-string.es-5gRBdMgP.js.map} +1 -1
- package/dist/chunks/markup-CNqU2j9U.js +13349 -0
- package/dist/chunks/markup-CNqU2j9U.js.map +1 -0
- package/dist/internal/markup.js +1 -696
- package/dist/internal/transform.js +1 -1
- package/dist/language-server.js +1 -1
- package/dist/mod.js +1 -1
- package/dist/preprocess.js +1 -1
- package/dist/root-node.js +1 -1
- package/package.json +1 -1
- package/dist/internal/markup.js.map +0 -1
package/dist/internal/markup.js
CHANGED
|
@@ -1,697 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
import { parse } from "svelte/compiler";
|
|
3
|
-
import ts from "typescript";
|
|
4
|
-
//#region internal/markup.ts
|
|
5
|
-
const DEFAULT_RUNTIME_MODULE_ID = "svelte-effect-runtime";
|
|
6
|
-
const DEFAULT_EFFECT_MODULE_ID = "effect";
|
|
7
|
-
const DEFAULT_SVELTE_MODULE_ID = "svelte";
|
|
8
|
-
const MARKUP_HELPER_PREFIX = "__svelteEffectRuntimeMarkup";
|
|
9
|
-
function transformEffectMarkup(content, options) {
|
|
10
|
-
const sanitized = sanitizeEffectMarkup(content, options.filename);
|
|
11
|
-
if (sanitized.candidates.length === 0) return {
|
|
12
|
-
code: content,
|
|
13
|
-
map: new MagicString(content).generateMap({
|
|
14
|
-
hires: true,
|
|
15
|
-
includeContent: true,
|
|
16
|
-
source: options.filename
|
|
17
|
-
})
|
|
18
|
-
};
|
|
19
|
-
const replacements = collectMarkupReplacements(create_parse_safe_markup_source(sanitized.code), sanitized.candidates, options.filename);
|
|
20
|
-
const magicString = new MagicString(content);
|
|
21
|
-
for (const replacement of replacements) magicString.overwrite(replacement.start, replacement.end, replacement.text);
|
|
22
|
-
injectMarkupHelpers(magicString, content, options);
|
|
23
|
-
return {
|
|
24
|
-
code: magicString.toString(),
|
|
25
|
-
map: magicString.generateMap({
|
|
26
|
-
hires: true,
|
|
27
|
-
includeContent: true,
|
|
28
|
-
source: options.filename
|
|
29
|
-
})
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
function create_parse_safe_markup_source(content) {
|
|
33
|
-
const excluded_ranges = findExcludedRanges(content);
|
|
34
|
-
if (excluded_ranges.length === 0) return content;
|
|
35
|
-
let result = "";
|
|
36
|
-
let cursor = 0;
|
|
37
|
-
for (const range of excluded_ranges) {
|
|
38
|
-
result += content.slice(cursor, range.start);
|
|
39
|
-
result += mask_excluded_text(content.slice(range.start, range.end));
|
|
40
|
-
cursor = range.end;
|
|
41
|
-
}
|
|
42
|
-
result += content.slice(cursor);
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
function mask_excluded_text(text) {
|
|
46
|
-
let result = "";
|
|
47
|
-
for (const character of text) result += character === "\n" || character === "\r" ? character : " ";
|
|
48
|
-
return result;
|
|
49
|
-
}
|
|
50
|
-
function sanitizeEffectMarkup(content, filename) {
|
|
51
|
-
const excludedRanges = findExcludedRanges(content);
|
|
52
|
-
const candidates = [];
|
|
53
|
-
const magicString = new MagicString(content);
|
|
54
|
-
let helperIndex = 0;
|
|
55
|
-
for (let index = 0; index < content.length; index += 1) {
|
|
56
|
-
if (content[index] !== "{") continue;
|
|
57
|
-
const range = findExcludedRangeAt(excludedRanges, index);
|
|
58
|
-
if (range) {
|
|
59
|
-
index = range.end - 1;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
const closingIndex = findClosingBrace(content, index + 1);
|
|
63
|
-
if (closingIndex === -1) continue;
|
|
64
|
-
const inner = content.slice(index + 1, closingIndex);
|
|
65
|
-
const candidate = getCandidateForBraceTag(index, closingIndex, inner, filename, helperIndex);
|
|
66
|
-
if (candidate) {
|
|
67
|
-
helperIndex += 1;
|
|
68
|
-
candidates.push(candidate);
|
|
69
|
-
magicString.overwrite(candidate.start, candidate.end, candidate.placeholder);
|
|
70
|
-
}
|
|
71
|
-
index = closingIndex;
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
code: magicString.toString(),
|
|
75
|
-
candidates
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
function collectMarkupReplacements(sanitizedContent, candidates, filename) {
|
|
79
|
-
const ast = parse(sanitizedContent, {
|
|
80
|
-
filename,
|
|
81
|
-
modern: true
|
|
82
|
-
});
|
|
83
|
-
const candidatesByPlaceholder = new Map(candidates.map((candidate) => [candidate.placeholder, candidate]));
|
|
84
|
-
const replacements = [];
|
|
85
|
-
const matchedPlaceholders = /* @__PURE__ */ new Set();
|
|
86
|
-
visitFragment(ast.fragment, candidatesByPlaceholder, matchedPlaceholders, (candidate, kind) => {
|
|
87
|
-
replacements.push(makeAstReplacement(candidate, kind, filename));
|
|
88
|
-
});
|
|
89
|
-
const unmatched = candidates.filter((candidate) => !matchedPlaceholders.has(candidate.placeholder));
|
|
90
|
-
if (unmatched.length > 0) throw new Error(`${filename}: failed to classify some markup Effect expressions.\n` + unmatched.map((candidate) => `Problematic expression:\n${candidate.expressionText}`).join("\n\n"));
|
|
91
|
-
return replacements.sort((left, right) => left.start - right.start);
|
|
92
|
-
}
|
|
93
|
-
function getCandidateForBraceTag(openBraceIndex, closeBraceIndex, inner, filename, helperIndex) {
|
|
94
|
-
const trimmed = inner.trimStart();
|
|
95
|
-
const leadingWhitespaceLength = inner.length - trimmed.length;
|
|
96
|
-
if (!containsYieldStarText(trimmed)) return;
|
|
97
|
-
if (trimmed.startsWith("@const ")) {
|
|
98
|
-
const initializerRange = findConstInitializerRange(trimmed.slice(7), filename);
|
|
99
|
-
return initializerRange ? makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 7 + initializerRange.start, openBraceIndex + 1 + leadingWhitespaceLength + 7 + initializerRange.end, trimmed.slice(7 + initializerRange.start, 7 + initializerRange.end), helperIndex) : void 0;
|
|
100
|
-
}
|
|
101
|
-
if (trimmed.startsWith("#if ")) return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 4, closeBraceIndex, trimmed.slice(4), helperIndex);
|
|
102
|
-
if (trimmed.startsWith(":else if ")) return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 9, closeBraceIndex, trimmed.slice(9), helperIndex);
|
|
103
|
-
if (trimmed.startsWith("#each ")) {
|
|
104
|
-
const eachHeader = trimmed.slice(6);
|
|
105
|
-
const asIndex = findTopLevelKeyword(eachHeader, " as ");
|
|
106
|
-
if (asIndex === -1) return;
|
|
107
|
-
const listExpression = eachHeader.slice(0, asIndex);
|
|
108
|
-
return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 6, openBraceIndex + 1 + leadingWhitespaceLength + 6 + listExpression.length, listExpression, helperIndex);
|
|
109
|
-
}
|
|
110
|
-
if (trimmed.startsWith("#await ")) {
|
|
111
|
-
const awaitHeader = trimmed.slice(7);
|
|
112
|
-
const boundary = findAwaitBoundary(awaitHeader);
|
|
113
|
-
const expressionText = boundary === -1 ? awaitHeader : awaitHeader.slice(0, boundary);
|
|
114
|
-
return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 7, openBraceIndex + 1 + leadingWhitespaceLength + 7 + expressionText.length, expressionText, helperIndex);
|
|
115
|
-
}
|
|
116
|
-
if (trimmed.startsWith("@html ")) return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 6, closeBraceIndex, trimmed.slice(6), helperIndex);
|
|
117
|
-
if (trimmed.startsWith("@render ")) throw new Error(`${filename}: {@render ...} cannot depend on yield* in markup right now.\nMove the Effect code into <script effect> or a helper function instead.\n\nProblematic tag:\n{${inner}}`);
|
|
118
|
-
if (trimmed.startsWith("@attach ")) return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 8, closeBraceIndex, trimmed.slice(8), helperIndex);
|
|
119
|
-
if (trimmed.startsWith("#key ")) return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 5, closeBraceIndex, trimmed.slice(5), helperIndex);
|
|
120
|
-
if (trimmed.startsWith("/") || trimmed.startsWith(":then") || trimmed.startsWith(":catch") || trimmed === ":else") return;
|
|
121
|
-
if (trimmed.startsWith("...")) return makeMarkupCandidate(openBraceIndex + 1 + leadingWhitespaceLength + 3, closeBraceIndex, trimmed.slice(3), helperIndex);
|
|
122
|
-
return makeMarkupCandidate(openBraceIndex + 1, closeBraceIndex, inner, helperIndex);
|
|
123
|
-
}
|
|
124
|
-
function makeMarkupCandidate(start, end, expressionText, helperIndex) {
|
|
125
|
-
return {
|
|
126
|
-
expressionText,
|
|
127
|
-
placeholder: `${MARKUP_HELPER_PREFIX}Placeholder${helperIndex}`,
|
|
128
|
-
start,
|
|
129
|
-
end
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
function makeAstReplacement(candidate, kind, filename) {
|
|
133
|
-
if (kind === "event") return {
|
|
134
|
-
start: candidate.start,
|
|
135
|
-
end: candidate.end,
|
|
136
|
-
text: transformEventExpression(candidate.expressionText.trim(), filename)
|
|
137
|
-
};
|
|
138
|
-
const helperId = `${MARKUP_HELPER_PREFIX}${candidate.placeholder}`;
|
|
139
|
-
const deps = collectFreeIdentifiers(candidate.expressionText, filename);
|
|
140
|
-
const depsText = deps.length === 0 ? "[]" : `[${deps.join(", ")}]`;
|
|
141
|
-
const trimmedExpression = candidate.expressionText.trim();
|
|
142
|
-
const replacementText = kind === "await" ? `${MARKUP_HELPER_PREFIX}Promise("${helperId}", ${depsText}, function* () { return (${trimmedExpression}); })` : `${MARKUP_HELPER_PREFIX}Value("${helperId}", ${depsText}, function* () { return (${trimmedExpression}); }, ${kind === "each" ? "[]" : "undefined"})`;
|
|
143
|
-
return {
|
|
144
|
-
start: candidate.start,
|
|
145
|
-
end: candidate.end,
|
|
146
|
-
text: replacementText
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
function visitFragment(fragment, candidatesByPlaceholder, matchedPlaceholders, onReplacement) {
|
|
150
|
-
for (const node of fragment.nodes) visitNode(node, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
151
|
-
}
|
|
152
|
-
function visitNode(node, candidatesByPlaceholder, matchedPlaceholders, onReplacement) {
|
|
153
|
-
switch (node.type) {
|
|
154
|
-
case "ExpressionTag":
|
|
155
|
-
case "HtmlTag":
|
|
156
|
-
case "AttachTag":
|
|
157
|
-
emitReplacementForExpression(node.expression, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
158
|
-
return;
|
|
159
|
-
case "ConstTag":
|
|
160
|
-
emitReplacementForExpression(node.declaration.declarations[0]?.init, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
161
|
-
return;
|
|
162
|
-
case "IfBlock":
|
|
163
|
-
emitReplacementForExpression(node.test, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
164
|
-
visitFragment(node.consequent, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
165
|
-
if (node.alternate) visitFragment(node.alternate, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
166
|
-
return;
|
|
167
|
-
case "EachBlock":
|
|
168
|
-
emitReplacementForExpression(node.expression, "each", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
169
|
-
visitFragment(node.body, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
170
|
-
if (node.fallback) visitFragment(node.fallback, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
171
|
-
return;
|
|
172
|
-
case "AwaitBlock":
|
|
173
|
-
emitReplacementForExpression(node.expression, "await", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
174
|
-
if (node.pending) visitFragment(node.pending, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
175
|
-
if (node.then) visitFragment(node.then, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
176
|
-
if (node.catch) visitFragment(node.catch, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
177
|
-
return;
|
|
178
|
-
case "KeyBlock":
|
|
179
|
-
emitReplacementForExpression(node.expression, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
180
|
-
visitFragment(node.fragment, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
181
|
-
return;
|
|
182
|
-
case "RegularElement":
|
|
183
|
-
case "Component":
|
|
184
|
-
case "TitleElement":
|
|
185
|
-
case "SlotElement":
|
|
186
|
-
case "SvelteBody":
|
|
187
|
-
case "SvelteBoundary":
|
|
188
|
-
case "SvelteComponent":
|
|
189
|
-
case "SvelteDocument":
|
|
190
|
-
case "SvelteElement":
|
|
191
|
-
case "SvelteFragment":
|
|
192
|
-
case "SvelteHead":
|
|
193
|
-
case "SvelteSelf":
|
|
194
|
-
case "SvelteWindow":
|
|
195
|
-
for (const attribute of node.attributes) visitAttribute(attribute, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
196
|
-
visitFragment(node.fragment, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
197
|
-
return;
|
|
198
|
-
default: return;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
function visitAttribute(attribute, candidatesByPlaceholder, matchedPlaceholders, onReplacement) {
|
|
202
|
-
switch (attribute.type) {
|
|
203
|
-
case "Attribute": {
|
|
204
|
-
const kind = isEventAttribute(attribute.name) ? "event" : "plain";
|
|
205
|
-
visitAttributeValue(attribute.value, kind, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
case "OnDirective":
|
|
209
|
-
emitReplacementForExpression(attribute.expression, "event", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
210
|
-
return;
|
|
211
|
-
case "SpreadAttribute":
|
|
212
|
-
case "AnimateDirective":
|
|
213
|
-
case "BindDirective":
|
|
214
|
-
case "ClassDirective":
|
|
215
|
-
case "TransitionDirective":
|
|
216
|
-
case "UseDirective":
|
|
217
|
-
emitReplacementForExpression(attribute.expression, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
218
|
-
return;
|
|
219
|
-
case "StyleDirective":
|
|
220
|
-
visitAttributeValue(attribute.value, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
221
|
-
return;
|
|
222
|
-
case "LetDirective":
|
|
223
|
-
emitReplacementForExpression(attribute.expression, "plain", candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
224
|
-
return;
|
|
225
|
-
default: return;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
function visitAttributeValue(value, kind, candidatesByPlaceholder, matchedPlaceholders, onReplacement) {
|
|
229
|
-
if (value === true) return;
|
|
230
|
-
if (Array.isArray(value)) {
|
|
231
|
-
for (const part of value) if (part.type === "ExpressionTag") emitReplacementForExpression(part.expression, kind, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
emitReplacementForExpression(value.expression, kind, candidatesByPlaceholder, matchedPlaceholders, onReplacement);
|
|
235
|
-
}
|
|
236
|
-
function emitReplacementForExpression(expression, kind, candidatesByPlaceholder, matchedPlaceholders, onReplacement) {
|
|
237
|
-
if (!expression || expression.type !== "Identifier" || !expression.name) return;
|
|
238
|
-
const candidate = candidatesByPlaceholder.get(expression.name);
|
|
239
|
-
if (!candidate || matchedPlaceholders.has(candidate.placeholder)) return;
|
|
240
|
-
matchedPlaceholders.add(candidate.placeholder);
|
|
241
|
-
onReplacement(candidate, kind);
|
|
242
|
-
}
|
|
243
|
-
function findConstInitializerRange(declarationText, filename) {
|
|
244
|
-
const sourceFile = ts.createSourceFile(filename, `const ${declarationText};`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
245
|
-
const statement = sourceFile.statements[0];
|
|
246
|
-
if (!statement || !ts.isVariableStatement(statement)) return;
|
|
247
|
-
const declaration = statement.declarationList.declarations[0];
|
|
248
|
-
if (!declaration?.initializer) return;
|
|
249
|
-
return {
|
|
250
|
-
start: declaration.initializer.getStart(sourceFile) - 6,
|
|
251
|
-
end: declaration.initializer.end - 6
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function transformEventExpression(expressionText, filename) {
|
|
255
|
-
const wrapped = parseWrappedExpression(expressionText, filename);
|
|
256
|
-
const expression = unwrapParentheses(wrapped.expression);
|
|
257
|
-
if (ts.isArrowFunction(expression)) {
|
|
258
|
-
const signatureText = sliceWrappedNode(expressionText, wrapped, expression.getStart(wrapped.sourceFile), expression.equalsGreaterThanToken.end);
|
|
259
|
-
if (ts.isBlock(expression.body)) return `${signatureText} ${makeInlineEventBlock(sliceWrappedNode(expressionText, wrapped, expression.body.getStart(wrapped.sourceFile) + 1, expression.body.end - 1))}`;
|
|
260
|
-
return `${signatureText} ${makeInlineEventExpressionBody(sliceWrappedNode(expressionText, wrapped, expression.body.getStart(wrapped.sourceFile), expression.body.end))}`;
|
|
261
|
-
}
|
|
262
|
-
if (ts.isFunctionExpression(expression)) return `${sliceWrappedNode(expressionText, wrapped, expression.getStart(wrapped.sourceFile), expression.body.getStart(wrapped.sourceFile))}${makeInlineEventBlock(sliceWrappedNode(expressionText, wrapped, expression.body.getStart(wrapped.sourceFile) + 1, expression.body.end - 1))}`;
|
|
263
|
-
return `() => ${makeInlineEventExpressionBody(expressionText)}`;
|
|
264
|
-
}
|
|
265
|
-
function makeInlineEventBlock(bodyText) {
|
|
266
|
-
const normalizedBody = bodyText.trim();
|
|
267
|
-
if (normalizedBody.length === 0) return `{ void ${MARKUP_HELPER_PREFIX}Run(function* () {}); }`;
|
|
268
|
-
return [
|
|
269
|
-
"{",
|
|
270
|
-
` void ${MARKUP_HELPER_PREFIX}Run(function* () {`,
|
|
271
|
-
indentBlock(normalizedBody, " "),
|
|
272
|
-
" });",
|
|
273
|
-
"}"
|
|
274
|
-
].join("\n");
|
|
275
|
-
}
|
|
276
|
-
function makeInlineEventExpressionBody(expressionText) {
|
|
277
|
-
return [
|
|
278
|
-
"{",
|
|
279
|
-
` void ${MARKUP_HELPER_PREFIX}Run(function* () {`,
|
|
280
|
-
` return (${expressionText.trim()});`,
|
|
281
|
-
" });",
|
|
282
|
-
"}"
|
|
283
|
-
].join("\n");
|
|
284
|
-
}
|
|
285
|
-
function parseWrappedExpression(expressionText, filename) {
|
|
286
|
-
const sourceFile = ts.createSourceFile(filename, `function* __svelteEffectRuntimeMarkupWrapper(){ return (${expressionText}); }`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
287
|
-
const functionDeclaration = sourceFile.statements[0];
|
|
288
|
-
if (!functionDeclaration || !ts.isFunctionDeclaration(functionDeclaration) || !functionDeclaration.body) throw new Error(`${filename}: could not parse markup Effect expression:\n${expressionText}`);
|
|
289
|
-
const returnStatement = functionDeclaration.body.statements[0];
|
|
290
|
-
if (!returnStatement || !ts.isReturnStatement(returnStatement) || !returnStatement.expression) throw new Error(`${filename}: could not locate markup Effect expression:\n${expressionText}`);
|
|
291
|
-
return {
|
|
292
|
-
expression: returnStatement.expression,
|
|
293
|
-
offset: 56,
|
|
294
|
-
sourceFile
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
function unwrapParentheses(expression) {
|
|
298
|
-
let current = expression;
|
|
299
|
-
while (ts.isParenthesizedExpression(current)) current = current.expression;
|
|
300
|
-
return current;
|
|
301
|
-
}
|
|
302
|
-
function sliceWrappedNode(expressionText, wrapped, start, end) {
|
|
303
|
-
return expressionText.slice(start - wrapped.offset, end - wrapped.offset);
|
|
304
|
-
}
|
|
305
|
-
function collectFreeIdentifiers(expressionText, filename) {
|
|
306
|
-
const wrapped = parseWrappedExpression(expressionText, filename);
|
|
307
|
-
const identifiers = [];
|
|
308
|
-
const seen = /* @__PURE__ */ new Set();
|
|
309
|
-
const scopes = [/* @__PURE__ */ new Set()];
|
|
310
|
-
function isDeclaredLocally(identifier) {
|
|
311
|
-
return scopes.some((scope) => scope.has(identifier));
|
|
312
|
-
}
|
|
313
|
-
function visit(node) {
|
|
314
|
-
if (ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isFunctionDeclaration(node)) {
|
|
315
|
-
if (!node.body) return;
|
|
316
|
-
const nextScope = /* @__PURE__ */ new Set();
|
|
317
|
-
if (node.name) nextScope.add(node.name.text);
|
|
318
|
-
for (const parameter of node.parameters) declareInto(nextScope, parameter.name);
|
|
319
|
-
scopes.unshift(nextScope);
|
|
320
|
-
if (ts.isBlock(node.body)) for (const statement of node.body.statements) statement.forEachChild(visit);
|
|
321
|
-
else node.body.forEachChild(visit);
|
|
322
|
-
scopes.shift();
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
if (ts.isIdentifier(node)) {
|
|
326
|
-
if (node.text === "yield" || node.text === "undefined") return;
|
|
327
|
-
if (shouldSkipIdentifier(node)) return;
|
|
328
|
-
if (!isDeclaredLocally(node.text) && !seen.has(node.text)) {
|
|
329
|
-
seen.add(node.text);
|
|
330
|
-
identifiers.push(node.text);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
if (ts.isVariableDeclaration(node)) {
|
|
334
|
-
if (node.initializer) node.initializer.forEachChild(visit);
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
node.forEachChild(visit);
|
|
338
|
-
}
|
|
339
|
-
function declareInto(scope, name) {
|
|
340
|
-
if (ts.isIdentifier(name)) {
|
|
341
|
-
scope.add(name.text);
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
for (const element of name.elements) {
|
|
345
|
-
if (ts.isOmittedExpression(element)) continue;
|
|
346
|
-
declareInto(scope, element.name);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
visit(unwrapParentheses(wrapped.expression));
|
|
350
|
-
return identifiers;
|
|
351
|
-
}
|
|
352
|
-
function shouldSkipIdentifier(node) {
|
|
353
|
-
const parent = node.parent;
|
|
354
|
-
return ts.isPropertyAccessExpression(parent) && parent.name === node || ts.isPropertyAssignment(parent) && parent.name === node || ts.isShorthandPropertyAssignment(parent) && parent.objectAssignmentInitializer === node || ts.isBindingElement(parent) && parent.propertyName === node || ts.isImportSpecifier(parent) || ts.isExportSpecifier(parent) || ts.isLabeledStatement(parent) && parent.label === node;
|
|
355
|
-
}
|
|
356
|
-
function containsYieldStarText(text) {
|
|
357
|
-
return /\byield\s*\*/.test(text);
|
|
358
|
-
}
|
|
359
|
-
function findExcludedRanges(content) {
|
|
360
|
-
const ranges = [];
|
|
361
|
-
for (const pattern of [
|
|
362
|
-
/<script\b[\s\S]*?<\/script\s*>/gi,
|
|
363
|
-
/<style\b[\s\S]*?<\/style\s*>/gi,
|
|
364
|
-
/<!--[\s\S]*?-->/g
|
|
365
|
-
]) for (const match of content.matchAll(pattern)) {
|
|
366
|
-
if (match.index === void 0) continue;
|
|
367
|
-
ranges.push({
|
|
368
|
-
start: match.index,
|
|
369
|
-
end: match.index + match[0].length
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
return ranges.sort((left, right) => left.start - right.start);
|
|
373
|
-
}
|
|
374
|
-
function findExcludedRangeAt(ranges, index) {
|
|
375
|
-
return ranges.find((range) => range.start <= index && index < range.end);
|
|
376
|
-
}
|
|
377
|
-
function findClosingBrace(content, start) {
|
|
378
|
-
let braceDepth = 0;
|
|
379
|
-
let bracketDepth = 0;
|
|
380
|
-
let parenDepth = 0;
|
|
381
|
-
let quote;
|
|
382
|
-
let templateBraceDepth = 0;
|
|
383
|
-
for (let index = start; index < content.length; index += 1) {
|
|
384
|
-
const character = content[index];
|
|
385
|
-
const nextCharacter = content[index + 1];
|
|
386
|
-
if (quote === "'") {
|
|
387
|
-
if (character === "\\" && nextCharacter) {
|
|
388
|
-
index += 1;
|
|
389
|
-
continue;
|
|
390
|
-
}
|
|
391
|
-
if (character === "'") quote = void 0;
|
|
392
|
-
continue;
|
|
393
|
-
}
|
|
394
|
-
if (quote === "\"") {
|
|
395
|
-
if (character === "\\" && nextCharacter) {
|
|
396
|
-
index += 1;
|
|
397
|
-
continue;
|
|
398
|
-
}
|
|
399
|
-
if (character === "\"") quote = void 0;
|
|
400
|
-
continue;
|
|
401
|
-
}
|
|
402
|
-
if (quote === "`") {
|
|
403
|
-
if (character === "\\" && nextCharacter) {
|
|
404
|
-
index += 1;
|
|
405
|
-
continue;
|
|
406
|
-
}
|
|
407
|
-
if (character === "$" && nextCharacter === "{") {
|
|
408
|
-
templateBraceDepth += 1;
|
|
409
|
-
braceDepth += 1;
|
|
410
|
-
index += 1;
|
|
411
|
-
continue;
|
|
412
|
-
}
|
|
413
|
-
if (character === "}" && templateBraceDepth > 0) {
|
|
414
|
-
templateBraceDepth -= 1;
|
|
415
|
-
braceDepth -= 1;
|
|
416
|
-
continue;
|
|
417
|
-
}
|
|
418
|
-
if (character === "`" && templateBraceDepth === 0) quote = void 0;
|
|
419
|
-
continue;
|
|
420
|
-
}
|
|
421
|
-
if (character === "'" || character === "\"" || character === "`") {
|
|
422
|
-
quote = character;
|
|
423
|
-
continue;
|
|
424
|
-
}
|
|
425
|
-
if (character === "/" && nextCharacter === "/") {
|
|
426
|
-
index += 2;
|
|
427
|
-
while (index < content.length && content[index] !== "\n") index += 1;
|
|
428
|
-
continue;
|
|
429
|
-
}
|
|
430
|
-
if (character === "/" && nextCharacter === "*") {
|
|
431
|
-
index += 2;
|
|
432
|
-
while (index < content.length && !(content[index] === "*" && content[index + 1] === "/")) index += 1;
|
|
433
|
-
index += 1;
|
|
434
|
-
continue;
|
|
435
|
-
}
|
|
436
|
-
if (character === "(") {
|
|
437
|
-
parenDepth += 1;
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
if (character === ")") {
|
|
441
|
-
parenDepth -= 1;
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
if (character === "[") {
|
|
445
|
-
bracketDepth += 1;
|
|
446
|
-
continue;
|
|
447
|
-
}
|
|
448
|
-
if (character === "]") {
|
|
449
|
-
bracketDepth -= 1;
|
|
450
|
-
continue;
|
|
451
|
-
}
|
|
452
|
-
if (character === "{") {
|
|
453
|
-
braceDepth += 1;
|
|
454
|
-
continue;
|
|
455
|
-
}
|
|
456
|
-
if (character === "}") {
|
|
457
|
-
if (braceDepth === 0 && parenDepth === 0 && bracketDepth === 0) return index;
|
|
458
|
-
braceDepth -= 1;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return -1;
|
|
462
|
-
}
|
|
463
|
-
function findTopLevelKeyword(text, keyword) {
|
|
464
|
-
let braceDepth = 0;
|
|
465
|
-
let bracketDepth = 0;
|
|
466
|
-
let parenDepth = 0;
|
|
467
|
-
let quote;
|
|
468
|
-
for (let index = 0; index <= text.length - keyword.length; index += 1) {
|
|
469
|
-
const character = text[index];
|
|
470
|
-
const nextCharacter = text[index + 1];
|
|
471
|
-
if (quote) {
|
|
472
|
-
if (character === "\\" && nextCharacter) {
|
|
473
|
-
index += 1;
|
|
474
|
-
continue;
|
|
475
|
-
}
|
|
476
|
-
if (character === quote) quote = void 0;
|
|
477
|
-
continue;
|
|
478
|
-
}
|
|
479
|
-
if (character === "'" || character === "\"" || character === "`") {
|
|
480
|
-
quote = character;
|
|
481
|
-
continue;
|
|
482
|
-
}
|
|
483
|
-
if (character === "(") {
|
|
484
|
-
parenDepth += 1;
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
if (character === ")") {
|
|
488
|
-
parenDepth -= 1;
|
|
489
|
-
continue;
|
|
490
|
-
}
|
|
491
|
-
if (character === "[") {
|
|
492
|
-
bracketDepth += 1;
|
|
493
|
-
continue;
|
|
494
|
-
}
|
|
495
|
-
if (character === "]") {
|
|
496
|
-
bracketDepth -= 1;
|
|
497
|
-
continue;
|
|
498
|
-
}
|
|
499
|
-
if (character === "{") {
|
|
500
|
-
braceDepth += 1;
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
if (character === "}") {
|
|
504
|
-
braceDepth -= 1;
|
|
505
|
-
continue;
|
|
506
|
-
}
|
|
507
|
-
if (braceDepth === 0 && bracketDepth === 0 && parenDepth === 0 && text.startsWith(keyword, index)) return index;
|
|
508
|
-
}
|
|
509
|
-
return -1;
|
|
510
|
-
}
|
|
511
|
-
function findAwaitBoundary(text) {
|
|
512
|
-
const thenIndex = findTopLevelKeyword(text, " then ");
|
|
513
|
-
const catchIndex = findTopLevelKeyword(text, " catch ");
|
|
514
|
-
if (thenIndex === -1) return catchIndex;
|
|
515
|
-
if (catchIndex === -1) return thenIndex;
|
|
516
|
-
return Math.min(thenIndex, catchIndex);
|
|
517
|
-
}
|
|
518
|
-
function isEventAttribute(name) {
|
|
519
|
-
return name.startsWith("on:") || /^on[a-z]/.test(name);
|
|
520
|
-
}
|
|
521
|
-
function injectMarkupHelpers(magicString, content, options) {
|
|
522
|
-
const helperBlock = makeMarkupHelperBlock(options);
|
|
523
|
-
const scriptTagMatch = findInstanceScriptTag(content);
|
|
524
|
-
if (!scriptTagMatch) {
|
|
525
|
-
magicString.prepend(`<script>\n${helperBlock}\n<\/script>\n\n`);
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
magicString.appendLeft(scriptTagMatch.end, `\n${helperBlock}\n`);
|
|
529
|
-
}
|
|
530
|
-
function findInstanceScriptTag(content) {
|
|
531
|
-
for (const match of content.matchAll(/<script\b([^>]*)>([\s\S]*?)<\/script\s*>/gi)) {
|
|
532
|
-
if (match.index === void 0) continue;
|
|
533
|
-
const attributes = match[1] ?? "";
|
|
534
|
-
if (/\bcontext\s*=\s*["']module["']/.test(attributes) || /\bmodule\b/.test(attributes)) continue;
|
|
535
|
-
const openTag = match[0].indexOf(">") + 1;
|
|
536
|
-
return {
|
|
537
|
-
start: match.index + openTag,
|
|
538
|
-
end: match.index + match[0].length - 9
|
|
539
|
-
};
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
function makeMarkupHelperBlock(options) {
|
|
543
|
-
const runtimeModuleId = options.runtimeModuleId ?? DEFAULT_RUNTIME_MODULE_ID;
|
|
544
|
-
const effectModuleId = options.effectModuleId ?? DEFAULT_EFFECT_MODULE_ID;
|
|
545
|
-
const svelteModuleId = options.svelteModuleId ?? DEFAULT_SVELTE_MODULE_ID;
|
|
546
|
-
return [
|
|
547
|
-
`import { Effect as ${MARKUP_HELPER_PREFIX}Effect } from "${effectModuleId}";`,
|
|
548
|
-
`import { onDestroy as ${MARKUP_HELPER_PREFIX}OnDestroy } from "${svelteModuleId}";`,
|
|
549
|
-
`import { getEffectRuntimeOrThrow as ${MARKUP_HELPER_PREFIX}GetRuntime, registerHotDispose as ${MARKUP_HELPER_PREFIX}RegisterHotDispose, runComponentEffect as ${MARKUP_HELPER_PREFIX}RunComponentEffect, runInlineEffect as ${MARKUP_HELPER_PREFIX}RunInlineEffect } from "${runtimeModuleId}";`,
|
|
550
|
-
"",
|
|
551
|
-
`const ${MARKUP_HELPER_PREFIX}Values = Object.create(null);`,
|
|
552
|
-
`const ${MARKUP_HELPER_PREFIX}Promises = Object.create(null);`,
|
|
553
|
-
`const ${MARKUP_HELPER_PREFIX}Cleanups = new Map();`,
|
|
554
|
-
`const ${MARKUP_HELPER_PREFIX}ObjectIds = new WeakMap();`,
|
|
555
|
-
`const ${MARKUP_HELPER_PREFIX}PendingStarts = new Set();`,
|
|
556
|
-
`const ${MARKUP_HELPER_PREFIX}Runtime = typeof window === "undefined" ? undefined : ${MARKUP_HELPER_PREFIX}GetRuntime();`,
|
|
557
|
-
`let ${MARKUP_HELPER_PREFIX}Version = $state(0);`,
|
|
558
|
-
`let ${MARKUP_HELPER_PREFIX}NextObjectId = 1;`,
|
|
559
|
-
"",
|
|
560
|
-
`function ${MARKUP_HELPER_PREFIX}Hash(value) {`,
|
|
561
|
-
` if (value === null) {`,
|
|
562
|
-
` return "null";`,
|
|
563
|
-
" }",
|
|
564
|
-
"",
|
|
565
|
-
` if (value === undefined) {`,
|
|
566
|
-
` return "undefined";`,
|
|
567
|
-
" }",
|
|
568
|
-
"",
|
|
569
|
-
` const type = typeof value;`,
|
|
570
|
-
"",
|
|
571
|
-
` if (type === "string") {`,
|
|
572
|
-
` return \`string:\${value}\`;`,
|
|
573
|
-
" }",
|
|
574
|
-
"",
|
|
575
|
-
` if (type === "number") {`,
|
|
576
|
-
` return \`number:\${Object.is(value, -0) ? "-0" : String(value)}\`;`,
|
|
577
|
-
" }",
|
|
578
|
-
"",
|
|
579
|
-
` if (type === "bigint") {`,
|
|
580
|
-
` return \`bigint:\${value.toString()}\`;`,
|
|
581
|
-
" }",
|
|
582
|
-
"",
|
|
583
|
-
` if (type === "boolean") {`,
|
|
584
|
-
` return value ? "boolean:true" : "boolean:false";`,
|
|
585
|
-
" }",
|
|
586
|
-
"",
|
|
587
|
-
` if (type === "symbol") {`,
|
|
588
|
-
` return \`symbol:\${String(value)}\`;`,
|
|
589
|
-
" }",
|
|
590
|
-
"",
|
|
591
|
-
` let objectId = ${MARKUP_HELPER_PREFIX}ObjectIds.get(value);`,
|
|
592
|
-
"",
|
|
593
|
-
` if (objectId === undefined) {`,
|
|
594
|
-
` objectId = ${MARKUP_HELPER_PREFIX}NextObjectId;`,
|
|
595
|
-
` ${MARKUP_HELPER_PREFIX}NextObjectId += 1;`,
|
|
596
|
-
` ${MARKUP_HELPER_PREFIX}ObjectIds.set(value, objectId);`,
|
|
597
|
-
" }",
|
|
598
|
-
"",
|
|
599
|
-
` return \`object:\${objectId}\`;`,
|
|
600
|
-
"}",
|
|
601
|
-
"",
|
|
602
|
-
`function ${MARKUP_HELPER_PREFIX}DepsKey(deps) {`,
|
|
603
|
-
` return deps.map(${MARKUP_HELPER_PREFIX}Hash).join("|");`,
|
|
604
|
-
"}",
|
|
605
|
-
"",
|
|
606
|
-
`function ${MARKUP_HELPER_PREFIX}Value(id, deps, factory, fallback) {`,
|
|
607
|
-
` if (typeof window === "undefined") {`,
|
|
608
|
-
` return fallback;`,
|
|
609
|
-
" }",
|
|
610
|
-
"",
|
|
611
|
-
` ${MARKUP_HELPER_PREFIX}Version;`,
|
|
612
|
-
"",
|
|
613
|
-
` const cacheKey = \`\${id}::\${${MARKUP_HELPER_PREFIX}DepsKey(deps)}\`;`,
|
|
614
|
-
"",
|
|
615
|
-
` if (!${MARKUP_HELPER_PREFIX}Cleanups.has(cacheKey)) {`,
|
|
616
|
-
` if (!${MARKUP_HELPER_PREFIX}PendingStarts.has(cacheKey)) {`,
|
|
617
|
-
` ${MARKUP_HELPER_PREFIX}PendingStarts.add(cacheKey);`,
|
|
618
|
-
` queueMicrotask(() => {`,
|
|
619
|
-
` ${MARKUP_HELPER_PREFIX}PendingStarts.delete(cacheKey);`,
|
|
620
|
-
"",
|
|
621
|
-
` if (${MARKUP_HELPER_PREFIX}Cleanups.has(cacheKey)) {`,
|
|
622
|
-
" return;",
|
|
623
|
-
" }",
|
|
624
|
-
"",
|
|
625
|
-
` ${MARKUP_HELPER_PREFIX}Cleanups.set(`,
|
|
626
|
-
" cacheKey,",
|
|
627
|
-
` ${MARKUP_HELPER_PREFIX}RunComponentEffect(`,
|
|
628
|
-
` ${MARKUP_HELPER_PREFIX}Runtime,`,
|
|
629
|
-
` ${MARKUP_HELPER_PREFIX}Effect.gen(function* () {`,
|
|
630
|
-
` ${MARKUP_HELPER_PREFIX}Values[cacheKey] = yield* ${MARKUP_HELPER_PREFIX}Effect.gen(factory);`,
|
|
631
|
-
` ${MARKUP_HELPER_PREFIX}Version += 1;`,
|
|
632
|
-
" }),",
|
|
633
|
-
" ),",
|
|
634
|
-
" );",
|
|
635
|
-
" });",
|
|
636
|
-
" }",
|
|
637
|
-
" }",
|
|
638
|
-
"",
|
|
639
|
-
` return Object.prototype.hasOwnProperty.call(${MARKUP_HELPER_PREFIX}Values, cacheKey)`,
|
|
640
|
-
` ? ${MARKUP_HELPER_PREFIX}Values[cacheKey]`,
|
|
641
|
-
" : fallback;",
|
|
642
|
-
"}",
|
|
643
|
-
"",
|
|
644
|
-
`function ${MARKUP_HELPER_PREFIX}Promise(id, deps, factory) {`,
|
|
645
|
-
` if (typeof window === "undefined") {`,
|
|
646
|
-
` return Promise.resolve(undefined);`,
|
|
647
|
-
" }",
|
|
648
|
-
"",
|
|
649
|
-
` const cacheKey = \`\${id}::\${${MARKUP_HELPER_PREFIX}DepsKey(deps)}\`;`,
|
|
650
|
-
"",
|
|
651
|
-
` if (!Object.prototype.hasOwnProperty.call(${MARKUP_HELPER_PREFIX}Promises, cacheKey)) {`,
|
|
652
|
-
` ${MARKUP_HELPER_PREFIX}Promises[cacheKey] = new Promise((resolve, reject) => {`,
|
|
653
|
-
` queueMicrotask(() => {`,
|
|
654
|
-
` ${MARKUP_HELPER_PREFIX}RunInlineEffect(`,
|
|
655
|
-
` ${MARKUP_HELPER_PREFIX}Runtime,`,
|
|
656
|
-
` ${MARKUP_HELPER_PREFIX}Effect.gen(factory),`,
|
|
657
|
-
` ).then(resolve, reject);`,
|
|
658
|
-
" });",
|
|
659
|
-
` }).catch((error) => {`,
|
|
660
|
-
` delete ${MARKUP_HELPER_PREFIX}Promises[cacheKey];`,
|
|
661
|
-
" throw error;",
|
|
662
|
-
" });",
|
|
663
|
-
" }",
|
|
664
|
-
"",
|
|
665
|
-
` return ${MARKUP_HELPER_PREFIX}Promises[cacheKey];`,
|
|
666
|
-
"}",
|
|
667
|
-
"",
|
|
668
|
-
`function ${MARKUP_HELPER_PREFIX}Run(factory) {`,
|
|
669
|
-
` if (typeof window === "undefined") {`,
|
|
670
|
-
" return Promise.resolve(undefined);",
|
|
671
|
-
" }",
|
|
672
|
-
"",
|
|
673
|
-
` return ${MARKUP_HELPER_PREFIX}RunInlineEffect(`,
|
|
674
|
-
` ${MARKUP_HELPER_PREFIX}Runtime,`,
|
|
675
|
-
` ${MARKUP_HELPER_PREFIX}Effect.gen(factory),`,
|
|
676
|
-
" );",
|
|
677
|
-
"}",
|
|
678
|
-
"",
|
|
679
|
-
`function ${MARKUP_HELPER_PREFIX}CleanupAll() {`,
|
|
680
|
-
` for (const cleanup of ${MARKUP_HELPER_PREFIX}Cleanups.values()) {`,
|
|
681
|
-
" cleanup();",
|
|
682
|
-
" }",
|
|
683
|
-
"",
|
|
684
|
-
` ${MARKUP_HELPER_PREFIX}Cleanups.clear();`,
|
|
685
|
-
"}",
|
|
686
|
-
"",
|
|
687
|
-
`${MARKUP_HELPER_PREFIX}OnDestroy(${MARKUP_HELPER_PREFIX}CleanupAll);`,
|
|
688
|
-
`${MARKUP_HELPER_PREFIX}RegisterHotDispose(import.meta, ${MARKUP_HELPER_PREFIX}CleanupAll);`
|
|
689
|
-
].join("\n");
|
|
690
|
-
}
|
|
691
|
-
function indentBlock(text, indent) {
|
|
692
|
-
return text.split("\n").map((line) => line.length > 0 ? `${indent}${line}` : line).join("\n");
|
|
693
|
-
}
|
|
694
|
-
//#endregion
|
|
1
|
+
import { t as transformEffectMarkup } from "../chunks/markup-CNqU2j9U.js";
|
|
695
2
|
export { transformEffectMarkup };
|
|
696
|
-
|
|
697
|
-
//# sourceMappingURL=markup.js.map
|