@contentful/optimization-api-client 0.1.0-alpha15 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <a href="https://www.contentful.com/developers/docs/personalization/">
3
- <img alt="Contentful Logo" title="Contentful" src="https://raw.githubusercontent.com/contentful/optimization/v0.1.0-alpha15/contentful-icon.png" width="150">
3
+ <img alt="Contentful Logo" title="Contentful" src="https://raw.githubusercontent.com/contentful/optimization/v0.1.0-alpha16/contentful-icon.png" width="150">
4
4
  </a>
5
5
  </p>
6
6
 
@@ -11,7 +11,7 @@
11
11
  <div align="center">
12
12
 
13
13
  [Guides](https://contentful.github.io/optimization/documents/Documentation.Guides.html) ·
14
- [Reference](https://contentful.github.io/optimization) · [Contributing](https://github.com/contentful/optimization/blob/v0.1.0-alpha15/CONTRIBUTING.md)
14
+ [Reference](https://contentful.github.io/optimization) · [Contributing](https://github.com/contentful/optimization/blob/v0.1.0-alpha16/CONTRIBUTING.md)
15
15
 
16
16
  </div>
17
17
 
@@ -84,27 +84,30 @@ Common Experience API options:
84
84
  | Option | Required? | Default | Description |
85
85
  | ----------------- | --------- | ------------------------------------- | ----------------------------------------------- |
86
86
  | `baseUrl` | No | `'https://experience.ninetailed.co/'` | Base URL for the Experience API |
87
- | `enabledFeatures` | No | `['ip-enrichment', 'location']` | Experience API features for each request |
87
+ | `enabledFeatures` | No | `['ip-enrichment', 'location']` | Experience API features for mutation requests |
88
88
  | `ip` | No | `undefined` | IP address override for Experience API analysis |
89
89
  | `locale` | No | API default | Locale query parameter for localized responses |
90
- | `plainText` | No | `false` | Sends performance-critical endpoints as text |
90
+ | `plainText` | No | Endpoint-specific | Sends single-profile mutation endpoints as text |
91
91
  | `preflight` | No | `false` | Aggregates a profile state without storing it |
92
92
 
93
- All Experience options except `baseUrl` can also be provided per request. `locale` is sent as the
94
- Experience API `locale` query parameter and can localize profile fields such as `location.city` and
95
- `location.country`. Higher-level SDK merge-tag helpers resolve against the profile values returned
96
- by the Experience API, so applications that render localized Contentful entries commonly pass the
97
- same locale used for the CDA entry fetch. Pass a valid locale tag; invalid locale syntax can fail
98
- Experience API request validation. See
93
+ Experience mutation request options except `baseUrl` can also be provided per mutation request.
94
+ `getProfile` is a read request and only uses `locale` from per-call options; mutation-only options
95
+ such as `enabledFeatures`, `ip`, `plainText`, and `preflight` do not apply. Single-profile mutation
96
+ requests default to `plainText: true` and send `text/plain` unless overridden. Batch profile updates
97
+ with `upsertManyProfiles` are the JSON-default exception and use `plainText: false` by default.
98
+ `locale` is sent as the Experience API `locale` query parameter and can localize profile fields such
99
+ as `location.city` and `location.country`. Higher-level SDK merge-tag helpers resolve against the
100
+ profile values returned by the Experience API, so applications that render localized Contentful
101
+ entries commonly pass the same locale used for the CDA entry fetch. Pass a valid locale tag; invalid
102
+ locale syntax can fail Experience API request validation. See
99
103
  [Locale handling in the Optimization SDK Suite](https://contentful.github.io/optimization/documents/Documentation.Concepts.Locale_handling_in_the_Optimization_SDK_Suite.html)
100
104
  for how this request locale relates to Contentful and SDK-resolved locales.
101
105
 
102
106
  Common Insights API options:
103
107
 
104
- | Option | Required? | Default | Description |
105
- | --------------- | --------- | ------------------------------------------ | ----------------------------------------------------- |
106
- | `baseUrl` | No | `'https://ingest.insights.ninetailed.co/'` | Base URL for the Insights API |
107
- | `beaconHandler` | No | `undefined` | Custom handler for enqueueing event batches if needed |
108
+ | Option | Required? | Default | Description |
109
+ | --------- | --------- | ------------------------------------------ | ----------------------------- |
110
+ | `baseUrl` | No | `'https://ingest.insights.ninetailed.co/'` | Base URL for the Insights API |
108
111
 
109
112
  Common `fetchOptions` are `fetchMethod`, `requestTimeout`, `retries`, `intervalTimeout`,
110
113
  `onFailedAttempt`, and `onRequestTimeout`. Default retries intentionally apply only to HTTP `503`
@@ -137,13 +140,16 @@ Common methods include `getProfile`, `createProfile`, `updateProfile`, `upsertPr
137
140
  Insights API methods are scoped to `client.insights` and send analytics event batches:
138
141
 
139
142
  ```ts
140
- await client.insights.sendBatchEvents({
141
- profile,
142
- events: [viewEvent],
143
- })
143
+ await client.insights.sendBatchEvents([
144
+ {
145
+ profile,
146
+ events: [viewEvent],
147
+ },
148
+ ])
144
149
  ```
145
150
 
146
- Insights endpoints do not return response data.
151
+ Insights endpoints do not return response data. For last-chance browser lifecycle delivery, pass a
152
+ per-call `beacon` sender that receives the request URL and already serialized body.
147
153
 
148
154
  ### Fetch helpers
149
155
 
@@ -161,8 +167,8 @@ Use generated reference docs for helper signatures and callback payloads.
161
167
 
162
168
  - [API Client generated reference](https://contentful.github.io/optimization/modules/_contentful_optimization-api-client.html) -
163
169
  exported API reference
164
- - [API Schemas](https://github.com/contentful/optimization/blob/v0.1.0-alpha15/packages/universal/api-schemas/README.md) - runtime validation schemas and inferred API types
165
- - [Optimization Core SDK](https://github.com/contentful/optimization/blob/v0.1.0-alpha15/packages/universal/core-sdk/README.md) - platform-agnostic SDK layer that composes this
170
+ - [API Schemas](https://github.com/contentful/optimization/blob/v0.1.0-alpha16/packages/universal/api-schemas/README.md) - runtime validation schemas and inferred API types
171
+ - [Optimization Core SDK](https://github.com/contentful/optimization/blob/v0.1.0-alpha16/packages/universal/core-sdk/README.md) - platform-agnostic SDK layer that composes this
166
172
  client
167
173
  - [Choosing the right SDK](https://contentful.github.io/optimization/documents/Documentation.Guides.choosing-the-right-sdk.html) -
168
174
  package selection guidance for application integrations
@@ -1,5 +1,33 @@
1
1
  THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED IN PORTIONS OF THIS PRODUCT
2
2
 
3
+ The following software may be included in this product: @babel/runtime (7.28.6)
4
+ This software contains the following license and notice below:
5
+
6
+ MIT License
7
+
8
+ Copyright (c) 2014-present Sebastian McKenzie and other contributors
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining
11
+ a copy of this software and associated documentation files (the
12
+ "Software"), to deal in the Software without restriction, including
13
+ without limitation the rights to use, copy, modify, merge, publish,
14
+ distribute, sublicense, and/or sell copies of the Software, and to
15
+ permit persons to whom the Software is furnished to do so, subject to
16
+ the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be
19
+ included in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
+
29
+ ---
30
+
3
31
  The following software may be included in this product: @contentful/content-source-maps (0.11.44)
4
32
  This software contains the following license and notice below:
5
33
 
@@ -54,6 +82,113 @@ SOFTWARE.
54
82
 
55
83
  ---
56
84
 
85
+ The following software may be included in this product: @contentful/rich-text-types (17.2.5)
86
+ This software contains the following license and notice below:
87
+
88
+ MIT License
89
+
90
+ Copyright (c) 2018 Contentful
91
+
92
+ Permission is hereby granted, free of charge, to any person obtaining a copy
93
+ of this software and associated documentation files (the "Software"), to deal
94
+ in the Software without restriction, including without limitation the rights
95
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
96
+ copies of the Software, and to permit persons to whom the Software is
97
+ furnished to do so, subject to the following conditions:
98
+
99
+ The above copyright notice and this permission notice shall be included in all
100
+ copies or substantial portions of the Software.
101
+
102
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
103
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
104
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
105
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
106
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
107
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
108
+ SOFTWARE.
109
+
110
+ ---
111
+
112
+ The following software may be included in this product: @lingui/core (5.9.2)
113
+ This software contains the following license and notice below:
114
+
115
+ The MIT License (MIT)
116
+
117
+ Copyright (c) 2017-2022 Tomáš Ehrlich, (c) 2022-2023 Crowdin.
118
+
119
+ Permission is hereby granted, free of charge, to any person obtaining a copy
120
+ of this software and associated documentation files (the "Software"), to deal
121
+ in the Software without restriction, including without limitation the rights
122
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
123
+ copies of the Software, and to permit persons to whom the Software is
124
+ furnished to do so, subject to the following conditions:
125
+
126
+ The above copyright notice and this permission notice shall be included in
127
+ all copies or substantial portions of the Software.
128
+
129
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
130
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
132
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
133
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
134
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
135
+ THE SOFTWARE.
136
+
137
+ ---
138
+
139
+ The following software may be included in this product: @lingui/message-utils (5.9.2)
140
+ This software contains the following license and notice below:
141
+
142
+ The MIT License (MIT)
143
+
144
+ Copyright (c) 2017-2022 Tomáš Ehrlich, (c) 2022-2023 Crowdin.
145
+
146
+ Permission is hereby granted, free of charge, to any person obtaining a copy
147
+ of this software and associated documentation files (the "Software"), to deal
148
+ in the Software without restriction, including without limitation the rights
149
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
150
+ copies of the Software, and to permit persons to whom the Software is
151
+ furnished to do so, subject to the following conditions:
152
+
153
+ The above copyright notice and this permission notice shall be included in
154
+ all copies or substantial portions of the Software.
155
+
156
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
158
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
159
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
160
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
161
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
162
+ THE SOFTWARE.
163
+
164
+ ---
165
+
166
+ The following software may be included in this product: @messageformat/parser (5.1.1)
167
+ This software contains the following license and notice below:
168
+
169
+ Copyright OpenJS Foundation and contributors, https://openjsf.org/
170
+
171
+ Permission is hereby granted, free of charge, to any person obtaining
172
+ a copy of this software and associated documentation files (the
173
+ "Software"), to deal in the Software without restriction, including
174
+ without limitation the rights to use, copy, modify, merge, publish,
175
+ distribute, sublicense, and/or sell copies of the Software, and to
176
+ permit persons to whom the Software is furnished to do so, subject to
177
+ the following conditions:
178
+
179
+ The above copyright notice and this permission notice shall be
180
+ included in all copies or substantial portions of the Software.
181
+
182
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
183
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
184
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
185
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
186
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
187
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
188
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
189
+
190
+ ---
191
+
57
192
  The following software may be included in this product: @rollup/rollup-linux-x64-gnu (4.60.1)
58
193
  This software contains the following license and notice below:
59
194
 
@@ -512,37 +647,6 @@ SOFTWARE.
512
647
 
513
648
  ---
514
649
 
515
- The following software may be included in this product: es-toolkit (1.46.0)
516
- This software contains the following license and notice below:
517
-
518
- MIT License
519
-
520
- Copyright (c) 2024 Viva Republica, Inc
521
-
522
- Copyright OpenJS Foundation and other contributors
523
-
524
- Parts of the test suite and compatibility layer in `es-toolkit/compat` are derived from Lodash (https://github.com/lodash/lodash) by the OpenJS Foundation (https://openjsf.org/) and Underscore.js by Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors (http://underscorejs.org/)
525
-
526
- Permission is hereby granted, free of charge, to any person obtaining a copy
527
- of this software and associated documentation files (the "Software"), to deal
528
- in the Software without restriction, including without limitation the rights
529
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
530
- copies of the Software, and to permit persons to whom the Software is
531
- furnished to do so, subject to the following conditions:
532
-
533
- The above copyright notice and this permission notice shall be included in all
534
- copies or substantial portions of the Software.
535
-
536
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
537
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
538
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
539
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
540
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
541
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
542
- SOFTWARE.
543
-
544
- ---
545
-
546
650
  The following software may be included in this product: fast-copy (3.0.2)
547
651
  This software contains the following license and notice below:
548
652
 
@@ -860,6 +964,49 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
860
964
 
861
965
  ---
862
966
 
967
+ The following software may be included in this product: is-plain-obj (3.0.0)
968
+ This software contains the following license and notice below:
969
+
970
+ MIT License
971
+
972
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
973
+
974
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
975
+
976
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
977
+
978
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
979
+
980
+ ---
981
+
982
+ The following software may be included in this product: js-sha256 (0.10.1)
983
+ This software contains the following license and notice below:
984
+
985
+ Copyright (c) 2014-2023 Chen, Yi-Cyuan
986
+
987
+ MIT License
988
+
989
+ Permission is hereby granted, free of charge, to any person obtaining
990
+ a copy of this software and associated documentation files (the
991
+ "Software"), to deal in the Software without restriction, including
992
+ without limitation the rights to use, copy, modify, merge, publish,
993
+ distribute, sublicense, and/or sell copies of the Software, and to
994
+ permit persons to whom the Software is furnished to do so, subject to
995
+ the following conditions:
996
+
997
+ The above copyright notice and this permission notice shall be
998
+ included in all copies or substantial portions of the Software.
999
+
1000
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1001
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1002
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1003
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
1004
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
1005
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1006
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1007
+
1008
+ ---
1009
+
863
1010
  The following software may be included in this product: json-pointer (0.6.2)
864
1011
  This software contains the following license and notice below:
865
1012
 
@@ -1677,6 +1824,41 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1677
1824
 
1678
1825
  ---
1679
1826
 
1827
+ The following software may be included in this product: moo (0.5.3)
1828
+ This software contains the following license and notice below:
1829
+
1830
+ BSD 3-Clause License
1831
+
1832
+ Copyright (c) 2017, Tim Radvan (tjvr)
1833
+ All rights reserved.
1834
+
1835
+ Redistribution and use in source and binary forms, with or without
1836
+ modification, are permitted provided that the following conditions are met:
1837
+
1838
+ * Redistributions of source code must retain the above copyright notice, this
1839
+ list of conditions and the following disclaimer.
1840
+
1841
+ * Redistributions in binary form must reproduce the above copyright notice,
1842
+ this list of conditions and the following disclaimer in the documentation
1843
+ and/or other materials provided with the distribution.
1844
+
1845
+ * Neither the name of the copyright holder nor the names of its
1846
+ contributors may be used to endorse or promote products derived from
1847
+ this software without specific prior written permission.
1848
+
1849
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1850
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1851
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1852
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1853
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1854
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1855
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1856
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1857
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1858
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1859
+
1860
+ ---
1861
+
1680
1862
  The following software may be included in this product: qs (6.15.0)
1681
1863
  This software contains the following license and notice below:
1682
1864
 
package/dist/index.cjs CHANGED
@@ -159,6 +159,16 @@ var __webpack_exports__ = {};
159
159
  });
160
160
  const optimization_api_schemas_namespaceObject = require("@contentful/optimization-api-schemas");
161
161
  var logger = __webpack_require__("./src/logger.ts");
162
+ const fetchInputToString = (input)=>{
163
+ if ('string' == typeof input) return input;
164
+ return input.url;
165
+ };
166
+ const MISSING_FETCH_METHOD_MESSAGE = 'No fetch implementation available. Provide a fetchMethod.';
167
+ function resolveFetchMethod(fetchMethod) {
168
+ if (fetchMethod) return fetchMethod;
169
+ if ('function' == typeof globalThis.fetch) return globalThis.fetch.bind(globalThis);
170
+ throw new Error(MISSING_FETCH_METHOD_MESSAGE);
171
+ }
162
172
  const createRetryFetchMethod_logger = (0, logger.createScopedLogger)('ApiClient:Retry');
163
173
  const DEFAULT_INTERVAL_TIMEOUT = 0;
164
174
  const DEFAULT_RETRY_COUNT = 1;
@@ -172,22 +182,23 @@ var __webpack_exports__ = {};
172
182
  this.status = status;
173
183
  }
174
184
  }
175
- function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod = fetch, init, url }) {
185
+ function createRetryFetchCallback({ apiName = 'Optimization', controller, fetchMethod, init, url }) {
176
186
  return async ()=>{
187
+ const urlLabel = fetchInputToString(url);
177
188
  try {
178
189
  const response = await fetchMethod(url, init);
179
- 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);
190
+ if (response.status === RETRY_RESPONSE_STATUS) throw new HttpError(`${apiName} API request to "${urlLabel}" failed with status: "[${response.status}] ${response.statusText}".`, RETRY_RESPONSE_STATUS);
180
191
  if (!response.ok) {
181
- const httpError = new Error(`Request to "${url.toString()}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
192
+ const httpError = new Error(`Request to "${urlLabel}" failed with status: [${response.status}] ${response.statusText} - traceparent: ${response.headers.get('traceparent')}`);
182
193
  createRetryFetchMethod_logger.error('Request failed with non-OK status:', httpError);
183
194
  controller.abort();
184
195
  return;
185
196
  }
186
- createRetryFetchMethod_logger.debug(`Response from "${url.toString()}":`, response);
197
+ createRetryFetchMethod_logger.debug(`Response from "${urlLabel}":`, response);
187
198
  return response;
188
199
  } catch (error) {
189
200
  if (error instanceof HttpError && error.status === RETRY_RESPONSE_STATUS) throw error;
190
- createRetryFetchMethod_logger.error(`Request to "${url.toString()}" failed:`, error);
201
+ createRetryFetchMethod_logger.error(`Request to "${urlLabel}" failed:`, error);
191
202
  controller.abort();
192
203
  }
193
204
  };
@@ -200,14 +211,15 @@ var __webpack_exports__ = {};
200
211
  }, intervalTimeout);
