@contentful/optimization-core 0.1.0-alpha → 0.1.0-alpha10

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.
Files changed (149) hide show
  1. package/README.md +221 -31
  2. package/dist/260.mjs +14 -0
  3. package/dist/260.mjs.map +1 -0
  4. package/dist/499.mjs +4 -0
  5. package/dist/632.mjs +5 -0
  6. package/dist/632.mjs.map +1 -0
  7. package/dist/808.mjs +2 -0
  8. package/dist/942.mjs +2 -0
  9. package/dist/api-client.cjs +60 -0
  10. package/dist/api-client.cjs.map +1 -0
  11. package/dist/api-client.d.cts +4 -0
  12. package/dist/api-client.d.mts +4 -0
  13. package/dist/api-client.d.ts +4 -0
  14. package/dist/api-client.mjs +2 -0
  15. package/dist/api-schemas.cjs +60 -0
  16. package/dist/api-schemas.cjs.map +1 -0
  17. package/dist/api-schemas.d.cts +4 -0
  18. package/dist/api-schemas.d.mts +4 -0
  19. package/dist/api-schemas.d.ts +4 -0
  20. package/dist/api-schemas.mjs +2 -0
  21. package/dist/constants.cjs +78 -0
  22. package/dist/constants.cjs.map +1 -0
  23. package/dist/constants.d.cts +88 -0
  24. package/dist/constants.d.mts +88 -0
  25. package/dist/constants.d.ts +88 -0
  26. package/dist/constants.mjs +1 -0
  27. package/dist/index.cjs +1853 -1665
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +2432 -0
  30. package/dist/index.d.mts +2432 -0
  31. package/dist/index.d.ts +2432 -15
  32. package/dist/index.mjs +625 -327
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/logger.cjs +67 -0
  35. package/dist/logger.cjs.map +1 -0
  36. package/dist/logger.d.cts +8 -0
  37. package/dist/logger.d.mts +8 -0
  38. package/dist/logger.d.ts +8 -0
  39. package/dist/logger.mjs +2 -0
  40. package/dist/symbols.cjs +42 -0
  41. package/dist/symbols.cjs.map +1 -0
  42. package/dist/symbols.d.cts +10 -0
  43. package/dist/symbols.d.mts +10 -0
  44. package/dist/symbols.d.ts +10 -0
  45. package/dist/symbols.mjs +1 -0
  46. package/package.json +65 -12
  47. package/dist/Consent.d.ts +0 -44
  48. package/dist/Consent.d.ts.map +0 -1
  49. package/dist/Consent.js +0 -2
  50. package/dist/Consent.js.map +0 -1
  51. package/dist/CoreBase.d.ts +0 -161
  52. package/dist/CoreBase.d.ts.map +0 -1
  53. package/dist/CoreBase.js +0 -151
  54. package/dist/CoreBase.js.map +0 -1
  55. package/dist/CoreStateful.d.ts +0 -142
  56. package/dist/CoreStateful.d.ts.map +0 -1
  57. package/dist/CoreStateful.js +0 -137
  58. package/dist/CoreStateful.js.map +0 -1
  59. package/dist/CoreStateless.d.ts +0 -53
  60. package/dist/CoreStateless.d.ts.map +0 -1
  61. package/dist/CoreStateless.js +0 -43
  62. package/dist/CoreStateless.js.map +0 -1
  63. package/dist/ProductBase.d.ts +0 -83
  64. package/dist/ProductBase.d.ts.map +0 -1
  65. package/dist/ProductBase.js +0 -50
  66. package/dist/ProductBase.js.map +0 -1
  67. package/dist/analytics/AnalyticsBase.d.ts +0 -35
  68. package/dist/analytics/AnalyticsBase.d.ts.map +0 -1
  69. package/dist/analytics/AnalyticsBase.js +0 -13
  70. package/dist/analytics/AnalyticsBase.js.map +0 -1
  71. package/dist/analytics/AnalyticsStateful.d.ts +0 -138
  72. package/dist/analytics/AnalyticsStateful.d.ts.map +0 -1
  73. package/dist/analytics/AnalyticsStateful.js +0 -179
  74. package/dist/analytics/AnalyticsStateful.js.map +0 -1
  75. package/dist/analytics/AnalyticsStateless.d.ts +0 -48
  76. package/dist/analytics/AnalyticsStateless.d.ts.map +0 -1
  77. package/dist/analytics/AnalyticsStateless.js +0 -61
  78. package/dist/analytics/AnalyticsStateless.js.map +0 -1
  79. package/dist/analytics/index.d.ts +0 -5
  80. package/dist/analytics/index.d.ts.map +0 -1
  81. package/dist/analytics/index.js +0 -5
  82. package/dist/analytics/index.js.map +0 -1
  83. package/dist/global-constants.d.ts +0 -18
  84. package/dist/global-constants.d.ts.map +0 -1
  85. package/dist/global-constants.js +0 -18
  86. package/dist/global-constants.js.map +0 -1
  87. package/dist/index.d.ts.map +0 -1
  88. package/dist/index.js +0 -15
  89. package/dist/index.js.map +0 -1
  90. package/dist/lib/decorators/guardedBy.d.ts +0 -113
  91. package/dist/lib/decorators/guardedBy.d.ts.map +0 -1
  92. package/dist/lib/decorators/guardedBy.js +0 -143
  93. package/dist/lib/decorators/guardedBy.js.map +0 -1
  94. package/dist/lib/decorators/index.d.ts +0 -2
  95. package/dist/lib/decorators/index.d.ts.map +0 -1
  96. package/dist/lib/decorators/index.js +0 -2
  97. package/dist/lib/decorators/index.js.map +0 -1
  98. package/dist/lib/interceptor/InterceptorManager.d.ts +0 -127
  99. package/dist/lib/interceptor/InterceptorManager.d.ts.map +0 -1
  100. package/dist/lib/interceptor/InterceptorManager.js +0 -125
  101. package/dist/lib/interceptor/InterceptorManager.js.map +0 -1
  102. package/dist/lib/interceptor/index.d.ts +0 -2
  103. package/dist/lib/interceptor/index.d.ts.map +0 -1
  104. package/dist/lib/interceptor/index.js +0 -2
  105. package/dist/lib/interceptor/index.js.map +0 -1
  106. package/dist/lib/value-presence/ValuePresence.d.ts +0 -123
  107. package/dist/lib/value-presence/ValuePresence.d.ts.map +0 -1
  108. package/dist/lib/value-presence/ValuePresence.js +0 -141
  109. package/dist/lib/value-presence/ValuePresence.js.map +0 -1
  110. package/dist/lib/value-presence/index.d.ts +0 -2
  111. package/dist/lib/value-presence/index.d.ts.map +0 -1
  112. package/dist/lib/value-presence/index.js +0 -2
  113. package/dist/lib/value-presence/index.js.map +0 -1
  114. package/dist/personalization/PersonalizationBase.d.ts +0 -184
  115. package/dist/personalization/PersonalizationBase.d.ts.map +0 -1
  116. package/dist/personalization/PersonalizationBase.js +0 -76
  117. package/dist/personalization/PersonalizationBase.js.map +0 -1
  118. package/dist/personalization/PersonalizationStateful.d.ts +0 -226
  119. package/dist/personalization/PersonalizationStateful.d.ts.map +0 -1
  120. package/dist/personalization/PersonalizationStateful.js +0 -297
  121. package/dist/personalization/PersonalizationStateful.js.map +0 -1
  122. package/dist/personalization/PersonalizationStateless.d.ts +0 -74
  123. package/dist/personalization/PersonalizationStateless.d.ts.map +0 -1
  124. package/dist/personalization/PersonalizationStateless.js +0 -98
  125. package/dist/personalization/PersonalizationStateless.js.map +0 -1
  126. package/dist/personalization/index.d.ts +0 -6
  127. package/dist/personalization/index.d.ts.map +0 -1
  128. package/dist/personalization/index.js +0 -6
  129. package/dist/personalization/index.js.map +0 -1
  130. package/dist/personalization/resolvers/FlagsResolver.d.ts +0 -35
  131. package/dist/personalization/resolvers/FlagsResolver.d.ts.map +0 -1
  132. package/dist/personalization/resolvers/FlagsResolver.js +0 -47
  133. package/dist/personalization/resolvers/FlagsResolver.js.map +0 -1
  134. package/dist/personalization/resolvers/MergeTagValueResolver.d.ts +0 -74
  135. package/dist/personalization/resolvers/MergeTagValueResolver.d.ts.map +0 -1
  136. package/dist/personalization/resolvers/MergeTagValueResolver.js +0 -109
  137. package/dist/personalization/resolvers/MergeTagValueResolver.js.map +0 -1
  138. package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts +0 -142
  139. package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts.map +0 -1
  140. package/dist/personalization/resolvers/PersonalizedEntryResolver.js +0 -196
  141. package/dist/personalization/resolvers/PersonalizedEntryResolver.js.map +0 -1
  142. package/dist/personalization/resolvers/index.d.ts +0 -7
  143. package/dist/personalization/resolvers/index.d.ts.map +0 -1
  144. package/dist/personalization/resolvers/index.js +0 -7
  145. package/dist/personalization/resolvers/index.js.map +0 -1
  146. package/dist/signals.d.ts +0 -35
  147. package/dist/signals.d.ts.map +0 -1
  148. package/dist/signals.js +0 -30
  149. package/dist/signals.js.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
