@walkeros/web-destination-optimizely 3.4.2 → 4.0.0-next-1777882869103

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/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var t,e=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,a=(t,e,i,a)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let s of r(e))c.call(t,s)||s===i||n(t,s,{get:()=>e[s],enumerable:!(a=o(e,s))||a.enumerable});return t},s={};((t,e)=>{for(var o in e)n(t,o,{get:e[o],enumerable:!0})})(s,{DestinationOptimizely:()=>P,default:()=>z,destinationOptimizely:()=>I}),module.exports=(t=s,a(n({},"__esModule",{value:!0}),t));var l=Object.defineProperty;((t,e)=>{for(var n in e)l(t,n,{get:e[n],enumerable:!0})})({},{Level:()=>f});var u,f=((u=f||{})[u.ERROR=0]="ERROR",u[u.WARN=1]="WARN",u[u.INFO=2]="INFO",u[u.DEBUG=3]="DEBUG",u);function v(t){return Array.isArray(t)}function d(t){return void 0!==t}function y(t){return"number"==typeof t&&!Number.isNaN(t)}function p(t){return"object"==typeof t&&null!==t&&!v(t)&&"[object Object]"===Object.prototype.toString.call(t)}function b(t){return"string"==typeof t}function g(t,e="",n){const o=e.split(".");let r=t;for(let t=0;t<o.length;t++){const e=o[t];if("*"===e&&v(r)){const e=o.slice(t+1).join("."),i=[];for(const t of r){const o=g(t,e,n);i.push(o)}return i}if(r=r instanceof Object?r[e]:void 0,void 0===r)break}return d(r)?r:n}function O(t){return function(t){return"boolean"==typeof t}(t)||b(t)||y(t)||!d(t)||v(t)&&t.every(O)||p(t)&&Object.values(t).every(O)}function m(t){return O(t)?t:void 0}function j(t,e,n){return async function(...o){try{return await t(...o)}catch(t){if(!e)return;return await e(t)}finally{await(null==n?void 0:n())}}}async function w(t,e={},n={}){var o;if(!d(t))return;const r=p(t)&&t.consent||n.consent||(null==(o=n.collector)?void 0:o.consent),i=v(e)?e:[e];for(const e of i){const o=await j(h)(t,e,{...n,consent:r});if(d(o))return o}}async function h(t,e,n={}){const{collector:o,consent:r}=n;return(v(e)?e:[e]).reduce(async(e,i)=>{const c=await e;if(c)return c;const a=b(i)?{key:i}:i;if(!Object.keys(a).length)return;const{condition:s,consent:l,fn:u,key:f,loop:y,map:p,set:O,validate:k,value:P}=a;if(s&&!await j(s)(t,i,o))return;if(l&&!function(t,e={},n={}){const o={...e,...n},r={};let i=!t||0===Object.keys(t).length;return Object.keys(o).forEach(e=>{o[e]&&(r[e]=!0,t&&t[e]&&(i=!0))}),!!i&&r}(l,r))return P;let I=d(P)?P:t;if(u&&(I=await j(u)(t,i,n)),f&&(I=g(t,f,P)),y){const[e,o]=y,r="this"===e?[t]:await w(t,e,n);v(r)&&(I=(await Promise.all(r.map(t=>w(t,o,n)))).filter(d))}else p?I=await Object.entries(p).reduce(async(e,[o,r])=>{const i=await e,c=await w(t,r,n);return d(c)&&(i[o]=c),i},Promise.resolve({})):O&&(I=await Promise.all(O.map(e=>h(t,e,n))));k&&!await j(k)(I)&&(I=void 0);const z=m(I);return d(z)?z:m(P)},Promise.resolve(void 0))}var k=((t,o,r)=>(r=null!=t?e(i(t)):{},a(!o&&t&&t.__esModule?r:n(r,"default",{value:t,enumerable:!0}),t)))(require("@optimizely/optimizely-sdk")),P={};var I={type:"optimizely",config:{},async init({config:t,env:e}){var n,o,r,i;const c=t.settings;if(!(null==c?void 0:c.sdkKey))return!1;const a=function(t){return(null==t?void 0:t.optimizely)?t.optimizely:k}(e),s={projectConfigManager:a.createPollingProjectConfigManager({sdkKey:c.sdkKey,autoUpdate:null==(n=c.autoUpdate)||n,updateInterval:null!=(o=c.updateInterval)?o:6e4}),eventProcessor:a.createBatchEventProcessor({batchSize:null!=(r=c.batchSize)?r:10,flushInterval:null!=(i=c.flushInterval)?i:1e3})},l=a.createInstance(s);await l.onReady();const u={client:l};return{...t,settings:{...c,_state:u}}},async push(t,{config:e,rule:n,env:o,collector:r}){const i=e.settings||{},c=i._state||{},a=(null==n?void 0:n.settings)||{};if(!c.client)return;const s=i.userId;let l,u;if(void 0!==s){const e=await w(t,s,{collector:r});b(e)&&(l=e)}if(!l)return;if(void 0!==i.attributes){const e=await w(t,i.attributes,{collector:r});p(e)&&(u=e)}if(l!==c.lastUserId||!c.userContext){const t=c.client.createUserContext(l,u);if(!t)return;c.userContext=t,c.lastUserId=l}const f=c.userContext;if(f){if(void 0!==a.attributes){const e=await w(t,a.attributes,{collector:r});if(p(e))for(const[t,n]of Object.entries(e))f.setAttribute(t,n)}if(!0!==(null==n?void 0:n.skip)){const e=b(null==n?void 0:n.name)?n.name:t.name,o={};if(void 0!==a.eventTags){const e=await w(t,a.eventTags,{collector:r});p(e)&&Object.assign(o,e)}if(void 0!==a.revenue){const e=await w(t,a.revenue,{collector:r});y(e)&&(o.revenue=e)}if(void 0!==a.value){const e=await w(t,a.value,{collector:r});y(e)&&(o.value=e)}f.trackEvent(e,o)}i._state=c}},on(t,e){var n,o,r;if("consent"!==t||!e.data)return;const i=null==(n=e.config)?void 0:n.consent;if(!i||0===Object.keys(i).length)return;const c=e.data,a=Object.keys(i).every(t=>!0===c[t]),s=null==(r=null==(o=e.config)?void 0:o.settings)?void 0:r._state;!a&&(null==s?void 0:s.client)&&(s.client.close(),s.client=void 0,s.userContext=void 0)},destroy({config:t}){const e=((null==t?void 0:t.settings)||{})._state;(null==e?void 0:e.client)&&(e.client.close(),e.client=void 0,e.userContext=void 0)}},z=I;//# sourceMappingURL=index.js.map
1
+ "use strict";var t,e=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,a=(t,e,i,a)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let l of r(e))c.call(t,l)||l===i||n(t,l,{get:()=>e[l],enumerable:!(a=o(e,l))||a.enumerable});return t},l={};((t,e)=>{for(var o in e)n(t,o,{get:e[o],enumerable:!0})})(l,{DestinationOptimizely:()=>k,default:()=>z,destinationOptimizely:()=>I}),module.exports=(t=l,a(n({},"__esModule",{value:!0}),t));var s=Object.defineProperty;((t,e)=>{for(var n in e)s(t,n,{get:e[n],enumerable:!0})})({},{Level:()=>f});var u,f=((u=f||{})[u.ERROR=0]="ERROR",u[u.WARN=1]="WARN",u[u.INFO=2]="INFO",u[u.DEBUG=3]="DEBUG",u);function v(t){return Array.isArray(t)}function d(t){return void 0!==t}function y(t){return"number"==typeof t&&!Number.isNaN(t)}function p(t){return"object"==typeof t&&null!==t&&!v(t)&&"[object Object]"===Object.prototype.toString.call(t)}function g(t){return"string"==typeof t}function b(t,e="",n){const o=e.split(".");let r=t;for(let t=0;t<o.length;t++){const e=o[t];if("*"===e&&v(r)){const e=o.slice(t+1).join("."),i=[];for(const t of r){const o=b(t,e,n);i.push(o)}return i}if(r=r instanceof Object?r[e]:void 0,void 0===r)break}return d(r)?r:n}function m(t){return function(t){return"boolean"==typeof t}(t)||g(t)||y(t)||!d(t)||v(t)&&t.every(m)||p(t)&&Object.values(t).every(m)}function O(t){return m(t)?t:void 0}function w(t,e,n){return async function(...o){try{return await t(...o)}catch(t){if(!e)return;return await e(t)}finally{await(null==n?void 0:n())}}}async function j(t,e={},n={}){var o,r;if(!d(t))return;const i=p(t)&&t.consent||n.consent||(null==(o=n.collector)?void 0:o.consent),c=null!=(r=n.event)?r:p(t)?t:{};if(!n.collector)throw new Error("getMappingValue: context.collector is required");const a={event:c,mapping:e,collector:n.collector,logger:n.collector.logger,consent:i},l=v(e)?e:[e];for(const e of l){const n=await w(h)(t,e,{...a,mapping:e});if(d(n))return n}}async function h(t,e,n){return(v(e)?e:[e]).reduce(async(e,o)=>{const r=await e;if(r)return r;const i=g(o)?{key:o}:o;if(!Object.keys(i).length)return;const{condition:c,consent:a,fn:l,key:s,loop:u,map:f,set:y,validate:p,value:m}=i,P={...n,mapping:o};if(c&&!await w(c)(t,P))return;if(a&&!function(t,e={},n={}){const o={...e,...n},r={};let i=!t||0===Object.keys(t).length;return Object.keys(o).forEach(e=>{o[e]&&(r[e]=!0,t&&t[e]&&(i=!0))}),!!i&&r}(a,P.consent))return m;let k=d(m)?m:t;if(l&&(k=await w(l)(t,P)),s&&(k=b(t,s,m)),u){const[e,n]=u,o="this"===e?[t]:await j(t,e,P);v(o)&&(k=(await Promise.all(o.map(t=>j(t,n,P)))).filter(d))}else f?k=await Object.entries(f).reduce(async(e,[n,o])=>{const r=await e,i=await j(t,o,P);return d(i)&&(r[n]=i),r},Promise.resolve({})):y&&(k=await Promise.all(y.map(e=>h(t,e,P))));p&&!await w(p)(k,P)&&(k=void 0);const I=O(k);return d(I)?I:O(m)},Promise.resolve(void 0))}var P=((t,o,r)=>(r=null!=t?e(i(t)):{},a(!o&&t&&t.__esModule?r:n(r,"default",{value:t,enumerable:!0}),t)))(require("@optimizely/optimizely-sdk")),k={};var I={type:"optimizely",config:{},async init({config:t,env:e}){var n,o,r,i;const c=t.settings;if(!(null==c?void 0:c.sdkKey))return!1;const a=function(t){return(null==t?void 0:t.optimizely)?t.optimizely:P}(e),l={projectConfigManager:a.createPollingProjectConfigManager({sdkKey:c.sdkKey,autoUpdate:null==(n=c.autoUpdate)||n,updateInterval:null!=(o=c.updateInterval)?o:6e4}),eventProcessor:a.createBatchEventProcessor({batchSize:null!=(r=c.batchSize)?r:10,flushInterval:null!=(i=c.flushInterval)?i:1e3})},s=a.createInstance(l);await s.onReady();const u={client:s};return{...t,settings:{...c,_state:u}}},async push(t,{config:e,rule:n,env:o,collector:r}){const i=e.settings||{},c=i._state||{},a=(null==n?void 0:n.settings)||{};if(!c.client)return;const l=i.userId;let s,u;if(void 0!==l){const e=await j(t,l,{collector:r});g(e)&&(s=e)}if(!s)return;if(void 0!==i.attributes){const e=await j(t,i.attributes,{collector:r});p(e)&&(u=e)}if(s!==c.lastUserId||!c.userContext){const t=c.client.createUserContext(s,u);if(!t)return;c.userContext=t,c.lastUserId=s}const f=c.userContext;if(f){if(void 0!==a.attributes){const e=await j(t,a.attributes,{collector:r});if(p(e))for(const[t,n]of Object.entries(e))f.setAttribute(t,n)}if(!0!==(null==n?void 0:n.silent)){const e=g(null==n?void 0:n.name)?n.name:t.name,o={};if(void 0!==a.eventTags){const e=await j(t,a.eventTags,{collector:r});p(e)&&Object.assign(o,e)}if(void 0!==a.revenue){const e=await j(t,a.revenue,{collector:r});y(e)&&(o.revenue=e)}if(void 0!==a.value){const e=await j(t,a.value,{collector:r});y(e)&&(o.value=e)}f.trackEvent(e,o)}i._state=c}},on(t,e){var n,o,r;if("consent"!==t||!e.data)return;const i=null==(n=e.config)?void 0:n.consent;if(!i||0===Object.keys(i).length)return;const c=e.data,a=Object.keys(i).every(t=>!0===c[t]),l=null==(r=null==(o=e.config)?void 0:o.settings)?void 0:r._state;!a&&(null==l?void 0:l.client)&&(l.client.close(),l.client=void 0,l.userContext=void 0)},destroy({config:t}){const e=((null==t?void 0:t.settings)||{})._state;(null==e?void 0:e.client)&&(e.client.close(),e.client=void 0,e.userContext=void 0)}},z=I;//# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/index.ts"],"sourcesContent":["import type { WalkerOS } from '@walkeros/core';\nimport { getMappingValue, isNumber, isObject, isString } from '@walkeros/core';\nimport * as optimizelySDK from '@optimizely/optimizely-sdk';\nimport type {\n Destination,\n Env,\n OptimizelySDK as OptimizelySDKType,\n RuntimeState,\n Settings,\n} from './types';\n\n// Types export\nexport * as DestinationOptimizely from './types';\n\n/**\n * Resolve the Optimizely SDK: use the caller-provided mock when available\n * (tests), otherwise fall back to the real @optimizely/optimizely-sdk.\n */\nfunction getOptimizely(env: Env | undefined): OptimizelySDKType {\n if (env?.optimizely) return env.optimizely;\n return optimizelySDK as unknown as OptimizelySDKType;\n}\n\nexport const destinationOptimizely: Destination = {\n type: 'optimizely',\n\n config: {},\n\n async init({ config, env }) {\n const settings = config.settings;\n if (!settings?.sdkKey) return false;\n\n const sdk = getOptimizely(env as Env | undefined);\n\n const configManager = sdk.createPollingProjectConfigManager({\n sdkKey: settings.sdkKey,\n autoUpdate: settings.autoUpdate ?? true,\n updateInterval: settings.updateInterval ?? 60000,\n });\n\n const eventProcessor = sdk.createBatchEventProcessor({\n batchSize: settings.batchSize ?? 10,\n flushInterval: settings.flushInterval ?? 1000,\n });\n\n const instanceConfig: Record<string, unknown> = {\n projectConfigManager: configManager,\n eventProcessor: eventProcessor,\n };\n\n const client = sdk.createInstance(instanceConfig);\n await client.onReady();\n\n const _state: RuntimeState = { client };\n\n return { ...config, settings: { ...settings, _state } };\n },\n\n async push(event, { config, rule, env, collector }) {\n const settings = (config.settings || {}) as Settings;\n const state: RuntimeState = settings._state || {};\n const mappingSettings = rule?.settings || {};\n\n if (!state.client) return;\n\n // 1. Resolve userId\n const userIdMapping = settings.userId;\n let userId: string | undefined;\n if (userIdMapping !== undefined) {\n const resolved = await getMappingValue(event, userIdMapping, {\n collector,\n });\n if (isString(resolved)) userId = resolved;\n }\n\n // Fallback: no userId means we cannot create a user context\n if (!userId) return;\n\n // 2. Resolve destination-level attributes\n let baseAttributes: Record<string, unknown> | undefined;\n if (settings.attributes !== undefined) {\n const resolved = await getMappingValue(event, settings.attributes, {\n collector,\n });\n if (isObject(resolved)) {\n baseAttributes = resolved as Record<string, unknown>;\n }\n }\n\n // 3. Create or reuse user context\n if (userId !== state.lastUserId || !state.userContext) {\n const userContext = state.client.createUserContext(\n userId,\n baseAttributes,\n );\n if (!userContext) return;\n state.userContext = userContext;\n state.lastUserId = userId;\n }\n\n const userContext = state.userContext;\n if (!userContext) return;\n\n // 4. Per-event attributes via setAttribute\n if (mappingSettings.attributes !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.attributes,\n { collector },\n );\n if (isObject(resolved)) {\n for (const [key, value] of Object.entries(\n resolved as Record<string, unknown>,\n )) {\n userContext.setAttribute(key, value);\n }\n }\n }\n\n // 5. Track event (unless skip: true)\n if (rule?.skip !== true) {\n const eventKey = isString(rule?.name) ? rule.name : event.name;\n\n // Build eventTags\n const eventTags: Record<string, unknown> = {};\n\n // Resolve eventTags mapping first (so revenue/value can override)\n if (mappingSettings.eventTags !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.eventTags,\n { collector },\n );\n if (isObject(resolved)) {\n Object.assign(eventTags, resolved);\n }\n }\n\n // Revenue (integer, cents)\n if (mappingSettings.revenue !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.revenue, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.revenue = resolved;\n }\n }\n\n // Value (float)\n if (mappingSettings.value !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.value, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.value = resolved;\n }\n }\n\n userContext.trackEvent(eventKey, eventTags);\n }\n\n // Persist state mutations\n settings._state = state;\n },\n\n on(type, context) {\n if (type !== 'consent' || !context.data) return;\n\n const required = context.config?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const consent = context.data as WalkerOS.Consent;\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n\n const state = (context.config?.settings as Settings)?._state;\n if (!allGranted && state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n\n destroy({ config }) {\n const settings = (config?.settings || {}) as Settings;\n const state = settings._state;\n if (state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n};\n\nexport default destinationOptimizely;\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\n/**\n * Destination-level settings.\n */\nexport interface Settings {\n /** Optimizely Feature Experimentation SDK key. Required. */\n sdkKey: string;\n /** walkerOS mapping value to resolve userId for experiment bucketing. */\n userId?: WalkerOSMapping.Value;\n /** User attributes for audience targeting, applied to every event. */\n attributes?: WalkerOSMapping.Value;\n /** Polling interval for datafile updates in ms. Default: 60000. */\n updateInterval?: number;\n /** Auto-update datafile via polling. Default: true. */\n autoUpdate?: boolean;\n /** Batch event processor: events per batch. Default: 10. */\n batchSize?: number;\n /** Batch event processor: flush interval in ms. Default: 1000. */\n flushInterval?: number;\n /** Skip ODP manager initialization. Default: true. */\n skipOdp?: boolean;\n /** Runtime state -- not user-facing. Mutated by init/push. */\n _state?: RuntimeState;\n}\n\nexport interface RuntimeState {\n /** The Optimizely client instance (typed as OptimizelyClient). */\n client?: OptimizelyClient;\n /** Cached user context. Recreated when userId changes. */\n userContext?: OptimizelyUserContext;\n /** Last resolved userId to detect identity changes. */\n lastUserId?: string;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings.\n */\nexport interface Mapping {\n /** Override event key sent to Optimizely. If omitted, event.name is used. */\n eventKey?: string;\n /** Revenue mapping. Resolves to integer (cents). Passed as eventTags.revenue. */\n revenue?: WalkerOSMapping.Value;\n /** Numeric value mapping. Resolves to float. Passed as eventTags.value. */\n value?: WalkerOSMapping.Value;\n /** Additional event tags. Resolves to Record<string, unknown>. */\n eventTags?: WalkerOSMapping.Value;\n /** Per-event user attributes override. Merged onto user context for this event. */\n attributes?: WalkerOSMapping.Value;\n}\n\n/**\n * OptimizelyClient -- the subset of the Optimizely SDK client the destination\n * actually uses. Tests provide a mock via env.optimizely.\n */\nexport interface OptimizelyClient {\n onReady: () => Promise<{ success: boolean }>;\n createUserContext: (\n userId: string,\n attributes?: Record<string, unknown>,\n ) => OptimizelyUserContext | null;\n close: () => void;\n}\n\n/**\n * OptimizelyUserContext -- user context methods the destination calls.\n */\nexport interface OptimizelyUserContext {\n trackEvent: (eventKey: string, eventTags?: Record<string, unknown>) => void;\n setAttribute: (key: string, value: unknown) => void;\n}\n\n/**\n * OptimizelySDK -- factory functions the destination imports from the SDK.\n * Tests provide this via env.optimizely to avoid importing the real SDK.\n */\nexport interface OptimizelySDK {\n createInstance: (config: Record<string, unknown>) => OptimizelyClient;\n createPollingProjectConfigManager: (\n config: Record<string, unknown>,\n ) => unknown;\n createBatchEventProcessor: (config: Record<string, unknown>) => unknown;\n}\n\n/**\n * Env -- optional SDK override. Production leaves env.optimizely undefined\n * and the destination falls back to the real @optimizely/optimizely-sdk\n * import. Tests provide a mock via env.optimizely.\n */\nexport interface Env extends DestinationWeb.Env {\n optimizely?: OptimizelySDK;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":"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","names":["userContext"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/index.ts"],"sourcesContent":["import type { WalkerOS } from '@walkeros/core';\nimport { getMappingValue, isNumber, isObject, isString } from '@walkeros/core';\nimport * as optimizelySDK from '@optimizely/optimizely-sdk';\nimport type {\n Destination,\n Env,\n OptimizelySDK as OptimizelySDKType,\n RuntimeState,\n Settings,\n} from './types';\n\n// Types export\nexport * as DestinationOptimizely from './types';\n\n/**\n * Resolve the Optimizely SDK: use the caller-provided mock when available\n * (tests), otherwise fall back to the real @optimizely/optimizely-sdk.\n */\nfunction getOptimizely(env: Env | undefined): OptimizelySDKType {\n if (env?.optimizely) return env.optimizely;\n return optimizelySDK as unknown as OptimizelySDKType;\n}\n\nexport const destinationOptimizely: Destination = {\n type: 'optimizely',\n\n config: {},\n\n async init({ config, env }) {\n const settings = config.settings;\n if (!settings?.sdkKey) return false;\n\n const sdk = getOptimizely(env as Env | undefined);\n\n const configManager = sdk.createPollingProjectConfigManager({\n sdkKey: settings.sdkKey,\n autoUpdate: settings.autoUpdate ?? true,\n updateInterval: settings.updateInterval ?? 60000,\n });\n\n const eventProcessor = sdk.createBatchEventProcessor({\n batchSize: settings.batchSize ?? 10,\n flushInterval: settings.flushInterval ?? 1000,\n });\n\n const instanceConfig: Record<string, unknown> = {\n projectConfigManager: configManager,\n eventProcessor: eventProcessor,\n };\n\n const client = sdk.createInstance(instanceConfig);\n await client.onReady();\n\n const _state: RuntimeState = { client };\n\n return { ...config, settings: { ...settings, _state } };\n },\n\n async push(event, { config, rule, env, collector }) {\n const settings = (config.settings || {}) as Settings;\n const state: RuntimeState = settings._state || {};\n const mappingSettings = rule?.settings || {};\n\n if (!state.client) return;\n\n // 1. Resolve userId\n const userIdMapping = settings.userId;\n let userId: string | undefined;\n if (userIdMapping !== undefined) {\n const resolved = await getMappingValue(event, userIdMapping, {\n collector,\n });\n if (isString(resolved)) userId = resolved;\n }\n\n // Fallback: no userId means we cannot create a user context\n if (!userId) return;\n\n // 2. Resolve destination-level attributes\n let baseAttributes: Record<string, unknown> | undefined;\n if (settings.attributes !== undefined) {\n const resolved = await getMappingValue(event, settings.attributes, {\n collector,\n });\n if (isObject(resolved)) {\n baseAttributes = resolved as Record<string, unknown>;\n }\n }\n\n // 3. Create or reuse user context\n if (userId !== state.lastUserId || !state.userContext) {\n const userContext = state.client.createUserContext(\n userId,\n baseAttributes,\n );\n if (!userContext) return;\n state.userContext = userContext;\n state.lastUserId = userId;\n }\n\n const userContext = state.userContext;\n if (!userContext) return;\n\n // 4. Per-event attributes via setAttribute\n if (mappingSettings.attributes !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.attributes,\n { collector },\n );\n if (isObject(resolved)) {\n for (const [key, value] of Object.entries(\n resolved as Record<string, unknown>,\n )) {\n userContext.setAttribute(key, value);\n }\n }\n }\n\n // 5. Track event (unless silent: true)\n if (rule?.silent !== true) {\n const eventKey = isString(rule?.name) ? rule.name : event.name;\n\n // Build eventTags\n const eventTags: Record<string, unknown> = {};\n\n // Resolve eventTags mapping first (so revenue/value can override)\n if (mappingSettings.eventTags !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.eventTags,\n { collector },\n );\n if (isObject(resolved)) {\n Object.assign(eventTags, resolved);\n }\n }\n\n // Revenue (integer, cents)\n if (mappingSettings.revenue !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.revenue, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.revenue = resolved;\n }\n }\n\n // Value (float)\n if (mappingSettings.value !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.value, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.value = resolved;\n }\n }\n\n userContext.trackEvent(eventKey, eventTags);\n }\n\n // Persist state mutations\n settings._state = state;\n },\n\n on(type, context) {\n if (type !== 'consent' || !context.data) return;\n\n const required = context.config?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const consent = context.data as WalkerOS.Consent;\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n\n const state = (context.config?.settings as Settings)?._state;\n if (!allGranted && state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n\n destroy({ config }) {\n const settings = (config?.settings || {}) as Settings;\n const state = settings._state;\n if (state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n};\n\nexport default destinationOptimizely;\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\n/**\n * Destination-level settings.\n */\nexport interface Settings {\n /** Optimizely Feature Experimentation SDK key. Required. */\n sdkKey: string;\n /** walkerOS mapping value to resolve userId for experiment bucketing. */\n userId?: WalkerOSMapping.Value;\n /** User attributes for audience targeting, applied to every event. */\n attributes?: WalkerOSMapping.Value;\n /** Polling interval for datafile updates in ms. Default: 60000. */\n updateInterval?: number;\n /** Auto-update datafile via polling. Default: true. */\n autoUpdate?: boolean;\n /** Batch event processor: events per batch. Default: 10. */\n batchSize?: number;\n /** Batch event processor: flush interval in ms. Default: 1000. */\n flushInterval?: number;\n /** Skip ODP manager initialization. Default: true. */\n skipOdp?: boolean;\n /** Runtime state -- not user-facing. Mutated by init/push. */\n _state?: RuntimeState;\n}\n\nexport interface RuntimeState {\n /** The Optimizely client instance (typed as OptimizelyClient). */\n client?: OptimizelyClient;\n /** Cached user context. Recreated when userId changes. */\n userContext?: OptimizelyUserContext;\n /** Last resolved userId to detect identity changes. */\n lastUserId?: string;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings.\n */\nexport interface Mapping {\n /** Override event key sent to Optimizely. If omitted, event.name is used. */\n eventKey?: string;\n /** Revenue mapping. Resolves to integer (cents). Passed as eventTags.revenue. */\n revenue?: WalkerOSMapping.Value;\n /** Numeric value mapping. Resolves to float. Passed as eventTags.value. */\n value?: WalkerOSMapping.Value;\n /** Additional event tags. Resolves to Record<string, unknown>. */\n eventTags?: WalkerOSMapping.Value;\n /** Per-event user attributes override. Merged onto user context for this event. */\n attributes?: WalkerOSMapping.Value;\n}\n\n/**\n * OptimizelyClient -- the subset of the Optimizely SDK client the destination\n * actually uses. Tests provide a mock via env.optimizely.\n */\nexport interface OptimizelyClient {\n onReady: () => Promise<{ success: boolean }>;\n createUserContext: (\n userId: string,\n attributes?: Record<string, unknown>,\n ) => OptimizelyUserContext | null;\n close: () => void;\n}\n\n/**\n * OptimizelyUserContext -- user context methods the destination calls.\n */\nexport interface OptimizelyUserContext {\n trackEvent: (eventKey: string, eventTags?: Record<string, unknown>) => void;\n setAttribute: (key: string, value: unknown) => void;\n}\n\n/**\n * OptimizelySDK -- factory functions the destination imports from the SDK.\n * Tests provide this via env.optimizely to avoid importing the real SDK.\n */\nexport interface OptimizelySDK {\n createInstance: (config: Record<string, unknown>) => OptimizelyClient;\n createPollingProjectConfigManager: (\n config: Record<string, unknown>,\n ) => unknown;\n createBatchEventProcessor: (config: Record<string, unknown>) => unknown;\n}\n\n/**\n * Env -- optional SDK override. Production leaves env.optimizely undefined\n * and the destination falls back to the real @optimizely/optimizely-sdk\n * import. Tests provide a mock via env.optimizely.\n */\nexport interface Env extends DestinationWeb.Env {\n optimizely?: OptimizelySDK;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":"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","names":["userContext"]}
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var t=Object.defineProperty;((e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})})({},{Level:()=>n});var e,n=((e=n||{})[e.ERROR=0]="ERROR",e[e.WARN=1]="WARN",e[e.INFO=2]="INFO",e[e.DEBUG=3]="DEBUG",e);function o(t){return Array.isArray(t)}function i(t){return void 0!==t}function r(t){return"number"==typeof t&&!Number.isNaN(t)}function c(t){return"object"==typeof t&&null!==t&&!o(t)&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return"string"==typeof t}function s(t,e="",n){const r=e.split(".");let c=t;for(let t=0;t<r.length;t++){const e=r[t];if("*"===e&&o(c)){const e=r.slice(t+1).join("."),o=[];for(const t of c){const i=s(t,e,n);o.push(i)}return o}if(c=c instanceof Object?c[e]:void 0,void 0===c)break}return i(c)?c:n}function l(t){return function(t){return"boolean"==typeof t}(t)||a(t)||r(t)||!i(t)||o(t)&&t.every(l)||c(t)&&Object.values(t).every(l)}function u(t){return l(t)?t:void 0}function f(t,e,n){return async function(...o){try{return await t(...o)}catch(t){if(!e)return;return await e(t)}finally{await(null==n?void 0:n())}}}async function v(t,e={},n={}){var r;if(!i(t))return;const a=c(t)&&t.consent||n.consent||(null==(r=n.collector)?void 0:r.consent),s=o(e)?e:[e];for(const e of s){const o=await f(d)(t,e,{...n,consent:a});if(i(o))return o}}async function d(t,e,n={}){const{collector:r,consent:c}=n;return(o(e)?e:[e]).reduce(async(e,l)=>{const y=await e;if(y)return y;const p=a(l)?{key:l}:l;if(!Object.keys(p).length)return;const{condition:b,consent:g,fn:m,key:w,loop:j,map:O,set:h,validate:k,value:I}=p;if(b&&!await f(b)(t,l,r))return;if(g&&!function(t,e={},n={}){const o={...e,...n},i={};let r=!t||0===Object.keys(t).length;return Object.keys(o).forEach(e=>{o[e]&&(i[e]=!0,t&&t[e]&&(r=!0))}),!!r&&i}(g,c))return I;let P=i(I)?I:t;if(m&&(P=await f(m)(t,l,n)),w&&(P=s(t,w,I)),j){const[e,r]=j,c="this"===e?[t]:await v(t,e,n);o(c)&&(P=(await Promise.all(c.map(t=>v(t,r,n)))).filter(i))}else O?P=await Object.entries(O).reduce(async(e,[o,r])=>{const c=await e,a=await v(t,r,n);return i(a)&&(c[o]=a),c},Promise.resolve({})):h&&(P=await Promise.all(h.map(e=>d(t,e,n))));k&&!await f(k)(P)&&(P=void 0);const R=u(P);return i(R)?R:u(I)},Promise.resolve(void 0))}import*as y from"@optimizely/optimizely-sdk";var p={};var b={type:"optimizely",config:{},async init({config:t,env:e}){var n,o,i,r;const c=t.settings;if(!(null==c?void 0:c.sdkKey))return!1;const a=function(t){return(null==t?void 0:t.optimizely)?t.optimizely:y}(e),s={projectConfigManager:a.createPollingProjectConfigManager({sdkKey:c.sdkKey,autoUpdate:null==(n=c.autoUpdate)||n,updateInterval:null!=(o=c.updateInterval)?o:6e4}),eventProcessor:a.createBatchEventProcessor({batchSize:null!=(i=c.batchSize)?i:10,flushInterval:null!=(r=c.flushInterval)?r:1e3})},l=a.createInstance(s);await l.onReady();const u={client:l};return{...t,settings:{...c,_state:u}}},async push(t,{config:e,rule:n,env:o,collector:i}){const s=e.settings||{},l=s._state||{},u=(null==n?void 0:n.settings)||{};if(!l.client)return;const f=s.userId;let d,y;if(void 0!==f){const e=await v(t,f,{collector:i});a(e)&&(d=e)}if(!d)return;if(void 0!==s.attributes){const e=await v(t,s.attributes,{collector:i});c(e)&&(y=e)}if(d!==l.lastUserId||!l.userContext){const t=l.client.createUserContext(d,y);if(!t)return;l.userContext=t,l.lastUserId=d}const p=l.userContext;if(p){if(void 0!==u.attributes){const e=await v(t,u.attributes,{collector:i});if(c(e))for(const[t,n]of Object.entries(e))p.setAttribute(t,n)}if(!0!==(null==n?void 0:n.skip)){const e=a(null==n?void 0:n.name)?n.name:t.name,o={};if(void 0!==u.eventTags){const e=await v(t,u.eventTags,{collector:i});c(e)&&Object.assign(o,e)}if(void 0!==u.revenue){const e=await v(t,u.revenue,{collector:i});r(e)&&(o.revenue=e)}if(void 0!==u.value){const e=await v(t,u.value,{collector:i});r(e)&&(o.value=e)}p.trackEvent(e,o)}s._state=l}},on(t,e){var n,o,i;if("consent"!==t||!e.data)return;const r=null==(n=e.config)?void 0:n.consent;if(!r||0===Object.keys(r).length)return;const c=e.data,a=Object.keys(r).every(t=>!0===c[t]),s=null==(i=null==(o=e.config)?void 0:o.settings)?void 0:i._state;!a&&(null==s?void 0:s.client)&&(s.client.close(),s.client=void 0,s.userContext=void 0)},destroy({config:t}){const e=((null==t?void 0:t.settings)||{})._state;(null==e?void 0:e.client)&&(e.client.close(),e.client=void 0,e.userContext=void 0)}},g=b;export{p as DestinationOptimizely,g as default,b as destinationOptimizely};//# sourceMappingURL=index.mjs.map
1
+ var t=Object.defineProperty;((e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})})({},{Level:()=>n});var e,n=((e=n||{})[e.ERROR=0]="ERROR",e[e.WARN=1]="WARN",e[e.INFO=2]="INFO",e[e.DEBUG=3]="DEBUG",e);function o(t){return Array.isArray(t)}function i(t){return void 0!==t}function r(t){return"number"==typeof t&&!Number.isNaN(t)}function c(t){return"object"==typeof t&&null!==t&&!o(t)&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return"string"==typeof t}function s(t,e="",n){const r=e.split(".");let c=t;for(let t=0;t<r.length;t++){const e=r[t];if("*"===e&&o(c)){const e=r.slice(t+1).join("."),o=[];for(const t of c){const i=s(t,e,n);o.push(i)}return o}if(c=c instanceof Object?c[e]:void 0,void 0===c)break}return i(c)?c:n}function l(t){return function(t){return"boolean"==typeof t}(t)||a(t)||r(t)||!i(t)||o(t)&&t.every(l)||c(t)&&Object.values(t).every(l)}function u(t){return l(t)?t:void 0}function f(t,e,n){return async function(...o){try{return await t(...o)}catch(t){if(!e)return;return await e(t)}finally{await(null==n?void 0:n())}}}async function v(t,e={},n={}){var r,a;if(!i(t))return;const s=c(t)&&t.consent||n.consent||(null==(r=n.collector)?void 0:r.consent),l=null!=(a=n.event)?a:c(t)?t:{};if(!n.collector)throw new Error("getMappingValue: context.collector is required");const u={event:l,mapping:e,collector:n.collector,logger:n.collector.logger,consent:s},v=o(e)?e:[e];for(const e of v){const n=await f(d)(t,e,{...u,mapping:e});if(i(n))return n}}async function d(t,e,n){return(o(e)?e:[e]).reduce(async(e,r)=>{const c=await e;if(c)return c;const l=a(r)?{key:r}:r;if(!Object.keys(l).length)return;const{condition:y,consent:g,fn:p,key:b,loop:m,map:w,set:j,validate:O,value:h}=l,k={...n,mapping:r};if(y&&!await f(y)(t,k))return;if(g&&!function(t,e={},n={}){const o={...e,...n},i={};let r=!t||0===Object.keys(t).length;return Object.keys(o).forEach(e=>{o[e]&&(i[e]=!0,t&&t[e]&&(r=!0))}),!!r&&i}(g,k.consent))return h;let I=i(h)?h:t;if(p&&(I=await f(p)(t,k)),b&&(I=s(t,b,h)),m){const[e,n]=m,r="this"===e?[t]:await v(t,e,k);o(r)&&(I=(await Promise.all(r.map(t=>v(t,n,k)))).filter(i))}else w?I=await Object.entries(w).reduce(async(e,[n,o])=>{const r=await e,c=await v(t,o,k);return i(c)&&(r[n]=c),r},Promise.resolve({})):j&&(I=await Promise.all(j.map(e=>d(t,e,k))));O&&!await f(O)(I,k)&&(I=void 0);const P=u(I);return i(P)?P:u(h)},Promise.resolve(void 0))}import*as y from"@optimizely/optimizely-sdk";var g={};var p={type:"optimizely",config:{},async init({config:t,env:e}){var n,o,i,r;const c=t.settings;if(!(null==c?void 0:c.sdkKey))return!1;const a=function(t){return(null==t?void 0:t.optimizely)?t.optimizely:y}(e),s={projectConfigManager:a.createPollingProjectConfigManager({sdkKey:c.sdkKey,autoUpdate:null==(n=c.autoUpdate)||n,updateInterval:null!=(o=c.updateInterval)?o:6e4}),eventProcessor:a.createBatchEventProcessor({batchSize:null!=(i=c.batchSize)?i:10,flushInterval:null!=(r=c.flushInterval)?r:1e3})},l=a.createInstance(s);await l.onReady();const u={client:l};return{...t,settings:{...c,_state:u}}},async push(t,{config:e,rule:n,env:o,collector:i}){const s=e.settings||{},l=s._state||{},u=(null==n?void 0:n.settings)||{};if(!l.client)return;const f=s.userId;let d,y;if(void 0!==f){const e=await v(t,f,{collector:i});a(e)&&(d=e)}if(!d)return;if(void 0!==s.attributes){const e=await v(t,s.attributes,{collector:i});c(e)&&(y=e)}if(d!==l.lastUserId||!l.userContext){const t=l.client.createUserContext(d,y);if(!t)return;l.userContext=t,l.lastUserId=d}const g=l.userContext;if(g){if(void 0!==u.attributes){const e=await v(t,u.attributes,{collector:i});if(c(e))for(const[t,n]of Object.entries(e))g.setAttribute(t,n)}if(!0!==(null==n?void 0:n.silent)){const e=a(null==n?void 0:n.name)?n.name:t.name,o={};if(void 0!==u.eventTags){const e=await v(t,u.eventTags,{collector:i});c(e)&&Object.assign(o,e)}if(void 0!==u.revenue){const e=await v(t,u.revenue,{collector:i});r(e)&&(o.revenue=e)}if(void 0!==u.value){const e=await v(t,u.value,{collector:i});r(e)&&(o.value=e)}g.trackEvent(e,o)}s._state=l}},on(t,e){var n,o,i;if("consent"!==t||!e.data)return;const r=null==(n=e.config)?void 0:n.consent;if(!r||0===Object.keys(r).length)return;const c=e.data,a=Object.keys(r).every(t=>!0===c[t]),s=null==(i=null==(o=e.config)?void 0:o.settings)?void 0:i._state;!a&&(null==s?void 0:s.client)&&(s.client.close(),s.client=void 0,s.userContext=void 0)},destroy({config:t}){const e=((null==t?void 0:t.settings)||{})._state;(null==e?void 0:e.client)&&(e.client.close(),e.client=void 0,e.userContext=void 0)}},b=p;export{g as DestinationOptimizely,b as default,p as destinationOptimizely};//# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/index.ts"],"sourcesContent":["import type { WalkerOS } from '@walkeros/core';\nimport { getMappingValue, isNumber, isObject, isString } from '@walkeros/core';\nimport * as optimizelySDK from '@optimizely/optimizely-sdk';\nimport type {\n Destination,\n Env,\n OptimizelySDK as OptimizelySDKType,\n RuntimeState,\n Settings,\n} from './types';\n\n// Types export\nexport * as DestinationOptimizely from './types';\n\n/**\n * Resolve the Optimizely SDK: use the caller-provided mock when available\n * (tests), otherwise fall back to the real @optimizely/optimizely-sdk.\n */\nfunction getOptimizely(env: Env | undefined): OptimizelySDKType {\n if (env?.optimizely) return env.optimizely;\n return optimizelySDK as unknown as OptimizelySDKType;\n}\n\nexport const destinationOptimizely: Destination = {\n type: 'optimizely',\n\n config: {},\n\n async init({ config, env }) {\n const settings = config.settings;\n if (!settings?.sdkKey) return false;\n\n const sdk = getOptimizely(env as Env | undefined);\n\n const configManager = sdk.createPollingProjectConfigManager({\n sdkKey: settings.sdkKey,\n autoUpdate: settings.autoUpdate ?? true,\n updateInterval: settings.updateInterval ?? 60000,\n });\n\n const eventProcessor = sdk.createBatchEventProcessor({\n batchSize: settings.batchSize ?? 10,\n flushInterval: settings.flushInterval ?? 1000,\n });\n\n const instanceConfig: Record<string, unknown> = {\n projectConfigManager: configManager,\n eventProcessor: eventProcessor,\n };\n\n const client = sdk.createInstance(instanceConfig);\n await client.onReady();\n\n const _state: RuntimeState = { client };\n\n return { ...config, settings: { ...settings, _state } };\n },\n\n async push(event, { config, rule, env, collector }) {\n const settings = (config.settings || {}) as Settings;\n const state: RuntimeState = settings._state || {};\n const mappingSettings = rule?.settings || {};\n\n if (!state.client) return;\n\n // 1. Resolve userId\n const userIdMapping = settings.userId;\n let userId: string | undefined;\n if (userIdMapping !== undefined) {\n const resolved = await getMappingValue(event, userIdMapping, {\n collector,\n });\n if (isString(resolved)) userId = resolved;\n }\n\n // Fallback: no userId means we cannot create a user context\n if (!userId) return;\n\n // 2. Resolve destination-level attributes\n let baseAttributes: Record<string, unknown> | undefined;\n if (settings.attributes !== undefined) {\n const resolved = await getMappingValue(event, settings.attributes, {\n collector,\n });\n if (isObject(resolved)) {\n baseAttributes = resolved as Record<string, unknown>;\n }\n }\n\n // 3. Create or reuse user context\n if (userId !== state.lastUserId || !state.userContext) {\n const userContext = state.client.createUserContext(\n userId,\n baseAttributes,\n );\n if (!userContext) return;\n state.userContext = userContext;\n state.lastUserId = userId;\n }\n\n const userContext = state.userContext;\n if (!userContext) return;\n\n // 4. Per-event attributes via setAttribute\n if (mappingSettings.attributes !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.attributes,\n { collector },\n );\n if (isObject(resolved)) {\n for (const [key, value] of Object.entries(\n resolved as Record<string, unknown>,\n )) {\n userContext.setAttribute(key, value);\n }\n }\n }\n\n // 5. Track event (unless skip: true)\n if (rule?.skip !== true) {\n const eventKey = isString(rule?.name) ? rule.name : event.name;\n\n // Build eventTags\n const eventTags: Record<string, unknown> = {};\n\n // Resolve eventTags mapping first (so revenue/value can override)\n if (mappingSettings.eventTags !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.eventTags,\n { collector },\n );\n if (isObject(resolved)) {\n Object.assign(eventTags, resolved);\n }\n }\n\n // Revenue (integer, cents)\n if (mappingSettings.revenue !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.revenue, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.revenue = resolved;\n }\n }\n\n // Value (float)\n if (mappingSettings.value !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.value, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.value = resolved;\n }\n }\n\n userContext.trackEvent(eventKey, eventTags);\n }\n\n // Persist state mutations\n settings._state = state;\n },\n\n on(type, context) {\n if (type !== 'consent' || !context.data) return;\n\n const required = context.config?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const consent = context.data as WalkerOS.Consent;\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n\n const state = (context.config?.settings as Settings)?._state;\n if (!allGranted && state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n\n destroy({ config }) {\n const settings = (config?.settings || {}) as Settings;\n const state = settings._state;\n if (state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n};\n\nexport default destinationOptimizely;\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\n/**\n * Destination-level settings.\n */\nexport interface Settings {\n /** Optimizely Feature Experimentation SDK key. Required. */\n sdkKey: string;\n /** walkerOS mapping value to resolve userId for experiment bucketing. */\n userId?: WalkerOSMapping.Value;\n /** User attributes for audience targeting, applied to every event. */\n attributes?: WalkerOSMapping.Value;\n /** Polling interval for datafile updates in ms. Default: 60000. */\n updateInterval?: number;\n /** Auto-update datafile via polling. Default: true. */\n autoUpdate?: boolean;\n /** Batch event processor: events per batch. Default: 10. */\n batchSize?: number;\n /** Batch event processor: flush interval in ms. Default: 1000. */\n flushInterval?: number;\n /** Skip ODP manager initialization. Default: true. */\n skipOdp?: boolean;\n /** Runtime state -- not user-facing. Mutated by init/push. */\n _state?: RuntimeState;\n}\n\nexport interface RuntimeState {\n /** The Optimizely client instance (typed as OptimizelyClient). */\n client?: OptimizelyClient;\n /** Cached user context. Recreated when userId changes. */\n userContext?: OptimizelyUserContext;\n /** Last resolved userId to detect identity changes. */\n lastUserId?: string;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings.\n */\nexport interface Mapping {\n /** Override event key sent to Optimizely. If omitted, event.name is used. */\n eventKey?: string;\n /** Revenue mapping. Resolves to integer (cents). Passed as eventTags.revenue. */\n revenue?: WalkerOSMapping.Value;\n /** Numeric value mapping. Resolves to float. Passed as eventTags.value. */\n value?: WalkerOSMapping.Value;\n /** Additional event tags. Resolves to Record<string, unknown>. */\n eventTags?: WalkerOSMapping.Value;\n /** Per-event user attributes override. Merged onto user context for this event. */\n attributes?: WalkerOSMapping.Value;\n}\n\n/**\n * OptimizelyClient -- the subset of the Optimizely SDK client the destination\n * actually uses. Tests provide a mock via env.optimizely.\n */\nexport interface OptimizelyClient {\n onReady: () => Promise<{ success: boolean }>;\n createUserContext: (\n userId: string,\n attributes?: Record<string, unknown>,\n ) => OptimizelyUserContext | null;\n close: () => void;\n}\n\n/**\n * OptimizelyUserContext -- user context methods the destination calls.\n */\nexport interface OptimizelyUserContext {\n trackEvent: (eventKey: string, eventTags?: Record<string, unknown>) => void;\n setAttribute: (key: string, value: unknown) => void;\n}\n\n/**\n * OptimizelySDK -- factory functions the destination imports from the SDK.\n * Tests provide this via env.optimizely to avoid importing the real SDK.\n */\nexport interface OptimizelySDK {\n createInstance: (config: Record<string, unknown>) => OptimizelyClient;\n createPollingProjectConfigManager: (\n config: Record<string, unknown>,\n ) => unknown;\n createBatchEventProcessor: (config: Record<string, unknown>) => unknown;\n}\n\n/**\n * Env -- optional SDK override. Production leaves env.optimizely undefined\n * and the destination falls back to the real @optimizely/optimizely-sdk\n * import. Tests provide a mock via env.optimizely.\n */\nexport interface Env extends DestinationWeb.Env {\n optimizely?: OptimizelySDK;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":"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","names":["userContext"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/index.ts"],"sourcesContent":["import type { WalkerOS } from '@walkeros/core';\nimport { getMappingValue, isNumber, isObject, isString } from '@walkeros/core';\nimport * as optimizelySDK from '@optimizely/optimizely-sdk';\nimport type {\n Destination,\n Env,\n OptimizelySDK as OptimizelySDKType,\n RuntimeState,\n Settings,\n} from './types';\n\n// Types export\nexport * as DestinationOptimizely from './types';\n\n/**\n * Resolve the Optimizely SDK: use the caller-provided mock when available\n * (tests), otherwise fall back to the real @optimizely/optimizely-sdk.\n */\nfunction getOptimizely(env: Env | undefined): OptimizelySDKType {\n if (env?.optimizely) return env.optimizely;\n return optimizelySDK as unknown as OptimizelySDKType;\n}\n\nexport const destinationOptimizely: Destination = {\n type: 'optimizely',\n\n config: {},\n\n async init({ config, env }) {\n const settings = config.settings;\n if (!settings?.sdkKey) return false;\n\n const sdk = getOptimizely(env as Env | undefined);\n\n const configManager = sdk.createPollingProjectConfigManager({\n sdkKey: settings.sdkKey,\n autoUpdate: settings.autoUpdate ?? true,\n updateInterval: settings.updateInterval ?? 60000,\n });\n\n const eventProcessor = sdk.createBatchEventProcessor({\n batchSize: settings.batchSize ?? 10,\n flushInterval: settings.flushInterval ?? 1000,\n });\n\n const instanceConfig: Record<string, unknown> = {\n projectConfigManager: configManager,\n eventProcessor: eventProcessor,\n };\n\n const client = sdk.createInstance(instanceConfig);\n await client.onReady();\n\n const _state: RuntimeState = { client };\n\n return { ...config, settings: { ...settings, _state } };\n },\n\n async push(event, { config, rule, env, collector }) {\n const settings = (config.settings || {}) as Settings;\n const state: RuntimeState = settings._state || {};\n const mappingSettings = rule?.settings || {};\n\n if (!state.client) return;\n\n // 1. Resolve userId\n const userIdMapping = settings.userId;\n let userId: string | undefined;\n if (userIdMapping !== undefined) {\n const resolved = await getMappingValue(event, userIdMapping, {\n collector,\n });\n if (isString(resolved)) userId = resolved;\n }\n\n // Fallback: no userId means we cannot create a user context\n if (!userId) return;\n\n // 2. Resolve destination-level attributes\n let baseAttributes: Record<string, unknown> | undefined;\n if (settings.attributes !== undefined) {\n const resolved = await getMappingValue(event, settings.attributes, {\n collector,\n });\n if (isObject(resolved)) {\n baseAttributes = resolved as Record<string, unknown>;\n }\n }\n\n // 3. Create or reuse user context\n if (userId !== state.lastUserId || !state.userContext) {\n const userContext = state.client.createUserContext(\n userId,\n baseAttributes,\n );\n if (!userContext) return;\n state.userContext = userContext;\n state.lastUserId = userId;\n }\n\n const userContext = state.userContext;\n if (!userContext) return;\n\n // 4. Per-event attributes via setAttribute\n if (mappingSettings.attributes !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.attributes,\n { collector },\n );\n if (isObject(resolved)) {\n for (const [key, value] of Object.entries(\n resolved as Record<string, unknown>,\n )) {\n userContext.setAttribute(key, value);\n }\n }\n }\n\n // 5. Track event (unless silent: true)\n if (rule?.silent !== true) {\n const eventKey = isString(rule?.name) ? rule.name : event.name;\n\n // Build eventTags\n const eventTags: Record<string, unknown> = {};\n\n // Resolve eventTags mapping first (so revenue/value can override)\n if (mappingSettings.eventTags !== undefined) {\n const resolved = await getMappingValue(\n event,\n mappingSettings.eventTags,\n { collector },\n );\n if (isObject(resolved)) {\n Object.assign(eventTags, resolved);\n }\n }\n\n // Revenue (integer, cents)\n if (mappingSettings.revenue !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.revenue, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.revenue = resolved;\n }\n }\n\n // Value (float)\n if (mappingSettings.value !== undefined) {\n const resolved = await getMappingValue(event, mappingSettings.value, {\n collector,\n });\n if (isNumber(resolved)) {\n eventTags.value = resolved;\n }\n }\n\n userContext.trackEvent(eventKey, eventTags);\n }\n\n // Persist state mutations\n settings._state = state;\n },\n\n on(type, context) {\n if (type !== 'consent' || !context.data) return;\n\n const required = context.config?.consent;\n if (!required || Object.keys(required).length === 0) return;\n\n const consent = context.data as WalkerOS.Consent;\n const allGranted = Object.keys(required).every(\n (key) => consent[key] === true,\n );\n\n const state = (context.config?.settings as Settings)?._state;\n if (!allGranted && state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n\n destroy({ config }) {\n const settings = (config?.settings || {}) as Settings;\n const state = settings._state;\n if (state?.client) {\n state.client.close();\n state.client = undefined;\n state.userContext = undefined;\n }\n },\n};\n\nexport default destinationOptimizely;\n","import type {\n Mapping as WalkerOSMapping,\n Destination as CoreDestination,\n} from '@walkeros/core';\nimport type { DestinationWeb } from '@walkeros/web-core';\n\n/**\n * Destination-level settings.\n */\nexport interface Settings {\n /** Optimizely Feature Experimentation SDK key. Required. */\n sdkKey: string;\n /** walkerOS mapping value to resolve userId for experiment bucketing. */\n userId?: WalkerOSMapping.Value;\n /** User attributes for audience targeting, applied to every event. */\n attributes?: WalkerOSMapping.Value;\n /** Polling interval for datafile updates in ms. Default: 60000. */\n updateInterval?: number;\n /** Auto-update datafile via polling. Default: true. */\n autoUpdate?: boolean;\n /** Batch event processor: events per batch. Default: 10. */\n batchSize?: number;\n /** Batch event processor: flush interval in ms. Default: 1000. */\n flushInterval?: number;\n /** Skip ODP manager initialization. Default: true. */\n skipOdp?: boolean;\n /** Runtime state -- not user-facing. Mutated by init/push. */\n _state?: RuntimeState;\n}\n\nexport interface RuntimeState {\n /** The Optimizely client instance (typed as OptimizelyClient). */\n client?: OptimizelyClient;\n /** Cached user context. Recreated when userId changes. */\n userContext?: OptimizelyUserContext;\n /** Last resolved userId to detect identity changes. */\n lastUserId?: string;\n}\n\nexport type InitSettings = Partial<Settings>;\n\n/**\n * Per-rule mapping settings.\n */\nexport interface Mapping {\n /** Override event key sent to Optimizely. If omitted, event.name is used. */\n eventKey?: string;\n /** Revenue mapping. Resolves to integer (cents). Passed as eventTags.revenue. */\n revenue?: WalkerOSMapping.Value;\n /** Numeric value mapping. Resolves to float. Passed as eventTags.value. */\n value?: WalkerOSMapping.Value;\n /** Additional event tags. Resolves to Record<string, unknown>. */\n eventTags?: WalkerOSMapping.Value;\n /** Per-event user attributes override. Merged onto user context for this event. */\n attributes?: WalkerOSMapping.Value;\n}\n\n/**\n * OptimizelyClient -- the subset of the Optimizely SDK client the destination\n * actually uses. Tests provide a mock via env.optimizely.\n */\nexport interface OptimizelyClient {\n onReady: () => Promise<{ success: boolean }>;\n createUserContext: (\n userId: string,\n attributes?: Record<string, unknown>,\n ) => OptimizelyUserContext | null;\n close: () => void;\n}\n\n/**\n * OptimizelyUserContext -- user context methods the destination calls.\n */\nexport interface OptimizelyUserContext {\n trackEvent: (eventKey: string, eventTags?: Record<string, unknown>) => void;\n setAttribute: (key: string, value: unknown) => void;\n}\n\n/**\n * OptimizelySDK -- factory functions the destination imports from the SDK.\n * Tests provide this via env.optimizely to avoid importing the real SDK.\n */\nexport interface OptimizelySDK {\n createInstance: (config: Record<string, unknown>) => OptimizelyClient;\n createPollingProjectConfigManager: (\n config: Record<string, unknown>,\n ) => unknown;\n createBatchEventProcessor: (config: Record<string, unknown>) => unknown;\n}\n\n/**\n * Env -- optional SDK override. Production leaves env.optimizely undefined\n * and the destination falls back to the real @optimizely/optimizely-sdk\n * import. Tests provide a mock via env.optimizely.\n */\nexport interface Env extends DestinationWeb.Env {\n optimizely?: OptimizelySDK;\n}\n\nexport type Types = CoreDestination.Types<Settings, Mapping, Env, InitSettings>;\n\nexport type Destination = DestinationWeb.Destination<Types>;\nexport type Config = DestinationWeb.Config<Types>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n"],"mappings":"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","names":["userContext"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$meta": {
3
3
  "package": "@walkeros/web-destination-optimizely",
