@eventcatalog/core 2.65.0 → 3.0.0-beta.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 (130) hide show
  1. package/README.md +1 -26
  2. package/dist/analytics/analytics.cjs +1 -1
  3. package/dist/analytics/analytics.js +2 -2
  4. package/dist/analytics/log-build.cjs +1 -1
  5. package/dist/analytics/log-build.js +3 -3
  6. package/dist/{chunk-NK6OYMRD.js → chunk-JB4YT5JY.js} +1 -1
  7. package/dist/{chunk-BMDTX5IN.js → chunk-TQ4HZREX.js} +1 -1
  8. package/dist/{chunk-IJRFYF4B.js → chunk-X4W4YC3U.js} +1 -1
  9. package/dist/constants.cjs +1 -1
  10. package/dist/constants.js +1 -1
  11. package/dist/eventcatalog.cjs +1 -21
  12. package/dist/eventcatalog.config.d.cts +10 -0
  13. package/dist/eventcatalog.config.d.ts +10 -0
  14. package/dist/eventcatalog.js +3 -20
  15. package/eventcatalog/src/components/CopyAsMarkdown.tsx +19 -1
  16. package/eventcatalog/src/components/FavoriteButton.tsx +54 -0
  17. package/eventcatalog/src/components/Grids/DomainGrid.tsx +386 -362
  18. package/eventcatalog/src/components/Grids/MessageGrid.tsx +166 -518
  19. package/eventcatalog/src/components/Header.astro +48 -23
  20. package/eventcatalog/src/components/Lists/VersionList.astro +2 -2
  21. package/eventcatalog/src/components/MDX/Design/Design.astro +4 -1
  22. package/eventcatalog/src/components/MDX/Flow/Flow.astro +2 -1
  23. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +3 -3
  24. package/eventcatalog/src/components/SchemaExplorer/SchemaDetailsPanel.tsx +8 -2
  25. package/eventcatalog/src/components/SchemaExplorer/SchemaPageViewer.tsx +37 -0
  26. package/eventcatalog/src/components/Search/Search.astro +48 -28
  27. package/eventcatalog/src/components/Search/SearchModal.tsx +393 -702
  28. package/eventcatalog/src/components/SideNav/NestedSideBar/SearchBar.tsx +298 -0
  29. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/container.ts +66 -0
  30. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/domain.ts +101 -0
  31. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/flow.ts +29 -0
  32. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/message.ts +84 -0
  33. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/service.ts +147 -0
  34. package/eventcatalog/src/components/SideNav/NestedSideBar/builders/shared.ts +146 -0
  35. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +1073 -0
  36. package/eventcatalog/src/components/SideNav/NestedSideBar/sidebar-builder.ts +365 -0
  37. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +90 -0
  38. package/eventcatalog/src/components/SideNav/SideNav.astro +18 -28
  39. package/eventcatalog/src/content.config.ts +2 -0
  40. package/eventcatalog/src/enterprise/custom-documentation/pages/docs/custom/index.astro +10 -4
  41. package/eventcatalog/src/enterprise/eventcatalog-chat/pages/chat/index.astro +3 -3
  42. package/eventcatalog/src/layouts/DirectoryLayout.astro +2 -2
  43. package/eventcatalog/src/layouts/DiscoverLayout.astro +3 -3
  44. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +85 -63
  45. package/eventcatalog/src/layouts/VisualiserLayout.astro +3 -3
  46. package/eventcatalog/src/pages/_index.astro +530 -110
  47. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +64 -0
  48. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +29 -0
  49. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +4 -4
  50. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +1 -4
  51. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +3 -3
  52. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -5
  53. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +362 -190
  54. package/eventcatalog/src/pages/docs/[type]/[id]/[version].md.ts +1 -1
  55. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +4 -4
  56. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +1 -4
  57. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +3 -27
  58. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +2 -2
  59. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +2 -2
  60. package/eventcatalog/src/pages/index.astro +14 -5
  61. package/eventcatalog/src/pages/nav-index.json.ts +30 -0
  62. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +77 -0
  63. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +90 -0
  64. package/eventcatalog/src/pages/schemas/{index.astro → explorer/index.astro} +3 -3
  65. package/eventcatalog/src/pages/studio.astro +3 -3
  66. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +4 -3
  67. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +2 -2
  68. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +4 -3
  69. package/eventcatalog/src/stores/favorites-store.ts +83 -0
  70. package/eventcatalog/src/stores/sidebar-store.ts +8 -0
  71. package/eventcatalog/src/utils/collections/changelogs.ts +7 -4
  72. package/eventcatalog/src/utils/{channels.ts → collections/channels.ts} +81 -31
  73. package/eventcatalog/src/utils/collections/commands.ts +134 -0
  74. package/eventcatalog/src/utils/collections/containers.ts +44 -33
  75. package/eventcatalog/src/utils/collections/domains.ts +204 -62
  76. package/eventcatalog/src/utils/{entities.ts → collections/entities.ts} +44 -24
  77. package/eventcatalog/src/utils/collections/events.ts +136 -0
  78. package/eventcatalog/src/utils/collections/flows.ts +59 -25
  79. package/eventcatalog/src/utils/{messages.ts → collections/messages.ts} +13 -4
  80. package/eventcatalog/src/utils/{queries.ts → collections/queries.ts} +49 -28
  81. package/eventcatalog/src/utils/collections/services.ts +100 -68
  82. package/eventcatalog/src/utils/collections/teams.ts +94 -0
  83. package/eventcatalog/src/utils/collections/users.ts +122 -0
  84. package/eventcatalog/src/utils/collections/util.ts +57 -1
  85. package/eventcatalog/src/utils/feature.ts +3 -1
  86. package/eventcatalog/src/utils/{collections/file-diffs.ts → file-diffs.ts} +1 -1
  87. package/eventcatalog/src/utils/node-graphs/container-node-graph.ts +2 -0
  88. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +16 -6
  89. package/eventcatalog/src/utils/node-graphs/domains-canvas.ts +14 -10
  90. package/eventcatalog/src/utils/node-graphs/domains-node-graph.ts +36 -64
  91. package/eventcatalog/src/utils/node-graphs/flows-node-graph.ts +23 -19
  92. package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +36 -49
  93. package/eventcatalog/src/utils/node-graphs/services-node-graph.ts +22 -18
  94. package/eventcatalog/src/utils/page-loaders/page-data-loader.ts +4 -4
  95. package/eventcatalog/tailwind.config.mjs +14 -0
  96. package/eventcatalog/tsconfig.json +2 -1
  97. package/package.json +7 -4
  98. package/eventcatalog/public/logo_old.png +0 -0
  99. package/eventcatalog/src/components/DiscoverInsight.astro +0 -61
  100. package/eventcatalog/src/components/Grids/ServiceGrid.tsx +0 -534
  101. package/eventcatalog/src/components/Lists/CustomSideBarSectionList.astro +0 -55
  102. package/eventcatalog/src/components/Lists/ProtocolList.tsx +0 -74
  103. package/eventcatalog/src/components/Lists/RepositoryList.astro +0 -37
  104. package/eventcatalog/src/components/Lists/SpecificationsList.astro +0 -67
  105. package/eventcatalog/src/components/SideBars/ChannelSideBar.astro +0 -204
  106. package/eventcatalog/src/components/SideBars/ContainerSideBar.astro +0 -180
  107. package/eventcatalog/src/components/SideBars/DomainSideBar.astro +0 -273
  108. package/eventcatalog/src/components/SideBars/EntitySideBar.astro +0 -139
  109. package/eventcatalog/src/components/SideBars/FlowSideBar.astro +0 -128
  110. package/eventcatalog/src/components/SideBars/MessageSideBar.astro +0 -248
  111. package/eventcatalog/src/components/SideBars/ServiceSideBar.astro +0 -294
  112. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/CollapsibleGroup.tsx +0 -46
  113. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/MessageList.tsx +0 -78
  114. package/eventcatalog/src/components/SideNav/ListViewSideBar/components/SpecificationList.tsx +0 -83
  115. package/eventcatalog/src/components/SideNav/ListViewSideBar/index.tsx +0 -1250
  116. package/eventcatalog/src/components/SideNav/ListViewSideBar/types.ts +0 -91
  117. package/eventcatalog/src/components/SideNav/ListViewSideBar/utils.ts +0 -201
  118. package/eventcatalog/src/components/SideNav/TreeView/getTreeView.ts +0 -190
  119. package/eventcatalog/src/components/SideNav/TreeView/index.tsx +0 -94
  120. package/eventcatalog/src/components/TreeView/index.tsx +0 -328
  121. package/eventcatalog/src/components/TreeView/styles.module.css +0 -264
  122. package/eventcatalog/src/components/TreeView/useSlots.ts +0 -95
  123. package/eventcatalog/src/pages/architecture/[type]/index.astro +0 -14
  124. package/eventcatalog/src/pages/architecture/architecture.astro +0 -101
  125. package/eventcatalog/src/pages/architecture/docs/[type]/index.astro +0 -14
  126. package/eventcatalog/src/utils/commands.ts +0 -112
  127. package/eventcatalog/src/utils/events.ts +0 -108
  128. package/eventcatalog/src/utils/generators/index.ts +0 -10
  129. package/eventcatalog/src/utils/teams.ts +0 -72
  130. package/eventcatalog/src/utils/users.ts +0 -72
