@contentful/optimization-core 0.1.0-alpha → 0.1.0-alpha11
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 +329 -93
- package/dist/160.mjs +3 -0
- 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/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 +63 -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 +1509 -1715
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2523 -0
- package/dist/index.d.mts +2523 -0
- package/dist/index.d.ts +2523 -15
- package/dist/index.mjs +1215 -1362
- 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 +78 -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,824 +1,298 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return acc;
|
|
14
|
-
}, {});
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
const resolvers_FlagsResolver = FlagsResolver;
|
|
18
|
-
class Logger {
|
|
19
|
-
name = '@contentful/optimization';
|
|
20
|
-
PREFIX_PARTS = [
|
|
21
|
-
'Ctfl',
|
|
22
|
-
'O10n'
|
|
23
|
-
];
|
|
24
|
-
DELIMITER = ':';
|
|
25
|
-
diary;
|
|
26
|
-
sinks = [];
|
|
27
|
-
constructor(){
|
|
28
|
-
this.diary = diary(this.name, this.onLogEvent.bind(this));
|
|
29
|
-
enable(this.name);
|
|
30
|
-
}
|
|
31
|
-
assembleLocationPrefix(logLocation) {
|
|
32
|
-
return `[${[
|
|
33
|
-
...this.PREFIX_PARTS,
|
|
34
|
-
logLocation
|
|
35
|
-
].join(this.DELIMITER)}]`;
|
|
36
|
-
}
|
|
37
|
-
addSink(sink) {
|
|
38
|
-
this.sinks = [
|
|
39
|
-
...this.sinks.filter((existingSink)=>existingSink.name !== sink.name),
|
|
40
|
-
sink
|
|
41
|
-
];
|
|
42
|
-
}
|
|
43
|
-
removeSink(name) {
|
|
44
|
-
this.sinks = this.sinks.filter((sink)=>sink.name !== name);
|
|
45
|
-
}
|
|
46
|
-
removeSinks() {
|
|
47
|
-
this.sinks = [];
|
|
48
|
-
}
|
|
49
|
-
debug(logLocation, message, ...args) {
|
|
50
|
-
this.diary.debug(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
51
|
-
}
|
|
52
|
-
info(logLocation, message, ...args) {
|
|
53
|
-
this.diary.info(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
54
|
-
}
|
|
55
|
-
log(logLocation, message, ...args) {
|
|
56
|
-
this.diary.log(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
57
|
-
}
|
|
58
|
-
warn(logLocation, message, ...args) {
|
|
59
|
-
this.diary.warn(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
60
|
-
}
|
|
61
|
-
error(logLocation, message, ...args) {
|
|
62
|
-
this.diary.error(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
63
|
-
}
|
|
64
|
-
fatal(logLocation, message, ...args) {
|
|
65
|
-
this.diary.fatal(`${this.assembleLocationPrefix(logLocation)} ${message}`, ...args);
|
|
66
|
-
}
|
|
67
|
-
onLogEvent(event) {
|
|
68
|
-
this.sinks.forEach((sink)=>{
|
|
69
|
-
sink.ingest(event);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
1
|
+
import { batch, computed, effect, signal, untracked } from "@preact/signals-core";
|
|
2
|
+
import { cloneDeep } from "es-toolkit";
|
|
3
|
+
import { merge } from "es-toolkit/object";
|
|
4
|
+
import { boolean as mini_boolean, extend, number, object, optional, partial, prefault, string } from "zod/mini";
|
|
5
|
+
import { isEqual as predicate_isEqual } from "es-toolkit/predicate";
|
|
6
|
+
import { __rspack_external__contentful_optimization_api_client_api_schemas_4192893e } from "./160.mjs";
|
|
7
|
+
import { __rspack_external__contentful_optimization_api_client_logger_f0d05f82 } from "./499.mjs";
|
|
8
|
+
import { __rspack_external__contentful_optimization_api_client_cba5a7ee } from "./942.mjs";
|
|
9
|
+
import { OPTIMIZATION_CORE_SDK_NAME, OPTIMIZATION_CORE_SDK_VERSION } from "./260.mjs";
|
|
10
|
+
import { PREVIEW_PANEL_SIGNALS_SYMBOL, PREVIEW_PANEL_SIGNAL_FNS_SYMBOL } from "./632.mjs";
|
|
11
|
+
function isNonNullish(value) {
|
|
12
|
+
return null != value;
|
|
72
13
|
}
|
|
73
|
-
|
|
74
|
-
|
|
14
|
+
function toError(value) {
|
|
15
|
+
if (value instanceof Error) return value;
|
|
16
|
+
return new Error(`Subscriber threw non-Error value: ${String(value)}`);
|
|
17
|
+
}
|
|
18
|
+
function toObservable(s) {
|
|
75
19
|
return {
|
|
76
|
-
|
|
77
|
-
|
|
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);
|
|
20
|
+
get current () {
|
|
21
|
+
return cloneDeep(s.value);
|
|
90
22
|
},
|
|
91
|
-
|
|
92
|
-
|
|
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');
|
|
133
|
-
const RESOLUTION_WARNING_BASE = 'Could not resolve Merge Tag value:';
|
|
134
|
-
const MergeTagValueResolver = {
|
|
135
|
-
isMergeTagEntry (embeddedEntryNodeTarget) {
|
|
136
|
-
return __rspack_external__contentful_optimization_api_client_cba5a7ee.MergeTagEntry.safeParse(embeddedEntryNodeTarget).success;
|
|
137
|
-
},
|
|
138
|
-
normalizeSelectors (id) {
|
|
139
|
-
return id.split('_').map((_path, index, paths)=>{
|
|
140
|
-
const dotPath = paths.slice(0, index).join('.');
|
|
141
|
-
const underScorePath = paths.slice(index).join('_');
|
|
142
|
-
return [
|
|
143
|
-
dotPath,
|
|
144
|
-
underScorePath
|
|
145
|
-
].filter((path)=>'' !== path).join('.');
|
|
146
|
-
});
|
|
147
|
-
},
|
|
148
|
-
getValueFromProfile (id, profile) {
|
|
149
|
-
const selectors = MergeTagValueResolver.normalizeSelectors(id);
|
|
150
|
-
const matchingSelector = selectors.find((selector)=>compat_get(profile, selector));
|
|
151
|
-
if (!matchingSelector) return;
|
|
152
|
-
const value = compat_get(profile, matchingSelector);
|
|
153
|
-
if (!value || 'string' != typeof value && 'number' != typeof value && 'boolean' != typeof value) return;
|
|
154
|
-
return `${value}`;
|
|
155
|
-
},
|
|
156
|
-
resolve (mergeTagEntry, profile) {
|
|
157
|
-
if (!MergeTagValueResolver.isMergeTagEntry(mergeTagEntry)) return void MergeTagValueResolver_logger.warn(`${RESOLUTION_WARNING_BASE} supplied entry is not a Merge Tag entry`);
|
|
158
|
-
const { fields: { nt_fallback: fallback } } = mergeTagEntry;
|
|
159
|
-
if (!__rspack_external__contentful_optimization_api_client_cba5a7ee.Profile.safeParse(profile).success) {
|
|
160
|
-
MergeTagValueResolver_logger.warn(`${RESOLUTION_WARNING_BASE} no valid profile`);
|
|
161
|
-
return fallback;
|
|
162
|
-
}
|
|
163
|
-
return MergeTagValueResolver.getValueFromProfile(mergeTagEntry.fields.nt_mergetag_id, profile) ?? fallback;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
const resolvers_MergeTagValueResolver = MergeTagValueResolver;
|
|
167
|
-
const PersonalizedEntryResolver_logger = createScopedLogger('Personalization');
|
|
168
|
-
const PersonalizedEntryResolver_RESOLUTION_WARNING_BASE = 'Could not resolve personalized entry variant:';
|
|
169
|
-
const PersonalizedEntryResolver = {
|
|
170
|
-
getPersonalizationEntry ({ personalizedEntry, selectedPersonalizations }, skipValidation = false) {
|
|
171
|
-
if (!skipValidation && (!selectedPersonalizations.length || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizedEntry)(personalizedEntry))) return;
|
|
172
|
-
const personalizationEntry = personalizedEntry.fields.nt_experiences.filter((maybePersonalization)=>(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(maybePersonalization)).find((personalizationEntry)=>selectedPersonalizations.some(({ experienceId })=>experienceId === personalizationEntry.fields.nt_experience_id));
|
|
173
|
-
return personalizationEntry;
|
|
174
|
-
},
|
|
175
|
-
getSelectedPersonalization ({ personalizationEntry, selectedPersonalizations }, skipValidation = false) {
|
|
176
|
-
if (!skipValidation && (!selectedPersonalizations.length || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(personalizationEntry))) return;
|
|
177
|
-
const selectedPersonalization = selectedPersonalizations.find(({ experienceId })=>experienceId === personalizationEntry.fields.nt_experience_id);
|
|
178
|
-
return selectedPersonalization;
|
|
179
|
-
},
|
|
180
|
-
getSelectedVariant ({ personalizedEntry, personalizationEntry, selectedVariantIndex }, skipValidation = false) {
|
|
181
|
-
if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizedEntry)(personalizedEntry) || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(personalizationEntry))) return;
|
|
182
|
-
const relevantVariants = personalizationEntry.fields.nt_config?.components?.filter((component)=>(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isEntryReplacementComponent)(component) && !component.baseline.hidden).find((component)=>component.baseline.id === personalizedEntry.sys.id)?.variants;
|
|
183
|
-
if (!relevantVariants?.length) return;
|
|
184
|
-
return relevantVariants.at(selectedVariantIndex - 1);
|
|
185
|
-
},
|
|
186
|
-
getSelectedVariantEntry ({ personalizationEntry, selectedVariant }, skipValidation = false) {
|
|
187
|
-
if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizationEntry)(personalizationEntry) || !(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isEntryReplacementVariant)(selectedVariant))) return;
|
|
188
|
-
const selectedVariantEntry = personalizationEntry.fields.nt_variants?.find((variant)=>variant.sys.id === selectedVariant.id);
|
|
189
|
-
return (0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isEntry)(selectedVariantEntry) ? selectedVariantEntry : void 0;
|
|
190
|
-
},
|
|
191
|
-
resolve (entry, selectedPersonalizations) {
|
|
192
|
-
PersonalizedEntryResolver_logger.debug(`Resolving personalized entry for baseline entry ${entry.sys.id}`);
|
|
193
|
-
if (!selectedPersonalizations?.length) {
|
|
194
|
-
PersonalizedEntryResolver_logger.warn(`${PersonalizedEntryResolver_RESOLUTION_WARNING_BASE} no selectedPersonalizations exist for the current profile`);
|
|
195
|
-
return {
|
|
196
|
-
entry
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
if (!(0, __rspack_external__contentful_optimization_api_client_cba5a7ee.isPersonalizedEntry)(entry)) {
|
|
200
|
-
PersonalizedEntryResolver_logger.warn(`${PersonalizedEntryResolver_RESOLUTION_WARNING_BASE} entry ${entry.sys.id} is not personalized`);
|
|
201
|
-
return {
|
|
202
|
-
entry
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
const personalizationEntry = PersonalizedEntryResolver.getPersonalizationEntry({
|
|
206
|
-
personalizedEntry: entry,
|
|
207
|
-
selectedPersonalizations
|
|
208
|
-
}, true);
|
|
209
|
-
if (!personalizationEntry) {
|
|
210
|
-
PersonalizedEntryResolver_logger.warn(`${PersonalizedEntryResolver_RESOLUTION_WARNING_BASE} could not find a personalization entry for ${entry.sys.id}`);
|
|
211
|
-
return {
|
|
212
|
-
entry
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
const selectedPersonalization = PersonalizedEntryResolver.getSelectedPersonalization({
|
|
216
|
-
personalizationEntry,
|
|
217
|
-
selectedPersonalizations
|
|
218
|
-
}, true);
|
|
219
|
-
const selectedVariantIndex = selectedPersonalization?.variantIndex ?? 0;
|
|
220
|
-
if (0 === selectedVariantIndex) {
|
|
221
|
-
PersonalizedEntryResolver_logger.debug(`Resolved personalization entry for entry ${entry.sys.id} is baseline`);
|
|
23
|
+
subscribe (next) {
|
|
24
|
+
const dispose = effect(()=>{
|
|
25
|
+
next(cloneDeep(s.value));
|
|
26
|
+
});
|
|
222
27
|
return {
|
|
223
|
-
|
|
28
|
+
unsubscribe: dispose
|
|
224
29
|
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
entry
|
|
30
|
+
},
|
|
31
|
+
subscribeOnce (next) {
|
|
32
|
+
let closed = false;
|
|
33
|
+
let isEffectActive = false;
|
|
34
|
+
let dispose = ()=>void 0;
|
|
35
|
+
const stop = ()=>{
|
|
36
|
+
if (closed) return;
|
|
37
|
+
closed = true;
|
|
38
|
+
if (isEffectActive) dispose();
|
|
235
39
|
};
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
40
|
+
dispose = effect(()=>{
|
|
41
|
+
if (closed) return;
|
|
42
|
+
const { value } = s;
|
|
43
|
+
if (!isNonNullish(value)) return;
|
|
44
|
+
closed = true;
|
|
45
|
+
let callbackError = null;
|
|
46
|
+
try {
|
|
47
|
+
next(cloneDeep(value));
|
|
48
|
+
} catch (error) {
|
|
49
|
+
callbackError = toError(error);
|
|
50
|
+
}
|
|
51
|
+
if (isEffectActive) dispose();
|
|
52
|
+
else queueMicrotask(dispose);
|
|
53
|
+
if (callbackError) throw callbackError;
|
|
54
|
+
});
|
|
55
|
+
isEffectActive = true;
|
|
244
56
|
return {
|
|
245
|
-
|
|
57
|
+
unsubscribe: stop
|
|
246
58
|
};
|
|
247
59
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
const resolvers_PersonalizedEntryResolver = PersonalizedEntryResolver;
|
|
255
|
-
const signals_changes = signal();
|
|
256
|
-
const consent = signal();
|
|
257
|
-
const signals_event = signal();
|
|
258
|
-
const flags = computed(()=>resolvers_FlagsResolver.resolve(signals_changes.value ?? []));
|
|
259
|
-
const online = signal(true);
|
|
260
|
-
const signals_personalizations = signal();
|
|
261
|
-
const signals_profile = signal();
|
|
262
|
-
function toObservable(s) {
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function toDistinctObservable(s, isEqual) {
|
|
63
|
+
const observable = toObservable(s);
|
|
263
64
|
return {
|
|
65
|
+
get current () {
|
|
66
|
+
return observable.current;
|
|
67
|
+
},
|
|
264
68
|
subscribe (next) {
|
|
265
|
-
|
|
266
|
-
|
|
69
|
+
let hasPrevious = false;
|
|
70
|
+
let previous = cloneDeep(observable.current);
|
|
71
|
+
return observable.subscribe((value)=>{
|
|
72
|
+
if (hasPrevious && isEqual(previous, value)) return;
|
|
73
|
+
hasPrevious = true;
|
|
74
|
+
previous = cloneDeep(value);
|
|
75
|
+
next(value);
|
|
267
76
|
});
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
77
|
+
},
|
|
78
|
+
subscribeOnce (next) {
|
|
79
|
+
return observable.subscribeOnce(next);
|
|
271
80
|
}
|
|
272
81
|
};
|
|
273
82
|
}
|
|
83
|
+
const signals_changes = signal();
|
|
84
|
+
const blockedEvent = signal();
|
|
85
|
+
const consent = signal();
|
|
86
|
+
const signals_event = signal();
|
|
87
|
+
const online = signal(true);
|
|
88
|
+
const previewPanelAttached = signal(false);
|
|
89
|
+
const previewPanelOpen = signal(false);
|
|
90
|
+
const signals_selectedOptimizations = signal();
|
|
91
|
+
const canOptimize = computed(()=>void 0 !== signals_selectedOptimizations.value);
|
|
92
|
+
const signals_profile = signal();
|
|
274
93
|
const signals = {
|
|
94
|
+
blockedEvent: blockedEvent,
|
|
275
95
|
changes: signals_changes,
|
|
276
96
|
consent: consent,
|
|
277
97
|
event: signals_event,
|
|
278
|
-
flags: flags,
|
|
279
98
|
online: online,
|
|
280
|
-
|
|
99
|
+
previewPanelAttached: previewPanelAttached,
|
|
100
|
+
previewPanelOpen: previewPanelOpen,
|
|
101
|
+
selectedOptimizations: signals_selectedOptimizations,
|
|
102
|
+
canOptimize: canOptimize,
|
|
281
103
|
profile: signals_profile
|
|
282
104
|
};
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
377
|
-
return function(initializer) {
|
|
378
|
-
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
379
|
-
assertCallable(initializer, "An initializer");
|
|
380
|
-
initializers.push(initializer);
|
|
105
|
+
const signalFns = {
|
|
106
|
+
batch: batch,
|
|
107
|
+
computed: computed,
|
|
108
|
+
effect: effect,
|
|
109
|
+
untracked: untracked
|
|
110
|
+
};
|
|
111
|
+
const UniversalEventBuilderArgs = object({
|
|
112
|
+
campaign: optional(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Campaign),
|
|
113
|
+
locale: optional(string()),
|
|
114
|
+
location: optional(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.GeoLocation),
|
|
115
|
+
page: optional(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Page),
|
|
116
|
+
screen: optional(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Screen),
|
|
117
|
+
userAgent: optional(string())
|
|
118
|
+
});
|
|
119
|
+
const EntryInteractionBuilderArgsBase = extend(UniversalEventBuilderArgs, {
|
|
120
|
+
componentId: string(),
|
|
121
|
+
experienceId: optional(string()),
|
|
122
|
+
variantIndex: optional(number())
|
|
123
|
+
});
|
|
124
|
+
const ViewBuilderArgs = extend(EntryInteractionBuilderArgsBase, {
|
|
125
|
+
sticky: optional(mini_boolean()),
|
|
126
|
+
viewId: string(),
|
|
127
|
+
viewDurationMs: number()
|
|
128
|
+
});
|
|
129
|
+
const FlagViewBuilderArgs = extend(EntryInteractionBuilderArgsBase, {
|
|
130
|
+
viewId: optional(string()),
|
|
131
|
+
viewDurationMs: optional(number())
|
|
132
|
+
});
|
|
133
|
+
const ClickBuilderArgs = EntryInteractionBuilderArgsBase;
|
|
134
|
+
const HoverBuilderArgs = extend(EntryInteractionBuilderArgsBase, {
|
|
135
|
+
hoverId: string(),
|
|
136
|
+
hoverDurationMs: number()
|
|
137
|
+
});
|
|
138
|
+
const IdentifyBuilderArgs = extend(UniversalEventBuilderArgs, {
|
|
139
|
+
traits: optional(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Traits),
|
|
140
|
+
userId: string()
|
|
141
|
+
});
|
|
142
|
+
const PageViewBuilderArgs = extend(UniversalEventBuilderArgs, {
|
|
143
|
+
properties: optional(partial(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Page))
|
|
144
|
+
});
|
|
145
|
+
const ScreenViewBuilderArgs = extend(UniversalEventBuilderArgs, {
|
|
146
|
+
name: string(),
|
|
147
|
+
properties: __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Properties
|
|
148
|
+
});
|
|
149
|
+
const TrackBuilderArgs = extend(UniversalEventBuilderArgs, {
|
|
150
|
+
event: string(),
|
|
151
|
+
properties: optional(prefault(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Properties, {}))
|
|
152
|
+
});
|
|
153
|
+
const DEFAULT_PAGE_PROPERTIES = {
|
|
154
|
+
path: '',
|
|
155
|
+
query: {},
|
|
156
|
+
referrer: '',
|
|
157
|
+
search: '',
|
|
158
|
+
title: '',
|
|
159
|
+
url: ''
|
|
160
|
+
};
|
|
161
|
+
class EventBuilder {
|
|
162
|
+
app;
|
|
163
|
+
channel;
|
|
164
|
+
library;
|
|
165
|
+
getLocale;
|
|
166
|
+
getPageProperties;
|
|
167
|
+
getUserAgent;
|
|
168
|
+
constructor(config){
|
|
169
|
+
const { app, channel, library, getLocale, getPageProperties, getUserAgent } = config;
|
|
170
|
+
this.app = app;
|
|
171
|
+
this.channel = channel;
|
|
172
|
+
this.library = library;
|
|
173
|
+
this.getLocale = getLocale ?? (()=>'en-US');
|
|
174
|
+
this.getPageProperties = getPageProperties ?? (()=>DEFAULT_PAGE_PROPERTIES);
|
|
175
|
+
this.getUserAgent = getUserAgent ?? (()=>void 0);
|
|
176
|
+
}
|
|
177
|
+
buildUniversalEventProperties({ campaign = {}, locale, location, page, screen, userAgent }) {
|
|
178
|
+
const timestamp = new Date().toISOString();
|
|
179
|
+
return {
|
|
180
|
+
channel: this.channel,
|
|
181
|
+
context: {
|
|
182
|
+
app: this.app,
|
|
183
|
+
campaign,
|
|
184
|
+
gdpr: {
|
|
185
|
+
isConsentGiven: true
|
|
186
|
+
},
|
|
187
|
+
library: this.library,
|
|
188
|
+
locale: locale ?? this.getLocale() ?? 'en-US',
|
|
189
|
+
location,
|
|
190
|
+
page: page ?? this.getPageProperties(),
|
|
191
|
+
screen,
|
|
192
|
+
userAgent: userAgent ?? this.getUserAgent()
|
|
193
|
+
},
|
|
194
|
+
messageId: crypto.randomUUID(),
|
|
195
|
+
originalTimestamp: timestamp,
|
|
196
|
+
sentAt: timestamp,
|
|
197
|
+
timestamp
|
|
381
198
|
};
|
|
382
199
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
kindStr = "method";
|
|
391
|
-
break;
|
|
392
|
-
case 3:
|
|
393
|
-
kindStr = "getter";
|
|
394
|
-
break;
|
|
395
|
-
case 4:
|
|
396
|
-
kindStr = "setter";
|
|
397
|
-
break;
|
|
398
|
-
default:
|
|
399
|
-
kindStr = "field";
|
|
400
|
-
}
|
|
401
|
-
var ctx = {
|
|
402
|
-
kind: kindStr,
|
|
403
|
-
name: isPrivate ? "#" + name : name,
|
|
404
|
-
static: isStatic,
|
|
405
|
-
private: isPrivate,
|
|
406
|
-
metadata: metadata
|
|
407
|
-
};
|
|
408
|
-
var decoratorFinishedRef = {
|
|
409
|
-
v: false
|
|
410
|
-
};
|
|
411
|
-
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
412
|
-
var get, set;
|
|
413
|
-
if (0 === kind) if (isPrivate) {
|
|
414
|
-
get = desc.get;
|
|
415
|
-
set = desc.set;
|
|
416
|
-
} else {
|
|
417
|
-
get = function() {
|
|
418
|
-
return this[name];
|
|
419
|
-
};
|
|
420
|
-
set = function(v) {
|
|
421
|
-
this[name] = v;
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
else if (2 === kind) get = function() {
|
|
425
|
-
return desc.value;
|
|
426
|
-
};
|
|
427
|
-
else {
|
|
428
|
-
if (1 === kind || 3 === kind) get = function() {
|
|
429
|
-
return desc.get.call(this);
|
|
430
|
-
};
|
|
431
|
-
if (1 === kind || 4 === kind) set = function(v) {
|
|
432
|
-
desc.set.call(this, v);
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
ctx.access = get && set ? {
|
|
436
|
-
get: get,
|
|
437
|
-
set: set
|
|
438
|
-
} : get ? {
|
|
439
|
-
get: get
|
|
440
|
-
} : {
|
|
441
|
-
set: set
|
|
200
|
+
buildEntryInteractionBase(universal, componentId, experienceId, variantIndex) {
|
|
201
|
+
return {
|
|
202
|
+
...this.buildUniversalEventProperties(universal),
|
|
203
|
+
componentType: 'Entry',
|
|
204
|
+
componentId,
|
|
205
|
+
experienceId,
|
|
206
|
+
variantIndex: variantIndex ?? 0
|
|
442
207
|
};
|
|
443
|
-
try {
|
|
444
|
-
return dec(value, ctx);
|
|
445
|
-
} finally{
|
|
446
|
-
decoratorFinishedRef.v = true;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
function assertNotFinished(decoratorFinishedRef, fnName) {
|
|
450
|
-
if (decoratorFinishedRef.v) throw new Error("attempted to call " + fnName + " after decoration was finished");
|
|
451
|
-
}
|
|
452
|
-
function assertCallable(fn, hint) {
|
|
453
|
-
if ("function" != typeof fn) throw new TypeError(hint + " must be a function");
|
|
454
|
-
}
|
|
455
|
-
function assertValidReturnValue(kind, value) {
|
|
456
|
-
var type = typeof value;
|
|
457
|
-
if (1 === kind) {
|
|
458
|
-
if ("object" !== type || null === value) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
459
|
-
if (void 0 !== value.get) assertCallable(value.get, "accessor.get");
|
|
460
|
-
if (void 0 !== value.set) assertCallable(value.set, "accessor.set");
|
|
461
|
-
if (void 0 !== value.init) assertCallable(value.init, "accessor.init");
|
|
462
|
-
} else if ("function" !== type) {
|
|
463
|
-
var hint;
|
|
464
|
-
hint = 0 === kind ? "field" : 10 === kind ? "class" : "method";
|
|
465
|
-
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
466
|
-
}
|
|
467
208
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
get: decInfo[3]
|
|
476
|
-
} : 4 === kind ? {
|
|
477
|
-
set: decInfo[3]
|
|
478
|
-
} : {
|
|
479
|
-
value: decInfo[3]
|
|
480
|
-
};
|
|
481
|
-
else if (0 !== kind) desc = Object.getOwnPropertyDescriptor(base, name);
|
|
482
|
-
if (1 === kind) value = {
|
|
483
|
-
get: desc.get,
|
|
484
|
-
set: desc.set
|
|
209
|
+
buildView(args) {
|
|
210
|
+
const { componentId, viewId, experienceId, variantIndex, viewDurationMs, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(ViewBuilderArgs, args);
|
|
211
|
+
return {
|
|
212
|
+
...this.buildEntryInteractionBase(universal, componentId, experienceId, variantIndex),
|
|
213
|
+
type: 'component',
|
|
214
|
+
viewId,
|
|
215
|
+
viewDurationMs
|
|
485
216
|
};
|
|
486
|
-
else if (2 === kind) value = desc.value;
|
|
487
|
-
else if (3 === kind) value = desc.get;
|
|
488
|
-
else if (4 === kind) value = desc.set;
|
|
489
|
-
var newValue, get, set;
|
|
490
|
-
if ("function" == typeof decs) {
|
|
491
|
-
newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
492
|
-
if (void 0 !== newValue) {
|
|
493
|
-
assertValidReturnValue(kind, newValue);
|
|
494
|
-
if (0 === kind) init = newValue;
|
|
495
|
-
else if (1 === kind) {
|
|
496
|
-
init = newValue.init;
|
|
497
|
-
get = newValue.get || value.get;
|
|
498
|
-
set = newValue.set || value.set;
|
|
499
|
-
value = {
|
|
500
|
-
get: get,
|
|
501
|
-
set: set
|
|
502
|
-
};
|
|
503
|
-
} else value = newValue;
|
|
504
|
-
}
|
|
505
|
-
} else for(var i = decs.length - 1; i >= 0; i--){
|
|
506
|
-
var dec = decs[i];
|
|
507
|
-
newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
508
|
-
if (void 0 !== newValue) {
|
|
509
|
-
assertValidReturnValue(kind, newValue);
|
|
510
|
-
var newInit;
|
|
511
|
-
if (0 === kind) newInit = newValue;
|
|
512
|
-
else if (1 === kind) {
|
|
513
|
-
newInit = newValue.init;
|
|
514
|
-
get = newValue.get || value.get;
|
|
515
|
-
set = newValue.set || value.set;
|
|
516
|
-
value = {
|
|
517
|
-
get: get,
|
|
518
|
-
set: set
|
|
519
|
-
};
|
|
520
|
-
} else value = newValue;
|
|
521
|
-
if (void 0 !== newInit) if (void 0 === init) init = newInit;
|
|
522
|
-
else if ("function" == typeof init) init = [
|
|
523
|
-
init,
|
|
524
|
-
newInit
|
|
525
|
-
];
|
|
526
|
-
else init.push(newInit);
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
if (0 === kind || 1 === kind) {
|
|
530
|
-
if (void 0 === init) init = function(instance, init) {
|
|
531
|
-
return init;
|
|
532
|
-
};
|
|
533
|
-
else if ("function" != typeof init) {
|
|
534
|
-
var ownInitializers = init;
|
|
535
|
-
init = function(instance, init) {
|
|
536
|
-
var value = init;
|
|
537
|
-
for(var i = 0; i < ownInitializers.length; i++)value = ownInitializers[i].call(instance, value);
|
|
538
|
-
return value;
|
|
539
|
-
};
|
|
540
|
-
} else {
|
|
541
|
-
var originalInitializer = init;
|
|
542
|
-
init = function(instance, init) {
|
|
543
|
-
return originalInitializer.call(instance, init);
|
|
544
|
-
};
|
|
545
|
-
}
|
|
546
|
-
ret.push(init);
|
|
547
|
-
}
|
|
548
|
-
if (0 !== kind) {
|
|
549
|
-
if (1 === kind) {
|
|
550
|
-
desc.get = value.get;
|
|
551
|
-
desc.set = value.set;
|
|
552
|
-
} else if (2 === kind) desc.value = value;
|
|
553
|
-
else if (3 === kind) desc.get = value;
|
|
554
|
-
else if (4 === kind) desc.set = value;
|
|
555
|
-
if (isPrivate) if (1 === kind) {
|
|
556
|
-
ret.push(function(instance, args) {
|
|
557
|
-
return value.get.call(instance, args);
|
|
558
|
-
});
|
|
559
|
-
ret.push(function(instance, args) {
|
|
560
|
-
return value.set.call(instance, args);
|
|
561
|
-
});
|
|
562
|
-
} else if (2 === kind) ret.push(value);
|
|
563
|
-
else ret.push(function(instance, args) {
|
|
564
|
-
return value.call(instance, args);
|
|
565
|
-
});
|
|
566
|
-
else Object.defineProperty(base, name, desc);
|
|
567
|
-
}
|
|
568
217
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
var protoInitializers;
|
|
572
|
-
var staticInitializers;
|
|
573
|
-
var existingProtoNonFields = new Map();
|
|
574
|
-
var existingStaticNonFields = new Map();
|
|
575
|
-
for(var i = 0; i < decInfos.length; i++){
|
|
576
|
-
var decInfo = decInfos[i];
|
|
577
|
-
if (Array.isArray(decInfo)) {
|
|
578
|
-
var kind = decInfo[1];
|
|
579
|
-
var name = decInfo[2];
|
|
580
|
-
var isPrivate = decInfo.length > 3;
|
|
581
|
-
var isStatic = kind >= 5;
|
|
582
|
-
var base;
|
|
583
|
-
var initializers;
|
|
584
|
-
if (isStatic) {
|
|
585
|
-
base = Class;
|
|
586
|
-
kind -= 5;
|
|
587
|
-
staticInitializers = staticInitializers || [];
|
|
588
|
-
initializers = staticInitializers;
|
|
589
|
-
} else {
|
|
590
|
-
base = Class.prototype;
|
|
591
|
-
protoInitializers = protoInitializers || [];
|
|
592
|
-
initializers = protoInitializers;
|
|
593
|
-
}
|
|
594
|
-
if (0 !== kind && !isPrivate) {
|
|
595
|
-
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
596
|
-
var existingKind = existingNonFields.get(name) || 0;
|
|
597
|
-
if (true === existingKind || 3 === existingKind && 4 !== kind || 4 === existingKind && 3 !== kind) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
598
|
-
if (!existingKind && kind > 2) existingNonFields.set(name, kind);
|
|
599
|
-
else existingNonFields.set(name, true);
|
|
600
|
-
}
|
|
601
|
-
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
pushInitializers(ret, protoInitializers);
|
|
605
|
-
pushInitializers(ret, staticInitializers);
|
|
606
|
-
return ret;
|
|
607
|
-
}
|
|
608
|
-
function pushInitializers(ret, initializers) {
|
|
609
|
-
if (initializers) ret.push(function(instance) {
|
|
610
|
-
for(var i = 0; i < initializers.length; i++)initializers[i].call(instance);
|
|
611
|
-
return instance;
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
function applyClassDecs(targetClass, classDecs, metadata) {
|
|
615
|
-
if (classDecs.length > 0) {
|
|
616
|
-
var initializers = [];
|
|
617
|
-
var newClass = targetClass;
|
|
618
|
-
var name = targetClass.name;
|
|
619
|
-
for(var i = classDecs.length - 1; i >= 0; i--){
|
|
620
|
-
var decoratorFinishedRef = {
|
|
621
|
-
v: false
|
|
622
|
-
};
|
|
623
|
-
try {
|
|
624
|
-
var nextNewClass = classDecs[i](newClass, {
|
|
625
|
-
kind: "class",
|
|
626
|
-
name: name,
|
|
627
|
-
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
628
|
-
metadata
|
|
629
|
-
});
|
|
630
|
-
} finally{
|
|
631
|
-
decoratorFinishedRef.v = true;
|
|
632
|
-
}
|
|
633
|
-
if (void 0 !== nextNewClass) {
|
|
634
|
-
assertValidReturnValue(10, nextNewClass);
|
|
635
|
-
newClass = nextNewClass;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
return [
|
|
639
|
-
defineMetadata(newClass, metadata),
|
|
640
|
-
function() {
|
|
641
|
-
for(var i = 0; i < initializers.length; i++)initializers[i].call(newClass);
|
|
642
|
-
}
|
|
643
|
-
];
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
function defineMetadata(Class, metadata) {
|
|
647
|
-
return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
|
|
648
|
-
configurable: true,
|
|
649
|
-
enumerable: true,
|
|
650
|
-
value: metadata
|
|
651
|
-
});
|
|
652
|
-
}
|
|
653
|
-
return function(targetClass, memberDecs, classDecs, parentClass) {
|
|
654
|
-
if (void 0 !== parentClass) var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
|
|
655
|
-
var metadata = Object.create(void 0 === parentMetadata ? null : parentMetadata);
|
|
656
|
-
var e = applyMemberDecs(targetClass, memberDecs, metadata);
|
|
657
|
-
if (!classDecs.length) defineMetadata(targetClass, metadata);
|
|
218
|
+
buildClick(args) {
|
|
219
|
+
const { componentId, experienceId, variantIndex, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(ClickBuilderArgs, args);
|
|
658
220
|
return {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
return applyClassDecs(targetClass, classDecs, metadata);
|
|
662
|
-
}
|
|
221
|
+
...this.buildEntryInteractionBase(universal, componentId, experienceId, variantIndex),
|
|
222
|
+
type: 'component_click'
|
|
663
223
|
};
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
667
|
-
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
668
|
-
}
|
|
669
|
-
var _dec, _dec1, _dec2, _dec3, _initProto;
|
|
670
|
-
const AnalyticsStateful_logger = createScopedLogger('Analytics');
|
|
671
|
-
const MAX_QUEUED_EVENTS = 25;
|
|
672
|
-
_dec = guardedBy('isNotDuplicated', {
|
|
673
|
-
onBlocked: 'onBlockedByDuplication'
|
|
674
|
-
}), _dec1 = guardedBy('hasConsent', {
|
|
675
|
-
onBlocked: 'onBlockedByConsent'
|
|
676
|
-
}), _dec2 = guardedBy('isNotDuplicated', {
|
|
677
|
-
onBlocked: 'onBlockedByDuplication'
|
|
678
|
-
}), _dec3 = guardedBy('hasConsent', {
|
|
679
|
-
onBlocked: 'onBlockedByConsent'
|
|
680
|
-
});
|
|
681
|
-
class AnalyticsStateful extends analytics_AnalyticsBase {
|
|
682
|
-
static{
|
|
683
|
-
({ e: [_initProto] } = _apply_decs_2203_r(this, [
|
|
684
|
-
[
|
|
685
|
-
[
|
|
686
|
-
_dec,
|
|
687
|
-
_dec1
|
|
688
|
-
],
|
|
689
|
-
2,
|
|
690
|
-
"trackComponentView"
|
|
691
|
-
],
|
|
692
|
-
[
|
|
693
|
-
[
|
|
694
|
-
_dec2,
|
|
695
|
-
_dec3
|
|
696
|
-
],
|
|
697
|
-
2,
|
|
698
|
-
"trackFlagView"
|
|
699
|
-
]
|
|
700
|
-
], []));
|
|
701
|
-
}
|
|
702
|
-
queue = (_initProto(this), new Map());
|
|
703
|
-
states = {
|
|
704
|
-
eventStream: toObservable(signals_event),
|
|
705
|
-
profile: toObservable(signals_profile)
|
|
706
|
-
};
|
|
707
|
-
constructor(options){
|
|
708
|
-
const { api, builder, config, interceptors } = options;
|
|
709
|
-
super({
|
|
710
|
-
api,
|
|
711
|
-
builder,
|
|
712
|
-
config,
|
|
713
|
-
interceptors
|
|
714
|
-
});
|
|
715
|
-
const { defaults } = config ?? {};
|
|
716
|
-
if (defaults?.profile !== void 0) {
|
|
717
|
-
const { profile: defaultProfile } = defaults;
|
|
718
|
-
signals_profile.value = defaultProfile;
|
|
719
|
-
}
|
|
720
|
-
effect(()=>{
|
|
721
|
-
const id = signals_profile.value?.id;
|
|
722
|
-
AnalyticsStateful_logger.info(`Analytics ${consent.value ? 'will' : 'will not'} be collected due to consent (${consent.value})`);
|
|
723
|
-
AnalyticsStateful_logger.debug(`Profile ${id && `with ID ${id}`} has been ${id ? 'set' : 'cleared'}`);
|
|
724
|
-
});
|
|
725
|
-
effect(()=>{
|
|
726
|
-
if (online.value) this.flush();
|
|
727
|
-
});
|
|
728
224
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
}
|
|
738
|
-
onBlockedByConsent(name, payload) {
|
|
739
|
-
AnalyticsStateful_logger.warn(`Event "${name}" was blocked due to lack of consent; payload: ${JSON.stringify(payload)}`);
|
|
740
|
-
}
|
|
741
|
-
isNotDuplicated(_name, payload) {
|
|
742
|
-
const [{ componentId: value }, duplicationScope] = payload;
|
|
743
|
-
const isDuplicated = this.duplicationDetector.isPresent(duplicationScope, value);
|
|
744
|
-
if (!isDuplicated) this.duplicationDetector.addValue(duplicationScope, value);
|
|
745
|
-
return !isDuplicated;
|
|
746
|
-
}
|
|
747
|
-
onBlockedByDuplication(name, payload) {
|
|
748
|
-
const componentType = 'trackFlagView' === name ? 'flag' : 'component';
|
|
749
|
-
AnalyticsStateful_logger.debug(`Duplicate "${componentType} view" event detected, skipping; payload: ${JSON.stringify(payload)}`);
|
|
750
|
-
}
|
|
751
|
-
async trackComponentView(payload, _duplicationScope = '') {
|
|
752
|
-
AnalyticsStateful_logger.info(`Processing "component view" event for ${payload.componentId}`);
|
|
753
|
-
await this.enqueueEvent(this.builder.buildComponentView(payload));
|
|
225
|
+
buildHover(args) {
|
|
226
|
+
const { hoverId, componentId, experienceId, hoverDurationMs, variantIndex, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(HoverBuilderArgs, args);
|
|
227
|
+
return {
|
|
228
|
+
...this.buildEntryInteractionBase(universal, componentId, experienceId, variantIndex),
|
|
229
|
+
type: 'component_hover',
|
|
230
|
+
hoverId,
|
|
231
|
+
hoverDurationMs
|
|
232
|
+
};
|
|
754
233
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
234
|
+
buildFlagView(args) {
|
|
235
|
+
const { componentId, experienceId, variantIndex, viewId, viewDurationMs, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(FlagViewBuilderArgs, args);
|
|
236
|
+
return {
|
|
237
|
+
...this.buildEntryInteractionBase(universal, componentId, experienceId, variantIndex),
|
|
238
|
+
...void 0 === viewDurationMs ? {} : {
|
|
239
|
+
viewDurationMs
|
|
240
|
+
},
|
|
241
|
+
...void 0 === viewId ? {} : {
|
|
242
|
+
viewId
|
|
243
|
+
},
|
|
244
|
+
type: 'component',
|
|
245
|
+
componentType: 'Variable'
|
|
246
|
+
};
|
|
758
247
|
}
|
|
759
|
-
|
|
760
|
-
const {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
if (profileEventQueue) profileEventQueue.push(validEvent);
|
|
768
|
-
else this.queue.set(profile, [
|
|
769
|
-
validEvent
|
|
770
|
-
]);
|
|
771
|
-
await this.flushMaxEvents();
|
|
248
|
+
buildIdentify(args) {
|
|
249
|
+
const { traits = {}, userId, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(IdentifyBuilderArgs, args);
|
|
250
|
+
return {
|
|
251
|
+
...this.buildUniversalEventProperties(universal),
|
|
252
|
+
type: 'identify',
|
|
253
|
+
traits,
|
|
254
|
+
userId
|
|
255
|
+
};
|
|
772
256
|
}
|
|
773
|
-
|
|
774
|
-
|
|
257
|
+
buildPageView(args = {}) {
|
|
258
|
+
const { properties = {}, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(PageViewBuilderArgs, args);
|
|
259
|
+
const pageProperties = this.getPageProperties();
|
|
260
|
+
const merged = merge({
|
|
261
|
+
...pageProperties,
|
|
262
|
+
title: pageProperties.title ?? DEFAULT_PAGE_PROPERTIES.title
|
|
263
|
+
}, properties);
|
|
264
|
+
const { context: { screen: _, ...universalContext }, ...universalProperties } = this.buildUniversalEventProperties(universal);
|
|
265
|
+
const context = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.PageEventContext, universalContext);
|
|
266
|
+
return {
|
|
267
|
+
...universalProperties,
|
|
268
|
+
context,
|
|
269
|
+
type: 'page',
|
|
270
|
+
properties: merged
|
|
271
|
+
};
|
|
775
272
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
const
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
273
|
+
buildScreenView(args) {
|
|
274
|
+
const { name, properties, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(ScreenViewBuilderArgs, args);
|
|
275
|
+
const { context: { page: _, ...universalContext }, ...universalProperties } = this.buildUniversalEventProperties(universal);
|
|
276
|
+
const context = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ScreenEventContext, universalContext);
|
|
277
|
+
return {
|
|
278
|
+
...universalProperties,
|
|
279
|
+
context,
|
|
280
|
+
type: 'screen',
|
|
281
|
+
name,
|
|
282
|
+
properties
|
|
283
|
+
};
|
|
786
284
|
}
|
|
787
|
-
|
|
788
|
-
const
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
const intercepted = await this.interceptors.event.run(event);
|
|
796
|
-
const parsed = __rspack_external__contentful_optimization_api_client_cba5a7ee.ComponentViewEvent.parse(intercepted);
|
|
797
|
-
await this.sendBatchEvent(parsed, profile);
|
|
798
|
-
}
|
|
799
|
-
async trackFlagView(args) {
|
|
800
|
-
AnalyticsStateless_logger.debug('Processing "flag view" event');
|
|
801
|
-
const { profile, ...builderArgs } = args;
|
|
802
|
-
const event = this.builder.buildFlagView(builderArgs);
|
|
803
|
-
const intercepted = await this.interceptors.event.run(event);
|
|
804
|
-
const parsed = __rspack_external__contentful_optimization_api_client_cba5a7ee.ComponentViewEvent.parse(intercepted);
|
|
805
|
-
await this.sendBatchEvent(parsed, profile);
|
|
806
|
-
}
|
|
807
|
-
async sendBatchEvent(event, profile) {
|
|
808
|
-
const batchEvent = __rspack_external__contentful_optimization_api_client_cba5a7ee.BatchInsightsEventArray.parse([
|
|
809
|
-
{
|
|
810
|
-
profile,
|
|
811
|
-
events: [
|
|
812
|
-
event
|
|
813
|
-
]
|
|
814
|
-
}
|
|
815
|
-
]);
|
|
816
|
-
await this.api.insights.sendBatchEvents(batchEvent);
|
|
285
|
+
buildTrack(args) {
|
|
286
|
+
const { event, properties = {}, ...universal } = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(TrackBuilderArgs, args);
|
|
287
|
+
return {
|
|
288
|
+
...this.buildUniversalEventProperties(universal),
|
|
289
|
+
type: 'track',
|
|
290
|
+
event,
|
|
291
|
+
properties
|
|
292
|
+
};
|
|
817
293
|
}
|
|
818
294
|
}
|
|
819
|
-
const
|
|
820
|
-
const OPTIMIZATION_CORE_SDK_VERSION = "0.1.0-alpha";
|
|
821
|
-
const ANONYMOUS_ID_COOKIE = 'ctfl-opt-aid';
|
|
295
|
+
const events_EventBuilder = EventBuilder;
|
|
822
296
|
class InterceptorManager {
|
|
823
297
|
interceptors = new Map();
|
|
824
298
|
nextId = 0;
|
|
@@ -840,696 +314,1075 @@ class InterceptorManager {
|
|
|
840
314
|
async run(input) {
|
|
841
315
|
const fns = Array.from(this.interceptors.values());
|
|
842
316
|
let acc = input;
|
|
843
|
-
for (const fn of fns)acc = await fn(acc);
|
|
317
|
+
for (const fn of fns)acc = await fn(cloneDeep(acc));
|
|
844
318
|
return acc;
|
|
845
319
|
}
|
|
846
320
|
}
|
|
321
|
+
const FlagsResolver = {
|
|
322
|
+
resolve (changes) {
|
|
323
|
+
if (!changes) return {};
|
|
324
|
+
return changes.reduce((acc, { key, value })=>{
|
|
325
|
+
const actualValue = 'object' == typeof value && null !== value && 'value' in value && 'object' == typeof value.value ? value.value : value;
|
|
326
|
+
acc[key] = actualValue;
|
|
327
|
+
return acc;
|
|
328
|
+
}, {});
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
const resolvers_FlagsResolver = FlagsResolver;
|
|
332
|
+
const logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Optimization');
|
|
333
|
+
const RESOLUTION_WARNING_BASE = 'Could not resolve Merge Tag value:';
|
|
334
|
+
const getAtPath = (value, path)=>{
|
|
335
|
+
if (!value || 'object' != typeof value) return;
|
|
336
|
+
if (!path) return value;
|
|
337
|
+
let current = value;
|
|
338
|
+
const segments = path.split('.').filter(Boolean);
|
|
339
|
+
for (const segment of segments){
|
|
340
|
+
if (!current || 'object' != typeof current && 'function' != typeof current) return;
|
|
341
|
+
current = Reflect.get(current, segment);
|
|
342
|
+
}
|
|
343
|
+
return current;
|
|
344
|
+
};
|
|
345
|
+
const MergeTagValueResolver = {
|
|
346
|
+
normalizeSelectors (id) {
|
|
347
|
+
return id.split('_').map((_path, index, paths)=>{
|
|
348
|
+
const dotPath = paths.slice(0, index).join('.');
|
|
349
|
+
const underScorePath = paths.slice(index).join('_');
|
|
350
|
+
return [
|
|
351
|
+
dotPath,
|
|
352
|
+
underScorePath
|
|
353
|
+
].filter((path)=>'' !== path).join('.');
|
|
354
|
+
});
|
|
355
|
+
},
|
|
356
|
+
getValueFromProfile (id, profile) {
|
|
357
|
+
const selectors = MergeTagValueResolver.normalizeSelectors(id);
|
|
358
|
+
const matchingSelector = selectors.find((selector)=>getAtPath(profile, selector));
|
|
359
|
+
if (!matchingSelector) return;
|
|
360
|
+
const value = getAtPath(profile, matchingSelector);
|
|
361
|
+
if (!value || 'string' != typeof value && 'number' != typeof value && 'boolean' != typeof value) return;
|
|
362
|
+
return `${value}`;
|
|
363
|
+
},
|
|
364
|
+
resolve (mergeTagEntry, profile) {
|
|
365
|
+
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`);
|
|
366
|
+
const { fields: { nt_fallback: fallback } } = mergeTagEntry;
|
|
367
|
+
if (!__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.Profile.safeParse(profile).success) {
|
|
368
|
+
logger.warn(`${RESOLUTION_WARNING_BASE} no valid profile`);
|
|
369
|
+
return fallback;
|
|
370
|
+
}
|
|
371
|
+
return MergeTagValueResolver.getValueFromProfile(mergeTagEntry.fields.nt_mergetag_id, profile) ?? fallback;
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
const resolvers_MergeTagValueResolver = MergeTagValueResolver;
|
|
375
|
+
const OptimizedEntryResolver_logger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('Optimization');
|
|
376
|
+
const OptimizedEntryResolver_RESOLUTION_WARNING_BASE = 'Could not resolve optimized entry variant:';
|
|
377
|
+
function resolve(entry, selectedOptimizations) {
|
|
378
|
+
OptimizedEntryResolver_logger.debug(`Resolving optimized entry for baseline entry ${entry.sys.id}`);
|
|
379
|
+
if (!selectedOptimizations?.length) {
|
|
380
|
+
OptimizedEntryResolver_logger.warn(`${OptimizedEntryResolver_RESOLUTION_WARNING_BASE} no selectedOptimizations exist for the current profile`);
|
|
381
|
+
return {
|
|
382
|
+
entry
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
if (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizedEntry)(entry)) {
|
|
386
|
+
OptimizedEntryResolver_logger.warn(`${OptimizedEntryResolver_RESOLUTION_WARNING_BASE} entry ${entry.sys.id} is not optimized`);
|
|
387
|
+
return {
|
|
388
|
+
entry
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const optimizationEntry = OptimizedEntryResolver.getOptimizationEntry({
|
|
392
|
+
optimizedEntry: entry,
|
|
393
|
+
selectedOptimizations
|
|
394
|
+
}, true);
|
|
395
|
+
if (!optimizationEntry) {
|
|
396
|
+
OptimizedEntryResolver_logger.warn(`${OptimizedEntryResolver_RESOLUTION_WARNING_BASE} could not find an optimization entry for ${entry.sys.id}`);
|
|
397
|
+
return {
|
|
398
|
+
entry
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
const selectedOptimization = OptimizedEntryResolver.getSelectedOptimization({
|
|
402
|
+
optimizationEntry,
|
|
403
|
+
selectedOptimizations
|
|
404
|
+
}, true);
|
|
405
|
+
const selectedVariantIndex = selectedOptimization?.variantIndex ?? 0;
|
|
406
|
+
if (0 === selectedVariantIndex) {
|
|
407
|
+
OptimizedEntryResolver_logger.debug(`Resolved optimization entry for entry ${entry.sys.id} is baseline`);
|
|
408
|
+
return {
|
|
409
|
+
entry
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
const selectedVariant = OptimizedEntryResolver.getSelectedVariant({
|
|
413
|
+
optimizedEntry: entry,
|
|
414
|
+
optimizationEntry,
|
|
415
|
+
selectedVariantIndex
|
|
416
|
+
}, true);
|
|
417
|
+
if (!selectedVariant) {
|
|
418
|
+
OptimizedEntryResolver_logger.warn(`${OptimizedEntryResolver_RESOLUTION_WARNING_BASE} could not find a valid replacement variant entry for ${entry.sys.id}`);
|
|
419
|
+
return {
|
|
420
|
+
entry
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
const selectedVariantEntry = OptimizedEntryResolver.getSelectedVariantEntry({
|
|
424
|
+
optimizationEntry,
|
|
425
|
+
selectedVariant
|
|
426
|
+
}, true);
|
|
427
|
+
if (selectedVariantEntry) OptimizedEntryResolver_logger.debug(`Entry ${entry.sys.id} has been resolved to variant entry ${selectedVariantEntry.sys.id}`);
|
|
428
|
+
else {
|
|
429
|
+
OptimizedEntryResolver_logger.warn(`${OptimizedEntryResolver_RESOLUTION_WARNING_BASE} could not find a valid replacement variant entry for ${entry.sys.id}`);
|
|
430
|
+
return {
|
|
431
|
+
entry
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
entry: selectedVariantEntry,
|
|
436
|
+
selectedOptimization
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
const OptimizedEntryResolver = {
|
|
440
|
+
getOptimizationEntry ({ optimizedEntry, selectedOptimizations }, skipValidation = false) {
|
|
441
|
+
if (!skipValidation && (!selectedOptimizations.length || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizedEntry)(optimizedEntry))) return;
|
|
442
|
+
const optimizationEntry = optimizedEntry.fields.nt_experiences.filter((maybeOptimization)=>(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizationEntry)(maybeOptimization)).find((optimizationEntry)=>selectedOptimizations.some(({ experienceId })=>experienceId === optimizationEntry.fields.nt_experience_id));
|
|
443
|
+
return optimizationEntry;
|
|
444
|
+
},
|
|
445
|
+
getSelectedOptimization ({ optimizationEntry, selectedOptimizations }, skipValidation = false) {
|
|
446
|
+
if (!skipValidation && (!selectedOptimizations.length || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizationEntry)(optimizationEntry))) return;
|
|
447
|
+
const selectedOptimization = selectedOptimizations.find(({ experienceId })=>experienceId === optimizationEntry.fields.nt_experience_id);
|
|
448
|
+
return selectedOptimization;
|
|
449
|
+
},
|
|
450
|
+
getSelectedVariant ({ optimizedEntry, optimizationEntry, selectedVariantIndex }, skipValidation = false) {
|
|
451
|
+
if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizedEntry)(optimizedEntry) || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizationEntry)(optimizationEntry))) return;
|
|
452
|
+
const relevantVariants = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.normalizeOptimizationConfig)(optimizationEntry.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 === optimizedEntry.sys.id)?.variants;
|
|
453
|
+
if (!relevantVariants?.length) return;
|
|
454
|
+
return relevantVariants.at(selectedVariantIndex - 1);
|
|
455
|
+
},
|
|
456
|
+
getSelectedVariantEntry ({ optimizationEntry, selectedVariant }, skipValidation = false) {
|
|
457
|
+
if (!skipValidation && (!(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isOptimizationEntry)(optimizationEntry) || !(0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isEntryReplacementVariant)(selectedVariant))) return;
|
|
458
|
+
const selectedVariantEntry = optimizationEntry.fields.nt_variants?.find((variant)=>variant.sys.id === selectedVariant.id);
|
|
459
|
+
return (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.isEntry)(selectedVariantEntry) ? selectedVariantEntry : void 0;
|
|
460
|
+
},
|
|
461
|
+
resolve: resolve
|
|
462
|
+
};
|
|
463
|
+
const resolvers_OptimizedEntryResolver = OptimizedEntryResolver;
|
|
847
464
|
class CoreBase {
|
|
848
465
|
api;
|
|
849
466
|
eventBuilder;
|
|
850
467
|
config;
|
|
468
|
+
flagsResolver = resolvers_FlagsResolver;
|
|
469
|
+
mergeTagValueResolver = resolvers_MergeTagValueResolver;
|
|
470
|
+
optimizedEntryResolver = resolvers_OptimizedEntryResolver;
|
|
851
471
|
interceptors = {
|
|
852
472
|
event: new InterceptorManager(),
|
|
853
473
|
state: new InterceptorManager()
|
|
854
474
|
};
|
|
855
|
-
constructor(config){
|
|
475
|
+
constructor(config, api = {}){
|
|
856
476
|
this.config = config;
|
|
857
|
-
const {
|
|
858
|
-
logger.addSink(new ConsoleLogSink(logLevel));
|
|
477
|
+
const { eventBuilder, logLevel, environment, clientId, fetchOptions } = config;
|
|
478
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.addSink(new __rspack_external__contentful_optimization_api_client_logger_f0d05f82.ConsoleLogSink(logLevel));
|
|
859
479
|
const apiConfig = {
|
|
860
|
-
...analytics,
|
|
861
|
-
...personalization,
|
|
862
480
|
clientId,
|
|
863
|
-
environment
|
|
481
|
+
environment,
|
|
482
|
+
fetchOptions,
|
|
483
|
+
experience: api.experience,
|
|
484
|
+
insights: api.insights
|
|
864
485
|
};
|
|
865
486
|
this.api = new __rspack_external__contentful_optimization_api_client_cba5a7ee.ApiClient(apiConfig);
|
|
866
|
-
this.eventBuilder = new
|
|
487
|
+
this.eventBuilder = new events_EventBuilder(eventBuilder ?? {
|
|
867
488
|
channel: 'server',
|
|
868
489
|
library: {
|
|
869
|
-
name:
|
|
490
|
+
name: OPTIMIZATION_CORE_SDK_NAME,
|
|
870
491
|
version: OPTIMIZATION_CORE_SDK_VERSION
|
|
871
492
|
}
|
|
872
493
|
});
|
|
873
494
|
}
|
|
874
|
-
|
|
875
|
-
return this.
|
|
495
|
+
getFlag(name, changes) {
|
|
496
|
+
return this.flagsResolver.resolve(changes)[name];
|
|
876
497
|
}
|
|
877
|
-
|
|
878
|
-
return this.
|
|
498
|
+
resolveOptimizedEntry(entry, selectedOptimizations) {
|
|
499
|
+
return this.optimizedEntryResolver.resolve(entry, selectedOptimizations);
|
|
879
500
|
}
|
|
880
501
|
getMergeTagValue(embeddedEntryNodeTarget, profile) {
|
|
881
|
-
return this.
|
|
502
|
+
return this.mergeTagValueResolver.resolve(embeddedEntryNodeTarget, profile);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
const src_CoreBase = CoreBase;
|
|
506
|
+
const coreLogger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('CoreStateful');
|
|
507
|
+
const CONSENT_EVENT_TYPE_MAP = {
|
|
508
|
+
trackView: 'component',
|
|
509
|
+
trackFlagView: 'component',
|
|
510
|
+
trackClick: 'component_click',
|
|
511
|
+
trackHover: 'component_hover'
|
|
512
|
+
};
|
|
513
|
+
class CoreStatefulEventEmitter extends src_CoreBase {
|
|
514
|
+
flagObservables = new Map();
|
|
515
|
+
getFlag(name, changes = signals_changes.value) {
|
|
516
|
+
const value = super.getFlag(name, changes);
|
|
517
|
+
const payload = this.buildFlagViewBuilderArgs(name, changes);
|
|
518
|
+
this.trackFlagView(payload).catch((error)=>{
|
|
519
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.warn(`Failed to emit "flag view" event for "${name}"`, String(error));
|
|
520
|
+
});
|
|
521
|
+
return value;
|
|
522
|
+
}
|
|
523
|
+
resolveOptimizedEntry(entry, selectedOptimizations = signals_selectedOptimizations.value) {
|
|
524
|
+
return super.resolveOptimizedEntry(entry, selectedOptimizations);
|
|
525
|
+
}
|
|
526
|
+
getMergeTagValue(embeddedEntryNodeTarget, profile = signals_profile.value) {
|
|
527
|
+
return super.getMergeTagValue(embeddedEntryNodeTarget, profile);
|
|
882
528
|
}
|
|
883
529
|
async identify(payload) {
|
|
884
|
-
|
|
530
|
+
const { profile, ...builderArgs } = payload;
|
|
531
|
+
return await this.sendExperienceEvent('identify', [
|
|
532
|
+
payload
|
|
533
|
+
], this.eventBuilder.buildIdentify(builderArgs), profile);
|
|
534
|
+
}
|
|
535
|
+
async page(payload = {}) {
|
|
536
|
+
const { profile, ...builderArgs } = payload;
|
|
537
|
+
return await this.sendExperienceEvent('page', [
|
|
538
|
+
payload
|
|
539
|
+
], this.eventBuilder.buildPageView(builderArgs), profile);
|
|
540
|
+
}
|
|
541
|
+
async screen(payload) {
|
|
542
|
+
const { profile, ...builderArgs } = payload;
|
|
543
|
+
return await this.sendExperienceEvent('screen', [
|
|
544
|
+
payload
|
|
545
|
+
], this.eventBuilder.buildScreenView(builderArgs), profile);
|
|
546
|
+
}
|
|
547
|
+
async track(payload) {
|
|
548
|
+
const { profile, ...builderArgs } = payload;
|
|
549
|
+
return await this.sendExperienceEvent('track', [
|
|
550
|
+
payload
|
|
551
|
+
], this.eventBuilder.buildTrack(builderArgs), profile);
|
|
552
|
+
}
|
|
553
|
+
async trackView(payload) {
|
|
554
|
+
const { profile, ...builderArgs } = payload;
|
|
555
|
+
let result;
|
|
556
|
+
if (payload.sticky) result = await this.sendExperienceEvent('trackView', [
|
|
557
|
+
payload
|
|
558
|
+
], this.eventBuilder.buildView(builderArgs), profile);
|
|
559
|
+
await this.sendInsightsEvent('trackView', [
|
|
560
|
+
payload
|
|
561
|
+
], this.eventBuilder.buildView(builderArgs), profile);
|
|
562
|
+
return result;
|
|
563
|
+
}
|
|
564
|
+
async trackClick(payload) {
|
|
565
|
+
await this.sendInsightsEvent('trackClick', [
|
|
566
|
+
payload
|
|
567
|
+
], this.eventBuilder.buildClick(payload));
|
|
568
|
+
}
|
|
569
|
+
async trackHover(payload) {
|
|
570
|
+
await this.sendInsightsEvent('trackHover', [
|
|
571
|
+
payload
|
|
572
|
+
], this.eventBuilder.buildHover(payload));
|
|
573
|
+
}
|
|
574
|
+
async trackFlagView(payload) {
|
|
575
|
+
await this.sendInsightsEvent('trackFlagView', [
|
|
576
|
+
payload
|
|
577
|
+
], this.eventBuilder.buildFlagView(payload));
|
|
578
|
+
}
|
|
579
|
+
hasConsent(name) {
|
|
580
|
+
const { [name]: mappedEventType } = CONSENT_EVENT_TYPE_MAP;
|
|
581
|
+
const isAllowed = void 0 !== mappedEventType ? this.allowedEventTypes.includes(mappedEventType) : this.allowedEventTypes.some((eventType)=>eventType === name);
|
|
582
|
+
return !!consent.value || isAllowed;
|
|
583
|
+
}
|
|
584
|
+
onBlockedByConsent(name, args) {
|
|
585
|
+
coreLogger.warn(`Event "${name}" was blocked due to lack of consent; payload: ${JSON.stringify(args)}`);
|
|
586
|
+
this.reportBlockedEvent('consent', name, args);
|
|
587
|
+
}
|
|
588
|
+
async sendExperienceEvent(method, args, event, _profile) {
|
|
589
|
+
if (!this.hasConsent(method)) return void this.onBlockedByConsent(method, args);
|
|
590
|
+
return await this.experienceQueue.send(event);
|
|
591
|
+
}
|
|
592
|
+
async sendInsightsEvent(method, args, event, _profile) {
|
|
593
|
+
if (!this.hasConsent(method)) return void this.onBlockedByConsent(method, args);
|
|
594
|
+
await this.insightsQueue.send(event);
|
|
595
|
+
}
|
|
596
|
+
buildFlagViewBuilderArgs(name, changes = signals_changes.value) {
|
|
597
|
+
const change = changes?.find((candidate)=>candidate.key === name);
|
|
598
|
+
return {
|
|
599
|
+
componentId: name,
|
|
600
|
+
experienceId: change?.meta.experienceId,
|
|
601
|
+
variantIndex: change?.meta.variantIndex
|
|
602
|
+
};
|
|
885
603
|
}
|
|
886
|
-
|
|
887
|
-
|
|
604
|
+
getFlagObservable(name) {
|
|
605
|
+
const existingObservable = this.flagObservables.get(name);
|
|
606
|
+
if (existingObservable) return existingObservable;
|
|
607
|
+
const trackFlagView = this.trackFlagView.bind(this);
|
|
608
|
+
const buildFlagViewBuilderArgs = this.buildFlagViewBuilderArgs.bind(this);
|
|
609
|
+
const valueSignal = signalFns.computed(()=>super.getFlag(name, signals_changes.value));
|
|
610
|
+
const distinctObservable = toDistinctObservable(valueSignal, predicate_isEqual);
|
|
611
|
+
const trackedObservable = {
|
|
612
|
+
get current () {
|
|
613
|
+
const { current: value } = distinctObservable;
|
|
614
|
+
const payload = buildFlagViewBuilderArgs(name, signals_changes.value);
|
|
615
|
+
trackFlagView(payload).catch((error)=>{
|
|
616
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.warn(`Failed to emit "flag view" event for "${name}"`, String(error));
|
|
617
|
+
});
|
|
618
|
+
return value;
|
|
619
|
+
},
|
|
620
|
+
subscribe: (next)=>distinctObservable.subscribe((value)=>{
|
|
621
|
+
const payload = buildFlagViewBuilderArgs(name, signals_changes.value);
|
|
622
|
+
trackFlagView(payload).catch((error)=>{
|
|
623
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.warn(`Failed to emit "flag view" event for "${name}"`, String(error));
|
|
624
|
+
});
|
|
625
|
+
next(value);
|
|
626
|
+
}),
|
|
627
|
+
subscribeOnce: (next)=>distinctObservable.subscribeOnce((value)=>{
|
|
628
|
+
const payload = buildFlagViewBuilderArgs(name, signals_changes.value);
|
|
629
|
+
trackFlagView(payload).catch((error)=>{
|
|
630
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.warn(`Failed to emit "flag view" event for "${name}"`, String(error));
|
|
631
|
+
});
|
|
632
|
+
next(value);
|
|
633
|
+
})
|
|
634
|
+
};
|
|
635
|
+
this.flagObservables.set(name, trackedObservable);
|
|
636
|
+
return trackedObservable;
|
|
637
|
+
}
|
|
638
|
+
reportBlockedEvent(reason, method, args) {
|
|
639
|
+
const event = {
|
|
640
|
+
reason,
|
|
641
|
+
method,
|
|
642
|
+
args
|
|
643
|
+
};
|
|
644
|
+
try {
|
|
645
|
+
this.onEventBlocked?.(event);
|
|
646
|
+
} catch (error) {
|
|
647
|
+
coreLogger.warn(`onEventBlocked callback failed for method "${method}"`, error);
|
|
648
|
+
}
|
|
649
|
+
blockedEvent.value = event;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
const src_CoreStatefulEventEmitter = CoreStatefulEventEmitter;
|
|
653
|
+
const toPositiveInt = (value, fallback)=>{
|
|
654
|
+
if (!Number.isFinite(value) || void 0 === value || value < 1) return fallback;
|
|
655
|
+
return Math.floor(value);
|
|
656
|
+
};
|
|
657
|
+
const toRatio = (value, fallback)=>{
|
|
658
|
+
if (!Number.isFinite(value) || void 0 === value) return fallback;
|
|
659
|
+
return Math.min(1, Math.max(0, value));
|
|
660
|
+
};
|
|
661
|
+
const DEFAULT_QUEUE_FLUSH_POLICY = {
|
|
662
|
+
flushIntervalMs: 30000,
|
|
663
|
+
baseBackoffMs: 500,
|
|
664
|
+
maxBackoffMs: 30000,
|
|
665
|
+
jitterRatio: 0.2,
|
|
666
|
+
maxConsecutiveFailures: 8,
|
|
667
|
+
circuitOpenMs: 120000
|
|
668
|
+
};
|
|
669
|
+
const resolveQueueFlushPolicy = (policy, defaults = DEFAULT_QUEUE_FLUSH_POLICY)=>{
|
|
670
|
+
const configuredPolicy = policy ?? {};
|
|
671
|
+
const baseBackoffMs = toPositiveInt(configuredPolicy.baseBackoffMs, defaults.baseBackoffMs);
|
|
672
|
+
const maxBackoffMs = Math.max(baseBackoffMs, toPositiveInt(configuredPolicy.maxBackoffMs, defaults.maxBackoffMs));
|
|
673
|
+
return {
|
|
674
|
+
flushIntervalMs: toPositiveInt(configuredPolicy.flushIntervalMs, defaults.flushIntervalMs),
|
|
675
|
+
baseBackoffMs,
|
|
676
|
+
maxBackoffMs,
|
|
677
|
+
jitterRatio: toRatio(configuredPolicy.jitterRatio, defaults.jitterRatio),
|
|
678
|
+
maxConsecutiveFailures: toPositiveInt(configuredPolicy.maxConsecutiveFailures, defaults.maxConsecutiveFailures),
|
|
679
|
+
circuitOpenMs: toPositiveInt(configuredPolicy.circuitOpenMs, defaults.circuitOpenMs),
|
|
680
|
+
onCircuitOpen: configuredPolicy.onCircuitOpen,
|
|
681
|
+
onFlushFailure: configuredPolicy.onFlushFailure,
|
|
682
|
+
onFlushRecovered: configuredPolicy.onFlushRecovered
|
|
683
|
+
};
|
|
684
|
+
};
|
|
685
|
+
const computeQueueFlushRetryDelayMs = (options)=>{
|
|
686
|
+
const { consecutiveFailures, policy: { baseBackoffMs, jitterRatio, maxBackoffMs } } = options;
|
|
687
|
+
const exponential = baseBackoffMs * 2 ** Math.max(0, consecutiveFailures - 1);
|
|
688
|
+
const capped = Math.min(maxBackoffMs, exponential);
|
|
689
|
+
const jitter = capped * jitterRatio * Math.random();
|
|
690
|
+
return Math.round(capped + jitter);
|
|
691
|
+
};
|
|
692
|
+
const createQueueFlushFailureWindow = (options)=>{
|
|
693
|
+
const { consecutiveFailures, failureTimestamp, retryDelayMs, policy: { maxConsecutiveFailures, circuitOpenMs } } = options;
|
|
694
|
+
if (consecutiveFailures < maxConsecutiveFailures) return {
|
|
695
|
+
openedCircuit: false,
|
|
696
|
+
retryDelayMs,
|
|
697
|
+
nextFlushAllowedAt: failureTimestamp + retryDelayMs,
|
|
698
|
+
circuitOpenUntil: 0
|
|
699
|
+
};
|
|
700
|
+
const circuitOpenUntil = failureTimestamp + circuitOpenMs;
|
|
701
|
+
return {
|
|
702
|
+
openedCircuit: true,
|
|
703
|
+
retryDelayMs: circuitOpenMs,
|
|
704
|
+
nextFlushAllowedAt: circuitOpenUntil,
|
|
705
|
+
circuitOpenUntil
|
|
706
|
+
};
|
|
707
|
+
};
|
|
708
|
+
const STATEFUL_RUNTIME_LOCK_KEY = '__ctfl_optimization_stateful_runtime_lock__';
|
|
709
|
+
const getStatefulRuntimeLock = ()=>{
|
|
710
|
+
const singletonGlobal = globalThis;
|
|
711
|
+
singletonGlobal[STATEFUL_RUNTIME_LOCK_KEY] ??= {
|
|
712
|
+
owner: void 0
|
|
713
|
+
};
|
|
714
|
+
return singletonGlobal[STATEFUL_RUNTIME_LOCK_KEY];
|
|
715
|
+
};
|
|
716
|
+
const acquireStatefulRuntimeSingleton = (owner)=>{
|
|
717
|
+
const lock = getStatefulRuntimeLock();
|
|
718
|
+
if (lock.owner) throw new Error(`Stateful Optimization SDK already initialized (${lock.owner}). Only one stateful instance is supported per runtime.`);
|
|
719
|
+
lock.owner = owner;
|
|
720
|
+
};
|
|
721
|
+
const releaseStatefulRuntimeSingleton = (owner)=>{
|
|
722
|
+
const lock = getStatefulRuntimeLock();
|
|
723
|
+
if (lock.owner === owner) lock.owner = void 0;
|
|
724
|
+
};
|
|
725
|
+
class QueueFlushRuntime {
|
|
726
|
+
circuitOpenUntil = 0;
|
|
727
|
+
flushFailureCount = 0;
|
|
728
|
+
flushInFlight = false;
|
|
729
|
+
nextFlushAllowedAt = 0;
|
|
730
|
+
onCallbackError;
|
|
731
|
+
onRetry;
|
|
732
|
+
policy;
|
|
733
|
+
retryTimer;
|
|
734
|
+
constructor(options){
|
|
735
|
+
const { onCallbackError, onRetry, policy } = options;
|
|
736
|
+
this.policy = policy;
|
|
737
|
+
this.onRetry = onRetry;
|
|
738
|
+
this.onCallbackError = onCallbackError;
|
|
888
739
|
}
|
|
889
|
-
|
|
890
|
-
|
|
740
|
+
reset() {
|
|
741
|
+
this.clearScheduledRetry();
|
|
742
|
+
this.circuitOpenUntil = 0;
|
|
743
|
+
this.flushFailureCount = 0;
|
|
744
|
+
this.flushInFlight = false;
|
|
745
|
+
this.nextFlushAllowedAt = 0;
|
|
746
|
+
}
|
|
747
|
+
clearScheduledRetry() {
|
|
748
|
+
if (void 0 === this.retryTimer) return;
|
|
749
|
+
clearTimeout(this.retryTimer);
|
|
750
|
+
this.retryTimer = void 0;
|
|
751
|
+
}
|
|
752
|
+
shouldSkip(options) {
|
|
753
|
+
const { force, isOnline } = options;
|
|
754
|
+
if (this.flushInFlight) return true;
|
|
755
|
+
if (force) return false;
|
|
756
|
+
if (!isOnline) return true;
|
|
757
|
+
const now = Date.now();
|
|
758
|
+
if (this.nextFlushAllowedAt > now) return true;
|
|
759
|
+
if (this.circuitOpenUntil > now) return true;
|
|
760
|
+
return false;
|
|
761
|
+
}
|
|
762
|
+
markFlushStarted() {
|
|
763
|
+
this.flushInFlight = true;
|
|
764
|
+
}
|
|
765
|
+
markFlushFinished() {
|
|
766
|
+
this.flushInFlight = false;
|
|
767
|
+
}
|
|
768
|
+
handleFlushSuccess() {
|
|
769
|
+
const { flushFailureCount: previousConsecutiveFailures } = this;
|
|
770
|
+
this.clearScheduledRetry();
|
|
771
|
+
this.circuitOpenUntil = 0;
|
|
772
|
+
this.flushFailureCount = 0;
|
|
773
|
+
this.nextFlushAllowedAt = 0;
|
|
774
|
+
if (previousConsecutiveFailures <= 0) return;
|
|
775
|
+
this.safeInvoke('onFlushRecovered', {
|
|
776
|
+
consecutiveFailures: previousConsecutiveFailures
|
|
777
|
+
});
|
|
891
778
|
}
|
|
892
|
-
|
|
893
|
-
|
|
779
|
+
handleFlushFailure(options) {
|
|
780
|
+
const { queuedBatches, queuedEvents } = options;
|
|
781
|
+
this.flushFailureCount += 1;
|
|
782
|
+
const retryDelayMs = computeQueueFlushRetryDelayMs({
|
|
783
|
+
consecutiveFailures: this.flushFailureCount,
|
|
784
|
+
policy: this.policy
|
|
785
|
+
});
|
|
786
|
+
const failureTimestamp = Date.now();
|
|
787
|
+
const failureContext = {
|
|
788
|
+
consecutiveFailures: this.flushFailureCount,
|
|
789
|
+
queuedBatches,
|
|
790
|
+
queuedEvents,
|
|
791
|
+
retryDelayMs
|
|
792
|
+
};
|
|
793
|
+
this.safeInvoke('onFlushFailure', failureContext);
|
|
794
|
+
const failureWindow = createQueueFlushFailureWindow({
|
|
795
|
+
consecutiveFailures: this.flushFailureCount,
|
|
796
|
+
failureTimestamp,
|
|
797
|
+
retryDelayMs,
|
|
798
|
+
policy: this.policy
|
|
799
|
+
});
|
|
800
|
+
const { circuitOpenUntil, nextFlushAllowedAt, openedCircuit, retryDelayMs: scheduledRetryDelayMs } = failureWindow;
|
|
801
|
+
this.nextFlushAllowedAt = nextFlushAllowedAt;
|
|
802
|
+
if (openedCircuit) {
|
|
803
|
+
this.circuitOpenUntil = circuitOpenUntil;
|
|
804
|
+
this.safeInvoke('onCircuitOpen', {
|
|
805
|
+
...failureContext,
|
|
806
|
+
retryDelayMs: scheduledRetryDelayMs
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
this.scheduleRetry(scheduledRetryDelayMs);
|
|
894
810
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
811
|
+
scheduleRetry(delayMs) {
|
|
812
|
+
this.clearScheduledRetry();
|
|
813
|
+
this.retryTimer = setTimeout(()=>{
|
|
814
|
+
this.retryTimer = void 0;
|
|
815
|
+
this.onRetry();
|
|
816
|
+
}, delayMs);
|
|
898
817
|
}
|
|
899
|
-
|
|
900
|
-
|
|
818
|
+
safeInvoke(...args) {
|
|
819
|
+
const [callbackName, payload] = args;
|
|
820
|
+
try {
|
|
821
|
+
if ('onFlushRecovered' === callbackName) return void this.policy.onFlushRecovered?.(payload);
|
|
822
|
+
if ('onCircuitOpen' === callbackName) return void this.policy.onCircuitOpen?.(payload);
|
|
823
|
+
this.policy.onFlushFailure?.(payload);
|
|
824
|
+
} catch (error) {
|
|
825
|
+
this.onCallbackError?.(callbackName, error);
|
|
826
|
+
}
|
|
901
827
|
}
|
|
902
828
|
}
|
|
903
|
-
const
|
|
904
|
-
class
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
829
|
+
const ExperienceQueue_coreLogger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('CoreStateful');
|
|
830
|
+
class ExperienceQueue {
|
|
831
|
+
experienceApi;
|
|
832
|
+
eventInterceptors;
|
|
833
|
+
flushRuntime;
|
|
834
|
+
getAnonymousId;
|
|
835
|
+
offlineMaxEvents;
|
|
836
|
+
onOfflineDrop;
|
|
837
|
+
queuedExperienceEvents = new Set();
|
|
838
|
+
stateInterceptors;
|
|
839
|
+
constructor(options){
|
|
840
|
+
const { experienceApi, eventInterceptors, flushPolicy, getAnonymousId, offlineMaxEvents, onOfflineDrop, stateInterceptors } = options;
|
|
841
|
+
this.experienceApi = experienceApi;
|
|
842
|
+
this.eventInterceptors = eventInterceptors;
|
|
843
|
+
this.getAnonymousId = getAnonymousId;
|
|
844
|
+
this.offlineMaxEvents = offlineMaxEvents;
|
|
845
|
+
this.onOfflineDrop = onOfflineDrop;
|
|
846
|
+
this.stateInterceptors = stateInterceptors;
|
|
847
|
+
this.flushRuntime = new QueueFlushRuntime({
|
|
848
|
+
policy: flushPolicy,
|
|
849
|
+
onRetry: ()=>{
|
|
850
|
+
this.flush();
|
|
851
|
+
},
|
|
852
|
+
onCallbackError: (callbackName, error)=>{
|
|
853
|
+
ExperienceQueue_coreLogger.warn(`Experience flush policy callback "${callbackName}" failed`, error);
|
|
854
|
+
}
|
|
855
|
+
});
|
|
916
856
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
function PersonalizationStateful_applyDecs2203RFactory() {
|
|
920
|
-
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
921
|
-
return function(initializer) {
|
|
922
|
-
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
923
|
-
assertCallable(initializer, "An initializer");
|
|
924
|
-
initializers.push(initializer);
|
|
925
|
-
};
|
|
857
|
+
clearScheduledRetry() {
|
|
858
|
+
this.flushRuntime.clearScheduledRetry();
|
|
926
859
|
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
860
|
+
async send(event) {
|
|
861
|
+
const intercepted = await this.eventInterceptors.run(event);
|
|
862
|
+
const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ExperienceEvent, intercepted);
|
|
863
|
+
signals_event.value = validEvent;
|
|
864
|
+
if (online.value) return await this.upsertProfile([
|
|
865
|
+
validEvent
|
|
866
|
+
]);
|
|
867
|
+
ExperienceQueue_coreLogger.debug(`Queueing ${validEvent.type} event`, validEvent);
|
|
868
|
+
this.enqueueEvent(validEvent);
|
|
869
|
+
}
|
|
870
|
+
async flush(options = {}) {
|
|
871
|
+
const { force = false } = options;
|
|
872
|
+
if (this.flushRuntime.shouldSkip({
|
|
873
|
+
force,
|
|
874
|
+
isOnline: !!online.value
|
|
875
|
+
})) return;
|
|
876
|
+
if (0 === this.queuedExperienceEvents.size) return void this.flushRuntime.clearScheduledRetry();
|
|
877
|
+
ExperienceQueue_coreLogger.debug('Flushing offline Experience event queue');
|
|
878
|
+
const queuedEvents = Array.from(this.queuedExperienceEvents);
|
|
879
|
+
this.flushRuntime.markFlushStarted();
|
|
880
|
+
try {
|
|
881
|
+
const sendSuccess = await this.tryUpsertQueuedEvents(queuedEvents);
|
|
882
|
+
if (sendSuccess) {
|
|
883
|
+
queuedEvents.forEach((queuedEvent)=>{
|
|
884
|
+
this.queuedExperienceEvents.delete(queuedEvent);
|
|
885
|
+
});
|
|
886
|
+
this.flushRuntime.handleFlushSuccess();
|
|
887
|
+
} else this.flushRuntime.handleFlushFailure({
|
|
888
|
+
queuedBatches: this.queuedExperienceEvents.size > 0 ? 1 : 0,
|
|
889
|
+
queuedEvents: this.queuedExperienceEvents.size
|
|
890
|
+
});
|
|
891
|
+
} finally{
|
|
892
|
+
this.flushRuntime.markFlushFinished();
|
|
944
893
|
}
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
var decoratorFinishedRef = {
|
|
953
|
-
v: false
|
|
954
|
-
};
|
|
955
|
-
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
956
|
-
var get, set;
|
|
957
|
-
if (0 === kind) if (isPrivate) {
|
|
958
|
-
get = desc.get;
|
|
959
|
-
set = desc.set;
|
|
960
|
-
} else {
|
|
961
|
-
get = function() {
|
|
962
|
-
return this[name];
|
|
963
|
-
};
|
|
964
|
-
set = function(v) {
|
|
965
|
-
this[name] = v;
|
|
966
|
-
};
|
|
894
|
+
}
|
|
895
|
+
enqueueEvent(event) {
|
|
896
|
+
let droppedEvents = [];
|
|
897
|
+
if (this.queuedExperienceEvents.size >= this.offlineMaxEvents) {
|
|
898
|
+
const dropCount = this.queuedExperienceEvents.size - this.offlineMaxEvents + 1;
|
|
899
|
+
droppedEvents = this.dropOldestEvents(dropCount);
|
|
900
|
+
if (droppedEvents.length > 0) ExperienceQueue_coreLogger.warn(`Dropped ${droppedEvents.length} oldest offline event(s) due to queue limit (${this.offlineMaxEvents})`);
|
|
967
901
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
902
|
+
this.queuedExperienceEvents.add(event);
|
|
903
|
+
if (droppedEvents.length > 0) this.invokeOfflineDropCallback({
|
|
904
|
+
droppedCount: droppedEvents.length,
|
|
905
|
+
droppedEvents,
|
|
906
|
+
maxEvents: this.offlineMaxEvents,
|
|
907
|
+
queuedEvents: this.queuedExperienceEvents.size
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
dropOldestEvents(count) {
|
|
911
|
+
const droppedEvents = [];
|
|
912
|
+
for(let index = 0; index < count; index += 1){
|
|
913
|
+
const oldestEvent = this.queuedExperienceEvents.values().next();
|
|
914
|
+
if (oldestEvent.done) break;
|
|
915
|
+
this.queuedExperienceEvents.delete(oldestEvent.value);
|
|
916
|
+
droppedEvents.push(oldestEvent.value);
|
|
978
917
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
} : get ? {
|
|
983
|
-
get: get
|
|
984
|
-
} : {
|
|
985
|
-
set: set
|
|
986
|
-
};
|
|
918
|
+
return droppedEvents;
|
|
919
|
+
}
|
|
920
|
+
invokeOfflineDropCallback(context) {
|
|
987
921
|
try {
|
|
988
|
-
|
|
989
|
-
}
|
|
990
|
-
|
|
922
|
+
this.onOfflineDrop?.(context);
|
|
923
|
+
} catch (error) {
|
|
924
|
+
ExperienceQueue_coreLogger.warn('Offline queue drop callback failed', error);
|
|
991
925
|
}
|
|
992
926
|
}
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
var type = typeof value;
|
|
1001
|
-
if (1 === kind) {
|
|
1002
|
-
if ("object" !== type || null === value) throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
1003
|
-
if (void 0 !== value.get) assertCallable(value.get, "accessor.get");
|
|
1004
|
-
if (void 0 !== value.set) assertCallable(value.set, "accessor.set");
|
|
1005
|
-
if (void 0 !== value.init) assertCallable(value.init, "accessor.init");
|
|
1006
|
-
} else if ("function" !== type) {
|
|
1007
|
-
var hint;
|
|
1008
|
-
hint = 0 === kind ? "field" : 10 === kind ? "class" : "method";
|
|
1009
|
-
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
927
|
+
async tryUpsertQueuedEvents(events) {
|
|
928
|
+
try {
|
|
929
|
+
await this.upsertProfile(events);
|
|
930
|
+
return true;
|
|
931
|
+
} catch (error) {
|
|
932
|
+
ExperienceQueue_coreLogger.warn('Experience queue flush request threw an error', error);
|
|
933
|
+
return false;
|
|
1010
934
|
}
|
|
1011
935
|
}
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
};
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
};
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
var newInit;
|
|
1055
|
-
if (0 === kind) newInit = newValue;
|
|
1056
|
-
else if (1 === kind) {
|
|
1057
|
-
newInit = newValue.init;
|
|
1058
|
-
get = newValue.get || value.get;
|
|
1059
|
-
set = newValue.set || value.set;
|
|
1060
|
-
value = {
|
|
1061
|
-
get: get,
|
|
1062
|
-
set: set
|
|
1063
|
-
};
|
|
1064
|
-
} else value = newValue;
|
|
1065
|
-
if (void 0 !== newInit) if (void 0 === init) init = newInit;
|
|
1066
|
-
else if ("function" == typeof init) init = [
|
|
1067
|
-
init,
|
|
1068
|
-
newInit
|
|
1069
|
-
];
|
|
1070
|
-
else init.push(newInit);
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
if (0 === kind || 1 === kind) {
|
|
1074
|
-
if (void 0 === init) init = function(instance, init) {
|
|
1075
|
-
return init;
|
|
1076
|
-
};
|
|
1077
|
-
else if ("function" != typeof init) {
|
|
1078
|
-
var ownInitializers = init;
|
|
1079
|
-
init = function(instance, init) {
|
|
1080
|
-
var value = init;
|
|
1081
|
-
for(var i = 0; i < ownInitializers.length; i++)value = ownInitializers[i].call(instance, value);
|
|
1082
|
-
return value;
|
|
1083
|
-
};
|
|
1084
|
-
} else {
|
|
1085
|
-
var originalInitializer = init;
|
|
1086
|
-
init = function(instance, init) {
|
|
1087
|
-
return originalInitializer.call(instance, init);
|
|
1088
|
-
};
|
|
936
|
+
async upsertProfile(events) {
|
|
937
|
+
const anonymousId = this.getAnonymousId();
|
|
938
|
+
if (anonymousId) ExperienceQueue_coreLogger.debug(`Anonymous ID found: ${anonymousId}`);
|
|
939
|
+
const data = await this.experienceApi.upsertProfile({
|
|
940
|
+
profileId: anonymousId ?? signals_profile.value?.id,
|
|
941
|
+
events
|
|
942
|
+
});
|
|
943
|
+
await this.updateOutputSignals(data);
|
|
944
|
+
return data;
|
|
945
|
+
}
|
|
946
|
+
async updateOutputSignals(data) {
|
|
947
|
+
const intercepted = await this.stateInterceptors.run(data);
|
|
948
|
+
const { changes, profile, selectedOptimizations } = intercepted;
|
|
949
|
+
batch(()=>{
|
|
950
|
+
if (!predicate_isEqual(signals_changes.value, changes)) signals_changes.value = changes;
|
|
951
|
+
if (!predicate_isEqual(signals_profile.value, profile)) signals_profile.value = profile;
|
|
952
|
+
if (!predicate_isEqual(signals_selectedOptimizations.value, selectedOptimizations)) signals_selectedOptimizations.value = selectedOptimizations;
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
const InsightsQueue_coreLogger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('CoreStateful');
|
|
957
|
+
const MAX_QUEUED_INSIGHTS_EVENTS = 25;
|
|
958
|
+
class InsightsQueue {
|
|
959
|
+
eventInterceptors;
|
|
960
|
+
flushIntervalMs;
|
|
961
|
+
flushRuntime;
|
|
962
|
+
insightsApi;
|
|
963
|
+
queuedInsightsByProfile = new Map();
|
|
964
|
+
insightsPeriodicFlushTimer;
|
|
965
|
+
constructor(options){
|
|
966
|
+
const { eventInterceptors, flushPolicy, insightsApi } = options;
|
|
967
|
+
const { flushIntervalMs } = flushPolicy;
|
|
968
|
+
this.eventInterceptors = eventInterceptors;
|
|
969
|
+
this.flushIntervalMs = flushIntervalMs;
|
|
970
|
+
this.insightsApi = insightsApi;
|
|
971
|
+
this.flushRuntime = new QueueFlushRuntime({
|
|
972
|
+
policy: flushPolicy,
|
|
973
|
+
onRetry: ()=>{
|
|
974
|
+
this.flush();
|
|
975
|
+
},
|
|
976
|
+
onCallbackError: (callbackName, error)=>{
|
|
977
|
+
InsightsQueue_coreLogger.warn(`Insights flush policy callback "${callbackName}" failed`, error);
|
|
1089
978
|
}
|
|
1090
|
-
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
clearScheduledRetry() {
|
|
982
|
+
this.flushRuntime.clearScheduledRetry();
|
|
983
|
+
}
|
|
984
|
+
clearPeriodicFlushTimer() {
|
|
985
|
+
if (void 0 === this.insightsPeriodicFlushTimer) return;
|
|
986
|
+
clearInterval(this.insightsPeriodicFlushTimer);
|
|
987
|
+
this.insightsPeriodicFlushTimer = void 0;
|
|
988
|
+
}
|
|
989
|
+
async send(event) {
|
|
990
|
+
const { value: profile } = signals_profile;
|
|
991
|
+
if (!profile) return void InsightsQueue_coreLogger.warn('Attempting to emit an event without an Optimization profile');
|
|
992
|
+
const intercepted = await this.eventInterceptors.run(event);
|
|
993
|
+
const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.InsightsEvent, intercepted);
|
|
994
|
+
InsightsQueue_coreLogger.debug(`Queueing ${validEvent.type} event for profile ${profile.id}`, validEvent);
|
|
995
|
+
const queuedProfileEvents = this.queuedInsightsByProfile.get(profile.id);
|
|
996
|
+
signals_event.value = validEvent;
|
|
997
|
+
if (queuedProfileEvents) {
|
|
998
|
+
queuedProfileEvents.profile = profile;
|
|
999
|
+
queuedProfileEvents.events.push(validEvent);
|
|
1000
|
+
} else this.queuedInsightsByProfile.set(profile.id, {
|
|
1001
|
+
profile,
|
|
1002
|
+
events: [
|
|
1003
|
+
validEvent
|
|
1004
|
+
]
|
|
1005
|
+
});
|
|
1006
|
+
this.ensurePeriodicFlushTimer();
|
|
1007
|
+
if (this.getQueuedEventCount() >= MAX_QUEUED_INSIGHTS_EVENTS) await this.flush();
|
|
1008
|
+
this.reconcilePeriodicFlushTimer();
|
|
1009
|
+
}
|
|
1010
|
+
async flush(options = {}) {
|
|
1011
|
+
const { force = false } = options;
|
|
1012
|
+
if (this.flushRuntime.shouldSkip({
|
|
1013
|
+
force,
|
|
1014
|
+
isOnline: !!online.value
|
|
1015
|
+
})) return;
|
|
1016
|
+
InsightsQueue_coreLogger.debug('Flushing insights event queue');
|
|
1017
|
+
const batches = this.createBatches();
|
|
1018
|
+
if (!batches.length) {
|
|
1019
|
+
this.flushRuntime.clearScheduledRetry();
|
|
1020
|
+
this.reconcilePeriodicFlushTimer();
|
|
1021
|
+
return;
|
|
1091
1022
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
else
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
return value.get.call(instance, args);
|
|
1102
|
-
});
|
|
1103
|
-
ret.push(function(instance, args) {
|
|
1104
|
-
return value.set.call(instance, args);
|
|
1105
|
-
});
|
|
1106
|
-
} else if (2 === kind) ret.push(value);
|
|
1107
|
-
else ret.push(function(instance, args) {
|
|
1108
|
-
return value.call(instance, args);
|
|
1023
|
+
this.flushRuntime.markFlushStarted();
|
|
1024
|
+
try {
|
|
1025
|
+
const sendSuccess = await this.trySendBatches(batches);
|
|
1026
|
+
if (sendSuccess) {
|
|
1027
|
+
this.queuedInsightsByProfile.clear();
|
|
1028
|
+
this.flushRuntime.handleFlushSuccess();
|
|
1029
|
+
} else this.flushRuntime.handleFlushFailure({
|
|
1030
|
+
queuedBatches: batches.length,
|
|
1031
|
+
queuedEvents: this.getQueuedEventCount()
|
|
1109
1032
|
});
|
|
1110
|
-
|
|
1033
|
+
} finally{
|
|
1034
|
+
this.flushRuntime.markFlushFinished();
|
|
1035
|
+
this.reconcilePeriodicFlushTimer();
|
|
1111
1036
|
}
|
|
1112
1037
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
var decInfo = decInfos[i];
|
|
1121
|
-
if (Array.isArray(decInfo)) {
|
|
1122
|
-
var kind = decInfo[1];
|
|
1123
|
-
var name = decInfo[2];
|
|
1124
|
-
var isPrivate = decInfo.length > 3;
|
|
1125
|
-
var isStatic = kind >= 5;
|
|
1126
|
-
var base;
|
|
1127
|
-
var initializers;
|
|
1128
|
-
if (isStatic) {
|
|
1129
|
-
base = Class;
|
|
1130
|
-
kind -= 5;
|
|
1131
|
-
staticInitializers = staticInitializers || [];
|
|
1132
|
-
initializers = staticInitializers;
|
|
1133
|
-
} else {
|
|
1134
|
-
base = Class.prototype;
|
|
1135
|
-
protoInitializers = protoInitializers || [];
|
|
1136
|
-
initializers = protoInitializers;
|
|
1137
|
-
}
|
|
1138
|
-
if (0 !== kind && !isPrivate) {
|
|
1139
|
-
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
1140
|
-
var existingKind = existingNonFields.get(name) || 0;
|
|
1141
|
-
if (true === existingKind || 3 === existingKind && 4 !== kind || 4 === existingKind && 3 !== kind) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
1142
|
-
if (!existingKind && kind > 2) existingNonFields.set(name, kind);
|
|
1143
|
-
else existingNonFields.set(name, true);
|
|
1144
|
-
}
|
|
1145
|
-
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
pushInitializers(ret, protoInitializers);
|
|
1149
|
-
pushInitializers(ret, staticInitializers);
|
|
1150
|
-
return ret;
|
|
1151
|
-
}
|
|
1152
|
-
function pushInitializers(ret, initializers) {
|
|
1153
|
-
if (initializers) ret.push(function(instance) {
|
|
1154
|
-
for(var i = 0; i < initializers.length; i++)initializers[i].call(instance);
|
|
1155
|
-
return instance;
|
|
1038
|
+
createBatches() {
|
|
1039
|
+
const batches = [];
|
|
1040
|
+
this.queuedInsightsByProfile.forEach(({ profile, events })=>{
|
|
1041
|
+
batches.push({
|
|
1042
|
+
profile,
|
|
1043
|
+
events
|
|
1044
|
+
});
|
|
1156
1045
|
});
|
|
1046
|
+
return batches;
|
|
1157
1047
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
var decoratorFinishedRef = {
|
|
1165
|
-
v: false
|
|
1166
|
-
};
|
|
1167
|
-
try {
|
|
1168
|
-
var nextNewClass = classDecs[i](newClass, {
|
|
1169
|
-
kind: "class",
|
|
1170
|
-
name: name,
|
|
1171
|
-
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
1172
|
-
metadata
|
|
1173
|
-
});
|
|
1174
|
-
} finally{
|
|
1175
|
-
decoratorFinishedRef.v = true;
|
|
1176
|
-
}
|
|
1177
|
-
if (void 0 !== nextNewClass) {
|
|
1178
|
-
assertValidReturnValue(10, nextNewClass);
|
|
1179
|
-
newClass = nextNewClass;
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
return [
|
|
1183
|
-
defineMetadata(newClass, metadata),
|
|
1184
|
-
function() {
|
|
1185
|
-
for(var i = 0; i < initializers.length; i++)initializers[i].call(newClass);
|
|
1186
|
-
}
|
|
1187
|
-
];
|
|
1048
|
+
async trySendBatches(batches) {
|
|
1049
|
+
try {
|
|
1050
|
+
return await this.insightsApi.sendBatchEvents(batches);
|
|
1051
|
+
} catch (error) {
|
|
1052
|
+
InsightsQueue_coreLogger.warn('Insights queue flush request threw an error', error);
|
|
1053
|
+
return false;
|
|
1188
1054
|
}
|
|
1189
1055
|
}
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
value: metadata
|
|
1056
|
+
getQueuedEventCount() {
|
|
1057
|
+
let queuedCount = 0;
|
|
1058
|
+
this.queuedInsightsByProfile.forEach(({ events })=>{
|
|
1059
|
+
queuedCount += events.length;
|
|
1195
1060
|
});
|
|
1061
|
+
return queuedCount;
|
|
1196
1062
|
}
|
|
1197
|
-
|
|
1198
|
-
if (void 0 !==
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
e: e,
|
|
1204
|
-
get c () {
|
|
1205
|
-
return applyClassDecs(targetClass, classDecs, metadata);
|
|
1206
|
-
}
|
|
1207
|
-
};
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
function PersonalizationStateful_apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
1211
|
-
return (PersonalizationStateful_apply_decs_2203_r = PersonalizationStateful_applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
1212
|
-
}
|
|
1213
|
-
var PersonalizationStateful_dec, PersonalizationStateful_dec1, PersonalizationStateful_dec2, PersonalizationStateful_dec3, _dec4, _dec5, PersonalizationStateful_initProto;
|
|
1214
|
-
const PersonalizationStateful_logger = createScopedLogger('Personalization');
|
|
1215
|
-
PersonalizationStateful_dec = guardedBy('hasConsent', {
|
|
1216
|
-
onBlocked: 'onBlockedByConsent'
|
|
1217
|
-
}), PersonalizationStateful_dec1 = guardedBy('hasConsent', {
|
|
1218
|
-
onBlocked: 'onBlockedByConsent'
|
|
1219
|
-
}), PersonalizationStateful_dec2 = guardedBy('hasConsent', {
|
|
1220
|
-
onBlocked: 'onBlockedByConsent'
|
|
1221
|
-
}), PersonalizationStateful_dec3 = guardedBy('hasConsent', {
|
|
1222
|
-
onBlocked: 'onBlockedByConsent'
|
|
1223
|
-
}), _dec4 = guardedBy('isNotDuplicated', {
|
|
1224
|
-
onBlocked: 'onBlockedByDuplication'
|
|
1225
|
-
}), _dec5 = guardedBy('hasConsent', {
|
|
1226
|
-
onBlocked: 'onBlockedByConsent'
|
|
1227
|
-
});
|
|
1228
|
-
class PersonalizationStateful extends personalization_PersonalizationBase {
|
|
1229
|
-
static{
|
|
1230
|
-
({ e: [PersonalizationStateful_initProto] } = PersonalizationStateful_apply_decs_2203_r(this, [
|
|
1231
|
-
[
|
|
1232
|
-
PersonalizationStateful_dec,
|
|
1233
|
-
2,
|
|
1234
|
-
"identify"
|
|
1235
|
-
],
|
|
1236
|
-
[
|
|
1237
|
-
PersonalizationStateful_dec1,
|
|
1238
|
-
2,
|
|
1239
|
-
"page"
|
|
1240
|
-
],
|
|
1241
|
-
[
|
|
1242
|
-
PersonalizationStateful_dec2,
|
|
1243
|
-
2,
|
|
1244
|
-
"screen"
|
|
1245
|
-
],
|
|
1246
|
-
[
|
|
1247
|
-
PersonalizationStateful_dec3,
|
|
1248
|
-
2,
|
|
1249
|
-
"track"
|
|
1250
|
-
],
|
|
1251
|
-
[
|
|
1252
|
-
[
|
|
1253
|
-
_dec4,
|
|
1254
|
-
_dec5
|
|
1255
|
-
],
|
|
1256
|
-
2,
|
|
1257
|
-
"trackComponentView"
|
|
1258
|
-
]
|
|
1259
|
-
], []));
|
|
1063
|
+
ensurePeriodicFlushTimer() {
|
|
1064
|
+
if (void 0 !== this.insightsPeriodicFlushTimer) return;
|
|
1065
|
+
if (0 === this.getQueuedEventCount()) return;
|
|
1066
|
+
this.insightsPeriodicFlushTimer = setInterval(()=>{
|
|
1067
|
+
this.flush();
|
|
1068
|
+
}, this.flushIntervalMs);
|
|
1260
1069
|
}
|
|
1261
|
-
|
|
1070
|
+
reconcilePeriodicFlushTimer() {
|
|
1071
|
+
if (this.getQueuedEventCount() > 0) return void this.ensurePeriodicFlushTimer();
|
|
1072
|
+
this.clearPeriodicFlushTimer();
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
const CoreStateful_coreLogger = (0, __rspack_external__contentful_optimization_api_client_logger_f0d05f82.createScopedLogger)('CoreStateful');
|
|
1076
|
+
const DEFAULT_ALLOWED_EVENT_TYPES = [
|
|
1077
|
+
'identify',
|
|
1078
|
+
'page',
|
|
1079
|
+
'screen'
|
|
1080
|
+
];
|
|
1081
|
+
const OFFLINE_QUEUE_MAX_EVENTS = 100;
|
|
1082
|
+
const hasDefinedValues = (record)=>Object.values(record).some((value)=>void 0 !== value);
|
|
1083
|
+
const createStatefulExperienceApiConfig = (api)=>{
|
|
1084
|
+
if (void 0 === api) return;
|
|
1085
|
+
const experienceConfig = {
|
|
1086
|
+
baseUrl: api.experienceBaseUrl,
|
|
1087
|
+
enabledFeatures: api.enabledFeatures,
|
|
1088
|
+
ip: api.ip,
|
|
1089
|
+
locale: api.locale,
|
|
1090
|
+
plainText: api.plainText,
|
|
1091
|
+
preflight: api.preflight
|
|
1092
|
+
};
|
|
1093
|
+
return hasDefinedValues(experienceConfig) ? experienceConfig : void 0;
|
|
1094
|
+
};
|
|
1095
|
+
const createStatefulInsightsApiConfig = (api)=>{
|
|
1096
|
+
if (void 0 === api) return;
|
|
1097
|
+
const insightsConfig = {
|
|
1098
|
+
baseUrl: api.insightsBaseUrl,
|
|
1099
|
+
beaconHandler: api.beaconHandler
|
|
1100
|
+
};
|
|
1101
|
+
return hasDefinedValues(insightsConfig) ? insightsConfig : void 0;
|
|
1102
|
+
};
|
|
1103
|
+
const resolveQueuePolicy = (policy)=>({
|
|
1104
|
+
flush: resolveQueueFlushPolicy(policy?.flush),
|
|
1105
|
+
offlineMaxEvents: toPositiveInt(policy?.offlineMaxEvents, OFFLINE_QUEUE_MAX_EVENTS),
|
|
1106
|
+
onOfflineDrop: policy?.onOfflineDrop
|
|
1107
|
+
});
|
|
1108
|
+
let statefulInstanceCounter = 0;
|
|
1109
|
+
class CoreStateful extends src_CoreStatefulEventEmitter {
|
|
1110
|
+
singletonOwner;
|
|
1111
|
+
destroyed = false;
|
|
1112
|
+
allowedEventTypes;
|
|
1113
|
+
experienceQueue;
|
|
1114
|
+
insightsQueue;
|
|
1115
|
+
onEventBlocked;
|
|
1262
1116
|
states = {
|
|
1117
|
+
blockedEventStream: toObservable(blockedEvent),
|
|
1118
|
+
flag: (name)=>this.getFlagObservable(name),
|
|
1119
|
+
consent: toObservable(consent),
|
|
1263
1120
|
eventStream: toObservable(signals_event),
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1121
|
+
canOptimize: toObservable(canOptimize),
|
|
1122
|
+
selectedOptimizations: toObservable(signals_selectedOptimizations),
|
|
1123
|
+
previewPanelAttached: toObservable(previewPanelAttached),
|
|
1124
|
+
previewPanelOpen: toObservable(previewPanelOpen),
|
|
1125
|
+
profile: toObservable(signals_profile)
|
|
1267
1126
|
};
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
api,
|
|
1273
|
-
builder,
|
|
1274
|
-
config,
|
|
1275
|
-
interceptors
|
|
1127
|
+
constructor(config){
|
|
1128
|
+
super(config, {
|
|
1129
|
+
experience: createStatefulExperienceApiConfig(config.api),
|
|
1130
|
+
insights: createStatefulInsightsApiConfig(config.api)
|
|
1276
1131
|
});
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1132
|
+
this.singletonOwner = `CoreStateful#${++statefulInstanceCounter}`;
|
|
1133
|
+
acquireStatefulRuntimeSingleton(this.singletonOwner);
|
|
1134
|
+
try {
|
|
1135
|
+
const { allowedEventTypes, defaults, getAnonymousId, onEventBlocked, queuePolicy } = config;
|
|
1136
|
+
const { changes: defaultChanges, consent: defaultConsent, selectedOptimizations: defaultSelectedOptimizations, profile: defaultProfile } = defaults ?? {};
|
|
1137
|
+
const resolvedQueuePolicy = resolveQueuePolicy(queuePolicy);
|
|
1138
|
+
this.allowedEventTypes = allowedEventTypes ?? DEFAULT_ALLOWED_EVENT_TYPES;
|
|
1139
|
+
this.onEventBlocked = onEventBlocked;
|
|
1140
|
+
this.insightsQueue = new InsightsQueue({
|
|
1141
|
+
eventInterceptors: this.interceptors.event,
|
|
1142
|
+
flushPolicy: resolvedQueuePolicy.flush,
|
|
1143
|
+
insightsApi: this.api.insights
|
|
1144
|
+
});
|
|
1145
|
+
this.experienceQueue = new ExperienceQueue({
|
|
1146
|
+
experienceApi: this.api.experience,
|
|
1147
|
+
eventInterceptors: this.interceptors.event,
|
|
1148
|
+
flushPolicy: resolvedQueuePolicy.flush,
|
|
1149
|
+
getAnonymousId: getAnonymousId ?? (()=>void 0),
|
|
1150
|
+
offlineMaxEvents: resolvedQueuePolicy.offlineMaxEvents,
|
|
1151
|
+
onOfflineDrop: resolvedQueuePolicy.onOfflineDrop,
|
|
1152
|
+
stateInterceptors: this.interceptors.state
|
|
1153
|
+
});
|
|
1154
|
+
if (void 0 !== defaultConsent) consent.value = defaultConsent;
|
|
1280
1155
|
batch(()=>{
|
|
1281
|
-
signals_changes.value = defaultChanges;
|
|
1282
|
-
|
|
1283
|
-
signals_profile.value = defaultProfile;
|
|
1156
|
+
if (void 0 !== defaultChanges) signals_changes.value = defaultChanges;
|
|
1157
|
+
if (void 0 !== defaultSelectedOptimizations) signals_selectedOptimizations.value = defaultSelectedOptimizations;
|
|
1158
|
+
if (void 0 !== defaultProfile) signals_profile.value = defaultProfile;
|
|
1284
1159
|
});
|
|
1160
|
+
this.initializeEffects();
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
releaseStatefulRuntimeSingleton(this.singletonOwner);
|
|
1163
|
+
throw error;
|
|
1285
1164
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
consent.value = defaultConsent;
|
|
1289
|
-
}
|
|
1290
|
-
this.getAnonymousId = getAnonymousId ?? (()=>void 0);
|
|
1165
|
+
}
|
|
1166
|
+
initializeEffects() {
|
|
1291
1167
|
effect(()=>{
|
|
1292
|
-
|
|
1168
|
+
CoreStateful_coreLogger.debug(`Profile ${signals_profile.value && `with ID ${signals_profile.value.id}`} has been ${signals_profile.value ? 'set' : 'cleared'}`);
|
|
1293
1169
|
});
|
|
1294
1170
|
effect(()=>{
|
|
1295
|
-
|
|
1171
|
+
CoreStateful_coreLogger.debug(`Variants have been ${signals_selectedOptimizations.value?.length ? 'populated' : 'cleared'}`);
|
|
1296
1172
|
});
|
|
1297
1173
|
effect(()=>{
|
|
1298
|
-
|
|
1174
|
+
CoreStateful_coreLogger.info(`Core ${consent.value ? 'will' : 'will not'} emit gated events due to consent (${consent.value})`);
|
|
1299
1175
|
});
|
|
1300
1176
|
effect(()=>{
|
|
1301
|
-
if (online.value)
|
|
1177
|
+
if (!online.value) return;
|
|
1178
|
+
this.insightsQueue.clearScheduledRetry();
|
|
1179
|
+
this.experienceQueue.clearScheduledRetry();
|
|
1180
|
+
this.flushQueues({
|
|
1181
|
+
force: true
|
|
1182
|
+
});
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
async flushQueues(options = {}) {
|
|
1186
|
+
await this.insightsQueue.flush(options);
|
|
1187
|
+
await this.experienceQueue.flush(options);
|
|
1188
|
+
}
|
|
1189
|
+
destroy() {
|
|
1190
|
+
if (this.destroyed) return;
|
|
1191
|
+
this.destroyed = true;
|
|
1192
|
+
this.insightsQueue.flush({
|
|
1193
|
+
force: true
|
|
1194
|
+
}).catch((error)=>{
|
|
1195
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.warn('Failed to flush insights queue during destroy()', String(error));
|
|
1196
|
+
});
|
|
1197
|
+
this.experienceQueue.flush({
|
|
1198
|
+
force: true
|
|
1199
|
+
}).catch((error)=>{
|
|
1200
|
+
__rspack_external__contentful_optimization_api_client_logger_f0d05f82.logger.warn('Failed to flush Experience queue during destroy()', String(error));
|
|
1302
1201
|
});
|
|
1202
|
+
this.insightsQueue.clearPeriodicFlushTimer();
|
|
1203
|
+
releaseStatefulRuntimeSingleton(this.singletonOwner);
|
|
1303
1204
|
}
|
|
1304
1205
|
reset() {
|
|
1305
1206
|
batch(()=>{
|
|
1306
|
-
|
|
1207
|
+
blockedEvent.value = void 0;
|
|
1307
1208
|
signals_event.value = void 0;
|
|
1209
|
+
signals_changes.value = void 0;
|
|
1308
1210
|
signals_profile.value = void 0;
|
|
1309
|
-
|
|
1211
|
+
signals_selectedOptimizations.value = void 0;
|
|
1310
1212
|
});
|
|
1311
1213
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
}
|
|
1315
|
-
personalizeEntry(entry, personalizations = signals_personalizations.value) {
|
|
1316
|
-
return super.personalizeEntry(entry, personalizations);
|
|
1214
|
+
async flush() {
|
|
1215
|
+
await this.flushQueues();
|
|
1317
1216
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1217
|
+
consent(accept) {
|
|
1218
|
+
consent.value = accept;
|
|
1320
1219
|
}
|
|
1321
|
-
|
|
1322
|
-
return
|
|
1220
|
+
get online() {
|
|
1221
|
+
return online.value ?? false;
|
|
1323
1222
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1223
|
+
set online(isOnline) {
|
|
1224
|
+
online.value = isOnline;
|
|
1326
1225
|
}
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
if (!isDuplicated) this.duplicationDetector.addValue(duplicationScope, value);
|
|
1331
|
-
return !isDuplicated;
|
|
1226
|
+
registerPreviewPanel(previewPanel) {
|
|
1227
|
+
Reflect.set(previewPanel, PREVIEW_PANEL_SIGNALS_SYMBOL, signals);
|
|
1228
|
+
Reflect.set(previewPanel, PREVIEW_PANEL_SIGNAL_FNS_SYMBOL, signalFns);
|
|
1332
1229
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1230
|
+
}
|
|
1231
|
+
const src_CoreStateful = CoreStateful;
|
|
1232
|
+
const TRACK_CLICK_PROFILE_ERROR = 'CoreStateless.forRequest().trackClick() requires `payload.profile.id` for Insights delivery.';
|
|
1233
|
+
const TRACK_HOVER_PROFILE_ERROR = 'CoreStateless.forRequest().trackHover() requires `payload.profile.id` for Insights delivery.';
|
|
1234
|
+
const TRACK_FLAG_VIEW_PROFILE_ERROR = 'CoreStateless.forRequest().trackFlagView() requires `payload.profile.id` for Insights delivery.';
|
|
1235
|
+
const NON_STICKY_TRACK_VIEW_PROFILE_ERROR = 'CoreStateless.forRequest().trackView() requires `payload.profile.id` when `payload.sticky` is not `true`.';
|
|
1236
|
+
const STICKY_TRACK_VIEW_PROFILE_ERROR = 'CoreStateless.forRequest().trackView() could not derive a profile from the sticky Experience response. Pass `payload.profile.id` explicitly if you need a fallback.';
|
|
1237
|
+
const requireInsightsProfile = (profile, errorMessage)=>{
|
|
1238
|
+
if (void 0 !== profile) return profile;
|
|
1239
|
+
throw new Error(errorMessage);
|
|
1240
|
+
};
|
|
1241
|
+
class CoreStatelessRequestScope {
|
|
1242
|
+
core;
|
|
1243
|
+
options;
|
|
1244
|
+
constructor(core, options = {}){
|
|
1245
|
+
this.core = core;
|
|
1246
|
+
this.options = Object.freeze({
|
|
1247
|
+
...options
|
|
1248
|
+
});
|
|
1335
1249
|
}
|
|
1336
1250
|
async identify(payload) {
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
return await this.sendOrEnqueueEvent(event);
|
|
1251
|
+
const { profile, ...builderArgs } = payload;
|
|
1252
|
+
return await this.sendExperienceEvent(this.core.eventBuilder.buildIdentify(builderArgs), profile);
|
|
1340
1253
|
}
|
|
1341
|
-
async page(payload) {
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
return await this.sendOrEnqueueEvent(event);
|
|
1254
|
+
async page(payload = {}) {
|
|
1255
|
+
const { profile, ...builderArgs } = payload;
|
|
1256
|
+
return await this.sendExperienceEvent(this.core.eventBuilder.buildPageView(builderArgs), profile);
|
|
1345
1257
|
}
|
|
1346
1258
|
async screen(payload) {
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
return await this.sendOrEnqueueEvent(event);
|
|
1259
|
+
const { profile, ...builderArgs } = payload;
|
|
1260
|
+
return await this.sendExperienceEvent(this.core.eventBuilder.buildScreenView(builderArgs), profile);
|
|
1350
1261
|
}
|
|
1351
1262
|
async track(payload) {
|
|
1352
|
-
PersonalizationStateful_logger.info(`Sending "track" event "${payload.event}"`);
|
|
1353
|
-
const event = this.builder.buildTrack(payload);
|
|
1354
|
-
return await this.sendOrEnqueueEvent(event);
|
|
1355
|
-
}
|
|
1356
|
-
async trackComponentView(payload, _duplicationScope = '') {
|
|
1357
|
-
PersonalizationStateful_logger.info(`Sending "track personalization" event for ${payload.componentId}`);
|
|
1358
|
-
const event = this.builder.buildComponentView(payload);
|
|
1359
|
-
return await this.sendOrEnqueueEvent(event);
|
|
1360
|
-
}
|
|
1361
|
-
async sendOrEnqueueEvent(event) {
|
|
1362
|
-
const intercepted = await this.interceptors.event.run(event);
|
|
1363
|
-
const validEvent = __rspack_external__contentful_optimization_api_client_cba5a7ee.ExperienceEvent.parse(intercepted);
|
|
1364
|
-
signals_event.value = validEvent;
|
|
1365
|
-
if (online.value) return await this.upsertProfile([
|
|
1366
|
-
validEvent
|
|
1367
|
-
]);
|
|
1368
|
-
PersonalizationStateful_logger.debug(`Queueing ${validEvent.type} event`, validEvent);
|
|
1369
|
-
this.offlineQueue.add(validEvent);
|
|
1370
|
-
}
|
|
1371
|
-
async flush() {
|
|
1372
|
-
if (0 === this.offlineQueue.size) return;
|
|
1373
|
-
PersonalizationStateful_logger.debug('Flushing offline event queue');
|
|
1374
|
-
await this.upsertProfile(Array.from(this.offlineQueue));
|
|
1375
|
-
this.offlineQueue.clear();
|
|
1376
|
-
}
|
|
1377
|
-
async upsertProfile(events) {
|
|
1378
|
-
const anonymousId = this.getAnonymousId();
|
|
1379
|
-
if (anonymousId) PersonalizationStateful_logger.debug(`Anonymous ID found: ${anonymousId}`);
|
|
1380
|
-
const data = await this.api.experience.upsertProfile({
|
|
1381
|
-
profileId: anonymousId ?? signals_profile.value?.id,
|
|
1382
|
-
events
|
|
1383
|
-
});
|
|
1384
|
-
await this.updateOutputSignals(data);
|
|
1385
|
-
return data;
|
|
1386
|
-
}
|
|
1387
|
-
async updateOutputSignals(data) {
|
|
1388
|
-
const intercepted = await this.interceptors.state.run(data);
|
|
1389
|
-
const { changes, personalizations, profile } = intercepted;
|
|
1390
|
-
batch(()=>{
|
|
1391
|
-
if (!isEqual(signals_changes.value, changes)) signals_changes.value = changes;
|
|
1392
|
-
if (!isEqual(signals_profile.value, profile)) signals_profile.value = profile;
|
|
1393
|
-
if (!isEqual(signals_personalizations.value, personalizations)) signals_personalizations.value = personalizations;
|
|
1394
|
-
});
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
const personalization_PersonalizationStateful = PersonalizationStateful;
|
|
1398
|
-
const PersonalizationStateless_logger = createScopedLogger('Personalization');
|
|
1399
|
-
class PersonalizationStateless extends personalization_PersonalizationBase {
|
|
1400
|
-
async identify(payload) {
|
|
1401
|
-
PersonalizationStateless_logger.info('Sending "identify" event');
|
|
1402
1263
|
const { profile, ...builderArgs } = payload;
|
|
1403
|
-
|
|
1404
|
-
return await this.upsertProfile(event, profile);
|
|
1264
|
+
return await this.sendExperienceEvent(this.core.eventBuilder.buildTrack(builderArgs), profile);
|
|
1405
1265
|
}
|
|
1406
|
-
async
|
|
1407
|
-
PersonalizationStateless_logger.info('Sending "page" event');
|
|
1266
|
+
async trackView(payload) {
|
|
1408
1267
|
const { profile, ...builderArgs } = payload;
|
|
1409
|
-
|
|
1410
|
-
|
|
1268
|
+
let result;
|
|
1269
|
+
let insightsProfile = profile;
|
|
1270
|
+
if (payload.sticky) {
|
|
1271
|
+
result = await this.sendExperienceEvent(this.core.eventBuilder.buildView(builderArgs), profile);
|
|
1272
|
+
const { profile: responseProfile } = result;
|
|
1273
|
+
insightsProfile = responseProfile;
|
|
1274
|
+
}
|
|
1275
|
+
await this.sendInsightsEvent(this.core.eventBuilder.buildView(builderArgs), requireInsightsProfile(insightsProfile, payload.sticky ? STICKY_TRACK_VIEW_PROFILE_ERROR : NON_STICKY_TRACK_VIEW_PROFILE_ERROR));
|
|
1276
|
+
return result;
|
|
1411
1277
|
}
|
|
1412
|
-
async
|
|
1413
|
-
PersonalizationStateless_logger.info(`Sending "screen" event for "${payload.name}"`);
|
|
1278
|
+
async trackClick(payload) {
|
|
1414
1279
|
const { profile, ...builderArgs } = payload;
|
|
1415
|
-
|
|
1416
|
-
return await this.upsertProfile(event, profile);
|
|
1280
|
+
await this.sendInsightsEvent(this.core.eventBuilder.buildClick(builderArgs), requireInsightsProfile(profile, TRACK_CLICK_PROFILE_ERROR));
|
|
1417
1281
|
}
|
|
1418
|
-
async
|
|
1419
|
-
PersonalizationStateless_logger.info(`Sending "track" event "${payload.event}"`);
|
|
1282
|
+
async trackHover(payload) {
|
|
1420
1283
|
const { profile, ...builderArgs } = payload;
|
|
1421
|
-
|
|
1422
|
-
return await this.upsertProfile(event, profile);
|
|
1284
|
+
await this.sendInsightsEvent(this.core.eventBuilder.buildHover(builderArgs), requireInsightsProfile(profile, TRACK_HOVER_PROFILE_ERROR));
|
|
1423
1285
|
}
|
|
1424
|
-
async
|
|
1425
|
-
PersonalizationStateless_logger.info('Sending "track personalization" event');
|
|
1286
|
+
async trackFlagView(payload) {
|
|
1426
1287
|
const { profile, ...builderArgs } = payload;
|
|
1427
|
-
|
|
1428
|
-
return await this.upsertProfile(event, profile);
|
|
1288
|
+
await this.sendInsightsEvent(this.core.eventBuilder.buildFlagView(builderArgs), requireInsightsProfile(profile, TRACK_FLAG_VIEW_PROFILE_ERROR));
|
|
1429
1289
|
}
|
|
1430
|
-
async
|
|
1431
|
-
const intercepted = await this.interceptors.event.run(event);
|
|
1432
|
-
const
|
|
1290
|
+
async sendExperienceEvent(event, profile) {
|
|
1291
|
+
const intercepted = await this.core.interceptors.event.run(event);
|
|
1292
|
+
const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.ExperienceEvent, intercepted);
|
|
1293
|
+
return await this.core.api.experience.upsertProfile({
|
|
1433
1294
|
profileId: profile?.id,
|
|
1434
1295
|
events: [
|
|
1435
|
-
|
|
1296
|
+
validEvent
|
|
1436
1297
|
]
|
|
1437
|
-
});
|
|
1438
|
-
return data;
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
const personalization_PersonalizationStateless = PersonalizationStateless;
|
|
1442
|
-
class CoreStateful extends src_CoreBase {
|
|
1443
|
-
analytics;
|
|
1444
|
-
personalization;
|
|
1445
|
-
constructor(config){
|
|
1446
|
-
super(config);
|
|
1447
|
-
const { allowedEventTypes, defaults, getAnonymousId, preventedComponentEvents } = config;
|
|
1448
|
-
if (defaults?.consent !== void 0) {
|
|
1449
|
-
const { consent: defaultConsent } = defaults;
|
|
1450
|
-
consent.value = defaultConsent;
|
|
1451
|
-
}
|
|
1452
|
-
this.analytics = new analytics_AnalyticsStateful({
|
|
1453
|
-
api: this.api,
|
|
1454
|
-
builder: this.eventBuilder,
|
|
1455
|
-
config: {
|
|
1456
|
-
allowedEventTypes,
|
|
1457
|
-
preventedComponentEvents,
|
|
1458
|
-
defaults: {
|
|
1459
|
-
consent: defaults?.consent,
|
|
1460
|
-
profile: defaults?.profile
|
|
1461
|
-
}
|
|
1462
|
-
},
|
|
1463
|
-
interceptors: this.interceptors
|
|
1464
|
-
});
|
|
1465
|
-
this.personalization = new personalization_PersonalizationStateful({
|
|
1466
|
-
api: this.api,
|
|
1467
|
-
builder: this.eventBuilder,
|
|
1468
|
-
config: {
|
|
1469
|
-
allowedEventTypes,
|
|
1470
|
-
getAnonymousId,
|
|
1471
|
-
preventedComponentEvents,
|
|
1472
|
-
defaults: {
|
|
1473
|
-
consent: defaults?.consent,
|
|
1474
|
-
changes: defaults?.changes,
|
|
1475
|
-
profile: defaults?.profile,
|
|
1476
|
-
personalizations: defaults?.personalizations
|
|
1477
|
-
}
|
|
1478
|
-
},
|
|
1479
|
-
interceptors: this.interceptors
|
|
1480
|
-
});
|
|
1481
|
-
}
|
|
1482
|
-
get states() {
|
|
1483
|
-
return {
|
|
1484
|
-
consent: toObservable(consent),
|
|
1485
|
-
eventStream: toObservable(signals_event),
|
|
1486
|
-
flags: toObservable(flags),
|
|
1487
|
-
personalizations: toObservable(signals_personalizations),
|
|
1488
|
-
profile: toObservable(signals_profile)
|
|
1489
|
-
};
|
|
1490
|
-
}
|
|
1491
|
-
reset() {
|
|
1492
|
-
batch(()=>{
|
|
1493
|
-
signals_event.value = void 0;
|
|
1494
|
-
signals_changes.value = void 0;
|
|
1495
|
-
signals_profile.value = void 0;
|
|
1496
|
-
signals_personalizations.value = void 0;
|
|
1497
|
-
});
|
|
1298
|
+
}, this.options);
|
|
1498
1299
|
}
|
|
1499
|
-
async
|
|
1500
|
-
await this.
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1300
|
+
async sendInsightsEvent(event, profile) {
|
|
1301
|
+
const intercepted = await this.core.interceptors.event.run(event);
|
|
1302
|
+
const validEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.InsightsEvent, intercepted);
|
|
1303
|
+
const batchEvent = (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.BatchInsightsEventArray, [
|
|
1304
|
+
{
|
|
1305
|
+
profile: (0, __rspack_external__contentful_optimization_api_client_api_schemas_4192893e.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_client_api_schemas_4192893e.PartialProfile, profile),
|
|
1306
|
+
events: [
|
|
1307
|
+
validEvent
|
|
1308
|
+
]
|
|
1309
|
+
}
|
|
1310
|
+
]);
|
|
1311
|
+
await this.core.api.insights.sendBatchEvents(batchEvent);
|
|
1511
1312
|
}
|
|
1512
1313
|
}
|
|
1513
|
-
const
|
|
1314
|
+
const CoreStateless_hasDefinedValues = (record)=>Object.values(record).some((value)=>void 0 !== value);
|
|
1315
|
+
const createStatelessExperienceApiConfig = (api)=>{
|
|
1316
|
+
if (void 0 === api) return;
|
|
1317
|
+
const experienceConfig = {
|
|
1318
|
+
baseUrl: api.experienceBaseUrl,
|
|
1319
|
+
enabledFeatures: api.enabledFeatures
|
|
1320
|
+
};
|
|
1321
|
+
return CoreStateless_hasDefinedValues(experienceConfig) ? experienceConfig : void 0;
|
|
1322
|
+
};
|
|
1323
|
+
const createStatelessInsightsApiConfig = (api)=>{
|
|
1324
|
+
if (api?.insightsBaseUrl === void 0) return;
|
|
1325
|
+
return {
|
|
1326
|
+
baseUrl: api.insightsBaseUrl
|
|
1327
|
+
};
|
|
1328
|
+
};
|
|
1514
1329
|
class CoreStateless extends src_CoreBase {
|
|
1515
|
-
analytics;
|
|
1516
|
-
personalization;
|
|
1517
1330
|
constructor(config){
|
|
1518
|
-
super(config
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
builder: this.eventBuilder,
|
|
1522
|
-
interceptors: this.interceptors
|
|
1523
|
-
});
|
|
1524
|
-
this.personalization = new personalization_PersonalizationStateless({
|
|
1525
|
-
api: this.api,
|
|
1526
|
-
builder: this.eventBuilder,
|
|
1527
|
-
interceptors: this.interceptors
|
|
1331
|
+
super(config, {
|
|
1332
|
+
experience: createStatelessExperienceApiConfig(config.api),
|
|
1333
|
+
insights: createStatelessInsightsApiConfig(config.api)
|
|
1528
1334
|
});
|
|
1529
1335
|
}
|
|
1336
|
+
forRequest(options = {}) {
|
|
1337
|
+
return new CoreStatelessRequestScope(this, options);
|
|
1338
|
+
}
|
|
1530
1339
|
}
|
|
1531
1340
|
const src_CoreStateless = CoreStateless;
|
|
1532
|
-
|
|
1533
|
-
|
|
1341
|
+
const isFunction = (v)=>'function' == typeof v;
|
|
1342
|
+
const nameToString = (name)=>'string' == typeof name ? name : 'symbol' == typeof name ? name.description ?? String(name) : String(name);
|
|
1343
|
+
const isOnBlockedKey = (v)=>'string' == typeof v || 'symbol' == typeof v;
|
|
1344
|
+
const isAsyncFunction = (fn)=>'[object AsyncFunction]' === Object.prototype.toString.call(fn);
|
|
1345
|
+
function guardedBy(predicateName, opts) {
|
|
1346
|
+
return function(_value, context) {
|
|
1347
|
+
const decoratedName = nameToString(context.name);
|
|
1348
|
+
context.addInitializer(function() {
|
|
1349
|
+
const originalUnknown = Reflect.get(this, context.name);
|
|
1350
|
+
if (!isFunction(originalUnknown)) return;
|
|
1351
|
+
const original = originalUnknown;
|
|
1352
|
+
const originalIsAsync = isAsyncFunction(original);
|
|
1353
|
+
const resolvePredicate = (self)=>{
|
|
1354
|
+
const { [predicateName]: cand } = self;
|
|
1355
|
+
if (!isFunction(cand)) throw new TypeError(`@guardedBy expects predicate "${String(predicateName)}" to be a synchronous function.`);
|
|
1356
|
+
return cand;
|
|
1357
|
+
};
|
|
1358
|
+
const computeAllowed = (self, args)=>{
|
|
1359
|
+
const pred = resolvePredicate(self);
|
|
1360
|
+
const ok = Boolean(pred.call(self, decoratedName, args));
|
|
1361
|
+
return opts?.invert === true ? !ok : ok;
|
|
1362
|
+
};
|
|
1363
|
+
const runOnBlocked = (self, args)=>{
|
|
1364
|
+
const { onBlocked } = opts ?? {};
|
|
1365
|
+
if (void 0 === onBlocked) return;
|
|
1366
|
+
if (isFunction(onBlocked)) return void onBlocked.call(self, decoratedName, args);
|
|
1367
|
+
if (isOnBlockedKey(onBlocked)) {
|
|
1368
|
+
const { [onBlocked]: handlerCandidate } = self;
|
|
1369
|
+
if (isFunction(handlerCandidate)) handlerCandidate.call(self, decoratedName, args);
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
const blockedReturn = ()=>originalIsAsync ? Promise.resolve(void 0) : void 0;
|
|
1373
|
+
const wrapped = function(...args) {
|
|
1374
|
+
if (!computeAllowed(this, args)) {
|
|
1375
|
+
runOnBlocked(this, args);
|
|
1376
|
+
return blockedReturn();
|
|
1377
|
+
}
|
|
1378
|
+
return original.call(this, ...args);
|
|
1379
|
+
};
|
|
1380
|
+
Reflect.set(this, context.name, wrapped);
|
|
1381
|
+
});
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
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, PROFILE_CACHE_KEY, SELECTED_OPTIMIZATIONS_CACHE_KEY } from "./260.mjs";
|
|
1385
|
+
export { PREVIEW_PANEL_SIGNALS_SYMBOL, PREVIEW_PANEL_SIGNAL_FNS_SYMBOL } from "./632.mjs";
|
|
1386
|
+
export { ClickBuilderArgs, CoreStatelessRequestScope, DEFAULT_PAGE_PROPERTIES, EntryInteractionBuilderArgsBase, FlagViewBuilderArgs, HoverBuilderArgs, IdentifyBuilderArgs, InterceptorManager, PageViewBuilderArgs, ScreenViewBuilderArgs, TrackBuilderArgs, UniversalEventBuilderArgs, ViewBuilderArgs, batch, effect, events_EventBuilder as EventBuilder, guardedBy, resolvers_FlagsResolver as FlagsResolver, resolvers_MergeTagValueResolver as MergeTagValueResolver, resolvers_OptimizedEntryResolver as OptimizedEntryResolver, signalFns, signals, src_CoreStateful as CoreStateful, src_CoreStateless as CoreStateless, toDistinctObservable, toObservable };
|
|
1534
1387
|
|
|
1535
1388
|
//# sourceMappingURL=index.mjs.map
|