@liteguard/core 0.2.20260314
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/index.d.mts +729 -0
- package/dist/index.d.ts +729 -0
- package/dist/index.js +1372 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1343 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/evaluation.ts","../src/client-base.ts"],"sourcesContent":["export { BaseLiteguardClient, LiteguardScope } from './client-base.js';\nexport type { FlushOptions, LiteguardChangeListener, ScopedOptions } from './client-base.js';\nexport { evaluateGuard } from './evaluation.js';\nexport type {\n ExecutionAdapter,\n ExecutionState,\n MeasurementAdapter,\n RequestScopeAdapter,\n RequestScopeStore,\n RuntimeAdapter,\n} from './runtime.js';\nexport type {\n GetGuardsRequest,\n GetGuardsResponse,\n Guard,\n GuardCheckPerformance,\n GuardExecutionPerformance,\n ClientOptions,\n Options,\n Operator,\n Properties,\n PropertyValue,\n ProtectedContext,\n Rule,\n SendUnadoptedGuardsRequest,\n SendUnadoptedGuardsResponse,\n Signal,\n SignalPerformance,\n TraceContext,\n} from './types.js';\n","import type { Guard, Properties, PropertyValue, Rule } from './types.js';\n\n/**\n * Evaluate all rules for a guard against the given properties.\n *\n * Rules are checked in order; the first matching, enabled rule wins and its\n * `result` is returned. If no rule matches, the guard's `defaultValue` is\n * returned instead.\n *\n * @param guard - The guard definition containing rules and a default value.\n * @param properties - The property bag to evaluate each rule against.\n * @returns `true` if the guard is open (traffic should proceed), `false` otherwise.\n */\nexport function evaluateGuard(guard: Guard, properties: Properties): boolean {\n for (const rule of guard.rules) {\n if (!rule.enabled) {\n continue;\n }\n if (matchesRule(rule, properties)) {\n return rule.result;\n }\n }\n return guard.defaultValue;\n}\n\n/**\n * Return `true` when a single rule matches the provided property bag.\n *\n * Missing properties, empty rule value lists, and invalid regex patterns are\n * treated as non-matches so evaluation can continue to the next rule.\n *\n * @param rule - Rule to test.\n * @param properties - Property bag supplied to the guard evaluation.\n * @returns `true` when the rule matches, otherwise `false`.\n */\nfunction matchesRule(rule: Rule, properties: Properties): boolean {\n const raw = properties[rule.propertyName];\n if (raw === undefined) {\n return false;\n }\n if (rule.values.length === 0) {\n return false;\n }\n\n switch (rule.operator) {\n case 'EQUALS':\n return valuesEqual(raw, rule.values[0]);\n case 'NOT_EQUALS':\n return !valuesEqual(raw, rule.values[0]);\n case 'IN':\n return rule.values.some((value) => valuesEqual(raw, value));\n case 'NOT_IN':\n return rule.values.every((value) => !valuesEqual(raw, value));\n case 'REGEX': {\n const pattern = String(rule.values[0] ?? '');\n try {\n return new RegExp(pattern).test(String(raw));\n } catch {\n return false;\n }\n }\n case 'GT':\n return (compareOrdered(raw, rule.values[0]) ?? 0) > 0;\n case 'GTE':\n return (compareOrdered(raw, rule.values[0]) ?? -1) >= 0;\n case 'LT':\n return (compareOrdered(raw, rule.values[0]) ?? 0) < 0;\n case 'LTE':\n return (compareOrdered(raw, rule.values[0]) ?? 1) <= 0;\n default:\n return false;\n }\n}\n\n/**\n * Determine whether two Liteguard property values are equal without mixed-type\n * coercion.\n *\n * @param a - Actual property value from the request scope.\n * @param b - Rule value to compare against.\n * @returns `true` when the values are equal and of the same supported kind.\n */\nfunction valuesEqual(a: PropertyValue, b: PropertyValue | undefined): boolean {\n if (b === undefined) {\n return false;\n }\n if (typeof a === 'boolean' || typeof b === 'boolean') {\n return typeof a === 'boolean' && typeof b === 'boolean' && a === b;\n }\n if (typeof a === 'string' || typeof b === 'string') {\n return typeof a === 'string' && typeof b === 'string' && a === b;\n }\n\n if (typeof a === 'number' && typeof b === 'number') {\n return a === b;\n }\n\n return false;\n}\n\n/**\n * Compare two Liteguard property values for ordered operators without\n * mixed-type coercion.\n *\n * @param a - Actual property value from the request scope.\n * @param b - Rule value to compare against.\n * @returns A negative number when `a < b`, zero when equal, a positive number\n * when `a > b`, or `undefined` when the values are not comparable.\n */\nfunction compareOrdered(a: PropertyValue, b: PropertyValue | undefined): number | undefined {\n if (b === undefined) {\n return undefined;\n }\n if (typeof a === 'string' || typeof b === 'string') {\n if (typeof a !== 'string' || typeof b !== 'string') {\n return undefined;\n }\n return a.localeCompare(b);\n }\n if (typeof a === 'number' && typeof b === 'number') {\n return a - b;\n }\n return undefined;\n}\n","import { evaluateGuard } from './evaluation.js';\nimport type {\n GetGuardsRequest,\n Guard,\n ClientOptions,\n Options,\n Properties,\n ProtectedContext,\n SendUnadoptedGuardsRequest,\n Signal,\n} from './types.js';\nimport type { ExecutionState, RequestScopeStore, RuntimeAdapter } from './runtime.js';\n\nconst DEFAULT_BACKEND_URL = 'https://api.liteguard.io';\nconst DEFAULT_REFRESH_RATE_S = 30;\nconst DEFAULT_FLUSH_RATE_S = 10;\nconst DEFAULT_FLUSH_SIZE = 500;\nconst DEFAULT_HTTP_TIMEOUT_S = 4;\nconst DEFAULT_FLUSH_BUFFER_MULTIPLIER = 4;\nconst DEFAULT_QUIET = true;\nconst PUBLIC_BUNDLE_KEY = '';\n\n/** Callback invoked whenever the guard bundle is refreshed from the backend. */\nexport type LiteguardChangeListener = () => void;\n\n/** Options for {@link BaseLiteguardClient.flushSignals}. */\nexport type FlushOptions = {\n /**\n * When `true`, the underlying `fetch` request is sent with the\n * [`keepalive`](https://developer.mozilla.org/en-US/docs/Web/API/Request/keepalive)\n * flag so it survives page navigation. Set this when flushing during\n * `visibilitychange` or `pagehide` in the browser.\n */\n keepalive?: boolean;\n};\n\n/**\n * Per-call options accepted by guard-evaluation methods. Extends the\n * standard {@link Options} with an optional explicit {@link LiteguardScope}.\n */\nexport type ScopedOptions = Partial<Options> & {\n /**\n * Explicit scope to evaluate against. When omitted the client resolves the\n * scope from the current async context or falls back to the default scope.\n */\n scope?: LiteguardScope;\n};\n\ntype GuardBundle = {\n key: string;\n guards: Map<string, Guard>;\n ready: boolean;\n etag: string;\n protectedContext: ProtectedContext | null;\n refreshRateSeconds: number;\n};\n\ntype ScopeSnapshot = {\n properties: Properties;\n protectedBundleKey: string;\n protectedContext: ProtectedContext | null;\n};\n\ntype BufferedSignalInput = {\n guardName: string;\n result: boolean;\n properties: Properties;\n callsiteId: string;\n kind: 'guard_check' | 'guard_execution';\n measurement?: Signal['measurement'];\n parentSignalIdOverride?: string;\n};\n\n/**\n * Return a positive numeric option value, or the provided default when the\n * input is missing or invalid.\n */\nfunction positiveNumberOrDefault(value: number | undefined, fallback: number): number {\n return value !== undefined && value > 0 ? value : fallback;\n}\n\n/**\n * Return a trimmed string option when present, otherwise the provided default.\n */\nfunction nonEmptyStringOrDefault(value: string | undefined, fallback: string): string {\n return value !== undefined && value.trim() !== '' ? value : fallback;\n}\n\n/** Return a shallow copy of a property bag so scopes stay immutable. */\nfunction cloneProperties(properties: Properties): Properties {\n return { ...properties };\n}\n\n/**\n * Clone a protected-context payload so callers cannot mutate cached bundle\n * state through shared object references.\n */\nfunction cloneProtectedContext(protectedContext: ProtectedContext | null): ProtectedContext | null {\n if (!protectedContext) {\n return null;\n }\n return {\n signature: protectedContext.signature,\n properties: { ...(protectedContext.properties ?? {}) },\n };\n}\n\n/**\n * Build a stable cache key for a protected-context guard bundle.\n *\n * The key includes the signature and sorted property pairs so equivalent\n * contexts reuse the same fetched bundle regardless of object key order.\n */\nfunction protectedContextCacheKey(protectedContext: ProtectedContext | null): string {\n if (!protectedContext) {\n return PUBLIC_BUNDLE_KEY;\n }\n const keys = Object.keys(protectedContext.properties ?? {}).sort();\n const parts = [protectedContext.signature, ''];\n for (const key of keys) {\n parts.push(`${key}=${protectedContext.properties?.[key] ?? ''}`);\n }\n return parts.join('\\x00');\n}\n\n/**\n * Detect promise-like values so scope cleanup can be deferred until async\n * work settles.\n */\nfunction isPromiseLike<T>(value: T | PromiseLike<T>): value is PromiseLike<T> {\n return typeof value === 'object' && value !== null && 'then' in value;\n}\n\nfunction asyncContextUnsupportedError(operation: string): Error {\n return new Error(\n `[liteguard] ${operation} cannot cross await boundaries in this runtime. ` +\n 'Use an explicit LiteguardScope and call scope methods directly after each await.',\n );\n}\n\nlet signalCounter = 0;\n\n/**\n * An immutable snapshot of evaluation context (properties and optional\n * protected context) that can be passed to guard-evaluation methods.\n *\n * Scopes are created via {@link BaseLiteguardClient.createScope} or by\n * deriving from an existing scope with methods like {@link withProperties}.\n * They are cheap to create and safe to share across async boundaries.\n */\nexport class LiteguardScope {\n private readonly client: BaseLiteguardClient;\n private readonly snapshot: ScopeSnapshot;\n\n /** @internal — use {@link BaseLiteguardClient.createScope} instead. */\n constructor(client: BaseLiteguardClient, snapshot: ScopeSnapshot) {\n this.client = client;\n this.snapshot = {\n properties: cloneProperties(snapshot.properties),\n protectedBundleKey: snapshot.protectedBundleKey,\n protectedContext: cloneProtectedContext(snapshot.protectedContext),\n };\n }\n\n /**\n * Derive a new scope with the given properties merged on top of this\n * scope's existing properties. Does not mutate the current scope.\n *\n * @param properties - Key/value pairs to merge into the new scope.\n * @returns A new {@link LiteguardScope} with the merged properties.\n */\n withProperties(properties: Properties): LiteguardScope {\n return this.client._deriveScope(this, {\n properties: {\n ...this.snapshot.properties,\n ...properties,\n },\n });\n }\n\n /**\n * Alias for {@link withProperties} — derives a new scope with additional properties.\n *\n * @param properties - Key/value pairs to add.\n * @returns A new {@link LiteguardScope} with the merged properties.\n */\n addProperties(properties: Properties): LiteguardScope {\n return this.withProperties(properties);\n }\n\n /**\n * Derive a new scope with the specified property keys removed.\n *\n * @param names - Property keys to remove.\n * @returns A new {@link LiteguardScope} without the listed properties.\n */\n clearProperties(names: string[]): LiteguardScope {\n const next = cloneProperties(this.snapshot.properties);\n for (const name of names) {\n delete next[name];\n }\n return this.client._deriveScope(this, { properties: next });\n }\n\n /**\n * Derive a new scope with all properties removed.\n *\n * @returns A new {@link LiteguardScope} with an empty property bag.\n */\n resetProperties(): LiteguardScope {\n return this.client._deriveScope(this, { properties: {} });\n }\n\n /**\n * Derive a new scope bound to the supplied protected context. The client\n * will fetch (or reuse) a guard bundle specific to this context.\n *\n * @param protectedContext - Signed context bundle from your auth backend.\n * @returns A new {@link LiteguardScope} bound to the protected context.\n */\n async bindProtectedContext(protectedContext: ProtectedContext): Promise<LiteguardScope> {\n return await this.client._bindProtectedContextToScope(this, protectedContext);\n }\n\n /**\n * Derive a new scope with protected context cleared, reverting to the\n * public guard bundle.\n *\n * @returns A new {@link LiteguardScope} using the public guard bundle.\n */\n clearProtectedContext(): LiteguardScope {\n return this.client._deriveScope(this, {\n protectedBundleKey: PUBLIC_BUNDLE_KEY,\n protectedContext: null,\n });\n }\n\n /**\n * Check whether the named guard is open within this scope. Buffers a\n * `guard_check` telemetry signal.\n *\n * @param name - Guard name (e.g. `\"payments.checkout\"`).\n * @param options - Optional per-call overrides (extra properties, fallback).\n * @returns `true` if the guard is open, `false` otherwise.\n */\n isOpen(name: string, options: Partial<Options> = {}): boolean {\n return this.client.isOpen(name, { ...options, scope: this });\n }\n\n /**\n * Check whether the named guard is open without emitting a telemetry\n * signal or consuming a rate-limit slot. Useful in hot paths or render\n * loops where you only need the boolean result.\n *\n * @param name - Guard name to evaluate.\n * @param options - Optional per-call overrides.\n * @returns `true` if the guard is open, `false` otherwise.\n */\n peekIsOpen(name: string, options: Partial<Options> = {}): boolean {\n return this.client.peekIsOpen(name, { ...options, scope: this });\n }\n\n /**\n * Evaluate the guard and, if open, call `fn` within a correlated execution\n * scope. Returns `fn`'s result when open, or `undefined` when closed.\n *\n * Emits both a `guard_check` and a `guard_execution` telemetry signal so\n * you can measure the guarded code path.\n *\n * @param name - Guard name to evaluate.\n * @param fn - Synchronous function to invoke when the guard is open.\n * @param options - Optional per-call overrides.\n * @returns The return value of `fn`, or `undefined` if the guard is closed.\n */\n executeIfOpen<T>(name: string, fn: () => T, options: Partial<Options> = {}): T | undefined {\n return this.client.executeIfOpen(name, fn, { ...options, scope: this });\n }\n\n /**\n * Async variant of {@link executeIfOpen}. Evaluates the guard and, if open,\n * awaits `fn` within a correlated execution scope.\n *\n * @param name - Guard name to evaluate.\n * @param fn - Async function to invoke when the guard is open.\n * @param options - Optional per-call overrides.\n * @returns The resolved value of `fn`, or `undefined` if the guard is closed.\n */\n async executeIfOpenAsync<T>(\n name: string,\n fn: () => Promise<T>,\n options: Partial<Options> = {},\n ): Promise<T | undefined> {\n return await this.client.executeIfOpenAsync(name, fn, { ...options, scope: this });\n }\n\n /**\n * Run `fn` with this scope as the active scope for all guard checks made\n * during its execution.\n *\n * @param fn - Callback to execute within this scope.\n * @returns The return value of `fn`.\n */\n run<T>(fn: () => T): T {\n return this.client.runWithScope(this, fn);\n }\n\n /**\n * Run `fn` with this scope active **and** inside a Liteguard execution\n * context so that all guard signals share a common execution ID.\n *\n * @param fn - Callback to execute.\n * @returns The return value of `fn`.\n */\n withExecution<T>(fn: () => T): T {\n return this.client.runWithScope(this, () => this.client.withExecution(fn));\n }\n\n /**\n * Return a shallow copy of this scope's properties.\n *\n * @returns A plain object of property key/value pairs.\n */\n getProperties(): Properties {\n return cloneProperties(this.snapshot.properties);\n }\n\n /**\n * Return the protected context bound to this scope, or `null` if none.\n *\n * @returns A copy of the protected context, or `null`.\n */\n getProtectedContext(): ProtectedContext | null {\n return cloneProtectedContext(this.snapshot.protectedContext);\n }\n\n _getBundleKey(): string {\n return this.snapshot.protectedBundleKey;\n }\n\n _getSnapshot(): ScopeSnapshot {\n return {\n properties: cloneProperties(this.snapshot.properties),\n protectedBundleKey: this.snapshot.protectedBundleKey,\n protectedContext: cloneProtectedContext(this.snapshot.protectedContext),\n };\n }\n\n _belongsTo(client: BaseLiteguardClient): boolean {\n return this.client === client;\n }\n}\n\n/**\n * Core Liteguard client that evaluates guards, buffers telemetry signals,\n * and manages background refresh and flush cycles.\n *\n * This is the platform-agnostic base class. Use the platform-specific\n * `LiteguardClient` from `@liteguard/liteguard-node` or\n * `@liteguard/liteguard-browser` unless you are providing a custom\n * {@link RuntimeAdapter}.\n */\nexport class BaseLiteguardClient {\n private readonly projectClientKeyId: string;\n private readonly runtime: RuntimeAdapter;\n private readonly options: Required<ClientOptions>;\n\n private readonly bundles = new Map<string, GuardBundle>();\n private defaultScope: LiteguardScope;\n\n private signalBuffer: Signal[] = [];\n private droppedSignalsPending = 0;\n private readonly reportedUnadoptedGuards = new Set<string>();\n private readonly pendingUnadoptedGuards = new Set<string>();\n private refreshTimer: unknown = null;\n private flushTimer: unknown = null;\n private lifecycleCleanup: (() => void) | null = null;\n private currentRefreshRateSeconds: number;\n private readonly rateLimitState: Map<string, { windowStart: number; count: number }> = new Map();\n private readonly listeners = new Set<LiteguardChangeListener>();\n\n /**\n * Create a new Liteguard client.\n *\n * Call {@link start} after construction to fetch the initial guard bundle\n * and begin background timers.\n *\n * @param runtime - Platform adapter providing timers, fetch, and context storage.\n * @param projectClientKeyId - Your project client key ID from the Liteguard dashboard.\n * @param options - Optional SDK configuration overrides.\n */\n constructor(runtime: RuntimeAdapter, projectClientKeyId: string, options: ClientOptions = {}) {\n this.runtime = runtime;\n this.projectClientKeyId = projectClientKeyId;\n this.options = {\n environment: options.environment ?? '',\n fallback: options.fallback ?? false,\n refreshRateSeconds: positiveNumberOrDefault(options.refreshRateSeconds, DEFAULT_REFRESH_RATE_S),\n flushRateSeconds: positiveNumberOrDefault(options.flushRateSeconds, DEFAULT_FLUSH_RATE_S),\n flushSize: positiveNumberOrDefault(options.flushSize, DEFAULT_FLUSH_SIZE),\n httpTimeoutSeconds: positiveNumberOrDefault(options.httpTimeoutSeconds, DEFAULT_HTTP_TIMEOUT_S),\n flushBufferMultiplier: positiveNumberOrDefault(\n options.flushBufferMultiplier,\n DEFAULT_FLUSH_BUFFER_MULTIPLIER,\n ),\n disableMeasurement: options.disableMeasurement ?? false,\n backendUrl: nonEmptyStringOrDefault(options.backendUrl, DEFAULT_BACKEND_URL),\n quiet: options.quiet ?? DEFAULT_QUIET,\n };\n this.currentRefreshRateSeconds = this.options.refreshRateSeconds;\n this.bundles.set(PUBLIC_BUNDLE_KEY, this.createEmptyBundle(PUBLIC_BUNDLE_KEY, null));\n this.defaultScope = new LiteguardScope(this, {\n properties: {},\n protectedBundleKey: PUBLIC_BUNDLE_KEY,\n protectedContext: null,\n });\n }\n\n /**\n * Fetch the initial public guard bundle and start background refresh and\n * flush timers. Must be called once after construction before using the\n * client in production.\n */\n async start(): Promise<void> {\n await this.fetchGuardsForBundle(PUBLIC_BUNDLE_KEY);\n this.scheduleNextRefresh();\n\n this.flushTimer = this.runtime.setInterval(() => {\n void this.flushSignals();\n }, this.options.flushRateSeconds * 1_000);\n this.runtime.detachTimer?.(this.flushTimer);\n\n this.lifecycleCleanup = this.runtime.installLifecycleHooks?.({\n flushKeepalive: () => {\n void this.flushSignals({ keepalive: true });\n },\n }) ?? null;\n }\n\n /**\n * Stop all background timers and flush remaining buffered signals.\n * After calling `shutdown` the client should not be used further.\n */\n async shutdown(): Promise<void> {\n if (this.refreshTimer !== null) {\n this.runtime.clearTimeout(this.refreshTimer);\n this.refreshTimer = null;\n }\n if (this.flushTimer !== null) {\n this.runtime.clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n this.lifecycleCleanup?.();\n this.lifecycleCleanup = null;\n await this.flushSignals();\n }\n\n /**\n * Returns `true` once the initial public guard bundle has been fetched.\n */\n isReady(): boolean {\n return this.getBundle(PUBLIC_BUNDLE_KEY)?.ready ?? false;\n }\n\n /**\n * Register a listener that is called whenever the guard bundle is refreshed.\n *\n * @param listener - Callback invoked on each guard bundle update.\n * @returns An unsubscribe function — call it to remove the listener.\n *\n * @example\n * ```ts\n * const unsubscribe = client.subscribe(() => {\n * console.log('Guards refreshed');\n * });\n * // later…\n * unsubscribe();\n * ```\n */\n subscribe(listener: LiteguardChangeListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n /**\n * Create a new request scope with optional initial properties. The scope\n * uses the public guard bundle by default; call\n * {@link LiteguardScope.bindProtectedContext} on the returned scope to\n * attach signed user context.\n *\n * @param properties - Initial property key/value pairs for the scope.\n * @returns A new {@link LiteguardScope}.\n *\n * @example\n * ```ts\n * const scope = client.createScope({ plan: 'enterprise' });\n * scope.isOpen('feature.beta'); // evaluates with plan=enterprise\n * ```\n */\n createScope(properties: Properties = {}): LiteguardScope {\n return new LiteguardScope(this, {\n properties: cloneProperties(properties),\n protectedBundleKey: PUBLIC_BUNDLE_KEY,\n protectedContext: null,\n });\n }\n\n /**\n * Return the currently active request scope, or the shared default scope\n * when no request-local scope is active.\n *\n * On Node.js, the active scope is resolved from `AsyncLocalStorage` so\n * each concurrent request can carry its own context automatically.\n *\n * @returns The active {@link LiteguardScope}.\n */\n getActiveScope(): LiteguardScope {\n const active = this.getRuntimeScope();\n return active ?? this.defaultScope;\n }\n\n /**\n * Run `fn` inside the given request scope. All guard checks performed\n * during `fn` will use the properties and protected context of `scope`.\n *\n * @param scope - The scope to activate.\n * @param fn - Callback to execute within the scope.\n * @returns The return value of `fn`.\n */\n runWithScope<T>(scope: LiteguardScope, fn: () => T): T {\n const resolvedScope = this.resolveScope(scope);\n const adapter = this.runtime.requestScope;\n if (adapter) {\n const result = adapter.run({ currentScope: resolvedScope }, fn);\n if (isPromiseLike(result) && !this.runtime.supportsAsyncContextPropagation) {\n throw asyncContextUnsupportedError('scope.run(), client.runWithScope(), and property-scoped callbacks');\n }\n return result;\n }\n\n const previousScope = this.defaultScope;\n this.defaultScope = resolvedScope;\n try {\n const result = fn();\n if (isPromiseLike(result)) {\n if (!this.runtime.supportsAsyncContextPropagation) {\n throw asyncContextUnsupportedError('scope.run(), client.runWithScope(), and property-scoped callbacks');\n }\n return Promise.resolve(result).finally(() => {\n this.defaultScope = previousScope;\n }) as T;\n }\n this.defaultScope = previousScope;\n return result;\n } catch (error) {\n this.defaultScope = previousScope;\n throw error;\n }\n }\n\n /**\n * Convenience helper that derives a scope from the current active scope,\n * merges in the supplied properties, and runs `fn` inside it.\n *\n * @param properties - Key/value pairs to add for the duration of `fn`.\n * @param fn - Callback to execute within the scoped context.\n * @returns The return value of `fn`.\n *\n * @example\n * ```ts\n * const result = client.withProperties({ userId: '42' }, () => {\n * return client.isOpen('feature.beta');\n * });\n * ```\n */\n withProperties<T>(properties: Properties, fn: () => T): T {\n const scope = this.getActiveScope().withProperties(properties);\n return this.runWithScope(scope, fn);\n }\n\n /**\n * Bind protected context to a derived scope and run `fn` inside it.\n * Fetches (or reuses) a guard bundle specific to this context before\n * executing `fn`.\n *\n * @param protectedContext - Signed context bundle from your auth backend.\n * @param fn - Callback to execute within the protected scope.\n * @returns The (awaited) return value of `fn`.\n */\n async withProtectedContext<T>(\n protectedContext: ProtectedContext,\n fn: () => T | Promise<T>,\n ): Promise<Awaited<T>> {\n const scope = await this.getActiveScope().bindProtectedContext(protectedContext);\n return await Promise.resolve(this.runWithScope(scope, fn));\n }\n\n /**\n * Run `fn` inside a Liteguard execution scope so that all guard signals\n * emitted during `fn` share a common execution ID for correlated\n * telemetry. If an execution scope is already active, `fn` is called\n * directly without creating a new one.\n *\n * @param fn - Callback to execute within the execution scope.\n * @returns The return value of `fn`.\n */\n withExecution<T>(fn: () => T): T {\n const existing = this.runtime.execution.getStore();\n if (existing) {\n const result = fn();\n if (isPromiseLike(result) && !this.runtime.supportsAsyncContextPropagation) {\n throw asyncContextUnsupportedError('withExecution()');\n }\n return result;\n }\n const result = this.runtime.execution.run({ executionId: nextSignalId(), sequenceNumber: 0 }, fn);\n if (isPromiseLike(result) && !this.runtime.supportsAsyncContextPropagation) {\n throw asyncContextUnsupportedError('withExecution()');\n }\n return result;\n }\n\n /**\n * Return `true` if the named guard is open for the resolved request scope.\n * Buffers a `guard_check` telemetry signal and consumes a rate-limit slot\n * when applicable.\n *\n * Guards that have not yet been adopted on the Liteguard dashboard always\n * return `true`, allowing you to instrument code before enabling the guard.\n *\n * @param name - Guard name (e.g. `\"payments.checkout\"`).\n * @param callOptions - Optional per-call overrides (extra properties, fallback, scope).\n * @returns `true` if the guard is open, `false` otherwise.\n */\n isOpen(name: string, callOptions: ScopedOptions = {}): boolean {\n return this.evaluateIsOpen(name, callOptions, true);\n }\n\n /**\n * Signal-free variant of {@link isOpen}. Returns the same boolean result\n * but does **not** emit a telemetry signal or consume a rate-limit slot.\n * Ideal for render loops or other hot paths where you only need the\n * boolean value.\n *\n * @param name - Guard name to evaluate.\n * @param callOptions - Optional per-call overrides.\n * @returns `true` if the guard is open, `false` otherwise.\n */\n peekIsOpen(name: string, callOptions: ScopedOptions = {}): boolean {\n return this.evaluateIsOpen(name, callOptions, false);\n }\n\n private evaluateIsOpen(name: string, callOptions: ScopedOptions, emitSignal: boolean): boolean {\n const scope = this.resolveScope(callOptions.scope);\n const options: Options = {\n disableMeasurement: false,\n ...callOptions,\n };\n const fallback = options.fallback ?? this.options.fallback;\n const bundle = this.bundleForScope(scope);\n\n if (!bundle.ready) {\n return fallback;\n }\n\n const guard = bundle.guards.get(name);\n if (!guard) {\n this.recordUnadoptedGuard(name);\n return true;\n }\n if (!guard.adopted) {\n this.recordUnadoptedGuard(name);\n return true;\n }\n\n const props: Properties = {\n ...scope.getProperties(),\n ...(options.properties ?? {}),\n };\n\n let result = evaluateGuard(guard, props);\n if (result && guard.rateLimitPerMinute > 0) {\n result = emitSignal\n ? this.checkRateLimit(name, guard.rateLimitPerMinute, guard.rateLimitProperties, props)\n : this.wouldPassRateLimit(name, guard.rateLimitPerMinute, guard.rateLimitProperties, props);\n }\n\n if (emitSignal) {\n this.bufferSignal({\n guardName: name,\n result,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_check',\n measurement: this.isMeasurementEnabled(guard, options)\n ? this.runtime.measurement.captureGuardCheck()\n : undefined,\n });\n }\n\n return result;\n }\n\n /**\n * Evaluate the guard and, if open, call `fn` inside a correlated execution\n * scope. Returns `fn`'s result when the guard is open, or `undefined` when\n * closed. Emits correlated `guard_check` and `guard_execution` signals.\n *\n * @param name - Guard name to evaluate.\n * @param fn - Synchronous function to invoke when the guard is open.\n * @param callOptions - Optional per-call overrides.\n * @returns The return value of `fn`, or `undefined` if the guard is closed.\n *\n * @example\n * ```ts\n * const banner = client.executeIfOpen('promo.banner', () => {\n * return renderPromoBanner();\n * });\n * ```\n */\n executeIfOpen<T>(name: string, fn: () => T, callOptions: ScopedOptions = {}): T | undefined {\n const scope = this.resolveScope(callOptions.scope);\n return this.runWithScope(scope, () =>\n this.withExecution(() => {\n const options: Options = {\n disableMeasurement: false,\n ...callOptions,\n };\n const bundle = this.bundleForScope(scope);\n const guard = bundle.guards.get(name);\n const props: Properties = {\n ...scope.getProperties(),\n ...(options.properties ?? {}),\n };\n\n if (!this.isOpen(name, { ...options, scope })) {\n return undefined;\n }\n if (!guard?.adopted) {\n return fn();\n }\n\n const guardCheckSignalId = this.runtime.execution.getStore()?.lastSignalId;\n const measurementEnabled = this.isMeasurementEnabled(guard, options);\n const start = measurementEnabled ? this.runtime.measurement.beginGuardExecution() : undefined;\n\n try {\n const value = fn();\n this.bufferSignal({\n guardName: name,\n result: true,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_execution',\n measurement: measurementEnabled\n ? this.runtime.measurement.captureGuardExecution(start, true)\n : undefined,\n parentSignalIdOverride: guardCheckSignalId,\n });\n return value;\n } catch (error) {\n this.bufferSignal({\n guardName: name,\n result: true,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_execution',\n measurement: measurementEnabled\n ? this.runtime.measurement.captureGuardExecution(start, false, error)\n : undefined,\n parentSignalIdOverride: guardCheckSignalId,\n });\n throw error;\n }\n }),\n );\n }\n\n /**\n * Async variant of {@link executeIfOpen}. Evaluates the guard and, if\n * open, awaits `fn` inside a correlated execution scope.\n *\n * @param name - Guard name to evaluate.\n * @param fn - Async function to invoke when the guard is open.\n * @param callOptions - Optional per-call overrides.\n * @returns The resolved value of `fn`, or `undefined` if the guard is closed.\n */\n async executeIfOpenAsync<T>(\n name: string,\n fn: () => Promise<T>,\n callOptions: ScopedOptions = {},\n ): Promise<T | undefined> {\n const scope = this.resolveScope(callOptions.scope);\n if (!this.runtime.supportsAsyncContextPropagation) {\n return await this.executeIfOpenAsyncWithoutAsyncContext(name, scope, fn, callOptions);\n }\n return await this.runWithScope(scope, () =>\n this.withExecution(async () => {\n const options: Options = {\n disableMeasurement: false,\n ...callOptions,\n };\n const bundle = this.bundleForScope(scope);\n const guard = bundle.guards.get(name);\n const props: Properties = {\n ...scope.getProperties(),\n ...(options.properties ?? {}),\n };\n\n if (!this.isOpen(name, { ...options, scope })) {\n return undefined;\n }\n if (!guard?.adopted) {\n return await fn();\n }\n\n const guardCheckSignalId = this.runtime.execution.getStore()?.lastSignalId;\n const measurementEnabled = this.isMeasurementEnabled(guard, options);\n const start = measurementEnabled ? this.runtime.measurement.beginGuardExecution() : undefined;\n\n try {\n const value = await fn();\n this.bufferSignal({\n guardName: name,\n result: true,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_execution',\n measurement: measurementEnabled\n ? this.runtime.measurement.captureGuardExecution(start, true)\n : undefined,\n parentSignalIdOverride: guardCheckSignalId,\n });\n return value;\n } catch (error) {\n this.bufferSignal({\n guardName: name,\n result: true,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_execution',\n measurement: measurementEnabled\n ? this.runtime.measurement.captureGuardExecution(start, false, error)\n : undefined,\n parentSignalIdOverride: guardCheckSignalId,\n });\n throw error;\n }\n }),\n );\n }\n\n private async executeIfOpenAsyncWithoutAsyncContext<T>(\n name: string,\n scope: LiteguardScope,\n fn: () => Promise<T>,\n callOptions: ScopedOptions,\n ): Promise<T | undefined> {\n const options: Options = {\n disableMeasurement: false,\n ...callOptions,\n };\n const bundle = this.bundleForScope(scope);\n const guard = bundle.guards.get(name);\n const props: Properties = {\n ...scope.getProperties(),\n ...(options.properties ?? {}),\n };\n const executionState = this.runtime.execution.getStore() ?? { executionId: nextSignalId(), sequenceNumber: 0 };\n\n const isOpen = this.runWithExplicitExecutionState(executionState, () => this.isOpen(name, { ...options, scope }));\n if (!isOpen) {\n return undefined;\n }\n if (!guard?.adopted) {\n return await fn();\n }\n\n const guardCheckSignalId = executionState.lastSignalId;\n const measurementEnabled = this.isMeasurementEnabled(guard, options);\n const start = measurementEnabled ? this.runtime.measurement.beginGuardExecution() : undefined;\n\n try {\n const value = await fn();\n this.runWithExplicitExecutionState(executionState, () => {\n this.bufferSignal({\n guardName: name,\n result: true,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_execution',\n measurement: measurementEnabled\n ? this.runtime.measurement.captureGuardExecution(start, true)\n : undefined,\n parentSignalIdOverride: guardCheckSignalId,\n });\n });\n return value;\n } catch (error) {\n this.runWithExplicitExecutionState(executionState, () => {\n this.bufferSignal({\n guardName: name,\n result: true,\n properties: props,\n callsiteId: this.captureCallsiteId(),\n kind: 'guard_execution',\n measurement: measurementEnabled\n ? this.runtime.measurement.captureGuardExecution(start, false, error)\n : undefined,\n parentSignalIdOverride: guardCheckSignalId,\n });\n });\n throw error;\n }\n }\n\n /**\n * Merge `properties` into the active scope's property bag and persist\n * the derived scope as the new active scope. Subsequent {@link isOpen}\n * calls will include these properties unless overridden per-call.\n *\n * @param properties - Key/value pairs to add.\n * @returns The new active {@link LiteguardScope}.\n */\n addProperties(properties: Properties): LiteguardScope {\n const nextScope = this.getActiveScope().withProperties(properties);\n return this.replaceCurrentScope(nextScope);\n }\n\n /**\n * Remove the given property keys from the active scope and persist the\n * resulting scope.\n *\n * @param names - Property keys to remove.\n * @returns The new active {@link LiteguardScope}.\n */\n clearProperties(names: string[]): LiteguardScope {\n const nextScope = this.getActiveScope().clearProperties(names);\n return this.replaceCurrentScope(nextScope);\n }\n\n /**\n * Remove all properties from the active scope and persist the resulting\n * scope.\n *\n * @returns The new active {@link LiteguardScope} with an empty property bag.\n */\n resetProperties(): LiteguardScope {\n const nextScope = this.getActiveScope().resetProperties();\n return this.replaceCurrentScope(nextScope);\n }\n\n /**\n * Bind protected context to the active scope and persist the derived\n * scope. Fetches (or reuses) a guard bundle specific to this context.\n *\n * @param protectedContext - Signed context bundle from your auth backend.\n * @returns The new active {@link LiteguardScope}.\n */\n async bindProtectedContext(protectedContext: ProtectedContext): Promise<LiteguardScope> {\n const nextScope = await this.getActiveScope().bindProtectedContext(protectedContext);\n return this.replaceCurrentScope(nextScope);\n }\n\n /**\n * Clear protected context from the active scope and revert to the\n * public guard bundle.\n *\n * @returns The new active {@link LiteguardScope}.\n */\n clearProtectedContext(): LiteguardScope {\n const nextScope = this.getActiveScope().clearProtectedContext();\n return this.replaceCurrentScope(nextScope);\n }\n\n /**\n * Immediately transmit all buffered telemetry signals to the backend. Also\n * flushes any pending unadopted-guard reports.\n *\n * Call this before process exit or page unload to avoid losing signals.\n *\n * @param options - Flush options (e.g. `{ keepalive: true }` for page unload).\n */\n async flushSignals(options: FlushOptions = {}): Promise<void> {\n const signalBatch = this.signalBuffer.splice(0);\n const unadoptedGuardNames = [...this.pendingUnadoptedGuards];\n this.pendingUnadoptedGuards.clear();\n\n if (signalBatch.length > 0) {\n try {\n const url = new URL('/api/v1/signals', this.options.backendUrl);\n const body = JSON.stringify({\n projectClientKeyId: this.projectClientKeyId,\n environment: this.options.environment,\n signals: signalBatch,\n });\n await this.post(url, body, options.keepalive);\n } catch (error) {\n this.log('[liteguard] Signal flush failed', error);\n this.signalBuffer.unshift(...signalBatch);\n const maxBuf = this.options.flushSize * this.options.flushBufferMultiplier;\n if (this.signalBuffer.length > maxBuf) {\n this.droppedSignalsPending += this.signalBuffer.length - maxBuf;\n this.signalBuffer.length = maxBuf;\n }\n }\n }\n\n if (unadoptedGuardNames.length > 0) {\n try {\n const url = new URL('/api/v1/unadopted-guards', this.options.backendUrl);\n const requestBody: SendUnadoptedGuardsRequest = {\n projectClientKeyId: this.projectClientKeyId,\n environment: this.options.environment,\n guardNames: unadoptedGuardNames,\n };\n await this.post(url, JSON.stringify(requestBody), options.keepalive);\n } catch (error) {\n this.log('[liteguard] Unadopted guard flush failed', error);\n for (const guardName of unadoptedGuardNames) {\n this.pendingUnadoptedGuards.add(guardName);\n }\n }\n }\n }\n\n /** Notify subscribers that client-visible state has changed. */\n protected emitChange(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n\n /** @internal Derive a new immutable scope from an existing scope snapshot. */\n _deriveScope(scope: LiteguardScope, patch: Partial<ScopeSnapshot>): LiteguardScope {\n const resolved = this.resolveScope(scope);\n const snapshot = resolved._getSnapshot();\n return new LiteguardScope(this, {\n properties: patch.properties ? cloneProperties(patch.properties) : snapshot.properties,\n protectedBundleKey: patch.protectedBundleKey ?? snapshot.protectedBundleKey,\n protectedContext:\n patch.protectedContext === undefined\n ? snapshot.protectedContext\n : cloneProtectedContext(patch.protectedContext),\n });\n }\n\n /** @internal Bind protected context to a scope and ensure its bundle is loaded. */\n async _bindProtectedContextToScope(\n scope: LiteguardScope,\n protectedContext: ProtectedContext,\n ): Promise<LiteguardScope> {\n this.resolveScope(scope);\n const clonedProtectedContext = cloneProtectedContext(protectedContext);\n const bundleKey = await this.ensureBundleForProtectedContext(clonedProtectedContext);\n return new LiteguardScope(this, {\n properties: scope.getProperties(),\n protectedBundleKey: bundleKey,\n protectedContext: clonedProtectedContext,\n });\n }\n\n /** Persist a derived scope into the current request-local or default scope slot. */\n private replaceCurrentScope(nextScope: LiteguardScope): LiteguardScope {\n const resolved = this.resolveScope(nextScope);\n const store = this.runtime.requestScope?.getStore();\n if (store) {\n store.currentScope = resolved;\n return resolved;\n }\n\n this.defaultScope = resolved;\n this.emitChange();\n return resolved;\n }\n\n /** Resolve the active runtime scope store into a client-owned scope instance. */\n private getRuntimeScope(): LiteguardScope | null {\n const store = this.runtime.requestScope?.getStore();\n if (!store) {\n return null;\n }\n const scope = store.currentScope;\n if (scope instanceof LiteguardScope && scope._belongsTo(this)) {\n return scope;\n }\n return null;\n }\n\n /** Validate and resolve the scope used for a client operation. */\n private resolveScope(scope?: LiteguardScope): LiteguardScope {\n const resolved = scope ?? this.getRuntimeScope() ?? this.defaultScope;\n if (!resolved._belongsTo(this)) {\n throw new Error('[liteguard] Scope belongs to a different Liteguard client.');\n }\n return resolved;\n }\n\n /** Queue a one-time report for a guard that exists only in application code. */\n private recordUnadoptedGuard(name: string): void {\n if (!this.reportedUnadoptedGuards.has(name)) {\n this.reportedUnadoptedGuards.add(name);\n this.pendingUnadoptedGuards.add(name);\n }\n }\n\n /** Schedule the next periodic guard refresh using the current refresh interval. */\n private scheduleNextRefresh(): void {\n if (this.refreshTimer !== null) {\n this.runtime.clearTimeout(this.refreshTimer);\n }\n this.refreshTimer = this.runtime.setTimeout(() => {\n void this.runRefreshCycle();\n }, this.currentRefreshRateSeconds * 1_000);\n this.runtime.detachTimer?.(this.refreshTimer);\n }\n\n /** Refresh every cached bundle once, then reschedule the next cycle. */\n private async runRefreshCycle(): Promise<void> {\n if (this.refreshTimer === null) {\n return;\n }\n const bundleKeys = [...this.bundles.keys()].sort();\n for (const bundleKey of bundleKeys) {\n await this.fetchGuardsForBundle(bundleKey);\n }\n if (this.refreshTimer !== null) {\n this.scheduleNextRefresh();\n }\n }\n\n /** Create an empty bundle placeholder before the first successful fetch. */\n private createEmptyBundle(bundleKey: string, protectedContext: ProtectedContext | null): GuardBundle {\n return {\n key: bundleKey,\n guards: new Map(),\n ready: false,\n etag: '',\n protectedContext: cloneProtectedContext(protectedContext),\n refreshRateSeconds: this.options.refreshRateSeconds,\n };\n }\n\n /** Return a cached bundle by key, if present. */\n private getBundle(bundleKey: string): GuardBundle | undefined {\n return this.bundles.get(bundleKey);\n }\n\n /** Resolve the bundle used for a scope, falling back to the public bundle. */\n private bundleForScope(scope: LiteguardScope): GuardBundle {\n return this.getBundle(scope._getBundleKey())\n ?? this.getBundle(PUBLIC_BUNDLE_KEY)\n ?? this.createEmptyBundle(PUBLIC_BUNDLE_KEY, null);\n }\n\n /** Ensure the bundle for a protected context exists locally and is ready. */\n private async ensureBundleForProtectedContext(protectedContext: ProtectedContext | null): Promise<string> {\n const bundleKey = protectedContextCacheKey(protectedContext);\n const existing = this.getBundle(bundleKey);\n if (existing?.ready) {\n return bundleKey;\n }\n if (!existing) {\n this.bundles.set(bundleKey, this.createEmptyBundle(bundleKey, protectedContext));\n }\n await this.fetchGuardsForBundle(bundleKey);\n return bundleKey;\n }\n\n /** Use the shortest bundle refresh rate so all cached bundles stay current. */\n private recomputeRefreshInterval(): void {\n let next = 0;\n for (const bundle of this.bundles.values()) {\n if (bundle.refreshRateSeconds <= 0) {\n continue;\n }\n if (next === 0 || bundle.refreshRateSeconds < next) {\n next = bundle.refreshRateSeconds;\n }\n }\n if (next <= 0) {\n next = this.options.refreshRateSeconds;\n }\n if (next <= 0) {\n next = DEFAULT_REFRESH_RATE_S;\n }\n this.currentRefreshRateSeconds = next;\n }\n\n /** Fetch the latest guard bundle for a bundle key, respecting ETags and timeouts. */\n private async fetchGuardsForBundle(bundleKey: string): Promise<void> {\n const bundle = this.getBundle(bundleKey) ?? this.getBundle(PUBLIC_BUNDLE_KEY);\n const etag = bundle?.etag ?? '';\n const protectedContext = cloneProtectedContext(bundle?.protectedContext ?? null);\n const { signal, cleanup } = this.createTimeoutSignal(this.options.httpTimeoutSeconds * 1_000);\n try {\n const url = new URL('/api/v1/guards', this.options.backendUrl);\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.projectClientKeyId}`,\n 'Content-Type': 'application/json',\n };\n if (etag) {\n headers['If-None-Match'] = etag;\n }\n const requestBody: GetGuardsRequest = {\n projectClientKeyId: this.projectClientKeyId,\n environment: this.options.environment,\n ...(protectedContext ? { protectedContext } : {}),\n };\n\n const res = await this.runtime.fetch(url.toString(), {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n signal,\n });\n\n if (res.status === 304) {\n return;\n }\n if (!res.ok) {\n await res.text();\n this.log(`[liteguard] Guard fetch failed: ${res.status} ${res.statusText}`);\n return;\n }\n\n const body = (await res.json()) as {\n guards: Guard[];\n refreshRateSeconds?: number;\n etag?: string;\n };\n\n const guards = new Map<string, Guard>();\n for (const guard of body.guards) {\n guards.set(guard.name, guard);\n }\n\n const nextBundle = this.getBundle(bundleKey) ?? this.createEmptyBundle(bundleKey, protectedContext);\n nextBundle.guards = guards;\n nextBundle.ready = true;\n nextBundle.etag = body.etag ?? '';\n nextBundle.protectedContext = cloneProtectedContext(protectedContext);\n const previousRefreshRateSeconds = this.currentRefreshRateSeconds;\n nextBundle.refreshRateSeconds = positiveNumberOrDefault(\n body.refreshRateSeconds,\n this.options.refreshRateSeconds,\n );\n this.bundles.set(bundleKey, nextBundle);\n this.recomputeRefreshInterval();\n if (this.refreshTimer !== null && this.currentRefreshRateSeconds !== previousRefreshRateSeconds) {\n this.scheduleNextRefresh();\n }\n this.emitChange();\n } catch (error) {\n this.log('[liteguard] Guard fetch error:', error);\n } finally {\n cleanup();\n }\n }\n\n /** Create an `AbortSignal` that cancels an HTTP request after `timeoutMs`. */\n private createTimeoutSignal(timeoutMs: number): { signal: AbortSignal; cleanup: () => void } {\n const controller = new AbortController();\n const handle = this.runtime.setTimeout(() => {\n controller.abort();\n }, timeoutMs);\n this.runtime.detachTimer?.(handle);\n return {\n signal: controller.signal,\n cleanup: () => {\n this.runtime.clearTimeout(handle);\n },\n };\n }\n\n /** Send a JSON POST request to the Liteguard backend with the SDK defaults applied. */\n private async post(url: URL, body: string, keepalive = false): Promise<void> {\n const { signal, cleanup } = this.createTimeoutSignal(this.options.httpTimeoutSeconds * 1_000);\n try {\n const res = await this.runtime.fetch(url.toString(), {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.projectClientKeyId}`,\n 'Content-Type': 'application/json',\n ...(this.options.environment && { 'X-Liteguard-Environment': this.options.environment }),\n },\n body,\n signal,\n keepalive,\n });\n if (!res.ok) {\n throw new Error(`${res.status} ${res.statusText}`);\n }\n } finally {\n cleanup();\n }\n }\n\n /** Buffer a telemetry signal and trigger an eager flush when the batch is full. */\n private bufferSignal(input: BufferedSignalInput): Signal {\n const metadata = this.nextSignalMetadata(input.parentSignalIdOverride);\n const signal: Signal = {\n guardName: input.guardName,\n result: input.result,\n properties: { ...input.properties },\n timestampMs: this.runtime.now(),\n signalId: metadata.signalId,\n executionId: metadata.executionId,\n ...(metadata.parentSignalId ? { parentSignalId: metadata.parentSignalId } : {}),\n sequenceNumber: metadata.sequenceNumber,\n callsiteId: input.callsiteId,\n kind: input.kind,\n droppedSignalsSinceLast: this.takeDroppedSignals(),\n ...(input.measurement ? { measurement: input.measurement } : {}),\n };\n if (this.signalBuffer.length >= this.maxBufferSize()) {\n this.signalBuffer.shift();\n this.droppedSignalsPending += 1;\n }\n this.signalBuffer.push(signal);\n if (this.signalBuffer.length >= this.options.flushSize) {\n void this.flushSignals();\n }\n return signal;\n }\n\n /** Allocate signal correlation metadata for the current execution context. */\n private nextSignalMetadata(parentSignalIdOverride?: string): {\n signalId: string;\n executionId: string;\n parentSignalId?: string;\n sequenceNumber: number;\n } {\n const state = this.runtime.execution.getStore();\n const signalId = nextSignalId();\n if (!state) {\n return {\n signalId,\n executionId: nextSignalId(),\n sequenceNumber: 1,\n };\n }\n\n state.sequenceNumber += 1;\n const parentSignalId = parentSignalIdOverride ?? state.lastSignalId;\n state.lastSignalId = signalId;\n return {\n signalId,\n executionId: state.executionId,\n ...(parentSignalId ? { parentSignalId } : {}),\n sequenceNumber: state.sequenceNumber,\n };\n }\n\n private runWithExplicitExecutionState<T>(state: ExecutionState, fn: () => T): T {\n const existing = this.runtime.execution.getStore();\n if (existing === state) {\n return fn();\n }\n return this.runtime.execution.run(state, fn);\n }\n\n /** Capture the first external stack frame so telemetry can identify the call site. */\n private captureCallsiteId(): string {\n const err = new Error();\n const stack = err.stack?.split('\\n').slice(1) ?? [];\n const frame = stack.find((line) => {\n if (line.includes('node:internal')) return false;\n return !this.runtime.internalStackMarkers.some((marker) => line.includes(marker));\n });\n return frame?.trim().replace(/^at\\s+/, '') || 'unknown';\n }\n\n /** Build the in-memory rate-limit bucket key for a guard and property set. */\n private rateLimitBucketKey(name: string, rateLimitProperties: string[], props: Properties): string {\n if (rateLimitProperties.length === 0) return name;\n const parts = rateLimitProperties.map((property) => `${property}=${String(props[property] ?? '')}`);\n return `${name}\\x00${parts.join('\\x00')}`;\n }\n\n private checkRateLimit(\n name: string,\n limitPerMinute: number,\n rateLimitProperties: string[],\n props: Properties,\n ): boolean {\n const now = this.runtime.monotonicNow();\n const key = this.rateLimitBucketKey(name, rateLimitProperties, props);\n const state = this.rateLimitState.get(key) ?? { windowStart: now, count: 0 };\n if (now - state.windowStart >= 60_000) {\n state.windowStart = now;\n state.count = 0;\n }\n if (state.count >= limitPerMinute) {\n this.rateLimitState.set(key, state);\n return false;\n }\n state.count += 1;\n this.rateLimitState.set(key, state);\n return true;\n }\n\n /** Check whether a guard would pass the current rate-limit window without consuming a slot. */\n private wouldPassRateLimit(\n name: string,\n limitPerMinute: number,\n rateLimitProperties: string[],\n props: Properties,\n ): boolean {\n const now = this.runtime.monotonicNow();\n const key = this.rateLimitBucketKey(name, rateLimitProperties, props);\n const state = this.rateLimitState.get(key);\n if (!state) {\n return true;\n }\n if (now - state.windowStart >= 60_000) {\n return true;\n }\n return state.count < limitPerMinute;\n }\n\n /** Decide whether performance measurement should be captured for this guard call. */\n private isMeasurementEnabled(guard: Guard, options: Options): boolean {\n if (this.options.disableMeasurement) {\n return false;\n }\n if (options.disableMeasurement) {\n return false;\n }\n if (guard.disableMeasurement === true) {\n return false;\n }\n return true;\n }\n\n /** Return the hard cap for the in-memory signal buffer after flush failures. */\n private maxBufferSize(): number {\n return this.options.flushSize * this.options.flushBufferMultiplier;\n }\n\n /** Drain and reset the count of dropped signals to attach to the next emitted signal. */\n private takeDroppedSignals(): number {\n const dropped = this.droppedSignalsPending;\n this.droppedSignalsPending = 0;\n return dropped;\n }\n\n /** Write a warning only when quiet mode is disabled. */\n private log(...args: unknown[]): void {\n if (!this.options.quiet) {\n console.warn(...args);\n }\n }\n\n /** @internal Test helper for swapping the public guard bundle in memory. */\n _setGuards(guards: Guard[]): void {\n const bundle = this.getBundle(PUBLIC_BUNDLE_KEY) ?? this.createEmptyBundle(PUBLIC_BUNDLE_KEY, null);\n bundle.guards = new Map(guards.map((guard) => [guard.name, guard]));\n bundle.ready = true;\n bundle.etag = '';\n this.bundles.set(PUBLIC_BUNDLE_KEY, bundle);\n this.emitChange();\n }\n\n /** @internal Test helper for swapping a protected-context bundle in memory. */\n _setProtectedGuards(protectedContext: ProtectedContext, guards: Guard[]): void {\n const key = protectedContextCacheKey(protectedContext);\n const bundle = this.getBundle(key) ?? this.createEmptyBundle(key, protectedContext);\n bundle.guards = new Map(guards.map((guard) => [guard.name, guard]));\n bundle.ready = true;\n bundle.etag = '';\n bundle.protectedContext = cloneProtectedContext(protectedContext);\n this.bundles.set(key, bundle);\n this.recomputeRefreshInterval();\n this.emitChange();\n }\n\n /** @internal Clear all rate-limit counters, or only those for a specific guard. */\n _resetRateLimitState(name?: string): void {\n if (name !== undefined) {\n this.rateLimitState.delete(name);\n const prefix = name + '\\x00';\n for (const key of this.rateLimitState.keys()) {\n if (key.startsWith(prefix)) {\n this.rateLimitState.delete(key);\n }\n }\n return;\n }\n this.rateLimitState.clear();\n }\n\n /** @internal Return the default scope properties for tests and diagnostics. */\n _getContext(): Properties {\n return this.defaultScope.getProperties();\n }\n\n /** @internal Return the default scope protected context for tests and diagnostics. */\n _getProtectedContext(): ProtectedContext | null {\n return this.defaultScope.getProtectedContext();\n }\n\n /** @internal Return the active refresh cadence for tests and diagnostics. */\n _getRefreshRateSeconds(): number {\n return this.currentRefreshRateSeconds;\n }\n\n /** @internal Return a cloned view of the buffered signals for tests and diagnostics. */\n _getSignalBuffer(): Signal[] {\n return this.signalBuffer.map((signal) => ({\n ...signal,\n ...(signal.properties ? { properties: { ...signal.properties } } : {}),\n }));\n }\n\n /** @internal Return the sorted set of queued unadopted guards. */\n _getPendingUnadoptedGuards(): string[] {\n return [...this.pendingUnadoptedGuards].sort();\n }\n\n /** @internal Return the currently cached bundle keys. */\n _getBundleKeys(): string[] {\n return [...this.bundles.keys()].sort();\n }\n\n /** @internal Expose the request-scope store for tests. */\n _getRequestScopeStore(): RequestScopeStore | undefined {\n return this.runtime.requestScope?.getStore();\n }\n}\n\n/** Generate a lightweight unique identifier for signals and executions. */\nfunction nextSignalId(): string {\n signalCounter += 1;\n return `${Date.now().toString(36)}-${signalCounter.toString(36)}`;\n}\n"],"mappings":"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","names":["result"]}
|