foldkit 0.90.0 → 0.91.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 (103) hide show
  1. package/README.md +21 -10
  2. package/dist/canvas/index.d.ts +5 -0
  3. package/dist/canvas/index.d.ts.map +1 -0
  4. package/dist/canvas/index.js +2 -0
  5. package/dist/canvas/paint.d.ts +14 -0
  6. package/dist/canvas/paint.d.ts.map +1 -0
  7. package/dist/canvas/paint.js +144 -0
  8. package/dist/canvas/public.d.ts +3 -0
  9. package/dist/canvas/public.d.ts.map +1 -0
  10. package/dist/canvas/public.js +1 -0
  11. package/dist/canvas/shape.d.ts +188 -0
  12. package/dist/canvas/shape.d.ts.map +1 -0
  13. package/dist/canvas/shape.js +103 -0
  14. package/dist/canvas/view.d.ts +38 -0
  15. package/dist/canvas/view.d.ts.map +1 -0
  16. package/dist/canvas/view.js +97 -0
  17. package/dist/devTools/overlay.d.ts.map +1 -1
  18. package/dist/devTools/overlay.js +148 -148
  19. package/dist/devTools/store.d.ts +1 -1
  20. package/dist/devTools/store.d.ts.map +1 -1
  21. package/dist/devTools/store.js +1 -2
  22. package/dist/html/index.d.ts +3 -3
  23. package/dist/html/index.d.ts.map +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -0
  27. package/dist/runtime/crashUI.js +30 -30
  28. package/dist/runtime/runtime.d.ts.map +1 -1
  29. package/dist/runtime/runtime.js +15 -10
  30. package/dist/subscription/animationFrame.d.ts +53 -0
  31. package/dist/subscription/animationFrame.d.ts.map +1 -0
  32. package/dist/subscription/animationFrame.js +47 -0
  33. package/dist/subscription/public.d.ts +2 -0
  34. package/dist/subscription/public.d.ts.map +1 -1
  35. package/dist/subscription/public.js +1 -0
  36. package/dist/test/apps/bubbling.js +4 -4
  37. package/dist/test/apps/disabledButton.js +10 -10
  38. package/dist/test/apps/fileUpload.d.ts.map +1 -1
  39. package/dist/test/apps/fileUpload.js +13 -13
  40. package/dist/test/apps/interactions.d.ts.map +1 -1
  41. package/dist/test/apps/interactions.js +15 -15
  42. package/dist/test/apps/keypress.js +8 -8
  43. package/dist/test/apps/login.d.ts.map +1 -1
  44. package/dist/test/apps/login.js +32 -24
  45. package/dist/test/apps/logoutButton.d.ts.map +1 -1
  46. package/dist/test/apps/logoutButton.js +2 -2
  47. package/dist/test/apps/mountPanel.js +10 -10
  48. package/dist/test/apps/multiRole.js +3 -3
  49. package/dist/test/apps/pointer.d.ts.map +1 -1
  50. package/dist/test/apps/pointer.js +11 -11
  51. package/dist/test/apps/resumeUpload.d.ts.map +1 -1
  52. package/dist/test/apps/resumeUpload.js +8 -8
  53. package/dist/ui/animation/index.js +24 -24
  54. package/dist/ui/button/index.d.ts.map +1 -1
  55. package/dist/ui/button/index.js +6 -6
  56. package/dist/ui/calendar/index.d.ts.map +1 -1
  57. package/dist/ui/calendar/index.js +101 -99
  58. package/dist/ui/checkbox/index.d.ts.map +1 -1
  59. package/dist/ui/checkbox/index.js +15 -15
  60. package/dist/ui/combobox/shared.d.ts.map +1 -1
  61. package/dist/ui/combobox/shared.js +102 -90
  62. package/dist/ui/datePicker/index.js +4 -4
  63. package/dist/ui/dialog/index.d.ts.map +1 -1
  64. package/dist/ui/dialog/index.js +27 -27
  65. package/dist/ui/disclosure/index.d.ts.map +1 -1
  66. package/dist/ui/disclosure/index.js +24 -22
  67. package/dist/ui/dragAndDrop/index.d.ts +1 -1
  68. package/dist/ui/dragAndDrop/index.d.ts.map +1 -1
  69. package/dist/ui/dragAndDrop/index.js +15 -15
  70. package/dist/ui/fieldset/index.js +6 -6
  71. package/dist/ui/fileDrop/index.d.ts +2 -2
  72. package/dist/ui/fileDrop/index.d.ts.map +1 -1
  73. package/dist/ui/fileDrop/index.js +16 -16
  74. package/dist/ui/input/index.d.ts.map +1 -1
  75. package/dist/ui/input/index.js +15 -13
  76. package/dist/ui/listbox/multi.d.ts +1 -1
  77. package/dist/ui/listbox/shared.d.ts +1 -1
  78. package/dist/ui/listbox/shared.d.ts.map +1 -1
  79. package/dist/ui/listbox/shared.js +85 -79
  80. package/dist/ui/listbox/single.d.ts +1 -1
  81. package/dist/ui/menu/index.d.ts.map +1 -1
  82. package/dist/ui/menu/index.js +69 -67
  83. package/dist/ui/popover/index.d.ts.map +1 -1
  84. package/dist/ui/popover/index.js +41 -39
  85. package/dist/ui/radioGroup/index.d.ts.map +1 -1
  86. package/dist/ui/radioGroup/index.js +20 -20
  87. package/dist/ui/select/index.d.ts.map +1 -1
  88. package/dist/ui/select/index.js +13 -11
  89. package/dist/ui/slider/index.d.ts.map +1 -1
  90. package/dist/ui/slider/index.js +26 -26
  91. package/dist/ui/switch/index.d.ts.map +1 -1
  92. package/dist/ui/switch/index.js +14 -14
  93. package/dist/ui/tabs/index.d.ts.map +1 -1
  94. package/dist/ui/tabs/index.js +40 -36
  95. package/dist/ui/textarea/index.d.ts.map +1 -1
  96. package/dist/ui/textarea/index.js +15 -13
  97. package/dist/ui/toast/index.d.ts.map +1 -1
  98. package/dist/ui/toast/index.js +27 -27
  99. package/dist/ui/tooltip/index.d.ts.map +1 -1
  100. package/dist/ui/tooltip/index.js +23 -23
  101. package/dist/ui/virtualList/index.d.ts.map +1 -1
  102. package/dist/ui/virtualList/index.js +18 -15
  103. package/package.json +5 -1
