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