@adobe/alloy 2.36.0-beta.1 → 2.36.1-beta.0
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 +124 -51
- package/dist/alloy.min.js +2 -2
- package/dist/types/browser/src/services/injectSendFetchRequest.d.ts +7 -3
- 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
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
declare function _default({ fetch }: {
|
|
2
|
-
fetch:
|
|
3
|
-
|
|
1
|
+
declare function _default({ fetch, logger }: {
|
|
2
|
+
fetch: typeof window.fetch;
|
|
3
|
+
logger: {
|
|
4
|
+
info: (...args: any[]) => void;
|
|
5
|
+
};
|
|
6
|
+
}): NetworkService["sendFetchRequest"];
|
|
4
7
|
export default _default;
|
|
8
|
+
import type { NetworkService } from "@adobe/alloy-core/services";
|
|
@@ -4,11 +4,12 @@ declare function _default({ logger, sendFetchRequest, sendBeaconRequest, isReque
|
|
|
4
4
|
sendBeaconRequest: any;
|
|
5
5
|
isRequestRetryable: any;
|
|
6
6
|
getRequestRetryDelay: any;
|
|
7
|
-
}): ({ requestId, url, payload, useSendBeacon, headers }: {
|
|
7
|
+
}): ({ requestId, url, payload, useSendBeacon, useKeepalive, headers, }: {
|
|
8
8
|
requestId: any;
|
|
9
9
|
url: any;
|
|
10
10
|
payload: any;
|
|
11
11
|
useSendBeacon: any;
|
|
12
|
+
useKeepalive: any;
|
|
12
13
|
headers: any;
|
|
13
14
|
}) => any;
|
|
14
15
|
export default _default;
|
|
@@ -2,8 +2,24 @@ export type NetworkResponse = {
|
|
|
2
2
|
statusCode: number;
|
|
3
3
|
body: string;
|
|
4
4
|
getHeader: (name: string) => (string | null);
|
|
5
|
+
/**
|
|
6
|
+
* `true` when the request was handed to `navigator.sendBeacon`. The browser
|
|
7
|
+
* gives no response for these, so `statusCode`, `body`, and `getHeader` are
|
|
8
|
+
* placeholders rather than values from the server.
|
|
9
|
+
*/
|
|
10
|
+
sentWithBeacon?: boolean | undefined;
|
|
11
|
+
};
|
|
12
|
+
export type SendFetchRequestOptions = {
|
|
13
|
+
/**
|
|
14
|
+
* Send the request with `keepalive` so the
|
|
15
|
+
* browser finishes it even if the page unloads. Implementations fall back to
|
|
16
|
+
* a regular request if the browser refuses (for example, when in-flight
|
|
17
|
+
* keepalive data on the page would exceed 64 KiB). Ignored where there is no
|
|
18
|
+
* page to unload (Node).
|
|
19
|
+
*/
|
|
20
|
+
keepalive?: boolean | undefined;
|
|
5
21
|
};
|
|
6
|
-
export type SendFetchRequest = (url: string, body: string) => Promise<NetworkResponse>;
|
|
22
|
+
export type SendFetchRequest = (url: string, body: string, headers?: Record<string, string>, options?: SendFetchRequestOptions) => Promise<NetworkResponse>;
|
|
7
23
|
export type SendBeaconRequest = (url: string, body: string) => Promise<NetworkResponse>;
|
|
8
24
|
export type NetworkService = {
|
|
9
25
|
/**
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* @property {function({isIdentityEstablished: boolean}): string} getAction
|
|
8
8
|
* @property {function(): string|undefined} getDatastreamIdOverride
|
|
9
9
|
* @property {Function} getUseSendBeacon
|
|
10
|
+
* @property {function(): boolean} getUseKeepalive
|
|
10
11
|
* @property {function(): string|undefined} getEdgeSubPath
|
|
11
12
|
* @property {Function} getUseIdThirdPartyDomain
|
|
12
13
|
* @property {Function} setUseIdThirdPartyDomain
|
|
@@ -55,6 +56,7 @@ export type Request = {
|
|
|
55
56
|
}) => string;
|
|
56
57
|
getDatastreamIdOverride: () => string | undefined;
|
|
57
58
|
getUseSendBeacon: Function;
|
|
59
|
+
getUseKeepalive: () => boolean;
|
|
58
60
|
getEdgeSubPath: () => string | undefined;
|
|
59
61
|
getUseIdThirdPartyDomain: Function;
|
|
60
62
|
setUseIdThirdPartyDomain: Function;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/alloy",
|
|
3
|
-
"version": "2.36.
|
|
3
|
+
"version": "2.36.1-beta.0",
|
|
4
4
|
"description": "Adobe Experience Platform Web SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"commander": "^14.0.2",
|
|
70
70
|
"rollup": "^4.60.3",
|
|
71
71
|
"rollup-plugin-license": "^3.7.1",
|
|
72
|
-
"@adobe/alloy-core": "^1.3.
|
|
72
|
+
"@adobe/alloy-core": "^1.3.1-beta.0"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"glob": "^13.0.6",
|
|
@@ -86,7 +86,9 @@
|
|
|
86
86
|
"release": "node scripts/release.mjs",
|
|
87
87
|
"build:types": "tsc -p jsconfig.json --declaration --emitDeclarationOnly --outDir dist/types --checkJs false --noEmit false",
|
|
88
88
|
"build": "pnpm run clean && rollup -c --environment BASE_CODE_MIN,STANDALONE,STANDALONE_MIN,SERVICE_WORKER,SERVICE_WORKER_MIN,UTILITY_EXPORTS,BUNDLESIZE && pnpm run build:types",
|
|
89
|
-
"build:watch": "
|
|
89
|
+
"build:watch": "rollup -c --watch --environment BASE_CODE_MIN,STANDALONE,SERVICE_WORKER,UTILITY_EXPORTS",
|
|
90
|
+
"dev:prepare": "rollup -c --environment BASE_CODE_MIN,STANDALONE,SERVICE_WORKER,UTILITY_EXPORTS",
|
|
91
|
+
"dev": "pnpm run build:watch",
|
|
90
92
|
"build:custom": "node scripts/alloyBuilder.js",
|
|
91
93
|
"test:functional": "pnpm exec playwright install chromium && EDGE_BASE_PATH=\"ee-pre-prd\" ALLOY_ENV=\"int\" testcafe playwright:chromium",
|
|
92
94
|
"test:functional:custom": "node ./scripts/runFunctionalTests.js",
|
|
@@ -21,7 +21,7 @@ import injectSendBeaconRequest from "./injectSendBeaconRequest.js";
|
|
|
21
21
|
*/
|
|
22
22
|
const createBrowserNetworkService = ({ logger }) => {
|
|
23
23
|
const { fetch, navigator } = window;
|
|
24
|
-
const sendFetchRequest = injectSendFetchRequest({ fetch });
|
|
24
|
+
const sendFetchRequest = injectSendFetchRequest({ fetch, logger });
|
|
25
25
|
const sendBeaconRequest =
|
|
26
26
|
typeof navigator.sendBeacon === "function"
|
|
27
27
|
? injectSendBeaconRequest({
|
|
@@ -20,13 +20,15 @@ export default ({ sendBeacon, sendFetchRequest, logger }) => {
|
|
|
20
20
|
|
|
21
21
|
// Using sendBeacon, we technically don't get a response back from
|
|
22
22
|
// the server, but we'll resolve the promise with an object to maintain
|
|
23
|
-
// consistency with other network strategies.
|
|
23
|
+
// consistency with other network strategies. `sentWithBeacon` marks the
|
|
24
|
+
// response as synthetic so it isn't logged as a real server response.
|
|
24
25
|
return Promise.resolve({
|
|
25
26
|
statusCode: 204,
|
|
26
27
|
getHeader() {
|
|
27
28
|
return null;
|
|
28
29
|
},
|
|
29
30
|
body: "",
|
|
31
|
+
sentWithBeacon: true,
|
|
30
32
|
});
|
|
31
33
|
};
|
|
32
34
|
};
|
|
@@ -10,9 +10,23 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
10
10
|
governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
/** @import { NetworkService } from "@adobe/alloy-core/services" */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {Object} params
|
|
17
|
+
* @param {typeof window.fetch} params.fetch
|
|
18
|
+
* @param {{ info: (...args: any[]) => void }} params.logger
|
|
19
|
+
* @returns {NetworkService["sendFetchRequest"]}
|
|
20
|
+
*/
|
|
21
|
+
export default ({ fetch, logger }) => {
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} url
|
|
24
|
+
* @param {string} body
|
|
25
|
+
* @param {Record<string, string> | undefined} headers
|
|
26
|
+
* @param {boolean} keepalive
|
|
27
|
+
*/
|
|
28
|
+
const startFetch = (url, body, headers, keepalive) =>
|
|
29
|
+
fetch(url, {
|
|
16
30
|
method: "POST",
|
|
17
31
|
cache: "no-cache",
|
|
18
32
|
credentials: "include", // To set the cookie header in the request.
|
|
@@ -22,7 +36,30 @@ export default ({ fetch }) => {
|
|
|
22
36
|
},
|
|
23
37
|
referrerPolicy: "no-referrer-when-downgrade",
|
|
24
38
|
body,
|
|
25
|
-
|
|
39
|
+
...(keepalive ? { keepalive: true } : {}),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return (url, body, headers, { keepalive = false } = {}) => {
|
|
43
|
+
let responsePromise = startFetch(url, body, headers, keepalive);
|
|
44
|
+
|
|
45
|
+
if (keepalive) {
|
|
46
|
+
// Browsers reject keepalive requests whose body, together with every
|
|
47
|
+
// other in-flight keepalive request and sendBeacon on the page, exceeds
|
|
48
|
+
// 64 KiB. The rejection is a TypeError that looks the same as any other
|
|
49
|
+
// network error ("Failed to fetch", "NetworkError when attempting to
|
|
50
|
+
// fetch resource.", "Load failed") and arrives before anything is sent,
|
|
51
|
+
// so retry once without keepalive. Only fetch() itself is covered here;
|
|
52
|
+
// a failure while reading the response is not retried because the
|
|
53
|
+
// server already received the request.
|
|
54
|
+
responsePromise = responsePromise.catch(() => {
|
|
55
|
+
logger.info(
|
|
56
|
+
"Unable to send the request with `keepalive`; falling back to a regular `fetch`.",
|
|
57
|
+
);
|
|
58
|
+
return startFetch(url, body, headers, false);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return responsePromise.then((response) => {
|
|
26
63
|
return response.text().then((responseBody) => ({
|
|
27
64
|
statusCode: response.status,
|
|
28
65
|
// We expose headers through a function instead of creating an object
|