UNPKG

@optimizely/optimizely-sdk

Version:

JavaScript SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts

1 lines 644 kB
{"version":3,"file":"index.node.es.min.mjs","sources":["../.build/utils/enums/index.js","../.build/utils/fns/index.js","../.build/logging/logger.js","../.build/error/optimizly_error.js","../.build/message/log_message.gen.js","../.build/message/error_message.gen.js","../.build/message/message_resolver.js","../.build/logging/logger_factory.js","../.build/error/error_notifier.js","../.build/error/error_notifier_factory.js","../.build/core/condition_tree_evaluator/index.js","../.build/project_config/optimizely_config.js","../.build/utils/config_validator/index.js","../.build/odp/odp_config.js","../.build/project_config/project_config.js","../.build/utils/promise/resolvablePromise.js","../.build/service.js","../.build/utils/event_emitter/event_emitter.js","../.build/project_config/project_config_manager.js","../node_modules/tslib/tslib.es6.mjs","../.build/project_config/constant.js","../.build/utils/http_request_handler/http_util.js","../.build/project_config/polling_datafile_manager.js","../.build/utils/repeater/repeater.js","../.build/utils/microtask/index.js","../.build/utils/cache/store_validator.js","../.build/project_config/config_manager_factory.js","../.build/utils/cache/store.js","../.build/event_processor/event_builder/log_event.js","../.build/utils/executor/backoff_retry_runner.js","../.build/utils/id_generator/index.js","../.build/core/decision/index.js","../.build/notification_center/type.js","../.build/shared_types.js","../.build/event_processor/event_builder/user_event.js","../.build/utils/event_tag_utils/index.js","../.build/utils/attributes_validator/index.js","../.build/event_processor/batch_event_processor.js","../.build/utils/executor/serial_runner.js","../.build/event_processor/event_store.js","../.build/event_processor/forwarding_event_processor.js","../.build/event_processor/event_processor_factory.js","../.build/utils/cache/in_memory_lru_cache.js","../.build/odp/event_manager/odp_event_api_manager.js","../.build/odp/constant.js","../.build/odp/event_manager/odp_event_manager.js","../.build/odp/event_manager/odp_event.js","../.build/vuid/vuid.js","../.build/odp/odp_manager.js","../.build/project_config/project_config_schema.js","../.build/odp/segment_manager/odp_response_schema.js","../.build/odp/segment_manager/odp_segment_api_manager.js","../.build/utils/json_schema_validator/index.js","../.build/odp/segment_manager/optimizely_segment_option.js","../.build/odp/segment_manager/odp_segment_manager.js","../.build/odp/odp_manager_factory.js","../.build/vuid/vuid_manager_factory.js","../.build/error/error_reporter.js","../.build/notification_center/index.js","../.build/optimizely_decision/index.js","../.build/optimizely_user_context/index.js","../.build/core/bucketer/bucket_value_generator.js","../.build/core/bucketer/index.js","../.build/utils/semantic_version/index.js","../.build/core/custom_attribute_condition_evaluator/index.js","../.build/core/audience_evaluator/odp_segment_condition_evaluator/index.js","../.build/core/audience_evaluator/index.js","../.build/utils/string_value_validator/index.js","../.build/utils/promise/operation_value.js","../.build/message/error_message.js","../.build/core/decision_service/index.js","../.build/optimizely/index.js","../.build/utils/user_profile_service_validator/index.js","../.build/utils/event_tags_validator/index.js","../.build/core/decision_service/cmab/cmab_client.js","../.build/core/decision_service/cmab/cmab_service.js","../.build/utils/cache/cache.js","../.build/client_factory.js","../.build/utils/http_request_handler/request_handler.node.js","../.build/event_processor/event_dispatcher/default_dispatcher.node.js","../.build/event_processor/event_dispatcher/default_dispatcher.js","../.build/project_config/config_manager_factory.node.js","../.build/event_processor/event_processor_factory.node.js","../.build/odp/odp_manager_factory.node.js","../.build/vuid/vuid_manager_factory.node.js","../.build/index.node.js"],"sourcesContent":["/**\n * Copyright 2016-2026, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const LOG_LEVEL = {\n NOTSET: 0,\n DEBUG: 1,\n INFO: 2,\n WARNING: 3,\n ERROR: 4,\n};\nexport const CONTROL_ATTRIBUTES = {\n BOT_FILTERING: '$opt_bot_filtering',\n BUCKETING_ID: '$opt_bucketing_id',\n STICKY_BUCKETING_KEY: '$opt_experiment_bucket_map',\n USER_AGENT: '$opt_user_agent',\n};\nexport const JAVASCRIPT_CLIENT_ENGINE = 'javascript-sdk';\nexport const NODE_CLIENT_ENGINE = 'node-sdk';\nexport const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk';\nexport const CLIENT_VERSION = '6.3.1';\n/*\n * Represents the source of a decision for feature management. When a feature\n * is accessed through isFeatureEnabled or getVariableValue APIs, the decision\n * source is used to decide whether to dispatch an impression event to\n * Optimizely.\n */\nexport const DECISION_SOURCES = {\n FEATURE_TEST: 'feature-test',\n ROLLOUT: 'rollout',\n EXPERIMENT: 'experiment',\n HOLDOUT: 'holdout',\n};\nexport const AUDIENCE_EVALUATION_TYPES = {\n RULE: 'rule',\n EXPERIMENT: 'experiment',\n};\n/*\n * Possible types of variables attached to features\n */\nexport const FEATURE_VARIABLE_TYPES = {\n BOOLEAN: 'boolean',\n DOUBLE: 'double',\n INTEGER: 'integer',\n STRING: 'string',\n JSON: 'json',\n};\n/*\n * Supported datafile versions\n */\nexport const DATAFILE_VERSIONS = {\n V2: '2',\n V3: '3',\n V4: '4',\n};\nexport const DECISION_MESSAGES = {\n SDK_NOT_READY: 'Optimizely SDK not configured properly yet.',\n FLAG_KEY_INVALID: 'No flag was found for key \"%s\".',\n VARIABLE_VALUE_INVALID: 'Variable value for key \"%s\" is invalid or wrong type.',\n};\n/**\n * Default milliseconds before request timeout\n */\nexport const REQUEST_TIMEOUT_MS = 60 * 1000; // 1 minute\nexport const DEFAULT_CMAB_CACHE_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes\nexport const DEFAULT_CMAB_CACHE_SIZE = 10000;\nexport const DEFAULT_CMAB_RETRIES = 1;\nexport const DEFAULT_CMAB_BACKOFF_MS = 100; // 100 milliseconds\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=index.js.map","/**\n * Copyright 2017, 2019-2020, 2022-2023, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { v4 } from 'uuid';\nconst MAX_SAFE_INTEGER_LIMIT = Math.pow(2, 53);\nexport function currentTimestamp() {\n return Math.round(new Date().getTime());\n}\nexport function isSafeInteger(number) {\n return typeof number == 'number' && Math.abs(number) <= MAX_SAFE_INTEGER_LIMIT;\n}\nexport function keyBy(arr, key) {\n if (!arr)\n return {};\n const base = {};\n assignBy(arr, key, base);\n return base;\n}\nexport function assignBy(arr, key, base) {\n if (!arr)\n return;\n arr.forEach((e) => {\n base[e[key]] = e;\n });\n}\nfunction isNumber(value) {\n return typeof value === 'number';\n}\nexport function uuid() {\n return v4();\n}\nexport function getTimestamp() {\n return new Date().getTime();\n}\nexport function groupBy(arr, grouperFn) {\n const grouper = {};\n arr.forEach(item => {\n const key = grouperFn(item);\n grouper[key] = grouper[key] || [];\n grouper[key].push(item);\n });\n return objectValues(grouper);\n}\nexport function objectValues(obj) {\n return Object.keys(obj).map(key => obj[key]);\n}\nexport function objectEntries(obj) {\n return Object.keys(obj).map(key => [key, obj[key]]);\n}\nexport function find(arr, cond) {\n let found;\n for (const item of arr) {\n if (cond(item)) {\n found = item;\n break;\n }\n }\n return found;\n}\n// TODO[OASIS-6649]: Don't use any type\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function sprintf(format, ...args) {\n let i = 0;\n return format.replace(/%s/g, function () {\n const arg = args[i++];\n const type = typeof arg;\n if (type === 'function') {\n return arg();\n }\n else if (type === 'string') {\n return arg;\n }\n else {\n return String(arg);\n }\n });\n}\n/**\n * Checks two string arrays for equality.\n * @param arrayA First Array to be compared against.\n * @param arrayB Second Array to be compared against.\n * @returns {boolean} True if both arrays are equal, otherwise returns false.\n */\nexport function checkArrayEquality(arrayA, arrayB) {\n return arrayA.length === arrayB.length && arrayA.every((item, index) => item === arrayB[index]);\n}\nexport default {\n checkArrayEquality,\n currentTimestamp,\n isSafeInteger,\n keyBy,\n uuid,\n isNumber,\n getTimestamp,\n groupBy,\n objectValues,\n objectEntries,\n find,\n sprintf,\n};\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=index.js.map","/**\n * Copyright 2019, 2024, 2025, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { OptimizelyError } from '../error/optimizly_error';\nimport { sprintf } from '../utils/fns';\nexport var LogLevel;\n(function (LogLevel) {\n LogLevel[LogLevel[\"Debug\"] = 0] = \"Debug\";\n LogLevel[LogLevel[\"Info\"] = 1] = \"Info\";\n LogLevel[LogLevel[\"Warn\"] = 2] = \"Warn\";\n LogLevel[LogLevel[\"Error\"] = 3] = \"Error\";\n})(LogLevel || (LogLevel = {}));\nexport const LogLevelToUpper = {\n [LogLevel.Debug]: 'DEBUG',\n [LogLevel.Info]: 'INFO',\n [LogLevel.Warn]: 'WARN',\n [LogLevel.Error]: 'ERROR',\n};\nexport const LogLevelToLower = {\n [LogLevel.Debug]: 'debug',\n [LogLevel.Info]: 'info',\n [LogLevel.Warn]: 'warn',\n [LogLevel.Error]: 'error',\n};\nexport class ConsoleLogHandler {\n constructor(prefix) {\n this.prefix = prefix || '[OPTIMIZELY]';\n }\n log(level, message) {\n const log = `${this.prefix} - ${LogLevelToUpper[level]} ${this.getTime()} ${message}`;\n this.consoleLog(level, log);\n }\n getTime() {\n return new Date().toISOString();\n }\n consoleLog(logLevel, log) {\n const methodName = LogLevelToLower[logLevel];\n const method = console[methodName] || console.log;\n method.call(console, log);\n }\n}\nexport class OptimizelyLogger {\n constructor(config) {\n this.prefix = '';\n this.logHandler = config.logHandler;\n this.infoResolver = config.infoMsgResolver;\n this.errorResolver = config.errorMsgResolver;\n this.level = config.level;\n if (config.name) {\n this.setName(config.name);\n }\n }\n child(name) {\n return new OptimizelyLogger({\n logHandler: this.logHandler,\n infoMsgResolver: this.infoResolver,\n errorMsgResolver: this.errorResolver,\n level: this.level,\n name,\n });\n }\n setName(name) {\n this.name = name;\n this.prefix = `${name}: `;\n }\n info(message, ...args) {\n this.log(LogLevel.Info, message, args);\n }\n debug(message, ...args) {\n this.log(LogLevel.Debug, message, args);\n }\n warn(message, ...args) {\n this.log(LogLevel.Warn, message, args);\n }\n error(message, ...args) {\n this.log(LogLevel.Error, message, args);\n }\n handleLog(level, message, args) {\n const log = args.length > 0 ? `${this.prefix}${sprintf(message, ...args)}`\n : `${this.prefix}${message}`;\n this.logHandler.log(level, log);\n }\n log(level, message, args) {\n if (level < this.level) {\n return;\n }\n if (message instanceof Error) {\n if (message instanceof OptimizelyError) {\n message.setMessage(this.errorResolver);\n }\n this.handleLog(level, message.message, []);\n return;\n }\n let resolver = this.errorResolver;\n if (level < LogLevel.Warn) {\n if (!this.infoResolver) {\n return;\n }\n resolver = this.infoResolver;\n }\n const resolvedMessage = resolver.resolve(message);\n this.handleLog(level, resolvedMessage, args);\n }\n}\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=logger.js.map","import { sprintf } from \"../utils/fns\";\nexport class OptimizelyError extends Error {\n constructor(baseMessage, ...params) {\n super();\n this.resolved = false;\n this.name = 'OptimizelyError';\n this.baseMessage = baseMessage;\n this.params = params;\n // this is needed cause instanceof doesn't work for\n // custom Errors when TS is compiled to es5\n Object.setPrototypeOf(this, OptimizelyError.prototype);\n }\n setMessage(resolver) {\n if (!this.resolved) {\n this.message = sprintf(resolver.resolve(this.baseMessage), ...this.params);\n this.resolved = true;\n }\n }\n}\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=optimizly_error.js.map","export const ADDING_AUTHORIZATION_HEADER_WITH_BEARER_TOKEN = '0';\nexport const AUDIENCE_EVALUATION_RESULT = '1';\nexport const CMAB_CACHE_ATTRIBUTES_MISMATCH = '2';\nexport const CMAB_CACHE_HIT = '3';\nexport const CMAB_CACHE_MISS = '4';\nexport const EVALUATING_AUDIENCE = '5';\nexport const FAILED_TO_PARSE_REVENUE = '6';\nexport const FAILED_TO_PARSE_VALUE = '7';\nexport const FEATURE_ENABLED_FOR_USER = '8';\nexport const FEATURE_NOT_ENABLED_FOR_USER = '9';\nexport const FEATURE_NOT_ENABLED_RETURN_DEFAULT_VARIABLE_VALUE = '10';\nexport const IGNORE_CMAB_CACHE = '11';\nexport const INVALIDATE_CMAB_CACHE = '12';\nexport const INVALID_CLIENT_ENGINE = '13';\nexport const INVALID_DECIDE_OPTIONS = '14';\nexport const INVALID_DEFAULT_DECIDE_OPTIONS = '15';\nexport const INVALID_EXPERIMENT_KEY_INFO = '16';\nexport const MAKING_DATAFILE_REQ_TO_URL_WITH_HEADERS = '17';\nexport const MISSING_ATTRIBUTE_VALUE = '18';\nexport const NOT_ACTIVATING_USER = '19';\nexport const PARSED_NUMERIC_VALUE = '20';\nexport const PARSED_REVENUE_VALUE = '21';\nexport const RESET_CMAB_CACHE = '22';\nexport const RESPONSE_STATUS_CODE = '23';\nexport const SAVED_LAST_MODIFIED_HEADER_VALUE_FROM_RESPONSE = '24';\nexport const SAVED_USER_VARIATION = '25';\nexport const SAVED_VARIATION_NOT_FOUND = '26';\nexport const SHOULD_NOT_DISPATCH_ACTIVATE = '27';\nexport const SKIPPING_JSON_VALIDATION = '28';\nexport const TRACK_EVENT = '29';\nexport const UNEXPECTED_TYPE_NULL = '30';\nexport const UPDATED_OPTIMIZELY_CONFIG = '31';\nexport const USER_HAS_NO_FORCED_VARIATION = '32';\nexport const USER_HAS_NO_FORCED_VARIATION_FOR_EXPERIMENT = '33';\nexport const USER_MAPPED_TO_FORCED_VARIATION = '34';\nexport const USER_RECEIVED_DEFAULT_VARIABLE_VALUE = '35';\nexport const USER_RECEIVED_VARIABLE_VALUE = '36';\nexport const VALID_BUCKETING_ID = '37';\nexport const VALID_DATAFILE = '38';\nexport const VALID_USER_PROFILE_SERVICE = '39';\nexport const VARIABLE_NOT_USED_RETURN_DEFAULT_VARIABLE_VALUE = '40';\nexport const VARIATION_REMOVED_FOR_USER = '41';\nexport const messages = [\n \"Adding Authorization header with Bearer Token\",\n \"Audience \\\"%s\\\" evaluated to %s.\",\n \"CMAB cache attributes mismatch for user %s and rule %s, fetching new decision.\",\n \"Cache hit for user %s and rule %s.\",\n \"Cache miss for user %s and rule %s.\",\n \"Starting to evaluate audience \\\"%s\\\" with conditions: %s.\",\n \"Failed to parse revenue value \\\"%s\\\" from event tags.\",\n \"Failed to parse event value \\\"%s\\\" from event tags.\",\n \"Feature %s is enabled for user %s.\",\n \"Feature %s is not enabled for user %s.\",\n \"Feature \\\"%s\\\" is not enabled for user %s. Returning the default variable value \\\"%s\\\".\",\n \"Ignoring CMAB cache for user %s and rule %s.\",\n \"Invalidating CMAB cache for user %s and rule %s.\",\n \"Invalid client engine passed: %s. Defaulting to node-sdk.\",\n \"Provided decide options is not an array. Using default decide options.\",\n \"Provided default decide options is not an array.\",\n \"Experiment key %s is not in datafile. It is either invalid, paused, or archived.\",\n \"Making datafile request to url %s with headers: %s\",\n \"Audience condition %s evaluated to UNKNOWN because no value was passed for user attribute \\\"%s\\\".\",\n \"Not activating user %s for experiment %s.\",\n \"Parsed event value \\\"%s\\\" from event tags.\",\n \"Parsed revenue value \\\"%s\\\" from event tags.\",\n \"Resetting CMAB cache for user %s and rule %s.\",\n \"Response status code: %s\",\n \"Saved last modified header value from response: %s\",\n \"Saved user profile for user \\\"%s\\\".\",\n \"User %s was previously bucketed into variation with ID %s for experiment %s, but no matching variation was found.\",\n \"Experiment %s is not in \\\"Running\\\" state. Not activating user.\",\n \"Skipping JSON schema validation.\",\n \"Tracking event %s for user %s.\",\n \"Audience condition %s evaluated to UNKNOWN because a null value was passed for user attribute \\\"%s\\\".\",\n \"Updated Optimizely config to revision %s (project id %s)\",\n \"User %s is not in the forced variation map.\",\n \"No experiment %s mapped to user %s in the forced variation map.\",\n \"Set variation %s for experiment %s and user %s in the forced variation map.\",\n \"User \\\"%s\\\" is not in any variation or rollout rule. Returning default value for variable \\\"%s\\\" of feature flag \\\"%s\\\".\",\n \"Got variable value \\\"%s\\\" for variable \\\"%s\\\" of feature flag \\\"%s\\\"\",\n \"BucketingId is valid: \\\"%s\\\"\",\n \"Datafile is valid.\",\n \"Valid user profile service provided.\",\n \"Variable \\\"%s\\\" is not used in variation \\\"%s\\\". Returning default value.\",\n \"Variation mapped to experiment %s has been removed for user %s.\"\n];\n//# sourceMappingURL=log_message.gen.js.map","export const BUCKETING_ID_NOT_STRING = '0';\nexport const CMAB_FETCH_FAILED = '1';\nexport const CONDITION_EVALUATOR_ERROR = '2';\nexport const DATAFILE_FETCH_REQUEST_FAILED = '3';\nexport const ERROR_FETCHING_DATAFILE = '4';\nexport const EVENT_ACTION_INVALID = '5';\nexport const EVENT_DATA_INVALID = '6';\nexport const EVENT_KEY_NOT_FOUND = '7';\nexport const EVENT_STORE_FULL = '8';\nexport const EXPERIMENT_KEY_NOT_IN_DATAFILE = '9';\nexport const FAILED_TO_DISPATCH_EVENTS = '10';\nexport const FAILED_TO_SEND_ODP_EVENTS = '11';\nexport const FEATURE_NOT_IN_DATAFILE = '12';\nexport const INVALID_ATTRIBUTES = '13';\nexport const INVALID_BUCKETING_ID = '14';\nexport const INVALID_CMAB_FETCH_RESPONSE = '15';\nexport const INVALID_CONFIG = '16';\nexport const INVALID_DATAFILE = '17';\nexport const INVALID_DATAFILE_MALFORMED = '18';\nexport const INVALID_DATAFILE_VERSION = '19';\nexport const INVALID_EVENT_TAGS = '20';\nexport const INVALID_EXPERIMENT_ID = '21';\nexport const INVALID_EXPERIMENT_KEY = '22';\nexport const INVALID_GROUP_ID = '23';\nexport const INVALID_INPUT_FORMAT = '24';\nexport const INVALID_JSON = '25';\nexport const INVALID_USER_ID = '26';\nexport const INVALID_USER_PROFILE_SERVICE = '27';\nexport const INVALID_VARIATION_KEY = '28';\nexport const MISSING_INTEGRATION_KEY = '29';\nexport const NOTIFICATION_LISTENER_EXCEPTION = '30';\nexport const NOT_TRACKING_USER = '31';\nexport const NO_DATAFILE_SPECIFIED = '32';\nexport const NO_EVENT_PROCESSOR = '33';\nexport const NO_JSON_PROVIDED = '34';\nexport const NO_PROJECT_CONFIG_FAILURE = '35';\nexport const NO_STATUS_CODE_IN_RESPONSE = '36';\nexport const NO_VARIATION_FOR_EXPERIMENT_KEY = '37';\nexport const ODP_CONFIG_NOT_AVAILABLE = '38';\nexport const ODP_EVENTS_SHOULD_HAVE_ATLEAST_ONE_KEY_VALUE = '39';\nexport const ODP_EVENT_FAILED = '40';\nexport const ODP_EVENT_MANAGER_STOPPED = '41';\nexport const ODP_MANAGER_MISSING = '42';\nexport const ODP_NOT_INTEGRATED = '43';\nexport const ONLY_POST_REQUESTS_ARE_SUPPORTED = '44';\nexport const OUT_OF_BOUNDS = '45';\nexport const PROMISE_NOT_ALLOWED = '46';\nexport const REQUEST_ERROR = '47';\nexport const REQUEST_TIMEOUT = '48';\nexport const RETRY_CANCELLED = '49';\nexport const SEND_BEACON_FAILED = '50';\nexport const SERVICE_NOT_RUNNING = '51';\nexport const UNABLE_TO_ATTACH_UNLOAD = '52';\nexport const UNABLE_TO_CAST_VALUE = '53';\nexport const UNABLE_TO_GET_VUID_VUID_MANAGER_NOT_AVAILABLE = '54';\nexport const UNABLE_TO_PARSE_AND_SKIPPED_HEADER = '55';\nexport const UNDEFINED_ATTRIBUTE = '56';\nexport const UNEXPECTED_CONDITION_VALUE = '57';\nexport const UNEXPECTED_RESERVED_ATTRIBUTE_PREFIX = '58';\nexport const UNEXPECTED_TYPE = '59';\nexport const UNKNOWN_CONDITION_TYPE = '60';\nexport const UNKNOWN_MATCH_TYPE = '61';\nexport const UNRECOGNIZED_ATTRIBUTE = '62';\nexport const UNRECOGNIZED_DECIDE_OPTION = '63';\nexport const UNSUPPORTED_PROTOCOL = '64';\nexport const USER_NOT_IN_FORCED_VARIATION = '65';\nexport const USER_PROFILE_LOOKUP_ERROR = '66';\nexport const USER_PROFILE_SAVE_ERROR = '67';\nexport const VARIABLE_KEY_NOT_IN_DATAFILE = '68';\nexport const VARIABLE_REQUESTED_WITH_WRONG_TYPE = '69';\nexport const VARIATION_ID_NOT_IN_DATAFILE = '70';\nexport const messages = [\n \"BucketingID attribute is not a string. Defaulted to userId\",\n \"CMAB decision fetch failed with status: %s\",\n \"Error evaluating audience condition of type %s: %s\",\n \"Datafile fetch request failed with status: %s\",\n \"Error fetching datafile: %s\",\n \"Event action invalid.\",\n \"Event data invalid.\",\n \"Event key %s is not in datafile.\",\n \"Event store is full. Not saving event with id %d.\",\n \"Experiment key %s is not in datafile.\",\n \"Failed to dispatch events, status: %s\",\n \"failed to send odp events\",\n \"Feature key %s is not in datafile.\",\n \"Provided attributes are in an invalid format.\",\n \"Unable to generate hash for bucketing ID %s: %s\",\n \"Invalid CMAB fetch response\",\n \"Provided Optimizely config is in an invalid format.\",\n \"Datafile is invalid - property %s: %s\",\n \"Datafile is invalid because it is malformed.\",\n \"This version of the JavaScript SDK does not support the given datafile version: %s\",\n \"Provided event tags are in an invalid format.\",\n \"Experiment ID %s is not in datafile.\",\n \"Experiment key %s is not in datafile. It is either invalid, paused, or archived.\",\n \"Group ID %s is not in datafile.\",\n \"Provided %s is in an invalid format.\",\n \"JSON object is not valid.\",\n \"Provided user ID is in an invalid format.\",\n \"Provided user profile service instance is in an invalid format: %s.\",\n \"Provided variation key is in an invalid format.\",\n \"Integration key missing from datafile. All integrations should include a key.\",\n \"Notification listener for (%s) threw exception: %s\",\n \"Not tracking user %s.\",\n \"No datafile specified. Cannot start optimizely.\",\n \"No event processor is provided\",\n \"No JSON object to validate against schema.\",\n \"No project config available. Failing %s.\",\n \"No status code in response\",\n \"No variation key %s defined in datafile for experiment %s.\",\n \"ODP config is not available.\",\n \"ODP events should have at least one key-value pair in identifiers.\",\n \"ODP event send failed.\",\n \"ODP event manager stopped before it could start\",\n \"ODP Manager is missing. %s failed.\",\n \"ODP is not integrated\",\n \"Only POST requests are supported\",\n \"Audience condition %s evaluated to UNKNOWN because the number value for user attribute \\\"%s\\\" is not in the range [-2^53, +2^53].\",\n \"Promise value is not allowed in sync operation\",\n \"Request error\",\n \"Request timeout\",\n \"Retry cancelled\",\n \"sendBeacon failed\",\n \"%s not running\",\n \"unable to bind optimizely.close() to page unload event: \\\"%s\\\"\",\n \"Unable to cast value %s to type %s, returning null.\",\n \"Unable to get VUID - VuidManager is not available\",\n \"Unable to parse & skipped header item\",\n \"Provided attribute: %s has an undefined value.\",\n \"Audience condition %s evaluated to UNKNOWN because the condition value is not supported.\",\n \"Attribute %s unexpectedly has reserved prefix %s; using attribute ID instead of reserved attribute name.\",\n \"Audience condition %s evaluated to UNKNOWN because a value of type \\\"%s\\\" was passed for user attribute \\\"%s\\\".\",\n \"Audience condition %s has an unknown condition type. You may need to upgrade to a newer release of the Optimizely SDK.\",\n \"Audience condition %s uses an unknown match type. You may need to upgrade to a newer release of the Optimizely SDK.\",\n \"Unrecognized attribute %s provided. Pruning before sending event to Optimizely.\",\n \"Unrecognized decide option %s provided.\",\n \"Unsupported protocol: %s\",\n \"User %s is not in the forced variation map. Cannot remove their forced variation.\",\n \"Error while looking up user profile for user ID \\\"%s\\\": %s.\",\n \"Error while saving user profile for user ID \\\"%s\\\": %s.\",\n \"Variable with key \\\"%s\\\" associated with feature with key \\\"%s\\\" is not in datafile.\",\n \"Requested variable type \\\"%s\\\", but variable is of type \\\"%s\\\". Use correct API to retrieve value. Returning None.\",\n \"Variation ID %s is not in the datafile.\"\n];\n//# sourceMappingURL=error_message.gen.js.map","import { messages as infoMessages } from 'log_message';\nimport { messages as errorMessages } from 'error_message';\nexport const infoResolver = {\n resolve(baseMessage) {\n const messageNum = parseInt(baseMessage);\n return infoMessages[messageNum] || baseMessage;\n }\n};\nexport const errorResolver = {\n resolve(baseMessage) {\n const messageNum = parseInt(baseMessage);\n return errorMessages[messageNum] || baseMessage;\n }\n};\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=message_resolver.js.map","/**\n * Copyright 2025, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { ConsoleLogHandler, LogLevel, OptimizelyLogger } from './logger';\nimport { errorResolver, infoResolver } from '../message/message_resolver';\nexport const INVALID_LOG_HANDLER = 'Invalid log handler';\nexport const INVALID_LEVEL_PRESET = 'Invalid level preset';\nconst debugPreset = {\n level: LogLevel.Debug,\n infoResolver,\n errorResolver,\n};\nconst infoPreset = {\n level: LogLevel.Info,\n infoResolver,\n errorResolver,\n};\nconst warnPreset = {\n level: LogLevel.Warn,\n errorResolver,\n};\nconst errorPreset = {\n level: LogLevel.Error,\n errorResolver,\n};\nconst levelPresetSymbol = Symbol();\nexport const DEBUG = {\n [levelPresetSymbol]: debugPreset,\n};\nexport const INFO = {\n [levelPresetSymbol]: infoPreset,\n};\nexport const WARN = {\n [levelPresetSymbol]: warnPreset,\n};\nexport const ERROR = {\n [levelPresetSymbol]: errorPreset,\n};\nexport const extractLevelPreset = (preset) => {\n if (!preset || typeof preset !== 'object' || !preset[levelPresetSymbol]) {\n throw new Error(INVALID_LEVEL_PRESET);\n }\n return preset[levelPresetSymbol];\n};\nconst loggerSymbol = Symbol();\nconst validateLogHandler = (logHandler) => {\n if (typeof logHandler !== 'object' || typeof logHandler.log !== 'function') {\n throw new Error(INVALID_LOG_HANDLER);\n }\n};\nexport const createLogger = (config) => {\n const { level, infoResolver, errorResolver } = extractLevelPreset(config.level);\n if (config.logHandler) {\n validateLogHandler(config.logHandler);\n }\n const loggerName = 'Optimizely';\n return {\n [loggerSymbol]: new OptimizelyLogger({\n name: loggerName,\n level,\n infoMsgResolver: infoResolver,\n errorMsgResolver: errorResolver,\n logHandler: config.logHandler || new ConsoleLogHandler(),\n }),\n };\n};\nexport const wrapLogger = (logger) => {\n return {\n [loggerSymbol]: logger,\n };\n};\nexport const extractLogger = (logger) => {\n if (!logger || typeof logger !== 'object') {\n return undefined;\n }\n return logger[loggerSymbol];\n};\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=logger_factory.js.map","import { OptimizelyError } from \"./optimizly_error\";\nexport class DefaultErrorNotifier {\n constructor(errorHandler, messageResolver, name) {\n this.errorHandler = errorHandler;\n this.messageResolver = messageResolver;\n this.name = name || '';\n }\n notify(error) {\n if (error instanceof OptimizelyError) {\n error.setMessage(this.messageResolver);\n }\n this.errorHandler.handleError(error);\n }\n child(name) {\n return new DefaultErrorNotifier(this.errorHandler, this.messageResolver, name);\n }\n}\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=error_notifier.js.map","/**\n * Copyright 2025, Optimizely\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { errorResolver } from \"../message/message_resolver\";\nimport { DefaultErrorNotifier } from \"./error_notifier\";\nexport const INVALID_ERROR_HANDLER = 'Invalid error handler';\nconst errorNotifierSymbol = Symbol();\nconst validateErrorHandler = (errorHandler) => {\n if (!errorHandler || typeof errorHandler !== 'object' || typeof errorHandler.handleError !== 'function') {\n throw new Error(INVALID_ERROR_HANDLER);\n }\n};\nexport const createErrorNotifier = (errorHandler) => {\n validateErrorHandler(errorHandler);\n return {\n [errorNotifierSymbol]: new DefaultErrorNotifier(errorHandler, errorResolver),\n };\n};\nexport const extractErrorNotifier = (errorNotifier) => {\n if (!errorNotifier || typeof errorNotifier !== 'object') {\n return undefined;\n }\n return errorNotifier[errorNotifierSymbol];\n};\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=error_notifier_factory.js.map","/****************************************************************************\n * Copyright 2018, 2021, Optimizely, Inc. and contributors *\n * *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); *\n * you may not use this file except in compliance with the License. *\n * You may obtain a copy of the License at *\n * *\n * http://www.apache.org/licenses/LICENSE-2.0 *\n * *\n * Unless required by applicable law or agreed to in writing, software *\n * distributed under the License is distributed on an \"AS IS\" BASIS, *\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *\n * See the License for the specific language governing permissions and *\n * limitations under the License. *\n ***************************************************************************/\nconst AND_CONDITION = 'and';\nconst OR_CONDITION = 'or';\nconst NOT_CONDITION = 'not';\nexport const DEFAULT_OPERATOR_TYPES = [AND_CONDITION, OR_CONDITION, NOT_CONDITION];\n/**\n * Top level method to evaluate conditions\n * @param {ConditionTree<Leaf>} conditions Nested array of and/or conditions, or a single leaf\n * condition value of any type\n * Example: ['and', '0', ['or', '1', '2']]\n * @param {LeafEvaluator<Leaf>} leafEvaluator Function which will be called to evaluate leaf condition\n * values\n * @return {?boolean} Result of evaluating the conditions using the operator\n * rules and the leaf evaluator. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nexport function evaluate(conditions, leafEvaluator) {\n if (Array.isArray(conditions)) {\n let firstOperator = conditions[0];\n let restOfConditions = conditions.slice(1);\n if (typeof firstOperator === 'string' && DEFAULT_OPERATOR_TYPES.indexOf(firstOperator) === -1) {\n // Operator to apply is not explicit - assume 'or'\n firstOperator = OR_CONDITION;\n restOfConditions = conditions;\n }\n switch (firstOperator) {\n case AND_CONDITION:\n return andEvaluator(restOfConditions, leafEvaluator);\n case NOT_CONDITION:\n return notEvaluator(restOfConditions, leafEvaluator);\n default:\n // firstOperator is OR_CONDITION\n return orEvaluator(restOfConditions, leafEvaluator);\n }\n }\n const leafCondition = conditions;\n return leafEvaluator(leafCondition);\n}\n/**\n * Evaluates an array of conditions as if the evaluator had been applied\n * to each entry and the results AND-ed together.\n * @param {unknown[]} conditions Array of conditions ex: [operand_1, operand_2]\n * @param {LeafEvaluator<Leaf>} leafEvaluator Function which will be called to evaluate leaf condition values\n * @return {?boolean} Result of evaluating the conditions. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nfunction andEvaluator(conditions, leafEvaluator) {\n let sawNullResult = false;\n if (Array.isArray(conditions)) {\n for (let i = 0; i < conditions.length; i++) {\n const conditionResult = evaluate(conditions[i], leafEvaluator);\n if (conditionResult === false) {\n return false;\n }\n if (conditionResult === null) {\n sawNullResult = true;\n }\n }\n return sawNullResult ? null : true;\n }\n return null;\n}\n/**\n * Evaluates an array of conditions as if the evaluator had been applied\n * to a single entry and NOT was applied to the result.\n * @param {unknown[]} conditions Array of conditions ex: [operand_1]\n * @param {LeafEvaluator<Leaf>} leafEvaluator Function which will be called to evaluate leaf condition values\n * @return {?boolean} Result of evaluating the conditions. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nfunction notEvaluator(conditions, leafEvaluator) {\n if (Array.isArray(conditions) && conditions.length > 0) {\n const result = evaluate(conditions[0], leafEvaluator);\n return result === null ? null : !result;\n }\n return null;\n}\n/**\n * Evaluates an array of conditions as if the evaluator had been applied\n * to each entry and the results OR-ed together.\n * @param {unknown[]} conditions Array of conditions ex: [operand_1, operand_2]\n * @param {LeafEvaluator<Leaf>} leafEvaluator Function which will be called to evaluate leaf condition values\n * @return {?boolean} Result of evaluating the conditions. A return value of null\n * indicates that the conditions are invalid or unable to be\n * evaluated.\n */\nfunction orEvaluator(conditions, leafEvaluator) {\n let sawNullResult = false;\n if (Array.isArray(conditions)) {\n for (let i = 0; i < conditions.length; i++) {\n const conditionResult = evaluate(conditions[i], leafEvaluator);\n if (conditionResult === true) {\n return true;\n }\n if (conditionResult === null) {\n sawNullResult = true;\n }\n }\n return sawNullResult ? null : false;\n }\n return null;\n}\nexport const __platforms = ['__universal__'];\n//# sourceMappingURL=index.js.map","import { DEFAULT_OPERATOR_TYPES } from '../core/condition_tree_evaluator';\n/**\n * The OptimizelyConfig class\n * @param {ProjectConfig} configObj\n * @param {string} datafile\n */\nexport class OptimizelyConfig {\n constructor(configObj, datafile, logger) {\n var _a, _b;\n this.sdkKey = (_a = configObj.sdkKey) !== null && _a !== void 0 ? _a : '';\n this.environmentKey = (_b = configObj.environmentKey) !== null && _b !== void 0 ? _b : '';\n this.attributes = configObj.attributes;\n this.audiences = OptimizelyConfig.getAudiences(configObj);\n this.events = configObj.events;\n this.revision = configObj.revision;\n const featureIdVariablesMap = (configObj.featureFlags || []).reduce((resultMap, feature) => {\n resultMap[feature.id] = feature.variables;\n return resultMap;\n }, {});\n const variableIdMap = OptimizelyConfig.getVariableIdMap(configObj);\n const { experimentsMapById, experimentsMapByKey } = OptimizelyConfig.getExperimentsMap(configObj, featureIdVariablesMap, variableIdMap, logger);\n this.experimentsMap = experimentsMapByKey;\n this.featuresMap = OptimizelyConfig.getFeaturesMap(configObj, featureIdVariablesMap, experimentsMapById, variableIdMap);\n this.datafile = datafile;\n }\n /**\n * Get the datafile\n * @returns {string} JSON string representation of the datafile that was used to create the current config object\n */\n getDatafile() {\n return this.datafile;\n }\n /**\n * Get Unique audiences list with typedAudiences as priority\n * @param {ProjectConfig} configObj\n * @returns {OptimizelyAudience[]} Array of unique audiences\n */\n static getAudiences(configObj) {\n const audiences = [];\n const typedAudienceIds = [];\n (configObj.typedAudiences || []).forEach((typedAudience) => {\n audiences.push({\n id: typedAudience.id,\n conditions: JSON.stringify(typedAudience.conditions),\n name: typedAudience.name,\n });\n typedAudienceIds.push(typedAudience.id);\n });\n (configObj.audiences || []).forEach((audience) => {\n if (typedAudienceIds.indexOf(audience.id) === -1 && audience.id != '$opt_dummy_audience') {\n audiences.push({\n id: audience.id,\n conditions: JSON.stringify(audience.conditions),\n name: audience.name,\n });\n }\n });\n return audiences;\n }\n /**\n * Converts list of audience conditions to serialized audiences used in experiment\n * for examples:\n * 1. Input: [\"or\", \"1\", \"2\"]\n * Output: \"\\\"us\\\" OR \\\"female\\\"\"\n * 2. Input: [\"not\", \"1\"]\n * Output: \"NOT \\\"us\\\"\"\n * 3. Input: [\"or\", \"1\"]\n * Output: \"\\\"us\\\"\"\n * 4. Input: [\"and\", [\"or\", \"1\", [\"and\", \"2\", \"3\"]], [\"and\", \"11\", [\"or\", \"12\", \"13\"]]]\n * Output: \"(\\\"us\\\" OR (\\\"female\\\" AND \\\"adult\\\")) AND (\\\"fr\\\" AND (\\\"male\\\" OR \\\"kid\\\"))\"\n * @param {Array<string | string[]>} conditions\n * @param {[id: string]: Audience} audiencesById\n * @returns {string} Serialized audiences condition string\n */\n static getSerializedAudiences(conditions, audiencesById) {\n let serializedAudience = '';\n if (conditions) {\n let cond = '';\n conditions.forEach((item) => {\n let subAudience = '';\n // Checks if item is list of conditions means it is sub audience\n if (item instanceof Array) {\n subAudience = OptimizelyConfig.getSerializedAudiences(item, audiencesById);\n subAudience = `(${subAudience})`;\n }\n else if (DEFAULT_OPERATOR_TYPES.indexOf(item) > -1) {\n cond = item.toUpperCase();\n }\n else {\n // Checks if item is audience id\n const audienceName = audiencesById[item] ? audiencesById[item].name : item;\n // if audience condition is \"NOT\" then add \"NOT\" at start. Otherwise check if there is already audience id in serializedAudience then append condition between serializedAudience and item\n if (serializedAudience || cond === 'NOT') {\n cond = cond === '' ? 'OR' : cond;\n if (serializedAudience === '') {\n serializedAudience = `${cond} \"${audiencesById[item].name}\"`;\n }\n else {\n serializedAudience = serializedAudience.concat(` ${cond} \"${audienceName}\"`);\n }\n }\n else {\n serializedAudience = `\"${audienceName}\"`;\n }\n }\n // Checks if sub audience is empty or not\n if (subAudience !== '') {\n if (serializedAudience !== '' || cond === 'NOT') {\n cond = cond === '' ? 'OR' : cond;\n if (serializedAudience === '') {\n serializedAudience = `${cond} ${subAudience}`;\n }\n else {\n serializedAudience = serializedAudience.concat(` ${cond} ${subAudience}`);\n }\n }\n else {\n serializedAudience = serializedAudience.concat(subAudience);\n }\n }\n });\n }\n return serializedAudience;\n }\n /**\n * Get serialized audience condition string for experiment\n * @param {Experiment} experiment\n * @param {ProjectConfig} configObj\n * @returns {string} Serialized audiences condition string\n */\n static getExperimentAudiences(experiment, configObj) {\n if (!experiment.audienceConditions) {\n return '';\n }\n return OptimizelyConfig.getSerializedAudiences(experiment.audienceConditions, configObj.audiencesById);\n }\n /**\n * Make map of featureVariable which are associated with given feature experiment\n * @param {FeatureVariablesMap} featureIdVariableMap\n * @param {[id: string]: FeatureVariable} variableIdMap\n * @param {string} featureId\n * @param {VariationVariable[] | undefined} featureVariableUsages\n * @param {boolean | undefined} isFeatureEnabled\n * @returns {OptimizelyVariablesMap} FeatureVariables mapped by key\n */\n static mergeFeatureVariables(featureIdVariableMap, variableIdMap, featureId, featureVariableUsages, isFeatureEnabled) {\n const variablesMap = (featureIdVariableMap[featureId] || []).reduce((optlyVariablesMap, featureVariable) => {\n optlyVariablesMap[featureVariable.key] = {\n id: featureVariable.id,\n key: featureVariable.key,\n type: featureVariable.type,\n value: featureVariable.defaultValue,\n };\n return optlyVariablesMap;\n }, {});\n (featureVariableUsages || []).forEach((featureVariableUsage) => {\n const defaultVariable = variableIdMap[featureVariableUsage.id];\n const optimizelyVariable = {\n id: featureVariableUsage.id,\n key: defaultVariable.key,\n type: defaultVariable.type,\n value: isFeatureEnabled ? featureVariableUsage.value : defaultVariable.defaultValue,\n };\n variablesMap[defaultVariable.key] = optimizelyVariable;\n });\n return variablesMap;\n }\n /**\n * Gets Map of all experiment variations and variables including rollouts\n * @param {Variation[]} variations\n * @param {FeatureVariablesMap} featureIdVariableMap\n * @param {{[id: string]: FeatureVariable}} variableIdMap\n * @param {string} featureId\n * @returns {[key: string]: Variation} Variations mapped by key\n */\n static getVariationsMap(variations, featureIdVariableMap, variableIdMap, featureId) {\n let variationsMap = {};\n variationsMap = variations.reduce((optlyVariationsMap, variation) => {\n const variablesMap = OptimizelyConfig.mergeFeatureVariables(featureIdVariableMap, variableIdMap, featureId, variation.variables, variation.featureEnabled);\n optlyVariationsMap[variation.key] = {\n id: variation.id,\n key: variation.key,\n featureEnabled: variation.featureEnabled,\n variablesMap: variablesMap,\n };\n return optlyVariationsMap;\n }, {});\n return variationsMap;\n }\n /**\n * Gets Map of FeatureVariable with respect to featureVariableId\n * @param {ProjectConfig} configObj\n * @returns {[id: string]: FeatureVariable} FeatureVariables mapped by id\n */\n static getVariableIdMap(configObj) {\n let variablesIdMap = {};\n variablesIdMap = (configObj.featureFlags || []).reduce((resultMap, feature) => {\n feature.variables.forEach((variable) => {\n resultMap[variable.id] = variable;\n });\n return resultMap;\n }, {});\n return variablesIdMap;\n }\n /**\n * Gets list of rollout experiments\n * @param {ProjectConfig} configObj\n * @param {FeatureVariablesMap} featureVariableIdMap\n * @param {string} featureId\n * @param {Experiment[]} experiments\n * @param {{[id: string]: FeatureVariable}} variableIdMap\n * @returns {OptimizelyExperiment[]} List of Optimizely rollout experiments\n */\n static getDeliveryRules(configObj, featureVa