@levo-so/core 0.1.30 → 0.1.33

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"}
@@ -4,6 +4,7 @@ import { LevoPlugin } from "./LevoPlugin";
4
4
  export declare class LevoAudience extends LevoPlugin {
5
5
  #private;
6
6
  instance: AnalyticsInstance | null;
7
+ idle_listener: any;
7
8
  request<ResponseBody = unknown, RequestBody = unknown>(url: string, data: RequestBody): Promise<Awaited<ResponseBody>>;
8
9
  initiate(properties: ILevoAudience.Properties): Promise<any>;
9
10
  identify(): Promise<void>;
@@ -18,7 +19,12 @@ export declare class LevoAudience extends LevoPlugin {
18
19
  data: Record<string, string>;
19
20
  raw: string;
20
21
  };
21
- startActivityListener(): any;
22
+ startActivityListener(): null;
23
+ getActivityStatus(): {
24
+ status: "idle" | "active";
25
+ seconds: number;
26
+ } | null;
27
+ bounce(properties: ILevoAudience.Properties): Promise<void>;
22
28
  track(event: string, properties: ILevoAudience.Properties): Promise<any>;
23
29
  getCurrentTabId(): string;
24
30
  getTabCount(): number;
@@ -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;IAmB1C,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;IAqBf,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;IAuI7C,QAAQ;IAiBd,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"}
@@ -171,38 +171,102 @@ 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
+ if (supportsTouch) {
246
+ properties.touch_support = true;
247
+ } else {
248
+ properties.touch_support = false;
249
+ }
250
+ if ("hardwareConcurrency" in navigator) {
251
+ properties.hardware_concurrency = navigator.hardwareConcurrency;
252
+ }
253
+ if (navigator && "mediaDevices" in navigator) {
254
+ const mediaDevices = navigator.mediaDevices;
255
+ const devices = await mediaDevices.enumerateDevices();
256
+ const hasCamera = devices.some((device) => device.kind === "videoinput");
257
+ properties.camera_supported = hasCamera;
258
+ const hasMicrophone = devices.some(
259
+ (device) => device.kind === "audioinput"
260
+ );
261
+ properties.microphone_supported = hasMicrophone;
262
+ }
263
+ properties.gpu = getGPUInfo();
201
264
  return {
202
265
  locale,
203
266
  timezone,
204
267
  dark_mode,
205
- private_mode
268
+ private_mode,
269
+ properties
206
270
  };
207
271
  };
208
272
 
@@ -238,6 +302,7 @@ var LocalStorageLock = class {
238
302
  // src/plugins/LevoAudience.ts
239
303
  var LevoAudience = class extends LevoPlugin {
240
304
  instance = null;
305
+ idle_listener = null;
241
306
  #IDLE_THROTTLE = 1 * 1e3;
242
307
  // every 1 second we check for idleness
243
308
  #IDLE_TIMEOUT = 60 * 1e3;
@@ -337,6 +402,7 @@ var LevoAudience = class extends LevoPlugin {
337
402
  timezone: payload.traits.timezone,
338
403
  locale: payload.traits.locale,
339
404
  referrer: payload.traits.referrer,
405
+ properties: payload.traits.properties,
340
406
  workspace_id: this.client.workspace,
341
407
  hostname: window.location.hostname,
342
408
  pathname: window.location.pathname,
@@ -383,8 +449,10 @@ var LevoAudience = class extends LevoPlugin {
383
449
  return;
384
450
  }
385
451
  const referrer = this.getReferrer();
452
+ const traits = await getUserProperties();
453
+ console.log(traits);
386
454
  await this.instance.identify("", {
387
- ...await getUserProperties(),
455
+ ...traits,
388
456
  referrer
389
457
  });
390
458
  }
@@ -410,8 +478,8 @@ var LevoAudience = class extends LevoPlugin {
410
478
  return { type, referrer, data, raw: document.referrer };
411
479
  }
412
480
  startActivityListener() {
413
- if (typeof document !== "undefined") {
414
- return onUserActivity({
481
+ if (typeof document !== "undefined" && !this.idle_listener) {
482
+ this.idle_listener = onUserActivity({
415
483
  timeout: this.#IDLE_TIMEOUT,
416
484
  throttle: this.#IDLE_THROTTLE,
417
485
  onIdle: (activeForSeconds) => {
@@ -428,6 +496,27 @@ var LevoAudience = class extends LevoPlugin {
428
496
  }
429
497
  return null;
430
498
  }
499
+ getActivityStatus() {
500
+ const status = this?.idle_listener?.getStatus();
501
+ if (!status) {
502
+ return null;
503
+ }
504
+ return {
505
+ status: status.isIdle ? "idle" : "active",
506
+ seconds: status.isIdle ? status.idle : status.active
507
+ };
508
+ }
509
+ async bounce(properties) {
510
+ const activity_status = this.getActivityStatus();
511
+ if (activity_status) {
512
+ if (activity_status?.status === "idle") {
513
+ properties.seconds_idle = activity_status.seconds;
514
+ } else {
515
+ properties.seconds_active = activity_status.seconds;
516
+ }
517
+ }
518
+ this.track("page.bounce", properties);
519
+ }
431
520
  async track(event, properties) {
432
521
  if (!this.client.workspace) {
433
522
  return;
@@ -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 === "production" ? 1 /* info */ : 0 /* debug */);
106
+ this.enableRemote = batchOptions?.enableRemote ?? this.client.NODE_ENV === "production";
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;
@@ -55,5 +56,11 @@ export declare namespace ILevoAudience {
55
56
  resource: string;
56
57
  identifier: string | undefined;
57
58
  };
59
+ type ActivityStatus = {
60
+ isIdle: boolean;
61
+ isDisabled: boolean;
62
+ active: number;
63
+ idle: number;
64
+ };
58
65
  }
59
66
  //# sourceMappingURL=audience.d.ts.map
@@ -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;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,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;;;;;;EAoH7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levo-so/core",
3
- "version": "0.1.30",
3
+ "version": "0.1.33",
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": {