@glyphlab/diagram-core 0.1.0 → 0.2.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.
@@ -22,7 +22,7 @@ var colorLabel = (color) => isPreset(color) ? color[0].toUpperCase() + color.sli
22
22
 
23
23
  // packages/diagram-core/src/format.ts
24
24
  import { z as z2 } from "zod";
25
- var DIAGRAM_SCHEMA_VERSION = 5;
25
+ var DIAGRAM_SCHEMA_VERSION = 6;
26
26
  var LAYERS = ["ui", "runtime", "tools", "domain"];
27
27
  var layerSchema = z2.enum(LAYERS);
28
28
  var idSchema = z2.string().min(1);
@@ -122,13 +122,16 @@ var nodeV4Schema = nodeV3Schema.extend({ links: z2.array(linkV4Schema).optional(
122
122
  var repoIdSchema = z2.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,39}$/, 'a repo id is letters, digits, "-" or "_"');
123
123
  var linkSchema = linkV4Schema.extend({ repo: repoIdSchema.optional() });
124
124
  var repoRefSchema = z2.strictObject({
125
- // e.g. "github.com/you/glyph"
125
+ // e.g. "github.com/you/cakeslice"
126
126
  remote: z2.string().min(1).optional(),
127
127
  branch: z2.string().min(1).optional(),
128
128
  // The commit the links were written against (a full or abbreviated hex SHA).
129
129
  sha: z2.string().regex(/^[0-9a-f]{7,64}$/, "a commit SHA is 7 to 64 lowercase hex characters").optional()
130
130
  });
131
131
  var nodeV5Schema = nodeV3Schema.extend({ links: z2.array(linkSchema).optional() });
132
+ var edgeWidthSchema = z2.enum(["thin", "thick"]);
133
+ var edgeArrowSchema = z2.enum(["end", "start", "both", "none"]);
134
+ var edgeV6Schema = edgeSchema.extend({ width: edgeWidthSchema.optional(), arrow: edgeArrowSchema.optional() });
132
135
  var orientationSchema = z2.enum(["horizontal", "vertical"]);
133
136
  var groupSchema = groupV2Schema.extend({
134
137
  lane: z2.object({ body: z2.string(), orientation: orientationSchema }).optional()
@@ -152,7 +155,7 @@ var diagramV4Schema = z2.strictObject({
152
155
  edges: z2.array(edgeSchema)
153
156
  }).superRefine(checkDiagram);
154
157
  var diagramV5Schema = z2.strictObject({
155
- schemaVersion: z2.literal(DIAGRAM_SCHEMA_VERSION),
158
+ schemaVersion: z2.literal(5),
156
159
  name: z2.string().min(1),
157
160
  description: z2.string().optional(),
158
161
  type: z2.enum(["system", "swimlane"]).optional(),
@@ -161,7 +164,17 @@ var diagramV5Schema = z2.strictObject({
161
164
  nodes: z2.array(nodeV5Schema),
162
165
  edges: z2.array(edgeSchema)
163
166
  }).superRefine(checkDiagram);
164
- var diagramSchema = diagramV5Schema;
167
+ var diagramV6Schema = z2.strictObject({
168
+ schemaVersion: z2.literal(DIAGRAM_SCHEMA_VERSION),
169
+ name: z2.string().min(1),
170
+ description: z2.string().optional(),
171
+ type: z2.enum(["system", "swimlane"]).optional(),
172
+ repos: z2.record(repoIdSchema, repoRefSchema).optional(),
173
+ groups: z2.array(groupSchema),
174
+ nodes: z2.array(nodeV5Schema),
175
+ edges: z2.array(edgeV6Schema)
176
+ }).superRefine(checkDiagram);
177
+ var diagramSchema = diagramV6Schema;
165
178
  var LAYER_COLOR = { ui: "blue", runtime: "purple", tools: "orange", domain: "green" };
166
179
  function upgradeV1(data) {
167
180
  const colored = (item) => ({ ...item, color: LAYER_COLOR[item.layer] });
@@ -176,7 +189,8 @@ var diagramFormat = defineFormat({
176
189
  { version: 2, schema: diagramV2Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 3 } }) },
177
190
  { version: 3, schema: diagramV3Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 4 } }) },
178
191
  { version: 4, schema: diagramV4Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 5 } }) },
179
- { version: 5, schema: diagramV5Schema }
192
+ { version: 5, schema: diagramV5Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 6 } }) },
193
+ { version: 6, schema: diagramV6Schema }
180
194
  ]
181
195
  });