201
212
  await promise;
202
213
  }
203
- function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
214
+ function createRetryFetchMethod({ apiName = 'Optimization', fetchMethod, intervalTimeout = DEFAULT_INTERVAL_TIMEOUT, onFailedAttempt, retries = DEFAULT_RETRY_COUNT } = {}) {
215
+ const resolvedFetchMethod = resolveFetchMethod(fetchMethod);
204
216
  return async (url, init)=>{
205
217
  const controller = new AbortController();
206
218
  const maxAttempts = retries + 1;
207
219
  const attemptFetch = createRetryFetchCallback({
208
220
  apiName,
209
221
  controller,
210
- fetchMethod,
222
+ fetchMethod: resolvedFetchMethod,
211
223
  init,
212
224
  url
213
225
  });
@@ -227,28 +239,32 @@ var __webpack_exports__ = {};
227
239
  if (0 === retriesLeft) throw error;
228
240
  await delayRetry(intervalTimeout);
229
241
  }
230
- throw new Error(`${apiName} API request to "${url.toString()}" may not be retried.`);
242
+ throw new Error(`${apiName} API request to "${fetchInputToString(url)}" may not be retried.`);
231
243
  };
232
244
  }
233
245
  const createTimeoutFetchMethod_logger = (0, logger.createScopedLogger)('ApiClient:Timeout');
