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

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.
@@ -0,0 +1,1999 @@
1
+ import { ApiClient } from '@contentful/optimization-api-client';
2
+ import { ApiClientConfig } from '@contentful/optimization-api-client';
3
+ import { batch } from '@preact/signals-core';
4
+ import type { ChainModifiers } from 'contentful';
5
+ import { ChangeArray } from '@contentful/optimization-api-client';
6
+ import { ComponentViewBuilderArgs } from '@contentful/optimization-api-client';
7
+ import { computed } from '@preact/signals-core';
8
+ import { effect } from '@preact/signals-core';
9
+ import type { Entry } from 'contentful';
10
+ import { EntryReplacementVariant } from '@contentful/optimization-api-schemas';
11
+ import { EntryReplacementVariant as EntryReplacementVariant_2 } from '@contentful/optimization-api-client';
12
+ import type { EntrySkeletonType } from 'contentful';
13
+ import { EventBuilder } from '@contentful/optimization-api-client';
14
+ import { EventBuilderConfig } from '@contentful/optimization-api-client';
15
+ 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';
20
+ import { GlobalApiConfigProperties } from '@contentful/optimization-api-client';
21
+ import { IdentifyBuilderArgs } from '@contentful/optimization-api-client';
22
+ 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';
26
+ 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';
31
+ import { PageViewBuilderArgs } from '@contentful/optimization-api-client';
32
+ import { PartialProfile } from '@contentful/optimization-api-client';
33
+ import { PersonalizationEntry } from '@contentful/optimization-api-schemas';
34
+ import { PersonalizationEntry as PersonalizationEntry_2 } from '@contentful/optimization-api-client';
35
+ 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';
38
+ import { ReadonlySignal } from '@preact/signals-core';
39
+ import { ScreenViewBuilderArgs } from '@contentful/optimization-api-client';
40
+ import { SelectedPersonalization } from '@contentful/optimization-api-client';
41
+ import { SelectedPersonalization as SelectedPersonalization_2 } from '@contentful/optimization-api-schemas';
42
+ import { SelectedPersonalizationArray } from '@contentful/optimization-api-client';
43
+ import { Signal } from '@preact/signals-core';
44
+ import { TrackBuilderArgs } from '@contentful/optimization-api-client';
45
+ import { untracked } from '@preact/signals-core';
46
+
47
+ /**
48
+ * Base class for analytics implementations (internal).
49
+ *
50
+ * @internal
51
+ * @remarks
52
+ * Concrete analytics classes should implement the component/flag view tracking
53
+ * methods below. This base is not part of the public API.
54
+ */
55
+ declare abstract class AnalyticsBase extends ProductBase {
56
+ /**
57
+ * Track a UI component view event.
58
+ *
59
+ * @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
64
+ */
65
+ abstract trackComponentView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void> | void;
66
+ /**
67
+ * Track a flag (feature) view event.
68
+ *
69
+ * @param payload - Flag view builder arguments.
70
+ * @param duplicationScope - Optional string used to scope duplication used in Stateful
71
+ * implementations.
72
+ * @returns A promise that resolves when processing is complete (or `void`).
73
+ * @privateRemarks
74
+ * Duplication prevention should be handled in Stateful implementations
75
+ */
76
+ abstract trackFlagView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void> | void;
77
+ }
78
+
79
+ /**
80
+ * Configuration for the stateful analytics implementation.
81
+ *
82
+ * @public
83
+ */
84
+ export declare interface AnalyticsProductConfig extends ProductConfig {
85
+ /**
86
+ * Default signal values applied on initialization.
87
+ */
88
+ defaults?: AnalyticsProductConfigDefaults;
89
+ }
90
+
91
+ /**
92
+ * Default analytics state values applied at construction time.
93
+ *
94
+ * @public
95
+ */
96
+ export declare interface AnalyticsProductConfigDefaults {
97
+ /** Whether analytics collection is allowed by default. */
98
+ consent?: boolean;
99
+ /** Default profile to associate with events. */
100
+ profile?: Profile;
101
+ }
102
+
103
+ /**
104
+ * Analytics implementation that maintains local state (consent, profile) and
105
+ * queues events until flushed or the queue reaches a maximum size.
106
+ *
107
+ * @public
108
+ */
109
+ export declare class AnalyticsStateful extends AnalyticsBase implements ConsentGuard {
110
+ /** In‑memory queue keyed by profile. */
111
+ private readonly queue;
112
+ /** Exposed observable state references. */
113
+ readonly states: AnalyticsStates;
114
+ /**
115
+ * Create a new stateful analytics instance.
116
+ *
117
+ * @param options - Options to configure the analytics product for stateful environments.
118
+ */
119
+ constructor(options: AnalyticsStatefulOptions);
120
+ /**
121
+ * Reset analytics‑related signals and the last emitted event.
122
+ */
123
+ reset(): void;
124
+ /**
125
+ * Determine whether the named operation is permitted based on consent and
126
+ * allowed event type configuration.
127
+ *
128
+ * @param name - The method name; `'trackComponentView'` is normalized
129
+ * to `'component'` for allow‑list checks.
130
+ * @returns `true` if the operation is permitted; otherwise `false`.
131
+ */
132
+ hasConsent(name: string): boolean;
133
+ /**
134
+ * Hook invoked when an operation is blocked due to missing consent.
135
+ *
136
+ * @param name - The blocked operation name.
137
+ * @param payload - The original arguments supplied to the operation.
138
+ */
139
+ onBlockedByConsent(name: string, payload: unknown[]): void;
140
+ /**
141
+ * Guard used to suppress duplicate component/flag view events based on a
142
+ * duplication key and the component identifier.
143
+ *
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.
147
+ */
148
+ isNotDuplicated(_name: string, payload: [ComponentViewBuilderArgs, string]): boolean;
149
+ /**
150
+ * Hook invoked when an operation is blocked by the duplication guard.
151
+ *
152
+ * @param name - The blocked operation name.
153
+ * @param payload - The original arguments supplied to the operation.
154
+ */
155
+ onBlockedByDuplication(name: string, payload: unknown[]): void;
156
+ /**
157
+ * Queue a component view event for the active profile.
158
+ *
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
162
+ */
163
+ trackComponentView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<void>;
164
+ /**
165
+ * Queue a flag view event for the active profile.
166
+ *
167
+ * @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
170
+ */
171
+ trackFlagView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<void>;
172
+ /**
173
+ * Intercept, validate, and place an event into the profile‑scoped queue; then
174
+ * trigger a size‑based flush if necessary.
175
+ *
176
+ * @param event - The event to enqueue.
177
+ */
178
+ private enqueueEvent;
179
+ /**
180
+ * Flush the queue automatically when the total number of queued events
181
+ * reaches {@link MAX_QUEUED_EVENTS}.
182
+ */
183
+ private flushMaxEvents;
184
+ /**
185
+ * Send all queued events grouped by profile and clear the queue.
186
+ * @remarks Only under rare circumstances should there be more than one
187
+ * profile in a stateful application.
188
+ */
189
+ flush(): Promise<void>;
190
+ }
191
+
192
+ /**
193
+ * Options for configuring {@link AnalyticsStateful} functionality.
194
+ *
195
+ * @public
196
+ * @see {@link ProductBaseOptions}
197
+ */
198
+ export declare type AnalyticsStatefulOptions = ProductBaseOptions & {
199
+ /** Configuration specific to the Analytics product */
200
+ config?: AnalyticsProductConfig;
201
+ };
202
+
203
+ /**
204
+ * Stateless analytics implementation that sends each event immediately in a
205
+ * single‑event batch.
206
+ *
207
+ * @public
208
+ */
209
+ export declare class AnalyticsStateless extends AnalyticsBase {
210
+ /**
211
+ * Build, intercept, validate, and send a component view event.
212
+ *
213
+ * @param args - {@link TrackViewArgs} used to build the event. Includes an
214
+ * optional partial profile.
215
+ * @returns A promise that resolves once the batch has been sent.
216
+ */
217
+ trackComponentView(args: TrackViewArgs): Promise<void>;
218
+ /**
219
+ * Build, intercept, validate, and send a flag view event.
220
+ *
221
+ * @param args - {@link TrackViewArgs} used to build the event. Includes an
222
+ * optional partial profile.
223
+ * @returns A promise that resolves once the batch has been sent.
224
+ */
225
+ trackFlagView(args: TrackViewArgs): Promise<void>;
226
+ /**
227
+ * Send a single {@link InsightsEvent} wrapped in a one‑item batch.
228
+ *
229
+ * @param event - The event to send.
230
+ * @param profile - Optional partial profile to attach to the batch.
231
+ * @returns A promise that resolves when the API call completes.
232
+ * @internal
233
+ */
234
+ private sendBatchEvent;
235
+ }
236
+
237
+ /**
238
+ * Observables exposed by the stateful analytics product.
239
+ *
240
+ * @public
241
+ */
242
+ export declare interface AnalyticsStates {
243
+ /** Observable stream of the latest {@link AnalyticsEvent} or {@link PersonalizationEvent} (or `undefined`). */
244
+ eventStream: Observable<InsightsEvent | ExperienceEvent | undefined>;
245
+ /** Observable stream of the active {@link Profile} (or `undefined`). */
246
+ profile: Observable<Profile | undefined>;
247
+ }
248
+
249
+ /**
250
+ * Anonymous-ID cookie name used by the Optimization Core.
251
+ *
252
+ * @public
253
+ * @remarks
254
+ * This constant represents the cookie key used by the Optimization Framework
255
+ * to persist an anonymous identifier for tracking personalization and analytics
256
+ * events when no explicit profile is known.
257
+ *
258
+ * @example
259
+ * ```ts
260
+ * import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core'
261
+ * const profileId = request.cookies[ANONYMOUS_ID_COOKIE]
262
+ * ```
263
+ */
264
+ export declare const ANONYMOUS_ID_COOKIE = "ctfl-opt-aid";
265
+
266
+ /**
267
+ * Legacy anoynmous ID cookie key for migration from experience.js
268
+ *
269
+ * @internal
270
+ */
271
+ export declare const ANONYMOUS_ID_COOKIE_LEGACY = "ntaid";
272
+
273
+ /**
274
+ * Storage key for the anonymous identifier.
275
+ *
276
+ * @internal
277
+ */
278
+ export declare const ANONYMOUS_ID_KEY = "__ctfl_opt_anonymous_id__";
279
+
280
+ /**
281
+ * Legacy anoynmous ID storage key for migration from experience.js
282
+ *
283
+ * @internal
284
+ */
285
+ export declare const ANONYMOUS_ID_KEY_LEGACY = "__nt_anonymous_id__";
286
+
287
+ export { batch }
288
+
289
+ /**
290
+ * A callback invoked when a method call is blocked by {@link guardedBy}.
291
+ *
292
+ * @param methodName - The name of the method that was attempted.
293
+ * @param args - The readonly array of arguments supplied to the blocked call.
294
+ * @returns Nothing.
295
+ *
296
+ * @public
297
+ */
298
+ declare type BlockHandler = (methodName: string, args: readonly unknown[]) => void;
299
+
300
+ declare const changes: Signal<ChangeArray | undefined>;
301
+
302
+ /**
303
+ * Storage key for cached Custom Flags.
304
+ *
305
+ * @internal
306
+ */
307
+ export declare const CHANGES_CACHE_KEY = "__ctfl_opt_changes__";
308
+
309
+ declare const consent: Signal<boolean | undefined>;
310
+
311
+ /**
312
+ * Storage key for the persisted consent status.
313
+ *
314
+ * @internal
315
+ */
316
+ export declare const CONSENT_KEY = "__ctfl_opt_consent__";
317
+
318
+ /**
319
+ * Controller for updating the current consent state.
320
+ *
321
+ * @internal
322
+ * @remarks
323
+ * Intended for internal wiring between Core classes and the consent signal/store.
324
+ */
325
+ declare interface ConsentController {
326
+ /**
327
+ * Update the runtime consent state.
328
+ *
329
+ * @param accept - `true` when the user has granted consent; `false` otherwise.
330
+ */
331
+ consent: (accept: boolean) => void;
332
+ }
333
+
334
+ /**
335
+ * Contract implemented by classes that gate operations based on consent.
336
+ *
337
+ * @internal
338
+ * @remarks
339
+ * These methods are consumed by the `@guardedBy` decorator to decide whether to
340
+ * proceed with an operation and how to report blocked calls.
341
+ */
342
+ declare interface ConsentGuard {
343
+ /**
344
+ * Determine whether the named operation is permitted given current consent and
345
+ * any allow‑list configuration.
346
+ *
347
+ * @param name - Logical operation/method name (e.g., `'track'`, `'page'`).
348
+ * @returns `true` if the operation may proceed; otherwise `false`.
349
+ * @remarks
350
+ * The mapping between method names and event type strings may be product‑specific.
351
+ */
352
+ hasConsent: (name: string) => boolean;
353
+ /**
354
+ * Hook invoked when an operation is blocked due to missing consent.
355
+ *
356
+ * @param name - The blocked operation/method name.
357
+ * @param args - The original call arguments, provided for diagnostics/telemetry.
358
+ * @returns Nothing. Implementations typically log and/or emit diagnostics.
359
+ */
360
+ onBlockedByConsent: (name: string, args: unknown[]) => void;
361
+ }
362
+
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
+ /**
371
+ * Internal base that wires the API client, event builder, and logging.
372
+ *
373
+ * @internal
374
+ */
375
+ declare abstract class CoreBase {
376
+ /** Product implementation for analytics. */
377
+ abstract readonly analytics: AnalyticsBase;
378
+ /** Product implementation for personalization. */
379
+ abstract readonly personalization: PersonalizationBase;
380
+ /** Shared Optimization API client instance. */
381
+ readonly api: ApiClient;
382
+ /** Shared event builder instance. */
383
+ readonly eventBuilder: EventBuilder;
384
+ /** Resolved core configuration (minus any name metadata). */
385
+ readonly config: Omit<CoreConfig, 'name'>;
386
+ readonly interceptors: LifecycleInterceptors;
387
+ /**
388
+ * Create the core with API client and logging preconfigured.
389
+ *
390
+ * @param config - Core configuration including API and builder options.
391
+ * @example
392
+ * ```ts
393
+ * const sdk = new CoreStateless({ clientId: 'abc123', environment: 'prod' })
394
+ * ```
395
+ */
396
+ constructor(config: CoreConfig);
397
+ /**
398
+ * Get the value of a custom flag derived from a set of optimization changes.
399
+ *
400
+ * @param name - The flag key to resolve.
401
+ * @param changes - Optional change list to resolve from
402
+ * @returns The resolved JSON value for the flag if available.
403
+ * @remarks
404
+ * This is a convenience wrapper around personalization’s flag resolution.
405
+ */
406
+ getCustomFlag(name: string, changes?: ChangeArray): Json;
407
+ /**
408
+ * Resolve a Contentful entry to the appropriate personalized variant (or
409
+ * return the baseline entry if no matching variant is selected).
410
+ *
411
+ * @typeParam S - Entry skeleton type.
412
+ * @typeParam M - Chain modifiers.
413
+ * @typeParam L - Locale code.
414
+ * @param entry - The baseline entry to resolve.
415
+ * @param personalizations - Optional selection array for the current profile.
416
+ * @returns {@link ResolvedData} containing the resolved entry and
417
+ * personalization metadata (if any).
418
+ */
419
+ personalizeEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = LocaleCode>(entry: Entry<S, M, L>, personalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
420
+ /**
421
+ * Resolve a merge-tag value from the given entry node and profile.
422
+ *
423
+ * @param embeddedEntryNodeTarget - The merge-tag entry node to resolve.
424
+ * @param profile - Optional profile used for value lookup.
425
+ * @returns The resolved value (typically a string) or `undefined` if not found.
426
+ */
427
+ getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile): unknown;
428
+ /**
429
+ * Convenience wrapper for sending an `identify` event via personalization.
430
+ *
431
+ * @param payload - Identify builder arguments.
432
+ * @returns The resulting {@link OptimizationData} for the identified user.
433
+ */
434
+ identify(payload: IdentifyBuilderArgs & {
435
+ profile?: PartialProfile;
436
+ }): Promise<OptimizationData | undefined>;
437
+ /**
438
+ * Convenience wrapper for sending a `page` event via personalization.
439
+ *
440
+ * @param payload - Page view builder arguments.
441
+ * @returns The evaluated {@link OptimizationData} for this page view.
442
+ */
443
+ page(payload: PageViewBuilderArgs & {
444
+ profile?: PartialProfile;
445
+ }): Promise<OptimizationData | undefined>;
446
+ /**
447
+ * Convenience wrapper for sending a `screen` event via personalization.
448
+ *
449
+ * @param payload - Screen view builder arguments.
450
+ * @returns The evaluated {@link OptimizationData} for this screen view.
451
+ */
452
+ screen(payload: ScreenViewBuilderArgs & {
453
+ profile?: PartialProfile;
454
+ }): Promise<OptimizationData | undefined>;
455
+ /**
456
+ * Convenience wrapper for sending a custom `track` event via personalization.
457
+ *
458
+ * @param payload - Track builder arguments.
459
+ * @returns The evaluated {@link OptimizationData} for this event.
460
+ */
461
+ track(payload: TrackBuilderArgs & {
462
+ profile?: PartialProfile;
463
+ }): Promise<OptimizationData | undefined>;
464
+ /**
465
+ * Track a component view in both personalization and analytics.
466
+ *
467
+ * @param payload - Component view builder arguments. When `payload.sticky` is
468
+ * `true`, the event will also be sent via personalization as a sticky
469
+ * component view.
470
+ * @param duplicationScope - Optional string used to scope duplication used in Stateful
471
+ * implementations
472
+ * @returns A promise that resolves when all delegated calls complete.
473
+ * @remarks
474
+ * The sticky behavior is delegated to personalization; analytics is always
475
+ * invoked regardless of `sticky`.
476
+ */
477
+ trackComponentView(payload: ComponentViewBuilderArgs & {
478
+ profile?: PartialProfile;
479
+ }, duplicationScope?: string): Promise<OptimizationData | undefined>;
480
+ /**
481
+ * Track a feature flag view via analytics.
482
+ *
483
+ * @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
+ * @returns A promise that resolves when processing completes.
487
+ */
488
+ trackFlagView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void>;
489
+ }
490
+
491
+ /**
492
+ * Options for configuring the {@link CoreBase} runtime and underlying clients.
493
+ *
494
+ * @public
495
+ */
496
+ export declare interface CoreConfig extends Pick<ApiClientConfig, GlobalApiConfigProperties> {
497
+ /**
498
+ * Configuration for the personalization (Experience) API client.
499
+ */
500
+ personalization?: Omit<ExperienceApiClientConfig, GlobalApiConfigProperties>;
501
+ /**
502
+ * Configuration for the analytics (Insights) API client.
503
+ */
504
+ analytics?: Omit<InsightsApiClientConfig, GlobalApiConfigProperties>;
505
+ /**
506
+ * Event builder configuration (channel/library metadata, etc.).
507
+ */
508
+ eventBuilder?: EventBuilderConfig;
509
+ /** Minimum log level for the default console sink. */
510
+ logLevel?: LogLevels;
511
+ }
512
+
513
+ /**
514
+ * Default values used to preconfigure the stateful core and products.
515
+ *
516
+ * @public
517
+ */
518
+ export declare interface CoreConfigDefaults {
519
+ /** Global consent default applied at construction time. */
520
+ consent?: boolean;
521
+ /** Default active profile used for personalization and analytics. */
522
+ profile?: Profile;
523
+ /** Initial diff of changes produced by the service. */
524
+ changes?: ChangeArray;
525
+ /** Preselected personalization variants (e.g., winning treatments). */
526
+ personalizations?: SelectedPersonalizationArray;
527
+ }
528
+
529
+ /**
530
+ * Core runtime that constructs stateful product instances and exposes shared
531
+ * states, including consent and the event stream.
532
+ *
533
+ * @public
534
+ * @remarks
535
+ * @see {@link CoreBase}
536
+ * @see {@link ConsentController}
537
+ */
538
+ export declare class CoreStateful extends CoreBase implements ConsentController {
539
+ /** Stateful analytics product. */
540
+ readonly analytics: AnalyticsStateful;
541
+ /** Stateful personalization product. */
542
+ readonly personalization: PersonalizationStateful;
543
+ /**
544
+ * Create a stateful core with optional default consent and product defaults.
545
+ *
546
+ * @param config - Core and defaults configuration.
547
+ * @example
548
+ * ```ts
549
+ * const core = new CoreStateful({
550
+ * clientId: 'app',
551
+ * environment: 'prod',
552
+ * defaults: { consent: true }
553
+ * })
554
+ * core.consent(true)
555
+ * ```
556
+ */
557
+ constructor(config: CoreStatefulConfig);
558
+ /**
559
+ * Expose merged observable state for consumers.
560
+ */
561
+ get states(): CoreStates;
562
+ /**
563
+ * Reset internal state. Consent is intentionally preserved.
564
+ *
565
+ * @remarks
566
+ * Resetting personalization also resets analytics dependencies as a
567
+ * consequence of the current shared-state design.
568
+ */
569
+ reset(): void;
570
+ /**
571
+ * Flush the queues for both the analytics and personalization products.
572
+ * @remarks
573
+ * The personalization queue is only populated if events have been triggered
574
+ * while a device is offline.
575
+ */
576
+ flush(): Promise<void>;
577
+ /**
578
+ * Update consent state
579
+ *
580
+ * @param accept - `true` if the user has granted consent; `false` otherwise.
581
+ */
582
+ consent(accept: boolean): void;
583
+ /**
584
+ * Update online state
585
+ *
586
+ * @param isOnline - `true` if the browser is online; `false` otherwise.
587
+ */
588
+ protected online(isOnline: boolean): void;
589
+ /**
590
+ * Register a preview panel compatible object to receive direct signal access.
591
+ * This enables the preview panel to modify SDK state for testing and simulation.
592
+ *
593
+ * @param previewPanel - An object implementing PreviewPanelSignalObject
594
+ * @remarks
595
+ * This method is intended for use by the Preview Panel component.
596
+ * Direct signal access allows immediate state updates without API calls.
597
+ */
598
+ registerPreviewPanel(previewPanel?: PreviewPanelSignalObject): PreviewPanelSignalObject;
599
+ }
600
+
601
+ /**
602
+ * Configuration for {@link CoreStateful}.
603
+ *
604
+ * @public
605
+ * @see {@link CoreConfig}
606
+ */
607
+ export declare interface CoreStatefulConfig extends CoreConfig {
608
+ /**
609
+ * Allow-listed event type strings permitted when consent is not set.
610
+ *
611
+ * @see {@link ProductConfig.allowedEventTypes}
612
+ */
613
+ allowedEventTypes?: ProductConfig['allowedEventTypes'];
614
+ /** Optional set of default values applied on initialization. */
615
+ defaults?: CoreConfigDefaults;
616
+ /** Function used to obtain an anonymous user identifier. */
617
+ getAnonymousId?: PersonalizationProductConfig['getAnonymousId'];
618
+ /**
619
+ * Initial duplication prevention configuration for component events.
620
+ *
621
+ * @see {@link ProductConfig.preventedComponentEvents}
622
+ */
623
+ preventedComponentEvents?: ProductConfig['preventedComponentEvents'];
624
+ }
625
+
626
+ /**
627
+ * Core runtime that constructs product instances for stateless environments.
628
+ *
629
+ * @public
630
+ * @see {@link CoreBase}
631
+ */
632
+ export declare class CoreStateless extends CoreBase {
633
+ /** Stateless analytics product. */
634
+ readonly analytics: AnalyticsStateless;
635
+ /** Stateless personalization product. */
636
+ readonly personalization: PersonalizationStateless;
637
+ /**
638
+ * Create a stateless core. Product instances share the same API client and
639
+ * event builder configured in {@link CoreBase}.
640
+ *
641
+ * @param config - Stateless Core configuration.
642
+ * @example
643
+ * ```ts
644
+ * const sdk = new CoreStateless({ clientId: 'app', environment: 'prod' })
645
+ * core.analytics.trackFlagView({ componentId: 'hero' })
646
+ * // or
647
+ * core.trackFlagView({ componentId: 'hero' })
648
+ * ```
649
+ */
650
+ constructor(config: CoreStatelessConfig);
651
+ }
652
+
653
+ /**
654
+ * Configuration for the Node-specific Optimization SDK.
655
+ *
656
+ * @public
657
+ * @remarks
658
+ * This configuration extends {@link CoreConfig} but allows partial overrides
659
+ * of the event-builder configuration. SDKs commonly inject their own library
660
+ * metadata or channel definitions.
661
+ */
662
+ export declare interface CoreStatelessConfig extends CoreConfig {
663
+ /**
664
+ * Override configuration for the analytics (Insights) API client. Omits
665
+ * `beaconHandler`.
666
+ */
667
+ analytics?: Omit<CoreConfig['analytics'], 'beaconHandler'>;
668
+ /**
669
+ * Overrides for the event builder configuration. Omits methods that are only
670
+ * useful in stateful environments.
671
+ */
672
+ eventBuilder?: Omit<EventBuilderConfig, 'getLocale' | 'getPageProperties' | 'getUserAgent'>;
673
+ }
674
+
675
+ /**
676
+ * Combined observable state exposed by the stateful core.
677
+ *
678
+ * @public
679
+ * @see {@link AnalyticsStates}
680
+ * @see {@link PersonalizationStates}
681
+ */
682
+ export declare interface CoreStates extends AnalyticsStates, PersonalizationStates {
683
+ /** Current consent value (if any). */
684
+ consent: Observable<boolean | undefined>;
685
+ /** Stream of the most recent event emitted (analytics or personalization). */
686
+ eventStream: Observable<InsightsEvent | ExperienceEvent | undefined>;
687
+ }
688
+
689
+ export declare function createScopedLogger(location: string): ScopedLogger;
690
+
691
+ /**
692
+ * Storage key for the debug flag toggle.
693
+ *
694
+ * @internal
695
+ */
696
+ export declare const DEBUG_FLAG_KEY = "__ctfl_opt_debug__";
697
+
698
+ export { effect }
699
+
700
+ declare const event_2: Signal<InsightsEvent | ExperienceEvent | undefined>;
701
+
702
+ /**
703
+ * Union of all event {@link AnalyticsEventType | type keys} that this package may emit.
704
+ *
705
+ * @public
706
+ */
707
+ declare type EventType = InsightsEventType | ExperienceEventType;
708
+
709
+ declare const flags: ReadonlySignal<Flags | undefined>;
710
+
711
+ /**
712
+ * Resolves a {@link Flags} map from a list of optimization changes.
713
+ *
714
+ * @public
715
+ * @remarks
716
+ * Given an Optimization {@link ChangeArray}, this utility flattens the list into a
717
+ * simple key–value object suitable for quick lookups in client code. When `changes`
718
+ * is `undefined`, an empty object is returned. If a change value is wrapped in an
719
+ * object like `{ value: { ... } }`, this resolver unwraps it to the underlying object.
720
+ */
721
+ export declare const FlagsResolver: {
722
+ /**
723
+ * Build a flattened map of flag keys to values from a change list.
724
+ *
725
+ * @param changes - The change list returned by the optimization service.
726
+ * @returns A map of flag keys to their resolved values.
727
+ * @example
728
+ * ```ts
729
+ * const flags = FlagsResolver.resolve(data.changes)
730
+ * if (flags['theme'] === 'dark') enableDarkMode()
731
+ * ```
732
+ * @example
733
+ * // Handles wrapped values produced by the API
734
+ * ```ts
735
+ * const flags = FlagsResolver.resolve([
736
+ * { type: 'Variable', key: 'price', value: { value: { amount: 10, currency: 'USD' } } }
737
+ * ])
738
+ * console.log(flags.price.amount) // 10
739
+ * ```
740
+ */
741
+ resolve(changes?: ChangeArray): Flags;
742
+ };
743
+
744
+ /**
745
+ * Decorator factory that **guards** class methods behind a synchronous predicate.
746
+ *
747
+ * When a decorated method is invoked:
748
+ * - If the predicate returns a value that evaluates to **allowed** (see `invert`), the original
749
+ * method is executed and its result is returned.
750
+ * - If the call is **blocked**, the optional `onBlocked` hook is invoked (if configured) and:
751
+ * - `undefined` is returned for sync methods; or
752
+ * - `Promise<undefined>` is returned for async methods (to preserve `await` compatibility).
753
+ *
754
+ * @typeParam T - The instance type that owns both the predicate and the decorated method.
755
+ *
756
+ * @param predicateName - The name (string or symbol) of a **synchronous** instance method on `this`
757
+ * that acts as the predicate. It is called as `this[predicateName](methodName, argsArray)`.
758
+ * @param opts - Optional {@link GuardedByOptions | options} to configure inversion and `onBlocked`.
759
+ *
760
+ * @returns A methods-only class decorator compatible with Stage-3 decorators that wraps the method.
761
+ *
762
+ * @throws TypeError
763
+ * Thrown at initialization time (first instance construction) if `predicateName` does not resolve
764
+ * to a **synchronous function** on the instance.
765
+ *
766
+ * @remarks
767
+ * - This is a **methods-only** decorator; applying it to accessors/fields is a no-op.
768
+ * - The decorator preserves the original method's sync/async shape.
769
+ * - The predicate is invoked with `(decoratedMethodName, argsArray)` to support context-aware checks.
770
+ *
771
+ * @example
772
+ * Here, `canRun` allows the call when it returns truthy:
773
+ * ```ts
774
+ * class Runner {
775
+ * canRun(method: string, _args: readonly unknown[]) { return method !== 'stop'; }
776
+ *
777
+ * @guardedBy<Runner>('canRun')
778
+ * go() { console.log('running'); }
779
+ * }
780
+ * ```
781
+ *
782
+ * @example
783
+ * Invert the predicate and call a handler on block:
784
+ * ```ts
785
+ * class Door {
786
+ * isLocked() { return true } // truthy means "locked"
787
+ * onBlocked(method: string) { console.warn(`${method} blocked`) }
788
+ *
789
+ * @guardedBy<Door>('isLocked', { invert: true, onBlocked: 'onBlocked' })
790
+ * open() { /* ... *\/ }
791
+ * }
792
+ * ```
793
+ *
794
+ * @public
795
+ */
796
+ export declare function guardedBy<T extends object>(predicateName: keyof T & (string | symbol), opts?: GuardedByOptions<T>): GuardedByFunction<T>;
797
+
798
+ /**
799
+ * The original method implementation.
800
+ *
801
+ * @typeParam A - The parameter tuple of the original method.
802
+ * @typeParam R - The return type of the original method.
803
+ * @param value - The method being decorated.
804
+ * @param context - The Stage-3 decorator context for a class method.
805
+ * @returns Nothing.
806
+ *
807
+ * @remarks
808
+ * Users do not call this directly; it's returned by {@link guardedBy}.
809
+ */
810
+ declare type GuardedByFunction<T extends object> = <A extends readonly unknown[], R>(value: (...args: A) => R, context: ClassMethodDecoratorContext<T, (...args: A) => R>) => void;
811
+
812
+ /**
813
+ * Options that tweak the behavior of {@link guardedBy}.
814
+ *
815
+ * @typeParam T - The instance type on which the decorator is applied.
816
+ *
817
+ * @public
818
+ */
819
+ declare interface GuardedByOptions<T extends object> {
820
+ /**
821
+ * Inverts the predicate result.
822
+ *
823
+ * When `true`, a truthy predicate result **blocks** the method.
824
+ * When `false` (default) or omitted, a truthy predicate result **allows** the method.
825
+ *
826
+ * @defaultValue `false`
827
+ * @remarks
828
+ * This option is useful when the predicate expresses a *forbid* condition
829
+ * (e.g. "isLocked" or "isDestroyed") rather than an *allow* condition.
830
+ */
831
+ readonly invert?: boolean;
832
+ /**
833
+ * Either a function to call when a method is blocked, or the name/symbol of
834
+ * an instance method on `this` to call when blocked.
835
+ *
836
+ * Both forms are **synchronous** and receive `(methodName, argsArray)`.
837
+ * If omitted, blocked calls fail silently (i.e., return `undefined` or
838
+ * `Promise<undefined>` for async methods).
839
+ *
840
+ * @remarks
841
+ * - If a property key is supplied and the instance does not have a callable at that key,
842
+ * the hook is ignored.
843
+ * - The hook **must not** be `async`; any async work should be scheduled manually.
844
+ */
845
+ readonly onBlocked?: BlockHandler | (keyof T & (string | symbol));
846
+ }
847
+
848
+ /**
849
+ * A function that receives a value of type `T` and returns a (possibly async)
850
+ * value of the same type `T`. The input is marked as `readonly` to discourage
851
+ * mutation of the original object.
852
+ *
853
+ * @typeParam T - The value type intercepted and returned.
854
+ * @param value - The current (readonly) value in the interception chain.
855
+ * @returns The next value for the chain, either directly or via a promise.
856
+ * @remarks Implementations SHOULD avoid mutating `value` and instead return a
857
+ * new or safely-updated instance.
858
+ * @see {@link InterceptorManager}
859
+ * @public
860
+ */
861
+ export declare type Interceptor<T> = (value: Readonly<T>) => MaybePromise<T>;
862
+
863
+ /**
864
+ * Manages a list of interceptors and provides a way to run them in sequence.
865
+ *
866
+ * Interceptors are executed in insertion order. Each interceptor receives the
867
+ * result of the previous interceptor (or the initial input for the first one)
868
+ * and may return a new value synchronously or asynchronously.
869
+ *
870
+ * @typeParam T - The value type processed by the interceptors.
871
+ * @remarks This class snapshots the current interceptor list at invocation time
872
+ * so additions/removals during `run` do not affect the in-flight execution.
873
+ * @example
874
+ * ```ts
875
+ * const mgr = new InterceptorManager<number>();
876
+ * const id = mgr.add((n) => n + 1);
877
+ * const final = await mgr.run(1); // 2
878
+ * mgr.remove(id);
879
+ * ```
880
+ * @public
881
+ */
882
+ export declare class InterceptorManager<T> {
883
+ /**
884
+ * The registry of interceptors keyed by their insertion id.
885
+ *
886
+ * @privateRemarks Internal storage; use {@link add}, {@link remove}, and
887
+ * {@link clear} to manage contents.
888
+ * @readonly
889
+ * @defaultValue `new Map()`
890
+ */
891
+ private readonly interceptors;
892
+ /**
893
+ * The next numeric id to assign to an added interceptor.
894
+ *
895
+ * @privateRemarks Used only to generate unique, monotonically increasing ids.
896
+ * @defaultValue `0`
897
+ */
898
+ private nextId;
899
+ /**
900
+ * Add an interceptor and return its identifier.
901
+ *
902
+ * @param interceptor - The interceptor function to register.
903
+ * @returns The numeric id that can later be used with {@link remove}.
904
+ * @remarks Interceptors are executed in the order they are added.
905
+ * @example
906
+ * ```ts
907
+ * const id = manager.add(async (value) => transform(value));
908
+ * ```
909
+ * @public
910
+ */
911
+ add(interceptor: Interceptor<T>): number;
912
+ /**
913
+ * Remove an interceptor by its identifier.
914
+ *
915
+ * @param id - The id previously returned by {@link add}.
916
+ * @returns `true` if an interceptor was removed; otherwise `false`.
917
+ * @example
918
+ * ```ts
919
+ * const removed = manager.remove(id);
920
+ * ```
921
+ * @public
922
+ */
923
+ remove(id: number): boolean;
924
+ /**
925
+ * Remove all registered interceptors.
926
+ *
927
+ * @returns Nothing.
928
+ * @remarks After calling this, {@link count} will return `0`.
929
+ * @example
930
+ * ```ts
931
+ * manager.clear();
932
+ * ```
933
+ * @public
934
+ */
935
+ clear(): void;
936
+ /**
937
+ * Get the number of currently registered interceptors.
938
+ *
939
+ * @returns The count of interceptors.
940
+ * @example
941
+ * ```ts
942
+ * if (manager.count() === 0) { /* ... *\/ }
943
+ * ```
944
+ * @public
945
+ */
946
+ count(): number;
947
+ /**
948
+ * Run all interceptors in sequence on an input value and return the final result.
949
+ *
950
+ * Supports both sync and async interceptors; the return type is always `Promise<T>`
951
+ * for consistency.
952
+ *
953
+ * @param input - The initial value to pass to the first interceptor.
954
+ * @returns A promise resolving to the final value after all interceptors have run.
955
+ * @throws May rethrow any error thrown by an interceptor. <!-- Intentionally vague: error type depends on interceptor implementation -->
956
+ * @remarks The interceptor list is snapshotted at invocation time; changes to
957
+ * the registry during execution do not affect the running sequence.
958
+ * @example
959
+ * ```ts
960
+ * const result = await manager.run(initial);
961
+ * ```
962
+ * @public
963
+ */
964
+ run(input: T): Promise<T>;
965
+ }
966
+
967
+ /**
968
+ * Lifecycle container for event and state interceptors.
969
+ *
970
+ * @public
971
+ */
972
+ export declare interface LifecycleInterceptors {
973
+ /** Interceptors invoked for individual events prior to validation/sending. */
974
+ event: InterceptorManager<InsightsEvent | ExperienceEvent>;
975
+ /** Interceptors invoked before optimization state updates. */
976
+ state: InterceptorManager<OptimizationData>;
977
+ }
978
+
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
+ /**
1011
+ * A utility type representing a value that may be synchronously available or
1012
+ * produced asynchronously.
1013
+ *
1014
+ * @typeParam T - The resolved value type.
1015
+ * @public
1016
+ */
1017
+ declare type MaybePromise<T> = T | Promise<T>;
1018
+
1019
+ /**
1020
+ * Resolves merge tag values from a {@link Profile}.
1021
+ *
1022
+ * @public
1023
+ * @remarks
1024
+ * *Merge tags* are references to user profile data that may be embedded in content
1025
+ * and expanded at runtime. This resolver normalizes the merge-tag identifier into
1026
+ * a set of candidate selectors and searches the profile for a matching value.
1027
+ * Result values are returned as strings; numeric/boolean primitives are stringified.
1028
+ */
1029
+ 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
+ /**
1044
+ * Generate a list of candidate selectors for a merge-tag ID.
1045
+ *
1046
+ * @param id - Merge-tag identifier (segments separated by `_`).
1047
+ * @returns Array of dot-path selectors to try against a profile.
1048
+ * @example
1049
+ * ```ts
1050
+ * // "profile_name_first" -> [
1051
+ * // 'profile',
1052
+ * // 'profile.name',
1053
+ * // 'profile.name.first'
1054
+ * // ]
1055
+ * const selectors = MergeTagValueResolver.normalizeSelectors('profile_name_first')
1056
+ * ```
1057
+ */
1058
+ normalizeSelectors(id: string): string[];
1059
+ /**
1060
+ * Look up a merge-tag value from a profile using normalized selectors.
1061
+ *
1062
+ * @param id - Merge-tag identifier.
1063
+ * @param profile - Profile from which to resolve the value.
1064
+ * @returns A stringified primitive if found; otherwise `undefined`.
1065
+ * @example
1066
+ * ```ts
1067
+ * const value = MergeTagValueResolver.getValueFromProfile('user_email', profile)
1068
+ * if (value) sendEmailTo(value)
1069
+ * ```
1070
+ * @remarks
1071
+ * Only string/number/boolean primitives are returned; objects/arrays are ignored.
1072
+ */
1073
+ getValueFromProfile(id: string, profile?: Profile): string | undefined;
1074
+ /**
1075
+ * Resolve the display value for a merge-tag entry using the provided profile,
1076
+ * falling back to the entry's configured `nt_fallback` when necessary.
1077
+ *
1078
+ * @param mergeTagEntry - The merge-tag entry to resolve.
1079
+ * @param profile - Optional profile used for lookup.
1080
+ * @returns The resolved string, or `undefined` if the entry is invalid and no
1081
+ * fallback is available.
1082
+ * @example
1083
+ * ```ts
1084
+ * const text = MergeTagValueResolver.resolve(entry, profile)
1085
+ * render(text ?? 'Guest')
1086
+ * ```
1087
+ */
1088
+ resolve(mergeTagEntry: MergeTagEntry | undefined, profile?: Profile): string | undefined;
1089
+ };
1090
+
1091
+ declare interface Observable<T> {
1092
+ subscribe: (next: (v: T) => void) => Subscription;
1093
+ }
1094
+
1095
+ declare const online: Signal<boolean | undefined>;
1096
+
1097
+ export declare const OPTIMIZATION_CORE_SDK_NAME: string;
1098
+
1099
+ export declare const OPTIMIZATION_CORE_SDK_VERSION: string;
1100
+
1101
+ /**
1102
+ * Internal base for personalization products.
1103
+ *
1104
+ * @internal
1105
+ * @remarks
1106
+ * Concrete implementations should extend this class to expose public methods for
1107
+ * identify, page, and track events. This base wires in shared singleton
1108
+ * resolvers used to fetch/resolve personalized data.
1109
+ */
1110
+ declare abstract class PersonalizationBase extends ProductBase implements ResolverMethods {
1111
+ /**
1112
+ * Static {@link FlagsResolver | resolver} for evaluating personalized
1113
+ * custom flags.
1114
+ */
1115
+ readonly flagsResolver: {
1116
+ resolve(changes?: ChangeArray): Flags_2;
1117
+ };
1118
+ /**
1119
+ * Static {@link MergeTagValueResolver | resolver} that returns values
1120
+ * sourced from a user profile based on a Contentful Merge Tag entry.
1121
+ */
1122
+ readonly mergeTagValueResolver: {
1123
+ isMergeTagEntry(embeddedEntryNodeTarget: unknown): embeddedEntryNodeTarget is MergeTagEntry;
1124
+ normalizeSelectors(id: string): string[];
1125
+ getValueFromProfile(id: string, profile?: Profile): string | undefined;
1126
+ resolve(mergeTagEntry: MergeTagEntry | undefined, profile?: Profile): string | undefined;
1127
+ };
1128
+ /**
1129
+ * Static {@link PersonalizedEntryResolver | resolver } for personalized
1130
+ * Contentful entries (e.g., entry variants targeted to a profile audience).
1131
+ *
1132
+ * @remarks
1133
+ * Used by higher-level personalization flows to materialize entry content
1134
+ * prior to event emission.
1135
+ */
1136
+ readonly personalizedEntryResolver: {
1137
+ getPersonalizationEntry({ personalizedEntry, selectedPersonalizations, }: {
1138
+ personalizedEntry: PersonalizedEntry;
1139
+ selectedPersonalizations: SelectedPersonalizationArray;
1140
+ }, skipValidation?: boolean): PersonalizationEntry | undefined;
1141
+ getSelectedPersonalization({ personalizationEntry, selectedPersonalizations, }: {
1142
+ personalizationEntry: PersonalizationEntry;
1143
+ selectedPersonalizations: SelectedPersonalizationArray;
1144
+ }, skipValidation?: boolean): SelectedPersonalization_2 | undefined;
1145
+ getSelectedVariant({ personalizedEntry, personalizationEntry, selectedVariantIndex, }: {
1146
+ personalizedEntry: PersonalizedEntry;
1147
+ personalizationEntry: PersonalizationEntry;
1148
+ selectedVariantIndex: number;
1149
+ }, skipValidation?: boolean): EntryReplacementVariant | undefined;
1150
+ getSelectedVariantEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>({ personalizationEntry, selectedVariant, }: {
1151
+ personalizationEntry: PersonalizationEntry;
1152
+ selectedVariant: EntryReplacementVariant;
1153
+ }, skipValidation?: boolean): Entry<S, M, L> | undefined;
1154
+ resolve<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>(entry: Entry<S, M, L>, selectedPersonalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
1155
+ };
1156
+ /**
1157
+ * Get the specified Custom Flag's value from the supplied changes.
1158
+ * @param name - The name/key of the Custom Flag.
1159
+ * @param changes - Optional changes array.
1160
+ * @returns The current value of the Custom Flag if found.
1161
+ * @remarks
1162
+ * The changes array can be sourced from the data returned when emitting any
1163
+ * personalization event.
1164
+ * */
1165
+ getCustomFlag(name: string, changes?: ChangeArray): Json;
1166
+ /**
1167
+ * Resolve a Contentful entry to a personalized variant using the current
1168
+ * or provided selected personalizations.
1169
+ *
1170
+ * @typeParam S - Entry skeleton type.
1171
+ * @typeParam M - Chain modifiers.
1172
+ * @typeParam L - Locale code.
1173
+ * @param entry - The entry to personalize.
1174
+ * @param personalizations - Optional selected personalizations.
1175
+ * @returns The resolved entry data.
1176
+ * @remarks
1177
+ * Selected personalizations can be sourced from the data returned when emitting any
1178
+ * personalization event.
1179
+ */
1180
+ personalizeEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = LocaleCode>(entry: Entry<S, M, L>, personalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
1181
+ /**
1182
+ * Resolve a merge tag to a value based on the current (or provided) profile.
1183
+ *
1184
+ * @param embeddedEntryNodeTarget - The merge tag entry node to resolve.
1185
+ * @param profile - Optional profile.
1186
+ * @returns The resolved value (type depends on the tag).
1187
+ * @remarks
1188
+ * Merge tags are references to profile data that can be substituted into content. The
1189
+ * profile can be sourced from the data returned when emitting any personalization event.
1190
+ */
1191
+ getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile): unknown;
1192
+ /**
1193
+ * Identify the current profile/visitor to associate traits with a profile.
1194
+ *
1195
+ * @param payload - Identify builder payload.
1196
+ * @returns The resulting {@link OptimizationData} for the identified user if the device is online.
1197
+ */
1198
+ abstract identify(payload: IdentifyBuilderArgs): Promise<OptimizationData | undefined>;
1199
+ /**
1200
+ * Record a page view.
1201
+ *
1202
+ * @param payload - Page view builder payload.
1203
+ * @returns The evaluated {@link OptimizationData} for this page view if the device is online.
1204
+ */
1205
+ abstract page(payload: PageViewBuilderArgs): Promise<OptimizationData | undefined>;
1206
+ /**
1207
+ * Record a screen view.
1208
+ *
1209
+ * @param payload - Screen view builder payload.
1210
+ * @returns The evaluated {@link OptimizationData} for this screen view if the device is online.
1211
+ */
1212
+ abstract screen(payload: ScreenViewBuilderArgs): Promise<OptimizationData | undefined>;
1213
+ /**
1214
+ * Record a custom track event.
1215
+ *
1216
+ * @param payload - Track builder payload.
1217
+ * @returns The evaluated {@link OptimizationData} for this event if the device is online.
1218
+ */
1219
+ abstract track(payload: TrackBuilderArgs): Promise<OptimizationData | undefined>;
1220
+ /**
1221
+ * Record a "sticky" component view.
1222
+ *
1223
+ * @param payload - "Sticky" component view builder payload.
1224
+ * @returns The evaluated {@link OptimizationData} for this component view if the device is online.
1225
+ * @remarks
1226
+ * This method is intended to be called only when a component is considered
1227
+ * "sticky".
1228
+ * @privateRemarks
1229
+ * Duplication prevention should be handled in Stateful implementations.
1230
+ */
1231
+ abstract trackComponentView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<OptimizationData | undefined>;
1232
+ }
1233
+
1234
+ /**
1235
+ * Configuration for {@link PersonalizationStateful}.
1236
+ *
1237
+ * @public
1238
+ */
1239
+ export declare interface PersonalizationProductConfig extends ProductConfig {
1240
+ /** Default signal values applied during initialization. */
1241
+ defaults?: PersonalizationProductConfigDefaults;
1242
+ /**
1243
+ * Function used to obtain an anonymous user identifier.
1244
+ *
1245
+ * @remarks
1246
+ * If a `getAnonymousId` function has been provided, the returned value will
1247
+ * take precedence over the `id` property of the current {@link Profile}
1248
+ * signal value
1249
+ *
1250
+ * @returns A string identifier, or `undefined` if no anonymous ID is available.
1251
+ */
1252
+ getAnonymousId?: () => string | undefined;
1253
+ }
1254
+
1255
+ /**
1256
+ * Default state values for {@link PersonalizationStateful} applied at construction time.
1257
+ *
1258
+ * @public
1259
+ */
1260
+ export declare interface PersonalizationProductConfigDefaults {
1261
+ /** Whether personalization is allowed by default. */
1262
+ consent?: boolean;
1263
+ /** Initial diff of changes produced by the service. */
1264
+ changes?: ChangeArray;
1265
+ /** Default active profile used for personalization. */
1266
+ profile?: Profile;
1267
+ /** Preselected personalization variants (e.g., winning treatments). */
1268
+ personalizations?: SelectedPersonalizationArray;
1269
+ }
1270
+
1271
+ declare const personalizations: Signal<{
1272
+ experienceId: string;
1273
+ variantIndex: number;
1274
+ variants: Record<string, string>;
1275
+ sticky?: boolean | undefined;
1276
+ }[] | undefined>;
1277
+
1278
+ /**
1279
+ * Storage key for cached selected personalizations.
1280
+ *
1281
+ * @internal
1282
+ */
1283
+ export declare const PERSONALIZATIONS_CACHE_KEY = "__ctfl_opt_personalizations__";
1284
+
1285
+ /**
1286
+ * Stateful personalization product that manages consent, profile, flags, and
1287
+ * selected variants while emitting Experience events and updating state.
1288
+ *
1289
+ * @public
1290
+ * @remarks
1291
+ * The class maintains reactive signals and exposes read‑only observables via
1292
+ * {@link PersonalizationStateful.states}. Events are validated via schema parsers and
1293
+ * run through interceptors before being submitted. Resulting state is merged
1294
+ * back into signals.
1295
+ */
1296
+ export declare class PersonalizationStateful extends PersonalizationBase implements ConsentGuard {
1297
+ /** In‑memory queue for offline events keyed by profile. */
1298
+ private readonly offlineQueue;
1299
+ /** Exposed observable state references. */
1300
+ readonly states: PersonalizationStates;
1301
+ /**
1302
+ * Function that provides an anonymous ID when available.
1303
+ *
1304
+ * @internal
1305
+ */
1306
+ getAnonymousId: () => string | undefined;
1307
+ /**
1308
+ * Create a new stateful personalization instance.
1309
+ *
1310
+ * @param options - Options to configure the personalization product for stateful environments.
1311
+ */
1312
+ constructor(options: PersonalizationStatefulOptions);
1313
+ /**
1314
+ * Reset stateful signals managed by this product.
1315
+ *
1316
+ * @remarks
1317
+ * Clears `changes`, `profile`, and selected `personalizations`.
1318
+ */
1319
+ reset(): void;
1320
+ /**
1321
+ * Get the specified Custom Flag's value (derived from the signal).
1322
+ * @param name - The name or key of the Custom Flag.
1323
+ * @returns The current value of the Custom Flag if found.
1324
+ * */
1325
+ getCustomFlag(name: string, changes?: ChangeArray | undefined): Json;
1326
+ /**
1327
+ * Resolve a Contentful entry to a personalized variant using the current
1328
+ * or provided selections.
1329
+ *
1330
+ * @typeParam S - Entry skeleton type.
1331
+ * @typeParam M - Chain modifiers.
1332
+ * @typeParam L - Locale code.
1333
+ * @param entry - The entry to personalize.
1334
+ * @param personalizations - Optional selections; defaults to the current signal value.
1335
+ * @returns The resolved entry data.
1336
+ */
1337
+ 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
+ /**
1339
+ * Resolve a merge tag to a value based on the current (or provided) profile.
1340
+ *
1341
+ * @param embeddedEntryNodeTarget - The merge‑tag entry node to resolve.
1342
+ * @param profile - Optional profile; defaults to the current signal value.
1343
+ * @returns The resolved value (type depends on the tag).
1344
+ * @remarks
1345
+ * Merge tags are references to profile data that can be substituted into content.
1346
+ */
1347
+ getMergeTagValue(embeddedEntryNodeTarget: MergeTagEntry, profile?: Profile | undefined): unknown;
1348
+ /**
1349
+ * Determine whether the named operation is permitted based on consent and
1350
+ * allowed event type configuration.
1351
+ *
1352
+ * @param name - Method name; `trackComponentView` is normalized to
1353
+ * `'component'` for allow‑list checks.
1354
+ * @returns `true` if the operation is permitted; otherwise `false`.
1355
+ */
1356
+ hasConsent(name: string): boolean;
1357
+ /**
1358
+ * Hook invoked when an operation is blocked due to missing consent.
1359
+ *
1360
+ * @param name - The blocked operation name.
1361
+ * @param payload - The original arguments supplied to the operation.
1362
+ */
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;
1380
+ /**
1381
+ * Identify the current profile/visitor to associate traits with a profile
1382
+ * and update optimization state.
1383
+ *
1384
+ * @param payload - Identify builder payload.
1385
+ * @returns The resulting {@link OptimizationData} for the identified user.
1386
+ */
1387
+ identify(payload: IdentifyBuilderArgs): Promise<OptimizationData | undefined>;
1388
+ /**
1389
+ * Record a page view and update optimization state.
1390
+ *
1391
+ * @param payload - Page view builder payload.
1392
+ * @returns The evaluated {@link OptimizationData} for this page view.
1393
+ */
1394
+ page(payload: PageViewBuilderArgs): Promise<OptimizationData | undefined>;
1395
+ /**
1396
+ * Record a screen view and update optimization state.
1397
+ *
1398
+ * @param payload - Screen view builder payload.
1399
+ * @returns The evaluated {@link OptimizationData} for this screen view.
1400
+ */
1401
+ screen(payload: ScreenViewBuilderArgs): Promise<OptimizationData | undefined>;
1402
+ /**
1403
+ * Record a custom track event and update optimization state.
1404
+ *
1405
+ * @param payload - Track builder payload.
1406
+ * @returns The evaluated {@link OptimizationData} for this event.
1407
+ */
1408
+ track(payload: TrackBuilderArgs): Promise<OptimizationData | undefined>;
1409
+ trackComponentView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<OptimizationData | undefined>;
1410
+ /**
1411
+ * Intercept, validate, and place an event into the offline eventd queue; then
1412
+ * trigger a size‑based flush if necessary.
1413
+ *
1414
+ * @param event - The event to enqueue.
1415
+ */
1416
+ private sendOrEnqueueEvent;
1417
+ /**
1418
+ * Flush the offline queue
1419
+ */
1420
+ flush(): Promise<void>;
1421
+ /**
1422
+ * Submit events to the Experience API, updating output signals with the
1423
+ * returned state.
1424
+ *
1425
+ * @param events - The events to submit.
1426
+ * @returns The {@link OptimizationData} returned by the service.
1427
+ * @internal
1428
+ * @privateRemarks
1429
+ * If a `getAnonymousId` function has been provided, the returned value will
1430
+ * take precedence over the `id` property of the current {@link Profile}
1431
+ * signal value
1432
+ */
1433
+ private upsertProfile;
1434
+ /**
1435
+ * Apply returned optimization state to local signals after interceptor processing.
1436
+ *
1437
+ * @param data - Optimization state returned by the service.
1438
+ * @internal
1439
+ */
1440
+ private updateOutputSignals;
1441
+ }
1442
+
1443
+ /**
1444
+ * Options for configuring {@link PersonalizationStateful} functionality.
1445
+ *
1446
+ * @public
1447
+ * @see {@link ProductBaseOptions}
1448
+ */
1449
+ export declare type PersonalizationStatefulOptions = ProductBaseOptions & {
1450
+ /** Configuration specific to the Personalization product */
1451
+ config?: PersonalizationProductConfig;
1452
+ };
1453
+
1454
+ /**
1455
+ * Stateless personalization implementation that immediately validates and sends
1456
+ * a single event to the Experience API, upserting the profile as needed.
1457
+ *
1458
+ * @public
1459
+ * @remarks
1460
+ * Each public method constructs a strongly-typed event via the shared builder,
1461
+ * runs it through event interceptors, and performs a profile upsert using the
1462
+ * Experience API. If an anonymous ID is available from the builder, it will be
1463
+ * preferred as the `profileId` unless an explicit profile is provided.
1464
+ */
1465
+ export declare class PersonalizationStateless extends PersonalizationBase {
1466
+ /**
1467
+ * Identify the current profile/visitor to associate traits with a profile.
1468
+ *
1469
+ * @param payload - Identify builder arguments with an optional partial
1470
+ * profile to attach to the upsert request.
1471
+ * @returns The resulting {@link OptimizationData} for the identified user.
1472
+ */
1473
+ identify(payload: IdentifyBuilderArgs & {
1474
+ profile?: PartialProfile;
1475
+ }): Promise<OptimizationData>;
1476
+ /**
1477
+ * Record a page view.
1478
+ *
1479
+ * @param payload - Page view builder arguments with an optional partial profile.
1480
+ * @returns The evaluated {@link OptimizationData} for this page view.
1481
+ */
1482
+ page(payload: PageViewBuilderArgs & {
1483
+ profile?: PartialProfile;
1484
+ }): Promise<OptimizationData>;
1485
+ /**
1486
+ * Record a screen view.
1487
+ *
1488
+ * @param payload - Screen view builder arguments with an optional partial profile.
1489
+ * @returns The evaluated {@link OptimizationData} for this screen view.
1490
+ */
1491
+ screen(payload: ScreenViewBuilderArgs & {
1492
+ profile?: PartialProfile;
1493
+ }): Promise<OptimizationData>;
1494
+ /**
1495
+ * Record a custom track event.
1496
+ *
1497
+ * @param payload - Track builder arguments with an optional partial profile.
1498
+ * @returns The evaluated {@link OptimizationData} for this event.
1499
+ */
1500
+ track(payload: TrackBuilderArgs & {
1501
+ profile?: PartialProfile;
1502
+ }): Promise<OptimizationData>;
1503
+ /**
1504
+ * Record a "sticky" component view.
1505
+ *
1506
+ * @param payload - Component view builder arguments with an optional partial profile.
1507
+ * @returns The evaluated {@link OptimizationData} for this component view.
1508
+ */
1509
+ trackComponentView(payload: ComponentViewBuilderArgs & {
1510
+ profile?: PartialProfile;
1511
+ }): Promise<OptimizationData>;
1512
+ /**
1513
+ * Intercept, validate, and upsert the profile with a single personalization
1514
+ * event.
1515
+ *
1516
+ * @param event - The {@link PersonalizationEvent} to submit.
1517
+ * @param profile - Optional partial profile. If omitted, the anonymous ID from
1518
+ * the builder (when present) is used as the `profileId`.
1519
+ * @returns The {@link OptimizationData} returned by the Experience API.
1520
+ * @internal
1521
+ */
1522
+ private upsertProfile;
1523
+ }
1524
+
1525
+ /**
1526
+ * Observables exposed by {@link PersonalizationStateful} that mirror internal signals.
1527
+ *
1528
+ * @public
1529
+ */
1530
+ export declare interface PersonalizationStates {
1531
+ /** Observable stream of the latest {@link AnalyticsEvent} or {@link PersonalizationEvent} (or `undefined`). */
1532
+ eventStream: Observable<InsightsEvent | ExperienceEvent | undefined>;
1533
+ /** Live view of effective flags for the current profile (if available). */
1534
+ flags: Observable<Flags | undefined>;
1535
+ /** Live view of the current profile. */
1536
+ profile: Observable<Profile | undefined>;
1537
+ /** Live view of selected personalizations (variants). */
1538
+ personalizations: Observable<SelectedPersonalizationArray | undefined>;
1539
+ }
1540
+
1541
+ /**
1542
+ * Resolve a personalized Contentful entry to the correct variant for the current
1543
+ * selections.
1544
+ *
1545
+ * @public
1546
+ * @remarks
1547
+ * Given a baseline {@link PersonalizedEntry} and a set of selected personalizations
1548
+ * (variants per experience), this resolver finds the matching replacement variant
1549
+ * for the component configured against the baseline entry.
1550
+ *
1551
+ * **Variant indexing**: `variantIndex` in {@link SelectedPersonalization} is treated as
1552
+ * 1‑based (index 1 = first variant). A value of `0` indicates baseline.
1553
+ */
1554
+ export declare const PersonalizedEntryResolver: {
1555
+ /**
1556
+ * Find the personalization entry corresponding to one of the selected experiences.
1557
+ *
1558
+ * @param params - Object containing the baseline personalized entry and the selections.
1559
+ * @param skipValidation - When `true`, skip type/shape validation for perf.
1560
+ * @returns The matching {@link PersonalizationEntry}, or `undefined` if not found/invalid.
1561
+ * @example
1562
+ * ```ts
1563
+ * const personalizationEntry = PersonalizedEntryResolver.getPersonalizationEntry({
1564
+ * personalizedEntry: entry,
1565
+ * selectedPersonalizations
1566
+ * })
1567
+ * ```
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
+ */
1573
+ getPersonalizationEntry({ personalizedEntry, selectedPersonalizations, }: {
1574
+ personalizedEntry: PersonalizedEntry_2;
1575
+ selectedPersonalizations: SelectedPersonalizationArray;
1576
+ }, skipValidation?: boolean): PersonalizationEntry_2 | undefined;
1577
+ /**
1578
+ * Look up the selection metadata for a specific personalization entry.
1579
+ *
1580
+ * @param params - Object with the target personalization entry and selections.
1581
+ * @param skipValidation - When `true`, skip type checks.
1582
+ * @returns The matching {@link SelectedPersonalization}, if present.
1583
+ * @example
1584
+ * ```ts
1585
+ * const selectedPersonalization = PersonalizedEntryResolver.getSelectedPersonalization({
1586
+ * personalizationEntry,
1587
+ * selectedPersonalizations
1588
+ * })
1589
+ * ```
1590
+ * @remarks
1591
+ * Selected personalizations are supplied by the Experience API in the
1592
+ * `experiences` response data property.
1593
+ */
1594
+ getSelectedPersonalization({ personalizationEntry, selectedPersonalizations, }: {
1595
+ personalizationEntry: PersonalizationEntry_2;
1596
+ selectedPersonalizations: SelectedPersonalizationArray;
1597
+ }, skipValidation?: boolean): SelectedPersonalization | undefined;
1598
+ /**
1599
+ * Get the replacement variant config for the given selection index.
1600
+ *
1601
+ * @param params - Baseline entry, personalization entry, and 1‑based variant index.
1602
+ * @param skipValidation - When `true`, skip type checks.
1603
+ * @returns The {@link EntryReplacementVariant} for the component, if any.
1604
+ * @example
1605
+ * ```ts
1606
+ * const selectedVariant = PersonalizedEntryResolver.getSelectedVariant({
1607
+ * personalizedEntry: entry,
1608
+ * personalizationEntry,
1609
+ * selectedVariantIndex: 2 // second variant (1‑based)
1610
+ * })
1611
+ * ```
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
+ */
1617
+ getSelectedVariant({ personalizedEntry, personalizationEntry, selectedVariantIndex, }: {
1618
+ personalizedEntry: PersonalizedEntry_2;
1619
+ personalizationEntry: PersonalizationEntry_2;
1620
+ selectedVariantIndex: number;
1621
+ }, skipValidation?: boolean): EntryReplacementVariant_2 | undefined;
1622
+ /**
1623
+ * Resolve the concrete Contentful entry that corresponds to a selected variant.
1624
+ *
1625
+ * @typeParam S - Entry skeleton type.
1626
+ * @typeParam M - Chain modifiers.
1627
+ * @typeParam L - Locale code.
1628
+ * @param params - Personalization entry and selected variant.
1629
+ * @param skipValidation - When `true`, skip type checks.
1630
+ * @returns The resolved entry typed as {@link Entry} or `undefined`.
1631
+ * @example
1632
+ * ```ts
1633
+ * const selectedVariantEntry = PersonalizedEntryResolver.getSelectedVariantEntry<{ fields: unknown }>({
1634
+ * personalizationEntry,
1635
+ * selectedVariant
1636
+ * })
1637
+ * ```
1638
+ * @remarks
1639
+ * A personalized entry will resolve either to the baseline (the entry
1640
+ * supplied as `personalizedEntry`) or the selected variant.
1641
+ */
1642
+ getSelectedVariantEntry<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>({ personalizationEntry, selectedVariant, }: {
1643
+ personalizationEntry: PersonalizationEntry_2;
1644
+ selectedVariant: EntryReplacementVariant_2;
1645
+ }, skipValidation?: boolean): Entry<S, M, L> | undefined;
1646
+ /**
1647
+ * Resolve the selected entry (baseline or variant) for a personalized entry
1648
+ * and optional selected personalizations, returning both the entry and the
1649
+ * personalization metadata.
1650
+ *
1651
+ * @typeParam S - Entry skeleton type.
1652
+ * @typeParam M - Chain modifiers.
1653
+ * @typeParam L - Locale code.
1654
+ * @param entry - The baseline personalized entry.
1655
+ * @param selectedPersonalizations - Optional selections for the current profile.
1656
+ * @returns An object containing the resolved entry and (if chosen) the selection.
1657
+ * @example
1658
+ * ```ts
1659
+ * const { entry: personalizedEntry, personalization } = PersonalizedEntryResolver.resolve(entry, selections)
1660
+ * if (personalization) console.log('Variant index', personalization.variantIndex)
1661
+ * ```
1662
+ */
1663
+ resolve<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = string>(entry: Entry<S, M, L>, selectedPersonalizations?: SelectedPersonalizationArray): ResolvedData<S, M, L>;
1664
+ };
1665
+
1666
+ /**
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.
1669
+ *
1670
+ * @public
1671
+ */
1672
+ 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;
1677
+ }
1678
+
1679
+ /**
1680
+ * Shared base for all product implementations.
1681
+ *
1682
+ * @internal
1683
+ * @remarks
1684
+ * This abstract class is not exported as part of the public API surface.
1685
+ * Concrete implementations (e.g., analytics) should extend this class and
1686
+ * expose their own public methods.
1687
+ */
1688
+ declare abstract class ProductBase {
1689
+ /**
1690
+ * Allow‑list of event {@link AnalyticsEventType | type keys} permitted when consent is not present.
1691
+ */
1692
+ protected readonly allowedEventTypes?: string[];
1693
+ /** Event builder used to construct strongly‑typed events. */
1694
+ protected readonly builder: EventBuilder;
1695
+ /** Optimization API client used to send events to the Experience and Insights APIs. */
1696
+ protected readonly api: ApiClient;
1697
+ /**
1698
+ * Deduplication helper used to track previously seen values within optional
1699
+ * scopes
1700
+ */
1701
+ readonly duplicationDetector: ValuePresence;
1702
+ /** Interceptors that can mutate/augment outgoing events or optimization state. */
1703
+ readonly interceptors: LifecycleInterceptors;
1704
+ /**
1705
+ * Creates a new product base instance.
1706
+ *
1707
+ * @param options - Options for configuring the functionality common among products.
1708
+ */
1709
+ constructor(options: ProductBaseOptions);
1710
+ }
1711
+
1712
+ /**
1713
+ * Options for configuring the common functionality of {@link ProductBase} descendents.
1714
+ *
1715
+ * @public
1716
+ */
1717
+ declare interface ProductBaseOptions {
1718
+ /** Optimization API client. */
1719
+ api: ApiClient;
1720
+ /** Event builder for constructing events. */
1721
+ builder: EventBuilder;
1722
+ /** Optional configuration for allow‑lists and duplication prevention. */
1723
+ config?: ProductConfig;
1724
+ /** Lifecycle container for event and state interceptors. */
1725
+ interceptors: LifecycleInterceptors;
1726
+ }
1727
+
1728
+ /**
1729
+ * Common configuration for all product implementations.
1730
+ *
1731
+ * @public
1732
+ */
1733
+ declare interface ProductConfig {
1734
+ /**
1735
+ * The set of event type strings that are allowed to be sent even if consent is
1736
+ * not granted.
1737
+ *
1738
+ * @defaultValue `['page', 'identify']`
1739
+ * @remarks These types are compared against the `type` property of events.
1740
+ */
1741
+ allowedEventTypes?: EventType[];
1742
+ /**
1743
+ * A map of duplication keys to a list of component IDs that should be
1744
+ * considered duplicates and therefore suppressed.
1745
+ *
1746
+ * @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.
1750
+ */
1751
+ preventedComponentEvents?: Record<string, string[]>;
1752
+ }
1753
+
1754
+ declare const profile: Signal<Profile | undefined>;
1755
+
1756
+ /**
1757
+ * Storage key for cached profile data.
1758
+ *
1759
+ * @internal
1760
+ */
1761
+ export declare const PROFILE_CACHE_KEY = "__ctfl_opt_profile__";
1762
+
1763
+ /**
1764
+ * Result returned by {@link PersonalizedEntryResolver.resolve}.
1765
+ *
1766
+ * @typeParam S - Entry skeleton type.
1767
+ * @typeParam M - Chain modifiers.
1768
+ * @typeParam L - Locale code.
1769
+ * @public
1770
+ */
1771
+ export declare interface ResolvedData<S extends EntrySkeletonType, M extends ChainModifiers = ChainModifiers, L extends LocaleCode = LocaleCode> {
1772
+ /** The baseline or resolved variant entry. */
1773
+ entry: Entry<S, M, L>;
1774
+ /** The selected personalization metadata, if a non‑baseline variant was chosen. */
1775
+ personalization?: SelectedPersonalization;
1776
+ }
1777
+
1778
+ /**
1779
+ * These methods assist in resolving values via Resolvers
1780
+ *
1781
+ * @internal
1782
+ * @privateRemarks
1783
+ * This interface exists to document that the included methods should not be
1784
+ * considered static.
1785
+ */
1786
+ declare interface ResolverMethods {
1787
+ /**
1788
+ * Get the specified Custom Flag's value from the supplied changes.
1789
+ * @param name - The name or key of the Custom Flag.
1790
+ * @param changes - Optional changes array.
1791
+ * @returns The current value of the Custom Flag if found.
1792
+ * @remarks
1793
+ * The changes array can be sourced from the data returned when emitting any
1794
+ * personalization event.
1795
+ * */
1796
+ getCustomFlag: (name: string, changes?: ChangeArray) => Json;
1797
+ /**
1798
+ * Resolve a Contentful entry to a personalized variant using the current
1799
+ * or provided selected personalizations.
1800
+ *
1801
+ * @typeParam S - Entry skeleton type.
1802
+ * @typeParam M - Chain modifiers.
1803
+ * @typeParam L - Locale code.
1804
+ * @param entry - The entry to personalize.
1805
+ * @param personalizations - Optional selections.
1806
+ * @returns The resolved entry data.
1807
+ * @remarks
1808
+ * Selected personalizations can be sourced from the data returned when emitting any
1809
+ * personalization event.
1810
+ */
1811
+ personalizeEntry: <S extends EntrySkeletonType, M extends ChainModifiers, L extends LocaleCode>(entry: Entry<S, M, L>, personalizations?: SelectedPersonalizationArray) => ResolvedData<S, M, L>;
1812
+ /**
1813
+ * Resolve a merge tag to a value based on the current (or provided) profile.
1814
+ *
1815
+ * @param embeddedEntryNodeTarget - The merge‑tag entry node to resolve.
1816
+ * @param profile - Optional profile.
1817
+ * @returns The resolved value (type depends on the tag).
1818
+ * @remarks
1819
+ * Merge tags are references to profile data that can be substituted into content. The
1820
+ * profile can be sourced from the data returned when emitting any personalization event.
1821
+ */
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;
1832
+ }
1833
+
1834
+ export { Signal }
1835
+
1836
+ export declare interface SignalFns {
1837
+ batch: typeof batch;
1838
+ computed: typeof computed;
1839
+ effect: typeof effect;
1840
+ untracked: typeof untracked;
1841
+ }
1842
+
1843
+ export declare const signalFns: SignalFns;
1844
+
1845
+ export declare interface Signals {
1846
+ changes: typeof changes;
1847
+ consent: typeof consent;
1848
+ event: typeof event_2;
1849
+ flags: typeof flags;
1850
+ online: typeof online;
1851
+ personalizations: typeof personalizations;
1852
+ profile: typeof profile;
1853
+ }
1854
+
1855
+ export declare const signals: Signals;
1856
+
1857
+ declare interface Subscription {
1858
+ unsubscribe: () => void;
1859
+ }
1860
+
1861
+ /**
1862
+ * Arguments for tracking a component/flag view in stateless mode.
1863
+ *
1864
+ * @public
1865
+ * @remarks
1866
+ * The `profile` is optional; when omitted, the APIs may infer identity via
1867
+ * other means.
1868
+ */
1869
+ export declare type TrackViewArgs = ComponentViewBuilderArgs & {
1870
+ profile?: PartialProfile;
1871
+ };
1872
+
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
+ export { }