@miso.ai/client-sdk-ui 1.11.0-beta.0 → 1.11.0-beta.10

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 (118) hide show
  1. package/dist/cjs/actor/data.js +6 -7
  2. package/dist/cjs/actor/feedback.js +6 -39
  3. package/dist/cjs/actor/fields.js +14 -6
  4. package/dist/cjs/actor/hub.js +1 -2
  5. package/dist/cjs/actor/index.js +0 -7
  6. package/dist/cjs/actor/interactions.js +4 -15
  7. package/dist/cjs/actor/sessions.js +2 -33
  8. package/dist/cjs/actor/tracker.js +25 -26
  9. package/dist/cjs/actor/utils.js +0 -49
  10. package/dist/cjs/actor/view.js +40 -40
  11. package/dist/cjs/actor/views.js +32 -8
  12. package/dist/cjs/asset/svgs.js +18 -8
  13. package/dist/cjs/constants.js +18 -19
  14. package/dist/cjs/defaults/hybrid-search/answer-box.js +19 -3
  15. package/dist/cjs/defaults/hybrid-search/phrases.js +5 -5
  16. package/dist/cjs/defaults/hybrid-search/templates.js +37 -9
  17. package/dist/cjs/element/role/index.js +12 -5
  18. package/dist/cjs/element/role/{miso-hits.js → miso-more.js} +4 -4
  19. package/dist/cjs/element/role/miso-total.js +20 -0
  20. package/dist/cjs/layout/affiliation/affiliation.js +0 -3
  21. package/dist/cjs/layout/banner/banner.js +0 -4
  22. package/dist/cjs/layout/button/more-button.js +73 -0
  23. package/dist/cjs/layout/container/container.js +0 -3
  24. package/dist/cjs/layout/error/error.js +0 -4
  25. package/dist/cjs/layout/index.js +7 -0
  26. package/dist/cjs/layout/input/facets.js +5 -5
  27. package/dist/cjs/layout/input/option-list.js +0 -4
  28. package/dist/cjs/layout/input/search-box.js +33 -12
  29. package/dist/cjs/layout/list/cards.js +0 -3
  30. package/dist/cjs/layout/list/carousel.js +0 -3
  31. package/dist/cjs/layout/list/collection.js +25 -7
  32. package/dist/cjs/layout/list/list.js +0 -3
  33. package/dist/cjs/layout/radio/feedback.js +0 -3
  34. package/dist/cjs/layout/radio/radio.js +0 -4
  35. package/dist/cjs/layout/raf.js +4 -2
  36. package/dist/cjs/layout/text/text.js +0 -4
  37. package/dist/cjs/layout/text/typewriter/index.js +3 -3
  38. package/dist/cjs/layout/triggerable.js +79 -0
  39. package/dist/cjs/util/states.js +0 -15
  40. package/dist/cjs/version.js +1 -1
  41. package/dist/cjs/workflow/answer-based.js +109 -111
  42. package/dist/cjs/workflow/ask.js +35 -27
  43. package/dist/cjs/workflow/asks.js +1 -1
  44. package/dist/cjs/workflow/autocompletable.js +33 -0
  45. package/dist/cjs/workflow/autocomplete.js +122 -0
  46. package/dist/cjs/workflow/base.js +169 -102
  47. package/dist/cjs/workflow/explore.js +26 -19
  48. package/dist/cjs/workflow/hybrid-search-answer.js +99 -0
  49. package/dist/cjs/workflow/hybrid-search-results.js +70 -0
  50. package/dist/cjs/workflow/hybrid-search-views.js +122 -0
  51. package/dist/cjs/workflow/hybrid-search.js +98 -103
  52. package/dist/cjs/workflow/options.js +32 -17
  53. package/dist/cjs/workflow/processors.js +185 -17
  54. package/dist/cjs/workflow/recommendation.js +36 -49
  55. package/dist/cjs/workflow/search-based.js +186 -0
  56. package/dist/cjs/workflow/search.js +21 -68
  57. package/package.json +2 -2
  58. package/src/actor/data.js +2 -4
  59. package/src/actor/feedback.js +6 -23
  60. package/src/actor/fields.js +14 -6
  61. package/src/actor/hub.js +1 -2
  62. package/src/actor/index.js +0 -1
  63. package/src/actor/interactions.js +4 -10
  64. package/src/actor/sessions.js +3 -30
  65. package/src/actor/tracker.js +25 -19
  66. package/src/actor/utils.js +0 -47
  67. package/src/actor/view.js +27 -15
  68. package/src/actor/views.js +36 -8
  69. package/src/asset/svgs.js +19 -7
  70. package/src/constants.js +25 -16
  71. package/src/defaults/hybrid-search/answer-box.js +17 -5
  72. package/src/defaults/hybrid-search/phrases.js +4 -4
  73. package/src/defaults/hybrid-search/templates.js +25 -9
  74. package/src/element/role/index.js +2 -1
  75. package/src/element/role/{miso-hits.js → miso-more.js} +3 -3
  76. package/src/element/role/miso-total.js +16 -0
  77. package/src/layout/affiliation/affiliation.js +1 -5
  78. package/src/layout/banner/banner.js +0 -5
  79. package/src/layout/button/more-button.js +69 -0
  80. package/src/layout/container/container.js +1 -5
  81. package/src/layout/error/error.js +0 -5
  82. package/src/layout/index.js +2 -1
  83. package/src/layout/input/facets.js +5 -6
  84. package/src/layout/input/option-list.js +0 -5
  85. package/src/layout/input/search-box.js +27 -14
  86. package/src/layout/list/cards.js +0 -4
  87. package/src/layout/list/carousel.js +0 -4
  88. package/src/layout/list/collection.js +22 -9
  89. package/src/layout/list/list.js +0 -4
  90. package/src/layout/radio/feedback.js +0 -4
  91. package/src/layout/radio/radio.js +0 -5
  92. package/src/layout/raf.js +2 -2
  93. package/src/layout/text/text.js +0 -5
  94. package/src/layout/text/typewriter/index.js +4 -5
  95. package/src/layout/trackable.js +1 -1
  96. package/src/layout/triggerable.js +76 -0
  97. package/src/util/states.js +0 -14
  98. package/src/version.js +1 -1
  99. package/src/workflow/answer-based.js +101 -77
  100. package/src/workflow/ask.js +33 -25
  101. package/src/workflow/asks.js +1 -1
  102. package/src/workflow/autocompletable.js +29 -0
  103. package/src/workflow/autocomplete.js +113 -0
  104. package/src/workflow/base.js +147 -93
  105. package/src/workflow/explore.js +23 -8
  106. package/src/workflow/hybrid-search-answer.js +92 -0
  107. package/src/workflow/hybrid-search-results.js +63 -0
  108. package/src/workflow/hybrid-search-views.js +124 -0
  109. package/src/workflow/hybrid-search.js +102 -73
  110. package/src/workflow/options.js +26 -11
  111. package/src/workflow/processors.js +165 -14
  112. package/src/workflow/recommendation.js +32 -33
  113. package/src/workflow/search-based.js +183 -0
  114. package/src/workflow/search.js +21 -65
  115. package/dist/cjs/actor/autocomplete.js +0 -160
  116. package/dist/cjs/workflow/utils.js +0 -42
  117. package/src/actor/autocomplete.js +0 -133
  118. package/src/workflow/utils.js +0 -29
