@plitzi/sdk-server 0.32.1 → 0.32.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +13 -11
  3. package/dist/core/mimeTypes.js +2 -2
  4. package/dist/core/requestHandler.js +22 -4
  5. package/dist/core/requestParser.js +16 -1
  6. package/dist/core/transports.js +1 -1
  7. package/dist/helpers/readCookie.js +11 -0
  8. package/dist/index.d.ts +1 -1
  9. package/dist/modules/mcp/handler.js +1 -1
  10. package/dist/modules/mcp/helpers.js +1 -1
  11. package/dist/modules/mcp/resources/index.js +1 -1
  12. package/dist/modules/mcp/tools/index.js +1 -1
  13. package/dist/modules/mcp/tools/space/schema/schemas.js +1 -1
  14. package/dist/modules/ssr/Component.js +4 -1
  15. package/dist/modules/ssr/applySSRResult.js +14 -0
  16. package/dist/modules/ssr/buildBody.js +10 -2
  17. package/dist/modules/ssr/handler.js +5 -3
  18. package/dist/modules/ssr/prepareRender.js +12 -4
  19. package/dist/modules/ssr/registerExternalPlugins.js +53 -3
  20. package/dist/modules/ssr/streamBody.js +11 -1
  21. package/dist/modules/ssr/views/template.ejs +1 -0
  22. package/dist/package.js +73 -58
  23. package/dist/package.json.d.ts +12 -12
  24. package/dist/src/core/requestParser.d.ts +1 -0
  25. package/dist/src/helpers/readCookie.d.ts +1 -0
  26. package/dist/src/modules/mcp/handler.d.ts +1 -1
  27. package/dist/src/modules/ssr/Component.d.ts +5 -2
  28. package/dist/src/modules/ssr/applySSRResult.d.ts +2 -0
  29. package/dist/src/modules/ssr/buildBody.d.ts +6 -2
  30. package/dist/src/standalone/alias-loader.d.mts +1 -0
  31. package/dist/src/standalone/plugins/ClientInfo.d.ts +1 -1
  32. package/dist/src/standalone/plugins/ServerInfo.d.ts +1 -1
  33. package/dist/src/standalone/plugins/SharedInfo.d.ts +1 -1
  34. package/dist/src/standalone/stubs/react-syntax-highlighter.d.mts +31 -0
  35. package/package.json +14 -14
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @plitzi/sdk-server
2
2
 
3
+ ## 0.32.2
4
+
5
+ ### Patch Changes
6
+
7
+ - v0.32.2
8
+ - Updated dependencies
9
+ - @plitzi/plitzi-sdk@0.32.2
10
+ - @plitzi/sdk-shared@0.32.2
11
+
3
12
  ## 0.32.1
4
13
 
5
14
  ### Patch Changes
