@atom.io/spa-devtools 0.0.4 → 0.0.6

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 CHANGED
@@ -7,11 +7,11 @@ Use spa's Vite or Astro integration to compile application JSX. Import the style
7
7
  ```tsx
8
8
  import "@atom.io/spa-devtools/css"
9
9
 
10
- import type { VNode } from "@atom.io/spa"
10
+ import type { SpaElement } from "@atom.io/spa"
11
11
  import { AtomIODevtools } from "@atom.io/spa-devtools"
12
12
  import type { RootStore } from "atom.io/internal"
13
13
 
14
- export function Debugger(props: { store: RootStore }): VNode {
14
+ export function Debugger(props: { store: RootStore }): SpaElement {
15
15
  return <AtomIODevtools store={props.store} hideByDefault />
16
16
  }
17
17
 
@@ -43,7 +43,7 @@ Sizes are exact minified and level-9 gzip JavaScript byte counts. Declarations,
43
43
 
44
44
  | Recipe | Entry | Minified JS | Gzip JS |
45
45
  | ----------------------------- | ----------------------------- | ----------: | -------: |
46
- | Interactive app with debugger | `tonnage-recipes/debugger.ts` | 87,866 B | 25,583 B |
46
+ | Interactive app with debugger | `tonnage-recipes/debugger.ts` | 88,331 B | 25,854 B |
47
47
 
48
48
  Report maintained with [tonnage](https://github.com/jeremybanka/tonnage).
49
49
 
package/README.mdx CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Tonnage } from "tonnage";
2
2
  import config from "./tonnage.config.ts";
3
- import Setup from "./exhibits/setup.spa.tsx" with { type: "code" };
3
+ import Setup from "./exhibits/setup.tsx" with { type: "code" };
4
4
 
5
5
  # SPA devtools
6
6
 
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { VNode } from "@atom.io/spa";
1
+ import { SpaElement } from "@atom.io/spa";
2
2
  import { RootStore } from "atom.io/internal";
3
3
  interface AtomIODevtoolsProps {
4
4
  /** Inspected store. Fixed for this component instance; change its key to replace it. */
@@ -6,6 +6,6 @@ interface AtomIODevtoolsProps {
6
6
  hideByDefault?: boolean;
7
7
  }
8
8
  /** Owns a rendering root in the inspected store, independently of its parent island. */
9
- export declare function AtomIODevtools(props: AtomIODevtoolsProps): VNode;
9
+ export declare function AtomIODevtools(props: AtomIODevtoolsProps): SpaElement;
10
10
  export type { AtomIODevtoolsProps };
11
11
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -546,6 +546,7 @@ function TransactionLog(props) {
546
546
  })) : null]
547
547
  });
548
548
  }
549
+ /** @internal Used by contributor tools or implementation tests. */
549
550
  function EventView(props) {
550
551
  const [getOpen, toggle] = useExpanded(props.tools, [
551
552
  `event`,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["_spa","_spa","_spa"],"sources":["../src/store.ts","../src/value.ts","../src/JsonEditor.tsx","../src/Indexes.tsx","../src/AtomIODevtools.tsx"],"sourcesContent":["import type { Accessor } from \"@atom.io/spa\"\nimport { onCleanup, useGetter, useId, useSetter } from \"@atom.io/spa\"\nimport type { RegularAtomFamilyToken, RegularAtomToken, Setter } from \"atom.io\"\nimport type { RootStore } from \"atom.io/internal\"\nimport {\n\tcreateRegularAtomFamily,\n\tdisposeFromStore,\n\tfindInStore,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { IntrospectionStates } from \"atom.io/introspection\"\nimport { attachIntrospectionStates } from \"atom.io/introspection\"\n\nconst locals = new WeakMap<RootStore, RegularAtomFamilyToken<unknown, string>>()\nconst introspection = new WeakMap<RootStore, IntrospectionStates>()\nexport type Path = readonly string[]\nexport interface Tools extends IntrospectionStates {\n\tstore: RootStore\n\texpanded: RegularAtomToken<Record<string, boolean>>\n\terror: RegularAtomToken<string>\n\tattempt(run: () => void): void\n}\n\nexport function ownedAtom<T>(store: RootStore, initial: T): RegularAtomToken<T> {\n\tlet family = locals.get(store)\n\tif (!family) {\n\t\tfamily = createRegularAtomFamily<unknown, string, never>(store, {\n\t\t\tkey: `🔍 spa devtools`,\n\t\t\tdefault: undefined,\n\t\t})\n\t\tlocals.set(store, family)\n\t}\n\tconst token = findInStore(store, family, useId()) as RegularAtomToken<T>\n\tsetIntoStore(store, token, initial)\n\tonCleanup(() => {\n\t\tdisposeFromStore(store, token)\n\t})\n\treturn token\n}\nexport function useLocal<T>(\n\tstore: RootStore,\n\tinitial: T,\n): [Accessor<T>, (next: T | Setter<T>) => void] {\n\tconst token = ownedAtom(store, initial)\n\treturn [useGetter(token) as Accessor<T>, useSetter(token)]\n}\nexport function useSaved<T>(\n\tstore: RootStore,\n\tkey: string,\n\tfallback: T,\n): [Accessor<T>, (next: T | Setter<T>) => void] {\n\tlet initial = fallback\n\ttry {\n\t\tconst saved: unknown = JSON.parse(localStorage.getItem(key) ?? `null`)\n\t\tif (saved !== null && typeof saved === typeof fallback) initial = saved as T\n\t} catch {\n\t\t/* Storage may be unavailable. */\n\t}\n\tconst [getValue, setValue] = useLocal(store, initial)\n\treturn [\n\t\tgetValue,\n\t\t(next) => {\n\t\t\tsetValue(next)\n\t\t\ttry {\n\t\t\t\tlocalStorage.setItem(key, JSON.stringify(getValue()))\n\t\t\t} catch {\n\t\t\t\t/* Keep in-memory state when storage is unavailable. */\n\t\t\t}\n\t\t},\n\t]\n}\nexport function useTools(store: RootStore): Tools {\n\tlet states = introspection.get(store)\n\tif (!states) {\n\t\tstates = attachIntrospectionStates(store)\n\t\tintrospection.set(store, states)\n\t}\n\tlet expanded: Record<string, boolean> = {}\n\ttry {\n\t\tconst saved: unknown = JSON.parse(\n\t\t\tlocalStorage.getItem(`🔍 spa expanded`) ?? `{}`,\n\t\t)\n\t\tif (\n\t\t\tsaved &&\n\t\t\ttypeof saved === `object` &&\n\t\t\t!Array.isArray(saved) &&\n\t\t\tObject.values(saved).every((value) => typeof value === `boolean`)\n\t\t)\n\t\t\texpanded = saved as Record<string, boolean>\n\t} catch {\n\t\t/* Ignore corrupt or unavailable storage. */\n\t}\n\tconst error = ownedAtom(store, ``)\n\tconst setError = useSetter(error)\n\treturn {\n\t\t...states,\n\t\tstore,\n\t\terror,\n\t\texpanded: ownedAtom(store, expanded),\n\t\tattempt(run) {\n\t\t\ttry {\n\t\t\t\trun()\n\t\t\t\tsetError(``)\n\t\t\t} catch (caught) {\n\t\t\t\tsetError(caught instanceof Error ? caught.message : String(caught))\n\t\t\t}\n\t\t},\n\t}\n}\nexport function useExpanded(\n\ttools: Tools,\n\tpath: Path,\n\tinitial = false,\n): [Accessor<boolean>, (event: MouseEvent) => void] {\n\tconst getExpanded = useGetter(tools.expanded)\n\tconst setExpanded = useSetter(tools.expanded)\n\tconst key = JSON.stringify(path)\n\tconst group = `all:${JSON.stringify(path.slice(0, -1))}`\n\tconst read = () => getExpanded()[key] ?? getExpanded()[group] ?? initial\n\treturn [\n\t\tread,\n\t\t(event) => {\n\t\t\tconst next = !read()\n\t\t\tsetExpanded((previous) => {\n\t\t\t\tconst result = { ...previous }\n\t\t\t\tif (event.shiftKey) {\n\t\t\t\t\tconst parent = JSON.stringify(path.slice(0, -1))\n\t\t\t\t\tfor (const item of Object.keys(result)) {\n\t\t\t\t\t\tif (item.startsWith(`[`)) {\n\t\t\t\t\t\t\tconst candidate = JSON.parse(item) as string[]\n\t\t\t\t\t\t\tif (JSON.stringify(candidate.slice(0, -1)) === parent)\n\t\t\t\t\t\t\t\tReflect.deleteProperty(result, item)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tresult[group] = next\n\t\t\t\t} else {\n\t\t\t\t\tresult[key] = next\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tlocalStorage.setItem(`🔍 spa expanded`, JSON.stringify(result))\n\t\t\t\t} catch {\n\t\t\t\t\t/* Keep in-memory expansion state. */\n\t\t\t\t}\n\t\t\t\treturn result\n\t\t\t})\n\t\t},\n\t]\n}\n","export type Change = (update: (previous: unknown) => unknown) => void\nexport type JsonKind =\n\t| `string`\n\t| `number`\n\t| `boolean`\n\t| `null`\n\t| `array`\n\t| `object`\nexport function kind(value: unknown): JsonKind | `other` {\n\tif (value === null) return `null`\n\tif (Array.isArray(value)) return `array`\n\tif (\n\t\ttypeof value === `object` &&\n\t\t(Object.getPrototypeOf(value) === Object.prototype ||\n\t\t\tObject.getPrototypeOf(value) === null)\n\t)\n\t\treturn `object`\n\tif (\n\t\ttypeof value === `string` ||\n\t\ttypeof value === `number` ||\n\t\ttypeof value === `boolean`\n\t)\n\t\treturn typeof value as JsonKind\n\treturn `other`\n}\nexport function describe(value: unknown): string {\n\ttry {\n\t\tconst seen = new WeakSet<object>()\n\t\treturn (\n\t\t\tJSON.stringify(value, (_, item: unknown) => {\n\t\t\t\tif (typeof item === `bigint`) return `${item}n`\n\t\t\t\tif (item instanceof Error) return `${item.name}: ${item.message}`\n\t\t\t\tif (item instanceof Map) return { Map: [...item] }\n\t\t\t\tif (item instanceof Set) return { Set: [...item] }\n\t\t\t\tif (typeof item === `object` && item !== null) {\n\t\t\t\t\tif (seen.has(item)) return `[Circular]`\n\t\t\t\t\tseen.add(item)\n\t\t\t\t}\n\t\t\t\treturn item\n\t\t\t}) ?? String(value)\n\t\t)\n\t} catch {\n\t\treturn Object.prototype.toString.call(value)\n\t}\n}\nexport function convert(value: unknown, type: JsonKind): unknown {\n\tswitch (type) {\n\t\tcase `null`:\n\t\t\treturn null\n\t\tcase `string`:\n\t\t\treturn value == null\n\t\t\t\t? ``\n\t\t\t\t: typeof value === `string`\n\t\t\t\t\t? value\n\t\t\t\t\t: describe(value)\n\t\tcase `number`: {\n\t\t\tconst next = Array.isArray(value) ? value.length : Number(value)\n\t\t\treturn Number.isFinite(next) ? next : 0\n\t\t}\n\t\tcase `boolean`:\n\t\t\treturn typeof value === `string` ? value === `true` : Boolean(value)\n\t\tcase `array`:\n\t\t\treturn Array.isArray(value)\n\t\t\t\t? value\n\t\t\t\t: value == null\n\t\t\t\t\t? []\n\t\t\t\t\t: typeof value === `object`\n\t\t\t\t\t\t? Object.entries(value)\n\t\t\t\t\t\t: [value]\n\t\tcase `object`:\n\t\t\treturn kind(value) === `object`\n\t\t\t\t? value\n\t\t\t\t: Array.isArray(value)\n\t\t\t\t\t? Object.fromEntries(value.map((item, index) => [index, item]))\n\t\t\t\t\t: value == null\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { value }\n\t}\n}\n","import type { Child, VNode } from \"@atom.io/spa\"\n\nimport type { Path, Tools } from \"./store.ts\"\nimport { useExpanded } from \"./store.ts\"\nimport type { Change, JsonKind } from \"./value.ts\"\nimport { convert, describe, kind } from \"./value.ts\"\n\ninterface EditorProps {\n\ttools: Tools\n\tvalue: unknown\n\tchange?: Change | undefined\n\tpath: Path\n\tancestors?: readonly unknown[]\n\tlabel?: Child\n\tactions?: Child\n}\nconst TYPES: JsonKind[] = [\n\t`string`,\n\t`number`,\n\t`boolean`,\n\t`null`,\n\t`array`,\n\t`object`,\n]\nexport function JsonEditor(props: EditorProps): VNode {\n\tconst [getExpanded, toggle] = useExpanded(props.tools, props.path)\n\tconst circular = () =>\n\t\t(props.ancestors?.includes(props.value) ?? false) || props.path.length > 50\n\tconst container = () =>\n\t\t!circular() &&\n\t\t(kind(props.value) === `object` || kind(props.value) === `array`)\n\tconst entries = () => Object.entries(props.value as Record<string, unknown>)\n\treturn (\n\t\t<section\n\t\t\tclass=\"json-editor\"\n\t\t\tdata-testid={`${props.path.join(`.`)}-state-editor`}\n\t\t>\n\t\t\t<header>\n\t\t\t\t{container() ? (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={`Expand ${props.path.at(-1)}`}\n\t\t\t\t\t\taria-expanded={getExpanded()}\n\t\t\t\t\t\tonClick={toggle}\n\t\t\t\t\t>\n\t\t\t\t\t\t{getExpanded() ? `▾` : `▸`}\n\t\t\t\t\t</button>\n\t\t\t\t) : (\n\t\t\t\t\t<span class=\"carat-spacer\" />\n\t\t\t\t)}\n\t\t\t\t<span class=\"field-name\">{props.label}</span>\n\t\t\t\t{props.change ? (\n\t\t\t\t\t<select\n\t\t\t\t\t\taria-label={`Type of ${props.path.at(-1)}`}\n\t\t\t\t\t\tvalue={kind(props.value)}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tconst type = event.currentTarget.value as JsonKind\n\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\tprops.change?.((previous) => convert(previous, type))\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<option value=\"other\" disabled>\n\t\t\t\t\t\t\tother\n\t\t\t\t\t\t</option>\n\t\t\t\t\t\t{TYPES.map((type) => (\n\t\t\t\t\t\t\t<option value={type}>{type}</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</select>\n\t\t\t\t) : (\n\t\t\t\t\t<small>{kind(props.value)}</small>\n\t\t\t\t)}\n\t\t\t\t{container() ? (\n\t\t\t\t\t<code title={describe(props.value)}>{describe(props.value)}</code>\n\t\t\t\t) : circular() ? (\n\t\t\t\t\t<code>[Circular]</code>\n\t\t\t\t) : (\n\t\t\t\t\t<Primitive\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tchange={props.change}\n\t\t\t\t\t\ttools={props.tools}\n\t\t\t\t\t\tlabel={props.path.at(-1) ?? `value`}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{props.actions}\n\t\t\t</header>\n\t\t\t{container() && getExpanded() ? (\n\t\t\t\t<section class=\"properties\">\n\t\t\t\t\t{entries().map(([key]) => (\n\t\t\t\t\t\t<Property key={key} name={key} editor={props} />\n\t\t\t\t\t))}\n\t\t\t\t\t{props.change ? (\n\t\t\t\t\t\t<footer>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\t\tprops.change?.((previous) => {\n\t\t\t\t\t\t\t\t\t\t\tif (Array.isArray(previous)) return [...previous, null]\n\t\t\t\t\t\t\t\t\t\t\tconst object = previous as Record<string, unknown>\n\t\t\t\t\t\t\t\t\t\t\tlet name = `new`\n\t\t\t\t\t\t\t\t\t\t\twhile (Object.hasOwn(object, name)) name += `_`\n\t\t\t\t\t\t\t\t\t\t\treturn { ...object, [name]: null }\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tadd {Array.isArray(props.value) ? `item` : `property`}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{Array.isArray(props.value) ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\t\t\tprops.change?.((previous) =>\n\t\t\t\t\t\t\t\t\t\t\t\t[...(previous as unknown[])].sort((a, b) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\ttypeof a === `number` && typeof b === `number`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? a - b\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: describe(a).localeCompare(describe(b)),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tsort\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</footer>\n\t\t\t\t\t) : null}\n\t\t\t\t</section>\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\nfunction Primitive(props: {\n\tvalue: unknown\n\tchange?: Change | undefined\n\ttools: Tools\n\tlabel: string\n}): VNode {\n\tconst set = (value: unknown) => {\n\t\tprops.tools.attempt(() => {\n\t\t\tprops.change?.(() => value)\n\t\t})\n\t}\n\treturn (\n\t\t<span class=\"primitive\">\n\t\t\t{kind(props.value) === `boolean` ? (\n\t\t\t\t<input\n\t\t\t\t\taria-label={props.label}\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tchecked={Boolean(props.value)}\n\t\t\t\t\tdisabled={!props.change}\n\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\tset(event.currentTarget.checked)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : kind(props.value) === `string` || kind(props.value) === `number` ? (\n\t\t\t\t<input\n\t\t\t\t\taria-label={props.label}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tinputmode={kind(props.value) === `number` ? `decimal` : `text`}\n\t\t\t\t\tvalue={String(props.value)}\n\t\t\t\t\treadOnly={!props.change}\n\t\t\t\t\tonInput={(event) => {\n\t\t\t\t\t\tconst text = event.currentTarget.value\n\t\t\t\t\t\tif (kind(props.value) === `string`) set(text)\n\t\t\t\t\t\telse if (text.trim() && Number.isFinite(Number(text)))\n\t\t\t\t\t\t\tset(Number(text))\n\t\t\t\t\t}}\n\t\t\t\t\tonBlur={(event) => {\n\t\t\t\t\t\tevent.currentTarget.value = String(props.value)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<code>{describe(props.value)}</code>\n\t\t\t)}\n\t\t</span>\n\t)\n}\nfunction Property(props: { name: string; editor: EditorProps }): VNode {\n\tconst parent = props.editor\n\tconst read = () => (parent.value as Record<string, unknown>)[props.name]\n\tconst change: Change = (update) => {\n\t\tparent.change?.((previous) => {\n\t\t\tif (Array.isArray(previous))\n\t\t\t\treturn previous.map((value, index) =>\n\t\t\t\t\tindex === Number(props.name) ? update(value) : value,\n\t\t\t\t)\n\t\t\tconst object = previous as Record<string, unknown>\n\t\t\treturn { ...object, [props.name]: update(object[props.name]) }\n\t\t})\n\t}\n\treturn (\n\t\t<section class=\"property\">\n\t\t\t<JsonEditor\n\t\t\t\tlabel={\n\t\t\t\t\tparent.change && !Array.isArray(parent.value) ? (\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\taria-label={`Rename ${props.name}`}\n\t\t\t\t\t\t\tstyle={`width:calc(${Math.max(1, props.name.length)}ch + 6px)`}\n\t\t\t\t\t\t\tvalue={props.name}\n\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\tconst input = event.currentTarget\n\t\t\t\t\t\t\t\tconst name = input.value\n\t\t\t\t\t\t\t\tparent.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\tparent.change?.((previous) => {\n\t\t\t\t\t\t\t\t\t\tconst object = previous as Record<string, unknown>\n\t\t\t\t\t\t\t\t\t\tif (name !== props.name && Object.hasOwn(object, name))\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(`Property \"${name}\" already exists`)\n\t\t\t\t\t\t\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\tObject.entries(object).map(([key, value]) => [\n\t\t\t\t\t\t\t\t\t\t\t\tkey === props.name ? name : key,\n\t\t\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tinput.value = props.name\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<strong>{props.name}</strong>\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tactions={\n\t\t\t\t\tparent.change ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label={`Delete ${props.name}`}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tparent.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\tparent.change?.((previous) =>\n\t\t\t\t\t\t\t\t\t\tArray.isArray(previous)\n\t\t\t\t\t\t\t\t\t\t\t? previous.filter(\n\t\t\t\t\t\t\t\t\t\t\t\t\t(_, index) => index !== Number(props.name),\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\t\t\tObject.entries(previous as object).filter(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t([key]) => key !== props.name,\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t×\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null\n\t\t\t\t}\n\t\t\t\ttools={parent.tools}\n\t\t\t\tpath={[...parent.path, props.name]}\n\t\t\t\tvalue={read()}\n\t\t\t\tchange={parent.change ? change : undefined}\n\t\t\t\tancestors={[...(parent.ancestors ?? []), parent.value]}\n\t\t\t/>\n\t\t</section>\n\t)\n}\n","import type { VNode } from \"@atom.io/spa\"\nimport { useGetter, useSetter, useTimeline } from \"@atom.io/spa\"\nimport type {\n\tReadableToken,\n\tTimelineToken,\n\tTransactionToken,\n\tWritableToken,\n} from \"atom.io\"\nimport {\n\tdisposeFromStore,\n\tfindInStore,\n\tisReservedIntrospectionKey,\n} from \"atom.io/internal\"\nimport type { FamilyNode } from \"atom.io/introspection\"\n\nimport { JsonEditor } from \"./JsonEditor.tsx\"\nimport type { Tools } from \"./store.ts\"\nimport { useExpanded } from \"./store.ts\"\nimport { describe } from \"./value.ts\"\n\ntype Token = ReadableToken<unknown, any, any>\nexport function StateIndex(props: {\n\ttools: Tools\n\ttype: `atoms` | `selectors`\n}): VNode {\n\tconst getStateIndex = useGetter<Map<string, Token | FamilyNode<Token>>>(\n\t\tprops.type === `atoms` ? props.tools.atomIndex : props.tools.selectorIndex,\n\t)\n\treturn (\n\t\t<article class=\"index\" data-testid=\"state-index\">\n\t\t\t{getStateIndex().size === 0 ? (\n\t\t\t\t<p>(no {props.type})</p>\n\t\t\t) : (\n\t\t\t\t[...getStateIndex().values()].map((node) => (\n\t\t\t\t\t<StateNode key={node.key} tools={props.tools} node={node} />\n\t\t\t\t))\n\t\t\t)}\n\t\t</article>\n\t)\n}\nfunction StateNode(props: {\n\ttools: Tools\n\tnode: Token | FamilyNode<Token>\n}): VNode {\n\tconst [getOpen, toggle] = useExpanded(props.tools, [props.node.key])\n\treturn (\n\t\t<section class=\"node\" data-testid={`state-${props.node.key}`}>\n\t\t\t{`familyMembers` in props.node ? (\n\t\t\t\t<>\n\t\t\t\t\t<header>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-expanded={getOpen()}\n\t\t\t\t\t\t\tdata-testid={`open-close-state-family-${props.node.key}`}\n\t\t\t\t\t\t\tonClick={toggle}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<h2>{props.node.key}</h2>\n\t\t\t\t\t\t<small>family</small>\n\t\t\t\t\t</header>\n\t\t\t\t\t{getOpen()\n\t\t\t\t\t\t? [...props.node.familyMembers.values()].map((token) => (\n\t\t\t\t\t\t\t\t<StateLeaf key={token.key} tools={props.tools} token={token} />\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t: null}\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<StateLeaf tools={props.tools} token={props.node} />\n\t\t\t)}\n\t\t</section>\n\t)\n}\nfunction StateLeaf(props: { tools: Tools; token: Token }): VNode {\n\tconst getValue = useGetter(props.token)\n\tconst writable = !props.token.type.startsWith(`readonly`)\n\tconst setValue = writable\n\t\t? useSetter(props.token as WritableToken<unknown, any, any>)\n\t\t: undefined\n\tconst value = () => {\n\t\ttry {\n\t\t\treturn getValue()\n\t\t} catch (error) {\n\t\t\treturn error\n\t\t}\n\t}\n\treturn (\n\t\t<section class=\"state-leaf\" data-testid={`state-value-${props.token.key}`}>\n\t\t\t<JsonEditor\n\t\t\t\tlabel={<h3>{props.token.family?.subKey ?? props.token.key}</h3>}\n\t\t\t\tactions={\n\t\t\t\t\tprops.token.family ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label={`Dispose ${props.token.key}`}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\tdisposeFromStore(props.tools.store, props.token)\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t×\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null\n\t\t\t\t}\n\t\t\t\ttools={props.tools}\n\t\t\t\tvalue={value()}\n\t\t\t\tchange={\n\t\t\t\t\tsetValue\n\t\t\t\t\t\t? (update) => {\n\t\t\t\t\t\t\t\t// Validate edits before opening an atom.io write operation.\n\t\t\t\t\t\t\t\tconst next = update(getValue())\n\t\t\t\t\t\t\t\tsetValue(() => next)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tpath={\n\t\t\t\t\tprops.token.family\n\t\t\t\t\t\t? [props.token.family.key, props.token.family.subKey]\n\t\t\t\t\t\t: [props.token.key]\n\t\t\t\t}\n\t\t\t/>\n\t\t</section>\n\t)\n}\nexport function TransactionIndex(props: { tools: Tools }): VNode {\n\tconst getTransactionIndex = useGetter(props.tools.transactionIndex)\n\tconst visible = () =>\n\t\tgetTransactionIndex().filter(\n\t\t\t(token) => !isReservedIntrospectionKey(token.key),\n\t\t)\n\treturn (\n\t\t<article class=\"index\" data-testid=\"transaction-index\">\n\t\t\t{visible().length === 0 ? (\n\t\t\t\t<p>(no transactions)</p>\n\t\t\t) : (\n\t\t\t\tvisible().map((token) => (\n\t\t\t\t\t<TransactionLog key={token.key} tools={props.tools} token={token} />\n\t\t\t\t))\n\t\t\t)}\n\t\t</article>\n\t)\n}\nfunction TransactionLog(props: {\n\ttools: Tools\n\ttoken: TransactionToken<any>\n}): VNode {\n\tconst getTransactionLog = useGetter(\n\t\tfindInStore(\n\t\t\tprops.tools.store,\n\t\t\tprops.tools.transactionLogSelectors,\n\t\t\tprops.token.key,\n\t\t),\n\t)\n\tconst [getOpen, toggle] = useExpanded(props.tools, [props.token.key])\n\treturn (\n\t\t<section class=\"node\" data-testid={`transaction-${props.token.key}`}>\n\t\t\t<header>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-expanded={getOpen()}\n\t\t\t\t\tdata-testid={`open-close-transaction-${props.token.key}`}\n\t\t\t\t\tonClick={toggle}\n\t\t\t\t>\n\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<h2>{props.token.key}</h2>\n\t\t\t\t<small>({getTransactionLog().length})</small>\n\t\t\t</header>\n\t\t\t{getOpen()\n\t\t\t\t? getTransactionLog().map((event, index) => (\n\t\t\t\t\t\t<EventView\n\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\ttools={props.tools}\n\t\t\t\t\t\t\tevent={event}\n\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))\n\t\t\t\t: null}\n\t\t</section>\n\t)\n}\n// Events are recursive discriminated records, including user-defined transaction outputs.\nexport function EventView(props: {\n\ttools: Tools\n\tevent: any\n\tindex: number\n}): VNode {\n\tconst [getOpen, toggle] = useExpanded(\n\t\tprops.tools,\n\t\t[`event`, props.event.token?.key ?? ``, String(props.index)],\n\t\ttrue,\n\t)\n\treturn (\n\t\t<section\n\t\t\tclass=\"event\"\n\t\t\tdata-testid={`${props.event.type === `transaction_outcome` ? `transaction` : `timeline`}-update-${props.event.token?.key}-${props.index}`}\n\t\t>\n\t\t\t<header>\n\t\t\t\t<button type=\"button\" aria-expanded={getOpen()} onClick={toggle}>\n\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<strong>{props.event.token?.key}</strong>\n\t\t\t\t<small>{props.event.type}</small>\n\t\t\t</header>\n\t\t\t{getOpen() ? (\n\t\t\t\tprops.event.type === `transaction_outcome` ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tparams: <code>{describe(props.event.params)}</code>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\toutput: <code>{describe(props.event.output)}</code>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<section class=\"impact\">\n\t\t\t\t\t\t\t{props.event.subEvents.map((event: any, index: number) => (\n\t\t\t\t\t\t\t\t<EventView\n\t\t\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\t\t\ttools={props.tools}\n\t\t\t\t\t\t\t\t\tevent={event}\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</section>\n\t\t\t\t\t</>\n\t\t\t\t) : props.event.update ? (\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<del>{describe(props.event.update.oldValue)}</del> →{` `}\n\t\t\t\t\t\t<ins>{describe(props.event.update.newValue)}</ins>\n\t\t\t\t\t</p>\n\t\t\t\t) : (\n\t\t\t\t\t<code>{describe(props.event)}</code>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\nexport function TimelineIndex(props: { tools: Tools }): VNode {\n\tconst getTimelineIndex = useGetter(props.tools.timelineIndex)\n\tconst groups = () => {\n\t\tconst result = new Map<string, TimelineToken<any>[]>()\n\t\tfor (const token of getTimelineIndex()) {\n\t\t\tif (isReservedIntrospectionKey(token.key) || token.key.startsWith(`👁‍🗨`))\n\t\t\t\tcontinue\n\t\t\tconst key = token.family?.key ?? ``\n\t\t\tconst members = result.get(key) ?? []\n\t\t\tmembers.push(token)\n\t\t\tresult.set(key, members)\n\t\t}\n\t\treturn [...result]\n\t}\n\treturn (\n\t\t<article class=\"index\" data-testid=\"timeline-index\">\n\t\t\t{groups().length === 0 ? (\n\t\t\t\t<p>(no timelines)</p>\n\t\t\t) : (\n\t\t\t\tgroups().map(([family, members]) => (\n\t\t\t\t\t<section\n\t\t\t\t\t\tkey={family}\n\t\t\t\t\t\tdata-testid={family ? `timeline-family-${family}` : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t{family ? <h2>{family}</h2> : null}\n\t\t\t\t\t\t{members.map((token) => (\n\t\t\t\t\t\t\t<TimelineLog key={token.key} tools={props.tools} token={token} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</section>\n\t\t\t\t))\n\t\t\t)}\n\t\t</article>\n\t)\n}\nfunction TimelineLog(props: { tools: Tools; token: TimelineToken<any> }): VNode {\n\tconst controls = useTimeline(props.token)\n\tconst getTimeline = useGetter(\n\t\tfindInStore(\n\t\t\tprops.tools.store,\n\t\t\tprops.tools.timelineSelectors,\n\t\t\tprops.token.key,\n\t\t),\n\t)\n\tconst [getOpen, toggle] = useExpanded(props.tools, [props.token.key])\n\treturn (\n\t\t<section class=\"node\" data-testid={`timeline-${props.token.key}`}>\n\t\t\t<header>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-expanded={getOpen()}\n\t\t\t\t\tdata-testid={`open-close-timeline-${props.token.key}`}\n\t\t\t\t\tonClick={toggle}\n\t\t\t\t>\n\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<h2>{props.token.family?.subKey ?? props.token.key}</h2>\n\t\t\t\t<small>\n\t\t\t\t\t({controls.getCursor()}/{controls.getLength()})\n\t\t\t\t</small>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdisabled={controls.getCursor() === 0}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tprops.tools.attempt(controls.undo)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tundo\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdisabled={controls.getCursor() === controls.getLength()}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tprops.tools.attempt(controls.redo)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tredo\n\t\t\t\t</button>\n\t\t\t</header>\n\t\t\t{getOpen() ? (\n\t\t\t\t<section>\n\t\t\t\t\t{getTimeline().history.map((event, index) => (\n\t\t\t\t\t\t<section key={index}>\n\t\t\t\t\t\t\t{index === getTimeline().at ? (\n\t\t\t\t\t\t\t\t<p class=\"you-are-here\">you are here</p>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<EventView tools={props.tools} event={event} index={index} />\n\t\t\t\t\t\t</section>\n\t\t\t\t\t))}\n\t\t\t\t\t{getTimeline().at === getTimeline().history.length ? (\n\t\t\t\t\t\t<p class=\"you-are-here\">you are here</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</section>\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\n","import type { VNode } from \"@atom.io/spa\"\nimport { onCleanup, onMount, render, useGetter } from \"@atom.io/spa\"\nimport type { RootStore } from \"atom.io/internal\"\nimport { IMPLICIT } from \"atom.io/internal\"\n\nimport { StateIndex, TimelineIndex, TransactionIndex } from \"./Indexes.tsx\"\nimport { useLocal, useSaved, useTools } from \"./store.ts\"\n\nexport interface AtomIODevtoolsProps {\n\t/** Inspected store. Fixed for this component instance; change its key to replace it. */\n\tstore?: RootStore\n\thideByDefault?: boolean\n}\n/** Owns a rendering root in the inspected store, independently of its parent island. */\nexport function AtomIODevtools(props: AtomIODevtoolsProps): VNode {\n\tlet host: HTMLElement | null = null\n\tconst attach = (element: HTMLElement | null) => {\n\t\thost = element\n\t}\n\tonMount(() => {\n\t\tconst store = props.store ?? IMPLICIT.STORE\n\t\tconst root = render(\n\t\t\t() => <Panel store={store} hideByDefault={props.hideByDefault ?? false} />,\n\t\t\thost!,\n\t\t\t{ store },\n\t\t)\n\t\tonCleanup(root.dispose)\n\t})\n\treturn <spa-devtools ref={attach} />\n}\nconst VIEWS = [`atoms`, `selectors`, `transactions`, `timelines`] as const\ntype View = (typeof VIEWS)[number]\nfunction Panel(props: { store: RootStore; hideByDefault: boolean }): VNode {\n\tconst tools = useTools(props.store)\n\tconst [getHidden, setHidden] = useSaved(\n\t\tprops.store,\n\t\t`🔍 Devtools Are Hidden`,\n\t\tprops.hideByDefault,\n\t)\n\tconst [getOpen, setOpen] = useSaved(props.store, `🔍 Devtools Are Open`, true)\n\tconst [getSelection, setSelection] = useSaved<string>(\n\t\tprops.store,\n\t\t`🔍 Devtools View`,\n\t\t`atoms`,\n\t)\n\tconst view = () =>\n\t\tVIEWS.includes(getSelection() as View) ? (getSelection() as View) : `atoms`\n\tconst [getPosition, setPosition] = useLocal(props.store, { x: 0, y: 0 })\n\tconst getError = useGetter(tools.error)\n\tlet panel: HTMLElement | null = null\n\tconst attach = (element: HTMLElement | null) => {\n\t\tpanel = element\n\t}\n\tlet drag:\n\t\t| { id: number; startX: number; startY: number; x: number; y: number }\n\t\t| undefined\n\tonMount(() => {\n\t\tconst shortcut = (event: KeyboardEvent) => {\n\t\t\tif (event.ctrlKey && event.shiftKey && event.code === `KeyA`) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetHidden((value) => !value)\n\t\t\t}\n\t\t}\n\t\tconst reset = () => {\n\t\t\tsetPosition({ x: 0, y: 0 })\n\t\t}\n\t\tdocument.addEventListener(`keydown`, shortcut)\n\t\twindow.addEventListener(`resize`, reset)\n\t\tonCleanup(() => {\n\t\t\tdocument.removeEventListener(`keydown`, shortcut)\n\t\t\twindow.removeEventListener(`resize`, reset)\n\t\t})\n\t})\n\treturn (\n\t\t<main\n\t\t\tref={attach}\n\t\t\tdata-css=\"spa-devtools\"\n\t\t\tdata-testid=\"atom-io-devtools\"\n\t\t\thidden={getHidden()}\n\t\t\tdata-open={getOpen()}\n\t\t\tstyle={`transform:translate(${getPosition().x}px,${getPosition().y}px)`}\n\t\t>\n\t\t\t<header class=\"toolbar\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"drag-handle\"\n\t\t\t\t\taria-label=\"Move debugger\"\n\t\t\t\t\ttitle=\"Drag to move; arrow keys to nudge\"\n\t\t\t\t\tonPointerdown={(event) => {\n\t\t\t\t\t\tif (event.button !== 0) return\n\t\t\t\t\t\tdrag = {\n\t\t\t\t\t\t\tid: event.pointerId,\n\t\t\t\t\t\t\tstartX: event.clientX,\n\t\t\t\t\t\t\tstartY: event.clientY,\n\t\t\t\t\t\t\t...getPosition(),\n\t\t\t\t\t\t}\n\t\t\t\t\t\t;(event.currentTarget as HTMLElement).setPointerCapture(\n\t\t\t\t\t\t\tevent.pointerId,\n\t\t\t\t\t\t)\n\t\t\t\t\t}}\n\t\t\t\t\tonPointermove={(event) => {\n\t\t\t\t\t\tif (!drag || drag.id !== event.pointerId || !panel) return\n\t\t\t\t\t\tconst rect = panel.getBoundingClientRect()\n\t\t\t\t\t\tconst next = {\n\t\t\t\t\t\t\tx: drag.x + event.clientX - drag.startX,\n\t\t\t\t\t\t\ty: drag.y + event.clientY - drag.startY,\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnext.x = Math.max(\n\t\t\t\t\t\t\tgetPosition().x - rect.left,\n\t\t\t\t\t\t\tMath.min(next.x, getPosition().x + window.innerWidth - rect.right),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tnext.y = Math.max(\n\t\t\t\t\t\t\tgetPosition().y - rect.top,\n\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\tnext.y,\n\t\t\t\t\t\t\t\tgetPosition().y + window.innerHeight - rect.bottom,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tsetPosition(next)\n\t\t\t\t\t}}\n\t\t\t\t\tonPointerup={() => {\n\t\t\t\t\t\tdrag = undefined\n\t\t\t\t\t}}\n\t\t\t\t\tonPointercancel={() => {\n\t\t\t\t\t\tdrag = undefined\n\t\t\t\t\t}}\n\t\t\t\t\tonKeydown={(event) => {\n\t\t\t\t\t\tconst step = {\n\t\t\t\t\t\t\tArrowLeft: [-10, 0],\n\t\t\t\t\t\t\tArrowRight: [10, 0],\n\t\t\t\t\t\t\tArrowUp: [0, -10],\n\t\t\t\t\t\t\tArrowDown: [0, 10],\n\t\t\t\t\t\t}[event.key]\n\t\t\t\t\t\tif (step) {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tsetPosition(({ x, y }) => ({ x: x + step[0], y: y + step[1] }))\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t⠿\n\t\t\t\t</button>\n\t\t\t\t<h1>atom.io</h1>\n\t\t\t\t{getOpen() ? (\n\t\t\t\t\t<nav aria-label=\"Debugger views\">\n\t\t\t\t\t\t{VIEWS.map((name) => (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\taria-pressed={view() === name}\n\t\t\t\t\t\t\t\tdata-testid={`view-${name}`}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetSelection(name)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{name}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</nav>\n\t\t\t\t) : null}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label={getOpen() ? `Minimize debugger` : `Open debugger`}\n\t\t\t\t\tdata-testid=\"open-close-devtools\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetOpen((value) => !value)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{getOpen() ? `−` : `🔍`}\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label=\"Hide debugger (Ctrl+Shift+A)\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetHidden(true)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t×\n\t\t\t\t</button>\n\t\t\t</header>\n\t\t\t{getOpen() ? (\n\t\t\t\t<>\n\t\t\t\t\t{getError() ? <p role=\"alert\">{getError()}</p> : null}\n\t\t\t\t\t{view() === `atoms` || view() === `selectors` ? (\n\t\t\t\t\t\t<StateIndex\n\t\t\t\t\t\t\tkey={view()}\n\t\t\t\t\t\t\ttools={tools}\n\t\t\t\t\t\t\ttype={view() as `atoms` | `selectors`}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : view() === `transactions` ? (\n\t\t\t\t\t\t<TransactionIndex tools={tools} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<TimelineIndex tools={tools} />\n\t\t\t\t\t)}\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</main>\n\t)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_spa","_spa","_spa"],"sources":["../src/store.ts","../src/value.ts","../src/JsonEditor.tsx","../src/Indexes.tsx","../src/AtomIODevtools.tsx"],"sourcesContent":["import type { Accessor } from \"@atom.io/spa\"\nimport { onCleanup, useGetter, useId, useSetter } from \"@atom.io/spa\"\nimport type { RegularAtomFamilyToken, RegularAtomToken, Setter } from \"atom.io\"\nimport type { RootStore } from \"atom.io/internal\"\nimport {\n\tcreateRegularAtomFamily,\n\tdisposeFromStore,\n\tfindInStore,\n\tsetIntoStore,\n} from \"atom.io/internal\"\nimport type { IntrospectionStates } from \"atom.io/introspection\"\nimport { attachIntrospectionStates } from \"atom.io/introspection\"\n\nconst locals = new WeakMap<RootStore, RegularAtomFamilyToken<unknown, string>>()\nconst introspection = new WeakMap<RootStore, IntrospectionStates>()\nexport type Path = readonly string[]\nexport interface Tools extends IntrospectionStates {\n\tstore: RootStore\n\texpanded: RegularAtomToken<Record<string, boolean>>\n\terror: RegularAtomToken<string>\n\tattempt(run: () => void): void\n}\n\nfunction ownedAtom<T>(store: RootStore, initial: T): RegularAtomToken<T> {\n\tlet family = locals.get(store)\n\tif (!family) {\n\t\tfamily = createRegularAtomFamily<unknown, string, never>(store, {\n\t\t\tkey: `🔍 spa devtools`,\n\t\t\tdefault: undefined,\n\t\t})\n\t\tlocals.set(store, family)\n\t}\n\tconst token = findInStore(store, family, useId()) as RegularAtomToken<T>\n\tsetIntoStore(store, token, initial)\n\tonCleanup(() => {\n\t\tdisposeFromStore(store, token)\n\t})\n\treturn token\n}\nexport function useLocal<T>(\n\tstore: RootStore,\n\tinitial: T,\n): [Accessor<T>, (next: T | Setter<T>) => void] {\n\tconst token = ownedAtom(store, initial)\n\treturn [useGetter(token) as Accessor<T>, useSetter(token)]\n}\nexport function useSaved<T>(\n\tstore: RootStore,\n\tkey: string,\n\tfallback: T,\n): [Accessor<T>, (next: T | Setter<T>) => void] {\n\tlet initial = fallback\n\ttry {\n\t\tconst saved: unknown = JSON.parse(localStorage.getItem(key) ?? `null`)\n\t\tif (saved !== null && typeof saved === typeof fallback) initial = saved as T\n\t} catch {\n\t\t/* Storage may be unavailable. */\n\t}\n\tconst [getValue, setValue] = useLocal(store, initial)\n\treturn [\n\t\tgetValue,\n\t\t(next) => {\n\t\t\tsetValue(next)\n\t\t\ttry {\n\t\t\t\tlocalStorage.setItem(key, JSON.stringify(getValue()))\n\t\t\t} catch {\n\t\t\t\t/* Keep in-memory state when storage is unavailable. */\n\t\t\t}\n\t\t},\n\t]\n}\nexport function useTools(store: RootStore): Tools {\n\tlet states = introspection.get(store)\n\tif (!states) {\n\t\tstates = attachIntrospectionStates(store)\n\t\tintrospection.set(store, states)\n\t}\n\tlet expanded: Record<string, boolean> = {}\n\ttry {\n\t\tconst saved: unknown = JSON.parse(\n\t\t\tlocalStorage.getItem(`🔍 spa expanded`) ?? `{}`,\n\t\t)\n\t\tif (\n\t\t\tsaved &&\n\t\t\ttypeof saved === `object` &&\n\t\t\t!Array.isArray(saved) &&\n\t\t\tObject.values(saved).every((value) => typeof value === `boolean`)\n\t\t)\n\t\t\texpanded = saved as Record<string, boolean>\n\t} catch {\n\t\t/* Ignore corrupt or unavailable storage. */\n\t}\n\tconst error = ownedAtom(store, ``)\n\tconst setError = useSetter(error)\n\treturn {\n\t\t...states,\n\t\tstore,\n\t\terror,\n\t\texpanded: ownedAtom(store, expanded),\n\t\tattempt(run) {\n\t\t\ttry {\n\t\t\t\trun()\n\t\t\t\tsetError(``)\n\t\t\t} catch (caught) {\n\t\t\t\tsetError(caught instanceof Error ? caught.message : String(caught))\n\t\t\t}\n\t\t},\n\t}\n}\nexport function useExpanded(\n\ttools: Tools,\n\tpath: Path,\n\tinitial = false,\n): [Accessor<boolean>, (event: MouseEvent) => void] {\n\tconst getExpanded = useGetter(tools.expanded)\n\tconst setExpanded = useSetter(tools.expanded)\n\tconst key = JSON.stringify(path)\n\tconst group = `all:${JSON.stringify(path.slice(0, -1))}`\n\tconst read = () => getExpanded()[key] ?? getExpanded()[group] ?? initial\n\treturn [\n\t\tread,\n\t\t(event) => {\n\t\t\tconst next = !read()\n\t\t\tsetExpanded((previous) => {\n\t\t\t\tconst result = { ...previous }\n\t\t\t\tif (event.shiftKey) {\n\t\t\t\t\tconst parent = JSON.stringify(path.slice(0, -1))\n\t\t\t\t\tfor (const item of Object.keys(result)) {\n\t\t\t\t\t\tif (item.startsWith(`[`)) {\n\t\t\t\t\t\t\tconst candidate = JSON.parse(item) as string[]\n\t\t\t\t\t\t\tif (JSON.stringify(candidate.slice(0, -1)) === parent)\n\t\t\t\t\t\t\t\tReflect.deleteProperty(result, item)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tresult[group] = next\n\t\t\t\t} else {\n\t\t\t\t\tresult[key] = next\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tlocalStorage.setItem(`🔍 spa expanded`, JSON.stringify(result))\n\t\t\t\t} catch {\n\t\t\t\t\t/* Keep in-memory expansion state. */\n\t\t\t\t}\n\t\t\t\treturn result\n\t\t\t})\n\t\t},\n\t]\n}\n","export type Change = (update: (previous: unknown) => unknown) => void\nexport type JsonKind =\n\t| `string`\n\t| `number`\n\t| `boolean`\n\t| `null`\n\t| `array`\n\t| `object`\nexport function kind(value: unknown): JsonKind | `other` {\n\tif (value === null) return `null`\n\tif (Array.isArray(value)) return `array`\n\tif (\n\t\ttypeof value === `object` &&\n\t\t(Object.getPrototypeOf(value) === Object.prototype ||\n\t\t\tObject.getPrototypeOf(value) === null)\n\t)\n\t\treturn `object`\n\tif (\n\t\ttypeof value === `string` ||\n\t\ttypeof value === `number` ||\n\t\ttypeof value === `boolean`\n\t)\n\t\treturn typeof value as JsonKind\n\treturn `other`\n}\nexport function describe(value: unknown): string {\n\ttry {\n\t\tconst seen = new WeakSet<object>()\n\t\treturn (\n\t\t\tJSON.stringify(value, (_, item: unknown) => {\n\t\t\t\tif (typeof item === `bigint`) return `${item}n`\n\t\t\t\tif (item instanceof Error) return `${item.name}: ${item.message}`\n\t\t\t\tif (item instanceof Map) return { Map: [...item] }\n\t\t\t\tif (item instanceof Set) return { Set: [...item] }\n\t\t\t\tif (typeof item === `object` && item !== null) {\n\t\t\t\t\tif (seen.has(item)) return `[Circular]`\n\t\t\t\t\tseen.add(item)\n\t\t\t\t}\n\t\t\t\treturn item\n\t\t\t}) ?? String(value)\n\t\t)\n\t} catch {\n\t\treturn Object.prototype.toString.call(value)\n\t}\n}\nexport function convert(value: unknown, type: JsonKind): unknown {\n\tswitch (type) {\n\t\tcase `null`:\n\t\t\treturn null\n\t\tcase `string`:\n\t\t\treturn value == null\n\t\t\t\t? ``\n\t\t\t\t: typeof value === `string`\n\t\t\t\t\t? value\n\t\t\t\t\t: describe(value)\n\t\tcase `number`: {\n\t\t\tconst next = Array.isArray(value) ? value.length : Number(value)\n\t\t\treturn Number.isFinite(next) ? next : 0\n\t\t}\n\t\tcase `boolean`:\n\t\t\treturn typeof value === `string` ? value === `true` : Boolean(value)\n\t\tcase `array`:\n\t\t\treturn Array.isArray(value)\n\t\t\t\t? value\n\t\t\t\t: value == null\n\t\t\t\t\t? []\n\t\t\t\t\t: typeof value === `object`\n\t\t\t\t\t\t? Object.entries(value)\n\t\t\t\t\t\t: [value]\n\t\tcase `object`:\n\t\t\treturn kind(value) === `object`\n\t\t\t\t? value\n\t\t\t\t: Array.isArray(value)\n\t\t\t\t\t? Object.fromEntries(value.map((item, index) => [index, item]))\n\t\t\t\t\t: value == null\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { value }\n\t}\n}\n","import type { Children, SpaElement } from \"@atom.io/spa\"\n\nimport type { Path, Tools } from \"./store.ts\"\nimport { useExpanded } from \"./store.ts\"\nimport type { Change, JsonKind } from \"./value.ts\"\nimport { convert, describe, kind } from \"./value.ts\"\n\ninterface EditorProps {\n\ttools: Tools\n\tvalue: unknown\n\tchange?: Change | undefined\n\tpath: Path\n\tancestors?: readonly unknown[]\n\tlabel?: Children\n\tactions?: Children\n}\nconst TYPES: JsonKind[] = [\n\t`string`,\n\t`number`,\n\t`boolean`,\n\t`null`,\n\t`array`,\n\t`object`,\n]\nexport function JsonEditor(props: EditorProps): SpaElement {\n\tconst [getExpanded, toggle] = useExpanded(props.tools, props.path)\n\tconst circular = () =>\n\t\t(props.ancestors?.includes(props.value) ?? false) || props.path.length > 50\n\tconst container = () =>\n\t\t!circular() &&\n\t\t(kind(props.value) === `object` || kind(props.value) === `array`)\n\tconst entries = () => Object.entries(props.value as Record<string, unknown>)\n\treturn (\n\t\t<section\n\t\t\tclass=\"json-editor\"\n\t\t\tdata-testid={`${props.path.join(`.`)}-state-editor`}\n\t\t>\n\t\t\t<header>\n\t\t\t\t{container() ? (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\taria-label={`Expand ${props.path.at(-1)}`}\n\t\t\t\t\t\taria-expanded={getExpanded()}\n\t\t\t\t\t\tonClick={toggle}\n\t\t\t\t\t>\n\t\t\t\t\t\t{getExpanded() ? `▾` : `▸`}\n\t\t\t\t\t</button>\n\t\t\t\t) : (\n\t\t\t\t\t<span class=\"carat-spacer\" />\n\t\t\t\t)}\n\t\t\t\t<span class=\"field-name\">{props.label}</span>\n\t\t\t\t{props.change ? (\n\t\t\t\t\t<select\n\t\t\t\t\t\taria-label={`Type of ${props.path.at(-1)}`}\n\t\t\t\t\t\tvalue={kind(props.value)}\n\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\tconst type = event.currentTarget.value as JsonKind\n\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\tprops.change?.((previous) => convert(previous, type))\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<option value=\"other\" disabled>\n\t\t\t\t\t\t\tother\n\t\t\t\t\t\t</option>\n\t\t\t\t\t\t{TYPES.map((type) => (\n\t\t\t\t\t\t\t<option value={type}>{type}</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</select>\n\t\t\t\t) : (\n\t\t\t\t\t<small>{kind(props.value)}</small>\n\t\t\t\t)}\n\t\t\t\t{container() ? (\n\t\t\t\t\t<code title={describe(props.value)}>{describe(props.value)}</code>\n\t\t\t\t) : circular() ? (\n\t\t\t\t\t<code>[Circular]</code>\n\t\t\t\t) : (\n\t\t\t\t\t<Primitive\n\t\t\t\t\t\tvalue={props.value}\n\t\t\t\t\t\tchange={props.change}\n\t\t\t\t\t\ttools={props.tools}\n\t\t\t\t\t\tlabel={props.path.at(-1) ?? `value`}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t{props.actions}\n\t\t\t</header>\n\t\t\t{container() && getExpanded() ? (\n\t\t\t\t<section class=\"properties\">\n\t\t\t\t\t{entries().map(([key]) => (\n\t\t\t\t\t\t<Property key={key} name={key} editor={props} />\n\t\t\t\t\t))}\n\t\t\t\t\t{props.change ? (\n\t\t\t\t\t\t<footer>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\t\tprops.change?.((previous) => {\n\t\t\t\t\t\t\t\t\t\t\tif (Array.isArray(previous)) return [...previous, null]\n\t\t\t\t\t\t\t\t\t\t\tconst object = previous as Record<string, unknown>\n\t\t\t\t\t\t\t\t\t\t\tlet name = `new`\n\t\t\t\t\t\t\t\t\t\t\twhile (Object.hasOwn(object, name)) name += `_`\n\t\t\t\t\t\t\t\t\t\t\treturn { ...object, [name]: null }\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tadd {Array.isArray(props.value) ? `item` : `property`}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t{Array.isArray(props.value) ? (\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\t\t\tprops.change?.((previous) =>\n\t\t\t\t\t\t\t\t\t\t\t\t[...(previous as unknown[])].sort((a, b) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\ttypeof a === `number` && typeof b === `number`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? a - b\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: describe(a).localeCompare(describe(b)),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\tsort\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</footer>\n\t\t\t\t\t) : null}\n\t\t\t\t</section>\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\nfunction Primitive(props: {\n\tvalue: unknown\n\tchange?: Change | undefined\n\ttools: Tools\n\tlabel: string\n}): SpaElement {\n\tconst set = (value: unknown) => {\n\t\tprops.tools.attempt(() => {\n\t\t\tprops.change?.(() => value)\n\t\t})\n\t}\n\treturn (\n\t\t<span class=\"primitive\">\n\t\t\t{kind(props.value) === `boolean` ? (\n\t\t\t\t<input\n\t\t\t\t\taria-label={props.label}\n\t\t\t\t\ttype=\"checkbox\"\n\t\t\t\t\tchecked={Boolean(props.value)}\n\t\t\t\t\tdisabled={!props.change}\n\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\tset(event.currentTarget.checked)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : kind(props.value) === `string` || kind(props.value) === `number` ? (\n\t\t\t\t<input\n\t\t\t\t\taria-label={props.label}\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tinputmode={kind(props.value) === `number` ? `decimal` : `text`}\n\t\t\t\t\tvalue={String(props.value)}\n\t\t\t\t\treadOnly={!props.change}\n\t\t\t\t\tonInput={(event) => {\n\t\t\t\t\t\tconst text = event.currentTarget.value\n\t\t\t\t\t\tif (kind(props.value) === `string`) set(text)\n\t\t\t\t\t\telse if (text.trim() && Number.isFinite(Number(text)))\n\t\t\t\t\t\t\tset(Number(text))\n\t\t\t\t\t}}\n\t\t\t\t\tonBlur={(event) => {\n\t\t\t\t\t\tevent.currentTarget.value = String(props.value)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : (\n\t\t\t\t<code>{describe(props.value)}</code>\n\t\t\t)}\n\t\t</span>\n\t)\n}\nfunction Property(props: { name: string; editor: EditorProps }): SpaElement {\n\tconst parent = props.editor\n\tconst read = () => (parent.value as Record<string, unknown>)[props.name]\n\tconst change: Change = (update) => {\n\t\tparent.change?.((previous) => {\n\t\t\tif (Array.isArray(previous))\n\t\t\t\treturn previous.map((value, index) =>\n\t\t\t\t\tindex === Number(props.name) ? update(value) : value,\n\t\t\t\t)\n\t\t\tconst object = previous as Record<string, unknown>\n\t\t\treturn { ...object, [props.name]: update(object[props.name]) }\n\t\t})\n\t}\n\treturn (\n\t\t<section class=\"property\">\n\t\t\t<JsonEditor\n\t\t\t\tlabel={\n\t\t\t\t\tparent.change && !Array.isArray(parent.value) ? (\n\t\t\t\t\t\t<input\n\t\t\t\t\t\t\taria-label={`Rename ${props.name}`}\n\t\t\t\t\t\t\tstyle={`width:calc(${Math.max(1, props.name.length)}ch + 6px)`}\n\t\t\t\t\t\t\tvalue={props.name}\n\t\t\t\t\t\t\tonChange={(event) => {\n\t\t\t\t\t\t\t\tconst input = event.currentTarget\n\t\t\t\t\t\t\t\tconst name = input.value\n\t\t\t\t\t\t\t\tparent.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\tparent.change?.((previous) => {\n\t\t\t\t\t\t\t\t\t\tconst object = previous as Record<string, unknown>\n\t\t\t\t\t\t\t\t\t\tif (name !== props.name && Object.hasOwn(object, name))\n\t\t\t\t\t\t\t\t\t\t\tthrow new Error(`Property \"${name}\" already exists`)\n\t\t\t\t\t\t\t\t\t\treturn Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\tObject.entries(object).map(([key, value]) => [\n\t\t\t\t\t\t\t\t\t\t\t\tkey === props.name ? name : key,\n\t\t\t\t\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\tinput.value = props.name\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<strong>{props.name}</strong>\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tactions={\n\t\t\t\t\tparent.change ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label={`Delete ${props.name}`}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tparent.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\tparent.change?.((previous) =>\n\t\t\t\t\t\t\t\t\t\tArray.isArray(previous)\n\t\t\t\t\t\t\t\t\t\t\t? previous.filter(\n\t\t\t\t\t\t\t\t\t\t\t\t\t(_, index) => index !== Number(props.name),\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\t\t\t\t\t\t\t\tObject.entries(previous as object).filter(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t([key]) => key !== props.name,\n\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t×\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null\n\t\t\t\t}\n\t\t\t\ttools={parent.tools}\n\t\t\t\tpath={[...parent.path, props.name]}\n\t\t\t\tvalue={read()}\n\t\t\t\tchange={parent.change ? change : undefined}\n\t\t\t\tancestors={[...(parent.ancestors ?? []), parent.value]}\n\t\t\t/>\n\t\t</section>\n\t)\n}\n","import type { SpaElement } from \"@atom.io/spa\"\nimport { useGetter, useSetter, useTimeline } from \"@atom.io/spa\"\nimport type {\n\tReadableToken,\n\tTimelineToken,\n\tTransactionToken,\n\tWritableToken,\n} from \"atom.io\"\nimport {\n\tdisposeFromStore,\n\tfindInStore,\n\tisReservedIntrospectionKey,\n} from \"atom.io/internal\"\nimport type { FamilyNode } from \"atom.io/introspection\"\n\nimport { JsonEditor } from \"./JsonEditor.tsx\"\nimport type { Tools } from \"./store.ts\"\nimport { useExpanded } from \"./store.ts\"\nimport { describe } from \"./value.ts\"\n\ntype Token = ReadableToken<unknown, any, any>\nexport function StateIndex(props: {\n\ttools: Tools\n\ttype: `atoms` | `selectors`\n}): SpaElement {\n\tconst getStateIndex = useGetter<Map<string, Token | FamilyNode<Token>>>(\n\t\tprops.type === `atoms` ? props.tools.atomIndex : props.tools.selectorIndex,\n\t)\n\treturn (\n\t\t<article class=\"index\" data-testid=\"state-index\">\n\t\t\t{getStateIndex().size === 0 ? (\n\t\t\t\t<p>(no {props.type})</p>\n\t\t\t) : (\n\t\t\t\t[...getStateIndex().values()].map((node) => (\n\t\t\t\t\t<StateNode key={node.key} tools={props.tools} node={node} />\n\t\t\t\t))\n\t\t\t)}\n\t\t</article>\n\t)\n}\nfunction StateNode(props: {\n\ttools: Tools\n\tnode: Token | FamilyNode<Token>\n}): SpaElement {\n\tconst [getOpen, toggle] = useExpanded(props.tools, [props.node.key])\n\treturn (\n\t\t<section class=\"node\" data-testid={`state-${props.node.key}`}>\n\t\t\t{`familyMembers` in props.node ? (\n\t\t\t\t<>\n\t\t\t\t\t<header>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-expanded={getOpen()}\n\t\t\t\t\t\t\tdata-testid={`open-close-state-family-${props.node.key}`}\n\t\t\t\t\t\t\tonClick={toggle}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<h2>{props.node.key}</h2>\n\t\t\t\t\t\t<small>family</small>\n\t\t\t\t\t</header>\n\t\t\t\t\t{getOpen()\n\t\t\t\t\t\t? [...props.node.familyMembers.values()].map((token) => (\n\t\t\t\t\t\t\t\t<StateLeaf key={token.key} tools={props.tools} token={token} />\n\t\t\t\t\t\t\t))\n\t\t\t\t\t\t: null}\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<StateLeaf tools={props.tools} token={props.node} />\n\t\t\t)}\n\t\t</section>\n\t)\n}\nfunction StateLeaf(props: { tools: Tools; token: Token }): SpaElement {\n\tconst getValue = useGetter(props.token)\n\tconst writable = !props.token.type.startsWith(`readonly`)\n\tconst setValue = writable\n\t\t? useSetter(props.token as WritableToken<unknown, any, any>)\n\t\t: undefined\n\tconst value = () => {\n\t\ttry {\n\t\t\treturn getValue()\n\t\t} catch (error) {\n\t\t\treturn error\n\t\t}\n\t}\n\treturn (\n\t\t<section class=\"state-leaf\" data-testid={`state-value-${props.token.key}`}>\n\t\t\t<JsonEditor\n\t\t\t\tlabel={<h3>{props.token.family?.subKey ?? props.token.key}</h3>}\n\t\t\t\tactions={\n\t\t\t\t\tprops.token.family ? (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\taria-label={`Dispose ${props.token.key}`}\n\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\tprops.tools.attempt(() => {\n\t\t\t\t\t\t\t\t\tdisposeFromStore(props.tools.store, props.token)\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t×\n\t\t\t\t\t\t</button>\n\t\t\t\t\t) : null\n\t\t\t\t}\n\t\t\t\ttools={props.tools}\n\t\t\t\tvalue={value()}\n\t\t\t\tchange={\n\t\t\t\t\tsetValue\n\t\t\t\t\t\t? (update) => {\n\t\t\t\t\t\t\t\t// Validate edits before opening an atom.io write operation.\n\t\t\t\t\t\t\t\tconst next = update(getValue())\n\t\t\t\t\t\t\t\tsetValue(() => next)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tpath={\n\t\t\t\t\tprops.token.family\n\t\t\t\t\t\t? [props.token.family.key, props.token.family.subKey]\n\t\t\t\t\t\t: [props.token.key]\n\t\t\t\t}\n\t\t\t/>\n\t\t</section>\n\t)\n}\nexport function TransactionIndex(props: { tools: Tools }): SpaElement {\n\tconst getTransactionIndex = useGetter(props.tools.transactionIndex)\n\tconst visible = () =>\n\t\tgetTransactionIndex().filter(\n\t\t\t(token) => !isReservedIntrospectionKey(token.key),\n\t\t)\n\treturn (\n\t\t<article class=\"index\" data-testid=\"transaction-index\">\n\t\t\t{visible().length === 0 ? (\n\t\t\t\t<p>(no transactions)</p>\n\t\t\t) : (\n\t\t\t\tvisible().map((token) => (\n\t\t\t\t\t<TransactionLog key={token.key} tools={props.tools} token={token} />\n\t\t\t\t))\n\t\t\t)}\n\t\t</article>\n\t)\n}\nfunction TransactionLog(props: {\n\ttools: Tools\n\ttoken: TransactionToken<any>\n}): SpaElement {\n\tconst getTransactionLog = useGetter(\n\t\tfindInStore(\n\t\t\tprops.tools.store,\n\t\t\tprops.tools.transactionLogSelectors,\n\t\t\tprops.token.key,\n\t\t),\n\t)\n\tconst [getOpen, toggle] = useExpanded(props.tools, [props.token.key])\n\treturn (\n\t\t<section class=\"node\" data-testid={`transaction-${props.token.key}`}>\n\t\t\t<header>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-expanded={getOpen()}\n\t\t\t\t\tdata-testid={`open-close-transaction-${props.token.key}`}\n\t\t\t\t\tonClick={toggle}\n\t\t\t\t>\n\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<h2>{props.token.key}</h2>\n\t\t\t\t<small>({getTransactionLog().length})</small>\n\t\t\t</header>\n\t\t\t{getOpen()\n\t\t\t\t? getTransactionLog().map((event, index) => (\n\t\t\t\t\t\t<EventView\n\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\ttools={props.tools}\n\t\t\t\t\t\t\tevent={event}\n\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))\n\t\t\t\t: null}\n\t\t</section>\n\t)\n}\n// Events are recursive discriminated records, including user-defined transaction outputs.\n/** @internal Used by contributor tools or implementation tests. */\nexport function EventView(props: {\n\ttools: Tools\n\tevent: any\n\tindex: number\n}): SpaElement {\n\tconst [getOpen, toggle] = useExpanded(\n\t\tprops.tools,\n\t\t[`event`, props.event.token?.key ?? ``, String(props.index)],\n\t\ttrue,\n\t)\n\treturn (\n\t\t<section\n\t\t\tclass=\"event\"\n\t\t\tdata-testid={`${props.event.type === `transaction_outcome` ? `transaction` : `timeline`}-update-${props.event.token?.key}-${props.index}`}\n\t\t>\n\t\t\t<header>\n\t\t\t\t<button type=\"button\" aria-expanded={getOpen()} onClick={toggle}>\n\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<strong>{props.event.token?.key}</strong>\n\t\t\t\t<small>{props.event.type}</small>\n\t\t\t</header>\n\t\t\t{getOpen() ? (\n\t\t\t\tprops.event.type === `transaction_outcome` ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\tparams: <code>{describe(props.event.params)}</code>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<p>\n\t\t\t\t\t\t\toutput: <code>{describe(props.event.output)}</code>\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t<section class=\"impact\">\n\t\t\t\t\t\t\t{props.event.subEvents.map((event: any, index: number) => (\n\t\t\t\t\t\t\t\t<EventView\n\t\t\t\t\t\t\t\t\tkey={index}\n\t\t\t\t\t\t\t\t\ttools={props.tools}\n\t\t\t\t\t\t\t\t\tevent={event}\n\t\t\t\t\t\t\t\t\tindex={index}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</section>\n\t\t\t\t\t</>\n\t\t\t\t) : props.event.update ? (\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<del>{describe(props.event.update.oldValue)}</del> →{` `}\n\t\t\t\t\t\t<ins>{describe(props.event.update.newValue)}</ins>\n\t\t\t\t\t</p>\n\t\t\t\t) : (\n\t\t\t\t\t<code>{describe(props.event)}</code>\n\t\t\t\t)\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\nexport function TimelineIndex(props: { tools: Tools }): SpaElement {\n\tconst getTimelineIndex = useGetter(props.tools.timelineIndex)\n\tconst groups = () => {\n\t\tconst result = new Map<string, TimelineToken<any>[]>()\n\t\tfor (const token of getTimelineIndex()) {\n\t\t\tif (isReservedIntrospectionKey(token.key) || token.key.startsWith(`👁‍🗨`))\n\t\t\t\tcontinue\n\t\t\tconst key = token.family?.key ?? ``\n\t\t\tconst members = result.get(key) ?? []\n\t\t\tmembers.push(token)\n\t\t\tresult.set(key, members)\n\t\t}\n\t\treturn [...result]\n\t}\n\treturn (\n\t\t<article class=\"index\" data-testid=\"timeline-index\">\n\t\t\t{groups().length === 0 ? (\n\t\t\t\t<p>(no timelines)</p>\n\t\t\t) : (\n\t\t\t\tgroups().map(([family, members]) => (\n\t\t\t\t\t<section\n\t\t\t\t\t\tkey={family}\n\t\t\t\t\t\tdata-testid={family ? `timeline-family-${family}` : undefined}\n\t\t\t\t\t>\n\t\t\t\t\t\t{family ? <h2>{family}</h2> : null}\n\t\t\t\t\t\t{members.map((token) => (\n\t\t\t\t\t\t\t<TimelineLog key={token.key} tools={props.tools} token={token} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</section>\n\t\t\t\t))\n\t\t\t)}\n\t\t</article>\n\t)\n}\nfunction TimelineLog(props: {\n\ttools: Tools\n\ttoken: TimelineToken<any>\n}): SpaElement {\n\tconst controls = useTimeline(props.token)\n\tconst getTimeline = useGetter(\n\t\tfindInStore(\n\t\t\tprops.tools.store,\n\t\t\tprops.tools.timelineSelectors,\n\t\t\tprops.token.key,\n\t\t),\n\t)\n\tconst [getOpen, toggle] = useExpanded(props.tools, [props.token.key])\n\treturn (\n\t\t<section class=\"node\" data-testid={`timeline-${props.token.key}`}>\n\t\t\t<header>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-expanded={getOpen()}\n\t\t\t\t\tdata-testid={`open-close-timeline-${props.token.key}`}\n\t\t\t\t\tonClick={toggle}\n\t\t\t\t>\n\t\t\t\t\t{getOpen() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<h2>{props.token.family?.subKey ?? props.token.key}</h2>\n\t\t\t\t<small>\n\t\t\t\t\t({controls.getCursor()}/{controls.getLength()})\n\t\t\t\t</small>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdisabled={controls.getCursor() === 0}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tprops.tools.attempt(controls.undo)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tundo\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tdisabled={controls.getCursor() === controls.getLength()}\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tprops.tools.attempt(controls.redo)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tredo\n\t\t\t\t</button>\n\t\t\t</header>\n\t\t\t{getOpen() ? (\n\t\t\t\t<section>\n\t\t\t\t\t{getTimeline().history.map((event, index) => (\n\t\t\t\t\t\t<section key={index}>\n\t\t\t\t\t\t\t{index === getTimeline().at ? (\n\t\t\t\t\t\t\t\t<p class=\"you-are-here\">you are here</p>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<EventView tools={props.tools} event={event} index={index} />\n\t\t\t\t\t\t</section>\n\t\t\t\t\t))}\n\t\t\t\t\t{getTimeline().at === getTimeline().history.length ? (\n\t\t\t\t\t\t<p class=\"you-are-here\">you are here</p>\n\t\t\t\t\t) : null}\n\t\t\t\t</section>\n\t\t\t) : null}\n\t\t</section>\n\t)\n}\n","import type { SpaElement } from \"@atom.io/spa\"\nimport { onCleanup, onMount, render, useGetter } from \"@atom.io/spa\"\nimport type { RootStore } from \"atom.io/internal\"\nimport { IMPLICIT } from \"atom.io/internal\"\n\nimport { StateIndex, TimelineIndex, TransactionIndex } from \"./Indexes.tsx\"\nimport { useLocal, useSaved, useTools } from \"./store.ts\"\n\nexport interface AtomIODevtoolsProps {\n\t/** Inspected store. Fixed for this component instance; change its key to replace it. */\n\tstore?: RootStore\n\thideByDefault?: boolean\n}\n/** Owns a rendering root in the inspected store, independently of its parent island. */\nexport function AtomIODevtools(props: AtomIODevtoolsProps): SpaElement {\n\tlet host: HTMLElement | null = null\n\tconst attach = (element: HTMLElement | null) => {\n\t\thost = element\n\t}\n\tonMount(() => {\n\t\tconst store = props.store ?? IMPLICIT.STORE\n\t\tconst root = render(\n\t\t\t() => <Panel store={store} hideByDefault={props.hideByDefault ?? false} />,\n\t\t\thost!,\n\t\t\t{ store },\n\t\t)\n\t\tonCleanup(root.dispose)\n\t})\n\treturn <spa-devtools ref={attach} />\n}\nconst VIEWS = [`atoms`, `selectors`, `transactions`, `timelines`] as const\ntype View = (typeof VIEWS)[number]\nfunction Panel(props: { store: RootStore; hideByDefault: boolean }): SpaElement {\n\tconst tools = useTools(props.store)\n\tconst [getHidden, setHidden] = useSaved(\n\t\tprops.store,\n\t\t`🔍 Devtools Are Hidden`,\n\t\tprops.hideByDefault,\n\t)\n\tconst [getOpen, setOpen] = useSaved(props.store, `🔍 Devtools Are Open`, true)\n\tconst [getSelection, setSelection] = useSaved<string>(\n\t\tprops.store,\n\t\t`🔍 Devtools View`,\n\t\t`atoms`,\n\t)\n\tconst view = () =>\n\t\tVIEWS.includes(getSelection() as View) ? (getSelection() as View) : `atoms`\n\tconst [getPosition, setPosition] = useLocal(props.store, { x: 0, y: 0 })\n\tconst getError = useGetter(tools.error)\n\tlet panel: HTMLElement | null = null\n\tconst attach = (element: HTMLElement | null) => {\n\t\tpanel = element\n\t}\n\tlet drag:\n\t\t| { id: number; startX: number; startY: number; x: number; y: number }\n\t\t| undefined\n\tonMount(() => {\n\t\tconst shortcut = (event: KeyboardEvent) => {\n\t\t\tif (event.ctrlKey && event.shiftKey && event.code === `KeyA`) {\n\t\t\t\tevent.preventDefault()\n\t\t\t\tsetHidden((value) => !value)\n\t\t\t}\n\t\t}\n\t\tconst reset = () => {\n\t\t\tsetPosition({ x: 0, y: 0 })\n\t\t}\n\t\tdocument.addEventListener(`keydown`, shortcut)\n\t\twindow.addEventListener(`resize`, reset)\n\t\tonCleanup(() => {\n\t\t\tdocument.removeEventListener(`keydown`, shortcut)\n\t\t\twindow.removeEventListener(`resize`, reset)\n\t\t})\n\t})\n\treturn (\n\t\t<main\n\t\t\tref={attach}\n\t\t\tdata-css=\"spa-devtools\"\n\t\t\tdata-testid=\"atom-io-devtools\"\n\t\t\thidden={getHidden()}\n\t\t\tdata-open={getOpen()}\n\t\t\tstyle={`transform:translate(${getPosition().x}px,${getPosition().y}px)`}\n\t\t>\n\t\t\t<header class=\"toolbar\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"drag-handle\"\n\t\t\t\t\taria-label=\"Move debugger\"\n\t\t\t\t\ttitle=\"Drag to move; arrow keys to nudge\"\n\t\t\t\t\tonPointerdown={(event) => {\n\t\t\t\t\t\tif (event.button !== 0) return\n\t\t\t\t\t\tdrag = {\n\t\t\t\t\t\t\tid: event.pointerId,\n\t\t\t\t\t\t\tstartX: event.clientX,\n\t\t\t\t\t\t\tstartY: event.clientY,\n\t\t\t\t\t\t\t...getPosition(),\n\t\t\t\t\t\t}\n\t\t\t\t\t\t;(event.currentTarget as HTMLElement).setPointerCapture(\n\t\t\t\t\t\t\tevent.pointerId,\n\t\t\t\t\t\t)\n\t\t\t\t\t}}\n\t\t\t\t\tonPointermove={(event) => {\n\t\t\t\t\t\tif (!drag || drag.id !== event.pointerId || !panel) return\n\t\t\t\t\t\tconst rect = panel.getBoundingClientRect()\n\t\t\t\t\t\tconst next = {\n\t\t\t\t\t\t\tx: drag.x + event.clientX - drag.startX,\n\t\t\t\t\t\t\ty: drag.y + event.clientY - drag.startY,\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnext.x = Math.max(\n\t\t\t\t\t\t\tgetPosition().x - rect.left,\n\t\t\t\t\t\t\tMath.min(next.x, getPosition().x + window.innerWidth - rect.right),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tnext.y = Math.max(\n\t\t\t\t\t\t\tgetPosition().y - rect.top,\n\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\tnext.y,\n\t\t\t\t\t\t\t\tgetPosition().y + window.innerHeight - rect.bottom,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\tsetPosition(next)\n\t\t\t\t\t}}\n\t\t\t\t\tonPointerup={() => {\n\t\t\t\t\t\tdrag = undefined\n\t\t\t\t\t}}\n\t\t\t\t\tonPointercancel={() => {\n\t\t\t\t\t\tdrag = undefined\n\t\t\t\t\t}}\n\t\t\t\t\tonKeydown={(event) => {\n\t\t\t\t\t\tconst step = {\n\t\t\t\t\t\t\tArrowLeft: [-10, 0],\n\t\t\t\t\t\t\tArrowRight: [10, 0],\n\t\t\t\t\t\t\tArrowUp: [0, -10],\n\t\t\t\t\t\t\tArrowDown: [0, 10],\n\t\t\t\t\t\t}[event.key]\n\t\t\t\t\t\tif (step) {\n\t\t\t\t\t\t\tevent.preventDefault()\n\t\t\t\t\t\t\tsetPosition(({ x, y }) => ({ x: x + step[0], y: y + step[1] }))\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t⠿\n\t\t\t\t</button>\n\t\t\t\t<h1>atom.io</h1>\n\t\t\t\t{getOpen() ? (\n\t\t\t\t\t<nav aria-label=\"Debugger views\">\n\t\t\t\t\t\t{VIEWS.map((name) => (\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\taria-pressed={view() === name}\n\t\t\t\t\t\t\t\tdata-testid={`view-${name}`}\n\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\tsetSelection(name)\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{name}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</nav>\n\t\t\t\t) : null}\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label={getOpen() ? `Minimize debugger` : `Open debugger`}\n\t\t\t\t\tdata-testid=\"open-close-devtools\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetOpen((value) => !value)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{getOpen() ? `−` : `🔍`}\n\t\t\t\t</button>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\taria-label=\"Hide debugger (Ctrl+Shift+A)\"\n\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\tsetHidden(true)\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t×\n\t\t\t\t</button>\n\t\t\t</header>\n\t\t\t{getOpen() ? (\n\t\t\t\t<>\n\t\t\t\t\t{getError() ? <p role=\"alert\">{getError()}</p> : null}\n\t\t\t\t\t{view() === `atoms` || view() === `selectors` ? (\n\t\t\t\t\t\t<StateIndex\n\t\t\t\t\t\t\tkey={view()}\n\t\t\t\t\t\t\ttools={tools}\n\t\t\t\t\t\t\ttype={view() as `atoms` | `selectors`}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : view() === `transactions` ? (\n\t\t\t\t\t\t<TransactionIndex tools={tools} />\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<TimelineIndex tools={tools} />\n\t\t\t\t\t)}\n\t\t\t\t</>\n\t\t\t) : null}\n\t\t</main>\n\t)\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atom.io/spa-devtools",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Atom.io's debugger, rendered with spa.",
5
5
  "homepage": "https://github.com/jeremybanka/atom.io/tree/main/packages/spa-devtools#readme",
6
6
  "repository": {
@@ -32,20 +32,20 @@
32
32
  "src"
33
33
  ],
34
34
  "devDependencies": {
35
- "@atom.io/spa": "0.0.4",
35
+ "@atom.io/spa": "0.0.6",
36
36
  "@breakage/changesets": "0.1.0",
37
37
  "@types/node": "26.6.6",
38
38
  "@vitest/coverage-v8": "5.1.0",
39
- "atom.io": "0.54.5",
39
+ "atom.io": "0.54.7",
40
40
  "breakage": "0.10.2",
41
41
  "eslint": "10.14.0",
42
42
  "happy-dom": "21.0.4",
43
- "tsdown": "0.23.5",
43
+ "tsdown": "0.23.7",
44
44
  "typescript": "7.0.2",
45
45
  "vitest": "5.1.0"
46
46
  },
47
47
  "peerDependencies": {
48
- "@atom.io/spa": ">=0.0.4 <0.2.0",
48
+ "@atom.io/spa": ">=0.0.5 <0.1.0",
49
49
  "atom.io": "^0.54.1"
50
50
  },
51
51
  "publishConfig": {
@@ -1,4 +1,4 @@
1
- import type { VNode } from "@atom.io/spa"
1
+ import type { SpaElement } from "@atom.io/spa"
2
2
  import { onCleanup, onMount, render, useGetter } from "@atom.io/spa"
3
3
  import type { RootStore } from "atom.io/internal"
4
4
  import { IMPLICIT } from "atom.io/internal"
@@ -12,7 +12,7 @@ export interface AtomIODevtoolsProps {
12
12
  hideByDefault?: boolean
13
13
  }
14
14
  /** Owns a rendering root in the inspected store, independently of its parent island. */
15
- export function AtomIODevtools(props: AtomIODevtoolsProps): VNode {
15
+ export function AtomIODevtools(props: AtomIODevtoolsProps): SpaElement {
16
16
  let host: HTMLElement | null = null
17
17
  const attach = (element: HTMLElement | null) => {
18
18
  host = element
@@ -30,7 +30,7 @@ export function AtomIODevtools(props: AtomIODevtoolsProps): VNode {
30
30
  }
31
31
  const VIEWS = [`atoms`, `selectors`, `transactions`, `timelines`] as const
32
32
  type View = (typeof VIEWS)[number]
33
- function Panel(props: { store: RootStore; hideByDefault: boolean }): VNode {
33
+ function Panel(props: { store: RootStore; hideByDefault: boolean }): SpaElement {
34
34
  const tools = useTools(props.store)
35
35
  const [getHidden, setHidden] = useSaved(
36
36
  props.store,
package/src/Indexes.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import type { VNode } from "@atom.io/spa"
1
+ import type { SpaElement } from "@atom.io/spa"
2
2
  import { useGetter, useSetter, useTimeline } from "@atom.io/spa"
3
3
  import type {
4
4
  ReadableToken,
@@ -22,7 +22,7 @@ type Token = ReadableToken<unknown, any, any>
22
22
  export function StateIndex(props: {
23
23
  tools: Tools
24
24
  type: `atoms` | `selectors`
25
- }): VNode {
25
+ }): SpaElement {
26
26
  const getStateIndex = useGetter<Map<string, Token | FamilyNode<Token>>>(
27
27
  props.type === `atoms` ? props.tools.atomIndex : props.tools.selectorIndex,
28
28
  )
@@ -41,7 +41,7 @@ export function StateIndex(props: {
41
41
  function StateNode(props: {
42
42
  tools: Tools
43
43
  node: Token | FamilyNode<Token>
44
- }): VNode {
44
+ }): SpaElement {
45
45
  const [getOpen, toggle] = useExpanded(props.tools, [props.node.key])
46
46
  return (
47
47
  <section class="node" data-testid={`state-${props.node.key}`}>
@@ -71,7 +71,7 @@ function StateNode(props: {
71
71
  </section>
72
72
  )
73
73
  }
74
- function StateLeaf(props: { tools: Tools; token: Token }): VNode {
74
+ function StateLeaf(props: { tools: Tools; token: Token }): SpaElement {
75
75
  const getValue = useGetter(props.token)
76
76
  const writable = !props.token.type.startsWith(`readonly`)
77
77
  const setValue = writable
@@ -123,7 +123,7 @@ function StateLeaf(props: { tools: Tools; token: Token }): VNode {
123
123
  </section>
124
124
  )
125
125
  }
126
- export function TransactionIndex(props: { tools: Tools }): VNode {
126
+ export function TransactionIndex(props: { tools: Tools }): SpaElement {
127
127
  const getTransactionIndex = useGetter(props.tools.transactionIndex)
128
128
  const visible = () =>
129
129
  getTransactionIndex().filter(
@@ -144,7 +144,7 @@ export function TransactionIndex(props: { tools: Tools }): VNode {
144
144
  function TransactionLog(props: {
145
145
  tools: Tools
146
146
  token: TransactionToken<any>
147
- }): VNode {
147
+ }): SpaElement {
148
148
  const getTransactionLog = useGetter(
149
149
  findInStore(
150
150
  props.tools.store,
@@ -181,11 +181,12 @@ function TransactionLog(props: {
181
181
  )
182
182
  }
183
183
  // Events are recursive discriminated records, including user-defined transaction outputs.
184
+ /** @internal Used by contributor tools or implementation tests. */
184
185
  export function EventView(props: {
185
186
  tools: Tools
186
187
  event: any
187
188
  index: number
188
- }): VNode {
189
+ }): SpaElement {
189
190
  const [getOpen, toggle] = useExpanded(
190
191
  props.tools,
191
192
  [`event`, props.event.token?.key ?? ``, String(props.index)],
@@ -235,7 +236,7 @@ export function EventView(props: {
235
236
  </section>
236
237
  )
237
238
  }
238
- export function TimelineIndex(props: { tools: Tools }): VNode {
239
+ export function TimelineIndex(props: { tools: Tools }): SpaElement {
239
240
  const getTimelineIndex = useGetter(props.tools.timelineIndex)
240
241
  const groups = () => {
241
242
  const result = new Map<string, TimelineToken<any>[]>()
@@ -269,7 +270,10 @@ export function TimelineIndex(props: { tools: Tools }): VNode {
269
270
  </article>
270
271
  )
271
272
  }
272
- function TimelineLog(props: { tools: Tools; token: TimelineToken<any> }): VNode {
273
+ function TimelineLog(props: {
274
+ tools: Tools
275
+ token: TimelineToken<any>
276
+ }): SpaElement {
273
277
  const controls = useTimeline(props.token)
274
278
  const getTimeline = useGetter(
275
279
  findInStore(
@@ -1,4 +1,4 @@
1
- import type { Child, VNode } from "@atom.io/spa"
1
+ import type { Children, SpaElement } from "@atom.io/spa"
2
2
 
3
3
  import type { Path, Tools } from "./store.ts"
4
4
  import { useExpanded } from "./store.ts"
@@ -11,8 +11,8 @@ interface EditorProps {
11
11
  change?: Change | undefined
12
12
  path: Path
13
13
  ancestors?: readonly unknown[]
14
- label?: Child
15
- actions?: Child
14
+ label?: Children
15
+ actions?: Children
16
16
  }
17
17
  const TYPES: JsonKind[] = [
18
18
  `string`,
@@ -22,7 +22,7 @@ const TYPES: JsonKind[] = [
22
22
  `array`,
23
23
  `object`,
24
24
  ]
25
- export function JsonEditor(props: EditorProps): VNode {
25
+ export function JsonEditor(props: EditorProps): SpaElement {
26
26
  const [getExpanded, toggle] = useExpanded(props.tools, props.path)
27
27
  const circular = () =>
28
28
  (props.ancestors?.includes(props.value) ?? false) || props.path.length > 50
@@ -137,7 +137,7 @@ function Primitive(props: {
137
137
  change?: Change | undefined
138
138
  tools: Tools
139
139
  label: string
140
- }): VNode {
140
+ }): SpaElement {
141
141
  const set = (value: unknown) => {
142
142
  props.tools.attempt(() => {
143
143
  props.change?.(() => value)
@@ -178,7 +178,7 @@ function Primitive(props: {
178
178
  </span>
179
179
  )
180
180
  }
181
- function Property(props: { name: string; editor: EditorProps }): VNode {
181
+ function Property(props: { name: string; editor: EditorProps }): SpaElement {
182
182
  const parent = props.editor
183
183
  const read = () => (parent.value as Record<string, unknown>)[props.name]
184
184
  const change: Change = (update) => {
package/src/store.ts CHANGED
@@ -21,7 +21,7 @@ export interface Tools extends IntrospectionStates {
21
21
  attempt(run: () => void): void
22
22
  }
23
23
 
24
- export function ownedAtom<T>(store: RootStore, initial: T): RegularAtomToken<T> {
24
+ function ownedAtom<T>(store: RootStore, initial: T): RegularAtomToken<T> {
25
25
  let family = locals.get(store)
26
26
  if (!family) {
27
27
  family = createRegularAtomFamily<unknown, string, never>(store, {