@markless/bundler 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-worker.d.ts +1 -0
- package/dist/build-worker.js +59 -0
- package/dist/chunk-ast-C8zKZiam.js +1 -0
- package/dist/chunk-ast-pN_P5wIo.js +204 -0
- package/dist/chunk-tasks-BexSGNjx.js +1 -0
- package/dist/compile-store-DxF9Vj4_.js +187 -0
- package/dist/{execution-log-BL-7a77M.d.ts → execution-log-7HH5XDfA.d.ts} +2 -2
- package/dist/lazy-module-facades-qZajWDD8.js +2691 -0
- package/dist/planned-landing-BHy22Yf5.js +2291 -0
- package/dist/preload.d.ts +2 -2
- package/dist/preload.js +2 -2
- package/dist/{rolldown-BMQrr9-Y.js → rolldown-DS8OY1i9.js} +801 -4406
- package/dist/rolldown.d.ts +3 -3
- package/dist/rolldown.js +3 -2
- package/dist/{roster-resume-CpphsFl_.js → roster-resume-DXptD6DG.js} +2 -1
- package/dist/{route-pack-groups-BLS6xeVV.js → route-pack-groups-ByQmKKom.js} +892 -1004
- package/dist/{types-iOUoceJ-.d.ts → types-B8YqEscg.d.ts} +55 -2
- package/dist/vite.d.ts +6 -1
- package/dist/vite.js +798 -26
- package/package.json +6 -5
- package/dist/optimized-deps-BfzxSm6C.js +0 -89
|
@@ -0,0 +1,2291 @@
|
|
|
1
|
+
import { c as createCompileErrorPayload, s as MarklessCompileError } from "./dev-error-BEduK_R3.js";
|
|
2
|
+
import { $ as EXECUTION_LOG_CHUNK_MODULE_PATTERN, A as emitSourceModule, B as symbolVirtualModuleSourceFile, C as MARKLESS_VIRTUAL_PREFIX, D as emitOverlayLoaderInstall, E as demandsOverlay, F as resumeVirtualModuleId, G as sharedInlineSourcesModuleId, H as emitSymbolRouteTable, I as rewriteSymbolModuleExport, J as compilePrerenderInlineResumerSources, L as scopedSymbolExportName, M as payloadModule, N as prerenderWakeVirtualModuleId, O as emitResumeModule, R as settleVirtualModuleId, _ as sourceForModuleId, ct as normalizeExecutionLogMode, k as emitSettleModule, ot as injectExecutionLogModuleHook, q as compileInlineResumerSources, z as symbolVirtualModuleId } from "./route-pack-groups-ByQmKKom.js";
|
|
3
|
+
import { artifactChildCandidates, collectTsrxModuleDiagnostics, compileTsrxModule, componentEdgeSymbolRoutes, emitSymbolResolverModule, importedNestedRepeats, importedRowBranchMints, importedRowComponentMints, importedRowSlotReaders, importedRowTemplateMints, importedSymbolRoutes, linkedRenderDataBoundarySymbols, moduleInterfaceHash, parseJavaScriptModule, prerenderInterfacesComplete, propsDeciding, rowsDecidedBy } from "@markless/compiler";
|
|
4
|
+
import { existsSync, readFileSync, readdirSync, realpathSync } from "node:fs";
|
|
5
|
+
import { dirname, isAbsolute, join, normalize, resolve } from "pathe";
|
|
6
|
+
import { joinURL, parsePath, withQuery, withoutLeadingSlash } from "ufo";
|
|
7
|
+
import { parseSync, transformSync } from "rolldown/experimental";
|
|
8
|
+
import { PROTOCOL_EVENT_ACTION_KIND, PROTOCOL_IDLE_EVENT_NAME, PROTOCOL_PROP_GRAPH_NODE_PREFIX, createStorageSeedMetadataFromGraphNodeId, jsonSourceWithNonFiniteNumbers, protocolEventActionKind } from "@markless/serializer";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
//#region src/build/preload-plan.ts
|
|
11
|
+
const DEFAULT_MIN_PROBABILITY = 0;
|
|
12
|
+
const JAVASCRIPT_MODULE_RE = /\.(?:mjs|js)(?:[?#].*)?$/;
|
|
13
|
+
const PRIORITY_RANK = {
|
|
14
|
+
high: 2,
|
|
15
|
+
auto: 1,
|
|
16
|
+
low: 0
|
|
17
|
+
};
|
|
18
|
+
function planModulePreloadUrls(input) {
|
|
19
|
+
return planModulePreloads(input).map((preload) => preload.href);
|
|
20
|
+
}
|
|
21
|
+
function planModulePreloads(input) {
|
|
22
|
+
const minProbability = input.minProbability ?? DEFAULT_MIN_PROBABILITY;
|
|
23
|
+
const maxPreloads = input.maxPreloads ?? Number.POSITIVE_INFINITY;
|
|
24
|
+
const graph = parseBundleGraph(input.bundleGraph);
|
|
25
|
+
const planned = /* @__PURE__ */ new Map();
|
|
26
|
+
const bestVisitByNode = /* @__PURE__ */ new Map();
|
|
27
|
+
let order = 0;
|
|
28
|
+
const addModule = (name, probability, priority, fetchPriority) => {
|
|
29
|
+
if (!isPreloadableModuleName(name)) return;
|
|
30
|
+
const href = preloadHref(input.base, name);
|
|
31
|
+
const existing = planned.get(href);
|
|
32
|
+
const nextRank = PRIORITY_RANK[priority];
|
|
33
|
+
const existingRank = existing ? PRIORITY_RANK[existing.priority] : -1;
|
|
34
|
+
if (existing && (existingRank > nextRank || existingRank === nextRank && existing.probability >= probability)) return;
|
|
35
|
+
planned.set(href, {
|
|
36
|
+
fetchPriority,
|
|
37
|
+
href,
|
|
38
|
+
name,
|
|
39
|
+
order: existing?.order ?? order++,
|
|
40
|
+
priority,
|
|
41
|
+
probability
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
const visit = (name, probability, priority, fetchPriority, seen, suppressed = false, suppressRootOnly = false) => {
|
|
45
|
+
if (probability < minProbability || planned.size >= maxPreloads) return;
|
|
46
|
+
if (!suppressed) {
|
|
47
|
+
const priorityRank = PRIORITY_RANK[priority];
|
|
48
|
+
const previousBest = bestVisitByNode.get(name);
|
|
49
|
+
if (previousBest && (previousBest.priorityRank > priorityRank || previousBest.priorityRank === priorityRank && previousBest.probability >= probability)) return;
|
|
50
|
+
bestVisitByNode.set(name, {
|
|
51
|
+
priorityRank,
|
|
52
|
+
probability
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (seen.has(name)) return;
|
|
56
|
+
const nextSeen = new Set(seen);
|
|
57
|
+
nextSeen.add(name);
|
|
58
|
+
const record = graph.get(name);
|
|
59
|
+
if (!record) {
|
|
60
|
+
if (!suppressed) addModule(name, probability, priority, fetchPriority);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
for (const dep of record.deps.filter((item) => item.kind === "static")) visit(dep.name, probability * dep.probability, priority, fetchPriority, nextSeen, suppressed && !suppressRootOnly);
|
|
64
|
+
if (!suppressed) addModule(name, probability, priority, fetchPriority);
|
|
65
|
+
for (const dep of record.deps.filter((item) => item.kind === "dynamic")) {
|
|
66
|
+
if (input.lazyChunks?.has(dep.name)) continue;
|
|
67
|
+
const edgeProbability = JAVASCRIPT_MODULE_RE.test(name) ? dep.probability : 1;
|
|
68
|
+
visit(dep.name, probability * edgeProbability, priority, fetchPriority, nextSeen, false);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
for (const root of input.roots) {
|
|
72
|
+
const normalized = normalizeRoot(root);
|
|
73
|
+
visit(normalized.name, 1, normalized.priority, normalized.fetchPriority, /* @__PURE__ */ new Set(), normalized.edges === "dynamic-only" || normalized.edges === "dependencies-only", normalized.edges === "dependencies-only");
|
|
74
|
+
}
|
|
75
|
+
return [...planned.values()].sort((left, right) => {
|
|
76
|
+
const priority = PRIORITY_RANK[right.priority] - PRIORITY_RANK[left.priority];
|
|
77
|
+
if (priority !== 0) return priority;
|
|
78
|
+
return left.order - right.order;
|
|
79
|
+
}).slice(0, maxPreloads).map(({ order: _order, ...preload }) => preload);
|
|
80
|
+
}
|
|
81
|
+
function parseBundleGraph(graph) {
|
|
82
|
+
const records = /* @__PURE__ */ new Map();
|
|
83
|
+
if (!graph) return records;
|
|
84
|
+
let index = 0;
|
|
85
|
+
while (index < graph.length) {
|
|
86
|
+
const name = graph[index++];
|
|
87
|
+
if (typeof name !== "string") continue;
|
|
88
|
+
const deps = [];
|
|
89
|
+
let probability = 1;
|
|
90
|
+
let kind = "static";
|
|
91
|
+
while (typeof graph[index] === "number") {
|
|
92
|
+
const marker = graph[index++];
|
|
93
|
+
if (marker < 0) {
|
|
94
|
+
probability = -marker / 10;
|
|
95
|
+
kind = "dynamic";
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
const dep = graph[marker];
|
|
99
|
+
if (typeof dep === "string") deps.push({
|
|
100
|
+
name: dep,
|
|
101
|
+
kind,
|
|
102
|
+
probability
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
records.set(name, {
|
|
106
|
+
name,
|
|
107
|
+
deps
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
return records;
|
|
111
|
+
}
|
|
112
|
+
function preloadHref(base, name) {
|
|
113
|
+
if (!base || /^(?:[a-z]+:)?\/\//i.test(name)) return name;
|
|
114
|
+
return joinURL(base, name);
|
|
115
|
+
}
|
|
116
|
+
function isPreloadableModuleName(name) {
|
|
117
|
+
return JAVASCRIPT_MODULE_RE.test(name) || isViteDevModuleUrl(name);
|
|
118
|
+
}
|
|
119
|
+
function isViteDevModuleUrl(name) {
|
|
120
|
+
return (name.startsWith("/") || name.startsWith("@id/")) && /(?:^|[?&])import(?:[&#]|$)/.test(name);
|
|
121
|
+
}
|
|
122
|
+
function normalizeRoot(root) {
|
|
123
|
+
if (typeof root === "string") return {
|
|
124
|
+
name: root,
|
|
125
|
+
priority: "auto",
|
|
126
|
+
fetchPriority: "auto"
|
|
127
|
+
};
|
|
128
|
+
const priority = root.priority ?? "auto";
|
|
129
|
+
return {
|
|
130
|
+
name: root.name,
|
|
131
|
+
priority,
|
|
132
|
+
edges: root.edges,
|
|
133
|
+
fetchPriority: root.fetchPriority ?? priorityToFetchPriority(priority)
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function priorityToFetchPriority(priority) {
|
|
137
|
+
if (priority === "auto") return "auto";
|
|
138
|
+
return priority;
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/optimized-deps.ts
|
|
142
|
+
const NESTED_DEPENDENCY = " > ";
|
|
143
|
+
const RUNTIME_FUNCTIONS_PREFIX = "@markless/web/fns/";
|
|
144
|
+
function optimizedDepsToInclude(specifiers, resolution) {
|
|
145
|
+
const root = resolve(resolution.root ?? "");
|
|
146
|
+
const preserveSymlinks = resolution.resolve?.preserveSymlinks === true;
|
|
147
|
+
const alias = resolution.resolve?.alias;
|
|
148
|
+
return specifiers.filter((specifier) => !servedFromSource(applyAlias(specifier.split(NESTED_DEPENDENCY)[0], alias), root, preserveSymlinks));
|
|
149
|
+
}
|
|
150
|
+
function includeOptimizedDeps(config, specifiers) {
|
|
151
|
+
const bundled = optimizedDepsToInclude(specifiers, config);
|
|
152
|
+
if (bundled.length === 0) return;
|
|
153
|
+
const optimizeDeps = config.optimizeDeps ??= {};
|
|
154
|
+
const include = optimizeDeps.include ?? [];
|
|
155
|
+
optimizeDeps.include = [...include, ...bundled.filter((specifier) => !include.includes(specifier))];
|
|
156
|
+
}
|
|
157
|
+
function runtimeFunctionSpecifiers(webEntry = import.meta.resolve?.("@markless/web")) {
|
|
158
|
+
if (!webEntry?.startsWith("file://")) return [];
|
|
159
|
+
let files;
|
|
160
|
+
try {
|
|
161
|
+
files = readdirSync(join(dirname(fileURLToPath(webEntry)), "fns"));
|
|
162
|
+
} catch {
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
return files.filter((file) => file.endsWith(".js")).map((file) => `@markless/core${NESTED_DEPENDENCY}${RUNTIME_FUNCTIONS_PREFIX}${file.slice(0, -3)}`);
|
|
166
|
+
}
|
|
167
|
+
function excludeSourceShippedDeps(config) {
|
|
168
|
+
const appManifest = nearestManifest(resolve(config.root ?? ""));
|
|
169
|
+
if (!appManifest) return;
|
|
170
|
+
const shipsSource = [];
|
|
171
|
+
const seen = /* @__PURE__ */ new Set();
|
|
172
|
+
const visit = (names, from) => {
|
|
173
|
+
for (const name of names) {
|
|
174
|
+
const directory = installedPackage(name, from);
|
|
175
|
+
if (directory === void 0 || seen.has(directory)) continue;
|
|
176
|
+
seen.add(directory);
|
|
177
|
+
const manifest = readManifest(join(directory, "package.json"));
|
|
178
|
+
if (manifest?.publishConfig?.marklessShipsSource !== true) continue;
|
|
179
|
+
if (!shipsSource.includes(name)) shipsSource.push(name);
|
|
180
|
+
visit(Object.keys(manifest.dependencies ?? {}), realpathOf(directory));
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
visit([...Object.keys(appManifest.manifest.dependencies ?? {}), ...Object.keys(appManifest.manifest.devDependencies ?? {})], appManifest.directory);
|
|
184
|
+
if (shipsSource.length === 0) return;
|
|
185
|
+
const optimizeDeps = config.optimizeDeps ??= {};
|
|
186
|
+
const exclude = optimizeDeps.exclude ?? [];
|
|
187
|
+
optimizeDeps.exclude = [...exclude, ...shipsSource.filter((name) => !exclude.includes(name))];
|
|
188
|
+
}
|
|
189
|
+
function readManifest(path) {
|
|
190
|
+
try {
|
|
191
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
192
|
+
} catch {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function nearestManifest(root) {
|
|
197
|
+
for (let directory = root;; directory = dirname(directory)) {
|
|
198
|
+
const manifest = existsSync(join(directory, "package.json")) ? readManifest(join(directory, "package.json")) : void 0;
|
|
199
|
+
if (manifest) return {
|
|
200
|
+
directory,
|
|
201
|
+
manifest
|
|
202
|
+
};
|
|
203
|
+
if (dirname(directory) === directory) return void 0;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function applyAlias(specifier, alias) {
|
|
207
|
+
if (!alias) return specifier;
|
|
208
|
+
const entries = Array.isArray(alias) ? alias : Object.entries(alias).map(([find, replacement]) => ({
|
|
209
|
+
find,
|
|
210
|
+
replacement
|
|
211
|
+
}));
|
|
212
|
+
for (const { find, replacement } of entries) if (typeof find === "string") {
|
|
213
|
+
if (specifier === find || specifier.startsWith(`${find}/`)) return replacement + specifier.slice(find.length);
|
|
214
|
+
} else if (find.test(specifier)) return specifier.replace(find, replacement);
|
|
215
|
+
return specifier;
|
|
216
|
+
}
|
|
217
|
+
function servedFromSource(id, root, preserveSymlinks) {
|
|
218
|
+
const path = isAbsolute(id) || id.startsWith(".") ? resolve(root, id) : installedPackage(id, root);
|
|
219
|
+
if (path === void 0) return false;
|
|
220
|
+
return !`${preserveSymlinks ? normalize(path) : realpathOf(path)}/`.includes("/node_modules/");
|
|
221
|
+
}
|
|
222
|
+
function installedPackage(specifier, root) {
|
|
223
|
+
const segments = specifier.split("/");
|
|
224
|
+
const name = specifier.startsWith("@") ? segments.slice(0, 2).join("/") : segments[0];
|
|
225
|
+
for (let directory = root;; directory = dirname(directory)) {
|
|
226
|
+
const entry = join(directory, "node_modules", name);
|
|
227
|
+
if (existsSync(entry)) return entry;
|
|
228
|
+
if (dirname(directory) === directory) return void 0;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function realpathOf(path) {
|
|
232
|
+
try {
|
|
233
|
+
return normalize(realpathSync(path));
|
|
234
|
+
} catch {
|
|
235
|
+
return normalize(path);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
const MARKLESS_BUILD_PREFIX = `build/`;
|
|
239
|
+
const MARKLESS_BUNDLE_GRAPH = `${MARKLESS_BUILD_PREFIX}bundle-graph.json`;
|
|
240
|
+
const MARKLESS_EXECUTION_SIZES = `${MARKLESS_BUILD_PREFIX}execution-sizes.json`;
|
|
241
|
+
const MARKLESS_EXECUTION_DEMAND = `${MARKLESS_BUILD_PREFIX}execution-demand.json`;
|
|
242
|
+
const MARKLESS_INTERACTION_CLOSURES = `${MARKLESS_BUILD_PREFIX}interaction-closures.json`;
|
|
243
|
+
const MARKLESS_BYTE_ATTRIBUTION = `${MARKLESS_BUILD_PREFIX}byte-attribution.json`;
|
|
244
|
+
const MARKLESS_SERVER_CHUNK_MAX_BYTES = 4194304;
|
|
245
|
+
const MARKLESS_BUILD_METADATA_FILES = [
|
|
246
|
+
MARKLESS_BUNDLE_GRAPH,
|
|
247
|
+
MARKLESS_EXECUTION_SIZES,
|
|
248
|
+
MARKLESS_EXECUTION_DEMAND,
|
|
249
|
+
MARKLESS_INTERACTION_CLOSURES,
|
|
250
|
+
MARKLESS_BYTE_ATTRIBUTION
|
|
251
|
+
];
|
|
252
|
+
const MARKLESS_PUBLIC_BUILD_METADATA_FILES = [MARKLESS_EXECUTION_SIZES];
|
|
253
|
+
const WEB_RUNTIME_CAPABILITY_GROUPS = [
|
|
254
|
+
{
|
|
255
|
+
name: "markless-direct-renderer",
|
|
256
|
+
test: fileBasenamePattern("direct")
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: "markless-resume-branches",
|
|
260
|
+
test: fileBasenamePattern("resume-branches", "resume-arm-records-lazy")
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: "markless-resume-behaviors",
|
|
264
|
+
test: fileBasenamePattern("resume-behaviors")
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "markless-resume-repeats",
|
|
268
|
+
test: fileBasenamePattern("resume-keyed-repeats", "resume-keyed-repeats-lazy", "repeat-runtime")
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: "markless-resume-async",
|
|
272
|
+
test: fileBasenamePattern("resume-async-boundaries", "resume-async-wiring")
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: "markless-resume-shared-patch",
|
|
276
|
+
test: fileBasenamePattern("resume-shared-patch")
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: "markless-resume-runtime",
|
|
280
|
+
test: fileBasenamePattern("resume-runtime")
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
name: "markless-resume-runtime-start",
|
|
284
|
+
test: fileBasenamePattern("resume-runtime-start")
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
name: "markless-resume-runtime-shared",
|
|
288
|
+
test: fileBasenamePattern("resume-runtime-shared")
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
name: "markless-resume-events",
|
|
292
|
+
test: fileBasenamePattern("resume-events")
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "markless-resume-handoff",
|
|
296
|
+
test: fileBasenamePattern("resume-handoff")
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
name: "markless-resume-locators",
|
|
300
|
+
test: fileBasenamePattern("resume-locators", "resume-census")
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "markless-resume-errors",
|
|
304
|
+
test: fileBasenamePattern("resume-errors")
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
name: "markless-resume-sync-computed",
|
|
308
|
+
test: fileBasenamePattern("resume-sync-computed")
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: "markless-resume-sync-demand",
|
|
312
|
+
test: fileBasenamePattern("resume-sync-demand")
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: "markless-payload-full",
|
|
316
|
+
test: fileBasenamePattern("payload-full", "payload-full-storage-free")
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
name: "markless-payload-resume",
|
|
320
|
+
test: fileBasenamePattern("payload-resume", "payload-resume-lazy")
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
name: "markless-inline-payload-document",
|
|
324
|
+
test: /[/\\]web[/\\]src[/\\]inline[/\\]payload-document\.ts(?:[?#].*)?$/
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
name: "markless-payload-document",
|
|
328
|
+
test: fileBasenamePattern("payload-document", "payload-document-common", "payload-resume-registry")
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: "markless-payload-graph-construct",
|
|
332
|
+
test: fileBasenamePattern("payload-graph-construct")
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: "markless-dom-journal",
|
|
336
|
+
test: fileBasenamePattern("dom-journal")
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
name: "markless-protocol-decode",
|
|
340
|
+
test: fileBasenamePattern("protocol-client", "protocol-client-storage", "protocol-state", "storage-record-client")
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: "markless-value-decode",
|
|
344
|
+
test: fileBasenamePattern("value-decode-client", "value-decode-client-lazy", "value-decode-extensions")
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
name: "markless-payload-leaves",
|
|
348
|
+
test: fileBasenamePattern("payload", "payload-document")
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: "markless-dev-log",
|
|
352
|
+
test: EXECUTION_LOG_CHUNK_MODULE_PATTERN
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
name: "markless-resume-core",
|
|
356
|
+
test: fileBasenamePattern("resume")
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
name: "markless-runtime-graph-core",
|
|
360
|
+
test: fileBasenamePattern("graph-core")
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
name: "markless-runtime-graph-collections",
|
|
364
|
+
test: fileBasenamePattern("graph-collections")
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
name: "markless-runtime-graph-computed",
|
|
368
|
+
test: fileBasenamePattern("graph-computed")
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: "markless-runtime-graph-async",
|
|
372
|
+
test: fileBasenamePattern("graph-async")
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: "markless-runtime-graph-scheduler",
|
|
376
|
+
test: fileBasenamePattern("graph-scheduler")
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
name: "markless-runtime-graph-shared",
|
|
380
|
+
test: fileBasenamePattern("graph-shared")
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
name: "markless-graph",
|
|
384
|
+
test: /[/\\](?:runtime[/\\]src[/\\](?!graph-(?:core|collections|computed|async|scheduler|shared)\.ts)|core[/\\]src[/\\]runtime)[/\\]?/
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: "markless-serializer",
|
|
388
|
+
test: /[/\\]serializer[/\\]src[/\\](?!protocol-validation)/
|
|
389
|
+
}
|
|
390
|
+
];
|
|
391
|
+
function fileBasenamePattern(...names) {
|
|
392
|
+
return new RegExp(`[/\\\\](?:${names.join("|")})\\.ts(?:[?#].*)?$`);
|
|
393
|
+
}
|
|
394
|
+
const MARKLESS_RUNTIME_GROUPS = [...WEB_RUNTIME_CAPABILITY_GROUPS, {
|
|
395
|
+
name: "markless-runtime",
|
|
396
|
+
test: /[/\\]@markless[/\\]runtime[/\\]/
|
|
397
|
+
}];
|
|
398
|
+
const MARKLESS_SERVER_COMPILED_GROUP = {
|
|
399
|
+
name: "markless-server",
|
|
400
|
+
minShareCount: 2,
|
|
401
|
+
test: /\.tsrx(?:[?#]|$)|^\0?virtual:markless:/,
|
|
402
|
+
entriesAware: true,
|
|
403
|
+
maxSize: MARKLESS_SERVER_CHUNK_MAX_BYTES
|
|
404
|
+
};
|
|
405
|
+
function outputDefaults(output, environment) {
|
|
406
|
+
if (environment === "lib") return output;
|
|
407
|
+
const next = {
|
|
408
|
+
...output,
|
|
409
|
+
hoistTransitiveImports: false
|
|
410
|
+
};
|
|
411
|
+
if (environment === "server") {
|
|
412
|
+
next.entryFileNames ??= "[name].js";
|
|
413
|
+
next.chunkFileNames ??= "chunk-[hash].js";
|
|
414
|
+
const splitting = marklessCodeSplitting(next.codeSplitting);
|
|
415
|
+
next.codeSplitting = {
|
|
416
|
+
...splitting,
|
|
417
|
+
groups: [...splitting.groups, MARKLESS_SERVER_COMPILED_GROUP]
|
|
418
|
+
};
|
|
419
|
+
return next;
|
|
420
|
+
}
|
|
421
|
+
next.entryFileNames ??= `${MARKLESS_BUILD_PREFIX}chunk-[hash].js`;
|
|
422
|
+
next.chunkFileNames ??= `${MARKLESS_BUILD_PREFIX}chunk-[hash].js`;
|
|
423
|
+
next.minifyInternalExports = true;
|
|
424
|
+
next.strictExecutionOrder = true;
|
|
425
|
+
next.codeSplitting = marklessCodeSplitting(next.codeSplitting);
|
|
426
|
+
return next;
|
|
427
|
+
}
|
|
428
|
+
function marklessCodeSplitting(codeSplitting) {
|
|
429
|
+
if (typeof codeSplitting === "boolean") throw new Error("@markless/bundler requires output.codeSplitting to be an object so runtime chunks can be grouped.");
|
|
430
|
+
return {
|
|
431
|
+
...codeSplitting,
|
|
432
|
+
groups: [...MARKLESS_RUNTIME_GROUPS, ...codeSplitting?.groups ?? []]
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
//#endregion
|
|
436
|
+
//#region src/render-data-literals.ts
|
|
437
|
+
const factored = /* @__PURE__ */ new Map();
|
|
438
|
+
const FACTORED_LIMIT = 512;
|
|
439
|
+
function factorRenderDataLiterals(records, declarations) {
|
|
440
|
+
if (records.length < 2) return {
|
|
441
|
+
records: [...records],
|
|
442
|
+
factories: []
|
|
443
|
+
};
|
|
444
|
+
const key = JSON.stringify([declarations, records]);
|
|
445
|
+
let result = factored.get(key);
|
|
446
|
+
if (result) factored.delete(key);
|
|
447
|
+
else {
|
|
448
|
+
result = factorUncached(records, declarations);
|
|
449
|
+
if (factored.size >= FACTORED_LIMIT) factored.delete(factored.keys().next().value);
|
|
450
|
+
}
|
|
451
|
+
factored.set(key, result);
|
|
452
|
+
return {
|
|
453
|
+
records: [...result.records],
|
|
454
|
+
factories: [...result.factories]
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function factorUncached(records, declarations) {
|
|
458
|
+
const unchanged = {
|
|
459
|
+
records: [...records],
|
|
460
|
+
factories: []
|
|
461
|
+
};
|
|
462
|
+
const reserved = /* @__PURE__ */ new Set();
|
|
463
|
+
const visit = (value) => {
|
|
464
|
+
if (!value || typeof value !== "object") return;
|
|
465
|
+
if (value.type === "Identifier") reserved.add(String(value.name));
|
|
466
|
+
for (const child of Object.values(value)) if (Array.isArray(child)) child.forEach(visit);
|
|
467
|
+
else if (child && typeof child === "object") visit(child);
|
|
468
|
+
};
|
|
469
|
+
const groups = /* @__PURE__ */ new Map();
|
|
470
|
+
const parsed = /* @__PURE__ */ new Map();
|
|
471
|
+
const prefix = "const data=";
|
|
472
|
+
try {
|
|
473
|
+
if (declarations.includes("\\")) visit(parseJavaScriptModule(declarations));
|
|
474
|
+
else for (const name of declarations.match(FACTORY_NAME) ?? []) reserved.add(name);
|
|
475
|
+
records.forEach((source, record) => {
|
|
476
|
+
let sites = parsed.get(source);
|
|
477
|
+
sites ??= scannedLiteralSites(source);
|
|
478
|
+
if (!sites) {
|
|
479
|
+
const literal = parseJavaScriptModule(prefix + source + ";").body[0]?.declarations[0]?.init;
|
|
480
|
+
sites = literal?.type === "ObjectExpression" ? literal.properties.flatMap((property) => {
|
|
481
|
+
if (property.type !== "Property" || property.computed || !["state", "view"].includes(String(property.key.value)) || !["ObjectExpression", "ArrayExpression"].includes(property.value.type)) return [];
|
|
482
|
+
const start = property.value.start - 11, end = property.value.end - 11;
|
|
483
|
+
return [{
|
|
484
|
+
start,
|
|
485
|
+
end,
|
|
486
|
+
source: source.slice(start, end)
|
|
487
|
+
}];
|
|
488
|
+
}) : [];
|
|
489
|
+
parsed.set(source, sites);
|
|
490
|
+
}
|
|
491
|
+
for (const site of sites) {
|
|
492
|
+
let group = groups.get(site.source);
|
|
493
|
+
if (!group) groups.set(site.source, group = []);
|
|
494
|
+
group.push({
|
|
495
|
+
...site,
|
|
496
|
+
record
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
} catch {
|
|
501
|
+
return unchanged;
|
|
502
|
+
}
|
|
503
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
504
|
+
const factories = [];
|
|
505
|
+
const bytes = (source) => new TextEncoder().encode(source).length;
|
|
506
|
+
let index = 0;
|
|
507
|
+
for (const [literal, sites] of groups) {
|
|
508
|
+
if (sites.length < 2) continue;
|
|
509
|
+
let name;
|
|
510
|
+
do
|
|
511
|
+
name = `marklessRenderLiteral${index++}`;
|
|
512
|
+
while (reserved.has(name));
|
|
513
|
+
const replacement = `${name}()`, factory = `function ${name}(){return ${literal}}`;
|
|
514
|
+
if (bytes(factory) + 1 + sites.length * bytes(replacement) >= sites.length * bytes(literal)) continue;
|
|
515
|
+
factories.push(factory);
|
|
516
|
+
reserved.add(name);
|
|
517
|
+
for (const site of sites) {
|
|
518
|
+
let entries = replacements.get(site.record);
|
|
519
|
+
if (!entries) replacements.set(site.record, entries = []);
|
|
520
|
+
entries.push({
|
|
521
|
+
...site,
|
|
522
|
+
replacement
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
factories,
|
|
528
|
+
records: records.map((source, index) => {
|
|
529
|
+
for (const site of (replacements.get(index) ?? []).sort((a, b) => b.start - a.start)) source = source.slice(0, site.start) + site.replacement + source.slice(site.end);
|
|
530
|
+
return source;
|
|
531
|
+
})
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
const FACTORY_NAME = /marklessRenderLiteral\d+/g;
|
|
535
|
+
function scannedLiteralSites(source) {
|
|
536
|
+
let cursor = skipSpace(source, 0);
|
|
537
|
+
if (source[cursor] !== "{") return void 0;
|
|
538
|
+
const sites = [];
|
|
539
|
+
cursor = skipSpace(source, cursor + 1);
|
|
540
|
+
if (source[cursor] === "}") return skipSpace(source, cursor + 1) === source.length ? sites : void 0;
|
|
541
|
+
for (;;) {
|
|
542
|
+
if (source[cursor] !== "\"") return void 0;
|
|
543
|
+
const keyEnd = stringEnd(source, cursor);
|
|
544
|
+
if (keyEnd < 0) return void 0;
|
|
545
|
+
const key = JSON.parse(source.slice(cursor, keyEnd));
|
|
546
|
+
cursor = skipSpace(source, keyEnd);
|
|
547
|
+
if (source[cursor] !== ":") return void 0;
|
|
548
|
+
const start = skipSpace(source, cursor + 1);
|
|
549
|
+
const end = valueEnd(source, start);
|
|
550
|
+
if (end < 0 || end === start) return void 0;
|
|
551
|
+
if ((key === "state" || key === "view") && (source[start] === "{" || source[start] === "[")) sites.push({
|
|
552
|
+
start,
|
|
553
|
+
end,
|
|
554
|
+
source: source.slice(start, end)
|
|
555
|
+
});
|
|
556
|
+
cursor = skipSpace(source, end);
|
|
557
|
+
if (source[cursor] === ",") {
|
|
558
|
+
cursor = skipSpace(source, cursor + 1);
|
|
559
|
+
continue;
|
|
560
|
+
}
|
|
561
|
+
if (source[cursor] !== "}") return void 0;
|
|
562
|
+
return skipSpace(source, cursor + 1) === source.length ? sites : void 0;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
function skipSpace(source, from) {
|
|
566
|
+
let cursor = from;
|
|
567
|
+
while (cursor < source.length && JSON_SPACE.has(source[cursor])) cursor++;
|
|
568
|
+
return cursor;
|
|
569
|
+
}
|
|
570
|
+
const JSON_SPACE = /* @__PURE__ */ new Set([
|
|
571
|
+
" ",
|
|
572
|
+
" ",
|
|
573
|
+
"\n",
|
|
574
|
+
"\r"
|
|
575
|
+
]);
|
|
576
|
+
function stringEnd(source, start) {
|
|
577
|
+
for (let cursor = start + 1; cursor < source.length; cursor++) {
|
|
578
|
+
const char = source[cursor];
|
|
579
|
+
if (char === "\\") cursor++;
|
|
580
|
+
else if (char === "\"") return cursor + 1;
|
|
581
|
+
}
|
|
582
|
+
return -1;
|
|
583
|
+
}
|
|
584
|
+
function valueEnd(source, start) {
|
|
585
|
+
let depth = 0;
|
|
586
|
+
for (let cursor = start; cursor < source.length; cursor++) {
|
|
587
|
+
const char = source[cursor];
|
|
588
|
+
if (char === "\"") {
|
|
589
|
+
const end = stringEnd(source, cursor);
|
|
590
|
+
if (end < 0) return -1;
|
|
591
|
+
if (depth === 0) return end;
|
|
592
|
+
cursor = end - 1;
|
|
593
|
+
} else if (char === "{" || char === "[") depth++;
|
|
594
|
+
else if (char === "}" || char === "]") {
|
|
595
|
+
if (depth === 0) return cursor;
|
|
596
|
+
if (--depth === 0) return cursor + 1;
|
|
597
|
+
} else if (depth === 0 && (char === "," || JSON_SPACE.has(char))) return cursor;
|
|
598
|
+
}
|
|
599
|
+
return depth === 0 ? source.length : -1;
|
|
600
|
+
}
|
|
601
|
+
//#endregion
|
|
602
|
+
//#region src/served-render-data.ts
|
|
603
|
+
const MARKLESS_SERVED_RENDER_DATA_QUERY = "markless-served";
|
|
604
|
+
/** The served spelling of a render-data source request. */
|
|
605
|
+
function servedRenderDataSourceReference(source) {
|
|
606
|
+
return withQuery(source, { [MARKLESS_SERVED_RENDER_DATA_QUERY]: null });
|
|
607
|
+
}
|
|
608
|
+
function isServedRenderDataRequest(id) {
|
|
609
|
+
return new URLSearchParams(parsePath(id).search).has(MARKLESS_SERVED_RENDER_DATA_QUERY);
|
|
610
|
+
}
|
|
611
|
+
//#endregion
|
|
612
|
+
//#region src/prop-flow.ts
|
|
613
|
+
function modulePropFlow(compiled, diagnostics) {
|
|
614
|
+
const graph = compiled.semanticGraph;
|
|
615
|
+
return {
|
|
616
|
+
components: (graph.components ?? []).map((component) => ({
|
|
617
|
+
name: component.name,
|
|
618
|
+
...component.exportName ? { exportName: component.exportName } : {}
|
|
619
|
+
})),
|
|
620
|
+
decided: diagnostics.flatMap((diagnostic) => diagnostic.decidedByProps && diagnostic.suppressed !== true ? [{
|
|
621
|
+
code: diagnostic.code,
|
|
622
|
+
componentName: diagnostic.decidedByProps.componentName,
|
|
623
|
+
props: diagnostic.decidedByProps.props,
|
|
624
|
+
message: diagnostic.message
|
|
625
|
+
}] : []),
|
|
626
|
+
edges: (graph.componentEdges ?? []).map((edge) => {
|
|
627
|
+
const spread = edge.props.find((prop) => prop.kind === "spread");
|
|
628
|
+
return {
|
|
629
|
+
id: edge.id,
|
|
630
|
+
parentComponentName: edge.parentComponentName,
|
|
631
|
+
childComponentName: edge.childComponentName,
|
|
632
|
+
...edge.importSource ? { importSource: edge.importSource } : {},
|
|
633
|
+
...edge.importedName ? { importedName: edge.importedName } : {},
|
|
634
|
+
props: Object.fromEntries(edge.props.flatMap((prop) => prop.kind === "spread" ? [] : [[prop.name, passedProp(prop, graph, edge.keyedRepeatScopeIds)]])),
|
|
635
|
+
...spread ? { spread: passedProp(spread, graph, edge.keyedRepeatScopeIds) } : {}
|
|
636
|
+
};
|
|
637
|
+
})
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
function passedProp(prop, graph, repeatIds = []) {
|
|
641
|
+
const row = rowValue(prop, graph, repeatIds);
|
|
642
|
+
if (row !== void 0) return !row ? {
|
|
643
|
+
kind: "changing",
|
|
644
|
+
source: prop.source
|
|
645
|
+
} : row.length === 0 ? { kind: "fixed" } : {
|
|
646
|
+
kind: "forwarded",
|
|
647
|
+
props: row,
|
|
648
|
+
source: prop.source
|
|
649
|
+
};
|
|
650
|
+
switch (prop.kind) {
|
|
651
|
+
case "serializable":
|
|
652
|
+
case "callback":
|
|
653
|
+
case "element-handle-id": return { kind: "fixed" };
|
|
654
|
+
case "opaque": return prop.buildTimeValue ? { kind: "fixed" } : {
|
|
655
|
+
kind: "unknown",
|
|
656
|
+
source: prop.source
|
|
657
|
+
};
|
|
658
|
+
case "graph-reference":
|
|
659
|
+
case "spread": {
|
|
660
|
+
if (prop.kind === "graph-reference" && prop.graphBindingKind === "element") return { kind: "fixed" };
|
|
661
|
+
if (prop.kind === "spread" && prop.graphNodeId.startsWith(PROTOCOL_PROP_GRAPH_NODE_PREFIX)) return {
|
|
662
|
+
kind: "forwarded",
|
|
663
|
+
props: [],
|
|
664
|
+
source: prop.source
|
|
665
|
+
};
|
|
666
|
+
const deciding = propsDeciding(prop.graphNodeId, prop.path, graph);
|
|
667
|
+
if (!deciding) return {
|
|
668
|
+
kind: "changing",
|
|
669
|
+
source: prop.source
|
|
670
|
+
};
|
|
671
|
+
return deciding.length === 0 ? { kind: "fixed" } : {
|
|
672
|
+
kind: "forwarded",
|
|
673
|
+
props: deciding,
|
|
674
|
+
source: prop.source
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
default: return {
|
|
678
|
+
kind: "unknown",
|
|
679
|
+
source: prop.source ?? ""
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
function rowValue(prop, graph, repeatIds) {
|
|
684
|
+
if (prop.kind !== "opaque" || prop.buildTimeValue) return void 0;
|
|
685
|
+
const root = /^[A-Za-z_$][\w$]*/.exec(prop.source)?.[0];
|
|
686
|
+
if (!root || !/^[A-Za-z_$][\w$]*(?:(?:\?\.|\.)[A-Za-z_$][\w$]*)*$/.test(prop.source)) return void 0;
|
|
687
|
+
for (const id of [...repeatIds].reverse()) {
|
|
688
|
+
const repeat = graph.keyedRepeats.find((candidate) => candidate.id === id);
|
|
689
|
+
if (repeat && (repeat.itemName === root || repeat.indexName === root)) return rowsDecidedBy(repeat, graph);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
var PropFlowRegistry = class {
|
|
693
|
+
#modules = /* @__PURE__ */ new Map();
|
|
694
|
+
record(source, flow, childSources) {
|
|
695
|
+
this.#modules.set(source, {
|
|
696
|
+
flow,
|
|
697
|
+
childSources
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
clear() {
|
|
701
|
+
this.#modules.clear();
|
|
702
|
+
}
|
|
703
|
+
/** One message per prop-decided @if some caller can change, or whose caller the build cannot see. */
|
|
704
|
+
refusals() {
|
|
705
|
+
const refusals = [];
|
|
706
|
+
for (const [source, { flow }] of this.#modules) for (const decided of flow.decided) for (const prop of decided.props) {
|
|
707
|
+
const reason = this.#changes(source, decided.componentName, prop, /* @__PURE__ */ new Set());
|
|
708
|
+
if (reason) refusals.push(refusalMessage(decided, source, prop, reason));
|
|
709
|
+
}
|
|
710
|
+
return refusals;
|
|
711
|
+
}
|
|
712
|
+
#changes(source, componentName, prop, seen) {
|
|
713
|
+
const key = `${source}\0${componentName}\0${prop}`;
|
|
714
|
+
if (seen.has(key)) return void 0;
|
|
715
|
+
seen.add(key);
|
|
716
|
+
for (const [callerSource, { flow, childSources }] of this.#modules) for (const edge of flow.edges) {
|
|
717
|
+
if (!this.#targets(callerSource, edge, childSources, source, componentName)) continue;
|
|
718
|
+
const passed = edge.props[prop] ?? edge.spread;
|
|
719
|
+
if (!passed || passed.kind === "fixed") continue;
|
|
720
|
+
const where = `<${edge.parentComponentName}> in ${callerSource}`;
|
|
721
|
+
if (passed.kind === "changing") return `${where} passes it \`${passed.source}\`, which changes.`;
|
|
722
|
+
if (passed.kind === "unknown") return `${where} passes it \`${passed.source}\`, which the build cannot prove never changes.`;
|
|
723
|
+
for (const forwarded of passed.props.length > 0 ? passed.props : [prop]) {
|
|
724
|
+
const deeper = this.#changes(callerSource, edge.parentComponentName, forwarded, seen);
|
|
725
|
+
if (deeper) return `${where} hands it its own prop \`${forwarded}\`; ${deeper}`;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
#targets(callerSource, edge, childSources, source, componentName) {
|
|
730
|
+
if (!edge.importSource) return callerSource === source && edge.childComponentName === componentName;
|
|
731
|
+
if (childSources.get(edge.id) !== source) return false;
|
|
732
|
+
const target = this.#modules.get(source);
|
|
733
|
+
const exportName = edge.importedName ?? "default";
|
|
734
|
+
return target?.flow.components.some((component) => component.name === componentName && (component.exportName === exportName || exportName !== "default" && component.name === exportName)) ?? false;
|
|
735
|
+
}
|
|
736
|
+
};
|
|
737
|
+
function refusalMessage(decided, source, prop, reason) {
|
|
738
|
+
const at = `${source}: <${decided.componentName}>: ${decided.message}`;
|
|
739
|
+
switch (decided.code) {
|
|
740
|
+
case "MARKLESS_BRANCH_ARM_UPDATE_UNSUPPORTED": return `MARKLESS_BRANCH_ARM_UPDATE_UNSUPPORTED: ${at} Its test reads the prop \`${prop}\`, and ${reason} Pass \`${prop}\` a value that does not change, or show the content outside the @if and hide it with an attribute.`;
|
|
741
|
+
case "MARKLESS_KEYED_REPEAT_ROW_MINT_UNSUPPORTED": return `MARKLESS_KEYED_REPEAT_ROW_MINT_UNSUPPORTED: ${at} The list comes from the prop \`${prop}\`, and ${reason} Pass \`${prop}\` a value that does not change, or keep the row to markup the browser can build.`;
|
|
742
|
+
case "MARKLESS_ROW_BRANCH_FLIP_UNSUPPORTED": return `MARKLESS_ROW_BRANCH_FLIP_UNSUPPORTED: ${at} The rows come from the prop \`${prop}\`, and ${reason} Pass \`${prop}\` a value that does not change, or keep the row to markup the browser can build.`;
|
|
743
|
+
case "MARKLESS_TEMPLATE_EXPRESSION_STATIC": return `MARKLESS_TEMPLATE_EXPRESSION_STATIC: ${at} It holds only while the prop \`${prop}\` never changes, and ${reason} Pass \`${prop}\` a value that does not change, or read a plain value from the prop.`;
|
|
744
|
+
default: return `${decided.code}: ${at} It holds only while the prop \`${prop}\` never changes, and ${reason} Pass \`${prop}\` a value that does not change.`;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
//#endregion
|
|
748
|
+
//#region src/bound-resolver.ts
|
|
749
|
+
function adaptImportedCaptureResolver(source, hasImportedRows) {
|
|
750
|
+
if (!hasImportedRows) return source;
|
|
751
|
+
const original = " return (context) => base({ ...context, capture: createCaptureContext(context, bound) });";
|
|
752
|
+
const replacement = [
|
|
753
|
+
" return async (context) => {",
|
|
754
|
+
" const pendingCallbacks = [];",
|
|
755
|
+
" const capture = createCaptureContext(context, bound);",
|
|
756
|
+
" const result = await base({ ...context, graph: createBoundGraph(context, bound, capture, pendingCallbacks), capture });",
|
|
757
|
+
" await Promise.all(pendingCallbacks);",
|
|
758
|
+
" return result;",
|
|
759
|
+
" };"
|
|
760
|
+
].join("\n");
|
|
761
|
+
const helper = [
|
|
762
|
+
"function createBoundGraph(context, bound, capture, pendingCallbacks) {",
|
|
763
|
+
" const legacySlots = new Map(bound.captureSlots.flatMap((slot) => slot.legacyGraphRead ? [[JSON.stringify([slot.legacyGraphRead.graphNodeId, slot.legacyGraphRead.path ?? []]), slot]] : []));",
|
|
764
|
+
" let lastCallback = Promise.resolve();",
|
|
765
|
+
" return {",
|
|
766
|
+
" ...context.graph,",
|
|
767
|
+
" read(graphNodeId, path = []) {",
|
|
768
|
+
" const slot = legacySlots.get(JSON.stringify([graphNodeId, path]));",
|
|
769
|
+
" if (!slot) return context.graph.read(graphNodeId, path);",
|
|
770
|
+
" if (slot.route.kind === callbackRoute) return (...args) => {",
|
|
771
|
+
" const pending = lastCallback.then(() => capture.invoke(slot.slotId, args));",
|
|
772
|
+
" lastCallback = pending.catch(() => {});",
|
|
773
|
+
" pendingCallbacks.push(pending);",
|
|
774
|
+
" return pending;",
|
|
775
|
+
" };",
|
|
776
|
+
" return capture.read(slot.slotId);",
|
|
777
|
+
" },",
|
|
778
|
+
" };",
|
|
779
|
+
"}",
|
|
780
|
+
""
|
|
781
|
+
].join("\n");
|
|
782
|
+
return source.replace(original, replacement).replace("function createCaptureContext(context, bound) {", `${helper}function createCaptureContext(context, bound) {`);
|
|
783
|
+
}
|
|
784
|
+
//#endregion
|
|
785
|
+
//#region src/trigger-groups.ts
|
|
786
|
+
const EVENT_STAGES_BROWSER_TRIGGER = {
|
|
787
|
+
[PROTOCOL_EVENT_ACTION_KIND.event]: true,
|
|
788
|
+
[PROTOCOL_EVENT_ACTION_KIND.externalDelegate]: false
|
|
789
|
+
};
|
|
790
|
+
function triggerGroupVirtualModuleId(filename, index) {
|
|
791
|
+
return `virtual:markless:trigger-group:${encodeURIComponent(filename)}:${index}`;
|
|
792
|
+
}
|
|
793
|
+
function triggerGroupVirtualModuleSourceFile(moduleId) {
|
|
794
|
+
const bare = moduleId.startsWith("\0") ? moduleId.slice(1) : moduleId;
|
|
795
|
+
const match = /^virtual:markless:trigger-group:([^:]+):\d+$/.exec(bare);
|
|
796
|
+
if (!match?.[1]) return null;
|
|
797
|
+
try {
|
|
798
|
+
return decodeURIComponent(match[1]);
|
|
799
|
+
} catch {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
function emitPrerenderTriggerGroupModule(input) {
|
|
804
|
+
const armRendererModuleId = input.armRendererModuleId ?? input.group.armRendererModuleId;
|
|
805
|
+
const ids = new Set(input.group.symbolIds);
|
|
806
|
+
const boundRows = input.boundRows.filter((row) => ids.has(row.id));
|
|
807
|
+
let source = emitSymbolResolverModule({
|
|
808
|
+
symbols: input.symbols.filter((symbol) => ids.has(symbol.id)),
|
|
809
|
+
boundSymbols: boundRows,
|
|
810
|
+
literalImports: input.literalImports,
|
|
811
|
+
bundlerVisibleImports: input.literalImports
|
|
812
|
+
});
|
|
813
|
+
const routes = (input.symbolRoutes ?? []).map((route) => route.boundSymbols ? {
|
|
814
|
+
...route,
|
|
815
|
+
boundSymbols: Object.fromEntries(Object.entries(route.boundSymbols).filter(([, rowId]) => ids.has(rowId)))
|
|
816
|
+
} : route);
|
|
817
|
+
if (routes.length > 0) {
|
|
818
|
+
source = source.replaceAll("loadSymbol(", "marklessLoadLocalSymbol(");
|
|
819
|
+
source += "\n" + emitSymbolRouteTable({
|
|
820
|
+
routes: routes.map((route) => "importSource" in route ? {
|
|
821
|
+
...route,
|
|
822
|
+
importSource: symbolRouteImportSource(route.importSource)
|
|
823
|
+
} : route),
|
|
824
|
+
functionName: "loadSymbol",
|
|
825
|
+
fallbackName: "marklessLoadLocalSymbol",
|
|
826
|
+
reboundName: "marklessLoadSymbolRebound",
|
|
827
|
+
exported: true
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
return [
|
|
831
|
+
armRendererModuleId ? [
|
|
832
|
+
`import { prepareBoundaryArm as marklessPrepareBoundaryArm, renderBoundaryArm as marklessRenderBoundaryArm } from ${JSON.stringify(armRendererModuleId)};`,
|
|
833
|
+
"export function prepareBoundaryArm(boundaryId, status, graph) {",
|
|
834
|
+
" return marklessPrepareBoundaryArm(boundaryId, status, graph, loadSymbol);",
|
|
835
|
+
"}",
|
|
836
|
+
"export function renderBoundaryArm(boundaryId, status, graph) {",
|
|
837
|
+
" return marklessRenderBoundaryArm(boundaryId, status, graph, loadSymbol);",
|
|
838
|
+
"}"
|
|
839
|
+
].join("\n") : "",
|
|
840
|
+
adaptImportedCaptureResolver(source, boundRows.some((row) => row.loaderSymbolId !== void 0)),
|
|
841
|
+
`export const groupId=${JSON.stringify(input.group.id)};`,
|
|
842
|
+
`export const state=${JSON.stringify(input.group.state)};`,
|
|
843
|
+
`export const view=${JSON.stringify(input.group.view)};`,
|
|
844
|
+
`export const graphNodeIds=${JSON.stringify(input.group.graphNodeIds)};`
|
|
845
|
+
].join("\n");
|
|
846
|
+
}
|
|
847
|
+
function emitPrerenderBoundaryRendererModule(renderDataId) {
|
|
848
|
+
return [
|
|
849
|
+
`import { marklessPrerenderData } from ${JSON.stringify(renderDataId)};`,
|
|
850
|
+
"import { renderPrerenderBoundary } from '@markless/web/fns/prerender-resume';",
|
|
851
|
+
"const marklessPreparedBoundaryArms = new WeakMap();",
|
|
852
|
+
"export async function prepareBoundaryArm(boundaryId, status, graph, loadSymbol) {",
|
|
853
|
+
" const rendered = await renderPrerenderBoundary(marklessPrerenderData, boundaryId, status, graph, loadSymbol);",
|
|
854
|
+
" if (!marklessPreparedBoundaryArms.has(graph)) marklessPreparedBoundaryArms.set(graph, new Map());",
|
|
855
|
+
" marklessPreparedBoundaryArms.get(graph).set(`${boundaryId}:${status}`, rendered);",
|
|
856
|
+
"}",
|
|
857
|
+
"export function renderBoundaryArm(boundaryId, status, graph) {",
|
|
858
|
+
" const key = `${boundaryId}:${status}`;",
|
|
859
|
+
" const prepared = marklessPreparedBoundaryArms.get(graph);",
|
|
860
|
+
" const rendered = prepared?.get(key);",
|
|
861
|
+
" if (!rendered) throw new Error(`Markless prerender arm ${key} was not prepared.`);",
|
|
862
|
+
" prepared.delete(key);",
|
|
863
|
+
" return rendered;",
|
|
864
|
+
"}"
|
|
865
|
+
].join("\n");
|
|
866
|
+
}
|
|
867
|
+
function symbolRouteImportSource(importSource) {
|
|
868
|
+
return importSource.includes("?") ? `${importSource}&markless-symbols` : `${importSource}?markless-symbols`;
|
|
869
|
+
}
|
|
870
|
+
function planPrerenderTriggerGroups(input) {
|
|
871
|
+
const symbols = new Map(input.symbolResolver.symbols.map((symbol) => [symbol.id, symbol]));
|
|
872
|
+
const bounds = new Map(input.boundRows.map((row) => [row.id, row]));
|
|
873
|
+
const completeView = input.completeView ?? input.view;
|
|
874
|
+
const completeBoundaries = new Map(completeView.asyncBoundaries.map((boundary) => [boundary.id, boundary]));
|
|
875
|
+
const selfWakeBoundaries = unsettledAsyncBoundaryIndexes(input.state, input.view);
|
|
876
|
+
const groups = [
|
|
877
|
+
...selfWakeBoundaries.length > 0 ? [{
|
|
878
|
+
event: {
|
|
879
|
+
hostNodeId: "self-wake",
|
|
880
|
+
eventName: "self-wake",
|
|
881
|
+
symbolIds: []
|
|
882
|
+
},
|
|
883
|
+
selfWakeBoundaries
|
|
884
|
+
}] : [],
|
|
885
|
+
...input.view.events.filter((event) => EVENT_STAGES_BROWSER_TRIGGER[protocolEventActionKind(event)]).map((event) => ({ event })),
|
|
886
|
+
...(input.view.branches ?? []).flatMap((branch, branchIndex) => {
|
|
887
|
+
const events = /* @__PURE__ */ new Map();
|
|
888
|
+
for (const arm of branch.armRecords ?? []) for (const event of arm.events) {
|
|
889
|
+
const key = `${event.eventName}:${event.hostPath.join(".")}`;
|
|
890
|
+
const route = events.get(key) ?? {
|
|
891
|
+
eventName: event.eventName,
|
|
892
|
+
hostPath: event.hostPath,
|
|
893
|
+
symbolIds: /* @__PURE__ */ new Set()
|
|
894
|
+
};
|
|
895
|
+
for (const symbolId of event.symbolIds ?? []) route.symbolIds.add(symbolId);
|
|
896
|
+
events.set(key, route);
|
|
897
|
+
}
|
|
898
|
+
return [...events.values()].map((route) => ({
|
|
899
|
+
event: {
|
|
900
|
+
hostNodeId: `branch:${branch.id}:${route.hostPath.join(".")}`,
|
|
901
|
+
eventName: route.eventName,
|
|
902
|
+
symbolIds: [...route.symbolIds]
|
|
903
|
+
},
|
|
904
|
+
branch,
|
|
905
|
+
branchIndex,
|
|
906
|
+
hostPath: route.hostPath
|
|
907
|
+
}));
|
|
908
|
+
})
|
|
909
|
+
].flatMap(({ event, branch, branchIndex, hostPath, selfWakeBoundaries }) => {
|
|
910
|
+
const closureView = selfWakeBoundaries ? completeView : input.view;
|
|
911
|
+
const host = branch ? void 0 : input.view.locators.find((locator) => locator.hostNodeId === event.hostNodeId);
|
|
912
|
+
if (!host && !branch && !selfWakeBoundaries) return [];
|
|
913
|
+
const compilerGroup = input.triggerGroups.groups.find((group) => group.hostNodeId === event.hostNodeId && group.eventName === event.eventName);
|
|
914
|
+
const graphNodeIds = /* @__PURE__ */ new Set();
|
|
915
|
+
const symbolIds = new Set(event.symbolIds ?? []);
|
|
916
|
+
const selected = {
|
|
917
|
+
domUpdates: /* @__PURE__ */ new Set(),
|
|
918
|
+
behaviors: /* @__PURE__ */ new Set(),
|
|
919
|
+
branches: /* @__PURE__ */ new Set(),
|
|
920
|
+
boundaries: /* @__PURE__ */ new Set(),
|
|
921
|
+
repeats: /* @__PURE__ */ new Set(),
|
|
922
|
+
elementHandles: /* @__PURE__ */ new Set()
|
|
923
|
+
};
|
|
924
|
+
if (branch && branchIndex !== void 0) {
|
|
925
|
+
selected.branches.add(branchIndex);
|
|
926
|
+
if (branch.symbolId) symbolIds.add(branch.symbolId);
|
|
927
|
+
for (const read of branch.testReads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
928
|
+
for (const arm of branch.armRecords ?? []) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
929
|
+
}
|
|
930
|
+
const adoptedBoundaryIds = /* @__PURE__ */ new Set();
|
|
931
|
+
const escalatedHostNodeIds = /* @__PURE__ */ new Set();
|
|
932
|
+
for (const boundaryIndex of selfWakeBoundaries ?? []) {
|
|
933
|
+
const servedBoundary = input.view.asyncBoundaries[boundaryIndex];
|
|
934
|
+
selected.boundaries.add(boundaryIndex);
|
|
935
|
+
collectSettledBoundaryClosure(input, completeBoundaries.get(servedBoundary.id) ?? servedBoundary, graphNodeIds, symbolIds);
|
|
936
|
+
}
|
|
937
|
+
closureView.behaviors.forEach((behavior, index) => {
|
|
938
|
+
if (selfWakeBoundaries) return;
|
|
939
|
+
const recordId = `behavior:${behavior.hostNodeId}:${behavior.symbolId ?? ""}`;
|
|
940
|
+
if ((behavior.inputGraphReads?.length ?? 0) > 0 && !compilerGroup?.payloadRecordIds.includes(recordId)) return;
|
|
941
|
+
selected.behaviors.add(index);
|
|
942
|
+
if (behavior.symbolId) symbolIds.add(behavior.symbolId);
|
|
943
|
+
});
|
|
944
|
+
let changed = true;
|
|
945
|
+
while (changed) {
|
|
946
|
+
const before = closureSize(graphNodeIds, symbolIds, selected);
|
|
947
|
+
const currentSymbolIds = Array.from(symbolIds);
|
|
948
|
+
for (const symbolId of currentSymbolIds) {
|
|
949
|
+
const bound = bounds.get(symbolId);
|
|
950
|
+
if (bound) {
|
|
951
|
+
symbolIds.add(bound.loaderSymbolId ?? bound.baseSymbolId);
|
|
952
|
+
for (const slot of bound.captureSlots) {
|
|
953
|
+
if (slot.route.kind === "graph-reference") graphNodeIds.add(slot.route.graphNodeId);
|
|
954
|
+
if (slot.route.kind === "callback-route") symbolIds.add(slot.route.callbackSymbolId);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
const symbol = symbols.get(symbolId);
|
|
958
|
+
if (!symbol) continue;
|
|
959
|
+
if ("reads" in symbol) for (const read of symbol.reads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
960
|
+
if ("writes" in symbol) for (const write of symbol.writes ?? []) graphNodeIds.add(write.graphNodeId);
|
|
961
|
+
if (symbol.kind === "async-computed-runner" || symbol.kind === "sync-computed-derive") {
|
|
962
|
+
graphNodeIds.add(symbol.graphNodeId);
|
|
963
|
+
for (const dependency of symbol.dependencies ?? []) graphNodeIds.add(dependency.graphNodeId);
|
|
964
|
+
}
|
|
965
|
+
if ("elementHandleCalls" in symbol) for (const call of symbol.elementHandleCalls ?? []) closureView.elementHandles.forEach((handle, index) => {
|
|
966
|
+
if (handle.name === call.handleName) selected.elementHandles.add(index);
|
|
967
|
+
});
|
|
968
|
+
if ("elementHandleReads" in symbol) for (const read of symbol.elementHandleReads ?? []) closureView.elementHandles.forEach((handle, index) => {
|
|
969
|
+
if (handle.handleId === read.handleId || handle.name === read.handleName) selected.elementHandles.add(index);
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
closeComputedGraph(graphNodeIds, input.state);
|
|
973
|
+
for (const computed of input.state.computed) if (computed.deriveSymbolId && graphNodeIds.has(computed.graphNodeId)) symbolIds.add(computed.deriveSymbolId);
|
|
974
|
+
for (const graphNodeId of graphNodeIds) {
|
|
975
|
+
const runnerSymbolId = closureView.asyncRunners?.[graphNodeId];
|
|
976
|
+
if (runnerSymbolId) symbolIds.add(runnerSymbolId);
|
|
977
|
+
}
|
|
978
|
+
selectViewSubscribers(closureView, graphNodeIds, symbolIds, selected);
|
|
979
|
+
const escalatedBranchIds = /* @__PURE__ */ new Set();
|
|
980
|
+
for (const index of selected.branches) {
|
|
981
|
+
const record = closureView.branches?.[index];
|
|
982
|
+
if (record?.escalates) escalatedBranchIds.add(record.id);
|
|
983
|
+
}
|
|
984
|
+
for (const index of selected.boundaries) {
|
|
985
|
+
const served = closureView.asyncBoundaries[index];
|
|
986
|
+
for (const arm of boundaryArmRecordSets(completeBoundaries.get(served.id) ?? served)) collectEscalatedArmBranchIds(arm, escalatedBranchIds);
|
|
987
|
+
}
|
|
988
|
+
for (const branchId of escalatedBranchIds) collectEscalatedBranchClosure(input, branchId, graphNodeIds, symbolIds, escalatedHostNodeIds);
|
|
989
|
+
if (!selfWakeBoundaries) input.view.asyncBoundaries.forEach((servedBoundary, index) => {
|
|
990
|
+
if (adoptedBoundaryIds.has(servedBoundary.id)) return;
|
|
991
|
+
const boundary = completeBoundaries.get(servedBoundary.id) ?? servedBoundary;
|
|
992
|
+
if (!settledArmReadGraphNodeIds(input, boundary).some((graphNodeId) => graphNodeIds.has(graphNodeId))) return;
|
|
993
|
+
adoptedBoundaryIds.add(servedBoundary.id);
|
|
994
|
+
selected.boundaries.add(index);
|
|
995
|
+
collectSettledBoundaryClosure(input, boundary, graphNodeIds, symbolIds);
|
|
996
|
+
collectSettledArmHostRecordClosure(completeView, boundary, graphNodeIds, symbolIds);
|
|
997
|
+
});
|
|
998
|
+
if (selfWakeBoundaries || adoptedBoundaryIds.size > 0) {
|
|
999
|
+
for (const symbol of symbols.values()) if (symbol.kind === "state-initializer" && graphNodeIds.has(symbol.graphNodeId)) symbolIds.add(symbol.id);
|
|
1000
|
+
}
|
|
1001
|
+
changed = closureSize(graphNodeIds, symbolIds, selected) !== before;
|
|
1002
|
+
}
|
|
1003
|
+
dropEscalatedHostRecords(closureView, selected, escalatedHostNodeIds);
|
|
1004
|
+
const neededHosts = new Set(branch ? [] : [event.hostNodeId]);
|
|
1005
|
+
for (const index of selected.domUpdates) neededHosts.add(closureView.domUpdates[index].hostNodeId);
|
|
1006
|
+
for (const index of selected.behaviors) neededHosts.add(closureView.behaviors[index].hostNodeId);
|
|
1007
|
+
for (const index of selected.repeats) neededHosts.add(closureView.keyedRepeats[index].parentHostNodeId);
|
|
1008
|
+
for (const index of selected.elementHandles) neededHosts.add(closureView.elementHandles[index].hostNodeId);
|
|
1009
|
+
const selectedBoundaryIds = new Set([...selected.boundaries].map((index) => closureView.asyncBoundaries[index].id));
|
|
1010
|
+
const view = {
|
|
1011
|
+
...input.view,
|
|
1012
|
+
locators: closureView.locators.filter((locator) => neededHosts.has(locator.hostNodeId)),
|
|
1013
|
+
events: branch || selfWakeBoundaries ? [] : [event],
|
|
1014
|
+
domUpdates: closureView.domUpdates.filter((_, index) => selected.domUpdates.has(index)),
|
|
1015
|
+
behaviors: closureView.behaviors.filter((_, index) => selected.behaviors.has(index)),
|
|
1016
|
+
elementHandles: closureView.elementHandles.filter((_, index) => selected.elementHandles.has(index)),
|
|
1017
|
+
keyedRepeats: closureView.keyedRepeats?.filter((_, index) => selected.repeats.has(index)),
|
|
1018
|
+
branches: closureView.branches?.filter((_, index) => selected.branches.has(index)),
|
|
1019
|
+
asyncBoundaries: closureView.asyncBoundaries.filter((boundary) => selectedBoundaryIds.has(boundary.id)).map((boundary) => adoptedBoundaryIds.has(boundary.id) ? completeBoundaries.get(boundary.id) ?? boundary : boundary),
|
|
1020
|
+
...closureView.asyncRunners ? { asyncRunners: Object.fromEntries(Object.entries(closureView.asyncRunners).filter(([graphNodeId]) => graphNodeIds.has(graphNodeId))) } : {}
|
|
1021
|
+
};
|
|
1022
|
+
const graphIds = [...graphNodeIds].sort();
|
|
1023
|
+
return [{
|
|
1024
|
+
id: selfWakeBoundaries ? "self-wake" : branch ? `branch:${branch.id}:${event.eventName}:${hostPath.join(".")}` : `${event.hostNodeId}:${event.eventName}`,
|
|
1025
|
+
hostNodeId: event.hostNodeId,
|
|
1026
|
+
eventName: event.eventName,
|
|
1027
|
+
hostIndex: host?.index ?? -1,
|
|
1028
|
+
hostTagName: host?.tagName ?? "*",
|
|
1029
|
+
...branch ? {
|
|
1030
|
+
branchStartIndex: branch.startAnchor.index,
|
|
1031
|
+
branchEndIndex: branch.endAnchor.index,
|
|
1032
|
+
hostPath
|
|
1033
|
+
} : {},
|
|
1034
|
+
graphNodeIds: graphIds,
|
|
1035
|
+
symbolIds: [...symbolIds].sort(),
|
|
1036
|
+
state: filterState(input.state, new Set(graphIds)),
|
|
1037
|
+
view,
|
|
1038
|
+
...adoptedBoundaryIds.size > 0 ? { adoptsSettledArm: true } : {}
|
|
1039
|
+
}];
|
|
1040
|
+
});
|
|
1041
|
+
const armRendererModuleId = groups.some((group) => group.id === "self-wake") ? triggerGroupVirtualModuleId(input.filename, groups.length) : void 0;
|
|
1042
|
+
return groups.map(({ adoptsSettledArm, ...group }) => adoptsSettledArm && armRendererModuleId ? {
|
|
1043
|
+
...group,
|
|
1044
|
+
armRendererModuleId
|
|
1045
|
+
} : group);
|
|
1046
|
+
}
|
|
1047
|
+
function settledArmReadGraphNodeIds(input, boundary) {
|
|
1048
|
+
const graphNodeIds = /* @__PURE__ */ new Set();
|
|
1049
|
+
for (const arm of boundaryArmRecordSets(boundary)) collectCompleteArmRecordClosure(arm, graphNodeIds, /* @__PURE__ */ new Set());
|
|
1050
|
+
for (const edge of input.componentEdges ?? []) if (edge.asyncBoundaryId === boundary.id) {
|
|
1051
|
+
for (const prop of edge.props) if (prop.kind === "graph-reference") graphNodeIds.add(prop.graphNodeId);
|
|
1052
|
+
}
|
|
1053
|
+
return [...graphNodeIds];
|
|
1054
|
+
}
|
|
1055
|
+
function collectSettledBoundaryClosure(input, boundary, graphNodeIds, symbolIds) {
|
|
1056
|
+
if (boundary.updateSymbolId) symbolIds.add(boundary.updateSymbolId);
|
|
1057
|
+
for (const read of boundary.asyncReads) {
|
|
1058
|
+
graphNodeIds.add(read.graphNodeId);
|
|
1059
|
+
if (read.runnerSymbolId) symbolIds.add(read.runnerSymbolId);
|
|
1060
|
+
}
|
|
1061
|
+
for (const arm of boundaryArmRecordSets(boundary)) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1062
|
+
const settledEdgeIds = /* @__PURE__ */ new Set();
|
|
1063
|
+
for (const edge of input.componentEdges ?? []) {
|
|
1064
|
+
if (edge.asyncBoundaryId !== boundary.id) continue;
|
|
1065
|
+
settledEdgeIds.add(edge.id);
|
|
1066
|
+
for (const prop of edge.props) if (prop.kind === "graph-reference") graphNodeIds.add(prop.graphNodeId);
|
|
1067
|
+
}
|
|
1068
|
+
for (const row of input.boundRows) if (row.componentEdgePath.some((edgeId) => settledEdgeIds.has(edgeId))) symbolIds.add(row.id);
|
|
1069
|
+
}
|
|
1070
|
+
function collectSettledArmHostRecordClosure(completeView, boundary, graphNodeIds, symbolIds) {
|
|
1071
|
+
const armHosts = /* @__PURE__ */ new Set();
|
|
1072
|
+
for (const arm of boundaryArmRecordSets(boundary)) for (const locator of arm.locators ?? []) armHosts.add(locator.hostNodeId);
|
|
1073
|
+
if (armHosts.size === 0) return;
|
|
1074
|
+
for (const record of completeView.events) if (armHosts.has(record.hostNodeId)) for (const symbolId of record.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1075
|
+
for (const record of completeView.domUpdates) if (armHosts.has(record.hostNodeId)) {
|
|
1076
|
+
graphNodeIds.add(record.graphNodeId);
|
|
1077
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1078
|
+
}
|
|
1079
|
+
for (const record of completeView.behaviors) if (armHosts.has(record.hostNodeId)) {
|
|
1080
|
+
for (const read of record.inputGraphReads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
1081
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1082
|
+
}
|
|
1083
|
+
for (const record of completeView.keyedRepeats ?? []) if (armHosts.has(record.parentHostNodeId)) {
|
|
1084
|
+
if (record.collectionGraphNodeId) graphNodeIds.add(record.collectionGraphNodeId);
|
|
1085
|
+
for (const rowEvent of record.rowEvents) for (const symbolId of rowEvent.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
function dropEscalatedHostRecords(view, selected, hostNodeIds) {
|
|
1089
|
+
if (hostNodeIds.size === 0) return;
|
|
1090
|
+
const drop = (indexes, hostOf) => {
|
|
1091
|
+
for (const index of indexes) if (hostNodeIds.has(hostOf(index) ?? "")) indexes.delete(index);
|
|
1092
|
+
};
|
|
1093
|
+
drop(selected.domUpdates, (index) => view.domUpdates[index]?.hostNodeId);
|
|
1094
|
+
drop(selected.behaviors, (index) => view.behaviors[index]?.hostNodeId);
|
|
1095
|
+
drop(selected.elementHandles, (index) => view.elementHandles[index]?.hostNodeId);
|
|
1096
|
+
drop(selected.repeats, (index) => view.keyedRepeats?.[index]?.parentHostNodeId);
|
|
1097
|
+
}
|
|
1098
|
+
function collectEscalatedArmBranchIds(arm, branchIds) {
|
|
1099
|
+
for (const branch of arm.branches ?? []) {
|
|
1100
|
+
if (!branch.symbolId && (branch.testReads?.length ?? 0) > 0) branchIds.add(branch.id);
|
|
1101
|
+
for (const nested of branch.armRecords ?? []) collectEscalatedArmBranchIds(nested, branchIds);
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
function collectEscalatedBranchClosure(input, branchSiteId, graphNodeIds, symbolIds, hostNodeIds) {
|
|
1105
|
+
const renderData = input.renderData;
|
|
1106
|
+
const branch = renderData?.branches.find((candidate) => candidate.branchSiteId === branchSiteId);
|
|
1107
|
+
if (!renderData || !branch) return;
|
|
1108
|
+
const chunks = new Map(renderData.chunks.map((chunk) => [chunk.id, chunk]));
|
|
1109
|
+
const edgeIds = /* @__PURE__ */ new Set();
|
|
1110
|
+
const walked = /* @__PURE__ */ new Set();
|
|
1111
|
+
const walk = (chunkId) => {
|
|
1112
|
+
if (!chunkId || walked.has(chunkId)) return;
|
|
1113
|
+
walked.add(chunkId);
|
|
1114
|
+
const chunk = chunks.get(chunkId);
|
|
1115
|
+
if (!chunk) return;
|
|
1116
|
+
for (const host of chunk.hosts) hostNodeIds.add(host.hostNodeId);
|
|
1117
|
+
for (const slot of chunk.slots) if (slot.kind === "child-component") {
|
|
1118
|
+
edgeIds.add(slot.componentEdgeId);
|
|
1119
|
+
walk(slot.childTemplateId);
|
|
1120
|
+
walk(slot.projectionChunkId);
|
|
1121
|
+
} else if (slot.kind === "branch") for (const armId of slot.armTemplateIds) walk(armId);
|
|
1122
|
+
else if (slot.kind === "repeat") {
|
|
1123
|
+
walk(slot.rowTemplateId);
|
|
1124
|
+
walk(slot.emptyTemplateId);
|
|
1125
|
+
} else if (slot.kind === "async") {
|
|
1126
|
+
walk(slot.armTemplateIds.try);
|
|
1127
|
+
walk(slot.armTemplateIds.pending);
|
|
1128
|
+
walk(slot.armTemplateIds.catch);
|
|
1129
|
+
} else if (slot.kind === "dynamic-host") walk(slot.childChunkId);
|
|
1130
|
+
else if ("residue" in slot && slot.residue.kind === "graph-read") graphNodeIds.add(slot.residue.graphNodeId);
|
|
1131
|
+
};
|
|
1132
|
+
for (const armId of branch.armChunkIds) walk(armId);
|
|
1133
|
+
for (const symbol of input.symbolResolver.symbols) if (symbol.kind === "dom-update" && hostNodeIds.has(symbol.hostNodeId)) graphNodeIds.add(symbol.graphNodeId);
|
|
1134
|
+
for (const symbol of input.symbolResolver.symbols) if ("hostNodeId" in symbol && hostNodeIds.has(symbol.hostNodeId) || symbol.kind === "callback-prop" && edgeIds.has(symbol.componentEdgeId) || (symbol.kind === "state-initializer" || symbol.kind === "sync-computed-derive" || symbol.kind === "async-computed-runner") && graphNodeIds.has(symbol.graphNodeId)) symbolIds.add(symbol.id);
|
|
1135
|
+
for (const row of input.boundRows) if (row.componentEdgePath.some((edgeId) => edgeIds.has(edgeId))) symbolIds.add(row.id);
|
|
1136
|
+
}
|
|
1137
|
+
function boundaryArmRecordSets(boundary) {
|
|
1138
|
+
return Array.isArray(boundary.armRecords) ? boundary.armRecords : boundary.armRecords ? [boundary.armRecords] : [];
|
|
1139
|
+
}
|
|
1140
|
+
function unsettledAsyncBoundaryIndexes(state, view) {
|
|
1141
|
+
const computed = new Map(state.computed.map((record) => [record.graphNodeId, record]));
|
|
1142
|
+
const runners = { ...view.asyncRunners };
|
|
1143
|
+
for (const boundary of view.asyncBoundaries) for (const read of boundary.asyncReads) if (read.runnerSymbolId) runners[read.graphNodeId] ??= read.runnerSymbolId;
|
|
1144
|
+
return view.asyncBoundaries.flatMap((boundary, index) => {
|
|
1145
|
+
const reachable = new Set(boundary.asyncReads.map((read) => read.graphNodeId));
|
|
1146
|
+
for (const graphNodeId of reachable) {
|
|
1147
|
+
const record = computed.get(graphNodeId);
|
|
1148
|
+
if (!record) continue;
|
|
1149
|
+
if (runners[graphNodeId] && record.snapshot?.status !== "fulfilled" && record.snapshot?.status !== "rejected") return [index];
|
|
1150
|
+
for (const dependency of record.dependencies ?? []) reachable.add(dependency.graphNodeId);
|
|
1151
|
+
}
|
|
1152
|
+
return [];
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
function selectViewSubscribers(view, graphNodeIds, symbolIds, selected) {
|
|
1156
|
+
view.domUpdates.forEach((record, index) => {
|
|
1157
|
+
if (!graphNodeIds.has(record.graphNodeId)) return;
|
|
1158
|
+
selected.domUpdates.add(index);
|
|
1159
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1160
|
+
});
|
|
1161
|
+
view.behaviors.forEach((record, index) => {
|
|
1162
|
+
if (!(record.inputGraphReads ?? []).some((read) => graphNodeIds.has(read.graphNodeId))) return;
|
|
1163
|
+
selected.behaviors.add(index);
|
|
1164
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1165
|
+
});
|
|
1166
|
+
(view.branches ?? []).forEach((record, index) => {
|
|
1167
|
+
if (!(record.testReads ?? []).some((read) => graphNodeIds.has(read.graphNodeId))) return;
|
|
1168
|
+
selected.branches.add(index);
|
|
1169
|
+
if (record.symbolId) symbolIds.add(record.symbolId);
|
|
1170
|
+
for (const arm of record.armRecords ?? []) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1171
|
+
});
|
|
1172
|
+
view.asyncBoundaries.forEach((record, index) => {
|
|
1173
|
+
if (!record.asyncReads.some((read) => graphNodeIds.has(read.graphNodeId))) return;
|
|
1174
|
+
selected.boundaries.add(index);
|
|
1175
|
+
if (record.updateSymbolId) symbolIds.add(record.updateSymbolId);
|
|
1176
|
+
for (const read of record.asyncReads) if (read.runnerSymbolId) symbolIds.add(read.runnerSymbolId);
|
|
1177
|
+
const arms = Array.isArray(record.armRecords) ? record.armRecords : record.armRecords ? [record.armRecords] : [];
|
|
1178
|
+
for (const arm of arms) collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds);
|
|
1179
|
+
});
|
|
1180
|
+
(view.keyedRepeats ?? []).forEach((record, index) => {
|
|
1181
|
+
if (!record.collectionGraphNodeId || !graphNodeIds.has(record.collectionGraphNodeId)) return;
|
|
1182
|
+
selected.repeats.add(index);
|
|
1183
|
+
for (const rowEvent of record.rowEvents) for (const symbolId of rowEvent.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
function collectCompleteArmRecordClosure(arm, graphNodeIds, symbolIds) {
|
|
1187
|
+
for (const event of arm.events ?? []) for (const symbolId of event.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1188
|
+
for (const update of arm.domUpdates ?? []) {
|
|
1189
|
+
if (typeof update.graphNodeId === "string") graphNodeIds.add(update.graphNodeId);
|
|
1190
|
+
if (typeof update.symbolId === "string") symbolIds.add(update.symbolId);
|
|
1191
|
+
}
|
|
1192
|
+
for (const behavior of arm.behaviors ?? []) {
|
|
1193
|
+
for (const read of behavior.inputGraphReads ?? []) if (typeof read.graphNodeId === "string") graphNodeIds.add(read.graphNodeId);
|
|
1194
|
+
if (typeof behavior.symbolId === "string") symbolIds.add(behavior.symbolId);
|
|
1195
|
+
}
|
|
1196
|
+
for (const repeat of arm.keyedRepeats ?? []) {
|
|
1197
|
+
if (repeat.collectionGraphNodeId) graphNodeIds.add(repeat.collectionGraphNodeId);
|
|
1198
|
+
for (const event of repeat.rowEvents) for (const symbolId of event.symbolIds ?? []) symbolIds.add(symbolId);
|
|
1199
|
+
}
|
|
1200
|
+
for (const branch of arm.branches ?? []) {
|
|
1201
|
+
if (branch.symbolId) symbolIds.add(branch.symbolId);
|
|
1202
|
+
for (const read of branch.testReads ?? []) graphNodeIds.add(read.graphNodeId);
|
|
1203
|
+
for (const nested of branch.armRecords ?? []) collectCompleteArmRecordClosure(nested, graphNodeIds, symbolIds);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
function closeComputedGraph(graphNodeIds, state) {
|
|
1207
|
+
let changed = true;
|
|
1208
|
+
while (changed) {
|
|
1209
|
+
changed = false;
|
|
1210
|
+
for (const computed of state.computed) {
|
|
1211
|
+
const dependencies = computed.dependencies ?? [];
|
|
1212
|
+
if (!graphNodeIds.has(computed.graphNodeId) && !dependencies.some((dependency) => graphNodeIds.has(dependency.graphNodeId))) continue;
|
|
1213
|
+
if (!graphNodeIds.has(computed.graphNodeId)) {
|
|
1214
|
+
graphNodeIds.add(computed.graphNodeId);
|
|
1215
|
+
changed = true;
|
|
1216
|
+
}
|
|
1217
|
+
for (const dependency of dependencies) if (!graphNodeIds.has(dependency.graphNodeId)) {
|
|
1218
|
+
graphNodeIds.add(dependency.graphNodeId);
|
|
1219
|
+
changed = true;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function filterState(state, graphNodeIds) {
|
|
1225
|
+
return {
|
|
1226
|
+
...state,
|
|
1227
|
+
cells: state.cells.filter((cell) => graphNodeIds.has(cell.graphNodeId)),
|
|
1228
|
+
computed: state.computed.filter((computed) => graphNodeIds.has(computed.graphNodeId)),
|
|
1229
|
+
storage: state.storage?.filter((cell) => graphNodeIds.has(cell.graphNodeId)),
|
|
1230
|
+
sharedDefinitions: state.sharedDefinitions?.filter((definition) => definition.graphNodeIds.some((graphNodeId) => graphNodeIds.has(graphNodeId)))
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
function closureSize(graphNodeIds, symbolIds, selected) {
|
|
1234
|
+
return graphNodeIds.size + symbolIds.size + Object.values(selected).reduce((total, records) => total + records.size, 0);
|
|
1235
|
+
}
|
|
1236
|
+
//#endregion
|
|
1237
|
+
//#region src/build/symbol-bundles.ts
|
|
1238
|
+
const SYMBOL_BUNDLE_VIRTUAL_PREFIX = `${MARKLESS_VIRTUAL_PREFIX}symbol-bundle:`;
|
|
1239
|
+
function symbolBundleVirtualModuleId(filename, index) {
|
|
1240
|
+
return `${SYMBOL_BUNDLE_VIRTUAL_PREFIX}${encodeURIComponent(filename)}:${index}`;
|
|
1241
|
+
}
|
|
1242
|
+
function emitSymbolBundleModule(symbolModuleIds) {
|
|
1243
|
+
return `${symbolModuleIds.map((id) => `export * from ${JSON.stringify(id)};`).join("\n")}\n`;
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1246
|
+
* Partitions this module's symbol chunks by the set of interactions that wake
|
|
1247
|
+
* them. A partition of one stays on its own module id: bundling it would only
|
|
1248
|
+
* add a re-export hop.
|
|
1249
|
+
*
|
|
1250
|
+
* The interaction list is one module's local view, so it cannot name a symbol
|
|
1251
|
+
* another module's host node wakes (a callback prop) or one that several writes
|
|
1252
|
+
* wake (a dom update). Unnamed means the owning set is unknown, never that it is
|
|
1253
|
+
* empty, so unnamed symbols stay on their own chunks.
|
|
1254
|
+
*/
|
|
1255
|
+
function planSymbolBundles(input) {
|
|
1256
|
+
if (input.symbols.length < 2) return [];
|
|
1257
|
+
const owners = /* @__PURE__ */ new Map();
|
|
1258
|
+
for (const interaction of input.interactions) for (const symbolId of interaction.symbolIds) {
|
|
1259
|
+
const current = owners.get(symbolId);
|
|
1260
|
+
if (current) current.push(interaction.id);
|
|
1261
|
+
else owners.set(symbolId, [interaction.id]);
|
|
1262
|
+
}
|
|
1263
|
+
const partitions = /* @__PURE__ */ new Map();
|
|
1264
|
+
for (const symbol of input.symbols) {
|
|
1265
|
+
const claimed = owners.get(symbol.symbolId);
|
|
1266
|
+
if (!claimed) continue;
|
|
1267
|
+
const key = [...new Set(claimed)].sort().join(" ");
|
|
1268
|
+
const current = partitions.get(key);
|
|
1269
|
+
if (current) current.push(symbol.moduleId);
|
|
1270
|
+
else partitions.set(key, [symbol.moduleId]);
|
|
1271
|
+
}
|
|
1272
|
+
return [...partitions.entries()].filter(([, moduleIds]) => moduleIds.length > 1).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, moduleIds], index) => ({
|
|
1273
|
+
key,
|
|
1274
|
+
id: symbolBundleVirtualModuleId(input.filename, index),
|
|
1275
|
+
symbolModuleIds: [...moduleIds].sort()
|
|
1276
|
+
}));
|
|
1277
|
+
}
|
|
1278
|
+
//#endregion
|
|
1279
|
+
//#region src/transform.ts
|
|
1280
|
+
const STRIPPED_CODE_LIMIT = 4096;
|
|
1281
|
+
const strippedCode = /* @__PURE__ */ new Map();
|
|
1282
|
+
let persistentStrippedCode;
|
|
1283
|
+
function usePersistentStrippedCode(memo) {
|
|
1284
|
+
persistentStrippedCode = memo;
|
|
1285
|
+
}
|
|
1286
|
+
async function stripEmittedTypes(code, moduleId, onlyRemoveTypeImports = false) {
|
|
1287
|
+
const key = `${onlyRemoveTypeImports ? 1 : 0}${code}`;
|
|
1288
|
+
const cached = strippedCode.get(key) ?? persistentStrippedCode?.get(key);
|
|
1289
|
+
if (cached !== void 0) {
|
|
1290
|
+
strippedCode.delete(key);
|
|
1291
|
+
strippedCode.set(key, cached);
|
|
1292
|
+
return cached;
|
|
1293
|
+
}
|
|
1294
|
+
const stripped = await stripEmittedTypesUncached(code, moduleId, onlyRemoveTypeImports);
|
|
1295
|
+
persistentStrippedCode?.set(key, stripped);
|
|
1296
|
+
strippedCode.set(key, stripped);
|
|
1297
|
+
if (strippedCode.size > STRIPPED_CODE_LIMIT) {
|
|
1298
|
+
const oldest = strippedCode.keys().next();
|
|
1299
|
+
if (!oldest.done) strippedCode.delete(oldest.value);
|
|
1300
|
+
}
|
|
1301
|
+
return stripped;
|
|
1302
|
+
}
|
|
1303
|
+
async function stripEmittedTypesUncached(code, moduleId, onlyRemoveTypeImports) {
|
|
1304
|
+
let out;
|
|
1305
|
+
try {
|
|
1306
|
+
out = transformSync("markless-emitted.ts", code, onlyRemoveTypeImports ? { typescript: { onlyRemoveTypeImports: true } } : void 0);
|
|
1307
|
+
} catch (error) {
|
|
1308
|
+
throw typeStripError(moduleId, error instanceof Error ? error.message : String(error));
|
|
1309
|
+
}
|
|
1310
|
+
const errors = out.errors ?? [];
|
|
1311
|
+
if (errors.length > 0 || !out.code) throw typeStripError(moduleId, errors.map((error) => error.message).join("; ") || "oxc produced no output.");
|
|
1312
|
+
return out.code;
|
|
1313
|
+
}
|
|
1314
|
+
async function stripEmittedTypesFromFragment(code, moduleId, onlyRemoveTypeImports = false) {
|
|
1315
|
+
if (!await fragmentCarriesTypeScript(code)) return code;
|
|
1316
|
+
return (await stripEmittedTypes(code, moduleId, onlyRemoveTypeImports)).trim();
|
|
1317
|
+
}
|
|
1318
|
+
async function stripEmittedTypesFromExpression(source, moduleId) {
|
|
1319
|
+
const stripped = await stripEmittedTypesFromFragment(source, moduleId);
|
|
1320
|
+
return stripped.endsWith(";") ? stripped.slice(0, -1).trimEnd() : stripped;
|
|
1321
|
+
}
|
|
1322
|
+
const fragmentVerdicts = /* @__PURE__ */ new Map();
|
|
1323
|
+
const FRAGMENT_VERDICT_LIMIT = 4096;
|
|
1324
|
+
async function fragmentCarriesTypeScript(code) {
|
|
1325
|
+
const known = fragmentVerdicts.get(code);
|
|
1326
|
+
if (known !== void 0) return known;
|
|
1327
|
+
const stored = persistentStrippedCode?.get(`t${code}`);
|
|
1328
|
+
const verdict = stored === void 0 ? await fragmentCarriesTypeScriptUncached(code) : stored === "true";
|
|
1329
|
+
if (stored === void 0) persistentStrippedCode?.set(`t${code}`, String(verdict));
|
|
1330
|
+
if (fragmentVerdicts.size >= FRAGMENT_VERDICT_LIMIT) fragmentVerdicts.delete(fragmentVerdicts.keys().next().value);
|
|
1331
|
+
fragmentVerdicts.set(code, verdict);
|
|
1332
|
+
return verdict;
|
|
1333
|
+
}
|
|
1334
|
+
async function fragmentCarriesTypeScriptUncached(code) {
|
|
1335
|
+
try {
|
|
1336
|
+
const parsed = parseSync("markless-emitted.ts", code, { lang: "ts" });
|
|
1337
|
+
if ((parsed.errors?.length ?? 0) > 0) return true;
|
|
1338
|
+
return carriesTypeScript(parsed.program);
|
|
1339
|
+
} catch {
|
|
1340
|
+
return true;
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
const TYPESCRIPT_FLAGS = [
|
|
1344
|
+
"declare",
|
|
1345
|
+
"abstract",
|
|
1346
|
+
"definite",
|
|
1347
|
+
"override",
|
|
1348
|
+
"accessibility"
|
|
1349
|
+
];
|
|
1350
|
+
function carriesTypeScript(node) {
|
|
1351
|
+
if (!node || typeof node !== "object") return false;
|
|
1352
|
+
if (Array.isArray(node)) return node.some((child) => carriesTypeScript(child));
|
|
1353
|
+
const record = node;
|
|
1354
|
+
if (typeof record.type === "string" && record.type.startsWith("TS")) return true;
|
|
1355
|
+
if (record.importKind === "type" || record.exportKind === "type") return true;
|
|
1356
|
+
if (TYPESCRIPT_FLAGS.some((flag) => record[flag])) return true;
|
|
1357
|
+
if (record.readonly === true) return true;
|
|
1358
|
+
if (Array.isArray(record.implements) && record.implements.length > 0) return true;
|
|
1359
|
+
for (const [key, value] of Object.entries(record)) {
|
|
1360
|
+
if (key === "type" || key === "loc" || key === "range" || key === "parent") continue;
|
|
1361
|
+
if (carriesTypeScript(value)) return true;
|
|
1362
|
+
}
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1365
|
+
function typeStripError(moduleId, message) {
|
|
1366
|
+
return new MarklessCompileError(createCompileErrorPayload({
|
|
1367
|
+
filename: moduleId,
|
|
1368
|
+
source: "",
|
|
1369
|
+
diagnostics: [],
|
|
1370
|
+
details: `MARKLESS_TYPE_STRIP_FAILED: ${moduleId} could not have its TypeScript syntax stripped. ${message}`
|
|
1371
|
+
}));
|
|
1372
|
+
}
|
|
1373
|
+
async function transformTsrxModule(input) {
|
|
1374
|
+
return transformTsrxModuleWithPrerenderWakeClosure(input, false);
|
|
1375
|
+
}
|
|
1376
|
+
function servedRenderDataId(encodedModuleId) {
|
|
1377
|
+
return `${MARKLESS_VIRTUAL_PREFIX}render-data-served:${encodedModuleId}`;
|
|
1378
|
+
}
|
|
1379
|
+
function servedRenderDataEntryId(encodedModuleId) {
|
|
1380
|
+
return `${MARKLESS_VIRTUAL_PREFIX}render-data-served-entry:${encodedModuleId}`;
|
|
1381
|
+
}
|
|
1382
|
+
function clientRenderDataEntryId(encodedModuleId) {
|
|
1383
|
+
return `${MARKLESS_VIRTUAL_PREFIX}${CLIENT_RENDER_DATA_ENTRY_KIND}:${encodedModuleId}`;
|
|
1384
|
+
}
|
|
1385
|
+
const CLIENT_RENDER_DATA_ENTRY_KIND = "render-data-csr-entry";
|
|
1386
|
+
function servedRenderDataReference(reference) {
|
|
1387
|
+
const canonical = `${MARKLESS_VIRTUAL_PREFIX}render-data:`;
|
|
1388
|
+
return reference.startsWith(canonical) ? servedRenderDataId(reference.slice(canonical.length)) : servedRenderDataSourceReference(reference);
|
|
1389
|
+
}
|
|
1390
|
+
function marklessVirtualModuleSourceFile(moduleId, root) {
|
|
1391
|
+
const bare = moduleId.startsWith("\0") ? moduleId.slice(1) : moduleId;
|
|
1392
|
+
if (!bare.startsWith("virtual:markless:")) return null;
|
|
1393
|
+
const rest = bare.slice(MARKLESS_VIRTUAL_PREFIX.length);
|
|
1394
|
+
const kindEnd = rest.indexOf(":");
|
|
1395
|
+
if (kindEnd <= 0) return null;
|
|
1396
|
+
const encoded = rest.slice(kindEnd + 1).split(":")[0].replace(/\.css$/, "");
|
|
1397
|
+
if (!encoded) return null;
|
|
1398
|
+
try {
|
|
1399
|
+
return sourceForModuleId(decodeURIComponent(encoded), root);
|
|
1400
|
+
} catch {
|
|
1401
|
+
return null;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
async function transformTsrxModuleWithPrerenderWakeClosure(input, linkedChildHasBrowserTriggers) {
|
|
1405
|
+
const encodedFilename = encodeURIComponent(input.filename);
|
|
1406
|
+
const encodedModuleId = encodeURIComponent(input.moduleId ?? input.filename);
|
|
1407
|
+
const payloadId = `${MARKLESS_VIRTUAL_PREFIX}payload:${encodedModuleId}`;
|
|
1408
|
+
const renderDataId = `${MARKLESS_VIRTUAL_PREFIX}render-data:${encodedModuleId}`;
|
|
1409
|
+
const resolverId = `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodedFilename}`;
|
|
1410
|
+
const resumeId = resumeVirtualModuleId(input.filename);
|
|
1411
|
+
const prerenderWakeId = prerenderWakeVirtualModuleId(input.filename);
|
|
1412
|
+
const settleId = settleVirtualModuleId(input.filename);
|
|
1413
|
+
const { compiled: compiledForAllClasses, blockingDiagnostics } = await compileWithBlockingDiagnostics(input, resolverId);
|
|
1414
|
+
throwIfBlocked(input, blockingDiagnostics);
|
|
1415
|
+
const runtimeDemandClass = input.runtimeDemandClass ?? "prerender";
|
|
1416
|
+
const servedScalarPlans = input.servedScalarPlans === true && runtimeDemandClass === "prerender" && !input.prerenderRecords ? compiledForAllClasses.runtimeDemandMaps?.["plain-ssr"] : void 0;
|
|
1417
|
+
const classDemandMap = compiledForAllClasses.runtimeDemandMaps?.[runtimeDemandClass] ?? compiledForAllClasses.runtimeDemandMap;
|
|
1418
|
+
const compiled = {
|
|
1419
|
+
...compiledForAllClasses,
|
|
1420
|
+
runtimeDemandMap: servedScalarPlans ? withServedScalarDemand(classDemandMap, servedScalarPlans) : classDemandMap
|
|
1421
|
+
};
|
|
1422
|
+
const compilerSymbolRows = compiled.symbolModules.modules.map((module) => ({
|
|
1423
|
+
id: module.symbolId,
|
|
1424
|
+
chunk: symbolVirtualModuleId(input.filename, module.symbolId),
|
|
1425
|
+
exportName: scopedSymbolExportName(input.moduleId ?? input.filename, module.exportName)
|
|
1426
|
+
}));
|
|
1427
|
+
const linkedBoundarySymbols = linkedRenderDataBoundarySymbols(linkedSymbolInput(compiled, input, renderDataId, resolverId, input.environment === "client"));
|
|
1428
|
+
const symbolRows = [...compilerSymbolRows, ...linkedBoundarySymbols.map((symbol) => symbol.row)];
|
|
1429
|
+
const behaviorSymbolIds = new Set((compiled.protocolView.behaviors ?? []).flatMap((behavior) => behavior.symbolId ? [behavior.symbolId] : []));
|
|
1430
|
+
const behaviorSymbols = compilerSymbolRows.filter((symbol) => behaviorSymbolIds.has(symbol.id));
|
|
1431
|
+
const importedBoundRows = compiled.boundSymbolResolver.rows.map((row) => row.loaderSymbolId ? {
|
|
1432
|
+
...row,
|
|
1433
|
+
baseSymbolId: row.loaderSymbolId
|
|
1434
|
+
} : row);
|
|
1435
|
+
const boundSymbolDescriptors = perBoundaryBoundSymbolDescriptors(compiled.renderData, importedBoundRows);
|
|
1436
|
+
const resolverSymbols = uniqueSymbolsById([...input.symbols ?? [], ...symbolRows]);
|
|
1437
|
+
const resolverSource = adaptImportedCaptureResolver(emitSymbolResolverModule({
|
|
1438
|
+
literalImports: input.experimentalNativePacking,
|
|
1439
|
+
resolverId: input.experimentalNativePacking ? `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodedModuleId}` : void 0,
|
|
1440
|
+
buildId: input.buildId,
|
|
1441
|
+
symbols: resolverSymbols,
|
|
1442
|
+
boundSymbols: importedBoundRows
|
|
1443
|
+
}), importedBoundRows.some((row) => row.loaderSymbolId !== void 0));
|
|
1444
|
+
const symbolRoutes = componentEdgeSymbolRoutes(compiled, input.artifactChildMaterializations);
|
|
1445
|
+
const closurePlanRoutes = symbolRoutes.filter((route) => !("importSource" in route) || answersClosurePlans("selfRecursive" in route && route.selfRecursive ? compiled.moduleGraphInterface : input.importedModuleInterfaces?.[route.importSource]));
|
|
1446
|
+
const executionLogModuleHookMode = input.executionLogModuleHooks === false ? "never" : input.executionLog;
|
|
1447
|
+
const symbolManifestEntries = [...compiled.symbolModules.modules.map((module, index) => ({
|
|
1448
|
+
symbolId: module.symbolId,
|
|
1449
|
+
kind: module.kind,
|
|
1450
|
+
exportName: compilerSymbolRows[index].exportName,
|
|
1451
|
+
virtualModuleId: symbolVirtualModuleId(input.filename, module.symbolId)
|
|
1452
|
+
})), ...linkedBoundarySymbols.map((symbol) => symbol.manifest)];
|
|
1453
|
+
const prerenderTriggerGroups = input.prerenderRecordData && input.prerenderWakeVariant ? planPrerenderTriggerGroups({
|
|
1454
|
+
filename: input.filename,
|
|
1455
|
+
...input.prerenderRecordData,
|
|
1456
|
+
completeView: containerScopedResumeView(compiled.protocolView),
|
|
1457
|
+
triggerGroups: compiled.triggerGroups,
|
|
1458
|
+
symbolResolver: compiled.symbolResolver,
|
|
1459
|
+
boundRows: importedBoundRows,
|
|
1460
|
+
componentEdges: compiled.semanticGraph.componentEdges,
|
|
1461
|
+
renderData: compiled.renderData
|
|
1462
|
+
}) : [];
|
|
1463
|
+
const selfWakeArmRendererId = prerenderTriggerGroups.some((group) => group.id === "self-wake") ? triggerGroupVirtualModuleId(input.filename, prerenderTriggerGroups.length) : void 0;
|
|
1464
|
+
const symbolBundles = !input.experimentalNativePacking && symbolRows.length > 8 ? planSymbolBundles({
|
|
1465
|
+
filename: input.filename,
|
|
1466
|
+
symbols: compiled.symbolModules.modules.filter((module) => module.kind !== "sync-computed-derive").map((module) => ({
|
|
1467
|
+
symbolId: module.symbolId,
|
|
1468
|
+
moduleId: symbolVirtualModuleId(input.filename, module.symbolId)
|
|
1469
|
+
})),
|
|
1470
|
+
interactions: prerenderTriggerGroups.length > 0 ? prerenderTriggerGroups : compiled.triggerGroups.groups
|
|
1471
|
+
}) : [];
|
|
1472
|
+
const styleCss = compiled.publicRenderPlan.styleScopes.map((scope) => scope.cssText).join("\n");
|
|
1473
|
+
const styleId = compiled.publicRenderPlan.styleScopes.length > 0 ? `${MARKLESS_VIRTUAL_PREFIX}style:${encodedModuleId}.css` : null;
|
|
1474
|
+
const rosterDerivation = compiled.moduleGraphInterface.render.components.some((component) => component.rosterDerivation === true);
|
|
1475
|
+
const storageCells = compiled.moduleGraphInterface.render.components.some((component) => component.storageCells === true);
|
|
1476
|
+
const prerenderClosureNeedsWake = needsFullResume(compiled.protocolState, compiled.protocolView, compiled.runtimeDemandMap) || input.prerenderRecords === true && linkedChildHasBrowserTriggers;
|
|
1477
|
+
const emitsPrerenderWakeVariant = input.prerenderWakeVariant === true && compiled.publicRenderModule.renderDataModuleSource !== void 0 && prerenderInterfacesComplete(compiled, input) && prerenderClosureNeedsWake;
|
|
1478
|
+
const emitsPrerenderWakeFacade = input.prerenderWakeFacade === true && input.prerenderWakeVariant === true && compiled.publicRenderModule.renderDataModuleSource !== void 0 && prerenderInterfacesComplete(compiled, input) && prerenderClosureNeedsWake;
|
|
1479
|
+
const manifestOwnsSymbolRoutes = input.prerenderWakeVariant !== true || input.preserveWakeSiblingClaims === true || emitsPrerenderWakeFacade;
|
|
1480
|
+
const manifest = {
|
|
1481
|
+
source: input.filename,
|
|
1482
|
+
captureMetadata: compiled.captureAnalysis,
|
|
1483
|
+
symbolRoutes: importedSymbolRoutes(symbolRoutes),
|
|
1484
|
+
payload: { virtualModuleId: payloadId },
|
|
1485
|
+
resolver: { virtualModuleId: emitsPrerenderWakeFacade ? prerenderWakeId : resolverId },
|
|
1486
|
+
symbols: manifestOwnsSymbolRoutes ? symbolManifestEntries : [],
|
|
1487
|
+
runtimeDemandMap: compiled.runtimeDemandMap,
|
|
1488
|
+
...input.directCsr === true && compiled.publicRenderModule.moduleSource ? { directCsr: true } : {}
|
|
1489
|
+
};
|
|
1490
|
+
const settlePlan = planSettleModule({
|
|
1491
|
+
boundaries: compiled.renderData?.boundaries,
|
|
1492
|
+
asyncRunners: compiled.protocolView.asyncRunners,
|
|
1493
|
+
descriptors: boundSymbolDescriptors,
|
|
1494
|
+
symbols: resolverSymbols
|
|
1495
|
+
});
|
|
1496
|
+
const prerenderBootVariants = input.environment === "server" ? await compilePrerenderInlineResumerSources() : void 0;
|
|
1497
|
+
const prerenderBoot = prerenderBootVariants ? {
|
|
1498
|
+
...prerenderBootVariants,
|
|
1499
|
+
...input.settleModuleUrl && settlePlan ? { settle: {
|
|
1500
|
+
moduleUrl: input.settleModuleUrl,
|
|
1501
|
+
boot: prerenderBootVariants.prerenderSettle,
|
|
1502
|
+
bound: settlePlan.bound
|
|
1503
|
+
} } : {}
|
|
1504
|
+
} : void 0;
|
|
1505
|
+
const linkedClientRenderData = input.environment === "client" && !input.prerenderRecords;
|
|
1506
|
+
const canonicalRenderData = (input.prerenderRecords || linkedClientRenderData) && prerenderInterfacesComplete(compiled, input);
|
|
1507
|
+
const lazyRenderDataId = canonicalRenderData && compiled.publicRenderModule.renderDataModuleSource ? `${MARKLESS_VIRTUAL_PREFIX}render-data-entry:${encodedModuleId}` : void 0;
|
|
1508
|
+
const servedRenderData = linkedClientRenderData && lazyRenderDataId ? compiled.publicRenderModule.servedRenderData : void 0;
|
|
1509
|
+
const virtualModules = [
|
|
1510
|
+
...compiled.publicRenderModule.renderDataModuleSource ? [{
|
|
1511
|
+
id: renderDataId,
|
|
1512
|
+
type: "render-data",
|
|
1513
|
+
...canonicalRenderData ? { canonicalRenderData: true } : {},
|
|
1514
|
+
source: canonicalRenderData ? await prerenderDataModuleSource(compiled, input.environment, input.importedModuleInterfaces, input.renderDataImportSources, input.artifactChildMaterializations, input.filename, input.moduleId ?? input.filename) : compiled.publicRenderModule.renderDataModuleSource
|
|
1515
|
+
}] : [],
|
|
1516
|
+
...lazyRenderDataId ? [{
|
|
1517
|
+
id: lazyRenderDataId,
|
|
1518
|
+
type: "render-data-entry",
|
|
1519
|
+
source: `export * from ${JSON.stringify(renderDataId)};`
|
|
1520
|
+
}] : [],
|
|
1521
|
+
...servedRenderData ? [
|
|
1522
|
+
{
|
|
1523
|
+
id: servedRenderDataId(encodedModuleId),
|
|
1524
|
+
type: "render-data-served",
|
|
1525
|
+
canonicalRenderData: true,
|
|
1526
|
+
source: await prerenderDataModuleSource(compiled, input.environment, input.importedModuleInterfaces, input.renderDataImportSources, input.artifactChildMaterializations, input.filename, input.moduleId ?? input.filename, servedRenderData)
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
id: servedRenderDataEntryId(encodedModuleId),
|
|
1530
|
+
type: "render-data-entry",
|
|
1531
|
+
source: `export * from ${JSON.stringify(servedRenderDataId(encodedModuleId))};`
|
|
1532
|
+
},
|
|
1533
|
+
{
|
|
1534
|
+
id: clientRenderDataEntryId(encodedModuleId),
|
|
1535
|
+
type: "render-data-entry",
|
|
1536
|
+
source: `export * from ${JSON.stringify(renderDataId)};`
|
|
1537
|
+
}
|
|
1538
|
+
] : [],
|
|
1539
|
+
...styleId ? [{
|
|
1540
|
+
id: styleId,
|
|
1541
|
+
type: "style",
|
|
1542
|
+
source: styleCss
|
|
1543
|
+
}] : [],
|
|
1544
|
+
{
|
|
1545
|
+
id: payloadId,
|
|
1546
|
+
type: "payload",
|
|
1547
|
+
source: payloadModule({
|
|
1548
|
+
...compiled.payloadScripts,
|
|
1549
|
+
runtimeDemandMap: compiled.runtimeDemandMap
|
|
1550
|
+
})
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
id: resolverId,
|
|
1554
|
+
type: "resolver",
|
|
1555
|
+
source: resolverSource,
|
|
1556
|
+
symbolClaims: [.../* @__PURE__ */ new Set([...resolverSymbols.map((symbol) => symbol.id), ...importedBoundRows.map((symbol) => symbol.id)])]
|
|
1557
|
+
},
|
|
1558
|
+
{
|
|
1559
|
+
id: resumeId,
|
|
1560
|
+
type: "resume",
|
|
1561
|
+
source: emitResumeModule({
|
|
1562
|
+
payloadId,
|
|
1563
|
+
resolverId,
|
|
1564
|
+
payloadState: compiled.payloadScripts.state,
|
|
1565
|
+
payloadView: containerScopedResumeView(compiled.payloadScripts.view),
|
|
1566
|
+
hasIdleEvents: viewHasIdleEvents(compiled.payloadScripts.view),
|
|
1567
|
+
streamsArms: authorsPendingArm(compiled.semanticGraph.markup),
|
|
1568
|
+
runtimeDemandMap: compiled.runtimeDemandMap,
|
|
1569
|
+
servedScalarPlans,
|
|
1570
|
+
executionLog: input.executionLog,
|
|
1571
|
+
needsFullResume: prerenderClosureNeedsWake,
|
|
1572
|
+
prerenderDataId: input.prerenderRecords && prerenderInterfacesComplete(compiled, input) ? renderDataId : void 0,
|
|
1573
|
+
lazyRenderDataId,
|
|
1574
|
+
...servedRenderData ? { servedRenderDataId: servedRenderDataEntryId(encodedModuleId) } : {},
|
|
1575
|
+
renderDataId: canonicalRenderData && compiled.publicRenderModule.renderDataModuleSource ? renderDataId : void 0,
|
|
1576
|
+
linkedRowSlotReaders: importedRowSlotReaders(input.importedModuleInterfaces),
|
|
1577
|
+
linkedRowComponents: importedRowComponentMints(input.importedModuleInterfaces),
|
|
1578
|
+
linkedRowTemplates: importedRowTemplateMints(input.importedModuleInterfaces),
|
|
1579
|
+
linkedNestedRepeats: importedNestedRepeats(input.importedModuleInterfaces),
|
|
1580
|
+
linkedRowBranches: importedRowBranchMints(input.importedModuleInterfaces),
|
|
1581
|
+
rosterDerivation,
|
|
1582
|
+
storageCells,
|
|
1583
|
+
hasBoundSymbols: compiled.boundSymbolResolver.rows.length > 0,
|
|
1584
|
+
boundSymbolDescriptors,
|
|
1585
|
+
symbols: symbolRows,
|
|
1586
|
+
symbolRoutes,
|
|
1587
|
+
closurePlanRoutes
|
|
1588
|
+
})
|
|
1589
|
+
},
|
|
1590
|
+
...emitsPrerenderWakeVariant ? [{
|
|
1591
|
+
id: prerenderWakeId,
|
|
1592
|
+
type: "prerender-wake",
|
|
1593
|
+
source: emitResumeModule({
|
|
1594
|
+
payloadId,
|
|
1595
|
+
resolverId,
|
|
1596
|
+
payloadState: compiled.payloadScripts.state,
|
|
1597
|
+
payloadView: containerScopedResumeView(compiled.payloadScripts.view),
|
|
1598
|
+
hasIdleEvents: viewHasIdleEvents(compiled.payloadScripts.view),
|
|
1599
|
+
runtimeDemandMap: compiled.runtimeDemandMap,
|
|
1600
|
+
executionLog: input.executionLog,
|
|
1601
|
+
needsFullResume: prerenderClosureNeedsWake,
|
|
1602
|
+
prerenderDataId: renderDataId,
|
|
1603
|
+
lazyRenderDataId,
|
|
1604
|
+
prerenderTriggerGroups: prerenderTriggerGroups.map((group, index) => ({
|
|
1605
|
+
...group,
|
|
1606
|
+
moduleId: triggerGroupVirtualModuleId(input.filename, index)
|
|
1607
|
+
})),
|
|
1608
|
+
rosterDerivation,
|
|
1609
|
+
storageCells,
|
|
1610
|
+
installResumeSummary: true,
|
|
1611
|
+
recordsOnly: true,
|
|
1612
|
+
hasBoundSymbols: compiled.boundSymbolResolver.rows.length > 0,
|
|
1613
|
+
boundSymbolDescriptors,
|
|
1614
|
+
symbols: symbolRows,
|
|
1615
|
+
symbolRoutes
|
|
1616
|
+
})
|
|
1617
|
+
}] : [],
|
|
1618
|
+
...emitsPrerenderWakeVariant && settlePlan ? [{
|
|
1619
|
+
id: settleId,
|
|
1620
|
+
type: "settle",
|
|
1621
|
+
source: emitSettleModule(settlePlan)
|
|
1622
|
+
}] : [],
|
|
1623
|
+
...(input.prerenderWakeVariant ? prerenderTriggerGroups : []).map((group, index) => ({
|
|
1624
|
+
id: triggerGroupVirtualModuleId(input.filename, index),
|
|
1625
|
+
type: "trigger-group",
|
|
1626
|
+
source: emitPrerenderTriggerGroupModule({
|
|
1627
|
+
group,
|
|
1628
|
+
symbols: uniqueSymbolsById([...input.symbols ?? [], ...symbolRows]),
|
|
1629
|
+
boundRows: importedBoundRows,
|
|
1630
|
+
symbolRoutes,
|
|
1631
|
+
armRendererModuleId: group.id === "self-wake" ? selfWakeArmRendererId : void 0,
|
|
1632
|
+
literalImports: input.experimentalNativePacking
|
|
1633
|
+
})
|
|
1634
|
+
})),
|
|
1635
|
+
...selfWakeArmRendererId ? [{
|
|
1636
|
+
id: selfWakeArmRendererId,
|
|
1637
|
+
type: "trigger-group",
|
|
1638
|
+
source: emitPrerenderBoundaryRendererModule(renderDataId)
|
|
1639
|
+
}] : [],
|
|
1640
|
+
...symbolBundles.map((bundle) => ({
|
|
1641
|
+
id: bundle.id,
|
|
1642
|
+
type: "symbol-bundle",
|
|
1643
|
+
source: emitSymbolBundleModule(bundle.symbolModuleIds),
|
|
1644
|
+
bundledSymbolModuleIds: bundle.symbolModuleIds
|
|
1645
|
+
})),
|
|
1646
|
+
...linkedBoundarySymbols.map((symbol) => symbol.module),
|
|
1647
|
+
...await Promise.all(compiled.symbolModules.modules.map(async (module, index) => ({
|
|
1648
|
+
id: symbolVirtualModuleId(input.filename, module.symbolId),
|
|
1649
|
+
type: "symbol",
|
|
1650
|
+
symbolId: module.symbolId,
|
|
1651
|
+
exportName: symbolRows[index].exportName,
|
|
1652
|
+
source: injectExecutionLogModuleHook(await stripEmittedTypes(rewriteSymbolModuleExport(module.source, module.exportName, symbolRows[index].exportName), symbolVirtualModuleId(input.filename, module.symbolId)), `symbol:${module.symbolId}`, executionLogModuleHookMode)
|
|
1653
|
+
})))
|
|
1654
|
+
];
|
|
1655
|
+
const styleImport = styleId ? `import ${JSON.stringify(styleId)};\n` : "";
|
|
1656
|
+
const inlineResumerSources = (input.environment ?? "lib") === "client" ? void 0 : await compileInlineResumerSources({
|
|
1657
|
+
debug: input.inlineResumerDebug === true,
|
|
1658
|
+
executionLog: input.executionLog ?? "never"
|
|
1659
|
+
});
|
|
1660
|
+
const styleModuleIds = [.../* @__PURE__ */ new Set([...styleId ? [styleId] : [], ...input.linkedStyleModuleIds ?? []])];
|
|
1661
|
+
const styleModuleUrl = input.styleModuleUrl;
|
|
1662
|
+
const headInjections = [...input.headInjections ?? [], ...styleModuleUrl ? styleModuleIds.map((id) => ({
|
|
1663
|
+
tag: "link",
|
|
1664
|
+
location: "head",
|
|
1665
|
+
attributes: {
|
|
1666
|
+
rel: "stylesheet",
|
|
1667
|
+
href: styleModuleUrl(id)
|
|
1668
|
+
}
|
|
1669
|
+
})) : []];
|
|
1670
|
+
const storageSeeds = compiled.payloadArena.state.storage.map((storage) => {
|
|
1671
|
+
const binding = compiled.semanticGraph.graphBindings.find((candidate) => candidate.id === storage.graphNodeId);
|
|
1672
|
+
if (typeof binding?.initialValue !== "string") throw new Error(`MARKLESS_STORAGE_SEED_FALLBACK_MISSING: ${storage.graphNodeId} has no static string fallback.`);
|
|
1673
|
+
return createStorageSeedMetadataFromGraphNodeId(storage.graphNodeId, storage.key, binding.initialValue);
|
|
1674
|
+
});
|
|
1675
|
+
return {
|
|
1676
|
+
code: styleImport + await stripEmittedTypes(emitSourceModule({
|
|
1677
|
+
filename: input.filename,
|
|
1678
|
+
dev: input.dev,
|
|
1679
|
+
payloadId,
|
|
1680
|
+
resolverId,
|
|
1681
|
+
renderDataId,
|
|
1682
|
+
environment: input.environment ?? "lib",
|
|
1683
|
+
linkedRowSlotReaders: importedRowSlotReaders(input.importedModuleInterfaces),
|
|
1684
|
+
linkedRowComponents: importedRowComponentMints(input.importedModuleInterfaces),
|
|
1685
|
+
linkedRowTemplates: importedRowTemplateMints(input.importedModuleInterfaces),
|
|
1686
|
+
linkedNestedRepeats: importedNestedRepeats(input.importedModuleInterfaces),
|
|
1687
|
+
linkedRowBranches: importedRowBranchMints(input.importedModuleInterfaces),
|
|
1688
|
+
clientOutput: input.clientOutput ?? "full",
|
|
1689
|
+
executionLog: input.executionLog,
|
|
1690
|
+
headInjections: headInjections.length > 0 ? headInjections : void 0,
|
|
1691
|
+
storageSeeds: storageSeeds.length > 0 ? storageSeeds : void 0,
|
|
1692
|
+
inlineResumerSources,
|
|
1693
|
+
prerenderBoot,
|
|
1694
|
+
...input.environment === "server" ? { sharedInlineSourcesModuleId: sharedInlineSourcesModuleId({
|
|
1695
|
+
debug: input.inlineResumerDebug === true,
|
|
1696
|
+
executionLog: input.executionLog ?? "never"
|
|
1697
|
+
}) } : {},
|
|
1698
|
+
devResumeReexport: input.devResumeReexport === true,
|
|
1699
|
+
needsFullResume: prerenderClosureNeedsWake,
|
|
1700
|
+
prerenderRecords: input.prerenderRecords,
|
|
1701
|
+
directCsr: input.directCsr,
|
|
1702
|
+
hasComputedState: compiled.payloadScripts.state.computed.length > 0,
|
|
1703
|
+
hasOverlayMarks: compiled.runtimeDemandMap.payloadRecords.some((record) => record.kind === "overlay"),
|
|
1704
|
+
hasIdleEvents: viewHasIdleEvents(compiled.payloadScripts.view),
|
|
1705
|
+
runtimeDemandMap: compiled.runtimeDemandMap,
|
|
1706
|
+
resumeModuleUrl: input.resumeModuleUrl,
|
|
1707
|
+
scalarActions: input.includeScalarActionPlans ? compiled.runtimeDemandMaps?.["plain-ssr"].actions : void 0,
|
|
1708
|
+
closureActions: (servedScalarPlans ?? (runtimeDemandClass === "plain-ssr" ? classDemandMap : void 0))?.actions,
|
|
1709
|
+
prerenderWakeModuleUrl: input.prerenderWakeModuleUrl,
|
|
1710
|
+
publicRenderModuleSource: compiled.publicRenderModule.moduleSource,
|
|
1711
|
+
publicRenderRootExportName: compiled.publicRenderModule.rootExportName,
|
|
1712
|
+
publicSsrModuleSource: compiled.publicRenderModule.ssrModuleSource,
|
|
1713
|
+
publicRenderSsrExportName: compiled.publicRenderModule.ssrExportName,
|
|
1714
|
+
publicRenderSsrComponentExports: compiled.publicRenderModule.ssrComponentExports,
|
|
1715
|
+
canonicalRenderData: prerenderInterfacesComplete(compiled, input),
|
|
1716
|
+
...servedRenderData && input.serverRenderedPages && !input.dev ? { lazyFullRenderDataId: clientRenderDataEntryId(encodedModuleId) } : {},
|
|
1717
|
+
sharedDefinitionExports: compiled.moduleGraphInterface?.sharedDefinitions?.map((published) => published.exportName),
|
|
1718
|
+
hasBoundSymbols: compiled.boundSymbolResolver.rows.length > 0,
|
|
1719
|
+
symbols: symbolRows,
|
|
1720
|
+
behaviorSymbols,
|
|
1721
|
+
symbolRoutes,
|
|
1722
|
+
closurePlanRoutes
|
|
1723
|
+
}), input.filename),
|
|
1724
|
+
map: null,
|
|
1725
|
+
virtualModules,
|
|
1726
|
+
manifest,
|
|
1727
|
+
moduleGraphInterface: compiled.moduleGraphInterface,
|
|
1728
|
+
interfaceHash: moduleInterfaceHash(compiled.moduleGraphInterface),
|
|
1729
|
+
moduleImports: compiled.semanticGraph.moduleImports,
|
|
1730
|
+
artifactChildren: artifactChildCandidates(compiled),
|
|
1731
|
+
propFlow: modulePropFlow(compiled, moduleDiagnostics(compiled)),
|
|
1732
|
+
importedConstantRequests: compiled.semanticGraph.componentEdges.flatMap((edge) => edge.props.flatMap((prop) => "importedConstants" in prop ? prop.importedConstants ?? [] : []))
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
function resolveAuthoredSpecifier(specifier, sourceFilename) {
|
|
1736
|
+
if (!specifier.startsWith(".")) return specifier;
|
|
1737
|
+
if (!isAbsolute(sourceFilename)) throw new Error(`MARKLESS_RENDER_DATA_READER_SPECIFIER_UNRESOLVABLE: ${JSON.stringify(specifier)} needs an absolute module filename, got ${JSON.stringify(sourceFilename)}.`);
|
|
1738
|
+
return resolve(dirname(sourceFilename), specifier);
|
|
1739
|
+
}
|
|
1740
|
+
function renderDataInitializerSymbolId(definition, initial, initializerSymbolIds) {
|
|
1741
|
+
if (initial.value.kind !== "symbol-function") return void 0;
|
|
1742
|
+
const symbolId = initial.value.symbolId;
|
|
1743
|
+
if (definition.initializerResidues?.[symbolId] || !initializerSymbolIds.has(symbolId)) return void 0;
|
|
1744
|
+
return symbolId;
|
|
1745
|
+
}
|
|
1746
|
+
function initializerModuleSymbolIds(compiled) {
|
|
1747
|
+
return new Set(compiled.symbolModules.modules.filter((module) => module.kind === "state-initializer" || module.kind === "sync-computed-derive").map((module) => module.symbolId));
|
|
1748
|
+
}
|
|
1749
|
+
const UNEVALUATED_DEFINITION_FIELDS = [
|
|
1750
|
+
"state",
|
|
1751
|
+
"stateCellIndexes",
|
|
1752
|
+
"stateComputedIndexes",
|
|
1753
|
+
"stateSharedSeedIndexes",
|
|
1754
|
+
"servedComputedIndexes",
|
|
1755
|
+
"view",
|
|
1756
|
+
"initialValues",
|
|
1757
|
+
"initialValueKinds",
|
|
1758
|
+
"initializerResidues",
|
|
1759
|
+
"stateGraphNodeIds"
|
|
1760
|
+
];
|
|
1761
|
+
function servedDefinition(record, served, rootsWidget) {
|
|
1762
|
+
const { chunks: _chunks, ...rest } = record;
|
|
1763
|
+
const seeds = Object.values(record.initialValueKinds ?? {}).includes("shared-seed");
|
|
1764
|
+
if (served.evaluatedComponents.includes(String(record.name)) || rootsWidget === true || seeds) return rest;
|
|
1765
|
+
return Object.fromEntries(Object.entries(rest).filter(([field]) => !UNEVALUATED_DEFINITION_FIELDS.includes(field)));
|
|
1766
|
+
}
|
|
1767
|
+
async function prerenderDataModuleSource(compiled, environment, importedModuleInterfaces, renderDataImportSources, artifactChildMaterializations, sourceFilename, moduleId, served) {
|
|
1768
|
+
const importedComponents = /* @__PURE__ */ new Map();
|
|
1769
|
+
const browserRenderedChildren = served ? new Set(compiled.semanticGraph.componentEdges.flatMap((edge) => served.browserRenderedEdgeIds.includes(edge.id) ? [edge.childComponentName] : [])) : void 0;
|
|
1770
|
+
for (const edge of compiled.semanticGraph.componentEdges) {
|
|
1771
|
+
if (!edge.importSource || importedComponents.has(edge.childComponentName)) continue;
|
|
1772
|
+
if (artifactChildMaterializations?.[edge.id]) continue;
|
|
1773
|
+
const linked = importedModuleInterfaces?.[edge.importSource];
|
|
1774
|
+
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.`);
|
|
1775
|
+
const full = renderDataImportSources?.[edge.importSource] ?? `virtual:markless:render-data:${encodeURIComponent(linked.moduleId ?? linked.filename)}`;
|
|
1776
|
+
importedComponents.set(edge.childComponentName, {
|
|
1777
|
+
source: browserRenderedChildren && !browserRenderedChildren.has(edge.childComponentName) ? servedRenderDataReference(full) : full,
|
|
1778
|
+
local: `marklessPrerenderImport${importedComponents.size}`
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
const renderDataId = `${MARKLESS_VIRTUAL_PREFIX}render-data:${encodeURIComponent(moduleId)}`;
|
|
1782
|
+
const readerImports = /* @__PURE__ */ new Map();
|
|
1783
|
+
const readerDeclarations = /* @__PURE__ */ new Map();
|
|
1784
|
+
const initializerImports = /* @__PURE__ */ new Map();
|
|
1785
|
+
const initializerSymbolIds = initializerModuleSymbolIds(compiled);
|
|
1786
|
+
const initializerModules = new Map(compiled.symbolModules.modules.filter((module) => initializerSymbolIds.has(module.symbolId)).map((module) => [module.symbolId, module]));
|
|
1787
|
+
const componentEntries = [];
|
|
1788
|
+
let qualifiesRows = false;
|
|
1789
|
+
for (const definition of compiled.publicRenderModule.componentDefinitions) {
|
|
1790
|
+
const { residueReaderSource, residueReaderImports, residueReaderDeclarations, rootsWidget, projectsIntoRows, ...record } = definition;
|
|
1791
|
+
const readerSource = served ? served.readers[String(definition.name)] : residueReaderSource;
|
|
1792
|
+
const initializers = /* @__PURE__ */ new Map();
|
|
1793
|
+
const initialized = !served || served.browserRenderedComponents.includes(String(definition.name));
|
|
1794
|
+
for (const initial of initialized ? record.initialValues ?? [] : []) {
|
|
1795
|
+
const symbolId = renderDataInitializerSymbolId(record, initial, initializerSymbolIds);
|
|
1796
|
+
if (!symbolId) continue;
|
|
1797
|
+
const module = initializerModules.get(symbolId);
|
|
1798
|
+
let imported = initializerImports.get(symbolId);
|
|
1799
|
+
if (!imported) {
|
|
1800
|
+
const local = `marklessRenderInitializer${initializerImports.size}`;
|
|
1801
|
+
imported = {
|
|
1802
|
+
local,
|
|
1803
|
+
line: `import { ${scopedSymbolExportName(moduleId, module.exportName)} as ${local} } from ${JSON.stringify(symbolVirtualModuleId(sourceFilename, symbolId))};`
|
|
1804
|
+
};
|
|
1805
|
+
initializerImports.set(symbolId, imported);
|
|
1806
|
+
}
|
|
1807
|
+
initializers.set(symbolId, imported.local);
|
|
1808
|
+
}
|
|
1809
|
+
for (const entry of (served ? served.imports : residueReaderImports) ?? []) {
|
|
1810
|
+
if (readerImports.has(entry.line)) continue;
|
|
1811
|
+
const rebound = entry.line.replace(JSON.stringify(entry.source), JSON.stringify(resolveAuthoredSpecifier(entry.source, sourceFilename)));
|
|
1812
|
+
readerImports.set(entry.line, await stripEmittedTypesFromFragment(rebound, `${renderDataId}:reader-import`, true));
|
|
1813
|
+
}
|
|
1814
|
+
for (const line of (served ? served.declarations : residueReaderDeclarations) ?? []) {
|
|
1815
|
+
if (readerDeclarations.has(line)) continue;
|
|
1816
|
+
readerDeclarations.set(line, await stripEmittedTypesFromFragment(line, `${renderDataId}:reader-declaration`));
|
|
1817
|
+
}
|
|
1818
|
+
const data = jsonSourceWithNonFiniteNumbers(served ? servedDefinition(record, served, rootsWidget) : record) ?? "undefined";
|
|
1819
|
+
const reader = readerSource ? await stripEmittedTypesFromExpression(readerSource, `${renderDataId}:reader:${String(definition.name)}`) : void 0;
|
|
1820
|
+
if (projectsIntoRows) qualifiesRows = true;
|
|
1821
|
+
const functions = [
|
|
1822
|
+
...reader ? [`readResidue:${reader}`] : [],
|
|
1823
|
+
...projectsIntoRows ? ["rowHosts:marklessRowHosts"] : [],
|
|
1824
|
+
...initializers.size ? [`initializers:{${[...initializers].map(([id, local]) => `${JSON.stringify(id)}:${local}`).join(",")}}`] : []
|
|
1825
|
+
];
|
|
1826
|
+
componentEntries.push({
|
|
1827
|
+
name: JSON.stringify(String(definition.name)),
|
|
1828
|
+
data,
|
|
1829
|
+
functions
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
const preludes = [...initializerImports.values()].map((entry) => entry.line).concat([...readerImports.values(), ...readerDeclarations.values()]);
|
|
1833
|
+
const factored = factorRenderDataLiterals(componentEntries.map((entry) => entry.data), preludes.concat(componentEntries.map((entry) => `const marklessLiteralReaderScope = {${entry.functions.join(",")}};`)).join("\n"));
|
|
1834
|
+
const seedsShared = compiled.publicRenderModule.componentDefinitions.some((definition) => {
|
|
1835
|
+
const record = definition;
|
|
1836
|
+
return record.rootsWidget === true || Object.values(record.initialValueKinds ?? {}).includes("shared-seed");
|
|
1837
|
+
});
|
|
1838
|
+
return [
|
|
1839
|
+
...environment === "client" && demandsOverlay(compiled.runtimeDemandMap) ? [emitOverlayLoaderInstall()] : [],
|
|
1840
|
+
...seedsShared ? ["import { installMarklessSharedSeedPass } from '@markless/web/fns/shared-seed';", "installMarklessSharedSeedPass();"] : [],
|
|
1841
|
+
...[...importedComponents.values()].map((entry) => `import { marklessPrerenderData as ${entry.local} } from ${JSON.stringify(entry.source)};`),
|
|
1842
|
+
...qualifiesRows ? ["import { marklessRowHosts } from '@markless/web/fns/row-qualified-view';"] : [],
|
|
1843
|
+
...preludes,
|
|
1844
|
+
served ? served.renderDataModuleSource : compiled.publicRenderModule.renderDataModuleSource,
|
|
1845
|
+
...factored.factories,
|
|
1846
|
+
`const marklessPrerenderComponents = {${componentEntries.map((entry, index) => `${entry.name}:${entry.functions.length ? `{...${factored.records[index]},${entry.functions.join(",")}}` : factored.records[index]}`).join(",")}};`,
|
|
1847
|
+
"export const marklessPrerenderData = {",
|
|
1848
|
+
`\trootComponentName: ${JSON.stringify(compiled.renderData.root?.componentName ?? null)},`,
|
|
1849
|
+
" renderData: marklessRenderData,",
|
|
1850
|
+
" components: marklessPrerenderComponents,",
|
|
1851
|
+
`\timports: {${[...importedComponents].map(([name, entry]) => `${JSON.stringify(name)}:${entry.local}`).join(",")}},`,
|
|
1852
|
+
"};"
|
|
1853
|
+
].join("\n");
|
|
1854
|
+
}
|
|
1855
|
+
async function preflightTsrxModuleDiagnostics(input) {
|
|
1856
|
+
const { blockingDiagnostics } = await compileWithBlockingDiagnostics(input, `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodeURIComponent(input.filename)}`);
|
|
1857
|
+
throwIfBlocked(input, blockingDiagnostics);
|
|
1858
|
+
}
|
|
1859
|
+
function linkedSymbolInput(compiled, input, renderDataId, resolverId, clientLink) {
|
|
1860
|
+
return {
|
|
1861
|
+
compiled,
|
|
1862
|
+
link: input,
|
|
1863
|
+
clientLink,
|
|
1864
|
+
renderDataId,
|
|
1865
|
+
resolverId,
|
|
1866
|
+
symbolModuleId: (symbolId) => symbolVirtualModuleId(input.filename, symbolId),
|
|
1867
|
+
boundaryExportName: (index) => scopedSymbolExportName(input.moduleId ?? input.filename, `marklessLinkedBoundaryUpdate${index}`),
|
|
1868
|
+
branchExportName: (index) => scopedSymbolExportName(input.moduleId ?? input.filename, `marklessLinkedBranchUpdate${index}`)
|
|
1869
|
+
};
|
|
1870
|
+
}
|
|
1871
|
+
function fulfilledEscalationSymbolIds(compiled, input, resolverId) {
|
|
1872
|
+
if ((compiled.symbolModules.armEscalationCandidates ?? []).length === 0) return /* @__PURE__ */ new Set();
|
|
1873
|
+
const renderDataId = `${MARKLESS_VIRTUAL_PREFIX}render-data:${encodeURIComponent(input.moduleId ?? input.filename)}`;
|
|
1874
|
+
return new Set(linkedRenderDataBoundarySymbols(linkedSymbolInput(compiled, input, renderDataId, resolverId, true)).flatMap((symbol) => symbol.manifest.kind === "branch-update" ? [symbol.row.id] : []));
|
|
1875
|
+
}
|
|
1876
|
+
/** The compiler input a transform compiles; anything else that only needs a module's interface asks for the same one. */
|
|
1877
|
+
function transformCompileInput(input) {
|
|
1878
|
+
return {
|
|
1879
|
+
filename: input.filename,
|
|
1880
|
+
moduleId: input.moduleId,
|
|
1881
|
+
source: input.source,
|
|
1882
|
+
...input.serverOnlyProps?.length ? { serverOnlyProps: input.serverOnlyProps } : {},
|
|
1883
|
+
...input.routeRoot ? { routeRoot: true } : {},
|
|
1884
|
+
buildId: input.buildId,
|
|
1885
|
+
resolverId: `${MARKLESS_VIRTUAL_PREFIX}resolver:${encodeURIComponent(input.filename)}`,
|
|
1886
|
+
symbols: input.symbols ?? [],
|
|
1887
|
+
importedModuleInterfaces: input.importedModuleInterfaces,
|
|
1888
|
+
importedModuleConstants: input.importedModuleConstants,
|
|
1889
|
+
artifactChildMaterializations: input.artifactChildMaterializations,
|
|
1890
|
+
omitAuthoredSource: normalizeExecutionLogMode(input.executionLog) === "never"
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
1893
|
+
async function compileWithBlockingDiagnostics(input, resolverId) {
|
|
1894
|
+
const compiled = await compileTsrxModule(transformCompileInput(input));
|
|
1895
|
+
const fulfilled = fulfilledEscalationSymbolIds(compiled, input, resolverId);
|
|
1896
|
+
return {
|
|
1897
|
+
compiled,
|
|
1898
|
+
blockingDiagnostics: moduleDiagnostics(compiled).filter((diagnostic) => diagnostic.severity === "error" && !(diagnostic.code === "MARKLESS_BRANCH_ARM_UPDATE_UNSUPPORTED" && typeof diagnostic.symbolId === "string" && fulfilled.has(diagnostic.symbolId)))
|
|
1899
|
+
};
|
|
1900
|
+
}
|
|
1901
|
+
const diagnosticsByCompile = /* @__PURE__ */ new WeakMap();
|
|
1902
|
+
function moduleDiagnostics(compiled) {
|
|
1903
|
+
let diagnostics = diagnosticsByCompile.get(compiled);
|
|
1904
|
+
if (!diagnostics) diagnosticsByCompile.set(compiled, diagnostics = collectTsrxModuleDiagnostics(compiled));
|
|
1905
|
+
return diagnostics;
|
|
1906
|
+
}
|
|
1907
|
+
function throwIfBlocked(input, blockingDiagnostics) {
|
|
1908
|
+
if (blockingDiagnostics.length === 0) return;
|
|
1909
|
+
const details = formatBlockedCompileError(input, blockingDiagnostics);
|
|
1910
|
+
throw new MarklessCompileError(createCompileErrorPayload({
|
|
1911
|
+
filename: input.filename,
|
|
1912
|
+
source: input.source,
|
|
1913
|
+
diagnostics: blockingDiagnostics,
|
|
1914
|
+
details
|
|
1915
|
+
}));
|
|
1916
|
+
}
|
|
1917
|
+
function formatBlockedCompileError(input, diagnostics) {
|
|
1918
|
+
return [`MARKLESS_COMPILE_BLOCKED: ${input.filename} has ${diagnostics.length} compiler error(s).`, ...diagnostics.map((diagnostic) => {
|
|
1919
|
+
const position = diagnostic.primarySpan ? formatSourcePosition(input.source, diagnostic.primarySpan.start) : void 0;
|
|
1920
|
+
const location = position ? ` (${diagnostic.primarySpan.filename}:${position.line}:${position.column})` : "";
|
|
1921
|
+
return [
|
|
1922
|
+
`${diagnostic.code}: ${diagnostic.message}${location}`,
|
|
1923
|
+
diagnostic.why,
|
|
1924
|
+
diagnostic.suggestions[0]?.message,
|
|
1925
|
+
diagnostic.docsUrl
|
|
1926
|
+
].filter((line) => Boolean(line)).join("\n");
|
|
1927
|
+
})].join("\n\n");
|
|
1928
|
+
}
|
|
1929
|
+
function formatSourcePosition(source, start) {
|
|
1930
|
+
const sourceBeforeSpan = source.slice(0, start);
|
|
1931
|
+
const lastLineBreak = sourceBeforeSpan.lastIndexOf("\n");
|
|
1932
|
+
return {
|
|
1933
|
+
line: sourceBeforeSpan.split("\n").length,
|
|
1934
|
+
column: sourceBeforeSpan.length - lastLineBreak
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
function uniqueSymbolsById(symbols) {
|
|
1938
|
+
return [...new Map(symbols.map((symbol) => [symbol.id, symbol])).values()];
|
|
1939
|
+
}
|
|
1940
|
+
function containerScopedResumeView(view) {
|
|
1941
|
+
return {
|
|
1942
|
+
...view,
|
|
1943
|
+
locators: (view.locators ?? []).map((locator) => ({
|
|
1944
|
+
...locator,
|
|
1945
|
+
index: locator.index + 1
|
|
1946
|
+
}))
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
function answersClosurePlans(moduleInterface) {
|
|
1950
|
+
return !!moduleInterface?.render.components.some((component) => component.closureActions);
|
|
1951
|
+
}
|
|
1952
|
+
function withServedScalarDemand(map, served) {
|
|
1953
|
+
const planned = served.actions.filter((action) => action.plan?.kind === "scalar" || action.plan?.kind === "closure");
|
|
1954
|
+
if (planned.length === 0) return map;
|
|
1955
|
+
const union = (left, right) => [.../* @__PURE__ */ new Set([...left, ...right])].sort();
|
|
1956
|
+
const servedRecords = new Map(served.payloadRecords.map((record) => [record.recordId, record]));
|
|
1957
|
+
const plannedRecordIds = new Set(planned.flatMap((action) => action.payloadRecordIds));
|
|
1958
|
+
return {
|
|
1959
|
+
...map,
|
|
1960
|
+
payloadRecords: map.payloadRecords.map((record) => {
|
|
1961
|
+
const lean = plannedRecordIds.has(record.recordId) ? servedRecords.get(record.recordId) : void 0;
|
|
1962
|
+
return lean ? {
|
|
1963
|
+
...record,
|
|
1964
|
+
runtimeModuleIds: union(record.runtimeModuleIds, lean.runtimeModuleIds)
|
|
1965
|
+
} : record;
|
|
1966
|
+
}),
|
|
1967
|
+
actions: map.actions.map((action) => {
|
|
1968
|
+
const lean = planned.find((candidate) => candidate.hostNodeId === action.hostNodeId && candidate.eventName === action.eventName && candidate.recordKind === action.recordKind);
|
|
1969
|
+
if (!lean) return action;
|
|
1970
|
+
return {
|
|
1971
|
+
...action,
|
|
1972
|
+
runtimeModuleIds: union(action.runtimeModuleIds, lean.runtimeModuleIds),
|
|
1973
|
+
...lean.firstUse ? { firstUse: lean.firstUse } : {},
|
|
1974
|
+
...lean.plan?.kind === "closure" ? { plan: lean.plan } : {}
|
|
1975
|
+
};
|
|
1976
|
+
})
|
|
1977
|
+
};
|
|
1978
|
+
}
|
|
1979
|
+
function needsFullResume(state, _view, runtimeDemandMap) {
|
|
1980
|
+
if ((state.storage?.length ?? 0) > 0) return true;
|
|
1981
|
+
return runtimeDemandMap.payloadRecords.some((record) => RECORD_NEEDS_FULL_RESUME[record.kind](runtimeDemandMap));
|
|
1982
|
+
}
|
|
1983
|
+
const RECORD_NEEDS_FULL_RESUME = {
|
|
1984
|
+
"async-boundary": () => true,
|
|
1985
|
+
behavior: () => false,
|
|
1986
|
+
branch: () => true,
|
|
1987
|
+
"dom-update": () => false,
|
|
1988
|
+
"element-handle": () => true,
|
|
1989
|
+
[PROTOCOL_EVENT_ACTION_KIND.event]: () => false,
|
|
1990
|
+
[PROTOCOL_EVENT_ACTION_KIND.externalDelegate]: () => false,
|
|
1991
|
+
"keyed-repeat": (runtimeDemandMap) => !recordKindReplaced(runtimeDemandMap, "keyed-repeat"),
|
|
1992
|
+
overlay: () => true
|
|
1993
|
+
};
|
|
1994
|
+
function recordKindReplaced(runtimeDemandMap, kind) {
|
|
1995
|
+
return runtimeDemandMap.recordKinds.some((record) => record.kind === kind && record.replaced === true);
|
|
1996
|
+
}
|
|
1997
|
+
/**
|
|
1998
|
+
* What the settle module must import, and what the document must carry to use
|
|
1999
|
+
* it. Fails closed: a boundary whose runner symbol or whose bound base symbol
|
|
2000
|
+
* is not in this page's symbol rows produces no settle module at all, so the
|
|
2001
|
+
* page keeps the self-wake path rather than half a settle.
|
|
2002
|
+
*/
|
|
2003
|
+
function planSettleModule(input) {
|
|
2004
|
+
const symbolById = new Map(input.symbols.map((symbol) => [symbol.id, symbol]));
|
|
2005
|
+
const runners = [];
|
|
2006
|
+
const derives = [];
|
|
2007
|
+
const bound = {};
|
|
2008
|
+
for (const boundary of input.boundaries ?? []) {
|
|
2009
|
+
const node = boundary.runnerGraphNodeId;
|
|
2010
|
+
if (!node) continue;
|
|
2011
|
+
const runner = symbolById.get(input.asyncRunners?.[node] ?? "");
|
|
2012
|
+
if (!runner) continue;
|
|
2013
|
+
const rows = (input.descriptors?.[boundary.boundaryId] ?? []).map((descriptor) => ({
|
|
2014
|
+
descriptor,
|
|
2015
|
+
symbol: symbolById.get(descriptor.base)
|
|
2016
|
+
}));
|
|
2017
|
+
if (rows.some((row) => !row.symbol)) continue;
|
|
2018
|
+
runners.push({
|
|
2019
|
+
node,
|
|
2020
|
+
symbol: runner
|
|
2021
|
+
});
|
|
2022
|
+
for (const row of rows) {
|
|
2023
|
+
derives.push({
|
|
2024
|
+
id: row.descriptor.id,
|
|
2025
|
+
symbol: row.symbol
|
|
2026
|
+
});
|
|
2027
|
+
bound[boundary.boundaryId] = {
|
|
2028
|
+
...bound[boundary.boundaryId],
|
|
2029
|
+
[row.descriptor.id]: Object.fromEntries(row.descriptor.slots.map((slot) => [`${slot[0]}|${slot[1].join(".")}`, [slot[2], slot[3]]]))
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
return runners.length > 0 ? {
|
|
2034
|
+
runners,
|
|
2035
|
+
derives,
|
|
2036
|
+
bound
|
|
2037
|
+
} : void 0;
|
|
2038
|
+
}
|
|
2039
|
+
function perBoundaryBoundSymbolDescriptors(renderData, boundRows) {
|
|
2040
|
+
if (boundRows.length === 0) return void 0;
|
|
2041
|
+
const chunks = new Map(renderData.chunks.map((chunk) => [chunk.id, chunk]));
|
|
2042
|
+
const descriptors = {};
|
|
2043
|
+
for (const boundary of renderData.boundaries) {
|
|
2044
|
+
const edges = componentEdgesReachableFrom(chunks, boundary.armChunkIds.try);
|
|
2045
|
+
const rows = boundRows.filter((row) => row.ancestry.some((step) => edges.has(step.componentEdgeId)));
|
|
2046
|
+
if (rows.length === 0) continue;
|
|
2047
|
+
descriptors[boundary.boundaryId] = rows.map((row) => ({
|
|
2048
|
+
id: row.id,
|
|
2049
|
+
base: row.baseSymbolId,
|
|
2050
|
+
slots: row.captureSlots.flatMap((slot) => slot.legacyGraphRead && slot.route.kind === "graph-reference" ? [[
|
|
2051
|
+
slot.legacyGraphRead.graphNodeId,
|
|
2052
|
+
slot.legacyGraphRead.path,
|
|
2053
|
+
slot.route.graphNodeId,
|
|
2054
|
+
slot.route.path
|
|
2055
|
+
]] : [])
|
|
2056
|
+
}));
|
|
2057
|
+
}
|
|
2058
|
+
return Object.keys(descriptors).length > 0 ? descriptors : void 0;
|
|
2059
|
+
}
|
|
2060
|
+
function componentEdgesReachableFrom(chunks, rootChunkId) {
|
|
2061
|
+
const edges = /* @__PURE__ */ new Set();
|
|
2062
|
+
const pending = [rootChunkId];
|
|
2063
|
+
const visited = /* @__PURE__ */ new Set();
|
|
2064
|
+
while (pending.length > 0) {
|
|
2065
|
+
const id = pending.pop();
|
|
2066
|
+
if (visited.has(id)) continue;
|
|
2067
|
+
visited.add(id);
|
|
2068
|
+
for (const slot of chunks.get(id)?.slots ?? []) if (slot.kind === "child-component") {
|
|
2069
|
+
edges.add(slot.componentEdgeId);
|
|
2070
|
+
pending.push(slot.childTemplateId);
|
|
2071
|
+
if (slot.projectionChunkId) pending.push(slot.projectionChunkId);
|
|
2072
|
+
} else if (slot.kind === "repeat") {
|
|
2073
|
+
pending.push(slot.rowTemplateId);
|
|
2074
|
+
if (slot.emptyTemplateId) pending.push(slot.emptyTemplateId);
|
|
2075
|
+
} else if (slot.kind === "branch") pending.push(...slot.armTemplateIds);
|
|
2076
|
+
}
|
|
2077
|
+
return edges;
|
|
2078
|
+
}
|
|
2079
|
+
function viewHasIdleEvents(view) {
|
|
2080
|
+
return [
|
|
2081
|
+
view,
|
|
2082
|
+
...(view.branches ?? []).flatMap((branch) => [...branch.armRecords ?? [], ...branch.servedArmRecords ? [branch.servedArmRecords] : []]),
|
|
2083
|
+
...view.asyncBoundaries.flatMap((boundary) => boundary.armRecords && !Array.isArray(boundary.armRecords) ? [boundary.armRecords] : [])
|
|
2084
|
+
].some((set) => (set.events ?? []).some((event) => event.eventName === PROTOCOL_IDLE_EVENT_NAME) || (set.keyedRepeats ?? []).some((repeat) => repeat.rowEvents.some((event) => event.eventName === PROTOCOL_IDLE_EVENT_NAME)));
|
|
2085
|
+
}
|
|
2086
|
+
function authorsPendingArm(markup) {
|
|
2087
|
+
return markup.chunks.some((chunk) => chunk.slots.some((slot) => slot.kind === "async" && slot.armTemplateIds.pending !== void 0));
|
|
2088
|
+
}
|
|
2089
|
+
//#endregion
|
|
2090
|
+
//#region src/virtual-ids.ts
|
|
2091
|
+
const TSRX_SOURCE_FILE = /\.tsrx(?:[?#].*)?$/;
|
|
2092
|
+
/** A request that exports its file as a string or URL (`?raw`, `?url`, `?inline`), never runs it. */
|
|
2093
|
+
const STRING_EXPORT_QUERY = /[?&](?:raw|url|inline)(?:&|=|$)/;
|
|
2094
|
+
const MARKLESS_SYMBOL_SOURCE_QUERY_RE = /[?&]markless-symbols(?:[&#]|$)/;
|
|
2095
|
+
const MARKLESS_RESUME_SOURCE_QUERY_RE = /[?&]markless-resume(?:[&#]|$)/;
|
|
2096
|
+
const MARKLESS_RENDER_DATA_SOURCE_QUERY_RE = /[?&]markless-render-data(?:[&#]|$)/;
|
|
2097
|
+
const MARKLESS_REACHED_FROM_SOURCE_QUERY = "markless-reached-from";
|
|
2098
|
+
const MARKLESS_REACHED_FROM_ROUTE = "route";
|
|
2099
|
+
const MARKLESS_PRERENDER_WAKE_SOURCE_QUERY_RE = /[?&]markless-prerender-wake(?:[&#]|$)/;
|
|
2100
|
+
const MARKLESS_ROUTE_SOURCE_QUERY_RE = /[?&]markless-route(?:[&#]|$)/;
|
|
2101
|
+
const RESUME_VIRTUAL_ID_RE = /^virtual:markless:resume:([^:]+)$/;
|
|
2102
|
+
const PRERENDER_WAKE_VIRTUAL_ID_RE = /^virtual:markless:prerender-wake:([^:]+)$/;
|
|
2103
|
+
const SETTLE_VIRTUAL_ID_RE = /^virtual:markless:settle:([^:]+)$/;
|
|
2104
|
+
const SYMBOL_VIRTUAL_STRING_RE = /(["'`])((?:virtual:markless:symbol:)[^"'`]+)\1/g;
|
|
2105
|
+
function stripBuildPrefix(fileName) {
|
|
2106
|
+
return fileName.startsWith("build/") ? fileName.slice(MARKLESS_BUILD_PREFIX.length) : fileName;
|
|
2107
|
+
}
|
|
2108
|
+
function virtualModuleSourceForLoad(module, options) {
|
|
2109
|
+
if (!options.dev || module.type !== "resolver") return module.source;
|
|
2110
|
+
if (!module.source.includes("moduleUrls[row[0]]")) return module.source;
|
|
2111
|
+
return module.source.replace(SYMBOL_VIRTUAL_STRING_RE, (_match, _quote, virtualId) => JSON.stringify(devBrowserVirtualModuleUrl(virtualId, options.publicPath)));
|
|
2112
|
+
}
|
|
2113
|
+
function devBrowserSourceModuleUrl(source, _root, publicPath) {
|
|
2114
|
+
const path = withQuery(joinURL("@fs", withoutLeadingSlash(source)), { import: null });
|
|
2115
|
+
return publicPath ? publicPath(path) : joinURL("/", path);
|
|
2116
|
+
}
|
|
2117
|
+
function devBrowserVirtualModuleUrl(virtualId, publicPath) {
|
|
2118
|
+
const path = joinURL("@id", resolveVirtualId(virtualId).replace("\0", "__x00__"));
|
|
2119
|
+
return publicPath ? publicPath(path) : joinURL("/", path);
|
|
2120
|
+
}
|
|
2121
|
+
function clientSymbolEntries(input, root) {
|
|
2122
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) return [];
|
|
2123
|
+
const sources = [];
|
|
2124
|
+
for (const [name, value] of Object.entries(input)) {
|
|
2125
|
+
if (!/symbol/i.test(name)) continue;
|
|
2126
|
+
for (const entry of inputEntryValues(value)) if (typeof entry === "string" && TSRX_SOURCE_FILE.test(entry)) sources.push(normalizeInputSource(entry, root));
|
|
2127
|
+
}
|
|
2128
|
+
return sources;
|
|
2129
|
+
}
|
|
2130
|
+
function inputEntryValues(value) {
|
|
2131
|
+
return Array.isArray(value) ? value.flatMap(inputEntryValues) : [value];
|
|
2132
|
+
}
|
|
2133
|
+
function normalizeInputSource(source, root) {
|
|
2134
|
+
const path = pathname(source);
|
|
2135
|
+
if (isAbsolute(path)) return path;
|
|
2136
|
+
return pathname(resolve(root ?? "", path));
|
|
2137
|
+
}
|
|
2138
|
+
function isSymbolOnlySourceRequest(id) {
|
|
2139
|
+
return MARKLESS_SYMBOL_SOURCE_QUERY_RE.test(id);
|
|
2140
|
+
}
|
|
2141
|
+
function isScalarPlanSourceRequest(id) {
|
|
2142
|
+
return isSymbolOnlySourceRequest(id) && new URLSearchParams(parsePath(id).search).has("markless-scalar-plans");
|
|
2143
|
+
}
|
|
2144
|
+
function isResumeSourceRequest(id) {
|
|
2145
|
+
return MARKLESS_RESUME_SOURCE_QUERY_RE.test(id);
|
|
2146
|
+
}
|
|
2147
|
+
function isRenderDataSourceRequest(id) {
|
|
2148
|
+
return MARKLESS_RENDER_DATA_SOURCE_QUERY_RE.test(id);
|
|
2149
|
+
}
|
|
2150
|
+
function renderDataReachedFromQuery(id) {
|
|
2151
|
+
return new URLSearchParams(parsePath(id).search).get(MARKLESS_REACHED_FROM_SOURCE_QUERY) ?? void 0;
|
|
2152
|
+
}
|
|
2153
|
+
/** The full render data a server-rendered app's client render loads on demand; no resume reaches it. */
|
|
2154
|
+
function isClientRenderDataEntry(id) {
|
|
2155
|
+
return normalizeVirtualId(id).startsWith(`${MARKLESS_VIRTUAL_PREFIX}${CLIENT_RENDER_DATA_ENTRY_KIND}:`);
|
|
2156
|
+
}
|
|
2157
|
+
function isRouteNavigationSourceRequest(id) {
|
|
2158
|
+
return MARKLESS_ROUTE_SOURCE_QUERY_RE.test(id) || isRenderDataSourceRequest(id) && renderDataReachedFromQuery(id) === void 0 && !isServedRenderDataRequest(id);
|
|
2159
|
+
}
|
|
2160
|
+
function materializedReachedRenderDataSource(source) {
|
|
2161
|
+
return withQuery(source, {
|
|
2162
|
+
"markless-render-data": null,
|
|
2163
|
+
[MARKLESS_REACHED_FROM_SOURCE_QUERY]: MARKLESS_REACHED_FROM_ROUTE
|
|
2164
|
+
});
|
|
2165
|
+
}
|
|
2166
|
+
function sharedReachedRenderDataRequest(id) {
|
|
2167
|
+
if (!isRenderDataSourceRequest(id)) return void 0;
|
|
2168
|
+
const reachedFrom = renderDataReachedFromQuery(id);
|
|
2169
|
+
return reachedFrom === void 0 || reachedFrom === MARKLESS_REACHED_FROM_ROUTE ? void 0 : withQuery(id, { [MARKLESS_REACHED_FROM_SOURCE_QUERY]: MARKLESS_REACHED_FROM_ROUTE });
|
|
2170
|
+
}
|
|
2171
|
+
function isPrerenderWakeSourceRequest(id) {
|
|
2172
|
+
return MARKLESS_PRERENDER_WAKE_SOURCE_QUERY_RE.test(id);
|
|
2173
|
+
}
|
|
2174
|
+
function isClientPrimarySourceRequest(id) {
|
|
2175
|
+
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));
|
|
2176
|
+
}
|
|
2177
|
+
function clientRouteArtifactReference(source) {
|
|
2178
|
+
const symbolSource = source.includes("?") ? `${source}&markless-symbols` : `${source}?markless-symbols`;
|
|
2179
|
+
const renderDataSource = source.includes("?") ? `${source}&markless-render-data` : `${source}?markless-render-data`;
|
|
2180
|
+
return [
|
|
2181
|
+
`const [symbolModule, renderDataModule] = await Promise.all([import(${JSON.stringify(symbolSource)}), import(${JSON.stringify(renderDataSource)})]);`,
|
|
2182
|
+
"const marklessRouteArtifact = {",
|
|
2183
|
+
" renderData: renderDataModule.marklessPrerenderData,",
|
|
2184
|
+
" loadSymbol: symbolModule.loadSymbol,",
|
|
2185
|
+
"};",
|
|
2186
|
+
"export default marklessRouteArtifact;"
|
|
2187
|
+
].join("\n");
|
|
2188
|
+
}
|
|
2189
|
+
function sourceForSymbolVirtualImporter(importer) {
|
|
2190
|
+
if (!importer) return null;
|
|
2191
|
+
return symbolVirtualModuleSourceFile(normalizeVirtualId(importer));
|
|
2192
|
+
}
|
|
2193
|
+
function sourceForResumeVirtualImporter(importer) {
|
|
2194
|
+
if (!importer) return null;
|
|
2195
|
+
const match = normalizeVirtualId(importer).match(RESUME_VIRTUAL_ID_RE);
|
|
2196
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
2197
|
+
}
|
|
2198
|
+
function resolverVirtualModuleSourceFile(id) {
|
|
2199
|
+
const prefix = `${MARKLESS_VIRTUAL_PREFIX}resolver:`;
|
|
2200
|
+
return id.startsWith(prefix) ? decodeURIComponent(id.slice(prefix.length)) : null;
|
|
2201
|
+
}
|
|
2202
|
+
function sourceForTriggerGroupVirtualImporter(importer) {
|
|
2203
|
+
if (!importer) return null;
|
|
2204
|
+
return triggerGroupVirtualModuleSourceFile(normalizeVirtualId(importer));
|
|
2205
|
+
}
|
|
2206
|
+
function sourceForPrerenderWakeVirtualImporter(importer) {
|
|
2207
|
+
if (!importer) return null;
|
|
2208
|
+
const match = normalizeVirtualId(importer).match(PRERENDER_WAKE_VIRTUAL_ID_RE);
|
|
2209
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
2210
|
+
}
|
|
2211
|
+
function sourceForSettleVirtualImporter(importer) {
|
|
2212
|
+
if (!importer) return null;
|
|
2213
|
+
const match = normalizeVirtualId(importer).match(SETTLE_VIRTUAL_ID_RE);
|
|
2214
|
+
return match?.[1] ? decodeURIComponent(match[1]) : null;
|
|
2215
|
+
}
|
|
2216
|
+
function isRelativeImport(source) {
|
|
2217
|
+
return source.startsWith("./") || source.startsWith("../");
|
|
2218
|
+
}
|
|
2219
|
+
function isCompilerStatefulModuleId(id) {
|
|
2220
|
+
const bare = id.startsWith("\0") ? id.slice(1) : id;
|
|
2221
|
+
return TSRX_SOURCE_FILE.test(bare) || bare.startsWith("virtual:markless:") || /[?&]markless-[a-z-]+(?:[=&#]|$)/.test(bare);
|
|
2222
|
+
}
|
|
2223
|
+
function isMarklessRuntimeModule(id) {
|
|
2224
|
+
const path = pathname(id);
|
|
2225
|
+
return /[/\\](?:web|runtime|serializer)[/\\]src[/\\].+\.ts$/.test(path);
|
|
2226
|
+
}
|
|
2227
|
+
function executionLogRuntimeModuleId(id) {
|
|
2228
|
+
const path = pathname(id);
|
|
2229
|
+
const match = path.match(/[/\\](web|runtime|serializer)[/\\]src[/\\]([^?#]+)\.ts$/);
|
|
2230
|
+
return match ? `${match[1]}:${match[2].replace(/[/\\]/g, "/")}` : path;
|
|
2231
|
+
}
|
|
2232
|
+
function normalizeVirtualId(id) {
|
|
2233
|
+
const bare = id.startsWith("\0") ? id.slice(1) : id;
|
|
2234
|
+
if (!bare.startsWith("virtual:markless:")) return bare;
|
|
2235
|
+
const queryIndex = bare.indexOf("?");
|
|
2236
|
+
const segments = (queryIndex === -1 ? bare : bare.slice(0, queryIndex)).slice(MARKLESS_VIRTUAL_PREFIX.length).split(":").map((segment) => {
|
|
2237
|
+
try {
|
|
2238
|
+
return encodeURIComponent(decodeURIComponent(segment));
|
|
2239
|
+
} catch {
|
|
2240
|
+
return segment;
|
|
2241
|
+
}
|
|
2242
|
+
});
|
|
2243
|
+
return `${MARKLESS_VIRTUAL_PREFIX}${segments.join(":")}`;
|
|
2244
|
+
}
|
|
2245
|
+
function emittedBundleModuleIds(bundle) {
|
|
2246
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2247
|
+
for (const output of Object.values(bundle)) {
|
|
2248
|
+
if (!output || typeof output !== "object") continue;
|
|
2249
|
+
const chunk = output;
|
|
2250
|
+
if (chunk.type !== "chunk") continue;
|
|
2251
|
+
if (typeof chunk.facadeModuleId === "string") ids.add(normalizeVirtualId(chunk.facadeModuleId));
|
|
2252
|
+
if (Array.isArray(chunk.moduleIds)) {
|
|
2253
|
+
for (const id of chunk.moduleIds) if (typeof id === "string") ids.add(normalizeVirtualId(id));
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
return ids;
|
|
2257
|
+
}
|
|
2258
|
+
function resolveVirtualId(id) {
|
|
2259
|
+
if (id.startsWith("\0")) return id;
|
|
2260
|
+
return `\0${id}`;
|
|
2261
|
+
}
|
|
2262
|
+
function pathname(id) {
|
|
2263
|
+
return parsePath(id).pathname;
|
|
2264
|
+
}
|
|
2265
|
+
const CLIENT_ONLY_SOURCE_QUERY_KEYS = /* @__PURE__ */ new Set([
|
|
2266
|
+
"markless-render-data",
|
|
2267
|
+
"markless-reached-from",
|
|
2268
|
+
MARKLESS_SERVED_RENDER_DATA_QUERY,
|
|
2269
|
+
"markless-symbols",
|
|
2270
|
+
"markless-scalar-plans"
|
|
2271
|
+
]);
|
|
2272
|
+
function serverSharedSourceRequest(id, environment) {
|
|
2273
|
+
if (environment !== "server") return void 0;
|
|
2274
|
+
const { pathname: path, search } = parsePath(id);
|
|
2275
|
+
if (!search || !TSRX_SOURCE_FILE.test(path)) return void 0;
|
|
2276
|
+
const keys = [...new URLSearchParams(search).keys()];
|
|
2277
|
+
return keys.length > 0 && keys.every((key) => CLIENT_ONLY_SOURCE_QUERY_KEYS.has(key)) ? path : void 0;
|
|
2278
|
+
}
|
|
2279
|
+
//#endregion
|
|
2280
|
+
//#region src/build/planned-landing.ts
|
|
2281
|
+
const MARKLESS_INTERACTION_CLOSURES_ASSET = MARKLESS_INTERACTION_CLOSURES;
|
|
2282
|
+
function plannedLandingFiles(bundle) {
|
|
2283
|
+
const asset = bundle[MARKLESS_INTERACTION_CLOSURES_ASSET];
|
|
2284
|
+
if (asset?.type !== "asset" || asset.source === void 0) return void 0;
|
|
2285
|
+
const parsed = JSON.parse(typeof asset.source === "string" ? asset.source : new TextDecoder().decode(asset.source));
|
|
2286
|
+
const planned = /* @__PURE__ */ new Map();
|
|
2287
|
+
for (const route of parsed.routes) if (!route.fallback && route.files) planned.set(route.route, new Set(route.files.firstUse));
|
|
2288
|
+
return planned;
|
|
2289
|
+
}
|
|
2290
|
+
//#endregion
|
|
2291
|
+
export { MARKLESS_INTERACTION_CLOSURES as $, sharedReachedRenderDataRequest as A, stripEmittedTypes as B, materializedReachedRenderDataSource as C, resolveVirtualId as D, renderDataReachedFromQuery as E, sourceForTriggerGroupVirtualImporter as F, PropFlowRegistry as G, transformTsrxModule as H, stripBuildPrefix as I, MARKLESS_BUILD_PREFIX as J, isServedRenderDataRequest as K, virtualModuleSourceForLoad as L, sourceForResumeVirtualImporter as M, sourceForSettleVirtualImporter as N, resolverVirtualModuleSourceFile as O, sourceForSymbolVirtualImporter as P, MARKLESS_EXECUTION_SIZES as Q, marklessVirtualModuleSourceFile as R, isSymbolOnlySourceRequest as S, pathname as T, transformTsrxModuleWithPrerenderWakeClosure as U, transformCompileInput as V, usePersistentStrippedCode as W, MARKLESS_BYTE_ATTRIBUTION as X, MARKLESS_BUNDLE_GRAPH as Y, MARKLESS_EXECUTION_DEMAND as Z, isRelativeImport as _, TSRX_SOURCE_FILE as a, optimizedDepsToInclude as at, isRouteNavigationSourceRequest as b, devBrowserSourceModuleUrl as c, planModulePreloads as ct, executionLogRuntimeModuleId as d, MARKLESS_PUBLIC_BUILD_METADATA_FILES as et, isClientPrimarySourceRequest as f, isPrerenderWakeSourceRequest as g, isMarklessRuntimeModule as h, STRING_EXPORT_QUERY as i, includeOptimizedDeps as it, sourceForPrerenderWakeVirtualImporter as j, serverSharedSourceRequest as k, devBrowserVirtualModuleUrl as l, isCompilerStatefulModuleId as m, plannedLandingFiles as n, RUNTIME_FUNCTIONS_PREFIX as nt, clientRouteArtifactReference as o, runtimeFunctionSpecifiers as ot, isClientRenderDataEntry as p, MARKLESS_BUILD_METADATA_FILES as q, MARKLESS_ROUTE_SOURCE_QUERY_RE as r, excludeSourceShippedDeps as rt, clientSymbolEntries as s, planModulePreloadUrls as st, MARKLESS_INTERACTION_CLOSURES_ASSET as t, outputDefaults as tt, emittedBundleModuleIds as u, isRenderDataSourceRequest as v, normalizeVirtualId as w, isScalarPlanSourceRequest as x, isResumeSourceRequest as y, preflightTsrxModuleDiagnostics as z };
|