- import * as __rspack_external__contentful_optimization_api_client_cba5a7ee from "@contentful/optimization-api-client";
2
- import { batch, computed, effect, signal } from "@preact/signals-core";
3
- import { get as compat_get } from "es-toolkit/compat";
4
- import { diary, enable } from "diary";
5
- import { compare } from "diary/utils";
6
- import { isEqual } from "es-toolkit";
1
+ import { batch, computed, effect, signal, untracked } from "@preact/signals-core";
2
+ import { isEqual } from "es-toolkit/predicate";
3
+ import { __rspack_external__contentful_optimization_api_client_api_schemas_4192893e } from "./808.mjs";
4
+ import { __rspack_external__contentful_optimization_api_client_logger_f0d05f82 } from "./499.mjs";
5
+ import { __rspack_external__contentful_optimization_api_client_cba5a7ee } from "./942.mjs";
6
+ import { OPTIMIZATION_CORE_SDK_NAME, OPTIMIZATION_CORE_SDK_VERSION } from "./260.mjs";
7
+ import { PREVIEW_PANEL_SIGNALS_SYMBOL, PREVIEW_PANEL_SIGNAL_FNS_SYMBOL } from "./632.mjs";
7
8
  const FlagsResolver = {
8
9
  resolve (changes) {
9
10
  if (!changes) return {};
@@ -15,126 +16,20 @@ const FlagsResolver = {
15
16
  }
16
17
  };
17
18
  const resolvers_FlagsResolver = FlagsResolver;
18
- class Logger {
19
- name = '@contentful/optimization';
20
- PREFIX_PARTS = [
21
- 'Ctfl',
22
- 'O10n'
23
- ];
24
- DELIMITER = ':';
25
- diary;
26
- sinks = [];
27
- constructor(){
28
- this.diary = diary(this.name, this.onLogEvent.bind(this));
29
- enable(this.name);
30
- }
31
- assembleLocationPrefix(logLocation) {
32
- return `[${[
33
- ...this.PREFIX_PARTS,
34
- logLocation
35
- ].join(this.DELIMITER)}]`;
36
- }
37
- addSink(sink) {
38
- this.sinks = [
39
- ...this.sinks.filter((existingSink)=>existingSink.name !== sink.name),
40
- sink
41
- ];
42
- }
43
- removeSink(name) {
44
- this.sinks = this.sinks.filter((sink)=>sink.name !== name);
45
- }
46
- removeSinks() {
47
- this.sinks = [];
48
- }
49
- debug(logLocation, message, ...args) {
50
- this.diary.debug(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
51
- }
52
- info(logLocation, message, ...args) {
53
- this.diary.info(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
54
- }
55
- log(logLocation, message, ...args) {
56
- this.diary.log(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
57
- }
58
- warn(logLocation, message, ...args) {
59
- this.diary.warn(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
60
- }
61
- error(logLocation, message, ...args) {
62
- this.diary.error(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
63
- }
64
- fatal(logLocation, message, ...args) {
65
- this.diary.fatal(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
66
- }
67
- onLogEvent(event) {
68
- this.sinks.forEach((sink)=>{
69
- sink.ingest(event);
70
- });
71
- }
72
- }
73
- const logger = new Logger();
74
- function createScopedLogger(location) {
75
- return {
76
- debug: (message, ...args)=>{
77
- logger.debug(location, message, ...args);
78
- },
79
- info: (message, ...args)=>{
80
- logger.info(location, message, ...args);
81
- },
82
- log: (message, ...args)=>{
83
- logger.log(location, message, ...args);
84
- },
85
- warn: (message, ...args)=>{
86
- logger.warn(location, message, ...args);
87
- },
88
- error: (message, ...args)=>{
89
- logger.error(location, message, ...args);
90
- },
91
- fatal: (message, ...args)=>{
92
- logger.fatal(location, message, ...args);
93
- }
94
- };
95
- }
96
- class LogSink {
97
- }
98
- const src_LogSink = LogSink;
99
- const consoleMap = {
100
- debug: (...args)=>{
101
- console.debug(...args);
102
- },
103
- info: (...args)=>{
104
- console.info(...args);
105
- },
106
- log: (...args)=>{
107
- console.log(...args);
108
- },
109
- warn: (...args)=>{
110
- console.warn(...args);
111
- },
112
- error: (...args)=>{
113
- console.error(...args);
114
- },
115
- fatal: (...args)=>{
116
- console.error(...args);
117
- }
118
- };
119
- const COMPARISON_EQUALITY = 0;
120
- class ConsoleLogSink extends src_LogSink {
121
- name = 'ConsoleLogSink';
122
- verbosity;
123
- constructor(verbosity){
124
- super();
125
- this.verbosity = verbosity ?? 'error';
126
- }
127
- ingest(event) {
128
- if (compare(this.verbosity, event.level) > COMPARISON_EQUALITY) return;
129
- consoleMap[event.level](...event.messages);
130
- }
131
- }
132
- const MergeTagValueResolver_logger = createScopedLogger('Personalization');
19
+ const logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Personalization');
133
20
  const RESOLUTION_WARNING_BASE = 'Could not resolve Merge Tag value:';
21
+ const getAtPath = (value, path)=>{
22
+ if (!value || 'object' != typeof value) return;
23
+ if (!path) return value;
24
+ let current = value;
25
+ const segments = path.split('.').filter(Boolean);
26
+ for (const segment of segments){
27
+ if (!current || 'object' != typeof current && 'function' != typeof current) return;
28
+ current = Reflect.get(current, segment);
29
+ }
30
+ return current;
31
+ };
134
32
  const MergeTagValueResolver = {
135
- isMergeTagEntry (embeddedEntryNodeTarget) {
136
- return __rspack_external__contentful_optimization_api_client_cba5a7ee.MergeTagEntry.safeParse(embeddedEntryNodeTarget).success;
137
- },
138
33
  normalizeSelectors (id) {
139
34
  return id.split('_').map((_path, index, paths)=>{
140
35
  const dotPath = paths.slice(0, index).join('.');
@@ -147,46 +42,46 @@ const MergeTagValueResolver = {
147
42
  },
148
43
  getValueFromProfile (id, profile) {
149
44
  const selectors = MergeTagValueResolver.normalizeSelectors(id);
150
- const matchingSelector = selectors.find((selector)=>compat_get(profile, selector));
45
+ const matchingSelector = selectors.find((selector)=>getAtPath(profile, selector));
151
46
  if (!matchingSelector) return;
152
- const value = compat_get(profile, matchingSelector);
47
+ const value = getAtPath(profile, matchingSelector);
153
48
  if (!value || 'string' != typeof value && 'number' != typeof value && 'boolean' != typeof value) return;
154
49
  return `${value}`;
155
50
  },
156
51
  resolve (mergeTagEntry, profile) {
157
- if (!MergeTagValueResolver.isMergeTagEntry(mergeTagEntry)) return void MergeTagValueResolver_logger.warn(`${RESOLUTION_WARNING_BASE} supplied entry is not a Merge Tag entry`);
52
+ if (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isMergeTagEntry)(mergeTagEntry)) return void logger.warn(`${RESOLUTION_WARNING_BASE} supplied entry is not a Merge Tag entry`);
158
53
  const { fields: { nt_fallback: fallback } } = mergeTagEntry;
159
- if (!__rspack_external__contentful_optimization_api_client_cba5a7ee.Profile.safeParse(profile).success) {
160
- MergeTagValueResolver_logger.warn(`${RESOLUTION_WARNING_BASE} no valid profile`);
54
+ if (!__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Profile.safeParse(profile).success) {
55
+ logger.warn(`${RESOLUTION_WARNING_BASE} no valid profile`);
161
56
  return fallback;
162
57
  }
163
58
  return MergeTagValueResolver.getValueFromProfile(mergeTagEntry.fields.nt_mergetag_id, profile) ?? fallback;
164
59
  }
165
60
  };
166
61
  const resolvers_MergeTagValueResolver = MergeTagValueResolver;
167
- const PersonalizedEntryResolver_logger = createScopedLogger('Personalization');
62
+ const PersonalizedEntryResolver_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Personalization');
168
63
  const PersonalizedEntryResolver_RESOLUTION_WARNING_BASE = 'Could not resolve personalized entry variant:';
169
64
  const PersonalizedEntryResolver = {
170
65
  getPersonalizationEntry ({ personalizedEntry, selectedPersonalizations }, skipValidation = false) {
171
- if (!skipValidation && (!selectedPersonalizations.length || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizedEntry)(personalizedEntry))) return;
172
- const personalizationEntry = personalizedEntry.fields.nt_experiences.filter((maybePersonalization)=>(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(maybePersonalization)).find((personalizationEntry)=>selectedPersonalizations.some(({ experienceId })=>experienceId === personalizationEntry.fields.nt_experience_id));
66
+ if (!skipValidation && (!selectedPersonalizations.length || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizedEntry)(personalizedEntry))) return;
67
+ const personalizationEntry = personalizedEntry.fields.nt_experiences.filter((maybePersonalization)=>(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizationEntry)(maybePersonalization)).find((personalizationEntry)=>selectedPersonalizations.some(({ experienceId })=>experienceId === personalizationEntry.fields.nt_experience_id));
173
68
  return personalizationEntry;
174
69
  },
175
70
  getSelectedPersonalization ({ personalizationEntry, selectedPersonalizations }, skipValidation = false) {
176
- if (!skipValidation && (!selectedPersonalizations.length || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(personalizationEntry))) return;
71
+ if (!skipValidation && (!selectedPersonalizations.length || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizationEntry)(personalizationEntry))) return;
177
72
  const selectedPersonalization = selectedPersonalizations.find(({ experienceId })=>experienceId === personalizationEntry.fields.nt_experience_id);
178
73
  return selectedPersonalization;
179
74
  },
180
75
  getSelectedVariant ({ personalizedEntry, personalizationEntry, selectedVariantIndex }, skipValidation = false) {
181
- if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizedEntry)(personalizedEntry) || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(personalizationEntry))) return;
182
- const relevantVariants = personalizationEntry.fields.nt_config?.components?.filter((component)=>(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isEntryReplacementComponent)(component) && !component.baseline.hidden).find((component)=>component.baseline.id === personalizedEntry.sys.id)?.variants;
76
+ if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizedEntry)(personalizedEntry) || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizationEntry)(personalizationEntry))) return;
77
+ const relevantVariants = personalizationEntry.fields.nt_config?.components?.filter((component)=>(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isEntryReplacementComponent)(component) && !component.baseline.hidden).find((component)=>component.baseline.id === personalizedEntry.sys.id)?.variants;
183
78
  if (!relevantVariants?.length) return;
184
79
  return relevantVariants.at(selectedVariantIndex - 1);
185
80
  },
186
81
  getSelectedVariantEntry ({ personalizationEntry, selectedVariant }, skipValidation = false) {
187
- if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(personalizationEntry) || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isEntryReplacementVariant)(selectedVariant))) return;
82
+ if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizationEntry)(personalizationEntry) || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isEntryReplacementVariant)(selectedVariant))) return;
188
83
  const selectedVariantEntry = personalizationEntry.fields.nt_variants?.find((variant)=>variant.sys.id === selectedVariant.id);
