@contentful/optimization-core 0.1.0-alpha8 → 0.1.0-alpha9

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 (147) 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/{global-constants.d.ts → constants.d.cts} +88 -67
  24. package/dist/{global-constants.js → constants.d.mts} +88 -69
  25. package/dist/constants.d.ts +88 -0
  26. package/dist/constants.mjs +1 -0
  27. package/dist/index.cjs +1833 -1706
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +774 -341
  30. package/dist/index.d.mts +774 -341
  31. package/dist/index.d.ts +2432 -15
  32. package/dist/index.mjs +617 -341
  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 +56 -8
  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 -144
  56. package/dist/CoreStateful.d.ts.map +0 -1
  57. package/dist/CoreStateful.js +0 -141
  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.map +0 -1
  84. package/dist/global-constants.js.map +0 -1
  85. package/dist/index.d.ts.map +0 -1
  86. package/dist/index.js +0 -15
  87. package/dist/index.js.map +0 -1
  88. package/dist/lib/decorators/guardedBy.d.ts +0 -113
  89. package/dist/lib/decorators/guardedBy.d.ts.map +0 -1
  90. package/dist/lib/decorators/guardedBy.js +0 -143
  91. package/dist/lib/decorators/guardedBy.js.map +0 -1
  92. package/dist/lib/decorators/index.d.ts +0 -2
  93. package/dist/lib/decorators/index.d.ts.map +0 -1
  94. package/dist/lib/decorators/index.js +0 -2
  95. package/dist/lib/decorators/index.js.map +0 -1
  96. package/dist/lib/interceptor/InterceptorManager.d.ts +0 -127
  97. package/dist/lib/interceptor/InterceptorManager.d.ts.map +0 -1
  98. package/dist/lib/interceptor/InterceptorManager.js +0 -125
  99. package/dist/lib/interceptor/InterceptorManager.js.map +0 -1
  100. package/dist/lib/interceptor/index.d.ts +0 -2
  101. package/dist/lib/interceptor/index.d.ts.map +0 -1
  102. package/dist/lib/interceptor/index.js +0 -2
  103. package/dist/lib/interceptor/index.js.map +0 -1
  104. package/dist/lib/value-presence/ValuePresence.d.ts +0 -123
  105. package/dist/lib/value-presence/ValuePresence.d.ts.map +0 -1
  106. package/dist/lib/value-presence/ValuePresence.js +0 -141
  107. package/dist/lib/value-presence/ValuePresence.js.map +0 -1
  108. package/dist/lib/value-presence/index.d.ts +0 -2
  109. package/dist/lib/value-presence/index.d.ts.map +0 -1
  110. package/dist/lib/value-presence/index.js +0 -2
  111. package/dist/lib/value-presence/index.js.map +0 -1
  112. package/dist/personalization/PersonalizationBase.d.ts +0 -184
  113. package/dist/personalization/PersonalizationBase.d.ts.map +0 -1
  114. package/dist/personalization/PersonalizationBase.js +0 -76
  115. package/dist/personalization/PersonalizationBase.js.map +0 -1
  116. package/dist/personalization/PersonalizationStateful.d.ts +0 -226
  117. package/dist/personalization/PersonalizationStateful.d.ts.map +0 -1
  118. package/dist/personalization/PersonalizationStateful.js +0 -297
  119. package/dist/personalization/PersonalizationStateful.js.map +0 -1
  120. package/dist/personalization/PersonalizationStateless.d.ts +0 -74
  121. package/dist/personalization/PersonalizationStateless.d.ts.map +0 -1
  122. package/dist/personalization/PersonalizationStateless.js +0 -98
  123. package/dist/personalization/PersonalizationStateless.js.map +0 -1
  124. package/dist/personalization/index.d.ts +0 -6
  125. package/dist/personalization/index.d.ts.map +0 -1
  126. package/dist/personalization/index.js +0 -6
  127. package/dist/personalization/index.js.map +0 -1
  128. package/dist/personalization/resolvers/FlagsResolver.d.ts +0 -35
  129. package/dist/personalization/resolvers/FlagsResolver.d.ts.map +0 -1
  130. package/dist/personalization/resolvers/FlagsResolver.js +0 -47
  131. package/dist/personalization/resolvers/FlagsResolver.js.map +0 -1
  132. package/dist/personalization/resolvers/MergeTagValueResolver.d.ts +0 -74
  133. package/dist/personalization/resolvers/MergeTagValueResolver.d.ts.map +0 -1
  134. package/dist/personalization/resolvers/MergeTagValueResolver.js +0 -109
  135. package/dist/personalization/resolvers/MergeTagValueResolver.js.map +0 -1
  136. package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts +0 -142
  137. package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts.map +0 -1
  138. package/dist/personalization/resolvers/PersonalizedEntryResolver.js +0 -196
  139. package/dist/personalization/resolvers/PersonalizedEntryResolver.js.map +0 -1
  140. package/dist/personalization/resolvers/index.d.ts +0 -7
  141. package/dist/personalization/resolvers/index.d.ts.map +0 -1
  142. package/dist/personalization/resolvers/index.js +0 -7
  143. package/dist/personalization/resolvers/index.js.map +0 -1
  144. package/dist/signals.d.ts +0 -42
  145. package/dist/signals.d.ts.map +0 -1
  146. package/dist/signals.js +0 -36
  147. package/dist/signals.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,45 +1,52 @@
1
+ /**
2
+ * Optimization Core SDK — platform-agnostic personalization and analytics.
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+
1
7
  import { ApiClient } from '@contentful/optimization-api-client';
2
8
  import { ApiClientConfig } from '@contentful/optimization-api-client';
3
9
  import { batch } from '@preact/signals-core';
4
10
  import type { ChainModifiers } from 'contentful';
5
- import { ChangeArray } from '@contentful/optimization-api-client';
11
+ import { ChangeArray } from '@contentful/optimization-api-client/api-schemas';
12
+ import { ComponentClickBuilderArgs } from '@contentful/optimization-api-client';
13
+ import { ComponentHoverBuilderArgs } from '@contentful/optimization-api-client';
6
14
  import { ComponentViewBuilderArgs } from '@contentful/optimization-api-client';
7
15
  import { computed } from '@preact/signals-core';
8
16
  import { effect } from '@preact/signals-core';
9
17
  import type { Entry } from 'contentful';
10
18
  import { EntryReplacementVariant } from '@contentful/optimization-api-schemas';
11
- import { EntryReplacementVariant as EntryReplacementVariant_2 } from '@contentful/optimization-api-client';
19
+ import { EntryReplacementVariant as EntryReplacementVariant_2 } from '@contentful/optimization-api-client/api-schemas';
12
20
  import type { EntrySkeletonType } from 'contentful';
13
21
  import { EventBuilder } from '@contentful/optimization-api-client';
14
22
  import { EventBuilderConfig } from '@contentful/optimization-api-client';
15
23
  import { ExperienceApiClientConfig } from '@contentful/optimization-api-client';
16
- import { ExperienceEvent } from '@contentful/optimization-api-client';
17
- import type { ExperienceEventType } from '@contentful/optimization-api-client';
18
- import { Flags } from '@contentful/optimization-api-client';
19
- import { Flags as Flags_2 } from '@contentful/optimization-api-schemas';
24
+ import { ExperienceEvent } from '@contentful/optimization-api-client/api-schemas';
25
+ import { ExperienceEventArray } from '@contentful/optimization-api-client/api-schemas';
26
+ import type { ExperienceEventType } from '@contentful/optimization-api-client/api-schemas';
27
+ import { Flags } from '@contentful/optimization-api-client/api-schemas';
20
28
  import { GlobalApiConfigProperties } from '@contentful/optimization-api-client';
21
29
  import { IdentifyBuilderArgs } from '@contentful/optimization-api-client';
22
30
  import { InsightsApiClientConfig } from '@contentful/optimization-api-client';
23
- import { InsightsEvent } from '@contentful/optimization-api-client';
24
- import type { InsightsEventType } from '@contentful/optimization-api-client';
25
- import { Json } from '@contentful/optimization-api-client';
31
+ import { InsightsEvent } from '@contentful/optimization-api-client/api-schemas';
32
+ import type { InsightsEventType } from '@contentful/optimization-api-client/api-schemas';
33
+ import { Json } from '@contentful/optimization-api-client/api-schemas';
26
34
  import type { LocaleCode } from 'contentful';
27
- import type { LogEvent } from 'diary';
28
- import type { LogLevels } from 'diary';
29
- import { MergeTagEntry } from '@contentful/optimization-api-client';
30
- import { OptimizationData } from '@contentful/optimization-api-client';
35
+ import type { LogLevels } from '@contentful/optimization-api-client/logger';
36
+ import { MergeTagEntry } from '@contentful/optimization-api-client/api-schemas';
37
+ import { OptimizationData } from '@contentful/optimization-api-client/api-schemas';
31
38
  import { PageViewBuilderArgs } from '@contentful/optimization-api-client';
32
- import { PartialProfile } from '@contentful/optimization-api-client';
39
+ import { PartialProfile } from '@contentful/optimization-api-client/api-schemas';
33
40
  import { PersonalizationEntry } from '@contentful/optimization-api-schemas';
34
- import { PersonalizationEntry as PersonalizationEntry_2 } from '@contentful/optimization-api-client';
41
+ import { PersonalizationEntry as PersonalizationEntry_2 } from '@contentful/optimization-api-client/api-schemas';
35
42
  import { PersonalizedEntry } from '@contentful/optimization-api-schemas';
36
- import { PersonalizedEntry as PersonalizedEntry_2 } from '@contentful/optimization-api-client';
37
- import { Profile } from '@contentful/optimization-api-client';
43
+ import { PersonalizedEntry as PersonalizedEntry_2 } from '@contentful/optimization-api-client/api-schemas';
44
+ import { Profile } from '@contentful/optimization-api-client/api-schemas';
38
45
  import { ReadonlySignal } from '@preact/signals-core';
39
46
  import { ScreenViewBuilderArgs } from '@contentful/optimization-api-client';
40
- import { SelectedPersonalization } from '@contentful/optimization-api-client';
47
+ import { SelectedPersonalization } from '@contentful/optimization-api-client/api-schemas';
41
48
  import { SelectedPersonalization as SelectedPersonalization_2 } from '@contentful/optimization-api-schemas';
42
- import { SelectedPersonalizationArray } from '@contentful/optimization-api-client';
49
+ import { SelectedPersonalizationArray } from '@contentful/optimization-api-client/api-schemas';
43
50
  import { Signal } from '@preact/signals-core';
44
51
  import { TrackBuilderArgs } from '@contentful/optimization-api-client';
45
52
  import { untracked } from '@preact/signals-core';
@@ -57,23 +64,30 @@ declare abstract class AnalyticsBase extends ProductBase {
57
64
  * Track a UI component view event.
58
65
  *
59
66
  * @param payload - Component view builder arguments.
60
- * @param duplicationScope - Optional string used to scope duplication used in Stateful
61
- * implementations.
62
- * @privateRemarks
63
- * Duplication prevention should be handled in Stateful implementations
67
+ * @returns A promise that resolves when processing is complete (or `void`).
68
+ */
69
+ abstract trackComponentView(payload: ComponentViewBuilderArgs): Promise<void> | void;
70
+ /**
71
+ * Track a UI component click event.
72
+ *
73
+ * @param payload - Component click builder arguments.
74
+ * @returns A promise that resolves when processing is complete (or `void`).
75
+ */
76
+ abstract trackComponentClick(payload: ComponentClickBuilderArgs): Promise<void> | void;
77
+ /**
78
+ * Track a UI component hover event.
79
+ *
80
+ * @param payload - Component hover builder arguments.
81
+ * @returns A promise that resolves when processing is complete (or `void`).
64
82
  */
