@solidjs/start 2.0.3 → 2.0.4

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 (44) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/shared/dev-toolbar/error-viewer/CodeView.jsx +9 -4
  3. package/dist/shared/dev-toolbar/error-viewer/create-stack-frame.d.ts +2 -1
  4. package/dist/shared/dev-toolbar/error-viewer/create-stack-frame.js +29 -19
  5. package/dist/shared/dev-toolbar/error-viewer/get-source-map.d.ts +2 -2
  6. package/dist/shared/dev-toolbar/error-viewer/get-source-map.js +3 -2
  7. package/dist/shared/dev-toolbar/error-viewer/index.jsx +52 -35
  8. package/dist/shared/dev-toolbar/error-viewer/styles.css +91 -43
  9. package/dist/shared/dev-toolbar/functions/BlobViewer.css +50 -2
  10. package/dist/shared/dev-toolbar/functions/BlobViewer.jsx +23 -4
  11. package/dist/shared/dev-toolbar/functions/FormDataViewer.jsx +9 -6
  12. package/dist/shared/dev-toolbar/functions/HeadersViewer.css +0 -4
  13. package/dist/shared/dev-toolbar/functions/HeadersViewer.jsx +9 -7
  14. package/dist/shared/dev-toolbar/functions/HexViewer.css +36 -17
  15. package/dist/shared/dev-toolbar/functions/HexViewer.jsx +7 -6
  16. package/dist/shared/dev-toolbar/functions/SerovalValue.css +21 -0
  17. package/dist/shared/dev-toolbar/functions/SerovalValue.d.ts +1 -0
  18. package/dist/shared/dev-toolbar/functions/SerovalValue.jsx +4 -2
  19. package/dist/shared/dev-toolbar/functions/SerovalViewer.css +98 -36
  20. package/dist/shared/dev-toolbar/functions/SerovalViewer.jsx +268 -279
  21. package/dist/shared/dev-toolbar/functions/URLSearchParamsViewer.jsx +9 -6
  22. package/dist/shared/dev-toolbar/functions/index.jsx +96 -69
  23. package/dist/shared/dev-toolbar/functions/styles.css +143 -10
  24. package/dist/shared/dev-toolbar/index.css +54 -14
  25. package/dist/shared/dev-toolbar/index.jsx +8 -1
  26. package/dist/shared/ui/Badge.css +21 -10
  27. package/dist/shared/ui/Button.css +7 -6
  28. package/dist/shared/ui/IconButton.css +16 -10
  29. package/dist/shared/ui/Placeholder.css +2 -0
  30. package/dist/shared/ui/Section.css +42 -3
  31. package/dist/shared/ui/Section.d.ts +3 -1
  32. package/dist/shared/ui/Section.jsx +14 -6
  33. package/dist/shared/ui/Select.css +11 -4
  34. package/dist/shared/ui/Tabs.css +30 -16
  35. package/package.json +5 -5
  36. package/dist/shared/ui/Cascade.css +0 -29
  37. package/dist/shared/ui/Cascade.d.ts +0 -4
  38. package/dist/shared/ui/Cascade.jsx +0 -4
  39. package/dist/shared/ui/Dialog.css +0 -25
  40. package/dist/shared/ui/Dialog.d.ts +0 -5
  41. package/dist/shared/ui/Dialog.jsx +0 -5
  42. package/dist/shared/ui/Table.css +0 -22
  43. package/dist/shared/ui/Table.d.ts +0 -11
  44. package/dist/shared/ui/Table.jsx +0 -13
@@ -1,7 +1,5 @@
1
- import { createEffect, createSignal, For, Show, splitProps } from "solid-js";
1
+ import { createEffect, createSignal, For, Show } from "solid-js";
2
2
  import { Badge } from "../../ui/Badge.jsx";
3
- import { Cascade, CascadeOption } from "../../ui/Cascade.jsx";
4
- import { Section } from "../../ui/Section.jsx";
5
3
  import { HexViewer } from "./HexViewer.jsx";
