foldkit 0.89.0 → 0.90.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -10
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +3 -11
- package/dist/devTools/overlay.d.ts +3 -3
- package/dist/devTools/overlay.d.ts.map +1 -1
- package/dist/devTools/overlay.js +209 -171
- package/dist/devTools/protocol.d.ts +77 -19
- package/dist/devTools/protocol.d.ts.map +1 -1
- package/dist/devTools/protocol.js +10 -5
- package/dist/devTools/serialize.d.ts +8 -2
- package/dist/devTools/serialize.d.ts.map +1 -1
- package/dist/devTools/serialize.js +11 -2
- package/dist/devTools/store.d.ts +9 -5
- package/dist/devTools/store.d.ts.map +1 -1
- package/dist/devTools/store.js +13 -13
- package/dist/devTools/webSocketBridge.d.ts.map +1 -1
- package/dist/devTools/webSocketBridge.js +2 -2
- package/dist/html/index.d.ts +12 -0
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +20 -4
- package/dist/mount/index.d.ts +64 -21
- package/dist/mount/index.d.ts.map +1 -1
- package/dist/mount/index.js +43 -32
- package/dist/mount/public.d.ts +1 -1
- package/dist/mount/public.d.ts.map +1 -1
- package/dist/runtime/crashUI.js +30 -30
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +4 -4
- package/dist/test/apps/bubbling.js +4 -4
- package/dist/test/apps/disabledButton.js +10 -10
- package/dist/test/apps/fileUpload.d.ts.map +1 -1
- package/dist/test/apps/fileUpload.js +13 -13
- package/dist/test/apps/interactions.d.ts.map +1 -1
- package/dist/test/apps/interactions.js +15 -15
- package/dist/test/apps/keypress.js +8 -8
- package/dist/test/apps/login.d.ts.map +1 -1
- package/dist/test/apps/login.js +32 -24
- package/dist/test/apps/logoutButton.d.ts.map +1 -1
- package/dist/test/apps/logoutButton.js +2 -2
- package/dist/test/apps/mountPanel.d.ts +19 -3
- package/dist/test/apps/mountPanel.d.ts.map +1 -1
- package/dist/test/apps/mountPanel.js +41 -20
- package/dist/test/apps/multiRole.js +3 -3
- package/dist/test/apps/pointer.d.ts.map +1 -1
- package/dist/test/apps/pointer.js +11 -11
- package/dist/test/apps/resumeUpload.d.ts.map +1 -1
- package/dist/test/apps/resumeUpload.js +8 -8
- package/dist/test/internal.d.ts +50 -20
- package/dist/test/internal.d.ts.map +1 -1
- package/dist/test/internal.js +65 -74
- package/dist/test/scene.d.ts +7 -7
- package/dist/test/scene.d.ts.map +1 -1
- package/dist/test/scene.js +42 -37
- package/dist/test/story.d.ts.map +1 -1
- package/dist/test/story.js +2 -2
- package/dist/ui/anchor.d.ts +12 -8
- package/dist/ui/anchor.d.ts.map +1 -1
- package/dist/ui/anchor.js +41 -16
- package/dist/ui/animation/index.js +24 -24
- package/dist/ui/button/index.d.ts.map +1 -1
- package/dist/ui/button/index.js +6 -6
- package/dist/ui/calendar/index.d.ts.map +1 -1
- package/dist/ui/calendar/index.js +101 -99
- package/dist/ui/checkbox/index.d.ts.map +1 -1
- package/dist/ui/checkbox/index.js +15 -15
- package/dist/ui/combobox/multi.d.ts +1 -7
- package/dist/ui/combobox/multi.d.ts.map +1 -1
- package/dist/ui/combobox/shared.d.ts +14 -5
- package/dist/ui/combobox/shared.d.ts.map +1 -1
- package/dist/ui/combobox/shared.js +137 -125
- package/dist/ui/combobox/single.d.ts +1 -7
- package/dist/ui/combobox/single.d.ts.map +1 -1
- package/dist/ui/datePicker/index.js +4 -4
- package/dist/ui/dialog/index.d.ts.map +1 -1
- package/dist/ui/dialog/index.js +27 -27
- package/dist/ui/disclosure/index.d.ts.map +1 -1
- package/dist/ui/disclosure/index.js +24 -22
- package/dist/ui/dragAndDrop/index.d.ts.map +1 -1
- package/dist/ui/dragAndDrop/index.js +15 -15
- package/dist/ui/fieldset/index.js +6 -6
- package/dist/ui/fileDrop/index.d.ts +2 -2
- package/dist/ui/fileDrop/index.d.ts.map +1 -1
- package/dist/ui/fileDrop/index.js +16 -16
- package/dist/ui/input/index.d.ts.map +1 -1
- package/dist/ui/input/index.js +15 -13
- package/dist/ui/listbox/multi.d.ts +1 -7
- package/dist/ui/listbox/multi.d.ts.map +1 -1
- package/dist/ui/listbox/shared.d.ts +12 -3
- package/dist/ui/listbox/shared.d.ts.map +1 -1
- package/dist/ui/listbox/shared.js +91 -89
- package/dist/ui/listbox/single.d.ts +1 -7
- package/dist/ui/listbox/single.d.ts.map +1 -1
- package/dist/ui/menu/index.d.ts +12 -3
- package/dist/ui/menu/index.d.ts.map +1 -1
- package/dist/ui/menu/index.js +75 -77
- package/dist/ui/popover/index.d.ts +13 -3
- package/dist/ui/popover/index.d.ts.map +1 -1
- package/dist/ui/popover/index.js +62 -53
- package/dist/ui/radioGroup/index.d.ts.map +1 -1
- package/dist/ui/radioGroup/index.js +20 -20
- package/dist/ui/select/index.d.ts.map +1 -1
- package/dist/ui/select/index.js +13 -11
- package/dist/ui/slider/index.d.ts.map +1 -1
- package/dist/ui/slider/index.js +26 -26
- package/dist/ui/switch/index.d.ts.map +1 -1
- package/dist/ui/switch/index.js +14 -14
- package/dist/ui/tabs/index.d.ts.map +1 -1
- package/dist/ui/tabs/index.js +40 -36
- package/dist/ui/textarea/index.d.ts.map +1 -1
- package/dist/ui/textarea/index.js +15 -13
- package/dist/ui/toast/index.d.ts.map +1 -1
- package/dist/ui/toast/index.js +27 -27
- package/dist/ui/tooltip/index.d.ts +11 -2
- package/dist/ui/tooltip/index.d.ts.map +1 -1
- package/dist/ui/tooltip/index.js +33 -33
- package/dist/ui/virtualList/index.d.ts.map +1 -1
- package/dist/ui/virtualList/index.js +18 -15
- package/package.json +1 -1
package/dist/devTools/overlay.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Array as Array_, Context, Effect, Equal, Function, HashSet, Match as M,
|
|
|
3
3
|
import * as Command from '../command/index.js';
|
|
4
4
|
import { lockScroll, unlockScroll } from '../dom/scrollLock.js';
|
|
5
5
|
import { OptionExt } from '../effectExtensions/index.js';
|
|
6
|
-
import { createKeyedLazy, createLazy, html, } from '../html/index.js';
|
|
6
|
+
import { DEVTOOLS_HOST_ID, createKeyedLazy, createLazy, html, } from '../html/index.js';
|
|
7
7
|
import { m } from '../message/index.js';
|
|
8
8
|
import { makeProgram } from '../runtime/runtime.js';
|
|
9
9
|
import { makeSubscriptions } from '../runtime/subscription.js';
|
|
@@ -19,13 +19,17 @@ const DisplayCommand = S.Struct({
|
|
|
19
19
|
name: S.String,
|
|
20
20
|
args: S.Option(S.Record(S.String, S.Unknown)),
|
|
21
21
|
});
|
|
22
|
+
const DisplayMount = S.Struct({
|
|
23
|
+
name: S.String,
|
|
24
|
+
args: S.Option(S.Record(S.String, S.Unknown)),
|
|
25
|
+
});
|
|
22
26
|
const DisplayEntry = S.Struct({
|
|
23
27
|
tag: S.String,
|
|
24
28
|
submodelPath: S.Array(S.String),
|
|
25
29
|
maybeLeafTag: S.Option(S.String),
|
|
26
30
|
commands: S.Array(DisplayCommand),
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
mountStarts: S.Array(DisplayMount),
|
|
32
|
+
mountEnds: S.Array(DisplayMount),
|
|
29
33
|
timestamp: S.Number,
|
|
30
34
|
isModelChanged: S.Boolean,
|
|
31
35
|
});
|
|
@@ -54,7 +58,7 @@ const Model = S.Struct({
|
|
|
54
58
|
isMobile: S.Boolean,
|
|
55
59
|
entries: S.Array(DisplayEntry),
|
|
56
60
|
initCommands: S.Array(DisplayCommand),
|
|
57
|
-
|
|
61
|
+
initMountStarts: S.Array(DisplayMount),
|
|
58
62
|
startIndex: S.Number,
|
|
59
63
|
isPaused: S.Boolean,
|
|
60
64
|
pausedAtIndex: S.Number,
|
|
@@ -74,7 +78,7 @@ const Flags = S.Struct({
|
|
|
74
78
|
isMobile: S.Boolean,
|
|
75
79
|
entries: S.Array(DisplayEntry),
|
|
76
80
|
initCommands: S.Array(DisplayCommand),
|
|
77
|
-
|
|
81
|
+
initMountStarts: S.Array(DisplayMount),
|
|
78
82
|
startIndex: S.Number,
|
|
79
83
|
isPaused: S.Boolean,
|
|
80
84
|
pausedAtIndex: S.Number,
|
|
@@ -107,7 +111,7 @@ const GotInspectorTabsMessage = m('GotInspectorTabsMessage', {
|
|
|
107
111
|
const ReceivedStoreUpdate = m('ReceivedStoreUpdate', {
|
|
108
112
|
entries: S.Array(DisplayEntry),
|
|
109
113
|
initCommands: S.Array(DisplayCommand),
|
|
110
|
-
|
|
114
|
+
initMountStarts: S.Array(DisplayMount),
|
|
111
115
|
startIndex: S.Number,
|
|
112
116
|
isPaused: S.Boolean,
|
|
113
117
|
pausedAtIndex: S.Number,
|
|
@@ -154,6 +158,10 @@ const toDisplayCommand = (command) => ({
|
|
|
154
158
|
name: command.name,
|
|
155
159
|
args: Option.fromNullishOr(command.args),
|
|
156
160
|
});
|
|
161
|
+
const toDisplayMount = (mount) => ({
|
|
162
|
+
name: mount.name,
|
|
163
|
+
args: Option.fromNullishOr(mount.args),
|
|
164
|
+
});
|
|
157
165
|
const toDisplayEntries = ({ entries }) => Array_.map(entries, entry => {
|
|
158
166
|
const { submodelPath, maybeLeafTag } = extractSubmodelInfo(entry.tag, entry.message);
|
|
159
167
|
return {
|
|
@@ -161,8 +169,8 @@ const toDisplayEntries = ({ entries }) => Array_.map(entries, entry => {
|
|
|
161
169
|
submodelPath,
|
|
162
170
|
maybeLeafTag,
|
|
163
171
|
commands: Array_.map(entry.commands, toDisplayCommand),
|
|
164
|
-
|
|
165
|
-
|
|
172
|
+
mountStarts: Array_.map(entry.mountStarts, toDisplayMount),
|
|
173
|
+
mountEnds: Array_.map(entry.mountEnds, toDisplayMount),
|
|
166
174
|
timestamp: entry.timestamp,
|
|
167
175
|
isModelChanged: entry.isModelChanged,
|
|
168
176
|
};
|
|
@@ -170,7 +178,7 @@ const toDisplayEntries = ({ entries }) => Array_.map(entries, entry => {
|
|
|
170
178
|
const toDisplayState = (state) => ({
|
|
171
179
|
entries: toDisplayEntries(state),
|
|
172
180
|
initCommands: Array_.map(state.initCommands, toDisplayCommand),
|
|
173
|
-
|
|
181
|
+
initMountStarts: Array_.map(state.initMountStarts, toDisplayMount),
|
|
174
182
|
startIndex: state.startIndex,
|
|
175
183
|
isPaused: state.isPaused,
|
|
176
184
|
pausedAtIndex: state.pausedAtIndex,
|
|
@@ -326,7 +334,7 @@ const makeUpdate = (store, shadow, mode) => {
|
|
|
326
334
|
}),
|
|
327
335
|
[],
|
|
328
336
|
],
|
|
329
|
-
ReceivedStoreUpdate: ({ entries, initCommands,
|
|
337
|
+
ReceivedStoreUpdate: ({ entries, initCommands, initMountStarts, startIndex, isPaused, pausedAtIndex, }) => {
|
|
330
338
|
const shouldFollowLatest = M.value(mode).pipe(M.when('TimeTravel', () => !isPaused), M.when('Inspect', () => model.isFollowingLatest), M.exhaustive);
|
|
331
339
|
const latestIndex = Array_.match(entries, {
|
|
332
340
|
onEmpty: () => INIT_INDEX,
|
|
@@ -338,7 +346,7 @@ const makeUpdate = (store, shadow, mode) => {
|
|
|
338
346
|
evo(model, {
|
|
339
347
|
entries: () => entries,
|
|
340
348
|
initCommands: () => initCommands,
|
|
341
|
-
|
|
349
|
+
initMountStarts: () => initMountStarts,
|
|
342
350
|
startIndex: () => startIndex,
|
|
343
351
|
isPaused: () => isPaused,
|
|
344
352
|
pausedAtIndex: () => pausedAtIndex,
|
|
@@ -414,34 +422,34 @@ const PANEL_POSITION_CLASS = {
|
|
|
414
422
|
TopLeft: 'dt-panel-tl',
|
|
415
423
|
};
|
|
416
424
|
const makeView = (position, mode, maybeBanner) => {
|
|
417
|
-
const
|
|
425
|
+
const h = html();
|
|
418
426
|
const lazyTreeNode = createKeyedLazy();
|
|
419
427
|
const lazyMessageRow = createKeyedLazy();
|
|
420
428
|
const lazyTabContent = createKeyedLazy();
|
|
421
429
|
const lazyMessageList = createLazy();
|
|
422
430
|
// JSON TREE
|
|
423
|
-
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)])));
|
|
424
|
-
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`]);
|
|
425
433
|
const CHEVRON_RIGHT = 'M8.25 4.5l7.5 7.5-7.5 7.5';
|
|
426
434
|
const CHEVRON_DOWN = 'M19.5 8.25l-7.5 7.5-7.5-7.5';
|
|
427
|
-
const arrowView = (isExpanded) => svg([
|
|
428
|
-
AriaHidden(true),
|
|
429
|
-
Class('json-arrow shrink-0'),
|
|
430
|
-
Xmlns('http://www.w3.org/2000/svg'),
|
|
431
|
-
Fill('none'),
|
|
432
|
-
ViewBox('0 0 24 24'),
|
|
433
|
-
StrokeWidth('2'),
|
|
434
|
-
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'),
|
|
435
443
|
], [
|
|
436
|
-
path([
|
|
437
|
-
StrokeLinecap('round'),
|
|
438
|
-
StrokeLinejoin('round'),
|
|
439
|
-
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),
|
|
440
448
|
], []),
|
|
441
449
|
]);
|
|
442
|
-
const tagLabelView = (tag) => span([Class('json-tag')], [tag]);
|
|
443
|
-
const diffDotView = span([Class('diff-dot')], []);
|
|
444
|
-
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')], []);
|
|
445
453
|
const flattenTree = ({ value, treePath, depth, key, ...shared }) => {
|
|
446
454
|
const { rootPath, expandedPaths, changedPaths, affectedPaths, accumulator, indentRootChildren, } = shared;
|
|
447
455
|
const isRoot = treePath === rootPath;
|
|
@@ -484,12 +492,12 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
484
492
|
}
|
|
485
493
|
};
|
|
486
494
|
const flatNodeView = (value, treePath, depth, key, nodeIsExpandable, isExpanded, isChanged, isAffected, isRoot, tag) => {
|
|
487
|
-
const indent = Style({ paddingLeft: `${depth * TREE_INDENT_PX}px` });
|
|
495
|
+
const indent = h.Style({ paddingLeft: `${depth * TREE_INDENT_PX}px` });
|
|
488
496
|
const hasDiffDot = isChanged || isAffected;
|
|
489
497
|
if (!nodeIsExpandable) {
|
|
490
|
-
return div([
|
|
491
|
-
Key(treePath),
|
|
492
|
-
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', {
|
|
493
501
|
'diff-changed': isChanged,
|
|
494
502
|
})),
|
|
495
503
|
indent,
|
|
@@ -504,20 +512,20 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
504
512
|
? `(${value.length})`
|
|
505
513
|
: ''
|
|
506
514
|
: collapsedPreview(value);
|
|
507
|
-
return div([
|
|
508
|
-
Key(treePath),
|
|
509
|
-
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', {
|
|
510
518
|
'tree-row-expandable cursor-pointer': !isRoot,
|
|
511
519
|
'diff-changed': isChanged,
|
|
512
520
|
})),
|
|
513
521
|
indent,
|
|
514
|
-
...(isRoot ? [] : [OnClick(ToggledTreeNode({ path: treePath }))]),
|
|
522
|
+
...(isRoot ? [] : [h.OnClick(ToggledTreeNode({ path: treePath }))]),
|
|
515
523
|
], [
|
|
516
524
|
...(isRoot ? [] : [arrowView(isExpanded)]),
|
|
517
525
|
...(!isRoot && hasDiffDot ? [diffDotView] : []),
|
|
518
526
|
...(String_.isNonEmpty(key) ? [keyView(key)] : []),
|
|
519
527
|
...(String_.isNonEmpty(tag) ? [tagLabelView(tag)] : []),
|
|
520
|
-
span([Class('json-preview')], [preview]),
|
|
528
|
+
h.span([h.Class('json-preview')], [preview]),
|
|
521
529
|
]);
|
|
522
530
|
};
|
|
523
531
|
const renderFlatNode = (node) => lazyTreeNode(node.treePath, flatNodeView, [
|
|
@@ -546,8 +554,8 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
546
554
|
accumulator: nodes,
|
|
547
555
|
indentRootChildren,
|
|
548
556
|
});
|
|
549
|
-
return div([
|
|
550
|
-
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'),
|
|
551
559
|
], nodes.map(renderFlatNode));
|
|
552
560
|
};
|
|
553
561
|
const inspectedTimestamp = (model) => {
|
|
@@ -571,8 +579,8 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
571
579
|
: `+${remainingMs.toFixed(1)}ms`;
|
|
572
580
|
}), Option.getOrElse(() => ''));
|
|
573
581
|
};
|
|
574
|
-
const emptyInspectorView = div([
|
|
575
|
-
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'),
|
|
576
584
|
], ['Click a message to inspect']);
|
|
577
585
|
const INSPECTOR_TABS = [
|
|
578
586
|
'Model',
|
|
@@ -580,8 +588,8 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
580
588
|
'Commands',
|
|
581
589
|
'Mounts',
|
|
582
590
|
];
|
|
583
|
-
const noMessageView = div([
|
|
584
|
-
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'),
|
|
585
593
|
], ['init — no Message']);
|
|
586
594
|
const modelTabContent = (inspectedModel, expandedPaths, changedPaths, affectedPaths) => treeView(inspectedModel, 'root', expandedPaths, changedPaths, affectedPaths, Option.none(), true);
|
|
587
595
|
const unwrapIfFiltered = (message, maybeSubmodelFilter) => {
|
|
@@ -611,11 +619,11 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
611
619
|
onNone: () => noMessageView,
|
|
612
620
|
onSome: rawMessage => {
|
|
613
621
|
const message = unwrapIfFiltered(rawMessage, maybeSubmodelFilter);
|
|
614
|
-
return div([Class('flex flex-col flex-1 min-h-0 min-w-0')], [
|
|
615
|
-
div([
|
|
616
|
-
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'),
|
|
617
625
|
], [timestamp]),
|
|
618
|
-
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')], [
|
|
619
627
|
treeView(message, 'root', expandedPaths, HashSet.empty(), HashSet.empty(), Option.none(), false),
|
|
620
628
|
]),
|
|
621
629
|
]);
|
|
@@ -653,58 +661,77 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
653
661
|
return nodes;
|
|
654
662
|
};
|
|
655
663
|
const commandsTabContent = (commands, expandedPaths) => Array_.match(commands, {
|
|
656
|
-
onEmpty: () => div([
|
|
657
|
-
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'),
|
|
658
666
|
], ['No Commands returned']),
|
|
659
|
-
onNonEmpty: commandList => div([
|
|
660
|
-
Class('flex flex-col flex-1 min-h-0 min-w-0 overflow-auto overscroll-none'),
|
|
661
|
-
], Array_.map(commandList, (command, index) => div([Class('flex items-start px-2 py-1 border-b gap-1.5')], [
|
|
662
|
-
span([Class(indexClass)], [String(index + 1)]),
|
|
663
|
-
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)),
|
|
664
672
|
]))),
|
|
665
673
|
});
|
|
666
674
|
const selectedMountActivity = (model) => {
|
|
667
675
|
const selectedIndex = selectedHistoryIndex(model);
|
|
668
676
|
if (selectedIndex === INIT_INDEX) {
|
|
669
|
-
return { starts: model.
|
|
677
|
+
return { starts: model.initMountStarts, ends: NO_MOUNTS };
|
|
670
678
|
}
|
|
671
679
|
else {
|
|
672
680
|
return pipe(model.entries, Array_.get(selectedIndex - model.startIndex), Option.match({
|
|
673
681
|
onNone: () => ({ starts: NO_MOUNTS, ends: NO_MOUNTS }),
|
|
674
682
|
onSome: entry => ({
|
|
675
|
-
starts: entry.
|
|
676
|
-
ends: entry.
|
|
683
|
+
starts: entry.mountStarts,
|
|
684
|
+
ends: entry.mountEnds,
|
|
677
685
|
}),
|
|
678
686
|
}));
|
|
679
687
|
}
|
|
680
688
|
};
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
689
|
+
const flattenMount = (mount, sectionLabel, index, expandedPaths) => {
|
|
690
|
+
const taggedValue = Option.match(mount.args, {
|
|
691
|
+
onNone: () => ({ _tag: mount.name }),
|
|
692
|
+
onSome: argsValue => ({ ...argsValue, _tag: mount.name }),
|
|
693
|
+
});
|
|
694
|
+
const rootPath = `mount-${sectionLabel}-${index}`;
|
|
695
|
+
const nodes = [];
|
|
696
|
+
flattenTree({
|
|
697
|
+
value: toInspectableValue(taggedValue),
|
|
698
|
+
treePath: rootPath,
|
|
699
|
+
rootPath,
|
|
700
|
+
expandedPaths,
|
|
701
|
+
changedPaths: HashSet.empty(),
|
|
702
|
+
affectedPaths: HashSet.empty(),
|
|
703
|
+
depth: 0,
|
|
704
|
+
key: '',
|
|
705
|
+
accumulator: nodes,
|
|
706
|
+
indentRootChildren: false,
|
|
707
|
+
});
|
|
708
|
+
return nodes;
|
|
709
|
+
};
|
|
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'),
|
|
684
713
|
], [label]),
|
|
685
|
-
...Array_.map(
|
|
686
|
-
Class(
|
|
687
|
-
|
|
688
|
-
span([Class(indexClass)], [String(index + 1)]),
|
|
689
|
-
span([Class('json-tag')], [name]),
|
|
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)),
|
|
690
717
|
])),
|
|
691
718
|
]);
|
|
692
|
-
const mountsTabContent = (starts, ends) => {
|
|
719
|
+
const mountsTabContent = (starts, ends, expandedPaths) => {
|
|
693
720
|
const hasAny = Array_.isReadonlyArrayNonEmpty(starts) ||
|
|
694
721
|
Array_.isReadonlyArrayNonEmpty(ends);
|
|
695
722
|
if (!hasAny) {
|
|
696
|
-
return div([
|
|
697
|
-
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'),
|
|
698
725
|
], ['No Mounts during this render']);
|
|
699
726
|
}
|
|
700
|
-
return div([
|
|
701
|
-
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'),
|
|
702
729
|
], [
|
|
703
730
|
...(Array_.isReadonlyArrayNonEmpty(starts)
|
|
704
|
-
? [mountListSection('Started', starts)]
|
|
731
|
+
? [mountListSection('Started', starts, expandedPaths)]
|
|
705
732
|
: []),
|
|
706
733
|
...(Array_.isReadonlyArrayNonEmpty(ends)
|
|
707
|
-
? [mountListSection('Ended', ends)]
|
|
734
|
+
? [mountListSection('Ended', ends, expandedPaths)]
|
|
708
735
|
: []),
|
|
709
736
|
]);
|
|
710
737
|
};
|
|
@@ -723,10 +750,14 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
723
750
|
model.expandedPaths,
|
|
724
751
|
])), M.when('Mounts', () => {
|
|
725
752
|
const { starts, ends } = selectedMountActivity(model);
|
|
726
|
-
return lazyTabContent('Mounts', mountsTabContent, [
|
|
753
|
+
return lazyTabContent('Mounts', mountsTabContent, [
|
|
754
|
+
starts,
|
|
755
|
+
ends,
|
|
756
|
+
model.expandedPaths,
|
|
757
|
+
]);
|
|
727
758
|
}), M.exhaustive);
|
|
728
|
-
const inspectorPaneView = (model) => div([
|
|
729
|
-
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'),
|
|
730
761
|
], [
|
|
731
762
|
Tabs.view({
|
|
732
763
|
model: model.inspectorTabs,
|
|
@@ -734,14 +765,14 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
734
765
|
tabs: INSPECTOR_TABS,
|
|
735
766
|
tabListAriaLabel: 'Inspector tabs',
|
|
736
767
|
persistPanels: true,
|
|
737
|
-
attributes: [Class('flex flex-col flex-1 min-h-0')],
|
|
738
|
-
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')],
|
|
739
770
|
tabToConfig: (tab, { isActive }) => ({
|
|
740
771
|
buttonAttributes: [
|
|
741
|
-
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-h.button cursor-pointer text-base font-mono px-3 py-1', isActive ? 'text-dt dt-tab-active' : 'text-dt-muted')),
|
|
742
773
|
],
|
|
743
|
-
buttonContent: span([], [tab]),
|
|
744
|
-
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')],
|
|
745
776
|
panelContent: Option.match(model.maybeInspectedModel, {
|
|
746
777
|
onNone: () => emptyInspectorView,
|
|
747
778
|
onSome: inspectedModel => inspectorTabContent(model, tab, inspectedModel),
|
|
@@ -750,47 +781,47 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
750
781
|
}),
|
|
751
782
|
]);
|
|
752
783
|
// MESSAGE LIST
|
|
753
|
-
const badgeView = (model) => button([
|
|
754
|
-
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')),
|
|
755
|
-
Style({ width: '22px', height: '56px', fontSize: '10px' }),
|
|
756
|
-
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()),
|
|
757
788
|
], [
|
|
758
789
|
model.isOpen
|
|
759
|
-
? svg([
|
|
760
|
-
AriaHidden(true),
|
|
761
|
-
Xmlns('http://www.w3.org/2000/svg'),
|
|
762
|
-
Fill('none'),
|
|
763
|
-
ViewBox('0 0 24 24'),
|
|
764
|
-
StrokeWidth('1.5'),
|
|
765
|
-
Stroke('currentColor'),
|
|
766
|
-
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' }),
|
|
767
798
|
], [
|
|
768
|
-
path([
|
|
769
|
-
StrokeLinecap('round'),
|
|
770
|
-
StrokeLinejoin('round'),
|
|
771
|
-
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'),
|
|
772
803
|
], []),
|
|
773
804
|
])
|
|
774
|
-
: div([
|
|
775
|
-
Class(clsx('flex flex-col items-center gap-0.5 font-semibold tracking-wider leading-none', model.isPaused ? 'text-dt-bg' : 'text-dt-muted')),
|
|
776
|
-
], [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'])]),
|
|
777
808
|
]);
|
|
778
809
|
const headerClass = 'flex items-center justify-between px-3 py-1.5 border-b shrink-0';
|
|
779
|
-
const actionButtonClass = 'dt-resume-button bg-transparent border-none text-dt-live cursor-pointer text-base font-mono font-medium';
|
|
810
|
+
const actionButtonClass = 'dt-resume-h.button bg-transparent border-none text-dt-live cursor-pointer text-base font-mono font-medium';
|
|
780
811
|
const statusClass = 'text-base font-mono';
|
|
781
|
-
const clearHistoryButton = button([Class(headerButtonClass), OnClick(ClickedClear())], ['Clear history']);
|
|
812
|
+
const clearHistoryButton = h.button([h.Class(headerButtonClass), h.OnClick(ClickedClear())], ['Clear history']);
|
|
782
813
|
const submodelLabel = (tag) => pipe(tag, String_.replace(/^Got/, ''), String_.replace(/Message$/, ''));
|
|
783
814
|
const CHECK_ICON = 'M4.5 12.75l6 6 9-13.5';
|
|
784
|
-
const checkIconView = svg([
|
|
785
|
-
AriaHidden(true),
|
|
786
|
-
Class('dt-filter-check shrink-0'),
|
|
787
|
-
Xmlns('http://www.w3.org/2000/svg'),
|
|
788
|
-
Fill('none'),
|
|
789
|
-
ViewBox('0 0 24 24'),
|
|
790
|
-
StrokeWidth('2'),
|
|
791
|
-
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'),
|
|
792
823
|
], [
|
|
793
|
-
path([D(CHECK_ICON), StrokeLinecap('round'), StrokeLinejoin('round')], []),
|
|
824
|
+
h.path([h.D(CHECK_ICON), h.StrokeLinecap('round'), h.StrokeLinejoin('round')], []),
|
|
794
825
|
]);
|
|
795
826
|
const filterItemLabel = (item) => String_.isNonEmpty(item) ? submodelLabel(item) : 'All Messages';
|
|
796
827
|
const submodelFilterView = (model) => {
|
|
@@ -805,27 +836,27 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
805
836
|
items: [ALL_MESSAGES_VALUE, ...model.submodelTags],
|
|
806
837
|
itemToConfig: item => ({
|
|
807
838
|
className: 'dt-filter-item',
|
|
808
|
-
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)])]),
|
|
809
840
|
}),
|
|
810
|
-
buttonContent: span([Class('flex flex-1 items-center justify-between')], [
|
|
811
|
-
span([], [buttonLabel]),
|
|
812
|
-
svg([
|
|
813
|
-
AriaHidden(true),
|
|
814
|
-
Class('json-arrow shrink-0'),
|
|
815
|
-
Xmlns('http://www.w3.org/2000/svg'),
|
|
816
|
-
Fill('none'),
|
|
817
|
-
ViewBox('0 0 24 24'),
|
|
818
|
-
StrokeWidth('2'),
|
|
819
|
-
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'),
|
|
820
851
|
], [
|
|
821
|
-
path([
|
|
822
|
-
D(CHEVRON_DOWN),
|
|
823
|
-
StrokeLinecap('round'),
|
|
824
|
-
StrokeLinejoin('round'),
|
|
852
|
+
h.path([
|
|
853
|
+
h.D(CHEVRON_DOWN),
|
|
854
|
+
h.StrokeLinecap('round'),
|
|
855
|
+
h.StrokeLinejoin('round'),
|
|
825
856
|
], []),
|
|
826
857
|
]),
|
|
827
858
|
]),
|
|
828
|
-
buttonClassName: 'dt-filter-button',
|
|
859
|
+
buttonClassName: 'dt-filter-h.button',
|
|
829
860
|
itemsClassName: 'dt-filter-items',
|
|
830
861
|
className: 'dt-filter-wrapper',
|
|
831
862
|
backdropClassName: 'dt-filter-backdrop',
|
|
@@ -834,60 +865,60 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
834
865
|
const headerView = (model) => {
|
|
835
866
|
const { status, maybeAction } = M.value(mode).pipe(M.withReturnType(), M.when('TimeTravel', () => model.isPaused
|
|
836
867
|
? {
|
|
837
|
-
status: span([Class(`${statusClass} text-dt-paused`)], [
|
|
868
|
+
status: h.span([h.Class(`${statusClass} text-dt-paused`)], [
|
|
838
869
|
model.pausedAtIndex === INIT_INDEX
|
|
839
870
|
? 'Paused (init)'
|
|
840
871
|
: `Paused (${model.pausedAtIndex + 1})`,
|
|
841
872
|
]),
|
|
842
|
-
maybeAction: Option.some(button([Class(actionButtonClass), OnClick(ClickedResume())], ['Resume →'])),
|
|
873
|
+
maybeAction: Option.some(h.button([h.Class(actionButtonClass), h.OnClick(ClickedResume())], ['Resume →'])),
|
|
843
874
|
}
|
|
844
875
|
: {
|
|
845
|
-
status: span([Class(`${statusClass} text-dt-live font-medium`)], ['Live']),
|
|
876
|
+
status: h.span([h.Class(`${statusClass} text-dt-live font-medium`)], ['Live']),
|
|
846
877
|
maybeAction: Option.none(),
|
|
847
878
|
}), M.when('Inspect', () => ({
|
|
848
|
-
status: span([Class(`${statusClass} text-dt-accent`)], [
|
|
879
|
+
status: h.span([h.Class(`${statusClass} text-dt-accent`)], [
|
|
849
880
|
model.selectedIndex === INIT_INDEX
|
|
850
881
|
? 'Inspecting (init)'
|
|
851
882
|
: `Inspecting (${model.selectedIndex + 1})`,
|
|
852
883
|
]),
|
|
853
|
-
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 →'])),
|
|
854
885
|
})), M.exhaustive);
|
|
855
|
-
return header([Class(headerClass)], [status, ...Option.toArray(maybeAction), clearHistoryButton]);
|
|
886
|
+
return h.header([h.Class(headerClass)], [status, ...Option.toArray(maybeAction), clearHistoryButton]);
|
|
856
887
|
};
|
|
857
|
-
const initRowView = (isSelected, isPausedHere) => keyed('li')('init', [
|
|
858
|
-
Class(clsx(ROW_BASE, { selected: isSelected })),
|
|
859
|
-
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 })),
|
|
860
891
|
], [
|
|
861
|
-
...OptionExt.when(mode === 'TimeTravel', span([Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
|
|
862
|
-
span([Class('dot-column')], []),
|
|
863
|
-
span([Class(indexClass)], []),
|
|
864
|
-
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']),
|
|
865
896
|
]);
|
|
866
|
-
const pauseIconView = svg([
|
|
867
|
-
AriaHidden(true),
|
|
868
|
-
Class('dt-pause-icon'),
|
|
869
|
-
Xmlns('http://www.w3.org/2000/svg'),
|
|
870
|
-
Fill('none'),
|
|
871
|
-
ViewBox('0 0 24 24'),
|
|
872
|
-
StrokeWidth('2.5'),
|
|
873
|
-
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'),
|
|
874
905
|
], [
|
|
875
|
-
path([
|
|
876
|
-
StrokeLinecap('round'),
|
|
877
|
-
StrokeLinejoin('round'),
|
|
878
|
-
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'),
|
|
879
910
|
], []),
|
|
880
911
|
]);
|
|
881
|
-
const messageRowView = (tag, absoluteIndex, isSelected, isPausedHere, timeDelta, isModelChanged) => keyed('li')(String(absoluteIndex), [
|
|
882
|
-
Class(clsx(ROW_BASE, { selected: isSelected })),
|
|
883
|
-
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 })),
|
|
884
915
|
], [
|
|
885
|
-
...OptionExt.when(mode === 'TimeTravel', span([Class('pause-column')], isPausedHere ? [pauseIconView] : [])).pipe(Option.toArray),
|
|
886
|
-
span([Class('dot-column')], isModelChanged ? [inlineDiffDotView] : []),
|
|
887
|
-
span([Class(indexClass)], [String(absoluteIndex + 1)]),
|
|
888
|
-
span([Class('text-base text-dt font-mono flex-1 truncate')], [tag]),
|
|
889
|
-
span([
|
|
890
|
-
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'),
|
|
891
922
|
], [formatTimeDelta(timeDelta)]),
|
|
892
923
|
]);
|
|
893
924
|
const messageListBody = (entries, startIndex, selectedIndex, isPaused, pausedAtIndex, maybeFilterTag) => {
|
|
@@ -918,7 +949,7 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
918
949
|
entry.isModelChanged,
|
|
919
950
|
]);
|
|
920
951
|
}), Array_.reverse);
|
|
921
|
-
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
|
|
922
953
|
? messageRows
|
|
923
954
|
: [
|
|
924
955
|
...messageRows,
|
|
@@ -941,15 +972,15 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
941
972
|
]);
|
|
942
973
|
};
|
|
943
974
|
// PANEL
|
|
944
|
-
const panelView = (model) => keyed('div')('dt-panel', [
|
|
945
|
-
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])),
|
|
946
977
|
], [
|
|
947
|
-
...Option.map(maybeBanner, banner => div([
|
|
948
|
-
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'),
|
|
949
980
|
], [banner])).pipe(Option.toArray),
|
|
950
981
|
headerView(model),
|
|
951
|
-
div([Class('flex flex-1 min-h-0 dt-content')], [
|
|
952
|
-
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')], [
|
|
953
984
|
...Array_.match(model.submodelTags, {
|
|
954
985
|
onEmpty: () => [],
|
|
955
986
|
onNonEmpty: () => [submodelFilterView(model)],
|
|
@@ -959,10 +990,10 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
959
990
|
inspectorPaneView(model),
|
|
960
991
|
]),
|
|
961
992
|
]);
|
|
962
|
-
const interactionBlocker = div([Class('dt-interaction-blocker')], []);
|
|
993
|
+
const interactionBlocker = h.div([h.Class('dt-interaction-blocker')], []);
|
|
963
994
|
return (model) => ({
|
|
964
995
|
title: 'Foldkit DevTools',
|
|
965
|
-
body: div([], [
|
|
996
|
+
body: h.div([], [
|
|
966
997
|
...OptionExt.when(model.isPaused && mode === 'TimeTravel', interactionBlocker).pipe(Option.toArray),
|
|
967
998
|
...OptionExt.when(model.isOpen, panelView(model)).pipe(Option.toArray),
|
|
968
999
|
badgeView(model),
|
|
@@ -970,7 +1001,6 @@ const makeView = (position, mode, maybeBanner) => {
|
|
|
970
1001
|
});
|
|
971
1002
|
};
|
|
972
1003
|
// CREATE
|
|
973
|
-
const DEVTOOLS_HOST_ID = 'foldkit-devtools';
|
|
974
1004
|
const createShadowContainer = () => {
|
|
975
1005
|
const existingHost = document.getElementById(DEVTOOLS_HOST_ID);
|
|
976
1006
|
if (existingHost) {
|
|
@@ -978,6 +1008,14 @@ const createShadowContainer = () => {
|
|
|
978
1008
|
}
|
|
979
1009
|
const host = document.createElement('div');
|
|
980
1010
|
host.id = DEVTOOLS_HOST_ID;
|
|
1011
|
+
host.addEventListener('pointerdown', event => {
|
|
1012
|
+
const activeElement = document.activeElement;
|
|
1013
|
+
if (activeElement !== null &&
|
|
1014
|
+
activeElement !== host &&
|
|
1015
|
+
activeElement !== document.body) {
|
|
1016
|
+
event.preventDefault();
|
|
1017
|
+
}
|
|
1018
|
+
}, { capture: true });
|
|
981
1019
|
document.body.appendChild(host);
|
|
982
1020
|
const shadow = host.attachShadow({ mode: 'open' });
|
|
983
1021
|
const styleElement = document.createElement('style');
|