@@ -0,0 +1,97 @@
1
+ import { Array, Effect, Predicate, Record, String, pipe } from 'effect';
2
+ import { h } from 'snabbdom';
3
+ import { Dispatch } from '../runtime/index.js';
4
+ import { paintScene } from './paint.js';
5
+ /**
6
+ * Per-element 2D context cache. Keyed by the live `<canvas>` element so the
7
+ * postpatch hook reads the same context the insert hook captured. `WeakMap`
8
+ * lets the entry be reclaimed if the element is removed.
9
+ */
10
+ const contextStore = new WeakMap();
11
+ const toCanvasPoint = (canvas, event) => {
12
+ const rect = canvas.getBoundingClientRect();
13
+ const scaleX = rect.width === 0 ? 1 : canvas.width / rect.width;
14
+ const scaleY = rect.height === 0 ? 1 : canvas.height / rect.height;
15
+ return {
16
+ x: (event.clientX - rect.left) * scaleX,
17
+ y: (event.clientY - rect.top) * scaleY,
18
+ };
19
+ };
20
+ const classesFromClassName = (className) => pipe(className, String.split(/\s+/), Array.filter(String.isNonEmpty), Record.fromIterableWith(name => [name, true]));
21
+ /**
22
+ * A virtual DOM `<canvas>` element backed by a declarative scene description.
23
+ * The insert hook captures the 2D context and paints the initial scene; the
24
+ * postpatch hook re-paints on every render. The canvas is a pure function of
25
+ * `shapes`. Same shapes produce the same pixels.
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * Canvas.view<Message>({
30
+ * width: 400,
31
+ * height: 300,
32
+ * shapes: [
33
+ * Canvas.Rect({ x: 0, y: 0, width: 400, height: 300, fill: '#000' }),
34
+ * Canvas.Circle({ x: 200, y: 150, radius: 50, fill: '#f0a' }),
35
+ * ],
36
+ * onPointerDown: ({ x, y }) => ClickedCanvas({ x, y }),
37
+ * })
38
+ * ```
39
+ */
40
+ export const view = (config) => Effect.gen(function* () {
41
+ const { dispatchSync } = yield* Dispatch;
42
+ const { width, height, shapes, className, onPointerDown, onPointerMove, onPointerUp, } = config;
43
+ const pointerListener = (toMessage) => (event) => {
44
+ const target = event.currentTarget;
45
+ if (target instanceof HTMLCanvasElement) {
46
+ dispatchSync(toMessage(toCanvasPoint(target, event)));
47
+ }
48
+ };
49
+ const listeners = {
50
+ ...(onPointerDown !== undefined && {
51
+ pointerdown: pointerListener(onPointerDown),
52
+ }),
53
+ ...(onPointerMove !== undefined && {
54
+ pointermove: pointerListener(onPointerMove),
55
+ }),
56
+ ...(onPointerUp !== undefined && {
57
+ pointerup: pointerListener(onPointerUp),
58
+ }),
59
+ };
60
+ const data = {
61
+ props: { width, height },
62
+ on: listeners,
63
+ ...(className !== undefined && {
64
+ class: classesFromClassName(className),
65
+ }),
66
+ hook: {
67
+ insert: vnode => {
68
+ if (!(vnode.elm instanceof HTMLCanvasElement)) {
69
+ return;
70
+ }
71
+ const canvas = vnode.elm;
72
+ const nullableContext = canvas.getContext('2d');
73
+ if (Predicate.isNull(nullableContext)) {
74
+ return;
75
+ }
76
+ contextStore.set(canvas, nullableContext);
77
+ paintScene(nullableContext, width, height, shapes);
78
+ },
79
+ postpatch: (_oldVnode, vnode) => {
80
+ if (!(vnode.elm instanceof HTMLCanvasElement)) {
81
+ return;
82
+ }
83
+ const nullableContext = contextStore.get(vnode.elm);
84
+ if (nullableContext === undefined) {
85
+ return;
86
+ }
87
+ paintScene(nullableContext, width, height, shapes);
88
+ },
89
+ destroy: vnode => {
90
+ if (vnode.elm instanceof HTMLCanvasElement) {
91
+ contextStore.delete(vnode.elm);
92
+ }
93
+ },
94
+ },
95
+ };
96
+ return h('canvas', data);
97
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/devTools/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,OAAO,EACP,MAAM,EAGN,OAAO,EAGP,MAAM,EAKN,MAAM,IAAI,CAAC,EAGX,eAAe,EAEhB,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAa9C,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO3E,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAElB,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;;oFAiYJ,CAAC;;;;;;;;;;;;;AAtIhB,cAAM,YAAa,SAAQ,iBAE1B;CAAG;;AAEJ,cAAM,iBAAkB,SAAQ,sBAGC;CAAG;AAEpC,eAAO,MAAM,UAAU;;iBAGsB,CAAA;AAE7C,eAAO,MAAM,YAAY;;iBAGwB,CAAA;AAWjD,eAAO,MAAM,MAAM;;;;wBAUlB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;wBAIqB,CAAA;AAE9C,eAAO,MAAM,aAAa;;;;;;wBAYzB,CAAA;AAED,eAAO,MAAM,MAAM;;wBASlB,CAAA;AAED,eAAO,MAAM,KAAK;;wBASjB,CAAA;AAED,eAAO,MAAM,WAAW;;6BAYvB,CAAA;AAugDD,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,sCAoDhC,CAAA"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/devTools/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,OAAO,EACP,MAAM,EAGN,OAAO,EAGP,MAAM,EAKN,MAAM,IAAI,CAAC,EAGX,eAAe,EAEhB,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAa9C,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO3E,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAElB,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;;oFA+XH,CAAC;;;;;;;;;;;;;AApIjB,cAAM,YAAa,SAAQ,iBAE1B;CAAG;;AAEJ,cAAM,iBAAkB,SAAQ,sBAGC;CAAG;AAEpC,eAAO,MAAM,UAAU;;iBAGsB,CAAA;AAE7C,eAAO,MAAM,YAAY;;iBAGwB,CAAA;AAWjD,eAAO,MAAM,MAAM;;;;wBAUlB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;wBAIqB,CAAA;AAE9C,eAAO,MAAM,aAAa;;;;;;wBAYzB,CAAA;AAED,eAAO,MAAM,MAAM;;wBASlB,CAAA;AAED,eAAO,MAAM,KAAK;;wBASjB,CAAA;AAED,eAAO,MAAM,WAAW;;6BAYvB,CAAA;AA2/CD,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,sCAoDhC,CAAA"}
@@ -422,34 +422,34 @@ const PANEL_POSITION_CLASS = {
422
422
  TopLeft: 'dt-panel-tl',
423
423
  };
424
424
  const makeView = (position, mode, maybeBanner) => {
425
- const { div, header, span, ul, button, svg, path, keyed, Key, Class, Style, OnClick, AriaHidden, Xmlns, Fill, ViewBox, StrokeWidth, Stroke, StrokeLinecap, StrokeLinejoin, D, } = html();
425
+ const h = html();
426
426
  const lazyTreeNode = createKeyedLazy();
427
427
  const lazyMessageRow = createKeyedLazy();
428
428
  const lazyTabContent = createKeyedLazy();
429
429
  const lazyMessageList = createLazy();
430
430
  // JSON TREE
431
- const leafValueView = (value) => M.value(value).pipe(M.when(Predicate.isNull, () => span([Class('json-null italic')], ['null'])), M.when(Predicate.isUndefined, () => span([Class('json-null italic')], ['undefined'])), M.when(Predicate.isString, stringValue => span([Class('json-string')], [`"${stringValue}"`])), M.when(Predicate.isNumber, numberValue => span([Class('json-number')], [String(numberValue)])), M.when(Predicate.isBoolean, booleanValue => span([Class('json-boolean')], [String(booleanValue)])), M.orElse(unknownValue => span([Class('json-null')], [String(unknownValue)])));
432
- const keyView = (key) => span([Class('json-key')], [`${key}:\u00a0`]);
431
+ const leafValueView = (value) => M.value(value).pipe(M.when(Predicate.isNull, () => h.span([h.Class('json-null italic')], ['null'])), M.when(Predicate.isUndefined, () => h.span([h.Class('json-null italic')], ['undefined'])), M.when(Predicate.isString, stringValue => h.span([h.Class('json-string')], [`"${stringValue}"`])), M.when(Predicate.isNumber, numberValue => h.span([h.Class('json-number')], [String(numberValue)])), M.when(Predicate.isBoolean, booleanValue => h.span([h.Class('json-boolean')], [String(booleanValue)])), M.orElse(unknownValue => h.span([h.Class('json-null')], [String(unknownValue)])));
432
+ const keyView = (key) => h.span([h.Class('json-key')], [`${key}:\u00a0`]);
433
433
  const CHEVRON_RIGHT = 'M8.25 4.5l7.5 7.5-7.5 7.5';
434
434
  const CHEVRON_DOWN = 'M19.5 8.25l-7.5 7.5-7.5-7.5';
435
- const arrowView = (isExpanded) => svg([
436
- AriaHidden(true),
437
- Class('json-arrow shrink-0'),
438
- Xmlns('http://www.w3.org/2000/svg'),
439
- Fill('none'),
440
- ViewBox('0 0 24 24'),
441
- StrokeWidth('2'),
442
- Stroke('currentColor'),
435
+ const arrowView = (isExpanded) => h.svg([
436
+ h.AriaHidden(true),
437
+ h.Class('json-arrow shrink-0'),
438
+ h.Xmlns('http://www.w3.org/2000/h.svg'),
439
+ h.Fill('none'),
440
+ h.ViewBox('0 0 24 24'),
441
+ h.StrokeWidth('2'),
442
+ h.Stroke('currentColor'),
443
443
  ], [
444
- path([
445
- StrokeLinecap('round'),
446
- StrokeLinejoin('round'),
447
- D(isExpanded ? CHEVRON_DOWN : CHEVRON_RIGHT),
444
+ h.path([
445
+ h.StrokeLinecap('round'),
446
+ h.StrokeLinejoin('round'),
447
+ h.D(isExpanded ? CHEVRON_DOWN : CHEVRON_RIGHT),
448
448
  ], []),
449
449
  ]);
450
- const tagLabelView = (tag) => span([Class('json-tag')], [tag]);
451
- const diffDotView = span([Class('diff-dot')], []);
452
- const inlineDiffDotView = span([Class('diff-dot-inline')], []);
450
+ const tagLabelView = (tag) => h.span([h.Class('json-tag')], [tag]);
451
+ const diffDotView = h.span([h.Class('diff-dot')], []);
452
+ const inlineDiffDotView = h.span([h.Class('diff-dot-inline')], []);
453
453
  const flattenTree = ({ value, treePath, depth, key, ...shared }) => {
454
454
  const { rootPath, expandedPaths, changedPaths, affectedPaths, accumulator, indentRootChildren, } = shared;
455
455
  const isRoot = treePath === rootPath;
@@ -492,12 +492,12 @@ const makeView = (position, mode, maybeBanner) => {
492
492
  }
493
493
  };
494
494
  const flatNodeView = (value, treePath, depth, key, nodeIsExpandable, isExpanded, isChanged, isAffected, isRoot, tag) => {
495
- const indent = Style({ paddingLeft: `${depth * TREE_INDENT_PX}px` });
495
+ const indent = h.Style({ paddingLeft: `${depth * TREE_INDENT_PX}px` });
496
496
  const hasDiffDot = isChanged || isAffected;
497
497
  if (!nodeIsExpandable) {
498
- return div([
499
- Key(treePath),
500
- Class(clsx('tree-row flex items-center gap-px font-mono text-2xs', {
498
+ return h.div([
499
+ h.Key(treePath),
500
+ h.Class(clsx('tree-row flex items-center gap-px font-mono text-2xs', {
501
501
  'diff-changed': isChanged,
502
502
  })),
503
503
  indent,
@@ -512,20 +512,20 @@ const makeView = (position, mode, maybeBanner) => {
512
512
  ? `(${value.length})`
513
513
  : ''
514
514
  : collapsedPreview(value);
515
- return div([
516
- Key(treePath),
517
- Class(clsx('tree-row flex items-center gap-px font-mono text-2xs', {
515
+ return h.div([
516
+ h.Key(treePath),
517
+ h.Class(clsx('tree-row flex items-center gap-px font-mono text-2xs', {
518
518
  'tree-row-expandable cursor-pointer': !isRoot,
519
519
  'diff-changed': isChanged,
520
520
  })),
521
521
  indent,
522
- ...(isRoot ? [] : [OnClick(ToggledTreeNode({ path: treePath }))]),
522
+ ...(isRoot ? [] : [h.OnClick(ToggledTreeNode({ path: treePath }))]),
523
523
  ], [
524
524
  ...(isRoot ? [] : [arrowView(isExpanded)]),
525
525
  ...(!isRoot && hasDiffDot ? [diffDotView] : []),
526
526
  ...(String_.isNonEmpty(key) ? [keyView(key)] : []),
527
527
  ...(String_.isNonEmpty(tag) ? [tagLabelView(tag)] : []),
528
- span([Class('json-preview')], [preview]),
528
+ h.span([h.Class('json-preview')], [preview]),
529
529
  ]);
530
530
  };
531
531
  const renderFlatNode = (node) => lazyTreeNode(node.treePath, flatNodeView, [
@@ -554,8 +554,8 @@ const makeView = (position, mode, maybeBanner) => {
554
554
  accumulator: nodes,
555
555
  indentRootChildren,
556
556
  });
557
- return div([
558
- Class('inspector-tree flex-1 overflow-auto min-h-0 min-w-0 overscroll-none'),
557
+ return h.div([
558
+ h.Class('inspector-tree flex-1 overflow-auto min-h-0 min-w-0 overscroll-none'),
559
559
  ], nodes.map(renderFlatNode));
560
560
  };
561
561
  const inspectedTimestamp = (model) => {
@@ -579,8 +579,8 @@ const makeView = (position, mode, maybeBanner) => {
579
579
  : `+${remainingMs.toFixed(1)}ms`;
580
580
  }), Option.getOrElse(() => ''));
581
581
  };
582
- const emptyInspectorView = div([
583
- Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
582
+ const emptyInspectorView = h.div([
583
+ h.Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
584
584
  ], ['Click a message to inspect']);
585
585
  const INSPECTOR_TABS = [
586
586
  'Model',
@@ -588,8 +588,8 @@ const makeView = (position, mode, maybeBanner) => {
588
588
  'Commands',
589
589
  'Mounts',
590
590
  ];
591
- const noMessageView = div([
592
- Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
591
+ const noMessageView = h.div([
592
+ h.Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
593
593
  ], ['init — no Message']);
594
594
  const modelTabContent = (inspectedModel, expandedPaths, changedPaths, affectedPaths) => treeView(inspectedModel, 'root', expandedPaths, changedPaths, affectedPaths, Option.none(), true);
595
595
  const unwrapIfFiltered = (message, maybeSubmodelFilter) => {
@@ -619,11 +619,11 @@ const makeView = (position, mode, maybeBanner) => {
619
619
  onNone: () => noMessageView,
620
620
  onSome: rawMessage => {
621
621
  const message = unwrapIfFiltered(rawMessage, maybeSubmodelFilter);
622
- return div([Class('flex flex-col flex-1 min-h-0 min-w-0')], [
623
- div([
624
- Class('px-2 py-1 border-b text-2xs text-dt-muted font-mono shrink-0'),
622
+ return h.div([h.Class('flex flex-col flex-1 min-h-0 min-w-0')], [
623
+ h.div([
624
+ h.Class('px-2 py-1 border-b text-2xs text-dt-muted font-mono shrink-0'),
625
625
  ], [timestamp]),
626
- div([Class('flex flex-col flex-1 min-h-0 min-w-0 pt-1 pl-1')], [
626
+ h.div([h.Class('flex flex-col flex-1 min-h-0 min-w-0 pt-1 pl-1')], [
627
627
  treeView(message, 'root', expandedPaths, HashSet.empty(), HashSet.empty(), Option.none(), false),
628
628
  ]),
629
629
  ]);
@@ -661,14 +661,14 @@ const makeView = (position, mode, maybeBanner) => {
661
661
  return nodes;
662
662
  };
663
663
  const commandsTabContent = (commands, expandedPaths) => Array_.match(commands, {
664
- onEmpty: () => div([
665
- Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
664
+ onEmpty: () => h.div([
665
+ h.Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
666
666
  ], ['No Commands returned']),
667
- onNonEmpty: commandList => div([
668
- Class('flex flex-col flex-1 min-h-0 min-w-0 overflow-auto overscroll-none'),
669
- ], Array_.map(commandList, (command, index) => div([Class('flex items-start px-2 py-1 border-b gap-1.5')], [
670
- span([Class(indexClass)], [String(index + 1)]),
671
- div([Class('flex flex-col flex-1 min-w-0')], Array_.map(flattenCommand(command, index, expandedPaths), renderFlatNode)),
667
+ onNonEmpty: commandList => h.div([
668
+ h.Class('flex flex-col flex-1 min-h-0 min-w-0 overflow-auto overscroll-none'),
669
+ ], Array_.map(commandList, (command, index) => h.div([h.Class('flex items-start px-2 py-1 border-b gap-1.5')], [
670
+ h.span([h.Class(indexClass)], [String(index + 1)]),
671
+ h.div([h.Class('flex flex-col flex-1 min-w-0')], Array_.map(flattenCommand(command, index, expandedPaths), renderFlatNode)),
672
672
  ]))),
673
673
  });
674
674
  const selectedMountActivity = (model) => {
@@ -707,25 +707,25 @@ const makeView = (position, mode, maybeBanner) => {
707
707
  });
708
708
  return nodes;
709
709
  };
710
- const mountListSection = (label, mounts, expandedPaths) => div([Class('flex flex-col shrink-0')], [
711
- div([
712
- Class('px-2 py-1 border-b text-2xs text-dt-muted font-mono shrink-0'),
710
+ const mountListSection = (label, mounts, expandedPaths) => h.div([h.Class('flex flex-col shrink-0')], [
711
+ h.div([
712
+ h.Class('px-2 py-1 border-b text-2xs text-dt-muted font-mono shrink-0'),
713
713
  ], [label]),
714
- ...Array_.map(mounts, (mount, index) => div([Class('flex items-start px-2 py-1 border-b gap-1.5')], [
715
- span([Class(indexClass)], [String(index + 1)]),
716
- div([Class('flex flex-col flex-1 min-w-0')], Array_.map(flattenMount(mount, label, index, expandedPaths), renderFlatNode)),
714
+ ...Array_.map(mounts, (mount, index) => h.div([h.Class('flex items-start px-2 py-1 border-b gap-1.5')], [
715
+ h.span([h.Class(indexClass)], [String(index + 1)]),
716
+ h.div([h.Class('flex flex-col flex-1 min-w-0')], Array_.map(flattenMount(mount, label, index, expandedPaths), renderFlatNode)),
717
717
  ])),
718
718
  ]);
719
719
  const mountsTabContent = (starts, ends, expandedPaths) => {
720
720
  const hasAny = Array_.isReadonlyArrayNonEmpty(starts) ||
721
721
  Array_.isReadonlyArrayNonEmpty(ends);
722
722
  if (!hasAny) {
723
- return div([
724
- Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
723
+ return h.div([
724
+ h.Class('flex-1 flex items-center justify-center text-dt-muted text-2xs font-mono min-w-0'),
725
725
  ], ['No Mounts during this render']);
726
726
  }
727
- return div([
728
- Class('flex flex-col flex-1 min-h-0 min-w-0 overflow-auto overscroll-none'),
727
+ return h.div([
728
+ h.Class('flex flex-col flex-1 min-h-0 min-w-0 overflow-auto overscroll-none'),
729
729
  ], [
730
730
  ...(Array_.isReadonlyArrayNonEmpty(starts)
731
731
  ? [mountListSection('Started', starts, expandedPaths)]
@@ -756,8 +756,8 @@ const makeView = (position, mode, maybeBanner) => {
756
756
  model.expandedPaths,
757
757
  ]);
758
758
  }), M.exhaustive);
759
- const inspectorPaneView = (model) => div([
760
- Class('flex flex-col border-l min-w-0 min-h-0 flex-1 dt-inspector-pane'),
759
+ const inspectorPaneView = (model) => h.div([
760
+ h.Class('flex flex-col border-l min-w-0 min-h-0 flex-1 dt-inspector-pane'),
761
761
  ], [
762
762
  Tabs.view({
763
763
  model: model.inspectorTabs,
@@ -765,14 +765,14 @@ const makeView = (position, mode, maybeBanner) => {
765
765
  tabs: INSPECTOR_TABS,
766
766
  tabListAriaLabel: 'Inspector tabs',
767
767
  persistPanels: true,
768
- attributes: [Class('flex flex-col flex-1 min-h-0')],
769
- tabListAttributes: [Class('flex border-b shrink-0')],
768
+ attributes: [h.Class('flex flex-col flex-1 min-h-0')],
769
+ tabListAttributes: [h.Class('flex border-b shrink-0')],
770
770
  tabToConfig: (tab, { isActive }) => ({
771
771
  buttonAttributes: [
772
- Class(clsx('dt-tab-button cursor-pointer text-base font-mono px-3 py-1', isActive ? 'text-dt dt-tab-active' : 'text-dt-muted')),
772
+ h.Class(clsx('dt-tab-button cursor-pointer text-base font-mono px-3 py-1', isActive ? 'text-dt dt-tab-active' : 'text-dt-muted')),
773
773
  ],
774
- buttonContent: span([], [tab]),
775
- panelAttributes: [Class('flex flex-col flex-1 min-h-0 min-w-0')],
774
+ buttonContent: h.span([], [tab]),
775
+ panelAttributes: [h.Class('flex flex-col flex-1 min-h-0 min-w-0')],
776
776
  panelContent: Option.match(model.maybeInspectedModel, {
777
777
  onNone: () => emptyInspectorView,
778
778
  onSome: inspectedModel => inspectorTabContent(model, tab, inspectedModel),
@@ -781,47 +781,47 @@ const makeView = (position, mode, maybeBanner) => {
781
781
  }),
782
782
  ]);
783
783
  // MESSAGE LIST
784
- const badgeView = (model) => button([
785
- Class(clsx('fixed bg-dt-bg text-dt cursor-pointer flex flex-col items-center justify-center font-mono outline-none dt-badge', BADGE_POSITION_CLASS[position], model.isPaused ? 'dt-badge-paused' : 'dt-badge-accent')),
786
- Style({ width: '22px', height: '56px', fontSize: '10px' }),
787
- OnClick(ClickedToggle()),
784
+ const badgeView = (model) => h.button([
785
+ h.Class(clsx('fixed bg-dt-bg text-dt cursor-pointer flex flex-col items-center justify-center font-mono outline-none dt-badge', BADGE_POSITION_CLASS[position], model.isPaused ? 'dt-badge-paused' : 'dt-badge-accent')),
786
+ h.Style({ width: '22px', height: '56px', fontSize: '10px' }),
787
+ h.OnClick(ClickedToggle()),
788
788
  ], [
789
789
  model.isOpen
790
- ? svg([
791
- AriaHidden(true),
792
- Xmlns('http://www.w3.org/2000/svg'),
793
- Fill('none'),
794
- ViewBox('0 0 24 24'),
795
- StrokeWidth('1.5'),
796
- Stroke('currentColor'),
797
- Style({ width: '12px', height: '12px' }),
790
+ ? h.svg([
791
+ h.AriaHidden(true),
792
+ h.Xmlns('http://www.w3.org/2000/h.svg'),
793
+ h.Fill('none'),
794
+ h.ViewBox('0 0 24 24'),
795
+ h.StrokeWidth('1.5'),
796
+ h.Stroke('currentColor'),
797
+ h.Style({ width: '12px', height: '12px' }),
798
798
  ], [
799
- path([
800
- StrokeLinecap('round'),
801
- StrokeLinejoin('round'),
802
- D('M6 18L18 6M6 6l12 12'),
799
+ h.path([
800
+ h.StrokeLinecap('round'),
801
+ h.StrokeLinejoin('round'),
802
+ h.D('M6 18L18 6M6 6l12 12'),
803
803
  ], []),
804
804
  ])
805
- : div([
806
- Class(clsx('flex flex-col items-center gap-0.5 font-semibold tracking-wider leading-none', model.isPaused ? 'text-dt-bg' : 'text-dt-muted')),
807
- ], [span([], ['D']), span([], ['E']), span([], ['V'])]),
805
+ : h.div([
806
+ h.Class(clsx('flex flex-col items-center gap-0.5 font-semibold tracking-wider leading-none', model.isPaused ? 'text-dt-bg' : 'text-dt-muted')),
807
+ ], [h.span([], ['D']), h.span([], ['E']), h.span([], ['V'])]),
808
808
  ]);
809
809
  const headerClass = 'flex items-center justify-between px-3 py-1.5 border-b shrink-0';
810
810
  const actionButtonClass = 'dt-resume-button bg-transparent border-none text-dt-live cursor-pointer text-base font-mono font-medium';
811
811
  const statusClass = 'text-base font-mono';
812
- const clearHistoryButton = button([Class(headerButtonClass), OnClick(ClickedClear())], ['Clear history']);
812
+ const clearHistoryButton = h.button([h.Class(headerButtonClass), h.OnClick(ClickedClear())], ['Clear history']);
813
813
  const submodelLabel = (tag) => pipe(tag, String_.replace(/^Got/, ''), String_.replace(/Message$/, ''));
814
814
  const CHECK_ICON = 'M4.5 12.75l6 6 9-13.5';
815
- const checkIconView = svg([
816
- AriaHidden(true),
817
- Class('dt-filter-check shrink-0'),
818
- Xmlns('http://www.w3.org/2000/svg'),
819
- Fill('none'),
820
- ViewBox('0 0 24 24'),
821
- StrokeWidth('2'),
822
- Stroke('currentColor'),
815
+ const checkIconView = h.svg([
816
+ h.AriaHidden(true),
817
+ h.Class('dt-filter-check shrink-0'),
818
+ h.Xmlns('http://www.w3.org/2000/h.svg'),
819
+ h.Fill('none'),
820
+ h.ViewBox('0 0 24 24'),
821
+ h.StrokeWidth('2'),
822
+ h.Stroke('currentColor'),
823
823
  ], [
824
- path([D(CHECK_ICON), StrokeLinecap('round'), StrokeLinejoin('round')], []),
824
+ h.path([h.D(CHECK_ICON), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
825
825
  ]);
826
826
  const filterItemLabel = (item) => String_.isNonEmpty(item) ? submodelLabel(item) : 'All Messages';
827
827
  const submodelFilterView = (model) => {
@@ -836,23 +836,23 @@ const makeView = (position, mode, maybeBanner) => {
836
836
  items: [ALL_MESSAGES_VALUE, ...model.submodelTags],
837
837
  itemToConfig: item => ({
838
838
  className: 'dt-filter-item',
839
- content: div([Class('flex items-center gap-2')], [checkIconView, span([], [filterItemLabel(item)])]),
839
+ content: h.div([h.Class('flex items-center gap-2')], [checkIconView, h.span([], [filterItemLabel(item)])]),
840
840
  }),
841
- buttonContent: span([Class('flex flex-1 items-center justify-between')], [
842
- span([], [buttonLabel]),
843
- svg([
844
- AriaHidden(true),
845
- Class('json-arrow shrink-0'),
846
- Xmlns('http://www.w3.org/2000/svg'),
847
- Fill('none'),
848
- ViewBox('0 0 24 24'),
849
- StrokeWidth('2'),
850
- Stroke('currentColor'),
841
+ buttonContent: h.span([h.Class('flex flex-1 items-center justify-between')], [
842
+ h.span([], [buttonLabel]),
843
+ h.svg([
844
+ h.AriaHidden(true),
845
+ h.Class('json-arrow shrink-0'),
846
+ h.Xmlns('http://www.w3.org/2000/h.svg'),
847
+ h.Fill('none'),
848
+ h.ViewBox('0 0 24 24'),
849
+ h.StrokeWidth('2'),
850
+ h.Stroke('currentColor'),
851
851
  ], [
852
- path([
853
- D(CHEVRON_DOWN),
854
- StrokeLinecap('round'),
855
- StrokeLinejoin('round'),
852
+ h.path([
853
+ h.D(CHEVRON_DOWN),
854
+ h.StrokeLinecap('round'),
855
+ h.StrokeLinejoin('round'),
856
856
  ], []),
857
857
  ]),
858
858
  ]),
@@ -865,60 +865,60 @@ const makeView = (position, mode, maybeBanner) => {
865
865
  const headerView = (model) => {
866
866
  const { status, maybeAction } = M.value(mode).pipe(M.withReturnType(), M.when('TimeTravel', () => model.isPaused
867
867
  ? {
868
- status: span([Class(`${statusClass} text-dt-paused`)], [
868
+ status: h.span([h.Class(`${statusClass} text-dt-paused`)], [
869
869
  model.pausedAtIndex === INIT_INDEX
870
870
  ? 'Paused (init)'
871
871
  : `Paused (${model.pausedAtIndex + 1})`,
872
872
  ]),
873
- maybeAction: Option.some(button([Class(actionButtonClass), OnClick(ClickedResume())], ['Resume →'])),
873
+ maybeAction: Option.some(h.button([h.Class(actionButtonClass), h.OnClick(ClickedResume())], ['Resume →'])),
874
874
  }
875
875
  : {
876
- status: span([Class(`${statusClass} text-dt-live font-medium`)], ['Live']),
876
+ status: h.span([h.Class(`${statusClass} text-dt-live font-medium`)], ['Live']),
877
877
  maybeAction: Option.none(),
878
878
  }), M.when('Inspect', () => ({
879
- status: span([Class(`${statusClass} text-dt-accent`)], [
879
+ status: h.span([h.Class(`${statusClass} text-dt-accent`)], [
880
880
  model.selectedIndex === INIT_INDEX
881
881
  ? 'Inspecting (init)'
882
882
  : `Inspecting (${model.selectedIndex + 1})`,
883
883
  ]),
884
- maybeAction: OptionExt.when(!model.isFollowingLatest, button([Class(actionButtonClass), OnClick(ClickedFollowLatest())], ['Follow Latest →'])),
884
+ maybeAction: OptionExt.when(!model.isFollowingLatest, h.button([h.Class(actionButtonClass), h.OnClick(ClickedFollowLatest())], ['Follow Latest →'])),
885
885
  })), M.exhaustive);
886
- return header([Class(headerClass)], [status, ...Option.toArray(maybeAction), clearHistoryButton]);
886
+ return h.header([h.Class(headerClass)], [status, ...Option.toArray(maybeAction), clearHistoryButton]);
887
887
  };
888
- const initRowView = (isSelected, isPausedHere) => keyed('li')('init', [
889
- Class(clsx(ROW_BASE, { selected: isSelected })),
890
- OnClick(ClickedRow({ index: INIT_INDEX })),
888
+ const initRowView = (isSelected, isPausedHere) => h.keyed('li')('init', [
889
+ h.Class(clsx(ROW_BASE, { selected: isSelected })),
890
+ h.OnClick(ClickedRow({ index: INIT_INDEX })),
891
891
  ], [
892
- ...OptionExt.when(mode === 'TimeTravel', span([Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
893
- span([Class('dot-column')], []),
894
- span([Class(indexClass)], []),
895
- span([Class('text-base text-dt-muted font-mono')], ['init']),
892
+ ...OptionExt.when(mode === 'TimeTravel', h.span([h.Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
893
+ h.span([h.Class('dot-column')], []),
894
+ h.span([h.Class(indexClass)], []),
895
+ h.span([h.Class('text-base text-dt-muted font-mono')], ['init']),
896
896
  ]);
897
- const pauseIconView = svg([
898
- AriaHidden(true),
899
- Class('dt-pause-icon'),
900
- Xmlns('http://www.w3.org/2000/svg'),
901
- Fill('none'),
902
- ViewBox('0 0 24 24'),
903
- StrokeWidth('2.5'),
904
- Stroke('currentColor'),
897
+ const pauseIconView = h.svg([
898
+ h.AriaHidden(true),
899
+ h.Class('dt-pause-icon'),
900
+ h.Xmlns('http://www.w3.org/2000/h.svg'),
901
+ h.Fill('none'),
902
+ h.ViewBox('0 0 24 24'),
903
+ h.StrokeWidth('2.5'),
904
+ h.Stroke('currentColor'),
905
905
  ], [
906
- path([
907
- StrokeLinecap('round'),
908
- StrokeLinejoin('round'),
909
- D('M5.75 3v18M18.25 3v18'),
906
+ h.path([
907
+ h.StrokeLinecap('round'),
908
+ h.StrokeLinejoin('round'),
909
+ h.D('M5.75 3v18M18.25 3v18'),
910
910
  ], []),
911
911
  ]);
912
- const messageRowView = (tag, absoluteIndex, isSelected, isPausedHere, timeDelta, isModelChanged) => keyed('li')(String(absoluteIndex), [
913
- Class(clsx(ROW_BASE, { selected: isSelected })),
914
- OnClick(ClickedRow({ index: absoluteIndex })),
912
+ const messageRowView = (tag, absoluteIndex, isSelected, isPausedHere, timeDelta, isModelChanged) => h.keyed('li')(String(absoluteIndex), [
913
+ h.Class(clsx(ROW_BASE, { selected: isSelected })),
914
+ h.OnClick(ClickedRow({ index: absoluteIndex })),
915
915
  ], [
916
- ...OptionExt.when(mode === 'TimeTravel', span([Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
917
- span([Class('dot-column')], isModelChanged ? [inlineDiffDotView] : []),
918
- span([Class(indexClass)], [String(absoluteIndex + 1)]),
919
- span([Class('text-base text-dt font-mono flex-1 truncate')], [tag]),
920
- span([
921
- Class('text-2xs text-dt-muted font-mono shrink-0 text-right min-w-5'),
916
+ ...OptionExt.when(mode === 'TimeTravel', h.span([h.Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
917
+ h.span([h.Class('dot-column')], isModelChanged ? [inlineDiffDotView] : []),
918
+ h.span([h.Class(indexClass)], [String(absoluteIndex + 1)]),
919
+ h.span([h.Class('text-base text-dt font-mono flex-1 truncate')], [tag]),
920
+ h.span([
921
+ h.Class('text-2xs text-dt-muted font-mono shrink-0 text-right min-w-5'),
922
922
  ], [formatTimeDelta(timeDelta)]),
923
923
  ]);
924
924
  const messageListBody = (entries, startIndex, selectedIndex, isPaused, pausedAtIndex, maybeFilterTag) => {
@@ -949,7 +949,7 @@ const makeView = (position, mode, maybeBanner) => {
949
949
  entry.isModelChanged,
950
950
  ]);
951
951
  }), Array_.reverse);
952
- return ul([Class('message-list flex-1 overflow-y-auto min-h-0 overscroll-none')], isFiltered
952
+ return h.ul([h.Class('message-list flex-1 overflow-y-auto min-h-0 overscroll-none')], isFiltered
953
953
  ? messageRows
954
954
  : [
955
955
  ...messageRows,
@@ -972,15 +972,15 @@ const makeView = (position, mode, maybeBanner) => {
972
972
  ]);
973
973
  };
974
974
  // PANEL
975
- const panelView = (model) => keyed('div')('dt-panel', [
976
- Class(clsx('fixed dt-panel dt-panel-wide bg-dt-bg border rounded-lg flex flex-col overflow-hidden font-mono text-dt', PANEL_POSITION_CLASS[position])),
975
+ const panelView = (model) => h.keyed('div')('dt-panel', [
976
+ h.Class(clsx('fixed dt-panel dt-panel-wide bg-dt-bg border rounded-lg flex flex-col overflow-hidden font-mono text-dt', PANEL_POSITION_CLASS[position])),
977
977
  ], [
978
- ...Option.map(maybeBanner, banner => div([
979
- Class('px-3 py-2 border-b text-sm text-dt-muted font-mono shrink-0 leading-snug'),
978
+ ...Option.map(maybeBanner, banner => h.div([
979
+ h.Class('px-3 py-2 border-b text-sm text-dt-muted font-mono shrink-0 leading-snug'),
980
980
  ], [banner])).pipe(Option.toArray),
981
981
  headerView(model),
982
- div([Class('flex flex-1 min-h-0 dt-content')], [
983
- div([Class('flex flex-col min-h-0 dt-message-pane')], [
982
+ h.div([h.Class('flex flex-1 min-h-0 dt-content')], [
983
+ h.div([h.Class('flex flex-col min-h-0 dt-message-pane')], [
984
984
  ...Array_.match(model.submodelTags, {
985
985
  onEmpty: () => [],
986
986
  onNonEmpty: () => [submodelFilterView(model)],
@@ -990,10 +990,10 @@ const makeView = (position, mode, maybeBanner) => {
990
990
  inspectorPaneView(model),
991
991
  ]),
992
992
  ]);
993
- const interactionBlocker = div([Class('dt-interaction-blocker')], []);
993
+ const interactionBlocker = h.div([h.Class('dt-interaction-blocker')], []);
994
994
  return (model) => ({
995
995
  title: 'Foldkit DevTools',
996
- body: div([], [
996
+ body: h.div([], [
997
997
  ...OptionExt.when(model.isPaused && mode === 'TimeTravel', interactionBlocker).pipe(Option.toArray),
998
998
  ...OptionExt.when(model.isOpen, panelView(model)).pipe(Option.toArray),
999
999
  badgeView(model),
@@ -38,7 +38,7 @@ export type StoreState = Readonly<{
38
38
  export type Bridge = Readonly<{
39
39
  replay: (model: unknown, message: unknown) => unknown;
40
40
  render: (model: unknown) => Effect.Effect<void>;
41
- getCurrentModel: Effect.Effect<unknown>;
41
+ markRenderPending: Effect.Effect<void>;
42
42
  }>;
43
43
  export declare const createDevToolsStore: (bridge: Bridge, maxEntries?: number) => Effect.Effect<DevToolsStore>;
44
44
  export type DevToolsStore = Readonly<{
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/devTools/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/devTools/store.ts"],"names":[],"mappings":"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"}
@@ -187,12 +187,11 @@ export const createDevToolsStore = (bridge, maxEntries = DEFAULT_MAX_ENTRIES) =>
187
187
  });
188
188
  });
189
189
  const resume = Effect.gen(function* () {
190
- const currentModel = yield* bridge.getCurrentModel;
191
- yield* bridge.render(currentModel);
192
190
  yield* SubscriptionRef.update(stateRef, state => ({
193
191
  ...state,
194
192
  isPaused: false,
195
193
  }));
194
+ yield* bridge.markRenderPending;
196
195
  });
197
196
  const clear = SubscriptionRef.update(stateRef, state => ({
198
197
  ...emptyState,