konpeki 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/.agents/skills/authoring-visuals/SKILL.md +82 -0
  2. package/AGENTS.md +33 -0
  3. package/AUTHORING.md +233 -0
  4. package/LICENSE +201 -0
  5. package/README.md +70 -0
  6. package/SETUP.md +86 -0
  7. package/composition/README.md +166 -0
  8. package/composition/compile.ts +227 -0
  9. package/composition/document.ts +709 -0
  10. package/composition/schema.json +2992 -0
  11. package/composition/schema.ts +435 -0
  12. package/composition/theme-tokens.ts +16 -0
  13. package/composition/types.ts +286 -0
  14. package/composition/validate.ts +684 -0
  15. package/composition/vector.ts +143 -0
  16. package/composition/visualizations.ts +335 -0
  17. package/design/README.md +17 -0
  18. package/design/palettes/README.md +14 -0
  19. package/design/palettes/base.ts +14 -0
  20. package/design/palettes/candidates.ts +19 -0
  21. package/design/palettes/index.ts +78 -0
  22. package/design/review/color-theme.md +44 -0
  23. package/design/review/layout.md +16 -0
  24. package/design/review/text.md +18 -0
  25. package/design/review/typography.md +15 -0
  26. package/design/review/visuals.md +31 -0
  27. package/design/semantic-patterns.md +43 -0
  28. package/design/themes/README.md +22 -0
  29. package/design/themes/index.ts +13 -0
  30. package/design/visual-languages/technical-product.md +17 -0
  31. package/design/visual-review.md +88 -0
  32. package/docs/development.md +140 -0
  33. package/docs/workflow.md +61 -0
  34. package/index.html +17 -0
  35. package/lib/assets.d.ts +8 -0
  36. package/lib/charts.ts +18 -0
  37. package/lib/contrast.ts +16 -0
  38. package/lib/layouts.ts +50 -0
  39. package/lib/slide.tsx +42 -0
  40. package/lib/taste.ts +17 -0
  41. package/lib/text.tsx +89 -0
  42. package/lib/typeface.ts +44 -0
  43. package/package.json +85 -0
  44. package/runtime/konpeki.mjs +1685 -0
  45. package/scripts/migrate-react-page.ts +120 -0
  46. package/slides/README.md +153 -0
  47. package/slides/architecture/PROMPT.md +31 -0
  48. package/slides/architecture/index.tsx +102 -0
  49. package/slides/article-brief/PROMPT.md +35 -0
  50. package/slides/article-brief/index.tsx +71 -0
  51. package/slides/bar-chart/PROMPT.md +39 -0
  52. package/slides/bar-chart/index.tsx +97 -0
  53. package/slides/comparison/PROMPT.md +29 -0
  54. package/slides/comparison/index.tsx +95 -0
  55. package/slides/decision-memo/PROMPT.md +34 -0
  56. package/slides/decision-memo/index.tsx +85 -0
  57. package/slides/delivery-plan/PROMPT.md +45 -0
  58. package/slides/delivery-plan/index.tsx +105 -0
  59. package/slides/experiment/PROMPT.md +44 -0
  60. package/slides/experiment/index.tsx +127 -0
  61. package/slides/incident-workflow/PROMPT.md +57 -0
  62. package/slides/incident-workflow/index.tsx +78 -0
  63. package/slides/introducing-konpeki/PROMPT.md +19 -0
  64. package/slides/introducing-konpeki/README.md +54 -0
  65. package/slides/introducing-konpeki/SOURCE.md +20 -0
  66. package/slides/introducing-konpeki/author.ts +163 -0
  67. package/slides/introducing-konpeki/composition.json +3265 -0
  68. package/slides/line-chart/PROMPT.md +40 -0
  69. package/slides/line-chart/index.tsx +72 -0
  70. package/slides/migration/PROMPT.md +38 -0
  71. package/slides/migration/index.tsx +89 -0
  72. package/slides/og-images/PROMPT.md +21 -0
  73. package/slides/og-images/index.tsx +76 -0
  74. package/slides/product-introduction/PROMPT.md +24 -0
  75. package/slides/product-introduction/index.tsx +105 -0
  76. package/slides/research-brief/PROMPT.md +40 -0
  77. package/slides/research-brief/index.tsx +104 -0
  78. package/slides/results-explanation/PROMPT.md +32 -0
  79. package/slides/results-explanation/index.tsx +96 -0
  80. package/slides/retrospective/PROMPT.md +43 -0
  81. package/slides/retrospective/index.tsx +105 -0
  82. package/slides/sankey/PROMPT.md +11 -0
  83. package/slides/sankey/index.tsx +93 -0
  84. package/slides/teaching/PROMPT.md +45 -0
  85. package/slides/teaching/index.tsx +124 -0
  86. package/slides/vertical-bar-charts/PROMPT.md +13 -0
  87. package/slides/vertical-bar-charts/index.tsx +97 -0
  88. package/src/app/App.tsx +694 -0
  89. package/src/assets/konpeki-mark.png +0 -0
  90. package/src/components/Canvas.tsx +1168 -0
  91. package/src/components/DiagramTypeIcon.tsx +78 -0
  92. package/src/components/InspectorPanel.tsx +687 -0
  93. package/src/components/LeftPanel.tsx +107 -0
  94. package/src/components/PageSizePicker.tsx +30 -0
  95. package/src/components/Presentation.tsx +105 -0
  96. package/src/components/RightPanel.tsx +201 -0
  97. package/src/components/VectorOverflowWarning.tsx +46 -0
  98. package/src/components/WorkspaceChrome.tsx +199 -0
  99. package/src/components/ui.tsx +53 -0
  100. package/src/lib/examples/react-page-migration.json +1295 -0
  101. package/src/lib/examples.ts +42 -0
  102. package/src/lib/export-png.ts +101 -0
  103. package/src/lib/file-session.ts +74 -0
  104. package/src/lib/history.ts +53 -0
  105. package/src/lib/model.ts +188 -0
  106. package/src/lib/page-size.ts +24 -0
  107. package/src/lib/presentation.ts +17 -0
  108. package/src/lib/storage.ts +43 -0
  109. package/src/lib/theme.ts +25 -0
  110. package/src/lib/use-file-session.ts +162 -0
  111. package/src/main.tsx +26 -0
  112. package/src/styles/base.css +105 -0
  113. package/src/styles/canvas.css +268 -0
  114. package/src/styles/chrome.css +214 -0
  115. package/src/styles/component-previews.css +386 -0
  116. package/src/styles/feedback.css +71 -0
  117. package/src/styles/left-panel.css +125 -0
  118. package/src/styles/presentation.css +72 -0
  119. package/src/styles/right-panel.css +1172 -0
  120. package/src/styles/shell.css +247 -0
  121. package/vite.config.ts +6 -0
