plugeen 0.0.7 → 0.0.9
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/index.cjs +465 -588
- package/dist/index.js +464 -562
- package/dist/plugeen.global.js +2 -14
- package/package.json +20 -33
- package/dist/index.d.cts +0 -118
- package/dist/index.d.ts +0 -118
package/dist/index.cjs
CHANGED
|
@@ -1,651 +1,528 @@
|
|
|
1
|
-
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var src_exports = {};
|
|
22
|
-
__export(src_exports, {
|
|
23
|
-
createPlugeen: () => createPlugeen
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(src_exports);
|
|
1
|
+
'use strict';
|
|
26
2
|
|
|
27
|
-
// src/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// src/lib/helpers/storage.ts
|
|
32
|
-
function withPrefix(key) {
|
|
33
|
-
return `${APP_PREFIX}_${key}`;
|
|
34
|
-
}
|
|
35
|
-
function ensureServerStore() {
|
|
36
|
-
if (!globalThis.Plugeen) {
|
|
37
|
-
globalThis.Plugeen = {};
|
|
3
|
+
// src/helpers/uuid.ts
|
|
4
|
+
function generateUUID() {
|
|
5
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
6
|
+
return crypto.randomUUID();
|
|
38
7
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
8
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
9
|
+
const bytes = new Uint8Array(16);
|
|
10
|
+
crypto.getRandomValues(bytes);
|
|
11
|
+
bytes[6] = bytes[6] & 15 | 64;
|
|
12
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
13
|
+
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
14
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
15
|
+
}
|
|
16
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
17
|
+
const r = Math.floor(Math.random() * 16);
|
|
18
|
+
return (c === "x" ? r : r & 3 | 8).toString(16);
|
|
19
|
+
});
|
|
51
20
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return JSON.parse(raw);
|
|
66
|
-
} catch {
|
|
67
|
-
return void 0;
|
|
21
|
+
|
|
22
|
+
// src/storage.ts
|
|
23
|
+
var IDENTITY_KEY = "plugeen_anon_id";
|
|
24
|
+
var SESSION_KEY = "plugeen_session_id";
|
|
25
|
+
var SESSION_TS_KEY = "plugeen_session_ts";
|
|
26
|
+
var SESSION_TTL = 18e5;
|
|
27
|
+
var memStore = {};
|
|
28
|
+
function getOrCreateIdentityId() {
|
|
29
|
+
try {
|
|
30
|
+
let id = localStorage.getItem(IDENTITY_KEY);
|
|
31
|
+
if (!id) {
|
|
32
|
+
id = `anon_${generateUUID()}`;
|
|
33
|
+
localStorage.setItem(IDENTITY_KEY, id);
|
|
68
34
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (typeof window === "undefined") return serverStorage();
|
|
77
|
-
return clientStorage();
|
|
35
|
+
return id;
|
|
36
|
+
} catch {
|
|
37
|
+
if (!memStore[IDENTITY_KEY]) {
|
|
38
|
+
memStore[IDENTITY_KEY] = `anon_${generateUUID()}`;
|
|
39
|
+
}
|
|
40
|
+
return memStore[IDENTITY_KEY];
|
|
41
|
+
}
|
|
78
42
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const newId = crypto.randomUUID();
|
|
86
|
-
storage.set("identity", newId);
|
|
87
|
-
return newId;
|
|
43
|
+
function setIdentityId(id) {
|
|
44
|
+
try {
|
|
45
|
+
localStorage.setItem(IDENTITY_KEY, id);
|
|
46
|
+
} catch {
|
|
47
|
+
memStore[IDENTITY_KEY] = id;
|
|
48
|
+
}
|
|
88
49
|
}
|
|
89
|
-
|
|
90
|
-
// src/lib/helpers/session.ts
|
|
91
|
-
var SESSION_KEY = "pl_session";
|
|
92
50
|
function getOrCreateSessionId() {
|
|
93
51
|
try {
|
|
94
|
-
if (typeof window === "undefined") return "";
|
|
95
52
|
const existing = sessionStorage.getItem(SESSION_KEY);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
53
|
+
const ts = sessionStorage.getItem(SESSION_TS_KEY);
|
|
54
|
+
if (existing && ts && Date.now() - parseInt(ts, 10) < SESSION_TTL) {
|
|
55
|
+
sessionStorage.setItem(SESSION_TS_KEY, String(Date.now()));
|
|
56
|
+
return existing;
|
|
57
|
+
}
|
|
58
|
+
sessionStorage.removeItem(SESSION_KEY);
|
|
59
|
+
sessionStorage.removeItem(SESSION_TS_KEY);
|
|
60
|
+
const id = `sess_${generateUUID()}`;
|
|
100
61
|
sessionStorage.setItem(SESSION_KEY, id);
|
|
62
|
+
sessionStorage.setItem(SESSION_TS_KEY, String(Date.now()));
|
|
63
|
+
return id;
|
|
64
|
+
} catch {
|
|
65
|
+
const existing = memStore[SESSION_KEY];
|
|
66
|
+
const ts = memStore[SESSION_TS_KEY];
|
|
67
|
+
if (existing && ts && Date.now() - parseInt(ts, 10) < SESSION_TTL) {
|
|
68
|
+
memStore[SESSION_TS_KEY] = String(Date.now());
|
|
69
|
+
return existing;
|
|
70
|
+
}
|
|
71
|
+
const id = `sess_${generateUUID()}`;
|
|
72
|
+
memStore[SESSION_KEY] = id;
|
|
73
|
+
memStore[SESSION_TS_KEY] = String(Date.now());
|
|
101
74
|
return id;
|
|
102
75
|
}
|
|
103
76
|
}
|
|
104
77
|
|
|
105
|
-
// src/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (method === "POST" || method === "PUT") {
|
|
113
|
-
headers.set("Content-Type", "application/json");
|
|
78
|
+
// src/helpers/http-client/index.ts
|
|
79
|
+
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
80
|
+
var HttpClient = class {
|
|
81
|
+
constructor(baseUrl, apiKey, maxRetries = 3) {
|
|
82
|
+
this.baseUrl = baseUrl;
|
|
83
|
+
this.apiKey = apiKey;
|
|
84
|
+
this.maxRetries = maxRetries;
|
|
114
85
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
86
|
+
headers(method) {
|
|
87
|
+
const h = {
|
|
88
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
89
|
+
"x-identity-id": getOrCreateIdentityId(),
|
|
90
|
+
"x-session-id": getOrCreateSessionId()
|
|
91
|
+
};
|
|
92
|
+
if (method !== "GET") h["Content-Type"] = "application/json";
|
|
93
|
+
return h;
|
|
94
|
+
}
|
|
95
|
+
async request(path, { attempt = 0, method, body }) {
|
|
96
|
+
const url = `${this.baseUrl}${path}`;
|
|
97
|
+
try {
|
|
98
|
+
const res = await fetch(url, {
|
|
99
|
+
method,
|
|
100
|
+
headers: this.headers(method),
|
|
101
|
+
credentials: "omit",
|
|
102
|
+
body: body ? JSON.stringify(body) : void 0
|
|
103
|
+
});
|
|
104
|
+
if (res.status === 401 || res.status === 404) return [null, res.status];
|
|
105
|
+
if ((res.status >= 500 || res.status === 429) && attempt < this.maxRetries) {
|
|
106
|
+
const jitter = 0.85 + Math.random() * 0.3;
|
|
107
|
+
await delay(500 * 2 ** attempt * jitter);
|
|
108
|
+
return this.request(path, {
|
|
109
|
+
body,
|
|
110
|
+
attempt: attempt + 1,
|
|
111
|
+
method
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (res.status >= 200 && res.status < 300) {
|
|
115
|
+
try {
|
|
116
|
+
const json = await res.json();
|
|
117
|
+
return [json.data, null];
|
|
118
|
+
} catch {
|
|
119
|
+
return [null, "Failed to parse json"];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return [null, "Error"];
|
|
123
|
+
} catch (err) {
|
|
124
|
+
if (err instanceof TypeError && attempt < this.maxRetries) {
|
|
125
|
+
const jitter = 0.85 + Math.random() * 0.3;
|
|
126
|
+
await delay(500 * 2 ** attempt * jitter);
|
|
127
|
+
return this.get(path, attempt + 1);
|
|
128
|
+
}
|
|
129
|
+
return [null, err];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async post(path, body, attempt = 0) {
|
|
133
|
+
return this.request(path, {
|
|
134
|
+
attempt,
|
|
135
|
+
body,
|
|
136
|
+
method: "POST"
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async get(path, attempt = 0) {
|
|
140
|
+
return this.request(path, {
|
|
141
|
+
attempt,
|
|
142
|
+
method: "GET"
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
beacon(path, body) {
|
|
146
|
+
if (typeof navigator === "undefined" || !navigator.sendBeacon) return false;
|
|
147
|
+
try {
|
|
148
|
+
const blob = new Blob([JSON.stringify(body)], {
|
|
149
|
+
type: "application/json"
|
|
150
|
+
});
|
|
151
|
+
return navigator.sendBeacon(`${this.baseUrl}${path}`, blob);
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// src/plugins/events/index.ts
|
|
159
|
+
function createEventsModule(http) {
|
|
125
160
|
return {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
161
|
+
create: async (name, data = {}) => {
|
|
162
|
+
return http.post("/events", { name, data, source: "api" });
|
|
163
|
+
}
|
|
129
164
|
};
|
|
130
|
-
}
|
|
165
|
+
}
|
|
131
166
|
|
|
132
|
-
// src/
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
title: document.title,
|
|
140
|
-
referrer: document.referrer ?? "",
|
|
141
|
-
screenWidth: window.screen.width,
|
|
142
|
-
screenHeight: window.screen.height,
|
|
143
|
-
sessionId: getOrCreateSessionId()
|
|
167
|
+
// src/plugins/identities/index.ts
|
|
168
|
+
function createIdentitiesModule(http) {
|
|
169
|
+
return {
|
|
170
|
+
create: async (distinctId, data = {}) => {
|
|
171
|
+
const result = await http.post("/identities", {
|
|
172
|
+
id: distinctId,
|
|
173
|
+
...data
|
|
144
174
|
});
|
|
175
|
+
setIdentityId(distinctId);
|
|
176
|
+
return result;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/plugins/analytics/index.ts
|
|
182
|
+
function initAnalyticsPlugin(http) {
|
|
183
|
+
if (typeof window === "undefined") return;
|
|
184
|
+
let pageStartTime = Date.now();
|
|
185
|
+
let pageCount = 0;
|
|
186
|
+
let currentUrl = window.location.href;
|
|
187
|
+
const trackPageView = () => {
|
|
188
|
+
pageCount++;
|
|
189
|
+
void http.post("/v1/analytics", {
|
|
190
|
+
event: "page_view",
|
|
191
|
+
url: window.location.href,
|
|
192
|
+
title: document.title,
|
|
193
|
+
sessionId: getOrCreateSessionId(),
|
|
194
|
+
referrer: document.referrer || void 0,
|
|
195
|
+
screenWidth: window.innerWidth,
|
|
196
|
+
screenHeight: window.innerHeight
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
const trackPageExit = (useBeacon = false) => {
|
|
200
|
+
const data = {
|
|
201
|
+
event: "page_exit",
|
|
202
|
+
url: window.location.href,
|
|
203
|
+
title: document.title,
|
|
204
|
+
sessionId: getOrCreateSessionId(),
|
|
205
|
+
referrer: document.referrer || void 0,
|
|
206
|
+
screenWidth: window.innerWidth,
|
|
207
|
+
screenHeight: window.innerHeight,
|
|
208
|
+
metadata: {
|
|
209
|
+
timeOnPage: Math.round((Date.now() - pageStartTime) / 1e3),
|
|
210
|
+
pageCount
|
|
211
|
+
}
|
|
145
212
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
213
|
+
if (useBeacon) {
|
|
214
|
+
http.beacon("/v1/analytics", data);
|
|
215
|
+
} else {
|
|
216
|
+
void http.post("/v1/analytics", data);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const onRouteChange = () => {
|
|
220
|
+
if (window.location.href === currentUrl) return;
|
|
221
|
+
trackPageExit();
|
|
222
|
+
pageStartTime = Date.now();
|
|
223
|
+
currentUrl = window.location.href;
|
|
224
|
+
trackPageView();
|
|
225
|
+
};
|
|
226
|
+
const patchHistoryMethod = (method) => {
|
|
227
|
+
const original = history[method].bind(history);
|
|
228
|
+
history[method] = (...args) => {
|
|
229
|
+
original(...args);
|
|
230
|
+
onRouteChange();
|
|
155
231
|
};
|
|
156
|
-
window.addEventListener("popstate", () => changePage());
|
|
157
|
-
changePage();
|
|
158
232
|
};
|
|
159
|
-
|
|
233
|
+
patchHistoryMethod("pushState");
|
|
234
|
+
patchHistoryMethod("replaceState");
|
|
235
|
+
window.addEventListener("popstate", onRouteChange);
|
|
236
|
+
window.addEventListener("beforeunload", () => trackPageExit(true));
|
|
237
|
+
document.addEventListener("visibilitychange", () => {
|
|
238
|
+
if (document.visibilityState === "hidden") {
|
|
239
|
+
trackPageExit(true);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
trackPageView();
|
|
160
243
|
}
|
|
161
244
|
|
|
162
|
-
// src/
|
|
163
|
-
var
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
245
|
+
// src/plugins/logs/index.ts
|
|
246
|
+
var EXTENSION_PREFIXES = [
|
|
247
|
+
"chrome-extension://",
|
|
248
|
+
"moz-extension://",
|
|
249
|
+
"safari-extension://",
|
|
250
|
+
"edge-extension://"
|
|
251
|
+
];
|
|
252
|
+
function isExtensionSource(str) {
|
|
253
|
+
if (!str) return false;
|
|
254
|
+
const lower = str.toLowerCase();
|
|
255
|
+
return EXTENSION_PREFIXES.some((prefix) => lower.includes(prefix));
|
|
256
|
+
}
|
|
257
|
+
function initErrorsPlugin(http) {
|
|
258
|
+
if (typeof window === "undefined") return;
|
|
259
|
+
window.addEventListener("error", (event) => {
|
|
260
|
+
if (isExtensionSource(event.filename) || isExtensionSource(event.error?.stack))
|
|
261
|
+
return;
|
|
262
|
+
if (event.error === null && event.message === "Script error.") return;
|
|
263
|
+
void http.post("/v1/logs", {
|
|
264
|
+
message: event.message || "Unknown Error",
|
|
265
|
+
filename: event.filename,
|
|
266
|
+
lineno: event.lineno,
|
|
267
|
+
colno: event.colno,
|
|
268
|
+
stack: event.error?.stack,
|
|
269
|
+
error_type: event.error?.name || "Error"
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
window.addEventListener(
|
|
273
|
+
"unhandledrejection",
|
|
274
|
+
(event) => {
|
|
275
|
+
const { reason } = event;
|
|
276
|
+
if (isExtensionSource(reason?.stack))
|
|
277
|
+
return;
|
|
278
|
+
let message = "Unknown Error";
|
|
279
|
+
let stack;
|
|
280
|
+
if (reason instanceof Error) {
|
|
281
|
+
message = reason.message;
|
|
282
|
+
stack = reason.stack;
|
|
283
|
+
} else if (typeof reason === "string") {
|
|
284
|
+
message = reason;
|
|
285
|
+
} else if (reason !== null && typeof reason === "object" && "message" in reason) {
|
|
286
|
+
message = String(reason.message);
|
|
287
|
+
}
|
|
288
|
+
void http.post("/v1/logs", {
|
|
289
|
+
message,
|
|
290
|
+
stack,
|
|
291
|
+
error_type: "UnhandledRejection"
|
|
292
|
+
});
|
|
196
293
|
}
|
|
197
294
|
);
|
|
198
295
|
}
|
|
199
296
|
|
|
200
|
-
// src/
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return
|
|
297
|
+
// src/plugins/web-vitals/helpers.ts
|
|
298
|
+
function getRating(value, thresholds) {
|
|
299
|
+
if (value > thresholds[1]) return "poor";
|
|
300
|
+
if (value > thresholds[0]) return "needs-improvement";
|
|
301
|
+
return "good";
|
|
302
|
+
}
|
|
303
|
+
function getActivationStart() {
|
|
304
|
+
const nav = performance.getEntriesByType(
|
|
305
|
+
"navigation"
|
|
306
|
+
)[0];
|
|
307
|
+
return nav?.activationStart ?? 0;
|
|
308
|
+
}
|
|
309
|
+
function getNavEntry() {
|
|
310
|
+
const entry = performance.getEntriesByType("navigation")[0];
|
|
311
|
+
if (entry && entry.responseStart > 0 && entry.responseStart < performance.now())
|
|
312
|
+
return entry;
|
|
313
|
+
}
|
|
314
|
+
function observe(type, cb, opts) {
|
|
315
|
+
try {
|
|
316
|
+
if (!PerformanceObserver.supportedEntryTypes.includes(type)) return;
|
|
317
|
+
const po = new PerformanceObserver((list) => {
|
|
318
|
+
Promise.resolve().then(() => cb(list.getEntries()));
|
|
319
|
+
});
|
|
320
|
+
po.observe({
|
|
321
|
+
type,
|
|
322
|
+
buffered: true,
|
|
323
|
+
...opts ?? {}
|
|
324
|
+
});
|
|
325
|
+
return po;
|
|
326
|
+
} catch {
|
|
327
|
+
return void 0;
|
|
328
|
+
}
|
|
205
329
|
}
|
|
206
|
-
function
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
330
|
+
function observeFCP(cb) {
|
|
331
|
+
const reported = /* @__PURE__ */ new Set();
|
|
332
|
+
observe("paint", (entries) => {
|
|
333
|
+
for (const entry of entries) {
|
|
334
|
+
if (entry.name === "first-contentful-paint" && !reported.has("FCP")) {
|
|
335
|
+
reported.add("FCP");
|
|
336
|
+
const value = Math.max(entry.startTime - getActivationStart(), 0);
|
|
337
|
+
cb({
|
|
338
|
+
name: "FCP",
|
|
339
|
+
value: Math.round(value),
|
|
340
|
+
rating: getRating(value, [1800, 3e3])
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
217
344
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
updatedAt: Date.now()
|
|
231
|
-
});
|
|
232
|
-
if (!mounted.current) return;
|
|
233
|
-
setState({
|
|
234
|
-
data,
|
|
235
|
-
error: void 0,
|
|
236
|
-
isLoading: false,
|
|
237
|
-
isFetching: false
|
|
238
|
-
});
|
|
239
|
-
} catch (error) {
|
|
240
|
-
if (!mounted.current) return;
|
|
241
|
-
setState({
|
|
242
|
-
data: void 0,
|
|
243
|
-
error,
|
|
244
|
-
isLoading: false,
|
|
245
|
-
isFetching: false
|
|
345
|
+
}
|
|
346
|
+
function observeLCP(cb) {
|
|
347
|
+
let reported = false;
|
|
348
|
+
const po = observe("largest-contentful-paint", (entries) => {
|
|
349
|
+
if (reported) return;
|
|
350
|
+
const last = entries[entries.length - 1];
|
|
351
|
+
if (last) {
|
|
352
|
+
const value = Math.max(last.startTime - getActivationStart(), 0);
|
|
353
|
+
cb({
|
|
354
|
+
name: "LCP",
|
|
355
|
+
value: Math.round(value),
|
|
356
|
+
rating: getRating(value, [2500, 4e3])
|
|
246
357
|
});
|
|
247
358
|
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
359
|
+
});
|
|
360
|
+
if (!po) return;
|
|
361
|
+
const finalize = () => {
|
|
362
|
+
if (reported) return;
|
|
363
|
+
reported = true;
|
|
364
|
+
const records = po.takeRecords();
|
|
365
|
+
if (records.length > 0) {
|
|
366
|
+
const last = records[records.length - 1];
|
|
367
|
+
const value = Math.max(last.startTime - getActivationStart(), 0);
|
|
368
|
+
cb({
|
|
369
|
+
name: "LCP",
|
|
370
|
+
value: Math.round(value),
|
|
371
|
+
rating: getRating(value, [2500, 4e3])
|
|
259
372
|
});
|
|
260
|
-
if (isStale) {
|
|
261
|
-
fetchData(false);
|
|
262
|
-
}
|
|
263
|
-
} else {
|
|
264
|
-
fetchData(true);
|
|
265
|
-
}
|
|
266
|
-
return () => {
|
|
267
|
-
mounted.current = false;
|
|
268
|
-
};
|
|
269
|
-
}, [key]);
|
|
270
|
-
(0, import_hooks.useEffect)(() => {
|
|
271
|
-
let interval;
|
|
272
|
-
if (revalidateTime > 0) {
|
|
273
|
-
interval = setInterval(() => {
|
|
274
|
-
fetchData(false);
|
|
275
|
-
}, revalidateTime);
|
|
276
373
|
}
|
|
277
|
-
|
|
278
|
-
clearInterval(interval);
|
|
279
|
-
};
|
|
280
|
-
}, [revalidateTime]);
|
|
281
|
-
return {
|
|
282
|
-
...state,
|
|
283
|
-
refetch: () => fetchData(false)
|
|
374
|
+
po.disconnect();
|
|
284
375
|
};
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// src/lib/helpers/ui.ts
|
|
288
|
-
var import_preact = require("preact");
|
|
289
|
-
var noopUnmount = () => {
|
|
290
|
-
};
|
|
291
|
-
function getOrCreateRoot(target, id) {
|
|
292
|
-
const existing = document.getElementById(id);
|
|
293
|
-
if (existing instanceof HTMLDivElement) {
|
|
294
|
-
return existing;
|
|
376
|
+
for (const evt of ["keydown", "click", "visibilitychange"]) {
|
|
377
|
+
addEventListener(evt, finalize, { capture: true, once: true });
|
|
295
378
|
}
|
|
296
|
-
const container = document.createElement("div");
|
|
297
|
-
container.id = id;
|
|
298
|
-
target.appendChild(container);
|
|
299
|
-
return container;
|
|
300
379
|
}
|
|
301
|
-
function
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
if (el) {
|
|
327
|
-
(0, import_preact.render)(null, el);
|
|
328
|
-
el.remove();
|
|
380
|
+
function observeCLS(cb) {
|
|
381
|
+
let sessionValue = 0;
|
|
382
|
+
let sessionEntries = [];
|
|
383
|
+
let clsValue = 0;
|
|
384
|
+
observe("layout-shift", (entries) => {
|
|
385
|
+
for (const raw of entries) {
|
|
386
|
+
const entry = raw;
|
|
387
|
+
if (entry.hadRecentInput) continue;
|
|
388
|
+
const last = sessionEntries[sessionEntries.length - 1];
|
|
389
|
+
const first = sessionEntries[0];
|
|
390
|
+
if (sessionEntries.length > 0 && last && first && entry.startTime - last.startTime < 1e3 && entry.startTime - first.startTime < 5e3) {
|
|
391
|
+
sessionValue += entry.value;
|
|
392
|
+
sessionEntries.push(entry);
|
|
393
|
+
} else {
|
|
394
|
+
sessionValue = entry.value;
|
|
395
|
+
sessionEntries = [entry];
|
|
396
|
+
}
|
|
397
|
+
if (sessionValue > clsValue) {
|
|
398
|
+
clsValue = sessionValue;
|
|
399
|
+
const rounded = Math.round(clsValue * 1e4) / 1e4;
|
|
400
|
+
cb({
|
|
401
|
+
name: "CLS",
|
|
402
|
+
value: rounded,
|
|
403
|
+
rating: getRating(clsValue, [0.1, 0.25])
|
|
404
|
+
});
|
|
329
405
|
}
|
|
330
406
|
}
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// src/lib/plugins/chat/index.tsx
|
|
335
|
-
var import_jsx_runtime2 = require("preact/jsx-runtime");
|
|
336
|
-
var pluginName = "chats";
|
|
337
|
-
var text = (0, import_signals2.signal)("");
|
|
338
|
-
var open = (0, import_signals2.signal)(false);
|
|
339
|
-
var submitting = (0, import_signals2.signal)(false);
|
|
340
|
-
function FloatingChat({
|
|
341
|
-
api,
|
|
342
|
-
options: { accentColor, foregroundColor },
|
|
343
|
-
id
|
|
344
|
-
}) {
|
|
345
|
-
const identity = getStorage().get("identity");
|
|
346
|
-
const { data, refetch, isLoading, error } = useQuery({
|
|
347
|
-
queryKey: [id],
|
|
348
|
-
queryFn: async () => {
|
|
349
|
-
return await api.get("/plugins/chats");
|
|
350
|
-
},
|
|
351
|
-
revalidateTime: 1e4
|
|
352
407
|
});
|
|
353
|
-
const onSubmit = async () => {
|
|
354
|
-
submitting.value = true;
|
|
355
|
-
await api.post("/plugins/chats", {
|
|
356
|
-
text: text.value
|
|
357
|
-
});
|
|
358
|
-
await refetch();
|
|
359
|
-
text.value = "";
|
|
360
|
-
submitting.value = false;
|
|
361
|
-
};
|
|
362
|
-
if (!data && !error && isLoading) return null;
|
|
363
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
364
|
-
"div",
|
|
365
|
-
{
|
|
366
|
-
style: {
|
|
367
|
-
position: "fixed",
|
|
368
|
-
right: "24px",
|
|
369
|
-
bottom: "24px",
|
|
370
|
-
zIndex: "9999",
|
|
371
|
-
fontFamily: "system-ui, sans-serif"
|
|
372
|
-
},
|
|
373
|
-
children: [
|
|
374
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
375
|
-
"div",
|
|
376
|
-
{
|
|
377
|
-
style: {
|
|
378
|
-
width: "320px",
|
|
379
|
-
marginBottom: "12px",
|
|
380
|
-
borderRadius: "12px",
|
|
381
|
-
boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
|
|
382
|
-
background: "#fff",
|
|
383
|
-
overflow: "hidden",
|
|
384
|
-
maxHeight: open.value ? "500px" : "0px",
|
|
385
|
-
opacity: open.value ? 1 : 0,
|
|
386
|
-
transition: "all 0.4s ease"
|
|
387
|
-
},
|
|
388
|
-
children: [
|
|
389
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
390
|
-
"div",
|
|
391
|
-
{
|
|
392
|
-
style: {
|
|
393
|
-
background: accentColor,
|
|
394
|
-
color: "#fff",
|
|
395
|
-
padding: "14px 16px",
|
|
396
|
-
fontWeight: "600",
|
|
397
|
-
fontSize: "14px"
|
|
398
|
-
},
|
|
399
|
-
children: "Chat with us"
|
|
400
|
-
}
|
|
401
|
-
),
|
|
402
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
403
|
-
"div",
|
|
404
|
-
{
|
|
405
|
-
style: {
|
|
406
|
-
display: "grid",
|
|
407
|
-
height: "200px",
|
|
408
|
-
overflowY: "auto",
|
|
409
|
-
padding: "16px",
|
|
410
|
-
gap: "4px"
|
|
411
|
-
},
|
|
412
|
-
children: data?.messages.map((m, index) => {
|
|
413
|
-
const isMine = identity === m.identity.id;
|
|
414
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
415
|
-
"div",
|
|
416
|
-
{
|
|
417
|
-
style: {
|
|
418
|
-
justifySelf: isMine ? "start" : "end",
|
|
419
|
-
width: "max-content"
|
|
420
|
-
},
|
|
421
|
-
children: [
|
|
422
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
423
|
-
"p",
|
|
424
|
-
{
|
|
425
|
-
style: {
|
|
426
|
-
padding: "2px 8px",
|
|
427
|
-
borderRadius: "8px",
|
|
428
|
-
width: "max-content",
|
|
429
|
-
background: isMine ? "silver" : accentColor,
|
|
430
|
-
color: isMine ? "black" : foregroundColor
|
|
431
|
-
},
|
|
432
|
-
children: m.text
|
|
433
|
-
}
|
|
434
|
-
),
|
|
435
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
436
|
-
"span",
|
|
437
|
-
{
|
|
438
|
-
style: {
|
|
439
|
-
fontSize: "12px",
|
|
440
|
-
color: "silver",
|
|
441
|
-
textAlign: isMine ? "left" : "right"
|
|
442
|
-
},
|
|
443
|
-
children: new Date(m.createdAt).toLocaleDateString()
|
|
444
|
-
}
|
|
445
|
-
)
|
|
446
|
-
]
|
|
447
|
-
},
|
|
448
|
-
m.text + index.toString()
|
|
449
|
-
);
|
|
450
|
-
})
|
|
451
|
-
}
|
|
452
|
-
),
|
|
453
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
454
|
-
"form",
|
|
455
|
-
{
|
|
456
|
-
onSubmit: (e) => {
|
|
457
|
-
e.preventDefault();
|
|
458
|
-
onSubmit();
|
|
459
|
-
},
|
|
460
|
-
style: { padding: "12px 16px" },
|
|
461
|
-
children: [
|
|
462
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
463
|
-
"textarea",
|
|
464
|
-
{
|
|
465
|
-
value: text.value,
|
|
466
|
-
onInput: (e) => {
|
|
467
|
-
text.value = e.target?.value;
|
|
468
|
-
},
|
|
469
|
-
name: "message",
|
|
470
|
-
placeholder: "Send us a message\u2026",
|
|
471
|
-
rows: 3,
|
|
472
|
-
style: {
|
|
473
|
-
width: "100%",
|
|
474
|
-
border: "1px solid #e5e7eb",
|
|
475
|
-
borderRadius: "8px",
|
|
476
|
-
padding: "8px",
|
|
477
|
-
fontSize: "13px",
|
|
478
|
-
resize: "none",
|
|
479
|
-
outline: "none",
|
|
480
|
-
boxSizing: "border-box"
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
),
|
|
484
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Button, { fullWidth: true, disabled: !text.value, children: submitting.value ? "Sending" : "Send" })
|
|
485
|
-
]
|
|
486
|
-
}
|
|
487
|
-
)
|
|
488
|
-
]
|
|
489
|
-
}
|
|
490
|
-
),
|
|
491
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
492
|
-
"button",
|
|
493
|
-
{
|
|
494
|
-
type: "button",
|
|
495
|
-
onClick: () => {
|
|
496
|
-
open.value = !open.value;
|
|
497
|
-
},
|
|
498
|
-
"aria-label": "Open chat",
|
|
499
|
-
style: {
|
|
500
|
-
transform: `rotate(${open.value ? 180 : 0}deg)`,
|
|
501
|
-
transition: "transform 0.4s ease",
|
|
502
|
-
width: "52px",
|
|
503
|
-
height: "52px",
|
|
504
|
-
borderRadius: "50%",
|
|
505
|
-
background: accentColor,
|
|
506
|
-
border: "none",
|
|
507
|
-
cursor: "pointer",
|
|
508
|
-
display: "flex",
|
|
509
|
-
alignItems: "center",
|
|
510
|
-
justifyContent: "center",
|
|
511
|
-
boxShadow: "0 4px 16px rgba(0,0,0,0.18)",
|
|
512
|
-
marginLeft: "auto"
|
|
513
|
-
},
|
|
514
|
-
children: open.value ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_preact.X, { color: foregroundColor }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_preact.MessageCircle, { color: foregroundColor })
|
|
515
|
-
}
|
|
516
|
-
)
|
|
517
|
-
]
|
|
518
|
-
}
|
|
519
|
-
);
|
|
520
408
|
}
|
|
521
|
-
function
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
409
|
+
function observeTTFB(cb) {
|
|
410
|
+
const nav = getNavEntry();
|
|
411
|
+
if (!nav) return;
|
|
412
|
+
const value = Math.max(nav.responseStart - getActivationStart(), 0);
|
|
413
|
+
cb({
|
|
414
|
+
name: "TTFB",
|
|
415
|
+
value: Math.round(value),
|
|
416
|
+
rating: getRating(value, [800, 1800])
|
|
527
417
|
});
|
|
528
|
-
return render();
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
// src/lib/plugins/events/index.ts
|
|
532
|
-
function initEvents(api) {
|
|
533
|
-
return {
|
|
534
|
-
create: (eventName, data) => api.post("/events", {
|
|
535
|
-
name: eventName,
|
|
536
|
-
data
|
|
537
|
-
})
|
|
538
|
-
};
|
|
539
418
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
419
|
+
function observeINP(cb) {
|
|
420
|
+
const interactions = /* @__PURE__ */ new Map();
|
|
421
|
+
let worstDuration = 0;
|
|
422
|
+
observe(
|
|
423
|
+
"event",
|
|
424
|
+
(entries) => {
|
|
425
|
+
for (const raw of entries) {
|
|
426
|
+
const entry = raw;
|
|
427
|
+
if (!entry.interactionId) continue;
|
|
428
|
+
const existing = interactions.get(entry.interactionId) ?? 0;
|
|
429
|
+
if (entry.duration > existing) {
|
|
430
|
+
interactions.set(entry.interactionId, entry.duration);
|
|
431
|
+
if (entry.duration > worstDuration) {
|
|
432
|
+
worstDuration = entry.duration;
|
|
433
|
+
cb({
|
|
434
|
+
name: "INP",
|
|
435
|
+
value: Math.round(entry.duration),
|
|
436
|
+
rating: getRating(entry.duration, [200, 500])
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
{ durationThreshold: 40 }
|
|
443
|
+
);
|
|
546
444
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
445
|
+
function observeFPS(cb) {
|
|
446
|
+
if (typeof requestAnimationFrame === "undefined") return;
|
|
447
|
+
let frames = 0;
|
|
448
|
+
const duration = 2e3;
|
|
449
|
+
const start = performance.now();
|
|
450
|
+
const tick = () => {
|
|
451
|
+
frames++;
|
|
452
|
+
if (performance.now() - start < duration) {
|
|
453
|
+
requestAnimationFrame(tick);
|
|
454
|
+
} else {
|
|
455
|
+
cb({ name: "FPS", value: Math.round(frames / duration * 1e3) });
|
|
555
456
|
}
|
|
556
457
|
};
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
const res = await api.post("/identities", { ...data, id: distinctId });
|
|
564
|
-
storage.set("identity", distinctId);
|
|
565
|
-
return res;
|
|
458
|
+
if (document.readyState === "complete") {
|
|
459
|
+
requestAnimationFrame(tick);
|
|
460
|
+
} else {
|
|
461
|
+
window.addEventListener("load", () => requestAnimationFrame(tick), {
|
|
462
|
+
once: true
|
|
463
|
+
});
|
|
566
464
|
}
|
|
567
|
-
return {
|
|
568
|
-
// get,
|
|
569
|
-
set
|
|
570
|
-
};
|
|
571
465
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
466
|
+
function initWebVitals(cb) {
|
|
467
|
+
if (typeof window === "undefined" || typeof PerformanceObserver === "undefined")
|
|
468
|
+
return;
|
|
469
|
+
observeFCP(cb);
|
|
470
|
+
observeLCP(cb);
|
|
471
|
+
observeCLS(cb);
|
|
472
|
+
observeTTFB(cb);
|
|
473
|
+
observeINP(cb);
|
|
474
|
+
observeFPS(cb);
|
|
578
475
|
}
|
|
579
476
|
|
|
580
|
-
// src/
|
|
581
|
-
function
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
477
|
+
// src/plugins/web-vitals/index.ts
|
|
478
|
+
function initWebVitalsPlugin(http) {
|
|
479
|
+
initWebVitals((metric) => {
|
|
480
|
+
http.post("/v1/web-vitals", {
|
|
481
|
+
name: metric.name,
|
|
482
|
+
value: metric.value,
|
|
483
|
+
...metric.rating !== void 0 ? { rating: metric.rating } : {}
|
|
484
|
+
});
|
|
485
|
+
});
|
|
585
486
|
}
|
|
586
487
|
|
|
587
|
-
// src/
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
const api = createApi(apiKey, options);
|
|
594
|
-
return {
|
|
595
|
-
events: initEvents(api),
|
|
596
|
-
identities: initIdentities(api),
|
|
597
|
-
featureFlags: initFeatureFlags(api),
|
|
598
|
-
logs: initLogTracing(api),
|
|
599
|
-
surveys: initSurveys(api),
|
|
600
|
-
experiments: initExperiments(api)
|
|
488
|
+
// src/plugins/index.ts
|
|
489
|
+
function initPlugins(http, plugins) {
|
|
490
|
+
const initializers = {
|
|
491
|
+
analytics: initAnalyticsPlugin(http),
|
|
492
|
+
"web-vitals": initWebVitalsPlugin(http),
|
|
493
|
+
errors: initErrorsPlugin(http)
|
|
601
494
|
};
|
|
602
|
-
|
|
603
|
-
function initClientSdk(apiKey, options) {
|
|
604
|
-
const isBrowser = typeof window !== "undefined";
|
|
605
|
-
const api = createApi(apiKey, options);
|
|
606
|
-
if (isBrowser) {
|
|
607
|
-
const style = document.createElement("style");
|
|
608
|
-
style.innerHTML = reset;
|
|
609
|
-
document.head.appendChild(style);
|
|
610
|
-
if (options.plugins.includes("chats")) {
|
|
611
|
-
initChat(api, options);
|
|
612
|
-
}
|
|
613
|
-
if (options.plugins.includes("analytics")) {
|
|
614
|
-
initAnalytics(api);
|
|
615
|
-
}
|
|
616
|
-
return {};
|
|
617
|
-
}
|
|
618
|
-
return null;
|
|
495
|
+
plugins.map((p) => initializers[p]);
|
|
619
496
|
}
|
|
620
497
|
|
|
621
|
-
// src/
|
|
622
|
-
var
|
|
623
|
-
baseUrl: "https://plugeen.app/api",
|
|
624
|
-
|
|
625
|
-
foregroundColor: "#fff",
|
|
498
|
+
// src/index.ts
|
|
499
|
+
var defaults = {
|
|
500
|
+
baseUrl: "https://dev.plugeen.app/api",
|
|
501
|
+
debug: false,
|
|
626
502
|
plugins: []
|
|
627
503
|
};
|
|
628
|
-
var baseInstance = null;
|
|
629
|
-
var clientInstance = null;
|
|
630
504
|
function createPlugeen(apiKey, options) {
|
|
631
|
-
const
|
|
632
|
-
baseUrl: options
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
plugins: options?.plugins || []
|
|
505
|
+
const resolved = {
|
|
506
|
+
baseUrl: options.baseUrl || defaults.baseUrl,
|
|
507
|
+
debug: options.debug || defaults.debug,
|
|
508
|
+
plugins: options.plugins || defaults.plugins
|
|
636
509
|
};
|
|
637
510
|
if (!apiKey) {
|
|
638
|
-
|
|
639
|
-
}
|
|
640
|
-
if (!baseInstance) {
|
|
641
|
-
baseInstance = initBaseSdk(apiKey, _options);
|
|
511
|
+
throw new TypeError("[plugeen] apiKey is required");
|
|
642
512
|
}
|
|
643
|
-
|
|
644
|
-
|
|
513
|
+
const http = new HttpClient(resolved.baseUrl, apiKey);
|
|
514
|
+
const events = createEventsModule(http);
|
|
515
|
+
const identities = createIdentitiesModule(http);
|
|
516
|
+
const plugeen = {
|
|
517
|
+
track: (event, properties) => {
|
|
518
|
+
void events.create(event, properties);
|
|
519
|
+
},
|
|
520
|
+
identify: (userId, data) => identities.create(userId, data)
|
|
521
|
+
};
|
|
522
|
+
if (resolved.plugins.length > 0) {
|
|
523
|
+
initPlugins(http, resolved.plugins);
|
|
645
524
|
}
|
|
646
|
-
return
|
|
525
|
+
return plugeen;
|
|
647
526
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
createPlugeen
|
|
651
|
-
});
|
|
527
|
+
|
|
528
|
+
exports.createPlugeen = createPlugeen;
|