@miso.ai/client-sdk-ui 1.11.0-beta.9 → 1.11.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.
Files changed (111) hide show
  1. package/dist/cjs/actor/feedback.js +6 -39
  2. package/dist/cjs/actor/fields.js +14 -6
  3. package/dist/cjs/actor/index.js +0 -7
  4. package/dist/cjs/actor/interactions.js +4 -15
  5. package/dist/cjs/actor/sessions.js +2 -32
  6. package/dist/cjs/actor/tracker.js +25 -26
  7. package/dist/cjs/actor/utils.js +0 -49
  8. package/dist/cjs/actor/view.js +40 -40
  9. package/dist/cjs/actor/views.js +29 -8
  10. package/dist/cjs/constants.js +18 -19
  11. package/dist/cjs/defaults/hybrid-search/phrases.js +3 -3
  12. package/dist/cjs/defaults/hybrid-search/templates.js +22 -7
  13. package/dist/cjs/element/role/index.js +12 -5
  14. package/dist/cjs/element/role/{miso-hits.js → miso-more.js} +4 -4
  15. package/dist/cjs/element/role/miso-total.js +20 -0
  16. package/dist/cjs/layout/affiliation/affiliation.js +0 -3
  17. package/dist/cjs/layout/banner/banner.js +0 -4
  18. package/dist/cjs/layout/button/more-button.js +73 -0
  19. package/dist/cjs/layout/container/container.js +0 -3
  20. package/dist/cjs/layout/error/error.js +0 -4
  21. package/dist/cjs/layout/index.js +7 -0
  22. package/dist/cjs/layout/input/facets.js +0 -4
  23. package/dist/cjs/layout/input/option-list.js +0 -4
  24. package/dist/cjs/layout/input/search-box.js +13 -12
  25. package/dist/cjs/layout/list/cards.js +0 -3
  26. package/dist/cjs/layout/list/carousel.js +0 -3
  27. package/dist/cjs/layout/list/collection.js +22 -7
  28. package/dist/cjs/layout/list/list.js +0 -3
  29. package/dist/cjs/layout/radio/feedback.js +0 -3
  30. package/dist/cjs/layout/radio/radio.js +0 -4
  31. package/dist/cjs/layout/raf.js +4 -2
  32. package/dist/cjs/layout/text/text.js +0 -4
  33. package/dist/cjs/layout/text/typewriter/index.js +0 -3
  34. package/dist/cjs/layout/triggerable.js +79 -0
  35. package/dist/cjs/util/states.js +0 -15
  36. package/dist/cjs/version.js +1 -1
  37. package/dist/cjs/workflow/answer-based.js +70 -105
  38. package/dist/cjs/workflow/ask.js +29 -27
  39. package/dist/cjs/workflow/asks.js +1 -1
  40. package/dist/cjs/workflow/autocompletable.js +33 -0
  41. package/dist/cjs/workflow/autocomplete.js +122 -0
  42. package/dist/cjs/workflow/base.js +156 -98
  43. package/dist/cjs/workflow/explore.js +48 -46
  44. package/dist/cjs/workflow/hybrid-search-answer.js +17 -7
  45. package/dist/cjs/workflow/hybrid-search-results.js +17 -87
  46. package/dist/cjs/workflow/hybrid-search-views.js +122 -0
  47. package/dist/cjs/workflow/hybrid-search.js +47 -168
  48. package/dist/cjs/workflow/options.js +32 -17
  49. package/dist/cjs/workflow/processors.js +166 -2
  50. package/dist/cjs/workflow/recommendation.js +36 -49
  51. package/dist/cjs/workflow/search-based.js +228 -0
  52. package/dist/cjs/workflow/search.js +21 -68
  53. package/dist/cjs/workflow/use-link.js +44 -0
  54. package/package.json +2 -2
  55. package/src/actor/feedback.js +6 -23
  56. package/src/actor/fields.js +14 -6
  57. package/src/actor/index.js +0 -1
  58. package/src/actor/interactions.js +4 -10
  59. package/src/actor/sessions.js +3 -31
  60. package/src/actor/tracker.js +25 -19
  61. package/src/actor/utils.js +0 -47
  62. package/src/actor/view.js +27 -15
  63. package/src/actor/views.js +32 -8
  64. package/src/constants.js +25 -16
  65. package/src/defaults/hybrid-search/phrases.js +2 -2
  66. package/src/defaults/hybrid-search/templates.js +17 -5
  67. package/src/element/role/index.js +2 -1
  68. package/src/element/role/{miso-hits.js → miso-more.js} +3 -3
  69. package/src/element/role/miso-total.js +16 -0
  70. package/src/layout/affiliation/affiliation.js +1 -5
  71. package/src/layout/banner/banner.js +0 -5
  72. package/src/layout/button/more-button.js +69 -0
  73. package/src/layout/container/container.js +1 -5
  74. package/src/layout/error/error.js +0 -5
  75. package/src/layout/index.js +2 -1
  76. package/src/layout/input/facets.js +0 -5
  77. package/src/layout/input/option-list.js +0 -5
  78. package/src/layout/input/search-box.js +11 -14
  79. package/src/layout/list/cards.js +0 -4
  80. package/src/layout/list/carousel.js +0 -4
  81. package/src/layout/list/collection.js +21 -9
  82. package/src/layout/list/list.js +0 -4
  83. package/src/layout/radio/feedback.js +0 -4
  84. package/src/layout/radio/radio.js +0 -5
  85. package/src/layout/raf.js +2 -2
  86. package/src/layout/text/text.js +0 -5
  87. package/src/layout/text/typewriter/index.js +1 -5
  88. package/src/layout/triggerable.js +76 -0
  89. package/src/util/states.js +0 -14
  90. package/src/version.js +1 -1
  91. package/src/workflow/answer-based.js +61 -72
  92. package/src/workflow/ask.js +30 -24
  93. package/src/workflow/asks.js +1 -1
  94. package/src/workflow/autocompletable.js +29 -0
  95. package/src/workflow/autocomplete.js +113 -0
  96. package/src/workflow/base.js +133 -87
  97. package/src/workflow/explore.js +38 -30
  98. package/src/workflow/hybrid-search-answer.js +17 -6
  99. package/src/workflow/hybrid-search-results.js +17 -77
  100. package/src/workflow/hybrid-search-views.js +124 -0
  101. package/src/workflow/hybrid-search.js +47 -157
  102. package/src/workflow/options.js +26 -11
  103. package/src/workflow/processors.js +151 -3
  104. package/src/workflow/recommendation.js +32 -33
  105. package/src/workflow/search-based.js +222 -0
  106. package/src/workflow/search.js +21 -65
  107. package/src/workflow/use-link.js +40 -0
  108. package/dist/cjs/actor/autocomplete.js +0 -160
  109. package/dist/cjs/workflow/utils.js +0 -42
  110. package/src/actor/autocomplete.js +0 -133
  111. package/src/workflow/utils.js +0 -29
