@croct/sdk 0.17.9 → 0.17.10
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/activeRecord.cjs +135 -0
- package/apiKey.cjs +178 -0
- package/base64Url.cjs +41 -0
- package/cache/cache.cjs +34 -0
- package/cache/cookieCache.cjs +85 -0
- package/cache/fallbackCache.cjs +47 -0
- package/cache/inMemoryCache.cjs +41 -0
- package/cache/index.cjs +37 -0
- package/cache/localStorageCache.cjs +81 -0
- package/channel/channel.cjs +48 -0
- package/channel/encodedChannel.cjs +39 -0
- package/channel/guaranteedChannel.cjs +105 -0
- package/channel/httpBeaconChannel.cjs +111 -0
- package/channel/index.cjs +46 -0
- package/channel/queuedChannel.cjs +122 -0
- package/channel/retryChannel.cjs +87 -0
- package/channel/sandboxChannel.cjs +63 -0
- package/cid/assigner.cjs +16 -0
- package/cid/cachedAssigner.cjs +66 -0
- package/cid/fixedAssigner.cjs +35 -0
- package/cid/index.cjs +37 -0
- package/cid/remoteAssigner.cjs +65 -0
- package/constants.cjs +37 -0
- package/constants.cjs.map +1 -1
- package/constants.d.ts +2 -2
- package/constants.js +1 -1
- package/constants.js.map +1 -1
- package/container.cjs +305 -0
- package/contentFetcher.cjs +193 -0
- package/context.cjs +114 -0
- package/error.cjs +52 -0
- package/evaluator.cjs +219 -0
- package/eventManager.cjs +53 -0
- package/eventSubjectProcessor.cjs +84 -0
- package/facade/contentFetcherFacade.cjs +61 -0
- package/facade/evaluatorFacade.cjs +94 -0
- package/facade/index.cjs +52 -0
- package/facade/sdkFacade.cjs +229 -0
- package/facade/sessionFacade.cjs +36 -0
- package/facade/sessionPatch.cjs +48 -0
- package/facade/trackerFacade.cjs +87 -0
- package/facade/userFacade.cjs +43 -0
- package/facade/userPatch.cjs +48 -0
- package/help.cjs +45 -0
- package/index.cjs +33 -0
- package/logging/consoleLogger.cjs +50 -0
- package/logging/filteredLogger.cjs +62 -0
- package/logging/index.cjs +40 -0
- package/logging/logger.cjs +16 -0
- package/logging/namespacedLogger.cjs +48 -0
- package/logging/nullLogger.cjs +37 -0
- package/namespacedStorage.cjs +77 -0
- package/package.json +7 -6
- package/patch.cjs +16 -0
- package/queue/capacityRestrictedQueue.cjs +57 -0
- package/queue/inMemoryQueue.cjs +58 -0
- package/queue/index.cjs +40 -0
- package/queue/monitoredQueue.cjs +141 -0
- package/queue/persistentQueue.cjs +78 -0
- package/queue/queue.cjs +16 -0
- package/retry/arbitraryPolicy.cjs +41 -0
- package/retry/backoffPolicy.cjs +81 -0
- package/retry/index.cjs +40 -0
- package/retry/maxAttemptsPolicy.cjs +45 -0
- package/retry/neverPolicy.cjs +35 -0
- package/retry/policy.cjs +16 -0
- package/schema/attributeSchema.cjs +32 -0
- package/schema/contentFetcherSchemas.cjs +49 -0
- package/schema/contentSchemas.cjs +70 -0
- package/schema/contextSchemas.cjs +31 -0
- package/schema/ecommerceSchemas.cjs +209 -0
- package/schema/evaluatorSchemas.cjs +64 -0
- package/schema/eventSchemas.cjs +162 -0
- package/schema/index.cjs +42 -0
- package/schema/loggerSchema.cjs +38 -0
- package/schema/operationSchemas.cjs +122 -0
- package/schema/sdkFacadeSchemas.cjs +82 -0
- package/schema/sdkSchemas.cjs +110 -0
- package/schema/tokenSchema.cjs +68 -0
- package/schema/userSchema.cjs +202 -0
- package/sdk.cjs +134 -0
- package/sdkEvents.cjs +16 -0
- package/sourceLocation.cjs +92 -0
- package/tab.cjs +122 -0
- package/token/cachedTokenStore.cjs +51 -0
- package/token/inMemoryTokenStore.cjs +38 -0
- package/token/index.cjs +37 -0
- package/token/replicatedTokenStore.cjs +40 -0
- package/token/token.cjs +239 -0
- package/tracker.cjs +358 -0
- package/trackingEvents.cjs +94 -0
- package/transformer.cjs +30 -0
- package/utilityTypes.cjs +16 -0
- package/uuid.cjs +55 -0
- package/validation/arrayType.cjs +75 -0
- package/validation/booleanType.cjs +46 -0
- package/validation/functionType.cjs +46 -0
- package/validation/index.cjs +66 -0
- package/validation/jsonType.cjs +142 -0
- package/validation/mixedSchema.cjs +31 -0
- package/validation/nullType.cjs +46 -0
- package/validation/numberType.cjs +69 -0
- package/validation/objectType.cjs +114 -0
- package/validation/schema.cjs +34 -0
- package/validation/stringType.cjs +106 -0
- package/validation/unionType.cjs +67 -0
- package/validation/violation.cjs +47 -0
package/token/token.cjs
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var token_exports = {};
|
|
19
|
+
__export(token_exports, {
|
|
20
|
+
FixedTokenProvider: () => FixedTokenProvider,
|
|
21
|
+
Token: () => Token
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(token_exports);
|
|
24
|
+
var import_schema = require("../schema");
|
|
25
|
+
var import_error = require("../error");
|
|
26
|
+
var import_base64Url = require("../base64Url");
|
|
27
|
+
const _Token = class _Token {
|
|
28
|
+
constructor(headers, payload, signature = "") {
|
|
29
|
+
this.headers = headers;
|
|
30
|
+
this.payload = payload;
|
|
31
|
+
this.signature = signature;
|
|
32
|
+
}
|
|
33
|
+
static issue(appId, subject = null, timestamp = Math.floor(Date.now() / 1e3)) {
|
|
34
|
+
if (timestamp < 0) {
|
|
35
|
+
throw new Error("The timestamp must be non-negative.");
|
|
36
|
+
}
|
|
37
|
+
if (subject === "") {
|
|
38
|
+
throw new Error("The subject must be non-empty.");
|
|
39
|
+
}
|
|
40
|
+
return new _Token(
|
|
41
|
+
{
|
|
42
|
+
typ: "JWT",
|
|
43
|
+
alg: "none",
|
|
44
|
+
appId
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
iss: "croct.io",
|
|
48
|
+
aud: "croct.io",
|
|
49
|
+
iat: timestamp,
|
|
50
|
+
...subject !== null ? { sub: subject } : null
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
static parse(token) {
|
|
55
|
+
if (token === "") {
|
|
56
|
+
throw new Error("The token cannot be empty.");
|
|
57
|
+
}
|
|
58
|
+
const parts = token.split(".", 3);
|
|
59
|
+
if (parts.length < 2) {
|
|
60
|
+
throw new Error("The token is malformed.");
|
|
61
|
+
}
|
|
62
|
+
let headers;
|
|
63
|
+
let payload;
|
|
64
|
+
try {
|
|
65
|
+
headers = JSON.parse((0, import_base64Url.base64UrlDecode)(parts[0], true));
|
|
66
|
+
payload = JSON.parse((0, import_base64Url.base64UrlDecode)(parts[1], true));
|
|
67
|
+
} catch (error) {
|
|
68
|
+
throw new Error("The token is corrupted.");
|
|
69
|
+
}
|
|
70
|
+
return _Token.of(headers, payload, parts[2]);
|
|
71
|
+
}
|
|
72
|
+
static of(headers, payload, signature = "") {
|
|
73
|
+
try {
|
|
74
|
+
import_schema.tokenSchema.validate({
|
|
75
|
+
headers,
|
|
76
|
+
payload,
|
|
77
|
+
signature
|
|
78
|
+
});
|
|
79
|
+
} catch (violation) {
|
|
80
|
+
throw new Error(`The token is invalid: ${(0, import_error.formatCause)(violation)}`);
|
|
81
|
+
}
|
|
82
|
+
return new _Token(headers, payload, signature);
|
|
83
|
+
}
|
|
84
|
+
async signedWith(apiKey) {
|
|
85
|
+
const keyId = await apiKey.getIdentifierHash();
|
|
86
|
+
const headers = {
|
|
87
|
+
...this.headers,
|
|
88
|
+
kid: keyId,
|
|
89
|
+
alg: apiKey.getSigningAlgorithm()
|
|
90
|
+
};
|
|
91
|
+
const encodedHeader = (0, import_base64Url.base64UrlEncode)(JSON.stringify(headers), true);
|
|
92
|
+
const encodedPayload = (0, import_base64Url.base64UrlEncode)(JSON.stringify(this.payload), true);
|
|
93
|
+
const signature = await apiKey.sign(`${encodedHeader}.${encodedPayload}`);
|
|
94
|
+
return new _Token(headers, this.payload, (0, import_base64Url.base64UrlEncode)(signature, false));
|
|
95
|
+
}
|
|
96
|
+
isSigned() {
|
|
97
|
+
return this.headers.alg !== "none" && this.signature !== "";
|
|
98
|
+
}
|
|
99
|
+
isSubject(subject) {
|
|
100
|
+
return this.getSubject() === subject;
|
|
101
|
+
}
|
|
102
|
+
isAnonymous() {
|
|
103
|
+
return this.payload.sub === void 0;
|
|
104
|
+
}
|
|
105
|
+
isValidNow(now = Math.floor(Date.now() / 1e3)) {
|
|
106
|
+
const { exp, iat } = this.payload;
|
|
107
|
+
return (exp === void 0 || exp >= now) && iat <= now;
|
|
108
|
+
}
|
|
109
|
+
isNewerThan(token) {
|
|
110
|
+
return this.payload.iat > token.payload.iat;
|
|
111
|
+
}
|
|
112
|
+
async matchesKeyId(apiKey) {
|
|
113
|
+
return this.headers.kid === await apiKey.getIdentifierHash();
|
|
114
|
+
}
|
|
115
|
+
getHeaders() {
|
|
116
|
+
return { ...this.headers };
|
|
117
|
+
}
|
|
118
|
+
getPayload() {
|
|
119
|
+
return { ...this.payload };
|
|
120
|
+
}
|
|
121
|
+
getSignature() {
|
|
122
|
+
return this.signature;
|
|
123
|
+
}
|
|
124
|
+
getApplicationId() {
|
|
125
|
+
return this.headers.appId ?? null;
|
|
126
|
+
}
|
|
127
|
+
getAlgorithm() {
|
|
128
|
+
return this.headers.alg;
|
|
129
|
+
}
|
|
130
|
+
getType() {
|
|
131
|
+
return this.headers.typ;
|
|
132
|
+
}
|
|
133
|
+
getKeyId() {
|
|
134
|
+
return this.headers.kid ?? null;
|
|
135
|
+
}
|
|
136
|
+
getSubject() {
|
|
137
|
+
return this.payload.sub ?? null;
|
|
138
|
+
}
|
|
139
|
+
getIssueTime() {
|
|
140
|
+
return this.payload.iat;
|
|
141
|
+
}
|
|
142
|
+
getExpirationTime() {
|
|
143
|
+
return this.payload.exp ?? null;
|
|
144
|
+
}
|
|
145
|
+
getTokenId() {
|
|
146
|
+
return this.payload.jti ?? null;
|
|
147
|
+
}
|
|
148
|
+
getAudience() {
|
|
149
|
+
return this.payload.aud;
|
|
150
|
+
}
|
|
151
|
+
getIssuer() {
|
|
152
|
+
return this.payload.iss;
|
|
153
|
+
}
|
|
154
|
+
withTokenId(tokenId) {
|
|
155
|
+
if (tokenId === "" || !_Token.UUID_PATTERN.test(tokenId)) {
|
|
156
|
+
throw new Error("The token ID must be a valid UUID.");
|
|
157
|
+
}
|
|
158
|
+
return new _Token(
|
|
159
|
+
this.headers,
|
|
160
|
+
{
|
|
161
|
+
...this.payload,
|
|
162
|
+
jti: tokenId
|
|
163
|
+
},
|
|
164
|
+
this.signature
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
withDuration(duration, now = Math.floor(Date.now() / 1e3)) {
|
|
168
|
+
return new _Token(
|
|
169
|
+
this.headers,
|
|
170
|
+
{
|
|
171
|
+
...this.payload,
|
|
172
|
+
iat: now,
|
|
173
|
+
exp: now + duration
|
|
174
|
+
},
|
|
175
|
+
this.signature
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
withAddedHeaders(headers) {
|
|
179
|
+
return this.withHeaders({
|
|
180
|
+
...this.headers,
|
|
181
|
+
...Object.fromEntries(
|
|
182
|
+
Object.entries(headers).filter(([, value]) => value !== void 0)
|
|
183
|
+
)
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
withAddedClaims(claims) {
|
|
187
|
+
return this.withPayload({
|
|
188
|
+
...this.payload,
|
|
189
|
+
...Object.fromEntries(
|
|
190
|
+
Object.entries(claims).filter(([, value]) => value !== void 0)
|
|
191
|
+
)
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
withHeaders(headers) {
|
|
195
|
+
return new _Token(
|
|
196
|
+
headers,
|
|
197
|
+
this.payload,
|
|
198
|
+
this.signature
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
withPayload(payload) {
|
|
202
|
+
return new _Token(
|
|
203
|
+
this.headers,
|
|
204
|
+
payload,
|
|
205
|
+
this.signature
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
withSignature(signature) {
|
|
209
|
+
return new _Token(
|
|
210
|
+
this.headers,
|
|
211
|
+
this.payload,
|
|
212
|
+
signature
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
toJSON() {
|
|
216
|
+
return this.toString();
|
|
217
|
+
}
|
|
218
|
+
toString() {
|
|
219
|
+
const headers = (0, import_base64Url.base64UrlEncode)(JSON.stringify(this.headers), true);
|
|
220
|
+
const payload = (0, import_base64Url.base64UrlEncode)(JSON.stringify(this.payload), true);
|
|
221
|
+
return `${headers}.${payload}.${this.signature}`;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
_Token.UUID_PATTERN = /^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$/;
|
|
225
|
+
let Token = _Token;
|
|
226
|
+
class FixedTokenProvider {
|
|
227
|
+
constructor(token) {
|
|
228
|
+
this.token = token;
|
|
229
|
+
}
|
|
230
|
+
getToken() {
|
|
231
|
+
return this.token;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
235
|
+
0 && (module.exports = {
|
|
236
|
+
FixedTokenProvider,
|
|
237
|
+
Token
|
|
238
|
+
});
|
|
239
|
+
//# sourceMappingURL=token.cjs.map
|
package/tracker.cjs
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var tracker_exports = {};
|
|
19
|
+
__export(tracker_exports, {
|
|
20
|
+
Tracker: () => Tracker
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(tracker_exports);
|
|
23
|
+
var import_logging = require("./logging");
|
|
24
|
+
var import_error = require("./error");
|
|
25
|
+
var import_trackingEvents = require("./trackingEvents");
|
|
26
|
+
const trackedEvents = {};
|
|
27
|
+
class Tracker {
|
|
28
|
+
constructor(config) {
|
|
29
|
+
this.listeners = [];
|
|
30
|
+
this.pending = [];
|
|
31
|
+
this.state = {
|
|
32
|
+
enabled: false,
|
|
33
|
+
initialized: false,
|
|
34
|
+
suspended: false
|
|
35
|
+
};
|
|
36
|
+
this.inactivityTimer = {
|
|
37
|
+
since: 0
|
|
38
|
+
};
|
|
39
|
+
const { tab, tokenProvider, channel, logger, inactivityRetryPolicy, ...options } = config;
|
|
40
|
+
this.tab = tab;
|
|
41
|
+
this.tokenProvider = tokenProvider;
|
|
42
|
+
this.inactivityRetryPolicy = inactivityRetryPolicy;
|
|
43
|
+
this.channel = channel;
|
|
44
|
+
this.logger = logger ?? new import_logging.NullLogger();
|
|
45
|
+
this.processor = config.processor;
|
|
46
|
+
this.options = {
|
|
47
|
+
...options,
|
|
48
|
+
eventMetadata: options.eventMetadata ?? {}
|
|
49
|
+
};
|
|
50
|
+
this.enable = this.enable.bind(this);
|
|
51
|
+
this.disable = this.disable.bind(this);
|
|
52
|
+
this.suspend = this.suspend.bind(this);
|
|
53
|
+
this.unsuspend = this.unsuspend.bind(this);
|
|
54
|
+
this.trackPageLoad = this.trackPageLoad.bind(this);
|
|
55
|
+
this.trackTabVisibilityChange = this.trackTabVisibilityChange.bind(this);
|
|
56
|
+
this.trackTabUrlChange = this.trackTabUrlChange.bind(this);
|
|
57
|
+
this.trackInactivity = this.trackInactivity.bind(this);
|
|
58
|
+
}
|
|
59
|
+
addListener(listener) {
|
|
60
|
+
this.listeners.push(listener);
|
|
61
|
+
}
|
|
62
|
+
removeListener(listener) {
|
|
63
|
+
let index = this.listeners.indexOf(listener);
|
|
64
|
+
while (index >= 0) {
|
|
65
|
+
this.listeners.splice(index, 1);
|
|
66
|
+
index = this.listeners.indexOf(listener);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
get flushed() {
|
|
70
|
+
const suppress = () => {
|
|
71
|
+
};
|
|
72
|
+
return Promise.all(this.pending).then(suppress, suppress);
|
|
73
|
+
}
|
|
74
|
+
isEnabled() {
|
|
75
|
+
return this.state.enabled;
|
|
76
|
+
}
|
|
77
|
+
isSuspended() {
|
|
78
|
+
return this.state.suspended;
|
|
79
|
+
}
|
|
80
|
+
enable() {
|
|
81
|
+
if (this.state.enabled) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this.logger.info("Tracker enabled");
|
|
85
|
+
this.state.enabled = true;
|
|
86
|
+
if (this.state.suspended) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.startInactivityTimer();
|
|
90
|
+
if (!this.state.initialized) {
|
|
91
|
+
this.state.initialized = true;
|
|
92
|
+
this.initialize();
|
|
93
|
+
}
|
|
94
|
+
this.tab.addListener("load", this.trackPageLoad);
|
|
95
|
+
this.tab.addListener("urlChange", this.trackTabUrlChange);
|
|
96
|
+
this.tab.addListener("visibilityChange", this.trackTabVisibilityChange);
|
|
97
|
+
}
|
|
98
|
+
disable() {
|
|
99
|
+
if (!this.state.enabled) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.logger.info("Tracker disabled");
|
|
103
|
+
this.state.enabled = false;
|
|
104
|
+
if (this.state.suspended) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.tab.removeListener("load", this.trackPageLoad);
|
|
108
|
+
this.tab.removeListener("urlChange", this.trackTabUrlChange);
|
|
109
|
+
this.tab.removeListener("visibilityChange", this.trackTabVisibilityChange);
|
|
110
|
+
this.stopInactivityTimer();
|
|
111
|
+
}
|
|
112
|
+
suspend() {
|
|
113
|
+
if (this.state.suspended) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.logger.info("Tracker suspended");
|
|
117
|
+
if (this.state.enabled) {
|
|
118
|
+
this.disable();
|
|
119
|
+
this.state.enabled = true;
|
|
120
|
+
}
|
|
121
|
+
this.state.suspended = true;
|
|
122
|
+
}
|
|
123
|
+
unsuspend() {
|
|
124
|
+
if (!this.state.suspended) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
this.logger.info("Tracker unsuspended");
|
|
128
|
+
this.state.suspended = false;
|
|
129
|
+
if (this.state.enabled) {
|
|
130
|
+
this.state.enabled = false;
|
|
131
|
+
this.enable();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
initialize() {
|
|
135
|
+
if (trackedEvents[this.tab.id] === void 0) {
|
|
136
|
+
trackedEvents[this.tab.id] = {};
|
|
137
|
+
}
|
|
138
|
+
const initEvents = trackedEvents[this.tab.id];
|
|
139
|
+
if (this.tab.isNew && !initEvents.tabOpened) {
|
|
140
|
+
initEvents.tabOpened = true;
|
|
141
|
+
this.trackTabOpen({ tabId: this.tab.id });
|
|
142
|
+
}
|
|
143
|
+
if (!initEvents.pageOpened) {
|
|
144
|
+
initEvents.pageOpened = true;
|
|
145
|
+
this.trackPageOpen({
|
|
146
|
+
url: this.tab.url,
|
|
147
|
+
referrer: this.tab.referrer
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
stopInactivityTimer() {
|
|
152
|
+
if (this.inactivityTimer.id !== void 0) {
|
|
153
|
+
window.clearTimeout(this.inactivityTimer.id);
|
|
154
|
+
delete this.inactivityTimer.id;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
startInactivityTimer() {
|
|
158
|
+
this.stopInactivityTimer();
|
|
159
|
+
this.inactivityTimer.since = Date.now();
|
|
160
|
+
let iteration = -1;
|
|
161
|
+
const startTimer = () => {
|
|
162
|
+
if (!this.inactivityRetryPolicy.shouldRetry(iteration + 1, this.inactivityTimer.since)) {
|
|
163
|
+
window.clearTimeout(this.inactivityTimer.id);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
iteration += 1;
|
|
167
|
+
this.inactivityTimer.id = window.setTimeout(
|
|
168
|
+
() => {
|
|
169
|
+
this.trackInactivity();
|
|
170
|
+
startTimer();
|
|
171
|
+
},
|
|
172
|
+
this.inactivityRetryPolicy.getDelay(iteration)
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
startTimer();
|
|
176
|
+
}
|
|
177
|
+
track(event, timestamp = Date.now()) {
|
|
178
|
+
return this.dispatch(this.enrichEvent(event, timestamp), timestamp).then(() => event);
|
|
179
|
+
}
|
|
180
|
+
trackPageOpen({ referrer, ...payload }) {
|
|
181
|
+
this.enqueue({
|
|
182
|
+
type: "pageOpened",
|
|
183
|
+
...payload,
|
|
184
|
+
...referrer.length > 0 ? { referrer } : {}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
trackPageLoad({ detail: { tab } }) {
|
|
188
|
+
this.enqueue({
|
|
189
|
+
type: "pageLoaded",
|
|
190
|
+
url: tab.url,
|
|
191
|
+
title: tab.title,
|
|
192
|
+
lastModifiedTime: Date.parse(tab.document.lastModified)
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
trackTabOpen(payload) {
|
|
196
|
+
this.enqueue({
|
|
197
|
+
type: "tabOpened",
|
|
198
|
+
...payload
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
trackTabUrlChange({ detail }) {
|
|
202
|
+
this.enqueue({
|
|
203
|
+
type: "tabUrlChanged",
|
|
204
|
+
tabId: detail.tab.id,
|
|
205
|
+
url: detail.url
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
trackTabVisibilityChange({ detail }) {
|
|
209
|
+
this.enqueue({
|
|
210
|
+
type: "tabVisibilityChanged",
|
|
211
|
+
tabId: detail.tab.id,
|
|
212
|
+
visibility: detail.visible ? "visible" : "hidden"
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
trackInactivity() {
|
|
216
|
+
this.enqueue({
|
|
217
|
+
type: "nothingChanged",
|
|
218
|
+
sinceTime: this.inactivityTimer.since
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
enqueue(event, timestamp = Date.now()) {
|
|
222
|
+
this.dispatch(event, timestamp).catch(() => {
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
notifyEvent(event) {
|
|
226
|
+
this.listeners.map((listener) => listener(event));
|
|
227
|
+
}
|
|
228
|
+
dispatch(event, timestamp) {
|
|
229
|
+
const userToken = this.tokenProvider.getToken();
|
|
230
|
+
const metadata = this.options.eventMetadata;
|
|
231
|
+
const context = {
|
|
232
|
+
tabId: this.tab.id,
|
|
233
|
+
url: this.tab.url,
|
|
234
|
+
...Object.keys(metadata).length > 0 ? { metadata } : {}
|
|
235
|
+
};
|
|
236
|
+
const queuedEvent = {
|
|
237
|
+
...userToken !== null ? { userToken } : {},
|
|
238
|
+
event,
|
|
239
|
+
timestamp,
|
|
240
|
+
context
|
|
241
|
+
};
|
|
242
|
+
const processedEvents = this.processor !== void 0 ? this.processor.process(queuedEvent) : [queuedEvent];
|
|
243
|
+
processedEvents.sort((left, right) => left.timestamp - right.timestamp);
|
|
244
|
+
let result = null;
|
|
245
|
+
for (const processedEvent of processedEvents) {
|
|
246
|
+
if (processedEvent === queuedEvent) {
|
|
247
|
+
result = this.publish(queuedEvent);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
this.publish(processedEvent);
|
|
251
|
+
}
|
|
252
|
+
if (result === null) {
|
|
253
|
+
return Promise.reject(new Error("Event suppressed."));
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
publish(queuedEvent) {
|
|
258
|
+
const { event } = queuedEvent;
|
|
259
|
+
if (event.type !== "nothingChanged") {
|
|
260
|
+
this.stopInactivityTimer();
|
|
261
|
+
}
|
|
262
|
+
const eventInfo = {
|
|
263
|
+
...queuedEvent,
|
|
264
|
+
status: "pending"
|
|
265
|
+
};
|
|
266
|
+
if (this.state.suspended) {
|
|
267
|
+
this.logger.warn(`Tracker is suspended, ignoring event "${event.type}"`);
|
|
268
|
+
this.notifyEvent({ ...eventInfo, status: "ignored" });
|
|
269
|
+
return Promise.reject(new Error("The tracker is suspended."));
|
|
270
|
+
}
|
|
271
|
+
this.logger.info(`Tracked event "${event.type}"`);
|
|
272
|
+
this.notifyEvent(eventInfo);
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
const promise = this.channel.publish(this.createBeacon(queuedEvent)).then(
|
|
275
|
+
() => {
|
|
276
|
+
this.logger.debug(`Successfully published event "${event.type}"`);
|
|
277
|
+
this.notifyEvent({ ...eventInfo, status: "confirmed" });
|
|
278
|
+
resolve(event);
|
|
279
|
+
},
|
|
280
|
+
(cause) => {
|
|
281
|
+
this.logger.error(`Failed to publish event "${event.type}", reason: ${(0, import_error.formatCause)(cause)}`);
|
|
282
|
+
this.notifyEvent({ ...eventInfo, status: "failed" });
|
|
283
|
+
reject(cause);
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
this.pending.push(promise);
|
|
287
|
+
promise.finally(() => {
|
|
288
|
+
this.pending.splice(this.pending.indexOf(promise), 1);
|
|
289
|
+
});
|
|
290
|
+
if (this.state.enabled && event.type !== "nothingChanged") {
|
|
291
|
+
this.startInactivityTimer();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
enrichEvent(event, timestamp) {
|
|
296
|
+
if ((0, import_trackingEvents.isCartPartialEvent)(event)) {
|
|
297
|
+
const { cart: { lastUpdateTime = timestamp, ...cart }, ...payload } = event;
|
|
298
|
+
return {
|
|
299
|
+
...payload,
|
|
300
|
+
cart: {
|
|
301
|
+
...cart,
|
|
302
|
+
lastUpdateTime
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
return event;
|
|
307
|
+
}
|
|
308
|
+
createBeacon({ event, timestamp, context, userToken }) {
|
|
309
|
+
return {
|
|
310
|
+
timestamp,
|
|
311
|
+
...userToken !== void 0 ? { token: userToken.toString() } : {},
|
|
312
|
+
context,
|
|
313
|
+
payload: this.enrichBeaconPayload(this.createBeaconPayload(event))
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
createBeaconPayload(event) {
|
|
317
|
+
if (!(0, import_trackingEvents.isIdentifiedUserEvent)(event)) {
|
|
318
|
+
return event;
|
|
319
|
+
}
|
|
320
|
+
if (event.type === "userSignedUp" && event.profile !== void 0) {
|
|
321
|
+
const { userId: userId2, profile, ...payload2 } = event;
|
|
322
|
+
return {
|
|
323
|
+
...payload2,
|
|
324
|
+
externalUserId: userId2,
|
|
325
|
+
patch: {
|
|
326
|
+
operations: [
|
|
327
|
+
{
|
|
328
|
+
type: "merge",
|
|
329
|
+
path: ".",
|
|
330
|
+
value: profile
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
const { userId, ...payload } = event;
|
|
337
|
+
return {
|
|
338
|
+
...payload,
|
|
339
|
+
externalUserId: userId
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
enrichBeaconPayload(event) {
|
|
343
|
+
switch (event.type) {
|
|
344
|
+
case "linkOpened":
|
|
345
|
+
return {
|
|
346
|
+
...event,
|
|
347
|
+
link: new URL(event.link, this.tab.url).toString()
|
|
348
|
+
};
|
|
349
|
+
default:
|
|
350
|
+
return event;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
355
|
+
0 && (module.exports = {
|
|
356
|
+
Tracker
|
|
357
|
+
});
|
|
358
|
+
//# sourceMappingURL=tracker.cjs.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var trackingEvents_exports = {};
|
|
19
|
+
__export(trackingEvents_exports, {
|
|
20
|
+
cartEventTypes: () => cartEventTypes,
|
|
21
|
+
ecommerceEventTypes: () => ecommerceEventTypes,
|
|
22
|
+
eventTypes: () => eventTypes,
|
|
23
|
+
identifiedUserEventTypes: () => identifiedUserEventTypes,
|
|
24
|
+
isCartPartialEvent: () => isCartPartialEvent,
|
|
25
|
+
isIdentifiedUserEvent: () => isIdentifiedUserEvent,
|
|
26
|
+
miscEventTypes: () => miscEventTypes,
|
|
27
|
+
pageEventTypes: () => pageEventTypes,
|
|
28
|
+
tabEventTypes: () => tabEventTypes,
|
|
29
|
+
userEventTypes: () => userEventTypes
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(trackingEvents_exports);
|
|
32
|
+
const pageEventTypes = [
|
|
33
|
+
"pageLoaded",
|
|
34
|
+
"pageOpened"
|
|
35
|
+
];
|
|
36
|
+
const tabEventTypes = [
|
|
37
|
+
"tabOpened",
|
|
38
|
+
"tabUrlChanged",
|
|
39
|
+
"tabVisibilityChanged"
|
|
40
|
+
];
|
|
41
|
+
const cartEventTypes = [
|
|
42
|
+
"cartModified",
|
|
43
|
+
"cartViewed",
|
|
44
|
+
"checkoutStarted"
|
|
45
|
+
];
|
|
46
|
+
const ecommerceEventTypes = [
|
|
47
|
+
...cartEventTypes,
|
|
48
|
+
"orderPlaced",
|
|
49
|
+
"productViewed"
|
|
50
|
+
];
|
|
51
|
+
const identifiedUserEventTypes = [
|
|
52
|
+
"userSignedIn",
|
|
53
|
+
"userSignedOut",
|
|
54
|
+
"userSignedUp"
|
|
55
|
+
];
|
|
56
|
+
const userEventTypes = [
|
|
57
|
+
...identifiedUserEventTypes,
|
|
58
|
+
"userProfileChanged"
|
|
59
|
+
];
|
|
60
|
+
const miscEventTypes = [
|
|
61
|
+
"nothingChanged",
|
|
62
|
+
"sessionAttributesChanged",
|
|
63
|
+
"goalCompleted",
|
|
64
|
+
"interestShown",
|
|
65
|
+
"postViewed",
|
|
66
|
+
"eventOccurred",
|
|
67
|
+
"linkOpened"
|
|
68
|
+
];
|
|
69
|
+
const eventTypes = [
|
|
70
|
+
...pageEventTypes,
|
|
71
|
+
...ecommerceEventTypes,
|
|
72
|
+
...userEventTypes,
|
|
73
|
+
...miscEventTypes
|
|
74
|
+
];
|
|
75
|
+
function isIdentifiedUserEvent(event) {
|
|
76
|
+
return identifiedUserEventTypes.includes(event.type);
|
|
77
|
+
}
|
|
78
|
+
function isCartPartialEvent(event) {
|
|
79
|
+
return cartEventTypes.includes(event.type);
|
|
80
|
+
}
|
|
81
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
82
|
+
0 && (module.exports = {
|
|
83
|
+
cartEventTypes,
|
|
84
|
+
ecommerceEventTypes,
|
|
85
|
+
eventTypes,
|
|
86
|
+
identifiedUserEventTypes,
|
|
87
|
+
isCartPartialEvent,
|
|
88
|
+
isIdentifiedUserEvent,
|
|
89
|
+
miscEventTypes,
|
|
90
|
+
pageEventTypes,
|
|
91
|
+
tabEventTypes,
|
|
92
|
+
userEventTypes
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=trackingEvents.cjs.map
|
package/transformer.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var transformer_exports = {};
|
|
19
|
+
__export(transformer_exports, {
|
|
20
|
+
encodeJson: () => encodeJson
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(transformer_exports);
|
|
23
|
+
const encodeJson = function encodeJson2(input) {
|
|
24
|
+
return Promise.resolve(JSON.stringify(input));
|
|
25
|
+
};
|
|
26
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
27
|
+
0 && (module.exports = {
|
|
28
|
+
encodeJson
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=transformer.cjs.map
|