@miragon/team-topologies-schema-model 0.15.1 → 0.16.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/dist/index.cjs +59 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -3
- package/dist/index.d.ts +12 -3
- package/dist/index.js +59 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -344,6 +344,47 @@ function pathInFile(path, interactionFileIndexes) {
|
|
|
344
344
|
return fileIndex === void 0 ? path : [collection, fileIndex, ...rest];
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
+
// src/canonical-copy.ts
|
|
348
|
+
var MAX_REPEATED_ENTRIES = 1e6;
|
|
349
|
+
function canonicalCopier() {
|
|
350
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
351
|
+
const copiedContainers = /* @__PURE__ */ new WeakSet();
|
|
352
|
+
let repeatedEntries = 0;
|
|
353
|
+
const copy = (value) => {
|
|
354
|
+
if (value === null || typeof value !== "object") return value;
|
|
355
|
+
if (ancestors.has(value)) throw new Error("Cannot serialize a cyclic document.");
|
|
356
|
+
if (copiedContainers.has(value)) {
|
|
357
|
+
repeatedEntries += Array.isArray(value) ? value.length : Object.keys(value).length;
|
|
358
|
+
if (repeatedEntries > MAX_REPEATED_ENTRIES) {
|
|
359
|
+
throw new Error(
|
|
360
|
+
`Cannot serialize a document whose shared objects and arrays would repeat more than ${MAX_REPEATED_ENTRIES} entries.`
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
copiedContainers.add(value);
|
|
365
|
+
}
|
|
366
|
+
ancestors.add(value);
|
|
367
|
+
const record = value;
|
|
368
|
+
const copied = Array.isArray(value) ? value.map(copy) : Object.fromEntries(
|
|
369
|
+
Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, copy(record[key])])
|
|
370
|
+
);
|
|
371
|
+
ancestors.delete(value);
|
|
372
|
+
return copied;
|
|
373
|
+
};
|
|
374
|
+
return copy;
|
|
375
|
+
}
|
|
376
|
+
function copyForeignFields(value, knownFields, copy) {
|
|
377
|
+
const record = value;
|
|
378
|
+
const names = Object.keys(record).filter((name) => !knownFields.includes(name) && record[name] !== void 0).sort();
|
|
379
|
+
if (names.length === 0) return void 0;
|
|
380
|
+
return Object.fromEntries(names.map((name) => [name, copy(record[name])]));
|
|
381
|
+
}
|
|
382
|
+
function appendForeignFields(known, source, knownFields, copy) {
|
|
383
|
+
const foreign = source ? copyForeignFields(source, knownFields, copy) : void 0;
|
|
384
|
+
if (!foreign) return known;
|
|
385
|
+
return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]);
|
|
386
|
+
}
|
|
387
|
+
|
|
347
388
|
// src/foreign.ts
|
|
348
389
|
var DOCUMENT_FIELDS = [
|
|
349
390
|
"version",
|
|
@@ -374,24 +415,11 @@ var INTERACTION_FIELDS = [
|
|
|
374
415
|
];
|
|
375
416
|
var FLOW_FIELDS = ["id", "label", "position", "size"];
|
|
376
417
|
var ANNOTATION_FIELDS = ["id", "text", "position", "size", "attachedTo"];
|
|
377
|
-
function canonicalValue(value) {
|
|
378
|
-
if (Array.isArray(value)) return value.map(canonicalValue);
|
|
379
|
-
if (value === null || typeof value !== "object") return value;
|
|
380
|
-
const record = value;
|
|
381
|
-
return Object.fromEntries(
|
|
382
|
-
Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, canonicalValue(record[key])])
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
418
|
function foreignFields(value, knownFields) {
|
|
386
|
-
|
|
387
|
-
const names = Object.keys(record).filter((name) => !knownFields.includes(name) && record[name] !== void 0).sort();
|
|
388
|
-
if (names.length === 0) return void 0;
|
|
389
|
-
return Object.fromEntries(names.map((name) => [name, canonicalValue(record[name])]));
|
|
419
|
+
return copyForeignFields(value, knownFields, canonicalCopier());
|
|
390
420
|
}
|
|
391
421
|
function withForeignFields(known, source, knownFields) {
|
|
392
|
-
|
|
393
|
-
if (!foreign) return known;
|
|
394
|
-
return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]);
|
|
422
|
+
return appendForeignFields(known, source, knownFields, canonicalCopier());
|
|
395
423
|
}
|
|
396
424
|
|
|
397
425
|
// src/serialize.ts
|
|
@@ -404,7 +432,7 @@ function normPosition(p) {
|
|
|
404
432
|
function normSize(s2) {
|
|
405
433
|
return { width: round(s2.width), height: round(s2.height) };
|
|
406
434
|
}
|
|
407
|
-
function normNode(n) {
|
|
435
|
+
function normNode(n, copy) {
|
|
408
436
|
const out = {
|
|
409
437
|
id: n.id,
|
|
410
438
|
type: n.type,
|
|
@@ -415,9 +443,9 @@ function normNode(n) {
|
|
|
415
443
|
if (n.description) out.description = n.description;
|
|
416
444
|
if (n.fill) out.fill = n.fill;
|
|
417
445
|
if (n.stroke) out.stroke = n.stroke;
|
|
418
|
-
return
|
|
446
|
+
return appendForeignFields(out, n, TEAM_NODE_FIELDS, copy);
|
|
419
447
|
}
|
|
420
|
-
function normInteraction(e) {
|
|
448
|
+
function normInteraction(e, copy) {
|
|
421
449
|
const out = {
|
|
422
450
|
id: e.id,
|
|
423
451
|
mode: e.mode,
|
|
@@ -427,18 +455,18 @@ function normInteraction(e) {
|
|
|
427
455
|
if (e.label) out.label = e.label;
|
|
428
456
|
if (e.fill) out.fill = e.fill;
|
|
429
457
|
if (e.stroke) out.stroke = e.stroke;
|
|
430
|
-
return
|
|
458
|
+
return appendForeignFields(out, e, INTERACTION_FIELDS, copy);
|
|
431
459
|
}
|
|
432
|
-
function normFlow(f) {
|
|
460
|
+
function normFlow(f, copy) {
|
|
433
461
|
const out = {
|
|
434
462
|
id: f.id,
|
|
435
463
|
position: normPosition(f.position),
|
|
436
464
|
size: normSize(f.size)
|
|
437
465
|
};
|
|
438
466
|
if (f.label) out.label = f.label;
|
|
439
|
-
return
|
|
467
|
+
return appendForeignFields(out, f, FLOW_FIELDS, copy);
|
|
440
468
|
}
|
|
441
|
-
function normAnnotation(a) {
|
|
469
|
+
function normAnnotation(a, copy) {
|
|
442
470
|
const out = {
|
|
443
471
|
id: a.id,
|
|
444
472
|
text: a.text,
|
|
@@ -446,21 +474,23 @@ function normAnnotation(a) {
|
|
|
446
474
|
size: normSize(a.size)
|
|
447
475
|
};
|
|
448
476
|
if (a.attachedTo) out.attachedTo = a.attachedTo;
|
|
449
|
-
return
|
|
477
|
+
return appendForeignFields(out, a, ANNOTATION_FIELDS, copy);
|
|
450
478
|
}
|
|
451
479
|
var byId = (a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
452
480
|
function canonicalize(doc) {
|
|
453
|
-
|
|
481
|
+
const copy = canonicalCopier();
|
|
482
|
+
return appendForeignFields(
|
|
454
483
|
{
|
|
455
484
|
version: DOCUMENT_VERSION,
|
|
456
485
|
title: doc.title,
|
|
457
|
-
nodes: [...doc.nodes].map(normNode).sort(byId),
|
|
458
|
-
interactions: [...doc.interactions].map(normInteraction).sort(byId),
|
|
459
|
-
flows: [...doc.flows].map(normFlow).sort(byId),
|
|
460
|
-
annotations: [...doc.annotations].map(normAnnotation).sort(byId)
|
|
486
|
+
nodes: [...doc.nodes].map((node) => normNode(node, copy)).sort(byId),
|
|
487
|
+
interactions: [...doc.interactions].map((interaction) => normInteraction(interaction, copy)).sort(byId),
|
|
488
|
+
flows: [...doc.flows].map((flow) => normFlow(flow, copy)).sort(byId),
|
|
489
|
+
annotations: [...doc.annotations].map((annotation) => normAnnotation(annotation, copy)).sort(byId)
|
|
461
490
|
},
|
|
462
491
|
doc,
|
|
463
|
-
DOCUMENT_FIELDS
|
|
492
|
+
DOCUMENT_FIELDS,
|
|
493
|
+
copy
|
|
464
494
|
);
|
|
465
495
|
}
|
|
466
496
|
function serializeDocument(doc, pretty = true) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/notation.ts","../src/ids.ts","../src/schema.ts","../src/foreign.ts","../src/serialize.ts","../src/factory.ts","../src/sample.ts"],"names":["z","i","s","nanoid"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Pure (DOM-free) domain types for the Team Topologies model.\n *\n * This module is the canonical representation of a diagram and must never\n * import from the rendering layer (`@xyflow/react`) or touch the DOM, so it\n * can be unit-tested in isolation and reused across views / exporters.\n */\n\n/** MIME type used when dragging a team type from the palette onto the canvas. */\nexport const DND_MIME = \"application/x-tt-team-type\";\n\n/** The four fundamental team types in Team Topologies. */\nexport type TeamType = \"stream-aligned\" | \"enabling\" | \"complicated-subsystem\" | \"platform\";\n\nexport const TEAM_TYPES: readonly TeamType[] = [\n \"stream-aligned\",\n \"enabling\",\n \"complicated-subsystem\",\n \"platform\",\n] as const;\n\n/** The three core team interaction modes in Team Topologies. */\nexport type InteractionMode = \"collaboration\" | \"x-as-a-service\" | \"facilitating\";\n\nexport const INTERACTION_MODES: readonly InteractionMode[] = [\n \"collaboration\",\n \"x-as-a-service\",\n \"facilitating\",\n] as const;\n\n/** Geometric size of a node in canvas units (px). Encodes cognitive load. */\nexport interface Size {\n width: number;\n height: number;\n}\n\n/** Position of a node on the canvas in canvas units (px). */\nexport interface Position {\n x: number;\n y: number;\n}\n\n/** A team node in the canonical document model. */\nexport interface TeamNode {\n id: string;\n type: TeamType;\n label: string;\n description?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * An interaction in the canonical document model.\n *\n * Per the official Team Topologies notation, an interaction is a placed,\n * resizable SHAPE (parallelogram / triangle / circle) overlaid on the boundary\n * between the teams it relates to — not a connecting line. The relationship is\n * therefore spatial (overlap), so there is no source/target reference.\n */\nexport interface InteractionShape {\n id: string;\n mode: InteractionMode;\n label?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * A \"flow of change\" guide: a placed, resizable arrow element. Lets you anchor\n * the implied left-to-right flow, and visualise several team groupings on one\n * canvas.\n */\nexport interface FlowShape {\n id: string;\n label?: string;\n position: Position;\n size: Size;\n}\n\n/**\n * A free-text note beside the diagram (like a BPMN text annotation). It either\n * stands alone or is attached to exactly one team, interaction or flow, which\n * its dashed connector points at.\n */\nexport interface TextAnnotation {\n id: string;\n text: string;\n position: Position;\n size: Size;\n /** Id of the team, interaction or flow this annotation is attached to. */\n attachedTo?: string;\n}\n\n/** Current document schema version. Bump + add a migration when shape changes. */\nexport const DOCUMENT_VERSION = 3 as const;\n\n/**\n * A complete Team Topologies diagram. This is what gets serialised to JSON,\n * embedded into exported images, and encoded into share URLs.\n */\nexport interface TtDocument {\n version: typeof DOCUMENT_VERSION;\n title: string;\n nodes: TeamNode[];\n interactions: InteractionShape[];\n flows: FlowShape[];\n annotations: TextAnnotation[];\n}\n","/**\n * The Team Topologies visual notation, encoded as data.\n *\n * Colours, shapes and stroke styles follow the official\n * \"Team-Shape-Templates\" specification published by Team Topologies\n * (https://github.com/TeamTopologies/Team-Shape-Templates):\n *\n * - Team shapes are SOLID outlines (long-lived structures).\n * - Interaction-mode shapes are 50% transparent with DASHED outlines\n * (short-lived interactions).\n * - Each element is distinguished by SHAPE as well as colour, so the\n * notation stays readable for people with colour-vision deficiency.\n *\n * This module is pure data — it must not import the rendering layer.\n */\n\nimport type { InteractionMode, Size, TeamType } from \"./types\";\n\nexport type TeamShape = \"rounded-rect-horizontal\" | \"rounded-rect-vertical\" | \"octagon\" | \"rect\";\n\nexport type InteractionGlyph = \"parallelogram\" | \"triangle\" | \"circle\";\n\nexport type StrokeStyle = \"solid\" | \"dashed\" | \"dotted\";\n\nexport interface TeamTypeSpec {\n type: TeamType;\n /** Short display name. */\n label: string;\n /** One-line purpose, shown in the palette and inspector. */\n description: string;\n shape: TeamShape;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /** Default size when a node of this type is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\nexport interface InteractionModeSpec {\n mode: InteractionMode;\n label: string;\n description: string;\n shape: InteractionGlyph;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /**\n * The templates' fill opacity (short-lived → translucent). The renderer premixes the fill over\n * white at it and draws it opaque.\n */\n opacity: number;\n /** Whether direction is semantically meaningful (the X-as-a-Service triangle). */\n directional: boolean;\n /** Default size when a shape of this mode is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\n/** The left-to-right \"flow of change\" guide, a placeable annotation element. */\nexport interface FlowSpec {\n label: string;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n defaultSize: Size;\n minSize: Size;\n}\n\n// The official notation colours (Team-Shape-Templates, above): foreign notation, guide §10.6.\n// brand-lint-disable\nexport const TEAM_TYPE_SPECS: Record<TeamType, TeamTypeSpec> = {\n \"stream-aligned\": {\n type: \"stream-aligned\",\n label: \"Stream-aligned\",\n description: \"Aligned to a single, valuable stream of work; owns it end-to-end.\",\n shape: \"rounded-rect-horizontal\",\n fill: \"#FFEDB8\",\n stroke: \"#FFD966\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 240, height: 96 },\n minSize: { width: 140, height: 64 },\n },\n enabling: {\n type: \"enabling\",\n label: \"Enabling\",\n description:\n \"Helps stream-aligned teams acquire missing capabilities; coaches, then steps back.\",\n shape: \"rounded-rect-vertical\",\n fill: \"#DFBDCF\",\n stroke: \"#D09CB7\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 120, height: 200 },\n minSize: { width: 80, height: 120 },\n },\n \"complicated-subsystem\": {\n type: \"complicated-subsystem\",\n label: \"Complicated Subsystem\",\n description:\n \"Owns a part of the system needing deep specialist knowledge, reducing others' cognitive load.\",\n shape: \"octagon\",\n fill: \"#FFC08B\",\n stroke: \"#E88814\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 170, height: 150 },\n minSize: { width: 110, height: 100 },\n },\n platform: {\n type: \"platform\",\n label: \"Platform\",\n description:\n \"Provides internal self-service capabilities to reduce cognitive load for stream-aligned teams.\",\n shape: \"rect\",\n fill: \"#B7CDF1\",\n stroke: \"#6D9EEB\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 380, height: 130 },\n minSize: { width: 200, height: 90 },\n },\n};\n\nexport const INTERACTION_MODE_SPECS: Record<InteractionMode, InteractionModeSpec> = {\n collaboration: {\n mode: \"collaboration\",\n label: \"Collaboration\",\n description:\n \"Two teams work closely together for a defined period; high overhead, high discovery.\",\n shape: \"parallelogram\",\n fill: \"#C6BEDF\",\n stroke: \"#967EE2\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 112, height: 72 },\n minSize: { width: 60, height: 44 },\n },\n \"x-as-a-service\": {\n mode: \"x-as-a-service\",\n label: \"X-as-a-Service\",\n description:\n \"One team consumes something the other provides 'as a service'; minimal collaboration.\",\n shape: \"triangle\",\n fill: \"#B4B4B4\",\n stroke: \"#999696\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: true,\n defaultSize: { width: 88, height: 78 },\n minSize: { width: 54, height: 48 },\n },\n facilitating: {\n mode: \"facilitating\",\n label: \"Facilitating\",\n description:\n \"One team helps/coaches another to clear impediments and learn; sensing and discovery.\",\n shape: \"circle\",\n fill: \"#C9DFBE\",\n stroke: \"#78996B\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 84, height: 84 },\n minSize: { width: 48, height: 48 },\n },\n};\n\n/**\n * The \"flow of change\" guide — a placeable dashed arrow (left-to-right).\n * Not a team or interaction: a standalone annotation element.\n */\nexport const FLOW_SPEC: FlowSpec = {\n label: \"Flow of change\",\n fill: \"transparent\",\n stroke: \"#6b6459\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n defaultSize: { width: 520, height: 64 },\n minSize: { width: 160, height: 36 },\n};\n// brand-lint-enable\n\n/**\n * A text annotation — not part of the Team Topologies notation, so it carries\n * no colours here; the renderer draws it in the neutral brand ink.\n */\nexport interface AnnotationSpec {\n label: string;\n defaultSize: Size;\n minSize: Size;\n}\n\nexport const ANNOTATION_SPEC: AnnotationSpec = {\n label: \"Annotation\",\n defaultSize: { width: 200, height: 64 },\n minSize: { width: 60, height: 30 },\n};\n\n/** Maps a stroke style to an SVG/CSS dash array (empty string = solid). */\nexport function dashArray(style: StrokeStyle, strokeWidth = 2): string {\n switch (style) {\n case \"dashed\":\n return `${strokeWidth * 3} ${strokeWidth * 2}`;\n case \"dotted\":\n return `${strokeWidth} ${strokeWidth * 1.5}`;\n case \"solid\":\n default:\n return \"\";\n }\n}\n\nexport const ALL_TEAM_SPECS: readonly TeamTypeSpec[] = Object.values(TEAM_TYPE_SPECS);\nexport const ALL_INTERACTION_SPECS: readonly InteractionModeSpec[] =\n Object.values(INTERACTION_MODE_SPECS);\n","/**\n * The id rules of a Team Topologies document. Besides the elements a document lists, a diagram\n * holds parts it never writes down: the diagram itself and the connector of every annotation. They\n * take ids of their own, so no element may use one of them; otherwise opening the file would fail\n * halfway, with the previous diagram already gone. The canvas also keeps its elements in a plain\n * object, where the names of JavaScript's built-in object properties already resolve.\n */\n\n/** The id of the diagram itself (the canvas root of the renderer). */\nexport const DIAGRAM_ROOT_ID = \"tt-root\";\n\n/** diagram-js names the roots it creates on its own `__implicitroot_<n>`. */\nconst ENGINE_ROOT_ID_PREFIX = \"__implicitroot\";\n\n/** Connectors are not stored: an annotation's connector derives its id from the annotation. */\nexport function associationId(annotationId: string): string {\n return `assoc_${annotationId}`;\n}\n\nexport interface DocumentIdProblem {\n /** Where the offending id sits, e.g. `[\"nodes\", 2, \"id\"]`. */\n path: (string | number)[];\n message: string;\n}\n\nconst COLLECTIONS = [\"nodes\", \"interactions\", \"flows\", \"annotations\"] as const;\n\ntype DocumentElements = Record<(typeof COLLECTIONS)[number], readonly { id: string }[]>;\n\n/** Ids such as `constructor`, `toString` or `__proto__`, which every plain object already has. */\nfunction isBuiltInPropertyId(id: string): boolean {\n return Object.hasOwn(Object.prototype, id);\n}\n\n/**\n * Every id of the document that would collide on the canvas: a duplicate, the diagram's own id, a\n * diagram-js root id, the name of a built-in object property, or the id of an annotation's\n * connector.\n */\nexport function documentIdProblems(doc: DocumentElements): DocumentIdProblem[] {\n const problems: DocumentIdProblem[] = [];\n const connectorIds = new Map(\n doc.annotations.map((annotation) => [associationId(annotation.id), annotation.id]),\n );\n const seen = new Set<string>();\n for (const collection of COLLECTIONS) {\n doc[collection].forEach((element, index) => {\n const path = [collection, index, \"id\"];\n const { id } = element;\n if (seen.has(id)) {\n problems.push({\n path,\n message: `duplicate id \"${id}\"; ids must be unique across nodes, interactions, flows and annotations`,\n });\n }\n seen.add(id);\n if (id === DIAGRAM_ROOT_ID) {\n problems.push({ path, message: `\"${id}\" is reserved for the diagram itself` });\n } else if (id.startsWith(ENGINE_ROOT_ID_PREFIX)) {\n problems.push({\n path,\n message: `ids starting with \"${ENGINE_ROOT_ID_PREFIX}\" are reserved`,\n });\n } else if (isBuiltInPropertyId(id)) {\n problems.push({\n path,\n message: `\"${id}\" is reserved: it names a built-in property of JavaScript objects`,\n });\n }\n const annotationId = connectorIds.get(id);\n if (annotationId !== undefined) {\n problems.push({\n path,\n message: `\"${id}\" is reserved for the connector of annotation \"${annotationId}\"`,\n });\n }\n });\n }\n return problems;\n}\n","/**\n * Runtime validation for the document model using Zod.\n *\n * Anything entering the app from the outside world (imported files, share\n * URLs, localStorage) is parsed through {@link parseDocument} so malformed or\n * tampered data can never corrupt the editor state. Fields the schema does not\n * know pass through untouched (see `foreign.ts`), so another tool's data\n * survives a save.\n */\n\nimport { z } from \"zod\";\nimport { documentIdProblems } from \"./ids\";\nimport { DOCUMENT_VERSION, INTERACTION_MODES, TEAM_TYPES } from \"./types\";\nimport type { TtDocument } from \"./types\";\n\nconst teamTypeSchema = z.enum(TEAM_TYPES as unknown as [string, ...string[]]);\nconst interactionModeSchema = z.enum(INTERACTION_MODES as unknown as [string, ...string[]]);\n\nconst sizeSchema = z.object({\n width: z.number().finite().positive(),\n height: z.number().finite().positive(),\n});\n\nconst positionSchema = z.object({\n x: z.number().finite(),\n y: z.number().finite(),\n});\n\nconst hexColor = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, \"expected a hex colour\");\n\nexport const teamNodeSchema = z.looseObject({\n id: z.string().min(1),\n type: teamTypeSchema,\n label: z.string(),\n description: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const interactionSchema = z.looseObject({\n id: z.string().min(1),\n mode: interactionModeSchema,\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const flowSchema = z.looseObject({\n id: z.string().min(1),\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n});\n\nexport const annotationSchema = z.looseObject({\n id: z.string().min(1),\n text: z.string(),\n position: positionSchema,\n size: sizeSchema,\n attachedTo: z.string().min(1).optional(),\n});\n\nexport const documentSchema = z\n .looseObject({\n version: z.literal(DOCUMENT_VERSION),\n title: z.string(),\n nodes: z.array(teamNodeSchema),\n interactions: z.array(interactionSchema),\n flows: z.array(flowSchema),\n annotations: z.array(annotationSchema),\n })\n .superRefine((document, context) => {\n for (const { path, message } of documentIdProblems(document)) {\n context.addIssue({ code: \"custom\", path, message });\n }\n });\n\n/** One reason a document is invalid, at the path of the offending value. */\nexport interface DocumentIssue {\n path: (string | number)[];\n message: string;\n}\n\nexport type ParseResult =\n { ok: true; document: TtDocument } | { ok: false; error: string; issues: DocumentIssue[] };\n\n/**\n * Objects and arrays nested deeper than this make a document invalid, the document itself counting\n * as the first level. The serializer, structured cloning and JSON tooling such as jsonc-parser\n * descend one call per level and overflow the stack a few thousand levels down; a Team Topologies\n * document needs four.\n */\nexport const MAX_NESTING_DEPTH = 100;\n\n/**\n * Validates and (if necessary) migrates unknown data into a {@link TtDocument}.\n * Returns a discriminated result rather than throwing so callers can show a\n * friendly message, or point at each offending value (`issues`).\n */\nexport function parseDocument(input: unknown): ParseResult {\n const tooDeep = nestingIssues(input);\n if (tooDeep.length > 0) return refused(tooDeep);\n const { document: migrated, interactionFileIndexes } = migrate(input);\n const result = documentSchema.safeParse(migrated);\n if (!result.success) {\n return refused(\n result.error.issues.map((issue) => ({\n path: pathInFile(\n issue.path.filter((key): key is string | number => typeof key !== \"symbol\"),\n interactionFileIndexes,\n ),\n message: issue.message,\n })),\n );\n }\n return { ok: true, document: result.data as TtDocument };\n}\n\nfunction refused(issues: DocumentIssue[]): ParseResult {\n return {\n ok: false,\n error: issues.map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`).join(\"; \"),\n issues,\n };\n}\n\n/**\n * At most this many nesting issues per document. Each carries a path of {@link MAX_NESTING_DEPTH}\n * keys, so one wide container beyond the limit would otherwise give millions of them and an error\n * text longer than a string may be.\n */\nconst MAX_NESTING_ISSUES = 100;\n\ninterface OpenContainer {\n readonly container: object;\n readonly keys: readonly string[] | undefined;\n readonly size: number;\n next: number;\n readonly keyInParent: string | number | undefined;\n}\n\n/**\n * Each object or array at the first level beyond {@link MAX_NESTING_DEPTH}, in document order, up\n * to {@link MAX_NESTING_ISSUES}; what lies below it is not visited. Walked with an explicit stack,\n * because the documents it guards against are the ones that overflow a recursive walk. The stack\n * holds only the containers the walk is inside of and a path is built only for an issue, so the\n * walk's memory grows with the number of containers, not with their number times their depth.\n */\nfunction nestingIssues(input: unknown): DocumentIssue[] {\n const issues: DocumentIssue[] = [];\n if (!isContainer(input)) return issues;\n // A caller in JavaScript may put one container in several places, or inside itself: walking it\n // again at a level no deeper than before finds nothing new, and would grow exponentially.\n const deepestWalk = new WeakMap<object, number>();\n const open: OpenContainer[] = [];\n const enter = (container: object, keyInParent?: string | number): void => {\n deepestWalk.set(container, open.length);\n const keys = Array.isArray(container) ? undefined : Object.keys(container);\n const size = keys?.length ?? (container as unknown[]).length;\n open.push({ container, keys, size, next: 0, keyInParent });\n };\n enter(input);\n while (open.length > 0 && issues.length < MAX_NESTING_ISSUES) {\n const current = open[open.length - 1]!;\n if (current.next === current.size) {\n open.pop();\n continue;\n }\n const index = current.next++;\n const key = current.keys === undefined ? index : current.keys[index]!;\n const entry: unknown = (current.container as Record<string | number, unknown>)[key];\n if (!isContainer(entry)) continue;\n if (open.length >= MAX_NESTING_DEPTH) {\n issues.push({\n path: [...open.flatMap(({ keyInParent }) => keyInParent ?? []), key],\n message: `objects and arrays may nest at most ${MAX_NESTING_DEPTH} levels deep`,\n });\n continue;\n }\n if ((deepestWalk.get(entry) ?? -1) >= open.length) continue;\n enter(entry, key);\n }\n return issues;\n}\n\nfunction isContainer(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\n/** The last document version that modelled interactions as edges without geometry. */\nconst EDGE_INTERACTIONS_VERSION = 1;\n\ninterface Migration {\n document: unknown;\n /** For each interaction the migrated document keeps, its index in the input. */\n interactionFileIndexes: readonly number[];\n}\n\n/**\n * Forward-migrates older document shapes to the current version. v1 modelled\n * interactions as edges (source/target, no geometry) and carried a\n * `showFlowOfChange` flag; v2 makes interactions placed shapes and adds `flows`;\n * v3 adds `annotations`. The edge-interactions of a v1 file can't be placed\n * meaningfully, so they're dropped. From v2 on, an interaction without position\n * or size is refused like any other missing field: dropped, it would vanish from\n * the file on the next save without a word.\n */\nfunction migrate(input: unknown): Migration {\n if (input == null || typeof input !== \"object\") {\n return { document: input, interactionFileIndexes: [] };\n }\n const doc = input as Record<string, unknown>;\n const next: Record<string, unknown> = { ...doc };\n delete next.showFlowOfChange; // v1 flag, gone in v2\n next.version = DOCUMENT_VERSION;\n if (typeof next.title !== \"string\") next.title = \"Untitled team topology\";\n if (!Array.isArray(next.nodes)) next.nodes = [];\n const dropsEdgeInteractions = doc.version === EDGE_INTERACTIONS_VERSION;\n const keptInteractions = Array.isArray(next.interactions)\n ? next.interactions\n .map((interaction: unknown, fileIndex) => ({ interaction, fileIndex }))\n .filter(({ interaction }) => !dropsEdgeInteractions || isPlacedShape(interaction))\n : [];\n next.interactions = keptInteractions.map(({ interaction }) => interaction);\n if (!Array.isArray(next.flows)) next.flows = [];\n if (!Array.isArray(next.annotations)) next.annotations = [];\n return {\n document: next,\n interactionFileIndexes: keptInteractions.map(({ fileIndex }) => fileIndex),\n };\n}\n\nfunction isPlacedShape(value: unknown): boolean {\n return value != null && typeof value === \"object\" && \"position\" in value && \"size\" in value;\n}\n\n/**\n * An issue's path in the input rather than in the migrated document: an editor points at the\n * file, and every legacy interaction dropped before an invalid one would shift its index.\n */\nfunction pathInFile(\n path: (string | number)[],\n interactionFileIndexes: readonly number[],\n): (string | number)[] {\n const [collection, index, ...rest] = path;\n if (collection !== \"interactions\" || typeof index !== \"number\") return path;\n const fileIndex = interactionFileIndexes[index];\n return fileIndex === undefined ? path : [collection, fileIndex, ...rest];\n}\n","/**\n * Fields a document carries that this modeler does not know, such as a vendor's `\"x-vendor\"` on a\n * team. They are kept through open and save, written after the known fields and sorted, so another\n * tool's data survives an edit in the modeler and the output stays deterministic.\n */\n\nexport const DOCUMENT_FIELDS = [\n \"version\",\n \"title\",\n \"nodes\",\n \"interactions\",\n \"flows\",\n \"annotations\",\n] as const;\nexport const TEAM_NODE_FIELDS = [\n \"id\",\n \"type\",\n \"label\",\n \"description\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const INTERACTION_FIELDS = [\n \"id\",\n \"mode\",\n \"label\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const FLOW_FIELDS = [\"id\", \"label\", \"position\", \"size\"] as const;\nexport const ANNOTATION_FIELDS = [\"id\", \"text\", \"position\", \"size\", \"attachedTo\"] as const;\n\n/** Unknown fields by name, sorted, with their values in canonical form. */\nexport type ForeignFields = Readonly<Record<string, unknown>>;\n\n/** JSON objects have no key order, so nested keys are sorted too: equal data, equal bytes. */\nfunction canonicalValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalValue);\n if (value === null || typeof value !== \"object\") return value;\n const record = value as Record<string, unknown>;\n return Object.fromEntries(\n Object.keys(record)\n .filter((key) => record[key] !== undefined)\n .sort()\n .map((key) => [key, canonicalValue(record[key])]),\n );\n}\n\n/** The fields of `value` outside `knownFields`, or undefined when there are none. */\nexport function foreignFields(\n value: object,\n knownFields: readonly string[],\n): ForeignFields | undefined {\n const record = value as Record<string, unknown>;\n const names = Object.keys(record)\n .filter((name) => !knownFields.includes(name) && record[name] !== undefined)\n .sort();\n if (names.length === 0) return undefined;\n return Object.fromEntries(names.map((name) => [name, canonicalValue(record[name])]));\n}\n\n/**\n * `known` followed by the foreign fields of `source`. Built from entries, never by assignment, so\n * a field named `__proto__` stays a field instead of replacing the prototype.\n */\nexport function withForeignFields<T extends object>(\n known: T,\n source: object | undefined,\n knownFields: readonly string[],\n): T {\n const foreign = source ? foreignFields(source, knownFields) : undefined;\n if (!foreign) return known;\n return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]) as T;\n}\n","/**\n * Deterministic serialisation of the document model.\n *\n * Producing byte-stable JSON (sorted arrays, fixed key order, rounded\n * coordinates) makes diagrams diff-friendly in version control and gives\n * stable share URLs / embedded payloads.\n */\n\nimport {\n ANNOTATION_FIELDS,\n DOCUMENT_FIELDS,\n FLOW_FIELDS,\n INTERACTION_FIELDS,\n TEAM_NODE_FIELDS,\n withForeignFields,\n} from \"./foreign\";\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type {\n FlowShape,\n InteractionShape,\n Position,\n Size,\n TeamNode,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\n\n/** Round to 2 decimals to strip floating-point drift from drag operations. */\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction normPosition(p: Position): Position {\n return { x: round(p.x), y: round(p.y) };\n}\n\nfunction normSize(s: Size): Size {\n return { width: round(s.width), height: round(s.height) };\n}\n\n/** Drops undefined fields and applies a fixed key order to a node. */\nfunction normNode(n: TeamNode): TeamNode {\n const out: TeamNode = {\n id: n.id,\n type: n.type,\n label: n.label,\n position: normPosition(n.position),\n size: normSize(n.size),\n };\n if (n.description) out.description = n.description;\n if (n.fill) out.fill = n.fill;\n if (n.stroke) out.stroke = n.stroke;\n return withForeignFields(out, n, TEAM_NODE_FIELDS);\n}\n\nfunction normInteraction(e: InteractionShape): InteractionShape {\n const out: InteractionShape = {\n id: e.id,\n mode: e.mode,\n position: normPosition(e.position),\n size: normSize(e.size),\n };\n if (e.label) out.label = e.label;\n if (e.fill) out.fill = e.fill;\n if (e.stroke) out.stroke = e.stroke;\n return withForeignFields(out, e, INTERACTION_FIELDS);\n}\n\nfunction normFlow(f: FlowShape): FlowShape {\n const out: FlowShape = {\n id: f.id,\n position: normPosition(f.position),\n size: normSize(f.size),\n };\n if (f.label) out.label = f.label;\n return withForeignFields(out, f, FLOW_FIELDS);\n}\n\nfunction normAnnotation(a: TextAnnotation): TextAnnotation {\n const out: TextAnnotation = {\n id: a.id,\n text: a.text,\n position: normPosition(a.position),\n size: normSize(a.size),\n };\n if (a.attachedTo) out.attachedTo = a.attachedTo;\n return withForeignFields(out, a, ANNOTATION_FIELDS);\n}\n\nconst byId = (a: { id: string }, b: { id: string }): number =>\n a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\n/**\n * Returns a canonicalised copy of a document (sorted, rounded, version-stamped). Fields the\n * modeler does not know follow the known ones, sorted by name.\n */\nexport function canonicalize(doc: TtDocument): TtDocument {\n return withForeignFields(\n {\n version: DOCUMENT_VERSION,\n title: doc.title,\n nodes: [...doc.nodes].map(normNode).sort(byId),\n interactions: [...doc.interactions].map(normInteraction).sort(byId),\n flows: [...doc.flows].map(normFlow).sort(byId),\n annotations: [...doc.annotations].map(normAnnotation).sort(byId),\n },\n doc,\n DOCUMENT_FIELDS,\n );\n}\n\n/**\n * Serialises a document to deterministic JSON. An empty `annotations` list is left out, so\n * re-saving a model that has no annotations changes nothing but its version stamp. The pretty\n * form is the file on disk and ends with a line break, like the files editors and Git expect;\n * the compact form (share links, local storage) has none.\n */\nexport function serializeDocument(doc: TtDocument, pretty = true): string {\n const canonical = canonicalize(doc);\n const output =\n canonical.annotations.length > 0\n ? canonical\n : Object.fromEntries(Object.entries(canonical).filter(([key]) => key !== \"annotations\"));\n return pretty ? `${JSON.stringify(output, null, 2)}\\n` : JSON.stringify(output);\n}\n","/**\n * Factory helpers for constructing well-formed model objects with the correct\n * notation defaults (sizes, labels). Kept DOM-free.\n */\n\nimport { nanoid } from \"nanoid\";\nimport { ANNOTATION_SPEC, FLOW_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\nimport type {\n FlowShape,\n InteractionMode,\n InteractionShape,\n Position,\n TeamNode,\n TeamType,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\nimport { DOCUMENT_VERSION } from \"./types\";\n\nexport function newId(prefix: string): string {\n return `${prefix}_${nanoid(8)}`;\n}\n\n/** Creates a team node of the given type at a position, with notation defaults. */\nexport function createTeamNode(\n type: TeamType,\n position: Position,\n overrides: Partial<Omit<TeamNode, \"id\" | \"type\">> = {},\n): TeamNode {\n const spec = TEAM_TYPE_SPECS[type];\n return {\n id: newId(\"team\"),\n type,\n label: overrides.label ?? spec.label,\n description: overrides.description,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed interaction shape of the given mode, with notation defaults. */\nexport function createInteractionShape(\n mode: InteractionMode,\n position: Position,\n overrides: Partial<Omit<InteractionShape, \"id\" | \"mode\" | \"position\">> = {},\n): InteractionShape {\n const spec = INTERACTION_MODE_SPECS[mode];\n return {\n id: newId(\"int\"),\n mode,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n label: overrides.label,\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed \"flow of change\" arrow, with notation defaults. */\nexport function createFlowShape(\n position: Position,\n overrides: Partial<Omit<FlowShape, \"id\" | \"position\">> = {},\n): FlowShape {\n return {\n id: newId(\"flow\"),\n position,\n size: overrides.size ?? { ...FLOW_SPEC.defaultSize },\n label: overrides.label ?? FLOW_SPEC.label,\n };\n}\n\n/** Creates a text annotation, optionally attached to a team, interaction or flow. */\nexport function createTextAnnotation(\n position: Position,\n overrides: Partial<Omit<TextAnnotation, \"id\" | \"position\">> = {},\n): TextAnnotation {\n return {\n id: newId(\"ann\"),\n text: overrides.text ?? \"\",\n position,\n size: overrides.size ?? { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: overrides.attachedTo,\n };\n}\n\n/** An empty document with sensible defaults. */\nexport function emptyDocument(title = \"Untitled team topology\"): TtDocument {\n return {\n version: DOCUMENT_VERSION,\n title,\n nodes: [],\n interactions: [],\n flows: [],\n annotations: [],\n };\n}\n","/**\n * A small but complete example diagram exercising all four team types, all three\n * interaction modes (as placed shapes overlaying the team boundaries), a\n * flow-of-change element and an attached annotation. The stream-aligned teams\n * are stacked as parallel lanes along the flow of change, as in the Team\n * Topologies book: side by side on the flow they would read as hand-offs. Ids are\n * fixed so the fixture serialises stably.\n */\n\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type { TtDocument } from \"./types\";\nimport { ANNOTATION_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\n\nconst s = TEAM_TYPE_SPECS;\nconst i = INTERACTION_MODE_SPECS;\n\nconst LANE_WIDTH = 600;\n\nexport const SAMPLE_DOCUMENT: TtDocument = {\n version: DOCUMENT_VERSION,\n title: \"Online shop team topology\",\n nodes: [\n {\n id: \"team_test_automation\",\n type: \"enabling\",\n label: \"Test Automation\",\n description: \"Coaches stream-aligned teams in test automation, then steps back.\",\n position: { x: 40, y: 150 },\n size: { width: s.enabling.defaultSize.width, height: 222 },\n },\n {\n id: \"team_discovery\",\n type: \"stream-aligned\",\n label: \"Product Discovery\",\n description: \"Owns search, browsing and product pages end-to-end.\",\n position: { x: 220, y: 150 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_checkout\",\n type: \"stream-aligned\",\n label: \"Checkout & Payments\",\n description: \"Owns the checkout and payment journey end-to-end.\",\n position: { x: 220, y: 276 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fulfilment\",\n type: \"stream-aligned\",\n label: \"Order Fulfilment\",\n description: \"Owns delivery, tracking and returns end-to-end.\",\n position: { x: 220, y: 402 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fraud\",\n type: \"complicated-subsystem\",\n label: \"Fraud Detection\",\n description: \"Specialists for the real-time fraud scoring model.\",\n position: { x: 880, y: 249 },\n size: { ...s[\"complicated-subsystem\"].defaultSize },\n },\n {\n id: \"team_platform\",\n type: \"platform\",\n label: \"Cloud Platform\",\n description: \"Self-service CI/CD, runtime and observability for all teams.\",\n position: { x: 220, y: 552 },\n size: { width: LANE_WIDTH, height: 110 },\n },\n ],\n interactions: [\n {\n id: \"int_testing_discovery\",\n mode: \"facilitating\",\n position: { x: 148, y: 156 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_testing_checkout\",\n mode: \"facilitating\",\n position: { x: 148, y: 282 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_checkout_fraud\",\n mode: \"collaboration\",\n label: \"fraud rules\",\n position: { x: 794, y: 288 },\n size: { ...i.collaboration.defaultSize },\n },\n {\n id: \"int_platform_fulfilment\",\n mode: \"x-as-a-service\",\n position: { x: 476, y: 486 },\n size: { ...i[\"x-as-a-service\"].defaultSize },\n },\n ],\n flows: [\n {\n id: \"flow_main\",\n label: \"Flow of change\",\n position: { x: 40, y: 40 },\n size: { width: 1010, height: 56 },\n },\n ],\n annotations: [\n {\n id: \"ann_fraud_handover\",\n text: \"Collaboration until the fraud rules are stable (Q3), then X-as-a-Service\",\n position: { x: 880, y: 423 },\n size: { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: \"int_checkout_fraud\",\n },\n ],\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/notation.ts","../src/ids.ts","../src/schema.ts","../src/canonical-copy.ts","../src/foreign.ts","../src/serialize.ts","../src/factory.ts","../src/sample.ts"],"names":["z","i","s","nanoid"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Pure (DOM-free) domain types for the Team Topologies model.\n *\n * This module is the canonical representation of a diagram and must never\n * import from the rendering layer (`@xyflow/react`) or touch the DOM, so it\n * can be unit-tested in isolation and reused across views / exporters.\n */\n\n/** MIME type used when dragging a team type from the palette onto the canvas. */\nexport const DND_MIME = \"application/x-tt-team-type\";\n\n/** The four fundamental team types in Team Topologies. */\nexport type TeamType = \"stream-aligned\" | \"enabling\" | \"complicated-subsystem\" | \"platform\";\n\nexport const TEAM_TYPES: readonly TeamType[] = [\n \"stream-aligned\",\n \"enabling\",\n \"complicated-subsystem\",\n \"platform\",\n] as const;\n\n/** The three core team interaction modes in Team Topologies. */\nexport type InteractionMode = \"collaboration\" | \"x-as-a-service\" | \"facilitating\";\n\nexport const INTERACTION_MODES: readonly InteractionMode[] = [\n \"collaboration\",\n \"x-as-a-service\",\n \"facilitating\",\n] as const;\n\n/** Geometric size of a node in canvas units (px). Encodes cognitive load. */\nexport interface Size {\n width: number;\n height: number;\n}\n\n/** Position of a node on the canvas in canvas units (px). */\nexport interface Position {\n x: number;\n y: number;\n}\n\n/** A team node in the canonical document model. */\nexport interface TeamNode {\n id: string;\n type: TeamType;\n label: string;\n description?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * An interaction in the canonical document model.\n *\n * Per the official Team Topologies notation, an interaction is a placed,\n * resizable SHAPE (parallelogram / triangle / circle) overlaid on the boundary\n * between the teams it relates to — not a connecting line. The relationship is\n * therefore spatial (overlap), so there is no source/target reference.\n */\nexport interface InteractionShape {\n id: string;\n mode: InteractionMode;\n label?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * A \"flow of change\" guide: a placed, resizable arrow element. Lets you anchor\n * the implied left-to-right flow, and visualise several team groupings on one\n * canvas.\n */\nexport interface FlowShape {\n id: string;\n label?: string;\n position: Position;\n size: Size;\n}\n\n/**\n * A free-text note beside the diagram (like a BPMN text annotation). It either\n * stands alone or is attached to exactly one team, interaction or flow, which\n * its dashed connector points at.\n */\nexport interface TextAnnotation {\n id: string;\n text: string;\n position: Position;\n size: Size;\n /** Id of the team, interaction or flow this annotation is attached to. */\n attachedTo?: string;\n}\n\n/** Current document schema version. Bump + add a migration when shape changes. */\nexport const DOCUMENT_VERSION = 3 as const;\n\n/**\n * A complete Team Topologies diagram. This is what gets serialised to JSON,\n * embedded into exported images, and encoded into share URLs.\n */\nexport interface TtDocument {\n version: typeof DOCUMENT_VERSION;\n title: string;\n nodes: TeamNode[];\n interactions: InteractionShape[];\n flows: FlowShape[];\n annotations: TextAnnotation[];\n}\n","/**\n * The Team Topologies visual notation, encoded as data.\n *\n * Colours, shapes and stroke styles follow the official\n * \"Team-Shape-Templates\" specification published by Team Topologies\n * (https://github.com/TeamTopologies/Team-Shape-Templates):\n *\n * - Team shapes are SOLID outlines (long-lived structures).\n * - Interaction-mode shapes are 50% transparent with DASHED outlines\n * (short-lived interactions).\n * - Each element is distinguished by SHAPE as well as colour, so the\n * notation stays readable for people with colour-vision deficiency.\n *\n * This module is pure data — it must not import the rendering layer.\n */\n\nimport type { InteractionMode, Size, TeamType } from \"./types\";\n\nexport type TeamShape = \"rounded-rect-horizontal\" | \"rounded-rect-vertical\" | \"octagon\" | \"rect\";\n\nexport type InteractionGlyph = \"parallelogram\" | \"triangle\" | \"circle\";\n\nexport type StrokeStyle = \"solid\" | \"dashed\" | \"dotted\";\n\nexport interface TeamTypeSpec {\n type: TeamType;\n /** Short display name. */\n label: string;\n /** One-line purpose, shown in the palette and inspector. */\n description: string;\n shape: TeamShape;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /** Default size when a node of this type is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\nexport interface InteractionModeSpec {\n mode: InteractionMode;\n label: string;\n description: string;\n shape: InteractionGlyph;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /**\n * The templates' fill opacity (short-lived → translucent). The renderer premixes the fill over\n * white at it and draws it opaque.\n */\n opacity: number;\n /** Whether direction is semantically meaningful (the X-as-a-Service triangle). */\n directional: boolean;\n /** Default size when a shape of this mode is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\n/** The left-to-right \"flow of change\" guide, a placeable annotation element. */\nexport interface FlowSpec {\n label: string;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n defaultSize: Size;\n minSize: Size;\n}\n\n// The official notation colours (Team-Shape-Templates, above): foreign notation, guide §10.6.\n// brand-lint-disable\nexport const TEAM_TYPE_SPECS: Record<TeamType, TeamTypeSpec> = {\n \"stream-aligned\": {\n type: \"stream-aligned\",\n label: \"Stream-aligned\",\n description: \"Aligned to a single, valuable stream of work; owns it end-to-end.\",\n shape: \"rounded-rect-horizontal\",\n fill: \"#FFEDB8\",\n stroke: \"#FFD966\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 240, height: 96 },\n minSize: { width: 140, height: 64 },\n },\n enabling: {\n type: \"enabling\",\n label: \"Enabling\",\n description:\n \"Helps stream-aligned teams acquire missing capabilities; coaches, then steps back.\",\n shape: \"rounded-rect-vertical\",\n fill: \"#DFBDCF\",\n stroke: \"#D09CB7\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 120, height: 200 },\n minSize: { width: 80, height: 120 },\n },\n \"complicated-subsystem\": {\n type: \"complicated-subsystem\",\n label: \"Complicated Subsystem\",\n description:\n \"Owns a part of the system needing deep specialist knowledge, reducing others' cognitive load.\",\n shape: \"octagon\",\n fill: \"#FFC08B\",\n stroke: \"#E88814\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 170, height: 150 },\n minSize: { width: 110, height: 100 },\n },\n platform: {\n type: \"platform\",\n label: \"Platform\",\n description:\n \"Provides internal self-service capabilities to reduce cognitive load for stream-aligned teams.\",\n shape: \"rect\",\n fill: \"#B7CDF1\",\n stroke: \"#6D9EEB\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 380, height: 130 },\n minSize: { width: 200, height: 90 },\n },\n};\n\nexport const INTERACTION_MODE_SPECS: Record<InteractionMode, InteractionModeSpec> = {\n collaboration: {\n mode: \"collaboration\",\n label: \"Collaboration\",\n description:\n \"Two teams work closely together for a defined period; high overhead, high discovery.\",\n shape: \"parallelogram\",\n fill: \"#C6BEDF\",\n stroke: \"#967EE2\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 112, height: 72 },\n minSize: { width: 60, height: 44 },\n },\n \"x-as-a-service\": {\n mode: \"x-as-a-service\",\n label: \"X-as-a-Service\",\n description:\n \"One team consumes something the other provides 'as a service'; minimal collaboration.\",\n shape: \"triangle\",\n fill: \"#B4B4B4\",\n stroke: \"#999696\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: true,\n defaultSize: { width: 88, height: 78 },\n minSize: { width: 54, height: 48 },\n },\n facilitating: {\n mode: \"facilitating\",\n label: \"Facilitating\",\n description:\n \"One team helps/coaches another to clear impediments and learn; sensing and discovery.\",\n shape: \"circle\",\n fill: \"#C9DFBE\",\n stroke: \"#78996B\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 84, height: 84 },\n minSize: { width: 48, height: 48 },\n },\n};\n\n/**\n * The \"flow of change\" guide — a placeable dashed arrow (left-to-right).\n * Not a team or interaction: a standalone annotation element.\n */\nexport const FLOW_SPEC: FlowSpec = {\n label: \"Flow of change\",\n fill: \"transparent\",\n stroke: \"#6b6459\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n defaultSize: { width: 520, height: 64 },\n minSize: { width: 160, height: 36 },\n};\n// brand-lint-enable\n\n/**\n * A text annotation — not part of the Team Topologies notation, so it carries\n * no colours here; the renderer draws it in the neutral brand ink.\n */\nexport interface AnnotationSpec {\n label: string;\n defaultSize: Size;\n minSize: Size;\n}\n\nexport const ANNOTATION_SPEC: AnnotationSpec = {\n label: \"Annotation\",\n defaultSize: { width: 200, height: 64 },\n minSize: { width: 60, height: 30 },\n};\n\n/** Maps a stroke style to an SVG/CSS dash array (empty string = solid). */\nexport function dashArray(style: StrokeStyle, strokeWidth = 2): string {\n switch (style) {\n case \"dashed\":\n return `${strokeWidth * 3} ${strokeWidth * 2}`;\n case \"dotted\":\n return `${strokeWidth} ${strokeWidth * 1.5}`;\n case \"solid\":\n default:\n return \"\";\n }\n}\n\nexport const ALL_TEAM_SPECS: readonly TeamTypeSpec[] = Object.values(TEAM_TYPE_SPECS);\nexport const ALL_INTERACTION_SPECS: readonly InteractionModeSpec[] =\n Object.values(INTERACTION_MODE_SPECS);\n","/**\n * The id rules of a Team Topologies document. Besides the elements a document lists, a diagram\n * holds parts it never writes down: the diagram itself and the connector of every annotation. They\n * take ids of their own, so no element may use one of them; otherwise opening the file would fail\n * halfway, with the previous diagram already gone. The canvas also keeps its elements in a plain\n * object, where the names of JavaScript's built-in object properties already resolve.\n */\n\n/** The id of the diagram itself (the canvas root of the renderer). */\nexport const DIAGRAM_ROOT_ID = \"tt-root\";\n\n/** diagram-js names the roots it creates on its own `__implicitroot_<n>`. */\nconst ENGINE_ROOT_ID_PREFIX = \"__implicitroot\";\n\n/** Connectors are not stored: an annotation's connector derives its id from the annotation. */\nexport function associationId(annotationId: string): string {\n return `assoc_${annotationId}`;\n}\n\nexport interface DocumentIdProblem {\n /** Where the offending id sits, e.g. `[\"nodes\", 2, \"id\"]`. */\n path: (string | number)[];\n message: string;\n}\n\nconst COLLECTIONS = [\"nodes\", \"interactions\", \"flows\", \"annotations\"] as const;\n\ntype DocumentElements = Record<(typeof COLLECTIONS)[number], readonly { id: string }[]>;\n\n/** Ids such as `constructor`, `toString` or `__proto__`, which every plain object already has. */\nfunction isBuiltInPropertyId(id: string): boolean {\n return Object.hasOwn(Object.prototype, id);\n}\n\n/**\n * Every id of the document that would collide on the canvas: a duplicate, the diagram's own id, a\n * diagram-js root id, the name of a built-in object property, or the id of an annotation's\n * connector.\n */\nexport function documentIdProblems(doc: DocumentElements): DocumentIdProblem[] {\n const problems: DocumentIdProblem[] = [];\n const connectorIds = new Map(\n doc.annotations.map((annotation) => [associationId(annotation.id), annotation.id]),\n );\n const seen = new Set<string>();\n for (const collection of COLLECTIONS) {\n doc[collection].forEach((element, index) => {\n const path = [collection, index, \"id\"];\n const { id } = element;\n if (seen.has(id)) {\n problems.push({\n path,\n message: `duplicate id \"${id}\"; ids must be unique across nodes, interactions, flows and annotations`,\n });\n }\n seen.add(id);\n if (id === DIAGRAM_ROOT_ID) {\n problems.push({ path, message: `\"${id}\" is reserved for the diagram itself` });\n } else if (id.startsWith(ENGINE_ROOT_ID_PREFIX)) {\n problems.push({\n path,\n message: `ids starting with \"${ENGINE_ROOT_ID_PREFIX}\" are reserved`,\n });\n } else if (isBuiltInPropertyId(id)) {\n problems.push({\n path,\n message: `\"${id}\" is reserved: it names a built-in property of JavaScript objects`,\n });\n }\n const annotationId = connectorIds.get(id);\n if (annotationId !== undefined) {\n problems.push({\n path,\n message: `\"${id}\" is reserved for the connector of annotation \"${annotationId}\"`,\n });\n }\n });\n }\n return problems;\n}\n","/**\n * Runtime validation for the document model using Zod.\n *\n * Anything entering the app from the outside world (imported files, share\n * URLs, localStorage) is parsed through {@link parseDocument} so malformed or\n * tampered data can never corrupt the editor state. Fields the schema does not\n * know pass through untouched (see `foreign.ts`), so another tool's data\n * survives a save.\n */\n\nimport { z } from \"zod\";\nimport { documentIdProblems } from \"./ids\";\nimport { DOCUMENT_VERSION, INTERACTION_MODES, TEAM_TYPES } from \"./types\";\nimport type { TtDocument } from \"./types\";\n\nconst teamTypeSchema = z.enum(TEAM_TYPES as unknown as [string, ...string[]]);\nconst interactionModeSchema = z.enum(INTERACTION_MODES as unknown as [string, ...string[]]);\n\nconst sizeSchema = z.object({\n width: z.number().finite().positive(),\n height: z.number().finite().positive(),\n});\n\nconst positionSchema = z.object({\n x: z.number().finite(),\n y: z.number().finite(),\n});\n\nconst hexColor = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, \"expected a hex colour\");\n\nexport const teamNodeSchema = z.looseObject({\n id: z.string().min(1),\n type: teamTypeSchema,\n label: z.string(),\n description: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const interactionSchema = z.looseObject({\n id: z.string().min(1),\n mode: interactionModeSchema,\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const flowSchema = z.looseObject({\n id: z.string().min(1),\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n});\n\nexport const annotationSchema = z.looseObject({\n id: z.string().min(1),\n text: z.string(),\n position: positionSchema,\n size: sizeSchema,\n attachedTo: z.string().min(1).optional(),\n});\n\nexport const documentSchema = z\n .looseObject({\n version: z.literal(DOCUMENT_VERSION),\n title: z.string(),\n nodes: z.array(teamNodeSchema),\n interactions: z.array(interactionSchema),\n flows: z.array(flowSchema),\n annotations: z.array(annotationSchema),\n })\n .superRefine((document, context) => {\n for (const { path, message } of documentIdProblems(document)) {\n context.addIssue({ code: \"custom\", path, message });\n }\n });\n\n/** One reason a document is invalid, at the path of the offending value. */\nexport interface DocumentIssue {\n path: (string | number)[];\n message: string;\n}\n\nexport type ParseResult =\n { ok: true; document: TtDocument } | { ok: false; error: string; issues: DocumentIssue[] };\n\n/**\n * Objects and arrays nested deeper than this make a document invalid, the document itself counting\n * as the first level. The serializer, structured cloning and JSON tooling such as jsonc-parser\n * descend one call per level and overflow the stack a few thousand levels down; a Team Topologies\n * document needs four.\n */\nexport const MAX_NESTING_DEPTH = 100;\n\n/**\n * Validates and (if necessary) migrates unknown data into a {@link TtDocument}.\n * Returns a discriminated result rather than throwing so callers can show a\n * friendly message, or point at each offending value (`issues`).\n */\nexport function parseDocument(input: unknown): ParseResult {\n const tooDeep = nestingIssues(input);\n if (tooDeep.length > 0) return refused(tooDeep);\n const { document: migrated, interactionFileIndexes } = migrate(input);\n const result = documentSchema.safeParse(migrated);\n if (!result.success) {\n return refused(\n result.error.issues.map((issue) => ({\n path: pathInFile(\n issue.path.filter((key): key is string | number => typeof key !== \"symbol\"),\n interactionFileIndexes,\n ),\n message: issue.message,\n })),\n );\n }\n return { ok: true, document: result.data as TtDocument };\n}\n\nfunction refused(issues: DocumentIssue[]): ParseResult {\n return {\n ok: false,\n error: issues.map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`).join(\"; \"),\n issues,\n };\n}\n\n/**\n * At most this many nesting issues per document. Each carries a path of {@link MAX_NESTING_DEPTH}\n * keys, so one wide container beyond the limit would otherwise give millions of them and an error\n * text longer than a string may be.\n */\nconst MAX_NESTING_ISSUES = 100;\n\ninterface OpenContainer {\n readonly container: object;\n readonly keys: readonly string[] | undefined;\n readonly size: number;\n next: number;\n readonly keyInParent: string | number | undefined;\n}\n\n/**\n * Each object or array at the first level beyond {@link MAX_NESTING_DEPTH}, in document order, up\n * to {@link MAX_NESTING_ISSUES}; what lies below it is not visited. Walked with an explicit stack,\n * because the documents it guards against are the ones that overflow a recursive walk. The stack\n * holds only the containers the walk is inside of and a path is built only for an issue, so the\n * walk's memory grows with the number of containers, not with their number times their depth.\n */\nfunction nestingIssues(input: unknown): DocumentIssue[] {\n const issues: DocumentIssue[] = [];\n if (!isContainer(input)) return issues;\n // A caller in JavaScript may put one container in several places, or inside itself: walking it\n // again at a level no deeper than before finds nothing new, and would grow exponentially.\n const deepestWalk = new WeakMap<object, number>();\n const open: OpenContainer[] = [];\n const enter = (container: object, keyInParent?: string | number): void => {\n deepestWalk.set(container, open.length);\n const keys = Array.isArray(container) ? undefined : Object.keys(container);\n const size = keys?.length ?? (container as unknown[]).length;\n open.push({ container, keys, size, next: 0, keyInParent });\n };\n enter(input);\n while (open.length > 0 && issues.length < MAX_NESTING_ISSUES) {\n const current = open[open.length - 1]!;\n if (current.next === current.size) {\n open.pop();\n continue;\n }\n const index = current.next++;\n const key = current.keys === undefined ? index : current.keys[index]!;\n const entry: unknown = (current.container as Record<string | number, unknown>)[key];\n if (!isContainer(entry)) continue;\n if (open.length >= MAX_NESTING_DEPTH) {\n issues.push({\n path: [...open.flatMap(({ keyInParent }) => keyInParent ?? []), key],\n message: `objects and arrays may nest at most ${MAX_NESTING_DEPTH} levels deep`,\n });\n continue;\n }\n if ((deepestWalk.get(entry) ?? -1) >= open.length) continue;\n enter(entry, key);\n }\n return issues;\n}\n\nfunction isContainer(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\n/** The last document version that modelled interactions as edges without geometry. */\nconst EDGE_INTERACTIONS_VERSION = 1;\n\ninterface Migration {\n document: unknown;\n /** For each interaction the migrated document keeps, its index in the input. */\n interactionFileIndexes: readonly number[];\n}\n\n/**\n * Forward-migrates older document shapes to the current version. v1 modelled\n * interactions as edges (source/target, no geometry) and carried a\n * `showFlowOfChange` flag; v2 makes interactions placed shapes and adds `flows`;\n * v3 adds `annotations`. The edge-interactions of a v1 file can't be placed\n * meaningfully, so they're dropped. From v2 on, an interaction without position\n * or size is refused like any other missing field: dropped, it would vanish from\n * the file on the next save without a word.\n */\nfunction migrate(input: unknown): Migration {\n if (input == null || typeof input !== \"object\") {\n return { document: input, interactionFileIndexes: [] };\n }\n const doc = input as Record<string, unknown>;\n const next: Record<string, unknown> = { ...doc };\n delete next.showFlowOfChange; // v1 flag, gone in v2\n next.version = DOCUMENT_VERSION;\n if (typeof next.title !== \"string\") next.title = \"Untitled team topology\";\n if (!Array.isArray(next.nodes)) next.nodes = [];\n const dropsEdgeInteractions = doc.version === EDGE_INTERACTIONS_VERSION;\n const keptInteractions = Array.isArray(next.interactions)\n ? next.interactions\n .map((interaction: unknown, fileIndex) => ({ interaction, fileIndex }))\n .filter(({ interaction }) => !dropsEdgeInteractions || isPlacedShape(interaction))\n : [];\n next.interactions = keptInteractions.map(({ interaction }) => interaction);\n if (!Array.isArray(next.flows)) next.flows = [];\n if (!Array.isArray(next.annotations)) next.annotations = [];\n return {\n document: next,\n interactionFileIndexes: keptInteractions.map(({ fileIndex }) => fileIndex),\n };\n}\n\nfunction isPlacedShape(value: unknown): boolean {\n return value != null && typeof value === \"object\" && \"position\" in value && \"size\" in value;\n}\n\n/**\n * An issue's path in the input rather than in the migrated document: an editor points at the\n * file, and every legacy interaction dropped before an invalid one would shift its index.\n */\nfunction pathInFile(\n path: (string | number)[],\n interactionFileIndexes: readonly number[],\n): (string | number)[] {\n const [collection, index, ...rest] = path;\n if (collection !== \"interactions\" || typeof index !== \"number\") return path;\n const fileIndex = interactionFileIndexes[index];\n return fileIndex === undefined ? path : [collection, fileIndex, ...rest];\n}\n","/**\n * The copy of the fields a document carries that this modeler does not know, in canonical form.\n * Not part of the package's API: `foreign.ts` copies with a new copier on every call, the\n * serializer with one copier for the whole document, so a value the document shares counts at\n * every place.\n */\n\n/**\n * A copy holds an object or array that sits in several places at each of them. An object that\n * holds the level below twice would need memory doubling with every level, and a wide object held\n * a thousand times would need a thousand copies of it. So each time a copier copies a container\n * again, it counts that container's entries; no real document repeats this many. A document that\n * shares nothing counts none, however large it is.\n */\nconst MAX_REPEATED_ENTRIES = 1_000_000;\n\n/** Copies one value into canonical form. */\nexport type CanonicalCopy = (value: unknown) => unknown;\n\n/**\n * A copier for one document. JSON objects have no key order, so nested keys are sorted too: equal\n * data, equal bytes. A value that sits in several places is copied at each of them, and its\n * entries count at every place after the first: past {@link MAX_REPEATED_ENTRIES} such repeated\n * entries it throws, and so does a value that contains itself.\n */\nexport function canonicalCopier(): CanonicalCopy {\n // Only the containers on the current path: one object in several places is no cycle.\n const ancestors = new Set<object>();\n const copiedContainers = new WeakSet<object>();\n let repeatedEntries = 0;\n const copy = (value: unknown): unknown => {\n if (value === null || typeof value !== \"object\") return value;\n if (ancestors.has(value)) throw new Error(\"Cannot serialize a cyclic document.\");\n if (copiedContainers.has(value)) {\n repeatedEntries += Array.isArray(value) ? value.length : Object.keys(value).length;\n if (repeatedEntries > MAX_REPEATED_ENTRIES) {\n throw new Error(\n `Cannot serialize a document whose shared objects and arrays would repeat more than ${MAX_REPEATED_ENTRIES} entries.`,\n );\n }\n } else {\n copiedContainers.add(value);\n }\n ancestors.add(value);\n const record = value as Record<string, unknown>;\n const copied = Array.isArray(value)\n ? value.map(copy)\n : Object.fromEntries(\n Object.keys(record)\n .filter((key) => record[key] !== undefined)\n .sort()\n .map((key) => [key, copy(record[key])]),\n );\n ancestors.delete(value);\n return copied;\n };\n return copy;\n}\n\n/** The fields of `value` outside `knownFields`, copied by `copy`, or undefined when there are none. */\nexport function copyForeignFields(\n value: object,\n knownFields: readonly string[],\n copy: CanonicalCopy,\n): Readonly<Record<string, unknown>> | undefined {\n const record = value as Record<string, unknown>;\n const names = Object.keys(record)\n .filter((name) => !knownFields.includes(name) && record[name] !== undefined)\n .sort();\n if (names.length === 0) return undefined;\n return Object.fromEntries(names.map((name) => [name, copy(record[name])]));\n}\n\n/**\n * `known` followed by the foreign fields of `source`, copied by `copy`. Built from entries, never\n * by assignment, so a field named `__proto__` stays a field instead of replacing the prototype.\n */\nexport function appendForeignFields<T extends object>(\n known: T,\n source: object | undefined,\n knownFields: readonly string[],\n copy: CanonicalCopy,\n): T {\n const foreign = source ? copyForeignFields(source, knownFields, copy) : undefined;\n if (!foreign) return known;\n return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]) as T;\n}\n","/**\n * Fields a document carries that this modeler does not know, such as a vendor's `\"x-vendor\"` on a\n * team. They are kept through open and save, written after the known fields and sorted, so another\n * tool's data survives an edit in the modeler and the output stays deterministic.\n */\n\nimport { appendForeignFields, canonicalCopier, copyForeignFields } from \"./canonical-copy\";\n\nexport const DOCUMENT_FIELDS = [\n \"version\",\n \"title\",\n \"nodes\",\n \"interactions\",\n \"flows\",\n \"annotations\",\n] as const;\nexport const TEAM_NODE_FIELDS = [\n \"id\",\n \"type\",\n \"label\",\n \"description\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const INTERACTION_FIELDS = [\n \"id\",\n \"mode\",\n \"label\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const FLOW_FIELDS = [\"id\", \"label\", \"position\", \"size\"] as const;\nexport const ANNOTATION_FIELDS = [\"id\", \"text\", \"position\", \"size\", \"attachedTo\"] as const;\n\n/** Unknown fields by name, sorted, with their values in canonical form. */\nexport type ForeignFields = Readonly<Record<string, unknown>>;\n\n/**\n * The fields of `value` outside `knownFields`, or undefined when there are none. A value that\n * sits in several places of `value` is copied at each of them; past 1,000,000 entries repeated\n * that way it throws, and so does a value that contains itself.\n */\nexport function foreignFields(\n value: object,\n knownFields: readonly string[],\n): ForeignFields | undefined {\n return copyForeignFields(value, knownFields, canonicalCopier());\n}\n\n/**\n * `known` followed by the foreign fields of `source`. Built from entries, never by assignment, so\n * a field named `__proto__` stays a field instead of replacing the prototype. A value that sits in\n * several places of `source` is copied at each of them; past 1,000,000 entries repeated that way\n * it throws, and so does a value that contains itself.\n */\nexport function withForeignFields<T extends object>(\n known: T,\n source: object | undefined,\n knownFields: readonly string[],\n): T {\n return appendForeignFields(known, source, knownFields, canonicalCopier());\n}\n","/**\n * Deterministic serialisation of the document model.\n *\n * Producing byte-stable JSON (sorted arrays, fixed key order, rounded\n * coordinates) makes diagrams diff-friendly in version control and gives\n * stable share URLs / embedded payloads.\n */\n\nimport {\n ANNOTATION_FIELDS,\n DOCUMENT_FIELDS,\n FLOW_FIELDS,\n INTERACTION_FIELDS,\n TEAM_NODE_FIELDS,\n} from \"./foreign\";\nimport { appendForeignFields, canonicalCopier, type CanonicalCopy } from \"./canonical-copy\";\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type {\n FlowShape,\n InteractionShape,\n Position,\n Size,\n TeamNode,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\n\n/** Round to 2 decimals to strip floating-point drift from drag operations. */\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction normPosition(p: Position): Position {\n return { x: round(p.x), y: round(p.y) };\n}\n\nfunction normSize(s: Size): Size {\n return { width: round(s.width), height: round(s.height) };\n}\n\n/** Drops undefined fields and applies a fixed key order to a node. */\nfunction normNode(n: TeamNode, copy: CanonicalCopy): TeamNode {\n const out: TeamNode = {\n id: n.id,\n type: n.type,\n label: n.label,\n position: normPosition(n.position),\n size: normSize(n.size),\n };\n if (n.description) out.description = n.description;\n if (n.fill) out.fill = n.fill;\n if (n.stroke) out.stroke = n.stroke;\n return appendForeignFields(out, n, TEAM_NODE_FIELDS, copy);\n}\n\nfunction normInteraction(e: InteractionShape, copy: CanonicalCopy): InteractionShape {\n const out: InteractionShape = {\n id: e.id,\n mode: e.mode,\n position: normPosition(e.position),\n size: normSize(e.size),\n };\n if (e.label) out.label = e.label;\n if (e.fill) out.fill = e.fill;\n if (e.stroke) out.stroke = e.stroke;\n return appendForeignFields(out, e, INTERACTION_FIELDS, copy);\n}\n\nfunction normFlow(f: FlowShape, copy: CanonicalCopy): FlowShape {\n const out: FlowShape = {\n id: f.id,\n position: normPosition(f.position),\n size: normSize(f.size),\n };\n if (f.label) out.label = f.label;\n return appendForeignFields(out, f, FLOW_FIELDS, copy);\n}\n\nfunction normAnnotation(a: TextAnnotation, copy: CanonicalCopy): TextAnnotation {\n const out: TextAnnotation = {\n id: a.id,\n text: a.text,\n position: normPosition(a.position),\n size: normSize(a.size),\n };\n if (a.attachedTo) out.attachedTo = a.attachedTo;\n return appendForeignFields(out, a, ANNOTATION_FIELDS, copy);\n}\n\nconst byId = (a: { id: string }, b: { id: string }): number =>\n a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\n/**\n * Returns a canonicalised copy of a document (sorted, rounded, version-stamped). Fields the\n * modeler does not know follow the known ones, sorted by name. A value of such a field that sits\n * in several places of the document is copied at each of them, and its entries count at every\n * place after the first: past 1,000,000 such repeated entries it throws, and so does a value that\n * contains itself. A document that shares nothing has no such limit.\n */\nexport function canonicalize(doc: TtDocument): TtDocument {\n const copy = canonicalCopier();\n return appendForeignFields(\n {\n version: DOCUMENT_VERSION,\n title: doc.title,\n nodes: [...doc.nodes].map((node) => normNode(node, copy)).sort(byId),\n interactions: [...doc.interactions]\n .map((interaction) => normInteraction(interaction, copy))\n .sort(byId),\n flows: [...doc.flows].map((flow) => normFlow(flow, copy)).sort(byId),\n annotations: [...doc.annotations]\n .map((annotation) => normAnnotation(annotation, copy))\n .sort(byId),\n },\n doc,\n DOCUMENT_FIELDS,\n copy,\n );\n}\n\n/**\n * Serialises a document to deterministic JSON. An empty `annotations` list is left out, so\n * re-saving a model that has no annotations changes nothing but its version stamp. The pretty\n * form is the file on disk and ends with a line break, like the files editors and Git expect;\n * the compact form (share links, local storage) has none.\n */\nexport function serializeDocument(doc: TtDocument, pretty = true): string {\n const canonical = canonicalize(doc);\n const output =\n canonical.annotations.length > 0\n ? canonical\n : Object.fromEntries(Object.entries(canonical).filter(([key]) => key !== \"annotations\"));\n return pretty ? `${JSON.stringify(output, null, 2)}\\n` : JSON.stringify(output);\n}\n","/**\n * Factory helpers for constructing well-formed model objects with the correct\n * notation defaults (sizes, labels). Kept DOM-free.\n */\n\nimport { nanoid } from \"nanoid\";\nimport { ANNOTATION_SPEC, FLOW_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\nimport type {\n FlowShape,\n InteractionMode,\n InteractionShape,\n Position,\n TeamNode,\n TeamType,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\nimport { DOCUMENT_VERSION } from \"./types\";\n\nexport function newId(prefix: string): string {\n return `${prefix}_${nanoid(8)}`;\n}\n\n/** Creates a team node of the given type at a position, with notation defaults. */\nexport function createTeamNode(\n type: TeamType,\n position: Position,\n overrides: Partial<Omit<TeamNode, \"id\" | \"type\">> = {},\n): TeamNode {\n const spec = TEAM_TYPE_SPECS[type];\n return {\n id: newId(\"team\"),\n type,\n label: overrides.label ?? spec.label,\n description: overrides.description,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed interaction shape of the given mode, with notation defaults. */\nexport function createInteractionShape(\n mode: InteractionMode,\n position: Position,\n overrides: Partial<Omit<InteractionShape, \"id\" | \"mode\" | \"position\">> = {},\n): InteractionShape {\n const spec = INTERACTION_MODE_SPECS[mode];\n return {\n id: newId(\"int\"),\n mode,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n label: overrides.label,\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed \"flow of change\" arrow, with notation defaults. */\nexport function createFlowShape(\n position: Position,\n overrides: Partial<Omit<FlowShape, \"id\" | \"position\">> = {},\n): FlowShape {\n return {\n id: newId(\"flow\"),\n position,\n size: overrides.size ?? { ...FLOW_SPEC.defaultSize },\n label: overrides.label ?? FLOW_SPEC.label,\n };\n}\n\n/** Creates a text annotation, optionally attached to a team, interaction or flow. */\nexport function createTextAnnotation(\n position: Position,\n overrides: Partial<Omit<TextAnnotation, \"id\" | \"position\">> = {},\n): TextAnnotation {\n return {\n id: newId(\"ann\"),\n text: overrides.text ?? \"\",\n position,\n size: overrides.size ?? { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: overrides.attachedTo,\n };\n}\n\n/** An empty document with sensible defaults. */\nexport function emptyDocument(title = \"Untitled team topology\"): TtDocument {\n return {\n version: DOCUMENT_VERSION,\n title,\n nodes: [],\n interactions: [],\n flows: [],\n annotations: [],\n };\n}\n","/**\n * A small but complete example diagram exercising all four team types, all three\n * interaction modes (as placed shapes overlaying the team boundaries), a\n * flow-of-change element and an attached annotation. The stream-aligned teams\n * are stacked as parallel lanes along the flow of change, as in the Team\n * Topologies book: side by side on the flow they would read as hand-offs. Ids are\n * fixed so the fixture serialises stably.\n */\n\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type { TtDocument } from \"./types\";\nimport { ANNOTATION_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\n\nconst s = TEAM_TYPE_SPECS;\nconst i = INTERACTION_MODE_SPECS;\n\nconst LANE_WIDTH = 600;\n\nexport const SAMPLE_DOCUMENT: TtDocument = {\n version: DOCUMENT_VERSION,\n title: \"Online shop team topology\",\n nodes: [\n {\n id: \"team_test_automation\",\n type: \"enabling\",\n label: \"Test Automation\",\n description: \"Coaches stream-aligned teams in test automation, then steps back.\",\n position: { x: 40, y: 150 },\n size: { width: s.enabling.defaultSize.width, height: 222 },\n },\n {\n id: \"team_discovery\",\n type: \"stream-aligned\",\n label: \"Product Discovery\",\n description: \"Owns search, browsing and product pages end-to-end.\",\n position: { x: 220, y: 150 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_checkout\",\n type: \"stream-aligned\",\n label: \"Checkout & Payments\",\n description: \"Owns the checkout and payment journey end-to-end.\",\n position: { x: 220, y: 276 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fulfilment\",\n type: \"stream-aligned\",\n label: \"Order Fulfilment\",\n description: \"Owns delivery, tracking and returns end-to-end.\",\n position: { x: 220, y: 402 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fraud\",\n type: \"complicated-subsystem\",\n label: \"Fraud Detection\",\n description: \"Specialists for the real-time fraud scoring model.\",\n position: { x: 880, y: 249 },\n size: { ...s[\"complicated-subsystem\"].defaultSize },\n },\n {\n id: \"team_platform\",\n type: \"platform\",\n label: \"Cloud Platform\",\n description: \"Self-service CI/CD, runtime and observability for all teams.\",\n position: { x: 220, y: 552 },\n size: { width: LANE_WIDTH, height: 110 },\n },\n ],\n interactions: [\n {\n id: \"int_testing_discovery\",\n mode: \"facilitating\",\n position: { x: 148, y: 156 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_testing_checkout\",\n mode: \"facilitating\",\n position: { x: 148, y: 282 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_checkout_fraud\",\n mode: \"collaboration\",\n label: \"fraud rules\",\n position: { x: 794, y: 288 },\n size: { ...i.collaboration.defaultSize },\n },\n {\n id: \"int_platform_fulfilment\",\n mode: \"x-as-a-service\",\n position: { x: 476, y: 486 },\n size: { ...i[\"x-as-a-service\"].defaultSize },\n },\n ],\n flows: [\n {\n id: \"flow_main\",\n label: \"Flow of change\",\n position: { x: 40, y: 40 },\n size: { width: 1010, height: 56 },\n },\n ],\n annotations: [\n {\n id: \"ann_fraud_handover\",\n text: \"Collaboration until the fraud rules are stable (Q3), then X-as-a-Service\",\n position: { x: 880, y: 423 },\n size: { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: \"int_checkout_fraud\",\n },\n ],\n};\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -351,7 +351,10 @@ declare function parseDocument(input: unknown): ParseResult;
|
|
|
351
351
|
|
|
352
352
|
/**
|
|
353
353
|
* Returns a canonicalised copy of a document (sorted, rounded, version-stamped). Fields the
|
|
354
|
-
* modeler does not know follow the known ones, sorted by name.
|
|
354
|
+
* modeler does not know follow the known ones, sorted by name. A value of such a field that sits
|
|
355
|
+
* in several places of the document is copied at each of them, and its entries count at every
|
|
356
|
+
* place after the first: past 1,000,000 such repeated entries it throws, and so does a value that
|
|
357
|
+
* contains itself. A document that shares nothing has no such limit.
|
|
355
358
|
*/
|
|
356
359
|
declare function canonicalize(doc: TtDocument): TtDocument;
|
|
357
360
|
/**
|
|
@@ -374,11 +377,17 @@ declare const FLOW_FIELDS: readonly ["id", "label", "position", "size"];
|
|
|
374
377
|
declare const ANNOTATION_FIELDS: readonly ["id", "text", "position", "size", "attachedTo"];
|
|
375
378
|
/** Unknown fields by name, sorted, with their values in canonical form. */
|
|
376
379
|
type ForeignFields = Readonly<Record<string, unknown>>;
|
|
377
|
-
/**
|
|
380
|
+
/**
|
|
381
|
+
* The fields of `value` outside `knownFields`, or undefined when there are none. A value that
|
|
382
|
+
* sits in several places of `value` is copied at each of them; past 1,000,000 entries repeated
|
|
383
|
+
* that way it throws, and so does a value that contains itself.
|
|
384
|
+
*/
|
|
378
385
|
declare function foreignFields(value: object, knownFields: readonly string[]): ForeignFields | undefined;
|
|
379
386
|
/**
|
|
380
387
|
* `known` followed by the foreign fields of `source`. Built from entries, never by assignment, so
|
|
381
|
-
* a field named `__proto__` stays a field instead of replacing the prototype.
|
|
388
|
+
* a field named `__proto__` stays a field instead of replacing the prototype. A value that sits in
|
|
389
|
+
* several places of `source` is copied at each of them; past 1,000,000 entries repeated that way
|
|
390
|
+
* it throws, and so does a value that contains itself.
|
|
382
391
|
*/
|
|
383
392
|
declare function withForeignFields<T extends object>(known: T, source: object | undefined, knownFields: readonly string[]): T;
|
|
384
393
|
|
package/dist/index.d.ts
CHANGED
|
@@ -351,7 +351,10 @@ declare function parseDocument(input: unknown): ParseResult;
|
|
|
351
351
|
|
|
352
352
|
/**
|
|
353
353
|
* Returns a canonicalised copy of a document (sorted, rounded, version-stamped). Fields the
|
|
354
|
-
* modeler does not know follow the known ones, sorted by name.
|
|
354
|
+
* modeler does not know follow the known ones, sorted by name. A value of such a field that sits
|
|
355
|
+
* in several places of the document is copied at each of them, and its entries count at every
|
|
356
|
+
* place after the first: past 1,000,000 such repeated entries it throws, and so does a value that
|
|
357
|
+
* contains itself. A document that shares nothing has no such limit.
|
|
355
358
|
*/
|
|
356
359
|
declare function canonicalize(doc: TtDocument): TtDocument;
|
|
357
360
|
/**
|
|
@@ -374,11 +377,17 @@ declare const FLOW_FIELDS: readonly ["id", "label", "position", "size"];
|
|
|
374
377
|
declare const ANNOTATION_FIELDS: readonly ["id", "text", "position", "size", "attachedTo"];
|
|
375
378
|
/** Unknown fields by name, sorted, with their values in canonical form. */
|
|
376
379
|
type ForeignFields = Readonly<Record<string, unknown>>;
|
|
377
|
-
/**
|
|
380
|
+
/**
|
|
381
|
+
* The fields of `value` outside `knownFields`, or undefined when there are none. A value that
|
|
382
|
+
* sits in several places of `value` is copied at each of them; past 1,000,000 entries repeated
|
|
383
|
+
* that way it throws, and so does a value that contains itself.
|
|
384
|
+
*/
|
|
378
385
|
declare function foreignFields(value: object, knownFields: readonly string[]): ForeignFields | undefined;
|
|
379
386
|
/**
|
|
380
387
|
* `known` followed by the foreign fields of `source`. Built from entries, never by assignment, so
|
|
381
|
-
* a field named `__proto__` stays a field instead of replacing the prototype.
|
|
388
|
+
* a field named `__proto__` stays a field instead of replacing the prototype. A value that sits in
|
|
389
|
+
* several places of `source` is copied at each of them; past 1,000,000 entries repeated that way
|
|
390
|
+
* it throws, and so does a value that contains itself.
|
|
382
391
|
*/
|
|
383
392
|
declare function withForeignFields<T extends object>(known: T, source: object | undefined, knownFields: readonly string[]): T;
|
|
384
393
|
|
package/dist/index.js
CHANGED
|
@@ -342,6 +342,47 @@ function pathInFile(path, interactionFileIndexes) {
|
|
|
342
342
|
return fileIndex === void 0 ? path : [collection, fileIndex, ...rest];
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
// src/canonical-copy.ts
|
|
346
|
+
var MAX_REPEATED_ENTRIES = 1e6;
|
|
347
|
+
function canonicalCopier() {
|
|
348
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
349
|
+
const copiedContainers = /* @__PURE__ */ new WeakSet();
|
|
350
|
+
let repeatedEntries = 0;
|
|
351
|
+
const copy = (value) => {
|
|
352
|
+
if (value === null || typeof value !== "object") return value;
|
|
353
|
+
if (ancestors.has(value)) throw new Error("Cannot serialize a cyclic document.");
|
|
354
|
+
if (copiedContainers.has(value)) {
|
|
355
|
+
repeatedEntries += Array.isArray(value) ? value.length : Object.keys(value).length;
|
|
356
|
+
if (repeatedEntries > MAX_REPEATED_ENTRIES) {
|
|
357
|
+
throw new Error(
|
|
358
|
+
`Cannot serialize a document whose shared objects and arrays would repeat more than ${MAX_REPEATED_ENTRIES} entries.`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
} else {
|
|
362
|
+
copiedContainers.add(value);
|
|
363
|
+
}
|
|
364
|
+
ancestors.add(value);
|
|
365
|
+
const record = value;
|
|
366
|
+
const copied = Array.isArray(value) ? value.map(copy) : Object.fromEntries(
|
|
367
|
+
Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, copy(record[key])])
|
|
368
|
+
);
|
|
369
|
+
ancestors.delete(value);
|
|
370
|
+
return copied;
|
|
371
|
+
};
|
|
372
|
+
return copy;
|
|
373
|
+
}
|
|
374
|
+
function copyForeignFields(value, knownFields, copy) {
|
|
375
|
+
const record = value;
|
|
376
|
+
const names = Object.keys(record).filter((name) => !knownFields.includes(name) && record[name] !== void 0).sort();
|
|
377
|
+
if (names.length === 0) return void 0;
|
|
378
|
+
return Object.fromEntries(names.map((name) => [name, copy(record[name])]));
|
|
379
|
+
}
|
|
380
|
+
function appendForeignFields(known, source, knownFields, copy) {
|
|
381
|
+
const foreign = source ? copyForeignFields(source, knownFields, copy) : void 0;
|
|
382
|
+
if (!foreign) return known;
|
|
383
|
+
return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]);
|
|
384
|
+
}
|
|
385
|
+
|
|
345
386
|
// src/foreign.ts
|
|
346
387
|
var DOCUMENT_FIELDS = [
|
|
347
388
|
"version",
|
|
@@ -372,24 +413,11 @@ var INTERACTION_FIELDS = [
|
|
|
372
413
|
];
|
|
373
414
|
var FLOW_FIELDS = ["id", "label", "position", "size"];
|
|
374
415
|
var ANNOTATION_FIELDS = ["id", "text", "position", "size", "attachedTo"];
|
|
375
|
-
function canonicalValue(value) {
|
|
376
|
-
if (Array.isArray(value)) return value.map(canonicalValue);
|
|
377
|
-
if (value === null || typeof value !== "object") return value;
|
|
378
|
-
const record = value;
|
|
379
|
-
return Object.fromEntries(
|
|
380
|
-
Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, canonicalValue(record[key])])
|
|
381
|
-
);
|
|
382
|
-
}
|
|
383
416
|
function foreignFields(value, knownFields) {
|
|
384
|
-
|
|
385
|
-
const names = Object.keys(record).filter((name) => !knownFields.includes(name) && record[name] !== void 0).sort();
|
|
386
|
-
if (names.length === 0) return void 0;
|
|
387
|
-
return Object.fromEntries(names.map((name) => [name, canonicalValue(record[name])]));
|
|
417
|
+
return copyForeignFields(value, knownFields, canonicalCopier());
|
|
388
418
|
}
|
|
389
419
|
function withForeignFields(known, source, knownFields) {
|
|
390
|
-
|
|
391
|
-
if (!foreign) return known;
|
|
392
|
-
return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]);
|
|
420
|
+
return appendForeignFields(known, source, knownFields, canonicalCopier());
|
|
393
421
|
}
|
|
394
422
|
|
|
395
423
|
// src/serialize.ts
|
|
@@ -402,7 +430,7 @@ function normPosition(p) {
|
|
|
402
430
|
function normSize(s2) {
|
|
403
431
|
return { width: round(s2.width), height: round(s2.height) };
|
|
404
432
|
}
|
|
405
|
-
function normNode(n) {
|
|
433
|
+
function normNode(n, copy) {
|
|
406
434
|
const out = {
|
|
407
435
|
id: n.id,
|
|
408
436
|
type: n.type,
|
|
@@ -413,9 +441,9 @@ function normNode(n) {
|
|
|
413
441
|
if (n.description) out.description = n.description;
|
|
414
442
|
if (n.fill) out.fill = n.fill;
|
|
415
443
|
if (n.stroke) out.stroke = n.stroke;
|
|
416
|
-
return
|
|
444
|
+
return appendForeignFields(out, n, TEAM_NODE_FIELDS, copy);
|
|
417
445
|
}
|
|
418
|
-
function normInteraction(e) {
|
|
446
|
+
function normInteraction(e, copy) {
|
|
419
447
|
const out = {
|
|
420
448
|
id: e.id,
|
|
421
449
|
mode: e.mode,
|
|
@@ -425,18 +453,18 @@ function normInteraction(e) {
|
|
|
425
453
|
if (e.label) out.label = e.label;
|
|
426
454
|
if (e.fill) out.fill = e.fill;
|
|
427
455
|
if (e.stroke) out.stroke = e.stroke;
|
|
428
|
-
return
|
|
456
|
+
return appendForeignFields(out, e, INTERACTION_FIELDS, copy);
|
|
429
457
|
}
|
|
430
|
-
function normFlow(f) {
|
|
458
|
+
function normFlow(f, copy) {
|
|
431
459
|
const out = {
|
|
432
460
|
id: f.id,
|
|
433
461
|
position: normPosition(f.position),
|
|
434
462
|
size: normSize(f.size)
|
|
435
463
|
};
|
|
436
464
|
if (f.label) out.label = f.label;
|
|
437
|
-
return
|
|
465
|
+
return appendForeignFields(out, f, FLOW_FIELDS, copy);
|
|
438
466
|
}
|
|
439
|
-
function normAnnotation(a) {
|
|
467
|
+
function normAnnotation(a, copy) {
|
|
440
468
|
const out = {
|
|
441
469
|
id: a.id,
|
|
442
470
|
text: a.text,
|
|
@@ -444,21 +472,23 @@ function normAnnotation(a) {
|
|
|
444
472
|
size: normSize(a.size)
|
|
445
473
|
};
|
|
446
474
|
if (a.attachedTo) out.attachedTo = a.attachedTo;
|
|
447
|
-
return
|
|
475
|
+
return appendForeignFields(out, a, ANNOTATION_FIELDS, copy);
|
|
448
476
|
}
|
|
449
477
|
var byId = (a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
450
478
|
function canonicalize(doc) {
|
|
451
|
-
|
|
479
|
+
const copy = canonicalCopier();
|
|
480
|
+
return appendForeignFields(
|
|
452
481
|
{
|
|
453
482
|
version: DOCUMENT_VERSION,
|
|
454
483
|
title: doc.title,
|
|
455
|
-
nodes: [...doc.nodes].map(normNode).sort(byId),
|
|
456
|
-
interactions: [...doc.interactions].map(normInteraction).sort(byId),
|
|
457
|
-
flows: [...doc.flows].map(normFlow).sort(byId),
|
|
458
|
-
annotations: [...doc.annotations].map(normAnnotation).sort(byId)
|
|
484
|
+
nodes: [...doc.nodes].map((node) => normNode(node, copy)).sort(byId),
|
|
485
|
+
interactions: [...doc.interactions].map((interaction) => normInteraction(interaction, copy)).sort(byId),
|
|
486
|
+
flows: [...doc.flows].map((flow) => normFlow(flow, copy)).sort(byId),
|
|
487
|
+
annotations: [...doc.annotations].map((annotation) => normAnnotation(annotation, copy)).sort(byId)
|
|
459
488
|
},
|
|
460
489
|
doc,
|
|
461
|
-
DOCUMENT_FIELDS
|
|
490
|
+
DOCUMENT_FIELDS,
|
|
491
|
+
copy
|
|
462
492
|
);
|
|
463
493
|
}
|
|
464
494
|
function serializeDocument(doc, pretty = true) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/notation.ts","../src/ids.ts","../src/schema.ts","../src/foreign.ts","../src/serialize.ts","../src/factory.ts","../src/sample.ts"],"names":["i","s"],"mappings":";;;;AASO,IAAM,QAAA,GAAW;AAKjB,IAAM,UAAA,GAAkC;AAAA,EAC7C,gBAAA;AAAA,EACA,UAAA;AAAA,EACA,uBAAA;AAAA,EACA;AACF;AAKO,IAAM,iBAAA,GAAgD;AAAA,EAC3D,eAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF;AAuEO,IAAM,gBAAA,GAAmB;;;ACvBzB,IAAM,eAAA,GAAkD;AAAA,EAC7D,gBAAA,EAAkB;AAAA,IAChB,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,EAAO,gBAAA;AAAA,IACP,WAAA,EAAa,mEAAA;AAAA,IACb,KAAA,EAAO,yBAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,OAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA,EAAG;AAAA,IACtC,OAAA,EAAS,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA;AAAG,GACpC;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,UAAA;AAAA,IACP,WAAA,EACE,oFAAA;AAAA,IACF,KAAA,EAAO,uBAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,OAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,GAAA,EAAI;AAAA,IACvC,OAAA,EAAS,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,GAAA;AAAI,GACpC;AAAA,EACA,uBAAA,EAAyB;AAAA,IACvB,IAAA,EAAM,uBAAA;AAAA,IACN,KAAA,EAAO,uBAAA;AAAA,IACP,WAAA,EACE,+FAAA;AAAA,IACF,KAAA,EAAO,SAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,OAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,GAAA,EAAI;AAAA,IACvC,OAAA,EAAS,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,GAAA;AAAI,GACrC;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,UAAA;AAAA,IACP,WAAA,EACE,gGAAA;AAAA,IACF,KAAA,EAAO,MAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,OAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,GAAA,EAAI;AAAA,IACvC,OAAA,EAAS,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA;AAAG;AAEtC;AAEO,IAAM,sBAAA,GAAuE;AAAA,EAClF,aAAA,EAAe;AAAA,IACb,IAAA,EAAM,eAAA;AAAA,IACN,KAAA,EAAO,eAAA;AAAA,IACP,WAAA,EACE,sFAAA;AAAA,IACF,KAAA,EAAO,eAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,QAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,OAAA,EAAS,GAAA;AAAA,IACT,WAAA,EAAa,KAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA,EAAG;AAAA,IACtC,OAAA,EAAS,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA;AAAG,GACnC;AAAA,EACA,gBAAA,EAAkB;AAAA,IAChB,IAAA,EAAM,gBAAA;AAAA,IACN,KAAA,EAAO,gBAAA;AAAA,IACP,WAAA,EACE,uFAAA;AAAA,IACF,KAAA,EAAO,UAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,QAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,OAAA,EAAS,GAAA;AAAA,IACT,WAAA,EAAa,IAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAG;AAAA,IACrC,OAAA,EAAS,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA;AAAG,GACnC;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO,cAAA;AAAA,IACP,WAAA,EACE,uFAAA;AAAA,IACF,KAAA,EAAO,QAAA;AAAA,IACP,IAAA,EAAM,SAAA;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,WAAA,EAAa,QAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,OAAA,EAAS,GAAA;AAAA,IACT,WAAA,EAAa,KAAA;AAAA,IACb,WAAA,EAAa,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAG;AAAA,IACrC,OAAA,EAAS,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA;AAAG;AAErC;AAMO,IAAM,SAAA,GAAsB;AAAA,EACjC,KAAA,EAAO,gBAAA;AAAA,EACP,IAAA,EAAM,aAAA;AAAA,EACN,MAAA,EAAQ,SAAA;AAAA,EACR,WAAA,EAAa,QAAA;AAAA,EACb,WAAA,EAAa,CAAA;AAAA,EACb,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA,EAAG;AAAA,EACtC,OAAA,EAAS,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA;AACjC;AAaO,IAAM,eAAA,GAAkC;AAAA,EAC7C,KAAA,EAAO,YAAA;AAAA,EACP,WAAA,EAAa,EAAE,KAAA,EAAO,GAAA,EAAK,QAAQ,EAAA,EAAG;AAAA,EACtC,OAAA,EAAS,EAAE,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA;AAChC;AAGO,SAAS,SAAA,CAAU,KAAA,EAAoB,WAAA,GAAc,CAAA,EAAW;AACrE,EAAA,QAAQ,KAAA;AAAO,IACb,KAAK,QAAA;AACH,MAAA,OAAO,CAAA,EAAG,WAAA,GAAc,CAAC,CAAA,CAAA,EAAI,cAAc,CAAC,CAAA,CAAA;AAAA,IAC9C,KAAK,QAAA;AACH,MAAA,OAAO,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,WAAA,GAAc,GAAG,CAAA,CAAA;AAAA,IAC5C,KAAK,OAAA;AAAA,IACL;AACE,MAAA,OAAO,EAAA;AAAA;AAEb;AAEO,IAAM,cAAA,GAA0C,MAAA,CAAO,MAAA,CAAO,eAAe;AAC7E,IAAM,qBAAA,GACX,MAAA,CAAO,MAAA,CAAO,sBAAsB;;;ACvN/B,IAAM,eAAA,GAAkB;AAG/B,IAAM,qBAAA,GAAwB,gBAAA;AAGvB,SAAS,cAAc,YAAA,EAA8B;AAC1D,EAAA,OAAO,SAAS,YAAY,CAAA,CAAA;AAC9B;AAQA,IAAM,WAAA,GAAc,CAAC,OAAA,EAAS,cAAA,EAAgB,SAAS,aAAa,CAAA;AAKpE,SAAS,oBAAoB,EAAA,EAAqB;AAChD,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,EAAE,CAAA;AAC3C;AAOO,SAAS,mBAAmB,GAAA,EAA4C;AAC7E,EAAA,MAAM,WAAgC,EAAC;AACvC,EAAA,MAAM,eAAe,IAAI,GAAA;AAAA,IACvB,GAAA,CAAI,WAAA,CAAY,GAAA,CAAI,CAAC,UAAA,KAAe,CAAC,aAAA,CAAc,UAAA,CAAW,EAAE,CAAA,EAAG,UAAA,CAAW,EAAE,CAAC;AAAA,GACnF;AACA,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,cAAc,WAAA,EAAa;AACpC,IAAA,GAAA,CAAI,UAAU,CAAA,CAAE,OAAA,CAAQ,CAAC,SAAS,KAAA,KAAU;AAC1C,MAAA,MAAM,IAAA,GAAO,CAAC,UAAA,EAAY,KAAA,EAAO,IAAI,CAAA;AACrC,MAAA,MAAM,EAAE,IAAG,GAAI,OAAA;AACf,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,EAAG;AAChB,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA;AAAA,UACA,OAAA,EAAS,iBAAiB,EAAE,CAAA,uEAAA;AAAA,SAC7B,CAAA;AAAA,MACH;AACA,MAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AACX,MAAA,IAAI,OAAO,eAAA,EAAiB;AAC1B,QAAA,QAAA,CAAS,KAAK,EAAE,IAAA,EAAM,SAAS,CAAA,CAAA,EAAI,EAAE,wCAAwC,CAAA;AAAA,MAC/E,CAAA,MAAA,IAAW,EAAA,CAAG,UAAA,CAAW,qBAAqB,CAAA,EAAG;AAC/C,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA;AAAA,UACA,OAAA,EAAS,sBAAsB,qBAAqB,CAAA,cAAA;AAAA,SACrD,CAAA;AAAA,MACH,CAAA,MAAA,IAAW,mBAAA,CAAoB,EAAE,CAAA,EAAG;AAClC,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA;AAAA,UACA,OAAA,EAAS,IAAI,EAAE,CAAA,iEAAA;AAAA,SAChB,CAAA;AAAA,MACH;AACA,MAAA,MAAM,YAAA,GAAe,YAAA,CAAa,GAAA,CAAI,EAAE,CAAA;AACxC,MAAA,IAAI,iBAAiB,MAAA,EAAW;AAC9B,QAAA,QAAA,CAAS,IAAA,CAAK;AAAA,UACZ,IAAA;AAAA,UACA,OAAA,EAAS,CAAA,CAAA,EAAI,EAAE,CAAA,+CAAA,EAAkD,YAAY,CAAA,CAAA;AAAA,SAC9E,CAAA;AAAA,MACH;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AACA,EAAA,OAAO,QAAA;AACT;;;AChEA,IAAM,cAAA,GAAiB,CAAA,CAAE,IAAA,CAAK,UAA8C,CAAA;AAC5E,IAAM,qBAAA,GAAwB,CAAA,CAAE,IAAA,CAAK,iBAAqD,CAAA;AAE1F,IAAM,UAAA,GAAa,EAAE,MAAA,CAAO;AAAA,EAC1B,OAAO,CAAA,CAAE,MAAA,EAAO,CAAE,MAAA,GAAS,QAAA,EAAS;AAAA,EACpC,QAAQ,CAAA,CAAE,MAAA,EAAO,CAAE,MAAA,GAAS,QAAA;AAC9B,CAAC,CAAA;AAED,IAAM,cAAA,GAAiB,EAAE,MAAA,CAAO;AAAA,EAC9B,CAAA,EAAG,CAAA,CAAE,MAAA,EAAO,CAAE,MAAA,EAAO;AAAA,EACrB,CAAA,EAAG,CAAA,CAAE,MAAA,EAAO,CAAE,MAAA;AAChB,CAAC,CAAA;AAED,IAAM,WAAW,CAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,wCAAwC,uBAAuB,CAAA;AAE1F,IAAM,cAAA,GAAiB,EAAE,WAAA,CAAY;AAAA,EAC1C,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACpB,IAAA,EAAM,cAAA;AAAA,EACN,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,EAChB,WAAA,EAAa,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,QAAA,EAAU,cAAA;AAAA,EACV,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,SAAS,QAAA,EAAS;AAAA,EACxB,MAAA,EAAQ,SAAS,QAAA;AACnB,CAAC;AAEM,IAAM,iBAAA,GAAoB,EAAE,WAAA,CAAY;AAAA,EAC7C,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACpB,IAAA,EAAM,qBAAA;AAAA,EACN,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC3B,QAAA,EAAU,cAAA;AAAA,EACV,IAAA,EAAM,UAAA;AAAA,EACN,IAAA,EAAM,SAAS,QAAA,EAAS;AAAA,EACxB,MAAA,EAAQ,SAAS,QAAA;AACnB,CAAC;AAEM,IAAM,UAAA,GAAa,EAAE,WAAA,CAAY;AAAA,EACtC,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACpB,KAAA,EAAO,CAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC3B,QAAA,EAAU,cAAA;AAAA,EACV,IAAA,EAAM;AACR,CAAC;AAEM,IAAM,gBAAA,GAAmB,EAAE,WAAA,CAAY;AAAA,EAC5C,EAAA,EAAI,CAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA;AAAA,EACpB,IAAA,EAAM,EAAE,MAAA,EAAO;AAAA,EACf,QAAA,EAAU,cAAA;AAAA,EACV,IAAA,EAAM,UAAA;AAAA,EACN,YAAY,CAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAAE,QAAA;AAChC,CAAC;AAEM,IAAM,cAAA,GAAiB,EAC3B,WAAA,CAAY;AAAA,EACX,OAAA,EAAS,CAAA,CAAE,OAAA,CAAQ,gBAAgB,CAAA;AAAA,EACnC,KAAA,EAAO,EAAE,MAAA,EAAO;AAAA,EAChB,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,cAAc,CAAA;AAAA,EAC7B,YAAA,EAAc,CAAA,CAAE,KAAA,CAAM,iBAAiB,CAAA;AAAA,EACvC,KAAA,EAAO,CAAA,CAAE,KAAA,CAAM,UAAU,CAAA;AAAA,EACzB,WAAA,EAAa,CAAA,CAAE,KAAA,CAAM,gBAAgB;AACvC,CAAC,CAAA,CACA,WAAA,CAAY,CAAC,QAAA,EAAU,OAAA,KAAY;AAClC,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,OAAA,EAAQ,IAAK,kBAAA,CAAmB,QAAQ,CAAA,EAAG;AAC5D,IAAA,OAAA,CAAQ,SAAS,EAAE,IAAA,EAAM,QAAA,EAAU,IAAA,EAAM,SAAS,CAAA;AAAA,EACpD;AACF,CAAC;AAiBI,IAAM,iBAAA,GAAoB;AAO1B,SAAS,cAAc,KAAA,EAA6B;AACzD,EAAA,MAAM,OAAA,GAAU,cAAc,KAAK,CAAA;AACnC,EAAA,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,OAAO,QAAQ,OAAO,CAAA;AAC9C,EAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,sBAAA,EAAuB,GAAI,QAAQ,KAAK,CAAA;AACpE,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,SAAA,CAAU,QAAQ,CAAA;AAChD,EAAA,IAAI,CAAC,OAAO,OAAA,EAAS;AACnB,IAAA,OAAO,OAAA;AAAA,MACL,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,QAClC,IAAA,EAAM,UAAA;AAAA,UACJ,MAAM,IAAA,CAAK,MAAA,CAAO,CAAC,GAAA,KAAgC,OAAO,QAAQ,QAAQ,CAAA;AAAA,UAC1E;AAAA,SACF;AAAA,QACA,SAAS,KAAA,CAAM;AAAA,OACjB,CAAE;AAAA,KACJ;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,QAAA,EAAU,OAAO,IAAA,EAAmB;AACzD;AAEA,SAAS,QAAQ,MAAA,EAAsC;AACrD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,KAAA;AAAA,IACJ,OAAO,MAAA,CAAO,GAAA,CAAI,CAACA,EAAAA,KAAM,CAAA,EAAGA,GAAE,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,IAAK,QAAQ,CAAA,EAAA,EAAKA,EAAAA,CAAE,OAAO,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAA;AAAA,IACnF;AAAA,GACF;AACF;AAOA,IAAM,kBAAA,GAAqB,GAAA;AAiB3B,SAAS,cAAc,KAAA,EAAiC;AACtD,EAAA,MAAM,SAA0B,EAAC;AACjC,EAAA,IAAI,CAAC,WAAA,CAAY,KAAK,CAAA,EAAG,OAAO,MAAA;AAGhC,EAAA,MAAM,WAAA,uBAAkB,OAAA,EAAwB;AAChD,EAAA,MAAM,OAAwB,EAAC;AAC/B,EAAA,MAAM,KAAA,GAAQ,CAAC,SAAA,EAAmB,WAAA,KAAwC;AACxE,IAAA,WAAA,CAAY,GAAA,CAAI,SAAA,EAAW,IAAA,CAAK,MAAM,CAAA;AACtC,IAAA,MAAM,IAAA,GAAO,MAAM,OAAA,CAAQ,SAAS,IAAI,MAAA,GAAY,MAAA,CAAO,KAAK,SAAS,CAAA;AACzE,IAAA,MAAM,IAAA,GAAO,IAAA,EAAM,MAAA,IAAW,SAAA,CAAwB,MAAA;AACtD,IAAA,IAAA,CAAK,IAAA,CAAK,EAAE,SAAA,EAAW,IAAA,EAAM,MAAM,IAAA,EAAM,CAAA,EAAG,aAAa,CAAA;AAAA,EAC3D,CAAA;AACA,EAAA,KAAA,CAAM,KAAK,CAAA;AACX,EAAA,OAAO,IAAA,CAAK,MAAA,GAAS,CAAA,IAAK,MAAA,CAAO,SAAS,kBAAA,EAAoB;AAC5D,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACpC,IAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,OAAA,CAAQ,IAAA,EAAM;AACjC,MAAA,IAAA,CAAK,GAAA,EAAI;AACT,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,OAAA,CAAQ,IAAA,EAAA;AACtB,IAAA,MAAM,MAAM,OAAA,CAAQ,IAAA,KAAS,SAAY,KAAA,GAAQ,OAAA,CAAQ,KAAK,KAAK,CAAA;AACnE,IAAA,MAAM,KAAA,GAAkB,OAAA,CAAQ,SAAA,CAA+C,GAAG,CAAA;AAClF,IAAA,IAAI,CAAC,WAAA,CAAY,KAAK,CAAA,EAAG;AACzB,IAAA,IAAI,IAAA,CAAK,UAAU,iBAAA,EAAmB;AACpC,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,CAAC,GAAG,IAAA,CAAK,OAAA,CAAQ,CAAC,EAAE,WAAA,EAAY,KAAM,WAAA,IAAe,EAAE,GAAG,GAAG,CAAA;AAAA,QACnE,OAAA,EAAS,uCAAuC,iBAAiB,CAAA,YAAA;AAAA,OAClE,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,YAAY,GAAA,CAAI,KAAK,CAAA,IAAK,EAAA,KAAO,KAAK,MAAA,EAAQ;AACnD,IAAA,KAAA,CAAM,OAAO,GAAG,CAAA;AAAA,EAClB;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,YAAY,KAAA,EAAiC;AACpD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA;AAChD;AAGA,IAAM,yBAAA,GAA4B,CAAA;AAiBlC,SAAS,QAAQ,KAAA,EAA2B;AAC1C,EAAA,IAAI,KAAA,IAAS,IAAA,IAAQ,OAAO,KAAA,KAAU,QAAA,EAAU;AAC9C,IAAA,OAAO,EAAE,QAAA,EAAU,KAAA,EAAO,sBAAA,EAAwB,EAAC,EAAE;AAAA,EACvD;AACA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,MAAM,IAAA,GAAgC,EAAE,GAAG,GAAA,EAAI;AAC/C,EAAA,OAAO,IAAA,CAAK,gBAAA;AACZ,EAAA,IAAA,CAAK,OAAA,GAAU,gBAAA;AACf,EAAA,IAAI,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,OAAe,KAAA,GAAQ,wBAAA;AACjD,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG,IAAA,CAAK,QAAQ,EAAC;AAC9C,EAAA,MAAM,qBAAA,GAAwB,IAAI,OAAA,KAAY,yBAAA;AAC9C,EAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,YAAY,CAAA,GACpD,IAAA,CAAK,YAAA,CACF,GAAA,CAAI,CAAC,WAAA,EAAsB,SAAA,MAAe,EAAE,WAAA,EAAa,SAAA,EAAU,CAAE,CAAA,CACrE,MAAA,CAAO,CAAC,EAAE,WAAA,EAAY,KAAM,CAAC,qBAAA,IAAyB,aAAA,CAAc,WAAW,CAAC,CAAA,GACnF,EAAC;AACL,EAAA,IAAA,CAAK,eAAe,gBAAA,CAAiB,GAAA,CAAI,CAAC,EAAE,WAAA,OAAkB,WAAW,CAAA;AACzE,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA,EAAG,IAAA,CAAK,QAAQ,EAAC;AAC9C,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,IAAA,CAAK,WAAW,CAAA,EAAG,IAAA,CAAK,cAAc,EAAC;AAC1D,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,IAAA;AAAA,IACV,wBAAwB,gBAAA,CAAiB,GAAA,CAAI,CAAC,EAAE,SAAA,OAAgB,SAAS;AAAA,GAC3E;AACF;AAEA,SAAS,cAAc,KAAA,EAAyB;AAC9C,EAAA,OAAO,SAAS,IAAA,IAAQ,OAAO,UAAU,QAAA,IAAY,UAAA,IAAc,SAAS,MAAA,IAAU,KAAA;AACxF;AAMA,SAAS,UAAA,CACP,MACA,sBAAA,EACqB;AACrB,EAAA,MAAM,CAAC,UAAA,EAAY,KAAA,EAAO,GAAG,IAAI,CAAA,GAAI,IAAA;AACrC,EAAA,IAAI,UAAA,KAAe,cAAA,IAAkB,OAAO,KAAA,KAAU,UAAU,OAAO,IAAA;AACvE,EAAA,MAAM,SAAA,GAAY,uBAAuB,KAAK,CAAA;AAC9C,EAAA,OAAO,cAAc,MAAA,GAAY,IAAA,GAAO,CAAC,UAAA,EAAY,SAAA,EAAW,GAAG,IAAI,CAAA;AACzE;;;ACtPO,IAAM,eAAA,GAAkB;AAAA,EAC7B,SAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,cAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF;AACO,IAAM,gBAAA,GAAmB;AAAA,EAC9B,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF;AACO,IAAM,kBAAA,GAAqB;AAAA,EAChC,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF;AACO,IAAM,WAAA,GAAc,CAAC,IAAA,EAAM,OAAA,EAAS,YAAY,MAAM;AACtD,IAAM,oBAAoB,CAAC,IAAA,EAAM,MAAA,EAAQ,UAAA,EAAY,QAAQ,YAAY;AAMhF,SAAS,eAAe,KAAA,EAAyB;AAC/C,EAAA,IAAI,MAAM,OAAA,CAAQ,KAAK,GAAG,OAAO,KAAA,CAAM,IAAI,cAAc,CAAA;AACzD,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,KAAU,UAAU,OAAO,KAAA;AACxD,EAAA,MAAM,MAAA,GAAS,KAAA;AACf,EAAA,OAAO,MAAA,CAAO,WAAA;AAAA,IACZ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CACf,MAAA,CAAO,CAAC,GAAA,KAAQ,MAAA,CAAO,GAAG,CAAA,KAAM,MAAS,CAAA,CACzC,MAAK,CACL,GAAA,CAAI,CAAC,GAAA,KAAQ,CAAC,GAAA,EAAK,eAAe,MAAA,CAAO,GAAG,CAAC,CAAC,CAAC;AAAA,GACpD;AACF;AAGO,SAAS,aAAA,CACd,OACA,WAAA,EAC2B;AAC3B,EAAA,MAAM,MAAA,GAAS,KAAA;AACf,EAAA,MAAM,QAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAC7B,MAAA,CAAO,CAAC,IAAA,KAAS,CAAC,WAAA,CAAY,QAAA,CAAS,IAAI,CAAA,IAAK,MAAA,CAAO,IAAI,CAAA,KAAM,MAAS,EAC1E,IAAA,EAAK;AACR,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAC/B,EAAA,OAAO,MAAA,CAAO,WAAA,CAAY,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,KAAS,CAAC,IAAA,EAAM,cAAA,CAAe,MAAA,CAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AACrF;AAMO,SAAS,iBAAA,CACd,KAAA,EACA,MAAA,EACA,WAAA,EACG;AACH,EAAA,MAAM,OAAA,GAAU,MAAA,GAAS,aAAA,CAAc,MAAA,EAAQ,WAAW,CAAA,GAAI,MAAA;AAC9D,EAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,EAAA,OAAO,MAAA,CAAO,WAAA,CAAY,CAAC,GAAG,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG,GAAG,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAC,CAAC,CAAA;AAClF;;;ACjDA,SAAS,MAAM,CAAA,EAAmB;AAChC,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,GAAG,CAAA,GAAI,GAAA;AAC/B;AAEA,SAAS,aAAa,CAAA,EAAuB;AAC3C,EAAA,OAAO,EAAE,CAAA,EAAG,KAAA,CAAM,CAAA,CAAE,CAAC,GAAG,CAAA,EAAG,KAAA,CAAM,CAAA,CAAE,CAAC,CAAA,EAAE;AACxC;AAEA,SAAS,SAASC,EAAAA,EAAe;AAC/B,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,CAAMA,EAAAA,CAAE,KAAK,GAAG,MAAA,EAAQ,KAAA,CAAMA,EAAAA,CAAE,MAAM,CAAA,EAAE;AAC1D;AAGA,SAAS,SAAS,CAAA,EAAuB;AACvC,EAAA,MAAM,GAAA,GAAgB;AAAA,IACpB,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,QAAA,EAAU,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AAAA,IACjC,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,IAAI;AAAA,GACvB;AACA,EAAA,IAAI,CAAA,CAAE,WAAA,EAAa,GAAA,CAAI,WAAA,GAAc,CAAA,CAAE,WAAA;AACvC,EAAA,IAAI,CAAA,CAAE,IAAA,EAAM,GAAA,CAAI,IAAA,GAAO,CAAA,CAAE,IAAA;AACzB,EAAA,IAAI,CAAA,CAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,CAAA,CAAE,MAAA;AAC7B,EAAA,OAAO,iBAAA,CAAkB,GAAA,EAAK,CAAA,EAAG,gBAAgB,CAAA;AACnD;AAEA,SAAS,gBAAgB,CAAA,EAAuC;AAC9D,EAAA,MAAM,GAAA,GAAwB;AAAA,IAC5B,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,QAAA,EAAU,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AAAA,IACjC,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,IAAI;AAAA,GACvB;AACA,EAAA,IAAI,CAAA,CAAE,KAAA,EAAO,GAAA,CAAI,KAAA,GAAQ,CAAA,CAAE,KAAA;AAC3B,EAAA,IAAI,CAAA,CAAE,IAAA,EAAM,GAAA,CAAI,IAAA,GAAO,CAAA,CAAE,IAAA;AACzB,EAAA,IAAI,CAAA,CAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,GAAS,CAAA,CAAE,MAAA;AAC7B,EAAA,OAAO,iBAAA,CAAkB,GAAA,EAAK,CAAA,EAAG,kBAAkB,CAAA;AACrD;AAEA,SAAS,SAAS,CAAA,EAAyB;AACzC,EAAA,MAAM,GAAA,GAAiB;AAAA,IACrB,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,QAAA,EAAU,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AAAA,IACjC,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,IAAI;AAAA,GACvB;AACA,EAAA,IAAI,CAAA,CAAE,KAAA,EAAO,GAAA,CAAI,KAAA,GAAQ,CAAA,CAAE,KAAA;AAC3B,EAAA,OAAO,iBAAA,CAAkB,GAAA,EAAK,CAAA,EAAG,WAAW,CAAA;AAC9C;AAEA,SAAS,eAAe,CAAA,EAAmC;AACzD,EAAA,MAAM,GAAA,GAAsB;AAAA,IAC1B,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,QAAA,EAAU,YAAA,CAAa,CAAA,CAAE,QAAQ,CAAA;AAAA,IACjC,IAAA,EAAM,QAAA,CAAS,CAAA,CAAE,IAAI;AAAA,GACvB;AACA,EAAA,IAAI,CAAA,CAAE,UAAA,EAAY,GAAA,CAAI,UAAA,GAAa,CAAA,CAAE,UAAA;AACrC,EAAA,OAAO,iBAAA,CAAkB,GAAA,EAAK,CAAA,EAAG,iBAAiB,CAAA;AACpD;AAEA,IAAM,IAAA,GAAO,CAAC,CAAA,EAAmB,CAAA,KAC/B,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,EAAA,GAAK,EAAA,GAAK,CAAA,CAAE,EAAA,GAAK,CAAA,CAAE,KAAK,CAAA,GAAI,CAAA;AAMhC,SAAS,aAAa,GAAA,EAA6B;AACxD,EAAA,OAAO,iBAAA;AAAA,IACL;AAAA,MACE,OAAA,EAAS,gBAAA;AAAA,MACT,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,KAAA,EAAO,CAAC,GAAG,GAAA,CAAI,KAAK,EAAE,GAAA,CAAI,QAAQ,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,MAC7C,YAAA,EAAc,CAAC,GAAG,GAAA,CAAI,YAAY,EAAE,GAAA,CAAI,eAAe,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,MAClE,KAAA,EAAO,CAAC,GAAG,GAAA,CAAI,KAAK,EAAE,GAAA,CAAI,QAAQ,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,MAC7C,WAAA,EAAa,CAAC,GAAG,GAAA,CAAI,WAAW,EAAE,GAAA,CAAI,cAAc,CAAA,CAAE,IAAA,CAAK,IAAI;AAAA,KACjE;AAAA,IACA,GAAA;AAAA,IACA;AAAA,GACF;AACF;AAQO,SAAS,iBAAA,CAAkB,GAAA,EAAiB,MAAA,GAAS,IAAA,EAAc;AACxE,EAAA,MAAM,SAAA,GAAY,aAAa,GAAG,CAAA;AAClC,EAAA,MAAM,SACJ,SAAA,CAAU,WAAA,CAAY,SAAS,CAAA,GAC3B,SAAA,GACA,OAAO,WAAA,CAAY,MAAA,CAAO,QAAQ,SAAS,CAAA,CAAE,OAAO,CAAC,CAAC,GAAG,CAAA,KAAM,GAAA,KAAQ,aAAa,CAAC,CAAA;AAC3F,EAAA,OAAO,SAAS,CAAA,EAAG,IAAA,CAAK,UAAU,MAAA,EAAQ,IAAA,EAAM,CAAC,CAAC;AAAA,CAAA,GAAO,IAAA,CAAK,UAAU,MAAM,CAAA;AAChF;ACzGO,SAAS,MAAM,MAAA,EAAwB;AAC5C,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,CAAC,CAAC,CAAA,CAAA;AAC/B;AAGO,SAAS,cAAA,CACd,IAAA,EACA,QAAA,EACA,SAAA,GAAoD,EAAC,EAC3C;AACV,EAAA,MAAM,IAAA,GAAO,gBAAgB,IAAI,CAAA;AACjC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAM,MAAM,CAAA;AAAA,IAChB,IAAA;AAAA,IACA,KAAA,EAAO,SAAA,CAAU,KAAA,IAAS,IAAA,CAAK,KAAA;AAAA,IAC/B,aAAa,SAAA,CAAU,WAAA;AAAA,IACvB,QAAA;AAAA,IACA,MAAM,SAAA,CAAU,IAAA,IAAQ,EAAE,GAAG,KAAK,WAAA,EAAY;AAAA,IAC9C,MAAM,SAAA,CAAU,IAAA;AAAA,IAChB,QAAQ,SAAA,CAAU;AAAA,GACpB;AACF;AAGO,SAAS,sBAAA,CACd,IAAA,EACA,QAAA,EACA,SAAA,GAAyE,EAAC,EACxD;AAClB,EAAA,MAAM,IAAA,GAAO,uBAAuB,IAAI,CAAA;AACxC,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAM,KAAK,CAAA;AAAA,IACf,IAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAM,SAAA,CAAU,IAAA,IAAQ,EAAE,GAAG,KAAK,WAAA,EAAY;AAAA,IAC9C,OAAO,SAAA,CAAU,KAAA;AAAA,IACjB,MAAM,SAAA,CAAU,IAAA;AAAA,IAChB,QAAQ,SAAA,CAAU;AAAA,GACpB;AACF;AAGO,SAAS,eAAA,CACd,QAAA,EACA,SAAA,GAAyD,EAAC,EAC/C;AACX,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAM,MAAM,CAAA;AAAA,IAChB,QAAA;AAAA,IACA,MAAM,SAAA,CAAU,IAAA,IAAQ,EAAE,GAAG,UAAU,WAAA,EAAY;AAAA,IACnD,KAAA,EAAO,SAAA,CAAU,KAAA,IAAS,SAAA,CAAU;AAAA,GACtC;AACF;AAGO,SAAS,oBAAA,CACd,QAAA,EACA,SAAA,GAA8D,EAAC,EAC/C;AAChB,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,MAAM,KAAK,CAAA;AAAA,IACf,IAAA,EAAM,UAAU,IAAA,IAAQ,EAAA;AAAA,IACxB,QAAA;AAAA,IACA,MAAM,SAAA,CAAU,IAAA,IAAQ,EAAE,GAAG,gBAAgB,WAAA,EAAY;AAAA,IACzD,YAAY,SAAA,CAAU;AAAA,GACxB;AACF;AAGO,SAAS,aAAA,CAAc,QAAQ,wBAAA,EAAsC;AAC1E,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,gBAAA;AAAA,IACT,KAAA;AAAA,IACA,OAAO,EAAC;AAAA,IACR,cAAc,EAAC;AAAA,IACf,OAAO,EAAC;AAAA,IACR,aAAa;AAAC,GAChB;AACF;;;ACpFA,IAAM,CAAA,GAAI,eAAA;AACV,IAAM,CAAA,GAAI,sBAAA;AAEV,IAAM,UAAA,GAAa,GAAA;AAEZ,IAAM,eAAA,GAA8B;AAAA,EACzC,OAAA,EAAS,gBAAA;AAAA,EACT,KAAA,EAAO,2BAAA;AAAA,EACP,KAAA,EAAO;AAAA,IACL;AAAA,MACE,EAAA,EAAI,sBAAA;AAAA,MACJ,IAAA,EAAM,UAAA;AAAA,MACN,KAAA,EAAO,iBAAA;AAAA,MACP,WAAA,EAAa,mEAAA;AAAA,MACb,QAAA,EAAU,EAAE,CAAA,EAAG,EAAA,EAAI,GAAG,GAAA,EAAI;AAAA,MAC1B,IAAA,EAAM,EAAE,KAAA,EAAO,CAAA,CAAE,SAAS,WAAA,CAAY,KAAA,EAAO,QAAQ,GAAA;AAAI,KAC3D;AAAA,IACA;AAAA,MACE,EAAA,EAAI,gBAAA;AAAA,MACJ,IAAA,EAAM,gBAAA;AAAA,MACN,KAAA,EAAO,mBAAA;AAAA,MACP,WAAA,EAAa,qDAAA;AAAA,MACb,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,KAAA,EAAO,UAAA,EAAY,QAAQ,CAAA,CAAE,gBAAgB,CAAA,CAAE,WAAA,CAAY,MAAA;AAAO,KAC5E;AAAA,IACA;AAAA,MACE,EAAA,EAAI,eAAA;AAAA,MACJ,IAAA,EAAM,gBAAA;AAAA,MACN,KAAA,EAAO,qBAAA;AAAA,MACP,WAAA,EAAa,mDAAA;AAAA,MACb,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,KAAA,EAAO,UAAA,EAAY,QAAQ,CAAA,CAAE,gBAAgB,CAAA,CAAE,WAAA,CAAY,MAAA;AAAO,KAC5E;AAAA,IACA;AAAA,MACE,EAAA,EAAI,iBAAA;AAAA,MACJ,IAAA,EAAM,gBAAA;AAAA,MACN,KAAA,EAAO,kBAAA;AAAA,MACP,WAAA,EAAa,iDAAA;AAAA,MACb,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,KAAA,EAAO,UAAA,EAAY,QAAQ,CAAA,CAAE,gBAAgB,CAAA,CAAE,WAAA,CAAY,MAAA;AAAO,KAC5E;AAAA,IACA;AAAA,MACE,EAAA,EAAI,YAAA;AAAA,MACJ,IAAA,EAAM,uBAAA;AAAA,MACN,KAAA,EAAO,iBAAA;AAAA,MACP,WAAA,EAAa,oDAAA;AAAA,MACb,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,MAAM,EAAE,GAAG,CAAA,CAAE,uBAAuB,EAAE,WAAA;AAAY,KACpD;AAAA,IACA;AAAA,MACE,EAAA,EAAI,eAAA;AAAA,MACJ,IAAA,EAAM,UAAA;AAAA,MACN,KAAA,EAAO,gBAAA;AAAA,MACP,WAAA,EAAa,8DAAA;AAAA,MACb,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,KAAA,EAAO,UAAA,EAAY,QAAQ,GAAA;AAAI;AACzC,GACF;AAAA,EACA,YAAA,EAAc;AAAA,IACZ;AAAA,MACE,EAAA,EAAI,uBAAA;AAAA,MACJ,IAAA,EAAM,cAAA;AAAA,MACN,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,GAAG,CAAA,CAAE,aAAa,WAAA;AAAY,KACxC;AAAA,IACA;AAAA,MACE,EAAA,EAAI,sBAAA;AAAA,MACJ,IAAA,EAAM,cAAA;AAAA,MACN,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,GAAG,CAAA,CAAE,aAAa,WAAA;AAAY,KACxC;AAAA,IACA;AAAA,MACE,EAAA,EAAI,oBAAA;AAAA,MACJ,IAAA,EAAM,eAAA;AAAA,MACN,KAAA,EAAO,aAAA;AAAA,MACP,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,GAAG,CAAA,CAAE,cAAc,WAAA;AAAY,KACzC;AAAA,IACA;AAAA,MACE,EAAA,EAAI,yBAAA;AAAA,MACJ,IAAA,EAAM,gBAAA;AAAA,MACN,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,MAAM,EAAE,GAAG,CAAA,CAAE,gBAAgB,EAAE,WAAA;AAAY;AAC7C,GACF;AAAA,EACA,KAAA,EAAO;AAAA,IACL;AAAA,MACE,EAAA,EAAI,WAAA;AAAA,MACJ,KAAA,EAAO,gBAAA;AAAA,MACP,QAAA,EAAU,EAAE,CAAA,EAAG,EAAA,EAAI,GAAG,EAAA,EAAG;AAAA,MACzB,IAAA,EAAM,EAAE,KAAA,EAAO,IAAA,EAAM,QAAQ,EAAA;AAAG;AAClC,GACF;AAAA,EACA,WAAA,EAAa;AAAA,IACX;AAAA,MACE,EAAA,EAAI,oBAAA;AAAA,MACJ,IAAA,EAAM,0EAAA;AAAA,MACN,QAAA,EAAU,EAAE,CAAA,EAAG,GAAA,EAAK,GAAG,GAAA,EAAI;AAAA,MAC3B,IAAA,EAAM,EAAE,GAAG,eAAA,CAAgB,WAAA,EAAY;AAAA,MACvC,UAAA,EAAY;AAAA;AACd;AAEJ","file":"index.js","sourcesContent":["/**\n * Pure (DOM-free) domain types for the Team Topologies model.\n *\n * This module is the canonical representation of a diagram and must never\n * import from the rendering layer (`@xyflow/react`) or touch the DOM, so it\n * can be unit-tested in isolation and reused across views / exporters.\n */\n\n/** MIME type used when dragging a team type from the palette onto the canvas. */\nexport const DND_MIME = \"application/x-tt-team-type\";\n\n/** The four fundamental team types in Team Topologies. */\nexport type TeamType = \"stream-aligned\" | \"enabling\" | \"complicated-subsystem\" | \"platform\";\n\nexport const TEAM_TYPES: readonly TeamType[] = [\n \"stream-aligned\",\n \"enabling\",\n \"complicated-subsystem\",\n \"platform\",\n] as const;\n\n/** The three core team interaction modes in Team Topologies. */\nexport type InteractionMode = \"collaboration\" | \"x-as-a-service\" | \"facilitating\";\n\nexport const INTERACTION_MODES: readonly InteractionMode[] = [\n \"collaboration\",\n \"x-as-a-service\",\n \"facilitating\",\n] as const;\n\n/** Geometric size of a node in canvas units (px). Encodes cognitive load. */\nexport interface Size {\n width: number;\n height: number;\n}\n\n/** Position of a node on the canvas in canvas units (px). */\nexport interface Position {\n x: number;\n y: number;\n}\n\n/** A team node in the canonical document model. */\nexport interface TeamNode {\n id: string;\n type: TeamType;\n label: string;\n description?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * An interaction in the canonical document model.\n *\n * Per the official Team Topologies notation, an interaction is a placed,\n * resizable SHAPE (parallelogram / triangle / circle) overlaid on the boundary\n * between the teams it relates to — not a connecting line. The relationship is\n * therefore spatial (overlap), so there is no source/target reference.\n */\nexport interface InteractionShape {\n id: string;\n mode: InteractionMode;\n label?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * A \"flow of change\" guide: a placed, resizable arrow element. Lets you anchor\n * the implied left-to-right flow, and visualise several team groupings on one\n * canvas.\n */\nexport interface FlowShape {\n id: string;\n label?: string;\n position: Position;\n size: Size;\n}\n\n/**\n * A free-text note beside the diagram (like a BPMN text annotation). It either\n * stands alone or is attached to exactly one team, interaction or flow, which\n * its dashed connector points at.\n */\nexport interface TextAnnotation {\n id: string;\n text: string;\n position: Position;\n size: Size;\n /** Id of the team, interaction or flow this annotation is attached to. */\n attachedTo?: string;\n}\n\n/** Current document schema version. Bump + add a migration when shape changes. */\nexport const DOCUMENT_VERSION = 3 as const;\n\n/**\n * A complete Team Topologies diagram. This is what gets serialised to JSON,\n * embedded into exported images, and encoded into share URLs.\n */\nexport interface TtDocument {\n version: typeof DOCUMENT_VERSION;\n title: string;\n nodes: TeamNode[];\n interactions: InteractionShape[];\n flows: FlowShape[];\n annotations: TextAnnotation[];\n}\n","/**\n * The Team Topologies visual notation, encoded as data.\n *\n * Colours, shapes and stroke styles follow the official\n * \"Team-Shape-Templates\" specification published by Team Topologies\n * (https://github.com/TeamTopologies/Team-Shape-Templates):\n *\n * - Team shapes are SOLID outlines (long-lived structures).\n * - Interaction-mode shapes are 50% transparent with DASHED outlines\n * (short-lived interactions).\n * - Each element is distinguished by SHAPE as well as colour, so the\n * notation stays readable for people with colour-vision deficiency.\n *\n * This module is pure data — it must not import the rendering layer.\n */\n\nimport type { InteractionMode, Size, TeamType } from \"./types\";\n\nexport type TeamShape = \"rounded-rect-horizontal\" | \"rounded-rect-vertical\" | \"octagon\" | \"rect\";\n\nexport type InteractionGlyph = \"parallelogram\" | \"triangle\" | \"circle\";\n\nexport type StrokeStyle = \"solid\" | \"dashed\" | \"dotted\";\n\nexport interface TeamTypeSpec {\n type: TeamType;\n /** Short display name. */\n label: string;\n /** One-line purpose, shown in the palette and inspector. */\n description: string;\n shape: TeamShape;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /** Default size when a node of this type is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\nexport interface InteractionModeSpec {\n mode: InteractionMode;\n label: string;\n description: string;\n shape: InteractionGlyph;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /**\n * The templates' fill opacity (short-lived → translucent). The renderer premixes the fill over\n * white at it and draws it opaque.\n */\n opacity: number;\n /** Whether direction is semantically meaningful (the X-as-a-Service triangle). */\n directional: boolean;\n /** Default size when a shape of this mode is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\n/** The left-to-right \"flow of change\" guide, a placeable annotation element. */\nexport interface FlowSpec {\n label: string;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n defaultSize: Size;\n minSize: Size;\n}\n\n// The official notation colours (Team-Shape-Templates, above): foreign notation, guide §10.6.\n// brand-lint-disable\nexport const TEAM_TYPE_SPECS: Record<TeamType, TeamTypeSpec> = {\n \"stream-aligned\": {\n type: \"stream-aligned\",\n label: \"Stream-aligned\",\n description: \"Aligned to a single, valuable stream of work; owns it end-to-end.\",\n shape: \"rounded-rect-horizontal\",\n fill: \"#FFEDB8\",\n stroke: \"#FFD966\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 240, height: 96 },\n minSize: { width: 140, height: 64 },\n },\n enabling: {\n type: \"enabling\",\n label: \"Enabling\",\n description:\n \"Helps stream-aligned teams acquire missing capabilities; coaches, then steps back.\",\n shape: \"rounded-rect-vertical\",\n fill: \"#DFBDCF\",\n stroke: \"#D09CB7\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 120, height: 200 },\n minSize: { width: 80, height: 120 },\n },\n \"complicated-subsystem\": {\n type: \"complicated-subsystem\",\n label: \"Complicated Subsystem\",\n description:\n \"Owns a part of the system needing deep specialist knowledge, reducing others' cognitive load.\",\n shape: \"octagon\",\n fill: \"#FFC08B\",\n stroke: \"#E88814\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 170, height: 150 },\n minSize: { width: 110, height: 100 },\n },\n platform: {\n type: \"platform\",\n label: \"Platform\",\n description:\n \"Provides internal self-service capabilities to reduce cognitive load for stream-aligned teams.\",\n shape: \"rect\",\n fill: \"#B7CDF1\",\n stroke: \"#6D9EEB\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 380, height: 130 },\n minSize: { width: 200, height: 90 },\n },\n};\n\nexport const INTERACTION_MODE_SPECS: Record<InteractionMode, InteractionModeSpec> = {\n collaboration: {\n mode: \"collaboration\",\n label: \"Collaboration\",\n description:\n \"Two teams work closely together for a defined period; high overhead, high discovery.\",\n shape: \"parallelogram\",\n fill: \"#C6BEDF\",\n stroke: \"#967EE2\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 112, height: 72 },\n minSize: { width: 60, height: 44 },\n },\n \"x-as-a-service\": {\n mode: \"x-as-a-service\",\n label: \"X-as-a-Service\",\n description:\n \"One team consumes something the other provides 'as a service'; minimal collaboration.\",\n shape: \"triangle\",\n fill: \"#B4B4B4\",\n stroke: \"#999696\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: true,\n defaultSize: { width: 88, height: 78 },\n minSize: { width: 54, height: 48 },\n },\n facilitating: {\n mode: \"facilitating\",\n label: \"Facilitating\",\n description:\n \"One team helps/coaches another to clear impediments and learn; sensing and discovery.\",\n shape: \"circle\",\n fill: \"#C9DFBE\",\n stroke: \"#78996B\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 84, height: 84 },\n minSize: { width: 48, height: 48 },\n },\n};\n\n/**\n * The \"flow of change\" guide — a placeable dashed arrow (left-to-right).\n * Not a team or interaction: a standalone annotation element.\n */\nexport const FLOW_SPEC: FlowSpec = {\n label: \"Flow of change\",\n fill: \"transparent\",\n stroke: \"#6b6459\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n defaultSize: { width: 520, height: 64 },\n minSize: { width: 160, height: 36 },\n};\n// brand-lint-enable\n\n/**\n * A text annotation — not part of the Team Topologies notation, so it carries\n * no colours here; the renderer draws it in the neutral brand ink.\n */\nexport interface AnnotationSpec {\n label: string;\n defaultSize: Size;\n minSize: Size;\n}\n\nexport const ANNOTATION_SPEC: AnnotationSpec = {\n label: \"Annotation\",\n defaultSize: { width: 200, height: 64 },\n minSize: { width: 60, height: 30 },\n};\n\n/** Maps a stroke style to an SVG/CSS dash array (empty string = solid). */\nexport function dashArray(style: StrokeStyle, strokeWidth = 2): string {\n switch (style) {\n case \"dashed\":\n return `${strokeWidth * 3} ${strokeWidth * 2}`;\n case \"dotted\":\n return `${strokeWidth} ${strokeWidth * 1.5}`;\n case \"solid\":\n default:\n return \"\";\n }\n}\n\nexport const ALL_TEAM_SPECS: readonly TeamTypeSpec[] = Object.values(TEAM_TYPE_SPECS);\nexport const ALL_INTERACTION_SPECS: readonly InteractionModeSpec[] =\n Object.values(INTERACTION_MODE_SPECS);\n","/**\n * The id rules of a Team Topologies document. Besides the elements a document lists, a diagram\n * holds parts it never writes down: the diagram itself and the connector of every annotation. They\n * take ids of their own, so no element may use one of them; otherwise opening the file would fail\n * halfway, with the previous diagram already gone. The canvas also keeps its elements in a plain\n * object, where the names of JavaScript's built-in object properties already resolve.\n */\n\n/** The id of the diagram itself (the canvas root of the renderer). */\nexport const DIAGRAM_ROOT_ID = \"tt-root\";\n\n/** diagram-js names the roots it creates on its own `__implicitroot_<n>`. */\nconst ENGINE_ROOT_ID_PREFIX = \"__implicitroot\";\n\n/** Connectors are not stored: an annotation's connector derives its id from the annotation. */\nexport function associationId(annotationId: string): string {\n return `assoc_${annotationId}`;\n}\n\nexport interface DocumentIdProblem {\n /** Where the offending id sits, e.g. `[\"nodes\", 2, \"id\"]`. */\n path: (string | number)[];\n message: string;\n}\n\nconst COLLECTIONS = [\"nodes\", \"interactions\", \"flows\", \"annotations\"] as const;\n\ntype DocumentElements = Record<(typeof COLLECTIONS)[number], readonly { id: string }[]>;\n\n/** Ids such as `constructor`, `toString` or `__proto__`, which every plain object already has. */\nfunction isBuiltInPropertyId(id: string): boolean {\n return Object.hasOwn(Object.prototype, id);\n}\n\n/**\n * Every id of the document that would collide on the canvas: a duplicate, the diagram's own id, a\n * diagram-js root id, the name of a built-in object property, or the id of an annotation's\n * connector.\n */\nexport function documentIdProblems(doc: DocumentElements): DocumentIdProblem[] {\n const problems: DocumentIdProblem[] = [];\n const connectorIds = new Map(\n doc.annotations.map((annotation) => [associationId(annotation.id), annotation.id]),\n );\n const seen = new Set<string>();\n for (const collection of COLLECTIONS) {\n doc[collection].forEach((element, index) => {\n const path = [collection, index, \"id\"];\n const { id } = element;\n if (seen.has(id)) {\n problems.push({\n path,\n message: `duplicate id \"${id}\"; ids must be unique across nodes, interactions, flows and annotations`,\n });\n }\n seen.add(id);\n if (id === DIAGRAM_ROOT_ID) {\n problems.push({ path, message: `\"${id}\" is reserved for the diagram itself` });\n } else if (id.startsWith(ENGINE_ROOT_ID_PREFIX)) {\n problems.push({\n path,\n message: `ids starting with \"${ENGINE_ROOT_ID_PREFIX}\" are reserved`,\n });\n } else if (isBuiltInPropertyId(id)) {\n problems.push({\n path,\n message: `\"${id}\" is reserved: it names a built-in property of JavaScript objects`,\n });\n }\n const annotationId = connectorIds.get(id);\n if (annotationId !== undefined) {\n problems.push({\n path,\n message: `\"${id}\" is reserved for the connector of annotation \"${annotationId}\"`,\n });\n }\n });\n }\n return problems;\n}\n","/**\n * Runtime validation for the document model using Zod.\n *\n * Anything entering the app from the outside world (imported files, share\n * URLs, localStorage) is parsed through {@link parseDocument} so malformed or\n * tampered data can never corrupt the editor state. Fields the schema does not\n * know pass through untouched (see `foreign.ts`), so another tool's data\n * survives a save.\n */\n\nimport { z } from \"zod\";\nimport { documentIdProblems } from \"./ids\";\nimport { DOCUMENT_VERSION, INTERACTION_MODES, TEAM_TYPES } from \"./types\";\nimport type { TtDocument } from \"./types\";\n\nconst teamTypeSchema = z.enum(TEAM_TYPES as unknown as [string, ...string[]]);\nconst interactionModeSchema = z.enum(INTERACTION_MODES as unknown as [string, ...string[]]);\n\nconst sizeSchema = z.object({\n width: z.number().finite().positive(),\n height: z.number().finite().positive(),\n});\n\nconst positionSchema = z.object({\n x: z.number().finite(),\n y: z.number().finite(),\n});\n\nconst hexColor = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, \"expected a hex colour\");\n\nexport const teamNodeSchema = z.looseObject({\n id: z.string().min(1),\n type: teamTypeSchema,\n label: z.string(),\n description: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const interactionSchema = z.looseObject({\n id: z.string().min(1),\n mode: interactionModeSchema,\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const flowSchema = z.looseObject({\n id: z.string().min(1),\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n});\n\nexport const annotationSchema = z.looseObject({\n id: z.string().min(1),\n text: z.string(),\n position: positionSchema,\n size: sizeSchema,\n attachedTo: z.string().min(1).optional(),\n});\n\nexport const documentSchema = z\n .looseObject({\n version: z.literal(DOCUMENT_VERSION),\n title: z.string(),\n nodes: z.array(teamNodeSchema),\n interactions: z.array(interactionSchema),\n flows: z.array(flowSchema),\n annotations: z.array(annotationSchema),\n })\n .superRefine((document, context) => {\n for (const { path, message } of documentIdProblems(document)) {\n context.addIssue({ code: \"custom\", path, message });\n }\n });\n\n/** One reason a document is invalid, at the path of the offending value. */\nexport interface DocumentIssue {\n path: (string | number)[];\n message: string;\n}\n\nexport type ParseResult =\n { ok: true; document: TtDocument } | { ok: false; error: string; issues: DocumentIssue[] };\n\n/**\n * Objects and arrays nested deeper than this make a document invalid, the document itself counting\n * as the first level. The serializer, structured cloning and JSON tooling such as jsonc-parser\n * descend one call per level and overflow the stack a few thousand levels down; a Team Topologies\n * document needs four.\n */\nexport const MAX_NESTING_DEPTH = 100;\n\n/**\n * Validates and (if necessary) migrates unknown data into a {@link TtDocument}.\n * Returns a discriminated result rather than throwing so callers can show a\n * friendly message, or point at each offending value (`issues`).\n */\nexport function parseDocument(input: unknown): ParseResult {\n const tooDeep = nestingIssues(input);\n if (tooDeep.length > 0) return refused(tooDeep);\n const { document: migrated, interactionFileIndexes } = migrate(input);\n const result = documentSchema.safeParse(migrated);\n if (!result.success) {\n return refused(\n result.error.issues.map((issue) => ({\n path: pathInFile(\n issue.path.filter((key): key is string | number => typeof key !== \"symbol\"),\n interactionFileIndexes,\n ),\n message: issue.message,\n })),\n );\n }\n return { ok: true, document: result.data as TtDocument };\n}\n\nfunction refused(issues: DocumentIssue[]): ParseResult {\n return {\n ok: false,\n error: issues.map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`).join(\"; \"),\n issues,\n };\n}\n\n/**\n * At most this many nesting issues per document. Each carries a path of {@link MAX_NESTING_DEPTH}\n * keys, so one wide container beyond the limit would otherwise give millions of them and an error\n * text longer than a string may be.\n */\nconst MAX_NESTING_ISSUES = 100;\n\ninterface OpenContainer {\n readonly container: object;\n readonly keys: readonly string[] | undefined;\n readonly size: number;\n next: number;\n readonly keyInParent: string | number | undefined;\n}\n\n/**\n * Each object or array at the first level beyond {@link MAX_NESTING_DEPTH}, in document order, up\n * to {@link MAX_NESTING_ISSUES}; what lies below it is not visited. Walked with an explicit stack,\n * because the documents it guards against are the ones that overflow a recursive walk. The stack\n * holds only the containers the walk is inside of and a path is built only for an issue, so the\n * walk's memory grows with the number of containers, not with their number times their depth.\n */\nfunction nestingIssues(input: unknown): DocumentIssue[] {\n const issues: DocumentIssue[] = [];\n if (!isContainer(input)) return issues;\n // A caller in JavaScript may put one container in several places, or inside itself: walking it\n // again at a level no deeper than before finds nothing new, and would grow exponentially.\n const deepestWalk = new WeakMap<object, number>();\n const open: OpenContainer[] = [];\n const enter = (container: object, keyInParent?: string | number): void => {\n deepestWalk.set(container, open.length);\n const keys = Array.isArray(container) ? undefined : Object.keys(container);\n const size = keys?.length ?? (container as unknown[]).length;\n open.push({ container, keys, size, next: 0, keyInParent });\n };\n enter(input);\n while (open.length > 0 && issues.length < MAX_NESTING_ISSUES) {\n const current = open[open.length - 1]!;\n if (current.next === current.size) {\n open.pop();\n continue;\n }\n const index = current.next++;\n const key = current.keys === undefined ? index : current.keys[index]!;\n const entry: unknown = (current.container as Record<string | number, unknown>)[key];\n if (!isContainer(entry)) continue;\n if (open.length >= MAX_NESTING_DEPTH) {\n issues.push({\n path: [...open.flatMap(({ keyInParent }) => keyInParent ?? []), key],\n message: `objects and arrays may nest at most ${MAX_NESTING_DEPTH} levels deep`,\n });\n continue;\n }\n if ((deepestWalk.get(entry) ?? -1) >= open.length) continue;\n enter(entry, key);\n }\n return issues;\n}\n\nfunction isContainer(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\n/** The last document version that modelled interactions as edges without geometry. */\nconst EDGE_INTERACTIONS_VERSION = 1;\n\ninterface Migration {\n document: unknown;\n /** For each interaction the migrated document keeps, its index in the input. */\n interactionFileIndexes: readonly number[];\n}\n\n/**\n * Forward-migrates older document shapes to the current version. v1 modelled\n * interactions as edges (source/target, no geometry) and carried a\n * `showFlowOfChange` flag; v2 makes interactions placed shapes and adds `flows`;\n * v3 adds `annotations`. The edge-interactions of a v1 file can't be placed\n * meaningfully, so they're dropped. From v2 on, an interaction without position\n * or size is refused like any other missing field: dropped, it would vanish from\n * the file on the next save without a word.\n */\nfunction migrate(input: unknown): Migration {\n if (input == null || typeof input !== \"object\") {\n return { document: input, interactionFileIndexes: [] };\n }\n const doc = input as Record<string, unknown>;\n const next: Record<string, unknown> = { ...doc };\n delete next.showFlowOfChange; // v1 flag, gone in v2\n next.version = DOCUMENT_VERSION;\n if (typeof next.title !== \"string\") next.title = \"Untitled team topology\";\n if (!Array.isArray(next.nodes)) next.nodes = [];\n const dropsEdgeInteractions = doc.version === EDGE_INTERACTIONS_VERSION;\n const keptInteractions = Array.isArray(next.interactions)\n ? next.interactions\n .map((interaction: unknown, fileIndex) => ({ interaction, fileIndex }))\n .filter(({ interaction }) => !dropsEdgeInteractions || isPlacedShape(interaction))\n : [];\n next.interactions = keptInteractions.map(({ interaction }) => interaction);\n if (!Array.isArray(next.flows)) next.flows = [];\n if (!Array.isArray(next.annotations)) next.annotations = [];\n return {\n document: next,\n interactionFileIndexes: keptInteractions.map(({ fileIndex }) => fileIndex),\n };\n}\n\nfunction isPlacedShape(value: unknown): boolean {\n return value != null && typeof value === \"object\" && \"position\" in value && \"size\" in value;\n}\n\n/**\n * An issue's path in the input rather than in the migrated document: an editor points at the\n * file, and every legacy interaction dropped before an invalid one would shift its index.\n */\nfunction pathInFile(\n path: (string | number)[],\n interactionFileIndexes: readonly number[],\n): (string | number)[] {\n const [collection, index, ...rest] = path;\n if (collection !== \"interactions\" || typeof index !== \"number\") return path;\n const fileIndex = interactionFileIndexes[index];\n return fileIndex === undefined ? path : [collection, fileIndex, ...rest];\n}\n","/**\n * Fields a document carries that this modeler does not know, such as a vendor's `\"x-vendor\"` on a\n * team. They are kept through open and save, written after the known fields and sorted, so another\n * tool's data survives an edit in the modeler and the output stays deterministic.\n */\n\nexport const DOCUMENT_FIELDS = [\n \"version\",\n \"title\",\n \"nodes\",\n \"interactions\",\n \"flows\",\n \"annotations\",\n] as const;\nexport const TEAM_NODE_FIELDS = [\n \"id\",\n \"type\",\n \"label\",\n \"description\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const INTERACTION_FIELDS = [\n \"id\",\n \"mode\",\n \"label\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const FLOW_FIELDS = [\"id\", \"label\", \"position\", \"size\"] as const;\nexport const ANNOTATION_FIELDS = [\"id\", \"text\", \"position\", \"size\", \"attachedTo\"] as const;\n\n/** Unknown fields by name, sorted, with their values in canonical form. */\nexport type ForeignFields = Readonly<Record<string, unknown>>;\n\n/** JSON objects have no key order, so nested keys are sorted too: equal data, equal bytes. */\nfunction canonicalValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalValue);\n if (value === null || typeof value !== \"object\") return value;\n const record = value as Record<string, unknown>;\n return Object.fromEntries(\n Object.keys(record)\n .filter((key) => record[key] !== undefined)\n .sort()\n .map((key) => [key, canonicalValue(record[key])]),\n );\n}\n\n/** The fields of `value` outside `knownFields`, or undefined when there are none. */\nexport function foreignFields(\n value: object,\n knownFields: readonly string[],\n): ForeignFields | undefined {\n const record = value as Record<string, unknown>;\n const names = Object.keys(record)\n .filter((name) => !knownFields.includes(name) && record[name] !== undefined)\n .sort();\n if (names.length === 0) return undefined;\n return Object.fromEntries(names.map((name) => [name, canonicalValue(record[name])]));\n}\n\n/**\n * `known` followed by the foreign fields of `source`. Built from entries, never by assignment, so\n * a field named `__proto__` stays a field instead of replacing the prototype.\n */\nexport function withForeignFields<T extends object>(\n known: T,\n source: object | undefined,\n knownFields: readonly string[],\n): T {\n const foreign = source ? foreignFields(source, knownFields) : undefined;\n if (!foreign) return known;\n return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]) as T;\n}\n","/**\n * Deterministic serialisation of the document model.\n *\n * Producing byte-stable JSON (sorted arrays, fixed key order, rounded\n * coordinates) makes diagrams diff-friendly in version control and gives\n * stable share URLs / embedded payloads.\n */\n\nimport {\n ANNOTATION_FIELDS,\n DOCUMENT_FIELDS,\n FLOW_FIELDS,\n INTERACTION_FIELDS,\n TEAM_NODE_FIELDS,\n withForeignFields,\n} from \"./foreign\";\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type {\n FlowShape,\n InteractionShape,\n Position,\n Size,\n TeamNode,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\n\n/** Round to 2 decimals to strip floating-point drift from drag operations. */\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction normPosition(p: Position): Position {\n return { x: round(p.x), y: round(p.y) };\n}\n\nfunction normSize(s: Size): Size {\n return { width: round(s.width), height: round(s.height) };\n}\n\n/** Drops undefined fields and applies a fixed key order to a node. */\nfunction normNode(n: TeamNode): TeamNode {\n const out: TeamNode = {\n id: n.id,\n type: n.type,\n label: n.label,\n position: normPosition(n.position),\n size: normSize(n.size),\n };\n if (n.description) out.description = n.description;\n if (n.fill) out.fill = n.fill;\n if (n.stroke) out.stroke = n.stroke;\n return withForeignFields(out, n, TEAM_NODE_FIELDS);\n}\n\nfunction normInteraction(e: InteractionShape): InteractionShape {\n const out: InteractionShape = {\n id: e.id,\n mode: e.mode,\n position: normPosition(e.position),\n size: normSize(e.size),\n };\n if (e.label) out.label = e.label;\n if (e.fill) out.fill = e.fill;\n if (e.stroke) out.stroke = e.stroke;\n return withForeignFields(out, e, INTERACTION_FIELDS);\n}\n\nfunction normFlow(f: FlowShape): FlowShape {\n const out: FlowShape = {\n id: f.id,\n position: normPosition(f.position),\n size: normSize(f.size),\n };\n if (f.label) out.label = f.label;\n return withForeignFields(out, f, FLOW_FIELDS);\n}\n\nfunction normAnnotation(a: TextAnnotation): TextAnnotation {\n const out: TextAnnotation = {\n id: a.id,\n text: a.text,\n position: normPosition(a.position),\n size: normSize(a.size),\n };\n if (a.attachedTo) out.attachedTo = a.attachedTo;\n return withForeignFields(out, a, ANNOTATION_FIELDS);\n}\n\nconst byId = (a: { id: string }, b: { id: string }): number =>\n a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\n/**\n * Returns a canonicalised copy of a document (sorted, rounded, version-stamped). Fields the\n * modeler does not know follow the known ones, sorted by name.\n */\nexport function canonicalize(doc: TtDocument): TtDocument {\n return withForeignFields(\n {\n version: DOCUMENT_VERSION,\n title: doc.title,\n nodes: [...doc.nodes].map(normNode).sort(byId),\n interactions: [...doc.interactions].map(normInteraction).sort(byId),\n flows: [...doc.flows].map(normFlow).sort(byId),\n annotations: [...doc.annotations].map(normAnnotation).sort(byId),\n },\n doc,\n DOCUMENT_FIELDS,\n );\n}\n\n/**\n * Serialises a document to deterministic JSON. An empty `annotations` list is left out, so\n * re-saving a model that has no annotations changes nothing but its version stamp. The pretty\n * form is the file on disk and ends with a line break, like the files editors and Git expect;\n * the compact form (share links, local storage) has none.\n */\nexport function serializeDocument(doc: TtDocument, pretty = true): string {\n const canonical = canonicalize(doc);\n const output =\n canonical.annotations.length > 0\n ? canonical\n : Object.fromEntries(Object.entries(canonical).filter(([key]) => key !== \"annotations\"));\n return pretty ? `${JSON.stringify(output, null, 2)}\\n` : JSON.stringify(output);\n}\n","/**\n * Factory helpers for constructing well-formed model objects with the correct\n * notation defaults (sizes, labels). Kept DOM-free.\n */\n\nimport { nanoid } from \"nanoid\";\nimport { ANNOTATION_SPEC, FLOW_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\nimport type {\n FlowShape,\n InteractionMode,\n InteractionShape,\n Position,\n TeamNode,\n TeamType,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\nimport { DOCUMENT_VERSION } from \"./types\";\n\nexport function newId(prefix: string): string {\n return `${prefix}_${nanoid(8)}`;\n}\n\n/** Creates a team node of the given type at a position, with notation defaults. */\nexport function createTeamNode(\n type: TeamType,\n position: Position,\n overrides: Partial<Omit<TeamNode, \"id\" | \"type\">> = {},\n): TeamNode {\n const spec = TEAM_TYPE_SPECS[type];\n return {\n id: newId(\"team\"),\n type,\n label: overrides.label ?? spec.label,\n description: overrides.description,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed interaction shape of the given mode, with notation defaults. */\nexport function createInteractionShape(\n mode: InteractionMode,\n position: Position,\n overrides: Partial<Omit<InteractionShape, \"id\" | \"mode\" | \"position\">> = {},\n): InteractionShape {\n const spec = INTERACTION_MODE_SPECS[mode];\n return {\n id: newId(\"int\"),\n mode,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n label: overrides.label,\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed \"flow of change\" arrow, with notation defaults. */\nexport function createFlowShape(\n position: Position,\n overrides: Partial<Omit<FlowShape, \"id\" | \"position\">> = {},\n): FlowShape {\n return {\n id: newId(\"flow\"),\n position,\n size: overrides.size ?? { ...FLOW_SPEC.defaultSize },\n label: overrides.label ?? FLOW_SPEC.label,\n };\n}\n\n/** Creates a text annotation, optionally attached to a team, interaction or flow. */\nexport function createTextAnnotation(\n position: Position,\n overrides: Partial<Omit<TextAnnotation, \"id\" | \"position\">> = {},\n): TextAnnotation {\n return {\n id: newId(\"ann\"),\n text: overrides.text ?? \"\",\n position,\n size: overrides.size ?? { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: overrides.attachedTo,\n };\n}\n\n/** An empty document with sensible defaults. */\nexport function emptyDocument(title = \"Untitled team topology\"): TtDocument {\n return {\n version: DOCUMENT_VERSION,\n title,\n nodes: [],\n interactions: [],\n flows: [],\n annotations: [],\n };\n}\n","/**\n * A small but complete example diagram exercising all four team types, all three\n * interaction modes (as placed shapes overlaying the team boundaries), a\n * flow-of-change element and an attached annotation. The stream-aligned teams\n * are stacked as parallel lanes along the flow of change, as in the Team\n * Topologies book: side by side on the flow they would read as hand-offs. Ids are\n * fixed so the fixture serialises stably.\n */\n\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type { TtDocument } from \"./types\";\nimport { ANNOTATION_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\n\nconst s = TEAM_TYPE_SPECS;\nconst i = INTERACTION_MODE_SPECS;\n\nconst LANE_WIDTH = 600;\n\nexport const SAMPLE_DOCUMENT: TtDocument = {\n version: DOCUMENT_VERSION,\n title: \"Online shop team topology\",\n nodes: [\n {\n id: \"team_test_automation\",\n type: \"enabling\",\n label: \"Test Automation\",\n description: \"Coaches stream-aligned teams in test automation, then steps back.\",\n position: { x: 40, y: 150 },\n size: { width: s.enabling.defaultSize.width, height: 222 },\n },\n {\n id: \"team_discovery\",\n type: \"stream-aligned\",\n label: \"Product Discovery\",\n description: \"Owns search, browsing and product pages end-to-end.\",\n position: { x: 220, y: 150 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_checkout\",\n type: \"stream-aligned\",\n label: \"Checkout & Payments\",\n description: \"Owns the checkout and payment journey end-to-end.\",\n position: { x: 220, y: 276 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fulfilment\",\n type: \"stream-aligned\",\n label: \"Order Fulfilment\",\n description: \"Owns delivery, tracking and returns end-to-end.\",\n position: { x: 220, y: 402 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fraud\",\n type: \"complicated-subsystem\",\n label: \"Fraud Detection\",\n description: \"Specialists for the real-time fraud scoring model.\",\n position: { x: 880, y: 249 },\n size: { ...s[\"complicated-subsystem\"].defaultSize },\n },\n {\n id: \"team_platform\",\n type: \"platform\",\n label: \"Cloud Platform\",\n description: \"Self-service CI/CD, runtime and observability for all teams.\",\n position: { x: 220, y: 552 },\n size: { width: LANE_WIDTH, height: 110 },\n },\n ],\n interactions: [\n {\n id: \"int_testing_discovery\",\n mode: \"facilitating\",\n position: { x: 148, y: 156 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_testing_checkout\",\n mode: \"facilitating\",\n position: { x: 148, y: 282 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_checkout_fraud\",\n mode: \"collaboration\",\n label: \"fraud rules\",\n position: { x: 794, y: 288 },\n size: { ...i.collaboration.defaultSize },\n },\n {\n id: \"int_platform_fulfilment\",\n mode: \"x-as-a-service\",\n position: { x: 476, y: 486 },\n size: { ...i[\"x-as-a-service\"].defaultSize },\n },\n ],\n flows: [\n {\n id: \"flow_main\",\n label: \"Flow of change\",\n position: { x: 40, y: 40 },\n size: { width: 1010, height: 56 },\n },\n ],\n annotations: [\n {\n id: \"ann_fraud_handover\",\n text: \"Collaboration until the fraud rules are stable (Q3), then X-as-a-Service\",\n position: { x: 880, y: 423 },\n size: { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: \"int_checkout_fraud\",\n },\n ],\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/notation.ts","../src/ids.ts","../src/schema.ts","../src/canonical-copy.ts","../src/foreign.ts","../src/serialize.ts","../src/factory.ts","../src/sample.ts"],"names":["i","s"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Pure (DOM-free) domain types for the Team Topologies model.\n *\n * This module is the canonical representation of a diagram and must never\n * import from the rendering layer (`@xyflow/react`) or touch the DOM, so it\n * can be unit-tested in isolation and reused across views / exporters.\n */\n\n/** MIME type used when dragging a team type from the palette onto the canvas. */\nexport const DND_MIME = \"application/x-tt-team-type\";\n\n/** The four fundamental team types in Team Topologies. */\nexport type TeamType = \"stream-aligned\" | \"enabling\" | \"complicated-subsystem\" | \"platform\";\n\nexport const TEAM_TYPES: readonly TeamType[] = [\n \"stream-aligned\",\n \"enabling\",\n \"complicated-subsystem\",\n \"platform\",\n] as const;\n\n/** The three core team interaction modes in Team Topologies. */\nexport type InteractionMode = \"collaboration\" | \"x-as-a-service\" | \"facilitating\";\n\nexport const INTERACTION_MODES: readonly InteractionMode[] = [\n \"collaboration\",\n \"x-as-a-service\",\n \"facilitating\",\n] as const;\n\n/** Geometric size of a node in canvas units (px). Encodes cognitive load. */\nexport interface Size {\n width: number;\n height: number;\n}\n\n/** Position of a node on the canvas in canvas units (px). */\nexport interface Position {\n x: number;\n y: number;\n}\n\n/** A team node in the canonical document model. */\nexport interface TeamNode {\n id: string;\n type: TeamType;\n label: string;\n description?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * An interaction in the canonical document model.\n *\n * Per the official Team Topologies notation, an interaction is a placed,\n * resizable SHAPE (parallelogram / triangle / circle) overlaid on the boundary\n * between the teams it relates to — not a connecting line. The relationship is\n * therefore spatial (overlap), so there is no source/target reference.\n */\nexport interface InteractionShape {\n id: string;\n mode: InteractionMode;\n label?: string;\n position: Position;\n size: Size;\n fill?: string;\n stroke?: string;\n}\n\n/**\n * A \"flow of change\" guide: a placed, resizable arrow element. Lets you anchor\n * the implied left-to-right flow, and visualise several team groupings on one\n * canvas.\n */\nexport interface FlowShape {\n id: string;\n label?: string;\n position: Position;\n size: Size;\n}\n\n/**\n * A free-text note beside the diagram (like a BPMN text annotation). It either\n * stands alone or is attached to exactly one team, interaction or flow, which\n * its dashed connector points at.\n */\nexport interface TextAnnotation {\n id: string;\n text: string;\n position: Position;\n size: Size;\n /** Id of the team, interaction or flow this annotation is attached to. */\n attachedTo?: string;\n}\n\n/** Current document schema version. Bump + add a migration when shape changes. */\nexport const DOCUMENT_VERSION = 3 as const;\n\n/**\n * A complete Team Topologies diagram. This is what gets serialised to JSON,\n * embedded into exported images, and encoded into share URLs.\n */\nexport interface TtDocument {\n version: typeof DOCUMENT_VERSION;\n title: string;\n nodes: TeamNode[];\n interactions: InteractionShape[];\n flows: FlowShape[];\n annotations: TextAnnotation[];\n}\n","/**\n * The Team Topologies visual notation, encoded as data.\n *\n * Colours, shapes and stroke styles follow the official\n * \"Team-Shape-Templates\" specification published by Team Topologies\n * (https://github.com/TeamTopologies/Team-Shape-Templates):\n *\n * - Team shapes are SOLID outlines (long-lived structures).\n * - Interaction-mode shapes are 50% transparent with DASHED outlines\n * (short-lived interactions).\n * - Each element is distinguished by SHAPE as well as colour, so the\n * notation stays readable for people with colour-vision deficiency.\n *\n * This module is pure data — it must not import the rendering layer.\n */\n\nimport type { InteractionMode, Size, TeamType } from \"./types\";\n\nexport type TeamShape = \"rounded-rect-horizontal\" | \"rounded-rect-vertical\" | \"octagon\" | \"rect\";\n\nexport type InteractionGlyph = \"parallelogram\" | \"triangle\" | \"circle\";\n\nexport type StrokeStyle = \"solid\" | \"dashed\" | \"dotted\";\n\nexport interface TeamTypeSpec {\n type: TeamType;\n /** Short display name. */\n label: string;\n /** One-line purpose, shown in the palette and inspector. */\n description: string;\n shape: TeamShape;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /** Default size when a node of this type is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\nexport interface InteractionModeSpec {\n mode: InteractionMode;\n label: string;\n description: string;\n shape: InteractionGlyph;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n /**\n * The templates' fill opacity (short-lived → translucent). The renderer premixes the fill over\n * white at it and draws it opaque.\n */\n opacity: number;\n /** Whether direction is semantically meaningful (the X-as-a-Service triangle). */\n directional: boolean;\n /** Default size when a shape of this mode is created. */\n defaultSize: Size;\n /** Minimum size enforced by the resizer. */\n minSize: Size;\n}\n\n/** The left-to-right \"flow of change\" guide, a placeable annotation element. */\nexport interface FlowSpec {\n label: string;\n fill: string;\n stroke: string;\n strokeStyle: StrokeStyle;\n strokeWidth: number;\n defaultSize: Size;\n minSize: Size;\n}\n\n// The official notation colours (Team-Shape-Templates, above): foreign notation, guide §10.6.\n// brand-lint-disable\nexport const TEAM_TYPE_SPECS: Record<TeamType, TeamTypeSpec> = {\n \"stream-aligned\": {\n type: \"stream-aligned\",\n label: \"Stream-aligned\",\n description: \"Aligned to a single, valuable stream of work; owns it end-to-end.\",\n shape: \"rounded-rect-horizontal\",\n fill: \"#FFEDB8\",\n stroke: \"#FFD966\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 240, height: 96 },\n minSize: { width: 140, height: 64 },\n },\n enabling: {\n type: \"enabling\",\n label: \"Enabling\",\n description:\n \"Helps stream-aligned teams acquire missing capabilities; coaches, then steps back.\",\n shape: \"rounded-rect-vertical\",\n fill: \"#DFBDCF\",\n stroke: \"#D09CB7\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 120, height: 200 },\n minSize: { width: 80, height: 120 },\n },\n \"complicated-subsystem\": {\n type: \"complicated-subsystem\",\n label: \"Complicated Subsystem\",\n description:\n \"Owns a part of the system needing deep specialist knowledge, reducing others' cognitive load.\",\n shape: \"octagon\",\n fill: \"#FFC08B\",\n stroke: \"#E88814\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 170, height: 150 },\n minSize: { width: 110, height: 100 },\n },\n platform: {\n type: \"platform\",\n label: \"Platform\",\n description:\n \"Provides internal self-service capabilities to reduce cognitive load for stream-aligned teams.\",\n shape: \"rect\",\n fill: \"#B7CDF1\",\n stroke: \"#6D9EEB\",\n strokeStyle: \"solid\",\n strokeWidth: 2,\n defaultSize: { width: 380, height: 130 },\n minSize: { width: 200, height: 90 },\n },\n};\n\nexport const INTERACTION_MODE_SPECS: Record<InteractionMode, InteractionModeSpec> = {\n collaboration: {\n mode: \"collaboration\",\n label: \"Collaboration\",\n description:\n \"Two teams work closely together for a defined period; high overhead, high discovery.\",\n shape: \"parallelogram\",\n fill: \"#C6BEDF\",\n stroke: \"#967EE2\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 112, height: 72 },\n minSize: { width: 60, height: 44 },\n },\n \"x-as-a-service\": {\n mode: \"x-as-a-service\",\n label: \"X-as-a-Service\",\n description:\n \"One team consumes something the other provides 'as a service'; minimal collaboration.\",\n shape: \"triangle\",\n fill: \"#B4B4B4\",\n stroke: \"#999696\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: true,\n defaultSize: { width: 88, height: 78 },\n minSize: { width: 54, height: 48 },\n },\n facilitating: {\n mode: \"facilitating\",\n label: \"Facilitating\",\n description:\n \"One team helps/coaches another to clear impediments and learn; sensing and discovery.\",\n shape: \"circle\",\n fill: \"#C9DFBE\",\n stroke: \"#78996B\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n opacity: 0.5,\n directional: false,\n defaultSize: { width: 84, height: 84 },\n minSize: { width: 48, height: 48 },\n },\n};\n\n/**\n * The \"flow of change\" guide — a placeable dashed arrow (left-to-right).\n * Not a team or interaction: a standalone annotation element.\n */\nexport const FLOW_SPEC: FlowSpec = {\n label: \"Flow of change\",\n fill: \"transparent\",\n stroke: \"#6b6459\",\n strokeStyle: \"dashed\",\n strokeWidth: 2,\n defaultSize: { width: 520, height: 64 },\n minSize: { width: 160, height: 36 },\n};\n// brand-lint-enable\n\n/**\n * A text annotation — not part of the Team Topologies notation, so it carries\n * no colours here; the renderer draws it in the neutral brand ink.\n */\nexport interface AnnotationSpec {\n label: string;\n defaultSize: Size;\n minSize: Size;\n}\n\nexport const ANNOTATION_SPEC: AnnotationSpec = {\n label: \"Annotation\",\n defaultSize: { width: 200, height: 64 },\n minSize: { width: 60, height: 30 },\n};\n\n/** Maps a stroke style to an SVG/CSS dash array (empty string = solid). */\nexport function dashArray(style: StrokeStyle, strokeWidth = 2): string {\n switch (style) {\n case \"dashed\":\n return `${strokeWidth * 3} ${strokeWidth * 2}`;\n case \"dotted\":\n return `${strokeWidth} ${strokeWidth * 1.5}`;\n case \"solid\":\n default:\n return \"\";\n }\n}\n\nexport const ALL_TEAM_SPECS: readonly TeamTypeSpec[] = Object.values(TEAM_TYPE_SPECS);\nexport const ALL_INTERACTION_SPECS: readonly InteractionModeSpec[] =\n Object.values(INTERACTION_MODE_SPECS);\n","/**\n * The id rules of a Team Topologies document. Besides the elements a document lists, a diagram\n * holds parts it never writes down: the diagram itself and the connector of every annotation. They\n * take ids of their own, so no element may use one of them; otherwise opening the file would fail\n * halfway, with the previous diagram already gone. The canvas also keeps its elements in a plain\n * object, where the names of JavaScript's built-in object properties already resolve.\n */\n\n/** The id of the diagram itself (the canvas root of the renderer). */\nexport const DIAGRAM_ROOT_ID = \"tt-root\";\n\n/** diagram-js names the roots it creates on its own `__implicitroot_<n>`. */\nconst ENGINE_ROOT_ID_PREFIX = \"__implicitroot\";\n\n/** Connectors are not stored: an annotation's connector derives its id from the annotation. */\nexport function associationId(annotationId: string): string {\n return `assoc_${annotationId}`;\n}\n\nexport interface DocumentIdProblem {\n /** Where the offending id sits, e.g. `[\"nodes\", 2, \"id\"]`. */\n path: (string | number)[];\n message: string;\n}\n\nconst COLLECTIONS = [\"nodes\", \"interactions\", \"flows\", \"annotations\"] as const;\n\ntype DocumentElements = Record<(typeof COLLECTIONS)[number], readonly { id: string }[]>;\n\n/** Ids such as `constructor`, `toString` or `__proto__`, which every plain object already has. */\nfunction isBuiltInPropertyId(id: string): boolean {\n return Object.hasOwn(Object.prototype, id);\n}\n\n/**\n * Every id of the document that would collide on the canvas: a duplicate, the diagram's own id, a\n * diagram-js root id, the name of a built-in object property, or the id of an annotation's\n * connector.\n */\nexport function documentIdProblems(doc: DocumentElements): DocumentIdProblem[] {\n const problems: DocumentIdProblem[] = [];\n const connectorIds = new Map(\n doc.annotations.map((annotation) => [associationId(annotation.id), annotation.id]),\n );\n const seen = new Set<string>();\n for (const collection of COLLECTIONS) {\n doc[collection].forEach((element, index) => {\n const path = [collection, index, \"id\"];\n const { id } = element;\n if (seen.has(id)) {\n problems.push({\n path,\n message: `duplicate id \"${id}\"; ids must be unique across nodes, interactions, flows and annotations`,\n });\n }\n seen.add(id);\n if (id === DIAGRAM_ROOT_ID) {\n problems.push({ path, message: `\"${id}\" is reserved for the diagram itself` });\n } else if (id.startsWith(ENGINE_ROOT_ID_PREFIX)) {\n problems.push({\n path,\n message: `ids starting with \"${ENGINE_ROOT_ID_PREFIX}\" are reserved`,\n });\n } else if (isBuiltInPropertyId(id)) {\n problems.push({\n path,\n message: `\"${id}\" is reserved: it names a built-in property of JavaScript objects`,\n });\n }\n const annotationId = connectorIds.get(id);\n if (annotationId !== undefined) {\n problems.push({\n path,\n message: `\"${id}\" is reserved for the connector of annotation \"${annotationId}\"`,\n });\n }\n });\n }\n return problems;\n}\n","/**\n * Runtime validation for the document model using Zod.\n *\n * Anything entering the app from the outside world (imported files, share\n * URLs, localStorage) is parsed through {@link parseDocument} so malformed or\n * tampered data can never corrupt the editor state. Fields the schema does not\n * know pass through untouched (see `foreign.ts`), so another tool's data\n * survives a save.\n */\n\nimport { z } from \"zod\";\nimport { documentIdProblems } from \"./ids\";\nimport { DOCUMENT_VERSION, INTERACTION_MODES, TEAM_TYPES } from \"./types\";\nimport type { TtDocument } from \"./types\";\n\nconst teamTypeSchema = z.enum(TEAM_TYPES as unknown as [string, ...string[]]);\nconst interactionModeSchema = z.enum(INTERACTION_MODES as unknown as [string, ...string[]]);\n\nconst sizeSchema = z.object({\n width: z.number().finite().positive(),\n height: z.number().finite().positive(),\n});\n\nconst positionSchema = z.object({\n x: z.number().finite(),\n y: z.number().finite(),\n});\n\nconst hexColor = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, \"expected a hex colour\");\n\nexport const teamNodeSchema = z.looseObject({\n id: z.string().min(1),\n type: teamTypeSchema,\n label: z.string(),\n description: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const interactionSchema = z.looseObject({\n id: z.string().min(1),\n mode: interactionModeSchema,\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n fill: hexColor.optional(),\n stroke: hexColor.optional(),\n});\n\nexport const flowSchema = z.looseObject({\n id: z.string().min(1),\n label: z.string().optional(),\n position: positionSchema,\n size: sizeSchema,\n});\n\nexport const annotationSchema = z.looseObject({\n id: z.string().min(1),\n text: z.string(),\n position: positionSchema,\n size: sizeSchema,\n attachedTo: z.string().min(1).optional(),\n});\n\nexport const documentSchema = z\n .looseObject({\n version: z.literal(DOCUMENT_VERSION),\n title: z.string(),\n nodes: z.array(teamNodeSchema),\n interactions: z.array(interactionSchema),\n flows: z.array(flowSchema),\n annotations: z.array(annotationSchema),\n })\n .superRefine((document, context) => {\n for (const { path, message } of documentIdProblems(document)) {\n context.addIssue({ code: \"custom\", path, message });\n }\n });\n\n/** One reason a document is invalid, at the path of the offending value. */\nexport interface DocumentIssue {\n path: (string | number)[];\n message: string;\n}\n\nexport type ParseResult =\n { ok: true; document: TtDocument } | { ok: false; error: string; issues: DocumentIssue[] };\n\n/**\n * Objects and arrays nested deeper than this make a document invalid, the document itself counting\n * as the first level. The serializer, structured cloning and JSON tooling such as jsonc-parser\n * descend one call per level and overflow the stack a few thousand levels down; a Team Topologies\n * document needs four.\n */\nexport const MAX_NESTING_DEPTH = 100;\n\n/**\n * Validates and (if necessary) migrates unknown data into a {@link TtDocument}.\n * Returns a discriminated result rather than throwing so callers can show a\n * friendly message, or point at each offending value (`issues`).\n */\nexport function parseDocument(input: unknown): ParseResult {\n const tooDeep = nestingIssues(input);\n if (tooDeep.length > 0) return refused(tooDeep);\n const { document: migrated, interactionFileIndexes } = migrate(input);\n const result = documentSchema.safeParse(migrated);\n if (!result.success) {\n return refused(\n result.error.issues.map((issue) => ({\n path: pathInFile(\n issue.path.filter((key): key is string | number => typeof key !== \"symbol\"),\n interactionFileIndexes,\n ),\n message: issue.message,\n })),\n );\n }\n return { ok: true, document: result.data as TtDocument };\n}\n\nfunction refused(issues: DocumentIssue[]): ParseResult {\n return {\n ok: false,\n error: issues.map((i) => `${i.path.join(\".\") || \"(root)\"}: ${i.message}`).join(\"; \"),\n issues,\n };\n}\n\n/**\n * At most this many nesting issues per document. Each carries a path of {@link MAX_NESTING_DEPTH}\n * keys, so one wide container beyond the limit would otherwise give millions of them and an error\n * text longer than a string may be.\n */\nconst MAX_NESTING_ISSUES = 100;\n\ninterface OpenContainer {\n readonly container: object;\n readonly keys: readonly string[] | undefined;\n readonly size: number;\n next: number;\n readonly keyInParent: string | number | undefined;\n}\n\n/**\n * Each object or array at the first level beyond {@link MAX_NESTING_DEPTH}, in document order, up\n * to {@link MAX_NESTING_ISSUES}; what lies below it is not visited. Walked with an explicit stack,\n * because the documents it guards against are the ones that overflow a recursive walk. The stack\n * holds only the containers the walk is inside of and a path is built only for an issue, so the\n * walk's memory grows with the number of containers, not with their number times their depth.\n */\nfunction nestingIssues(input: unknown): DocumentIssue[] {\n const issues: DocumentIssue[] = [];\n if (!isContainer(input)) return issues;\n // A caller in JavaScript may put one container in several places, or inside itself: walking it\n // again at a level no deeper than before finds nothing new, and would grow exponentially.\n const deepestWalk = new WeakMap<object, number>();\n const open: OpenContainer[] = [];\n const enter = (container: object, keyInParent?: string | number): void => {\n deepestWalk.set(container, open.length);\n const keys = Array.isArray(container) ? undefined : Object.keys(container);\n const size = keys?.length ?? (container as unknown[]).length;\n open.push({ container, keys, size, next: 0, keyInParent });\n };\n enter(input);\n while (open.length > 0 && issues.length < MAX_NESTING_ISSUES) {\n const current = open[open.length - 1]!;\n if (current.next === current.size) {\n open.pop();\n continue;\n }\n const index = current.next++;\n const key = current.keys === undefined ? index : current.keys[index]!;\n const entry: unknown = (current.container as Record<string | number, unknown>)[key];\n if (!isContainer(entry)) continue;\n if (open.length >= MAX_NESTING_DEPTH) {\n issues.push({\n path: [...open.flatMap(({ keyInParent }) => keyInParent ?? []), key],\n message: `objects and arrays may nest at most ${MAX_NESTING_DEPTH} levels deep`,\n });\n continue;\n }\n if ((deepestWalk.get(entry) ?? -1) >= open.length) continue;\n enter(entry, key);\n }\n return issues;\n}\n\nfunction isContainer(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\n/** The last document version that modelled interactions as edges without geometry. */\nconst EDGE_INTERACTIONS_VERSION = 1;\n\ninterface Migration {\n document: unknown;\n /** For each interaction the migrated document keeps, its index in the input. */\n interactionFileIndexes: readonly number[];\n}\n\n/**\n * Forward-migrates older document shapes to the current version. v1 modelled\n * interactions as edges (source/target, no geometry) and carried a\n * `showFlowOfChange` flag; v2 makes interactions placed shapes and adds `flows`;\n * v3 adds `annotations`. The edge-interactions of a v1 file can't be placed\n * meaningfully, so they're dropped. From v2 on, an interaction without position\n * or size is refused like any other missing field: dropped, it would vanish from\n * the file on the next save without a word.\n */\nfunction migrate(input: unknown): Migration {\n if (input == null || typeof input !== \"object\") {\n return { document: input, interactionFileIndexes: [] };\n }\n const doc = input as Record<string, unknown>;\n const next: Record<string, unknown> = { ...doc };\n delete next.showFlowOfChange; // v1 flag, gone in v2\n next.version = DOCUMENT_VERSION;\n if (typeof next.title !== \"string\") next.title = \"Untitled team topology\";\n if (!Array.isArray(next.nodes)) next.nodes = [];\n const dropsEdgeInteractions = doc.version === EDGE_INTERACTIONS_VERSION;\n const keptInteractions = Array.isArray(next.interactions)\n ? next.interactions\n .map((interaction: unknown, fileIndex) => ({ interaction, fileIndex }))\n .filter(({ interaction }) => !dropsEdgeInteractions || isPlacedShape(interaction))\n : [];\n next.interactions = keptInteractions.map(({ interaction }) => interaction);\n if (!Array.isArray(next.flows)) next.flows = [];\n if (!Array.isArray(next.annotations)) next.annotations = [];\n return {\n document: next,\n interactionFileIndexes: keptInteractions.map(({ fileIndex }) => fileIndex),\n };\n}\n\nfunction isPlacedShape(value: unknown): boolean {\n return value != null && typeof value === \"object\" && \"position\" in value && \"size\" in value;\n}\n\n/**\n * An issue's path in the input rather than in the migrated document: an editor points at the\n * file, and every legacy interaction dropped before an invalid one would shift its index.\n */\nfunction pathInFile(\n path: (string | number)[],\n interactionFileIndexes: readonly number[],\n): (string | number)[] {\n const [collection, index, ...rest] = path;\n if (collection !== \"interactions\" || typeof index !== \"number\") return path;\n const fileIndex = interactionFileIndexes[index];\n return fileIndex === undefined ? path : [collection, fileIndex, ...rest];\n}\n","/**\n * The copy of the fields a document carries that this modeler does not know, in canonical form.\n * Not part of the package's API: `foreign.ts` copies with a new copier on every call, the\n * serializer with one copier for the whole document, so a value the document shares counts at\n * every place.\n */\n\n/**\n * A copy holds an object or array that sits in several places at each of them. An object that\n * holds the level below twice would need memory doubling with every level, and a wide object held\n * a thousand times would need a thousand copies of it. So each time a copier copies a container\n * again, it counts that container's entries; no real document repeats this many. A document that\n * shares nothing counts none, however large it is.\n */\nconst MAX_REPEATED_ENTRIES = 1_000_000;\n\n/** Copies one value into canonical form. */\nexport type CanonicalCopy = (value: unknown) => unknown;\n\n/**\n * A copier for one document. JSON objects have no key order, so nested keys are sorted too: equal\n * data, equal bytes. A value that sits in several places is copied at each of them, and its\n * entries count at every place after the first: past {@link MAX_REPEATED_ENTRIES} such repeated\n * entries it throws, and so does a value that contains itself.\n */\nexport function canonicalCopier(): CanonicalCopy {\n // Only the containers on the current path: one object in several places is no cycle.\n const ancestors = new Set<object>();\n const copiedContainers = new WeakSet<object>();\n let repeatedEntries = 0;\n const copy = (value: unknown): unknown => {\n if (value === null || typeof value !== \"object\") return value;\n if (ancestors.has(value)) throw new Error(\"Cannot serialize a cyclic document.\");\n if (copiedContainers.has(value)) {\n repeatedEntries += Array.isArray(value) ? value.length : Object.keys(value).length;\n if (repeatedEntries > MAX_REPEATED_ENTRIES) {\n throw new Error(\n `Cannot serialize a document whose shared objects and arrays would repeat more than ${MAX_REPEATED_ENTRIES} entries.`,\n );\n }\n } else {\n copiedContainers.add(value);\n }\n ancestors.add(value);\n const record = value as Record<string, unknown>;\n const copied = Array.isArray(value)\n ? value.map(copy)\n : Object.fromEntries(\n Object.keys(record)\n .filter((key) => record[key] !== undefined)\n .sort()\n .map((key) => [key, copy(record[key])]),\n );\n ancestors.delete(value);\n return copied;\n };\n return copy;\n}\n\n/** The fields of `value` outside `knownFields`, copied by `copy`, or undefined when there are none. */\nexport function copyForeignFields(\n value: object,\n knownFields: readonly string[],\n copy: CanonicalCopy,\n): Readonly<Record<string, unknown>> | undefined {\n const record = value as Record<string, unknown>;\n const names = Object.keys(record)\n .filter((name) => !knownFields.includes(name) && record[name] !== undefined)\n .sort();\n if (names.length === 0) return undefined;\n return Object.fromEntries(names.map((name) => [name, copy(record[name])]));\n}\n\n/**\n * `known` followed by the foreign fields of `source`, copied by `copy`. Built from entries, never\n * by assignment, so a field named `__proto__` stays a field instead of replacing the prototype.\n */\nexport function appendForeignFields<T extends object>(\n known: T,\n source: object | undefined,\n knownFields: readonly string[],\n copy: CanonicalCopy,\n): T {\n const foreign = source ? copyForeignFields(source, knownFields, copy) : undefined;\n if (!foreign) return known;\n return Object.fromEntries([...Object.entries(known), ...Object.entries(foreign)]) as T;\n}\n","/**\n * Fields a document carries that this modeler does not know, such as a vendor's `\"x-vendor\"` on a\n * team. They are kept through open and save, written after the known fields and sorted, so another\n * tool's data survives an edit in the modeler and the output stays deterministic.\n */\n\nimport { appendForeignFields, canonicalCopier, copyForeignFields } from \"./canonical-copy\";\n\nexport const DOCUMENT_FIELDS = [\n \"version\",\n \"title\",\n \"nodes\",\n \"interactions\",\n \"flows\",\n \"annotations\",\n] as const;\nexport const TEAM_NODE_FIELDS = [\n \"id\",\n \"type\",\n \"label\",\n \"description\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const INTERACTION_FIELDS = [\n \"id\",\n \"mode\",\n \"label\",\n \"position\",\n \"size\",\n \"fill\",\n \"stroke\",\n] as const;\nexport const FLOW_FIELDS = [\"id\", \"label\", \"position\", \"size\"] as const;\nexport const ANNOTATION_FIELDS = [\"id\", \"text\", \"position\", \"size\", \"attachedTo\"] as const;\n\n/** Unknown fields by name, sorted, with their values in canonical form. */\nexport type ForeignFields = Readonly<Record<string, unknown>>;\n\n/**\n * The fields of `value` outside `knownFields`, or undefined when there are none. A value that\n * sits in several places of `value` is copied at each of them; past 1,000,000 entries repeated\n * that way it throws, and so does a value that contains itself.\n */\nexport function foreignFields(\n value: object,\n knownFields: readonly string[],\n): ForeignFields | undefined {\n return copyForeignFields(value, knownFields, canonicalCopier());\n}\n\n/**\n * `known` followed by the foreign fields of `source`. Built from entries, never by assignment, so\n * a field named `__proto__` stays a field instead of replacing the prototype. A value that sits in\n * several places of `source` is copied at each of them; past 1,000,000 entries repeated that way\n * it throws, and so does a value that contains itself.\n */\nexport function withForeignFields<T extends object>(\n known: T,\n source: object | undefined,\n knownFields: readonly string[],\n): T {\n return appendForeignFields(known, source, knownFields, canonicalCopier());\n}\n","/**\n * Deterministic serialisation of the document model.\n *\n * Producing byte-stable JSON (sorted arrays, fixed key order, rounded\n * coordinates) makes diagrams diff-friendly in version control and gives\n * stable share URLs / embedded payloads.\n */\n\nimport {\n ANNOTATION_FIELDS,\n DOCUMENT_FIELDS,\n FLOW_FIELDS,\n INTERACTION_FIELDS,\n TEAM_NODE_FIELDS,\n} from \"./foreign\";\nimport { appendForeignFields, canonicalCopier, type CanonicalCopy } from \"./canonical-copy\";\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type {\n FlowShape,\n InteractionShape,\n Position,\n Size,\n TeamNode,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\n\n/** Round to 2 decimals to strip floating-point drift from drag operations. */\nfunction round(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nfunction normPosition(p: Position): Position {\n return { x: round(p.x), y: round(p.y) };\n}\n\nfunction normSize(s: Size): Size {\n return { width: round(s.width), height: round(s.height) };\n}\n\n/** Drops undefined fields and applies a fixed key order to a node. */\nfunction normNode(n: TeamNode, copy: CanonicalCopy): TeamNode {\n const out: TeamNode = {\n id: n.id,\n type: n.type,\n label: n.label,\n position: normPosition(n.position),\n size: normSize(n.size),\n };\n if (n.description) out.description = n.description;\n if (n.fill) out.fill = n.fill;\n if (n.stroke) out.stroke = n.stroke;\n return appendForeignFields(out, n, TEAM_NODE_FIELDS, copy);\n}\n\nfunction normInteraction(e: InteractionShape, copy: CanonicalCopy): InteractionShape {\n const out: InteractionShape = {\n id: e.id,\n mode: e.mode,\n position: normPosition(e.position),\n size: normSize(e.size),\n };\n if (e.label) out.label = e.label;\n if (e.fill) out.fill = e.fill;\n if (e.stroke) out.stroke = e.stroke;\n return appendForeignFields(out, e, INTERACTION_FIELDS, copy);\n}\n\nfunction normFlow(f: FlowShape, copy: CanonicalCopy): FlowShape {\n const out: FlowShape = {\n id: f.id,\n position: normPosition(f.position),\n size: normSize(f.size),\n };\n if (f.label) out.label = f.label;\n return appendForeignFields(out, f, FLOW_FIELDS, copy);\n}\n\nfunction normAnnotation(a: TextAnnotation, copy: CanonicalCopy): TextAnnotation {\n const out: TextAnnotation = {\n id: a.id,\n text: a.text,\n position: normPosition(a.position),\n size: normSize(a.size),\n };\n if (a.attachedTo) out.attachedTo = a.attachedTo;\n return appendForeignFields(out, a, ANNOTATION_FIELDS, copy);\n}\n\nconst byId = (a: { id: string }, b: { id: string }): number =>\n a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n\n/**\n * Returns a canonicalised copy of a document (sorted, rounded, version-stamped). Fields the\n * modeler does not know follow the known ones, sorted by name. A value of such a field that sits\n * in several places of the document is copied at each of them, and its entries count at every\n * place after the first: past 1,000,000 such repeated entries it throws, and so does a value that\n * contains itself. A document that shares nothing has no such limit.\n */\nexport function canonicalize(doc: TtDocument): TtDocument {\n const copy = canonicalCopier();\n return appendForeignFields(\n {\n version: DOCUMENT_VERSION,\n title: doc.title,\n nodes: [...doc.nodes].map((node) => normNode(node, copy)).sort(byId),\n interactions: [...doc.interactions]\n .map((interaction) => normInteraction(interaction, copy))\n .sort(byId),\n flows: [...doc.flows].map((flow) => normFlow(flow, copy)).sort(byId),\n annotations: [...doc.annotations]\n .map((annotation) => normAnnotation(annotation, copy))\n .sort(byId),\n },\n doc,\n DOCUMENT_FIELDS,\n copy,\n );\n}\n\n/**\n * Serialises a document to deterministic JSON. An empty `annotations` list is left out, so\n * re-saving a model that has no annotations changes nothing but its version stamp. The pretty\n * form is the file on disk and ends with a line break, like the files editors and Git expect;\n * the compact form (share links, local storage) has none.\n */\nexport function serializeDocument(doc: TtDocument, pretty = true): string {\n const canonical = canonicalize(doc);\n const output =\n canonical.annotations.length > 0\n ? canonical\n : Object.fromEntries(Object.entries(canonical).filter(([key]) => key !== \"annotations\"));\n return pretty ? `${JSON.stringify(output, null, 2)}\\n` : JSON.stringify(output);\n}\n","/**\n * Factory helpers for constructing well-formed model objects with the correct\n * notation defaults (sizes, labels). Kept DOM-free.\n */\n\nimport { nanoid } from \"nanoid\";\nimport { ANNOTATION_SPEC, FLOW_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\nimport type {\n FlowShape,\n InteractionMode,\n InteractionShape,\n Position,\n TeamNode,\n TeamType,\n TextAnnotation,\n TtDocument,\n} from \"./types\";\nimport { DOCUMENT_VERSION } from \"./types\";\n\nexport function newId(prefix: string): string {\n return `${prefix}_${nanoid(8)}`;\n}\n\n/** Creates a team node of the given type at a position, with notation defaults. */\nexport function createTeamNode(\n type: TeamType,\n position: Position,\n overrides: Partial<Omit<TeamNode, \"id\" | \"type\">> = {},\n): TeamNode {\n const spec = TEAM_TYPE_SPECS[type];\n return {\n id: newId(\"team\"),\n type,\n label: overrides.label ?? spec.label,\n description: overrides.description,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed interaction shape of the given mode, with notation defaults. */\nexport function createInteractionShape(\n mode: InteractionMode,\n position: Position,\n overrides: Partial<Omit<InteractionShape, \"id\" | \"mode\" | \"position\">> = {},\n): InteractionShape {\n const spec = INTERACTION_MODE_SPECS[mode];\n return {\n id: newId(\"int\"),\n mode,\n position,\n size: overrides.size ?? { ...spec.defaultSize },\n label: overrides.label,\n fill: overrides.fill,\n stroke: overrides.stroke,\n };\n}\n\n/** Creates a placed \"flow of change\" arrow, with notation defaults. */\nexport function createFlowShape(\n position: Position,\n overrides: Partial<Omit<FlowShape, \"id\" | \"position\">> = {},\n): FlowShape {\n return {\n id: newId(\"flow\"),\n position,\n size: overrides.size ?? { ...FLOW_SPEC.defaultSize },\n label: overrides.label ?? FLOW_SPEC.label,\n };\n}\n\n/** Creates a text annotation, optionally attached to a team, interaction or flow. */\nexport function createTextAnnotation(\n position: Position,\n overrides: Partial<Omit<TextAnnotation, \"id\" | \"position\">> = {},\n): TextAnnotation {\n return {\n id: newId(\"ann\"),\n text: overrides.text ?? \"\",\n position,\n size: overrides.size ?? { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: overrides.attachedTo,\n };\n}\n\n/** An empty document with sensible defaults. */\nexport function emptyDocument(title = \"Untitled team topology\"): TtDocument {\n return {\n version: DOCUMENT_VERSION,\n title,\n nodes: [],\n interactions: [],\n flows: [],\n annotations: [],\n };\n}\n","/**\n * A small but complete example diagram exercising all four team types, all three\n * interaction modes (as placed shapes overlaying the team boundaries), a\n * flow-of-change element and an attached annotation. The stream-aligned teams\n * are stacked as parallel lanes along the flow of change, as in the Team\n * Topologies book: side by side on the flow they would read as hand-offs. Ids are\n * fixed so the fixture serialises stably.\n */\n\nimport { DOCUMENT_VERSION } from \"./types\";\nimport type { TtDocument } from \"./types\";\nimport { ANNOTATION_SPEC, INTERACTION_MODE_SPECS, TEAM_TYPE_SPECS } from \"./notation\";\n\nconst s = TEAM_TYPE_SPECS;\nconst i = INTERACTION_MODE_SPECS;\n\nconst LANE_WIDTH = 600;\n\nexport const SAMPLE_DOCUMENT: TtDocument = {\n version: DOCUMENT_VERSION,\n title: \"Online shop team topology\",\n nodes: [\n {\n id: \"team_test_automation\",\n type: \"enabling\",\n label: \"Test Automation\",\n description: \"Coaches stream-aligned teams in test automation, then steps back.\",\n position: { x: 40, y: 150 },\n size: { width: s.enabling.defaultSize.width, height: 222 },\n },\n {\n id: \"team_discovery\",\n type: \"stream-aligned\",\n label: \"Product Discovery\",\n description: \"Owns search, browsing and product pages end-to-end.\",\n position: { x: 220, y: 150 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_checkout\",\n type: \"stream-aligned\",\n label: \"Checkout & Payments\",\n description: \"Owns the checkout and payment journey end-to-end.\",\n position: { x: 220, y: 276 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fulfilment\",\n type: \"stream-aligned\",\n label: \"Order Fulfilment\",\n description: \"Owns delivery, tracking and returns end-to-end.\",\n position: { x: 220, y: 402 },\n size: { width: LANE_WIDTH, height: s[\"stream-aligned\"].defaultSize.height },\n },\n {\n id: \"team_fraud\",\n type: \"complicated-subsystem\",\n label: \"Fraud Detection\",\n description: \"Specialists for the real-time fraud scoring model.\",\n position: { x: 880, y: 249 },\n size: { ...s[\"complicated-subsystem\"].defaultSize },\n },\n {\n id: \"team_platform\",\n type: \"platform\",\n label: \"Cloud Platform\",\n description: \"Self-service CI/CD, runtime and observability for all teams.\",\n position: { x: 220, y: 552 },\n size: { width: LANE_WIDTH, height: 110 },\n },\n ],\n interactions: [\n {\n id: \"int_testing_discovery\",\n mode: \"facilitating\",\n position: { x: 148, y: 156 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_testing_checkout\",\n mode: \"facilitating\",\n position: { x: 148, y: 282 },\n size: { ...i.facilitating.defaultSize },\n },\n {\n id: \"int_checkout_fraud\",\n mode: \"collaboration\",\n label: \"fraud rules\",\n position: { x: 794, y: 288 },\n size: { ...i.collaboration.defaultSize },\n },\n {\n id: \"int_platform_fulfilment\",\n mode: \"x-as-a-service\",\n position: { x: 476, y: 486 },\n size: { ...i[\"x-as-a-service\"].defaultSize },\n },\n ],\n flows: [\n {\n id: \"flow_main\",\n label: \"Flow of change\",\n position: { x: 40, y: 40 },\n size: { width: 1010, height: 56 },\n },\n ],\n annotations: [\n {\n id: \"ann_fraud_handover\",\n text: \"Collaboration until the fraud rules are stable (Q3), then X-as-a-Service\",\n position: { x: 880, y: 423 },\n size: { ...ANNOTATION_SPEC.defaultSize },\n attachedTo: \"int_checkout_fraud\",\n },\n ],\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miragon/team-topologies-schema-model",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "The Team Topologies data model with types, the notation specification, runtime validation, migrations and deterministic JSON serialization.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|