65
- abstract trackComponentView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void> | void;
83
+ abstract trackComponentHover(payload: ComponentHoverBuilderArgs): Promise<void> | void;
66
84
  /**
67
85
  * Track a flag (feature) view event.
68
86
  *
69
87
  * @param payload - Flag view builder arguments.
70
- * @param duplicationScope - Optional string used to scope duplication used in Stateful
71
- * implementations.
72
88
  * @returns A promise that resolves when processing is complete (or `void`).
73
- * @privateRemarks
74
- * Duplication prevention should be handled in Stateful implementations
75
89
  */
76
- abstract trackFlagView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void> | void;
90
+ abstract trackFlagView(payload: ComponentViewBuilderArgs): Promise<void> | void;
77
91
  }
78
92
 
79
93
  /**
@@ -86,6 +100,11 @@ export declare interface AnalyticsProductConfig extends ProductConfig {
86
100
  * Default signal values applied on initialization.
87
101
  */
88
102
  defaults?: AnalyticsProductConfigDefaults;
103
+ /**
104
+ * Policy that controls stateful queue flush retries, backoff, and circuit
105
+ * behavior after repeated failures.
106
+ */
107
+ queuePolicy?: QueueFlushPolicy;
89
108
  }
90
109
 
91
110
  /**
@@ -104,30 +123,51 @@ export declare interface AnalyticsProductConfigDefaults {
104
123
  * Analytics implementation that maintains local state (consent, profile) and
105
124
  * queues events until flushed or the queue reaches a maximum size.
106
125
  *
126
+ * @remarks
127
+ * Repeated flush failures are managed by the configured {@link QueueFlushPolicy}
128
+ * using bounded backoff and a temporary circuit-open window.
129
+ *
107
130
  * @public
108
131
  */
109
132
  export declare class AnalyticsStateful extends AnalyticsBase implements ConsentGuard {
110
- /** Inmemory queue keyed by profile. */
133
+ /** In-memory queue keyed by stable profile identifier. */
111
134
  private readonly queue;
135
+ /** Shared queue flush retry runtime state machine. */
136
+ private readonly flushRuntime;
112
137
  /** Exposed observable state references. */
113
138
  readonly states: AnalyticsStates;
114
139
  /**
115
140
  * Create a new stateful analytics instance.
116
141
  *
117
142
  * @param options - Options to configure the analytics product for stateful environments.
143
+ * @example
144
+ * ```ts
145
+ * const analytics = new AnalyticsStateful({ api, builder, config: { defaults: { consent: true } }, interceptors })
146
+ * ```
118
147
  */
119
148
  constructor(options: AnalyticsStatefulOptions);
120
149
  /**
121
150
  * Reset analytics‑related signals and the last emitted event.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * analytics.reset()
155
+ * ```
122
156
  */
123
157
  reset(): void;
124
158
  /**
125
159
  * Determine whether the named operation is permitted based on consent and
126
160
  * allowed event type configuration.
127
161
  *
128
- * @param name - The method name; `'trackComponentView'` is normalized
129
- * to `'component'` for allow‑list checks.
162
+ * @param name - The method name; component view/flag methods are normalized
163
+ * to `'component'`, component click methods are normalized to `'component_click'`,
164
+ * and component hover methods are normalized to `'component_hover'` for
165
+ * allow‑list checks.
130
166
  * @returns `true` if the operation is permitted; otherwise `false`.
167
+ * @example
168
+ * ```ts
169
+ * if (analytics.hasConsent('track')) { ... }
170
+ * ```
131
171
  */
132
172
  hasConsent(name: string): boolean;
133
173
  /**
@@ -135,40 +175,56 @@ export declare class AnalyticsStateful extends AnalyticsBase implements ConsentG
135
175
  *
136
176
  * @param name - The blocked operation name.
137
177
  * @param payload - The original arguments supplied to the operation.
178
+ * @example
179
+ * ```ts
180
+ * analytics.onBlockedByConsent('track', [payload])
181
+ * ```
138
182
  */
139
- onBlockedByConsent(name: string, payload: unknown[]): void;
183
+ onBlockedByConsent(name: string, payload: readonly unknown[]): void;
140
184
  /**
141
- * Guard used to suppress duplicate component/flag view events based on a
142
- * duplication key and the component identifier.
185
+ * Queue a component view event for the active profile.
143
186
  *
144
- * @param _name - The operation name (unused).
145
- * @param payload - Tuple of [builderArgs, duplicationScope].
146
- * @returns `true` if the event is NOT a duplicate and should proceed.
187
+ * @param payload - Component view builder arguments.
188
+ * @returns A promise that resolves when the event has been queued.
189
+ * @example
190
+ * ```ts
191
+ * await analytics.trackComponentView({ componentId: 'hero-banner' })
192
+ * ```
147
193
  */
148
- isNotDuplicated(_name: string, payload: [ComponentViewBuilderArgs, string]): boolean;
194
+ trackComponentView(payload: ComponentViewBuilderArgs): Promise<void>;
149
195
  /**
150
- * Hook invoked when an operation is blocked by the duplication guard.
196
+ * Queue a component click event for the active profile.
151
197
  *
152
- * @param name - The blocked operation name.
153
- * @param payload - The original arguments supplied to the operation.
198
+ * @param payload - Component click builder arguments.
199
+ * @returns A promise that resolves when the event has been queued.
200
+ * @example
201
+ * ```ts
202
+ * await analytics.trackComponentClick({ componentId: 'hero-banner' })
203
+ * ```
154
204
  */
155
- onBlockedByDuplication(name: string, payload: unknown[]): void;
205
+ trackComponentClick(payload: ComponentClickBuilderArgs): Promise<void>;
156
206
  /**
157
- * Queue a component view event for the active profile.
207
+ * Queue a component hover event for the active profile.
158
208
  *
159
- * @param payload - Component view builder arguments.
160
- * @param _duplicationScope - Optional string used to scope duplication (used
161
- * by guards); an empty string `''` is converted to the `undefined` scope
209
+ * @param payload - Component hover builder arguments.
210
+ * @returns A promise that resolves when the event has been queued.
211
+ * @example
212
+ * ```ts
213
+ * await analytics.trackComponentHover({ componentId: 'hero-banner' })
214
+ * ```
162
215
  */
163
- trackComponentView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<void>;
216
+ trackComponentHover(payload: ComponentHoverBuilderArgs): Promise<void>;
164
217
  /**
165
218
  * Queue a flag view event for the active profile.
166
219
  *
167
220
  * @param payload - Flag view builder arguments.
168
- * @param _duplicationScope - Optional string used to scope duplication (used
169
- * by guards); an empty string `''` is converted to the `undefined` scope
221
+ * @returns A promise that resolves when the event has been queued.
222
+ * @example
223
+ * ```ts
224
+ * await analytics.trackFlagView({ componentId: 'feature-flag-123' })
225
+ * ```
170
226
  */
171
- trackFlagView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<void>;
227
+ trackFlagView(payload: ComponentViewBuilderArgs): Promise<void>;
172
228
  /**
173
229
  * Intercept, validate, and place an event into the profile‑scoped queue; then
174
230
  * trigger a size‑based flush if necessary.
@@ -183,10 +239,48 @@ export declare class AnalyticsStateful extends AnalyticsBase implements ConsentG
183
239
  private flushMaxEvents;
184
240
  /**
185
241
  * Send all queued events grouped by profile and clear the queue.
242
+ *
243
+ * @param options - Optional flush controls.
244
+ * @param options.force - When `true`, bypass offline/backoff/circuit gates and attempt immediately.
186
245
  * @remarks Only under rare circumstances should there be more than one
187
246
  * profile in a stateful application.
247
+ * @example
248
+ * ```ts
249
+ * await analytics.flush()
250
+ * ```
251
+ */
252
+ flush(options?: {
253
+ force?: boolean;
254
+ }): Promise<void>;
255
+ /**
256
+ * Apply default stateful analytics values when provided.
257
+ *
258
+ * @param defaults - Optional defaults for analytics state.
259
+ */
260
+ private applyDefaults;
261
+ /**
262
+ * Initialize reactive effects for consent/profile logging and online flushes.
263
+ */
264
+ private initializeEffects;
265
+ /**
266
+ * Build batch payloads grouped by profile from the in-memory queue.
267
+ *
268
+ * @returns Grouped batch payloads.
269
+ */
270
+ private createBatches;
271
+ /**
272
+ * Attempt to send queued batches to the Insights API.
273
+ *
274
+ * @param batches - Batches to send.
275
+ * @returns `true` when send succeeds; otherwise `false`.
276
+ */
277
+ private trySendBatches;
278
+ /**
279
+ * Compute the total number of queued events across all profiles.
280
+ *
281
+ * @returns Total queued event count.
188
282
  */
189
- flush(): Promise<void>;
283
+ private getQueuedEventCount;
190
284
  }
191
285
 
192
286
  /**
@@ -210,21 +304,53 @@ export declare class AnalyticsStateless extends AnalyticsBase {
210
304
  /**
211
305
  * Build, intercept, validate, and send a component view event.
212
306
  *
213
- * @param args - {@link TrackViewArgs} used to build the event. Includes an
307
+ * @param args - {@link TrackComponentViewArgs} used to build the event. Includes an
308
+ * optional partial profile.
309
+ * @returns A promise that resolves once the batch has been sent.
310
+ * @example
311
+ * ```ts
312
+ * await analytics.trackComponentView({ componentId: 'hero-banner', profile: { id: 'user-1' } })
313
+ * ```
314
+ */
315
+ trackComponentView(args: TrackComponentViewArgs): Promise<void>;
316
+ /**
317
+ * Build, intercept, validate, and send a component click event.
318
+ *
319
+ * @param args - {@link TrackComponentClickArgs} used to build the event. Includes an
320
+ * optional partial profile.
321
+ * @returns A promise that resolves once the batch has been sent.
322
+ * @example
323
+ * ```ts
324
+ * await analytics.trackComponentClick({ componentId: 'hero-banner', profile: { id: 'user-1' } })
325
+ * ```
326
+ */
327
+ trackComponentClick(args: TrackComponentClickArgs): Promise<void>;
328
+ /**
329
+ * Build, intercept, validate, and send a component hover event.
330
+ *
331
+ * @param args - {@link TrackComponentHoverArgs} used to build the event. Includes an
214
332
  * optional partial profile.
215
333
  * @returns A promise that resolves once the batch has been sent.
334
+ * @example
335
+ * ```ts
336
+ * await analytics.trackComponentHover({ componentId: 'hero-banner', profile: { id: 'user-1' } })
337
+ * ```
216
338
  */