4
- "version": "3.4.2",
4
+ "version": "4.0.0-next-1777882869103",
5
5
  "type": "destination",
6
6
  "platform": [
7
7
  "web"
@@ -86,7 +86,7 @@
86
86
  "init": {
87
87
  "optimizely": {
88
88
  "createInstance": {
89
- "$code": "()=>Ih()"
89
+ "$code": "()=>xh()"
90
90
  },
91
91
  "createPollingProjectConfigManager": {
92
92
  "$code": "()=>({})"
@@ -99,7 +99,7 @@
99
99
  "push": {
100
100
  "optimizely": {
101
101
  "createInstance": {
102
- "$code": "()=>Ih()"
102
+ "$code": "()=>xh()"
103
103
  },
104
104
  "createPollingProjectConfigManager": {
105
105
  "$code": "()=>({})"
@@ -119,7 +119,7 @@
119
119
  ]
120
120
  },
121
121
  "step": {
122
- "attributesOnlySkipTrack": {
122
+ "attributesOnlySilent": {
123
123
  "title": "Attributes only",
124
124
  "description": "A profile update sets Optimizely user attributes without firing a trackEvent for user enrichment.",
125
125
  "in": {
@@ -150,39 +150,25 @@
150
150
  "entity": "child",
151
151
  "data": {
152
152
  "is": "subordinated"
153
- },
154
- "nested": [],
155
- "context": {
156
- "element": [
157
- "child",
158
- 0
159
- ]
160
153
  }
161
154
  }
162
155
  ],
163
156
  "consent": {
164
157
  "functional": true
165
158
  },
166
- "id": "1700000105-gr0up-1",
159
+ "id": "1ecdbe158acfe8d2",
167
160
  "trigger": "test",
168
161
  "entity": "profile",
169
162
  "action": "update",
170
163
  "timestamp": 1700000105,
171
164
  "timing": 3.14,
172
- "group": "gr0up",
173
- "count": 1,
174
- "version": {
175
- "source": "3.4.2",
176
- "tagging": 1
177
- },
178
165
  "source": {
179
- "type": "web",
180
- "id": "https://localhost:80",
181
- "previous_id": "http://remotehost:9001"
166
+ "type": "collector",
167
+ "schema": "4"
182
168
  }
183
169
  },
184
170
  "mapping": {
185
- "skip": true,
171
+ "silent": true,
186
172
  "settings": {
187
173
  "attributes": {
188
174
  "map": {
@@ -263,35 +249,21 @@
263
249
  "entity": "child",
264
250
  "data": {
265
251
  "is": "subordinated"
266
- },
267
- "nested": [],
268
- "context": {
269
- "element": [
270
- "child",
271
- 0
272
- ]
273
252
  }
274
253
  }
275
254
  ],
276
255
  "consent": {
277
256
  "functional": true
278
257
  },
279
- "id": "1700000100-gr0up-1",
258
+ "id": "5ae522bedc56ae7d",
280
259
  "trigger": "load",
281
260
  "entity": "page",
282
261
  "action": "view",
283
262
  "timestamp": 1700000100,
284
263
  "timing": 3.14,
285
- "group": "gr0up",
286
- "count": 1,
287
- "version": {
288
- "source": "3.4.2",
289
- "tagging": 1
290
- },
291
264
  "source": {
292
- "type": "web",
293
- "id": "https://localhost:80",
294
- "previous_id": "http://remotehost:9001"
265
+ "type": "collector",
266
+ "schema": "4"
295
267
  }
296
268
  },
297
269
  "out": [
@@ -335,22 +307,15 @@
335
307
  "consent": {
336
308
  "functional": true
337
309
  },
338
- "id": "1700000101-gr0up-1",
310
+ "id": "345afd9abaeb0c1d",
339
311
  "trigger": "load",
340
312
  "entity": "product",
341
313
  "action": "view",
342
314
  "timestamp": 1700000101,
343
315
  "timing": 3.14,
344
- "group": "gr0up",
345
- "count": 1,
346
- "version": {
347
- "source": "3.4.2",
348
- "tagging": 1
349
- },
350
316
  "source": {
351
- "type": "web",
352
- "id": "https://localhost:80",
353
- "previous_id": "http://remotehost:9001"
317
+ "type": "collector",
318
+ "schema": "4"
354
319
  }
355
320
  },
356
321
  "mapping": {
@@ -443,22 +408,15 @@
443
408
  "consent": {
444
409
  "functional": true
445
410
  },
446
- "id": "1700000102-gr0up-1",
411
+ "id": "aed55e9e6ec7a6cc",
447
412
  "trigger": "load",
448
413
  "entity": "order",
449
414
  "action": "complete",
450
415
  "timestamp": 1700000102,
451
416
  "timing": 3.14,
452
- "group": "gr0up",
453
- "count": 1,
454
- "version": {
455
- "source": "3.4.2",
456
- "tagging": 1
457
- },
458
417
  "source": {
459
- "type": "web",
460
- "id": "https://localhost:80",
461
- "previous_id": "http://remotehost:9001"
418
+ "type": "collector",
419
+ "schema": "4"
462
420
  }
463
421
  },
464
422
  "mapping": {
@@ -518,35 +476,21 @@
518
476
  "entity": "child",
519
477
  "data": {
520
478
  "is": "subordinated"
521
- },
522
- "nested": [],
523
- "context": {
524
- "element": [
525
- "child",
526
- 0
527
- ]
528
479
  }
529
480
  }
530
481
  ],
531
482
  "consent": {
532
483
  "functional": true
533
484
  },
534
- "id": "1700000103-gr0up-1",
485
+ "id": "3041f481a2d98b5b",
535
486
  "trigger": "test",
536
487
  "entity": "user",
537
488
  "action": "signup",
538
489
  "timestamp": 1700000103,
539
490
  "timing": 3.14,
540
- "group": "gr0up",
541
- "count": 1,
542
- "version": {
543
- "source": "3.4.2",
544
- "tagging": 1
545
- },
546
491
  "source": {
547
- "type": "web",
548
- "id": "https://localhost:80",
549
- "previous_id": "http://remotehost:9001"
492
+ "type": "collector",
493
+ "schema": "4"
550
494
  }
551
495
  },
552
496
  "mapping": {
@@ -614,35 +558,21 @@
614
558
  "entity": "child",
615
559
  "data": {
616
560
  "is": "subordinated"
617
- },
618
- "nested": [],
619
- "context": {
620
- "element": [
621
- "child",
622
- 0
623
- ]
624
561
  }
625
562
  }
626
563
  ],
627
564
  "consent": {
628
565
  "functional": true
629
566
  },
630
- "id": "1700000104-gr0up-1",
567
+ "id": "7966071bc6aa32de",
631
568
  "trigger": "test",
632
569
  "entity": "debug",
633
570
  "action": "noise",
634
571
  "timestamp": 1700000104,
635
572
  "timing": 3.14,
636
- "group": "gr0up",
637
- "count": 1,
638
- "version": {
639
- "source": "3.4.2",
640
- "tagging": 1
641
- },
642
573
  "source": {
643
- "type": "web",
644
- "id": "https://localhost:80",
645
- "previous_id": "http://remotehost:9001"
574
+ "type": "collector",
575
+ "schema": "4"
646
576
  }
647
577
  },
648
578
  "mapping": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/web-destination-optimizely",
3
3
  "description": "Optimizely Feature Experimentation web destination for walkerOS (conversion tracking, revenue metrics, user targeting)",
4
- "version": "3.4.2",
4
+ "version": "4.0.0-next-1777882869103",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -38,10 +38,10 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@optimizely/optimizely-sdk": "^6.0.0",
41
- "@walkeros/web-core": "3.4.2"
41
+ "@walkeros/web-core": "4.0.0-next-1777882869103"
42
42
  },
43
43
  "devDependencies": {
44
- "@walkeros/collector": "3.4.2"
44
+ "@walkeros/collector": "4.0.0-next-1777882869103"
45
45
  },
46
46
  "repository": {
47
47
  "url": "git+https://github.com/elbwalker/walkerOS.git",