@adobe/alloy 2.18.0 → 2.19.0-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.
Files changed (75) hide show
  1. package/libEs5/components/DataCollector/index.js +4 -2
  2. package/libEs5/components/DataCollector/validateApplyResponse.js +6 -1
  3. package/libEs5/components/DataCollector/validateUserEventOptions.js +5 -1
  4. package/libEs5/components/Personalization/createApplyPropositions.js +38 -25
  5. package/libEs5/components/Personalization/createComponent.js +22 -14
  6. package/libEs5/components/Personalization/createFetchDataHandler.js +83 -18
  7. package/libEs5/components/Personalization/createOnClickHandler.js +2 -2
  8. package/libEs5/components/Personalization/createPendingNotificationsHandler.js +29 -0
  9. package/libEs5/components/Personalization/createPersonalizationDetails.js +8 -2
  10. package/libEs5/components/Personalization/createViewCacheManager.js +60 -21
  11. package/libEs5/components/Personalization/createViewChangeHandler.js +25 -30
  12. package/libEs5/components/Personalization/dom-actions/action.js +5 -20
  13. package/{libEs6/components/Personalization/utils/composePersonalizationResultingObject.js → libEs5/components/Personalization/dom-actions/createPreprocess.js} +17 -13
  14. package/libEs5/components/Personalization/dom-actions/index.js +1 -9
  15. package/libEs5/components/Personalization/dom-actions/initDomActionsModules.js +2 -10
  16. package/libEs5/components/Personalization/dom-actions/remapHeadOffers.js +4 -0
  17. package/libEs5/components/Personalization/handlers/createProcessDomAction.js +61 -0
  18. package/libEs5/components/Personalization/handlers/createProcessHtmlContent.js +43 -0
  19. package/libEs5/components/Personalization/handlers/createProcessPropositions.js +240 -0
  20. package/libEs5/components/Personalization/handlers/createProcessRedirect.js +45 -0
  21. package/libEs5/components/Personalization/handlers/injectCreateProposition.js +124 -0
  22. package/libEs5/components/Personalization/{dom-actions/clicks/index.js → handlers/processDefaultContent.js} +8 -4
  23. package/libEs5/components/Personalization/index.js +70 -53
  24. package/libEs5/components/Personalization/utils/createAsyncArray.js +42 -0
  25. package/libEs5/components/Personalization/validateApplyPropositionsOptions.js +3 -2
  26. package/libEs5/constants/libraryVersion.js +1 -1
  27. package/libEs5/core/createEvent.js +31 -13
  28. package/libEs5/core/createEventManager.js +3 -2
  29. package/libEs5/{components/Personalization/utils/composePersonalizationResultingObject.js → utils/deduplicateArray.js} +16 -14
  30. package/libEs5/utils/index.js +8 -0
  31. package/libEs6/components/DataCollector/index.js +4 -2
  32. package/libEs6/components/DataCollector/validateApplyResponse.js +6 -1
  33. package/libEs6/components/DataCollector/validateUserEventOptions.js +5 -1
  34. package/libEs6/components/Personalization/createApplyPropositions.js +25 -24
  35. package/libEs6/components/Personalization/createComponent.js +23 -15
  36. package/libEs6/components/Personalization/createFetchDataHandler.js +65 -9
  37. package/libEs6/components/Personalization/createOnClickHandler.js +3 -3
  38. package/{libEs5/components/Personalization/dom-actions/click.js → libEs6/components/Personalization/createPendingNotificationsHandler.js} +11 -15
  39. package/libEs6/components/Personalization/createPersonalizationDetails.js +10 -2
  40. package/libEs6/components/Personalization/createViewCacheManager.js +55 -20
  41. package/libEs6/components/Personalization/createViewChangeHandler.js +25 -28
  42. package/libEs6/components/Personalization/dom-actions/action.js +4 -12
  43. package/libEs6/components/Personalization/dom-actions/{click.js → createPreprocess.js} +8 -11
  44. package/libEs6/components/Personalization/dom-actions/index.js +1 -2
  45. package/libEs6/components/Personalization/dom-actions/initDomActionsModules.js +3 -7
  46. package/libEs6/components/Personalization/dom-actions/remapHeadOffers.js +4 -0
  47. package/libEs6/components/Personalization/handlers/createProcessDomAction.js +53 -0
  48. package/libEs6/components/Personalization/handlers/createProcessHtmlContent.js +37 -0
  49. package/libEs6/components/Personalization/handlers/createProcessPropositions.js +202 -0
  50. package/libEs6/components/Personalization/handlers/createProcessRedirect.js +39 -0
  51. package/libEs6/components/Personalization/handlers/injectCreateProposition.js +129 -0
  52. package/libEs6/components/Personalization/{dom-actions/clicks/index.js → handlers/processDefaultContent.js} +7 -3
  53. package/libEs6/components/Personalization/index.js +60 -40
  54. package/libEs6/components/Personalization/utils/createAsyncArray.js +37 -0
  55. package/libEs6/components/Personalization/validateApplyPropositionsOptions.js +4 -3
  56. package/libEs6/constants/libraryVersion.js +1 -1
  57. package/libEs6/core/createEvent.js +19 -3
  58. package/libEs6/core/createEventManager.js +3 -2
  59. package/libEs6/utils/deduplicateArray.js +26 -0
  60. package/libEs6/utils/index.js +1 -0
  61. package/package.json +2 -2
  62. package/libEs5/components/Personalization/createAutoRenderingHandler.js +0 -92
  63. package/libEs5/components/Personalization/createExecuteDecisions.js +0 -89
  64. package/libEs5/components/Personalization/createNonRenderingHandler.js +0 -66
  65. package/libEs5/components/Personalization/createOnResponseHandler.js +0 -73
  66. package/libEs5/components/Personalization/createRedirectHandler.js +0 -58
  67. package/libEs5/components/Personalization/dom-actions/executeActions.js +0 -75
  68. package/libEs5/components/Personalization/groupDecisions.js +0 -160
  69. package/libEs6/components/Personalization/createAutoRenderingHandler.js +0 -84
  70. package/libEs6/components/Personalization/createExecuteDecisions.js +0 -77
  71. package/libEs6/components/Personalization/createNonRenderingHandler.js +0 -56
  72. package/libEs6/components/Personalization/createOnResponseHandler.js +0 -68
  73. package/libEs6/components/Personalization/createRedirectHandler.js +0 -57
  74. package/libEs6/components/Personalization/dom-actions/executeActions.js +0 -66
  75. package/libEs6/components/Personalization/groupDecisions.js +0 -131
