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