182
196
  function parseDiagram(input) {
@@ -220,11 +234,15 @@ export {
220
234
  linkSchema,
221
235
  repoRefSchema,
222
236
  nodeV5Schema,
237
+ edgeWidthSchema,
238
+ edgeArrowSchema,
239
+ edgeV6Schema,
223
240
  orientationSchema,
224
241
  groupSchema,
225
242
  diagramV3Schema,
226
243
  diagramV4Schema,
227
244
  diagramV5Schema,
245
+ diagramV6Schema,
228
246
  diagramSchema,
229
247
  diagramFormat,
230
248
  parseDiagram,
@@ -232,4 +250,4 @@ export {
232
250
  parseDiagramJson,
233
251
  serializeDiagram
234
252
  };
235
- //# sourceMappingURL=chunk-XCRPIPPL.js.map
253
+ //# sourceMappingURL=chunk-KZD7D662.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/colors.ts","../src/format.ts"],"sourcesContent":["import { z } from 'zod'\n\n// The colours a node, group or edge can be given. A colour is a preset name, which follows the theme (see --c-* in theme.css of\n// @glyphlab/diagram-react), or a fixed #rrggbb. The website checks the same two forms (glyph-remote lib/pull-request-reports/schema.ts).\nexport const COLOR_PRESETS = ['red', 'orange', 'yellow', 'green', 'teal', 'blue', 'purple', 'pink', 'gray'] as const\nexport type ColorPreset = (typeof COLOR_PRESETS)[number]\n\nexport const HEX_COLOR = /^#[0-9a-fA-F]{6}$/\n\nexport const colorSchema = z.union([z.enum(COLOR_PRESETS), z.string().regex(HEX_COLOR)])\n\nexport const isPreset = (color: string): color is ColorPreset => (COLOR_PRESETS as readonly string[]).includes(color)\n\n// What CSS draws for a stored colour. Anything that is neither a preset nor a hex gives nothing, so a bad value in a file\n// can never reach a style attribute.\nexport function colorCss(color: string | undefined): string | undefined {\n if (color === undefined) return undefined\n if (isPreset(color)) return `var(--c-${color})`\n return HEX_COLOR.test(color) ? color.toLowerCase() : undefined\n}\n\n// One arrow head is drawn for each colour in use, since a marker cannot take the colour of the line that points at it.\nexport const colorKey = (color: string) => (isPreset(color) ? color : color.slice(1).toLowerCase())\nexport const arrowId = (base: string, color: string | undefined) => (colorCss(color) && color ? `${base}-${colorKey(color)}` : base)\n\nexport const colorLabel = (color: string) => (isPreset(color) ? color[0].toUpperCase() + color.slice(1) : color.toLowerCase())\n","import { z } from 'zod'\nimport { colorSchema } from './colors'\nimport { defineFormat, readVersioned, readVersionedOrThrow, serializeVersioned } from './versioning'\n\n// Bump when the serialized shape changes in a way old files can't satisfy.\nexport const DIAGRAM_SCHEMA_VERSION = 5\n\n// Layers were the only way to colour a node in v1. From v2 a layer is an optional label and a colour is its own setting.\nexport const LAYERS = ['ui', 'runtime', 'tools', 'domain'] as const\nexport const layerSchema = z.enum(LAYERS)\n\nexport { colorSchema }\n\nconst idSchema = z.string().min(1)\nconst coordinate = z.number().finite()\nconst dimension = z.number().finite().positive()\n\nexport const groupV1Schema = z.strictObject({\n id: idSchema,\n title: z.string().min(1),\n layer: layerSchema,\n x: coordinate,\n y: coordinate,\n w: dimension,\n h: dimension,\n})\n\nexport const nodeV1Schema = z.strictObject({\n id: idSchema,\n title: z.string().min(1),\n layer: layerSchema,\n x: coordinate,\n y: coordinate,\n w: dimension,\n h: dimension,\n // Markdown (GFM) with fenced code blocks.\n body: z.string(),\n})\n\nexport const edgeV1Schema = z.strictObject({\n id: idSchema,\n from: idSchema,\n to: idSchema,\n label: z.string(),\n // Asynchronous event rather than a direct call.\n dashed: z.boolean().optional(),\n // Optional AI assistance rather than a required step.\n optional: z.boolean().optional(),\n})\n\nfunction findDuplicates(ids: string[]) {\n const seen = new Set<string>()\n const dupes = new Set<string>()\n for (const id of ids) {\n if (seen.has(id)) dupes.add(id)\n seen.add(id)\n }\n return [...dupes]\n}\n\n// The checks both versions share: ids are unique and an edge joins nodes that exist.\nfunction checkDiagram(\n diagram: { groups: { id: string }[]; nodes: { id: string }[]; edges: { id: string; from: string; to: string }[] },\n ctx: z.RefinementCtx,\n) {\n const collections = [\n ['groups', diagram.groups],\n ['nodes', diagram.nodes],\n ['edges', diagram.edges],\n ] as const\n\n for (const [key, items] of collections) {\n for (const id of findDuplicates(items.map((item) => item.id))) {\n ctx.addIssue({ code: 'custom', path: [key], message: `Duplicate ${key} id \"${id}\"` })\n }\n }\n\n const nodeIds = new Set(diagram.nodes.map((n) => n.id))\n diagram.edges.forEach((edge, i) => {\n for (const end of ['from', 'to'] as const) {\n if (!nodeIds.has(edge[end])) {\n ctx.addIssue({\n code: 'custom',\n path: ['edges', i, end],\n message: `Edge \"${edge.id}\" references unknown node \"${edge[end]}\"`,\n })\n }\n }\n })\n}\n\n// Version 1 of the file format. Frozen: a released schema is never edited. A breaking change adds\n// a new version (and a migration) in `diagramFormat` below instead.\nexport const diagramV1Schema = z\n .strictObject({\n schemaVersion: z.literal(1),\n name: z.string().min(1),\n description: z.string().optional(),\n groups: z.array(groupV1Schema),\n nodes: z.array(nodeV1Schema),\n edges: z.array(edgeV1Schema),\n })\n .superRefine(checkDiagram)\n\n// Version 2: a node, group or edge may have its own colour, and a layer is optional (a node needs none).\nexport const groupV2Schema = groupV1Schema.extend({ layer: layerSchema.optional(), color: colorSchema.optional() })\nexport const nodeV2Schema = nodeV1Schema.extend({ layer: layerSchema.optional(), color: colorSchema.optional() })\nexport const edgeSchema = edgeV1Schema.extend({ color: colorSchema.optional() })\n\nexport const diagramV2Schema = z\n .strictObject({\n schemaVersion: z.literal(2),\n name: z.string().min(1),\n description: z.string().optional(),\n groups: z.array(groupV2Schema),\n nodes: z.array(nodeV2Schema),\n edges: z.array(edgeSchema),\n })\n .superRefine(checkDiagram)\n\n// Version 3 additions: a node may carry `decisions`, optional Markdown on why it was chosen and what else was considered.\n// `systemsDesign` holds the node's answers to the Systems design questions, by question id (see checklist.ts).\nexport const nodeSchema = nodeV2Schema.extend({ decisions: z.string().optional(), systemsDesign: z.record(z.string(), z.string()).optional() })\n\n// Version 4 addition: a node may list the code it describes. `hash` is taken from the linked lines when the link is made, so a later\n// check can tell that the code changed; a link without lines or a hash can still be checked for the file and symbol existing.\nexport const linkV4Schema = z.strictObject({\n path: z.string().min(1),\n symbol: z.string().min(1).optional(),\n lines: z.tuple([z.number().int().positive(), z.number().int().positive()]).refine(([from, to]) => from <= to, 'lines must run from a line to the same or a later one').optional(),\n hash: z.string().min(1).optional(),\n})\nexport const nodeV3Schema = nodeSchema\nexport const nodeV4Schema = nodeV3Schema.extend({ links: z.array(linkV4Schema).optional() })\n\n// Version 5 additions: a link names the repo its path is in (`repo`, an id from the project's workspace file), and the path is then\n// relative to that repo. A link with no `repo` belongs to the project's default repo, so v4 files read unchanged. The diagram may\n// carry `repos`: for each repo id, where it is on GitHub and which commit the design was written against (filled in when publishing),\n// so a viewer with no access to the files can still link to them. Nothing about where a repo is on a person's disk is ever stored here.\nexport const repoIdSchema = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,39}$/, 'a repo id is letters, digits, \"-\" or \"_\"')\nexport const linkSchema = linkV4Schema.extend({ repo: repoIdSchema.optional() })\nexport const repoRefSchema = z.strictObject({\n // e.g. \"github.com/you/glyph\"\n remote: z.string().min(1).optional(),\n branch: z.string().min(1).optional(),\n // The commit the links were written against (a full or abbreviated hex SHA).\n sha: z.string().regex(/^[0-9a-f]{7,64}$/, 'a commit SHA is 7 to 64 lowercase hex characters').optional(),\n})\nexport const nodeV5Schema = nodeV3Schema.extend({ links: z.array(linkSchema).optional() })\n\nexport const orientationSchema = z.enum(['horizontal', 'vertical'])\nexport const groupSchema = groupV2Schema.extend({\n lane: z.object({ body: z.string(), orientation: orientationSchema }).optional(),\n})\nexport const diagramV3Schema = z.strictObject({\n schemaVersion: z.literal(3),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV3Schema),\n edges: z.array(edgeSchema),\n}).superRefine(checkDiagram)\nexport const diagramV4Schema = z.strictObject({\n schemaVersion: z.literal(4),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV4Schema),\n edges: z.array(edgeSchema),\n}).superRefine(checkDiagram)\n\nexport const diagramV5Schema = z.strictObject({\n schemaVersion: z.literal(DIAGRAM_SCHEMA_VERSION),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n repos: z.record(repoIdSchema, repoRefSchema).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV5Schema),\n edges: z.array(edgeSchema),\n}).superRefine(checkDiagram)\n\nexport type LaneOrientation = z.infer<typeof orientationSchema>\nexport type DiagramType = 'system' | 'swimlane'\nexport type Layer = z.infer<typeof layerSchema>\nexport type Color = z.infer<typeof colorSchema>\nexport type GroupDef = z.infer<typeof groupSchema>\nexport type LinkDef = z.infer<typeof linkSchema>\nexport type NodeDef = z.infer<typeof nodeV5Schema>\nexport type RepoRef = z.infer<typeof repoRefSchema>\nexport type EdgeDef = z.infer<typeof edgeSchema>\nexport type DiagramFile = z.infer<typeof diagramSchema>\n\n// The part of a diagram the stores hold: everything except file metadata.\nexport type DiagramData = Pick<DiagramFile, 'groups' | 'nodes' | 'edges' | 'type' | 'repos'>\n\n// The schema of the current version.\nexport const diagramSchema = diagramV5Schema\n\nconst LAYER_COLOR = { ui: 'blue', runtime: 'purple', tools: 'orange', domain: 'green' } as const\n\nfunction upgradeV1(data: z.infer<typeof diagramV1Schema>) {\n const colored = <T extends { layer: Layer }>(item: T) => ({ ...item, color: LAYER_COLOR[item.layer] })\n return { data: { ...data, schemaVersion: 2, groups: data.groups.map(colored), nodes: data.nodes.map(colored) } }\n}\n\n// Every version the app can read, oldest first, ending with the current one.\nexport const diagramFormat = defineFormat<DiagramFile>({\n name: 'diagram',\n history: [\n // Nodes and groups were coloured by their layer. Each is given that layer's colour, so a v1 diagram looks the same and a\n // colour is from then on its own setting.\n { version: 1, schema: diagramV1Schema, migrate: upgradeV1 },\n { version: 2, schema: diagramV2Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 3 } }) },\n { version: 3, schema: diagramV3Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 4 } }) },\n { version: 4, schema: diagramV4Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 5 } }) },\n { version: 5, schema: diagramV5Schema },\n ],\n})\n\n// Throws a typed error (see shared/versioning); use for trusted input like bundled samples.\nexport function parseDiagram(input: unknown): DiagramFile {\n return readVersionedOrThrow(diagramFormat, input)\n}\n\n// Returns a result instead of throwing; use for user-supplied files. Older versions are\n// upgraded on the way in, with any warnings reported.\nexport function readDiagram(input: unknown) {\n return readVersioned(diagramFormat, input)\n}\n\nexport function parseDiagramJson(text: string): DiagramFile {\n return parseDiagram(JSON.parse(text))\n}\n\n// Always writes the current version.\nexport function serializeDiagram(diagram: DiagramFile): string {\n return serializeVersioned(diagramFormat, diagram)\n}\n"],"mappings":"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","names":["z","z","z"]}
1
+ {"version":3,"sources":["../src/colors.ts","../src/format.ts"],"sourcesContent":["import { z } from 'zod'\n\n// The colours a node, group or edge can be given. A colour is a preset name, which follows the theme (see --c-* in theme.css of\n// @glyphlab/diagram-react), or a fixed #rrggbb. The website checks the same two forms (glyph-remote lib/pull-request-reports/schema.ts).\nexport const COLOR_PRESETS = ['red', 'orange', 'yellow', 'green', 'teal', 'blue', 'purple', 'pink', 'gray'] as const\nexport type ColorPreset = (typeof COLOR_PRESETS)[number]\n\nexport const HEX_COLOR = /^#[0-9a-fA-F]{6}$/\n\nexport const colorSchema = z.union([z.enum(COLOR_PRESETS), z.string().regex(HEX_COLOR)])\n\nexport const isPreset = (color: string): color is ColorPreset => (COLOR_PRESETS as readonly string[]).includes(color)\n\n// What CSS draws for a stored colour. Anything that is neither a preset nor a hex gives nothing, so a bad value in a file\n// can never reach a style attribute.\nexport function colorCss(color: string | undefined): string | undefined {\n if (color === undefined) return undefined\n if (isPreset(color)) return `var(--c-${color})`\n return HEX_COLOR.test(color) ? color.toLowerCase() : undefined\n}\n\n// One arrow head is drawn for each colour in use, since a marker cannot take the colour of the line that points at it.\nexport const colorKey = (color: string) => (isPreset(color) ? color : color.slice(1).toLowerCase())\nexport const arrowId = (base: string, color: string | undefined) => (colorCss(color) && color ? `${base}-${colorKey(color)}` : base)\n\nexport const colorLabel = (color: string) => (isPreset(color) ? color[0].toUpperCase() + color.slice(1) : color.toLowerCase())\n","import { z } from 'zod'\nimport { colorSchema } from './colors'\nimport { defineFormat, readVersioned, readVersionedOrThrow, serializeVersioned } from './versioning'\n\n// Bump when the serialized shape changes in a way old files can't satisfy.\nexport const DIAGRAM_SCHEMA_VERSION = 6\n\n// Layers were the only way to colour a node in v1. From v2 a layer is an optional label and a colour is its own setting.\nexport const LAYERS = ['ui', 'runtime', 'tools', 'domain'] as const\nexport const layerSchema = z.enum(LAYERS)\n\nexport { colorSchema }\n\nconst idSchema = z.string().min(1)\nconst coordinate = z.number().finite()\nconst dimension = z.number().finite().positive()\n\nexport const groupV1Schema = z.strictObject({\n id: idSchema,\n title: z.string().min(1),\n layer: layerSchema,\n x: coordinate,\n y: coordinate,\n w: dimension,\n h: dimension,\n})\n\nexport const nodeV1Schema = z.strictObject({\n id: idSchema,\n title: z.string().min(1),\n layer: layerSchema,\n x: coordinate,\n y: coordinate,\n w: dimension,\n h: dimension,\n // Markdown (GFM) with fenced code blocks.\n body: z.string(),\n})\n\nexport const edgeV1Schema = z.strictObject({\n id: idSchema,\n from: idSchema,\n to: idSchema,\n label: z.string(),\n // Asynchronous event rather than a direct call.\n dashed: z.boolean().optional(),\n // Optional AI assistance rather than a required step.\n optional: z.boolean().optional(),\n})\n\nfunction findDuplicates(ids: string[]) {\n const seen = new Set<string>()\n const dupes = new Set<string>()\n for (const id of ids) {\n if (seen.has(id)) dupes.add(id)\n seen.add(id)\n }\n return [...dupes]\n}\n\n// The checks both versions share: ids are unique and an edge joins nodes that exist.\nfunction checkDiagram(\n diagram: { groups: { id: string }[]; nodes: { id: string }[]; edges: { id: string; from: string; to: string }[] },\n ctx: z.RefinementCtx,\n) {\n const collections = [\n ['groups', diagram.groups],\n ['nodes', diagram.nodes],\n ['edges', diagram.edges],\n ] as const\n\n for (const [key, items] of collections) {\n for (const id of findDuplicates(items.map((item) => item.id))) {\n ctx.addIssue({ code: 'custom', path: [key], message: `Duplicate ${key} id \"${id}\"` })\n }\n }\n\n const nodeIds = new Set(diagram.nodes.map((n) => n.id))\n diagram.edges.forEach((edge, i) => {\n for (const end of ['from', 'to'] as const) {\n if (!nodeIds.has(edge[end])) {\n ctx.addIssue({\n code: 'custom',\n path: ['edges', i, end],\n message: `Edge \"${edge.id}\" references unknown node \"${edge[end]}\"`,\n })\n }\n }\n })\n}\n\n// Version 1 of the file format. Frozen: a released schema is never edited. A breaking change adds\n// a new version (and a migration) in `diagramFormat` below instead.\nexport const diagramV1Schema = z\n .strictObject({\n schemaVersion: z.literal(1),\n name: z.string().min(1),\n description: z.string().optional(),\n groups: z.array(groupV1Schema),\n nodes: z.array(nodeV1Schema),\n edges: z.array(edgeV1Schema),\n })\n .superRefine(checkDiagram)\n\n// Version 2: a node, group or edge may have its own colour, and a layer is optional (a node needs none).\nexport const groupV2Schema = groupV1Schema.extend({ layer: layerSchema.optional(), color: colorSchema.optional() })\nexport const nodeV2Schema = nodeV1Schema.extend({ layer: layerSchema.optional(), color: colorSchema.optional() })\nexport const edgeSchema = edgeV1Schema.extend({ color: colorSchema.optional() })\n\nexport const diagramV2Schema = z\n .strictObject({\n schemaVersion: z.literal(2),\n name: z.string().min(1),\n description: z.string().optional(),\n groups: z.array(groupV2Schema),\n nodes: z.array(nodeV2Schema),\n edges: z.array(edgeSchema),\n })\n .superRefine(checkDiagram)\n\n// Version 3 additions: a node may carry `decisions`, optional Markdown on why it was chosen and what else was considered.\n// `systemsDesign` holds the node's answers to the Systems design questions, by question id (see checklist.ts).\nexport const nodeSchema = nodeV2Schema.extend({ decisions: z.string().optional(), systemsDesign: z.record(z.string(), z.string()).optional() })\n\n// Version 4 addition: a node may list the code it describes. `hash` is taken from the linked lines when the link is made, so a later\n// check can tell that the code changed; a link without lines or a hash can still be checked for the file and symbol existing.\nexport const linkV4Schema = z.strictObject({\n path: z.string().min(1),\n symbol: z.string().min(1).optional(),\n lines: z.tuple([z.number().int().positive(), z.number().int().positive()]).refine(([from, to]) => from <= to, 'lines must run from a line to the same or a later one').optional(),\n hash: z.string().min(1).optional(),\n})\nexport const nodeV3Schema = nodeSchema\nexport const nodeV4Schema = nodeV3Schema.extend({ links: z.array(linkV4Schema).optional() })\n\n// Version 5 additions: a link names the repo its path is in (`repo`, an id from the project's workspace file), and the path is then\n// relative to that repo. A link with no `repo` belongs to the project's default repo, so v4 files read unchanged. The diagram may\n// carry `repos`: for each repo id, where it is on GitHub and which commit the design was written against (filled in when publishing),\n// so a viewer with no access to the files can still link to them. Nothing about where a repo is on a person's disk is ever stored here.\nexport const repoIdSchema = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9_-]{0,39}$/, 'a repo id is letters, digits, \"-\" or \"_\"')\nexport const linkSchema = linkV4Schema.extend({ repo: repoIdSchema.optional() })\nexport const repoRefSchema = z.strictObject({\n // e.g. \"github.com/you/cakeslice\"\n remote: z.string().min(1).optional(),\n branch: z.string().min(1).optional(),\n // The commit the links were written against (a full or abbreviated hex SHA).\n sha: z.string().regex(/^[0-9a-f]{7,64}$/, 'a commit SHA is 7 to 64 lowercase hex characters').optional(),\n})\nexport const nodeV5Schema = nodeV3Schema.extend({ links: z.array(linkSchema).optional() })\n\n// Version 6 additions: an edge may set how thick its line is (`width`; none means the usual thickness) and which end carries an arrow head\n// (`arrow`; none means the end, at the `to` node). `arrow` only changes how the line is drawn: the edge still runs from `from` to `to`.\nexport const edgeWidthSchema = z.enum(['thin', 'thick'])\nexport const edgeArrowSchema = z.enum(['end', 'start', 'both', 'none'])\nexport const edgeV6Schema = edgeSchema.extend({ width: edgeWidthSchema.optional(), arrow: edgeArrowSchema.optional() })\n\nexport const orientationSchema = z.enum(['horizontal', 'vertical'])\nexport const groupSchema = groupV2Schema.extend({\n lane: z.object({ body: z.string(), orientation: orientationSchema }).optional(),\n})\nexport const diagramV3Schema = z.strictObject({\n schemaVersion: z.literal(3),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV3Schema),\n edges: z.array(edgeSchema),\n}).superRefine(checkDiagram)\nexport const diagramV4Schema = z.strictObject({\n schemaVersion: z.literal(4),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV4Schema),\n edges: z.array(edgeSchema),\n}).superRefine(checkDiagram)\n\nexport const diagramV5Schema = z.strictObject({\n schemaVersion: z.literal(5),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n repos: z.record(repoIdSchema, repoRefSchema).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV5Schema),\n edges: z.array(edgeSchema),\n}).superRefine(checkDiagram)\n\nexport const diagramV6Schema = z.strictObject({\n schemaVersion: z.literal(DIAGRAM_SCHEMA_VERSION),\n name: z.string().min(1),\n description: z.string().optional(),\n type: z.enum(['system', 'swimlane']).optional(),\n repos: z.record(repoIdSchema, repoRefSchema).optional(),\n groups: z.array(groupSchema),\n nodes: z.array(nodeV5Schema),\n edges: z.array(edgeV6Schema),\n}).superRefine(checkDiagram)\n\nexport type LaneOrientation = z.infer<typeof orientationSchema>\nexport type DiagramType = 'system' | 'swimlane'\nexport type Layer = z.infer<typeof layerSchema>\nexport type Color = z.infer<typeof colorSchema>\nexport type GroupDef = z.infer<typeof groupSchema>\nexport type LinkDef = z.infer<typeof linkSchema>\nexport type NodeDef = z.infer<typeof nodeV5Schema>\nexport type RepoRef = z.infer<typeof repoRefSchema>\nexport type EdgeDef = z.infer<typeof edgeV6Schema>\nexport type EdgeWidth = z.infer<typeof edgeWidthSchema>\nexport type EdgeArrow = z.infer<typeof edgeArrowSchema>\nexport type DiagramFile = z.infer<typeof diagramSchema>\n\n// The part of a diagram the stores hold: everything except file metadata.\nexport type DiagramData = Pick<DiagramFile, 'groups' | 'nodes' | 'edges' | 'type' | 'repos'>\n\n// The schema of the current version.\nexport const diagramSchema = diagramV6Schema\n\nconst LAYER_COLOR = { ui: 'blue', runtime: 'purple', tools: 'orange', domain: 'green' } as const\n\nfunction upgradeV1(data: z.infer<typeof diagramV1Schema>) {\n const colored = <T extends { layer: Layer }>(item: T) => ({ ...item, color: LAYER_COLOR[item.layer] })\n return { data: { ...data, schemaVersion: 2, groups: data.groups.map(colored), nodes: data.nodes.map(colored) } }\n}\n\n// Every version the app can read, oldest first, ending with the current one.\nexport const diagramFormat = defineFormat<DiagramFile>({\n name: 'diagram',\n history: [\n // Nodes and groups were coloured by their layer. Each is given that layer's colour, so a v1 diagram looks the same and a\n // colour is from then on its own setting.\n { version: 1, schema: diagramV1Schema, migrate: upgradeV1 },\n { version: 2, schema: diagramV2Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 3 } }) },\n { version: 3, schema: diagramV3Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 4 } }) },\n { version: 4, schema: diagramV4Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 5 } }) },\n { version: 5, schema: diagramV5Schema, migrate: (data) => ({ data: { ...data, schemaVersion: 6 } }) },\n { version: 6, schema: diagramV6Schema },\n ],\n})\n\n// Throws a typed error (see shared/versioning); use for trusted input like bundled samples.\nexport function parseDiagram(input: unknown): DiagramFile {\n return readVersionedOrThrow(diagramFormat, input)\n}\n\n// Returns a result instead of throwing; use for user-supplied files. Older versions are\n// upgraded on the way in, with any warnings reported.\nexport function readDiagram(input: unknown) {\n return readVersioned(diagramFormat, input)\n}\n\nexport function parseDiagramJson(text: string): DiagramFile {\n return parseDiagram(JSON.parse(text))\n}\n\n// Always writes the current version.\nexport function serializeDiagram(diagram: DiagramFile): string {\n return serializeVersioned(diagramFormat, diagram)\n}\n"],"mappings":"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","names":["z","z","z"]}
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as GroupDef, N as NodeDef, E as EdgeDef, D as DiagramFile } from './repository-C4DyvGsM.js';
2
- export { A as ApplyRequest, a as ApplyResult, B as BindOptions, b as Binding, C as COLOR_PRESETS, c as ChangeEvent, d as Color, e as ColorPreset, f as DIAGRAM_SCHEMA_VERSION, g as DiagramController, h as DiagramData, i as DiagramOp, j as DiagramRepository, k as DiagramSnapshot, l as DiagramStores, m as DiagramType, n as EdgeState, o as GroupState, H as HEX_COLOR, L as LAYERS, p as LIMITS, q as LaneOrientation, r as Layer, s as LinkDef, M as MIN_GROUP, t as MIN_NODE, u as MetaState, v as NodeState, P as Patch, w as PlanResult, R as RepoRef, x as RepositoryConflictError, S as SaveMeta, y as Snapshot, z as StoredDiagram, F as applyPatch, I as arrowId, J as bindRepository, K as colorCss, O as colorKey, Q as colorLabel, T as colorSchema, U as createDiagramController, V as diagramFormat, W as diagramOpSchema, X as diagramSchema, Y as diagramV1Schema, Z as diagramV2Schema, _ as diagramV3Schema, $ as diagramV4Schema, a0 as diagramV5Schema, a1 as diffSnapshots, a2 as edgeSchema, a3 as edgeV1Schema, a4 as findNodeRef, a5 as groupSchema, a6 as groupV1Schema, a7 as groupV2Schema, a8 as httpRepository, a9 as isEmptyPatch, aa as isPreset, ab as layerSchema, ac as linkSchema, ad as linkV4Schema, ae as memoryRepository, af as nodeSchema, ag as nodeV1Schema, ah as nodeV2Schema, ai as nodeV3Schema, aj as nodeV4Schema, ak as nodeV5Schema, al as orientationSchema, am as parseDiagram, an as parseDiagramJson, ao as planChanges, ap as readDiagram, aq as repoIdSchema, ar as repoRefSchema, as as serializeDiagram, at as storageRepository } from './repository-C4DyvGsM.js';
1
+ import { G as GroupDef, N as NodeDef, E as EdgeDef, D as DiagramFile } from './repository-n7clVcr3.js';
2
+ export { A as ApplyRequest, a as ApplyResult, B as BindOptions, b as Binding, C as COLOR_PRESETS, c as ChangeEvent, d as Color, e as ColorPreset, f as DIAGRAM_SCHEMA_VERSION, g as DiagramController, h as DiagramData, i as DiagramOp, j as DiagramRepository, k as DiagramSnapshot, l as DiagramStores, m as DiagramType, n as EdgeArrow, o as EdgeState, p as EdgeWidth, q as GroupState, H as HEX_COLOR, L as LAYERS, r as LIMITS, s as LaneOrientation, t as Layer, u as LinkDef, M as MIN_GROUP, v as MIN_NODE, w as MetaState, x as NodeState, P as Patch, y as PlanResult, R as REMOTE_SOURCE, z as RepoRef, F as RepositoryConflictError, S as SaveMeta, I as Snapshot, J as StoredDiagram, K as applyPatch, O as arrowId, Q as bindRepository, T as colorCss, U as colorKey, V as colorLabel, W as colorSchema, X as createDiagramController, Y as diagramFormat, Z as diagramOpSchema, _ as diagramSchema, $ as diagramV1Schema, a0 as diagramV2Schema, a1 as diagramV3Schema, a2 as diagramV4Schema, a3 as diagramV5Schema, a4 as diagramV6Schema, a5 as diffSnapshots, a6 as edgeArrowSchema, a7 as edgeSchema, a8 as edgeV1Schema, a9 as edgeV6Schema, aa as edgeWidthSchema, ab as findNodeRef, ac as groupSchema, ad as groupV1Schema, ae as groupV2Schema, af as httpRepository, ag as isEmptyPatch, ah as isPreset, ai as layerSchema, aj as linkSchema, ak as linkV4Schema, al as memoryRepository, am as nodeSchema, an as nodeV1Schema, ao as nodeV2Schema, ap as nodeV3Schema, aq as nodeV4Schema, ar as nodeV5Schema, as as orientationSchema, at as parseDiagram, au as parseDiagramJson, av as planChanges, aw as readDiagram, ax as repoIdSchema, ay as repoRefSchema, az as serializeDiagram, aA as storageRepository } from './repository-n7clVcr3.js';
3
3
  export { CurrentVersionDef, Format, MigrationError, MigrationResult, NotADocumentError, ReadOptions, ReadResult, UnsupportedVersionError, ValidationError, VersionDef, VersionError, defineFormat, describeVersionError, readVersioned, readVersionedOrThrow, serializeVersioned, writeVersioned } from './versioning.js';
4
4
  import 'zustand/vanilla';
5
5
  import 'zod';
@@ -149,7 +149,7 @@ declare function linkRepo<R extends KnownRepo>(link: {
149
149
  /** A path inside a repo's folder: relative, no "..", no empty parts. */
150
150
  declare const isRepoRelativePath: (path: string) => boolean;
151
151
  /**
152
- * While editing: the problems in the links of these nodes, given the repos of the project's workspace (`.glyph/workspace.json`, where each
152
+ * While editing: the problems in the links of these nodes, given the repos of the project's workspace (`.cakeslice/workspace.json`, where each
153
153
  * has a folder and a GitHub remote). A link must resolve both ways: its repo (the one it names, or the default when it names none; with
154
154
  * several repos it must name one) is listed and has a remote written as github.com/owner/repo, so it can open on the web, and its path stays
155
155
  * inside that repo's folder, so it can open on disk. The remote is only checked to be defined, never looked up. That the file exists is
package/index.js CHANGED
@@ -15,8 +15,12 @@ import {
15
15
  diagramV3Schema,
16
16
  diagramV4Schema,
17
17
  diagramV5Schema,
18
+ diagramV6Schema,
19
+ edgeArrowSchema,
18
20
  edgeSchema,
19
21
  edgeV1Schema,
22
+ edgeV6Schema,
23
+ edgeWidthSchema,
20
24
  groupSchema,
21
25
  groupV1Schema,
22
26
  groupV2Schema,
@@ -37,7 +41,7 @@ import {
37
41
  repoIdSchema,
38
42
  repoRefSchema,
39
43
  serializeDiagram
40
- } from "./chunk-XCRPIPPL.js";
44
+ } from "./chunk-KZD7D662.js";
41
45
  import {
42
46
  MigrationError,
43
47
  NotADocumentError,
@@ -456,20 +460,26 @@ function applyOp(draft, op) {
456
460
  label: spec.label,
457
461
  ...spec.dashed !== void 0 && { dashed: spec.dashed },
458
462
  ...spec.optional !== void 0 && { optional: spec.optional },
459
- ...spec.color !== void 0 && { color: spec.color }
463
+ ...spec.color !== void 0 && { color: spec.color },
464
+ ...spec.width !== void 0 && { width: spec.width },
465
+ ...spec.arrow !== void 0 && { arrow: spec.arrow }
460
466
  }
461
467
  ];
462
468
  return;
463
469
  }
464
470
  case "updateEdge": {
465
471
  const current = edge(draft, op.id);
466
- const { label, dashed, optional, color } = op.patch;
472
+ const { label, dashed, optional, color, width, arrow } = op.patch;
467
473
  if (Object.values(op.patch).every((v) => v === void 0)) fail(`The update to "${op.id}" changes nothing.`);
468
474
  if (label !== void 0) checkText("The label", label, LIMITS.label);
469
475
  draft.edges = draft.edges.map((e) => {
470
476
  if (e.id !== current.id) return e;
471
477
  const next = { ...e, ...label !== void 0 && { label }, ...dashed !== void 0 && { dashed }, ...optional !== void 0 && { optional } };
472
478
  setColor(next, color);
479
+ if (width === null) delete next.width;
480
+ else if (width !== void 0) next.width = width;
481
+ if (arrow === null) delete next.arrow;
482
+ else if (arrow !== void 0) next.arrow = arrow;
473
483
  return next;
474
484
  });
475
485
  return;
@@ -629,13 +639,22 @@ var diagramOpSchema = z.discriminatedUnion("op", [
629
639
  label: z.string(),
630
640
  dashed: z.boolean().optional(),
631
641
  optional: z.boolean().optional(),
632
- color: colorSchema.optional().describe(colorHelp)
642
+ color: colorSchema.optional().describe(colorHelp),
643
+ width: edgeWidthSchema.optional().describe('Line thickness: "thin" or "thick". Leave out for the usual thickness.'),
644
+ arrow: edgeArrowSchema.optional().describe('Which end has an arrow head: "end" (at the "to" node, the default), "start" (at the "from" node), "both" or "none". It only changes the drawing; the edge still runs from "from" to "to".')
633
645
  })
634
646
  }),
635
647
  z.object({
636
648
  op: z.literal("updateEdge"),
637
649
  id: z.string(),
638
- patch: z.object({ label: z.string().optional(), dashed: z.boolean().optional(), optional: z.boolean().optional(), color: colorPatch })
650
+ patch: z.object({
651
+ label: z.string().optional(),
652
+ dashed: z.boolean().optional(),
653
+ optional: z.boolean().optional(),
654
+ color: colorPatch,
655
+ width: edgeWidthSchema.nullable().optional().describe('"thin" or "thick"; null returns to the usual thickness.'),
656
+ arrow: edgeArrowSchema.nullable().optional().describe('"end", "start", "both" or "none"; null returns to the default (end).')
657
+ })
639
658
  }),
640
659
  z.object({ op: z.literal("deleteEdge"), id: z.string() }),
641
660
  z.object({
@@ -654,6 +673,7 @@ var diagramOpSchema = z.discriminatedUnion("op", [
654
673
 
655
674
  // packages/diagram-core/src/controller.ts
656
675
  import { createStore } from "zustand/vanilla";
676
+ var REMOTE_SOURCE = "remote";
657
677
  function collection(set) {
658
678
  return {
659
679
  replace: (items) => set({ byId: Object.fromEntries(items.map((i) => [i.id, i])), ids: items.map((i) => i.id) })
@@ -748,6 +768,7 @@ function createDiagramController(initial) {
748
768
  const changeListeners = /* @__PURE__ */ new Set();
749
769
  const loadListeners = /* @__PURE__ */ new Set();
750
770
  let snapshot = null;
771
+ let readOnly = null;
751
772
  let depth = 0;
752
773
  let dirty = false;
753
774
  const notify = () => {
@@ -824,7 +845,14 @@ function createDiagramController(initial) {
824
845
  listeners.add(listener);
825
846
  return () => void listeners.delete(listener);
826
847
  },
848
+ get readOnly() {
849
+ return readOnly;
850
+ },
851
+ setReadOnly(message) {
852
+ readOnly = message;
853
+ },
827
854
  apply(request) {
855
+ if (readOnly && request.source !== REMOTE_SOURCE) return { ok: false, error: "invalid", message: readOnly, currentRevision: stores.meta.getState().revision };
828
856
  const meta = stores.meta.getState();
829
857
  if (request.expectedRevision !== void 0 && request.expectedRevision !== meta.revision) {
830
858
  return {
@@ -837,6 +865,7 @@ function createDiagramController(initial) {
837
865
  return run(planChanges(getSnapshot(), request.ops), request, request.ops.length);
838
866
  },
839
867
  applyPatch(patch, meta) {
868
+ if (readOnly && meta.source !== REMOTE_SOURCE) return { ok: false, error: "invalid", message: readOnly, currentRevision: stores.meta.getState().revision };
840
869
  const before = getSnapshot();
841
870
  const next = applyPatch(before, patch);
842
871
  return run({ ok: true, next, patch, inverse: diffSnapshots(next, before), applied: 1 }, meta, 1);
@@ -1171,7 +1200,7 @@ function workspaceLinkIssues(nodes, known) {
1171
1200
  const ids = known.map((repo) => repo.id).join(", ");
1172
1201
  for (const node2 of nodes) for (const link of node2.links ?? []) {
1173
1202
  if (!known.length) {
1174
- issues.add("links: this project lists no repos in .glyph/workspace.json, so a link has nowhere to resolve");
1203
+ issues.add("links: this project lists no repos in .cakeslice/workspace.json, so a link has nowhere to resolve");
1175
1204
  continue;
1176
1205
  }
1177
1206
  if (!link.repo && known.length > 1) {
@@ -1226,6 +1255,7 @@ export {
1226
1255
  MigrationError,
1227
1256
  NODE_HIGHLIGHTS,
1228
1257
  NotADocumentError,
1258
+ REMOTE_SOURCE,
1229
1259
  RepositoryConflictError,
1230
1260
  UnsupportedVersionError,
1231
1261
  ValidationError,
@@ -1250,11 +1280,15 @@ export {
1250
1280
  diagramV3Schema,
1251
1281
  diagramV4Schema,
1252
1282
  diagramV5Schema,
1283
+ diagramV6Schema,
1253
1284
  diffSnapshots,
1254
1285
  dragRect,
1286
+ edgeArrowSchema,
1255
1287
  edgeGeometry,
1256
1288
  edgeSchema,
1257
1289
  edgeV1Schema,
1290
+ edgeV6Schema,
1291
+ edgeWidthSchema,
1258
1292
  findNodeRef,
1259
1293
  groupSchema,
1260
1294
  groupV1Schema,