@@ -5,29 +5,25 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
- var _base = _interopRequireDefault(require("./base.js"));
8
+ var _searchBased = _interopRequireDefault(require("./search-based.js"));
9
9
  var _index = require("../actor/index.js");
10
10
  var _constants = require("../constants.js");
11
11
  var _options = require("./options.js");
12
- var _processors = require("./processors.js");
13
- const _excluded = ["filters"],
14
- _excluded2 = ["filters"];
12
+ const _excluded = ["filters"];
15
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
14
  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 ROLES_CONFIG = Object.freeze({
18
- [_constants.ROLE.FACETS]: {
19
- mapping: 'facet_counts'
20
- }
15
+ const ROLES_OPTIONS = (0, _options.mergeRolesOptions)(_searchBased.default.ROLES_OPTIONS, {
16
+ members: [_constants.ROLE.PRODUCTS, _constants.ROLE.KEYWORDS, _constants.ROLE.TOTAL, _constants.ROLE.FACETS, _constants.ROLE.MORE]
21
17
  });
22
- class HybridSearchResults extends _base.default {
18
+ class HybridSearchResults extends _searchBased.default {
23
19
  constructor(superworkflow) {
24
20
  super({
25
21
  name: 'hybrid-search/results',
26
22
  plugin: superworkflow._plugin,
27
23
  client: superworkflow._client,
28
24
  options: superworkflow._options,
29
- roles: [_constants.ROLE.PRODUCTS, _constants.ROLE.KEYWORDS, _constants.ROLE.HITS, _constants.ROLE.FACETS],
30
- rolesConfig: ROLES_CONFIG,
25
+ defaults: superworkflow._defaults,
26
+ roles: ROLES_OPTIONS,
31
27
  superworkflow
32
28
  });
33
29
  }
@@ -35,61 +31,30 @@ class HybridSearchResults extends _base.default {
35
31
  super._initProperties(args);
36
32
  this._superworkflow = args.superworkflow;
37
33
  }
38
- _initSubscriptions(args) {
39
- super._initSubscriptions(args);
40
- this._unsubscribes = [...this._unsubscribes, this._hub.on(_index.fields.filters(), filters => this._refine(filters))];
34
+ _initSession() {} // no reset here, will manually reset later
35
+
36
+ // lifecycle //
37
+ _emitLifecycleEvent(name, event) {
38
+ super._emitLifecycleEvent(name, event);
39
+ this._superworkflow._emitLifecycleEvent(name, event);
41
40
  }
42
- _initReset() {} // no reset here, will manually reset later
43
41
 
44
42
  // query //
45
- _refine(filters) {
46
- // remember current facet_counts
47
- const {
48
- facet_counts
49
- } = this._hub.states[_index.fields.data()].value || {};
50
- this._previousFacetCounts = facet_counts;
51
-
52
- // start a new session
53
- this.restart();
54
-
43
+ _getQuery() {
55
44
  // get stored query from sibling
56
- const query = this._superworkflow._answer._hub.states[_index.fields.query()];
57
- const payload = this._buildPayload(Object.assign({}, query, {
58
- filters
59
- }));
60
- const {
61
- session
62
- } = this;
63
- const event = (0, _options.mergeApiOptions)(this._options.resolved.api, {
64
- payload,
65
- session
66
- });
67
- this._request(event);
45
+ return this._superworkflow._answer._hub.states[_index.fields.query()];
68
46
  }
69
47
  _buildPayload() {
70
48
  let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
71
- let {
72
- filters
73
- } = _ref,
74
- payload = _objectWithoutPropertiesLoose(_ref, _excluded);
49
+ let payload = _objectWithoutPropertiesLoose(_ref, _excluded);
75
50
  // borrow the work from the sibling
76
51
  payload = this._superworkflow._answer._buildPayload(payload);
77
- payload = this._writeFiltersToPayload(Object.assign({}, payload, {
78
- filters
79
- }));
52
+ payload = _searchBased.default.prototype._buildPayload.call(this, payload);
80
53
  payload = this._writeQuestionIdToPayload(payload);
81
54
  return Object.assign({}, payload, {
82
55
  answer: false
83
56
  });
84
57
  }
85
- _writeFiltersToPayload() {
86
- let _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
87
- let {
88
- filters
89
- } = _ref2,
90
- payload = _objectWithoutPropertiesLoose(_ref2, _excluded2);
91
- return (0, _commons.trimObj)(Object.assign({}, payload, (0, _processors.composeFiltersPayload)(filters)));
92
- }
93
58
  _writeQuestionIdToPayload(payload) {
94
59
  return Object.assign({}, payload, {
95
60
  _meta: (0, _commons.trimObj)(Object.assign({}, payload._meta, {
@@ -97,40 +62,5 @@ class HybridSearchResults extends _base.default {
97
62
  }))
98
63
  });
99
64
  }
100
- _request(event) {
101
- this._hub.update(_index.fields.request(), event);
102
- }
103
-
104
- // data //
105
- _defaultProcessData(data) {
106
- data = super._defaultProcessData(data);
107
- data = (0, _processors.writeKeywordsToData)(data);
108
- data = this._retainFacetCounts(data);
109
- return data;
110
- }
111
- _retainFacetCounts(data) {
112
- if (!this._previousFacetCounts) {
113
- return data;
114
- }
115
- const {
116
- status,
117
- value
118
- } = data;
119
- switch (status) {
120
- case _constants.STATUS.INITIAL:
121
- case _constants.STATUS.LOADING:
122
- break;
123
- default:
124
- return data;
125
- }
126
- if (value && value.facet_counts) {
127
- return data;
128
- }
129
- return Object.assign({}, data, {
130
- value: Object.assign({}, value, {
131
- facet_counts: this._previousFacetCounts
132
- })
133
- });
134
- }
135
65
  }
136
66
  exports.default = HybridSearchResults;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _constants = require("../constants.js");
8
+ function getSubworkflowByRole(role) {
9
+ // TODO: ROLE.ERROR
10
+ switch (role) {
11
+ case _constants.ROLE.PRODUCTS:
12
+ case _constants.ROLE.TOTAL:
13
+ case _constants.ROLE.FACETS:
14
+ case _constants.ROLE.KEYWORDS:
15
+ case _constants.ROLE.MORE:
16
+ return 'results';
17
+ default:
18
+ return 'answer';
19
+ }
20
+ }
21
+ class HybridSearchViewsActor {
22
+ constructor(workflow) {
23
+ this._workflow = workflow;
24
+ this._containers = new Set();
25
+ }
26
+ get(role) {
27
+ return this._getSubviews(role).get(role);
28
+ }
29
+ addContainer(element) {
30
+ if (this._containers.has(element)) {
31
+ return;
32
+ }
33
+ this._containers.add(element);
34
+ const {
35
+ components
36
+ } = element;
37
+ for (const component of components) {
38
+ this.addComponent(component);
39
+ }
40
+ }
41
+ removeContainer(element) {
42
+ for (const subworkflow of this._workflow._subworkflows) {
43
+ subworkflow._views.removeContainer(element);
44
+ }
45
+ this._containers.delete(element);
46
+ }
47
+ addComponent(element) {
48
+ this._getViewByElement(element).element = element;
49
+ this._addContainerToSubviews(element._container, element);
50
+ }
51
+ removeComponent(element) {
52
+ this._getViewByElement(element).element = undefined;
53
+ this._removeContainerFromSubviewsIfNecessary(element._container);
54
+ }
55
+ updateComponentRole(element, oldRole, newRole) {
56
+ // TODO
57
+ }
58
+ refreshElement(element) {
59
+ const view = element.isContainer ? this._containers.get(element) : this._getViewByElement(element);
60
+ view && view.refresh({
61
+ force: true
62
+ });
63
+ }
64
+
65
+ // helpers //
66
+ _getSubworkflow(role) {
67
+ return this._workflow._getSubworkflow(getSubworkflowByRole(role));
68
+ }
69
+ _getAllSubviews() {
70
+ return this._workflow._subworkflows.flatMap(subworkflow => subworkflow._views);
71
+ }
72
+ _getSubviews(role) {
73
+ return this._getSubworkflow(role)._views;
74
+ }
75
+ _getViewByElement(element) {
76
+ let {
77
+ role
78
+ } = element;
79
+ if (!role) {
80
+ throw new Error('Component must have a role');
81
+ }
82
+ return this.get(role);
83
+ }
84
+ _addContainerToSubviews(container, child) {
85
+ if (!container) {
86
+ return;
87
+ }
88
+ const {
89
+ role
90
+ } = child;
91
+ const subviews = this._getSubviews(role);
92
+ if (subviews._containers.has(container)) {
93
+ return;
94
+ }
95
+ // check if the container is in other subviews
96
+ for (const otherSubviews of this._getAllSubviews()) {
97
+ if (otherSubviews === subviews) {
98
+ continue;
99
+ }
100
+ if (otherSubviews._containers.has(container)) {
101
+ // find the conflicting element
102
+ for (const component of container.components) {
103
+ if (otherSubviews.containsElement(component)) {
104
+ throw new Error(`<${container.tagName}> cannot contain both <${component.tagName}> and <${child.tagName}>, for they don't share the same data lifecycle.`);
105
+ }
106
+ }
107
+ throw new Error(`Failed to add container <${container.tagName}> with child component <${child.tagName}>.`);
108
+ }
109
+ }
110
+ // add the container to the subviews
111
+ subviews.addContainer(container);
112
+ }
113
+ _removeContainerFromSubviewsIfNecessary(container) {
114
+ if (!container || container.components.length > 0) {
115
+ return;
116
+ }
117
+ for (const subviews of this._getAllSubviews()) {
118
+ subviews.removeContainer(container);
119
+ }
120
+ }
121
+ }
122
+ exports.default = HybridSearchViewsActor;
@@ -7,76 +7,61 @@ exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
8
  var _index = require("../actor/index.js");
9
9
  var _base = _interopRequireDefault(require("./base.js"));
10
+ var _searchBased = _interopRequireDefault(require("./search-based.js"));
10
11
  var _answerBased = _interopRequireDefault(require("./answer-based.js"));
11
12
  var _constants = require("../constants.js");
12
13
  var _index2 = require("../layout/index.js");
13
14
  var _hybridSearchAnswer = _interopRequireDefault(require("./hybrid-search-answer.js"));
14
15
  var _hybridSearchResults = _interopRequireDefault(require("./hybrid-search-results.js"));
16
+ var _hybridSearchViews = _interopRequireDefault(require("./hybrid-search-views.js"));
15
17
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
- const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_API_OPTIONS, {
18
+ const DEFAULT_API_OPTIONS = Object.freeze({
19
+ group: _commons.API.GROUP.ASK,
17
20
  name: _commons.API.NAME.SEARCH,
18
- payload: Object.assign({}, _answerBased.default.DEFAULT_API_OPTIONS.payload, {
19
- source_fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at', 'title'],
20
- fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at', 'title']
21
+ payload: Object.assign({}, _answerBased.default.DEFAULT_API_OPTIONS.payload, _searchBased.default.DEFAULT_API_OPTIONS.payload, {
22
+ source_fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at', 'title']
21
23
  })
22
- }));
23
- const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_LAYOUTS, {
24
+ });
25
+ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_LAYOUTS, _searchBased.default.DEFAULT_LAYOUTS, {
24
26
  [_constants.ROLE.QUERY]: [_index2.SearchBoxLayout.type, {
25
27
  placeholder: ''
26
28
  }],
27
29
  [_constants.ROLE.QUESTION]: [_index2.TextLayout.type, {
28
30
  raw: true
29
- }],
30
- [_constants.ROLE.PRODUCTS]: [_index2.ListLayout.type, {
31
- itemType: 'article'
32
- }],
33
- [_constants.ROLE.KEYWORDS]: [_index2.TextLayout.type, {
34
- raw: true
35
- }],
36
- [_constants.ROLE.HITS]: [_index2.TextLayout.type, {
37
- raw: true,
38
- format: 'number'
39
- }],
40
- [_constants.ROLE.FACETS]: [_index2.FacetsLayout.type]
31
+ }]
41
32
  }));
42
- const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_TRACKERS));
43
- const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_OPTIONS, {
44
- api: DEFAULT_API_OPTIONS,
45
- layouts: DEFAULT_LAYOUTS,
46
- trackers: DEFAULT_TRACKERS
33
+ const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_TRACKERS, _searchBased.default.DEFAULT_TRACKERS));
34
+ const DEFAULT_PAGINATION = Object.freeze(Object.assign({}, _searchBased.default.DEFAULT_PAGINATION, {
35
+ active: true
47
36
  }));
