{"_id":"@abmeter/node","name":"@abmeter/node","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@abmeter/node","version":"0.1.0","description":"ABMeter Node.js server SDK — feature flags and A/B experiments with client-side assignment","license":"MIT","homepage":"https://abmeter.ai","repository":{"type":"git","url":"git+https://github.com/abmeter/abmeter-node.git"},"keywords":["ab-testing","feature-flags","experiments","abmeter"],"type":"module","sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./package.json":"./package.json"},"engines":{"node":">=20"},"scripts":{"build":"tsup","test":"vitest run","lint":"eslint . && tsc --noEmit"},"devDependencies":{"@types/node":"^22.10.0","eslint":"^9.17.0","tsup":"^8.3.5","typescript":"^5.7.2","typescript-eslint":"^8.18.0","vitest":"^2.1.8"},"_id":"@abmeter/node@0.1.0","gitHead":"27bb068c16aa0bebc30a8a6c8005db24386f587d","bugs":{"url":"https://github.com/abmeter/abmeter-node/issues"},"_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-z+/kxLPbqV2T16jK7ooJylz24VTpu5RktjNT/WhNBn2m52euYdjPkKNz+3LqYk+XBV5qViT6NsxDWyXpg5Yzjg==","shasum":"19d1f0c631188b86a5065917a15ab83b6ce3eeaf","tarball":"https://registry.npmjs.org/@abmeter/node/-/node-0.1.0.tgz","fileCount":23,"unpackedSize":209941,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD4+l8ZiOXmacRf8pxeF+MuEHQQ3WwqNwTP6GXnTVZyQAIgN1uT26PGcQ/FefGEZ1a/ErhiDNibAz4o3WR7bW9s05c="}]},"_npmUser":{"name":"abmeter","email":"info@abmeter.com"},"directories":{},"maintainers":[{"name":"abmeter","email":"info@abmeter.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node_0.1.0_1786755098715_0.4799272059697308"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-15T00:51:38.402Z","0.1.0":"2026-08-15T00:51:38.873Z","modified":"2026-08-15T00:51:39.590Z"},"maintainers":[{"name":"abmeter","email":"info@abmeter.com"}],"description":"ABMeter Node.js server SDK — feature flags and A/B experiments with client-side assignment","homepage":"https://abmeter.ai","keywords":["ab-testing","feature-flags","experiments","abmeter"],"repository":{"type":"git","url":"git+https://github.com/abmeter/abmeter-node.git"},"bugs":{"url":"https://github.com/abmeter/abmeter-node/issues"},"license":"MIT","readme":"# ABMeter Node.js SDK\n\n[ABMeter](https://abmeter.ai) is a feature-flag and A/B-testing platform. You define parameters, experiments, and feature flags in the ABMeter Lab; this package reads the value assigned to each user in your Node.js app and reports events back.\n\nThis is the **server-side** SDK: it holds a secret API key and resolves assignments in your process. For web pages, use the [`abmeter`](https://www.npmjs.com/package/abmeter) browser SDK instead — it works with publishable keys and never receives assignment rules.\n\n## Supported Node.js versions\n\n`@abmeter/node` supports **Node.js 20 and newer** (tested against 20 and 22). ESM and CommonJS are both supported, with TypeScript types included.\n\n## Installation\n\n```bash\nnpm install @abmeter/node\n```\n\n## Getting an API key\n\nSign up at [abmeter.ai](https://abmeter.ai), then in the **Lab** open **API Keys** and create one. Pass it to `configure` (e.g. from an environment variable). Use a secret key — this SDK runs on your servers, never in a browser.\n\n## Usage\n\nConfigure the client once at startup:\n\n```js\nimport * as abmeter from '@abmeter/node';\n\nabmeter.configure({ apiKey: process.env.ABMETER_API_KEY });\n```\n\nThe example below assumes a parameter `welcome_text` (in a space, with a variant, controlled by a running experiment or feature flag) and an event type `user_purchases_plan` already exist — create them through the ABMeter API or, more easily, your AI assistant over MCP. Until they do, `resolveParameter` just returns the parameter's default and `trackEvent` rejects unknown event types.\n\n```js\n// In request handling: read the value assigned to this user. `userId` is the\n// only required field; an optional `email` is available for predicate-based\n// (email-pattern) audience targeting.\nconst user = new abmeter.User({ userId: currentUser.id });\nconst text = await abmeter.resolveParameter(user, 'welcome_text');\n\n// In business logic: record an action that feeds a metric.\nabmeter.trackEvent('user_purchases_plan', currentUser.id, {\n  plan: purchasedPlan.name,\n  price: purchasedPlan.price,\n});\n```\n\nThe two calls are one loop: the experiment varies `welcome_text`, and the event feeds a metric whose effect the experiment measures across variants. Assignment is random across users and consistent per user. Note that `resolveParameter` is **not** a pure read — it resolves the variant **client-side** against a cached assignment config (no per-call round-trip; the returned promise only awaits the network on the very first call) and records an exposure in the background. Full guides live at [abmeter.ai](https://abmeter.ai).\n\nOn shutdown, flush anything still queued:\n\n```js\nawait abmeter.reset(); // drains pending exposures/events (bounded), then tears down\n```\n\n## What this SDK is\n\nA **thin client**: it fetches the assignment config in the background (revalidating with ETags), resolves parameters locally, and submits exposures/events in batches. It deliberately does **not** contain platform-side concerns (config serialization, allocation range-building, type validation) — those live in the ABMeter API.\n\n## Development\n\nPure client library — the unit suite needs no database or any other running service.\n\n```bash\nnpm install   # install dependencies\nnpm test      # tests (vitest)\nnpm run lint  # eslint + tsc --noEmit\n```\n\n## License\n\nAvailable as open source under the terms of the\n[MIT License](https://opensource.org/licenses/MIT).\n","readmeFilename":"README.md","_rev":"1-47a54ecca7aca5ab3a957cebc6f951f3"}