@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/README.md +27 -21
- package/THIRD_PARTY_NOTICES.txt +2038 -0
- package/dist/index.cjs +50 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -31
- package/dist/index.d.mts +25 -31
- package/dist/index.d.ts +25 -31
- package/dist/index.mjs +50 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -6
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 (
|
|
613
|
-
* return fetch(
|
|
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
|
|
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
|
|
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 `
|
|
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
|
-
*
|
|
722
|
+
* sender or a direct request is successfully sent, `false` otherwise.
|
|
727
723
|
*
|
|
728
724
|
* @remarks
|
|
729
|
-
* If a `
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
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
|
|
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
|
-
* //
|
|
740
|
+
* // Use Beacon for a last-chance lifecycle flush
|
|
745
741
|
* const success = await insightsClient.sendBatchEvents(batches, {
|
|
746
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
778
|
-
*
|
|
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
|
-
|
|
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 (
|
|
613
|
-
* return fetch(
|
|
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
|
|
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
|
|
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 `
|
|
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
|
-
*
|
|
722
|
+
* sender or a direct request is successfully sent, `false` otherwise.
|
|
727
723
|
*
|
|
728
724
|
* @remarks
|
|
729
|
-
* If a `
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
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
|
|
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
|
-
* //
|
|
740
|
+
* // Use Beacon for a last-chance lifecycle flush
|
|
745
741
|
* const success = await insightsClient.sendBatchEvents(batches, {
|
|
746
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
778
|
-
*
|
|
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
|
-
|
|
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 (
|
|
613
|
-
* return fetch(
|
|
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
|
|
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
|
|
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 `
|
|
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
|
-
*
|
|
722
|
+
* sender or a direct request is successfully sent, `false` otherwise.
|
|
727
723
|
*
|
|
728
724
|
* @remarks
|
|
729
|
-
* If a `
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
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
|
|
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
|
-
* //
|
|
740
|
+
* // Use Beacon for a last-chance lifecycle flush
|
|
745
741
|
* const success = await insightsClient.sendBatchEvents(batches, {
|
|
746
|
-
*
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
-
*
|
|
778
|
-
*
|
|
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
|
-
|
|
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
|
|
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 "${
|
|
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 "${
|
|
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 "${
|
|
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 "${
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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 {
|
|
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
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
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(
|
|
358
|
+
await this.fetch(urlString, {
|
|
338
359
|
method: 'POST',
|
|
339
360
|
headers: {
|
|
340
361
|
'Content-Type': 'application/json'
|
|
341
362
|
},
|
|
342
|
-
body:
|
|
343
|
-
keepalive:
|
|
363
|
+
body: serializedBody,
|
|
364
|
+
keepalive: !!beacon
|
|
344
365
|
});
|
|
345
366
|
InsightsApiClient_logger.debug(`"${requestName}" request successfully completed`);
|
|
346
367
|
return true;
|