@atom.io/spa-devtools 0.0.0-stage → 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +51 -2
- package/README.mdx +35 -0
- package/dist/css.d.ts +2 -0
- package/dist/devtools.css +289 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +904 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -5
- package/src/AtomIODevtools.tsx +194 -0
- package/src/Indexes.tsx +331 -0
- package/src/JsonEditor.tsx +259 -0
- package/src/css.d.ts +2 -0
- package/src/devtools.css +289 -0
- package/src/index.ts +2 -0
- package/src/store.ts +148 -0
- package/src/value.ts +79 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["Child","VNode","Path","Tools","useExpanded","Change","JsonKind","convert","describe","kind","EditorProps","tools","value","change","path","ancestors","label","actions","TYPES","JsonEditor","props","expanded","toggle","circular","includes","length","container","entries","Object","Record","_spa","data-testid","join","children","aria-label","at","aria-expanded","onClick","event","type","currentTarget","attempt","previous","map","title","Primitive","key","Property","name","editor","Array","isArray","object","hasOwn","sort","a","b","localeCompare","set","checked","Boolean","disabled","inputmode","String","readOnly","text","trim","Number","isFinite","parent","read","update","index","style","Math","max","input","Error","fromEntries","filter","_","undefined","spa","_spa","VNode","useSetter","useTimeline","useValue","ReadableToken","TimelineToken","TransactionToken","WritableToken","disposeFromStore","findInStore","isReservedIntrospectionKey","FamilyNode","JsonEditor","Tools","useExpanded","describe","Token","StateIndex","props","tools","type","index","Map","atomIndex","selectorIndex","_spa","children","size","values","map","node","StateNode","key","open","toggle","data-testid","aria-expanded","onClick","familyMembers","token","StateLeaf","read","writable","startsWith","set","undefined","value","error","label","family","subKey","actions","aria-label","attempt","store","change","update","next","path","TransactionIndex","transactionIndex","visible","filter","length","TransactionLog","log","transactionLogSelectors","event","EventView","String","params","output","subEvents","oldValue","newValue","TimelineIndex","timelineIndex","groups","result","members","get","push","TimelineLog","controls","timelineSelectors","at","disabled","undo","redo","history","spa","_spa","VNode","onCleanup","onMount","render","useValue","RootStore","IMPLICIT","StateIndex","TimelineIndex","TransactionIndex","useLocal","useSaved","useTools","AtomIODevtoolsProps","store","hideByDefault","AtomIODevtools","props","host","HTMLElement","attach","element","STORE","root","_spa","Panel","dispose","ref","VIEWS","const","View","tools","hidden","setHidden","open","setOpen","selection","setSelection","view","includes","position","setPosition","x","y","error","panel","drag","id","startX","startY","shortcut","event","KeyboardEvent","ctrlKey","shiftKey","code","preventDefault","value","reset","document","addEventListener","window","removeEventListener","data-open","style","children","button","pointerId","clientX","clientY","currentTarget","setPointerCapture","rect","getBoundingClientRect","next","Math","max","left","min","innerWidth","right","top","innerHeight","bottom","onPointerup","undefined","onPointercancel","step","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","key","map","name","aria-pressed","data-testid","onClick","aria-label","type","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, useId, useSetter, useValue } 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 [useValue(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 [value, set] = useLocal(store, initial)\n\treturn [\n\t\tvalue,\n\t\t(next) => {\n\t\t\tset(next)\n\t\t\ttry {\n\t\t\t\tlocalStorage.setItem(key, JSON.stringify(value()))\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 value = useValue(tools.expanded)\n\tconst set = useSetter(tools.expanded)\n\tconst key = JSON.stringify(path)\n\tconst group = `all:${JSON.stringify(path.slice(0, -1))}`\n\tconst read = () => value()[key] ?? value()[group] ?? initial\n\treturn [\n\t\tread,\n\t\t(event) => {\n\t\t\tconst next = !read()\n\t\t\tset((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 [expanded, 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={expanded()}\n\t\t\t\t\t\tonClick={toggle}\n\t\t\t\t\t>\n\t\t\t\t\t\t{expanded() ? `▾` : `▸`}\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() && expanded() ? (\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 { useSetter, useTimeline, useValue } 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 index = useValue<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{index().size === 0 ? (\n\t\t\t\t<p>(no {props.type})</p>\n\t\t\t) : (\n\t\t\t\t[...index().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 [open, 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={open()}\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{open() ? `▾` : `▸`}\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{open()\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 read = useValue(props.token)\n\tconst writable = !props.token.type.startsWith(`readonly`)\n\tconst set = 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 read()\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\tset\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(read())\n\t\t\t\t\t\t\t\tset(() => 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 index = useValue(props.tools.transactionIndex)\n\tconst visible = () =>\n\t\tindex().filter((token) => !isReservedIntrospectionKey(token.key))\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 log = useValue(\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 [open, 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={open()}\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{open() ? `▾` : `▸`}\n\t\t\t\t</button>\n\t\t\t\t<h2>{props.token.key}</h2>\n\t\t\t\t<small>({log().length})</small>\n\t\t\t</header>\n\t\t\t{open()\n\t\t\t\t? log().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 [open, 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={open()} onClick={toggle}>\n\t\t\t\t\t{open() ? `▾` : `▸`}\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{open() ? (\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 index = useValue(props.tools.timelineIndex)\n\tconst groups = () => {\n\t\tconst result = new Map<string, TimelineToken<any>[]>()\n\t\tfor (const token of index()) {\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 log = useValue(\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 [open, 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={open()}\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{open() ? `▾` : `▸`}\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().at}/{controls().length})\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().at === 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().at === controls().length}\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{open() ? (\n\t\t\t\t<section>\n\t\t\t\t\t{log().history.map((event, index) => (\n\t\t\t\t\t\t<section key={index}>\n\t\t\t\t\t\t\t{index === log().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{log().at === log().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, useValue } 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 [hidden, setHidden] = useSaved(\n\t\tprops.store,\n\t\t`🔍 Devtools Are Hidden`,\n\t\tprops.hideByDefault,\n\t)\n\tconst [open, setOpen] = useSaved(props.store, `🔍 Devtools Are Open`, true)\n\tconst [selection, 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(selection() as View) ? (selection() as View) : `atoms`\n\tconst [position, setPosition] = useLocal(props.store, { x: 0, y: 0 })\n\tconst error = useValue(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={hidden()}\n\t\t\tdata-open={open()}\n\t\t\tstyle={`transform:translate(${position().x}px,${position().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...position(),\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\tposition().x - rect.left,\n\t\t\t\t\t\t\tMath.min(next.x, position().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\tposition().y - rect.top,\n\t\t\t\t\t\t\tMath.min(next.y, position().y + window.innerHeight - rect.bottom),\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{open() ? (\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={open() ? `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{open() ? `−` : `🔍`}\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{open() ? (\n\t\t\t\t<>\n\t\t\t\t\t{error() ? <p role=\"alert\">{error()}</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,70 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@atom.io/spa-devtools",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Atom.io's debugger, rendered with spa.",
|
|
5
|
+
"homepage": "https://github.com/jeremybanka/atom.io/tree/main/packages/spa-devtools#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/jeremybanka/atom.io.git",
|
|
9
|
+
"directory": "packages/spa-devtools"
|
|
10
|
+
},
|
|
11
|
+
"license": "MPL-2.0",
|
|
12
|
+
"author": "Jeremy Banka",
|
|
13
|
+
"sideEffects": [
|
|
14
|
+
"**/*.css"
|
|
15
|
+
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./css": {
|
|
23
|
+
"types": "./dist/css.d.ts",
|
|
24
|
+
"default": "./dist/devtools.css"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"src"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsdown",
|
|
36
|
+
"lint:eslint": "eslint",
|
|
37
|
+
"lint:oxlint": "oxlint",
|
|
38
|
+
"lint:types": "tsc",
|
|
39
|
+
"pack:breakage": "pnpm --reporter=silent pack --out .breakage/package.tgz",
|
|
40
|
+
"test:breakage:peers": "breakage npm check",
|
|
41
|
+
"test": "vitest",
|
|
42
|
+
"test:once": "vitest run --config vitest.config.ts && pnpm test:consumer",
|
|
43
|
+
"test:consumer": "node __tests__/fixtures/consumer/check.ts",
|
|
44
|
+
"cov": "vitest run --config vitest.config.ts --coverage",
|
|
45
|
+
"readme:write": "galley write README.mdx",
|
|
46
|
+
"readme:check": "galley check README.mdx",
|
|
47
|
+
"tonnage": "pnpm readme:write",
|
|
48
|
+
"tonnage:check": "pnpm readme:check"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@atom.io/spa": "workspace:*",
|
|
52
|
+
"@breakage/changesets": "0.1.0",
|
|
53
|
+
"@types/node": "26.6.5",
|
|
54
|
+
"@vitest/coverage-v8": "5.0.5",
|
|
55
|
+
"atom.io": "workspace:*",
|
|
56
|
+
"breakage": "0.10.1",
|
|
57
|
+
"eslint": "10.13.0",
|
|
58
|
+
"happy-dom": "21.0.4",
|
|
59
|
+
"tsdown": "0.23.3",
|
|
60
|
+
"typescript": "7.0.2",
|
|
61
|
+
"vitest": "5.0.5"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@atom.io/spa": ">=0.0.0 <0.2.0",
|
|
65
|
+
"atom.io": "^0.54.1"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import type { VNode } from "@atom.io/spa"
|
|
2
|
+
import { onCleanup, onMount, render, useValue } from "@atom.io/spa"
|
|
3
|
+
import type { RootStore } from "atom.io/internal"
|
|
4
|
+
import { IMPLICIT } from "atom.io/internal"
|
|
5
|
+
|
|
6
|
+
import { StateIndex, TimelineIndex, TransactionIndex } from "./Indexes.tsx"
|
|
7
|
+
import { useLocal, useSaved, useTools } from "./store.ts"
|
|
8
|
+
|
|
9
|
+
export interface AtomIODevtoolsProps {
|
|
10
|
+
/** Inspected store. Fixed for this component instance; change its key to replace it. */
|
|
11
|
+
store?: RootStore
|
|
12
|
+
hideByDefault?: boolean
|
|
13
|
+
}
|
|
14
|
+
/** Owns a rendering root in the inspected store, independently of its parent island. */
|
|
15
|
+
export function AtomIODevtools(props: AtomIODevtoolsProps): VNode {
|
|
16
|
+
let host: HTMLElement | null = null
|
|
17
|
+
const attach = (element: HTMLElement | null) => {
|
|
18
|
+
host = element
|
|
19
|
+
}
|
|
20
|
+
onMount(() => {
|
|
21
|
+
const store = props.store ?? IMPLICIT.STORE
|
|
22
|
+
const root = render(
|
|
23
|
+
() => <Panel store={store} hideByDefault={props.hideByDefault ?? false} />,
|
|
24
|
+
host!,
|
|
25
|
+
{ store },
|
|
26
|
+
)
|
|
27
|
+
onCleanup(root.dispose)
|
|
28
|
+
})
|
|
29
|
+
return <spa-devtools ref={attach} />
|
|
30
|
+
}
|
|
31
|
+
const VIEWS = [`atoms`, `selectors`, `transactions`, `timelines`] as const
|
|
32
|
+
type View = (typeof VIEWS)[number]
|
|
33
|
+
function Panel(props: { store: RootStore; hideByDefault: boolean }): VNode {
|
|
34
|
+
const tools = useTools(props.store)
|
|
35
|
+
const [hidden, setHidden] = useSaved(
|
|
36
|
+
props.store,
|
|
37
|
+
`🔍 Devtools Are Hidden`,
|
|
38
|
+
props.hideByDefault,
|
|
39
|
+
)
|
|
40
|
+
const [open, setOpen] = useSaved(props.store, `🔍 Devtools Are Open`, true)
|
|
41
|
+
const [selection, setSelection] = useSaved<string>(
|
|
42
|
+
props.store,
|
|
43
|
+
`🔍 Devtools View`,
|
|
44
|
+
`atoms`,
|
|
45
|
+
)
|
|
46
|
+
const view = () =>
|
|
47
|
+
VIEWS.includes(selection() as View) ? (selection() as View) : `atoms`
|
|
48
|
+
const [position, setPosition] = useLocal(props.store, { x: 0, y: 0 })
|
|
49
|
+
const error = useValue(tools.error)
|
|
50
|
+
let panel: HTMLElement | null = null
|
|
51
|
+
const attach = (element: HTMLElement | null) => {
|
|
52
|
+
panel = element
|
|
53
|
+
}
|
|
54
|
+
let drag:
|
|
55
|
+
| { id: number; startX: number; startY: number; x: number; y: number }
|
|
56
|
+
| undefined
|
|
57
|
+
onMount(() => {
|
|
58
|
+
const shortcut = (event: KeyboardEvent) => {
|
|
59
|
+
if (event.ctrlKey && event.shiftKey && event.code === `KeyA`) {
|
|
60
|
+
event.preventDefault()
|
|
61
|
+
setHidden((value) => !value)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const reset = () => {
|
|
65
|
+
setPosition({ x: 0, y: 0 })
|
|
66
|
+
}
|
|
67
|
+
document.addEventListener(`keydown`, shortcut)
|
|
68
|
+
window.addEventListener(`resize`, reset)
|
|
69
|
+
onCleanup(() => {
|
|
70
|
+
document.removeEventListener(`keydown`, shortcut)
|
|
71
|
+
window.removeEventListener(`resize`, reset)
|
|
72
|
+
})
|
|
73
|
+
})
|
|
74
|
+
return (
|
|
75
|
+
<main
|
|
76
|
+
ref={attach}
|
|
77
|
+
data-css="spa-devtools"
|
|
78
|
+
data-testid="atom-io-devtools"
|
|
79
|
+
hidden={hidden()}
|
|
80
|
+
data-open={open()}
|
|
81
|
+
style={`transform:translate(${position().x}px,${position().y}px)`}
|
|
82
|
+
>
|
|
83
|
+
<header class="toolbar">
|
|
84
|
+
<button
|
|
85
|
+
type="button"
|
|
86
|
+
class="drag-handle"
|
|
87
|
+
aria-label="Move debugger"
|
|
88
|
+
title="Drag to move; arrow keys to nudge"
|
|
89
|
+
onPointerdown={(event) => {
|
|
90
|
+
if (event.button !== 0) return
|
|
91
|
+
drag = {
|
|
92
|
+
id: event.pointerId,
|
|
93
|
+
startX: event.clientX,
|
|
94
|
+
startY: event.clientY,
|
|
95
|
+
...position(),
|
|
96
|
+
}
|
|
97
|
+
;(event.currentTarget as HTMLElement).setPointerCapture(
|
|
98
|
+
event.pointerId,
|
|
99
|
+
)
|
|
100
|
+
}}
|
|
101
|
+
onPointermove={(event) => {
|
|
102
|
+
if (!drag || drag.id !== event.pointerId || !panel) return
|
|
103
|
+
const rect = panel.getBoundingClientRect()
|
|
104
|
+
const next = {
|
|
105
|
+
x: drag.x + event.clientX - drag.startX,
|
|
106
|
+
y: drag.y + event.clientY - drag.startY,
|
|
107
|
+
}
|
|
108
|
+
next.x = Math.max(
|
|
109
|
+
position().x - rect.left,
|
|
110
|
+
Math.min(next.x, position().x + window.innerWidth - rect.right),
|
|
111
|
+
)
|
|
112
|
+
next.y = Math.max(
|
|
113
|
+
position().y - rect.top,
|
|
114
|
+
Math.min(next.y, position().y + window.innerHeight - rect.bottom),
|
|
115
|
+
)
|
|
116
|
+
setPosition(next)
|
|
117
|
+
}}
|
|
118
|
+
onPointerup={() => {
|
|
119
|
+
drag = undefined
|
|
120
|
+
}}
|
|
121
|
+
onPointercancel={() => {
|
|
122
|
+
drag = undefined
|
|
123
|
+
}}
|
|
124
|
+
onKeydown={(event) => {
|
|
125
|
+
const step = {
|
|
126
|
+
ArrowLeft: [-10, 0],
|
|
127
|
+
ArrowRight: [10, 0],
|
|
128
|
+
ArrowUp: [0, -10],
|
|
129
|
+
ArrowDown: [0, 10],
|
|
130
|
+
}[event.key]
|
|
131
|
+
if (step) {
|
|
132
|
+
event.preventDefault()
|
|
133
|
+
setPosition(({ x, y }) => ({ x: x + step[0], y: y + step[1] }))
|
|
134
|
+
}
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
⠿
|
|
138
|
+
</button>
|
|
139
|
+
<h1>atom.io</h1>
|
|
140
|
+
{open() ? (
|
|
141
|
+
<nav aria-label="Debugger views">
|
|
142
|
+
{VIEWS.map((name) => (
|
|
143
|
+
<button
|
|
144
|
+
type="button"
|
|
145
|
+
aria-pressed={view() === name}
|
|
146
|
+
data-testid={`view-${name}`}
|
|
147
|
+
onClick={() => {
|
|
148
|
+
setSelection(name)
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
{name}
|
|
152
|
+
</button>
|
|
153
|
+
))}
|
|
154
|
+
</nav>
|
|
155
|
+
) : null}
|
|
156
|
+
<button
|
|
157
|
+
type="button"
|
|
158
|
+
aria-label={open() ? `Minimize debugger` : `Open debugger`}
|
|
159
|
+
data-testid="open-close-devtools"
|
|
160
|
+
onClick={() => {
|
|
161
|
+
setOpen((value) => !value)
|
|
162
|
+
}}
|
|
163
|
+
>
|
|
164
|
+
{open() ? `−` : `🔍`}
|
|
165
|
+
</button>
|
|
166
|
+
<button
|
|
167
|
+
type="button"
|
|
168
|
+
aria-label="Hide debugger (Ctrl+Shift+A)"
|
|
169
|
+
onClick={() => {
|
|
170
|
+
setHidden(true)
|
|
171
|
+
}}
|
|
172
|
+
>
|
|
173
|
+
×
|
|
174
|
+
</button>
|
|
175
|
+
</header>
|
|
176
|
+
{open() ? (
|
|
177
|
+
<>
|
|
178
|
+
{error() ? <p role="alert">{error()}</p> : null}
|
|
179
|
+
{view() === `atoms` || view() === `selectors` ? (
|
|
180
|
+
<StateIndex
|
|
181
|
+
key={view()}
|
|
182
|
+
tools={tools}
|
|
183
|
+
type={view() as `atoms` | `selectors`}
|
|
184
|
+
/>
|
|
185
|
+
) : view() === `transactions` ? (
|
|
186
|
+
<TransactionIndex tools={tools} />
|
|
187
|
+
) : (
|
|
188
|
+
<TimelineIndex tools={tools} />
|
|
189
|
+
)}
|
|
190
|
+
</>
|
|
191
|
+
) : null}
|
|
192
|
+
</main>
|
|
193
|
+
)
|
|
194
|
+
}
|