48
- const ROLES_CONFIG = Object.freeze({
49
- [_constants.ROLE.QUESTION]: {
50
- mapping: _constants.ROLE.KEYWORDS
51
- },
52
- [_constants.ROLE.FACETS]: {
53
- mapping: 'facet_counts'
37
+ const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
38
+ api: {
39
+ group: _commons.API.GROUP.ASK,
40
+ name: _commons.API.NAME.SEARCH_AUTOCOMPLETE,
41
+ payload: {
42
+ completion_fields: ['suggested_queries']
43
+ }
54
44
  }
55
45
  });
56
- const SUBWORKFLOW = Object.freeze({
57
- ANSWER: 'answer',
58
- RESULTS: 'results'
46
+ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_OPTIONS, _searchBased.default.DEFAULT_OPTIONS, {
47
+ api: DEFAULT_API_OPTIONS,
48
+ layouts: DEFAULT_LAYOUTS,
49
+ trackers: DEFAULT_TRACKERS,
50
+ autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
51
+ pagination: DEFAULT_PAGINATION
52
+ }));
53
+ const ROLES_OPTIONS = Object.freeze({
54
+ main: _constants.ROLE.PRODUCTS,
55
+ members: Object.keys(DEFAULT_LAYOUTS),
56
+ mappings: Object.freeze(Object.assign({}, _answerBased.default.ROLES_OPTIONS.mappings, _searchBased.default.ROLES_OPTIONS.mappings))
59
57
  });
60
- function getSubworkflowByRole(role) {
61
- // TODO: ROLE.ERROR
62
- switch (role) {
63
- case _constants.ROLE.PRODUCTS:
64
- case _constants.ROLE.HITS:
65
- case _constants.ROLE.FACETS:
66
- case _constants.ROLE.KEYWORDS:
67
- return SUBWORKFLOW.RESULTS;
68
- default:
69
- return SUBWORKFLOW.ANSWER;
70
- }
71
- }
72
58
  class HybridSearch extends _base.default {
73
59
  constructor(plugin, client) {
74
60
  super({
75
61
  name: 'hybrid-search',
76
62
  plugin,
77
63
  client,
78
- roles: Object.keys(DEFAULT_LAYOUTS),
79
- rolesConfig: ROLES_CONFIG,
64
+ roles: ROLES_OPTIONS,
80
65
  defaults: DEFAULT_OPTIONS
81
66
  });
82
67
  }
@@ -86,9 +71,9 @@ class HybridSearch extends _base.default {
86
71
  }
87
72
  _getSubworkflow(name) {
88
73
  switch (name) {
89
- case SUBWORKFLOW.ANSWER:
74
+ case 'answer':
90
75
  return this._answer;
91
- case SUBWORKFLOW.RESULTS:
76
+ case 'results':
92
77
  return this._results;
93
78
  default:
94
79
  throw new Error(`Invalid subworkflow: ${name}`);
@@ -98,28 +83,20 @@ class HybridSearch extends _base.default {
98
83
  const hub = this._hub;
99
84
  const client = this._client;
100
85
  const options = this._options;
101
- this._views = new HybridSearchViewsActor(this);
86
+ this._views = new _hybridSearchViews.default(this);
102
87
  this._interactions = new _index.InteractionsActor(hub, {
103
88
  client,
104
89
  options
105
90
  });
106
91
  }
107
- _initReset() {
108
- this._results.reset();
109
- this._answer.reset();
92
+ _initSession() {
93
+ this._results._sessions.restart();
94
+ this._answer._sessions.restart();
110
95
  }
111
- restart() {
112
- let {
113
- answer = true
114
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
115
- const previousSession = this.session;
116
- this._sessions.restart();
117
- const {
118
- session
119
- } = this;
120
- if (!answer) {
121
- session._answer = previousSession._answer || previousSession;
122
- }
96
+
97
+ // configuration //
98
+ useLink(fn, options) {
99
+ this._answer.useLink(fn, options);
123
100
  return this;
124
101
  }
125
102
 
@@ -130,6 +107,9 @@ class HybridSearch extends _base.default {
130
107
  get filters() {
131
108
  return this._results._views.filters;
132
109
  }
110
+ get autocomplete() {
111
+ return this._answer.autocomplete;
112
+ }
133
113
 
134
114
  // query //
135
115
  autoQuery(options) {
@@ -140,8 +120,8 @@ class HybridSearch extends _base.default {
140
120
  }
141
121
 
142
122
  // interactions //
143
- _preprocessInteraction(payload) {
144
- return this._answer._preprocessInteraction(payload);
123
+ _defaultProcessInteraction(payload, args) {
124
+ return this._answer._defaultProcessInteraction(payload, args);
145
125
  }
146
126
 
147
127
  // destroy //
@@ -152,105 +132,4 @@ class HybridSearch extends _base.default {
152
132
  super._destroy();
153
133
  }
154
134
  }
155
- exports.default = HybridSearch;
156
- class HybridSearchViewsActor {
157
- constructor(workflow) {
158
- this._workflow = workflow;
159
- this._containers = new Set();
160
- }
161
- get(role) {
162
- return this._getSubviews(role).get(role);
163
- }
164
- addContainer(element) {
165
- if (this._containers.has(element)) {
166
- return;
167
- }
168
- this._containers.add(element);
169
- const {
170
- components
171
- } = element;
172
- for (const component of components) {
173
- this.addComponent(component);
174
- }
175
- }
176
- removeContainer(element) {
177
- for (const subworkflow of this._workflow._subworkflows) {
178
- subworkflow._views.removeContainer(element);
179
- }
180
- this._containers.delete(element);
181
- }
182
- addComponent(element) {
183
- this._getViewByElement(element).element = element;
184
- this._addContainerToSubviews(element._container, element);
185
- }
186
- removeComponent(element) {
187
- this._getViewByElement(element).element = undefined;
188
- this._removeContainerFromSubviewsIfNecessary(element._container);
189
- }
190
- updateComponentRole(element, oldRole, newRole) {
191
- // TODO
192
- }
193
- refreshElement(element) {
194
- const view = element.isContainer ? this._containers.get(element) : this._getViewByElement(element);
195
- view && view.refresh({
196
- force: true
197
- });
198
- }
199
-
200
- // helpers //
201
- _getSubworkflow(role) {
202
- return this._workflow._getSubworkflow(getSubworkflowByRole(role));
203
- }
204
- _getAllSubviews() {
205
- return this._workflow._subworkflows.flatMap(subworkflow => subworkflow._views);
206
- }
207
- _getSubviews(role) {
208
- return this._getSubworkflow(role)._views;
209
- }
210
- _getViewByElement(element) {
211
- let {
212
- role
213
- } = element;
214
- if (!role) {
215
- throw new Error('Component must have a role');
216
- }
217
- return this.get(role);
218
- }
219
- _addContainerToSubviews(container, child) {
220
- if (!container) {
221
- return;
222
- }
223
- const {
224
- role
225
- } = child;
226
- const subviews = this._getSubviews(role);
227
- if (subviews._containers.has(container)) {
228
- return;
229
- }
230
- // check if the container is in other subviews
231
- for (const otherSubviews of this._getAllSubviews()) {
232
- if (otherSubviews === subviews) {
233
- continue;
234
- }
235
- if (otherSubviews._containers.has(container)) {
236
- // find the conflicting element
237
- for (const component of container.components) {
238
- if (otherSubviews.containsElement(component)) {
239
- throw new Error(`<${container.tagName}> cannot contain both <${component.tagName}> and <${child.tagName}>, for they don't share the same data lifecycle.`);
240
- }
241
- }
242
- throw new Error(`Failed to add container <${container.tagName}> with child component <${child.tagName}>.`);
243
- }
244
- }
245
- // add the container to the subviews
246
- subviews.addContainer(container);
247
- }
248
- _removeContainerFromSubviewsIfNecessary(container) {
249
- if (!container || container.components.length > 0) {
250
- return;
251
- }
252
- for (const subviews of this._getAllSubviews()) {
253
- subviews.removeContainer(container);
254
- }
255
- }
256
- }
135
+ exports.default = HybridSearch;
@@ -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;