@levo-so/core 0.1.32 → 0.1.34

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.
@@ -7,6 +7,7 @@ export interface IPageContext {
7
7
  title?: string;
8
8
  }
9
9
  export interface ILevoConfig {
10
+ appName?: string;
10
11
  workspace: WorkspaceID | null;
11
12
  apiUrl: string;
12
13
  insightsUrl: string;
@@ -21,6 +22,7 @@ export interface ILevoConfig {
21
22
  */
22
23
  declare class LevoClient implements ILevoConfig {
23
24
  #private;
25
+ appName?: string | undefined;
24
26
  constructor(props: Partial<ILevoConfig>);
25
27
  get workspace(): `W${string}` | null;
26
28
  get apiUrl(): string;
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import QueryStringAddon from 'wretch/addons/queryString';
6
6
 
7
7
  var workspaceIdRegex = /^W[A-Z0-9]{7}$/;
8
8
  var LevoClient = class {
9
+ appName;
9
10
  #workspace;
10
11
  #apiUrl;
11
12
  #insightsUrl;
@@ -36,6 +37,7 @@ var LevoClient = class {
36
37
  this.#insightsUrl = finalProps.insightsUrl;
37
38
  this.#NODE_ENV = finalProps.NODE_ENV;
38
39
  this.#APP_MODE = finalProps.APP_MODE;
40
+ this.appName = finalProps.appName;
39
41
  }
40
42
  get workspace() {
41
43
  return this.#workspace;
@@ -0,0 +1,16 @@
1
+ export interface BatchOptions {
2
+ logApiUrl?: string;
3
+ }
4
+ export type CallbackFunction = (log: object) => Promise<void>;
5
+ export declare class LogBatch {
6
+ logApiUrl: string;
7
+ logs: Array<object>;
8
+ activeFlush: Promise<void>;
9
+ nextFlush: NodeJS.Timeout;
10
+ lastFlush: Date;
11
+ constructor(options?: BatchOptions);
12
+ sendLogs: (logs: Array<object>) => Promise<void | import("wretch").WretchResponse>;
13
+ ingest: (log: object) => void;
14
+ flush: () => Promise<void>;
15
+ }
16
+ //# sourceMappingURL=batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../src/logger/batch.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9D,qBAAa,QAAQ;IACnB,SAAS,SAAgC;IAEzC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAM;IAEzB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,CAAqB;IAC/C,SAAS,EAAE,MAAM,CAAC,OAAO,CAA2B;IACpD,SAAS,EAAE,IAAI,CAAc;gBAEjB,OAAO,GAAE,YAAiB;IAMtC,QAAQ,SAAgB,KAAK,CAAC,MAAM,CAAC,qDAqCnC;IAEF,MAAM,QAAS,MAAM,UAoBnB;IAEF,KAAK,QAAa,OAAO,CAAC,IAAI,CAAC,CAoB7B;CACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"LevoAudience.d.ts","sourceRoot":"","sources":["../../src/plugins/LevoAudience.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMvD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,qBAAa,YAAa,SAAQ,UAAU;;IAC1C,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC1C,aAAa,EAAE,GAAG,CAAQ;IAoB1B,OAAO,CAAC,YAAY,GAAG,OAAO,EAAE,WAAW,GAAG,OAAO,EACnD,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW;IA8Bb,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU;IAsI7C,QAAQ;IAad,WAAW;;;;;;;;;;;IAmEX,qBAAqB;IAqBrB,iBAAiB,IAAI;QACnB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI;IAcF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU;IAc3C,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,UAAU;IAkC/D,eAAe;IAaf,WAAW;CAYZ"}
1
+ {"version":3,"file":"LevoAudience.d.ts","sourceRoot":"","sources":["../../src/plugins/LevoAudience.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMvD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,qBAAa,YAAa,SAAQ,UAAU;;IAC1C,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAC1C,aAAa,EAAE,GAAG,CAAQ;IAoB1B,OAAO,CAAC,YAAY,GAAG,OAAO,EAAE,WAAW,GAAG,OAAO,EACnD,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW;IA8Bb,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU;IA8J7C,QAAQ;IAed,WAAW;;;;;;;;;;;IAmEX,qBAAqB;IAqBrB,iBAAiB,IAAI;QACnB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI;IAcF,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU;IAc3C,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,UAAU;IAoC/D,eAAe;IAaf,WAAW;CAYZ"}
@@ -171,38 +171,98 @@ var isIncognito = () => new Promise((resolve, reject) => {
171
171
  var isIncognito_default = isIncognito;
172
172
 
173
173
  // src/utils/getUserProperties.ts
174
+ var getGPUInfo = () => {
175
+ const canvas = document.createElement("canvas");
176
+ const gl = canvas?.getContext("webgl") || canvas?.getContext("experimental-webgl");
177
+ if (!gl) {
178
+ return null;
179
+ }
180
+ const debugInfo = gl?.getExtension("WEBGL_debug_renderer_info");
181
+ return debugInfo ? gl?.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : null;
182
+ };
174
183
  var getUserProperties = async () => {
175
184
  let locale = "";
176
185
  let timezone = "";
177
186
  let dark_mode = false;
178
187
  let private_mode = false;
179
- if (window) {
180
- try {
181
- ({ isPrivate: private_mode } = await isIncognito_default());
182
- } catch (e) {
183
- console.error(e);
184
- }
185
- try {
186
- dark_mode = window.matchMedia?.("(prefers-color-scheme: dark)").matches;
187
- } catch (e) {
188
- console.error(e);
189
- }
190
- try {
191
- timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
192
- } catch (e) {
193
- console.error(e);
194
- }
195
- try {
196
- locale = getUserLocale();
197
- } catch (e) {
198
- console.error(e);
188
+ const properties = {};
189
+ if (!window) {
190
+ return {
191
+ locale,
192
+ timezone,
193
+ dark_mode,
194
+ private_mode,
195
+ properties
196
+ };
197
+ }
198
+ try {
199
+ ({ isPrivate: private_mode } = await isIncognito_default());
200
+ } catch (e) {
201
+ console.error(e);
202
+ }
203
+ try {
204
+ dark_mode = window.matchMedia?.("(prefers-color-scheme: dark)").matches;
205
+ } catch (e) {
206
+ console.error(e);
207
+ }
208
+ try {
209
+ timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
210
+ } catch (e) {
211
+ console.error(e);
212
+ }
213
+ try {
214
+ locale = getUserLocale();
215
+ } catch (e) {
216
+ console.error(e);
217
+ }
218
+ if (navigator && "connection" in navigator) {
219
+ const connection = navigator.connection || navigator?.mozConnection || navigator.webkitConnection;
220
+ properties.network_type = connection.effectiveType;
221
+ }
222
+ properties.width = window?.innerWidth;
223
+ properties.height = window?.innerHeight;
224
+ properties.pixel_ratio = window?.devicePixelRatio;
225
+ if (screen) {
226
+ properties.screen_width = screen?.width;
227
+ properties.screen_height = screen?.height;
228
+ properties.color_depth = screen?.colorDepth;
229
+ properties.orientation = screen?.orientation?.type;
230
+ }
231
+ if (navigator && "getBattery" in navigator) {
232
+ const battery = await navigator?.getBattery();
233
+ if (battery) {
234
+ properties.battery_level = Number((battery?.level * 100).toFixed(0));
235
+ properties.battery_charging = battery?.charging;
236
+ properties.battery_discharging_time = battery?.dischargingTime;
237
+ properties.battery_full_charge_capacity = battery?.fullChargeCapacity;
238
+ properties.battery_charging_time = battery?.chargingTime;
199
239
  }
200
240
  }
241
+ if (navigator && "deviceMemory" in navigator) {
242
+ properties.device_memory = navigator?.deviceMemory;
243
+ }
244
+ const supportsTouch = "ontouchstart" in window || typeof navigator?.maxTouchPoints !== "undefined" && navigator?.maxTouchPoints > 0;
245
+ properties.touch_supported = supportsTouch;
246
+ if ("hardwareConcurrency" in navigator) {
247
+ properties.hardware_concurrency = navigator?.hardwareConcurrency;
248
+ }
249
+ if (navigator && "mediaDevices" in navigator) {
250
+ const mediaDevices = navigator?.mediaDevices;
251
+ const devices = await mediaDevices?.enumerateDevices();
252
+ const hasCamera = devices.some((device) => device?.kind === "videoinput");
253
+ properties.camera_supported = hasCamera;
254
+ const hasMicrophone = devices.some(
255
+ (device) => device?.kind === "audioinput"
256
+ );
257
+ properties.microphone_supported = hasMicrophone;
258
+ }
259
+ properties.gpu = getGPUInfo();
201
260
  return {
202
261
  locale,
203
262
  timezone,
204
263
  dark_mode,
205
- private_mode
264
+ private_mode,
265
+ properties
206
266
  };
207
267
  };
208
268
 
@@ -283,10 +343,12 @@ var LevoAudience = class extends LevoPlugin {
283
343
  session_id: this.#session,
284
344
  device_id: this.#device,
285
345
  event: payload.event,
346
+ version: payload.version || 1,
286
347
  workspace_id: this.client.workspace,
287
348
  properties: {
288
349
  ...properties,
289
350
  ...payloadProperties,
351
+ version: void 0,
290
352
  resource: void 0,
291
353
  identifier: void 0,
292
354
  hostname: void 0,
@@ -305,10 +367,17 @@ var LevoAudience = class extends LevoPlugin {
305
367
  tab_id: this.getCurrentTabId(),
306
368
  tab_count: this.getTabCount()
307
369
  };
308
- const isQueued = navigator.sendBeacon(
309
- `${this?.client?.insightsUrl}/v1/insights/event/collect`,
310
- JSON.stringify(collectInput)
311
- );
370
+ let isQueued = false;
371
+ try {
372
+ isQueued = navigator.sendBeacon(
373
+ `${this?.client?.insightsUrl}/v1/insights/event/collect`,
374
+ JSON.stringify(collectInput)
375
+ );
376
+ } catch (e) {
377
+ }
378
+ if (!isQueued) {
379
+ this.request("/v1/insights/event/collect", collectInput);
380
+ }
312
381
  this.#events.push({
313
382
  input: payload,
314
383
  payload: collectInput,
@@ -338,6 +407,7 @@ var LevoAudience = class extends LevoPlugin {
338
407
  timezone: payload.traits.timezone,
339
408
  locale: payload.traits.locale,
340
409
  referrer: payload.traits.referrer,
410
+ properties: payload.traits.properties,
341
411
  workspace_id: this.client.workspace,
342
412
  hostname: window.location.hostname,
343
413
  pathname: window.location.pathname,
@@ -356,10 +426,18 @@ var LevoAudience = class extends LevoPlugin {
356
426
  this.#is_identified = true;
357
427
  this.#session = data.content.data.session;
358
428
  this.#device = data.content.data.device;
359
- navigator.sendBeacon(
360
- `${this?.client?.insightsUrl}/v1/insights/event/bulk?workspace=${this?.client?.workspace}`,
361
- JSON.stringify(this.#batch)
362
- );
429
+ let isQueued = false;
430
+ try {
431
+ isQueued = navigator.sendBeacon(
432
+ `${this?.client?.insightsUrl}/v1/insights/event/bulk?workspace=${this?.client?.workspace}`,
433
+ JSON.stringify(this.#batch)
434
+ );
435
+ } catch (e) {
436
+ }
437
+ if (!isQueued) {
438
+ this.request("/v1/insights/event/bulk", this.#batch);
439
+ }
440
+ this.#batch = [];
363
441
  identifyLock.releaseLock();
364
442
  }).catch((e) => {
365
443
  identifyLock.releaseLock();
@@ -384,8 +462,9 @@ var LevoAudience = class extends LevoPlugin {
384
462
  return;
385
463
  }
386
464
  const referrer = this.getReferrer();
465
+ const traits = await getUserProperties();
387
466
  await this.instance.identify("", {
388
- ...await getUserProperties(),
467
+ ...traits,
389
468
  referrer
390
469
  });
391
470
  }
@@ -459,8 +538,10 @@ var LevoAudience = class extends LevoPlugin {
459
538
  }
460
539
  return this.#batch.push({
461
540
  event,
541
+ version: properties?.version || 1,
462
542
  properties: {
463
543
  ...properties,
544
+ version: void 0,
464
545
  resource: void 0,
465
546
  identifier: void 0,
466
547
  hostname: void 0,
@@ -1,12 +1,32 @@
1
- import logger from "loglevel";
2
1
  import type LevoClient from "../LevoClient";
2
+ import { BatchOptions, LogBatch } from "../logger/batch";
3
3
  import { LevoPlugin } from "./LevoPlugin";
4
+ export declare const isBrowser: boolean;
5
+ export declare enum LogLevel {
6
+ debug = 0,
7
+ info = 1,
8
+ warn = 2,
9
+ error = 3,
10
+ off = 100
11
+ }
12
+ export interface LoggerOptions extends BatchOptions {
13
+ level?: LogLevel;
14
+ enableRemote?: boolean;
15
+ }
4
16
  export declare class LevoLogger extends LevoPlugin {
5
- logger: logger.RootLogger;
6
- constructor(props: LevoClient);
7
- error(...msg: any[]): void;
8
- log(...msg: any[]): void;
9
- info(...msg: any[]): void;
10
- warn(...msg: any[]): void;
17
+ logLevel: LogLevel;
18
+ enableRemote: boolean;
19
+ batch: LogBatch;
20
+ context: Record<string, any>;
21
+ constructor(client: LevoClient, batchOptions?: LoggerOptions, context?: Record<string, any>);
22
+ debug: (...args: any[]) => void;
23
+ info: (...args: any[]) => void;
24
+ warn: (...args: any[]) => void;
25
+ error: (...args: any[]) => void;
26
+ format(messages: any[]): {
27
+ message: string;
28
+ content?: Array<object> | object | string;
29
+ };
30
+ log: (level: LogLevel, args: any[]) => void;
11
31
  }
12
32
  //# sourceMappingURL=LevoLogger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LevoLogger.d.ts","sourceRoot":"","sources":["../../src/plugins/LevoLogger.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,UAAU,CAAC;AAG9B,OAAO,KAAK,UAAU,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,qBAAa,UAAW,SAAQ,UAAU;IACxC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAU;gBAEvB,KAAK,EAAE,UAAU;IAyB7B,KAAK,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE;IAInB,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE;IAIjB,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE;IAIlB,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE;CAGnB"}
1
+ {"version":3,"file":"LevoLogger.d.ts","sourceRoot":"","sources":["../../src/plugins/LevoLogger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,eAAO,MAAM,SAAS,SAAgC,CAAC;AAEvD,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;IACT,GAAG,MAAM;CACV;AAiBD,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AACD,qBAAa,UAAW,SAAQ,UAAU;IACxC,QAAQ,EAAE,QAAQ,CAAkB;IACpC,YAAY,EAAE,OAAO,CAAS;IAE9B,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAG3B,MAAM,EAAE,UAAU,EAClB,YAAY,GAAE,aAAkB,EAChC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAcnC,KAAK,YAAa,GAAG,EAAE,UAErB;IAEF,IAAI,YAAa,GAAG,EAAE,UAEpB;IAEF,IAAI,YAAa,GAAG,EAAE,UAEpB;IAEF,KAAK,YAAa,GAAG,EAAE,UAErB;IAEF,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;KAC3C;IAsDD,GAAG,UAAW,QAAQ,QAAQ,GAAG,EAAE,UAsCjC;CACH"}
@@ -1,35 +1,193 @@
1
1
  import { LevoPlugin } from '../chunk-QJSKNLTV.js';
2
- import logger from 'loglevel';
3
2
  import wretch from 'wretch';
4
3
 
5
- var LevoLogger = class extends LevoPlugin {
6
- logger = logger;
7
- constructor(props) {
8
- super(props);
9
- logger.setLevel(
10
- this.client.NODE_ENV === "production" ? logger.levels.INFO : logger.levels.DEBUG
11
- );
12
- logger.methodFactory = (methodName) => (message, attributes = {}) => {
13
- wretch().url(`${this.client.apiUrl}/v1/apm/logs/json`).post({
14
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
15
- level: methodName,
16
- message,
17
- ...attributes
18
- }).res().catch((e) => console.error(e));
19
- };
20
- }
21
- error(...msg) {
22
- return this.logger.error(...msg);
4
+ var LogBatch = class {
5
+ logApiUrl = "https://public-api.levo.so";
6
+ logs = [];
7
+ activeFlush = Promise.resolve();
8
+ nextFlush = setTimeout(() => {
9
+ }, 0);
10
+ lastFlush = /* @__PURE__ */ new Date();
11
+ constructor(options = {}) {
12
+ if (options?.logApiUrl) {
13
+ this.logApiUrl = options?.logApiUrl;
14
+ }
23
15
  }
24
- log(...msg) {
25
- return this.logger.debug(...msg);
16
+ sendLogs = async (logs) => {
17
+ const url = `${this.logApiUrl}/v1/apm/logs/json`;
18
+ const sendFallback = () => {
19
+ return wretch().url(url).post(logs).res().catch((e) => console.error(e));
20
+ };
21
+ try {
22
+ if (typeof fetch === "undefined") {
23
+ throw new Error("fetch is not defined");
24
+ } else if (typeof window !== "undefined" && navigator.sendBeacon) {
25
+ try {
26
+ if (!navigator.sendBeacon.bind(navigator)(url, JSON.stringify(logs))) {
27
+ return sendFallback();
28
+ }
29
+ } catch {
30
+ return sendFallback();
31
+ }
32
+ } else {
33
+ return sendFallback();
34
+ }
35
+ } catch (e) {
36
+ console.warn(`Failed to send logs to server: ${e}`);
37
+ this.logs = [...this.logs, ...logs];
38
+ }
39
+ };
40
+ ingest = (log) => {
41
+ if (!this.logApiUrl) return;
42
+ const task = Array.isArray(log) ? log : [log];
43
+ this.logs.push(task);
44
+ if (this.logs.length >= 50 || this.lastFlush.getTime() < Date.now() - 1500) {
45
+ clearTimeout(this.nextFlush);
46
+ this.activeFlush = this.flush();
47
+ } else {
48
+ clearTimeout(this.nextFlush);
49
+ this.nextFlush = setTimeout(() => {
50
+ this.activeFlush = this.flush();
51
+ }, 1500);
52
+ }
53
+ };
54
+ flush = async () => {
55
+ const tasks = this.logs.splice(0, this.logs.length);
56
+ clearTimeout(this.nextFlush);
57
+ await this.activeFlush;
58
+ if (tasks.length === 0) {
59
+ this.lastFlush = /* @__PURE__ */ new Date();
60
+ return;
61
+ }
62
+ try {
63
+ await this.sendLogs(tasks);
64
+ } catch (e) {
65
+ console.log("error sending logs", e);
66
+ } finally {
67
+ this.lastFlush = /* @__PURE__ */ new Date();
68
+ }
69
+ };
70
+ };
71
+
72
+ // src/plugins/LevoLogger.ts
73
+ var isBrowser = typeof window !== "undefined";
74
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
75
+ LogLevel2[LogLevel2["debug"] = 0] = "debug";
76
+ LogLevel2[LogLevel2["info"] = 1] = "info";
77
+ LogLevel2[LogLevel2["warn"] = 2] = "warn";
78
+ LogLevel2[LogLevel2["error"] = 3] = "error";
79
+ LogLevel2[LogLevel2["off"] = 100] = "off";
80
+ return LogLevel2;
81
+ })(LogLevel || {});
82
+ var getMethodName = (level) => {
83
+ switch (level) {
84
+ case 0 /* debug */:
85
+ return "log";
86
+ case 1 /* info */:
87
+ return "info";
88
+ case 2 /* warn */:
89
+ return "warn";
90
+ case 3 /* error */:
91
+ return "error";
92
+ default:
93
+ return "log";
26
94
  }
27
- info(...msg) {
28
- return this.logger.info(...msg);
95
+ };
96
+ var LevoLogger = class extends LevoPlugin {
97
+ logLevel = 0 /* debug */;
98
+ enableRemote = false;
99
+ batch;
100
+ context;
101
+ constructor(client, batchOptions = {}, context = {}) {
102
+ super(client);
103
+ this.batch = new LogBatch(batchOptions);
104
+ this.context = context;
105
+ this.logLevel = batchOptions?.level ?? (this.client.NODE_ENV !== "development" ? 1 /* info */ : 0 /* debug */);
106
+ this.enableRemote = batchOptions?.enableRemote ?? this.client.NODE_ENV !== "development";
29
107
  }
30
- warn(...msg) {
31
- return this.logger.warn(...msg);
108
+ debug = (...args) => {
109
+ this.log(0 /* debug */, args);
110
+ };
111
+ info = (...args) => {
112
+ this.log(1 /* info */, args);
113
+ };
114
+ warn = (...args) => {
115
+ this.log(2 /* warn */, args);
116
+ };
117
+ error = (...args) => {
118
+ this.log(3 /* error */, args);
119
+ };
120
+ format(messages) {
121
+ let message = "";
122
+ const formattedMessages = messages.map((arg) => {
123
+ let payload = "";
124
+ const isMessageEmpty = !message;
125
+ if (typeof arg === "string") {
126
+ payload = arg;
127
+ if (isMessageEmpty) {
128
+ message = arg;
129
+ }
130
+ } else if (arg instanceof Error) {
131
+ payload = {
132
+ message: arg.message,
133
+ name: arg.name,
134
+ stack: arg.stack
135
+ };
136
+ if (isMessageEmpty) {
137
+ message = arg.message;
138
+ }
139
+ } else if (typeof arg === "object") {
140
+ payload = arg;
141
+ } else {
142
+ payload = String(arg);
143
+ if (isMessageEmpty) {
144
+ message = String(arg);
145
+ }
146
+ }
147
+ return payload;
148
+ }).filter(Boolean);
149
+ if (!message && formattedMessages.length > 0) {
150
+ message = "Default message (Check content for details)";
151
+ }
152
+ if (formattedMessages?.length === 1 && formattedMessages[0] === message) {
153
+ return { message, content: {} };
154
+ }
155
+ return {
156
+ message,
157
+ content: formattedMessages
158
+ };
32
159
  }
160
+ log = (level, args) => {
161
+ const messages = Array.isArray(args) ? args : [args];
162
+ if (level < this.logLevel) {
163
+ return;
164
+ }
165
+ if (this.enableRemote && level === 3 /* error */) {
166
+ const { content = {}, message } = this.format(messages);
167
+ if (message) {
168
+ const log = {
169
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
170
+ level: "error",
171
+ workspace: this.client.workspace,
172
+ appName: this.client.appName,
173
+ isBrowser,
174
+ ...this.context,
175
+ message,
176
+ content
177
+ };
178
+ if (isBrowser) {
179
+ log.hostname = window.location.hostname;
180
+ log.pathname = window.location.pathname;
181
+ log.url = window.location.href;
182
+ log.page_title = window.document.title;
183
+ log.userAgent = window.navigator.userAgent;
184
+ }
185
+ this.batch.ingest(log);
186
+ }
187
+ }
188
+ const method = getMethodName(level);
189
+ console[method](...messages);
190
+ };
33
191
  };
34
192
 
35
- export { LevoLogger };
193
+ export { LevoLogger, LogLevel, isBrowser };
@@ -9,6 +9,7 @@ export declare namespace ILevoAudience {
9
9
  referrer: Record<string, string>;
10
10
  data: Record<string, string>;
11
11
  };
12
+ properties: Record<string, any>;
12
13
  }
13
14
  type BaseProperties = Traits & {
14
15
  resource: string;
@@ -51,6 +52,7 @@ export declare namespace ILevoAudience {
51
52
  session_id?: string;
52
53
  device_id?: string;
53
54
  event: string;
55
+ version?: number;
54
56
  properties: Properties;
55
57
  resource: string;
56
58
  identifier: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"audience.d.ts","sourceRoot":"","sources":["../../src/types/audience.ts"],"names":[],"mappings":"AACA,yBAAiB,aAAa,CAAC;IAC7B,UAAiB,MAAM;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9B,CAAC;KACH;IAED,KAAY,cAAc,GAAG,MAAM,GAAG;QACpC,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,UAAiB,eAAe;QAC9B,EAAE,EAAE,MAAM,CAAC;KACZ;IAED,UAAiB,kBAAkB;QACjC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;IAED,UAAiB,gBAAgB;QAC/B,OAAO,EAAE,MAAM,CAAC;KACjB;IAED,KAAY,UAAU,GAAG,OAAO,CAC9B,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,gBAAgB,CACzE,GACC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,WAAW,GAAG,QAAQ,CAAC,CAAC,GACjE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEtB,KAAY,eAAe,GAAG;QAC5B,UAAU,EAAE,UAAU,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;QACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IAEF,KAAY,SAAS,GAAG;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,KAAY,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;IAE9C,KAAY,eAAe,GAAG;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,KAAY,YAAY,GAAG,SAAS,GAAG;QACrC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,CAAC;IAEF,KAAY,cAAc,GAAG;QAC3B,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH"}
1
+ {"version":3,"file":"audience.d.ts","sourceRoot":"","sources":["../../src/types/audience.ts"],"names":[],"mappings":"AACA,yBAAiB,aAAa,CAAC;IAC7B,UAAiB,MAAM;QACrB,YAAY,EAAE,OAAO,CAAC;QACtB,SAAS,EAAE,OAAO,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC9B,CAAC;QACF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACjC;IAED,KAAY,cAAc,GAAG,MAAM,GAAG;QACpC,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,UAAiB,eAAe;QAC9B,EAAE,EAAE,MAAM,CAAC;KACZ;IAED,UAAiB,kBAAkB;QACjC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;IAED,UAAiB,gBAAgB;QAC/B,OAAO,EAAE,MAAM,CAAC;KACjB;IAED,KAAY,UAAU,GAAG,OAAO,CAC9B,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,gBAAgB,CACzE,GACC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,GAAG,WAAW,GAAG,QAAQ,CAAC,CAAC,GACjE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEtB,KAAY,eAAe,GAAG;QAC5B,UAAU,EAAE,UAAU,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;QACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;KACvB,CAAC;IAEF,KAAY,SAAS,GAAG;QACtB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,KAAY,YAAY,GAAG,MAAM,GAAG,SAAS,CAAC;IAE9C,KAAY,eAAe,GAAG;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,KAAY,YAAY,GAAG,SAAS,GAAG;QACrC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,UAAU,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;KAChC,CAAC;IAEF,KAAY,cAAc,GAAG;QAC3B,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH"}
@@ -3,5 +3,6 @@ export declare const getUserProperties: () => Promise<{
3
3
  timezone: string;
4
4
  dark_mode: boolean;
5
5
  private_mode: boolean;
6
+ properties: Record<string, any>;
6
7
  }>;
7
8
  //# sourceMappingURL=getUserProperties.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getUserProperties.d.ts","sourceRoot":"","sources":["../../src/utils/getUserProperties.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB;;;;;EAoC7B,CAAC"}
1
+ {"version":3,"file":"getUserProperties.d.ts","sourceRoot":"","sources":["../../src/utils/getUserProperties.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,iBAAiB;;;;;;EAgH7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levo-so/core",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "author": "Levo Engineering <devs@theinternetfolks.com>",
5
5
  "description": "Levo common utilities",
6
6
  "type": "module",
@@ -14,12 +14,11 @@
14
14
  "package.json"
15
15
  ],
16
16
  "dependencies": {
17
- "wretch": "2.9.0",
18
17
  "@analytics/activity-utils": "0.1.16",
19
18
  "@analytics/visitor-source": "0.0.7",
20
- "loglevel": "1.9.1",
21
19
  "analytics": "0.8.14",
22
- "get-user-locale": "2.3.2"
20
+ "get-user-locale": "2.3.2",
21
+ "wretch": "2.9.0"
23
22
  },
24
23
  "devDependencies": {
25
24
  "tsup": "8.2.4",
@@ -58,6 +57,9 @@
58
57
  "./membership-plugin": {
59
58
  "types": "./dist/plugins/LevoMembership.d.ts",
60
59
  "default": "./dist/plugins/LevoMembership.js"
60
+ },
61
+ "./pino-transport": {
62
+ "default": "./dist/pino/transport.js"
61
63
  }
62
64
  },
63
65
  "scripts": {