@blinkk/root-cms 2.1.2-alpha.0 → 2.2.1-alpha.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/app.js CHANGED
@@ -1,13 +1,89 @@
1
1
  // core/app.tsx
2
2
  import crypto from "crypto";
3
3
  import path from "path";
4
- import { fileURLToPath } from "url";
5
4
  import { render as renderToString } from "preact-render-to-string";
6
5
 
6
+ // core/project.ts
7
+ var SCHEMA_MODULES = import.meta.glob(
8
+ [
9
+ "/**/*.schema.ts",
10
+ "!/appengine/**/*.schema.ts",
11
+ "!/functions/**/*.schema.ts",
12
+ "!/gae/**/*.schema.ts"
13
+ ],
14
+ { eager: true }
15
+ );
16
+ async function getProjectSchemas() {
17
+ const schemas = {};
18
+ for (const fileId in SCHEMA_MODULES) {
19
+ const schemaModule = SCHEMA_MODULES[fileId];
20
+ if (schemaModule.default) {
21
+ schemas[fileId] = schemaModule.default;
22
+ }
23
+ }
24
+ return schemas;
25
+ }
26
+ async function getCollectionSchema(collectionId) {
27
+ if (!testValidCollectionId(collectionId)) {
28
+ throw new Error(`invalid collection id: ${collectionId}`);
29
+ }
30
+ const fileId = `/collections/${collectionId}.schema.ts`;
31
+ const module = SCHEMA_MODULES[fileId];
32
+ if (!module.default) {
33
+ console.warn(`collection schema not exported in: ${fileId}`);
34
+ return null;
35
+ }
36
+ const collection = module.default;
37
+ collection.id = collectionId;
38
+ return convertOneOfTypes(collection);
39
+ }
40
+ function testValidCollectionId(id) {
41
+ return /^[A-Za-z0-9_-]+$/.test(id);
42
+ }
43
+ function convertOneOfTypes(collection) {
44
+ const clone = structuredClone(collection);
45
+ const types = clone.types || {};
46
+ function handleOneOfField(field) {
47
+ const names = [];
48
+ (field.types || []).forEach((sub) => {
49
+ if (typeof sub === "string") {
50
+ names.push(sub);
51
+ return;
52
+ }
53
+ if (sub.name) {
54
+ names.push(sub.name);
55
+ if (!types[sub.name]) {
56
+ types[sub.name] = sub;
57
+ if (sub.fields) {
58
+ walk(sub);
59
+ }
60
+ }
61
+ }
62
+ });
63
+ field.types = names;
64
+ }
65
+ function handleField(field) {
66
+ if (field.type === "oneof") {
67
+ handleOneOfField(field);
68
+ } else if (field.type === "object") {
69
+ walk(field);
70
+ } else if (field.type === "array" && field.of) {
71
+ handleField(field.of);
72
+ }
73
+ }
74
+ function walk(schema) {
75
+ const fields = schema?.fields || [];
76
+ fields.forEach(handleField);
77
+ }
78
+ walk(clone);
79
+ clone.types = types;
80
+ return clone;
81
+ }
82
+
7
83
  // package.json
