@eventcatalog/core 3.13.0-beta.2 → 3.14.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.
Files changed (50) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +1 -1
  4. package/dist/analytics/log-build.js +3 -3
  5. package/dist/catalog-to-astro-content-directory.cjs +1 -1
  6. package/dist/{chunk-XIZQ27W3.js → chunk-2OZIUQR5.js} +1 -1
  7. package/dist/{chunk-PBMJ6OIP.js → chunk-BWF7CUGM.js} +1 -1
  8. package/dist/{chunk-QCHSOWJP.js → chunk-KZCWZ5PZ.js} +1 -1
  9. package/dist/{chunk-VQJRAI3N.js → chunk-Q23QNBZG.js} +1 -1
  10. package/dist/{chunk-GC6XBLGZ.js → chunk-SJ5OPJEM.js} +1 -1
  11. package/dist/constants.cjs +1 -1
  12. package/dist/constants.js +1 -1
  13. package/dist/eventcatalog.cjs +66 -4
  14. package/dist/eventcatalog.config.d.cts +2 -1
  15. package/dist/eventcatalog.config.d.ts +2 -1
  16. package/dist/eventcatalog.js +70 -7
  17. package/dist/generate.cjs +1 -1
  18. package/dist/generate.js +3 -3
  19. package/dist/utils/cli-logger.cjs +1 -1
  20. package/dist/utils/cli-logger.js +2 -2
  21. package/eventcatalog/integrations/eventcatalog-features.ts +9 -0
  22. package/eventcatalog/src/components/Header.astro +5 -5
  23. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +14 -11
  24. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraphPortal.tsx +1 -1
  25. package/eventcatalog/src/components/MDX/RemoteFile.astro +5 -16
  26. package/eventcatalog/src/components/Search/Search.astro +1 -1
  27. package/eventcatalog/src/components/Search/SearchDataLoader.astro +25 -13
  28. package/eventcatalog/src/components/Search/SearchModal.tsx +101 -39
  29. package/eventcatalog/src/components/ThemeToggle.tsx +11 -3
  30. package/eventcatalog/src/content.config.ts +12 -11
  31. package/eventcatalog/src/enterprise/api/catalog.ts +22 -0
  32. package/eventcatalog/src/pages/api/search-index.json.ts +46 -0
  33. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +51 -5
  34. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_OpenAPI.tsx +26 -21
  35. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +4 -4
  36. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +7 -2
  37. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +7 -2
  38. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +5 -0
  39. package/eventcatalog/src/pages/visualiser/context-map/index.astro +2 -2
  40. package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +4 -4
  41. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +6 -2
  42. package/eventcatalog/src/pages/visualiser/domain-integrations/index.astro +2 -2
  43. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +7 -2
  44. package/eventcatalog/src/utils/collections/util.ts +2 -0
  45. package/eventcatalog/src/utils/eventcatalog-config/catalog.ts +3 -18
  46. package/eventcatalog/src/utils/feature.ts +2 -0
  47. package/eventcatalog/src/utils/remote-file.ts +15 -0
  48. package/eventcatalog/src/utils/remote-spec.ts +45 -0
  49. package/package.json +4 -4
  50. package/eventcatalog/src/pages/api/catalog.ts +0 -34
@@ -37,7 +37,7 @@ var import_axios = __toESM(require("axios"), 1);
37
37
  var import_os = __toESM(require("os"), 1);
38
38
 
39
39
  // package.json
40
- var version = "3.13.0-beta.2";
40
+ var version = "3.14.0";
41
41
 
42
42
  // src/constants.ts
43
43
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "../chunk-GC6XBLGZ.js";
4
- import "../chunk-XIZQ27W3.js";
3
+ } from "../chunk-SJ5OPJEM.js";
4
+ import "../chunk-2OZIUQR5.js";
5
5
  export {
6
6
  raiseEvent
7
7
  };
@@ -106,7 +106,7 @@ var import_axios = __toESM(require("axios"), 1);
106
106
  var import_os = __toESM(require("os"), 1);
107
107
 
108
108
  // package.json
109
- var version = "3.13.0-beta.2";
109
+ var version = "3.14.0";
110
110
 
111
111
  // src/constants.ts
