{"_id":"@aihu/signals","_rev":"8-32660ffbc967da5c1b62281502848b54","name":"@aihu/signals","dist-tags":{"canary":"0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113","latest":"0.5.1"},"versions":{"0.1.0":{"name":"@aihu/signals","version":"0.1.0","license":"MIT","_id":"@aihu/signals@0.1.0","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"cb4cec3beb0df71f87050078acd3a7912a6bc2d0","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.1.0.tgz","fileCount":7,"integrity":"sha512-Ic50LRIGOomElIFnoqnJVVyxjJeB2GcuOt6VdPMYAuZccG1nQk7ds7RTXm+RIXMNs3hvdGNuFBcNFFjdOdW4Qw==","signatures":[{"sig":"MEQCIEKYZfHAfh2lOcmQcltNl6Y0WQh7eT5SXL7rokHx7UdMAiBJSQgiPKL1O2KojtE9qq++cS+nFYsDyoJNhyD4auwyig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60594},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"02c309492183f2abf030a21a847ac41b1e9ffb00","scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.9.0","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/signals_0.1.0_1778009809390_0.6513998392426095","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aihu/signals","version":"0.1.1","license":"MIT","_id":"@aihu/signals@0.1.1","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":"https://github.com/fellwork/aihu/issues","dist":{"shasum":"df543874416b2a6fcde2969413aba3a773ca0299","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.1.1.tgz","fileCount":7,"integrity":"sha512-57CiX+f1tVIHiNzIJbjzng89VDxXr3Xkr9JBpWYOXQd03vFsecOFbnXzph6x4DVz/BZML5NNKNEGxpMh5jC01g==","signatures":[{"sig":"MEYCIQD6RLn3ffIPyrDejXkdvMfRkRevYI/oaw82p2kznD+sVAIhAI9v3LUJX6AzVO9zwBgxby9HE/a8USzPW5Id/sIsNkqH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63156},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"df543874416b2a6fcde2969413aba3a773ca0299","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_integrity":"sha512-57CiX+f1tVIHiNzIJbjzng89VDxXr3Xkr9JBpWYOXQd03vFsecOFbnXzph6x4DVz/BZML5NNKNEGxpMh5jC01g==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.8.3","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/signals_0.1.1_1778018652633_0.987557389123952","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aihu/signals","version":"0.2.0","license":"MIT","_id":"@aihu/signals@0.2.0","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"70afaca4c7f1c976cdf4850da50c6fb59069e09b","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.2.0.tgz","fileCount":7,"integrity":"sha512-NK8/8qcRdtN1vumJ0elPKcVSvUaKzQ70dKjnLsYG0eLL6z/1TnKSYyGSffSlVw+O95nNMWut7LRCOwEDcK1ilQ==","signatures":[{"sig":"MEQCIC1ff+KhbsG5SHCAyzs5R8MTHzYzlBI9ZfRiMXOWaET9AiB70SiYB8Y3jFRJyjUUZf3D62jGrfbUT0aUyu0pTlMRsQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fsignals@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":68116},"main":"./dist/index.js","type":"module","_from":"file:/tmp/tmp.6i1Grk3iEn/aihu-signals-0.2.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_resolved":"/tmp/tmp.6i1Grk3iEn/aihu-signals-0.2.0.tgz","_integrity":"sha512-NK8/8qcRdtN1vumJ0elPKcVSvUaKzQ70dKjnLsYG0eLL6z/1TnKSYyGSffSlVw+O95nNMWut7LRCOwEDcK1ilQ==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.8.2","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/signals_0.2.0_1780691002752_0.24266153001912505","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aihu/signals","version":"0.3.0","license":"MIT","_id":"@aihu/signals@0.3.0","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"f9bbd70e8e27d9e25537f6615dc3b88e03da27df","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.3.0.tgz","fileCount":7,"integrity":"sha512-JPm86ONQlnJG24jGxexbtGEcbYUwQ69t9Oma+ByN+vPjoLcX3lEbBT+pqwIJ11mC+0eGQ6zE9rP9EMpDT2ISyg==","signatures":[{"sig":"MEYCIQDJAILwZza8tg+0W69lCwj1+Bj4dRoALfOWISKuicU1qAIhAPWQj9PrAU6JzVWgk094TEnmsQWhU0Lnxnk5tMlsOJCp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fsignals@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":69624},"main":"./dist/index.js","type":"module","_from":"file:/tmp/tmp.4rm0e22lMw/aihu-signals-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_resolved":"/tmp/tmp.4rm0e22lMw/aihu-signals-0.3.0.tgz","_integrity":"sha512-JPm86ONQlnJG24jGxexbtGEcbYUwQ69t9Oma+ByN+vPjoLcX3lEbBT+pqwIJ11mC+0eGQ6zE9rP9EMpDT2ISyg==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.8.2","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/signals_0.3.0_1784389917182_0.5962043025761314","host":"s3://npm-registry-packages-npm-production"}},"0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113":{"name":"@aihu/signals","version":"0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113","license":"MIT","_id":"@aihu/signals@0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"cc1912a86b7c537420f4347c897277fa1a53b07c","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113.tgz","fileCount":7,"integrity":"sha512-51uxPnXrfBDL3qkZGXVrdHb/dtvxfQQFJtl04nXd1W1uwNrL2DMNckWxlf7Bb/RUJODBPHmV3G75fhEOP8b//g==","signatures":[{"sig":"MEYCIQCnNnQJyB2gmDsSnWhVKi/Q6kBoiHV6e6pTzKz4wylaDAIhAN1LVWXnMlqkvoanqq1MTusKZSSeVLMFFDKCkv+qsQ2E","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fsignals@0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":69724},"main":"./dist/index.js","type":"module","_from":"file:/tmp/tmp.9xn2Oawxan/aihu-signals-0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_resolved":"/tmp/tmp.9xn2Oawxan/aihu-signals-0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113.tgz","_integrity":"sha512-51uxPnXrfBDL3qkZGXVrdHb/dtvxfQQFJtl04nXd1W1uwNrL2DMNckWxlf7Bb/RUJODBPHmV3G75fhEOP8b//g==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.8.2","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","_npmOperationalInternal":{"tmp":"tmp/signals_0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113_1784720249080_0.7333906184895702","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aihu/signals","version":"0.4.0","license":"MIT","_id":"@aihu/signals@0.4.0","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"a720cfd5cc869aecf5e57ee4cc73eb6b85cb966b","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.4.0.tgz","fileCount":7,"integrity":"sha512-vHmSZwm2/Ita9wsUQp1nevXDeVq4KlHDdXHPINH8Q2kRiWFbf6tr9zeevG/HeNY1IikJ982zAq8BlSz2Ndngdg==","signatures":[{"sig":"MEYCIQDNEuQOjYvjE2lnWbSfdyZyrlPB+DuHdnAj3vqk0HwzgAIhAINOn8VldIBNc2BGWP+0iK2qHA7HjJd9hBFF4rutTow6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fsignals@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":98740},"main":"./dist/index.js","type":"module","_from":"file:/tmp/tmp.gTThje7biW/aihu-signals-0.4.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_resolved":"/tmp/tmp.gTThje7biW/aihu-signals-0.4.0.tgz","_integrity":"sha512-vHmSZwm2/Ita9wsUQp1nevXDeVq4KlHDdXHPINH8Q2kRiWFbf6tr9zeevG/HeNY1IikJ982zAq8BlSz2Ndngdg==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.8.2","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/signals_0.4.0_1784822261981_0.8144080460836125","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@aihu/signals","version":"0.5.0","license":"MIT","_id":"@aihu/signals@0.5.0","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"55d124973531cfa938dac07fad172826d6c097c7","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.5.0.tgz","fileCount":11,"integrity":"sha512-N7dYnbaj7hDYOmurXFvyRiu3AWVCKBPlkh4vGPjv9cq4Xo46576HdxrY6y3N+ruwNMlQpuNEkzwdIQ9EfpqyQg==","signatures":[{"sig":"MEUCIHI4w8wTSTAYopcWsz27Ehpapjw5gs+IvG0CoaHflOXZAiEAv/yVBHsfnbn/1Lb9wQ/Zs3WpLB4ebJAcFoFeOiy9D0g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fsignals@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":104956},"main":"./dist/index.js","type":"module","_from":"file:/tmp/tmp.xI88xwHBlr/aihu-signals-0.5.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./lifecycle":{"types":"./dist/lifecycle.d.ts","import":"./dist/lifecycle.js"}},"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_resolved":"/tmp/tmp.xI88xwHBlr/aihu-signals-0.5.0.tgz","_integrity":"sha512-N7dYnbaj7hDYOmurXFvyRiu3AWVCKBPlkh4vGPjv9cq4Xo46576HdxrY6y3N+ruwNMlQpuNEkzwdIQ9EfpqyQg==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/signals"},"_npmVersion":"10.8.2","description":"Tiny reactive signals — the reactive primitive at the core of aihu.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/signals_0.5.0_1785028447985_0.3913269347457107","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@aihu/signals","version":"0.5.1","license":"MIT","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./lifecycle":{"types":"./dist/lifecycle.d.ts","import":"./dist/lifecycle.js"}},"sideEffects":false,"scripts":{"build":"rolldown -c && node scripts/mangle-dist.mjs","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"description":"Tiny reactive signals — the reactive primitive at the core of aihu.","repository":{"type":"git","url":"git+https://github.com/aihu-project/aihu-dom.git","directory":"packages/signals"},"homepage":"https://github.com/aihu-project/aihu-dom/tree/main/packages/signals#readme","bugs":{"url":"https://github.com/aihu-project/aihu-dom/issues"},"publishConfig":{"access":"public"},"gitHead":"058ed2d523cb68197eaf64e5a3a5389dab9d4669","_id":"@aihu/signals@0.5.1","_nodeVersion":"26.2.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-lUJmxLIW5mCWHibv/XYg3Rh/SG4qrF/83JuWtfU2XZTnlrxsN+l+IIx3OO/wAZLGRibJVd6Q55LVu7dkkj1cdw==","shasum":"158d3d5930747cab42272581e584e9bc96733f2c","tarball":"https://registry.npmjs.org/@aihu/signals/-/signals-0.5.1.tgz","fileCount":11,"unpackedSize":106138,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHzNalWQeJHon4F2tt/+d1Q68HlX7sXY9FBGhJhp/pZXAiEA2PmWmv9cmI7nqudJ+ShV78z92xLz5T0sU5ap+p/DFj0="}]},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"directories":{},"maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/signals_0.5.1_1788744075490_0.6787582919327764"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-05T19:36:49.324Z","modified":"2026-09-07T01:21:15.860Z","0.1.0":"2026-05-05T19:36:49.539Z","0.1.1":"2026-05-05T22:04:12.831Z","0.2.0":"2026-06-05T20:23:22.924Z","0.3.0":"2026-07-18T15:51:57.315Z","0.0.0-canary-331b0151f7756608a00168b6de1d3b7bae639113":"2026-07-22T11:37:29.208Z","0.4.0":"2026-07-23T15:57:42.108Z","0.5.0":"2026-07-26T01:14:08.103Z","0.5.1":"2026-09-07T01:21:15.622Z"},"bugs":{"url":"https://github.com/aihu-project/aihu-dom/issues"},"license":"MIT","homepage":"https://github.com/aihu-project/aihu-dom/tree/main/packages/signals#readme","repository":{"type":"git","url":"git+https://github.com/aihu-project/aihu-dom.git","directory":"packages/signals"},"description":"Tiny reactive signals — the reactive primitive at the core of aihu.","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"readme":"# @aihu/signals\n\n> **Aihu** — agentic discovery and interaction, for human purpose.\n\nTiny reactive signals — the reactive primitive at the core of aihu.\n\nPart of the **runtime core** layer of the Aihu meta-framework. Shipped to the client; sized via `bun run size`. The runtime core is dep-free and stacks under `@aihu/runtime` → `@aihu/router` → `@aihu/server` → `@aihu/app`.\n\n<!-- BEGIN_HANDWRITTEN: prose -->\nSmall (≤ 2 kB gz) reactive primitives — the foundation layer for Aihu's arbor renderer. One read shape (`signal` tuple), one underlying cell. Sync semantics, lazy `computed`, explicit `batch`. No proxies, no scheduler queue, no global tick.\n\n## Hello counter\n\n```ts\nimport { signal, effect } from '@aihu/signals'\n\nconst [count, setCount] = signal(0)\neffect(() => console.log('count =', count()))\nsetCount(1)            // logs \"count = 1\"\nsetCount((n) => n + 10) // logs \"count = 11\"\n```\n\n## Derived values with `computed`\n\n```ts\nimport { signal, computed, effect } from '@aihu/signals'\n\nconst [n, setN] = signal(2)\nconst doubled = computed(() => n() * 2)\n\neffect(() => console.log('doubled =', doubled())) // logs \"doubled = 4\"\nsetN(3)                                            // logs \"doubled = 6\"\n```\n\n`computed` is **lazy**: the body doesn't run until you read it. Subsequent reads return the cached value until a dep changes.\n\n## Atomic updates with `batch`\n\n```ts\nimport { signal, effect, batch } from '@aihu/signals'\n\nconst [name, setName] = signal('')\nconst [email, setEmail] = signal('')\n\neffect(() => save(name(), email()))   // runs once per save event\n\nbatch(() => {\n  setName('Ada')\n  setEmail('ada@example.com')\n})\n// effect ran exactly once after the batch closed — not once per write.\n```\n\n`batch` returns `void`. To get a value out, capture it in a closure variable:\n```ts\nlet id: string\nbatch(() => { id = insertRow(); setName('Ada') })\n```\n\n## Cross-library cheat sheet\n\n| Vue 3 | Solid | Preact Signals | aihu |\n|---|---|---|---|\n| `ref(0)` + `.value` | `createSignal(0)` → `[get, set]` | `signal(0)` + `.value` | `signal(0)` → `[get, set]` |\n| `computed(fn)` + `.value` | `createMemo(fn)` (eager) | `computed(fn)` + `.value` (lazy) | `computed(fn)` (lazy, call-shape) |\n| `watchEffect(fn)` → `WatchHandle.stop()` | `createEffect(fn)` (microtask) | `effect(fn)` → dispose | `effect(fn)` → dispose (sync) |\n| `nextTick` (no batch) | `batch(fn)` (returns) | `batch(fn)` (void) | `batch(fn)` (void) |\n\n## Untrack a read\n\n```ts\nimport { signal, computed, untrack } from '@aihu/signals'\n\nconst [a, setA] = signal(1)\nconst [b, setB] = signal(10)\n\nconst sum = computed(() => a() + untrack(() => b()))\n// sum tracks `a` only; setB updates won't recompute `sum`\n```\n\n## Effect error isolation\n\nWhen multiple effects fire in the same wave and one throws, sibling effects still run. The first thrown error rethrows directly; multiple thrown errors surface as `AggregateError`:\n\n```ts\nconst [n, setN] = signal(0)\neffect(() => { /* runs */ })\neffect(() => { if (n() > 0) throw new Error('boom') })\neffect(() => { /* still runs after sibling throws */ })\n\ntry { setN(1) } catch (e) { /* e is the original Error */ }\n```\n\nComputed-body throws bypass this path and continue to fail fast.\n\n## Storing functions in signals\n\n`Signal<T>` for function-typed `T` requires the closure-of-closure idiom:\n\n```ts\nconst [getFn, setFn] = signal<() => number>(() => 5)\nsetFn(() => 6)            // ❌ TypeScript error\nsetFn(() => () => 6)      // ✅ stores the function\n```\n\nThe runtime disambiguates `value` vs `updater` by `typeof === 'function'`, so a raw function is unambiguous *only* via the updater form. Mirrors SolidJS's `Setter<T>`. Detail: [`.team/phase-2/spec-signals-write-of-functions.md`](../../.team/phase-2/spec-signals-write-of-functions.md).\n\n## v0 limitations\n\n- **Cycle errors carry no chain context.** `SignalCircularError` is thrown synchronously from the writer; richer chain info lands with devtools.\n- **No `peek` / `onCleanup`.** Single-purpose primitives only; arbor's higher-level scopes live in `@aihu/arbor`.\n- **Batch cascade cap.** `batch()` re-iterates up to 100 times before throwing `SignalCircularError`. The cap is internal; if tooling needs to sanity-check legitimate cascade depth in the future, we'll re-export it.\n<!-- END_HANDWRITTEN: prose -->\n\n## Install\n\n<!-- BEGIN_AUTOGEN: install -->\n<!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->\n\n```bash\nnpm install @aihu/signals\n# or\nbun add @aihu/signals\n```\n\n<sub><i>Auto-generated against `@aihu/signals@0.5.0`.</i></sub>\n\n<!-- END_AUTOGEN: install -->\n\n## Package facts\n\n<!-- BEGIN_AUTOGEN: stats -->\n<!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->\n\n| | |\n|---|---|\n| **Version** | `0.5.0` |\n| **Tier** | A — Reactive runtime core — signals/computeds/effects |\n| **Bundle size** | 2.18 kB (gz) — limit 2350 B |\n| **Published files** | 3 entries |\n| **License** | MIT |\n\n<sub><i>Auto-generated against `@aihu/signals@0.5.0`.</i></sub>\n\n<!-- END_AUTOGEN: stats -->\n\n## Exports\n\n<!-- BEGIN_AUTOGEN: exports -->\n<!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->\n\n| Subpath | ESM | CJS |\n|---|---|---|\n| `.` | `./dist/index.js` | `—` |\n| `./lifecycle` | `./dist/lifecycle.js` | `—` |\n\n<sub><i>Auto-generated against `@aihu/signals@0.5.0`.</i></sub>\n\n<!-- END_AUTOGEN: exports -->\n\n## Dependencies\n\n<!-- BEGIN_AUTOGEN: deps -->\n<!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->\n\n_Zero runtime dependencies_ (per the [dep-free thesis](../../README.md#project-posture))_._\n\n<sub><i>Auto-generated against `@aihu/signals@0.5.0`.</i></sub>\n\n<!-- END_AUTOGEN: deps -->\n\n## Server-Side Rendering (SSR)\n\n`@aihu/signals` uses module-level reactive state (`currentObserver`, `batchQueue`, `effectQueue`, `wave`, and the link pool) that is **shared across all concurrent requests** in the same Node.js worker thread — it is not request-isolated by default.\n\nIf you use `@aihu/signals` in server-side code (via `@aihu-plugin/data`'s `resource()` or directly):\n\n- Wrap all async operations inside effects with `untrack()` to prevent `currentObserver` from leaking across request boundaries during event-loop yields.\n- Do not hold live reactive graphs between requests — dispose effects when the request completes.\n- For true request isolation, instantiate signals within a request-scoped context rather than at module level.\n\nClient-side usage (browser custom elements, arbor mounts) is unaffected — each tab is an isolated JS environment.\n\n## See also\n\n<!-- BEGIN_AUTOGEN: see-also -->\n<!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->\n\n- [Phase 2 spec (signals)](../../.team/phase-2/spec-signals.md)\n- [bench/signals](../../bench/signals/RESULTS.md)\n- [@aihu/arbor](../arbor)\n- [Aihu framework root](../../README.md)\n\n<sub><i>Auto-generated against `@aihu/signals@0.5.0`.</i></sub>\n\n<!-- END_AUTOGEN: see-also -->\n\n## License\n\n<!-- BEGIN_AUTOGEN: license -->\n<!-- regenerate: bun scripts/sync-readme.ts (also runs in pre-commit + CI) -->\n\nMIT — see [LICENSE](../../LICENSE).\n\n<sub><i>Auto-generated against `@aihu/signals@0.5.0`.</i></sub>\n\n<!-- END_AUTOGEN: license -->\n","readmeFilename":"README.md"}