{"_id":"@absolutejs/vue-composables","_rev":"7-b8cc775a0d77600b5eae9004bd282662","name":"@absolutejs/vue-composables","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@absolutejs/vue-composables","version":"0.1.0","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/vue-composables@0.1.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"dist":{"shasum":"158e1ba881e9a6c5db046a031b45eb55858580f1","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.1.0.tgz","fileCount":6,"integrity":"sha512-0Dvwk3UUhrq6mc6VTLRlLnnjvcRQ8Ybc4rSsDLnUNXxOw01tFOFtQVOdJlmQqFBcivxwTsPwEbGV0tq5vE4qDw==","signatures":[{"sig":"MEYCIQDWkPpCivNzhavIfHIertuZ5XUY6uwYEZBzjgFLIhxK9wIhANK4xuug4QDoP7+bqWBbyy9hcCduU3QucqO+n1GM4Jxo","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23177},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","scripts":{"build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/vue-composables.git","type":"git"},"_npmVersion":"10.9.2","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.38","typescript":"^6.0.3"},"peerDependencies":{"vue":">=3.3"},"_npmOperationalInternal":{"tmp":"tmp/vue-composables_0.1.0_1782364660785_0.4704096124050088","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@absolutejs/vue-composables","version":"0.2.0","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/vue-composables@0.2.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"dist":{"shasum":"6a95d7a2dd36f1c6d52d797690d3a459130b81af","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.2.0.tgz","fileCount":6,"integrity":"sha512-x3aWrGdhLE5bkQgjnO1Tc9+zqoZy+3V5p0TIpsCowiASCKu3wSIixB2TzCUyVGy7TFBK3lEp2GXT3ut0SBvwtA==","signatures":[{"sig":"MEQCIB57v5B0YxgREmVB1nbugOYRANNBLtS+9PPmwf4hnHUOAiB0kJ4FwS/6ZXGfYfCEcshUv0u0MNhy3Zl/gmaWYRvWlw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33158},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","gitHead":"0ccd3c7e7b6f8a15865adacaad2e2fea1c96e55b","scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/vue-composables.git","type":"git"},"_npmVersion":"10.9.2","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.38","typescript":"^6.0.3"},"peerDependencies":{"vue":">=3.3"},"_npmOperationalInternal":{"tmp":"tmp/vue-composables_0.2.0_1784721813065_0.39839435058306294","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@absolutejs/vue-composables","version":"0.3.0","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/vue-composables@0.3.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"dist":{"shasum":"b20e2e52e94b2150ea390855011505a2af0b13fb","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.3.0.tgz","fileCount":6,"integrity":"sha512-U8yst+Pg6F6wBvC7AZURyHyvgIKsC4C6Ek2GXoPVwHVp5svkRCkwhFBrW2UJO3bshMvjKJPdGGgD5+wzwLqsGg==","signatures":[{"sig":"MEUCIFI3bn8cFxqB8E1kRYxEtXuztTknFmBjC0o6poK4Fl/QAiEAjv5/4t8ZVNMDBHEbDZm8JsTQbZJ8ztsubaPLqWaLW3w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37547},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","gitHead":"1b6a374515915a34b59654c7019f15b7fea08098","scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/vue-composables.git","type":"git"},"_npmVersion":"10.9.2","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.38","typescript":"^6.0.3"},"peerDependencies":{"vue":">=3.3"},"_npmOperationalInternal":{"tmp":"tmp/vue-composables_0.3.0_1784770372311_0.1825092613725099","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@absolutejs/vue-composables","version":"0.3.1","author":"Alex Kahn","license":"Apache-2.0","_id":"@absolutejs/vue-composables@0.3.1","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"dist":{"shasum":"d4388b6cad6887f267e5f2763bdabf6216f43c2d","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.3.1.tgz","fileCount":6,"integrity":"sha512-88tOSpbV676tvDNOte1UsWeb0InQJwkvZKo/jqEyfumXIhfeywVlqLsE7Iho4zNRs5EDXcjKRDwCeYmkDIKC/Q==","signatures":[{"sig":"MEUCIQDHDDMeJld0XFndVG9VBbA/5vQC0BHOlar9JrPgnIeRNQIgZ2hYo+aHa/sfF8cbqui4BPwkn5qdkOGTVoW9Dm2vwbY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41502},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","shasum":"d4388b6cad6887f267e5f2763bdabf6216f43c2d","scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"_integrity":"sha512-88tOSpbV676tvDNOte1UsWeb0InQJwkvZKo/jqEyfumXIhfeywVlqLsE7Iho4zNRs5EDXcjKRDwCeYmkDIKC/Q==","repository":{"url":"https://github.com/absolutejs/vue-composables.git","type":"git"},"_npmVersion":"10.8.3","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","directories":{},"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.38","typescript":"^6.0.3"},"peerDependencies":{"vue":">=3.3"},"_npmOperationalInternal":{"tmp":"tmp/vue-composables_0.3.1_1784956789704_0.2648275225204517","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@absolutejs/vue-composables","version":"0.3.2","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/vue-composables@0.3.2","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"dist":{"shasum":"9edf5c990c23923ad33093015a4600c9855472fb","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.3.2.tgz","fileCount":6,"integrity":"sha512-ca2cS7aDziE5DJmSJRiiUkeBVQdzUABqhJQxu9dZwCV3+V63aMMBpMvWLSh5TibbF6y8tCJ4ElX7D6kNm3fFbw==","signatures":[{"sig":"MEUCIQDOischkD/grqaLF18drZZ7EkLtlzXgPxmvWri2NzcSdAIgX6xkgqLPUbRLo/JKv8Mk6YxrKpNRrnJ4RxCIhdX6A04=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42057},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","gitHead":"212b237fd78492c0428e9b5f3b383c1a7c1b69c7","scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/vue-composables.git","type":"git"},"_npmVersion":"10.9.2","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.38","typescript":"^6.0.3"},"peerDependencies":{"vue":">=3.3"},"_npmOperationalInternal":{"tmp":"tmp/vue-composables_0.3.2_1785741795227_0.2646951768963397","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"name":"@absolutejs/vue-composables","version":"0.3.3","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/vue-composables@0.3.3","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"dist":{"shasum":"f4210706dd6b074fd7b18794b0e2734771cfe2d4","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.3.3.tgz","fileCount":6,"integrity":"sha512-2PJNlcxTS0Pq2vFVVdFVD3lyE8Vx9e7je9ouHFIq3HRoMyb8l/R09zHWg9Mv0GAA26ivMzgTsEx6dNqqizfGtw==","signatures":[{"sig":"MEUCIAiUkClTjvK2xYFxNaTJ7E+J3YRS9CvwE7XzbiroG37ZAiEAouwFCyjESCVNYIAPQ3BbPyPAehJDTchXPlu1W19aR/k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42035},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","gitHead":"fc08c8d848196b3c2416cfa85d7217570c0a3123","scripts":{"test":"bun test","build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/vue-composables.git","type":"git"},"_npmVersion":"10.9.2","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.38","typescript":"^6.0.3"},"peerDependencies":{"vue":">=3.3"},"_npmOperationalInternal":{"tmp":"tmp/vue-composables_0.3.3_1785742365632_0.9713849628749582","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"author":"Alex Kahn","description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","license":"Apache-2.0","publishConfig":{"access":"public"},"main":"./dist/index.js","module":"./dist/index.js","type":"module","name":"@absolutejs/vue-composables","repository":{"type":"git","url":"https://github.com/absolutejs/vue-composables.git"},"homepage":"https://github.com/absolutejs/vue-composables","bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"scripts":{"build":"rm -rf dist && bun build src/index.ts --outdir dist --sourcemap --external vue && tsc --emitDeclarationOnly --project tsconfig.json","test":"bun test","typecheck":"tsc --noEmit"},"types":"./dist/index.d.ts","version":"0.4.0","peerDependencies":{"vue":">=3.3"},"devDependencies":{"typescript":"^6.0.3","vue":"^3.5.38"},"_id":"@absolutejs/vue-composables@0.4.0","_integrity":"sha512-cTzKV+O7nzZuP4vB/Wh0b/dyww3dJs/gqjAkeKMk2p3wr2br1Bm7ftGgkQb+hHKVaRx4qN6T9OKJzpraOeD9jg==","_nodeVersion":"24.3.0","_npmVersion":"10.8.3","shasum":"3bfb871057f7c7af83f44c9581f816c9d218ca89","dist":{"integrity":"sha512-cTzKV+O7nzZuP4vB/Wh0b/dyww3dJs/gqjAkeKMk2p3wr2br1Bm7ftGgkQb+hHKVaRx4qN6T9OKJzpraOeD9jg==","shasum":"3bfb871057f7c7af83f44c9581f816c9d218ca89","tarball":"https://registry.npmjs.org/@absolutejs/vue-composables/-/vue-composables-0.4.0.tgz","fileCount":6,"unpackedSize":45197,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICGhz+nOCzK8+atv/oEKlm6ENFr/5u6weKIlJjqxPW7wAiEAhzFFfsyRp8bvu9i9f/C2HNDqOc3MbsGBOVoskbJsbm4="}]},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vue-composables_0.4.0_1785838647968_0.9872307688544435"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-25T05:17:40.600Z","modified":"2026-08-04T10:17:28.328Z","0.1.0":"2026-06-25T05:17:40.945Z","0.2.0":"2026-07-22T12:03:33.207Z","0.3.0":"2026-07-23T01:32:52.474Z","0.3.1":"2026-07-25T05:19:49.895Z","0.3.2":"2026-08-03T07:23:15.379Z","0.3.3":"2026-08-03T07:32:45.764Z","0.4.0":"2026-08-04T10:17:28.147Z"},"bugs":{"url":"https://github.com/absolutejs/vue-composables/issues"},"author":"Alex Kahn","license":"Apache-2.0","homepage":"https://github.com/absolutejs/vue-composables","repository":{"type":"git","url":"https://github.com/absolutejs/vue-composables.git"},"description":"A few small, broadly-useful Vue composables for AbsoluteJS apps: useHydrated (SSR hydration gate), isBrowser, useDebouncedAction, and runAsyncAction (try/catch/loading/notify wrapper with an injectable notifier). Vue is a peer dependency.","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"readme":"# @absolutejs/vue-composables\n\nA few small, broadly-useful Vue composables for AbsoluteJS (SSR-first) apps.\nVue is a peer dependency.\n\n## Installation\n\n```sh\nbun add @absolutejs/vue-composables vue\n```\n\n## Composables\n\n- **`useHydrated()`** — a ref that's `false` during SSR + the first client\n  render, then `true` after mount. Gate client-only data on it to avoid\n  hydration mismatches: `loading = !hydrated.value || actualLoading.value`.\n- **`isBrowser`** — `true` on the client, `false` during SSR.\n- **`useDebouncedAction(fn, delayMs?)`** — trailing-edge debouncer auto-cleared\n  on scope dispose; `.trigger()` (re)starts the delay.\n- **`useResizeObserver(target, callback, options?)`** — SSR-safe element\n  observer that coalesces notifications to the next animation frame and\n  automatically cleans up when the target or Vue scope changes.\n- **`useAutoGrowTextarea(target, { maxHeight })`** — keeps chat composers\n  content-sized until a reactive maximum, then switches to internal scrolling.\n- **`isTextSubmitKey(event)`** — recognizes plain Enter while excluding\n  Shift+Enter and IME composition confirmation.\n- **`useClickOutside(target, handler)`** — fires `handler` on a capture-phase\n  `pointerdown` outside `target`; auto-removed on scope dispose. For a\n  toggle-button + panel pair, pass the element wrapping both.\n- **`runAsyncAction(task, options)`** — the try/catch/finally + notify +\n  console.error + loading-flag wrapper. Inject your toast once with\n  `configureAsyncNotifier({ success, error })`.\n- **`useOffsetPagination(options)`** — zero-based page, offset, range, and\n  navigation state that automatically clamps when a filtered total shrinks.\n- **`useCursorPagination()`** — opaque cursor history for stable keyset APIs.\n\n## Async actions\n\n```ts\nimport {\n\tconfigureAsyncNotifier,\n\trunAsyncAction,\n\tuseHydrated\n} from '@absolutejs/vue-composables';\n\nconfigureAsyncNotifier({ success: toast.success, error: toast.error });\n\nawait runAsyncAction(() => api.save(payload), {\n\tsuccessMessage: 'Saved',\n\tloading: (s) => (saving.value = s),\n\tonSuccess: () => emit('updated')\n});\n```\n\n## Resize observation\n\n```ts\nconst panel = useTemplateRef<HTMLElement>('panel');\n\nuseResizeObserver(panel, ([entry]) => {\n\tif (entry) compact.value = entry.contentRect.width < 640;\n});\n```\n\n## Pagination\n\n```ts\nconst total = computed(() => query.data.value?.total ?? 0);\nconst pagination = useOffsetPagination({ pageSize: 25, total });\n\nawait listRows({\n\tlimit: pagination.pageSize.value,\n\toffset: pagination.offset.value\n});\n```\n\nApache-2.0\n","readmeFilename":"README.md"}