{"_id":"@bloonio/chat-client-core","name":"@bloonio/chat-client-core","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@bloonio/chat-client-core","version":"0.1.0","description":"Framework-agnostic TypeScript core for the bloonio chat widget + SDKs. WebSocket protocol, REST client, signed-token handling, branding config types.","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","require":"./dist/index.cjs","types":"./dist/index.d.ts"}},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","typecheck":"tsc --noEmit","lint":"tsc --noEmit --strict"},"keywords":["bloonio","chat","websocket","widget","sdk"],"author":{"name":"Bloonio"},"license":"MIT","devDependencies":{"@types/node":"^20.11.5","tsup":"^8.0.1","typescript":"^5.3.3","vitest":"^1.2.1"},"gitHead":"d28b0d22e90f63788d56cc2a8be24be3398f920f","_id":"@bloonio/chat-client-core@0.1.0","_nodeVersion":"26.3.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-/NmeRECMdYPFhYe9NbxTfTh4b0x5UBPyx9LjOGRQHrVqiquBkw2t7YdxRN+zRTYOU81pEy4atov+hDXqav8YiQ==","shasum":"b55a71f1a27ccc5dd552949901c013aa1e28980d","tarball":"https://registry.npmjs.org/@bloonio/chat-client-core/-/chat-client-core-0.1.0.tgz","fileCount":8,"unpackedSize":124751,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCXVnngozYb7LpgWOh8QIxBatKT3EYftqE2sKic7QBXAAIgL1iICQ9edZfva9f/sFE1WfTlIbHN81SHjOu7Phmb164="}]},"_npmUser":{"name":"bloonio.dev025","email":"dev.bloonio025@gmail.com"},"directories":{},"maintainers":[{"name":"bloonio.dev025","email":"dev.bloonio025@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/chat-client-core_0.1.0_1782640269380_0.9133211918921018"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-28T09:51:09.182Z","0.1.0":"2026-06-28T09:51:09.505Z","modified":"2026-06-28T09:51:09.786Z"},"maintainers":[{"name":"bloonio.dev025","email":"dev.bloonio025@gmail.com"}],"description":"Framework-agnostic TypeScript core for the bloonio chat widget + SDKs. WebSocket protocol, REST client, signed-token handling, branding config types.","keywords":["bloonio","chat","websocket","widget","sdk"],"author":{"name":"Bloonio"},"license":"MIT","readme":"# @bloonio/chat-client-core\n\nFramework-agnostic TypeScript core for the bloonio chat widget and framework\nSDKs (Preact widget, Angular, future React/Vue). Zero runtime dependencies.\n\n```\n@bloonio/chat-widget       (Preact embeddable, phase 9f)\n@bloonio/chat-angular      (Angular library, phase 9g)\n@bloonio/chat-react        (future, phase 15)        ─── all depend on ──┐\n@bloonio/chat-vue          (future)                                      │\n                                                                         ▼\n                                                       @bloonio/chat-client-core\n                                                       (this package)\n```\n\n## What's in here\n\n| Module | Surface |\n|---|---|\n| `client.ts` | `ChatClient` — REST wrapper for `/fetch/widget-config`, `/create/visitor-session`, `/identify/visitor` |\n| `ws.ts` | `WSClient` — WebSocket wrapper with typed handlers, ping/pong heartbeat, exponential-backoff reconnect |\n| `protocol.ts` | TS types for every inbound/outbound frame — mirrors `bloonio_chat_relay/app/modules/ws_hub/protocol.py` |\n| `config.ts` | `WidgetBootstrapConfig` + request/response shapes for the REST endpoints |\n| `storage.ts` | `TokenStorage` interface + `localStorage`-backed default (graceful fallback to in-memory in private mode) |\n| `errors.ts` | Typed error hierarchy (`BloonioChatError`, `…Network`, `…Server`, `…Auth`, `…Protocol`) |\n\n## Quick start\n\n```ts\nimport { ChatClient, WSClient } from '@bloonio/chat-client-core';\n\nconst client = new ChatClient({ baseUrl: 'https://chat-relay.example.com' });\n\n// 1. Bootstrap (no session — just config so we can render the launcher)\nconst cfg = await client.fetchWidgetConfig({\n  tenantId: '019e4ae7-...',\n  widgetPublicKey: 'pk_...',\n  origin: window.location.origin,\n});\n\n// 2. Create a visitor session (returns a signed JWT)\nconst sess = await client.createVisitorSession({\n  tenantId: cfg.tenant_id,\n  widgetPublicKey: 'pk_...',\n  origin: window.location.origin,\n});\n\n// 3. Open the WebSocket\nconst ws = new WSClient(\n  { baseUrl: 'https://chat-relay.example.com', visitorToken: sess.visitor_token },\n  {\n    onWelcome: (f) => console.log('welcome', f),\n    onMessage: (f) => console.log('msg', f),\n    onTyping: (f) => console.log('typing', f),\n    onError: (f) => console.error('proto error', f),\n  },\n);\nws.connect();\n\n// 4. Send a message\nws.send({ type: 'msg', client_msg_id: 'c1', content: 'Where is my order?' });\n```\n\n## Build + test\n\n```bash\nnpm install\nnpm run build       # tsup → dist/index.js (ESM) + index.cjs + index.d.ts\nnpm test            # vitest, no-watch\nnpm run typecheck   # tsc --noEmit\n```\n\n## Design notes\n\n- **Zero runtime deps.** Production bundle is whatever you write in `src/` —\n  tsup just transpiles + emits `.d.ts`. Consumer bundlers tree-shake naturally.\n- **No framework primitives.** `WSClient` exposes plain callback handlers,\n  not RxJS / signals / hooks. Each framework SDK wraps these into its idiom.\n- **Protocol parity with the relay.** Adding a new frame type means editing\n  both `src/protocol.ts` here and\n  `bloonio_chat_relay/app/modules/ws_hub/protocol.py` on the Python side —\n  one PR per change, kept lockstep.\n- **Reconnect strategy.** Exponential backoff (0.5s → 1s → 2s → 4s → 8s,\n  capped at 30s). Caps at `maxReconnectAttempts` (default Infinity). Manual\n  `close()` suppresses reconnect; transport-level failures don't.\n\n## Related\n\n- `bloonio_chat_relay/` — the relay this client talks to (Python, FastAPI)\n- `bloonio_chat_api/docs/12_PAAS_CONVERSION_PLAN.md` — full PaaS plan, this package is part of phase 9e\n","readmeFilename":"README.md","_rev":"1-2ca0fe99160857e1f543b0e4683c0811"}