@contentful/optimization-core 0.1.0-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +408 -0
- package/dist/Consent.d.ts +44 -0
- package/dist/Consent.d.ts.map +1 -0
- package/dist/Consent.js +2 -0
- package/dist/Consent.js.map +1 -0
- package/dist/CoreBase.d.ts +161 -0
- package/dist/CoreBase.d.ts.map +1 -0
- package/dist/CoreBase.js +151 -0
- package/dist/CoreBase.js.map +1 -0
- package/dist/CoreStateful.d.ts +142 -0
- package/dist/CoreStateful.d.ts.map +1 -0
- package/dist/CoreStateful.js +137 -0
- package/dist/CoreStateful.js.map +1 -0
- package/dist/CoreStateless.d.ts +53 -0
- package/dist/CoreStateless.d.ts.map +1 -0
- package/dist/CoreStateless.js +43 -0
- package/dist/CoreStateless.js.map +1 -0
- package/dist/ProductBase.d.ts +83 -0
- package/dist/ProductBase.d.ts.map +1 -0
- package/dist/ProductBase.js +50 -0
- package/dist/ProductBase.js.map +1 -0
- package/dist/analytics/AnalyticsBase.d.ts +35 -0
- package/dist/analytics/AnalyticsBase.d.ts.map +1 -0
- package/dist/analytics/AnalyticsBase.js +13 -0
- package/dist/analytics/AnalyticsBase.js.map +1 -0
- package/dist/analytics/AnalyticsStateful.d.ts +138 -0
- package/dist/analytics/AnalyticsStateful.d.ts.map +1 -0
- package/dist/analytics/AnalyticsStateful.js +179 -0
- package/dist/analytics/AnalyticsStateful.js.map +1 -0
- package/dist/analytics/AnalyticsStateless.d.ts +48 -0
- package/dist/analytics/AnalyticsStateless.d.ts.map +1 -0
- package/dist/analytics/AnalyticsStateless.js +61 -0
- package/dist/analytics/AnalyticsStateless.js.map +1 -0
- package/dist/analytics/index.d.ts +5 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +5 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/global-constants.d.ts +18 -0
- package/dist/global-constants.d.ts.map +1 -0
- package/dist/global-constants.js +18 -0
- package/dist/global-constants.js.map +1 -0
- package/dist/index.cjs +1808 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1535 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/decorators/guardedBy.d.ts +113 -0
- package/dist/lib/decorators/guardedBy.d.ts.map +1 -0
- package/dist/lib/decorators/guardedBy.js +143 -0
- package/dist/lib/decorators/guardedBy.js.map +1 -0
- package/dist/lib/decorators/index.d.ts +2 -0
- package/dist/lib/decorators/index.d.ts.map +1 -0
- package/dist/lib/decorators/index.js +2 -0
- package/dist/lib/decorators/index.js.map +1 -0
- package/dist/lib/interceptor/InterceptorManager.d.ts +127 -0
- package/dist/lib/interceptor/InterceptorManager.d.ts.map +1 -0
- package/dist/lib/interceptor/InterceptorManager.js +125 -0
- package/dist/lib/interceptor/InterceptorManager.js.map +1 -0
- package/dist/lib/interceptor/index.d.ts +2 -0
- package/dist/lib/interceptor/index.d.ts.map +1 -0
- package/dist/lib/interceptor/index.js +2 -0
- package/dist/lib/interceptor/index.js.map +1 -0
- package/dist/lib/value-presence/ValuePresence.d.ts +123 -0
- package/dist/lib/value-presence/ValuePresence.d.ts.map +1 -0
- package/dist/lib/value-presence/ValuePresence.js +141 -0
- package/dist/lib/value-presence/ValuePresence.js.map +1 -0
- package/dist/lib/value-presence/index.d.ts +2 -0
- package/dist/lib/value-presence/index.d.ts.map +1 -0
- package/dist/lib/value-presence/index.js +2 -0
- package/dist/lib/value-presence/index.js.map +1 -0
- package/dist/personalization/PersonalizationBase.d.ts +184 -0
- package/dist/personalization/PersonalizationBase.d.ts.map +1 -0
- package/dist/personalization/PersonalizationBase.js +76 -0
- package/dist/personalization/PersonalizationBase.js.map +1 -0
- package/dist/personalization/PersonalizationStateful.d.ts +226 -0
- package/dist/personalization/PersonalizationStateful.d.ts.map +1 -0
- package/dist/personalization/PersonalizationStateful.js +297 -0
- package/dist/personalization/PersonalizationStateful.js.map +1 -0
- package/dist/personalization/PersonalizationStateless.d.ts +74 -0
- package/dist/personalization/PersonalizationStateless.d.ts.map +1 -0
- package/dist/personalization/PersonalizationStateless.js +98 -0
- package/dist/personalization/PersonalizationStateless.js.map +1 -0
- package/dist/personalization/index.d.ts +6 -0
- package/dist/personalization/index.d.ts.map +1 -0
- package/dist/personalization/index.js +6 -0
- package/dist/personalization/index.js.map +1 -0
- package/dist/personalization/resolvers/FlagsResolver.d.ts +35 -0
- package/dist/personalization/resolvers/FlagsResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/FlagsResolver.js +47 -0
- package/dist/personalization/resolvers/FlagsResolver.js.map +1 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.d.ts +74 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.js +109 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.js.map +1 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts +142 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.js +196 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.js.map +1 -0
- package/dist/personalization/resolvers/index.d.ts +7 -0
- package/dist/personalization/resolvers/index.d.ts.map +1 -0
- package/dist/personalization/resolvers/index.js +7 -0
- package/dist/personalization/resolvers/index.js.map +1 -0
- package/dist/signals.d.ts +35 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +30 -0
- package/dist/signals.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import ValuePresence from './lib/value-presence/ValuePresence';
|
|
2
|
+
/**
|
|
3
|
+
* Default allow‑list of event types that can be emitted without explicit consent.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
* @privateRemarks These defaults are only applied when a consumer does not provide
|
|
7
|
+
* {@link ProductConfig.allowedEventTypes}.
|
|
8
|
+
*/
|
|
9
|
+
const defaultAllowedEvents = ['page', 'identify'];
|
|
10
|
+
/**
|
|
11
|
+
* Shared base for all product implementations.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
* @remarks
|
|
15
|
+
* This abstract class is not exported as part of the public API surface.
|
|
16
|
+
* Concrete implementations (e.g., analytics) should extend this class and
|
|
17
|
+
* expose their own public methods.
|
|
18
|
+
*/
|
|
19
|
+
class ProductBase {
|
|
20
|
+
/**
|
|
21
|
+
* Allow‑list of event {@link AnalyticsEventType | type keys} permitted when consent is not present.
|
|
22
|
+
*/
|
|
23
|
+
allowedEventTypes;
|
|
24
|
+
/** Event builder used to construct strongly‑typed events. */
|
|
25
|
+
builder;
|
|
26
|
+
/** Optimization API client used to send events to the Experience and Insights APIs. */
|
|
27
|
+
api;
|
|
28
|
+
/**
|
|
29
|
+
* Deduplication helper used to track previously seen values within optional
|
|
30
|
+
* scopes
|
|
31
|
+
*/
|
|
32
|
+
duplicationDetector;
|
|
33
|
+
/** Interceptors that can mutate/augment outgoing events or optimization state. */
|
|
34
|
+
interceptors;
|
|
35
|
+
/**
|
|
36
|
+
* Creates a new product base instance.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Options for configuring the functionality common among products.
|
|
39
|
+
*/
|
|
40
|
+
constructor(options) {
|
|
41
|
+
const { api, builder, config, interceptors } = options;
|
|
42
|
+
this.allowedEventTypes = config?.allowedEventTypes ?? defaultAllowedEvents;
|
|
43
|
+
this.api = api;
|
|
44
|
+
this.builder = builder;
|
|
45
|
+
this.duplicationDetector = new ValuePresence(config?.preventedComponentEvents);
|
|
46
|
+
this.interceptors = interceptors;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export default ProductBase;
|
|
50
|
+
//# sourceMappingURL=ProductBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductBase.js","sourceRoot":"","sources":["../src/ProductBase.ts"],"names":[],"mappings":"AAOA,OAAO,aAAa,MAAM,oCAAoC,CAAA;AAS9D;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAgB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;AA6C9D;;;;;;;;GAQG;AACH,MAAe,WAAW;IACxB;;OAEG;IACgB,iBAAiB,CAAW;IAE/C,6DAA6D;IAC1C,OAAO,CAAc;IAExC,uFAAuF;IACpE,GAAG,CAAW;IAEjC;;;OAGG;IACM,mBAAmB,CAAe;IAE3C,kFAAkF;IACzE,YAAY,CAAuB;IAE5C;;;;OAIG;IACH,YAAY,OAA2B;QACrC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAA;QACtD,IAAI,CAAC,iBAAiB,GAAG,MAAM,EAAE,iBAAiB,IAAI,oBAAoB,CAAA;QAC1E,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,mBAAmB,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;QAC9E,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;IAClC,CAAC;CACF;AAED,eAAe,WAAW,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ComponentViewBuilderArgs } from '@contentful/optimization-api-client';
|
|
2
|
+
import ProductBase from '../ProductBase';
|
|
3
|
+
/**
|
|
4
|
+
* Base class for analytics implementations (internal).
|
|
5
|
+
*
|
|
6
|
+
* @internal
|
|
7
|
+
* @remarks
|
|
8
|
+
* Concrete analytics classes should implement the component/flag view tracking
|
|
9
|
+
* methods below. This base is not part of the public API.
|
|
10
|
+
*/
|
|
11
|
+
declare abstract class AnalyticsBase extends ProductBase {
|
|
12
|
+
/**
|
|
13
|
+
* Track a UI component view event.
|
|
14
|
+
*
|
|
15
|
+
* @param payload - Component view builder arguments.
|
|
16
|
+
* @param duplicationScope - Optional string used to scope duplication used in Stateful
|
|
17
|
+
* implementations.
|
|
18
|
+
* @privateRemarks
|
|
19
|
+
* Duplication prevention should be handled in Stateful implementations
|
|
20
|
+
*/
|
|
21
|
+
abstract trackComponentView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void> | void;
|
|
22
|
+
/**
|
|
23
|
+
* Track a flag (feature) view event.
|
|
24
|
+
*
|
|
25
|
+
* @param payload - Flag view builder arguments.
|
|
26
|
+
* @param duplicationScope - Optional string used to scope duplication used in Stateful
|
|
27
|
+
* implementations.
|
|
28
|
+
* @returns A promise that resolves when processing is complete (or `void`).
|
|
29
|
+
* @privateRemarks
|
|
30
|
+
* Duplication prevention should be handled in Stateful implementations
|
|
31
|
+
*/
|
|
32
|
+
abstract trackFlagView(payload: ComponentViewBuilderArgs, duplicationScope?: string): Promise<void> | void;
|
|
33
|
+
}
|
|
34
|
+
export default AnalyticsBase;
|
|
35
|
+
//# sourceMappingURL=AnalyticsBase.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsBase.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsBase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AACnF,OAAO,WAAW,MAAM,gBAAgB,CAAA;AAExC;;;;;;;GAOG;AACH,uBAAe,aAAc,SAAQ,WAAW;IAC9C;;;;;;;;OAQG;IACH,QAAQ,CAAC,kBAAkB,CACzB,OAAO,EAAE,wBAAwB,EACjC,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAEvB;;;;;;;;;OASG;IACH,QAAQ,CAAC,aAAa,CACpB,OAAO,EAAE,wBAAwB,EACjC,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;CACxB;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import ProductBase from '../ProductBase';
|
|
2
|
+
/**
|
|
3
|
+
* Base class for analytics implementations (internal).
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
* @remarks
|
|
7
|
+
* Concrete analytics classes should implement the component/flag view tracking
|
|
8
|
+
* methods below. This base is not part of the public API.
|
|
9
|
+
*/
|
|
10
|
+
class AnalyticsBase extends ProductBase {
|
|
11
|
+
}
|
|
12
|
+
export default AnalyticsBase;
|
|
13
|
+
//# sourceMappingURL=AnalyticsBase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsBase.js","sourceRoot":"","sources":["../../src/analytics/AnalyticsBase.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,gBAAgB,CAAA;AAExC;;;;;;;GAOG;AACH,MAAe,aAAc,SAAQ,WAAW;CA6B/C;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { InsightsEvent as AnalyticsEvent, type ComponentViewBuilderArgs, type ExperienceEvent as PersonalizationEvent, type Profile } from '@contentful/optimization-api-client';
|
|
2
|
+
import type { ConsentGuard } from '../Consent';
|
|
3
|
+
import type { ProductBaseOptions, ProductConfig } from '../ProductBase';
|
|
4
|
+
import { type Observable } from '../signals';
|
|
5
|
+
import AnalyticsBase from './AnalyticsBase';
|
|
6
|
+
/**
|
|
7
|
+
* Default analytics state values applied at construction time.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export interface AnalyticsProductConfigDefaults {
|
|
12
|
+
/** Whether analytics collection is allowed by default. */
|
|
13
|
+
consent?: boolean;
|
|
14
|
+
/** Default profile to associate with events. */
|
|
15
|
+
profile?: Profile;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Configuration for the stateful analytics implementation.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export interface AnalyticsProductConfig extends ProductConfig {
|
|
23
|
+
/**
|
|
24
|
+
* Default signal values applied on initialization.
|
|
25
|
+
*/
|
|
26
|
+
defaults?: AnalyticsProductConfigDefaults;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Observables exposed by the stateful analytics product.
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export interface AnalyticsStates {
|
|
34
|
+
/** Observable stream of the latest {@link AnalyticsEvent} or {@link PersonalizationEvent} (or `undefined`). */
|
|
35
|
+
eventStream: Observable<AnalyticsEvent | PersonalizationEvent | undefined>;
|
|
36
|
+
/** Observable stream of the active {@link Profile} (or `undefined`). */
|
|
37
|
+
profile: Observable<Profile | undefined>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Options for configuring {@link AnalyticsStateful} functionality.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
* @see {@link ProductBaseOptions}
|
|
44
|
+
*/
|
|
45
|
+
export type AnalyticsStatefulOptions = ProductBaseOptions & {
|
|
46
|
+
/** Configuration specific to the Analytics product */
|
|
47
|
+
config?: AnalyticsProductConfig;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Analytics implementation that maintains local state (consent, profile) and
|
|
51
|
+
* queues events until flushed or the queue reaches a maximum size.
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
declare class AnalyticsStateful extends AnalyticsBase implements ConsentGuard {
|
|
56
|
+
/** In‑memory queue keyed by profile. */
|
|
57
|
+
private readonly queue;
|
|
58
|
+
/** Exposed observable state references. */
|
|
59
|
+
readonly states: AnalyticsStates;
|
|
60
|
+
/**
|
|
61
|
+
* Create a new stateful analytics instance.
|
|
62
|
+
*
|
|
63
|
+
* @param options - Options to configure the analytics product for stateful environments.
|
|
64
|
+
*/
|
|
65
|
+
constructor(options: AnalyticsStatefulOptions);
|
|
66
|
+
/**
|
|
67
|
+
* Reset analytics‑related signals and the last emitted event.
|
|
68
|
+
*/
|
|
69
|
+
reset(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Determine whether the named operation is permitted based on consent and
|
|
72
|
+
* allowed event type configuration.
|
|
73
|
+
*
|
|
74
|
+
* @param name - The method name; `'trackComponentView'` is normalized
|
|
75
|
+
* to `'component'` for allow‑list checks.
|
|
76
|
+
* @returns `true` if the operation is permitted; otherwise `false`.
|
|
77
|
+
*/
|
|
78
|
+
hasConsent(name: string): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Hook invoked when an operation is blocked due to missing consent.
|
|
81
|
+
*
|
|
82
|
+
* @param name - The blocked operation name.
|
|
83
|
+
* @param payload - The original arguments supplied to the operation.
|
|
84
|
+
*/
|
|
85
|
+
onBlockedByConsent(name: string, payload: unknown[]): void;
|
|
86
|
+
/**
|
|
87
|
+
* Guard used to suppress duplicate component/flag view events based on a
|
|
88
|
+
* duplication key and the component identifier.
|
|
89
|
+
*
|
|
90
|
+
* @param _name - The operation name (unused).
|
|
91
|
+
* @param payload - Tuple of [builderArgs, duplicationScope].
|
|
92
|
+
* @returns `true` if the event is NOT a duplicate and should proceed.
|
|
93
|
+
*/
|
|
94
|
+
isNotDuplicated(_name: string, payload: [ComponentViewBuilderArgs, string]): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Hook invoked when an operation is blocked by the duplication guard.
|
|
97
|
+
*
|
|
98
|
+
* @param name - The blocked operation name.
|
|
99
|
+
* @param payload - The original arguments supplied to the operation.
|
|
100
|
+
*/
|
|
101
|
+
onBlockedByDuplication(name: string, payload: unknown[]): void;
|
|
102
|
+
/**
|
|
103
|
+
* Queue a component view event for the active profile.
|
|
104
|
+
*
|
|
105
|
+
* @param payload - Component view builder arguments.
|
|
106
|
+
* @param _duplicationScope - Optional string used to scope duplication (used
|
|
107
|
+
* by guards); an empty string `''` is converted to the `undefined` scope
|
|
108
|
+
*/
|
|
109
|
+
trackComponentView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Queue a flag view event for the active profile.
|
|
112
|
+
*
|
|
113
|
+
* @param payload - Flag view builder arguments.
|
|
114
|
+
* @param _duplicationScope - Optional string used to scope duplication (used
|
|
115
|
+
* by guards); an empty string `''` is converted to the `undefined` scope
|
|
116
|
+
*/
|
|
117
|
+
trackFlagView(payload: ComponentViewBuilderArgs, _duplicationScope?: string): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Intercept, validate, and place an event into the profile‑scoped queue; then
|
|
120
|
+
* trigger a size‑based flush if necessary.
|
|
121
|
+
*
|
|
122
|
+
* @param event - The event to enqueue.
|
|
123
|
+
*/
|
|
124
|
+
private enqueueEvent;
|
|
125
|
+
/**
|
|
126
|
+
* Flush the queue automatically when the total number of queued events
|
|
127
|
+
* reaches {@link MAX_QUEUED_EVENTS}.
|
|
128
|
+
*/
|
|
129
|
+
private flushMaxEvents;
|
|
130
|
+
/**
|
|
131
|
+
* Send all queued events grouped by profile and clear the queue.
|
|
132
|
+
* @remarks Only under rare circumstances should there be more than one
|
|
133
|
+
* profile in a stateful application.
|
|
134
|
+
*/
|
|
135
|
+
flush(): Promise<void>;
|
|
136
|
+
}
|
|
137
|
+
export default AnalyticsStateful;
|
|
138
|
+
//# sourceMappingURL=AnalyticsStateful.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsStateful.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsStateful.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,IAAI,cAAc,EAE/B,KAAK,wBAAwB,EAE7B,KAAK,eAAe,IAAI,oBAAoB,EAC5C,KAAK,OAAO,EACb,MAAM,qCAAqC,CAAA;AAE5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACvE,OAAO,EAQL,KAAK,UAAU,EAChB,MAAM,YAAY,CAAA;AACnB,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAI3C;;;;GAIG;AACH,MAAM,WAAW,8BAA8B;IAC7C,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC3D;;OAEG;IACH,QAAQ,CAAC,EAAE,8BAA8B,CAAA;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,+GAA+G;IAC/G,WAAW,EAAE,UAAU,CAAC,cAAc,GAAG,oBAAoB,GAAG,SAAS,CAAC,CAAA;IAC1E,wEAAwE;IACxE,OAAO,EAAE,UAAU,CAAC,OAAO,GAAG,SAAS,CAAC,CAAA;CACzC;AAED;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,kBAAkB,GAAG;IAC1D,sDAAsD;IACtD,MAAM,CAAC,EAAE,sBAAsB,CAAA;CAChC,CAAA;AAOD;;;;;GAKG;AACH,cAAM,iBAAkB,SAAQ,aAAc,YAAW,YAAY;IACnE,wCAAwC;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyC;IAE/D,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,eAAe,CAG/B;IAED;;;;OAIG;gBACS,OAAO,EAAE,wBAAwB;IA2B7C;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;;;;;;OAOG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IASjC;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI;IAM1D;;;;;;;OAOG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,wBAAwB,EAAE,MAAM,CAAC,GAAG,OAAO;IAUpF;;;;;OAKG;IACH,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI;IAQ9D;;;;;;OAMG;IAGG,kBAAkB,CACtB,OAAO,EAAE,wBAAwB,EACjC,iBAAiB,SAAK,GACrB,OAAO,CAAC,IAAI,CAAC;IAMhB;;;;;;OAMG;IAGG,aAAa,CAAC,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7F;;;;;OAKG;YACW,YAAY;IA4B1B;;;OAGG;YACW,cAAc;IAI5B;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAa7B;AAED,eAAe,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { InsightsEvent as AnalyticsEvent, } from '@contentful/optimization-api-client';
|
|
2
|
+
import { createScopedLogger } from 'logger';
|
|
3
|
+
import { guardedBy } from '../lib/decorators';
|
|
4
|
+
import { batch, consent, effect, event as eventSignal, online as onlineSignal, profile as profileSignal, toObservable, } from '../signals';
|
|
5
|
+
import AnalyticsBase from './AnalyticsBase';
|
|
6
|
+
const logger = createScopedLogger('Analytics');
|
|
7
|
+
/**
|
|
8
|
+
* Maximum number of queued events before an automatic flush is triggered.
|
|
9
|
+
*/
|
|
10
|
+
const MAX_QUEUED_EVENTS = 25;
|
|
11
|
+
/**
|
|
12
|
+
* Analytics implementation that maintains local state (consent, profile) and
|
|
13
|
+
* queues events until flushed or the queue reaches a maximum size.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
class AnalyticsStateful extends AnalyticsBase {
|
|
18
|
+
/** In‑memory queue keyed by profile. */
|
|
19
|
+
queue = new Map();
|
|
20
|
+
/** Exposed observable state references. */
|
|
21
|
+
states = {
|
|
22
|
+
eventStream: toObservable(eventSignal),
|
|
23
|
+
profile: toObservable(profileSignal),
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Create a new stateful analytics instance.
|
|
27
|
+
*
|
|
28
|
+
* @param options - Options to configure the analytics product for stateful environments.
|
|
29
|
+
*/
|
|
30
|
+
constructor(options) {
|
|
31
|
+
const { api, builder, config, interceptors } = options;
|
|
32
|
+
super({ api, builder, config, interceptors });
|
|
33
|
+
const { defaults } = config ?? {};
|
|
34
|
+
if (defaults?.profile !== undefined) {
|
|
35
|
+
const { profile: defaultProfile } = defaults;
|
|
36
|
+
profileSignal.value = defaultProfile;
|
|
37
|
+
}
|
|
38
|
+
effect(() => {
|
|
39
|
+
const id = profileSignal.value?.id;
|
|
40
|
+
logger.info(`Analytics ${consent.value ? 'will' : 'will not'} be collected due to consent (${consent.value})`);
|
|
41
|
+
logger.debug(`Profile ${id && `with ID ${id}`} has been ${id ? 'set' : 'cleared'}`);
|
|
42
|
+
});
|
|
43
|
+
effect(() => {
|
|
44
|
+
if (onlineSignal.value)
|
|
45
|
+
void this.flush();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reset analytics‑related signals and the last emitted event.
|
|
50
|
+
*/
|
|
51
|
+
reset() {
|
|
52
|
+
batch(() => {
|
|
53
|
+
eventSignal.value = undefined;
|
|
54
|
+
profileSignal.value = undefined;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Determine whether the named operation is permitted based on consent and
|
|
59
|
+
* allowed event type configuration.
|
|
60
|
+
*
|
|
61
|
+
* @param name - The method name; `'trackComponentView'` is normalized
|
|
62
|
+
* to `'component'` for allow‑list checks.
|
|
63
|
+
* @returns `true` if the operation is permitted; otherwise `false`.
|
|
64
|
+
*/
|
|
65
|
+
hasConsent(name) {
|
|
66
|
+
return (!!consent.value ||
|
|
67
|
+
(this.allowedEventTypes ?? []).includes(name === 'trackComponentView' || name === 'trackFlagView' ? 'component' : name));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Hook invoked when an operation is blocked due to missing consent.
|
|
71
|
+
*
|
|
72
|
+
* @param name - The blocked operation name.
|
|
73
|
+
* @param payload - The original arguments supplied to the operation.
|
|
74
|
+
*/
|
|
75
|
+
onBlockedByConsent(name, payload) {
|
|
76
|
+
logger.warn(`Event "${name}" was blocked due to lack of consent; payload: ${JSON.stringify(payload)}`);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Guard used to suppress duplicate component/flag view events based on a
|
|
80
|
+
* duplication key and the component identifier.
|
|
81
|
+
*
|
|
82
|
+
* @param _name - The operation name (unused).
|
|
83
|
+
* @param payload - Tuple of [builderArgs, duplicationScope].
|
|
84
|
+
* @returns `true` if the event is NOT a duplicate and should proceed.
|
|
85
|
+
*/
|
|
86
|
+
isNotDuplicated(_name, payload) {
|
|
87
|
+
const [{ componentId: value }, duplicationScope] = payload;
|
|
88
|
+
const isDuplicated = this.duplicationDetector.isPresent(duplicationScope, value);
|
|
89
|
+
if (!isDuplicated)
|
|
90
|
+
this.duplicationDetector.addValue(duplicationScope, value);
|
|
91
|
+
return !isDuplicated;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Hook invoked when an operation is blocked by the duplication guard.
|
|
95
|
+
*
|
|
96
|
+
* @param name - The blocked operation name.
|
|
97
|
+
* @param payload - The original arguments supplied to the operation.
|
|
98
|
+
*/
|
|
99
|
+
onBlockedByDuplication(name, payload) {
|
|
100
|
+
const componentType = name === 'trackFlagView' ? 'flag' : 'component';
|
|
101
|
+
logger.debug(`Duplicate "${componentType} view" event detected, skipping; payload: ${JSON.stringify(payload)}`);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Queue a component view event for the active profile.
|
|
105
|
+
*
|
|
106
|
+
* @param payload - Component view builder arguments.
|
|
107
|
+
* @param _duplicationScope - Optional string used to scope duplication (used
|
|
108
|
+
* by guards); an empty string `''` is converted to the `undefined` scope
|
|
109
|
+
*/
|
|
110
|
+
@guardedBy('isNotDuplicated', { onBlocked: 'onBlockedByDuplication' })
|
|
111
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
112
|
+
async trackComponentView(payload, _duplicationScope = '') {
|
|
113
|
+
logger.info(`Processing "component view" event for ${payload.componentId}`);
|
|
114
|
+
await this.enqueueEvent(this.builder.buildComponentView(payload));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Queue a flag view event for the active profile.
|
|
118
|
+
*
|
|
119
|
+
* @param payload - Flag view builder arguments.
|
|
120
|
+
* @param _duplicationScope - Optional string used to scope duplication (used
|
|
121
|
+
* by guards); an empty string `''` is converted to the `undefined` scope
|
|
122
|
+
*/
|
|
123
|
+
@guardedBy('isNotDuplicated', { onBlocked: 'onBlockedByDuplication' })
|
|
124
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
125
|
+
async trackFlagView(payload, _duplicationScope = '') {
|
|
126
|
+
logger.debug(`Processing "flag view" event for ${payload.componentId}`);
|
|
127
|
+
await this.enqueueEvent(this.builder.buildFlagView(payload));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Intercept, validate, and place an event into the profile‑scoped queue; then
|
|
131
|
+
* trigger a size‑based flush if necessary.
|
|
132
|
+
*
|
|
133
|
+
* @param event - The event to enqueue.
|
|
134
|
+
*/
|
|
135
|
+
async enqueueEvent(event) {
|
|
136
|
+
const { value: profile } = profileSignal;
|
|
137
|
+
if (!profile) {
|
|
138
|
+
logger.warn('Attempting to emit an event without an Optimization profile');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const intercepted = await this.interceptors.event.run(event);
|
|
142
|
+
const validEvent = AnalyticsEvent.parse(intercepted);
|
|
143
|
+
logger.debug(`Queueing ${validEvent.type} event for profile ${profile.id}`, validEvent);
|
|
144
|
+
const profileEventQueue = this.queue.get(profile);
|
|
145
|
+
eventSignal.value = validEvent;
|
|
146
|
+
if (profileEventQueue) {
|
|
147
|
+
profileEventQueue.push(validEvent);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
this.queue.set(profile, [validEvent]);
|
|
151
|
+
}
|
|
152
|
+
await this.flushMaxEvents();
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Flush the queue automatically when the total number of queued events
|
|
156
|
+
* reaches {@link MAX_QUEUED_EVENTS}.
|
|
157
|
+
*/
|
|
158
|
+
async flushMaxEvents() {
|
|
159
|
+
if (this.queue.values().toArray().flat().length >= MAX_QUEUED_EVENTS)
|
|
160
|
+
await this.flush();
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Send all queued events grouped by profile and clear the queue.
|
|
164
|
+
* @remarks Only under rare circumstances should there be more than one
|
|
165
|
+
* profile in a stateful application.
|
|
166
|
+
*/
|
|
167
|
+
async flush() {
|
|
168
|
+
logger.debug('Flushing event queue');
|
|
169
|
+
const batches = [];
|
|
170
|
+
this.queue.forEach((events, profile) => batches.push({ profile, events }));
|
|
171
|
+
if (!batches.length)
|
|
172
|
+
return;
|
|
173
|
+
const sendSuccess = await this.api.insights.sendBatchEvents(batches);
|
|
174
|
+
if (sendSuccess)
|
|
175
|
+
this.queue.clear();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export default AnalyticsStateful;
|
|
179
|
+
//# sourceMappingURL=AnalyticsStateful.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsStateful.js","sourceRoot":"","sources":["../../src/analytics/AnalyticsStateful.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ComponentViewBuilderArgs, type PartialProfile } from '@contentful/optimization-api-client';
|
|
2
|
+
import AnalyticsBase from './AnalyticsBase';
|
|
3
|
+
/**
|
|
4
|
+
* Arguments for tracking a component/flag view in stateless mode.
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
* @remarks
|
|
8
|
+
* The `profile` is optional; when omitted, the APIs may infer identity via
|
|
9
|
+
* other means.
|
|
10
|
+
*/
|
|
11
|
+
export type TrackViewArgs = ComponentViewBuilderArgs & {
|
|
12
|
+
profile?: PartialProfile;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Stateless analytics implementation that sends each event immediately in a
|
|
16
|
+
* single‑event batch.
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
declare class AnalyticsStateless extends AnalyticsBase {
|
|
21
|
+
/**
|
|
22
|
+
* Build, intercept, validate, and send a component view event.
|
|
23
|
+
*
|
|
24
|
+
* @param args - {@link TrackViewArgs} used to build the event. Includes an
|
|
25
|
+
* optional partial profile.
|
|
26
|
+
* @returns A promise that resolves once the batch has been sent.
|
|
27
|
+
*/
|
|
28
|
+
trackComponentView(args: TrackViewArgs): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Build, intercept, validate, and send a flag view event.
|
|
31
|
+
*
|
|
32
|
+
* @param args - {@link TrackViewArgs} used to build the event. Includes an
|
|
33
|
+
* optional partial profile.
|
|
34
|
+
* @returns A promise that resolves once the batch has been sent.
|
|
35
|
+
*/
|
|
36
|
+
trackFlagView(args: TrackViewArgs): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Send a single {@link InsightsEvent} wrapped in a one‑item batch.
|
|
39
|
+
*
|
|
40
|
+
* @param event - The event to send.
|
|
41
|
+
* @param profile - Optional partial profile to attach to the batch.
|
|
42
|
+
* @returns A promise that resolves when the API call completes.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
private sendBatchEvent;
|
|
46
|
+
}
|
|
47
|
+
export default AnalyticsStateless;
|
|
48
|
+
//# sourceMappingURL=AnalyticsStateless.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsStateless.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsStateless.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAG7B,KAAK,cAAc,EACpB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAI3C;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,wBAAwB,GAAG;IAAE,OAAO,CAAC,EAAE,cAAc,CAAA;CAAE,CAAA;AAEnF;;;;;GAKG;AACH,cAAM,kBAAmB,SAAQ,aAAa;IAC5C;;;;;;OAMG;IACG,kBAAkB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAc5D;;;;;;OAMG;IACG,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvD;;;;;;;OAOG;YACW,cAAc;CAU7B;AAED,eAAe,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { BatchInsightsEventArray, ComponentViewEvent, } from '@contentful/optimization-api-client';
|
|
2
|
+
import { createScopedLogger } from 'logger';
|
|
3
|
+
import AnalyticsBase from './AnalyticsBase';
|
|
4
|
+
const logger = createScopedLogger('Analytics');
|
|
5
|
+
/**
|
|
6
|
+
* Stateless analytics implementation that sends each event immediately in a
|
|
7
|
+
* single‑event batch.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
class AnalyticsStateless extends AnalyticsBase {
|
|
12
|
+
/**
|
|
13
|
+
* Build, intercept, validate, and send a component view event.
|
|
14
|
+
*
|
|
15
|
+
* @param args - {@link TrackViewArgs} used to build the event. Includes an
|
|
16
|
+
* optional partial profile.
|
|
17
|
+
* @returns A promise that resolves once the batch has been sent.
|
|
18
|
+
*/
|
|
19
|
+
async trackComponentView(args) {
|
|
20
|
+
logger.info('Processing "component view" event');
|
|
21
|
+
const { profile, ...builderArgs } = args;
|
|
22
|
+
const event = this.builder.buildComponentView(builderArgs);
|
|
23
|
+
const intercepted = await this.interceptors.event.run(event);
|
|
24
|
+
const parsed = ComponentViewEvent.parse(intercepted);
|
|
25
|
+
await this.sendBatchEvent(parsed, profile);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build, intercept, validate, and send a flag view event.
|
|
29
|
+
*
|
|
30
|
+
* @param args - {@link TrackViewArgs} used to build the event. Includes an
|
|
31
|
+
* optional partial profile.
|
|
32
|
+
* @returns A promise that resolves once the batch has been sent.
|
|
33
|
+
*/
|
|
34
|
+
async trackFlagView(args) {
|
|
35
|
+
logger.debug('Processing "flag view" event');
|
|
36
|
+
const { profile, ...builderArgs } = args;
|
|
37
|
+
const event = this.builder.buildFlagView(builderArgs);
|
|
38
|
+
const intercepted = await this.interceptors.event.run(event);
|
|
39
|
+
const parsed = ComponentViewEvent.parse(intercepted);
|
|
40
|
+
await this.sendBatchEvent(parsed, profile);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Send a single {@link InsightsEvent} wrapped in a one‑item batch.
|
|
44
|
+
*
|
|
45
|
+
* @param event - The event to send.
|
|
46
|
+
* @param profile - Optional partial profile to attach to the batch.
|
|
47
|
+
* @returns A promise that resolves when the API call completes.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
async sendBatchEvent(event, profile) {
|
|
51
|
+
const batchEvent = BatchInsightsEventArray.parse([
|
|
52
|
+
{
|
|
53
|
+
profile,
|
|
54
|
+
events: [event],
|
|
55
|
+
},
|
|
56
|
+
]);
|
|
57
|
+
await this.api.insights.sendBatchEvents(batchEvent);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export default AnalyticsStateless;
|
|
61
|
+
//# sourceMappingURL=AnalyticsStateless.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsStateless.js","sourceRoot":"","sources":["../../src/analytics/AnalyticsStateless.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAEvB,kBAAkB,GAGnB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AAC3C,OAAO,aAAa,MAAM,iBAAiB,CAAA;AAE3C,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;AAY9C;;;;;GAKG;AACH,MAAM,kBAAmB,SAAQ,aAAa;IAC5C;;;;;;OAMG;IACH,KAAK,CAAC,kBAAkB,CAAC,IAAmB;QAC1C,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;QAEhD,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,CAAA;QAExC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAA;QAE1D,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAE5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAEpD,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,aAAa,CAAC,IAAmB;QACrC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;QAE5C,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,CAAA;QAExC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;QAErD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAE5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAEpD,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,cAAc,CAAC,KAAoB,EAAE,OAAwB;QACzE,MAAM,UAAU,GAA4B,uBAAuB,CAAC,KAAK,CAAC;YACxE;gBACE,OAAO;gBACP,MAAM,EAAE,CAAC,KAAK,CAAC;aAChB;SACF,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;IACrD,CAAC;CACF;AAED,eAAe,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAElE,cAAc,sBAAsB,CAAA;AACpC,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAA;AACnC,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAElE,cAAc,sBAAsB,CAAA;AACpC,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const OPTIMIZATION_CORE_SDK_VERSION: string;
|
|
2
|
+
/**
|
|
3
|
+
* Anonymous-ID cookie name used by the Optimization Core.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
* @remarks
|
|
7
|
+
* This constant represents the cookie key used by the Optimization Framework
|
|
8
|
+
* to persist an anonymous identifier for tracking personalization and analytics
|
|
9
|
+
* events when no explicit profile is known.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core'
|
|
14
|
+
* const profileId = request.cookies[ANONYMOUS_ID_COOKIE]
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare const ANONYMOUS_ID_COOKIE = "ctfl-opt-aid";
|
|
18
|
+
//# sourceMappingURL=global-constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-constants.d.ts","sourceRoot":"","sources":["../src/global-constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,6BAA6B,QACyC,CAAA;AAEnF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const OPTIMIZATION_CORE_SDK_VERSION = typeof __OPTIMIZATION_VERSION__ === 'string' ? __OPTIMIZATION_VERSION__ : '0.0.0';
|
|
2
|
+
/**
|
|
3
|
+
* Anonymous-ID cookie name used by the Optimization Core.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
* @remarks
|
|
7
|
+
* This constant represents the cookie key used by the Optimization Framework
|
|
8
|
+
* to persist an anonymous identifier for tracking personalization and analytics
|
|
9
|
+
* events when no explicit profile is known.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { ANONYMOUS_ID_COOKIE } from '@contentful/optimization-core'
|
|
14
|
+
* const profileId = request.cookies[ANONYMOUS_ID_COOKIE]
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const ANONYMOUS_ID_COOKIE = 'ctfl-opt-aid';
|
|
18
|
+
//# sourceMappingURL=global-constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-constants.js","sourceRoot":"","sources":["../src/global-constants.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,6BAA6B,GACxC,OAAO,wBAAwB,KAAK,QAAQ,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,OAAO,CAAA;AAEnF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,cAAc,CAAA"}
|