@jay-framework/stack-server-runtime 0.15.2 → 0.15.4
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/index.d.ts +25 -3
- package/dist/index.js +64 -18
- package/package.json +13 -13
package/dist/index.d.ts
CHANGED
|
@@ -539,6 +539,15 @@ interface PluginClientInitInfo {
|
|
|
539
539
|
*/
|
|
540
540
|
declare function preparePluginClientInits(plugins: PluginWithInit[]): PluginClientInitInfo[];
|
|
541
541
|
|
|
542
|
+
/**
|
|
543
|
+
* Generate JS code to reconstruct Promise.resolve()/Promise.reject() for async ViewState properties.
|
|
544
|
+
* JSON.stringify drops Promise objects, so this emits assignments that recreate them from tracked outcomes.
|
|
545
|
+
*/
|
|
546
|
+
declare function generatePromiseReconstruction(outcomes: Array<{
|
|
547
|
+
id: string;
|
|
548
|
+
status: 'resolved' | 'rejected';
|
|
549
|
+
value: any;
|
|
550
|
+
}>): string;
|
|
542
551
|
/**
|
|
543
552
|
* Information needed to generate client init script for the project.
|
|
544
553
|
*/
|
|
@@ -583,7 +592,21 @@ declare function buildScriptFragments(parts: DevServerPagePart[], clientInitData
|
|
|
583
592
|
* @param mode - 'client' appends to DOM; 'hydrate' skips appendChild (DOM already present)
|
|
584
593
|
*/
|
|
585
594
|
declare function buildAutomationWrap(options: GenerateClientScriptOptions, mode: 'client' | 'hydrate'): string;
|
|
586
|
-
|
|
595
|
+
/**
|
|
596
|
+
* Resolve all top-level Promise values in a ViewState object.
|
|
597
|
+
* Returns the ViewState with Promises replaced by their resolved values,
|
|
598
|
+
* plus a list of outcomes for reconstructing Promise.resolve()/Promise.reject()
|
|
599
|
+
* in the client script.
|
|
600
|
+
*/
|
|
601
|
+
declare function resolveViewStatePromises(viewState: object): Promise<{
|
|
602
|
+
resolved: object;
|
|
603
|
+
outcomes: Array<{
|
|
604
|
+
id: string;
|
|
605
|
+
status: 'resolved' | 'rejected';
|
|
606
|
+
value: any;
|
|
607
|
+
}>;
|
|
608
|
+
}>;
|
|
609
|
+
declare function generateClientScript(defaultViewState: object, fastCarryForward: object, parts: DevServerPagePart[], jayHtmlPath: string, trackByMap?: TrackByMap, clientInitData?: Record<string, Record<string, any>>, projectInit?: ProjectClientInitInfo, pluginInits?: PluginClientInitInfo[], options?: GenerateClientScriptOptions): Promise<string>;
|
|
587
610
|
|
|
588
611
|
/**
|
|
589
612
|
* Invalidate the cached server element module for a jay-html file.
|
|
@@ -896,7 +919,6 @@ interface PluginsIndexEntry {
|
|
|
896
919
|
actions?: ActionIndexEntry[];
|
|
897
920
|
}
|
|
898
921
|
interface PluginsIndex {
|
|
899
|
-
jay_stack_version: string;
|
|
900
922
|
plugins: PluginsIndexEntry[];
|
|
901
923
|
}
|
|
902
924
|
interface MaterializeContractsOptions {
|
|
@@ -1128,4 +1150,4 @@ declare function executePluginReferences(plugin: PluginWithReferences, options:
|
|
|
1128
1150
|
verbose?: boolean;
|
|
1129
1151
|
}): Promise<PluginReferencesResult>;
|
|
1130
1152
|
|
|
1131
|
-
export { type ActionDiscoveryOptions, type ActionDiscoveryResult, type ActionErrorResponse, type ActionExecutionResult, type ActionIndexEntry, type ActionMetadata, ActionRegistry, type ActionSchema, type DevServerPagePart, DevSlowlyChangingPhase, type GenerateClientScriptOptions, type HeadlessInstanceComponent, type InstancePhaseData, type InstanceSlowRenderResult, type LoadedPageParts, type MaterializeContractsOptions, type MaterializeResult, type PluginActionDiscoveryOptions, type PluginClientInitInfo, type PluginContractEntry, type PluginInitDiscoveryOptions, type PluginReferencesContext, type PluginReferencesHandler, type PluginReferencesResult, type PluginScanOptions, type PluginSetupContext, type PluginSetupHandler, type PluginSetupResult, type PluginWithInit, type PluginWithReferences, type PluginWithSetup, type PluginsIndex, type PluginsIndexEntry, type ProjectClientInitInfo, type RegisteredAction, type ScannedPlugin, type ScriptFragments, SlowRenderCache, type SlowRenderCacheEntry, type SlowlyChangingPhase, type ViteSSRLoader, actionRegistry, buildAutomationWrap, buildScriptFragments, clearActionRegistry, clearClientInitData, clearLifecycleCallbacks, clearServerElementCache, clearServiceRegistry, discoverAllPluginActions, discoverAndRegisterActions, discoverPluginActions, discoverPluginsWithInit, discoverPluginsWithReferences, discoverPluginsWithSetup, executeAction, executePluginReferences, executePluginServerInits, executePluginSetup, generateClientScript, generateSSRPageHtml, getActionCacheHeaders, getClientInitData, getClientInitDataForKey, getRegisteredAction, getRegisteredActionNames, getService, getServiceRegistry, hasAction, hasService, invalidateServerElementCache, listContracts, loadActionMetadata, loadPageParts, materializeContracts, onInit, onShutdown, parseActionMetadata, preparePluginClientInits, registerAction, registerService, renderFastChangingData, resolveActionMetadataPath, resolveServices, runInitCallbacks, runLoadParams, runShutdownCallbacks, runSlowlyChangingRender, scanPlugins, setClientInitData, slowRenderInstances, sortPluginsByDependencies, validateForEachInstances };
|
|
1153
|
+
export { type ActionDiscoveryOptions, type ActionDiscoveryResult, type ActionErrorResponse, type ActionExecutionResult, type ActionIndexEntry, type ActionMetadata, ActionRegistry, type ActionSchema, type DevServerPagePart, DevSlowlyChangingPhase, type GenerateClientScriptOptions, type HeadlessInstanceComponent, type InstancePhaseData, type InstanceSlowRenderResult, type LoadedPageParts, type MaterializeContractsOptions, type MaterializeResult, type PluginActionDiscoveryOptions, type PluginClientInitInfo, type PluginContractEntry, type PluginInitDiscoveryOptions, type PluginReferencesContext, type PluginReferencesHandler, type PluginReferencesResult, type PluginScanOptions, type PluginSetupContext, type PluginSetupHandler, type PluginSetupResult, type PluginWithInit, type PluginWithReferences, type PluginWithSetup, type PluginsIndex, type PluginsIndexEntry, type ProjectClientInitInfo, type RegisteredAction, type ScannedPlugin, type ScriptFragments, SlowRenderCache, type SlowRenderCacheEntry, type SlowlyChangingPhase, type ViteSSRLoader, actionRegistry, buildAutomationWrap, buildScriptFragments, clearActionRegistry, clearClientInitData, clearLifecycleCallbacks, clearServerElementCache, clearServiceRegistry, discoverAllPluginActions, discoverAndRegisterActions, discoverPluginActions, discoverPluginsWithInit, discoverPluginsWithReferences, discoverPluginsWithSetup, executeAction, executePluginReferences, executePluginServerInits, executePluginSetup, generateClientScript, generatePromiseReconstruction, generateSSRPageHtml, getActionCacheHeaders, getClientInitData, getClientInitDataForKey, getRegisteredAction, getRegisteredActionNames, getService, getServiceRegistry, hasAction, hasService, invalidateServerElementCache, listContracts, loadActionMetadata, loadPageParts, materializeContracts, onInit, onShutdown, parseActionMetadata, preparePluginClientInits, registerAction, registerService, renderFastChangingData, resolveActionMetadataPath, resolveServices, resolveViewStatePromises, runInitCallbacks, runLoadParams, runShutdownCallbacks, runSlowlyChangingRender, scanPlugins, setClientInitData, slowRenderInstances, sortPluginsByDependencies, validateForEachInstances };
|
package/dist/index.js
CHANGED
|
@@ -483,6 +483,18 @@ async function renderFastChangingData(pageParams, pageProps, carryForward, parts
|
|
|
483
483
|
}
|
|
484
484
|
return Promise.resolve(phaseOutput(fastViewState, fastCarryForward));
|
|
485
485
|
}
|
|
486
|
+
function generatePromiseReconstruction(outcomes) {
|
|
487
|
+
if (outcomes.length === 0)
|
|
488
|
+
return "";
|
|
489
|
+
return outcomes.map((outcome) => {
|
|
490
|
+
if (outcome.status === "resolved") {
|
|
491
|
+
return ` viewState[${JSON.stringify(outcome.id)}] = Promise.resolve(${JSON.stringify(outcome.value)});`;
|
|
492
|
+
} else {
|
|
493
|
+
const errMsg = outcome.value?.message ?? "Unknown error";
|
|
494
|
+
return ` viewState[${JSON.stringify(outcome.id)}] = Promise.reject(new Error(${JSON.stringify(errMsg)}));`;
|
|
495
|
+
}
|
|
496
|
+
}).join("\n") + "\n";
|
|
497
|
+
}
|
|
486
498
|
function buildScriptFragments(parts, clientInitData2, projectInit, pluginInits, options) {
|
|
487
499
|
const { enableAutomation = true, slowViewState } = options;
|
|
488
500
|
const hasSlowViewState = slowViewState && Object.keys(slowViewState).length > 0;
|
|
@@ -558,7 +570,34 @@ function buildAutomationWrap(options, mode) {
|
|
|
558
570
|
window.__jay.automation = wrapped.automation;
|
|
559
571
|
window.dispatchEvent(new Event('jay:automation-ready'));${appendLine}`;
|
|
560
572
|
}
|
|
561
|
-
function
|
|
573
|
+
async function resolveViewStatePromises(viewState) {
|
|
574
|
+
const entries = Object.entries(viewState);
|
|
575
|
+
const hasPromises = entries.some(([, v]) => v instanceof Promise);
|
|
576
|
+
if (!hasPromises)
|
|
577
|
+
return { resolved: viewState, outcomes: [] };
|
|
578
|
+
const result = { ...viewState };
|
|
579
|
+
const outcomes = [];
|
|
580
|
+
for (const [key, value] of entries) {
|
|
581
|
+
if (value instanceof Promise) {
|
|
582
|
+
try {
|
|
583
|
+
const val = await value;
|
|
584
|
+
result[key] = val;
|
|
585
|
+
outcomes.push({ id: key, status: "resolved", value: val });
|
|
586
|
+
} catch (err) {
|
|
587
|
+
delete result[key];
|
|
588
|
+
outcomes.push({
|
|
589
|
+
id: key,
|
|
590
|
+
status: "rejected",
|
|
591
|
+
value: { message: err?.message ?? String(err) }
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return { resolved: result, outcomes };
|
|
597
|
+
}
|
|
598
|
+
async function generateClientScript(defaultViewState, fastCarryForward, parts, jayHtmlPath, trackByMap = {}, clientInitData2 = {}, projectInit, pluginInits = [], options = {}) {
|
|
599
|
+
const { resolved, outcomes } = await resolveViewStatePromises(defaultViewState);
|
|
600
|
+
defaultViewState = resolved;
|
|
562
601
|
const {
|
|
563
602
|
partImports,
|
|
564
603
|
compositeParts,
|
|
@@ -586,7 +625,7 @@ function generateClientScript(defaultViewState, fastCarryForward, parts, jayHtml
|
|
|
586
625
|
import { render } from '${jayHtmlPath}';
|
|
587
626
|
${partImports}${slowViewStateDecl}
|
|
588
627
|
const viewState = ${JSON.stringify(defaultViewState)};
|
|
589
|
-
const fastCarryForward = ${JSON.stringify(fastCarryForward)};
|
|
628
|
+
${generatePromiseReconstruction(outcomes)} const fastCarryForward = ${JSON.stringify(fastCarryForward)};
|
|
590
629
|
const trackByMap = ${JSON.stringify(trackByMap)};
|
|
591
630
|
${clientInitExecution}
|
|
592
631
|
const target = document.getElementById('target');
|
|
@@ -598,6 +637,10 @@ ${automationWrap}
|
|
|
598
637
|
</body>
|
|
599
638
|
</html>`;
|
|
600
639
|
}
|
|
640
|
+
function asyncSwapScript(id, html) {
|
|
641
|
+
const escapedHtml = html.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
642
|
+
return `<script>(function(){var t=document.querySelector('[jay-async="${id}:pending"]');if(t){var d=document.createElement('div');d.innerHTML='${escapedHtml}';t.replaceWith(d.firstChild);}window.__jay&&window.__jay.hydrateAsync&&window.__jay.hydrateAsync('${id}');})()<\/script>`;
|
|
643
|
+
}
|
|
601
644
|
const serverModuleCache = /* @__PURE__ */ new Map();
|
|
602
645
|
function invalidateServerElementCache(jayHtmlPath) {
|
|
603
646
|
if (serverModuleCache.delete(jayHtmlPath)) {
|
|
@@ -625,6 +668,7 @@ async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtm
|
|
|
625
668
|
}
|
|
626
669
|
const htmlChunks = [];
|
|
627
670
|
const asyncPromises = [];
|
|
671
|
+
const asyncOutcomes = [];
|
|
628
672
|
const ctx = {
|
|
629
673
|
write: (chunk) => {
|
|
630
674
|
htmlChunks.push(chunk);
|
|
@@ -632,14 +676,20 @@ async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtm
|
|
|
632
676
|
onAsync: (promise, id, templates) => {
|
|
633
677
|
const asyncPromise = promise.then(
|
|
634
678
|
(val) => {
|
|
679
|
+
asyncOutcomes.push({ id, status: "resolved", value: val });
|
|
635
680
|
if (templates.resolved) {
|
|
636
|
-
return templates.resolved(val);
|
|
681
|
+
return asyncSwapScript(id, templates.resolved(val));
|
|
637
682
|
}
|
|
638
683
|
return "";
|
|
639
684
|
},
|
|
640
685
|
(err) => {
|
|
686
|
+
asyncOutcomes.push({
|
|
687
|
+
id,
|
|
688
|
+
status: "rejected",
|
|
689
|
+
value: { message: err?.message ?? String(err) }
|
|
690
|
+
});
|
|
641
691
|
if (templates.rejected) {
|
|
642
|
-
return templates.rejected(err);
|
|
692
|
+
return asyncSwapScript(id, templates.rejected(err));
|
|
643
693
|
}
|
|
644
694
|
return "";
|
|
645
695
|
}
|
|
@@ -660,7 +710,8 @@ async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtm
|
|
|
660
710
|
clientInitData2,
|
|
661
711
|
projectInit,
|
|
662
712
|
pluginInits,
|
|
663
|
-
options
|
|
713
|
+
options,
|
|
714
|
+
asyncOutcomes
|
|
664
715
|
);
|
|
665
716
|
const headLinksHtml = cached.headLinks.map((link) => {
|
|
666
717
|
const attrs = Object.entries(link.attributes).map(([k, v]) => ` ${k}="${v}"`).join("");
|
|
@@ -722,6 +773,10 @@ async function compileAndLoadServerElement(vite, jayHtmlContent, jayHtmlFilename
|
|
|
722
773
|
const serverElementFilename = jayHtmlFilename.replace(".jay-html", ".server-element.ts");
|
|
723
774
|
const serverElementPath = path__default.join(serverElementDir, serverElementFilename);
|
|
724
775
|
await fs$2.writeFile(serverElementPath, adjustedCode, "utf-8");
|
|
776
|
+
const existingModule = vite.moduleGraph.getModuleById(serverElementPath);
|
|
777
|
+
if (existingModule) {
|
|
778
|
+
vite.moduleGraph.invalidateModule(existingModule);
|
|
779
|
+
}
|
|
725
780
|
const serverModule = await vite.ssrLoadModule(serverElementPath);
|
|
726
781
|
return {
|
|
727
782
|
renderToStream: serverModule.renderToStream,
|
|
@@ -729,7 +784,7 @@ async function compileAndLoadServerElement(vite, jayHtmlContent, jayHtmlFilename
|
|
|
729
784
|
css: parsedJayFile.css
|
|
730
785
|
};
|
|
731
786
|
}
|
|
732
|
-
function generateHydrationScript(defaultViewState, fastCarryForward, parts, jayHtmlPath, trackByMap = {}, clientInitData2 = {}, projectInit, pluginInits = [], options = {}) {
|
|
787
|
+
function generateHydrationScript(defaultViewState, fastCarryForward, parts, jayHtmlPath, trackByMap = {}, clientInitData2 = {}, projectInit, pluginInits = [], options = {}, asyncOutcomes = []) {
|
|
733
788
|
const {
|
|
734
789
|
partImports,
|
|
735
790
|
compositeParts,
|
|
@@ -749,7 +804,7 @@ function generateHydrationScript(defaultViewState, fastCarryForward, parts, jayH
|
|
|
749
804
|
import { hydrate } from '${hydrateImportPath}';
|
|
750
805
|
${partImports}${slowViewStateDecl}
|
|
751
806
|
const viewState = ${JSON.stringify(defaultViewState)};
|
|
752
|
-
const fastCarryForward = ${JSON.stringify(fastCarryForward)};
|
|
807
|
+
${generatePromiseReconstruction(asyncOutcomes)} const fastCarryForward = ${JSON.stringify(fastCarryForward)};
|
|
753
808
|
const trackByMap = ${JSON.stringify(trackByMap)};
|
|
754
809
|
|
|
755
810
|
const target = document.getElementById('target');
|
|
@@ -2042,15 +2097,6 @@ function resolveActionFilePath(actionPath, packageName, pluginPath, isLocal, pro
|
|
|
2042
2097
|
function toKebabCase(str) {
|
|
2043
2098
|
return str.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
2044
2099
|
}
|
|
2045
|
-
function getJayStackVersion() {
|
|
2046
|
-
try {
|
|
2047
|
-
const packageJsonPath = path.join(__dirname, "..", "package.json");
|
|
2048
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
2049
|
-
return packageJson.version || "0.0.0";
|
|
2050
|
-
} catch {
|
|
2051
|
-
return "0.0.0";
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
2100
|
async function materializeContracts(options, services = /* @__PURE__ */ new Map()) {
|
|
2055
2101
|
const {
|
|
2056
2102
|
projectRoot,
|
|
@@ -2183,7 +2229,6 @@ async function materializeContracts(options, services = /* @__PURE__ */ new Map(
|
|
|
2183
2229
|
}
|
|
2184
2230
|
}
|
|
2185
2231
|
const pluginsIndex = {
|
|
2186
|
-
jay_stack_version: getJayStackVersion(),
|
|
2187
2232
|
plugins: Array.from(pluginsIndexMap.entries()).map(([name, data]) => ({
|
|
2188
2233
|
name,
|
|
2189
2234
|
path: data.path,
|
|
@@ -2251,7 +2296,6 @@ async function listContracts(options) {
|
|
|
2251
2296
|
}
|
|
2252
2297
|
}
|
|
2253
2298
|
return {
|
|
2254
|
-
jay_stack_version: getJayStackVersion(),
|
|
2255
2299
|
plugins: Array.from(pluginsMap.entries()).map(([name, data]) => ({
|
|
2256
2300
|
name,
|
|
2257
2301
|
path: data.path,
|
|
@@ -2409,6 +2453,7 @@ export {
|
|
|
2409
2453
|
executePluginServerInits,
|
|
2410
2454
|
executePluginSetup,
|
|
2411
2455
|
generateClientScript,
|
|
2456
|
+
generatePromiseReconstruction,
|
|
2412
2457
|
generateSSRPageHtml,
|
|
2413
2458
|
getActionCacheHeaders,
|
|
2414
2459
|
getClientInitData,
|
|
@@ -2433,6 +2478,7 @@ export {
|
|
|
2433
2478
|
renderFastChangingData,
|
|
2434
2479
|
resolveActionMetadataPath,
|
|
2435
2480
|
resolveServices,
|
|
2481
|
+
resolveViewStatePromises,
|
|
2436
2482
|
runInitCallbacks,
|
|
2437
2483
|
runLoadParams,
|
|
2438
2484
|
runShutdownCallbacks,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/stack-server-runtime",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.4",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.mts",
|
|
@@ -26,21 +26,21 @@
|
|
|
26
26
|
"test:watch": "vitest"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@jay-framework/compiler-jay-html": "^0.15.
|
|
30
|
-
"@jay-framework/compiler-shared": "^0.15.
|
|
31
|
-
"@jay-framework/component": "^0.15.
|
|
32
|
-
"@jay-framework/fullstack-component": "^0.15.
|
|
33
|
-
"@jay-framework/logger": "^0.15.
|
|
34
|
-
"@jay-framework/runtime": "^0.15.
|
|
35
|
-
"@jay-framework/ssr-runtime": "^0.15.
|
|
36
|
-
"@jay-framework/stack-route-scanner": "^0.15.
|
|
37
|
-
"@jay-framework/view-state-merge": "^0.15.
|
|
29
|
+
"@jay-framework/compiler-jay-html": "^0.15.4",
|
|
30
|
+
"@jay-framework/compiler-shared": "^0.15.4",
|
|
31
|
+
"@jay-framework/component": "^0.15.4",
|
|
32
|
+
"@jay-framework/fullstack-component": "^0.15.4",
|
|
33
|
+
"@jay-framework/logger": "^0.15.4",
|
|
34
|
+
"@jay-framework/runtime": "^0.15.4",
|
|
35
|
+
"@jay-framework/ssr-runtime": "^0.15.4",
|
|
36
|
+
"@jay-framework/stack-route-scanner": "^0.15.4",
|
|
37
|
+
"@jay-framework/view-state-merge": "^0.15.4",
|
|
38
38
|
"yaml": "^2.3.4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@jay-framework/dev-environment": "^0.15.
|
|
42
|
-
"@jay-framework/jay-cli": "^0.15.
|
|
43
|
-
"@jay-framework/stack-client-runtime": "^0.15.
|
|
41
|
+
"@jay-framework/dev-environment": "^0.15.4",
|
|
42
|
+
"@jay-framework/jay-cli": "^0.15.4",
|
|
43
|
+
"@jay-framework/stack-client-runtime": "^0.15.4",
|
|
44
44
|
"@types/express": "^5.0.2",
|
|
45
45
|
"@types/node": "^22.15.21",
|
|
46
46
|
"nodemon": "^3.0.3",
|