@solid-devtools/debugger
Advanced tools
| // src/roots.ts | ||
| import { createEffect as createEffect2, onCleanup, untrack as untrack3 } from "solid-js"; | ||
| import { throttle as throttle3 } from "@solid-primitives/scheduled"; | ||
| import { | ||
| getOwner as getOwner2, | ||
| NodeType as NodeType3 | ||
| } from "@solid-devtools/shared/graph"; | ||
| import { INTERNAL as INTERNAL2 } from "@solid-devtools/shared/variables"; | ||
| // src/walker.ts | ||
| import { resolveElements } from "@solid-primitives/refs"; | ||
| import { NodeType as NodeType2 } from "@solid-devtools/shared/graph"; | ||
| // src/utils.ts | ||
| import { createComputed, createRoot, runWithOwner } from "solid-js"; | ||
| import { noop, warn } from "@solid-primitives/utils"; | ||
| import { | ||
| NodeType, | ||
| getOwner | ||
| } from "@solid-devtools/shared/graph"; | ||
| import { INTERNAL, UNNAMED } from "@solid-devtools/shared/variables"; | ||
| import { trimString } from "@solid-devtools/shared/utils"; | ||
| import { createSimpleEmitter } from "@solid-primitives/event-bus"; | ||
| import { throttle } from "@solid-primitives/scheduled"; | ||
| var isSolidComputation = (o) => "fn" in o; | ||
| var isSolidMemo = (o) => "sdtType" in o ? o.sdtType === NodeType.Memo : _isMemo(o) && !fnMatchesRefresh(o.fn); | ||
| var isSolidOwner = (o) => "owned" in o; | ||
| var isSolidRoot = (o) => o.sdtType === NodeType.Root || !isSolidComputation(o); | ||
| var isSolidComponent = (o) => "componentName" in o; | ||
| var _isMemo = (o) => "value" in o && "comparator" in o && o.pure === true; | ||
| var fnMatchesRefresh = (fn) => (fn + "").replace(/[\n\t]/g, "").replace(/ +/g, " ") === "() => { const c = source(); if (c) { return untrack(() => c(props)); } return undefined; }"; | ||
| function getOwnerName(owner) { | ||
| const { name, componentName: component } = owner; | ||
| if (component && typeof component === "string") | ||
| return component.startsWith("_Hot$$") ? component.slice(6) : component; | ||
| return name || UNNAMED; | ||
| } | ||
| function getSignalName(signal) { | ||
| return signal.name || UNNAMED; | ||
| } | ||
| function getNodeName(o) { | ||
| const name = isSolidOwner(o) ? getOwnerName(o) : getSignalName(o); | ||
| return trimString(name, 16); | ||
| } | ||
| function getNodeType(o) { | ||
| if (isSolidOwner(o)) | ||
| return getOwnerType(o); | ||
| return NodeType.Signal; | ||
| } | ||
| var getOwnerType = (o) => { | ||
| if (typeof o.sdtType !== "undefined") | ||
| return o.sdtType; | ||
| if (!isSolidComputation(o)) | ||
| return NodeType.Root; | ||
| if (isSolidComponent(o)) | ||
| return NodeType.Component; | ||
| if (_isMemo(o)) { | ||
| if (fnMatchesRefresh(o.fn)) | ||
| return NodeType.Refresh; | ||
| return NodeType.Memo; | ||
| } | ||
| if (o.pure === false) { | ||
| if (o.user === true) | ||
| return NodeType.Effect; | ||
| return NodeType.Render; | ||
| } | ||
| return NodeType.Computation; | ||
| }; | ||
| function lookupOwner(owner, predicate) { | ||
| do { | ||
| if (predicate(owner)) | ||
| return owner; | ||
| owner = owner.owner; | ||
| } while (owner.owner); | ||
| return null; | ||
| } | ||
| function setDebuggerContext(owner, ctx) { | ||
| owner.sdtContext = ctx; | ||
| } | ||
| function getDebuggerContext(owner) { | ||
| while (!owner.sdtContext && owner.owner) | ||
| owner = owner.owner; | ||
| return owner.sdtContext; | ||
| } | ||
| function removeDebuggerContext(owner) { | ||
| delete owner.sdtContext; | ||
| } | ||
| function onOwnerCleanup(owner, fn, prepend = false) { | ||
| if (owner.cleanups === null) | ||
| owner.cleanups = [fn]; | ||
| else if (prepend) | ||
| owner.cleanups.splice(0, 0, fn); | ||
| else | ||
| owner.cleanups.push(fn); | ||
| return () => { | ||
| var _a; | ||
| return (_a = owner.cleanups) == null ? void 0 : _a.splice(owner.cleanups.indexOf(fn), 1); | ||
| }; | ||
| } | ||
| function onParentCleanup(owner, fn, prepend = false) { | ||
| if (owner.owner) | ||
| return onOwnerCleanup(owner.owner, fn, prepend); | ||
| return noop; | ||
| } | ||
| var DISPOSE_ID = Symbol("Dispose ID"); | ||
| function createUnownedRoot(fn) { | ||
| return runWithOwner(null, () => createRoot(fn)); | ||
| } | ||
| function getFunctionSources(fn) { | ||
| let nodes; | ||
| let init = true; | ||
| runWithOwner( | ||
| null, | ||
| () => createRoot( | ||
| (dispose) => createComputed(() => { | ||
| if (!init) | ||
| return; | ||
| init = false; | ||
| fn(); | ||
| const sources = getOwner().sources; | ||
| if (sources) | ||
| nodes = [...sources]; | ||
| dispose(); | ||
| }) | ||
| ) | ||
| ); | ||
| return nodes ?? []; | ||
| } | ||
| var LAST_ID = 0; | ||
| var getNewSdtId = () => (LAST_ID++).toString(16); | ||
| function markOwnerName(o) { | ||
| if (o.sdtName !== void 0) | ||
| return o.sdtName; | ||
| return o.sdtName = getNodeName(o); | ||
| } | ||
| function markOwnerType(o, type) { | ||
| if (o.sdtType !== void 0) | ||
| return o.sdtType; | ||
| return o.sdtType = type ?? getOwnerType(o); | ||
| } | ||
| function markNodeID(o) { | ||
| if (o.sdtId !== void 0) | ||
| return o.sdtId; | ||
| return o.sdtId = getNewSdtId(); | ||
| } | ||
| function markNodesID(nodes) { | ||
| if (!nodes || !nodes.length) | ||
| return []; | ||
| return nodes.map(markNodeID); | ||
| } | ||
| var SkipInternalRoot = null; | ||
| var createInternalRoot = (fn, detachedOwner) => { | ||
| SkipInternalRoot = fn; | ||
| const v = createRoot((dispose) => { | ||
| const owner = getOwner(); | ||
| setDebuggerContext(owner, INTERNAL); | ||
| return fn(dispose); | ||
| }, detachedOwner); | ||
| if (SkipInternalRoot === fn) | ||
| SkipInternalRoot = null; | ||
| return v; | ||
| }; | ||
| var skipInternalRoot = () => { | ||
| const skip = !!SkipInternalRoot; | ||
| if (skip) | ||
| SkipInternalRoot = null; | ||
| return skip; | ||
| }; | ||
| function createBatchedUpdateEmitter() { | ||
| const [handleUpdates, emitUpdates] = createSimpleEmitter(); | ||
| const updates = []; | ||
| const triggerUpdateEmit = throttle(() => { | ||
| const ids = /* @__PURE__ */ new Set(); | ||
| const deduped = []; | ||
| for (let i = updates.length - 1; i >= 0; i--) { | ||
| const update = updates[i]; | ||
| if (ids.has(update.id)) | ||
| continue; | ||
| ids.add(update.id); | ||
| deduped.push(update); | ||
| } | ||
| updates.length = 0; | ||
| emitUpdates(deduped); | ||
| }); | ||
| const pushUpdate = (update) => { | ||
| updates.push(update); | ||
| triggerUpdateEmit(); | ||
| }; | ||
| return [handleUpdates, pushUpdate]; | ||
| } | ||
| // src/update.ts | ||
| import { untrack } from "solid-js"; | ||
| import { noop as noop2, onRootCleanup } from "@solid-primitives/utils"; | ||
| import { Observable } from "object-observer"; | ||
| import { WINDOW_WRAP_STORE_PROPERTY } from "@solid-devtools/shared/variables"; | ||
| var GraphUpdateListeners = /* @__PURE__ */ new Set(); | ||
| { | ||
| const runListeners = () => GraphUpdateListeners.forEach((f) => f()); | ||
| if (typeof window._$afterUpdate === "function") { | ||
| GraphUpdateListeners.add(window._$afterUpdate); | ||
| } | ||
| window._$afterUpdate = runListeners; | ||
| } | ||
| function makeSolidUpdateListener(onUpdate2) { | ||
| GraphUpdateListeners.add(onUpdate2); | ||
| return onRootCleanup(() => { | ||
| GraphUpdateListeners.delete(onUpdate2); | ||
| }); | ||
| } | ||
| var CreateRootListeners = /* @__PURE__ */ new Set(); | ||
| { | ||
| const runListeners = (root) => { | ||
| if (skipInternalRoot()) | ||
| return; | ||
| CreateRootListeners.forEach((f) => f(root)); | ||
| }; | ||
| if (typeof window._$afterCreateRoot === "function") { | ||
| CreateRootListeners.add(window._$afterCreateRoot); | ||
| } | ||
| window._$afterCreateRoot = runListeners; | ||
| } | ||
| function makeCreateRootListener(onUpdate2) { | ||
| CreateRootListeners.add(onUpdate2); | ||
| return onRootCleanup(() => CreateRootListeners.delete(onUpdate2)); | ||
| } | ||
| window[WINDOW_WRAP_STORE_PROPERTY] = (init) => { | ||
| return Observable.from(init); | ||
| }; | ||
| function makeStoreObserver(state, onUpdate2) { | ||
| if (!Observable.isObservable(state)) { | ||
| console.warn(`Object ${state} is not wrapped`); | ||
| return noop2; | ||
| } | ||
| Observable.observe(state, onUpdate2); | ||
| return onRootCleanup(() => Observable.unobserve(state, onUpdate2)); | ||
| } | ||
| function observeComputationUpdate(owner, onRun) { | ||
| if (owner.onComputationUpdate) | ||
| return void (owner.onComputationUpdate = onRun); | ||
| owner.onComputationUpdate = onRun; | ||
| interceptComputationRerun(owner, (fn) => { | ||
| untrack(owner.onComputationUpdate); | ||
| fn(); | ||
| }); | ||
| } | ||
| function interceptComputationRerun(owner, onRun) { | ||
| const _fn = owner.fn; | ||
| let v; | ||
| let prev; | ||
| const fn = () => v = _fn(prev); | ||
| owner.fn = !!owner.fn.length ? (p) => { | ||
| onRun(fn, prev = p); | ||
| return v; | ||
| } : () => { | ||
| onRun(fn, void 0); | ||
| return v; | ||
| }; | ||
| } | ||
| function observeValueUpdate(node, onUpdate2, symbol) { | ||
| if (node.onValueUpdate) { | ||
| node.onValueUpdate[symbol] = onUpdate2; | ||
| return; | ||
| } | ||
| const map = node.onValueUpdate = { [symbol]: onUpdate2 }; | ||
| let value = node.value; | ||
| Object.defineProperty(node, "value", { | ||
| get: () => value, | ||
| set: (newValue) => { | ||
| for (let sym of Object.getOwnPropertySymbols(map)) | ||
| map[sym](newValue, value); | ||
| value = newValue; | ||
| } | ||
| }); | ||
| } | ||
| function removeValueUpdateObserver(node, symbol) { | ||
| if (node.onValueUpdate) | ||
| delete node.onValueUpdate[symbol]; | ||
| } | ||
| function makeValueUpdateListener(node, onUpdate2, symbol) { | ||
| observeValueUpdate(node, onUpdate2, symbol); | ||
| onRootCleanup(() => removeValueUpdateObserver(node, symbol)); | ||
| } | ||
| // src/walker.ts | ||
| var InspectedId; | ||
| var RootId; | ||
| var OnComputationUpdate; | ||
| var GatherComponents; | ||
| var Components = []; | ||
| var InspectedOwner; | ||
| function observeComputation(owner, id) { | ||
| if (isSolidComputation(owner)) | ||
| observeComputationUpdate(owner, OnComputationUpdate.bind(void 0, RootId, id)); | ||
| } | ||
| function mapChildren({ owned, ownedRoots }) { | ||
| const children = []; | ||
| if (owned) | ||
| children.push.apply( | ||
| children, | ||
| owned.map((child) => mapOwner(child)) | ||
| ); | ||
| if (ownedRoots) | ||
| children.push.apply( | ||
| children, | ||
| [...ownedRoots].map((child) => mapOwner(child, NodeType2.Root)) | ||
| ); | ||
| return children; | ||
| } | ||
| function mapOwner(owner, type) { | ||
| type = markOwnerType(owner, type); | ||
| const id = markNodeID(owner); | ||
| const name = markOwnerName(owner); | ||
| if (id === InspectedId) | ||
| InspectedOwner = owner; | ||
| observeComputation(owner, id); | ||
| if (GatherComponents && type === NodeType2.Component) { | ||
| const element = resolveElements(owner.value); | ||
| if (element) | ||
| Components.push({ id, name, element }); | ||
| } | ||
| return { | ||
| id, | ||
| name, | ||
| type, | ||
| children: mapChildren(owner), | ||
| sources: owner.sources ? owner.sources.length : 0 | ||
| }; | ||
| } | ||
| function walkSolidTree(owner, config) { | ||
| InspectedId = config.inspectedId; | ||
| RootId = config.rootId; | ||
| OnComputationUpdate = config.onComputationUpdate; | ||
| GatherComponents = config.gatherComponents; | ||
| InspectedOwner = null; | ||
| Components = []; | ||
| const tree = mapOwner(owner); | ||
| return { tree, components: Components, inspectedOwner: InspectedOwner }; | ||
| } | ||
| // src/plugin.ts | ||
| import { batch, createEffect, createSignal, untrack as untrack2 } from "solid-js"; | ||
| import { createSimpleEmitter as createSimpleEmitter2 } from "@solid-primitives/event-bus"; | ||
| import { omit } from "@solid-primitives/immutable"; | ||
| import { createLazyMemo } from "@solid-primitives/memo"; | ||
| import { createStaticStore } from "@solid-primitives/utils"; | ||
| import { throttle as throttle2 } from "@solid-primitives/scheduled"; | ||
| import { encodeValue as encodeValue2, ElementMap as ElementMap2 } from "@solid-devtools/shared/serialize"; | ||
| import { createConsumers, untrackedCallback } from "@solid-devtools/shared/primitives"; | ||
| // src/inspect.ts | ||
| import { encodeValue, ValueType } from "@solid-devtools/shared/serialize"; | ||
| import { $PROXY } from "solid-js"; | ||
| var $elementMap; | ||
| var $signalMap; | ||
| var INSPECTOR = Symbol("inspector"); | ||
| function mapSignalNode(node, handler) { | ||
| const id = markNodeID(node); | ||
| $signalMap[id] = node; | ||
| observeValueUpdate(node, (value) => handler(id, value), INSPECTOR); | ||
| return { | ||
| type: getNodeType(node), | ||
| name: getNodeName(node), | ||
| id, | ||
| observers: markNodesID(node.observers), | ||
| value: encodeValue(node.value, false, $elementMap) | ||
| }; | ||
| } | ||
| function clearOwnerObservers(owner) { | ||
| if (owner.sourceMap) | ||
| Object.values(owner.sourceMap).forEach((node) => removeValueUpdateObserver(node, INSPECTOR)); | ||
| if (owner.owned) | ||
| owner.owned.forEach((node) => removeValueUpdateObserver(node, INSPECTOR)); | ||
| } | ||
| function encodeComponentProps(owner, config) { | ||
| if (!isSolidComponent(owner)) | ||
| return null; | ||
| const { elementMap, inspectedProps } = config; | ||
| const { props } = owner; | ||
| const proxy = !!props[$PROXY]; | ||
| const record = Object.entries(Object.getOwnPropertyDescriptors(props)).reduce( | ||
| (record2, [key, descriptor]) => { | ||
| record2[key] = "get" in descriptor ? { type: ValueType.Getter, value: key } : encodeValue(descriptor.value, inspectedProps.has(key), elementMap); | ||
| return record2; | ||
| }, | ||
| {} | ||
| ); | ||
| return { proxy, record }; | ||
| } | ||
| function collectOwnerDetails(owner, config) { | ||
| var _a; | ||
| const { elementMap, signalUpdateHandler, inspectedProps } = config; | ||
| const signalMap = {}; | ||
| $elementMap = elementMap; | ||
| $signalMap = signalMap; | ||
| const path = []; | ||
| let current = owner.owner; | ||
| while (current) { | ||
| path.unshift(markNodeID(current)); | ||
| current = current.owner; | ||
| } | ||
| const signals = owner.sourceMap ? Object.values(owner.sourceMap).map((s) => mapSignalNode(s, signalUpdateHandler)) : []; | ||
| (_a = owner.owned) == null ? void 0 : _a.forEach((child) => { | ||
| if (!isSolidMemo(child)) | ||
| return; | ||
| signals.push(mapSignalNode(child, signalUpdateHandler)); | ||
| }); | ||
| const details = { | ||
| id: markNodeID(owner), | ||
| name: markOwnerName(owner), | ||
| type: markOwnerType(owner), | ||
| path, | ||
| signals | ||
| }; | ||
| if (isSolidComputation(owner)) { | ||
| details.value = encodeValue(owner.value, false, elementMap); | ||
| details.sources = markNodesID(owner.sources); | ||
| if (isSolidMemo(owner)) { | ||
| details.observers = markNodesID(owner.observers); | ||
| } | ||
| const props = encodeComponentProps(owner, { inspectedProps, elementMap }); | ||
| if (props) | ||
| details.props = props; | ||
| } | ||
| return { | ||
| details, | ||
| signalMap | ||
| }; | ||
| } | ||
| // src/plugin.ts | ||
| var getNullInspected = () => ({ | ||
| id: null, | ||
| rootId: null, | ||
| owner: null, | ||
| details: null, | ||
| signalMap: {}, | ||
| elementMap: new ElementMap2() | ||
| }); | ||
| var exported = createInternalRoot(() => { | ||
| const [onUpdate2, triggerUpdate] = createSimpleEmitter2(); | ||
| const [onForceUpdate2, forceTriggerUpdate] = createSimpleEmitter2(); | ||
| const [enabled2, addDebuggerConsumer] = createConsumers(); | ||
| const [gatherComponents2, addGatherComponentsConsumer] = createConsumers(); | ||
| const [roots, setRoots] = createSignal({}); | ||
| const serialisedRoots = createLazyMemo(() => { | ||
| const serialisedRoots2 = {}; | ||
| for (const [id, root] of Object.entries(roots())) { | ||
| serialisedRoots2[id] = root.tree(); | ||
| } | ||
| return serialisedRoots2; | ||
| }); | ||
| const updatedIds = /* @__PURE__ */ new Set(); | ||
| const removedIds = /* @__PURE__ */ new Set(); | ||
| const rootsUpdates = createLazyMemo(() => { | ||
| const _updatedIds = [...updatedIds].filter((id) => !removedIds.has(id)); | ||
| const sRoots = serialisedRoots(); | ||
| const updated = _updatedIds.map((id) => ({ id, tree: sRoots[id] })); | ||
| const removed = [...removedIds]; | ||
| updatedIds.clear(); | ||
| removedIds.clear(); | ||
| return { updated, removed }; | ||
| }); | ||
| function removeRoot2(rootId) { | ||
| removedIds.add(rootId); | ||
| setRoots((map) => omit(map, rootId)); | ||
| } | ||
| function updateRoot2(newRoot) { | ||
| const rootMap = untrack2(roots); | ||
| const rootId = newRoot.id; | ||
| const root = rootMap[rootId]; | ||
| updatedIds.add(rootId); | ||
| if (root) { | ||
| batch(() => { | ||
| root.setTree(newRoot.tree); | ||
| root.setComponents(newRoot.components); | ||
| }); | ||
| } else { | ||
| const [tree, setTree] = createSignal(newRoot.tree); | ||
| const [components2, setComponents] = createSignal(newRoot.components); | ||
| setRoots((map) => ({ | ||
| ...map, | ||
| [rootId]: { id: rootId, tree, setTree, components: components2, setComponents } | ||
| })); | ||
| } | ||
| } | ||
| const [inspected, setInspected] = createStaticStore(getNullInspected()); | ||
| let lastInspectedOwner = null; | ||
| const inspectedSignals = /* @__PURE__ */ new Set(); | ||
| const inspectedProps = /* @__PURE__ */ new Set(); | ||
| const [handleSignalUpdates, pushSignalUpdate] = createBatchedUpdateEmitter(); | ||
| const signalUpdateHandler = untrackedCallback((id, value) => { | ||
| if (!enabled2() || !inspected.id) | ||
| return; | ||
| const isSelected = inspectedSignals.has(id); | ||
| pushSignalUpdate({ id, value: encodeValue2(value, isSelected, inspected.elementMap) }); | ||
| }); | ||
| const [handlePropsUpdate, emitPropsUpdate] = createSimpleEmitter2(); | ||
| const updateInspectedDetails = untrackedCallback(() => { | ||
| const { owner, elementMap } = inspected; | ||
| if (!owner) | ||
| return; | ||
| const { details, signalMap } = collectOwnerDetails(owner, { | ||
| elementMap, | ||
| signalUpdateHandler, | ||
| inspectedProps | ||
| }); | ||
| setInspected({ details, signalMap }); | ||
| }); | ||
| const updateInspectedProps = untrackedCallback(() => { | ||
| const { owner, elementMap } = inspected; | ||
| if (!owner) | ||
| return; | ||
| const props = encodeComponentProps(owner, { inspectedProps, elementMap }); | ||
| props && emitPropsUpdate(props); | ||
| }); | ||
| createEffect(() => { | ||
| if (!enabled2()) | ||
| lastInspectedOwner && clearOwnerObservers(lastInspectedOwner); | ||
| else | ||
| updateInspectedDetails(); | ||
| createEffect(() => { | ||
| const owner = inspected.owner; | ||
| if (lastInspectedOwner && lastInspectedOwner !== owner) | ||
| clearOwnerObservers(lastInspectedOwner); | ||
| lastInspectedOwner = owner; | ||
| makeSolidUpdateListener(throttle2(updateInspectedProps, 150)); | ||
| }); | ||
| }); | ||
| const setInspectedOwner = untrackedCallback((payload) => { | ||
| if (!payload) | ||
| return setInspected(getNullInspected()); | ||
| const { rootId, nodeId } = payload; | ||
| if (inspected.id === nodeId) | ||
| return; | ||
| const result = walkSolidRoot(rootId, nodeId); | ||
| if (!result || !result.inspectedOwner) | ||
| return setInspected(getNullInspected()); | ||
| const owner = result.inspectedOwner; | ||
| const elementMap = new ElementMap2(); | ||
| inspectedProps.clear(); | ||
| inspectedSignals.clear(); | ||
| const { details, signalMap } = collectOwnerDetails(owner, { | ||
| elementMap, | ||
| signalUpdateHandler, | ||
| inspectedProps | ||
| }); | ||
| setInspected({ id: nodeId, rootId, owner, details, signalMap, elementMap }); | ||
| }); | ||
| const setInspectedSignal = untrackedCallback((id, selected) => { | ||
| const { signalMap, elementMap } = inspected; | ||
| const signal = signalMap[id]; | ||
| if (!signal) | ||
| return null; | ||
| if (selected) | ||
| inspectedSignals.add(id); | ||
| else | ||
| inspectedSignals.delete(id); | ||
| return encodeValue2(signal.value, selected, elementMap); | ||
| }); | ||
| const setInspectedProp = untrackedCallback((key, selected) => { | ||
| if (selected) | ||
| inspectedProps.add(key); | ||
| else | ||
| inspectedProps.delete(key); | ||
| updateInspectedProps(); | ||
| }); | ||
| const [handleComputationUpdates, _pushComputationUpdate] = createBatchedUpdateEmitter(); | ||
| const pushComputationUpdate2 = (rootId, id) => { | ||
| _pushComputationUpdate({ rootId, id }); | ||
| }; | ||
| const components = createLazyMemo( | ||
| () => Object.entries(roots()).reduce((obj, [rootId, root]) => { | ||
| obj[rootId] = root.components(); | ||
| return obj; | ||
| }, {}) | ||
| ); | ||
| const pluginData = { | ||
| handleComputationUpdates, | ||
| handleSignalUpdates, | ||
| handlePropsUpdate, | ||
| roots, | ||
| serialisedRoots, | ||
| rootsUpdates, | ||
| components, | ||
| triggerUpdate, | ||
| forceTriggerUpdate, | ||
| setInspectedOwner, | ||
| inspected, | ||
| setInspectedSignal, | ||
| setInspectedProp | ||
| }; | ||
| function useDebugger2(options) { | ||
| const { enabled: enabled3, gatherComponents: gatherComponents3 } = options; | ||
| enabled3 && addDebuggerConsumer(enabled3); | ||
| gatherComponents3 && addGatherComponentsConsumer(gatherComponents3); | ||
| return pluginData; | ||
| } | ||
| return { | ||
| onUpdate: onUpdate2, | ||
| onForceUpdate: onForceUpdate2, | ||
| enabled: enabled2, | ||
| useDebugger: useDebugger2, | ||
| updateRoot: updateRoot2, | ||
| removeRoot: removeRoot2, | ||
| gatherComponents: gatherComponents2, | ||
| pushComputationUpdate: pushComputationUpdate2 | ||
| }; | ||
| }); | ||
| var { | ||
| onUpdate, | ||
| onForceUpdate, | ||
| enabled, | ||
| gatherComponents, | ||
| useDebugger, | ||
| updateRoot, | ||
| removeRoot, | ||
| pushComputationUpdate | ||
| } = exported; | ||
| // src/roots.ts | ||
| import { untrackedCallback as untrackedCallback2 } from "@solid-devtools/shared/primitives"; | ||
| var RootMap = {}; | ||
| var walkSolidRoot = (rootId, inspectedId) => { | ||
| const walk = RootMap[rootId]; | ||
| return walk ? walk(inspectedId) : null; | ||
| }; | ||
| function createGraphRoot(owner) { | ||
| createInternalRoot((dispose) => { | ||
| onOwnerCleanup(owner, dispose); | ||
| const rootId = getNewSdtId(); | ||
| const onComputationUpdate = (rootId2, nodeId) => { | ||
| if (owner.isDisposed) | ||
| return; | ||
| if (untrack3(enabled)) | ||
| triggerRootUpdate(); | ||
| pushComputationUpdate(rootId2, nodeId); | ||
| }; | ||
| const forceRootUpdate = untrackedCallback2((inspectedId) => { | ||
| if (owner.isDisposed) | ||
| return null; | ||
| const { tree, components, inspectedOwner } = walkSolidTree(owner, { | ||
| onComputationUpdate, | ||
| rootId, | ||
| inspectedId: inspectedId ?? null, | ||
| gatherComponents: gatherComponents() | ||
| }); | ||
| updateRoot({ id: rootId, tree, components }); | ||
| return { tree, components, inspectedOwner }; | ||
| }); | ||
| const triggerRootUpdate = throttle3(forceRootUpdate, 350); | ||
| RootMap[rootId] = forceRootUpdate; | ||
| onUpdate(triggerRootUpdate); | ||
| onForceUpdate(forceRootUpdate); | ||
| createEffect2(() => { | ||
| enabled() && forceRootUpdate(); | ||
| }); | ||
| setDebuggerContext(owner, { rootId, triggerRootUpdate, forceRootUpdate }); | ||
| onCleanup(() => { | ||
| removeDebuggerContext(owner); | ||
| removeRoot(rootId); | ||
| owner.isDisposed = true; | ||
| delete RootMap[rootId]; | ||
| }); | ||
| }); | ||
| } | ||
| function attachDebugger(_owner = getOwner2()) { | ||
| let owner = _owner; | ||
| if (!owner) | ||
| return console.warn( | ||
| "reatachOwner helper should be used synchronously inside createRoot callback body." | ||
| ); | ||
| forEachLookupRoot(owner, (root, ctx) => { | ||
| root.sdtAttached = true; | ||
| markOwnerType(root, NodeType3.Root); | ||
| if (ctx === INTERNAL2) | ||
| return; | ||
| if (ctx) { | ||
| ctx.triggerRootUpdate(); | ||
| let parent = findClosestAliveParent(root); | ||
| if (!parent.owner) | ||
| return console.warn("PARENT_SHOULD_BE_ALIVE"); | ||
| let removeFromOwned = addRootToOwnedRoots(parent.owner, root); | ||
| const onParentCleanup2 = () => { | ||
| const newParent = findClosestAliveParent(root); | ||
| if (newParent.owner) { | ||
| parent = newParent; | ||
| removeFromOwned(); | ||
| removeFromOwned = addRootToOwnedRoots(parent.owner, root); | ||
| onOwnerCleanup(parent.root, onParentCleanup2); | ||
| } else { | ||
| removeFromOwned(); | ||
| removeOwnCleanup(); | ||
| createGraphRoot(root); | ||
| } | ||
| }; | ||
| const removeParentCleanup = onOwnerCleanup(parent.root, onParentCleanup2); | ||
| const removeOwnCleanup = onOwnerCleanup(root, () => { | ||
| root.isDisposed = true; | ||
| removeFromOwned(); | ||
| removeParentCleanup(); | ||
| ctx.triggerRootUpdate(); | ||
| }); | ||
| } else | ||
| createGraphRoot(root); | ||
| }); | ||
| } | ||
| function addRootToOwnedRoots(parent, root) { | ||
| const ownedRoots = parent.ownedRoots ?? (parent.ownedRoots = /* @__PURE__ */ new Set()); | ||
| ownedRoots.add(root); | ||
| return () => void ownedRoots.delete(root); | ||
| } | ||
| function findClosestAliveParent(owner) { | ||
| let disposed = null; | ||
| let closestAliveRoot = null; | ||
| let current = owner; | ||
| while (current.owner && !closestAliveRoot) { | ||
| current = current.owner; | ||
| if (isSolidRoot(current)) { | ||
| if (current.isDisposed) | ||
| disposed = current; | ||
| else | ||
| closestAliveRoot = current; | ||
| } | ||
| } | ||
| if (!closestAliveRoot) | ||
| return { owner: null, root: null }; | ||
| return { owner: (disposed == null ? void 0 : disposed.owner) ?? owner.owner, root: closestAliveRoot }; | ||
| } | ||
| function forEachLookupRoot(owner, callback) { | ||
| const roots = []; | ||
| let ctx; | ||
| do { | ||
| if (isSolidRoot(owner)) { | ||
| if (owner.sdtAttached) { | ||
| if (!ctx) | ||
| ctx = getDebuggerContext(owner); | ||
| break; | ||
| } | ||
| if (owner.sdtContext === INTERNAL2) { | ||
| ctx = INTERNAL2; | ||
| break; | ||
| } | ||
| roots.push(owner); | ||
| } | ||
| owner = owner.owner; | ||
| } while (owner); | ||
| for (let i = roots.length - 1; i >= 0; i--) { | ||
| const root = roots[i]; | ||
| callback(root, ctx); | ||
| if (root.sdtContext) | ||
| ctx = root.sdtContext; | ||
| } | ||
| } | ||
| // src/index.ts | ||
| var Debugger = (props) => { | ||
| attachDebugger(); | ||
| return props.children; | ||
| }; | ||
| export { | ||
| isSolidComputation, | ||
| isSolidMemo, | ||
| isSolidOwner, | ||
| isSolidRoot, | ||
| getNodeName, | ||
| getNodeType, | ||
| getOwnerType, | ||
| lookupOwner, | ||
| onOwnerCleanup, | ||
| onParentCleanup, | ||
| createUnownedRoot, | ||
| getFunctionSources, | ||
| createInternalRoot, | ||
| makeSolidUpdateListener, | ||
| makeCreateRootListener, | ||
| makeStoreObserver, | ||
| observeComputationUpdate, | ||
| interceptComputationRerun, | ||
| observeValueUpdate, | ||
| removeValueUpdateObserver, | ||
| makeValueUpdateListener, | ||
| useDebugger, | ||
| attachDebugger, | ||
| Debugger | ||
| }; |
+213
-186
@@ -45,4 +45,4 @@ "use strict"; | ||
| onParentCleanup: () => onParentCleanup, | ||
| registerDebuggerPlugin: () => registerDebuggerPlugin, | ||
| removeValueUpdateObserver: () => removeValueUpdateObserver | ||
| removeValueUpdateObserver: () => removeValueUpdateObserver, | ||
| useDebugger: () => useDebugger | ||
| }); | ||
@@ -52,4 +52,4 @@ module.exports = __toCommonJS(src_exports); | ||
| // src/roots.ts | ||
| var import_solid_js4 = require("solid-js"); | ||
| var import_scheduled2 = require("@solid-primitives/scheduled"); | ||
| var import_solid_js5 = require("solid-js"); | ||
| var import_scheduled3 = require("@solid-primitives/scheduled"); | ||
| var import_graph3 = require("@solid-devtools/shared/graph"); | ||
@@ -61,3 +61,2 @@ var import_variables3 = require("@solid-devtools/shared/variables"); | ||
| var import_graph2 = require("@solid-devtools/shared/graph"); | ||
| var import_serialize = require("@solid-devtools/shared/serialize"); | ||
@@ -76,3 +75,3 @@ // src/utils.ts | ||
| var isSolidRoot = (o) => o.sdtType === import_graph.NodeType.Root || !isSolidComputation(o); | ||
| var _isComponent = (o) => "componentName" in o; | ||
| var isSolidComponent = (o) => "componentName" in o; | ||
| var _isMemo = (o) => "value" in o && "comparator" in o && o.pure === true; | ||
@@ -103,3 +102,3 @@ var fnMatchesRefresh = (fn) => (fn + "").replace(/[\n\t]/g, "").replace(/ +/g, " ") === "() => { const c = source(); if (c) { return untrack(() => c(props)); } return undefined; }"; | ||
| return import_graph.NodeType.Root; | ||
| if (_isComponent(o)) | ||
| if (isSolidComponent(o)) | ||
| return import_graph.NodeType.Component; | ||
@@ -335,13 +334,8 @@ if (_isMemo(o)) { | ||
| // src/walker.ts | ||
| var SelectedId; | ||
| var InspectedId; | ||
| var RootId; | ||
| var OnSignalUpdate; | ||
| var OnComputationUpdate; | ||
| var GatherComponents; | ||
| var Components = []; | ||
| var SelectedOwner; | ||
| var SelectedDetails; | ||
| var SelectedSignalMap; | ||
| var ElementMap; | ||
| var WALKER = Symbol("walker"); | ||
| var InspectedOwner; | ||
| function observeComputation(owner, id) { | ||
@@ -351,56 +345,2 @@ if (isSolidComputation(owner)) | ||
| } | ||
| function observeValue(node) { | ||
| const id = markNodeID(node); | ||
| const handler = OnSignalUpdate; | ||
| observeValueUpdate(node, (value) => handler(id, value), WALKER); | ||
| } | ||
| function mapSignalNode(node) { | ||
| const id = markNodeID(node); | ||
| SelectedSignalMap[id] = node; | ||
| observeValue(node); | ||
| return { | ||
| type: getNodeType(node), | ||
| name: getNodeName(node), | ||
| id, | ||
| observers: markNodesID(node.observers), | ||
| value: (0, import_serialize.encodeValue)(node.value, false, ElementMap) | ||
| }; | ||
| } | ||
| function clearOwnerObservers(owner) { | ||
| if (owner.sourceMap) | ||
| Object.values(owner.sourceMap).forEach((node) => removeValueUpdateObserver(node, WALKER)); | ||
| if (owner.owned) | ||
| owner.owned.forEach((node) => removeValueUpdateObserver(node, WALKER)); | ||
| } | ||
| function collectOwnerDetails(owner) { | ||
| var _a; | ||
| const path = []; | ||
| let current = owner.owner; | ||
| while (current) { | ||
| path.unshift(markNodeID(current)); | ||
| current = current.owner; | ||
| } | ||
| const signals = owner.sourceMap ? Object.values(owner.sourceMap).map(mapSignalNode) : []; | ||
| (_a = owner.owned) == null ? void 0 : _a.forEach((child) => { | ||
| if (!isSolidMemo(child)) | ||
| return; | ||
| signals.push(mapSignalNode(child)); | ||
| }); | ||
| const details = { | ||
| id: owner.sdtId, | ||
| name: owner.sdtName, | ||
| type: owner.sdtType, | ||
| path, | ||
| signals | ||
| }; | ||
| if (isSolidComputation(owner)) { | ||
| details.value = (0, import_serialize.encodeValue)(owner.value, false, ElementMap); | ||
| details.sources = markNodesID(owner.sources); | ||
| if (isSolidMemo(owner)) { | ||
| details.observers = markNodesID(owner.observers); | ||
| } | ||
| } | ||
| SelectedOwner = owner; | ||
| SelectedDetails = details; | ||
| } | ||
| function mapChildren({ owned, ownedRoots }) { | ||
@@ -424,4 +364,4 @@ const children = []; | ||
| const name = markOwnerName(owner); | ||
| if (id === SelectedId) | ||
| collectOwnerDetails(owner); | ||
| if (id === InspectedId) | ||
| InspectedOwner = owner; | ||
| observeComputation(owner, id); | ||
@@ -442,39 +382,104 @@ if (GatherComponents && type === import_graph2.NodeType.Component) { | ||
| function walkSolidTree(owner, config) { | ||
| SelectedId = config.selectedId; | ||
| InspectedId = config.inspectedId; | ||
| RootId = config.rootId; | ||
| OnSignalUpdate = config.onSignalUpdate; | ||
| OnComputationUpdate = config.onComputationUpdate; | ||
| GatherComponents = config.gatherComponents; | ||
| SelectedOwner = null; | ||
| SelectedDetails = null; | ||
| SelectedSignalMap = {}; | ||
| InspectedOwner = null; | ||
| Components = []; | ||
| ElementMap = config.elementMap ?? {}; | ||
| const tree = mapOwner(owner); | ||
| const components = Components; | ||
| const focusedOwner = SelectedOwner; | ||
| const focusedOwnerDetails = SelectedDetails; | ||
| const focusedOwnerSignalMap = SelectedSignalMap; | ||
| const elementMap = ElementMap; | ||
| return { | ||
| tree, | ||
| components, | ||
| selected: { | ||
| details: focusedOwnerDetails, | ||
| owner: focusedOwner, | ||
| signalMap: focusedOwnerSignalMap, | ||
| elementMap | ||
| } | ||
| }; | ||
| return { tree, components: Components, inspectedOwner: InspectedOwner }; | ||
| } | ||
| // src/plugin.ts | ||
| var import_solid_js3 = require("solid-js"); | ||
| var import_solid_js4 = require("solid-js"); | ||
| var import_event_bus2 = require("@solid-primitives/event-bus"); | ||
| var import_immutable = require("@solid-primitives/immutable"); | ||
| var import_memo = require("@solid-primitives/memo"); | ||
| var import_utils6 = require("@solid-primitives/utils"); | ||
| var import_utils7 = require("@solid-primitives/utils"); | ||
| var import_scheduled2 = require("@solid-primitives/scheduled"); | ||
| var import_serialize2 = require("@solid-devtools/shared/serialize"); | ||
| var import_primitives = require("@solid-devtools/shared/primitives"); | ||
| var getNullFocusedState = () => ({ | ||
| // src/inspect.ts | ||
| var import_serialize = require("@solid-devtools/shared/serialize"); | ||
| var import_solid_js3 = require("solid-js"); | ||
| var $elementMap; | ||
| var $signalMap; | ||
| var INSPECTOR = Symbol("inspector"); | ||
| function mapSignalNode(node, handler) { | ||
| const id = markNodeID(node); | ||
| $signalMap[id] = node; | ||
| observeValueUpdate(node, (value) => handler(id, value), INSPECTOR); | ||
| return { | ||
| type: getNodeType(node), | ||
| name: getNodeName(node), | ||
| id, | ||
| observers: markNodesID(node.observers), | ||
| value: (0, import_serialize.encodeValue)(node.value, false, $elementMap) | ||
| }; | ||
| } | ||
| function clearOwnerObservers(owner) { | ||
| if (owner.sourceMap) | ||
| Object.values(owner.sourceMap).forEach((node) => removeValueUpdateObserver(node, INSPECTOR)); | ||
| if (owner.owned) | ||
| owner.owned.forEach((node) => removeValueUpdateObserver(node, INSPECTOR)); | ||
| } | ||
| function encodeComponentProps(owner, config) { | ||
| if (!isSolidComponent(owner)) | ||
| return null; | ||
| const { elementMap, inspectedProps } = config; | ||
| const { props } = owner; | ||
| const proxy = !!props[import_solid_js3.$PROXY]; | ||
| const record = Object.entries(Object.getOwnPropertyDescriptors(props)).reduce( | ||
| (record2, [key, descriptor]) => { | ||
| record2[key] = "get" in descriptor ? { type: import_serialize.ValueType.Getter, value: key } : (0, import_serialize.encodeValue)(descriptor.value, inspectedProps.has(key), elementMap); | ||
| return record2; | ||
| }, | ||
| {} | ||
| ); | ||
| return { proxy, record }; | ||
| } | ||
| function collectOwnerDetails(owner, config) { | ||
| var _a; | ||
| const { elementMap, signalUpdateHandler, inspectedProps } = config; | ||
| const signalMap = {}; | ||
| $elementMap = elementMap; | ||
| $signalMap = signalMap; | ||
| const path = []; | ||
| let current = owner.owner; | ||
| while (current) { | ||
| path.unshift(markNodeID(current)); | ||
| current = current.owner; | ||
| } | ||
| const signals = owner.sourceMap ? Object.values(owner.sourceMap).map((s) => mapSignalNode(s, signalUpdateHandler)) : []; | ||
| (_a = owner.owned) == null ? void 0 : _a.forEach((child) => { | ||
| if (!isSolidMemo(child)) | ||
| return; | ||
| signals.push(mapSignalNode(child, signalUpdateHandler)); | ||
| }); | ||
| const details = { | ||
| id: markNodeID(owner), | ||
| name: markOwnerName(owner), | ||
| type: markOwnerType(owner), | ||
| path, | ||
| signals | ||
| }; | ||
| if (isSolidComputation(owner)) { | ||
| details.value = (0, import_serialize.encodeValue)(owner.value, false, elementMap); | ||
| details.sources = markNodesID(owner.sources); | ||
| if (isSolidMemo(owner)) { | ||
| details.observers = markNodesID(owner.observers); | ||
| } | ||
| const props = encodeComponentProps(owner, { inspectedProps, elementMap }); | ||
| if (props) | ||
| details.props = props; | ||
| } | ||
| return { | ||
| details, | ||
| signalMap | ||
| }; | ||
| } | ||
| // src/plugin.ts | ||
| var getNullInspected = () => ({ | ||
| id: null, | ||
@@ -485,3 +490,3 @@ rootId: null, | ||
| signalMap: {}, | ||
| elementMap: {} | ||
| elementMap: new import_serialize2.ElementMap() | ||
| }); | ||
@@ -493,4 +498,3 @@ var exported = createInternalRoot(() => { | ||
| const [gatherComponents2, addGatherComponentsConsumer] = (0, import_primitives.createConsumers)(); | ||
| const [observeComputations, addObserveComputationsConsumer] = (0, import_primitives.createConsumers)(); | ||
| const [roots, setRoots] = (0, import_solid_js3.createSignal)({}); | ||
| const [roots, setRoots] = (0, import_solid_js4.createSignal)({}); | ||
| const serialisedRoots = (0, import_memo.createLazyMemo)(() => { | ||
@@ -519,3 +523,3 @@ const serialisedRoots2 = {}; | ||
| function updateRoot2(newRoot) { | ||
| const rootMap = (0, import_solid_js3.untrack)(roots); | ||
| const rootMap = (0, import_solid_js4.untrack)(roots); | ||
| const rootId = newRoot.id; | ||
@@ -525,3 +529,3 @@ const root = rootMap[rootId]; | ||
| if (root) { | ||
| (0, import_solid_js3.batch)(() => { | ||
| (0, import_solid_js4.batch)(() => { | ||
| root.setTree(newRoot.tree); | ||
@@ -531,4 +535,4 @@ root.setComponents(newRoot.components); | ||
| } else { | ||
| const [tree, setTree] = (0, import_solid_js3.createSignal)(newRoot.tree); | ||
| const [components2, setComponents] = (0, import_solid_js3.createSignal)(newRoot.components); | ||
| const [tree, setTree] = (0, import_solid_js4.createSignal)(newRoot.tree); | ||
| const [components2, setComponents] = (0, import_solid_js4.createSignal)(newRoot.components); | ||
| setRoots((map) => ({ | ||
@@ -540,40 +544,85 @@ ...map, | ||
| } | ||
| const [focusedState2, setFocusedState] = (0, import_utils6.createStaticStore)(getNullFocusedState()); | ||
| const setFocusedOwner = (0, import_primitives.untrackedCallback)((payload) => { | ||
| const [inspected, setInspected] = (0, import_utils7.createStaticStore)(getNullInspected()); | ||
| let lastInspectedOwner = null; | ||
| const inspectedSignals = /* @__PURE__ */ new Set(); | ||
| const inspectedProps = /* @__PURE__ */ new Set(); | ||
| const [handleSignalUpdates, pushSignalUpdate] = createBatchedUpdateEmitter(); | ||
| const signalUpdateHandler = (0, import_primitives.untrackedCallback)((id, value) => { | ||
| if (!enabled2() || !inspected.id) | ||
| return; | ||
| const isSelected = inspectedSignals.has(id); | ||
| pushSignalUpdate({ id, value: (0, import_serialize2.encodeValue)(value, isSelected, inspected.elementMap) }); | ||
| }); | ||
| const [handlePropsUpdate, emitPropsUpdate] = (0, import_event_bus2.createSimpleEmitter)(); | ||
| const updateInspectedDetails = (0, import_primitives.untrackedCallback)(() => { | ||
| const { owner, elementMap } = inspected; | ||
| if (!owner) | ||
| return; | ||
| const { details, signalMap } = collectOwnerDetails(owner, { | ||
| elementMap, | ||
| signalUpdateHandler, | ||
| inspectedProps | ||
| }); | ||
| setInspected({ details, signalMap }); | ||
| }); | ||
| const updateInspectedProps = (0, import_primitives.untrackedCallback)(() => { | ||
| const { owner, elementMap } = inspected; | ||
| if (!owner) | ||
| return; | ||
| const props = encodeComponentProps(owner, { inspectedProps, elementMap }); | ||
| props && emitPropsUpdate(props); | ||
| }); | ||
| (0, import_solid_js4.createEffect)(() => { | ||
| if (!enabled2()) | ||
| lastInspectedOwner && clearOwnerObservers(lastInspectedOwner); | ||
| else | ||
| updateInspectedDetails(); | ||
| (0, import_solid_js4.createEffect)(() => { | ||
| const owner = inspected.owner; | ||
| if (lastInspectedOwner && lastInspectedOwner !== owner) | ||
| clearOwnerObservers(lastInspectedOwner); | ||
| lastInspectedOwner = owner; | ||
| makeSolidUpdateListener((0, import_scheduled2.throttle)(updateInspectedProps, 150)); | ||
| }); | ||
| }); | ||
| const setInspectedOwner = (0, import_primitives.untrackedCallback)((payload) => { | ||
| if (!payload) | ||
| return setFocusedState(getNullFocusedState()); | ||
| return setInspected(getNullInspected()); | ||
| const { rootId, nodeId } = payload; | ||
| if (focusedState2.id === nodeId) | ||
| if (inspected.id === nodeId) | ||
| return; | ||
| setFocusedState({ ...getNullFocusedState(), id: nodeId, rootId }); | ||
| forceRootUpdate(rootId); | ||
| const result = walkSolidRoot(rootId, nodeId); | ||
| if (!result || !result.inspectedOwner) | ||
| return setInspected(getNullInspected()); | ||
| const owner = result.inspectedOwner; | ||
| const elementMap = new import_serialize2.ElementMap(); | ||
| inspectedProps.clear(); | ||
| inspectedSignals.clear(); | ||
| const { details, signalMap } = collectOwnerDetails(owner, { | ||
| elementMap, | ||
| signalUpdateHandler, | ||
| inspectedProps | ||
| }); | ||
| setInspected({ id: nodeId, rootId, owner, details, signalMap, elementMap }); | ||
| }); | ||
| const setSelectedDetails2 = (payload) => { | ||
| setFocusedState(payload.details ? payload : getNullFocusedState()); | ||
| }; | ||
| const selectedSignalIds = /* @__PURE__ */ new Set(); | ||
| const setSelectedSignal = (0, import_primitives.untrackedCallback)( | ||
| ({ id, selected }) => { | ||
| const { signalMap, elementMap } = focusedState2; | ||
| const signal = signalMap[id]; | ||
| if (!signal) | ||
| return null; | ||
| if (selected) | ||
| selectedSignalIds.add(id); | ||
| else | ||
| selectedSignalIds.delete(id); | ||
| return (0, import_serialize2.encodeValue)(signal.value, selected, elementMap); | ||
| } | ||
| ); | ||
| const [handleSignalUpdates, _pushSignalUpdate] = createBatchedUpdateEmitter(); | ||
| const pushSignalUpdate2 = (0, import_primitives.untrackedCallback)((id, value) => { | ||
| if (!enabled2() || !focusedState2.id) | ||
| return; | ||
| const isSelected = selectedSignalIds.has(id); | ||
| _pushSignalUpdate({ id, value: (0, import_serialize2.encodeValue)(value, isSelected, focusedState2.elementMap) }); | ||
| const setInspectedSignal = (0, import_primitives.untrackedCallback)((id, selected) => { | ||
| const { signalMap, elementMap } = inspected; | ||
| const signal = signalMap[id]; | ||
| if (!signal) | ||
| return null; | ||
| if (selected) | ||
| inspectedSignals.add(id); | ||
| else | ||
| inspectedSignals.delete(id); | ||
| return (0, import_serialize2.encodeValue)(signal.value, selected, elementMap); | ||
| }); | ||
| const setInspectedProp = (0, import_primitives.untrackedCallback)((key, selected) => { | ||
| if (selected) | ||
| inspectedProps.add(key); | ||
| else | ||
| inspectedProps.delete(key); | ||
| updateInspectedProps(); | ||
| }); | ||
| const [handleComputationUpdates, _pushComputationUpdate] = createBatchedUpdateEmitter(); | ||
| const pushComputationUpdate2 = (rootId, id) => { | ||
| if (!(0, import_solid_js3.untrack)(enabled2) || !(0, import_solid_js3.untrack)(observeComputations)) | ||
| return; | ||
| _pushComputationUpdate({ rootId, id }); | ||
@@ -590,2 +639,3 @@ }; | ||
| handleSignalUpdates, | ||
| handlePropsUpdate, | ||
| roots, | ||
@@ -597,14 +647,12 @@ serialisedRoots, | ||
| forceTriggerUpdate, | ||
| setFocusedOwner, | ||
| focusedState: focusedState2, | ||
| setSelectedSignal | ||
| setInspectedOwner, | ||
| inspected, | ||
| setInspectedSignal, | ||
| setInspectedProp | ||
| }; | ||
| const owner = (0, import_solid_js3.getOwner)(); | ||
| function registerDebuggerPlugin2(factory) { | ||
| (0, import_solid_js3.runWithOwner)(owner, () => { | ||
| const { enabled: enabled3, gatherComponents: gatherComponents3, observeComputations: observeComputations2 } = factory(pluginData); | ||
| enabled3 && addDebuggerConsumer(enabled3); | ||
| gatherComponents3 && addGatherComponentsConsumer(gatherComponents3); | ||
| observeComputations2 && addObserveComputationsConsumer(observeComputations2); | ||
| }); | ||
| function useDebugger2(options) { | ||
| const { enabled: enabled3, gatherComponents: gatherComponents3 } = options; | ||
| enabled3 && addDebuggerConsumer(enabled3); | ||
| gatherComponents3 && addGatherComponentsConsumer(gatherComponents3); | ||
| return pluginData; | ||
| } | ||
@@ -615,9 +663,6 @@ return { | ||
| enabled: enabled2, | ||
| registerDebuggerPlugin: registerDebuggerPlugin2, | ||
| useDebugger: useDebugger2, | ||
| updateRoot: updateRoot2, | ||
| removeRoot: removeRoot2, | ||
| gatherComponents: gatherComponents2, | ||
| pushSignalUpdate: pushSignalUpdate2, | ||
| setSelectedDetails: setSelectedDetails2, | ||
| focusedState: focusedState2, | ||
| pushComputationUpdate: pushComputationUpdate2 | ||
@@ -631,8 +676,5 @@ }; | ||
| gatherComponents, | ||
| registerDebuggerPlugin, | ||
| useDebugger, | ||
| updateRoot, | ||
| removeRoot, | ||
| pushSignalUpdate, | ||
| setSelectedDetails, | ||
| focusedState, | ||
| pushComputationUpdate | ||
@@ -644,3 +686,6 @@ } = exported; | ||
| var RootMap = {}; | ||
| var forceRootUpdate = (rootId) => RootMap[rootId].forceUpdate(); | ||
| var walkSolidRoot = (rootId, inspectedId) => { | ||
| const walk = RootMap[rootId]; | ||
| return walk ? walk(inspectedId) : null; | ||
| }; | ||
| function createGraphRoot(owner) { | ||
@@ -653,48 +698,30 @@ createInternalRoot((dispose) => { | ||
| return; | ||
| if ((0, import_solid_js4.untrack)(enabled)) | ||
| if ((0, import_solid_js5.untrack)(enabled)) | ||
| triggerRootUpdate(); | ||
| pushComputationUpdate(rootId2, nodeId); | ||
| }; | ||
| const onSignalUpdate = (nodeId, value) => { | ||
| const forceRootUpdate = (0, import_primitives2.untrackedCallback)((inspectedId) => { | ||
| if (owner.isDisposed) | ||
| return; | ||
| pushSignalUpdate(nodeId, value); | ||
| }; | ||
| let lastSelectedOwner = null; | ||
| const forceRootUpdate2 = (0, import_primitives2.untrackedCallback)(() => { | ||
| if (owner.isDisposed) | ||
| return; | ||
| lastSelectedOwner && clearOwnerObservers(lastSelectedOwner); | ||
| const { tree, components, selected } = walkSolidTree(owner, { | ||
| return null; | ||
| const { tree, components, inspectedOwner } = walkSolidTree(owner, { | ||
| onComputationUpdate, | ||
| onSignalUpdate, | ||
| rootId, | ||
| selectedId: focusedState.id, | ||
| gatherComponents: gatherComponents(), | ||
| elementMap: focusedState.elementMap | ||
| inspectedId: inspectedId ?? null, | ||
| gatherComponents: gatherComponents() | ||
| }); | ||
| lastSelectedOwner = selected.owner; | ||
| if (focusedState.rootId === rootId) | ||
| setSelectedDetails(selected); | ||
| updateRoot({ id: rootId, tree, components }); | ||
| return { tree, components, inspectedOwner }; | ||
| }); | ||
| const triggerRootUpdate = (0, import_scheduled2.throttle)(forceRootUpdate2, 350); | ||
| RootMap[rootId] = { | ||
| update: triggerRootUpdate, | ||
| forceUpdate: forceRootUpdate2 | ||
| }; | ||
| const triggerRootUpdate = (0, import_scheduled3.throttle)(forceRootUpdate, 350); | ||
| RootMap[rootId] = forceRootUpdate; | ||
| onUpdate(triggerRootUpdate); | ||
| onForceUpdate(forceRootUpdate2); | ||
| (0, import_solid_js4.createEffect)(() => { | ||
| if (enabled()) | ||
| forceRootUpdate2(); | ||
| else | ||
| lastSelectedOwner && clearOwnerObservers(lastSelectedOwner); | ||
| onForceUpdate(forceRootUpdate); | ||
| (0, import_solid_js5.createEffect)(() => { | ||
| enabled() && forceRootUpdate(); | ||
| }); | ||
| setDebuggerContext(owner, { rootId, triggerRootUpdate, forceRootUpdate: forceRootUpdate2 }); | ||
| (0, import_solid_js4.onCleanup)(() => { | ||
| setDebuggerContext(owner, { rootId, triggerRootUpdate, forceRootUpdate }); | ||
| (0, import_solid_js5.onCleanup)(() => { | ||
| removeDebuggerContext(owner); | ||
| removeRoot(rootId); | ||
| owner.isDisposed = true; | ||
| lastSelectedOwner && clearOwnerObservers(lastSelectedOwner); | ||
| delete RootMap[rootId]; | ||
@@ -822,4 +849,4 @@ }); | ||
| onParentCleanup, | ||
| registerDebuggerPlugin, | ||
| removeValueUpdateObserver | ||
| removeValueUpdateObserver, | ||
| useDebugger | ||
| }); |
+16
-23
| import { Accessor, createRoot, ParentComponent } from 'solid-js'; | ||
| import { Listen } from '@solid-primitives/event-bus'; | ||
| import { NodeID, Solid, Mapped, ComputationUpdate, RootsUpdates, SignalUpdate, Core, ValueUpdateListener, NodeType } from '@solid-devtools/shared/graph'; | ||
| import { EncodedValue } from '@solid-devtools/shared/serialize'; | ||
| import { ElementMap, EncodedValue } from '@solid-devtools/shared/serialize'; | ||
| import { Observer } from 'object-observer'; | ||
@@ -8,9 +9,9 @@ export { Observer as ObjectObserver } from 'object-observer'; | ||
| declare type SetSelectedOwner = (payload: { | ||
| declare type SetInspectedOwner = (payload: { | ||
| rootId: NodeID; | ||
| nodeId: NodeID; | ||
| } | null) => void; | ||
| declare type FocusedState = Readonly<{ | ||
| declare type InspectedState = Readonly<{ | ||
| signalMap: Record<NodeID, Solid.Signal>; | ||
| elementMap: Record<NodeID, HTMLElement>; | ||
| elementMap: ElementMap; | ||
| } & ({ | ||
@@ -24,7 +25,2 @@ id: null; | ||
| rootId: NodeID; | ||
| owner: null; | ||
| details: null; | ||
| } | { | ||
| id: NodeID; | ||
| rootId: NodeID; | ||
| owner: Solid.Owner; | ||
@@ -40,3 +36,3 @@ details: Mapped.OwnerDetails; | ||
| declare type BatchSignalUpdatesHandler = (payload: SignalUpdate[]) => void; | ||
| declare type PluginFactoryData = { | ||
| declare type PluginData = { | ||
| readonly triggerUpdate: VoidFunction; | ||
@@ -46,2 +42,3 @@ readonly forceTriggerUpdate: VoidFunction; | ||
| readonly handleSignalUpdates: (listener: BatchSignalUpdatesHandler) => VoidFunction; | ||
| readonly handlePropsUpdate: Listen<Mapped.Props>; | ||
| readonly roots: Accessor<Record<NodeID, SignaledRoot>>; | ||
@@ -51,15 +48,11 @@ readonly serialisedRoots: Accessor<Record<NodeID, Mapped.Owner>>; | ||
| readonly components: Accessor<Record<NodeID, Mapped.Component[]>>; | ||
| readonly setFocusedOwner: SetSelectedOwner; | ||
| readonly focusedState: FocusedState; | ||
| readonly setSelectedSignal: (payload: { | ||
| id: NodeID; | ||
| selected: boolean; | ||
| }) => EncodedValue<boolean> | null; | ||
| readonly setInspectedOwner: SetInspectedOwner; | ||
| readonly inspected: InspectedState; | ||
| readonly setInspectedSignal: (id: NodeID, selected: boolean) => EncodedValue<boolean> | null; | ||
| readonly setInspectedProp: (key: NodeID, selected: boolean) => void; | ||
| }; | ||
| declare type PluginFactory = (data: PluginFactoryData) => { | ||
| enabled?: Accessor<boolean>; | ||
| observeComputations?: Accessor<boolean>; | ||
| gatherComponents?: Accessor<boolean>; | ||
| }; | ||
| declare const registerDebuggerPlugin: (factory: PluginFactory) => void; | ||
| declare const useDebugger: (options: { | ||
| enabled?: Accessor<boolean> | undefined; | ||
| gatherComponents?: Accessor<boolean> | undefined; | ||
| }) => PluginData; | ||
@@ -157,2 +150,2 @@ /** | ||
| export { AfterCrateRoot, BatchComputationUpdatesHandler, Debugger, FocusedState, PluginFactory, PluginFactoryData, SetSelectedOwner, SignaledRoot, attachDebugger, createInternalRoot, createUnownedRoot, getFunctionSources, getNodeName, getNodeType, getOwnerType, interceptComputationRerun, isSolidComputation, isSolidMemo, isSolidOwner, isSolidRoot, lookupOwner, makeCreateRootListener, makeSolidUpdateListener, makeStoreObserver, makeValueUpdateListener, observeComputationUpdate, observeValueUpdate, onOwnerCleanup, onParentCleanup, registerDebuggerPlugin, removeValueUpdateObserver }; | ||
| export { AfterCrateRoot, BatchComputationUpdatesHandler, Debugger, InspectedState, PluginData, SetInspectedOwner, SignaledRoot, attachDebugger, createInternalRoot, createUnownedRoot, getFunctionSources, getNodeName, getNodeType, getOwnerType, interceptComputationRerun, isSolidComputation, isSolidMemo, isSolidOwner, isSolidRoot, lookupOwner, makeCreateRootListener, makeSolidUpdateListener, makeStoreObserver, makeValueUpdateListener, observeComputationUpdate, observeValueUpdate, onOwnerCleanup, onParentCleanup, removeValueUpdateObserver, useDebugger }; |
+5
-5
@@ -24,5 +24,5 @@ import { | ||
| onParentCleanup, | ||
| registerDebuggerPlugin, | ||
| removeValueUpdateObserver | ||
| } from "./chunk-RQ2OKIAD.js"; | ||
| removeValueUpdateObserver, | ||
| useDebugger | ||
| } from "./chunk-7UMZO4QB.js"; | ||
| export { | ||
@@ -51,4 +51,4 @@ Debugger, | ||
| onParentCleanup, | ||
| registerDebuggerPlugin, | ||
| removeValueUpdateObserver | ||
| removeValueUpdateObserver, | ||
| useDebugger | ||
| }; |
+27
-5
@@ -45,4 +45,4 @@ "use strict"; | ||
| onParentCleanup: () => onParentCleanup2, | ||
| registerDebuggerPlugin: () => registerDebuggerPlugin, | ||
| removeValueUpdateObserver: () => removeValueUpdateObserver | ||
| removeValueUpdateObserver: () => removeValueUpdateObserver, | ||
| useDebugger: () => useDebugger | ||
| }); | ||
@@ -53,2 +53,3 @@ module.exports = __toCommonJS(server_exports); | ||
| var import_solid_js2 = require("solid-js"); | ||
| var import_serialize = require("@solid-devtools/shared/serialize"); | ||
@@ -71,3 +72,24 @@ // src/utils.ts | ||
| var attachDebugger = import_utils4.noop; | ||
| var registerDebuggerPlugin = import_utils4.noop; | ||
| var useDebugger = () => ({ | ||
| triggerUpdate: import_utils4.noop, | ||
| forceTriggerUpdate: import_utils4.noop, | ||
| handleComputationUpdates: () => import_utils4.noop, | ||
| handleSignalUpdates: () => import_utils4.noop, | ||
| roots: () => ({}), | ||
| serialisedRoots: () => ({}), | ||
| rootsUpdates: () => ({ removed: [], updated: [] }), | ||
| components: () => ({}), | ||
| setInspectedOwner: import_utils4.noop, | ||
| inspected: { | ||
| details: null, | ||
| elementMap: new import_serialize.ElementMap(), | ||
| id: null, | ||
| owner: null, | ||
| rootId: null, | ||
| signalMap: {} | ||
| }, | ||
| handlePropsUpdate: () => import_utils4.noop, | ||
| setInspectedSignal: () => null, | ||
| setInspectedProp: import_utils4.noop | ||
| }); | ||
| var makeSolidUpdateListener = () => import_utils4.noop; | ||
@@ -117,4 +139,4 @@ var makeCreateRootListener = () => import_utils4.noop; | ||
| onParentCleanup, | ||
| registerDebuggerPlugin, | ||
| removeValueUpdateObserver | ||
| removeValueUpdateObserver, | ||
| useDebugger | ||
| }); |
+26
-4
| import { | ||
| createUnownedRoot | ||
| } from "./chunk-RQ2OKIAD.js"; | ||
| } from "./chunk-7UMZO4QB.js"; | ||
@@ -9,5 +9,27 @@ // src/server.ts | ||
| import { createRoot } from "solid-js"; | ||
| import { ElementMap } from "@solid-devtools/shared/serialize"; | ||
| var Debugger = (props) => props.children; | ||
| var attachDebugger = noop; | ||
| var registerDebuggerPlugin = noop; | ||
| var useDebugger = () => ({ | ||
| triggerUpdate: noop, | ||
| forceTriggerUpdate: noop, | ||
| handleComputationUpdates: () => noop, | ||
| handleSignalUpdates: () => noop, | ||
| roots: () => ({}), | ||
| serialisedRoots: () => ({}), | ||
| rootsUpdates: () => ({ removed: [], updated: [] }), | ||
| components: () => ({}), | ||
| setInspectedOwner: noop, | ||
| inspected: { | ||
| details: null, | ||
| elementMap: new ElementMap(), | ||
| id: null, | ||
| owner: null, | ||
| rootId: null, | ||
| signalMap: {} | ||
| }, | ||
| handlePropsUpdate: () => noop, | ||
| setInspectedSignal: () => null, | ||
| setInspectedProp: noop | ||
| }); | ||
| var makeSolidUpdateListener = () => noop; | ||
@@ -56,4 +78,4 @@ var makeCreateRootListener = () => noop; | ||
| onParentCleanup, | ||
| registerDebuggerPlugin, | ||
| removeValueUpdateObserver | ||
| removeValueUpdateObserver, | ||
| useDebugger | ||
| }; |
+4
-4
| { | ||
| "name": "@solid-devtools/debugger", | ||
| "version": "0.7.2", | ||
| "version": "0.8.0", | ||
| "description": "Debugger of the Solid's reactivity graph — a cornerstone of all solid-devtools.", | ||
@@ -50,3 +50,3 @@ "license": "MIT", | ||
| "jest-environment-jsdom": "^28.1.3", | ||
| "solid-js": "^1.5.2", | ||
| "solid-js": "^1.5.5", | ||
| "ts-node": "^10.9.1", | ||
@@ -57,3 +57,3 @@ "tsup": "^6.2.3", | ||
| "dependencies": { | ||
| "@solid-devtools/shared": "^0.7.2", | ||
| "@solid-devtools/shared": "^0.7.4", | ||
| "@solid-primitives/event-bus": "^0.1.2", | ||
@@ -72,3 +72,3 @@ "@solid-primitives/immutable": "^0.1.2", | ||
| "optionalDependencies": { | ||
| "@solid-devtools/transform": "^0.7.1" | ||
| "@solid-devtools/transform": "^0.7.2" | ||
| }, | ||
@@ -75,0 +75,0 @@ "packageManager": "pnpm@7.9.0", |
| // src/roots.ts | ||
| import { createEffect, onCleanup, untrack as untrack3 } from "solid-js"; | ||
| import { throttle as throttle2 } from "@solid-primitives/scheduled"; | ||
| import { | ||
| getOwner as getOwner3, | ||
| NodeType as NodeType3 | ||
| } from "@solid-devtools/shared/graph"; | ||
| import { INTERNAL as INTERNAL2 } from "@solid-devtools/shared/variables"; | ||
| // src/walker.ts | ||
| import { resolveElements } from "@solid-primitives/refs"; | ||
| import { NodeType as NodeType2 } from "@solid-devtools/shared/graph"; | ||
| import { encodeValue } from "@solid-devtools/shared/serialize"; | ||
| // src/utils.ts | ||
| import { | ||
| createComputed, | ||
| createRoot, | ||
| runWithOwner | ||
| } from "solid-js"; | ||
| import { noop, warn } from "@solid-primitives/utils"; | ||
| import { | ||
| NodeType, | ||
| getOwner | ||
| } from "@solid-devtools/shared/graph"; | ||
| import { INTERNAL, UNNAMED } from "@solid-devtools/shared/variables"; | ||
| import { trimString } from "@solid-devtools/shared/utils"; | ||
| import { createSimpleEmitter } from "@solid-primitives/event-bus"; | ||
| import { throttle } from "@solid-primitives/scheduled"; | ||
| var isSolidComputation = (o) => "fn" in o; | ||
| var isSolidMemo = (o) => "sdtType" in o ? o.sdtType === NodeType.Memo : _isMemo(o) && !fnMatchesRefresh(o.fn); | ||
| var isSolidOwner = (o) => "owned" in o; | ||
| var isSolidRoot = (o) => o.sdtType === NodeType.Root || !isSolidComputation(o); | ||
| var _isComponent = (o) => "componentName" in o; | ||
| var _isMemo = (o) => "value" in o && "comparator" in o && o.pure === true; | ||
| var fnMatchesRefresh = (fn) => (fn + "").replace(/[\n\t]/g, "").replace(/ +/g, " ") === "() => { const c = source(); if (c) { return untrack(() => c(props)); } return undefined; }"; | ||
| function getOwnerName(owner) { | ||
| const { name, componentName: component } = owner; | ||
| if (component && typeof component === "string") | ||
| return component.startsWith("_Hot$$") ? component.slice(6) : component; | ||
| return name || UNNAMED; | ||
| } | ||
| function getSignalName(signal) { | ||
| return signal.name || UNNAMED; | ||
| } | ||
| function getNodeName(o) { | ||
| const name = isSolidOwner(o) ? getOwnerName(o) : getSignalName(o); | ||
| return trimString(name, 16); | ||
| } | ||
| function getNodeType(o) { | ||
| if (isSolidOwner(o)) | ||
| return getOwnerType(o); | ||
| return NodeType.Signal; | ||
| } | ||
| var getOwnerType = (o) => { | ||
| if (typeof o.sdtType !== "undefined") | ||
| return o.sdtType; | ||
| if (!isSolidComputation(o)) | ||
| return NodeType.Root; | ||
| if (_isComponent(o)) | ||
| return NodeType.Component; | ||
| if (_isMemo(o)) { | ||
| if (fnMatchesRefresh(o.fn)) | ||
| return NodeType.Refresh; | ||
| return NodeType.Memo; | ||
| } | ||
| if (o.pure === false) { | ||
| if (o.user === true) | ||
| return NodeType.Effect; | ||
| return NodeType.Render; | ||
| } | ||
| return NodeType.Computation; | ||
| }; | ||
| function lookupOwner(owner, predicate) { | ||
| do { | ||
| if (predicate(owner)) | ||
| return owner; | ||
| owner = owner.owner; | ||
| } while (owner.owner); | ||
| return null; | ||
| } | ||
| function setDebuggerContext(owner, ctx) { | ||
| owner.sdtContext = ctx; | ||
| } | ||
| function getDebuggerContext(owner) { | ||
| while (!owner.sdtContext && owner.owner) | ||
| owner = owner.owner; | ||
| return owner.sdtContext; | ||
| } | ||
| function removeDebuggerContext(owner) { | ||
| delete owner.sdtContext; | ||
| } | ||
| function onOwnerCleanup(owner, fn, prepend = false) { | ||
| if (owner.cleanups === null) | ||
| owner.cleanups = [fn]; | ||
| else if (prepend) | ||
| owner.cleanups.splice(0, 0, fn); | ||
| else | ||
| owner.cleanups.push(fn); | ||
| return () => { | ||
| var _a; | ||
| return (_a = owner.cleanups) == null ? void 0 : _a.splice(owner.cleanups.indexOf(fn), 1); | ||
| }; | ||
| } | ||
| function onParentCleanup(owner, fn, prepend = false) { | ||
| if (owner.owner) | ||
| return onOwnerCleanup(owner.owner, fn, prepend); | ||
| return noop; | ||
| } | ||
| var DISPOSE_ID = Symbol("Dispose ID"); | ||
| function createUnownedRoot(fn) { | ||
| return runWithOwner(null, () => createRoot(fn)); | ||
| } | ||
| function getFunctionSources(fn) { | ||
| let nodes; | ||
| let init = true; | ||
| runWithOwner( | ||
| null, | ||
| () => createRoot( | ||
| (dispose) => createComputed(() => { | ||
| if (!init) | ||
| return; | ||
| init = false; | ||
| fn(); | ||
| const sources = getOwner().sources; | ||
| if (sources) | ||
| nodes = [...sources]; | ||
| dispose(); | ||
| }) | ||
| ) | ||
| ); | ||
| return nodes ?? []; | ||
| } | ||
| var LAST_ID = 0; | ||
| var getNewSdtId = () => (LAST_ID++).toString(16); | ||
| function markOwnerName(o) { | ||
| if (o.sdtName !== void 0) | ||
| return o.sdtName; | ||
| return o.sdtName = getNodeName(o); | ||
| } | ||
| function markOwnerType(o, type) { | ||
| if (o.sdtType !== void 0) | ||
| return o.sdtType; | ||
| return o.sdtType = type ?? getOwnerType(o); | ||
| } | ||
| function markNodeID(o) { | ||
| if (o.sdtId !== void 0) | ||
| return o.sdtId; | ||
| return o.sdtId = getNewSdtId(); | ||
| } | ||
| function markNodesID(nodes) { | ||
| if (!nodes || !nodes.length) | ||
| return []; | ||
| return nodes.map(markNodeID); | ||
| } | ||
| var SkipInternalRoot = null; | ||
| var createInternalRoot = (fn, detachedOwner) => { | ||
| SkipInternalRoot = fn; | ||
| const v = createRoot((dispose) => { | ||
| const owner = getOwner(); | ||
| setDebuggerContext(owner, INTERNAL); | ||
| return fn(dispose); | ||
| }, detachedOwner); | ||
| if (SkipInternalRoot === fn) | ||
| SkipInternalRoot = null; | ||
| return v; | ||
| }; | ||
| var skipInternalRoot = () => { | ||
| const skip = !!SkipInternalRoot; | ||
| if (skip) | ||
| SkipInternalRoot = null; | ||
| return skip; | ||
| }; | ||
| function createBatchedUpdateEmitter() { | ||
| const [handleUpdates, emitUpdates] = createSimpleEmitter(); | ||
| const updates = []; | ||
| const triggerUpdateEmit = throttle(() => { | ||
| const ids = /* @__PURE__ */ new Set(); | ||
| const deduped = []; | ||
| for (let i = updates.length - 1; i >= 0; i--) { | ||
| const update = updates[i]; | ||
| if (ids.has(update.id)) | ||
| continue; | ||
| ids.add(update.id); | ||
| deduped.push(update); | ||
| } | ||
| updates.length = 0; | ||
| emitUpdates(deduped); | ||
| }); | ||
| const pushUpdate = (update) => { | ||
| updates.push(update); | ||
| triggerUpdateEmit(); | ||
| }; | ||
| return [handleUpdates, pushUpdate]; | ||
| } | ||
| // src/update.ts | ||
| import { untrack } from "solid-js"; | ||
| import { noop as noop2, onRootCleanup } from "@solid-primitives/utils"; | ||
| import { Observable } from "object-observer"; | ||
| import { WINDOW_WRAP_STORE_PROPERTY } from "@solid-devtools/shared/variables"; | ||
| var GraphUpdateListeners = /* @__PURE__ */ new Set(); | ||
| { | ||
| const runListeners = () => GraphUpdateListeners.forEach((f) => f()); | ||
| if (typeof window._$afterUpdate === "function") { | ||
| GraphUpdateListeners.add(window._$afterUpdate); | ||
| } | ||
| window._$afterUpdate = runListeners; | ||
| } | ||
| function makeSolidUpdateListener(onUpdate2) { | ||
| GraphUpdateListeners.add(onUpdate2); | ||
| return onRootCleanup(() => { | ||
| GraphUpdateListeners.delete(onUpdate2); | ||
| }); | ||
| } | ||
| var CreateRootListeners = /* @__PURE__ */ new Set(); | ||
| { | ||
| const runListeners = (root) => { | ||
| if (skipInternalRoot()) | ||
| return; | ||
| CreateRootListeners.forEach((f) => f(root)); | ||
| }; | ||
| if (typeof window._$afterCreateRoot === "function") { | ||
| CreateRootListeners.add(window._$afterCreateRoot); | ||
| } | ||
| window._$afterCreateRoot = runListeners; | ||
| } | ||
| function makeCreateRootListener(onUpdate2) { | ||
| CreateRootListeners.add(onUpdate2); | ||
| return onRootCleanup(() => CreateRootListeners.delete(onUpdate2)); | ||
| } | ||
| window[WINDOW_WRAP_STORE_PROPERTY] = (init) => { | ||
| return Observable.from(init); | ||
| }; | ||
| function makeStoreObserver(state, onUpdate2) { | ||
| if (!Observable.isObservable(state)) { | ||
| console.warn(`Object ${state} is not wrapped`); | ||
| return noop2; | ||
| } | ||
| Observable.observe(state, onUpdate2); | ||
| return onRootCleanup(() => Observable.unobserve(state, onUpdate2)); | ||
| } | ||
| function observeComputationUpdate(owner, onRun) { | ||
| if (owner.onComputationUpdate) | ||
| return void (owner.onComputationUpdate = onRun); | ||
| owner.onComputationUpdate = onRun; | ||
| interceptComputationRerun(owner, (fn) => { | ||
| untrack(owner.onComputationUpdate); | ||
| fn(); | ||
| }); | ||
| } | ||
| function interceptComputationRerun(owner, onRun) { | ||
| const _fn = owner.fn; | ||
| let v; | ||
| let prev; | ||
| const fn = () => v = _fn(prev); | ||
| owner.fn = !!owner.fn.length ? (p) => { | ||
| onRun(fn, prev = p); | ||
| return v; | ||
| } : () => { | ||
| onRun(fn, void 0); | ||
| return v; | ||
| }; | ||
| } | ||
| function observeValueUpdate(node, onUpdate2, symbol) { | ||
| if (node.onValueUpdate) { | ||
| node.onValueUpdate[symbol] = onUpdate2; | ||
| return; | ||
| } | ||
| const map = node.onValueUpdate = { [symbol]: onUpdate2 }; | ||
| let value = node.value; | ||
| Object.defineProperty(node, "value", { | ||
| get: () => value, | ||
| set: (newValue) => { | ||
| for (let sym of Object.getOwnPropertySymbols(map)) | ||
| map[sym](newValue, value); | ||
| value = newValue; | ||
| } | ||
| }); | ||
| } | ||
| function removeValueUpdateObserver(node, symbol) { | ||
| if (node.onValueUpdate) | ||
| delete node.onValueUpdate[symbol]; | ||
| } | ||
| function makeValueUpdateListener(node, onUpdate2, symbol) { | ||
| observeValueUpdate(node, onUpdate2, symbol); | ||
| onRootCleanup(() => removeValueUpdateObserver(node, symbol)); | ||
| } | ||
| // src/walker.ts | ||
| var SelectedId; | ||
| var RootId; | ||
| var OnSignalUpdate; | ||
| var OnComputationUpdate; | ||
| var GatherComponents; | ||
| var Components = []; | ||
| var SelectedOwner; | ||
| var SelectedDetails; | ||
| var SelectedSignalMap; | ||
| var ElementMap; | ||
| var WALKER = Symbol("walker"); | ||
| function observeComputation(owner, id) { | ||
| if (isSolidComputation(owner)) | ||
| observeComputationUpdate(owner, OnComputationUpdate.bind(void 0, RootId, id)); | ||
| } | ||
| function observeValue(node) { | ||
| const id = markNodeID(node); | ||
| const handler = OnSignalUpdate; | ||
| observeValueUpdate(node, (value) => handler(id, value), WALKER); | ||
| } | ||
| function mapSignalNode(node) { | ||
| const id = markNodeID(node); | ||
| SelectedSignalMap[id] = node; | ||
| observeValue(node); | ||
| return { | ||
| type: getNodeType(node), | ||
| name: getNodeName(node), | ||
| id, | ||
| observers: markNodesID(node.observers), | ||
| value: encodeValue(node.value, false, ElementMap) | ||
| }; | ||
| } | ||
| function clearOwnerObservers(owner) { | ||
| if (owner.sourceMap) | ||
| Object.values(owner.sourceMap).forEach((node) => removeValueUpdateObserver(node, WALKER)); | ||
| if (owner.owned) | ||
| owner.owned.forEach((node) => removeValueUpdateObserver(node, WALKER)); | ||
| } | ||
| function collectOwnerDetails(owner) { | ||
| var _a; | ||
| const path = []; | ||
| let current = owner.owner; | ||
| while (current) { | ||
| path.unshift(markNodeID(current)); | ||
| current = current.owner; | ||
| } | ||
| const signals = owner.sourceMap ? Object.values(owner.sourceMap).map(mapSignalNode) : []; | ||
| (_a = owner.owned) == null ? void 0 : _a.forEach((child) => { | ||
| if (!isSolidMemo(child)) | ||
| return; | ||
| signals.push(mapSignalNode(child)); | ||
| }); | ||
| const details = { | ||
| id: owner.sdtId, | ||
| name: owner.sdtName, | ||
| type: owner.sdtType, | ||
| path, | ||
| signals | ||
| }; | ||
| if (isSolidComputation(owner)) { | ||
| details.value = encodeValue(owner.value, false, ElementMap); | ||
| details.sources = markNodesID(owner.sources); | ||
| if (isSolidMemo(owner)) { | ||
| details.observers = markNodesID(owner.observers); | ||
| } | ||
| } | ||
| SelectedOwner = owner; | ||
| SelectedDetails = details; | ||
| } | ||
| function mapChildren({ owned, ownedRoots }) { | ||
| const children = []; | ||
| if (owned) | ||
| children.push.apply( | ||
| children, | ||
| owned.map((child) => mapOwner(child)) | ||
| ); | ||
| if (ownedRoots) | ||
| children.push.apply( | ||
| children, | ||
| [...ownedRoots].map((child) => mapOwner(child, NodeType2.Root)) | ||
| ); | ||
| return children; | ||
| } | ||
| function mapOwner(owner, type) { | ||
| type = markOwnerType(owner, type); | ||
| const id = markNodeID(owner); | ||
| const name = markOwnerName(owner); | ||
| if (id === SelectedId) | ||
| collectOwnerDetails(owner); | ||
| observeComputation(owner, id); | ||
| if (GatherComponents && type === NodeType2.Component) { | ||
| const element = resolveElements(owner.value); | ||
| if (element) | ||
| Components.push({ id, name, element }); | ||
| } | ||
| return { | ||
| id, | ||
| name, | ||
| type, | ||
| children: mapChildren(owner), | ||
| sources: owner.sources ? owner.sources.length : 0 | ||
| }; | ||
| } | ||
| function walkSolidTree(owner, config) { | ||
| SelectedId = config.selectedId; | ||
| RootId = config.rootId; | ||
| OnSignalUpdate = config.onSignalUpdate; | ||
| OnComputationUpdate = config.onComputationUpdate; | ||
| GatherComponents = config.gatherComponents; | ||
| SelectedOwner = null; | ||
| SelectedDetails = null; | ||
| SelectedSignalMap = {}; | ||
| Components = []; | ||
| ElementMap = config.elementMap ?? {}; | ||
| const tree = mapOwner(owner); | ||
| const components = Components; | ||
| const focusedOwner = SelectedOwner; | ||
| const focusedOwnerDetails = SelectedDetails; | ||
| const focusedOwnerSignalMap = SelectedSignalMap; | ||
| const elementMap = ElementMap; | ||
| return { | ||
| tree, | ||
| components, | ||
| selected: { | ||
| details: focusedOwnerDetails, | ||
| owner: focusedOwner, | ||
| signalMap: focusedOwnerSignalMap, | ||
| elementMap | ||
| } | ||
| }; | ||
| } | ||
| // src/plugin.ts | ||
| import { batch, createSignal as createSignal2, getOwner as getOwner2, runWithOwner as runWithOwner2, untrack as untrack2 } from "solid-js"; | ||
| import { createSimpleEmitter as createSimpleEmitter2 } from "@solid-primitives/event-bus"; | ||
| import { omit } from "@solid-primitives/immutable"; | ||
| import { createLazyMemo } from "@solid-primitives/memo"; | ||
| import { createStaticStore } from "@solid-primitives/utils"; | ||
| import { encodeValue as encodeValue2 } from "@solid-devtools/shared/serialize"; | ||
| import { createConsumers, untrackedCallback } from "@solid-devtools/shared/primitives"; | ||
| var getNullFocusedState = () => ({ | ||
| id: null, | ||
| rootId: null, | ||
| owner: null, | ||
| details: null, | ||
| signalMap: {}, | ||
| elementMap: {} | ||
| }); | ||
| var exported = createInternalRoot(() => { | ||
| const [onUpdate2, triggerUpdate] = createSimpleEmitter2(); | ||
| const [onForceUpdate2, forceTriggerUpdate] = createSimpleEmitter2(); | ||
| const [enabled2, addDebuggerConsumer] = createConsumers(); | ||
| const [gatherComponents2, addGatherComponentsConsumer] = createConsumers(); | ||
| const [observeComputations, addObserveComputationsConsumer] = createConsumers(); | ||
| const [roots, setRoots] = createSignal2({}); | ||
| const serialisedRoots = createLazyMemo(() => { | ||
| const serialisedRoots2 = {}; | ||
| for (const [id, root] of Object.entries(roots())) { | ||
| serialisedRoots2[id] = root.tree(); | ||
| } | ||
| return serialisedRoots2; | ||
| }); | ||
| const updatedIds = /* @__PURE__ */ new Set(); | ||
| const removedIds = /* @__PURE__ */ new Set(); | ||
| const rootsUpdates = createLazyMemo(() => { | ||
| const _updatedIds = [...updatedIds].filter((id) => !removedIds.has(id)); | ||
| const sRoots = serialisedRoots(); | ||
| const updated = _updatedIds.map((id) => ({ id, tree: sRoots[id] })); | ||
| const removed = [...removedIds]; | ||
| updatedIds.clear(); | ||
| removedIds.clear(); | ||
| return { updated, removed }; | ||
| }); | ||
| function removeRoot2(rootId) { | ||
| removedIds.add(rootId); | ||
| setRoots((map) => omit(map, rootId)); | ||
| } | ||
| function updateRoot2(newRoot) { | ||
| const rootMap = untrack2(roots); | ||
| const rootId = newRoot.id; | ||
| const root = rootMap[rootId]; | ||
| updatedIds.add(rootId); | ||
| if (root) { | ||
| batch(() => { | ||
| root.setTree(newRoot.tree); | ||
| root.setComponents(newRoot.components); | ||
| }); | ||
| } else { | ||
| const [tree, setTree] = createSignal2(newRoot.tree); | ||
| const [components2, setComponents] = createSignal2(newRoot.components); | ||
| setRoots((map) => ({ | ||
| ...map, | ||
| [rootId]: { id: rootId, tree, setTree, components: components2, setComponents } | ||
| })); | ||
| } | ||
| } | ||
| const [focusedState2, setFocusedState] = createStaticStore(getNullFocusedState()); | ||
| const setFocusedOwner = untrackedCallback((payload) => { | ||
| if (!payload) | ||
| return setFocusedState(getNullFocusedState()); | ||
| const { rootId, nodeId } = payload; | ||
| if (focusedState2.id === nodeId) | ||
| return; | ||
| setFocusedState({ ...getNullFocusedState(), id: nodeId, rootId }); | ||
| forceRootUpdate(rootId); | ||
| }); | ||
| const setSelectedDetails2 = (payload) => { | ||
| setFocusedState(payload.details ? payload : getNullFocusedState()); | ||
| }; | ||
| const selectedSignalIds = /* @__PURE__ */ new Set(); | ||
| const setSelectedSignal = untrackedCallback( | ||
| ({ id, selected }) => { | ||
| const { signalMap, elementMap } = focusedState2; | ||
| const signal = signalMap[id]; | ||
| if (!signal) | ||
| return null; | ||
| if (selected) | ||
| selectedSignalIds.add(id); | ||
| else | ||
| selectedSignalIds.delete(id); | ||
| return encodeValue2(signal.value, selected, elementMap); | ||
| } | ||
| ); | ||
| const [handleSignalUpdates, _pushSignalUpdate] = createBatchedUpdateEmitter(); | ||
| const pushSignalUpdate2 = untrackedCallback((id, value) => { | ||
| if (!enabled2() || !focusedState2.id) | ||
| return; | ||
| const isSelected = selectedSignalIds.has(id); | ||
| _pushSignalUpdate({ id, value: encodeValue2(value, isSelected, focusedState2.elementMap) }); | ||
| }); | ||
| const [handleComputationUpdates, _pushComputationUpdate] = createBatchedUpdateEmitter(); | ||
| const pushComputationUpdate2 = (rootId, id) => { | ||
| if (!untrack2(enabled2) || !untrack2(observeComputations)) | ||
| return; | ||
| _pushComputationUpdate({ rootId, id }); | ||
| }; | ||
| const components = createLazyMemo( | ||
| () => Object.entries(roots()).reduce((obj, [rootId, root]) => { | ||
| obj[rootId] = root.components(); | ||
| return obj; | ||
| }, {}) | ||
| ); | ||
| const pluginData = { | ||
| handleComputationUpdates, | ||
| handleSignalUpdates, | ||
| roots, | ||
| serialisedRoots, | ||
| rootsUpdates, | ||
| components, | ||
| triggerUpdate, | ||
| forceTriggerUpdate, | ||
| setFocusedOwner, | ||
| focusedState: focusedState2, | ||
| setSelectedSignal | ||
| }; | ||
| const owner = getOwner2(); | ||
| function registerDebuggerPlugin2(factory) { | ||
| runWithOwner2(owner, () => { | ||
| const { enabled: enabled3, gatherComponents: gatherComponents3, observeComputations: observeComputations2 } = factory(pluginData); | ||
| enabled3 && addDebuggerConsumer(enabled3); | ||
| gatherComponents3 && addGatherComponentsConsumer(gatherComponents3); | ||
| observeComputations2 && addObserveComputationsConsumer(observeComputations2); | ||
| }); | ||
| } | ||
| return { | ||
| onUpdate: onUpdate2, | ||
| onForceUpdate: onForceUpdate2, | ||
| enabled: enabled2, | ||
| registerDebuggerPlugin: registerDebuggerPlugin2, | ||
| updateRoot: updateRoot2, | ||
| removeRoot: removeRoot2, | ||
| gatherComponents: gatherComponents2, | ||
| pushSignalUpdate: pushSignalUpdate2, | ||
| setSelectedDetails: setSelectedDetails2, | ||
| focusedState: focusedState2, | ||
| pushComputationUpdate: pushComputationUpdate2 | ||
| }; | ||
| }); | ||
| var { | ||
| onUpdate, | ||
| onForceUpdate, | ||
| enabled, | ||
| gatherComponents, | ||
| registerDebuggerPlugin, | ||
| updateRoot, | ||
| removeRoot, | ||
| pushSignalUpdate, | ||
| setSelectedDetails, | ||
| focusedState, | ||
| pushComputationUpdate | ||
| } = exported; | ||
| // src/roots.ts | ||
| import { untrackedCallback as untrackedCallback2 } from "@solid-devtools/shared/primitives"; | ||
| var RootMap = {}; | ||
| var forceRootUpdate = (rootId) => RootMap[rootId].forceUpdate(); | ||
| function createGraphRoot(owner) { | ||
| createInternalRoot((dispose) => { | ||
| onOwnerCleanup(owner, dispose); | ||
| const rootId = getNewSdtId(); | ||
| const onComputationUpdate = (rootId2, nodeId) => { | ||
| if (owner.isDisposed) | ||
| return; | ||
| if (untrack3(enabled)) | ||
| triggerRootUpdate(); | ||
| pushComputationUpdate(rootId2, nodeId); | ||
| }; | ||
| const onSignalUpdate = (nodeId, value) => { | ||
| if (owner.isDisposed) | ||
| return; | ||
| pushSignalUpdate(nodeId, value); | ||
| }; | ||
| let lastSelectedOwner = null; | ||
| const forceRootUpdate2 = untrackedCallback2(() => { | ||
| if (owner.isDisposed) | ||
| return; | ||
| lastSelectedOwner && clearOwnerObservers(lastSelectedOwner); | ||
| const { tree, components, selected } = walkSolidTree(owner, { | ||
| onComputationUpdate, | ||
| onSignalUpdate, | ||
| rootId, | ||
| selectedId: focusedState.id, | ||
| gatherComponents: gatherComponents(), | ||
| elementMap: focusedState.elementMap | ||
| }); | ||
| lastSelectedOwner = selected.owner; | ||
| if (focusedState.rootId === rootId) | ||
| setSelectedDetails(selected); | ||
| updateRoot({ id: rootId, tree, components }); | ||
| }); | ||
| const triggerRootUpdate = throttle2(forceRootUpdate2, 350); | ||
| RootMap[rootId] = { | ||
| update: triggerRootUpdate, | ||
| forceUpdate: forceRootUpdate2 | ||
| }; | ||
| onUpdate(triggerRootUpdate); | ||
| onForceUpdate(forceRootUpdate2); | ||
| createEffect(() => { | ||
| if (enabled()) | ||
| forceRootUpdate2(); | ||
| else | ||
| lastSelectedOwner && clearOwnerObservers(lastSelectedOwner); | ||
| }); | ||
| setDebuggerContext(owner, { rootId, triggerRootUpdate, forceRootUpdate: forceRootUpdate2 }); | ||
| onCleanup(() => { | ||
| removeDebuggerContext(owner); | ||
| removeRoot(rootId); | ||
| owner.isDisposed = true; | ||
| lastSelectedOwner && clearOwnerObservers(lastSelectedOwner); | ||
| delete RootMap[rootId]; | ||
| }); | ||
| }); | ||
| } | ||
| function attachDebugger(_owner = getOwner3()) { | ||
| let owner = _owner; | ||
| if (!owner) | ||
| return console.warn( | ||
| "reatachOwner helper should be used synchronously inside createRoot callback body." | ||
| ); | ||
| forEachLookupRoot(owner, (root, ctx) => { | ||
| root.sdtAttached = true; | ||
| markOwnerType(root, NodeType3.Root); | ||
| if (ctx === INTERNAL2) | ||
| return; | ||
| if (ctx) { | ||
| ctx.triggerRootUpdate(); | ||
| let parent = findClosestAliveParent(root); | ||
| if (!parent.owner) | ||
| return console.warn("PARENT_SHOULD_BE_ALIVE"); | ||
| let removeFromOwned = addRootToOwnedRoots(parent.owner, root); | ||
| const onParentCleanup2 = () => { | ||
| const newParent = findClosestAliveParent(root); | ||
| if (newParent.owner) { | ||
| parent = newParent; | ||
| removeFromOwned(); | ||
| removeFromOwned = addRootToOwnedRoots(parent.owner, root); | ||
| onOwnerCleanup(parent.root, onParentCleanup2); | ||
| } else { | ||
| removeFromOwned(); | ||
| removeOwnCleanup(); | ||
| createGraphRoot(root); | ||
| } | ||
| }; | ||
| const removeParentCleanup = onOwnerCleanup(parent.root, onParentCleanup2); | ||
| const removeOwnCleanup = onOwnerCleanup(root, () => { | ||
| root.isDisposed = true; | ||
| removeFromOwned(); | ||
| removeParentCleanup(); | ||
| ctx.triggerRootUpdate(); | ||
| }); | ||
| } else | ||
| createGraphRoot(root); | ||
| }); | ||
| } | ||
| function addRootToOwnedRoots(parent, root) { | ||
| const ownedRoots = parent.ownedRoots ?? (parent.ownedRoots = /* @__PURE__ */ new Set()); | ||
| ownedRoots.add(root); | ||
| return () => void ownedRoots.delete(root); | ||
| } | ||
| function findClosestAliveParent(owner) { | ||
| let disposed = null; | ||
| let closestAliveRoot = null; | ||
| let current = owner; | ||
| while (current.owner && !closestAliveRoot) { | ||
| current = current.owner; | ||
| if (isSolidRoot(current)) { | ||
| if (current.isDisposed) | ||
| disposed = current; | ||
| else | ||
| closestAliveRoot = current; | ||
| } | ||
| } | ||
| if (!closestAliveRoot) | ||
| return { owner: null, root: null }; | ||
| return { owner: (disposed == null ? void 0 : disposed.owner) ?? owner.owner, root: closestAliveRoot }; | ||
| } | ||
| function forEachLookupRoot(owner, callback) { | ||
| const roots = []; | ||
| let ctx; | ||
| do { | ||
| if (isSolidRoot(owner)) { | ||
| if (owner.sdtAttached) { | ||
| if (!ctx) | ||
| ctx = getDebuggerContext(owner); | ||
| break; | ||
| } | ||
| if (owner.sdtContext === INTERNAL2) { | ||
| ctx = INTERNAL2; | ||
| break; | ||
| } | ||
| roots.push(owner); | ||
| } | ||
| owner = owner.owner; | ||
| } while (owner); | ||
| for (let i = roots.length - 1; i >= 0; i--) { | ||
| const root = roots[i]; | ||
| callback(root, ctx); | ||
| if (root.sdtContext) | ||
| ctx = root.sdtContext; | ||
| } | ||
| } | ||
| // src/index.ts | ||
| var Debugger = (props) => { | ||
| attachDebugger(); | ||
| return props.children; | ||
| }; | ||
| export { | ||
| isSolidComputation, | ||
| isSolidMemo, | ||
| isSolidOwner, | ||
| isSolidRoot, | ||
| getNodeName, | ||
| getNodeType, | ||
| getOwnerType, | ||
| lookupOwner, | ||
| onOwnerCleanup, | ||
| onParentCleanup, | ||
| createUnownedRoot, | ||
| getFunctionSources, | ||
| createInternalRoot, | ||
| makeSolidUpdateListener, | ||
| makeCreateRootListener, | ||
| makeStoreObserver, | ||
| observeComputationUpdate, | ||
| interceptComputationRerun, | ||
| observeValueUpdate, | ||
| removeValueUpdateObserver, | ||
| makeValueUpdateListener, | ||
| registerDebuggerPlugin, | ||
| attachDebugger, | ||
| Debugger | ||
| }; |
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
73682
4.45%2001
4.33%1
Infinity%1
Infinity%