@amplitude/analytics-core 2.11.1 → 2.11.2
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.
|
@@ -118,11 +118,12 @@ var NetworkObserver = /** @class */ (function () {
|
|
|
118
118
|
}
|
|
119
119
|
var originalFetch = this.globalScope.fetch;
|
|
120
120
|
this.globalScope.fetch = function (input, init) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
121
|
-
var startTime, requestEvent, response,
|
|
121
|
+
var startTime, durationStart, requestEvent, response, headers_1, contentLength_1, error_1, endTime, typedError;
|
|
122
122
|
return tslib_1.__generator(this, function (_a) {
|
|
123
123
|
switch (_a.label) {
|
|
124
124
|
case 0:
|
|
125
125
|
startTime = Date.now();
|
|
126
|
+
durationStart = performance.now();
|
|
126
127
|
requestEvent = {
|
|
127
128
|
timestamp: startTime,
|
|
128
129
|
startTime: startTime,
|
|
@@ -138,11 +139,10 @@ var NetworkObserver = /** @class */ (function () {
|
|
|
138
139
|
return [4 /*yield*/, originalFetch(input, init)];
|
|
139
140
|
case 2:
|
|
140
141
|
response = _a.sent();
|
|
141
|
-
endTime = Date.now();
|
|
142
142
|
requestEvent.status = response.status;
|
|
143
|
-
requestEvent.duration =
|
|
143
|
+
requestEvent.duration = Math.floor(performance.now() - durationStart);
|
|
144
144
|
requestEvent.startTime = startTime;
|
|
145
|
-
requestEvent.endTime =
|
|
145
|
+
requestEvent.endTime = Math.floor(startTime + requestEvent.duration);
|
|
146
146
|
headers_1 = {};
|
|
147
147
|
contentLength_1 = undefined;
|
|
148
148
|
response.headers.forEach(function (value, key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-observer.js","sourceRoot":"","sources":["../../src/network-observer.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGlobalScope } from './global-scope';\nimport { UUID } from './utils/uuid';\nimport { ILogger } from '.';\n\nconst MAXIMUM_ENTRIES = 100;\nexport interface NetworkRequestEvent {\n type: string;\n method: string;\n url: string;\n timestamp: number;\n status?: number;\n duration?: number;\n requestBodySize?: number;\n requestHeaders?: Record<string, string>;\n responseBodySize?: number;\n responseHeaders?: Record<string, string>;\n error?: {\n name: string;\n message: string;\n };\n startTime?: number;\n endTime?: number;\n}\n\n// using this type instead of the DOM's ttp so that it's Node compatible\ntype FormDataEntryValueBrowser = string | Blob | null;\nexport interface FormDataBrowser {\n entries(): IterableIterator<[string, FormDataEntryValueBrowser]>;\n}\n\nexport type FetchRequestBody = string | Blob | ArrayBuffer | FormDataBrowser | URLSearchParams | null | undefined;\n\nexport function getRequestBodyLength(body: FetchRequestBody | null | undefined): number | undefined {\n const global = getGlobalScope();\n if (!global?.TextEncoder) {\n return;\n }\n const { TextEncoder } = global;\n\n if (typeof body === 'string') {\n return new TextEncoder().encode(body).length;\n } else if (body instanceof Blob) {\n return body.size;\n } else if (body instanceof URLSearchParams) {\n return new TextEncoder().encode(body.toString()).length;\n } else if (body instanceof ArrayBuffer) {\n return body.byteLength;\n } else if (ArrayBuffer.isView(body)) {\n return body.byteLength;\n } else if (body instanceof FormData) {\n // Estimating only for text parts; not accurate for files\n const formData = body as FormDataBrowser;\n\n let total = 0;\n let count = 0;\n for (const [key, value] of formData.entries()) {\n total += key.length;\n if (typeof value === 'string') {\n total += new TextEncoder().encode(value).length;\n } else if ((value as Blob).size) {\n // if we encounter a \"File\" type, we should not count it and just return undefined\n total += (value as Blob).size;\n }\n // terminate if we reach the maximum number of entries\n // to avoid performance issues in case of very large FormDataß\n if (++count >= MAXIMUM_ENTRIES) {\n return;\n }\n }\n return total;\n }\n // Stream or unknown\n return;\n}\n\nexport type NetworkEventCallbackFn = (event: NetworkRequestEvent) => void;\n\nexport class NetworkEventCallback {\n constructor(public readonly callback: (event: NetworkRequestEvent) => void, public readonly id: string = UUID()) {}\n}\n\nexport class NetworkObserver {\n private originalFetch?: typeof fetch;\n private eventCallbacks: Map<string, NetworkEventCallback> = new Map();\n private isObserving = false;\n // eslint-disable-next-line no-restricted-globals\n private globalScope?: typeof globalThis;\n\n constructor(logger?: ILogger) {\n const globalScope = getGlobalScope();\n if (!NetworkObserver.isSupported()) {\n /* istanbul ignore next */\n logger?.error('Fetch API is not supported in this environment.');\n return;\n }\n this.globalScope = globalScope;\n /* istanbul ignore next */\n this.originalFetch = this.globalScope?.fetch;\n }\n\n static isSupported(): boolean {\n const globalScope = getGlobalScope();\n return !!globalScope && !!globalScope.fetch;\n }\n\n subscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.set(eventCallback.id, eventCallback);\n if (!this.isObserving) {\n this.observeFetch();\n this.isObserving = true;\n }\n }\n\n unsubscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.delete(eventCallback.id);\n if (this.originalFetch && this.globalScope && this.eventCallbacks.size === 0 && this.isObserving) {\n this.globalScope.fetch = this.originalFetch;\n this.isObserving = false;\n }\n }\n\n protected triggerEventCallbacks(event: NetworkRequestEvent) {\n this.eventCallbacks.forEach((callback) => {\n callback.callback(event);\n });\n }\n\n private observeFetch() {\n /* istanbul ignore next */\n if (!this.globalScope || !this.originalFetch) {\n return;\n }\n const originalFetch = this.globalScope.fetch;\n\n this.globalScope.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {\n const startTime = Date.now();\n const requestEvent: NetworkRequestEvent = {\n timestamp: startTime,\n startTime,\n type: 'fetch',\n method: init?.method || 'GET', // Fetch API defaulted to GET when no method is provided\n url: input.toString(),\n requestHeaders: init?.headers as Record<string, string>,\n requestBodySize: getRequestBodyLength(init?.body as FetchRequestBody),\n };\n\n try {\n const response = await originalFetch(input, init);\n const endTime = Date.now();\n\n requestEvent.status = response.status;\n requestEvent.duration = endTime - startTime;\n requestEvent.startTime = startTime;\n requestEvent.endTime = endTime;\n\n // Convert Headers\n const headers: Record<string, string> = {};\n let contentLength: number | undefined = undefined;\n response.headers.forEach((value: string, key: string) => {\n headers[key] = value;\n if (key === 'content-length') {\n contentLength = parseInt(value, 10) || undefined;\n }\n });\n requestEvent.responseHeaders = headers;\n requestEvent.responseBodySize = contentLength;\n\n this.triggerEventCallbacks(requestEvent);\n return response;\n } catch (error) {\n const endTime = Date.now();\n requestEvent.duration = endTime - startTime;\n\n // Capture error information\n const typedError = error as Error;\n requestEvent.error = {\n name: typedError.name || 'UnknownError',\n message: typedError.message || 'An unknown error occurred',\n };\n\n this.triggerEventCallbacks(requestEvent);\n throw error;\n }\n };\n }\n}\n\n// singleton instance of NetworkObserver\nexport const networkObserver = new NetworkObserver();\n"]}
|
|
1
|
+
{"version":3,"file":"network-observer.js","sourceRoot":"","sources":["../../src/network-observer.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGlobalScope } from './global-scope';\nimport { UUID } from './utils/uuid';\nimport { ILogger } from '.';\n\nconst MAXIMUM_ENTRIES = 100;\nexport interface NetworkRequestEvent {\n type: string;\n method: string;\n url: string;\n timestamp: number;\n status?: number;\n duration?: number;\n requestBodySize?: number;\n requestHeaders?: Record<string, string>;\n responseBodySize?: number;\n responseHeaders?: Record<string, string>;\n error?: {\n name: string;\n message: string;\n };\n startTime?: number;\n endTime?: number;\n}\n\n// using this type instead of the DOM's ttp so that it's Node compatible\ntype FormDataEntryValueBrowser = string | Blob | null;\nexport interface FormDataBrowser {\n entries(): IterableIterator<[string, FormDataEntryValueBrowser]>;\n}\n\nexport type FetchRequestBody = string | Blob | ArrayBuffer | FormDataBrowser | URLSearchParams | null | undefined;\n\nexport function getRequestBodyLength(body: FetchRequestBody | null | undefined): number | undefined {\n const global = getGlobalScope();\n if (!global?.TextEncoder) {\n return;\n }\n const { TextEncoder } = global;\n\n if (typeof body === 'string') {\n return new TextEncoder().encode(body).length;\n } else if (body instanceof Blob) {\n return body.size;\n } else if (body instanceof URLSearchParams) {\n return new TextEncoder().encode(body.toString()).length;\n } else if (body instanceof ArrayBuffer) {\n return body.byteLength;\n } else if (ArrayBuffer.isView(body)) {\n return body.byteLength;\n } else if (body instanceof FormData) {\n // Estimating only for text parts; not accurate for files\n const formData = body as FormDataBrowser;\n\n let total = 0;\n let count = 0;\n for (const [key, value] of formData.entries()) {\n total += key.length;\n if (typeof value === 'string') {\n total += new TextEncoder().encode(value).length;\n } else if ((value as Blob).size) {\n // if we encounter a \"File\" type, we should not count it and just return undefined\n total += (value as Blob).size;\n }\n // terminate if we reach the maximum number of entries\n // to avoid performance issues in case of very large FormDataß\n if (++count >= MAXIMUM_ENTRIES) {\n return;\n }\n }\n return total;\n }\n // Stream or unknown\n return;\n}\n\nexport type NetworkEventCallbackFn = (event: NetworkRequestEvent) => void;\n\nexport class NetworkEventCallback {\n constructor(public readonly callback: (event: NetworkRequestEvent) => void, public readonly id: string = UUID()) {}\n}\n\nexport class NetworkObserver {\n private originalFetch?: typeof fetch;\n private eventCallbacks: Map<string, NetworkEventCallback> = new Map();\n private isObserving = false;\n // eslint-disable-next-line no-restricted-globals\n private globalScope?: typeof globalThis;\n\n constructor(logger?: ILogger) {\n const globalScope = getGlobalScope();\n if (!NetworkObserver.isSupported()) {\n /* istanbul ignore next */\n logger?.error('Fetch API is not supported in this environment.');\n return;\n }\n this.globalScope = globalScope;\n /* istanbul ignore next */\n this.originalFetch = this.globalScope?.fetch;\n }\n\n static isSupported(): boolean {\n const globalScope = getGlobalScope();\n return !!globalScope && !!globalScope.fetch;\n }\n\n subscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.set(eventCallback.id, eventCallback);\n if (!this.isObserving) {\n this.observeFetch();\n this.isObserving = true;\n }\n }\n\n unsubscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.delete(eventCallback.id);\n if (this.originalFetch && this.globalScope && this.eventCallbacks.size === 0 && this.isObserving) {\n this.globalScope.fetch = this.originalFetch;\n this.isObserving = false;\n }\n }\n\n protected triggerEventCallbacks(event: NetworkRequestEvent) {\n this.eventCallbacks.forEach((callback) => {\n callback.callback(event);\n });\n }\n\n private observeFetch() {\n /* istanbul ignore next */\n if (!this.globalScope || !this.originalFetch) {\n return;\n }\n const originalFetch = this.globalScope.fetch;\n\n this.globalScope.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {\n const startTime = Date.now();\n const durationStart = performance.now();\n const requestEvent: NetworkRequestEvent = {\n timestamp: startTime,\n startTime,\n type: 'fetch',\n method: init?.method || 'GET', // Fetch API defaulted to GET when no method is provided\n url: input.toString(),\n requestHeaders: init?.headers as Record<string, string>,\n requestBodySize: getRequestBodyLength(init?.body as FetchRequestBody),\n };\n\n try {\n const response = await originalFetch(input, init);\n\n requestEvent.status = response.status;\n requestEvent.duration = Math.floor(performance.now() - durationStart);\n requestEvent.startTime = startTime;\n requestEvent.endTime = Math.floor(startTime + requestEvent.duration);\n\n // Convert Headers\n const headers: Record<string, string> = {};\n let contentLength: number | undefined = undefined;\n response.headers.forEach((value: string, key: string) => {\n headers[key] = value;\n if (key === 'content-length') {\n contentLength = parseInt(value, 10) || undefined;\n }\n });\n requestEvent.responseHeaders = headers;\n requestEvent.responseBodySize = contentLength;\n\n this.triggerEventCallbacks(requestEvent);\n return response;\n } catch (error) {\n const endTime = Date.now();\n requestEvent.duration = endTime - startTime;\n\n // Capture error information\n const typedError = error as Error;\n requestEvent.error = {\n name: typedError.name || 'UnknownError',\n message: typedError.message || 'An unknown error occurred',\n };\n\n this.triggerEventCallbacks(requestEvent);\n throw error;\n }\n };\n }\n}\n\n// singleton instance of NetworkObserver\nexport const networkObserver = new NetworkObserver();\n"]}
|
|
@@ -114,11 +114,12 @@ var NetworkObserver = /** @class */ (function () {
|
|
|
114
114
|
}
|
|
115
115
|
var originalFetch = this.globalScope.fetch;
|
|
116
116
|
this.globalScope.fetch = function (input, init) { return __awaiter(_this, void 0, void 0, function () {
|
|
117
|
-
var startTime, requestEvent, response,
|
|
117
|
+
var startTime, durationStart, requestEvent, response, headers_1, contentLength_1, error_1, endTime, typedError;
|
|
118
118
|
return __generator(this, function (_a) {
|
|
119
119
|
switch (_a.label) {
|
|
120
120
|
case 0:
|
|
121
121
|
startTime = Date.now();
|
|
122
|
+
durationStart = performance.now();
|
|
122
123
|
requestEvent = {
|
|
123
124
|
timestamp: startTime,
|
|
124
125
|
startTime: startTime,
|
|
@@ -134,11 +135,10 @@ var NetworkObserver = /** @class */ (function () {
|
|
|
134
135
|
return [4 /*yield*/, originalFetch(input, init)];
|
|
135
136
|
case 2:
|
|
136
137
|
response = _a.sent();
|
|
137
|
-
endTime = Date.now();
|
|
138
138
|
requestEvent.status = response.status;
|
|
139
|
-
requestEvent.duration =
|
|
139
|
+
requestEvent.duration = Math.floor(performance.now() - durationStart);
|
|
140
140
|
requestEvent.startTime = startTime;
|
|
141
|
-
requestEvent.endTime =
|
|
141
|
+
requestEvent.endTime = Math.floor(startTime + requestEvent.duration);
|
|
142
142
|
headers_1 = {};
|
|
143
143
|
contentLength_1 = undefined;
|
|
144
144
|
response.headers.forEach(function (value, key) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network-observer.js","sourceRoot":"","sources":["../../src/network-observer.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGlobalScope } from './global-scope';\nimport { UUID } from './utils/uuid';\nimport { ILogger } from '.';\n\nconst MAXIMUM_ENTRIES = 100;\nexport interface NetworkRequestEvent {\n type: string;\n method: string;\n url: string;\n timestamp: number;\n status?: number;\n duration?: number;\n requestBodySize?: number;\n requestHeaders?: Record<string, string>;\n responseBodySize?: number;\n responseHeaders?: Record<string, string>;\n error?: {\n name: string;\n message: string;\n };\n startTime?: number;\n endTime?: number;\n}\n\n// using this type instead of the DOM's ttp so that it's Node compatible\ntype FormDataEntryValueBrowser = string | Blob | null;\nexport interface FormDataBrowser {\n entries(): IterableIterator<[string, FormDataEntryValueBrowser]>;\n}\n\nexport type FetchRequestBody = string | Blob | ArrayBuffer | FormDataBrowser | URLSearchParams | null | undefined;\n\nexport function getRequestBodyLength(body: FetchRequestBody | null | undefined): number | undefined {\n const global = getGlobalScope();\n if (!global?.TextEncoder) {\n return;\n }\n const { TextEncoder } = global;\n\n if (typeof body === 'string') {\n return new TextEncoder().encode(body).length;\n } else if (body instanceof Blob) {\n return body.size;\n } else if (body instanceof URLSearchParams) {\n return new TextEncoder().encode(body.toString()).length;\n } else if (body instanceof ArrayBuffer) {\n return body.byteLength;\n } else if (ArrayBuffer.isView(body)) {\n return body.byteLength;\n } else if (body instanceof FormData) {\n // Estimating only for text parts; not accurate for files\n const formData = body as FormDataBrowser;\n\n let total = 0;\n let count = 0;\n for (const [key, value] of formData.entries()) {\n total += key.length;\n if (typeof value === 'string') {\n total += new TextEncoder().encode(value).length;\n } else if ((value as Blob).size) {\n // if we encounter a \"File\" type, we should not count it and just return undefined\n total += (value as Blob).size;\n }\n // terminate if we reach the maximum number of entries\n // to avoid performance issues in case of very large FormDataß\n if (++count >= MAXIMUM_ENTRIES) {\n return;\n }\n }\n return total;\n }\n // Stream or unknown\n return;\n}\n\nexport type NetworkEventCallbackFn = (event: NetworkRequestEvent) => void;\n\nexport class NetworkEventCallback {\n constructor(public readonly callback: (event: NetworkRequestEvent) => void, public readonly id: string = UUID()) {}\n}\n\nexport class NetworkObserver {\n private originalFetch?: typeof fetch;\n private eventCallbacks: Map<string, NetworkEventCallback> = new Map();\n private isObserving = false;\n // eslint-disable-next-line no-restricted-globals\n private globalScope?: typeof globalThis;\n\n constructor(logger?: ILogger) {\n const globalScope = getGlobalScope();\n if (!NetworkObserver.isSupported()) {\n /* istanbul ignore next */\n logger?.error('Fetch API is not supported in this environment.');\n return;\n }\n this.globalScope = globalScope;\n /* istanbul ignore next */\n this.originalFetch = this.globalScope?.fetch;\n }\n\n static isSupported(): boolean {\n const globalScope = getGlobalScope();\n return !!globalScope && !!globalScope.fetch;\n }\n\n subscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.set(eventCallback.id, eventCallback);\n if (!this.isObserving) {\n this.observeFetch();\n this.isObserving = true;\n }\n }\n\n unsubscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.delete(eventCallback.id);\n if (this.originalFetch && this.globalScope && this.eventCallbacks.size === 0 && this.isObserving) {\n this.globalScope.fetch = this.originalFetch;\n this.isObserving = false;\n }\n }\n\n protected triggerEventCallbacks(event: NetworkRequestEvent) {\n this.eventCallbacks.forEach((callback) => {\n callback.callback(event);\n });\n }\n\n private observeFetch() {\n /* istanbul ignore next */\n if (!this.globalScope || !this.originalFetch) {\n return;\n }\n const originalFetch = this.globalScope.fetch;\n\n this.globalScope.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {\n const startTime = Date.now();\n const requestEvent: NetworkRequestEvent = {\n timestamp: startTime,\n startTime,\n type: 'fetch',\n method: init?.method || 'GET', // Fetch API defaulted to GET when no method is provided\n url: input.toString(),\n requestHeaders: init?.headers as Record<string, string>,\n requestBodySize: getRequestBodyLength(init?.body as FetchRequestBody),\n };\n\n try {\n const response = await originalFetch(input, init);\n const endTime = Date.now();\n\n requestEvent.status = response.status;\n requestEvent.duration = endTime - startTime;\n requestEvent.startTime = startTime;\n requestEvent.endTime = endTime;\n\n // Convert Headers\n const headers: Record<string, string> = {};\n let contentLength: number | undefined = undefined;\n response.headers.forEach((value: string, key: string) => {\n headers[key] = value;\n if (key === 'content-length') {\n contentLength = parseInt(value, 10) || undefined;\n }\n });\n requestEvent.responseHeaders = headers;\n requestEvent.responseBodySize = contentLength;\n\n this.triggerEventCallbacks(requestEvent);\n return response;\n } catch (error) {\n const endTime = Date.now();\n requestEvent.duration = endTime - startTime;\n\n // Capture error information\n const typedError = error as Error;\n requestEvent.error = {\n name: typedError.name || 'UnknownError',\n message: typedError.message || 'An unknown error occurred',\n };\n\n this.triggerEventCallbacks(requestEvent);\n throw error;\n }\n };\n }\n}\n\n// singleton instance of NetworkObserver\nexport const networkObserver = new NetworkObserver();\n"]}
|
|
1
|
+
{"version":3,"file":"network-observer.js","sourceRoot":"","sources":["../../src/network-observer.ts"],"names":[],"mappings":"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","sourcesContent":["import { getGlobalScope } from './global-scope';\nimport { UUID } from './utils/uuid';\nimport { ILogger } from '.';\n\nconst MAXIMUM_ENTRIES = 100;\nexport interface NetworkRequestEvent {\n type: string;\n method: string;\n url: string;\n timestamp: number;\n status?: number;\n duration?: number;\n requestBodySize?: number;\n requestHeaders?: Record<string, string>;\n responseBodySize?: number;\n responseHeaders?: Record<string, string>;\n error?: {\n name: string;\n message: string;\n };\n startTime?: number;\n endTime?: number;\n}\n\n// using this type instead of the DOM's ttp so that it's Node compatible\ntype FormDataEntryValueBrowser = string | Blob | null;\nexport interface FormDataBrowser {\n entries(): IterableIterator<[string, FormDataEntryValueBrowser]>;\n}\n\nexport type FetchRequestBody = string | Blob | ArrayBuffer | FormDataBrowser | URLSearchParams | null | undefined;\n\nexport function getRequestBodyLength(body: FetchRequestBody | null | undefined): number | undefined {\n const global = getGlobalScope();\n if (!global?.TextEncoder) {\n return;\n }\n const { TextEncoder } = global;\n\n if (typeof body === 'string') {\n return new TextEncoder().encode(body).length;\n } else if (body instanceof Blob) {\n return body.size;\n } else if (body instanceof URLSearchParams) {\n return new TextEncoder().encode(body.toString()).length;\n } else if (body instanceof ArrayBuffer) {\n return body.byteLength;\n } else if (ArrayBuffer.isView(body)) {\n return body.byteLength;\n } else if (body instanceof FormData) {\n // Estimating only for text parts; not accurate for files\n const formData = body as FormDataBrowser;\n\n let total = 0;\n let count = 0;\n for (const [key, value] of formData.entries()) {\n total += key.length;\n if (typeof value === 'string') {\n total += new TextEncoder().encode(value).length;\n } else if ((value as Blob).size) {\n // if we encounter a \"File\" type, we should not count it and just return undefined\n total += (value as Blob).size;\n }\n // terminate if we reach the maximum number of entries\n // to avoid performance issues in case of very large FormDataß\n if (++count >= MAXIMUM_ENTRIES) {\n return;\n }\n }\n return total;\n }\n // Stream or unknown\n return;\n}\n\nexport type NetworkEventCallbackFn = (event: NetworkRequestEvent) => void;\n\nexport class NetworkEventCallback {\n constructor(public readonly callback: (event: NetworkRequestEvent) => void, public readonly id: string = UUID()) {}\n}\n\nexport class NetworkObserver {\n private originalFetch?: typeof fetch;\n private eventCallbacks: Map<string, NetworkEventCallback> = new Map();\n private isObserving = false;\n // eslint-disable-next-line no-restricted-globals\n private globalScope?: typeof globalThis;\n\n constructor(logger?: ILogger) {\n const globalScope = getGlobalScope();\n if (!NetworkObserver.isSupported()) {\n /* istanbul ignore next */\n logger?.error('Fetch API is not supported in this environment.');\n return;\n }\n this.globalScope = globalScope;\n /* istanbul ignore next */\n this.originalFetch = this.globalScope?.fetch;\n }\n\n static isSupported(): boolean {\n const globalScope = getGlobalScope();\n return !!globalScope && !!globalScope.fetch;\n }\n\n subscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.set(eventCallback.id, eventCallback);\n if (!this.isObserving) {\n this.observeFetch();\n this.isObserving = true;\n }\n }\n\n unsubscribe(eventCallback: NetworkEventCallback) {\n this.eventCallbacks.delete(eventCallback.id);\n if (this.originalFetch && this.globalScope && this.eventCallbacks.size === 0 && this.isObserving) {\n this.globalScope.fetch = this.originalFetch;\n this.isObserving = false;\n }\n }\n\n protected triggerEventCallbacks(event: NetworkRequestEvent) {\n this.eventCallbacks.forEach((callback) => {\n callback.callback(event);\n });\n }\n\n private observeFetch() {\n /* istanbul ignore next */\n if (!this.globalScope || !this.originalFetch) {\n return;\n }\n const originalFetch = this.globalScope.fetch;\n\n this.globalScope.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {\n const startTime = Date.now();\n const durationStart = performance.now();\n const requestEvent: NetworkRequestEvent = {\n timestamp: startTime,\n startTime,\n type: 'fetch',\n method: init?.method || 'GET', // Fetch API defaulted to GET when no method is provided\n url: input.toString(),\n requestHeaders: init?.headers as Record<string, string>,\n requestBodySize: getRequestBodyLength(init?.body as FetchRequestBody),\n };\n\n try {\n const response = await originalFetch(input, init);\n\n requestEvent.status = response.status;\n requestEvent.duration = Math.floor(performance.now() - durationStart);\n requestEvent.startTime = startTime;\n requestEvent.endTime = Math.floor(startTime + requestEvent.duration);\n\n // Convert Headers\n const headers: Record<string, string> = {};\n let contentLength: number | undefined = undefined;\n response.headers.forEach((value: string, key: string) => {\n headers[key] = value;\n if (key === 'content-length') {\n contentLength = parseInt(value, 10) || undefined;\n }\n });\n requestEvent.responseHeaders = headers;\n requestEvent.responseBodySize = contentLength;\n\n this.triggerEventCallbacks(requestEvent);\n return response;\n } catch (error) {\n const endTime = Date.now();\n requestEvent.duration = endTime - startTime;\n\n // Capture error information\n const typedError = error as Error;\n requestEvent.error = {\n name: typedError.name || 'UnknownError',\n message: typedError.message || 'An unknown error occurred',\n };\n\n this.triggerEventCallbacks(requestEvent);\n throw error;\n }\n };\n }\n}\n\n// singleton instance of NetworkObserver\nexport const networkObserver = new NetworkObserver();\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amplitude/analytics-core",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "Amplitude Inc",
|
|
6
6
|
"homepage": "https://github.com/amplitude/Amplitude-TypeScript",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"files": [
|
|
43
43
|
"lib"
|
|
44
44
|
],
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "f659dd0d6491ec3d16b763b4c791644e64a7fddc"
|
|
46
46
|
}
|