@posthog/browser-common 0.9.3 → 0.9.4

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/client.d.ts CHANGED
@@ -19,6 +19,8 @@ export interface SessionContext {
19
19
  readonly windowId: string;
20
20
  /** When the session started, as a Unix timestamp in milliseconds. */
21
21
  readonly sessionStartTimestamp: number;
22
+ /** Most recent session activity, as a Unix timestamp in milliseconds. */
23
+ readonly lastActivityTimestamp: number;
22
24
  }
23
25
  /** A captured event, as observed by `onEvent`. */
24
26
  export interface CapturedEventInfo {
@@ -98,8 +100,8 @@ export interface Client {
98
100
  readonly initialPersonProperties: DeepReadonly<Record<string, unknown>>;
99
101
  /** Active group memberships attached to events as `$groups`. */
100
102
  readonly groups: DeepReadonly<Record<string, string>>;
101
- /** The current session, created on first read if needed. */
102
- readonly session: SessionContext;
103
+ /** The current session, if one exists. Reading it need not create one. */
104
+ readonly session: SessionContext | undefined;
103
105
  /** Whether the host currently permits data capture. */
104
106
  readonly canCapture: boolean;
105
107
  /** Synchronously admits an analytics event to the client's normal pipeline. */
package/dist/config.js CHANGED
@@ -27,7 +27,7 @@ var __webpack_require__ = {};
27
27
  })();
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
- const packageVersion = "0.9.3";
30
+ const packageVersion = "0.9.4";
31
31
  const Config = {
32
32
  DEBUG: false,
33
33
  LIB_VERSION: packageVersion,
package/dist/config.mjs CHANGED
@@ -1,4 +1,4 @@
1
- const packageVersion = "0.9.3";
1
+ const packageVersion = "0.9.4";
2
2
  const Config = {
3
3
  DEBUG: false,
4
4
  LIB_VERSION: packageVersion,
@@ -0,0 +1,15 @@
1
+ import type { BufferedConsoleEntry } from './logs-types';
2
+ import type { CaptureLogOptions } from '@posthog/types';
3
+ import type { LogSdkContext } from '@posthog/core';
4
+ export interface ConsoleLogsSink {
5
+ captureConsoleLog(options: CaptureLogOptions): void;
6
+ captureBufferedConsoleLog?(options: CaptureLogOptions, context: LogSdkContext, occurredAtMs: number): void;
7
+ }
8
+ export interface ConsoleLogsHost {
9
+ console: Console;
10
+ hostname: string;
11
+ getCapturingLogs(): ConsoleLogsSink | undefined;
12
+ }
13
+ export declare const initializeLogs: (host: ConsoleLogsHost) => (() => void);
14
+ /** Replays console calls the main bundle recorded before this script loaded. */
15
+ export declare const replayConsoleBuffer: (host: ConsoleLogsHost, entries: BufferedConsoleEntry[]) => void;
@@ -0,0 +1,317 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
13
+ };
14
+ })();
15
+ (()=>{
16
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
17
+ })();
18
+ (()=>{
19
+ __webpack_require__.r = (exports1)=>{
20
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
21
+ value: 'Module'
22
+ });
23
+ Object.defineProperty(exports1, '__esModule', {
24
+ value: true
25
+ });
26
+ };
27
+ })();
28
+ var __webpack_exports__ = {};
29
+ __webpack_require__.r(__webpack_exports__);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ initializeLogs: ()=>initializeLogs,
32
+ replayConsoleBuffer: ()=>replayConsoleBuffer
33
+ });
34
+ const patch_js_namespaceObject = require("./utils/patch.js");
35
+ const console_original_js_namespaceObject = require("./utils/console-original.js");
36
+ const core_namespaceObject = require("@posthog/core");
37
+ const LOG_BODY_SIZE_LIMIT = 10000;
38
+ const LOG_ATTRIBUTES_LIMIT = 50;
39
+ const appendWithLimit = (parts, text, budget)=>{
40
+ if (budget.remaining <= 0) {
41
+ budget.truncated = true;
42
+ return false;
43
+ }
44
+ if (text.length <= budget.remaining) {
45
+ parts.push(text);
46
+ budget.remaining -= text.length;
47
+ return true;
48
+ }
49
+ parts.push(text.slice(0, budget.remaining));
50
+ budget.remaining = 0;
51
+ budget.truncated = true;
52
+ return false;
53
+ };
54
+ const stringifyStringWithLimit = (value, parts, budget)=>{
55
+ const serialized = JSON.stringify(value);
56
+ if (serialized.length <= budget.remaining) return appendWithLimit(parts, serialized, budget);
57
+ budget.truncated = true;
58
+ if (budget.remaining < 2) return false;
59
+ let low = 0;
60
+ let high = Math.min(value.length, budget.remaining - 2);
61
+ while(low < high){
62
+ const mid = Math.ceil((low + high) / 2);
63
+ if (JSON.stringify(value.slice(0, mid)).length <= budget.remaining) low = mid;
64
+ else high = mid - 1;
65
+ }
66
+ return appendWithLimit(parts, JSON.stringify(value.slice(0, low)), budget);
67
+ };
68
+ const isJSONSerializablePrimitive = (value)=>void 0 !== value && 'function' != typeof value && 'symbol' != typeof value && 'bigint' != typeof value;
69
+ const isNumberOrBoolean = (value)=>{
70
+ try {
71
+ return (0, core_namespaceObject.isNumber)(value) || (0, core_namespaceObject.isBoolean)(value);
72
+ } catch {
73
+ return false;
74
+ }
75
+ };
76
+ const collectAttributeValue = (key, value, collector)=>{
77
+ if (collector.truncated) return;
78
+ collector.keysRemaining -= 1;
79
+ collector.sizeRemaining -= String(value).length + key.length;
80
+ if (collector.keysRemaining <= 0 || collector.sizeRemaining <= 0) {
81
+ collector.truncated = true;
82
+ collector.result['attributes_truncated'] = true;
83
+ return;
84
+ }
85
+ collector.result[key] = value;
86
+ };
87
+ const collectFlattenedAttributes = (value, key, collector)=>{
88
+ if (collector.truncated) return;
89
+ if ((0, core_namespaceObject.isObject)(value)) {
90
+ if (collector.seen.has(value)) return void collectAttributeValue(key || 'circular', '[Circular]', collector);
91
+ collector.seen.add(value);
92
+ try {
93
+ for(const childKey in value)try {
94
+ if (!Object.prototype.hasOwnProperty.call(value, childKey)) continue;
95
+ const childValue = value[childKey];
96
+ collectFlattenedAttributes(childValue, key ? `${key}.${childKey}` : childKey, collector);
97
+ if (collector.truncated) break;
98
+ } catch {
99
+ continue;
100
+ }
101
+ } catch {}
102
+ return;
103
+ }
104
+ collectAttributeValue(key, value, collector);
105
+ };
106
+ const stringifyValueWithLimit = (value, parts, budget, seen, inArray = false, attributeCollector)=>{
107
+ if (!isJSONSerializablePrimitive(value)) return inArray ? appendWithLimit(parts, 'null', budget) : true;
108
+ if ((0, core_namespaceObject.isNull)(value) || isNumberOrBoolean(value)) return appendWithLimit(parts, JSON.stringify(value), budget);
109
+ if ('string' == typeof value) return stringifyStringWithLimit(value, parts, budget);
110
+ if (!(0, core_namespaceObject.isObject)(value) && !(0, core_namespaceObject.isArray)(value)) return appendWithLimit(parts, JSON.stringify(value), budget);
111
+ if (seen.has(value)) return stringifyStringWithLimit('[Circular]', parts, budget);
112
+ seen.add(value);
113
+ try {
114
+ const toJSON = value.toJSON;
115
+ if ((0, core_namespaceObject.isFunction)(toJSON)) return stringifyValueWithLimit(toJSON.call(value), parts, budget, seen, inArray);
116
+ } catch {}
117
+ try {
118
+ const objectTag = Object.prototype.toString.call(value);
119
+ if ('[object String]' === objectTag) return stringifyStringWithLimit(String(value.valueOf()), parts, budget);
120
+ if ('[object Number]' === objectTag || '[object Boolean]' === objectTag) return appendWithLimit(parts, JSON.stringify(value.valueOf()), budget);
121
+ } catch {}
122
+ if (value instanceof Error) {
123
+ const errorObject = {};
124
+ try {
125
+ for(const key in value)if (Object.prototype.hasOwnProperty.call(value, key)) errorObject[key] = value[key];
126
+ } catch {}
127
+ try {
128
+ errorObject.name = value.name;
129
+ } catch {}
130
+ try {
131
+ errorObject.message = value.message;
132
+ } catch {}
133
+ try {
134
+ errorObject.stack = value.stack;
135
+ } catch {}
136
+ return stringifyValueWithLimit(errorObject, parts, budget, seen, inArray, attributeCollector);
137
+ }
138
+ if ((0, core_namespaceObject.isArray)(value)) {
139
+ if (!appendWithLimit(parts, '[', budget)) return false;
140
+ for(let i = 0; i < value.length; i++){
141
+ if (i > 0 && !appendWithLimit(parts, ',', budget)) return false;
142
+ let item;
143
+ try {
144
+ item = value[i];
145
+ } catch {
146
+ item = void 0;
147
+ }
148
+ if (!stringifyValueWithLimit(item, parts, budget, seen, true)) return false;
149
+ }
150
+ return appendWithLimit(parts, ']', budget);
151
+ }
152
+ if (!appendWithLimit(parts, '{', budget)) return false;
153
+ let isFirst = true;
154
+ try {
155
+ for(const key in value){
156
+ if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
157
+ if (budget.remaining <= 0) {
158
+ budget.truncated = true;
159
+ return false;
160
+ }
161
+ let propertyValue;
162
+ try {
163
+ propertyValue = value[key];
164
+ } catch {
165
+ continue;
166
+ }
167
+ if (attributeCollector) try {
168
+ collectFlattenedAttributes(propertyValue, key, attributeCollector);
169
+ } catch {}
170
+ if (!isJSONSerializablePrimitive(propertyValue)) continue;
171
+ const propertyPrefix = `${isFirst ? '' : ','}${JSON.stringify(key)}:`;
172
+ if (propertyPrefix.length >= budget.remaining) {
173
+ budget.truncated = true;
174
+ return false;
175
+ }
176
+ const partsBeforeProperty = parts.length;
177
+ const remainingBeforeProperty = budget.remaining;
178
+ const truncatedBeforeProperty = budget.truncated;
179
+ if (!appendWithLimit(parts, propertyPrefix, budget)) return false;
180
+ const partsBeforeValue = parts.length;
181
+ const serialized = stringifyValueWithLimit(propertyValue, parts, budget, seen, false);
182
+ const truncatedAfterValue = budget.truncated;
183
+ if (parts.length === partsBeforeValue) {
184
+ parts.length = partsBeforeProperty;
185
+ budget.remaining = remainingBeforeProperty;
186
+ budget.truncated = serialized ? truncatedBeforeProperty : truncatedAfterValue;
187
+ if (!serialized) return false;
188
+ continue;
189
+ }
190
+ isFirst = false;
191
+ if (!serialized) return false;
192
+ }
193
+ } catch {}
194
+ return appendWithLimit(parts, '}', budget);
195
+ };
196
+ const stringifyArgsSafely = (args, sizeLimit)=>{
197
+ const parts = [];
198
+ const budget = {
199
+ remaining: sizeLimit,
200
+ truncated: false
201
+ };
202
+ const attributeCollector = (0, core_namespaceObject.isObject)(args[0]) ? {
203
+ result: {},
204
+ keysRemaining: LOG_ATTRIBUTES_LIMIT,
205
+ sizeRemaining: LOG_BODY_SIZE_LIMIT,
206
+ truncated: false,
207
+ seen: new WeakSet([
208
+ args[0]
209
+ ])
210
+ } : void 0;
211
+ for(let i = 0; i < args.length; i++){
212
+ if (i > 0 && !appendWithLimit(parts, ' ', budget)) break;
213
+ if (!stringifyValueWithLimit(args[i], parts, budget, new WeakSet(), false, 0 === i ? attributeCollector : void 0)) break;
214
+ }
215
+ return {
216
+ body: parts.join('') + (budget.truncated ? '...' : ''),
217
+ truncated: budget.truncated,
218
+ attributes: attributeCollector?.result || {}
219
+ };
220
+ };
221
+ const LEVEL_MAP = {
222
+ debug: 'debug',
223
+ log: 'info',
224
+ warn: 'warn',
225
+ error: 'error',
226
+ info: 'info'
227
+ };
228
+ const initializeLogs = (host)=>{
229
+ const console = host.console;
230
+ let currentHost = host;
231
+ const restoreConsoleMethods = [];
232
+ const attributes = {
233
+ host: host.hostname
234
+ };
235
+ let isCapturingLog = false;
236
+ const dispose = ()=>{
237
+ currentHost = void 0;
238
+ for (const restore of restoreConsoleMethods)try {
239
+ restore();
240
+ } catch {}
241
+ };
242
+ try {
243
+ for (const level of Object.keys(LEVEL_MAP)){
244
+ const logWrapper = (next)=>(...args)=>{
245
+ let acquiredGuard = false;
246
+ try {
247
+ const activeHost = currentHost;
248
+ if (args.length > 0 && !isCapturingLog && activeHost) {
249
+ const logs = activeHost.getCapturingLogs();
250
+ if (logs) {
251
+ isCapturingLog = true;
252
+ acquiredGuard = true;
253
+ const { body, truncated, attributes: flattenedAttributes } = stringifyArgsSafely(args, LOG_BODY_SIZE_LIMIT);
254
+ const logAttributes = {
255
+ ...attributes,
256
+ ...truncated ? {
257
+ body_truncated: 'true'
258
+ } : {}
259
+ };
260
+ const options = {
261
+ level: LEVEL_MAP[level],
262
+ body,
263
+ attributes: {
264
+ 'log.source': `console.${level}`,
265
+ ...logAttributes,
266
+ ...flattenedAttributes
267
+ }
268
+ };
269
+ logs.captureConsoleLog(options);
270
+ }
271
+ }
272
+ } catch {} finally{
273
+ if (acquiredGuard) isCapturingLog = false;
274
+ next.apply(console, args);
275
+ }
276
+ };
277
+ const consoleBeforePatch = console[level];
278
+ restoreConsoleMethods.push((0, patch_js_namespaceObject.patch)(console, level, (next)=>{
279
+ const wrapped = logWrapper(next);
280
+ wrapped.__rrweb_original__ = (0, console_original_js_namespaceObject.originalConsoleMethod)(consoleBeforePatch);
281
+ return wrapped;
282
+ }));
283
+ }
284
+ } catch (error) {
285
+ dispose();
286
+ throw error;
287
+ }
288
+ return dispose;
289
+ };
290
+ const replayConsoleBuffer = (host, entries)=>{
291
+ const logs = host.getCapturingLogs();
292
+ if (!logs) return;
293
+ for (const entry of entries)try {
294
+ const { body, truncated, attributes: flattenedAttributes } = stringifyArgsSafely(entry.args, LOG_BODY_SIZE_LIMIT);
295
+ logs.captureBufferedConsoleLog?.({
296
+ level: LEVEL_MAP[entry.level],
297
+ body,
298
+ attributes: {
299
+ 'log.source': `console.${entry.level}`,
300
+ host: host.hostname,
301
+ ...truncated ? {
302
+ body_truncated: 'true'
303
+ } : {},
304
+ ...flattenedAttributes
305
+ }
306
+ }, entry.context, entry.occurredAtMs);
307
+ } catch {}
308
+ };
309
+ exports.initializeLogs = __webpack_exports__.initializeLogs;
310
+ exports.replayConsoleBuffer = __webpack_exports__.replayConsoleBuffer;
311
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
312
+ "initializeLogs",
313
+ "replayConsoleBuffer"
314
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
315
+ Object.defineProperty(exports, '__esModule', {
316
+ value: true
317
+ });
@@ -0,0 +1,276 @@
1
+ import { patch } from "./utils/patch.mjs";
2
+ import { originalConsoleMethod } from "./utils/console-original.mjs";
3
+ import { isArray, isBoolean, isFunction, isNull, isNumber, isObject } from "@posthog/core";
4
+ const LOG_BODY_SIZE_LIMIT = 10000;
5
+ const LOG_ATTRIBUTES_LIMIT = 50;
6
+ const appendWithLimit = (parts, text, budget)=>{
7
+ if (budget.remaining <= 0) {
8
+ budget.truncated = true;
9
+ return false;
10
+ }
11
+ if (text.length <= budget.remaining) {
12
+ parts.push(text);
13
+ budget.remaining -= text.length;
14
+ return true;
15
+ }
16
+ parts.push(text.slice(0, budget.remaining));
17
+ budget.remaining = 0;
18
+ budget.truncated = true;
19
+ return false;
20
+ };
21
+ const stringifyStringWithLimit = (value, parts, budget)=>{
22
+ const serialized = JSON.stringify(value);
23
+ if (serialized.length <= budget.remaining) return appendWithLimit(parts, serialized, budget);
24
+ budget.truncated = true;
25
+ if (budget.remaining < 2) return false;
26
+ let low = 0;
27
+ let high = Math.min(value.length, budget.remaining - 2);
28
+ while(low < high){
29
+ const mid = Math.ceil((low + high) / 2);
30
+ if (JSON.stringify(value.slice(0, mid)).length <= budget.remaining) low = mid;
31
+ else high = mid - 1;
32
+ }
33
+ return appendWithLimit(parts, JSON.stringify(value.slice(0, low)), budget);
34
+ };
35
+ const isJSONSerializablePrimitive = (value)=>void 0 !== value && 'function' != typeof value && 'symbol' != typeof value && 'bigint' != typeof value;
36
+ const isNumberOrBoolean = (value)=>{
37
+ try {
38
+ return isNumber(value) || isBoolean(value);
39
+ } catch {
40
+ return false;
41
+ }
42
+ };
43
+ const collectAttributeValue = (key, value, collector)=>{
44
+ if (collector.truncated) return;
45
+ collector.keysRemaining -= 1;
46
+ collector.sizeRemaining -= String(value).length + key.length;
47
+ if (collector.keysRemaining <= 0 || collector.sizeRemaining <= 0) {
48
+ collector.truncated = true;
49
+ collector.result['attributes_truncated'] = true;
50
+ return;
51
+ }
52
+ collector.result[key] = value;
53
+ };
54
+ const collectFlattenedAttributes = (value, key, collector)=>{
55
+ if (collector.truncated) return;
56
+ if (isObject(value)) {
57
+ if (collector.seen.has(value)) return void collectAttributeValue(key || 'circular', '[Circular]', collector);
58
+ collector.seen.add(value);
59
+ try {
60
+ for(const childKey in value)try {
61
+ if (!Object.prototype.hasOwnProperty.call(value, childKey)) continue;
62
+ const childValue = value[childKey];
63
+ collectFlattenedAttributes(childValue, key ? `${key}.${childKey}` : childKey, collector);
64
+ if (collector.truncated) break;
65
+ } catch {
66
+ continue;
67
+ }
68
+ } catch {}
69
+ return;
70
+ }
71
+ collectAttributeValue(key, value, collector);
72
+ };
73
+ const stringifyValueWithLimit = (value, parts, budget, seen, inArray = false, attributeCollector)=>{
74
+ if (!isJSONSerializablePrimitive(value)) return inArray ? appendWithLimit(parts, 'null', budget) : true;
75
+ if (isNull(value) || isNumberOrBoolean(value)) return appendWithLimit(parts, JSON.stringify(value), budget);
76
+ if ('string' == typeof value) return stringifyStringWithLimit(value, parts, budget);
77
+ if (!isObject(value) && !isArray(value)) return appendWithLimit(parts, JSON.stringify(value), budget);
78
+ if (seen.has(value)) return stringifyStringWithLimit('[Circular]', parts, budget);
79
+ seen.add(value);
80
+ try {
81
+ const toJSON = value.toJSON;
82
+ if (isFunction(toJSON)) return stringifyValueWithLimit(toJSON.call(value), parts, budget, seen, inArray);
83
+ } catch {}
84
+ try {
85
+ const objectTag = Object.prototype.toString.call(value);
86
+ if ('[object String]' === objectTag) return stringifyStringWithLimit(String(value.valueOf()), parts, budget);
87
+ if ('[object Number]' === objectTag || '[object Boolean]' === objectTag) return appendWithLimit(parts, JSON.stringify(value.valueOf()), budget);
88
+ } catch {}
89
+ if (value instanceof Error) {
90
+ const errorObject = {};
91
+ try {
92
+ for(const key in value)if (Object.prototype.hasOwnProperty.call(value, key)) errorObject[key] = value[key];
93
+ } catch {}
94
+ try {
95
+ errorObject.name = value.name;
96
+ } catch {}
97
+ try {
98
+ errorObject.message = value.message;
99
+ } catch {}
100
+ try {
101
+ errorObject.stack = value.stack;
102
+ } catch {}
103
+ return stringifyValueWithLimit(errorObject, parts, budget, seen, inArray, attributeCollector);
104
+ }
105
+ if (isArray(value)) {
106
+ if (!appendWithLimit(parts, '[', budget)) return false;
107
+ for(let i = 0; i < value.length; i++){
108
+ if (i > 0 && !appendWithLimit(parts, ',', budget)) return false;
109
+ let item;
110
+ try {
111
+ item = value[i];
112
+ } catch {
113
+ item = void 0;
114
+ }
115
+ if (!stringifyValueWithLimit(item, parts, budget, seen, true)) return false;
116
+ }
117
+ return appendWithLimit(parts, ']', budget);
118
+ }
119
+ if (!appendWithLimit(parts, '{', budget)) return false;
120
+ let isFirst = true;
121
+ try {
122
+ for(const key in value){
123
+ if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
124
+ if (budget.remaining <= 0) {
125
+ budget.truncated = true;
126
+ return false;
127
+ }
128
+ let propertyValue;
129
+ try {
130
+ propertyValue = value[key];
131
+ } catch {
132
+ continue;
133
+ }
134
+ if (attributeCollector) try {
135
+ collectFlattenedAttributes(propertyValue, key, attributeCollector);
136
+ } catch {}
137
+ if (!isJSONSerializablePrimitive(propertyValue)) continue;
138
+ const propertyPrefix = `${isFirst ? '' : ','}${JSON.stringify(key)}:`;
139
+ if (propertyPrefix.length >= budget.remaining) {
140
+ budget.truncated = true;
141
+ return false;
142
+ }
143
+ const partsBeforeProperty = parts.length;
144
+ const remainingBeforeProperty = budget.remaining;
145
+ const truncatedBeforeProperty = budget.truncated;
146
+ if (!appendWithLimit(parts, propertyPrefix, budget)) return false;
147
+ const partsBeforeValue = parts.length;
148
+ const serialized = stringifyValueWithLimit(propertyValue, parts, budget, seen, false);
149
+ const truncatedAfterValue = budget.truncated;
150
+ if (parts.length === partsBeforeValue) {
151
+ parts.length = partsBeforeProperty;
152
+ budget.remaining = remainingBeforeProperty;
153
+ budget.truncated = serialized ? truncatedBeforeProperty : truncatedAfterValue;
154
+ if (!serialized) return false;
155
+ continue;
156
+ }
157
+ isFirst = false;
158
+ if (!serialized) return false;
159
+ }
160
+ } catch {}
161
+ return appendWithLimit(parts, '}', budget);
162
+ };
163
+ const stringifyArgsSafely = (args, sizeLimit)=>{
164
+ const parts = [];
165
+ const budget = {
166
+ remaining: sizeLimit,
167
+ truncated: false
168
+ };
169
+ const attributeCollector = isObject(args[0]) ? {
170
+ result: {},
171
+ keysRemaining: LOG_ATTRIBUTES_LIMIT,
172
+ sizeRemaining: LOG_BODY_SIZE_LIMIT,
173
+ truncated: false,
174
+ seen: new WeakSet([
175
+ args[0]
176
+ ])
177
+ } : void 0;
178
+ for(let i = 0; i < args.length; i++){
179
+ if (i > 0 && !appendWithLimit(parts, ' ', budget)) break;
180
+ if (!stringifyValueWithLimit(args[i], parts, budget, new WeakSet(), false, 0 === i ? attributeCollector : void 0)) break;
181
+ }
182
+ return {
183
+ body: parts.join('') + (budget.truncated ? '...' : ''),
184
+ truncated: budget.truncated,
185
+ attributes: attributeCollector?.result || {}
186
+ };
187
+ };
188
+ const LEVEL_MAP = {
189
+ debug: 'debug',
190
+ log: 'info',
191
+ warn: 'warn',
192
+ error: 'error',
193
+ info: 'info'
194
+ };
195
+ const initializeLogs = (host)=>{
196
+ const console = host.console;
197
+ let currentHost = host;
198
+ const restoreConsoleMethods = [];
199
+ const attributes = {
200
+ host: host.hostname
201
+ };
202
+ let isCapturingLog = false;
203
+ const dispose = ()=>{
204
+ currentHost = void 0;
205
+ for (const restore of restoreConsoleMethods)try {
206
+ restore();
207
+ } catch {}
208
+ };
209
+ try {
210
+ for (const level of Object.keys(LEVEL_MAP)){
211
+ const logWrapper = (next)=>(...args)=>{
212
+ let acquiredGuard = false;
213
+ try {
214
+ const activeHost = currentHost;
215
+ if (args.length > 0 && !isCapturingLog && activeHost) {
216
+ const logs = activeHost.getCapturingLogs();
217
+ if (logs) {
218
+ isCapturingLog = true;
219
+ acquiredGuard = true;
220
+ const { body, truncated, attributes: flattenedAttributes } = stringifyArgsSafely(args, LOG_BODY_SIZE_LIMIT);
221
+ const logAttributes = {
222
+ ...attributes,
223
+ ...truncated ? {
224
+ body_truncated: 'true'
225
+ } : {}
226
+ };
227
+ const options = {
228
+ level: LEVEL_MAP[level],
229
+ body,
230
+ attributes: {
231
+ 'log.source': `console.${level}`,
232
+ ...logAttributes,
233
+ ...flattenedAttributes
234
+ }
235
+ };
236
+ logs.captureConsoleLog(options);
237
+ }
238
+ }
239
+ } catch {} finally{
240
+ if (acquiredGuard) isCapturingLog = false;
241
+ next.apply(console, args);
242
+ }
243
+ };
244
+ const consoleBeforePatch = console[level];
245
+ restoreConsoleMethods.push(patch(console, level, (next)=>{
246
+ const wrapped = logWrapper(next);
247
+ wrapped.__rrweb_original__ = originalConsoleMethod(consoleBeforePatch);
248
+ return wrapped;
249
+ }));
250
+ }
251
+ } catch (error) {
252
+ dispose();
253
+ throw error;
254
+ }
255
+ return dispose;
256
+ };
257
+ const replayConsoleBuffer = (host, entries)=>{
258
+ const logs = host.getCapturingLogs();
259
+ if (!logs) return;
260
+ for (const entry of entries)try {
261
+ const { body, truncated, attributes: flattenedAttributes } = stringifyArgsSafely(entry.args, LOG_BODY_SIZE_LIMIT);
262
+ logs.captureBufferedConsoleLog?.({
263
+ level: LEVEL_MAP[entry.level],
264
+ body,
265
+ attributes: {
266
+ 'log.source': `console.${entry.level}`,
267
+ host: host.hostname,
268
+ ...truncated ? {
269
+ body_truncated: 'true'
270
+ } : {},
271
+ ...flattenedAttributes
272
+ }
273
+ }, entry.context, entry.occurredAtMs);
274
+ } catch {}
275
+ };
276
+ export { initializeLogs, replayConsoleBuffer };
@@ -0,0 +1,4 @@
1
+ import type { PostHogFeatureFlags } from './feature-flags';
2
+ import type { ExtensionToken } from './token';
3
+ /** Resolve the common feature-flags API without importing its implementation. */
4
+ export declare const FeatureFlagsCommonExtension: ExtensionToken<PostHogFeatureFlags>;