@@ -1,26 +1,21 @@
1
1
  ---
2
+ // External dependencies
3
+ import { marked } from 'marked';
4
+
5
+ import { render } from 'astro:content';
6
+ import type { CollectionEntry } from 'astro:content';
7
+
2
8
  import VerticalSideBarLayout from '@layouts/VerticalSideBarLayout.astro';
3
9
  import Footer from '@layouts/Footer.astro';
4
- import { marked } from 'marked';
5
10
 
6
11
  import components from '@components/MDX/components';
7
12
  import NodeGraph from '@components/MDX/NodeGraph/NodeGraph.astro';
8
13
  import SchemaViewer from '@components/MDX/SchemaViewer/SchemaViewerRoot.astro';
9
14
  import Admonition from '@components/MDX/Admonition';
10
-
11
- import { getSpecificationsForService } from '@utils/collections/services';
12
-
13
- import { resourceToCollectionMap, collectionToResourceMap } from '@utils/collections/util';
14
-
15
- // SideBars
16
- import ServiceSideBar from '@components/SideBars/ServiceSideBar.astro';
17
- import MessageSideBar from '@components/SideBars/MessageSideBar.astro';
18
- import DomainSideBar from '@components/SideBars/DomainSideBar.astro';
19
- import ChannelSideBar from '@components/SideBars/ChannelSideBar.astro';
20
- import FlowSideBar from '@components/SideBars/FlowSideBar.astro';
21
- import EntitySideBar from '@components/SideBars/EntitySideBar.astro';
22
- import ContainerSideBar from '@components/SideBars/ContainerSideBar.astro';
15
+ import VersionList from '@components/Lists/VersionList.astro';
23
16
  import CopyAsMarkdown from '@components/CopyAsMarkdown';
