@contentful/optimization-api-client 0.1.0-alpha14 → 0.1.0-alpha16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -213,7 +213,8 @@ export declare interface BaseFetchMethodOptions {
213
213
  *
214
214
  * @remarks
215
215
  * This is useful for providing polyfills, mocks, or instrumented fetch
216
- * implementations.
216
+ * implementations. It is required in runtimes that do not provide
217
+ * `globalThis.fetch`.
217
218
  */
218
219
  fetchMethod?: FetchMethod;
219
220
  }
@@ -609,14 +610,16 @@ export declare type Feature = 'ip-enrichment' | 'location';
609
610
  *
610
611
  * @example
611
612
  * ```ts
612
- * const method: FetchMethod = async (url, init) => {
613
- * return fetch(url, init)
613
+ * const method: FetchMethod = async (input, init) => {
614
+ * return fetch(input, init)
614
615
  * }
615
616
  * ```
616
617
  *
617
618
  * @public
618
619
  */
619
- export declare type FetchMethod = (url: string | URL, init: RequestInit) => Promise<Response>;
620
+ export declare type FetchInput = string | Request;
621
+
622
+ export declare type FetchMethod = (input: FetchInput, init?: RequestInit) => Promise<Response>;
620
623
 
621
624
  /**
622
625
  * Options passed to callback functions invoked by fetch wrappers.
@@ -664,7 +667,7 @@ export declare const INSIGHTS_BASE_URL = "https://ingest.insights.ninetailed.co/
664
667
  *
665
668
  * @remarks
666
669
  * This client is optimized for sending batched events, optionally using a
667
- * custom beacon-like handler when available.
670
+ * custom beacon-like sender for last-chance lifecycle delivery.
668
671
  *
669
672
  * @example
670
673
  * ```ts
@@ -696,10 +699,6 @@ export declare class InsightsApiClient extends ApiClientBase {
696
699
  * Base URL used for Insights API requests.
697
700
  */
698
701
  protected readonly baseUrl: string;
699
- /**
700
- * Optional handler used to enqueue events via the Beacon API or a similar mechanism.
701
- */
702
- private readonly beaconHandler;
703
702
  /**
704
703
  * Creates a new {@link InsightsApiClient} instance.
705
704
  *
@@ -710,9 +709,6 @@ export declare class InsightsApiClient extends ApiClientBase {
710
709
  * const client = new InsightsApiClient({
711
710
  * clientId: 'org-id',
712
711
  * environment: 'main',
713
- * beaconHandler: (url, data) => {
714
- * return navigator.sendBeacon(url.toString(), JSON.stringify(data))
715
- * },
716
712
  * })
717
713
  * ```
718
714
  */
