@markless/bundler 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.js CHANGED
@@ -1,19 +1,25 @@
1
+ import { i as persistentCompileCacheAvailable, n as compilerFingerprint, r as createPersistentCompileCache } from "./compile-store-DxF9Vj4_.js";
1
2
  import { a as MARKLESS_DEV_RELOADS_ATTRIBUTE, d as renderMarklessDevErrorDocument, i as MARKLESS_DEV_PAGE_EDIT_EVENT, n as MARKLESS_DEV_ERROR_CLIENT_ID, o as MARKLESS_DEV_RELOADS_EVENT, r as MARKLESS_DEV_ERROR_EVENT, t as MARKLESS_DEV_ERROR_CLEAR_EVENT, u as normalizeMarklessDevError } from "./dev-error-BEduK_R3.js";
2
- import { N as pathname, R as sharedReachedRenderDataRequest, at as outputDefaults, ct as STORAGE_FREE_RESUME_ENTRY_SPECIFIER, kt as executionLogActivationInjection, st as RESUME_ENTRY_SPECIFIER, t as MARKLESS_DEFERRED_PACK } from "./route-pack-groups-BLS6xeVV.js";
3
- import { n as includeOptimizedDeps, t as excludeSourceShippedDeps } from "./optimized-deps-BfzxSm6C.js";
4
- import { A as INLINE_DEFER_LOADER_SOURCE, D as prefetchChunkParses, M as inlineDeferSource, N as moduleIdFor, O as preflightTsrxModuleDiagnostics, _ as createPreloadGraphAdder, a as collapseInitFacadeImports, d as nativePackingEnabled, f as nativePackingPlugins, h as withUndemandedReExportDoors, j as createInlineDeferTriggerSource, l as marklessRuntimeSpecifierId, m as undemandedRuntimeModules, o as unwrapAsyncImportWrappers, p as isReExportDoor, t as createMarklessRolldownPlugin, u as DEPRECATED_NATIVE_PACKING_WARNING, v as entryReachableModuleIds, y as runtimeModuleIdFromOrigin } from "./rolldown-BMQrr9-Y.js";
3
+ import { A as sharedReachedRenderDataRequest, T as pathname, W as usePersistentStrippedCode, i as STRING_EXPORT_QUERY, it as includeOptimizedDeps, m as isCompilerStatefulModuleId, ot as runtimeFunctionSpecifiers, rt as excludeSourceShippedDeps, tt as outputDefaults, z as preflightTsrxModuleDiagnostics } from "./planned-landing-BHy22Yf5.js";
4
+ import { C as MARKLESS_VIRTUAL_PREFIX, Q as PROTOCOL_BLOCK_START_COMMENT, T as STORAGE_FREE_RESUME_ENTRY_SPECIFIER, X as createInlineDeferTriggerSource, Y as INLINE_DEFER_LOADER_SOURCE, Z as inlineDeferSource, f as PACK_COST_MODEL, h as moduleIdFor, rt as executionLogActivationInjection, t as MARKLESS_DEFERRED_PACK, w as RESUME_ENTRY_SPECIFIER } from "./route-pack-groups-ByQmKKom.js";
5
+ import { o as clearChunkFactCaches } from "./chunk-ast-pN_P5wIo.js";
6
+ import { a as collapseInitFacadeImports, b as runtimeModuleIdFromOrigin, c as marklessRuntimeSpecifierId, d as nativePackingPlugins, f as isReExportDoor, g as isPlannedCoLocation, h as dynamicImportersOf, l as DEPRECATED_NATIVE_PACKING_WARNING, m as withUndemandedReExportDoors, p as undemandedRuntimeModules, t as createMarklessRolldownPlugin, u as nativePackingEnabled, v as createPreloadGraphAdder, y as entryReachableModuleIds } from "./rolldown-DS8OY1i9.js";
7
+ import { a as createCompileWorkerPool, i as buildWorkerCount, n as prefetchChunkDynamicImports, u as unwrapAsyncImportWrappers } from "./lazy-module-facades-qZajWDD8.js";
5
8
  import { n as marklessRosterPositions, r as marklessRosterRenderContext, t as marklessRosterPositionSeeds } from "./shared-seed-slot-ihIVCD2S.js";
9
+ import { DEBUGGING_PLAYBOOK_HINT, evaluateModuleConstants, parseJavaScriptModule, useCompileRunner, usePersistentCompileStore } from "@markless/compiler";
10
+ import { readFileSync } from "node:fs";
11
+ import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
12
+ import { builtinModules } from "node:module";
13
+ import { isAbsolute, join, relative, resolve } from "pathe";
6
14
  import { joinURL, parsePath, withQuery } from "ufo";
7
15
  import { ASYNC_PROTOCOL_VERSION, PROTOCOL_CONTAINER_HOST_NODE_ID, STORAGE_SLOT_SYMBOL_KEY, escapeScriptJson, serializeRuntimeAsyncSnapshots, serializeRuntimeStateCells, storageAttributeName, storageCookieName, storageSlotEntryKeyFromGraphNodeId } from "@markless/serializer";
8
- import { isAbsolute, join, resolve } from "pathe";
9
- import { DEBUGGING_PLAYBOOK_HINT } from "@markless/compiler";
10
- import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
11
- import { isAbsolute as isAbsolute$1 } from "node:path";
12
16
  import { pathToFileURL } from "node:url";
13
- import { createServerModuleRunner, isRunnableDevEnvironment } from "vite";
14
17
  import { tmpdir } from "node:os";
18
+ import { isAbsolute as isAbsolute$1 } from "node:path";
19
+ import { createServerModuleRunner, isCSSRequest, isRunnableDevEnvironment } from "vite";
15
20
  import { PROTOCOL_CONTAINER_END_COMMENT, PROTOCOL_CONTAINER_START_COMMENT, PROTOCOL_EVENT_ACTION_KIND as PROTOCOL_EVENT_ACTION_KIND$1, PROTOCOL_EVENT_HOST_ATTRIBUTE, PROTOCOL_EVENT_HOST_DELEGATED_REF, PROTOCOL_IDLE_EVENT_NAME as PROTOCOL_IDLE_EVENT_NAME$1, PROTOCOL_LOCATOR_PATHS_ATTRIBUTE, PROTOCOL_SYNC_POLICY_TABLE_TYPE, PROTOCOL_VISIBLE_EVENT_NAME, constantSyncPolicyCode, formatEventHostEntries, protocolEventDispatchesMarkless, syncPolicyNeverActs } from "@markless/serializer/protocol";
16
21
  import "@markless/serializer/resume-record-delta";
22
+ import { analyze } from "yuku/analyzer";
17
23
  //#region ../web/src/inline/served-census.ts
18
24
  /**
19
25
  * Pins the container's elements in DOM order as its census and returns them,
@@ -39,7 +45,24 @@ function marklessServedCensus(root, attribute) {
39
45
  return value && (parseInt(value) !== live.length || order && order !== (signature >>> 0).toString(36)) ? (root.__marklessShifted = 1, []) : live;
40
46
  }
41
47
  //#endregion
48
+ //#region ../serializer/src/protocol-record-keys.ts
49
+ /** The field names each templated record list may spell, in the order its templates index them. */
50
+ const PROTOCOL_RECORD_KEYS = {
51
+ "markless/state": {
52
+ computed: "graphNodeId name async deriveSymbolId value version root $type $ref source flags records id type fields items entries values bytes arrayType buffer byteOffset length byteLength directValue dependencies path snapshot status key error hostScope",
53
+ sharedSeeds: "graphNodeId deriveSymbolId dependencies path reads",
54
+ sharedDefinitions: "id name exportedName scope version graphNodeIds projectionIds dependencies definitionId definitionName returnProperties kind graphNodeId path"
55
+ },
56
+ "markless/view": {
57
+ domUpdates: "hostNodeId source graphNodeId path target kind prefix suffix trueValue falseValue textNode name constantClass leadingClass symbolId",
58
+ behaviors: "hostNodeId source functionSource inputSources inputValues inputGraphReads inputIndex graphNodeId path symbolId usesGraph",
59
+ elementHandles: "hostNodeId handleId name plural"
60
+ }
61
+ };
62
+ //#endregion
42
63
  //#region ../web/src/inline/resumer.ts
