@jay-framework/dev-server 0.16.2 → 0.16.3

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.
Files changed (2) hide show
  1. package/dist/index.js +58 -25
  2. 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 fs from "node:fs";
17
- import fs__default$1 from "node:fs";
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$1 from "node:fs/promises";
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$2 from "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 (fs.existsSync(resolvedPath + ".ts")) {
1321
+ if (fsSync.existsSync(resolvedPath + ".ts")) {
1322
1322
  resolvedPath += ".ts";
1323
- } else if (fs.existsSync(resolvedPath + ".js")) {
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") && !fs.existsSync(resolvedPath)) {
1328
+ } else if (resolvedPath.endsWith(".js") && !fsSync.existsSync(resolvedPath)) {
1329
1329
  const tsPath = resolvedPath.slice(0, -3) + ".ts";
1330
- if (fs.existsSync(tsPath)) {
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 fs.promises.readFile(actualPath, "utf-8");
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 (fs.existsSync(filePath)) {
1504
+ if (fsSync.existsSync(filePath)) {
1486
1505
  return filePath;
1487
1506
  }
1488
1507
  }
@@ -1863,7 +1882,7 @@ const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
1863
1882
  const DEFAULT_MAX_FILES = 10;
1864
1883
  function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
1865
1884
  return new Promise((resolve, reject) => {
1866
- fs$2.mkdirSync(tempDir, { recursive: true });
1885
+ fs$1.mkdirSync(tempDir, { recursive: true });
1867
1886
  const files = {};
1868
1887
  let jsonData = {};
1869
1888
  let fileCount = 0;
@@ -1884,7 +1903,7 @@ function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
1884
1903
  const tempPath = path$1.join(tempDir, `${fileCount}-${filename}`);
1885
1904
  let size = 0;
1886
1905
  let truncated = false;
1887
- const writeStream = fs$2.createWriteStream(tempPath);
1906
+ const writeStream = fs$1.createWriteStream(tempPath);
1888
1907
  stream.pipe(writeStream);
1889
1908
  stream.on("data", (data) => {
1890
1909
  size += data.length;
@@ -1952,7 +1971,7 @@ function parseMultipart(req, tempDir, maxFileSize, maxFiles) {
1952
1971
  }
1953
1972
  function cleanupTempDir(dir) {
1954
1973
  try {
1955
- fs$2.rmSync(dir, { recursive: true, force: true });
1974
+ fs$1.rmSync(dir, { recursive: true, force: true });
1956
1975
  } catch {
1957
1976
  }
1958
1977
  }
@@ -2032,7 +2051,7 @@ class FreezeStore {
2032
2051
  this.dir = path.join(buildFolder, "freezes");
2033
2052
  }
2034
2053
  async save(route, viewState, routePattern) {
2035
- await fs$1.mkdir(this.dir, { recursive: true });
2054
+ await fs.mkdir(this.dir, { recursive: true });
2036
2055
  const entry = {
2037
2056
  id: randomUUID().slice(0, 8),
2038
2057
  route,
@@ -2040,7 +2059,7 @@ class FreezeStore {
2040
2059
  viewState,
2041
2060
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
2042
2061
  };
2043
- await fs$1.writeFile(
2062
+ await fs.writeFile(
2044
2063
  path.join(this.dir, `${entry.id}.json`),
2045
2064
  JSON.stringify(entry, null, 2),
2046
2065
  "utf-8"
@@ -2049,7 +2068,7 @@ class FreezeStore {
2049
2068
  }
2050
2069
  async get(id) {
2051
2070
  try {
2052
- const content = await fs$1.readFile(path.join(this.dir, `${id}.json`), "utf-8");
2071
+ const content = await fs.readFile(path.join(this.dir, `${id}.json`), "utf-8");
2053
2072
  return JSON.parse(content);
2054
2073
  } catch {
2055
2074
  return void 0;
@@ -2057,13 +2076,13 @@ class FreezeStore {
2057
2076
  }
2058
2077
  async list(route) {
2059
2078
  try {
2060
- const files = await fs$1.readdir(this.dir);
2079
+ const files = await fs.readdir(this.dir);
2061
2080
  const entries = [];
2062
2081
  for (const file of files) {
2063
2082
  if (!file.endsWith(".json"))
2064
2083
  continue;
2065
2084
  try {
2066
- const content = await fs$1.readFile(path.join(this.dir, file), "utf-8");
2085
+ const content = await fs.readFile(path.join(this.dir, file), "utf-8");
2067
2086
  const entry = JSON.parse(content);
2068
2087
  if (!route || entry.routePattern === route || entry.route === route) {
2069
2088
  entries.push(entry);
@@ -2083,7 +2102,7 @@ class FreezeStore {
2083
2102
  if (!entry)
2084
2103
  return false;
2085
2104
  entry.name = name;
2086
- await fs$1.writeFile(
2105
+ await fs.writeFile(
2087
2106
  path.join(this.dir, `${id}.json`),
2088
2107
  JSON.stringify(entry, null, 2),
2089
2108
  "utf-8"
@@ -2092,7 +2111,7 @@ class FreezeStore {
2092
2111
  }
2093
2112
  async delete(id) {
2094
2113
  try {
2095
- await fs$1.unlink(path.join(this.dir, `${id}.json`));
2114
+ await fs.unlink(path.join(this.dir, `${id}.json`));
2096
2115
  return true;
2097
2116
  } catch {
2098
2117
  return false;
@@ -2186,7 +2205,7 @@ function resolvePluginExport(pluginPath, exportSubpath) {
2186
2205
  const normalized = exportSubpath.replace(/^\.\//, "");
2187
2206
  const packageJsonPath = path__default.join(pluginPath, "package.json");
2188
2207
  try {
2189
- const packageJson = JSON.parse(fs__default$1.readFileSync(packageJsonPath, "utf-8"));
2208
+ const packageJson = JSON.parse(fsSync__default.readFileSync(packageJsonPath, "utf-8"));
2190
2209
  if (packageJson.exports) {
2191
2210
  const exportKey = "./" + normalized;
2192
2211
  const exportValue = packageJson.exports[exportKey];
@@ -2203,7 +2222,7 @@ function resolvePluginExport(pluginPath, exportSubpath) {
2203
2222
  for (const dir of ["dist", "lib", ""]) {
2204
2223
  const candidate = path__default.join(pluginPath, dir, normalized);
2205
2224
  try {
2206
- fs__default$1.accessSync(candidate);
2225
+ fsSync__default.accessSync(candidate);
2207
2226
  return candidate;
2208
2227
  } catch {
2209
2228
  }
@@ -2211,11 +2230,25 @@ function resolvePluginExport(pluginPath, exportSubpath) {
2211
2230
  return void 0;
2212
2231
  }
2213
2232
  function resolvePluginModule(plugin) {
2233
+ const pkgJsonPath = path__default.join(plugin.pluginPath, "package.json");
2234
+ if (fsSync__default.existsSync(pkgJsonPath)) {
2235
+ try {
2236
+ const pkg = JSON.parse(fsSync__default.readFileSync(pkgJsonPath, "utf-8"));
2237
+ const mainExport = pkg.exports?.["."];
2238
+ const mainPath = typeof mainExport === "string" ? mainExport : mainExport?.default || mainExport?.import || pkg.main;
2239
+ if (mainPath) {
2240
+ const resolved = path__default.join(plugin.pluginPath, mainPath);
2241
+ if (fsSync__default.existsSync(resolved))
2242
+ return resolved;
2243
+ }
2244
+ } catch {
2245
+ }
2246
+ }
2214
2247
  const modulePath = plugin.manifest.module || "index";
2215
2248
  for (const ext of [".ts", ".js", "/index.ts", "/index.js"]) {
2216
2249
  const candidate = path__default.join(plugin.pluginPath, modulePath + ext);
2217
2250
  try {
2218
- fs__default$1.accessSync(candidate);
2251
+ fsSync__default.accessSync(candidate);
2219
2252
  return candidate;
2220
2253
  } catch {
2221
2254
  }
@@ -2223,7 +2256,7 @@ function resolvePluginModule(plugin) {
2223
2256
  for (const ext of [".ts", ".js"]) {
2224
2257
  const candidate = path__default.join(plugin.pluginPath, "lib", path__default.basename(modulePath) + ext);
2225
2258
  try {
2226
- fs__default$1.accessSync(candidate);
2259
+ fsSync__default.accessSync(candidate);
2227
2260
  return candidate;
2228
2261
  } catch {
2229
2262
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/dev-server",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
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.2",
27
- "@jay-framework/compiler-shared": "^0.16.2",
28
- "@jay-framework/component": "^0.16.2",
29
- "@jay-framework/fullstack-component": "^0.16.2",
30
- "@jay-framework/logger": "^0.16.2",
31
- "@jay-framework/runtime": "^0.16.2",
32
- "@jay-framework/stack-client-runtime": "^0.16.2",
33
- "@jay-framework/stack-route-scanner": "^0.16.2",
34
- "@jay-framework/stack-server-runtime": "^0.16.2",
35
- "@jay-framework/view-state-merge": "^0.16.2",
26
+ "@jay-framework/compiler-jay-stack": "^0.16.3",
27
+ "@jay-framework/compiler-shared": "^0.16.3",
28
+ "@jay-framework/component": "^0.16.3",
29
+ "@jay-framework/fullstack-component": "^0.16.3",
30
+ "@jay-framework/logger": "^0.16.3",
31
+ "@jay-framework/runtime": "^0.16.3",
32
+ "@jay-framework/stack-client-runtime": "^0.16.3",
33
+ "@jay-framework/stack-route-scanner": "^0.16.3",
34
+ "@jay-framework/stack-server-runtime": "^0.16.3",
35
+ "@jay-framework/view-state-merge": "^0.16.3",
36
36
  "busboy": "^1.6.0",
37
37
  "vite": "^5.0.11"
38
38
  },
39
39
  "devDependencies": {
40
- "@jay-framework/dev-environment": "^0.16.2",
41
- "@jay-framework/jay-cli": "^0.16.2",
42
- "@jay-framework/stack-client-runtime": "^0.16.2",
40
+ "@jay-framework/dev-environment": "^0.16.3",
41
+ "@jay-framework/jay-cli": "^0.16.3",
42
+ "@jay-framework/stack-client-runtime": "^0.16.3",
43
43
  "@playwright/test": "^1.58.2",
44
44
  "@types/busboy": "^1.5.4",
45
45
  "@types/express": "^5.0.2",