6
4
  import { PropertySeparator, SerovalValue } from "./SerovalValue.jsx";
7
5
  import { SerovalChunkReader } from "../../../fns/serialization.js";
@@ -125,7 +123,7 @@ function getNodeType(node) {
125
123
  case 35:
126
124
  return "Sequence";
127
125
  }
128
- throw new Error("unsupported node type");
126
+ return "unknown";
129
127
  }
130
128
  function traverse(node, handler) {
131
129
  handler(node);
@@ -365,335 +363,320 @@ function getStreamKeyword(t) {
365
363
  return "return";
366
364
  }
367
365
  }
368
- function renderSerovalNode(ctx, node, onSelect, inner) {
369
- if (node.t >= 4 &&
370
- (inner || node.t === 4) &&
371
- node.i != null &&
372
- !(node.t === 5 || node.t === 6 || node.t === 17)) {
366
+ const PREVIEW_LENGTH = 32;
367
+ const PREVIEW_KEYS = 3;
368
+ function truncate(value) {
369
+ if (value.length > PREVIEW_LENGTH) {
370
+ return `${value.slice(0, PREVIEW_LENGTH)}…`;
371
+ }
372
+ return value;
373
+ }
374
+ function previewNode(ctx, node, depth) {
375
+ switch (node.t) {
376
+ case 0:
377
+ return `${node.s}`;
378
+ case 1:
379
+ return truncate(`"${node.s}"`);
380
+ case 2:
381
+ return getConstantValue(node.s);
382
+ case 3:
383
+ return `${node.s}n`;
384
+ case 4: {
385
+ if (depth >= 1) {
386
+ return `#${node.i}`;
387
+ }
388
+ const target = ctx.getNode(node.i);
389
+ return target ? previewNode(ctx, target, depth + 1) : `#${node.i}`;
390
+ }
391
+ case 5:
392
+ return truncate(`${node.s}`);
393
+ case 6:
394
+ return truncate(`/${node.c}/${node.m}`);
395
+ case 7:
396
+ return `Set(${node.a.length})`;
397
+ case 8:
398
+ return `Map(${node.e.k.length})`;
399
+ case 9:
400
+ return `Array(${node.a.length})`;
401
+ case 10:
402
+ case 11: {
403
+ if (depth >= 1) {
404
+ return "{…}";
405
+ }
406
+ const keys = node.p.k.filter(key => typeof key === "string").slice(0, PREVIEW_KEYS);
407
+ const rest = node.p.k.length > keys.length ? ", …" : "";
408
+ return keys.length ? `{${keys.join(", ")}${rest}}` : "{}";
409
+ }
410
+ case 12:
411
+ return "Promise";
412
+ case 13:
413
+ case 14:
414
+ return truncate(`${getNodeType(node)}: ${node.m}`);
415
+ case 15:
416
+ case 16:
417
+ return `${node.c}(${node.l})`;
418
+ case 17:
419
+ return getSymbolValue(node.s);
420
+ case 19:
421
+ return "ArrayBuffer";
422
+ case 20:
423
+ return `DataView(${node.l})`;
424
+ case 21:
425
+ return previewNode(ctx, node.f, depth);
426
+ case 22: {
427
+ const result = ctx.getPromise(node.s);
428
+ if (result) {
429
+ return `Promise<${result.t === 23 ? "success" : "failure"}>`;
430
+ }
431
+ return "Promise<pending>";
432
+ }
433
+ case 25:
434
+ return `Plugin(${node.c})`;
435
+ case 28:
436
+ return "Iterator";
437
+ case 30:
438
+ return "AsyncIterator";
439
+ case 31:
440
+ return `Stream(${(ctx.getStream(node.i) || []).length})`;
441
+ case 35:
442
+ return `Sequence(${node.a.length})`;
443
+ default:
444
+ return getNodeType(node);
445
+ }
446
+ }
447
+ function EntryKey(props) {
448
+ return (<span data-start-seroval-tree-key>
449
+ <SerovalValue kind={props.kind ?? "key"} value={props.value}/>
450
+ <PropertySeparator />
451
+ </span>);
452
+ }
453
+ function LeafRow(props) {
454
+ return (<div data-start-seroval-tree-node>
455
+ <div data-start-seroval-tree-row>
456
+ <span data-start-seroval-tree-chevron data-leaf="true"/>
457
+ {props.label}
458
+ {props.children}
459
+ </div>
460
+ </div>);
461
+ }
462
+ function ExpandableRow(props) {
463
+ const [open, setOpen] = createSignal(props.open ?? false);
464
+ return (<div data-start-seroval-tree-node>
465
+ <button type="button" data-start-seroval-tree-row data-expanded={open() ? "true" : undefined} onClick={() => setOpen(current => !current)}>
466
+ <span data-start-seroval-tree-chevron/>
467
+ {props.label}
468
+ {props.badges}
469
+ <Show when={!open()}>
470
+ <span data-start-seroval-tree-preview>{props.preview}</span>
471
+ </Show>
472
+ </button>
473
+ <Show when={open()}>
474
+ <div data-start-seroval-tree-children>{props.children}</div>
475
+ </Show>
476
+ </div>);
477
+ }
478
+ function TreeValue(props) {
479
+ const ctx = props.ctx;
480
+ const node = props.node;
481
+ // Indexed reference: resolve reactively, guard cycles
482
+ if (node.t === 4) {
373
483
  const index = node.i;
374
- const description = `id: ${index}`;
375
- const lookup = ctx.getNode(index);
376
- return (<CascadeOption data-start-seroval-link value={index}>
377
- <LinkIcon title={description}/>
378
- <Badge type="info">{getNodeType(lookup)}</Badge>
379
- <Badge type="info">{description}</Badge>
380
- </CascadeOption>);
484
+ if (props.seen.includes(index)) {
485
+ return (<LeafRow label={props.label}>
486
+ <span data-start-seroval-tree-circular>
487
+ <LinkIcon title={`Circular reference to #${index}`}/>
488
+ <Badge type="info">{`circular #${index}`}</Badge>
489
+ </span>
490
+ </LeafRow>);
491
+ }
492
+ return (<Show when={ctx.getNode(index)} keyed fallback={<LeafRow label={props.label}>
493
+ <Badge type="warning">{`#${index} pending`}</Badge>
494
+ </LeafRow>}>
495
+ {target => (<TreeValue ctx={ctx} node={target} seen={props.seen} label={props.label} open={props.open}/>)}
496
+ </Show>);
381
497
  }
498
+ const seen = node.i != null ? [...props.seen, node.i] : props.seen;
499
+ const flag = "o" in node ? getObjectFlag(node.o ?? 0) : "none";
500
+ const badges = (<>
501
+ {node.i != null && <Badge type="info">{`#${node.i}`}</Badge>}
502
+ {flag !== "none" && <Badge type="warning">{flag}</Badge>}
503
+ </>);
382
504
  switch (node.t) {
383
505
  // Number = 0,
384
506
  case 0:
385
- return <SerovalValue value={node.s}/>;
507
+ return (<LeafRow label={props.label}>
508
+ <SerovalValue kind="number" value={node.s}/>
509
+ </LeafRow>);
386
510
  // String = 1,
387
511
  case 1:
388
- return <SerovalValue value={`"${node.s}"`}/>;
512
+ return (<LeafRow label={props.label}>
513
+ <SerovalValue kind="string" value={`"${node.s}"`}/>
514
+ </LeafRow>);
389
515
  // Constant = 2,
390
516
  case 2:
391
- return <SerovalValue value={getConstantValue(node.s)}/>;
517
+ return (<LeafRow label={props.label}>
518
+ <SerovalValue kind="keyword" value={getConstantValue(node.s)}/>
519
+ </LeafRow>);
392
520
  // BigInt = 3,
393
521
  case 3:
394
- return (<div data-start-seroval-link>
395
- <Badge type="info">bigint</Badge>
396
- <SerovalValue value={node.s}/>
397
- </div>);
522
+ return (<LeafRow label={props.label}>
523
+ <SerovalValue kind="number" value={`${node.s}n`}/>
524
+ </LeafRow>);
398
525
  // Date = 5,
399
526
  case 5:
400
- return (<div data-start-seroval-link>
527
+ return (<LeafRow label={props.label}>
401
528
  <Badge type="info">Date</Badge>
402
- <SerovalValue value={node.s}/>
403
- </div>);
529
+ <SerovalValue kind="string" value={node.s}/>
530
+ </LeafRow>);
404
531
  // RegExp = 6,
405
532
  case 6:
406
- return (<div data-start-seroval-link>
533
+ return (<LeafRow label={props.label}>
407
534
  <Badge type="info">RegExp</Badge>
408
- <SerovalValue value={`/${node.c}/${node.m}`}/>
409
- </div>);
535
+ <SerovalValue kind="string" value={`/${node.c}/${node.m}`}/>
536
+ </LeafRow>);
537
+ // WKSymbol = 17,
538
+ case 17:
539
+ return (<LeafRow label={props.label}>
540
+ <SerovalValue kind="keyword" value={getSymbolValue(node.s)}/>
541
+ </LeafRow>);
410
542
  // Set = 7,
411
543
  case 7:
412
- return (<>
413
- <Section title="Information" options={{ size: "xs" }}>
414
- <div data-start-property>
415
- <SerovalValue value="size"/>
416
- <PropertySeparator />
417
- <SerovalValue value={`${node.a.length}`}/>
418
- </div>
419
- </Section>
420
- <Section title="Items" options={{ size: "xs" }}>
421
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
422
- <For each={node.a.map((node, index) => [index, node])}>
423
- {([key, value]) => (<div data-start-property>
424
- <SerovalValue value={key}/>
425
- <PropertySeparator />
426
- {renderSerovalNode(ctx, value, onSelect, true)}
427
- </div>)}
428
- </For>
429
- </Cascade>
430
- </Section>
431
- </>);
544
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
545
+ <For each={node.a}>
546
+ {(child, index) => (<TreeValue ctx={ctx} node={child} seen={seen} label={<EntryKey kind="number" value={index()}/>}/>)}
547
+ </For>
548
+ </ExpandableRow>);
432
549
  // Map = 8,
433
550
  case 8:
434
- return (<>
435
- <Section title="Information" options={{ size: "xs" }}>
436
- <div data-start-property>
437
- <SerovalValue value="size"/>
438
- <PropertySeparator />
439
- <SerovalValue value={`${node.e.k.length}`}/>
440
- </div>
441
- </Section>
442
- <Section title="Items" options={{ size: "xs" }}>
443
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
444
- <For each={zip(node.e.k, node.e.v)} fallback={<SerovalValue value="none"/>}>
445
- {([key, value]) => (<div data-start-property>
446
- {renderSerovalNode(ctx, key, onSelect, true)}
447
- <PropertySeparator />
448
- {renderSerovalNode(ctx, value, onSelect, true)}
449
- </div>)}
450
- </For>
451
- </Cascade>
452
- </Section>
453
- </>);
551
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
552
+ <For each={zip(node.e.k, node.e.v)}>
553
+ {([key, value], index) => (<ExpandableRow label={<EntryKey kind="number" value={index()}/>} preview={`{${previewNode(ctx, key, 1)} => ${previewNode(ctx, value, 1)}}`}>
554
+ <TreeValue ctx={ctx} node={key} seen={seen} label={<EntryKey kind="keyword" value="key"/>}/>
555
+ <TreeValue ctx={ctx} node={value} seen={seen} label={<EntryKey kind="keyword" value="value"/>}/>
556
+ </ExpandableRow>)}
557
+ </For>
558
+ </ExpandableRow>);
454
559
  // Array = 9,
455
560
  case 9:
456
- return (<>
457
- <Section title="Information" options={{ size: "xs" }}>
458
- <div data-start-property>
459
- <SerovalValue value="length"/>
460
- <PropertySeparator />
461
- <SerovalValue value={`${node.a.length}`}/>
462
- </div>
463
- <div data-start-property>
464
- <SerovalValue value="state"/>
465
- <PropertySeparator />
466
- <Badge type="info">{getObjectFlag(node.o)}</Badge>
467
- </div>
468
- </Section>
469
- <Section title="Items" options={{ size: "xs" }}>
470
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
471
- <For each={node.a.map((node, index) => [index, node])} fallback={<SerovalValue value="none"/>}>
472
- {([key, value]) => (<div data-start-property>
473
- <SerovalValue value={key}/>
474
- <PropertySeparator />
475
- {value === 0 ? (<SerovalValue value="empty"/>) : (renderSerovalNode(ctx, value, onSelect, true))}
476
- </div>)}
477
- </For>
478
- </Cascade>
479
- </Section>
480
- </>);
561
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
562
+ <For each={node.a}>
563
+ {(child, index) => child === 0 ? (<LeafRow label={<EntryKey kind="number" value={index()}/>}>
564
+ <SerovalValue kind="keyword" value="empty"/>
565
+ </LeafRow>) : (<TreeValue ctx={ctx} node={child} seen={seen} label={<EntryKey kind="number" value={index()}/>}/>)}
566
+ </For>
567
+ </ExpandableRow>);
481
568
  // Object = 10,
482
569
  case 10:
483
570
  // NullConstructor = 11,
484
571
  case 11:
485
- return (<>
486
- <Section title="Information" options={{ size: "xs" }}>
487
- <div data-start-property>
488
- <SerovalValue value="size"/>
489
- <PropertySeparator />
490
- <SerovalValue value={`${node.p.k.length}`}/>
491
- </div>
492
- <div data-start-property>
493
- <SerovalValue value="state"/>
494
- <PropertySeparator />
495
- <Badge type="info">{getObjectFlag(node.o)}</Badge>
496
- </div>
497
- </Section>
498
- <Section title="Properties" options={{ size: "xs" }}>
499
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
500
- <For each={zip(node.p.k, node.p.v)} fallback={<SerovalValue value="none"/>}>
501
- {([key, value]) => (<div data-start-property>
502
- {typeof key === "string" ? (<SerovalValue value={`"${key}"`}/>) : (renderSerovalNode(ctx, key, onSelect, true))}
503
- <PropertySeparator />
504
- {renderSerovalNode(ctx, value, onSelect, true)}
505
- </div>)}
506
- </For>
507
- </Cascade>
508
- </Section>
509
- </>);
572
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
573
+ <For each={zip(node.p.k, node.p.v)}>
574
+ {([key, value]) => (<TreeValue ctx={ctx} node={value} seen={seen} label={<EntryKey value={typeof key === "string" ? key : previewNode(ctx, key, 1)}/>}/>)}
575
+ </For>
576
+ </ExpandableRow>);
510
577
  // Promise = 12,