@@ -0,0 +1,202 @@
1
+ /*
2
+ Copyright 2023 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ export default (({
13
+ schemaProcessors,
14
+ logger
15
+ }) => {
16
+ const wrapRenderWithLogging = (render, item) => () => {
17
+ return Promise.resolve().then(render).then(() => {
18
+ if (logger.enabled) {
19
+ logger.info(`Action ${item.toString()} executed.`);
20
+ }
21
+
22
+ return true;
23
+ }).catch(error => {
24
+ if (logger.enabled) {
25
+ const {
26
+ message,
27
+ stack
28
+ } = error;
29
+ const errorMessage = `Failed to execute action ${item.toString()}. ${message} ${stack}`;
30
+ logger.error(errorMessage);
31
+ }
32
+
33
+ return false;
34
+ });
35
+ };
36
+
37
+ const renderItems = (renderers, meta) => Promise.all(renderers.map(renderer => renderer())).then(successes => {
38
+ // as long as at least one renderer succeeds, we want to add the notification
39
+ // to the display notifications
40
+ if (!successes.includes(true)) {
41
+ return undefined;
42
+ }
43
+
44
+ return meta;
45
+ });
46
+
47
+ const processItem = item => {
48
+ const processor = schemaProcessors[item.getSchema()];
49
+
50
+ if (!processor) {
51
+ return {};
52
+ }
53
+
54
+ return processor(item);
55
+ };
56
+
57
+ const processItems = ({
58
+ renderers: existingRenderers,
59
+ returnedPropositions: existingReturnedPropositions,
60
+ returnedDecisions: existingReturnedDecisions,
61
+ items,
62
+ proposition
63
+ }) => {
64
+ let renderers = [...existingRenderers];
65
+ let returnedPropositions = [...existingReturnedPropositions];
66
+ let returnedDecisions = [...existingReturnedDecisions];
67
+ let renderedItems = [];
68
+ let nonRenderedItems = [];
69
+ let itemRenderers = [];
70
+ let atLeastOneWithNotification = false;
71
+ let render;
72
+ let setRenderAttempted;
73
+ let includeInNotification;
74
+ let onlyRenderThis = false;
75
+ let i = 0;
76
+ let item;
77
+
78
+ while (items.length > i) {
79
+ item = items[i];
80
+ ({
81
+ render,
82
+ setRenderAttempted,
83
+ includeInNotification,
84
+ onlyRenderThis
85
+ } = processItem(item));
86
+
87
+ if (onlyRenderThis) {
88
+ returnedPropositions = [];
89
+ returnedDecisions = [];
90
+
91
+ if (setRenderAttempted) {
92
+ renderedItems = [item];
93
+ nonRenderedItems = [];
94
+ } else {
95
+ renderedItems = [];
96
+ nonRenderedItems = [item];
97
+ }
98
+
99
+ renderers = [];
100
+ itemRenderers = [render];
101
+ atLeastOneWithNotification = includeInNotification;
102
+ break;
103
+ }
104
+
105
+ if (render) {
106
+ itemRenderers.push(wrapRenderWithLogging(render, item));
107
+ }
108
+
109
+ if (includeInNotification) {
110
+ atLeastOneWithNotification = true;
111
+ }
112
+
113
+ if (setRenderAttempted) {
114
+ renderedItems.push(item);
115
+ } else {
116
+ nonRenderedItems.push(item);
117
+ }
118
+
119
+ i += 1;
120
+ }
121
+
122
+ if (itemRenderers.length > 0) {
123
+ const meta = atLeastOneWithNotification ? proposition.getNotification() : undefined;
124
+ renderers.push(() => renderItems(itemRenderers, meta));
125
+ } else if (atLeastOneWithNotification) {
126
+ renderers.push(() => proposition.getNotification());
127
+ }
128
+
129
+ if (renderedItems.length > 0) {
130
+ proposition.addToReturnValues(returnedPropositions, returnedDecisions, renderedItems, true);
131
+ }
132
+
133
+ if (nonRenderedItems.length > 0) {
134
+ proposition.addToReturnValues(returnedPropositions, returnedDecisions, nonRenderedItems, false);
135
+ }
136
+
137
+ return {
138
+ renderers,
139
+ returnedPropositions,
140
+ returnedDecisions,
141
+ onlyRenderThis
142
+ };
143
+ };
144
+
145
+ return (renderPropositions, nonRenderPropositions = []) => {
146
+ let renderers = [];
147
+ let returnedPropositions = [];
148
+ let returnedDecisions = [];
149
+ let onlyRenderThis;
150
+ let i = 0;
151
+ let proposition;
152
+ let items;
153
+
154
+ while (renderPropositions.length > i) {
155
+ proposition = renderPropositions[i];
156
+ items = proposition.getItems();
157
+ ({
158
+ renderers,
159
+ returnedPropositions,
160
+ returnedDecisions,
161
+ onlyRenderThis
162
+ } = processItems({
163
+ renderers,
164
+ returnedPropositions,
165
+ returnedDecisions,
166
+ items,
167
+ proposition
168
+ }));
169
+
170
+ if (onlyRenderThis) {
171
+ break;
172
+ }
173
+
174
+ i += 1;
175
+ }
176
+
177
+ if (onlyRenderThis) {
178
+ // if onlyRenderThis is true, that means returnedPropositions and returnedDecisions
179
+ // only contains the proposition that triggered only rendering this. We need to
180
+ // add the other propositions to the returnedPropositions and returnedDecisions.
181
+ renderPropositions.forEach((p, index) => {
182
+ if (index !== i) {
183
+ p.addToReturnValues(returnedPropositions, returnedDecisions, p.getItems(), false);
184
+ }
185
+ });
186
+ }
187
+
188
+ nonRenderPropositions.forEach(p => {
189
+ p.addToReturnValues(returnedPropositions, returnedDecisions, p.getItems(), false);
190
+ });
191
+
192
+ const render = () => {
193
+ return Promise.all(renderers.map(renderer => renderer())).then(metas => metas.filter(meta => meta));
194
+ };
195
+
196
+ return {
197
+ returnedPropositions,
198
+ returnedDecisions,
199
+ render
200
+ };
201
+ };
202
+ });
@@ -0,0 +1,39 @@
1
+ /*
2
+ Copyright 2023 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ export default (({
13
+ logger,
14
+ executeRedirect,
15
+ collect
16
+ }) => item => {
17
+ const {
18
+ content
19
+ } = item.getData() || {};
20
+
21
+ if (!content) {
22
+ logger.warn("Invalid Redirect data", item.getData());
23
+ return {};
24
+ }
25
+
26
+ const render = () => {
27
+ return collect({
28
+ decisionsMeta: [item.getMeta()]
29
+ }).then(() => {
30
+ executeRedirect(content); // We've already sent the display notification, so don't return anything
31
+ });
32
+ };
33
+
34
+ return {
35
+ render,
36
+ setRenderAttempted: true,
37
+ onlyRenderThis: true
38
+ };
39
+ });
@@ -0,0 +1,129 @@
1
+ /*
2
+ Copyright 2023 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ import PAGE_WIDE_SCOPE from "../../../constants/pageWideScope";
13
+ export default (({
14
+ preprocess,
15
+ isPageWideSurface
16
+ }) => {
17
+ const createItem = (item, meta) => {
18
+ const {
19
+ schema,
20
+ data,
21
+ characteristics: {
22
+ trackingLabel
23
+ } = {}
24
+ } = item;
25
+ const processedData = preprocess(data);
26
+
27
+ if (trackingLabel) {
28
+ meta.trackingLabel = trackingLabel;
29
+ }
30
+
31
+ return {
32
+ getSchema() {
33
+ return schema;
34
+ },
35
+
36
+ getData() {
37
+ return processedData;
38
+ },
39
+
40
+ getMeta() {
41
+ return meta;
42
+ },
43
+
44
+ getOriginalItem() {
45
+ return item;
46
+ },
47
+
48
+ toString() {
49
+ return JSON.stringify(item);
50
+ },
51
+
52
+ toJSON() {
53
+ return item;
54
+ }
55
+
56
+ };
57
+ };
58
+
59
+ return (payload, visibleInReturnedItems = true) => {
60
+ const {
61
+ id,
62
+ scope,
63
+ scopeDetails,
64
+ items = []
65
+ } = payload;
66
+ const {
67
+ characteristics: {
68
+ scopeType
69
+ } = {}
70
+ } = scopeDetails || {};
71
+ return {
72
+ getScope() {
73
+ if (!scope) {
74
+ return scope;
75
+ }
76
+
77
+ return scope;
78
+ },
79
+
80
+ getScopeType() {
81
+ if (scope === PAGE_WIDE_SCOPE || isPageWideSurface(scope)) {
82
+ return "page";
83
+ }
84
+
85
+ if (scopeType === "view") {
86
+ return "view";
87
+ }
88
+
89
+ return "proposition";
90
+ },
91
+
92
+ getItems() {
93
+ return items.map(item => createItem(item, {
94
+ id,
95
+ scope,
96
+ scopeDetails
97
+ }));
98
+ },
99
+
100
+ getNotification() {
101
+ return {
102
+ id,
103
+ scope,
104
+ scopeDetails
105
+ };
106
+ },
107
+
108
+ toJSON() {
109
+ return payload;
110
+ },
111
+
112
+ addToReturnValues(propositions, decisions, includedItems, renderAttempted) {
113
+ if (visibleInReturnedItems) {
114
+ propositions.push({ ...payload,
115
+ items: includedItems.map(i => i.getOriginalItem()),
116
+ renderAttempted
117
+ });
118
+
119
+ if (!renderAttempted) {
120
+ decisions.push({ ...payload,
121
+ items: includedItems.map(i => i.getOriginalItem())
122
+ });
123
+ }
124
+ }
125
+ }
126
+
127
+ };
128
+ };
129
+ });
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2019 Adobe. All rights reserved.
2
+ Copyright 2023 Adobe. All rights reserved.
3
3
  This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  you may not use this file except in compliance with the License. You may obtain a copy
5
5
  of the License at http://www.apache.org/licenses/LICENSE-2.0
@@ -9,5 +9,9 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- import collectClicks from "./collectClicks";
13
- export default collectClicks;
12
+ export default (() => {
13
+ return {
14
+ setRenderAttempted: true,
15
+ includeInNotification: true
16
+ };
17
+ });
@@ -11,9 +11,8 @@ governing permissions and limitations under the License.
11
11
  */