112
112
  var VERSION = version;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  log_build_default
3
- } from "../chunk-QCHSOWJP.js";
4
- import "../chunk-GC6XBLGZ.js";
3
+ } from "../chunk-KZCWZ5PZ.js";
4
+ import "../chunk-SJ5OPJEM.js";
5
5
  import "../chunk-4UVFXLPI.js";
6
- import "../chunk-XIZQ27W3.js";
6
+ import "../chunk-2OZIUQR5.js";
7
7
  import "../chunk-UPONRQSN.js";
8
8
  export {
9
9
  log_build_default as default
@@ -34,7 +34,7 @@ __export(catalog_to_astro_content_directory_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(catalog_to_astro_content_directory_exports);
36
36
 
37
- // ../../node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
37
+ // ../../node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
38
38
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
39
39
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
40
40
 
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "3.13.0-beta.2";
2
+ var version = "3.14.0";
3
3
 
4
4
  // src/constants.ts
5
5
  var VERSION = version;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  logger
3
- } from "./chunk-VQJRAI3N.js";
3
+ } from "./chunk-Q23QNBZG.js";
4
4
  import {
5
5
  cleanup,
6
6
  getEventCatalogConfigFile
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  raiseEvent
3
- } from "./chunk-GC6XBLGZ.js";
3
+ } from "./chunk-SJ5OPJEM.js";
4
4
  import {
5
5
  countResources,
6
6
  serializeCounts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-XIZQ27W3.js";
3
+ } from "./chunk-2OZIUQR5.js";
4
4
 
5
5
  // src/utils/cli-logger.ts
6
6
  import pc from "picocolors";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-XIZQ27W3.js";
3
+ } from "./chunk-2OZIUQR5.js";
4
4
 
5
5
  // src/analytics/analytics.js
6
6
  import axios from "axios";
@@ -25,7 +25,7 @@ __export(constants_exports, {
25
25
  module.exports = __toCommonJS(constants_exports);
26
26
 
27
27
  // package.json
28
- var version = "3.13.0-beta.2";
28
+ var version = "3.14.0";
29
29
 
30
30
  // src/constants.ts
31
31
  var VERSION = version;
package/dist/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  VERSION
3
- } from "./chunk-XIZQ27W3.js";
3
+ } from "./chunk-2OZIUQR5.js";
4
4
  export {
5
5
  VERSION
6
6
  };
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
 
25
- // ../../node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
25
+ // ../../node_modules/.pnpm/tsup@8.5.0_jiti@1.21.7_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/cjs_shims.js
26
26
  var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
27
27
  var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
28
28
 
@@ -30,6 +30,7 @@ var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
30
30
  var import_commander = require("commander");
31
31
  var import_node_child_process = require("child_process");
32
32
  var import_node_path7 = require("path");
33
+ var import_node_http = __toESM(require("http"), 1);
33
34
  var import_fs2 = __toESM(require("fs"), 1);
34
35
  var import_node_path8 = __toESM(require("path"), 1);
35
36
  var import_node_url = require("url");
@@ -109,7 +110,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
109
110
  var import_picocolors = __toESM(require("picocolors"), 1);
110
111
 
111
112
  // package.json
112
- var version = "3.13.0-beta.2";
113
+ var version = "3.14.0";
113
114
 
114
115
  // src/constants.ts
115
116
  var VERSION = version;
@@ -710,6 +711,56 @@ var ensureDir = (dir2) => {
710
711
  import_fs2.default.mkdirSync(dir2);
711
712
  }
712
713
  };
