@adobe/alloy 2.36.0 → 2.36.1
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/alloy.js +143 -55
- package/dist/alloy.min.js +2 -2
- package/dist/types/browser/src/services/injectSendFetchRequest.d.ts +7 -3
- package/dist/types/core/src/components/RulesEngine/types.d.ts +1 -0
- package/dist/types/core/src/core/network/injectSendNetworkRequest.d.ts +2 -1
- package/dist/types/core/src/services/types.d.ts +17 -1
- package/dist/types/core/src/utils/request/createRequest.d.ts +1 -0
- package/dist/types/core/src/utils/request/types.d.ts +2 -0
- package/package.json +5 -3
- package/src/services/createBrowserNetworkService.js +1 -1
- package/src/services/injectSendBeaconRequest.js +3 -1
- package/src/services/injectSendFetchRequest.js +41 -4
package/dist/alloy.js
CHANGED
|
@@ -3750,7 +3750,14 @@
|
|
|
3750
3750
|
/**
|
|
3751
3751
|
* Send a network request and returns details about the response.
|
|
3752
3752
|
*/
|
|
3753
|
-
return ({
|
|
3753
|
+
return ({
|
|
3754
|
+
requestId,
|
|
3755
|
+
url,
|
|
3756
|
+
payload,
|
|
3757
|
+
useSendBeacon,
|
|
3758
|
+
useKeepalive,
|
|
3759
|
+
headers,
|
|
3760
|
+
}) => {
|
|
3754
3761
|
// We want to log raw payload and event data rather than
|
|
3755
3762
|
// our fancy wrapper objects. Calling payload.toJSON() is
|
|
3756
3763
|
// insufficient to get all the nested raw data, because it's
|
|
@@ -3771,53 +3778,55 @@
|
|
|
3771
3778
|
// navigator.sendBeacon() has no way to attach custom headers, so a
|
|
3772
3779
|
// request that needs any (e.g. authenticated Server API requests)
|
|
3773
3780
|
// must always go through fetch, regardless of useSendBeacon.
|
|
3774
|
-
const
|
|
3775
|
-
useSendBeacon && !headers
|
|
3781
|
+
const request =
|
|
3782
|
+
useSendBeacon && !headers
|
|
3783
|
+
? sendBeaconRequest(url, stringifiedPayload)
|
|
3784
|
+
: sendFetchRequest(url, stringifiedPayload, headers, {
|
|
3785
|
+
keepalive: Boolean(useKeepalive),
|
|
3786
|
+
});
|
|
3776
3787
|
|
|
3777
|
-
return
|
|
3778
|
-
|
|
3779
|
-
|
|
3788
|
+
return request.then((response) => {
|
|
3789
|
+
const requestIsRetryable = isRequestRetryable({
|
|
3790
|
+
response,
|
|
3791
|
+
retriesAttempted,
|
|
3792
|
+
});
|
|
3793
|
+
|
|
3794
|
+
if (requestIsRetryable) {
|
|
3795
|
+
const requestRetryDelay = getRequestRetryDelay({
|
|
3780
3796
|
response,
|
|
3781
3797
|
retriesAttempted,
|
|
3782
3798
|
});
|
|
3799
|
+
return new Promise((resolve) => {
|
|
3800
|
+
setTimeout(() => {
|
|
3801
|
+
resolve(executeRequest(retriesAttempted + 1));
|
|
3802
|
+
}, requestRetryDelay);
|
|
3803
|
+
});
|
|
3804
|
+
}
|
|
3783
3805
|
|
|
3784
|
-
|
|
3785
|
-
const requestRetryDelay = getRequestRetryDelay({
|
|
3786
|
-
response,
|
|
3787
|
-
retriesAttempted,
|
|
3788
|
-
});
|
|
3789
|
-
return new Promise((resolve) => {
|
|
3790
|
-
setTimeout(() => {
|
|
3791
|
-
resolve(executeRequest(retriesAttempted + 1));
|
|
3792
|
-
}, requestRetryDelay);
|
|
3793
|
-
});
|
|
3794
|
-
}
|
|
3795
|
-
|
|
3796
|
-
let parsedBody;
|
|
3806
|
+
let parsedBody;
|
|
3797
3807
|
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3808
|
+
try {
|
|
3809
|
+
parsedBody = JSON.parse(response.body);
|
|
3810
|
+
} catch {
|
|
3811
|
+
// Non-JSON. Something went wrong.
|
|
3812
|
+
}
|
|
3803
3813
|
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3814
|
+
logger.logOnNetworkResponse({
|
|
3815
|
+
requestId,
|
|
3816
|
+
url,
|
|
3817
|
+
payload: parsedPayload,
|
|
3818
|
+
...response,
|
|
3819
|
+
parsedBody,
|
|
3820
|
+
retriesAttempted,
|
|
3821
|
+
});
|
|
3812
3822
|
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
);
|
|
3823
|
+
return {
|
|
3824
|
+
statusCode: response.statusCode,
|
|
3825
|
+
body: response.body,
|
|
3826
|
+
parsedBody,
|
|
3827
|
+
getHeader: response.getHeader,
|
|
3828
|
+
};
|
|
3829
|
+
});
|
|
3821
3830
|
};
|
|
3822
3831
|
|
|
3823
3832
|
return executeRequest().catch((error) => {
|
|
@@ -5229,6 +5238,15 @@
|
|
|
5229
5238
|
},
|
|
5230
5239
|
logOnNetworkResponse(data) {
|
|
5231
5240
|
notifyMonitors("onNetworkResponse", data);
|
|
5241
|
+
if (data.sentWithBeacon) {
|
|
5242
|
+
// sendBeacon only tells us the browser queued the request; there is
|
|
5243
|
+
// no server response to report.
|
|
5244
|
+
log(
|
|
5245
|
+
"info",
|
|
5246
|
+
`Request ${data.requestId}: Sent using sendBeacon. No response is available for sendBeacon requests. If the page navigates away, the browser keeps sending the request in the background, but its developer tools may show it as canceled.`,
|
|
5247
|
+
);
|
|
5248
|
+
return;
|
|
5249
|
+
}
|
|
5232
5250
|
const messagesSuffix =
|
|
5233
5251
|
data.parsedBody || data.body ? `response body:` : `no response body.`;
|
|
5234
5252
|
log(
|
|
@@ -5335,6 +5353,9 @@
|
|
|
5335
5353
|
* @param {RequestPayload} options.payload
|
|
5336
5354
|
* @param {function({isIdentityEstablished: boolean}): string} options.getAction
|
|
5337
5355
|
* @param {function({isIdentityEstablished: boolean}): boolean} options.getUseSendBeacon
|
|
5356
|
+
* @param {function(): boolean} [options.getUseKeepalive] Whether a fetch
|
|
5357
|
+
* request should be sent with `keepalive` so it survives a page unload.
|
|
5358
|
+
* Defaults to false.
|
|
5338
5359
|
* @param {string} [options.datastreamIdOverride]
|
|
5339
5360
|
* @param {string} [options.edgeSubPath]
|
|
5340
5361
|
*
|
|
@@ -5358,6 +5379,7 @@
|
|
|
5358
5379
|
payload,
|
|
5359
5380
|
getAction,
|
|
5360
5381
|
getUseSendBeacon,
|
|
5382
|
+
getUseKeepalive = () => false,
|
|
5361
5383
|
datastreamIdOverride,
|
|
5362
5384
|
edgeSubPath,
|
|
5363
5385
|
requestParams = {},
|
|
@@ -5383,6 +5405,9 @@
|
|
|
5383
5405
|
getUseSendBeacon() {
|
|
5384
5406
|
return getUseSendBeacon({ isIdentityEstablished });
|
|
5385
5407
|
},
|
|
5408
|
+
getUseKeepalive() {
|
|
5409
|
+
return getUseKeepalive();
|
|
5410
|
+
},
|
|
5386
5411
|
getEdgeSubPath() {
|
|
5387
5412
|
if (edgeSubPath) {
|
|
5388
5413
|
return edgeSubPath;
|
|
@@ -5451,9 +5476,9 @@
|
|
|
5451
5476
|
// No error will be thrown and an identity is established. This is good.
|
|
5452
5477
|
// 3. The document is unloaded and Alloy does not receive the empty response
|
|
5453
5478
|
// back from the collect endpoint before navigation is completed. In this
|
|
5454
|
-
// case, no error is thrown, but no identity was established
|
|
5455
|
-
//
|
|
5456
|
-
//
|
|
5479
|
+
// case, no error is thrown, but no identity was established. Because the
|
|
5480
|
+
// fetch is sent with `keepalive` (see getUseKeepalive below), the browser
|
|
5481
|
+
// still delivers the request to the server after the page unloads.
|
|
5457
5482
|
//
|
|
5458
5483
|
// The second approach seemed preferable.
|
|
5459
5484
|
return (
|
|
@@ -5462,6 +5487,12 @@
|
|
|
5462
5487
|
);
|
|
5463
5488
|
};
|
|
5464
5489
|
|
|
5490
|
+
// When the document may be unloading but we use fetch anyway (for example,
|
|
5491
|
+
// before an identity is established), send the fetch with `keepalive` so the
|
|
5492
|
+
// browser doesn't cancel the request when the page navigates away.
|
|
5493
|
+
const getUseKeepalive = () =>
|
|
5494
|
+
dataCollectionRequestPayload.getDocumentMayUnload();
|
|
5495
|
+
|
|
5465
5496
|
return createRequest({
|
|
5466
5497
|
payload: dataCollectionRequestPayload,
|
|
5467
5498
|
getAction({ isIdentityEstablished }) {
|
|
@@ -5470,6 +5501,7 @@
|
|
|
5470
5501
|
: "interact";
|
|
5471
5502
|
},
|
|
5472
5503
|
getUseSendBeacon,
|
|
5504
|
+
getUseKeepalive,
|
|
5473
5505
|
datastreamIdOverride,
|
|
5474
5506
|
});
|
|
5475
5507
|
};
|
|
@@ -6335,6 +6367,7 @@
|
|
|
6335
6367
|
url,
|
|
6336
6368
|
payload: outgoingPayload,
|
|
6337
6369
|
useSendBeacon: request.getUseSendBeacon(),
|
|
6370
|
+
useKeepalive: request.getUseKeepalive(),
|
|
6338
6371
|
headers,
|
|
6339
6372
|
});
|
|
6340
6373
|
})
|
|
@@ -6355,6 +6388,7 @@
|
|
|
6355
6388
|
url,
|
|
6356
6389
|
payload,
|
|
6357
6390
|
useSendBeacon: request.getUseSendBeacon(),
|
|
6391
|
+
useKeepalive: request.getUseKeepalive(),
|
|
6358
6392
|
});
|
|
6359
6393
|
}
|
|
6360
6394
|
return handleRequestFailure(onRequestFailureCallbackAggregator)(error);
|
|
@@ -7956,10 +7990,10 @@
|
|
|
7956
7990
|
governing permissions and limitations under the License.
|
|
7957
7991
|
*/
|
|
7958
7992
|
|
|
7959
|
-
// The 2.36.
|
|
7993
|
+
// The 2.36.1 keyword will be replace at alloy build time with the package.json version.
|
|
7960
7994
|
// see babel-plugin-version
|
|
7961
7995
|
|
|
7962
|
-
var libraryVersion = "2.36.
|
|
7996
|
+
var libraryVersion = "2.36.1";
|
|
7963
7997
|
|
|
7964
7998
|
/*
|
|
7965
7999
|
Copyright 2019 Adobe. All rights reserved.
|
|
@@ -10446,6 +10480,8 @@
|
|
|
10446
10480
|
const TYPE$1 = "type";
|
|
10447
10481
|
const VALID_EVENT_TYPES = [IAM_EVENT_TYPE, EVENT_TYPE, TYPE$1];
|
|
10448
10482
|
const VALID_EVENT_IDS = [IAM_ID, ID];
|
|
10483
|
+
const IAM_ACTION = "iam.action";
|
|
10484
|
+
const ACTION = "action";
|
|
10449
10485
|
const checkForHistoricalMatcher = (eventCount, matcherKey, value) => {
|
|
10450
10486
|
switch (matcherKey) {
|
|
10451
10487
|
case MatcherType.GREATER_THAN:
|
|
@@ -10481,6 +10517,10 @@
|
|
|
10481
10517
|
event[normalizedKeyName] = event[keyName];
|
|
10482
10518
|
delete event[keyName];
|
|
10483
10519
|
});
|
|
10520
|
+
if (!isUndefined(event[IAM_ACTION])) {
|
|
10521
|
+
event[ACTION] = event[IAM_ACTION];
|
|
10522
|
+
delete event[IAM_ACTION];
|
|
10523
|
+
}
|
|
10484
10524
|
return event;
|
|
10485
10525
|
};
|
|
10486
10526
|
function queryAndCountAnyEvent(events, context, options, from = 0, to = Infinity) {
|
|
@@ -11539,12 +11579,21 @@
|
|
|
11539
11579
|
const filteredItems = [];
|
|
11540
11580
|
proposition.items.forEach((item) => {
|
|
11541
11581
|
if (item.schema === EVENT_HISTORY_OPERATION) {
|
|
11582
|
+
const { content } = item.data;
|
|
11583
|
+
const event = {
|
|
11584
|
+
eventId: content["iam.id"],
|
|
11585
|
+
eventType: content["iam.eventType"],
|
|
11586
|
+
};
|
|
11587
|
+
|
|
11588
|
+
// Web SDK records interactions with an `action` (from
|
|
11589
|
+
// propositionAction.id), so carry it over to land in the same entry.
|
|
11590
|
+
if (content["iam.action"] !== undefined) {
|
|
11591
|
+
event.action = content["iam.action"];
|
|
11592
|
+
}
|
|
11593
|
+
|
|
11542
11594
|
result.push({
|
|
11543
11595
|
operation: item.data.operation,
|
|
11544
|
-
event
|
|
11545
|
-
eventId: item.data.content["iam.id"],
|
|
11546
|
-
eventType: item.data.content["iam.eventType"],
|
|
11547
|
-
},
|
|
11596
|
+
event,
|
|
11548
11597
|
});
|
|
11549
11598
|
} else {
|
|
11550
11599
|
filteredItems.push(item);
|
|
@@ -22117,9 +22166,23 @@
|
|
|
22117
22166
|
governing permissions and limitations under the License.
|
|
22118
22167
|
*/
|
|
22119
22168
|
|
|
22120
|
-
|
|
22121
|
-
|
|
22122
|
-
|
|
22169
|
+
/** @import { NetworkService } from "@adobe/alloy-core/services" */
|
|
22170
|
+
|
|
22171
|
+
/**
|
|
22172
|
+
* @param {Object} params
|
|
22173
|
+
* @param {typeof window.fetch} params.fetch
|
|
22174
|
+
* @param {{ info: (...args: any[]) => void }} params.logger
|
|
22175
|
+
* @returns {NetworkService["sendFetchRequest"]}
|
|
22176
|
+
*/
|
|
22177
|
+
var injectSendFetchRequest = ({ fetch, logger }) => {
|
|
22178
|
+
/**
|
|
22179
|
+
* @param {string} url
|
|
22180
|
+
* @param {string} body
|
|
22181
|
+
* @param {Record<string, string> | undefined} headers
|
|
22182
|
+
* @param {boolean} keepalive
|
|
22183
|
+
*/
|
|
22184
|
+
const startFetch = (url, body, headers, keepalive) =>
|
|
22185
|
+
fetch(url, {
|
|
22123
22186
|
method: "POST",
|
|
22124
22187
|
cache: "no-cache",
|
|
22125
22188
|
credentials: "include", // To set the cookie header in the request.
|
|
@@ -22129,7 +22192,30 @@
|
|
|
22129
22192
|
},
|
|
22130
22193
|
referrerPolicy: "no-referrer-when-downgrade",
|
|
22131
22194
|
body,
|
|
22132
|
-
|
|
22195
|
+
...(keepalive ? { keepalive: true } : {}),
|
|
22196
|
+
});
|
|
22197
|
+
|
|
22198
|
+
return (url, body, headers, { keepalive = false } = {}) => {
|
|
22199
|
+
let responsePromise = startFetch(url, body, headers, keepalive);
|
|
22200
|
+
|
|
22201
|
+
if (keepalive) {
|
|
22202
|
+
// Browsers reject keepalive requests whose body, together with every
|
|
22203
|
+
// other in-flight keepalive request and sendBeacon on the page, exceeds
|
|
22204
|
+
// 64 KiB. The rejection is a TypeError that looks the same as any other
|
|
22205
|
+
// network error ("Failed to fetch", "NetworkError when attempting to
|
|
22206
|
+
// fetch resource.", "Load failed") and arrives before anything is sent,
|
|
22207
|
+
// so retry once without keepalive. Only fetch() itself is covered here;
|
|
22208
|
+
// a failure while reading the response is not retried because the
|
|
22209
|
+
// server already received the request.
|
|
22210
|
+
responsePromise = responsePromise.catch(() => {
|
|
22211
|
+
logger.info(
|
|
22212
|
+
"Unable to send the request with `keepalive`; falling back to a regular `fetch`.",
|
|
22213
|
+
);
|
|
22214
|
+
return startFetch(url, body, headers, false);
|
|
22215
|
+
});
|
|
22216
|
+
}
|
|
22217
|
+
|
|
22218
|
+
return responsePromise.then((response) => {
|
|
22133
22219
|
return response.text().then((responseBody) => ({
|
|
22134
22220
|
statusCode: response.status,
|
|
22135
22221
|
// We expose headers through a function instead of creating an object
|
|
@@ -22166,13 +22252,15 @@
|
|
|
22166
22252
|
|
|
22167
22253
|
// Using sendBeacon, we technically don't get a response back from
|
|
22168
22254
|
// the server, but we'll resolve the promise with an object to maintain
|
|
22169
|
-
// consistency with other network strategies.
|
|
22255
|
+
// consistency with other network strategies. `sentWithBeacon` marks the
|
|
22256
|
+
// response as synthetic so it isn't logged as a real server response.
|
|
22170
22257
|
return Promise.resolve({
|
|
22171
22258
|
statusCode: 204,
|
|
22172
22259
|
getHeader() {
|
|
22173
22260
|
return null;
|
|
22174
22261
|
},
|
|
22175
22262
|
body: "",
|
|
22263
|
+
sentWithBeacon: true,
|
|
22176
22264
|
});
|
|
22177
22265
|
};
|
|
22178
22266
|
};
|
|
@@ -22196,7 +22284,7 @@
|
|
|
22196
22284
|
*/
|
|
22197
22285
|
const createBrowserNetworkService = ({ logger }) => {
|
|
22198
22286
|
const { fetch, navigator } = window;
|
|
22199
|
-
const sendFetchRequest = injectSendFetchRequest({ fetch });
|
|
22287
|
+
const sendFetchRequest = injectSendFetchRequest({ fetch, logger });
|
|
22200
22288
|
const sendBeaconRequest =
|
|
22201
22289
|
typeof navigator.sendBeacon === "function"
|
|
22202
22290
|
? injectSendBeaconRequest({
|