12
12
  import { string, boolean, objectOf } from "../../utils/validation";
13
13
  import createComponent from "./createComponent";
14
- import { initDomActionsModules, executeActions } from "./dom-actions";
14
+ import { initDomActionsModules } from "./dom-actions";
15
15
  import createCollect from "./createCollect";
16
- import createExecuteDecisions from "./createExecuteDecisions";
17
16
  import { hideContainers, showContainers } from "./flicker";
18
17
  import createFetchDataHandler from "./createFetchDataHandler";
19
18
  import collectClicks from "./dom-actions/clicks/collectClicks";
@@ -22,15 +21,23 @@ import { mergeDecisionsMeta, mergeQuery } from "./event";
22
21
  import createOnClickHandler from "./createOnClickHandler";
23
22
  import createViewCacheManager from "./createViewCacheManager";
24
23
  import createViewChangeHandler from "./createViewChangeHandler";
25
- import groupDecisions from "./groupDecisions";
26
- import createOnResponseHandler from "./createOnResponseHandler";
27
24
  import createClickStorage from "./createClickStorage";
28
- import createRedirectHandler from "./createRedirectHandler";
29
- import createAutorenderingHandler from "./createAutoRenderingHandler";
30
- import createNonRenderingHandler from "./createNonRenderingHandler";
31
25
  import createApplyPropositions from "./createApplyPropositions";