217
- trackComponentView(args: TrackViewArgs): Promise<void>;
339
+ trackComponentHover(args: TrackComponentHoverArgs): Promise<void>;
218
340
  /**
219
341
  * Build, intercept, validate, and send a flag view event.
220
342
  *
221
- * @param args - {@link TrackViewArgs} used to build the event. Includes an
343
+ * @param args - {@link TrackComponentViewArgs} used to build the event. Includes an
222
344
  * optional partial profile.
223
345
  * @returns A promise that resolves once the batch has been sent.
346
+ * @example
347
+ * ```ts
348
+ * await analytics.trackFlagView({ componentId: 'feature-flag-123' })
349
+ * ```
224
350
  */
225
- trackFlagView(args: TrackViewArgs): Promise<void>;
351
+ trackFlagView(args: TrackComponentViewArgs): Promise<void>;
226
352
  /**
227
- * Send a single {@link InsightsEvent} wrapped in a one‑item batch.
353
+ * Send a single {@link AnalyticsEvent} wrapped in a one‑item batch.
228
354
  *
229
355
  * @param event - The event to send.
230
356
  * @param profile - Optional partial profile to attach to the batch.
@@ -240,6 +366,8 @@ export declare class AnalyticsStateless extends AnalyticsBase {
240
366
  * @public
241
367
  */
