atom.io 0.33.12 → 0.33.14

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 (45) hide show
  1. package/dist/data/index.js.map +1 -1
  2. package/dist/eslint-plugin/index.js.map +1 -1
  3. package/dist/internal/index.js +25 -23
  4. package/dist/internal/index.js.map +1 -1
  5. package/dist/introspection/index.d.ts +7 -7
  6. package/dist/introspection/index.d.ts.map +1 -1
  7. package/dist/introspection/index.js +26 -38
  8. package/dist/introspection/index.js.map +1 -1
  9. package/dist/json/index.js.map +1 -1
  10. package/dist/main/index.js +11 -11
  11. package/dist/main/index.js.map +1 -1
  12. package/dist/react/index.js.map +1 -1
  13. package/dist/react-devtools/index.css +182 -96
  14. package/dist/react-devtools/index.css.map +1 -1
  15. package/dist/react-devtools/index.d.ts +1 -0
  16. package/dist/react-devtools/index.d.ts.map +1 -1
  17. package/dist/react-devtools/index.js +177 -81
  18. package/dist/react-devtools/index.js.map +1 -1
  19. package/dist/realtime/index.js.map +1 -1
  20. package/dist/realtime-client/index.js.map +1 -1
  21. package/dist/realtime-react/index.js.map +1 -1
  22. package/dist/realtime-server/index.js.map +1 -1
  23. package/dist/realtime-testing/index.js.map +1 -1
  24. package/dist/transceivers/set-rtx/index.js.map +1 -1
  25. package/dist/use-o-BrXc7Qro.js.map +1 -1
  26. package/dist/web/index.js.map +1 -1
  27. package/package.json +10 -10
  28. package/src/internal/transaction/create-transaction.ts +9 -5
  29. package/src/introspection/attach-atom-index.ts +6 -15
  30. package/src/introspection/attach-introspection-states.ts +5 -5
  31. package/src/introspection/attach-selector-index.ts +78 -85
  32. package/src/introspection/attach-timeline-index.ts +5 -12
  33. package/src/introspection/attach-transaction-index.ts +18 -16
  34. package/src/introspection/auditor.ts +2 -3
  35. package/src/react-devtools/Button.tsx +12 -4
  36. package/src/react-devtools/StateEditor.tsx +13 -1
  37. package/src/react-devtools/StateIndex.tsx +83 -39
  38. package/src/react-devtools/TimelineIndex.tsx +16 -12
  39. package/src/react-devtools/TransactionIndex.tsx +22 -18
  40. package/src/react-devtools/devtools.css +182 -96
  41. package/src/react-devtools/json-editor/developer-interface.tsx +2 -1
  42. package/src/react-devtools/json-editor/editors-by-type/array-editor.tsx +23 -20
  43. package/src/react-devtools/json-editor/editors-by-type/object-editor.tsx +7 -23
  44. package/src/react-devtools/json-editor/json-editor-internal.tsx +94 -77
  45. package/src/react-devtools/store.ts +97 -6
@@ -1,22 +1,25 @@
1
1
  import { useI, useO } from "../use-o-BrXc7Qro.js";
2
- import { IMPLICIT, become, createAtomFamily, createStandaloneAtom, findInStore } from "atom.io/internal";
2
+ import { IMPLICIT, actUponStore, arbitrary, become, createAtomFamily, createStandaloneAtom, createTransaction, disposeFromStore, findInStore, getFromStore } from "atom.io/internal";
3
3
  import { JSON_DEFAULTS, fromEntries, isJson, stringifyJson, toEntries } from "atom.io/json";