511
578
  case 12:
512
- return (<Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
513
- {renderSerovalNode(ctx, node.f, onSelect, true)}
514
- </Cascade>);
579
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
580
+ <TreeValue ctx={ctx} node={node.f} seen={seen} label={<EntryKey kind="keyword" value="value"/>}/>
581
+ </ExpandableRow>);
515
582
  // Error = 13,
516
583
  case 13:
517
584
  // AggregateError = 14,
518
585
  case 14:
519
- return (<>
520
- <Section title="Information" options={{ size: "xs" }}>
521
- <div data-start-property>
522
- <SerovalValue value="message"/>
523
- <PropertySeparator />
524
- <SerovalValue value={`"${node.m}"`}/>
525
- </div>
526
- </Section>
586
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
587
+ <LeafRow label={<EntryKey kind="keyword" value="message"/>}>
588
+ <SerovalValue kind="string" value={`"${node.m}"`}/>
589
+ </LeafRow>
527
590
  <Show when={node.p}>
528
- {current => (<Section title="Properties" options={{ size: "xs" }}>
529
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
530
- <For each={zip(current().k, current().v)} fallback={<SerovalValue value="none"/>}>
531
- {([key, value]) => (<div data-start-property>
532
- {typeof key === "string" ? (<SerovalValue value={`"${key}"`}/>) : (renderSerovalNode(ctx, key, onSelect, true))}
533
- <PropertySeparator />
534
- {renderSerovalNode(ctx, value, onSelect, true)}
535
- </div>)}
536
- </For>
537
- </Cascade>
538
- </Section>)}
591
+ {properties => (<For each={zip(properties().k, properties().v)}>
592
+ {([key, value]) => (<TreeValue ctx={ctx} node={value} seen={seen} label={<EntryKey value={typeof key === "string" ? key : previewNode(ctx, key, 1)}/>}/>)}
593
+ </For>)}
539
594
  </Show>
540
- </>);
541
- // WKSymbol = 17,
542
- case 17:
543
- return <SerovalValue value={getSymbolValue(node.s)}/>;
544
- // Reference = 18,
545
- case 18:
546
- break;
547
- // ArrayBuffer = 19,
548
- case 19: {
549
- const data = atob(node.s);
550
- const result = new TextEncoder().encode(data);
551
- return <HexViewer bytes={result}/>;
552
- }
595
+ </ExpandableRow>);
553
596
  // TypedArray = 15,
