@eventcatalog/core 4.9.0 → 4.10.1
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/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/{chunk-HKVOSQTD.js → chunk-OC2RGFPU.js} +1 -1
- package/dist/{chunk-MPHX5C7M.js → chunk-PHG7KEUH.js} +1 -1
- package/dist/{chunk-LVGQ23LR.js → chunk-QIV7LWVJ.js} +1 -1
- package/dist/{chunk-XQHS36GO.js → chunk-SQNVL7PI.js} +1 -1
- package/dist/{chunk-3CGSSMTK.js → chunk-T2HLSITU.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/eventcatalog.cjs +1 -1
- package/dist/eventcatalog.js +5 -5
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/astro.config.mjs +6 -0
- package/eventcatalog/src/components/Badge.astro +3 -1
- package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +260 -175
- package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +0 -5
- package/eventcatalog/src/components/MDX/ArchitectureGraph/ArchitectureGraph.astro +62 -0
- package/eventcatalog/src/components/MDX/ArchitectureGraph/ArchitectureGraphPortal.tsx +22 -0
- package/eventcatalog/src/components/MDX/ArchitectureGraph/AstroArchitectureGraph.tsx +42 -0
- package/eventcatalog/src/components/MDX/Design/Design.astro +2 -0
- package/eventcatalog/src/components/MDX/EntityMap/EntityMap.astro +2 -0
- package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +5 -7
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -0
- package/eventcatalog/src/components/MDX/components.tsx +13 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +121 -88
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +55 -7
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.spec.ts +59 -15
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +53 -7
- package/eventcatalog/src/content.config.ts +70 -0
- package/eventcatalog/src/enterprise/collections/resource-docs-utils.ts +19 -0
- package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +46 -1
- package/eventcatalog/src/enterprise/fields/pages/fields.astro +2 -0
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +16 -15
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +21 -17
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +45 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +16 -8
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +48 -65
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +45 -18
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -1
- package/eventcatalog/src/pages/index.astro +34 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +5 -1
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +2 -0
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -0
- package/eventcatalog/src/pages/visualiser/graph/index.astro +2 -23
- package/eventcatalog/src/stores/sidebar-store/builders/adr.ts +96 -34
- package/eventcatalog/src/stores/sidebar-store/builders/agent.ts +167 -75
- package/eventcatalog/src/stores/sidebar-store/builders/container.ts +135 -59
- package/eventcatalog/src/stores/sidebar-store/builders/data-product.ts +144 -58
- package/eventcatalog/src/stores/sidebar-store/builders/domain.ts +306 -188
- package/eventcatalog/src/stores/sidebar-store/builders/entity.ts +108 -39
- package/eventcatalog/src/stores/sidebar-store/builders/flow.ts +147 -63
- package/eventcatalog/src/stores/sidebar-store/builders/message.ts +212 -121
- package/eventcatalog/src/stores/sidebar-store/builders/service.ts +223 -127
- package/eventcatalog/src/stores/sidebar-store/builders/shared.ts +3 -23
- package/eventcatalog/src/stores/sidebar-store/builders/system.ts +187 -97
- package/eventcatalog/src/stores/sidebar-store/custom-sidebar.ts +678 -0
- package/eventcatalog/src/stores/sidebar-store/state.ts +66 -36
- package/eventcatalog/src/styles/tailwind.css +82 -0
- package/eventcatalog/src/utils/collections/resource-docs.ts +1 -0
- package/eventcatalog/src/utils/node-graphs/catalog-force-graph.ts +41 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getCollection } from 'astro:content';
|
|
2
|
+
import { getSidebarForResource, indexSidebarsByFolder } from './custom-sidebar';
|
|
2
3
|
import type { CollectionEntry } from 'astro:content';
|
|
3
4
|
import { getAgents } from '@utils/collections/agents';
|
|
4
5
|
import { getAdrAliasNodeKey, getAdrNodeKey, getAdrs, type Adr } from '@utils/collections/adrs';
|
|
@@ -40,7 +41,7 @@ import {
|
|
|
40
41
|
shouldRenderSideBarSection,
|
|
41
42
|
withArchitectureDecisionsSection,
|
|
42
43
|
} from './builders/shared';
|
|
43
|
-
import { isArchitectureGraphEnabled, isChangelogEnabled } from '@utils/feature';
|
|
44
|
+
import { isArchitectureGraphEnabled, isChangelogEnabled, isResourceDocsEnabled } from '@utils/feature';
|
|
44
45
|
|
|
45
46
|
export type { NavigationData, NavNode, ChildRef };
|
|
46
47
|
|
|
@@ -296,6 +297,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
296
297
|
ubiquitousLanguages,
|
|
297
298
|
resourceDocs,
|
|
298
299
|
resourceDocCategories,
|
|
300
|
+
customSidebarEntries,
|
|
299
301
|
] = await Promise.all([
|
|
300
302
|
getDomains({ getAllVersions: false, includeServicesInSubdomains: false }),
|
|
301
303
|
getSystems({ getAllVersions: false }),
|
|
@@ -316,8 +318,12 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
316
318
|
getCollection('ubiquitousLanguages'),
|
|
317
319
|
getResourceDocs(),
|
|
318
320
|
getResourceDocCategories(),
|
|
321
|
+
getCollection('sidebars'),
|
|
319
322
|
]);
|
|
320
323
|
|
|
324
|
+
// Optional per-resource `sidebar.json` overrides, keyed by the folder they sit in.
|
|
325
|
+
const customSidebars = indexSidebarsByFolder(customSidebarEntries);
|
|
326
|
+
|
|
321
327
|
// Calculate derived lists to avoid extra fetches
|
|
322
328
|
const allSubDomainIds = new Set(domains.flatMap((d) => (d.data.domains || []).map((sd: any) => sd.data.id)));
|
|
323
329
|
const rootDomains = domains.filter((d) => !allSubDomainIds.has(d.data.id));
|
|
@@ -328,6 +334,7 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
328
334
|
const messages = [...allEvents, ...allCommands, ...allQueries];
|
|
329
335
|
|
|
330
336
|
const context = {
|
|
337
|
+
resourceDocsEnabled: isResourceDocsEnabled(),
|
|
331
338
|
agents,
|
|
332
339
|
services,
|
|
333
340
|
domains,
|
|
@@ -433,11 +440,14 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
433
440
|
|
|
434
441
|
const flowNodes = flows.reduce(
|
|
435
442
|
(acc, flow) => {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
)
|
|
443
|
+
const sidebar = getSidebarForResource(customSidebars, flow);
|
|
444
|
+
const node = buildFlowNode(flow, context, { sidebar });
|
|
445
|
+
const versionedKey = `flow:${flow.data.id}:${flow.data.version}`;
|
|
446
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, flow, adrs);
|
|
447
|
+
if (flow.data.latestVersion === flow.data.version) {
|
|
448
|
+
// Store reference to versioned key instead of duplicating the full node
|
|
449
|
+
acc[`flow:${flow.data.id}`] = versionedKey;
|
|
450
|
+
}
|
|
441
451
|
return acc;
|
|
442
452
|
},
|
|
443
453
|
{} as Record<string, NavNode>
|
|
@@ -446,7 +456,10 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
446
456
|
const domainNodes = domainsWithOwners.reduce(
|
|
447
457
|
(acc, { domain, owners }) => {
|
|
448
458
|
const versionedKey = `domain:${domain.data.id}:${domain.data.version}`;
|
|
449
|
-
|
|
459
|
+
const sidebar = getSidebarForResource(customSidebars, domain);
|
|
460
|
+
const domainNode = buildDomainNode(domain, owners, context, { sidebar });
|
|
461
|
+
// A custom sidebar decides for itself whether (and where) `$decision-records` renders.
|
|
462
|
+
acc[versionedKey] = sidebar ? domainNode : withArchitectureDecisionsSection(domainNode, domain, adrs);
|
|
450
463
|
if (domain.data.latestVersion === domain.data.version) {
|
|
451
464
|
// Store reference to versioned key instead of duplicating the full node
|
|
452
465
|
acc[`domain:${domain.data.id}`] = versionedKey;
|
|
@@ -538,11 +551,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
538
551
|
(acc, { agent, owners }) => {
|
|
539
552
|
const versionedKey = `agent:${agent.data.id}:${agent.data.version}`;
|
|
540
553
|
const agentChannels = agentChannelsMap.get(`${agent.data.id}:${agent.data.version}`) || [];
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
adrs
|
|
545
|
-
);
|
|
554
|
+
const sidebar = getSidebarForResource(customSidebars, agent);
|
|
555
|
+
const node = buildAgentNode(agent, owners, context, agentChannels, flowRefsByAgent.get(versionedKey) || [], { sidebar });
|
|
556
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, agent, adrs);
|
|
546
557
|
if (agent.data.latestVersion === agent.data.version) {
|
|
547
558
|
acc[`agent:${agent.data.id}`] = versionedKey;
|
|
548
559
|
}
|
|
@@ -555,11 +566,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
555
566
|
(acc, { service, owners }) => {
|
|
556
567
|
const versionedKey = `service:${service.data.id}:${service.data.version}`;
|
|
557
568
|
const serviceChannels = serviceChannelsMap.get(`${service.data.id}:${service.data.version}`) || [];
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
);
|
|
569
|
+
const sidebar = getSidebarForResource(customSidebars, service);
|
|
570
|
+
const node = buildServiceNode(service, owners, context, serviceChannels, flowRefsByService.get(versionedKey) || [], {
|
|
571
|
+
sidebar,
|
|
572
|
+
});
|
|
573
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, service, adrs);
|
|
563
574
|
if (service.data.latestVersion === service.data.version) {
|
|
564
575
|
// Store reference to versioned key instead of duplicating the full node
|
|
565
576
|
acc[`service:${service.data.id}`] = versionedKey;
|
|
@@ -612,14 +623,17 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
612
623
|
const hasFieldUsage = messagesWithFieldUsage.has(message.data.id);
|
|
613
624
|
const triggers = getTriggersOfMessage(messageReceivers, message, messages);
|
|
614
625
|
const triggeredBy = getTriggeredByOfMessage(messageReceivers, message, messages);
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
triggers,
|
|
618
|
-
triggeredBy,
|
|
619
|
-
}),
|
|
626
|
+
const sidebar = getSidebarForResource(customSidebars, message);
|
|
627
|
+
const node = buildMessageNode(
|
|
620
628
|
message,
|
|
621
|
-
|
|
629
|
+
owners,
|
|
630
|
+
context,
|
|
631
|
+
hasFieldUsage,
|
|
632
|
+
flowRefsByMessage.get(versionedKey) || [],
|
|
633
|
+
{ triggers, triggeredBy },
|
|
634
|
+
{ sidebar }
|
|
622
635
|
);
|
|
636
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, message, adrs);
|
|
623
637
|
if (message.data.latestVersion === message.data.version) {
|
|
624
638
|
// Store reference to versioned key instead of duplicating the full node
|
|
625
639
|
acc[`${type}:${message.data.id}`] = versionedKey;
|
|
@@ -634,11 +648,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
634
648
|
const containerNodes = containerWithOwners.reduce(
|
|
635
649
|
(acc, { container, owners }) => {
|
|
636
650
|
const versionedKey = `container:${container.data.id}:${container.data.version}`;
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
adrs
|
|
641
|
-
);
|
|
651
|
+
const sidebar = getSidebarForResource(customSidebars, container);
|
|
652
|
+
const node = buildContainerNode(container, owners, context, flowRefsByContainer.get(versionedKey) || [], { sidebar });
|
|
653
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, container, adrs);
|
|
642
654
|
if (container.data.latestVersion === container.data.version) {
|
|
643
655
|
// Store reference to versioned key instead of duplicating the full node
|
|
644
656
|
acc[`container:${container.data.id}`] = versionedKey;
|
|
@@ -651,7 +663,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
651
663
|
const systemNodes = systemWithOwners.reduce(
|
|
652
664
|
(acc, { system, owners }) => {
|
|
653
665
|
const versionedKey = `system:${system.data.id}:${system.data.version}`;
|
|
654
|
-
|
|
666
|
+
const sidebar = getSidebarForResource(customSidebars, system);
|
|
667
|
+
const node = buildSystemNode(system, owners, context, { sidebar });
|
|
668
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, system, adrs);
|
|
655
669
|
if (system.data.latestVersion === system.data.version) {
|
|
656
670
|
// Store reference to versioned key instead of duplicating the full node
|
|
657
671
|
acc[`system:${system.data.id}`] = versionedKey;
|
|
@@ -670,12 +684,24 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
670
684
|
);
|
|
671
685
|
|
|
672
686
|
const dataProductContext = {
|
|
687
|
+
resourceDocsEnabled: isResourceDocsEnabled(),
|
|
673
688
|
events,
|
|
674
689
|
commands,
|
|
675
690
|
queries,
|
|
676
691
|
services,
|
|
677
692
|
containers,
|
|
678
693
|
channels,
|
|
694
|
+
adrs,
|
|
695
|
+
// Included so data-product sidebar.json files resolve the same refs as every other
|
|
696
|
+
// resource (cross-resource specs, schema-existence checks, latest-only pins).
|
|
697
|
+
domains,
|
|
698
|
+
systems,
|
|
699
|
+
agents,
|
|
700
|
+
flows,
|
|
701
|
+
entities,
|
|
702
|
+
dataProducts,
|
|
703
|
+
diagrams,
|
|
704
|
+
schemas,
|
|
679
705
|
resourceDocs,
|
|
680
706
|
resourceDocCategories,
|
|
681
707
|
};
|
|
@@ -685,11 +711,11 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
685
711
|
const dataProductNodes = dataProductWithOwners.reduce(
|
|
686
712
|
(acc, { dataProduct, owners }) => {
|
|
687
713
|
const versionedKey = `data-product:${dataProduct.data.id}:${dataProduct.data.version}`;
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
);
|
|
714
|
+
const sidebar = getSidebarForResource(customSidebars, dataProduct);
|
|
715
|
+
const node = buildDataProductNode(dataProduct, owners, dataProductContext, flowRefsByDataProduct.get(versionedKey) || [], {
|
|
716
|
+
sidebar,
|
|
717
|
+
});
|
|
718
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, dataProduct, adrs);
|
|
693
719
|
if (dataProduct.data.latestVersion === dataProduct.data.version) {
|
|
694
720
|
acc[`data-product:${dataProduct.data.id}`] = versionedKey;
|
|
695
721
|
}
|
|
@@ -701,7 +727,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
701
727
|
const adrNodes = adrsWithOwners.reduce(
|
|
702
728
|
(acc, { adr, owners, decisionMakers }) => {
|
|
703
729
|
const versionedKey = getAdrNodeKey(adr);
|
|
704
|
-
acc[versionedKey] = buildAdrNode(adr, owners, decisionMakers, context
|
|
730
|
+
acc[versionedKey] = buildAdrNode(adr, owners, decisionMakers, context, {
|
|
731
|
+
sidebar: getSidebarForResource(customSidebars, adr),
|
|
732
|
+
});
|
|
705
733
|
if (adr.data.latestVersion === adr.data.version) {
|
|
706
734
|
acc[getAdrAliasNodeKey(adr)] = versionedKey;
|
|
707
735
|
}
|
|
@@ -713,7 +741,9 @@ export const getNestedSideBarData = async (): Promise<NavigationData> => {
|
|
|
713
741
|
const entityNodes = entitiesWithOwners.reduce(
|
|
714
742
|
(acc, { entity, owners }) => {
|
|
715
743
|
const versionedKey = `entity:${entity.data.id}:${entity.data.version}`;
|
|
716
|
-
|
|
744
|
+
const sidebar = getSidebarForResource(customSidebars, entity);
|
|
745
|
+
const node = buildEntityNode(entity, owners, context, { sidebar });
|
|
746
|
+
acc[versionedKey] = sidebar ? node : withArchitectureDecisionsSection(node, entity, adrs);
|
|
717
747
|
if (entity.data.latestVersion === entity.data.version) {
|
|
718
748
|
acc[`entity:${entity.data.id}`] = versionedKey;
|
|
719
749
|
}
|
|
@@ -20,6 +20,88 @@
|
|
|
20
20
|
font-weight: 400;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/*
|
|
24
|
+
* Docs typography scale.
|
|
25
|
+
*
|
|
26
|
+
* Tailwind Typography's defaults are tuned for long-form articles: 1.75 line-height,
|
|
27
|
+
* paragraph gaps of 1.25em and heading gaps of 2em. Reference documentation (Stripe,
|
|
28
|
+
* GitHub, Vercel, Mintlify) measures at ~1.6 line-height, 1em paragraph gaps and heading
|
|
29
|
+
* gaps of ~1.5em with 500–600 weight headings. Tighten to match so pages read as reference
|
|
30
|
+
* material rather than essays.
|
|
31
|
+
*
|
|
32
|
+
* Scoped to `.docs-layout` (resource, resource-doc, resources, language pages) and
|
|
33
|
+
* `.custom-docs-shell` (custom documentation) so other
|
|
34
|
+
* prose surfaces — chat panel, admonitions on custom pages, the homepage — keep the plugin
|
|
35
|
+
* defaults. These rules are unlayered, so they win over the plugin's `@layer utilities`
|
|
36
|
+
* output regardless of source order; `h2 + *` etc. are restated because the plugin's
|
|
37
|
+
* zero-specificity `:where()` versions would otherwise lose to the rules above them.
|
|
38
|
+
*/
|
|
39
|
+
.docs-layout .prose,
|
|
40
|
+
.custom-docs-shell .prose {
|
|
41
|
+
line-height: 1.6;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.docs-layout .prose p,
|
|
45
|
+
.custom-docs-shell .prose p,
|
|
46
|
+
.docs-layout .prose ul,
|
|
47
|
+
.custom-docs-shell .prose ul,
|
|
48
|
+
.docs-layout .prose ol,
|
|
49
|
+
.custom-docs-shell .prose ol,
|
|
50
|
+
.docs-layout .prose blockquote,
|
|
51
|
+
.custom-docs-shell .prose blockquote,
|
|
52
|
+
.docs-layout .prose table,
|
|
53
|
+
.custom-docs-shell .prose table {
|
|
54
|
+
margin-top: 1em;
|
|
55
|
+
margin-bottom: 1em;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.docs-layout .prose li,
|
|
59
|
+
.custom-docs-shell .prose li {
|
|
60
|
+
margin-top: 0.25em;
|
|
61
|
+
margin-bottom: 0.25em;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.docs-layout .prose h2,
|
|
65
|
+
.custom-docs-shell .prose h2 {
|
|
66
|
+
font-weight: 600;
|
|
67
|
+
letter-spacing: -0.01em;
|
|
68
|
+
margin-top: 1.6em;
|
|
69
|
+
margin-bottom: 0.6em;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.docs-layout .prose h3,
|
|
73
|
+
.custom-docs-shell .prose h3 {
|
|
74
|
+
font-weight: 600;
|
|
75
|
+
margin-top: 1.5em;
|
|
76
|
+
margin-bottom: 0.5em;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.docs-layout .prose h4,
|
|
80
|
+
.custom-docs-shell .prose h4 {
|
|
81
|
+
font-weight: 600;
|
|
82
|
+
margin-top: 1.4em;
|
|
83
|
+
margin-bottom: 0.4em;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.docs-layout .prose h2 + *,
|
|
87
|
+
.custom-docs-shell .prose h2 + *,
|
|
88
|
+
.docs-layout .prose h3 + *,
|
|
89
|
+
.custom-docs-shell .prose h3 + *,
|
|
90
|
+
.docs-layout .prose h4 + *,
|
|
91
|
+
.custom-docs-shell .prose h4 + * {
|
|
92
|
+
margin-top: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.docs-layout .prose > :first-child,
|
|
96
|
+
.custom-docs-shell .prose > :first-child {
|
|
97
|
+
margin-top: 0;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.docs-layout .prose > :last-child,
|
|
101
|
+
.custom-docs-shell .prose > :last-child {
|
|
102
|
+
margin-bottom: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
23
105
|
/* Dark mode uses data-theme attribute, not prefers-color-scheme */
|
|
24
106
|
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
|
|
25
107
|
|
|
@@ -35,6 +35,47 @@ export interface CatalogGraphLink {
|
|
|
35
35
|
label: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/** Compact wire format — index-based links keep the payload Astro serialises into the island small. */
|
|
39
|
+
export interface CatalogGraphWireNode {
|
|
40
|
+
/** Resource id, e.g. `InventoryService` — the client rebuilds the `${collection}/${id}` key */
|
|
41
|
+
id: string;
|
|
42
|
+
label: string;
|
|
43
|
+
collection: string;
|
|
44
|
+
version?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** [sourceIndex, targetIndex, labelIndex] into the nodes / linkLabels arrays */
|
|
48
|
+
export type CatalogGraphWireLink = [number, number, number];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Compacts the built graph for serialisation into a client island: node ids are
|
|
52
|
+
* stripped of their `${collection}/` prefix, link labels are deduped into one
|
|
53
|
+
* array, and each link becomes an index tuple. URLs are dropped server-side and
|
|
54
|
+
* rebuilt client-side.
|
|
55
|
+
*/
|
|
56
|
+
export const toCatalogForceGraphWire = ({ nodes, links }: { nodes: CatalogGraphNode[]; links: CatalogGraphLink[] }) => {
|
|
57
|
+
const nodeIndexById = new Map(nodes.map((node, index) => [node.id, index]));
|
|
58
|
+
const linkLabels = [...new Set(links.map((link) => link.label))];
|
|
59
|
+
const labelIndexByLabel = new Map(linkLabels.map((label, index) => [label, index]));
|
|
60
|
+
|
|
61
|
+
const wireNodes: CatalogGraphWireNode[] = nodes.map(({ id, label, collection, version }) => ({
|
|
62
|
+
id: id.slice(collection.length + 1),
|
|
63
|
+
label,
|
|
64
|
+
collection,
|
|
65
|
+
version,
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
const wireLinks = links.map(
|
|
69
|
+
(link): CatalogGraphWireLink => [
|
|
70
|
+
nodeIndexById.get(link.source)!,
|
|
71
|
+
nodeIndexById.get(link.target)!,
|
|
72
|
+
labelIndexByLabel.get(link.label)!,
|
|
73
|
+
]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return { nodes: wireNodes, links: wireLinks, linkLabels };
|
|
77
|
+
};
|
|
78
|
+
|
|
38
79
|
type AnyEntry = {
|
|
39
80
|
collection?: string;
|
|
40
81
|
data: { id: string; name?: string; version?: string; latestVersion?: string; visualiser?: boolean };
|