@adobe/alloy 2.30.1-beta.21 → 2.30.1-beta.23
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/libEs5/components/Advertising/createComponent.js +7 -3
- package/libEs5/components/Advertising/handlers/sendAdConversion.js +11 -6
- package/libEs5/components/Advertising/index.js +2 -1
- package/libEs5/components/BrandConcierge/configValidators.js +25 -0
- package/libEs5/components/BrandConcierge/createSendConversationEvent.js +6 -4
- package/libEs5/components/BrandConcierge/createStreamParser.js +49 -14
- package/libEs5/components/BrandConcierge/createTimeoutWrapper.js +47 -20
- package/libEs5/components/BrandConcierge/index.js +3 -5
- package/libEs5/components/BrandConcierge/validateMessage.js +5 -2
- package/libEs5/components/Context/injectOneTimeAnalyticsReferrer.js +4 -1
- package/libEs5/components/Personalization/createFetchDataHandler.js +6 -1
- package/libEs5/components/Personalization/dom-actions/remapHeadOffers.js +5 -0
- package/libEs5/components/StreamingMedia/createMediaEventManager.js +1 -1
- package/libEs5/constants/libraryVersion.js +1 -1
- package/libEs5/core/createEvent.js +4 -0
- package/libEs5/core/edgeNetwork/injectSendEdgeNetworkRequest.js +23 -0
- package/libEs5/utils/clamp.js +25 -0
- package/libEs5/utils/filterObject.js +1 -1
- package/libEs5/utils/prepareConfigOverridesForEdge.js +4 -2
- package/libEs5/utils/request/createDataCollectionRequestPayload.js +3 -0
- package/libEs5/utils/request/createRequestParams.js +1 -0
- package/libEs5/utils/request/createRequestPayload.js +11 -1
- package/libEs5/utils/request/types.js +1 -0
- package/libEs6/components/Advertising/createComponent.js +7 -3
- package/libEs6/components/Advertising/handlers/sendAdConversion.js +11 -6
- package/libEs6/components/Advertising/index.js +2 -1
- package/libEs6/components/BrandConcierge/configValidators.js +22 -0
- package/libEs6/components/BrandConcierge/createSendConversationEvent.js +6 -4
- package/libEs6/components/BrandConcierge/createStreamParser.js +49 -14
- package/libEs6/components/BrandConcierge/createTimeoutWrapper.js +47 -20
- package/libEs6/components/BrandConcierge/index.js +3 -5
- package/libEs6/components/BrandConcierge/validateMessage.js +6 -3
- package/libEs6/components/Context/injectOneTimeAnalyticsReferrer.js +3 -1
- package/libEs6/components/Personalization/createFetchDataHandler.js +6 -1
- package/libEs6/components/Personalization/dom-actions/remapHeadOffers.js +6 -1
- package/libEs6/components/StreamingMedia/createMediaEventManager.js +1 -1
- package/libEs6/constants/libraryVersion.js +1 -1
- package/libEs6/core/createEvent.js +4 -0
- package/libEs6/core/edgeNetwork/injectSendEdgeNetworkRequest.js +23 -0
- package/libEs6/utils/clamp.js +22 -0
- package/libEs6/utils/filterObject.js +1 -1
- package/libEs6/utils/prepareConfigOverridesForEdge.js +4 -2
- package/libEs6/utils/request/createDataCollectionRequestPayload.js +3 -0
- package/libEs6/utils/request/createRequestParams.js +1 -0
- package/libEs6/utils/request/createRequestPayload.js +11 -1
- package/libEs6/utils/request/types.js +1 -0
- package/package.json +1 -1
- package/types/components/Advertising/createComponent.d.ts +3 -2
- package/types/components/Advertising/createComponent.d.ts.map +1 -1
- package/types/components/Advertising/handlers/sendAdConversion.d.ts +2 -1
- package/types/components/Advertising/handlers/sendAdConversion.d.ts.map +1 -1
- package/types/components/Advertising/index.d.ts +1 -1
- package/types/components/Advertising/index.d.ts.map +1 -1
- package/types/components/BrandConcierge/configValidators.d.ts +3 -0
- package/types/components/BrandConcierge/configValidators.d.ts.map +1 -0
- package/types/components/BrandConcierge/createSendConversationEvent.d.ts.map +1 -1
- package/types/components/BrandConcierge/createStreamParser.d.ts +5 -1
- package/types/components/BrandConcierge/createStreamParser.d.ts.map +1 -1
- package/types/components/BrandConcierge/createTimeoutWrapper.d.ts +4 -1
- package/types/components/BrandConcierge/createTimeoutWrapper.d.ts.map +1 -1
- package/types/components/BrandConcierge/index.d.ts +3 -2
- package/types/components/BrandConcierge/index.d.ts.map +1 -1
- package/types/components/BrandConcierge/validateMessage.d.ts.map +1 -1
- package/types/components/Context/injectOneTimeAnalyticsReferrer.d.ts.map +1 -1
- package/types/components/Personalization/createFetchDataHandler.d.ts.map +1 -1
- package/types/components/Personalization/dom-actions/remapHeadOffers.d.ts.map +1 -1
- package/types/core/createEvent.d.ts +1 -0
- package/types/core/createEvent.d.ts.map +1 -1
- package/types/core/edgeNetwork/injectSendEdgeNetworkRequest.d.ts.map +1 -1
- package/types/utils/clamp.d.ts +3 -0
- package/types/utils/clamp.d.ts.map +1 -0
- package/types/utils/prepareConfigOverridesForEdge.d.ts.map +1 -1
- package/types/utils/request/createDataCollectionRequestPayload.d.ts.map +1 -1
- package/types/utils/request/createRequestParams.d.ts.map +1 -1
- package/types/utils/request/createRequestPayload.d.ts.map +1 -1
- package/types/utils/request/types.d.ts +2 -0
- package/types/utils/request/types.d.ts.map +1 -1
|
@@ -20,7 +20,8 @@ var _default = ({
|
|
|
20
20
|
eventManager,
|
|
21
21
|
cookieManager,
|
|
22
22
|
adConversionHandler,
|
|
23
|
-
getBrowser
|
|
23
|
+
getBrowser,
|
|
24
|
+
consent
|
|
24
25
|
}) => {
|
|
25
26
|
const componentConfig = config.advertising;
|
|
26
27
|
const sendAdConversionHandler = (0, _sendAdConversion.default)({
|
|
@@ -29,12 +30,15 @@ var _default = ({
|
|
|
29
30
|
adConversionHandler,
|
|
30
31
|
logger,
|
|
31
32
|
componentConfig,
|
|
32
|
-
getBrowser
|
|
33
|
+
getBrowser,
|
|
34
|
+
consent
|
|
33
35
|
});
|
|
34
36
|
return {
|
|
35
37
|
lifecycle: {
|
|
36
38
|
onComponentsRegistered() {
|
|
37
|
-
return
|
|
39
|
+
// Fire-and-forget: don't return the promise so we don't block
|
|
40
|
+
// the configure command from resolving while waiting for consent.
|
|
41
|
+
sendAdConversionHandler();
|
|
38
42
|
},
|
|
39
43
|
onBeforeEvent: ({
|
|
40
44
|
event,
|
|
@@ -26,16 +26,21 @@ var _default = ({
|
|
|
26
26
|
adConversionHandler,
|
|
27
27
|
logger,
|
|
28
28
|
componentConfig,
|
|
29
|
-
getBrowser
|
|
29
|
+
getBrowser,
|
|
30
|
+
consent
|
|
30
31
|
}) => {
|
|
31
32
|
const activeAdvertiserIds = componentConfig?.advertiserSettings ? (0, _helpers.normalizeAdvertiser)(componentConfig.advertiserSettings) : "";
|
|
32
33
|
return async () => {
|
|
33
|
-
const {
|
|
34
|
-
skwcid,
|
|
35
|
-
efid
|
|
36
|
-
} = (0, _helpers.getUrlParams)();
|
|
37
|
-
const isClickThru = !!(skwcid || efid);
|
|
38
34
|
try {
|
|
35
|
+
// Wait for consent before any ad conversion processing.
|
|
36
|
+
// This ensures no advertising cookies are set without user consent.
|
|
37
|
+
// If consent is declined, awaitConsent() rejects and we exit gracefully.
|
|
38
|
+
await consent.awaitConsent();
|
|
39
|
+
const {
|
|
40
|
+
skwcid,
|
|
41
|
+
efid
|
|
42
|
+
} = (0, _helpers.getUrlParams)();
|
|
43
|
+
const isClickThru = !!(skwcid || efid);
|
|
39
44
|
if (isClickThru) {
|
|
40
45
|
// wait for click through to complete
|
|
41
46
|
return (0, _clickThroughHandler.default)({
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
var _constants = require("./constants.js");
|
|
5
|
+
var _index = require("../../utils/validation/index.js");
|
|
6
|
+
/*
|
|
7
|
+
Copyright 2026 Adobe. All rights reserved.
|
|
8
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
9
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
10
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
|
|
12
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
13
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
14
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
15
|
+
governing permissions and limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
var _default = exports.default = (0, _index.objectOf)({
|
|
18
|
+
conversation: (0, _index.objectOf)({
|
|
19
|
+
stickyConversationSession: (0, _index.boolean)().default(false),
|
|
20
|
+
streamTimeout: (0, _index.number)().integer().minimum(_constants.STREAM_START_TIMEOUT_MS).default(_constants.STREAM_START_TIMEOUT_MS)
|
|
21
|
+
}).default({
|
|
22
|
+
stickyConversationSession: false,
|
|
23
|
+
streamTimeout: _constants.STREAM_START_TIMEOUT_MS
|
|
24
|
+
})
|
|
25
|
+
});
|
|
@@ -35,7 +35,8 @@ var _default = ({
|
|
|
35
35
|
edgeDomain,
|
|
36
36
|
edgeBasePath,
|
|
37
37
|
datastreamId,
|
|
38
|
-
onBeforeEventSend
|
|
38
|
+
onBeforeEventSend,
|
|
39
|
+
conversation
|
|
39
40
|
} = config;
|
|
40
41
|
return options => {
|
|
41
42
|
let streamingEnabled = false;
|
|
@@ -134,11 +135,12 @@ var _default = ({
|
|
|
134
135
|
logger.info("onStreamResponse callback called with", response.getPayloadsByType("brand-concierge:conversation"));
|
|
135
136
|
onStreamResponse(response.getPayloadsByType("brand-concierge:conversation"));
|
|
136
137
|
};
|
|
137
|
-
const
|
|
138
|
-
onStreamResponseCallback
|
|
138
|
+
const timeoutWrapper = (0, _createTimeoutWrapper.default)({
|
|
139
|
+
onStreamResponseCallback,
|
|
140
|
+
streamTimeout: conversation.streamTimeout
|
|
139
141
|
});
|
|
140
142
|
const streamParser = (0, _createStreamParser.default)();
|
|
141
|
-
streamParser(response.body,
|
|
143
|
+
streamParser(response.body, timeoutWrapper);
|
|
142
144
|
});
|
|
143
145
|
});
|
|
144
146
|
};
|
|
@@ -19,6 +19,20 @@ var _default = () => {
|
|
|
19
19
|
const LINE_ENDING_REGEX = /\r\n|\r|\n/;
|
|
20
20
|
// Events are separated by blank lines (double line endings)
|
|
21
21
|
const EVENT_SEPARATOR_REGEX = /\r\n\r\n|\n\n|\r\r/;
|
|
22
|
+
// Ping comment format: `: ping` (colon followed immediately by "ping")
|
|
23
|
+
const PING_COMMENT = ": ping";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Check if an event block is a ping comment.
|
|
27
|
+
* Ping comments are SSE comments in the format `:ping`
|
|
28
|
+
*
|
|
29
|
+
* @param {string} eventData - Raw event data
|
|
30
|
+
* @returns {boolean} - True if this is a ping comment
|
|
31
|
+
*/
|
|
32
|
+
const isPingComment = eventData => {
|
|
33
|
+
const trimmed = eventData.trim();
|
|
34
|
+
return trimmed.startsWith(PING_COMMENT);
|
|
35
|
+
};
|
|
22
36
|
|
|
23
37
|
/**
|
|
24
38
|
* Parse a single SSE event from raw event data.
|
|
@@ -57,9 +71,16 @@ var _default = () => {
|
|
|
57
71
|
* Uses modern async iteration (for await...of) for clean, performant stream processing.
|
|
58
72
|
*
|
|
59
73
|
* @param {ReadableStream} stream - The readable stream from fetch response
|
|
60
|
-
* @param {
|
|
74
|
+
* @param {Object} callbacks - Callback functions for stream events
|
|
75
|
+
* @param {Function} callbacks.onEvent - Callback function called for each parsed event
|
|
76
|
+
* @param {Function} callbacks.onPing - Callback function called for ping comments
|
|
77
|
+
* @param {Function} callbacks.onComplete - Callback function called when stream ends
|
|
61
78
|
*/
|
|
62
|
-
return async (stream,
|
|
79
|
+
return async (stream, {
|
|
80
|
+
onEvent,
|
|
81
|
+
onPing,
|
|
82
|
+
onComplete
|
|
83
|
+
}) => {
|
|
63
84
|
const decoder = new TextDecoder(ENCODING);
|
|
64
85
|
let buffer = "";
|
|
65
86
|
try {
|
|
@@ -69,27 +90,41 @@ var _default = () => {
|
|
|
69
90
|
});
|
|
70
91
|
const events = buffer.split(EVENT_SEPARATOR_REGEX);
|
|
71
92
|
buffer = events.pop() || "";
|
|
72
|
-
for (const
|
|
73
|
-
const trimmedEvent =
|
|
74
|
-
if (trimmedEvent) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
for (const event of events) {
|
|
94
|
+
const trimmedEvent = event.trim();
|
|
95
|
+
if (!trimmedEvent) {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (isPingComment(trimmedEvent)) {
|
|
99
|
+
onPing();
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const parsedEvent = parseEventFromBuffer(trimmedEvent);
|
|
103
|
+
if (parsedEvent !== null) {
|
|
104
|
+
onEvent(parsedEvent);
|
|
79
105
|
}
|
|
80
106
|
}
|
|
81
107
|
}
|
|
82
108
|
const trimmedBuffer = buffer.trim();
|
|
83
|
-
if (trimmedBuffer) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
109
|
+
if (!trimmedBuffer) {
|
|
110
|
+
onComplete();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (isPingComment(trimmedBuffer)) {
|
|
114
|
+
onPing();
|
|
115
|
+
onComplete();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const event = parseEventFromBuffer(trimmedBuffer);
|
|
119
|
+
if (event !== null) {
|
|
120
|
+
onEvent(event);
|
|
88
121
|
}
|
|
122
|
+
onComplete();
|
|
89
123
|
} catch (error) {
|
|
90
124
|
onEvent({
|
|
91
125
|
error
|
|
92
126
|
});
|
|
127
|
+
onComplete();
|
|
93
128
|
}
|
|
94
129
|
};
|
|
95
130
|
};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
exports.default = void 0;
|
|
4
|
-
var _constants = require("./constants.js");
|
|
5
4
|
/*
|
|
6
5
|
Copyright 2025 Adobe. All rights reserved.
|
|
7
6
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -14,39 +13,67 @@ OF ANY KIND, either express or implied. See the License for the specific languag
|
|
|
14
13
|
governing permissions and limitations under the License.
|
|
15
14
|
*/
|
|
16
15
|
/**
|
|
17
|
-
* Creates a wrapper around a callback that implements a timeout
|
|
18
|
-
*
|
|
16
|
+
* Creates a wrapper around a callback that implements a rolling timeout.
|
|
17
|
+
* The timeout resets on every data event or ping. If no activity occurs
|
|
18
|
+
* within the timeout period, an error is passed to the callback.
|
|
19
19
|
* After timeout fires, all subsequent calls are ignored.
|
|
20
20
|
*
|
|
21
|
-
* @param {
|
|
22
|
-
* @
|
|
21
|
+
* @param {Object} options - Configuration options
|
|
22
|
+
* @param {Function} options.onStreamResponseCallback - The callback function to wrap
|
|
23
|
+
* @param {number} options.streamTimeout - Timeout duration in milliseconds
|
|
24
|
+
* @returns {Object} Object with onEvent, onPing, and onComplete handler functions
|
|
23
25
|
*/
|
|
24
26
|
var _default = ({
|
|
25
|
-
onStreamResponseCallback
|
|
27
|
+
onStreamResponseCallback,
|
|
28
|
+
streamTimeout
|
|
26
29
|
}) => {
|
|
27
|
-
const timeoutMs = _constants.STREAM_START_TIMEOUT_MS;
|
|
28
|
-
let firstCallMade = false;
|
|
29
30
|
let timedOut = false;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
let timeoutId;
|
|
32
|
+
const resetTimeout = () => {
|
|
33
|
+
clearTimeout(timeoutId);
|
|
34
|
+
timeoutId = setTimeout(() => {
|
|
33
35
|
timedOut = true;
|
|
34
36
|
onStreamResponseCallback({
|
|
35
37
|
error: {
|
|
36
38
|
message: "Stream timeout: No data received within 10 seconds"
|
|
37
39
|
}
|
|
38
40
|
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
}, streamTimeout);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Start initial timeout
|
|
45
|
+
resetTimeout();
|
|
46
|
+
return {
|
|
47
|
+
/**
|
|
48
|
+
* Handle data events from the stream parser.
|
|
49
|
+
* Resets the timeout and forwards the event to the callback.
|
|
50
|
+
*
|
|
51
|
+
* @param {Object} event - The parsed SSE event
|
|
52
|
+
*/
|
|
53
|
+
onEvent: event => {
|
|
54
|
+
if (timedOut) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
resetTimeout();
|
|
58
|
+
onStreamResponseCallback(event);
|
|
59
|
+
},
|
|
60
|
+
/**
|
|
61
|
+
* Handle ping events from the stream parser.
|
|
62
|
+
* Resets the timeout but does not forward anything to the callback.
|
|
63
|
+
*/
|
|
64
|
+
onPing: () => {
|
|
65
|
+
if (timedOut) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
resetTimeout();
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* Handle stream completion.
|
|
72
|
+
* Clears the timeout since the stream has ended successfully.
|
|
73
|
+
*/
|
|
74
|
+
onComplete: () => {
|
|
47
75
|
clearTimeout(timeoutId);
|
|
48
76
|
}
|
|
49
|
-
onStreamResponseCallback(event);
|
|
50
77
|
};
|
|
51
78
|
};
|
|
52
79
|
exports.default = _default;
|
|
@@ -7,9 +7,9 @@ var _createBuildEndpointUrl = require("./createBuildEndpointUrl.js");
|
|
|
7
7
|
var _reactorQueryString = require("@adobe/reactor-query-string");
|
|
8
8
|
var _index = require("../../utils/index.js");
|
|
9
9
|
var _constants = require("./constants.js");
|
|
10
|
-
var _index2 = require("../../utils/validation/index.js");
|
|
11
10
|
var _createDecodeKndctrCookie = require("../../utils/createDecodeKndctrCookie.js");
|
|
12
11
|
var _createSendConversationServiceRequest = require("./createSendConversationServiceRequest.js");
|
|
12
|
+
var _configValidators = require("./configValidators.js");
|
|
13
13
|
/*
|
|
14
14
|
Copyright 2024 Adobe. All rights reserved.
|
|
15
15
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -38,7 +38,7 @@ const createConciergeComponent = ({
|
|
|
38
38
|
const {
|
|
39
39
|
fetch
|
|
40
40
|
} = window;
|
|
41
|
-
if (!config.stickyConversationSession) {
|
|
41
|
+
if (!config.conversation.stickyConversationSession) {
|
|
42
42
|
loggingCookieJar.remove((0, _index.getNamespacedCookieName)(config.orgId, _constants.BC_SESSION_COOKIE_NAME), {
|
|
43
43
|
domain: apexDomain
|
|
44
44
|
});
|
|
@@ -98,7 +98,5 @@ const createConciergeComponent = ({
|
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
100
|
createConciergeComponent.namespace = "BrandConcierge";
|
|
101
|
-
createConciergeComponent.configValidators =
|
|
102
|
-
stickyConversationSession: (0, _index2.boolean)().default(false)
|
|
103
|
-
});
|
|
101
|
+
createConciergeComponent.configValidators = _configValidators.default;
|
|
104
102
|
var _default = exports.default = createConciergeComponent;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports.default = void 0;
|
|
4
4
|
var _index = require("../../utils/validation/index.js");
|
|
5
|
+
var _index2 = require("../../utils/index.js");
|
|
5
6
|
/*
|
|
6
7
|
Copyright 2025 Adobe. All rights reserved.
|
|
7
8
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -17,7 +18,8 @@ var _default = ({
|
|
|
17
18
|
options
|
|
18
19
|
}) => {
|
|
19
20
|
const brandConciergeEventValidator = (0, _index.anyOf)([(0, _index.objectOf)({
|
|
20
|
-
message: (0, _index.string)().required()
|
|
21
|
+
message: (0, _index.string)().required(),
|
|
22
|
+
onStreamResponse: (0, _index.callback)().default(_index2.noop)
|
|
21
23
|
}), (0, _index.objectOf)({
|
|
22
24
|
xdm: (0, _index.objectOf)({
|
|
23
25
|
interactionId: (0, _index.string)(),
|
|
@@ -34,7 +36,8 @@ var _default = ({
|
|
|
34
36
|
data: (0, _index.objectOf)({
|
|
35
37
|
type: (0, _index.string)().required(),
|
|
36
38
|
payload: (0, _index.objectOf)({})
|
|
37
|
-
}).required()
|
|
39
|
+
}).required(),
|
|
40
|
+
onStreamResponse: (0, _index.callback)().default(_index2.noop)
|
|
38
41
|
})]);
|
|
39
42
|
return brandConciergeEventValidator(options);
|
|
40
43
|
};
|
|
@@ -12,12 +12,15 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
|
|
|
12
12
|
OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
13
|
governing permissions and limitations under the License.
|
|
14
14
|
*/
|
|
15
|
+
|
|
16
|
+
// Because these events are originated by the SDK rather than user actions, don't change the referrer
|
|
17
|
+
const IGNORED_EVENT_TYPES = new Set(["decisioning.propositionFetch", "decisioning.propositionDisplay", "decisioning.propositionInteract"]);
|
|
15
18
|
var _default = window => {
|
|
16
19
|
let lastReferrerSent = null;
|
|
17
20
|
return event => {
|
|
18
21
|
const content = event.getContent();
|
|
19
22
|
const eventType = content.xdm?.eventType;
|
|
20
|
-
if (eventType
|
|
23
|
+
if (IGNORED_EVENT_TYPES.has(eventType)) {
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
exports.default = void 0;
|
|
4
4
|
var _index = require("../../utils/index.js");
|
|
5
5
|
var _pageWideScope = require("../../constants/pageWideScope.js");
|
|
6
|
+
var _schema = require("../../constants/schema.js");
|
|
6
7
|
/*
|
|
7
8
|
Copyright 2023 Adobe. All rights reserved.
|
|
8
9
|
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
@@ -107,7 +108,11 @@ var _default = ({
|
|
|
107
108
|
// Render could take a long time especially if one of the renders
|
|
108
109
|
// is waiting for html to appear on the page. We show the containers
|
|
109
110
|
// immediately, and whatever renders quickly will not have flicker.
|
|
110
|
-
|
|
111
|
+
// However, skip showing containers if there's only one page proposition with a single REDIRECT_ITEM
|
|
112
|
+
const shouldSkipShowContainers = pagePropositions.length === 1 && pagePropositions[0].getItems().every(p => p.getSchema() === _schema.REDIRECT_ITEM);
|
|
113
|
+
if (!shouldSkipShowContainers) {
|
|
114
|
+
showContainers();
|
|
115
|
+
}
|
|
111
116
|
} else {
|
|
112
117
|
({
|
|
113
118
|
returnedPropositions,
|
|
@@ -39,6 +39,11 @@ var _default = action => {
|
|
|
39
39
|
content,
|
|
40
40
|
selector
|
|
41
41
|
} = result;
|
|
42
|
+
|
|
43
|
+
// Custom code actions have a "HEAD" selector, but are handled differently.
|
|
44
|
+
if (result.type === _initDomActionsModules.DOM_ACTION_CUSTOM_CODE) {
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
42
47
|
if ((0, _isBlankString.default)(content)) {
|
|
43
48
|
return result;
|
|
44
49
|
}
|
|
@@ -14,4 +14,4 @@ governing permissions and limitations under the License.
|
|
|
14
14
|
*/
|
|
15
15
|
// The __VERSION__ keyword will be replace at alloy build time with the package.json version.
|
|
16
16
|
// see babel-plugin-version
|
|
17
|
-
var _default = exports.default = "2.30.1-beta.
|
|
17
|
+
var _default = exports.default = "2.30.1-beta.23";
|
|
@@ -27,6 +27,7 @@ const getXdmPropositions = xdm => {
|
|
|
27
27
|
};
|
|
28
28
|
var _default = () => {
|
|
29
29
|
const content = {};
|
|
30
|
+
const createdAt = Date.now();
|
|
30
31
|
let userXdm;
|
|
31
32
|
let userData;
|
|
32
33
|
let documentMayUnload = false;
|
|
@@ -141,6 +142,9 @@ var _default = () => {
|
|
|
141
142
|
getDocumentMayUnload() {
|
|
142
143
|
return documentMayUnload;
|
|
143
144
|
},
|
|
145
|
+
getCreatedAt() {
|
|
146
|
+
return createdAt;
|
|
147
|
+
},
|
|
144
148
|
isEmpty() {
|
|
145
149
|
return (0, _index.isEmptyObject)(content) && (!userXdm || (0, _index.isEmptyObject)(userXdm)) && (!userData || (0, _index.isEmptyObject)(userData));
|
|
146
150
|
},
|
|
@@ -5,6 +5,7 @@ var _domain = require("../../constants/domain.js");
|
|
|
5
5
|
var _apiVersion = require("../../constants/apiVersion.js");
|
|
6
6
|
var _index = require("../../utils/index.js");
|
|
7
7
|
var _networkErrors = require("../../utils/networkErrors.js");
|
|
8
|
+
var _clamp = require("../../utils/clamp.js");
|
|
8
9
|
var _mergeLifecycleResponses = require("./mergeLifecycleResponses.js");
|
|
9
10
|
var _handleRequestFailure = require("./handleRequestFailure.js");
|
|
10
11
|
/*
|
|
@@ -22,6 +23,22 @@ governing permissions and limitations under the License.
|
|
|
22
23
|
/** @import { EdgeRequestExecutor } from './types.js' */
|
|
23
24
|
/** @import { ResponseCreator } from '../types.js' */
|
|
24
25
|
|
|
26
|
+
const MAX_QUEUE_TIME_MILLIS = 300000; // 5 minutes
|
|
27
|
+
|
|
28
|
+
const calculateQueueTimeMillis = payload => {
|
|
29
|
+
if (typeof payload.getEvents !== "function") {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const events = payload.getEvents();
|
|
33
|
+
if (events.length === 0) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// In practice, there should only be one event in the payload, in the future if this changes we'll need to
|
|
38
|
+
// evaluate what timestamp to use (earliest, average, latest), or move the queueTime to the event meta
|
|
39
|
+
const earliestCreatedAt = Math.min(...events.map(event => event.getCreatedAt()));
|
|
40
|
+
return (0, _clamp.default)(Date.now() - earliestCreatedAt, 0, MAX_QUEUE_TIME_MILLIS);
|
|
41
|
+
};
|
|
25
42
|
const isDemdexBlockedError = (error, request) => {
|
|
26
43
|
return request.getUseIdThirdPartyDomain() && (0, _networkErrors.isNetworkError)(error);
|
|
27
44
|
};
|
|
@@ -97,6 +114,12 @@ var _default = ({
|
|
|
97
114
|
const endpointDomain = hasDemdexFailed || !request.getUseIdThirdPartyDomain() ? edgeDomain : _domain.ID_THIRD_PARTY;
|
|
98
115
|
const url = buildEndpointUrl(endpointDomain, request);
|
|
99
116
|
const payload = request.getPayload();
|
|
117
|
+
const queueTimeMillis = calculateQueueTimeMillis(payload);
|
|
118
|
+
if (queueTimeMillis !== undefined) {
|
|
119
|
+
payload.mergeMeta({
|
|
120
|
+
queueTimeMillis
|
|
121
|
+
});
|
|
122
|
+
}
|
|
100
123
|
cookieTransfer.cookiesToPayload(payload, endpointDomain);
|
|
101
124
|
return sendNetworkRequest({
|
|
102
125
|
requestId: request.getId(),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.default = void 0;
|
|
4
|
+
/*
|
|
5
|
+
Copyright 2025 Adobe. All rights reserved.
|
|
6
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
|
8
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
|
11
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
12
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
|
+
governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Clamps a value between a minimum and maximum value.
|
|
17
|
+
* @param {number} value - The value to clamp.
|
|
18
|
+
* @param {number} min - The minimum value.
|
|
19
|
+
* @param {number} max - The maximum value.
|
|
20
|
+
* @returns {number} The clamped value.
|
|
21
|
+
*/
|
|
22
|
+
var _default = (value, min, max) => {
|
|
23
|
+
return Math.max(min, Math.min(value, max));
|
|
24
|
+
};
|
|
25
|
+
exports.default = _default;
|
|
@@ -27,11 +27,13 @@ var _default = configuration => {
|
|
|
27
27
|
return null;
|
|
28
28
|
}
|
|
29
29
|
// remove entries that are empty strings or arrays
|
|
30
|
-
const configOverrides = (0, _filterObject.default)(configuration, value => {
|
|
30
|
+
const configOverrides = (0, _filterObject.default)(configuration, (value, key) => {
|
|
31
31
|
if ((0, _isNil.default)(value)) {
|
|
32
32
|
return false;
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
// We want to remove all the { enabled: true } values, but leave any other boolean values.
|
|
35
|
+
// Experience Edge will not accept { enabled: true } values as true is the default for "enabled".
|
|
36
|
+
if ((0, _isBoolean.default)(value) && (key !== "enabled" || value === false)) {
|
|
35
37
|
return true;
|
|
36
38
|
}
|
|
37
39
|
if ((0, _isNumber.default)(value)) {
|
|
@@ -34,6 +34,9 @@ var _default = () => {
|
|
|
34
34
|
content.events = content.events || [];
|
|
35
35
|
content.events.push(event);
|
|
36
36
|
},
|
|
37
|
+
getEvents: () => {
|
|
38
|
+
return content.events || [];
|
|
39
|
+
},
|
|
37
40
|
getDocumentMayUnload: () => {
|
|
38
41
|
return (content.events || []).some(event => event.getDocumentMayUnload());
|
|
39
42
|
}
|
|
@@ -44,6 +44,7 @@ var _default = ({
|
|
|
44
44
|
if (localConfigOverridesWithoutDatastreamId && !(0, _index.isEmptyObject)(localConfigOverridesWithoutDatastreamId)) {
|
|
45
45
|
payload.mergeConfigOverride(localConfigOverridesWithoutDatastreamId);
|
|
46
46
|
}
|
|
47
|
+
payload.finalizeConfigOverrides();
|
|
47
48
|
return requestParams;
|
|
48
49
|
};
|
|
49
50
|
exports.default = _default;
|
|
@@ -90,7 +90,17 @@ var _default = options => {
|
|
|
90
90
|
mergeMeta: (0, _index.createMerger)(content, "meta"),
|
|
91
91
|
mergeState: (0, _index.createMerger)(content, "meta.state"),
|
|
92
92
|
mergeQuery: (0, _index.createMerger)(content, "query"),
|
|
93
|
-
mergeConfigOverride: updates => mergeConfigOverrides(
|
|
93
|
+
mergeConfigOverride: updates => mergeConfigOverrides(updates),
|
|
94
|
+
finalizeConfigOverrides: () => {
|
|
95
|
+
if (content.meta?.configOverrides) {
|
|
96
|
+
const prepared = (0, _index.prepareConfigOverridesForEdge)(content.meta.configOverrides);
|
|
97
|
+
if (prepared === null) {
|
|
98
|
+
delete content.meta.configOverrides;
|
|
99
|
+
} else {
|
|
100
|
+
content.meta.configOverrides = prepared;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
94
104
|
addIdentity,
|
|
95
105
|
hasIdentity,
|
|
96
106
|
toJSON() {
|
|
@@ -52,6 +52,7 @@ governing permissions and limitations under the License.
|
|
|
52
52
|
* @property {function(string, Identity): void} options.addIdentity
|
|
53
53
|
* @property {function(string): boolean} options.hasIdentity
|
|
54
54
|
* @property {function(object): void} addEvent
|
|
55
|
+
* @property {function(): Array} getEvents
|
|
55
56
|
* @property {function(): boolean} getDocumentMayUnload
|
|
56
57
|
* @property {function(): object} toJSON
|
|
57
58
|
*/
|
|
@@ -18,7 +18,8 @@ export default ({
|
|
|
18
18
|
eventManager,
|
|
19
19
|
cookieManager,
|
|
20
20
|
adConversionHandler,
|
|
21
|
-
getBrowser
|
|
21
|
+
getBrowser,
|
|
22
|
+
consent
|
|
22
23
|
}) => {
|
|
23
24
|
const componentConfig = config.advertising;
|
|
24
25
|
const sendAdConversionHandler = createSendAdConversion({
|
|
@@ -27,12 +28,15 @@ export default ({
|
|
|
27
28
|
adConversionHandler,
|
|
28
29
|
logger,
|
|
29
30
|
componentConfig,
|
|
30
|
-
getBrowser
|
|
31
|
+
getBrowser,
|
|
32
|
+
consent
|
|
31
33
|
});
|
|
32
34
|
return {
|
|
33
35
|
lifecycle: {
|
|
34
36
|
onComponentsRegistered() {
|
|
35
|
-
return
|
|
37
|
+
// Fire-and-forget: don't return the promise so we don't block
|
|
38
|
+
// the configure command from resolving while waiting for consent.
|
|
39
|
+
sendAdConversionHandler();
|
|
36
40
|
},
|
|
37
41
|
onBeforeEvent: ({
|
|
38
42
|
event,
|
|
@@ -25,16 +25,21 @@ export default ({
|
|
|
25
25
|
adConversionHandler,
|
|
26
26
|
logger,
|
|
27
27
|
componentConfig,
|
|
28
|
-
getBrowser
|
|
28
|
+
getBrowser,
|
|
29
|
+
consent
|
|
29
30
|
}) => {
|
|
30
31
|
const activeAdvertiserIds = componentConfig?.advertiserSettings ? normalizeAdvertiser(componentConfig.advertiserSettings) : "";
|
|
31
32
|
return async () => {
|
|
32
|
-
const {
|
|
33
|
-
skwcid,
|
|
34
|
-
efid
|
|
35
|
-
} = getUrlParams();
|
|
36
|
-
const isClickThru = !!(skwcid || efid);
|
|
37
33
|
try {
|
|
34
|
+
// Wait for consent before any ad conversion processing.
|
|
35
|
+
// This ensures no advertising cookies are set without user consent.
|
|
36
|
+
// If consent is declined, awaitConsent() rejects and we exit gracefully.
|
|
37
|
+
await consent.awaitConsent();
|
|
38
|
+
const {
|
|
39
|
+
skwcid,
|
|
40
|
+
efid
|
|
41
|
+
} = getUrlParams();
|
|
42
|
+
const isClickThru = !!(skwcid || efid);
|
|
38
43
|
if (isClickThru) {
|
|
39
44
|
// wait for click through to complete
|
|
40
45
|
return handleClickThrough({
|