554
597
  case 15:
555
598
  // BigIntTypedArray = 16,
556
599
  case 16:
557
600
  // DataView = 20,
558
601
  case 20:
559
- return (<>
560
- <Section title="Information" options={{ size: "xs" }}>
561
- <div data-start-property>
562
- <SerovalValue value="byteLength"/>
563
- <PropertySeparator />
564
- <SerovalValue value={node.l}/>
565
- </div>
566
- <div data-start-property>
567
- <SerovalValue value="byteOffset"/>
568
- <PropertySeparator />
569
- <SerovalValue value={node.b}/>
570
- </div>
571
- </Section>
572
- <Section title="Buffer" options={{ size: "xs" }}>
573
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
574
- {renderSerovalNode(ctx, node.f, onSelect, true)}
575
- </Cascade>
576
- </Section>
577
- </>);
602
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
603
+ <LeafRow label={<EntryKey kind="keyword" value="byteLength"/>}>
604
+ <SerovalValue kind="number" value={node.l}/>
605
+ </LeafRow>
606
+ <LeafRow label={<EntryKey kind="keyword" value="byteOffset"/>}>
607
+ <SerovalValue kind="number" value={node.b}/>
608
+ </LeafRow>
609
+ <TreeValue ctx={ctx} node={node.f} seen={seen} label={<EntryKey kind="keyword" value="buffer"/>}/>
610
+ </ExpandableRow>);
611
+ // ArrayBuffer = 19,
612
+ case 19:
613
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
614
+ <div data-start-seroval-tree-raw>
615
+ {(() => {
616
+ const data = atob(node.s);
617
+ const result = new TextEncoder().encode(data);
618
+ return <HexViewer bytes={result}/>;
619
+ })()}
620
+ </div>
621
+ </ExpandableRow>);
578
622
  // Boxed = 21,
