@markless/bundler 0.3.3 → 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,10 +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}';`,
|
|
507
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,
|
|
508
517
|
"",
|
|
509
518
|
emitLoadSymbol(input),
|
|
510
519
|
input.behaviorSymbols?.length ? emitDirectSourceSymbolLoader(input.behaviorSymbols, "readMarklessBehaviorSourceSymbol").replace("function loadSymbol(", "function loadBehaviorSymbol(") : "",
|
|
@@ -519,8 +528,9 @@ function emitSourceModule(input) {
|
|
|
519
528
|
executionLogEnabled: input.executionLog !== "never",
|
|
520
529
|
rootExportName: input.publicRenderRootExportName
|
|
521
530
|
}),
|
|
522
|
-
|
|
531
|
+
emitsSsrBody ? input.publicSsrModuleSource : "",
|
|
523
532
|
routeSymbols ? emitLazySymbolRouteFunction(input.symbolRoutes, "marklessSsrLoadSymbolRoute", "marklessLoadLocalSymbol") : "",
|
|
533
|
+
routeSymbols && !symbolsOnly && input.directCsr === true ? emitComposedArmRecordsInstall() : null,
|
|
524
534
|
symbolsOnly && routeSymbols ? "export { marklessSsrLoadSymbolRoute as loadSymbol };" : "",
|
|
525
535
|
symbolsOnly ? "" : emitCompiledAppDefault({
|
|
526
536
|
environment: input.environment,
|
|
@@ -532,15 +542,44 @@ function emitSourceModule(input) {
|
|
|
532
542
|
resumeModuleUrl: input.resumeModuleUrl,
|
|
533
543
|
prerenderWakeModuleUrl: input.prerenderWakeModuleUrl,
|
|
534
544
|
rootExportName: input.publicRenderRootExportName,
|
|
545
|
+
csrRootName,
|
|
535
546
|
symbolLoaderName: routeSymbols ? "marklessSsrLoadSymbolRoute" : "loadSymbol",
|
|
536
547
|
ssrExportName: input.publicRenderSsrExportName,
|
|
548
|
+
ssrComponents: input.publicRenderSsrComponentExports ?? [],
|
|
537
549
|
canonicalRenderData,
|
|
538
550
|
prerenderRecords: input.prerenderRecords,
|
|
539
551
|
dev: input.dev
|
|
540
552
|
}),
|
|
553
|
+
...emitSharedDefinitionExports(input.sharedDefinitionExports ?? [], input.publicRenderSsrComponentExports ?? []),
|
|
541
554
|
""
|
|
542
555
|
].filter((line) => line !== null).join("\n");
|
|
543
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
|
+
}
|
|
544
583
|
/**
|
|
545
584
|
* Whether this app's serialized state defines any computed node. Computed
|
|
546
585
|
* definitions are what `createRuntimeGraph` turns into derived graph nodes on
|
|
@@ -550,20 +589,64 @@ function payloadHasComputed(payloadState) {
|
|
|
550
589
|
const computed = payloadState?.computed;
|
|
551
590
|
return Array.isArray(computed) && computed.length > 0;
|
|
552
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
|
+
}
|
|
553
636
|
function emitResumeModule(input) {
|
|
554
637
|
const routeSymbols = input.symbolRoutes.length > 0;
|
|
555
638
|
const resumeSymbolLoader = routeSymbols ? "marklessSsrLoadSymbolRoute" : "loadSymbol";
|
|
556
639
|
const scalarSpecializations = scalarDispatcherSpecializations(input);
|
|
557
640
|
const stagedPrerender = (input.prerenderTriggerGroups?.length ?? 0) > 0;
|
|
558
|
-
const
|
|
559
|
-
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);
|
|
560
|
-
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));
|
|
561
642
|
return [
|
|
562
643
|
input.boundSymbolDescriptors ? `export const ${MARKLESS_BOUND_SYMBOLS_EXPORT} = ${emitBoundSymbolDescriptors(input.boundSymbolDescriptors)};` : null,
|
|
563
644
|
input.prerenderDataId && !stagedPrerender && resumeContainerEvent.includes("marklessPrerenderData") ? `import { marklessPrerenderData } from '${input.prerenderDataId}';` : null,
|
|
564
645
|
stagedPrerender && input.prerenderDataId ? `async function marklessLoadPrerenderData() { const module = await import('${input.prerenderDataId}'); return module.marklessPrerenderData; }` : null,
|
|
565
646
|
`import { runtimeDemandMap as payloadRuntimeDemandMap } from '${input.payloadId}';`,
|
|
566
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,
|
|
567
650
|
scalarSpecializations.length > 0 ? [
|
|
568
651
|
"import { marklessDecodeScalarCell, marklessReadScalarCell, marklessScalarSpecializedError } from '@markless/web/fns/scalar-specialized';",
|
|
569
652
|
"import { marklessWriteScalar } from '@markless/web/fns/write-scalar';",
|
|
@@ -578,6 +661,7 @@ function emitResumeModule(input) {
|
|
|
578
661
|
routeSymbols ? "const marklessLoadLocalSymbol = loadSymbol;" : "",
|
|
579
662
|
routeSymbols ? emitLazySymbolRouteFunction(input.symbolRoutes, "marklessSsrLoadSymbolRoute", "marklessLoadLocalSymbol") : "",
|
|
580
663
|
routeSymbols ? "export { marklessSsrLoadSymbolRoute as loadSymbol };" : "",
|
|
664
|
+
routeSymbols ? emitComposedArmRecordsInstall() : null,
|
|
581
665
|
stagedPrerender ? emitPrerenderTriggerGroupLoader(input.prerenderTriggerGroups ?? []) : "",
|
|
582
666
|
resumeContainerEvent,
|
|
583
667
|
""
|
|
@@ -612,13 +696,17 @@ function emitQueuedResumeContainerEvent(source) {
|
|
|
612
696
|
"}"
|
|
613
697
|
].join("\n");
|
|
614
698
|
}
|
|
699
|
+
function emitComposedArmRecordsInstall() {
|
|
700
|
+
return ["import { installMarklessComposedArmRecords } from '@markless/web/fns/instance-scope';", "installMarklessComposedArmRecords();"].join("\n");
|
|
701
|
+
}
|
|
615
702
|
function emitLazySymbolRouteFunction(routes, functionName, fallbackName = "loadSymbol") {
|
|
616
703
|
if (routes.length === 0) return "";
|
|
704
|
+
const ordered = [...routes].sort((left, right) => right.prefix.length - left.prefix.length);
|
|
617
705
|
return [
|
|
618
706
|
`function ${functionName}(symbolId) {`,
|
|
619
|
-
...
|
|
707
|
+
...ordered.flatMap((route) => [
|
|
620
708
|
` if (symbolId.startsWith(${JSON.stringify(route.prefix)})) {`,
|
|
621
|
-
` 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}));`,
|
|
622
710
|
" }"
|
|
623
711
|
]),
|
|
624
712
|
` return ${fallbackName}(symbolId);`,
|
|
@@ -629,14 +717,16 @@ function symbolRouteImportSource(importSource) {
|
|
|
629
717
|
return importSource.includes("?") ? `${importSource}&markless-symbols` : `${importSource}?markless-symbols`;
|
|
630
718
|
}
|
|
631
719
|
function emitCompiledAppDefault(input) {
|
|
632
|
-
const renderCsrEntry = input.
|
|
720
|
+
const renderCsrEntry = input.csrRootName ? [` renderCsr: ${input.csrRootName},`] : [];
|
|
633
721
|
const symbolLoaderEntry = input.environment !== "server" && input.rootExportName === null ? [`\tloadSymbol: ${input.symbolLoaderName},`] : input.prerenderRecords === true ? [`\tloadSymbol: ${input.symbolLoaderName},`] : [];
|
|
634
722
|
const renderDataEntry = input.canonicalRenderData ? [" renderData: marklessPrerenderData,"] : [];
|
|
635
|
-
const
|
|
723
|
+
const servesSsr = !!input.ssrExportName && (input.environment !== "client" || input.prerenderRecords || input.dev);
|
|
724
|
+
const renderSsrEntry = servesSsr ? [
|
|
636
725
|
" renderSsr(props, marklessRenderContext) {",
|
|
637
726
|
` return ${input.ssrExportName}(props, marklessRenderContext);`,
|
|
638
727
|
" },"
|
|
639
728
|
] : [];
|
|
729
|
+
const renderSsrComponentsEntry = servesSsr && input.ssrComponents.length > 0 ? [` renderSsrComponents: { ${input.ssrComponents.map((component) => `${JSON.stringify(component.exportName)}: { renderSsr: ${component.ssrFunctionName} }`).join(", ")} },`] : [];
|
|
640
730
|
const resumeModuleEntry = input.resumeModuleUrl && input.environment !== "client" ? [` resumeModuleUrl: ${JSON.stringify(input.resumeModuleUrl)},`] : [];
|
|
641
731
|
const prerenderWakeModuleEntry = input.prerenderWakeModuleUrl && input.environment !== "client" ? [`\tprerenderWakeModuleUrl: ${JSON.stringify(input.prerenderWakeModuleUrl)},`] : [];
|
|
642
732
|
const inlineResumerEntry = input.inlineResumerSources && input.environment !== "client" ? [`\tinlineResumerSources: ${JSON.stringify(input.inlineResumerSources)},`] : [];
|
|
@@ -661,11 +751,57 @@ function emitCompiledAppDefault(input) {
|
|
|
661
751
|
...renderDataEntry,
|
|
662
752
|
...symbolLoaderEntry,
|
|
663
753
|
...renderSsrEntry,
|
|
754
|
+
...renderSsrComponentsEntry,
|
|
664
755
|
...metadataEntries,
|
|
665
756
|
"};",
|
|
666
|
-
"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
|
+
})
|
|
667
763
|
].join("\n");
|
|
668
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
|
+
}
|
|
669
805
|
function emitResumeContainerEvent(loadSymbolName, needsFullResume, storageFreePayload, leanMode, scalarSpecializations, runtimeDemandMap, executionLogEnabled, prerenderDataId, stagedPrerender = false) {
|
|
670
806
|
const fullResumeHandoff = stagedPrerender && prerenderDataId ? [
|
|
671
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",
|