189
- return (0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isEntry)(selectedVariantEntry) ? selectedVariantEntry : void 0;
84
+ return (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isEntry)(selectedVariantEntry) ? selectedVariantEntry : void 0;
190
85
  },
191
86
  resolve (entry, selectedPersonalizations) {
192
87
  PersonalizedEntryResolver_logger.debug(`Resolving personalized entry for baseline entry ${entry.sys.id}`);
@@ -196,7 +91,7 @@ const PersonalizedEntryResolver = {
196
91
  entry
197
92
  };
198
93
  }
199
- if (!(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizedEntry)(entry)) {
94
+ if (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isPersonalizedEntry)(entry)) {
200
95
  PersonalizedEntryResolver_logger.warn(`${PersonalizedEntryResolver_RESOLUTION_WARNING_BASE} entry ${entry.sys.id} is not personalized`);
201
96
  return {
202
97
  entry
@@ -253,10 +148,13 @@ const PersonalizedEntryResolver = {
253
148
  };
254
149
  const resolvers_PersonalizedEntryResolver = PersonalizedEntryResolver;
255
150
  const signals_changes = signal();
151
+ const blockedEvent = signal();
256
152
  const consent = signal();
257
153
  const signals_event = signal();
258
154
  const flags = computed(()=>resolvers_FlagsResolver.resolve(signals_changes.value ?? []));
259
155
  const online = signal(true);
156
+ const previewPanelAttached = signal(false);
157
+ const previewPanelOpen = signal(false);
260
158
  const signals_personalizations = signal();
261
159
  const signals_profile = signal();
262
160
  function toObservable(s) {
@@ -272,14 +170,23 @@ function toObservable(s) {
272
170
  };
273
171
  }
274
172
  const signals = {
173
+ blockedEvent: blockedEvent,
275
174
  changes: signals_changes,
276
175
  consent: consent,
277
176
  event: signals_event,
278
177
  flags: flags,
279
178
  online: online,
179
+ previewPanelAttached: previewPanelAttached,
180
+ previewPanelOpen: previewPanelOpen,
280
181
  personalizations: signals_personalizations,
281
182
  profile: signals_profile
282
183
  };
184
+ const signalFns = {
185
+ batch: batch,
186
+ computed: computed,
187
+ effect: effect,
188
+ untracked: untracked
189
+ };
283
190
  const isFunction = (v)=>'function' == typeof v;
284
191
  const nameToString = (name)=>'string' == typeof name ? name : 'symbol' == typeof name ? name.description ?? String(name) : String(name);
285
192
  const isOnBlockedKey = (v)=>'string' == typeof v || 'symbol' == typeof v;
@@ -323,49 +230,195 @@ function guardedBy(predicateName, opts) {
323
230
  });
324
231
  };
325
232
  }
326
- class ValuePresence {
327
- #map;
328
- constructor(defaultMap){
329
- const map = new Map();
330
- if (defaultMap) Object.entries(defaultMap).map(([scope, values])=>map.set(scope.length ? scope : void 0, new Set(values)));
331
- this.#map = map;
332
- }
333
- isPresent(scope, value) {
334
- return this.#map.get(scope)?.has(value) ?? false;
335
- }
336
- addValue(scope, value) {
337
- const values = this.#map.get(scope);
338
- if (values) values.add(value);
339
- else this.#map.set(scope, new Set([
340
- value
341
- ]));
342
- }
343
- removeValue(scope, value) {
344
- this.#map.get(scope)?.delete(value);
345
- }
346
- reset(scope) {
347
- if (void 0 !== scope) this.#map.get(scope)?.clear();
348
- else this.#map.clear();
233
+ const toPositiveInt = (value, fallback)=>{
234
+ if (!Number.isFinite(value) || void 0 === value || value < 1) return fallback;
235
+ return Math.floor(value);
236
+ };
237
+ const toRatio = (value, fallback)=>{
238
+ if (!Number.isFinite(value) || void 0 === value) return fallback;
239
+ return Math.min(1, Math.max(0, value));
240
+ };
241
+ const DEFAULT_QUEUE_FLUSH_POLICY = {
242
+ baseBackoffMs: 500,
243
+ maxBackoffMs: 30000,
244
+ jitterRatio: 0.2,
245
+ maxConsecutiveFailures: 8,
246
+ circuitOpenMs: 120000
247
+ };
248
+ const resolveQueueFlushPolicy = (policy, defaults = DEFAULT_QUEUE_FLUSH_POLICY)=>{
249
+ const baseBackoffMs = toPositiveInt(policy?.baseBackoffMs, defaults.baseBackoffMs);
250
+ const maxBackoffMs = Math.max(baseBackoffMs, toPositiveInt(policy?.maxBackoffMs, defaults.maxBackoffMs));
251
+ return {
252
+ baseBackoffMs,
253
+ maxBackoffMs,
254
+ jitterRatio: toRatio(policy?.jitterRatio, defaults.jitterRatio),
255
+ maxConsecutiveFailures: toPositiveInt(policy?.maxConsecutiveFailures, defaults.maxConsecutiveFailures),
256
+ circuitOpenMs: toPositiveInt(policy?.circuitOpenMs, defaults.circuitOpenMs),
257
+ onCircuitOpen: policy?.onCircuitOpen,
258
+ onFlushFailure: policy?.onFlushFailure,
259
+ onFlushRecovered: policy?.onFlushRecovered
260
+ };
261
+ };
262
+ const computeQueueFlushRetryDelayMs = (options)=>{
263
+ const { consecutiveFailures, policy: { baseBackoffMs, jitterRatio, maxBackoffMs } } = options;
264
+ const exponential = baseBackoffMs * 2 ** Math.max(0, consecutiveFailures - 1);
265
+ const capped = Math.min(maxBackoffMs, exponential);
266
+ const jitter = capped * jitterRatio * Math.random();
267
+ return Math.round(capped + jitter);
268
+ };
269
+ const createQueueFlushFailureWindow = (options)=>{
270
+ const { consecutiveFailures, failureTimestamp, retryDelayMs, policy: { maxConsecutiveFailures, circuitOpenMs } } = options;
271
+ if (consecutiveFailures < maxConsecutiveFailures) return {
272
+ openedCircuit: false,
273
+ retryDelayMs,
274
+ nextFlushAllowedAt: failureTimestamp + retryDelayMs,
275
+ circuitOpenUntil: 0
276
+ };
277
+ const circuitOpenUntil = failureTimestamp + circuitOpenMs;
278
+ return {
279
+ openedCircuit: true,
280
+ retryDelayMs: circuitOpenMs,
281
+ nextFlushAllowedAt: circuitOpenUntil,
282
+ circuitOpenUntil
283
+ };
284
+ };
285
+ class QueueFlushRuntime {
286
+ circuitOpenUntil = 0;
287
+ flushFailureCount = 0;
288
+ flushInFlight = false;
289
+ nextFlushAllowedAt = 0;
290
+ onCallbackError;
291
+ onRetry;
292
+ policy;
293
+ retryTimer;
294
+ constructor(options){
295
+ const { onCallbackError, onRetry, policy } = options;
296
+ this.policy = policy;
297
+ this.onRetry = onRetry;
298
+ this.onCallbackError = onCallbackError;
299
+ }
300
+ reset() {
301
+ this.clearScheduledRetry();
302
+ this.circuitOpenUntil = 0;
303
+ this.flushFailureCount = 0;
304
+ this.flushInFlight = false;
305
+ this.nextFlushAllowedAt = 0;
306
+ }
307
+ clearScheduledRetry() {
308
+ if (void 0 === this.retryTimer) return;
309
+ clearTimeout(this.retryTimer);
310
+ this.retryTimer = void 0;
311
+ }
312
+ shouldSkip(options) {
313
+ const { force, isOnline } = options;
314
+ if (this.flushInFlight) return true;
315
+ if (force) return false;
316
+ if (!isOnline) return true;
317
+ const now = Date.now();
318
+ if (this.nextFlushAllowedAt > now) return true;
319
+ if (this.circuitOpenUntil > now) return true;
320
+ return false;
321
+ }
322
+ markFlushStarted() {
323
+ this.flushInFlight = true;
324
+ }
325
+ markFlushFinished() {
326
+ this.flushInFlight = false;
327
+ }
328
+ handleFlushSuccess() {
329
+ const { flushFailureCount: previousConsecutiveFailures } = this;
330
+ this.clearScheduledRetry();
331
+ this.circuitOpenUntil = 0;
332
+ this.flushFailureCount = 0;
333
+ this.nextFlushAllowedAt = 0;
334
+ if (previousConsecutiveFailures <= 0) return;
335
+ this.safeInvoke('onFlushRecovered', {
336
+ consecutiveFailures: previousConsecutiveFailures
337
+ });
338
+ }
339
+ handleFlushFailure(options) {
340
+ const { queuedBatches, queuedEvents } = options;
341
+ this.flushFailureCount += 1;
342
+ const retryDelayMs = computeQueueFlushRetryDelayMs({
343
+ consecutiveFailures: this.flushFailureCount,
344
+ policy: this.policy
345
+ });
346
+ const failureTimestamp = Date.now();
347
+ const failureContext = {
348
+ consecutiveFailures: this.flushFailureCount,
349
+ queuedBatches,
350
+ queuedEvents,
351
+ retryDelayMs
352
+ };
353
+ this.safeInvoke('onFlushFailure', failureContext);
354
+ const failureWindow = createQueueFlushFailureWindow({
355
+ consecutiveFailures: this.flushFailureCount,
356
+ failureTimestamp,
357
+ retryDelayMs,
358
+ policy: this.policy
359
+ });
360
+ const { circuitOpenUntil, nextFlushAllowedAt, openedCircuit, retryDelayMs: scheduledRetryDelayMs } = failureWindow;
361
+ this.nextFlushAllowedAt = nextFlushAllowedAt;
362
+ if (openedCircuit) {
363
+ this.circuitOpenUntil = circuitOpenUntil;
364
+ this.safeInvoke('onCircuitOpen', {
365
+ ...failureContext,
366
+ retryDelayMs: scheduledRetryDelayMs
367
+ });
368
+ }
369
+ this.scheduleRetry(scheduledRetryDelayMs);
370
+ }
371
+ scheduleRetry(delayMs) {
372
+ this.clearScheduledRetry();
373
+ this.retryTimer = setTimeout(()=>{
374
+ this.retryTimer = void 0;
375
+ this.onRetry();
376
+ }, delayMs);
377
+ }
378
+ safeInvoke(...args) {
379
+ const [callbackName, payload] = args;
380
+ try {
381
+ if ('onFlushRecovered' === callbackName) return void this.policy.onFlushRecovered?.(payload);
382
+ if ('onCircuitOpen' === callbackName) return void this.policy.onCircuitOpen?.(payload);
383
+ this.policy.onFlushFailure?.(payload);
384
+ } catch (error) {
385
+ this.onCallbackError?.(callbackName, error);
386
+ }
349
387
  }
350
388
  }
351
- const value_presence_ValuePresence = ValuePresence;
389
+ const ProductBase_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('ProductBase');
352
390
  const defaultAllowedEvents = [
391
+ 'identify',
353
392
  'page',
354
- 'identify'
393
+ 'screen'
355
394
  ];
356
395
  class ProductBase {
357
396
  allowedEventTypes;
358
397
  builder;
359
398
  api;
360
- duplicationDetector;
361
399
  interceptors;
400
+ onEventBlocked;
362
401
  constructor(options){
363
402
  const { api, builder, config, interceptors } = options;
364
403
  this.allowedEventTypes = config?.allowedEventTypes ?? defaultAllowedEvents;
365
404
  this.api = api;
366
405
  this.builder = builder;
367
- this.duplicationDetector = new value_presence_ValuePresence(config?.preventedComponentEvents);
368
406
  this.interceptors = interceptors;
407
+ this.onEventBlocked = config?.onEventBlocked;
408
+ }
409
+ reportBlockedEvent(reason, product, method, args) {
410
+ const event = {
411
+ reason,
412
+ product,
413
+ method,
414
+ args
415
+ };
416
+ try {
417
+ this.onEventBlocked?.(event);
418
+ } catch (error) {
419
+ ProductBase_logger.warn(`onEventBlocked callback failed for method "${method}"`, error);
420
+ }
421
+ blockedEvent.value = event;
369
422
  }
370
423
  }
371
424
  const src_ProductBase = ProductBase;
@@ -667,14 +720,20 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
667
720
  return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
668
721
  }