17
+ import FavoriteButton from '@components/FavoriteButton';
18
+ import { shouldRenderSideBarSection } from '@components/SideNav/NestedSideBar/builders/shared';
24
19
 
25
20
  import {
26
21
  QueueListIcon,
@@ -33,21 +28,26 @@ import {
33
28
  ClockIcon,
34
29
  } from '@heroicons/react/24/outline';
35
30
  import { ArrowsRightLeftIcon } from '@heroicons/react/20/solid';
36
- import { Box, Boxes, SquarePenIcon, DatabaseIcon, DatabaseZapIcon, ShieldCheckIcon } from 'lucide-react';
37
- import type { CollectionTypes } from '@types';
38
-
39
- import { render } from 'astro:content';
40
- import type { CollectionEntry } from 'astro:content';
31
+ import { Box, Boxes, SquarePenIcon, DatabaseIcon, DatabaseZapIcon, ShieldCheckIcon, AlignLeft } from 'lucide-react';
41
32
 
33
+ import { getSpecificationsForService } from '@utils/collections/services';
34
+ import { resourceToCollectionMap, collectionToResourceMap, getDeprecatedDetails } from '@utils/collections/util';
35
+ import { getSchemasFromResource } from '@utils/collections/schemas';
42
36
  import { getIcon } from '@utils/badges';
43
- import { getDeprecatedDetails } from '@utils/collections/util';
44
37
  import { buildUrl, buildEditUrlForResource } from '@utils/url-builder';
45
- import { getSchemasFromResource } from '@utils/collections/schemas';
46
- import { isEventCatalogChatEnabled, isMarkdownDownloadEnabled } from '@utils/feature';
47
-
38
+ import {
39
+ isEventCatalogChatEnabled,
40
+ isMarkdownDownloadEnabled,
41
+ isVisualiserEnabled,
42
+ isChangelogEnabled,
43
+ isRSSEnabled,
44
+ } from '@utils/feature';
48
45
  import { getMDXComponentsByName } from '@utils/markdown';
49
46
 
47
+ import type { CollectionTypes } from '@types';
48
+
50
49
  import config from '@config';
50
+
51
51
  import { Page } from './_index.data';
52
52
 
53
53
  export const prerender = Page.prerender;
@@ -56,7 +56,7 @@ export const getStaticPaths = Page.getStaticPaths;
56
56
  // Get data
57
57
  const props = await Page.getData(Astro);
58
58
 
59
- const { Content } = await render(props);
59
+ const { Content, headings } = await render(props);
60
60
 
61
61
  const pageTitle = `${props.collection} | ${props.data.name}`.replace(/^\w/, (c) => c.toUpperCase());
62
62
  const contentBadges = props.data.badges || [];
@@ -259,6 +259,9 @@ let nodeGraphs = getMDXComponentsByName(props.body || '', 'NodeGraph') || [];
259
259
  // Get props for the node graph (when no id is passed, we assume its the current page)
260
260
  const nodeGraphPropsForPage = nodeGraphs.find((nodeGraph: any) => nodeGraph.id === undefined) || ({} as any);
261
261
 
262
+ const shouldRenderVersionList =
263
+ shouldRenderSideBarSection(props, 'versions') && props.data.versions && props.data.versions.length > 1;
264
+
262
265
  // This will render the graph for this page
263
266
  nodeGraphs.push({
264
267
  id: props.data.id,
@@ -271,19 +274,31 @@ nodeGraphs.push({
271
274
  ---
272
275
 
273
276
  <VerticalSideBarLayout title={pageTitle} description={props.data.summary}>
274
- <main class="flex sm:px-8 docs-layout h-full" {...pagefindAttributes}>
275
- <div class="flex docs-layout w-full">
277
+ <main class="flex docs-layout h-full" {...pagefindAttributes}>
278
+ <div class="flex docs-layout w-full pl-16 pr-24">
276
279
  <div class="w-full lg:mr-2 pr-8 overflow-y-auto py-8">
277
280
  <div class="border-b border-gray-200 md:pb-2">
278
281
  <div>
279
282
  <div class="flex justify-between items-center">
280
- <h2
281
- id="doc-page-header"
282
- class={`text-2xl md:text-4xl font-bold text-black ${props.data.deprecated && hasDeprecated ? 'text-red-500' : ''}`}
283
- >
284
- {props.data.name}
285
- <span class="">(v{props.data.version})</span>
286
- </h2>
283
+ <div class="flex items-center gap-2">
284
+ <h2
285
+ id="doc-page-header"
286
+ class={`text-2xl md:text-4xl font-bold text-black ${props.data.deprecated && hasDeprecated ? 'text-red-500' : ''}`}
287
+ >
288
+ {props.data.name}
289
+ <span class="">(v{props.data.version})</span>
290
+ </h2>
291
+ <FavoriteButton
292
+ client:load
293
+ nodeKey={`${collectionToResourceMap[props.collection as keyof typeof collectionToResourceMap]}:${props.data.id}:${props.data.version}`}
294
+ title={props.data.name}
295
+ badge={collectionToResourceMap[props.collection as keyof typeof collectionToResourceMap]
296
+ .charAt(0)
297
+ .toUpperCase() + collectionToResourceMap[props.collection as keyof typeof collectionToResourceMap].slice(1)}
298
+ href={buildUrl(`/docs/${props.collection}/${props.data.id}/${props.data.version}`)}
299
+ size="md"
300
+ />
301
+ </div>
287
302
  <div class="hidden lg:block">
288
303
  <CopyAsMarkdown
289
304
  client:only="react"
@@ -291,6 +306,7 @@ nodeGraphs.push({
291
306
  chatQuery={generatePromptForResource(props)}
292
307
  chatEnabled={isEventCatalogChatEnabled()}
293
308
  markdownDownloadEnabled={isMarkdownDownloadEnabled()}
309
+ rssFeedEnabled={isRSSEnabled()}
294
310
  editUrl={editUrl}
295
311
  />
296
312
  </div>
@@ -446,10 +462,14 @@ nodeGraphs.push({
446
462
  linksToVisualiser={true}
447
463
  showSearch={nodeGraph.search ?? true}
448
464
  showLegend={nodeGraph.legend ?? true}
449
- href={{
450
- label: 'Open in Visualiser',
451
- url: buildUrl(`/visualiser/${collection}/${nodeGraph.id}/${nodeGraph.version}`),
452
- }}
465
+ href={
466
+ isVisualiserEnabled()
467
+ ? {
468
+ label: 'Open in Visualiser',
469
+ url: buildUrl(`/visualiser/${collection}/${nodeGraph.id}/${nodeGraph.version}`),
470
+ }
471
+ : undefined
472
+ }
453
473
  />
454
474
  );
455
475
  })
@@ -471,185 +491,337 @@ nodeGraphs.push({
471
491
  }
472
492
  </div>
473
493
  </div>
474
- <aside class="hidden lg:block sticky top-0 pb-10 w-96 overflow-y-auto py-2" data-pagefind-ignore>
475
- <!-- @ts-ignore -->
476
- {
477
- (props?.collection === 'events' || props.collection === 'commands' || props.collection === 'queries') && (
478
- <MessageSideBar message={props} />
479
- )
480
- }
481
- {props?.collection === 'services' && <ServiceSideBar service={props} />}
482
- {props?.collection === 'domains' && <DomainSideBar domain={props} />}
483
- {props?.collection === 'channels' && <ChannelSideBar channel={props} />}
484
- {props?.collection === 'flows' && <FlowSideBar flow={props} />}
485
- {props?.collection === 'entities' && <EntitySideBar entity={props} />}
486
- {props?.collection === 'containers' && <ContainerSideBar container={props} />}
494
+ <aside class="hidden lg:block sticky top-0 pb-10 w-80 overflow-y-auto bg-white py-2 flex-shrink-0">
495
+ <div class="py-4 mt-4 space-y-8">
496
+ {
497
+ headings.length > 0 && (
498
+ <div>
499
+ <h3 class="text-xs text-black font-semibold group-data-[hover]:text-black/80 capitalize flex items-center gap-2 mb-4">
500
+ <AlignLeft className="w-4 h-4" />
501
+ On this page
502
+ </h3>
503
+ <div class="space-y-8">
504
+ <nav class="text-xs border-l border-gray-200">
505
+ {headings.map((heading) => {
506
+ const level = heading.depth > 2 ? heading.depth : 1;
507
+ if (heading.depth > 3) {
508
+ return null;
509
+ }
510
+ return (
511
+ <a
512
+ href={`#${heading.slug}`}
513
+ class={`block py-1.5 pr-2.5 leading-5 text-gray-500 hover:border-gray-300 hover:text-gray-900 border-l-2 border-transparent -ml-px transition-all duration-200`}
514
+ style={`padding-left: ${level * 0.75}rem`}
515
+ >
516
+ {heading.text}
517
+ </a>
518
+ );
519
+ })}
520
+ </nav>
521
+ </div>
522
+ </div>
523
+ )
524
+ }
525
+ {
526
+ shouldRenderVersionList && (
527
+ <VersionList
528
+ title={`Versions (${props.data.versions?.length})`}
529
+ versions={props.data.versions}
530
+ collectionItem={props}
531
+ />
532
+ )
533
+ }
534
+ <!-- Change log link -->
535
+ {
536
+ isChangelogEnabled() && shouldRenderSideBarSection(props, 'changelog') && (
537
+ <a
538
+ href={buildUrl(`/docs/${props.collection}/${props.data.id}/${props.data.latestVersion}/changelog`)}
539
+ class="text-xs text-gray-500 underline"
540
+ >
541
+ <span class="block">Read changelog &rarr;</span>
542
+ </a>
543
+ )
544
+ }
545
+ </div>
487
546
  </aside>
488
547
  </div>
489
- </main>
490
548
 
491
- <style is:global>
492
- .docs-layout .prose {
493
- max-width: none;
494
- overflow: auto;
495
- }
549
+ <style is:global>
550
+ .docs-layout .prose {
551
+ max-width: none;
552
+ overflow: auto;
553
+ }
496
554
 
497
- .mermaid svg {
498
- margin: 1em auto 2em;
499
- }
555
+ .mermaid svg {
556
+ margin: 1em auto 2em;
557
+ }
500
558
 
501
- /* Fix for architecture diagrams */
502
- .mermaid[data-content*='architecture'] svg {
503
- max-width: 350px !important;
504
- margin: 0;
505
- /* width: 100px !important; */
506
- }
507
- </style>
559
+ /* Fix for architecture diagrams */
560
+ .mermaid[data-content*='architecture'] svg {
561
+ max-width: 350px !important;
562
+ margin: 0;
563
+ /* width: 100px !important; */
564
+ }
565
+ </style>
508
566
 
509
- <script define:vars={{ props, config }}>
510
- // Fix to pass information to componets that are client side only
511
- // and require catalog information
512
- window.eventcatalog = {};
513
- // @ts-ignore
514
- window.eventcatalog[`${props.collection}-${props.data.id}`] = props.catalog;
567
+ <script define:vars={{ props, config }}>
568
+ // Fix to pass information to componets that are client side only
569
+ // and require catalog information
570
+ window.eventcatalog = {};
571
+ // @ts-ignore
572
+ window.eventcatalog[`${props.collection}-${props.data.id}`] = props.catalog;
515
573
 
516
- window.eventcatalog.mermaid = config.mermaid;
517
- </script>
574
+ window.eventcatalog.mermaid = config.mermaid;
575
+ </script>
518
576
 
519
- <script>
520
- // Listen for Astro transititions
521
- document.addEventListener('astro:page-load', () => {
522
- const graphs = document.getElementsByClassName('mermaid');
523
- if (document.getElementsByClassName('mermaid').length > 0) {
524
- renderDiagrams(graphs);
525
- }
526
- });
527
-
528
- /**
529
- * Renders mermaid diagrams in the page
530
- * @param {HTMLCollectionOf<HTMLElement>} graphs - The collection of mermaid graph elements
531
- */
532
- async function renderDiagrams(graphs: any) {
533
- const { default: mermaid } = await import('mermaid');
534
-
535
- if (window.eventcatalog.mermaid) {
536
- const { icons } = await import('@iconify-json/logos');
537
- const { iconPacks = [], enableSupportForElkLayout = false } = window.eventcatalog.mermaid ?? {};
538
-
539
- if (iconPacks.length > 0) {
540
- const iconPacksToRegister = iconPacks.map((name: any) => {
541
- return {
542
- name,
543
- icons,
544
- };
545
- });
577
+ <script>
578
+ // Listen for Astro transititions
579
+ document.addEventListener('astro:page-load', () => {
580
+ const graphs = document.getElementsByClassName('mermaid');
581
+ if (document.getElementsByClassName('mermaid').length > 0) {
582
+ renderDiagrams(graphs);
583
+ }
584
+ });
546
585
 
547
- mermaid.registerIconPacks(iconPacksToRegister);
586
+ /**
587
+ * Renders mermaid diagrams in the page
588
+ * @param {HTMLCollectionOf<HTMLElement>} graphs - The collection of mermaid graph elements
589
+ */
590
+ async function renderDiagrams(graphs: any) {
591
+ const { default: mermaid } = await import('mermaid');
592
+
593
+ if (window.eventcatalog.mermaid) {
594
+ const { icons } = await import('@iconify-json/logos');
595
+ const { iconPacks = [], enableSupportForElkLayout = false } = window.eventcatalog.mermaid ?? {};
596
+
597
+ if (iconPacks.length > 0) {
598
+ const iconPacksToRegister = iconPacks.map((name: any) => {
599
+ return {
600
+ name,
601
+ icons,
602
+ };
603
+ });
604
+
605
+ mermaid.registerIconPacks(iconPacksToRegister);
606
+ }
607
+
608
+ if (enableSupportForElkLayout) {
609
+ // @ts-ignore
610
+ const { default: elkLayouts } = await import('@mermaid-js/layout-elk/dist/mermaid-layout-elk.core.mjs');
611
+ mermaid.registerLayoutLoaders(elkLayouts);
612
+ }
548
613
  }
549
614
 
550
- if (enableSupportForElkLayout) {
551
- // @ts-ignore
552
- const { default: elkLayouts } = await import('@mermaid-js/layout-elk/dist/mermaid-layout-elk.core.mjs');
553
- mermaid.registerLayoutLoaders(elkLayouts);
615
+ mermaid.initialize({
616
+ // fontSize: 2,
617
+ flowchart: {
618
+ curve: 'linear',
619
+ rankSpacing: 0,
620
+ nodeSpacing: 0,
621
+ },
622
+ startOnLoad: false,
623
+ fontFamily: 'var(--sans-font)',
624
+ // @ts-ignore This works, but TS expects a enum for some reason
625
+ theme: 'light',
626
+ architecture: {
627
+ useMaxWidth: true,
628
+ },
629
+ });
630
+
631
+ for (const graph of graphs) {
632
+ const content = graph.getAttribute('data-content');
633
+ if (!content) continue;
634
+ let svg = document.createElement('svg');
635
+ const id = (svg.id = 'mermaid-' + Math.round(Math.random() * 100000));
636
+ graph.appendChild(svg);
637
+ mermaid.render(id, content).then((result) => {
638
+ graph.innerHTML = result.svg;
639
+ });
554
640
  }
555
641
  }
556
642
 
557
- mermaid.initialize({
558
- // fontSize: 2,
559
- flowchart: {
560
- curve: 'linear',
561
- rankSpacing: 0,
562
- nodeSpacing: 0,
563
- },
564
- startOnLoad: false,
565
- fontFamily: 'var(--sans-font)',
566
- // @ts-ignore This works, but TS expects a enum for some reason
567
- theme: 'light',
568
- architecture: {
569
- useMaxWidth: true,
570
- },
571
- });
643
+ const graphs = document.getElementsByClassName('mermaid');
644
+ if (document.getElementsByClassName('mermaid').length > 0) {
645
+ renderDiagrams(graphs);
646
+ }
572
647
 
573
- for (const graph of graphs) {
574
- const content = graph.getAttribute('data-content');
575
- if (!content) continue;
576
- let svg = document.createElement('svg');
577
- const id = (svg.id = 'mermaid-' + Math.round(Math.random() * 100000));
578
- graph.appendChild(svg);
579
- mermaid.render(id, content).then((result) => {
580
- graph.innerHTML = result.svg;
648
+ // Make renderDiagrams available globally for accordion component
649
+ window.renderDiagrams = renderDiagrams;
650
+ </script>
651
+
652
+ <script>
653
+ import('pako').then(({ deflate }: any) => {
654
+ document.addEventListener('astro:page-load', () => {
655
+ const blocks = document.getElementsByClassName('plantuml');
656
+ if (blocks.length > 0) {
657
+ renderPlantUML(blocks, deflate);
658
+ }
581
659
  });
582
- }
583
- }
584
660
 
585
- const graphs = document.getElementsByClassName('mermaid');
586
- if (document.getElementsByClassName('mermaid').length > 0) {
587
- renderDiagrams(graphs);
588
- }
661
+ function renderPlantUML(blocks: any, deflate: any) {
662
+ for (const block of blocks) {
663
+ const content = block.getAttribute('data-content');
664
+ if (!content) continue;
665
+
666
+ const encoded = encodePlantUML(content, deflate);
667
+ const img = document.createElement('img');
668
+ img.src = `https://www.plantuml.com/plantuml/svg/~1${encoded}`;
669
+ img.alt = 'PlantUML diagram';
670
+ img.loading = 'lazy';
671
+ block.innerHTML = '';
672
+ // Add class to the img
673
+ img.classList.add('mx-auto');
674
+ block.appendChild(img);
675
+ }
676
+ }
589
677
 
590
- // Make renderDiagrams available globally for accordion component
591
- window.renderDiagrams = renderDiagrams;
592
- </script>
678
+ function encodePlantUML(text: any, deflate: any) {
679
+ const utf8encoded = new TextEncoder().encode(text);
680
+ const compressed = deflate(utf8encoded, { level: 9 });
681
+ return encode64(compressed);
682
+ }
593
683
 
594
- <script>
595
- import('pako').then(({ deflate }: any) => {
596
- document.addEventListener('astro:page-load', () => {
597
- const blocks = document.getElementsByClassName('plantuml');
598
- if (blocks.length > 0) {
599
- renderPlantUML(blocks, deflate);
684
+ const encode64 = (data: any) => {
685
+ const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_';
686
+ let str = '';
687
+ let i = 0;
688
+ while (i < data.length) {
689
+ let b1 = data[i++];
690
+ let b2 = i < data.length ? data[i++] : 0;
691
+ let b3 = i < data.length ? data[i++] : 0;
692
+
693
+ let c1 = b1 >> 2;
694
+ let c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
695
+ let c3 = ((b2 & 0xf) << 2) | (b3 >> 6);
696
+ let c4 = b3 & 0x3f;
697
+
698
+ str += chars[c1] + chars[c2] + chars[c3] + chars[c4];
699
+ }
700
+ return str;
701
+ };
702
+
703
+ const graphs = document.getElementsByClassName('plantuml');
704
+ if (document.getElementsByClassName('plantuml').length > 0) {
705
+ renderPlantUML(graphs, deflate);
600
706
  }
707
+
708
+ window.renderPlantUML = (graphs: any) => {
709
+ renderPlantUML(graphs, deflate);
710
+ };
601
711
  });
712
+ </script>
713
+ <script>
714
+ // @ts-nocheck
715
+ function setupObserver() {
716
+ try {
717
+ const observerOptions = {
718
+ rootMargin: '0px 0px -40% 0px',
719
+ threshold: 0.1,
720
+ };
721
+
722
+ // Flag to temporarily disable observer after click
723
+ let observerPaused = false;
724
+
725
+ // Function to highlight a TOC item
726
+ function highlightTocItem(id) {
727
+ // Remove active class from all links
728
+ document.querySelectorAll('.active-toc-item').forEach((link) => {
729
+ link.classList.remove('active-toc-item', 'text-purple-600', 'font-medium', 'border-purple-600');
730
+ link.classList.add('text-gray-500', 'border-transparent');
731
+ });
732
+
733
+ // Add active class to current link
734
+ const tocLink = document.querySelector(`nav a[href="#${id}"]`);
735
+ if (tocLink) {
736
+ tocLink.classList.add('active-toc-item', 'text-purple-600', 'font-medium', 'border-purple-600');
737
+ tocLink.classList.remove('text-gray-500', 'border-transparent');
738
+
739
+ // Scroll the highlighted item into view with a small delay to ensure DOM updates first
740
+ setTimeout(() => {
741
+ tocLink.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });
742
+ }, 10);
743
+ }
744
+ }
602
745
 
603
- function renderPlantUML(blocks: any, deflate: any) {
604
- for (const block of blocks) {
605
- const content = block.getAttribute('data-content');
606
- if (!content) continue;
746
+ // Set up the intersection observer for scrolling
747
+ const observer = new IntersectionObserver((entries) => {
748
+ // If observer is paused, don't process entries
749
+ if (observerPaused) return;
750
+
751
+ entries.forEach((entry) => {
752
+ try {
753
+ const id = entry.target.getAttribute('id');
754
+ if (entry.isIntersecting && id) {
755
+ highlightTocItem(id);
756
+ }
757
+ } catch (entryError) {
758
+ console.error('Error processing intersection entry:', entryError);
759
+ }
760
+ });
761
+ }, observerOptions);
762
+
763
+ // Find all headings in the content area within the .prose container to observe
764
+ const prose = document.querySelector('.prose');
765
+ if (!prose) {
766
+ console.warn('No .prose container found for TOC highlighting');
767
+ return;
768
+ }
607
769
 
608
- const encoded = encodePlantUML(content, deflate);
609
- const img = document.createElement('img');
610
- img.src = `https://www.plantuml.com/plantuml/svg/~1${encoded}`;
611
- img.alt = 'PlantUML diagram';
612
- img.loading = 'lazy';
613
- block.innerHTML = '';
614
- // Add class to the img
615
- img.classList.add('mx-auto');
616
- block.appendChild(img);
617
- }
618
- }
770
+ // First try to find headings with IDs
771
+ const headings = prose.querySelectorAll('h1[id], h2[id], h3[id]');
772
+
773
+ if (headings.length > 0) {
774
+ headings.forEach((heading) => {
775
+ observer.observe(heading);
776
+ });
777
+ } else {
778
+ // Fallback: If no headings with IDs found, attach IDs to them
779
+ const allHeadings = prose.querySelectorAll('h1, h2, h3');
780
+
781
+ allHeadings.forEach((heading) => {
782
+ // Only add ID if it doesn't exist
783
+ if (!heading.id) {
784
+ const text = heading.textContent || '';
785
+ const slug = text
786
+ .toLowerCase()
787
+ .replace(/[^\w\s-]/g, '')
788
+ .replace(/\s+/g, '-');
789
+ heading.id = slug;
790
+ }
791
+ observer.observe(heading);
792
+ });
793
+ }
619
794
 
620
- function encodePlantUML(text: any, deflate: any) {
621
- const utf8encoded = new TextEncoder().encode(text);
622
- const compressed = deflate(utf8encoded, { level: 9 });
623
- return encode64(compressed);
624
- }
795
+ // Add click event listeners to all TOC links
796
+ const tocLinks = document.querySelectorAll('nav a[href^="#"]');
797
+ tocLinks.forEach((link) => {
798
+ link.addEventListener('click', (e) => {
799
+ // Get the ID from the href attribute
800
+ const hrefAttr = link.getAttribute('href');
801
+ if (!hrefAttr) return;
625
802
 
626
- const encode64 = (data: any) => {
627
- const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_';
628
- let str = '';
629
- let i = 0;
630
- while (i < data.length) {
631
- let b1 = data[i++];
632
- let b2 = i < data.length ? data[i++] : 0;
633
- let b3 = i < data.length ? data[i++] : 0;
634
-
635
- let c1 = b1 >> 2;
636
- let c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
637
- let c3 = ((b2 & 0xf) << 2) | (b3 >> 6);
638
- let c4 = b3 & 0x3f;
639
-
640
- str += chars[c1] + chars[c2] + chars[c3] + chars[c4];
641
- }
642
- return str;
643
- };
803
+ const id = hrefAttr.substring(1);
644
804
 
645
- const graphs = document.getElementsByClassName('plantuml');
646
- if (document.getElementsByClassName('plantuml').length > 0) {
647
- renderPlantUML(graphs, deflate);
805
+ // Highlight the clicked item
806
+ highlightTocItem(id);
807
+
808
+ // Temporarily pause the observer to prevent immediate highlighting changes
809
+ observerPaused = true;
810
+
811
+ // Resume the observer after a delay (1.5 seconds)
812
+ setTimeout(() => {
813
+ observerPaused = false;
814
+ }, 500);
815
+ });
816
+ });
817
+ } catch (error) {
818
+ console.error('Error setting up TOC highlighting:', error);
819
+ }
648
820
  }
649
821
 
650
- window.renderPlantUML = (graphs: any) => {
651
- renderPlantUML(graphs, deflate);
652
- };
653
- });
654
- </script>
822
+ setupObserver();
823
+
824
+ document.addEventListener('astro:page-load', setupObserver);
825
+ </script>
826
+ </main>
655
827
  </VerticalSideBarLayout>
@@ -4,7 +4,7 @@
4
4
 
5
5
  import type { APIRoute } from 'astro';
6
6
  import { getCollection } from 'astro:content';
7
- import { getEntities } from '@utils/entities';
7
+ import { getEntities } from '@utils/collections/entities';
8
8
  import config from '@config';
9
9
  import fs from 'fs';
10
10