{
  "version": 3,
  "sources": ["../../src/capture.ts"],
  "sourcesContent": ["import { attach, detach } from './helpers.js'\nimport { Child, Signal } from './types.js'\n\nconst signiaKey = Symbol.for('__signia__')\nconst global = globalThis as { [signiaKey]?: true }\n\nif (global[signiaKey]) {\n\tconsole.error(\n\t\t'Multiple versions of signia detected. This will cause unexpected behavior. Please add \"resolutions\" (yarn/pnpm) or \"overrides\" (npm) in your package.json to ensure only one version of signia is loaded.'\n\t)\n} else {\n\tglobal[signiaKey] = true\n}\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\nlet stack: CaptureStackFrame | null = null\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 console.log(name.value, 'was changed at', unsafe__withoutCapture(() => time.value))\n * })\n *\n * ```\n *\n * @public\n */\nexport function unsafe__withoutCapture<T>(fn: () => T): T {\n\tconst oldStack = stack\n\tstack = null\n\ttry {\n\t\treturn fn()\n\t} finally {\n\t\tstack = oldStack\n\t}\n}\n\nexport function startCapturingParents(child: Child) {\n\tstack = new CaptureStackFrame(stack, child)\n}\n\nexport function stopCapturingParents() {\n\tconst frame = stack!\n\tstack = 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 (stack?.maybeRemoved) {\n\t\tfor (let i = 0; i < stack.maybeRemoved.length; i++) {\n\t\t\tconst maybeRemovedParent = 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 (stack) {\n\t\tconst idx = 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\tstack.numNewParents++\n\t\t\tif (stack.child.isActivelyListening) {\n\t\t\t\tattach(p, stack.child)\n\t\t\t}\n\t\t}\n\n\t\tif (idx < 0 || idx >= stack.offset) {\n\t\t\tif (idx !== stack.offset && idx > 0) {\n\t\t\t\tconst maybeRemovedParent = stack.child.parents[stack.offset]\n\n\t\t\t\tif (!stack.maybeRemoved) {\n\t\t\t\t\tstack.maybeRemoved = [maybeRemovedParent]\n\t\t\t\t} else if (stack.maybeRemoved.indexOf(maybeRemovedParent) === -1) {\n\t\t\t\t\tstack.maybeRemoved.push(maybeRemovedParent)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstack.child.parents[stack.offset] = p\n\t\t\tstack.child.parentEpochs[stack.offset] = p.lastChangedEpoch\n\t\t\tstack.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 *\tconsole.log('Hello', name.value)\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 = 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": []
}