579
623
  case 21:
580
- return (<Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
581
- {renderSerovalNode(ctx, node.f, onSelect, true)}
582
- </Cascade>);
624
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
625
+ <TreeValue ctx={ctx} node={node.f} seen={seen} label={<EntryKey kind="keyword" value="value"/>}/>
626
+ </ExpandableRow>);
627
+ // PromiseConstructor = 22,
583
628
  case 22:
584
- return (<>
585
- {(() => {
586
- const result = ctx.getPromise(node.s);
587
- if (result) {
588
- const status = result.t === 23 ? "success" : "failure";
589
- return (<Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
590
- <div data-start-property>
591
- <SerovalValue value="status"/>
592
- <PropertySeparator />
593
- <Badge type={status}>{status}</Badge>
594
- </div>
595
- <span data-start-property>
596
- <SerovalValue value="value"/>
597
- <PropertySeparator />
598
- {renderSerovalNode(ctx, result.a[1], onSelect, true)}
599
- </span>
600
- </Cascade>);
601
- }
602
- return <Badge type="warning">pending</Badge>;
603
- })()}
604
- </>);
605
- // Plugin = 25
629
+ return (<ExpandableRow label={props.label} badges={badges} preview={<>{previewNode(ctx, node, 0)}</>} open={props.open}>
630
+ <Show when={ctx.getPromise(node.s)} keyed fallback={<LeafRow label={<EntryKey kind="keyword" value="status"/>}>
631
+ <Badge type="warning">pending</Badge>
632
+ </LeafRow>}>
633
+ {result => (<>
634
+ <LeafRow label={<EntryKey kind="keyword" value="status"/>}>
635
+ <Badge type={result.t === 23 ? "success" : "failure"}>
636
+ {result.t === 23 ? "success" : "failure"}
637
+ </Badge>
638
+ </LeafRow>
639
+ <TreeValue ctx={ctx} node={result.a[1]} seen={seen} label={<EntryKey kind="keyword" value="value"/>}/>
640
+ </>)}
641
+ </Show>
642
+ </ExpandableRow>);
643
+ // Plugin = 25,
606
644
  case 25:
