{"_id":"@adamantjs/signals","_rev":"2-cef2ef33ad601876febb28400de0a54f","name":"@adamantjs/signals","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@adamantjs/signals","version":"0.1.0","description":"A lightweight reactive programming library.","license":"MIT","author":{"name":"Aidan Loughran"},"repository":{"type":"git","url":"git+https://github.com/aidlran/signals.git"},"bugs":{"url":"https://github.com/aidlran/signals/issues"},"homepage":"https://github.com/aidlran/signals#readme","main":"./dist/cjs/index.js","types":"./dist/cjs/index.d.ts","type":"module","sideEffects":false,"exports":{".":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.js"}},"./svelte":{"types":"./dist/mjs/svelte.d.ts","default":"./dist/mjs/svelte.js"}},"scripts":{"build":"rm -dr dist; tsc && npm run build:cjs","build:cjs":"tsc --module commonjs --downlevelIteration --outDir dist/cjs && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json","cost":"bun build --minify src/signal/index.ts | gzip | wc -c","format":"prettier --write .","lint":"publint && eslint .","prepack":"npm run build","start":"tsc --watch --preserveWatchOutput"},"peerDependencies":{"svelte":">=3.44.2 <6.0.0"},"peerDependenciesMeta":{"svelte":{"optional":true}},"devDependencies":{"@types/node":"^20.11.5","@typescript-eslint/eslint-plugin":"^6.19.0","@typescript-eslint/parser":"^6.19.0","eslint":"^8.56.0","eslint-config-prettier":"^9.1.0","eslint-plugin-deprecation":"^2.0.0","eslint-plugin-prettier":"^5.1.3","prettier":"^3.2.4","prettier-plugin-jsdoc":"^1.3.0","publint":"^0.2.7","svelte":"^4.2.9","typescript":"~5.3.3"},"_id":"@adamantjs/signals@0.1.0","_nodeVersion":"20.10.0","_npmVersion":"10.4.0","dist":{"integrity":"sha512-JL3UK0SIlCibiNwe0Vuu2dHTnaFESNkx2/7/XIYYbUiKxUSedOBo+mYgovRcAgKwTPJou6AupuNorAWviEfVYQ==","shasum":"1edeffbfd8bfb3a01b94aaccd03763c1f2404dd5","tarball":"https://registry.npmjs.org/@adamantjs/signals/-/signals-0.1.0.tgz","fileCount":52,"unpackedSize":34509,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHBSl6OtuPje9xNkwQrhKiQH6DcTxQAsuHNz1sBAdDuiAiAbdo89CITdg4yuqi2kQp6uNNp5Tix0tcRDTsujxliG2A=="}]},"_npmUser":{"name":"aidlran","email":"aidlo.dev+npm@pm.me"},"directories":{},"maintainers":[{"name":"aidlran","email":"aidlo.dev+npm@pm.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/signals_0.1.0_1706299501977_0.78763456308711"},"_hasShrinkwrap":false},"0.1.1":{"name":"@adamantjs/signals","version":"0.1.1","description":"A lightweight reactive programming library.","license":"MIT","author":{"name":"Aidan Loughran"},"repository":{"type":"git","url":"git+https://github.com/aidlran/signals.git"},"bugs":{"url":"https://github.com/aidlran/signals/issues"},"homepage":"https://github.com/aidlran/signals#readme","main":"./dist/cjs/index.js","types":"./dist/cjs/index.d.ts","type":"module","sideEffects":false,"exports":{".":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.js"}},"./svelte":{"types":"./dist/mjs/svelte.d.ts","default":"./dist/mjs/svelte.js"}},"scripts":{"build":"rm -dr dist; tsc && npm run build:cjs","build:cjs":"tsc --module commonjs --downlevelIteration --outDir dist/cjs && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json","cost":"bun build --minify src/signal/index.ts | gzip | wc -c","format":"prettier --write .","lint":"publint && eslint .","prepack":"npm run build","start":"tsc --watch --preserveWatchOutput"},"peerDependencies":{"svelte":">=3.44.2 <6.0.0"},"peerDependenciesMeta":{"svelte":{"optional":true}},"devDependencies":{"@types/node":"^20.11.20","@typescript-eslint/eslint-plugin":"^7.0.2","@typescript-eslint/parser":"^7.0.2","eslint":"^8.57.0","eslint-config-prettier":"^9.1.0","eslint-plugin-deprecation":"^2.0.0","eslint-plugin-prettier":"^5.1.3","prettier":"^3.2.5","prettier-plugin-jsdoc":"^1.3.0","publint":"^0.2.7","svelte":"^4.2.12","typescript":"~5.3.3"},"_id":"@adamantjs/signals@0.1.1","_nodeVersion":"20.11.1","_npmVersion":"10.4.0","dist":{"integrity":"sha512-LrNpBg4v2mCMqSsLV16r9e3LOFSJcSgrucBQlJp58+U3DeInx3jFyOBzDmpCUA2KoMm/6rqnCYInDoo1wm8sLQ==","shasum":"b838e0d1944cba5112b06e6b900ec0be0c53b3dc","tarball":"https://registry.npmjs.org/@adamantjs/signals/-/signals-0.1.1.tgz","fileCount":44,"unpackedSize":34843,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHJR0gP/OMnGOrOm7tIRlA+o7PBxPFHErwsTRHv2osqaAiEAxnk3hKSjducf2LpOBNjWTxVlq6oqZ6gUJewa//9jPew="}]},"_npmUser":{"name":"aidlran","email":"aidlo.dev+npm@pm.me"},"directories":{},"maintainers":[{"name":"aidlran","email":"aidlo.dev+npm@pm.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/signals_0.1.1_1708905582293_0.8689390357833626"},"_hasShrinkwrap":false},"0.2.0":{"name":"@adamantjs/signals","version":"0.2.0","description":"A lightweight reactive programming library.","license":"MIT","author":{"name":"Aidan Loughran"},"repository":{"type":"git","url":"git+https://github.com/aidlran/signals.git"},"bugs":{"url":"https://github.com/aidlran/signals/issues"},"homepage":"https://github.com/aidlran/signals#readme","main":"./dist/cjs/index.js","types":"./dist/cjs/index.d.ts","type":"module","sideEffects":false,"exports":{".":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.js"}},"./svelte":{"types":"./dist/mjs/svelte.d.ts","default":"./dist/mjs/svelte.js"}},"scripts":{"build":"rm -dr dist; tsc && npm run build:cjs","build:cjs":"tsc --module commonjs --downlevelIteration --outDir dist/cjs && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json","ci":"npm run build && npm run lint && npm run test","cost":"bun build --minify src/signal/index.ts | gzip | wc -c","format":"prettier --write .","lint":"publint && eslint .","prepack":"npm run build","start":"tsc --watch --preserveWatchOutput","test":"node src/signal/signals.test.js"},"peerDependencies":{"svelte":">=3.44.2 <6.0.0"},"peerDependenciesMeta":{"svelte":{"optional":true}},"devDependencies":{"@types/node":"^20.11.24","@typescript-eslint/eslint-plugin":"^7.1.0","@typescript-eslint/parser":"^7.1.0","eslint":"^8.57.0","eslint-config-prettier":"^9.1.0","eslint-plugin-prettier":"^5.1.3","prettier":"^3.2.5","prettier-plugin-jsdoc":"^1.3.0","publint":"^0.2.7","svelte":"^4.2.12","typescript":"~5.3.3"},"_id":"@adamantjs/signals@0.2.0","_nodeVersion":"20.11.1","_npmVersion":"10.5.0","dist":{"integrity":"sha512-Eh5+Ld+Ry7NeZUN0LhRze32We21RoIwxaMLZyNsCafAnQpXybLPX1FtT15Uf0EVd+rdZbhsBbEwvO4kCGk1DCw==","shasum":"513a60789dbe4ecfac42578c476bfa448c4a1fd5","tarball":"https://registry.npmjs.org/@adamantjs/signals/-/signals-0.2.0.tgz","fileCount":36,"unpackedSize":38179,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCl42ksgeDsZOcpoa3KD0E8+TCh1Z7kG/fyA44FsQs/iAIhAIYHU0sdvk5QWsb2HlvgS/S6nIiL8STmpp04EDLuaa/p"}]},"_npmUser":{"name":"aidlran","email":"aidlo.dev+npm@pm.me"},"directories":{},"maintainers":[{"name":"aidlran","email":"aidlo.dev+npm@pm.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/signals_0.2.0_1709484905519_0.9609602068938852"},"_hasShrinkwrap":false}},"time":{"created":"2024-01-26T20:05:01.674Z","0.1.0":"2024-01-26T20:05:02.274Z","modified":"2024-03-03T16:55:06.421Z","0.1.1":"2024-02-25T23:59:42.522Z","0.2.0":"2024-03-03T16:55:05.757Z"},"maintainers":[{"name":"aidlran","email":"aidlo.dev+npm@pm.me"}],"description":"A lightweight reactive programming library.","homepage":"https://github.com/aidlran/signals#readme","repository":{"type":"git","url":"git+https://github.com/aidlran/signals.git"},"author":{"name":"Aidan Loughran"},"bugs":{"url":"https://github.com/aidlran/signals/issues"},"license":"MIT","readme":"# [@adamantjs/signals](https://github.com/aidlran/adamant)\n\nA lightweight reactive programming library based on the signals design pattern which has been popularised by many modern frontend JavaScript frameworks.\n\nThis implementation ships with both CommonJS and ESM versions and is intended to work in any runtime. The module is is tree-shakable, however using all functions should cost less than 500 bytes in a minified and gzipped bundle.\n\n## Usage\n\n### `signal`\n\nCreates a signal and assigns it an initial value. Returns a tuple consisting of a **getter** and a **setter** which you can name anything you like:\n\n```js\nimport { signal } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\nconsole.log(count()); // logged: 1\n\nsetCount(2);\nconsole.log(count()); // logged: 2\n\nsetCount(count() * 2);\nconsole.log(count()); // logged: 4\n```\n\n#### Typed signals\n\nA signal can be of any type. If you use TypeScript, you can specify a type `T` like so:\n\n```ts\nimport { signal } from '@adamantjs/signals';\n\ntype Fruit = 'Apple' | 'Banana' | 'Orange';\n\nconst [fruit, setFruit] = signal<Fruit>('Apple');\n```\n\n### `effect`\n\nThis is where it gets interesting. `effect` creates a **reactive callback**. The callback is executed once immediately. From that point onwards it will be executed again when a value of any of the signals it depends on changes.\n\n```js\nimport { effect, signal } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\neffect(() => {\n  // whenever the value changes, log it\n  console.log(count());\n});\n\n// increment the count every second\nsetInterval(() => {\n  setCount(count() + 1);\n}, 1000);\n```\n\n#### Unsubscribing\n\nOur effect will continue to be called **forever**. We need to manually unsubscribe when our effect is no longer needed. The `effect` function returns an unsubscribe function we can use. For instance, you might call this in a component's lifecycle \"destroy\" or \"unmount\" hook.\n\n```js\nimport { effect, signal } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\nconst unsubscribe = effect(() => {\n  // whenever the count has changed, log it\n  console.log(count());\n});\n\n// increment the count every second\nsetInterval(() => {\n  setCount(count() + 1);\n}, 1000);\n\n// unsubscribe after 5 seconds\nsetTimeout(() => {\n  unsubscribe();\n}, 5000);\n```\n\n### `derived`\n\nThis lets you create a special signal of which the value is derived from other signals. `derived` takes a callback, similar to `effect`, however it expects a return value.\n\n```js\nimport { derived, effect, signal } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\nconst doubled = derived(() => {\n  return count() * 2;\n});\n\neffect(() => {\n  // whenever the derived value has changed, log it\n  console.log(doubled());\n});\n\n// increment the count every second\nsetInterval(() => {\n  setCount(count() + 1);\n}, 1000);\n```\n\nIf a signal changes its value and no one is around to hear it, does it make a sound? The answer is no! Derived signals will subscribe to their dependencies and re-calculate their value only if they themselves are actively subscribed to.\n\nYou can use derived signals to create other derived signals, making them very flexible and powerful. You can create entire computed **signal chains** where values and computations propagate only to where they are subscribed.\n\n```js\nimport { derived, effect, signal } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\nconst doubled = derived(() => {\n  return count() * 2;\n});\n\nconst quadrupled = derived(() => {\n  return doubled() * 2;\n});\n\neffect(() => {\n  console.log(quadrupled());\n});\n\nsetInterval(() => {\n  setCount(count() + 1);\n}, 1000);\n```\n\n### Timing and `tick`\n\n> [!IMPORTANT]\n> To maximize efficiency, effects and derived signals are not recalculated until the call stack completes.\n\n```js\nimport { effect, signal } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\neffect(() => {\n  // whenever the value changes, log it\n  console.log(count());\n});\n\nsetInterval(() => {\n  // this entire call stack will complete before the effect is called\n  setCount(count() + 1); // this value is not logged!\n  setCount(count() + 1);\n}, 1000);\n```\n\nSometimes you need a dependent effect or derived signal to recalculate before you can continue. You can use the `tick` function for this. `tick` will await any pending notifications:\n\n```js\nimport { effect, signal, tick } from '@adamantjs/signals';\n\nconst [count, setCount] = signal(1);\n\neffect(() => {\n  // whenever the value changes, log it\n  console.log(count());\n});\n\nsetInterval(async () => {\n  setCount(count() + 1);\n  await tick(); // now the value is logged\n  setCount(count() + 1);\n}, 1000);\n```\n\n### `signalToStore` (Svelte)\n\nSvelte users with a matching `svelte` peer dependency may use the specialised export `@adamantjs/signals/svelte`. This exposes an additional function `signalToStore` which allows Svelte components to reactively read the signal via `$`.\n\n```svelte\n<script>\n  import { signal, signaltoStore } from '@adamantjs/signals/svelte';\n\n  const [countSignal, setCount] = signal(0);\n\n  const count = signalToStore(countSignal);\n</script>\n\n<button on:click={() => setCount($count + 1)}>{ $count }</button>\n```\n","readmeFilename":"README.md"}