242
368
  export declare interface AnalyticsStates {
369
+ /** Observable stream of the latest blocked event payload (or `undefined`). */
370
+ blockedEventStream: Observable<BlockedEvent | undefined>;
243
371
  /** Observable stream of the latest {@link AnalyticsEvent} or {@link PersonalizationEvent} (or `undefined`). */
244
372
  eventStream: Observable<InsightsEvent | ExperienceEvent | undefined>;
245
373
  /** Observable stream of the active {@link Profile} (or `undefined`). */
@@ -257,7 +385,7 @@ export declare interface AnalyticsStates {
257
385
  *
258
386
  * @example
259
387
  * ```ts
260
- * import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core'
388
+ * import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core/constants'
261
389
  * const profileId = request.cookies[ANONYMOUS_ID_COOKIE]
262
390
  * ```
263
391
  */
@@ -286,6 +414,38 @@ export declare const ANONYMOUS_ID_KEY_LEGACY = "__nt_anonymous_id__";
286
414
 
287
415
  export { batch }
288
416
 
417
+ /**
418
+ * Payload emitted when event processing is blocked.
419
+ *
420
+ * @public
421
+ */
422
+ export declare interface BlockedEvent {
423
+ /** Why the event was blocked. */
424
+ reason: BlockedEventReason;
425
+ /** Product that blocked the event. */
426
+ product: BlockedEventProduct;
427
+ /** Method name that was blocked. */
428
+ method: string;
429
+ /** Original arguments passed to the blocked method call. */
430
+ args: readonly unknown[];
431
+ }
432
+
433
+ declare const blockedEvent: Signal<BlockedEvent | undefined>;
434
+
435
+ /**
436
+ * Product that blocked the event.
437
+ *
438
+ * @public
439
+ */
440
+ export declare type BlockedEventProduct = 'analytics' | 'personalization';
441
+
442
+ /**
443
+ * Reasons why an event was blocked before being sent.
444
+ *
445
+ * @public
446
+ */
447
+ export declare type BlockedEventReason = 'consent';
448
+
289
449
  /**
290
450
  * A callback invoked when a method call is blocked by {@link guardedBy}.
291
451
  *
@@ -360,29 +520,23 @@ declare interface ConsentGuard {
360
520
  onBlockedByConsent: (name: string, args: unknown[]) => void;
361
521
  }
362
522
 
363
- export declare class ConsoleLogSink extends LogSink {
364
- name: string;
365
- readonly verbosity: LogLevels;
366
- constructor(verbosity?: LogLevels);
367
- ingest(event: LogEvent): void;
368
- }
369
-
370
523
  /**
371
524
  * Internal base that wires the API client, event builder, and logging.
372
525
  *
373
526
  * @internal
374
527
  */
375
- declare abstract class CoreBase {
528
+ declare abstract class CoreBase implements ResolverMethods {
376
529
  /** Product implementation for analytics. */
377
- abstract readonly analytics: AnalyticsBase;
530
+ protected abstract _analytics: AnalyticsBase;
378
531
  /** Product implementation for personalization. */
379
- abstract readonly personalization: PersonalizationBase;
532
+ protected abstract _personalization: PersonalizationBase;
380
533
  /** Shared Optimization API client instance. */
381
534
  readonly api: ApiClient;
382
535
  /** Shared event builder instance. */
383
536
  readonly eventBuilder: EventBuilder;
384
537
  /** Resolved core configuration (minus any name metadata). */
385
538
  readonly config: Omit<CoreConfig, 'name'>;
539
+ /** Lifecycle interceptors for events and state updates. */
386
540
  readonly interceptors: LifecycleInterceptors;
387
541
  /**
388
542
  * Create the core with API client and logging preconfigured.
@@ -394,16 +548,52 @@ declare abstract class CoreBase {
394
548
  * ```
395
549
  */
396
550
  constructor(config: CoreConfig);
551
+ /**
552
+ * Static {@link FlagsResolver | resolver} for evaluating personalized
553
+ * custom flags.
554
+ */
555
+ get flagsResolver(): typeof FlagsResolver;
556
+ /**
557
+ * Static {@link MergeTagValueResolver | resolver} that returns values
558
+ * sourced from a user profile based on a Contentful Merge Tag entry.
559
+ */
560
+ get mergeTagValueResolver(): typeof MergeTagValueResolver;
561
+ /**
562
+ * Static {@link PersonalizedEntryResolver | resolver } for personalized
563
+ * Contentful entries (e.g., entry variants targeted to a profile audience).
564
+ *
565
+ * @remarks
566
+ * Used by higher-level personalization flows to materialize entry content
567
+ * prior to event emission.
568
+ */
569
+ get personalizedEntryResolver(): typeof PersonalizedEntryResolver;
397
570
  /**
398
571
  * Get the value of a custom flag derived from a set of optimization changes.
399
572
  *
400
573
  * @param name - The flag key to resolve.
401
- * @param changes - Optional change list to resolve from
574
+ * @param changes - Optional change list to resolve from.
402
575
  * @returns The resolved JSON value for the flag if available.
403
576
  * @remarks
404
577
  * This is a convenience wrapper around personalization’s flag resolution.
578
+ * @example
579
+ * ```ts
580
+ * const darkMode = core.getCustomFlag('dark-mode', data.changes)
581
+ * ```
405
582
  */
406
583
  getCustomFlag(name: string, changes?: ChangeArray): Json;
584
+ /**
585
+ * Get all resolved custom flags derived from a set of optimization changes.
586
+ *
587
+ * @param changes - Optional change list to resolve from.
588
+ * @returns The resolved custom flag map.
589
+ * @remarks
590
+ * This is a convenience wrapper around personalization’s flag resolution.
591
+ * @example
592
+ * ```ts
593
+ * const flags = core.getCustomFlags(data.changes)
594
+ * ```
595
+ */
596
+ getCustomFlags(changes?: ChangeArray): Flags;
407
597
  /**
408
598
  * Resolve a Contentful entry to the appropriate personalized variant (or
409
599
  * return the baseline entry if no matching variant is selected).
@@ -415,6 +605,10 @@ declare abstract class CoreBase {
415
605
  * @param personalizations - Optional selection array for the current profile.
416
606
  * @returns {@link ResolvedData} containing the resolved entry and
417
607
  * personalization metadata (if any).
608
+ * @example
609
+ * ```ts
610
+ * const { entry, personalization } = core.personalizeEntry(baselineEntry, data.personalizations)
611
+ * ```
418
612
  */
419
613
  personalizeEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = LocaleCode>(entry: Entry<S, M, L>, personalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
420
614
  /**
@@ -423,13 +617,21 @@ declare abstract class CoreBase {
423
617
  * @param embeddedEntryNodeTarget - The merge-tag entry node to resolve.
424
618
  * @param profile - Optional profile used for value lookup.
425
619
  * @returns The resolved value (typically a string) or `undefined` if not found.
620
+ * @example
621
+ * ```ts
622
+ * const name = core.getMergeTagValue(mergeTagNode, profile)
623
+ * ```
426
624
  */
427
- getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile): unknown;
625
+ getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile): string | undefined;
428
626
  /**
429
627
  * Convenience wrapper for sending an `identify` event via personalization.
430
628
  *
431
629
  * @param payload - Identify builder arguments.
432
630
  * @returns The resulting {@link OptimizationData} for the identified user.
631
+ * @example
632
+ * ```ts
633
+ * const data = await core.identify({ userId: 'user-123', traits: { plan: 'pro' } })
634
+ * ```
433
635
  */
434
636
  identify(payload: IdentifyBuilderArgs & {
435
637
  profile?: PartialProfile;
@@ -439,6 +641,10 @@ declare abstract class CoreBase {
439
641
  *
440
642
  * @param payload - Page view builder arguments.
441
643
  * @returns The evaluated {@link OptimizationData} for this page view.
644
+ * @example
645
+ * ```ts
646
+ * const data = await core.page({ properties: { title: 'Home' } })
647
+ * ```
442
648
  */
443
649
  page(payload: PageViewBuilderArgs & {
444
650
  profile?: PartialProfile;
@@ -448,6 +654,10 @@ declare abstract class CoreBase {
448
654
  *
449
655
  * @param payload - Screen view builder arguments.
450
656
  * @returns The evaluated {@link OptimizationData} for this screen view.
657
+ * @example
658
+ * ```ts
659
+ * const data = await core.screen({ name: 'HomeScreen' })
660
+ * ```
451
661
  */
452
662
  screen(payload: ScreenViewBuilderArgs & {
453
663
  profile?: PartialProfile;
@@ -457,6 +667,10 @@ declare abstract class CoreBase {
457
667
  *
458
668
  * @param payload - Track builder arguments.
459
669
  * @returns The evaluated {@link OptimizationData} for this event.
670
+ * @example
671
+ * ```ts
672
+ * const data = await core.track({ event: 'button_click', properties: { label: 'Buy' } })
673
+ * ```
460
674
  */
461
675
  track(payload: TrackBuilderArgs & {
462
676
  profile?: PartialProfile;
@@ -467,25 +681,51 @@ declare abstract class CoreBase {
467
681
  * @param payload - Component view builder arguments. When `payload.sticky` is
468
682
  * `true`, the event will also be sent via personalization as a sticky
469
683
  * component view.
470
- * @param duplicationScope - Optional string used to scope duplication used in Stateful
471
- * implementations
472
684
  * @returns A promise that resolves when all delegated calls complete.
473
685
  * @remarks
474
686
  * The sticky behavior is delegated to personalization; analytics is always
475
687
  * invoked regardless of `sticky`.
688
+ * @example
689
+ * ```ts
690
+ * await core.trackComponentView({ componentId: 'hero-banner', sticky: true })
691
+ * ```
476
692
  */
477
693
  trackComponentView(payload: ComponentViewBuilderArgs & {
478
694
  profile?: PartialProfile;
479
- }, duplicationScope?: string): Promise<OptimizationData | undefined>;
695
+ }): Promise<OptimizationData | undefined>;
696
+ /**
697
+ * Track a component click via analytics.
698
+ *
699
+ * @param payload - Component click builder arguments.
700
+ * @returns A promise that resolves when processing completes.
701
+ * @example
702
+ * ```ts
703
+ * await core.trackComponentClick({ componentId: 'hero-banner' })
704
+ * ```
705
+ */
706
+ trackComponentClick(payload: ComponentClickBuilderArgs): Promise<void>;
707
+ /**
708
+ * Track a component hover via analytics.
709
+ *
710
+ * @param payload - Component hover builder arguments.
711
+ * @returns A promise that resolves when processing completes.
712
+ * @example
713
+ * ```ts
714
+ * await core.trackComponentHover({ componentId: 'hero-banner' })
715
+ * ```
716
+ */
717
+ trackComponentHover(payload: ComponentHoverBuilderArgs): Promise<void>;
480
718
  /**
481
719
  * Track a feature flag view via analytics.
482
720
  *
483
721
  * @param payload - Component view builder arguments used to build the flag view event.
484
- * @param duplicationScope - Optional string used to scope duplication used in Stateful
485
- * implementations
486
722
  * @returns A promise that resolves when processing completes.
723
+ * @example
724
+ * ```ts
725
+ * await core.trackFlagView({ componentId: 'feature-flag-123' })
726
+ * ```
487
727
  */
488
- trackFlagView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void>;
728
+ trackFlagView(payload: ComponentViewBuilderArgs): Promise<void>;
489
729
  }
490
730
 
491
731
  /**
@@ -528,18 +768,22 @@ declare abstract class CoreBase {
528
768
 
529
769
  /**
530
770
  * Core runtime that constructs stateful product instances and exposes shared
531
- * states, including consent and the event stream.
771
+ * states, including consent, blocked events, and the event stream.
532
772
  *
533
- * @public
534
773
  * @remarks
774
+ * Extends {@link CoreBase} with stateful capabilities, including
775
+ * consent management via {@link ConsentController}.
535
776
  * @see {@link CoreBase}
536
777
  * @see {@link ConsentController}
778
+ * @public
537
779
  */
538
780
  export declare class CoreStateful extends CoreBase implements ConsentController {
781
+ private readonly singletonOwner;
782
+ private destroyed;
539
783
  /** Stateful analytics product. */
540
- readonly analytics: AnalyticsStateful;
784
+ protected _analytics: AnalyticsStateful;
541
785
  /** Stateful personalization product. */
542
- readonly personalization: PersonalizationStateful;
786
+ protected _personalization: PersonalizationStateful;
543
787
  /**
544
788
  * Create a stateful core with optional default consent and product defaults.
545
789
  *
@@ -555,16 +799,30 @@ declare abstract class CoreBase {
555
799
  * ```
556
800
  */
557
801
  constructor(config: CoreStatefulConfig);
802
+ /**
803
+ * Release singleton ownership for stateful runtime usage.
804
+ *
805
+ * @remarks
806
+ * This method is idempotent and should be called when a stateful SDK instance
807
+ * is no longer needed (e.g. tests, hot reload, explicit teardown).
808
+ */
809
+ destroy(): void;
558
810
  /**
559
811
  * Expose merged observable state for consumers.
812
+ *
813
+ * @returns The combined {@link CoreStates} observable object.
560
814
  */
561
815
  get states(): CoreStates;
562
816
  /**
563
- * Reset internal state. Consent is intentionally preserved.
817
+ * Reset internal state. Consent and preview panel state are intentionally preserved.
564
818
  *
565
819
  * @remarks
566
820
  * Resetting personalization also resets analytics dependencies as a
567
821
  * consequence of the current shared-state design.
822
+ * @example
823
+ * ```ts
824
+ * core.reset()
825
+ * ```
568
826
  */
569
827
  reset(): void;
570
828
  /**
@@ -572,20 +830,43 @@ declare abstract class CoreBase {
572
830
  * @remarks
573
831
  * The personalization queue is only populated if events have been triggered
574
832
  * while a device is offline.
833
+ * @example
834
+ * ```ts
835
+ * await core.flush()
836
+ * ```
575
837
  */
576
838
  flush(): Promise<void>;
577
839
  /**
578
840
  * Update consent state
579
841
  *
580
842
  * @param accept - `true` if the user has granted consent; `false` otherwise.
843
+ * @example
844
+ * ```ts
845
+ * core.consent(true)
846
+ * ```
581
847
  */
582
848
  consent(accept: boolean): void;
583
849
  /**
584
- * Update online state
850
+ * Read current online state.
585
851
  *
586
- * @param isOnline - `true` if the browser is online; `false` otherwise.
852
+ * @example
853
+ * ```ts
854
+ * if (this.online) {
855
+ * await this.flush()
856
+ * }
857
+ * ```
858
+ */
859
+ protected get online(): boolean;
860
+ /**
861
+ * Update online state.
862
+ *
863
+ * @param isOnline - `true` if the runtime is online; `false` otherwise.
864
+ * @example
865
+ * ```ts
866
+ * this.online = navigator.onLine
867
+ * ```
587
868
  */
588
- protected online(isOnline: boolean): void;
869
+ protected set online(isOnline: boolean);
589
870
  /**
590
871
  * Register a preview panel compatible object to receive direct signal access.
591
872
  * This enables the preview panel to modify SDK state for testing and simulation.
@@ -594,10 +875,29 @@ declare abstract class CoreBase {
594
875
  * @remarks
595
876
  * This method is intended for use by the Preview Panel component.
596
877
  * Direct signal access allows immediate state updates without API calls.
878
+ * @example
879
+ * ```ts
880
+ * const previewBridge: PreviewPanelSignalObject = {}
881
+ * core.registerPreviewPanel(previewBridge)
882
+ * ```
597
883
  */
598
- registerPreviewPanel(previewPanel?: PreviewPanelSignalObject): PreviewPanelSignalObject;
884
+ registerPreviewPanel(previewPanel: PreviewPanelSignalObject): void;
599
885
  }
600
886
 
887
+ /**
888
+ * Stateful analytics configuration.
889
+ *
890
+ * @public
891
+ */
892
+ export declare type CoreStatefulAnalyticsConfig = NonNullable<CoreConfig['analytics']> & {
893
+ /**
894
+ * Queue policy for stateful analytics event buffering and flush retries.
895
+ *
896
+ * @see {@link AnalyticsProductConfig.queuePolicy}
897
+ */
898
+ queuePolicy?: AnalyticsProductConfig['queuePolicy'];
899
+ };
900
+
601
901
  /**
602
902
  * Configuration for {@link CoreStateful}.
603
903
  *
@@ -605,6 +905,14 @@ declare abstract class CoreBase {
605
905
  * @see {@link CoreConfig}
606
906
  */
607
907
  export declare interface CoreStatefulConfig extends CoreConfig {
908
+ /**
909
+ * Configuration for the analytics (Insights) API client plus stateful queue behavior.
910
+ */
911
+ analytics?: CoreStatefulAnalyticsConfig;
912
+ /**
913
+ * Configuration for the personalization (Experience) API client plus stateful queue behavior.
914
+ */
915
+ personalization?: CoreStatefulPersonalizationConfig;
608
916
  /**
609
917
  * Allow-listed event type strings permitted when consent is not set.
610
918
  *
@@ -616,13 +924,25 @@ declare abstract class CoreBase {
616
924
  /** Function used to obtain an anonymous user identifier. */
617
925
  getAnonymousId?: PersonalizationProductConfig['getAnonymousId'];
618
926
  /**
619
- * Initial duplication prevention configuration for component events.
620
- *
621
- * @see {@link ProductConfig.preventedComponentEvents}
927
+ * Callback invoked whenever an event call is blocked by checks.
622
928
  */
623
- preventedComponentEvents?: ProductConfig['preventedComponentEvents'];
929
+ onEventBlocked?: ProductConfig['onEventBlocked'];
624
930
  }
625
931
 
932
+ /**
933
+ * Stateful personalization configuration.
934
+ *
935
+ * @public
936
+ */
937
+ export declare type CoreStatefulPersonalizationConfig = NonNullable<CoreConfig['personalization']> & {
938
+ /**
939
+ * Queue policy for stateful personalization offline event buffering.
940
+ *
941
+ * @see {@link PersonalizationProductConfig.queuePolicy}
942
+ */
943
+ queuePolicy?: PersonalizationProductConfig['queuePolicy'];
944
+ };
945
+
626
946
  /**
627
947
  * Core runtime that constructs product instances for stateless environments.
628
948
  *
@@ -631,9 +951,9 @@ declare abstract class CoreBase {
631
951
  */
632
952
  export declare class CoreStateless extends CoreBase {
633
953
  /** Stateless analytics product. */
634
- readonly analytics: AnalyticsStateless;
954
+ protected _analytics: AnalyticsStateless;
635
955
  /** Stateless personalization product. */
636
- readonly personalization: PersonalizationStateless;
956
+ protected _personalization: PersonalizationStateless;
637
957
  /**
638
958
  * Create a stateless core. Product instances share the same API client and
639
959
  * event builder configured in {@link CoreBase}.
@@ -642,8 +962,6 @@ declare abstract class CoreBase {
642
962
  * @example
643
963
  * ```ts
644
964
  * const sdk = new CoreStateless({ clientId: 'app', environment: 'prod' })
645
- * core.analytics.trackFlagView({ componentId: 'hero' })
646
- * // or
647
965
  * core.trackFlagView({ componentId: 'hero' })
648
966
  * ```
649
967
  */
@@ -682,12 +1000,16 @@ declare abstract class CoreBase {
682
1000
  export declare interface CoreStates extends AnalyticsStates, PersonalizationStates {
683
1001
  /** Current consent value (if any). */
684
1002
  consent: Observable<boolean | undefined>;
1003
+ /** Whether the preview panel has been attached to the host runtime. */
1004
+ previewPanelAttached: Observable<boolean>;
1005
+ /** Whether the preview panel is currently open in the host runtime. */
1006
+ previewPanelOpen: Observable<boolean>;
1007
+ /** Stream of the most recent blocked event payload. */
1008
+ blockedEventStream: Observable<BlockedEvent | undefined>;
685
1009
  /** Stream of the most recent event emitted (analytics or personalization). */
686
1010
  eventStream: Observable<InsightsEvent | ExperienceEvent | undefined>;
687
1011
  }
688
1012
 
689
- export declare function createScopedLogger(location: string): ScopedLogger;
690
-
691
1013
  /**
692
1014
  * Storage key for the debug flag toggle.
693
1015
  *
@@ -806,6 +1128,8 @@ declare abstract class CoreBase {
806
1128
  *
807
1129
  * @remarks
808
1130
  * Users do not call this directly; it's returned by {@link guardedBy}.
1131
+ *
1132
+ * @internal
809
1133
  */
810
1134
  declare type GuardedByFunction<T extends object> = <A extends readonly unknown[], R>(value: (...args: A) => R, context: ClassMethodDecoratorContext<T, (...args: A) => R>) => void;
811
1135
 
@@ -976,37 +1300,6 @@ declare abstract class CoreBase {
976
1300
  state: InterceptorManager<OptimizationData>;
977
1301
  }
978
1302
 
979
- export { LogEvent }
980
-
981
- export declare class Logger {
982
- readonly name = "@contentful/optimization";
983
- private readonly PREFIX_PARTS;
984
- private readonly DELIMITER;
985
- private readonly diary;
986
- private sinks;
987
- constructor();
988
- private assembleLocationPrefix;
989
- addSink(sink: LogSink): void;
990
- removeSink(name: string): void;
991
- removeSinks(): void;
992
- debug(logLocation: string, message: string, ...args: unknown[]): void;
993
- info(logLocation: string, message: string, ...args: unknown[]): void;
994
- log(logLocation: string, message: string, ...args: unknown[]): void;
995
- warn(logLocation: string, message: string, ...args: unknown[]): void;
996
- error(logLocation: string, message: string | Error, ...args: unknown[]): void;
997
- fatal(logLocation: string, message: string | Error, ...args: unknown[]): void;
998
- private onLogEvent;
999
- }
1000
-
1001
- export declare const logger: Logger;
1002
-
1003
- export { LogLevels }
1004
-
1005
- export declare abstract class LogSink {
1006
- abstract name: string;
1007
- abstract ingest(event: LogEvent): void;
1008
- }
1009
-
1010
1303
  /**
1011
1304
  * A utility type representing a value that may be synchronously available or
1012
1305
  * produced asynchronously.
@@ -1027,19 +1320,6 @@ declare abstract class CoreBase {
1027
1320
  * Result values are returned as strings; numeric/boolean primitives are stringified.
1028
1321
  */
1029
1322
  export declare const MergeTagValueResolver: {
1030
- /**
1031
- * Type guard to ensure the input is a {@link MergeTagEntry}.
1032
- *
1033
- * @param embeddedEntryNodeTarget - Unknown value to validate.
1034
- * @returns `true` if the input is a valid merge-tag entry.
1035
- * @example
1036
- * ```ts
1037
- * if (MergeTagValueResolver.isMergeTagEntry(node)) {
1038
- * // safe to read fields
1039
- * }
1040
- * ```
1041
- */
1042
- isMergeTagEntry(embeddedEntryNodeTarget: unknown): embeddedEntryNodeTarget is MergeTagEntry;
1043
1323
  /**
1044
1324
  * Generate a list of candidate selectors for a merge-tag ID.
1045
1325
  *
@@ -1062,13 +1342,13 @@ declare abstract class CoreBase {
1062
1342
  * @param id - Merge-tag identifier.
1063
1343
  * @param profile - Profile from which to resolve the value.
1064
1344
  * @returns A stringified primitive if found; otherwise `undefined`.
1345
+ * @remarks
1346
+ * Only string/number/boolean primitives are returned; objects/arrays are ignored.
1065
1347
  * @example
1066
1348
  * ```ts
1067
1349
  * const value = MergeTagValueResolver.getValueFromProfile('user_email', profile)
1068
1350
  * if (value) sendEmailTo(value)
1069
1351
  * ```
1070
- * @remarks
1071
- * Only string/number/boolean primitives are returned; objects/arrays are ignored.
1072
1352
  */
1073
1353
  getValueFromProfile(id: string, profile?: Profile): string | undefined;
1074
1354
  /**
@@ -1094,8 +1374,18 @@ declare abstract class CoreBase {
1094
1374
 
1095
1375
  declare const online: Signal<boolean | undefined>;
1096
1376
 
1377
+ /**
1378
+ * The package name of the Optimization Core SDK, injected at build time.
1379
+ *
1380
+ * @public
1381
+ */
1097
1382
  export declare const OPTIMIZATION_CORE_SDK_NAME: string;
1098
1383
 
1384
+ /**
1385
+ * The current version of the Optimization Core SDK, injected at build time.
1386
+ *
1387
+ * @public
1388
+ */
1099
1389
  export declare const OPTIMIZATION_CORE_SDK_VERSION: string;
1100
1390
 
1101
1391
  /**
@@ -1107,20 +1397,19 @@ declare abstract class CoreBase {
1107
1397
  * identify, page, and track events. This base wires in shared singleton
1108
1398
  * resolvers used to fetch/resolve personalized data.
1109
1399
  */
1110
- declare abstract class PersonalizationBase extends ProductBase implements ResolverMethods {
1400
+ export declare abstract class PersonalizationBase extends ProductBase implements ResolverMethods {
1111
1401
  /**
1112
1402
  * Static {@link FlagsResolver | resolver} for evaluating personalized
1113
1403
  * custom flags.
1114
1404
  */
1115
1405
  readonly flagsResolver: {
1116
- resolve(changes?: ChangeArray): Flags_2;
1406
+ resolve(changes?: ChangeArray): Flags;
1117
1407
  };
1118
1408
  /**
1119
1409
  * Static {@link MergeTagValueResolver | resolver} that returns values
1120
1410
  * sourced from a user profile based on a Contentful Merge Tag entry.
1121
1411
  */
1122
1412
  readonly mergeTagValueResolver: {
1123
- isMergeTagEntry(embeddedEntryNodeTarget: unknown): embeddedEntryNodeTarget is MergeTagEntry;
1124
1413
  normalizeSelectors(id: string): string[];
1125
1414
  getValueFromProfile(id: string, profile?: Profile): string | undefined;
1126
1415
  resolve(mergeTagEntry: MergeTagEntry | undefined, profile?: Profile): string | undefined;
@@ -1163,6 +1452,15 @@ declare abstract class CoreBase {
1163
1452
  * personalization event.
1164
1453
  * */
1165
1454
  getCustomFlag(name: string, changes?: ChangeArray): Json;
1455
+ /**
1456
+ * Get all resolved Custom Flags from the supplied changes.
1457
+ * @param changes - Optional changes array.
1458
+ * @returns The resolved Custom Flag map.
1459
+ * @remarks
1460
+ * The changes array can be sourced from the data returned when emitting any
1461
+ * personalization event.
1462
+ * */
1463
+ getCustomFlags(changes?: ChangeArray): Flags;
1166
1464
  /**
1167
1465
  * Resolve a Contentful entry to a personalized variant using the current
1168
1466
  * or provided selected personalizations.
@@ -1188,7 +1486,7 @@ declare abstract class CoreBase {
1188
1486
  * Merge tags are references to profile data that can be substituted into content. The
1189
1487
  * profile can be sourced from the data returned when emitting any personalization event.
1190
1488
  */
1191
- getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile): unknown;
1489
+ getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile): string | undefined;
1192
1490
  /**
1193
1491
  * Identify the current profile/visitor to associate traits with a profile.
1194
1492
  *
@@ -1225,10 +1523,24 @@ declare abstract class CoreBase {
1225
1523
  * @remarks
1226
1524
  * This method is intended to be called only when a component is considered
1227
1525
  * "sticky".
1228
- * @privateRemarks
1229
- * Duplication prevention should be handled in Stateful implementations.
1230
1526
  */
1231
- abstract trackComponentView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<OptimizationData | undefined>;
1527
+ abstract trackComponentView(payload: ComponentViewBuilderArgs): Promise<OptimizationData | undefined>;
1528
+ }
1529
+
1530
+ /**
1531
+ * Context payload emitted when offline personalization events are dropped due to queue bounds.
1532
+ *
1533
+ * @public
1534
+ */
1535
+ export declare interface PersonalizationOfflineQueueDropContext {
1536
+ /** Number of dropped events. */
1537
+ droppedCount: number;
1538
+ /** Dropped events in oldest-first order. */
1539
+ droppedEvents: ExperienceEventArray;
1540
+ /** Configured queue max size. */
1541
+ maxEvents: number;
1542
+ /** Queue size after enqueueing the current event. */
1543
+ queuedEvents: number;
1232
1544
  }
1233
1545
 
1234
1546
  /**
@@ -1239,6 +1551,10 @@ declare abstract class CoreBase {
1239
1551
  export declare interface PersonalizationProductConfig extends ProductConfig {
1240
1552
  /** Default signal values applied during initialization. */
1241
1553
  defaults?: PersonalizationProductConfigDefaults;
1554
+ /**
1555
+ * Policy that controls the offline personalization queue size and drop telemetry.
1556
+ */
1557
+ queuePolicy?: PersonalizationQueuePolicy;
1242
1558
  /**
1243
1559
  * Function used to obtain an anonymous user identifier.
1244
1560
  *
@@ -1268,6 +1584,27 @@ declare abstract class CoreBase {
1268
1584
  personalizations?: SelectedPersonalizationArray;
1269
1585
  }
1270
1586
 
1587
+ /**
1588
+ * Policy options for the stateful personalization offline queue.
1589
+ *
1590
+ * @public
1591
+ */
1592
+ export declare interface PersonalizationQueuePolicy {
1593
+ /**
1594
+ * Maximum number of personalization events retained while offline.
1595
+ */
1596
+ maxEvents?: number;
1597
+ /**
1598
+ * Callback invoked whenever oldest events are dropped due to queue bounds.
1599
+ */
1600
+ onDrop?: (context: PersonalizationOfflineQueueDropContext) => void;
1601
+ /**
1602
+ * Policy that controls offline queue flush retries, backoff, and circuit
1603
+ * behavior after repeated failures.
1604
+ */
1605
+ flushPolicy?: QueueFlushPolicy;
1606
+ }
1607
+
1271
1608
  declare const personalizations: Signal<{
1272
1609
  experienceId: string;
1273
1610
  variantIndex: number;
@@ -1294,8 +1631,12 @@ declare abstract class CoreBase {
1294
1631
  * back into signals.
1295
1632
  */
1296
1633
  export declare class PersonalizationStateful extends PersonalizationBase implements ConsentGuard {
1297
- /** Inmemory queue for offline events keyed by profile. */
1634
+ /** In-memory ordered queue for offline personalization events. */
1298
1635
  private readonly offlineQueue;
1636
+ /** Resolved offline queue policy values. */
1637
+ private readonly queuePolicy;
1638
+ /** Shared queue flush retry runtime state machine. */
1639
+ private readonly flushRuntime;
1299
1640
  /** Exposed observable state references. */
1300
1641
  readonly states: PersonalizationStates;
1301
1642
  /**
@@ -1308,6 +1649,10 @@ declare abstract class CoreBase {
1308
1649
  * Create a new stateful personalization instance.
1309
1650
  *
1310
1651
  * @param options - Options to configure the personalization product for stateful environments.
1652
+ * @example
1653
+ * ```ts
1654
+ * const personalization = new PersonalizationStateful({ api, builder, config: { getAnonymousId }, interceptors })
1655
+ * ```
1311
1656
  */
1312
1657
  constructor(options: PersonalizationStatefulOptions);
1313
1658
  /**
@@ -1315,14 +1660,32 @@ declare abstract class CoreBase {
1315
1660
  *
1316
1661
  * @remarks
1317
1662
  * Clears `changes`, `profile`, and selected `personalizations`.
1663
+ * @example
1664
+ * ```ts
1665
+ * personalization.reset()
1666
+ * ```
1318
1667
  */
1319
1668
  reset(): void;
1320
1669
  /**
1321
1670
  * Get the specified Custom Flag's value (derived from the signal).
1322
1671
  * @param name - The name or key of the Custom Flag.
1323
1672
  * @returns The current value of the Custom Flag if found.
1673
+ * @example
1674
+ * ```ts
1675
+ * const flagValue = personalization.getCustomFlag('dark-mode')
1676
+ * ```
1324
1677
  * */
1325
1678
  getCustomFlag(name: string, changes?: ChangeArray | undefined): Json;
1679
+ /**
1680
+ * Get all resolved Custom Flags (derived from the signal).
1681
+ * @param changes - Optional changes array; defaults to the current signal value.
1682
+ * @returns The resolved Custom Flag map.
1683
+ * @example
1684
+ * ```ts
1685
+ * const flags = personalization.getCustomFlags()
1686
+ * ```
1687
+ */
1688
+ getCustomFlags(changes?: ChangeArray | undefined): Flags;
1326
1689
  /**
1327
1690
  * Resolve a Contentful entry to a personalized variant using the current
1328
1691
  * or provided selections.
@@ -1333,6 +1696,10 @@ declare abstract class CoreBase {
1333
1696
  * @param entry - The entry to personalize.
1334
1697
  * @param personalizations - Optional selections; defaults to the current signal value.
1335
1698
  * @returns The resolved entry data.
1699
+ * @example
1700
+ * ```ts
1701
+ * const { entry } = personalization.personalizeEntry(baselineEntry)
1702
+ * ```
1336
1703
  */
1337
1704
  personalizeEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = LocaleCode>(entry: Entry<S, M, L>, personalizations?: SelectedPersonalizationArray | undefined): ResolvedData<S, M, L>;
1338
1705
  /**
@@ -1343,8 +1710,12 @@ declare abstract class CoreBase {
1343
1710
  * @returns The resolved value (type depends on the tag).
1344
1711
  * @remarks
1345
1712
  * Merge tags are references to profile data that can be substituted into content.
1713
+ * @example
1714
+ * ```ts
1715
+ * const name = personalization.getMergeTagValue(mergeTagNode)
1716
+ * ```
1346
1717
  */
1347
- getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile | undefined): unknown;
1718
+ getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile | undefined): string | undefined;
1348
1719
  /**
1349
1720
  * Determine whether the named operation is permitted based on consent and
1350
1721
  * allowed event type configuration.
@@ -1352,6 +1723,10 @@ declare abstract class CoreBase {
1352
1723
  * @param name - Method name; `trackComponentView` is normalized to
1353
1724
  * `'component'` for allow‑list checks.
1354
1725
  * @returns `true` if the operation is permitted; otherwise `false`.
1726
+ * @example
1727
+ * ```ts
1728
+ * if (personalization.hasConsent('track')) { ... }
1729
+ * ```
1355
1730
  */
1356
1731
  hasConsent(name: string): boolean;
1357
1732
  /**
@@ -1359,30 +1734,22 @@ declare abstract class CoreBase {
1359
1734
  *
1360
1735
  * @param name - The blocked operation name.
1361
1736
  * @param payload - The original arguments supplied to the operation.
1737
+ * @example
1738
+ * ```ts
1739
+ * personalization.onBlockedByConsent('track', [payload])
1740
+ * ```
1362
1741
  */
1363
- onBlockedByConsent(name: string, payload: unknown[]): void;
1364
- /**
1365
- * Guard used to suppress duplicate component view events for the same
1366
- * component based on a duplication key and the component identifier.
1367
- *
1368
- * @param _name - Operation name (unused).
1369
- * @param payload - Tuple `[builderArgs, duplicationScope]`.
1370
- * @returns `true` if the event is NOT a duplicate and should proceed.
1371
- */
1372
- isNotDuplicated(_name: string, payload: [ComponentViewBuilderArgs, string]): boolean;
1373
- /**
1374
- * Hook invoked when an operation is blocked by the duplication guard.
1375
- *
1376
- * @param _name - The blocked operation name (unused).
1377
- * @param payload - The original arguments supplied to the operation.
1378
- */
1379
- onBlockedByDuplication(_name: string, payload: unknown[]): void;
1742
+ onBlockedByConsent(name: string, payload: readonly unknown[]): void;
1380
1743
  /**
1381
1744
  * Identify the current profile/visitor to associate traits with a profile
1382
1745
  * and update optimization state.
1383
1746
  *
1384
1747
  * @param payload - Identify builder payload.
1385
1748
  * @returns The resulting {@link OptimizationData} for the identified user.
1749
+ * @example
1750
+ * ```ts
1751
+ * const data = await personalization.identify({ userId: 'user-123' })
1752
+ * ```
1386
1753
  */
1387
1754
  identify(payload: IdentifyBuilderArgs): Promise<OptimizationData | undefined>;
1388
1755
  /**
@@ -1390,6 +1757,10 @@ declare abstract class CoreBase {
1390
1757
  *
1391
1758
  * @param payload - Page view builder payload.
1392
1759
  * @returns The evaluated {@link OptimizationData} for this page view.
1760
+ * @example
1761
+ * ```ts
1762
+ * const data = await personalization.page({ properties: { title: 'Home' } })
1763
+ * ```
1393
1764
  */
1394
1765
  page(payload: PageViewBuilderArgs): Promise<OptimizationData | undefined>;
1395
1766
  /**
@@ -1397,6 +1768,10 @@ declare abstract class CoreBase {
1397
1768
  *
1398
1769
  * @param payload - Screen view builder payload.
1399
1770
  * @returns The evaluated {@link OptimizationData} for this screen view.
1771
+ * @example
1772
+ * ```ts
1773
+ * const data = await personalization.screen({ name: 'HomeScreen' })
1774
+ * ```
1400
1775
  */
1401
1776
  screen(payload: ScreenViewBuilderArgs): Promise<OptimizationData | undefined>;
1402
1777
  /**
@@ -1404,20 +1779,76 @@ declare abstract class CoreBase {
1404
1779
  *
1405
1780
  * @param payload - Track builder payload.
1406
1781
  * @returns The evaluated {@link OptimizationData} for this event.
1782
+ * @example
1783
+ * ```ts
1784
+ * const data = await personalization.track({ event: 'button_click' })
1785
+ * ```
1407
1786
  */
1408
1787
  track(payload: TrackBuilderArgs): Promise<OptimizationData | undefined>;
1409
- trackComponentView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<OptimizationData | undefined>;
1410
1788
  /**
1411
- * Intercept, validate, and place an event into the offline eventd queue; then
1789
+ * Record a "sticky" component view and update optimization state.
1790
+ *
1791
+ * @param payload - Component view builder payload.
1792
+ * @returns The evaluated {@link OptimizationData} for this component view.
1793
+ * @example
1794
+ * ```ts
1795
+ * const data = await personalization.trackComponentView({ componentId: 'hero-banner' })
1796
+ * ```
1797
+ */
1798
+ trackComponentView(payload: ComponentViewBuilderArgs): Promise<OptimizationData | undefined>;
1799
+ /**
1800
+ * Intercept, validate, and place an event into the offline event queue; then
1412
1801
  * trigger a size‑based flush if necessary.
1413
1802
  *
1414
1803
  * @param event - The event to enqueue.
1415
1804
  */
1416
1805
  private sendOrEnqueueEvent;
1806
+ /**
1807
+ * Enqueue an offline event, dropping oldest events first when queue bounds are reached.
1808
+ *
1809
+ * @param event - Event to enqueue.
1810
+ */
1811
+ private enqueueOfflineEvent;
1812
+ /**
1813
+ * Drop oldest offline events from the queue.
1814
+ *
1815
+ * @param count - Number of oldest events to drop.
1816
+ * @returns Dropped events in oldest-first order.
1817
+ */
1818
+ private dropOldestOfflineEvents;
1819
+ /**
1820
+ * Invoke offline queue drop callback in a fault-tolerant manner.
1821
+ *
1822
+ * @param context - Drop callback payload.
1823
+ */
1824
+ private invokeQueueDropCallback;
1417
1825
  /**
1418
1826
  * Flush the offline queue
1827
+ *
1828
+ * @param options - Optional flush controls.
1829
+ * @param options.force - When `true`, bypass offline/backoff/circuit gates and attempt immediately.
1830
+ *
1831
+ * @example
1832
+ * ```ts
1833
+ * await personalization.flush()
1419
1834
  */
1420
- flush(): Promise<void>;
1835
+ flush(options?: {
1836
+ force?: boolean;
1837
+ }): Promise<void>;
1838
+ /**
1839
+ * Flush queued offline events using retry/circuit guards.
1840
+ *
1841
+ * @param options - Flush controls.
1842
+ * @param options.force - When true, bypass online/backoff/circuit gates.
1843
+ */
1844
+ private flushOfflineQueue;
1845
+ /**
1846
+ * Attempt to send queued events to the Experience API.
1847
+ *
1848
+ * @param events - Snapshot of queued events to send.
1849
+ * @returns `true` when send succeeds; otherwise `false`.
1850
+ */
1851
+ private tryUpsertQueuedEvents;
1421
1852
  /**
1422
1853
  * Submit events to the Experience API, updating output signals with the
1423
1854
  * returned state.
@@ -1469,6 +1900,10 @@ declare abstract class CoreBase {
1469
1900
  * @param payload - Identify builder arguments with an optional partial
1470
1901
  * profile to attach to the upsert request.
1471
1902
  * @returns The resulting {@link OptimizationData} for the identified user.
1903
+ * @example
1904
+ * ```ts
1905
+ * const data = await personalization.identify({ userId: 'user-123', profile: { id: 'anon-1' } })
1906
+ * ```
1472
1907
  */
1473
1908
  identify(payload: IdentifyBuilderArgs & {
1474
1909
  profile?: PartialProfile;
@@ -1478,6 +1913,10 @@ declare abstract class CoreBase {
1478
1913
  *
1479
1914
  * @param payload - Page view builder arguments with an optional partial profile.
1480
1915
  * @returns The evaluated {@link OptimizationData} for this page view.
1916
+ * @example
1917
+ * ```ts
1918
+ * const data = await personalization.page({ properties: { title: 'Home' }, profile: { id: 'anon-1' } })
1919
+ * ```
1481
1920
  */
1482
1921
  page(payload: PageViewBuilderArgs & {
1483
1922
  profile?: PartialProfile;
@@ -1487,6 +1926,10 @@ declare abstract class CoreBase {
1487
1926
  *
1488
1927
  * @param payload - Screen view builder arguments with an optional partial profile.
1489
1928
  * @returns The evaluated {@link OptimizationData} for this screen view.
1929
+ * @example
1930
+ * ```ts
1931
+ * const data = await personalization.screen({ name: 'HomeScreen', profile: { id: 'anon-1' } })
1932
+ * ```
1490
1933
  */
1491
1934
  screen(payload: ScreenViewBuilderArgs & {
1492
1935
  profile?: PartialProfile;
@@ -1496,6 +1939,10 @@ declare abstract class CoreBase {
1496
1939
  *
1497
1940
  * @param payload - Track builder arguments with an optional partial profile.
1498
1941
  * @returns The evaluated {@link OptimizationData} for this event.
1942
+ * @example
1943
+ * ```ts
1944
+ * const data = await personalization.track({ event: 'purchase', profile: { id: 'anon-1' } })
1945
+ * ```
1499
1946
  */
1500
1947
  track(payload: TrackBuilderArgs & {
1501
1948
  profile?: PartialProfile;
@@ -1505,6 +1952,10 @@ declare abstract class CoreBase {
1505
1952
  *
1506
1953
  * @param payload - Component view builder arguments with an optional partial profile.
1507
1954
  * @returns The evaluated {@link OptimizationData} for this component view.
1955
+ * @example
1956
+ * ```ts
1957
+ * const data = await personalization.trackComponentView({ componentId: 'hero', profile: { id: 'anon-1' } })
1958
+ * ```
1508
1959
  */
1509
1960
  trackComponentView(payload: ComponentViewBuilderArgs & {
1510
1961
  profile?: PartialProfile;
@@ -1528,6 +1979,8 @@ declare abstract class CoreBase {
1528
1979
  * @public
1529
1980
  */
1530
1981
  export declare interface PersonalizationStates {
1982
+ /** Observable stream of the latest blocked event payload (or `undefined`). */
1983
+ blockedEventStream: Observable<BlockedEvent | undefined>;
1531
1984
  /** Observable stream of the latest {@link AnalyticsEvent} or {@link PersonalizationEvent} (or `undefined`). */
1532
1985
  eventStream: Observable<InsightsEvent | ExperienceEvent | undefined>;
1533
1986
  /** Live view of effective flags for the current profile (if available). */
@@ -1558,6 +2011,10 @@ declare abstract class CoreBase {
1558
2011
  * @param params - Object containing the baseline personalized entry and the selections.
1559
2012
  * @param skipValidation - When `true`, skip type/shape validation for perf.
1560
2013
  * @returns The matching {@link PersonalizationEntry}, or `undefined` if not found/invalid.
2014
+ * @remarks
2015
+ * A personalization entry is a personalization configuration object supplied in a
2016
+ * `PersonalizedEntry.nt_experiences` array. A personalized entry may relate to
2017
+ * multiple personalizations.
1561
2018
  * @example
1562
2019
  * ```ts
1563
2020
  * const personalizationEntry = PersonalizedEntryResolver.getPersonalizationEntry({
@@ -1565,10 +2022,6 @@ declare abstract class CoreBase {
1565
2022
  * selectedPersonalizations
1566
2023
  * })
1567
2024
  * ```
1568
- * @remarks
1569
- * A personalization entry is a personalization configuration object supplied in a
1570
- * `PersonalizedEntry.nt_experiences` array. A personalized entry may relate to
1571
- * multiple personalizations.
1572
2025
  */
1573
2026
  getPersonalizationEntry({ personalizedEntry, selectedPersonalizations, }: {
1574
2027
  personalizedEntry: PersonalizedEntry_2;
@@ -1580,6 +2033,9 @@ declare abstract class CoreBase {
1580
2033
  * @param params - Object with the target personalization entry and selections.
1581
2034
  * @param skipValidation - When `true`, skip type checks.
1582
2035
  * @returns The matching {@link SelectedPersonalization}, if present.
2036
+ * @remarks
2037
+ * Selected personalizations are supplied by the Experience API in the
2038
+ * `experiences` response data property.
1583
2039
  * @example
1584
2040
  * ```ts
1585
2041
  * const selectedPersonalization = PersonalizedEntryResolver.getSelectedPersonalization({
@@ -1587,9 +2043,6 @@ declare abstract class CoreBase {
1587
2043
  * selectedPersonalizations
1588
2044
  * })
1589
2045
  * ```
1590
- * @remarks
1591
- * Selected personalizations are supplied by the Experience API in the
1592
- * `experiences` response data property.
1593
2046
  */
1594
2047
  getSelectedPersonalization({ personalizationEntry, selectedPersonalizations, }: {
1595
2048
  personalizationEntry: PersonalizationEntry_2;
@@ -1601,6 +2054,10 @@ declare abstract class CoreBase {
1601
2054
  * @param params - Baseline entry, personalization entry, and 1‑based variant index.
1602
2055
  * @param skipValidation - When `true`, skip type checks.
1603
2056
  * @returns The {@link EntryReplacementVariant} for the component, if any.
2057
+ * @remarks
2058
+ * Entry replacement variants are variant configurations specified in a
2059
+ * personalization configuration component's `variants` array supplied by the
2060
+ * personalized entry via its `nt_config` field.
1604
2061
  * @example
1605
2062
  * ```ts
1606
2063
  * const selectedVariant = PersonalizedEntryResolver.getSelectedVariant({
@@ -1609,10 +2066,6 @@ declare abstract class CoreBase {
1609
2066
  * selectedVariantIndex: 2 // second variant (1‑based)
1610
2067
  * })
1611
2068
  * ```
1612
- * @remarks
1613
- * Entry replacement variants are variant configurations specified in a
1614
- * personalization configuration component's `variants` array supplied by the
1615
- * personalized entry via its `nt_config` field.
1616
2069
  */
1617
2070
  getSelectedVariant({ personalizedEntry, personalizationEntry, selectedVariantIndex, }: {
1618
2071
  personalizedEntry: PersonalizedEntry_2;
@@ -1628,6 +2081,9 @@ declare abstract class CoreBase {
1628
2081
  * @param params - Personalization entry and selected variant.
1629
2082
  * @param skipValidation - When `true`, skip type checks.
1630
2083
  * @returns The resolved entry typed as {@link Entry} or `undefined`.
2084
+ * @remarks
2085
+ * A personalized entry will resolve either to the baseline (the entry
2086
+ * supplied as `personalizedEntry`) or the selected variant.
1631
2087
  * @example
1632
2088
  * ```ts
1633
2089
  * const selectedVariantEntry = PersonalizedEntryResolver.getSelectedVariantEntry<{ fields: unknown }>({
@@ -1635,9 +2091,6 @@ declare abstract class CoreBase {
1635
2091
  * selectedVariant
1636
2092
  * })
1637
2093
  * ```
1638
- * @remarks
1639
- * A personalized entry will resolve either to the baseline (the entry
1640
- * supplied as `personalizedEntry`) or the selected variant.
1641
2094
  */
1642
2095
  getSelectedVariantEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>({ personalizationEntry, selectedVariant, }: {
1643
2096
  personalizationEntry: PersonalizationEntry_2;
@@ -1663,17 +2116,29 @@ declare abstract class CoreBase {
1663
2116
  resolve<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>(entry: Entry<S, M, L>, selectedPersonalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
1664
2117
  };
1665
2118
 
2119
+ export declare const PREVIEW_PANEL_SIGNAL_FNS_SYMBOL: unique symbol;
2120
+
1666
2121
  /**
1667
- * Interface for objects that can be registered with the preview panel system.
1668
- * When registered, the object receives direct access to SDK signals for state manipulation.
2122
+ * Well-known symbols used by the preview panel bridge.
2123
+ *
2124
+ * @public
2125
+ */
2126
+ export declare const PREVIEW_PANEL_SIGNALS_SYMBOL: unique symbol;
2127
+
2128
+ declare const previewPanelAttached: Signal<boolean>;
2129
+
2130
+ declare const previewPanelOpen: Signal<boolean>;
2131
+
2132
+ /**
2133
+ * Symbol-keyed signal bridge shared between core and first-party preview tooling.
1669
2134
  *
1670
2135
  * @public
1671
2136
  */
1672
2137
  export declare interface PreviewPanelSignalObject {
1673
- /** Signals instance that will be populated by registerPreviewPanel */
1674
- signals: Signals | null | undefined;
1675
- /** Signal functions that can be used across micro-frontend barriers */
1676
- signalFns: SignalFns | null | undefined;
2138
+ /** Signals instance populated by {@link CoreStateful.registerPreviewPanel}. */
2139
+ [PREVIEW_PANEL_SIGNALS_SYMBOL]?: Signals | null | undefined;
2140
+ /** Signal helper functions populated by {@link CoreStateful.registerPreviewPanel}. */
2141
+ [PREVIEW_PANEL_SIGNAL_FNS_SYMBOL]?: SignalFns | null | undefined;
1677
2142
  }
1678
2143
 
1679
2144
  /**
@@ -1694,19 +2159,25 @@ declare abstract class CoreBase {
1694
2159
  protected readonly builder: EventBuilder;
1695
2160
  /** Optimization API client used to send events to the Experience and Insights APIs. */
1696
2161
  protected readonly api: ApiClient;
1697
- /**
1698
- * Deduplication helper used to track previously seen values within optional
1699
- * scopes
1700
- */
1701
- readonly duplicationDetector: ValuePresence;
1702
2162
  /** Interceptors that can mutate/augment outgoing events or optimization state. */
1703
2163
  readonly interceptors: LifecycleInterceptors;
2164
+ /** Optional callback invoked when an event call is blocked. */
2165
+ protected readonly onEventBlocked?: ProductConfig['onEventBlocked'];
1704
2166
  /**
1705
2167
  * Creates a new product base instance.
1706
2168
  *
1707
2169
  * @param options - Options for configuring the functionality common among products.
1708
2170
  */
1709
2171
  constructor(options: ProductBaseOptions);
2172
+ /**
2173
+ * Publish blocked event metadata to both callback and blocked event signal.
2174
+ *
2175
+ * @param reason - Reason the method call was blocked.
2176
+ * @param product - Product that blocked the method call.
2177
+ * @param method - Name of the blocked method.
2178
+ * @param args - Original blocked call arguments.
2179
+ */
2180
+ protected reportBlockedEvent(reason: BlockedEventReason, product: BlockedEventProduct, method: string, args: readonly unknown[]): void;
1710
2181
  }
1711
2182
 
1712
2183
  /**
@@ -1719,7 +2190,7 @@ declare abstract class CoreBase {
1719
2190
  api: ApiClient;
1720
2191
  /** Event builder for constructing events. */
1721
2192
  builder: EventBuilder;
1722
- /** Optional configuration for allow‑lists and duplication prevention. */
2193
+ /** Optional configuration for allow‑lists and guard callbacks. */
1723
2194
  config?: ProductConfig;
1724
2195
  /** Lifecycle container for event and state interceptors. */
1725
2196
  interceptors: LifecycleInterceptors;
@@ -1735,20 +2206,18 @@ declare abstract class CoreBase {
1735
2206
  * The set of event type strings that are allowed to be sent even if consent is
1736
2207
  * not granted.
1737
2208
  *
1738
- * @defaultValue `['page', 'identify']`
2209
+ * @defaultValue `['identify', 'page', 'screen']`
1739
2210
  * @remarks These types are compared against the `type` property of events.
1740
2211
  */
1741
2212
  allowedEventTypes?: EventType[];
1742
2213
  /**
1743
- * A map of duplication keys to a list of component IDs that should be
1744
- * considered duplicates and therefore suppressed.
2214
+ * Callback invoked whenever an event call is blocked by guards.
1745
2215
  *
1746
2216
  * @remarks
1747
- * The actual duplication check is performed by {@link ValuePresence}. The
1748
- * keys of this record are used as duplication scopes. An empty string `''`
1749
- * is converted to an `indefined` scope when specific scopes are not required.
2217
+ * This callback is best-effort. Any exception thrown by the callback is
2218
+ * swallowed to keep event handling fault tolerant.
1750
2219
  */
1751
- preventedComponentEvents?: Record<string, string[]>;
2220
+ onEventBlocked?: (event: BlockedEvent) => void;
1752
2221
  }
1753
2222
 
1754
2223
  declare const profile: Signal<Profile | undefined>;
@@ -1760,6 +2229,85 @@ declare abstract class CoreBase {
1760
2229
  */
1761
2230
  export declare const PROFILE_CACHE_KEY = "__ctfl_opt_profile__";
1762
2231
 
2232
+ /**
2233
+ * Context payload emitted when a queue flush fails.
2234
+ *
2235
+ * @public
2236
+ */
2237
+ declare interface QueueFlushFailureContext {
2238
+ /** Number of consecutive failed flush attempts. */
2239
+ consecutiveFailures: number;
2240
+ /** Number of queued batches at the time of the failed attempt. */
2241
+ queuedBatches: number;
2242
+ /** Number of queued events at the time of the failed attempt. */
2243
+ queuedEvents: number;
2244
+ /** Delay before the next retry attempt is scheduled. */
2245
+ retryDelayMs: number;
2246
+ }
2247
+
2248
+ /**
2249
+ * Policy options for controlling queue flush retry behavior.
2250
+ *
2251
+ * @public
2252
+ */
2253
+ declare interface QueueFlushPolicy {
2254
+ /**
2255
+ * Base retry backoff delay in milliseconds.
2256
+ *
2257
+ * @defaultValue `500`
2258
+ */
2259
+ baseBackoffMs?: number;
2260
+ /**
2261
+ * Maximum retry backoff delay in milliseconds.
2262
+ *
2263
+ * @defaultValue `30000`
2264
+ */
2265
+ maxBackoffMs?: number;
2266
+ /**
2267
+ * Jitter ratio applied to retry delay to avoid synchronized retries.
2268
+ *
2269
+ * @remarks
2270
+ * Value is clamped to `[0, 1]`.
2271
+ *
2272
+ * @defaultValue `0.2`
2273
+ */
2274
+ jitterRatio?: number;
2275
+ /**
2276
+ * Consecutive failures threshold before opening the circuit window.
2277
+ *
2278
+ * @defaultValue `8`
2279
+ */
2280
+ maxConsecutiveFailures?: number;
2281
+ /**
2282
+ * Duration in milliseconds to wait before retrying after circuit opens.
2283
+ *
2284
+ * @defaultValue `120000`
2285
+ */
2286
+ circuitOpenMs?: number;
2287
+ /**
2288
+ * Callback invoked after each failed flush attempt.
2289
+ */
2290
+ onFlushFailure?: (context: QueueFlushFailureContext) => void;
2291
+ /**
2292
+ * Callback invoked when the circuit opens after consecutive failures.
2293
+ */
2294
+ onCircuitOpen?: (context: QueueFlushFailureContext) => void;
2295
+ /**
2296
+ * Callback invoked when a flush succeeds after previous failures.
2297
+ */
2298
+ onFlushRecovered?: (context: QueueFlushRecoveredContext) => void;
2299
+ }
2300
+
2301
+ /**
2302
+ * Context payload emitted when a failed queue flush sequence recovers.
2303
+ *
2304
+ * @public
2305
+ */
2306
+ declare interface QueueFlushRecoveredContext {
2307
+ /** Consecutive failure count that existed immediately before recovery. */
2308
+ consecutiveFailures: number;
2309
+ }
2310
+
1763
2311
  /**
1764
2312
  * Result returned by {@link PersonalizedEntryResolver.resolve}.
1765
2313
  *
@@ -1783,7 +2331,7 @@ declare abstract class CoreBase {
1783
2331
  * This interface exists to document that the included methods should not be
1784
2332
  * considered static.
1785
2333
  */
1786
- declare interface ResolverMethods {
2334
+ export declare interface ResolverMethods {
1787
2335
  /**
1788
2336
  * Get the specified Custom Flag's value from the supplied changes.
1789
2337
  * @param name - The name or key of the Custom Flag.
@@ -1794,6 +2342,15 @@ declare abstract class CoreBase {
1794
2342
  * personalization event.
1795
2343
  * */
1796
2344
  getCustomFlag: (name: string, changes?: ChangeArray) => Json;
2345
+ /**
2346
+ * Get all resolved Custom Flags from the supplied changes.
2347
+ * @param changes - Optional changes array.
2348
+ * @returns The resolved Custom Flag map.
2349
+ * @remarks
2350
+ * The changes array can be sourced from the data returned when emitting any
2351
+ * personalization event.
2352
+ * */
2353
+ getCustomFlags: (changes?: ChangeArray) => Flags;
1797
2354
  /**
1798
2355
  * Resolve a Contentful entry to a personalized variant using the current
1799
2356
  * or provided selected personalizations.
@@ -1819,16 +2376,7 @@ declare abstract class CoreBase {
1819
2376
  * Merge tags are references to profile data that can be substituted into content. The
1820
2377
  * profile can be sourced from the data returned when emitting any personalization event.
1821
2378
  */
1822
- getMergeTagValue: (embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile) => unknown;
1823
- }
1824
-
1825
- export declare interface ScopedLogger {
1826
- debug: (message: string, ...args: unknown[]) => void;
1827
- info: (message: string, ...args: unknown[]) => void;
1828
- log: (message: string, ...args: unknown[]) => void;
1829
- warn: (message: string, ...args: unknown[]) => void;
1830
- error: (message: string | Error, ...args: unknown[]) => void;
1831
- fatal: (message: string | Error, ...args: unknown[]) => void;
2379
+ getMergeTagValue: (embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile) => string | undefined;
1832
2380
  }
1833
2381
 
1834
2382
  export { Signal }
@@ -1843,11 +2391,14 @@ declare abstract class CoreBase {
1843
2391
  export declare const signalFns: SignalFns;
1844
2392
 
1845
2393
  export declare interface Signals {
2394
+ blockedEvent: typeof blockedEvent;
1846
2395
  changes: typeof changes;
1847
2396
  consent: typeof consent;
1848
2397
  event: typeof event_2;
1849
2398
  flags: typeof flags;
1850
2399
  online: typeof online;
2400
+ previewPanelAttached: typeof previewPanelAttached;
2401
+ previewPanelOpen: typeof previewPanelOpen;
1851
2402
  personalizations: typeof personalizations;
1852
2403
  profile: typeof profile;
1853
2404
  }
@@ -1858,6 +2409,14 @@ declare abstract class CoreBase {
1858
2409
  unsubscribe: () => void;
1859
2410
  }
1860
2411
 
2412
+ export declare type TrackComponentClickArgs = ComponentClickBuilderArgs & {
2413
+ profile?: PartialProfile;
2414
+ };
2415
+
2416
+ export declare type TrackComponentHoverArgs = ComponentHoverBuilderArgs & {
2417
+ profile?: PartialProfile;
2418
+ };
2419
+
1861
2420
  /**
1862
2421
  * Arguments for tracking a component/flag view in stateless mode.
1863
2422
  *
@@ -1866,134 +2425,8 @@ declare abstract class CoreBase {
1866
2425
  * The `profile` is optional; when omitted, the APIs may infer identity via
1867
2426
  * other means.
1868
2427
  */
1869
- export declare type TrackViewArgs = ComponentViewBuilderArgs & {
2428
+ export declare type TrackComponentViewArgs = ComponentViewBuilderArgs & {
1870
2429
  profile?: PartialProfile;
1871
2430
  };
1872
2431
 
1873
- /**
1874
- * Tracks whether a given value is present within one or more logical scopes.
1875
- *
1876
- * @remarks
1877
- * - Scope names are case-sensitive.
1878
- * - Presence is based on `Set.has` reference equality for objects and
1879
- * value equality for primitives.
1880
- *
1881
- * @example
1882
- * ```ts
1883
- * const presence = new ValuePresence({ default: ['a', 'b'] })
1884
- * presence.isPresent('default', 'a') // true
1885
- * presence.addValue('default', 'c')
1886
- * presence.removeValue('default', 'b')
1887
- * presence.reset('default')
1888
- * ```
1889
- *
1890
- * @see {@link ValuePresenceScope}
1891
- * @public
1892
- */
1893
- export declare class ValuePresence {
1894
- #private;
1895
- /**
1896
- * Create a new {@link ValuePresence}.
1897
- *
1898
- * @param defaultMap - Optional initial data. Keys are scope names; values are arrays of items to seed.
1899
- * Empty-string keys are normalized to the default scope (`undefined`).
1900
- *
1901
- * @remarks
1902
- * - If `defaultMap` contains duplicate items for a scope, duplicates are collapsed by the `Set`.
1903
- */
1904
- constructor(defaultMap?: Record<string, unknown[]>);
1905
- /**
1906
- * Check whether a value is present within a given scope.
1907
- *
1908
- * @param scope - The scope to check. Use `undefined` for the default scope.
1909
- * @param value - The value to test for presence.
1910
- * @returns `true` if the value is present in the specified scope; otherwise `false`.
1911
- *
1912
- * @remarks
1913
- * Presence testing uses `Set.prototype.has` semantics.
1914
- *
1915
- * @example
1916
- * ```ts
1917
- * presence.isPresent(undefined, 42) // e.g., true or false
1918
- * ```
1919
- *
1920
- * @public
1921
- */
1922
- isPresent(scope: ValuePresenceScope, value: unknown): boolean;
1923
- /**
1924
- * Add a value to a scope, creating the scope if it does not exist.
1925
- *
1926
- * @param scope - Scope to add the value to. Use `undefined` for the default scope.
1927
- * @param value - The value to add.
1928
- * @returns void
1929
- *
1930
- * @remarks
1931
- * - No-op if the value is already present (due to `Set` semantics).
1932
- *
1933
- * @example
1934
- * ```ts
1935
- * presence.addValue('users', userId)
1936
- * ```
1937
- *
1938
- * @public
1939
- */
1940
- addValue(scope: ValuePresenceScope, value: unknown): void;
1941
- /**
1942
- * Remove a value from a scope.
1943
- *
1944
- * @param scope - Scope to remove from. Use `undefined` for the default scope.
1945
- * @param value - The value to remove.
1946
- * @returns void
1947
- *
1948
- * @remarks
1949
- * If the scope does not exist or the value is not present, this is a no-op.
1950
- *
1951
- * @example
1952
- * ```ts
1953
- * presence.removeValue('users', userId)
1954
- * ```
1955
- *
1956
- * @public
1957
- */
1958
- removeValue(scope: ValuePresenceScope, value: unknown): void;
1959
- /**
1960
- * Clear values from a single scope, or from all scopes.
1961
- *
1962
- * @param scope - If provided, clears only that scope. If omitted, clears all scopes.
1963
- * @returns void
1964
- *
1965
- * @remarks
1966
- * - When called with a specific scope that does not exist, this is a no-op.
1967
- * - When called with no arguments, all scopes and values are removed.
1968
- * - Clearing a non-existent scope will not create the scope.
1969
- *
1970
- * @example
1971
- * ```ts
1972
- * // Clear one scope
1973
- * presence.reset('users')
1974
- *
1975
- * // Clear all scopes
1976
- * presence.reset()
1977
- * ```
1978
- *
1979
- * @public
1980
- */
1981
- reset(scope?: ValuePresenceScope): void;
1982
- }
1983
-
1984
- /**
1985
- * A scope identifier for grouping values.
1986
- *
1987
- * @remarks
1988
- * Use a non-empty string for a named scope. Use `undefined` for the
1989
- * "global/default" scope. An empty string (`""`) passed to the constructor
1990
- * initializer is normalized to `undefined`.
1991
- *
1992
- * @public
1993
- */
1994
- declare type ValuePresenceScope = string | undefined;
1995
-
1996
-
1997
- export * from "@contentful/optimization-api-client";
1998
-
1999
2432
  export { }