@bendyline/squisq 1.5.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -10
- package/dist/{Doc-BBVGq1_9.d.ts → Doc-ylqWKDc_.d.ts} +248 -37
- package/dist/{ImageEditDoc-FuyGtt6o.d.ts → ImageEditDoc-D828IXJ1.d.ts} +1 -1
- package/dist/annotationCoercion-Dr_DY9Hx.d.ts +86 -0
- package/dist/{chunk-VWUFZ6ZG.js → chunk-3E5F2XMR.js} +2 -29
- package/dist/chunk-3E5F2XMR.js.map +1 -0
- package/dist/chunk-4X3JQXNM.js +35 -0
- package/dist/chunk-4X3JQXNM.js.map +1 -0
- package/dist/{chunk-2OIBZYKP.js → chunk-5DKBFXPY.js} +31 -121
- package/dist/chunk-5DKBFXPY.js.map +1 -0
- package/dist/{chunk-DLXZMS5K.js → chunk-5J4HKRJF.js} +51 -3
- package/dist/chunk-5J4HKRJF.js.map +1 -0
- package/dist/chunk-5UYI3RJB.js +2503 -0
- package/dist/chunk-5UYI3RJB.js.map +1 -0
- package/dist/{chunk-TEEEILMP.js → chunk-66QO7XFB.js} +19 -292
- package/dist/chunk-66QO7XFB.js.map +1 -0
- package/dist/{chunk-KKNUBQ6Y.js → chunk-6PJRB2CF.js} +156 -91
- package/dist/chunk-6PJRB2CF.js.map +1 -0
- package/dist/{chunk-HWVFJAAH.js → chunk-AMIR72JP.js} +28 -10
- package/dist/chunk-AMIR72JP.js.map +1 -0
- package/dist/chunk-FVJUUTEM.js +74 -0
- package/dist/chunk-FVJUUTEM.js.map +1 -0
- package/dist/{chunk-LH7I6SH7.js → chunk-GF3BVNLU.js} +6360 -5723
- package/dist/chunk-GF3BVNLU.js.map +1 -0
- package/dist/{chunk-Q3ROPT5H.js → chunk-GZY66SDN.js} +1 -1
- package/dist/{chunk-Q3ROPT5H.js.map → chunk-GZY66SDN.js.map} +1 -1
- package/dist/chunk-JOQYPRDZ.js +127 -0
- package/dist/chunk-JOQYPRDZ.js.map +1 -0
- package/dist/{chunk-A4O7GIWE.js → chunk-LYNJEOAC.js} +10 -73
- package/dist/chunk-LYNJEOAC.js.map +1 -0
- package/dist/{chunk-LDQ2HJIX.js → chunk-PXLVXTLW.js} +252 -54
- package/dist/chunk-PXLVXTLW.js.map +1 -0
- package/dist/{chunk-TQWLI6S2.js → chunk-Q7LROV2H.js} +4 -2
- package/dist/{chunk-TQWLI6S2.js.map → chunk-Q7LROV2H.js.map} +1 -1
- package/dist/{chunk-T5UK6YOB.js → chunk-QTSJOY54.js} +60 -17
- package/dist/chunk-QTSJOY54.js.map +1 -0
- package/dist/chunk-QVANWDPH.js +2358 -0
- package/dist/chunk-QVANWDPH.js.map +1 -0
- package/dist/{chunk-6ATE2PSM.js → chunk-R2GC6RLD.js} +7 -7
- package/dist/chunk-R2GC6RLD.js.map +1 -0
- package/dist/chunk-R2YZTCLO.js +292 -0
- package/dist/chunk-R2YZTCLO.js.map +1 -0
- package/dist/chunk-S7A5D7ZJ.js +174 -0
- package/dist/chunk-S7A5D7ZJ.js.map +1 -0
- package/dist/chunk-T3TI7GSZ.js +884 -0
- package/dist/chunk-T3TI7GSZ.js.map +1 -0
- package/dist/{chunk-RUDYOTA6.js → chunk-TUWMK62B.js} +110 -4
- package/dist/chunk-TUWMK62B.js.map +1 -0
- package/dist/{chunk-IMSCRLLV.js → chunk-VR7UPJ7C.js} +35 -25
- package/dist/chunk-VR7UPJ7C.js.map +1 -0
- package/dist/doc/index.d.ts +2334 -5
- package/dist/doc/index.js +134 -34
- package/dist/generate/index.d.ts +7 -2
- package/dist/generate/index.js +1 -1
- package/dist/imageEdit/index.d.ts +9 -6
- package/dist/imageEdit/index.js +3 -3
- package/dist/index.d.ts +12 -10
- package/dist/index.js +253 -81
- package/dist/jsonForm/index.d.ts +7 -3
- package/dist/jsonForm/index.js +9 -4
- package/dist/markdown/index.d.ts +6 -70
- package/dist/markdown/index.js +13 -9
- package/dist/narration/index.d.ts +618 -0
- package/dist/narration/index.js +82 -0
- package/dist/recommend/index.d.ts +15 -1
- package/dist/recommend/index.js +2 -2
- package/dist/schemas/index.d.ts +28 -6
- package/dist/schemas/index.js +15 -13
- package/dist/spatial/index.d.ts +0 -1
- package/dist/spatial/index.js +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/{themeLibrary-CehcJhzz.d.ts → themeLibrary-RjVgLpUi.d.ts} +10 -11
- package/dist/timing/index.js +5 -3
- package/dist/transform/index.d.ts +35 -24
- package/dist/transform/index.js +9 -10
- package/dist/{types-DlAZ7MW4.d.ts → types-BwMPl2CB.d.ts} +1 -1
- package/dist/{types-D98li1gV.d.ts → types-C4kiRn_k.d.ts} +3 -1
- package/dist/versions/index.d.ts +2 -1
- package/dist/versions/index.js +2 -2
- package/package.json +6 -6
- package/src/__tests__/applyNarrationTiming.test.ts +190 -0
- package/src/__tests__/applyRenderStyle.test.ts +3 -3
- package/src/__tests__/asciiDiagramBattle.test.ts +246 -0
- package/src/__tests__/asciiDiagramDetect.test.ts +162 -0
- package/src/__tests__/asciiDiagramMapping.test.ts +38 -0
- package/src/__tests__/asciiDiagramParse.test.ts +233 -0
- package/src/__tests__/asciiDiagramPipeline.test.ts +273 -0
- package/src/__tests__/asciiDiagramRender.test.ts +162 -0
- package/src/__tests__/asciiDiagramRepair.test.ts +84 -0
- package/src/__tests__/asciiTimelineDetect.test.ts +157 -0
- package/src/__tests__/asciiTimelineParse.test.ts +205 -0
- package/src/__tests__/asciiTimelinePipeline.test.ts +349 -0
- package/src/__tests__/asciiTimelineRender.test.ts +376 -0
- package/src/__tests__/attrTokens.test.ts +5 -0
- package/src/__tests__/contentContainer.test.ts +43 -0
- package/src/__tests__/coverBlock.test.ts +33 -2
- package/src/__tests__/customTemplatesFrontmatter.test.ts +0 -15
- package/src/__tests__/dataTable.test.ts +25 -15
- package/src/__tests__/diagramBlock.test.ts +3 -3
- package/src/__tests__/diagramText.test.ts +26 -0
- package/src/__tests__/docToMarkdownMedia.test.ts +83 -0
- package/src/__tests__/drawingBlock.test.ts +3 -3
- package/src/__tests__/fixtures/asciiDiagramBattle.ts +512 -0
- package/src/__tests__/fixtures/asciiDiagrams.ts +287 -0
- package/src/__tests__/fixtures/asciiTimelines.ts +35 -0
- package/src/__tests__/fixtures/treeviewFixtures.ts +243 -0
- package/src/__tests__/getLayers.test.ts +32 -18
- package/src/__tests__/getLayersFallback.test.ts +8 -8
- package/src/__tests__/imageEditVersions.test.ts +2 -0
- package/src/__tests__/jsonForm.pointer.test.ts +47 -1
- package/src/__tests__/layoutBlock.test.ts +3 -3
- package/src/__tests__/majorApiTypes.test.ts +18 -0
- package/src/__tests__/markdown.test.ts +41 -0
- package/src/__tests__/markdownToDoc.test.ts +5 -2
- package/src/__tests__/matchFontFamily.test.ts +114 -0
- package/src/__tests__/materializeBlockLayers.test.ts +135 -0
- package/src/__tests__/materializeTestUtils.ts +17 -0
- package/src/__tests__/narrationAlign.test.ts +150 -0
- package/src/__tests__/narrationFeatures.test.ts +71 -0
- package/src/__tests__/narrationNuclei.test.ts +45 -0
- package/src/__tests__/narrationPacing.test.ts +189 -0
- package/src/__tests__/narrationScript.test.ts +149 -0
- package/src/__tests__/narrationSessionRepro.test.ts +62 -0
- package/src/__tests__/narrationSidecar.test.ts +88 -0
- package/src/__tests__/narrationSyllables.test.ts +65 -0
- package/src/__tests__/narrationTestSignals.ts +167 -0
- package/src/__tests__/narrationVad.test.ts +66 -0
- package/src/__tests__/resolveDocTheme.test.ts +16 -2
- package/src/__tests__/rootExports.test.ts +18 -0
- package/src/__tests__/scopedContentContainer.test.ts +20 -0
- package/src/__tests__/shapeGeometry.test.ts +49 -0
- package/src/__tests__/templateAnnotationParse.test.ts +10 -0
- package/src/__tests__/templateInputs.test.ts +69 -0
- package/src/__tests__/templateMetadata.test.ts +2 -1
- package/src/__tests__/templates.test.ts +143 -17
- package/src/__tests__/themeCompile.test.ts +49 -22
- package/src/__tests__/transformProvenance.test.ts +160 -0
- package/src/__tests__/transformV2.test.ts +40 -14
- package/src/__tests__/treeviewBattle.test.ts +76 -0
- package/src/__tests__/treeviewDetect.test.ts +168 -0
- package/src/__tests__/treeviewParse.test.ts +118 -0
- package/src/__tests__/treeviewPipeline.test.ts +183 -0
- package/src/__tests__/treeviewRender.test.ts +91 -0
- package/src/__tests__/versions.test.ts +44 -0
- package/src/doc/applyNarrationTiming.ts +244 -0
- package/src/doc/asciiDiagram/chars.ts +210 -0
- package/src/doc/asciiDiagram/detect.ts +175 -0
- package/src/doc/asciiDiagram/index.ts +38 -0
- package/src/doc/asciiDiagram/mapping.ts +225 -0
- package/src/doc/asciiDiagram/parse.ts +1095 -0
- package/src/doc/asciiDiagram/render.ts +963 -0
- package/src/doc/asciiDiagram/repair.ts +400 -0
- package/src/doc/asciiDiagram/types.ts +65 -0
- package/src/doc/asciiTimeline/detect.ts +138 -0
- package/src/doc/asciiTimeline/index.ts +26 -0
- package/src/doc/asciiTimeline/mapping.ts +43 -0
- package/src/doc/asciiTimeline/parse.ts +870 -0
- package/src/doc/asciiTimeline/render.ts +427 -0
- package/src/doc/asciiTimeline/types.ts +73 -0
- package/src/doc/asciiTimeline/wrappedFlow.ts +427 -0
- package/src/doc/audioMapping.ts +60 -46
- package/src/doc/customTemplatesFrontmatter.ts +0 -41
- package/src/doc/docToMarkdown.ts +126 -39
- package/src/doc/index.ts +76 -4
- package/src/doc/markdownToDoc.ts +135 -1
- package/src/doc/materializeBlockLayers.ts +304 -0
- package/src/doc/mediaAnnotations.ts +20 -0
- package/src/doc/resolveDocTheme.ts +8 -7
- package/src/doc/templateInputs.ts +185 -2
- package/src/doc/templates/__tests__/customTemplateRegistry.test.ts +22 -8
- package/src/doc/templates/coverBlock.ts +49 -13
- package/src/doc/templates/diagramBlock.ts +237 -38
- package/src/doc/templates/drawingBlock.ts +2 -2
- package/src/doc/templates/fallbackBlock.ts +1 -1
- package/src/doc/templates/index.ts +134 -279
- package/src/doc/templates/inputDescriptors.ts +20 -1
- package/src/doc/templates/metadata.ts +10 -0
- package/src/doc/templates/persistentLayers.ts +12 -126
- package/src/doc/templates/registry.ts +88 -0
- package/src/doc/templates/templateNames.ts +22 -0
- package/src/doc/templates/timelineBlock.ts +613 -0
- package/src/doc/templates/treeBlock.ts +131 -0
- package/src/doc/treeview/chars.ts +72 -0
- package/src/doc/treeview/detect.ts +145 -0
- package/src/doc/treeview/index.ts +30 -0
- package/src/doc/treeview/mapping.ts +95 -0
- package/src/doc/treeview/parse.ts +201 -0
- package/src/doc/treeview/render.ts +41 -0
- package/src/doc/treeview/types.ts +43 -0
- package/src/doc/utils/applyRenderStyle.ts +2 -9
- package/src/doc/utils/diagramText.ts +78 -0
- package/src/doc/utils/shapeGeometry.ts +157 -7
- package/src/doc/validate.ts +1 -1
- package/src/generate/templateMapper.ts +7 -0
- package/src/imageEdit/export.ts +6 -5
- package/src/imageEdit/versionPaths.ts +13 -26
- package/src/imageEdit/versions.ts +21 -100
- package/src/index.ts +1 -0
- package/src/internal/immutable.ts +58 -0
- package/src/jsonForm/index.ts +9 -1
- package/src/jsonForm/pointer.ts +68 -23
- package/src/markdown/attrTokens.ts +7 -5
- package/src/markdown/convert.ts +11 -1
- package/src/markdown/index.ts +1 -0
- package/src/markdown/stringify.ts +4 -9
- package/src/markdown/utils.ts +36 -14
- package/src/narration/align.ts +514 -0
- package/src/narration/features.ts +231 -0
- package/src/narration/index.ts +86 -0
- package/src/narration/nuclei.ts +118 -0
- package/src/narration/pacing.ts +211 -0
- package/src/narration/script.ts +239 -0
- package/src/narration/session.ts +100 -0
- package/src/narration/sidecar.ts +187 -0
- package/src/narration/syllables.ts +85 -0
- package/src/narration/trace.ts +50 -0
- package/src/narration/types.ts +299 -0
- package/src/narration/vad.ts +131 -0
- package/src/recommend/numberHighlight.ts +25 -0
- package/src/recommend/templates.ts +108 -12
- package/src/schemas/BlockTemplates.ts +156 -7
- package/src/schemas/Doc.ts +72 -9
- package/src/schemas/Media.ts +12 -2
- package/src/schemas/Theme.ts +45 -25
- package/src/schemas/Viewport.ts +2 -2
- package/src/schemas/fontStacks.ts +79 -0
- package/src/schemas/themeCompile.ts +15 -0
- package/src/schemas/themeConstants.ts +2 -0
- package/src/schemas/themeLibrary.ts +25 -19
- package/src/schemas/themeValidator.ts +1 -1
- package/src/spatial/Geohash.ts +0 -3
- package/src/storage/ContentContainer.ts +17 -9
- package/src/storage/ScopedContentContainer.ts +45 -15
- package/src/transform/applyTransform.ts +5 -5
- package/src/transform/index.ts +3 -1
- package/src/transform/registry.ts +169 -49
- package/src/transform/templateSelector.ts +21 -2
- package/src/transform/timingAllocator.ts +152 -21
- package/src/transform/types.ts +14 -1
- package/src/versions/gitignore.ts +34 -0
- package/src/versions/index.ts +2 -0
- package/src/versions/operations.ts +18 -104
- package/src/versions/paths.ts +13 -28
- package/src/versions/snapshotStore.ts +202 -0
- package/src/versions/types.ts +3 -1
- package/dist/chunk-2OIBZYKP.js.map +0 -1
- package/dist/chunk-6ATE2PSM.js.map +0 -1
- package/dist/chunk-A4O7GIWE.js.map +0 -1
- package/dist/chunk-DLXZMS5K.js.map +0 -1
- package/dist/chunk-HWVFJAAH.js.map +0 -1
- package/dist/chunk-IMSCRLLV.js.map +0 -1
- package/dist/chunk-JELIRVDP.js +0 -24
- package/dist/chunk-JELIRVDP.js.map +0 -1
- package/dist/chunk-KKNUBQ6Y.js.map +0 -1
- package/dist/chunk-LDQ2HJIX.js.map +0 -1
- package/dist/chunk-LH7I6SH7.js.map +0 -1
- package/dist/chunk-RUDYOTA6.js.map +0 -1
- package/dist/chunk-T5UK6YOB.js.map +0 -1
- package/dist/chunk-TEEEILMP.js.map +0 -1
- package/dist/chunk-UY7KGQ5R.js +0 -192
- package/dist/chunk-UY7KGQ5R.js.map +0 -1
- package/dist/chunk-VLJJHDAC.js +0 -218
- package/dist/chunk-VLJJHDAC.js.map +0 -1
- package/dist/chunk-VWUFZ6ZG.js.map +0 -1
- package/dist/story/index.d.ts +0 -1777
- package/dist/story/index.js +0 -273
- package/src/doc/getLayers.ts +0 -195
- /package/dist/{story → narration}/index.js.map +0 -0
|
@@ -98,9 +98,9 @@ describe('diagramBlock template', () => {
|
|
|
98
98
|
});
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
-
describe('diagramBlock integration with
|
|
101
|
+
describe('diagramBlock integration with materializeBlockLayers', () => {
|
|
102
102
|
it('renders through the full template registry', async () => {
|
|
103
|
-
const {
|
|
103
|
+
const { materializeBlockLayers } = await import('../doc/materializeBlockLayers.js');
|
|
104
104
|
const parentBlock: Block = {
|
|
105
105
|
id: 'family',
|
|
106
106
|
startTime: 0,
|
|
@@ -113,7 +113,7 @@ describe('diagramBlock integration with getLayers', () => {
|
|
|
113
113
|
makeBlock({ id: 'b', title: 'B', x: 400, y: 100, connectsTo: [{ target: 'a' }] }),
|
|
114
114
|
],
|
|
115
115
|
};
|
|
116
|
-
const layers =
|
|
116
|
+
const layers = materializeBlockLayers(parentBlock, { persistentLayers: false }).layers;
|
|
117
117
|
// Should contain at least one shape (node card) and one path (edge).
|
|
118
118
|
const types = new Set(layers.map((l: Layer) => l.type));
|
|
119
119
|
expect(types.has('shape')).toBe(true);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { DIAGRAM_LABEL_LINE_HEIGHT, fitDiagramLabel } from '../doc/utils/diagramText';
|
|
3
|
+
|
|
4
|
+
describe('fitDiagramLabel', () => {
|
|
5
|
+
it('keeps a short single-line label at its preferred size', () => {
|
|
6
|
+
expect(fitDiagramLabel('Web1', 180, 64, 22)).toMatchObject({
|
|
7
|
+
fontSize: 22,
|
|
8
|
+
lineCount: 1,
|
|
9
|
+
firstLineOffset: 0,
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('shrinks and centers a dense multi-line package label inside its card', () => {
|
|
14
|
+
const fit = fitDiagramLabel(
|
|
15
|
+
'@bendyline/molen-kernel\nheadless sim — no DOM, no thread\nWorker + Node',
|
|
16
|
+
252,
|
|
17
|
+
112,
|
|
18
|
+
38,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(fit.fontSize).toBeLessThan(38);
|
|
22
|
+
expect(fit.lineCount).toBeGreaterThanOrEqual(3);
|
|
23
|
+
expect(fit.lineCount * fit.fontSize * DIAGRAM_LABEL_LINE_HEIGHT).toBeLessThanOrEqual(96);
|
|
24
|
+
expect(fit.firstLineOffset).toBeLessThan(0);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseMarkdown, stringifyMarkdown } from '../markdown/index';
|
|
3
|
+
import { markdownToDoc } from '../doc/markdownToDoc';
|
|
4
|
+
import { docToMarkdown } from '../doc/docToMarkdown';
|
|
5
|
+
|
|
6
|
+
/** One full normalization cycle: md → doc → md. */
|
|
7
|
+
function normalize(markdown: string): string {
|
|
8
|
+
return stringifyMarkdown(docToMarkdown(markdownToDoc(parseMarkdown(markdown))));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Byte-stability convention: stable after one normalization cycle. */
|
|
12
|
+
function expectStable(markdown: string): string {
|
|
13
|
+
const once = normalize(markdown);
|
|
14
|
+
const twice = normalize(once);
|
|
15
|
+
expect(twice).toBe(once);
|
|
16
|
+
return once;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('docToMarkdown media round-trip', () => {
|
|
20
|
+
it('preserves a preamble document-anchored narration annotation', () => {
|
|
21
|
+
const md = `{[audio src=audio/narration-001.webm anchor=document]}\n\n# Hello\n\nBody text.\n`;
|
|
22
|
+
const once = expectStable(md);
|
|
23
|
+
expect(once).toContain('{[audio src=audio/narration-001.webm anchor=document]}');
|
|
24
|
+
// It must come back at the TOP (before the first heading) so reparsing
|
|
25
|
+
// yields documentMedia again.
|
|
26
|
+
expect(once.indexOf('{[audio')).toBeLessThan(once.indexOf('# Hello'));
|
|
27
|
+
const reparsed = markdownToDoc(parseMarkdown(once));
|
|
28
|
+
expect(reparsed.documentMedia?.length).toBe(1);
|
|
29
|
+
expect(reparsed.documentMedia![0].anchor).toBe('document');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('preserves a block-level clip mid-contents with params', () => {
|
|
33
|
+
const md = `# Scene\n\nLead-in paragraph.\n\n{[video src=video/b.mp4 startAt=2 clipStart=1 clipEnd=9 spillover=true]}\n\nTrailing paragraph.\n`;
|
|
34
|
+
const once = expectStable(md);
|
|
35
|
+
expect(once).toContain(
|
|
36
|
+
'{[video src=video/b.mp4 startAt=2 clipStart=1 clipEnd=9 spillover=true]}',
|
|
37
|
+
);
|
|
38
|
+
// Original position: after the lead-in, before the trailing paragraph.
|
|
39
|
+
expect(once.indexOf('Lead-in')).toBeLessThan(once.indexOf('{[video'));
|
|
40
|
+
expect(once.indexOf('{[video')).toBeLessThan(once.indexOf('Trailing'));
|
|
41
|
+
const reparsed = markdownToDoc(parseMarkdown(once));
|
|
42
|
+
const withMedia = reparsed.blocks.find((b) => b.media && b.media.length > 0);
|
|
43
|
+
expect(withMedia?.media?.[0].clipStart).toBe(1);
|
|
44
|
+
expect(withMedia?.media?.[0].spillover).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('preserves a document-anchored annotation authored inside a section body', () => {
|
|
48
|
+
const md = `# Section\n\nSome text.\n\n{[audio src=audio/full.mp3 anchor=document startAt=0:30]}\n\nMore text.\n`;
|
|
49
|
+
const once = expectStable(md);
|
|
50
|
+
// Raw text passthrough keeps the mm:ss time form byte-identical.
|
|
51
|
+
expect(once).toContain('{[audio src=audio/full.mp3 anchor=document startAt=0:30]}');
|
|
52
|
+
const reparsed = markdownToDoc(parseMarkdown(once));
|
|
53
|
+
expect(reparsed.documentMedia?.[0].startAt).toBe(30);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('preserves quoted srcs with spaces', () => {
|
|
57
|
+
const md = `{[audio src="audio/my take.webm" anchor=document]}\n\n# Doc\n\nText.\n`;
|
|
58
|
+
const once = expectStable(md);
|
|
59
|
+
expect(once).toContain('src="audio/my take.webm"');
|
|
60
|
+
const reparsed = markdownToDoc(parseMarkdown(once));
|
|
61
|
+
expect(reparsed.documentMedia?.[0].src).toBe('audio/my take.webm');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('emits programmatic doc clips (no origin) at the document top canonically', () => {
|
|
65
|
+
const doc = markdownToDoc(parseMarkdown('# Title\n\nBody.\n'));
|
|
66
|
+
doc.documentMedia = [
|
|
67
|
+
{ id: 'clip-1', src: 'audio/take.webm', kind: 'audio', startAt: 0, anchor: 'document' },
|
|
68
|
+
];
|
|
69
|
+
const md = stringifyMarkdown(docToMarkdown(doc));
|
|
70
|
+
expect(md).toContain('{[audio src=audio/take.webm anchor=document]}');
|
|
71
|
+
expect(md.indexOf('{[audio')).toBeLessThan(md.indexOf('# Title'));
|
|
72
|
+
// And the emission itself round-trips.
|
|
73
|
+
const reparsed = markdownToDoc(parseMarkdown(md));
|
|
74
|
+
expect(reparsed.documentMedia?.length).toBe(1);
|
|
75
|
+
expect(stringifyMarkdown(docToMarkdown(reparsed))).toBe(md);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('leaves docs without media untouched', () => {
|
|
79
|
+
const md = `# Plain\n\nNothing to see.\n`;
|
|
80
|
+
const once = expectStable(md);
|
|
81
|
+
expect(once).not.toContain('{[audio');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -90,9 +90,9 @@ describe('drawingBlock template', () => {
|
|
|
90
90
|
});
|
|
91
91
|
});
|
|
92
92
|
|
|
93
|
-
describe('drawingBlock integration with
|
|
93
|
+
describe('drawingBlock integration with materializeBlockLayers', () => {
|
|
94
94
|
it('renders a drawing block through the template registry', async () => {
|
|
95
|
-
const {
|
|
95
|
+
const { materializeBlockLayers } = await import('../doc/materializeBlockLayers.js');
|
|
96
96
|
const parent: Block = {
|
|
97
97
|
id: 'sketch',
|
|
98
98
|
startTime: 0,
|
|
@@ -116,7 +116,7 @@ describe('drawingBlock integration with getLayers', () => {
|
|
|
116
116
|
shape('l', 'arrow', { from: 'ceo', to: 'dev' }, { title: 'manages' }),
|
|
117
117
|
],
|
|
118
118
|
};
|
|
119
|
-
const layers =
|
|
119
|
+
const layers = materializeBlockLayers(parent, { persistentLayers: false }).layers;
|
|
120
120
|
const types = new Set(layers.map((l: Layer) => l.type));
|
|
121
121
|
expect(types.has('shape')).toBe(true);
|
|
122
122
|
expect(types.has('path')).toBe(true);
|
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Battle-test corpus: a broad, category-organized set of AI-style ASCII
|
|
3
|
+
* diagrams, each with its intended semantics. Every fixture here is
|
|
4
|
+
* verified to (a) detect as a diagram, (b) parse to exactly these
|
|
5
|
+
* nodes/edges/containers, and (c) survive the render↔parse fixpoint
|
|
6
|
+
* byte-stably. See asciiDiagramBattle.test.ts.
|
|
7
|
+
*
|
|
8
|
+
* GENERATED by scratchpad/gen-battle-fixtures.mjs — edit there and re-run.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface BattleDiagram {
|
|
12
|
+
name: string;
|
|
13
|
+
category: string;
|
|
14
|
+
art: string;
|
|
15
|
+
/** Expected node ids (order-independent). */
|
|
16
|
+
nodes: string[];
|
|
17
|
+
/** Expected edges: [source, target, label?, directed?]. directed defaults true. */
|
|
18
|
+
edges: Array<[string, string, (string | undefined)?, boolean?]>;
|
|
19
|
+
/** Expected containment: childId → containerId. */
|
|
20
|
+
containers?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const BATTLE_DIAGRAMS: BattleDiagram[] = [
|
|
24
|
+
{
|
|
25
|
+
name: 'linearEtl',
|
|
26
|
+
category: 'linear',
|
|
27
|
+
art: `┌─────────┐ ┌───────────┐ ┌──────────┐
|
|
28
|
+
│ Extract │ ──> │ Transform │ ──> │ Load │
|
|
29
|
+
└─────────┘ └───────────┘ └──────────┘`,
|
|
30
|
+
nodes: ['extract', 'transform', 'load'],
|
|
31
|
+
edges: [
|
|
32
|
+
['extract', 'transform'],
|
|
33
|
+
['transform', 'load'],
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'requestLifecycle',
|
|
38
|
+
category: 'linear',
|
|
39
|
+
art: `┌────────┐ ┌───────────────┐ ┌─────────┐ ┌──────────┐
|
|
40
|
+
│ Client │───>│ Load Balancer │───>│ API │───>│ Database │
|
|
41
|
+
└────────┘ └───────────────┘ └─────────┘ └──────────┘`,
|
|
42
|
+
nodes: ['client', 'load-balancer', 'api', 'database'],
|
|
43
|
+
edges: [
|
|
44
|
+
['client', 'load-balancer'],
|
|
45
|
+
['load-balancer', 'api'],
|
|
46
|
+
['api', 'database'],
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'deployPipelineAscii',
|
|
51
|
+
category: 'linear',
|
|
52
|
+
art: `+-------+ +------+ +-------+ +--------+
|
|
53
|
+
| Build | --> | Test | --> | Stage | --> | Deploy |
|
|
54
|
+
+-------+ +------+ +-------+ +--------+`,
|
|
55
|
+
nodes: ['build', 'test', 'stage', 'deploy'],
|
|
56
|
+
edges: [
|
|
57
|
+
['build', 'test'],
|
|
58
|
+
['test', 'stage'],
|
|
59
|
+
['stage', 'deploy'],
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'mlPipeline',
|
|
64
|
+
category: 'linear',
|
|
65
|
+
art: `┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
66
|
+
│ Data │──►│ Features │──►│ Train │──►│ Model │
|
|
67
|
+
└──────────┘ └──────────┘ └────┬─────┘ └──────────┘
|
|
68
|
+
│ metrics
|
|
69
|
+
▼
|
|
70
|
+
┌──────────┐
|
|
71
|
+
│ Evaluate │
|
|
72
|
+
└──────────┘`,
|
|
73
|
+
nodes: ['data', 'features', 'train', 'model', 'evaluate'],
|
|
74
|
+
edges: [
|
|
75
|
+
['data', 'features'],
|
|
76
|
+
['features', 'train'],
|
|
77
|
+
['train', 'model'],
|
|
78
|
+
['train', 'evaluate', 'metrics'],
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'approvalFlow',
|
|
83
|
+
category: 'linear',
|
|
84
|
+
art: `┌─────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐
|
|
85
|
+
│ Draft │──►│ Review │──►│ Approved │──►│ Published │
|
|
86
|
+
└─────────┘ └──────────┘ └──────────┘ └───────────┘`,
|
|
87
|
+
nodes: ['draft', 'review', 'approved', 'published'],
|
|
88
|
+
edges: [
|
|
89
|
+
['draft', 'review'],
|
|
90
|
+
['review', 'approved'],
|
|
91
|
+
['approved', 'published'],
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'loadBalancerFanout',
|
|
96
|
+
category: 'fan-out',
|
|
97
|
+
art: ` ┌───────────────┐
|
|
98
|
+
│ Load Balancer │
|
|
99
|
+
└──┬──┬──┬──┬───┘
|
|
100
|
+
┌──────┘ │ │ └──────┐
|
|
101
|
+
▼ ▼ ▼ ▼
|
|
102
|
+
┌──────┐┌──────┐┌──────┐┌──────┐
|
|
103
|
+
│ Web1 ││ Web2 ││ Web3 ││ Web4 │
|
|
104
|
+
└──────┘└──────┘└──────┘└──────┘`,
|
|
105
|
+
nodes: ['load-balancer', 'web1', 'web2', 'web3', 'web4'],
|
|
106
|
+
edges: [
|
|
107
|
+
['load-balancer', 'web1'],
|
|
108
|
+
['load-balancer', 'web2'],
|
|
109
|
+
['load-balancer', 'web3'],
|
|
110
|
+
['load-balancer', 'web4'],
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'pubsubBroker',
|
|
115
|
+
category: 'fan-out',
|
|
116
|
+
art: ` ┌──────────┐ ┌──────────┐
|
|
117
|
+
│ Producer │─────►│ Broker │
|
|
118
|
+
└──────────┘ └─┬──┬──┬──┘
|
|
119
|
+
┌─────────┘ │ └─────────┐
|
|
120
|
+
▼ ▼ ▼
|
|
121
|
+
┌──────────┐┌──────────┐┌──────────┐
|
|
122
|
+
│ Sub1 ││ Sub2 ││ Sub3 │
|
|
123
|
+
└──────────┘└──────────┘└──────────┘`,
|
|
124
|
+
nodes: ['producer', 'broker', 'sub1', 'sub2', 'sub3'],
|
|
125
|
+
edges: [
|
|
126
|
+
['producer', 'broker'],
|
|
127
|
+
['broker', 'sub1'],
|
|
128
|
+
['broker', 'sub2'],
|
|
129
|
+
['broker', 'sub3'],
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'collectorFanin',
|
|
134
|
+
category: 'fan-in',
|
|
135
|
+
art: `┌────┐ ┌────┐ ┌────┐
|
|
136
|
+
│ S1 │ │ S2 │ │ S3 │
|
|
137
|
+
└─┬──┘ └─┬──┘ └─┬──┘
|
|
138
|
+
│ │ │
|
|
139
|
+
▼ ▼ ▼
|
|
140
|
+
┌─────────────────────┐
|
|
141
|
+
│ Collector │
|
|
142
|
+
└─────────────────────┘`,
|
|
143
|
+
nodes: ['s1', 's2', 's3', 'collector'],
|
|
144
|
+
edges: [
|
|
145
|
+
['s1', 'collector'],
|
|
146
|
+
['s2', 'collector'],
|
|
147
|
+
['s3', 'collector'],
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
name: 'sharedCache',
|
|
152
|
+
category: 'fan-in',
|
|
153
|
+
art: `┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
154
|
+
│ Service1 │ │ Service2 │ │ Service3 │
|
|
155
|
+
└────┬─────┘ └────┬─────┘ └────┬─────┘
|
|
156
|
+
│ │ │
|
|
157
|
+
▼ ▼ ▼
|
|
158
|
+
┌────────────────────────────────────────┐
|
|
159
|
+
│ Shared Cache │
|
|
160
|
+
└────────────────────────────────────────┘`,
|
|
161
|
+
nodes: ['service1', 'service2', 'service3', 'shared-cache'],
|
|
162
|
+
edges: [
|
|
163
|
+
['service1', 'shared-cache'],
|
|
164
|
+
['service2', 'shared-cache'],
|
|
165
|
+
['service3', 'shared-cache'],
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: 'diamond',
|
|
170
|
+
category: 'dag',
|
|
171
|
+
art: ` ┌───┐
|
|
172
|
+
│ A │
|
|
173
|
+
└┬─┬┘
|
|
174
|
+
┌───┘ └───┐
|
|
175
|
+
▼ ▼
|
|
176
|
+
┌───┐ ┌───┐
|
|
177
|
+
│ B │ │ C │
|
|
178
|
+
└─┬─┘ └─┬─┘
|
|
179
|
+
└───┐ ┌───┘
|
|
180
|
+
▼ ▼
|
|
181
|
+
┌───┐
|
|
182
|
+
│ D │
|
|
183
|
+
└───┘`,
|
|
184
|
+
nodes: ['a', 'b', 'c', 'd'],
|
|
185
|
+
edges: [
|
|
186
|
+
['a', 'b'],
|
|
187
|
+
['a', 'c'],
|
|
188
|
+
['b', 'd'],
|
|
189
|
+
['c', 'd'],
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: 'orgTree',
|
|
194
|
+
category: 'dag',
|
|
195
|
+
art: ` ┌───────┐
|
|
196
|
+
│ CEO │
|
|
197
|
+
└───┬───┘
|
|
198
|
+
┌─────────┴─────────┐
|
|
199
|
+
▼ ▼
|
|
200
|
+
┌───────┐ ┌───────┐
|
|
201
|
+
│ VP-Eng│ │ VP-Ops│
|
|
202
|
+
└───┬───┘ └───────┘
|
|
203
|
+
┌───┴───┐
|
|
204
|
+
▼ ▼
|
|
205
|
+
┌───────┐┌───────┐
|
|
206
|
+
│ Dev ││ QA │
|
|
207
|
+
└───────┘└───────┘`,
|
|
208
|
+
nodes: ['ceo', 'vp-eng', 'vp-ops', 'dev', 'qa'],
|
|
209
|
+
edges: [
|
|
210
|
+
['ceo', 'vp-eng'],
|
|
211
|
+
['ceo', 'vp-ops'],
|
|
212
|
+
['vp-eng', 'dev'],
|
|
213
|
+
['vp-eng', 'qa'],
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: 'decisionTree',
|
|
218
|
+
category: 'dag',
|
|
219
|
+
art: ` ┌───────────┐
|
|
220
|
+
│ Check? │
|
|
221
|
+
└──┬─────┬──┘
|
|
222
|
+
│ │
|
|
223
|
+
▼ ▼
|
|
224
|
+
┌────────┐ ┌────────┐
|
|
225
|
+
│ Accept │ │ Reject │
|
|
226
|
+
└────────┘ └────────┘`,
|
|
227
|
+
nodes: ['check', 'accept', 'reject'],
|
|
228
|
+
edges: [
|
|
229
|
+
['check', 'accept'],
|
|
230
|
+
['check', 'reject'],
|
|
231
|
+
],
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: 'microservices',
|
|
235
|
+
category: 'dag',
|
|
236
|
+
art: ` ┌──────────────┐
|
|
237
|
+
│ Gateway │
|
|
238
|
+
└──┬────┬────┬─┘
|
|
239
|
+
┌──────────┘ │ └──────────┐
|
|
240
|
+
▼ ▼ ▼
|
|
241
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
242
|
+
│ Users │ │ Orders │ │ Payments │
|
|
243
|
+
└────┬─────┘ └────┬─────┘ └────┬─────┘
|
|
244
|
+
▼ ▼ ▼
|
|
245
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
246
|
+
│ UsersDB │ │ OrdersDB │ │ PayDB │
|
|
247
|
+
└──────────┘ └──────────┘ └──────────┘`,
|
|
248
|
+
nodes: ['gateway', 'users', 'orders', 'payments', 'usersdb', 'ordersdb', 'paydb'],
|
|
249
|
+
edges: [
|
|
250
|
+
['gateway', 'users'],
|
|
251
|
+
['gateway', 'orders'],
|
|
252
|
+
['gateway', 'payments'],
|
|
253
|
+
['users', 'usersdb'],
|
|
254
|
+
['orders', 'ordersdb'],
|
|
255
|
+
['payments', 'paydb'],
|
|
256
|
+
],
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: 'layered',
|
|
260
|
+
category: 'dag',
|
|
261
|
+
art: `┌─────────────────────────────┐
|
|
262
|
+
│ Presentation Layer │
|
|
263
|
+
└──────────────┬──────────────┘
|
|
264
|
+
▼
|
|
265
|
+
┌─────────────────────────────┐
|
|
266
|
+
│ Business Layer │
|
|
267
|
+
└──────────────┬──────────────┘
|
|
268
|
+
▼
|
|
269
|
+
┌─────────────────────────────┐
|
|
270
|
+
│ Data Layer │
|
|
271
|
+
└─────────────────────────────┘`,
|
|
272
|
+
nodes: ['presentation-layer', 'business-layer', 'data-layer'],
|
|
273
|
+
edges: [
|
|
274
|
+
['presentation-layer', 'business-layer'],
|
|
275
|
+
['business-layer', 'data-layer'],
|
|
276
|
+
],
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
name: 'threeTier',
|
|
280
|
+
category: 'dag',
|
|
281
|
+
art: `┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
282
|
+
│ Browser │────►│ App │────►│ DB │
|
|
283
|
+
└──────────┘ └────┬─────┘ └──────────┘
|
|
284
|
+
│
|
|
285
|
+
▼
|
|
286
|
+
┌──────────┐
|
|
287
|
+
│ Cache │
|
|
288
|
+
└──────────┘`,
|
|
289
|
+
nodes: ['browser', 'app', 'db', 'cache'],
|
|
290
|
+
edges: [
|
|
291
|
+
['browser', 'app'],
|
|
292
|
+
['app', 'db'],
|
|
293
|
+
['app', 'cache'],
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
name: 'retryLoop',
|
|
298
|
+
category: 'cycle',
|
|
299
|
+
art: `┌─────────┐ ┌──────────┐
|
|
300
|
+
│ Request │ ──────> │ Worker │
|
|
301
|
+
└─────────┘ └────┬─────┘
|
|
302
|
+
▲ │
|
|
303
|
+
└───────────────────┘`,
|
|
304
|
+
nodes: ['request', 'worker'],
|
|
305
|
+
edges: [
|
|
306
|
+
['request', 'worker'],
|
|
307
|
+
['worker', 'request'],
|
|
308
|
+
],
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: 'stateMachine',
|
|
312
|
+
category: 'cycle',
|
|
313
|
+
art: `┌─────────┐ ┌─────────┐ ┌──────────┐
|
|
314
|
+
│ Idle │ ───────> │ Running │ ──────> │ Complete │
|
|
315
|
+
└─────────┘ └────┬────┘ └──────────┘
|
|
316
|
+
▲ │
|
|
317
|
+
└────────────────────┘`,
|
|
318
|
+
nodes: ['idle', 'running', 'complete'],
|
|
319
|
+
edges: [
|
|
320
|
+
['idle', 'running'],
|
|
321
|
+
['running', 'complete'],
|
|
322
|
+
['running', 'idle'],
|
|
323
|
+
],
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
name: 'circuitBreaker',
|
|
327
|
+
category: 'cycle',
|
|
328
|
+
art: ` ┌──────────┐
|
|
329
|
+
│ Closed │
|
|
330
|
+
└──┬─────┬─┘
|
|
331
|
+
│ ▲
|
|
332
|
+
┌───────────┘ │
|
|
333
|
+
▼ │
|
|
334
|
+
┌──────────┐ ┌─────┴─────┐
|
|
335
|
+
│ Open │────►│ Half-Open │
|
|
336
|
+
└──────────┘ └───────────┘`,
|
|
337
|
+
nodes: ['closed', 'open', 'half-open'],
|
|
338
|
+
edges: [
|
|
339
|
+
['closed', 'open'],
|
|
340
|
+
['open', 'half-open'],
|
|
341
|
+
['half-open', 'closed'],
|
|
342
|
+
],
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
name: 'fullMesh3',
|
|
346
|
+
category: 'many-to-many',
|
|
347
|
+
art: ` ┌───────┐
|
|
348
|
+
│ Alpha │
|
|
349
|
+
└──┬─┬──┘
|
|
350
|
+
▲ ▲
|
|
351
|
+
┌───────────┘ │
|
|
352
|
+
│ └────────────┐
|
|
353
|
+
▼ ▼
|
|
354
|
+
┌──────┐ ┌───────┐
|
|
355
|
+
│ Beta ├◄────────────────►┤ Gamma │
|
|
356
|
+
└──────┘ └───────┘`,
|
|
357
|
+
nodes: ['alpha', 'beta', 'gamma'],
|
|
358
|
+
edges: [
|
|
359
|
+
['alpha', 'beta'],
|
|
360
|
+
['beta', 'alpha'],
|
|
361
|
+
['alpha', 'gamma'],
|
|
362
|
+
['gamma', 'alpha'],
|
|
363
|
+
['beta', 'gamma'],
|
|
364
|
+
['gamma', 'beta'],
|
|
365
|
+
],
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'bidirReplication',
|
|
369
|
+
category: 'edges',
|
|
370
|
+
art: `┌──────────┐ ┌──────────┐
|
|
371
|
+
│ Primary │ <───────────> │ Replica │
|
|
372
|
+
└──────────┘ └──────────┘`,
|
|
373
|
+
nodes: ['primary', 'replica'],
|
|
374
|
+
edges: [
|
|
375
|
+
['primary', 'replica'],
|
|
376
|
+
['replica', 'primary'],
|
|
377
|
+
],
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
name: 'undirectedPair',
|
|
381
|
+
category: 'edges',
|
|
382
|
+
art: `┌────────┐ ┌────────┐
|
|
383
|
+
│ NodeA │──────────│ NodeB │
|
|
384
|
+
└────────┘ └────────┘`,
|
|
385
|
+
nodes: ['nodea', 'nodeb'],
|
|
386
|
+
edges: [['nodea', 'nodeb', undefined, false]],
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
name: 'labeledTyped',
|
|
390
|
+
category: 'labels',
|
|
391
|
+
art: `┌──────────┐ ┌──────────┐
|
|
392
|
+
│ API │ ─── reads ──►│ Database │
|
|
393
|
+
└────┬─────┘ └──────────┘
|
|
394
|
+
│ writes
|
|
395
|
+
▼
|
|
396
|
+
┌──────────┐
|
|
397
|
+
│ Cache │
|
|
398
|
+
└──────────┘`,
|
|
399
|
+
nodes: ['api', 'database', 'cache'],
|
|
400
|
+
edges: [
|
|
401
|
+
['api', 'database', 'reads'],
|
|
402
|
+
['api', 'cache', 'writes'],
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
name: 'queueDlq',
|
|
407
|
+
category: 'labels',
|
|
408
|
+
art: `┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
409
|
+
│ Producer │────►│ Queue │────►│ Consumer │
|
|
410
|
+
└──────────┘ └────┬─────┘ └──────────┘
|
|
411
|
+
│ on-fail
|
|
412
|
+
▼
|
|
413
|
+
┌──────────┐
|
|
414
|
+
│ DLQ │
|
|
415
|
+
└──────────┘`,
|
|
416
|
+
nodes: ['producer', 'queue', 'consumer', 'dlq'],
|
|
417
|
+
edges: [
|
|
418
|
+
['producer', 'queue'],
|
|
419
|
+
['queue', 'consumer'],
|
|
420
|
+
['queue', 'dlq', 'on-fail'],
|
|
421
|
+
],
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: 'cqrs',
|
|
425
|
+
category: 'labels',
|
|
426
|
+
art: `┌──────────┐ ┌──────────────┐
|
|
427
|
+
│ Client │─── command ───────►│ Write Model │
|
|
428
|
+
└────┬─────┘ └──────┬───────┘
|
|
429
|
+
│ query │ events
|
|
430
|
+
▼ ▼
|
|
431
|
+
┌──────────────┐ ┌──────────────┐
|
|
432
|
+
│ Read Model │◄────────────────│ Event Store │
|
|
433
|
+
└──────────────┘ └──────────────┘`,
|
|
434
|
+
nodes: ['client', 'write-model', 'read-model', 'event-store'],
|
|
435
|
+
edges: [
|
|
436
|
+
['client', 'write-model', 'command'],
|
|
437
|
+
['client', 'read-model', 'query'],
|
|
438
|
+
['write-model', 'event-store', 'events'],
|
|
439
|
+
['event-store', 'read-model'],
|
|
440
|
+
],
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: 'multilineLabels',
|
|
444
|
+
category: 'labels',
|
|
445
|
+
art: `┌──────────────┐ ┌──────────────┐
|
|
446
|
+
│ molen-kernel │ │ molen-client │
|
|
447
|
+
│ headless sim │───────►│ three.js │
|
|
448
|
+
│ no DOM │ │ WebGL │
|
|
449
|
+
└──────────────┘ └──────────────┘`,
|
|
450
|
+
nodes: ['molen-kernel', 'molen-client'],
|
|
451
|
+
edges: [['molen-kernel', 'molen-client']],
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: 'k8sCluster',
|
|
455
|
+
category: 'container',
|
|
456
|
+
art: `┌───────────── Kubernetes Cluster ─────────────┐
|
|
457
|
+
│ │
|
|
458
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
459
|
+
│ │ Pod A │ │ Pod B │ │ Pod C │ │
|
|
460
|
+
│ └─────────┘ └─────────┘ └─────────┘ │
|
|
461
|
+
│ │
|
|
462
|
+
└──────────────────────────────────────────────┘`,
|
|
463
|
+
nodes: ['kubernetes-cluster', 'pod-a', 'pod-b', 'pod-c'],
|
|
464
|
+
edges: [],
|
|
465
|
+
containers: {
|
|
466
|
+
'pod-a': 'kubernetes-cluster',
|
|
467
|
+
'pod-b': 'kubernetes-cluster',
|
|
468
|
+
'pod-c': 'kubernetes-cluster',
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
name: 'twoRegions',
|
|
473
|
+
category: 'container',
|
|
474
|
+
art: `┌──── Region US ─────┐ ┌──── Region EU ─────┐
|
|
475
|
+
│ │ │ │
|
|
476
|
+
│ ┌──────────────┐ │ │ ┌──────────────┐ │
|
|
477
|
+
│ │ us-worker │ │ │ │ eu-worker │ │
|
|
478
|
+
│ └──────────────┘ │ │ └──────────────┘ │
|
|
479
|
+
│ │ │ │
|
|
480
|
+
└────────────────────┘ └────────────────────┘`,
|
|
481
|
+
nodes: ['region-us', 'us-worker', 'region-eu', 'eu-worker'],
|
|
482
|
+
edges: [],
|
|
483
|
+
containers: { 'us-worker': 'region-us', 'eu-worker': 'region-eu' },
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
name: 'nestedTwoLevels',
|
|
487
|
+
category: 'container',
|
|
488
|
+
art: `┌─────────── Region ────────────┐
|
|
489
|
+
│ │
|
|
490
|
+
│ ┌─────── Zone A ────────┐ │
|
|
491
|
+
│ │ │ │
|
|
492
|
+
│ │ ┌──────────────┐ │ │
|
|
493
|
+
│ │ │ Instance 1 │ │ │
|
|
494
|
+
│ │ └──────────────┘ │ │
|
|
495
|
+
│ │ │ │
|
|
496
|
+
│ └───────────────────────┘ │
|
|
497
|
+
│ │
|
|
498
|
+
└───────────────────────────────┘`,
|
|
499
|
+
nodes: ['region', 'zone-a', 'instance-1'],
|
|
500
|
+
edges: [],
|
|
501
|
+
containers: { 'zone-a': 'region', 'instance-1': 'zone-a' },
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
name: 'roundedCorners',
|
|
505
|
+
category: 'style',
|
|
506
|
+
art: `╭─────────╮ ╭─────────╮
|
|
507
|
+
│ Start │ ───► │ End │
|
|
508
|
+
╰─────────╯ ╰─────────╯`,
|
|
509
|
+
nodes: ['start', 'end'],
|
|
510
|
+
edges: [['start', 'end']],
|
|
511
|
+
},
|
|
512
|
+
];
|