64
+ const listKeys = (type, list) => PROTOCOL_RECORD_KEYS[type][list] ?? "";
65
+ listKeys("markless/state", "cells"), listKeys("markless/state", "sharedRecords"), listKeys("markless/view", "events");
43
66
  const withPageMarkers = (source) => source.replaceAll("__MARKLESS_PAGE_START__", JSON.stringify(PROTOCOL_CONTAINER_START_COMMENT)).replaceAll("__MARKLESS_PAGE_END__", JSON.stringify(PROTOCOL_CONTAINER_END_COMMENT));
44
67
  const servedCensusSource = () => withPageMarkers(marklessServedCensus.toString());
45
68
  PROTOCOL_EVENT_ACTION_KIND$1.event, PROTOCOL_EVENT_ACTION_KIND$1.externalDelegate;
@@ -163,11 +186,13 @@ function runPrerenderInlineResumer(eventNames, fallbackResumeModuleUrl, loadModu
163
186
  const root = currentScript?.closest("[data-async-container]");
164
187
  const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
165
188
  if (!root || !resumeModuleUrl) return;
189
+ const life = root.__mL ||= {};
166
190
  let loaded;
167
191
  const dispatch = (event) => {
192
+ if (root.__mL !== life) return root.removeEventListener(event.type, dispatch, true);
168
193
  root.__marklessDelegatedDispatch = true;
169
194
  if (!root.__marklessCensus) census(root, pathsAttribute);
170
- return (loaded ||= loadModule(resumeModuleUrl)).then((module) => module.resumeContainerEvent({
195
+ return (loaded ||= loadModule(resumeModuleUrl)).then((module) => root.__mL === life && module.resumeContainerEvent({
171
196
  root,
172
197
  event,
173
198
  element: event.target,
@@ -181,10 +206,12 @@ function runInlineResumerSelfWake(fallbackResumeModuleUrl, loadModule, defer) {
181
206
  const root = currentScript?.closest("[data-async-container]");
182
207
  const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
183
208
  if (!root || !resumeModuleUrl) return;
209
+ const life = root.__mL ||= {};
184
210
  defer.idle(root, async () => {
185
- if (root.__asyncResumeRuntimeStarted) return;
211
+ if (root.__asyncResumeRuntimeStarted || root.__mL !== life) return;
186
212
  root.__marklessDelegatedDispatch = true;
187
- await (await (root.__mResume ||= loadModule(resumeModuleUrl))).resumeContainerEvent({
213
+ const module = await (root.__mResume ||= loadModule(resumeModuleUrl));
214
+ if (root.__mL === life) await module.resumeContainerEvent({
188
215
  root,
189
216
  event: 0
190
217
  });
@@ -195,8 +222,9 @@ function runInlineResumerOverlayPrimer(fallbackResumeModuleUrl, loadModule) {
195
222
  const root = currentScript?.closest("[data-async-container]");
196
223
  const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
197
224
  if (!root || !resumeModuleUrl) return;
225
+ const life = root.__mL ||= {};
198
226
  const prime = (event) => {
199
- if (root.__marklessOverlayInstalled) {
227
+ if (root.__marklessOverlayInstalled || root.__mL !== life) {
200
228
  removeEventListener("keydown", prime, true);
201
229
  removeEventListener("pointerdown", prime, true);
202
230
  return;
@@ -213,9 +241,9 @@ function runInlineResumerOverlayPrimer(fallbackResumeModuleUrl, loadModule) {
213
241
  root.__marklessCensus = census;
214
242
  }
215
243
  setTimeout(() => {
216
- if (root.__marklessDelegatedDispatch === true) return;
244
+ if (root.__marklessDelegatedDispatch === true || root.__mL !== life) return;
217
245
  root.__marklessDelegatedDispatch = true;
218
- loadModule(resumeModuleUrl).then((module) => module.resumeContainerEvent({
246
+ loadModule(resumeModuleUrl).then((module) => root.__mL === life && module.resumeContainerEvent({
219
247
  root,
220
248
  event: 0
221
249
  }));
@@ -370,11 +398,24 @@ function servedElementTree(html) {
370
398
  const elements = [{
371
399
  tag: "",
372
400
  parent: -1,
373
- child: 0
401
+ child: 0,
402
+ node: 0
374
403
  }];
375
404
  const childCounts = [0];
405
+ const nodeCounts = [0];
406
+ const inText = [false];
407
+ const current = () => stack.length ? stack[stack.length - 1].index : 0;
408
+ const node = (parent, text) => {
409
+ if (templateDepth > 0 || text && inText[parent]) return;
410
+ nodeCounts[parent]++;
411
+ inText[parent] = text;
412
+ };
376
413
  const commentElementIndexes = [];
377
414
  const nameEnds = [0];
415
+ const addressSteps = [[]];
416
+ const blockSteps = /* @__PURE__ */ new Map();
417
+ const openBlocks = [[]];
418
+ const stepsOf = (parent) => openBlocks[parent].at(-1)?.steps ?? addressSteps[parent];
378
419
  const stack = [];
379
420
  let templateDepth = 0;
380
421
  let foreignDepth = 0;
@@ -383,11 +424,28 @@ function servedElementTree(html) {
383
424
  while (at < html.length) {
384
425
  const open = html.indexOf("<", at);
385
426
  if (open < 0) break;
427
+ if (open > at) node(current(), true);
386
428
  if (html.startsWith("<!--", open)) {
429
+ node(current(), false);
387
430
  const end = html.indexOf("-->", open + 4);
388
431
  at = end < 0 ? html.length : end + 3;
389
432
  const data = html.slice(open + 4, end < 0 ? html.length : end);
390
- if (templateDepth === 0 && !isArmBranchAnchorComment({
433
+ if (templateDepth > 0) continue;
434
+ const parent = current();
435
+ if (openBlocks[parent].at(-1)?.end === data) openBlocks[parent].pop();
436
+ else if (PROTOCOL_BLOCK_START_COMMENT.test(data)) {
437
+ const steps = [];
438
+ stepsOf(parent).push(-1);
439
+ openBlocks[parent].push({
440
+ end: `/${data}`,
441
+ steps
442
+ });
443
+ if (!isArmBranchAnchorComment({
444
+ nodeType: 8,
445
+ data
446
+ })) blockSteps.set(commentElementIndexes.length, steps);
447
+ }
448
+ if (!isArmBranchAnchorComment({
391
449
  nodeType: 8,
392
450
  data
393
451
  })) commentElementIndexes.push(elements.length);
@@ -395,6 +453,7 @@ function servedElementTree(html) {
395
453
  }
396
454
  const next = html[open + 1] ?? "";
397
455
  if (next === "!" || next === "?") {
456
+ node(current(), false);
398
457
  const end = html.indexOf(">", open);
399
458
  at = end < 0 ? html.length : end + 1;
400
459
  continue;
@@ -403,6 +462,7 @@ function servedElementTree(html) {
403
462
  const nameStart = closing ? open + 2 : open + 1;
404
463
  const nameMatch = /^[a-zA-Z][^\s/>]*/.exec(html.slice(nameStart, nameStart + 64));
405
464
  if (!nameMatch) {
465
+ node(current(), true);
406
466
  at = open + 1;
407
467
  continue;
408
468
  }
@@ -428,10 +488,17 @@ function servedElementTree(html) {
428
488
  index = elements.push({
429
489
  tag,
430
490
  parent,
431
- child: childCounts[parent]++
491
+ child: childCounts[parent]++,
492
+ node: nodeCounts[parent]
432
493
  }) - 1;
494
+ node(parent, false);
495
+ stepsOf(parent).push(index);
433
496
  childCounts.push(0);
497
+ nodeCounts.push(0);
498
+ inText.push(false);
434
499
  nameEnds.push(nameStart + name.length);
500
+ addressSteps.push([]);
501
+ openBlocks.push([]);
435
502
  }
436
503
  if (VOID_TAGS.has(lower) || selfClosing) continue;
437
504
  if (PROTOCOL_RAW_TEXT_TAGS.has(lower)) {
@@ -450,7 +517,9 @@ function servedElementTree(html) {
450
517
  elements,
451
518
  childCounts,
452
519
  commentElementIndexes,
453
- nameEnds
520
+ nameEnds,
521
+ addressSteps,
522
+ blockSteps
454
523
  };
455
524
  }
456
525
  /** Writes `attribute="value"` on each element the map names by its index in servedElementTree(html). */
@@ -553,7 +622,7 @@ async function assemblePrerenderPageParts(component, output, options) {
553
622
  }
554
623
  async function renderSsrOutput(component, props, renderContext) {
555
624
  assertPageRenderable(component);
556
- globalThis.__marklessRosterResume ??= () => import("./roster-resume-CpphsFl_.js");
625
+ globalThis.__marklessRosterResume ??= () => import("./roster-resume-DXptD6DG.js");
557
626
  const context = marklessSsrRosterPositionContext(renderContext);
558
627
  if (typeof component === "function") return marklessSsrRosterCounted(context, await marklessSsrDeferredCounted(context, await component(props, context)));
559
628
  if (component && typeof component.renderSsr === "function") return marklessSsrRosterCounted(context, await marklessSsrDeferredCounted(context, await component.renderSsr(props, context)));
@@ -718,8 +787,64 @@ function addEventHostEntry(marks, index, entry) {
718
787
  const entries = marks.get(index);
719
788
  if (!entries) return void marks.set(index, [entry]);
720
789
  const same = entries.findIndex((candidate) => candidate.name === entry.name);
721
- if (same < 0) entries.push(entry);
722
- else if (entries[same].ref === void 0 && entry.ref !== void 0) entries[same] = entry;
790
+ if (same < 0) return void entries.push(entry);
791
+ const held = entries[same];
792
+ entries[same] = {
793
+ ...held,
794
+ ...held.ref === void 0 && entry.ref !== void 0 ? { ref: entry.ref } : {},
795
+ ...held.policy === void 0 && entry.policy !== void 0 ? { policy: entry.policy } : {}
796
+ };
797
+ }
798
+ const childLists = /* @__PURE__ */ new WeakMap();
799
+ function addRowPolicyMarks(marks, tree, parent, repeat, policyTable) {
800
+ if (repeat.rowEndOffset === void 0) return;
801
+ const events = repeat.rowEvents.flatMap((event) => {
802
+ const policy = policyTable.entry(event.syncPolicy);
803
+ return policy === void 0 ? [] : [{
804
+ ...event,
805
+ policy
806
+ }];
807
+ });
808
+ if (!events.length) return;
809
+ const rows = servedChildren(tree, parent);
810
+ for (const row of rows.slice(repeat.rowStartOffset ?? 0, rows.length - repeat.rowEndOffset)) for (const event of events) {
811
+ const host = event.hostPath.length ? servedElementAt(tree, tree.addressSteps[row], event.hostPath) : row;
812
+ if (host !== void 0) addEventHostEntry(marks, host, {
813
+ name: event.eventName,
814
+ policy: event.policy
815
+ });
816
+ }
817
+ }
818
+ function servedChildren(tree, of) {
819
+ let lists = childLists.get(tree);
820
+ if (!lists) {
821
+ lists = tree.elements.map(() => []);
822
+ tree.elements.forEach((element, index) => index && lists.at(element.parent).push(index));
823
+ childLists.set(tree, lists);
824
+ }
825
+ return lists[of];
826
+ }
827
+ function servedElementAt(tree, steps, address) {
828
+ let host;
829
+ for (const step of address) {
830
+ host = steps?.at(step);
831
+ steps = host === void 0 || host < 0 ? void 0 : tree.addressSteps[host];
832
+ }
833
+ return host === void 0 || host < 0 ? void 0 : host;
834
+ }
835
+ function addPaintedArmPolicyMarks(marks, tree, branch, policyTable) {
836
+ const taken = branch.takenArm;
837
+ const set = taken === void 0 ? void 0 : branch.armRecords?.[taken];
838
+ const steps = tree.blockSteps.get(branch.startAnchor.index);
839
+ if (!set || !steps) return;
840
+ for (const event of set.events) {
841
+ const policy = policyTable.entry(event.syncPolicy);
842
+ const host = servedElementAt(tree, steps, event.hostPath);
843
+ if (policy !== void 0 && host !== void 0) addEventHostEntry(marks, host, {
844
+ name: event.eventName,
845
+ policy
846
+ });
847
+ }
723
848
  }
724
849
  function writeEventHostMarks(html, nameEnds, marks) {
725
850
  return marks.size ? withElementAttributes(html, nameEnds, PROTOCOL_EVENT_HOST_ATTRIBUTE, new Map([...marks].map(([index, entries]) => [index, formatEventHostEntries(entries)]))) : html;
@@ -750,6 +875,7 @@ function withEventHostMarks(view, html, policyTable) {
750
875
  const index = shell.get(repeat.parentHostNodeId);
751
876
  if (index === void 0) continue;
752
877
  for (const event of repeat.rowEvents) addEventHostEntry(marks, index, { name: event.eventName });
878
+ addRowPolicyMarks(marks, tree, index, repeat, policyTable);
753
879
  }
754
880
  for (const [anchor, records] of [...view.asyncBoundaries.map((boundary) => [boundary.startAnchor, boundary.armRecords]), ...(view.branches ?? []).map((branch) => [branch.startAnchor, branch.servedArmRecords])]) {
755
881
  if (!records || Array.isArray(records)) continue;
@@ -766,7 +892,12 @@ function withEventHostMarks(view, html, policyTable) {
766
892
  policy
767
893
  });
768
894
  }
895
+ for (const repeat of set.keyedRepeats ?? []) {
896
+ const index = arm.get(repeat.parentHostNodeId);
897
+ if (index !== void 0) addRowPolicyMarks(marks, tree, offset + index, repeat, policyTable);
898
+ }
769
899
  }
900
+ for (const branch of view.branches ?? []) if (!branch.servedArmRecords) addPaintedArmPolicyMarks(marks, tree, branch, policyTable);
770
901
  return writeEventHostMarks(html, tree.nameEnds, marks);
771
902
  }
772
903
  function renderSyncPolicyTableScript(policies) {
@@ -1378,6 +1509,7 @@ function deferredRuntimePacks(input) {
1378
1509
  }
1379
1510
  function deferredRuntimePlugin(demandMaps) {
1380
1511
  let packs = /* @__PURE__ */ new Map();
1512
+ let dynamicImporters = /* @__PURE__ */ new Map();
1381
1513
  return {
1382
1514
  name: "markless:deferred-runtime",
1383
1515
  options(input) {
@@ -1388,6 +1520,7 @@ function deferredRuntimePlugin(demandMaps) {
1388
1520
  },
1389
1521
  buildEnd(error) {
1390
1522
  packs = /* @__PURE__ */ new Map();
1523
+ dynamicImporters = /* @__PURE__ */ new Map();
1391
1524
  if (error) return;
1392
1525
  const modules = /* @__PURE__ */ new Map();
1393
1526
  for (const id of entryReachableModuleIds(this)) {
@@ -1406,6 +1539,10 @@ function deferredRuntimePlugin(demandMaps) {
1406
1539
  moduleIds: modules.keys()
1407
1540
  })
1408
1541
  });
1542
+ dynamicImporters = dynamicImportersOf(modules);
1543
+ },
1544
+ onLog(_level, log) {
1545
+ if (isPlannedCoLocation(log, (id) => packs.get(id), dynamicImporters)) return false;
1409
1546
  },
1410
1547
  outputOptions(output) {
1411
1548
  if (typeof output.codeSplitting !== "object") return null;
@@ -1414,6 +1551,7 @@ function deferredRuntimePlugin(demandMaps) {
1414
1551
  codeSplitting: {
1415
1552
  ...output.codeSplitting,
1416
1553
  groups: [{
1554
+ debugName: "markless-deferred-runtime",
1417
1555
  name: (id) => packs.get(id) ?? null,
1418
1556
  priority: 1e3,
1419
1557
  includeDependenciesRecursively: false
@@ -2167,6 +2305,590 @@ function installDevRuntimeImportResolution(server, clientEnvironment) {
2167
2305
  }
2168
2306
  }
2169
2307
  //#endregion
2308
+ //#region src/vite/browser-node-guard.ts
2309
+ const NODE_IN_BROWSER_ERROR = "MARKLESS_NODE_IN_BROWSER";
2310
+ const VITE_BROWSER_EXTERNAL = "__vite-browser-external";
2311
+ const OPTIMIZER_BROWSER_EXTERNAL = "browser-external:";
2312
+ const builtinNames = builtinModules.filter((name) => !name.includes(":"));
2313
+ const escape = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2314
+ /** Specifiers that name a Node built-in: `node:*`, `bun:*`, or a bare built-in and its subpaths. */
2315
+ const NODE_BUILTIN_SPECIFIER = new RegExp(`^(?:node:|bun:|(?:${builtinNames.map(escape).join("|")})(?:/|$))`);
2316
+ function isNodeBuiltinSpecifier(specifier) {
2317
+ return NODE_BUILTIN_SPECIFIER.test(specifier);
2318
+ }
2319
+ /** Free names that only exist in Node; a browser throws a ReferenceError on any of them. */
2320
+ const NODE_ONLY_GLOBALS = [
2321
+ "process",
2322
+ "Buffer",
2323
+ "global",
2324
+ "__dirname",
2325
+ "__filename",
2326
+ "require"
2327
+ ];
2328
+ const NODE_GLOBAL_WORD = new RegExp(`\\b(?:${NODE_ONLY_GLOBALS.join("|")})\\b`);
2329
+ function parsed(code) {
2330
+ for (const options of [
2331
+ {
2332
+ lang: "js",
2333
+ sourceType: "module"
2334
+ },
2335
+ {
2336
+ lang: "js",
2337
+ sourceType: "commonjs"
2338
+ },
2339
+ {
2340
+ lang: "ts",
2341
+ sourceType: "module"
2342
+ }
2343
+ ]) {
2344
+ const module = analyze(code, options);
2345
+ if (!module.diagnostics.some((diagnostic) => diagnostic.severity === "error")) return module;
2346
+ }
2347
+ }
2348
+ function contains(outer, inner) {
2349
+ return !!outer && outer.start <= inner.start && inner.end <= outer.end;
2350
+ }
2351
+ function testsTypeof(module, test, name) {
2352
+ if (!test) return false;
2353
+ return module.unresolvedReferences.some((reference) => {
2354
+ const node = reference.node;
2355
+ if (reference.name !== name || !contains(test, node)) return false;
2356
+ const parent = module.parentOf(reference.node);
2357
+ return parent?.type === "UnaryExpression" && parent.operator === "typeof";
2358
+ });
2359
+ }
2360
+ function allowedUse(module, reference) {
2361
+ const node = reference.node;
2362
+ const parent = module.parentOf(reference.node);
2363
+ if (parent?.type === "UnaryExpression" && parent.operator === "typeof") return true;
2364
+ const name = reference.name;
2365
+ if (name === "process" && parent?.type === "MemberExpression" && parent.object === reference.node && !parent.computed && parent.property.name === "env") return true;
2366
+ if (name === "require" && parent?.type === "CallExpression" && parent.callee === reference.node && parent.arguments.length === 1 && parent.arguments[0].type === "Literal" && typeof parent.arguments[0].value === "string") return true;
2367
+ for (const ancestor of module.ancestors(reference.node)) {
2368
+ if (ancestor === node) continue;
2369
+ if ((ancestor.type === "ConditionalExpression" || ancestor.type === "IfStatement") && !contains(ancestor.test, node) && testsTypeof(module, ancestor.test, name)) return true;
2370
+ if (ancestor.type === "LogicalExpression" && contains(ancestor.right, node) && testsTypeof(module, ancestor.left, name)) return true;
2371
+ }
2372
+ return false;
2373
+ }
2374
+ function lineAndColumn(code, offset) {
2375
+ let line = 1;
2376
+ let lineStart = 0;
2377
+ for (let index = code.indexOf("\n"); index !== -1 && index < offset; index = code.indexOf("\n", index + 1)) {
2378
+ line++;
2379
+ lineStart = index + 1;
2380
+ }
2381
+ const lineEnd = code.indexOf("\n", offset);
2382
+ return {
2383
+ line,
2384
+ column: offset - lineStart + 1,
2385
+ code: code.slice(lineStart, lineEnd === -1 ? void 0 : lineEnd).trim().slice(0, 120)
2386
+ };
2387
+ }
2388
+ /**
2389
+ * The places `code` uses a Node-only global a browser does not have. `typeof X`, a branch that runs
2390
+ * only after testing `typeof X`, `process.env` (Vite replaces it, Vitest's browser runner provides
2391
+ * it) and a literal `require("x")` (the bundler resolves it) are allowed.
2392
+ */
2393
+ function nodeGlobalUses(code) {
2394
+ if (!NODE_GLOBAL_WORD.test(code)) return [];
2395
+ const module = parsed(code);
2396
+ if (!module) return [];
2397
+ const uses = [];
2398
+ for (const reference of module.unresolvedReferences) {
2399
+ if (!NODE_ONLY_GLOBALS.includes(reference.name)) continue;
2400
+ if (reference.inTypePosition) continue;
2401
+ if (allowedUse(module, reference)) continue;
2402
+ const node = reference.node;
2403
+ uses.push({
2404
+ name: reference.name,
2405
+ ...lineAndColumn(code, node.start)
2406
+ });
2407
+ }
2408
+ return uses;
2409
+ }
2410
+ /** The shortest import chain from an entry to `id`, entry first; a link is `dynamic` when reached by `import()`. */
2411
+ function importChain(graph, id) {
2412
+ const reachedFrom = /* @__PURE__ */ new Map([[id, null]]);
2413
+ const queue = [id];
2414
+ let root = id;
2415
+ for (let index = 0; index < queue.length; index++) {
2416
+ const current = queue[index];
2417
+ const { static: staticImporters, dynamic } = graph.importers(current);
2418
+ if (graph.isEntry(current) || staticImporters.length === 0 && dynamic.length === 0) {
2419
+ root = current;
2420
+ break;
2421
+ }
2422
+ for (const [importers, isDynamic] of [[staticImporters, false], [dynamic, true]]) for (const importer of importers) {
2423
+ if (reachedFrom.has(importer)) continue;
2424
+ reachedFrom.set(importer, {
2425
+ toward: current,
2426
+ dynamic: isDynamic
2427
+ });
2428
+ queue.push(importer);
2429
+ }
2430
+ }
2431
+ const chain = [{
2432
+ id: root,
2433
+ dynamic: false
2434
+ }];
2435
+ for (let step = reachedFrom.get(root); step; step = reachedFrom.get(step.toward)) chain.push({
2436
+ id: step.toward,
2437
+ dynamic: step.dynamic
2438
+ });
2439
+ return chain;
2440
+ }
2441
+ function displayId(id, root) {
2442
+ const clean = id.replace(/^\0/, "").replace(/\?.*$/, "");
2443
+ const relativeToRoot = (path) => path.startsWith("/") && root ? relative(root, path) : path;
2444
+ if (clean.startsWith("virtual:markless:")) {
2445
+ const [kind = "", ...source] = clean.slice(MARKLESS_VIRTUAL_PREFIX.length).split(":");
2446
+ return `${relativeToRoot(decodeURIComponent(source.join(":")))} (Markless ${kind.replaceAll("-", " ")} module)`;
2447
+ }
2448
+ return relativeToRoot(clean);
2449
+ }
2450
+ const FINDING_ORDER = {
2451
+ builtin: 0,
2452
+ "browser-field": 1,
2453
+ global: 2
2454
+ };
2455
+ function compareFindings(a, b) {
2456
+ if (a.kind !== b.kind) return FINDING_ORDER[a.kind] - FINDING_ORDER[b.kind];
2457
+ if (a.kind === "global" && b.kind === "global") return a.use.line - b.use.line || a.use.column - b.use.column;
2458
+ if (a.kind === "builtin" && b.kind === "builtin") return a.specifier < b.specifier ? -1 : a.specifier > b.specifier ? 1 : 0;
2459
+ return 0;
2460
+ }
2461
+ function describeFinding(violation) {
2462
+ switch (violation.kind) {
2463
+ case "builtin": return `imports "${violation.specifier}", a Node built-in module`;
2464
+ case "browser-field": return "imports a module its package removes from browser builds (its package.json \"browser\" field maps it to false)";
2465
+ case "global": return `uses \`${violation.use.name}\` at ${violation.use.line}:${violation.use.column}, a global only Node has: ${violation.use.code}`;
2466
+ }
2467
+ }
2468
+ /** The error a browser build fails with: each import chain once, what its last module does, then how to fix it. */
2469
+ function nodeInBrowserMessage(environment, violations, chainOf, root) {
2470
+ const byImporter = /* @__PURE__ */ new Map();
2471
+ for (const violation of violations) {
2472
+ const list = byImporter.get(violation.importer) ?? [];
2473
+ list.push(violation);
2474
+ byImporter.set(violation.importer, list);
2475
+ }
2476
+ const sections = [...byImporter].map(([importer, findings]) => {
2477
+ const lines = chainOf(importer).map((link, index) => {
2478
+ return `${index === 0 ? " " : link.dynamic ? " → import() " : " → "}${displayId(link.id, root)}`;
2479
+ });
2480
+ const described = [...new Set(findings.toSorted(compareFindings).map(describeFinding))];
2481
+ return [...lines, ...described.map((finding) => ` ${finding}`)].join("\n");
2482
+ });
2483
+ return [
2484
+ `${NODE_IN_BROWSER_ERROR}: Node-only code is reachable from the browser build ("${environment}").`,
2485
+ "",
2486
+ sections.join("\n\n"),
2487
+ "",
2488
+ "A browser cannot run Node code: Vite would ship an empty stand-in that breaks when it is used.",
2489
+ "Fix: move what the browser side needs (a constant, a type, a pure function) into a module that imports nothing from Node, and import that module instead. Keep Node work in server-only files."
2490
+ ].join("\n");
2491
+ }
2492
+ function isBrowserExternal(id) {
2493
+ return id === VITE_BROWSER_EXTERNAL || id.startsWith(`${VITE_BROWSER_EXTERNAL}:`);
2494
+ }
2495
+ function guardsEnvironment(environment) {
2496
+ return environment.config.consumer === "client";
2497
+ }
2498
+ function devChain(environment, id) {
2499
+ const graph = environment.moduleGraph;
2500
+ return importChain({
2501
+ importers: (current) => ({
2502
+ static: [...graph?.getModuleById(current)?.importers ?? []].map((node) => node.id).filter((importer) => !!importer),
2503
+ dynamic: []
2504
+ }),
2505
+ isEntry: () => false
2506
+ }, id);
2507
+ }
2508
+ const ROLLDOWN_RUNTIME = "\0rolldown/runtime.js";
2509
+ /**
2510
+ * Fails every browser build, worker bundle and dev request that reaches a Node built-in, a module
2511
+ * Vite would replace with an empty browser stand-in, or a global only Node has.
2512
+ */
2513
+ function browserNodeGuard() {
2514
+ const violationsByEnvironment = /* @__PURE__ */ new Map();
2515
+ const record = (environment, violation) => {
2516
+ const list = violationsByEnvironment.get(environment) ?? [];
2517
+ list.push(violation);
2518
+ violationsByEnvironment.set(environment, list);
2519
+ };
2520
+ let root = "";
2521
+ return {
2522
+ name: "markless:browser-node-guard",
2523
+ enforce: "pre",
2524
+ applyToEnvironment(environment) {
2525
+ return guardsEnvironment(environment);
2526
+ },
2527
+ configEnvironment(name, config) {
2528
+ if ((config.consumer ?? (name === "client" ? "client" : "server")) !== "client") return void 0;
2529
+ return { optimizeDeps: { rolldownOptions: { plugins: [optimizedDepsGuard(name, () => root)] } } };
2530
+ },
2531
+ configResolved(config) {
2532
+ root = config.root;
2533
+ },
2534
+ config() {
2535
+ return { worker: { plugins: () => [browserNodeGuard()] } };
2536
+ },
2537
+ buildStart() {
2538
+ violationsByEnvironment.delete(this.environment.name);
2539
+ },
2540
+ resolveId: {
2541
+ order: "pre",
2542
+ filter: { id: NODE_BUILTIN_SPECIFIER },
2543
+ async handler(source, importer, options) {
2544
+ if (!importer) return null;
2545
+ const resolved = await this.resolve(source, importer, {
2546
+ ...options,
2547
+ skipSelf: true
2548
+ });
2549
+ if (!resolved) return null;
2550
+ if (!(isBrowserExternal(resolved.id) || resolved.external !== false && resolved.external !== void 0 && isNodeBuiltinSpecifier(resolved.id))) return resolved;
2551
+ const environment = this.environment;
2552
+ const violation = {
2553
+ kind: "builtin",
2554
+ importer,
2555
+ specifier: source
2556
+ };
2557
+ if (environment.mode === "dev") throw new Error(nodeInBrowserMessage(environment.name, [violation], (id) => devChain(environment, id), environment.config.root));
2558
+ record(environment.name, violation);
2559
+ return resolved;
2560
+ }
2561
+ },
2562
+ transform: {
2563
+ order: "post",
2564
+ filter: { code: NODE_GLOBAL_WORD },
2565
+ handler(code, id) {
2566
+ if (id === ROLLDOWN_RUNTIME || isCSSRequest(id) || STRING_EXPORT_QUERY.test(id)) return null;
2567
+ const environment = this.environment;
2568
+ if (environment.depsOptimizer?.isOptimizedDepFile(id)) return null;
2569
+ const uses = nodeGlobalUses(code);
2570
+ if (uses.length === 0) return null;
2571
+ const violations = uses.map((use) => ({
2572
+ kind: "global",
2573
+ importer: id,
2574
+ use
2575
+ }));
2576
+ if (environment.mode === "dev") throw new Error(nodeInBrowserMessage(environment.name, violations, (target) => devChain(environment, target), environment.config.root));
2577
+ for (const violation of violations) record(environment.name, violation);
2578
+ return null;
2579
+ }
2580
+ },
2581
+ buildEnd(error) {
2582
+ if (error) return;
2583
+ const environment = this.environment;
2584
+ const violations = [...violationsByEnvironment.get(environment.name) ?? []];
2585
+ violationsByEnvironment.delete(environment.name);
2586
+ const recorded = new Set(violations.map((violation) => violation.kind === "builtin" ? `${violation.importer}\0${violation.specifier}` : ""));
2587
+ const explained = new Set(violations.filter((violation) => violation.kind === "builtin").map((violation) => violation.importer));
2588
+ for (const importer of this.getModuleIds()) {
2589
+ const info = this.getModuleInfo(importer);
2590
+ for (const id of [...info?.importedIds ?? [], ...info?.dynamicallyImportedIds ?? []]) if (isNodeBuiltinSpecifier(id)) {
2591
+ if (!recorded.has(`${importer}\0${id}`)) violations.push({
2592
+ kind: "builtin",
2593
+ importer,
2594
+ specifier: id
2595
+ });
2596
+ } else if (isBrowserExternal(id) && !explained.has(importer)) violations.push({
2597
+ kind: "browser-field",
2598
+ importer
2599
+ });
2600
+ }
2601
+ if (violations.length === 0) return;
2602
+ const graph = {
2603
+ importers: (id) => {
2604
+ const info = this.getModuleInfo(id);
2605
+ return {
2606
+ static: info?.importers ?? [],
2607
+ dynamic: info?.dynamicImporters ?? []
2608
+ };
2609
+ },
2610
+ isEntry: (id) => this.getModuleInfo(id)?.isEntry === true
2611
+ };
2612
+ this.error(nodeInBrowserMessage(environment.name, violations, (id) => importChain(graph, id), environment.config.root));
2613
+ }
2614
+ };
2615
+ }
2616
+ /** The dev dependency optimizer's half: a pre-bundled package that reaches a Node built-in fails too. */
2617
+ function optimizedDepsGuard(environment, root) {
2618
+ return {
2619
+ name: "markless:browser-node-guard-deps",
2620
+ buildEnd(error) {
2621
+ if (error) return;
2622
+ const violations = [];
2623
+ for (const id of this.getModuleIds()) {
2624
+ const specifier = id.startsWith(OPTIMIZER_BROWSER_EXTERNAL) ? id.slice(17) : void 0;
2625
+ if (specifier === void 0 && id !== VITE_BROWSER_EXTERNAL) continue;
2626
+ for (const importer of this.getModuleInfo(id)?.importers ?? []) violations.push(specifier === void 0 ? {
2627
+ kind: "browser-field",
2628
+ importer
2629
+ } : {
2630
+ kind: "builtin",
2631
+ importer,
2632
+ specifier
2633
+ });
2634
+ }
2635
+ if (violations.length === 0) return;
2636
+ const graph = {
2637
+ importers: (id) => {
2638
+ const info = this.getModuleInfo(id);
2639
+ return {
2640
+ static: info?.importers ?? [],
2641
+ dynamic: info?.dynamicImporters ?? []
2642
+ };
2643
+ },
2644
+ isEntry: (id) => this.getModuleInfo(id)?.isEntry === true
2645
+ };
2646
+ this.error(nodeInBrowserMessage(environment, violations, (id) => importChain(graph, id), root()));
2647
+ }
2648
+ };
2649
+ }
2650
+ //#endregion
2651
+ //#region src/constant-slices.ts
2652
+ const SLICE_PREFIX = `${MARKLESS_VIRTUAL_PREFIX}constant-slice:`;
2653
+ const SLICED_MODULE = /^\0virtual:markless:(?:symbol|symbol-bundle|render-data|render-data-served):|[?&]markless-render-data(?:[&#]|$)/;
2654
+ const AUTHORED_IMPORT = /\bimport\s*\{[^}]*\}\s*from\s*["'](?!@markless\/|virtual:)/;
2655
+ const PLAIN_SCRIPT_FILE = /\.[cm]?[jt]sx?$/;
2656
+ const MUTATING_METHODS = /* @__PURE__ */ new Set([
2657
+ "push",
2658
+ "pop",
2659
+ "shift",
2660
+ "unshift",
2661
+ "splice",
2662
+ "sort",
2663
+ "reverse",
2664
+ "fill",
2665
+ "copyWithin",
2666
+ "set",
2667
+ "add",
2668
+ "delete",
2669
+ "clear"
2670
+ ]);
2671
+ const evaluated = /* @__PURE__ */ new Map();
2672
+ function moduleConstants(file) {
2673
+ const source = readFileSync(file, "utf8");
2674
+ const cached = evaluated.get(file);
2675
+ if (cached?.source === source) return cached.constants;
2676
+ const constants = evaluateModuleConstants({
2677
+ filename: file,
2678
+ source
2679
+ });
2680
+ evaluated.set(file, {
2681
+ source,
2682
+ constants
2683
+ });
2684
+ return constants;
2685
+ }
2686
+ function constantSliceId(file, exportName, path) {
2687
+ return `${SLICE_PREFIX}${encodeURIComponent(file)}:${encodeURIComponent(exportName)}:${encodeURIComponent(JSON.stringify(path))}`;
2688
+ }
2689
+ function sliceAt(value, path) {
2690
+ let current = value;
2691
+ for (const segment of path) current = current[segment];
2692
+ return current;
2693
+ }
2694
+ function plainJson(value) {
2695
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
2696
+ if (typeof value === "number") return Number.isFinite(value) && !Object.is(value, -0);
2697
+ if (Array.isArray(value)) return value.every(plainJson);
2698
+ if (typeof value === "object") return Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every(plainJson);
2699
+ return false;
2700
+ }
2701
+ function children(node) {
2702
+ const out = [];
2703
+ for (const [key, value] of Object.entries(node)) {
2704
+ if (key === "start" || key === "end" || key === "type") continue;
2705
+ if (Array.isArray(value)) {
2706
+ for (const item of value) if (item && typeof item === "object" && "type" in item) out.push(item);
2707
+ } else if (value && typeof value === "object" && "type" in value) out.push(value);
2708
+ }
2709
+ return out;
2710
+ }
2711
+ function declaredNames(node, into) {
2712
+ if (!node) return;
2713
+ if (node.type === "Identifier") into.add(node.name);
2714
+ else if (node.type === "ObjectPattern") for (const property of node.properties) declaredNames(property.type === "RestElement" ? property.argument : property.value, into);
2715
+ else if (node.type === "ArrayPattern") for (const element of node.elements ?? []) declaredNames(element, into);
2716
+ else if (node.type === "AssignmentPattern") declaredNames(node.left, into);
2717
+ else if (node.type === "RestElement") declaredNames(node.argument, into);
2718
+ }
2719
+ /** Every use of `local` as the root of a member chain, with the chain cut where the value stops having that own property. */
2720
+ function references(program, local, value) {
2721
+ const found = [];
2722
+ const shadowed = /* @__PURE__ */ new Set();
2723
+ let bare = false;
2724
+ const visit = (node, parents) => {
2725
+ if (node.type === "VariableDeclarator") declaredNames(node.id, shadowed);
2726
+ if (/Function/.test(node.type)) {
2727
+ for (const param of node.params ?? []) declaredNames(param, shadowed);
2728
+ if (node.id) declaredNames(node.id, shadowed);
2729
+ }
2730
+ if (node.type === "CatchClause") declaredNames(node.param, shadowed);
2731
+ if (node.type === "Identifier" && node.name === local) {
2732
+ const parent = parents.at(-1);
2733
+ if (!(parent?.type === "MemberExpression" && parent.property === node && !parent.computed || parent?.type === "Property" && parent.key === node && !parent.computed && !parent.shorthand || parent?.type === "ImportSpecifier")) {
2734
+ const chain = [node];
2735
+ const path = [];
2736
+ let current = value;
2737
+ for (let depth = parents.length - 1; depth >= 0; depth--) {
2738
+ const member = parents[depth];
2739
+ if (member.type !== "MemberExpression" || member.object !== chain.at(-1)) break;
2740
+ const property = member.property;
2741
+ const key = member.computed ? property.type === "Literal" && (typeof property.value === "string" || typeof property.value === "number") ? property.value : void 0 : property.name;
2742
+ if (key === void 0 || !current || typeof current !== "object" || !Object.hasOwn(current, key)) break;
2743
+ current = current[key];
2744
+ path.push(key);
2745
+ chain.push(member);
2746
+ }
2747
+ if (path.length === 0) bare = true;
2748
+ const top = chain.at(-1);
2749
+ const above = parents[parents.length - chain.length];
2750
+ const mutates = above?.type === "AssignmentExpression" && above.left === top || above?.type === "UpdateExpression" || above?.type === "UnaryExpression" && above.operator === "delete" || above?.type === "MemberExpression" && above.object === top && !above.computed && MUTATING_METHODS.has(above.property.name);
2751
+ found.push({
2752
+ chain,
2753
+ path,
2754
+ mutates
2755
+ });
2756
+ }
2757
+ }
2758
+ for (const child of children(node)) visit(child, [...parents, node]);
2759
+ };
2760
+ visit(program, []);
2761
+ if (bare || shadowed.has(local) || found.some((reference) => reference.mutates)) return null;
2762
+ return found;
2763
+ }
2764
+ function slicingPays(value, roots, droppedPathBytes, maxModuleBytes) {
2765
+ const sliced = roots.reduce((sum, path) => sum + JSON.stringify(sliceAt(value, path)).length + PACK_COST_MODEL.packedModuleWrapperBytes, 0);
2766
+ const whole = JSON.stringify(value).length * 1.015 + PACK_COST_MODEL.packedModuleWrapperBytes;
2767
+ return sliced - droppedPathBytes < whole || whole > maxModuleBytes;
2768
+ }
2769
+ /** The module with each imported constant it reads only in slices narrowed to those slices, or null when nothing narrows. */
2770
+ async function narrowConstantImports(code, resolve, maxModuleBytes = Infinity) {
2771
+ if (!AUTHORED_IMPORT.test(code)) return null;
2772
+ let program;
2773
+ try {
2774
+ program = parseJavaScriptModule(code);
2775
+ } catch {
2776
+ return null;
2777
+ }
2778
+ const edits = [];
2779
+ const sliceImports = [];
2780
+ const files = [];
2781
+ const sliceLocals = /* @__PURE__ */ new Map();
2782
+ for (const statement of program.body) {
2783
+ if (statement.type !== "ImportDeclaration" || statement.importKind === "type") continue;
2784
+ const specifier = statement.source.value;
2785
+ if (specifier.startsWith("@markless/") || specifier.startsWith("virtual:")) continue;
2786
+ const named = statement.specifiers.filter((entry) => entry.type === "ImportSpecifier");
2787
+ if (named.length === 0) continue;
2788
+ const file = await resolve(specifier);
2789
+ if (!file || !PLAIN_SCRIPT_FILE.test(file)) continue;
2790
+ const constants = moduleConstants(file);
2791
+ const kept = [];
2792
+ for (const entry of statement.specifiers) {
2793
+ const imported = entry.type === "ImportSpecifier" ? entry.imported : void 0;
2794
+ const exportName = imported ? imported.name ?? imported.value : void 0;
2795
+ const local = entry.local.name;
2796
+ const value = exportName !== void 0 ? constants[exportName] : void 0;
2797
+ const uses = exportName !== void 0 && Object.hasOwn(constants, exportName) && value && typeof value === "object" ? references(program, local, value) : null;
2798
+ const paths = uses ? [...new Map(uses.map((use) => [JSON.stringify(use.path), use.path])).values()].sort((left, right) => left.length - right.length) : [];
2799
+ const roots = paths.filter((path, index) => !paths.slice(0, index).some((shorter) => shorter.every((segment, at) => path[at] === segment)));
2800
+ if (!uses || roots.some((path) => !plainJson(sliceAt(value, path))) || !slicingPays(value, roots, uses.reduce((sum, use) => {
2801
+ const root = roots.find((path) => path.every((segment, at) => use.path[at] === segment));
2802
+ return sum + use.chain[root.length].end - use.chain[0].start - local.length;
2803
+ }, 0), maxModuleBytes)) {
2804
+ kept.push(entry);
2805
+ continue;
2806
+ }
2807
+ for (const use of uses) {
2808
+ const root = roots.find((path) => path.every((segment, at) => use.path[at] === segment));
2809
+ const id = constantSliceId(file, exportName, root);
2810
+ let name = sliceLocals.get(id);
2811
+ if (!name) {
2812
+ name = `marklessConstantSlice${sliceLocals.size}`;
2813
+ sliceLocals.set(id, name);
2814
+ sliceImports.push(`import ${name} from ${JSON.stringify(id)};`);
2815
+ }
2816
+ const node = use.chain[root.length];
2817
+ edits.push({
2818
+ start: use.chain[0].start,
2819
+ end: node.end,
2820
+ text: name
2821
+ });
2822
+ }
2823
+ if (!files.includes(file)) files.push(file);
2824
+ }
2825
+ if (kept.length === named.length && kept.length === statement.specifiers.length) continue;
2826
+ const remaining = kept.map((entry) => code.slice(entry.start, entry.end));
2827
+ edits.push({
2828
+ start: statement.start,
2829
+ end: statement.end,
2830
+ text: remaining.length ? `import ${kept.some((entry) => entry.type === "ImportSpecifier") ? `{ ${remaining.join(", ")} }` : remaining.join(", ")} from ${JSON.stringify(specifier)};` : ""
2831
+ });
2832
+ }
2833
+ if (sliceImports.length === 0) return null;
2834
+ let out = code;
2835
+ for (const edit of edits.sort((left, right) => right.start - left.start)) out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
2836
+ return {
2837
+ code: `${sliceImports.join("\n")}\n${out}`,
2838
+ files
2839
+ };
2840
+ }
2841
+ function constantSlicesPlugin() {
2842
+ return {
2843
+ name: "markless:constant-slices",
2844
+ enforce: "post",
2845
+ applyToEnvironment(environment) {
2846
+ return environment.config.consumer === "client";
2847
+ },
2848
+ buildEnd() {
2849
+ if (this.environment?.mode !== "dev") evaluated.clear();
2850
+ },
2851
+ resolveId: {
2852
+ filter: { id: /^virtual:markless:constant-slice:/ },
2853
+ handler(source) {
2854
+ return `\0${source}`;
2855
+ }
2856
+ },
2857
+ load: {
2858
+ filter: { id: /^\0virtual:markless:constant-slice:/ },
2859
+ handler(id) {
2860
+ const [file, exportName, path] = id.slice(1 + SLICE_PREFIX.length).split(":").map(decodeURIComponent);
2861
+ this.addWatchFile(file);
2862
+ const at = JSON.parse(path);
2863
+ const value = sliceAt(moduleConstants(file)[exportName], at);
2864
+ const json = JSON.stringify(value);
2865
+ const limitKb = this.environment?.config.build.chunkSizeWarningLimit;
2866
+ if (limitKb === void 0 || json.length <= limitKb * 1e3 || !value || typeof value !== "object") return `export default ${json};`;
2867
+ const keys = Array.isArray(value) ? value.map((_, index) => index) : Object.keys(value);
2868
+ const parts = keys.map((key, index) => `import marklessSlicePart${index} from ${JSON.stringify(constantSliceId(file, exportName, [...at, key]))};`);
2869
+ const body = Array.isArray(value) ? `[${keys.map((_, index) => `marklessSlicePart${index}`).join(",")}]` : `{${keys.map((key, index) => `${JSON.stringify(key)}:marklessSlicePart${index}`).join(",")}}`;
2870
+ return `${parts.join("\n")}\nexport default ${body};`;
2871
+ }
2872
+ },
2873
+ transform: {
2874
+ filter: { id: SLICED_MODULE },
2875
+ async handler(code, id) {
2876
+ const limitKb = this.environment?.config.build.chunkSizeWarningLimit;
2877
+ const narrowed = await narrowConstantImports(code, async (specifier) => {
2878
+ const resolved = await this.resolve(specifier, id, { skipSelf: true });
2879
+ return resolved && !resolved.external ? resolved.id.split("?")[0] : null;
2880
+ }, limitKb === void 0 ? Infinity : limitKb * 1e3);
2881
+ if (!narrowed) return null;
2882
+ for (const file of narrowed.files) this.addWatchFile(file);
2883
+ return {
2884
+ code: narrowed.code,
2885
+ map: null
2886
+ };
2887
+ }
2888
+ }
2889
+ };
2890
+ }
2891
+ //#endregion
2170
2892
  //#region src/vite/index.ts
2171
2893
  const MARKLESS_SKIP_DUPLICATE_BUILDS = Symbol("markless-skip-duplicate-builds");
2172
2894
  const TSRX_INPUT_FILE = /\.tsrx(?:[?#].*)?$/;
@@ -2190,6 +2912,7 @@ function markless(options = {}) {
2190
2912
  rolldownOptions.productionPrerenderWakeModuleUrls = /* @__PURE__ */ new Map();
2191
2913
  let prerenderEntry = null;
2192
2914
  let resolvedRoot = "";
2915
+ let chunkSizeWarningBytes;
2193
2916
  let clientOutDir = "dist";
2194
2917
  rolldownOptions.bundleGraphAdders = bundleGraphAdders;
2195
2918
  const hmrOptions = {
@@ -2202,6 +2925,20 @@ function markless(options = {}) {
2202
2925
  pageForUrl: void 0
2203
2926
  };
2204
2927
  let devPrerender;
2928
+ let compileCache;
2929
+ let compileWorkers;
2930
+ const flushCompileCache = async () => {
2931
+ const workers = compileWorkers;
2932
+ compileWorkers = void 0;
2933
+ useCompileRunner(void 0);
2934
+ await workers?.close();
2935
+ const cache = compileCache;
2936
+ if (!cache) return;
2937
+ compileCache = void 0;
2938
+ usePersistentCompileStore(void 0);
2939
+ usePersistentStrippedCode(void 0);
2940
+ await cache.flush();
2941
+ };
2205
2942
  const devTags = createDevTags();
2206
2943
  rolldownOptions.devInjections = devTags.tags;
2207
2944
  const basePlugin = createMarklessRolldownPlugin({
@@ -2209,6 +2946,9 @@ function markless(options = {}) {
2209
2946
  options: rolldownOptions,
2210
2947
  prerenderRecordsBySource
2211
2948
  });
2949
+ const packingPlugins = nativePackingEnabled(options) ? nativePackingPlugins(() => resolvedRoot, () => basePlugin.api.runtimeDemandMaps(), () => basePlugin.api.runtimeDemandSources(), () => basePlugin.api.directCsrOnly(), () => chunkSizeWarningBytes) : void 0;
2950
+ const packOwnership = packingPlugins?.[0]?.api;
2951
+ if (packOwnership) basePlugin.api.declarePackOwnership(packOwnership);
2212
2952
  const hmr = createViteHmr(hmrOptions);
2213
2953
  const marklessPlugin = {
2214
2954
  ...basePlugin,
@@ -2247,7 +2987,11 @@ function markless(options = {}) {
2247
2987
  };
2248
2988
  configDefaults(config, options, rolldownOptions);
2249
2989
  if (devEnabled) {
2250
- includeOptimizedDeps(config, [RESUME_ENTRY_SPECIFIER, STORAGE_FREE_RESUME_ENTRY_SPECIFIER]);
2990
+ includeOptimizedDeps(config, [
2991
+ RESUME_ENTRY_SPECIFIER,
2992
+ STORAGE_FREE_RESUME_ENTRY_SPECIFIER,
2993
+ ...runtimeFunctionSpecifiers()
2994
+ ]);
2251
2995
  excludeSourceShippedDeps(config);
2252
2996
  }
2253
2997
  if (prerender || stagePrerenderWake) {
@@ -2258,6 +3002,8 @@ function markless(options = {}) {
2258
3002
  configResolved(resolvedConfig) {
2259
3003
  if (options.experimentalNativePacking !== void 0) resolvedConfig.logger.warn(DEPRECATED_NATIVE_PACKING_WARNING);
2260
3004
  resolvedRoot = resolvedConfig.root;
3005
+ const warningKb = (resolvedConfig.environments?.client ?? resolvedConfig).build?.chunkSizeWarningLimit;
3006
+ chunkSizeWarningBytes = warningKb === void 0 ? void 0 : warningKb * 1e3;
2261
3007
  clientOutDir = resolvedConfig.build?.outDir ?? "dist";
2262
3008
  const serve = resolvedConfig.command === "serve";
2263
3009
  hmrOptions.base = resolvedConfig.base;
@@ -2265,6 +3011,25 @@ function markless(options = {}) {
2265
3011
  rolldownOptions.dev = serve;
2266
3012
  rolldownOptions.rootDir = resolvedConfig.root;
2267
3013
  rolldownOptions.publicPath = (fileName) => joinURL(resolvedConfig.base, fileName);
3014
+ if (!serve && resolvedConfig.cacheDir && options.compileCache !== false && persistentCompileCacheAvailable()) {
3015
+ const directory = resolve(resolvedConfig.cacheDir, "markless-compile");
3016
+ const fingerprint = compilerFingerprint();
3017
+ compileCache = createPersistentCompileCache({
3018
+ directory,
3019
+ fingerprint
3020
+ });
3021
+ usePersistentCompileStore(compileCache);
3022
+ usePersistentStrippedCode(compileCache.strippedCode);
3023
+ compileWorkers = createCompileWorkerPool({
3024
+ size: buildWorkerCount(),
3025
+ store: {
3026
+ cache: compileCache,
3027
+ directory,
3028
+ fingerprint
3029
+ }
3030
+ });
3031
+ } else if (!serve) compileWorkers = createCompileWorkerPool({ size: buildWorkerCount() });
3032
+ if (compileWorkers) useCompileRunner(compileWorkers.run);
2268
3033
  if (serve) {
2269
3034
  devTags.registerViteTags(resolvedConfig.base);
2270
3035
  if (prerender && prerenderEntry) {
@@ -2314,6 +3079,7 @@ function markless(options = {}) {
2314
3079
  }));
2315
3080
  }
2316
3081
  await buildMarklessEnvironments(builder, options);
3082
+ await flushCompileCache();
2317
3083
  if (prerender && prerenderEntry) {
2318
3084
  const source = resolve(resolvedRoot, prerenderEntry);
2319
3085
  const clientEnvironment = builder.environments[viteEnvironmentName("client", options)];
@@ -2335,6 +3101,9 @@ function markless(options = {}) {
2335
3101
  }
2336
3102
  }
2337
3103
  },
3104
+ configureVitest({ defineCacheKeyGenerator }) {
3105
+ defineCacheKeyGenerator(({ id }) => isCompilerStatefulModuleId(id) ? false : void 0);
3106
+ },
2338
3107
  configureServer(server) {
2339
3108
  server.config.logger?.info(`markless diagnostics available - window.__MARKLESS_DEBUG__ records containers, lifecycles, and event routing; ${DEBUGGING_PLAYBOOK_HINT}.`);
2340
3109
  rolldownOptions.devServer = {
@@ -2379,7 +3148,7 @@ function markless(options = {}) {
2379
3148
  return hmr.load(id) ?? runHook(basePlugin.load, this, id, loadOptions);
2380
3149
  },
2381
3150
  transform: { async handler(code, id, transformOptions) {
2382
- if (rolldownOptions.dev === true && TSRX_INPUT_FILE.test(id)) transformedTsrxSources.set(parsePath(id).pathname, code);
3151
+ if (rolldownOptions.dev === true && TSRX_INPUT_FILE.test(id) && !STRING_EXPORT_QUERY.test(id)) transformedTsrxSources.set(parsePath(id).pathname, code);
2383
3152
  try {
2384
3153
  const context = rolldownOptions.dev === true ? withDevServerExternals(this) : this;
2385
3154
  return await runHook(basePlugin.transform, context, code, id, transformOptions);
@@ -2398,6 +3167,8 @@ function markless(options = {}) {
2398
3167
  };
2399
3168
  return [
2400
3169
  marklessPlugin,
3170
+ browserNodeGuard(),
3171
+ constantSlicesPlugin(),
2401
3172
  {
2402
3173
  name: "markless:shared-render-data-reach",
2403
3174
  enforce: "pre",
@@ -2419,13 +3190,14 @@ function markless(options = {}) {
2419
3190
  generateBundle: {
2420
3191
  order: "post",
2421
3192
  async handler(_options, bundle) {
2422
- await prefetchChunkParses(Object.values(bundle).filter((output) => output.type === "chunk" && output.code.includes("import(")));
3193
+ await prefetchChunkDynamicImports(Object.values(bundle).filter((output) => output.type === "chunk" && output.code.includes("import(")));
2423
3194
  collapseInitFacadeImports(bundle);
2424
- unwrapAsyncImportWrappers(bundle);
3195
+ await unwrapAsyncImportWrappers(bundle);
3196
+ clearChunkFactCaches();
2425
3197
  }
2426
3198
  }
2427
3199
  },
2428
- ...nativePackingEnabled(options) ? nativePackingPlugins(() => resolvedRoot, () => basePlugin.api.runtimeDemandMaps(), () => basePlugin.api.runtimeDemandSources()).map((plugin) => ({
3200
+ ...packingPlugins ? packingPlugins.map((plugin) => ({
2429
3201
  ...plugin,
2430
3202
  apply: "build",
2431
3203
  enforce: "post",