{"_id":"@adaptivesoftwarellc/observability-client-js","name":"@adaptivesoftwarellc/observability-client-js","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@adaptivesoftwarellc/observability-client-js","version":"0.1.0","description":"Adaptive Observability frontend SDK. API surface mirrors SCH's analytics.ts so PostHog migration is import-line-only.","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./axios":{"types":"./dist/axios.d.ts","import":"./dist/axios.js","require":"./dist/axios.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js","require":"./dist/react.cjs"},"./replay":{"types":"./dist/replay.d.ts","import":"./dist/replay.js","require":"./dist/replay.cjs"}},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","lint":"tsc --noEmit"},"peerDependencies":{"axios":">=1.0.0","react":">=17.0.0"},"peerDependenciesMeta":{"axios":{"optional":true},"react":{"optional":true}},"devDependencies":{"@types/react":"^18.3.12","axios":"^1.7.7","react":"^18.3.1","tsup":"^8.3.0","typescript":"^5.6.3","vitest":"^2.1.4"},"_id":"@adaptivesoftwarellc/observability-client-js@0.1.0","gitHead":"457987df45ee259b9cc41a2c3b827fb7b2222aea","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-q+bjUP14tslScPK0T9B8AT6jtJ/+kaF5BjGSWbaeSXK7JWu5BBTow8KE9tHvhUDVOJPWBm3mtwePlH1HWXiZmQ==","shasum":"3aba1409c15514530ab91fe054a81e15aeb77bc0","tarball":"https://registry.npmjs.org/@adaptivesoftwarellc/observability-client-js/-/observability-client-js-0.1.0.tgz","fileCount":26,"unpackedSize":195700,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHwgLW+wZjVX8zZXSbxWYYvdKNZndAR34TD/PK9iPNALAiEAtftAZpFocSOp567kfV63f+C9qmbeTSD+wfVKPfAVwm8="}]},"_npmUser":{"name":"arlok432","email":"arlo.kharod@gmail.com"},"directories":{},"maintainers":[{"name":"arlok432","email":"arlo.kharod@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/observability-client-js_0.1.0_1779513688618_0.04881657461524913"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-23T05:21:28.401Z","0.1.0":"2026-05-23T05:21:28.780Z","modified":"2026-05-23T05:21:28.997Z"},"maintainers":[{"name":"arlok432","email":"arlo.kharod@gmail.com"}],"description":"Adaptive Observability frontend SDK. API surface mirrors SCH's analytics.ts so PostHog migration is import-line-only.","readme":"# @adaptivesoftwarellc/observability-client-js\n\nFrontend SDK for the Adaptive Observability platform.\n\nThe public surface mirrors `sch-ui/src/services/analytics.ts` so the SCH PostHog → Adaptive cutover (Phase 6) is import-line + DI-swap only.\n\n## Install\n\n```bash\nnpm install @adaptivesoftwarellc/observability-client-js\n```\n\n## Quickstart (under 50 LOC)\n\n```ts\n// src/main.tsx (or wherever your app boots)\nimport * as observability from \"@adaptivesoftwarellc/observability-client-js\";\n\nobservability.init({\n  ingestUrl: import.meta.env.VITE_OBSERVABILITY_URL!,\n  apiKey: import.meta.env.VITE_OBSERVABILITY_KEY!,\n  environment: import.meta.env.MODE,\n  releaseSha: import.meta.env.VITE_RELEASE_SHA,\n});\n\n// On login:\nobservability.identify(String(userId)); // string only — caller is responsible for safety\n\n// Page views (call from your router):\nobservability.capturePageView(location.pathname);\n\n// Auth events:\nobservability.track(\"auth_login_success\", { generic_role: \"clinician\" });\nobservability.track(\"auth_logout\");\n```\n\nSee [`docs/privacy-rules.md`](../../docs/privacy-rules.md) for what you may NOT send.\n\n## Optional: Axios interceptor\n\n```ts\nimport axios from \"axios\";\nimport { attachAxiosInterceptor } from \"@adaptivesoftwarellc/observability-client-js/axios\";\n\nconst api = axios.create({ baseURL: \"/api\" });\nattachAxiosInterceptor(api);\n```\n\nCaptures `endpoint_group`, `method`, `http_status_code`, `is_network_error`, and `correlation_id` (read from `x-correlation-id` response header) on every failure.\n\n## Optional: React error boundary\n\n```tsx\nimport { ObservabilityErrorBoundary } from \"@adaptivesoftwarellc/observability-client-js/react\";\n\n<ObservabilityErrorBoundary fallback={<p>Something went wrong.</p>}>\n  <App />\n</ObservabilityErrorBoundary>\n```\n\nNEVER sends `error.message`, `error.stack`, or React `componentStack` text. Only `error_type`, `source`, `component_stack_depth`.\n\n## Replay slot (Phase 9)\n\nPhase 4 ships only the no-op adapter and the type contract — no `rrweb` dependency yet. Phase 9 will drop in an rrweb-backed adapter at `@adaptivesoftwarellc/observability-client-js/replay` without breaking SemVer.\n\n## API surface\n\n| Function | Notes |\n|---|---|\n| `init(options)` | Idempotent; calling with `enabled: false` is a no-op. Set `trackSessions: false` to opt out of automatic `/sessions/start` + `/sessions/end` calls. |\n| `identify(distinctId)` | String only. No `user_` prefix per platform identity rules. |\n| `track(event, props)` | Compile-time event allowlist (TS unions) per `events.ts`. |\n| `capturePageView(path?, featureArea?)` | Auto-normalizes route. |\n| `captureException({ errorType, source, componentStackDepth, normalizedRoute })` | Never accepts message/stack text. |\n| `captureFailedRequest({ url, method, httpStatusCode, isNetworkError, correlationId })` | |\n| `flush()` | Force-send pending batch. |\n| `shutdown()` | Drains transport, stops replay adapter, and sends `/sessions/end`. |\n| `getSessionId()` | The shared id used by replay (Phase 9) and session timeline (Phase 5). |\n| `reset()` | New session id, clear distinct id (call on logout). |\n\n## Live ingest smoke check (4.11 closure harness)\n\n[`scripts/live-ingest-check.mjs`](scripts/live-ingest-check.mjs) is a standalone Node harness that boots the SDK against a real ingestion API, emits one event, calls `shutdown()`, and asserts that the `Sessions` row exists with `started_at` / `last_seen_at` / `ended_at` populated. Use it to close the 4.11 deferred integration test against `obs-api-dev` (or any environment) without standing up a browser.\n\n```bash\nOBS_INGEST_URL=https://obs-api-dev.azurewebsites.net \\\nOBS_API_KEY=aopub_xxx \\\nnode scripts/live-ingest-check.mjs\n```\n\nExit code 0 = pass. The SDK must be built first (`npm run build`).\n\n## PostHog migration cheatsheet\n\n| PostHog (current SCH) | Adaptive (this SDK) |\n|---|---|\n| `posthog.init(key, { api_host })` | `observability.init({ ingestUrl, apiKey })` |\n| `posthog.identify(String(userId))` | `observability.identify(String(userId))` |\n| `posthog.capture(\"event\", props)` | `observability.track(\"event\", props)` |\n| `posthog.reset()` | `observability.reset()` |\n| Manual page view | `observability.capturePageView()` |\n\nEvent names, identity rules, and allowed property shapes are unchanged from `POSTHOG_EVENT_CATALOG.md`.\n","readmeFilename":"README.md","_rev":"1-718f95cd6944f2478f0d0620235d8da8"}