607
- return (<>
608
- <Section title="Information" options={{ size: "xs" }}>
609
- <div data-start-property>
610
- <SerovalValue value="plugin"/>
611
- <PropertySeparator />
612
- <SerovalValue value={node.c}/>
613
- </div>
614
- </Section>
615
- <Section title="Properties" options={{ size: "xs" }}>
616
- <Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
617
- <For each={Object.entries(node.s)} fallback={<SerovalValue value="none"/>}>
618
- {([key, value]) => (<div data-start-property>
619
- <SerovalValue value={key}/>
620
- <PropertySeparator />
621
- {renderSerovalNode(ctx, value, onSelect, true)}
622
- </div>)}
623
- </For>
624
- </Cascade>
625
- </Section>
626
- </>);
627
- // IteratorFactory = 27,
628
- case 27:
629
- break;
645
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
646
+ <For each={Object.entries(node.s)}>
647
+ {([key, value]) => (<TreeValue ctx={ctx} node={value} seen={seen} label={<EntryKey value={key}/>}/>)}
648
+ </For>
649
+ </ExpandableRow>);
630
650
  // IteratorFactoryInstance = 28,
631
651
  case 28:
632
- return renderSerovalNode(ctx, node.a[1], onSelect, true);
633
- // AsyncIteratorFactory = 29,
634
- case 29:
635
- break;
636
652
  // AsyncIteratorFactoryInstance = 30,
