{"_id":"@sockudo/client","_rev":"6-005496503ffbb6423d32d8d63e32a2eb","name":"@sockudo/client","dist-tags":{"latest":"2.2.0"},"versions":{"1.0.0":{"name":"@sockudo/client","version":"1.0.0","keywords":["sockudo","pusher-compatible","websocket","events","pubsub","bun","node"],"license":"MIT","_id":"@sockudo/client@1.0.0","maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"homepage":"https://github.com/sockudo/sockudo-js#readme","bugs":{"url":"https://github.com/sockudo/sockudo-js/issues"},"dist":{"shasum":"c2797e2ae54dacd3c0641b187d8c30680b280613","tarball":"https://registry.npmjs.org/@sockudo/client/-/client-1.0.0.tgz","fileCount":151,"integrity":"sha512-wAfezyGYVzn7YamtWbVBYTSH7puDU6hlqIT2AaVVyoedxIztpDDrRAULRb/l3d+7dl+bL3jyKBV2eif2rhChEg==","signatures":[{"sig":"MEUCIQD31KJkZ9KVG7XehO3uOuevOT2cuw808doeoZItX6habQIgXtDi5+G9LoFcszN+LW7V8kmGqzWRhnFfj/QAHzrpp5E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@sockudo%2fclient@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2770676},"main":"dist/node/pusher.js","type":"module","types":"index.d.ts","browser":"dist/web/pusher.mjs","engines":{"bun":">=1.0.0","node":">=22"},"exports":{".":{"node":"./dist/node/pusher.js","types":"./index.d.ts","import":"./dist/web/pusher.mjs","browser":"./dist/web/pusher.mjs","default":"./dist/web/pusher.mjs","react-native":"./dist/react-native/pusher.js"},"./filter":{"types":"./types/core/channels/filter.d.ts","import":"./dist/web/filter.mjs","default":"./dist/web/filter.mjs"},"./worker":{"types":"./worker/index.d.ts","default":"./worker/index.js"},"./react-native":{"types":"./react-native/index.d.ts","default":"./react-native/index.js"},"./with-encryption":{"types":"./with-encryption/index.d.ts","default":"./with-encryption/index.js"},"./worker/with-encryption":{"types":"./worker/with-encryption/index.d.ts","default":"./worker/with-encryption/index.js"}},"gitHead":"bafbc72e0a21a64790e6621927a0599587373321","scripts":{"lint":"oxlint --config .oxlintrc.json src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts","test":"bun test ./test","build":"bun run clean && bun run build:web","check":"bun run typecheck && bun run lint && bun test","clean":"rm -rf dist","format":"oxfmt src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts","lint:fix":"oxlint --config .oxlintrc.json --fix src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts","build:all":"bun run clean && bun run build:web && bun run build:node","build:web":"vite build && vite build --config vite.config.filter.ts && vite build --config vite.config.with-encryption.ts","typecheck":"tsc --noEmit","build:node":"vite build --config vite.config.node.ts && vite build --config vite.config.filter.node.ts && vite build --config vite.config.worker.ts && vite build --config vite.config.worker.with-encryption.ts && vite build --config vite.config.react-native.ts","test:watch":"bun test --watch ./test","build:watch":"vite build --watch","format:check":"oxfmt --check src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts"},"_npmUser":{"name":"sockudorealtime","email":"radu@sockudo.io"},"repository":{"url":"git+https://github.com/sockudo/sockudo-js.git","type":"git"},"_npmVersion":"10.9.4","description":"Sockudo JavaScript client full port on Bun + Oxc + Vite(Rolldown)","directories":{},"_nodeVersion":"22.22.0","dependencies":{"tweetnacl":"^1.0.3","fossil-delta":"^2.0.0","@stablelib/utf8":"^1.0.0","@stablelib/base64":"^1.0.0","@ably/vcdiff-decoder":"^1.0.6"},"react-native":"dist/react-native/pusher.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.9","devDependencies":{"oxfmt":"^0.4.0","oxlint":"^0.15.14","@types/bun":"latest","typescript":"^5.9.2","@types/node":"^20.19.0","rolldown-vite":"^7.3.0","@react-native-community/netinfo":"^5.9.7"},"peerDependencies":{"@react-native-community/netinfo":"*"},"peerDependenciesMeta":{"@react-native-community/netinfo":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/client_1.0.0_1770839535593_0.3905067376576057","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@sockudo/client","version":"1.1.0","keywords":["sockudo","pusher-compatible","websocket","events","pubsub","bun","node"],"license":"MIT","_id":"@sockudo/client@1.1.0","maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"homepage":"https://github.com/sockudo/sockudo-js#readme","bugs":{"url":"https://github.com/sockudo/sockudo-js/issues"},"dist":{"shasum":"0041536ffa385f37388dae01eaa88e01ef8b5c53","tarball":"https://registry.npmjs.org/@sockudo/client/-/client-1.1.0.tgz","fileCount":151,"integrity":"sha512-UUBTi6QHfxIrGfj+6hzK+FnJNSXZIZx9lR7Igmqlds9CFNDU3/nbzhuDjZ9fuxC7OeI7VS6LqhvhOvDbEt/YNQ==","signatures":[{"sig":"MEUCIBSN4L02BJQPHWDbyNtn/iq/S7ESDBLi3qvoRVBPXxSvAiEA6VQYpaF6F3+7dgur3dRr2dFyp82ES2c+qs0+7oMe1j0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@sockudo%2fclient@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2772759},"main":"dist/node/pusher.js","type":"module","types":"index.d.ts","browser":"dist/web/pusher.mjs","engines":{"bun":">=1.0.0","node":">=22"},"exports":{".":{"node":"./dist/node/pusher.js","types":"./index.d.ts","import":"./dist/web/pusher.mjs","browser":"./dist/web/pusher.mjs","default":"./dist/web/pusher.mjs","react-native":"./dist/react-native/pusher.js"},"./filter":{"types":"./types/core/channels/filter.d.ts","import":"./dist/web/filter.mjs","default":"./dist/web/filter.mjs"},"./worker":{"types":"./worker/index.d.ts","default":"./worker/index.js"},"./react-native":{"types":"./react-native/index.d.ts","default":"./react-native/index.js"},"./with-encryption":{"types":"./with-encryption/index.d.ts","default":"./with-encryption/index.js"},"./worker/with-encryption":{"types":"./worker/with-encryption/index.d.ts","default":"./worker/with-encryption/index.js"}},"gitHead":"23b460df6c7c53a6a44e1f86c2851d3cadef344f","scripts":{"lint":"oxlint --config .oxlintrc.json src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts","test":"bun test ./test","build":"bun run clean && bun run build:web","check":"bun run typecheck && bun run lint && bun test","clean":"rm -rf dist","format":"oxfmt src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts","lint:fix":"oxlint --config .oxlintrc.json --fix src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts","build:all":"bun run clean && bun run build:web && bun run build:node","build:web":"vite build && vite build --config vite.config.filter.ts && vite build --config vite.config.with-encryption.ts","typecheck":"tsc --noEmit","build:node":"vite build --config vite.config.node.ts && vite build --config vite.config.filter.node.ts && vite build --config vite.config.worker.ts && vite build --config vite.config.worker.with-encryption.ts && vite build --config vite.config.react-native.ts","test:watch":"bun test --watch ./test","build:watch":"vite build --watch","format:check":"oxfmt --check src test vite.config.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts"},"_npmUser":{"name":"sockudorealtime","email":"radu@sockudo.io"},"repository":{"url":"git+https://github.com/sockudo/sockudo-js.git","type":"git"},"_npmVersion":"10.9.4","description":"Sockudo JavaScript client full port on Bun + Oxc + Vite(Rolldown)","directories":{},"_nodeVersion":"22.22.0","dependencies":{"tweetnacl":"^1.0.3","fossil-delta":"^2.0.0","@stablelib/utf8":"^1.0.0","@stablelib/base64":"^1.0.0","@ably/vcdiff-decoder":"^1.0.6"},"react-native":"dist/react-native/pusher.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.9","devDependencies":{"oxfmt":"^0.4.0","oxlint":"^0.15.14","@types/bun":"latest","typescript":"^5.9.2","@types/node":"^20.19.0","rolldown-vite":"^7.3.0","@react-native-community/netinfo":"^5.9.7"},"peerDependencies":{"@react-native-community/netinfo":"*"},"peerDependenciesMeta":{"@react-native-community/netinfo":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/client_1.1.0_1770841530873_0.9356448516457192","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@sockudo/client","version":"1.3.0","keywords":["sockudo","pusher-protocol-compatible","websocket","events","pubsub","bun","node"],"license":"MIT","_id":"@sockudo/client@1.3.0","maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"homepage":"https://github.com/sockudo/sockudo-js#readme","bugs":{"url":"https://github.com/sockudo/sockudo-js/issues"},"dist":{"shasum":"d5fe6dad1b27209fd6672b994071a35528926a45","tarball":"https://registry.npmjs.org/@sockudo/client/-/client-1.3.0.tgz","fileCount":163,"integrity":"sha512-IlXMb7Sv+RBNcJMvFTGoNo8exgy8fSxQcMLXOJsBDi4Tq/KPwJUFodti/ClaPSYmdFnNquPrankfSv8fpcEITg==","signatures":[{"sig":"MEYCIQCLnIcM/XKm+4ldUoyI1MAQnbyFqJ0NhRT5un3xOYlXpAIhAN4RPWRDz6V4OfnsOWTkNRs9jX7CGQaqUZC4h7xzdxyt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@sockudo%2fclient@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":7900256},"main":"dist/node/sockudo.js","type":"module","types":"index.d.ts","browser":"dist/web/sockudo.mjs","engines":{"bun":">=1.0.0","node":">=22"},"exports":{".":{"node":"./dist/node/sockudo.js","types":"./index.d.ts","import":"./dist/web/sockudo.mjs","browser":"./dist/web/sockudo.mjs","default":"./dist/web/sockudo.mjs","nativescript":"./dist/nativescript/sockudo.js","react-native":"./dist/react-native/sockudo.js"},"./vue":{"types":"./vue/index.d.ts","default":"./vue/index.js"},"./react":{"types":"./react/index.d.ts","default":"./react/index.js"},"./filter":{"types":"./types/core/channels/filter.d.ts","import":"./dist/web/filter.mjs","default":"./dist/web/filter.mjs"},"./worker":{"types":"./worker/index.d.ts","default":"./worker/index.js"},"./nativescript":{"types":"./nativescript/index.d.ts","default":"./nativescript/index.js"},"./react-native":{"types":"./react-native/index.d.ts","default":"./react-native/index.js"},"./with-encryption":{"types":"./with-encryption/index.d.ts","default":"./with-encryption/index.js"},"./worker/with-encryption":{"types":"./worker/with-encryption/index.d.ts","default":"./worker/with-encryption/index.js"}},"gitHead":"1455d40e85964c6186923d7f03bc6daf22ac46a8","scripts":{"lint":"oxlint --config .oxlintrc.json src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","test":"vitest run","build":"bun run clean && bun run build:web","check":"bun run typecheck && bun run lint && bun run test","clean":"rm -rf dist","format":"oxfmt src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","lint:fix":"oxlint --config .oxlintrc.json --fix src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","build:all":"bun run clean && bun run build:web && bun run build:node","build:web":"vite build && vite build --config vite.config.react.ts && vite build --config vite.config.vue.ts && vite build --config vite.config.filter.ts && vite build --config vite.config.with-encryption.ts","typecheck":"tsc --noEmit","build:node":"vite build --config vite.config.node.ts && vite build --config vite.config.filter.node.ts && vite build --config vite.config.worker.ts && vite build --config vite.config.worker.with-encryption.ts && vite build --config vite.config.react-native.ts && vite build --config vite.config.nativescript.ts","test:watch":"vitest","build:watch":"vite build --watch","format:check":"oxfmt --check src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts"},"_npmUser":{"name":"sockudorealtime","email":"radu@sockudo.io"},"repository":{"url":"git+https://github.com/sockudo/sockudo-js.git","type":"git"},"_npmVersion":"10.9.7","description":"Sockudo JavaScript client full port on Bun + Oxc + Vite 8","directories":{},"_nodeVersion":"22.22.2","dependencies":{"tweetnacl":"^1.0.3","protobufjs":"^7.5.4","fossil-delta":"^2.0.0","@stablelib/utf8":"^1.0.0","@msgpack/msgpack":"^3.1.2","@stablelib/base64":"^1.0.0","@ably/vcdiff-decoder":"^1.0.6"},"nativescript":"dist/nativescript/sockudo.js","react-native":"dist/react-native/sockudo.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.9","devDependencies":{"vue":"^3.5.22","vite":"^8.0.3","jsdom":"^26.1.0","oxfmt":"^0.4.0","react":"^19.2.0","oxlint":"^0.15.14","vitest":"^4.1.2","react-dom":"^19.2.0","@types/bun":"latest","typescript":"^5.9.2","@types/node":"^20.19.0","@types/react":"^19.2.2","@types/react-dom":"^19.2.2","@valor/nativescript-websockets":"^2.0.3","@react-native-community/netinfo":"^5.9.7"},"peerDependencies":{"vue":">=3.4","react":">=18","react-dom":">=18","@valor/nativescript-websockets":"*","@react-native-community/netinfo":"*"},"peerDependenciesMeta":{"vue":{"optional":true},"react":{"optional":true},"react-dom":{"optional":true},"@valor/nativescript-websockets":{"optional":true},"@react-native-community/netinfo":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/client_1.3.0_1776341268108_0.8885623164714693","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@sockudo/client","version":"2.0.0","keywords":["sockudo","pusher-protocol-compatible","websocket","events","pubsub","bun","node"],"license":"MIT","_id":"@sockudo/client@2.0.0","maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"homepage":"https://github.com/sockudo/sockudo/tree/master/client-sdks/sockudo-js#readme","bugs":{"url":"https://github.com/sockudo/sockudo/issues"},"dist":{"shasum":"98b922d251d6cdbdf561c818b15618bff1eac652","tarball":"https://registry.npmjs.org/@sockudo/client/-/client-2.0.0.tgz","fileCount":164,"integrity":"sha512-npJhVTDq1tl8BJFXlf9APkxvtBSEiuQ9JWNlGDmGTHCZNmxtknlzQ5l+aOHYs2sarwa1GmUOHHFSvIwx+atKlg==","signatures":[{"sig":"MEQCIAh6mi8CFa39NbbotdhvteYvjb14RBvMDcRrH0MgATp4AiBR2RIo2e/eipGcF/5gq+d9l23Ik29XGKy9Y12NEsf06A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@sockudo%2fclient@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":8965709},"main":"dist/node/sockudo.js","type":"module","types":"index.d.ts","browser":"dist/web/sockudo.mjs","engines":{"bun":">=1.0.0","node":">=22"},"exports":{".":{"node":"./dist/node/sockudo.js","types":"./index.d.ts","import":"./dist/web/sockudo.mjs","browser":"./dist/web/sockudo.mjs","default":"./dist/web/sockudo.mjs","nativescript":"./dist/nativescript/sockudo.js","react-native":"./dist/react-native/sockudo.js"},"./vue":{"types":"./vue/index.d.ts","default":"./vue/index.js"},"./react":{"types":"./react/index.d.ts","default":"./react/index.js"},"./filter":{"types":"./types/core/channels/filter.d.ts","import":"./dist/web/filter.mjs","default":"./dist/web/filter.mjs"},"./worker":{"types":"./worker/index.d.ts","default":"./worker/index.js"},"./nativescript":{"types":"./nativescript/index.d.ts","default":"./nativescript/index.js"},"./react-native":{"types":"./react-native/index.d.ts","default":"./react-native/index.js"},"./with-encryption":{"types":"./with-encryption/index.d.ts","default":"./with-encryption/index.js"},"./worker/with-encryption":{"types":"./worker/with-encryption/index.d.ts","default":"./worker/with-encryption/index.js"}},"gitHead":"ff3d5f949f336b46c538c85b2ad91d7b9d862e97","scripts":{"lint":"oxlint --config .oxlintrc.json src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","test":"vitest run","build":"bun run clean && bun run build:web","check":"bun run typecheck && bun run lint && bun run test","clean":"rm -rf dist","format":"oxfmt src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","lint:fix":"oxlint --config .oxlintrc.json --fix src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","build:all":"bun run clean && bun run build:web && bun run build:node","build:web":"vite build && vite build --config vite.config.react.ts && vite build --config vite.config.vue.ts && vite build --config vite.config.filter.ts && vite build --config vite.config.with-encryption.ts","typecheck":"tsc --noEmit","build:node":"vite build --config vite.config.node.ts && vite build --config vite.config.filter.node.ts && vite build --config vite.config.worker.ts && vite build --config vite.config.worker.with-encryption.ts && vite build --config vite.config.react-native.ts && vite build --config vite.config.nativescript.ts","test:watch":"vitest","build:watch":"vite build --watch","format:check":"oxfmt --check src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8b6795fd-845b-4cdd-bb12-93748652f28f"}},"overrides":{"yaml":"^2.9.0","picomatch":"^4.0.4"},"repository":{"url":"git+https://github.com/sockudo/sockudo.git","type":"git","directory":"client-sdks/sockudo-js"},"_npmVersion":"11.17.0","description":"Sockudo JavaScript client full port on Bun + Oxc + Vite 8","directories":{},"_nodeVersion":"24.16.0","dependencies":{"tweetnacl":"^1.0.3","protobufjs":"^7.6.4","fossil-delta":"^2.0.0","@stablelib/utf8":"^1.0.0","@msgpack/msgpack":"^3.1.2","@stablelib/base64":"^1.0.0","@ably/vcdiff-decoder":"^1.0.6"},"nativescript":"dist/nativescript/sockudo.js","react-native":"dist/react-native/sockudo.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.9","devDependencies":{"vue":"^3.5.38","vite":"^8.0.16","jsdom":"^29.1.1","oxfmt":"^0.55.0","react":"^19.2.7","oxlint":"^1.70.0","vitest":"^4.1.9","react-dom":"^19.2.7","@types/bun":"^1.3.9","typescript":"^5.9.2","@types/node":"^24.0.0","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@valor/nativescript-websockets":"^2.0.3"},"peerDependencies":{"vue":">=3.4","react":">=18","react-dom":">=18","@valor/nativescript-websockets":"*","@react-native-community/netinfo":"*"},"peerDependenciesMeta":{"vue":{"optional":true},"react":{"optional":true},"react-dom":{"optional":true},"@valor/nativescript-websockets":{"optional":true},"@react-native-community/netinfo":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/client_2.0.0_1781984071485_0.8496071744323563","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@sockudo/client","version":"2.1.0","keywords":["sockudo","pusher-protocol-compatible","websocket","events","pubsub","bun","node"],"license":"MIT","_id":"@sockudo/client@2.1.0","maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"homepage":"https://github.com/sockudo/sockudo/tree/master/client-sdks/sockudo-js#readme","bugs":{"url":"https://github.com/sockudo/sockudo/issues"},"dist":{"shasum":"4fcfa90f3df5853c2b9dcbdb844794f9a8dba006","tarball":"https://registry.npmjs.org/@sockudo/client/-/client-2.1.0.tgz","fileCount":164,"integrity":"sha512-T6a/8/05RzLNqF3KrD0zRLDyV35/DvXqArb6Xv61WsUUGOZr1RWRtHt9jZTdUj3CwqnnNtxoJwyaywf3qyoRJA==","signatures":[{"sig":"MEUCIEpBUwX8WlqlZrWHlKGj6UgqZqIErORx3PhomvR3RD7vAiEAxA1HB4LICkNJu2XdyFM2a4P+AOtIzhO2RcoBXhofM8w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@sockudo%2fclient@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":9037029},"main":"dist/node/sockudo.js","type":"module","types":"index.d.ts","browser":"dist/web/sockudo.mjs","engines":{"bun":">=1.0.0","node":">=22"},"exports":{".":{"node":"./dist/node/sockudo.js","types":"./index.d.ts","import":"./dist/web/sockudo.mjs","browser":"./dist/web/sockudo.mjs","default":"./dist/web/sockudo.mjs","nativescript":"./dist/nativescript/sockudo.js","react-native":"./dist/react-native/sockudo.js"},"./vue":{"types":"./vue/index.d.ts","default":"./vue/index.js"},"./react":{"types":"./react/index.d.ts","default":"./react/index.js"},"./filter":{"types":"./types/core/channels/filter.d.ts","import":"./dist/web/filter.mjs","default":"./dist/web/filter.mjs"},"./worker":{"types":"./worker/index.d.ts","default":"./worker/index.js"},"./nativescript":{"types":"./nativescript/index.d.ts","default":"./nativescript/index.js"},"./react-native":{"types":"./react-native/index.d.ts","default":"./react-native/index.js"},"./with-encryption":{"types":"./with-encryption/index.d.ts","default":"./with-encryption/index.js"},"./worker/with-encryption":{"types":"./worker/with-encryption/index.d.ts","default":"./worker/with-encryption/index.js"}},"gitHead":"1d80be3685abb0b3e878a3704595b2538748b53a","scripts":{"lint":"oxlint --config .oxlintrc.json src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","test":"vitest run","build":"bun run clean && bun run build:web","check":"bun run typecheck && bun run lint && bun run test","clean":"rm -rf dist","format":"oxfmt src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","lint:fix":"oxlint --config .oxlintrc.json --fix src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","build:all":"bun run clean && bun run build:web && bun run build:node","build:web":"vite build && vite build --config vite.config.react.ts && vite build --config vite.config.vue.ts && vite build --config vite.config.filter.ts && vite build --config vite.config.with-encryption.ts","typecheck":"tsc --noEmit","build:node":"vite build --config vite.config.node.ts && vite build --config vite.config.filter.node.ts && vite build --config vite.config.worker.ts && vite build --config vite.config.worker.with-encryption.ts && vite build --config vite.config.react-native.ts && vite build --config vite.config.nativescript.ts","test:watch":"vitest","build:watch":"vite build --watch","format:check":"oxfmt --check src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8b6795fd-845b-4cdd-bb12-93748652f28f"}},"overrides":{"yaml":"^2.9.0","picomatch":"^4.0.4"},"repository":{"url":"git+https://github.com/sockudo/sockudo.git","type":"git","directory":"client-sdks/sockudo-js"},"_npmVersion":"11.17.0","description":"Sockudo JavaScript client full port on Bun + Oxc + Vite 8","directories":{},"_nodeVersion":"24.17.0","dependencies":{"tweetnacl":"^1.0.3","protobufjs":"^7.6.4","fossil-delta":"^2.0.0","@stablelib/utf8":"^1.0.0","@msgpack/msgpack":"^3.1.2","@stablelib/base64":"^1.0.0","@ably/vcdiff-decoder":"^1.0.6"},"nativescript":"dist/nativescript/sockudo.js","react-native":"dist/react-native/sockudo.js","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.9","devDependencies":{"vue":"^3.5.38","vite":"^8.0.16","jsdom":"^29.1.1","oxfmt":"^0.55.0","react":"^19.2.7","oxlint":"^1.70.0","vitest":"^4.1.9","react-dom":"^19.2.7","@types/bun":"^1.3.9","typescript":"^5.9.2","@types/node":"^24.0.0","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@valor/nativescript-websockets":"^2.0.3"},"peerDependencies":{"vue":">=3.4","react":">=18","react-dom":">=18","@valor/nativescript-websockets":"*","@react-native-community/netinfo":"*"},"peerDependenciesMeta":{"vue":{"optional":true},"react":{"optional":true},"react-dom":{"optional":true},"@valor/nativescript-websockets":{"optional":true},"@react-native-community/netinfo":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/client_2.1.0_1782635017513_0.24245205828074967","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@sockudo/client","version":"2.2.0","description":"Sockudo JavaScript client full port on Bun + Oxc + Vite 8","type":"module","packageManager":"bun@1.3.9","types":"index.d.ts","main":"dist/node/sockudo.js","browser":"dist/web/sockudo.mjs","react-native":"dist/react-native/sockudo.js","nativescript":"dist/nativescript/sockudo.js","engines":{"node":">=22","bun":">=1.0.0"},"exports":{".":{"types":"./index.d.ts","node":"./dist/node/sockudo.js","browser":"./dist/web/sockudo.mjs","import":"./dist/web/sockudo.mjs","react-native":"./dist/react-native/sockudo.js","nativescript":"./dist/nativescript/sockudo.js","default":"./dist/web/sockudo.mjs"},"./filter":{"types":"./types/core/channels/filter.d.ts","import":"./dist/web/filter.mjs","default":"./dist/web/filter.mjs"},"./with-encryption":{"types":"./with-encryption/index.d.ts","default":"./with-encryption/index.js"},"./worker":{"types":"./worker/index.d.ts","default":"./worker/index.js"},"./worker/with-encryption":{"types":"./worker/with-encryption/index.d.ts","default":"./worker/with-encryption/index.js"},"./react-native":{"types":"./react-native/index.d.ts","default":"./react-native/index.js"},"./react":{"types":"./react/index.d.ts","default":"./react/index.js"},"./vue":{"types":"./vue/index.d.ts","default":"./vue/index.js"},"./nativescript":{"types":"./nativescript/index.d.ts","default":"./nativescript/index.js"}},"scripts":{"clean":"rm -rf dist","build":"bun run clean && bun run build:web","build:all":"bun run clean && bun run build:web && bun run build:node","build:web":"vite build && vite build --config vite.config.react.ts && vite build --config vite.config.vue.ts && vite build --config vite.config.filter.ts && vite build --config vite.config.with-encryption.ts","build:node":"vite build --config vite.config.node.ts && vite build --config vite.config.filter.node.ts && vite build --config vite.config.worker.ts && vite build --config vite.config.worker.with-encryption.ts && vite build --config vite.config.react-native.ts && vite build --config vite.config.nativescript.ts","build:watch":"vite build --watch","check":"bun run typecheck && bun run lint && bun run test","typecheck":"tsc --noEmit","lint":"oxlint --config .oxlintrc.json src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","lint:fix":"oxlint --config .oxlintrc.json --fix src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","format":"oxfmt src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","format:check":"oxfmt --check src test vite.config.ts vite.config.react.ts vite.config.vue.ts vite.config.filter.ts vite.config.node.ts vite.config.filter.node.ts vite.config.with-encryption.ts vite.config.worker.ts vite.config.worker.with-encryption.ts vite.config.react-native.ts vite.config.nativescript.ts vitest.config.ts","test":"vitest run","test:watch":"vitest"},"keywords":["sockudo","pusher-protocol-compatible","websocket","events","pubsub","bun","node"],"repository":{"type":"git","url":"git+https://github.com/sockudo/sockudo.git","directory":"client-sdks/sockudo-js"},"bugs":{"url":"https://github.com/sockudo/sockudo/issues"},"homepage":"https://github.com/sockudo/sockudo/tree/master/client-sdks/sockudo-js#readme","license":"MIT","publishConfig":{"access":"public"},"dependencies":{"@ably/vcdiff-decoder":"^1.0.6","@msgpack/msgpack":"^3.1.2","@stablelib/base64":"^1.0.0","@stablelib/utf8":"^1.0.0","fossil-delta":"^2.0.0","protobufjs":"^7.6.5","tweetnacl":"^1.0.3"},"peerDependencies":{"@react-native-community/netinfo":"*","@valor/nativescript-websockets":"*","react":">=18","react-dom":">=18","vue":">=3.4"},"peerDependenciesMeta":{"@react-native-community/netinfo":{"optional":true},"@valor/nativescript-websockets":{"optional":true},"react":{"optional":true},"react-dom":{"optional":true},"vue":{"optional":true}},"devDependencies":{"@types/bun":"^1.3.9","@types/node":"^24.0.0","@types/react":"^19.2.17","@types/react-dom":"^19.2.3","@valor/nativescript-websockets":"^2.0.3","jsdom":"^29.1.1","oxfmt":"^0.55.0","oxlint":"^1.70.0","react":"^19.2.7","react-dom":"^19.2.7","typescript":"^5.9.2","vite":"^8.0.16","vitest":"^4.1.9","vue":"^3.5.38"},"overrides":{"nanoid":"^3.3.18","picomatch":"^4.0.4","postcss":"^8.5.26","undici":"^7.29.0","yaml":"^2.9.0"},"gitHead":"c69e23af4738e162f0e1bb0089992e00621cf075","_id":"@sockudo/client@2.2.0","_nodeVersion":"24.19.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-IBuoMSL+SCJmqmdHgS6qsUHwBM/c/eBhXQZvGO8u7QwOKkNQExpBrvmkhfgS/A5L9ObNFRH622DG5Mj3Ctkn+Q==","shasum":"5144164817808695c1d6147259477b1929f1ada2","tarball":"https://registry.npmjs.org/@sockudo/client/-/client-2.2.0.tgz","fileCount":165,"unpackedSize":9297549,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@sockudo%2fclient@2.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCVHH+YFuJqTEVIvrRjvnxlI0dkFWkxEo9bLwfe2wCQJgIgRW0yKPIUp1EP5W0LI0pCQQHpz5zYB6wminXN6wn4wxs="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:8b6795fd-845b-4cdd-bb12-93748652f28f"}},"directories":{},"maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/client_2.2.0_1787292876707_0.44337874608307093"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-11T19:52:15.525Z","modified":"2026-08-21T06:14:37.232Z","1.0.0":"2026-02-11T19:52:15.802Z","1.1.0":"2026-02-11T20:25:31.080Z","1.3.0":"2026-04-16T12:07:48.360Z","2.0.0":"2026-06-20T19:34:31.692Z","2.1.0":"2026-06-28T08:23:37.694Z","2.2.0":"2026-08-21T06:14:36.887Z"},"bugs":{"url":"https://github.com/sockudo/sockudo/issues"},"license":"MIT","homepage":"https://github.com/sockudo/sockudo/tree/master/client-sdks/sockudo-js#readme","keywords":["sockudo","pusher-protocol-compatible","websocket","events","pubsub","bun","node"],"repository":{"type":"git","url":"git+https://github.com/sockudo/sockudo.git","directory":"client-sdks/sockudo-js"},"description":"Sockudo JavaScript client full port on Bun + Oxc + Vite 8","maintainers":[{"name":"sockudorealtime","email":"radu@sockudo.io"}],"readme":"# @sockudo/client\n\nSockudo JavaScript client SDK with modern runtime targets:\n- Web\n- Node.js\n- Web Worker\n- React hooks\n- Vue composables\n- React Native\n- NativeScript\n\n## Install\n\nFor apps, install the published package:\n\n```bash\nnpm install @sockudo/client\n# or: bun add @sockudo/client\n# or: pnpm add @sockudo/client\n```\n\nFor contributors working inside this repository, build the SDK from its package directory:\n\n```bash\ncd client-sdks/sockudo-js\nbun install\nbun run build:all\n```\n\n## Runtime Imports\n\nUse the entrypoint that matches your runtime:\n\n```ts\n// Browser / default\nimport Sockudo from \"@sockudo/client\";\n\n// Filter helper entrypoint\nimport { Filter } from \"@sockudo/client/filter\";\n\n// With encryption\nimport SockudoEncrypted from \"@sockudo/client/with-encryption\";\n\n// Worker\nimport WorkerSockudo from \"@sockudo/client/worker\";\n\n// Worker with encryption\nimport WorkerEncrypted from \"@sockudo/client/worker/with-encryption\";\n\n// React hooks\nimport { SockudoProvider, useChannel } from \"@sockudo/client/react\";\n\n// Vue composables\nimport { createSockudoPlugin, useChannel as useSockudoChannel } from \"@sockudo/client/vue\";\n\n// React Native\nimport ReactNativeSockudo from \"@sockudo/client/react-native\";\n\n// NativeScript\nimport NativeScriptSockudo from \"@sockudo/client/nativescript\";\n```\n\nThe package also exposes runtime-aware fields in `package.json` (`main`, `browser`, `react-native`, `nativescript`, `exports`) so bundlers can resolve correctly.\n\n## Quick Start\n\n```ts\nimport Sockudo from \"@sockudo/client\";\n\nconst sockudo = new Sockudo(\"app-key\", {\n  wsHost: \"your-sockudo-host\",\n  wsPort: 6001,\n  wssPort: 6001,\n  forceTLS: true,\n  enabledTransports: [\"ws\", \"wss\"],\n});\n\nconst channel = sockudo.subscribe(\"public-updates\");\nchannel.bind(\"message\", (payload: unknown) => {\n  console.log(payload);\n});\n```\n\nThe default client mode is Protocol V1 compatibility (`protocol=7`). Opt into Protocol V2 explicitly when you want Sockudo-native event prefixes and V2-only features.\n\n```ts\nconst sockudoV2 = new Sockudo(\"app-key\", {\n  wsHost: \"your-sockudo-host\",\n  wsPort: 6001,\n  forceTLS: true,\n  protocolVersion: 2,\n});\n```\n\nProtocol V2 heartbeat behavior:\n\n- the server uses native WebSocket ping/pong frames for automatic liveness\n- browser-style runtimes that do not expose native ping APIs may still use lightweight `sockudo:ping` / `sockudo:pong` fallback messages for client-side activity checks\n- fallback heartbeat messages are not part of V2 broadcast continuity and do not carry `message_id`, `serial`, or `stream_id`\n\nProtocol V2 also supports `wireFormat: \"messagepack\"` and\n`wireFormat: \"protobuf\"`. Both preserve `Uint8Array` message data as native\nbinary values. The MessagePack representation is the additive tagged variant\n`[\"binary\", <bin>]`; existing wire variants remain unchanged.\n\n### Capability-token authentication\n\nProtocol V2 can authenticate the WebSocket with a scoped capability token.\nUse `authCallback` (or `authUrl`) when the client must refresh credentials:\n\n```ts\nconst client = new Sockudo(\"app-key\", {\n  cluster: \"local\",\n  protocolVersion: 2,\n  token: initialToken,\n  authCallback: async ({ socketId, reason }) => {\n    return fetchCapabilityToken({ socketId, reason });\n  },\n});\n```\n\nThe optional static `token` is used for the first connection. Provider-backed\ntokens are fetched again before reconnects and refreshed in place with\n`sockudo:auth` at 80% of a JWT's `iat`–`exp` lifetime. `authUrl` receives a\nJSON `POST` containing `{ socket_id, reason }` and must return either a token\nstring as JSON or an object containing `token` and optional expiry fields.\n\nCode `40142` refreshes only when a provider is configured; static tokens are\nnever resent in a refresh loop. Code `40160` emits `TokenRevokedError` and is\nnot retried in place. Token auth with Protocol V1 is rejected during client\nconstruction.\n\n## Reconnection\n\nUnexpected disconnects emit the distinct `reconnecting` state and retry with a\nbounded quadratic delay: 0s, 1s, 4s, 9s, up to 120s. Protocol retry and\nTLS-upgrade close codes reconnect immediately. The default retry limit is six;\nset `maxReconnectAttempts: null` for unlimited retries.\n\n```ts\nconst client = new Sockudo(\"app-key\", {\n  cluster: \"local\",\n  maxReconnectAttempts: 10,\n  maxReconnectGapInSeconds: 60,\n});\n\nclient.connection.bind(\"reconnecting\", () => {\n  console.log(\"reconnecting\");\n});\n```\n\nThe attempt counter resets after a successful connection and on explicit\n`connect()` or `disconnect()` calls.\n\n## Features\n\nProtocol V2 subscriptions can combine event names, tag filters, and a bounded\nJMESPath expression. All supplied components must match:\n\n```ts\nclient.subscribe(\"orders.*\", {\n  events: [\"order.updated\"],\n  filter: Filter.eq(\"region\", \"eu\"),\n  expression: 'data.total >= `100` && headers.priority == `\"high\"`',\n});\n```\n\n- Pusher-protocol-compatible client surface\n- Protocol V1 compatibility by default\n- WebSocket-first connection strategy\n- Fetch-first auth/timeline integrations\n- ESM-first package outputs\n- Runtime-specific builds for web/node/worker/react-native/nativescript\n- Built-in React hooks via `@sockudo/client/react`\n- Built-in Vue composables via `@sockudo/client/vue`\n- Continuity-aware recovery positions and subscribe-time rewind in Protocol V2\n\n## Recovery And Rewind\n\n```ts\nconst client = new Sockudo(\"app-key\", {\n  wsHost: \"127.0.0.1\",\n  wsPort: 6001,\n  forceTLS: false,\n  protocolVersion: 2,\n  connectionRecovery: true,\n});\n\nconst channel = client.subscribe(\"market:BTC\", {\n  rewind: { seconds: 30 },\n});\n\nchannel.bind(\"message\", () => {\n  console.log(client.getRecoveryPosition(\"market:BTC\"));\n});\n\nclient.bind(\"sockudo:resume_success\", (payload) => {\n  console.log(payload.recovered, payload.failed);\n});\n\nchannel.bind(\"sockudo:rewind_complete\", (payload) => {\n  console.log(payload.historical_count, payload.complete);\n});\n```\n\n## Mutable Messages (Release 4.3)\n\nProtocol V2 mutable messages use explicit action events:\n\n- `sockudo:message.update`\n- `sockudo:message.delete`\n- `sockudo:message.append`\n\nClient interpretation rules:\n\n- `message.update`: replace local state with the full payload in the event\n- `message.delete`: treat the event as the latest visible version; the payload may be `null`\n- `message.append`: concatenate the incoming string fragment onto your current local string state\n\nIf you do not already have a string base for `message.append`, fetch the latest visible message first and seed local state before applying more appends.\n\nThe JS SDK exports helpers for this:\n\n```ts\nimport Sockudo, {\n  isMutableMessageEvent,\n  reduceMutableMessageEvent,\n  type MutableMessageState,\n} from \"@sockudo/client\";\n\nconst client = new Sockudo(\"app-key\", {\n  wsHost: \"127.0.0.1\",\n  wsPort: 6001,\n  forceTLS: false,\n  protocolVersion: 2,\n});\n\nlet state: MutableMessageState | null = null;\n\nclient.subscribe(\"chat:room-1\").bind_global((eventName, payload) => {\n  if (!isMutableMessageEvent(payload)) {\n    return;\n  }\n  state = reduceMutableMessageEvent(state, payload);\n  console.log(state?.messageSerial, state?.action, state?.data);\n});\n```\n\nVersion-history consumption:\n\n- consume `GET /apps/{appId}/channels/{channelName}/messages/{messageSerial}` when you need the latest visible state\n- consume `GET /apps/{appId}/channels/{channelName}/messages/{messageSerial}/versions` when you need preserved historical versions\n- process versions in `version_serial` order; the last version is the winning visible state\n\nProxy-backed read helpers:\n\nConfigure `versionedMessages.endpoint` when you want first-class helper methods without exposing server credentials in the client. The endpoint should accept a JSON POST body of the form `{ channel, messageSerial?, params?, action }` and proxy the request to Sockudo's REST API using server-side HMAC auth.\n\n```ts\nconst client = new Sockudo(\"app-key\", {\n  cluster: \"local\",\n  wsHost: \"127.0.0.1\",\n  wsPort: 6001,\n  forceTLS: false,\n  versionedMessages: {\n    endpoint: \"/sockudo/versioned\",\n  },\n});\n\nconst channel = client.subscribe(\"chat:room-1\");\n\nconst latest = await channel.getMessage(\"message-serial\");\nconst versions = await channel.getMessageVersions(\"message-serial\", {\n  limit: 20,\n  direction: \"oldest_first\",\n});\nconst history = await channel.channelHistory({\n  limit: 50,\n  direction: \"newest_first\",\n});\n```\n\n## React Hooks\n\nInstall the framework peer dependencies:\n\n```bash\nnpm install @sockudo/client react react-dom\n```\n\n```ts\nimport React from \"react\";\nimport Sockudo from \"@sockudo/client\";\nimport { SockudoProvider, useChannel } from \"@sockudo/client/react\";\n\nconst client = new Sockudo(\"app-key\", {\n  wsHost: \"127.0.0.1\",\n  wsPort: 6001,\n  forceTLS: false,\n});\n\nclient.connect();\n\nfunction PresencePanel() {\n  const { subscribed, members } = useChannel(\"presence-room\");\n\n  return (\n    <div>\n      <div>Subscribed: {String(subscribed)}</div>\n      <div>Members: {members?.length ?? 0}</div>\n    </div>\n  );\n}\n\nexport function App() {\n  return (\n    <SockudoProvider client={client}>\n      <PresencePanel />\n    </SockudoProvider>\n  );\n}\n```\n\nAvailable React exports:\n- `SockudoProvider`\n- `useSockudo`\n- `useSockudoEvent`\n- `useChannel`\n- `usePresenceChannel`\n\n## Vue Composables\n\nInstall the framework peer dependency:\n\n```bash\nnpm install @sockudo/client vue\n```\n\n```ts\nimport { createApp, defineComponent, h } from \"vue\";\nimport Sockudo from \"@sockudo/client\";\nimport { createSockudoPlugin, useChannel } from \"@sockudo/client/vue\";\n\nconst client = new Sockudo(\"app-key\", {\n  wsHost: \"127.0.0.1\",\n  wsPort: 6001,\n  forceTLS: false,\n});\n\nclient.connect();\n\nconst PresencePanel = defineComponent({\n  setup() {\n    const { subscribed, members } = useChannel(\"presence-room\");\n    return () =>\n      h(\"div\", [\n        h(\"div\", `Subscribed: ${String(subscribed.value)}`),\n        h(\"div\", `Members: ${members.value?.length ?? 0}`),\n      ]);\n  },\n});\n\ncreateApp(PresencePanel).use(createSockudoPlugin(client)).mount(\"#app\");\n```\n\nAvailable Vue exports:\n- `createSockudoPlugin`\n- `provideSockudo`\n- `useSockudo`\n- `useSockudoEvent`\n- `useChannel`\n- `usePresenceChannel`\n\n## React Native Notes\n\n- React Native build output is `dist/react-native/sockudo.js`\n- Package exposes both:\n  - root `react-native` resolution\n  - explicit `@sockudo/client/react-native` subpath\n- `@react-native-community/netinfo` is an optional peer dependency\n- React Native support remains inside `@sockudo/client`; React and Vue integrations stay as subpath exports in the same package\n\n## NativeScript Notes\n\n- Install the NativeScript websocket polyfill:\n\n```bash\nnpm install @sockudo/client @valor/nativescript-websockets\n```\n\n- Import `@sockudo/client/nativescript` to automatically load the websocket polyfill before the SDK.\n- NativeScript build output is `dist/nativescript/sockudo.js`\n- Package exposes both:\n  - root `nativescript` resolution\n  - explicit `@sockudo/client/nativescript` subpath\n\n## Development\n\n### Requirements\n\n- Bun `>=1.0.0`\n- Node.js `>=22`\n\n### Commands\n\n```bash\n# typecheck + lint + tests\nbun run check\n\n# typecheck only\nbun run typecheck\n\n# lint\nbun run lint\n\n# format\nbun run format\nbun run format:check\n\n# tests\nbun test\nbun run test:watch\n\n# builds\nbun run build\nbun run build:all\n```\n\n## Release Process\n\nGitHub Actions are managed from the monorepo root:\n\n- CI: `.github/workflows/sdk-ci.yml`\n- Publish: `.github/workflows/sdk-release.yml` with tag `client-js-vX.Y.Z`\n- Setup: see `docs/sdk-publishing-2026.md` for npm trusted publishing and provenance.\n\nThe release gate runs format checks, type checks, linting, tests, `build:all`, and `npm pack\n--dry-run` before publishing.\n\n## Repository\n\n- Source: `https://github.com/sockudo/sockudo/tree/main/client-sdks/sockudo-js`\n- Legacy repo: `https://github.com/sockudo/sockudo-js` (archived)\n- npm: `https://www.npmjs.com/package/@sockudo/client`\n","readmeFilename":"README.md"}