234
246
  const DEFAULT_REQUEST_TIMEOUT = 3000;
235
- function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod = fetch, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
247
+ function isFetchAbortSignal(signal) {
248
+ return 'object' == typeof signal && null !== signal;
249
+ }
250
+ function createTimeoutFetchMethod({ apiName = 'Optimization', fetchMethod, onRequestTimeout, requestTimeout = DEFAULT_REQUEST_TIMEOUT } = {}) {
251
+ const resolvedFetchMethod = resolveFetchMethod(fetchMethod);
236
252
  return async (url, init)=>{
237
253
  const controller = new AbortController();
238
254
  const id = setTimeout(()=>{
239
255
  if ('function' == typeof onRequestTimeout) onRequestTimeout({
240
256
  apiName
241
257
  });
242
- else createTimeoutFetchMethod_logger.error(`Request to "${url.toString()}" timed out`, new Error('Request timeout'));
258
+ else createTimeoutFetchMethod_logger.error(`Request to "${fetchInputToString(url)}" timed out`, new Error('Request timeout'));
243
259
  controller.abort();
244
260
  }, requestTimeout);
261
+ const { signal } = controller;
262
+ if (!isFetchAbortSignal(signal)) throw new Error('AbortController signal is not compatible with fetch.');
245
263
  const requestInit = {
246
- ...init
264
+ ...init,
265
+ signal
247
266
  };
248
- Object.assign(requestInit, {
249
- signal: controller.signal
250
- });
251
- const response = await fetchMethod(url, requestInit);
267
+ const response = await resolvedFetchMethod(url, requestInit);
252
268
  clearTimeout(id);
253
269
  return response;
254
270
  };
@@ -272,7 +288,7 @@ var __webpack_exports__ = {};
272
288
  create: createProtectedFetchMethod
273
289
  };
