{
  "version": 3,
  "sources": ["../../../src/lib/core/capture.ts"],
  "sourcesContent": ["import { attach, detach, singleton } from './helpers'\nimport type { Child, Signal } from './types'\n\nclass CaptureStackFrame {\n\toffset = 0\n\tnumNewParents = 0\n\n\tmaybeRemoved?: Signal<any>[]\n\n\tconstructor(public readonly below: CaptureStackFrame | null, public readonly child: Child) {}\n}\n\nconst inst = singleton('capture', () => ({ stack: null as null | CaptureStackFrame }))\n\n/**\n * Executes the given function without capturing any parents in the current capture context.\n *\n * This is mainly useful if you want to run an effect only when certain signals change while also\n * dereferencing other signals which should not cause the effect to rerun on their own.\n *\n * @example\n * ```ts\n * const name = atom('name', 'Sam')\n * const time = atom('time', () => new Date().getTime())\n *\n * setInterval(() => {\n *   time.set(new Date().getTime())\n * })\n *\n * react('log name changes', () => {\n * \t print(name.get(), 'was changed at', unsafe__withoutCapture(() => time.get()))\n * })\n *\n * ```\n *\n * @public\n */\nexport function unsafe__withoutCapture<T>(fn: () => T): T {\n\tconst oldStack = inst.stack\n\tinst.stack = null\n\ttry {\n\t\treturn fn()\n\t} finally {\n\t\tinst.stack = oldStack\n\t}\n}\n\nexport function startCapturingParents(child: Child) {\n\tinst.stack = new CaptureStackFrame(inst.stack, child)\n}\n\nexport function stopCapturingParents() {\n\tconst frame = inst.stack!\n\tinst.stack = frame.below\n\n\tconst didParentsChange = frame.numNewParents > 0 || frame.offset !== frame.child.parents.length\n\n\tif (!didParentsChange) {\n\t\treturn\n\t}\n\n\tfor (let i = frame.offset; i < frame.child.parents.length; i++) {\n\t\tconst p = frame.child.parents[i]\n\t\tconst parentWasRemoved = frame.child.parents.indexOf(p) >= frame.offset\n\t\tif (parentWasRemoved) {\n\t\t\tdetach(p, frame.child)\n\t\t}\n\t}\n\n\tframe.child.parents.length = frame.offset\n\tframe.child.parentEpochs.length = frame.offset\n\n\tif (inst.stack?.maybeRemoved) {\n\t\tfor (let i = 0; i < inst.stack.maybeRemoved.length; i++) {\n\t\t\tconst maybeRemovedParent = inst.stack.maybeRemoved[i]\n\t\t\tif (frame.child.parents.indexOf(maybeRemovedParent) === -1) {\n\t\t\t\tdetach(maybeRemovedParent, frame.child)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// this must be called after the parent is up to date\nexport function maybeCaptureParent(p: Signal<any, any>) {\n\tif (inst.stack) {\n\t\tconst idx = inst.stack.child.parents.indexOf(p)\n\t\t// if the child didn't deref this parent last time it executed, then idx will be -1\n\t\t// if the child did deref this parent last time but in a different order relative to other parents, then idx will be greater than stack.offset\n\t\t// if the child did deref this parent last time in the same order, then idx will be the same as stack.offset\n\t\t// if the child did deref this parent already during this capture session then 0 <= idx < stack.offset\n\n\t\tif (idx < 0) {\n\t\t\tinst.stack.numNewParents++\n\t\t\tif (inst.stack.child.isActivelyListening) {\n\t\t\t\tattach(p, inst.stack.child)\n\t\t\t}\n\t\t}\n\n\t\tif (idx < 0 || idx >= inst.stack.offset) {\n\t\t\tif (idx !== inst.stack.offset && idx > 0) {\n\t\t\t\tconst maybeRemovedParent = inst.stack.child.parents[inst.stack.offset]\n\n\t\t\t\tif (!inst.stack.maybeRemoved) {\n\t\t\t\t\tinst.stack.maybeRemoved = [maybeRemovedParent]\n\t\t\t\t} else if (inst.stack.maybeRemoved.indexOf(maybeRemovedParent) === -1) {\n\t\t\t\t\tinst.stack.maybeRemoved.push(maybeRemovedParent)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinst.stack.child.parents[inst.stack.offset] = p\n\t\t\tinst.stack.child.parentEpochs[inst.stack.offset] = p.lastChangedEpoch\n\t\t\tinst.stack.offset++\n\t\t}\n\t}\n}\n\n/**\n * A debugging tool that tells you why a computed signal or effect is running.\n * Call in the body of a computed signal or effect function.\n *\n * @example\n * ```ts\n * const name = atom('name', 'Bob')\n * react('greeting', () => {\n * \twhyAmIRunning()\n *\tprint('Hello', name.get())\n * })\n *\n * name.set('Alice')\n *\n * // 'greeting' is running because:\n * //     'name' changed => 'Alice'\n * ```\n *\n * @public\n */\nexport function whyAmIRunning() {\n\tconst child = inst.stack?.child\n\tif (!child) {\n\t\tthrow new Error('whyAmIRunning() called outside of a reactive context')\n\t}\n\n\tconst changedParents = []\n\tfor (let i = 0; i < child.parents.length; i++) {\n\t\tconst parent = child.parents[i]\n\n\t\tif (parent.lastChangedEpoch > child.parentEpochs[i]) {\n\t\t\tchangedParents.push(parent)\n\t\t}\n\t}\n\n\tif (changedParents.length === 0) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log((child as any).name, 'is running but none of the parents changed')\n\t} else {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log((child as any).name, 'is running because:')\n\t\tfor (const changedParent of changedParents) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.log(\n\t\t\t\t'\\t',\n\t\t\t\t(changedParent as any).name,\n\t\t\t\t'changed =>',\n\t\t\t\tchangedParent.__unsafe__getWithoutCapture()\n\t\t\t)\n\t\t}\n\t}\n}\n"],
  "mappings": "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",
  "names": []
}