637
653
  case 30:
638
- return renderSerovalNode(ctx, node.a[1], onSelect, true);
654
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
655
+ <TreeValue ctx={ctx} node={node.a[1]} seen={seen} label={<EntryKey kind="keyword" value="values"/>}/>
656
+ </ExpandableRow>);
639
657
  // StreamConstructor = 31,
640
658
  case 31:
641
- return (<>
642
- {(() => {
643
- const result = ctx.getStream(node.i) || [];
644
- return (<Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
645
- <For each={result} fallback={<SerovalValue value="none"/>}>
646
- {current => (<div data-start-property>
647
- <SerovalValue value={getStreamKeyword(current.t)}/>
648
- <PropertySeparator />
649
- {renderSerovalNode(ctx, current.f, onSelect, true)}
650
- </div>)}
651
- </For>
652
- </Cascade>);
653
- })()}
654
- </>);
659
+ return (<ExpandableRow label={props.label} badges={badges} preview={<>{previewNode(ctx, node, 0)}</>} open={props.open}>
660
+ <For each={ctx.getStream(node.i) || []} fallback={<LeafRow label={<EntryKey kind="keyword" value="status"/>}>
661
+ <Badge type="warning">waiting</Badge>
662
+ </LeafRow>}>
663
+ {chunk => (<TreeValue ctx={ctx} node={chunk.f} seen={seen} label={<EntryKey kind="keyword" value={getStreamKeyword(chunk.t)}/>}/>)}
664
+ </For>
665
+ </ExpandableRow>);
655
666
  case 35:
