@workleap/logrocket 1.2.4 → 1.2.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @workleap/logrocket
2
2
 
3
+ ## 1.2.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [#79](https://github.com/workleap/wl-telemetry/pull/79) [`7ad31c6`](https://github.com/workleap/wl-telemetry/commit/7ad31c6c317c4aad758e29862b6d06f9465b4da3) Thanks [@patricklafrance](https://github.com/patricklafrance)! - Updated LogRocketLogger group logs by indenting the logs under the label rather than prefixing every log with the label.
8
+
9
+ ## 1.2.5
10
+
11
+ ### Patch Changes
12
+
13
+ - [#68](https://github.com/workleap/wl-telemetry/pull/68) [`80c1f39`](https://github.com/workleap/wl-telemetry/commit/80c1f39747ac689d6e175ff6b880a2b8c8fa9abd) Thanks [@patricklafrance](https://github.com/patricklafrance)! - LogRocketLogger refactor.
14
+
15
+ - Updated dependencies [[`80c1f39`](https://github.com/workleap/wl-telemetry/commit/80c1f39747ac689d6e175ff6b880a2b8c8fa9abd)]:
16
+ - @workleap/telemetry@1.1.6
17
+
3
18
  ## 1.2.4
4
19
 
5
20
  ### Patch Changes
@@ -1,4 +1,4 @@
1
- import { type Logger, type LoggerOptions, type LoggerScope, type LoggerScopeEndOptions, LogLevel } from "@workleap/logging";
1
+ import { type Logger, type LoggerOptions, type LoggerScope, type LoggerScopeEndOptions, LogLevel, type LogOptions } from "@workleap/logging";
2
2
  /**
3
3
  * An scope implementation for the LogRocket logger.
4
4
  * @see {@link https://workleap.github.io/wl-telemetry}
@@ -12,7 +12,7 @@ export declare class LogRocketLoggerScope implements LoggerScope {
12
12
  /**
13
13
  * @see {@link https://workleap.github.io/wl-logging}
14
14
  */
15
- withText(text?: string): this;
15
+ withText(text?: string, options?: Omit<LogOptions, "style">): this;
16
16
  /**
17
17
  * @see {@link https://workleap.github.io/wl-logging}
18
18
  */
@@ -72,7 +72,7 @@ export declare class LogRocketLogger implements Logger {
72
72
  /**
73
73
  * @see {@link https://workleap.github.io/wl-logging}
74
74
  */
75
- withText(text?: string): this;
75
+ withText(text?: string, options?: Omit<LogOptions, "style">): this;
76
76
  /**
77
77
  * @see {@link https://workleap.github.io/wl-logging}
78
78
  */
@@ -8,6 +8,43 @@ import logrocket from "logrocket";
8
8
  ;// CONCATENATED MODULE: ./src/LogRocketLogger.ts
9
9
 
10
10
 
11
+ function appendText(currentText, newText, options = {}) {
12
+ const { leadingSpace = true } = options;
13
+ if (currentText.length > 0) {
14
+ return `${currentText}${leadingSpace ? " " : ""}${newText}`;
15
+ }
16
+ return newText;
17
+ }
18
+ /**
19
+ * Formats an array of Segment objects into a list of log arguments.
20
+ *
21
+ * - Consecutive "text" segments are concatenated into a single string, separated by spaces (unless `leadingSpace` is false).
22
+ * - Non-"text" segments ("object", "error", "line-change") are added directly to the output array.
23
+ * - When a non-"text" segment is encountered, any buffered text is flushed to the output before adding the segment.
24
+ * - At the end, any remaining buffered text is flushed.
25
+ */ function formatSegments(segments) {
26
+ const logs = [];
27
+ let textBuffer = "";
28
+ const flushText = ()=>{
29
+ if (textBuffer.length > 0) {
30
+ logs.push(textBuffer);
31
+ textBuffer = "";
32
+ }
33
+ };
34
+ segments.forEach((x)=>{
35
+ if (x.type === "text") {
36
+ textBuffer = appendText(textBuffer, x.value, {
37
+ leadingSpace: x.options?.leadingSpace
38
+ });
39
+ } else {
40
+ flushText();
41
+ logs.push(x.value);
42
+ }
43
+ });
44
+ // If the last segment is text, the text buffer hasn't been flushed.
45
+ flushText();
46
+ return logs;
47
+ }
11
48
  /**
12
49
  * An scope implementation for the LogRocket logger.
13
50
  * @see {@link https://workleap.github.io/wl-telemetry}
@@ -32,9 +69,11 @@ import logrocket from "logrocket";
32
69
  // Required closure to preserved the current log items for when they will be formatted when the scope is ended.
33
70
  const segments = this.#segments;
34
71
  this.#pendingLogs.push(()=>{
35
- const values = segments.map((x)=>x.value);
36
- values.unshift(`(${this.#label})`);
37
- fct(...values);
72
+ const formattedSegments = formatSegments(segments);
73
+ // Since LogRocket session replay UI doesn't have a concept similar to console.group,
74
+ // the logs of a group are indented by 4 spaces under the group label.
75
+ formattedSegments.unshift(" ");
76
+ fct(...formattedSegments);
38
77
  });
39
78
  }
40
79
  this.#resetSegments();
@@ -42,11 +81,12 @@ import logrocket from "logrocket";
42
81
  }
43
82
  /**
44
83
  * @see {@link https://workleap.github.io/wl-logging}
45
- */ withText(text) {
84
+ */ withText(text, options) {
46
85
  if (text) {
47
86
  this.#segments.push({
48
87
  type: "text",
49
- value: text
88
+ value: text,
89
+ options
50
90
  });
51
91
  }
52
92
  return this;
@@ -150,6 +190,7 @@ import logrocket from "logrocket";
150
190
  this.#hasEnded = true;
151
191
  if (!dismiss) {
152
192
  if (this.#pendingLogs.length > 0) {
193
+ logrocket.log(this.#label);
153
194
  this.#pendingLogs.forEach((x)=>{
154
195
  x();
155
196
  });
@@ -177,8 +218,8 @@ import logrocket from "logrocket";
177
218
  #log(fct, threshold) {
178
219
  if (this.#segments.length > 0) {
179
220
  if (this.#logLevel <= threshold) {
180
- const values = this.#segments.map((x)=>x.value);
181
- fct(...values);
221
+ const formattedSegments = formatSegments(this.#segments);
222
+ fct(...formattedSegments);
182
223
  }
183
224
  this.#resetSegments();
184
225
  }
@@ -190,11 +231,12 @@ import logrocket from "logrocket";
190
231
  }
191
232
  /**
192
233
  * @see {@link https://workleap.github.io/wl-logging}
193
- */ withText(text) {
234
+ */ withText(text, options) {
194
235
  if (text) {
195
236
  this.#segments.push({
196
237
  type: "text",
197
- value: text
238
+ value: text,
239
+ options
198
240
  });
199
241
  }
200
242
  return this;
@@ -1 +1 @@
1
- {"version":3,"file":"LogRocketLogger.js","sources":["webpack://@workleap/logrocket/./src/LogRocketLogger.ts"],"sourcesContent":["import { type Logger, type LoggerOptions, type LoggerScope, type LoggerScopeEndOptions, LogLevel } from \"@workleap/logging\";\nimport LogRocket from \"logrocket\";\n\ninterface Segment {\n type: \"text\" | \"object\" | \"error\" | \"line-change\";\n value: unknown;\n}\n\ntype LogFunction = (...rest: unknown[]) => void;\ntype PendingLog = () => void;\n\n/**\n * An scope implementation for the LogRocket logger.\n * @see {@link https://workleap.github.io/wl-telemetry}\n */\nexport class LogRocketLoggerScope implements LoggerScope {\n readonly #logLevel: LogLevel;\n readonly #label: string;\n\n #segments: Segment[] = [];\n #pendingLogs: PendingLog[] = [];\n #hasEnded: boolean = false;\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n constructor(label: string, logLevel: LogLevel) {\n this.#logLevel = logLevel;\n this.#label = label;\n }\n\n #resetSegments() {\n this.#segments = [];\n }\n\n #log(fct: LogFunction, threshold: LogLevel) {\n if (this.#segments.length > 0) {\n if (this.#logLevel <= threshold) {\n // Required closure to preserved the current log items for when they will be formatted when the scope is ended.\n const segments = this.#segments;\n\n this.#pendingLogs.push(() => {\n const values = segments.map(x => x.value);\n values.unshift(`(${this.#label})`);\n\n fct(...values);\n });\n }\n\n this.#resetSegments();\n }\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withText(text?: string) {\n if (text) {\n this.#segments.push({\n type: \"text\",\n value: text\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withError(error?: Error) {\n if (error) {\n this.#segments.push({\n type: \"error\",\n value: error\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withObject(obj?: unknown) {\n if (obj) {\n this.#segments.push({\n type: \"object\",\n value: obj\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withLineChange() {\n this.#segments.push({\n type: \"line-change\",\n value: \"\\r\\n\"\n });\n\n return this;\n }\n\n /**\n * Write a debug log. The log will be processed only if the logger LogLevel is >= debug.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n debug(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.debug);\n }\n\n /**\n * Write an information log. The log will be processed only if the logger LogLevel is >= information.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n information(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.information);\n }\n\n /**\n * Write a warning log. The log will be processed only if the logger LogLevel is >= warning.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n warning(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.warn, LogLevel.warning);\n }\n\n /**\n * Write an error log. The log will be processed only if the logger LogLevel is >= error.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n error(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.error);\n }\n\n /**\n * Write a critical log. The log will be processed only if the logger LogLevel is >= critical.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n critical(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.critical);\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n end(options: LoggerScopeEndOptions = {}) {\n const {\n dismiss = false\n } = options;\n\n if (!this.#hasEnded) {\n this.#hasEnded = true;\n\n if (!dismiss) {\n if (this.#pendingLogs.length > 0) {\n this.#pendingLogs.forEach(x => {\n x();\n });\n\n this.#pendingLogs = [];\n }\n }\n }\n }\n}\n\n/**\n * A logger implementation for LogRocket.\n * @see {@link https://workleap.github.io/wl-telemetry}\n */\nexport class LogRocketLogger implements Logger {\n readonly #logLevel: LogLevel;\n #segments: Segment[] = [];\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n constructor(options: LoggerOptions = {}) {\n const {\n logLevel = LogLevel.debug\n } = options;\n\n this.#logLevel = logLevel;\n }\n\n #resetSegments() {\n this.#segments = [];\n }\n\n #log(fct: LogFunction, threshold: LogLevel) {\n if (this.#segments.length > 0) {\n if (this.#logLevel <= threshold) {\n const values = this.#segments.map(x => x.value);\n\n fct(...values);\n }\n\n this.#resetSegments();\n }\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n getName() {\n return LogRocketLogger.name;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withText(text?: string) {\n if (text) {\n this.#segments.push({\n type: \"text\",\n value: text\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withError(error?: Error) {\n if (error) {\n this.#segments.push({\n type: \"error\",\n value: error\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withObject(obj?: unknown) {\n if (obj) {\n this.#segments.push({\n type: \"object\",\n value: obj\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withLineChange() {\n this.#segments.push({\n type: \"line-change\",\n value: \"\\r\\n\"\n });\n\n return this;\n }\n\n /**\n * Write a debug log. The log will be processed only if the logger LogLevel is >= debug.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n debug(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.debug);\n }\n\n /**\n * Write an information log. The log will be processed only if the logger LogLevel is >= information.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n information(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.information);\n }\n\n /**\n * Write a warning log. The log will be processed only if the logger LogLevel is >= warning.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n warning(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.warn, LogLevel.warning);\n }\n\n /**\n * Write an error log. The log will be processed only if the logger LogLevel is >= error.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n error(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.error);\n }\n\n /**\n * Write a critical log. The log will be processed only if the logger LogLevel is >= critical.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n critical(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.critical);\n }\n\n /**\n * Start a new logging scope. The scope will inherit the LogLevel of the root logger.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n startScope(label: string) {\n return new LogRocketLoggerScope(label, this.#logLevel);\n }\n}\n"],"names":["LogLevel","LogRocket","LogRocketLoggerScope","label","logLevel","fct","threshold","segments","values","x","text","error","obj","log","options","dismiss","LogRocketLogger"],"mappings":";;;;;;;;AAA4H;AAC1F;AAUlC;;;CAGC,GACM,MAAME;IACA,SAAS,CAAW;IACpB,MAAM,CAAS;IAExB,SAAS,GAAc,EAAE,CAAC;IAC1B,YAAY,GAAiB,EAAE,CAAC;IAChC,SAAS,GAAY,MAAM;IAE3B;;KAEC,GACD,YAAYC,KAAa,EAAEC,QAAkB,CAAE;QAC3C,IAAI,CAAC,SAAS,GAAGA;QACjB,IAAI,CAAC,MAAM,GAAGD;IAClB;IAEA,cAAc;QACV,IAAI,CAAC,SAAS,GAAG,EAAE;IACvB;IAEA,IAAI,CAACE,GAAgB,EAAEC,SAAmB;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,GAAG;YAC3B,IAAI,IAAI,CAAC,SAAS,IAAIA,WAAW;gBAC7B,+GAA+G;gBAC/G,MAAMC,WAAW,IAAI,CAAC,SAAS;gBAE/B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;oBACnB,MAAMC,SAASD,SAAS,GAAG,CAACE,CAAAA,IAAKA,EAAE,KAAK;oBACxCD,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;oBAEjCH,OAAOG;gBACX;YACJ;YAEA,IAAI,CAAC,cAAc;QACvB;IACJ;IAEA;;KAEC,GACD,SAASE,IAAa,EAAE;QACpB,IAAIA,MAAM;YACN,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,OAAO,IAAI;IACf;IAEA;;KAEC,GACD,UAAUC,KAAa,EAAE;QACrB,IAAIA,OAAO;YACP,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,OAAO,IAAI;IACf;IAEA;;KAEC,GACD,WAAWC,GAAa,EAAE;QACtB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,OAAO,IAAI;IACf;IAEA;;KAEC,GACD,iBAAiB;QACb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAChB,MAAM;YACN,OAAO;QACX;QAEA,OAAO,IAAI;IACf;IAEA;;;KAGC,GACD,MAAMC,GAAY,EAAE;QAChB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,aAAa,EAAED,cAAc;IAC3C;IAEA;;;KAGC,GACD,YAAYa,GAAY,EAAE;QACtB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,aAAa,EAAED,oBAAoB;IACjD;IAEA;;;KAGC,GACD,QAAQa,GAAY,EAAE;QAClB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,cAAc,EAAED,gBAAgB;IAC9C;IAEA;;;KAGC,GACD,MAAMa,GAAY,EAAE;QAChB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,eAAe,EAAED,cAAc;IAC7C;IAEA;;;KAGC,GACD,SAASa,GAAY,EAAE;QACnB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,eAAe,EAAED,iBAAiB;IAChD;IAEA;;KAEC,GACD,IAAIc,UAAiC,CAAC,CAAC,EAAE;QACrC,MAAM,EACFC,UAAU,KAAK,EAClB,GAAGD;QAEJ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACjB,IAAI,CAAC,SAAS,GAAG;YAEjB,IAAI,CAACC,SAAS;gBACV,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,GAAG;oBAC9B,IAAI,CAAC,YAAY,CAAC,OAAO,CAACN,CAAAA;wBACtBA;oBACJ;oBAEA,IAAI,CAAC,YAAY,GAAG,EAAE;gBAC1B;YACJ;QACJ;IACJ;AACJ;AAEA;;;CAGC,GACM,MAAMO;IACA,SAAS,CAAW;IAC7B,SAAS,GAAc,EAAE,CAAC;IAE1B;;KAEC,GACD,YAAYF,UAAyB,CAAC,CAAC,CAAE;QACrC,MAAM,EACFV,WAAWJ,cAAc,EAC5B,GAAGc;QAEJ,IAAI,CAAC,SAAS,GAAGV;IACrB;IAEA,cAAc;QACV,IAAI,CAAC,SAAS,GAAG,EAAE;IACvB;IAEA,IAAI,CAACC,GAAgB,EAAEC,SAAmB;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,GAAG;YAC3B,IAAI,IAAI,CAAC,SAAS,IAAIA,WAAW;gBAC7B,MAAME,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAACC,CAAAA,IAAKA,EAAE,KAAK;gBAE9CJ,OAAOG;YACX;YAEA,IAAI,CAAC,cAAc;QACvB;IACJ;IAEA;;KAEC,GACD,UAAU;QACN,OAAOQ,gBAAgB,IAAI;IAC/B;IAEA;;KAEC,GACD,SAASN,IAAa,EAAE;QACpB,IAAIA,MAAM;YACN,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,OAAO,IAAI;IACf;IAEA;;KAEC,GACD,UAAUC,KAAa,EAAE;QACrB,IAAIA,OAAO;YACP,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,OAAO,IAAI;IACf;IAEA;;KAEC,GACD,WAAWC,GAAa,EAAE;QACtB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,OAAO,IAAI;IACf;IAEA;;KAEC,GACD,iBAAiB;QACb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAChB,MAAM;YACN,OAAO;QACX;QAEA,OAAO,IAAI;IACf;IAEA;;;KAGC,GACD,MAAMC,GAAY,EAAE;QAChB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,aAAa,EAAED,cAAc;IAC3C;IAEA;;;KAGC,GACD,YAAYa,GAAY,EAAE;QACtB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,aAAa,EAAED,oBAAoB;IACjD;IAEA;;;KAGC,GACD,QAAQa,GAAY,EAAE;QAClB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,cAAc,EAAED,gBAAgB;IAC9C;IAEA;;;KAGC,GACD,MAAMa,GAAY,EAAE;QAChB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,eAAe,EAAED,cAAc;IAC7C;IAEA;;;KAGC,GACD,SAASa,GAAY,EAAE;QACnB,IAAIA,KAAK;YACL,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAChB,MAAM;gBACN,OAAOA;YACX;QACJ;QAEA,IAAI,CAAC,IAAI,CAACZ,eAAe,EAAED,iBAAiB;IAChD;IAEA;;;KAGC,GACD,WAAWG,KAAa,EAAE;QACtB,OAAO,IAAID,qBAAqBC,OAAO,IAAI,CAAC,SAAS;IACzD;AACJ"}
1
+ {"version":3,"file":"LogRocketLogger.js","sources":["webpack://@workleap/logrocket/./src/LogRocketLogger.ts"],"sourcesContent":["import { type Logger, type LoggerOptions, type LoggerScope, type LoggerScopeEndOptions, LogLevel, type LogOptions } from \"@workleap/logging\";\nimport LogRocket from \"logrocket\";\n\ninterface Segment {\n type: \"text\" | \"object\" | \"error\" | \"line-change\";\n value: unknown;\n options?: LogOptions;\n}\n\nfunction appendText(currentText: string, newText: string, options: { leadingSpace?: boolean } = {}) {\n const {\n leadingSpace = true\n } = options;\n\n if (currentText.length > 0) {\n return `${currentText}${leadingSpace ? \" \" : \"\"}${newText}`;\n }\n\n return newText;\n}\n\n/**\n * Formats an array of Segment objects into a list of log arguments.\n *\n * - Consecutive \"text\" segments are concatenated into a single string, separated by spaces (unless `leadingSpace` is false).\n * - Non-\"text\" segments (\"object\", \"error\", \"line-change\") are added directly to the output array.\n * - When a non-\"text\" segment is encountered, any buffered text is flushed to the output before adding the segment.\n * - At the end, any remaining buffered text is flushed.\n */\nfunction formatSegments(segments: Segment[]) {\n const logs: unknown[] = [];\n\n let textBuffer = \"\";\n\n const flushText = () => {\n if (textBuffer.length > 0) {\n logs.push(textBuffer);\n\n textBuffer = \"\";\n }\n };\n\n segments.forEach(x => {\n if (x.type === \"text\") {\n textBuffer = appendText(textBuffer, x.value as string, {\n leadingSpace: x.options?.leadingSpace\n });\n } else {\n flushText();\n\n logs.push(x.value);\n }\n });\n\n // If the last segment is text, the text buffer hasn't been flushed.\n flushText();\n\n return logs;\n}\n\ntype LogFunction = (...rest: unknown[]) => void;\ntype PendingLog = () => void;\n\n/**\n * An scope implementation for the LogRocket logger.\n * @see {@link https://workleap.github.io/wl-telemetry}\n */\nexport class LogRocketLoggerScope implements LoggerScope {\n readonly #logLevel: LogLevel;\n readonly #label: string;\n\n #segments: Segment[] = [];\n #pendingLogs: PendingLog[] = [];\n #hasEnded: boolean = false;\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n constructor(label: string, logLevel: LogLevel) {\n this.#logLevel = logLevel;\n this.#label = label;\n }\n\n #resetSegments() {\n this.#segments = [];\n }\n\n #log(fct: LogFunction, threshold: LogLevel) {\n if (this.#segments.length > 0) {\n if (this.#logLevel <= threshold) {\n // Required closure to preserved the current log items for when they will be formatted when the scope is ended.\n const segments = this.#segments;\n\n this.#pendingLogs.push(() => {\n const formattedSegments = formatSegments(segments);\n // Since LogRocket session replay UI doesn't have a concept similar to console.group,\n // the logs of a group are indented by 4 spaces under the group label.\n formattedSegments.unshift(\" \");\n\n fct(...formattedSegments);\n });\n }\n\n this.#resetSegments();\n }\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withText(text?: string, options?: Omit<LogOptions, \"style\">) {\n if (text) {\n this.#segments.push({\n type: \"text\",\n value: text,\n options\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withError(error?: Error) {\n if (error) {\n this.#segments.push({\n type: \"error\",\n value: error\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withObject(obj?: unknown) {\n if (obj) {\n this.#segments.push({\n type: \"object\",\n value: obj\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withLineChange() {\n this.#segments.push({\n type: \"line-change\",\n value: \"\\r\\n\"\n });\n\n return this;\n }\n\n /**\n * Write a debug log. The log will be processed only if the logger LogLevel is >= debug.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n debug(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.debug);\n }\n\n /**\n * Write an information log. The log will be processed only if the logger LogLevel is >= information.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n information(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.information);\n }\n\n /**\n * Write a warning log. The log will be processed only if the logger LogLevel is >= warning.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n warning(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.warn, LogLevel.warning);\n }\n\n /**\n * Write an error log. The log will be processed only if the logger LogLevel is >= error.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n error(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.error);\n }\n\n /**\n * Write a critical log. The log will be processed only if the logger LogLevel is >= critical.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n critical(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.critical);\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n end(options: LoggerScopeEndOptions = {}) {\n const {\n dismiss = false\n } = options;\n\n if (!this.#hasEnded) {\n this.#hasEnded = true;\n\n if (!dismiss) {\n if (this.#pendingLogs.length > 0) {\n LogRocket.log(this.#label);\n\n this.#pendingLogs.forEach(x => {\n x();\n });\n\n this.#pendingLogs = [];\n }\n }\n }\n }\n}\n\n/**\n * A logger implementation for LogRocket.\n * @see {@link https://workleap.github.io/wl-telemetry}\n */\nexport class LogRocketLogger implements Logger {\n readonly #logLevel: LogLevel;\n #segments: Segment[] = [];\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n constructor(options: LoggerOptions = {}) {\n const {\n logLevel = LogLevel.debug\n } = options;\n\n this.#logLevel = logLevel;\n }\n\n #resetSegments() {\n this.#segments = [];\n }\n\n #log(fct: LogFunction, threshold: LogLevel) {\n if (this.#segments.length > 0) {\n if (this.#logLevel <= threshold) {\n const formattedSegments = formatSegments(this.#segments);\n\n fct(...formattedSegments);\n }\n\n this.#resetSegments();\n }\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n getName() {\n return LogRocketLogger.name;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withText(text?: string, options?: Omit<LogOptions, \"style\">) {\n if (text) {\n this.#segments.push({\n type: \"text\",\n value: text,\n options\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withError(error?: Error) {\n if (error) {\n this.#segments.push({\n type: \"error\",\n value: error\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withObject(obj?: unknown) {\n if (obj) {\n this.#segments.push({\n type: \"object\",\n value: obj\n });\n }\n\n return this;\n }\n\n /**\n * @see {@link https://workleap.github.io/wl-logging}\n */\n withLineChange() {\n this.#segments.push({\n type: \"line-change\",\n value: \"\\r\\n\"\n });\n\n return this;\n }\n\n /**\n * Write a debug log. The log will be processed only if the logger LogLevel is >= debug.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n debug(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.debug);\n }\n\n /**\n * Write an information log. The log will be processed only if the logger LogLevel is >= information.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n information(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.log, LogLevel.information);\n }\n\n /**\n * Write a warning log. The log will be processed only if the logger LogLevel is >= warning.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n warning(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.warn, LogLevel.warning);\n }\n\n /**\n * Write an error log. The log will be processed only if the logger LogLevel is >= error.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n error(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.error);\n }\n\n /**\n * Write a critical log. The log will be processed only if the logger LogLevel is >= critical.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n critical(log?: string) {\n if (log) {\n this.#segments.push({\n type: \"text\",\n value: log\n });\n }\n\n this.#log(LogRocket.error, LogLevel.critical);\n }\n\n /**\n * Start a new logging scope. The scope will inherit the LogLevel of the root logger.\n * @see {@link https://workleap.github.io/wl-logging}\n */\n startScope(label: string) {\n return new LogRocketLoggerScope(label, this.#logLevel);\n }\n}\n"],"names":["LogLevel","LogRocket","appendText","currentText","newText","options","leadingSpace","formatSegments","segments","logs","textBuffer","flushText","x","LogRocketLoggerScope","label","logLevel","fct","threshold","formattedSegments","text","error","obj","log","dismiss","LogRocketLogger"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@workleap/logrocket",
3
3
  "author": "Workleap",
4
- "version": "1.2.4",
4
+ "version": "1.2.6",
5
5
  "description": "A package containing utilities for LogRocket.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -31,9 +31,9 @@
31
31
  "logrocket": "^10.1.0"
32
32
  },
33
33
  "dependencies": {
34
- "@workleap/logging": "^1.2.3",
34
+ "@workleap/logging": "^1.2.5",
35
35
  "logrocket-fuzzy-search-sanitizer": "0.0.2",
36
- "@workleap/telemetry": "1.1.5"
36
+ "@workleap/telemetry": "1.1.6"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@rsbuild/core": "1.4.6",
@@ -1,9 +1,61 @@
1
- import { type Logger, type LoggerOptions, type LoggerScope, type LoggerScopeEndOptions, LogLevel } from "@workleap/logging";
1
+ import { type Logger, type LoggerOptions, type LoggerScope, type LoggerScopeEndOptions, LogLevel, type LogOptions } from "@workleap/logging";
2
2
  import LogRocket from "logrocket";
3
3
 
4
4
  interface Segment {
5
5
  type: "text" | "object" | "error" | "line-change";
6
6
  value: unknown;
7
+ options?: LogOptions;
8
+ }
9
+
10
+ function appendText(currentText: string, newText: string, options: { leadingSpace?: boolean } = {}) {
11
+ const {
12
+ leadingSpace = true
13
+ } = options;
14
+
15
+ if (currentText.length > 0) {
16
+ return `${currentText}${leadingSpace ? " " : ""}${newText}`;
17
+ }
18
+
19
+ return newText;
20
+ }
21
+
22
+ /**
23
+ * Formats an array of Segment objects into a list of log arguments.
24
+ *
25
+ * - Consecutive "text" segments are concatenated into a single string, separated by spaces (unless `leadingSpace` is false).
26
+ * - Non-"text" segments ("object", "error", "line-change") are added directly to the output array.
27
+ * - When a non-"text" segment is encountered, any buffered text is flushed to the output before adding the segment.
28
+ * - At the end, any remaining buffered text is flushed.
29
+ */
30
+ function formatSegments(segments: Segment[]) {
31
+ const logs: unknown[] = [];
32
+
33
+ let textBuffer = "";
34
+
35
+ const flushText = () => {
36
+ if (textBuffer.length > 0) {
37
+ logs.push(textBuffer);
38
+
39
+ textBuffer = "";
40
+ }
41
+ };
42
+
43
+ segments.forEach(x => {
44
+ if (x.type === "text") {
45
+ textBuffer = appendText(textBuffer, x.value as string, {
46
+ leadingSpace: x.options?.leadingSpace
47
+ });
48
+ } else {
49
+ flushText();
50
+
51
+ logs.push(x.value);
52
+ }
53
+ });
54
+
55
+ // If the last segment is text, the text buffer hasn't been flushed.
56
+ flushText();
57
+
58
+ return logs;
7
59
  }
8
60
 
9
61
  type LogFunction = (...rest: unknown[]) => void;
@@ -40,10 +92,12 @@ export class LogRocketLoggerScope implements LoggerScope {
40
92
  const segments = this.#segments;
41
93
 
42
94
  this.#pendingLogs.push(() => {
43
- const values = segments.map(x => x.value);
44
- values.unshift(`(${this.#label})`);
95
+ const formattedSegments = formatSegments(segments);
96
+ // Since LogRocket session replay UI doesn't have a concept similar to console.group,
97
+ // the logs of a group are indented by 4 spaces under the group label.
98
+ formattedSegments.unshift(" ");
45
99
 
46
- fct(...values);
100
+ fct(...formattedSegments);
47
101
  });
48
102
  }
49
103
 
@@ -54,11 +108,12 @@ export class LogRocketLoggerScope implements LoggerScope {
54
108
  /**
55
109
  * @see {@link https://workleap.github.io/wl-logging}
56
110
  */
57
- withText(text?: string) {
111
+ withText(text?: string, options?: Omit<LogOptions, "style">) {
58
112
  if (text) {
59
113
  this.#segments.push({
60
114
  type: "text",
61
- value: text
115
+ value: text,
116
+ options
62
117
  });
63
118
  }
64
119
 
@@ -193,6 +248,8 @@ export class LogRocketLoggerScope implements LoggerScope {
193
248
 
194
249
  if (!dismiss) {
195
250
  if (this.#pendingLogs.length > 0) {
251
+ LogRocket.log(this.#label);
252
+
196
253
  this.#pendingLogs.forEach(x => {
197
254
  x();
198
255
  });
@@ -230,9 +287,9 @@ export class LogRocketLogger implements Logger {
230
287
  #log(fct: LogFunction, threshold: LogLevel) {
231
288
  if (this.#segments.length > 0) {
232
289
  if (this.#logLevel <= threshold) {
233
- const values = this.#segments.map(x => x.value);
290
+ const formattedSegments = formatSegments(this.#segments);
234
291
 
235
- fct(...values);
292
+ fct(...formattedSegments);
236
293
  }
237
294
 
238
295
  this.#resetSegments();
@@ -249,11 +306,12 @@ export class LogRocketLogger implements Logger {
249
306
  /**
250
307
  * @see {@link https://workleap.github.io/wl-logging}
251
308
  */
252
- withText(text?: string) {
309
+ withText(text?: string, options?: Omit<LogOptions, "style">) {
253
310
  if (text) {
254
311
  this.#segments.push({
255
312
  type: "text",
256
- value: text
313
+ value: text,
314
+ options
257
315
  });
258
316
  }
259
317