{"_id":"@aihu/store","_rev":"2-298005e499925d89b8ad1fd16260962e","name":"@aihu/store","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.1":{"name":"@aihu/store","version":"0.1.1","license":"MIT","_id":"@aihu/store@0.1.1","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"homepage":"https://github.com/fellwork/aihu/tree/main/packages/store#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"dist":{"shasum":"e300cddbb704d42e0c6e57680aeebeb655b3e133","tarball":"https://registry.npmjs.org/@aihu/store/-/store-0.1.1.tgz","fileCount":7,"integrity":"sha512-U7FTesAQrM4hktPTOflpUDhX6N/9OzclzeDaFlU7lKOCo+7QpnGsFcL8A8s7ugma9/xFg45ZGojP1hZ1Gcy2EQ==","signatures":[{"sig":"MEUCIAr9yuD6D0UD7O0F4H2W3zQL7m7INI9YS2Qm8msJPfDFAiEA+GbfzgBxxAWSXit/3oTyMVmY1JKuCoKBrBOy71i9iBk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fstore@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":52852},"main":"./dist/index.js","type":"module","_from":"file:/tmp/tmp.oug7jd2NJF/aihu-store-0.1.1.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"rolldown -c","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"_npmUser":{"name":"srmcguirt","email":"srmcguirt@gmail.com"},"_resolved":"/tmp/tmp.oug7jd2NJF/aihu-store-0.1.1.tgz","_integrity":"sha512-U7FTesAQrM4hktPTOflpUDhX6N/9OzclzeDaFlU7lKOCo+7QpnGsFcL8A8s7ugma9/xFg45ZGojP1hZ1Gcy2EQ==","repository":{"url":"git+https://github.com/fellwork/aihu.git","type":"git","directory":"packages/store"},"_npmVersion":"10.8.2","description":"Pinia-style global stores on aihu signals — defineStore, SSR-safe per-request instances, registry-based serialize/hydrate, plugins.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"@aihu/context":"0.2.0","@aihu/signals":"0.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/store_0.1.1_1784838452670_0.33953300684192067","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@aihu/store","version":"0.1.2","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"}},"sideEffects":false,"scripts":{"build":"rolldown -c","typecheck":"tsc --noEmit","prepublishOnly":"bun run build"},"dependencies":{"@aihu/context":"0.2.0","@aihu/signals":"0.5.0"},"description":"Pinia-style global stores on aihu signals — defineStore, SSR-safe per-request instances, registry-based serialize/hydrate, plugins.","repository":{"type":"git","url":"git+https://github.com/fellwork/aihu.git","directory":"packages/store"},"homepage":"https://github.com/fellwork/aihu/tree/main/packages/store#readme","bugs":{"url":"https://github.com/fellwork/aihu/issues"},"publishConfig":{"access":"public"},"_id":"@aihu/store@0.1.2","_integrity":"sha512-G+fqb/YZurAkNyD+pncyHXIfSA8c2LDDIAQd2GwydOOlvRjUxQqjHuZYC2N7gvGTERaRsBLp8Pi6JNYgkfMfow==","_resolved":"/tmp/tmp.m6y0rXU9qc/aihu-store-0.1.2.tgz","_from":"file:/tmp/tmp.m6y0rXU9qc/aihu-store-0.1.2.tgz","_nodeVersion":"22.12.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-G+fqb/YZurAkNyD+pncyHXIfSA8c2LDDIAQd2GwydOOlvRjUxQqjHuZYC2N7gvGTERaRsBLp8Pi6JNYgkfMfow==","shasum":"e427845e223a23399e3741d26cc221c4b1b2208a","tarball":"https://registry.npmjs.org/@aihu/store/-/store-0.1.2.tgz","fileCount":7,"unpackedSize":52904,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aihu%2fstore@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHEV8SvsXD/OWe0oPYY7f1ddTb3u5Azj+kn/ysB+bp3PAiEAg50YYW7opPGViqtv7Ts8IS9HaXM4md6YCGJcAZI9R7M="}]},"_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/store_0.1.2_1785028497584_0.21262164408074202"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-23T20:27:32.524Z","modified":"2026-07-26T01:14:58.040Z","0.1.1":"2026-07-23T20:27:32.805Z","0.1.2":"2026-07-26T01:14:57.730Z"},"bugs":{"url":"https://github.com/fellwork/aihu/issues"},"license":"MIT","homepage":"https://github.com/fellwork/aihu/tree/main/packages/store#readme","repository":{"type":"git","url":"git+https://github.com/fellwork/aihu.git","directory":"packages/store"},"description":"Pinia-style global stores on aihu signals — defineStore, SSR-safe per-request instances, registry-based serialize/hydrate, plugins.","maintainers":[{"name":"srmcguirt","email":"srmcguirt@gmail.com"}],"readme":"# @aihu/store\n\n> **Aihu** — agentic discovery and interaction, for human purpose.\n\nPinia-style global stores on aihu signals — defineStore, SSR-safe per-request instances, registry-based serialize/hydrate, plugins.\n\nHeld-private workspace package. Not yet published to npm.\n\n> **Status:** Held private — not yet published to npm. See [v1.1 roadmap](../../docs/roadmap/SUMMARY.md) for ratification gating (e.g. RFC #56 live-binding for `@aihu/plugin` enforcement).\n\n<!-- BEGIN_HANDWRITTEN: prose -->\n## defineStore\n\nSetup-function style is primary — use `signal`/`computed`/plain functions and return the store shape. State is the set of `k`/`setK` read-write pairs:\n\n```ts\nimport { computed, signal } from '@aihu/signals'\nimport { defineStore } from '@aihu/store'\n\nexport const useCart = defineStore('cart', () => {\n  const [items, setItems] = signal<string[]>([])\n  const size = computed(() => items().length)\n  function add(item: string) {\n    setItems((prev) => [...prev, item])\n  }\n  return { items, setItems, size, add }\n})\n\nconst cart = useCart() // lazy singleton per id (per request on the server)\ncart.add('apple')\ncart.size() // 1\n```\n\nOptions style lowers onto the same core — each `state()` key becomes a `k`/`setK` signal pair, getters become computeds over the state reads, actions get `this` bound to the store:\n\n```ts\nexport const useCart = defineStore('cart', {\n  state: () => ({ items: [] as string[] }),\n  getters: { size: (s) => s.items().length },\n  actions: {\n    add(item: string) {\n      this.setItems((prev) => [...prev, item])\n    },\n  },\n})\n```\n\nPer-store custom options (consumed by plugins) go in the third argument for **both** styles: `defineStore(id, def, { persist: true })`.\n\n### Instance surface\n\n- `$id` — the store id.\n- `$patch(objOrFn)` — several writes, one notification (object form writes state keys; function form receives the store).\n- `$reset()` — options-style only: re-runs the `state()` factory. Setup stores throw (their initial values are arbitrary expressions inside the setup closure — there is no factory to re-run; write an explicit reset action instead).\n- `$subscribe(cb)` — `cb(stateSnapshot)` after each state change (batch = one call). Returns dispose.\n- `$onAction(cb)` — before/`after`/`onError` hooks around every action call. Returns dispose.\n- `$dispose()` — tears down subscriptions and store-owned computeds, unregisters the instance (next `useStore()` re-instantiates).\n\n### State detection (setup style)\n\nA key `k` is **state** when the setup returns a read function under `k` and a setter under `set${Capitalize(k)}`. Computed reads are recognized by their `.dispose` property and are neither state nor actions; remaining returned functions are actions; plain values pass through untouched (and are not serialized). An unpaired signal read is treated as an action-shaped function — expose state as read+setter pairs.\n\n## SSR\n\nServer: wrap each request in `runWithContext(new Map(), render)` (from `@aihu/context`). Store instances then live per request — no cross-request leakage — and `serializeStores()` reads only the active request's registry. This path is **arbor-independent**: it never touches the arbor tree or `MountScope.serialize()`, so a compile-time SSR string renderer serializes stores identically.\n\nWire shape — `{ [storeId]: { [stateKey]: jsonValue } }`, `<script type=\"application/json\">` compatible. Only state is serialized, never getters/actions:\n\n```ts\n// server, inside the request scope, after rendering\nconst json = JSON.stringify(serializeStores()).replace(/</g, '\\\\u003c')\nhtml += `<script type=\"application/json\" id=\"__AIHU_STORE_STATE__\">${json}</script>`\n\n// client entry, BEFORE mounting components\nconst el = document.getElementById('__AIHU_STORE_STATE__')\nif (el) hydrateStores(JSON.parse(el.textContent!))\n```\n\n`hydrateStores` pre-seeds the registry: stores used later adopt their snapshot during instantiation (before any subscriber can observe defaults); snapshot entries for stores never used stay pending; client stores absent from the snapshot initialize fresh.\n\n## Plugins\n\n```ts\nimport { registerStorePlugin } from '@aihu/store'\n\nconst dispose = registerStorePlugin(({ store, id, options }) => {\n  store.$onAction(({ name }) => console.log(`${id}.${name}`))\n  return { $custom: true } // merged onto the instance\n})\n```\n\nFirst-party: `persistPlugin` / `createPersistPlugin({ storage, prefix })` — localStorage write-through, opt-in via `{ persist: true | { key } }`, SSR-guarded (no window access on server), hydrate-from-storage on client init (local edits win over an SSR snapshot), writes coalesced per microtask.\n\n## Dev\n\nIn dev builds (`process.env.NODE_ENV !== 'production'`, same convention as `@aihu/signals`) the client registry is exposed as `globalThis.__AIHU_STORES__` for console inspection.\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/store\n# or\nbun add @aihu/store\n```\n\n<sub><i>Auto-generated against `@aihu/store@0.1.2`.</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.1.2` |\n| **Tier** | G — State — Pinia-style global stores on aihu signals (SSR-safe per-request) |\n| **Bundle size** | 1.81 kB (gz) — limit 2.5 KB |\n| **Published files** | 3 entries |\n| **License** | MIT |\n\n<sub><i>Auto-generated against `@aihu/store@0.1.2`.</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\n<sub><i>Auto-generated against `@aihu/store@0.1.2`.</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**Dependencies:**\n\n- `@aihu/context` — `workspace:*`\n- `@aihu/signals` — `workspace:*`\n\n<sub><i>Auto-generated against `@aihu/store@0.1.2`.</i></sub>\n\n<!-- END_AUTOGEN: deps -->\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- [@aihu/signals](../signals)\n- [@aihu/context](../context)\n- [Aihu framework root](../../README.md)\n\n<sub><i>Auto-generated against `@aihu/store@0.1.2`.</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/store@0.1.2`.</i></sub>\n\n<!-- END_AUTOGEN: license -->\n","readmeFilename":"README.md"}