274
290
  const fetch_Fetch = Fetch;
275
- const src_fetch = fetch_Fetch;
291
+ const fetch = fetch_Fetch;
276
292
  const ApiClientBase_logger = (0, logger.createScopedLogger)('ApiClient');
277
293
  const DEFAULT_ENVIRONMENT = 'main';
278
294
  class ApiClientBase {
@@ -284,7 +300,7 @@ var __webpack_exports__ = {};
284
300
  this.clientId = clientId;
285
301
  this.environment = environment ?? DEFAULT_ENVIRONMENT;
286
302
  this.name = name;
287
- this.fetch = src_fetch.create({
303
+ this.fetch = fetch.create({
288
304
  ...fetchOptions ?? {},
289
305
  apiName: name
290
306
  });
@@ -469,37 +485,42 @@ var __webpack_exports__ = {};
469
485
  }
470
486
  }
471
487
  const InsightsApiClient_logger = (0, logger.createScopedLogger)('ApiClient:Insights');
488
+ const BEACON_FALLBACK_MESSAGE = 'beacon failed; falling back to fetch';
472
489
  const INSIGHTS_BASE_URL = 'https://ingest.insights.ninetailed.co/';
473
490
  class InsightsApiClient extends src_ApiClientBase {
474
491
  baseUrl;
475
- beaconHandler;
476
492
  constructor(config){
477
493
  super('Insights', config);
478
- const { baseUrl, beaconHandler } = config;
494
+ const { baseUrl } = config;
479
495
  this.baseUrl = baseUrl || INSIGHTS_BASE_URL;
480
- this.beaconHandler = beaconHandler;
481
496
  }
482
497
  async sendBatchEvents(batches, options = {}) {
483
- const { beaconHandler = this.beaconHandler } = options;
498
+ const { beacon } = options;
484
499
  const url = new URL(`v1/organizations/${this.clientId}/environments/${this.environment}/events`, this.baseUrl);
500
+ const urlString = url.toString();
485
501
  const body = (0, optimization_api_schemas_namespaceObject.parseWithFriendlyError)(optimization_api_schemas_namespaceObject.BatchInsightsEventArray, batches);
486
- if ('function' == typeof beaconHandler) {
487
- InsightsApiClient_logger.debug('Queueing events via beaconHandler');
488
- const beaconSuccessfullyQueued = beaconHandler(url, body);
489
- if (beaconSuccessfullyQueued) return true;
490
- InsightsApiClient_logger.warn('beaconHandler failed to queue events; events will be emitted immediately via fetch');
502
+ const serializedBody = JSON.stringify(body);
503
+ if (beacon) {
504
+ InsightsApiClient_logger.debug('Queueing events via beacon');
505
+ try {
506
+ const beaconSuccessfullyQueued = beacon(urlString, serializedBody);
507
+ if (beaconSuccessfullyQueued) return true;
508
+ InsightsApiClient_logger.warn(BEACON_FALLBACK_MESSAGE);
509
+ } catch (error) {
510
+ InsightsApiClient_logger.warn(BEACON_FALLBACK_MESSAGE, error);
511
+ }
491
512
  }
492
513
  const requestName = 'Event Batches';
493
514
  InsightsApiClient_logger.info(`Sending "${requestName}" request`);
494
515
  InsightsApiClient_logger.debug(`"${requestName}" request body:`, body);
495
516
  try {
496
- await this.fetch(url, {
517
+ await this.fetch(urlString, {
497
518
  method: 'POST',
498
519
  headers: {
499
520
  'Content-Type': 'application/json'
500
521
  },
501
- body: JSON.stringify(body),
502
- keepalive: true
522
+ body: serializedBody,
523
+ keepalive: !!beacon
503
524
  });
504
525
  InsightsApiClient_logger.debug(`"${requestName}" request successfully completed`);
505
526
  return true;