@jay-framework/stack-server-runtime 0.15.4 → 0.15.6
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 +55 -3
- package/dist/index.js +311 -56
- package/package.json +13 -13
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AnyJayStackComponentDefinition, PageProps, AnySlowlyRenderResult, UrlParams, JayStackComponentDefinition, AnyFastRenderResult, HttpMethod, CacheOptions, JayAction, JayActionDefinition, ServiceMarker } from '@jay-framework/fullstack-component';
|
|
1
|
+
import { AnyJayStackComponentDefinition, PageProps, AnySlowlyRenderResult, UrlParams, JayStackComponentDefinition, AnyFastRenderResult, HttpMethod, CacheOptions, JayAction, JayActionDefinition, HeadTag, ServiceMarker } from '@jay-framework/fullstack-component';
|
|
2
2
|
import { JayComponentCore } from '@jay-framework/component';
|
|
3
3
|
import { ViteDevServer } from 'vite';
|
|
4
4
|
import { JayRoute } from '@jay-framework/stack-route-scanner';
|
|
@@ -49,6 +49,10 @@ interface LoadedPageParts {
|
|
|
49
49
|
discoveredInstances: DiscoveredHeadlessInstance[];
|
|
50
50
|
/** Discovered forEach <jay:xxx> instances from the jay-html (DL#109) */
|
|
51
51
|
forEachInstances: ForEachHeadlessInstance[];
|
|
52
|
+
/** Absolute paths to linked CSS files (from <link rel="stylesheet">) for dev-server watching */
|
|
53
|
+
linkedCssFiles: string[];
|
|
54
|
+
/** Absolute paths to headfull FS component jay-html files for dev-server watching */
|
|
55
|
+
linkedComponentFiles: string[];
|
|
52
56
|
}
|
|
53
57
|
interface LoadPagePartsOptions {
|
|
54
58
|
/**
|
|
@@ -97,6 +101,8 @@ interface InstancePhaseData {
|
|
|
97
101
|
}>;
|
|
98
102
|
/** CarryForward per instance (keyed by coordinate path, e.g. "p1/product-card:0") */
|
|
99
103
|
carryForwards: Record<string, object>;
|
|
104
|
+
/** Slow ViewState per instance (keyed by coordinate path) */
|
|
105
|
+
slowViewStates?: Record<string, object>;
|
|
100
106
|
/** ForEach instances that need fast-phase per-item rendering */
|
|
101
107
|
forEachInstances?: ForEachHeadlessInstance[];
|
|
102
108
|
}
|
|
@@ -626,7 +632,11 @@ declare function clearServerElementCache(): void;
|
|
|
626
632
|
* 3. Build hydration script (uses ?jay-hydrate query for hydrate target)
|
|
627
633
|
* 4. Return full HTML page string
|
|
628
634
|
*/
|
|
629
|
-
declare function generateSSRPageHtml(vite: ViteDevServer, jayHtmlContent: string, jayHtmlFilename: string, jayHtmlDir: string, viewState: object, jayHtmlImportPath: string, parts: DevServerPagePart[], carryForward: object, trackByMap: TrackByMap, clientInitData: Record<string, Record<string, any>>, buildFolder: string, projectRoot: string, routeDir: string, tsConfigFilePath?: string, projectInit?: ProjectClientInitInfo, pluginInits?: PluginClientInitInfo[], options?: GenerateClientScriptOptions
|
|
635
|
+
declare function generateSSRPageHtml(vite: ViteDevServer, jayHtmlContent: string, jayHtmlFilename: string, jayHtmlDir: string, viewState: object, jayHtmlImportPath: string, parts: DevServerPagePart[], carryForward: object, trackByMap: TrackByMap, clientInitData: Record<string, Record<string, any>>, buildFolder: string, projectRoot: string, routeDir: string, tsConfigFilePath?: string, projectInit?: ProjectClientInitInfo, pluginInits?: PluginClientInitInfo[], options?: GenerateClientScriptOptions,
|
|
636
|
+
/** Source directory for headfull FS file resolution when jayHtmlDir is pre-rendered */
|
|
637
|
+
sourceDir?: string,
|
|
638
|
+
/** Head tags to inject into <head> during SSR (Design Log #127) */
|
|
639
|
+
headTags?: HeadTag[]): Promise<string>;
|
|
630
640
|
|
|
631
641
|
/**
|
|
632
642
|
* Service registry for Jay Stack server-side dependency injection.
|
|
@@ -906,10 +916,25 @@ interface ActionIndexEntry {
|
|
|
906
916
|
/** Contract entry within a plugin in plugins-index.yaml */
|
|
907
917
|
interface PluginContractEntry {
|
|
908
918
|
name: string;
|
|
919
|
+
description?: string;
|
|
909
920
|
type: 'static' | 'dynamic';
|
|
910
921
|
path: string;
|
|
911
922
|
metadata?: Record<string, unknown>;
|
|
912
923
|
}
|
|
924
|
+
/** Service entry in plugins-index.yaml (DL#125) */
|
|
925
|
+
interface ServiceIndexEntry {
|
|
926
|
+
name: string;
|
|
927
|
+
marker: string;
|
|
928
|
+
description?: string;
|
|
929
|
+
doc?: string;
|
|
930
|
+
}
|
|
931
|
+
/** Context entry in plugins-index.yaml (DL#125) */
|
|
932
|
+
interface ContextIndexEntry {
|
|
933
|
+
name: string;
|
|
934
|
+
marker: string;
|
|
935
|
+
description?: string;
|
|
936
|
+
doc?: string;
|
|
937
|
+
}
|
|
913
938
|
/** Entry for plugins-index.yaml (Design Log #85) */
|
|
914
939
|
interface PluginsIndexEntry {
|
|
915
940
|
name: string;
|
|
@@ -917,6 +942,10 @@ interface PluginsIndexEntry {
|
|
|
917
942
|
contracts: PluginContractEntry[];
|
|
918
943
|
/** Actions with .jay-action metadata (exposed to AI agents) */
|
|
919
944
|
actions?: ActionIndexEntry[];
|
|
945
|
+
/** Server-side services provided by this plugin (DL#125) */
|
|
946
|
+
services?: ServiceIndexEntry[];
|
|
947
|
+
/** Client-side contexts provided by this plugin (DL#125) */
|
|
948
|
+
contexts?: ContextIndexEntry[];
|
|
920
949
|
}
|
|
921
950
|
interface PluginsIndex {
|
|
922
951
|
plugins: PluginsIndexEntry[];
|
|
@@ -1150,4 +1179,27 @@ declare function executePluginReferences(plugin: PluginWithReferences, options:
|
|
|
1150
1179
|
verbose?: boolean;
|
|
1151
1180
|
}): Promise<PluginReferencesResult>;
|
|
1152
1181
|
|
|
1153
|
-
|
|
1182
|
+
/**
|
|
1183
|
+
* Head tag utilities for SSR head injection (Design Log #127).
|
|
1184
|
+
*
|
|
1185
|
+
* Components declare HeadTag[] via phaseOutput(). The SSR pipeline collects
|
|
1186
|
+
* tags from all sources, deduplicates with last-write-wins + collision warning,
|
|
1187
|
+
* and serializes to HTML for injection into <head>.
|
|
1188
|
+
*/
|
|
1189
|
+
|
|
1190
|
+
/**
|
|
1191
|
+
* Compute a unique identity key for deduplication.
|
|
1192
|
+
* Returns undefined for tags that should always be included (no dedup).
|
|
1193
|
+
*/
|
|
1194
|
+
declare function tagIdentityKey(tag: HeadTag): string | undefined;
|
|
1195
|
+
/**
|
|
1196
|
+
* Merge head tags from multiple sources with last-write-wins.
|
|
1197
|
+
* Warns on collision via logger.
|
|
1198
|
+
*/
|
|
1199
|
+
declare function mergeHeadTags(sources: HeadTag[][]): HeadTag[];
|
|
1200
|
+
/**
|
|
1201
|
+
* Serialize an array of HeadTag objects into an HTML string.
|
|
1202
|
+
*/
|
|
1203
|
+
declare function serializeHeadTags(tags: HeadTag[]): string;
|
|
1204
|
+
|
|
1205
|
+
export { type ActionDiscoveryOptions, type ActionDiscoveryResult, type ActionErrorResponse, type ActionExecutionResult, type ActionIndexEntry, type ActionMetadata, ActionRegistry, type ActionSchema, type ContextIndexEntry, 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, type ServiceIndexEntry, 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, mergeHeadTags, onInit, onShutdown, parseActionMetadata, preparePluginClientInits, registerAction, registerService, renderFastChangingData, resolveActionMetadataPath, resolveServices, resolveViewStatePromises, runInitCallbacks, runLoadParams, runShutdownCallbacks, runSlowlyChangingRender, scanPlugins, serializeHeadTags, setClientInitData, slowRenderInstances, sortPluginsByDependencies, tagIdentityKey, validateForEachInstances };
|
package/dist/index.js
CHANGED
|
@@ -11,14 +11,14 @@ import fs$1 from "fs";
|
|
|
11
11
|
import path$1 from "path";
|
|
12
12
|
import YAML from "yaml";
|
|
13
13
|
import { createRequire } from "module";
|
|
14
|
-
import { parseJayFile, JAY_IMPORT_RESOLVER, generateServerElementFile, discoverHeadlessInstances, parseAction } from "@jay-framework/compiler-jay-html";
|
|
14
|
+
import { parseJayFile, JAY_IMPORT_RESOLVER, generateServerElementFile, injectHeadfullFSTemplates, discoverHeadlessInstances, assignCoordinatesToJayHtml, parseAction } from "@jay-framework/compiler-jay-html";
|
|
15
|
+
import { getLogger } from "@jay-framework/logger";
|
|
15
16
|
import fs$2 from "node:fs/promises";
|
|
16
17
|
import * as path from "node:path";
|
|
17
18
|
import path__default from "node:path";
|
|
18
|
-
import
|
|
19
|
+
import crypto from "node:crypto";
|
|
19
20
|
import * as fs from "node:fs";
|
|
20
21
|
import { createRequire as createRequire$1 } from "node:module";
|
|
21
|
-
import crypto from "node:crypto";
|
|
22
22
|
const serviceRegistry = /* @__PURE__ */ new Map();
|
|
23
23
|
function registerService(marker, service) {
|
|
24
24
|
serviceRegistry.set(marker, service);
|
|
@@ -87,6 +87,7 @@ class DevSlowlyChangingPhase {
|
|
|
87
87
|
async runSlowlyForPage(pageParams, pageProps, parts, discoveredInstances, headlessInstanceComponents, jayHtmlPath) {
|
|
88
88
|
let slowlyViewState = {};
|
|
89
89
|
let carryForward = {};
|
|
90
|
+
const slowHeadTagSources = [];
|
|
90
91
|
for (const part of parts) {
|
|
91
92
|
const { compDefinition, key, contractInfo } = part;
|
|
92
93
|
if (compDefinition.slowlyRender) {
|
|
@@ -111,6 +112,9 @@ class DevSlowlyChangingPhase {
|
|
|
111
112
|
slowlyViewState[key] = slowlyRenderedPart.rendered;
|
|
112
113
|
carryForward[key] = slowlyRenderedPart.carryForward;
|
|
113
114
|
}
|
|
115
|
+
if (slowlyRenderedPart.headTags) {
|
|
116
|
+
slowHeadTagSources.push(slowlyRenderedPart.headTags);
|
|
117
|
+
}
|
|
114
118
|
} else
|
|
115
119
|
return slowlyRenderedPart;
|
|
116
120
|
}
|
|
@@ -158,6 +162,9 @@ class DevSlowlyChangingPhase {
|
|
|
158
162
|
contract: comp.contract,
|
|
159
163
|
slowViewState: slowResult.rendered
|
|
160
164
|
});
|
|
165
|
+
if (slowResult.headTags) {
|
|
166
|
+
slowHeadTagSources.push(slowResult.headTags);
|
|
167
|
+
}
|
|
161
168
|
}
|
|
162
169
|
}
|
|
163
170
|
}
|
|
@@ -165,6 +172,9 @@ class DevSlowlyChangingPhase {
|
|
|
165
172
|
carryForward.__instanceSlowViewStates = instanceSlowViewStates;
|
|
166
173
|
carryForward.__instanceResolvedData = instanceResolvedData;
|
|
167
174
|
}
|
|
175
|
+
if (slowHeadTagSources.length > 0) {
|
|
176
|
+
carryForward.__slowHeadTags = slowHeadTagSources;
|
|
177
|
+
}
|
|
168
178
|
return phaseOutput(slowlyViewState, carryForward);
|
|
169
179
|
}
|
|
170
180
|
}
|
|
@@ -203,7 +213,7 @@ new JayObjectType("Error", {
|
|
|
203
213
|
stack: new JayAtomicType("string")
|
|
204
214
|
});
|
|
205
215
|
function isOptionalType(aType) {
|
|
206
|
-
return aType.kind ===
|
|
216
|
+
return aType.kind === 14;
|
|
207
217
|
}
|
|
208
218
|
function isAtomicType(aType) {
|
|
209
219
|
return aType.kind === 0;
|
|
@@ -220,6 +230,9 @@ function isObjectType(aType) {
|
|
|
220
230
|
function isArrayType(aType) {
|
|
221
231
|
return aType.kind === 9;
|
|
222
232
|
}
|
|
233
|
+
function isRecordType(aType) {
|
|
234
|
+
return aType.kind === 11;
|
|
235
|
+
}
|
|
223
236
|
function jayTypeToJsonSchema(type) {
|
|
224
237
|
if (isOptionalType(type)) {
|
|
225
238
|
return jayTypeToJsonSchema(type.innerType);
|
|
@@ -244,6 +257,13 @@ function jayTypeToJsonSchema(type) {
|
|
|
244
257
|
}
|
|
245
258
|
return { type: "array" };
|
|
246
259
|
}
|
|
260
|
+
if (isRecordType(type)) {
|
|
261
|
+
const valueSchema = jayTypeToJsonSchema(type.itemType);
|
|
262
|
+
if (valueSchema) {
|
|
263
|
+
return { type: "object", additionalProperties: valueSchema };
|
|
264
|
+
}
|
|
265
|
+
return { type: "object" };
|
|
266
|
+
}
|
|
247
267
|
if (isObjectType(type)) {
|
|
248
268
|
const properties = {};
|
|
249
269
|
const required = [];
|
|
@@ -368,6 +388,7 @@ function resolveBinding(binding, item) {
|
|
|
368
388
|
async function renderFastChangingData(pageParams, pageProps, carryForward, parts, instancePhaseData, forEachInstances, headlessInstanceComponents, mergedSlowViewState, query = {}) {
|
|
369
389
|
let fastViewState = {};
|
|
370
390
|
let fastCarryForward = {};
|
|
391
|
+
const fastHeadTagSources = [];
|
|
371
392
|
for (const part of parts) {
|
|
372
393
|
const { compDefinition, key, contractInfo } = part;
|
|
373
394
|
if (compDefinition.fastRender) {
|
|
@@ -395,6 +416,9 @@ async function renderFastChangingData(pageParams, pageProps, carryForward, parts
|
|
|
395
416
|
fastViewState[key] = fastRenderedPart.rendered;
|
|
396
417
|
fastCarryForward[key] = fastRenderedPart.carryForward;
|
|
397
418
|
}
|
|
419
|
+
if (fastRenderedPart.headTags) {
|
|
420
|
+
fastHeadTagSources.push(fastRenderedPart.headTags);
|
|
421
|
+
}
|
|
398
422
|
} else
|
|
399
423
|
return fastRenderedPart;
|
|
400
424
|
}
|
|
@@ -409,18 +433,25 @@ async function renderFastChangingData(pageParams, pageProps, carryForward, parts
|
|
|
409
433
|
for (const instance of instancePhaseData.discovered) {
|
|
410
434
|
const coordKey = instance.coordinate.join("/");
|
|
411
435
|
const comp = componentByContractName.get(instance.contractName);
|
|
412
|
-
if (!comp
|
|
436
|
+
if (!comp)
|
|
413
437
|
continue;
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
438
|
+
const instanceSlowVS = instancePhaseData.slowViewStates?.[coordKey] ?? carryForward?.__instanceSlowViewStates?.[coordKey];
|
|
439
|
+
if (comp.compDefinition.fastRender) {
|
|
440
|
+
const services = resolveServices(comp.compDefinition.services);
|
|
441
|
+
const cf = instancePhaseData.carryForwards[coordKey];
|
|
442
|
+
const instanceProps = { ...instance.props, query };
|
|
443
|
+
const fastResult = comp.compDefinition.slowlyRender ? await comp.compDefinition.fastRender(instanceProps, cf, ...services) : await comp.compDefinition.fastRender(instanceProps, ...services);
|
|
444
|
+
if (fastResult.kind === "PhaseOutput") {
|
|
445
|
+
instanceViewStates[coordKey] = instanceSlowVS ? { ...instanceSlowVS, ...fastResult.rendered } : fastResult.rendered;
|
|
446
|
+
if (fastResult.carryForward) {
|
|
447
|
+
instanceCarryForwards[coordKey] = fastResult.carryForward;
|
|
448
|
+
}
|
|
449
|
+
if (fastResult.headTags) {
|
|
450
|
+
fastHeadTagSources.push(fastResult.headTags);
|
|
451
|
+
}
|
|
423
452
|
}
|
|
453
|
+
} else {
|
|
454
|
+
instanceViewStates[coordKey] = instanceSlowVS ?? {};
|
|
424
455
|
}
|
|
425
456
|
}
|
|
426
457
|
}
|
|
@@ -481,7 +512,11 @@ async function renderFastChangingData(pageParams, pageProps, carryForward, parts
|
|
|
481
512
|
if (Object.keys(instanceCarryForwards).length > 0) {
|
|
482
513
|
fastCarryForward.__headlessInstances = instanceCarryForwards;
|
|
483
514
|
}
|
|
484
|
-
|
|
515
|
+
const result = phaseOutput(fastViewState, fastCarryForward);
|
|
516
|
+
if (fastHeadTagSources.length > 0) {
|
|
517
|
+
result.headTags = fastHeadTagSources.flat();
|
|
518
|
+
}
|
|
519
|
+
return Promise.resolve(result);
|
|
485
520
|
}
|
|
486
521
|
function generatePromiseReconstruction(outcomes) {
|
|
487
522
|
if (outcomes.length === 0)
|
|
@@ -625,7 +660,8 @@ async function generateClientScript(defaultViewState, fastCarryForward, parts, j
|
|
|
625
660
|
import { render } from '${jayHtmlPath}';
|
|
626
661
|
${partImports}${slowViewStateDecl}
|
|
627
662
|
const viewState = ${JSON.stringify(defaultViewState)};
|
|
628
|
-
${generatePromiseReconstruction(outcomes)}
|
|
663
|
+
${generatePromiseReconstruction(outcomes)}
|
|
664
|
+
const fastCarryForward = ${JSON.stringify(fastCarryForward)};
|
|
629
665
|
const trackByMap = ${JSON.stringify(trackByMap)};
|
|
630
666
|
${clientInitExecution}
|
|
631
667
|
const target = document.getElementById('target');
|
|
@@ -641,6 +677,65 @@ function asyncSwapScript(id, html) {
|
|
|
641
677
|
const escapedHtml = html.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
642
678
|
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
679
|
}
|
|
680
|
+
function tagIdentityKey(tag) {
|
|
681
|
+
const t = tag.tag.toLowerCase();
|
|
682
|
+
if (t === "title")
|
|
683
|
+
return "title";
|
|
684
|
+
if (t === "meta") {
|
|
685
|
+
if (tag.attrs?.name)
|
|
686
|
+
return `meta:name:${tag.attrs.name}`;
|
|
687
|
+
if (tag.attrs?.property)
|
|
688
|
+
return `meta:property:${tag.attrs.property}`;
|
|
689
|
+
if (tag.attrs?.charset !== void 0)
|
|
690
|
+
return "meta:charset";
|
|
691
|
+
return void 0;
|
|
692
|
+
}
|
|
693
|
+
if (t === "link") {
|
|
694
|
+
if (tag.attrs?.rel === "canonical")
|
|
695
|
+
return "link:canonical";
|
|
696
|
+
return void 0;
|
|
697
|
+
}
|
|
698
|
+
return void 0;
|
|
699
|
+
}
|
|
700
|
+
function mergeHeadTags(sources) {
|
|
701
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
702
|
+
const result = [];
|
|
703
|
+
for (let si = 0; si < sources.length; si++) {
|
|
704
|
+
for (const tag of sources[si]) {
|
|
705
|
+
const key = tagIdentityKey(tag);
|
|
706
|
+
if (key) {
|
|
707
|
+
const existing = byKey.get(key);
|
|
708
|
+
if (existing && existing.sourceIndex !== si) {
|
|
709
|
+
getLogger().warn(
|
|
710
|
+
`[head-tags] Collision on "${key}" — overwriting with tag from source ${si}`
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
byKey.set(key, { tag, sourceIndex: si });
|
|
714
|
+
} else {
|
|
715
|
+
result.push(tag);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return [...[...byKey.values()].map((v) => v.tag), ...result];
|
|
720
|
+
}
|
|
721
|
+
function escapeAttr(value) {
|
|
722
|
+
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
723
|
+
}
|
|
724
|
+
function escapeHtml(value) {
|
|
725
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
726
|
+
}
|
|
727
|
+
const VOID_ELEMENTS = /* @__PURE__ */ new Set(["meta", "link", "base", "br", "hr", "img", "input"]);
|
|
728
|
+
function serializeHeadTags(tags) {
|
|
729
|
+
return tags.map((tag) => {
|
|
730
|
+
const t = tag.tag.toLowerCase();
|
|
731
|
+
const attrs = tag.attrs ? Object.entries(tag.attrs).map(([k, v]) => ` ${k}="${escapeAttr(v)}"`).join("") : "";
|
|
732
|
+
if (VOID_ELEMENTS.has(t)) {
|
|
733
|
+
return ` <${t}${attrs} />`;
|
|
734
|
+
}
|
|
735
|
+
const children = tag.children ? escapeHtml(tag.children) : "";
|
|
736
|
+
return ` <${t}${attrs}>${children}</${t}>`;
|
|
737
|
+
}).join("\n");
|
|
738
|
+
}
|
|
644
739
|
const serverModuleCache = /* @__PURE__ */ new Map();
|
|
645
740
|
function invalidateServerElementCache(jayHtmlPath) {
|
|
646
741
|
if (serverModuleCache.delete(jayHtmlPath)) {
|
|
@@ -650,7 +745,7 @@ function invalidateServerElementCache(jayHtmlPath) {
|
|
|
650
745
|
function clearServerElementCache() {
|
|
651
746
|
serverModuleCache.clear();
|
|
652
747
|
}
|
|
653
|
-
async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtmlDir, viewState, jayHtmlImportPath, parts, carryForward, trackByMap = {}, clientInitData2 = {}, buildFolder, projectRoot, routeDir, tsConfigFilePath, projectInit, pluginInits = [], options = {}) {
|
|
748
|
+
async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtmlDir, viewState, jayHtmlImportPath, parts, carryForward, trackByMap = {}, clientInitData2 = {}, buildFolder, projectRoot, routeDir, tsConfigFilePath, projectInit, pluginInits = [], options = {}, sourceDir, headTags) {
|
|
654
749
|
const jayHtmlPath = path__default.join(jayHtmlDir, jayHtmlFilename);
|
|
655
750
|
let cached = serverModuleCache.get(jayHtmlPath);
|
|
656
751
|
if (!cached) {
|
|
@@ -662,7 +757,8 @@ async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtm
|
|
|
662
757
|
buildFolder,
|
|
663
758
|
projectRoot,
|
|
664
759
|
routeDir,
|
|
665
|
-
tsConfigFilePath
|
|
760
|
+
tsConfigFilePath,
|
|
761
|
+
sourceDir
|
|
666
762
|
);
|
|
667
763
|
serverModuleCache.set(jayHtmlPath, cached);
|
|
668
764
|
}
|
|
@@ -717,17 +813,17 @@ async function generateSSRPageHtml(vite, jayHtmlContent, jayHtmlFilename, jayHtm
|
|
|
717
813
|
const attrs = Object.entries(link.attributes).map(([k, v]) => ` ${k}="${v}"`).join("");
|
|
718
814
|
return ` <link rel="${link.rel}" href="${link.href}"${attrs} />`;
|
|
719
815
|
}).join("\n");
|
|
720
|
-
const
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
const
|
|
816
|
+
const cssLink = cached.cssHref ? ` <link rel="stylesheet" href="${cached.cssHref}" />` : "";
|
|
817
|
+
const headTagsHtml = headTags && headTags.length > 0 ? serializeHeadTags(headTags) : "";
|
|
818
|
+
const hasCustomTitle = headTags?.some((t) => t.tag.toLowerCase() === "title");
|
|
819
|
+
const titleHtml = hasCustomTitle ? "" : " <title>Vite + TS</title>\n";
|
|
820
|
+
const headExtras = [headLinksHtml, cssLink, headTagsHtml].filter((_) => _).join("\n");
|
|
724
821
|
return `<!doctype html>
|
|
725
822
|
<html lang="en">
|
|
726
823
|
<head>
|
|
727
824
|
<meta charset="UTF-8" />
|
|
728
825
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
729
|
-
|
|
730
|
-
${headExtras ? headExtras + "\n" : ""} </head>
|
|
826
|
+
${titleHtml}${headExtras ? headExtras + "\n" : ""} </head>
|
|
731
827
|
<body>
|
|
732
828
|
<div id="target">${ssrHtml}</div>${asyncScripts}
|
|
733
829
|
${hydrationScript}
|
|
@@ -744,14 +840,15 @@ function rebaseRelativeImports(code, fromDir, toDir) {
|
|
|
744
840
|
return `from "${newRelPath}"`;
|
|
745
841
|
});
|
|
746
842
|
}
|
|
747
|
-
async function compileAndLoadServerElement(vite, jayHtmlContent, jayHtmlFilename, jayHtmlDir, buildFolder, projectRoot, routeDir, tsConfigFilePath) {
|
|
843
|
+
async function compileAndLoadServerElement(vite, jayHtmlContent, jayHtmlFilename, jayHtmlDir, buildFolder, projectRoot, routeDir, tsConfigFilePath, sourceDir) {
|
|
748
844
|
const jayFile = await parseJayFile(
|
|
749
845
|
jayHtmlContent,
|
|
750
846
|
jayHtmlFilename,
|
|
751
847
|
jayHtmlDir,
|
|
752
848
|
{ relativePath: tsConfigFilePath },
|
|
753
849
|
JAY_IMPORT_RESOLVER,
|
|
754
|
-
projectRoot
|
|
850
|
+
projectRoot,
|
|
851
|
+
sourceDir
|
|
755
852
|
);
|
|
756
853
|
const parsedJayFile = checkValidationErrors(jayFile);
|
|
757
854
|
const pageName = jayHtmlFilename.replace(".jay-html", "");
|
|
@@ -777,13 +874,57 @@ async function compileAndLoadServerElement(vite, jayHtmlContent, jayHtmlFilename
|
|
|
777
874
|
if (existingModule) {
|
|
778
875
|
vite.moduleGraph.invalidateModule(existingModule);
|
|
779
876
|
}
|
|
877
|
+
const jayHtmlPath = path__default.join(serverElementDir, jayHtmlFilename);
|
|
878
|
+
invalidateJayHtmlModules(vite, jayHtmlPath);
|
|
780
879
|
const serverModule = await vite.ssrLoadModule(serverElementPath);
|
|
880
|
+
let cssHref;
|
|
881
|
+
if (parsedJayFile.css) {
|
|
882
|
+
const cssFilename = jayHtmlFilename.replace(".jay-html", ".css");
|
|
883
|
+
const cssPath = path__default.join(serverElementDir, cssFilename);
|
|
884
|
+
await fs$2.writeFile(cssPath, parsedJayFile.css, "utf-8");
|
|
885
|
+
const cssModules = vite.moduleGraph.getModulesByFile(cssPath);
|
|
886
|
+
if (cssModules) {
|
|
887
|
+
for (const mod of cssModules) {
|
|
888
|
+
vite.moduleGraph.invalidateModule(mod);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
const hash = crypto.createHash("md5").update(parsedJayFile.css).digest("hex").slice(0, 8);
|
|
892
|
+
cssHref = "/@fs" + cssPath + "?v=" + hash + "&direct";
|
|
893
|
+
}
|
|
781
894
|
return {
|
|
782
895
|
renderToStream: serverModule.renderToStream,
|
|
783
896
|
headLinks: parsedJayFile.headLinks,
|
|
784
|
-
|
|
897
|
+
cssHref
|
|
785
898
|
};
|
|
786
899
|
}
|
|
900
|
+
function invalidateJayHtmlModules(vite, jayHtmlPath) {
|
|
901
|
+
let count = 0;
|
|
902
|
+
const byFile = vite.moduleGraph.getModulesByFile(jayHtmlPath);
|
|
903
|
+
if (byFile) {
|
|
904
|
+
for (const mod of byFile) {
|
|
905
|
+
vite.moduleGraph.invalidateModule(mod);
|
|
906
|
+
count++;
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
const knownIds = [jayHtmlPath + ".ts", jayHtmlPath + JAY_QUERY_HYDRATE + ".ts"];
|
|
910
|
+
for (const id of knownIds) {
|
|
911
|
+
const mod = vite.moduleGraph.getModuleById(id);
|
|
912
|
+
if (mod) {
|
|
913
|
+
vite.moduleGraph.invalidateModule(mod);
|
|
914
|
+
count++;
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
const idMap = vite.moduleGraph.idToModuleMap;
|
|
918
|
+
for (const [id, mod] of idMap) {
|
|
919
|
+
if (id.includes(jayHtmlPath)) {
|
|
920
|
+
vite.moduleGraph.invalidateModule(mod);
|
|
921
|
+
count++;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
if (count > 0) {
|
|
925
|
+
getLogger().info(`[SSR] Invalidated ${count} Vite module(s) for ${jayHtmlPath}`);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
787
928
|
function generateHydrationScript(defaultViewState, fastCarryForward, parts, jayHtmlPath, trackByMap = {}, clientInitData2 = {}, projectInit, pluginInits = [], options = {}, asyncOutcomes = []) {
|
|
788
929
|
const {
|
|
789
930
|
partImports,
|
|
@@ -885,7 +1026,29 @@ async function loadPageParts(vite, route, pagesBase, projectBase, jayRollupConfi
|
|
|
885
1026
|
contract: hi.contract,
|
|
886
1027
|
contractPath: hi.contractPath
|
|
887
1028
|
}));
|
|
888
|
-
const
|
|
1029
|
+
const jayHtmlForDiscovery = injectHeadfullFSTemplates(
|
|
1030
|
+
jayHtmlSource,
|
|
1031
|
+
dirName,
|
|
1032
|
+
JAY_IMPORT_RESOLVER
|
|
1033
|
+
);
|
|
1034
|
+
let discoveryResult;
|
|
1035
|
+
if (headlessInstanceComponents.length > 0) {
|
|
1036
|
+
const firstDiscovery = discoverHeadlessInstances(jayHtmlForDiscovery);
|
|
1037
|
+
const headlessContractNameSet = new Set(
|
|
1038
|
+
jayHtml.headlessImports.map((hi) => hi.contractName)
|
|
1039
|
+
);
|
|
1040
|
+
const jayHtmlWithCoords = assignCoordinatesToJayHtml(
|
|
1041
|
+
firstDiscovery.preRenderedJayHtml,
|
|
1042
|
+
headlessContractNameSet
|
|
1043
|
+
);
|
|
1044
|
+
discoveryResult = discoverHeadlessInstances(jayHtmlWithCoords);
|
|
1045
|
+
} else {
|
|
1046
|
+
discoveryResult = {
|
|
1047
|
+
instances: [],
|
|
1048
|
+
forEachInstances: [],
|
|
1049
|
+
preRenderedJayHtml: jayHtmlSource
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
889
1052
|
return {
|
|
890
1053
|
parts,
|
|
891
1054
|
serverTrackByMap: jayHtml.serverTrackByMap,
|
|
@@ -894,7 +1057,9 @@ async function loadPageParts(vite, route, pagesBase, projectBase, jayRollupConfi
|
|
|
894
1057
|
headlessContracts,
|
|
895
1058
|
headlessInstanceComponents,
|
|
896
1059
|
discoveredInstances: discoveryResult.instances,
|
|
897
|
-
forEachInstances: discoveryResult.forEachInstances
|
|
1060
|
+
forEachInstances: discoveryResult.forEachInstances,
|
|
1061
|
+
linkedCssFiles: jayHtml.linkedCssFiles ?? [],
|
|
1062
|
+
linkedComponentFiles: jayHtml.linkedComponentFiles ?? []
|
|
898
1063
|
};
|
|
899
1064
|
});
|
|
900
1065
|
}
|
|
@@ -909,31 +1074,32 @@ async function slowRenderInstances(discovered, headlessInstanceComponents) {
|
|
|
909
1074
|
const carryForwards = {};
|
|
910
1075
|
for (const instance of discovered) {
|
|
911
1076
|
const comp = componentByContractName.get(instance.contractName);
|
|
912
|
-
if (!comp
|
|
1077
|
+
if (!comp)
|
|
913
1078
|
continue;
|
|
914
|
-
}
|
|
915
1079
|
const contractProps = comp.contract?.props ?? [];
|
|
916
1080
|
const normalizedProps = {};
|
|
917
1081
|
for (const [key, value] of Object.entries(instance.props)) {
|
|
918
1082
|
const match = contractProps.find((p) => p.name.toLowerCase() === key.toLowerCase());
|
|
919
1083
|
normalizedProps[match ? match.name : key] = value;
|
|
920
1084
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1085
|
+
discoveredForFast.push({
|
|
1086
|
+
contractName: instance.contractName,
|
|
1087
|
+
props: normalizedProps,
|
|
1088
|
+
coordinate: instance.coordinate
|
|
1089
|
+
});
|
|
1090
|
+
if (comp.compDefinition.slowlyRender) {
|
|
1091
|
+
const services = resolveServices(comp.compDefinition.services);
|
|
1092
|
+
const slowResult = await comp.compDefinition.slowlyRender(normalizedProps, ...services);
|
|
1093
|
+
if (slowResult.kind === "PhaseOutput") {
|
|
1094
|
+
const coordKey = instance.coordinate.join("/");
|
|
1095
|
+
resolvedData.push({
|
|
1096
|
+
coordinate: instance.coordinate,
|
|
1097
|
+
contract: comp.contract,
|
|
1098
|
+
slowViewState: slowResult.rendered
|
|
1099
|
+
});
|
|
1100
|
+
slowViewStates[coordKey] = slowResult.rendered;
|
|
1101
|
+
carryForwards[coordKey] = slowResult.carryForward;
|
|
1102
|
+
}
|
|
937
1103
|
}
|
|
938
1104
|
}
|
|
939
1105
|
if (discoveredForFast.length === 0) {
|
|
@@ -942,7 +1108,7 @@ async function slowRenderInstances(discovered, headlessInstanceComponents) {
|
|
|
942
1108
|
return {
|
|
943
1109
|
resolvedData,
|
|
944
1110
|
slowViewStates,
|
|
945
|
-
instancePhaseData: { discovered: discoveredForFast, carryForwards }
|
|
1111
|
+
instancePhaseData: { discovered: discoveredForFast, carryForwards, slowViewStates }
|
|
946
1112
|
};
|
|
947
1113
|
}
|
|
948
1114
|
function validateForEachInstances(forEachInstances, headlessInstanceComponents) {
|
|
@@ -1957,7 +2123,7 @@ class SlowRenderCache {
|
|
|
1957
2123
|
try {
|
|
1958
2124
|
const files = await fs$2.readdir(cacheSubDir);
|
|
1959
2125
|
for (const file of files) {
|
|
1960
|
-
if (file.startsWith(basename)
|
|
2126
|
+
if (file.startsWith(basename)) {
|
|
1961
2127
|
try {
|
|
1962
2128
|
await fs$2.unlink(path__default.join(cacheSubDir, file));
|
|
1963
2129
|
} catch {
|
|
@@ -2131,11 +2297,34 @@ async function materializeContracts(options, services = /* @__PURE__ */ new Map(
|
|
|
2131
2297
|
const { manifest } = plugin;
|
|
2132
2298
|
const pluginRelPath = path.relative(projectRoot, plugin.pluginPath);
|
|
2133
2299
|
if (!pluginsIndexMap.has(plugin.name)) {
|
|
2134
|
-
|
|
2300
|
+
const entry = {
|
|
2135
2301
|
path: "./" + pluginRelPath.replace(/\\/g, "/"),
|
|
2136
2302
|
contracts: [],
|
|
2137
2303
|
actions: []
|
|
2138
|
-
}
|
|
2304
|
+
};
|
|
2305
|
+
if (manifest.services?.length) {
|
|
2306
|
+
entry.services = manifest.services.map((s2) => {
|
|
2307
|
+
const docPath = s2.doc ? "./" + path.relative(projectRoot, path.resolve(plugin.pluginPath, s2.doc)) : void 0;
|
|
2308
|
+
return {
|
|
2309
|
+
name: s2.name,
|
|
2310
|
+
marker: s2.marker,
|
|
2311
|
+
...s2.description && { description: s2.description },
|
|
2312
|
+
...docPath && { doc: docPath }
|
|
2313
|
+
};
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
if (manifest.contexts?.length) {
|
|
2317
|
+
entry.contexts = manifest.contexts.map((c) => {
|
|
2318
|
+
const docPath = c.doc ? "./" + path.relative(projectRoot, path.resolve(plugin.pluginPath, c.doc)) : void 0;
|
|
2319
|
+
return {
|
|
2320
|
+
name: c.name,
|
|
2321
|
+
marker: c.marker,
|
|
2322
|
+
...c.description && { description: c.description },
|
|
2323
|
+
...docPath && { doc: docPath }
|
|
2324
|
+
};
|
|
2325
|
+
});
|
|
2326
|
+
}
|
|
2327
|
+
pluginsIndexMap.set(plugin.name, entry);
|
|
2139
2328
|
}
|
|
2140
2329
|
if (!dynamicOnly && manifest.contracts) {
|
|
2141
2330
|
for (const contract of manifest.contracts) {
|
|
@@ -2145,8 +2334,20 @@ async function materializeContracts(options, services = /* @__PURE__ */ new Map(
|
|
|
2145
2334
|
projectRoot
|
|
2146
2335
|
);
|
|
2147
2336
|
const relativePath = path.relative(projectRoot, contractPath);
|
|
2337
|
+
let description = contract.description;
|
|
2338
|
+
if (!description) {
|
|
2339
|
+
try {
|
|
2340
|
+
const contractContent = fs.readFileSync(contractPath, "utf-8");
|
|
2341
|
+
const parsed = YAML.parse(contractContent);
|
|
2342
|
+
if (parsed?.description && typeof parsed.description === "string") {
|
|
2343
|
+
description = parsed.description;
|
|
2344
|
+
}
|
|
2345
|
+
} catch {
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2148
2348
|
pluginsIndexMap.get(plugin.name).contracts.push({
|
|
2149
2349
|
name: contract.name,
|
|
2350
|
+
...description && { description },
|
|
2150
2351
|
type: "static",
|
|
2151
2352
|
path: "./" + relativePath
|
|
2152
2353
|
});
|
|
@@ -2180,8 +2381,17 @@ async function materializeContracts(options, services = /* @__PURE__ */ new Map(
|
|
|
2180
2381
|
const filePath = path.join(pluginOutputDir, fileName);
|
|
2181
2382
|
fs.writeFileSync(filePath, generated.yaml, "utf-8");
|
|
2182
2383
|
const relativePath = path.relative(projectRoot, filePath);
|
|
2384
|
+
let dynDescription;
|
|
2385
|
+
try {
|
|
2386
|
+
const parsedYaml = YAML.parse(generated.yaml);
|
|
2387
|
+
if (parsedYaml?.description && typeof parsedYaml.description === "string") {
|
|
2388
|
+
dynDescription = parsedYaml.description;
|
|
2389
|
+
}
|
|
2390
|
+
} catch {
|
|
2391
|
+
}
|
|
2183
2392
|
const contractEntry = {
|
|
2184
2393
|
name: fullName,
|
|
2394
|
+
...dynDescription && { description: dynDescription },
|
|
2185
2395
|
type: "dynamic",
|
|
2186
2396
|
path: "./" + relativePath,
|
|
2187
2397
|
...generated.metadata && { metadata: generated.metadata }
|
|
@@ -2217,7 +2427,10 @@ async function materializeContracts(options, services = /* @__PURE__ */ new Map(
|
|
|
2217
2427
|
if (!metadata)
|
|
2218
2428
|
continue;
|
|
2219
2429
|
const actionRelPath = path.relative(projectRoot, metadataFilePath);
|
|
2220
|
-
pluginsIndexMap.get(plugin.name)
|
|
2430
|
+
const pluginEntry = pluginsIndexMap.get(plugin.name);
|
|
2431
|
+
if (!pluginEntry.actions)
|
|
2432
|
+
pluginEntry.actions = [];
|
|
2433
|
+
pluginEntry.actions.push({
|
|
2221
2434
|
name: metadata.name,
|
|
2222
2435
|
description: metadata.description,
|
|
2223
2436
|
path: "./" + actionRelPath.replace(/\\/g, "/")
|
|
@@ -2233,7 +2446,9 @@ async function materializeContracts(options, services = /* @__PURE__ */ new Map(
|
|
|
2233
2446
|
name,
|
|
2234
2447
|
path: data.path,
|
|
2235
2448
|
contracts: data.contracts,
|
|
2236
|
-
...data.actions.length > 0 && { actions: data.actions }
|
|
2449
|
+
...data.actions && data.actions.length > 0 && { actions: data.actions },
|
|
2450
|
+
...data.services?.length && { services: data.services },
|
|
2451
|
+
...data.contexts?.length && { contexts: data.contexts }
|
|
2237
2452
|
}))
|
|
2238
2453
|
};
|
|
2239
2454
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
@@ -2264,10 +2479,33 @@ async function listContracts(options) {
|
|
|
2264
2479
|
const { manifest } = plugin;
|
|
2265
2480
|
const pluginRelPath = path.relative(projectRoot, plugin.pluginPath);
|
|
2266
2481
|
if (!pluginsMap.has(plugin.name)) {
|
|
2267
|
-
|
|
2482
|
+
const entry = {
|
|
2268
2483
|
path: "./" + pluginRelPath.replace(/\\/g, "/"),
|
|
2269
2484
|
contracts: []
|
|
2270
|
-
}
|
|
2485
|
+
};
|
|
2486
|
+
if (manifest.services?.length) {
|
|
2487
|
+
entry.services = manifest.services.map((s2) => {
|
|
2488
|
+
const docPath = s2.doc ? "./" + path.relative(projectRoot, path.resolve(plugin.pluginPath, s2.doc)) : void 0;
|
|
2489
|
+
return {
|
|
2490
|
+
name: s2.name,
|
|
2491
|
+
marker: s2.marker,
|
|
2492
|
+
...s2.description && { description: s2.description },
|
|
2493
|
+
...docPath && { doc: docPath }
|
|
2494
|
+
};
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2497
|
+
if (manifest.contexts?.length) {
|
|
2498
|
+
entry.contexts = manifest.contexts.map((c) => {
|
|
2499
|
+
const docPath = c.doc ? "./" + path.relative(projectRoot, path.resolve(plugin.pluginPath, c.doc)) : void 0;
|
|
2500
|
+
return {
|
|
2501
|
+
name: c.name,
|
|
2502
|
+
marker: c.marker,
|
|
2503
|
+
...c.description && { description: c.description },
|
|
2504
|
+
...docPath && { doc: docPath }
|
|
2505
|
+
};
|
|
2506
|
+
});
|
|
2507
|
+
}
|
|
2508
|
+
pluginsMap.set(plugin.name, entry);
|
|
2271
2509
|
}
|
|
2272
2510
|
if (!dynamicOnly && manifest.contracts) {
|
|
2273
2511
|
for (const contract of manifest.contracts) {
|
|
@@ -2277,8 +2515,20 @@ async function listContracts(options) {
|
|
|
2277
2515
|
projectRoot
|
|
2278
2516
|
);
|
|
2279
2517
|
const relativePath = path.relative(projectRoot, contractPath);
|
|
2518
|
+
let listDescription = contract.description;
|
|
2519
|
+
if (!listDescription) {
|
|
2520
|
+
try {
|
|
2521
|
+
const contractContent = fs.readFileSync(contractPath, "utf-8");
|
|
2522
|
+
const parsed = YAML.parse(contractContent);
|
|
2523
|
+
if (parsed?.description && typeof parsed.description === "string") {
|
|
2524
|
+
listDescription = parsed.description;
|
|
2525
|
+
}
|
|
2526
|
+
} catch {
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2280
2529
|
pluginsMap.get(plugin.name).contracts.push({
|
|
2281
2530
|
name: contract.name,
|
|
2531
|
+
...listDescription && { description: listDescription },
|
|
2282
2532
|
type: "static",
|
|
2283
2533
|
path: "./" + relativePath
|
|
2284
2534
|
});
|
|
@@ -2299,7 +2549,9 @@ async function listContracts(options) {
|
|
|
2299
2549
|
plugins: Array.from(pluginsMap.entries()).map(([name, data]) => ({
|
|
2300
2550
|
name,
|
|
2301
2551
|
path: data.path,
|
|
2302
|
-
contracts: data.contracts
|
|
2552
|
+
contracts: data.contracts,
|
|
2553
|
+
...data.services?.length && { services: data.services },
|
|
2554
|
+
...data.contexts?.length && { contexts: data.contexts }
|
|
2303
2555
|
}))
|
|
2304
2556
|
};
|
|
2305
2557
|
}
|
|
@@ -2469,6 +2721,7 @@ export {
|
|
|
2469
2721
|
loadActionMetadata,
|
|
2470
2722
|
loadPageParts,
|
|
2471
2723
|
materializeContracts,
|
|
2724
|
+
mergeHeadTags,
|
|
2472
2725
|
onInit,
|
|
2473
2726
|
onShutdown,
|
|
2474
2727
|
parseActionMetadata,
|
|
@@ -2484,8 +2737,10 @@ export {
|
|
|
2484
2737
|
runShutdownCallbacks,
|
|
2485
2738
|
runSlowlyChangingRender,
|
|
2486
2739
|
scanPlugins,
|
|
2740
|
+
serializeHeadTags,
|
|
2487
2741
|
setClientInitData,
|
|
2488
2742
|
slowRenderInstances,
|
|
2489
2743
|
sortPluginsByDependencies,
|
|
2744
|
+
tagIdentityKey,
|
|
2490
2745
|
validateForEachInstances
|
|
2491
2746
|
};
|
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.6",
|
|
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.6",
|
|
30
|
+
"@jay-framework/compiler-shared": "^0.15.6",
|
|
31
|
+
"@jay-framework/component": "^0.15.6",
|
|
32
|
+
"@jay-framework/fullstack-component": "^0.15.6",
|
|
33
|
+
"@jay-framework/logger": "^0.15.6",
|
|
34
|
+
"@jay-framework/runtime": "^0.15.6",
|
|
35
|
+
"@jay-framework/ssr-runtime": "^0.15.6",
|
|
36
|
+
"@jay-framework/stack-route-scanner": "^0.15.6",
|
|
37
|
+
"@jay-framework/view-state-merge": "^0.15.6",
|
|
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.6",
|
|
42
|
+
"@jay-framework/jay-cli": "^0.15.6",
|
|
43
|
+
"@jay-framework/stack-client-runtime": "^0.15.6",
|
|
44
44
|
"@types/express": "^5.0.2",
|
|
45
45
|
"@types/node": "^22.15.21",
|
|
46
46
|
"nodemon": "^3.0.3",
|