714
+ var resolveDevPort = async ({ projectDir }) => {
715
+ try {
716
+ const config = await getEventCatalogConfigFile(projectDir);
717
+ const fromConfig = Number(config?.port);
718
+ if (Number.isFinite(fromConfig) && fromConfig > 0) return fromConfig;
719
+ } catch (error) {
720
+ }
721
+ return 3e3;
722
+ };
723
+ var startDevPrewarm = ({
724
+ port = 3e3,
725
+ paths = ["/ping", "/"],
726
+ retries = 80,
727
+ intervalMs = 250,
728
+ initialDelayMs = 500
729
+ }) => {
730
+ let attempt = 0;
731
+ const hit = (requestPath) => new Promise((resolve2) => {
732
+ const req = import_node_http.default.get(
733
+ {
734
+ hostname: "127.0.0.1",
735
+ port,
736
+ path: requestPath,
737
+ timeout: 1200
738
+ },
739
+ (res) => {
740
+ res.resume();
741
+ resolve2(true);
742
+ }
743
+ );
744
+ req.on("error", () => resolve2(false));
745
+ req.on("timeout", () => {
746
+ req.destroy();
747
+ resolve2(false);
748
+ });
749
+ });
750
+ const tick = async () => {
751
+ attempt += 1;
752
+ for (const requestPath of paths) {
753
+ const ok = await hit(requestPath);
754
+ if (ok) {
755
+ return;
756
+ }
757
+ }
758
+ if (attempt < retries) {
759
+ setTimeout(tick, intervalMs);
760
+ }
761
+ };
762
+ setTimeout(tick, initialDelayMs);
763
+ };
713
764
  var copyCore = () => {
714
765
  ensureDir(core);
715
766
  if (eventCatalogDir === core) {
@@ -772,7 +823,7 @@ Run npm i @eventcatalog/core to update`;
772
823
  );
773
824
  }
774
825
  };
775
- program.command("dev").description("Run development server of EventCatalog").option("-d, --debug", "Output EventCatalog application information into your terminal").option("--force-recreate", "Recreate the eventcatalog-core directory", false).action(async (options, command) => {
826
+ program.command("dev").description("Run development server of EventCatalog").option("-d, --debug", "Output EventCatalog application information into your terminal").option("--force-recreate", "Recreate the eventcatalog-core directory", false).option("--no-prewarm", "Disable automatic dev prewarm request").action(async (options, command) => {
776
827
  logger.welcome();
777
828
  logger.info("Setting up EventCatalog...", "eventcatalog");
778
829
  const isServer = await isOutputServer();
@@ -801,11 +852,22 @@ program.command("dev").description("Run development server of EventCatalog").opt
801
852
  let watchUnsub;
802
853
  try {
803
854
  watchUnsub = await watch(dir, core);
855
+ const args = command.args.join(" ").trim();
856
+ if (options.prewarm) {
857
+ const prewarmPort = await resolveDevPort({
858
+ projectDir: dir
859
+ });
860
+ startDevPrewarm({
861
+ port: prewarmPort,
862
+ paths: ["/ping", "/"]
863
+ });
864
+ }
865
+ const astroCommand = process.platform === "win32" ? `npx astro dev ${args} 2>&1 | findstr /V /C:"[glob-loader]" /C:"The collection" /C:"[router]"` : `npx astro dev ${args} 2>&1 | grep -v -e "\\[glob-loader\\]" -e "The collection.*does not exist" -e "\\[router\\]"`;
804
866
  const { result } = (0, import_concurrently.default)(
805
867
  [
806
868
  {
807
869
  name: "astro",
808
- command: process.platform === "win32" ? `npx astro dev ${command.args.join(" ").trim()} 2>&1 | findstr /V /C:"[glob-loader]" /C:"The collection" /C:"[router]"` : `npx astro dev ${command.args.join(" ").trim()} 2>&1 | grep -v -e "\\[glob-loader\\]" -e "The collection.*does not exist" -e "\\[router\\]"`,
870
+ command: astroCommand,
809
871
  cwd: core,
810
872
  env: {
811
873
  PROJECT_DIR: dir,
@@ -82,6 +82,7 @@ interface Config {
82
82
  };
83
83
  asyncAPI?: {
84
84
  renderParsedSchemas?: boolean;
85
+ allowAnyEnvInSpecHeaders?: boolean;
85
86
  };
86
87
  mdxOptimize?: boolean;
87
88
  compress?: boolean;
@@ -124,7 +125,7 @@ interface Config {
124
125
  /**
125
126
  * Enable or disable the /api/catalog endpoint that dumps the entire catalog as JSON.
126
127
  * Disabling this can significantly reduce memory usage during builds for large catalogs (1000+ files).
127
- * @default true
128
+ * @default false
128
129
  */
129
130
  fullCatalogAPIEnabled?: boolean;
130
131
  };
@@ -82,6 +82,7 @@ interface Config {
82
82
  };
83
83
  asyncAPI?: {
84
84
  renderParsedSchemas?: boolean;
85
+ allowAnyEnvInSpecHeaders?: boolean;
85
86
  };
86
87
  mdxOptimize?: boolean;
87
88
  compress?: boolean;
@@ -124,7 +125,7 @@ interface Config {
124
125
  /**
125
126
  * Enable or disable the /api/catalog endpoint that dumps the entire catalog as JSON.
126
127
  * Disabling this can significantly reduce memory usage during builds for large catalogs (1000+ files).
127
- * @default true
128
+ * @default false
128
129
  */
129
130
  fullCatalogAPIEnabled?: boolean;
130
131
  };
@@ -6,8 +6,8 @@ import {
6
6
  } from "./chunk-PLNJC7NZ.js";
7
7
  import {
8
8
  log_build_default
9
- } from "./chunk-QCHSOWJP.js";
10
- import "./chunk-GC6XBLGZ.js";
9
+ } from "./chunk-KZCWZ5PZ.js";
10
+ import "./chunk-SJ5OPJEM.js";
11
11
  import "./chunk-4UVFXLPI.js";
12
12
  import {
13
13
  runMigrations
@@ -22,14 +22,15 @@ import {
22
22
  } from "./chunk-5VBIXL6C.js";
23
23
  import {
24
24
  generate
25
- } from "./chunk-PBMJ6OIP.js";
25
+ } from "./chunk-BWF7CUGM.js";
26
26
  import {
27
27
  logger
28
- } from "./chunk-VQJRAI3N.js";
28
+ } from "./chunk-Q23QNBZG.js";
29
29
  import {
30
30
  VERSION
31
- } from "./chunk-XIZQ27W3.js";
31
+ } from "./chunk-2OZIUQR5.js";
32
32
  import {
33
+ getEventCatalogConfigFile,
33
34
  verifyRequiredFieldsAreInCatalogConfigFile
34
35
  } from "./chunk-UPONRQSN.js";
35
36
 
@@ -37,6 +38,7 @@ import {
37
38
  import { Command } from "commander";
38
39
  import { execSync } from "child_process";
39
40
  import { join } from "path";
41
+ import http from "http";
40
42
  import fs from "fs";
41
43
  import path from "path";
42
44
  import { fileURLToPath } from "url";
@@ -65,6 +67,56 @@ var ensureDir = (dir2) => {
65
67
  fs.mkdirSync(dir2);
66
68
  }
67
69
  };
70
+ var resolveDevPort = async ({ projectDir }) => {
71
+ try {
72
+ const config = await getEventCatalogConfigFile(projectDir);
73
+ const fromConfig = Number(config?.port);
74
+ if (Number.isFinite(fromConfig) && fromConfig > 0) return fromConfig;
75
+ } catch (error) {
76
+ }
77
+ return 3e3;
78
+ };
79
+ var startDevPrewarm = ({
80
+ port = 3e3,
81
+ paths = ["/ping", "/"],
82
+ retries = 80,
83
+ intervalMs = 250,
84
+ initialDelayMs = 500
85
+ }) => {
86
+ let attempt = 0;
87
+ const hit = (requestPath) => new Promise((resolve) => {
88
+ const req = http.get(
89
+ {
90
+ hostname: "127.0.0.1",
91
+ port,
92
+ path: requestPath,
93
+ timeout: 1200
94
+ },
95
+ (res) => {
96
+ res.resume();
97
+ resolve(true);
98
+ }
99
+ );
100
+ req.on("error", () => resolve(false));
101
+ req.on("timeout", () => {
102
+ req.destroy();
103
+ resolve(false);
104
+ });
105
+ });
106
+ const tick = async () => {
107
+ attempt += 1;
108
+ for (const requestPath of paths) {
109
+ const ok = await hit(requestPath);
110
+ if (ok) {
111
+ return;
112
+ }
113
+ }
114
+ if (attempt < retries) {
115
+ setTimeout(tick, intervalMs);
116
+ }
117
+ };
118
+ setTimeout(tick, initialDelayMs);
119
+ };
68
120
  var copyCore = () => {
69
121
  ensureDir(core);
70
122
  if (eventCatalogDir === core) {
@@ -127,7 +179,7 @@ Run npm i @eventcatalog/core to update`;
127
179
  );
128
180
  }