32
26
  import createGetPageLocation from "./createGetPageLocation";
33
27
  import createSetTargetMigration from "./createSetTargetMigration";
28
+ import remapCustomCodeOffers from "./dom-actions/remapCustomCodeOffers";
29
+ import remapHeadOffers from "./dom-actions/remapHeadOffers";
30
+ import createPreprocess from "./dom-actions/createPreprocess";
31
+ import injectCreateProposition from "./handlers/injectCreateProposition";
32
+ import createAsyncArray from "./utils/createAsyncArray";
33
+ import createPendingNotificationsHandler from "./createPendingNotificationsHandler";
34
+ import * as schema from "./constants/schema";
35
+ import processDefaultContent from "./handlers/processDefaultContent";
36
+ import { isPageWideSurface } from "./utils/surfaceUtils";
37
+ import createProcessDomAction from "./handlers/createProcessDomAction";
38
+ import createProcessHtmlContent from "./handlers/createProcessHtmlContent";
39
+ import createProcessRedirect from "./handlers/createProcessRedirect";
40
+ import createProcessPropositions from "./handlers/createProcessPropositions";
34
41
 
35
42
  const createPersonalization = ({
36
43
  config,
@@ -53,43 +60,50 @@ const createPersonalization = ({
53
60
  const getPageLocation = createGetPageLocation({
54
61
  window
55
62
  });
56
- const viewCache = createViewCacheManager();
57
- const modules = initDomActionsModules(storeClickMetrics);
58
- const executeDecisions = createExecuteDecisions({
59
- modules,
60
- logger,
61
- executeActions
63
+ const modules = initDomActionsModules();
64
+ const preprocess = createPreprocess([remapHeadOffers, remapCustomCodeOffers]);
65
+ const createProposition = injectCreateProposition({
66
+ preprocess,
67
+ isPageWideSurface
62
68
  });
63
- const handleRedirectDecisions = createRedirectHandler({
64
- collect,
65
- window,
66
- logger,
67
- showContainers
69
+ const viewCache = createViewCacheManager({
70
+ createProposition
68
71
  });
69
- const autoRenderingHandler = createAutorenderingHandler({
70
- viewCache,
71
- executeDecisions,
72
- showContainers,
73
- collect
74
- });
75
- const applyPropositions = createApplyPropositions({
76
- executeDecisions
77
- });
78
- const nonRenderingHandler = createNonRenderingHandler({
79
- viewCache
72
+ const schemaProcessors = {
73
+ [schema.DEFAULT_CONTENT_ITEM]: processDefaultContent,
74
+ [schema.DOM_ACTION]: createProcessDomAction({
75
+ modules,
76
+ logger,
77
+ storeClickMetrics
78
+ }),
79
+ [schema.HTML_CONTENT_ITEM]: createProcessHtmlContent({
80
+ modules,
81
+ logger
82
+ }),
83
+ [schema.REDIRECT_ITEM]: createProcessRedirect({
84
+ logger,
85
+ executeRedirect: url => window.location.replace(url),
86
+ collect
87
+ })
88
+ };
89
+ const processPropositions = createProcessPropositions({
90
+ schemaProcessors,
91
+ logger
80
92
  });
81
- const responseHandler = createOnResponseHandler({
82
- autoRenderingHandler,
83
- nonRenderingHandler,
84
- groupDecisions,
85
- handleRedirectDecisions,
86
- showContainers
93
+ const pendingDisplayNotifications = createAsyncArray();
94
+ const pendingNotificationsHandler = createPendingNotificationsHandler({
95
+ pendingDisplayNotifications,
96
+ mergeDecisionsMeta
87
97
  });
88
98
  const fetchDataHandler = createFetchDataHandler({
89
99
  prehidingStyle,
90
- responseHandler,
100
+ showContainers,
91
101
  hideContainers,
92
- mergeQuery
102
+ mergeQuery,
103
+ collect,
104
+ processPropositions,
105
+ createProposition,
106
+ pendingDisplayNotifications
93
107
  });
94
108
  const onClickHandler = createOnClickHandler({
95
109
  mergeDecisionsMeta,
@@ -99,8 +113,13 @@ const createPersonalization = ({
99
113
  });
100
114
  const viewChangeHandler = createViewChangeHandler({
101
115
  mergeDecisionsMeta,
102
- collect,
103
- executeDecisions,
116
+ processPropositions,
117
+ viewCache
118
+ });
119
+ const applyPropositions = createApplyPropositions({
120
+ processPropositions,
121
+ createProposition,
122
+ pendingDisplayNotifications,
104
123
  viewCache
105
124
  });
106
125
  const setTargetMigration = createSetTargetMigration({
@@ -117,7 +136,8 @@ const createPersonalization = ({
117
136
  viewCache,
118
137
  showContainers,
119
138
  applyPropositions,
120
- setTargetMigration
139
+ setTargetMigration,
140
+ pendingNotificationsHandler
121
141
  });
122
142
  };
123
143
 
@@ -0,0 +1,37 @@
1
+ /*
2
+ Copyright 2023 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ export default (() => {
13
+ let latest = Promise.resolve([]);
14
+ return {
15
+ concat(promise) {
16
+ latest = latest.then(existingPropositions => {
17
+ return promise.then(newPropositions => {
18
+ return existingPropositions.concat(newPropositions);
19
+ }).catch(() => {
20
+ return existingPropositions;
21
+ });
22
+ });
23
+ },
24
+
25
+ /**
26
+ * Clears the saved propositions, waiting until the next propositions are resolved and available.
27
+ *
28
+ * @returns {Promise<Array>} A promise that resolves to the latest propositions.
29
+ */
30
+ clear() {
31
+ const oldLatest = latest;
32
+ latest = Promise.resolve([]);
33
+ return oldLatest;
34
+ }
35
+
36
+ };
37
+ });
@@ -9,7 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- import { anything, objectOf, arrayOf } from "../../utils/validation";
12
+ import { anything, objectOf, arrayOf, string } from "../../utils/validation";
13
13
  export const EMPTY_PROPOSITIONS = {
14
14
  propositions: []
15
15
  };
@@ -18,8 +18,9 @@ export default (({
18
18
  options
19
19
  }) => {
20
20
  const applyPropositionsOptionsValidator = objectOf({
21
- propositions: arrayOf(objectOf(anything())).nonEmpty(),
22
- metadata: objectOf(anything())
21
+ propositions: arrayOf(objectOf(anything())),
22
+ metadata: objectOf(anything()),
23
+ viewName: string()
23
24
  }).required();
24
25
 
25
26
  try {
@@ -11,4 +11,4 @@ governing permissions and limitations under the License.
11
11
  */
12
12
  // The __VERSION__ keyword will be replace at alloy build time with the package.json version.
13
13
  // see babel-plugin-version
14
- export default "2.18.0";
14
+ export default "2.19.0-beta.0";
@@ -9,7 +9,16 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
9
9
  OF ANY KIND, either express or implied. See the License for the specific language
10
10
  governing permissions and limitations under the License.
11
11
  */
12
- import { isEmptyObject, deepAssign } from "../utils";
12
+ import { isEmptyObject, deepAssign, isNonEmptyArray, deduplicateArray } from "../utils";
13
+
14
+ const getXdmPropositions = xdm => {
15
+ return xdm && // eslint-disable-next-line no-underscore-dangle
16
+ xdm._experience && // eslint-disable-next-line no-underscore-dangle
17
+ xdm._experience.decisioning && // eslint-disable-next-line no-underscore-dangle
18
+ isNonEmptyArray(xdm._experience.decisioning.propositions) ? // eslint-disable-next-line no-underscore-dangle
19
+ xdm._experience.decisioning.propositions : [];
20
+ };
21
+
13
22
  export default (() => {
14
23
  const content = {};
15
24
  let userXdm;
@@ -74,8 +83,15 @@ export default (() => {
74
83
  return;
75
84
  }
76
85
 
86
+ const newPropositions = deduplicateArray([...getXdmPropositions(userXdm), ...getXdmPropositions(content.xdm)], (a, b) => a === b || a.id && b.id && a.id === b.id && a.scope && b.scope && a.scope === b.scope);
87
+
77
88
  if (userXdm) {
78
- event.mergeXdm(userXdm);
89
+ this.mergeXdm(userXdm);
90
+ }
91
+
92
+ if (newPropositions.length > 0) {
93
+ // eslint-disable-next-line no-underscore-dangle
94
+ content.xdm._experience.decisioning.propositions = newPropositions;
79
95
  }
80
96
 
81
97
  if (userData) {
@@ -122,7 +138,7 @@ export default (() => {
122
138
  },
123
139
 
124
140
  getViewName() {
125
- if (!userXdm || !userXdm.web || !userXdm.web.webPageDetails) {
141
+ if (!userXdm || !userXdm.web || !userXdm.web.webPageDetails || !userXdm.web.webPageDetails.viewName) {
126
142
  return undefined;
127
143
  }
128
144
 
@@ -116,7 +116,8 @@ export default (({
116
116
  responseHeaders = {},
117
117
  responseBody = {
118
118
  handle: []
119
- }
119
+ },
120
+ personalization
120
121
  } = options;
121
122
  const payload = createDataCollectionRequestPayload();
122
123
  const request = createDataCollectionRequest({
@@ -127,7 +128,7 @@ export default (({
127
128
  event,
128
129
  renderDecisions,
129
130
  decisionScopes: [PAGE_WIDE_SCOPE],
130
- personalization: {},
131
+ personalization,
131
132
  onResponse: onResponseCallbackAggregator.add,
132
133
  onRequestFailure: noop
133
134
  }).then(() => {
@@ -0,0 +1,26 @@
1
+ /*
2
+ Copyright 2023 Adobe. All rights reserved.
3
+ This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License. You may obtain a copy
5
+ of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software distributed under
8
+ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ OF ANY KIND, either express or implied. See the License for the specific language
10
+ governing permissions and limitations under the License.
11
+ */
12
+ const REFERENCE_EQUALITY = (a, b) => a === b;
13
+
14
+ const findIndex = (array, item, isEqual) => {
15
+ for (let i = 0; i < array.length; i += 1) {
16
+ if (isEqual(array[i], item)) {
17
+ return i;
18
+ }
19
+ }
20
+
21
+ return -1;
22
+ };
23
+
24
+ export default ((array, isEqual = REFERENCE_EQUALITY) => {
25
+ return array.filter((item, index) => findIndex(array, item, isEqual) === index);
26
+ });