@@ -10,12 +10,14 @@ exports.mergeAutocompleteOptions = mergeAutocompleteOptions;
10
10
  exports.mergeDataProcessorOptions = mergeDataProcessorOptions;
11
11
  exports.mergeInteractionsOptions = mergeInteractionsOptions;
12
12
  exports.mergeLayoutsOptions = mergeLayoutsOptions;
13
+ exports.mergePaginationOptions = mergePaginationOptions;
14
+ exports.mergeRolesOptions = mergeRolesOptions;
13
15
  exports.mergeTrackersOptions = mergeTrackersOptions;
14
16
  exports.normalizeApiOptions = normalizeApiOptions;
15
- exports.normalizeAutocompleteOptions = normalizeAutocompleteOptions;
16
17
  exports.normalizeDataProcessorOptions = normalizeDataProcessorOptions;
17
18
  exports.normalizeInteractionsOptions = normalizeInteractionsOptions;
18
19
  exports.normalizeLayoutsOptions = normalizeLayoutsOptions;
20
+ exports.normalizePaginationOptions = normalizePaginationOptions;
19
21
  exports.normalizeTrackers = normalizeTrackers;
20
22
  var _commons = require("@miso.ai/commons");
21
23
  var _constants = require("../constants.js");
@@ -139,19 +141,16 @@ function normalizeInteractionsOptions(options) {
139
141
  preprocess
140
142
  });
