@searchspring/snap-tracker 0.20.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.
- package/LICENSE +21 -0
- package/README.md +474 -0
- package/dist/cjs/BeaconEvent.d.ts +12 -0
- package/dist/cjs/BeaconEvent.d.ts.map +1 -0
- package/dist/cjs/BeaconEvent.js +22 -0
- package/dist/cjs/PixelEvent.d.ts +9 -0
- package/dist/cjs/PixelEvent.d.ts.map +1 -0
- package/dist/cjs/PixelEvent.js +63 -0
- package/dist/cjs/TrackEvent.d.ts +11 -0
- package/dist/cjs/TrackEvent.d.ts.map +1 -0
- package/dist/cjs/TrackEvent.js +31 -0
- package/dist/cjs/Tracker.d.ts +31 -0
- package/dist/cjs/Tracker.d.ts.map +1 -0
- package/dist/cjs/Tracker.js +491 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +16 -0
- package/dist/cjs/types.d.ts +144 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +30 -0
- package/dist/esm/BeaconEvent.d.ts +12 -0
- package/dist/esm/BeaconEvent.d.ts.map +1 -0
- package/dist/esm/BeaconEvent.js +16 -0
- package/dist/esm/PixelEvent.d.ts +9 -0
- package/dist/esm/PixelEvent.d.ts.map +1 -0
- package/dist/esm/PixelEvent.js +57 -0
- package/dist/esm/TrackEvent.d.ts +11 -0
- package/dist/esm/TrackEvent.d.ts.map +1 -0
- package/dist/esm/TrackEvent.js +25 -0
- package/dist/esm/Tracker.d.ts +31 -0
- package/dist/esm/Tracker.d.ts.map +1 -0
- package/dist/esm/Tracker.js +462 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/types.d.ts +144 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +27 -0
- package/package.json +33 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { StorageStore } from '@searchspring/snap-store-mobx';
|
|
2
|
+
import { BeaconEvent } from './BeaconEvent';
|
|
3
|
+
import { TrackerGlobals, TrackMethods, BeaconContext, TrackerConfig } from './types';
|
|
4
|
+
export declare class Tracker {
|
|
5
|
+
globals: TrackerGlobals;
|
|
6
|
+
localStorage: StorageStore;
|
|
7
|
+
context: BeaconContext;
|
|
8
|
+
isSending: number;
|
|
9
|
+
private config;
|
|
10
|
+
private targeters;
|
|
11
|
+
constructor(globals: TrackerGlobals, config?: TrackerConfig);
|
|
12
|
+
retarget(): void;
|
|
13
|
+
track: TrackMethods;
|
|
14
|
+
getUserId: () => string;
|
|
15
|
+
getSessionId: () => string;
|
|
16
|
+
getShopperId: () => string;
|
|
17
|
+
cookies: {
|
|
18
|
+
cart: {
|
|
19
|
+
get: () => string[];
|
|
20
|
+
set: (items: string[]) => void;
|
|
21
|
+
add: (items: string[]) => void;
|
|
22
|
+
remove: (items: string[]) => void;
|
|
23
|
+
clear: () => void;
|
|
24
|
+
};
|
|
25
|
+
viewed: {
|
|
26
|
+
get: () => string[];
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
sendEvents: (eventsToSend?: BeaconEvent[]) => void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=Tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tracker.d.ts","sourceRoot":"","sources":["../../src/Tracker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAe,MAAM,+BAA+B,CAAC;AAK1E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACN,cAAc,EACd,YAAY,EAIZ,aAAa,EAOb,aAAa,EACb,MAAM,SAAS,CAAC;AAkBjB,qBAAa,OAAO;IACnB,OAAO,EAAE,cAAc,CAAC;IACxB,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,aAAa,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAElB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,SAAS,CAAqB;gBAE1B,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,aAAa;IAwGpD,QAAQ,IAAI,IAAI;IAMvB,KAAK,EAAE,YAAY,CA6PjB;IAEF,SAAS,QAAO,MAAM,CAiBpB;IAEF,YAAY,QAAO,MAAM,CAoBvB;IAEF,YAAY,QAAO,MAAM,CAOvB;IAEF,OAAO;;uBAEI,MAAM,EAAE;yBAOJ,MAAM,EAAE,KAAG,IAAI;yBAOf,MAAM,EAAE,KAAG,IAAI;4BAQZ,MAAM,EAAE,KAAG,IAAI;;;;uBAatB,MAAM,EAAE;;MAQjB;IAEF,UAAU,kBAAmB,WAAW,EAAE,KAAG,IAAI,CAoB/C;CACF"}
|
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
14
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
15
|
+
if (ar || !(i in from)) {
|
|
16
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
17
|
+
ar[i] = from[i];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.Tracker = void 0;
|
|
27
|
+
var deepmerge_1 = __importDefault(require("deepmerge"));
|
|
28
|
+
var uuid_1 = require("uuid");
|
|
29
|
+
var snap_store_mobx_1 = require("@searchspring/snap-store-mobx");
|
|
30
|
+
var snap_toolbox_1 = require("@searchspring/snap-toolbox");
|
|
31
|
+
var TrackEvent_1 = require("./TrackEvent");
|
|
32
|
+
var PixelEvent_1 = require("./PixelEvent");
|
|
33
|
+
var BeaconEvent_1 = require("./BeaconEvent");
|
|
34
|
+
var types_1 = require("./types");
|
|
35
|
+
var BATCH_TIMEOUT = 150;
|
|
36
|
+
var USERID_COOKIE_NAME = 'ssUserId';
|
|
37
|
+
var SHOPPERID_COOKIE_NAME = 'ssShopperId';
|
|
38
|
+
var COOKIE_EXPIRATION = 31536000000; // 1 year
|
|
39
|
+
var VIEWED_COOKIE_EXPIRATION = 220752000000; // 7 years
|
|
40
|
+
var COOKIE_SAMESITE = 'Lax';
|
|
41
|
+
var SESSIONID_STORAGE_NAME = 'ssSessionIdNamespace';
|
|
42
|
+
var LOCALSTORAGE_BEACON_POOL_NAME = 'ssBeaconPool';
|
|
43
|
+
var CART_PRODUCTS = 'ssCartProducts';
|
|
44
|
+
var VIEWED_PRODUCTS = 'ssViewedProducts';
|
|
45
|
+
var MAX_VIEWED_COUNT = 15;
|
|
46
|
+
var defaultConfig = {
|
|
47
|
+
id: 'track',
|
|
48
|
+
};
|
|
49
|
+
var Tracker = /** @class */ (function () {
|
|
50
|
+
function Tracker(globals, config) {
|
|
51
|
+
var _this = this;
|
|
52
|
+
var _a;
|
|
53
|
+
this.targeters = [];
|
|
54
|
+
this.track = {
|
|
55
|
+
event: function (payload) {
|
|
56
|
+
var event = {
|
|
57
|
+
type: (payload === null || payload === void 0 ? void 0 : payload.type) || types_1.BeaconType.CUSTOM,
|
|
58
|
+
category: (payload === null || payload === void 0 ? void 0 : payload.category) || types_1.BeaconCategory.CUSTOM,
|
|
59
|
+
context: (payload === null || payload === void 0 ? void 0 : payload.context) ? (0, deepmerge_1.default)(_this.context, payload.context) : _this.context,
|
|
60
|
+
event: payload.event,
|
|
61
|
+
pid: (payload === null || payload === void 0 ? void 0 : payload.pid) || undefined,
|
|
62
|
+
};
|
|
63
|
+
var beaconEvent = new BeaconEvent_1.BeaconEvent(event);
|
|
64
|
+
_this.sendEvents([beaconEvent]);
|
|
65
|
+
return beaconEvent;
|
|
66
|
+
},
|
|
67
|
+
shopper: {
|
|
68
|
+
login: function (data, siteId) {
|
|
69
|
+
// sets shopperid if logged in
|
|
70
|
+
if (!snap_toolbox_1.featureFlags.cookies) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!data.id) {
|
|
74
|
+
console.error('tracker.shopper.login event: requires a valid shopper ID parameter. Example: tracker.shopper.login({ id: "1234" })');
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
var context = _this.context;
|
|
78
|
+
if (siteId) {
|
|
79
|
+
context = (0, deepmerge_1.default)(context, {
|
|
80
|
+
context: {
|
|
81
|
+
website: {
|
|
82
|
+
trackingCode: siteId,
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
var storedShopperId = _this.getShopperId();
|
|
88
|
+
data.id = "".concat(data.id);
|
|
89
|
+
if (storedShopperId != data.id) {
|
|
90
|
+
// user's logged in id has changed, update shopperId cookie send login event
|
|
91
|
+
snap_toolbox_1.cookies.set(SHOPPERID_COOKIE_NAME, data.id, COOKIE_SAMESITE, COOKIE_EXPIRATION);
|
|
92
|
+
_this.context.shopperId = data.id;
|
|
93
|
+
var payload = {
|
|
94
|
+
type: types_1.BeaconType.LOGIN,
|
|
95
|
+
category: types_1.BeaconCategory.PERSONALIZATION,
|
|
96
|
+
context: context,
|
|
97
|
+
event: {},
|
|
98
|
+
};
|
|
99
|
+
return _this.track.event(payload);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
product: {
|
|
104
|
+
view: function (data, siteId) {
|
|
105
|
+
if (!(data === null || data === void 0 ? void 0 : data.sku) && !(data === null || data === void 0 ? void 0 : data.childSku)) {
|
|
106
|
+
console.error('track.product.view event: requires a valid sku and/or childSku. \nExample: track.product.view({ sku: "product123", childSku: "product123_a" })');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
var context = _this.context;
|
|
110
|
+
if (siteId) {
|
|
111
|
+
context = (0, deepmerge_1.default)(context, {
|
|
112
|
+
context: {
|
|
113
|
+
website: {
|
|
114
|
+
trackingCode: siteId,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
var payload = {
|
|
120
|
+
type: types_1.BeaconType.PRODUCT,
|
|
121
|
+
category: types_1.BeaconCategory.PAGEVIEW,
|
|
122
|
+
context: context,
|
|
123
|
+
event: {
|
|
124
|
+
sku: (data === null || data === void 0 ? void 0 : data.sku) ? "".concat(data.sku) : undefined,
|
|
125
|
+
childSku: (data === null || data === void 0 ? void 0 : data.childSku) ? "".concat(data.childSku) : undefined,
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
// save recently viewed products to cookie
|
|
129
|
+
var sku = (data === null || data === void 0 ? void 0 : data.sku) || (data === null || data === void 0 ? void 0 : data.childSku);
|
|
130
|
+
if (sku) {
|
|
131
|
+
var lastViewedProducts = _this.cookies.viewed.get();
|
|
132
|
+
var uniqueCartItems = Array.from(new Set(__spreadArray(__spreadArray([], lastViewedProducts, true), [sku], false))).map(function (item) { return item.trim(); });
|
|
133
|
+
snap_toolbox_1.cookies.set(VIEWED_PRODUCTS, uniqueCartItems.slice(0, MAX_VIEWED_COUNT).join(','), COOKIE_SAMESITE, VIEWED_COOKIE_EXPIRATION);
|
|
134
|
+
}
|
|
135
|
+
// legacy tracking
|
|
136
|
+
if (data === null || data === void 0 ? void 0 : data.sku) {
|
|
137
|
+
// only send sku to pixel tracker if present (don't send childSku)
|
|
138
|
+
new PixelEvent_1.PixelEvent(__assign(__assign({}, payload), { event: {
|
|
139
|
+
sku: data.sku,
|
|
140
|
+
} }));
|
|
141
|
+
}
|
|
142
|
+
return _this.track.event(payload);
|
|
143
|
+
},
|
|
144
|
+
click: function (data, siteId) {
|
|
145
|
+
if (!(data === null || data === void 0 ? void 0 : data.intellisuggestData) || !(data === null || data === void 0 ? void 0 : data.intellisuggestSignature)) {
|
|
146
|
+
console.error("track.product.click event: object parameter requires a valid intellisuggestData and intellisuggestSignature. \nExample: track.click.product({ intellisuggestData: \"eJwrTs4tNM9jYCjKTM8oYXDWdQ3TDTfUDbIwMDVjMARCYwMQSi_KTAEA9IQKWA\", intellisuggestSignature: \"9e46f9fd3253c267fefc298704e39084a6f8b8e47abefdee57277996b77d8e70\" })");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
var context = _this.context;
|
|
150
|
+
if (siteId) {
|
|
151
|
+
context = (0, deepmerge_1.default)(context, {
|
|
152
|
+
context: {
|
|
153
|
+
website: {
|
|
154
|
+
trackingCode: siteId,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
var payload = {
|
|
160
|
+
type: types_1.BeaconType.CLICK,
|
|
161
|
+
category: types_1.BeaconCategory.INTERACTION,
|
|
162
|
+
context: context,
|
|
163
|
+
event: {
|
|
164
|
+
intellisuggestData: data.intellisuggestData,
|
|
165
|
+
intellisuggestSignature: data.intellisuggestSignature,
|
|
166
|
+
href: (data === null || data === void 0 ? void 0 : data.href) ? "".concat(data.href) : undefined,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
// legacy tracking
|
|
170
|
+
new TrackEvent_1.TrackEvent(payload);
|
|
171
|
+
return _this.track.event(payload);
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
cart: {
|
|
175
|
+
view: function (data, siteId) {
|
|
176
|
+
if (!Array.isArray(data === null || data === void 0 ? void 0 : data.items) || !(data === null || data === void 0 ? void 0 : data.items.length)) {
|
|
177
|
+
console.error('track.view.cart event: parameter must be an array of cart items. \nExample: track.view.cart({ items: [{ sku: "product123", childSku: "product123_a", qty: "1", price: "9.99" }] })');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
var context = _this.context;
|
|
181
|
+
if (siteId) {
|
|
182
|
+
context = (0, deepmerge_1.default)(context, {
|
|
183
|
+
context: {
|
|
184
|
+
website: {
|
|
185
|
+
trackingCode: siteId,
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
var items = data.items.map(function (item, index) {
|
|
191
|
+
if (!(item === null || item === void 0 ? void 0 : item.qty) || !(item === null || item === void 0 ? void 0 : item.price) || (!(item === null || item === void 0 ? void 0 : item.sku) && !(item === null || item === void 0 ? void 0 : item.childSku))) {
|
|
192
|
+
console.error("track.view.cart event: item ".concat(item, " at index ").concat(index, " requires a valid qty, price, and (sku and/or childSku.) \nExample: track.view.cart({ items: [{ sku: \"product123\", childSku: \"product123_a\", qty: \"1\", price: \"9.99\" }] })"));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
var product = {
|
|
196
|
+
qty: "".concat(item.qty),
|
|
197
|
+
price: "".concat(item.price),
|
|
198
|
+
};
|
|
199
|
+
if (item === null || item === void 0 ? void 0 : item.sku) {
|
|
200
|
+
product.sku = "".concat(item.sku);
|
|
201
|
+
}
|
|
202
|
+
if (item === null || item === void 0 ? void 0 : item.childSku) {
|
|
203
|
+
product.childSku = "".concat(item.childSku);
|
|
204
|
+
}
|
|
205
|
+
return product;
|
|
206
|
+
});
|
|
207
|
+
var payload = {
|
|
208
|
+
type: types_1.BeaconType.CART,
|
|
209
|
+
category: types_1.BeaconCategory.CARTVIEW,
|
|
210
|
+
context: context,
|
|
211
|
+
event: { items: items },
|
|
212
|
+
};
|
|
213
|
+
// save cart items to cookie
|
|
214
|
+
if (items.length) {
|
|
215
|
+
var products = items.map(function (item) { return item.sku || item.childSku; });
|
|
216
|
+
_this.cookies.cart.add(products);
|
|
217
|
+
}
|
|
218
|
+
// legacy tracking
|
|
219
|
+
new PixelEvent_1.PixelEvent(payload);
|
|
220
|
+
return _this.track.event(payload);
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
order: {
|
|
224
|
+
transaction: function (data, siteId) {
|
|
225
|
+
var _a, _b, _c, _d, _e;
|
|
226
|
+
if (!(data === null || data === void 0 ? void 0 : data.items) || !Array.isArray(data.items) || !data.items.length) {
|
|
227
|
+
console.error('track.order.transaction event: object parameter must contain `items` array of cart items. \nExample: order.transaction({ order: { id: "1001", total: "9.99", city: "Los Angeles", state: "CA", country: "US" }, items: [{ sku: "product123", childSku: "product123_a", qty: "1", price: "9.99" }] })');
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
var context = _this.context;
|
|
231
|
+
if (siteId) {
|
|
232
|
+
context = (0, deepmerge_1.default)(context, {
|
|
233
|
+
context: {
|
|
234
|
+
website: {
|
|
235
|
+
trackingCode: siteId,
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
var items = data.items.map(function (item, index) {
|
|
241
|
+
if (!(item === null || item === void 0 ? void 0 : item.qty) || !(item === null || item === void 0 ? void 0 : item.price) || (!(item === null || item === void 0 ? void 0 : item.sku) && !(item === null || item === void 0 ? void 0 : item.childSku))) {
|
|
242
|
+
console.error("track.order.transaction event: object parameter `items`: item ".concat(item, " at index ").concat(index, " requires a valid qty, price, and (sku and/or childSku.) \nExample: order.view({ items: [{ sku: \"product123\", childSku: \"product123_a\", qty: \"1\", price: \"9.99\" }] })"));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
var product = {
|
|
246
|
+
qty: "".concat(item.qty),
|
|
247
|
+
price: "".concat(item.price),
|
|
248
|
+
};
|
|
249
|
+
if (item === null || item === void 0 ? void 0 : item.sku) {
|
|
250
|
+
product.sku = "".concat(item.sku);
|
|
251
|
+
}
|
|
252
|
+
if (item === null || item === void 0 ? void 0 : item.childSku) {
|
|
253
|
+
product.childSku = "".concat(item.childSku);
|
|
254
|
+
}
|
|
255
|
+
return product;
|
|
256
|
+
});
|
|
257
|
+
var eventPayload = {
|
|
258
|
+
orderId: ((_a = data === null || data === void 0 ? void 0 : data.order) === null || _a === void 0 ? void 0 : _a.id) ? "".concat(data.order.id) : undefined,
|
|
259
|
+
total: ((_b = data === null || data === void 0 ? void 0 : data.order) === null || _b === void 0 ? void 0 : _b.total) ? "".concat(data.order.total) : undefined,
|
|
260
|
+
city: ((_c = data === null || data === void 0 ? void 0 : data.order) === null || _c === void 0 ? void 0 : _c.city) ? "".concat(data.order.city) : undefined,
|
|
261
|
+
state: ((_d = data === null || data === void 0 ? void 0 : data.order) === null || _d === void 0 ? void 0 : _d.state) ? "".concat(data.order.state) : undefined,
|
|
262
|
+
country: ((_e = data === null || data === void 0 ? void 0 : data.order) === null || _e === void 0 ? void 0 : _e.country) ? "".concat(data.order.country) : undefined,
|
|
263
|
+
items: items,
|
|
264
|
+
};
|
|
265
|
+
var payload = {
|
|
266
|
+
type: types_1.BeaconType.ORDER,
|
|
267
|
+
category: types_1.BeaconCategory.ORDERVIEW,
|
|
268
|
+
context: context,
|
|
269
|
+
event: eventPayload,
|
|
270
|
+
};
|
|
271
|
+
// clear cart items from cookie when order is placed
|
|
272
|
+
_this.cookies.cart.clear();
|
|
273
|
+
// legacy tracking
|
|
274
|
+
new PixelEvent_1.PixelEvent(payload);
|
|
275
|
+
return _this.track.event(payload);
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
this.getUserId = function () {
|
|
280
|
+
var userId;
|
|
281
|
+
try {
|
|
282
|
+
userId = snap_toolbox_1.featureFlags.storage && window.localStorage.getItem(USERID_COOKIE_NAME);
|
|
283
|
+
if (snap_toolbox_1.featureFlags.cookies) {
|
|
284
|
+
userId = userId || snap_toolbox_1.cookies.get(USERID_COOKIE_NAME) || (0, uuid_1.v4)();
|
|
285
|
+
snap_toolbox_1.cookies.set(USERID_COOKIE_NAME, userId, COOKIE_SAMESITE, COOKIE_EXPIRATION);
|
|
286
|
+
}
|
|
287
|
+
else if (!userId && snap_toolbox_1.featureFlags.storage) {
|
|
288
|
+
// if cookies are disabled, use localStorage instead
|
|
289
|
+
userId = (0, uuid_1.v4)();
|
|
290
|
+
window.localStorage.setItem(USERID_COOKIE_NAME, userId);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (e) {
|
|
294
|
+
console.error('Failed to persist user id to cookie or local storage:', e);
|
|
295
|
+
}
|
|
296
|
+
return userId;
|
|
297
|
+
};
|
|
298
|
+
this.getSessionId = function () {
|
|
299
|
+
var sessionId;
|
|
300
|
+
if (snap_toolbox_1.featureFlags.storage) {
|
|
301
|
+
try {
|
|
302
|
+
sessionId = window.sessionStorage.getItem(SESSIONID_STORAGE_NAME) || (0, uuid_1.v4)();
|
|
303
|
+
window.sessionStorage.setItem(SESSIONID_STORAGE_NAME, sessionId);
|
|
304
|
+
snap_toolbox_1.featureFlags.cookies && snap_toolbox_1.cookies.set(SESSIONID_STORAGE_NAME, sessionId, COOKIE_SAMESITE, 0); //session cookie
|
|
305
|
+
}
|
|
306
|
+
catch (e) {
|
|
307
|
+
console.error('Failed to persist session id to session storage:', e);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else if (snap_toolbox_1.featureFlags.cookies) {
|
|
311
|
+
// use cookies if sessionStorage is not enabled and only reset cookie if new session to keep expiration
|
|
312
|
+
sessionId = snap_toolbox_1.cookies.get(SESSIONID_STORAGE_NAME);
|
|
313
|
+
if (!sessionId) {
|
|
314
|
+
sessionId = (0, uuid_1.v4)();
|
|
315
|
+
snap_toolbox_1.cookies.set(SESSIONID_STORAGE_NAME, sessionId, COOKIE_SAMESITE, 0);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return sessionId;
|
|
319
|
+
};
|
|
320
|
+
this.getShopperId = function () {
|
|
321
|
+
var shopperId = snap_toolbox_1.cookies.get(SHOPPERID_COOKIE_NAME);
|
|
322
|
+
if (!shopperId) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
return shopperId;
|
|
326
|
+
};
|
|
327
|
+
this.cookies = {
|
|
328
|
+
cart: {
|
|
329
|
+
get: function () {
|
|
330
|
+
var items = snap_toolbox_1.cookies.get(CART_PRODUCTS);
|
|
331
|
+
if (!items) {
|
|
332
|
+
return [];
|
|
333
|
+
}
|
|
334
|
+
return items.split(',');
|
|
335
|
+
},
|
|
336
|
+
set: function (items) {
|
|
337
|
+
if (items.length) {
|
|
338
|
+
var cartItems = items.map(function (item) { return item.trim(); });
|
|
339
|
+
var uniqueCartItems = Array.from(new Set(cartItems));
|
|
340
|
+
snap_toolbox_1.cookies.set(CART_PRODUCTS, uniqueCartItems.join(','), COOKIE_SAMESITE, 0);
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
add: function (items) {
|
|
344
|
+
if (items.length) {
|
|
345
|
+
var currentCartItems = _this.cookies.cart.get();
|
|
346
|
+
var itemsToAdd = items.map(function (item) { return item.trim(); });
|
|
347
|
+
var uniqueCartItems = Array.from(new Set(__spreadArray(__spreadArray([], currentCartItems, true), itemsToAdd, true)));
|
|
348
|
+
snap_toolbox_1.cookies.set(CART_PRODUCTS, uniqueCartItems.join(','), COOKIE_SAMESITE, 0);
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
remove: function (items) {
|
|
352
|
+
if (items.length) {
|
|
353
|
+
var currentCartItems = _this.cookies.cart.get();
|
|
354
|
+
var itemsToRemove_1 = items.map(function (item) { return item.trim(); });
|
|
355
|
+
var updatedItems = currentCartItems.filter(function (item) { return !itemsToRemove_1.includes(item); });
|
|
356
|
+
snap_toolbox_1.cookies.set(CART_PRODUCTS, updatedItems.join(','), COOKIE_SAMESITE, 0);
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
clear: function () {
|
|
360
|
+
snap_toolbox_1.cookies.unset(CART_PRODUCTS);
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
viewed: {
|
|
364
|
+
get: function () {
|
|
365
|
+
var items = snap_toolbox_1.cookies.get(VIEWED_PRODUCTS);
|
|
366
|
+
if (!items) {
|
|
367
|
+
return [];
|
|
368
|
+
}
|
|
369
|
+
return items.split(',');
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
this.sendEvents = function (eventsToSend) {
|
|
374
|
+
var events = JSON.parse(_this.localStorage.get(LOCALSTORAGE_BEACON_POOL_NAME) || '[]');
|
|
375
|
+
if (eventsToSend) {
|
|
376
|
+
eventsToSend.forEach(function (event) {
|
|
377
|
+
events.push(__assign({}, event));
|
|
378
|
+
});
|
|
379
|
+
_this.localStorage.set(LOCALSTORAGE_BEACON_POOL_NAME, JSON.stringify(events));
|
|
380
|
+
}
|
|
381
|
+
clearTimeout(_this.isSending);
|
|
382
|
+
_this.isSending = window.setTimeout(function () {
|
|
383
|
+
if (events.length) {
|
|
384
|
+
var xhr = new XMLHttpRequest();
|
|
385
|
+
xhr.open('POST', 'https://beacon.searchspring.io/beacon');
|
|
386
|
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
|
387
|
+
xhr.send(JSON.stringify(events.length == 1 ? events[0] : events));
|
|
388
|
+
}
|
|
389
|
+
_this.localStorage.set(LOCALSTORAGE_BEACON_POOL_NAME, JSON.stringify([]));
|
|
390
|
+
}, BATCH_TIMEOUT);
|
|
391
|
+
};
|
|
392
|
+
if (typeof globals != 'object' || typeof globals.siteId != 'string') {
|
|
393
|
+
throw new Error("Invalid config passed to tracker. The \"siteId\" attribute must be provided.");
|
|
394
|
+
}
|
|
395
|
+
this.config = (0, deepmerge_1.default)(defaultConfig, config || {});
|
|
396
|
+
this.globals = globals;
|
|
397
|
+
this.localStorage = new snap_store_mobx_1.StorageStore({
|
|
398
|
+
type: snap_store_mobx_1.StorageType.LOCAL,
|
|
399
|
+
key: "ss-".concat(this.config.id, "-").concat(this.globals.siteId, "-local"),
|
|
400
|
+
});
|
|
401
|
+
this.context = {
|
|
402
|
+
userId: this.getUserId(),
|
|
403
|
+
sessionId: this.getSessionId(),
|
|
404
|
+
shopperId: this.getShopperId(),
|
|
405
|
+
pageLoadId: (0, uuid_1.v4)(),
|
|
406
|
+
website: {
|
|
407
|
+
trackingCode: this.globals.siteId,
|
|
408
|
+
},
|
|
409
|
+
};
|
|
410
|
+
if (!((_a = window.searchspring) === null || _a === void 0 ? void 0 : _a.tracker)) {
|
|
411
|
+
window.searchspring = window.searchspring || {};
|
|
412
|
+
window.searchspring.tracker = this;
|
|
413
|
+
window.searchspring.version = snap_toolbox_1.version;
|
|
414
|
+
}
|
|
415
|
+
// one targeter to rule them all
|
|
416
|
+
this.targeters.push(new snap_toolbox_1.DomTargeter([{ selector: 'script[type^="searchspring/track/"]', emptyTarget: false }], function (target, elem) {
|
|
417
|
+
var _a = (0, snap_toolbox_1.getContext)(['item', 'items', 'siteId', 'shopper', 'order'], elem), item = _a.item, items = _a.items, siteId = _a.siteId, shopper = _a.shopper, order = _a.order, type = _a.type;
|
|
418
|
+
switch (type) {
|
|
419
|
+
case 'searchspring/track/shopper/login':
|
|
420
|
+
_this.track.shopper.login(shopper, siteId);
|
|
421
|
+
break;
|
|
422
|
+
case 'searchspring/track/product/view':
|
|
423
|
+
_this.track.product.view(item, siteId);
|
|
424
|
+
break;
|
|
425
|
+
case 'searchspring/track/cart/view':
|
|
426
|
+
_this.track.cart.view({ items: items }, siteId);
|
|
427
|
+
break;
|
|
428
|
+
case 'searchspring/track/order/transaction':
|
|
429
|
+
_this.track.order.transaction({ order: order, items: items }, siteId);
|
|
430
|
+
break;
|
|
431
|
+
default:
|
|
432
|
+
console.error("".concat(type, " event is not supported or incorrect"));
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
}));
|
|
436
|
+
document.addEventListener('click', function (event) {
|
|
437
|
+
event.preventDefault();
|
|
438
|
+
var attributes = {};
|
|
439
|
+
Object.values(event.target.attributes).forEach(function (attr) {
|
|
440
|
+
attributes[attr.nodeName] = event.target.getAttribute(attr.nodeName);
|
|
441
|
+
});
|
|
442
|
+
var updateRecsControllers = function () {
|
|
443
|
+
if (window.searchspring.controller) {
|
|
444
|
+
Object.keys(window.searchspring.controller).forEach(function (name) {
|
|
445
|
+
var _a;
|
|
446
|
+
var controller = window.searchspring.controller[name];
|
|
447
|
+
if (controller.type === 'recommendation' && ((_a = controller.config) === null || _a === void 0 ? void 0 : _a.realtime)) {
|
|
448
|
+
controller.search();
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
if (attributes["ss-".concat(_this.config.id, "-cart-add")]) {
|
|
454
|
+
// add skus to cart
|
|
455
|
+
var skus = attributes["ss-".concat(_this.config.id, "-cart-add")].split(',');
|
|
456
|
+
_this.cookies.cart.add(skus);
|
|
457
|
+
updateRecsControllers();
|
|
458
|
+
}
|
|
459
|
+
else if (attributes["ss-".concat(_this.config.id, "-cart-remove")]) {
|
|
460
|
+
// remove skus from cart
|
|
461
|
+
var skus = attributes["ss-".concat(_this.config.id, "-cart-remove")].split(',');
|
|
462
|
+
_this.cookies.cart.remove(skus);
|
|
463
|
+
updateRecsControllers();
|
|
464
|
+
}
|
|
465
|
+
else if ("ss-".concat(_this.config.id, "-cart-clear") in attributes) {
|
|
466
|
+
// clear all from cart
|
|
467
|
+
_this.cookies.cart.clear();
|
|
468
|
+
updateRecsControllers();
|
|
469
|
+
}
|
|
470
|
+
else if (attributes["ss-".concat(_this.config.id, "-intellisuggest")] && attributes["ss-".concat(_this.config.id, "-intellisuggest-signature")]) {
|
|
471
|
+
// product click
|
|
472
|
+
var intellisuggestData = attributes["ss-".concat(_this.config.id, "-intellisuggest")];
|
|
473
|
+
var intellisuggestSignature = attributes["ss-".concat(_this.config.id, "-intellisuggest-signature")];
|
|
474
|
+
var href = attributes['href'];
|
|
475
|
+
_this.track.product.click({
|
|
476
|
+
intellisuggestData: intellisuggestData,
|
|
477
|
+
intellisuggestSignature: intellisuggestSignature,
|
|
478
|
+
href: href,
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
this.sendEvents();
|
|
483
|
+
}
|
|
484
|
+
Tracker.prototype.retarget = function () {
|
|
485
|
+
this.targeters.forEach(function (target) {
|
|
486
|
+
target.retarget();
|
|
487
|
+
});
|
|
488
|
+
};
|
|
489
|
+
return Tracker;
|
|
490
|
+
}());
|
|
491
|
+
exports.Tracker = Tracker;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.Tracker = void 0;
|
|
14
|
+
var Tracker_1 = require("./Tracker");
|
|
15
|
+
Object.defineProperty(exports, "Tracker", { enumerable: true, get: function () { return Tracker_1.Tracker; } });
|
|
16
|
+
__exportStar(require("./types"), exports);
|