{"_id":"@canarygate/sdk","_rev":"6-7663a3576cdf3388bd816b98eb8fd03f","name":"@canarygate/sdk","dist-tags":{"latest":"0.1.5"},"versions":{"0.1.0":{"name":"@canarygate/sdk","version":"0.1.0","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"license":"MIT","_id":"@canarygate/sdk@0.1.0","maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"dist":{"shasum":"8d83c6c274c3e9d462a281d55ec9ab4df9780b59","tarball":"https://registry.npmjs.org/@canarygate/sdk/-/sdk-0.1.0.tgz","fileCount":14,"integrity":"sha512-jcWeW7G6sb4uQf2GvRsiogOLlCbTskqKr0LqntmSE3mskByVwcVGkIxPz8vce1Zq/OKWlp5FnFYGfhE4T5o+mw==","signatures":[{"sig":"MEUCIQDi0sUb8+aqFb1V0k+V9ixhYapNiIqdYevkB/xbgvXeRwIgUPZXnubS0KKECDLCtHjx0K2rRKjELAR+r5CfpgYVzfU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45049},"_from":"file:canarygate-sdk-0.1.0.tgz","exports":{"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs","require":"./dist/client.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.mjs","require":"./dist/server.js"},"./package.json":"./package.json"},"scripts":{"test":"vitest run","build":"tsup src/client.ts src/server.ts --format esm,cjs --dts --out-dir dist","test:watch":"vitest","check-types":"tsc --noEmit","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"rborges98","email":"rcborges98@gmail.com"},"_resolved":"C:\\Users\\r_bor\\AppData\\Local\\Temp\\f7a21b754ccb89afe3e654464957151e\\canarygate-sdk-0.1.0.tgz","_integrity":"sha512-jcWeW7G6sb4uQf2GvRsiogOLlCbTskqKr0LqntmSE3mskByVwcVGkIxPz8vce1Zq/OKWlp5FnFYGfhE4T5o+mw==","repository":{"url":"git+https://github.com/rborges98/canarygate.git","type":"git","directory":"sdks/js"},"_npmVersion":"10.8.2","description":"CanaryGate SDK — feature flags with real-time SSE streaming","directories":{},"sideEffects":false,"_nodeVersion":"22.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^3.0.0","happy-dom":"^20.11.2","typescript":"^5","@vitest/coverage-v8":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1787710292189_0.7144331879582895","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@canarygate/sdk","version":"0.1.1","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"license":"MIT","_id":"@canarygate/sdk@0.1.1","maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"dist":{"shasum":"a20654bb1fed710d133e5d4cd07c95dcfb7fe40a","tarball":"https://registry.npmjs.org/@canarygate/sdk/-/sdk-0.1.1.tgz","fileCount":14,"integrity":"sha512-K92k4T0znN/pd9yqa7RR0FsLtK6h5aoEW/HJidLteHf26snvBYDFDr9fwRHAwzZgQEIaPi5QGyeIIVR31VFq1Q==","signatures":[{"sig":"MEUCICvDiu44d9aJ3aUCySWg//cunGATEWLbOcJ6ovtBrcuPAiEAyCoRS1BBrcxCQyGu5GylVgAY4nzywKezJBWStEgcFDc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":47453},"exports":{"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs","require":"./dist/client.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.mjs","require":"./dist/server.js"},"./package.json":"./package.json"},"gitHead":"f0e246561b9fd966818f19e7f11264e07ea154fd","scripts":{"test":"vitest run","build":"tsup src/client.ts src/server.ts --format esm,cjs --dts --out-dir dist","test:watch":"vitest","check-types":"tsc --noEmit","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm build"},"_npmUser":{"name":"rborges98","email":"rcborges98@gmail.com"},"repository":{"url":"git+https://github.com/rborges98/canarygate.git","type":"git","directory":"sdks/js"},"_npmVersion":"10.8.2","description":"CanaryGate SDK — feature flags with real-time SSE streaming","directories":{},"sideEffects":false,"_nodeVersion":"22.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^3.0.0","happy-dom":"^20.11.2","typescript":"^5","@vitest/coverage-v8":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.1_1787883045824_0.351731987494039","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@canarygate/sdk","version":"0.1.2","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"license":"MIT","_id":"@canarygate/sdk@0.1.2","maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"dist":{"shasum":"ee6eb40670759f0a713249aed53515a4d704ca1c","tarball":"https://registry.npmjs.org/@canarygate/sdk/-/sdk-0.1.2.tgz","fileCount":14,"integrity":"sha512-KdMpB0hkQTkcF7i7x5Z8WDU0W0bqYc5MC3gyAxVL2vk/Vkgps/Zu09lNmZZclxTeCZsL6voCxcWGbxzlMguf7Q==","signatures":[{"sig":"MEUCIQD5wIaueZ3wzClAWhQrYb2ml39SsUKtj3kLECRZuzaArAIgMPGYcgI+BnDE8flKa2AkfzugGWWPJmj/t86Z99M44Yw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":48826},"exports":{"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs","require":"./dist/client.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.mjs","require":"./dist/server.js"},"./package.json":"./package.json"},"gitHead":"72720efa6336486a5fa3989ec610570ce38f7766","scripts":{"test":"vitest run","build":"tsup src/client.ts src/server.ts --format esm,cjs --dts --out-dir dist","test:watch":"vitest","check-types":"tsc --noEmit","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm build"},"_npmUser":{"name":"rborges98","email":"rcborges98@gmail.com"},"repository":{"url":"git+https://github.com/rborges98/canarygate.git","type":"git","directory":"sdks/js"},"_npmVersion":"10.8.2","description":"CanaryGate SDK — feature flags with real-time SSE streaming","directories":{},"sideEffects":false,"_nodeVersion":"22.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^3.0.0","happy-dom":"^20.11.2","typescript":"^5","@vitest/coverage-v8":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.2_1787884141275_0.23518489502377538","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@canarygate/sdk","version":"0.1.3","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"license":"MIT","_id":"@canarygate/sdk@0.1.3","maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"dist":{"shasum":"3c1cf8b8b857b8382cffd67ded13e1ae8ac7ed1c","tarball":"https://registry.npmjs.org/@canarygate/sdk/-/sdk-0.1.3.tgz","fileCount":17,"integrity":"sha512-nhMrODBLdd0WW48A5Ny9kKd78dOsVGokHw8ZxIWfElzyovw3+FyTF4SbADNN8Ul/EKY6lVviV9nPK+ZXwc6Fzg==","signatures":[{"sig":"MEUCIA9H6eWe//vDs5x4UFHpLYCU+ABdah/KtiW5z9xV7illAiEAiQDA6egN8B9WB4X9YwgcoyBvX1Q6THiS5q5p4csKbBg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":66789},"exports":{"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs","require":"./dist/client.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.mjs","require":"./dist/server.js"},"./package.json":"./package.json"},"gitHead":"0475ba94770c68a749861866fb1f0a49e4c93f52","scripts":{"test":"vitest run","build":"tsup src/client.ts src/server.ts --format esm,cjs --dts --out-dir dist","test:watch":"vitest","check-types":"tsc --noEmit","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm build"},"_npmUser":{"name":"rborges98","email":"rcborges98@gmail.com"},"repository":{"url":"git+https://github.com/rborges98/canarygate.git","type":"git","directory":"sdks/js"},"_npmVersion":"10.8.2","description":"CanaryGate SDK — feature flags with real-time SSE streaming","directories":{},"sideEffects":false,"_nodeVersion":"22.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^3.0.0","happy-dom":"^20.11.2","typescript":"^5","@vitest/coverage-v8":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.3_1787889962115_0.43380138867469253","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@canarygate/sdk","version":"0.1.4","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"license":"MIT","_id":"@canarygate/sdk@0.1.4","maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"dist":{"shasum":"e2ac3a5fb4576278d2986be28a5b3588ea83e917","tarball":"https://registry.npmjs.org/@canarygate/sdk/-/sdk-0.1.4.tgz","fileCount":18,"integrity":"sha512-lONjagzLuqq9bXlqKTlo4qKtGsFKyyMOiq8fQ9umT4andrP3tCunwS/197/a66Lez54apzupKIS//iKHnyJOrQ==","signatures":[{"sig":"MEQCIHnq2/D/0kj/BiH+AQiV4PBkGHVwm0U0SSrBMLILe0/KAiAQFXn/RXnvII7YHqYViAF4HsuMgAJUToWZZh6TdCspsQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78170},"exports":{"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs","require":"./dist/client.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.mjs","require":"./dist/server.js"},"./package.json":"./package.json"},"gitHead":"b0471f892d57817051d57aa4216c910d4f173dd2","scripts":{"test":"vitest run","build":"tsup src/client.ts src/server.ts --format esm,cjs --dts --out-dir dist","test:watch":"vitest","check-types":"tsc --noEmit","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm build"},"_npmUser":{"name":"rborges98","email":"rcborges98@gmail.com"},"repository":{"url":"git+https://github.com/rborges98/canarygate.git","type":"git","directory":"sdks/js"},"_npmVersion":"10.8.2","description":"CanaryGate SDK — feature flags with real-time SSE streaming","directories":{},"sideEffects":false,"_nodeVersion":"22.8.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","vitest":"^3.0.0","happy-dom":"^20.11.2","typescript":"^5","@vitest/coverage-v8":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.4_1787891655843_0.5600891227405735","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@canarygate/sdk","version":"0.1.5","description":"CanaryGate SDK — feature flags with real-time SSE streaming","exports":{"./client":{"types":"./dist/client.d.ts","import":"./dist/client.mjs","require":"./dist/client.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.mjs","require":"./dist/server.js"},"./package.json":"./package.json"},"scripts":{"build":"tsup src/client.ts src/server.ts --format esm,cjs --dts --out-dir dist","check-types":"tsc --noEmit","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"pnpm build"},"sideEffects":false,"license":"MIT","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"repository":{"type":"git","url":"git+https://github.com/rborges98/canarygate.git","directory":"sdks/js"},"homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"publishConfig":{"access":"public"},"devDependencies":{"@vitest/coverage-v8":"^3.0.0","happy-dom":"^20.11.2","tsup":"^8.5.1","typescript":"^5","vitest":"^3.0.0"},"_id":"@canarygate/sdk@0.1.5","gitHead":"1fbc76c6f0a7017e47340d909cb8ad0ded317202","_nodeVersion":"22.8.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-pRibgvdJIldeZnMI/jZy5FsHCCsbl7+mVbQS7YIy6NIntg9cByC8rQuXN169IRQB3Mis4tRkkDeoh3iQsvxkOQ==","shasum":"cfa8151d7d4c231e4dd4c79ad17488b90d197c90","tarball":"https://registry.npmjs.org/@canarygate/sdk/-/sdk-0.1.5.tgz","fileCount":21,"unpackedSize":97430,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDGZRl3JBboYgshn54NBrJNESMAJmiIMt5MQZumL018CQIhAJrUqQitPuB+d4rzYFo7USrEU+Qh8Kjw4BSyXtSMMJ3c"}]},"_npmUser":{"name":"rborges98","email":"rcborges98@gmail.com"},"directories":{},"maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.1.5_1787893924048_0.387382885498025"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-26T02:11:31.738Z","modified":"2026-08-28T05:12:04.386Z","0.1.0":"2026-08-26T02:11:32.338Z","0.1.1":"2026-08-28T02:10:45.983Z","0.1.2":"2026-08-28T02:29:01.424Z","0.1.3":"2026-08-28T04:06:02.259Z","0.1.4":"2026-08-28T04:34:16.021Z","0.1.5":"2026-08-28T05:12:04.215Z"},"bugs":{"url":"https://github.com/rborges98/canarygate/issues"},"license":"MIT","homepage":"https://github.com/rborges98/canarygate/tree/main/sdks/js#readme","keywords":["feature-flags","feature-toggles","sse","real-time","rollout"],"repository":{"type":"git","url":"git+https://github.com/rborges98/canarygate.git","directory":"sdks/js"},"description":"CanaryGate SDK — feature flags with real-time SSE streaming","maintainers":[{"name":"rborges98","email":"rcborges98@gmail.com"}],"readme":"# @canarygate/sdk\n\nFeature flag client for [CanaryGate](https://github.com/rborges98/canarygate).\n\n- **Server (Node.js)** — snapshot on `init()` + live updates via SSE, auto-reconnect and heartbeat\n- **Browser** — snapshot + polling via `pollIntervalMs`\n\n## Install\n\n```sh\nnpm install @canarygate/sdk\n```\n\n## Quick start\n\n### Server — real-time\n\n```ts\nimport { CanaryGate } from '@canarygate/sdk/server'\n\nconst gate = new CanaryGate('your-api-key', {\n  environment: 'production'\n})\n\nawait gate.init()\n// the snapshot is fetched and SSE opens automatically\n\ngate.disconnect() // when shutting down\n```\n\n### Browser — cached\n\n```ts\nimport { CanaryGate } from '@canarygate/sdk/client'\n\nconst gate = new CanaryGate('your-api-key', {\n  environment: 'production'\n})\n\nawait gate.init()\n```\n\n## Evaluating flags\n\n```ts\nconst flag = gate.getFlag('new-checkout', { userId: 'user-123' })\n\nif (flag?.enabled) {\n  // boolean flag is on,\n  // or user-123 falls inside the rollout percentage\n}\n\nconst allFlags = gate.getFlags({ userId: 'user-123' })\n```\n\nEvaluations return a `FlagData`:\n\n```ts\ntype FlagData =\n  | { key: string; type: 'boolean'; enabled: boolean }\n  | { key: string; type: 'rollout'; enabled: boolean; percent: number }\n```\n\nRollout evaluation hashes `userId` deterministically — the same user always gets the same result for the same percentage.\n\n## Options\n\nThe API base URL is resolved automatically from the `CANARYGATE_BASE_URL` environment variable (in browsers, `NEXT_PUBLIC_CANARYGATE_BASE_URL`), falling back to `https://api.canarygate.dev`. Set the variable when self-hosting or during local development.\n\n| Option               | Type      | Default                 | Description                                      |\n| -------------------- | --------- | ----------------------- | ------------------------------------------------ |\n| `environment`        | `string`  | —                       | Environment to evaluate flags against            |\n| `pollIntervalMs`     | `number`  | `30000`                 | Browser polling interval in ms (clamped to a 3000ms minimum). Set `0` to disable. Throws if passed to the server entry |\n| `reconnectDelay`     | `number`  | `5000`                  | Initial SSE reconnect delay (ms). Server-only; throws on the browser entry |\n| `maxReconnectDelay`  | `number`  | `30000`                 | Reconnect delay cap, exponential backoff (ms). Server-only |\n| `heartbeatTimeoutMs` | `number`  | `65000`                 | Silence window before treating the stream as dead. Server-only |\n| `onUpdate`           | `function`| —                       | Called with the updated evaluated flags whenever the flag set changes (polling refresh or SSE event). Never called on initial load |\n\n## Methods\n\n| Method                | Description                                        |\n| --------------------- | -------------------------------------------------- |\n| `init()`              | Fetches the snapshot; the server entry opens SSE, the browser entry starts polling |\n| `getFlag(key, ctx?)`  | Evaluates one flag (`boolean` or `rollout`)        |\n| `getFlags(ctx?)`      | Evaluates all cached flags                         |\n| `isStale()`           | Whether the last sync attempt failed               |\n| `getLastSyncAt()`     | Timestamp of the last successful sync              |\n| `disconnect()`        | Stops the stream and clears timers                 |\n\n## How sync works\n\n1. `init()` fetches a full snapshot from `/sdk/flags`.\n2. The server entry always opens an SSE connection that receives granular updates per change; the browser entry polls the snapshot every `pollIntervalMs`. In both cases, whenever the evaluated flag set changes, the `onUpdate` callback fires with the updated flags.\n3. On disconnect, the SDK reconnects with exponential backoff and does a full resync over the snapshot endpoint.\n\n## Entry-point guards\n\nEach entry point is bound to its environment: the server entry throws `Error('@canarygate/sdk/server is server-only. In browsers import from \"@canarygate/sdk/client\" instead.')` if used where `window` exists, and the client entry throws a browser-only error if used where there is no `window`.\n\n## License\n\n[MIT](./LICENSE)\n","readmeFilename":"README.md"}