@eventcatalog/core 5.0.0-beta.12 → 5.0.0-beta.14
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/LICENSE +13 -12
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/catalog-runtime.cjs +1 -1
- package/dist/{chunk-TSY5CC27.js → chunk-4KE3EUDJ.js} +1 -1
- package/dist/{chunk-FY6MSP6J.js → chunk-I3XDOICA.js} +1 -1
- package/dist/{chunk-QB7X34OD.js → chunk-OFK7U7BX.js} +1 -1
- package/dist/{chunk-CX2VB7AI.js → chunk-PI5YNZZZ.js} +1 -1
- package/dist/{chunk-BWC4YKW3.js → chunk-WY6M3RPT.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +11 -6
- package/dist/eventcatalog.js +14 -9
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +3 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/astro.config.mjs +13 -1
- package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
- package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
- package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +11 -3
- package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
- package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +133 -71
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +66 -66
- package/eventcatalog/src/features/studio/agent-choreography.ts +5 -4
- package/eventcatalog/src/features/studio/agents.ts +28 -0
- package/eventcatalog/src/features/studio/api/canvases-api.ts +1 -1
- package/eventcatalog/src/features/studio/canvas-actions.ts +22 -14
- package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
- package/eventcatalog/src/features/studio/catalog.ts +1 -4
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +246 -115
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +7 -3
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
- package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +1 -1
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +102 -241
- package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
- package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +1 -1
- package/eventcatalog/src/features/studio/components/Presence.tsx +6 -8
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
- package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1005 -354
- package/eventcatalog/src/features/studio/document-name.ts +7 -0
- package/eventcatalog/src/features/studio/from-visualiser.ts +1 -1
- package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +162 -23
- package/eventcatalog/src/features/studio/identity.ts +23 -1
- package/eventcatalog/src/features/studio/pages/[id].astro +2 -1
- package/eventcatalog/src/features/studio/pages/index.astro +1 -2
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +7 -22
- package/eventcatalog/src/features/studio/server/runtime.ts +4 -5
- package/package.json +3 -3
- package/eventcatalog/src/features/studio/canvas-doc.ts +0 -569
- package/eventcatalog/src/features/studio/clipboard.ts +0 -97
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -119
- package/eventcatalog/src/features/studio/components/Comments.tsx +0 -777
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
- package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -271
- package/eventcatalog/src/features/studio/components/icons.ts +0 -53
- package/eventcatalog/src/features/studio/components/status.ts +0 -53
- package/eventcatalog/src/features/studio/edges.ts +0 -56
- package/eventcatalog/src/features/studio/flow-state.ts +0 -121
- package/eventcatalog/src/features/studio/grouping.ts +0 -230
- package/eventcatalog/src/features/studio/hooks/use-counter-scale.ts +0 -20
- package/eventcatalog/src/features/studio/layout.ts +0 -56
- package/eventcatalog/src/features/studio/level-layout.ts +0 -145
- package/eventcatalog/src/features/studio/levels.ts +0 -337
- package/eventcatalog/src/features/studio/node-types.ts +0 -245
- package/eventcatalog/src/features/studio/placement.ts +0 -197
- package/eventcatalog/src/features/studio/studio.css +0 -273
package/LICENSE
CHANGED
|
@@ -17,13 +17,13 @@ Licensed Work: EventCatalog version 5.0 or later, including pre-releases,
|
|
|
17
17
|
and the examples directory. The Licensed Work is (c) 2026
|
|
18
18
|
EventCatalog Ltd.
|
|
19
19
|
Additional Use Grant: You may make Production use of the Licensed Work if You
|
|
20
|
-
|
|
20
|
+
qualify for Free Use and Your use is not a Hosted
|
|
21
21
|
Offering. Sections 1 to 7 below form part of this grant.
|
|
22
22
|
Capitalised terms are defined in section 6.
|
|
23
23
|
|
|
24
|
-
1.
|
|
24
|
+
1. Free Use
|
|
25
25
|
|
|
26
|
-
You
|
|
26
|
+
You qualify for "Free Use" if You are:
|
|
27
27
|
|
|
28
28
|
(a) an individual using the Licensed Work for Your own
|
|
29
29
|
personal purposes, and not for or on behalf of any
|
|
@@ -47,9 +47,9 @@ Additional Use Grant: You may make Production use of the Licensed Work if You
|
|
|
47
47
|
|
|
48
48
|
2. Growing past the thresholds
|
|
49
49
|
|
|
50
|
-
An Organisation that
|
|
51
|
-
|
|
52
|
-
following to happen:
|
|
50
|
+
An Organisation that qualifies for Free Use under 1(b)
|
|
51
|
+
continues to qualify until ninety (90) days after the
|
|
52
|
+
first of the following to happen:
|
|
53
53
|
|
|
54
54
|
(a) the end of the first financial year in which its
|
|
55
55
|
Annual Revenue reaches USD 10,000,000; or
|
|
@@ -68,7 +68,7 @@ Additional Use Grant: You may make Production use of the Licensed Work if You
|
|
|
68
68
|
vendor), including building, customising, hosting or
|
|
69
69
|
distributing the Licensed Work or a catalog built with it
|
|
70
70
|
for that client, Your use for that client is permitted if
|
|
71
|
-
the client
|
|
71
|
+
the client qualifies for Free Use or holds a Commercial
|
|
72
72
|
License covering that use. You may rely on a client's
|
|
73
73
|
written statement of its status unless You know it is
|
|
74
74
|
wrong. Your own use of the Licensed Work for Your own
|
|
@@ -76,7 +76,7 @@ Additional Use Grant: You may make Production use of the Licensed Work if You
|
|
|
76
76
|
|
|
77
77
|
4. Coming into compliance
|
|
78
78
|
|
|
79
|
-
(a) If You stop
|
|
79
|
+
(a) If You stop qualifying for Free Use (for example
|
|
80
80
|
because Your Evaluation Period ends), or You become
|
|
81
81
|
aware (including by notice from the Licensor) that
|
|
82
82
|
Your Production use is not permitted by this grant,
|
|
@@ -219,7 +219,8 @@ Additional Use Grant: You may make Production use of the Licensed Work if You
|
|
|
219
219
|
Public Open Source Projects.
|
|
220
220
|
|
|
221
221
|
"Commercial License" means a written license from the
|
|
222
|
-
Licensor
|
|
222
|
+
Licensor, including one accepted online, permitting
|
|
223
|
+
Production use beyond this grant.
|
|
223
224
|
|
|
224
225
|
7. Everything else
|
|
225
226
|
|
|
@@ -230,9 +231,9 @@ Additional Use Grant: You may make Production use of the Licensed Work if You
|
|
|
230
231
|
Work. The content of Your own catalog (the documentation,
|
|
231
232
|
schemas, diagrams and configuration You create) is Yours
|
|
232
233
|
and is not part of the Licensed Work.
|
|
233
|
-
Change Date: Four years after the first public release
|
|
234
|
-
pre-release
|
|
235
|
-
|
|
234
|
+
Change Date: Four years after the first public release (including any
|
|
235
|
+
pre-release) in the same release series as the Licensed
|
|
236
|
+
Work.
|
|
236
237
|
|
|
237
238
|
A "release series" is every release that shares the same
|
|
238
239
|
major and minor release number, including its pre-releases
|
|
@@ -176,7 +176,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
176
176
|
var import_os = __toESM(require("os"), 1);
|
|
177
177
|
|
|
178
178
|
// package.json
|
|
179
|
-
var version = "5.0.0-beta.
|
|
179
|
+
var version = "5.0.0-beta.14";
|
|
180
180
|
|
|
181
181
|
// src/constants.ts
|
|
182
182
|
var VERSION = version;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log_build_default
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-WY6M3RPT.js";
|
|
4
4
|
import "../chunk-AWOO63ME.js";
|
|
5
5
|
import "../chunk-ZAZHAVKB.js";
|
|
6
|
-
import "../chunk-
|
|
6
|
+
import "../chunk-PI5YNZZZ.js";
|
|
7
7
|
import "../chunk-CPW6G62V.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-I3XDOICA.js";
|
|
9
9
|
import "../chunk-RFIXKATC.js";
|
|
10
10
|
export {
|
|
11
11
|
log_build_default as default
|
package/dist/catalog-runtime.cjs
CHANGED
|
@@ -36,7 +36,7 @@ __export(catalog_runtime_exports, {
|
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(catalog_runtime_exports);
|
|
38
38
|
|
|
39
|
-
// ../../node_modules/.pnpm/tsup@8.5.0_jiti@2.7.0_postcss@8.5.
|
|
39
|
+
// ../../node_modules/.pnpm/tsup@8.5.0_jiti@2.7.0_postcss@8.5.29_tsx@4.23.15_typescript@5.9.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js
|
|
40
40
|
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
|
|
41
41
|
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
42
42
|
|
package/dist/constants.cjs
CHANGED
package/dist/constants.js
CHANGED
package/dist/eventcatalog.cjs
CHANGED
|
@@ -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@2.7.0_postcss@8.5.
|
|
25
|
+
// ../../node_modules/.pnpm/tsup@8.5.0_jiti@2.7.0_postcss@8.5.29_tsx@4.23.15_typescript@5.9.3_yaml@2.9.0/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
|
|
|
@@ -181,7 +181,7 @@ var verifyRequiredFieldsAreInCatalogConfigFile = async (projectDirectory) => {
|
|
|
181
181
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
182
182
|
|
|
183
183
|
// package.json
|
|
184
|
-
var version = "5.0.0-beta.
|
|
184
|
+
var version = "5.0.0-beta.14";
|
|
185
185
|
|
|
186
186
|
// src/constants.ts
|
|
187
187
|
var VERSION = version;
|
|
@@ -2980,7 +2980,7 @@ var resolveDevPort = async ({ projectDir }) => {
|
|
|
2980
2980
|
};
|
|
2981
2981
|
var startDevPrewarm = ({
|
|
2982
2982
|
port = 3e3,
|
|
2983
|
-
paths = ["/
|
|
2983
|
+
paths = ["/"],
|
|
2984
2984
|
retries = 80,
|
|
2985
2985
|
intervalMs = 250,
|
|
2986
2986
|
initialDelayMs = 500
|
|
@@ -2989,10 +2989,13 @@ var startDevPrewarm = ({
|
|
|
2989
2989
|
const hit = (requestPath) => new Promise((resolve2) => {
|
|
2990
2990
|
const req = import_node_http.default.get(
|
|
2991
2991
|
{
|
|
2992
|
-
|
|
2992
|
+
// Not 127.0.0.1: the dev server can listen on IPv6 only ([::1]), which refused
|
|
2993
|
+
// every prewarm request
|
|
2994
|
+
hostname: "localhost",
|
|
2993
2995
|
port,
|
|
2994
2996
|
path: requestPath,
|
|
2995
|
-
|
|
2997
|
+
// A refused connection fails at once; once connected, let the first render finish
|
|
2998
|
+
timeout: 3e4
|
|
2996
2999
|
},
|
|
2997
3000
|
(res) => {
|
|
2998
3001
|
res.resume();
|
|
@@ -3251,7 +3254,9 @@ program.command("dev").description("Run development server of EventCatalog").opt
|
|
|
3251
3254
|
});
|
|
3252
3255
|
startDevPrewarm({
|
|
3253
3256
|
port: prewarmPort,
|
|
3254
|
-
|
|
3257
|
+
// Renders the homepage before anyone opens it. Requests stop at the first response,
|
|
3258
|
+
// so a probe path like /ping first would leave the homepage cold.
|
|
3259
|
+
paths: ["/"]
|
|
3255
3260
|
});
|
|
3256
3261
|
}
|
|
3257
3262
|
await runCommandWithFilteredOutput({
|
package/dist/eventcatalog.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import "./chunk-CA4U2JP7.js";
|
|
5
5
|
import {
|
|
6
6
|
log_build_default
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WY6M3RPT.js";
|
|
8
8
|
import {
|
|
9
9
|
getLicenseStatus,
|
|
10
10
|
printLicenseStatus
|
|
@@ -33,10 +33,10 @@ import {
|
|
|
33
33
|
} from "./chunk-MDWB5HLO.js";
|
|
34
34
|
import {
|
|
35
35
|
generate
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-4KE3EUDJ.js";
|
|
37
37
|
import {
|
|
38
38
|
logger
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-OFK7U7BX.js";
|
|
40
40
|
import {
|
|
41
41
|
resolve_catalog_dependencies_default
|
|
42
42
|
} from "./chunk-36RYTYT5.js";
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
import {
|
|
51
51
|
watch
|
|
52
52
|
} from "./chunk-U63GDPPY.js";
|
|
53
|
-
import "./chunk-
|
|
53
|
+
import "./chunk-PI5YNZZZ.js";
|
|
54
54
|
import "./chunk-CPW6G62V.js";
|
|
55
55
|
import {
|
|
56
56
|
getAstroConfigPath
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
} from "./chunk-LFQJXLHG.js";
|
|
68
68
|
import {
|
|
69
69
|
VERSION
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-I3XDOICA.js";
|
|
71
71
|
import {
|
|
72
72
|
getEventCatalogConfigFile,
|
|
73
73
|
verifyRequiredFieldsAreInCatalogConfigFile
|
|
@@ -669,7 +669,7 @@ var resolveDevPort = async ({ projectDir }) => {
|
|
|
669
669
|
};
|
|
670
670
|
var startDevPrewarm = ({
|
|
671
671
|
port = 3e3,
|
|
672
|
-
paths = ["/
|
|
672
|
+
paths = ["/"],
|
|
673
673
|
retries = 80,
|
|
674
674
|
intervalMs = 250,
|
|
675
675
|
initialDelayMs = 500
|
|
@@ -678,10 +678,13 @@ var startDevPrewarm = ({
|
|
|
678
678
|
const hit = (requestPath) => new Promise((resolve) => {
|
|
679
679
|
const req = http.get(
|
|
680
680
|
{
|
|
681
|
-
|
|
681
|
+
// Not 127.0.0.1: the dev server can listen on IPv6 only ([::1]), which refused
|
|
682
|
+
// every prewarm request
|
|
683
|
+
hostname: "localhost",
|
|
682
684
|
port,
|
|
683
685
|
path: requestPath,
|
|
684
|
-
|
|
686
|
+
// A refused connection fails at once; once connected, let the first render finish
|
|
687
|
+
timeout: 3e4
|
|
685
688
|
},
|
|
686
689
|
(res) => {
|
|
687
690
|
res.resume();
|
|
@@ -940,7 +943,9 @@ program.command("dev").description("Run development server of EventCatalog").opt
|
|
|
940
943
|
});
|
|
941
944
|
startDevPrewarm({
|
|
942
945
|
port: prewarmPort,
|
|
943
|
-
|
|
946
|
+
// Renders the homepage before anyone opens it. Requests stop at the first response,
|
|
947
|
+
// so a probe path like /ping first would leave the homepage cold.
|
|
948
|
+
paths: ["/"]
|
|
944
949
|
});
|
|
945
950
|
}
|
|
946
951
|
await runCommandWithFilteredOutput({
|
package/dist/generate.cjs
CHANGED
|
@@ -112,7 +112,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
|
|
|
112
112
|
var import_picocolors = __toESM(require("picocolors"), 1);
|
|
113
113
|
|
|
114
114
|
// package.json
|
|
115
|
-
var version = "5.0.0-beta.
|
|
115
|
+
var version = "5.0.0-beta.14";
|
|
116
116
|
|
|
117
117
|
// src/constants.ts
|
|
118
118
|
var VERSION = version;
|
package/dist/generate.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generate
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
5
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-4KE3EUDJ.js";
|
|
4
|
+
import "./chunk-OFK7U7BX.js";
|
|
5
|
+
import "./chunk-I3XDOICA.js";
|
|
6
6
|
import "./chunk-RFIXKATC.js";
|
|
7
7
|
export {
|
|
8
8
|
generate
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
"@eventcatalog/sdk": "@eventcatalog__sdk.mjs",
|
|
22
22
|
"@eventcatalog/visualiser": "@eventcatalog__visualiser.mjs",
|
|
23
23
|
"@eventcatalog/visualiser/layout": "@eventcatalog__visualiser__layout.mjs",
|
|
24
|
+
"@eventcatalog/visualiser/studio": "@eventcatalog__visualiser__studio.mjs",
|
|
25
|
+
"@eventcatalog/visualiser/studio-fonts.css": "@eventcatalog__visualiser__studio-fonts.css.mjs",
|
|
26
|
+
"@eventcatalog/visualiser/studio.css": "@eventcatalog__visualiser__studio.css.mjs",
|
|
24
27
|
"@eventcatalog/visualiser/styles-core.css": "@eventcatalog__visualiser__styles-core.css.mjs",
|
|
25
28
|
"@fontsource/inter": "@fontsource__inter.mjs",
|
|
26
29
|
"@fontsource/inter/400.css": "@fontsource__inter__400.css.mjs",
|
package/dist/utils/cli-logger.js
CHANGED
|
@@ -35,6 +35,8 @@ import config from './src/utils/eventcatalog-config/source.ts';
|
|
|
35
35
|
import preprocessExpressiveCodeConfig from './integrations/expressive-code-config.mjs';
|
|
36
36
|
import catalogAssets from './integrations/catalog-assets.mjs';
|
|
37
37
|
import runtimeDependencies from './integrations/runtime-dependencies.mjs';
|
|
38
|
+
import stableDependencyOrder from './integrations/stable-dependency-order.mjs';
|
|
39
|
+
import skipStartupReload from './integrations/skip-startup-reload.mjs';
|
|
38
40
|
import { getRuntimePaths } from './integrations/runtime-paths.mjs';
|
|
39
41
|
import { collectClientDependencies } from './integrations/client-dependencies.mjs';
|
|
40
42
|
|
|
@@ -166,6 +168,8 @@ export default defineConfig({
|
|
|
166
168
|
},
|
|
167
169
|
plugins: [
|
|
168
170
|
runtimeDependencies(),
|
|
171
|
+
stableDependencyOrder(),
|
|
172
|
+
skipStartupReload(),
|
|
169
173
|
tailwindcss(),
|
|
170
174
|
...(await eventCatalogLikeC4(projectDirectory)),
|
|
171
175
|
...(config.trailingSlash === true ? [astroTrailingSlashEndpointFix()] : []),
|
|
@@ -224,7 +228,15 @@ export default defineConfig({
|
|
|
224
228
|
},
|
|
225
229
|
optimizeDeps: {
|
|
226
230
|
exclude: [],
|
|
227
|
-
include:
|
|
231
|
+
include: [
|
|
232
|
+
...collectClientDependencies(),
|
|
233
|
+
// <ClientRouter /> imports these from a virtual module the dependency scan can't follow,
|
|
234
|
+
// so without them every cold start re-bundles on the first page and reloads it
|
|
235
|
+
'astro/virtual-modules/transitions-events.js',
|
|
236
|
+
'astro/virtual-modules/transitions-router.js',
|
|
237
|
+
'astro/virtual-modules/transitions-swap-functions.js',
|
|
238
|
+
'astro/virtual-modules/transitions-types.js',
|
|
239
|
+
],
|
|
228
240
|
},
|
|
229
241
|
},
|
|
230
242
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Astro writes its content data store as the dev server starts, which sends the browser a
|
|
2
|
+
// full reload. With no browser connected yet, Vite holds that reload and hands it to the
|
|
3
|
+
// first page that connects, so the first page opened after every start loaded twice.
|
|
4
|
+
// A reload sent before any page has been served has nothing to refresh (a tab left open
|
|
5
|
+
// from the previous run reloads itself when it reconnects), so drop those. Once a page has
|
|
6
|
+
// been requested, reloads pass through as usual.
|
|
7
|
+
|
|
8
|
+
const isFullReload = (payload) => typeof payload === 'object' && payload?.type === 'full-reload';
|
|
9
|
+
|
|
10
|
+
export default function skipStartupReload() {
|
|
11
|
+
return {
|
|
12
|
+
name: 'eventcatalog:skip-startup-reload',
|
|
13
|
+
apply: 'serve',
|
|
14
|
+
configureServer(server) {
|
|
15
|
+
let pageRequested = false;
|
|
16
|
+
server.middlewares.use((req, _res, next) => {
|
|
17
|
+
// Browser navigations ask for HTML; the CLI's prewarm request doesn't
|
|
18
|
+
if (!pageRequested && req.headers.accept?.includes('text/html')) pageRequested = true;
|
|
19
|
+
next();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
for (const channel of new Set([server.ws, server.environments?.client?.hot].filter(Boolean))) {
|
|
23
|
+
const send = channel.send.bind(channel);
|
|
24
|
+
channel.send = (...args) => {
|
|
25
|
+
if (!pageRequested && isFullReload(args[0])) return;
|
|
26
|
+
return send(...args);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Astro crawls framework packages with vitefu, which looks them up concurrently and lists
|
|
2
|
+
// each one in `resolve.external` / `resolve.noExternal` as its lookup finishes, so the
|
|
3
|
+
// order changes from one start to the next. Vite hashes these lists unsorted to decide
|
|
4
|
+
// whether its pre-bundled dependencies are still valid, so every `eventcatalog dev` saw a
|
|
5
|
+
// "changed" config and re-bundled all of them. Only membership matters in these lists, so
|
|
6
|
+
// sorting them keeps the hash (and the dependency cache) stable across starts.
|
|
7
|
+
|
|
8
|
+
const byName = (a, b) => {
|
|
9
|
+
const left = String(a);
|
|
10
|
+
const right = String(b);
|
|
11
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const sortResolveLists = (resolve) => {
|
|
15
|
+
if (Array.isArray(resolve?.external)) resolve.external.sort(byName);
|
|
16
|
+
if (Array.isArray(resolve?.noExternal)) resolve.noExternal.sort(byName);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default function stableDependencyOrder() {
|
|
20
|
+
return {
|
|
21
|
+
name: 'eventcatalog:stable-dependency-order',
|
|
22
|
+
apply: 'serve',
|
|
23
|
+
configResolved(config) {
|
|
24
|
+
sortResolveLists(config.resolve);
|
|
25
|
+
sortResolveLists(config.ssr);
|
|
26
|
+
for (const environment of Object.values(config.environments ?? {})) sortResolveLists(environment.resolve);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -170,6 +170,16 @@ const nodeRadius = (degree: number, isHub = false) =>
|
|
|
170
170
|
/** Above this node count, expensive extras (collision force) are disabled. */
|
|
171
171
|
const LARGE_GRAPH_NODE_COUNT = 1500;
|
|
172
172
|
|
|
173
|
+
/**
|
|
174
|
+
* The first layout settles before it paints instead of animating into place for ~5s: ticks
|
|
175
|
+
* run in short slices across frames (no long tasks) until it settles, ~40ms of work for 100
|
|
176
|
+
* nodes. Big catalogs stop once ticking has taken the work limit, paint past their largest
|
|
177
|
+
* moves and animate the rest. The limit counts ticking time, not elapsed time, so a page busy
|
|
178
|
+
* hydrating other islands doesn't cut the settle short.
|
|
179
|
+
*/
|
|
180
|
+
const INITIAL_SETTLE_SLICE_MS = 12;
|
|
181
|
+
const INITIAL_SETTLE_WORK_LIMIT_MS = 400;
|
|
182
|
+
|
|
173
183
|
/** Sprite resolution for node icons (drawn scaled-down, so keep it crisp) */
|
|
174
184
|
const ICON_SPRITE_SIZE = 64;
|
|
175
185
|
|
|
@@ -617,6 +627,10 @@ const CatalogForceGraph = ({
|
|
|
617
627
|
// normal-sized, whatever the lens's usual hubs are
|
|
618
628
|
const isHub = (d: SimNode) => (focusKey ? d.key === focusKey : hubs.has(d.collection));
|
|
619
629
|
|
|
630
|
+
// Later layouts (lens, focus and filter changes) animate from the previous positions
|
|
631
|
+
const isFirstLayout = positionsRef.current.size === 0;
|
|
632
|
+
// Nothing paints until the first layout has settled (see INITIAL_SETTLE_SLICE_MS)
|
|
633
|
+
let settling = isFirstLayout;
|
|
620
634
|
const visibleNodes: SimNode[] = viewNodes
|
|
621
635
|
.filter((n) => !hiddenCollections.has(n.collection))
|
|
622
636
|
.map((n) => ({ ...n, degree: 0, ...positionsRef.current.get(n.key) }));
|
|
@@ -734,6 +748,7 @@ const CatalogForceGraph = ({
|
|
|
734
748
|
};
|
|
735
749
|
|
|
736
750
|
const draw = () => {
|
|
751
|
+
if (settling) return;
|
|
737
752
|
context.save();
|
|
738
753
|
context.setTransform(devicePixelRatio, 0, 0, devicePixelRatio, 0, 0);
|
|
739
754
|
context.clearRect(0, 0, width, height);
|
|
@@ -1014,6 +1029,29 @@ const CatalogForceGraph = ({
|
|
|
1014
1029
|
);
|
|
1015
1030
|
}
|
|
1016
1031
|
|
|
1032
|
+
// Settle the first layout before it paints rather than animating it into place
|
|
1033
|
+
let settleFrame: number | undefined;
|
|
1034
|
+
if (isFirstLayout) {
|
|
1035
|
+
simulation.stop();
|
|
1036
|
+
let workLeft = INITIAL_SETTLE_WORK_LIMIT_MS;
|
|
1037
|
+
const settle = () => {
|
|
1038
|
+
const sliceStart = performance.now();
|
|
1039
|
+
const sliceEnd = sliceStart + Math.min(INITIAL_SETTLE_SLICE_MS, workLeft);
|
|
1040
|
+
while (simulation.alpha() > simulation.alphaMin() && performance.now() < sliceEnd) simulation.tick();
|
|
1041
|
+
workLeft -= performance.now() - sliceStart;
|
|
1042
|
+
if (simulation.alpha() > simulation.alphaMin() && workLeft > 0) {
|
|
1043
|
+
settleFrame = requestAnimationFrame(settle);
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
settling = false;
|
|
1047
|
+
// Settled: paint it as is (restarting would run one tick more than the animated
|
|
1048
|
+
// layout). Otherwise paint and animate whatever is left.
|
|
1049
|
+
if (simulation.alpha() <= simulation.alphaMin()) fitToView();
|
|
1050
|
+
else simulation.restart();
|
|
1051
|
+
};
|
|
1052
|
+
settleFrame = requestAnimationFrame(settle);
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1017
1055
|
const findNode = (canvasX: number, canvasY: number): SimNode | null => {
|
|
1018
1056
|
if (Number.isNaN(canvasX) || Number.isNaN(canvasY)) return null;
|
|
1019
1057
|
const x = transform.invertX(canvasX);
|
|
@@ -1219,6 +1257,7 @@ const CatalogForceGraph = ({
|
|
|
1219
1257
|
for (const node of visibleNodes) {
|
|
1220
1258
|
if (node.x !== undefined && node.y !== undefined) positionsRef.current.set(node.key, { x: node.x, y: node.y });
|
|
1221
1259
|
}
|
|
1260
|
+
if (settleFrame !== undefined) cancelAnimationFrame(settleFrame);
|
|
1222
1261
|
simulation.stop();
|
|
1223
1262
|
// The tooltip outlives this effect — never leave it showing stale content
|
|
1224
1263
|
tooltip.style.opacity = '0';
|
|
@@ -17,9 +17,11 @@ import type { Node, Edge } from '@xyflow/react';
|
|
|
17
17
|
import type { FlowGroupBy, OpenInStudioRequest } from '@eventcatalog/visualiser';
|
|
18
18
|
import { buildUrl } from '@utils/url-builder';
|
|
19
19
|
import { createCanvasThroughApi } from '@features/studio/api/client';
|
|
20
|
-
import { canvasFromVisualiser } from '@features/studio/from-visualiser';
|
|
21
20
|
import { getStoredName } from '@features/studio/identity';
|
|
22
|
-
|
|
21
|
+
|
|
22
|
+
// Studio's canvas code (what turns a diagram into a canvas, and the dialog asking for its name) is only loaded when a
|
|
23
|
+
// diagram is opened in Studio: every page with a diagram would load it otherwise, with Studio on or not
|
|
24
|
+
const OpenInStudioDialog = lazy(() => import('@features/studio/components/OpenInStudioDialog'));
|
|
23
25
|
|
|
24
26
|
const NodeGraph = lazy(() =>
|
|
25
27
|
import('@eventcatalog/visualiser').then((module) => ({ default: module.NodeGraph }))
|
|
@@ -123,6 +125,7 @@ const AstroNodeGraph = ({ isDevMode = false, resourceKey, studioApiUrl, ...other
|
|
|
123
125
|
async (title: string | undefined) => {
|
|
124
126
|
if (!studioApiUrl || !toOpen) return;
|
|
125
127
|
const snapshot = await toOpen.getSnapshot();
|
|
128
|
+
const { canvasFromVisualiser } = await import('@features/studio/from-visualiser');
|
|
126
129
|
const { nodes, edges, levels } = canvasFromVisualiser(snapshot);
|
|
127
130
|
if (nodes.length === 0) throw new Error('Nothing on this diagram can go on a canvas yet');
|
|
128
131
|
const canvas = await createCanvasThroughApi(studioApiUrl, {
|
|
@@ -149,7 +152,12 @@ const AstroNodeGraph = ({ isDevMode = false, resourceKey, studioApiUrl, ...other
|
|
|
149
152
|
onResetLayout={handleResetLayout}
|
|
150
153
|
onOpenInStudio={studioApiUrl ? setToOpen : undefined}
|
|
151
154
|
/>
|
|
152
|
-
{toOpen &&
|
|
155
|
+
{toOpen && (
|
|
156
|
+
// Its own, so the diagram isn't swapped for "Loading graph..." while the dialog loads
|
|
157
|
+
<Suspense fallback={null}>
|
|
158
|
+
<OpenInStudioDialog title={toOpen.title} onOpen={openInStudio} onClose={closeOpenInStudio} />
|
|
159
|
+
</Suspense>
|
|
160
|
+
)}
|
|
153
161
|
</Suspense>
|
|
154
162
|
);
|
|
155
163
|
};
|