{"_id":"@avsbhq/core","_rev":"5-4beb66a41c3e3921c5080e884d45b599","name":"@avsbhq/core","dist-tags":{"latest":"1.5.1"},"versions":{"1.0.0":{"name":"@avsbhq/core","version":"1.0.0","_id":"@avsbhq/core@1.0.0","maintainers":[{"name":"main1479","email":"m.main2402@gmail.com"}],"homepage":"https://github.com/main1479/a-vs-b/tree/main/packages/avsb-core#readme","bugs":{"url":"https://github.com/main1479/a-vs-b/issues"},"dist":{"shasum":"81ae85af9f910c0942fa91f36ae2c7ecb0499c8b","tarball":"https://registry.npmjs.org/@avsbhq/core/-/core-1.0.0.tgz","fileCount":13,"integrity":"sha512-6bXN/qD2+dD8LmFS+OOsKZtfXf+9/6MgNbvRx/rXPh3gWEneMzpRGhr/o0pCBhUtW7vd2vSPbDBuSV7X3lVt6Q==","signatures":[{"sig":"MEYCIQDozxE+N9SBPVIMYhapqzD6KeJy8mk6iMdh/yzrEUE/pgIhAIPxk9BHF+xvvPMXJ3I/cwCYOMg3GF+bLhzKa72zd1+i","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":148780},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./engine":{"types":"./dist/engine.d.ts","import":"./dist/engine.js","require":"./dist/engine.cjs"}},"gitHead":"8cd6226e120fe67c198b2f1db0087cd38b4a4060","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"main1479","email":"m.main2402@gmail.com"},"repository":{"url":"git+https://github.com/main1479/a-vs-b.git","type":"git","directory":"packages/avsb-core"},"_npmVersion":"10.9.2","description":"Pure evaluation engine, shared types, and schemas for the A vs B SDK ecosystem.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_npmOperationalInternal":{"tmp":"tmp/core_1.0.0_1780034328634_0.7697215470870677","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@avsbhq/core","version":"1.1.0","_id":"@avsbhq/core@1.1.0","maintainers":[{"name":"main1479","email":"m.main2402@gmail.com"}],"homepage":"https://github.com/main1479/a-vs-b/tree/main/packages/avsb-core#readme","bugs":{"url":"https://github.com/main1479/a-vs-b/issues"},"dist":{"shasum":"c9adc6cb08c4229e7e263b3854e6701d14c2cf70","tarball":"https://registry.npmjs.org/@avsbhq/core/-/core-1.1.0.tgz","fileCount":13,"integrity":"sha512-+p/PqCdus5pMeuznkq/0PYq0bBFQrCVVfHZruKMIFASiFRMT1nG1QUikIGo+RmeQRukGxrNHIGn584GLZST7Ug==","signatures":[{"sig":"MEQCIFcT5bY4F6J4yLdIreo3WGA4oRKs/796laoNWRnXJ9oMAiAVWkws1Nrhd7qNp3GbkYF8eltaxsnnWppjZlOyI4U+ng==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":149951},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./engine":{"types":"./dist/engine.d.ts","import":"./dist/engine.js","require":"./dist/engine.cjs"}},"gitHead":"123dcb4c9c057ba28db9c98bad7bfa4d7f770457","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"main1479","email":"m.main2402@gmail.com"},"repository":{"url":"git+https://github.com/main1479/a-vs-b.git","type":"git","directory":"packages/avsb-core"},"_npmVersion":"10.9.8","description":"Pure evaluation engine, shared types, and schemas for the A vs B SDK ecosystem.","directories":{},"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_npmOperationalInternal":{"tmp":"tmp/core_1.1.0_1781206049448_0.17899636776039407","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@avsbhq/core","version":"1.4.0","_id":"@avsbhq/core@1.4.0","maintainers":[{"name":"main1479","email":"m.main2402@gmail.com"}],"homepage":"https://github.com/main1479/a-vs-b/tree/main/packages/avsb-core#readme","bugs":{"url":"https://github.com/main1479/a-vs-b/issues"},"dist":{"shasum":"f6c6154ae4bb7121d95cba125f097f1e0f4f575e","tarball":"https://registry.npmjs.org/@avsbhq/core/-/core-1.4.0.tgz","fileCount":13,"integrity":"sha512-ADCH6HQkAYq7r5wyItcA3c4hXYBdsCAjjVDWMVcCEMG9ZYhs7DMeIhMJc3Ejd588Km/P+/ZMcE4OinQ+3z+JIw==","signatures":[{"sig":"MEUCIHFlPoS77TtlSEJutnIUbHuLbk+eburhkCPlogHOCGcKAiEA54JdU4CJodxNAOaVOvDKIssfPsjk5FVJsTmCdlE9nt0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":169377},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./engine":{"types":"./dist/engine.d.ts","import":"./dist/engine.js","require":"./dist/engine.cjs"}},"scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"main1479","email":"m.main2402@gmail.com"},"repository":{"url":"git+https://github.com/main1479/a-vs-b.git","type":"git","directory":"packages/avsb-core"},"_npmVersion":"10.9.8","description":"Pure evaluation engine, shared types, and schemas for the A vs B SDK ecosystem.","directories":{},"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_npmOperationalInternal":{"tmp":"tmp/core_1.4.0_1785346440647_0.8024340153007412","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@avsbhq/core","version":"1.5.0","keywords":["avsb","feature-flags","ab-testing","experiments","evaluation","sdk"],"license":"MIT","_id":"@avsbhq/core@1.5.0","maintainers":[{"name":"main1479","email":"m.main2402@gmail.com"}],"homepage":"https://github.com/avsbhq/a-vs-b/tree/main/packages/avsb-core#readme","bugs":{"url":"https://github.com/avsbhq/a-vs-b/issues"},"dist":{"shasum":"967f9b8ae5f51bbe13186645b04c3c582060c6c3","tarball":"https://registry.npmjs.org/@avsbhq/core/-/core-1.5.0.tgz","fileCount":14,"integrity":"sha512-RKRycwKl3BqKkJ8BAq2rg+4XyhAFj5SIIrSWmEZ07xzqp7uUlJ3G/viN++oWsjMebduT+mgpFLDchvxvFD9IQA==","signatures":[{"sig":"MEQCIC71s/EyFQmTtG6MahbfpufY02zblPqq6XO/K+/6v6qrAiB28+7fiQ4twJ+Q4AJv6g+97WY8iKbAlgHnZM6e1aN66g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":232130},"main":"dist/index.cjs","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./package.json":"./package.json"},"gitHead":"5eed46d5944b522ba0aa34e82850c98bb91667fe","scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"main1479","email":"m.main2402@gmail.com"},"repository":{"url":"git+https://github.com/avsbhq/a-vs-b.git","type":"git","directory":"packages/avsb-core"},"_npmVersion":"10.9.8","description":"Shared evaluation engine and types for the A vs B SDKs: flag evaluation, audiences, bucketing, and the datafile contract.","directories":{},"sideEffects":false,"_nodeVersion":"22.22.3","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_npmOperationalInternal":{"tmp":"tmp/core_1.5.0_1785971458934_0.8859685889208808","host":"s3://npm-registry-packages-npm-production"}},"1.5.1":{"name":"@avsbhq/core","version":"1.5.1","description":"Shared evaluation engine and types for the A vs B SDKs: flag evaluation, audiences, bucketing, and the datafile contract.","keywords":["avsb","feature-flags","ab-testing","experiments","evaluation","sdk"],"license":"MIT","type":"module","sideEffects":false,"main":"dist/index.cjs","module":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}},"./engine":{"import":{"types":"./dist/engine.d.ts","default":"./dist/engine.js"},"require":{"types":"./dist/engine.d.cts","default":"./dist/engine.cjs"}},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/avsbhq/a-vs-b.git","directory":"packages/avsb-core"},"homepage":"https://github.com/avsbhq/a-vs-b/tree/main/packages/avsb-core#readme","bugs":{"url":"https://github.com/avsbhq/a-vs-b/issues"},"scripts":{"build":"tsup","dev":"tsup --watch"},"devDependencies":{"tsup":"^8.0.0","typescript":"^5.5.0"},"_id":"@avsbhq/core@1.5.1","gitHead":"d31d88fbf202f40041b4cb47f77882f454fa5ef8","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-Qfvm+6DzkrOqQpukT/+5sjatgKCprdONKtt8wAdbrPQ9EygfE2ukWN9pLx6wXfPzSMFI6nvQp1Kf2bOwouUlkg==","shasum":"2f027c1140db38c9ba1616195d5c789b7ab8545a","tarball":"https://registry.npmjs.org/@avsbhq/core/-/core-1.5.1.tgz","fileCount":14,"unpackedSize":232162,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIA5SBcBEF3YQLxqfVMFUcG9aDrBxoUqOjTrS9HrOUuLfAiBzadDnskVlRr91l7fkj6zjbylQAgqoVGXxeIsCqWYcRg=="}]},"_npmUser":{"name":"main1479","email":"m.main2402@gmail.com"},"directories":{},"maintainers":[{"name":"main1479","email":"m.main2402@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_1.5.1_1786795808016_0.8941029337300743"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-29T05:58:48.472Z","modified":"2026-08-15T12:10:08.358Z","1.0.0":"2026-05-29T05:58:48.782Z","1.1.0":"2026-06-11T19:27:29.616Z","1.4.0":"2026-07-29T17:34:00.799Z","1.5.0":"2026-08-05T23:10:59.094Z","1.5.1":"2026-08-15T12:10:08.172Z"},"bugs":{"url":"https://github.com/avsbhq/a-vs-b/issues"},"license":"MIT","homepage":"https://github.com/avsbhq/a-vs-b/tree/main/packages/avsb-core#readme","keywords":["avsb","feature-flags","ab-testing","experiments","evaluation","sdk"],"repository":{"type":"git","url":"git+https://github.com/avsbhq/a-vs-b.git","directory":"packages/avsb-core"},"description":"Shared evaluation engine and types for the A vs B SDKs: flag evaluation, audiences, bucketing, and the datafile contract.","maintainers":[{"name":"main1479","email":"m.main2402@gmail.com"}],"readme":"# @avsbhq/core\n\nPure evaluation engine, shared types, and schemas for the A vs B SDK ecosystem.\n\nThis package is the foundation that every other A vs B SDK package builds on. It contains no I/O, no DOM, no Node.js APIs, just the evaluator, type definitions, and shared helpers that all runtimes share.\n\n**Most application code should not import this package directly.** Use `@avsbhq/browser`, `@avsbhq/node`, `@avsbhq/react`, or another runtime-specific package instead. Those packages re-export everything from `@avsbhq/core` you need at the application layer.\n\n---\n\n## 1. Install\n\n```bash\nnpm install @avsbhq/core\n```\n\nCompatible with any JavaScript runtime: Node.js 18+, modern browsers, Cloudflare Workers, Deno, Bun, and React Native (Hermes).\n\nNo peer dependencies.\n\n---\n\n## 2. Quickstart\n\nThe primary use of `@avsbhq/core` in application code is importing its types. If you are building a per-language port of the A vs B SDK, use the `/engine` subpath for the evaluation primitives.\n\n```ts\n// Import types for type annotations in your own code\nimport type { EvalContext, Flag, TrackPayload, FlagDatafile } from '@avsbhq/core';\n\n// Import the createFlag helper to construct Flag<T> objects in tests\nimport { createFlag, notFoundFlag } from '@avsbhq/core';\n\n// Engine primitives: only for SDK implementors, not application code\nimport { evaluateFlag, murmurhash3 } from '@avsbhq/core/engine';\n```\n\nFor application-level flag evaluation, use the runtime SDKs:\n\n```ts\n// Browser / client-side:\nimport { AvsbClient } from '@avsbhq/browser';\n\n// Server / Node.js:\nimport { AvsbServer } from '@avsbhq/node';\n```\n\n---\n\n## 3. SDK keys\n\nNot applicable to `@avsbhq/core`. This package contains no networking code. SDK key handling lives in `@avsbhq/browser` (client keys) and `@avsbhq/node` (server keys).\n\n---\n\n## 4. Identity: `EvalContext`\n\n`EvalContext` is the kinded context type used across every SDK. It replaces the legacy flat `{ attributes: Record<string, unknown> }` bag.\n\nThe shapes below and the `Flag<T>` shape in section 6 name a few more of the package's own types. They all come from the same entry point:\n\n```ts\nimport type { ContextMeta, EvaluationSource, RuleType } from '@avsbhq/core';\n```\n\n```ts\nexport type EvalContext = SingleContext | MultiContext;\n\n// Single-kind context: the common case\ninterface SingleContext {\n  kind: string; // 'user' is conventional; any string is valid\n  key: string; // bucketing identifier (unique per kind)\n  name?: string; // optional display name, never used in eval\n  _meta?: ContextMeta;\n  [attribute: string]: unknown; // targeting attributes\n}\n\n// Multi-kind context: user + organization + device simultaneously\ninterface MultiContext {\n  kind: 'multi';\n  [contextKind: string]: SingleContext | 'multi';\n}\n```\n\nExamples:\n\n```ts\n// Single context\nconst userCtx: EvalContext = {\n  kind: 'user',\n  key: 'u_123',\n  plan: 'pro',\n  country: 'US',\n};\n\n// Multi context\nconst multiCtx: EvalContext = {\n  kind: 'multi',\n  user: { kind: 'user', key: 'u_123', plan: 'pro' },\n  organization: { kind: 'organization', key: 'org_456', tier: 'enterprise' },\n};\n```\n\nContext helper functions exported from `@avsbhq/core`:\n\n```ts\nimport {\n  isMultiContext,\n  getContextByKind,\n  userContext,\n  bucketingKey,\n  contextSummary,\n  privateAttributesFrom,\n} from '@avsbhq/core';\n\nisMultiContext(multiCtx); // type guard: narrows an EvalContext to MultiContext\ngetContextByKind(multiCtx, 'user'); // extract a SingleContext from a multi-context\nuserContext('u_123', { plan: 'pro' }); // shorthand for {kind:'user',key:'u_123',plan:'pro'}\nbucketingKey(userCtx); // the key used for bucketing (kind-specific)\ncontextSummary(multiCtx); // [{kind,key}], for decision logging (no attributes)\nprivateAttributesFrom(userCtx); // attribute names the context marked private\n```\n\n---\n\n## 5. Multi-context\n\n`@avsbhq/core` defines the `MultiContext` type and the evaluator supports kinded targeting natively. A rule can target `organization.tier` while bucketing on `user.key`:\n\n```ts\n// Rule in the datafile:\n// { hashAttribute: 'user.key', audienceIds: ['org-enterprise-audience'] }\n//\n// Audience condition:\n// { contextKind: 'organization', attribute: 'tier', operator: 'equals', value: 'enterprise' }\n```\n\nThe `resolveDottedAttribute` helper (exported for conformance tests) resolves a dotted path like `'user.plan'` against a multi-context:\n\n```ts\nimport { resolveDottedAttribute } from '@avsbhq/core';\n\nresolveDottedAttribute(multiCtx, 'user.plan'); // → 'pro'\nresolveDottedAttribute(multiCtx, 'organization.tier'); // → 'enterprise'\n```\n\n---\n\n## 6. Reading flags: `Flag<T>` shape\n\nEvery evaluation in the SDK ecosystem returns a `Flag<T>`:\n\n```ts\nexport interface Flag<T = unknown> {\n  readonly value: T; // the variation value\n  readonly variationKey: string | null; // null if served the default\n  readonly source: EvaluationSource;\n  readonly ruleId: string | null;\n  readonly ruleType: RuleType | null;\n  readonly reasons: string[];\n  readonly evaluatedAt: number; // ms epoch\n  readonly durationMicros: number;\n  isEnabled(): boolean; // source === 'rule' && value is truthy\n  exists(): boolean; // source !== 'not_found'\n}\n```\n\n`EvaluationSource` values:\n\n```ts\ntype EvaluationSource =\n  | 'datafileOverride' // override declared in dashboard\n  | 'runtimeOverride' // set via setOverrideForUser / setGlobalOverride\n  | 'sticky' // sticky bucketing assignment\n  | 'rule' // matched a targeting or rollout rule\n  | 'holdout' // user is in a holdout cohort\n  | 'bandit' // bandit algorithm decision\n  | 'default' // no rule matched; falling through to default\n  | 'not_found' // flag key does not exist in the datafile\n  | 'disabled'; // flag is disabled globally\n```\n\nBuild `Flag<T>` objects in tests using the factory functions:\n\n```ts\nimport { createFlag, notFoundFlag } from '@avsbhq/core';\n\nconst flag = createFlag<boolean>({\n  value: true,\n  variationKey: 'on',\n  source: 'rule',\n  ruleId: 'r_abc',\n  ruleType: 'ab_test',\n  reasons: ['matched audience: paid-users'],\n});\n\nconst missing = notFoundFlag(false, 'flag key not in datafile');\n```\n\n---\n\n## 7. Tracking events\n\n`@avsbhq/core` defines the `TrackPayload` interface. Event submission is handled by the runtime SDKs (`@avsbhq/browser`, `@avsbhq/node`).\n\n```ts\nexport interface TrackPayload {\n  value?: number; // numeric metric quantity (revenue, count, etc.)\n  properties?: Record<string, unknown>; // free-form analytics properties\n  context?: EvalContext; // server SDK: required unless via forUser()\n}\n```\n\n---\n\n## 8. Error handling: `Logger`\n\n`@avsbhq/core` exports the shared `Logger` interface and factory functions:\n\n```ts\nimport { createLogger, noopLogger, consoleLogger, consoleTransport } from '@avsbhq/core';\n\n// Logger interface:\ninterface Logger {\n  debug(message: string, data?: Record<string, unknown>): void;\n  info(message: string, data?: Record<string, unknown>): void;\n  warn(message: string, data?: Record<string, unknown>): void;\n  error(message: string, data?: Record<string, unknown>): void;\n  child(prefix: string): Logger;\n}\n\n// Build a logger with multiple transports:\nconst logger = createLogger({\n  level: 'warn',\n  prefix: 'my-app',\n  transports: [consoleTransport('warn')],\n});\n```\n\nSee `@avsbhq/utils` for pino and winston adapters.\n\n---\n\n## 9. SSR / hydration\n\nNot applicable to `@avsbhq/core`. Hydration bootstrap logic lives in `@avsbhq/browser` (`serializeBootstrap` / `hydrateBootstrap`) and `@avsbhq/next` (`AvsbHydrator`, `AvsbServerProvider`).\n\n---\n\n## 10. Graceful shutdown\n\nNot applicable to `@avsbhq/core`. Lifecycle management (polling, streaming, event flushing) lives in the runtime SDKs.\n\n---\n\n## 11. Testing: using `@avsbhq/core` in tests\n\nWhen writing SDK port tests or testing code that handles `Flag<T>` objects, import the factory helpers directly:\n\n```ts\nimport { createFlag, notFoundFlag, createEventBus } from '@avsbhq/core';\nimport { evaluateFlag } from '@avsbhq/core/engine';\n\n// Build deterministic test flags\nconst FLAG_ENABLED = createFlag<boolean>({\n  value: true,\n  variationKey: 'on',\n  source: 'rule',\n  ruleId: 'r1',\n  ruleType: 'ab_test',\n  reasons: ['matched rule'],\n});\n\n// For application-level component and hook tests, use @avsbhq/test instead:\n// import { createMockClient, TestData } from '@avsbhq/test'\n// import { AvsbTestProvider } from '@avsbhq/test/react'\n```\n\nFor application tests (components, hooks, route handlers), do not import `@avsbhq/core/engine` directly. Use `@avsbhq/test` mock utilities instead: they provide a stable, lifecycle-aware mock that does not depend on internal engine primitives.\n\n---\n\n## 12. Migration\n\nThere is no direct competitor to `@avsbhq/core` as a standalone pure-engine package. LaunchDarkly and Statsig embed their evaluation engines inside their runtime SDKs without a separately installable engine package. If you are migrating from either vendor and need to understand the shared types, the relevant comparison is:\n\n| Concept            | LaunchDarkly         | Statsig         | `@avsbhq/core`         |\n| ------------------ | -------------------- | --------------- | ---------------------- |\n| Evaluation context | `LDContext`          | `StatsigUser`   | `EvalContext` (kinded) |\n| Flag result        | `LDEvaluationDetail` | `DynamicConfig` | `Flag<T>`              |\n| Event payload      | `LDCustomEventData`  | `LogEvent`      | `TrackPayload`         |\n| Evaluation source  | `LDEvaluationReason` | inferred        | `EvaluationSource`     |\n\n---\n\n## Things to never call directly\n\nEngine primitives (`evaluateFlag`, `evaluateAudience`, `murmurhash3`, `bucketContext`) live on the `@avsbhq/core/engine` subpath and are intentionally excluded from the default export.\n\nImporting these directly in application code bypasses the tracker, the override system, sticky buckets, holdout logic, and the event bus. Only import from `/engine` when:\n\n- You are implementing a per-language SDK port (Go, Python, Ruby, etc.)\n- You are writing conformance tests against `@avsbhq/conformance`\n- You are building a custom SDK layer\n\nDo not import from `@avsbhq/core/engine` in application code or component tests. Use the runtime SDK (or `@avsbhq/test` for mocking) instead.\n\n```ts\n// Engine subpath: for SDK implementors only\nimport {\n  evaluateFlag,\n  evaluateAudience,\n  murmurhash3,\n  bucketContext, // traffic-allocation bucket\n  assignmentBucket, // variation-assignment bucket\n  holdoutBucket, // holdout classification bucket\n  evaluateBandit,\n  evaluateHoldout,\n} from '@avsbhq/core/engine';\n```\n\nThe three bucket helpers exist because the evaluator computes three\ndifferent hashes from three different input strings. Port authors should\nread `packages/avsb-conformance/README.md` (the bucketing section) before\nimplementing them.\n","readmeFilename":"README.md"}