@contentful/optimization-core 0.1.0-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +408 -0
- package/dist/Consent.d.ts +44 -0
- package/dist/Consent.d.ts.map +1 -0
- package/dist/Consent.js +2 -0
- package/dist/Consent.js.map +1 -0
- package/dist/CoreBase.d.ts +161 -0
- package/dist/CoreBase.d.ts.map +1 -0
- package/dist/CoreBase.js +151 -0
- package/dist/CoreBase.js.map +1 -0
- package/dist/CoreStateful.d.ts +142 -0
- package/dist/CoreStateful.d.ts.map +1 -0
- package/dist/CoreStateful.js +137 -0
- package/dist/CoreStateful.js.map +1 -0
- package/dist/CoreStateless.d.ts +53 -0
- package/dist/CoreStateless.d.ts.map +1 -0
- package/dist/CoreStateless.js +43 -0
- package/dist/CoreStateless.js.map +1 -0
- package/dist/ProductBase.d.ts +83 -0
- package/dist/ProductBase.d.ts.map +1 -0
- package/dist/ProductBase.js +50 -0
- package/dist/ProductBase.js.map +1 -0
- package/dist/analytics/AnalyticsBase.d.ts +35 -0
- package/dist/analytics/AnalyticsBase.d.ts.map +1 -0
- package/dist/analytics/AnalyticsBase.js +13 -0
- package/dist/analytics/AnalyticsBase.js.map +1 -0
- package/dist/analytics/AnalyticsStateful.d.ts +138 -0
- package/dist/analytics/AnalyticsStateful.d.ts.map +1 -0
- package/dist/analytics/AnalyticsStateful.js +179 -0
- package/dist/analytics/AnalyticsStateful.js.map +1 -0
- package/dist/analytics/AnalyticsStateless.d.ts +48 -0
- package/dist/analytics/AnalyticsStateless.d.ts.map +1 -0
- package/dist/analytics/AnalyticsStateless.js +61 -0
- package/dist/analytics/AnalyticsStateless.js.map +1 -0
- package/dist/analytics/index.d.ts +5 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +5 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/global-constants.d.ts +18 -0
- package/dist/global-constants.d.ts.map +1 -0
- package/dist/global-constants.js +18 -0
- package/dist/global-constants.js.map +1 -0
- package/dist/index.cjs +1808 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1535 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/decorators/guardedBy.d.ts +113 -0
- package/dist/lib/decorators/guardedBy.d.ts.map +1 -0
- package/dist/lib/decorators/guardedBy.js +143 -0
- package/dist/lib/decorators/guardedBy.js.map +1 -0
- package/dist/lib/decorators/index.d.ts +2 -0
- package/dist/lib/decorators/index.d.ts.map +1 -0
- package/dist/lib/decorators/index.js +2 -0
- package/dist/lib/decorators/index.js.map +1 -0
- package/dist/lib/interceptor/InterceptorManager.d.ts +127 -0
- package/dist/lib/interceptor/InterceptorManager.d.ts.map +1 -0
- package/dist/lib/interceptor/InterceptorManager.js +125 -0
- package/dist/lib/interceptor/InterceptorManager.js.map +1 -0
- package/dist/lib/interceptor/index.d.ts +2 -0
- package/dist/lib/interceptor/index.d.ts.map +1 -0
- package/dist/lib/interceptor/index.js +2 -0
- package/dist/lib/interceptor/index.js.map +1 -0
- package/dist/lib/value-presence/ValuePresence.d.ts +123 -0
- package/dist/lib/value-presence/ValuePresence.d.ts.map +1 -0
- package/dist/lib/value-presence/ValuePresence.js +141 -0
- package/dist/lib/value-presence/ValuePresence.js.map +1 -0
- package/dist/lib/value-presence/index.d.ts +2 -0
- package/dist/lib/value-presence/index.d.ts.map +1 -0
- package/dist/lib/value-presence/index.js +2 -0
- package/dist/lib/value-presence/index.js.map +1 -0
- package/dist/personalization/PersonalizationBase.d.ts +184 -0
- package/dist/personalization/PersonalizationBase.d.ts.map +1 -0
- package/dist/personalization/PersonalizationBase.js +76 -0
- package/dist/personalization/PersonalizationBase.js.map +1 -0
- package/dist/personalization/PersonalizationStateful.d.ts +226 -0
- package/dist/personalization/PersonalizationStateful.d.ts.map +1 -0
- package/dist/personalization/PersonalizationStateful.js +297 -0
- package/dist/personalization/PersonalizationStateful.js.map +1 -0
- package/dist/personalization/PersonalizationStateless.d.ts +74 -0
- package/dist/personalization/PersonalizationStateless.d.ts.map +1 -0
- package/dist/personalization/PersonalizationStateless.js +98 -0
- package/dist/personalization/PersonalizationStateless.js.map +1 -0
- package/dist/personalization/index.d.ts +6 -0
- package/dist/personalization/index.d.ts.map +1 -0
- package/dist/personalization/index.js +6 -0
- package/dist/personalization/index.js.map +1 -0
- package/dist/personalization/resolvers/FlagsResolver.d.ts +35 -0
- package/dist/personalization/resolvers/FlagsResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/FlagsResolver.js +47 -0
- package/dist/personalization/resolvers/FlagsResolver.js.map +1 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.d.ts +74 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.js +109 -0
- package/dist/personalization/resolvers/MergeTagValueResolver.js.map +1 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts +142 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.d.ts.map +1 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.js +196 -0
- package/dist/personalization/resolvers/PersonalizedEntryResolver.js.map +1 -0
- package/dist/personalization/resolvers/index.d.ts +7 -0
- package/dist/personalization/resolvers/index.d.ts.map +1 -0
- package/dist/personalization/resolvers/index.js +7 -0
- package/dist/personalization/resolvers/index.js.map +1 -0
- package/dist/signals.d.ts +35 -0
- package/dist/signals.d.ts.map +1 -0
- package/dist/signals.js +30 -0
- package/dist/signals.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import { ExperienceEvent as PersonalizationEvent, } from '@contentful/optimization-api-client';
|
|
2
|
+
import { isEqual } from 'es-toolkit';
|
|
3
|
+
import { createScopedLogger } from 'logger';
|
|
4
|
+
import { guardedBy } from '../lib/decorators';
|
|
5
|
+
import { batch, changes as changesSignal, consent as consentSignal, effect, event as eventSignal, flags as flagsSignal, online as onlineSignal, personalizations as personalizationsSignal, profile as profileSignal, toObservable, } from '../signals';
|
|
6
|
+
import PersonalizationBase from './PersonalizationBase';
|
|
7
|
+
const logger = createScopedLogger('Personalization');
|
|
8
|
+
/**
|
|
9
|
+
* Stateful personalization product that manages consent, profile, flags, and
|
|
10
|
+
* selected variants while emitting Experience events and updating state.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
* @remarks
|
|
14
|
+
* The class maintains reactive signals and exposes read‑only observables via
|
|
15
|
+
* {@link PersonalizationStateful.states}. Events are validated via schema parsers and
|
|
16
|
+
* run through interceptors before being submitted. Resulting state is merged
|
|
17
|
+
* back into signals.
|
|
18
|
+
*/
|
|
19
|
+
class PersonalizationStateful extends PersonalizationBase {
|
|
20
|
+
/** In‑memory queue for offline events keyed by profile. */
|
|
21
|
+
offlineQueue = new Set();
|
|
22
|
+
/** Exposed observable state references. */
|
|
23
|
+
states = {
|
|
24
|
+
eventStream: toObservable(eventSignal),
|
|
25
|
+
flags: toObservable(flagsSignal),
|
|
26
|
+
profile: toObservable(profileSignal),
|
|
27
|
+
personalizations: toObservable(personalizationsSignal),
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Function that provides an anonymous ID when available.
|
|
31
|
+
*
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
getAnonymousId;
|
|
35
|
+
/**
|
|
36
|
+
* Create a new stateful personalization instance.
|
|
37
|
+
*
|
|
38
|
+
* @param options - Options to configure the personalization product for stateful environments.
|
|
39
|
+
*/
|
|
40
|
+
constructor(options) {
|
|
41
|
+
const { api, builder, config, interceptors } = options;
|
|
42
|
+
super({ api, builder, config, interceptors });
|
|
43
|
+
const { defaults, getAnonymousId } = config ?? {};
|
|
44
|
+
if (defaults) {
|
|
45
|
+
const { changes: defaultChanges, personalizations: defaultPersonalizations, profile: defaultProfile, } = defaults;
|
|
46
|
+
batch(() => {
|
|
47
|
+
changesSignal.value = defaultChanges;
|
|
48
|
+
personalizationsSignal.value = defaultPersonalizations;
|
|
49
|
+
profileSignal.value = defaultProfile;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (defaults?.consent !== undefined) {
|
|
53
|
+
const { consent: defaultConsent } = defaults;
|
|
54
|
+
consentSignal.value = defaultConsent;
|
|
55
|
+
}
|
|
56
|
+
this.getAnonymousId = getAnonymousId ?? (() => undefined);
|
|
57
|
+
// Log signal changes for observability
|
|
58
|
+
effect(() => {
|
|
59
|
+
logger.debug(`Profile ${profileSignal.value && `with ID ${profileSignal.value.id}`} has been ${profileSignal.value ? 'set' : 'cleared'}`);
|
|
60
|
+
});
|
|
61
|
+
effect(() => {
|
|
62
|
+
logger.debug(`Variants have been ${personalizationsSignal.value?.length ? 'populated' : 'cleared'}`);
|
|
63
|
+
});
|
|
64
|
+
effect(() => {
|
|
65
|
+
logger.info(`Personalization ${consentSignal.value ? 'will' : 'will not'} take effect due to consent (${consentSignal.value})`);
|
|
66
|
+
});
|
|
67
|
+
effect(() => {
|
|
68
|
+
if (onlineSignal.value)
|
|
69
|
+
void this.flush();
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Reset stateful signals managed by this product.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* Clears `changes`, `profile`, and selected `personalizations`.
|
|
77
|
+
*/
|
|
78
|
+
reset() {
|
|
79
|
+
batch(() => {
|
|
80
|
+
changesSignal.value = undefined;
|
|
81
|
+
eventSignal.value = undefined;
|
|
82
|
+
profileSignal.value = undefined;
|
|
83
|
+
personalizationsSignal.value = undefined;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get the specified Custom Flag's value (derived from the signal).
|
|
88
|
+
* @param name - The name or key of the Custom Flag.
|
|
89
|
+
* @returns The current value of the Custom Flag if found.
|
|
90
|
+
* */
|
|
91
|
+
getCustomFlag(name, changes = changesSignal.value) {
|
|
92
|
+
return super.getCustomFlag(name, changes);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resolve a Contentful entry to a personalized variant using the current
|
|
96
|
+
* or provided selections.
|
|
97
|
+
*
|
|
98
|
+
* @typeParam S - Entry skeleton type.
|
|
99
|
+
* @typeParam M - Chain modifiers.
|
|
100
|
+
* @typeParam L - Locale code.
|
|
101
|
+
* @param entry - The entry to personalize.
|
|
102
|
+
* @param personalizations - Optional selections; defaults to the current signal value.
|
|
103
|
+
* @returns The resolved entry data.
|
|
104
|
+
*/
|
|
105
|
+
personalizeEntry(entry, personalizations = personalizationsSignal.value) {
|
|
106
|
+
return super.personalizeEntry(entry, personalizations);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Resolve a merge tag to a value based on the current (or provided) profile.
|
|
110
|
+
*
|
|
111
|
+
* @param embeddedEntryNodeTarget - The merge‑tag entry node to resolve.
|
|
112
|
+
* @param profile - Optional profile; defaults to the current signal value.
|
|
113
|
+
* @returns The resolved value (type depends on the tag).
|
|
114
|
+
* @remarks
|
|
115
|
+
* Merge tags are references to profile data that can be substituted into content.
|
|
116
|
+
*/
|
|
117
|
+
getMergeTagValue(embeddedEntryNodeTarget, profile = profileSignal.value) {
|
|
118
|
+
return super.getMergeTagValue(embeddedEntryNodeTarget, profile);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Determine whether the named operation is permitted based on consent and
|
|
122
|
+
* allowed event type configuration.
|
|
123
|
+
*
|
|
124
|
+
* @param name - Method name; `trackComponentView` is normalized to
|
|
125
|
+
* `'component'` for allow‑list checks.
|
|
126
|
+
* @returns `true` if the operation is permitted; otherwise `false`.
|
|
127
|
+
*/
|
|
128
|
+
hasConsent(name) {
|
|
129
|
+
return (!!consentSignal.value ||
|
|
130
|
+
(this.allowedEventTypes ?? []).includes(name === 'trackComponentView' || name === 'trackFlagView' ? 'component' : name));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Hook invoked when an operation is blocked due to missing consent.
|
|
134
|
+
*
|
|
135
|
+
* @param name - The blocked operation name.
|
|
136
|
+
* @param payload - The original arguments supplied to the operation.
|
|
137
|
+
*/
|
|
138
|
+
onBlockedByConsent(name, payload) {
|
|
139
|
+
logger.warn(`Event "${name}" was blocked due to lack of consent; payload: ${JSON.stringify(payload)}`);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Guard used to suppress duplicate component view events for the same
|
|
143
|
+
* component based on a duplication key and the component identifier.
|
|
144
|
+
*
|
|
145
|
+
* @param _name - Operation name (unused).
|
|
146
|
+
* @param payload - Tuple `[builderArgs, duplicationScope]`.
|
|
147
|
+
* @returns `true` if the event is NOT a duplicate and should proceed.
|
|
148
|
+
*/
|
|
149
|
+
isNotDuplicated(_name, payload) {
|
|
150
|
+
const [{ componentId: value }, duplicationScope] = payload;
|
|
151
|
+
const isDuplicated = this.duplicationDetector.isPresent(duplicationScope, value);
|
|
152
|
+
if (!isDuplicated)
|
|
153
|
+
this.duplicationDetector.addValue(duplicationScope, value);
|
|
154
|
+
return !isDuplicated;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Hook invoked when an operation is blocked by the duplication guard.
|
|
158
|
+
*
|
|
159
|
+
* @param _name - The blocked operation name (unused).
|
|
160
|
+
* @param payload - The original arguments supplied to the operation.
|
|
161
|
+
*/
|
|
162
|
+
onBlockedByDuplication(_name, payload) {
|
|
163
|
+
logger.debug(`Duplicate "component view" event detected, skipping; payload: ${JSON.stringify(payload)}`);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Identify the current profile/visitor to associate traits with a profile
|
|
167
|
+
* and update optimization state.
|
|
168
|
+
*
|
|
169
|
+
* @param payload - Identify builder payload.
|
|
170
|
+
* @returns The resulting {@link OptimizationData} for the identified user.
|
|
171
|
+
*/
|
|
172
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
173
|
+
async identify(payload) {
|
|
174
|
+
logger.info('Sending "identify" event');
|
|
175
|
+
const event = this.builder.buildIdentify(payload);
|
|
176
|
+
return await this.sendOrEnqueueEvent(event);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Record a page view and update optimization state.
|
|
180
|
+
*
|
|
181
|
+
* @param payload - Page view builder payload.
|
|
182
|
+
* @returns The evaluated {@link OptimizationData} for this page view.
|
|
183
|
+
*/
|
|
184
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
185
|
+
async page(payload) {
|
|
186
|
+
logger.info('Sending "page" event');
|
|
187
|
+
const event = this.builder.buildPageView(payload);
|
|
188
|
+
return await this.sendOrEnqueueEvent(event);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Record a screen view and update optimization state.
|
|
192
|
+
*
|
|
193
|
+
* @param payload - Screen view builder payload.
|
|
194
|
+
* @returns The evaluated {@link OptimizationData} for this screen view.
|
|
195
|
+
*/
|
|
196
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
197
|
+
async screen(payload) {
|
|
198
|
+
logger.info(`Sending "screen" event for "${payload.name}"`);
|
|
199
|
+
const event = this.builder.buildScreenView(payload);
|
|
200
|
+
return await this.sendOrEnqueueEvent(event);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Record a custom track event and update optimization state.
|
|
204
|
+
*
|
|
205
|
+
* @param payload - Track builder payload.
|
|
206
|
+
* @returns The evaluated {@link OptimizationData} for this event.
|
|
207
|
+
*/
|
|
208
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
209
|
+
async track(payload) {
|
|
210
|
+
logger.info(`Sending "track" event "${payload.event}"`);
|
|
211
|
+
const event = this.builder.buildTrack(payload);
|
|
212
|
+
return await this.sendOrEnqueueEvent(event);
|
|
213
|
+
}
|
|
214
|
+
@guardedBy('isNotDuplicated', { onBlocked: 'onBlockedByDuplication' })
|
|
215
|
+
@guardedBy('hasConsent', { onBlocked: 'onBlockedByConsent' })
|
|
216
|
+
/**
|
|
217
|
+
* Record a "sticky" component view and update optimization state.
|
|
218
|
+
*
|
|
219
|
+
* @param payload - Component view builder payload.
|
|
220
|
+
* @param _duplicationScope - Optional duplication scope key used to suppress duplicates.
|
|
221
|
+
* @returns The evaluated {@link OptimizationData} for this component view.
|
|
222
|
+
*/
|
|
223
|
+
async trackComponentView(payload, _duplicationScope = '') {
|
|
224
|
+
logger.info(`Sending "track personalization" event for ${payload.componentId}`);
|
|
225
|
+
const event = this.builder.buildComponentView(payload);
|
|
226
|
+
return await this.sendOrEnqueueEvent(event);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Intercept, validate, and place an event into the offline eventd queue; then
|
|
230
|
+
* trigger a size‑based flush if necessary.
|
|
231
|
+
*
|
|
232
|
+
* @param event - The event to enqueue.
|
|
233
|
+
*/
|
|
234
|
+
async sendOrEnqueueEvent(event) {
|
|
235
|
+
const intercepted = await this.interceptors.event.run(event);
|
|
236
|
+
const validEvent = PersonalizationEvent.parse(intercepted);
|
|
237
|
+
eventSignal.value = validEvent;
|
|
238
|
+
if (onlineSignal.value)
|
|
239
|
+
return await this.upsertProfile([validEvent]);
|
|
240
|
+
logger.debug(`Queueing ${validEvent.type} event`, validEvent);
|
|
241
|
+
this.offlineQueue.add(validEvent);
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Flush the offline queue
|
|
246
|
+
*/
|
|
247
|
+
async flush() {
|
|
248
|
+
if (this.offlineQueue.size === 0)
|
|
249
|
+
return;
|
|
250
|
+
logger.debug('Flushing offline event queue');
|
|
251
|
+
await this.upsertProfile(Array.from(this.offlineQueue));
|
|
252
|
+
this.offlineQueue.clear();
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Submit events to the Experience API, updating output signals with the
|
|
256
|
+
* returned state.
|
|
257
|
+
*
|
|
258
|
+
* @param events - The events to submit.
|
|
259
|
+
* @returns The {@link OptimizationData} returned by the service.
|
|
260
|
+
* @internal
|
|
261
|
+
* @privateRemarks
|
|
262
|
+
* If a `getAnonymousId` function has been provided, the returned value will
|
|
263
|
+
* take precedence over the `id` property of the current {@link Profile}
|
|
264
|
+
* signal value
|
|
265
|
+
*/
|
|
266
|
+
async upsertProfile(events) {
|
|
267
|
+
const anonymousId = this.getAnonymousId();
|
|
268
|
+
if (anonymousId)
|
|
269
|
+
logger.debug(`Anonymous ID found: ${anonymousId}`);
|
|
270
|
+
const data = await this.api.experience.upsertProfile({
|
|
271
|
+
profileId: anonymousId ?? profileSignal.value?.id,
|
|
272
|
+
events,
|
|
273
|
+
});
|
|
274
|
+
await this.updateOutputSignals(data);
|
|
275
|
+
return data;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Apply returned optimization state to local signals after interceptor processing.
|
|
279
|
+
*
|
|
280
|
+
* @param data - Optimization state returned by the service.
|
|
281
|
+
* @internal
|
|
282
|
+
*/
|
|
283
|
+
async updateOutputSignals(data) {
|
|
284
|
+
const intercepted = await this.interceptors.state.run(data);
|
|
285
|
+
const { changes, personalizations, profile } = intercepted;
|
|
286
|
+
batch(() => {
|
|
287
|
+
if (!isEqual(changesSignal.value, changes))
|
|
288
|
+
changesSignal.value = changes;
|
|
289
|
+
if (!isEqual(profileSignal.value, profile))
|
|
290
|
+
profileSignal.value = profile;
|
|
291
|
+
if (!isEqual(personalizationsSignal.value, personalizations))
|
|
292
|
+
personalizationsSignal.value = personalizations;
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
export default PersonalizationStateful;
|
|
297
|
+
//# sourceMappingURL=PersonalizationStateful.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersonalizationStateful.js","sourceRoot":"","sources":["../../src/personalization/PersonalizationStateful.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type ComponentViewBuilderArgs, type IdentifyBuilderArgs, type OptimizationData, type PageViewBuilderArgs, type PartialProfile, type ScreenViewBuilderArgs, type TrackBuilderArgs } from '@contentful/optimization-api-client';
|
|
2
|
+
import PersonalizationBase from './PersonalizationBase';
|
|
3
|
+
/**
|
|
4
|
+
* Stateless personalization implementation that immediately validates and sends
|
|
5
|
+
* a single event to the Experience API, upserting the profile as needed.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
* @remarks
|
|
9
|
+
* Each public method constructs a strongly-typed event via the shared builder,
|
|
10
|
+
* runs it through event interceptors, and performs a profile upsert using the
|
|
11
|
+
* Experience API. If an anonymous ID is available from the builder, it will be
|
|
12
|
+
* preferred as the `profileId` unless an explicit profile is provided.
|
|
13
|
+
*/
|
|
14
|
+
declare class PersonalizationStateless extends PersonalizationBase {
|
|
15
|
+
/**
|
|
16
|
+
* Identify the current profile/visitor to associate traits with a profile.
|
|
17
|
+
*
|
|
18
|
+
* @param payload - Identify builder arguments with an optional partial
|
|
19
|
+
* profile to attach to the upsert request.
|
|
20
|
+
* @returns The resulting {@link OptimizationData} for the identified user.
|
|
21
|
+
*/
|
|
22
|
+
identify(payload: IdentifyBuilderArgs & {
|
|
23
|
+
profile?: PartialProfile;
|
|
24
|
+
}): Promise<OptimizationData>;
|
|
25
|
+
/**
|
|
26
|
+
* Record a page view.
|
|
27
|
+
*
|
|
28
|
+
* @param payload - Page view builder arguments with an optional partial profile.
|
|
29
|
+
* @returns The evaluated {@link OptimizationData} for this page view.
|
|
30
|
+
*/
|
|
31
|
+
page(payload: PageViewBuilderArgs & {
|
|
32
|
+
profile?: PartialProfile;
|
|
33
|
+
}): Promise<OptimizationData>;
|
|
34
|
+
/**
|
|
35
|
+
* Record a screen view.
|
|
36
|
+
*
|
|
37
|
+
* @param payload - Screen view builder arguments with an optional partial profile.
|
|
38
|
+
* @returns The evaluated {@link OptimizationData} for this screen view.
|
|
39
|
+
*/
|
|
40
|
+
screen(payload: ScreenViewBuilderArgs & {
|
|
41
|
+
profile?: PartialProfile;
|
|
42
|
+
}): Promise<OptimizationData>;
|
|
43
|
+
/**
|
|
44
|
+
* Record a custom track event.
|
|
45
|
+
*
|
|
46
|
+
* @param payload - Track builder arguments with an optional partial profile.
|
|
47
|
+
* @returns The evaluated {@link OptimizationData} for this event.
|
|
48
|
+
*/
|
|
49
|
+
track(payload: TrackBuilderArgs & {
|
|
50
|
+
profile?: PartialProfile;
|
|
51
|
+
}): Promise<OptimizationData>;
|
|
52
|
+
/**
|
|
53
|
+
* Record a "sticky" component view.
|
|
54
|
+
*
|
|
55
|
+
* @param payload - Component view builder arguments with an optional partial profile.
|
|
56
|
+
* @returns The evaluated {@link OptimizationData} for this component view.
|
|
57
|
+
*/
|
|
58
|
+
trackComponentView(payload: ComponentViewBuilderArgs & {
|
|
59
|
+
profile?: PartialProfile;
|
|
60
|
+
}): Promise<OptimizationData>;
|
|
61
|
+
/**
|
|
62
|
+
* Intercept, validate, and upsert the profile with a single personalization
|
|
63
|
+
* event.
|
|
64
|
+
*
|
|
65
|
+
* @param event - The {@link PersonalizationEvent} to submit.
|
|
66
|
+
* @param profile - Optional partial profile. If omitted, the anonymous ID from
|
|
67
|
+
* the builder (when present) is used as the `profileId`.
|
|
68
|
+
* @returns The {@link OptimizationData} returned by the Experience API.
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
private upsertProfile;
|
|
72
|
+
}
|
|
73
|
+
export default PersonalizationStateless;
|
|
74
|
+
//# sourceMappingURL=PersonalizationStateless.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersonalizationStateless.d.ts","sourceRoot":"","sources":["../../src/personalization/PersonalizationStateless.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAE7B,KAAK,mBAAmB,EAExB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EAExB,KAAK,cAAc,EAEnB,KAAK,qBAAqB,EAE1B,KAAK,gBAAgB,EAEtB,MAAM,qCAAqC,CAAA;AAE5C,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AAIvD;;;;;;;;;;GAUG;AACH,cAAM,wBAAyB,SAAQ,mBAAmB;IACxD;;;;;;OAMG;IACG,QAAQ,CACZ,OAAO,EAAE,mBAAmB,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,GAC1D,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;;;;OAKG;IACG,IAAI,CACR,OAAO,EAAE,mBAAmB,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,GAC1D,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;;;;OAKG;IACG,MAAM,CACV,OAAO,EAAE,qBAAqB,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,GAC5D,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;;;;OAKG;IACG,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAUhG;;;;;OAKG;IACG,kBAAkB,CACtB,OAAO,EAAE,wBAAwB,GAAG;QAAE,OAAO,CAAC,EAAE,cAAc,CAAA;KAAE,GAC/D,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;;;;;;;;OASG;YACW,aAAa;CAa5B;AAED,eAAe,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { ComponentViewEvent, IdentifyEvent, PageViewEvent, ScreenViewEvent, TrackEvent, } from '@contentful/optimization-api-client';
|
|
2
|
+
import { createScopedLogger } from 'logger';
|
|
3
|
+
import PersonalizationBase from './PersonalizationBase';
|
|
4
|
+
const logger = createScopedLogger('Personalization');
|
|
5
|
+
/**
|
|
6
|
+
* Stateless personalization implementation that immediately validates and sends
|
|
7
|
+
* a single event to the Experience API, upserting the profile as needed.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
* @remarks
|
|
11
|
+
* Each public method constructs a strongly-typed event via the shared builder,
|
|
12
|
+
* runs it through event interceptors, and performs a profile upsert using the
|
|
13
|
+
* Experience API. If an anonymous ID is available from the builder, it will be
|
|
14
|
+
* preferred as the `profileId` unless an explicit profile is provided.
|
|
15
|
+
*/
|
|
16
|
+
class PersonalizationStateless extends PersonalizationBase {
|
|
17
|
+
/**
|
|
18
|
+
* Identify the current profile/visitor to associate traits with a profile.
|
|
19
|
+
*
|
|
20
|
+
* @param payload - Identify builder arguments with an optional partial
|
|
21
|
+
* profile to attach to the upsert request.
|
|
22
|
+
* @returns The resulting {@link OptimizationData} for the identified user.
|
|
23
|
+
*/
|
|
24
|
+
async identify(payload) {
|
|
25
|
+
logger.info('Sending "identify" event');
|
|
26
|
+
const { profile, ...builderArgs } = payload;
|
|
27
|
+
const event = IdentifyEvent.parse(this.builder.buildIdentify(builderArgs));
|
|
28
|
+
return await this.upsertProfile(event, profile);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Record a page view.
|
|
32
|
+
*
|
|
33
|
+
* @param payload - Page view builder arguments with an optional partial profile.
|
|
34
|
+
* @returns The evaluated {@link OptimizationData} for this page view.
|
|
35
|
+
*/
|
|
36
|
+
async page(payload) {
|
|
37
|
+
logger.info('Sending "page" event');
|
|
38
|
+
const { profile, ...builderArgs } = payload;
|
|
39
|
+
const event = PageViewEvent.parse(this.builder.buildPageView(builderArgs));
|
|
40
|
+
return await this.upsertProfile(event, profile);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Record a screen view.
|
|
44
|
+
*
|
|
45
|
+
* @param payload - Screen view builder arguments with an optional partial profile.
|
|
46
|
+
* @returns The evaluated {@link OptimizationData} for this screen view.
|
|
47
|
+
*/
|
|
48
|
+
async screen(payload) {
|
|
49
|
+
logger.info(`Sending "screen" event for "${payload.name}"`);
|
|
50
|
+
const { profile, ...builderArgs } = payload;
|
|
51
|
+
const event = ScreenViewEvent.parse(this.builder.buildScreenView(builderArgs));
|
|
52
|
+
return await this.upsertProfile(event, profile);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Record a custom track event.
|
|
56
|
+
*
|
|
57
|
+
* @param payload - Track builder arguments with an optional partial profile.
|
|
58
|
+
* @returns The evaluated {@link OptimizationData} for this event.
|
|
59
|
+
*/
|
|
60
|
+
async track(payload) {
|
|
61
|
+
logger.info(`Sending "track" event "${payload.event}"`);
|
|
62
|
+
const { profile, ...builderArgs } = payload;
|
|
63
|
+
const event = TrackEvent.parse(this.builder.buildTrack(builderArgs));
|
|
64
|
+
return await this.upsertProfile(event, profile);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Record a "sticky" component view.
|
|
68
|
+
*
|
|
69
|
+
* @param payload - Component view builder arguments with an optional partial profile.
|
|
70
|
+
* @returns The evaluated {@link OptimizationData} for this component view.
|
|
71
|
+
*/
|
|
72
|
+
async trackComponentView(payload) {
|
|
73
|
+
logger.info('Sending "track personalization" event');
|
|
74
|
+
const { profile, ...builderArgs } = payload;
|
|
75
|
+
const event = ComponentViewEvent.parse(this.builder.buildComponentView(builderArgs));
|
|
76
|
+
return await this.upsertProfile(event, profile);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Intercept, validate, and upsert the profile with a single personalization
|
|
80
|
+
* event.
|
|
81
|
+
*
|
|
82
|
+
* @param event - The {@link PersonalizationEvent} to submit.
|
|
83
|
+
* @param profile - Optional partial profile. If omitted, the anonymous ID from
|
|
84
|
+
* the builder (when present) is used as the `profileId`.
|
|
85
|
+
* @returns The {@link OptimizationData} returned by the Experience API.
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
async upsertProfile(event, profile) {
|
|
89
|
+
const intercepted = await this.interceptors.event.run(event);
|
|
90
|
+
const data = await this.api.experience.upsertProfile({
|
|
91
|
+
profileId: profile?.id,
|
|
92
|
+
events: [intercepted],
|
|
93
|
+
});
|
|
94
|
+
return data;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export default PersonalizationStateless;
|
|
98
|
+
//# sourceMappingURL=PersonalizationStateless.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersonalizationStateless.js","sourceRoot":"","sources":["../../src/personalization/PersonalizationStateless.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './resolvers';
|
|
2
|
+
export * from './PersonalizationStateful';
|
|
3
|
+
export { default as PersonalizationStateful } from './PersonalizationStateful';
|
|
4
|
+
export * from './PersonalizationStateless';
|
|
5
|
+
export { default as PersonalizationStateless } from './PersonalizationStateless';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/personalization/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAE3B,cAAc,2BAA2B,CAAA;AACzC,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAE9E,cAAc,4BAA4B,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,4BAA4B,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './resolvers';
|
|
2
|
+
export * from './PersonalizationStateful';
|
|
3
|
+
export { default as PersonalizationStateful } from './PersonalizationStateful';
|
|
4
|
+
export * from './PersonalizationStateless';
|
|
5
|
+
export { default as PersonalizationStateless } from './PersonalizationStateless';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/personalization/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAE3B,cAAc,2BAA2B,CAAA;AACzC,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,2BAA2B,CAAA;AAE9E,cAAc,4BAA4B,CAAA;AAC1C,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,4BAA4B,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ChangeArray, Flags } from '@contentful/optimization-api-client';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a {@link Flags} map from a list of optimization changes.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
* @remarks
|
|
7
|
+
* Given an Optimization {@link ChangeArray}, this utility flattens the list into a
|
|
8
|
+
* simple key–value object suitable for quick lookups in client code. When `changes`
|
|
9
|
+
* is `undefined`, an empty object is returned. If a change value is wrapped in an
|
|
10
|
+
* object like `{ value: { ... } }`, this resolver unwraps it to the underlying object.
|
|
11
|
+
*/
|
|
12
|
+
declare const FlagsResolver: {
|
|
13
|
+
/**
|
|
14
|
+
* Build a flattened map of flag keys to values from a change list.
|
|
15
|
+
*
|
|
16
|
+
* @param changes - The change list returned by the optimization service.
|
|
17
|
+
* @returns A map of flag keys to their resolved values.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const flags = FlagsResolver.resolve(data.changes)
|
|
21
|
+
* if (flags['theme'] === 'dark') enableDarkMode()
|
|
22
|
+
* ```
|
|
23
|
+
* @example
|
|
24
|
+
* // Handles wrapped values produced by the API
|
|
25
|
+
* ```ts
|
|
26
|
+
* const flags = FlagsResolver.resolve([
|
|
27
|
+
* { type: 'Variable', key: 'price', value: { value: { amount: 10, currency: 'USD' } } }
|
|
28
|
+
* ])
|
|
29
|
+
* console.log(flags.price.amount) // 10
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
resolve(changes?: ChangeArray): Flags;
|
|
33
|
+
};
|
|
34
|
+
export default FlagsResolver;
|
|
35
|
+
//# sourceMappingURL=FlagsResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlagsResolver.d.ts","sourceRoot":"","sources":["../../../src/personalization/resolvers/FlagsResolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAA;AAE7E;;;;;;;;;GASG;AACH,QAAA,MAAM,aAAa;IACjB;;;;;;;;;;;;;;;;;;OAkBG;sBACe,WAAW,GAAG,KAAK;CAiBtC,CAAA;AAED,eAAe,aAAa,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a {@link Flags} map from a list of optimization changes.
|
|
3
|
+
*
|
|
4
|
+
* @public
|
|
5
|
+
* @remarks
|
|
6
|
+
* Given an Optimization {@link ChangeArray}, this utility flattens the list into a
|
|
7
|
+
* simple key–value object suitable for quick lookups in client code. When `changes`
|
|
8
|
+
* is `undefined`, an empty object is returned. If a change value is wrapped in an
|
|
9
|
+
* object like `{ value: { ... } }`, this resolver unwraps it to the underlying object.
|
|
10
|
+
*/
|
|
11
|
+
const FlagsResolver = {
|
|
12
|
+
/**
|
|
13
|
+
* Build a flattened map of flag keys to values from a change list.
|
|
14
|
+
*
|
|
15
|
+
* @param changes - The change list returned by the optimization service.
|
|
16
|
+
* @returns A map of flag keys to their resolved values.
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* const flags = FlagsResolver.resolve(data.changes)
|
|
20
|
+
* if (flags['theme'] === 'dark') enableDarkMode()
|
|
21
|
+
* ```
|
|
22
|
+
* @example
|
|
23
|
+
* // Handles wrapped values produced by the API
|
|
24
|
+
* ```ts
|
|
25
|
+
* const flags = FlagsResolver.resolve([
|
|
26
|
+
* { type: 'Variable', key: 'price', value: { value: { amount: 10, currency: 'USD' } } }
|
|
27
|
+
* ])
|
|
28
|
+
* console.log(flags.price.amount) // 10
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
resolve(changes) {
|
|
32
|
+
if (!changes)
|
|
33
|
+
return {};
|
|
34
|
+
return changes.reduce((acc, { key, value }) => {
|
|
35
|
+
const actualValue = typeof value === 'object' &&
|
|
36
|
+
value !== null &&
|
|
37
|
+
'value' in value &&
|
|
38
|
+
typeof value.value === 'object'
|
|
39
|
+
? value.value
|
|
40
|
+
: value;
|
|
41
|
+
acc[key] = actualValue;
|
|
42
|
+
return acc;
|
|
43
|
+
}, {});
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export default FlagsResolver;
|
|
47
|
+
//# sourceMappingURL=FlagsResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlagsResolver.js","sourceRoot":"","sources":["../../../src/personalization/resolvers/FlagsResolver.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,aAAa,GAAG;IACpB;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,OAAqB;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAA;QAEvB,OAAO,OAAO,CAAC,MAAM,CAAQ,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;YACnD,MAAM,WAAW,GACf,OAAO,KAAK,KAAK,QAAQ;gBACzB,KAAK,KAAK,IAAI;gBACd,OAAO,IAAI,KAAK;gBAChB,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;gBAC7B,CAAC,CAAC,KAAK,CAAC,KAAK;gBACb,CAAC,CAAC,KAAK,CAAA;YAEX,GAAG,CAAC,GAAG,CAAC,GAAG,WAAW,CAAA;YAEtB,OAAO,GAAG,CAAA;QACZ,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC;CACF,CAAA;AAED,eAAe,aAAa,CAAA"}
|