@jay-framework/stack-server-runtime 0.16.0 → 0.16.2
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 +5 -3
- package/dist/index.js +46 -17
- package/package.json +13 -13
package/dist/index.d.ts
CHANGED
|
@@ -205,6 +205,8 @@ interface RegisteredActionBase {
|
|
|
205
205
|
/** Optional metadata from .jay-action file (description, input/output schemas).
|
|
206
206
|
* Actions with metadata are exposed to AI agents; those without are not. */
|
|
207
207
|
metadata?: ActionMetadata;
|
|
208
|
+
/** Whether this action accepts file uploads (DL#131) */
|
|
209
|
+
acceptsFiles?: boolean;
|
|
208
210
|
}
|
|
209
211
|
/**
|
|
210
212
|
* Registered request-response action entry.
|
|
@@ -895,17 +897,17 @@ declare class SlowRenderCache {
|
|
|
895
897
|
* Get a cached pre-rendered jay-html entry by reading from disk.
|
|
896
898
|
* Returns undefined if the cache file doesn't exist or has no metadata tag.
|
|
897
899
|
*/
|
|
898
|
-
get(jayHtmlPath: string, params: Record<string, string
|
|
900
|
+
get(jayHtmlPath: string, params: Record<string, string>, routeDir?: string): Promise<SlowRenderCacheEntry | undefined>;
|
|
899
901
|
/**
|
|
900
902
|
* Store a pre-rendered jay-html entry.
|
|
901
903
|
* Embeds metadata as a <script> tag and writes to disk.
|
|
902
904
|
* Returns the full cache entry with stripped content.
|
|
903
905
|
*/
|
|
904
|
-
set(jayHtmlPath: string, params: Record<string, string>, preRenderedJayHtml: string, slowViewState: object, carryForward: object): Promise<SlowRenderCacheEntry>;
|
|
906
|
+
set(jayHtmlPath: string, params: Record<string, string>, preRenderedJayHtml: string, slowViewState: object, carryForward: object, routeDir?: string): Promise<SlowRenderCacheEntry>;
|
|
905
907
|
/**
|
|
906
908
|
* Check if a pre-rendered entry exists for the given path and params
|
|
907
909
|
*/
|
|
908
|
-
has(jayHtmlPath: string, params: Record<string, string
|
|
910
|
+
has(jayHtmlPath: string, params: Record<string, string>, routeDir?: string): Promise<boolean>;
|
|
909
911
|
/**
|
|
910
912
|
* Invalidate all cached entries for a given jay-html source path.
|
|
911
913
|
* Deletes cached files from disk.
|
package/dist/index.js
CHANGED
|
@@ -204,6 +204,7 @@ new JayAtomicType("string");
|
|
|
204
204
|
new JayAtomicType("number");
|
|
205
205
|
new JayAtomicType("boolean");
|
|
206
206
|
new JayAtomicType("Date");
|
|
207
|
+
new JayAtomicType("file");
|
|
207
208
|
new JayAtomicType("Unknown");
|
|
208
209
|
class JayObjectType {
|
|
209
210
|
constructor(name, props) {
|
|
@@ -247,6 +248,9 @@ function jayTypeToJsonSchema(type) {
|
|
|
247
248
|
if (name === "string" || name === "number" || name === "boolean") {
|
|
248
249
|
return { type: name };
|
|
249
250
|
}
|
|
251
|
+
if (name === "file") {
|
|
252
|
+
return { type: "string", description: "Binary file upload (JayFile)" };
|
|
253
|
+
}
|
|
250
254
|
return { type: "string" };
|
|
251
255
|
}
|
|
252
256
|
if (isEnumType(type)) {
|
|
@@ -649,6 +653,17 @@ function buildFreezeScript(routePattern) {
|
|
|
649
653
|
__jayDoFreeze();
|
|
650
654
|
}
|
|
651
655
|
});
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Targeted page reload: only reload if this page matches the changed route prefix
|
|
659
|
+
if (import.meta.hot) {
|
|
660
|
+
import.meta.hot.on('jay:page-reload', (data) => {
|
|
661
|
+
const prefix = data.routePrefix;
|
|
662
|
+
const pathname = window.location.pathname;
|
|
663
|
+
if (pathname === prefix || pathname.startsWith(prefix + '/')) {
|
|
664
|
+
window.location.reload();
|
|
665
|
+
}
|
|
666
|
+
});
|
|
652
667
|
}`;
|
|
653
668
|
}
|
|
654
669
|
function buildAutomationWrap(options, mode) {
|
|
@@ -1114,11 +1129,12 @@ async function loadPageParts(vite, route, pagesBase, projectBase, jayRollupConfi
|
|
|
1114
1129
|
const exists = await fs$2.access(route.compPath, fs$2.constants.F_OK).then(() => true).catch(() => false);
|
|
1115
1130
|
const parts = [];
|
|
1116
1131
|
if (exists) {
|
|
1117
|
-
const
|
|
1132
|
+
const exportName = route.componentExport || "page";
|
|
1133
|
+
const pageComponent = (await vite.ssrLoadModule(route.compPath))[exportName];
|
|
1118
1134
|
parts.push({
|
|
1119
1135
|
compDefinition: pageComponent,
|
|
1120
|
-
clientImport: `import {
|
|
1121
|
-
clientPart: `{comp:
|
|
1136
|
+
clientImport: `import {${exportName}} from '${route.compPath}'`,
|
|
1137
|
+
clientPart: `{comp: ${exportName}.comp, contextMarkers: ${exportName}.contexts || []}`
|
|
1122
1138
|
});
|
|
1123
1139
|
}
|
|
1124
1140
|
const jayHtmlFilePath = options?.preRenderedPath ?? route.jayHtmlPath;
|
|
@@ -1295,7 +1311,8 @@ class ActionRegistry {
|
|
|
1295
1311
|
method: action.method,
|
|
1296
1312
|
cacheOptions: action.cacheOptions,
|
|
1297
1313
|
services: action.services,
|
|
1298
|
-
handler: action.handler
|
|
1314
|
+
handler: action.handler,
|
|
1315
|
+
...action.acceptsFiles && { acceptsFiles: true }
|
|
1299
1316
|
};
|
|
1300
1317
|
this.actions.set(action.actionName, entry);
|
|
1301
1318
|
}
|
|
@@ -1452,7 +1469,8 @@ class ActionRegistry {
|
|
|
1452
1469
|
method: "POST",
|
|
1453
1470
|
isStreaming: true,
|
|
1454
1471
|
services: action.services,
|
|
1455
|
-
handler: action.handler
|
|
1472
|
+
handler: action.handler,
|
|
1473
|
+
...action.acceptsFiles && { acceptsFiles: true }
|
|
1456
1474
|
};
|
|
1457
1475
|
this.actions.set(action.actionName, entry);
|
|
1458
1476
|
}
|
|
@@ -2192,8 +2210,8 @@ class SlowRenderCache {
|
|
|
2192
2210
|
* Get a cached pre-rendered jay-html entry by reading from disk.
|
|
2193
2211
|
* Returns undefined if the cache file doesn't exist or has no metadata tag.
|
|
2194
2212
|
*/
|
|
2195
|
-
async get(jayHtmlPath, params) {
|
|
2196
|
-
const preRenderedPath = this.computeCachePath(jayHtmlPath, params);
|
|
2213
|
+
async get(jayHtmlPath, params, routeDir) {
|
|
2214
|
+
const preRenderedPath = this.computeCachePath(jayHtmlPath, params, routeDir);
|
|
2197
2215
|
let fileContent;
|
|
2198
2216
|
try {
|
|
2199
2217
|
fileContent = await fs$2.readFile(preRenderedPath, "utf-8");
|
|
@@ -2217,8 +2235,8 @@ class SlowRenderCache {
|
|
|
2217
2235
|
* Embeds metadata as a <script> tag and writes to disk.
|
|
2218
2236
|
* Returns the full cache entry with stripped content.
|
|
2219
2237
|
*/
|
|
2220
|
-
async set(jayHtmlPath, params, preRenderedJayHtml, slowViewState, carryForward) {
|
|
2221
|
-
const preRenderedPath = this.computeCachePath(jayHtmlPath, params);
|
|
2238
|
+
async set(jayHtmlPath, params, preRenderedJayHtml, slowViewState, carryForward, routeDir) {
|
|
2239
|
+
const preRenderedPath = this.computeCachePath(jayHtmlPath, params, routeDir);
|
|
2222
2240
|
const fileContent = embedCacheMetadata(
|
|
2223
2241
|
preRenderedJayHtml,
|
|
2224
2242
|
slowViewState,
|
|
@@ -2239,8 +2257,8 @@ class SlowRenderCache {
|
|
|
2239
2257
|
/**
|
|
2240
2258
|
* Check if a pre-rendered entry exists for the given path and params
|
|
2241
2259
|
*/
|
|
2242
|
-
async has(jayHtmlPath, params) {
|
|
2243
|
-
const preRenderedPath = this.computeCachePath(jayHtmlPath, params);
|
|
2260
|
+
async has(jayHtmlPath, params, routeDir) {
|
|
2261
|
+
const preRenderedPath = this.computeCachePath(jayHtmlPath, params, routeDir);
|
|
2244
2262
|
try {
|
|
2245
2263
|
await fs$2.access(preRenderedPath);
|
|
2246
2264
|
return true;
|
|
@@ -2314,10 +2332,18 @@ class SlowRenderCache {
|
|
|
2314
2332
|
/**
|
|
2315
2333
|
* Compute the cache file path for a given jay-html path and params.
|
|
2316
2334
|
*/
|
|
2317
|
-
computeCachePath(jayHtmlPath, params) {
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2335
|
+
computeCachePath(jayHtmlPath, params, routeDir) {
|
|
2336
|
+
let dir;
|
|
2337
|
+
if (routeDir) {
|
|
2338
|
+
dir = routeDir;
|
|
2339
|
+
} else {
|
|
2340
|
+
const relativePath = path__default.relative(this.pagesRoot, jayHtmlPath);
|
|
2341
|
+
dir = relativePath.startsWith("..") ? path__default.join(
|
|
2342
|
+
"_plugins",
|
|
2343
|
+
crypto.createHash("md5").update(jayHtmlPath).digest("hex").slice(0, 12)
|
|
2344
|
+
) : path__default.dirname(relativePath);
|
|
2345
|
+
}
|
|
2346
|
+
const basename = path__default.basename(jayHtmlPath, ".jay-html");
|
|
2321
2347
|
const paramsHash = hashParams(params);
|
|
2322
2348
|
const cacheFileName = `${basename}${paramsHash}.jay-html`;
|
|
2323
2349
|
return path__default.join(this.cacheDir, dir, cacheFileName);
|
|
@@ -2337,8 +2363,11 @@ class SlowRenderCache {
|
|
|
2337
2363
|
*/
|
|
2338
2364
|
async scanAndDeleteCacheFiles(jayHtmlPath) {
|
|
2339
2365
|
const relativePath = path__default.relative(this.pagesRoot, jayHtmlPath);
|
|
2340
|
-
const dir = path__default.
|
|
2341
|
-
|
|
2366
|
+
const dir = relativePath.startsWith("..") ? path__default.join(
|
|
2367
|
+
"_plugins",
|
|
2368
|
+
crypto.createHash("md5").update(jayHtmlPath).digest("hex").slice(0, 12)
|
|
2369
|
+
) : path__default.dirname(relativePath);
|
|
2370
|
+
const basename = path__default.basename(jayHtmlPath, ".jay-html");
|
|
2342
2371
|
const cacheSubDir = path__default.join(this.cacheDir, dir);
|
|
2343
2372
|
try {
|
|
2344
2373
|
const files = await fs$2.readdir(cacheSubDir);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/stack-server-runtime",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.2",
|
|
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.16.
|
|
30
|
-
"@jay-framework/compiler-shared": "^0.16.
|
|
31
|
-
"@jay-framework/component": "^0.16.
|
|
32
|
-
"@jay-framework/fullstack-component": "^0.16.
|
|
33
|
-
"@jay-framework/logger": "^0.16.
|
|
34
|
-
"@jay-framework/runtime": "^0.16.
|
|
35
|
-
"@jay-framework/ssr-runtime": "^0.16.
|
|
36
|
-
"@jay-framework/stack-route-scanner": "^0.16.
|
|
37
|
-
"@jay-framework/view-state-merge": "^0.16.
|
|
29
|
+
"@jay-framework/compiler-jay-html": "^0.16.2",
|
|
30
|
+
"@jay-framework/compiler-shared": "^0.16.2",
|
|
31
|
+
"@jay-framework/component": "^0.16.2",
|
|
32
|
+
"@jay-framework/fullstack-component": "^0.16.2",
|
|
33
|
+
"@jay-framework/logger": "^0.16.2",
|
|
34
|
+
"@jay-framework/runtime": "^0.16.2",
|
|
35
|
+
"@jay-framework/ssr-runtime": "^0.16.2",
|
|
36
|
+
"@jay-framework/stack-route-scanner": "^0.16.2",
|
|
37
|
+
"@jay-framework/view-state-merge": "^0.16.2",
|
|
38
38
|
"yaml": "^2.3.4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@jay-framework/dev-environment": "^0.16.
|
|
42
|
-
"@jay-framework/jay-cli": "^0.16.
|
|
43
|
-
"@jay-framework/stack-client-runtime": "^0.16.
|
|
41
|
+
"@jay-framework/dev-environment": "^0.16.2",
|
|
42
|
+
"@jay-framework/jay-cli": "^0.16.2",
|
|
43
|
+
"@jay-framework/stack-client-runtime": "^0.16.2",
|
|
44
44
|
"@types/express": "^5.0.2",
|
|
45
45
|
"@types/node": "^22.15.21",
|
|
46
46
|
"nodemon": "^3.0.3",
|