@jay-framework/dev-server 0.12.0 → 0.13.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/index.js +144 -11
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import { getLogger, getDevLogger } from "@jay-framework/logger";
|
|
|
15
15
|
import { createRequire as createRequire$1 } from "node:module";
|
|
16
16
|
import * as fs from "node:fs";
|
|
17
17
|
import { scanRoutes, routeToExpressRoute } from "@jay-framework/stack-route-scanner";
|
|
18
|
-
import { discoverPluginsWithInit, sortPluginsByDependencies, executePluginServerInits, runInitCallbacks, actionRegistry, discoverAndRegisterActions, discoverAllPluginActions, runShutdownCallbacks, clearLifecycleCallbacks, clearServiceRegistry, clearClientInitData, DevSlowlyChangingPhase, SlowRenderCache, preparePluginClientInits, getServiceRegistry, materializeContracts, loadPageParts, renderFastChangingData, slowRenderInstances, generateClientScript, getClientInitData, resolveServices } from "@jay-framework/stack-server-runtime";
|
|
18
|
+
import { discoverPluginsWithInit, sortPluginsByDependencies, executePluginServerInits, runInitCallbacks, actionRegistry, discoverAndRegisterActions, discoverAllPluginActions, runShutdownCallbacks, clearLifecycleCallbacks, clearServiceRegistry, clearClientInitData, DevSlowlyChangingPhase, SlowRenderCache, preparePluginClientInits, getServiceRegistry, materializeContracts, loadPageParts, renderFastChangingData, validateForEachInstances, slowRenderInstances, generateClientScript, getClientInitData, resolveServices } from "@jay-framework/stack-server-runtime";
|
|
19
19
|
import fs$1 from "node:fs/promises";
|
|
20
20
|
import { pathToFileURL } from "node:url";
|
|
21
21
|
const s$1 = createRequire(import.meta.url), e$1 = s$1("typescript"), c$1 = new Proxy(e$1, {
|
|
@@ -1401,9 +1401,7 @@ async function createViteForCli(options) {
|
|
|
1401
1401
|
ignored: ["**/build/**"]
|
|
1402
1402
|
}
|
|
1403
1403
|
},
|
|
1404
|
-
plugins: [
|
|
1405
|
-
...jayStackCompiler({ tsConfigFilePath })
|
|
1406
|
-
],
|
|
1404
|
+
plugins: [...jayStackCompiler({ tsConfigFilePath })],
|
|
1407
1405
|
appType: "custom",
|
|
1408
1406
|
root: projectRoot,
|
|
1409
1407
|
ssr: {
|
|
@@ -1864,7 +1862,12 @@ function filterPluginsForPage(allPluginClientInits, allPluginsWithInit, usedPack
|
|
|
1864
1862
|
pluginsByPackage.set(plugin.packageName, plugin);
|
|
1865
1863
|
}
|
|
1866
1864
|
const expandedPackages = new Set(usedPackages);
|
|
1867
|
-
const
|
|
1865
|
+
for (const plugin of allPluginsWithInit) {
|
|
1866
|
+
if (plugin.global) {
|
|
1867
|
+
expandedPackages.add(plugin.packageName);
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
const toProcess = [...expandedPackages];
|
|
1868
1871
|
while (toProcess.length > 0) {
|
|
1869
1872
|
const packageName = toProcess.pop();
|
|
1870
1873
|
const plugin = pluginsByPackage.get(packageName);
|
|
@@ -2001,10 +2004,11 @@ async function handleCachedRequest(vite, route, options, cachedEntry, pageParams
|
|
|
2001
2004
|
let fastViewState = renderedFast.rendered;
|
|
2002
2005
|
let fastCarryForward = renderedFast.carryForward;
|
|
2003
2006
|
const instancePhaseData = cachedEntry.carryForward?.__instances;
|
|
2004
|
-
|
|
2007
|
+
const headlessComps = pagePartsResult.val.headlessInstanceComponents;
|
|
2008
|
+
if (instancePhaseData && headlessComps.length > 0) {
|
|
2005
2009
|
const instanceFastResult = await renderFastChangingDataForInstances(
|
|
2006
2010
|
instancePhaseData,
|
|
2007
|
-
|
|
2011
|
+
headlessComps
|
|
2008
2012
|
);
|
|
2009
2013
|
if (instanceFastResult) {
|
|
2010
2014
|
fastViewState = {
|
|
@@ -2016,6 +2020,20 @@ async function handleCachedRequest(vite, route, options, cachedEntry, pageParams
|
|
|
2016
2020
|
__headlessInstances: instanceFastResult.carryForwards
|
|
2017
2021
|
};
|
|
2018
2022
|
}
|
|
2023
|
+
if (instancePhaseData.forEachInstances && instancePhaseData.forEachInstances.length > 0) {
|
|
2024
|
+
const forEachResult = await renderFastChangingDataForForEachInstances(
|
|
2025
|
+
instancePhaseData.forEachInstances,
|
|
2026
|
+
headlessComps,
|
|
2027
|
+
fastViewState
|
|
2028
|
+
);
|
|
2029
|
+
if (forEachResult) {
|
|
2030
|
+
const existingHeadless = fastViewState.__headlessInstances || {};
|
|
2031
|
+
fastViewState = {
|
|
2032
|
+
...fastViewState,
|
|
2033
|
+
__headlessInstances: { ...existingHeadless, ...forEachResult }
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2019
2037
|
}
|
|
2020
2038
|
await sendResponse(
|
|
2021
2039
|
vite,
|
|
@@ -2075,7 +2093,20 @@ async function handlePreRenderRequest(vite, route, options, slowlyPhase, slowRen
|
|
|
2075
2093
|
timing?.end();
|
|
2076
2094
|
return;
|
|
2077
2095
|
}
|
|
2078
|
-
|
|
2096
|
+
let instancePhaseDataForCache = preRenderResult.instancePhaseData;
|
|
2097
|
+
if (instancePhaseDataForCache && preRenderResult.forEachInstances) {
|
|
2098
|
+
instancePhaseDataForCache = {
|
|
2099
|
+
...instancePhaseDataForCache,
|
|
2100
|
+
forEachInstances: preRenderResult.forEachInstances
|
|
2101
|
+
};
|
|
2102
|
+
} else if (preRenderResult.forEachInstances) {
|
|
2103
|
+
instancePhaseDataForCache = {
|
|
2104
|
+
discovered: [],
|
|
2105
|
+
carryForwards: {},
|
|
2106
|
+
forEachInstances: preRenderResult.forEachInstances
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
2109
|
+
const carryForward = instancePhaseDataForCache ? { ...renderedSlowly.carryForward, __instances: instancePhaseDataForCache } : renderedSlowly.carryForward;
|
|
2079
2110
|
const preRenderedPath = await slowRenderCache.set(
|
|
2080
2111
|
route.jayHtmlPath,
|
|
2081
2112
|
pageParams,
|
|
@@ -2120,10 +2151,11 @@ async function handlePreRenderRequest(vite, route, options, slowlyPhase, slowRen
|
|
|
2120
2151
|
let fastViewState = renderedFast.rendered;
|
|
2121
2152
|
let fastCarryForward = renderedFast.carryForward;
|
|
2122
2153
|
const instancePhaseData = carryForward?.__instances;
|
|
2123
|
-
|
|
2154
|
+
const headlessComps = pagePartsResult.val.headlessInstanceComponents;
|
|
2155
|
+
if (instancePhaseData && headlessComps.length > 0) {
|
|
2124
2156
|
const instanceFastResult = await renderFastChangingDataForInstances(
|
|
2125
2157
|
instancePhaseData,
|
|
2126
|
-
|
|
2158
|
+
headlessComps
|
|
2127
2159
|
);
|
|
2128
2160
|
if (instanceFastResult) {
|
|
2129
2161
|
fastViewState = {
|
|
@@ -2135,6 +2167,20 @@ async function handlePreRenderRequest(vite, route, options, slowlyPhase, slowRen
|
|
|
2135
2167
|
__headlessInstances: instanceFastResult.carryForwards
|
|
2136
2168
|
};
|
|
2137
2169
|
}
|
|
2170
|
+
if (instancePhaseData.forEachInstances && instancePhaseData.forEachInstances.length > 0) {
|
|
2171
|
+
const forEachResult = await renderFastChangingDataForForEachInstances(
|
|
2172
|
+
instancePhaseData.forEachInstances,
|
|
2173
|
+
headlessComps,
|
|
2174
|
+
fastViewState
|
|
2175
|
+
);
|
|
2176
|
+
if (forEachResult) {
|
|
2177
|
+
const existingHeadless = fastViewState.__headlessInstances || {};
|
|
2178
|
+
fastViewState = {
|
|
2179
|
+
...fastViewState,
|
|
2180
|
+
__headlessInstances: { ...existingHeadless, ...forEachResult }
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2138
2184
|
}
|
|
2139
2185
|
await sendResponse(
|
|
2140
2186
|
vite,
|
|
@@ -2191,10 +2237,26 @@ async function handleDirectRequest(vite, route, options, slowlyPhase, pageParams
|
|
|
2191
2237
|
}
|
|
2192
2238
|
let instanceViewStates;
|
|
2193
2239
|
let instancePhaseDataForFast;
|
|
2240
|
+
let forEachInstancesForFast;
|
|
2194
2241
|
const headlessInstanceComponents = pagePartsResult.val.headlessInstanceComponents ?? [];
|
|
2195
2242
|
if (headlessInstanceComponents.length > 0) {
|
|
2196
2243
|
const jayHtmlContent = await fs$1.readFile(route.jayHtmlPath, "utf-8");
|
|
2197
2244
|
const discoveryResult = discoverHeadlessInstances(jayHtmlContent);
|
|
2245
|
+
if (discoveryResult.forEachInstances.length > 0) {
|
|
2246
|
+
const validationErrors = validateForEachInstances(
|
|
2247
|
+
discoveryResult.forEachInstances,
|
|
2248
|
+
headlessInstanceComponents
|
|
2249
|
+
);
|
|
2250
|
+
if (validationErrors.length > 0) {
|
|
2251
|
+
getLogger().error(
|
|
2252
|
+
`[SlowRender] ForEach instance validation failed: ${validationErrors.join(", ")}`
|
|
2253
|
+
);
|
|
2254
|
+
res.status(500).end(validationErrors.join("\n"));
|
|
2255
|
+
timing?.end();
|
|
2256
|
+
return;
|
|
2257
|
+
}
|
|
2258
|
+
forEachInstancesForFast = discoveryResult.forEachInstances;
|
|
2259
|
+
}
|
|
2198
2260
|
if (discoveryResult.instances.length > 0) {
|
|
2199
2261
|
const slowResult = await slowRenderInstances(
|
|
2200
2262
|
discoveryResult.instances,
|
|
@@ -2228,6 +2290,20 @@ async function handleDirectRequest(vite, route, options, slowlyPhase, pageParams
|
|
|
2228
2290
|
}
|
|
2229
2291
|
}
|
|
2230
2292
|
}
|
|
2293
|
+
if (forEachInstancesForFast && renderedFast.kind === "PhaseOutput") {
|
|
2294
|
+
const forEachResult = await renderFastChangingDataForForEachInstances(
|
|
2295
|
+
forEachInstancesForFast,
|
|
2296
|
+
headlessInstanceComponents,
|
|
2297
|
+
{ ...renderedSlowly.rendered, ...renderedFast.rendered }
|
|
2298
|
+
);
|
|
2299
|
+
if (forEachResult) {
|
|
2300
|
+
if (!instanceViewStates)
|
|
2301
|
+
instanceViewStates = {};
|
|
2302
|
+
for (const [coordKey, fastVS] of Object.entries(forEachResult)) {
|
|
2303
|
+
instanceViewStates[coordKey] = fastVS;
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2231
2307
|
timing?.recordFastRender(Date.now() - fastStart);
|
|
2232
2308
|
if (renderedFast.kind !== "PhaseOutput") {
|
|
2233
2309
|
handleOtherResponseCodes(res, renderedFast);
|
|
@@ -2332,9 +2408,23 @@ async function preRenderJayHtml(route, slowViewState, headlessContracts, headles
|
|
|
2332
2408
|
}
|
|
2333
2409
|
let preRenderedJayHtml = result.val.preRenderedJayHtml;
|
|
2334
2410
|
let instancePhaseData;
|
|
2411
|
+
let forEachInstances;
|
|
2335
2412
|
if (headlessInstanceComponents.length > 0) {
|
|
2336
2413
|
const discoveryResult = discoverHeadlessInstances(preRenderedJayHtml);
|
|
2337
2414
|
preRenderedJayHtml = discoveryResult.preRenderedJayHtml;
|
|
2415
|
+
if (discoveryResult.forEachInstances.length > 0) {
|
|
2416
|
+
const validationErrors = validateForEachInstances(
|
|
2417
|
+
discoveryResult.forEachInstances,
|
|
2418
|
+
headlessInstanceComponents
|
|
2419
|
+
);
|
|
2420
|
+
if (validationErrors.length > 0) {
|
|
2421
|
+
getLogger().error(
|
|
2422
|
+
`[SlowRender] ForEach instance validation failed: ${validationErrors.join(", ")}`
|
|
2423
|
+
);
|
|
2424
|
+
return void 0;
|
|
2425
|
+
}
|
|
2426
|
+
forEachInstances = discoveryResult.forEachInstances;
|
|
2427
|
+
}
|
|
2338
2428
|
if (discoveryResult.instances.length > 0) {
|
|
2339
2429
|
const slowResult = await slowRenderInstances(
|
|
2340
2430
|
discoveryResult.instances,
|
|
@@ -2358,7 +2448,7 @@ async function preRenderJayHtml(route, slowViewState, headlessContracts, headles
|
|
|
2358
2448
|
}
|
|
2359
2449
|
}
|
|
2360
2450
|
}
|
|
2361
|
-
return { preRenderedJayHtml, instancePhaseData };
|
|
2451
|
+
return { preRenderedJayHtml, instancePhaseData, forEachInstances };
|
|
2362
2452
|
}
|
|
2363
2453
|
async function renderFastChangingDataForInstances(instancePhaseData, headlessInstanceComponents) {
|
|
2364
2454
|
const componentByContractName = /* @__PURE__ */ new Map();
|
|
@@ -2389,6 +2479,49 @@ async function renderFastChangingDataForInstances(instancePhaseData, headlessIns
|
|
|
2389
2479
|
}
|
|
2390
2480
|
return hasResults ? { viewStates, carryForwards } : void 0;
|
|
2391
2481
|
}
|
|
2482
|
+
async function renderFastChangingDataForForEachInstances(forEachInstances, headlessInstanceComponents, mergedViewState) {
|
|
2483
|
+
const componentByContractName = /* @__PURE__ */ new Map();
|
|
2484
|
+
for (const comp of headlessInstanceComponents) {
|
|
2485
|
+
componentByContractName.set(comp.contractName, comp);
|
|
2486
|
+
}
|
|
2487
|
+
const viewStates = {};
|
|
2488
|
+
let hasResults = false;
|
|
2489
|
+
for (const instance of forEachInstances) {
|
|
2490
|
+
const comp = componentByContractName.get(instance.contractName);
|
|
2491
|
+
if (!comp)
|
|
2492
|
+
continue;
|
|
2493
|
+
const items = resolvePathValue(mergedViewState, instance.forEachPath);
|
|
2494
|
+
if (!Array.isArray(items))
|
|
2495
|
+
continue;
|
|
2496
|
+
for (const item of items) {
|
|
2497
|
+
const trackByValue = String(item[instance.trackBy]);
|
|
2498
|
+
const props = {};
|
|
2499
|
+
for (const [propName, binding] of Object.entries(instance.propBindings)) {
|
|
2500
|
+
props[propName] = resolveBinding(String(binding), item);
|
|
2501
|
+
}
|
|
2502
|
+
if (comp.compDefinition.fastRender) {
|
|
2503
|
+
const services = resolveServices(comp.compDefinition.services);
|
|
2504
|
+
const fastResult = await comp.compDefinition.fastRender(props, ...services);
|
|
2505
|
+
if (fastResult.kind === "PhaseOutput") {
|
|
2506
|
+
const coord = [trackByValue, instance.coordinateSuffix].toString();
|
|
2507
|
+
viewStates[coord] = fastResult.rendered;
|
|
2508
|
+
hasResults = true;
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
return hasResults ? viewStates : void 0;
|
|
2514
|
+
}
|
|
2515
|
+
function resolvePathValue(obj, path2) {
|
|
2516
|
+
return path2.split(".").reduce((current, segment) => current?.[segment], obj);
|
|
2517
|
+
}
|
|
2518
|
+
function resolveBinding(binding, item) {
|
|
2519
|
+
const match = binding.match(/^\{(.+)\}$/);
|
|
2520
|
+
if (match) {
|
|
2521
|
+
return String(item[match[1]] ?? "");
|
|
2522
|
+
}
|
|
2523
|
+
return binding;
|
|
2524
|
+
}
|
|
2392
2525
|
async function materializeDynamicContracts(projectRootFolder, buildFolder, viteServer) {
|
|
2393
2526
|
try {
|
|
2394
2527
|
const services = getServiceRegistry();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/dev-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,22 +22,22 @@
|
|
|
22
22
|
"test:watch": "vitest"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@jay-framework/compiler-jay-stack": "^0.
|
|
26
|
-
"@jay-framework/compiler-shared": "^0.
|
|
27
|
-
"@jay-framework/component": "^0.
|
|
28
|
-
"@jay-framework/fullstack-component": "^0.
|
|
29
|
-
"@jay-framework/logger": "^0.
|
|
30
|
-
"@jay-framework/runtime": "^0.
|
|
31
|
-
"@jay-framework/stack-client-runtime": "^0.
|
|
32
|
-
"@jay-framework/stack-route-scanner": "^0.
|
|
33
|
-
"@jay-framework/stack-server-runtime": "^0.
|
|
34
|
-
"@jay-framework/view-state-merge": "^0.
|
|
25
|
+
"@jay-framework/compiler-jay-stack": "^0.13.0",
|
|
26
|
+
"@jay-framework/compiler-shared": "^0.13.0",
|
|
27
|
+
"@jay-framework/component": "^0.13.0",
|
|
28
|
+
"@jay-framework/fullstack-component": "^0.13.0",
|
|
29
|
+
"@jay-framework/logger": "^0.13.0",
|
|
30
|
+
"@jay-framework/runtime": "^0.13.0",
|
|
31
|
+
"@jay-framework/stack-client-runtime": "^0.13.0",
|
|
32
|
+
"@jay-framework/stack-route-scanner": "^0.13.0",
|
|
33
|
+
"@jay-framework/stack-server-runtime": "^0.13.0",
|
|
34
|
+
"@jay-framework/view-state-merge": "^0.13.0",
|
|
35
35
|
"vite": "^5.0.11"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@jay-framework/dev-environment": "^0.
|
|
39
|
-
"@jay-framework/jay-cli": "^0.
|
|
40
|
-
"@jay-framework/stack-client-runtime": "^0.
|
|
38
|
+
"@jay-framework/dev-environment": "^0.13.0",
|
|
39
|
+
"@jay-framework/jay-cli": "^0.13.0",
|
|
40
|
+
"@jay-framework/stack-client-runtime": "^0.13.0",
|
|
41
41
|
"@types/express": "^5.0.2",
|
|
42
42
|
"@types/node": "^22.15.21",
|
|
43
43
|
"nodemon": "^3.0.3",
|