@blotoutio/edgetag-sdk-js 0.51.1 → 0.52.0

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.
Files changed (4) hide show
  1. package/index.cjs.js +601 -469
  2. package/index.d.ts +29 -6
  3. package/index.mjs +601 -469
  4. package/package.json +1 -1
package/index.mjs CHANGED
@@ -13,11 +13,174 @@ var api = /*#__PURE__*/Object.freeze({
13
13
  get user () { return user; }
14
14
  });
15
15
 
16
- const _config = {};
17
- const setConfig$1 = (config) => {
18
- Object.assign(_config, config);
16
+ const isBool = (v) => typeof v == 'boolean';
17
+ const isRecord = (v) => !!v && typeof v == 'object' && !Array.isArray(v);
18
+ /**
19
+ * This function validates user consent for a given provider and tag name.
20
+ * It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
21
+ */
22
+ const hasUserConsent = (consent, provider, tagName) => {
23
+ if (!isRecord(consent)) {
24
+ return false;
25
+ }
26
+ let allowed = isBool(consent.all) ? consent.all : false;
27
+ if (provider in consent) {
28
+ const providerSpecific = consent[provider];
29
+ if (isBool(providerSpecific)) {
30
+ allowed = providerSpecific;
31
+ }
32
+ else if (isRecord(providerSpecific)) {
33
+ if ('all' in providerSpecific && isBool(providerSpecific.all)) {
34
+ allowed = providerSpecific.all;
35
+ }
36
+ if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
37
+ allowed = providerSpecific[tagName];
38
+ }
39
+ }
40
+ }
41
+ return allowed;
42
+ };
43
+ /**
44
+ * This function validates user consent for a given provider type, not based on tagName.
45
+ */
46
+ const hasUserConsentForProvider = (consent, provider) => {
47
+ if (!isRecord(consent)) {
48
+ return false;
49
+ }
50
+ let allowed = isBool(consent.all) ? consent.all : false;
51
+ if (provider in consent) {
52
+ const providerSpecific = consent[provider];
53
+ if (isBool(providerSpecific)) {
54
+ allowed = providerSpecific;
55
+ }
56
+ else if (isRecord(providerSpecific)) {
57
+ return Object.keys(providerSpecific).some((instance) => providerSpecific[instance] === true);
58
+ }
59
+ }
60
+ return allowed;
61
+ };
62
+ /**
63
+ * This function validates provider allowance for a given provider and tag name.
64
+ * It should not be used to validate `UserConsent`.
65
+ */
66
+ const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
67
+ if (!isRecord(providersConfig)) {
68
+ return true;
69
+ }
70
+ if (provider in providersConfig) {
71
+ const providerSpecific = providersConfig[provider];
72
+ if (isBool(providerSpecific)) {
73
+ return providerSpecific;
74
+ }
75
+ if (isRecord(providerSpecific)) {
76
+ const tagKeys = Object.keys(providerSpecific).filter((k) => k != 'all');
77
+ if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
78
+ return providerSpecific[tagName];
79
+ }
80
+ return isBool(providerSpecific.all)
81
+ ? providerSpecific.all
82
+ : tagKeys.length == 0;
83
+ }
84
+ }
85
+ const providerKeys = Object.keys(providersConfig).filter((k) => k != 'all');
86
+ return isBool(providersConfig.all)
87
+ ? providersConfig.all
88
+ : providerKeys.length == 0;
89
+ };
90
+
91
+ const upsert = (map, key, update, createDefault) => {
92
+ const currentValue = map.has(key)
93
+ ? map.get(key)
94
+ : createDefault();
95
+ return map.set(key, update(currentValue));
96
+ };
97
+
98
+ const expand = (str) => str.split(',').flatMap((entry) => {
99
+ if (!entry.includes('-')) {
100
+ return entry;
101
+ }
102
+ const result = [];
103
+ const [start, end] = entry.split('-').map(Number);
104
+ for (let i = start; i <= end; i++) {
105
+ result.push(i.toString());
106
+ }
107
+ return result;
108
+ });
109
+ /**
110
+ * Exported from https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes
111
+ *
112
+ * In Dev Tools, select the `tbody` element containing the area codes and run the following code,
113
+ * replacing the emdash character with a simple endash:
114
+ *
115
+ * ```ts
116
+ * [...$0.querySelectorAll('td:first-child')]
117
+ * .filter(cell => cell.firstChild.nodeName != 'A')
118
+ * .map(cell => cell.textContent.trim()).join(',')
119
+ * ```
120
+ */
121
+ new Set([
122
+ ...expand('200,211,221,222,230,232,233,235,237-238,241,243,244,245,247,255,257,258-259,261,265,266,271,273,274,275,277,278,280,282,283,285-287,288,290-299'),
123
+ ...expand('300,311,322,324,327,328,333,335,338,342,344,348-349,353,355,356,357-359,362,366,369,370-379,381,382,383-384,387,388,389,390-399'),
124
+ ...expand('400,411,420,421-422,426-427,428,429,433,439,444,446,449,451-454,455,456,457,459,460,461-462,465,466,467,471,476,477,481-483,485-486,487,488,489,490-499'),
125
+ ...expand('511,532,535,536,537,538,542-543,545-547,549-550,552-554,555,556,558,560,565,568,569,576,578,583,589,590-599'),
126
+ ...expand('611,621,624,625,627,632,633,634-635,637-638,642-643,644,648,652-654,655,663,665,666,668,673-676,677,679,685,686,687,688,690-699'),
127
+ ...expand('711,722,723,729,733,735-736,739,741,744,745-746,748,749-751,752,755,756,759,761,764,766,768,776,777,783,788,789,790-799'),
128
+ ...expand('811,821,822,823-824,827,834,836,841-842,846,851,852-853,871,874-875,879,880-887,889,890-899'),
129
+ ...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
130
+ ]);
131
+
132
+ // eslint-disable-next-line @nx/enforce-module-boundaries
133
+ let edgeTagSettings;
134
+ const initSettings = (destination, options) => {
135
+ if (!edgeTagSettings) {
136
+ edgeTagSettings = {};
137
+ }
138
+ edgeTagSettings[destination] = {
139
+ destination,
140
+ initialized: false,
141
+ stubs: [],
142
+ channels: new Map(),
143
+ ...options,
144
+ };
145
+ };
146
+ const setSetting = (options, destination) => {
147
+ if (!edgeTagSettings) {
148
+ return;
149
+ }
150
+ if (!destination) {
151
+ Object.keys(edgeTagSettings).forEach((key) => {
152
+ edgeTagSettings[key] = {
153
+ ...edgeTagSettings[key],
154
+ ...options,
155
+ };
156
+ });
157
+ return;
158
+ }
159
+ edgeTagSettings[destination] = {
160
+ ...edgeTagSettings[destination],
161
+ ...options,
162
+ };
163
+ };
164
+ const getSetting = (destination, key) => {
165
+ var _a;
166
+ return (_a = edgeTagSettings === null || edgeTagSettings === void 0 ? void 0 : edgeTagSettings[destination]) === null || _a === void 0 ? void 0 : _a[key];
167
+ };
168
+ const getInstances = () => {
169
+ return Object.keys(edgeTagSettings || {});
170
+ };
171
+ const addChannel = (destination, pkg, tagName) => upsert(getSetting(destination, 'channels'), pkg, (names) => names.add(tagName), () => new Set());
172
+ const getProviderVariables = (destination, packageId) => {
173
+ const setting = getSetting(destination, 'packages');
174
+ if (!setting) {
175
+ return [];
176
+ }
177
+ return (setting
178
+ .filter((pkg) => pkg.package === packageId)
179
+ .map((pkg) => ({
180
+ tagName: pkg.tagName,
181
+ variableSet: pkg.variables || {},
182
+ })) || []);
19
183
  };
20
- const getConfig = () => _config;
21
184
 