129
181
  };
130
- program.command("dev").description("Run development server of EventCatalog").option("-d, --debug", "Output EventCatalog application information into your terminal").option("--force-recreate", "Recreate the eventcatalog-core directory", false).action(async (options, command) => {
182
+ program.command("dev").description("Run development server of EventCatalog").option("-d, --debug", "Output EventCatalog application information into your terminal").option("--force-recreate", "Recreate the eventcatalog-core directory", false).option("--no-prewarm", "Disable automatic dev prewarm request").action(async (options, command) => {
131
183
  logger.welcome();
132
184
  logger.info("Setting up EventCatalog...", "eventcatalog");
133
185
  const isServer = await isOutputServer();
@@ -156,11 +208,22 @@ program.command("dev").description("Run development server of EventCatalog").opt
156
208
  let watchUnsub;
157
209
  try {
158
210
  watchUnsub = await watch(dir, core);
211
+ const args = command.args.join(" ").trim();
212
+ if (options.prewarm) {
213
+ const prewarmPort = await resolveDevPort({
214
+ projectDir: dir
215
+ });
216
+ startDevPrewarm({
217
+ port: prewarmPort,
218
+ paths: ["/ping", "/"]
219
+ });
220
+ }
221
+ const astroCommand = process.platform === "win32" ? `npx astro dev ${args} 2>&1 | findstr /V /C:"[glob-loader]" /C:"The collection" /C:"[router]"` : `npx astro dev ${args} 2>&1 | grep -v -e "\\[glob-loader\\]" -e "The collection.*does not exist" -e "\\[router\\]"`;
159
222
  const { result } = concurrently(
160
223
  [
161
224
  {
162
225
  name: "astro",
163
- command: process.platform === "win32" ? `npx astro dev ${command.args.join(" ").trim()} 2>&1 | findstr /V /C:"[glob-loader]" /C:"The collection" /C:"[router]"` : `npx astro dev ${command.args.join(" ").trim()} 2>&1 | grep -v -e "\\[glob-loader\\]" -e "The collection.*does not exist" -e "\\[router\\]"`,
226
+ command: astroCommand,
164
227
  cwd: core,
165
228
  env: {
166
229
  PROJECT_DIR: dir,
package/dist/generate.cjs CHANGED
@@ -73,7 +73,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
73
73
  var import_picocolors = __toESM(require("picocolors"), 1);
74
74
 
75
75
  // package.json
76
- var version = "3.13.0-beta.2";
76
+ var version = "3.14.0";
77
77
 
78
78
  // src/constants.ts
79
79
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-PBMJ6OIP.js";
4
- import "./chunk-VQJRAI3N.js";
5
- import "./chunk-XIZQ27W3.js";
3
+ } from "./chunk-BWF7CUGM.js";
4
+ import "./chunk-Q23QNBZG.js";
5
+ import "./chunk-2OZIUQR5.js";
6
6
  import "./chunk-UPONRQSN.js";
7
7
  export {
8
8
  generate
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.13.0-beta.2";
39
+ var version = "3.14.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-VQJRAI3N.js";
4
- import "../chunk-XIZQ27W3.js";
3
+ } from "../chunk-Q23QNBZG.js";
4
+ import "../chunk-2OZIUQR5.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -6,6 +6,7 @@ import {
6
6
  isEventCatalogScaleEnabled,
7
7
  isEventCatalogStarterEnabled,
8
8
  isEventCatalogMCPEnabled,
9
+ isFullCatalogAPIEnabled,
9
10
  isDevMode,
10
11
  } from '../src/utils/feature';
11
12
 
@@ -74,6 +75,14 @@ export default function eventCatalogIntegration(): AstroIntegration {
74
75
  });
75
76
  }
76
77
 
78
+ // Full catalog API route (opt-in)
79
+ if (isFullCatalogAPIEnabled()) {
80
+ params.injectRoute({
81
+ pattern: '/api/catalog',
82
+ entrypoint: path.join(catalogDirectory, 'src/enterprise/api/catalog.ts'),
83
+ });
84
+ }
85
+
77
86
  // Dev-only routes for visualizer layout persistence
78
87
  if (isDevMode()) {
79
88
  params.injectRoute({
@@ -48,7 +48,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
48
48
  <div class="flex-grow max-w-xl">
49
49
  <Search />
50
50
  </div>
51
- {isEventCatalogChatEnabled() && <ChatPanelButton client:load />}
51
+ {isEventCatalogChatEnabled() && <ChatPanelButton client:idle />}
52
52
  </div>
53
53
 
54
54
  <div class="hidden md:block w-3/12">
@@ -56,9 +56,9 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
56
56
  session ? (
57
57
  <div class="flex items-center space-x-4 justify-end pr-2">
58
58
  {catalog.environments && catalog.environments.length > 0 && (
59
- <EnvironmentDropdown environments={catalog.environments} client:load />
59
+ <EnvironmentDropdown environments={catalog.environments} client:idle />
60
60
  )}
61
- <ThemeToggle client:load />
61
+ <ThemeToggle client:idle />
62
62
  <div class="relative">
63
63
  <button
64
64
  id="profile-menu-button"
@@ -110,7 +110,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
110
110
  <>
111
111
  <div class="flex items-center space-x-4 justify-end pr-2">
112
112
  {catalog.environments && catalog.environments.length > 0 && (
113
- <EnvironmentDropdown environments={catalog.environments} client:load />
113
+ <EnvironmentDropdown environments={catalog.environments} client:idle />
114
114
  )}
115
115
  {isAuthEnabled() && (
116
116
  <button
@@ -120,7 +120,7 @@ const repositoryUrl = catalog?.repositoryUrl || 'https://github.com/event-catalo
120
120
  Sign In
121
121
  </button>
122
122
  )}
123
- <ThemeToggle client:load />
123
+ <ThemeToggle client:idle />
124
124
  {showEventCatalogBranding() && (
125
125
  <ul class="flex space-x-4">
126
126
  <li>
@@ -8,11 +8,12 @@
8
8
  * - URL building with Astro's URL utilities
9
9
  */
10
10
 
11
- import { useCallback } from 'react';
12
- import { NodeGraph } from '@eventcatalog/visualiser';
11
+ import { useCallback, lazy, Suspense } from 'react';
13
12
  import '@eventcatalog/visualiser/styles.css';
14
13
  import type { Node, Edge } from '@xyflow/react';
15
14
 
15
+ const NodeGraph = lazy(() => import('@eventcatalog/visualiser').then((module) => ({ default: module.NodeGraph })));
16
+
16
17
  interface AstroNodeGraphProps {
17
18
  id: string;
18
19
  nodes: Node[];
@@ -89,15 +90,17 @@ const AstroNodeGraph = ({ isDevMode = false, resourceKey, ...otherProps }: Astro
89
90
  }, []);
90
91
 
91
92
  return (
92
- <NodeGraph
93
- {...otherProps}
94
- resourceKey={resourceKey}
95
- isDevMode={isDevMode}
96
- onNavigate={handleNavigate}
97
- onBuildUrl={handleBuildUrl}
98
- onSaveLayout={handleSaveLayout}
99
- onResetLayout={handleResetLayout}
100
- />
93
+ <Suspense fallback={<div>Loading graph...</div>}>
94
+ <NodeGraph
95
+ {...otherProps}
96
+ resourceKey={resourceKey}
97
+ isDevMode={isDevMode}
98
+ onNavigate={handleNavigate}
99
+ onBuildUrl={handleBuildUrl}
100
+ onSaveLayout={handleSaveLayout}
101
+ onResetLayout={handleResetLayout}
102
+ />
103
+ </Suspense>
101
104
  );
102
105
  };
103
106
 
@@ -1,7 +1,7 @@
1
1
  const NodeGraphPortal = (props: any) => {
2
2
  return (
3
3
  <div
4
- className="h-[30em] my-6 mb-12 w-full relative border border-gray-200 rounded-md"
4
+ className="h-[30em] my-6 mb-12 w-full relative border border-[rgb(var(--ec-page-border))] rounded-md"
5
5
  id={`${props.id}-portal`}
6
6
  style={{
7
7
  maxHeight: props.maxHeight ? `${props.maxHeight}em` : `30em`,
@@ -3,6 +3,7 @@ import jsonpath from 'jsonpath';
3
3
  import JSONSchemaViewer from '@components/SchemaExplorer/JSONSchemaViewer';
4
4
  import { Code } from 'astro-expressive-code/components';
5
5
  import { isPrivateRemoteSchemaEnabled } from '@utils/feature';
6
+ import { resolveTemplateVariables } from '@utils/remote-file';
6
7
 
7
8
  const {
8
9
  url,
@@ -14,18 +15,6 @@ const {
14
15
  ...props
15
16
  } = Astro.props;
16
17
 
17
- function resolveTemplates(input: any): any {
18
- if (typeof input === 'string') {
19
- return input.replace(/\$\{(\w+)\}/g, (_, varName) => import.meta.env[varName] || '');
20
- }
21
-
22
- if (typeof input === 'object' && input !== null) {
23
- return Object.fromEntries(Object.entries(input).map(([k, v]) => [k, resolveTemplates(v)]));
24
- }
25
-
26
- return input;
27
- }
28
-
29
18
  function isValidJSON(str: string): boolean {
30
19
  try {
31
20
  JSON.parse(str);
@@ -69,8 +58,8 @@ function extractWithJSONPath(data: any, path: string): any {
69
58
  }
70
59
  }
71
60
 
72
- const resolvedUrl = resolveTemplates(url);
73
- const resolvedHeaders = isPrivateRemoteSchemaEnabled() ? resolveTemplates(headers) : {};
61
+ const resolvedUrl = resolveTemplateVariables(url);
62
+ const resolvedHeaders = isPrivateRemoteSchemaEnabled() ? resolveTemplateVariables(headers) : {};
74
63
 
75
64
  let content = '';
76
65
  let processedData: any = null;
@@ -86,8 +75,8 @@ if (Object.keys(headers).length > 0 && !isPrivateRemoteSchemaEnabled()) {
86
75
  }
87
76
 
88
77
  try {
89
- const response = await fetch(resolvedUrl, {
90
- headers: resolvedHeaders,
78
+ const response = await fetch(String(resolvedUrl), {
79
+ headers: resolvedHeaders as HeadersInit,
91
80
  });
92
81
 
93
82
  if (!response.ok) {
@@ -20,7 +20,7 @@ import SearchModal from './SearchModal.tsx';
20
20
  </div>
21
21
  </div>
22
22
 
23
- <SearchModal client:only="react" />
23
+ <SearchModal client:idle />
24
24
 
25
25
  <script>
26
26
  // Create a global state for the search modal
@@ -20,18 +20,30 @@
20
20
  if (!sidebarStore.get()) {
21
21
  const apiUrl = buildUrl('/api/sidebar-data.json', true);
22
22
 
23
- fetch(apiUrl)
24
- .then((response) => {
25
- if (!response.ok) {
26
- throw new Error(`Failed to fetch sidebar data: ${response.status}`);
27
- }
28
- return response.json();
29
- })
30
- .then((data) => {
31
- setSidebarData(data);
32
- })
33
- .catch((error) => {
34
- console.error('Error loading sidebar data:', error);
35
- });
23
+ const loadSidebarData = () => {
24
+ // Double-check cache in case another component loaded data while waiting for idle
25
+ if (sidebarStore.get()) return;
26
+
27
+ fetch(apiUrl)
28
+ .then((response) => {
29
+ if (!response.ok) {
30
+ throw new Error(`Failed to fetch sidebar data: ${response.status}`);
31
+ }
32
+ return response.json();
33
+ })
34
+ .then((data) => {
35
+ setSidebarData(data);
36
+ })
37
+ .catch((error) => {
38
+ console.error('Error loading sidebar data:', error);
39
+ });
40
+ };
41
+
42
+ // Defer non-critical sidebar payload fetch until browser is idle
43
+ if (typeof window.requestIdleCallback === 'function') {
44
+ window.requestIdleCallback(loadSidebarData, { timeout: 1200 });
45
+ } else {
46
+ setTimeout(loadSidebarData, 300);
47
+ }
36
48
  }
37
49
  </script>