@markless/bundler 0.3.2 → 0.4.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/rolldown.d.ts
CHANGED
|
@@ -9,6 +9,9 @@ type BuiltPrerenderRecords = {
|
|
|
9
9
|
readonly view: ProtocolViewPayload;
|
|
10
10
|
};
|
|
11
11
|
//#endregion
|
|
12
|
+
//#region src/hooks/hook-context.d.ts
|
|
13
|
+
type Environment = MarklessEnvironment | ((context: unknown) => MarklessEnvironment);
|
|
14
|
+
//#endregion
|
|
12
15
|
//#region src/build/chunking.d.ts
|
|
13
16
|
declare const MARKLESS_BUILD_PREFIX = "build/";
|
|
14
17
|
declare const MARKLESS_BUNDLE_GRAPH = "build/bundle-graph.json";
|
|
@@ -71,7 +74,6 @@ declare function collectHeadLinkInjections(bundle: HeadLinkBundle, options?: {
|
|
|
71
74
|
declare function transformTsrxModule(input: TransformTsrxModuleInput): Promise<TransformTsrxModuleResult>;
|
|
72
75
|
//#endregion
|
|
73
76
|
//#region src/rolldown.d.ts
|
|
74
|
-
type Environment = MarklessEnvironment | ((context: unknown) => MarklessEnvironment);
|
|
75
77
|
type MarklessRolldownPlugin = Plugin & {
|
|
76
78
|
api: MarklessRolldownPluginApi;
|
|
77
79
|
};
|
package/dist/rolldown.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { l as resumeVirtualModuleId, s as prerenderWakeVirtualModuleId, t as MARKLESS_VIRTUAL_PREFIX } from "./source-module-
|
|
2
|
-
import { a as createBuildMetadata, c as
|
|
1
|
+
import { l as resumeVirtualModuleId, s as prerenderWakeVirtualModuleId, t as MARKLESS_VIRTUAL_PREFIX } from "./source-module-DI20i0ZG.js";
|
|
2
|
+
import { a as createBuildMetadata, c as createPreloadGraphAdder, d as MARKLESS_BUILD_PREFIX, f as MARKLESS_BUNDLE_GRAPH, i as marklessServer, n as marklessClient, o as collectHeadLinkInjections, p as outputDefaults, r as marklessLib, s as convertManifestToBundleGraph, t as createMarklessRolldownPlugin, u as transformTsrxModule } from "./rolldown-CB2Xpf-E.js";
|
|
3
3
|
export { MARKLESS_BUILD_PREFIX, MARKLESS_BUNDLE_GRAPH, MARKLESS_VIRTUAL_PREFIX, collectHeadLinkInjections, convertManifestToBundleGraph, createBuildMetadata, createMarklessRolldownPlugin, createPreloadGraphAdder, marklessClient, marklessLib, marklessServer, outputDefaults, prerenderWakeVirtualModuleId, resumeVirtualModuleId, transformTsrxModule };
|
|
@@ -479,14 +479,20 @@ function payloadModule(payload) {
|
|
|
479
479
|
""
|
|
480
480
|
].join("\n");
|
|
481
481
|
}
|
|
482
|
+
/** The module-local name a direct-CSR module's root renders under. */
|
|
483
|
+
function csrRootLocalName(rootExportName) {
|
|
484
|
+
return `marklessCsr${rootExportName}`;
|
|
485
|
+
}
|
|
482
486
|
function emitPublicRenderModule(source, input) {
|
|
483
|
-
if (!input.
|
|
487
|
+
if (!input.rootExportName) return source;
|
|
484
488
|
const declaration = `export function ${input.rootExportName}()`;
|
|
485
|
-
if (!source.includes(declaration))
|
|
489
|
+
if (!source.includes(declaration)) throw new Error(`MARKLESS_CSR_ROOT_DECLARATION_MISSING: ${input.rootExportName}`);
|
|
490
|
+
const localName = csrRootLocalName(input.rootExportName);
|
|
491
|
+
if (!input.executionLogEnabled) return source.replace(declaration, `function ${localName}()`);
|
|
486
492
|
const implementationName = `marklessRender${input.rootExportName}`;
|
|
487
493
|
return [
|
|
488
494
|
source.replace(declaration, `function ${implementationName}()`),
|
|
489
|
-
`
|
|
495
|
+
`function ${localName}() {`,
|
|
490
496
|
`\tconst output = ${implementationName}();`,
|
|
491
497
|
" globalThis.__mxLoadLog().then(log => log.logMarklessRenderSummary());",
|
|
492
498
|
" return output;",
|
|
@@ -501,9 +507,13 @@ function emitSourceModule(input) {
|
|
|
501
507
|
const symbolsOnly = input.environment === "client" && input.clientOutput === "symbols-only";
|
|
502
508
|
const routeSymbols = input.environment === "client" && input.symbolRoutes.length > 0;
|
|
503
509
|
const canonicalRenderData = input.environment === "client" && !symbolsOnly && !input.prerenderRecords && input.canonicalRenderData === true && input.publicRenderRootExportName === null && !!input.publicSsrModuleSource && !!input.renderDataId;
|
|
510
|
+
const emitsSsrBody = !!input.publicSsrModuleSource && !(input.environment === "client" && (symbolsOnly || !input.prerenderRecords && !input.dev));
|
|
511
|
+
const csrRootName = input.environment !== "server" && !symbolsOnly && !input.prerenderRecords && input.publicRenderRootExportName ? csrRootLocalName(input.publicRenderRootExportName) : null;
|
|
504
512
|
return [
|
|
505
|
-
!input.publicSsrModuleSource && !input.publicRenderModuleSource || symbolsOnly || !input.renderDataId || input.environment === "client" && !input.publicRenderModuleSource && !input.prerenderRecords && !input.dev && !canonicalRenderData ? "" : canonicalRenderData ? `import { marklessPrerenderData } from '${input.renderDataId}';` : `import { marklessRenderData } from '${input.renderDataId}';`,
|
|
513
|
+
!input.publicSsrModuleSource && !input.publicRenderModuleSource || symbolsOnly || !input.renderDataId || input.environment === "client" && !input.publicRenderModuleSource && !input.prerenderRecords && !input.dev && !canonicalRenderData ? "" : canonicalRenderData ? emitsSsrBody ? `import { marklessPrerenderData, marklessRenderData } from '${input.renderDataId}';` : `import { marklessPrerenderData } from '${input.renderDataId}';` : `import { marklessRenderData } from '${input.renderDataId}';`,
|
|
506
514
|
symbolsOnly ? "" : `import { state as payloadState, view as payloadView, runtimeDemandMap as payloadRuntimeDemandMap } from '${input.payloadId}';`,
|
|
515
|
+
input.environment === "client" && input.directCsr === true && input.hasComputedState === true ? ["import { installMarklessDerivedReconcile } from '@markless/web/fns/reconcile-plane';", "installMarklessDerivedReconcile();"].join("\n") : null,
|
|
516
|
+
input.environment === "client" && input.hasOverlayMarks === true ? emitOverlayLoaderInstall() : null,
|
|
507
517
|
"",
|
|
508
518
|
emitLoadSymbol(input),
|
|
509
519
|
input.behaviorSymbols?.length ? emitDirectSourceSymbolLoader(input.behaviorSymbols, "readMarklessBehaviorSourceSymbol").replace("function loadSymbol(", "function loadBehaviorSymbol(") : "",
|
|
@@ -518,8 +528,9 @@ function emitSourceModule(input) {
|
|
|
518
528
|
executionLogEnabled: input.executionLog !== "never",
|
|
519
529
|
rootExportName: input.publicRenderRootExportName
|
|
520
530
|
}),
|
|
521
|
-
|
|
531
|
+
emitsSsrBody ? input.publicSsrModuleSource : "",
|
|
522
532
|
routeSymbols ? emitLazySymbolRouteFunction(input.symbolRoutes, "marklessSsrLoadSymbolRoute", "marklessLoadLocalSymbol") : "",
|
|
533
|
+
routeSymbols && !symbolsOnly && input.directCsr === true ? emitComposedArmRecordsInstall() : null,
|
|
523
534
|
symbolsOnly && routeSymbols ? "export { marklessSsrLoadSymbolRoute as loadSymbol };" : "",
|
|
524
535
|
symbolsOnly ? "" : emitCompiledAppDefault({
|
|
525
536
|
environment: input.environment,
|
|
@@ -531,28 +542,111 @@ function emitSourceModule(input) {
|
|
|
531
542
|
resumeModuleUrl: input.resumeModuleUrl,
|
|
532
543
|
prerenderWakeModuleUrl: input.prerenderWakeModuleUrl,
|
|
533
544
|
rootExportName: input.publicRenderRootExportName,
|
|
545
|
+
csrRootName,
|
|
534
546
|
symbolLoaderName: routeSymbols ? "marklessSsrLoadSymbolRoute" : "loadSymbol",
|
|
535
547
|
ssrExportName: input.publicRenderSsrExportName,
|
|
548
|
+
ssrComponents: input.publicRenderSsrComponentExports ?? [],
|
|
536
549
|
canonicalRenderData,
|
|
537
550
|
prerenderRecords: input.prerenderRecords,
|
|
538
551
|
dev: input.dev
|
|
539
552
|
}),
|
|
553
|
+
...emitSharedDefinitionExports(input.sharedDefinitionExports ?? [], input.publicRenderSsrComponentExports ?? []),
|
|
540
554
|
""
|
|
541
555
|
].filter((line) => line !== null).join("\n");
|
|
542
556
|
}
|
|
557
|
+
const MARKLESS_SHARED_CALL_UNCOMPILED = "MARKLESS_SHARED_CALL_UNCOMPILED";
|
|
558
|
+
/**
|
|
559
|
+
* One real ES named export per authored shared definition, bound to a callable
|
|
560
|
+
* that only ever throws.
|
|
561
|
+
*
|
|
562
|
+
* The export exists for two reasons, and neither is "run the definition".
|
|
563
|
+
* Linking first: a `.ts` barrel writing `export { nscShared as state } from
|
|
564
|
+
* './family.tsrx'` is resolved before anything runs, and the emitted module
|
|
565
|
+
* replacing the authored one wholesale made that a SyntaxError. Failing closed
|
|
566
|
+
* second: a compiled consumer's `family.state()` is lowered by the compiler and
|
|
567
|
+
* never reaches this binding, so anything that DOES reach it is an uncompiled
|
|
568
|
+
* call site, which cannot be served correctly — a shared instance resolves
|
|
569
|
+
* against the widget the caller renders under, and an uncompiled call has no
|
|
570
|
+
* such caller. It throws by name rather than quietly becoming a second,
|
|
571
|
+
* unratified runtime API.
|
|
572
|
+
*/
|
|
573
|
+
function emitSharedDefinitionExports(sharedExports, ssrComponents) {
|
|
574
|
+
if (sharedExports.length === 0) return [];
|
|
575
|
+
const taken = new Set([...RESERVED_MODULE_BINDINGS, ...ssrComponents.map((component) => component.exportName)]);
|
|
576
|
+
return sharedExports.map((name) => {
|
|
577
|
+
if (taken.has(name)) throw new Error(`MARKLESS_SHARED_EXPORT_NAME_RESERVED: ${name}`);
|
|
578
|
+
taken.add(name);
|
|
579
|
+
const message = `${MARKLESS_SHARED_CALL_UNCOMPILED}: ${name} — a shared definition can only be called from a compiled module; this call site was not compiled.`;
|
|
580
|
+
return `export const ${name} = () => { throw new Error(${JSON.stringify(message)}); };`;
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Whether this app's serialized state defines any computed node. Computed
|
|
585
|
+
* definitions are what `createRuntimeGraph` turns into derived graph nodes on
|
|
586
|
+
* resume, so they are exactly the apps derived reconciliation can act on.
|
|
587
|
+
*/
|
|
588
|
+
function payloadHasComputed(payloadState) {
|
|
589
|
+
const computed = payloadState?.computed;
|
|
590
|
+
return Array.isArray(computed) && computed.length > 0;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* The one line that makes elevation cost nothing until it is used.
|
|
594
|
+
*
|
|
595
|
+
* Writing the `import()` specifier HERE rather than in the runtime is the whole
|
|
596
|
+
* mechanism: a module every app loads cannot name the behaviour without making
|
|
597
|
+
* every app ship its chunk. The handoff is a global rather than a slot module
|
|
598
|
+
* for the same reason - a slot module is bytes every app pays for a capability
|
|
599
|
+
* most of them do not have. Nothing is fetched until the runtime calls it.
|
|
600
|
+
*/
|
|
601
|
+
function emitOverlayLoaderInstall() {
|
|
602
|
+
return [
|
|
603
|
+
"globalThis.__marklessOverlay = (root) =>",
|
|
604
|
+
" root.querySelector('[overlay]')",
|
|
605
|
+
" ? import('@markless/web/fns/overlay').then((m) => m.installOverlayBehavior(root))",
|
|
606
|
+
" : undefined;"
|
|
607
|
+
].join("\n");
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* The same one line for the row mint, and for the same reason.
|
|
611
|
+
*
|
|
612
|
+
* `resume-keyed-repeats` is loaded by EVERY repeat, so it cannot name the
|
|
613
|
+
* building half: doing so makes an app whose rows only reorder emit the mint
|
|
614
|
+
* chunk anyway. Written here, the specifier exists only in a build the compiler
|
|
615
|
+
* recorded a mintable repeat for; the repeat runtime reads the loader off the
|
|
616
|
+
* global and refuses to build without one.
|
|
617
|
+
*/
|
|
618
|
+
function emitRowMintLoaderInstall() {
|
|
619
|
+
return "globalThis.__marklessRowMint = () => import('@markless/web/fns/row-mint');";
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* True when the compiler folded the mint into a keyed-repeat record - which it
|
|
623
|
+
* does exactly for a record carrying `rowTemplate` or `emptyArm`, the two fields
|
|
624
|
+
* that make a repeat able to build nodes.
|
|
625
|
+
*/
|
|
626
|
+
function demandsRowMint(runtimeDemandMap) {
|
|
627
|
+
const records = runtimeDemandMap?.payloadRecords;
|
|
628
|
+
return Array.isArray(records) && records.some((record) => record.kind === "keyed-repeat" && record.runtimeModuleIds?.includes(ROW_MINT_RUNTIME_MODULE_ID) === true);
|
|
629
|
+
}
|
|
630
|
+
const ROW_MINT_RUNTIME_MODULE_ID = "web/fns/row-mint";
|
|
631
|
+
/** True when the compiler recorded an `overlay` mark for this module. */
|
|
632
|
+
function demandsOverlay(runtimeDemandMap) {
|
|
633
|
+
const records = runtimeDemandMap?.payloadRecords;
|
|
634
|
+
return Array.isArray(records) && records.some((record) => record.kind === "overlay");
|
|
635
|
+
}
|
|
543
636
|
function emitResumeModule(input) {
|
|
544
637
|
const routeSymbols = input.symbolRoutes.length > 0;
|
|
545
638
|
const resumeSymbolLoader = routeSymbols ? "marklessSsrLoadSymbolRoute" : "loadSymbol";
|
|
546
639
|
const scalarSpecializations = scalarDispatcherSpecializations(input);
|
|
547
640
|
const stagedPrerender = (input.prerenderTriggerGroups?.length ?? 0) > 0;
|
|
548
|
-
const
|
|
549
|
-
const bareResumeContainerEvent = emitResumeContainerEvent(resumeSymbolLoader, input.needsFullResume ?? false, input.payloadState?.version === ASYNC_PROTOCOL_VERSION, input.symbolRoutes.length > 0 ? "none" : leanResumeMode(input.runtimeDemandMap), scalarSpecializations, input.runtimeDemandMap, input.executionLog !== "never", input.prerenderDataId, stagedPrerender);
|
|
550
|
-
const resumeContainerEvent = streamedResume ? emitQueuedResumeContainerEvent(bareResumeContainerEvent) : bareResumeContainerEvent;
|
|
641
|
+
const resumeContainerEvent = emitQueuedResumeContainerEvent(emitResumeContainerEvent(resumeSymbolLoader, input.needsFullResume ?? false, input.payloadState?.version === ASYNC_PROTOCOL_VERSION, input.symbolRoutes.length > 0 ? "none" : leanResumeMode(input.runtimeDemandMap), scalarSpecializations, input.runtimeDemandMap, input.executionLog !== "never", input.prerenderDataId, stagedPrerender));
|
|
551
642
|
return [
|
|
552
643
|
input.boundSymbolDescriptors ? `export const ${MARKLESS_BOUND_SYMBOLS_EXPORT} = ${emitBoundSymbolDescriptors(input.boundSymbolDescriptors)};` : null,
|
|
553
644
|
input.prerenderDataId && !stagedPrerender && resumeContainerEvent.includes("marklessPrerenderData") ? `import { marklessPrerenderData } from '${input.prerenderDataId}';` : null,
|
|
554
645
|
stagedPrerender && input.prerenderDataId ? `async function marklessLoadPrerenderData() { const module = await import('${input.prerenderDataId}'); return module.marklessPrerenderData; }` : null,
|
|
555
646
|
`import { runtimeDemandMap as payloadRuntimeDemandMap } from '${input.payloadId}';`,
|
|
647
|
+
payloadHasComputed(input.payloadState) ? ["import { installMarklessDerivedReconcile } from '@markless/web/fns/reconcile-plane';", "installMarklessDerivedReconcile();"].join("\n") : null,
|
|
648
|
+
demandsOverlay(input.runtimeDemandMap) ? emitOverlayLoaderInstall() : null,
|
|
649
|
+
demandsRowMint(input.runtimeDemandMap) ? emitRowMintLoaderInstall() : null,
|
|
556
650
|
scalarSpecializations.length > 0 ? [
|
|
557
651
|
"import { marklessDecodeScalarCell, marklessReadScalarCell, marklessScalarSpecializedError } from '@markless/web/fns/scalar-specialized';",
|
|
558
652
|
"import { marklessWriteScalar } from '@markless/web/fns/write-scalar';",
|
|
@@ -567,6 +661,7 @@ function emitResumeModule(input) {
|
|
|
567
661
|
routeSymbols ? "const marklessLoadLocalSymbol = loadSymbol;" : "",
|
|
568
662
|
routeSymbols ? emitLazySymbolRouteFunction(input.symbolRoutes, "marklessSsrLoadSymbolRoute", "marklessLoadLocalSymbol") : "",
|
|
569
663
|
routeSymbols ? "export { marklessSsrLoadSymbolRoute as loadSymbol };" : "",
|
|
664
|
+
routeSymbols ? emitComposedArmRecordsInstall() : null,
|
|
570
665
|
stagedPrerender ? emitPrerenderTriggerGroupLoader(input.prerenderTriggerGroups ?? []) : "",
|
|
571
666
|
resumeContainerEvent,
|
|
572
667
|
""
|
|
@@ -601,13 +696,17 @@ function emitQueuedResumeContainerEvent(source) {
|
|
|
601
696
|
"}"
|
|
602
697
|
].join("\n");
|
|
603
698
|
}
|
|
699
|
+
function emitComposedArmRecordsInstall() {
|
|
700
|
+
return ["import { installMarklessComposedArmRecords } from '@markless/web/fns/instance-scope';", "installMarklessComposedArmRecords();"].join("\n");
|
|
701
|
+
}
|
|
604
702
|
function emitLazySymbolRouteFunction(routes, functionName, fallbackName = "loadSymbol") {
|
|
605
703
|
if (routes.length === 0) return "";
|
|
704
|
+
const ordered = [...routes].sort((left, right) => right.prefix.length - left.prefix.length);
|
|
606
705
|
return [
|
|
607
706
|
`function ${functionName}(symbolId) {`,
|
|
608
|
-
...
|
|
707
|
+
...ordered.flatMap((route) => [
|
|
609
708
|
` if (symbolId.startsWith(${JSON.stringify(route.prefix)})) {`,
|
|
610
|
-
` return 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}\`)));`,
|
|
709
|
+
"importSource" in route ? ` return 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}\`)));` : ` return ${route.prefix.length > 0 ? functionName : fallbackName}(symbolId.slice(${route.prefix.length}));`,
|
|
611
710
|
" }"
|
|
612
711
|
]),
|
|
613
712
|
` return ${fallbackName}(symbolId);`,
|
|
@@ -618,14 +717,16 @@ function symbolRouteImportSource(importSource) {
|
|
|
618
717
|
return importSource.includes("?") ? `${importSource}&markless-symbols` : `${importSource}?markless-symbols`;
|
|
619
718
|
}
|
|
620
719
|
function emitCompiledAppDefault(input) {
|
|
621
|
-
const renderCsrEntry = input.
|
|
720
|
+
const renderCsrEntry = input.csrRootName ? [` renderCsr: ${input.csrRootName},`] : [];
|
|
622
721
|
const symbolLoaderEntry = input.environment !== "server" && input.rootExportName === null ? [`\tloadSymbol: ${input.symbolLoaderName},`] : input.prerenderRecords === true ? [`\tloadSymbol: ${input.symbolLoaderName},`] : [];
|
|
623
722
|
const renderDataEntry = input.canonicalRenderData ? [" renderData: marklessPrerenderData,"] : [];
|
|
624
|
-
const
|
|
723
|
+
const servesSsr = !!input.ssrExportName && (input.environment !== "client" || input.prerenderRecords || input.dev);
|
|
724
|
+
const renderSsrEntry = servesSsr ? [
|
|
625
725
|
" renderSsr(props, marklessRenderContext) {",
|
|
626
726
|
` return ${input.ssrExportName}(props, marklessRenderContext);`,
|
|
627
727
|
" },"
|
|
628
728
|
] : [];
|
|
729
|
+
const renderSsrComponentsEntry = servesSsr && input.ssrComponents.length > 0 ? [` renderSsrComponents: { ${input.ssrComponents.map((component) => `${JSON.stringify(component.exportName)}: { renderSsr: ${component.ssrFunctionName} }`).join(", ")} },`] : [];
|
|
629
730
|
const resumeModuleEntry = input.resumeModuleUrl && input.environment !== "client" ? [` resumeModuleUrl: ${JSON.stringify(input.resumeModuleUrl)},`] : [];
|
|
630
731
|
const prerenderWakeModuleEntry = input.prerenderWakeModuleUrl && input.environment !== "client" ? [`\tprerenderWakeModuleUrl: ${JSON.stringify(input.prerenderWakeModuleUrl)},`] : [];
|
|
631
732
|
const inlineResumerEntry = input.inlineResumerSources && input.environment !== "client" ? [`\tinlineResumerSources: ${JSON.stringify(input.inlineResumerSources)},`] : [];
|
|
@@ -650,11 +751,57 @@ function emitCompiledAppDefault(input) {
|
|
|
650
751
|
...renderDataEntry,
|
|
651
752
|
...symbolLoaderEntry,
|
|
652
753
|
...renderSsrEntry,
|
|
754
|
+
...renderSsrComponentsEntry,
|
|
653
755
|
...metadataEntries,
|
|
654
756
|
"};",
|
|
655
|
-
"export default marklessCompiledApp;"
|
|
757
|
+
"export default marklessCompiledApp;",
|
|
758
|
+
...emitComponentExports({
|
|
759
|
+
ssrComponents: input.ssrComponents,
|
|
760
|
+
rootExportName: input.ssrComponents.find((component) => component.ssrFunctionName === input.ssrExportName)?.exportName,
|
|
761
|
+
servesSsr: !!servesSsr
|
|
762
|
+
})
|
|
656
763
|
].join("\n");
|
|
657
764
|
}
|
|
765
|
+
const RESERVED_MODULE_BINDINGS = new Set([
|
|
766
|
+
"loadBehaviorSymbol",
|
|
767
|
+
"loadSymbol",
|
|
768
|
+
"marklessCompiledApp",
|
|
769
|
+
"marklessLoadLocalSymbol",
|
|
770
|
+
"marklessPrerenderData",
|
|
771
|
+
"marklessRenderData",
|
|
772
|
+
"marklessRenderSsr",
|
|
773
|
+
"marklessSsrLoadSymbolRoute",
|
|
774
|
+
"payloadRuntimeDemandMap",
|
|
775
|
+
"payloadState",
|
|
776
|
+
"payloadView",
|
|
777
|
+
"readMarklessBehaviorSourceSymbol",
|
|
778
|
+
"resumeContainerEvent"
|
|
779
|
+
]);
|
|
780
|
+
/**
|
|
781
|
+
* One real ES named export per component the module serves, so plain ESM reaches
|
|
782
|
+
* them: a `.ts` barrel writing `export { CheckboxRoot as root } from
|
|
783
|
+
* './checkbox.tsrx'`, and an app writing `import { Gallery } from
|
|
784
|
+
* './Gallery.tsrx'`, are both named reads the bundler resolves at LINK time.
|
|
785
|
+
* Publishing components only on the default export's map answered neither
|
|
786
|
+
* (MISSING_EXPORT at build, "does not provide an export named" in the browser).
|
|
787
|
+
*
|
|
788
|
+
* The root is published merged - the module surface plus its own part's
|
|
789
|
+
* `renderSsr` - because both consumers reach it by that one name: `render(Gallery,
|
|
790
|
+
* { target })` reads the surface (`renderCsr`/`renderData`/`loadSymbol`), while a
|
|
791
|
+
* barrel re-export composed as a member tag reads the part. Every other component
|
|
792
|
+
* is published as exactly the part `marklessSsrComponentPart` hands a composed
|
|
793
|
+
* child, through the same access path, so a named import and a member tag reach
|
|
794
|
+
* one object.
|
|
795
|
+
*/
|
|
796
|
+
function emitComponentExports(input) {
|
|
797
|
+
return input.ssrComponents.map((component) => {
|
|
798
|
+
if (RESERVED_MODULE_BINDINGS.has(component.exportName)) throw new Error(`MARKLESS_COMPONENT_EXPORT_NAME_RESERVED: ${component.exportName}`);
|
|
799
|
+
const part = `marklessCompiledApp.renderSsrComponents[${JSON.stringify(component.exportName)}]`;
|
|
800
|
+
const isRoot = component.exportName === input.rootExportName;
|
|
801
|
+
if (input.servesSsr) return `export const ${component.exportName} = ${isRoot ? `{ ...marklessCompiledApp, renderSsr: ${part}.renderSsr }` : part};`;
|
|
802
|
+
return isRoot ? `export const ${component.exportName} = marklessCompiledApp;` : `export const ${component.exportName} = { marklessCsrOnlyPart: ${JSON.stringify(component.exportName)} };`;
|
|
803
|
+
});
|
|
804
|
+
}
|
|
658
805
|
function emitResumeContainerEvent(loadSymbolName, needsFullResume, storageFreePayload, leanMode, scalarSpecializations, runtimeDemandMap, executionLogEnabled, prerenderDataId, stagedPrerender = false) {
|
|
659
806
|
const fullResumeHandoff = stagedPrerender && prerenderDataId ? [
|
|
660
807
|
"async function marklessFullResumeHandoff(handoff) {",
|
package/dist/vite.js
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import { MARKLESS_DEV_ERROR_CLEAR_EVENT, MARKLESS_DEV_ERROR_CLIENT_ID, MARKLESS_DEV_ERROR_EVENT, normalizeMarklessDevError, renderMarklessDevErrorDocument } from "./dev-error.js";
|
|
2
|
-
import { _ as executionLogActivationInjection } from "./source-module-
|
|
3
|
-
import {
|
|
2
|
+
import { _ as executionLogActivationInjection } from "./source-module-DI20i0ZG.js";
|
|
3
|
+
import { c as createPreloadGraphAdder, l as preflightTsrxModuleDiagnostics, p as outputDefaults, t as createMarklessRolldownPlugin } from "./rolldown-CB2Xpf-E.js";
|
|
4
4
|
import { joinURL, parsePath, withQuery } from "ufo";
|
|
5
5
|
import { ASYNC_PROTOCOL_VERSION, STORAGE_SLOT_SYMBOL_KEY, serializeRuntimeAsyncSnapshots, serializeRuntimeStateCells, storageAttributeName } from "@markless/serializer";
|
|
6
|
-
import { pathToFileURL } from "node:url";
|
|
7
6
|
import { join, resolve } from "pathe";
|
|
7
|
+
import { isAbsolute as isAbsolute$1 } from "node:path";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
8
9
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
9
10
|
import { tmpdir } from "node:os";
|
|
10
11
|
import { PROTOCOL_EVENT_ACTION_KIND as PROTOCOL_EVENT_ACTION_KIND$1, protocolEventDispatchesMarkless } from "@markless/serializer/protocol";
|
|
11
12
|
import "@markless/serializer/resume-record-delta";
|
|
12
13
|
import { deserializeGraphValueForClient } from "@markless/serializer/decode-client";
|
|
13
14
|
import { createServerModuleRunner, isRunnableDevEnvironment } from "vite";
|
|
14
|
-
import { isAbsolute as isAbsolute$1 } from "node:path";
|
|
15
15
|
//#region ../web/src/inline/resumer.ts
|
|
16
16
|
PROTOCOL_EVENT_ACTION_KIND$1.event, PROTOCOL_EVENT_ACTION_KIND$1.externalDelegate;
|
|
17
17
|
function createInlineResumerSelfWakeSource(resumeModuleUrl) {
|
|
18
18
|
return `;(${runInlineResumerSelfWake.toString()})(${JSON.stringify(resumeModuleUrl)});`;
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* The Escape primer, appended only to a page whose served HTML carries an
|
|
22
|
+
* `overlay` mark.
|
|
23
|
+
*
|
|
24
|
+
* Appended rather than composed into the resumer body for the same reason the
|
|
25
|
+
* self-wake is: the body is serialized whole, so a flag inside it would put the
|
|
26
|
+
* text on every page in the world to serve the few that elevate anything. A page
|
|
27
|
+
* with no mark ships a byte-identical resumer.
|
|
28
|
+
*/
|
|
29
|
+
function createInlineResumerOverlayPrimerSource(resumeModuleUrl) {
|
|
30
|
+
return `;(${runInlineResumerOverlayPrimer.toString()})(${JSON.stringify(resumeModuleUrl)},(url) => import(/* @vite-ignore */ url));`;
|
|
31
|
+
}
|
|
20
32
|
const PRERENDER_INLINE_EVENT_NAMES_TOKEN = "__MARKLESS_PRERENDER_EVENT_NAMES__";
|
|
21
33
|
function renderPrerenderInlineResumerSource(compiled, eventNames) {
|
|
22
34
|
return compiled.replace(PRERENDER_INLINE_EVENT_NAMES_TOKEN, JSON.stringify(eventNames));
|
|
@@ -114,9 +126,10 @@ function runPrerenderInlineResumer(eventNames, fallbackResumeModuleUrl, loadModu
|
|
|
114
126
|
const root = currentScript?.closest("[data-async-container]");
|
|
115
127
|
const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
|
|
116
128
|
if (!root || !resumeModuleUrl) return;
|
|
129
|
+
let loaded;
|
|
117
130
|
for (const eventName of eventNames) root.addEventListener(eventName, (event) => {
|
|
118
131
|
root.__marklessDelegatedDispatch = true;
|
|
119
|
-
return loadModule(resumeModuleUrl).then((module) => module.resumeContainerEvent({
|
|
132
|
+
return (loaded ||= loadModule(resumeModuleUrl)).then((module) => module.resumeContainerEvent({
|
|
120
133
|
root,
|
|
121
134
|
event,
|
|
122
135
|
element: event.target,
|
|
@@ -146,6 +159,45 @@ function runInlineResumerSelfWake(fallbackResumeModuleUrl) {
|
|
|
146
159
|
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", wake, { once: true });
|
|
147
160
|
else wake();
|
|
148
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* One window-level listen, from first paint, on a page that elevates something.
|
|
164
|
+
*
|
|
165
|
+
* Two facts make it necessary. A page served with an open overlay is on the
|
|
166
|
+
* stack the moment the behaviour installs, but nothing installs until the
|
|
167
|
+
* runtime wakes; and Escape is the one gesture with no route into the page -
|
|
168
|
+
* every other one reaches an authored handler through the container's own
|
|
169
|
+
* listener, while a dismissal is reported by a document listener that does not
|
|
170
|
+
* exist yet. So the first Escape on such a page would be spent waking and
|
|
171
|
+
* dismiss nothing. This listens above the container, leaves the reason where the
|
|
172
|
+
* behaviour's installer takes it, and lets the wake finish the job.
|
|
173
|
+
*
|
|
174
|
+
* Deliberately one-shot, and deliberately not the waker of first resort. The
|
|
175
|
+
* container's own capture listener runs after this one and wakes the runtime for
|
|
176
|
+
* any event the page has a record for; waking here as well would start a second
|
|
177
|
+
* runtime for one gesture. Deciding a task later is what tells the two apart.
|
|
178
|
+
*/
|
|
179
|
+
function runInlineResumerOverlayPrimer(fallbackResumeModuleUrl, loadModule) {
|
|
180
|
+
const currentScript = document.currentScript;
|
|
181
|
+
const root = currentScript?.closest("[data-async-container]");
|
|
182
|
+
const resumeModuleUrl = currentScript?.getAttribute?.("data-markless-resume-module") ?? fallbackResumeModuleUrl;
|
|
183
|
+
if (!root || !resumeModuleUrl) return;
|
|
184
|
+
const prime = (event) => {
|
|
185
|
+
removeEventListener("keydown", prime, true);
|
|
186
|
+
removeEventListener("pointerdown", prime, true);
|
|
187
|
+
if (root.__marklessDelegatedDispatch) return;
|
|
188
|
+
if (event.key === "Escape") globalThis.__marklessOverlayPrimedDismissal = "escape";
|
|
189
|
+
setTimeout(() => {
|
|
190
|
+
if (root.__marklessDelegatedDispatch) return;
|
|
191
|
+
root.__marklessDelegatedDispatch = true;
|
|
192
|
+
loadModule(resumeModuleUrl).then((module) => module.resumeContainerEvent({
|
|
193
|
+
root,
|
|
194
|
+
event: 0
|
|
195
|
+
}));
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
addEventListener("keydown", prime, true);
|
|
199
|
+
addEventListener("pointerdown", prime, true);
|
|
200
|
+
}
|
|
149
201
|
//#endregion
|
|
150
202
|
//#region ../web/src/repeat-runtime.ts
|
|
151
203
|
var KeyedRepeatRuntimeError = class extends Error {
|
|
@@ -396,8 +448,14 @@ function browserEventNames(view) {
|
|
|
396
448
|
function renderContainerAttributes(containerId) {
|
|
397
449
|
return containerId ? ` data-async-container="${escapeAttribute(containerId)}"` : " data-async-container";
|
|
398
450
|
}
|
|
399
|
-
function renderInlineResumerScript(source, nonce, resumeModuleUrl, selfWake, settleModuleUrl, appendSelfWakeSource = true) {
|
|
400
|
-
|
|
451
|
+
function renderInlineResumerScript(source, nonce, resumeModuleUrl, selfWake, settleModuleUrl, appendSelfWakeSource = true, overlayPrimer = false) {
|
|
452
|
+
const nonceAttribute = nonce ? ` nonce="${escapeAttribute(nonce)}"` : "";
|
|
453
|
+
const resumeModuleAttribute = resumeModuleUrl ? ` data-markless-resume-module="${escapeAttribute(resumeModuleUrl)}"` : "";
|
|
454
|
+
const settleModuleAttribute = settleModuleUrl ? ` data-markless-settle-module="${escapeAttribute(settleModuleUrl)}"` : "";
|
|
455
|
+
const selfWakeAttribute = selfWake ? " data-markless-self-wake" : "";
|
|
456
|
+
const selfWakeSource = selfWake && appendSelfWakeSource ? createInlineResumerSelfWakeSource(resumeModuleUrl) : "";
|
|
457
|
+
const overlayPrimerSource = overlayPrimer ? createInlineResumerOverlayPrimerSource(resumeModuleUrl) : "";
|
|
458
|
+
return `<script data-async-resumer${nonceAttribute}${resumeModuleAttribute}${settleModuleAttribute}${selfWakeAttribute}>${escapeInlineScript(source + selfWakeSource + overlayPrimerSource)}<\/script>`;
|
|
401
459
|
}
|
|
402
460
|
function escapeAttribute(value) {
|
|
403
461
|
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markless/bundler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Markless build plugins for Rolldown and Vite.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,12 +39,12 @@
|
|
|
39
39
|
"@thi.ng/dgraph": "^2.1.205",
|
|
40
40
|
"pathe": "^2.0.3",
|
|
41
41
|
"ufo": "^1.6.4",
|
|
42
|
-
"@markless/compiler": "0.
|
|
43
|
-
"@markless/
|
|
44
|
-
"@markless/
|
|
42
|
+
"@markless/compiler": "0.4.0",
|
|
43
|
+
"@markless/serializer": "0.4.0",
|
|
44
|
+
"@markless/web": "0.4.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@markless/analyzer": "0.
|
|
47
|
+
"@markless/analyzer": "0.4.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"rolldown": "1.0.3",
|