@jitsu/js 1.0.0-canary-20230211030946 → 1.0.0-canary-20230219230011

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/dist/web/p.js.txt CHANGED
@@ -68,7 +68,151 @@
68
68
  return ke(_objectSpread2(_objectSpread2({}, defaultSettings), opts));
69
69
  }
70
70
 
71
+ var __awaiter$1 = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
72
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
73
+ return new (P || (P = Promise))(function (resolve, reject) {
74
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
75
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
76
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
77
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
78
+ });
79
+ };
80
+ function satisfyFilter(filter, subject) {
81
+ return filter === "*" || filter.toLowerCase().trim() === (subject || "").trim().toLowerCase();
82
+ }
83
+ function applyFilters(event, creds) {
84
+ const { hosts = ["*"], events = ["*"] } = creds;
85
+ return (!!hosts.find(hostFilter => { var _a; return satisfyFilter(hostFilter, (_a = event.context) === null || _a === void 0 ? void 0 : _a.host); }) &&
86
+ !!events.find(eventFilter => satisfyFilter(eventFilter, event.type)));
87
+ }
88
+ const tagPlugin = {
89
+ id: "tag",
90
+ handle(config, payload) {
91
+ return __awaiter$1(this, void 0, void 0, function* () {
92
+ if (!applyFilters(payload, config)) {
93
+ return;
94
+ }
95
+ insertTags(config.code, payload);
96
+ });
97
+ },
98
+ };
99
+ function insertTags(code, event, opts = {}) {
100
+ let tag;
101
+ try {
102
+ tag = JSON.parse(code);
103
+ }
104
+ catch (e) {
105
+ tag = { code, lang: "javascript" };
106
+ }
107
+ const debug = opts.debug || false;
108
+ if (isInBrowser()) {
109
+ if (tag.lang === "javascript") {
110
+ execJs(tag.code, event);
111
+ }
112
+ else {
113
+ const codeHolder = document.createElement("span");
114
+ codeHolder.innerHTML = replaceMacro(tag.code, event);
115
+ document.body.insertAdjacentElement("beforeend", codeHolder);
116
+ const scripts = codeHolder.querySelectorAll("script");
117
+ scripts.forEach(script => {
118
+ const scriptClone = document.createElement("script");
119
+ scriptClone.type = scriptClone.type || "text/javascript";
120
+ if (script.hasAttribute("src")) {
121
+ scriptClone.src = script.src;
122
+ }
123
+ scriptClone.text = script.text;
124
+ if (debug) {
125
+ console.log(`[JITSU] Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
126
+ }
127
+ document.head.appendChild(scriptClone);
128
+ document.head.removeChild(scriptClone);
129
+ });
130
+ }
131
+ }
132
+ else {
133
+ if (debug) {
134
+ console.log(`[JITSU] insertTags(): cannot insert tags in non-browser environment`);
135
+ }
136
+ }
137
+ }
138
+ function execJs(code, event) {
139
+ const varName = `jitsu_event_${randomId()}`;
140
+ window[varName] = event;
141
+ const iif = `(function(){
142
+ const event = ${varName};
143
+ ${code}
144
+ })()`;
145
+ try {
146
+ eval(iif);
147
+ }
148
+ catch (e) {
149
+ console.error(`[JITSU] Error executing JS code: ${e.message}. Code: `, iif);
150
+ }
151
+ finally {
152
+ delete window[varName];
153
+ }
154
+ return iif;
155
+ }
156
+ function replaceMacro(code, event) {
157
+ return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
158
+ }
159
+ const internalDestinationPlugins = {
160
+ [tagPlugin.id]: tagPlugin,
161
+ };
162
+
163
+ function findScript(src) {
164
+ const scripts = Array.prototype.slice.call(window.document.querySelectorAll("script"));
165
+ return scripts.find(s => s.src === src);
166
+ }
167
+ function loadScript(src, attributes) {
168
+ const found = findScript(src);
169
+ if (found !== undefined) {
170
+ const status = found === null || found === void 0 ? void 0 : found.getAttribute("status");
171
+ if (status === "loaded") {
172
+ return Promise.resolve(found);
173
+ }
174
+ if (status === "loading") {
175
+ return new Promise((resolve, reject) => {
176
+ found.addEventListener("load", () => resolve(found));
177
+ found.addEventListener("error", err => reject(err));
178
+ });
179
+ }
180
+ }
181
+ return new Promise((resolve, reject) => {
182
+ var _a;
183
+ const script = window.document.createElement("script");
184
+ script.type = "text/javascript";
185
+ script.src = src;
186
+ script.async = true;
187
+ script.setAttribute("status", "loading");
188
+ for (const [k, v] of Object.entries(attributes !== null && attributes !== void 0 ? attributes : {})) {
189
+ script.setAttribute(k, v);
190
+ }
191
+ script.onload = () => {
192
+ script.onerror = script.onload = null;
193
+ script.setAttribute("status", "loaded");
194
+ resolve(script);
195
+ };
196
+ script.onerror = () => {
197
+ script.onerror = script.onload = null;
198
+ script.setAttribute("status", "error");
199
+ reject(new Error(`Failed to load ${src}`));
200
+ };
201
+ const tag = window.document.getElementsByTagName("script")[0];
202
+ (_a = tag.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(script, tag);
203
+ });
204
+ }
205
+
71
206
  /* global analytics */
207
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
208
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
209
+ return new (P || (P = Promise))(function (resolve, reject) {
210
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
211
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
212
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
213
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
214
+ });
215
+ };
72
216
  const config = {
73
217
  /* Your segment writeKey */
74
218
  writeKey: null,
@@ -280,7 +424,7 @@
280
424
  }, target);
281
425
  }
282
426
  function isInBrowser() {
283
- return typeof document !== "undefined";
427
+ return typeof document !== "undefined" && typeof window !== "undefined";
284
428
  }
285
429
  function adjustPayload(payload, config, storage) {
286
430
  var _a, _b;
@@ -318,62 +462,62 @@
318
462
  delete withContext.options;
319
463
  return withContext;
320
464
  }
321
- function execJs(code, event) {
322
- const varName = `jitsu_event_${randomId()}`;
323
- window[varName] = event;
324
- const iif = `(function(){
325
- ${code}
326
- onEvent(${varName});
327
- })()`;
328
- try {
329
- eval(iif);
330
- }
331
- catch (e) {
332
- console.error(`[JITSU] Error executing JS code: ${e.message}`);
333
- }
334
- finally {
335
- delete window[varName];
336
- }
337
- return iif;
338
- }
339
- function replaceMacro(code, event) {
340
- return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
341
- }
342
- function insertTags(tags, event, opts = {}) {
343
- const debug = opts.debug || false;
344
- if (isInBrowser()) {
345
- Object.values(tags).forEach(tag => {
346
- if (tag.mode === "javascript") {
347
- execJs(tag.code, event);
465
+ function processDestinations(destinations, method, event, debug, analyticsInstance) {
466
+ return __awaiter(this, void 0, void 0, function* () {
467
+ const promises = [];
468
+ for (const destination of destinations) {
469
+ if (destination.deviceOptions.type === "internal-plugin") {
470
+ const plugin = internalDestinationPlugins[destination.deviceOptions.name];
471
+ if (plugin) {
472
+ try {
473
+ promises.push(plugin.handle(destination.credentials, event));
474
+ }
475
+ catch (e) {
476
+ console.warn(`[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
477
+ }
478
+ }
479
+ else {
480
+ console.warn(`[JITSU] Unknown internal plugin '${destination.deviceOptions.name}' for destination '${destination.id}'`);
481
+ }
348
482
  }
349
- else {
350
- const codeHolder = document.createElement("span");
351
- codeHolder.innerHTML = replaceMacro(tag.code, event);
352
- document.body.insertAdjacentElement("beforeend", codeHolder);
353
- const scripts = codeHolder.querySelectorAll("script");
354
- scripts.forEach(script => {
355
- const scriptClone = document.createElement("script");
356
- scriptClone.type = scriptClone.type || "text/javascript";
357
- if (script.hasAttribute("src")) {
358
- scriptClone.src = script.src;
483
+ else if (destination.deviceOptions.type === "analytics-plugin") {
484
+ yield loadScript(destination.deviceOptions.packageCdn);
485
+ const plugin = window[destination.deviceOptions.moduleVarName];
486
+ if (!plugin) {
487
+ console.warn(`[JITSU] Broken plugin '${destination.deviceOptions.packageCdn}' for destination '${destination.id}' - it doesn't export '${destination.deviceOptions.moduleVarName}' variable`);
488
+ }
489
+ else {
490
+ let pluginInstance;
491
+ try {
492
+ pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(destination.credentials);
493
+ }
494
+ catch (e) {
495
+ console.warn(`[JITSU] Error creating plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
496
+ }
497
+ try {
498
+ if (debug) {
499
+ console.log(`[JITSU] Plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}' initialized with config:`, pluginInstance.config);
500
+ }
501
+ pluginInstance.initialize({ config: pluginInstance.config, instance: analyticsInstance });
359
502
  }
360
- scriptClone.text = script.text;
361
- if (debug) {
362
- console.log(`Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
503
+ catch (e) {
504
+ console.warn(`[JITSU] Error initializing plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e === null || e === void 0 ? void 0 : e.message}. Config: ${JSON.stringify(pluginInstance.config)}`, e);
505
+ continue;
363
506
  }
364
- document.head.appendChild(scriptClone);
365
- document.head.removeChild(scriptClone);
366
- });
507
+ if (pluginInstance[method]) {
508
+ try {
509
+ pluginInstance[method]({ payload: event, config: pluginInstance.config, instance: analyticsInstance });
510
+ }
511
+ catch (e) {
512
+ console.warn(`[JITSU] Error processing ${method}() with plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e === null || e === void 0 ? void 0 : e.message}`, e);
513
+ }
514
+ }
515
+ }
367
516
  }
368
- });
369
- }
370
- else {
371
- if (debug) {
372
- console.log(`insertTags: cannot insert tags in non-browser environment`);
373
517
  }
374
- }
518
+ });
375
519
  }
376
- function send(method, payload, jitsuConfig, store) {
520
+ function send(method, payload, jitsuConfig, instance, store) {
377
521
  if (jitsuConfig.echoEvents) {
378
522
  console.log(`[JITSU] sending '${method}' event:`, payload);
379
523
  return;
@@ -406,18 +550,19 @@
406
550
  }
407
551
  })
408
552
  .then(responseText => {
553
+ let response;
409
554
  try {
410
- const response = JSON.parse(responseText);
411
- if (response.tags) {
412
- if (jitsuConfig.debug) {
413
- console.log(`[JITSU] Response Tags: `, JSON.stringify(response.tags, null, 2));
414
- }
415
- insertTags(response.tags, payload, { debug: jitsuConfig.debug });
416
- }
555
+ response = JSON.parse(responseText);
417
556
  }
418
557
  catch (e) {
419
558
  return Promise.reject(`Can't parse JSON: ${responseText}: ${e === null || e === void 0 ? void 0 : e.message}`);
420
559
  }
560
+ if (response.destinations) {
561
+ if (jitsuConfig.debug) {
562
+ console.log(`[JITSU] Processing device destianations: `, JSON.stringify(response.destinations, null, 2));
563
+ }
564
+ return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
565
+ }
421
566
  })
422
567
  .catch(err => {
423
568
  if (jitsuConfig.debug) {
@@ -447,9 +592,9 @@
447
592
  name: "jitsu",
448
593
  config: Object.assign(Object.assign({}, config), pluginConfig),
449
594
  initialize: args => {
450
- const { config, instance } = args;
595
+ const { config } = args;
451
596
  if (config.debug) {
452
- console.debug("Initializing Jitsu plugin with config: ", JSON.stringify(config));
597
+ console.debug("[JITSU] Initializing Jitsu plugin with config: ", JSON.stringify(config));
453
598
  }
454
599
  if (!config.host && !config.echoEvents) {
455
600
  throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
@@ -457,17 +602,17 @@
457
602
  },
458
603
  page: args => {
459
604
  const { payload, config, instance } = args;
460
- return send("page", payload, config, cachingStorageWrapper(instance.storage));
605
+ return send("page", payload, config, instance, cachingStorageWrapper(instance.storage));
461
606
  },
462
607
  track: args => {
463
608
  const { payload, config, instance } = args;
464
- return send("track", payload, config, cachingStorageWrapper(instance.storage));
609
+ return send("track", payload, config, instance, cachingStorageWrapper(instance.storage));
465
610
  },
466
611
  identify: args => {
467
612
  const { payload, config, instance } = args;
468
613
  // Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
469
614
  storageCache["__user_traits"] = payload.traits;
470
- return send("identify", payload, config, cachingStorageWrapper(instance.storage));
615
+ return send("identify", payload, config, instance, cachingStorageWrapper(instance.storage));
471
616
  },
472
617
  reset: args => {
473
618
  //clear storage cache
@@ -520,13 +665,12 @@
520
665
  }
521
666
  return value;
522
667
  }
523
- function jitsuAnalytics(opts) {
524
- const rt = opts.runtime || (typeof window === "undefined" ? emptyRuntime(opts) : windowRuntime(opts));
668
+ function createUnderlyingAnalyticsInstance(opts, rt, plugins = []) {
525
669
  const analytics = analyticsLib({
526
670
  app: "test",
527
671
  debug: !!opts.debug,
528
672
  storage: rt.store(),
529
- plugins: [jitsuAnalyticsPlugin(opts)],
673
+ plugins: [jitsuAnalyticsPlugin(opts), ...plugins],
530
674
  });
531
675
  const originalPage = analytics.page;
532
676
  analytics.page = (...args) => {
@@ -539,6 +683,33 @@
539
683
  };
540
684
  return analytics;
541
685
  }
686
+ function jitsuAnalytics(opts) {
687
+ const inBrowser = isInBrowser();
688
+ const rt = opts.runtime || (inBrowser ? windowRuntime(opts) : emptyRuntime(opts));
689
+ return createUnderlyingAnalyticsInstance(opts, rt);
690
+ // if (inBrowser) {
691
+ // const fetch = opts.fetch || globalThis.fetch;
692
+ // if (!fetch) {
693
+ // throw new Error(
694
+ // "Please specify fetch function in jitsu plugin initialization, fetch isn't available in global scope"
695
+ // );
696
+ // }
697
+ // const url = `${opts.host}/api/s/cfg`;
698
+ // const authHeader = {};
699
+ // const debugHeader = opts.debug ? { "X-Enable-Debug": "true" } : {};
700
+ // fetch(url)
701
+ // .then(res => res.json())
702
+ // .then(res => {
703
+ // result.loaded(createUnderlyingAnalyticsInstance(opts, rt, []));
704
+ // })
705
+ // .catch(e => {
706
+ // console.warn(`[JITSU] error getting device-destinations from ${url}`, e);
707
+ // result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
708
+ // });
709
+ // } else {
710
+ // result.loaded(createUnderlyingAnalyticsInstance(opts, rt));
711
+ // }
712
+ }
542
713
 
543
714
  function snakeToCamel(s) {
544
715
  return s.replace(/([-_][a-z])/gi, $1 => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jitsu/js",
3
- "version": "1.0.0-canary-20230211030946",
3
+ "version": "1.0.0-canary-20230219230011",
4
4
  "description": "",
5
5
  "author": "Jitsu Dev Team <dev@jitsu.com>",
6
6
  "main": "dist/jitsu.cjs.js",
@@ -12,7 +12,7 @@
12
12
  "license": "MIT",
13
13
  "private": false,
14
14
  "devDependencies": {
15
- "@playwright/test": "^1.28.1",
15
+ "@playwright/test": "^1.30.0",
16
16
  "@rollup/plugin-commonjs": "^23.0.2",
17
17
  "@rollup/plugin-json": "^5.0.1",
18
18
  "@rollup/plugin-multi-entry": "^6.0.0",
@@ -35,8 +35,8 @@
35
35
  "ts-jest": "^29.0.3"
36
36
  },
37
37
  "dependencies": {
38
- "@jitsu/protocols": "0.0.0",
39
- "analytics": "^0.8.1"
38
+ "analytics": "^0.8.1",
39
+ "@jitsu/protocols": "0.0.0"
40
40
  },
41
41
  "scripts": {
42
42
  "clean": "rm -rf ./dist",
@@ -3,7 +3,9 @@
3
3
  import { JitsuOptions, PersistentStorage, RuntimeFacade } from "./jitsu";
4
4
  import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
5
5
  import parse from "./index";
6
- import { AnalyticsPlugin } from "analytics";
6
+ import { AnalyticsInstance, AnalyticsPlugin } from "analytics";
7
+ import { internalDestinationPlugins } from "./destination-plugins";
8
+ import { loadScript } from "./script-loader";
7
9
 
8
10
  const config: JitsuOptions = {
9
11
  /* Your segment writeKey */
@@ -238,8 +240,8 @@ function deepMerge(target: any, source: any) {
238
240
  }, target);
239
241
  }
240
242
 
241
- function isInBrowser() {
242
- return typeof document !== "undefined";
243
+ export function isInBrowser() {
244
+ return typeof document !== "undefined" && typeof window !== "undefined";
243
245
  }
244
246
 
245
247
  function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentStorage): AnalyticsClientEvent {
@@ -285,65 +287,107 @@ function adjustPayload(payload: any, config: JitsuOptions, storage: PersistentSt
285
287
  return withContext;
286
288
  }
287
289
 
288
- function execJs(code: string, event: any) {
289
- const varName = `jitsu_event_${randomId()}`;
290
- window[varName] = event;
291
- const iif = `(function(){
292
- ${code}
293
- onEvent(${varName});
294
- })()`;
295
- try {
296
- eval(iif);
297
- } catch (e) {
298
- console.error(`[JITSU] Error executing JS code: ${e.message}`);
299
- } finally {
300
- delete window[varName];
301
- }
302
- return iif;
303
- }
290
+ export type DestinationDescriptor = {
291
+ id: string;
292
+ destinationType: string;
293
+ credentials: any;
294
+ deviceOptions: DeviceOptions;
295
+ };
296
+ export type AnalyticsPluginDescriptor = {
297
+ type: "analytics-plugin";
298
+ packageCdn: string;
299
+ moduleVarName: string;
300
+ };
304
301
 
305
- function replaceMacro(code, event) {
306
- return code.replace(/{{\s*event\s*}}/g, JSON.stringify(event));
307
- }
302
+ export type InternalPluginDescriptor = {
303
+ type: "internal-plugin";
304
+ name: string;
305
+ };
306
+
307
+ export type DeviceOptions = AnalyticsPluginDescriptor | InternalPluginDescriptor;
308
308
 
309
- function insertTags(
310
- tags: Record<string, { mode: "javascript" | "html"; code }>,
311
- event: any,
312
- opts: { debug?: boolean } = {}
309
+ async function processDestinations(
310
+ destinations: DestinationDescriptor[],
311
+ method: string,
312
+ event: AnalyticsClientEvent,
313
+ debug: boolean,
314
+ analyticsInstance: AnalyticsInstance
313
315
  ) {
314
- const debug = opts.debug || false;
315
- if (isInBrowser()) {
316
- Object.values(tags).forEach(tag => {
317
- if (tag.mode === "javascript") {
318
- execJs(tag.code, event);
316
+ const promises: Promise<any>[] = [];
317
+ for (const destination of destinations) {
318
+ if (destination.deviceOptions.type === "internal-plugin") {
319
+ const plugin = internalDestinationPlugins[destination.deviceOptions.name];
320
+ if (plugin) {
321
+ try {
322
+ promises.push(plugin.handle(destination.credentials, event));
323
+ } catch (e) {
324
+ console.warn(
325
+ `[JITSU] Error processing event with internal plugin '${destination.deviceOptions.name}': ${e?.message}`,
326
+ e
327
+ );
328
+ }
319
329
  } else {
320
- const codeHolder = document.createElement("span");
321
- codeHolder.innerHTML = replaceMacro(tag.code, event);
322
- document.body.insertAdjacentElement("beforeend", codeHolder);
323
- const scripts = codeHolder.querySelectorAll("script");
324
- scripts.forEach(script => {
325
- const scriptClone = document.createElement("script");
326
- scriptClone.type = scriptClone.type || "text/javascript";
327
- if (script.hasAttribute("src")) {
328
- scriptClone.src = script.src;
329
- }
330
- scriptClone.text = script.text;
330
+ console.warn(
331
+ `[JITSU] Unknown internal plugin '${destination.deviceOptions.name}' for destination '${destination.id}'`
332
+ );
333
+ }
334
+ } else if (destination.deviceOptions.type === "analytics-plugin") {
335
+ await loadScript(destination.deviceOptions.packageCdn);
336
+ const plugin = window[destination.deviceOptions.moduleVarName];
337
+ if (!plugin) {
338
+ console.warn(
339
+ `[JITSU] Broken plugin '${destination.deviceOptions.packageCdn}' for destination '${destination.id}' - it doesn't export '${destination.deviceOptions.moduleVarName}' variable`
340
+ );
341
+ } else {
342
+ let pluginInstance: any;
343
+ try {
344
+ pluginInstance = (typeof plugin === "function" ? plugin : plugin.init)(destination.credentials);
345
+ } catch (e) {
346
+ console.warn(
347
+ `[JITSU] Error creating plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e?.message}`,
348
+ e
349
+ );
350
+ }
351
+ try {
331
352
  if (debug) {
332
- console.log(`Executing script${script.hasAttribute("src") ? ` ${script.src}` : ""}`, scriptClone.text);
353
+ console.log(
354
+ `[JITSU] Plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}' initialized with config:`,
355
+ pluginInstance.config
356
+ );
333
357
  }
334
- document.head.appendChild(scriptClone);
335
- document.head.removeChild(scriptClone);
336
- });
358
+ pluginInstance.initialize({ config: pluginInstance.config, instance: analyticsInstance });
359
+ } catch (e) {
360
+ console.warn(
361
+ `[JITSU] Error initializing plugin '${destination.deviceOptions.moduleVarName}@${
362
+ destination.deviceOptions.packageCdn
363
+ }' for destination '${destination.id}': ${e?.message}. Config: ${JSON.stringify(pluginInstance.config)}`,
364
+ e
365
+ );
366
+ continue;
367
+ }
368
+
369
+ if (pluginInstance[method]) {
370
+ try {
371
+ pluginInstance[method]({ payload: event, config: pluginInstance.config, instance: analyticsInstance });
372
+ } catch (e) {
373
+ console.warn(
374
+ `[JITSU] Error processing ${method}() with plugin '${destination.deviceOptions.moduleVarName}@${destination.deviceOptions.packageCdn}' for destination '${destination.id}': ${e?.message}`,
375
+ e
376
+ );
377
+ }
378
+ }
337
379
  }
338
- });
339
- } else {
340
- if (debug) {
341
- console.log(`insertTags: cannot insert tags in non-browser environment`);
342
380
  }
343
381
  }
344
382
  }
345
383
 
346
- function send(method, payload, jitsuConfig: Required<JitsuOptions>, store: PersistentStorage): Promise<void> {
384
+ function send(
385
+ method,
386
+ payload,
387
+ jitsuConfig: Required<JitsuOptions>,
388
+ instance: AnalyticsInstance,
389
+ store: PersistentStorage
390
+ ): Promise<void> {
347
391
  if (jitsuConfig.echoEvents) {
348
392
  console.log(`[JITSU] sending '${method}' event:`, payload);
349
393
  return;
@@ -387,17 +431,18 @@ function send(method, payload, jitsuConfig: Required<JitsuOptions>, store: Persi
387
431
  }
388
432
  })
389
433
  .then(responseText => {
434
+ let response: any;
390
435
  try {
391
- const response = JSON.parse(responseText);
392
- if (response.tags) {
393
- if (jitsuConfig.debug) {
394
- console.log(`[JITSU] Response Tags: `, JSON.stringify(response.tags, null, 2));
395
- }
396
- insertTags(response.tags, payload, { debug: jitsuConfig.debug });
397
- }
436
+ response = JSON.parse(responseText);
398
437
  } catch (e) {
399
438
  return Promise.reject(`Can't parse JSON: ${responseText}: ${e?.message}`);
400
439
  }
440
+ if (response.destinations) {
441
+ if (jitsuConfig.debug) {
442
+ console.log(`[JITSU] Processing device destianations: `, JSON.stringify(response.destinations, null, 2));
443
+ }
444
+ return processDestinations(response.destinations, method, adjustedPayload, !!jitsuConfig.debug, instance);
445
+ }
401
446
  })
402
447
  .catch(err => {
403
448
  if (jitsuConfig.debug) {
@@ -431,9 +476,9 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
431
476
  ...pluginConfig,
432
477
  },
433
478
  initialize: args => {
434
- const { config, instance } = args;
479
+ const { config } = args;
435
480
  if (config.debug) {
436
- console.debug("Initializing Jitsu plugin with config: ", JSON.stringify(config));
481
+ console.debug("[JITSU] Initializing Jitsu plugin with config: ", JSON.stringify(config));
437
482
  }
438
483
  if (!config.host && !config.echoEvents) {
439
484
  throw new Error("Please specify host variable in jitsu plugin initialization, or set echoEvents to true");
@@ -441,17 +486,17 @@ const jitsuAnalyticsPlugin = (pluginConfig: JitsuOptions = {}): AnalyticsPlugin
441
486
  },
442
487
  page: args => {
443
488
  const { payload, config, instance } = args;
444
- return send("page", payload, config, cachingStorageWrapper(instance.storage));
489
+ return send("page", payload, config, instance, cachingStorageWrapper(instance.storage));
445
490
  },
446
491
  track: args => {
447
492
  const { payload, config, instance } = args;
448
- return send("track", payload, config, cachingStorageWrapper(instance.storage));
493
+ return send("track", payload, config, instance, cachingStorageWrapper(instance.storage));
449
494
  },
450
495
  identify: args => {
451
496
  const { payload, config, instance } = args;
452
497
  // Store traits in cache to be able to use them in page and track events that run asynchronously with current identify.
453
498
  storageCache["__user_traits"] = payload.traits;
454
- return send("identify", payload, config, cachingStorageWrapper(instance.storage));
499
+ return send("identify", payload, config, instance, cachingStorageWrapper(instance.storage));
455
500
  },
456
501
  reset: args => {
457
502
  //clear storage cache