@jay-framework/dev-server 0.16.2 → 0.16.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.js +83 -26
- package/package.json +14 -14
package/dist/index.js
CHANGED
|
@@ -13,15 +13,15 @@ import path__default from "node:path";
|
|
|
13
13
|
import { JAY_IMPORT_RESOLVER, injectHeadfullFSTemplates, parseContract, slowRenderTransform, discoverHeadlessInstances, assignCoordinatesToJayHtml, resolveHeadlessInstances } from "@jay-framework/compiler-jay-html";
|
|
14
14
|
import { getLogger, getDevLogger } from "@jay-framework/logger";
|
|
15
15
|
import { createRequire as createRequire$1 } from "node:module";
|
|
16
|
-
import * as
|
|
17
|
-
import
|
|
16
|
+
import * as fsSync from "node:fs";
|
|
17
|
+
import fsSync__default from "node:fs";
|
|
18
18
|
import { scanRoutes, createRoute, routeToExpressRoute } from "@jay-framework/stack-route-scanner";
|
|
19
19
|
import { discoverPluginsWithInit, sortPluginsByDependencies, executePluginServerInits, runInitCallbacks, actionRegistry, discoverAndRegisterActions, discoverAllPluginActions, runShutdownCallbacks, clearLifecycleCallbacks, clearServiceRegistry, clearClientInitData, loadPageParts, runLoadParams, DevSlowlyChangingPhase, SlowRenderCache, preparePluginClientInits, registerService, clearServerElementCache, scanPlugins, getServiceRegistry, materializeContracts, renderFastChangingData, mergeHeadTags, generateClientScript, getClientInitData, generateSSRPageHtml, generateFrozenPageHtml, validateForEachInstances, slowRenderInstances } from "@jay-framework/stack-server-runtime";
|
|
20
|
-
import * as fs
|
|
20
|
+
import * as fs from "node:fs/promises";
|
|
21
21
|
import fs__default from "node:fs/promises";
|
|
22
22
|
import { pathToFileURL } from "node:url";
|
|
23
23
|
import Busboy from "busboy";
|
|
24
|
-
import fs$
|
|
24
|
+
import fs$1 from "fs";
|
|
25
25
|
import path$1 from "path";
|
|
26
26
|
import crypto from "crypto";
|
|
27
27
|
import { randomUUID } from "node:crypto";
|
|
@@ -1318,16 +1318,16 @@ function jayStackCompiler(options = {}) {
|
|
|
1318
1318
|
const importerDir = path.dirname(importer);
|
|
1319
1319
|
let resolvedPath = path.resolve(importerDir, source);
|
|
1320
1320
|
if (!resolvedPath.endsWith(".ts") && !resolvedPath.endsWith(".js")) {
|
|
1321
|
-
if (
|
|
1321
|
+
if (fsSync.existsSync(resolvedPath + ".ts")) {
|
|
1322
1322
|
resolvedPath += ".ts";
|
|
1323
|
-
} else if (
|
|
1323
|
+
} else if (fsSync.existsSync(resolvedPath + ".js")) {
|
|
1324
1324
|
resolvedPath += ".js";
|
|
1325
1325
|
} else {
|
|
1326
1326
|
return null;
|
|
1327
1327
|
}
|
|
1328
|
-
} else if (resolvedPath.endsWith(".js") && !
|
|
1328
|
+
} else if (resolvedPath.endsWith(".js") && !fsSync.existsSync(resolvedPath)) {
|
|
1329
1329
|
const tsPath = resolvedPath.slice(0, -3) + ".ts";
|
|
1330
|
-
if (
|
|
1330
|
+
if (fsSync.existsSync(tsPath)) {
|
|
1331
1331
|
resolvedPath = tsPath;
|
|
1332
1332
|
} else {
|
|
1333
1333
|
return null;
|
|
@@ -1342,7 +1342,7 @@ function jayStackCompiler(options = {}) {
|
|
|
1342
1342
|
const actualPath = id.slice("\0jay-action:".length);
|
|
1343
1343
|
let code;
|
|
1344
1344
|
try {
|
|
1345
|
-
code = await
|
|
1345
|
+
code = await fsSync.promises.readFile(actualPath, "utf-8");
|
|
1346
1346
|
} catch (err) {
|
|
1347
1347
|
getLogger().error(
|
|
1348
1348
|
`[action-transform] Could not read ${actualPath}: ${err}`
|
|
@@ -1417,6 +1417,22 @@ async function createViteServer(options) {
|
|
|
1417
1417
|
base,
|
|
1418
1418
|
// Root directory for module resolution
|
|
1419
1419
|
root: pagesRoot,
|
|
1420
|
+
// Force singleton resolution for all runtime packages.
|
|
1421
|
+
// Without this, pre-bundled deps (in .vite/deps/) inline their own copy
|
|
1422
|
+
// of these packages, while plugin client bundles (served as raw ESM via /@fs/)
|
|
1423
|
+
// resolve to a separate instance → duplicate createJayContext() → runtime crash.
|
|
1424
|
+
resolve: {
|
|
1425
|
+
dedupe: [
|
|
1426
|
+
"@jay-framework/runtime",
|
|
1427
|
+
"@jay-framework/reactive",
|
|
1428
|
+
"@jay-framework/component",
|
|
1429
|
+
"@jay-framework/fullstack-component",
|
|
1430
|
+
"@jay-framework/stack-client-runtime",
|
|
1431
|
+
"@jay-framework/runtime-automation",
|
|
1432
|
+
"@jay-framework/view-state-merge",
|
|
1433
|
+
"@jay-framework/json-patch"
|
|
1434
|
+
]
|
|
1435
|
+
},
|
|
1420
1436
|
// SSR configuration
|
|
1421
1437
|
ssr: {
|
|
1422
1438
|
// Mark jay-framework packages as external so Vite uses Node's require
|
|
@@ -1424,7 +1440,10 @@ async function createViteServer(options) {
|
|
|
1424
1440
|
external: ["@jay-framework/stack-server-runtime", "@jay-framework/fullstack-component"]
|
|
1425
1441
|
},
|
|
1426
1442
|
// Disable automatic entry point discovery for pre-bundling —
|
|
1427
|
-
// we run in middleware mode with no HTML files, so Vite can't auto-detect entries
|
|
1443
|
+
// we run in middleware mode with no HTML files, so Vite can't auto-detect entries.
|
|
1444
|
+
// Explicitly include singleton packages so Vite pre-bundles them as separate entries.
|
|
1445
|
+
// Without this, stack-client-runtime inlines its own copy of component/reactive/runtime
|
|
1446
|
+
// into the .vite/deps/ chunk, while plugin client bundles import the raw ESM copy → duplicates.
|
|
1428
1447
|
optimizeDeps: {
|
|
1429
1448
|
entries: []
|
|
1430
1449
|
},
|
|
@@ -1482,7 +1501,7 @@ class ServiceLifecycleManager {
|
|
|
1482
1501
|
const extensions = [".ts", ".js"];
|
|
1483
1502
|
for (const ext of extensions) {
|
|
1484
1503
|
const filePath = path.join(this.projectRoot, this.sourceBase, "init" + ext);
|
|
1485
|
-
if (
|
|
1504
|
+
if (fsSync.existsSync(filePath)) {
|
|
1486
1505
|
return filePath;
|
|
1487
1506
|
}
|
|
1488
1507
|
}
|
|
@@ -1861,9 +1880,29 @@ function getStatusCodeForError(code, isActionError) {
|
|
|
1861
1880
|
}
|
|
1862
1881
|
const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
1863
1882
|
const DEFAULT_MAX_FILES = 10;
|
|
1883
|
+
function mergeDottedMultipartKeys(body) {
|
|
1884
|
+
const keys = Object.keys(body);
|
|
1885
|
+
for (const key of keys) {
|
|
1886
|
+
if (!key.includes("."))
|
|
1887
|
+
continue;
|
|
1888
|
+
const val = body[key];
|
|
1889
|
+
delete body[key];
|
|
1890
|
+
const parts = key.split(".");
|
|
1891
|
+
let cur = body;
|
|
1892
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
1893
|
+
const p = parts[i];
|
|
1894
|
+
const next = cur[p];
|
|
1895
|
+
if (typeof next !== "object" || next === null || Array.isArray(next)) {
|
|
1896
|
+
cur[p] = {};
|
|
1897
|
+
}
|
|
1898
|
+
cur = cur[p];
|
|
1899
|
+
}
|
|
1900
|
+
cur[parts[parts.length - 1]] = val;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1864
1903
|
function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
|
|
1865
1904
|
return new Promise((resolve, reject) => {
|
|
1866
|
-
fs$
|
|
1905
|
+
fs$1.mkdirSync(tempDir, { recursive: true });
|
|
1867
1906
|
const files = {};
|
|
1868
1907
|
let jsonData = {};
|
|
1869
1908
|
let fileCount = 0;
|
|
@@ -1884,7 +1923,7 @@ function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
|
|
|
1884
1923
|
const tempPath = path$1.join(tempDir, `${fileCount}-${filename}`);
|
|
1885
1924
|
let size = 0;
|
|
1886
1925
|
let truncated = false;
|
|
1887
|
-
const writeStream = fs$
|
|
1926
|
+
const writeStream = fs$1.createWriteStream(tempPath);
|
|
1888
1927
|
stream.pipe(writeStream);
|
|
1889
1928
|
stream.on("data", (data) => {
|
|
1890
1929
|
size += data.length;
|
|
@@ -1939,7 +1978,11 @@ function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
|
|
|
1939
1978
|
bb.on("close", () => {
|
|
1940
1979
|
if (errored)
|
|
1941
1980
|
return;
|
|
1942
|
-
Promise.all(pendingWrites).then(() =>
|
|
1981
|
+
Promise.all(pendingWrites).then(() => {
|
|
1982
|
+
const body = { ...jsonData, ...files };
|
|
1983
|
+
mergeDottedMultipartKeys(body);
|
|
1984
|
+
resolve({ body, tempDir });
|
|
1985
|
+
}).catch((err) => reject(err));
|
|
1943
1986
|
});
|
|
1944
1987
|
bb.on("error", (err) => {
|
|
1945
1988
|
if (!errored) {
|
|
@@ -1952,7 +1995,7 @@ function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
|
|
|
1952
1995
|
}
|
|
1953
1996
|
function cleanupTempDir(dir) {
|
|
1954
1997
|
try {
|
|
1955
|
-
fs$
|
|
1998
|
+
fs$1.rmSync(dir, { recursive: true, force: true });
|
|
1956
1999
|
} catch {
|
|
1957
2000
|
}
|
|
1958
2001
|
}
|
|
@@ -2032,7 +2075,7 @@ class FreezeStore {
|
|
|
2032
2075
|
this.dir = path.join(buildFolder, "freezes");
|
|
2033
2076
|
}
|
|
2034
2077
|
async save(route, viewState, routePattern) {
|
|
2035
|
-
await fs
|
|
2078
|
+
await fs.mkdir(this.dir, { recursive: true });
|
|
2036
2079
|
const entry = {
|
|
2037
2080
|
id: randomUUID().slice(0, 8),
|
|
2038
2081
|
route,
|
|
@@ -2040,7 +2083,7 @@ class FreezeStore {
|
|
|
2040
2083
|
viewState,
|
|
2041
2084
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2042
2085
|
};
|
|
2043
|
-
await fs
|
|
2086
|
+
await fs.writeFile(
|
|
2044
2087
|
path.join(this.dir, `${entry.id}.json`),
|
|
2045
2088
|
JSON.stringify(entry, null, 2),
|
|
2046
2089
|
"utf-8"
|
|
@@ -2049,7 +2092,7 @@ class FreezeStore {
|
|
|
2049
2092
|
}
|
|
2050
2093
|
async get(id) {
|
|
2051
2094
|
try {
|
|
2052
|
-
const content = await fs
|
|
2095
|
+
const content = await fs.readFile(path.join(this.dir, `${id}.json`), "utf-8");
|
|
2053
2096
|
return JSON.parse(content);
|
|
2054
2097
|
} catch {
|
|
2055
2098
|
return void 0;
|
|
@@ -2057,13 +2100,13 @@ class FreezeStore {
|
|
|
2057
2100
|
}
|
|
2058
2101
|
async list(route) {
|
|
2059
2102
|
try {
|
|
2060
|
-
const files = await fs
|
|
2103
|
+
const files = await fs.readdir(this.dir);
|
|
2061
2104
|
const entries = [];
|
|
2062
2105
|
for (const file of files) {
|
|
2063
2106
|
if (!file.endsWith(".json"))
|
|
2064
2107
|
continue;
|
|
2065
2108
|
try {
|
|
2066
|
-
const content = await fs
|
|
2109
|
+
const content = await fs.readFile(path.join(this.dir, file), "utf-8");
|
|
2067
2110
|
const entry = JSON.parse(content);
|
|
2068
2111
|
if (!route || entry.routePattern === route || entry.route === route) {
|
|
2069
2112
|
entries.push(entry);
|
|
@@ -2083,7 +2126,7 @@ class FreezeStore {
|
|
|
2083
2126
|
if (!entry)
|
|
2084
2127
|
return false;
|
|
2085
2128
|
entry.name = name;
|
|
2086
|
-
await fs
|
|
2129
|
+
await fs.writeFile(
|
|
2087
2130
|
path.join(this.dir, `${id}.json`),
|
|
2088
2131
|
JSON.stringify(entry, null, 2),
|
|
2089
2132
|
"utf-8"
|
|
@@ -2092,7 +2135,7 @@ class FreezeStore {
|
|
|
2092
2135
|
}
|
|
2093
2136
|
async delete(id) {
|
|
2094
2137
|
try {
|
|
2095
|
-
await fs
|
|
2138
|
+
await fs.unlink(path.join(this.dir, `${id}.json`));
|
|
2096
2139
|
return true;
|
|
2097
2140
|
} catch {
|
|
2098
2141
|
return false;
|
|
@@ -2186,7 +2229,7 @@ function resolvePluginExport(pluginPath, exportSubpath) {
|
|
|
2186
2229
|
const normalized = exportSubpath.replace(/^\.\//, "");
|
|
2187
2230
|
const packageJsonPath = path__default.join(pluginPath, "package.json");
|
|
2188
2231
|
try {
|
|
2189
|
-
const packageJson = JSON.parse(
|
|
2232
|
+
const packageJson = JSON.parse(fsSync__default.readFileSync(packageJsonPath, "utf-8"));
|
|
2190
2233
|
if (packageJson.exports) {
|
|
2191
2234
|
const exportKey = "./" + normalized;
|
|
2192
2235
|
const exportValue = packageJson.exports[exportKey];
|
|
@@ -2203,7 +2246,7 @@ function resolvePluginExport(pluginPath, exportSubpath) {
|
|
|
2203
2246
|
for (const dir of ["dist", "lib", ""]) {
|
|
2204
2247
|
const candidate = path__default.join(pluginPath, dir, normalized);
|
|
2205
2248
|
try {
|
|
2206
|
-
|
|
2249
|
+
fsSync__default.accessSync(candidate);
|
|
2207
2250
|
return candidate;
|
|
2208
2251
|
} catch {
|
|
2209
2252
|
}
|
|
@@ -2211,11 +2254,25 @@ function resolvePluginExport(pluginPath, exportSubpath) {
|
|
|
2211
2254
|
return void 0;
|
|
2212
2255
|
}
|
|
2213
2256
|
function resolvePluginModule(plugin) {
|
|
2257
|
+
const pkgJsonPath = path__default.join(plugin.pluginPath, "package.json");
|
|
2258
|
+
if (fsSync__default.existsSync(pkgJsonPath)) {
|
|
2259
|
+
try {
|
|
2260
|
+
const pkg = JSON.parse(fsSync__default.readFileSync(pkgJsonPath, "utf-8"));
|
|
2261
|
+
const mainExport = pkg.exports?.["."];
|
|
2262
|
+
const mainPath = typeof mainExport === "string" ? mainExport : mainExport?.default || mainExport?.import || pkg.main;
|
|
2263
|
+
if (mainPath) {
|
|
2264
|
+
const resolved = path__default.join(plugin.pluginPath, mainPath);
|
|
2265
|
+
if (fsSync__default.existsSync(resolved))
|
|
2266
|
+
return resolved;
|
|
2267
|
+
}
|
|
2268
|
+
} catch {
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2214
2271
|
const modulePath = plugin.manifest.module || "index";
|
|
2215
2272
|
for (const ext of [".ts", ".js", "/index.ts", "/index.js"]) {
|
|
2216
2273
|
const candidate = path__default.join(plugin.pluginPath, modulePath + ext);
|
|
2217
2274
|
try {
|
|
2218
|
-
|
|
2275
|
+
fsSync__default.accessSync(candidate);
|
|
2219
2276
|
return candidate;
|
|
2220
2277
|
} catch {
|
|
2221
2278
|
}
|
|
@@ -2223,7 +2280,7 @@ function resolvePluginModule(plugin) {
|
|
|
2223
2280
|
for (const ext of [".ts", ".js"]) {
|
|
2224
2281
|
const candidate = path__default.join(plugin.pluginPath, "lib", path__default.basename(modulePath) + ext);
|
|
2225
2282
|
try {
|
|
2226
|
-
|
|
2283
|
+
fsSync__default.accessSync(candidate);
|
|
2227
2284
|
return candidate;
|
|
2228
2285
|
} catch {
|
|
2229
2286
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/dev-server",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -23,23 +23,23 @@
|
|
|
23
23
|
"test:watch": "vitest"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@jay-framework/compiler-jay-stack": "^0.16.
|
|
27
|
-
"@jay-framework/compiler-shared": "^0.16.
|
|
28
|
-
"@jay-framework/component": "^0.16.
|
|
29
|
-
"@jay-framework/fullstack-component": "^0.16.
|
|
30
|
-
"@jay-framework/logger": "^0.16.
|
|
31
|
-
"@jay-framework/runtime": "^0.16.
|
|
32
|
-
"@jay-framework/stack-client-runtime": "^0.16.
|
|
33
|
-
"@jay-framework/stack-route-scanner": "^0.16.
|
|
34
|
-
"@jay-framework/stack-server-runtime": "^0.16.
|
|
35
|
-
"@jay-framework/view-state-merge": "^0.16.
|
|
26
|
+
"@jay-framework/compiler-jay-stack": "^0.16.4",
|
|
27
|
+
"@jay-framework/compiler-shared": "^0.16.4",
|
|
28
|
+
"@jay-framework/component": "^0.16.4",
|
|
29
|
+
"@jay-framework/fullstack-component": "^0.16.4",
|
|
30
|
+
"@jay-framework/logger": "^0.16.4",
|
|
31
|
+
"@jay-framework/runtime": "^0.16.4",
|
|
32
|
+
"@jay-framework/stack-client-runtime": "^0.16.4",
|
|
33
|
+
"@jay-framework/stack-route-scanner": "^0.16.4",
|
|
34
|
+
"@jay-framework/stack-server-runtime": "^0.16.4",
|
|
35
|
+
"@jay-framework/view-state-merge": "^0.16.4",
|
|
36
36
|
"busboy": "^1.6.0",
|
|
37
37
|
"vite": "^5.0.11"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@jay-framework/dev-environment": "^0.16.
|
|
41
|
-
"@jay-framework/jay-cli": "^0.16.
|
|
42
|
-
"@jay-framework/stack-client-runtime": "^0.16.
|
|
40
|
+
"@jay-framework/dev-environment": "^0.16.4",
|
|
41
|
+
"@jay-framework/jay-cli": "^0.16.4",
|
|
42
|
+
"@jay-framework/stack-client-runtime": "^0.16.4",
|
|
43
43
|
"@playwright/test": "^1.58.2",
|
|
44
44
|
"@types/busboy": "^1.5.4",
|
|
45
45
|
"@types/express": "^5.0.2",
|