656
- return (<Cascade data-start-properties defaultValue={undefined} onChange={onSelect}>
657
- <For each={node.a} fallback={<SerovalValue value="none"/>}>
658
- {(current, index) => (<div data-start-property>
659
- <SerovalValue value={index() === node.l ? "return" : index() === node.s ? "throw" : "next"}/>
660
- <PropertySeparator />
661
- {renderSerovalNode(ctx, current, onSelect, true)}
662
- </div>)}
667
+ return (<ExpandableRow label={props.label} badges={badges} preview={previewNode(ctx, node, 0)} open={props.open}>
668
+ <For each={node.a}>
669
+ {(child, index) => (<Show when={child}>
670
+ {current => (<TreeValue ctx={ctx} node={current()} seen={seen} label={<EntryKey kind="keyword" value={index() === node.l ? "return" : index() === node.s ? "throw" : "next"}/>}/>)}
671
+ </Show>)}
663
672
  </For>
664
- </Cascade>);
673
+ </ExpandableRow>);
674
+ default:
675
+ return (<LeafRow label={props.label}>
676
+ <Badge type="warning">{getNodeType(node)}</Badge>
677
+ </LeafRow>);
665
678
  }
666
679
  }
667
- function SerovalNodeRenderer(props) {
668
- const [, rest] = splitProps(props, ["node"]);
669
- const [next, setNext] = createSignal();
670
- function onSelect(index) {
671
- if (index == null) {
672
- setNext(undefined);
673
- }
674
- else {
675
- setNext(props.getNode(index));
676
- }
677
- }
678
- return (<>
679
- <div data-start-seroval-node>
680
- <div data-start-seroval-node-header>
681
- <Badge type="info">{getNodeType(props.node)}</Badge>
682
- {props.node.i != null && <Badge type="info">{`id: ${props.node.i}`}</Badge>}
683
- </div>
684
- <div data-start-seroval-node-content>{renderSerovalNode(props, props.node, onSelect)}</div>
685
- </div>
686
- <Show when={next()} keyed>
687
- {current => <SerovalNodeRenderer node={current} {...rest}/>}
688
- </Show>
689
- </>);
690
- }
691
- function SerovalRenderer(props) {
692
- const [, rest] = splitProps(props, ["node"]);
693
- return (<div data-start-seroval-renderer>
694
- <Show when={props.node}>{current => <SerovalNodeRenderer node={current()} {...rest}/>}</Show>
695
- </div>);
696
- }
697
680
  function createSimpleStore(initial) {
698
681
  const [state, setState] = createSignal(initial);
699
682
  return {
@@ -791,6 +774,12 @@ export function SerovalViewer(props) {
791
774
  }
792
775
  });
793
776
  return (<div data-start-seroval-viewer>
794
- <SerovalRenderer node={selected()} getNode={index => references.read(index)} getPromise={index => promises.read(index)} getStream={index => streams.read(index)}/>
777
+ <Show when={selected()} keyed>
778
+ {root => (<TreeValue ctx={{
779
+ getNode: index => references.read(index),
780
+ getPromise: index => promises.read(index),
781
+ getStream: index => streams.read(index),
782
+ }} node={root} seen={[]} open/>)}
783
+ </Show>
795
784
  </div>);
796
785
  }