4
- import { getState, redo, undo } from "atom.io";
4
+ import { redo, undo } from "atom.io";
5
5
  import { Component, Fragment, createContext, forwardRef, useContext, useId, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
6
6
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
7
  import { StoreContext, useI as useI$1, useO as useO$1 } from "atom.io/react";
8
8
  import { LayoutGroup, motion } from "motion/react";
9
- import { attachIntrospectionStates, discoverType, jsonRefinery, prettyJson, primitiveRefinery } from "atom.io/introspection";
9
+ import { attachIntrospectionStates, discoverType, isPlainObject, jsonRefinery, prettyJson, primitiveRefinery } from "atom.io/introspection";
10
10
  import { persistSync } from "atom.io/web";
11
11
 
12
12
  //#region src/react-devtools/Button.tsx
13
- const OpenClose = ({ isOpen, setIsOpen, disabled, testid }) => {
13
+ const OpenClose = ({ isOpen, setIsOpen, onShiftClick, disabled, testid }) => {
14
14
  return /* @__PURE__ */ jsx("button", {
15
15
  type: "button",
16
16
  "data-testid": testid,
17
17
  className: `carat ${isOpen ? `open` : `closed`}`,
18
- onClick: () => {
19
- setIsOpen((prev) => !prev);
18
+ onClick: (event) => {
19
+ if (onShiftClick && event.shiftKey) {
20
+ if (!onShiftClick(event)) return;
21
+ }
22
+ setIsOpen?.((prev) => !prev);
20
23
  },
21
24
  disabled,
22
25
  children: /* @__PURE__ */ jsx("span", {
@@ -189,7 +192,52 @@ function attachDevtoolsStates(store) {
189
192
  const viewIsOpenAtoms = createAtomFamily(store, {
190
193
  key: `🔍 Devtools View Is Open`,
191
194
  default: false,
192
- effects: (key) => typeof window === `undefined` ? [] : [persistSync(window.localStorage, JSON, key + `:view-is-open`)]
195
+ effects: (key) => typeof window === `undefined` ? [] : [persistSync(window.localStorage, JSON, `view-is-open:${key.join()}`)]
196
+ });
197
+ const openCloseAllTX = createTransaction(store, {
198
+ key: `🔍 Open Close All`,
199
+ do: ({ get, set }, path, current) => {
200
+ const currentView = get(devtoolsViewSelectionState);
201
+ let states;
202
+ switch (currentView) {
203
+ case `atoms`:
204
+ states = get(introspectionStates.atomIndex);
205
+ break;
206
+ case `selectors`:
207
+ states = get(introspectionStates.selectorIndex);
208
+ break;
209
+ case `transactions`:
210
+ case `timelines`: return;
211
+ }
212
+ switch (path.length) {
213
+ case 1:
214
+ for (const [key] of states) set(viewIsOpenAtoms, [key], !current);
215
+ break;
216
+ default: {
217
+ const item = states.get(path[0]);
218
+ let value;
219
+ let segments;
220
+ if (item) {
221
+ if (`familyMembers` in item) {
222
+ if (path.length === 2) {
223
+ for (const [subKey] of item.familyMembers) set(viewIsOpenAtoms, [path[0], subKey], !current);
224
+ return;
225
+ }
226
+ const token = item.familyMembers.get(path[1]);
227
+ value = get(token);
228
+ segments = path.slice(2, -1);
229
+ } else {
230
+ value = get(item);
231
+ segments = path.slice(1, -1);
232
+ }
233
+ for (const segment of segments) if (value && typeof value === `object`) value = value[segment];
234
+ const head = path.slice(0, -1);
235
+ if (Array.isArray(value)) for (let i = 0; i < value.length; i++) set(viewIsOpenAtoms, [...head, i], !current);
236
+ else if (isPlainObject(value)) for (const key of Object.keys(value)) set(viewIsOpenAtoms, [...head, key], !current);
237
+ }
238
+ }
239
+ }
240
+ }
193
241
  });
194
242
  return {
195
243
  ...introspectionStates,
@@ -197,6 +245,7 @@ function attachDevtoolsStates(store) {
197
245
  devtoolsViewSelectionState,
198
246
  devtoolsViewOptionsState,
199
247
  viewIsOpenAtoms,
248
+ openCloseAllTX,
200
249
  store
201
250
  };
202
251
  }
@@ -410,6 +459,7 @@ const NonJsonEditor = ({ data, testid }) => {
410
459
  //#endregion
411
460
  //#region src/react-devtools/json-editor/json-editor-internal.tsx
412
461
  const JsonEditor_INTERNAL = ({ data, set, name, rename, remove, recast, path = [], isReadonly = () => false, isHidden = () => false, className, style, Components, isOpen, setIsOpen, testid }) => {
462
+ const { openCloseAllTX, store } = useContext(DevtoolsContext);
413
463
  const dataIsJson = isJson(data);
414
464
  const refined = jsonRefinery.refine(data) ?? {
415
465
  type: `non-json`,
@@ -418,23 +468,21 @@ const JsonEditor_INTERNAL = ({ data, set, name, rename, remove, recast, path = [
418
468
  const SubEditor = dataIsJson ? SubEditors[refined.type] : NonJsonEditor;
419
469
  const disabled = isReadonly(path);
420
470
  const dataIsTree = refined.type === `array` || refined.type === `object`;
471
+ const dataIsExpandable = dataIsTree && isOpen !== void 0 && setIsOpen;
421
472
  return isHidden(path) ? null : /* @__PURE__ */ jsx(Components.ErrorBoundary, { children: /* @__PURE__ */ jsxs(Components.EditorWrapper, {
422
473
  className,
423
474
  style,
424
475
  testid,
425
- children: [/* @__PURE__ */ jsxs("header", { children: [
426
- remove ? /* @__PURE__ */ jsx(Components.Button, {
427
- disabled,
428
- onClick: () => {
429
- remove();
430
- },
431
- testid: `${testid}-delete`,
432
- children: /* @__PURE__ */ jsx(Components.DeleteIcon, {})
433
- }) : null,
434
- dataIsTree && isOpen !== void 0 && setIsOpen ? /* @__PURE__ */ jsx(button.OpenClose, {
435
- isOpen,
476
+ children: [/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsxs("main", { children: [
477
+ remove || dataIsExpandable ? /* @__PURE__ */ jsx(button.OpenClose, {
478
+ isOpen: isOpen ?? false,
436
479
  testid: `${testid}-open-close`,
437
- setIsOpen
480
+ onShiftClick: () => {
481
+ actUponStore(store, openCloseAllTX, arbitrary())(path, isOpen);
482
+ return false;
483
+ },
484
+ setIsOpen,
485
+ disabled: !dataIsExpandable
438
486
  }) : null,
439
487
  rename && /* @__PURE__ */ jsx(Components.KeyWrapper, { children: /* @__PURE__ */ jsx(ElasticInput, {
440
488
  value: name,
@@ -444,7 +492,10 @@ const JsonEditor_INTERNAL = ({ data, set, name, rename, remove, recast, path = [
444
492
  disabled,
445
493
  "data-testid": `${testid}-rename`
446
494
  }) }),
447
- dataIsTree ? /* @__PURE__ */ jsxs(Fragment$1, { children: [recast ? /* @__PURE__ */ jsx("select", {
495
+ dataIsTree ? /* @__PURE__ */ jsxs(Fragment$1, { children: [isOpen !== void 0 && setIsOpen ? /* @__PURE__ */ jsx("span", {
496
+ className: "json_viewer",
497
+ children: JSON.stringify(data)
498
+ }) : null, recast ? /* @__PURE__ */ jsx("select", {
448
499
  onChange: (e) => {
449
500
  recast(e.target.value);
450
501
  },
@@ -455,9 +506,6 @@ const JsonEditor_INTERNAL = ({ data, set, name, rename, remove, recast, path = [
455
506
  value: type,
456
507
  children: type
457
508
  }, type))
458
- }) : null, isOpen !== void 0 && setIsOpen ? /* @__PURE__ */ jsx("span", {
459
- className: "json_viewer",
460
- children: JSON.stringify(data)
461
509
  }) : null] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SubEditor, {
462
510
  data: refined.data,
463
511
  set,
@@ -480,7 +528,14 @@ const JsonEditor_INTERNAL = ({ data, set, name, rename, remove, recast, path = [
480
528
  children: type
481
529
  }, type))
482
530
  }) : null] })
483
- ] }), dataIsTree && isOpen !== false ? /* @__PURE__ */ jsx(SubEditor, {
531
+ ] }), remove ? /* @__PURE__ */ jsx(Components.Button, {
532
+ disabled,
533
+ onClick: () => {
534
+ remove();
535
+ },
536
+ testid: `${testid}-delete`,
537
+ children: /* @__PURE__ */ jsx(Components.DeleteIcon, {})
538
+ }) : null] }), dataIsTree && isOpen !== false ? /* @__PURE__ */ jsx(SubEditor, {
484
539
  data: refined.data,
485
540
  set,
486
541
  remove,
@@ -775,12 +830,12 @@ const ArrayEditor = ({ path = [], isReadonly = () => false, isHidden = () => fal
775
830
  const setElement = makeElementSetters(data, set);
776
831
  const removeElement = makePropertyRemovers(data, set);
777
832
  const recastElement = makePropertyRecasters(data, set);
778
- return /* @__PURE__ */ jsxs(Components.ArrayWrapper, { children: [/* @__PURE__ */ jsx("div", {
833
+ return /* @__PURE__ */ jsxs(Components.ArrayWrapper, { children: [/* @__PURE__ */ jsx("main", {
779
834
  className: `json_editor_elements${disabled ? ` readonly` : ``}`,
780
835
  children: data.map((element, index) => {
781
836
  const elementPath = [...path, index];
782
837
  const pathKey = elementPath.join(`,`);
783
- const viewIsOpenAtom = findInStore(store, viewIsOpenAtoms, `${testid}__${pathKey}`);
838
+ const viewIsOpenAtom = findInStore(store, viewIsOpenAtoms, [...path, index]);
784
839
  return /* @__PURE__ */ jsx(ArrayElement, {
785
840
  path: elementPath,
786
841
  isReadonly,
@@ -794,7 +849,7 @@ const ArrayEditor = ({ path = [], isReadonly = () => false, isHidden = () => fal
794
849
  viewIsOpenAtom
795
850
  }, pathKey);
796
851
  })
797
- }), /* @__PURE__ */ jsx(Components.Button, {
852
+ }), !disabled ? /* @__PURE__ */ jsx("footer", { children: /* @__PURE__ */ jsx(Components.Button, {
798
853
  testid: `${testid}-add-element`,
799
854
  disabled,
800
855
  onClick: () => {
@@ -804,7 +859,7 @@ const ArrayEditor = ({ path = [], isReadonly = () => false, isHidden = () => fal
804
859
  });
805
860
  },
806
861
  children: /* @__PURE__ */ jsx(Components.AddIcon, {})
807
- })] });
862
+ }) }) : null] });
808
863
  };
809
864
 
810
865
  //#endregion
@@ -850,7 +905,7 @@ const ObjectEditor = ({ path = [], isReadonly = () => false, isHidden = () => fa
850
905
  const propertyPath = [...path, key];
851
906
  const originalPropertyPath = [...path, originalKey];
852
907
  const stablePathKey = originalPropertyPath.join(`.`);
853
- const viewIsOpenAtom = findInStore(store, viewIsOpenAtoms, `${testid}__${stablePathKey}`);
908
+ const viewIsOpenAtom = findInStore(store, viewIsOpenAtoms, [...path, key]);
854
909
  return /* @__PURE__ */ jsx(ObjectProperty, {
855
910
  path: propertyPath,
856
911
  isReadonly,
@@ -865,7 +920,7 @@ const ObjectEditor = ({ path = [], isReadonly = () => false, isHidden = () => fa
865
920
  viewIsOpenAtom
866
921
  }, stablePathKey);
867
922
  })
868
- }), disabled ? null : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Components.Button, {
923
+ }), disabled ? null : /* @__PURE__ */ jsxs("footer", { children: [/* @__PURE__ */ jsx(Components.Button, {
869
924
  disabled,
870
925
  testid: `${testid}-add-property`,
871
926
  onClick: () => {
@@ -923,7 +978,7 @@ const SubEditors = {
923
978
  object: ObjectEditor,
924
979
  string: StringEditor
925
980
  };
926
- const JsonEditor = ({ data, set, name, rename, remove, isReadonly = () => false, isHidden = () => false, className, Header, style, Components: CustomComponents = {}, testid }) => {
981
+ const JsonEditor = ({ data, set, name, rename, remove, path = [], isReadonly = () => false, isHidden = () => false, className, Header, style, Components: CustomComponents = {}, testid }) => {
927
982
  const Components = {
928
983
  ...DEFAULT_JSON_EDITOR_COMPONENTS,
929
984
  ...CustomComponents
@@ -934,7 +989,7 @@ const JsonEditor = ({ data, set, name, rename, remove, isReadonly = () => false,
934
989
  name,
935
990
  rename,
936
991
  remove,
937
- path: [],
992
+ path,
938
993
  isReadonly,
939
994
  isHidden,
940
995
  className,
@@ -950,19 +1005,23 @@ const JsonEditor = ({ data, set, name, rename, remove, isReadonly = () => false,
950
1005
  const StateEditor = ({ token }) => {
951
1006
  const set = useI$1(token);
952
1007
  const data = useO$1(token);
1008
+ const metaPath = token.family ? [token.family.key, token.family.subKey] : [token.key];
953
1009
  return /* @__PURE__ */ jsx(JsonEditor, {
954
1010
  testid: `${token.key}-state-editor`,
955
1011
  data,
956
- set
1012
+ set,
1013
+ path: metaPath
957
1014
  });
958
1015
  };
959
1016
  const ReadonlySelectorViewer = ({ token }) => {
960
1017
  const data = useO$1(token);
1018
+ const metaPath = token.family ? [token.family.key, token.family.subKey] : [token.key];
961
1019
  return /* @__PURE__ */ jsx(JsonEditor, {
962
1020
  testid: `${token.key}-state-editor`,
963
1021
  data,
964
1022
  set: () => null,
965
- isReadonly: () => true
1023
+ isReadonly: () => true,
1024
+ path: metaPath
966
1025
  });
967
1026
  };
968
1027
  const StoreEditor = ({ token }) => {
@@ -978,71 +1037,95 @@ const StoreEditor = ({ token }) => {
978
1037
 
979
1038
  //#endregion
980
1039
  //#region src/react-devtools/StateIndex.tsx
981
- const StateIndexLeafNode = ({ node, isOpenState, typeState }) => {
1040
+ const StateIndexLeafNode = ({ node, isOpenState, typeState, dispose }) => {
1041
+ const { openCloseAllTX, store } = useContext(DevtoolsContext);
982
1042
  const setIsOpen = useI$1(isOpenState);
983
1043
  const isOpen = useO$1(isOpenState);
984
1044
  const state = useO$1(node);
985
1045
  const stateTypeLoadable = useO$1(typeState);
986
1046
  const stateType = stateTypeLoadable instanceof Promise ? `Promise` : stateTypeLoadable;
987
1047
  const isPrimitive = Boolean(primitiveRefinery.refine(state));
988
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("header", { children: [
989
- /* @__PURE__ */ jsx(button.OpenClose, {
990
- isOpen: isOpen && !isPrimitive,
991
- testid: `open-close-state-${node.key}`,
992
- setIsOpen,
993
- disabled: isPrimitive
994
- }),
995
- /* @__PURE__ */ jsxs("main", {
996
- onClick: () => {
997
- console.log(node, getState(node));
998
- },
999
- onKeyUp: () => {
1000
- console.log(node, getState(node));
1001
- },
1002
- children: [/* @__PURE__ */ jsx("h2", { children: node.family?.subKey ?? node.key }), /* @__PURE__ */ jsxs("span", {
1048
+ const path = node.family ? [node.family.key, node.family.subKey] : [node.key];
1049
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsxs("main", {
1050
+ onClick: () => {
1051
+ console.log(node, getFromStore(store, node));
1052
+ },
1053
+ onKeyUp: () => {
1054
+ console.log(node, getFromStore(store, node));
1055
+ },
1056
+ children: [
1057
+ /* @__PURE__ */ jsx(button.OpenClose, {
1058
+ isOpen: isOpen && !isPrimitive,
1059
+ testid: `open-close-state-${node.key}`,
1060
+ onShiftClick: () => {
1061
+ actUponStore(store, openCloseAllTX, arbitrary())(path, isOpen);
1062
+ return false;
1063
+ },
1064
+ setIsOpen,
1065
+ disabled: isPrimitive
1066
+ }),
1067
+ /* @__PURE__ */ jsx("h2", { children: node.family?.subKey ?? node.key }),
1068
+ /* @__PURE__ */ jsxs("span", {
1003
1069
  className: "type detail",
1004
1070
  children: [
1005
1071
  "(",
1006
1072
  stateType,
1007
1073
  ")"
1008
1074
  ]
1009
- })]
1010
- }),
1011
- isPrimitive ? /* @__PURE__ */ jsx(StoreEditor, { token: node }) : /* @__PURE__ */ jsx("div", {
1012
- className: "json_viewer",
1013
- children: JSON.stringify(state)
1014
- })
1015
- ] }), isOpen && !isPrimitive ? /* @__PURE__ */ jsx("main", { children: /* @__PURE__ */ jsx(StoreEditor, { token: node }) }) : null] });
1075
+ })
1076
+ ]
1077
+ }), /* @__PURE__ */ jsxs("footer", { children: [isPrimitive ? /* @__PURE__ */ jsx(StoreEditor, { token: node }) : /* @__PURE__ */ jsx("div", {
1078
+ className: "json_viewer",
1079
+ children: JSON.stringify(state)
1080
+ }), dispose ? /* @__PURE__ */ jsx(DEFAULT_JSON_EDITOR_COMPONENTS.Button, {
1081
+ onClick: () => {
1082
+ dispose?.();
1083
+ },
1084
+ testid: `${node.key}-dispose`,
1085
+ children: /* @__PURE__ */ jsx(DEFAULT_JSON_EDITOR_COMPONENTS.DeleteIcon, {})
1086
+ }) : null] })] }), isOpen && !isPrimitive ? /* @__PURE__ */ jsx("main", { children: /* @__PURE__ */ jsx(StoreEditor, { token: node }) }) : null] });
1016
1087
  };
1017
1088
  const StateIndexTreeNode = ({ node, isOpenState }) => {
1018
1089
  const setIsOpen = useI$1(isOpenState);
1019
1090
  const isOpen = useO$1(isOpenState);
1020
- const { typeSelectors, viewIsOpenAtoms, store } = useContext(DevtoolsContext);
1091
+ const { typeSelectors, viewIsOpenAtoms, openCloseAllTX, store } = useContext(DevtoolsContext);
1021
1092
  for (const [key, childNode] of node.familyMembers) {
1022
- findInStore(store, viewIsOpenAtoms, key);
1093
+ findInStore(store, viewIsOpenAtoms, [key]);
1023
1094
  findInStore(store, typeSelectors, childNode.key);
1024
1095
  }
1025
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsx(button.OpenClose, {
1026
- isOpen,
1027
- testid: `open-close-state-family-${node.key}`,
1028
- setIsOpen
1029
- }), /* @__PURE__ */ jsxs("main", { children: [/* @__PURE__ */ jsx("h2", { children: node.key }), /* @__PURE__ */ jsx("span", {
1030
- className: "type detail",
1031
- children: " (family)"
1032
- })] })] }), isOpen ? [...node.familyMembers.entries()].map(([key, childNode]) => /* @__PURE__ */ jsx(StateIndexNode, {
1096
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("header", { children: /* @__PURE__ */ jsxs("main", { children: [
1097
+ /* @__PURE__ */ jsx(button.OpenClose, {
1098
+ isOpen,
1099
+ testid: `open-close-state-family-${node.key}`,
1100
+ onShiftClick: () => {
1101
+ actUponStore(store, openCloseAllTX, arbitrary())([node.key], isOpen);
1102
+ return false;
1103
+ },
1104
+ setIsOpen
1105
+ }),
1106
+ /* @__PURE__ */ jsx("h2", { children: node.key }),
1107
+ /* @__PURE__ */ jsx("span", {
1108
+ className: "type detail",
1109
+ children: " (family)"
1110
+ })
1111
+ ] }) }), isOpen ? [...node.familyMembers.entries()].map(([key, childNode]) => /* @__PURE__ */ jsx(StateIndexNode, {
1033
1112
  node: childNode,
1034
- isOpenState: findInStore(store, viewIsOpenAtoms, childNode.key),
1035
- typeState: findInStore(store, typeSelectors, childNode.key)
1113
+ isOpenState: findInStore(store, viewIsOpenAtoms, [node.key, key]),
1114
+ typeState: findInStore(store, typeSelectors, childNode.key),
1115
+ dispose: () => {
1116
+ disposeFromStore(store, childNode);
1117
+ }
1036
1118
  }, key)) : null] });
1037
1119
  };
1038
- const StateIndexNode = ({ node, isOpenState, typeState }) => {
1120
+ const StateIndexNode = ({ node, isOpenState, typeState, dispose }) => {
1039
1121
  return /* @__PURE__ */ jsx("section", {
1040
1122
  className: "node state",
1041
1123
  "data-testid": `state-${node.key}`,
1042
1124
  children: `type` in node ? /* @__PURE__ */ jsx(StateIndexLeafNode, {
1043
1125
  node,
1044
1126
  isOpenState,
1045
- typeState
1127
+ typeState,
1128
+ dispose
1046
1129
  }) : /* @__PURE__ */ jsx(StateIndexTreeNode, {
1047
1130
  node,
1048
1131
  isOpenState
@@ -1052,14 +1135,21 @@ const StateIndexNode = ({ node, isOpenState, typeState }) => {
1052
1135
  const StateIndex = ({ tokenIndex }) => {
1053
1136
  const tokenIds = useO$1(tokenIndex);
1054
1137
  const { typeSelectors, viewIsOpenAtoms, store } = useContext(DevtoolsContext);
1055
- console.log(tokenIds);
1138
+ const statesName = tokenIndex.key.includes(`Atom`) ? `atoms` : `selectors`;
1056
1139
  return /* @__PURE__ */ jsx("article", {
1057
1140
  className: "index state_index",
1058
1141
  "data-testid": "state-index",
1059
- children: [...tokenIds.entries()].map(([key, node]) => {
1142
+ children: tokenIds.size === 0 ? /* @__PURE__ */ jsxs("p", {
1143
+ className: "index-empty-state",
1144
+ children: [
1145
+ "(no ",
1146
+ statesName,
1147
+ ")"
1148
+ ]
1149
+ }) : [...tokenIds.entries()].map(([key, node]) => {
1060
1150
  return /* @__PURE__ */ jsx(StateIndexNode, {
1061
1151
  node,
1062
- isOpenState: findInStore(store, viewIsOpenAtoms, node.key),
1152
+ isOpenState: findInStore(store, viewIsOpenAtoms, [node.key]),
1063
1153
  typeState: findInStore(store, typeSelectors, node.key)
1064
1154
  }, key);
1065
1155
  })
@@ -1267,10 +1357,13 @@ const TimelineIndex = () => {
1267
1357
  return /* @__PURE__ */ jsx("article", {
1268
1358
  className: "index timeline_index",
1269
1359
  "data-testid": "timeline-index",
1270
- children: tokenIds.filter((token) => !token.key.startsWith(`👁‍🗨`)).map((token) => {
1360
+ children: tokenIds.length === 0 ? /* @__PURE__ */ jsx("p", {
1361
+ className: "index-empty-state",
1362
+ children: "(no timelines)"
1363
+ }) : tokenIds.filter((token) => !token.key.startsWith(`👁‍🗨`)).map((token) => {
1271
1364
  return /* @__PURE__ */ jsx(TimelineLog, {
1272
1365
  token,
1273
- isOpenState: findInStore(store, viewIsOpenAtoms, token.key),
1366
+ isOpenState: findInStore(store, viewIsOpenAtoms, [token.key]),
1274
1367
  timelineState: findInStore(store, timelineSelectors, token.key)
1275
1368
  }, token.key);
1276
1369
  })
@@ -1286,18 +1379,18 @@ const TransactionLog = ({ token, isOpenState, logState }) => {
1286
1379
  return /* @__PURE__ */ jsxs("section", {
1287
1380
  className: "node transaction_log",
1288
1381
  "data-testid": `transaction-${token.key}`,
1289
- children: [/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsx(button.OpenClose, {
1382
+ children: [/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsxs("main", { children: [/* @__PURE__ */ jsx(button.OpenClose, {
1290
1383
  isOpen,
1291
1384
  testid: `open-close-transaction-${token.key}`,
1292
1385
  setIsOpen
1293
- }), /* @__PURE__ */ jsxs("main", { children: [/* @__PURE__ */ jsx("h2", { children: token.key }), /* @__PURE__ */ jsxs("span", {
1386
+ }), /* @__PURE__ */ jsx("h2", { children: token.key })] }), /* @__PURE__ */ jsxs("span", {
1294
1387
  className: "detail length",
1295
1388
  children: [
1296
1389
  "(",
1297
1390
  log.length,
1298
1391
  ")"
1299
1392
  ]
1300
- })] })] }), isOpen ? /* @__PURE__ */ jsx("main", { children: log.map((update, index) => /* @__PURE__ */ jsx(article.TransactionUpdate, {
1393
+ })] }), isOpen ? /* @__PURE__ */ jsx("main", { children: log.map((update, index) => /* @__PURE__ */ jsx(article.TransactionUpdate, {
1301
1394
  serialNumber: index,
1302
1395
  transactionUpdate: update
1303
1396
  }, update.key + index)) }) : null]
@@ -1309,10 +1402,13 @@ const TransactionIndex = () => {
1309
1402
  return /* @__PURE__ */ jsx("article", {
1310
1403
  className: "index transaction_index",
1311
1404
  "data-testid": "transaction-index",
1312
- children: tokenIds.filter((token) => !token.key.startsWith(`🔍`)).map((token) => {
1405
+ children: tokenIds.length === 0 ? /* @__PURE__ */ jsx("p", {
1406
+ className: "index-empty-state",
1407
+ children: "(no transactions)"
1408
+ }) : tokenIds.filter((token) => !token.key.startsWith(`🔍`)).map((token) => {
1313
1409
  return /* @__PURE__ */ jsx(TransactionLog, {
1314
1410
  token,
1315
- isOpenState: findInStore(store, viewIsOpenAtoms, token.key),
1411
+ isOpenState: findInStore(store, viewIsOpenAtoms, [token.key]),
1316
1412
  logState: findInStore(store, transactionLogSelectors, token.key)
1317
1413
  }, token.key);
1318
1414
  })