@ninetailed/experience.js 7.5.3-beta.1 → 7.5.3-beta.2
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/index.cjs.d.ts +1 -0
- package/{index.js → index.esm.js} +117 -122
- package/package.json +5 -8
- /package/{index.cjs → index.cjs.js} +0 -0
package/index.cjs.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./src/index";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FEATURES, logger, ConsoleLogSink, buildPageEvent, buildTrackEvent, buildIdentifyEvent, unionBy,
|
|
1
|
+
import { FEATURES, logger, ConsoleLogSink, buildPageEvent, buildTrackEvent, buildIdentifyEvent, unionBy, PageviewProperties, Properties, Traits, NinetailedApiClient, OnLogLogSink, OnErrorLogSink, pipe } from '@ninetailed/experience.js-shared';
|
|
2
2
|
export { EXPERIENCE_TRAIT_PREFIX, isExperienceMatch, selectActiveExperiments, selectDistribution, selectExperience, selectBaselineWithVariants as selectExperienceBaselineWithVariants, selectVariant as selectExperienceVariant, selectVariants as selectExperienceVariants, selectHasVariants as selectHasExperienceVariants } from '@ninetailed/experience.js-shared';
|
|
3
3
|
import Analytics from 'analytics';
|
|
4
4
|
import { z } from 'zod';
|
|
@@ -9,43 +9,6 @@ const COMPONENT = 'component';
|
|
|
9
9
|
const COMPONENT_START = 'componentStart';
|
|
10
10
|
const PAGE_HIDDEN = 'page_hidden';
|
|
11
11
|
|
|
12
|
-
/******************************************************************************
|
|
13
|
-
Copyright (c) Microsoft Corporation.
|
|
14
|
-
|
|
15
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
16
|
-
purpose with or without fee is hereby granted.
|
|
17
|
-
|
|
18
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
19
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
20
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
21
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
22
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
23
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
24
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
25
|
-
***************************************************************************** */
|
|
26
|
-
|
|
27
|
-
function __rest(s, e) {
|
|
28
|
-
var t = {};
|
|
29
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
30
|
-
t[p] = s[p];
|
|
31
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
32
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
33
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
34
|
-
t[p[i]] = s[p[i]];
|
|
35
|
-
}
|
|
36
|
-
return t;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
40
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
41
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
42
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
43
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
44
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
45
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
12
|
const buildClientLocale = () => navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language;
|
|
50
13
|
|
|
51
14
|
const buildClientNinetailedRequestContext = () => ({
|
|
@@ -58,15 +21,15 @@ const buildClientNinetailedRequestContext = () => ({
|
|
|
58
21
|
}
|
|
59
22
|
});
|
|
60
23
|
|
|
61
|
-
/**
|
|
62
|
-
* Similar to _.throttle but waits for the promise to resolve.
|
|
63
|
-
* There is no "wait time" because you can simply await `Promise.timeout` inside `fn` to wait some time before the next call.
|
|
24
|
+
/**
|
|
25
|
+
* Similar to _.throttle but waits for the promise to resolve.
|
|
26
|
+
* There is no "wait time" because you can simply await `Promise.timeout` inside `fn` to wait some time before the next call.
|
|
64
27
|
*/
|
|
65
28
|
function asyncThrottle(fn) {
|
|
66
29
|
let runningPromise;
|
|
67
30
|
let queuedPromise;
|
|
68
31
|
let nextArgs;
|
|
69
|
-
return args =>
|
|
32
|
+
return async args => {
|
|
70
33
|
if (runningPromise) {
|
|
71
34
|
nextArgs = args;
|
|
72
35
|
if (queuedPromise) {
|
|
@@ -83,7 +46,7 @@ function asyncThrottle(fn) {
|
|
|
83
46
|
runningPromise = fn(args);
|
|
84
47
|
return runningPromise;
|
|
85
48
|
}
|
|
86
|
-
}
|
|
49
|
+
};
|
|
87
50
|
}
|
|
88
51
|
|
|
89
52
|
const LEGACY_ANONYMOUS_ID = '__anon_id';
|
|
@@ -110,7 +73,7 @@ const ninetailedCorePlugin = ({
|
|
|
110
73
|
let queue = [];
|
|
111
74
|
let enabledFeatures = Object.values(FEATURES);
|
|
112
75
|
const buildContext = buildClientContext || buildClientNinetailedRequestContext;
|
|
113
|
-
const flush = () =>
|
|
76
|
+
const flush = async () => {
|
|
114
77
|
const events = Object.assign([], queue);
|
|
115
78
|
logger.info('Start flushing events.');
|
|
116
79
|
queue = [];
|
|
@@ -124,7 +87,7 @@ const ninetailedCorePlugin = ({
|
|
|
124
87
|
const {
|
|
125
88
|
profile,
|
|
126
89
|
experiences
|
|
127
|
-
} =
|
|
90
|
+
} = await apiClient.upsertProfile({
|
|
128
91
|
profileId: anonymousId,
|
|
129
92
|
events
|
|
130
93
|
}, {
|
|
@@ -141,7 +104,7 @@ const ninetailedCorePlugin = ({
|
|
|
141
104
|
profile,
|
|
142
105
|
experiences
|
|
143
106
|
});
|
|
144
|
-
|
|
107
|
+
await delay(20);
|
|
145
108
|
return {
|
|
146
109
|
success: true
|
|
147
110
|
};
|
|
@@ -169,10 +132,10 @@ const ninetailedCorePlugin = ({
|
|
|
169
132
|
success: false
|
|
170
133
|
};
|
|
171
134
|
}
|
|
172
|
-
}
|
|
173
|
-
const enqueueEvent = event =>
|
|
135
|
+
};
|
|
136
|
+
const enqueueEvent = async event => {
|
|
174
137
|
queue = unionBy([event], queue, 'messageId');
|
|
175
|
-
}
|
|
138
|
+
};
|
|
176
139
|
const abortNonClientEvents = ({
|
|
177
140
|
abort,
|
|
178
141
|
payload
|
|
@@ -185,14 +148,15 @@ const ninetailedCorePlugin = ({
|
|
|
185
148
|
return {
|
|
186
149
|
name: 'ninetailed',
|
|
187
150
|
config: {},
|
|
188
|
-
initialize: ({
|
|
151
|
+
initialize: async ({
|
|
189
152
|
instance
|
|
190
|
-
}) =>
|
|
153
|
+
}) => {
|
|
191
154
|
_instance = instance;
|
|
192
155
|
if (instance.storage.getItem(DEBUG_FLAG)) {
|
|
193
156
|
logger.addSink(new ConsoleLogSink());
|
|
194
157
|
logger.info('Ninetailed Debug Mode is enabled.');
|
|
195
158
|
}
|
|
159
|
+
|
|
196
160
|
// legacy support for the old anonymousId
|
|
197
161
|
const legacyAnonymousId = instance.storage.getItem(LEGACY_ANONYMOUS_ID);
|
|
198
162
|
if (legacyAnonymousId) {
|
|
@@ -201,7 +165,7 @@ const ninetailedCorePlugin = ({
|
|
|
201
165
|
instance.storage.removeItem(LEGACY_ANONYMOUS_ID);
|
|
202
166
|
}
|
|
203
167
|
if (typeof onInitProfileId === 'function') {
|
|
204
|
-
const profileId =
|
|
168
|
+
const profileId = await onInitProfileId(instance.storage.getItem(ANONYMOUS_ID));
|
|
205
169
|
if (typeof profileId === 'string') {
|
|
206
170
|
instance.storage.setItem(ANONYMOUS_ID, profileId);
|
|
207
171
|
}
|
|
@@ -212,14 +176,14 @@ const ninetailedCorePlugin = ({
|
|
|
212
176
|
enabledFeatures = payload.features || [];
|
|
213
177
|
});
|
|
214
178
|
logger.debug('Ninetailed Core plugin initialized.');
|
|
215
|
-
}
|
|
179
|
+
},
|
|
216
180
|
flush: asyncThrottle(flush),
|
|
217
181
|
pageStart: params => {
|
|
218
182
|
return abortNonClientEvents(params);
|
|
219
183
|
},
|
|
220
|
-
page: ({
|
|
184
|
+
page: async ({
|
|
221
185
|
payload
|
|
222
|
-
}) =>
|
|
186
|
+
}) => {
|
|
223
187
|
logger.info('Sending Page event.');
|
|
224
188
|
const ctx = buildContext();
|
|
225
189
|
return enqueueEvent(buildPageEvent({
|
|
@@ -228,13 +192,13 @@ const ninetailedCorePlugin = ({
|
|
|
228
192
|
properties: payload.properties,
|
|
229
193
|
ctx
|
|
230
194
|
}));
|
|
231
|
-
}
|
|
195
|
+
},
|
|
232
196
|
trackStart: params => {
|
|
233
197
|
return abortNonClientEvents(params);
|
|
234
198
|
},
|
|
235
|
-
track: ({
|
|
199
|
+
track: async ({
|
|
236
200
|
payload
|
|
237
|
-
}) =>
|
|
201
|
+
}) => {
|
|
238
202
|
logger.info('Sending Track event.');
|
|
239
203
|
const ctx = buildContext();
|
|
240
204
|
return enqueueEvent(buildTrackEvent({
|
|
@@ -244,13 +208,13 @@ const ninetailedCorePlugin = ({
|
|
|
244
208
|
properties: payload.properties,
|
|
245
209
|
ctx
|
|
246
210
|
}));
|
|
247
|
-
}
|
|
211
|
+
},
|
|
248
212
|
identifyStart: params => {
|
|
249
213
|
return abortNonClientEvents(params);
|
|
250
214
|
},
|
|
251
|
-
identify: ({
|
|
215
|
+
identify: async ({
|
|
252
216
|
payload
|
|
253
|
-
}) =>
|
|
217
|
+
}) => {
|
|
254
218
|
logger.info('Sending Identify event.');
|
|
255
219
|
const ctx = buildContext();
|
|
256
220
|
if (payload.userId === EMPTY_MERGE_ID && (!payload.traits || typeof payload.traits === 'object' && Object.keys(payload.traits).length === 0)) {
|
|
@@ -264,7 +228,7 @@ const ninetailedCorePlugin = ({
|
|
|
264
228
|
userId: payload.userId === EMPTY_MERGE_ID ? '' : payload.userId,
|
|
265
229
|
ctx
|
|
266
230
|
}));
|
|
267
|
-
}
|
|
231
|
+
},
|
|
268
232
|
setItemStart: ({
|
|
269
233
|
abort,
|
|
270
234
|
payload
|
|
@@ -275,7 +239,7 @@ const ninetailedCorePlugin = ({
|
|
|
275
239
|
return payload;
|
|
276
240
|
},
|
|
277
241
|
methods: {
|
|
278
|
-
reset: (...args) =>
|
|
242
|
+
reset: async (...args) => {
|
|
279
243
|
logger.debug('Resetting profile.');
|
|
280
244
|
const instance = args[args.length - 1];
|
|
281
245
|
instance.dispatch({
|
|
@@ -286,16 +250,16 @@ const ninetailedCorePlugin = ({
|
|
|
286
250
|
instance.storage.removeItem(EXPERIENCES_FALLBACK_CACHE);
|
|
287
251
|
logger.debug('Removed old profile data from localstorage.');
|
|
288
252
|
if (typeof onInitProfileId === 'function') {
|
|
289
|
-
const profileId =
|
|
253
|
+
const profileId = await onInitProfileId(undefined);
|
|
290
254
|
if (typeof profileId === 'string') {
|
|
291
255
|
instance.storage.setItem(ANONYMOUS_ID, profileId);
|
|
292
256
|
}
|
|
293
257
|
}
|
|
294
|
-
|
|
258
|
+
await ninetailed.track('nt_reset');
|
|
295
259
|
logger.info('Profile reset successful.');
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
debug: (...args) =>
|
|
260
|
+
await delay(10);
|
|
261
|
+
},
|
|
262
|
+
debug: async (...args) => {
|
|
299
263
|
const enabled = args[0];
|
|
300
264
|
const instance = args[args.length - 1];
|
|
301
265
|
const consoleLogSink = new ConsoleLogSink();
|
|
@@ -308,13 +272,29 @@ const ninetailedCorePlugin = ({
|
|
|
308
272
|
logger.info('Debug mode disabled.');
|
|
309
273
|
logger.removeSink(consoleLogSink.name);
|
|
310
274
|
}
|
|
311
|
-
}
|
|
275
|
+
}
|
|
312
276
|
}
|
|
313
277
|
};
|
|
314
278
|
};
|
|
315
279
|
|
|
280
|
+
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
281
|
+
if (source == null) return {};
|
|
282
|
+
var target = {};
|
|
283
|
+
var sourceKeys = Object.keys(source);
|
|
284
|
+
var key, i;
|
|
285
|
+
for (i = 0; i < sourceKeys.length; i++) {
|
|
286
|
+
key = sourceKeys[i];
|
|
287
|
+
if (excluded.indexOf(key) >= 0) continue;
|
|
288
|
+
target[key] = source[key];
|
|
289
|
+
}
|
|
290
|
+
return target;
|
|
291
|
+
}
|
|
292
|
+
|
|
316
293
|
class ElementSeenObserver {
|
|
317
294
|
constructor(_options) {
|
|
295
|
+
this._intersectionObserver = void 0;
|
|
296
|
+
this._elementDelays = void 0;
|
|
297
|
+
this._intersectionTimers = void 0;
|
|
318
298
|
this._options = _options;
|
|
319
299
|
this._elementDelays = new WeakMap();
|
|
320
300
|
this._intersectionTimers = new WeakMap();
|
|
@@ -343,13 +323,13 @@ class ElementSeenObserver {
|
|
|
343
323
|
});
|
|
344
324
|
}
|
|
345
325
|
observe(element, options) {
|
|
346
|
-
var
|
|
347
|
-
this._elementDelays.set(element, (
|
|
348
|
-
(
|
|
326
|
+
var _options$delay, _this$_intersectionOb;
|
|
327
|
+
this._elementDelays.set(element, (_options$delay = options == null ? void 0 : options.delay) != null ? _options$delay : 2000);
|
|
328
|
+
(_this$_intersectionOb = this._intersectionObserver) == null || _this$_intersectionOb.observe(element);
|
|
349
329
|
}
|
|
350
330
|
unobserve(element) {
|
|
351
|
-
var
|
|
352
|
-
(
|
|
331
|
+
var _this$_intersectionOb2;
|
|
332
|
+
(_this$_intersectionOb2 = this._intersectionObserver) == null || _this$_intersectionOb2.unobserve(element);
|
|
353
333
|
}
|
|
354
334
|
}
|
|
355
335
|
|
|
@@ -361,6 +341,7 @@ const isInterestedInHiddenPage = arg => {
|
|
|
361
341
|
return typeof arg === 'object' && arg !== null && PAGE_HIDDEN in arg && typeof arg[PAGE_HIDDEN] === 'function';
|
|
362
342
|
};
|
|
363
343
|
|
|
344
|
+
const _excluded = ["element"];
|
|
364
345
|
class Ninetailed {
|
|
365
346
|
constructor(ninetailedApiClientInstanceOrOptions, {
|
|
366
347
|
plugins,
|
|
@@ -374,16 +355,28 @@ class Ninetailed {
|
|
|
374
355
|
componentViewTrackingThreshold = 2000,
|
|
375
356
|
storageImpl
|
|
376
357
|
} = {}) {
|
|
358
|
+
var _this = this;
|
|
359
|
+
this.instance = void 0;
|
|
360
|
+
this._profileState = void 0;
|
|
377
361
|
this.isInitialized = false;
|
|
378
|
-
this.
|
|
362
|
+
this.apiClient = void 0;
|
|
363
|
+
this.ninetailedCorePlugin = void 0;
|
|
364
|
+
this.elementSeenObserver = void 0;
|
|
365
|
+
this.observedElements = void 0;
|
|
366
|
+
this.clientId = void 0;
|
|
367
|
+
this.environment = void 0;
|
|
368
|
+
this.plugins = void 0;
|
|
369
|
+
this.logger = void 0;
|
|
370
|
+
this.componentViewTrackingThreshold = void 0;
|
|
371
|
+
this.page = async function (data, options) {
|
|
379
372
|
try {
|
|
380
373
|
const result = PageviewProperties.partial().default({}).safeParse(data);
|
|
381
374
|
if (!result.success) {
|
|
382
375
|
throw new Error(`[Validation Error] "page" was called with invalid params. Page data is not valid: ${result.error.format()}`);
|
|
383
376
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return
|
|
377
|
+
await _this.waitUntilInitialized();
|
|
378
|
+
await _this.instance.page(data, _this.buildOptions(options));
|
|
379
|
+
return _this.ninetailedCorePlugin.flush();
|
|
387
380
|
} catch (error) {
|
|
388
381
|
logger.error(error);
|
|
389
382
|
if (error instanceof RangeError) {
|
|
@@ -391,16 +384,16 @@ class Ninetailed {
|
|
|
391
384
|
}
|
|
392
385
|
throw error;
|
|
393
386
|
}
|
|
394
|
-
}
|
|
395
|
-
this.track = (event, properties, options)
|
|
387
|
+
};
|
|
388
|
+
this.track = async function (event, properties, options) {
|
|
396
389
|
try {
|
|
397
390
|
const result = Properties.default({}).safeParse(properties);
|
|
398
391
|
if (!result.success) {
|
|
399
392
|
throw new Error(`[Validation Error] "track" was called with invalid params. Properties are no valid json object: ${result.error.format()}`);
|
|
400
393
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
return
|
|
394
|
+
await _this.waitUntilInitialized();
|
|
395
|
+
await _this.instance.track(event.toString(), result.data, _this.buildOptions(options));
|
|
396
|
+
return _this.ninetailedCorePlugin.flush();
|
|
404
397
|
} catch (error) {
|
|
405
398
|
logger.error(error);
|
|
406
399
|
if (error instanceof RangeError) {
|
|
@@ -408,18 +401,18 @@ class Ninetailed {
|
|
|
408
401
|
}
|
|
409
402
|
throw error;
|
|
410
403
|
}
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* @deprecated The legacy datamodel is not recommended anymore
|
|
414
|
-
* Will be removed in the next version of the SDK
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* @deprecated The legacy datamodel is not recommended anymore
|
|
407
|
+
* Will be removed in the next version of the SDK
|
|
415
408
|
*/
|
|
416
|
-
this.trackHasSeenComponent =
|
|
417
|
-
return
|
|
409
|
+
this.trackHasSeenComponent = async function (properties) {
|
|
410
|
+
return _this.instance.dispatch(Object.assign({}, properties, {
|
|
418
411
|
type: HAS_SEEN_COMPONENT
|
|
419
412
|
}));
|
|
420
|
-
}
|
|
413
|
+
};
|
|
421
414
|
this.trackComponentView = properties => {
|
|
422
|
-
return this.instance.dispatch(Object.assign(
|
|
415
|
+
return this.instance.dispatch(Object.assign({}, properties, {
|
|
423
416
|
type: HAS_SEEN_ELEMENT
|
|
424
417
|
}));
|
|
425
418
|
};
|
|
@@ -427,7 +420,7 @@ class Ninetailed {
|
|
|
427
420
|
const {
|
|
428
421
|
element
|
|
429
422
|
} = payload,
|
|
430
|
-
remaingPayload =
|
|
423
|
+
remaingPayload = _objectWithoutPropertiesLoose(payload, _excluded);
|
|
431
424
|
if (!(element instanceof Element)) {
|
|
432
425
|
const isObject = typeof element === 'object' && element !== null;
|
|
433
426
|
const constructorName = isObject ? element.constructor.name : '';
|
|
@@ -452,15 +445,15 @@ class Ninetailed {
|
|
|
452
445
|
}, payload));
|
|
453
446
|
}
|
|
454
447
|
};
|
|
455
|
-
this.identify = (uid, traits, options)
|
|
448
|
+
this.identify = async function (uid, traits, options) {
|
|
456
449
|
try {
|
|
457
450
|
const result = Traits.default({}).safeParse(traits);
|
|
458
451
|
if (!result.success) {
|
|
459
452
|
throw new Error(`[Validation Error] "identify" was called with invalid params. Traits are no valid json: ${result.error.format()}`);
|
|
460
453
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
return
|
|
454
|
+
await _this.waitUntilInitialized();
|
|
455
|
+
await _this.instance.identify(uid && uid.toString() !== '' ? uid.toString() : EMPTY_MERGE_ID, result.data, _this.buildOptions(options));
|
|
456
|
+
return _this.ninetailedCorePlugin.flush();
|
|
464
457
|
} catch (error) {
|
|
465
458
|
logger.error(error);
|
|
466
459
|
if (error instanceof RangeError) {
|
|
@@ -468,33 +461,33 @@ class Ninetailed {
|
|
|
468
461
|
}
|
|
469
462
|
throw error;
|
|
470
463
|
}
|
|
471
|
-
}
|
|
472
|
-
this.reset =
|
|
473
|
-
|
|
464
|
+
};
|
|
465
|
+
this.reset = async function () {
|
|
466
|
+
await _this.waitUntilInitialized();
|
|
474
467
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
475
468
|
// @ts-ignore
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
this.debug =
|
|
479
|
-
|
|
469
|
+
_this.instance.plugins[PLUGIN_NAME].reset();
|
|
470
|
+
};
|
|
471
|
+
this.debug = async function (enabled) {
|
|
472
|
+
await _this.waitUntilInitialized();
|
|
480
473
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
481
474
|
// @ts-ignore
|
|
482
|
-
|
|
483
|
-
}
|
|
475
|
+
_this.instance.plugins[PLUGIN_NAME].debug(enabled);
|
|
476
|
+
};
|
|
484
477
|
this.onProfileChange = cb => {
|
|
485
478
|
cb(this.profileState);
|
|
486
479
|
return this.instance.on(PROFILE_CHANGE, ({
|
|
487
480
|
payload
|
|
488
481
|
}) => {
|
|
489
482
|
if (payload.error) {
|
|
490
|
-
cb(Object.assign(
|
|
483
|
+
cb(Object.assign({}, this._profileState, {
|
|
491
484
|
status: 'error',
|
|
492
485
|
profile: payload.profile,
|
|
493
486
|
experiences: payload.experiences,
|
|
494
487
|
error: payload.error
|
|
495
488
|
}));
|
|
496
489
|
} else {
|
|
497
|
-
cb(Object.assign(
|
|
490
|
+
cb(Object.assign({}, this._profileState, {
|
|
498
491
|
status: 'success',
|
|
499
492
|
profile: payload.profile,
|
|
500
493
|
experiences: payload.experiences,
|
|
@@ -550,7 +543,7 @@ class Ninetailed {
|
|
|
550
543
|
preview
|
|
551
544
|
});
|
|
552
545
|
}
|
|
553
|
-
this.plugins = (plugins
|
|
546
|
+
this.plugins = (plugins != null ? plugins : []).flat();
|
|
554
547
|
this.plugins.forEach(plugin => {
|
|
555
548
|
if (acceptsCredentials(plugin) && this.clientId && this.environment) {
|
|
556
549
|
plugin.setCredentials({
|
|
@@ -587,11 +580,12 @@ class Ninetailed {
|
|
|
587
580
|
}, storageImpl ? {
|
|
588
581
|
storage: storageImpl
|
|
589
582
|
} : {}));
|
|
590
|
-
const
|
|
583
|
+
const _detachOnReadyListener = this.instance.on('ready', () => {
|
|
591
584
|
this.isInitialized = true;
|
|
592
585
|
logger.info('Ninetailed Experience.js SDK is completely initialized.');
|
|
593
|
-
|
|
586
|
+
_detachOnReadyListener();
|
|
594
587
|
});
|
|
588
|
+
|
|
595
589
|
// put in private method
|
|
596
590
|
this.onProfileChange(profileState => {
|
|
597
591
|
this._profileState = profileState;
|
|
@@ -643,7 +637,7 @@ const selectVariant = (baseline, variants, {
|
|
|
643
637
|
if (status === 'loading') {
|
|
644
638
|
return {
|
|
645
639
|
loading: true,
|
|
646
|
-
variant: Object.assign(
|
|
640
|
+
variant: Object.assign({}, baseline, {
|
|
647
641
|
id: 'baseline',
|
|
648
642
|
audience: {
|
|
649
643
|
id: 'baseline'
|
|
@@ -659,7 +653,7 @@ const selectVariant = (baseline, variants, {
|
|
|
659
653
|
if (status === 'error') {
|
|
660
654
|
return {
|
|
661
655
|
loading: false,
|
|
662
|
-
variant: Object.assign(
|
|
656
|
+
variant: Object.assign({}, baseline, {
|
|
663
657
|
id: 'baseline',
|
|
664
658
|
audience: {
|
|
665
659
|
id: 'baseline'
|
|
@@ -673,19 +667,19 @@ const selectVariant = (baseline, variants, {
|
|
|
673
667
|
};
|
|
674
668
|
}
|
|
675
669
|
const variant = variants.find(variant => {
|
|
676
|
-
var
|
|
677
|
-
return
|
|
670
|
+
var _profile$audiences, _variant$audience;
|
|
671
|
+
return profile == null || (_profile$audiences = profile.audiences) == null ? void 0 : _profile$audiences.includes((_variant$audience = variant.audience) == null ? void 0 : _variant$audience.id);
|
|
678
672
|
});
|
|
679
673
|
if (variant) {
|
|
680
|
-
if (
|
|
674
|
+
if (options != null && options.holdout || -1 > ((profile == null ? void 0 : profile.random) || 0)) {
|
|
681
675
|
return {
|
|
682
676
|
loading: false,
|
|
683
|
-
variant: Object.assign(
|
|
677
|
+
variant: Object.assign({}, baseline, {
|
|
684
678
|
audience: {
|
|
685
679
|
id: 'baseline'
|
|
686
680
|
}
|
|
687
681
|
}),
|
|
688
|
-
audience: Object.assign(
|
|
682
|
+
audience: Object.assign({}, variant.audience, {
|
|
689
683
|
id: variant.audience.id
|
|
690
684
|
}),
|
|
691
685
|
isPersonalized: false,
|
|
@@ -695,19 +689,20 @@ const selectVariant = (baseline, variants, {
|
|
|
695
689
|
return {
|
|
696
690
|
loading: false,
|
|
697
691
|
variant,
|
|
698
|
-
audience: Object.assign(
|
|
692
|
+
audience: Object.assign({}, variant.audience, {
|
|
699
693
|
id: variant.audience.id
|
|
700
694
|
}),
|
|
701
695
|
isPersonalized: true,
|
|
702
696
|
error: null
|
|
703
697
|
};
|
|
704
698
|
}
|
|
705
|
-
|
|
706
|
-
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* There was no matching audience found.
|
|
707
702
|
*/
|
|
708
703
|
return {
|
|
709
704
|
loading: false,
|
|
710
|
-
variant: Object.assign(
|
|
705
|
+
variant: Object.assign({}, baseline, {
|
|
711
706
|
id: 'baseline',
|
|
712
707
|
audience: {
|
|
713
708
|
id: 'baseline'
|
|
@@ -767,7 +762,7 @@ const decodeExperienceVariantsMap = encodedExperienceVariantsMap => {
|
|
|
767
762
|
experienceId,
|
|
768
763
|
variantIndex
|
|
769
764
|
};
|
|
770
|
-
}).filter(x => !!x).reduce((acc, curr) => Object.assign(
|
|
765
|
+
}).filter(x => !!x).reduce((acc, curr) => Object.assign({}, acc, {
|
|
771
766
|
[curr.experienceId]: curr.variantIndex
|
|
772
767
|
}), {});
|
|
773
768
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ninetailed/experience.js",
|
|
3
|
-
"version": "7.5.3-beta.
|
|
3
|
+
"version": "7.5.3-beta.2",
|
|
4
4
|
"description": "Ninetailed SDK for javascript",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -8,14 +8,11 @@
|
|
|
8
8
|
"url": "https://github.com/ninetailed-inc/experience.js.git",
|
|
9
9
|
"directory": "packages/sdks/javascript"
|
|
10
10
|
},
|
|
11
|
-
"module": "./index.js",
|
|
12
|
-
"main": "./index.cjs",
|
|
13
|
-
"type": "module",
|
|
14
|
-
"types": "./src/index.d.ts",
|
|
15
11
|
"dependencies": {
|
|
16
|
-
"@ninetailed/experience.js-shared": "7.5.3-beta.1",
|
|
17
12
|
"analytics": "0.8.1",
|
|
18
|
-
"zod": "3.21.4"
|
|
13
|
+
"zod": "3.21.4",
|
|
14
|
+
"@ninetailed/experience.js-shared": "*"
|
|
19
15
|
},
|
|
20
|
-
"
|
|
16
|
+
"module": "./index.esm.js",
|
|
17
|
+
"main": "./index.cjs.js"
|
|
21
18
|
}
|
|
File without changes
|