Socket
Socket
Sign inDemoInstall

@datadog/browser-core

Package Overview
Dependencies
0
Maintainers
1
Versions
248
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 5.1.0 to 5.2.0

cjs/tools/encoder.d.ts

2

cjs/boot/init.js

@@ -9,3 +9,3 @@ "use strict";

var publicApi = (0, polyfills_1.assign)({
version: "5.1.0",
version: "5.2.0",
// This API method is intentionally not monitored, since the only thing executed is the

@@ -12,0 +12,0 @@ // user-provided 'callback'. All SDK usages executed in the callback should be monitored, and

@@ -8,4 +8,10 @@ export interface CookieOptions {

export declare function getCookie(name: string): string | undefined;
/**
* Returns a cached value of the cookie. Use this during SDK initialization (and whenever possible)
* to avoid accessing document.cookie multiple times.
*/
export declare function getInitCookie(name: string): string | undefined;
export declare function resetInitCookies(): void;
export declare function deleteCookie(name: string, options?: CookieOptions): void;
export declare function areCookiesAuthorized(options: CookieOptions): boolean;
export declare function getCurrentSite(): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCurrentSite = exports.areCookiesAuthorized = exports.deleteCookie = exports.getCookie = exports.setCookie = void 0;
exports.getCurrentSite = exports.areCookiesAuthorized = exports.deleteCookie = exports.resetInitCookies = exports.getInitCookie = exports.getCookie = exports.setCookie = void 0;
var display_1 = require("../tools/display");

@@ -21,2 +21,18 @@ var timeUtils_1 = require("../tools/utils/timeUtils");

exports.getCookie = getCookie;
var initCookieParsed;
/**
* Returns a cached value of the cookie. Use this during SDK initialization (and whenever possible)
* to avoid accessing document.cookie multiple times.
*/
function getInitCookie(name) {
if (!initCookieParsed) {
initCookieParsed = (0, stringUtils_1.findCommaSeparatedValues)(document.cookie);
}
return initCookieParsed.get(name);
}
exports.getInitCookie = getInitCookie;
function resetInitCookies() {
initCookieParsed = undefined;
}
exports.resetInitCookies = resetInitCookies;
function deleteCookie(name, options) {

@@ -23,0 +39,0 @@ setCookie(name, '', 0, options);

@@ -27,2 +27,4 @@ "use strict";

if (context) {
// casting should be `RequestInfo` but node types are ahead of DOM types, making `typecheck test/e2e` fail.
// it should be resolved with https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483
responsePromise = originalFetch.call(this, context.input, context.init);

@@ -29,0 +31,0 @@ (0, monitor_1.callMonitored)(afterSend, null, [observable, responsePromise, context]);

@@ -52,3 +52,3 @@ "use strict";

var retry = _b.retry, flushReason = _b.flushReason, encoding = _b.encoding;
var tags = ["sdk_version:".concat("5.1.0"), "api:".concat(api)].concat(configurationTags);
var tags = ["sdk_version:".concat("5.2.0"), "api:".concat(api)].concat(configurationTags);
if (flushReason && (0, experimentalFeatures_1.isExperimentalFeatureEnabled)(experimentalFeatures_1.ExperimentalFeature.COLLECT_FLUSH_REASON)) {

@@ -64,3 +64,3 @@ tags.push("flush_reason:".concat(flushReason));

"dd-api-key=".concat(clientToken),
"dd-evp-origin-version=".concat(encodeURIComponent("5.1.0")),
"dd-evp-origin-version=".concat(encodeURIComponent("5.2.0")),
'dd-evp-origin=browser',

@@ -67,0 +67,0 @@ "dd-request-id=".concat((0, stringUtils_1.generateUUID)()),

@@ -0,1 +1,2 @@

import type { Encoder } from '../../tools/encoder';
export type DeflateWorkerAction = {

@@ -27,1 +28,12 @@ action: 'init';

};
export interface DeflateWorker extends Worker {
postMessage(message: DeflateWorkerAction): void;
}
export type DeflateEncoder = Encoder<Uint8Array> & {
stop: () => void;
};
export declare const enum DeflateEncoderStreamId {
REPLAY = 1,
RUM = 2,
RUM_REPLICA = 3
}

@@ -18,7 +18,7 @@ "use strict";

function tryOldCookiesMigration(cookieStoreStrategy) {
var sessionString = (0, cookie_1.getCookie)(sessionStoreStrategy_1.SESSION_STORE_KEY);
var sessionString = (0, cookie_1.getInitCookie)(sessionStoreStrategy_1.SESSION_STORE_KEY);
if (!sessionString) {
var oldSessionId = (0, cookie_1.getCookie)(exports.OLD_SESSION_COOKIE_NAME);
var oldRumType = (0, cookie_1.getCookie)(exports.OLD_RUM_COOKIE_NAME);
var oldLogsType = (0, cookie_1.getCookie)(exports.OLD_LOGS_COOKIE_NAME);
var oldSessionId = (0, cookie_1.getInitCookie)(exports.OLD_SESSION_COOKIE_NAME);
var oldRumType = (0, cookie_1.getInitCookie)(exports.OLD_RUM_COOKIE_NAME);
var oldLogsType = (0, cookie_1.getInitCookie)(exports.OLD_LOGS_COOKIE_NAME);
var session = {};

@@ -25,0 +25,0 @@ if (oldSessionId) {

@@ -9,7 +9,7 @@ "use strict";

function willSyntheticsInjectRum() {
return Boolean(window._DATADOG_SYNTHETICS_INJECTS_RUM || (0, cookie_1.getCookie)(exports.SYNTHETICS_INJECTS_RUM_COOKIE_NAME));
return Boolean(window._DATADOG_SYNTHETICS_INJECTS_RUM || (0, cookie_1.getInitCookie)(exports.SYNTHETICS_INJECTS_RUM_COOKIE_NAME));
}
exports.willSyntheticsInjectRum = willSyntheticsInjectRum;
function getSyntheticsTestId() {
var value = window._DATADOG_SYNTHETICS_PUBLIC_ID || (0, cookie_1.getCookie)(exports.SYNTHETICS_TEST_ID_COOKIE_NAME);
var value = window._DATADOG_SYNTHETICS_PUBLIC_ID || (0, cookie_1.getInitCookie)(exports.SYNTHETICS_TEST_ID_COOKIE_NAME);
return typeof value === 'string' ? value : undefined;

@@ -19,3 +19,3 @@ }

function getSyntheticsResultId() {
var value = window._DATADOG_SYNTHETICS_RESULT_ID || (0, cookie_1.getCookie)(exports.SYNTHETICS_RESULT_ID_COOKIE_NAME);
var value = window._DATADOG_SYNTHETICS_RESULT_ID || (0, cookie_1.getInitCookie)(exports.SYNTHETICS_RESULT_ID_COOKIE_NAME);
return typeof value === 'string' ? value : undefined;

@@ -22,0 +22,0 @@ }

@@ -54,3 +54,3 @@ "use strict";

service: telemetryService,
version: "5.1.0",
version: "5.2.0",
source: 'browser',

@@ -57,0 +57,0 @@ _dd: {

@@ -14,2 +14,3 @@ export { Configuration, InitConfiguration, validateAndBuildConfiguration, DefaultPrivacyLevel, EndpointBuilder, serializeConfiguration, INTAKE_SITE_STAGING, INTAKE_SITE_US1, INTAKE_SITE_US1_FED, INTAKE_SITE_EU1, } from './domain/configuration';

export * from './tools/display';
export { Encoder, EncoderResult, createIdentityEncoder } from './tools/encoder';
export * from './tools/utils/urlPolyfill';

@@ -16,0 +17,0 @@ export * from './tools/utils/timeUtils';

@@ -17,4 +17,4 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.NO_ERROR_STACK_PRESENT_MESSAGE = exports.getFileFromStackTraceString = exports.toStackTraceString = exports.createHandlingStack = exports.computeRawError = exports.instrumentSetter = exports.instrumentMethodAndCallOriginal = exports.instrumentMethod = exports.getZoneJsOriginalValue = exports.runOnReadyState = exports.sendToExtension = exports.AbstractLifeCycle = exports.createFlushController = exports.startBatchWithReplica = exports.getEventBridge = exports.canUseEventBridge = exports.createHttpRequest = exports.SESSION_TIME_OUT_DELAY = exports.stopSessionManager = exports.startSessionManager = exports.Observable = exports.setDebugMode = exports.callMonitored = exports.monitor = exports.monitored = exports.addTelemetryConfiguration = exports.isTelemetryReplicationAllowed = exports.resetTelemetry = exports.startFakeTelemetry = exports.addTelemetryError = exports.addTelemetryDebug = exports.startTelemetry = exports.RawReportType = exports.initReportObservable = exports.makePublicApi = exports.defineGlobal = exports.computeStackTrace = exports.trackRuntimeError = exports.ExperimentalFeature = exports.getExperimentalFeatures = exports.resetExperimentalFeatures = exports.addExperimentalFeatures = exports.isExperimentalFeatureEnabled = exports.INTAKE_SITE_EU1 = exports.INTAKE_SITE_US1_FED = exports.INTAKE_SITE_US1 = exports.INTAKE_SITE_STAGING = exports.serializeConfiguration = exports.DefaultPrivacyLevel = exports.validateAndBuildConfiguration = void 0;
exports.ErrorSource = exports.sanitizeUser = exports.checkUser = exports.getSyntheticsResultId = exports.getSyntheticsTestId = exports.willSyntheticsInjectRum = exports.SESSION_STORE_KEY = exports.STORAGE_POLL_DELAY = exports.readBytesFromStream = exports.CLEAR_OLD_VALUES_INTERVAL = exports.ValueHistory = exports.CUSTOMER_DATA_BYTES_LIMIT = exports.warnIfCustomerDataLimitReached = exports.removeStorageListeners = exports.createStoredContextManager = exports.createContextManager = exports.catchUserErrors = exports.BoundedBuffer = exports.resetConsoleObservable = exports.initConsoleObservable = exports.isPageExitReason = exports.PageExitReason = exports.createPageExitObservable = exports.initFetchObservable = exports.initXhrObservable = exports.deleteCookie = exports.setCookie = exports.getCookie = exports.areCookiesAuthorized = void 0;
exports.getFileFromStackTraceString = exports.toStackTraceString = exports.createHandlingStack = exports.computeRawError = exports.instrumentSetter = exports.instrumentMethodAndCallOriginal = exports.instrumentMethod = exports.getZoneJsOriginalValue = exports.runOnReadyState = exports.sendToExtension = exports.AbstractLifeCycle = exports.createIdentityEncoder = exports.createFlushController = exports.startBatchWithReplica = exports.getEventBridge = exports.canUseEventBridge = exports.createHttpRequest = exports.SESSION_TIME_OUT_DELAY = exports.stopSessionManager = exports.startSessionManager = exports.Observable = exports.setDebugMode = exports.callMonitored = exports.monitor = exports.monitored = exports.addTelemetryConfiguration = exports.isTelemetryReplicationAllowed = exports.resetTelemetry = exports.startFakeTelemetry = exports.addTelemetryError = exports.addTelemetryDebug = exports.startTelemetry = exports.RawReportType = exports.initReportObservable = exports.makePublicApi = exports.defineGlobal = exports.computeStackTrace = exports.trackRuntimeError = exports.ExperimentalFeature = exports.getExperimentalFeatures = exports.resetExperimentalFeatures = exports.addExperimentalFeatures = exports.isExperimentalFeatureEnabled = exports.INTAKE_SITE_EU1 = exports.INTAKE_SITE_US1_FED = exports.INTAKE_SITE_US1 = exports.INTAKE_SITE_STAGING = exports.serializeConfiguration = exports.DefaultPrivacyLevel = exports.validateAndBuildConfiguration = void 0;
exports.ErrorSource = exports.sanitizeUser = exports.checkUser = exports.getSyntheticsResultId = exports.getSyntheticsTestId = exports.willSyntheticsInjectRum = exports.SESSION_STORE_KEY = exports.STORAGE_POLL_DELAY = exports.readBytesFromStream = exports.CLEAR_OLD_VALUES_INTERVAL = exports.ValueHistory = exports.CUSTOMER_DATA_BYTES_LIMIT = exports.warnIfCustomerDataLimitReached = exports.removeStorageListeners = exports.createStoredContextManager = exports.createContextManager = exports.catchUserErrors = exports.BoundedBuffer = exports.resetConsoleObservable = exports.initConsoleObservable = exports.isPageExitReason = exports.PageExitReason = exports.createPageExitObservable = exports.initFetchObservable = exports.initXhrObservable = exports.deleteCookie = exports.setCookie = exports.getCookie = exports.areCookiesAuthorized = exports.NO_ERROR_STACK_PRESENT_MESSAGE = void 0;
var configuration_1 = require("./domain/configuration");

@@ -72,2 +72,4 @@ Object.defineProperty(exports, "validateAndBuildConfiguration", { enumerable: true, get: function () { return configuration_1.validateAndBuildConfiguration; } });

__exportStar(require("./tools/display"), exports);
var encoder_1 = require("./tools/encoder");
Object.defineProperty(exports, "createIdentityEncoder", { enumerable: true, get: function () { return encoder_1.createIdentityEncoder; } });
__exportStar(require("./tools/utils/urlPolyfill"), exports);

@@ -74,0 +76,0 @@ __exportStar(require("./tools/utils/timeUtils"), exports);

@@ -17,3 +17,4 @@ /**

WEB_VITALS_ATTRIBUTION = "web_vitals_attribution",
DISABLE_REPLAY_INLINE_CSS = "disable_replay_inline_css"
DISABLE_REPLAY_INLINE_CSS = "disable_replay_inline_css",
COMPRESS_BATCH = "compress_batch"
}

@@ -20,0 +21,0 @@ export declare function addExperimentalFeatures(enabledFeatures: ExperimentalFeature[]): void;

@@ -25,2 +25,3 @@ "use strict";

ExperimentalFeature["DISABLE_REPLAY_INLINE_CSS"] = "disable_replay_inline_css";
ExperimentalFeature["COMPRESS_BATCH"] = "compress_batch";
})(ExperimentalFeature || (exports.ExperimentalFeature = ExperimentalFeature = {}));

@@ -27,0 +28,0 @@ var enabledExperimentalFeatures = new Set();

@@ -0,3 +1,10 @@

export declare const enum Browser {
IE = 0,
CHROMIUM = 1,
SAFARI = 2,
OTHER = 3
}
export declare function isIE(): boolean;
export declare function isChromium(): boolean;
export declare function isSafari(): boolean;
export declare function detectBrowser(browserWindow?: Window): Browser;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isSafari = exports.isChromium = exports.isIE = void 0;
var browserIsIE;
exports.detectBrowser = exports.isSafari = exports.isChromium = exports.isIE = void 0;
function isIE() {
return browserIsIE !== null && browserIsIE !== void 0 ? browserIsIE : (browserIsIE = Boolean(document.documentMode));
return detectBrowserCached() === 0 /* Browser.IE */;
}
exports.isIE = isIE;
var browserIsChromium;
function isChromium() {
return (browserIsChromium !== null && browserIsChromium !== void 0 ? browserIsChromium : (browserIsChromium = !!window.chrome || /HeadlessChrome/.test(window.navigator.userAgent)));
return detectBrowserCached() === 1 /* Browser.CHROMIUM */;
}
exports.isChromium = isChromium;
var browserIsSafari;
function isSafari() {
return browserIsSafari !== null && browserIsSafari !== void 0 ? browserIsSafari : (browserIsSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent));
return detectBrowserCached() === 2 /* Browser.SAFARI */;
}
exports.isSafari = isSafari;
var browserCache;
function detectBrowserCached() {
return browserCache !== null && browserCache !== void 0 ? browserCache : (browserCache = detectBrowser());
}
// Exported only for tests
function detectBrowser(browserWindow) {
var _a;
if (browserWindow === void 0) { browserWindow = window; }
var userAgent = browserWindow.navigator.userAgent;
if (browserWindow.chrome || /HeadlessChrome/.test(userAgent)) {
return 1 /* Browser.CHROMIUM */;
}
if (
// navigator.vendor is deprecated, but it is the most resilient way we found to detect
// "Apple maintained browsers" (AKA Safari). If one day it gets removed, we still have the
// useragent test as a semi-working fallback.
((_a = browserWindow.navigator.vendor) === null || _a === void 0 ? void 0 : _a.indexOf('Apple')) === 0 ||
(/safari/i.test(userAgent) && !/chrome|android/i.test(userAgent))) {
return 2 /* Browser.SAFARI */;
}
if (browserWindow.document.documentMode) {
return 0 /* Browser.IE */;
}
return 3 /* Browser.OTHER */;
}
exports.detectBrowser = detectBrowser;
//# sourceMappingURL=browserDetection.js.map

@@ -7,2 +7,3 @@ /**

export declare function findCommaSeparatedValue(rawString: string, name: string): string | undefined;
export declare function findCommaSeparatedValues(rawString: string): Map<string, string>;
export declare function safeTruncate(candidate: string, length: number, suffix?: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeTruncate = exports.findCommaSeparatedValue = exports.generateUUID = void 0;
exports.safeTruncate = exports.findCommaSeparatedValues = exports.findCommaSeparatedValue = exports.generateUUID = void 0;
/**

@@ -15,8 +15,35 @@ * UUID v4

exports.generateUUID = generateUUID;
var COMMA_SEPARATED_KEY_VALUE = /([\w-]+)\s*=\s*([^;]+)/g;
function findCommaSeparatedValue(rawString, name) {
var regex = new RegExp("(?:^|;)\\s*".concat(name, "\\s*=\\s*([^;]+)"));
var matches = regex.exec(rawString);
return matches ? matches[1] : undefined;
COMMA_SEPARATED_KEY_VALUE.lastIndex = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
var match = COMMA_SEPARATED_KEY_VALUE.exec(rawString);
if (match) {
if (match[1] === name) {
return match[2];
}
}
else {
break;
}
}
}
exports.findCommaSeparatedValue = findCommaSeparatedValue;
function findCommaSeparatedValues(rawString) {
var result = new Map();
COMMA_SEPARATED_KEY_VALUE.lastIndex = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
var match = COMMA_SEPARATED_KEY_VALUE.exec(rawString);
if (match) {
result.set(match[1], match[2]);
}
else {
break;
}
}
return result;
}
exports.findCommaSeparatedValues = findCommaSeparatedValues;
function safeTruncate(candidate, length, suffix) {

@@ -23,0 +50,0 @@ if (suffix === void 0) { suffix = ''; }

import type { Context } from '../tools/serialisation/context';
import type { Encoder } from '../tools/encoder';
import type { HttpRequest } from './httpRequest';
import type { FlushController } from './flushController';
export declare class Batch {
private encoder;
private request;
flushController: FlushController;
private messageBytesLimit;
private pushOnlyBuffer;
private upsertBuffer;
private flushSubscription;
constructor(request: HttpRequest, flushController: FlushController, messageBytesLimit: number);
constructor(encoder: Encoder, request: HttpRequest, flushController: FlushController, messageBytesLimit: number);
add(message: Context): void;

@@ -17,3 +18,2 @@ upsert(message: Context, key: string): void;

private addOrUpdate;
private process;
private push;

@@ -20,0 +20,0 @@ private remove;

@@ -7,11 +7,11 @@ "use strict";

var pageExitObservable_1 = require("../browser/pageExitObservable");
var jsonStringify_1 = require("../tools/serialisation/jsonStringify");
var byteUtils_1 = require("../tools/utils/byteUtils");
var jsonStringify_1 = require("../tools/serialisation/jsonStringify");
var Batch = /** @class */ (function () {
function Batch(request, flushController, messageBytesLimit) {
function Batch(encoder, request, flushController, messageBytesLimit) {
var _this = this;
this.encoder = encoder;
this.request = request;
this.flushController = flushController;
this.messageBytesLimit = messageBytesLimit;
this.pushOnlyBuffer = [];
this.upsertBuffer = {};

@@ -30,16 +30,40 @@ this.flushSubscription = this.flushController.flushObservable.subscribe(function (event) { return _this.flush(event); });

Batch.prototype.flush = function (event) {
var messages = this.pushOnlyBuffer.concat((0, polyfills_1.objectValues)(this.upsertBuffer));
this.pushOnlyBuffer = [];
var upsertMessages = (0, polyfills_1.objectValues)(this.upsertBuffer).join('\n');
this.upsertBuffer = {};
var payload = { data: messages.join('\n'), bytesCount: event.bytesCount, flushReason: event.reason };
if ((0, pageExitObservable_1.isPageExitReason)(event.reason)) {
this.request.sendOnExit(payload);
var isPageExit = (0, pageExitObservable_1.isPageExitReason)(event.reason);
var send = isPageExit ? this.request.sendOnExit : this.request.send;
if (isPageExit &&
// Note: checking that the encoder is async is not strictly needed, but it's an optimization:
// if the encoder is async we need to send two requests in some cases (one for encoded data
// and the other for non-encoded data). But if it's not async, we don't have to worry about
// it and always send a single request.
this.encoder.isAsync) {
var encoderResult = this.encoder.finishSync();
// Send encoded messages
if (encoderResult.outputBytesCount) {
send(formatPayloadFromEncoder(encoderResult, event));
}
// Send messages that are not yet encoded at this point
var pendingMessages = [encoderResult.pendingData, upsertMessages].filter(Boolean).join('\n');
if (pendingMessages) {
send({
data: pendingMessages,
bytesCount: (0, byteUtils_1.computeBytesCount)(pendingMessages),
flushReason: event.reason,
});
}
}
else {
this.request.send(payload);
if (upsertMessages) {
this.encoder.write(this.encoder.isEmpty ? upsertMessages : "\n".concat(upsertMessages));
}
this.encoder.finish(function (encoderResult) {
send(formatPayloadFromEncoder(encoderResult, event));
});
}
};
Batch.prototype.addOrUpdate = function (message, key) {
var _a = this.process(message), processedMessage = _a.processedMessage, messageBytesCount = _a.messageBytesCount;
if (messageBytesCount >= this.messageBytesLimit) {
var serializedMessage = (0, jsonStringify_1.jsonStringify)(message);
var estimatedMessageBytesCount = this.encoder.estimateEncodedBytesCount(serializedMessage);
if (estimatedMessageBytesCount >= this.messageBytesLimit) {
display_1.display.warn("Discarded a message whose size was bigger than the maximum allowed size ".concat(this.messageBytesLimit, "KB."));

@@ -51,20 +75,16 @@ return;

}
this.push(processedMessage, messageBytesCount, key);
this.push(serializedMessage, estimatedMessageBytesCount, key);
};
Batch.prototype.process = function (message) {
var processedMessage = (0, jsonStringify_1.jsonStringify)(message);
var messageBytesCount = (0, byteUtils_1.computeBytesCount)(processedMessage);
return { processedMessage: processedMessage, messageBytesCount: messageBytesCount };
};
Batch.prototype.push = function (processedMessage, messageBytesCount, key) {
// If there are other messages, a '\n' will be added at serialization
var separatorBytesCount = this.flushController.messagesCount > 0 ? 1 : 0;
this.flushController.notifyBeforeAddMessage(messageBytesCount + separatorBytesCount);
Batch.prototype.push = function (serializedMessage, estimatedMessageBytesCount, key) {
var _this = this;
this.flushController.notifyBeforeAddMessage(estimatedMessageBytesCount);
if (key !== undefined) {
this.upsertBuffer[key] = processedMessage;
this.upsertBuffer[key] = serializedMessage;
this.flushController.notifyAfterAddMessage();
}
else {
this.pushOnlyBuffer.push(processedMessage);
this.encoder.write(this.encoder.isEmpty ? serializedMessage : "\n".concat(serializedMessage), function (realMessageBytesCount) {
_this.flushController.notifyAfterAddMessage(realMessageBytesCount - estimatedMessageBytesCount);
});
}
this.flushController.notifyAfterAddMessage();
};

@@ -74,6 +94,4 @@ Batch.prototype.remove = function (key) {

delete this.upsertBuffer[key];
var messageBytesCount = (0, byteUtils_1.computeBytesCount)(removedMessage);
// If there are other messages, a '\n' will be added at serialization
var separatorBytesCount = this.flushController.messagesCount > 1 ? 1 : 0;
this.flushController.notifyAfterRemoveMessage(messageBytesCount + separatorBytesCount);
var messageBytesCount = this.encoder.estimateEncodedBytesCount(removedMessage);
this.flushController.notifyAfterRemoveMessage(messageBytesCount);
};

@@ -86,2 +104,25 @@ Batch.prototype.hasMessageFor = function (key) {

exports.Batch = Batch;
function formatPayloadFromEncoder(encoderResult, flushEvent) {
var data;
if (typeof encoderResult.output === 'string') {
data = encoderResult.output;
}
else {
data = new Blob([encoderResult.output], {
// This will set the 'Content-Type: text/plain' header. Reasoning:
// * The intake rejects the request if there is no content type.
// * The browser will issue CORS preflight requests if we set it to 'application/json', which
// could induce higher intake load (and maybe has other impacts).
// * Also it's not quite JSON, since we are concatenating multiple JSON objects separated by
// new lines.
type: 'text/plain',
});
}
return {
data: data,
bytesCount: encoderResult.outputBytesCount,
encoding: encoderResult.encoding,
flushReason: flushEvent.reason,
};
}
//# sourceMappingURL=batch.js.map

@@ -31,4 +31,7 @@ import type { PageExitEvent, PageExitReason } from '../browser/pageExitObservable';

* event can happen after `notifyBeforeAddMessage` and before adding the message.
*
* @param estimatedMessageBytesCount: an estimation of the message bytes count once it is
* actually added.
*/
notifyBeforeAddMessage(messageBytesCount: number): void;
notifyBeforeAddMessage(estimatedMessageBytesCount: number): void;
/**

@@ -39,4 +42,7 @@ * Notifies that a message *was* added to a pool of pending messages waiting to be flushed.

* should not be called if a flush event occurred in between.
*
* @param messageBytesCountDiff: the difference between the estimated message bytes count and
* its actual bytes count once added to the pool.
*/
notifyAfterAddMessage(): void;
notifyAfterAddMessage(messageBytesCountDiff?: number): void;
/**

@@ -47,2 +53,6 @@ * Notifies that a message was removed from a pool of pending messages waiting to be flushed.

* event can happen after removing the message and before `notifyAfterRemoveMessage`.
*
* @param messageBytesCount: the message bytes count that was added to the pool. Should
* correspond to the sum of bytes counts passed to `notifyBeforeAddMessage` and
* `notifyAfterAddMessage`.
*/

@@ -49,0 +59,0 @@ notifyAfterRemoveMessage(messageBytesCount: number): void;

@@ -58,5 +58,8 @@ "use strict";

* event can happen after `notifyBeforeAddMessage` and before adding the message.
*
* @param estimatedMessageBytesCount: an estimation of the message bytes count once it is
* actually added.
*/
notifyBeforeAddMessage: function (messageBytesCount) {
if (currentBytesCount + messageBytesCount >= bytesLimit) {
notifyBeforeAddMessage: function (estimatedMessageBytesCount) {
if (currentBytesCount + estimatedMessageBytesCount >= bytesLimit) {
flush('bytes_limit');

@@ -68,3 +71,3 @@ }

currentMessagesCount += 1;
currentBytesCount += messageBytesCount;
currentBytesCount += estimatedMessageBytesCount;
scheduleDurationLimitTimeout();

@@ -77,4 +80,9 @@ },

* should not be called if a flush event occurred in between.
*
* @param messageBytesCountDiff: the difference between the estimated message bytes count and
* its actual bytes count once added to the pool.
*/
notifyAfterAddMessage: function () {
notifyAfterAddMessage: function (messageBytesCountDiff) {
if (messageBytesCountDiff === void 0) { messageBytesCountDiff = 0; }
currentBytesCount += messageBytesCountDiff;
if (currentMessagesCount >= messagesLimit) {

@@ -92,2 +100,6 @@ flush('messages_limit');

* event can happen after removing the message and before `notifyAfterRemoveMessage`.
*
* @param messageBytesCount: the message bytes count that was added to the pool. Should
* correspond to the sum of bytes counts passed to `notifyBeforeAddMessage` and
* `notifyAfterAddMessage`.
*/

@@ -94,0 +106,0 @@ notifyAfterRemoveMessage: function (messageBytesCount) {

@@ -19,3 +19,3 @@ import type { EndpointBuilder, Configuration } from '../domain/configuration';

export interface Payload {
data: string | FormData;
data: string | FormData | Blob;
bytesCount: number;

@@ -22,0 +22,0 @@ retry?: RetryInfo;

@@ -79,2 +79,8 @@ "use strict";

request.open('POST', url, true);
if (data instanceof Blob) {
// When using a Blob instance, IE does not use its 'type' to define the 'Content-Type' header
// automatically, so the intake request ends up being rejected with an HTTP status 415
// Defining the header manually fixes this issue.
request.setRequestHeader('Content-Type', data.type);
}
(0, addEventListener_1.addEventListener)(configuration, request, 'loadend', function () {

@@ -81,0 +87,0 @@ onResponse === null || onResponse === void 0 ? void 0 : onResponse({ status: request.status });

@@ -6,8 +6,11 @@ import type { Configuration, EndpointBuilder } from '../domain/configuration';

import type { RawError } from '../domain/error/error.types';
export declare function startBatchWithReplica<T extends Context>(configuration: Configuration, primary: {
import type { Encoder } from '../tools/encoder';
export interface BatchConfiguration {
endpoint: EndpointBuilder;
}, replica: {
endpoint: EndpointBuilder;
encoder: Encoder;
}
interface ReplicaBatchConfiguration<T> extends BatchConfiguration {
transformMessage?: (message: T) => T;
} | undefined, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>): {
}
export declare function startBatchWithReplica<T extends Context>(configuration: Configuration, primary: BatchConfiguration, replica: ReplicaBatchConfiguration<T> | undefined, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>): {
flushObservable: Observable<import("./flushController").FlushEvent>;

@@ -18,1 +21,2 @@ add(message: T, replicated?: boolean): void;

};
export {};

@@ -8,6 +8,7 @@ "use strict";

function startBatchWithReplica(configuration, primary, replica, reportError, pageExitObservable, sessionExpireObservable) {
var primaryBatch = createBatch(configuration, primary.endpoint);
var replicaBatch = replica && createBatch(configuration, replica.endpoint);
function createBatch(configuration, endpointBuilder) {
return new batch_1.Batch((0, httpRequest_1.createHttpRequest)(configuration, endpointBuilder, configuration.batchBytesLimit, reportError), (0, flushController_1.createFlushController)({
var primaryBatch = createBatch(configuration, primary);
var replicaBatch = replica && createBatch(configuration, replica);
function createBatch(configuration, _a) {
var endpoint = _a.endpoint, encoder = _a.encoder;
return new batch_1.Batch(encoder, (0, httpRequest_1.createHttpRequest)(configuration, endpoint, configuration.batchBytesLimit, reportError), (0, flushController_1.createFlushController)({
messagesLimit: configuration.batchMessagesLimit,

@@ -14,0 +15,0 @@ bytesLimit: configuration.batchBytesLimit,

@@ -6,3 +6,3 @@ import { catchUserErrors } from '../tools/catchUserErrors';

var publicApi = assign({
version: "5.1.0",
version: "5.2.0",
// This API method is intentionally not monitored, since the only thing executed is the

@@ -9,0 +9,0 @@ // user-provided 'callback'. All SDK usages executed in the callback should be monitored, and

@@ -8,4 +8,10 @@ export interface CookieOptions {

export declare function getCookie(name: string): string | undefined;
/**
* Returns a cached value of the cookie. Use this during SDK initialization (and whenever possible)
* to avoid accessing document.cookie multiple times.
*/
export declare function getInitCookie(name: string): string | undefined;
export declare function resetInitCookies(): void;
export declare function deleteCookie(name: string, options?: CookieOptions): void;
export declare function areCookiesAuthorized(options: CookieOptions): boolean;
export declare function getCurrentSite(): string;
import { display } from '../tools/display';
import { ONE_MINUTE, ONE_SECOND } from '../tools/utils/timeUtils';
import { findCommaSeparatedValue, generateUUID } from '../tools/utils/stringUtils';
import { findCommaSeparatedValue, findCommaSeparatedValues, generateUUID } from '../tools/utils/stringUtils';
export function setCookie(name, value, expireDelay, options) {

@@ -16,2 +16,16 @@ var date = new Date();

}
var initCookieParsed;
/**
* Returns a cached value of the cookie. Use this during SDK initialization (and whenever possible)
* to avoid accessing document.cookie multiple times.
*/
export function getInitCookie(name) {
if (!initCookieParsed) {
initCookieParsed = findCommaSeparatedValues(document.cookie);
}
return initCookieParsed.get(name);
}
export function resetInitCookies() {
initCookieParsed = undefined;
}
export function deleteCookie(name, options) {

@@ -18,0 +32,0 @@ setCookie(name, '', 0, options);

@@ -23,2 +23,4 @@ import { instrumentMethod } from '../tools/instrumentMethod';

if (context) {
// casting should be `RequestInfo` but node types are ahead of DOM types, making `typecheck test/e2e` fail.
// it should be resolved with https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483
responsePromise = originalFetch.call(this, context.input, context.init);

@@ -25,0 +27,0 @@ callMonitored(afterSend, null, [observable, responsePromise, context]);

@@ -48,3 +48,3 @@ import { timeStampNow } from '../../tools/utils/timeUtils';

var retry = _b.retry, flushReason = _b.flushReason, encoding = _b.encoding;
var tags = ["sdk_version:".concat("5.1.0"), "api:".concat(api)].concat(configurationTags);
var tags = ["sdk_version:".concat("5.2.0"), "api:".concat(api)].concat(configurationTags);
if (flushReason && isExperimentalFeatureEnabled(ExperimentalFeature.COLLECT_FLUSH_REASON)) {

@@ -60,3 +60,3 @@ tags.push("flush_reason:".concat(flushReason));

"dd-api-key=".concat(clientToken),
"dd-evp-origin-version=".concat(encodeURIComponent("5.1.0")),
"dd-evp-origin-version=".concat(encodeURIComponent("5.2.0")),
'dd-evp-origin=browser',

@@ -63,0 +63,0 @@ "dd-request-id=".concat(generateUUID()),

@@ -0,1 +1,2 @@

import type { Encoder } from '../../tools/encoder';
export type DeflateWorkerAction = {

@@ -27,1 +28,12 @@ action: 'init';

};
export interface DeflateWorker extends Worker {
postMessage(message: DeflateWorkerAction): void;
}
export type DeflateEncoder = Encoder<Uint8Array> & {
stop: () => void;
};
export declare const enum DeflateEncoderStreamId {
REPLAY = 1,
RUM = 2,
RUM_REPLICA = 3
}

@@ -1,2 +0,2 @@

import { getCookie } from '../../browser/cookie';
import { getInitCookie } from '../../browser/cookie';
import { SESSION_STORE_KEY } from './storeStrategies/sessionStoreStrategy';

@@ -15,7 +15,7 @@ import { expandSessionState, isSessionInExpiredState } from './sessionState';

export function tryOldCookiesMigration(cookieStoreStrategy) {
var sessionString = getCookie(SESSION_STORE_KEY);
var sessionString = getInitCookie(SESSION_STORE_KEY);
if (!sessionString) {
var oldSessionId = getCookie(OLD_SESSION_COOKIE_NAME);
var oldRumType = getCookie(OLD_RUM_COOKIE_NAME);
var oldLogsType = getCookie(OLD_LOGS_COOKIE_NAME);
var oldSessionId = getInitCookie(OLD_SESSION_COOKIE_NAME);
var oldRumType = getInitCookie(OLD_RUM_COOKIE_NAME);
var oldLogsType = getInitCookie(OLD_LOGS_COOKIE_NAME);
var session = {};

@@ -22,0 +22,0 @@ if (oldSessionId) {

@@ -1,2 +0,2 @@

import { getCookie } from '../../browser/cookie';
import { getInitCookie } from '../../browser/cookie';
export var SYNTHETICS_TEST_ID_COOKIE_NAME = 'datadog-synthetics-public-id';

@@ -6,12 +6,12 @@ export var SYNTHETICS_RESULT_ID_COOKIE_NAME = 'datadog-synthetics-result-id';

export function willSyntheticsInjectRum() {
return Boolean(window._DATADOG_SYNTHETICS_INJECTS_RUM || getCookie(SYNTHETICS_INJECTS_RUM_COOKIE_NAME));
return Boolean(window._DATADOG_SYNTHETICS_INJECTS_RUM || getInitCookie(SYNTHETICS_INJECTS_RUM_COOKIE_NAME));
}
export function getSyntheticsTestId() {
var value = window._DATADOG_SYNTHETICS_PUBLIC_ID || getCookie(SYNTHETICS_TEST_ID_COOKIE_NAME);
var value = window._DATADOG_SYNTHETICS_PUBLIC_ID || getInitCookie(SYNTHETICS_TEST_ID_COOKIE_NAME);
return typeof value === 'string' ? value : undefined;
}
export function getSyntheticsResultId() {
var value = window._DATADOG_SYNTHETICS_RESULT_ID || getCookie(SYNTHETICS_RESULT_ID_COOKIE_NAME);
var value = window._DATADOG_SYNTHETICS_RESULT_ID || getInitCookie(SYNTHETICS_RESULT_ID_COOKIE_NAME);
return typeof value === 'string' ? value : undefined;
}
//# sourceMappingURL=syntheticsWorkerValues.js.map

@@ -51,3 +51,3 @@ import { ConsoleApiName } from '../../tools/display';

service: telemetryService,
version: "5.1.0",
version: "5.2.0",
source: 'browser',

@@ -54,0 +54,0 @@ _dd: {

@@ -14,2 +14,3 @@ export { Configuration, InitConfiguration, validateAndBuildConfiguration, DefaultPrivacyLevel, EndpointBuilder, serializeConfiguration, INTAKE_SITE_STAGING, INTAKE_SITE_US1, INTAKE_SITE_US1_FED, INTAKE_SITE_EU1, } from './domain/configuration';

export * from './tools/display';
export { Encoder, EncoderResult, createIdentityEncoder } from './tools/encoder';
export * from './tools/utils/urlPolyfill';

@@ -16,0 +17,0 @@ export * from './tools/utils/timeUtils';

@@ -17,2 +17,3 @@ export { validateAndBuildConfiguration, DefaultPrivacyLevel, serializeConfiguration, INTAKE_SITE_STAGING, INTAKE_SITE_US1, INTAKE_SITE_US1_FED, INTAKE_SITE_EU1, } from './domain/configuration';

export * from './tools/display';
export { createIdentityEncoder } from './tools/encoder';
export * from './tools/utils/urlPolyfill';

@@ -19,0 +20,0 @@ export * from './tools/utils/timeUtils';

@@ -17,3 +17,4 @@ /**

WEB_VITALS_ATTRIBUTION = "web_vitals_attribution",
DISABLE_REPLAY_INLINE_CSS = "disable_replay_inline_css"
DISABLE_REPLAY_INLINE_CSS = "disable_replay_inline_css",
COMPRESS_BATCH = "compress_batch"
}

@@ -20,0 +21,0 @@ export declare function addExperimentalFeatures(enabledFeatures: ExperimentalFeature[]): void;

@@ -22,2 +22,3 @@ /**

ExperimentalFeature["DISABLE_REPLAY_INLINE_CSS"] = "disable_replay_inline_css";
ExperimentalFeature["COMPRESS_BATCH"] = "compress_batch";
})(ExperimentalFeature || (ExperimentalFeature = {}));

@@ -24,0 +25,0 @@ var enabledExperimentalFeatures = new Set();

@@ -0,3 +1,10 @@

export declare const enum Browser {
IE = 0,
CHROMIUM = 1,
SAFARI = 2,
OTHER = 3
}
export declare function isIE(): boolean;
export declare function isChromium(): boolean;
export declare function isSafari(): boolean;
export declare function detectBrowser(browserWindow?: Window): Browser;

@@ -1,13 +0,35 @@

var browserIsIE;
export function isIE() {
return browserIsIE !== null && browserIsIE !== void 0 ? browserIsIE : (browserIsIE = Boolean(document.documentMode));
return detectBrowserCached() === 0 /* Browser.IE */;
}
var browserIsChromium;
export function isChromium() {
return (browserIsChromium !== null && browserIsChromium !== void 0 ? browserIsChromium : (browserIsChromium = !!window.chrome || /HeadlessChrome/.test(window.navigator.userAgent)));
return detectBrowserCached() === 1 /* Browser.CHROMIUM */;
}
var browserIsSafari;
export function isSafari() {
return browserIsSafari !== null && browserIsSafari !== void 0 ? browserIsSafari : (browserIsSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent));
return detectBrowserCached() === 2 /* Browser.SAFARI */;
}
var browserCache;
function detectBrowserCached() {
return browserCache !== null && browserCache !== void 0 ? browserCache : (browserCache = detectBrowser());
}
// Exported only for tests
export function detectBrowser(browserWindow) {
var _a;
if (browserWindow === void 0) { browserWindow = window; }
var userAgent = browserWindow.navigator.userAgent;
if (browserWindow.chrome || /HeadlessChrome/.test(userAgent)) {
return 1 /* Browser.CHROMIUM */;
}
if (
// navigator.vendor is deprecated, but it is the most resilient way we found to detect
// "Apple maintained browsers" (AKA Safari). If one day it gets removed, we still have the
// useragent test as a semi-working fallback.
((_a = browserWindow.navigator.vendor) === null || _a === void 0 ? void 0 : _a.indexOf('Apple')) === 0 ||
(/safari/i.test(userAgent) && !/chrome|android/i.test(userAgent))) {
return 2 /* Browser.SAFARI */;
}
if (browserWindow.document.documentMode) {
return 0 /* Browser.IE */;
}
return 3 /* Browser.OTHER */;
}
//# sourceMappingURL=browserDetection.js.map

@@ -7,2 +7,3 @@ /**

export declare function findCommaSeparatedValue(rawString: string, name: string): string | undefined;
export declare function findCommaSeparatedValues(rawString: string): Map<string, string>;
export declare function safeTruncate(candidate: string, length: number, suffix?: string): string;

@@ -11,7 +11,33 @@ /**

}
var COMMA_SEPARATED_KEY_VALUE = /([\w-]+)\s*=\s*([^;]+)/g;
export function findCommaSeparatedValue(rawString, name) {
var regex = new RegExp("(?:^|;)\\s*".concat(name, "\\s*=\\s*([^;]+)"));
var matches = regex.exec(rawString);
return matches ? matches[1] : undefined;
COMMA_SEPARATED_KEY_VALUE.lastIndex = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
var match = COMMA_SEPARATED_KEY_VALUE.exec(rawString);
if (match) {
if (match[1] === name) {
return match[2];
}
}
else {
break;
}
}
}
export function findCommaSeparatedValues(rawString) {
var result = new Map();
COMMA_SEPARATED_KEY_VALUE.lastIndex = 0;
// eslint-disable-next-line no-constant-condition
while (true) {
var match = COMMA_SEPARATED_KEY_VALUE.exec(rawString);
if (match) {
result.set(match[1], match[2]);
}
else {
break;
}
}
return result;
}
export function safeTruncate(candidate, length, suffix) {

@@ -18,0 +44,0 @@ if (suffix === void 0) { suffix = ''; }

import type { Context } from '../tools/serialisation/context';
import type { Encoder } from '../tools/encoder';
import type { HttpRequest } from './httpRequest';
import type { FlushController } from './flushController';
export declare class Batch {
private encoder;
private request;
flushController: FlushController;
private messageBytesLimit;
private pushOnlyBuffer;
private upsertBuffer;
private flushSubscription;
constructor(request: HttpRequest, flushController: FlushController, messageBytesLimit: number);
constructor(encoder: Encoder, request: HttpRequest, flushController: FlushController, messageBytesLimit: number);
add(message: Context): void;

@@ -17,3 +18,2 @@ upsert(message: Context, key: string): void;

private addOrUpdate;
private process;
private push;

@@ -20,0 +20,0 @@ private remove;

import { display } from '../tools/display';
import { objectValues } from '../tools/utils/polyfills';
import { isPageExitReason } from '../browser/pageExitObservable';
import { jsonStringify } from '../tools/serialisation/jsonStringify';
import { computeBytesCount } from '../tools/utils/byteUtils';
import { jsonStringify } from '../tools/serialisation/jsonStringify';
var Batch = /** @class */ (function () {
function Batch(request, flushController, messageBytesLimit) {
function Batch(encoder, request, flushController, messageBytesLimit) {
var _this = this;
this.encoder = encoder;
this.request = request;
this.flushController = flushController;
this.messageBytesLimit = messageBytesLimit;
this.pushOnlyBuffer = [];
this.upsertBuffer = {};

@@ -26,16 +26,40 @@ this.flushSubscription = this.flushController.flushObservable.subscribe(function (event) { return _this.flush(event); });

Batch.prototype.flush = function (event) {
var messages = this.pushOnlyBuffer.concat(objectValues(this.upsertBuffer));
this.pushOnlyBuffer = [];
var upsertMessages = objectValues(this.upsertBuffer).join('\n');
this.upsertBuffer = {};
var payload = { data: messages.join('\n'), bytesCount: event.bytesCount, flushReason: event.reason };
if (isPageExitReason(event.reason)) {
this.request.sendOnExit(payload);
var isPageExit = isPageExitReason(event.reason);
var send = isPageExit ? this.request.sendOnExit : this.request.send;
if (isPageExit &&
// Note: checking that the encoder is async is not strictly needed, but it's an optimization:
// if the encoder is async we need to send two requests in some cases (one for encoded data
// and the other for non-encoded data). But if it's not async, we don't have to worry about
// it and always send a single request.
this.encoder.isAsync) {
var encoderResult = this.encoder.finishSync();
// Send encoded messages
if (encoderResult.outputBytesCount) {
send(formatPayloadFromEncoder(encoderResult, event));
}
// Send messages that are not yet encoded at this point
var pendingMessages = [encoderResult.pendingData, upsertMessages].filter(Boolean).join('\n');
if (pendingMessages) {
send({
data: pendingMessages,
bytesCount: computeBytesCount(pendingMessages),
flushReason: event.reason,
});
}
}
else {
this.request.send(payload);
if (upsertMessages) {
this.encoder.write(this.encoder.isEmpty ? upsertMessages : "\n".concat(upsertMessages));
}
this.encoder.finish(function (encoderResult) {
send(formatPayloadFromEncoder(encoderResult, event));
});
}
};
Batch.prototype.addOrUpdate = function (message, key) {
var _a = this.process(message), processedMessage = _a.processedMessage, messageBytesCount = _a.messageBytesCount;
if (messageBytesCount >= this.messageBytesLimit) {
var serializedMessage = jsonStringify(message);
var estimatedMessageBytesCount = this.encoder.estimateEncodedBytesCount(serializedMessage);
if (estimatedMessageBytesCount >= this.messageBytesLimit) {
display.warn("Discarded a message whose size was bigger than the maximum allowed size ".concat(this.messageBytesLimit, "KB."));

@@ -47,20 +71,16 @@ return;

}
this.push(processedMessage, messageBytesCount, key);
this.push(serializedMessage, estimatedMessageBytesCount, key);
};
Batch.prototype.process = function (message) {
var processedMessage = jsonStringify(message);
var messageBytesCount = computeBytesCount(processedMessage);
return { processedMessage: processedMessage, messageBytesCount: messageBytesCount };
};
Batch.prototype.push = function (processedMessage, messageBytesCount, key) {
// If there are other messages, a '\n' will be added at serialization
var separatorBytesCount = this.flushController.messagesCount > 0 ? 1 : 0;
this.flushController.notifyBeforeAddMessage(messageBytesCount + separatorBytesCount);
Batch.prototype.push = function (serializedMessage, estimatedMessageBytesCount, key) {
var _this = this;
this.flushController.notifyBeforeAddMessage(estimatedMessageBytesCount);
if (key !== undefined) {
this.upsertBuffer[key] = processedMessage;
this.upsertBuffer[key] = serializedMessage;
this.flushController.notifyAfterAddMessage();
}
else {
this.pushOnlyBuffer.push(processedMessage);
this.encoder.write(this.encoder.isEmpty ? serializedMessage : "\n".concat(serializedMessage), function (realMessageBytesCount) {
_this.flushController.notifyAfterAddMessage(realMessageBytesCount - estimatedMessageBytesCount);
});
}
this.flushController.notifyAfterAddMessage();
};

@@ -70,6 +90,4 @@ Batch.prototype.remove = function (key) {

delete this.upsertBuffer[key];
var messageBytesCount = computeBytesCount(removedMessage);
// If there are other messages, a '\n' will be added at serialization
var separatorBytesCount = this.flushController.messagesCount > 1 ? 1 : 0;
this.flushController.notifyAfterRemoveMessage(messageBytesCount + separatorBytesCount);
var messageBytesCount = this.encoder.estimateEncodedBytesCount(removedMessage);
this.flushController.notifyAfterRemoveMessage(messageBytesCount);
};

@@ -82,2 +100,25 @@ Batch.prototype.hasMessageFor = function (key) {

export { Batch };
function formatPayloadFromEncoder(encoderResult, flushEvent) {
var data;
if (typeof encoderResult.output === 'string') {
data = encoderResult.output;
}
else {
data = new Blob([encoderResult.output], {
// This will set the 'Content-Type: text/plain' header. Reasoning:
// * The intake rejects the request if there is no content type.
// * The browser will issue CORS preflight requests if we set it to 'application/json', which
// could induce higher intake load (and maybe has other impacts).
// * Also it's not quite JSON, since we are concatenating multiple JSON objects separated by
// new lines.
type: 'text/plain',
});
}
return {
data: data,
bytesCount: encoderResult.outputBytesCount,
encoding: encoderResult.encoding,
flushReason: flushEvent.reason,
};
}
//# sourceMappingURL=batch.js.map

@@ -31,4 +31,7 @@ import type { PageExitEvent, PageExitReason } from '../browser/pageExitObservable';

* event can happen after `notifyBeforeAddMessage` and before adding the message.
*
* @param estimatedMessageBytesCount: an estimation of the message bytes count once it is
* actually added.
*/
notifyBeforeAddMessage(messageBytesCount: number): void;
notifyBeforeAddMessage(estimatedMessageBytesCount: number): void;
/**

@@ -39,4 +42,7 @@ * Notifies that a message *was* added to a pool of pending messages waiting to be flushed.

* should not be called if a flush event occurred in between.
*
* @param messageBytesCountDiff: the difference between the estimated message bytes count and
* its actual bytes count once added to the pool.
*/
notifyAfterAddMessage(): void;
notifyAfterAddMessage(messageBytesCountDiff?: number): void;
/**

@@ -47,2 +53,6 @@ * Notifies that a message was removed from a pool of pending messages waiting to be flushed.

* event can happen after removing the message and before `notifyAfterRemoveMessage`.
*
* @param messageBytesCount: the message bytes count that was added to the pool. Should
* correspond to the sum of bytes counts passed to `notifyBeforeAddMessage` and
* `notifyAfterAddMessage`.
*/

@@ -49,0 +59,0 @@ notifyAfterRemoveMessage(messageBytesCount: number): void;

@@ -55,5 +55,8 @@ import { Observable } from '../tools/observable';

* event can happen after `notifyBeforeAddMessage` and before adding the message.
*
* @param estimatedMessageBytesCount: an estimation of the message bytes count once it is
* actually added.
*/
notifyBeforeAddMessage: function (messageBytesCount) {
if (currentBytesCount + messageBytesCount >= bytesLimit) {
notifyBeforeAddMessage: function (estimatedMessageBytesCount) {
if (currentBytesCount + estimatedMessageBytesCount >= bytesLimit) {
flush('bytes_limit');

@@ -65,3 +68,3 @@ }

currentMessagesCount += 1;
currentBytesCount += messageBytesCount;
currentBytesCount += estimatedMessageBytesCount;
scheduleDurationLimitTimeout();

@@ -74,4 +77,9 @@ },

* should not be called if a flush event occurred in between.
*
* @param messageBytesCountDiff: the difference between the estimated message bytes count and
* its actual bytes count once added to the pool.
*/
notifyAfterAddMessage: function () {
notifyAfterAddMessage: function (messageBytesCountDiff) {
if (messageBytesCountDiff === void 0) { messageBytesCountDiff = 0; }
currentBytesCount += messageBytesCountDiff;
if (currentMessagesCount >= messagesLimit) {

@@ -89,2 +97,6 @@ flush('messages_limit');

* event can happen after removing the message and before `notifyAfterRemoveMessage`.
*
* @param messageBytesCount: the message bytes count that was added to the pool. Should
* correspond to the sum of bytes counts passed to `notifyBeforeAddMessage` and
* `notifyAfterAddMessage`.
*/

@@ -91,0 +103,0 @@ notifyAfterRemoveMessage: function (messageBytesCount) {

@@ -19,3 +19,3 @@ import type { EndpointBuilder, Configuration } from '../domain/configuration';

export interface Payload {
data: string | FormData;
data: string | FormData | Blob;
bytesCount: number;

@@ -22,0 +22,0 @@ retry?: RetryInfo;

@@ -74,2 +74,8 @@ import { addTelemetryError } from '../domain/telemetry';

request.open('POST', url, true);
if (data instanceof Blob) {
// When using a Blob instance, IE does not use its 'type' to define the 'Content-Type' header
// automatically, so the intake request ends up being rejected with an HTTP status 415
// Defining the header manually fixes this issue.
request.setRequestHeader('Content-Type', data.type);
}
addEventListener(configuration, request, 'loadend', function () {

@@ -76,0 +82,0 @@ onResponse === null || onResponse === void 0 ? void 0 : onResponse({ status: request.status });

@@ -6,8 +6,11 @@ import type { Configuration, EndpointBuilder } from '../domain/configuration';

import type { RawError } from '../domain/error/error.types';
export declare function startBatchWithReplica<T extends Context>(configuration: Configuration, primary: {
import type { Encoder } from '../tools/encoder';
export interface BatchConfiguration {
endpoint: EndpointBuilder;
}, replica: {
endpoint: EndpointBuilder;
encoder: Encoder;
}
interface ReplicaBatchConfiguration<T> extends BatchConfiguration {
transformMessage?: (message: T) => T;
} | undefined, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>): {
}
export declare function startBatchWithReplica<T extends Context>(configuration: Configuration, primary: BatchConfiguration, replica: ReplicaBatchConfiguration<T> | undefined, reportError: (error: RawError) => void, pageExitObservable: Observable<PageExitEvent>, sessionExpireObservable: Observable<void>): {
flushObservable: Observable<import("./flushController").FlushEvent>;

@@ -18,1 +21,2 @@ add(message: T, replicated?: boolean): void;

};
export {};

@@ -5,6 +5,7 @@ import { Batch } from './batch';

export function startBatchWithReplica(configuration, primary, replica, reportError, pageExitObservable, sessionExpireObservable) {
var primaryBatch = createBatch(configuration, primary.endpoint);
var replicaBatch = replica && createBatch(configuration, replica.endpoint);
function createBatch(configuration, endpointBuilder) {
return new Batch(createHttpRequest(configuration, endpointBuilder, configuration.batchBytesLimit, reportError), createFlushController({
var primaryBatch = createBatch(configuration, primary);
var replicaBatch = replica && createBatch(configuration, replica);
function createBatch(configuration, _a) {
var endpoint = _a.endpoint, encoder = _a.encoder;
return new Batch(encoder, createHttpRequest(configuration, endpoint, configuration.batchBytesLimit, reportError), createFlushController({
messagesLimit: configuration.batchMessagesLimit,

@@ -11,0 +12,0 @@ bytesLimit: configuration.batchBytesLimit,

{
"name": "@datadog/browser-core",
"version": "5.1.0",
"version": "5.2.0",
"license": "Apache-2.0",

@@ -26,3 +26,3 @@ "main": "cjs/index.js",

},
"gitHead": "3a31ebae7c56ed6d68cabf3cd96391ad57be0ab3"
"gitHead": "1896ddf29a7da4ea02b3d229f583d4a72d87d0a8"
}
import { display } from '../tools/display'
import { ONE_MINUTE, ONE_SECOND } from '../tools/utils/timeUtils'
import { findCommaSeparatedValue, generateUUID } from '../tools/utils/stringUtils'
import { findCommaSeparatedValue, findCommaSeparatedValues, generateUUID } from '../tools/utils/stringUtils'

@@ -25,2 +25,19 @@ export interface CookieOptions {

let initCookieParsed: Map<string, string> | undefined
/**
* Returns a cached value of the cookie. Use this during SDK initialization (and whenever possible)
* to avoid accessing document.cookie multiple times.
*/
export function getInitCookie(name: string) {
if (!initCookieParsed) {
initCookieParsed = findCommaSeparatedValues(document.cookie)
}
return initCookieParsed.get(name)
}
export function resetInitCookies() {
initCookieParsed = undefined
}
export function deleteCookie(name: string, options?: CookieOptions) {

@@ -27,0 +44,0 @@ setCookie(name, '', 0, options)

@@ -55,3 +55,5 @@ import { instrumentMethod } from '../tools/instrumentMethod'

if (context) {
responsePromise = originalFetch.call(this, context.input as RequestInfo, context.init)
// casting should be `RequestInfo` but node types are ahead of DOM types, making `typecheck test/e2e` fail.
// it should be resolved with https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1483
responsePromise = originalFetch.call(this, context.input as any, context.init)
callMonitored(afterSend, null, [observable, responsePromise, context])

@@ -58,0 +60,0 @@ } else {

@@ -0,1 +1,3 @@

import type { Encoder } from '../../tools/encoder'
export type DeflateWorkerAction =

@@ -42,1 +44,13 @@ // Action to send when creating the worker to check if the communication is working correctly.

}
export interface DeflateWorker extends Worker {
postMessage(message: DeflateWorkerAction): void
}
export type DeflateEncoder = Encoder<Uint8Array> & { stop: () => void }
export const enum DeflateEncoderStreamId {
REPLAY = 1,
RUM = 2,
RUM_REPLICA = 3,
}

@@ -1,2 +0,2 @@

import { getCookie } from '../../browser/cookie'
import { getInitCookie } from '../../browser/cookie'
import type { SessionStoreStrategy } from './storeStrategies/sessionStoreStrategy'

@@ -20,7 +20,7 @@ import { SESSION_STORE_KEY } from './storeStrategies/sessionStoreStrategy'

export function tryOldCookiesMigration(cookieStoreStrategy: SessionStoreStrategy) {
const sessionString = getCookie(SESSION_STORE_KEY)
const sessionString = getInitCookie(SESSION_STORE_KEY)
if (!sessionString) {
const oldSessionId = getCookie(OLD_SESSION_COOKIE_NAME)
const oldRumType = getCookie(OLD_RUM_COOKIE_NAME)
const oldLogsType = getCookie(OLD_LOGS_COOKIE_NAME)
const oldSessionId = getInitCookie(OLD_SESSION_COOKIE_NAME)
const oldRumType = getInitCookie(OLD_RUM_COOKIE_NAME)
const oldLogsType = getInitCookie(OLD_LOGS_COOKIE_NAME)
const session: SessionState = {}

@@ -27,0 +27,0 @@

@@ -1,2 +0,2 @@

import { getCookie } from '../../browser/cookie'
import { getInitCookie } from '../../browser/cookie'

@@ -15,3 +15,3 @@ export const SYNTHETICS_TEST_ID_COOKIE_NAME = 'datadog-synthetics-public-id'

return Boolean(
(window as BrowserWindow)._DATADOG_SYNTHETICS_INJECTS_RUM || getCookie(SYNTHETICS_INJECTS_RUM_COOKIE_NAME)
(window as BrowserWindow)._DATADOG_SYNTHETICS_INJECTS_RUM || getInitCookie(SYNTHETICS_INJECTS_RUM_COOKIE_NAME)
)

@@ -21,3 +21,3 @@ }

export function getSyntheticsTestId(): string | undefined {
const value = (window as BrowserWindow)._DATADOG_SYNTHETICS_PUBLIC_ID || getCookie(SYNTHETICS_TEST_ID_COOKIE_NAME)
const value = (window as BrowserWindow)._DATADOG_SYNTHETICS_PUBLIC_ID || getInitCookie(SYNTHETICS_TEST_ID_COOKIE_NAME)
return typeof value === 'string' ? value : undefined

@@ -27,4 +27,5 @@ }

export function getSyntheticsResultId(): string | undefined {
const value = (window as BrowserWindow)._DATADOG_SYNTHETICS_RESULT_ID || getCookie(SYNTHETICS_RESULT_ID_COOKIE_NAME)
const value =
(window as BrowserWindow)._DATADOG_SYNTHETICS_RESULT_ID || getInitCookie(SYNTHETICS_RESULT_ID_COOKIE_NAME)
return typeof value === 'string' ? value : undefined
}

@@ -64,2 +64,3 @@ export {

export * from './tools/display'
export { Encoder, EncoderResult, createIdentityEncoder } from './tools/encoder'
export * from './tools/utils/urlPolyfill'

@@ -66,0 +67,0 @@ export * from './tools/utils/timeUtils'

@@ -21,2 +21,3 @@ /**

DISABLE_REPLAY_INLINE_CSS = 'disable_replay_inline_css',
COMPRESS_BATCH = 'compress_batch',
}

@@ -23,0 +24,0 @@

@@ -1,17 +0,48 @@

let browserIsIE: boolean | undefined
// Exported only for tests
export const enum Browser {
IE,
CHROMIUM,
SAFARI,
OTHER,
}
export function isIE() {
return browserIsIE ?? (browserIsIE = Boolean((document as any).documentMode))
return detectBrowserCached() === Browser.IE
}
let browserIsChromium: boolean | undefined
export function isChromium() {
return (
browserIsChromium ??
(browserIsChromium = !!(window as any).chrome || /HeadlessChrome/.test(window.navigator.userAgent))
)
return detectBrowserCached() === Browser.CHROMIUM
}
let browserIsSafari: boolean | undefined
export function isSafari() {
return browserIsSafari ?? (browserIsSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent))
return detectBrowserCached() === Browser.SAFARI
}
let browserCache: Browser | undefined
function detectBrowserCached() {
return browserCache ?? (browserCache = detectBrowser())
}
// Exported only for tests
export function detectBrowser(browserWindow: Window = window) {
const userAgent = browserWindow.navigator.userAgent
if ((browserWindow as any).chrome || /HeadlessChrome/.test(userAgent)) {
return Browser.CHROMIUM
}
if (
// navigator.vendor is deprecated, but it is the most resilient way we found to detect
// "Apple maintained browsers" (AKA Safari). If one day it gets removed, we still have the
// useragent test as a semi-working fallback.
browserWindow.navigator.vendor?.indexOf('Apple') === 0 ||
(/safari/i.test(userAgent) && !/chrome|android/i.test(userAgent))
) {
return Browser.SAFARI
}
if ((browserWindow.document as any).documentMode) {
return Browser.IE
}
return Browser.OTHER
}

@@ -12,8 +12,34 @@ /**

export function findCommaSeparatedValue(rawString: string, name: string) {
const regex = new RegExp(`(?:^|;)\\s*${name}\\s*=\\s*([^;]+)`)
const matches = regex.exec(rawString)
return matches ? matches[1] : undefined
const COMMA_SEPARATED_KEY_VALUE = /([\w-]+)\s*=\s*([^;]+)/g
export function findCommaSeparatedValue(rawString: string, name: string): string | undefined {
COMMA_SEPARATED_KEY_VALUE.lastIndex = 0
// eslint-disable-next-line no-constant-condition
while (true) {
const match = COMMA_SEPARATED_KEY_VALUE.exec(rawString)
if (match) {
if (match[1] === name) {
return match[2]
}
} else {
break
}
}
}
export function findCommaSeparatedValues(rawString: string): Map<string, string> {
const result = new Map<string, string>()
COMMA_SEPARATED_KEY_VALUE.lastIndex = 0
// eslint-disable-next-line no-constant-condition
while (true) {
const match = COMMA_SEPARATED_KEY_VALUE.exec(rawString)
if (match) {
result.set(match[1], match[2])
} else {
break
}
}
return result
}
export function safeTruncate(candidate: string, length: number, suffix = '') {

@@ -20,0 +46,0 @@ const lastChar = candidate.charCodeAt(length - 1)

@@ -5,10 +5,10 @@ import { display } from '../tools/display'

import { isPageExitReason } from '../browser/pageExitObservable'
import { computeBytesCount } from '../tools/utils/byteUtils'
import { jsonStringify } from '../tools/serialisation/jsonStringify'
import type { Subscription } from '../tools/observable'
import type { HttpRequest } from './httpRequest'
import type { Encoder, EncoderResult } from '../tools/encoder'
import { computeBytesCount } from '../tools/utils/byteUtils'
import type { HttpRequest, Payload } from './httpRequest'
import type { FlushController, FlushEvent } from './flushController'
export class Batch {
private pushOnlyBuffer: string[] = []
private upsertBuffer: { [key: string]: string } = {}

@@ -18,2 +18,3 @@ private flushSubscription: Subscription

constructor(
private encoder: Encoder,
private request: HttpRequest,

@@ -39,12 +40,39 @@ public flushController: FlushController,

private flush(event: FlushEvent) {
const messages = this.pushOnlyBuffer.concat(objectValues(this.upsertBuffer))
this.pushOnlyBuffer = []
const upsertMessages = objectValues(this.upsertBuffer).join('\n')
this.upsertBuffer = {}
const payload = { data: messages.join('\n'), bytesCount: event.bytesCount, flushReason: event.reason }
if (isPageExitReason(event.reason)) {
this.request.sendOnExit(payload)
const isPageExit = isPageExitReason(event.reason)
const send = isPageExit ? this.request.sendOnExit : this.request.send
if (
isPageExit &&
// Note: checking that the encoder is async is not strictly needed, but it's an optimization:
// if the encoder is async we need to send two requests in some cases (one for encoded data
// and the other for non-encoded data). But if it's not async, we don't have to worry about
// it and always send a single request.
this.encoder.isAsync
) {
const encoderResult = this.encoder.finishSync()
// Send encoded messages
if (encoderResult.outputBytesCount) {
send(formatPayloadFromEncoder(encoderResult, event))
}
// Send messages that are not yet encoded at this point
const pendingMessages = [encoderResult.pendingData, upsertMessages].filter(Boolean).join('\n')
if (pendingMessages) {
send({
data: pendingMessages,
bytesCount: computeBytesCount(pendingMessages),
flushReason: event.reason,
})
}
} else {
this.request.send(payload)
if (upsertMessages) {
this.encoder.write(this.encoder.isEmpty ? upsertMessages : `\n${upsertMessages}`)
}
this.encoder.finish((encoderResult) => {
send(formatPayloadFromEncoder(encoderResult, event))
})
}

@@ -54,5 +82,7 @@ }

private addOrUpdate(message: Context, key?: string) {
const { processedMessage, messageBytesCount } = this.process(message)
const serializedMessage = jsonStringify(message)!
if (messageBytesCount >= this.messageBytesLimit) {
const estimatedMessageBytesCount = this.encoder.estimateEncodedBytesCount(serializedMessage)
if (estimatedMessageBytesCount >= this.messageBytesLimit) {
display.warn(

@@ -68,22 +98,19 @@ `Discarded a message whose size was bigger than the maximum allowed size ${this.messageBytesLimit}KB.`

this.push(processedMessage, messageBytesCount, key)
this.push(serializedMessage, estimatedMessageBytesCount, key)
}
private process(message: Context) {
const processedMessage = jsonStringify(message)!
const messageBytesCount = computeBytesCount(processedMessage)
return { processedMessage, messageBytesCount }
}
private push(serializedMessage: string, estimatedMessageBytesCount: number, key?: string) {
this.flushController.notifyBeforeAddMessage(estimatedMessageBytesCount)
private push(processedMessage: string, messageBytesCount: number, key?: string) {
// If there are other messages, a '\n' will be added at serialization
const separatorBytesCount = this.flushController.messagesCount > 0 ? 1 : 0
this.flushController.notifyBeforeAddMessage(messageBytesCount + separatorBytesCount)
if (key !== undefined) {
this.upsertBuffer[key] = processedMessage
this.upsertBuffer[key] = serializedMessage
this.flushController.notifyAfterAddMessage()
} else {
this.pushOnlyBuffer.push(processedMessage)
this.encoder.write(
this.encoder.isEmpty ? serializedMessage : `\n${serializedMessage}`,
(realMessageBytesCount) => {
this.flushController.notifyAfterAddMessage(realMessageBytesCount - estimatedMessageBytesCount)
}
)
}
this.flushController.notifyAfterAddMessage()
}

@@ -94,6 +121,4 @@

delete this.upsertBuffer[key]
const messageBytesCount = computeBytesCount(removedMessage)
// If there are other messages, a '\n' will be added at serialization
const separatorBytesCount = this.flushController.messagesCount > 1 ? 1 : 0
this.flushController.notifyAfterRemoveMessage(messageBytesCount + separatorBytesCount)
const messageBytesCount = this.encoder.estimateEncodedBytesCount(removedMessage)
this.flushController.notifyAfterRemoveMessage(messageBytesCount)
}

@@ -105,1 +130,25 @@

}
function formatPayloadFromEncoder(encoderResult: EncoderResult, flushEvent: FlushEvent): Payload {
let data: string | Blob
if (typeof encoderResult.output === 'string') {
data = encoderResult.output
} else {
data = new Blob([encoderResult.output], {
// This will set the 'Content-Type: text/plain' header. Reasoning:
// * The intake rejects the request if there is no content type.
// * The browser will issue CORS preflight requests if we set it to 'application/json', which
// could induce higher intake load (and maybe has other impacts).
// * Also it's not quite JSON, since we are concatenating multiple JSON objects separated by
// new lines.
type: 'text/plain',
})
}
return {
data,
bytesCount: encoderResult.outputBytesCount,
encoding: encoderResult.encoding,
flushReason: flushEvent.reason,
}
}

@@ -91,5 +91,8 @@ import type { PageExitEvent, PageExitReason } from '../browser/pageExitObservable'

* event can happen after `notifyBeforeAddMessage` and before adding the message.
*
* @param estimatedMessageBytesCount: an estimation of the message bytes count once it is
* actually added.
*/
notifyBeforeAddMessage(messageBytesCount: number) {
if (currentBytesCount + messageBytesCount >= bytesLimit) {
notifyBeforeAddMessage(estimatedMessageBytesCount: number) {
if (currentBytesCount + estimatedMessageBytesCount >= bytesLimit) {
flush('bytes_limit')

@@ -101,3 +104,3 @@ }

currentMessagesCount += 1
currentBytesCount += messageBytesCount
currentBytesCount += estimatedMessageBytesCount
scheduleDurationLimitTimeout()

@@ -111,4 +114,9 @@ },

* should not be called if a flush event occurred in between.
*
* @param messageBytesCountDiff: the difference between the estimated message bytes count and
* its actual bytes count once added to the pool.
*/
notifyAfterAddMessage() {
notifyAfterAddMessage(messageBytesCountDiff = 0) {
currentBytesCount += messageBytesCountDiff
if (currentMessagesCount >= messagesLimit) {

@@ -126,2 +134,6 @@ flush('messages_limit')

* event can happen after removing the message and before `notifyAfterRemoveMessage`.
*
* @param messageBytesCount: the message bytes count that was added to the pool. Should
* correspond to the sum of bytes counts passed to `notifyBeforeAddMessage` and
* `notifyAfterAddMessage`.
*/

@@ -128,0 +140,0 @@ notifyAfterRemoveMessage(messageBytesCount: number) {

@@ -27,3 +27,3 @@ import type { EndpointBuilder, Configuration } from '../domain/configuration'

export interface Payload {
data: string | FormData
data: string | FormData | Blob
bytesCount: number

@@ -138,2 +138,8 @@ retry?: RetryInfo

request.open('POST', url, true)
if (data instanceof Blob) {
// When using a Blob instance, IE does not use its 'type' to define the 'Content-Type' header
// automatically, so the intake request ends up being rejected with an HTTP status 415
// Defining the header manually fixes this issue.
request.setRequestHeader('Content-Type', data.type)
}
addEventListener(

@@ -140,0 +146,0 @@ configuration,

@@ -6,2 +6,3 @@ import type { Configuration, EndpointBuilder } from '../domain/configuration'

import type { RawError } from '../domain/error/error.types'
import type { Encoder } from '../tools/encoder'
import { Batch } from './batch'

@@ -11,6 +12,15 @@ import { createHttpRequest } from './httpRequest'

export interface BatchConfiguration {
endpoint: EndpointBuilder
encoder: Encoder
}
interface ReplicaBatchConfiguration<T> extends BatchConfiguration {
transformMessage?: (message: T) => T
}
export function startBatchWithReplica<T extends Context>(
configuration: Configuration,
primary: { endpoint: EndpointBuilder },
replica: { endpoint: EndpointBuilder; transformMessage?: (message: T) => T } | undefined,
primary: BatchConfiguration,
replica: ReplicaBatchConfiguration<T> | undefined,
reportError: (error: RawError) => void,

@@ -20,8 +30,9 @@ pageExitObservable: Observable<PageExitEvent>,

) {
const primaryBatch = createBatch(configuration, primary.endpoint)
const replicaBatch = replica && createBatch(configuration, replica.endpoint)
const primaryBatch = createBatch(configuration, primary)
const replicaBatch = replica && createBatch(configuration, replica)
function createBatch(configuration: Configuration, endpointBuilder: EndpointBuilder) {
function createBatch(configuration: Configuration, { endpoint, encoder }: BatchConfiguration) {
return new Batch(
createHttpRequest(configuration, endpointBuilder, configuration.batchBytesLimit, reportError),
encoder,
createHttpRequest(configuration, endpoint, configuration.batchBytesLimit, reportError),
createFlushController({

@@ -28,0 +39,0 @@ messagesLimit: configuration.batchMessagesLimit,

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc