-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathsdkClientMethodCSWithTT.ts
More file actions
101 lines (87 loc) · 4.28 KB
/
sdkClientMethodCSWithTT.ts
File metadata and controls
101 lines (87 loc) · 4.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { clientCSDecorator } from './clientCS';
import { SplitIO } from '../types';
import { validateKey } from '../utils/inputValidation/key';
import { validateTrafficType } from '../utils/inputValidation/trafficType';
import { getMatching, keyParser } from '../utils/key';
import { sdkClientFactory } from './sdkClient';
import { ISyncManagerCS } from '../sync/types';
import { objectAssign } from '../utils/lang/objectAssign';
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
import { ISdkFactoryContext } from '../sdkFactory/types';
import { buildInstanceId } from './identity';
import { IStorageSync } from '../storages/types';
/**
* Factory of client method for the client-side (browser) variant of the Isomorphic JS SDK,
* where clients can have a bound TT for the track method, which is provided via the settings
* (default client) or the client method (shared clients).
*/
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
const { clients, storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, startup: { readyTimeout }, log } } = params;
const mainClientInstance = clientCSDecorator(
log,
sdkClientFactory(objectAssign({}, params, {
mySegmentsSyncManager: syncManager && storage.shared && (syncManager as ISyncManagerCS).shared(getMatching(key), sdkReadinessManager.readinessManager, storage as IStorageSync),
})) as SplitIO.IClient,
key,
trafficType
);
const parsedDefaultKey = keyParser(key);
const defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
// Cache instances created per factory.
clients[defaultInstanceId] = mainClientInstance;
return function client(key?: SplitIO.SplitKey, trafficType?: string) {
if (key === undefined) {
log.debug(RETRIEVE_CLIENT_DEFAULT);
return mainClientInstance;
}
// Validate the key value
const validKey = validateKey(log, key, LOG_PREFIX_CLIENT_INSTANTIATION);
if (validKey === false) {
throw new Error('Shared Client needs a valid key.');
}
let validTrafficType;
if (trafficType !== undefined) {
validTrafficType = validateTrafficType(log, trafficType, LOG_PREFIX_CLIENT_INSTANTIATION);
if (validTrafficType === false) {
throw new Error('Shared Client needs a valid traffic type or no traffic type at all.');
}
}
const instanceId = buildInstanceId(validKey, validTrafficType);
if (!clients[instanceId]) {
const matchingKey = getMatching(validKey);
const sharedSdkReadiness = sdkReadinessManager.shared(readyTimeout);
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
if (err) {
sharedSdkReadiness.readinessManager.timeout();
return;
}
// Emit SDK_READY in consumer mode for shared clients
sharedSdkReadiness.readinessManager.segments.emit(SDK_SEGMENTS_ARRIVED);
});
// 3 possibilities:
// - Standalone mode: both syncManager and mySegmentsSyncManager are defined
// - Consumer mode: both syncManager and mySegmentsSyncManager are undefined
// - Consumer partial mode: syncManager is defined (only for submitters) but mySegmentsSyncManager not
// @ts-ignore
const mySegmentsSyncManager = syncManager && sharedStorage && (syncManager as ISyncManagerCS).shared(matchingKey, sharedSdkReadiness.readinessManager, sharedStorage);
// As shared clients reuse all the storage information, we don't need to check here if we
// will use offline or online mode. We should stick with the original decision.
clients[instanceId] = clientCSDecorator(
log,
sdkClientFactory(objectAssign({}, params, {
sdkReadinessManager: sharedSdkReadiness,
storage: sharedStorage || storage,
mySegmentsSyncManager,
})) as SplitIO.IClient,
validKey,
validTrafficType
);
mySegmentsSyncManager && mySegmentsSyncManager.start();
log.info(NEW_SHARED_CLIENT);
} else {
log.debug(RETRIEVE_CLIENT_EXISTING);
}
return clients[instanceId] as SplitIO.ICsClient;
};
}