@@ -0,0 +1,1295 @@
1
+ {
2
+ "schema": "konpeki-composition/v14",
3
+ "title": "Parcel Relay — migrated React deck",
4
+ "theme": {
5
+ "id": "plex",
6
+ "mode": "paper"
7
+ },
8
+ "slides": [
9
+ {
10
+ "id": "slide-1",
11
+ "name": "Migrated page 1",
12
+ "canvas": {
13
+ "width": 1920,
14
+ "height": 1080
15
+ },
16
+ "innerPadding": {
17
+ "top": 72,
18
+ "right": 112,
19
+ "bottom": 0,
20
+ "left": 112
21
+ },
22
+ "pageNumber": {
23
+ "style": "none",
24
+ "color": "muted"
25
+ },
26
+ "audience": "Reviewers of the migrated slide",
27
+ "question": "Does the former React page survive in the shared canvas?",
28
+ "intendedViewingSize": "presentation",
29
+ "contentSlots": [
30
+ {
31
+ "id": "migrated-page-1-content",
32
+ "label": "Migrated page",
33
+ "required": true,
34
+ "instruction": "Preserve the trusted React page as editable vector elements.",
35
+ "role": "entity"
36
+ }
37
+ ],
38
+ "components": [
39
+ {
40
+ "id": "migrated-page-1",
41
+ "kind": "diagram",
42
+ "preferredRect": {
43
+ "x": 0,
44
+ "y": 0,
45
+ "width": 1920,
46
+ "height": 1080
47
+ },
48
+ "slotIds": [
49
+ "migrated-page-1-content"
50
+ ],
51
+ "intent": "A former React page converted to editable vector elements.",
52
+ "appearance": {
53
+ "type": "architecture",
54
+ "border": "none"
55
+ },
56
+ "customVisual": {
57
+ "format": "vector",
58
+ "elements": [
59
+ {
60
+ "id": "vector-root",
61
+ "kind": "g",
62
+ "attributes": {
63
+ "width": "1920",
64
+ "height": "1080",
65
+ "font-family": "IBM Plex Sans, sans-serif"
66
+ }
67
+ },
68
+ {
69
+ "id": "vector-2",
70
+ "kind": "rect",
71
+ "parentId": "vector-root",
72
+ "attributes": {
73
+ "width": "1920",
74
+ "height": "1080",
75
+ "fill": "#FFFFFF"
76
+ }
77
+ },
78
+ {
79
+ "id": "vector-3",
80
+ "kind": "text",
81
+ "parentId": "vector-root",
82
+ "attributes": {
83
+ "x": "112",
84
+ "y": "150",
85
+ "font-size": "64",
86
+ "font-weight": "600",
87
+ "fill": "#172633"
88
+ },
89
+ "text": "Parcel Relay accepts an event after commit"
90
+ },
91
+ {
92
+ "id": "vector-4",
93
+ "kind": "text",
94
+ "parentId": "vector-root",
95
+ "attributes": {
96
+ "x": "112",
97
+ "y": "224",
98
+ "font-size": "34",
99
+ "font-weight": "400",
100
+ "fill": "#4D5D6B"
101
+ },
102
+ "text": "A fictional webhook service • the database holds both events and the job queue"
103
+ },
104
+ {
105
+ "id": "vector-5",
106
+ "kind": "text",
107
+ "parentId": "vector-root",
108
+ "attributes": {
109
+ "x": "160",
110
+ "y": "365",
111
+ "font-size": "40",
112
+ "font-weight": "600",
113
+ "fill": "#172633"
114
+ },
115
+ "text": "Producer"
116
+ },
117
+ {
118
+ "id": "vector-6",
119
+ "kind": "text",
120
+ "parentId": "vector-root",
121
+ "attributes": {
122
+ "x": "548",
123
+ "y": "365",
124
+ "font-size": "40",
125
+ "font-weight": "600",
126
+ "fill": "#172633"
127
+ },
128
+ "text": "API"
129
+ },
130
+ {
131
+ "id": "vector-7",
132
+ "kind": "path",
133
+ "parentId": "vector-root",
134
+ "attributes": {
135
+ "d": "M250 390 V635 M580 390 V635",
136
+ "fill": "none",
137
+ "stroke": "#A7B2BC",
138
+ "stroke-width": "2"
139
+ }
140
+ },
141
+ {
142
+ "id": "vector-8",
143
+ "kind": "rect",
144
+ "parentId": "vector-root",
145
+ "attributes": {
146
+ "x": "965",
147
+ "y": "294",
148
+ "width": "835",
149
+ "height": "280",
150
+ "rx": "8",
151
+ "fill": "#FFFFFF",
152
+ "stroke": "#A7B2BC",
153
+ "stroke-width": "2"
154
+ }
155
+ },
156
+ {
157
+ "id": "vector-9",
158
+ "kind": "text",
159
+ "parentId": "vector-root",
160
+ "attributes": {
161
+ "x": "1005",
162
+ "y": "355",
163
+ "font-size": "40",
164
+ "font-weight": "600",
165
+ "fill": "#172633"
166
+ },
167
+ "text": "Database"
168
+ },
169
+ {
170
+ "id": "vector-10",
171
+ "kind": "text",
172
+ "parentId": "vector-root",
173
+ "attributes": {
174
+ "x": "1005",
175
+ "y": "423",
176
+ "font-size": "34",
177
+ "font-weight": "400",
178
+ "fill": "#172633"
179
+ },
180
+ "text": "Event + delivery job"
181
+ },
182
+ {
183
+ "id": "vector-11",
184
+ "kind": "text",
185
+ "parentId": "vector-root",
186
+ "attributes": {
187
+ "x": "1005",
188
+ "y": "479",
189
+ "font-size": "34",
190
+ "font-weight": "500",
191
+ "fill": "#006EAC"
192
+ },
193
+ "text": "Saved in one transaction"
194
+ },
195
+ {
196
+ "id": "vector-12",
197
+ "kind": "text",
198
+ "parentId": "vector-root",
199
+ "attributes": {
200
+ "x": "1005",
201
+ "y": "531",
202
+ "font-size": "30",
203
+ "font-weight": "400",
204
+ "fill": "#4D5D6B"
205
+ },
206
+ "text": "Commit is the acceptance boundary."
207
+ },
208
+ {
209
+ "id": "vector-13",
210
+ "kind": "g",
211
+ "parentId": "vector-root",
212
+ "attributes": {
213
+ "fill": "none",
214
+ "stroke": "#006EAC",
215
+ "stroke-width": "3"
216
+ }
217
+ },
218
+ {
219
+ "id": "vector-14",
220
+ "kind": "path",
221
+ "parentId": "vector-13",
222
+ "attributes": {
223
+ "d": "M250 415 H580"
224
+ }
225
+ },
226
+ {
227
+ "id": "vector-15",
228
+ "kind": "path",
229
+ "parentId": "vector-13",
230
+ "attributes": {
231
+ "d": "M564 405 L580 415 L564 425"
232
+ }
233
+ },
234
+ {
235
+ "id": "vector-16",
236
+ "kind": "text",
237
+ "parentId": "vector-root",
238
+ "attributes": {
239
+ "x": "280",
240
+ "y": "397",
241
+ "font-size": "30",
242
+ "font-weight": "400",
243
+ "fill": "#172633"
244
+ },
245
+ "text": "Submit event ID"
246
+ },
247
+ {
248
+ "id": "vector-17",
249
+ "kind": "g",
250
+ "parentId": "vector-root",
251
+ "attributes": {
252
+ "fill": "none",
253
+ "stroke": "#006EAC",
254
+ "stroke-width": "3"
255
+ }
256
+ },
257
+ {
258
+ "id": "vector-18",
259
+ "kind": "path",
260
+ "parentId": "vector-17",
261
+ "attributes": {
262
+ "d": "M580 415 H965"
263
+ }
264
+ },
265
+ {
266
+ "id": "vector-19",
267
+ "kind": "path",
268
+ "parentId": "vector-17",
269
+ "attributes": {
270
+ "d": "M949 405 L965 415 L949 425"
271
+ }
272
+ },
273
+ {
274
+ "id": "vector-20",
275
+ "kind": "text",
276
+ "parentId": "vector-root",
277
+ "attributes": {
278
+ "x": "690",
279
+ "y": "391",
280
+ "font-size": "30",
281
+ "font-weight": "400",
282
+ "fill": "#172633"
283
+ },
284
+ "text": "Save both"
285
+ },
286
+ {
287
+ "id": "vector-21",
288
+ "kind": "g",
289
+ "parentId": "vector-root",
290
+ "attributes": {
291
+ "fill": "none",
292
+ "stroke": "#006EAC",
293
+ "stroke-width": "3"
294
+ }
295
+ },
296
+ {
297
+ "id": "vector-22",
298
+ "kind": "path",
299
+ "parentId": "vector-21",
300
+ "attributes": {
301
+ "d": "M965 515 H580"
302
+ }
303
+ },
304
+ {
305
+ "id": "vector-23",
306
+ "kind": "path",
307
+ "parentId": "vector-21",
308
+ "attributes": {
309
+ "d": "M596 505 L580 515 L596 525"
310
+ }
311
+ },
312
+ {
313
+ "id": "vector-24",
314
+ "kind": "text",
315
+ "parentId": "vector-root",
316
+ "attributes": {
317
+ "x": "680",
318
+ "y": "563",
319
+ "font-size": "30",
320
+ "font-weight": "400",
321
+ "fill": "#172633"
322
+ },
323
+ "text": "Commit succeeds"
324
+ },
325
+ {
326
+ "id": "vector-25",
327
+ "kind": "g",
328
+ "parentId": "vector-root",
329
+ "attributes": {
330
+ "fill": "none",
331
+ "stroke": "#006EAC",
332
+ "stroke-width": "3"
333
+ }
334
+ },
335
+ {
336
+ "id": "vector-26",
337
+ "kind": "path",
338
+ "parentId": "vector-25",
339
+ "attributes": {
340
+ "d": "M580 610 H250"
341
+ }
342
+ },
343
+ {
344
+ "id": "vector-27",
345
+ "kind": "path",
346
+ "parentId": "vector-25",
347
+ "attributes": {
348
+ "d": "M266 600 L250 610 L266 620"
349
+ }
350
+ },
351
+ {
352
+ "id": "vector-28",
353
+ "kind": "text",
354
+ "parentId": "vector-root",
355
+ "attributes": {
356
+ "x": "236",
357
+ "y": "660",
358
+ "font-size": "34",
359
+ "font-weight": "500",
360
+ "fill": "#006EAC"
361
+ },
362
+ "text": "Return Accepted"
363
+ },
364
+ {
365
+ "id": "vector-29",
366
+ "kind": "path",
367
+ "parentId": "vector-root",
368
+ "attributes": {
369
+ "d": "M1120 704 V574 M1110 590 L1120 574 L1130 590",
370
+ "fill": "none",
371
+ "stroke": "#006EAC",
372
+ "stroke-width": "3"
373
+ }
374
+ },
375
+ {
376
+ "id": "vector-30",
377
+ "kind": "text",
378
+ "parentId": "vector-root",
379
+ "attributes": {
380
+ "x": "1160",
381
+ "y": "644",
382
+ "font-size": "30",
383
+ "font-weight": "400",
384
+ "fill": "#172633"
385
+ },
386
+ "text": "Claim leased job"
387
+ },
388
+ {
389
+ "id": "vector-31",
390
+ "kind": "text",
391
+ "parentId": "vector-root",
392
+ "attributes": {
393
+ "x": "112",
394
+ "y": "797",
395
+ "font-size": "40",
396
+ "font-weight": "600",
397
+ "fill": "#172633"
398
+ },
399
+ "text": "If commit fails"
400
+ },
401
+ {
402
+ "id": "vector-32",
403
+ "kind": "text",
404
+ "parentId": "vector-root",
405
+ "attributes": {
406
+ "x": "112",
407
+ "y": "855",
408
+ "font-size": "34",
409
+ "font-weight": "400",
410
+ "fill": "#172633"
411
+ },
412
+ "text": "API returns an error."
413
+ },
414
+ {
415
+ "id": "vector-33",
416
+ "kind": "text",
417
+ "parentId": "vector-root",
418
+ "attributes": {
419
+ "x": "112",
420
+ "y": "907",
421
+ "font-size": "34",
422
+ "font-weight": "400",
423
+ "fill": "#172633"
424
+ },
425
+ "text": "The event has not been accepted."
426
+ },
427
+ {
428
+ "id": "vector-34",
429
+ "kind": "text",
430
+ "parentId": "vector-root",
431
+ "attributes": {
432
+ "x": "1020",
433
+ "y": "738",
434
+ "font-size": "40",
435
+ "font-weight": "600",
436
+ "fill": "#172633"
437
+ },
438
+ "text": "Worker"
439
+ },
440
+ {
441
+ "id": "vector-35",
442
+ "kind": "path",
443
+ "parentId": "vector-root",
444
+ "attributes": {
445
+ "d": "M1120 756 V844",
446
+ "fill": "none",
447
+ "stroke": "#006EAC",
448
+ "stroke-width": "3"
449
+ }
450
+ },
451
+ {
452
+ "id": "vector-36",
453
+ "kind": "g",
454
+ "parentId": "vector-root",
455
+ "attributes": {
456
+ "fill": "none",
457
+ "stroke": "#006EAC",
458
+ "stroke-width": "3"
459
+ }
460
+ },
461
+ {
462
+ "id": "vector-37",
463
+ "kind": "path",
464
+ "parentId": "vector-36",
465
+ "attributes": {
466
+ "d": "M1120 844 H1550"
467
+ }
468
+ },
469
+ {
470
+ "id": "vector-38",
471
+ "kind": "path",
472
+ "parentId": "vector-36",
473
+ "attributes": {
474
+ "d": "M1534 834 L1550 844 L1534 854"
475
+ }
476
+ },
477
+ {
478
+ "id": "vector-39",
479
+ "kind": "text",
480
+ "parentId": "vector-root",
481
+ "attributes": {
482
+ "x": "1160",
483
+ "y": "891",
484
+ "font-size": "30",
485
+ "font-weight": "400",
486
+ "fill": "#172633"
487
+ },
488
+ "text": "POST + event ID"
489
+ },
490
+ {
491
+ "id": "vector-40",
492
+ "kind": "text",
493
+ "parentId": "vector-root",
494
+ "attributes": {
495
+ "x": "1555",
496
+ "y": "817",
497
+ "font-size": "38",
498
+ "font-weight": "600",
499
+ "fill": "#172633"
500
+ },
501
+ "text": "Customer"
502
+ },
503
+ {
504
+ "id": "vector-41",
505
+ "kind": "text",
506
+ "parentId": "vector-root",
507
+ "attributes": {
508
+ "x": "1555",
509
+ "y": "869",
510
+ "font-size": "30",
511
+ "font-weight": "400",
512
+ "fill": "#172633"
513
+ },
514
+ "text": "endpoint"
515
+ },
516
+ {
517
+ "id": "vector-42",
518
+ "kind": "text",
519
+ "parentId": "vector-root",
520
+ "attributes": {
521
+ "x": "1760",
522
+ "y": "1018",
523
+ "font-size": "26",
524
+ "font-weight": "400",
525
+ "fill": "#4D5D6B"
526
+ },
527
+ "text": "1 / 3"
528
+ }
529
+ ],
530
+ "viewBox": {
531
+ "x": 0,
532
+ "y": 0,
533
+ "width": 1920,
534
+ "height": 1080
535
+ },
536
+ "description": "Migrated page 1 from Parcel Relay",
537
+ "fit": "stretch"
538
+ }
539
+ }
540
+ ],
541
+ "groups": [],
542
+ "readingOrder": [
543
+ {
544
+ "kind": "component",
545
+ "id": "migrated-page-1"
546
+ }
547
+ ],
548
+ "paintOrder": [
549
+ "migrated-page-1"
550
+ ],
551
+ "relationships": []
552
+ },
553
+ {
554
+ "id": "slide-2",
555
+ "name": "Migrated page 2",
556
+ "canvas": {
557
+ "width": 1920,
558
+ "height": 1080
559
+ },
560
+ "innerPadding": {
561
+ "top": 72,
562
+ "right": 112,
563
+ "bottom": 0,
564
+ "left": 112
565
+ },
566
+ "pageNumber": {
567
+ "style": "none",
568
+ "color": "muted"
569
+ },
570
+ "audience": "Reviewers of the migrated slide",
571
+ "question": "Does the former React page survive in the shared canvas?",
572
+ "intendedViewingSize": "presentation",
573
+ "contentSlots": [
574
+ {
575
+ "id": "migrated-page-2-content",
576
+ "label": "Migrated page",
577
+ "required": true,
578
+ "instruction": "Preserve the trusted React page as editable vector elements.",
579
+ "role": "entity"
580
+ }
581
+ ],
582
+ "components": [
583
+ {
584
+ "id": "migrated-page-2",
585
+ "kind": "diagram",
586
+ "preferredRect": {
587
+ "x": 0,
588
+ "y": 0,
589
+ "width": 1920,
590
+ "height": 1080
591
+ },
592
+ "slotIds": [
593
+ "migrated-page-2-content"
594
+ ],
595
+ "intent": "A former React page converted to editable vector elements.",
596
+ "appearance": {
597
+ "type": "architecture",
598
+ "border": "none"
599
+ },
600
+ "customVisual": {
601
+ "format": "vector",
602
+ "elements": [
603
+ {
604
+ "id": "vector-root",
605
+ "kind": "g",
606
+ "attributes": {
607
+ "width": "1920",
608
+ "height": "1080",
609
+ "font-family": "IBM Plex Sans, sans-serif"
610
+ }
611
+ },
612
+ {
613
+ "id": "vector-2",
614
+ "kind": "rect",
615
+ "parentId": "vector-root",
616
+ "attributes": {
617
+ "width": "1920",
618
+ "height": "1080",
619
+ "fill": "#FFFFFF"
620
+ }
621
+ },
622
+ {
623
+ "id": "vector-3",
624
+ "kind": "text",
625
+ "parentId": "vector-root",
626
+ "attributes": {
627
+ "x": "112",
628
+ "y": "150",
629
+ "font-size": "64",
630
+ "font-weight": "600",
631
+ "fill": "#172633"
632
+ },
633
+ "text": "The response decides the job’s next state"
634
+ },
635
+ {
636
+ "id": "vector-4",
637
+ "kind": "text",
638
+ "parentId": "vector-root",
639
+ "attributes": {
640
+ "x": "112",
641
+ "y": "228",
642
+ "font-size": "34",
643
+ "font-weight": "400",
644
+ "fill": "#4D5D6B"
645
+ },
646
+ "text": "After each POST, the worker records the outcome in the database."
647
+ },
648
+ {
649
+ "id": "vector-5",
650
+ "kind": "text",
651
+ "parentId": "vector-root",
652
+ "attributes": {
653
+ "x": "112",
654
+ "y": "346",
655
+ "font-size": "30",
656
+ "font-weight": "400",
657
+ "fill": "#4D5D6B"
658
+ },
659
+ "text": "OBSERVED RESULT"
660
+ },
661
+ {
662
+ "id": "vector-6",
663
+ "kind": "text",
664
+ "parentId": "vector-root",
665
+ "attributes": {
666
+ "x": "660",
667
+ "y": "346",
668
+ "font-size": "30",
669
+ "font-weight": "400",
670
+ "fill": "#4D5D6B"
671
+ },
672
+ "text": "WHAT RELAY DOES"
673
+ },
674
+ {
675
+ "id": "vector-7",
676
+ "kind": "line",
677
+ "parentId": "vector-root",
678
+ "attributes": {
679
+ "x1": "112",
680
+ "x2": "1808",
681
+ "y1": "380",
682
+ "y2": "380",
683
+ "stroke": "#A7B2BC",
684
+ "stroke-width": "2"
685
+ }
686
+ },
687
+ {
688
+ "id": "vector-8",
689
+ "kind": "line",
690
+ "parentId": "vector-root",
691
+ "attributes": {
692
+ "x1": "112",
693
+ "x2": "1808",
694
+ "y1": "490",
695
+ "y2": "490",
696
+ "stroke": "#A7B2BC",
697
+ "stroke-width": "2"
698
+ }
699
+ },
700
+ {
701
+ "id": "vector-9",
702
+ "kind": "line",
703
+ "parentId": "vector-root",
704
+ "attributes": {
705
+ "x1": "112",
706
+ "x2": "1808",
707
+ "y1": "660",
708
+ "y2": "660",
709
+ "stroke": "#A7B2BC",
710
+ "stroke-width": "2"
711
+ }
712
+ },
713
+ {
714
+ "id": "vector-10",
715
+ "kind": "line",
716
+ "parentId": "vector-root",
717
+ "attributes": {
718
+ "x1": "112",
719
+ "x2": "1808",
720
+ "y1": "780",
721
+ "y2": "780",
722
+ "stroke": "#A7B2BC",
723
+ "stroke-width": "2"
724
+ }
725
+ },
726
+ {
727
+ "id": "vector-11",
728
+ "kind": "text",
729
+ "parentId": "vector-root",
730
+ "attributes": {
731
+ "x": "112",
732
+ "y": "447",
733
+ "font-size": "40",
734
+ "font-weight": "600",
735
+ "fill": "#172633"
736
+ },
737
+ "text": "2xx"
738
+ },
739
+ {
740
+ "id": "vector-12",
741
+ "kind": "text",
742
+ "parentId": "vector-root",
743
+ "attributes": {
744
+ "x": "660",
745
+ "y": "447",
746
+ "font-size": "38",
747
+ "font-weight": "400",
748
+ "fill": "#172633"
749
+ },
750
+ "text": "Marks the job delivered."
751
+ },
752
+ {
753
+ "id": "vector-13",
754
+ "kind": "text",
755
+ "parentId": "vector-root",
756
+ "attributes": {
757
+ "x": "112",
758
+ "y": "555",
759
+ "font-size": "40",
760
+ "font-weight": "600",
761
+ "fill": "#172633"
762
+ },
763
+ "text": "Timeout or 5xx"
764
+ },
765
+ {
766
+ "id": "vector-14",
767
+ "kind": "text",
768
+ "parentId": "vector-root",
769
+ "attributes": {
770
+ "x": "660",
771
+ "y": "552",
772
+ "font-size": "38",
773
+ "font-weight": "400",
774
+ "fill": "#172633"
775
+ },
776
+ "text": "Schedules another attempt; three attempts total."
777
+ },
778
+ {
779
+ "id": "vector-15",
780
+ "kind": "text",
781
+ "parentId": "vector-root",
782
+ "attributes": {
783
+ "x": "660",
784
+ "y": "609",
785
+ "font-size": "32",
786
+ "font-weight": "400",
787
+ "fill": "#4D5D6B"
788
+ },
789
+ "text": "Third unsuccessful attempt: failed, for human investigation."
790
+ },
791
+ {
792
+ "id": "vector-16",
793
+ "kind": "text",
794
+ "parentId": "vector-root",
795
+ "attributes": {
796
+ "x": "112",
797
+ "y": "731",
798
+ "font-size": "40",
799
+ "font-weight": "600",
800
+ "fill": "#172633"
801
+ },
802
+ "text": "4xx"
803
+ },
804
+ {
805
+ "id": "vector-17",
806
+ "kind": "text",
807
+ "parentId": "vector-root",
808
+ "attributes": {
809
+ "x": "660",
810
+ "y": "731",
811
+ "font-size": "38",
812
+ "font-weight": "400",
813
+ "fill": "#172633"
814
+ },
815
+ "text": "Terminal in this example."
816
+ },
817
+ {
818
+ "id": "vector-18",
819
+ "kind": "text",
820
+ "parentId": "vector-root",
821
+ "attributes": {
822
+ "x": "112",
823
+ "y": "865",
824
+ "font-size": "38",
825
+ "font-weight": "600",
826
+ "fill": "#172633"
827
+ },
828
+ "text": "A worker crash can also repeat a request"
829
+ },
830
+ {
831
+ "id": "vector-19",
832
+ "kind": "text",
833
+ "parentId": "vector-root",
834
+ "attributes": {
835
+ "x": "112",
836
+ "y": "925",
837
+ "font-size": "34",
838
+ "font-weight": "400",
839
+ "fill": "#172633"
840
+ },
841
+ "text": "After lease expiry, another worker can claim the unfinished job,"
842
+ },
843
+ {
844
+ "id": "vector-20",
845
+ "kind": "text",
846
+ "parentId": "vector-root",
847
+ "attributes": {
848
+ "x": "112",
849
+ "y": "975",
850
+ "font-size": "34",
851
+ "font-weight": "400",
852
+ "fill": "#172633"
853
+ },
854
+ "text": "even if the customer already received the earlier request."
855
+ },
856
+ {
857
+ "id": "vector-21",
858
+ "kind": "text",
859
+ "parentId": "vector-root",
860
+ "attributes": {
861
+ "x": "1760",
862
+ "y": "1018",
863
+ "font-size": "26",
864
+ "font-weight": "400",
865
+ "fill": "#4D5D6B"
866
+ },
867
+ "text": "2 / 3"
868
+ }
869
+ ],
870
+ "viewBox": {
871
+ "x": 0,
872
+ "y": 0,
873
+ "width": 1920,
874
+ "height": 1080
875
+ },
876
+ "description": "Migrated page 2 from Parcel Relay",
877
+ "fit": "stretch"
878
+ }
879
+ }
880
+ ],
881
+ "groups": [],
882
+ "readingOrder": [
883
+ {
884
+ "kind": "component",
885
+ "id": "migrated-page-2"
886
+ }
887
+ ],
888
+ "paintOrder": [
889
+ "migrated-page-2"
890
+ ],
891
+ "relationships": []
892
+ },
893
+ {
894
+ "id": "slide-3",
895
+ "name": "Migrated page 3",
896
+ "canvas": {
897
+ "width": 1920,
898
+ "height": 1080
899
+ },
900
+ "innerPadding": {
901
+ "top": 72,
902
+ "right": 112,
903
+ "bottom": 0,
904
+ "left": 112
905
+ },
906
+ "pageNumber": {
907
+ "style": "none",
908
+ "color": "muted"
909
+ },
910
+ "audience": "Reviewers of the migrated slide",
911
+ "question": "Does the former React page survive in the shared canvas?",
912
+ "intendedViewingSize": "presentation",
913
+ "contentSlots": [
914
+ {
915
+ "id": "migrated-page-3-content",
916
+ "label": "Migrated page",
917
+ "required": true,
918
+ "instruction": "Preserve the trusted React page as editable vector elements.",
919
+ "role": "entity"
920
+ }
921
+ ],
922
+ "components": [
923
+ {
924
+ "id": "migrated-page-3",
925
+ "kind": "diagram",
926
+ "preferredRect": {
927
+ "x": 0,
928
+ "y": 0,
929
+ "width": 1920,
930
+ "height": 1080
931
+ },
932
+ "slotIds": [
933
+ "migrated-page-3-content"
934
+ ],
935
+ "intent": "A former React page converted to editable vector elements.",
936
+ "appearance": {
937
+ "type": "architecture",
938
+ "border": "none"
939
+ },
940
+ "customVisual": {
941
+ "format": "vector",
942
+ "elements": [
943
+ {
944
+ "id": "vector-root",
945
+ "kind": "g",
946
+ "attributes": {
947
+ "width": "1920",
948
+ "height": "1080",
949
+ "font-family": "IBM Plex Sans, sans-serif"
950
+ }
951
+ },
952
+ {
953
+ "id": "vector-2",
954
+ "kind": "rect",
955
+ "parentId": "vector-root",
956
+ "attributes": {
957
+ "width": "1920",
958
+ "height": "1080",
959
+ "fill": "#FFFFFF"
960
+ }
961
+ },
962
+ {
963
+ "id": "vector-3",
964
+ "kind": "text",
965
+ "parentId": "vector-root",
966
+ "attributes": {
967
+ "x": "112",
968
+ "y": "150",
969
+ "font-size": "64",
970
+ "font-weight": "600",
971
+ "fill": "#172633"
972
+ },
973
+ "text": "A timeout can hide a completed update"
974
+ },
975
+ {
976
+ "id": "vector-4",
977
+ "kind": "text",
978
+ "parentId": "vector-root",
979
+ "attributes": {
980
+ "x": "112",
981
+ "y": "224",
982
+ "font-size": "34",
983
+ "font-weight": "400",
984
+ "fill": "#4D5D6B"
985
+ },
986
+ "text": "The same event ID connects both requests: evt-204."
987
+ },
988
+ {
989
+ "id": "vector-5",
990
+ "kind": "text",
991
+ "parentId": "vector-root",
992
+ "attributes": {
993
+ "x": "260",
994
+ "y": "334",
995
+ "font-size": "40",
996
+ "font-weight": "600",
997
+ "fill": "#172633"
998
+ },
999
+ "text": "Relay worker"
1000
+ },
1001
+ {
1002
+ "id": "vector-6",
1003
+ "kind": "text",
1004
+ "parentId": "vector-root",
1005
+ "attributes": {
1006
+ "x": "1130",
1007
+ "y": "334",
1008
+ "font-size": "40",
1009
+ "font-weight": "600",
1010
+ "fill": "#172633"
1011
+ },
1012
+ "text": "Customer endpoint"
1013
+ },
1014
+ {
1015
+ "id": "vector-7",
1016
+ "kind": "line",
1017
+ "parentId": "vector-root",
1018
+ "attributes": {
1019
+ "x1": "380",
1020
+ "x2": "380",
1021
+ "y1": "367",
1022
+ "y2": "785",
1023
+ "stroke": "#A7B2BC",
1024
+ "stroke-width": "2"
1025
+ }
1026
+ },
1027
+ {
1028
+ "id": "vector-8",
1029
+ "kind": "line",
1030
+ "parentId": "vector-root",
1031
+ "attributes": {
1032
+ "x1": "1260",
1033
+ "x2": "1260",
1034
+ "y1": "367",
1035
+ "y2": "785",
1036
+ "stroke": "#A7B2BC",
1037
+ "stroke-width": "2"
1038
+ }
1039
+ },
1040
+ {
1041
+ "id": "vector-9",
1042
+ "kind": "g",
1043
+ "parentId": "vector-root",
1044
+ "attributes": {
1045
+ "fill": "none",
1046
+ "stroke": "#006EAC",
1047
+ "stroke-width": "3"
1048
+ }
1049
+ },
1050
+ {
1051
+ "id": "vector-10",
1052
+ "kind": "path",
1053
+ "parentId": "vector-9",
1054
+ "attributes": {
1055
+ "d": "M380 432 H1260"
1056
+ }
1057
+ },
1058
+ {
1059
+ "id": "vector-11",
1060
+ "kind": "path",
1061
+ "parentId": "vector-9",
1062
+ "attributes": {
1063
+ "d": "M1244 422 L1260 432 L1244 442"
1064
+ }
1065
+ },
1066
+ {
1067
+ "id": "vector-12",
1068
+ "kind": "text",
1069
+ "parentId": "vector-root",
1070
+ "attributes": {
1071
+ "x": "610",
1072
+ "y": "406",
1073
+ "font-size": "32",
1074
+ "font-weight": "400",
1075
+ "fill": "#172633"
1076
+ },
1077
+ "text": "POST evt-204"
1078
+ },
1079
+ {
1080
+ "id": "vector-13",
1081
+ "kind": "text",
1082
+ "parentId": "vector-root",
1083
+ "attributes": {
1084
+ "x": "1310",
1085
+ "y": "445",
1086
+ "font-size": "34",
1087
+ "font-weight": "500",
1088
+ "fill": "#172633"
1089
+ },
1090
+ "text": "Applies update"
1091
+ },
1092
+ {
1093
+ "id": "vector-14",
1094
+ "kind": "path",
1095
+ "parentId": "vector-root",
1096
+ "attributes": {
1097
+ "d": "M1260 525 H760",
1098
+ "fill": "none",
1099
+ "stroke": "#006EAC",
1100
+ "stroke-width": "3",
1101
+ "stroke-dasharray": "10 8"
1102
+ }
1103
+ },
1104
+ {
1105
+ "id": "vector-15",
1106
+ "kind": "path",
1107
+ "parentId": "vector-root",
1108
+ "attributes": {
1109
+ "d": "M746 511 L774 539 M774 511 L746 539",
1110
+ "stroke": "#006EAC",
1111
+ "stroke-width": "3"
1112
+ }
1113
+ },
1114
+ {
1115
+ "id": "vector-16",
1116
+ "kind": "text",
1117
+ "parentId": "vector-root",
1118
+ "attributes": {
1119
+ "x": "835",
1120
+ "y": "504",
1121
+ "font-size": "32",
1122
+ "font-weight": "400",
1123
+ "fill": "#172633"
1124
+ },
1125
+ "text": "Response lost"
1126
+ },
1127
+ {
1128
+ "id": "vector-17",
1129
+ "kind": "text",
1130
+ "parentId": "vector-root",
1131
+ "attributes": {
1132
+ "x": "112",
1133
+ "y": "561",
1134
+ "font-size": "32",
1135
+ "font-weight": "400",
1136
+ "fill": "#172633"
1137
+ },
1138
+ "text": "Times out"
1139
+ },
1140
+ {
1141
+ "id": "vector-18",
1142
+ "kind": "text",
1143
+ "parentId": "vector-root",
1144
+ "attributes": {
1145
+ "x": "112",
1146
+ "y": "603",
1147
+ "font-size": "30",
1148
+ "font-weight": "400",
1149
+ "fill": "#4D5D6B"
1150
+ },
1151
+ "text": "Outcome unknown"
1152
+ },
1153
+ {
1154
+ "id": "vector-19",
1155
+ "kind": "g",
1156
+ "parentId": "vector-root",
1157
+ "attributes": {
1158
+ "fill": "none",
1159
+ "stroke": "#006EAC",
1160
+ "stroke-width": "3"
1161
+ }
1162
+ },
1163
+ {
1164
+ "id": "vector-20",
1165
+ "kind": "path",
1166
+ "parentId": "vector-19",
1167
+ "attributes": {
1168
+ "d": "M380 663 H1260"
1169
+ }
1170
+ },
1171
+ {
1172
+ "id": "vector-21",
1173
+ "kind": "path",
1174
+ "parentId": "vector-19",
1175
+ "attributes": {
1176
+ "d": "M1244 653 L1260 663 L1244 673"
1177
+ }
1178
+ },
1179
+ {
1180
+ "id": "vector-22",
1181
+ "kind": "text",
1182
+ "parentId": "vector-root",
1183
+ "attributes": {
1184
+ "x": "610",
1185
+ "y": "637",
1186
+ "font-size": "32",
1187
+ "font-weight": "400",
1188
+ "fill": "#172633"
1189
+ },
1190
+ "text": "Retry POST evt-204"
1191
+ },
1192
+ {
1193
+ "id": "vector-23",
1194
+ "kind": "text",
1195
+ "parentId": "vector-root",
1196
+ "attributes": {
1197
+ "x": "1310",
1198
+ "y": "672",
1199
+ "font-size": "34",
1200
+ "font-weight": "500",
1201
+ "fill": "#172633"
1202
+ },
1203
+ "text": "Recognizes evt-204"
1204
+ },
1205
+ {
1206
+ "id": "vector-24",
1207
+ "kind": "text",
1208
+ "parentId": "vector-root",
1209
+ "attributes": {
1210
+ "x": "1310",
1211
+ "y": "720",
1212
+ "font-size": "34",
1213
+ "font-weight": "500",
1214
+ "fill": "#006EAC"
1215
+ },
1216
+ "text": "Skips repeated update"
1217
+ },
1218
+ {
1219
+ "id": "vector-25",
1220
+ "kind": "text",
1221
+ "parentId": "vector-root",
1222
+ "attributes": {
1223
+ "x": "112",
1224
+ "y": "861",
1225
+ "font-size": "40",
1226
+ "font-weight": "600",
1227
+ "fill": "#172633"
1228
+ },
1229
+ "text": "Customers must handle repeated event IDs."
1230
+ },
1231
+ {
1232
+ "id": "vector-26",
1233
+ "kind": "text",
1234
+ "parentId": "vector-root",
1235
+ "attributes": {
1236
+ "x": "112",
1237
+ "y": "924",
1238
+ "font-size": "34",
1239
+ "font-weight": "400",
1240
+ "fill": "#172633"
1241
+ },
1242
+ "text": "The skip above depends on customer code; Relay does not enforce it."
1243
+ },
1244
+ {
1245
+ "id": "vector-27",
1246
+ "kind": "text",
1247
+ "parentId": "vector-root",
1248
+ "attributes": {
1249
+ "x": "112",
1250
+ "y": "974",
1251
+ "font-size": "34",
1252
+ "font-weight": "400",
1253
+ "fill": "#172633"
1254
+ },
1255
+ "text": "Relay cannot make customer side effects atomic or guarantee exactly-once delivery."
1256
+ },
1257
+ {
1258
+ "id": "vector-28",
1259
+ "kind": "text",
1260
+ "parentId": "vector-root",
1261
+ "attributes": {
1262
+ "x": "1760",
1263
+ "y": "1018",
1264
+ "font-size": "26",
1265
+ "font-weight": "400",
1266
+ "fill": "#4D5D6B"
1267
+ },
1268
+ "text": "3 / 3"
1269
+ }
1270
+ ],
1271
+ "viewBox": {
1272
+ "x": 0,
1273
+ "y": 0,
1274
+ "width": 1920,
1275
+ "height": 1080
1276
+ },
1277
+ "description": "Migrated page 3 from Parcel Relay",
1278
+ "fit": "stretch"
1279
+ }
1280
+ }
1281
+ ],
1282
+ "groups": [],
1283
+ "readingOrder": [
1284
+ {
1285
+ "kind": "component",
1286
+ "id": "migrated-page-3"
1287
+ }
1288
+ ],
1289
+ "paintOrder": [
1290
+ "migrated-page-3"
1291
+ ],
1292
+ "relationships": []
1293
+ }
1294
+ ]
1295
+ }