22
185
  const getUserAgent = () => {
23
186
  try {
@@ -28,11 +191,11 @@ const getUserAgent = () => {
28
191
  return '';
29
192
  }
30
193
  };
31
- const getReferrer = () => {
194
+ const getReferrer = (destination) => {
32
195
  let referrer = '';
33
196
  try {
34
197
  const referrerUrl = new URL(document.referrer);
35
- const pageUrl = new URL(getPageUrl());
198
+ const pageUrl = new URL(getPageUrl(destination));
36
199
  if (referrerUrl.host !== pageUrl.host) {
37
200
  referrer = referrerUrl.href;
38
201
  }
@@ -42,22 +205,22 @@ const getReferrer = () => {
42
205
  return referrer;
43
206
  }
44
207
  };
45
- const getPageUrl = () => {
208
+ const getPageUrl = (destination) => {
46
209
  try {
47
210
  // we need to leave this one in for existing Custom pixel customers
48
211
  if (window.edgetagData && window.edgetagData['pageUrl']) {
49
212
  return window.edgetagData['pageUrl'];
50
213
  }
51
- const { pageUrl } = getConfig();
52
- return pageUrl || window.location.href;
214
+ const config = getSetting(destination, 'config');
215
+ return (config === null || config === void 0 ? void 0 : config.pageUrl) || window.location.href;
53
216
  }
54
217
  catch {
55
218
  return '';
56
219
  }
57
220
  };
58
- const getSearch = () => {
221
+ const getSearch = (destination) => {
59
222
  try {
60
- return new URL(getPageUrl()).search;
223
+ return new URL(getPageUrl(destination)).search;
61
224
  }
62
225
  catch {
63
226
  return '';
@@ -110,7 +273,6 @@ const areEqual = (a, b) => {
110
273
  const tagStorage = 'edgeTag';
111
274
  const consentKey = 'consent';
112
275
  const keyPrefix = `_worker`;
113
- const cookieKey = 'tag_user_id';
114
276
 
115
277
  const getMessage = (error) => {
116
278
  if (error instanceof Error) {
@@ -144,9 +306,9 @@ const error = (data) => {
144
306
  console.error('[EdgeTag]', getMessage(data));
145
307
  };
146
308
 
147
- const initKey = `${keyPrefix}Store`;
148
- const saveDataPerKey = (persistType, provider, value, key) => {
149
- const storage = getData$1(persistType);
309
+ const initKey = `${keyPrefix}StoreMultiple`;
310
+ const saveDataPerKey = (destination, persistType, provider, value, key) => {
311
+ const storage = getData$1(destination, persistType);
150
312
  if (!storage['data']) {
151
313
  storage['data'] = {};
152
314
  }
@@ -154,49 +316,54 @@ const saveDataPerKey = (persistType, provider, value, key) => {
154
316
  storage['data'][provider] = {};
155
317
  }
156
318
  storage['data'][provider][key] = value;
157
- saveData(persistType, storage);
319
+ saveData(destination, persistType, storage);
320
+ };
321
+ const saveKV = (destination, data) => {
322
+ const currentSession = getData$1(destination, 'session');
323
+ if (!currentSession['kv']) {
324
+ currentSession['kv'] = {};
325
+ }
326
+ currentSession['kv'] = {
327
+ ...currentSession['kv'],
328
+ ...data,
329
+ };
330
+ saveData(destination, 'session', currentSession);
158
331
  };
159
- const savePerKey = (persistType, provider, value, key) => {
160
- const storage = getData$1(persistType);
332
+ const savePerKey = (destination, persistType, provider, value, key) => {
333
+ const storage = getData$1(destination, persistType);
161
334
  if (!storage[provider]) {
162
335
  storage[provider] = {};
163
336
  }
164
337
  storage[provider][key] = value;
165
- saveData(persistType, storage);
338
+ saveData(destination, persistType, storage);
166
339
  };
167
- const getDataPerKey = (persistType, provider, key) => {
168
- const storage = getData$1(persistType);
340
+ const getDataPerKey = (destination, persistType, provider, key) => {
341
+ const storage = getData$1(destination, persistType);
169
342
  if (!storage[provider]) {
170
343
  return undefined;
171
344
  }
172
345
  return storage[provider][key];
173
346
  };
174
- const saveData = (persistType, value, key = initKey) => {
347
+ const saveData = (destination, persistType, value, key = initKey) => {
175
348
  if (persistType === 'session') {
176
- saveSession(value, key);
349
+ const data = getSession(key);
350
+ data[destination] = value;
351
+ saveSession(data, key);
177
352
  return;
178
353
  }
179
- saveLocal(value, key);
354
+ const data = getLocal(key);
355
+ data[destination] = value;
356
+ saveLocal(data, key);
180
357
  };
181
- const getData$1 = (persistType, key = initKey) => {
358
+ const getData$1 = (destination, persistType, key = initKey) => {
359
+ let data;
182
360
  if (persistType === 'session') {
183
- return getSession(key);
361
+ data = getSession(key);
184
362
  }
185
- return getLocal(key);
186
- };
187
- const saveKV = (data) => {
188
- let currentSession = getData$1('session');
189
- if (!currentSession) {
190
- currentSession = {};
191
- }
192
- if (!currentSession['kv']) {
193
- currentSession['kv'] = {};
363
+ else {
364
+ data = getLocal(key);
194
365
  }
195
- currentSession['kv'] = {
196
- ...currentSession['kv'],
197
- ...data,
198
- };
199
- saveData('session', currentSession);
366
+ return (data === null || data === void 0 ? void 0 : data[destination]) || {};
200
367
  };
201
368
  const saveLocal = (value, key) => {
202
369
  try {
@@ -251,85 +418,19 @@ const getSession = (key) => {
251
418
  }
252
419
  };
253
420
 
254
- const encodeString = (name) => {
255
- if (typeof btoa === 'undefined') {
256
- return Buffer.from(name).toString('base64');
257
- }
258
- return btoa(name);
259
- };
260
- const getBasicRandomNumber = () => {
261
- return parseInt((Math.random() * 10000000000).toString(), 10);
262
- };
263
- const generateUUID = () => {
264
- let id = '';
265
- try {
266
- id = crypto.randomUUID();
267
- if (!id) {
268
- const array = new Uint32Array(20);
269
- const numbers = crypto.getRandomValues(array);
270
- for (let i = 0; i < 5; i++) {
271
- const y = i * 3;
272
- if (i !== 0) {
273
- id += '-';
274
- }
275
- const sum = numbers[y + 1] + numbers[y + 2] + numbers[y + 3];
276
- id += sum.toString();
277
- }
278
- }
279
- }
280
- catch {
281
- id = `${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}`;
282
- console.log('[EdgeTag] Crypto module not found');
283
- }
284
- return id;
285
- };
286
- const generateEventId = (name) => {
287
- let time = Date.now().toString();
288
- if (typeof performance !== 'undefined' &&
289
- typeof performance.now === 'function') {
290
- const perf = performance.now();
291
- if (perf) {
292
- time = perf.toFixed(4);
293
- }
294
- }
295
- return `${encodeString(name)}-${generateUUID()}-${time}`;
421
+ const getUserId$1 = (destination) => {
422
+ return getSetting(destination, 'userId');
296
423
  };
297
-
298
- const getCookieValue = (key) => {
299
- try {
300
- if (!document || !document.cookie) {
301
- return '';
302
- }
303
- const name = `${key}=`;
304
- const decodedCookie = decodeURIComponent(document.cookie);
305
- const ca = decodedCookie.split(';');
306
- for (let i = 0; i < ca.length; i++) {
307
- let c = ca[i];
308
- while (c.charAt(0) === ' ') {
309
- c = c.substring(1);
310
- }
311
- if (c.indexOf(name) === 0) {
312
- return c.substring(name.length, c.length);
313
- }
314
- }
315
- return '';
424
+ const handleGetUserId = (options) => {
425
+ if (options === null || options === void 0 ? void 0 : options.destination) {
426
+ return getUserId$1(options.destination);
316
427
  }
317
- catch {
318
- return '';
428
+ const instances = getInstances();
429
+ if (instances.length > 1) {
430
+ error('Multiple instances detected! Please provide a destination.');
431
+ return null;
319
432
  }
320
- };
321
-
322
- let initUserId = '';
323
- const handleGetUserId = () => {
324
- if (initUserId) {
325
- return initUserId;
326
- }
327
- // leaving this for backward compatibility as worker was maybe not updated yet
328
- // reference https://github.com/blotoutio/solutions/issues/1960
329
- return getCookieValue(cookieKey);
330
- };
331
- const setUserId = (userId) => {
332
- initUserId = userId;
433
+ return getUserId$1(instances[0]);
333
434
  };
334
435
 
335
436
  const beacon = (url, payload) => {
@@ -344,12 +445,12 @@ const beacon = (url, payload) => {
344
445
  return Promise.reject(new Error('Beacon not supported.'));
345
446
  }
346
447
  };
347
- const ajax = (method, url, payload) => fetch(url, {
448
+ const ajax = (destination, method, url, payload) => fetch(url, {
348
449
  method,
349
450
  headers: {
350
451
  'Content-type': 'application/json; charset=utf-8',
351
452
  Accept: 'application/json; charset=utf-8',
352
- EdgeTagUserId: handleGetUserId(),
453
+ EdgeTagUserId: getUserId$1(destination),
353
454
  },
354
455
  body: JSON.stringify(payload),
355
456
  credentials: 'include',
@@ -363,26 +464,26 @@ const ajax = (method, url, payload) => fetch(url, {
363
464
  }
364
465
  return Promise.resolve(body);
365
466
  });
366
- const getStandardPayload = (payload) => {
467
+ const getStandardPayload = (destination, payload) => {
367
468
  const data = {
368
- pageUrl: getPageUrl(),
469
+ pageUrl: getPageUrl(destination),
369
470
  pageTitle: getPageTitle(),
370
471
  userAgent: getUserAgent(),
371
- referrer: getReferrer(),
372
- search: getSearch(),
472
+ referrer: getReferrer(destination),
473
+ search: getSearch(destination),
373
474
  locale: getLocale(),
374
- sdkVersion: "0.51.1" ,
475
+ sdkVersion: "0.52.0" ,
375
476
  ...(payload || {}),
376
477
  };
377
478
  let storage = {};
378
- const session = getData$1('session');
479
+ const session = getData$1(destination, 'session');
379
480
  if (session) {
380
481
  storage = {
381
482
  ...storage,
382
483
  ...session,
383
484
  };
384
485
  }
385
- const local = getData$1('local');
486
+ const local = getData$1(destination, 'local');
386
487
  if (local) {
387
488
  storage = {
388
489
  ...storage,
@@ -396,11 +497,13 @@ async function postRequest(url, data, options) {
396
497
  if (!url) {
397
498
  return Promise.reject(new Error('URL is empty.'));
398
499
  }
399
- const payload = getStandardPayload(data);
500
+ const parsedUrl = new URL(url);
501
+ const destination = parsedUrl.origin;
502
+ const payload = getStandardPayload(destination, data);
400
503
  if (options && options.method === 'beacon') {
401
504
  return Promise.resolve(beacon(url, payload));
402
505
  }
403
- return await ajax('POST', url, payload);
506
+ return await ajax(destination, 'POST', url, payload);
404
507
  }
405
508
  async function getRequest(url, options) {
406
509
  if (!url) {
@@ -411,170 +514,44 @@ async function getRequest(url, options) {
411
514
  result: Promise.resolve(beacon(url)),
412
515
  };
413
516
  }
414
- return await ajax('GET', url);
517
+ const parsedUrl = new URL(url);
518
+ const destination = parsedUrl.origin;
519
+ return await ajax(destination, 'GET', url);
415
520
  }
416
521
 
417
- let endpointUrl = '';
418
- const generateUrl = (path) => {
419
- const endpoint = getUrl();
420
- if (!endpoint) {
522
+ const generateUrl = (destination, path) => {
523
+ if (!destination) {
421
524
  log('URL is not valid');
422
525
  return '';
423
526
  }
424
- return `${endpoint}${path}`;
425
- };
426
- const getUrl = () => {
427
- return endpointUrl;
527
+ return `${destination}${path}`;
428
528
  };
429
- const setUrl = (url) => {
430
- if (url == null) {
431
- return;
432
- }
433
- endpointUrl = url;
434
- };
435
- const getTagURL = (options) => {
436
- const url = new URL(generateUrl('/tag'));
529
+ const getTagURL = (destination, options) => {
530
+ const parsedUrl = new URL(generateUrl(destination, '/tag'));
437
531
  if (options === null || options === void 0 ? void 0 : options.sync) {
438
- url.searchParams.set('sync', 'true');
532
+ parsedUrl.searchParams.set('sync', 'true');
439
533
  }
440
- return url.toString();
534
+ return parsedUrl.toString();
441
535
  };
442
- const getInitURL = () => {
443
- return generateUrl('/init');
536
+ const getInitURL = (destination) => {
537
+ return generateUrl(destination, '/init');
444
538
  };
445
- const getConsentURL = () => {
446
- return generateUrl('/consent');
539
+ const getConsentURL = (destination) => {
540
+ return generateUrl(destination, '/consent');
447
541
  };
448
- const getUserURL = () => {
449
- return generateUrl('/user');
542
+ const getUserURL = (destination) => {
543
+ return generateUrl(destination, '/user');
450
544
  };
451
- const getDataURL = () => {
452
- return generateUrl(`/data`);
545
+ const getDataURL = (destination) => {
546
+ return generateUrl(destination, `/data`);
453
547
  };
454
- const getGetDataURL = (keys) => {
455
- return generateUrl(`/data?keys=${encodeURIComponent(keys.join(','))}`);
548
+ const getGetDataURL = (destination, keys) => {
549
+ return generateUrl(destination, `/data?keys=${encodeURIComponent(keys.join(','))}`);
456
550
  };
457
- const getKeysURL = () => {
458
- return generateUrl(`/keys`);
551
+ const getKeysURL = (destination) => {
552
+ return generateUrl(destination, `/keys`);
459
553
  };
460
554
 
461
- const isBool = (v) => typeof v == 'boolean';
462
- const isRecord = (v) => !!v && typeof v == 'object' && !Array.isArray(v);
463
- /**
464
- * This function validates user consent for a given provider and tag name.
465
- * It should be used in conjunction with `UserConsent`, not `ProvidersConfig`.
466
- */
467
- const hasUserConsent = (consent, provider, tagName) => {
468
- if (!isRecord(consent)) {
469
- return false;
470
- }
471
- let allowed = isBool(consent.all) ? consent.all : false;
472
- if (provider in consent) {
473
- const providerSpecific = consent[provider];
474
- if (isBool(providerSpecific)) {
475
- allowed = providerSpecific;
476
- }
477
- else if (isRecord(providerSpecific)) {
478
- if ('all' in providerSpecific && isBool(providerSpecific.all)) {
479
- allowed = providerSpecific.all;
480
- }
481
- if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
482
- allowed = providerSpecific[tagName];
483
- }
484
- }
485
- }
486
- return allowed;
487
- };
488
- /**
489
- * This function validates user consent for a given provider type, not based on tagName.
490
- */
491
- const hasUserConsentForProvider = (consent, provider) => {
492
- if (!isRecord(consent)) {
493
- return false;
494
- }
495
- let allowed = isBool(consent.all) ? consent.all : false;
496
- if (provider in consent) {
497
- const providerSpecific = consent[provider];
498
- if (isBool(providerSpecific)) {
499
- allowed = providerSpecific;
500
- }
501
- else if (isRecord(providerSpecific)) {
502
- return Object.keys(providerSpecific).some((instance) => providerSpecific[instance] === true);
503
- }
504
- }
505
- return allowed;
506
- };
507
- /**
508
- * This function validates provider allowance for a given provider and tag name.
509
- * It should not be used to validate `UserConsent`.
510
- */
511
- const isProviderInstanceAllowed = (providersConfig, provider, tagName) => {
512
- if (!isRecord(providersConfig)) {
513
- return true;
514
- }
515
- if (provider in providersConfig) {
516
- const providerSpecific = providersConfig[provider];
517
- if (isBool(providerSpecific)) {
518
- return providerSpecific;
519
- }
520
- if (isRecord(providerSpecific)) {
521
- const tagKeys = Object.keys(providerSpecific).filter((k) => k != 'all');
522
- if (tagName in providerSpecific && isBool(providerSpecific[tagName])) {
523
- return providerSpecific[tagName];
524
- }
525
- return isBool(providerSpecific.all)
526
- ? providerSpecific.all
527
- : tagKeys.length == 0;
528
- }
529
- }
530
- const providerKeys = Object.keys(providersConfig).filter((k) => k != 'all');
531
- return isBool(providersConfig.all)
532
- ? providersConfig.all
533
- : providerKeys.length == 0;
534
- };
535
-
536
- const upsert = (map, key, update, createDefault) => {
537
- const currentValue = map.has(key)
538
- ? map.get(key)
539
- : createDefault();
540
- return map.set(key, update(currentValue));
541
- };
542
-
543
- const expand = (str) => str.split(',').flatMap((entry) => {
544
- if (!entry.includes('-')) {
545
- return entry;
546
- }
547
- const result = [];
548
- const [start, end] = entry.split('-').map(Number);
549
- for (let i = start; i <= end; i++) {
550
- result.push(i.toString());
551
- }
552
- return result;
553
- });
554
- /**
555
- * Exported from https://en.wikipedia.org/wiki/List_of_North_American_Numbering_Plan_area_codes
556
- *
557
- * In Dev Tools, select the `tbody` element containing the area codes and run the following code,
558
- * replacing the emdash character with a simple endash:
559
- *
560
- * ```ts
561
- * [...$0.querySelectorAll('td:first-child')]
562
- * .filter(cell => cell.firstChild.nodeName != 'A')
563
- * .map(cell => cell.textContent.trim()).join(',')
564
- * ```
565
- */
566
- new Set([
567
- ...expand('200,211,221,222,230,232,233,235,237-238,241,243,244,245,247,255,257,258-259,261,265,266,271,273,274,275,277,278,280,282,283,285-287,288,290-299'),
568
- ...expand('300,311,322,324,327,328,333,335,338,342,344,348-349,353,355,356,357-359,362,366,369,370-379,381,382,383-384,387,388,389,390-399'),
569
- ...expand('400,411,420,421-422,426-427,428,429,433,439,444,446,449,451-454,455,456,457,459,460,461-462,465,466,467,471,476,477,481-483,485-486,487,488,489,490-499'),
570
- ...expand('511,532,535,536,537,538,542-543,545-547,549-550,552-554,555,556,558,560,565,568,569,576,578,583,589,590-599'),
571
- ...expand('611,621,624,625,627,632,633,634-635,637-638,642-643,644,648,652-654,655,663,665,666,668,673-676,677,679,685,686,687,688,690-699'),
572
- ...expand('711,722,723,729,733,735-736,739,741,744,745-746,748,749-751,752,755,756,759,761,764,766,768,776,777,783,788,789,790-799'),
573
- ...expand('811,821,822,823-824,827,834,836,841-842,846,851,852-853,871,874-875,879,880-887,889,890-899'),
574
- ...expand('911,921,922,923,924,926,927,932,933,935,942,944,946,950,953,955,957-958,960-969,974,975,976,977,981-982,987,988,990-999'),
575
- ]);
576
-
577
- let initialized = false;
578
555
  const providersPackages = {};
579
556
  const setPreferences = (preferences) => {
580
557
  var _a;
@@ -585,7 +562,6 @@ const setPreferences = (preferences) => {
585
562
  error('Please provide URL for EdgeTag');
586
563
  return false;
587
564
  }
588
- !!preferences.disableConsentCheck;
589
565
  (_a = preferences.providers) === null || _a === void 0 ? void 0 : _a.forEach((provider) => {
590
566
  if (!provider.name) {
591
567
  return;
@@ -605,52 +581,122 @@ const setPreferences = (preferences) => {
605
581
  catch {
606
582
  // do nothing
607
583
  }
608
- setUrl(preferences.edgeURL);
584
+ initSettings(preferences.edgeURL, {
585
+ disableConsent: !!preferences.disableConsentCheck,
586
+ });
609
587
  return true;
610
588
  };
611
- const getProvidersPackage = () => providersPackages;
612
- const isInitialized = () => initialized;
613
- const setInitialized = () => {
614
- initialized = true;
589
+ const getProvidersPackage = (destination) => {
590
+ const packages = getSetting(destination, 'packages');
591
+ const providers = [];
592
+ packages === null || packages === void 0 ? void 0 : packages.forEach((pkg) => {
593
+ const provider = providersPackages[pkg.package];
594
+ if (!provider) {
595
+ return;
596
+ }
597
+ providers.push(provider);
598
+ });
599
+ return providers;
615
600
  };
616
- const configuredTags = new Map();
617
- const addConfiguredTag = (pkg, tagName) => upsert(configuredTags, pkg, (names) => names.add(tagName), () => new Set());
618
- const getConfiguredTags = () => configuredTags;
619
601
 
620
- const manifestVariables = {};
621
- const addProviderVariable = (name, variables, tagName) => {
622
- manifestVariables[name] = {
623
- ...manifestVariables[name],
624
- [tagName]: variables || {},
625
- };
602
+ const encodeString = (name) => {
603
+ if (typeof btoa === 'undefined') {
604
+ return Buffer.from(name).toString('base64');
605
+ }
606
+ return btoa(name);
626
607
  };
627
- const getProviderVariables = (name) => {
628
- if (!name) {
629
- return {};
608
+ const getBasicRandomNumber = () => {
609
+ return parseInt((Math.random() * 10000000000).toString(), 10);
610
+ };
611
+ const generateUUID = () => {
612
+ let id = '';
613
+ try {
614
+ id = crypto.randomUUID();
615
+ if (!id) {
616
+ const array = new Uint32Array(20);
617
+ const numbers = crypto.getRandomValues(array);
618
+ for (let i = 0; i < 5; i++) {
619
+ const y = i * 3;
620
+ if (i !== 0) {
621
+ id += '-';
622
+ }
623
+ const sum = numbers[y + 1] + numbers[y + 2] + numbers[y + 3];
624
+ id += sum.toString();
625
+ }
626
+ }
627
+ }
628
+ catch {
629
+ id = `${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}-${getBasicRandomNumber()}`;
630
+ console.log('[EdgeTag] Crypto module not found');
631
+ }
632
+ return id;
633
+ };
634
+ const generateEventId = (name) => {
635
+ let time = Date.now().toString();
636
+ if (typeof performance !== 'undefined' &&
637
+ typeof performance.now === 'function') {
638
+ const perf = performance.now();
639
+ if (perf) {
640
+ time = perf.toFixed(4);
641
+ }
630
642
  }
631
- return manifestVariables[name] || {};
643
+ return `${encodeString(name)}-${generateUUID()}-${time}`;
632
644
  };
633
645
 
634
- let stubs = [];
635
- const addStubs = (newStubs) => {
636
- stubs = [...stubs, ...newStubs];
646
+ const getCookieValue = (key) => {
647
+ try {
648
+ if (!document || !document.cookie) {
649
+ return '';
650
+ }
651
+ const name = `${key}=`;
652
+ const decodedCookie = decodeURIComponent(document.cookie);
653
+ const ca = decodedCookie.split(';');
654
+ for (let i = 0; i < ca.length; i++) {
655
+ let c = ca[i];
656
+ while (c.charAt(0) === ' ') {
657
+ c = c.substring(1);
658
+ }
659
+ if (c.indexOf(name) === 0) {
660
+ return c.substring(name.length, c.length);
661
+ }
662
+ }
663
+ return '';
664
+ }
665
+ catch {
666
+ return '';
667
+ }
637
668
  };
638
- const addStub = (stub) => {
639
- stubs.push(stub);
669
+
670
+ const getConsent$1 = (destination) => {
671
+ const storageConsent = getDataPerKey(destination, 'local', tagStorage, consentKey);
672
+ if (storageConsent) {
673
+ return storageConsent;
674
+ }
675
+ return getSetting(destination, 'consent');
640
676
  };
641
- const processStubs = () => {
677
+
678
+ const processStubs = (destination) => {
642
679
  try {
680
+ const stubs = getSetting(destination, 'stubs');
643
681
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
644
682
  // @ts-ignore
645
683
  stubs.forEach((stub) => api[stub.name](...(stub.arguments || [])));
646
- stubs = [];
684
+ setSetting({
685
+ stubs: [],
686
+ }, destination);
647
687
  }
648
688
  catch (e) {
649
689
  error(e);
650
690
  }
651
691
  };
692
+ const addStub = (destination, stub) => {
693
+ const otherStubs = getSetting(destination, 'stubs') || [];
694
+ setSetting({
695
+ stubs: [...otherStubs, stub],
696
+ }, destination);
697
+ };
652
698
 
653
- const sendTag = ({ eventName, eventId, data, providerData, providers, options, }) => {
699
+ const sendTag = (destination, { eventName, eventId, data, providerData, providers, options }) => {
654
700
  const payload = {
655
701
  eventName,
656
702
  eventId,
@@ -661,11 +707,11 @@ const sendTag = ({ eventName, eventId, data, providerData, providers, options, }
661
707
  if (providers) {
662
708
  payload.providers = providers;
663
709
  }
664
- postRequest(getTagURL(options), payload, options).catch(error);
710
+ postRequest(getTagURL(destination, options), payload, options).catch(error);
665
711
  };
666
- const handleTag = (eventName, data = {}, providers, options) => {
667
- if (!isInitialized()) {
668
- addStub({
712
+ const processTag = (destination, eventName, data = {}, providers, options) => {
713
+ if (!getSetting(destination, 'initialized')) {
714
+ addStub(destination, {
669
715
  name: 'tag',
670
716
  arguments: [eventName, data, providers, options],
671
717
  });
@@ -675,11 +721,11 @@ const handleTag = (eventName, data = {}, providers, options) => {
675
721
  if (!eventId) {
676
722
  eventId = generateEventId(eventName);
677
723
  }
678
- const providerPackages = getProvidersPackage();
679
- const configuredTags = getConfiguredTags();
680
- const userId = handleGetUserId();
724
+ const providerPackages = getProvidersPackage(destination);
725
+ const configuredTags = getSetting(destination, 'channels');
726
+ const userId = getUserId$1(destination);
681
727
  const providerData = {};
682
- const consent = getConsent$1();
728
+ const consent = getConsent$1(destination);
683
729
  for (const pkg of Object.values(providerPackages)) {
684
730
  if (!pkg || !pkg.name || !pkg.tag) {
685
731
  continue;
@@ -688,26 +734,25 @@ const handleTag = (eventName, data = {}, providers, options) => {
688
734
  log(`Provider ${pkg.name} is not in allow list`);
689
735
  continue;
690
736
  }
691
- const variables = getProviderVariables(pkg.name);
737
+ const variables = getProviderVariables(destination, pkg.name);
692
738
  const result = {};
693
- const providerVariables = Object.entries(variables);
694
739
  const executionContext = new Map();
695
- for (const [tagName, variableSet] of providerVariables) {
696
- if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
697
- log(`Provider instance is not allowed (${pkg.name}: ${tagName})`);
740
+ for (const variable of variables) {
741
+ if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
742
+ log(`Provider instance is not allowed (${pkg.name}: ${variable.tagName})`);
698
743
  continue;
699
744
  }
700
- if (!hasUserConsent(consent, pkg.name, tagName)) {
701
- log(`Consent is missing (${pkg.name}: ${tagName})`);
745
+ if (!hasUserConsent(consent, pkg.name, variable.tagName)) {
746
+ log(`Consent is missing (${pkg.name}: ${variable.tagName})`);
702
747
  continue;
703
748
  }
704
- result[tagName] = pkg.tag({
749
+ result[variable.tagName] = pkg.tag({
705
750
  userId,
706
751
  eventName,
707
752
  eventId,
708
753
  data: JSON.parse(JSON.stringify(data)),
709
- sendTag,
710
- manifestVariables: variableSet,
754
+ sendTag: sendTag.bind(null, destination),
755
+ manifestVariables: variable.variableSet,
711
756
  executionContext,
712
757
  });
713
758
  }
@@ -716,7 +761,7 @@ const handleTag = (eventName, data = {}, providers, options) => {
716
761
  if (!hasAllowedManifestTags(configuredTags, consent, providers)) {
717
762
  return;
718
763
  }
719
- sendTag({
764
+ sendTag(destination, {
720
765
  eventName,
721
766
  eventId,
722
767
  data,
@@ -725,6 +770,15 @@ const handleTag = (eventName, data = {}, providers, options) => {
725
770
  options,
726
771
  });
727
772
  };
773
+ const handleTag = (eventName, data = {}, providers, options) => {
774
+ if (options === null || options === void 0 ? void 0 : options.destination) {
775
+ processTag(options.destination, eventName, data, providers, options);
776
+ return;
777
+ }
778
+ getInstances().forEach((instance) => {
779
+ processTag(instance, eventName, data, providers, options);
780
+ });
781
+ };
728
782
  const hasAllowedManifestTags = (tags, consent, providersConfig) => {
729
783
  for (const [pkg, tagNames] of tags) {
730
784
  for (const tagName of tagNames) {
@@ -737,28 +791,37 @@ const hasAllowedManifestTags = (tags, consent, providersConfig) => {
737
791
  return false;
738
792
  };
739
793
 
740
- const handleGetData = (keys, callback) => {
741
- if (!keys || keys.length === 0) {
742
- error('Provide keys for get data API.');
743
- return;
744
- }
745
- getRequest(getGetDataURL(keys))
794
+ const processGetData = (destination, keys, callback) => {
795
+ getRequest(getGetDataURL(destination, keys))
746
796
  .then((result) => {
747
797
  callback((result === null || result === void 0 ? void 0 : result.result) || {});
748
798
  })
749
799
  .catch(error);
750
800
  };
751
-
752
- const handleData = (data, providers, options) => {
753
- if (!data || Object.keys(data).length === 0) {
754
- error('Provide data for data API.');
801
+ const handleGetData = (keys, callback, options) => {
802
+ if (!keys || keys.length === 0) {
803
+ error('Provide keys for get data API.');
804
+ return;
805
+ }
806
+ if (options === null || options === void 0 ? void 0 : options.destination) {
807
+ processGetData(options.destination, keys, callback);
808
+ return;
809
+ }
810
+ const instances = getInstances();
811
+ if (instances.length > 1) {
812
+ error('Multiple instances found! Please provide destination.');
813
+ callback({});
755
814
  return;
756
815
  }
757
- saveKV(data);
758
- const providerPackages = getProvidersPackage();
759
- const configuredTags = getConfiguredTags();
760
- const userId = handleGetUserId();
761
- const consent = getConsent$1();
816
+ processGetData(instances[0], keys, callback);
817
+ };
818
+
819
+ const processData = (destination, data, providers, options) => {
820
+ saveKV(destination, data);
821
+ const providerPackages = getProvidersPackage(destination);
822
+ const configuredTags = getSetting(destination, 'channels');
823
+ const userId = getUserId$1(destination);
824
+ const consent = getConsent$1(destination);
762
825
  for (const pkg of Object.values(providerPackages)) {
763
826
  if (!pkg || !pkg.user || !pkg.name) {
764
827
  continue;
@@ -767,70 +830,92 @@ const handleData = (data, providers, options) => {
767
830
  log(`Provider ${pkg.name} is not in allow list`);
768
831
  continue;
769
832
  }
770
- const variables = getProviderVariables(pkg.name);
771
- for (const [tagName, variableSet] of Object.entries(variables)) {
772
- if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
773
- log(`Data not allowed for ${pkg.name} (${tagName})`);
833
+ const variables = getProviderVariables(destination, pkg.name);
834
+ for (const variable of variables) {
835
+ if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
836
+ log(`Data not allowed for ${pkg.name} (${variable.tagName})`);
774
837
  continue;
775
838
  }
776
- if (!hasUserConsent(consent, pkg.name, tagName)) {
777
- log(`Consent is missing for ${pkg.name} (${tagName})`);
839
+ if (!hasUserConsent(consent, pkg.name, variable.tagName)) {
840
+ log(`Consent is missing for ${pkg.name} (${variable.tagName})`);
778
841
  continue;
779
842
  }
780
843
  pkg.user({
781
844
  userId,
782
845
  data,
783
- manifestVariables: variableSet,
846
+ manifestVariables: variable.variableSet,
784
847
  });
785
848
  }
786
849
  }
787
- postRequest(getDataURL(), { data, providers }, options).catch(error);
850
+ postRequest(getDataURL(destination), { data, providers }, options).catch(error);
788
851
  };
789
-
790
- let memoryConsent;
791
- const saveConsent = (consent) => {
792
- setConsent(consent);
793
- savePerKey('local', tagStorage, consent, consentKey);
852
+ const handleData = (data, providers, options) => {
853
+ if (!data || Object.keys(data).length === 0) {
854
+ error('Provide data for data API.');
855
+ return;
856
+ }
857
+ if (options === null || options === void 0 ? void 0 : options.destination) {
858
+ processData(options.destination, data, providers, options);
859
+ return;
860
+ }
861
+ getInstances().forEach((destination) => {
862
+ processData(destination, data, providers, options);
863
+ });
794
864
  };
865
+
795
866
  const handleConsent = (consent, options) => {
796
- const existingConsent = getConsent$1();
867
+ if (options === null || options === void 0 ? void 0 : options.destination) {
868
+ processConsent(options.destination, consent, options === null || options === void 0 ? void 0 : options.localSave);
869
+ return;
870
+ }
871
+ getInstances().forEach((destination) => {
872
+ processConsent(destination, consent, options === null || options === void 0 ? void 0 : options.localSave);
873
+ });
874
+ };
875
+ const saveConsent = (destination, consent) => {
876
+ setSetting({
877
+ consent,
878
+ }, destination);
879
+ savePerKey(destination, 'local', tagStorage, consent, consentKey);
880
+ };
881
+ const processConsent = (destination, consent, localSave) => {
882
+ const existingConsent = getConsent$1(destination);
797
883
  if (areEqual(existingConsent, consent)) {
798
884
  return;
799
885
  }
800
886
  const payload = {
801
887
  consentString: consent,
802
888
  };
803
- saveConsent(consent);
804
- if (!(options === null || options === void 0 ? void 0 : options.localSave)) {
805
- postRequest(getConsentURL(), payload).catch(error);
889
+ saveConsent(destination, consent);
890
+ if (!localSave) {
891
+ postRequest(getConsentURL(destination), payload).catch(error);
806
892
  }
807
- const userId = handleGetUserId();
808
- const providerPackages = getProvidersPackage();
893
+ const userId = getUserId$1(destination);
894
+ const providerPackages = getProvidersPackage(destination);
809
895
  const executionContext = new Map();
810
896
  /* Calling Init for all provider instances based on consent check */
811
897
  for (const pkg of Object.values(providerPackages)) {
812
898
  if (!pkg || !pkg.name || !pkg.init) {
813
899
  continue;
814
900
  }
815
- const variables = getProviderVariables(pkg.name);
816
- const providerVariables = Object.entries(variables);
817
- for (const [tagName, variablesSet] of providerVariables) {
818
- const hasConsent = hasUserConsent(consent, pkg.name, tagName);
901
+ const variables = getProviderVariables(destination, pkg.name);
902
+ for (const variable of variables) {
903
+ const hasConsent = hasUserConsent(consent, pkg.name, variable.tagName);
819
904
  if (!hasConsent) {
820
905
  continue;
821
906
  }
822
907
  pkg.init({
823
908
  userId,
824
909
  isNewUser: false,
825
- baseUrl: getUrl(),
910
+ baseUrl: destination,
826
911
  manifest: {
827
- tagName,
828
- variables: variablesSet,
912
+ tagName: variable.tagName,
913
+ variables: variable.variableSet,
829
914
  package: pkg.name,
830
915
  },
831
- sendTag,
832
- sendEdgeData: handleData,
833
- getEdgeData: handleGetData,
916
+ sendTag: sendTag.bind(null, destination),
917
+ sendEdgeData: processData.bind(null, destination),
918
+ getEdgeData: processGetData.bind(null, destination),
834
919
  keyName: `${keyPrefix}Store`,
835
920
  executionContext,
836
921
  session: null,
@@ -840,6 +925,7 @@ const handleConsent = (consent, options) => {
840
925
  try {
841
926
  window.dispatchEvent(new CustomEvent('edgetag-consent', {
842
927
  detail: {
928
+ destination,
843
929
  oldConsent: existingConsent,
844
930
  newConsent: consent,
845
931
  },
@@ -858,20 +944,10 @@ const handleConsent = (consent, options) => {
858
944
  pkg.consent({ hasConsent });
859
945
  }
860
946
  };
861
- const setConsent = (newConsent) => {
862
- memoryConsent = newConsent;
863
- };
864
- const getConsent$1 = () => {
865
- const storageConsent = getDataPerKey('local', tagStorage, consentKey);
866
- if (storageConsent) {
867
- return storageConsent;
868
- }
869
- return memoryConsent;
870
- };
871
947
 
872
948
  const cacheKey = `${keyPrefix}Cache`;
873
949
  const identity = (v) => v;
874
- const saveDataToEdge = (key, value, provider) => {
950
+ const saveDataToEdge = (destination, key, value, provider) => {
875
951
  if (!value) {
876
952
  return;
877
953
  }
@@ -885,9 +961,11 @@ const saveDataToEdge = (key, value, provider) => {
885
961
  return;
886
962
  }
887
963
  }
888
- handleData({ [`${provider}::${key}`]: updatedValue });
964
+ handleData({ [`${provider}::${key}`]: updatedValue }, undefined, {
965
+ destination,
966
+ });
889
967
  };
890
- const handleCaptureQuery = (provider, key, persistType, map) => {
968
+ const handleCaptureQuery = (destination, provider, key, persistType, map) => {
891
969
  try {
892
970
  if (!window) {
893
971
  return;
@@ -896,7 +974,7 @@ const handleCaptureQuery = (provider, key, persistType, map) => {
896
974
  catch {
897
975
  return;
898
976
  }
899
- const params = new URLSearchParams(getSearch());
977
+ const params = new URLSearchParams(getSearch(destination));
900
978
  if (!params || !params.get(key)) {
901
979
  return;
902
980
  }
@@ -905,27 +983,29 @@ const handleCaptureQuery = (provider, key, persistType, map) => {
905
983
  return;
906
984
  }
907
985
  if (persistType === 'edge') {
908
- saveDataToEdge(key, data, provider);
986
+ saveDataToEdge(destination, key, data, provider);
909
987
  return;
910
988
  }
911
- saveDataPerKey(persistType, provider, data, key);
989
+ saveDataPerKey(destination, persistType, provider, data, key);
912
990
  };
913
- const getFromCache = (persistType, provider, key) => {
991
+ const getFromCache = (destination, persistType, provider, key) => {
914
992
  var _a;
915
- const cache = getData$1(persistType === 'edge' ? 'local' : persistType, cacheKey);
993
+ const type = persistType === 'edge' ? 'local' : persistType;
994
+ const cache = getData$1(destination, type, cacheKey);
916
995
  return (_a = cache[provider]) === null || _a === void 0 ? void 0 : _a[key];
917
996
  };
918
- const saveToCache = (persistType, provider, key, value) => {
919
- const cache = getData$1(persistType === 'edge' ? 'local' : persistType, cacheKey);
997
+ const saveToCache = (destination, persistType, provider, key, value) => {
998
+ const type = persistType === 'edge' ? 'local' : persistType;
999
+ const cache = getData$1(destination, type, cacheKey);
920
1000
  if (!cache[provider]) {
921
1001
  cache[provider] = { [key]: value };
922
1002
  }
923
1003
  else {
924
1004
  cache[provider][key] = value;
925
1005
  }
926
- saveData(persistType === 'edge' ? 'local' : persistType, cache, cacheKey);
1006
+ saveData(destination, type, cache, cacheKey);
927
1007
  };
928
- const handleCaptureStorage = (provider, key, persistType, location, map) => {
1008
+ const handleCaptureStorage = (destination, provider, key, persistType, location, map) => {
929
1009
  let data;
930
1010
  try {
931
1011
  switch (location) {
@@ -948,44 +1028,43 @@ const handleCaptureStorage = (provider, key, persistType, location, map) => {
948
1028
  if (!data) {
949
1029
  return;
950
1030
  }
951
- const cachedKey = `${handleGetUserId()}/${key}`;
952
- const cachedValue = getFromCache(persistType, provider, cachedKey);
1031
+ const cachedKey = `${getUserId$1(destination)}/${key}`;
1032
+ const cachedValue = getFromCache(destination, persistType, provider, cachedKey);
953
1033
  if (persistType === 'edge' && cachedValue !== data) {
954
- saveDataToEdge(key, data, provider);
955
- saveToCache(persistType, provider, cachedKey, data);
1034
+ saveDataToEdge(destination, key, data, provider);
1035
+ saveToCache(destination, persistType, provider, cachedKey, data);
956
1036
  return;
957
1037
  }
958
- saveDataPerKey(persistType, provider, data, key);
1038
+ saveDataPerKey(destination, persistType, provider, data, key);
959
1039
  };
960
- const handleCapture = (provider, params, capture) => {
1040
+ const handleCapture = (destination, provider, params, capture) => {
961
1041
  params.forEach((param) => {
962
1042
  switch (param.type) {
963
1043
  case 'query': {
964
- handleCaptureQuery(provider, param.key, param.persist, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
1044
+ handleCaptureQuery(destination, provider, param.key, param.persist, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
965
1045
  break;
966
1046
  }
967
1047
  case 'storage': {
968
- handleCaptureStorage(provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
1048
+ handleCaptureStorage(destination, provider, param.key, param.persist, param.location, capture === null || capture === void 0 ? void 0 : capture.bind(null, param));
969
1049
  break;
970
1050
  }
971
1051
  }
972
1052
  });
973
1053
  };
974
1054
 
975
- const handleManifest = (response, consent) => {
976
- const providerPackages = getProvidersPackage();
977
- const userId = handleGetUserId();
1055
+ const handleManifest = (destination, response) => {
1056
+ const providerPackages = getProvidersPackage(destination);
1057
+ const userId = getUserId$1(destination);
978
1058
  const executionContext = new Map();
979
1059
  const manifest = response.result;
980
1060
  manifest.forEach((provider) => {
981
- addConfiguredTag(provider.package, provider.tagName);
982
- addProviderVariable(provider.package, provider.variables, provider.tagName);
1061
+ addChannel(destination, provider.package, provider.tagName);
983
1062
  const pkg = providerPackages[provider.package];
984
1063
  if (provider.rules) {
985
1064
  Object.entries(provider.rules).forEach(([name, recipe]) => {
986
1065
  switch (name) {
987
1066
  case 'capture': {
988
- handleCapture(provider.package, recipe, pkg === null || pkg === void 0 ? void 0 : pkg.capture);
1067
+ handleCapture(destination, provider.package, recipe, pkg === null || pkg === void 0 ? void 0 : pkg.capture);
989
1068
  return;
990
1069
  }
991
1070
  }
@@ -993,36 +1072,27 @@ const handleManifest = (response, consent) => {
993
1072
  }
994
1073
  if (pkg && pkg.name && pkg.init) {
995
1074
  /* this defines if the consent is given for a specific instance of a provider */
996
- const hasConsent = hasUserConsent(consent, pkg.name, provider.tagName);
1075
+ const hasConsent = hasUserConsent(getSetting(destination, 'consent'), pkg.name, provider.tagName);
997
1076
  if (hasConsent) {
998
1077
  pkg.init({
999
1078
  userId,
1000
1079
  isNewUser: !!response.isNewUser,
1001
1080
  session: response.session,
1002
- baseUrl: getUrl(),
1081
+ baseUrl: destination,
1003
1082
  manifest: provider,
1004
- sendTag,
1005
- sendEdgeData: handleData,
1006
- getEdgeData: handleGetData,
1083
+ sendTag: sendTag.bind(null, destination),
1084
+ sendEdgeData: processData.bind(null, destination),
1085
+ getEdgeData: processGetData.bind(null, destination),
1007
1086
  keyName: `${keyPrefix}Store`,
1008
1087
  executionContext,
1009
1088
  });
1010
1089
  }
1011
1090
  }
1012
1091
  });
1013
- setInitialized();
1014
- processStubs();
1015
- };
1016
-
1017
- let initIsNewUser = undefined;
1018
- const handleIsNewUser = () => {
1019
- if (initIsNewUser !== undefined) {
1020
- return initIsNewUser;
1021
- }
1022
- return undefined;
1023
- };
1024
- const setIsNewUSer = (isNewUser) => {
1025
- initIsNewUser = isNewUser;
1092
+ setSetting({
1093
+ initialized: true,
1094
+ }, destination);
1095
+ processStubs(destination);
1026
1096
  };
1027
1097
 
1028
1098
  const handleInit = (preferences) => {
@@ -1031,15 +1101,17 @@ const handleInit = (preferences) => {
1031
1101
  return;
1032
1102
  }
1033
1103
  if (preferences.afterManifestEvents) {
1034
- addStubs(preferences.afterManifestEvents);
1104
+ setSetting({
1105
+ stubs: preferences.afterManifestEvents,
1106
+ }, preferences.edgeURL);
1035
1107
  }
1036
- const url = new URL(getInitURL());
1108
+ const url = new URL(getInitURL(preferences.edgeURL));
1037
1109
  if (preferences.disableConsentCheck) {
1038
1110
  url.searchParams.set('consentDisabled', 'true');
1039
- saveConsent({ all: true });
1111
+ saveConsent(preferences.edgeURL, { all: true });
1040
1112
  }
1041
1113
  if (preferences.userId) {
1042
- setUserId(preferences.userId);
1114
+ setSetting({ userId: preferences.userId }, preferences.edgeURL);
1043
1115
  url.searchParams.set('userId', preferences.userId);
1044
1116
  }
1045
1117
  getRequest(url.href)
@@ -1048,18 +1120,17 @@ const handleInit = (preferences) => {
1048
1120
  error('Initialization failed');
1049
1121
  return;
1050
1122
  }
1051
- if (result.userId) {
1052
- setUserId(result.userId);
1053
- }
1054
- const consent = getConsent$1();
1055
- if (result.consent && !consent) {
1056
- saveConsent(result.consent);
1057
- }
1058
- setIsNewUSer(result.isNewUser);
1059
- handleManifest(result, consent || result.consent);
1123
+ setSetting({
1124
+ isNewUser: result.isNewUser,
1125
+ consent: getConsent$1(preferences.edgeURL) || result.consent,
1126
+ userId: result.userId,
1127
+ packages: result.result,
1128
+ }, preferences.edgeURL);
1129
+ handleManifest(preferences.edgeURL, result);
1060
1130
  try {
1061
1131
  window.dispatchEvent(new CustomEvent('edgetag-initialized', {
1062
1132
  detail: {
1133
+ destination: preferences.edgeURL,
1063
1134
  userId: result.userId,
1064
1135
  isNewUser: result.isNewUser,
1065
1136
  consent: result.consent,
@@ -1075,18 +1146,14 @@ const handleInit = (preferences) => {
1075
1146
  .catch(error);
1076
1147
  };
1077
1148
 
1078
- const handleUser = (key, value, providers, options) => {
1079
- if (!key || !value) {
1080
- error('Key or Value is missing in user API.');
1081
- return;
1082
- }
1083
- saveKV({
1149
+ const processUser = (destination, key, value, providers, options) => {
1150
+ saveKV(destination, {
1084
1151
  [key]: value,
1085
1152
  });
1086
- const providerPackages = getProvidersPackage();
1087
- const configuredTags = getConfiguredTags();
1088
- const consent = getConsent$1();
1089
- const userId = handleGetUserId();
1153
+ const providerPackages = getProvidersPackage(destination);
1154
+ const configuredTags = getSetting(destination, 'channels');
1155
+ const consent = getConsent$1(destination);
1156
+ const userId = getUserId$1(destination);
1090
1157
  for (const pkg of Object.values(providerPackages)) {
1091
1158
  if (!pkg || !pkg.name || !pkg.user) {
1092
1159
  continue;
@@ -1095,47 +1162,73 @@ const handleUser = (key, value, providers, options) => {
1095
1162
  log(`Provider ${pkg.name} is not in allow list`);
1096
1163
  continue;
1097
1164
  }
1098
- const variables = getProviderVariables(pkg.name);
1099
- for (const [tagName, variableSet] of Object.entries(variables)) {
1100
- if (!isProviderInstanceAllowed(providers, pkg.name, tagName)) {
1101
- log(`User not allowed for ${pkg.name} (${tagName})`);
1165
+ const variables = getProviderVariables(destination, pkg.name);
1166
+ for (const variable of variables) {
1167
+ if (!isProviderInstanceAllowed(providers, pkg.name, variable.tagName)) {
1168
+ log(`User not allowed for ${pkg.name} (${variable.tagName})`);
1102
1169
  continue;
1103
1170
  }
1104
- if (!hasUserConsent(consent, pkg.name, tagName)) {
1105
- log(`User doesn't have consent for ${pkg.name} (${tagName})`);
1171
+ if (!hasUserConsent(consent, pkg.name, variable.tagName)) {
1172
+ log(`User doesn't have consent for ${pkg.name} (${variable.tagName})`);
1106
1173
  continue;
1107
1174
  }
1108
1175
  pkg.user({
1109
1176
  userId,
1110
1177
  data: { [key]: value },
1111
- manifestVariables: variableSet,
1178
+ manifestVariables: variable.variableSet,
1112
1179
  });
1113
1180
  }
1114
1181
  }
1115
- postRequest(getUserURL(), {
1182
+ postRequest(getUserURL(destination), {
1116
1183
  key,
1117
1184
  value,
1118
1185
  providers,
1119
1186
  }, options).catch(error);
1120
1187
  };
1188
+ const handleUser = (key, value, providers, options) => {
1189
+ if (!key || !value) {
1190
+ error('Key or Value is missing in user API.');
1191
+ return;
1192
+ }
1193
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1194
+ processUser(options.destination, key, value, providers, options);
1195
+ return;
1196
+ }
1197
+ getInstances().forEach((destination) => {
1198
+ processUser(destination, key, value, providers, options);
1199
+ });
1200
+ };
1121
1201
 
1122
- const handleKeys = (callback) => {
1123
- getRequest(getKeysURL())
1202
+ const processKeys = (destination, callback) => {
1203
+ getRequest(getKeysURL(destination))
1124
1204
  .then((result) => {
1125
1205
  callback((result === null || result === void 0 ? void 0 : result.result) || []);
1126
1206
  })
1127
1207
  .catch(error);
1128
1208
  };
1209
+ const handleKeys = (callback, options) => {
1210
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1211
+ processKeys(options.destination, callback);
1212
+ return;
1213
+ }
1214
+ const instances = getInstances();
1215
+ if (instances.length > 1) {
1216
+ error('Multiple instances found! Please provide destination.');
1217
+ callback([]);
1218
+ return;
1219
+ }
1220
+ processKeys(instances[0], callback);
1221
+ };
1129
1222
 
1130
- const handleGetConsent = (callback) => {
1131
- getRequest(getConsentURL())
1223
+ const processGetConsent = (destination, callback) => {
1224
+ getRequest(getConsentURL(destination))
1132
1225
  .then((result) => {
1133
1226
  // this will try to return the consent data stored in Edge
1134
1227
  return result === null || result === void 0 ? void 0 : result.result;
1135
1228
  })
1136
1229
  .catch(() => undefined)
1137
1230
  .then((result) => {
1138
- const consent = result !== null && result !== void 0 ? result : getConsent$1(); // this is a default value i.e. value from local storage and memory incase Edge doesn't have consent
1231
+ const consent = result !== null && result !== void 0 ? result : getConsent$1(destination); // this is a default value i.e. value from local storage and memory incase Edge doesn't have consent
1139
1232
  if (consent) {
1140
1233
  callback(consent);
1141
1234
  }
@@ -1144,9 +1237,48 @@ const handleGetConsent = (callback) => {
1144
1237
  }
1145
1238
  });
1146
1239
  };
1240
+ const handleGetConsent = (callback, options) => {
1241
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1242
+ processGetConsent(options.destination, callback);
1243
+ return;
1244
+ }
1245
+ const instances = getInstances();
1246
+ if (instances.length > 1) {
1247
+ callback(null, new Error('Multiple instances found! Please provide destination.'));
1248
+ return;
1249
+ }
1250
+ processGetConsent(instances[0], callback);
1251
+ };
1147
1252
 
1148
- const handleConfig = (config) => {
1149
- setConfig$1(config);
1253
+ const handleIsNewUser = (options) => {
1254
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1255
+ return getSetting(options.destination, 'isNewUser');
1256
+ }
1257
+ const instances = getInstances();
1258
+ if (instances.length > 1) {
1259
+ error('Multiple instances found! Please provide destination.');
1260
+ return undefined;
1261
+ }
1262
+ return getSetting(instances[0], 'isNewUser');
1263
+ };
1264
+
1265
+ const processConfig = (destination, config) => {
1266
+ const existingConfig = getSetting(destination, 'config');
1267
+ setSetting({
1268
+ config: {
1269
+ ...existingConfig,
1270
+ ...config,
1271
+ },
1272
+ }, destination);
1273
+ };
1274
+ const handleConfig = (config, options) => {
1275
+ if (options === null || options === void 0 ? void 0 : options.destination) {
1276
+ processConfig(options.destination, config);
1277
+ return;
1278
+ }
1279
+ getInstances().forEach((destination) => {
1280
+ processConfig(destination, config);
1281
+ });
1150
1282
  };
1151
1283
 
1152
1284
  const init = (preferences) => {
@@ -1164,23 +1296,23 @@ const user = (key, value, providers, options) => {
1164
1296
  const data = (value, providers, options) => {
1165
1297
  handleData(value, providers, options);
1166
1298
  };
1167
- const getData = (keys, callback) => {
1168
- handleGetData(keys, callback);
1299
+ const getData = (keys, callback, options) => {
1300
+ handleGetData(keys, callback, options);
1169
1301
  };
1170
- const keys = (callback) => {
1171
- handleKeys(callback);
1302
+ const keys = (callback, options) => {
1303
+ handleKeys(callback, options);
1172
1304
  };
1173
- const getUserId = () => {
1174
- return handleGetUserId();
1305
+ const getUserId = (options) => {
1306
+ return handleGetUserId(options);
1175
1307
  };
1176
- const getConsent = (callback) => {
1177
- handleGetConsent(callback);
1308
+ const getConsent = (callback, options) => {
1309
+ handleGetConsent(callback, options);
1178
1310
  };
1179
- const isNewUser = () => {
1180
- return handleIsNewUser();
1311
+ const isNewUser = (options) => {
1312
+ return handleIsNewUser(options);
1181
1313
  };
1182
- const setConfig = (config) => {
1183
- return handleConfig(config);
1314
+ const setConfig = (config, options) => {
1315
+ handleConfig(config, options);
1184
1316
  };
1185
1317
 
1186
1318
  export { consent, data, getConsent, getData, getUserId, init, isNewUser, keys, setConfig, tag, user };