@markless/bundler 0.2.2 → 0.3.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/README.md +1 -1
- package/dist/preload.d.ts +4 -4
- package/dist/preload.js +2 -2
- package/dist/rolldown-DAsY_7V1.js +4515 -0
- package/dist/rolldown.d.ts +11 -3
- package/dist/rolldown.js +3 -3
- package/dist/{source-module-C8W2THUI.js → source-module-BCEdLQvG.js} +362 -286
- package/dist/source-module-XFgOFX1c.d.ts +8 -0
- package/dist/{types-CzXV_ABj.d.ts → types-BuooJg32.d.ts} +47 -2
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +1298 -115
- package/package.json +6 -6
- package/dist/rolldown-CpG_S-ZJ.js +0 -2554
- package/dist/source-module-BRb5P7wL.d.ts +0 -6
|
@@ -0,0 +1,4515 @@
|
|
|
1
|
+
import { MarklessCompileError, createCompileErrorPayload } from "./dev-error.js";
|
|
2
|
+
import { S as requalifyExecutionLogModuleHook, _ as executionLogActivationInjection, a as encodedSymbolSource, b as injectExecutionLogModuleHook, d as scopedSymbolExportName, f as settleVirtualModuleId, g as MARKLESS_EXECUTION_LOG_MODULE_ID, h as EXECUTION_LOG_DISPATCH_MODULE_IDS, i as emitSourceModule, l as resumeVirtualModuleId, m as symbolVirtualModuleSourceFile, n as emitResumeModule, o as payloadModule, p as symbolVirtualModuleId, r as emitSettleModule, s as prerenderWakeVirtualModuleId, t as MARKLESS_VIRTUAL_PREFIX, u as rewriteSymbolModuleExport, v as executionLogVirtualModuleSource, w as planModulePreloads, x as normalizeExecutionLogMode, y as hasExecutionLogModuleHook } from "./source-module-BCEdLQvG.js";
|
|
3
|
+
import { joinURL, parsePath, withLeadingSlash, withQuery, withoutLeadingSlash } from "ufo";
|
|
4
|
+
import { PROTOCOL_EVENT_ACTION_KIND, createStorageSeedMetadataFromGraphNodeId, protocolEventActionKind } from "@markless/serializer";
|
|
5
|
+
import { existsSync, statSync } from "node:fs";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { dirname, isAbsolute, join, normalize, relative, resolve } from "pathe";
|
|
8
|
+
import { defDGraph } from "@thi.ng/dgraph";
|
|
9
|
+
import { collectTsrxModuleDiagnostics, compileTsrxModule, emitSymbolResolverModule, parseJavaScriptModule } from "@markless/compiler";
|
|
10
|
+
import { PRERENDER_INLINE_EVENT_NAMES_TOKEN, createInlineResumerDebugRegistrationSource, createInlineResumerSelfWakeSource, createInlineResumerSource, createPrerenderInlineResumerSource, createPrerenderSettleInlineResumerSource } from "@markless/web/inline/resumer";
|
|
11
|
+
//#region src/build/bundle-graph.ts
|
|
12
|
+
const SLOW_BUNDLE_TOTAL = 300 * 1024 / 8 * .5;
|
|
13
|
+
const SMALL_BUNDLE_TOTAL = 1e3;
|
|
14
|
+
function convertManifestToBundleGraph(manifest, bundleGraphAdders) {
|
|
15
|
+
const graph = bundleGraphRecords(manifest, bundleGraphAdders);
|
|
16
|
+
const dag = defDGraph(bundleGraphEdges(graph));
|
|
17
|
+
const reduced = dag.copy();
|
|
18
|
+
for (const name of dag.nodes()) for (const dep of dag.immediateDependencies(name)) for (const transitive of dag.transitiveDependencies(dep)) reduced.removeEdge(name, transitive);
|
|
19
|
+
const nodes = Object.keys(graph).sort().map((name) => {
|
|
20
|
+
const bundle = graph[name];
|
|
21
|
+
const dynamicImports = (bundle?.dynamicImports ?? []).map((dep) => [dep, dynamicImportMarker(bundle, graph[dep])]).sort((a, b) => a[1] - b[1] || a[0].localeCompare(b[0]));
|
|
22
|
+
const deps = [...reduced.immediateDependencies(name)].sort();
|
|
23
|
+
let lastMarker;
|
|
24
|
+
for (const [dep, marker] of dynamicImports) {
|
|
25
|
+
if (marker !== lastMarker) {
|
|
26
|
+
deps.push(marker);
|
|
27
|
+
lastMarker = marker;
|
|
28
|
+
}
|
|
29
|
+
deps.push(dep);
|
|
30
|
+
}
|
|
31
|
+
return [name, deps];
|
|
32
|
+
});
|
|
33
|
+
const indexes = /* @__PURE__ */ new Map();
|
|
34
|
+
let index = 0;
|
|
35
|
+
for (const [name, deps] of nodes) {
|
|
36
|
+
indexes.set(name, index);
|
|
37
|
+
index += 1 + deps.length;
|
|
38
|
+
}
|
|
39
|
+
return nodes.flatMap(([name, deps]) => [name, ...deps.map((dep) => {
|
|
40
|
+
if (typeof dep === "number") return dep;
|
|
41
|
+
return indexes.get(dep);
|
|
42
|
+
})]);
|
|
43
|
+
}
|
|
44
|
+
function createPreloadGraphAdder(addEntries) {
|
|
45
|
+
return (manifest) => addEntries({
|
|
46
|
+
manifest,
|
|
47
|
+
hasBundle: (bundleName) => !!manifest.bundles[bundleName],
|
|
48
|
+
bundlesForOrigins: (origins) => bundlesForOrigins(manifest, origins)
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function bundlesForOrigins(manifest, origins) {
|
|
52
|
+
const normalizedOrigins = new Set(origins.map(normalizeManifestOrigin));
|
|
53
|
+
const bundles = [];
|
|
54
|
+
for (const [bundleName, bundle] of Object.entries(manifest.bundles)) if (bundle.origins?.some((origin) => normalizedOrigins.has(normalizeManifestOrigin(origin)))) bundles.push(bundleName);
|
|
55
|
+
return bundles.sort();
|
|
56
|
+
}
|
|
57
|
+
function bundleGraphRecords(manifest, bundleGraphAdders) {
|
|
58
|
+
const graph = { ...manifest.bundles };
|
|
59
|
+
const runtimeBundles = runtimeBundleNamesByModuleId(manifest);
|
|
60
|
+
for (const module of manifest.modules) {
|
|
61
|
+
const runtimeModuleIdsBySymbolId = new Map((module.runtimeDemandMap?.symbols ?? []).map((symbol) => [symbol.symbolId, symbol.runtimeModuleIds]));
|
|
62
|
+
for (const symbol of module.symbols) {
|
|
63
|
+
if (!symbol.fileName) continue;
|
|
64
|
+
const imports = [...manifest.bundles[symbol.fileName]?.imports ?? [], ...module.resolver.fileName ? [module.resolver.fileName] : []];
|
|
65
|
+
const runtimeDemandBundles = (runtimeModuleIdsBySymbolId.get(symbol.symbolId) ?? []).flatMap((id) => runtimeBundles.get(id) ?? []);
|
|
66
|
+
const symbolBundle = {
|
|
67
|
+
size: 0,
|
|
68
|
+
total: 0,
|
|
69
|
+
dynamicImports: [...new Set([symbol.fileName, ...runtimeDemandBundles])]
|
|
70
|
+
};
|
|
71
|
+
if (imports.length > 0) symbolBundle.imports = imports;
|
|
72
|
+
graph[symbol.symbolId] = symbolBundle;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
for (const [bundleName, bundle] of Object.entries(graph)) for (const symbolId of bundle.symbols ?? []) {
|
|
76
|
+
if (symbolId === bundleName) continue;
|
|
77
|
+
graph[symbolId] = appendDynamicImport(graph[symbolId] ?? {
|
|
78
|
+
size: 0,
|
|
79
|
+
total: 0
|
|
80
|
+
}, bundleName);
|
|
81
|
+
}
|
|
82
|
+
if (bundleGraphAdders) {
|
|
83
|
+
const combined = {
|
|
84
|
+
...manifest,
|
|
85
|
+
bundles: graph
|
|
86
|
+
};
|
|
87
|
+
for (const add of bundleGraphAdders) Object.assign(graph, add(combined));
|
|
88
|
+
}
|
|
89
|
+
for (const bundleName of Object.keys(graph)) {
|
|
90
|
+
const bundle = graph[bundleName];
|
|
91
|
+
if (!bundle) continue;
|
|
92
|
+
graph[bundleName] = {
|
|
93
|
+
...bundle,
|
|
94
|
+
imports: bundle.imports?.filter((dep) => graph[dep]) ?? [],
|
|
95
|
+
dynamicImports: bundle.dynamicImports?.filter((dep) => graph[dep]) ?? []
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
const used = /* @__PURE__ */ new Set();
|
|
99
|
+
for (const bundle of Object.values(graph)) {
|
|
100
|
+
for (const dep of bundle.imports ?? []) used.add(dep);
|
|
101
|
+
for (const dep of bundle.dynamicImports ?? []) used.add(dep);
|
|
102
|
+
}
|
|
103
|
+
for (const [bundleName, bundle] of Object.entries(graph)) if (!used.has(bundleName) && !bundle.imports?.length && !bundle.dynamicImports?.length) delete graph[bundleName];
|
|
104
|
+
return graph;
|
|
105
|
+
}
|
|
106
|
+
function appendDynamicImport(bundle, dependency) {
|
|
107
|
+
if (bundle.dynamicImports?.includes(dependency)) return bundle;
|
|
108
|
+
return {
|
|
109
|
+
...bundle,
|
|
110
|
+
dynamicImports: [...bundle.dynamicImports ?? [], dependency]
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function runtimeBundleNamesByModuleId(manifest) {
|
|
114
|
+
const entries = /* @__PURE__ */ new Map();
|
|
115
|
+
for (const [bundleName, bundle] of Object.entries(manifest.bundles)) for (const origin of bundle.origins ?? []) {
|
|
116
|
+
const runtimeModuleId = runtimeModuleIdFromOrigin(origin);
|
|
117
|
+
if (!runtimeModuleId) continue;
|
|
118
|
+
entries.set(runtimeModuleId, [...entries.get(runtimeModuleId) ?? [], bundleName]);
|
|
119
|
+
}
|
|
120
|
+
for (const [id, names] of entries) entries.set(id, names.sort());
|
|
121
|
+
return entries;
|
|
122
|
+
}
|
|
123
|
+
function runtimeModuleIdFromOrigin(origin) {
|
|
124
|
+
const normalized = normalizeManifestOrigin(origin);
|
|
125
|
+
for (const [prefix, marker] of [["web", "packages/web/src/"], ["core", "packages/core/src/"]]) {
|
|
126
|
+
const index = normalized.lastIndexOf(marker);
|
|
127
|
+
if (index === -1 || !normalized.endsWith(".ts")) continue;
|
|
128
|
+
return `${prefix}/${normalized.slice(index + marker.length, -3)}`;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function dynamicImportMarker(bundle, dependency) {
|
|
132
|
+
let probability = .5;
|
|
133
|
+
if (hasRelatedOrigin(bundle, dependency)) probability += .25;
|
|
134
|
+
if ((dependency?.total ?? 0) > SLOW_BUNDLE_TOTAL) if (probability > .5) probability += .02;
|
|
135
|
+
else probability -= .02;
|
|
136
|
+
if ((dependency?.total ?? 0) < SMALL_BUNDLE_TOTAL) probability += .15;
|
|
137
|
+
probability = Math.min(probability, .99);
|
|
138
|
+
return -Math.round(probability * 10);
|
|
139
|
+
}
|
|
140
|
+
function hasRelatedOrigin(bundle, dependency) {
|
|
141
|
+
return !!bundle?.origins?.some((origin) => dependency?.origins?.some((depOrigin) => depOrigin.startsWith(origin)));
|
|
142
|
+
}
|
|
143
|
+
function* bundleGraphEdges(graph) {
|
|
144
|
+
for (const [bundleName, bundle] of Object.entries(graph)) {
|
|
145
|
+
yield [bundleName, null];
|
|
146
|
+
for (const dep of bundle.imports ?? []) yield [bundleName, dep];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function normalizeManifestOrigin(origin) {
|
|
150
|
+
return withoutLeadingSlash(normalize(origin));
|
|
151
|
+
}
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/build/dynamic-import-scan.ts
|
|
154
|
+
function scanEmittedDynamicImports(code, chunkFileName) {
|
|
155
|
+
if (!code.includes("import(")) return [];
|
|
156
|
+
let ast;
|
|
157
|
+
try {
|
|
158
|
+
ast = parseJavaScriptModule(code);
|
|
159
|
+
} catch {
|
|
160
|
+
return [];
|
|
161
|
+
}
|
|
162
|
+
const specifiers = /* @__PURE__ */ new Set();
|
|
163
|
+
const visit = (node) => {
|
|
164
|
+
if (!node || typeof node !== "object") return;
|
|
165
|
+
if (node.type === "ImportExpression") {
|
|
166
|
+
const specifier = staticSpecifier(node.source ?? node.arguments);
|
|
167
|
+
if (specifier?.startsWith(".")) specifiers.add(join(dirname(chunkFileName), specifier));
|
|
168
|
+
}
|
|
169
|
+
for (const child of childNodes$1(node)) visit(child);
|
|
170
|
+
};
|
|
171
|
+
visit(ast);
|
|
172
|
+
return [...specifiers];
|
|
173
|
+
}
|
|
174
|
+
function staticSpecifier(source) {
|
|
175
|
+
const node = Array.isArray(source) ? source[0] : source;
|
|
176
|
+
if (!node || typeof node !== "object") return void 0;
|
|
177
|
+
const astNode = node;
|
|
178
|
+
if (astNode.type === "Literal" || astNode.type === "StringLiteral") return typeof astNode.value === "string" ? astNode.value : void 0;
|
|
179
|
+
if (astNode.type === "TemplateLiteral" && (astNode.expressions ?? []).length === 0) {
|
|
180
|
+
const quasi = astNode.quasis?.[0];
|
|
181
|
+
return quasi?.value?.cooked ?? quasi?.cooked;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function childNodes$1(node) {
|
|
185
|
+
const children = [];
|
|
186
|
+
for (const [key, value] of Object.entries(node)) {
|
|
187
|
+
if (key === "loc" || key === "span" || key === "range") continue;
|
|
188
|
+
if (Array.isArray(value)) {
|
|
189
|
+
for (const item of value) if (isAstNode$1(item)) children.push(item);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (isAstNode$1(value)) children.push(value);
|
|
193
|
+
}
|
|
194
|
+
return children;
|
|
195
|
+
}
|
|
196
|
+
function isAstNode$1(value) {
|
|
197
|
+
return !!value && typeof value === "object" && "type" in value;
|
|
198
|
+
}
|
|
199
|
+
const MARKLESS_BUILD_PREFIX = `build/`;
|
|
200
|
+
const MARKLESS_BUNDLE_GRAPH = `${MARKLESS_BUILD_PREFIX}bundle-graph.json`;
|
|
201
|
+
const WEB_RUNTIME_CAPABILITY_GROUPS = [
|
|
202
|
+
{
|
|
203
|
+
name: "markless-direct-renderer",
|
|
204
|
+
test: fileBasenamePattern("direct")
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
name: "markless-resume-branches",
|
|
208
|
+
test: fileBasenamePattern("resume-branches")
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "markless-resume-behaviors",
|
|
212
|
+
test: fileBasenamePattern("resume-behaviors")
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
name: "markless-resume-repeats",
|
|
216
|
+
test: fileBasenamePattern("resume-keyed-repeats", "repeat-runtime")
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: "markless-resume-async",
|
|
220
|
+
test: fileBasenamePattern("resume-async-boundaries", "resume-async-wiring")
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
name: "markless-resume-shared-patch",
|
|
224
|
+
test: fileBasenamePattern("resume-shared-patch")
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "markless-resume-runtime",
|
|
228
|
+
test: fileBasenamePattern("resume-runtime")
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: "markless-resume-runtime-start",
|
|
232
|
+
test: fileBasenamePattern("resume-runtime-start")
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: "markless-resume-runtime-shared",
|
|
236
|
+
test: fileBasenamePattern("resume-runtime-shared")
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "markless-resume-events",
|
|
240
|
+
test: fileBasenamePattern("resume-events")
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: "markless-resume-handoff",
|
|
244
|
+
test: fileBasenamePattern("resume-handoff")
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: "markless-resume-locators",
|
|
248
|
+
test: fileBasenamePattern("resume-locators")
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: "markless-resume-errors",
|
|
252
|
+
test: fileBasenamePattern("resume-errors")
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
name: "markless-resume-sync-computed",
|
|
256
|
+
test: fileBasenamePattern("resume-sync-computed")
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: "markless-resume-sync-demand",
|
|
260
|
+
test: fileBasenamePattern("resume-sync-demand")
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "markless-payload-full",
|
|
264
|
+
test: fileBasenamePattern("payload-full", "payload-full-storage-free")
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "markless-payload-resume",
|
|
268
|
+
test: fileBasenamePattern("payload-resume")
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "markless-inline-payload-document",
|
|
272
|
+
test: /[/\\]web[/\\]src[/\\]inline[/\\]payload-document\.ts(?:[?#].*)?$/
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: "markless-payload-document",
|
|
276
|
+
test: fileBasenamePattern("payload-document", "payload-document-common", "payload-resume-registry")
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: "markless-payload-graph-construct",
|
|
280
|
+
test: fileBasenamePattern("payload-graph-construct")
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: "markless-dom-journal",
|
|
284
|
+
test: fileBasenamePattern("dom-journal")
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: "markless-protocol-decode",
|
|
288
|
+
test: fileBasenamePattern("protocol-client", "protocol-client-storage", "protocol-state", "storage-record-client")
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
name: "markless-value-decode",
|
|
292
|
+
test: fileBasenamePattern("value-decode-client", "value-decode-extensions")
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "markless-payload-leaves",
|
|
296
|
+
test: fileBasenamePattern("payload", "payload-document")
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "markless-dev-log",
|
|
300
|
+
test: /virtual:markless:dev-log|[/\\]web[/\\]src[/\\]dev-log\.ts(?:[?#].*)?$/
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "markless-resume-core",
|
|
304
|
+
test: fileBasenamePattern("resume")
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "markless-runtime-graph-core",
|
|
308
|
+
test: fileBasenamePattern("graph-core")
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: "markless-runtime-graph-collections",
|
|
312
|
+
test: fileBasenamePattern("graph-collections")
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: "markless-runtime-graph-computed",
|
|
316
|
+
test: fileBasenamePattern("graph-computed")
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: "markless-runtime-graph-async",
|
|
320
|
+
test: fileBasenamePattern("graph-async")
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: "markless-runtime-graph-scheduler",
|
|
324
|
+
test: fileBasenamePattern("graph-scheduler")
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: "markless-runtime-graph-shared",
|
|
328
|
+
test: fileBasenamePattern("graph-shared")
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: "markless-graph",
|
|
332
|
+
test: /[/\\](?:runtime[/\\]src[/\\](?!graph-(?:core|collections|computed|async|scheduler|shared)\.ts)|core[/\\]src[/\\]runtime)[/\\]?/
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: "markless-serializer",
|
|
336
|
+
test: /[/\\]serializer[/\\]src[/\\](?!protocol-validation)/
|
|
337
|
+
}
|
|
338
|
+
];
|
|
339
|
+
function fileBasenamePattern(...names) {
|
|
340
|
+
return new RegExp(`[/\\\\](?:${names.join("|")})\\.ts(?:[?#].*)?$`);
|
|
341
|
+
}
|
|
342
|
+
const MARKLESS_RUNTIME_GROUPS = [...WEB_RUNTIME_CAPABILITY_GROUPS, {
|
|
343
|
+
name: "markless-runtime",
|
|
344
|
+
test: /[/\\]@markless[/\\]runtime[/\\]/
|
|
345
|
+
}];
|
|
346
|
+
function outputDefaults(output, environment) {
|
|
347
|
+
if (environment === "lib") return output;
|
|
348
|
+
const next = {
|
|
349
|
+
...output,
|
|
350
|
+
hoistTransitiveImports: false
|
|
351
|
+
};
|
|
352
|
+
if (environment === "server") {
|
|
353
|
+
next.entryFileNames ??= "[name].js";
|
|
354
|
+
next.chunkFileNames ??= "chunk-[hash].js";
|
|
355
|
+
next.codeSplitting = marklessCodeSplitting(next.codeSplitting);
|
|
356
|
+
return next;
|
|
357
|
+
}
|
|
358
|
+
next.entryFileNames ??= `${MARKLESS_BUILD_PREFIX}chunk-[hash].js`;
|
|
359
|
+
next.chunkFileNames ??= `${MARKLESS_BUILD_PREFIX}chunk-[hash].js`;
|
|
360
|
+
next.minifyInternalExports = true;
|
|
361
|
+
next.strictExecutionOrder = true;
|
|
362
|
+
next.codeSplitting = marklessCodeSplitting(next.codeSplitting);
|
|
363
|
+
return next;
|
|
364
|
+
}
|
|
365
|
+
function marklessCodeSplitting(codeSplitting) {
|
|
366
|
+
if (typeof codeSplitting === "boolean") throw new Error("@markless/bundler requires output.codeSplitting to be an object so runtime chunks can be grouped.");
|
|
367
|
+
return {
|
|
368
|
+
...codeSplitting,
|
|
369
|
+
groups: [...MARKLESS_RUNTIME_GROUPS, ...codeSplitting?.groups ?? []]
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
//#endregion
|
|
373
|
+
//#region src/build/head-links.ts
|
|
374
|
+
const STYLESHEET_ASSET_RE = /\.css$/;
|
|
375
|
+
function collectHeadLinkInjections(bundle, options = {}) {
|
|
376
|
+
const publicPath = options.publicPath ?? ((fileName) => fileName);
|
|
377
|
+
const stylesheetFiles = stylesheetFilesFromViteMetadata(bundle);
|
|
378
|
+
if (stylesheetFiles.size === 0) {
|
|
379
|
+
for (const item of Object.values(bundle)) if (item.type === "asset" && STYLESHEET_ASSET_RE.test(item.fileName)) stylesheetFiles.add(item.fileName);
|
|
380
|
+
}
|
|
381
|
+
return [...stylesheetFiles].sort().map((fileName) => stylesheetInjection(publicPath(fileName)));
|
|
382
|
+
}
|
|
383
|
+
function stylesheetFilesFromViteMetadata(bundle) {
|
|
384
|
+
const stylesheetFiles = /* @__PURE__ */ new Set();
|
|
385
|
+
for (const item of Object.values(bundle)) {
|
|
386
|
+
if (item.type !== "chunk") continue;
|
|
387
|
+
for (const fileName of item.viteMetadata?.importedCss ?? []) stylesheetFiles.add(fileName);
|
|
388
|
+
}
|
|
389
|
+
return stylesheetFiles;
|
|
390
|
+
}
|
|
391
|
+
function collectModulePreloadInjections(preloadSource, options = {}) {
|
|
392
|
+
const buildMetadata = isBuildMetadata(preloadSource) ? preloadSource : void 0;
|
|
393
|
+
const bundleGraph = buildMetadata ? buildMetadata.bundleGraph : preloadSource;
|
|
394
|
+
const roots = [
|
|
395
|
+
...buildMetadata ? symbolRootsFromBuildMetadata(buildMetadata) : (bundleGraph ?? []).filter((name) => typeof name === "string" && name.startsWith("symbol:")).map((name) => ({
|
|
396
|
+
name,
|
|
397
|
+
priority: "high"
|
|
398
|
+
})),
|
|
399
|
+
...(options.entryChunks ?? []).map((name) => ({
|
|
400
|
+
name,
|
|
401
|
+
priority: "auto",
|
|
402
|
+
edges: "dynamic-only"
|
|
403
|
+
})),
|
|
404
|
+
...(options.wakeChunks ?? []).map((name) => ({
|
|
405
|
+
name,
|
|
406
|
+
priority: "auto"
|
|
407
|
+
}))
|
|
408
|
+
];
|
|
409
|
+
return planModulePreloads({
|
|
410
|
+
base: options.publicPath ? options.publicPath(MARKLESS_BUILD_PREFIX) : joinURL("/", MARKLESS_BUILD_PREFIX),
|
|
411
|
+
bundleGraph,
|
|
412
|
+
roots
|
|
413
|
+
}).map(modulePreloadInjection);
|
|
414
|
+
}
|
|
415
|
+
function symbolRootsFromBuildMetadata(metadata) {
|
|
416
|
+
const roots = [];
|
|
417
|
+
const seen = /* @__PURE__ */ new Set();
|
|
418
|
+
for (const module of metadata.modules) for (const symbol of module.symbols) {
|
|
419
|
+
if (!symbol.fileName || seen.has(symbol.symbolId)) continue;
|
|
420
|
+
seen.add(symbol.symbolId);
|
|
421
|
+
roots.push({
|
|
422
|
+
name: symbol.symbolId,
|
|
423
|
+
priority: "high"
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
return roots;
|
|
427
|
+
}
|
|
428
|
+
function isBuildMetadata(value) {
|
|
429
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && Array.isArray(value.modules);
|
|
430
|
+
}
|
|
431
|
+
function injectHeadLinks(bundle, injections) {
|
|
432
|
+
if (injections.length === 0) return;
|
|
433
|
+
const links = [...new Map(injections.map((injection) => [headLinkKey(injection), injection])).values()].map(headLinkTag).join("");
|
|
434
|
+
for (const output of Object.values(bundle)) {
|
|
435
|
+
if (!isHtmlAssetWithSource(output)) continue;
|
|
436
|
+
output.source = output.source.includes("</head>") ? output.source.replace("</head>", `${links}</head>`) : `${links}${output.source}`;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
function headLinkTag(injection) {
|
|
440
|
+
if (injection.tag === "link" && injection.attributes?.rel === "modulepreload") return `<link ${Object.entries(injection.attributes).map(([name, value]) => compactAttribute(name, value)).join(" ")}>`;
|
|
441
|
+
const attributes = Object.entries(injection.attributes ?? {}).map(([name, value]) => `${name}="${value.replaceAll("\"", """)}"`);
|
|
442
|
+
const open = attributes.length > 0 ? `<${injection.tag} ${attributes.join(" ")}>` : `<${injection.tag}>`;
|
|
443
|
+
return injection.children === void 0 ? open : `${open}${injection.children}</${injection.tag}>`;
|
|
444
|
+
}
|
|
445
|
+
function headLinkKey(injection) {
|
|
446
|
+
return JSON.stringify([
|
|
447
|
+
injection.tag,
|
|
448
|
+
injection.location,
|
|
449
|
+
Object.entries(injection.attributes ?? {}),
|
|
450
|
+
injection.children
|
|
451
|
+
]);
|
|
452
|
+
}
|
|
453
|
+
function compactAttribute(name, value) {
|
|
454
|
+
if (name === "crossorigin" && value === "anonymous") return name;
|
|
455
|
+
return /^[^\s"'`=<>]+$/.test(value) ? `${name}=${value}` : `${name}="${value.replaceAll("\"", """)}"`;
|
|
456
|
+
}
|
|
457
|
+
function isHtmlAssetWithSource(output) {
|
|
458
|
+
if (!output || typeof output !== "object") return false;
|
|
459
|
+
const asset = output;
|
|
460
|
+
return asset.type === "asset" && typeof asset.fileName === "string" && asset.fileName.endsWith(".html") && typeof asset.source === "string";
|
|
461
|
+
}
|
|
462
|
+
function modulePreloadInjection(preload) {
|
|
463
|
+
const attributes = {
|
|
464
|
+
rel: "modulepreload",
|
|
465
|
+
href: preload.href,
|
|
466
|
+
crossorigin: "anonymous"
|
|
467
|
+
};
|
|
468
|
+
if (preload.fetchPriority && preload.fetchPriority !== "auto") attributes.fetchpriority = preload.fetchPriority;
|
|
469
|
+
return {
|
|
470
|
+
tag: "link",
|
|
471
|
+
location: "head",
|
|
472
|
+
attributes
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
function stylesheetInjection(href) {
|
|
476
|
+
return {
|
|
477
|
+
tag: "link",
|
|
478
|
+
location: "head",
|
|
479
|
+
attributes: {
|
|
480
|
+
rel: "stylesheet",
|
|
481
|
+
href
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
//#endregion
|
|
486
|
+
//#region ../web/src/debug-channel.ts
|
|
487
|
+
function installDebugChannelLayer(root, initialPhase, initiallyActive = true) {
|
|
488
|
+
const global = globalThis;
|
|
489
|
+
const previous = global.__MARKLESS_DEBUG__?.version === 1 ? global.__MARKLESS_DEBUG__ : void 0;
|
|
490
|
+
let priorRoot;
|
|
491
|
+
try {
|
|
492
|
+
priorRoot = previous?.explainInteraction(root, "__markless_debug_root__");
|
|
493
|
+
} catch {}
|
|
494
|
+
const priorContainer = priorRoot && "containerId" in priorRoot ? previous?.containers.find((entry) => entry.id === priorRoot.containerId) : void 0;
|
|
495
|
+
const seed = `${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
496
|
+
const id = priorContainer?.id ?? `container:${seed}`;
|
|
497
|
+
const rootKey = priorContainer?.root.key ?? `root:${seed}`;
|
|
498
|
+
const rootRef = new WeakRef(root);
|
|
499
|
+
const events = /* @__PURE__ */ new WeakMap();
|
|
500
|
+
const delegatedEvents = /* @__PURE__ */ new Set();
|
|
501
|
+
const keys = /* @__PURE__ */ new WeakMap();
|
|
502
|
+
const invalidated = /* @__PURE__ */ new WeakSet();
|
|
503
|
+
const routerSources = global[Symbol.for("markless.debug.channel.v1.router-sources")] ??= /* @__PURE__ */ new Set();
|
|
504
|
+
const ownViolations = [];
|
|
505
|
+
let phase = initialPhase;
|
|
506
|
+
let lifecycle = initiallyActive ? "active" : "registered";
|
|
507
|
+
let boundarySnapshots = Object.freeze([]);
|
|
508
|
+
let nextElement = 1;
|
|
509
|
+
let nextSequence = (previous?.violations.at(-1)?.sequence ?? 0) + 1;
|
|
510
|
+
let dropped = 0;
|
|
511
|
+
let pruned = false;
|
|
512
|
+
const freeze = (value) => Object.freeze(value);
|
|
513
|
+
const contains = (element) => {
|
|
514
|
+
const currentRoot = rootRef.deref();
|
|
515
|
+
return !!currentRoot && (currentRoot === element || currentRoot.contains?.(element) === true);
|
|
516
|
+
};
|
|
517
|
+
const keyFor = (element) => {
|
|
518
|
+
let key = keys.get(element);
|
|
519
|
+
if (!key) {
|
|
520
|
+
key = `${rootKey}:element:${nextElement++}`;
|
|
521
|
+
keys.set(element, key);
|
|
522
|
+
}
|
|
523
|
+
return key;
|
|
524
|
+
};
|
|
525
|
+
const eligibleAnchor = (element) => {
|
|
526
|
+
const anchor = element.closest?.("a[href]");
|
|
527
|
+
if (!anchor?.hasAttribute("data-markless-router-link") || anchor.hasAttribute("download")) return false;
|
|
528
|
+
const target = anchor.getAttribute("target");
|
|
529
|
+
if (target && target !== "_self" || anchor.relList?.contains("external")) return false;
|
|
530
|
+
try {
|
|
531
|
+
const base = global.location?.href ?? "http://localhost/";
|
|
532
|
+
return new URL(anchor.href ?? "", base).origin === new URL(base).origin;
|
|
533
|
+
} catch {
|
|
534
|
+
return false;
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
const none = (element, eventName, reason) => freeze({
|
|
538
|
+
kind: "none",
|
|
539
|
+
eventName,
|
|
540
|
+
reason,
|
|
541
|
+
containerId: id,
|
|
542
|
+
elementKey: keyFor(element)
|
|
543
|
+
});
|
|
544
|
+
const explain = (element, eventName) => {
|
|
545
|
+
if (lifecycle === "disposed" && (contains(element) || keys.has(element))) return none(element, eventName, "container-disposed");
|
|
546
|
+
if (!contains(element)) try {
|
|
547
|
+
return previous?.explainInteraction(element, eventName) ?? freeze({
|
|
548
|
+
kind: "none",
|
|
549
|
+
eventName,
|
|
550
|
+
reason: "outside-known-container"
|
|
551
|
+
});
|
|
552
|
+
} catch {
|
|
553
|
+
return freeze({
|
|
554
|
+
kind: "none",
|
|
555
|
+
eventName,
|
|
556
|
+
reason: "outside-known-container"
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
if (element.isConnected === false) return none(element, eventName, "element-disconnected");
|
|
560
|
+
if (eligibleAnchor(element)) {
|
|
561
|
+
const source = eventName === "navigate" && routerSources.has("navigation-event") ? "navigation-event" : eventName === "click" && routerSources.has("spa-click-listener") ? "spa-click-listener" : eventName === "click" && routerSources.has("ssr-link-bridge") ? "ssr-link-bridge" : void 0;
|
|
562
|
+
if (source) return freeze({
|
|
563
|
+
kind: "router-delegation",
|
|
564
|
+
source,
|
|
565
|
+
containerId: id,
|
|
566
|
+
elementKey: keyFor(element),
|
|
567
|
+
eventName
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
const interaction = events.get(element)?.get(eventName);
|
|
571
|
+
if (interaction) return freeze({ ...interaction });
|
|
572
|
+
if (delegatedEvents.has(eventName)) return freeze({
|
|
573
|
+
kind: "inline-resumer",
|
|
574
|
+
source: "ssr-inline",
|
|
575
|
+
containerId: id,
|
|
576
|
+
elementKey: keyFor(element),
|
|
577
|
+
eventName
|
|
578
|
+
});
|
|
579
|
+
if (invalidated.has(element)) return none(element, eventName, "not-registered");
|
|
580
|
+
try {
|
|
581
|
+
const prior = previous?.explainInteraction(element, eventName);
|
|
582
|
+
if (prior && prior.kind !== "none") return prior;
|
|
583
|
+
} catch {}
|
|
584
|
+
return none(element, eventName, "not-registered");
|
|
585
|
+
};
|
|
586
|
+
const cloneJson = (value, seen = /* @__PURE__ */ new Set()) => {
|
|
587
|
+
if (value === null) return null;
|
|
588
|
+
if (typeof value === "boolean" || typeof value === "string") return value;
|
|
589
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
590
|
+
if (!value || typeof value !== "object" || seen.has(value)) return void 0;
|
|
591
|
+
seen.add(value);
|
|
592
|
+
if (Array.isArray(value)) {
|
|
593
|
+
const copy = value.map((entry) => cloneJson(entry, seen));
|
|
594
|
+
return copy.some((entry) => entry === void 0) ? void 0 : freeze(copy);
|
|
595
|
+
}
|
|
596
|
+
if (Object.getPrototypeOf(value) !== Object.prototype) return void 0;
|
|
597
|
+
const copy = {};
|
|
598
|
+
for (const [name, entry] of Object.entries(value)) {
|
|
599
|
+
const cloned = cloneJson(entry, seen);
|
|
600
|
+
if (cloned === void 0) return void 0;
|
|
601
|
+
copy[name] = cloned;
|
|
602
|
+
}
|
|
603
|
+
return freeze(copy);
|
|
604
|
+
};
|
|
605
|
+
const pushViolation = (input) => {
|
|
606
|
+
const cloned = input.details === void 0 ? void 0 : cloneJson(input.details);
|
|
607
|
+
const details = cloned && !Array.isArray(cloned) && typeof cloned === "object" ? cloned : void 0;
|
|
608
|
+
const { details: _details, ...metadata } = input;
|
|
609
|
+
ownViolations.push(freeze({
|
|
610
|
+
...metadata,
|
|
611
|
+
...details ? { details } : {},
|
|
612
|
+
sequence: nextSequence++,
|
|
613
|
+
timestamp: Date.now()
|
|
614
|
+
}));
|
|
615
|
+
if (input.details !== void 0 && !details) ownViolations.push(freeze({
|
|
616
|
+
code: "MARKLESS_DEBUG_DETAILS_DROPPED",
|
|
617
|
+
message: "Debug violation details were not JSON-safe and were dropped.",
|
|
618
|
+
sequence: nextSequence++,
|
|
619
|
+
timestamp: Date.now()
|
|
620
|
+
}));
|
|
621
|
+
while (ownViolations.length > 100) {
|
|
622
|
+
ownViolations.shift();
|
|
623
|
+
dropped++;
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
const channel = freeze({
|
|
627
|
+
version: 1,
|
|
628
|
+
get containers() {
|
|
629
|
+
const inherited = previous?.containers.filter((entry) => entry.id !== id) ?? [];
|
|
630
|
+
if (pruned || lifecycle === "disposed") return freeze([...inherited]);
|
|
631
|
+
const currentRoot = rootRef.deref();
|
|
632
|
+
const connected = !!currentRoot && currentRoot.isConnected !== false;
|
|
633
|
+
const snapshot = freeze({
|
|
634
|
+
id,
|
|
635
|
+
phase,
|
|
636
|
+
lifecycle: connected ? lifecycle : "disposed",
|
|
637
|
+
root: freeze({
|
|
638
|
+
key: rootKey,
|
|
639
|
+
connected
|
|
640
|
+
}),
|
|
641
|
+
boundaries: freeze([...boundarySnapshots])
|
|
642
|
+
});
|
|
643
|
+
if (!connected) pruned = true;
|
|
644
|
+
return freeze([...inherited, snapshot]);
|
|
645
|
+
},
|
|
646
|
+
get violations() {
|
|
647
|
+
return freeze([...previous?.violations ?? [], ...ownViolations].slice(-100));
|
|
648
|
+
},
|
|
649
|
+
violationCapacity: 100,
|
|
650
|
+
get droppedViolationCount() {
|
|
651
|
+
return (previous?.droppedViolationCount ?? 0) + dropped;
|
|
652
|
+
},
|
|
653
|
+
explainInteraction: explain
|
|
654
|
+
});
|
|
655
|
+
Object.defineProperty(global, "__MARKLESS_DEBUG__", {
|
|
656
|
+
configurable: true,
|
|
657
|
+
enumerable: false,
|
|
658
|
+
value: channel,
|
|
659
|
+
writable: false
|
|
660
|
+
});
|
|
661
|
+
return {
|
|
662
|
+
start(nextPhase, active = true) {
|
|
663
|
+
phase = nextPhase === "ssr-resume" && phase === "csr" ? "csr" : nextPhase;
|
|
664
|
+
if (active) lifecycle = "active";
|
|
665
|
+
return id;
|
|
666
|
+
},
|
|
667
|
+
activate: () => void (lifecycle === "disposed" || (lifecycle = "active")),
|
|
668
|
+
dispose() {
|
|
669
|
+
lifecycle = "disposed";
|
|
670
|
+
boundarySnapshots = freeze([]);
|
|
671
|
+
},
|
|
672
|
+
invalidate(element) {
|
|
673
|
+
events.delete(element);
|
|
674
|
+
invalidated.add(element);
|
|
675
|
+
},
|
|
676
|
+
record(element, eventName, input) {
|
|
677
|
+
if (lifecycle === "disposed") return;
|
|
678
|
+
let byName = events.get(element);
|
|
679
|
+
if (!byName) events.set(element, byName = /* @__PURE__ */ new Map());
|
|
680
|
+
const symbolIds = "symbolIds" in input ? freeze([...input.symbolIds]) : void 0;
|
|
681
|
+
byName.set(eventName, freeze({
|
|
682
|
+
...input,
|
|
683
|
+
...symbolIds ? { symbolIds } : {},
|
|
684
|
+
containerId: id,
|
|
685
|
+
elementKey: keyFor(element),
|
|
686
|
+
eventName
|
|
687
|
+
}));
|
|
688
|
+
},
|
|
689
|
+
delegated(eventNames) {
|
|
690
|
+
if (lifecycle === "disposed") return;
|
|
691
|
+
for (const eventName of eventNames) delegatedEvents.add(eventName);
|
|
692
|
+
},
|
|
693
|
+
violation: pushViolation,
|
|
694
|
+
router: (source) => void routerSources.add(source),
|
|
695
|
+
boundaries(value) {
|
|
696
|
+
boundarySnapshots = freeze(value.map((entry) => freeze({ ...entry })));
|
|
697
|
+
},
|
|
698
|
+
disposed: () => lifecycle === "disposed"
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
function __marklessDebugBootstrapSource() {
|
|
702
|
+
return `((root,phase,active)=>{const controls=(${installDebugChannelLayer.toString()})(root,phase,active);return Object.freeze({record:(element,eventName,input)=>controls.record(element,eventName,input),delegated:(eventNames)=>controls.delegated(eventNames),router:(source)=>controls.router(source),activate:()=>controls.activate()})})`;
|
|
703
|
+
}
|
|
704
|
+
//#endregion
|
|
705
|
+
//#region src/inline-resumer.ts
|
|
706
|
+
let oxcToolsPromise;
|
|
707
|
+
const compiledSources = /* @__PURE__ */ new Map();
|
|
708
|
+
function loadOxcTools() {
|
|
709
|
+
oxcToolsPromise ??= import("rolldown/experimental").then(({ minifySync, transformSync }) => ({
|
|
710
|
+
minifySync,
|
|
711
|
+
transformSync
|
|
712
|
+
}));
|
|
713
|
+
return oxcToolsPromise;
|
|
714
|
+
}
|
|
715
|
+
function compileInlineResumerSources(options) {
|
|
716
|
+
const cacheKey = `${options.debug ? "debug" : "production"}:${options.executionLog}`;
|
|
717
|
+
let compiled = compiledSources.get(cacheKey);
|
|
718
|
+
if (!compiled) {
|
|
719
|
+
compiled = compileInlineResumerSourceVariants(options);
|
|
720
|
+
compiledSources.set(cacheKey, compiled);
|
|
721
|
+
}
|
|
722
|
+
return compiled;
|
|
723
|
+
}
|
|
724
|
+
async function compileInlineResumerSourceVariants(options) {
|
|
725
|
+
const shared = {
|
|
726
|
+
debug: options.debug,
|
|
727
|
+
executionLog: options.executionLog
|
|
728
|
+
};
|
|
729
|
+
const [event, syncPolicy, graphSyncPolicyOwner, graphSyncPolicyConsumer] = await Promise.all([
|
|
730
|
+
compileInlineResumerSource({
|
|
731
|
+
...shared,
|
|
732
|
+
graphSyncPolicy: false,
|
|
733
|
+
sharedGraphPolicy: false,
|
|
734
|
+
syncPolicy: false
|
|
735
|
+
}),
|
|
736
|
+
compileInlineResumerSource({
|
|
737
|
+
...shared,
|
|
738
|
+
graphSyncPolicy: false,
|
|
739
|
+
sharedGraphPolicy: false,
|
|
740
|
+
syncPolicy: true
|
|
741
|
+
}),
|
|
742
|
+
compileInlineResumerSource({
|
|
743
|
+
...shared,
|
|
744
|
+
graphSyncPolicy: true,
|
|
745
|
+
sharedGraphPolicy: true,
|
|
746
|
+
syncPolicy: true
|
|
747
|
+
}),
|
|
748
|
+
compileInlineResumerSource({
|
|
749
|
+
...shared,
|
|
750
|
+
graphSyncPolicy: true,
|
|
751
|
+
sharedGraphPolicy: false,
|
|
752
|
+
syncPolicy: true
|
|
753
|
+
})
|
|
754
|
+
]);
|
|
755
|
+
return {
|
|
756
|
+
...shared,
|
|
757
|
+
event,
|
|
758
|
+
syncPolicy,
|
|
759
|
+
graphSyncPolicyOwner,
|
|
760
|
+
graphSyncPolicyConsumer
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
async function compileInlineResumerSource(options) {
|
|
764
|
+
const source = createInlineResumerSource({
|
|
765
|
+
...options,
|
|
766
|
+
...options.debug ? {
|
|
767
|
+
debugBootstrapSource: __marklessDebugBootstrapSource(),
|
|
768
|
+
debugRegistrationSource: createInlineResumerDebugRegistrationSource()
|
|
769
|
+
} : {}
|
|
770
|
+
});
|
|
771
|
+
const { minifySync, transformSync } = await loadOxcTools();
|
|
772
|
+
const transformed = transformSync("markless-inline-resumer.js", source, {
|
|
773
|
+
lang: "js",
|
|
774
|
+
sourceType: "script",
|
|
775
|
+
target: "es2020"
|
|
776
|
+
});
|
|
777
|
+
assertOxcResult("transform", transformed.errors);
|
|
778
|
+
const minified = minifySync("markless-inline-resumer.js", transformed.code, {
|
|
779
|
+
compress: true,
|
|
780
|
+
mangle: { toplevel: true },
|
|
781
|
+
module: false
|
|
782
|
+
});
|
|
783
|
+
assertOxcResult("minify", minified.errors);
|
|
784
|
+
return minified.code.trim();
|
|
785
|
+
}
|
|
786
|
+
function assertOxcResult(phase, errors) {
|
|
787
|
+
if (errors.length === 0) return;
|
|
788
|
+
throw new Error(`MARKLESS_INLINE_RESUMER_${phase.toUpperCase()}_FAILED:\n${errors.map((error) => error.message).join("\n")}`);
|
|
789
|
+
}
|
|
790
|
+
const compiledPrerenderSources = /* @__PURE__ */ new Map();
|
|
791
|
+
function compilePrerenderInlineResumerSources() {
|
|
792
|
+
let compiled = compiledPrerenderSources.get("production");
|
|
793
|
+
if (!compiled) {
|
|
794
|
+
compiled = compilePrerenderVariants();
|
|
795
|
+
compiledPrerenderSources.set("production", compiled);
|
|
796
|
+
}
|
|
797
|
+
return compiled;
|
|
798
|
+
}
|
|
799
|
+
async function compilePrerenderVariants() {
|
|
800
|
+
const [prerender, prerenderSelfWake, prerenderSettle] = await Promise.all([
|
|
801
|
+
compilePrerenderInlineResumerSource(false),
|
|
802
|
+
compilePrerenderInlineResumerSource(true),
|
|
803
|
+
compilePrerenderInlineResumerSource("settle")
|
|
804
|
+
]);
|
|
805
|
+
return {
|
|
806
|
+
prerender,
|
|
807
|
+
prerenderSelfWake,
|
|
808
|
+
prerenderSettle
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
async function compilePrerenderInlineResumerSource(selfWake) {
|
|
812
|
+
const source = parameterizedPrerenderInlineResumerSource(selfWake);
|
|
813
|
+
const { minifySync, transformSync } = await loadOxcTools();
|
|
814
|
+
const transformed = transformSync("markless-prerender-inline-resumer.js", source, {
|
|
815
|
+
lang: "js",
|
|
816
|
+
sourceType: "script",
|
|
817
|
+
target: "es2020"
|
|
818
|
+
});
|
|
819
|
+
assertOxcResult("transform", transformed.errors);
|
|
820
|
+
const minified = minifySync("markless-prerender-inline-resumer.js", transformed.code, {
|
|
821
|
+
compress: true,
|
|
822
|
+
mangle: { toplevel: true },
|
|
823
|
+
module: false
|
|
824
|
+
});
|
|
825
|
+
assertOxcResult("minify", minified.errors);
|
|
826
|
+
const code = minified.code.trim();
|
|
827
|
+
if (code.split(PRERENDER_INLINE_EVENT_NAMES_TOKEN).length !== 2) throw new Error("MARKLESS_PRERENDER_INLINE_RESUMER_EVENT_NAMES_TOKEN_LOST");
|
|
828
|
+
return code;
|
|
829
|
+
}
|
|
830
|
+
function parameterizedPrerenderInlineResumerSource(selfWake) {
|
|
831
|
+
const placeholder = [PRERENDER_INLINE_EVENT_NAMES_TOKEN];
|
|
832
|
+
const literal = JSON.stringify(placeholder);
|
|
833
|
+
const plain = selfWake === "settle" ? createPrerenderSettleInlineResumerSource(placeholder, void 0) : createPrerenderInlineResumerSource(placeholder, void 0);
|
|
834
|
+
if (plain.split(literal).length !== 2) throw new Error("MARKLESS_PRERENDER_INLINE_RESUMER_EVENT_NAMES_UNPLACEABLE");
|
|
835
|
+
return `${plain.replace(literal, PRERENDER_INLINE_EVENT_NAMES_TOKEN)}${selfWake === true ? createInlineResumerSelfWakeSource(void 0) : ""}`;
|
|
836
|
+
}
|
|
837
|
+
//#endregion
|
|
838
|
+
//#region src/bound-resolver.ts
|
|
839
|
+
function adaptImportedCaptureResolver(source, hasImportedRows) {
|
|
840
|
+
if (!hasImportedRows) return source;
|
|
841
|
+
const original = " return (context) => base({ ...context, capture: createCaptureContext(context, bound) });";
|
|
842
|
+
const replacement = [
|
|
843
|
+
" return async (context) => {",
|
|
844
|
+
" const pendingCallbacks = [];",
|
|
845
|
+
" const capture = createCaptureContext(context, bound);",
|
|
846
|
+
" const result = await base({ ...context, graph: createBoundGraph(context, bound, capture, pendingCallbacks), capture });",
|
|
847
|
+
" await Promise.all(pendingCallbacks);",
|
|
848
|
+
" return result;",
|
|
849
|
+
" };"
|
|
850
|
+
].join("\n");
|
|
851
|
+
const helper = [
|
|
852
|
+
"function createBoundGraph(context, bound, capture, pendingCallbacks) {",
|
|
853
|
+
" const legacySlots = new Map(bound.captureSlots.flatMap((slot) => slot.legacyGraphRead ? [[JSON.stringify([slot.legacyGraphRead.graphNodeId, slot.legacyGraphRead.path ?? []]), slot]] : []));",
|
|
854
|
+
" return {",
|
|
855
|
+
" ...context.graph,",
|
|
856
|
+
" read(graphNodeId, path = []) {",
|
|
857
|
+
" const slot = legacySlots.get(JSON.stringify([graphNodeId, path]));",
|
|
858
|
+
" if (!slot) return context.graph.read(graphNodeId, path);",
|
|
859
|
+
" if (slot.route.kind === callbackRoute) return (...args) => {",
|
|
860
|
+
" const pending = context.invokeSymbol(slot.route.callbackSymbolId, { ...context, event: context.event, args });",
|
|
861
|
+
" pendingCallbacks.push(Promise.resolve(pending));",
|
|
862
|
+
" return pending;",
|
|
863
|
+
" };",
|
|
864
|
+
" return capture.read(slot.slotId);",
|
|
865
|
+
" },",
|
|
866
|
+
" };",
|
|
867
|
+
"}",
|
|
868
|
+
""
|
|
869
|
+
].join("\n");
|
|
870
|
+
return source.replace(original, replacement).replace("function createCaptureContext(context, bound) {", `${helper}function createCaptureContext(context, bound) {`);
|
|
871
|
+
}
|
|
872
|
+
//#endregion
|
|
873
|
+
//#region src/trigger-groups.ts
|
|
874
|
+
const EVENT_STAGES_BROWSER_TRIGGER = {
|
|
875
|
+
[PROTOCOL_EVENT_ACTION_KIND.event]: true,
|
|
876
|
+
[PROTOCOL_EVENT_ACTION_KIND.externalDelegate]: false
|
|
877
|
+
};
|
|
878
|
+
function triggerGroupVirtualModuleId(filename, index) {
|
|
879
|
+
return `virtual:markless:trigger-group:${encodeURIComponent(filename)}:${index}`;
|
|
880
|
+
}
|
|
881
|
+
function triggerGroupVirtualModuleSourceFile(moduleId) {
|
|
882
|
+
const bare = moduleId.startsWith("\0") ? moduleId.slice(1) : moduleId;
|
|
883
|
+
const match = /^virtual:markless:trigger-group:([^:]+):\d+$/.exec(bare);
|
|
884
|
+
if (!match?.[1]) return null;
|
|
885
|
+
try {
|
|
886
|
+
return decodeURIComponent(match[1]);
|
|
887
|
+
} catch {
|
|
888
|
+
return null;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
function emitPrerenderTriggerGroupModule(input) {
|
|
892
|
+
const armRendererModuleId = input.armRendererModuleId ?? input.group.armRendererModuleId;
|
|
893
|
+
const ids = new Set(input.group.symbolIds);
|
|
894
|
+
const boundRows = input.boundRows.filter((row) => ids.has(row.id));
|
|
895
|
+
let source = emitSymbolResolverModule({
|
|
896
|
+
symbols: input.symbols.filter((symbol) => ids.has(symbol.id)),
|
|
897
|
+
boundSymbols: boundRows
|
|
898
|
+
});
|
|
899
|
+
const routes = input.symbolRoutes ?? [];
|
|
900
|
+
if (routes.length > 0) {
|
|
901
|
+
source = source.replaceAll("loadSymbol(", "marklessLoadLocalSymbol(");
|
|
902
|
+
source += [
|
|
903
|
+
"export function loadSymbol(symbolId) {",
|
|
904
|
+
...routes.flatMap((route) => [
|
|
905
|
+
`\tif (symbolId.startsWith(${JSON.stringify(route.prefix)})) {`,
|
|
906
|
+
`\t\treturn import(${JSON.stringify(symbolRouteImportSource(route.importSource))}).then((mod) => mod.loadSymbol ? mod.loadSymbol(symbolId.slice(${route.prefix.length})) : Promise.reject(new Error(\`Unknown child async symbol \${symbolId}\`)));`,
|
|
907
|
+
" }"
|
|
908
|
+
]),
|
|
909
|
+
" return marklessLoadLocalSymbol(symbolId);",
|
|
910
|
+
"}"
|
|
911
|
+
].join("\n");
|
|
912
|
+
}
|
|
913
|
+
return [
|
|
914
|
+
armRendererModuleId ? [
|
|
915
|
+
`import { prepareBoundaryArm as marklessPrepareBoundaryArm, renderBoundaryArm as marklessRenderBoundaryArm } from ${JSON.stringify(armRendererModuleId)};`,
|
|
916
|
+
"export function prepareBoundaryArm(boundaryId, status, graph) {",
|
|
917
|
+
" return marklessPrepareBoundaryArm(boundaryId, status, graph, loadSymbol);",
|
|
918
|
+
"}",
|
|
919
|
+
"export function renderBoundaryArm(boundaryId, status, graph) {",
|
|
920
|
+
" return marklessRenderBoundaryArm(boundaryId, status, graph, loadSymbol);",
|
|
921
|
+
"}"
|
|
922
|
+
].join("\n") : "",
|
|
923
|
+
adaptImportedCaptureResolver(source, boundRows.some((row) => row.loaderSymbolId !== void 0)),
|
|
924
|
+
`export const groupId=${JSON.stringify(input.group.id)};`,
|
|
925
|
+
`export const state=${JSON.stringify(input.group.state)};`,
|
|
926
|
+
`export const view=${JSON.stringify(input.group.view)};`,
|
|
927
|
+
`export const graphNodeIds=${JSON.stringify(input.group.graphNodeIds)};`
|
|
928
|
+
].join("\n");
|
|
929
|
+
}
|
|
930
|
+
function emitPrerenderBoundaryRendererModule(renderDataId) {
|
|
931
|
+
return [
|
|
932
|
+
`import { marklessPrerenderData } from ${JSON.stringify(renderDataId)};`,
|
|
933
|
+
"import { renderPrerenderBoundary } from '@markless/web/fns/prerender-resume';",
|
|
934
|
+
"const marklessPreparedBoundaryArms = new Map();",
|
|
935
|
+
"export async function prepareBoundaryArm(boundaryId, status, graph, loadSymbol) {",
|
|
936
|
+
" const rendered = await renderPrerenderBoundary(marklessPrerenderData, boundaryId, status, graph, loadSymbol);",
|
|
937
|
+
" marklessPreparedBoundaryArms.set(`${boundaryId}:${status}`, rendered);",
|
|
938
|
+
"}",
|
|
939
|
+
"export function renderBoundaryArm(boundaryId, status) {",
|
|
940
|
+
" const key = `${boundaryId}:${status}`;",
|
|
941
|
+
" const rendered = marklessPreparedBoundaryArms.get(key);",
|
|
942
|
+
" if (!rendered) throw new Error(`Markless prerender arm ${key} was not prepared.`);",
|
|
943
|
+
" marklessPreparedBoundaryArms.delete(key);",
|
|
944
|
+
" return rendered;",
|
|
945
|
+
"}"
|
|
946
|
+
].join("\n");
|
|
947
|
+
}
|
|
948
|
+
function symbolRouteImportSource(importSource) {
|
|
949
|
+
return importSource.includes("?") ? `${importSource}&markless-symbols` : `${importSource}?markless-symbols`;
|
|
950
|
+
}
|
|
951
|
+
function planPrerenderTriggerGroups(input) {
|
|
952
|
+
const symbols = new Map(input.symbolResolver.symbols.map((symbol) => [symbol.id, symbol]));
|
|
953
|
+
const bounds = new Map(input.boundRows.map((row) => [row.id, row]));
|
|
954
|
+
const completeView = input.completeView ?? input.view;
|
|
955
|
+
const completeBoundaries = new Map(completeView.asyncBoundaries.map((boundary) => [boundary.id, boundary]));
|
|
956
|
+
const selfWakeBoundaries = unsettledAsyncBoundaryIndexes(input.state, input.view);
|
|
957
|
+
const groups = [
|
|
958
|
+
...selfWakeBoundaries.length > 0 ? [{
|
|
959
|
+
event: {
|
|
960
|
+
hostNodeId: "self-wake",
|
|
961
|
+
eventName: "self-wake",
|
|
962
|
+
symbolIds: []
|
|
963
|
+
},
|
|
964
|
+
selfWakeBoundaries
|
|
965
|
+
}] : [],
|
|
966
|
+
...input.view.events.filter((event) => EVENT_STAGES_BROWSER_TRIGGER[protocolEventActionKind(event)]).map((event) => ({ event })),
|
|
967
|
+
...(input.view.branches ?? []).flatMap((branch, branchIndex) => {
|
|
968
|
+
const events = /* @__PURE__ */ new Map();
|
|
969
|
+
for (const arm of branch.armRecords ?? []) for (const event of arm.events) {
|
|
970
|
+
const key = `${event.eventName}:${event.hostPath.join(".")}`;
|
|
971
|
+
const route = events.get(key) ?? {
|
|
972
|
+
eventName: event.eventName,
|
|
973
|
+
hostPath: event.hostPath,
|
|
974
|
+
symbolIds: /* @__PURE__ */ new Set()
|
|
975
|
+
};
|
|
976
|
+
for (const symbolId of event.symbolIds ?? []) route.symbolIds.add(symbolId);
|
|
977
|
+
events.set(key, route);
|
|
978
|
+
}
|
|
979
|
+
return [...events.values()].map((route) => ({
|
|
980
|
+
event: {
|
|
981
|
+
hostNodeId: `branch:${branch.id}:${route.hostPath.join(".")}`,
|
|
982
|
+
eventName: route.eventName,
|
|
983
|
+
symbolIds: [...route.symbolIds]
|
|
984
|
+
},
|
|
985
|
+
branch,
|
|
986
|
+
branchIndex,
|
|
987
|
+
hostPath: route.hostPath
|
|
988
|
+
}));
|
|
989
|
+
})
|
|
990
|
+
].flatMap(({ event, branch, branchIndex, hostPath, selfWakeBoundaries }) => {
|
|
991
|
+
const closureView = selfWakeBoundaries ? completeView : input.view;
|
|
992
|
+
if (event.eventName === "visible") return [];
|
|
993
|
+
const host = branch ? void 0 : input.view.locators.find((locator) => locator.hostNodeId === event.hostNodeId);
|
|
994
|
+
if (!host && !branch && !selfWakeBoundaries) return [];
|
|
995
|
+
const compilerGroup = input.triggerGroups.groups.find((group) => group.hostNodeId === event.hostNodeId && group.eventName === event.eventName);
|
|
996
|
+
const graphNodeIds = /* @__PURE__ */ new Set();
|
|
997
|
+
const symbolIds = new Set(event.symbolIds ?? []);
|
|
998
|
+
const selected = {
|
|
999
|
+
domUpdates: /* @__PURE__ */ new Set(),
|
|
1000
|
+
behaviors: /* @__PURE__ */ new Set(),
|
|
1001
|
+
branches: /* @__PURE__ */ new Set(),
|
|
1002
|
+
boundaries: /* @__PURE__ */ new Set(),
|
|
1003
|
+
repeats: /* @__PURE__ */ new Set(),
|
|
1004
|
+
elementHandles: /* @__PURE__ */ new Set()
|
|
1005
|
+
};
|
|
1006
|
+
if (branch && branchIndex !== void 0) {
|
|
1007
|
+
selected.branches.add(branchIndex);
|
|
1008
|
+
if (branch.symbolId) symbolIds.add(branch.symbolId);
|
|
1009
|
+
for (const read of branch.testReads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
1010
|
+
for (const arm of branch.armRecords ?? []) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1011
|
+
}
|
|
1012
|
+
const adoptedBoundaryIds = /* @__PURE__ */ new Set();
|
|
1013
|
+
for (const boundaryIndex of selfWakeBoundaries ?? []) {
|
|
1014
|
+
const servedBoundary = input.view.asyncBoundaries[boundaryIndex];
|
|
1015
|
+
selected.boundaries.add(boundaryIndex);
|
|
1016
|
+
collectSettledBoundaryClosure(input, completeBoundaries.get(servedBoundary.id) ?? servedBoundary, graphNodeIds, symbolIds);
|
|
1017
|
+
}
|
|
1018
|
+
closureView.behaviors.forEach((behavior, index) => {
|
|
1019
|
+
if (selfWakeBoundaries) return;
|
|
1020
|
+
const recordId = `behavior:${behavior.hostNodeId}:${behavior.symbolId ?? ""}`;
|
|
1021
|
+
if ((behavior.inputGraphReads?.length ?? 0) > 0 && !compilerGroup?.payloadRecordIds.includes(recordId)) return;
|
|
1022
|
+
selected.behaviors.add(index);
|
|
1023
|
+
if (behavior.symbolId) symbolIds.add(behavior.symbolId);
|
|
1024
|
+
});
|
|
1025
|
+
let changed = true;
|
|
1026
|
+
while (changed) {
|
|
1027
|
+
const before = closureSize(graphNodeIds, symbolIds, selected);
|
|
1028
|
+
const currentSymbolIds = Array.from(symbolIds);
|
|
1029
|
+
for (const symbolId of currentSymbolIds) {
|
|
1030
|
+
const bound = bounds.get(symbolId);
|
|
1031
|
+
if (bound) {
|
|
1032
|
+
symbolIds.add(bound.loaderSymbolId ?? bound.baseSymbolId);
|
|
1033
|
+
for (const slot of bound.captureSlots) {
|
|
1034
|
+
if (slot.route.kind === "graph-reference") graphNodeIds.add(slot.route.graphNodeId);
|
|
1035
|
+
if (slot.route.kind === "callback-route") symbolIds.add(slot.route.callbackSymbolId);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
const symbol = symbols.get(symbolId);
|
|
1039
|
+
if (!symbol) continue;
|
|
1040
|
+
if ("reads" in symbol) for (const read of symbol.reads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
1041
|
+
if ("writes" in symbol) for (const write of symbol.writes ?? []) graphNodeIds.add(write.graphNodeId);
|
|
1042
|
+
if (symbol.kind === "async-computed-runner" || symbol.kind === "sync-computed-derive") {
|
|
1043
|
+
graphNodeIds.add(symbol.graphNodeId);
|
|
1044
|
+
for (const dependency of symbol.dependencies ?? []) graphNodeIds.add(dependency.graphNodeId);
|
|
1045
|
+
}
|
|
1046
|
+
if ("elementHandleCalls" in symbol) for (const call of symbol.elementHandleCalls ?? []) closureView.elementHandles.forEach((handle, index) => {
|
|
1047
|
+
if (handle.name === call.handleName) selected.elementHandles.add(index);
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
closeComputedGraph(graphNodeIds, input.state);
|
|
1051
|
+
for (const graphNodeId of graphNodeIds) {
|
|
1052
|
+
const runnerSymbolId = closureView.asyncRunners?.[graphNodeId];
|
|
1053
|
+
if (runnerSymbolId) symbolIds.add(runnerSymbolId);
|
|
1054
|
+
}
|
|
1055
|
+
selectViewSubscribers(closureView, graphNodeIds, symbolIds, selected);
|
|
1056
|
+
if (!selfWakeBoundaries) input.view.asyncBoundaries.forEach((servedBoundary, index) => {
|
|
1057
|
+
if (adoptedBoundaryIds.has(servedBoundary.id)) return;
|
|
1058
|
+
const boundary = completeBoundaries.get(servedBoundary.id) ?? servedBoundary;
|
|
1059
|
+
if (!settledArmReadGraphNodeIds(input, boundary).some((graphNodeId) => graphNodeIds.has(graphNodeId))) return;
|
|
1060
|
+
adoptedBoundaryIds.add(servedBoundary.id);
|
|
1061
|
+
selected.boundaries.add(index);
|
|
1062
|
+
collectSettledBoundaryClosure(input, boundary, graphNodeIds, symbolIds);
|
|
1063
|
+
collectSettledArmHostRecordClosure(completeView, boundary, graphNodeIds, symbolIds);
|
|
1064
|
+
});
|
|
1065
|
+
if (selfWakeBoundaries || adoptedBoundaryIds.size > 0) {
|
|
1066
|
+
for (const symbol of symbols.values()) if (symbol.kind === "state-initializer" && graphNodeIds.has(symbol.graphNodeId)) symbolIds.add(symbol.id);
|
|
1067
|
+
}
|
|
1068
|
+
changed = closureSize(graphNodeIds, symbolIds, selected) !== before;
|
|
1069
|
+
}
|
|
1070
|
+
const neededHosts = new Set(branch ? [] : [event.hostNodeId]);
|
|
1071
|
+
for (const index of selected.domUpdates) neededHosts.add(closureView.domUpdates[index].hostNodeId);
|
|
1072
|
+
for (const index of selected.behaviors) neededHosts.add(closureView.behaviors[index].hostNodeId);
|
|
1073
|
+
for (const index of selected.repeats) neededHosts.add(closureView.keyedRepeats[index].parentHostNodeId);
|
|
1074
|
+
for (const index of selected.elementHandles) neededHosts.add(closureView.elementHandles[index].hostNodeId);
|
|
1075
|
+
const selectedBoundaryIds = new Set([...selected.boundaries].map((index) => closureView.asyncBoundaries[index].id));
|
|
1076
|
+
const view = {
|
|
1077
|
+
...input.view,
|
|
1078
|
+
locators: closureView.locators.filter((locator) => neededHosts.has(locator.hostNodeId)),
|
|
1079
|
+
events: branch || selfWakeBoundaries ? [] : [event],
|
|
1080
|
+
domUpdates: closureView.domUpdates.filter((_, index) => selected.domUpdates.has(index)),
|
|
1081
|
+
behaviors: closureView.behaviors.filter((_, index) => selected.behaviors.has(index)),
|
|
1082
|
+
elementHandles: closureView.elementHandles.filter((_, index) => selected.elementHandles.has(index)),
|
|
1083
|
+
keyedRepeats: closureView.keyedRepeats?.filter((_, index) => selected.repeats.has(index)),
|
|
1084
|
+
branches: closureView.branches?.filter((_, index) => selected.branches.has(index)),
|
|
1085
|
+
asyncBoundaries: closureView.asyncBoundaries.filter((boundary) => selectedBoundaryIds.has(boundary.id)).map((boundary) => adoptedBoundaryIds.has(boundary.id) ? completeBoundaries.get(boundary.id) ?? boundary : boundary),
|
|
1086
|
+
...closureView.asyncRunners ? { asyncRunners: Object.fromEntries(Object.entries(closureView.asyncRunners).filter(([graphNodeId]) => graphNodeIds.has(graphNodeId))) } : {}
|
|
1087
|
+
};
|
|
1088
|
+
const graphIds = [...graphNodeIds].sort();
|
|
1089
|
+
return [{
|
|
1090
|
+
id: selfWakeBoundaries ? "self-wake" : branch ? `branch:${branch.id}:${event.eventName}:${hostPath.join(".")}` : `${event.hostNodeId}:${event.eventName}`,
|
|
1091
|
+
hostNodeId: event.hostNodeId,
|
|
1092
|
+
eventName: event.eventName,
|
|
1093
|
+
hostIndex: host?.index ?? -1,
|
|
1094
|
+
hostTagName: host?.tagName ?? "*",
|
|
1095
|
+
...branch ? {
|
|
1096
|
+
branchStartIndex: branch.startAnchor.index,
|
|
1097
|
+
branchEndIndex: branch.endAnchor.index,
|
|
1098
|
+
hostPath
|
|
1099
|
+
} : {},
|
|
1100
|
+
graphNodeIds: graphIds,
|
|
1101
|
+
symbolIds: [...symbolIds].sort(),
|
|
1102
|
+
state: filterState(input.state, new Set(graphIds)),
|
|
1103
|
+
view,
|
|
1104
|
+
...adoptedBoundaryIds.size > 0 ? { adoptsSettledArm: true } : {}
|
|
1105
|
+
}];
|
|
1106
|
+
});
|
|
1107
|
+
const armRendererModuleId = groups.some((group) => group.id === "self-wake") ? triggerGroupVirtualModuleId(input.filename, groups.length) : void 0;
|
|
1108
|
+
return groups.map(({ adoptsSettledArm, ...group }) => adoptsSettledArm && armRendererModuleId ? {
|
|
1109
|
+
...group,
|
|
1110
|
+
armRendererModuleId
|
|
1111
|
+
} : group);
|
|
1112
|
+
}
|
|
1113
|
+
function settledArmReadGraphNodeIds(input, boundary) {
|
|
1114
|
+
const graphNodeIds = /* @__PURE__ */ new Set();
|
|
1115
|
+
for (const arm of boundaryArmRecordSets(boundary)) collectCompleteArmRecordClosure(arm, graphNodeIds, /* @__PURE__ */ new Set());
|
|
1116
|
+
for (const edge of input.componentEdges ?? []) if (edge.asyncBoundaryId === boundary.id) {
|
|
1117
|
+
for (const prop of edge.props) if (prop.kind === "graph-reference") graphNodeIds.add(prop.graphNodeId);
|
|
1118
|
+
}
|
|
1119
|
+
return [...graphNodeIds];
|
|
1120
|
+
}
|
|
1121
|
+
function collectSettledBoundaryClosure(input, boundary, graphNodeIds, symbolIds) {
|
|
1122
|
+
if (boundary.updateSymbolId) symbolIds.add(boundary.updateSymbolId);
|
|
1123
|
+
for (const read of boundary.asyncReads) {
|
|
1124
|
+
graphNodeIds.add(read.graphNodeId);
|
|
1125
|
+
if (read.runnerSymbolId) symbolIds.add(read.runnerSymbolId);
|
|
1126
|
+
}
|
|
1127
|
+
for (const arm of boundaryArmRecordSets(boundary)) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1128
|
+
const settledEdgeIds = /* @__PURE__ */ new Set();
|
|
1129
|
+
for (const edge of input.componentEdges ?? []) {
|
|
1130
|
+
if (edge.asyncBoundaryId !== boundary.id) continue;
|
|
1131
|
+
settledEdgeIds.add(edge.id);
|
|
1132
|
+
for (const prop of edge.props) if (prop.kind === "graph-reference") graphNodeIds.add(prop.graphNodeId);
|
|
1133
|
+
}
|
|
1134
|
+
for (const row of input.boundRows) if (row.componentEdgePath.some((edgeId) => settledEdgeIds.has(edgeId))) symbolIds.add(row.id);
|
|
1135
|
+
}
|
|
1136
|
+
function collectSettledArmHostRecordClosure(completeView, boundary, graphNodeIds, symbolIds) {
|
|
1137
|
+
const armHosts = /* @__PURE__ */ new Set();
|
|
1138
|
+
for (const arm of boundaryArmRecordSets(boundary)) for (const locator of arm.locators ?? []) armHosts.add(locator.hostNodeId);
|
|
1139
|
+
if (armHosts.size === 0) return;
|
|
1140
|
+
for (const record of completeView.events) if (armHosts.has(record.hostNodeId)) for (const symbolId of record.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1141
|
+
for (const record of completeView.domUpdates) if (armHosts.has(record.hostNodeId)) {
|
|
1142
|
+
graphNodeIds.add(record.graphNodeId);
|
|
1143
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1144
|
+
}
|
|
1145
|
+
for (const record of completeView.behaviors) if (armHosts.has(record.hostNodeId)) {
|
|
1146
|
+
for (const read of record.inputGraphReads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
1147
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1148
|
+
}
|
|
1149
|
+
for (const record of completeView.keyedRepeats ?? []) if (armHosts.has(record.parentHostNodeId)) {
|
|
1150
|
+
if (record.collectionGraphNodeId) graphNodeIds.add(record.collectionGraphNodeId);
|
|
1151
|
+
for (const rowEvent of record.rowEvents) for (const symbolId of rowEvent.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
function boundaryArmRecordSets(boundary) {
|
|
1155
|
+
return Array.isArray(boundary.armRecords) ? boundary.armRecords : boundary.armRecords ? [boundary.armRecords] : [];
|
|
1156
|
+
}
|
|
1157
|
+
function unsettledAsyncBoundaryIndexes(state, view) {
|
|
1158
|
+
const computed = new Map(state.computed.map((record) => [record.graphNodeId, record]));
|
|
1159
|
+
const runners = { ...view.asyncRunners };
|
|
1160
|
+
for (const boundary of view.asyncBoundaries) for (const read of boundary.asyncReads) if (read.runnerSymbolId) runners[read.graphNodeId] ??= read.runnerSymbolId;
|
|
1161
|
+
return view.asyncBoundaries.flatMap((boundary, index) => {
|
|
1162
|
+
const reachable = new Set(boundary.asyncReads.map((read) => read.graphNodeId));
|
|
1163
|
+
for (const graphNodeId of reachable) {
|
|
1164
|
+
const record = computed.get(graphNodeId);
|
|
1165
|
+
if (!record) continue;
|
|
1166
|
+
if (runners[graphNodeId] && record.snapshot?.status !== "fulfilled" && record.snapshot?.status !== "rejected") return [index];
|
|
1167
|
+
for (const dependency of record.dependencies ?? []) reachable.add(dependency.graphNodeId);
|
|
1168
|
+
}
|
|
1169
|
+
return [];
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
function selectViewSubscribers(view, graphNodeIds, symbolIds, selected) {
|
|
1173
|
+
view.domUpdates.forEach((record, index) => {
|
|
1174
|
+
if (!graphNodeIds.has(record.graphNodeId)) return;
|
|
1175
|
+
selected.domUpdates.add(index);
|
|
1176
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1177
|
+
});
|
|
1178
|
+
view.behaviors.forEach((record, index) => {
|
|
1179
|
+
if (!(record.inputGraphReads ?? []).some((read) => graphNodeIds.has(read.graphNodeId))) return;
|
|
1180
|
+
selected.behaviors.add(index);
|
|
1181
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1182
|
+
});
|
|
1183
|
+
(view.branches ?? []).forEach((record, index) => {
|
|
1184
|
+
if (!(record.testReads ?? []).some((read) => graphNodeIds.has(read.graphNodeId))) return;
|
|
1185
|
+
selected.branches.add(index);
|
|
1186
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1187
|
+
for (const arm of record.armRecords ?? []) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1188
|
+
});
|
|
1189
|
+
view.asyncBoundaries.forEach((record, index) => {
|
|
1190
|
+
if (!record.asyncReads.some((read) => graphNodeIds.has(read.graphNodeId))) return;
|
|
1191
|
+
selected.boundaries.add(index);
|
|
1192
|
+
if (record.updateSymbolId) symbolIds.add(record.updateSymbolId);
|
|
1193
|
+
for (const read of record.asyncReads) if (read.runnerSymbolId) symbolIds.add(read.runnerSymbolId);
|
|
1194
|
+
const arms = Array.isArray(record.armRecords) ? record.armRecords : record.armRecords ? [record.armRecords] : [];
|
|
1195
|
+
for (const arm of arms) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1196
|
+
});
|
|
1197
|
+
(view.keyedRepeats ?? []).forEach((record, index) => {
|
|
1198
|
+
if (!record.collectionGraphNodeId || !graphNodeIds.has(record.collectionGraphNodeId)) return;
|
|
1199
|
+
selected.repeats.add(index);
|
|
1200
|
+
for (const rowEvent of record.rowEvents) for (const symbolId of rowEvent.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
function collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds) {
|
|
1204
|
+
for (const event of arm.events ?? []) for (const symbolId of event.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1205
|
+
for (const update of arm.domUpdates ?? []) {
|
|
1206
|
+
if (typeof update.graphNodeId === "string") graphNodeIds.add(update.graphNodeId);
|
|
1207
|
+
if (typeof update.symbolId === "string") symbolIds.add(update.symbolId);
|
|
1208
|
+
}
|
|
1209
|
+
for (const behavior of arm.behaviors ?? []) {
|
|
1210
|
+
for (const read of behavior.inputGraphReads ?? []) if (typeof read.graphNodeId === "string") graphNodeIds.add(read.graphNodeId);
|
|
1211
|
+
if (typeof behavior.symbolId === "string") symbolIds.add(behavior.symbolId);
|
|
1212
|
+
}
|
|
1213
|
+
for (const repeat of arm.keyedRepeats ?? []) {
|
|
1214
|
+
if (repeat.collectionGraphNodeId) graphNodeIds.add(repeat.collectionGraphNodeId);
|
|
1215
|
+
for (const event of repeat.rowEvents) for (const symbolId of event.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1216
|
+
}
|
|
1217
|
+
for (const branch of arm.branches ?? []) {
|
|
1218
|
+
if (branch.symbolId) symbolIds.add(branch.symbolId);
|
|
1219
|
+
for (const read of branch.testReads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
1220
|
+
for (const nested of branch.armRecords ?? []) collectCompleteArmRecordClosure(nested, graphNodeIds, symbolIds);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
function closeComputedGraph(graphNodeIds, state) {
|
|
1224
|
+
let changed = true;
|
|
1225
|
+
while (changed) {
|
|
1226
|
+
changed = false;
|
|
1227
|
+
for (const computed of state.computed) {
|
|
1228
|
+
const dependencies = computed.dependencies ?? [];
|
|
1229
|
+
if (!graphNodeIds.has(computed.graphNodeId) && !dependencies.some((dependency) => graphNodeIds.has(dependency.graphNodeId))) continue;
|
|
1230
|
+
if (!graphNodeIds.has(computed.graphNodeId)) {
|
|
1231
|
+
graphNodeIds.add(computed.graphNodeId);
|
|
1232
|
+
changed = true;
|
|
1233
|
+
}
|
|
1234
|
+
for (const dependency of dependencies) if (!graphNodeIds.has(dependency.graphNodeId)) {
|
|
1235
|
+
graphNodeIds.add(dependency.graphNodeId);
|
|
1236
|
+
changed = true;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
function filterState(state, graphNodeIds) {
|
|
1242
|
+
return {
|
|
1243
|
+
...state,
|
|
1244
|
+
cells: state.cells.filter((cell) => graphNodeIds.has(cell.graphNodeId)),
|
|
1245
|
+
computed: state.computed.filter((computed) => graphNodeIds.has(computed.graphNodeId)),
|
|
1246
|
+
storage: state.storage?.filter((cell) => graphNodeIds.has(cell.graphNodeId)),
|
|
1247
|
+
sharedDefinitions: state.sharedDefinitions?.filter((definition) => definition.graphNodeIds.some((graphNodeId) => graphNodeIds.has(graphNodeId)))
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
function closureSize(graphNodeIds, symbolIds, selected) {
|
|
1251
|
+
return graphNodeIds.size + symbolIds.size + Object.values(selected).reduce((total, records) => total + records.size, 0);
|
|
1252
|
+
}
|
|
1253
|
+
//#endregion
|
|
1254
|
+
//#region src/transform.ts
|
|
1255
|
+
let oxcTransformSyncPromise;
|
|
1256
|
+
function loadOxcTransformSync() {
|
|
1257
|
+
oxcTransformSyncPromise ??= import("rolldown/experimental").then((mod) => mod.transformSync, () => void 0);
|
|
1258
|
+
return oxcTransformSyncPromise;
|
|
1259
|
+
}
|
|
1260
|
+
async function stripEmittedTypes(code) {
|
|
1261
|
+
const oxcTransformSync = await loadOxcTransformSync();
|
|
1262
|
+
if (!oxcTransformSync) return code;
|
|
1263
|
+
try {
|
|
1264
|
+
const out = oxcTransformSync("markless-emitted.ts", code);
|
|
1265
|
+
if (!out.code || (out.errors?.length ?? 0) > 0) return code;
|
|
1266
|
+
return out.code;
|
|
1267
|
+
} catch {
|
|
1268
|
+
return code;
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
async function transformTsrxModule(input) {
|
|
1272
|
+
return transformTsrxModuleWithPrerenderWakeClosure(input, false);
|
|
1273
|
+
}
|
|
1274
|
+
function marklessVirtualModuleSourceFile(moduleId) {
|
|
1275
|
+
const bare = moduleId.startsWith("\0") ? moduleId.slice(1) : moduleId;
|
|
1276
|
+
if (!bare.startsWith("virtual:markless:")) return null;
|
|
1277
|
+
const rest = bare.slice(MARKLESS_VIRTUAL_PREFIX.length);
|
|
1278
|
+
const kindEnd = rest.indexOf(":");
|
|
1279
|
+
if (kindEnd <= 0) return null;
|
|
1280
|
+
const encoded = rest.slice(kindEnd + 1).split(":")[0].replace(/\.css$/, "");
|
|
1281
|
+
if (!encoded) return null;
|
|
1282
|
+
try {
|
|
1283
|
+
return decodeURIComponent(encoded);
|
|
1284
|
+
} catch {
|
|
1285
|
+
return null;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
async function transformTsrxModuleWithPrerenderWakeClosure(input, linkedChildHasBrowserTriggers) {
|
|
1289
|
+
const encodedFilename = encodeURIComponent(input.filename);
|
|
1290
|
+
const payloadId = `${MARKLESS_VIRTUAL_PREFIX}payload:${encodedFilename}`;
|
|
1291
|
+
const renderDataId = `${MARKLESS_VIRTUAL_PREFIX}render-data:${encodedFilename}`;
|
|
1292
|
+
const resolverId = `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodedFilename}`;
|
|
1293
|
+
const resumeId = resumeVirtualModuleId(input.filename);
|
|
1294
|
+
const prerenderWakeId = prerenderWakeVirtualModuleId(input.filename);
|
|
1295
|
+
const settleId = settleVirtualModuleId(input.filename);
|
|
1296
|
+
const { compiled: compiledForAllClasses, blockingDiagnostics } = await compileWithBlockingDiagnostics(input, resolverId);
|
|
1297
|
+
throwIfBlocked(input, blockingDiagnostics);
|
|
1298
|
+
const runtimeDemandClass = input.runtimeDemandClass ?? "prerender";
|
|
1299
|
+
const compiled = {
|
|
1300
|
+
...compiledForAllClasses,
|
|
1301
|
+
runtimeDemandMap: compiledForAllClasses.runtimeDemandMaps?.[runtimeDemandClass] ?? compiledForAllClasses.runtimeDemandMap
|
|
1302
|
+
};
|
|
1303
|
+
const compilerSymbolRows = compiled.symbolModules.modules.map((module) => ({
|
|
1304
|
+
id: module.symbolId,
|
|
1305
|
+
chunk: symbolVirtualModuleId(input.filename, module.symbolId),
|
|
1306
|
+
exportName: scopedSymbolExportName(input.filename, module.exportName)
|
|
1307
|
+
}));
|
|
1308
|
+
const linkedBoundarySymbols = linkedRenderDataBoundarySymbols({
|
|
1309
|
+
compiled,
|
|
1310
|
+
input,
|
|
1311
|
+
renderDataId,
|
|
1312
|
+
resolverId
|
|
1313
|
+
});
|
|
1314
|
+
const symbolRows = [...compilerSymbolRows, ...linkedBoundarySymbols.map((symbol) => symbol.row)];
|
|
1315
|
+
const behaviorSymbolIds = new Set((compiled.protocolView.behaviors ?? []).flatMap((behavior) => behavior.symbolId ? [behavior.symbolId] : []));
|
|
1316
|
+
const behaviorSymbols = compilerSymbolRows.filter((symbol) => behaviorSymbolIds.has(symbol.id));
|
|
1317
|
+
const importedBoundRows = compiled.boundSymbolResolver.rows.map((row) => row.loaderSymbolId ? {
|
|
1318
|
+
...row,
|
|
1319
|
+
baseSymbolId: row.loaderSymbolId
|
|
1320
|
+
} : row);
|
|
1321
|
+
const boundSymbolDescriptors = perBoundaryBoundSymbolDescriptors(compiled.renderData, importedBoundRows);
|
|
1322
|
+
const resolverSymbols = uniqueSymbolsById([...input.symbols ?? [], ...symbolRows]);
|
|
1323
|
+
const resolverSource = adaptImportedCaptureResolver(emitSymbolResolverModule({
|
|
1324
|
+
buildId: input.buildId,
|
|
1325
|
+
symbols: resolverSymbols,
|
|
1326
|
+
boundSymbols: importedBoundRows
|
|
1327
|
+
}), importedBoundRows.some((row) => row.loaderSymbolId !== void 0));
|
|
1328
|
+
const symbolRoutes = compiled.semanticGraph.componentEdges.flatMap((edge, index) => edge.importSource && !input.artifactChildMaterializations?.[edge.id] ? [{
|
|
1329
|
+
prefix: `c${index}:`,
|
|
1330
|
+
importSource: edge.importSource,
|
|
1331
|
+
componentEdgeId: edge.id
|
|
1332
|
+
}] : []);
|
|
1333
|
+
const executionLogModuleHookMode = input.executionLogModuleHooks === false ? "never" : input.executionLog;
|
|
1334
|
+
const symbolManifestEntries = [...compiled.symbolModules.modules.map((module, index) => ({
|
|
1335
|
+
symbolId: module.symbolId,
|
|
1336
|
+
kind: module.kind,
|
|
1337
|
+
exportName: compilerSymbolRows[index].exportName,
|
|
1338
|
+
virtualModuleId: symbolVirtualModuleId(input.filename, module.symbolId)
|
|
1339
|
+
})), ...linkedBoundarySymbols.map((symbol) => symbol.manifest)];
|
|
1340
|
+
const prerenderTriggerGroups = input.prerenderRecordData && input.prerenderWakeVariant ? planPrerenderTriggerGroups({
|
|
1341
|
+
filename: input.filename,
|
|
1342
|
+
...input.prerenderRecordData,
|
|
1343
|
+
completeView: containerScopedResumeView(compiled.protocolView),
|
|
1344
|
+
triggerGroups: compiled.triggerGroups,
|
|
1345
|
+
symbolResolver: compiled.symbolResolver,
|
|
1346
|
+
boundRows: importedBoundRows,
|
|
1347
|
+
componentEdges: compiled.semanticGraph.componentEdges
|
|
1348
|
+
}) : [];
|
|
1349
|
+
const selfWakeArmRendererId = prerenderTriggerGroups.some((group) => group.id === "self-wake") ? triggerGroupVirtualModuleId(input.filename, prerenderTriggerGroups.length) : void 0;
|
|
1350
|
+
const styleScope = compiled.publicRenderPlan.styleScopes[0];
|
|
1351
|
+
const styleId = styleScope ? `${MARKLESS_VIRTUAL_PREFIX}style:${encodedFilename}.css` : null;
|
|
1352
|
+
const prerenderClosureNeedsWake = needsFullResume(compiled.protocolState, compiled.protocolView, compiled.runtimeDemandMap) || input.prerenderRecords === true && linkedChildHasBrowserTriggers;
|
|
1353
|
+
const emitsPrerenderWakeVariant = input.prerenderWakeVariant === true && compiled.publicRenderModule.renderDataModuleSource !== void 0 && prerenderInterfacesComplete(compiled, input) && prerenderClosureNeedsWake;
|
|
1354
|
+
const emitsPrerenderWakeFacade = input.prerenderWakeFacade === true && input.prerenderWakeVariant === true && compiled.publicRenderModule.renderDataModuleSource !== void 0 && prerenderInterfacesComplete(compiled, input) && prerenderClosureNeedsWake;
|
|
1355
|
+
const manifestOwnsSymbolRoutes = input.prerenderWakeVariant !== true || input.preserveWakeSiblingClaims === true || emitsPrerenderWakeFacade;
|
|
1356
|
+
const manifest = {
|
|
1357
|
+
source: input.filename,
|
|
1358
|
+
captureMetadata: compiled.captureAnalysis,
|
|
1359
|
+
symbolRoutes,
|
|
1360
|
+
payload: { virtualModuleId: payloadId },
|
|
1361
|
+
resolver: { virtualModuleId: emitsPrerenderWakeFacade ? prerenderWakeId : resolverId },
|
|
1362
|
+
symbols: manifestOwnsSymbolRoutes ? symbolManifestEntries : [],
|
|
1363
|
+
runtimeDemandMap: compiled.runtimeDemandMap
|
|
1364
|
+
};
|
|
1365
|
+
const settlePlan = planSettleModule({
|
|
1366
|
+
boundaries: compiled.renderData?.boundaries,
|
|
1367
|
+
asyncRunners: compiled.protocolView.asyncRunners,
|
|
1368
|
+
descriptors: boundSymbolDescriptors,
|
|
1369
|
+
symbols: resolverSymbols
|
|
1370
|
+
});
|
|
1371
|
+
const prerenderBootVariants = input.environment === "server" ? await compilePrerenderInlineResumerSources() : void 0;
|
|
1372
|
+
const prerenderBoot = prerenderBootVariants ? {
|
|
1373
|
+
...prerenderBootVariants,
|
|
1374
|
+
...input.settleModuleUrl && settlePlan ? { settle: {
|
|
1375
|
+
moduleUrl: input.settleModuleUrl,
|
|
1376
|
+
boot: prerenderBootVariants.prerenderSettle,
|
|
1377
|
+
bound: settlePlan.bound
|
|
1378
|
+
} } : {}
|
|
1379
|
+
} : void 0;
|
|
1380
|
+
const linkedClientRenderData = input.environment === "client" && !input.prerenderRecords;
|
|
1381
|
+
const canonicalRenderData = (input.prerenderRecords || linkedClientRenderData) && prerenderInterfacesComplete(compiled, input);
|
|
1382
|
+
const virtualModules = [
|
|
1383
|
+
...compiled.publicRenderModule.renderDataModuleSource ? [{
|
|
1384
|
+
id: renderDataId,
|
|
1385
|
+
type: "render-data",
|
|
1386
|
+
...canonicalRenderData ? { canonicalRenderData: true } : {},
|
|
1387
|
+
source: canonicalRenderData ? prerenderDataModuleSource(compiled, input.importedModuleInterfaces, input.renderDataImportSources, input.artifactChildMaterializations, input.filename) : compiled.publicRenderModule.renderDataModuleSource
|
|
1388
|
+
}] : [],
|
|
1389
|
+
...styleScope && styleId ? [{
|
|
1390
|
+
id: styleId,
|
|
1391
|
+
type: "style",
|
|
1392
|
+
source: styleScope.cssText
|
|
1393
|
+
}] : [],
|
|
1394
|
+
{
|
|
1395
|
+
id: payloadId,
|
|
1396
|
+
type: "payload",
|
|
1397
|
+
source: payloadModule({
|
|
1398
|
+
...compiled.payloadScripts,
|
|
1399
|
+
runtimeDemandMap: compiled.runtimeDemandMap
|
|
1400
|
+
})
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
id: resolverId,
|
|
1404
|
+
type: "resolver",
|
|
1405
|
+
source: resolverSource,
|
|
1406
|
+
symbolClaims: [...new Set([...resolverSymbols.map((symbol) => symbol.id), ...importedBoundRows.map((symbol) => symbol.id)])]
|
|
1407
|
+
},
|
|
1408
|
+
{
|
|
1409
|
+
id: resumeId,
|
|
1410
|
+
type: "resume",
|
|
1411
|
+
source: emitResumeModule({
|
|
1412
|
+
payloadId,
|
|
1413
|
+
resolverId,
|
|
1414
|
+
payloadState: compiled.payloadScripts.state,
|
|
1415
|
+
payloadView: containerScopedResumeView(compiled.payloadScripts.view),
|
|
1416
|
+
runtimeDemandMap: compiled.runtimeDemandMap,
|
|
1417
|
+
executionLog: input.executionLog,
|
|
1418
|
+
needsFullResume: prerenderClosureNeedsWake,
|
|
1419
|
+
prerenderDataId: input.prerenderRecords && prerenderInterfacesComplete(compiled, input) ? renderDataId : void 0,
|
|
1420
|
+
hasBoundSymbols: compiled.boundSymbolResolver.rows.length > 0,
|
|
1421
|
+
boundSymbolDescriptors,
|
|
1422
|
+
symbols: symbolRows,
|
|
1423
|
+
symbolRoutes
|
|
1424
|
+
})
|
|
1425
|
+
},
|
|
1426
|
+
...emitsPrerenderWakeVariant ? [{
|
|
1427
|
+
id: prerenderWakeId,
|
|
1428
|
+
type: "prerender-wake",
|
|
1429
|
+
source: emitResumeModule({
|
|
1430
|
+
payloadId,
|
|
1431
|
+
resolverId,
|
|
1432
|
+
payloadState: compiled.payloadScripts.state,
|
|
1433
|
+
payloadView: containerScopedResumeView(compiled.payloadScripts.view),
|
|
1434
|
+
runtimeDemandMap: compiled.runtimeDemandMap,
|
|
1435
|
+
executionLog: input.executionLog,
|
|
1436
|
+
needsFullResume: prerenderClosureNeedsWake,
|
|
1437
|
+
prerenderDataId: renderDataId,
|
|
1438
|
+
prerenderTriggerGroups: prerenderTriggerGroups.map((group, index) => ({
|
|
1439
|
+
...group,
|
|
1440
|
+
moduleId: triggerGroupVirtualModuleId(input.filename, index)
|
|
1441
|
+
})),
|
|
1442
|
+
installResumeSummary: true,
|
|
1443
|
+
recordsOnly: true,
|
|
1444
|
+
hasBoundSymbols: compiled.boundSymbolResolver.rows.length > 0,
|
|
1445
|
+
boundSymbolDescriptors,
|
|
1446
|
+
symbols: symbolRows,
|
|
1447
|
+
symbolRoutes
|
|
1448
|
+
})
|
|
1449
|
+
}] : [],
|
|
1450
|
+
...emitsPrerenderWakeVariant && settlePlan ? [{
|
|
1451
|
+
id: settleId,
|
|
1452
|
+
type: "settle",
|
|
1453
|
+
source: emitSettleModule(settlePlan)
|
|
1454
|
+
}] : [],
|
|
1455
|
+
...(input.prerenderWakeVariant ? prerenderTriggerGroups : []).map((group, index) => ({
|
|
1456
|
+
id: triggerGroupVirtualModuleId(input.filename, index),
|
|
1457
|
+
type: "trigger-group",
|
|
1458
|
+
source: emitPrerenderTriggerGroupModule({
|
|
1459
|
+
group,
|
|
1460
|
+
symbols: uniqueSymbolsById([...input.symbols ?? [], ...symbolRows]),
|
|
1461
|
+
boundRows: importedBoundRows,
|
|
1462
|
+
symbolRoutes,
|
|
1463
|
+
armRendererModuleId: group.id === "self-wake" ? selfWakeArmRendererId : void 0
|
|
1464
|
+
})
|
|
1465
|
+
})),
|
|
1466
|
+
...selfWakeArmRendererId ? [{
|
|
1467
|
+
id: selfWakeArmRendererId,
|
|
1468
|
+
type: "trigger-group",
|
|
1469
|
+
source: emitPrerenderBoundaryRendererModule(renderDataId)
|
|
1470
|
+
}] : [],
|
|
1471
|
+
...linkedBoundarySymbols.map((symbol) => symbol.module),
|
|
1472
|
+
...await Promise.all(compiled.symbolModules.modules.map(async (module, index) => ({
|
|
1473
|
+
id: symbolVirtualModuleId(input.filename, module.symbolId),
|
|
1474
|
+
type: "symbol",
|
|
1475
|
+
symbolId: module.symbolId,
|
|
1476
|
+
exportName: symbolRows[index].exportName,
|
|
1477
|
+
source: injectExecutionLogModuleHook(await stripEmittedTypes(rewriteSymbolModuleExport(module.source, module.exportName, symbolRows[index].exportName)), `symbol:${module.symbolId}`, executionLogModuleHookMode)
|
|
1478
|
+
})))
|
|
1479
|
+
];
|
|
1480
|
+
const styleImport = styleId ? `import ${JSON.stringify(styleId)};\n` : "";
|
|
1481
|
+
const inlineResumerSources = (input.environment ?? "lib") === "client" ? void 0 : await compileInlineResumerSources({
|
|
1482
|
+
debug: input.inlineResumerDebug === true,
|
|
1483
|
+
executionLog: input.executionLog ?? "never"
|
|
1484
|
+
});
|
|
1485
|
+
const headInjections = [...input.headInjections ?? [], ...styleId && input.styleModuleUrl ? [{
|
|
1486
|
+
tag: "link",
|
|
1487
|
+
location: "head",
|
|
1488
|
+
attributes: {
|
|
1489
|
+
rel: "stylesheet",
|
|
1490
|
+
href: input.styleModuleUrl(styleId)
|
|
1491
|
+
}
|
|
1492
|
+
}] : []];
|
|
1493
|
+
const storageSeeds = compiled.payloadArena.state.storage.map((storage) => {
|
|
1494
|
+
const binding = compiled.semanticGraph.graphBindings.find((candidate) => candidate.id === storage.graphNodeId);
|
|
1495
|
+
if (typeof binding?.initialValue !== "string") throw new Error(`MARKLESS_STORAGE_SEED_FALLBACK_MISSING: ${storage.graphNodeId} has no static string fallback.`);
|
|
1496
|
+
return createStorageSeedMetadataFromGraphNodeId(storage.graphNodeId, storage.key, binding.initialValue);
|
|
1497
|
+
});
|
|
1498
|
+
return {
|
|
1499
|
+
code: styleImport + await stripEmittedTypes(emitSourceModule({
|
|
1500
|
+
filename: input.filename,
|
|
1501
|
+
dev: input.dev,
|
|
1502
|
+
payloadId,
|
|
1503
|
+
resolverId,
|
|
1504
|
+
renderDataId,
|
|
1505
|
+
environment: input.environment ?? "lib",
|
|
1506
|
+
clientOutput: input.clientOutput ?? "full",
|
|
1507
|
+
executionLog: input.executionLog,
|
|
1508
|
+
headInjections: headInjections.length > 0 ? headInjections : void 0,
|
|
1509
|
+
storageSeeds: storageSeeds.length > 0 ? storageSeeds : void 0,
|
|
1510
|
+
inlineResumerSources,
|
|
1511
|
+
prerenderBoot,
|
|
1512
|
+
devResumeReexport: input.devResumeReexport === true,
|
|
1513
|
+
needsFullResume: prerenderClosureNeedsWake,
|
|
1514
|
+
prerenderRecords: input.prerenderRecords,
|
|
1515
|
+
directCsr: input.directCsr,
|
|
1516
|
+
resumeModuleUrl: input.resumeModuleUrl,
|
|
1517
|
+
prerenderWakeModuleUrl: input.prerenderWakeModuleUrl,
|
|
1518
|
+
publicRenderModuleSource: compiled.publicRenderModule.moduleSource,
|
|
1519
|
+
publicRenderRootExportName: compiled.publicRenderModule.rootExportName,
|
|
1520
|
+
publicSsrModuleSource: compiled.publicRenderModule.ssrModuleSource,
|
|
1521
|
+
publicRenderSsrExportName: compiled.publicRenderModule.ssrExportName,
|
|
1522
|
+
canonicalRenderData: prerenderInterfacesComplete(compiled, input),
|
|
1523
|
+
hasBoundSymbols: compiled.boundSymbolResolver.rows.length > 0,
|
|
1524
|
+
symbols: symbolRows,
|
|
1525
|
+
behaviorSymbols,
|
|
1526
|
+
symbolRoutes
|
|
1527
|
+
})),
|
|
1528
|
+
map: null,
|
|
1529
|
+
virtualModules,
|
|
1530
|
+
manifest,
|
|
1531
|
+
moduleGraphInterface: compiled.moduleGraphInterface,
|
|
1532
|
+
interfaceHash: moduleInterfaceHash(compiled.moduleGraphInterface),
|
|
1533
|
+
moduleImports: compiled.semanticGraph.moduleImports,
|
|
1534
|
+
artifactChildren: artifactChildCandidates(compiled)
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
function linkedRenderDataBoundarySymbols(input) {
|
|
1538
|
+
if (input.input.environment !== "client" || !input.compiled.publicRenderModule.renderDataModuleSource || !prerenderInterfacesComplete(input.compiled, input.input)) return [];
|
|
1539
|
+
const emittedSymbolIds = new Set(input.compiled.symbolModules.modules.map((module) => module.symbolId));
|
|
1540
|
+
const plannedSymbols = new Map(input.compiled.symbolResolver.symbols.map((symbol) => [symbol.id, symbol]));
|
|
1541
|
+
const routes = input.compiled.semanticGraph.componentEdges.flatMap((edge, index) => edge.importSource && !input.input.artifactChildMaterializations?.[edge.id] ? [{
|
|
1542
|
+
prefix: `c${index}:`,
|
|
1543
|
+
importSource: edge.importSource
|
|
1544
|
+
}] : []);
|
|
1545
|
+
return input.compiled.protocolView.asyncBoundaries.flatMap((boundary, index) => {
|
|
1546
|
+
const symbolId = boundary.updateSymbolId;
|
|
1547
|
+
if (!symbolId || emittedSymbolIds.has(symbolId)) return [];
|
|
1548
|
+
if (plannedSymbols.get(symbolId)?.kind !== "async-boundary-update") return [];
|
|
1549
|
+
const virtualModuleId = symbolVirtualModuleId(input.input.filename, symbolId);
|
|
1550
|
+
const exportName = scopedSymbolExportName(input.input.filename, `marklessLinkedBoundaryUpdate${index}`);
|
|
1551
|
+
return [{
|
|
1552
|
+
row: {
|
|
1553
|
+
id: symbolId,
|
|
1554
|
+
chunk: virtualModuleId,
|
|
1555
|
+
exportName
|
|
1556
|
+
},
|
|
1557
|
+
manifest: {
|
|
1558
|
+
symbolId,
|
|
1559
|
+
kind: "async-boundary-update",
|
|
1560
|
+
exportName,
|
|
1561
|
+
virtualModuleId
|
|
1562
|
+
},
|
|
1563
|
+
module: {
|
|
1564
|
+
id: virtualModuleId,
|
|
1565
|
+
type: "symbol",
|
|
1566
|
+
symbolId,
|
|
1567
|
+
exportName,
|
|
1568
|
+
source: linkedRenderDataBoundarySymbolSource({
|
|
1569
|
+
boundaryId: boundary.id,
|
|
1570
|
+
exportName,
|
|
1571
|
+
renderDataId: input.renderDataId,
|
|
1572
|
+
resolverId: input.resolverId,
|
|
1573
|
+
routes
|
|
1574
|
+
})
|
|
1575
|
+
}
|
|
1576
|
+
}];
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
function linkedRenderDataBoundarySymbolSource(input) {
|
|
1580
|
+
return [
|
|
1581
|
+
`import { marklessPrerenderData } from ${JSON.stringify(input.renderDataId)};`,
|
|
1582
|
+
`import { loadSymbol as marklessLoadLocalSymbol } from ${JSON.stringify(input.resolverId)};`,
|
|
1583
|
+
"import { renderPrerenderBoundary } from '@markless/web/fns/prerender-resume';",
|
|
1584
|
+
"function marklessLoadLinkedSymbol(symbolId) {",
|
|
1585
|
+
...input.routes.flatMap((route) => [
|
|
1586
|
+
`\tif (symbolId.startsWith(${JSON.stringify(route.prefix)})) {`,
|
|
1587
|
+
`\t\treturn import(${JSON.stringify(linkedRenderDataSymbolRouteSource(route.importSource))}).then((module) => module.loadSymbol(symbolId.slice(${route.prefix.length})));`,
|
|
1588
|
+
" }"
|
|
1589
|
+
]),
|
|
1590
|
+
" return marklessLoadLocalSymbol(symbolId);",
|
|
1591
|
+
"}",
|
|
1592
|
+
`export async function ${input.exportName}(context) {`,
|
|
1593
|
+
`\tconst rendered = await renderPrerenderBoundary(marklessPrerenderData, ${JSON.stringify(input.boundaryId)}, context.status, context.graph, marklessLoadLinkedSymbol);`,
|
|
1594
|
+
" return { ...rendered, arm: context.status === \"rejected\" ? 2 : 0 };",
|
|
1595
|
+
"}"
|
|
1596
|
+
].join("\n");
|
|
1597
|
+
}
|
|
1598
|
+
function linkedRenderDataSymbolRouteSource(importSource) {
|
|
1599
|
+
return importSource.includes("?") ? `${importSource}&markless-symbols` : `${importSource}?markless-symbols`;
|
|
1600
|
+
}
|
|
1601
|
+
function prerenderInterfacesComplete(compiled, input) {
|
|
1602
|
+
return compiled.semanticGraph.componentEdges.every((edge) => !edge.importSource || input.artifactChildMaterializations?.[edge.id] !== void 0 || input.importedModuleInterfaces?.[edge.importSource] !== void 0);
|
|
1603
|
+
}
|
|
1604
|
+
function artifactChildCandidates(compiled) {
|
|
1605
|
+
const definitions = compiled.publicRenderModule.componentDefinitions;
|
|
1606
|
+
const definitionsByEdge = new Map(definitions.flatMap((definition) => (definition.edges ?? []).map((edge) => [edge.id, edge])));
|
|
1607
|
+
return compiled.semanticGraph.componentEdges.flatMap((edge) => {
|
|
1608
|
+
if (!edge.importSource || !edge.importKind) return [];
|
|
1609
|
+
const definition = definitionsByEdge.get(edge.id);
|
|
1610
|
+
return definition ? [{
|
|
1611
|
+
edgeId: edge.id,
|
|
1612
|
+
componentName: edge.childComponentName,
|
|
1613
|
+
importSource: edge.importSource,
|
|
1614
|
+
importKind: edge.importKind,
|
|
1615
|
+
...edge.importedName ? { importedName: edge.importedName } : {},
|
|
1616
|
+
hasChildren: edge.children.childCount > 0,
|
|
1617
|
+
props: definition.props,
|
|
1618
|
+
...definition.projection ? { projection: definition.projection } : {}
|
|
1619
|
+
}] : [];
|
|
1620
|
+
});
|
|
1621
|
+
}
|
|
1622
|
+
function resolveAuthoredSpecifier(specifier, sourceFilename) {
|
|
1623
|
+
if (!specifier.startsWith(".")) return specifier;
|
|
1624
|
+
if (!isAbsolute(sourceFilename)) throw new Error(`MARKLESS_RENDER_DATA_READER_SPECIFIER_UNRESOLVABLE: ${JSON.stringify(specifier)} needs an absolute module filename, got ${JSON.stringify(sourceFilename)}.`);
|
|
1625
|
+
return resolve(dirname(sourceFilename), specifier);
|
|
1626
|
+
}
|
|
1627
|
+
function prerenderDataModuleSource(compiled, importedModuleInterfaces, renderDataImportSources, artifactChildMaterializations, sourceFilename) {
|
|
1628
|
+
const importedComponents = /* @__PURE__ */ new Map();
|
|
1629
|
+
for (const edge of compiled.semanticGraph.componentEdges) {
|
|
1630
|
+
if (!edge.importSource || importedComponents.has(edge.childComponentName)) continue;
|
|
1631
|
+
if (artifactChildMaterializations?.[edge.id]) continue;
|
|
1632
|
+
const linked = importedModuleInterfaces?.[edge.importSource];
|
|
1633
|
+
if (!linked) throw new Error(`MARKLESS_PRERENDER_RENDER_DATA_MISSING: Imported child ${JSON.stringify(edge.childComponentName)} from ${JSON.stringify(edge.importSource)} has no linked render-data artifact.`);
|
|
1634
|
+
importedComponents.set(edge.childComponentName, {
|
|
1635
|
+
source: renderDataImportSources?.[edge.importSource] ?? `virtual:markless:render-data:${encodeURIComponent(linked.filename)}`,
|
|
1636
|
+
local: `marklessPrerenderImport${importedComponents.size}`
|
|
1637
|
+
});
|
|
1638
|
+
}
|
|
1639
|
+
const readerImports = /* @__PURE__ */ new Map();
|
|
1640
|
+
const readerDeclarations = /* @__PURE__ */ new Set();
|
|
1641
|
+
const componentEntries = compiled.publicRenderModule.componentDefinitions.map((definition) => {
|
|
1642
|
+
const { residueReaderSource, residueReaderImports, residueReaderDeclarations, ...record } = definition;
|
|
1643
|
+
for (const entry of residueReaderImports ?? []) readerImports.set(entry.line, entry.line.replace(JSON.stringify(entry.source), JSON.stringify(resolveAuthoredSpecifier(entry.source, sourceFilename))));
|
|
1644
|
+
for (const line of residueReaderDeclarations ?? []) readerDeclarations.add(line);
|
|
1645
|
+
const data = JSON.stringify(record);
|
|
1646
|
+
return `${JSON.stringify(String(definition.name))}:${residueReaderSource ? `{...${data},readResidue:${residueReaderSource}}` : data}`;
|
|
1647
|
+
});
|
|
1648
|
+
const preludes = [...readerImports.values(), ...readerDeclarations];
|
|
1649
|
+
return [
|
|
1650
|
+
...[...importedComponents.values()].map((entry) => `import { marklessPrerenderData as ${entry.local} } from ${JSON.stringify(entry.source)};`),
|
|
1651
|
+
...preludes,
|
|
1652
|
+
compiled.publicRenderModule.renderDataModuleSource,
|
|
1653
|
+
`const marklessPrerenderComponents = {${componentEntries.join(",")}};`,
|
|
1654
|
+
"export const marklessPrerenderData = {",
|
|
1655
|
+
`\trootComponentName: ${JSON.stringify(compiled.renderData.root?.componentName ?? null)},`,
|
|
1656
|
+
" renderData: marklessRenderData,",
|
|
1657
|
+
" components: marklessPrerenderComponents,",
|
|
1658
|
+
`\timports: {${[...importedComponents].map(([name, entry]) => `${JSON.stringify(name)}:${entry.local}`).join(",")}},`,
|
|
1659
|
+
"};"
|
|
1660
|
+
].join("\n");
|
|
1661
|
+
}
|
|
1662
|
+
async function compileTsrxModuleLinkArtifact(input) {
|
|
1663
|
+
const compiled = await compileTsrxModule({
|
|
1664
|
+
filename: input.filename,
|
|
1665
|
+
source: input.source,
|
|
1666
|
+
buildId: input.buildId,
|
|
1667
|
+
symbols: []
|
|
1668
|
+
});
|
|
1669
|
+
return {
|
|
1670
|
+
moduleGraphInterface: compiled.moduleGraphInterface,
|
|
1671
|
+
interfaceHash: moduleInterfaceHash(compiled.moduleGraphInterface),
|
|
1672
|
+
moduleImports: compiled.semanticGraph.moduleImports
|
|
1673
|
+
};
|
|
1674
|
+
}
|
|
1675
|
+
function moduleInterfaceHash(value) {
|
|
1676
|
+
let hash = 2166136261;
|
|
1677
|
+
const source = JSON.stringify(value ?? null);
|
|
1678
|
+
for (let index = 0; index < source.length; index++) {
|
|
1679
|
+
hash ^= source.charCodeAt(index);
|
|
1680
|
+
hash = Math.imul(hash, 16777619);
|
|
1681
|
+
}
|
|
1682
|
+
return `mgi1-${(hash >>> 0).toString(36)}`;
|
|
1683
|
+
}
|
|
1684
|
+
async function preflightTsrxModuleDiagnostics(input) {
|
|
1685
|
+
const { blockingDiagnostics } = await compileWithBlockingDiagnostics(input, `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodeURIComponent(input.filename)}`);
|
|
1686
|
+
throwIfBlocked(input, blockingDiagnostics);
|
|
1687
|
+
}
|
|
1688
|
+
async function compileWithBlockingDiagnostics(input, resolverId) {
|
|
1689
|
+
const compiled = await compileTsrxModule({
|
|
1690
|
+
filename: input.filename,
|
|
1691
|
+
source: input.source,
|
|
1692
|
+
buildId: input.buildId,
|
|
1693
|
+
resolverId,
|
|
1694
|
+
symbols: input.symbols ?? [],
|
|
1695
|
+
importedModuleInterfaces: input.importedModuleInterfaces,
|
|
1696
|
+
artifactChildMaterializations: input.artifactChildMaterializations,
|
|
1697
|
+
omitAuthoredSource: normalizeExecutionLogMode(input.executionLog) === "never"
|
|
1698
|
+
});
|
|
1699
|
+
return {
|
|
1700
|
+
compiled,
|
|
1701
|
+
blockingDiagnostics: collectTsrxModuleDiagnostics(compiled).filter((diagnostic) => diagnostic.severity === "error")
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
function throwIfBlocked(input, blockingDiagnostics) {
|
|
1705
|
+
if (blockingDiagnostics.length === 0) return;
|
|
1706
|
+
const details = formatBlockedCompileError(input, blockingDiagnostics);
|
|
1707
|
+
throw new MarklessCompileError(createCompileErrorPayload({
|
|
1708
|
+
filename: input.filename,
|
|
1709
|
+
source: input.source,
|
|
1710
|
+
diagnostics: blockingDiagnostics,
|
|
1711
|
+
details
|
|
1712
|
+
}));
|
|
1713
|
+
}
|
|
1714
|
+
function formatBlockedCompileError(input, diagnostics) {
|
|
1715
|
+
return [`MARKLESS_COMPILE_BLOCKED: ${input.filename} has ${diagnostics.length} compiler error(s).`, ...diagnostics.map((diagnostic) => {
|
|
1716
|
+
const position = diagnostic.primarySpan ? formatSourcePosition(input.source, diagnostic.primarySpan.start) : void 0;
|
|
1717
|
+
const location = position ? ` (${diagnostic.primarySpan.filename}:${position.line}:${position.column})` : "";
|
|
1718
|
+
return [
|
|
1719
|
+
`${diagnostic.code}: ${diagnostic.message}${location}`,
|
|
1720
|
+
diagnostic.why,
|
|
1721
|
+
diagnostic.suggestions[0]?.message,
|
|
1722
|
+
diagnostic.docsUrl
|
|
1723
|
+
].filter((line) => Boolean(line)).join("\n");
|
|
1724
|
+
})].join("\n\n");
|
|
1725
|
+
}
|
|
1726
|
+
function formatSourcePosition(source, start) {
|
|
1727
|
+
const sourceBeforeSpan = source.slice(0, start);
|
|
1728
|
+
const lastLineBreak = sourceBeforeSpan.lastIndexOf("\n");
|
|
1729
|
+
return {
|
|
1730
|
+
line: sourceBeforeSpan.split("\n").length,
|
|
1731
|
+
column: sourceBeforeSpan.length - lastLineBreak
|
|
1732
|
+
};
|
|
1733
|
+
}
|
|
1734
|
+
function uniqueSymbolsById(symbols) {
|
|
1735
|
+
return [...new Map(symbols.map((symbol) => [symbol.id, symbol])).values()];
|
|
1736
|
+
}
|
|
1737
|
+
function containerScopedResumeView(view) {
|
|
1738
|
+
return {
|
|
1739
|
+
...view,
|
|
1740
|
+
locators: (view.locators ?? []).map((locator) => ({
|
|
1741
|
+
...locator,
|
|
1742
|
+
index: locator.index + 1
|
|
1743
|
+
}))
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
function needsFullResume(state, _view, runtimeDemandMap) {
|
|
1747
|
+
if ((state.storage?.length ?? 0) > 0) return true;
|
|
1748
|
+
return runtimeDemandMap.payloadRecords.some((record) => RECORD_NEEDS_FULL_RESUME[record.kind](runtimeDemandMap));
|
|
1749
|
+
}
|
|
1750
|
+
const RECORD_NEEDS_FULL_RESUME = {
|
|
1751
|
+
"async-boundary": () => true,
|
|
1752
|
+
behavior: () => false,
|
|
1753
|
+
branch: () => true,
|
|
1754
|
+
"dom-update": () => false,
|
|
1755
|
+
"element-handle": () => true,
|
|
1756
|
+
[PROTOCOL_EVENT_ACTION_KIND.event]: () => false,
|
|
1757
|
+
[PROTOCOL_EVENT_ACTION_KIND.externalDelegate]: () => false,
|
|
1758
|
+
"keyed-repeat": (runtimeDemandMap) => !recordKindReplaced(runtimeDemandMap, "keyed-repeat")
|
|
1759
|
+
};
|
|
1760
|
+
function recordKindReplaced(runtimeDemandMap, kind) {
|
|
1761
|
+
return runtimeDemandMap.recordKinds.some((record) => record.kind === kind && record.replaced === true);
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* What the settle module must import, and what the document must carry to use
|
|
1765
|
+
* it. Fails closed: a boundary whose runner symbol or whose bound base symbol
|
|
1766
|
+
* is not in this page's symbol rows produces no settle module at all, so the
|
|
1767
|
+
* page keeps the self-wake path rather than half a settle.
|
|
1768
|
+
*/
|
|
1769
|
+
function planSettleModule(input) {
|
|
1770
|
+
const symbolById = new Map(input.symbols.map((symbol) => [symbol.id, symbol]));
|
|
1771
|
+
const runners = [];
|
|
1772
|
+
const derives = [];
|
|
1773
|
+
const bound = {};
|
|
1774
|
+
for (const boundary of input.boundaries ?? []) {
|
|
1775
|
+
const node = boundary.runnerGraphNodeId;
|
|
1776
|
+
if (!node || !boundary.protocolSupported) continue;
|
|
1777
|
+
const runner = symbolById.get(input.asyncRunners?.[node] ?? "");
|
|
1778
|
+
if (!runner) continue;
|
|
1779
|
+
const rows = (input.descriptors?.[boundary.boundaryId] ?? []).map((descriptor) => ({
|
|
1780
|
+
descriptor,
|
|
1781
|
+
symbol: symbolById.get(descriptor.base)
|
|
1782
|
+
}));
|
|
1783
|
+
if (rows.some((row) => !row.symbol)) continue;
|
|
1784
|
+
runners.push({
|
|
1785
|
+
node,
|
|
1786
|
+
symbol: runner
|
|
1787
|
+
});
|
|
1788
|
+
for (const row of rows) {
|
|
1789
|
+
derives.push({
|
|
1790
|
+
id: row.descriptor.id,
|
|
1791
|
+
symbol: row.symbol
|
|
1792
|
+
});
|
|
1793
|
+
bound[boundary.boundaryId] = {
|
|
1794
|
+
...bound[boundary.boundaryId],
|
|
1795
|
+
[row.descriptor.id]: Object.fromEntries(row.descriptor.slots.map((slot) => [`${slot[0]}|${slot[1].join(".")}`, [slot[2], slot[3]]]))
|
|
1796
|
+
};
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
return runners.length > 0 ? {
|
|
1800
|
+
runners,
|
|
1801
|
+
derives,
|
|
1802
|
+
bound
|
|
1803
|
+
} : void 0;
|
|
1804
|
+
}
|
|
1805
|
+
function perBoundaryBoundSymbolDescriptors(renderData, boundRows) {
|
|
1806
|
+
if (boundRows.length === 0) return void 0;
|
|
1807
|
+
const chunks = new Map(renderData.chunks.map((chunk) => [chunk.id, chunk]));
|
|
1808
|
+
const descriptors = {};
|
|
1809
|
+
for (const boundary of renderData.boundaries) {
|
|
1810
|
+
const edges = componentEdgesReachableFrom(chunks, boundary.armChunkIds.try);
|
|
1811
|
+
const rows = boundRows.filter((row) => row.ancestry.some((step) => edges.has(step.componentEdgeId)));
|
|
1812
|
+
if (rows.length === 0) continue;
|
|
1813
|
+
descriptors[boundary.boundaryId] = rows.map((row) => ({
|
|
1814
|
+
id: row.id,
|
|
1815
|
+
base: row.baseSymbolId,
|
|
1816
|
+
slots: row.captureSlots.flatMap((slot) => slot.legacyGraphRead && slot.route.kind === "graph-reference" ? [[
|
|
1817
|
+
slot.legacyGraphRead.graphNodeId,
|
|
1818
|
+
slot.legacyGraphRead.path,
|
|
1819
|
+
slot.route.graphNodeId,
|
|
1820
|
+
slot.route.path
|
|
1821
|
+
]] : [])
|
|
1822
|
+
}));
|
|
1823
|
+
}
|
|
1824
|
+
return Object.keys(descriptors).length > 0 ? descriptors : void 0;
|
|
1825
|
+
}
|
|
1826
|
+
function componentEdgesReachableFrom(chunks, rootChunkId) {
|
|
1827
|
+
const edges = /* @__PURE__ */ new Set();
|
|
1828
|
+
const pending = [rootChunkId];
|
|
1829
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1830
|
+
while (pending.length > 0) {
|
|
1831
|
+
const id = pending.pop();
|
|
1832
|
+
if (visited.has(id)) continue;
|
|
1833
|
+
visited.add(id);
|
|
1834
|
+
for (const slot of chunks.get(id)?.slots ?? []) if (slot.kind === "child-component") {
|
|
1835
|
+
edges.add(slot.componentEdgeId);
|
|
1836
|
+
pending.push(slot.childTemplateId);
|
|
1837
|
+
if (slot.projectionChunkId) pending.push(slot.projectionChunkId);
|
|
1838
|
+
} else if (slot.kind === "repeat") {
|
|
1839
|
+
pending.push(slot.rowTemplateId);
|
|
1840
|
+
if (slot.emptyTemplateId) pending.push(slot.emptyTemplateId);
|
|
1841
|
+
} else if (slot.kind === "branch") pending.push(...slot.armTemplateIds);
|
|
1842
|
+
}
|
|
1843
|
+
return edges;
|
|
1844
|
+
}
|
|
1845
|
+
//#endregion
|
|
1846
|
+
//#region src/build/symbol-table.ts
|
|
1847
|
+
const SYMBOL_VIRTUAL_PREFIX = `${MARKLESS_VIRTUAL_PREFIX}symbol:`;
|
|
1848
|
+
const PACKED_SYMBOL_VIRTUAL_LIST_RE = /(["'`])((?:virtual:markless:symbol:)[^"'`]+)\1\.split\(\s*(["'`]),\3\s*\)/g;
|
|
1849
|
+
const SYMBOL_VIRTUAL_STRING_RE$1 = /(["'`])((?:virtual:markless:symbol:)[^"'`]+)\1/g;
|
|
1850
|
+
const STRING_LIST_SOURCE = String.raw`(?:\[[^\]]*\]|["'\x60][^"'\x60]*["'\x60]\.split\(\s*["'\x60][^"'\x60]*["'\x60]\s*\))`;
|
|
1851
|
+
const SYMBOL_MANIFEST_TUPLE_RE = new RegExp(String.raw`(\[1,(?:null|["'\x60][^"'\x60]*["'\x60]),(?:null|["'\x60][^"'\x60]*["'\x60]),)(${STRING_LIST_SOURCE}),(${STRING_LIST_SOURCE}),(\{[^}]*\})(\])`, "g");
|
|
1852
|
+
const STRING_LITERAL_RE = /(["'`])([^"'`]*)\1/g;
|
|
1853
|
+
const SYMBOL_ROW_RE = /((?:["'`][^"'`]*["'`])\s*:\s*\[)(\d+)(,\s*\d+\])/g;
|
|
1854
|
+
const SYMBOL_ROW_CAPTURE_RE = /(["'`])([^"'`]*)\1\s*:\s*\[(\d+),\s*(\d+)\]/g;
|
|
1855
|
+
function rewriteGeneratedSymbolTableUrls(bundle) {
|
|
1856
|
+
const chunks = collectChunks$1(bundle);
|
|
1857
|
+
const symbolFiles = collectGeneratedSymbolFiles(chunks);
|
|
1858
|
+
let rewritten = 0;
|
|
1859
|
+
const unresolved = /* @__PURE__ */ new Set();
|
|
1860
|
+
for (const chunk of chunks.values()) {
|
|
1861
|
+
if (!chunk.code.includes(SYMBOL_VIRTUAL_PREFIX)) continue;
|
|
1862
|
+
const result = rewriteSymbolVirtualStrings(chunk, symbolFiles);
|
|
1863
|
+
chunk.code = result.code;
|
|
1864
|
+
rewritten += result.rewritten;
|
|
1865
|
+
for (const id of result.unresolved) unresolved.add(id);
|
|
1866
|
+
}
|
|
1867
|
+
return {
|
|
1868
|
+
rewritten,
|
|
1869
|
+
unresolved: [...unresolved].sort()
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Returns the final chunk routes encoded in generated symbol tables. These
|
|
1874
|
+
* routes feed computed import() calls, so bundler dynamic-import metadata and
|
|
1875
|
+
* a plain import-expression scan cannot observe them.
|
|
1876
|
+
*/
|
|
1877
|
+
function scanGeneratedSymbolTableImports(code, chunkFileName) {
|
|
1878
|
+
const imports = /* @__PURE__ */ new Set();
|
|
1879
|
+
for (const match of code.matchAll(SYMBOL_MANIFEST_TUPLE_RE)) for (const specifier of parseStringList(match[2]) ?? []) if (specifier.startsWith(".")) imports.add(resolveChunkSpecifier$1(chunkFileName, specifier));
|
|
1880
|
+
return [...imports];
|
|
1881
|
+
}
|
|
1882
|
+
/**
|
|
1883
|
+
* Checks emitted resolver routes against compiler manifests and Rolldown's
|
|
1884
|
+
* chunk ownership/export metadata. Table source is read only to recover each
|
|
1885
|
+
* claimed file; termination evidence stays structural.
|
|
1886
|
+
*/
|
|
1887
|
+
function verifyGeneratedSymbolTableRoutes(bundle, manifests) {
|
|
1888
|
+
const chunks = collectChunks$1(bundle);
|
|
1889
|
+
const errors = [];
|
|
1890
|
+
let verified = 0;
|
|
1891
|
+
for (const manifest of manifests) {
|
|
1892
|
+
if (manifest.symbols.length === 0) continue;
|
|
1893
|
+
const resolverChunk = findResolverRouteChunk(chunks, manifest.resolver.virtualModuleId, manifest.symbols);
|
|
1894
|
+
const routeChunk = resolverChunk ?? findChunkForVirtualId(chunks, manifest.source);
|
|
1895
|
+
if (!routeChunk) {
|
|
1896
|
+
for (const symbol of manifest.symbols) errors.push({
|
|
1897
|
+
symbolId: symbol.symbolId,
|
|
1898
|
+
claimedChunk: "<missing route chunk>",
|
|
1899
|
+
reason: `neither compiler resolver ${manifest.resolver.virtualModuleId} nor source ${manifest.source} was emitted`
|
|
1900
|
+
});
|
|
1901
|
+
continue;
|
|
1902
|
+
}
|
|
1903
|
+
const table = resolverChunk ? findSymbolTable(routeChunk.code, manifest.symbols) : void 0;
|
|
1904
|
+
for (const symbol of manifest.symbols) {
|
|
1905
|
+
if (!table) {
|
|
1906
|
+
const directRoute = verifyDirectRoute(chunks, routeChunk, symbol);
|
|
1907
|
+
if (directRoute.reason) errors.push({
|
|
1908
|
+
symbolId: symbol.symbolId,
|
|
1909
|
+
claimedChunk: directRoute.claimedChunk,
|
|
1910
|
+
reason: directRoute.reason
|
|
1911
|
+
});
|
|
1912
|
+
else verified++;
|
|
1913
|
+
continue;
|
|
1914
|
+
}
|
|
1915
|
+
const specifier = tableRouteSpecifier(table, symbol, routeChunk.fileName, errors);
|
|
1916
|
+
if (!specifier) continue;
|
|
1917
|
+
const claimedChunk = resolveChunkSpecifier$1(routeChunk.fileName, specifier);
|
|
1918
|
+
const reason = routeTerminationError(chunks, claimedChunk, symbol);
|
|
1919
|
+
if (reason) errors.push({
|
|
1920
|
+
symbolId: symbol.symbolId,
|
|
1921
|
+
claimedChunk,
|
|
1922
|
+
reason
|
|
1923
|
+
});
|
|
1924
|
+
else verified++;
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
return {
|
|
1928
|
+
verified,
|
|
1929
|
+
errors
|
|
1930
|
+
};
|
|
1931
|
+
}
|
|
1932
|
+
function collectChunks$1(bundle) {
|
|
1933
|
+
const chunks = /* @__PURE__ */ new Map();
|
|
1934
|
+
for (const output of Object.values(bundle)) if (isGeneratedChunk$1(output)) chunks.set(output.fileName, output);
|
|
1935
|
+
return chunks;
|
|
1936
|
+
}
|
|
1937
|
+
function collectGeneratedSymbolFiles(chunks) {
|
|
1938
|
+
const symbolFiles = /* @__PURE__ */ new Map();
|
|
1939
|
+
for (const chunk of chunks.values()) {
|
|
1940
|
+
const facadeId = chunk.facadeModuleId ? normalizeVirtualId$2(chunk.facadeModuleId) : void 0;
|
|
1941
|
+
if (facadeId?.startsWith(SYMBOL_VIRTUAL_PREFIX)) symbolFiles.set(facadeId, chunk.fileName);
|
|
1942
|
+
}
|
|
1943
|
+
for (const chunk of chunks.values()) for (const id of chunk.moduleIds.map(normalizeVirtualId$2)) if (id.startsWith(SYMBOL_VIRTUAL_PREFIX) && !symbolFiles.has(id)) symbolFiles.set(id, chunk.fileName);
|
|
1944
|
+
return symbolFiles;
|
|
1945
|
+
}
|
|
1946
|
+
function findSymbolTable(code, symbols) {
|
|
1947
|
+
let bestMatch;
|
|
1948
|
+
let bestScore = -1;
|
|
1949
|
+
for (const match of code.matchAll(SYMBOL_MANIFEST_TUPLE_RE)) {
|
|
1950
|
+
const moduleUrls = parseStringList(match[2]);
|
|
1951
|
+
const exportNames = parseStringList(match[3]);
|
|
1952
|
+
if (!moduleUrls || !exportNames) continue;
|
|
1953
|
+
const rows = /* @__PURE__ */ new Map();
|
|
1954
|
+
for (const row of match[4].matchAll(SYMBOL_ROW_CAPTURE_RE)) rows.set(row[2], [Number(row[3]), Number(row[4])]);
|
|
1955
|
+
if (rows.size === 0) continue;
|
|
1956
|
+
const score = symbols.filter((symbol) => exportNames.includes(symbol.exportName)).length;
|
|
1957
|
+
if (score > bestScore) {
|
|
1958
|
+
bestMatch = {
|
|
1959
|
+
moduleUrls,
|
|
1960
|
+
exportNames,
|
|
1961
|
+
rows
|
|
1962
|
+
};
|
|
1963
|
+
bestScore = score;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
return bestMatch;
|
|
1967
|
+
}
|
|
1968
|
+
function tableRouteSpecifier(table, symbol, resolverFileName, errors) {
|
|
1969
|
+
const row = table.rows.get(symbol.symbolId);
|
|
1970
|
+
if (!row) {
|
|
1971
|
+
errors.push({
|
|
1972
|
+
symbolId: symbol.symbolId,
|
|
1973
|
+
claimedChunk: resolverFileName,
|
|
1974
|
+
reason: "emitted symbol table has no row for this compiler symbol"
|
|
1975
|
+
});
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
const specifier = table.moduleUrls[row[0]];
|
|
1979
|
+
if (!specifier) {
|
|
1980
|
+
errors.push({
|
|
1981
|
+
symbolId: symbol.symbolId,
|
|
1982
|
+
claimedChunk: resolverFileName,
|
|
1983
|
+
reason: `emitted symbol table references missing module URL index ${row[0]}`
|
|
1984
|
+
});
|
|
1985
|
+
return;
|
|
1986
|
+
}
|
|
1987
|
+
const exportName = table.exportNames[row[1]];
|
|
1988
|
+
if (exportName !== symbol.exportName) {
|
|
1989
|
+
errors.push({
|
|
1990
|
+
symbolId: symbol.symbolId,
|
|
1991
|
+
claimedChunk: resolveChunkSpecifier$1(resolverFileName, specifier),
|
|
1992
|
+
reason: `emitted symbol table claims export ${exportName ?? `<missing index ${row[1]}>`} instead of ${symbol.exportName}`
|
|
1993
|
+
});
|
|
1994
|
+
return;
|
|
1995
|
+
}
|
|
1996
|
+
return specifier;
|
|
1997
|
+
}
|
|
1998
|
+
function verifyDirectRoute(chunks, routeChunk, symbol) {
|
|
1999
|
+
const target = findChunkForVirtualId(chunks, symbol.virtualModuleId);
|
|
2000
|
+
if (!target) return {
|
|
2001
|
+
claimedChunk: "<missing symbol chunk>",
|
|
2002
|
+
reason: `generated symbol module ${symbol.virtualModuleId} was not emitted`
|
|
2003
|
+
};
|
|
2004
|
+
if (!(target.exports ?? []).includes(symbol.exportName)) return {
|
|
2005
|
+
claimedChunk: target.fileName,
|
|
2006
|
+
reason: `claimed chunk does not export ${symbol.exportName}`
|
|
2007
|
+
};
|
|
2008
|
+
if (!dynamicRouteReachesChunk(chunks, routeChunk, target.fileName) && !rewrittenSpecifierRoutesTo(routeChunk, target.fileName)) return {
|
|
2009
|
+
claimedChunk: target.fileName,
|
|
2010
|
+
reason: `source chunk ${routeChunk.fileName} has no emitted dynamic route to the claimed chunk`
|
|
2011
|
+
};
|
|
2012
|
+
return { claimedChunk: target.fileName };
|
|
2013
|
+
}
|
|
2014
|
+
function rewrittenSpecifierRoutesTo(routeChunk, targetFileName) {
|
|
2015
|
+
const specifier = relativeChunkSpecifier$1(routeChunk.fileName, targetFileName);
|
|
2016
|
+
return routeChunk.code.includes(JSON.stringify(specifier)) || routeChunk.code.includes(`'${specifier}'`) || routeChunk.code.includes(`\`${specifier}\``);
|
|
2017
|
+
}
|
|
2018
|
+
function dynamicRouteReachesChunk(chunks, start, targetFileName) {
|
|
2019
|
+
const pending = [start];
|
|
2020
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2021
|
+
while (pending.length > 0) {
|
|
2022
|
+
const chunk = pending.shift();
|
|
2023
|
+
if (chunk.fileName === targetFileName) return true;
|
|
2024
|
+
if (visited.has(chunk.fileName)) continue;
|
|
2025
|
+
visited.add(chunk.fileName);
|
|
2026
|
+
for (const importedFileName of chunk.dynamicImports ?? []) {
|
|
2027
|
+
const imported = chunks.get(importedFileName);
|
|
2028
|
+
if (imported) pending.push(imported);
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
return false;
|
|
2032
|
+
}
|
|
2033
|
+
function routeTerminationError(chunks, claimedChunk, symbol) {
|
|
2034
|
+
const target = chunks.get(claimedChunk);
|
|
2035
|
+
if (!target) return "claimed chunk was not emitted. markless debugging playbook: run pnpm doctor, or read agent/markless.md in the installed @markless/core package";
|
|
2036
|
+
if (!chunkOrReexportChainContainsSymbol(chunks, target, normalizeVirtualId$2(symbol.virtualModuleId), symbol.exportName)) return `claimed chunk does not contain its generated symbol module ${symbol.virtualModuleId} or a live re-export chain to it. markless debugging playbook: run pnpm doctor, or read agent/markless.md in the installed @markless/core package`;
|
|
2037
|
+
if (!(target.exports ?? []).includes(symbol.exportName)) return `claimed chunk does not export ${symbol.exportName}. markless debugging playbook: run pnpm doctor, or read agent/markless.md in the installed @markless/core package`;
|
|
2038
|
+
}
|
|
2039
|
+
function chunkOrReexportChainContainsSymbol(chunks, start, virtualId, exportName) {
|
|
2040
|
+
const pending = [start];
|
|
2041
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2042
|
+
while (pending.length > 0) {
|
|
2043
|
+
const chunk = pending.shift();
|
|
2044
|
+
if (visited.has(chunk.fileName)) continue;
|
|
2045
|
+
visited.add(chunk.fileName);
|
|
2046
|
+
if (virtualIds(chunk).includes(virtualId) && (chunk.exports ?? []).includes(exportName)) return true;
|
|
2047
|
+
if (!(chunk.exports ?? []).includes(exportName)) continue;
|
|
2048
|
+
for (const importedFileName of chunk.imports ?? []) {
|
|
2049
|
+
const imported = chunks.get(importedFileName);
|
|
2050
|
+
if (imported && (imported.exports ?? []).includes(exportName)) pending.push(imported);
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
return false;
|
|
2054
|
+
}
|
|
2055
|
+
function findChunkForVirtualId(chunks, virtualId) {
|
|
2056
|
+
const normalized = normalizeVirtualId$2(virtualId);
|
|
2057
|
+
return [...chunks.values()].find((chunk) => !!chunk.facadeModuleId && normalizeVirtualId$2(chunk.facadeModuleId) === normalized) ?? [...chunks.values()].find((chunk) => chunk.moduleIds.map(normalizeVirtualId$2).includes(normalized));
|
|
2058
|
+
}
|
|
2059
|
+
function findResolverRouteChunk(chunks, virtualId, symbols) {
|
|
2060
|
+
const normalized = normalizeVirtualId$2(virtualId);
|
|
2061
|
+
const candidates = [...chunks.values()].filter((chunk) => virtualIds(chunk).includes(normalized));
|
|
2062
|
+
return candidates.find((chunk) => !!findSymbolTable(chunk.code, symbols)) ?? candidates.find((chunk) => chunk.moduleIds.map(normalizeVirtualId$2).includes(normalized)) ?? candidates[0];
|
|
2063
|
+
}
|
|
2064
|
+
function resolveChunkSpecifier$1(importerFileName, specifier) {
|
|
2065
|
+
if (!specifier.startsWith(".")) return normalize(specifier);
|
|
2066
|
+
return normalize(join(dirname(importerFileName), specifier));
|
|
2067
|
+
}
|
|
2068
|
+
function virtualIds(chunk) {
|
|
2069
|
+
return [chunk.facadeModuleId ?? void 0, ...chunk.moduleIds].filter((id) => !!id).map(normalizeVirtualId$2);
|
|
2070
|
+
}
|
|
2071
|
+
function rewriteSymbolVirtualStrings(chunk, symbolFiles) {
|
|
2072
|
+
let rewritten = 0;
|
|
2073
|
+
const unresolved = /* @__PURE__ */ new Set();
|
|
2074
|
+
return {
|
|
2075
|
+
code: compactSymbolManifestTables(chunk.code.replace(PACKED_SYMBOL_VIRTUAL_LIST_RE, (match, _quote, packedVirtualIds) => {
|
|
2076
|
+
const virtualIds = packedVirtualIds.split(",");
|
|
2077
|
+
if (virtualIds.length < 2 || virtualIds.some((id) => !id.startsWith(SYMBOL_VIRTUAL_PREFIX))) return match;
|
|
2078
|
+
return JSON.stringify(virtualIds.map((virtualId) => {
|
|
2079
|
+
const fileName = symbolFiles.get(virtualId);
|
|
2080
|
+
if (!fileName) return virtualId;
|
|
2081
|
+
rewritten++;
|
|
2082
|
+
return relativeChunkSpecifier$1(chunk.fileName, fileName);
|
|
2083
|
+
}));
|
|
2084
|
+
}).replace(SYMBOL_VIRTUAL_STRING_RE$1, (match, _quote, virtualId) => {
|
|
2085
|
+
const fileName = symbolFiles.get(virtualId);
|
|
2086
|
+
if (!fileName) {
|
|
2087
|
+
unresolved.add(virtualId);
|
|
2088
|
+
return match;
|
|
2089
|
+
}
|
|
2090
|
+
rewritten++;
|
|
2091
|
+
return JSON.stringify(relativeChunkSpecifier$1(chunk.fileName, fileName));
|
|
2092
|
+
})),
|
|
2093
|
+
rewritten,
|
|
2094
|
+
unresolved: [...unresolved]
|
|
2095
|
+
};
|
|
2096
|
+
}
|
|
2097
|
+
function compactSymbolManifestTables(code) {
|
|
2098
|
+
return code.replace(SYMBOL_MANIFEST_TUPLE_RE, (match, prefix, moduleUrlsSource, exportNamesSource, symbolRowsSource, suffix) => {
|
|
2099
|
+
const moduleUrls = parseStringArray(moduleUrlsSource);
|
|
2100
|
+
if (!moduleUrls) return match;
|
|
2101
|
+
const nextModuleUrls = [];
|
|
2102
|
+
const moduleIndexMap = /* @__PURE__ */ new Map();
|
|
2103
|
+
const seen = /* @__PURE__ */ new Map();
|
|
2104
|
+
for (const [index, moduleUrl] of moduleUrls.entries()) {
|
|
2105
|
+
let nextIndex = seen.get(moduleUrl);
|
|
2106
|
+
if (nextIndex === void 0) {
|
|
2107
|
+
nextIndex = nextModuleUrls.length;
|
|
2108
|
+
seen.set(moduleUrl, nextIndex);
|
|
2109
|
+
nextModuleUrls.push(moduleUrl);
|
|
2110
|
+
}
|
|
2111
|
+
moduleIndexMap.set(index, nextIndex);
|
|
2112
|
+
}
|
|
2113
|
+
if (nextModuleUrls.length === moduleUrls.length) return match;
|
|
2114
|
+
const nextSymbolRows = symbolRowsSource.replace(SYMBOL_ROW_RE, (rowMatch, rowPrefix, moduleIndexSource, rowSuffix) => {
|
|
2115
|
+
const moduleIndex = Number(moduleIndexSource);
|
|
2116
|
+
const nextModuleIndex = moduleIndexMap.get(moduleIndex);
|
|
2117
|
+
if (nextModuleIndex === void 0) return rowMatch;
|
|
2118
|
+
return `${rowPrefix}${nextModuleIndex}${rowSuffix}`;
|
|
2119
|
+
});
|
|
2120
|
+
return `${prefix}${JSON.stringify(nextModuleUrls)},${exportNamesSource},${nextSymbolRows}${suffix}`;
|
|
2121
|
+
});
|
|
2122
|
+
}
|
|
2123
|
+
function parseStringArray(source) {
|
|
2124
|
+
const values = [];
|
|
2125
|
+
let end = 1;
|
|
2126
|
+
for (const match of source.matchAll(STRING_LITERAL_RE)) {
|
|
2127
|
+
values.push(match[2]);
|
|
2128
|
+
end = (match.index ?? 0) + match[0].length;
|
|
2129
|
+
}
|
|
2130
|
+
if (source.slice(end).trim() !== "]") return void 0;
|
|
2131
|
+
return values;
|
|
2132
|
+
}
|
|
2133
|
+
function parseStringList(source) {
|
|
2134
|
+
if (source.startsWith("[")) return parseStringArray(source);
|
|
2135
|
+
const packed = source.match(/^(["'`])([^"'`]*)\1\.split\(\s*(["'`])([^"'`]*)\3\s*\)$/);
|
|
2136
|
+
return packed ? packed[2].split(packed[4]) : void 0;
|
|
2137
|
+
}
|
|
2138
|
+
function relativeChunkSpecifier$1(importerFileName, targetFileName) {
|
|
2139
|
+
const value = relative(dirname(importerFileName), targetFileName).replaceAll("\\", "/");
|
|
2140
|
+
return value.startsWith(".") ? value : `./${value}`;
|
|
2141
|
+
}
|
|
2142
|
+
function isGeneratedChunk$1(value) {
|
|
2143
|
+
if (!value || typeof value !== "object") return false;
|
|
2144
|
+
const chunk = value;
|
|
2145
|
+
return chunk.type === "chunk" && typeof chunk.fileName === "string" && typeof chunk.code === "string" && Array.isArray(chunk.moduleIds);
|
|
2146
|
+
}
|
|
2147
|
+
function normalizeVirtualId$2(id) {
|
|
2148
|
+
return id.startsWith("\0") ? id.slice(1) : id;
|
|
2149
|
+
}
|
|
2150
|
+
//#endregion
|
|
2151
|
+
//#region src/build/build-metadata.ts
|
|
2152
|
+
function createBuildMetadata(bundle, transformManifests, root, options = {}) {
|
|
2153
|
+
const canonPath = options.canonPath ?? ((fileName) => fileName);
|
|
2154
|
+
const publicPath = options.publicPath ?? ((fileName) => fileName);
|
|
2155
|
+
const modules = [...transformManifests].map(cloneTransformManifest);
|
|
2156
|
+
const metadata = {
|
|
2157
|
+
version: 1,
|
|
2158
|
+
modules,
|
|
2159
|
+
bundles: {},
|
|
2160
|
+
assets: {},
|
|
2161
|
+
injections: [...options.injections ?? [], ...collectHeadLinkInjections(bundle, { publicPath })]
|
|
2162
|
+
};
|
|
2163
|
+
for (const item of Object.values(bundle)) {
|
|
2164
|
+
if (item.type === "asset") {
|
|
2165
|
+
if (item.fileName.endsWith(".js.map")) continue;
|
|
2166
|
+
metadata.assets[item.fileName] = assetInfo(item);
|
|
2167
|
+
continue;
|
|
2168
|
+
}
|
|
2169
|
+
const bundleFileName = canonPath(item.fileName);
|
|
2170
|
+
const origins = getOrigins(item, root);
|
|
2171
|
+
const asyncBundle = {
|
|
2172
|
+
size: item.code.length,
|
|
2173
|
+
total: item.code.length
|
|
2174
|
+
};
|
|
2175
|
+
const imports = mapBundleNames(bundle, item.imports, canonPath);
|
|
2176
|
+
if (imports.length > 0) asyncBundle.imports = imports;
|
|
2177
|
+
const dynamicImports = [...new Set([
|
|
2178
|
+
...mapBundleNames(bundle, item.dynamicImports, canonPath),
|
|
2179
|
+
...mapBundleNames(bundle, scanEmittedDynamicImports(item.code, item.fileName), canonPath),
|
|
2180
|
+
...mapBundleNames(bundle, scanGeneratedSymbolTableImports(item.code, item.fileName), canonPath)
|
|
2181
|
+
])];
|
|
2182
|
+
if (dynamicImports.length > 0) asyncBundle.dynamicImports = dynamicImports;
|
|
2183
|
+
if (origins.length > 0) asyncBundle.origins = origins;
|
|
2184
|
+
finalizeVirtualModuleReferences(modules, item, bundleFileName);
|
|
2185
|
+
const symbols = modules.flatMap((module) => module.symbols.filter((symbol) => symbol.fileName === bundleFileName).map((symbol) => symbol.symbolId));
|
|
2186
|
+
if (symbols.length > 0) asyncBundle.symbols = symbols;
|
|
2187
|
+
metadata.bundles[bundleFileName] = asyncBundle;
|
|
2188
|
+
}
|
|
2189
|
+
computeTotals(metadata.bundles);
|
|
2190
|
+
sortBuildMetadata(metadata);
|
|
2191
|
+
if (options.bundleGraphAsset) {
|
|
2192
|
+
metadata.bundleGraph = convertManifestToBundleGraph(metadata, options.bundleGraphAdders);
|
|
2193
|
+
metadata.bundleGraphAsset = options.bundleGraphAsset;
|
|
2194
|
+
metadata.assets[options.bundleGraphAsset] = {
|
|
2195
|
+
name: "bundle-graph.json",
|
|
2196
|
+
size: JSON.stringify(metadata.bundleGraph).length
|
|
2197
|
+
};
|
|
2198
|
+
}
|
|
2199
|
+
return metadata;
|
|
2200
|
+
}
|
|
2201
|
+
function cloneTransformManifest(manifest) {
|
|
2202
|
+
return {
|
|
2203
|
+
source: manifest.source,
|
|
2204
|
+
payload: { ...manifest.payload },
|
|
2205
|
+
resolver: { ...manifest.resolver },
|
|
2206
|
+
symbols: manifest.symbols.map((symbol) => ({ ...symbol })),
|
|
2207
|
+
runtimeDemandMap: manifest.runtimeDemandMap
|
|
2208
|
+
};
|
|
2209
|
+
}
|
|
2210
|
+
function finalizeVirtualModuleReferences(modules, item, bundleFileName) {
|
|
2211
|
+
const ids = new Set([item.facadeModuleId ?? void 0, ...item.moduleIds].filter((id) => !!id).map(normalizeVirtualModuleId));
|
|
2212
|
+
for (const module of modules) {
|
|
2213
|
+
for (const reference of [module.payload, module.resolver]) if (ids.has(normalizeVirtualModuleId(reference.virtualModuleId))) reference.fileName = bundleFileName;
|
|
2214
|
+
for (const symbol of module.symbols) if (ids.has(normalizeVirtualModuleId(symbol.virtualModuleId))) symbol.fileName = bundleFileName;
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2217
|
+
function normalizeVirtualModuleId(id) {
|
|
2218
|
+
if (id.startsWith("\0")) return id.slice(1);
|
|
2219
|
+
return id;
|
|
2220
|
+
}
|
|
2221
|
+
function assetInfo(item) {
|
|
2222
|
+
return {
|
|
2223
|
+
name: item.names?.[0] ?? item.name,
|
|
2224
|
+
size: item.source.length
|
|
2225
|
+
};
|
|
2226
|
+
}
|
|
2227
|
+
function mapBundleNames(bundle, names, canonPath) {
|
|
2228
|
+
return names.flatMap((name) => {
|
|
2229
|
+
const item = bundle[name];
|
|
2230
|
+
if (item) return [canonPath(item.fileName)];
|
|
2231
|
+
return [canonPath(name)];
|
|
2232
|
+
});
|
|
2233
|
+
}
|
|
2234
|
+
function getOrigins(item, root) {
|
|
2235
|
+
return item.moduleIds.filter((id) => !id.startsWith("\0")).map((id) => {
|
|
2236
|
+
if (root) return relative(root, id);
|
|
2237
|
+
return id;
|
|
2238
|
+
}).sort();
|
|
2239
|
+
}
|
|
2240
|
+
function computeTotals(bundles) {
|
|
2241
|
+
const collect = (name, seen) => {
|
|
2242
|
+
const bundle = bundles[name];
|
|
2243
|
+
if (!bundle || seen.has(name)) return;
|
|
2244
|
+
seen.add(name);
|
|
2245
|
+
for (const dep of bundle.imports ?? []) collect(dep, seen);
|
|
2246
|
+
};
|
|
2247
|
+
for (const name of Object.keys(bundles)) {
|
|
2248
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2249
|
+
collect(name, seen);
|
|
2250
|
+
bundles[name].total = [...seen].reduce((sum, dep) => sum + (bundles[dep]?.size ?? 0), 0);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
function sortBuildMetadata(metadata) {
|
|
2254
|
+
metadata.modules = metadata.modules.sort((a, b) => a.source.localeCompare(b.source));
|
|
2255
|
+
metadata.bundles = sortRecord$1(metadata.bundles);
|
|
2256
|
+
metadata.assets = sortRecord$1(metadata.assets ?? {});
|
|
2257
|
+
metadata.injections?.sort((a, b) => injectionKey(a).localeCompare(injectionKey(b)));
|
|
2258
|
+
for (const bundle of Object.values(metadata.bundles)) {
|
|
2259
|
+
bundle.imports?.sort();
|
|
2260
|
+
bundle.dynamicImports?.sort();
|
|
2261
|
+
bundle.origins?.sort();
|
|
2262
|
+
bundle.symbols?.sort();
|
|
2263
|
+
}
|
|
2264
|
+
for (const module of metadata.modules) module.symbols.sort((a, b) => a.symbolId.localeCompare(b.symbolId));
|
|
2265
|
+
}
|
|
2266
|
+
function sortRecord$1(record) {
|
|
2267
|
+
const next = {};
|
|
2268
|
+
for (const key of Object.keys(record).sort()) {
|
|
2269
|
+
const value = record[key];
|
|
2270
|
+
if (value !== void 0) next[key] = value;
|
|
2271
|
+
}
|
|
2272
|
+
return next;
|
|
2273
|
+
}
|
|
2274
|
+
function injectionKey(injection) {
|
|
2275
|
+
return `${injection.location}:${injection.tag}:${injection.attributes?.href ?? ""}`;
|
|
2276
|
+
}
|
|
2277
|
+
//#endregion
|
|
2278
|
+
//#region src/build/execution-sizes.ts
|
|
2279
|
+
const MARKLESS_EXECUTION_SIZES = `${MARKLESS_BUILD_PREFIX}execution-sizes.json`;
|
|
2280
|
+
const CONTENT_HASH_MODULE_SPECIFIER = /chunk-[A-Za-z0-9_-]+\.js/g;
|
|
2281
|
+
const CONTENT_HASH_PLACEHOLDER = "chunk-________.js";
|
|
2282
|
+
function canonicalizeContentHashSpecifiers(source) {
|
|
2283
|
+
return source.replace(CONTENT_HASH_MODULE_SPECIFIER, CONTENT_HASH_PLACEHOLDER);
|
|
2284
|
+
}
|
|
2285
|
+
async function createExecutionSizesAsset(bundle, metadata, canonPath = (fileName) => fileName, attribution, options = {}) {
|
|
2286
|
+
const entries = {};
|
|
2287
|
+
const sizeByChunk = /* @__PURE__ */ new Map();
|
|
2288
|
+
const chunkSize = async (item, chunk) => {
|
|
2289
|
+
const cached = sizeByChunk.get(chunk);
|
|
2290
|
+
if (cached) return cached;
|
|
2291
|
+
const size = {
|
|
2292
|
+
raw: item.code.length,
|
|
2293
|
+
gzip: await gzipByteLength(canonicalizeContentHashSpecifiers(item.code)),
|
|
2294
|
+
chunk
|
|
2295
|
+
};
|
|
2296
|
+
sizeByChunk.set(chunk, size);
|
|
2297
|
+
return size;
|
|
2298
|
+
};
|
|
2299
|
+
const symbolLogIdsByChunk = /* @__PURE__ */ new Map();
|
|
2300
|
+
for (const module of metadata.modules) for (const symbol of module.symbols) {
|
|
2301
|
+
if (!symbol.fileName) continue;
|
|
2302
|
+
const chunk = symbolLogIdsByChunk.get(symbol.fileName) ?? [];
|
|
2303
|
+
chunk.push(stripResolvedIdMarker(symbol.virtualModuleId));
|
|
2304
|
+
symbolLogIdsByChunk.set(symbol.fileName, chunk);
|
|
2305
|
+
}
|
|
2306
|
+
for (const item of Object.values(bundle)) {
|
|
2307
|
+
if (item.type !== "chunk") continue;
|
|
2308
|
+
const chunk = canonPath(item.fileName);
|
|
2309
|
+
const logIds = new Set([...item.moduleIds.flatMap((id) => chunkModuleLogId(id) ?? []), ...symbolLogIdsByChunk.get(chunk) ?? []]);
|
|
2310
|
+
if (logIds.size === 0) continue;
|
|
2311
|
+
if (logIds.has("virtual:markless:dev-log") && logIds.size > 1) {
|
|
2312
|
+
const cohabitingIds = [...logIds].filter((id) => id !== MARKLESS_EXECUTION_LOG_MODULE_ID).sort();
|
|
2313
|
+
throw new Error(`Markless execution sizes require an isolated dev-log chunk; chunk "${chunk}" also contains logged module ids: ${cohabitingIds.join(", ")}.`);
|
|
2314
|
+
}
|
|
2315
|
+
const size = await chunkSize(item, chunk);
|
|
2316
|
+
for (const id of logIds) entries[id] = id === "virtual:markless:dev-log" ? {
|
|
2317
|
+
...size,
|
|
2318
|
+
instrument: true
|
|
2319
|
+
} : size;
|
|
2320
|
+
const emittedSpecifier = `./${chunk.split("/").pop()}`;
|
|
2321
|
+
entries[emittedSpecifier] ??= size;
|
|
2322
|
+
}
|
|
2323
|
+
const unshipped = {};
|
|
2324
|
+
if (options.executionLogActive === true) {
|
|
2325
|
+
const absorbing = absorbingChunkIndex(bundle);
|
|
2326
|
+
const unmappable = [];
|
|
2327
|
+
for (const required of requiredExecutionLogIds(metadata, options.hookedIds, absorbing)) {
|
|
2328
|
+
if (entries[required.id]) continue;
|
|
2329
|
+
const item = absorbing.get(required.id);
|
|
2330
|
+
if (!item) {
|
|
2331
|
+
if (required.shipped) unmappable.push(required.id);
|
|
2332
|
+
else if (required.hooked) unshipped[required.id] = UNSHIPPED_HOOK_REASON;
|
|
2333
|
+
continue;
|
|
2334
|
+
}
|
|
2335
|
+
const size = await chunkSize(item, canonPath(item.fileName));
|
|
2336
|
+
entries[required.id] = required.id === "virtual:markless:dev-log" ? {
|
|
2337
|
+
...size,
|
|
2338
|
+
instrument: true
|
|
2339
|
+
} : size;
|
|
2340
|
+
}
|
|
2341
|
+
if (unmappable.length > 0) throw new Error(`Markless execution sizes are incomplete: no chunk carries ${unmappable.sort().join(", ")}. Every id this build can log must join build/execution-sizes.json, or the in-page console reports "bytes unknown" for a real execution.`);
|
|
2342
|
+
}
|
|
2343
|
+
return {
|
|
2344
|
+
type: "asset",
|
|
2345
|
+
fileName: MARKLESS_EXECUTION_SIZES,
|
|
2346
|
+
source: JSON.stringify({
|
|
2347
|
+
...sortRecord(entries),
|
|
2348
|
+
...Object.keys(unshipped).length > 0 ? { unshipped: sortRecord(unshipped) } : {},
|
|
2349
|
+
...attribution && Object.keys(attribution).length > 0 ? { attribution: sortNestedRecord(attribution) } : {}
|
|
2350
|
+
})
|
|
2351
|
+
};
|
|
2352
|
+
}
|
|
2353
|
+
const UNSHIPPED_HOOK_REASON = "hooked at transform time (before chunk assignment exists); no client chunk carries this module, so it can never execute in a browser";
|
|
2354
|
+
function requiredExecutionLogIds(metadata, hookedIds = /* @__PURE__ */ new Map(), absorbing = /* @__PURE__ */ new Map()) {
|
|
2355
|
+
const required = /* @__PURE__ */ new Map();
|
|
2356
|
+
const add = (id, shipped, hooked = false) => {
|
|
2357
|
+
const current = required.get(id);
|
|
2358
|
+
if (!current || shipped && !current.shipped) required.set(id, {
|
|
2359
|
+
id,
|
|
2360
|
+
shipped,
|
|
2361
|
+
hooked: hooked || current?.hooked
|
|
2362
|
+
});
|
|
2363
|
+
};
|
|
2364
|
+
for (const [id, moduleId] of hookedIds) add(id, absorbing.has(moduleId), true);
|
|
2365
|
+
add(MARKLESS_EXECUTION_LOG_MODULE_ID, false);
|
|
2366
|
+
for (const id of EXECUTION_LOG_DISPATCH_MODULE_IDS) add(id, false);
|
|
2367
|
+
for (const module of metadata.modules) for (const symbol of module.symbols) add(stripResolvedIdMarker(symbol.virtualModuleId), !!symbol.fileName);
|
|
2368
|
+
return [...required.values()];
|
|
2369
|
+
}
|
|
2370
|
+
function absorbingChunkIndex(bundle) {
|
|
2371
|
+
const index = /* @__PURE__ */ new Map();
|
|
2372
|
+
for (const item of Object.values(bundle)) {
|
|
2373
|
+
if (item.type !== "chunk") continue;
|
|
2374
|
+
for (const raw of [...item.moduleIds, item.facadeModuleId ?? ""]) {
|
|
2375
|
+
if (!raw) continue;
|
|
2376
|
+
const id = stripResolvedIdMarker(raw);
|
|
2377
|
+
if (!index.has(id)) index.set(id, item);
|
|
2378
|
+
const logId = workspaceModuleLogId(id);
|
|
2379
|
+
if (logId && !index.has(logId)) index.set(logId, item);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
return index;
|
|
2383
|
+
}
|
|
2384
|
+
function workspaceModuleLogId(path) {
|
|
2385
|
+
const match = path.match(/[/\\]([a-z0-9-]+)[/\\]src[/\\]([^?#]+)\.ts$/);
|
|
2386
|
+
return match ? `${match[1]}:${match[2].replace(/[/\\]/g, "/")}` : null;
|
|
2387
|
+
}
|
|
2388
|
+
function chunkModuleLogId(id) {
|
|
2389
|
+
const path = stripResolvedIdMarker(id);
|
|
2390
|
+
if (path === "virtual:markless:dev-log") return path;
|
|
2391
|
+
const match = path.match(/[/\\](web|runtime|serializer)[/\\]src[/\\]([^?#]+)\.ts$/);
|
|
2392
|
+
return match ? `${match[1]}:${match[2].replace(/[/\\]/g, "/")}` : null;
|
|
2393
|
+
}
|
|
2394
|
+
function stripResolvedIdMarker(id) {
|
|
2395
|
+
return id.startsWith("\0") ? id.slice(1) : id;
|
|
2396
|
+
}
|
|
2397
|
+
async function gzipByteLength(code) {
|
|
2398
|
+
const encoded = new TextEncoder().encode(code);
|
|
2399
|
+
const reader = new ReadableStream({ start(controller) {
|
|
2400
|
+
controller.enqueue(encoded);
|
|
2401
|
+
controller.close();
|
|
2402
|
+
} }).pipeThrough(new CompressionStream("gzip")).getReader();
|
|
2403
|
+
let total = 0;
|
|
2404
|
+
while (true) {
|
|
2405
|
+
const { done, value } = await reader.read();
|
|
2406
|
+
if (done) break;
|
|
2407
|
+
total += value.byteLength;
|
|
2408
|
+
}
|
|
2409
|
+
return total;
|
|
2410
|
+
}
|
|
2411
|
+
function sortRecord(record) {
|
|
2412
|
+
const next = {};
|
|
2413
|
+
for (const key of Object.keys(record).sort()) next[key] = record[key];
|
|
2414
|
+
return next;
|
|
2415
|
+
}
|
|
2416
|
+
function sortNestedRecord(record) {
|
|
2417
|
+
const next = {};
|
|
2418
|
+
for (const key of Object.keys(record).sort()) next[key] = sortRecord({ ...record[key] });
|
|
2419
|
+
return next;
|
|
2420
|
+
}
|
|
2421
|
+
//#endregion
|
|
2422
|
+
//#region src/build/preload-cleanup.ts
|
|
2423
|
+
function stripEmptyVitePreloadWrappers(code) {
|
|
2424
|
+
return stripImportedVitePreloadHelper(stripUnusedVitePreloadHelper(stripAsyncEmptyPreloadWrappers(stripDirectEmptyPreloadWrappers(code))));
|
|
2425
|
+
}
|
|
2426
|
+
const IMPORT_DECLARATION_CANDIDATE_RE = /\bimport\s*\{[\s\S]*?\}\s*from\s*["'][^"']+["'];?/g;
|
|
2427
|
+
function stripDirectEmptyPreloadWrappers(code) {
|
|
2428
|
+
let next = "";
|
|
2429
|
+
let cursor = 0;
|
|
2430
|
+
let changed = false;
|
|
2431
|
+
const wrapperRE = /\b[$A-Z_a-z][$\w]*\(\(\)\s*=>\s*/g;
|
|
2432
|
+
for (let match = wrapperRE.exec(code); match; match = wrapperRE.exec(code)) {
|
|
2433
|
+
const callStart = match.index;
|
|
2434
|
+
const bodyStart = match.index + match[0].length;
|
|
2435
|
+
if (!code.startsWith("import(", bodyStart)) continue;
|
|
2436
|
+
const wrapper = findEmptyPreloadWrapper(code, callStart, bodyStart);
|
|
2437
|
+
if (!wrapper) continue;
|
|
2438
|
+
next += code.slice(cursor, callStart);
|
|
2439
|
+
next += code.slice(bodyStart, wrapper.firstArgumentEnd);
|
|
2440
|
+
cursor = wrapper.callEnd + 1;
|
|
2441
|
+
wrapperRE.lastIndex = cursor;
|
|
2442
|
+
changed = true;
|
|
2443
|
+
}
|
|
2444
|
+
if (!changed) return code;
|
|
2445
|
+
return next + code.slice(cursor);
|
|
2446
|
+
}
|
|
2447
|
+
function stripAsyncEmptyPreloadWrappers(code) {
|
|
2448
|
+
let next = "";
|
|
2449
|
+
let cursor = 0;
|
|
2450
|
+
let changed = false;
|
|
2451
|
+
const wrapperRE = /\b[$A-Z_a-z][$\w]*\(\s*async\s*\(\)\s*=>\s*\{/g;
|
|
2452
|
+
for (let match = wrapperRE.exec(code); match; match = wrapperRE.exec(code)) {
|
|
2453
|
+
const callStart = match.index;
|
|
2454
|
+
const callOpen = code.indexOf("(", callStart);
|
|
2455
|
+
if (callOpen < 0) continue;
|
|
2456
|
+
const firstArgumentEnd = findTopLevelComma(code, callOpen + 1);
|
|
2457
|
+
if (firstArgumentEnd < 0) continue;
|
|
2458
|
+
const wrapper = findEmptyPreloadWrapper(code, callStart, callOpen + 1);
|
|
2459
|
+
if (!wrapper) continue;
|
|
2460
|
+
const loader = code.slice(callOpen + 1, firstArgumentEnd);
|
|
2461
|
+
next += code.slice(cursor, callStart);
|
|
2462
|
+
next += `(${loader})()`;
|
|
2463
|
+
cursor = wrapper.callEnd + 1;
|
|
2464
|
+
wrapperRE.lastIndex = cursor;
|
|
2465
|
+
changed = true;
|
|
2466
|
+
}
|
|
2467
|
+
if (!changed) return code;
|
|
2468
|
+
return next + code.slice(cursor);
|
|
2469
|
+
}
|
|
2470
|
+
function findEmptyPreloadWrapper(code, callStart, bodyStart) {
|
|
2471
|
+
const callOpen = code.indexOf("(", callStart);
|
|
2472
|
+
if (callOpen < 0 || callOpen >= bodyStart) return void 0;
|
|
2473
|
+
const firstArgumentEnd = findTopLevelComma(code, callOpen + 1);
|
|
2474
|
+
if (firstArgumentEnd < 0) return void 0;
|
|
2475
|
+
let cursor = skipSpaces(code, firstArgumentEnd + 1);
|
|
2476
|
+
if (code[cursor] !== "[" || code[cursor + 1] !== "]") return void 0;
|
|
2477
|
+
cursor = skipSpaces(code, cursor + 2);
|
|
2478
|
+
if (code[cursor] === ")") return {
|
|
2479
|
+
firstArgumentEnd,
|
|
2480
|
+
callEnd: cursor
|
|
2481
|
+
};
|
|
2482
|
+
if (code[cursor] !== ",") return void 0;
|
|
2483
|
+
cursor = skipSpaces(code, cursor + 1);
|
|
2484
|
+
if (!code.startsWith("import.meta.url", cursor)) return void 0;
|
|
2485
|
+
cursor = skipSpaces(code, cursor + 15);
|
|
2486
|
+
if (code[cursor] !== ")") return void 0;
|
|
2487
|
+
return {
|
|
2488
|
+
firstArgumentEnd,
|
|
2489
|
+
callEnd: cursor
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
function findTopLevelComma(code, start) {
|
|
2493
|
+
let depth = 1;
|
|
2494
|
+
let quote = null;
|
|
2495
|
+
let escaped = false;
|
|
2496
|
+
for (let index = start; index < code.length; index++) {
|
|
2497
|
+
const char = code[index];
|
|
2498
|
+
if (quote) {
|
|
2499
|
+
if (escaped) {
|
|
2500
|
+
escaped = false;
|
|
2501
|
+
continue;
|
|
2502
|
+
}
|
|
2503
|
+
if (char === "\\") {
|
|
2504
|
+
escaped = true;
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
if (char === quote) quote = null;
|
|
2508
|
+
continue;
|
|
2509
|
+
}
|
|
2510
|
+
if (char === "\"" || char === "'" || char === "`") {
|
|
2511
|
+
quote = char;
|
|
2512
|
+
continue;
|
|
2513
|
+
}
|
|
2514
|
+
if (char === "(" || char === "[" || char === "{") {
|
|
2515
|
+
depth++;
|
|
2516
|
+
continue;
|
|
2517
|
+
}
|
|
2518
|
+
if (char === ")" || char === "]" || char === "}") {
|
|
2519
|
+
depth--;
|
|
2520
|
+
if (depth === 0) return -1;
|
|
2521
|
+
continue;
|
|
2522
|
+
}
|
|
2523
|
+
if (char === "," && depth === 1) return index;
|
|
2524
|
+
}
|
|
2525
|
+
return -1;
|
|
2526
|
+
}
|
|
2527
|
+
function skipSpaces(code, start) {
|
|
2528
|
+
let cursor = start;
|
|
2529
|
+
while (/\s/.test(code[cursor] ?? "")) cursor++;
|
|
2530
|
+
return cursor;
|
|
2531
|
+
}
|
|
2532
|
+
function stripImportedVitePreloadHelper(code) {
|
|
2533
|
+
const helper = findImportedVitePreloadHelper(code);
|
|
2534
|
+
if (!helper) return code;
|
|
2535
|
+
const withoutImport = code.slice(0, helper.importStart) + code.slice(helper.importEnd);
|
|
2536
|
+
if (hasCallableReference(withoutImport, helper.preloadFunction)) return code;
|
|
2537
|
+
const initCall = `${escapeRegExp$1(helper.initFunction)}\\(\\)`;
|
|
2538
|
+
return withoutImport.replace(new RegExp(String.raw`,${initCall},`, "g"), ",").replace(new RegExp(String.raw`\{${initCall},`, "g"), "{").replace(new RegExp(String.raw`,${initCall},`, "g"), ",").replace(new RegExp(String.raw`,${initCall}\}`, "g"), "}").replace(new RegExp(String.raw`\{${initCall}\}`, "g"), "{}");
|
|
2539
|
+
}
|
|
2540
|
+
function findImportedVitePreloadHelper(code) {
|
|
2541
|
+
for (const match of code.matchAll(IMPORT_DECLARATION_CANDIDATE_RE)) {
|
|
2542
|
+
const importStart = match.index ?? -1;
|
|
2543
|
+
if (importStart < 0) continue;
|
|
2544
|
+
const statement = match[0];
|
|
2545
|
+
const declaration = asNodes(tryParseJavaScriptModule(statement)?.body).find((node) => node.type === "ImportDeclaration");
|
|
2546
|
+
if (!declaration) continue;
|
|
2547
|
+
let preloadFunction;
|
|
2548
|
+
let initFunction;
|
|
2549
|
+
for (const specifier of asNodes(declaration.specifiers)) {
|
|
2550
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
2551
|
+
const imported = identifierName(specifier.imported);
|
|
2552
|
+
const local = identifierName(specifier.local);
|
|
2553
|
+
if (!imported || !local) continue;
|
|
2554
|
+
if (imported === "__vitePreload") preloadFunction = local;
|
|
2555
|
+
if (imported === "init_preload_helper") initFunction = local;
|
|
2556
|
+
}
|
|
2557
|
+
if (preloadFunction && initFunction) return {
|
|
2558
|
+
importStart,
|
|
2559
|
+
importEnd: importStart + statement.length,
|
|
2560
|
+
preloadFunction,
|
|
2561
|
+
initFunction
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
function stripUnusedVitePreloadHelper(code) {
|
|
2566
|
+
const marker = code.indexOf("vite:preloadError");
|
|
2567
|
+
if (marker < 0) return code;
|
|
2568
|
+
const helper = findVitePreloadHelperModule(code, marker);
|
|
2569
|
+
if (!helper) return code;
|
|
2570
|
+
const statementEnd = code[helper.removeStart] === "," && code[helper.removeEnd - 1] === ";" ? ";" : "";
|
|
2571
|
+
const outsideHelper = code.slice(0, helper.removeStart) + statementEnd + code.slice(helper.removeEnd);
|
|
2572
|
+
if (hasCallableReference(outsideHelper, helper.preloadFunction)) return code;
|
|
2573
|
+
let withoutHelper = outsideHelper;
|
|
2574
|
+
const chain = findVitePreloadHelperInitChain(withoutHelper, helper.moduleVariable);
|
|
2575
|
+
if (chain) withoutHelper = removeInitCall(withoutHelper.slice(0, chain.removeStart) + withoutHelper.slice(chain.removeEnd), chain.entryVariable);
|
|
2576
|
+
return removeInitCall(withoutHelper, helper.moduleVariable);
|
|
2577
|
+
}
|
|
2578
|
+
function findVitePreloadHelperModule(code, marker) {
|
|
2579
|
+
const initStart = code.lastIndexOf("=e((()=>{", marker);
|
|
2580
|
+
if (initStart < 0) return void 0;
|
|
2581
|
+
const moduleVariable = readIdentifierBefore(code, initStart);
|
|
2582
|
+
if (!moduleVariable) return void 0;
|
|
2583
|
+
const bodyStart = initStart + 9;
|
|
2584
|
+
const bodyEnd = findModuleInitEnd(code, initStart);
|
|
2585
|
+
if (bodyEnd < 0) return void 0;
|
|
2586
|
+
const helperBody = code.slice(bodyStart, bodyEnd);
|
|
2587
|
+
const preloadFunction = helperBody.match(/,([$A-Z_a-z][$\w]*)=function\([^)]*\)\{let\s+[$A-Z_a-z][$\w]*=Promise\.resolve\(\)/)?.[1];
|
|
2588
|
+
if (!preloadFunction) return void 0;
|
|
2589
|
+
const firstHelperVariable = helperBody.match(/^([$A-Z_a-z][$\w]*)=/)?.[1];
|
|
2590
|
+
if (!firstHelperVariable) return void 0;
|
|
2591
|
+
const removeStart = findHelperDeclarationStart(code, initStart, firstHelperVariable);
|
|
2592
|
+
if (removeStart < 0) return void 0;
|
|
2593
|
+
return {
|
|
2594
|
+
moduleVariable,
|
|
2595
|
+
preloadFunction,
|
|
2596
|
+
removeStart,
|
|
2597
|
+
removeEnd: bodyEnd + 4
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
function findVitePreloadHelperInitChain(code, moduleVariable) {
|
|
2601
|
+
const match = new RegExp(`var\\s+([$A-Z_a-z][$\\w]*)=e\\(\\(\\(\\)=>\\{${escapeRegExp$1(moduleVariable)}\\(\\)\\}\\)\\),([$A-Z_a-z][$\\w]*)=e\\(\\(\\(\\)=>\\{\\1\\(\\)\\}\\)\\);`).exec(code);
|
|
2602
|
+
if (!match) return void 0;
|
|
2603
|
+
return {
|
|
2604
|
+
entryVariable: match[2],
|
|
2605
|
+
removeStart: match.index,
|
|
2606
|
+
removeEnd: match.index + match[0].length
|
|
2607
|
+
};
|
|
2608
|
+
}
|
|
2609
|
+
function removeInitCall(code, entryVariable) {
|
|
2610
|
+
return code.replace(new RegExp(`,${escapeRegExp$1(entryVariable)}\\(\\)`), "").replace(new RegExp(`${escapeRegExp$1(entryVariable)}\\(\\),`), "").replace(new RegExp(`\\{${escapeRegExp$1(entryVariable)}\\(\\)\\}`), "{}");
|
|
2611
|
+
}
|
|
2612
|
+
function readIdentifierBefore(code, index) {
|
|
2613
|
+
let end = index;
|
|
2614
|
+
while (/\s/.test(code[end - 1] ?? "")) end--;
|
|
2615
|
+
let start = end;
|
|
2616
|
+
while (/[$\w]/.test(code[start - 1] ?? "")) start--;
|
|
2617
|
+
const value = code.slice(start, end);
|
|
2618
|
+
return /^[$A-Z_a-z][$\w]*$/.test(value) ? value : void 0;
|
|
2619
|
+
}
|
|
2620
|
+
function findModuleInitEnd(code, initStart) {
|
|
2621
|
+
return code.indexOf("}));", initStart);
|
|
2622
|
+
}
|
|
2623
|
+
function findHelperDeclarationStart(code, initStart, firstHelperVariable) {
|
|
2624
|
+
const commaStart = code.lastIndexOf(`,${firstHelperVariable},`, initStart);
|
|
2625
|
+
if (commaStart >= 0) return commaStart;
|
|
2626
|
+
const varStart = code.lastIndexOf(`var ${firstHelperVariable},`, initStart);
|
|
2627
|
+
if (varStart >= 0) return varStart;
|
|
2628
|
+
return -1;
|
|
2629
|
+
}
|
|
2630
|
+
function escapeRegExp$1(value) {
|
|
2631
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2632
|
+
}
|
|
2633
|
+
function hasCallableReference(code, name) {
|
|
2634
|
+
const ast = tryParseJavaScriptModule(code);
|
|
2635
|
+
if (!ast) return true;
|
|
2636
|
+
let found = false;
|
|
2637
|
+
walkReferenceScopes(ast, [], (node, scopes) => {
|
|
2638
|
+
if (node.type !== "CallExpression") return;
|
|
2639
|
+
const callee = node.callee;
|
|
2640
|
+
if (identifierName(callee) !== name) return;
|
|
2641
|
+
if (isDeclaredInScope(name, scopes)) return;
|
|
2642
|
+
found = true;
|
|
2643
|
+
});
|
|
2644
|
+
return found;
|
|
2645
|
+
}
|
|
2646
|
+
function walkReferenceScopes(node, scopes, visit) {
|
|
2647
|
+
if (!node || typeof node !== "object") return;
|
|
2648
|
+
if (node.type === "Program") {
|
|
2649
|
+
const scope = collectScopeDeclarations(asNodes(node.body));
|
|
2650
|
+
visit(node, [scope]);
|
|
2651
|
+
for (const child of asNodes(node.body)) walkReferenceScopes(child, [scope], visit);
|
|
2652
|
+
return;
|
|
2653
|
+
}
|
|
2654
|
+
if (isFunctionNode(node)) {
|
|
2655
|
+
const scope = /* @__PURE__ */ new Set();
|
|
2656
|
+
collectBindingNames(node.id, scope);
|
|
2657
|
+
for (const parameter of asNodes(node.params)) collectBindingNames(parameter, scope);
|
|
2658
|
+
const nextScopes = [...scopes, scope];
|
|
2659
|
+
visit(node, nextScopes);
|
|
2660
|
+
walkReferenceScopes(node.body, nextScopes, visit);
|
|
2661
|
+
return;
|
|
2662
|
+
}
|
|
2663
|
+
if (node.type === "BlockStatement") {
|
|
2664
|
+
const scope = collectScopeDeclarations(asNodes(node.body));
|
|
2665
|
+
const nextScopes = [...scopes, scope];
|
|
2666
|
+
visit(node, nextScopes);
|
|
2667
|
+
for (const child of asNodes(node.body)) walkReferenceScopes(child, nextScopes, visit);
|
|
2668
|
+
return;
|
|
2669
|
+
}
|
|
2670
|
+
visit(node, scopes);
|
|
2671
|
+
for (const child of childNodes(node)) walkReferenceScopes(child, scopes, visit);
|
|
2672
|
+
}
|
|
2673
|
+
function collectScopeDeclarations(nodes) {
|
|
2674
|
+
const declarations = /* @__PURE__ */ new Set();
|
|
2675
|
+
for (const node of nodes) {
|
|
2676
|
+
if (node.type === "FunctionDeclaration" || node.type === "ClassDeclaration") {
|
|
2677
|
+
collectBindingNames(node.id, declarations);
|
|
2678
|
+
continue;
|
|
2679
|
+
}
|
|
2680
|
+
if (node.type === "ImportDeclaration") {
|
|
2681
|
+
for (const specifier of asNodes(node.specifiers)) collectBindingNames(specifier.local, declarations);
|
|
2682
|
+
continue;
|
|
2683
|
+
}
|
|
2684
|
+
if (node.type === "VariableDeclaration") for (const declaration of asNodes(node.declarations)) collectBindingNames(declaration.id, declarations);
|
|
2685
|
+
}
|
|
2686
|
+
return declarations;
|
|
2687
|
+
}
|
|
2688
|
+
function collectBindingNames(node, names) {
|
|
2689
|
+
if (!node) return;
|
|
2690
|
+
const name = identifierName(node);
|
|
2691
|
+
if (name) {
|
|
2692
|
+
names.add(name);
|
|
2693
|
+
return;
|
|
2694
|
+
}
|
|
2695
|
+
for (const child of childNodes(node)) collectBindingNames(child, names);
|
|
2696
|
+
}
|
|
2697
|
+
function isDeclaredInScope(name, scopes) {
|
|
2698
|
+
return scopes.some((scope) => scope.has(name));
|
|
2699
|
+
}
|
|
2700
|
+
function isFunctionNode(node) {
|
|
2701
|
+
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
|
|
2702
|
+
}
|
|
2703
|
+
function tryParseJavaScriptModule(code) {
|
|
2704
|
+
try {
|
|
2705
|
+
return parseJavaScriptModule(code);
|
|
2706
|
+
} catch {
|
|
2707
|
+
return;
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
function childNodes(node) {
|
|
2711
|
+
const children = [];
|
|
2712
|
+
for (const [key, value] of Object.entries(node)) {
|
|
2713
|
+
if (ignoredAstKeys.has(key)) continue;
|
|
2714
|
+
if (Array.isArray(value)) {
|
|
2715
|
+
for (const item of value) if (isAstNode(item)) children.push(item);
|
|
2716
|
+
continue;
|
|
2717
|
+
}
|
|
2718
|
+
if (isAstNode(value)) children.push(value);
|
|
2719
|
+
}
|
|
2720
|
+
return children;
|
|
2721
|
+
}
|
|
2722
|
+
function asNodes(value) {
|
|
2723
|
+
return Array.isArray(value) ? value.filter(isAstNode) : [];
|
|
2724
|
+
}
|
|
2725
|
+
function isAstNode(value) {
|
|
2726
|
+
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
2727
|
+
}
|
|
2728
|
+
function identifierName(node) {
|
|
2729
|
+
return node?.type === "Identifier" && typeof node.name === "string" ? node.name : void 0;
|
|
2730
|
+
}
|
|
2731
|
+
const ignoredAstKeys = new Set([
|
|
2732
|
+
"closingElement",
|
|
2733
|
+
"id",
|
|
2734
|
+
"leadingComments",
|
|
2735
|
+
"loc",
|
|
2736
|
+
"metadata",
|
|
2737
|
+
"openingElement",
|
|
2738
|
+
"parent",
|
|
2739
|
+
"range",
|
|
2740
|
+
"trailingComments"
|
|
2741
|
+
]);
|
|
2742
|
+
//#endregion
|
|
2743
|
+
//#region src/build/symbol-facade-cleanup.ts
|
|
2744
|
+
const TSRX_SOURCE_FILE$1 = /\.tsrx(?:[?#].*)?$/;
|
|
2745
|
+
const SYMBOL_INIT_EXPORT_PREFIX = "init__virtual_markless_symbol";
|
|
2746
|
+
const STRING_LITERAL_SOURCE = String.raw`(?:"[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*'|` + "`[^`\\\\]*(?:\\\\.[^`\\\\]*)*`)";
|
|
2747
|
+
const FUNCTION_DECLARATION_RE = /\bfunction\s+([$A-Z_a-z][$\w]*)\s*\(\s*([$A-Z_a-z][$\w]*)\s*\)\s*\{/g;
|
|
2748
|
+
const LOCAL_DYNAMIC_IMPORT_HELPER_RE = /import\(\s*(["'`])([^"'`]+)\1\s*\)\.then\(\s*\(?\s*([$A-Z_a-z][$\w]*)\s*\)?\s*=>\s*([$A-Z_a-z][$\w]*)\(\s*\3\s*,\s*(["'`])([^"'`]*)\5\s*\)\s*\)/g;
|
|
2749
|
+
const LOCAL_DYNAMIC_IMPORT_RE = /import\(\s*(["'`])([^"'`]+)\1\s*\)(?:\.then\(\s*\(?\s*([$A-Z_a-z][$\w]*)\s*\)?\s*=>\s*\3\.([$A-Z_a-z][$\w]*)\s*\))?/g;
|
|
2750
|
+
function rewriteGeneratedSymbolFacadeImports(bundle) {
|
|
2751
|
+
const chunks = collectChunks(bundle);
|
|
2752
|
+
const rewrites = findSymbolFacadeRewrites(chunks);
|
|
2753
|
+
const removedFacades = /* @__PURE__ */ new Set();
|
|
2754
|
+
if (rewrites.size === 0) return removedFacades;
|
|
2755
|
+
for (const chunk of chunks.values()) {
|
|
2756
|
+
if (!isGeneratedAsyncChunk(chunk)) continue;
|
|
2757
|
+
const result = rewriteDynamicImportSpecifiers(chunk, rewrites);
|
|
2758
|
+
chunk.code = result.code;
|
|
2759
|
+
chunk.dynamicImports = unique(chunk.dynamicImports.map((fileName) => result.rewrittenFacades.has(fileName) ? rewrites.get(fileName)?.target.fileName ?? fileName : fileName));
|
|
2760
|
+
}
|
|
2761
|
+
for (const rewrite of rewrites.values()) {
|
|
2762
|
+
const facadeId = rewrite.facade.facadeModuleId;
|
|
2763
|
+
if (facadeId && !rewrite.target.moduleIds.includes(facadeId)) rewrite.target.moduleIds = [...rewrite.target.moduleIds, facadeId];
|
|
2764
|
+
}
|
|
2765
|
+
for (const rewrite of rewrites.values()) {
|
|
2766
|
+
deleteBundleChunk(bundle, rewrite.facade.fileName);
|
|
2767
|
+
chunks.delete(rewrite.facade.fileName);
|
|
2768
|
+
removedFacades.add(rewrite.facade.fileName);
|
|
2769
|
+
}
|
|
2770
|
+
return removedFacades;
|
|
2771
|
+
}
|
|
2772
|
+
function rewriteGeneratedSymbolInitExports(bundle) {
|
|
2773
|
+
const chunks = collectChunks(bundle);
|
|
2774
|
+
const rewrites = findSymbolInitExportRewrites(chunks);
|
|
2775
|
+
if (rewrites.length === 0) return { renamed: 0 };
|
|
2776
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
2777
|
+
for (const rewrite of rewrites) {
|
|
2778
|
+
rewrite.chunk.exports = rewrite.collapsed ? [...rewrite.collapsed.exports] : rewrite.chunk.exports.map((name) => rewrite.names.get(name) ?? name);
|
|
2779
|
+
if (rewrite.collapsed) rewrite.chunk.code = rewrite.collapsed.code;
|
|
2780
|
+
for (const [from, to] of rewrite.names) replacements.set(from, to);
|
|
2781
|
+
}
|
|
2782
|
+
for (const chunk of chunks.values()) {
|
|
2783
|
+
if (!isGeneratedAsyncChunk(chunk)) continue;
|
|
2784
|
+
chunk.code = replaceIdentifierNames(chunk.code, replacements);
|
|
2785
|
+
}
|
|
2786
|
+
return { renamed: replacements.size };
|
|
2787
|
+
}
|
|
2788
|
+
function compactGeneratedDirectSymbolLoaders(bundle) {
|
|
2789
|
+
let compacted = 0;
|
|
2790
|
+
for (const chunk of collectChunks(bundle).values()) {
|
|
2791
|
+
if (!isGeneratedAsyncChunk(chunk)) continue;
|
|
2792
|
+
if (!chunk.code.includes("?import(")) continue;
|
|
2793
|
+
const result = compactDirectSymbolLoadersInCode(chunk.code);
|
|
2794
|
+
if (result.compacted === 0) continue;
|
|
2795
|
+
chunk.code = result.code;
|
|
2796
|
+
compacted += result.compacted;
|
|
2797
|
+
}
|
|
2798
|
+
return { compacted };
|
|
2799
|
+
}
|
|
2800
|
+
function collectChunks(bundle) {
|
|
2801
|
+
const chunks = /* @__PURE__ */ new Map();
|
|
2802
|
+
for (const output of Object.values(bundle)) if (isGeneratedChunk(output)) chunks.set(output.fileName, output);
|
|
2803
|
+
return chunks;
|
|
2804
|
+
}
|
|
2805
|
+
function findSymbolFacadeRewrites(chunks) {
|
|
2806
|
+
const rewrites = /* @__PURE__ */ new Map();
|
|
2807
|
+
for (const chunk of chunks.values()) {
|
|
2808
|
+
const rewrite = findSymbolFacadeRewrite(chunk, chunks);
|
|
2809
|
+
if (rewrite) rewrites.set(chunk.fileName, rewrite);
|
|
2810
|
+
}
|
|
2811
|
+
return rewrites;
|
|
2812
|
+
}
|
|
2813
|
+
function findSymbolInitExportRewrites(chunks) {
|
|
2814
|
+
const rewrites = [];
|
|
2815
|
+
for (const chunk of chunks.values()) {
|
|
2816
|
+
const rewrite = findSymbolInitExportRewrite(chunk);
|
|
2817
|
+
if (rewrite) rewrites.push(rewrite);
|
|
2818
|
+
}
|
|
2819
|
+
return rewrites;
|
|
2820
|
+
}
|
|
2821
|
+
function findSymbolInitExportRewrite(chunk) {
|
|
2822
|
+
if (!isGeneratedAsyncChunk(chunk)) return void 0;
|
|
2823
|
+
const initExports = chunk.exports.filter(isGeneratedSymbolInitExport);
|
|
2824
|
+
if (initExports.length === 0) return void 0;
|
|
2825
|
+
const names = /* @__PURE__ */ new Map();
|
|
2826
|
+
const used = new Set(chunk.exports.filter((name) => !isGeneratedSymbolInitExport(name)));
|
|
2827
|
+
const collapsed = collapseGeneratedSymbolInitExports(chunk.code, initExports);
|
|
2828
|
+
if (collapsed) {
|
|
2829
|
+
for (const name of initExports) if (name !== SYMBOL_INIT_EXPORT_PREFIX) names.set(name, SYMBOL_INIT_EXPORT_PREFIX);
|
|
2830
|
+
return {
|
|
2831
|
+
chunk,
|
|
2832
|
+
names,
|
|
2833
|
+
collapsed
|
|
2834
|
+
};
|
|
2835
|
+
}
|
|
2836
|
+
for (const name of initExports) {
|
|
2837
|
+
const next = compactSymbolInitExportName(name, used);
|
|
2838
|
+
used.add(next);
|
|
2839
|
+
if (next !== name) names.set(name, next);
|
|
2840
|
+
}
|
|
2841
|
+
return names.size > 0 ? {
|
|
2842
|
+
chunk,
|
|
2843
|
+
names
|
|
2844
|
+
} : void 0;
|
|
2845
|
+
}
|
|
2846
|
+
function findSymbolFacadeRewrite(chunk, chunks) {
|
|
2847
|
+
if (!isGeneratedSymbolFacade(chunk)) return void 0;
|
|
2848
|
+
if (chunk.imports.length !== 1 || chunk.dynamicImports.length > 0) return void 0;
|
|
2849
|
+
const parsed = parseSymbolFacade(chunk.code);
|
|
2850
|
+
if (!parsed) return void 0;
|
|
2851
|
+
const target = chunks.get(chunk.imports[0]);
|
|
2852
|
+
if (!target) return void 0;
|
|
2853
|
+
const targetExports = new Set(target.exports);
|
|
2854
|
+
if (!chunk.exports.every((name) => targetExports.has(name))) return void 0;
|
|
2855
|
+
if (!parsed.initExports.every((name) => targetExports.has(name))) return void 0;
|
|
2856
|
+
return {
|
|
2857
|
+
facade: chunk,
|
|
2858
|
+
target,
|
|
2859
|
+
initExports: parsed.initExports
|
|
2860
|
+
};
|
|
2861
|
+
}
|
|
2862
|
+
function isGeneratedSymbolFacade(chunk) {
|
|
2863
|
+
return (chunk.facadeModuleId ? normalizeVirtualId$1(chunk.facadeModuleId) : "").startsWith(`${MARKLESS_VIRTUAL_PREFIX}symbol:`);
|
|
2864
|
+
}
|
|
2865
|
+
function isGeneratedSymbolInitExport(name) {
|
|
2866
|
+
return name === SYMBOL_INIT_EXPORT_PREFIX || name.startsWith(`${SYMBOL_INIT_EXPORT_PREFIX}_`) || /^\$\d+$/.test(name.slice(29));
|
|
2867
|
+
}
|
|
2868
|
+
function compactSymbolInitExportName(name, used) {
|
|
2869
|
+
const suffix = name.match(/\$(\d+)$/)?.[1];
|
|
2870
|
+
let candidate = suffix ? `${SYMBOL_INIT_EXPORT_PREFIX}$${suffix}` : SYMBOL_INIT_EXPORT_PREFIX;
|
|
2871
|
+
let nextSuffix = suffix ? Number(suffix) : 0;
|
|
2872
|
+
while (used.has(candidate)) {
|
|
2873
|
+
nextSuffix++;
|
|
2874
|
+
candidate = `${SYMBOL_INIT_EXPORT_PREFIX}$${nextSuffix}`;
|
|
2875
|
+
}
|
|
2876
|
+
return candidate;
|
|
2877
|
+
}
|
|
2878
|
+
function collapseGeneratedSymbolInitExports(code, initExports) {
|
|
2879
|
+
if (initExports.length < 2) return void 0;
|
|
2880
|
+
const match = code.match(/export\s*\{\s*([^}]*)\s*\}\s*;?\s*$/);
|
|
2881
|
+
if (!match || match.index === void 0) return void 0;
|
|
2882
|
+
const specifiers = parseExportSpecifiers(match[1]);
|
|
2883
|
+
if (!specifiers) return void 0;
|
|
2884
|
+
if (specifiers.some((specifier) => !isIdentifier(specifier.local))) return void 0;
|
|
2885
|
+
const initExportSet = new Set(initExports);
|
|
2886
|
+
const initLocals = unique(specifiers.filter((specifier) => initExportSet.has(specifier.exported)).map((specifier) => specifier.local));
|
|
2887
|
+
if (initLocals.length < 2) return void 0;
|
|
2888
|
+
const nonInitSpecifiers = specifiers.filter((specifier) => !initExportSet.has(specifier.exported));
|
|
2889
|
+
if (nonInitSpecifiers.some((specifier) => specifier.exported === SYMBOL_INIT_EXPORT_PREFIX)) return;
|
|
2890
|
+
const initLocal = uniqueIdentifier("$i", code);
|
|
2891
|
+
return {
|
|
2892
|
+
code: `${code.slice(0, match.index)}function ${initLocal}(){${initLocals.map((local) => `${local}()`).join(";")}}export{${[`${initLocal} as ${SYMBOL_INIT_EXPORT_PREFIX}`, ...nonInitSpecifiers.map(formatExportSpecifier)].join(",")}};`,
|
|
2893
|
+
exports: [SYMBOL_INIT_EXPORT_PREFIX, ...nonInitSpecifiers.map((specifier) => specifier.exported)]
|
|
2894
|
+
};
|
|
2895
|
+
}
|
|
2896
|
+
function rewriteDynamicImportSpecifiers(chunk, rewrites) {
|
|
2897
|
+
const rewrittenFacades = /* @__PURE__ */ new Set();
|
|
2898
|
+
return {
|
|
2899
|
+
code: chunk.code.replace(LOCAL_DYNAMIC_IMPORT_HELPER_RE, (match, quote, specifier, parameter, helperName, exportQuote, exportName) => {
|
|
2900
|
+
if (!isLocalSpecifier(specifier)) return match;
|
|
2901
|
+
const importedFileName = resolveChunkSpecifier(chunk.fileName, specifier);
|
|
2902
|
+
const rewrite = rewrites.get(importedFileName);
|
|
2903
|
+
if (!rewrite) return match;
|
|
2904
|
+
if (!rewrite.target.exports.includes(exportName)) return match;
|
|
2905
|
+
const nextSpecifier = relativeChunkSpecifier(chunk.fileName, rewrite.target.fileName);
|
|
2906
|
+
rewrittenFacades.add(importedFileName);
|
|
2907
|
+
return `import(${quote}${nextSpecifier}${quote}).then(${parameter}=>${helperName}(${parameter},${exportQuote}${exportName}${exportQuote}))`;
|
|
2908
|
+
}).replace(LOCAL_DYNAMIC_IMPORT_RE, (match, quote, specifier, parameter, exportName) => {
|
|
2909
|
+
if (!isLocalSpecifier(specifier)) return match;
|
|
2910
|
+
const importedFileName = resolveChunkSpecifier(chunk.fileName, specifier);
|
|
2911
|
+
const rewrite = rewrites.get(importedFileName);
|
|
2912
|
+
if (!rewrite) return match;
|
|
2913
|
+
if (rewrite.initExports.length > 0 && (!parameter || !exportName)) return match;
|
|
2914
|
+
const nextSpecifier = relativeChunkSpecifier(chunk.fileName, rewrite.target.fileName);
|
|
2915
|
+
rewrittenFacades.add(importedFileName);
|
|
2916
|
+
const nextImport = `import(${quote}${nextSpecifier}${quote})`;
|
|
2917
|
+
if (!parameter || !exportName || rewrite.initExports.length === 0) return nextImport;
|
|
2918
|
+
return `${nextImport}.then(${parameter}=>(${[...rewrite.initExports.map((name) => `${parameter}.${name}()`), `${parameter}.${exportName}`].join(",")}))`;
|
|
2919
|
+
}),
|
|
2920
|
+
rewrittenFacades
|
|
2921
|
+
};
|
|
2922
|
+
}
|
|
2923
|
+
function compactDirectSymbolLoadersInCode(code) {
|
|
2924
|
+
let next = "";
|
|
2925
|
+
let cursor = 0;
|
|
2926
|
+
let compacted = 0;
|
|
2927
|
+
for (let match = FUNCTION_DECLARATION_RE.exec(code); match; match = FUNCTION_DECLARATION_RE.exec(code)) {
|
|
2928
|
+
const functionStart = match.index;
|
|
2929
|
+
const bodyStart = FUNCTION_DECLARATION_RE.lastIndex;
|
|
2930
|
+
const bodyEnd = findBlockEnd(code, bodyStart - 1);
|
|
2931
|
+
if (bodyEnd < 0) continue;
|
|
2932
|
+
const body = code.slice(bodyStart, bodyEnd);
|
|
2933
|
+
const mapName = uniqueIdentifier("$s", `${code}${next}`);
|
|
2934
|
+
const moduleCacheName = uniqueIdentifier("$m", `${code}${next}${mapName}`);
|
|
2935
|
+
const replacement = compactDirectSymbolLoaderFunction({
|
|
2936
|
+
functionName: match[1],
|
|
2937
|
+
parameterName: match[2],
|
|
2938
|
+
body,
|
|
2939
|
+
mapName,
|
|
2940
|
+
moduleCacheName
|
|
2941
|
+
});
|
|
2942
|
+
if (!replacement) {
|
|
2943
|
+
FUNCTION_DECLARATION_RE.lastIndex = bodyEnd + 1;
|
|
2944
|
+
continue;
|
|
2945
|
+
}
|
|
2946
|
+
next += code.slice(cursor, functionStart);
|
|
2947
|
+
next += replacement;
|
|
2948
|
+
cursor = bodyEnd + 1;
|
|
2949
|
+
compacted++;
|
|
2950
|
+
FUNCTION_DECLARATION_RE.lastIndex = cursor;
|
|
2951
|
+
}
|
|
2952
|
+
if (compacted === 0) return {
|
|
2953
|
+
code,
|
|
2954
|
+
compacted
|
|
2955
|
+
};
|
|
2956
|
+
return {
|
|
2957
|
+
code: next + code.slice(cursor),
|
|
2958
|
+
compacted
|
|
2959
|
+
};
|
|
2960
|
+
}
|
|
2961
|
+
function compactDirectSymbolLoaderFunction(input) {
|
|
2962
|
+
const returnSource = input.body.trim();
|
|
2963
|
+
if (!returnSource.startsWith("return ")) return void 0;
|
|
2964
|
+
const parsed = parseDirectSymbolLoaderBranches(returnSource.slice(7), input.parameterName);
|
|
2965
|
+
if (!parsed) return void 0;
|
|
2966
|
+
const first = parsed.branches[0];
|
|
2967
|
+
if (parsed.branches.some((branch) => branch.importSpecifier !== first.importSpecifier || branch.helperName !== first.helperName)) return;
|
|
2968
|
+
const generatedCount = generatedSymbolRangeCount(parsed.branches);
|
|
2969
|
+
if (generatedCount !== void 0) return [
|
|
2970
|
+
`let ${input.moduleCacheName};`,
|
|
2971
|
+
`function ${input.functionName}(${input.parameterName}){`,
|
|
2972
|
+
`let t=+${input.parameterName}.slice(7);`,
|
|
2973
|
+
`if(${input.parameterName}===\`symbol:\${t}\`&&t>=0&&t<${generatedCount}){`,
|
|
2974
|
+
`if(${input.moduleCacheName})return ${first.helperName}(${input.moduleCacheName},\`symbol_\${t}\`);`,
|
|
2975
|
+
`return import(${JSON.stringify(first.importSpecifier)})`,
|
|
2976
|
+
`.then(${first.moduleParameter}=>(${input.moduleCacheName}=${first.moduleParameter},${first.helperName}(${first.moduleParameter},\`symbol_\${t}\`)))`,
|
|
2977
|
+
`}`,
|
|
2978
|
+
`return ${parsed.fallback}`,
|
|
2979
|
+
"}"
|
|
2980
|
+
].join("");
|
|
2981
|
+
const exportVariable = input.parameterName === "t" ? "n" : "t";
|
|
2982
|
+
const mapEntries = parsed.branches.map((branch) => `${JSON.stringify(branch.symbolId)}:${JSON.stringify(branch.exportName)}`).join(",");
|
|
2983
|
+
return [
|
|
2984
|
+
`const ${input.mapName}={${mapEntries}};`,
|
|
2985
|
+
`let ${input.moduleCacheName};`,
|
|
2986
|
+
`function ${input.functionName}(${input.parameterName}){`,
|
|
2987
|
+
`let ${exportVariable}=${input.mapName}[${input.parameterName}];`,
|
|
2988
|
+
`if(${exportVariable}){`,
|
|
2989
|
+
`if(${input.moduleCacheName})return ${first.helperName}(${input.moduleCacheName},${exportVariable});`,
|
|
2990
|
+
`return import(${JSON.stringify(first.importSpecifier)})`,
|
|
2991
|
+
`.then(${first.moduleParameter}=>(${input.moduleCacheName}=${first.moduleParameter},${first.helperName}(${first.moduleParameter},${exportVariable})))`,
|
|
2992
|
+
`}`,
|
|
2993
|
+
`return ${parsed.fallback}`,
|
|
2994
|
+
"}"
|
|
2995
|
+
].join("");
|
|
2996
|
+
}
|
|
2997
|
+
function parseDirectSymbolLoaderBranches(source, parameterName) {
|
|
2998
|
+
const branches = [];
|
|
2999
|
+
const branchRE = directSymbolLoaderBranchRE(parameterName);
|
|
3000
|
+
let cursor = 0;
|
|
3001
|
+
while (cursor < source.length) {
|
|
3002
|
+
const match = source.slice(cursor).match(branchRE);
|
|
3003
|
+
if (!match) break;
|
|
3004
|
+
const symbolId = simpleStringLiteralValue(match[1]);
|
|
3005
|
+
const importSpecifier = simpleStringLiteralValue(match[2]);
|
|
3006
|
+
const moduleParameter = match[3];
|
|
3007
|
+
const helperName = match[4];
|
|
3008
|
+
const helperArgument = match[5];
|
|
3009
|
+
const exportName = simpleStringLiteralValue(match[6]);
|
|
3010
|
+
if (symbolId === void 0 || importSpecifier === void 0 || exportName === void 0 || moduleParameter !== helperArgument) return;
|
|
3011
|
+
branches.push({
|
|
3012
|
+
symbolId,
|
|
3013
|
+
importSpecifier,
|
|
3014
|
+
moduleParameter,
|
|
3015
|
+
helperName,
|
|
3016
|
+
exportName
|
|
3017
|
+
});
|
|
3018
|
+
cursor += match[0].length;
|
|
3019
|
+
}
|
|
3020
|
+
const fallback = source.slice(cursor);
|
|
3021
|
+
if (branches.length < 2 || !fallback.startsWith("Promise.reject(")) return void 0;
|
|
3022
|
+
return {
|
|
3023
|
+
branches,
|
|
3024
|
+
fallback
|
|
3025
|
+
};
|
|
3026
|
+
}
|
|
3027
|
+
function generatedSymbolRangeCount(branches) {
|
|
3028
|
+
for (const [index, branch] of branches.entries()) if (branch.symbolId !== `symbol:${index}` || branch.exportName !== `symbol_${index}`) return;
|
|
3029
|
+
return branches.length;
|
|
3030
|
+
}
|
|
3031
|
+
function directSymbolLoaderBranchRE(parameterName) {
|
|
3032
|
+
return new RegExp(`^${escapeRegExp(parameterName)}\\s*===\\s*(${STRING_LITERAL_SOURCE})\\s*\\?\\s*import\\(\\s*(${STRING_LITERAL_SOURCE})\\s*\\)\\.then\\(\\s*\\(?\\s*([$A-Z_a-z][$\\w]*)\\s*\\)?\\s*=>\\s*([$A-Z_a-z][$\\w]*)\\(\\s*([$A-Z_a-z][$\\w]*)\\s*,\\s*(${STRING_LITERAL_SOURCE})\\s*\\)\\s*\\)\\s*:`);
|
|
3033
|
+
}
|
|
3034
|
+
function simpleStringLiteralValue(source) {
|
|
3035
|
+
const quote = source[0];
|
|
3036
|
+
if (quote !== "\"" && quote !== "'" && quote !== "`" || source[source.length - 1] !== quote) return;
|
|
3037
|
+
return source.slice(1, -1);
|
|
3038
|
+
}
|
|
3039
|
+
function findBlockEnd(code, open) {
|
|
3040
|
+
let depth = 0;
|
|
3041
|
+
let quote = null;
|
|
3042
|
+
let escaped = false;
|
|
3043
|
+
for (let index = open; index < code.length; index++) {
|
|
3044
|
+
const char = code[index];
|
|
3045
|
+
if (quote) {
|
|
3046
|
+
if (escaped) {
|
|
3047
|
+
escaped = false;
|
|
3048
|
+
continue;
|
|
3049
|
+
}
|
|
3050
|
+
if (char === "\\") {
|
|
3051
|
+
escaped = true;
|
|
3052
|
+
continue;
|
|
3053
|
+
}
|
|
3054
|
+
if (char === quote) quote = null;
|
|
3055
|
+
continue;
|
|
3056
|
+
}
|
|
3057
|
+
if (char === "\"" || char === "'" || char === "`") {
|
|
3058
|
+
quote = char;
|
|
3059
|
+
continue;
|
|
3060
|
+
}
|
|
3061
|
+
if (char === "{") {
|
|
3062
|
+
depth++;
|
|
3063
|
+
continue;
|
|
3064
|
+
}
|
|
3065
|
+
if (char === "}") {
|
|
3066
|
+
depth--;
|
|
3067
|
+
if (depth === 0) return index;
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
return -1;
|
|
3071
|
+
}
|
|
3072
|
+
function resolveChunkSpecifier(importerFileName, specifier) {
|
|
3073
|
+
return normalize(join(dirname(importerFileName), specifier));
|
|
3074
|
+
}
|
|
3075
|
+
function relativeChunkSpecifier(importerFileName, targetFileName) {
|
|
3076
|
+
const value = relative(dirname(importerFileName), targetFileName).replaceAll("\\", "/");
|
|
3077
|
+
return value.startsWith(".") ? value : `./${value}`;
|
|
3078
|
+
}
|
|
3079
|
+
function isGeneratedAsyncChunk(chunk) {
|
|
3080
|
+
return chunk.moduleIds.some((id) => {
|
|
3081
|
+
return normalizeVirtualId$1(id).startsWith("virtual:markless:") || TSRX_SOURCE_FILE$1.test(id);
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
function deleteBundleChunk(bundle, fileName) {
|
|
3085
|
+
for (const [key, output] of Object.entries(bundle)) if (isGeneratedChunk(output) && output.fileName === fileName) delete bundle[key];
|
|
3086
|
+
}
|
|
3087
|
+
function isGeneratedChunk(value) {
|
|
3088
|
+
if (!value || typeof value !== "object") return false;
|
|
3089
|
+
const chunk = value;
|
|
3090
|
+
return chunk.type === "chunk" && typeof chunk.fileName === "string" && typeof chunk.code === "string" && Array.isArray(chunk.exports) && Array.isArray(chunk.imports) && Array.isArray(chunk.dynamicImports) && Array.isArray(chunk.moduleIds);
|
|
3091
|
+
}
|
|
3092
|
+
function unique(values) {
|
|
3093
|
+
return [...new Set(values)];
|
|
3094
|
+
}
|
|
3095
|
+
function replaceIdentifierNames(code, replacements) {
|
|
3096
|
+
const names = [...replacements.keys()].sort((a, b) => b.length - a.length);
|
|
3097
|
+
let next = code;
|
|
3098
|
+
for (const name of names) next = next.replace(identifierNameRE(name), replacements.get(name));
|
|
3099
|
+
return next;
|
|
3100
|
+
}
|
|
3101
|
+
function identifierNameRE(name) {
|
|
3102
|
+
return new RegExp(`(?<![$\\w])${escapeRegExp(name)}(?![$\\w])`, "g");
|
|
3103
|
+
}
|
|
3104
|
+
function escapeRegExp(value) {
|
|
3105
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3106
|
+
}
|
|
3107
|
+
function isLocalSpecifier(specifier) {
|
|
3108
|
+
return specifier.startsWith("./") || specifier.startsWith("../");
|
|
3109
|
+
}
|
|
3110
|
+
function parseSymbolFacade(code) {
|
|
3111
|
+
const match = code.trim().match(/^import\s*\{\s*([^}]*)\s*\}\s*from\s*(["'`])([^"'`]+)\2\s*;\s*([\s\S]*?)\s*export\s*\{\s*([^}]*)\s*\}\s*;?\s*$/);
|
|
3112
|
+
if (!match) return void 0;
|
|
3113
|
+
const imports = parseImportSpecifiers(match[1]);
|
|
3114
|
+
const exportLocals = parseExportLocalNames(match[5]);
|
|
3115
|
+
if (!imports || !exportLocals) return void 0;
|
|
3116
|
+
const body = match[4].trim();
|
|
3117
|
+
const initLocals = body ? body.split(";").map((statement) => statement.trim()).filter(Boolean).map((statement) => statement.match(/^([$A-Z_a-z][$\w]*)\(\)$/)?.[1]) : [];
|
|
3118
|
+
if (initLocals.some((name) => !name)) return void 0;
|
|
3119
|
+
for (const local of exportLocals) if (!imports.has(local)) return void 0;
|
|
3120
|
+
return { initExports: unique(initLocals.filter((local) => !!local).map((local) => imports.get(local)).filter((name) => !!name)) };
|
|
3121
|
+
}
|
|
3122
|
+
function parseImportSpecifiers(value) {
|
|
3123
|
+
const imports = /* @__PURE__ */ new Map();
|
|
3124
|
+
for (const part of value.split(",")) {
|
|
3125
|
+
const specifier = part.trim();
|
|
3126
|
+
if (!specifier) continue;
|
|
3127
|
+
const aliased = specifier.match(/^(.+?)\s+as\s+(.+)$/);
|
|
3128
|
+
const imported = (aliased?.[1] ?? specifier).trim();
|
|
3129
|
+
const local = (aliased?.[2] ?? specifier).trim();
|
|
3130
|
+
if (!isIdentifier(imported) || !isIdentifier(local)) return void 0;
|
|
3131
|
+
imports.set(local, imported);
|
|
3132
|
+
}
|
|
3133
|
+
return imports;
|
|
3134
|
+
}
|
|
3135
|
+
function parseExportLocalNames(value) {
|
|
3136
|
+
const locals = [];
|
|
3137
|
+
for (const part of value.split(",")) {
|
|
3138
|
+
const specifier = part.trim();
|
|
3139
|
+
if (!specifier) continue;
|
|
3140
|
+
const aliased = specifier.match(/^(.+?)\s+as\s+(.+)$/);
|
|
3141
|
+
const local = (aliased?.[1] ?? specifier).trim();
|
|
3142
|
+
const exported = (aliased?.[2] ?? specifier).trim();
|
|
3143
|
+
if (!isIdentifier(local) || !isIdentifier(exported)) return void 0;
|
|
3144
|
+
locals.push(local);
|
|
3145
|
+
}
|
|
3146
|
+
return locals;
|
|
3147
|
+
}
|
|
3148
|
+
function parseExportSpecifiers(value) {
|
|
3149
|
+
const specifiers = [];
|
|
3150
|
+
for (const part of value.split(",")) {
|
|
3151
|
+
const specifier = part.trim();
|
|
3152
|
+
if (!specifier) continue;
|
|
3153
|
+
const aliased = specifier.match(/^(.+?)\s+as\s+(.+)$/);
|
|
3154
|
+
const local = (aliased?.[1] ?? specifier).trim();
|
|
3155
|
+
const exported = (aliased?.[2] ?? specifier).trim();
|
|
3156
|
+
if (!isIdentifier(local) || !isIdentifier(exported)) return void 0;
|
|
3157
|
+
specifiers.push({
|
|
3158
|
+
local,
|
|
3159
|
+
exported
|
|
3160
|
+
});
|
|
3161
|
+
}
|
|
3162
|
+
return specifiers;
|
|
3163
|
+
}
|
|
3164
|
+
function formatExportSpecifier(specifier) {
|
|
3165
|
+
return specifier.local === specifier.exported ? specifier.local : `${specifier.local} as ${specifier.exported}`;
|
|
3166
|
+
}
|
|
3167
|
+
function uniqueIdentifier(base, code) {
|
|
3168
|
+
let candidate = base;
|
|
3169
|
+
let index = 0;
|
|
3170
|
+
while (identifierNameRE(candidate).test(code)) {
|
|
3171
|
+
index++;
|
|
3172
|
+
candidate = `${base}${index}`;
|
|
3173
|
+
}
|
|
3174
|
+
return candidate;
|
|
3175
|
+
}
|
|
3176
|
+
function isIdentifier(value) {
|
|
3177
|
+
return /^[$A-Z_a-z][$\w]*$/.test(value);
|
|
3178
|
+
}
|
|
3179
|
+
function normalizeVirtualId$1(id) {
|
|
3180
|
+
return id.startsWith("\0") ? id.slice(1) : id;
|
|
3181
|
+
}
|
|
3182
|
+
//#endregion
|
|
3183
|
+
//#region src/dev.ts
|
|
3184
|
+
function createMarklessDevGraph() {
|
|
3185
|
+
const parentModules = /* @__PURE__ */ new Map();
|
|
3186
|
+
return {
|
|
3187
|
+
record(parent, ids, environment) {
|
|
3188
|
+
const entries = [...ids];
|
|
3189
|
+
for (const path of parentKeys(parent)) {
|
|
3190
|
+
const key = parentKey(environment, path);
|
|
3191
|
+
const existing = parentModules.get(key) ?? /* @__PURE__ */ new Set();
|
|
3192
|
+
for (const id of entries) existing.add(id);
|
|
3193
|
+
parentModules.set(key, existing);
|
|
3194
|
+
}
|
|
3195
|
+
},
|
|
3196
|
+
clear(parent, environment) {
|
|
3197
|
+
const deleted = [];
|
|
3198
|
+
for (const currentEnvironment of targetEnvironments(environment)) for (const path of parentKeys(parent)) {
|
|
3199
|
+
const key = parentKey(currentEnvironment, path);
|
|
3200
|
+
const ids = parentModules.get(key);
|
|
3201
|
+
if (!ids) continue;
|
|
3202
|
+
deleted.push(...ids);
|
|
3203
|
+
parentModules.delete(key);
|
|
3204
|
+
}
|
|
3205
|
+
return [...new Set(deleted)];
|
|
3206
|
+
},
|
|
3207
|
+
reset() {
|
|
3208
|
+
parentModules.clear();
|
|
3209
|
+
}
|
|
3210
|
+
};
|
|
3211
|
+
}
|
|
3212
|
+
function targetEnvironments(environment) {
|
|
3213
|
+
if (environment) return [environment];
|
|
3214
|
+
return allEnvironments;
|
|
3215
|
+
}
|
|
3216
|
+
const allEnvironments = [
|
|
3217
|
+
"client",
|
|
3218
|
+
"server",
|
|
3219
|
+
"lib"
|
|
3220
|
+
];
|
|
3221
|
+
function parentKeys(parent) {
|
|
3222
|
+
const path = pathname$1(parent);
|
|
3223
|
+
const normalized = normalize(path);
|
|
3224
|
+
const leadingPath = withLeadingSlash(normalized);
|
|
3225
|
+
const barePath = leadingPath.slice(1);
|
|
3226
|
+
return new Set([
|
|
3227
|
+
path,
|
|
3228
|
+
normalized,
|
|
3229
|
+
leadingPath,
|
|
3230
|
+
barePath
|
|
3231
|
+
]);
|
|
3232
|
+
}
|
|
3233
|
+
function parentKey(environment, parent) {
|
|
3234
|
+
return `${environment}:${parent}`;
|
|
3235
|
+
}
|
|
3236
|
+
function pathname$1(id) {
|
|
3237
|
+
return parsePath(id).pathname;
|
|
3238
|
+
}
|
|
3239
|
+
//#endregion
|
|
3240
|
+
//#region src/module-metadata-registry.ts
|
|
3241
|
+
/**
|
|
3242
|
+
* Capture data follows authored source identity. Symbol claims follow the exact
|
|
3243
|
+
* emitted module identity that owns the corresponding loadSymbol route.
|
|
3244
|
+
*/
|
|
3245
|
+
var ModuleMetadataRegistry = class {
|
|
3246
|
+
#captureManifestsBySource = /* @__PURE__ */ new Map();
|
|
3247
|
+
#symbolClaimsByEmittedModule = /* @__PURE__ */ new Map();
|
|
3248
|
+
#sourceClaimPublications = /* @__PURE__ */ new Map();
|
|
3249
|
+
clear() {
|
|
3250
|
+
this.#captureManifestsBySource.clear();
|
|
3251
|
+
this.#symbolClaimsByEmittedModule.clear();
|
|
3252
|
+
this.#sourceClaimPublications.clear();
|
|
3253
|
+
}
|
|
3254
|
+
recordCaptureMetadata(source, manifest) {
|
|
3255
|
+
if (manifest.captureMetadata) this.#captureManifestsBySource.set(source, manifest);
|
|
3256
|
+
else this.#captureManifestsBySource.delete(source);
|
|
3257
|
+
}
|
|
3258
|
+
captureMetadataForSource(source) {
|
|
3259
|
+
return this.#captureManifestsBySource.get(source)?.captureMetadata;
|
|
3260
|
+
}
|
|
3261
|
+
deleteCaptureMetadata(source) {
|
|
3262
|
+
this.#captureManifestsBySource.delete(source);
|
|
3263
|
+
}
|
|
3264
|
+
recordSymbolClaims(emittedModule, manifest) {
|
|
3265
|
+
this.#symbolClaimsByEmittedModule.set(emittedModule, manifest);
|
|
3266
|
+
}
|
|
3267
|
+
deleteSymbolClaims(emittedModule) {
|
|
3268
|
+
this.#symbolClaimsByEmittedModule.delete(emittedModule);
|
|
3269
|
+
}
|
|
3270
|
+
hasSymbolClaims(emittedModule) {
|
|
3271
|
+
return this.#symbolClaimsByEmittedModule.has(emittedModule);
|
|
3272
|
+
}
|
|
3273
|
+
beginSourceSymbolClaims(source, emittedModule) {
|
|
3274
|
+
const publication = this.#sourceClaimPublications.get(source) ?? {
|
|
3275
|
+
active: 0,
|
|
3276
|
+
expected: /* @__PURE__ */ new Set(),
|
|
3277
|
+
finalized: /* @__PURE__ */ new Set(),
|
|
3278
|
+
pending: /* @__PURE__ */ new Set(),
|
|
3279
|
+
revision: 0,
|
|
3280
|
+
sealed: false,
|
|
3281
|
+
waiters: []
|
|
3282
|
+
};
|
|
3283
|
+
publication.sealed = false;
|
|
3284
|
+
publication.finalized.delete(emittedModule);
|
|
3285
|
+
if (publication.expected.has(emittedModule)) publication.pending.add(emittedModule);
|
|
3286
|
+
publication.active += 1;
|
|
3287
|
+
publication.revision += 1;
|
|
3288
|
+
this.#sourceClaimPublications.set(source, publication);
|
|
3289
|
+
}
|
|
3290
|
+
expectSourceSymbolClaims(source, emittedModules) {
|
|
3291
|
+
const publication = this.#sourceClaimPublications.get(source) ?? {
|
|
3292
|
+
active: 0,
|
|
3293
|
+
expected: /* @__PURE__ */ new Set(),
|
|
3294
|
+
finalized: /* @__PURE__ */ new Set(),
|
|
3295
|
+
pending: /* @__PURE__ */ new Set(),
|
|
3296
|
+
revision: 0,
|
|
3297
|
+
sealed: false,
|
|
3298
|
+
waiters: []
|
|
3299
|
+
};
|
|
3300
|
+
for (const emittedModule of emittedModules) {
|
|
3301
|
+
publication.expected.add(emittedModule);
|
|
3302
|
+
if (!publication.finalized.has(emittedModule)) publication.pending.add(emittedModule);
|
|
3303
|
+
}
|
|
3304
|
+
publication.sealed = false;
|
|
3305
|
+
publication.revision += 1;
|
|
3306
|
+
this.#sourceClaimPublications.set(source, publication);
|
|
3307
|
+
}
|
|
3308
|
+
finishSourceSymbolClaims(source, emittedModule) {
|
|
3309
|
+
const publication = this.#sourceClaimPublications.get(source);
|
|
3310
|
+
if (!publication || publication.active === 0) throw new Error(`MARKLESS_SOURCE_SYMBOL_CLAIMS_FINAL_WITHOUT_START: Source ${JSON.stringify(source)} published final claims without an active emitted variant.`);
|
|
3311
|
+
publication.active -= 1;
|
|
3312
|
+
publication.finalized.add(emittedModule);
|
|
3313
|
+
publication.pending.delete(emittedModule);
|
|
3314
|
+
publication.revision += 1;
|
|
3315
|
+
if (publication.active !== 0 || publication.pending.size !== 0) return;
|
|
3316
|
+
for (const resolve of publication.waiters.splice(0)) resolve();
|
|
3317
|
+
}
|
|
3318
|
+
async sealSourceSymbolClaims(source) {
|
|
3319
|
+
const publication = this.#sourceClaimPublications.get(source);
|
|
3320
|
+
if (!publication || publication.sealed) return;
|
|
3321
|
+
for (;;) {
|
|
3322
|
+
while (publication.active > 0 || publication.pending.size > 0) await new Promise((resolve) => publication.waiters.push(resolve));
|
|
3323
|
+
const revision = publication.revision;
|
|
3324
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3325
|
+
if (publication.revision === revision && publication.active === 0 && publication.pending.size === 0) break;
|
|
3326
|
+
}
|
|
3327
|
+
publication.sealed = true;
|
|
3328
|
+
}
|
|
3329
|
+
symbolClaimManifests() {
|
|
3330
|
+
return this.#symbolClaimsByEmittedModule.values();
|
|
3331
|
+
}
|
|
3332
|
+
symbolClaimMap() {
|
|
3333
|
+
return this.#symbolClaimsByEmittedModule;
|
|
3334
|
+
}
|
|
3335
|
+
/** Combine sibling emitted-module claims by symbol identity; contradictions stay fail-closed. */
|
|
3336
|
+
sourceSymbolClaims(source, resolverId) {
|
|
3337
|
+
const publication = this.#sourceClaimPublications.get(source);
|
|
3338
|
+
if (publication && (publication.active > 0 || publication.pending.size > 0)) throw new Error(`MARKLESS_SOURCE_SYMBOL_CLAIMS_UNSEALED: Source ${JSON.stringify(source)} claims were consumed before final publication completed.`);
|
|
3339
|
+
const candidates = [...this.#symbolClaimsByEmittedModule.values()].filter((manifest) => manifest.resolver.virtualModuleId === resolverId && manifest.symbols.length > 0).sort((left, right) => left.source.localeCompare(right.source));
|
|
3340
|
+
const selected = candidates[0];
|
|
3341
|
+
if (!selected) return void 0;
|
|
3342
|
+
const symbols = /* @__PURE__ */ new Map();
|
|
3343
|
+
for (const candidate of candidates) for (const symbol of candidate.symbols) {
|
|
3344
|
+
const existing = symbols.get(symbol.symbolId);
|
|
3345
|
+
if (!existing) {
|
|
3346
|
+
symbols.set(symbol.symbolId, {
|
|
3347
|
+
owner: candidate.source,
|
|
3348
|
+
symbol
|
|
3349
|
+
});
|
|
3350
|
+
continue;
|
|
3351
|
+
}
|
|
3352
|
+
if (JSON.stringify(existing.symbol) !== JSON.stringify(symbol)) throw new Error(`MARKLESS_SOURCE_SYMBOL_CLAIMS_DIVERGED: Source ${JSON.stringify(source)} has incompatible emitted symbol claims in ${JSON.stringify(existing.owner)} and ${JSON.stringify(candidate.source)}.`);
|
|
3353
|
+
}
|
|
3354
|
+
return {
|
|
3355
|
+
...selected,
|
|
3356
|
+
symbols: [...symbols.values()].map(({ symbol }) => symbol)
|
|
3357
|
+
};
|
|
3358
|
+
}
|
|
3359
|
+
emittedSymbolClaimMap(emittedModules) {
|
|
3360
|
+
const emitted = new Set(emittedModules);
|
|
3361
|
+
return new Map([...this.#symbolClaimsByEmittedModule].filter(([owner]) => emitted.has(owner)));
|
|
3362
|
+
}
|
|
3363
|
+
};
|
|
3364
|
+
//#endregion
|
|
3365
|
+
//#region src/rolldown.ts
|
|
3366
|
+
const TSRX_SOURCE_FILE = /\.tsrx(?:[?#].*)?$/;
|
|
3367
|
+
const MARKLESS_SYMBOL_SOURCE_QUERY_RE = /[?&]markless-symbols(?:[&#]|$)/;
|
|
3368
|
+
const MARKLESS_RESUME_SOURCE_QUERY_RE = /[?&]markless-resume(?:[&#]|$)/;
|
|
3369
|
+
const MARKLESS_RENDER_DATA_SOURCE_QUERY_RE = /[?&]markless-render-data(?:[&#]|$)/;
|
|
3370
|
+
const MARKLESS_REACHED_FROM_SOURCE_QUERY = "markless-reached-from";
|
|
3371
|
+
const MARKLESS_PRERENDER_WAKE_SOURCE_QUERY_RE = /[?&]markless-prerender-wake(?:[&#]|$)/;
|
|
3372
|
+
const MARKLESS_ROUTE_SOURCE_QUERY_RE = /[?&]markless-route(?:[&#]|$)/;
|
|
3373
|
+
const RESUME_VIRTUAL_ID_RE = /^virtual:markless:resume:([^:]+)$/;
|
|
3374
|
+
const PRERENDER_WAKE_VIRTUAL_ID_RE = /^virtual:markless:prerender-wake:([^:]+)$/;
|
|
3375
|
+
const SETTLE_VIRTUAL_ID_RE = /^virtual:markless:settle:([^:]+)$/;
|
|
3376
|
+
const SYMBOL_VIRTUAL_STRING_RE = /(["'`])((?:virtual:markless:symbol:)[^"'`]+)\1/g;
|
|
3377
|
+
const marklessClient = (options = {}) => createMarklessRolldownPlugin({
|
|
3378
|
+
environment: "client",
|
|
3379
|
+
options
|
|
3380
|
+
});
|
|
3381
|
+
const marklessServer = (options = {}) => createMarklessRolldownPlugin({
|
|
3382
|
+
environment: "server",
|
|
3383
|
+
options
|
|
3384
|
+
});
|
|
3385
|
+
const marklessLib = (options = {}) => createMarklessRolldownPlugin({
|
|
3386
|
+
environment: "lib",
|
|
3387
|
+
options
|
|
3388
|
+
});
|
|
3389
|
+
function createMarklessRolldownPlugin(input) {
|
|
3390
|
+
const environment = input.environment;
|
|
3391
|
+
const internalOptions = input.options ?? {};
|
|
3392
|
+
const virtualModules = /* @__PURE__ */ new Map();
|
|
3393
|
+
const moduleMetadata = new ModuleMetadataRegistry();
|
|
3394
|
+
const prerenderWakeCapabilities = /* @__PURE__ */ new Map();
|
|
3395
|
+
const moduleLinkArtifacts = /* @__PURE__ */ new Map();
|
|
3396
|
+
const linkedTransformCache = /* @__PURE__ */ new Map();
|
|
3397
|
+
const importedChildren = /* @__PURE__ */ new Map();
|
|
3398
|
+
const importedChildSources = /* @__PURE__ */ new Set();
|
|
3399
|
+
const emittedClientResolverSources = /* @__PURE__ */ new Set();
|
|
3400
|
+
const transformVirtualModules = /* @__PURE__ */ new Map();
|
|
3401
|
+
const virtualModuleOwners = /* @__PURE__ */ new Map();
|
|
3402
|
+
const clientSymbolEntrySources = /* @__PURE__ */ new Set();
|
|
3403
|
+
const prerenderWakeSources = /* @__PURE__ */ new Set();
|
|
3404
|
+
const clientRouteArtifactSources = /* @__PURE__ */ new Set();
|
|
3405
|
+
const clientRouteArtifactMaterializations = /* @__PURE__ */ new Map();
|
|
3406
|
+
const transformedClientPrimarySources = /* @__PURE__ */ new Set();
|
|
3407
|
+
const executionLogEstimatedSizes = /* @__PURE__ */ new Map();
|
|
3408
|
+
const executionLogEmittedIds = /* @__PURE__ */ new Map();
|
|
3409
|
+
const dev = createMarklessDevGraph();
|
|
3410
|
+
let root = internalOptions.rootDir;
|
|
3411
|
+
const name = pluginName(environment);
|
|
3412
|
+
function getEnvironment(context) {
|
|
3413
|
+
if (typeof environment === "function") return environment(context);
|
|
3414
|
+
return environment;
|
|
3415
|
+
}
|
|
3416
|
+
function getRoot() {
|
|
3417
|
+
return root ?? internalOptions.rootDir;
|
|
3418
|
+
}
|
|
3419
|
+
function invalidateAllGeneratedModules(parent, currentEnvironment) {
|
|
3420
|
+
const changedSource = pathname(parent);
|
|
3421
|
+
moduleLinkArtifacts.delete(changedSource);
|
|
3422
|
+
moduleMetadata.deleteCaptureMetadata(changedSource);
|
|
3423
|
+
moduleMetadata.deleteSymbolClaims(changedSource);
|
|
3424
|
+
prerenderWakeCapabilities.delete(changedSource);
|
|
3425
|
+
prerenderWakeSources.delete(changedSource);
|
|
3426
|
+
for (const [key, cached] of linkedTransformCache) {
|
|
3427
|
+
if (cached.source !== changedSource) continue;
|
|
3428
|
+
moduleMetadata.deleteSymbolClaims(cached.manifestSource);
|
|
3429
|
+
linkedTransformCache.delete(key);
|
|
3430
|
+
}
|
|
3431
|
+
const ids = dev.clear(parent, currentEnvironment);
|
|
3432
|
+
const resolvedIds = /* @__PURE__ */ new Set();
|
|
3433
|
+
for (const id of ids) {
|
|
3434
|
+
const type = virtualModules.get(id)?.type;
|
|
3435
|
+
virtualModules.delete(id);
|
|
3436
|
+
const resolvedId = resolveVirtualId(id);
|
|
3437
|
+
resolvedIds.add(resolvedId);
|
|
3438
|
+
if (type === "style") resolvedIds.add(`${resolvedId}?direct`);
|
|
3439
|
+
}
|
|
3440
|
+
if ((currentEnvironment === "client" || currentEnvironment === void 0 && environment === "client") && internalOptions.dev === true && normalizeExecutionLogMode(internalOptions.executionLog) !== "never") resolvedIds.add(resolveVirtualId(MARKLESS_EXECUTION_LOG_MODULE_ID));
|
|
3441
|
+
return [...resolvedIds];
|
|
3442
|
+
}
|
|
3443
|
+
async function invalidateEditedGeneratedModules(parent, currentEnvironment, nextSource) {
|
|
3444
|
+
const changedSource = pathname(parent);
|
|
3445
|
+
const cachedEntries = [...linkedTransformCache].filter(([key, cached]) => cached.source === changedSource && (!currentEnvironment || key.startsWith(`${currentEnvironment}\0`)));
|
|
3446
|
+
if (cachedEntries.length === 0) return invalidateAllGeneratedModules(parent, currentEnvironment);
|
|
3447
|
+
const nextEntries = await Promise.all(cachedEntries.map(async ([key, cached]) => {
|
|
3448
|
+
const nextInput = {
|
|
3449
|
+
...cached.input,
|
|
3450
|
+
source: nextSource
|
|
3451
|
+
};
|
|
3452
|
+
return [
|
|
3453
|
+
key,
|
|
3454
|
+
cached,
|
|
3455
|
+
nextInput,
|
|
3456
|
+
await transformTsrxModuleWithPrerenderWakeClosure(nextInput, cached.linkedChildHasBrowserTriggers)
|
|
3457
|
+
];
|
|
3458
|
+
}));
|
|
3459
|
+
if (nextEntries.some(([, cached, , next]) => !isRenderDataOnlyTransformChange(cached.result, next))) return invalidateAllGeneratedModules(parent, currentEnvironment);
|
|
3460
|
+
const renderDataIds = /* @__PURE__ */ new Set();
|
|
3461
|
+
for (const [key, cached, nextInput, next] of nextEntries) {
|
|
3462
|
+
linkedTransformCache.set(key, {
|
|
3463
|
+
...cached,
|
|
3464
|
+
code: nextSource,
|
|
3465
|
+
input: nextInput,
|
|
3466
|
+
result: next
|
|
3467
|
+
});
|
|
3468
|
+
moduleLinkArtifacts.set(changedSource, {
|
|
3469
|
+
moduleGraphInterface: next.moduleGraphInterface,
|
|
3470
|
+
interfaceHash: next.interfaceHash,
|
|
3471
|
+
moduleImports: next.moduleImports
|
|
3472
|
+
});
|
|
3473
|
+
moduleMetadata.recordCaptureMetadata(changedSource, next.manifest);
|
|
3474
|
+
const symbolClaim = emittedSymbolClaim(moduleMetadata, changedSource, cached.manifestSource, next.manifest, next.virtualModules);
|
|
3475
|
+
moduleMetadata.recordSymbolClaims(symbolClaim.owner, isRenderDataSourceRequest(cached.manifestSource) ? renderDataClaimManifest(next.manifest, cached.manifestSource) : symbolClaim.manifest);
|
|
3476
|
+
prerenderWakeCapabilities.set(changedSource, manifestHasBrowserTriggers(next.manifest) || cached.linkedChildHasBrowserTriggers);
|
|
3477
|
+
for (const module of next.virtualModules) {
|
|
3478
|
+
if (module.type !== "render-data") continue;
|
|
3479
|
+
virtualModules.set(module.id, module);
|
|
3480
|
+
renderDataIds.add(resolveVirtualId(module.id));
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
return [...renderDataIds];
|
|
3484
|
+
}
|
|
3485
|
+
const regeneratingVirtualModules = /* @__PURE__ */ new Set();
|
|
3486
|
+
async function virtualModuleForRequest(normalizedId, currentEnvironment) {
|
|
3487
|
+
const registered = virtualModules.get(normalizedId);
|
|
3488
|
+
if (registered || internalOptions.dev !== true) return registered;
|
|
3489
|
+
const source = marklessVirtualModuleSourceFile(normalizedId);
|
|
3490
|
+
if (!source || !TSRX_SOURCE_FILE.test(source) || regeneratingVirtualModules.has(normalizedId)) return;
|
|
3491
|
+
regeneratingVirtualModules.add(normalizedId);
|
|
3492
|
+
try {
|
|
3493
|
+
internalOptions.devServer?.invalidateModule?.(source, currentEnvironment);
|
|
3494
|
+
await internalOptions.devServer?.transformRequest(source, currentEnvironment);
|
|
3495
|
+
} finally {
|
|
3496
|
+
regeneratingVirtualModules.delete(normalizedId);
|
|
3497
|
+
}
|
|
3498
|
+
return virtualModules.get(normalizedId);
|
|
3499
|
+
}
|
|
3500
|
+
const recoveringChildMetadata = /* @__PURE__ */ new Set();
|
|
3501
|
+
async function recoverImportedChildMetadata(child, currentEnvironment) {
|
|
3502
|
+
if (!TSRX_SOURCE_FILE.test(child.source) || moduleMetadata.captureMetadataForSource(child.source) !== void 0 || recoveringChildMetadata.has(child.source)) return;
|
|
3503
|
+
recoveringChildMetadata.add(child.source);
|
|
3504
|
+
try {
|
|
3505
|
+
internalOptions.devServer?.invalidateModule?.(child.source, currentEnvironment);
|
|
3506
|
+
await internalOptions.devServer?.transformRequest(child.source, currentEnvironment);
|
|
3507
|
+
} finally {
|
|
3508
|
+
recoveringChildMetadata.delete(child.source);
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
const plugin = {
|
|
3512
|
+
api: { invalidateGeneratedModules(parent, currentEnvironment, nextSource) {
|
|
3513
|
+
if (nextSource !== void 0) return invalidateEditedGeneratedModules(parent, currentEnvironment, nextSource);
|
|
3514
|
+
return invalidateAllGeneratedModules(parent, currentEnvironment);
|
|
3515
|
+
} },
|
|
3516
|
+
name,
|
|
3517
|
+
options(input) {
|
|
3518
|
+
if (getEnvironment(this) !== "client") return input;
|
|
3519
|
+
return {
|
|
3520
|
+
...input,
|
|
3521
|
+
preserveEntrySignatures: input.preserveEntrySignatures ?? "allow-extension"
|
|
3522
|
+
};
|
|
3523
|
+
},
|
|
3524
|
+
async buildStart(input) {
|
|
3525
|
+
if (!root) root = internalOptions.rootDir ?? input.cwd;
|
|
3526
|
+
clientSymbolEntrySources.clear();
|
|
3527
|
+
clientRouteArtifactSources.clear();
|
|
3528
|
+
clientRouteArtifactMaterializations.clear();
|
|
3529
|
+
transformedClientPrimarySources.clear();
|
|
3530
|
+
virtualModules.clear();
|
|
3531
|
+
moduleMetadata.clear();
|
|
3532
|
+
moduleLinkArtifacts.clear();
|
|
3533
|
+
linkedTransformCache.clear();
|
|
3534
|
+
importedChildren.clear();
|
|
3535
|
+
importedChildSources.clear();
|
|
3536
|
+
emittedClientResolverSources.clear();
|
|
3537
|
+
transformVirtualModules.clear();
|
|
3538
|
+
virtualModuleOwners.clear();
|
|
3539
|
+
executionLogEstimatedSizes.clear();
|
|
3540
|
+
executionLogEmittedIds.clear();
|
|
3541
|
+
dev.reset();
|
|
3542
|
+
const currentRoot = getRoot();
|
|
3543
|
+
if (getEnvironment(this) === "client") for (const source of clientSymbolEntries(input.input, currentRoot)) clientSymbolEntrySources.add(source);
|
|
3544
|
+
},
|
|
3545
|
+
outputOptions(output) {
|
|
3546
|
+
return outputDefaults(output, getEnvironment(this));
|
|
3547
|
+
},
|
|
3548
|
+
async resolveId(source, importer) {
|
|
3549
|
+
if (source.startsWith("@markless/web/fns/")) {
|
|
3550
|
+
const resolved = import.meta.resolve(source);
|
|
3551
|
+
if (resolved?.startsWith("file://")) return { id: decodeURIComponent(resolved.slice(7)) };
|
|
3552
|
+
}
|
|
3553
|
+
if (source.startsWith("@markless/web/inline/")) {
|
|
3554
|
+
const resolvedRoot = import.meta.resolve("@markless/web");
|
|
3555
|
+
if (resolvedRoot?.startsWith("file://") && resolvedRoot.endsWith("/index.ts")) {
|
|
3556
|
+
const helperPath = source.slice(14);
|
|
3557
|
+
return { id: decodeURIComponent(resolvedRoot.slice(7, -8) + `${helperPath}.ts`) };
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
const normalized = normalizeVirtualId(source);
|
|
3561
|
+
if (normalized === "virtual:markless:dev-log") return {
|
|
3562
|
+
id: resolveVirtualId(MARKLESS_EXECUTION_LOG_MODULE_ID),
|
|
3563
|
+
moduleSideEffects: true
|
|
3564
|
+
};
|
|
3565
|
+
const virtualModule = await virtualModuleForRequest(normalized, getEnvironment(this));
|
|
3566
|
+
if (virtualModule) {
|
|
3567
|
+
const directQuery = virtualModule.type === "style" && /(?:[?&])direct(?:[=&]|$)/.test(source) ? "?direct" : "";
|
|
3568
|
+
return {
|
|
3569
|
+
id: `${resolveVirtualId(normalized)}${directQuery}`,
|
|
3570
|
+
moduleSideEffects: true
|
|
3571
|
+
};
|
|
3572
|
+
}
|
|
3573
|
+
const missingSymbolSource = symbolVirtualModuleSourceFile(normalized);
|
|
3574
|
+
if (missingSymbolSource && importedChildSources.has(missingSymbolSource)) throw new Error(`MARKLESS_CHILD_SYMBOL_MISSING: Linked child ${JSON.stringify(missingSymbolSource)} does not provide requested symbol module ${JSON.stringify(normalized)}. Rebuild the child with the current Markless compiler and clear any stale build cache.`);
|
|
3575
|
+
const symbolSource = sourceForSymbolVirtualImporter(importer);
|
|
3576
|
+
if (symbolSource && isRelativeImport(source)) return await this.resolve(source, symbolSource, { skipSelf: true });
|
|
3577
|
+
const triggerGroupSource = sourceForTriggerGroupVirtualImporter(importer);
|
|
3578
|
+
if (triggerGroupSource && isRelativeImport(source)) return await this.resolve(source, triggerGroupSource, { skipSelf: true });
|
|
3579
|
+
const resumeSource = sourceForResumeVirtualImporter(importer) ?? sourceForPrerenderWakeVirtualImporter(importer);
|
|
3580
|
+
if (resumeSource && isRelativeImport(source)) return await this.resolve(source, resumeSource, { skipSelf: true });
|
|
3581
|
+
return null;
|
|
3582
|
+
},
|
|
3583
|
+
async load(id) {
|
|
3584
|
+
if (normalizeVirtualId(id) === "virtual:markless:dev-log") {
|
|
3585
|
+
const embedsDevSizes = internalOptions.dev === true && getEnvironment(this) === "client";
|
|
3586
|
+
return executionLogVirtualModuleSource({
|
|
3587
|
+
moduleSizes: embedsDevSizes ? executionLogEstimatedSizes : void 0,
|
|
3588
|
+
attribution: embedsDevSizes ? executionAttributionTables(moduleMetadata.symbolClaimMap().values(), getRoot(), importedChildren.values()) : void 0,
|
|
3589
|
+
sizesUrl: internalOptions.dev === true ? void 0 : internalOptions.publicPath?.(MARKLESS_EXECUTION_SIZES) ?? `/${MARKLESS_EXECUTION_SIZES}`
|
|
3590
|
+
});
|
|
3591
|
+
}
|
|
3592
|
+
const normalizedId = normalizeVirtualId(id);
|
|
3593
|
+
const resolverSource = resolverVirtualModuleSourceFile(normalizedId);
|
|
3594
|
+
if (resolverSource && getEnvironment(this) === "client" && internalOptions.dev !== true && internalOptions.prerenderWakeChannel === true && typeof this.getModuleInfo === "function") {
|
|
3595
|
+
const queryClaimSources = [
|
|
3596
|
+
withQuery(resolverSource, { "markless-resume": null }),
|
|
3597
|
+
withQuery(resolverSource, { "markless-prerender-wake": null }),
|
|
3598
|
+
withQuery(resolverSource, { "markless-symbols": null })
|
|
3599
|
+
];
|
|
3600
|
+
moduleMetadata.expectSourceSymbolClaims(resolverSource, queryClaimSources.filter((source) => this.getModuleInfo(source) != null));
|
|
3601
|
+
await moduleMetadata.sealSourceSymbolClaims(resolverSource);
|
|
3602
|
+
}
|
|
3603
|
+
const module = await virtualModuleForRequest(normalizedId, getEnvironment(this));
|
|
3604
|
+
if (module) return virtualModuleSourceForLoad(module, {
|
|
3605
|
+
dev: internalOptions.dev === true && getEnvironment(this) === "client",
|
|
3606
|
+
publicPath: internalOptions.publicPath
|
|
3607
|
+
});
|
|
3608
|
+
return null;
|
|
3609
|
+
},
|
|
3610
|
+
async transform(code, id) {
|
|
3611
|
+
const currentEnvironment = getEnvironment(this);
|
|
3612
|
+
const virtualId = normalizeVirtualId(id);
|
|
3613
|
+
if (!TSRX_SOURCE_FILE.test(id)) {
|
|
3614
|
+
if (currentEnvironment === "client" && internalOptions.dev !== true && internalOptions.prerender === true && normalizeExecutionLogMode(internalOptions.executionLog) !== "never" && this.getModuleInfo(id)?.isEntry === true) return {
|
|
3615
|
+
code: `${code}\nglobalThis.__mxLoadLog ||= () => import(${JSON.stringify(MARKLESS_EXECUTION_LOG_MODULE_ID)});\nglobalThis.__mxLoadLog().then(log => log.logMarklessRenderSummary());`,
|
|
3616
|
+
map: null
|
|
3617
|
+
};
|
|
3618
|
+
if (currentEnvironment === "client" && normalizeExecutionLogMode(internalOptions.executionLog) !== "never" && isMarklessRuntimeModule(id)) {
|
|
3619
|
+
executionLogEstimatedSizes.set(executionLogRuntimeModuleId(id), code.length);
|
|
3620
|
+
executionLogEmittedIds.set(executionLogRuntimeModuleId(id), pathname(id));
|
|
3621
|
+
return {
|
|
3622
|
+
code: injectExecutionLogModuleHook(code, executionLogRuntimeModuleId(id), internalOptions.executionLog),
|
|
3623
|
+
map: null
|
|
3624
|
+
};
|
|
3625
|
+
}
|
|
3626
|
+
return null;
|
|
3627
|
+
}
|
|
3628
|
+
if (virtualId.startsWith("virtual:markless:")) return null;
|
|
3629
|
+
const source = pathname(id);
|
|
3630
|
+
const renderDataRequest = isRenderDataSourceRequest(id);
|
|
3631
|
+
const prerenderWakeRequest = isPrerenderWakeSourceRequest(id);
|
|
3632
|
+
const clientRouteArtifact = MARKLESS_ROUTE_SOURCE_QUERY_RE.test(id);
|
|
3633
|
+
const materializedRenderDataReach = currentEnvironment === "client" && renderDataRequest ? materializedRenderDataReachRoot(id, source, clientRouteArtifactMaterializations) : void 0;
|
|
3634
|
+
if (currentEnvironment === "client" && prerenderWakeRequest) {
|
|
3635
|
+
clientSymbolEntrySources.add(source);
|
|
3636
|
+
prerenderWakeSources.add(source);
|
|
3637
|
+
}
|
|
3638
|
+
const ssrPrerenderArtifacts = currentEnvironment === "client" && (internalOptions.prerenderWakeChannel === true || prerenderWakeSources.size > 0);
|
|
3639
|
+
const prerenderRecords = currentEnvironment === "client" && (internalOptions.prerender === true || internalOptions.prerenderWakeChannel === true || materializedRenderDataReach !== void 0 || prerenderWakeRequest || ssrPrerenderArtifacts);
|
|
3640
|
+
const transformInput = {
|
|
3641
|
+
filename: source,
|
|
3642
|
+
source: code,
|
|
3643
|
+
dev: internalOptions.dev === true || currentEnvironment === "client" && clientRouteArtifactSources.has(source),
|
|
3644
|
+
buildId: internalOptions.buildId,
|
|
3645
|
+
executionLog: normalizeExecutionLogMode(internalOptions.executionLog),
|
|
3646
|
+
executionLogModuleHooks: currentEnvironment === "client" && normalizeExecutionLogMode(internalOptions.executionLog) !== "never",
|
|
3647
|
+
inlineResumerDebug: internalOptions.inlineResumerDebug === true,
|
|
3648
|
+
prerenderRecords,
|
|
3649
|
+
directCsr: currentEnvironment === "client" && internalOptions.emitResumeModules !== true && internalOptions.prerender !== true && !renderDataRequest && !prerenderWakeRequest && !isResumeSourceRequest(id) && !isSymbolOnlySourceRequest(id) && !clientRouteArtifact,
|
|
3650
|
+
runtimeDemandClass: currentEnvironment === "client" && internalOptions.emitResumeModules === true && !prerenderRecords && !clientRouteArtifactSources.has(source) ? "plain-ssr" : "prerender",
|
|
3651
|
+
prerenderWakeVariant: internalOptions.prerenderWakeChannel === true && (prerenderWakeRequest || ssrPrerenderArtifacts && clientSymbolEntrySources.has(source)),
|
|
3652
|
+
prerenderWakeFacade: prerenderWakeRequest,
|
|
3653
|
+
preserveWakeSiblingClaims: currentEnvironment === "client" && (isResumeSourceRequest(id) || isSymbolOnlySourceRequest(id)),
|
|
3654
|
+
environment: currentEnvironment,
|
|
3655
|
+
clientOutput: currentEnvironment === "client" && (clientSymbolEntrySources.has(source) && internalOptions.prerender !== true && !clientRouteArtifactSources.has(source) && isClientPrimarySourceRequest(id) && isModuleEntry(this, id) || isSymbolOnlySourceRequest(id)) ? "symbols-only" : void 0,
|
|
3656
|
+
resumeModuleUrl: internalOptions.dev === true && currentEnvironment === "server" ? devBrowserSourceModuleUrl(source, getRoot(), internalOptions.publicPath) : currentEnvironment === "server" ? internalOptions.productionResumeModuleUrls?.get(source) : void 0,
|
|
3657
|
+
prerenderWakeModuleUrl: currentEnvironment === "server" ? internalOptions.productionPrerenderWakeModuleUrls?.get(source) : void 0,
|
|
3658
|
+
settleModuleUrl: currentEnvironment === "server" ? internalOptions.productionSettleModuleUrls?.get(source) : void 0,
|
|
3659
|
+
styleModuleUrl: internalOptions.dev === true && currentEnvironment === "server" ? (virtualId) => withQuery(devBrowserVirtualModuleUrl(virtualId, internalOptions.publicPath), { direct: null }) : void 0,
|
|
3660
|
+
headInjections: internalOptions.dev === true && currentEnvironment === "server" ? internalOptions.devInjections : void 0,
|
|
3661
|
+
devResumeReexport: internalOptions.dev === true && currentEnvironment === "client",
|
|
3662
|
+
prerenderRecordData: currentEnvironment === "client" ? input.prerenderRecordsBySource?.get(source) : void 0
|
|
3663
|
+
};
|
|
3664
|
+
const manifestSource = currentEnvironment === "client" && !isClientPrimarySourceRequest(id) ? id : source;
|
|
3665
|
+
const publishesClientClaims = currentEnvironment === "client" && !renderDataRequest && !clientRouteArtifact;
|
|
3666
|
+
if (publishesClientClaims) moduleMetadata.beginSourceSymbolClaims(source, manifestSource);
|
|
3667
|
+
const cacheKey = [
|
|
3668
|
+
currentEnvironment,
|
|
3669
|
+
manifestSource,
|
|
3670
|
+
transformInput.clientOutput ?? "full",
|
|
3671
|
+
isResumeSourceRequest(id) ? "resume" : prerenderWakeRequest ? "prerender-wake" : renderDataRequest ? "render-data" : "source"
|
|
3672
|
+
].join("\0");
|
|
3673
|
+
const cached = linkedTransformCache.get(cacheKey);
|
|
3674
|
+
let linkedTransformResult;
|
|
3675
|
+
let linkedTransformInput = transformInput;
|
|
3676
|
+
let reusedLinkedTransform = false;
|
|
3677
|
+
if (cached?.code === code) {
|
|
3678
|
+
const cachedImports = await resolveImportedModuleInterfaces.call(this, manifestSource, cached.result.moduleImports);
|
|
3679
|
+
await forceImportedModules.call(this, cachedImports, moduleLinkArtifacts, moduleMetadata, internalOptions, currentEnvironment);
|
|
3680
|
+
if (cached.importedInterfaceHashes === importedInterfaceHashSignature(cachedImports, moduleLinkArtifacts) && cached.importedSymbolClaims === importedSymbolClaimSignature(cachedImports, moduleMetadata)) {
|
|
3681
|
+
linkedTransformResult = cached.result;
|
|
3682
|
+
linkedTransformInput = cached.input;
|
|
3683
|
+
reusedLinkedTransform = true;
|
|
3684
|
+
}
|
|
3685
|
+
}
|
|
3686
|
+
if (linkedTransformResult === void 0) try {
|
|
3687
|
+
linkedTransformResult = await transformTsrxModule(transformInput);
|
|
3688
|
+
} catch (error) {
|
|
3689
|
+
const provisional = await compileTsrxModuleLinkArtifact(transformInput);
|
|
3690
|
+
moduleLinkArtifacts.set(source, provisional);
|
|
3691
|
+
const provisionalImports = await resolveImportedModuleInterfaces.call(this, manifestSource, provisional.moduleImports);
|
|
3692
|
+
if (provisionalImports.length === 0) throw error;
|
|
3693
|
+
await forceImportedModules.call(this, provisionalImports, moduleLinkArtifacts, moduleMetadata, internalOptions, currentEnvironment);
|
|
3694
|
+
linkedTransformInput = {
|
|
3695
|
+
...transformInput,
|
|
3696
|
+
importedModuleInterfaces: importedModuleInterfaces(provisionalImports, moduleLinkArtifacts)
|
|
3697
|
+
};
|
|
3698
|
+
linkedTransformResult = await transformTsrxModule(linkedTransformInput);
|
|
3699
|
+
}
|
|
3700
|
+
let transformed = linkedTransformResult;
|
|
3701
|
+
if (currentEnvironment === "client" && clientRouteArtifact) {
|
|
3702
|
+
const artifactChildMaterializations = await materializeArtifactChildren.call(this, source, getRoot(), transformed.artifactChildren);
|
|
3703
|
+
if (Object.keys(artifactChildMaterializations).length > 0) clientRouteArtifactMaterializations.set(source, artifactChildMaterializations);
|
|
3704
|
+
registerClientRouteArtifactSource(source);
|
|
3705
|
+
return {
|
|
3706
|
+
code: clientRouteArtifactReference(source),
|
|
3707
|
+
map: null
|
|
3708
|
+
};
|
|
3709
|
+
}
|
|
3710
|
+
if (!reusedLinkedTransform) {
|
|
3711
|
+
const pageRoot = currentEnvironment === "client" && !isSymbolOnlySourceRequest(id) && isModuleEntry(this, id);
|
|
3712
|
+
const artifactChildMaterializations = currentEnvironment === "client" && clientRouteArtifactMaterializations.has(source) ? clientRouteArtifactMaterializations.get(source) : pageRoot || materializedRenderDataReach !== void 0 ? await materializeArtifactChildren.call(this, source, getRoot(), transformed.artifactChildren) : {};
|
|
3713
|
+
if (Object.keys(artifactChildMaterializations).length > 0) {
|
|
3714
|
+
linkedTransformInput = {
|
|
3715
|
+
...linkedTransformInput,
|
|
3716
|
+
artifactChildMaterializations
|
|
3717
|
+
};
|
|
3718
|
+
transformed = await transformTsrxModuleWithPrerenderWakeClosure(linkedTransformInput, false);
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
if (!renderDataRequest) registerTransformArtifacts({
|
|
3722
|
+
owner: cacheKey,
|
|
3723
|
+
source,
|
|
3724
|
+
manifestSource,
|
|
3725
|
+
result: transformed,
|
|
3726
|
+
virtualModules,
|
|
3727
|
+
moduleMetadata,
|
|
3728
|
+
moduleLinkArtifacts,
|
|
3729
|
+
transformVirtualModules,
|
|
3730
|
+
virtualModuleOwners,
|
|
3731
|
+
executionLogEstimatedSizes,
|
|
3732
|
+
executionLogEmittedIds,
|
|
3733
|
+
dev,
|
|
3734
|
+
environment: currentEnvironment,
|
|
3735
|
+
finalPublication: false,
|
|
3736
|
+
tracksSourceClaimPublication: false,
|
|
3737
|
+
updateDevPrerenderHashes: internalOptions.updateDevPrerenderHashes
|
|
3738
|
+
});
|
|
3739
|
+
else {
|
|
3740
|
+
moduleMetadata.recordCaptureMetadata(source, transformed.manifest);
|
|
3741
|
+
moduleMetadata.recordSymbolClaims(manifestSource, renderDataClaimManifest(transformed.manifest, manifestSource));
|
|
3742
|
+
moduleLinkArtifacts.set(source, {
|
|
3743
|
+
interfaceHash: transformed.interfaceHash,
|
|
3744
|
+
moduleGraphInterface: transformed.moduleGraphInterface,
|
|
3745
|
+
moduleImports: transformed.moduleImports
|
|
3746
|
+
});
|
|
3747
|
+
}
|
|
3748
|
+
const resolvedInterfaceImports = await resolveImportedModuleInterfaces.call(this, manifestSource, transformed.moduleImports);
|
|
3749
|
+
const resolvedChildren = await resolveImportedChildren.call(this, manifestSource, transformed.manifest);
|
|
3750
|
+
for (const child of resolvedChildren) {
|
|
3751
|
+
importedChildren.set(importedChildKey(child), child);
|
|
3752
|
+
importedChildSources.add(child.source);
|
|
3753
|
+
}
|
|
3754
|
+
await forceImportedModules.call(this, uniqueImportedModules([...resolvedInterfaceImports, ...resolvedChildren]), moduleLinkArtifacts, moduleMetadata, internalOptions, currentEnvironment);
|
|
3755
|
+
for (const child of resolvedChildren) if (internalOptions.dev === true) {
|
|
3756
|
+
await recoverImportedChildMetadata(child, currentEnvironment);
|
|
3757
|
+
validateImportedChild(child, moduleMetadata, transformed.manifest);
|
|
3758
|
+
}
|
|
3759
|
+
const linkedChildHasBrowserTriggers = linkedChildrenHaveBrowserTriggers(resolvedChildren, moduleMetadata, prerenderWakeCapabilities);
|
|
3760
|
+
if (!reusedLinkedTransform && (resolvedChildren.length > 0 || resolvedInterfaceImports.length > 0)) {
|
|
3761
|
+
const symbols = importedSymbolInputs(resolvedChildren, moduleMetadata);
|
|
3762
|
+
const renderDataImportSources = materializedRenderDataReach ? Object.fromEntries(resolvedInterfaceImports.map((imported) => [imported.specifier, materializedReachedRenderDataSource(imported.source, materializedRenderDataReach)])) : void 0;
|
|
3763
|
+
linkedTransformInput = {
|
|
3764
|
+
...linkedTransformInput,
|
|
3765
|
+
symbols,
|
|
3766
|
+
importedModuleInterfaces: importedModuleInterfaces(resolvedInterfaceImports, moduleLinkArtifacts),
|
|
3767
|
+
...renderDataImportSources ? { renderDataImportSources } : {}
|
|
3768
|
+
};
|
|
3769
|
+
transformed = await transformTsrxModuleWithPrerenderWakeClosure(linkedTransformInput, linkedChildHasBrowserTriggers);
|
|
3770
|
+
}
|
|
3771
|
+
prerenderWakeCapabilities.set(source, manifestHasBrowserTriggers(transformed.manifest) || linkedChildHasBrowserTriggers);
|
|
3772
|
+
if (publishesClientClaims && !isClientPrimarySourceRequest(id) && internalOptions.prerenderWakeChannel === true && typeof this.getModuleInfo === "function") {
|
|
3773
|
+
const aggregateInput = {
|
|
3774
|
+
...linkedTransformInput,
|
|
3775
|
+
clientOutput: void 0,
|
|
3776
|
+
prerenderWakeFacade: false,
|
|
3777
|
+
prerenderWakeVariant: false
|
|
3778
|
+
};
|
|
3779
|
+
let aggregate = await transformTsrxModuleWithPrerenderWakeClosure(aggregateInput, linkedChildHasBrowserTriggers);
|
|
3780
|
+
const aggregateChildren = await resolveImportedChildren.call(this, source, aggregate.manifest);
|
|
3781
|
+
await forceImportedModules.call(this, aggregateChildren, moduleLinkArtifacts, moduleMetadata, internalOptions, currentEnvironment);
|
|
3782
|
+
let aggregateSymbols = importedSymbolInputs(aggregateChildren, moduleMetadata);
|
|
3783
|
+
for (let attempt = 0; importedClaimsMissing(aggregateChildren, aggregateSymbols, moduleMetadata); attempt += 1) {
|
|
3784
|
+
if (attempt === 9) throw new Error(`MARKLESS_IMPORTED_SYMBOL_CLAIMS_UNREADY: Source ${JSON.stringify(source)} could not seal imported symbol claims after final publications.`);
|
|
3785
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3786
|
+
for (const child of aggregateChildren) await moduleMetadata.sealSourceSymbolClaims(child.source);
|
|
3787
|
+
aggregateSymbols = importedSymbolInputs(aggregateChildren, moduleMetadata);
|
|
3788
|
+
}
|
|
3789
|
+
aggregate = await transformTsrxModuleWithPrerenderWakeClosure({
|
|
3790
|
+
...aggregateInput,
|
|
3791
|
+
symbols: aggregateSymbols
|
|
3792
|
+
}, linkedChildHasBrowserTriggers);
|
|
3793
|
+
const resolver = aggregate.virtualModules.find((module) => module.type === "resolver");
|
|
3794
|
+
if (resolver) transformed = {
|
|
3795
|
+
...transformed,
|
|
3796
|
+
virtualModules: transformed.virtualModules.map((module) => module.type === "resolver" ? resolver : module)
|
|
3797
|
+
};
|
|
3798
|
+
}
|
|
3799
|
+
if (!renderDataRequest) registerTransformArtifacts({
|
|
3800
|
+
owner: cacheKey,
|
|
3801
|
+
source,
|
|
3802
|
+
manifestSource,
|
|
3803
|
+
result: transformed,
|
|
3804
|
+
virtualModules,
|
|
3805
|
+
moduleMetadata,
|
|
3806
|
+
moduleLinkArtifacts,
|
|
3807
|
+
transformVirtualModules,
|
|
3808
|
+
virtualModuleOwners,
|
|
3809
|
+
executionLogEstimatedSizes,
|
|
3810
|
+
executionLogEmittedIds,
|
|
3811
|
+
dev,
|
|
3812
|
+
environment: currentEnvironment,
|
|
3813
|
+
finalPublication: true,
|
|
3814
|
+
tracksSourceClaimPublication: publishesClientClaims,
|
|
3815
|
+
replaceOwnedArtifacts: true,
|
|
3816
|
+
updateDevPrerenderHashes: internalOptions.updateDevPrerenderHashes
|
|
3817
|
+
});
|
|
3818
|
+
else {
|
|
3819
|
+
moduleMetadata.recordCaptureMetadata(source, transformed.manifest);
|
|
3820
|
+
moduleMetadata.recordSymbolClaims(manifestSource, renderDataClaimManifest(transformed.manifest, manifestSource));
|
|
3821
|
+
}
|
|
3822
|
+
linkedTransformCache.set(cacheKey, {
|
|
3823
|
+
source,
|
|
3824
|
+
manifestSource,
|
|
3825
|
+
code,
|
|
3826
|
+
importedInterfaceHashes: importedInterfaceHashSignature(resolvedInterfaceImports, moduleLinkArtifacts),
|
|
3827
|
+
importedSymbolClaims: importedSymbolClaimSignature(uniqueImportedModules([...resolvedInterfaceImports, ...resolvedChildren]), moduleMetadata),
|
|
3828
|
+
input: linkedTransformInput,
|
|
3829
|
+
result: transformed,
|
|
3830
|
+
linkedChildHasBrowserTriggers
|
|
3831
|
+
});
|
|
3832
|
+
if (currentEnvironment === "client" && isClientPrimarySourceRequest(id)) transformedClientPrimarySources.add(source);
|
|
3833
|
+
if (currentEnvironment === "client" && renderDataRequest) {
|
|
3834
|
+
const renderDataModule = transformed.virtualModules.find((module) => module.type === "render-data");
|
|
3835
|
+
if (renderDataModule) {
|
|
3836
|
+
const styleModules = transformed.virtualModules.filter((module) => module.type === "style");
|
|
3837
|
+
registerRenderDataStyles({
|
|
3838
|
+
owner: cacheKey,
|
|
3839
|
+
source,
|
|
3840
|
+
modules: styleModules,
|
|
3841
|
+
virtualModules,
|
|
3842
|
+
transformVirtualModules,
|
|
3843
|
+
virtualModuleOwners,
|
|
3844
|
+
dev
|
|
3845
|
+
});
|
|
3846
|
+
return {
|
|
3847
|
+
code: [...styleModules.map((module) => `import ${JSON.stringify(module.id)};`), renderDataModule.source].join("\n"),
|
|
3848
|
+
map: null
|
|
3849
|
+
};
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
for (const child of resolvedChildren) dev.record(child.source, [transformed.manifest.resolver.virtualModuleId], currentEnvironment);
|
|
3853
|
+
if (currentEnvironment === "client" && isResumeSourceRequest(id)) {
|
|
3854
|
+
const resumeModule = transformed.virtualModules.find((module) => module.type === "resume");
|
|
3855
|
+
if (resumeModule) return {
|
|
3856
|
+
code: resumeModule.source,
|
|
3857
|
+
map: null
|
|
3858
|
+
};
|
|
3859
|
+
}
|
|
3860
|
+
if (currentEnvironment === "client" && prerenderWakeRequest) {
|
|
3861
|
+
const wakeModule = transformed.virtualModules.find((module) => module.type === "prerender-wake");
|
|
3862
|
+
return wakeModule ? {
|
|
3863
|
+
code: `export { resumeContainerEvent } from ${JSON.stringify(wakeModule.id)};`,
|
|
3864
|
+
map: null
|
|
3865
|
+
} : {
|
|
3866
|
+
code: [
|
|
3867
|
+
"export async function resumeContainerEvent() {",
|
|
3868
|
+
" throw new Error('MARKLESS_PRERENDER_WAKE_ROUTE_INELIGIBLE');",
|
|
3869
|
+
"}"
|
|
3870
|
+
].join("\n"),
|
|
3871
|
+
map: null
|
|
3872
|
+
};
|
|
3873
|
+
}
|
|
3874
|
+
if (currentEnvironment === "client" && !internalOptions.dev) for (const module of transformed.virtualModules.filter((item) => {
|
|
3875
|
+
if (item.type === "symbol") return true;
|
|
3876
|
+
if (item.type === "trigger-group") return true;
|
|
3877
|
+
if (item.type === "settle") return clientSymbolEntrySources.has(source);
|
|
3878
|
+
if (item.type === "resolver") return (importedChildSources.has(source) || (transformed.manifest.captureMetadata?.boundResolverRows?.length ?? 0) > 0) && !emittedClientResolverSources.has(source);
|
|
3879
|
+
return (item.type === "resume" || item.type === "prerender-wake") && internalOptions.emitResumeModules === true && clientSymbolEntrySources.has(source);
|
|
3880
|
+
})) {
|
|
3881
|
+
this.emitFile({
|
|
3882
|
+
type: "chunk",
|
|
3883
|
+
id: module.id,
|
|
3884
|
+
preserveSignature: "strict"
|
|
3885
|
+
});
|
|
3886
|
+
if (module.type === "resolver") emittedClientResolverSources.add(source);
|
|
3887
|
+
}
|
|
3888
|
+
return transformed;
|
|
3889
|
+
},
|
|
3890
|
+
generateBundle: {
|
|
3891
|
+
order: "post",
|
|
3892
|
+
async handler(_, bundle) {
|
|
3893
|
+
for (const child of importedChildren.values()) validateImportedChild(child, moduleMetadata);
|
|
3894
|
+
if (getEnvironment(this) !== "client") return;
|
|
3895
|
+
recordProductionResumeModuleUrls(bundle, internalOptions.productionResumeModuleUrls, internalOptions.publicPath);
|
|
3896
|
+
if (internalOptions.prerenderWakeChannel === true) {
|
|
3897
|
+
recordProductionPrerenderWakeModuleUrls(bundle, internalOptions.productionPrerenderWakeModuleUrls, internalOptions.publicPath);
|
|
3898
|
+
recordProductionSettleModuleUrls(bundle, internalOptions.productionSettleModuleUrls ??= /* @__PURE__ */ new Map(), internalOptions.publicPath);
|
|
3899
|
+
}
|
|
3900
|
+
stripEmptyPreloadWrappersFromChunks(bundle);
|
|
3901
|
+
const removedSymbolFacades = rewriteGeneratedSymbolFacadeImports(bundle);
|
|
3902
|
+
rewriteGeneratedSymbolInitExports(bundle);
|
|
3903
|
+
compactGeneratedDirectSymbolLoaders(bundle);
|
|
3904
|
+
const manifestBundle = bundleWithoutRemovedChunks(bundle, removedSymbolFacades);
|
|
3905
|
+
const tableRewrite = rewriteGeneratedSymbolTableUrls(manifestBundle);
|
|
3906
|
+
if (tableRewrite.unresolved.length > 0) this.error(`Markless symbol resolver table contains unresolved generated symbol chunks: ${tableRewrite.unresolved.join(", ")}. markless debugging playbook: run pnpm doctor, or read agent/markless.md in the installed @markless/core package`);
|
|
3907
|
+
const emittedSymbolClaims = moduleMetadata.emittedSymbolClaimMap(emittedBundleModuleIds(manifestBundle));
|
|
3908
|
+
const attributionClaims = [...moduleMetadata.symbolClaimManifests()];
|
|
3909
|
+
const tableIntegrity = verifyGeneratedSymbolTableRoutes(manifestBundle, emittedSymbolClaims.values());
|
|
3910
|
+
if (tableIntegrity.errors.length > 0) this.error(`Markless symbol resolver table integrity check failed:\n${tableIntegrity.errors.map((error) => `- ${error.symbolId} -> ${error.claimedChunk}: ${error.reason}`).join("\n")}`);
|
|
3911
|
+
const clientManifest = createBuildMetadata(manifestBundle, emittedSymbolClaims.values(), getRoot(), {
|
|
3912
|
+
bundleGraphAsset: MARKLESS_BUNDLE_GRAPH,
|
|
3913
|
+
bundleGraphAdders: internalOptions.bundleGraphAdders,
|
|
3914
|
+
canonPath: stripBuildPrefix,
|
|
3915
|
+
publicPath: internalOptions.publicPath,
|
|
3916
|
+
injections: internalOptions.devInjections
|
|
3917
|
+
});
|
|
3918
|
+
const executionLogInjection = executionLogActivationInjection(internalOptions.executionLog);
|
|
3919
|
+
if (executionLogInjection) injectHeadLinks(bundle, [executionLogInjection]);
|
|
3920
|
+
injectHeadLinks(bundle, collectModulePreloadInjections(clientManifest, {
|
|
3921
|
+
publicPath: internalOptions.publicPath,
|
|
3922
|
+
wakeChunks: internalOptions.prerender || internalOptions.prerenderWakeChannel === true ? productionWakeModuleChunks(bundle) : void 0,
|
|
3923
|
+
entryChunks: Object.values(bundle).filter((output) => !!output && typeof output === "object" && output.type === "chunk" && output.isEntry === true).map((chunk) => stripBuildPrefix(chunk.fileName))
|
|
3924
|
+
}));
|
|
3925
|
+
this.emitFile({
|
|
3926
|
+
type: "asset",
|
|
3927
|
+
fileName: MARKLESS_BUNDLE_GRAPH,
|
|
3928
|
+
source: JSON.stringify(clientManifest.bundleGraph)
|
|
3929
|
+
});
|
|
3930
|
+
this.emitFile(await createExecutionSizesAsset(manifestBundle, clientManifest, stripBuildPrefix, executionLogInjection ? executionAttributionTables(attributionClaims, getRoot(), importedChildren.values()) : void 0, {
|
|
3931
|
+
executionLogActive: executionLogInjection !== null,
|
|
3932
|
+
hookedIds: executionLogEmittedIds
|
|
3933
|
+
}));
|
|
3934
|
+
this.emitFile({
|
|
3935
|
+
type: "asset",
|
|
3936
|
+
fileName: `${MARKLESS_BUILD_PREFIX}execution-demand.json`,
|
|
3937
|
+
source: JSON.stringify(Object.fromEntries(clientManifest.modules.filter((module) => module.runtimeDemandMap).map((module) => [module.source, module.runtimeDemandMap])))
|
|
3938
|
+
});
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
};
|
|
3942
|
+
function registerClientRouteArtifactSource(source) {
|
|
3943
|
+
if (clientRouteArtifactSources.has(source)) return;
|
|
3944
|
+
if (transformedClientPrimarySources.has(source)) {
|
|
3945
|
+
if (internalOptions.dev !== true) throw new Error(`MARKLESS_ROUTE_ARTIFACT_REGISTERED_LATE: Client route artifact ${JSON.stringify(source)} was registered after its primary module transformed. Register every production route artifact before transformation begins.`);
|
|
3946
|
+
invalidateAllGeneratedModules(source, "client");
|
|
3947
|
+
transformedClientPrimarySources.delete(source);
|
|
3948
|
+
internalOptions.devServer?.invalidateModule?.(source, "client");
|
|
3949
|
+
}
|
|
3950
|
+
clientRouteArtifactSources.add(source);
|
|
3951
|
+
}
|
|
3952
|
+
return plugin;
|
|
3953
|
+
}
|
|
3954
|
+
async function materializeArtifactChildren(parent, appRoot, candidates) {
|
|
3955
|
+
const materialized = {};
|
|
3956
|
+
const loaded = /* @__PURE__ */ new Map();
|
|
3957
|
+
for (const candidate of candidates) {
|
|
3958
|
+
if (TSRX_SOURCE_FILE.test(candidate.importSource)) continue;
|
|
3959
|
+
const resolved = await this.resolve(candidate.importSource, parent, { skipSelf: true });
|
|
3960
|
+
const id = typeof resolved === "string" ? resolved : resolved?.id;
|
|
3961
|
+
if (!id) continue;
|
|
3962
|
+
const source = pathname(id);
|
|
3963
|
+
if (!appRoot || !isAbsolute(source) || !existsSync(source) || !statSync(source).isFile() || isInsideRoot(source, appRoot)) continue;
|
|
3964
|
+
let module = loaded.get(source);
|
|
3965
|
+
if (!module) {
|
|
3966
|
+
module = await import(pathToFileURL(source).href);
|
|
3967
|
+
loaded.set(source, module);
|
|
3968
|
+
}
|
|
3969
|
+
const component = candidate.importKind === "default" ? module.default : candidate.importKind === "namespace" ? module : module[candidate.importedName ?? candidate.componentName];
|
|
3970
|
+
const renderSsr = component?.renderSsr;
|
|
3971
|
+
if (typeof renderSsr !== "function") continue;
|
|
3972
|
+
const underivable = candidate.props.find((prop) => prop.kind !== "serializable");
|
|
3973
|
+
if (underivable || candidate.hasChildren && !candidate.projection) {
|
|
3974
|
+
const prop = underivable?.name ?? "children";
|
|
3975
|
+
throw new Error(`MARKLESS_ARTIFACT_CHILD_PROP_NOT_BUILD_KNOWN: <${candidate.componentName}> prop ${JSON.stringify(prop)} must be a build-known static value. Runtime component execution is not a fallback.`);
|
|
3976
|
+
}
|
|
3977
|
+
const props = Object.fromEntries(candidate.props.map((prop) => [prop.name, prop.value]));
|
|
3978
|
+
if (candidate.projection) props.children = candidate.projection.markup;
|
|
3979
|
+
const output = await renderSsr.call(component, props);
|
|
3980
|
+
if (!output || typeof output !== "object" || typeof output.html !== "string") throw new Error(`MARKLESS_ARTIFACT_CHILD_RENDER_INVALID: <${candidate.componentName}> renderSsr must return static HTML.`);
|
|
3981
|
+
const result = output;
|
|
3982
|
+
materialized[candidate.edgeId] = {
|
|
3983
|
+
html: result.html,
|
|
3984
|
+
elementCount: typeof result.elementCount === "number" ? result.elementCount : 0,
|
|
3985
|
+
...result.state ? { state: result.state } : {},
|
|
3986
|
+
...result.view ? { view: result.view } : {},
|
|
3987
|
+
...result.coordinates ? { coordinates: result.coordinates } : {},
|
|
3988
|
+
...result.structure ? { structure: result.structure } : {},
|
|
3989
|
+
...Array.isArray(result.structureTokens) ? { structureTokens: result.structureTokens } : {}
|
|
3990
|
+
};
|
|
3991
|
+
}
|
|
3992
|
+
return materialized;
|
|
3993
|
+
}
|
|
3994
|
+
function isInsideRoot(source, root) {
|
|
3995
|
+
const path = relative(root, source);
|
|
3996
|
+
return path === "" || !isAbsolute(path) && path !== ".." && !path.startsWith("../");
|
|
3997
|
+
}
|
|
3998
|
+
function isModuleEntry(context, id) {
|
|
3999
|
+
try {
|
|
4000
|
+
return context.getModuleInfo?.(id)?.isEntry === true;
|
|
4001
|
+
} catch {
|
|
4002
|
+
return false;
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
async function resolveImportedChildren(parent, manifest) {
|
|
4006
|
+
return await Promise.all((manifest.symbolRoutes ?? []).map(async (route) => {
|
|
4007
|
+
const resolvedImport = await this.resolve(route.importSource, parent, { skipSelf: true });
|
|
4008
|
+
const resolvedId = typeof resolvedImport === "string" ? resolvedImport : resolvedImport && typeof resolvedImport === "object" && "id" in resolvedImport ? String(resolvedImport.id) : fallbackImportedSource(parent, route.importSource);
|
|
4009
|
+
return {
|
|
4010
|
+
parent,
|
|
4011
|
+
specifier: route.importSource,
|
|
4012
|
+
source: pathname(resolvedId),
|
|
4013
|
+
componentEdgeId: route.componentEdgeId
|
|
4014
|
+
};
|
|
4015
|
+
}));
|
|
4016
|
+
}
|
|
4017
|
+
async function resolveImportedModuleInterfaces(parent, moduleImports) {
|
|
4018
|
+
return await Promise.all(moduleImports.filter((moduleImport) => TSRX_SOURCE_FILE.test(moduleImport.source)).map(async (moduleImport) => {
|
|
4019
|
+
const resolvedImport = await this.resolve(moduleImport.source, parent, { skipSelf: true });
|
|
4020
|
+
const resolvedId = typeof resolvedImport === "string" ? resolvedImport : resolvedImport && "id" in resolvedImport ? String(resolvedImport.id) : fallbackImportedSource(parent, moduleImport.source);
|
|
4021
|
+
return {
|
|
4022
|
+
parent,
|
|
4023
|
+
specifier: moduleImport.source,
|
|
4024
|
+
source: pathname(resolvedId)
|
|
4025
|
+
};
|
|
4026
|
+
}));
|
|
4027
|
+
}
|
|
4028
|
+
async function forceImportedModules(imports, artifacts, metadata, options, environment) {
|
|
4029
|
+
for (const imported of imports) {
|
|
4030
|
+
if (!artifacts.has(imported.source)) {
|
|
4031
|
+
if (options.dev === true) await options.devServer?.transformRequest(imported.source, environment);
|
|
4032
|
+
else if (typeof this.load === "function") await this.load({ id: imported.source });
|
|
4033
|
+
}
|
|
4034
|
+
const captureMetadata = metadata.captureMetadataForSource(imported.source);
|
|
4035
|
+
if (environment !== "client") continue;
|
|
4036
|
+
if (!captureMetadata?.extractedSymbols.length) {
|
|
4037
|
+
await metadata.sealSourceSymbolClaims(imported.source);
|
|
4038
|
+
continue;
|
|
4039
|
+
}
|
|
4040
|
+
const wakeSource = withQuery(imported.source, { "markless-prerender-wake": null });
|
|
4041
|
+
const completeWakeVariants = options.prerenderWakeChannel === true;
|
|
4042
|
+
const claimSources = [
|
|
4043
|
+
...completeWakeVariants ? [imported.source] : [],
|
|
4044
|
+
...completeWakeVariants ? [withQuery(imported.source, { "markless-resume": null })] : [],
|
|
4045
|
+
...completeWakeVariants ? [wakeSource] : [],
|
|
4046
|
+
withQuery(imported.source, { "markless-symbols": null })
|
|
4047
|
+
];
|
|
4048
|
+
if (typeof this.getModuleInfo === "function") metadata.expectSourceSymbolClaims(imported.source, claimSources);
|
|
4049
|
+
if (options.dev === true) await Promise.all(claimSources.map((source) => options.devServer?.transformRequest(source, environment)));
|
|
4050
|
+
else if (typeof this.load === "function") await Promise.all(claimSources.map((id) => this.load?.({ id })));
|
|
4051
|
+
await metadata.sealSourceSymbolClaims(imported.source);
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
function importedModuleInterfaces(imports, artifacts) {
|
|
4055
|
+
return Object.fromEntries(imports.flatMap((imported) => {
|
|
4056
|
+
const artifact = artifacts.get(imported.source);
|
|
4057
|
+
return artifact ? [[imported.specifier, artifact.moduleGraphInterface]] : [];
|
|
4058
|
+
}));
|
|
4059
|
+
}
|
|
4060
|
+
function uniqueImportedModules(imports) {
|
|
4061
|
+
return [...new Map(imports.map((imported) => [`${imported.parent}\0${imported.specifier}\0${imported.source}`, imported])).values()];
|
|
4062
|
+
}
|
|
4063
|
+
function importedSymbolInputs(children, metadata) {
|
|
4064
|
+
return children.flatMap((child) => {
|
|
4065
|
+
const captureMetadata = metadata.captureMetadataForSource(child.source);
|
|
4066
|
+
const claimManifest = sourceSymbolManifest(metadata, child.source);
|
|
4067
|
+
if (!captureMetadata || !claimManifest || !child.componentEdgeId) return [];
|
|
4068
|
+
return claimManifest.symbols.flatMap((symbol) => {
|
|
4069
|
+
const captureSymbol = captureMetadata.extractedSymbols.find((candidate) => candidate.symbolId === symbol.symbolId);
|
|
4070
|
+
return captureSymbol?.captureSlots.some((slot) => slot.propName !== void 0) ? [{
|
|
4071
|
+
id: `imported:${encodeURIComponent(child.source)}:${symbol.symbolId}`,
|
|
4072
|
+
chunk: symbol.virtualModuleId,
|
|
4073
|
+
exportName: symbol.exportName,
|
|
4074
|
+
componentEdgeId: child.componentEdgeId,
|
|
4075
|
+
captureSymbol
|
|
4076
|
+
}] : [];
|
|
4077
|
+
});
|
|
4078
|
+
});
|
|
4079
|
+
}
|
|
4080
|
+
function importedClaimsMissing(children, symbols, metadata) {
|
|
4081
|
+
return children.some((child) => {
|
|
4082
|
+
return metadata.captureMetadataForSource(child.source)?.extractedSymbols.some((symbol) => symbol.captureSlots.some((slot) => slot.propName !== void 0)) === true && !symbols.some((symbol) => symbol.componentEdgeId === child.componentEdgeId);
|
|
4083
|
+
});
|
|
4084
|
+
}
|
|
4085
|
+
function linkedChildrenHaveBrowserTriggers(children, metadata, capabilities) {
|
|
4086
|
+
return children.some((child) => {
|
|
4087
|
+
const manifest = sourceSymbolManifest(metadata, child.source);
|
|
4088
|
+
return manifest !== void 0 && manifestHasBrowserTriggers(manifest) || capabilities.get(child.source) === true;
|
|
4089
|
+
});
|
|
4090
|
+
}
|
|
4091
|
+
function sourceSymbolManifest(metadata, source) {
|
|
4092
|
+
const resolverId = `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodeURIComponent(source)}`;
|
|
4093
|
+
return metadata.sourceSymbolClaims(source, resolverId);
|
|
4094
|
+
}
|
|
4095
|
+
function manifestHasBrowserTriggers(manifest) {
|
|
4096
|
+
return manifest.symbols.some((symbol) => symbol.kind === "event-handler" || symbol.kind === "behavior");
|
|
4097
|
+
}
|
|
4098
|
+
function fallbackImportedSource(parent, specifier) {
|
|
4099
|
+
const source = specifier.split("?")[0];
|
|
4100
|
+
return isRelativeImport(source) ? resolve(dirname(parent), source) : source;
|
|
4101
|
+
}
|
|
4102
|
+
function importedChildKey(child) {
|
|
4103
|
+
return `${child.parent}\0${child.specifier}\0${child.source}`;
|
|
4104
|
+
}
|
|
4105
|
+
function validateImportedChild(child, metadata, parentManifest) {
|
|
4106
|
+
const parentMetadata = parentManifest?.captureMetadata ?? metadata.captureMetadataForSource(pathname(child.parent));
|
|
4107
|
+
const childMetadata = metadata.captureMetadataForSource(child.source);
|
|
4108
|
+
if (!childMetadata && isPlainTypeScriptSource(child.source)) return;
|
|
4109
|
+
if (parentMetadata && childMetadata?.passId === parentMetadata.passId && Array.isArray(childMetadata.extractedSymbols) && Array.isArray(childMetadata.diagnostics)) return;
|
|
4110
|
+
throw new Error(`MARKLESS_CAPTURE_METADATA_MISSING: Parent module ${JSON.stringify(child.parent)} composes imported child ${JSON.stringify(child.specifier)}, but its compiled artifact has no current capture metadata. Rebuild the child with the current Markless compiler and clear any stale build cache.`);
|
|
4111
|
+
}
|
|
4112
|
+
function isPlainTypeScriptSource(source) {
|
|
4113
|
+
return /\.[cm]?tsx?$/.test(source);
|
|
4114
|
+
}
|
|
4115
|
+
function canonicalExecutionAttributionSource(source) {
|
|
4116
|
+
return source.split("?")[0].split("#")[0];
|
|
4117
|
+
}
|
|
4118
|
+
function canonicalExecutionAttributionNodes(manifests) {
|
|
4119
|
+
const routesBySource = /* @__PURE__ */ new Map();
|
|
4120
|
+
const sorted = [...manifests].sort((left, right) => left.source.localeCompare(right.source));
|
|
4121
|
+
for (const manifest of sorted) {
|
|
4122
|
+
const source = canonicalExecutionAttributionSource(manifest.source);
|
|
4123
|
+
const routes = routesBySource.get(source) ?? /* @__PURE__ */ new Map();
|
|
4124
|
+
for (const route of manifest.symbolRoutes ?? []) if (!routes.has(route.prefix)) routes.set(route.prefix, route.importSource);
|
|
4125
|
+
routesBySource.set(source, routes);
|
|
4126
|
+
}
|
|
4127
|
+
return new Map([...routesBySource].map(([source, routes]) => [source, {
|
|
4128
|
+
source,
|
|
4129
|
+
symbolRoutes: [...routes].map(([prefix, importSource]) => ({
|
|
4130
|
+
prefix,
|
|
4131
|
+
importSource
|
|
4132
|
+
}))
|
|
4133
|
+
}]));
|
|
4134
|
+
}
|
|
4135
|
+
function executionAttributionRoots(nodes, childrenByRoute) {
|
|
4136
|
+
const children = /* @__PURE__ */ new Set();
|
|
4137
|
+
for (const node of nodes.values()) for (const route of node.symbolRoutes) {
|
|
4138
|
+
const child = resolvedRouteSource(node.source, route.importSource, childrenByRoute);
|
|
4139
|
+
if (nodes.has(child)) children.add(child);
|
|
4140
|
+
}
|
|
4141
|
+
return [...nodes.keys()].filter((source) => !children.has(source));
|
|
4142
|
+
}
|
|
4143
|
+
function executionAttributionTables(manifests, root, children) {
|
|
4144
|
+
const nodes = canonicalExecutionAttributionNodes(manifests);
|
|
4145
|
+
const childrenByRoute = new Map([...children].map((child) => [routeKey(canonicalExecutionAttributionSource(child.parent), child.specifier), canonicalExecutionAttributionSource(child.source)]).sort((left, right) => left[0].localeCompare(right[0]) || left[1].localeCompare(right[1])));
|
|
4146
|
+
return Object.fromEntries(executionAttributionRoots(nodes, childrenByRoute).sort().map((source) => [executionAttributionRouteKey(source, root), flattenExecutionAttributionScopes(source, nodes, childrenByRoute)]));
|
|
4147
|
+
}
|
|
4148
|
+
function executionAttributionRouteKey(source, root) {
|
|
4149
|
+
const prefix = root ? `${root.replace(/[/\\]+$/, "")}/` : "";
|
|
4150
|
+
return (prefix && source.startsWith(prefix) ? source.slice(prefix.length) : source).replace(/^[/\\]+/, "");
|
|
4151
|
+
}
|
|
4152
|
+
function flattenExecutionAttributionScopes(root, nodes, childrenByRoute) {
|
|
4153
|
+
const scopes = {};
|
|
4154
|
+
const visit = (source, scope, seen) => {
|
|
4155
|
+
if (seen.has(source)) return;
|
|
4156
|
+
scopes[scope] = encodedSymbolSource(source);
|
|
4157
|
+
const manifest = nodes.get(source);
|
|
4158
|
+
for (const route of manifest?.symbolRoutes ?? []) {
|
|
4159
|
+
const child = resolvedRouteSource(source, route.importSource, childrenByRoute);
|
|
4160
|
+
if (!nodes.has(child)) continue;
|
|
4161
|
+
visit(child, scope + route.prefix, new Set([...seen, source]));
|
|
4162
|
+
}
|
|
4163
|
+
};
|
|
4164
|
+
visit(root, "", /* @__PURE__ */ new Set());
|
|
4165
|
+
return scopes;
|
|
4166
|
+
}
|
|
4167
|
+
function resolvedRouteSource(parent, specifier, childrenByRoute) {
|
|
4168
|
+
return childrenByRoute.get(routeKey(parent, specifier)) ?? fallbackImportedSource(parent, specifier);
|
|
4169
|
+
}
|
|
4170
|
+
function routeKey(parent, specifier) {
|
|
4171
|
+
return `${parent}\0${specifier}`;
|
|
4172
|
+
}
|
|
4173
|
+
function bundleWithoutRemovedChunks(bundle, removedFileNames) {
|
|
4174
|
+
if (removedFileNames.size === 0) return bundle;
|
|
4175
|
+
const next = {};
|
|
4176
|
+
for (const [key, output] of Object.entries(bundle)) {
|
|
4177
|
+
if (isChunkFile(output) && removedFileNames.has(output.fileName)) continue;
|
|
4178
|
+
next[key] = output;
|
|
4179
|
+
}
|
|
4180
|
+
return next;
|
|
4181
|
+
}
|
|
4182
|
+
function stripEmptyPreloadWrappersFromChunks(bundle) {
|
|
4183
|
+
for (const output of Object.values(bundle)) {
|
|
4184
|
+
if (!isChunkWithCode(output)) continue;
|
|
4185
|
+
const nextCode = stripEmptyVitePreloadWrappers(output.code);
|
|
4186
|
+
if (nextCode !== output.code) output.code = nextCode;
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
function isChunkFile(output) {
|
|
4190
|
+
if (!output || typeof output !== "object") return false;
|
|
4191
|
+
const chunk = output;
|
|
4192
|
+
return chunk.type === "chunk" && typeof chunk.fileName === "string";
|
|
4193
|
+
}
|
|
4194
|
+
function isChunkWithCode(output) {
|
|
4195
|
+
if (!output || typeof output !== "object") return false;
|
|
4196
|
+
const chunk = output;
|
|
4197
|
+
return chunk.type === "chunk" && typeof chunk.code === "string";
|
|
4198
|
+
}
|
|
4199
|
+
function pluginName(environment) {
|
|
4200
|
+
if (typeof environment === "function") return "markless:rolldown";
|
|
4201
|
+
return `markless:rolldown:${environment}`;
|
|
4202
|
+
}
|
|
4203
|
+
function registerTransformArtifacts(input) {
|
|
4204
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4205
|
+
const renderDataHashes = /* @__PURE__ */ new Map();
|
|
4206
|
+
for (const module of input.result.virtualModules) {
|
|
4207
|
+
if (input.finalPublication === false && module.type === "resolver") continue;
|
|
4208
|
+
const isClientSymbol = input.environment === "client" && module.type === "symbol";
|
|
4209
|
+
const stored = isClientSymbol ? {
|
|
4210
|
+
...module,
|
|
4211
|
+
source: requalifyExecutionLogModuleHook(module.source, module.id)
|
|
4212
|
+
} : module;
|
|
4213
|
+
const current = input.virtualModules.get(module.id);
|
|
4214
|
+
if (module.type === "resolver" && current?.type === "resolver") {
|
|
4215
|
+
const currentClaims = new Set(current.symbolClaims ?? []);
|
|
4216
|
+
const nextClaims = new Set(module.symbolClaims ?? []);
|
|
4217
|
+
const currentContainsNext = [...nextClaims].every((claim) => currentClaims.has(claim));
|
|
4218
|
+
const nextContainsCurrent = [...currentClaims].every((claim) => nextClaims.has(claim));
|
|
4219
|
+
if (currentContainsNext && !nextContainsCurrent) continue;
|
|
4220
|
+
if (!currentContainsNext && !nextContainsCurrent) throw new Error(`MARKLESS_RESOLVER_CLAIMS_DIVERGED: Resolver ${JSON.stringify(module.id)} has incompatible final claim sets.`);
|
|
4221
|
+
}
|
|
4222
|
+
if (module.type !== "render-data" || current?.type !== "render-data" || current.canonicalRenderData !== true || module.canonicalRenderData === true) input.virtualModules.set(module.id, stored);
|
|
4223
|
+
ids.add(module.id);
|
|
4224
|
+
const owners = input.virtualModuleOwners.get(module.id) ?? /* @__PURE__ */ new Set();
|
|
4225
|
+
owners.add(input.owner);
|
|
4226
|
+
input.virtualModuleOwners.set(module.id, owners);
|
|
4227
|
+
if (module.type === "render-data") renderDataHashes.set(resolveVirtualId(module.id), renderDataHash(module.source));
|
|
4228
|
+
if (isClientSymbol) {
|
|
4229
|
+
input.executionLogEstimatedSizes.set(module.id, stored.source.length);
|
|
4230
|
+
if (hasExecutionLogModuleHook(stored.source)) input.executionLogEmittedIds.set(module.id, module.id);
|
|
4231
|
+
}
|
|
4232
|
+
}
|
|
4233
|
+
input.moduleMetadata.recordCaptureMetadata(input.source, input.result.manifest);
|
|
4234
|
+
if (input.finalPublication !== false) {
|
|
4235
|
+
const symbolClaim = emittedSymbolClaim(input.moduleMetadata, input.source, input.manifestSource, input.result.manifest, input.result.virtualModules);
|
|
4236
|
+
input.moduleMetadata.recordSymbolClaims(symbolClaim.owner, symbolClaim.manifest);
|
|
4237
|
+
if (input.tracksSourceClaimPublication === true) input.moduleMetadata.finishSourceSymbolClaims(input.source, input.manifestSource);
|
|
4238
|
+
}
|
|
4239
|
+
input.moduleLinkArtifacts.set(input.source, {
|
|
4240
|
+
moduleGraphInterface: input.result.moduleGraphInterface,
|
|
4241
|
+
interfaceHash: input.result.interfaceHash,
|
|
4242
|
+
moduleImports: input.result.moduleImports
|
|
4243
|
+
});
|
|
4244
|
+
const previouslyOwned = input.transformVirtualModules.get(input.owner) ?? /* @__PURE__ */ new Set();
|
|
4245
|
+
if (input.replaceOwnedArtifacts === true) {
|
|
4246
|
+
for (const staleId of previouslyOwned) {
|
|
4247
|
+
if (ids.has(staleId)) continue;
|
|
4248
|
+
const owners = input.virtualModuleOwners.get(staleId);
|
|
4249
|
+
owners?.delete(input.owner);
|
|
4250
|
+
if (!owners || owners.size === 0) {
|
|
4251
|
+
input.virtualModuleOwners.delete(staleId);
|
|
4252
|
+
input.virtualModules.delete(staleId);
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
input.transformVirtualModules.set(input.owner, ids);
|
|
4256
|
+
} else input.transformVirtualModules.set(input.owner, new Set([...previouslyOwned, ...ids]));
|
|
4257
|
+
input.dev.record(input.source, ids, input.environment);
|
|
4258
|
+
if (renderDataHashes.size > 0) input.updateDevPrerenderHashes?.(renderDataHashes);
|
|
4259
|
+
}
|
|
4260
|
+
function replaceClaimsWithPrerenderWakeOwner(metadata, source) {
|
|
4261
|
+
for (const emittedModule of metadata.symbolClaimMap().keys()) if (pathname(emittedModule) === source && (emittedModule === source || isResumeSourceRequest(emittedModule))) metadata.deleteSymbolClaims(emittedModule);
|
|
4262
|
+
}
|
|
4263
|
+
function emittedSymbolClaim(metadata, source, emittedModule, manifest, virtualModules) {
|
|
4264
|
+
const claim = manifestForSource(manifest, emittedModule);
|
|
4265
|
+
if (isPrerenderWakeSourceRequest(emittedModule) && manifest.symbols.length > 0) {
|
|
4266
|
+
replaceClaimsWithPrerenderWakeOwner(metadata, source);
|
|
4267
|
+
const resolver = virtualModules.find((module) => module.type === "resolver");
|
|
4268
|
+
if (!resolver) throw new Error("MARKLESS_PRERENDER_WAKE_RESOLVER_MISSING");
|
|
4269
|
+
return {
|
|
4270
|
+
owner: resolver.id,
|
|
4271
|
+
manifest: {
|
|
4272
|
+
...manifestForSource(manifest, source),
|
|
4273
|
+
resolver: { virtualModuleId: resolver.id }
|
|
4274
|
+
}
|
|
4275
|
+
};
|
|
4276
|
+
}
|
|
4277
|
+
return {
|
|
4278
|
+
owner: emittedModule,
|
|
4279
|
+
manifest: metadata.hasSymbolClaims(manifest.resolver.virtualModuleId) && (emittedModule === source || isResumeSourceRequest(emittedModule)) ? {
|
|
4280
|
+
...claim,
|
|
4281
|
+
symbols: []
|
|
4282
|
+
} : claim
|
|
4283
|
+
};
|
|
4284
|
+
}
|
|
4285
|
+
function registerRenderDataStyles(input) {
|
|
4286
|
+
if (input.modules.length === 0) return;
|
|
4287
|
+
const ids = new Set(input.transformVirtualModules.get(input.owner) ?? []);
|
|
4288
|
+
for (const module of input.modules) {
|
|
4289
|
+
input.virtualModules.set(module.id, module);
|
|
4290
|
+
ids.add(module.id);
|
|
4291
|
+
const owners = input.virtualModuleOwners.get(module.id) ?? /* @__PURE__ */ new Set();
|
|
4292
|
+
owners.add(input.owner);
|
|
4293
|
+
input.virtualModuleOwners.set(module.id, owners);
|
|
4294
|
+
}
|
|
4295
|
+
input.transformVirtualModules.set(input.owner, ids);
|
|
4296
|
+
input.dev.record(input.source, input.modules.map((module) => module.id), "client");
|
|
4297
|
+
}
|
|
4298
|
+
function manifestForSource(manifest, source) {
|
|
4299
|
+
return manifest.source === source ? manifest : {
|
|
4300
|
+
...manifest,
|
|
4301
|
+
source
|
|
4302
|
+
};
|
|
4303
|
+
}
|
|
4304
|
+
function renderDataClaimManifest(manifest, source) {
|
|
4305
|
+
return {
|
|
4306
|
+
...manifestForSource(manifest, source),
|
|
4307
|
+
symbols: []
|
|
4308
|
+
};
|
|
4309
|
+
}
|
|
4310
|
+
function renderDataHash(source) {
|
|
4311
|
+
let hash = 2166136261;
|
|
4312
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
4313
|
+
hash ^= source.charCodeAt(index);
|
|
4314
|
+
hash = Math.imul(hash, 16777619);
|
|
4315
|
+
}
|
|
4316
|
+
return `mrd1-${(hash >>> 0).toString(36)}`;
|
|
4317
|
+
}
|
|
4318
|
+
function importedInterfaceHashSignature(imports, artifacts) {
|
|
4319
|
+
return imports.map((imported) => [
|
|
4320
|
+
imported.specifier,
|
|
4321
|
+
imported.source,
|
|
4322
|
+
artifacts.get(imported.source)?.interfaceHash ?? "missing"
|
|
4323
|
+
].map(encodeURIComponent).join(":")).sort().join("|");
|
|
4324
|
+
}
|
|
4325
|
+
function importedSymbolClaimSignature(imports, metadata) {
|
|
4326
|
+
return [...new Set(imports.map((imported) => imported.source))].sort().map((source) => JSON.stringify([source, sourceSymbolManifest(metadata, source)?.symbols ?? []])).join("|");
|
|
4327
|
+
}
|
|
4328
|
+
function isRenderDataOnlyTransformChange(previous, next) {
|
|
4329
|
+
if (previous.interfaceHash !== next.interfaceHash || previous.code !== next.code) return false;
|
|
4330
|
+
if (JSON.stringify(previous.moduleImports) !== JSON.stringify(next.moduleImports)) return false;
|
|
4331
|
+
const withoutRenderData = (result) => result.virtualModules.filter((module) => module.type !== "render-data");
|
|
4332
|
+
if (JSON.stringify(withoutRenderData(previous)) !== JSON.stringify(withoutRenderData(next))) return false;
|
|
4333
|
+
return JSON.stringify(previous.manifest) === JSON.stringify(next.manifest);
|
|
4334
|
+
}
|
|
4335
|
+
function stripBuildPrefix(fileName) {
|
|
4336
|
+
return fileName.startsWith(MARKLESS_BUILD_PREFIX) ? fileName.slice(MARKLESS_BUILD_PREFIX.length) : fileName;
|
|
4337
|
+
}
|
|
4338
|
+
function virtualModuleSourceForLoad(module, options) {
|
|
4339
|
+
if (!options.dev || module.type !== "resolver") return module.source;
|
|
4340
|
+
if (!module.source.includes("moduleUrls[row[0]]")) return module.source;
|
|
4341
|
+
return module.source.replace(SYMBOL_VIRTUAL_STRING_RE, (_match, _quote, virtualId) => JSON.stringify(devBrowserVirtualModuleUrl(virtualId, options.publicPath)));
|
|
4342
|
+
}
|
|
4343
|
+
function devBrowserSourceModuleUrl(source, _root, publicPath) {
|
|
4344
|
+
const path = withQuery(joinURL("@fs", withoutLeadingSlash(source)), { import: null });
|
|
4345
|
+
return publicPath ? publicPath(path) : joinURL("/", path);
|
|
4346
|
+
}
|
|
4347
|
+
function devBrowserVirtualModuleUrl(virtualId, publicPath) {
|
|
4348
|
+
const path = joinURL("@id", resolveVirtualId(virtualId).replace("\0", "__x00__"));
|
|
4349
|
+
return publicPath ? publicPath(path) : joinURL("/", path);
|
|
4350
|
+
}
|
|
4351
|
+
function clientSymbolEntries(input, root) {
|
|
4352
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return [];
|
|
4353
|
+
const sources = [];
|
|
4354
|
+
for (const [name, value] of Object.entries(input)) {
|
|
4355
|
+
if (!/symbol/i.test(name)) continue;
|
|
4356
|
+
for (const entry of inputEntryValues(value)) if (typeof entry === "string" && TSRX_SOURCE_FILE.test(entry)) sources.push(normalizeInputSource(entry, root));
|
|
4357
|
+
}
|
|
4358
|
+
return sources;
|
|
4359
|
+
}
|
|
4360
|
+
function inputEntryValues(value) {
|
|
4361
|
+
return Array.isArray(value) ? value.flatMap(inputEntryValues) : [value];
|
|
4362
|
+
}
|
|
4363
|
+
function normalizeInputSource(source, root) {
|
|
4364
|
+
const path = pathname(source);
|
|
4365
|
+
if (isAbsolute(path)) return path;
|
|
4366
|
+
return pathname(resolve(root ?? "", path));
|
|
4367
|
+
}
|
|
4368
|
+
function isSymbolOnlySourceRequest(id) {
|
|
4369
|
+
return MARKLESS_SYMBOL_SOURCE_QUERY_RE.test(id);
|
|
4370
|
+
}
|
|
4371
|
+
function isResumeSourceRequest(id) {
|
|
4372
|
+
return MARKLESS_RESUME_SOURCE_QUERY_RE.test(id);
|
|
4373
|
+
}
|
|
4374
|
+
function isRenderDataSourceRequest(id) {
|
|
4375
|
+
return MARKLESS_RENDER_DATA_SOURCE_QUERY_RE.test(id);
|
|
4376
|
+
}
|
|
4377
|
+
function materializedRenderDataReachRoot(id, source, materializations) {
|
|
4378
|
+
if (materializations.has(source)) return source;
|
|
4379
|
+
return new URLSearchParams(parsePath(id).search).get(MARKLESS_REACHED_FROM_SOURCE_QUERY) ?? void 0;
|
|
4380
|
+
}
|
|
4381
|
+
function materializedReachedRenderDataSource(source, routeRoot) {
|
|
4382
|
+
return withQuery(source, {
|
|
4383
|
+
"markless-render-data": null,
|
|
4384
|
+
[MARKLESS_REACHED_FROM_SOURCE_QUERY]: routeRoot
|
|
4385
|
+
});
|
|
4386
|
+
}
|
|
4387
|
+
function isPrerenderWakeSourceRequest(id) {
|
|
4388
|
+
return MARKLESS_PRERENDER_WAKE_SOURCE_QUERY_RE.test(id);
|
|
4389
|
+
}
|
|
4390
|
+
function isClientPrimarySourceRequest(id) {
|
|
4391
|
+
return !(MARKLESS_SYMBOL_SOURCE_QUERY_RE.test(id) || MARKLESS_RESUME_SOURCE_QUERY_RE.test(id) || MARKLESS_RENDER_DATA_SOURCE_QUERY_RE.test(id) || MARKLESS_PRERENDER_WAKE_SOURCE_QUERY_RE.test(id) || MARKLESS_ROUTE_SOURCE_QUERY_RE.test(id));
|
|
4392
|
+
}
|
|
4393
|
+
function clientRouteArtifactReference(source) {
|
|
4394
|
+
const symbolSource = source.includes("?") ? `${source}&markless-symbols` : `${source}?markless-symbols`;
|
|
4395
|
+
const renderDataSource = source.includes("?") ? `${source}&markless-render-data` : `${source}?markless-render-data`;
|
|
4396
|
+
return [
|
|
4397
|
+
`const [symbolModule, renderDataModule] = await Promise.all([import(${JSON.stringify(symbolSource)}), import(${JSON.stringify(renderDataSource)})]);`,
|
|
4398
|
+
"const marklessRouteArtifact = {",
|
|
4399
|
+
" renderData: renderDataModule.marklessPrerenderData,",
|
|
4400
|
+
" loadSymbol: symbolModule.loadSymbol,",
|
|
4401
|
+
"};",
|
|
4402
|
+
"export default marklessRouteArtifact;"
|
|
4403
|
+
].join("\n");
|
|
4404
|
+
}
|
|
4405
|
+
function sourceForSymbolVirtualImporter(importer) {
|
|
4406
|
+
if (!importer) return null;
|
|
4407
|
+
return symbolVirtualModuleSourceFile(normalizeVirtualId(importer));
|
|
4408
|
+
}
|
|
4409
|
+
function sourceForResumeVirtualImporter(importer) {
|
|
4410
|
+
if (!importer) return null;
|
|
4411
|
+
const match = normalizeVirtualId(importer).match(RESUME_VIRTUAL_ID_RE);
|
|
4412
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
4413
|
+
}
|
|
4414
|
+
function resolverVirtualModuleSourceFile(id) {
|
|
4415
|
+
const prefix = `${MARKLESS_VIRTUAL_PREFIX}resolver:`;
|
|
4416
|
+
return id.startsWith(prefix) ? decodeURIComponent(id.slice(prefix.length)) : null;
|
|
4417
|
+
}
|
|
4418
|
+
function sourceForTriggerGroupVirtualImporter(importer) {
|
|
4419
|
+
if (!importer) return null;
|
|
4420
|
+
return triggerGroupVirtualModuleSourceFile(normalizeVirtualId(importer));
|
|
4421
|
+
}
|
|
4422
|
+
function sourceForPrerenderWakeVirtualImporter(importer) {
|
|
4423
|
+
if (!importer) return null;
|
|
4424
|
+
const match = normalizeVirtualId(importer).match(PRERENDER_WAKE_VIRTUAL_ID_RE);
|
|
4425
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
4426
|
+
}
|
|
4427
|
+
function sourceForSettleVirtualImporter(importer) {
|
|
4428
|
+
if (!importer) return null;
|
|
4429
|
+
const match = normalizeVirtualId(importer).match(SETTLE_VIRTUAL_ID_RE);
|
|
4430
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
4431
|
+
}
|
|
4432
|
+
function recordProductionSettleModuleUrls(bundle, urls, publicPath) {
|
|
4433
|
+
for (const output of Object.values(bundle)) {
|
|
4434
|
+
if (!output || typeof output !== "object") continue;
|
|
4435
|
+
const chunk = output;
|
|
4436
|
+
if (chunk.type !== "chunk" || typeof chunk.facadeModuleId !== "string" || typeof chunk.fileName !== "string") continue;
|
|
4437
|
+
const source = sourceForSettleVirtualImporter(chunk.facadeModuleId);
|
|
4438
|
+
if (source) urls.set(source, publicPath?.(chunk.fileName) ?? `/${chunk.fileName}`);
|
|
4439
|
+
}
|
|
4440
|
+
}
|
|
4441
|
+
function recordProductionResumeModuleUrls(bundle, urls, publicPath) {
|
|
4442
|
+
if (!urls) return;
|
|
4443
|
+
for (const output of Object.values(bundle)) {
|
|
4444
|
+
if (!output || typeof output !== "object") continue;
|
|
4445
|
+
const chunk = output;
|
|
4446
|
+
if (chunk.type !== "chunk" || typeof chunk.facadeModuleId !== "string" || typeof chunk.fileName !== "string") continue;
|
|
4447
|
+
const source = sourceForResumeVirtualImporter(chunk.facadeModuleId);
|
|
4448
|
+
if (source) urls.set(source, publicPath?.(chunk.fileName) ?? `/${chunk.fileName}`);
|
|
4449
|
+
}
|
|
4450
|
+
}
|
|
4451
|
+
function recordProductionPrerenderWakeModuleUrls(bundle, urls, publicPath) {
|
|
4452
|
+
if (!urls) return;
|
|
4453
|
+
for (const output of Object.values(bundle)) {
|
|
4454
|
+
if (!output || typeof output !== "object") continue;
|
|
4455
|
+
const chunk = output;
|
|
4456
|
+
if (chunk.type !== "chunk" || typeof chunk.facadeModuleId !== "string" || typeof chunk.fileName !== "string") continue;
|
|
4457
|
+
const source = sourceForPrerenderWakeVirtualImporter(chunk.facadeModuleId);
|
|
4458
|
+
if (source) urls.set(source, publicPath?.(chunk.fileName) ?? `/${chunk.fileName}`);
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
function productionWakeModuleChunks(bundle) {
|
|
4462
|
+
const chunks = [];
|
|
4463
|
+
for (const output of Object.values(bundle)) {
|
|
4464
|
+
if (!output || typeof output !== "object") continue;
|
|
4465
|
+
const chunk = output;
|
|
4466
|
+
if (chunk.type === "chunk" && typeof chunk.facadeModuleId === "string" && typeof chunk.fileName === "string" && (sourceForResumeVirtualImporter(chunk.facadeModuleId) || sourceForPrerenderWakeVirtualImporter(chunk.facadeModuleId))) chunks.push(stripBuildPrefix(chunk.fileName));
|
|
4467
|
+
}
|
|
4468
|
+
return chunks;
|
|
4469
|
+
}
|
|
4470
|
+
function isRelativeImport(source) {
|
|
4471
|
+
return source.startsWith("./") || source.startsWith("../");
|
|
4472
|
+
}
|
|
4473
|
+
function isMarklessRuntimeModule(id) {
|
|
4474
|
+
const path = pathname(id);
|
|
4475
|
+
return /[/\\](?:web|runtime|serializer)[/\\]src[/\\].+\.ts$/.test(path);
|
|
4476
|
+
}
|
|
4477
|
+
function executionLogRuntimeModuleId(id) {
|
|
4478
|
+
const path = pathname(id);
|
|
4479
|
+
const match = path.match(/[/\\](web|runtime|serializer)[/\\]src[/\\]([^?#]+)\.ts$/);
|
|
4480
|
+
return match ? `${match[1]}:${match[2].replace(/[/\\]/g, "/")}` : path;
|
|
4481
|
+
}
|
|
4482
|
+
function normalizeVirtualId(id) {
|
|
4483
|
+
const bare = id.startsWith("\0") ? id.slice(1) : id;
|
|
4484
|
+
if (!bare.startsWith("virtual:markless:")) return bare;
|
|
4485
|
+
const queryIndex = bare.indexOf("?");
|
|
4486
|
+
return `${MARKLESS_VIRTUAL_PREFIX}${(queryIndex === -1 ? bare : bare.slice(0, queryIndex)).slice(MARKLESS_VIRTUAL_PREFIX.length).split(":").map((segment) => {
|
|
4487
|
+
try {
|
|
4488
|
+
return encodeURIComponent(decodeURIComponent(segment));
|
|
4489
|
+
} catch {
|
|
4490
|
+
return segment;
|
|
4491
|
+
}
|
|
4492
|
+
}).join(":")}`;
|
|
4493
|
+
}
|
|
4494
|
+
function emittedBundleModuleIds(bundle) {
|
|
4495
|
+
const ids = /* @__PURE__ */ new Set();
|
|
4496
|
+
for (const output of Object.values(bundle)) {
|
|
4497
|
+
if (!output || typeof output !== "object") continue;
|
|
4498
|
+
const chunk = output;
|
|
4499
|
+
if (chunk.type !== "chunk") continue;
|
|
4500
|
+
if (typeof chunk.facadeModuleId === "string") ids.add(normalizeVirtualId(chunk.facadeModuleId));
|
|
4501
|
+
if (Array.isArray(chunk.moduleIds)) {
|
|
4502
|
+
for (const id of chunk.moduleIds) if (typeof id === "string") ids.add(normalizeVirtualId(id));
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
return ids;
|
|
4506
|
+
}
|
|
4507
|
+
function resolveVirtualId(id) {
|
|
4508
|
+
if (id.startsWith("\0")) return id;
|
|
4509
|
+
return `\0${id}`;
|
|
4510
|
+
}
|
|
4511
|
+
function pathname(id) {
|
|
4512
|
+
return parsePath(id).pathname;
|
|
4513
|
+
}
|
|
4514
|
+
//#endregion
|
|
4515
|
+
export { createBuildMetadata as a, collectHeadLinkInjections as c, outputDefaults as d, convertManifestToBundleGraph as f, marklessServer as i, MARKLESS_BUILD_PREFIX as l, marklessClient as n, preflightTsrxModuleDiagnostics as o, createPreloadGraphAdder as p, marklessLib as r, transformTsrxModule as s, createMarklessRolldownPlugin as t, MARKLESS_BUNDLE_GRAPH as u };
|