@@ -721,18 +717,18 @@ export declare class InsightsApiClient extends ApiClientBase {
721
717
  * Sends batches of insights events to the Ninetailed Insights API.
722
718
  *
723
719
  * @param batches - Array of event batches to send.
724
- * @param options - Optional request options, including a per-call `beaconHandler`.
720
+ * @param options - Optional request options, including a per-call `beacon` sender.
725
721
  * @returns `true` when the event batch is successfully queued by the beacon
726
- * handler or a direct request is successfully sent, `false` otherwise.
722
+ * sender or a direct request is successfully sent, `false` otherwise.
727
723
  *
728
724
  * @remarks
729
- * If a `beaconHandler` is provided (either in the method call or in the
730
- * client configuration) it will be invoked first. When the handler returns
731
- * `true`, the events are considered successfully queued and no network
732
- * request is made by this method.
725
+ * If a `beacon` sender is provided, it will be invoked first with the
726
+ * serialized request body. When the sender returns `true`, the events are
727
+ * considered successfully queued and no network request is made by this
728
+ * method.
733
729
  *
734
- * If the handler is missing or returns `false`, the events are emitted
735
- * immediately via `fetch`.
730
+ * If the sender is missing, returns `false`, or throws, the events are
731
+ * emitted immediately via `fetch`.
736
732
  *
737
733
  * @example
738
734
  * ```ts
@@ -741,11 +737,9 @@ export declare class InsightsApiClient extends ApiClientBase {
741
737
  *
742
738
  * @example
743
739
  * ```ts
744
- * // Override beaconHandler for a single call
740
+ * // Use Beacon for a last-chance lifecycle flush
745
741
  * const success = await insightsClient.sendBatchEvents(batches, {
746
- * beaconHandler: (url, data) => {
747
- * return navigator.sendBeacon(url.toString(), JSON.stringify(data))
748
- * },
742
+ * beacon: (url, body) => navigator.sendBeacon(url, body),
749
743
  * })
750
744
  * ```
751
745
  */
@@ -757,7 +751,7 @@ export declare class InsightsApiClient extends ApiClientBase {
757
751
  *
758
752
  * @public
759
753
  */
760
- export declare interface InsightsApiClientConfig extends ApiConfig, InsightsApiClientRequestOptions {
754
+ export declare interface InsightsApiClientConfig extends ApiConfig {
761
755
  }
762
756
 
763
757
  /**
@@ -767,18 +761,18 @@ export declare interface InsightsApiClientConfig extends ApiConfig, InsightsApiC
767
761
  */
768
762
  export declare interface InsightsApiClientRequestOptions {
769
763
  /**
770
- * Handler used to enqueue events via the Beacon API or a similar mechanism.
764
+ * Sender used to enqueue serialized events via the Beacon API or a similar mechanism.
771
765
  *
772
766
  * @param url - Target URL for the batched events.
773
- * @param data - Array of batched insights events to be sent.
767
+ * @param body - Serialized batched insights events to be sent.
774
768
  * @returns `true` if the events were successfully queued, `false` otherwise.
775
769
  *
776
770
  * @remarks
777
- * When provided, this handler is preferred over direct `fetch` calls. If it
778
- * returns `false`, the client falls back to emitting events immediately via
779
- * `fetch`.
771
+ * This option is intended for last-chance lifecycle delivery. If it returns
772
+ * `false` or throws, the client falls back to emitting events immediately via
773
+ * `fetch` with `keepalive`.
780
774
  */
781
- beaconHandler?: (url: string | URL, data: BatchInsightsEventArray) => boolean;
775
+ beacon?: (url: string, body: string) => boolean;
782
776
  }
783
777
 
784
778
  /**
package/dist/index.d.mts CHANGED
@@ -213,7 +213,8 @@ export declare interface BaseFetchMethodOptions {
213
213
  *
214
214
  * @remarks
215
215
  * This is useful for providing polyfills, mocks, or instrumented fetch
216
- * implementations.
216
+ * implementations. It is required in runtimes that do not provide
217
+ * `globalThis.fetch`.
217
218
  */
218
219
  fetchMethod?: FetchMethod;
219
220
  }
@@ -609,14 +610,16 @@ export declare type Feature = 'ip-enrichment' | 'location';
609
610
  *
610
611
  * @example
611
612
  * ```ts
612
- * const method: FetchMethod = async (url, init) => {
613
- * return fetch(url, init)
613
+ * const method: FetchMethod = async (input, init) => {
614
+ * return fetch(input, init)
614
615
  * }
615
616
  * ```
616
617
  *
617
618
  * @public
618
619
  */
619
- export declare type FetchMethod = (url: string | URL, init: RequestInit) => Promise<Response>;
620
+ export declare type FetchInput = string | Request;
621
+
622
+ export declare type FetchMethod = (input: FetchInput, init?: RequestInit) => Promise<Response>;
620
623
 
621
624
  /**
622
625
  * Options passed to callback functions invoked by fetch wrappers.
@@ -664,7 +667,7 @@ export declare const INSIGHTS_BASE_URL = "https://ingest.insights.ninetailed.co/
664
667
  *
665
668
  * @remarks
666
669
  * This client is optimized for sending batched events, optionally using a
667
- * custom beacon-like handler when available.
670
+ * custom beacon-like sender for last-chance lifecycle delivery.
668
671
  *
669
672
  * @example
670
673
  * ```ts
@@ -696,10 +699,6 @@ export declare class InsightsApiClient extends ApiClientBase {
696
699
  * Base URL used for Insights API requests.
697
700
  */
698
701
  protected readonly baseUrl: string;
699
- /**
700
- * Optional handler used to enqueue events via the Beacon API or a similar mechanism.
701
- */
702
- private readonly beaconHandler;
703
702
  /**
704
703
  * Creates a new {@link InsightsApiClient} instance.
705
704
  *
@@ -710,9 +709,6 @@ export declare class InsightsApiClient extends ApiClientBase {
710
709
  * const client = new InsightsApiClient({
711
710
  * clientId: 'org-id',
712
711
  * environment: 'main',
713
- * beaconHandler: (url, data) => {
714
- * return navigator.sendBeacon(url.toString(), JSON.stringify(data))
715
- * },
716
712
  * })
717
713
  * ```
718
714
  */
@@ -721,18 +717,18 @@ export declare class InsightsApiClient extends ApiClientBase {
721
717
  * Sends batches of insights events to the Ninetailed Insights API.
722
718
  *
723
719
  * @param batches - Array of event batches to send.
724
- * @param options - Optional request options, including a per-call `beaconHandler`.
720
+ * @param options - Optional request options, including a per-call `beacon` sender.
725
721
  * @returns `true` when the event batch is successfully queued by the beacon
726
- * handler or a direct request is successfully sent, `false` otherwise.
722
+ * sender or a direct request is successfully sent, `false` otherwise.
727
723
  *
728
724
  * @remarks
729
- * If a `beaconHandler` is provided (either in the method call or in the
730
- * client configuration) it will be invoked first. When the handler returns
731
- * `true`, the events are considered successfully queued and no network
732
- * request is made by this method.
725
+ * If a `beacon` sender is provided, it will be invoked first with the
726
+ * serialized request body. When the sender returns `true`, the events are
727
+ * considered successfully queued and no network request is made by this
728
+ * method.
733
729
  *
734
- * If the handler is missing or returns `false`, the events are emitted
735
- * immediately via `fetch`.
730
+ * If the sender is missing, returns `false`, or throws, the events are
731
+ * emitted immediately via `fetch`.
736
732
  *
737
733
  * @example
738
734
  * ```ts
@@ -741,11 +737,9 @@ export declare class InsightsApiClient extends ApiClientBase {
741
737
  *
742
738
  * @example
743
739
  * ```ts
744
- * // Override beaconHandler for a single call
740
+ * // Use Beacon for a last-chance lifecycle flush
745
741
  * const success = await insightsClient.sendBatchEvents(batches, {
746
- * beaconHandler: (url, data) => {
747
- * return navigator.sendBeacon(url.toString(), JSON.stringify(data))
748
- * },
742
+ * beacon: (url, body) => navigator.sendBeacon(url, body),
749
743
  * })
750
744
  * ```
751
745
  */
@@ -757,7 +751,7 @@ export declare class InsightsApiClient extends ApiClientBase {
757
751
  *
758
752
  * @public
759
753
  */
760
- export declare interface InsightsApiClientConfig extends ApiConfig, InsightsApiClientRequestOptions {
754
+ export declare interface InsightsApiClientConfig extends ApiConfig {
761
755
  }
762
756
 
763
757
  /**
@@ -767,18 +761,18 @@ export declare interface InsightsApiClientConfig extends ApiConfig, InsightsApiC
767
761
  */
768
762
  export declare interface InsightsApiClientRequestOptions {
769
763
  /**
770
- * Handler used to enqueue events via the Beacon API or a similar mechanism.
764
+ * Sender used to enqueue serialized events via the Beacon API or a similar mechanism.
771
765
  *
772
766
  * @param url - Target URL for the batched events.
773
- * @param data - Array of batched insights events to be sent.
767
+ * @param body - Serialized batched insights events to be sent.
774
768
  * @returns `true` if the events were successfully queued, `false` otherwise.
775
769
  *
776
770
  * @remarks
777
- * When provided, this handler is preferred over direct `fetch` calls. If it
778
- * returns `false`, the client falls back to emitting events immediately via
779
- * `fetch`.
771
+ * This option is intended for last-chance lifecycle delivery. If it returns
772
+ * `false` or throws, the client falls back to emitting events immediately via
773
+ * `fetch` with `keepalive`.
780
774
  */
781
- beaconHandler?: (url: string | URL, data: BatchInsightsEventArray) => boolean;
775
+ beacon?: (url: string, body: string) => boolean;
782
776
  }
783
777
 
784
778
  /**
package/dist/index.d.ts CHANGED
@@ -213,7 +213,8 @@ export declare interface BaseFetchMethodOptions {
213
213
  *
214
214
  * @remarks
215
215
  * This is useful for providing polyfills, mocks, or instrumented fetch
216
- * implementations.
216
+ * implementations. It is required in runtimes that do not provide
217
+ * `globalThis.fetch`.
217
218
  */
218
219
  fetchMethod?: FetchMethod;
219
220
  }
@@ -609,14 +610,16 @@ export declare type Feature = 'ip-enrichment' | 'location';
609
610
  *
610
611
  * @example
611
612
  * ```ts
612
- * const method: FetchMethod = async (url, init) => {
613
- * return fetch(url, init)
613
+ * const method: FetchMethod = async (input, init) => {
614
+ * return fetch(input, init)
614
615
  * }
615
616
  * ```
616
617
  *
617
618
  * @public
618
619
  */
619
- export declare type FetchMethod = (url: string | URL, init: RequestInit) => Promise<Response>;
620
+ export declare type FetchInput = string | Request;
621
+
622
+ export declare type FetchMethod = (input: FetchInput, init?: RequestInit) => Promise<Response>;
620
623
 
621
624
  /**
622
625
  * Options passed to callback functions invoked by fetch wrappers.
@@ -664,7 +667,7 @@ export declare const INSIGHTS_BASE_URL = "https://ingest.insights.ninetailed.co/
664
667
  *
665
668
  * @remarks
666
669
  * This client is optimized for sending batched events, optionally using a
667
- * custom beacon-like handler when available.
670
+ * custom beacon-like sender for last-chance lifecycle delivery.
668
671
  *
669
672
  * @example
670
673
  * ```ts
@@ -696,10 +699,6 @@ export declare class InsightsApiClient extends ApiClientBase {
696
699
  * Base URL used for Insights API requests.
697
700
  */
698
701
  protected readonly baseUrl: string;
699
- /**
700
- * Optional handler used to enqueue events via the Beacon API or a similar mechanism.
701
- */
702
- private readonly beaconHandler;
703
702
  /**
704
703
  * Creates a new {@link InsightsApiClient} instance.
705
704
  *
@@ -710,9 +709,6 @@ export declare class InsightsApiClient extends ApiClientBase {
710
709
  * const client = new InsightsApiClient({
711
710
  * clientId: 'org-id',
712
711
  * environment: 'main',
713
- * beaconHandler: (url, data) => {
714
- * return navigator.sendBeacon(url.toString(), JSON.stringify(data))
715
- * },
716
712
  * })
717
713
  * ```
718
714
  */
@@ -721,18 +717,18 @@ export declare class InsightsApiClient extends ApiClientBase {
721
717
  * Sends batches of insights events to the Ninetailed Insights API.
722
718
  *
723
719
  * @param batches - Array of event batches to send.
724
- * @param options - Optional request options, including a per-call `beaconHandler`.
720
+ * @param options - Optional request options, including a per-call `beacon` sender.
725
721
  * @returns `true` when the event batch is successfully queued by the beacon
726
- * handler or a direct request is successfully sent, `false` otherwise.
722
+ * sender or a direct request is successfully sent, `false` otherwise.
727
723
  *
728
724
  * @remarks
729
- * If a `beaconHandler` is provided (either in the method call or in the
730
- * client configuration) it will be invoked first. When the handler returns
731
- * `true`, the events are considered successfully queued and no network
732
- * request is made by this method.
725
+ * If a `beacon` sender is provided, it will be invoked first with the
726
+ * serialized request body. When the sender returns `true`, the events are
727
+ * considered successfully queued and no network request is made by this
728
+ * method.
733
729
  *
734
- * If the handler is missing or returns `false`, the events are emitted
735
- * immediately via `fetch`.
730
+ * If the sender is missing, returns `false`, or throws, the events are
731
+ * emitted immediately via `fetch`.
736
732
  *
737
733
  * @example
738
734
  * ```ts
@@ -741,11 +737,9 @@ export declare class InsightsApiClient extends ApiClientBase {
741
737
  *
742
738
  * @example
743
739
  * ```ts
744
- * // Override beaconHandler for a single call
740
+ * // Use Beacon for a last-chance lifecycle flush
745
741
  * const success = await insightsClient.sendBatchEvents(batches, {
746
- * beaconHandler: (url, data) => {
747
- * return navigator.sendBeacon(url.toString(), JSON.stringify(data))
748
- * },
742
+ * beacon: (url, body) => navigator.sendBeacon(url, body),
749
743
  * })
750
744
  * ```
751
745
  */
@@ -757,7 +751,7 @@ export declare class InsightsApiClient extends ApiClientBase {
757
751
  *
758
752
  * @public
759
753
  */
760
- export declare interface InsightsApiClientConfig extends ApiConfig, InsightsApiClientRequestOptions {
754
+ export declare interface InsightsApiClientConfig extends ApiConfig {
761
755
  }
762
756
 
763
757
  /**
@@ -767,18 +761,18 @@ export declare interface InsightsApiClientConfig extends ApiConfig, InsightsApiC
767
761
  */
768
762
  export declare interface InsightsApiClientRequestOptions {
769
763
  /**
770
- * Handler used to enqueue events via the Beacon API or a similar mechanism.
764
+ * Sender used to enqueue serialized events via the Beacon API or a similar mechanism.
771
765
  *
772
766
  * @param url - Target URL for the batched events.
773
- * @param data - Array of batched insights events to be sent.
767
+ * @param body - Serialized batched insights events to be sent.
774
768
  * @returns `true` if the events were successfully queued, `false` otherwise.
775
769
  *
776
770
  * @remarks
777
- * When provided, this handler is preferred over direct `fetch` calls. If it
778
- * returns `false`, the client falls back to emitting events immediately via
779
- * `fetch`.
771
+ * This option is intended for last-chance lifecycle delivery. If it returns
772
+ * `false` or throws, the client falls back to emitting events immediately via
773
+ * `fetch` with `keepalive`.
780
774
  */
781
- beaconHandler?: (url: string | URL, data: BatchInsightsEventArray) => boolean;
775
+ beacon?: (url: string, body: string) => boolean;
782
776
  }
783
777
 
784
778
  /**
package/dist/index.mjs CHANGED
@@ -1,5 +1,15 @@
1
1
  import { createScopedLogger } from "./649.mjs";
2
2
  import { __rspack_external__contentful_optimization_api_schemas_66dcf407 } from "./199.mjs";
3
+ const fetchInputToString = (input)=>{
4
+ if ('string' == typeof input) return input;
5
+ return input.url;
6
+ };
7
+ const MISSING_FETCH_METHOD_MESSAGE = 'No fetch implementation available. Provide a fetchMethod.';
8
+ function resolveFetchMethod(fetchMethod) {
9
+ if (fetchMethod) return fetchMethod;
10
+ if ('function' == typeof globalThis.fetch) return globalThis.fetch.bind(globalThis);
11
+ throw new Error(MISSING_FETCH_METHOD_MESSAGE);
12
+ }
3
13
  const logger = createScopedLogger('ApiClient:Retry');
4
14
  const DEFAULT_INTERVAL_TIMEOUT = 0;
5
15
  const DEFAULT_RETRY_COUNT = 1;
@@ -13,22 +23,23 @@ class HttpError extends Error {
13
23
  this.status = status;
14
24
  }
15
25
  }
16
- function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod = fetch, init, url }) {
26
+ function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod, init, url }) {
17
27
  return async ()=>{
28
+ const urlLabel = fetchInputToString(url);
18
29
  try {
19
30
  const response = await fetchMethod(url, init);
20
- if (response.status === RETRY_RESPONSE_STATUS) throw new HttpError(`${apiName} API request to "${url.toString()}" failed with status: "[${response.status}] ${response.statusText}".`, RETRY_RESPONSE_STATUS);
31
+ if (response.status === RETRY_RESPONSE_STATUS) throw new HttpError(`${apiName} API request to "${urlLabel}" failed with status: "[${response.status}] ${response.statusText}".`, RETRY_RESPONSE_STATUS);
21
32
  if (!response.ok) {
22
- const httpError = new Error(`Request to "${url.toString()}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
33
+ const httpError = new Error(`Request to "${urlLabel}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
23
34
  logger.error('Request failed with non-OK status:', httpError);
24
35
  controller.abort();
25
36
  return;
26
37
  }
27
- logger.debug(`Response from "${url.toString()}":`, response);
38
+ logger.debug(`Response from "${urlLabel}":`, response);
28
39
  return response;
29
40
  } catch (error) {
30
41
  if (error instanceof HttpError && error.status === RETRY_RESPONSE_STATUS) throw error;
31
- logger.error(`Request to "${url.toString()}" failed:`, error);
42
+ logger.error(`Request to "${urlLabel}" failed:`, error);
32
43
  controller.abort();
33
44
  }
34
45
  };
@@ -41,14 +52,15 @@ async function delayRetry(intervalTimeout) {
41
52
  }, intervalTimeout);
42
53
  await promise;
43
54
  }
44
- function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
55
+ function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
56
+ const resolvedFetchMethod = resolveFetchMethod(fetchMethod);
45
57
  return async (url, init)=>{
46
58
  const controller = new AbortController();
47
59
  const maxAttempts = retries + 1;
48
60
  const attemptFetch = createRetryFetchCallback({
49
61
  apiName,
50
62
  controller,
51
- fetchMethod,
63
+ fetchMethod: resolvedFetchMethod,
52
64
  init,
53
65
  url
54
66
  });
@@ -68,28 +80,32 @@ function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod = fetch,
68
80
  if (0 === retriesLeft) throw error;
69
81
  await delayRetry(intervalTimeout);
70
82
  }
71
- throw new Error(`${apiName} API request to "${url.toString()}" may not be retried.`);
83
+ throw new Error(`${apiName} API request to "${fetchInputToString(url)}" may not be retried.`);
72
84
  };
73
85
  }
74
86
  const createTimeoutFetchMethod_logger = createScopedLogger('ApiClient:Timeout');
75
87
  const DEFAULT_REQUEST_TIMEOUT = 3000;
76
- function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
88
+ function isFetchAbortSignal(signal) {
89
+ return 'object' == typeof signal && null !== signal;
90
+ }
91
+ function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
92
+ const resolvedFetchMethod = resolveFetchMethod(fetchMethod);
77
93
  return async (url, init)=>{
78
94
  const controller = new AbortController();
79
95
  const id = setTimeout(()=>{
80
96
  if ('function' == typeof onRequestTimeout) onRequestTimeout({
81
97
  apiName
82
98
  });
83
- else createTimeoutFetchMethod_logger.error(`Request to "${url.toString()}" timed out`, new Error('Request timeout'));
99
+ else createTimeoutFetchMethod_logger.error(`Request to "${fetchInputToString(url)}" timed out`, new Error('Request timeout'));
84
100
  controller.abort();
85
101
  }, requestTimeout);
102
+ const { signal } = controller;
103
+ if (!isFetchAbortSignal(signal)) throw new Error('AbortController signal is not compatible with fetch.');
86
104
  const requestInit = {
87
- ...init
105
+ ...init,
106
+ signal
88
107
  };
89
- Object.assign(requestInit, {
90
- signal: controller.signal
91
- });
92
- const response = await fetchMethod(url, requestInit);
108
+ const response = await resolvedFetchMethod(url, requestInit);
93
109
  clearTimeout(id);
94
110
  return response;
95
111
  };
@@ -113,7 +129,7 @@ const Fetch = {
113
129
  create: createProtectedFetchMethod
114
130
  };
115
131
  const fetch_Fetch = Fetch;
116
- const src_fetch = fetch_Fetch;
132
+ const fetch = fetch_Fetch;
117
133
  const ApiClientBase_logger = createScopedLogger('ApiClient');
118
134
  const DEFAULT_ENVIRONMENT = 'main';
119
135
  class ApiClientBase {
@@ -125,7 +141,7 @@ class ApiClientBase {
125
141
  this.clientId = clientId;
126
142
  this.environment = environment ?? DEFAULT_ENVIRONMENT;
127
143
  this.name = name;
128
- this.fetch = src_fetch.create({
144
+ this.fetch = fetch.create({
129
145
  ...fetchOptions ?? {},
130
146
  apiName: name
131
147
  });
@@ -310,37 +326,42 @@ class ExperienceApiClient extends src_ApiClientBase {
310
326
  }
311
327
  }
312
328
  const InsightsApiClient_logger = createScopedLogger('ApiClient:Insights');
329
+ const BEACON_FALLBACK_MESSAGE = 'beacon failed; falling back to fetch';
313
330
  const INSIGHTS_BASE_URL = 'https://ingest.insights.ninetailed.co/';
314
331
  class InsightsApiClient extends src_ApiClientBase {
315
332
  baseUrl;
316
- beaconHandler;
317
333
  constructor(config){
318
334
  super('Insights', config);
319
- const { baseUrl, beaconHandler } = config;
335
+ const { baseUrl } = config;
320
336
  this.baseUrl = baseUrl || INSIGHTS_BASE_URL;
321
- this.beaconHandler = beaconHandler;
322
337
  }
323
338
  async sendBatchEvents(batches, options = {}) {
324
- const { beaconHandler = this.beaconHandler } = options;
339
+ const { beacon } = options;
325
340
  const url = new URL(`v1/organizations/${this.clientId}/environments/${this.environment}/events`, this.baseUrl);
341
+ const urlString = url.toString();
326
342
  const body = (0, __rspack_external__contentful_optimization_api_schemas_66dcf407.parseWithFriendlyError)(__rspack_external__contentful_optimization_api_schemas_66dcf407.BatchInsightsEventArray, batches);
327
- if ('function' == typeof beaconHandler) {
328
- InsightsApiClient_logger.debug('Queueing events via beaconHandler');
329
- const beaconSuccessfullyQueued = beaconHandler(url, body);
330
- if (beaconSuccessfullyQueued) return true;
331
- InsightsApiClient_logger.warn('beaconHandler failed to queue events; events will be emitted immediately via fetch');
343
+ const serializedBody = JSON.stringify(body);
344
+ if (beacon) {
345
+ InsightsApiClient_logger.debug('Queueing events via beacon');
346
+ try {
347
+ const beaconSuccessfullyQueued = beacon(urlString, serializedBody);
348
+ if (beaconSuccessfullyQueued) return true;
349
+ InsightsApiClient_logger.warn(BEACON_FALLBACK_MESSAGE);
350
+ } catch (error) {
351
+ InsightsApiClient_logger.warn(BEACON_FALLBACK_MESSAGE, error);
352
+ }
332
353
  }
333
354
  const requestName = 'Event Batches';
334
355
  InsightsApiClient_logger.info(`Sending "${requestName}" request`);
335
356
  InsightsApiClient_logger.debug(`"${requestName}" request body:`, body);
336
357
  try {
337
- await this.fetch(url, {
358
+ await this.fetch(urlString, {
338
359
  method: 'POST',
339
360
  headers: {
340
361
  'Content-Type': 'application/json'
341
362
  },
342
- body: JSON.stringify(body),
343
- keepalive: true
363
+ body: serializedBody,
364
+ keepalive: !!beacon
344
365
  });
345
366
  InsightsApiClient_logger.debug(`"${requestName}" request successfully completed`);
346
367
  return true;