{"_id":"@alrim-me/sdk","_rev":"4-10c73e797b963ca94beacce88c95198d","name":"@alrim-me/sdk","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@alrim-me/sdk","version":"0.1.0","license":"MIT","_id":"@alrim-me/sdk@0.1.0","maintainers":[{"name":"gyeonguk","email":"admin@uchat.io"}],"dist":{"shasum":"c411aec2329136eb81c0ff920d8393fc2c7aa4b9","tarball":"https://registry.npmjs.org/@alrim-me/sdk/-/sdk-0.1.0.tgz","fileCount":35,"integrity":"sha512-46wevbQJ6DWSEUHGpPEqXcG+dUtOYuS7mNYleHJcCPJ6Uza/Ms2pF0h0WBa4iY8+/LWKnWPmOq/Bi2/IEi55vA==","signatures":[{"sig":"MEUCIQDGJkfDB8e2XSNZ3HLa4fnGpmu78Iv9ZdBoBc79ozf+agIgcXdr0AEij9XxXoaLAlU+up9IhQVnGYupf2VLf+kq+LA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120466},"type":"module","exports":{"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js","browser":"./dist/browser-error.js"},"./svelte":{"types":"./dist/svelte.d.ts","import":"./dist/svelte.js"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.js"},"./package.json":"./package.json"},"scripts":{"build":"npm run clean && npm run build:js && npm run build:cdn","check":"npm run build && node --test test/*.mjs","clean":"rm -rf dist","build:js":"tsc -p tsconfig.json","copy:cdn":"cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","build:cdn":"esbuild src/browser.ts --bundle --format=iife --global-name=AlrimSubscribe --target=es2020 --outfile=dist/alrim-subscribe.js"},"_npmUser":{"name":"gyeonguk","email":"admin@uchat.io"},"_npmVersion":"11.4.2","description":"Official JavaScript SDK for alrim publish and subscribe flows.","directories":{},"sideEffects":["./dist/browser.js","./dist/react.js","./dist/svelte.js","./dist/vue.js"],"_nodeVersion":"20.19.2","dependencies":{"qrcode":"^1.5.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.13","jsdom":"^26.1.0","react":"^19.1.0","svelte":"^5.28.2","esbuild":"^0.25.3","react-dom":"^19.1.0","typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^19.1.2","@types/qrcode":"^1.5.6"},"peerDependencies":{"vue":">=3","react":">=18","svelte":">=4"},"peerDependenciesMeta":{"vue":{"optional":true},"react":{"optional":true},"svelte":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1777642005940_0.4704383414157365","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@alrim-me/sdk","version":"0.2.0","license":"MIT","_id":"@alrim-me/sdk@0.2.0","maintainers":[{"name":"gyeonguk","email":"admin@uchat.io"}],"dist":{"shasum":"c64028d91724b0f6bc88e4d00977158a5bf82e45","tarball":"https://registry.npmjs.org/@alrim-me/sdk/-/sdk-0.2.0.tgz","fileCount":36,"integrity":"sha512-iGapw1U1I/Ddmwy7NtZM56AJ7W9SsWfJznA8KvsnS++VPfWgmFUKIIzUowArC9ZoukRAS/5fpioilIkxAyNREA==","signatures":[{"sig":"MEUCIB90icJU0MHJde8rRErRS7Z5Xrg4kA42Xndv2POjwxVpAiEArY77qpG9FdwOUN78n3R2Zw8ykEDx7fu+XA+MxfZmApY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":173425},"type":"module","exports":{"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js","browser":"./dist/browser-error.js"},"./svelte":{"types":"./dist/svelte.d.ts","import":"./dist/svelte.js"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.js"},"./package.json":"./package.json"},"gitHead":"969c7136db1e730ff4b6f8da55b77b75953e88f0","scripts":{"build":"npm run clean && npm run build:js && npm run build:cdn","check":"npm run build && node --test test/*.mjs","clean":"rm -rf dist","release":"npm run check && npm run verify:cdn && npm pack --dry-run && changeset publish","build:js":"tsc -p tsconfig.json","copy:cdn":"cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","build:cdn":"esbuild src/browser.ts --bundle --format=iife --global-name=AlrimSubscribe --target=es2020 --outfile=dist/alrim-subscribe.js","changeset":"changeset","verify:cdn":"cmp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cmp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","changeset:version":"changeset version && npm install --package-lock-only --ignore-scripts && npm run build && npm run copy:cdn"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5e31a991-25bb-4543-802e-09e0584f5c8f"}},"_npmVersion":"11.11.0","description":"Official JavaScript SDK for alrim publish and subscribe flows.","directories":{},"sideEffects":["./dist/browser.js","./dist/react.js","./dist/svelte.js","./dist/vue.js"],"_nodeVersion":"24.14.1","dependencies":{"qrcode":"^1.5.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.13","jsdom":"^26.1.0","react":"^19.1.0","svelte":"^5.28.2","esbuild":"^0.25.3","react-dom":"^19.1.0","typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^19.1.2","@types/qrcode":"^1.5.6","@changesets/cli":"^2.31.0"},"peerDependencies":{"vue":">=3","react":">=18","svelte":">=4"},"peerDependenciesMeta":{"vue":{"optional":true},"react":{"optional":true},"svelte":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.2.0_1778344653615_0.7952710891394574","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@alrim-me/sdk","version":"0.2.1","license":"MIT","_id":"@alrim-me/sdk@0.2.1","maintainers":[{"name":"gyeonguk","email":"admin@uchat.io"}],"dist":{"shasum":"4c6734f2f2faf64119720b65072aef08bf56b69a","tarball":"https://registry.npmjs.org/@alrim-me/sdk/-/sdk-0.2.1.tgz","fileCount":36,"integrity":"sha512-geuvR9Mp0H9jycNDRb5al/+cZ9gKWp8pHT+viD9grvpiIrZerRGuc0WIt8VOGO9ql59KkIbw2zHG30Xk564PqA==","signatures":[{"sig":"MEUCID9tYqyQaqu8LNdU6FrWh8WPWkmDqgV5pdhCytCgE0LGAiEA9sO6J3ej5wJzb7ls/qrxGu8aST+giWtJk++gBy9IptE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":177336},"type":"module","exports":{"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js","browser":"./dist/browser-error.js"},"./svelte":{"types":"./dist/svelte.d.ts","import":"./dist/svelte.js"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.js"},"./package.json":"./package.json"},"gitHead":"18a1a276ad7dddb0d07bba12b66108f32ceb436b","scripts":{"build":"npm run clean && npm run build:js && npm run build:cdn","check":"npm run build && node --test test/*.mjs","clean":"rm -rf dist","release":"npm run check && npm run verify:cdn && npm pack --dry-run && changeset publish","build:js":"tsc -p tsconfig.json","copy:cdn":"cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","build:cdn":"esbuild src/browser.ts --bundle --format=iife --global-name=AlrimSubscribe --target=es2020 --outfile=dist/alrim-subscribe.js","changeset":"changeset","verify:cdn":"cmp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cmp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","changeset:version":"changeset version && npm install --package-lock-only --ignore-scripts && npm run build && npm run copy:cdn"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5e31a991-25bb-4543-802e-09e0584f5c8f"}},"_npmVersion":"11.11.0","description":"Official JavaScript SDK for alrim publish and subscribe flows.","directories":{},"sideEffects":["./dist/browser.js","./dist/react.js","./dist/svelte.js","./dist/vue.js"],"_nodeVersion":"24.14.1","dependencies":{"qrcode":"^1.5.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.13","jsdom":"^26.1.0","react":"^19.1.0","svelte":"^5.28.2","esbuild":"^0.25.3","react-dom":"^19.1.0","typescript":"^5.8.3","@types/node":"^22.15.3","@types/react":"^19.1.2","@types/qrcode":"^1.5.6","@changesets/cli":"^2.31.0"},"peerDependencies":{"vue":">=3","react":">=18","svelte":">=4"},"peerDependenciesMeta":{"vue":{"optional":true},"react":{"optional":true},"svelte":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.2.1_1778345657272_0.9971799336862159","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alrim-me/sdk","version":"0.3.0","description":"Official JavaScript SDK for alrim publish and subscribe flows.","type":"module","license":"MIT","publishConfig":{"access":"public"},"sideEffects":["./dist/browser.js","./dist/react.js","./dist/svelte.js","./dist/vue.js"],"exports":{"./server":{"types":"./dist/server.d.ts","browser":"./dist/browser-error.js","import":"./dist/server.js"},"./browser":{"types":"./dist/browser.d.ts","import":"./dist/browser.js"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js"},"./svelte":{"types":"./dist/svelte.d.ts","import":"./dist/svelte.js"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.js"},"./package.json":"./package.json"},"scripts":{"clean":"rm -rf dist","build:js":"tsc -p tsconfig.json","build:cdn":"esbuild src/browser.ts --bundle --format=iife --global-name=AlrimSubscribe --target=es2020 --outfile=dist/alrim-subscribe.js","build":"npm run clean && npm run build:js && npm run build:cdn","copy:cdn":"cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","verify:cdn":"cmp dist/alrim-subscribe.js ../../alrim.me/static/sdk/v1/alrim-subscribe.js && cmp dist/alrim-subscribe.js ../../alrim.me/static/sdk/latest/alrim-subscribe.js","check":"npm run build && node --test test/*.mjs","changeset":"changeset","changeset:version":"changeset version && npm install --package-lock-only --ignore-scripts && npm run build && npm run copy:cdn","release":"npm run check && npm run verify:cdn && npm pack --dry-run && changeset publish"},"dependencies":{"qrcode":"^1.5.4"},"peerDependencies":{"react":">=18","svelte":">=4","vue":">=3"},"peerDependenciesMeta":{"react":{"optional":true},"svelte":{"optional":true},"vue":{"optional":true}},"devDependencies":{"@changesets/cli":"^2.31.0","@types/node":"^22.15.3","@types/qrcode":"^1.5.6","@types/react":"^19.1.2","esbuild":"^0.25.3","jsdom":"^26.1.0","react":"^19.1.0","react-dom":"^19.1.0","svelte":"^5.28.2","typescript":"^5.8.3","vue":"^3.5.13"},"gitHead":"2a3c6026703d2f43705ede5e650fd0d7f7b8dabf","_id":"@alrim-me/sdk@0.3.0","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-6gF/UDb+XNKk5AyWU7SYRKDao8vrWiCekwGOsj/AjWKAFbkY7aFXl86UMn4L+Hy82cSU5UOL03ACUZnvTKH+VA==","shasum":"771478374b407442334f28ed6ab8dea803914c46","tarball":"https://registry.npmjs.org/@alrim-me/sdk/-/sdk-0.3.0.tgz","fileCount":36,"unpackedSize":179798,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHgEY41HI97zdeLV4Ui5jNpqIHjjYe6OI6SpRRoXUjLRAiAqs6FLPkET/hsNinMHGDzz2P7Rfdfgi+cp5XS8cenK2g=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:5e31a991-25bb-4543-802e-09e0584f5c8f"}},"directories":{},"maintainers":[{"name":"gyeonguk","email":"admin@uchat.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.3.0_1778348602827_0.5887046288372542"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-01T13:26:45.770Z","modified":"2026-05-09T17:43:23.129Z","0.1.0":"2026-05-01T13:26:46.100Z","0.2.0":"2026-05-09T16:37:33.794Z","0.2.1":"2026-05-09T16:54:17.430Z","0.3.0":"2026-05-09T17:43:22.988Z"},"license":"MIT","description":"Official JavaScript SDK for alrim publish and subscribe flows.","maintainers":[{"name":"gyeonguk","email":"admin@uchat.io"}],"readme":"# @alrim-me/sdk\n\nOfficial JavaScript SDK for alrim publish and subscribe flows.\n\nThe package has two runtime sides:\n\n- `@alrim-me/sdk/server` — server-only publisher helpers. Never import this in browser code.\n- `@alrim-me/sdk/browser` — public subscribe widget helpers for browser pages.\n\nServer code derives private `publishKey` values from your private `secret + channel name`, publishes through `alrim.io`, and returns public subscribe config for browser UI. Browser code only receives public values such as `channelCode` and never receives `secret` or `publishKey`.\n\n## Install\n\n```bash\nnpm install @alrim-me/sdk\n```\n\n## Server publishing\n\nCreate a publisher once, then select a private channel with `channel(name)`.\n\n```ts\nimport { createAlrimPublisher } from \"@alrim-me/sdk/server\";\n\nconst alrim = createAlrimPublisher({\n  secret: process.env.ALRIM_SECRET!,\n});\n\nawait alrim.channel(\"deploys\").publish({\n  title: \"Server deploy\",\n  body: \"v1.2.3 shipped\",\n  data: { service: \"api\" },\n});\n```\n\n`\"deploys\"` is not a public channel id. It is your private server-side channel name. The SDK derives:\n\n```txt\npublishKey = hmacSha256(secret, channelName)\nchannelCode = sha256(publishKey).slice(0, 32)\n```\n\nThis means the same channel name with a different secret creates a different public channel.\n\n### Create public subscribe config\n\nUse this on the server, then pass only the returned public config to browser/UI code.\n\n```ts\nconst deploys = alrim.channel(\"deploys\");\n\nconst subscribe = deploys.subscribeConfig({\n  title: \"Deploys\",\n  icon: \"bolt\",\n  color: \"emerald\",\n});\n\n// Safe to expose:\n// {\n//   channelCode: '...',\n//   title: 'Deploys',\n//   icon: 'bolt',\n//   color: 'emerald',\n//   origin: 'https://alrim.me',\n//   subscribeUrl: 'https://alrim.me/<channelCode>?title=Deploys&...'\n// }\n```\n\nYou can also create just the URL:\n\n```ts\nconst subscribeUrl = alrim.channel(\"deploys\").subscribeUrl({\n  title: \"Deploys\",\n});\n```\n\n### Controls\n\nThe first argument to `publish()` is always the publisher-owned notification payload and is sent unchanged. Alrim-specific behavior goes in the second argument under `controls`, which the SDK sends as `X-Alrim-*` headers.\n\n```ts\nawait alrim.channel(\"deploys\").publish(\n  {\n    title: \"High error rate\",\n    body: \"api workers are above threshold\",\n  },\n  {\n    controls: {\n      severity: \"warning\",\n      show: \"1\",\n      ring: \"force\",\n      level: 2,\n    },\n  }\n);\n```\n\nSupported controls:\n\n- `severity`: `'info' | 'warning' | 'critical'`\n- `show`: `'1' | 'hide'`\n- `ring`: `'silent' | 'force'`\n- `level`: non-negative integer\n\n### Fan-out publishing\n\nPass a channel-name array to `channel()` to publish the same payload to multiple channels in one request. There is no separate `channels()` API.\n\n```ts\nawait alrim.channel([\"deploys\", \"incidents\"]).publish({\n  title: \"Server deploy\",\n  body: \"v1.2.3 shipped\",\n});\n```\n\nFor fan-out, the SDK derives one publish key per channel name and sends them through the `X-Alrim-Key` header while keeping the request body payload-only. Fan-out channel objects are publish-only; create subscribe config from a single `alrim.channel(\"name\")` value.\n\n### Attachments\n\nPass `attachments` in the second argument to send multipart form data. The SDK puts the JSON payload in the `data` field and appends files as repeated `files` fields. Do not set `Content-Type` manually; the fetch runtime supplies the multipart boundary.\n\n```ts\nawait alrim.channel(\"incidents\").publish(\n  {\n    title: \"Incident report\",\n    body: \"Screenshots and runbook attached\",\n    data: { incidentId: \"inc_123\" },\n  },\n  {\n    attachments: [\n      chartFile,\n      {\n        name: \"runbook.txt\",\n        content: \"restart api workers\",\n        type: \"text/plain\",\n      },\n      {\n        name: \"payload.json\",\n        content: JSON.stringify({ incidentId: \"inc_123\" }),\n        type: \"application/json\",\n      },\n    ],\n  }\n);\n```\n\nEach attachment can be:\n\n- a `File`\n- a `Blob`\n- `{ name: string, content: string | ArrayBuffer | Uint8Array | Blob, type?: string }`\n\n### Direct publish keys\n\nIf you already have publish keys, create a direct channel instead of using `secret + channel name`.\n\n```ts\nimport { createAlrimChannel } from \"@alrim-me/sdk/server\";\n\nconst alerts = createAlrimChannel({\n  publishKey: process.env.ALRIM_PUBLISH_KEY!,\n});\n\nawait alerts.publish({\n  title: \"Direct publish\",\n  body: \"Using an existing publish key\",\n});\n```\n\nDirect publish-key fan-out is also supported:\n\n```ts\nconst alerts = createAlrimChannel({\n  publishKey: [process.env.ALERTS_KEY!, process.env.INCIDENTS_KEY!],\n});\n\nawait alerts.publish({ title: \"Fan-out\", body: \"Sent to two publish keys\" });\n```\n\n### Low-level helpers\n\n```ts\nimport {\n  deriveChannelCode,\n  deriveChannelFromSecret,\n  derivePublishKey,\n} from \"@alrim-me/sdk/server\";\n\nconst publishKey = derivePublishKey({\n  secret: process.env.ALRIM_SECRET!,\n  channel: \"deploys\",\n});\nconst channelCode = deriveChannelCode(publishKey);\nconst channel = deriveChannelFromSecret({\n  secret: process.env.ALRIM_SECRET!,\n  channel: \"deploys\",\n});\n```\n\n`createAlrimPublisher` validates `secret` immediately. Missing or empty secrets throw `Missing secret` before any derived helper runs.\n\n### Response and errors\n\n`publish()` returns the parsed response from `alrim.io`.\n\n```ts\ntype AlrimPublishResponse = {\n  ok?: boolean;\n  channel_code?: string;\n  channel_url?: string;\n  notification_id?: string;\n  created_at_ms?: number;\n  attachments?: unknown[];\n  [key: string]: unknown;\n};\n```\n\nFailed publish responses throw `AlrimPublishError`.\n\n```ts\nimport { AlrimPublishError } from \"@alrim-me/sdk/server\";\n\ntry {\n  await alrim.channel(\"deploys\").publish({ title: \"Ping\" });\n} catch (error) {\n  if (error instanceof AlrimPublishError) {\n    console.error(error.status, error.body);\n  }\n}\n```\n\n### Advanced options\n\nUse these for self-hosting, dev/staging, tests, or custom runtimes.\n\n```ts\nconst alrim = createAlrimPublisher({\n  secret: process.env.ALRIM_SECRET!,\n  ioOrigin: \"https://dev.alrim.io\",\n  meOrigin: \"https://dev.alrim.me\",\n  fetch: customFetch,\n});\n```\n\n## Browser subscribe widget\n\nThe browser SDK renders subscribe buttons/modals with Shadow DOM. It only needs public subscribe config.\n\n### CDN custom element\n\nRecommended no-build usage:\n\n```html\n<script src=\"https://alrim.me/sdk/v1/alrim-subscribe.js\"></script>\n\n<alrim-me\n  channel-code=\"3ba3f5f43b92602683c19aee62a20342\"\n  title=\"Deploys\"\n  icon=\"bolt\"\n  color=\"emerald\"\n  button-label=\"Get alerts\"\n></alrim-me>\n```\n\n`origin` defaults to `https://alrim.me`. Set it only for dev/staging/self-hosted pages.\n\n```html\n<alrim-me\n  channel-code=\"3ba3f5f43b92602683c19aee62a20342\"\n  title=\"Deploys\"\n  origin=\"https://dev.alrim.me\"\n></alrim-me>\n```\n\nFor dynamic updates, call the element's `update()` method or set observed attributes such as `channel-code`, `title`, `origin`, and `button-label`.\n\n```js\ndocument.querySelector(\"alrim-me\")?.update({\n  channelCode: \"3ba3f5f43b92602683c19aee62a20342\",\n  title: \"New title\",\n});\n```\n\n### Attach to existing links/buttons\n\nKeep your own markup and let the SDK open the alrim subscribe modal on click.\n\n```html\n<a\n  data-alrim-subscribe\n  href=\"https://alrim.me/3ba3f5f43b92602683c19aee62a20342?title=Deploys\"\n>\n  Follow deploy alerts\n</a>\n\n<script src=\"https://alrim.me/sdk/v1/alrim-subscribe.js\"></script>\n<script>\n  AlrimSubscribe.auto();\n</script>\n```\n\nYou can also bind manually:\n\n```html\n<button id=\"custom-subscribe\">Open subscribe modal</button>\n\n<script src=\"https://alrim.me/sdk/v1/alrim-subscribe.js\"></script>\n<script>\n  const widget = AlrimSubscribe.attach(\"#custom-subscribe\", {\n    channelCode: \"3ba3f5f43b92602683c19aee62a20342\",\n    title: \"Deploys\",\n  });\n</script>\n```\n\n### Imperative mount\n\n```ts\nimport { mount } from \"@alrim-me/sdk/browser\";\n\nconst widget = mount(\"#alrim-subscribe\", {\n  channelCode: \"3ba3f5f43b92602683c19aee62a20342\",\n  title: \"Deploys\",\n  buttonLabel: \"Get alerts\",\n});\n\nwidget.open();\nwidget.update({\n  channelCode: \"3ba3f5f43b92602683c19aee62a20342\",\n  title: \"Incidents\",\n});\nwidget.destroy();\n```\n\nBrowser exports:\n\n```ts\nimport {\n  attach,\n  auto,\n  defineCustomElement,\n  mount,\n  open,\n} from \"@alrim-me/sdk/browser\";\n```\n\n## Framework adapters\n\n### React\n\n```tsx\nimport { AlrimSubscribe } from \"@alrim-me/sdk/react\";\n\nexport function SubscribeButton() {\n  return (\n    <AlrimSubscribe\n      channelCode=\"3ba3f5f43b92602683c19aee62a20342\"\n      title=\"Deploys\"\n      buttonLabel=\"Get alerts\"\n    />\n  );\n}\n```\n\n### Svelte\n\n```svelte\n<script lang=\"ts\">\n  import { alrimSubscribe } from '@alrim-me/sdk/svelte';\n\n  const config = {\n    channelCode: '3ba3f5f43b92602683c19aee62a20342',\n    title: 'Deploys',\n    buttonLabel: 'Get alerts'\n  };\n</script>\n\n<div use:alrimSubscribe={config}></div>\n```\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { AlrimSubscribe } from \"@alrim-me/sdk/vue\";\n\nconst config = {\n  channelCode: \"3ba3f5f43b92602683c19aee62a20342\",\n  title: \"Deploys\",\n  buttonLabel: \"Get alerts\",\n};\n</script>\n\n<template>\n  <AlrimSubscribe :config=\"config\" />\n</template>\n```\n\n## CDN versioning\n\nUse the versioned CDN path in production examples:\n\n```html\n<script src=\"https://alrim.me/sdk/v1/alrim-subscribe.js\"></script>\n```\n\n`/sdk/latest/alrim-subscribe.js` exists for quick testing, but production pages should prefer the versioned path.\n","readmeFilename":"README.md"}