package/README.md CHANGED
@@ -72,8 +72,8 @@ type SSRAdapters = {
72
72
  getOfflineData: (spaceId: number, environment: string, revision?: number) => Promise<OfflineDataRaw | undefined>;
73
73
  getSpaceDeployment: (req: SSRRequest) => Promise<SSRSpaceDeployment>;
74
74
  getUser?: (req: SSRRequest) => Promise<SSRUser | undefined>;
75
- onLogin?: (req: SSRRequest) => Promise<boolean>;
76
- onLogout?: (req: SSRRequest) => Promise<void>;
75
+ onLogin?: (req: SSRRequest, res: SSRResponseHelpers) => Promise<boolean>;
76
+ onLogout?: (req: SSRRequest, res: SSRResponseHelpers) => Promise<void>;
77
77
  getRscData?: (
78
78
  req: SSRRequest,
79
79
  spaceId: number,
@@ -88,8 +88,8 @@ type SSRAdapters = {
88
88
  - **`getOfflineData`** — returns the space snapshot (schema, plugins, styles, segments, collections) for SSR.
89
89
  - **`getSpaceDeployment`** — resolves which space and environment to render for a given inbound request. Return `{ error: { code, message } }` to abort with an HTTP error. Optionally include `templateProps` to override template variables, or `pluginNames` to activate plugins for the space (see [Plugins](#plugins) and [Template props](#template-props)).
90
90
  - **`getUser`** *(optional)* — resolves the authenticated user from the inbound request (e.g. via a session cookie or `Authorization` header). Called in parallel with `getOfflineData` on every cache miss. The returned user is forwarded to the SDK as `authenticated: true` and `user.details`, which controls page-level access for guest vs. registered users. Return `undefined` for unauthenticated requests.
91
- - **`onLogin`** *(optional)* — called when `POST {loginPath}` is received. Responsible for establishing a session or issuing tokens. Return `true` if login succeeded; return `false` to respond with `401 Unauthorized`.
92
- - **`onLogout`** *(optional)* — called when `POST {logoutPath}` is received. Responsible for invalidating any server-side user session or cache entry. The server responds with `204 No Content` after the adapter resolves.
91
+ - **`onLogin`** *(optional)* — called when `POST {loginPath}` is received. Responsible for establishing a session or issuing tokens. The raw request body is available on `req.body` (e.g. `JSON.stringify({ username, password })`), and `res` lets the adapter set the session cookie via `res.setHeader('Set-Cookie', …)`. Return `true` if login succeeded; return `false` to reject it. For a navigation (full-page form submit, `Sec-Fetch-Mode: navigate`) the server responds with a `303` redirect so the view re-renders via a GET; for a fetch it responds `200`/`401`.
92
+ - **`onLogout`** *(optional)* — called when `POST {logoutPath}` is received. Responsible for invalidating any server-side user session or cache entry, and may clear the session cookie via `res`. A navigation receives a `303` redirect; a fetch receives `204 No Content`.
93
93
  - **`getRscData`** *(optional)* — called by the RSC endpoint (`/_rsc`) to fetch server-side data for schema elements with `runtime: 'server'`. Receives the full request, space context, and the resolved user so that authenticated operations can be performed. When `ids` is provided the adapter should return data only for those element IDs (partial refresh); omitting `ids` means a full fetch for all elements. Return `{}` when there is no server data for the current request (see [RSC](#react-server-components-rsc)).
94
94
 
95
95
  ## JSON adapters (offline mode)
@@ -614,15 +614,15 @@ createSSRServer({ adapters: { getOfflineData, getSpaceDeployment, getUser } });
614
614
 
615
615
  ### Login endpoint
616
616
 
617
- The server exposes a built-in `POST /auth/login` endpoint. When hit, it calls `adapters.onLogin(req)` and responds with `200 OK` on success or `401 Unauthorized` when the adapter returns `false`:
617
+ The server exposes a built-in `POST /auth/login` endpoint. When hit, it calls `adapters.onLogin(req, res)`. The raw request body is on `req.body`, and `res` is used to set the session cookie. A navigation (full-page form submit) gets a `303` redirect so the view re-renders; a fetch gets `200 OK` on success or `401 Unauthorized` when the adapter returns `false`:
618
618
 
619
619
  ```ts
620
- const onLogin = async (req: SSRRequest): Promise<boolean> => {
620
+ const onLogin = async (req: SSRRequest, res: SSRResponseHelpers): Promise<boolean> => {
621
621
  const { username, password } = JSON.parse(req.body ?? '{}');
622
- const user = await db.users.authenticate(username, password);
623
- if (!user) return false;
622
+ const session = await db.users.authenticate(username, password);
623
+ if (!session) return false;
624
624
 
625
- // Set session cookie or issue token here
625
+ res.setHeader('Set-Cookie', `my_session=${session.token}; Path=/; HttpOnly; SameSite=Lax`);
626
626
  return true;
627
627
  };
628
628
 
@@ -641,14 +641,16 @@ createSSRServer({
641
641
 
642
642
  ### Logout endpoint
643
643
 
644
- The server exposes a built-in `POST /auth/logout` endpoint. When hit, it calls `adapters.onLogout(req)` and responds with `204 No Content`. Implement `onLogout` to invalidate the session or cached user entry:
644
+ The server exposes a built-in `POST /auth/logout` endpoint. When hit, it calls `adapters.onLogout(req, res)`. A navigation gets a `303` redirect so the view re-renders logged out; a fetch gets `204 No Content`. Implement `onLogout` to invalidate the session or cached user entry and clear the cookie:
645
645
 
646
646
  ```ts
647
- const onLogout = async (req: SSRRequest): Promise<void> => {
647
+ const onLogout = async (req: SSRRequest, res: SSRResponseHelpers): Promise<void> => {
648
648
  const token = parseCookies(req.headers['cookie'] ?? '')['my_session'];
649
649
  if (token) {
650
650
  await cache.delete(`user-${token}`);
651
651
  }
652
+
653
+ res.setHeader('Set-Cookie', 'my_session=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0');
652
654
  };
653
655
 
654
656
  createSSRServer({ adapters: { getOfflineData, getSpaceDeployment, getUser, onLogout } });
@@ -20,7 +20,7 @@ var MIME_TYPES = {
20
20
  ".txt": "text/plain; charset=utf-8",
21
21
  ".xml": "application/xml"
22
22
  };
23
- var IMMUTABLE_EXTS = new Set([
23
+ var IMMUTABLE_EXTS = /* @__PURE__ */ new Set([
24
24
  ".js",
25
25
  ".mjs",
26
26
  ".cjs",
@@ -38,4 +38,4 @@ var getCacheControl = (filePath) => {
38
38
  return IMMUTABLE_EXTS.has(ext) ? "public, max-age=31536000, immutable" : "public, max-age=3600";
39
39
  };
40
40
  //#endregion
41
- export { getCacheControl, getMimeType };
41
+ export { IMMUTABLE_EXTS, MIME_TYPES, getCacheControl, getMimeType };
@@ -1,4 +1,4 @@
1
- import { parseRequest } from "./requestParser.js";
1
+ import { parseRequest, readRawBody } from "./requestParser.js";
2
2
  import { serveStatic } from "./staticFiles.js";
3
3
  import { buildResponseHelpers } from "../helpers/buildResponseHelpers.js";
4
4
  import { runMiddlewares } from "../helpers/runMiddlewares.js";
@@ -13,6 +13,10 @@ import { fileURLToPath } from "node:url";
13
13
  //#region src/core/requestHandler.ts
14
14
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
15
15
  var BUILTIN_PUBLIC_DIR = path.resolve(__dirname, "../public");
16
+ var safeRedirectTarget = (req) => {
17
+ const redirectParam = req.query["redirect"];
18
+ return redirectParam && redirectParam.startsWith("/") && !redirectParam.startsWith("//") ? redirectParam : "/";
19
+ };
16
20
  var handleRequest = async (raw, rawRes, config, port, renderFn, caches, pluginManager) => {
17
21
  const req = parseRequest(raw);
18
22
  const res = buildResponseHelpers(rawRes, req.headers["accept-encoding"]);
@@ -54,14 +58,28 @@ var handleRequest = async (raw, rawRes, config, port, renderFn, caches, pluginMa
54
58
  }
55
59
  const loginPath = config.loginPath === false ? null : config.loginPath ?? "/auth/login";
56
60
  if (loginPath && req.method === "POST" && req.path === loginPath) {
57
- if (await config.adapters.onLogin?.(req)) res.setStatus(200);
58
- else res.setStatus(401);
61
+ req.body = await readRawBody(raw);
62
+ const isLoggedIn = await config.adapters.onLogin?.(req, res);
63
+ if (req.headers["sec-fetch-mode"] === "navigate") {
64
+ res.setStatus(303);
65
+ res.setHeader("Location", isLoggedIn ? safeRedirectTarget(req) : loginPath);
66
+ res.end();
67
+ return;
68
+ }
69
+ res.setStatus(isLoggedIn ? 200 : 401);
59
70
  res.end();
60
71
  return;
61
72
  }
62
73
  const logoutPath = config.logoutPath === false ? null : config.logoutPath ?? "/auth/logout";
63
74
  if (logoutPath && req.method === "POST" && req.path === logoutPath) {
64
- await config.adapters.onLogout?.(req);
75
+ req.body = await readRawBody(raw);
76
+ await config.adapters.onLogout?.(req, res);
77
+ if (req.headers["sec-fetch-mode"] === "navigate") {
78
+ res.setStatus(303);
79
+ res.setHeader("Location", safeRedirectTarget(req));
80
+ res.end();
81
+ return;
82
+ }
65
83
  res.setStatus(204);
66
84
  res.end();
67
85
  return;
@@ -30,5 +30,20 @@ var parseRequest = (raw) => {
30
30
  ctx: {}
31
31
  };
32
32
  };
33
+ var MAX_BODY_BYTES = 1024 * 1024;
34
+ var readRawBody = (raw) => new Promise((resolve, reject) => {
35
+ const chunks = [];
36
+ let size = 0;
37
+ raw.on("data", (chunk) => {
38
+ size += chunk.length;
39
+ if (size > MAX_BODY_BYTES) {
40
+ reject(/* @__PURE__ */ new Error("Request body too large"));
41
+ return;
42
+ }
43
+ chunks.push(chunk);
44
+ });
45
+ raw.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
46
+ raw.on("error", reject);
47
+ });
33
48
  //#endregion
34
- export { parseRequest };
49
+ export { parseRequest, readRawBody };
@@ -48,4 +48,4 @@ var buildTransport = (config, handler, port) => {
48
48
  };
49
49
  };
50
50
  //#endregion
51
- export { buildTransport, protoLabel };
51
+ export { buildTransport, protoLabel, tlsOptions };
@@ -0,0 +1,11 @@
1
+ //#region src/helpers/readCookie.ts
2
+ var readCookie = (cookieHeader, name) => {
3
+ if (!cookieHeader) return;
4
+ for (const part of cookieHeader.split(";")) {
5
+ const eq = part.indexOf("=");
6
+ if (eq === -1) continue;
7
+ if (part.slice(0, eq).trim() === name) return decodeURIComponent(part.slice(eq + 1).trim());
8
+ }
9
+ };
10
+ //#endregion
11
+ export { readCookie };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './src/index'
1
+ export * from './src/index.js'
2
2
  export {}
@@ -1,6 +1,6 @@
1
1
  import { createMcpServer } from "./server.js";
2
2
  import AIEngine from "../ai/AIEngine.js";
3
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp";
4
4
  //#region src/modules/mcp/handler.ts
5
5
  var readMcpBody = (req) => new Promise((resolve, reject) => {
6
6
  let raw = "";
@@ -72,4 +72,4 @@ var adapterWrapper = (adapterName, handler) => {
72
72
  };
73
73
  };
74
74
  //#endregion
75
- export { bindTools, getAllowedModes, isToolActive, resolveToolHandler, toolResponseErr, toolResponseOk, zodToJsonSchema };
75
+ export { adapterWrapper, bindTools, getAllowedModes, isToolActive, resolveToolHandler, toolResponseErr, toolResponseOk, zodToJsonSchema };
@@ -68,4 +68,4 @@ var getResourceList = () => allResources.map(({ uri, name, description }) => ({
68
68
  }));
69
69
  var getResourceByUri = (uri) => allResources.find((r) => r.uri === uri);
70
70
  //#endregion
71
- export { getResourceByUri, getResourceList, registerResources };
71
+ export { allResources, getResourceByUri, getResourceList, registerResources };
@@ -147,4 +147,4 @@ var tools_exports = /* @__PURE__ */ __exportAll({
147
147
  updateVariableTool: () => updateVariableTool
148
148
  });
149
149
  //#endregion
150
- export { tools_exports };
150
+ export { addPluginTool, addResourceTool, applyPreviewTool, cloneElementTool, createCollectionRecordTool, createCollectionTool, createElementTool, createPageFolderTool, createPageTool, createSegmentElementTool, createSegmentStyleVariableTool, createSegmentTool, createSegmentVariableTool, createStyleSelectorTool, createStyleVariableTool, createVariableTool, deleteCollectionRecordTool, deleteCollectionTool, deleteElementTool, deletePageFolderTool, deletePageTool, deleteSegmentElementTool, deleteSegmentStyleVariableTool, deleteSegmentTool, deleteSegmentVariableTool, deleteStyleSelectorTool, deleteStyleVariableTool, deleteVariableTool, getCollectionRecordTool, getCollectionRecordsTool, getCollectionTool, getCollectionsTool, getElementTool, getElementsTool, getPageBySlugTool, getPageFolderTool, getPageFoldersTool, getPageTool, getPagesTool, getResourceTool, getResourcesTool, getSegmentTool, getSegmentsTool, getSpaceSettingsTool, getStyleSelectorsTool, getStyleVariableTool, getStyleVariablesTool, getVariableTool, getVariablesTool, listElementsTool, listPluginsTool, listResourcesTool, moveElementTool, moveResourceTool, moveSegmentElementTool, readResourceTool, removePluginTool, removeResourceTool, tools_exports, updateCollectionRecordTool, updateCollectionTool, updateElementTool, updatePageFolderTool, updatePageTool, updatePluginTool, updateSegmentElementTool, updateSegmentStyleVariableTool, updateSegmentTool, updateSegmentVariableTool, updateSpaceSettingsTool, updateStyleSelectorTool, updateStyleVariableTool, updateVariableTool };
@@ -50,4 +50,4 @@ var schemaVariableSchema = z.object({
50
50
  })).describe("Conditional sub-values")
51
51
  });
52
52
  //#endregion
53
- export { elementSchema, pageFolderSchema, schemaVariableSchema };
53
+ export { elementDefinitionSchema, elementSchema, pageFolderSchema, schemaVariableSchema };
@@ -1,7 +1,7 @@
1
1
  import PlitziSdk from "@plitzi/plitzi-sdk";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/modules/ssr/Component.tsx
4
- var Component = ({ server, renderMode = "raw", previewMode = true, offlineData, environment = "main", plugins }) => {
4
+ var Component = ({ server, renderMode = "raw", previewMode = true, offlineData, environment = "main", plugins, ssrResult, sdkDevToolsStylePath, debugMode = false }) => {
5
5
  return /* @__PURE__ */ jsx(PlitziSdk, {
6
6
  environment,
7
7
  server,
@@ -9,6 +9,9 @@ var Component = ({ server, renderMode = "raw", previewMode = true, offlineData,
9
9
  renderMode,
10
10
  offlineMode: !!offlineData && Object.keys(offlineData).length > 0,
11
11
  offlineData,
12
+ ssrResult,
13
+ sdkDevToolsStylePath,
14
+ debugMode,
12
15
  children: plugins && Object.keys(plugins).map((key) => /* @__PURE__ */ jsx(PlitziSdk.Plugin, {
13
16
  renderType: key,
14
17
  component: plugins[key].component,
@@ -0,0 +1,14 @@
1
+ //#region src/modules/ssr/applySSRResult.ts
2
+ var applySSRResult = (res, result) => {
3
+ if (result.headers) for (const [name, value] of Object.entries(result.headers)) res.setHeader(name, value);
4
+ if (result.redirect !== void 0) {
5
+ res.setStatus(result.status ?? 302);
6
+ res.setHeader("Location", result.redirect);
7
+ res.send("");
8
+ return true;
9
+ }
10
+ if (result.status !== void 0) res.setStatus(result.status);
11
+ return false;
12
+ };
13
+ //#endregion
14
+ export { applySSRResult };
@@ -5,16 +5,24 @@ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/modules/ssr/buildBody.tsx
6
6
  var buildBody = async (req, config, spaceId, environment, revision, renderFn, pluginManager, offlineDataCache, metrics) => {
7
7
  const prep = await prepareRender(req, config, spaceId, environment, revision, pluginManager, offlineDataCache, metrics);
8
+ const result = {};
8
9
  const reactStart = metrics ? performance.now() : 0;
9
- const html = renderToString(/* @__PURE__ */ jsx(Component, { ...prep.componentProps })).trim();
10
+ const html = renderToString(/* @__PURE__ */ jsx(Component, {
11
+ ...prep.componentProps,
12
+ ssrResult: result
13
+ })).trim();
10
14
  metrics?.record("react", Math.round(performance.now() - reactStart));
15
+ if (result.redirect !== void 0) return { result };
11
16
  const templateStart = metrics ? performance.now() : 0;
12
17
  const body = renderFn({
13
18
  ...prep.templateParams,
14
19
  html
15
20
  });
16
21
  metrics?.record("template", Math.round(performance.now() - templateStart));
17
- return body;
22
+ return {
23
+ body,
24
+ result
25
+ };
18
26
  };
19
27
  //#endregion
20
28
  export { buildBody };
@@ -1,4 +1,5 @@
1
1
  import { buildHtmlCacheKey } from "../../helpers/cache/keys.js";
2
+ import { applySSRResult } from "./applySSRResult.js";
2
3
  import { buildBody } from "./buildBody.js";
3
4
  import { streamBody } from "./streamBody.js";
4
5
  import { RequestMetrics } from "../../helpers/metrics.js";
@@ -24,13 +25,14 @@ var renderSSR = async (req, res, config, renderFn, pluginManager, caches) => {
24
25
  await streamBody(req, res, config, spaceId, environment, revision, renderFn, pluginManager, caches.offlineData, htmlCache, cacheKey, metrics);
25
26
  return;
26
27
  }
27
- const body = await buildBody(req, config, spaceId, environment, revision, renderFn, pluginManager, caches.offlineData, metrics);
28
- if (htmlCache && cacheKey) htmlCache.set(cacheKey, body);
28
+ const { body, result } = await buildBody(req, config, spaceId, environment, revision, renderFn, pluginManager, caches.offlineData, metrics);
29
29
  if (metrics) {
30
30
  res.setHeader("Server-Timing", metrics.toServerTimingHeader());
31
31
  metrics.log(`${req.method} ${req.path}`);
32
32
  }
33
- res.send(body);
33
+ if (applySSRResult(res, result)) return;
34
+ if (htmlCache && cacheKey && body !== void 0) htmlCache.set(cacheKey, body);
35
+ res.send(body ?? "");
34
36
  };
35
37
  //#endregion
36
38
  export { renderSSR };
@@ -3,6 +3,7 @@ import { loadPluginComponents } from "./loadPluginComponents.js";
3
3
  import { registerExternalPlugins } from "./registerExternalPlugins.js";
4
4
  import { buildServerInfo } from "../../helpers/buildServerInfo.js";
5
5
  import { escapeJson } from "../../helpers/escapeJson.js";
6
+ import { readCookie } from "../../helpers/readCookie.js";
6
7
  //#region src/modules/ssr/prepareRender.tsx
7
8
  var prepareRender = async (req, config, spaceId, environment, revision, pluginManager, offlineDataCache, metrics) => {
8
9
  const m = (name, fn) => metrics ? metrics.measure(name, fn) : Promise.resolve(fn());
@@ -10,12 +11,17 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
10
11
  const cachedOfflineStr = offlineCacheKey ? offlineDataCache?.get(offlineCacheKey) : void 0;
11
12
  const [offlineData, server] = await Promise.all([cachedOfflineStr ? JSON.parse(cachedOfflineStr) : m("schema", () => config.adapters.getOfflineData(spaceId, environment, revision)), m("rsc", () => buildServerInfo(req, config))]);
12
13
  if (!cachedOfflineStr && offlineCacheKey && offlineData !== void 0) offlineDataCache?.set(offlineCacheKey, JSON.stringify(offlineData));
14
+ const v = config.assetVersion ? `?v=${config.assetVersion}` : "";
15
+ const sdkDevToolsStylePath = `/sdk-assets/plitzi-sdk-devtools.css${v}`;
16
+ const debugCookie = readCookie(req.headers.cookie, "plitzi_debug");
17
+ const debugMode = debugCookie === void 0 ? config.devMode : debugCookie === "true";
13
18
  const offlineDataStr = escapeJson(JSON.stringify({
14
19
  offlineData,
15
20
  offlineMode: true,
16
21
  environment,
17
22
  renderMode: "raw",
18
- server
23
+ server,
24
+ sdkDevToolsStylePath
19
25
  }));
20
26
  const pluginNames = req.ctx.spaceDeployment?.pluginNames ?? [];
21
27
  const pluginSources = req.ctx.spaceDeployment?.pluginSources;
@@ -34,14 +40,15 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
34
40
  const entries = allPluginNames.length > 0 ? await pluginManager.getEntries(allPluginNames) : [];
35
41
  const pluginComponents = await m("plugins", () => loadPluginComponents(entries, pluginManager.getComponents()));
36
42
  const templatePlugins = entries.length > 0 ? entries : req.ctx.spaceDeployment?.templateProps?.plugins;
37
- const v = config.assetVersion ? `?v=${config.assetVersion}` : "";
38
43
  const vendorJs = (config.devMode ? "/sdk-assets/plitzi-sdk-dev-vendor.js" : "/sdk-assets/plitzi-sdk-vendor.js") + v;
39
44
  return {
40
45
  componentProps: {
41
46
  plugins: Object.keys(pluginComponents).length > 0 ? pluginComponents : void 0,
42
47
  offlineData,
43
48
  server,
44
- environment: req.ctx.spaceDeployment?.environment ?? environment
49
+ environment: req.ctx.spaceDeployment?.environment ?? environment,
50
+ debugMode,
51
+ sdkDevToolsStylePath
45
52
  },
46
53
  entries,
47
54
  templateParams: {
@@ -52,9 +59,10 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
52
59
  reactJsx: vendorJs,
53
60
  reactDom: vendorJs,
54
61
  reactDomClient: vendorJs,
62
+ reactCompilerRuntime: vendorJs,
55
63
  ...req.ctx.spaceDeployment?.templateProps,
56
64
  plugins: templatePlugins,
57
- debugMode: config.devMode,
65
+ debugMode,
58
66
  ssrOnly: config.ssrOnly === true,
59
67
  offlineData: offlineDataStr
60
68
  }
@@ -1,5 +1,33 @@
1
+ import path from "node:path";
2
+ import crypto from "node:crypto";
3
+ import fs from "node:fs/promises";
1
4
  //#region src/modules/ssr/registerExternalPlugins.ts
2
- var fetchManifest = async (resource) => {
5
+ var MANIFEST_TTL_MS = 600 * 1e3;
6
+ var manifestCache = /* @__PURE__ */ new Map();
7
+ var refreshing = /* @__PURE__ */ new Set();
8
+ var cacheDir;
9
+ var manifestCacheDir = (pluginManager) => {
10
+ cacheDir ??= path.join(pluginManager.outputDir, ".manifest-cache");
11
+ return cacheDir;
12
+ };
13
+ var cacheFilePath = (dir, resource) => path.join(dir, `${crypto.createHash("sha1").update(resource).digest("hex")}.json`);
14
+ var readDiskEntry = async (dir, resource) => {
15
+ try {
16
+ const raw = await fs.readFile(cacheFilePath(dir, resource), "utf-8");
17
+ return JSON.parse(raw);
18
+ } catch {
19
+ return null;
20
+ }
21
+ };
22
+ var writeDiskEntry = async (dir, resource, entry) => {
23
+ try {
24
+ await fs.mkdir(dir, { recursive: true });
25
+ await fs.writeFile(cacheFilePath(dir, resource), JSON.stringify(entry), "utf-8");
26
+ } catch (err) {
27
+ console.warn(`[SSR] Failed to persist plugin manifest cache for ${resource}:`, err);
28
+ }
29
+ };
30
+ var fetchAndStore = async (dir, resource) => {
3
31
  try {
4
32
  const url = `${resource}/plugin-manifest.json`;
5
33
  const res = await fetch(url);
@@ -7,12 +35,34 @@ var fetchManifest = async (resource) => {
7
35
  console.warn(`[SSR] Failed to fetch plugin manifest from ${url}: HTTP ${res.status}`);
8
36
  return null;
9
37
  }
10
- return await res.json();
38
+ const manifest = await res.json();
39
+ const entry = {
40
+ manifest,
41
+ expiresAt: Date.now() + MANIFEST_TTL_MS
42
+ };
43
+ manifestCache.set(resource, entry);
44
+ await writeDiskEntry(dir, resource, entry);
45
+ return manifest;
11
46
  } catch (err) {
12
47
  console.warn(`[SSR] Error fetching plugin manifest from ${resource}:`, err);
13
48
  return null;
14
49
  }
15
50
  };
51
+ var revalidate = (dir, resource) => {
52
+ if (refreshing.has(resource)) return;
53
+ refreshing.add(resource);
54
+ fetchAndStore(dir, resource).finally(() => refreshing.delete(resource));
55
+ };
56
+ var fetchManifest = async (pluginManager, resource) => {
57
+ const dir = manifestCacheDir(pluginManager);
58
+ const cached = manifestCache.get(resource) ?? await readDiskEntry(dir, resource) ?? void 0;
59
+ if (cached) {
60
+ manifestCache.set(resource, cached);
61
+ if (cached.expiresAt <= Date.now()) revalidate(dir, resource);
62
+ return cached.manifest;
63
+ }
64
+ return fetchAndStore(dir, resource);
65
+ };
16
66
  var resolveAssetUrl = (resource, asset) => {
17
67
  if (asset.url) return asset.url;
18
68
  if (asset.src) return `${resource}/${asset.src}`;
@@ -26,7 +76,7 @@ var findAsset = (manifest, type, resource) => {
26
76
  var isAbsoluteUrl = (url) => url.startsWith("http://") || url.startsWith("https://");
27
77
  var registerPlugin = async (pluginManager, plugin) => {
28
78
  if (!plugin.resource || !isAbsoluteUrl(plugin.resource)) return null;
29
- const manifest = await fetchManifest(plugin.resource);
79
+ const manifest = await fetchManifest(pluginManager, plugin.resource);
30
80
  if (!manifest) return null;
31
81
  const jsUrl = findAsset(manifest, "script", plugin.resource);
32
82
  if (!jsUrl) {
@@ -1,3 +1,4 @@
1
+ import { applySSRResult } from "./applySSRResult.js";
1
2
  import Component from "./Component.js";
2
3
  import { prepareRender } from "./prepareRender.js";
3
4
  import { renderToPipeableStream } from "react-dom/server";
@@ -16,6 +17,7 @@ var streamBody = async (req, res, config, spaceId, environment, revision, render
16
17
  const sentinelIdx = fullTemplate.indexOf(SSR_SENTINEL);
17
18
  const head = sentinelIdx >= 0 ? fullTemplate.slice(0, sentinelIdx) : fullTemplate;
18
19
  const tail = sentinelIdx >= 0 ? fullTemplate.slice(sentinelIdx + 18) : "";
20
+ const result = {};
19
21
  await new Promise((resolve, reject) => {
20
22
  const chunks = cacheKey && htmlCache ? [] : null;
21
23
  const writable = new Writable({
@@ -34,13 +36,21 @@ var streamBody = async (req, res, config, spaceId, environment, revision, render
34
36
  }
35
37
  });
36
38
  const reactStart = metrics ? performance.now() : 0;
37
- const { pipe } = renderToPipeableStream(/* @__PURE__ */ jsx(Component, { ...prep.componentProps }), {
39
+ const { pipe, abort } = renderToPipeableStream(/* @__PURE__ */ jsx(Component, {
40
+ ...prep.componentProps,
41
+ ssrResult: result
42
+ }), {
38
43
  onShellReady() {
39
44
  metrics?.record("react", Math.round(performance.now() - reactStart));
40
45
  if (metrics) {
41
46
  res.setHeader("Server-Timing", metrics.toServerTimingHeader());
42
47
  metrics.log(`${req.method} ${req.path}`);
43
48
  }
49
+ if (applySSRResult(res, result)) {
50
+ abort();
51
+ resolve();
52
+ return;
53
+ }
44
54
  res.write(Buffer.from(head, "utf-8"));
45
55
  pipe(writable);
46
56
  },
@@ -20,6 +20,7 @@
20
20
  "react-dom": "<%= locals.reactDom || '' %>",
21
21
  "react-dom/client": "<%= locals.reactDomClient || '' %>",
22
22
  "react/jsx-runtime": "<%= locals.reactJsx || '' %>",
23
+ "react/compiler-runtime": "<%= locals.reactCompilerRuntime || locals.react || '' %>",
23
24
  "@plitzi/plitzi-sdk": "<%= locals.jsPath || '' %>"
24
25
  }
25
26
  }
package/dist/package.js CHANGED
@@ -1,62 +1,77 @@
1
+ //#region package.json
2
+ var name = "@plitzi/sdk-server";
3
+ var version = "0.32.2";
4
+ var license = "AGPL-3.0";
5
+ var files = ["dist"];
6
+ var main = "dist/index.js";
7
+ var module = "dist/index.js";
8
+ var types = "dist/index.d.ts";
9
+ var exports = { ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ } };
14
+ var repository = {
15
+ "type": "https",
16
+ "url": "https://github.com/plitzi/plitzi-workspace.git"
17
+ };
18
+ var type = "module";
19
+ var dependencies = {
20
+ "@modelcontextprotocol/sdk": "^1.29.0",
21
+ "@plitzi/plitzi-sdk": "workspace:*",
22
+ "@plitzi/sdk-shared": "workspace:*",
23
+ "ejs": "^6.0.1",
24
+ "esbuild": "^0.28.1",
25
+ "zod": "^4.4.3"
26
+ };
27
+ var peerDependencies = {
28
+ "react": "^19",
29
+ "react-dom": "^19"
30
+ };
31
+ var devDependencies = {
32
+ "@types/ejs": "^3.1.5",
33
+ "@types/node": "^26.0.0",
34
+ "@types/react": "^19.2.17",
35
+ "@vitejs/plugin-react": "^6.0.2",
36
+ "@vitest/coverage-v8": "^4.1.9",
37
+ "eslint": "^9.39.4",
38
+ "eslint-plugin-import": "^2.32.0",
39
+ "react": "^19.2.7",
40
+ "react-dom": "^19.2.7",
41
+ "tsx": "^4.22.4",
42
+ "typescript": "^6.0.3",
43
+ "vite": "^8.0.16",
44
+ "vite-plugin-dts": "^5.0.2",
45
+ "vitest": "^4.1.9"
46
+ };
47
+ var scripts = {
48
+ "start:dev": "node --import ./src/standalone/register-alias.mjs --watch src/standalone/server.ts",
49
+ "start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
50
+ "start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
51
+ "start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
52
+ "build:dev": "vite build --mode development",
53
+ "build:prod": "vite build",
54
+ "lint": "TIMING=1 eslint ./src",
55
+ "typecheck": "tsc -p tsconfig.app.json --noEmit",
56
+ "test": "vitest run",
57
+ "test:coverage": "vitest run --coverage"
58
+ };
1
59
  var package_default = {
2
- name: "@plitzi/sdk-server",
3
- version: "0.32.1",
4
- license: "AGPL-3.0",
5
- files: ["dist"],
6
- main: "dist/index.js",
7
- module: "dist/index.js",
8
- types: "dist/index.d.ts",
9
- exports: { ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "default": "./dist/index.js"
13
- } },
14
- repository: {
15
- "type": "https",
16
- "url": "https://github.com/plitzi/plitzi-workspace.git"
17
- },
18
- type: "module",
60
+ name,
61
+ version,
62
+ license,
63
+ files,
64
+ main,
65
+ module,
66
+ types,
67
+ exports,
68
+ repository,
69
+ type,
19
70
  sideEffects: false,
20
- dependencies: {
21
- "@modelcontextprotocol/sdk": "^1.29.0",
22
- "@plitzi/plitzi-sdk": "workspace:*",
23
- "@plitzi/sdk-shared": "workspace:*",
24
- "ejs": "^6.0.1",
25
- "esbuild": "^0.28.0",
26
- "zod": "^4.4.3"
27
- },
28
- peerDependencies: {
29
- "react": "^19",
30
- "react-dom": "^19"
31
- },
32
- devDependencies: {
33
- "@types/ejs": "^3.1.5",
34
- "@types/node": "^25.9.1",
35
- "@types/react": "^19.2.15",
36
- "@vitejs/plugin-react": "^6.0.2",
37
- "@vitest/coverage-v8": "^4.1.7",
38
- "eslint": "^9.39.4",
39
- "eslint-plugin-import": "^2.32.0",
40
- "react": "^19.2.6",
41
- "react-dom": "^19.2.6",
42
- "tsx": "^4.22.3",
43
- "typescript": "^6.0.3",
44
- "vite": "^8.0.14",
45
- "vite-plugin-dts": "^5.0.1",
46
- "vitest": "^4.1.7"
47
- },
48
- scripts: {
49
- "start:dev": "TSX_TSCONFIG_PATH=tsconfig.app.json ALIAS_LOADER_DEBUG=1 node --import ./src/standalone/register-alias.mjs --import tsx --watch src/standalone/server.ts",
50
- "start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
51
- "start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
52
- "start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
53
- "build:dev": "vite build --mode development",
54
- "build:prod": "vite build",
55
- "lint": "TIMING=1 eslint ./src",
56
- "typecheck": "tsc -p tsconfig.app.json --noEmit",
57
- "test": "vitest run",
58
- "test:coverage": "vitest run --coverage"
59
- }
71
+ dependencies,
72
+ peerDependencies,
73
+ devDependencies,
74
+ scripts
60
75
  };
61
76
  //#endregion
62
- export { package_default as default };
77
+ export { package_default as default, dependencies, devDependencies, exports, files, license, main, module, name, peerDependencies, repository, scripts, type, types, version };
@@ -1,6 +1,6 @@
1
1
  declare const _default: {
2
2
  "name": "@plitzi/sdk-server",
3
- "version": "0.32.1",
3
+ "version": "0.32.2",
4
4
  "license": "AGPL-3.0",
5
5
  "files": [
6
6
  "dist"
@@ -26,7 +26,7 @@ declare const _default: {
26
26
  "@plitzi/plitzi-sdk": "workspace:*",
27
27
  "@plitzi/sdk-shared": "workspace:*",
28
28
  "ejs": "^6.0.1",
29
- "esbuild": "^0.28.0",
29
+ "esbuild": "^0.28.1",
30
30
  "zod": "^4.4.3"
31
31
  },
32
32
  "peerDependencies": {
@@ -35,22 +35,22 @@ declare const _default: {
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/ejs": "^3.1.5",
38
- "@types/node": "^25.9.1",
39
- "@types/react": "^19.2.15",
38
+ "@types/node": "^26.0.0",
39
+ "@types/react": "^19.2.17",
40
40
  "@vitejs/plugin-react": "^6.0.2",
41
- "@vitest/coverage-v8": "^4.1.7",
41
+ "@vitest/coverage-v8": "^4.1.9",
42
42
  "eslint": "^9.39.4",
43
43
  "eslint-plugin-import": "^2.32.0",
44
- "react": "^19.2.6",
45
- "react-dom": "^19.2.6",
46
- "tsx": "^4.22.3",
44
+ "react": "^19.2.7",
45
+ "react-dom": "^19.2.7",
46
+ "tsx": "^4.22.4",
47
47
  "typescript": "^6.0.3",
48
- "vite": "^8.0.14",
49
- "vite-plugin-dts": "^5.0.1",
50
- "vitest": "^4.1.7"
48
+ "vite": "^8.0.16",
49
+ "vite-plugin-dts": "^5.0.2",
50
+ "vitest": "^4.1.9"
51
51
  },
52
52
  "scripts": {
53
- "start:dev": "TSX_TSCONFIG_PATH=tsconfig.app.json ALIAS_LOADER_DEBUG=1 node --import ./src/standalone/register-alias.mjs --import tsx --watch src/standalone/server.ts",
53
+ "start:dev": "node --import ./src/standalone/register-alias.mjs --watch src/standalone/server.ts",
54
54
  "start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
55
55
  "start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
56
56
  "start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
@@ -1,3 +1,4 @@
1
1
  import { SSRRequest } from '@plitzi/sdk-shared';
2
2
  import { IncomingMessage } from 'node:http';
3
3
  export declare const parseRequest: (raw: IncomingMessage) => SSRRequest;
4
+ export declare const readRawBody: (raw: IncomingMessage) => Promise<string>;
@@ -0,0 +1 @@
1
+ export declare const readCookie: (cookieHeader: string | undefined, name: string) => string | undefined;
@@ -1,4 +1,4 @@
1
- import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
1
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp';
2
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp';
3
3
  import { McpServerConfig, AiContext } from '@plitzi/sdk-shared';
4
4
  import { IncomingMessage, ServerResponse } from 'node:http';
@@ -1,4 +1,4 @@
1
- import { OfflineDataRaw, Environment, RenderMode, Server, SSRPlugin } from '@plitzi/sdk-shared';
1
+ import { OfflineDataRaw, Environment, RenderMode, Server, SSRPlugin, SSRRenderResult } from '@plitzi/sdk-shared';
2
2
  export type ComponentProps = {
3
3
  server: Partial<Server>;
4
4
  renderMode?: Extract<RenderMode, 'raw'>;
@@ -6,6 +6,9 @@ export type ComponentProps = {
6
6
  previewMode?: boolean;
7
7
  offlineData?: OfflineDataRaw;
8
8
  plugins?: Record<string, SSRPlugin>;
9
+ ssrResult?: SSRRenderResult;
10
+ sdkDevToolsStylePath?: string;
11
+ debugMode?: boolean;
9
12
  };
10
- declare const Component: ({ server, renderMode, previewMode, offlineData, environment, plugins }: ComponentProps) => import("react/jsx-runtime").JSX.Element;
13
+ declare const Component: ({ server, renderMode, previewMode, offlineData, environment, plugins, ssrResult, sdkDevToolsStylePath, debugMode }: ComponentProps) => import("react").JSX.Element;
11
14
  export default Component;
@@ -0,0 +1,2 @@
1
+ import { SSRRenderResult, SSRResponseHelpers } from '@plitzi/sdk-shared';
2
+ export declare const applySSRResult: (res: SSRResponseHelpers, result: SSRRenderResult) => boolean;
@@ -1,5 +1,9 @@
1
1
  import { TtlCache } from '../../helpers/cache';
2
2
  import { RequestMetrics } from '../../helpers/metrics';
3
3
  import { PluginManager } from '../../plugins/manager';
4
- import { Environment, SSRRequest, SSRServerConfig, SSRTemplateFn } from '@plitzi/sdk-shared';
5
- export declare const buildBody: (req: SSRRequest, config: SSRServerConfig, spaceId: number, environment: Environment, revision: number, renderFn: SSRTemplateFn, pluginManager: PluginManager, offlineDataCache?: TtlCache<string>, metrics?: RequestMetrics) => Promise<string>;
4
+ import { Environment, SSRRenderResult, SSRRequest, SSRServerConfig, SSRTemplateFn } from '@plitzi/sdk-shared';
5
+ export type BuildBodyResult = {
6
+ body?: string;
7
+ result: SSRRenderResult;
8
+ };
9
+ export declare const buildBody: (req: SSRRequest, config: SSRServerConfig, spaceId: number, environment: Environment, revision: number, renderFn: SSRTemplateFn, pluginManager: PluginManager, offlineDataCache?: TtlCache<string>, metrics?: RequestMetrics) => Promise<BuildBodyResult>;
@@ -1 +1,2 @@
1
1
  export function resolve(specifier: any, context: any, defaultResolve: any): Promise<any>;
2
+ export function load(url: any, context: any, nextLoad: any): Promise<any>;
@@ -1,2 +1,2 @@
1
- declare const ClientInfo: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const ClientInfo: () => import("react").JSX.Element;
2
2
  export default ClientInfo;
@@ -1,2 +1,2 @@
1
- declare const ServerInfo: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const ServerInfo: () => import("react").JSX.Element;
2
2
  export default ServerInfo;
@@ -1,2 +1,2 @@
1
- declare const SharedInfo: () => import("react/jsx-runtime").JSX.Element;
1
+ declare const SharedInfo: () => import("react").JSX.Element;
2
2
  export default SharedInfo;
@@ -0,0 +1,31 @@
1
+ export function PrismLight({ children }: {
2
+ children: any;
3
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
4
+ export namespace PrismLight {
5
+ function registerLanguage(): void;
6
+ }
7
+ export function PrismLight({ children }: {
8
+ children: any;
9
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
10
+ export namespace PrismLight { }
11
+ export function PrismLight({ children }: {
12
+ children: any;
13
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
14
+ export namespace PrismLight { }
15
+ export function PrismLight({ children }: {
16
+ children: any;
17
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
18
+ export namespace PrismLight { }
19
+ export function PrismLight({ children }: {
20
+ children: any;
21
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
22
+ export namespace PrismLight { }
23
+ export function PrismLight({ children }: {
24
+ children: any;
25
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
26
+ export namespace PrismLight { }
27
+ export default SyntaxHighlighter;
28
+ declare function SyntaxHighlighter({ children }: {
29
+ children: any;
30
+ }): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
31
+ declare namespace SyntaxHighlighter { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plitzi/sdk-server",
3
- "version": "0.32.1",
3
+ "version": "0.32.2",
4
4
  "license": "AGPL-3.0",
5
5
  "files": [
6
6
  "dist"
@@ -23,10 +23,10 @@
23
23
  "sideEffects": false,
24
24
  "dependencies": {
25
25
  "@modelcontextprotocol/sdk": "^1.29.0",
26
- "@plitzi/plitzi-sdk": "0.32.1",
27
- "@plitzi/sdk-shared": "0.32.1",
26
+ "@plitzi/plitzi-sdk": "0.32.2",
27
+ "@plitzi/sdk-shared": "0.32.2",
28
28
  "ejs": "^6.0.1",
29
- "esbuild": "^0.28.0",
29
+ "esbuild": "^0.28.1",
30
30
  "zod": "^4.4.3"
31
31
  },
32
32
  "peerDependencies": {
@@ -35,22 +35,22 @@
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/ejs": "^3.1.5",
38
- "@types/node": "^25.9.1",
39
- "@types/react": "^19.2.15",
38
+ "@types/node": "^26.0.0",
39
+ "@types/react": "^19.2.17",
40
40
  "@vitejs/plugin-react": "^6.0.2",
41
- "@vitest/coverage-v8": "^4.1.7",
41
+ "@vitest/coverage-v8": "^4.1.9",
42
42
  "eslint": "^9.39.4",
43
43
  "eslint-plugin-import": "^2.32.0",
44
- "react": "^19.2.6",
45
- "react-dom": "^19.2.6",
46
- "tsx": "^4.22.3",
44
+ "react": "^19.2.7",
45
+ "react-dom": "^19.2.7",
46
+ "tsx": "^4.22.4",
47
47
  "typescript": "^6.0.3",
48
- "vite": "^8.0.14",
49
- "vite-plugin-dts": "^5.0.1",
50
- "vitest": "^4.1.7"
48
+ "vite": "^8.0.16",
49
+ "vite-plugin-dts": "^5.0.2",
50
+ "vitest": "^4.1.9"
51
51
  },
52
52
  "scripts": {
53
- "start:dev": "TSX_TSCONFIG_PATH=tsconfig.app.json ALIAS_LOADER_DEBUG=1 node --import ./src/standalone/register-alias.mjs --import tsx --watch src/standalone/server.ts",
53
+ "start:dev": "node --import ./src/standalone/register-alias.mjs --watch src/standalone/server.ts",
54
54
  "start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
55
55
  "start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
56
56
  "start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",