Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
1 line
No EOL
7.7 KiB
Text
1 line
No EOL
7.7 KiB
Text
{"version":3,"file":"featureFlags.js","sources":["../../../src/utils/featureFlags.ts"],"sourcesContent":["import { getCurrentScope } from '../currentScopes';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { type Event } from '../types-hoist/event';\nimport { debug } from './debug-logger';\nimport { getActiveSpan, spanToJSON } from './spanUtils';\n\n/**\n * Ordered LRU cache for storing feature flags in the scope context. The name\n * of each flag in the buffer is unique, and the output of getAll() is ordered\n * from oldest to newest.\n */\n\nexport type FeatureFlag = { readonly flag: string; readonly result: boolean };\n\n/**\n * Max size of the LRU flag buffer stored in Sentry scope and event contexts.\n */\nexport const _INTERNAL_FLAG_BUFFER_SIZE = 100;\n\n/**\n * Max number of flag evaluations to record per span.\n */\nexport const _INTERNAL_MAX_FLAGS_PER_SPAN = 10;\n\nconst SPAN_FLAG_ATTRIBUTE_PREFIX = 'flag.evaluation.';\n\n/**\n * Copies feature flags that are in current scope context to the event context\n */\nexport function _INTERNAL_copyFlagsFromScopeToEvent(event: Event): Event {\n const scope = getCurrentScope();\n const flagContext = scope.getScopeData().contexts.flags;\n const flagBuffer = flagContext ? flagContext.values : [];\n\n if (!flagBuffer.length) {\n return event;\n }\n\n if (event.contexts === undefined) {\n event.contexts = {};\n }\n event.contexts.flags = { values: [...flagBuffer] };\n return event;\n}\n\n/**\n * Inserts a flag into the current scope's context while maintaining ordered LRU properties.\n * Not thread-safe. After inserting:\n * - The flag buffer is sorted in order of recency, with the newest evaluation at the end.\n * - The names in the buffer are always unique.\n * - The length of the buffer never exceeds `maxSize`.\n *\n * @param name Name of the feature flag to insert.\n * @param value Value of the feature flag.\n * @param maxSize Max number of flags the buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_insertFlagToScope(\n name: string,\n value: unknown,\n maxSize: number = _INTERNAL_FLAG_BUFFER_SIZE,\n): void {\n const scopeContexts = getCurrentScope().getScopeData().contexts;\n if (!scopeContexts.flags) {\n scopeContexts.flags = { values: [] };\n }\n const flags = scopeContexts.flags.values as FeatureFlag[];\n _INTERNAL_insertToFlagBuffer(flags, name, value, maxSize);\n}\n\n/**\n * Exported for tests only. Currently only accepts boolean values (otherwise no-op).\n * Inserts a flag into a FeatureFlag array while maintaining the following properties:\n * - Flags are sorted in order of recency, with the newest evaluation at the end.\n * - The flag names are always unique.\n * - The length of the array never exceeds `maxSize`.\n *\n * @param flags The buffer to insert the flag into.\n * @param name Name of the feature flag to insert.\n * @param value Value of the feature flag.\n * @param maxSize Max number of flags the buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_insertToFlagBuffer(\n flags: FeatureFlag[],\n name: string,\n value: unknown,\n maxSize: number,\n): void {\n if (typeof value !== 'boolean') {\n return;\n }\n\n if (flags.length > maxSize) {\n DEBUG_BUILD && debug.error(`[Feature Flags] insertToFlagBuffer called on a buffer larger than maxSize=${maxSize}`);\n return;\n }\n\n // Check if the flag is already in the buffer - O(n)\n const index = flags.findIndex(f => f.flag === name);\n\n if (index !== -1) {\n // The flag was found, remove it from its current position - O(n)\n flags.splice(index, 1);\n }\n\n if (flags.length === maxSize) {\n // If at capacity, pop the earliest flag - O(n)\n flags.shift();\n }\n\n // Push the flag to the end - O(1)\n flags.push({\n flag: name,\n result: value,\n });\n}\n\n/**\n * Records a feature flag evaluation for the active span. This is a no-op for non-boolean values.\n * The flag and its value is stored in span attributes with the `flag.evaluation` prefix. Once the\n * unique flags for a span reaches maxFlagsPerSpan, subsequent flags are dropped.\n *\n * @param name Name of the feature flag.\n * @param value Value of the feature flag. Non-boolean values are ignored.\n * @param maxFlagsPerSpan Max number of flags a buffer should store. Default value should always be used in production.\n */\nexport function _INTERNAL_addFeatureFlagToActiveSpan(\n name: string,\n value: unknown,\n maxFlagsPerSpan: number = _INTERNAL_MAX_FLAGS_PER_SPAN,\n): void {\n if (typeof value !== 'boolean') {\n return;\n }\n\n const span = getActiveSpan();\n if (!span) {\n return;\n }\n\n const attributes = spanToJSON(span).data;\n\n // If the flag already exists, always update it\n if (`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}` in attributes) {\n span.setAttribute(`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}`, value);\n return;\n }\n\n // Else, add the flag to the span if we have not reached the max number of flags\n const numOfAddedFlags = Object.keys(attributes).filter(key => key.startsWith(SPAN_FLAG_ATTRIBUTE_PREFIX)).length;\n if (numOfAddedFlags < maxFlagsPerSpan) {\n span.setAttribute(`${SPAN_FLAG_ATTRIBUTE_PREFIX}${name}`, value);\n }\n}\n"],"names":[],"mappings":"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"} |