8
84
  var package_default = {
9
85
  name: "@blinkk/root-cms",
10
- version: "2.1.2-alpha.0",
86
+ version: "3.0.0",
11
87
  author: "s@blinkk.com",
12
88
  license: "MIT",
13
89
  engines: {
@@ -61,8 +137,8 @@ var package_default = {
61
137
  build: 'rm -rf dist && concurrently -n "core,signin,ui" npm:build:core npm:build:signin npm:build:ui',
62
138
  "build:core": "tsup-node --config=./core/tsup.config.ts",
63
139
  "//": "NOTE: esbuild is used here because tsup doesn't currently support aliases.",
64
- "build:ui": "esbuild ui/ui.tsx --bundle --minify --alias:react=@preact/compat --alias:react-dom=@preact/compat --tsconfig=ui/tsconfig.json --outdir=dist/ui",
65
- "build:signin": "esbuild signin/signin.tsx --bundle --minify --tsconfig=signin/tsconfig.json --outdir=dist/ui",
140
+ "build:ui": "esbuild ui/ui.tsx --bundle --minify --alias:react=@preact/compat --alias:react-dom=@preact/compat --tsconfig=ui/tsconfig.json --outdir=dist/ui --legal-comments=external",
141
+ "build:signin": "esbuild signin/signin.tsx --bundle --minify --tsconfig=signin/tsconfig.json --outdir=dist/ui --legal-comments=external",
66
142
  dev: 'rm -rf dist && concurrently -k -n "core,ui" npm:dev:core npm:dev:signin npm:dev:ui',
67
143
  "dev:core": "pnpm build:core --watch",
68
144
  "dev:signin": "pnpm build:signin --watch",
@@ -131,7 +207,7 @@ var package_default = {
131
207
  "@types/jsonwebtoken": "9.0.1",
132
208
  "@types/node": "24.3.1",
133
209
  concurrently: "7.6.0",
134
- esbuild: "0.19.9",
210
+ esbuild: "0.25.9",
135
211
  firebase: "12.2.1",
136
212
  "firebase-admin": "13.5.0",
137
213
  "firebase-functions": "6.4.0",
@@ -156,7 +232,7 @@ var package_default = {
156
232
  yjs: "13.6.27"
157
233
  },
158
234
  peerDependencies: {
159
- "@blinkk/root": "2.1.2-alpha.0",
235
+ "@blinkk/root": "2.1.1",
160
236
  "firebase-admin": ">=11",
161
237
  "firebase-functions": ">=4",
162
238
  preact: ">=10",
@@ -169,86 +245,17 @@ var package_default = {
169
245
  }
170
246
  };
171
247
 
172
- // core/project.ts
173
- var SCHEMA_MODULES = import.meta.glob(
174
- [
175
- "/**/*.schema.ts",
176
- "!/appengine/**/*.schema.ts",
177
- "!/functions/**/*.schema.ts",
178
- "!/gae/**/*.schema.ts"
179
- ],
180
- { eager: true }
181
- );
182
- async function getProjectSchemas() {
183
- const schemas = {};
184
- for (const fileId in SCHEMA_MODULES) {
185
- const schemaModule = SCHEMA_MODULES[fileId];
186
- if (schemaModule.default) {
187
- schemas[fileId] = schemaModule.default;
188
- }
248
+ // core/server-version.ts
249
+ var SERVER_STARTUP_TS = String(Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3));
250
+ function getServerVersion() {
251
+ if (process.env.NODE_ENV === "development") {
252
+ return SERVER_STARTUP_TS;
189
253
  }
190
- return schemas;
191
- }
192
- async function getCollectionSchema(collectionId) {
193
- if (!testValidCollectionId(collectionId)) {
194
- throw new Error(`invalid collection id: ${collectionId}`);
195
- }
196
- const fileId = `/collections/${collectionId}.schema.ts`;
197
- const module = SCHEMA_MODULES[fileId];
198
- if (!module.default) {
199
- console.warn(`collection schema not exported in: ${fileId}`);
200
- return null;
201
- }
202
- const collection = module.default;
203
- collection.id = collectionId;
204
- return convertOneOfTypes(collection);
205
- }
206
- function testValidCollectionId(id) {
207
- return /^[A-Za-z0-9_-]+$/.test(id);
208
- }
209
- function convertOneOfTypes(collection) {
210
- const clone = structuredClone(collection);
211
- const types = clone.types || {};
212
- function handleOneOfField(field) {
213
- const names = [];
214
- (field.types || []).forEach((sub) => {
215
- if (typeof sub === "string") {
216
- names.push(sub);
217
- return;
218
- }
219
- if (sub.name) {
220
- names.push(sub.name);
221
- if (!types[sub.name]) {
222
- types[sub.name] = sub;
223
- if (sub.fields) {
224
- walk(sub);
225
- }
226
- }
227
- }
228
- });
229
- field.types = names;
230
- }
231
- function handleField(field) {
232
- if (field.type === "oneof") {
233
- handleOneOfField(field);
234
- } else if (field.type === "object") {
235
- walk(field);
236
- } else if (field.type === "array" && field.of) {
237
- handleField(field.of);
238
- }
239
- }
240
- function walk(schema) {
241
- const fields = schema?.fields || [];
242
- fields.forEach(handleField);
243
- }
244
- walk(clone);
245
- clone.types = types;
246
- return clone;
254
+ return package_default?.version || "root-3.0.0";
247
255
  }
248
256
 
249
257
  // core/app.tsx
250
258
  import { jsx, jsxs } from "preact/jsx-runtime";
251
- var __dirname = path.dirname(fileURLToPath(import.meta.url));
252
259
  var DEFAULT_FAVICON_URL = "https://lh3.googleusercontent.com/ijK50TfQlV_yJw3i-CMlnD6osH4PboZBILZrJcWhoNMEmoyCD5e1bAxXbaOPe5w4gG_Scf37EXrmZ6p8sP2lue5fLZ419m5JyLMs=e385-w256";
253
260
  function App(props) {
254
261
  return /* @__PURE__ */ jsxs("html", { children: [
@@ -356,21 +363,9 @@ async function renderApp(req, res, options) {
356
363
  const mainHtml = renderToString(
357
364
  /* @__PURE__ */ jsx(App, { title, ctx, favicon: cmsConfig.favicon })
358
365
  );
359
- let html = `<!doctype html>
360
- ${mainHtml}`;
361
366
  const nonce = generateNonce();
362
- if (req.viteServer) {
363
- const uiCssPath = path.join(__dirname, "ui/ui.css");
364
- const uiJsPath = path.join(__dirname, "ui/ui.js");
365
- const tpl = html.replace("{CSS_URL}", cachebust(req, `/@fs${uiCssPath}`)).replace("{JS_URL}", cachebust(req, `/@fs${uiJsPath}`)).replaceAll("{NONCE}", nonce);
366
- html = await req.viteServer.transformIndexHtml(req.originalUrl, tpl);
367
- html = html.replace(
368
- '<script type="module" src="/@vite/client"></script>',
369
- `<script type="module" src="/@vite/client" nonce="${nonce}"></script>`
370
- );
371
- } else {
372
- html = html.replace("{CSS_URL}", cachebust(req, "/cms/static/ui.css")).replace("{JS_URL}", cachebust(req, "/cms/static/ui.js")).replaceAll("{NONCE}", nonce);
373
- }
367
+ const html = `<!doctype html>
368
+ ${mainHtml}`.replace("{CSS_URL}", cachebust(req, "/cms/static/ui.css")).replace("{JS_URL}", cachebust(req, "/cms/static/ui.js")).replaceAll("{NONCE}", nonce);
374
369
  res.setHeader("Content-Type", "text/html");
375
370
  setSecurityHeaders(options, req, res, nonce);
376
371
  res.send(html);
@@ -450,21 +445,9 @@ async function renderSignIn(req, res, options) {
450
445
  const mainHtml = renderToString(
451
446
  /* @__PURE__ */ jsx(SignIn, { title: "Sign in", ctx, favicon: options.cmsConfig.favicon })
452
447
  );
453
- let html = `<!doctype html>
454
- ${mainHtml}`;
455
448
  const nonce = generateNonce();
456
- if (req.viteServer) {
457
- const cssPath = path.join(__dirname, "ui/signin.css");
458
- const jsPath = path.join(__dirname, "ui/signin.js");
459
- const tpl = html.replace("{CSS_URL}", cachebust(req, `/@fs${cssPath}`)).replace("{JS_URL}", cachebust(req, `/@fs${jsPath}`)).replaceAll("{NONCE}", nonce);
460
- html = await req.viteServer.transformIndexHtml(req.originalUrl, tpl);
461
- html = html.replace(
462
- '<script type="module" src="/@vite/client"></script>',
463
- `<script type="module" src="/@vite/client" nonce="${nonce}"></script>`
464
- );
465
- } else {
466
- html = html.replace("{CSS_URL}", cachebust(req, "/cms/static/signin.css")).replace("{JS_URL}", cachebust(req, "/cms/static/signin.js")).replaceAll("{NONCE}", nonce);
467
- }
449
+ const html = `<!doctype html>
450
+ ${mainHtml}`.replace("{CSS_URL}", cachebust(req, "/cms/static/signin.css")).replace("{JS_URL}", cachebust(req, "/cms/static/signin.js")).replaceAll("{NONCE}", nonce);
468
451
  res.setHeader("Content-Type", "text/html");
469
452
  setSecurityHeaders(options, req, res, nonce);
470
453
  res.status(403);
@@ -523,8 +506,12 @@ function getRefererOrigin(req) {
523
506
  return refererOrigin;
524
507
  }
525
508
  function cachebust(req, url) {
526
- const value = req.hostname === "localhost" ? Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3) : package_default.version;
527
- return `${url}?c=${value}`;
509
+ const cb = getServerVersion();
510
+ const host = req.get("host");
511
+ if (host?.includes("localhost")) {
512
+ return `http://${host}${url}?c=${cb}`;
513
+ }
514
+ return `${url}?c=${cb}`;
528
515
  }
529
516
  export {
530
517
  getCollection,
package/dist/plugin.js CHANGED
@@ -370,6 +370,18 @@ import { getFirestore } from "firebase-admin/firestore";
370
370
  import * as jsonwebtoken from "jsonwebtoken";
371
371
  import sirv from "sirv";
372
372
 
373
+ // shared/sse.ts
374
+ var SSEEvent = {
375
+ /**
376
+ * First connection event.
377
+ */
378
+ CONNECTED: "connected",
379
+ /**
380
+ * Changes to any .schema.ts file.
381
+ */
382
+ SCHEMA_CHANGED: "schemaChanged"
383
+ };
384
+
373
385
  // core/api.ts
374
386
  import { promises as fs2 } from "fs";
375
387
  import path3 from "path";
@@ -2413,6 +2425,227 @@ function api(server, options) {
2413
2425
  });
2414
2426
  }
2415
2427
 
2428
+ // package.json
2429
+ var package_default = {
2430
+ name: "@blinkk/root-cms",
2431
+ version: "3.0.0",
2432
+ author: "s@blinkk.com",
2433
+ license: "MIT",
2434
+ engines: {
2435
+ node: ">=16.0.0"
2436
+ },
2437
+ repository: {
2438
+ type: "git",
2439
+ url: "git+https://github.com/blinkk/rootjs.git",
2440
+ directory: "packages/root-cms"
2441
+ },
2442
+ files: [
2443
+ "dist/**/*"
2444
+ ],
2445
+ bin: {
2446
+ "root-cms": "./bin/root-cms.js"
2447
+ },
2448
+ type: "module",
2449
+ module: "./dist/index.js",
2450
+ types: "./dist/index.d.ts",
2451
+ exports: {
2452
+ ".": {
2453
+ types: "./dist/core.d.ts",
2454
+ import: "./dist/core.js"
2455
+ },
2456
+ "./client": {
2457
+ types: "./dist/client.d.ts",
2458
+ import: "./dist/client.js"
2459
+ },
2460
+ "./core": {
2461
+ types: "./dist/core.d.ts",
2462
+ import: "./dist/core.js"
2463
+ },
2464
+ "./functions": {
2465
+ types: "./dist/functions.d.ts",
2466
+ import: "./dist/functions.js"
2467
+ },
2468
+ "./plugin": {
2469
+ types: "./dist/plugin.d.ts",
2470
+ import: "./dist/plugin.js"
2471
+ },
2472
+ "./project": {
2473
+ types: "./dist/project.d.ts",
2474
+ import: "./dist/project.js"
2475
+ },
2476
+ "./richtext": {
2477
+ types: "./dist/richtext.d.ts",
2478
+ import: "./dist/richtext.js"
2479
+ }
2480
+ },
2481
+ scripts: {
2482
+ build: 'rm -rf dist && concurrently -n "core,signin,ui" npm:build:core npm:build:signin npm:build:ui',
2483
+ "build:core": "tsup-node --config=./core/tsup.config.ts",
2484
+ "//": "NOTE: esbuild is used here because tsup doesn't currently support aliases.",
2485
+ "build:ui": "esbuild ui/ui.tsx --bundle --minify --alias:react=@preact/compat --alias:react-dom=@preact/compat --tsconfig=ui/tsconfig.json --outdir=dist/ui --legal-comments=external",
2486
+ "build:signin": "esbuild signin/signin.tsx --bundle --minify --tsconfig=signin/tsconfig.json --outdir=dist/ui --legal-comments=external",
2487
+ dev: 'rm -rf dist && concurrently -k -n "core,ui" npm:dev:core npm:dev:signin npm:dev:ui',
2488
+ "dev:core": "pnpm build:core --watch",
2489
+ "dev:signin": "pnpm build:signin --watch",
2490
+ "dev:ui": "pnpm build:ui --watch",
2491
+ test: "pnpm build && firebase emulators:exec 'vitest run'",
2492
+ "test:watch": "pnpm build && firebase emulators:exec 'vitest'"
2493
+ },
2494
+ dependencies: {
2495
+ "@genkit-ai/ai": "1.18.0",
2496
+ "@genkit-ai/core": "1.18.0",
2497
+ "@genkit-ai/vertexai": "1.18.0",
2498
+ "@google-cloud/firestore": "7.11.3",
2499
+ "@hello-pangea/dnd": "18.0.1",
2500
+ "body-parser": "1.20.2",
2501
+ commander: "11.0.0",
2502
+ "csv-parse": "5.5.2",
2503
+ "csv-stringify": "6.4.4",
2504
+ diff: "8.0.2",
2505
+ "dts-dom": "3.7.0",
2506
+ "fnv-plus": "1.3.1",
2507
+ genkit: "1.18.0",
2508
+ jsonwebtoken: "9.0.2",
2509
+ kleur: "4.1.5",
2510
+ sirv: "2.0.3",
2511
+ "tiny-glob": "0.2.9",
2512
+ zod: "3.23.8"
2513
+ },
2514
+ "//": "NOTE(stevenle): due to compat issues with mantine and preact, mantine is pinned to v4.2.12",
2515
+ devDependencies: {
2516
+ "@babel/core": "7.17.9",
2517
+ "@blinkk/root": "workspace:*",
2518
+ "@editorjs/editorjs": "2.30.8",
2519
+ "@editorjs/header": "2.8.8",
2520
+ "@editorjs/image": "2.10.2",
2521
+ "@editorjs/list": "2.0.6",
2522
+ "@editorjs/nested-list": "1.4.3",
2523
+ "@editorjs/raw": "2.5.1",
2524
+ "@editorjs/table": "2.4.4",
2525
+ "@editorjs/underline": "1.2.1",
2526
+ "@emotion/react": "11.10.5",
2527
+ "@firebase/app-compat": "0.5.2",
2528
+ "@firebase/app-types": "0.9.3",
2529
+ "@firebase/rules-unit-testing": "5.0.0",
2530
+ "@lexical/code": "0.33.1",
2531
+ "@lexical/html": "0.33.1",
2532
+ "@lexical/link": "0.33.1",
2533
+ "@lexical/list": "0.33.1",
2534
+ "@lexical/markdown": "0.33.1",
2535
+ "@lexical/react": "0.33.1",
2536
+ "@lexical/rich-text": "0.33.1",
2537
+ "@lexical/selection": "0.33.1",
2538
+ "@lexical/utils": "0.33.1",
2539
+ "@mantine/core": "4.2.12",
2540
+ "@mantine/hooks": "4.2.12",
2541
+ "@mantine/modals": "4.2.12",
2542
+ "@mantine/notifications": "4.2.12",
2543
+ "@mantine/spotlight": "4.2.12",
2544
+ "@preact/compat": "17.1.2",
2545
+ "@tabler/icons-preact": "2.47.0",
2546
+ "@types/body-parser": "1.19.3",
2547
+ "@types/fnv-plus": "1.3.2",
2548
+ "@types/gapi": "0.0.47",
2549
+ "@types/gapi.client.drive-v3": "0.0.4",
2550
+ "@types/gapi.client.sheets-v4": "0.0.4",
2551
+ "@types/google.accounts": "0.0.14",
2552
+ "@types/jsonwebtoken": "9.0.1",
2553
+ "@types/node": "24.3.1",
2554
+ concurrently: "7.6.0",
2555
+ esbuild: "0.25.9",
2556
+ firebase: "12.2.1",
2557
+ "firebase-admin": "13.5.0",
2558
+ "firebase-functions": "6.4.0",
2559
+ "firebase-tools": "14.15.2",
2560
+ "highlight.js": "11.6.0",
2561
+ "json-diff-kit": "1.0.29",
2562
+ lexical: "0.33.1",
2563
+ marked: "9.1.1",
2564
+ "mdast-util-from-markdown": "2.0.1",
2565
+ "mdast-util-gfm": "3.0.0",
2566
+ "micromark-extension-gfm": "3.0.0",
2567
+ preact: "10.27.1",
2568
+ "preact-render-to-string": "6.6.1",
2569
+ "preact-router": "4.1.2",
2570
+ react: "npm:@preact/compat@^17.1.2",
2571
+ "react-dom": "npm:@preact/compat@^17.1.2",
2572
+ "react-json-view-compare": "2.0.2",
2573
+ tsup: "8.5.0",
2574
+ typescript: "5.9.2",
2575
+ vite: "7.1.4",
2576
+ vitest: "3.2.4",
2577
+ yjs: "13.6.27"
2578
+ },
2579
+ peerDependencies: {
2580
+ "@blinkk/root": "2.1.1",
2581
+ "firebase-admin": ">=11",
2582
+ "firebase-functions": ">=4",
2583
+ preact: ">=10",
2584
+ "preact-render-to-string": ">=5"
2585
+ },
2586
+ peerDependenciesMeta: {
2587
+ "firebase-functions": {
2588
+ optional: true
2589
+ }
2590
+ }
2591
+ };
2592
+
2593
+ // core/server-version.ts
2594
+ var SERVER_STARTUP_TS = String(Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3));
2595
+ function getServerVersion() {
2596
+ if (process.env.NODE_ENV === "development") {
2597
+ return SERVER_STARTUP_TS;
2598
+ }
2599
+ return package_default?.version || "root-3.0.0";
2600
+ }
2601
+
2602
+ // core/sse.ts
2603
+ function sse(server) {
2604
+ const sseClients = /* @__PURE__ */ new Set();
2605
+ const sseBroadcast = (event, data) => {
2606
+ const message = formatMessage(event, data);
2607
+ sseClients.forEach((res) => {
2608
+ try {
2609
+ res.write(message);
2610
+ } catch (error) {
2611
+ sseClients.delete(res);
2612
+ }
2613
+ });
2614
+ };
2615
+ server.use("/cms/api/sse.connect", async (req, res) => {
2616
+ res.writeHead(200, {
2617
+ "Content-Type": "text/event-stream",
2618
+ "Cache-Control": "no-cache",
2619
+ Connection: "keep-alive",
2620
+ "Access-Control-Allow-Origin": "*",
2621
+ "Access-Control-Allow-Headers": "Cache-Control"
2622
+ });
2623
+ sseClients.add(res);
2624
+ const connectedMessage = formatMessage(
2625
+ SSEEvent.CONNECTED,
2626
+ // Send the server version to notify clients if their current version is
2627
+ // out-of-date.
2628
+ { serverVersion: getServerVersion() }
2629
+ );
2630
+ res.write(connectedMessage);
2631
+ req.on("close", () => {
2632
+ sseClients.delete(res);
2633
+ });
2634
+ req.on("aborted", () => {
2635
+ sseClients.delete(res);
2636
+ });
2637
+ });
2638
+ return { sseBroadcast };
2639
+ }
2640
+ function formatMessage(event, data) {
2641
+ const lines = [`event: ${event}`];
2642
+ if (data) {
2643
+ lines.push(`data: ${JSON.stringify(data)}`);
2644
+ }
2645
+ const message = lines.join("\n") + "\n\n";
2646
+ return message;
2647
+ }
2648
+
2416
2649
  // core/plugin.ts
2417
2650
  var __dirname2 = path5.dirname(fileURLToPath2(import.meta.url));
2418
2651
  async function writeCollectionSchemasToJson(rootConfig) {
@@ -2477,6 +2710,7 @@ function cmsPlugin(options) {
2477
2710
  const firebaseConfig = options.firebaseConfig || {};
2478
2711
  const app = getFirebaseApp(firebaseConfig.projectId);
2479
2712
  const auth = getAuth(app);
2713
+ let sseBroadcast = null;
2480
2714
  function loginRequired(req) {
2481
2715
  const urlPath = String(req.originalUrl).split("?")[0].toLowerCase();
2482
2716
  if (urlPath === "/cms/api/cron.run") {
@@ -2743,6 +2977,10 @@ function cmsPlugin(options) {
2743
2977
  });
2744
2978
  const staticDir = path5.resolve(__dirname2, "ui");
2745
2979
  server.use("/cms/static", sirv(staticDir, { dev: false }));
2980
+ const sseData = sse(server);
2981
+ if (sseData.sseBroadcast) {
2982
+ sseBroadcast = sseData.sseBroadcast;
2983
+ }
2746
2984
  api(server, { getRenderer });
2747
2985
  server.use("/cms", async (req, res) => {
2748
2986
  try {
@@ -2762,13 +3000,19 @@ function cmsPlugin(options) {
2762
3000
  });
2763
3001
  }
2764
3002
  };
2765
- if (options.watch !== false) {
3003
+ if (process.env.NODE_ENV === "development" && options.watch !== false) {
2766
3004
  plugin.onFileChange = (eventName, filepath) => {
2767
3005
  if (filepath.endsWith(".schema.ts")) {
2768
3006
  Promise.resolve().then(() => (init_generate_types(), generate_types_exports)).then((generateTypesModule) => {
2769
3007
  const generateTypes2 = generateTypesModule.generateTypes;
2770
3008
  generateTypes2();
2771
3009
  });
3010
+ if (sseBroadcast) {
3011
+ const eventData = {
3012
+ file: path5.basename(filepath)
3013
+ };
3014
+ sseBroadcast(SSEEvent.SCHEMA_CHANGED, eventData);
3015
+ }
2772
3016
  }
2773
3017
  };
2774
3018
  }