{"_id":"@amatiasq/state-delta","name":"@amatiasq/state-delta","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@amatiasq/state-delta","version":"0.1.0","author":{"name":"A. Matías Quezada","email":"amatiasq@gmail.com"},"license":"MIT","type":"module","exports":{".":{"bun":"./src/index.ts","types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"vitest run"},"gitHead":"d2d07e8d6624c9ee9570da3364abc7a4febbd14c","_id":"@amatiasq/state-delta@0.1.0","description":"`diff` two JSON values, send the difference, `patch` it back. Made for state that travels thirty times a second: the delta carries only what changed, and a value the receiver can work out on its own costs nothing at all.","_nodeVersion":"24.18.1","_npmVersion":"11.16.0","dist":{"integrity":"sha512-F+GLLJI2Kd+N6inXf3mYzYMQgKJbssJmnTeIYBrHd7GFjnzKHfI28QMBff7Fl5olhEemvgLCNXlStDmYV+2neQ==","shasum":"93347b0bc8bfe385d68e95b90f3136b802ac82b8","tarball":"https://registry.npmjs.org/@amatiasq/state-delta/-/state-delta-0.1.0.tgz","fileCount":23,"unpackedSize":24728,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAIaEOpwrqe9aYx5V6Htc2oeJ5BAoHEC8/VWaeev0ggOAiEAyCtTlwpM15NX0LCPmoOcRqHrRK8fVR23kvJgiWLAWps="}]},"_npmUser":{"name":"amatiasq","email":"amatiasq@gmail.com"},"directories":{},"maintainers":[{"name":"amatiasq","email":"amatiasq@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/state-delta_0.1.0_1787726609247_0.9094637567436887"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-26T06:43:29.054Z","0.1.0":"2026-08-26T06:43:29.390Z","modified":"2026-08-26T06:43:29.570Z"},"maintainers":[{"name":"amatiasq","email":"amatiasq@gmail.com"}],"description":"`diff` two JSON values, send the difference, `patch` it back. Made for state that travels thirty times a second: the delta carries only what changed, and a value the receiver can work out on its own costs nothing at all.","author":{"name":"A. Matías Quezada","email":"amatiasq@gmail.com"},"license":"MIT","readme":"# @amatiasq/state-delta\n\n`diff` two JSON values, send the difference, `patch` it back. Made for state\nthat travels thirty times a second: the delta carries only what changed, and a\nvalue the receiver can work out on its own costs nothing at all.\n\n```sh\nnpm i --save @amatiasq/state-delta\n```\n\n## Usage\n\n```ts\nimport { diff, patch } from '@amatiasq/state-delta';\n\nconst delta = diff(previous, next);\nif (delta !== undefined) send(JSON.stringify(delta));\n\n// the other end\nstate = patch(state, JSON.parse(message));\n```\n\n`patch` never mutates what it is given, so the previous state stays valid and a\ndelta that arrives twice is harmless.\n\n## The format\n\nA delta is plain JSON and travels as it is:\n\n| Delta            | Means                                                 |\n| ---------------- | ----------------------------------------------------- |\n| `undefined`      | nothing changed                                        |\n| `[]`             | this is gone                                           |\n| `[value]`        | replace the whole object or array with `value`         |\n| `{ $: n, 2: … }` | an array of length `n`, with the indices that changed  |\n| anything else    | the new value                                          |\n\nA replacement is wrapped in an array so it cannot read as a partial update:\n`{ a: 1 }` says the key `a` changed, `[{ a: 1 }]` says the whole value is now\n`{ a: 1 }`.\n\n**`$` is reserved**: an array delta keeps its new length there, so `diff` throws\non an object that uses that key rather than let it travel as something else.\n\n## `UNCHANGED`\n\n`UNCHANGED` is the sender saying \"skip this one, you can work it out yourself\".\nThe key is left out of the delta and `patch` keeps whatever the receiver has —\nzero bytes, not a marker or a code.\n\n```ts\ndiff({ x: 0, hp: 3 }, { x: UNCHANGED, hp: 2 }); // { hp: 2 }\n```\n\n## The mirror invariant\n\n**Diff against what the receiver holds, never against the last value you built.**\nThe sender keeps a *mirror* of the receiver and moves it forward by patching the\nvery delta it just sent:\n\n```ts\nconst delta = diff(mirror, next);\nmirror = patch(mirror, delta);\nsend(delta);\n```\n\nThat is what keeps a skipped value from rotting. Diff against your own truth\ninstead and the field looks unchanged for ever: it never travels again, and the\nreceiver keeps a value nobody is going to correct.\n","readmeFilename":"README.md","_rev":"1-77cdabdcfaabf842458fbbb756b2536b"}