669
722
  var _dec, _dec1, _dec2, _dec3, _initProto;
670
- const AnalyticsStateful_logger = createScopedLogger('Analytics');
723
+ const AnalyticsStateful_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Analytics');
671
724
  const MAX_QUEUED_EVENTS = 25;
672
- _dec = guardedBy('isNotDuplicated', {
673
- onBlocked: 'onBlockedByDuplication'
725
+ const ANALYTICS_METHOD_EVENT_TYPE_MAP = {
726
+ trackComponentView: 'component',
727
+ trackFlagView: 'component',
728
+ trackComponentClick: 'component_click',
729
+ trackComponentHover: 'component_hover'
730
+ };
731
+ _dec = guardedBy('hasConsent', {
732
+ onBlocked: 'onBlockedByConsent'
674
733
  }), _dec1 = guardedBy('hasConsent', {
675
734
  onBlocked: 'onBlockedByConsent'
676
- }), _dec2 = guardedBy('isNotDuplicated', {
677
- onBlocked: 'onBlockedByDuplication'
735
+ }), _dec2 = guardedBy('hasConsent', {
736
+ onBlocked: 'onBlockedByConsent'
678
737
  }), _dec3 = guardedBy('hasConsent', {
679
738
  onBlocked: 'onBlockedByConsent'
680
739
  });
@@ -682,25 +741,31 @@ class AnalyticsStateful extends analytics_AnalyticsBase {
682
741
  static{
683
742
  ({ e: [_initProto] } = _apply_decs_2203_r(this, [
684
743
  [
685
- [
686
- _dec,
687
- _dec1
688
- ],
744
+ _dec,
689
745
  2,
690
746
  "trackComponentView"
691
747
  ],
692
748
  [
693
- [
694
- _dec2,
695
- _dec3
696
- ],
749
+ _dec1,
750
+ 2,
751
+ "trackComponentClick"
752
+ ],
753
+ [
754
+ _dec2,
755
+ 2,
756
+ "trackComponentHover"
757
+ ],
758
+ [
759
+ _dec3,
697
760
  2,
698
761
  "trackFlagView"
699
762
  ]
700
763
  ], []));
701
764
  }
702
765
  queue = (_initProto(this), new Map());
766
+ flushRuntime;
703
767
  states = {
768
+ blockedEventStream: toObservable(blockedEvent),
704
769
  eventStream: toObservable(signals_event),
705
770
  profile: toObservable(signals_profile)
706
771
  };
@@ -712,47 +777,47 @@ class AnalyticsStateful extends analytics_AnalyticsBase {
712
777
  config,
713
778
  interceptors
714
779
  });
715
- const { defaults } = config ?? {};
716
- if (defaults?.profile !== void 0) {
717
- const { profile: defaultProfile } = defaults;
718
- signals_profile.value = defaultProfile;
719
- }
720
- effect(()=>{
721
- const id = signals_profile.value?.id;
722
- AnalyticsStateful_logger.info(`Analytics ${consent.value ? 'will' : 'will not'} be collected due to consent (${consent.value})`);
723
- AnalyticsStateful_logger.debug(`Profile ${id && `with ID ${id}`} has been ${id ? 'set' : 'cleared'}`);
724
- });
725
- effect(()=>{
726
- if (online.value) this.flush();
780
+ this.applyDefaults(config?.defaults);
781
+ this.flushRuntime = new QueueFlushRuntime({
782
+ policy: resolveQueueFlushPolicy(config?.queuePolicy),
783
+ onRetry: ()=>{
784
+ this.flush();
785
+ },
786
+ onCallbackError: (callbackName, error)=>{
787
+ AnalyticsStateful_logger.warn(`Analytics flush policy callback "${callbackName}" failed`, error);
788
+ }
727
789
  });
790
+ this.initializeEffects();
728
791
  }
729
792
  reset() {
793
+ this.flushRuntime.reset();
730
794
  batch(()=>{
795
+ blockedEvent.value = void 0;
731
796
  signals_event.value = void 0;
732
797
  signals_profile.value = void 0;
733
798
  });
734
799
  }
735
800
  hasConsent(name) {
736
- return !!consent.value || (this.allowedEventTypes ?? []).includes('trackComponentView' === name || 'trackFlagView' === name ? 'component' : name);
801
+ const mappedEventType = ANALYTICS_METHOD_EVENT_TYPE_MAP[name] ?? name;
802
+ return !!consent.value || (this.allowedEventTypes ?? []).includes(mappedEventType);
737
803
  }
738
804
  onBlockedByConsent(name, payload) {
739
805
  AnalyticsStateful_logger.warn(`Event "${name}" was blocked due to lack of consent; payload: ${JSON.stringify(payload)}`);
806
+ this.reportBlockedEvent('consent', 'analytics', name, payload);
740
807
  }
741
- isNotDuplicated(_name, payload) {
742
- const [{ componentId: value }, duplicationScope] = payload;
743
- const isDuplicated = this.duplicationDetector.isPresent(duplicationScope, value);
744
- if (!isDuplicated) this.duplicationDetector.addValue(duplicationScope, value);
745
- return !isDuplicated;
746
- }
747
- onBlockedByDuplication(name, payload) {
748
- const componentType = 'trackFlagView' === name ? 'flag' : 'component';
749
- AnalyticsStateful_logger.debug(`Duplicate "${componentType} view" event detected, skipping; payload: ${JSON.stringify(payload)}`);
750
- }
751
- async trackComponentView(payload, _duplicationScope = '') {
808
+ async trackComponentView(payload) {
752
809
  AnalyticsStateful_logger.info(`Processing "component view" event for ${payload.componentId}`);
753
810
  await this.enqueueEvent(this.builder.buildComponentView(payload));
754
811
  }
755
- async trackFlagView(payload, _duplicationScope = '') {
812
+ async trackComponentClick(payload) {
813
+ AnalyticsStateful_logger.info(`Processing "component click" event for ${payload.componentId}`);
814
+ await this.enqueueEvent(this.builder.buildComponentClick(payload));
815
+ }
816
+ async trackComponentHover(payload) {
817
+ AnalyticsStateful_logger.info(`Processing "component hover" event for ${payload.componentId}`);
818
+ await this.enqueueEvent(this.builder.buildComponentHover(payload));
819
+ }
820
+ async trackFlagView(payload) {
756
821
  AnalyticsStateful_logger.debug(`Processing "flag view" event for ${payload.componentId}`);
757
822
  await this.enqueueEvent(this.builder.buildFlagView(payload));
758
823
  }
@@ -760,56 +825,128 @@ class AnalyticsStateful extends analytics_AnalyticsBase {
760
825
  const { value: profile } = signals_profile;
761
826
  if (!profile) return void AnalyticsStateful_logger.warn('Attempting to emit an event without an Optimization profile');
762
827
  const intercepted = await this.interceptors.event.run(event);
763
- const validEvent = __rspack_external__contentful_optimization_api_client_cba5a7ee.InsightsEvent.parse(intercepted);
828
+ const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.InsightsEvent, intercepted);
764
829
  AnalyticsStateful_logger.debug(`Queueing ${validEvent.type} event for profile ${profile.id}`, validEvent);
765
- const profileEventQueue = this.queue.get(profile);
830
+ const { id: profileId } = profile;
831
+ const queuedProfileEvents = this.queue.get(profileId);
766
832
  signals_event.value = validEvent;
767
- if (profileEventQueue) profileEventQueue.push(validEvent);
768
- else this.queue.set(profile, [
769
- validEvent
770
- ]);
833
+ if (queuedProfileEvents) {
834
+ queuedProfileEvents.profile = profile;
835
+ queuedProfileEvents.events.push(validEvent);
836
+ } else this.queue.set(profileId, {
837
+ profile,
838
+ events: [
839
+ validEvent
840
+ ]
841
+ });
771
842
  await this.flushMaxEvents();
772
843
  }
773
844
  async flushMaxEvents() {
774
- if (this.queue.values().toArray().flat().length >= MAX_QUEUED_EVENTS) await this.flush();
775
- }
776
- async flush() {
845
+ if (this.getQueuedEventCount() >= MAX_QUEUED_EVENTS) await this.flush();
846
+ }
847
+ async flush(options = {}) {
848
+ const { force = false } = options;
849
+ if (this.flushRuntime.shouldSkip({
850
+ force,
851
+ isOnline: !!online.value
852
+ })) return;
777
853
  AnalyticsStateful_logger.debug('Flushing event queue');
854
+ const batches = this.createBatches();
855
+ if (!batches.length) return void this.flushRuntime.clearScheduledRetry();
856
+ this.flushRuntime.markFlushStarted();
857
+ try {
858
+ const sendSuccess = await this.trySendBatches(batches);
859
+ if (sendSuccess) {
860
+ this.queue.clear();
861
+ this.flushRuntime.handleFlushSuccess();
862
+ } else this.flushRuntime.handleFlushFailure({
863
+ queuedBatches: batches.length,
864
+ queuedEvents: this.getQueuedEventCount()
865
+ });
866
+ } finally{
867
+ this.flushRuntime.markFlushFinished();
868
+ }
869
+ }
870
+ applyDefaults(defaults) {
871
+ if (defaults?.profile === void 0) return;
872
+ const { profile: defaultProfile } = defaults;
873
+ signals_profile.value = defaultProfile;
874
+ }
875
+ initializeEffects() {
876
+ effect(()=>{
877
+ const id = signals_profile.value?.id;
878
+ AnalyticsStateful_logger.info(`Analytics ${consent.value ? 'will' : 'will not'} be collected due to consent (${consent.value})`);
879
+ AnalyticsStateful_logger.debug(`Profile ${id && `with ID ${id}`} has been ${id ? 'set' : 'cleared'}`);
880
+ });
881
+ effect(()=>{
882
+ if (!online.value) return;
883
+ this.flushRuntime.clearScheduledRetry();
884
+ this.flush({
885
+ force: true
886
+ });
887
+ });
888
+ }
889
+ createBatches() {
778
890
  const batches = [];
779
- this.queue.forEach((events, profile)=>batches.push({
891
+ this.queue.forEach(({ profile, events })=>{
892
+ batches.push({
780
893
  profile,
781
894
  events
782
- }));
783
- if (!batches.length) return;
784
- const sendSuccess = await this.api.insights.sendBatchEvents(batches);
785
- if (sendSuccess) this.queue.clear();
895
+ });
896
+ });
897
+ return batches;
898
+ }
899
+ async trySendBatches(batches) {
900
+ try {
901
+ return await this.api.insights.sendBatchEvents(batches);
902
+ } catch (error) {
903
+ AnalyticsStateful_logger.warn('Analytics queue flush request threw an error', error);
904
+ return false;
905
+ }
906
+ }
907
+ getQueuedEventCount() {
908
+ let queuedCount = 0;
909
+ this.queue.forEach(({ events })=>{
910
+ queuedCount += events.length;
911
+ });
912
+ return queuedCount;
786
913
  }
787
914
  }
788
915
  const analytics_AnalyticsStateful = AnalyticsStateful;
789
- const AnalyticsStateless_logger = createScopedLogger('Analytics');
916
+ const AnalyticsStateless_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Analytics');
790
917
  class AnalyticsStateless extends analytics_AnalyticsBase {
791
918
  async trackComponentView(args) {
792
919
  AnalyticsStateless_logger.info('Processing "component view" event');
793
920
  const { profile, ...builderArgs } = args;
794
921
  const event = this.builder.buildComponentView(builderArgs);
795
- const intercepted = await this.interceptors.event.run(event);
796
- const parsed = __rspack_external__contentful_optimization_api_client_cba5a7ee.ComponentViewEvent.parse(intercepted);
797
- await this.sendBatchEvent(parsed, profile);
922
+ await this.sendBatchEvent(event, profile);
923
+ }
924
+ async trackComponentClick(args) {
925
+ AnalyticsStateless_logger.info('Processing "component click" event');
926
+ const { profile, ...builderArgs } = args;
927
+ const event = this.builder.buildComponentClick(builderArgs);
928
+ await this.sendBatchEvent(event, profile);
929
+ }
930
+ async trackComponentHover(args) {
931
+ AnalyticsStateless_logger.info('Processing "component hover" event');
932
+ const { profile, ...builderArgs } = args;
933
+ const event = this.builder.buildComponentHover(builderArgs);
934
+ await this.sendBatchEvent(event, profile);
798
935
  }
799
936
  async trackFlagView(args) {
800
937
  AnalyticsStateless_logger.debug('Processing "flag view" event');
801
938
  const { profile, ...builderArgs } = args;
802
939
  const event = this.builder.buildFlagView(builderArgs);
803
- const intercepted = await this.interceptors.event.run(event);
804
- const parsed = __rspack_external__contentful_optimization_api_client_cba5a7ee.ComponentViewEvent.parse(intercepted);
805
- await this.sendBatchEvent(parsed, profile);
940
+ await this.sendBatchEvent(event, profile);
806
941
  }
807
942
  async sendBatchEvent(event, profile) {
808
- const batchEvent = __rspack_external__contentful_optimization_api_client_cba5a7ee.BatchInsightsEventArray.parse([
943
+ const intercepted = await this.interceptors.event.run(event);
944
+ const parsed = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.InsightsEvent, intercepted);
945
+ const batchEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.BatchInsightsEventArray, [
809
946
  {
810
947
  profile,
811
948
  events: [
812
- event
949
+ parsed
813
950
  ]
814
951
  }
815
952
  ]);
@@ -817,8 +954,6 @@ class AnalyticsStateless extends analytics_AnalyticsBase {
817
954
  }
818
955
  }
819
956
  const analytics_AnalyticsStateless = AnalyticsStateless;
820
- const OPTIMIZATION_CORE_SDK_VERSION = "0.1.0-alpha";
821
- const ANONYMOUS_ID_COOKIE = 'ctfl-opt-aid';
822
957
  class InterceptorManager {
823
958
  interceptors = new Map();
824
959
  nextId = 0;
@@ -854,59 +989,98 @@ class CoreBase {
854
989
  };
855
990
  constructor(config){
856
991
  this.config = config;
857
- const { analytics, personalization, eventBuilder, logLevel, environment, clientId } = config;
858
- logger.addSink(new ConsoleLogSink(logLevel));
992
+ const { analytics, personalization, eventBuilder, logLevel, environment, clientId, fetchOptions } = config;
993
+ __rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.addSink(new __rspack_external__contentful_optimization_api_client_logger_f0d05f82.ConsoleLogSink(logLevel));
859
994
  const apiConfig = {
860
- ...analytics,
861
- ...personalization,
862
995
  clientId,
863
- environment
996
+ environment,
997
+ fetchOptions,
998
+ analytics,
999
+ personalization
864
1000
  };
865
1001
  this.api = new __rspack_external__contentful_optimization_api_client_cba5a7ee.ApiClient(apiConfig);
866
1002
  this.eventBuilder = new __rspack_external__contentful_optimization_api_client_cba5a7ee.EventBuilder(eventBuilder ?? {
867
1003
  channel: 'server',
868
1004
  library: {
869
- name: 'Optimization Core',
1005
+ name: OPTIMIZATION_CORE_SDK_NAME,
870
1006
  version: OPTIMIZATION_CORE_SDK_VERSION
871
1007
  }
872
1008
  });
873
1009
  }
1010
+ get flagsResolver() {
1011
+ return this._personalization.flagsResolver;
1012
+ }
1013
+ get mergeTagValueResolver() {
1014
+ return this._personalization.mergeTagValueResolver;
1015
+ }
1016
+ get personalizedEntryResolver() {
1017
+ return this._personalization.personalizedEntryResolver;
1018
+ }
874
1019
  getCustomFlag(name, changes) {
875
- return this.personalization.getCustomFlag(name, changes);
1020
+ return this._personalization.getCustomFlag(name, changes);
1021
+ }
1022
+ getCustomFlags(changes) {
1023
+ return this._personalization.getCustomFlags(changes);
876
1024
  }
877
1025
  personalizeEntry(entry, personalizations) {
878
- return this.personalization.personalizeEntry(entry, personalizations);
1026
+ return this._personalization.personalizeEntry(entry, personalizations);
879
1027
  }
880
1028
  getMergeTagValue(embeddedEntryNodeTarget, profile) {
881
- return this.personalization.getMergeTagValue(embeddedEntryNodeTarget, profile);
1029
+ return this._personalization.getMergeTagValue(embeddedEntryNodeTarget, profile);
882
1030
  }
883
1031
  async identify(payload) {
884
- return await this.personalization.identify(payload);
1032
+ return await this._personalization.identify(payload);
885
1033
  }
886
1034
  async page(payload) {
887
- return await this.personalization.page(payload);
1035
+ return await this._personalization.page(payload);
888
1036
  }
889
1037
  async screen(payload) {
890
- return await this.personalization.screen(payload);
1038
+ return await this._personalization.screen(payload);
891
1039
  }
892
1040
  async track(payload) {
893
- return await this.personalization.track(payload);
1041
+ return await this._personalization.track(payload);
1042
+ }
1043
+ async trackComponentView(payload) {
1044
+ if (payload.sticky) return await this._personalization.trackComponentView(payload);
1045
+ await this._analytics.trackComponentView(payload);
894
1046
  }
895
- async trackComponentView(payload, duplicationScope) {
896
- if (payload.sticky) return await this.personalization.trackComponentView(payload, duplicationScope);
897
- await this.analytics.trackComponentView(payload, duplicationScope);
1047
+ async trackComponentClick(payload) {
1048
+ await this._analytics.trackComponentClick(payload);
898
1049
  }
899
- async trackFlagView(payload, duplicationScope) {
900
- await this.analytics.trackFlagView(payload, duplicationScope);
1050
+ async trackComponentHover(payload) {
1051
+ await this._analytics.trackComponentHover(payload);
1052
+ }
1053
+ async trackFlagView(payload) {
1054
+ await this._analytics.trackFlagView(payload);
901
1055
  }
902
1056
  }
903
1057
  const src_CoreBase = CoreBase;
1058
+ const STATEFUL_RUNTIME_LOCK_KEY = '__ctfl_optimization_stateful_runtime_lock__';
1059
+ const getStatefulRuntimeLock = ()=>{
1060
+ const singletonGlobal = globalThis;
1061
+ singletonGlobal[STATEFUL_RUNTIME_LOCK_KEY] ??= {
1062
+ owner: void 0
1063
+ };
1064
+ return singletonGlobal[STATEFUL_RUNTIME_LOCK_KEY];
1065
+ };
1066
+ const acquireStatefulRuntimeSingleton = (owner)=>{
1067
+ const lock = getStatefulRuntimeLock();
1068
+ if (lock.owner) throw new Error(`Stateful Optimization SDK already initialized (${lock.owner}). Only one stateful instance is supported per runtime.`);
1069
+ lock.owner = owner;
1070
+ };
1071
+ const releaseStatefulRuntimeSingleton = (owner)=>{
1072
+ const lock = getStatefulRuntimeLock();
1073
+ if (lock.owner === owner) lock.owner = void 0;
1074
+ };
904
1075
  class PersonalizationBase extends src_ProductBase {
905
1076
  flagsResolver = resolvers_FlagsResolver;
906
1077
  mergeTagValueResolver = resolvers_MergeTagValueResolver;
907
1078
  personalizedEntryResolver = resolvers_PersonalizedEntryResolver;
908
1079
  getCustomFlag(name, changes) {
909
- return resolvers_FlagsResolver.resolve(changes)[name];
1080
+ return this.getCustomFlags(changes)[name];
1081
+ }
1082
+ getCustomFlags(changes) {
1083
+ return resolvers_FlagsResolver.resolve(changes);
910
1084
  }
911
1085
  personalizeEntry(entry, personalizations) {
912
1086
  return resolvers_PersonalizedEntryResolver.resolve(entry, personalizations);
@@ -1210,8 +1384,14 @@ function PersonalizationStateful_applyDecs2203RFactory() {
1210
1384
  function PersonalizationStateful_apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
1211
1385
  return (PersonalizationStateful_apply_decs_2203_r = PersonalizationStateful_applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
1212
1386
  }
1213
- var PersonalizationStateful_dec, PersonalizationStateful_dec1, PersonalizationStateful_dec2, PersonalizationStateful_dec3, _dec4, _dec5, PersonalizationStateful_initProto;
1214
- const PersonalizationStateful_logger = createScopedLogger('Personalization');
1387
+ var PersonalizationStateful_dec, PersonalizationStateful_dec1, PersonalizationStateful_dec2, PersonalizationStateful_dec3, _dec4, PersonalizationStateful_initProto;
1388
+ const PersonalizationStateful_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Personalization');
1389
+ const OFFLINE_QUEUE_MAX_EVENTS = 100;
1390
+ const resolvePersonalizationQueuePolicy = (policy)=>({
1391
+ maxEvents: toPositiveInt(policy?.maxEvents, OFFLINE_QUEUE_MAX_EVENTS),
1392
+ onDrop: policy?.onDrop,
1393
+ flushPolicy: resolveQueueFlushPolicy(policy?.flushPolicy)
1394
+ });
1215
1395
  PersonalizationStateful_dec = guardedBy('hasConsent', {
1216
1396
  onBlocked: 'onBlockedByConsent'
1217
1397
  }), PersonalizationStateful_dec1 = guardedBy('hasConsent', {
@@ -1220,9 +1400,7 @@ PersonalizationStateful_dec = guardedBy('hasConsent', {
1220
1400
  onBlocked: 'onBlockedByConsent'
1221
1401
  }), PersonalizationStateful_dec3 = guardedBy('hasConsent', {
1222
1402
  onBlocked: 'onBlockedByConsent'
1223
- }), _dec4 = guardedBy('isNotDuplicated', {
1224
- onBlocked: 'onBlockedByDuplication'
1225
- }), _dec5 = guardedBy('hasConsent', {
1403
+ }), _dec4 = guardedBy('hasConsent', {
1226
1404
  onBlocked: 'onBlockedByConsent'
1227
1405
  });
1228
1406
  class PersonalizationStateful extends personalization_PersonalizationBase {
@@ -1249,17 +1427,17 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1249
1427
  "track"
1250
1428
  ],
1251
1429
  [
1252
- [
1253
- _dec4,
1254
- _dec5
1255
- ],
1430
+ _dec4,
1256
1431
  2,
1257
1432
  "trackComponentView"
1258
1433
  ]
1259
1434
  ], []));
1260
1435
  }
1261
1436
  offlineQueue = (PersonalizationStateful_initProto(this), new Set());
1437
+ queuePolicy;
1438
+ flushRuntime;
1262
1439
  states = {
1440
+ blockedEventStream: toObservable(blockedEvent),
1263
1441
  eventStream: toObservable(signals_event),
1264
1442
  flags: toObservable(flags),
1265
1443
  profile: toObservable(signals_profile),
@@ -1274,7 +1452,17 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1274
1452
  config,
1275
1453
  interceptors
1276
1454
  });
1277
- const { defaults, getAnonymousId } = config ?? {};
1455
+ const { defaults, getAnonymousId, queuePolicy } = config ?? {};
1456
+ this.queuePolicy = resolvePersonalizationQueuePolicy(queuePolicy);
1457
+ this.flushRuntime = new QueueFlushRuntime({
1458
+ policy: this.queuePolicy.flushPolicy,
1459
+ onRetry: ()=>{
1460
+ this.flush();
1461
+ },
1462
+ onCallbackError: (callbackName, error)=>{
1463
+ PersonalizationStateful_logger.warn(`Personalization flush policy callback "${callbackName}" failed`, error);
1464
+ }
1465
+ });
1278
1466
  if (defaults) {
1279
1467
  const { changes: defaultChanges, personalizations: defaultPersonalizations, profile: defaultProfile } = defaults;
1280
1468
  batch(()=>{
@@ -1298,12 +1486,18 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1298
1486
  PersonalizationStateful_logger.info(`Personalization ${consent.value ? 'will' : 'will not'} take effect due to consent (${consent.value})`);
1299
1487
  });
1300
1488
  effect(()=>{
1301
- if (online.value) this.flush();
1489
+ if (!online.value) return;
1490
+ this.flushRuntime.clearScheduledRetry();
1491
+ this.flush({
1492
+ force: true
1493
+ });
1302
1494
  });
1303
1495
  }
1304
1496
  reset() {
1497
+ this.flushRuntime.reset();
1305
1498
  batch(()=>{
1306
1499
  signals_changes.value = void 0;
1500
+ blockedEvent.value = void 0;
1307
1501
  signals_event.value = void 0;
1308
1502
  signals_profile.value = void 0;
1309
1503
  signals_personalizations.value = void 0;
@@ -1312,6 +1506,9 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1312
1506
  getCustomFlag(name, changes = signals_changes.value) {
1313
1507
  return super.getCustomFlag(name, changes);
1314
1508
  }
1509
+ getCustomFlags(changes = signals_changes.value) {
1510
+ return super.getCustomFlags(changes);
1511
+ }
1315
1512
  personalizeEntry(entry, personalizations = signals_personalizations.value) {
1316
1513
  return super.personalizeEntry(entry, personalizations);
1317
1514
  }
@@ -1323,15 +1520,7 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1323
1520
  }
1324
1521
  onBlockedByConsent(name, payload) {
1325
1522
  PersonalizationStateful_logger.warn(`Event "${name}" was blocked due to lack of consent; payload: ${JSON.stringify(payload)}`);
1326
- }
1327
- isNotDuplicated(_name, payload) {
1328
- const [{ componentId: value }, duplicationScope] = payload;
1329
- const isDuplicated = this.duplicationDetector.isPresent(duplicationScope, value);
1330
- if (!isDuplicated) this.duplicationDetector.addValue(duplicationScope, value);
1331
- return !isDuplicated;
1332
- }
1333
- onBlockedByDuplication(_name, payload) {
1334
- PersonalizationStateful_logger.debug(`Duplicate "component view" event detected, skipping; payload: ${JSON.stringify(payload)}`);
1523
+ this.reportBlockedEvent('consent', 'personalization', name, payload);
1335
1524
  }
1336
1525
  async identify(payload) {
1337
1526
  PersonalizationStateful_logger.info('Sending "identify" event');
@@ -1353,26 +1542,89 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1353
1542
  const event = this.builder.buildTrack(payload);
1354
1543
  return await this.sendOrEnqueueEvent(event);
1355
1544
  }
1356
- async trackComponentView(payload, _duplicationScope = '') {
1545
+ async trackComponentView(payload) {
1357
1546
  PersonalizationStateful_logger.info(`Sending "track personalization" event for ${payload.componentId}`);
1358
1547
  const event = this.builder.buildComponentView(payload);
1359
1548
  return await this.sendOrEnqueueEvent(event);
1360
1549
  }
1361
1550
  async sendOrEnqueueEvent(event) {
1362
1551
  const intercepted = await this.interceptors.event.run(event);
1363
- const validEvent = __rspack_external__contentful_optimization_api_client_cba5a7ee.ExperienceEvent.parse(intercepted);
1552
+ const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ExperienceEvent, intercepted);
1364
1553
  signals_event.value = validEvent;
1365
1554
  if (online.value) return await this.upsertProfile([
1366
1555
  validEvent
1367
1556
  ]);
1368
1557
  PersonalizationStateful_logger.debug(`Queueing ${validEvent.type} event`, validEvent);
1369
- this.offlineQueue.add(validEvent);
1558
+ this.enqueueOfflineEvent(validEvent);
1559
+ }
1560
+ enqueueOfflineEvent(event) {
1561
+ let droppedEvents = [];
1562
+ if (this.offlineQueue.size >= this.queuePolicy.maxEvents) {
1563
+ const dropCount = this.offlineQueue.size - this.queuePolicy.maxEvents + 1;
1564
+ droppedEvents = this.dropOldestOfflineEvents(dropCount);
1565
+ if (droppedEvents.length > 0) PersonalizationStateful_logger.warn(`Dropped ${droppedEvents.length} oldest personalization offline event(s) due to queue limit (${this.queuePolicy.maxEvents})`);
1566
+ }
1567
+ this.offlineQueue.add(event);
1568
+ if (droppedEvents.length > 0) this.invokeQueueDropCallback({
1569
+ droppedCount: droppedEvents.length,
1570
+ droppedEvents,
1571
+ maxEvents: this.queuePolicy.maxEvents,
1572
+ queuedEvents: this.offlineQueue.size
1573
+ });
1370
1574
  }
1371
- async flush() {
1372
- if (0 === this.offlineQueue.size) return;
1575
+ dropOldestOfflineEvents(count) {
1576
+ const droppedEvents = [];
1577
+ for(let index = 0; index < count; index += 1){
1578
+ const oldestEvent = this.offlineQueue.values().next();
1579
+ if (oldestEvent.done) break;
1580
+ this.offlineQueue.delete(oldestEvent.value);
1581
+ droppedEvents.push(oldestEvent.value);
1582
+ }
1583
+ return droppedEvents;
1584
+ }
1585
+ invokeQueueDropCallback(context) {
1586
+ try {
1587
+ this.queuePolicy.onDrop?.(context);
1588
+ } catch (error) {
1589
+ PersonalizationStateful_logger.warn('Personalization offline queue drop callback failed', error);
1590
+ }
1591
+ }
1592
+ async flush(options = {}) {
1593
+ await this.flushOfflineQueue(options);
1594
+ }
1595
+ async flushOfflineQueue(options = {}) {
1596
+ const { force = false } = options;
1597
+ if (this.flushRuntime.shouldSkip({
1598
+ force,
1599
+ isOnline: !!online.value
1600
+ })) return;
1601
+ if (0 === this.offlineQueue.size) return void this.flushRuntime.clearScheduledRetry();
1373
1602
  PersonalizationStateful_logger.debug('Flushing offline event queue');
1374
- await this.upsertProfile(Array.from(this.offlineQueue));
1375
- this.offlineQueue.clear();
1603
+ const queuedEvents = Array.from(this.offlineQueue);
1604
+ this.flushRuntime.markFlushStarted();
1605
+ try {
1606
+ const sendSuccess = await this.tryUpsertQueuedEvents(queuedEvents);
1607
+ if (sendSuccess) {
1608
+ queuedEvents.forEach((event)=>{
1609
+ this.offlineQueue.delete(event);
1610
+ });
1611
+ this.flushRuntime.handleFlushSuccess();
1612
+ } else this.flushRuntime.handleFlushFailure({
1613
+ queuedBatches: this.offlineQueue.size > 0 ? 1 : 0,
1614
+ queuedEvents: this.offlineQueue.size
1615
+ });
1616
+ } finally{
1617
+ this.flushRuntime.markFlushFinished();
1618
+ }
1619
+ }
1620
+ async tryUpsertQueuedEvents(events) {
1621
+ try {
1622
+ await this.upsertProfile(events);
1623
+ return true;
1624
+ } catch (error) {
1625
+ PersonalizationStateful_logger.warn('Personalization offline queue flush request threw an error', error);
1626
+ return false;
1627
+ }
1376
1628
  }
1377
1629
  async upsertProfile(events) {
1378
1630
  const anonymousId = this.getAnonymousId();
@@ -1395,101 +1647,142 @@ class PersonalizationStateful extends personalization_PersonalizationBase {
1395
1647
  }
1396
1648
  }
1397
1649
  const personalization_PersonalizationStateful = PersonalizationStateful;
1398
- const PersonalizationStateless_logger = createScopedLogger('Personalization');
1650
+ const PersonalizationStateless_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Personalization');
1399
1651
  class PersonalizationStateless extends personalization_PersonalizationBase {
1400
1652
  async identify(payload) {
1401
1653
  PersonalizationStateless_logger.info('Sending "identify" event');
1402
1654
  const { profile, ...builderArgs } = payload;
1403
- const event = __rspack_external__contentful_optimization_api_client_cba5a7ee.IdentifyEvent.parse(this.builder.buildIdentify(builderArgs));
1655
+ const event = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.IdentifyEvent, this.builder.buildIdentify(builderArgs));
1404
1656
  return await this.upsertProfile(event, profile);
1405
1657
  }
1406
1658
  async page(payload) {
1407
1659
  PersonalizationStateless_logger.info('Sending "page" event');
1408
1660
  const { profile, ...builderArgs } = payload;
1409
- const event = __rspack_external__contentful_optimization_api_client_cba5a7ee.PageViewEvent.parse(this.builder.buildPageView(builderArgs));
1661
+ const event = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.PageViewEvent, this.builder.buildPageView(builderArgs));
1410
1662
  return await this.upsertProfile(event, profile);
1411
1663
  }
1412
1664
  async screen(payload) {
1413
1665
  PersonalizationStateless_logger.info(`Sending "screen" event for "${payload.name}"`);
1414
1666
  const { profile, ...builderArgs } = payload;
1415
- const event = __rspack_external__contentful_optimization_api_client_cba5a7ee.ScreenViewEvent.parse(this.builder.buildScreenView(builderArgs));
1667
+ const event = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ScreenViewEvent, this.builder.buildScreenView(builderArgs));
1416
1668
  return await this.upsertProfile(event, profile);
1417
1669
  }
1418
1670
  async track(payload) {
1419
1671
  PersonalizationStateless_logger.info(`Sending "track" event "${payload.event}"`);
1420
1672
  const { profile, ...builderArgs } = payload;
1421
- const event = __rspack_external__contentful_optimization_api_client_cba5a7ee.TrackEvent.parse(this.builder.buildTrack(builderArgs));
1673
+ const event = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.TrackEvent, this.builder.buildTrack(builderArgs));
1422
1674
  return await this.upsertProfile(event, profile);
1423
1675
  }
1424
1676
  async trackComponentView(payload) {
1425
1677
  PersonalizationStateless_logger.info('Sending "track personalization" event');
1426
1678
  const { profile, ...builderArgs } = payload;
1427
- const event = __rspack_external__contentful_optimization_api_client_cba5a7ee.ComponentViewEvent.parse(this.builder.buildComponentView(builderArgs));
1679
+ const event = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ComponentViewEvent, this.builder.buildComponentView(builderArgs));
1428
1680
  return await this.upsertProfile(event, profile);
1429
1681
  }
1430
1682
  async upsertProfile(event, profile) {
1431
1683
  const intercepted = await this.interceptors.event.run(event);
1684
+ const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ExperienceEvent, intercepted);
1432
1685
  const data = await this.api.experience.upsertProfile({
1433
1686
  profileId: profile?.id,
1434
1687
  events: [
1435
- intercepted
1688
+ validEvent
1436
1689
  ]
1437
1690
  });
1438
1691
  return data;
1439
1692
  }
1440
1693
  }
1441
1694
  const personalization_PersonalizationStateless = PersonalizationStateless;
1695
+ const splitScopedQueuePolicy = (config)=>{
1696
+ if (void 0 === config) return {
1697
+ apiConfig: void 0,
1698
+ queuePolicy: void 0
1699
+ };
1700
+ const { queuePolicy, ...apiConfig } = config;
1701
+ const resolvedApiConfig = Object.keys(apiConfig).length > 0 ? apiConfig : void 0;
1702
+ return {
1703
+ apiConfig: resolvedApiConfig,
1704
+ queuePolicy
1705
+ };
1706
+ };
1707
+ let statefulInstanceCounter = 0;
1442
1708
  class CoreStateful extends src_CoreBase {
1443
- analytics;
1444
- personalization;
1709
+ singletonOwner;
1710
+ destroyed = false;
1711
+ _analytics;
1712
+ _personalization;
1445
1713
  constructor(config){
1446
- super(config);
1447
- const { allowedEventTypes, defaults, getAnonymousId, preventedComponentEvents } = config;
1448
- if (defaults?.consent !== void 0) {
1449
- const { consent: defaultConsent } = defaults;
1450
- consent.value = defaultConsent;
1714
+ const { apiConfig: analyticsApiConfig, queuePolicy: analyticsRuntimeQueuePolicy } = splitScopedQueuePolicy(config.analytics);
1715
+ const { apiConfig: personalizationApiConfig, queuePolicy: personalizationRuntimeQueuePolicy } = splitScopedQueuePolicy(config.personalization);
1716
+ const baseConfig = {
1717
+ ...config,
1718
+ analytics: analyticsApiConfig,
1719
+ personalization: personalizationApiConfig
1720
+ };
1721
+ super(baseConfig);
1722
+ this.singletonOwner = `CoreStateful#${++statefulInstanceCounter}`;
1723
+ acquireStatefulRuntimeSingleton(this.singletonOwner);
1724
+ try {
1725
+ const { allowedEventTypes, defaults, getAnonymousId, onEventBlocked } = config;
1726
+ if (defaults?.consent !== void 0) {
1727
+ const { consent: defaultConsent } = defaults;
1728
+ consent.value = defaultConsent;
1729
+ }
1730
+ this._analytics = new analytics_AnalyticsStateful({
1731
+ api: this.api,
1732
+ builder: this.eventBuilder,
1733
+ config: {
1734
+ allowedEventTypes,
1735
+ queuePolicy: analyticsRuntimeQueuePolicy,
1736
+ onEventBlocked,
1737
+ defaults: {
1738
+ consent: defaults?.consent,
1739
+ profile: defaults?.profile
1740
+ }
1741
+ },
1742
+ interceptors: this.interceptors
1743
+ });
1744
+ this._personalization = new personalization_PersonalizationStateful({
1745
+ api: this.api,
1746
+ builder: this.eventBuilder,
1747
+ config: {
1748
+ allowedEventTypes,
1749
+ getAnonymousId,
1750
+ queuePolicy: personalizationRuntimeQueuePolicy,
1751
+ onEventBlocked,
1752
+ defaults: {
1753
+ consent: defaults?.consent,
1754
+ changes: defaults?.changes,
1755
+ profile: defaults?.profile,
1756
+ personalizations: defaults?.personalizations
1757
+ }
1758
+ },
1759
+ interceptors: this.interceptors
1760
+ });
1761
+ } catch (error) {
1762
+ releaseStatefulRuntimeSingleton(this.singletonOwner);
1763
+ throw error;
1451
1764
  }
1452
- this.analytics = new analytics_AnalyticsStateful({
1453
- api: this.api,
1454
- builder: this.eventBuilder,
1455
- config: {
1456
- allowedEventTypes,
1457
- preventedComponentEvents,
1458
- defaults: {
1459
- consent: defaults?.consent,
1460
- profile: defaults?.profile
1461
- }
1462
- },
1463
- interceptors: this.interceptors
1464
- });
1465
- this.personalization = new personalization_PersonalizationStateful({
1466
- api: this.api,
1467
- builder: this.eventBuilder,
1468
- config: {
1469
- allowedEventTypes,
1470
- getAnonymousId,
1471
- preventedComponentEvents,
1472
- defaults: {
1473
- consent: defaults?.consent,
1474
- changes: defaults?.changes,
1475
- profile: defaults?.profile,
1476
- personalizations: defaults?.personalizations
1477
- }
1478
- },
1479
- interceptors: this.interceptors
1480
- });
1765
+ }
1766
+ destroy() {
1767
+ if (this.destroyed) return;
1768
+ this.destroyed = true;
1769
+ releaseStatefulRuntimeSingleton(this.singletonOwner);
1481
1770
  }
1482
1771
  get states() {
1483
1772
  return {
1773
+ blockedEventStream: toObservable(blockedEvent),
1484
1774
  consent: toObservable(consent),
1485
1775
  eventStream: toObservable(signals_event),
1486
1776
  flags: toObservable(flags),
1487
1777
  personalizations: toObservable(signals_personalizations),
1778
+ previewPanelAttached: toObservable(previewPanelAttached),
1779
+ previewPanelOpen: toObservable(previewPanelOpen),
1488
1780
  profile: toObservable(signals_profile)
1489
1781
  };
1490
1782
  }
1491
1783
  reset() {
1492
1784
  batch(()=>{
1785
+ blockedEvent.value = void 0;
1493
1786
  signals_event.value = void 0;
1494
1787
  signals_changes.value = void 0;
1495
1788
  signals_profile.value = void 0;
@@ -1497,31 +1790,35 @@ class CoreStateful extends src_CoreBase {
1497
1790
  });
1498
1791
  }
1499
1792
  async flush() {
1500
- await this.analytics.flush();
1501
- await this.personalization.flush();
1793
+ await this._analytics.flush();
1794
+ await this._personalization.flush();
1502
1795
  }
1503
1796
  consent(accept) {
1504
1797
  consent.value = accept;
1505
1798
  }
1506
- online(isOnline) {
1799
+ get online() {
1800
+ return online.value ?? false;
1801
+ }
1802
+ set online(isOnline) {
1507
1803
  online.value = isOnline;
1508
1804
  }
1509
1805
  registerPreviewPanel(previewPanel) {
1510
- previewPanel.signals = signals;
1806
+ Reflect.set(previewPanel, PREVIEW_PANEL_SIGNALS_SYMBOL, signals);
1807
+ Reflect.set(previewPanel, PREVIEW_PANEL_SIGNAL_FNS_SYMBOL, signalFns);
1511
1808
  }
1512
1809
  }
1513
1810
  const src_CoreStateful = CoreStateful;
1514
1811
  class CoreStateless extends src_CoreBase {
1515
- analytics;
1516
- personalization;
1812
+ _analytics;
1813
+ _personalization;
1517
1814
  constructor(config){
1518
1815
  super(config);
1519
- this.analytics = new analytics_AnalyticsStateless({
1816
+ this._analytics = new analytics_AnalyticsStateless({
1520
1817
  api: this.api,
1521
1818
  builder: this.eventBuilder,
1522
1819
  interceptors: this.interceptors
1523
1820
  });
1524
- this.personalization = new personalization_PersonalizationStateless({
1821
+ this._personalization = new personalization_PersonalizationStateless({
1525
1822
  api: this.api,
1526
1823
  builder: this.eventBuilder,
1527
1824
  interceptors: this.interceptors
@@ -1529,7 +1826,8 @@ class CoreStateless extends src_CoreBase {
1529
1826
  }
1530
1827
  }
1531
1828
  const src_CoreStateless = CoreStateless;
1532
- export * from "@contentful/optimization-api-client";
1533
- export { ANONYMOUS_ID_COOKIE, ConsoleLogSink, InterceptorManager, Logger, OPTIMIZATION_CORE_SDK_VERSION, analytics_AnalyticsStateful as AnalyticsStateful, analytics_AnalyticsStateless as AnalyticsStateless, batch, createScopedLogger, effect, guardedBy, logger, personalization_PersonalizationStateful as PersonalizationStateful, personalization_PersonalizationStateless as PersonalizationStateless, resolvers_FlagsResolver as FlagsResolver, resolvers_MergeTagValueResolver as MergeTagValueResolver, resolvers_PersonalizedEntryResolver as PersonalizedEntryResolver, signals, src_CoreStateful as CoreStateful, src_CoreStateless as CoreStateless, src_LogSink as LogSink, value_presence_ValuePresence as ValuePresence };
1829
+ export { ANONYMOUS_ID_COOKIE, ANONYMOUS_ID_COOKIE_LEGACY, ANONYMOUS_ID_KEY, ANONYMOUS_ID_KEY_LEGACY, CHANGES_CACHE_KEY, CONSENT_KEY, DEBUG_FLAG_KEY, OPTIMIZATION_CORE_SDK_NAME, OPTIMIZATION_CORE_SDK_VERSION, PERSONALIZATIONS_CACHE_KEY, PROFILE_CACHE_KEY } from "./260.mjs";
1830
+ export { PREVIEW_PANEL_SIGNALS_SYMBOL, PREVIEW_PANEL_SIGNAL_FNS_SYMBOL } from "./632.mjs";
1831
+ export { InterceptorManager, analytics_AnalyticsStateful as AnalyticsStateful, analytics_AnalyticsStateless as AnalyticsStateless, batch, effect, guardedBy, personalization_PersonalizationBase as PersonalizationBase, personalization_PersonalizationStateful as PersonalizationStateful, personalization_PersonalizationStateless as PersonalizationStateless, resolvers_FlagsResolver as FlagsResolver, resolvers_MergeTagValueResolver as MergeTagValueResolver, resolvers_PersonalizedEntryResolver as PersonalizedEntryResolver, signalFns, signals, src_CoreStateful as CoreStateful, src_CoreStateless as CoreStateless };
1534
1832
 
1535
1833
  //# sourceMappingURL=index.mjs.map