141
143
  }
142
- function normalizeAutocompleteOptions(options) {
144
+ function normalizePaginationOptions(options) {
143
145
  if (options === undefined) {
144
- throw new Error(`Expect autocomplete options to be an object or a boolean value: ${options}`);
146
+ throw new Error(`Expect pagination options to be an object or a boolean value: ${options}`);
145
147
  }
146
148
  if (typeof options === 'boolean') {
147
149
  options = {
148
- actor: options
150
+ active: options
149
151
  };
150
152
  }
151
- const processData = normalizeDataProcessorOptions(options.processData);
152
- return Object.assign({}, options, {
153
- processData
154
- });
153
+ return options;
155
154
  }
156
155
 
157
156
  // merge //
@@ -239,18 +238,34 @@ function mergeInteractionsOptions() {
239
238
  preprocess: concatArrays(merged.preprocess, options.preprocess)
240
239
  })));
241
240
  }
242
- function mergeAutocompleteOptions() {
241
+ function mergePaginationOptions() {
243
242
  for (var _len6 = arguments.length, optionsList = new Array(_len6), _key7 = 0; _key7 < _len6; _key7++) {
244
243
  optionsList[_key7] = arguments[_key7];
245
244
  }
246
245
  if (optionsList[optionsList.length - 1] === false) {
247
246
  return false;
248
247
  }
248
+ return mergeOptions(optionsList, (merged, options) => Object.assign(merged, options));
249
+ }
250
+ function mergeAutocompleteOptions() {
251
+ for (var _len7 = arguments.length, optionsList = new Array(_len7), _key8 = 0; _key8 < _len7; _key8++) {
252
+ optionsList[_key8] = arguments[_key8];
253
+ }
249
254
  return mergeOptions(optionsList, (merged, options) => Object.assign(merged, Object.assign({}, options, {
250
- api: mergeApiOptions(merged.api, options.api),
251
- processData: mergeDataProcessorOptions(merged.processData, options.processData)
255
+ api: mergeApiOptions(merged.api, options.api)
252
256
  })));
253
257
  }
258
+ function mergeRolesOptions(base, overrides) {
259
+ return Object.freeze(Object.assign({}, base, overrides, {
260
+ members: mergeRolesMembers(base.members, overrides.members),
261
+ mappings: Object.freeze(Object.assign({}, base.mappings, overrides.mappings))
262
+ }));
263
+ }
264
+ function mergeRolesMembers() {
265
+ let base = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
266
+ let overrides = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
267
+ return [...new Set([...base, ...overrides])];
268
+ }
254
269
 
255
270
  // manifest //
256
271
  const FEATURES = [{
@@ -274,9 +289,9 @@ const FEATURES = [{
274
289
  normalize: normalizeInteractionsOptions,
275
290
  merge: mergeInteractionsOptions
276
291
  }, {
277
- key: 'autocomplete',
278
- normalize: normalizeAutocompleteOptions,
279
- merge: mergeAutocompleteOptions
292
+ key: 'pagination',
293
+ normalize: normalizePaginationOptions,
294
+ merge: mergePaginationOptions
280
295
  }];
281
296
  class WorkflowContextOptions {
282
297
  constructor() {
@@ -300,7 +315,7 @@ class WorkflowOptions {
300
315
  this._events = new _commons.EventEmitter({
301
316
  target: this
302
317
  });
303
- this._defaults = defaults;
318
+ this._defaults = defaults; // TODO: we should call normalize() on defaults
304
319
  this._context = context || {};
305
320
  this._locals = {};
306
321
  (0, _commons.defineValues)(this, {
@@ -388,8 +403,8 @@ function injectConfigurableFeature(prototype, feature) {
388
403
  if (feature === 'api') {
389
404
  Object.assign(prototype, {
390
405
  useApi() {
391
- for (var _len7 = arguments.length, args = new Array(_len7), _key8 = 0; _key8 < _len7; _key8++) {
392
- args[_key8] = arguments[_key8];
406
+ for (var _len8 = arguments.length, args = new Array(_len8), _key9 = 0; _key9 < _len8; _key9++) {
407
+ args[_key9] = arguments[_key9];
393
408
  }
394
409
  this._options.api.merge(args);
395
410
  return this;
@@ -3,23 +3,31 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.addDataInstructions = addDataInstructions;
7
- exports.removeDataInstructions = removeDataInstructions;
6
+ exports.buildBaseInteraction = buildBaseInteraction;
7
+ exports.concatResults = concatResults;
8
+ exports.getRevision = getRevision;
9
+ exports.markExhaustion = markExhaustion;
10
+ exports.mergeInteraction = mergeInteraction;
11
+ exports.retainFacetCounts = retainFacetCounts;
12
+ exports.writeAffiliationInfoToInteraction = writeAffiliationInfoToInteraction;
8
13
  exports.writeAnswerStageToMeta = writeAnswerStageToMeta;
9
14
  exports.writeDataStatus = writeDataStatus;
15
+ exports.writeFiltersToPayload = writeFiltersToPayload;
10
16
  exports.writeKeywordsToData = writeKeywordsToData;
11
17
  exports.writeMisoIdToMeta = writeMisoIdToMeta;
12
18
  var _commons = require("@miso.ai/commons");
13
19
  var _constants = require("../constants.js");
14
- const _excluded = ["_inst"];
15
- function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
20
+ // data //
21
+ function getRevision(data) {
22
+ return data && data.value && data.value.revision;
23
+ }
16
24
  function writeDataStatus(data) {
17
25
  const status = getStatus(data);
18
- const ongoing = status === _constants.STATUS.READY ? !!data.ongoing : undefined;
19
- return (0, _commons.trimObj)(Object.assign({}, data, {
26
+ const ongoing = status === _constants.STATUS.READY ? data.ongoing : undefined;
27
+ return (0, _commons.trimObj)(Object.assign({
20
28
  status,
21
29
  ongoing
22
- }));
30
+ }, data)); // let orinigal data override status and ongoing
23
31
  }
24
32
  function getStatus(data) {
25
33
  if (!data) {
@@ -56,7 +64,8 @@ function writeKeywordsToData(data) {
56
64
  request,
57
65
  value
58
66
  } = data;
59
- if (!request || !value) {
67
+ // we still want the value in loading status
68
+ if (!request) {
60
69
  return data;
61
70
  }
62
71
  const {
@@ -96,18 +105,177 @@ function writeAnswerStageToMeta(data) {
96
105
  })
97
106
  });
98
107
  }
99
- function addDataInstructions(data, instructions) {
100
- if (!instructions) {
108
+ function writeFiltersToPayload() {
109
+ let payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
110
+ let filters = arguments.length > 1 ? arguments[1] : undefined;
111
+ return (0, _commons.trimObj)(Object.assign({}, payload, composeFiltersPayload(filters)));
112
+ }
113
+ function composeFiltersPayload(filters) {
114
+ if (!filters) {
115
+ return undefined;
116
+ }
117
+ const {
118
+ facets
119
+ } = filters;
120
+ return (0, _commons.trimObj)({
121
+ facet_filters: composeFacetFilters(facets)
122
+ });
123
+ }
124
+ function composeFacetFilters(facets) {
125
+ if (!facets) {
126
+ return undefined;
127
+ }
128
+ const filters = {};
129
+ for (const field in facets) {
130
+ const values = facets[field];
131
+ if (!values || !values.length) {
132
+ continue; // just in case
133
+ }
134
+ filters[field] = {
135
+ terms: values
136
+ };
137
+ }
138
+ return Object.keys(filters).length ? filters : undefined;
139
+ }
140
+ function retainFacetCounts(data, currentFacetCounts) {
141
+ if (!currentFacetCounts) {
142
+ return data;
143
+ }
144
+ const {
145
+ status,
146
+ value
147
+ } = data;
148
+ switch (status) {
149
+ case _constants.STATUS.INITIAL:
150
+ case _constants.STATUS.LOADING:
151
+ break;
152
+ default:
153
+ return data;
154
+ }
155
+ if (value && value.facet_counts) {
101
156
  return data;
102
157
  }
103
- return Object.assign({
104
- _inst: Object.assign({}, data._inst, instructions)
105
- }, data);
158
+ return Object.assign({}, data, {
159
+ value: Object.assign({}, value, {
160
+ facet_counts: currentFacetCounts
161
+ })
162
+ });
163
+ }
164
+ function concatResults(oldData, newData) {
165
+ let {
166
+ role = _constants.ROLE.PRODUCTS
167
+ } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
168
+ if (!newData.value) {
169
+ return oldData;
170
+ }
171
+ const {
172
+ [role]: oldProducts = []
173
+ } = oldData.value;
174
+ const {
175
+ [role]: newProducts = []
176
+ } = newData.value;
177
+ // keep exhaustion flag
178
+ // TODO
179
+ return Object.assign({}, newData, {
180
+ value: Object.assign({}, newData.value, {
181
+ [role]: [...oldProducts, ...newProducts]
182
+ })
183
+ });
106
184
  }
107
- function removeDataInstructions(data) {
108
- if (typeof data !== 'object') {
185
+ function markExhaustion(data) {
186
+ let {
187
+ role = _constants.ROLE.PRODUCTS
188
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
189
+ const {
190
+ status,
191
+ request,
192
+ value
193
+ } = data;
194
+ // keep track of the exhaustion state
195
+ if (status !== _constants.STATUS.READY || !request || !value) {
196
+ return data;
197
+ }
198
+ const {
199
+ [role]: products
200
+ } = value;
201
+ if (!products) {
109
202
  return data;
110
203
  }
111
- const rest = _objectWithoutPropertiesLoose(data, _excluded);
112
- return rest;
204
+ const {
205
+ rows
206
+ } = request.payload;
207
+ const {
208
+ length
209
+ } = products;
210
+ const exhausted = length < rows;
211
+ if (!exhausted) {
212
+ return data;
213
+ }
214
+ return Object.assign({}, data, {
215
+ meta: Object.assign({}, data.meta, {
216
+ exhausted: true
217
+ })
218
+ });
219
+ }
220
+
221
+ // interactions //
222
+ function buildBaseInteraction(args) {
223
+ const {
224
+ role,
225
+ type,
226
+ items
227
+ } = args;
228
+ const payload = {
229
+ type: type === 'viewable' ? 'viewable_impression' : type,
230
+ context: {
231
+ custom_context: (0, _commons.trimObj)({
232
+ property: role
233
+ })
234
+ }
235
+ };
236
+ if ((0, _constants.isPerformanceEventType)(type)) {
237
+ if ((0, _constants.isProductRole)(role)) {
238
+ payload.product_ids = (items || []).map(v => typeof v === 'string' ? v : v.product_id).filter(v => v);
239
+ } else {
240
+ payload.product_ids = [];
241
+ payload.context.custom_context.items = (items || []).map(v => v.text || v.id || v);
242
+ }
243
+ }
244
+ switch (type) {
245
+ case _constants.EVENT_TYPE.SUBMIT:
246
+ payload.context.custom_context.value = args.value;
247
+ break;
248
+ case _constants.EVENT_TYPE.FEEDBACK:
249
+ payload.context.custom_context.value = payload.value = args.value;
250
+ payload.context.custom_context.result_type = payload.result_type = args.result_type;
251
+ break;
252
+ }
253
+ return (0, _commons.trimObj)(payload);
254
+ }
255
+ function writeAffiliationInfoToInteraction(payload, args) {
256
+ if (args.role !== _constants.ROLE.AFFILIATION) {
257
+ return payload;
258
+ }
259
+ const {
260
+ items
261
+ } = args;
262
+ const channel = items[0] && items[0].channel || undefined;
263
+ const positions = items.map(v => v.position);
264
+ return mergeInteraction(payload, {
265
+ context: {
266
+ custom_context: {
267
+ channel,
268
+ positions
269
+ }
270
+ }
271
+ });
272
+ }
273
+ function mergeInteraction() {
274
+ let base = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
275
+ let patch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
276
+ return (0, _commons.trimObj)(Object.assign({}, base, patch, {
277
+ context: (0, _commons.trimObj)(Object.assign({}, base.context, patch.context, {
278
+ custom_context: (0, _commons.trimObj)(Object.assign({}, base.context && base.context.custom_context, patch.context && patch.context.custom_context))
279
+ }))
280
+ }));
113
281
  }
@@ -6,35 +6,39 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
8
  var _base = _interopRequireDefault(require("./base.js"));
9
- var _options = require("./options.js");
10
- var _index = require("../actor/index.js");
11
- var _index2 = require("../layout/index.js");
9
+ var _index = require("../layout/index.js");
12
10
  var _constants = require("../constants.js");
11
+ var _options = require("./options.js");
12
+ var _processors = require("./processors.js");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- const DEFAULT_API_OPTIONS = Object.freeze({
14
+ const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_API_OPTIONS, {
15
15
  group: _commons.API.GROUP.RECOMMENDATION,
16
16
  name: _commons.API.NAME.USER_TO_PRODUCTS,
17
- payload: {
17
+ payload: Object.assign({}, _base.default.DEFAULT_API_OPTIONS.payload, {
18
18
  fl: ['*']
19
- }
20
- });
21
- const DEFAULT_LAYOUTS = Object.freeze({
22
- [_constants.ROLE.PRODUCTS]: _index2.ListLayout.type
23
- });
24
- const DEFAULT_TRACKERS = Object.freeze({
19
+ })
20
+ }));
21
+ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _base.default.DEFAULT_LAYOUTS, {
22
+ [_constants.ROLE.PRODUCTS]: _index.ListLayout.type
23
+ }));
24
+ const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _base.default.DEFAULT_TRACKERS, {
25
25
  [_constants.ROLE.PRODUCTS]: {}
26
- });
27
- const DEFAULT_OPTIONS = Object.freeze({
26
+ }));
27
+ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_OPTIONS, {
28
28
  api: DEFAULT_API_OPTIONS,
29
29
  layouts: DEFAULT_LAYOUTS,
30
30
  trackers: DEFAULT_TRACKERS
31
+ }));
32
+ const ROLES_OPTIONS = (0, _options.mergeRolesOptions)(_base.default.ROLES_OPTIONS, {
33
+ main: _constants.ROLE.PRODUCTS,
34
+ members: Object.keys(DEFAULT_LAYOUTS)
31
35
  });
32
36
  class Recommendation extends _base.default {
33
37
  constructor(context, id) {
34
38
  super({
35
39
  name: 'recommendation',
36
40
  context,
37
- roles: Object.keys(DEFAULT_LAYOUTS),
41
+ roles: ROLES_OPTIONS,
38
42
  defaults: DEFAULT_OPTIONS,
39
43
  id
40
44
  });
@@ -48,32 +52,15 @@ class Recommendation extends _base.default {
48
52
  id
49
53
  });
50
54
  }
51
- _initReset(args) {
55
+ _initSession(args) {
52
56
  this._context._members.set(args.id, this);
53
- super._initReset(args);
57
+ super._initSession(args);
54
58
  }
55
59
 
56
60
  // lifecycle //
57
61
  start() {
58
- this._sessions.start();
59
62
  // in recommendation workflow, start() triggers query
60
- // TODO: we should still make the query lifecycle
61
- const {
62
- session
63
- } = this;
64
- this._hub.update(_index.fields.request(), (0, _options.mergeApiOptions)(this._options.resolved.api, {
65
- session
66
- }));
67
- return this;
68
- }
69
-
70
- // TODO: deprecate this
71
- startTracker() {
72
- this.useApi(false);
73
- this.useLayouts(false);
74
- this._sessions.start();
75
- this.notifyViewUpdate(_constants.ROLE.CONTAINER);
76
- this.notifyViewUpdate(_constants.ROLE.PRODUCTS);
63
+ this._request();
77
64
  return this;
78
65
  }
79
66
  notifyViewUpdate() {
@@ -86,21 +73,21 @@ class Recommendation extends _base.default {
86
73
  }
87
74
 
88
75
  // interactions //
89
- _preprocessInteraction(payload) {
90
- payload = super._preprocessInteraction(payload) || {};
91
- const {
92
- context = {}
93
- } = payload;
94
- const {
95
- custom_context = {}
96
- } = context;
97
- return Object.assign({}, payload, {
98
- context: Object.assign({}, context, {
99
- custom_context: (0, _commons.trimObj)(Object.assign({
100
- unit_id: this.id,
101
- unit_instance_uuid: this.uuid
102
- }, custom_context))
103
- })
76
+ _defaultProcessInteraction(payload, args) {
77
+ payload = super._defaultProcessInteraction(payload, args);
78
+ payload = this._writeUnitIdToInteraction(payload, args);
79
+ return payload;
80
+ }
81
+ _writeUnitIdToInteraction(payload) {
82
+ const unit_id = this.id;
83
+ const unit_instance_uuid = this.uuid;
84
+ return (0, _processors.mergeInteraction)(payload, {
85
+ context: {
86
+ custom_context: {
87
+ unit_id,
88
+ unit_instance_uuid
89
+ }
90
+ }
104
91
  });
105
92
  }
106
93
 
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _commons = require("@miso.ai/commons");
8
+ var _base = _interopRequireDefault(require("./base.js"));
9
+ var _index = require("../actor/index.js");
10
+ var _constants = require("../constants.js");
11
+ var _index2 = require("../layout/index.js");
12
+ var _processors = require("./processors.js");
13
+ var _options = require("./options.js");
14
+ const _excluded = ["filters"];
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (e.includes(n)) continue; t[n] = r[n]; } return t; }
17
+ const DEFAULT_ROWS = 10;
18
+ const DEFAULT_PAGE_LIMIT = 10;
19
+ const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_API_OPTIONS, {
20
+ group: _commons.API.GROUP.SEARCH,
21
+ payload: Object.assign({}, _base.default.DEFAULT_API_OPTIONS.payload, {
22
+ fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at', 'title'],
23
+ rows: DEFAULT_ROWS
24
+ })
25
+ }));
26
+ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _base.default.DEFAULT_LAYOUTS, {
27
+ [_constants.ROLE.QUERY]: [_index2.SearchBoxLayout.type],
28
+ [_constants.ROLE.PRODUCTS]: [_index2.ListLayout.type, {
29
+ incremental: true,
30
+ infiniteScroll: true
31
+ }],
32
+ [_constants.ROLE.KEYWORDS]: [_index2.TextLayout.type, {
33
+ raw: true
34
+ }],
35
+ [_constants.ROLE.TOTAL]: [_index2.TextLayout.type, {
36
+ raw: true,
37
+ format: 'number'
38
+ }],
39
+ [_constants.ROLE.FACETS]: [_index2.FacetsLayout.type],
40
+ [_constants.ROLE.MORE]: [_index2.MoreButtonLayout.type]
41
+ }));
42
+ const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _base.default.DEFAULT_TRACKERS, {
43
+ [_constants.ROLE.PRODUCTS]: {}
44
+ }));
45
+ const DEFAULT_PAGINATION = Object.freeze({
46
+ active: false,
47
+ mode: 'infiniteScroll',
48
+ pageLimit: 10
49
+ });
50
+ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_OPTIONS, {
51
+ api: DEFAULT_API_OPTIONS,
52
+ layouts: DEFAULT_LAYOUTS,
53
+ trackers: DEFAULT_TRACKERS,
54
+ pagination: DEFAULT_PAGINATION
55
+ }));
56
+ const ROLES_OPTIONS = (0, _options.mergeRolesOptions)(_base.default.ROLES_OPTIONS, {
57
+ main: _constants.ROLE.PRODUCTS,
58
+ members: Object.keys(DEFAULT_LAYOUTS),
59
+ mappings: {
60
+ [_constants.ROLE.FACETS]: 'facet_counts'
61
+ }
62
+ });
63
+ class SearchBasedWorkflow extends _base.default {
64
+ _initSubscriptions(args) {
65
+ super._initSubscriptions(args);
66
+ this._unsubscribes = [...this._unsubscribes, this._hub.on(_index.fields.query(), args => this._query(args)), this._hub.on(_index.fields.filters(), filters => this._refine(filters)), this._hub.on(_index.fields.more(), () => this._more())];
67
+ }
68
+ restart() {
69
+ super.restart();
70
+ this._page = 0;
71
+ }
72
+
73
+ // properties //
74
+ get exhausted() {
75
+ const data = this._hub.states[_index.fields.data()];
76
+ return !!(data && data.meta && data.meta.exhausted);
77
+ }
78
+
79
+ // query //
80
+ query(args) {
81
+ if (!args.q) {
82
+ throw new Error(`q is required in query() call`);
83
+ }
84
+ this._hub.update(_index.fields.query(), args);
85
+ }
86
+ _query(args) {
87
+ // keep track of the query args for refine and more calls
88
+ this._queryArgs = args;
89
+
90
+ // start a new session
91
+ this.restart();
92
+
93
+ // payload
94
+ const payload = this._buildPayload(args);
95
+ this._request({
96
+ payload
97
+ });
98
+ }
99
+ _refine(filters) {
100
+ // remember current facet_counts
101
+ const {
102
+ facet_counts
103
+ } = this._hub.states[_index.fields.data()].value || {};
104
+ this._currentFacetCounts = facet_counts;
105
+
106
+ // start a new session
107
+ this.restart();
108
+
109
+ // payload
110
+ const query = this._getQuery();
111
+ const payload = this._buildPayload(Object.assign({}, query, {
112
+ filters
113
+ }));
114
+ this._request({
115
+ payload
116
+ });
117
+ }
118
+ _more() {
119
+ if (this.exhausted || this._page >= DEFAULT_PAGE_LIMIT - 1) {
120
+ return; // ignore
121
+ }
122
+ // don't create a new session!
123
+
124
+ // payload
125
+ const query = this._getQuery();
126
+ const filters = this._hub.states[_index.fields.filters()]; // get stored filters
127
+ const start = (this._page + 1) * this._getPageSize();
128
+ const payload = this._buildPayload(Object.assign({}, query, {
129
+ filters,
130
+ start
131
+ }));
132
+ this._request({
133
+ payload
134
+ });
135
+ this._page++;
136
+ }
137
+ _getQuery() {
138
+ return this._queryArgs;
139
+ }
140
+ _getPageSize() {
141
+ return this._options.resolved.api.payload.rows;
142
+ }
143
+ _buildPayload() {
144
+ let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
145
+ let {
146
+ filters
147
+ } = _ref,
148
+ payload = _objectWithoutPropertiesLoose(_ref, _excluded);
149
+ payload = (0, _processors.writeFiltersToPayload)(payload, filters);
150
+ return payload;
151
+ }
152
+
153
+ // data //
154
+ _defaultProcessData(data) {
155
+ data = super._defaultProcessData(data);
156
+ data = (0, _processors.writeKeywordsToData)(data);
157
+ data = (0, _processors.retainFacetCounts)(data, this._currentFacetCounts);
158
+ data = (0, _processors.markExhaustion)(data);
159
+ return data;
160
+ }
161
+ _updateDataInHub(data) {
162
+ data = this._appendResultsFromMoreRequest(data);
163
+ super._updateDataInHub(data);
164
+ }
165
+ _appendResultsFromMoreRequest(data) {
166
+ const {
167
+ request
168
+ } = data;
169
+ if (!request || !request.payload.start) {
170
+ return data; // the initial state, or not from "more" request
171
+ }
172
+ // concat records if it's from "more" request
173
+ const currentData = this._hub.states[_index.fields.data()];
174
+ return (0, _processors.concatResults)(currentData, data);
175
+ }
176
+ }
177
+ exports.default = SearchBasedWorkflow;
178
+ (0, _options.makeConfigurable)(SearchBasedWorkflow.prototype, ['pagination']);
179
+ Object.assign(SearchBasedWorkflow, {
180
+ DEFAULT_API_OPTIONS,
181
+ DEFAULT_LAYOUTS,
182
+ DEFAULT_TRACKERS,
183
+ DEFAULT_PAGINATION,
184
+ DEFAULT_OPTIONS,
185
+ ROLES_OPTIONS
186
+ });