@miso.ai/client-sdk-ui 1.11.0-beta.1 → 1.11.0-beta.11

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 +35 -17
  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 +22 -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 +0 -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 +66 -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 +191 -17
  54. package/dist/cjs/workflow/recommendation.js +36 -49
  55. package/dist/cjs/workflow/search-based.js +228 -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 +29 -19
  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 +21 -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 +1 -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 +62 -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 +169 -14
  112. package/src/workflow/recommendation.js +32 -33
  113. package/src/workflow/search-based.js +222 -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
@@ -6,18 +6,18 @@ 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
9
  var _index = require("../actor/index.js");
11
10
  var _constants = require("../constants.js");
12
11
  var _index2 = require("../layout/index.js");
12
+ var _options = require("./options.js");
13
13
  const _excluded = ["value"];
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
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; }
16
- const DEFAULT_API_OPTIONS = Object.freeze({
16
+ const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_API_OPTIONS, {
17
17
  group: _commons.API.GROUP.ASK,
18
18
  name: _commons.API.NAME.RELATED_QUESTIONS
19
- });
20
- const DEFAULT_LAYOUTS = Object.freeze({
19
+ }));
20
+ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _base.default.DEFAULT_LAYOUTS, {
21
21
  [_constants.ROLE.RELATED_QUESTIONS]: [_index2.ListLayout.type, {
22
22
  itemType: 'question',
23
23
  link: {
@@ -27,18 +27,22 @@ const DEFAULT_LAYOUTS = Object.freeze({
27
27
  [_constants.ROLE.QUERY]: [_index2.SearchBoxLayout.type, {
28
28
  placeholder: 'Ask a question'
29
29
  }]
30
- });
31
- const DEFAULT_TRACKERS = Object.freeze({
30
+ }));
31
+ const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _base.default.DEFAULT_TRACKERS, {
32
32
  [_constants.ROLE.RELATED_QUESTIONS]: {},
33
33
  [_constants.ROLE.CONTAINER]: {},
34
34
  [_constants.ROLE.QUERY]: {
35
35
  [_constants.EVENT_TYPE.SUBMIT]: {}
36
36
  }
37
- });
38
- const DEFAULT_OPTIONS = Object.freeze({
37
+ }));
38
+ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_OPTIONS, {
39
39
  api: DEFAULT_API_OPTIONS,
40
40
  layouts: DEFAULT_LAYOUTS,
41
41
  trackers: DEFAULT_TRACKERS
42
+ }));
43
+ const ROLES_OPTIONS = (0, _options.mergeRolesOptions)(_base.default.ROLES_OPTIONS, {
44
+ main: _constants.ROLE.RELATED_QUESTIONS,
45
+ members: Object.keys(DEFAULT_LAYOUTS)
42
46
  });
43
47
  class Explore extends _base.default {
44
48
  constructor(plugin, client) {
@@ -46,7 +50,7 @@ class Explore extends _base.default {
46
50
  name: 'explore',
47
51
  plugin,
48
52
  client,
49
- roles: Object.keys(DEFAULT_LAYOUTS),
53
+ roles: ROLES_OPTIONS,
50
54
  defaults: DEFAULT_OPTIONS
51
55
  });
52
56
  }
@@ -57,7 +61,7 @@ class Explore extends _base.default {
57
61
  }
58
62
  _initSubscriptions(args) {
59
63
  super._initSubscriptions(args);
60
- this._unsubscribes = [...this._unsubscribes, this._views.get(_constants.ROLE.RELATED_QUESTIONS).on('click', event => this._handleRelatedQuestionClick(event)), this._hub.on(_index.fields.query(), payload => this.query(payload))];
64
+ this._unsubscribes = [...this._unsubscribes, this._views.get(_constants.ROLE.RELATED_QUESTIONS).on('click', event => this._handleRelatedQuestionClick(event)), this._hub.on(_index.fields.query(), args => this._submit(args))];
61
65
  }
62
66
 
63
67
  // configuration //
@@ -89,21 +93,18 @@ class Explore extends _base.default {
89
93
  let {
90
94
  relatedQuestions = true
91
95
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
92
- if (relatedQuestions && this._linkFn === undefined) {
96
+ if (this._linkFn === undefined) {
93
97
  throw new Error('Define link mapping function before calling start()');
94
98
  }
95
- this._sessions.start();
96
99
  // in explore workflow, start() triggers query
97
100
  // TODO: we should still make the query lifecycle
98
- const {
99
- session
100
- } = this;
101
101
  if (relatedQuestions) {
102
- this._hub.update(_index.fields.request(), (0, _options.mergeApiOptions)(this._options.resolved.api, {
103
- session
104
- }));
102
+ this._request();
105
103
  } else {
106
104
  // TODO: ad-hoc
105
+ const {
106
+ session
107
+ } = this;
107
108
  this.updateData({
108
109
  session,
109
110
  request: {},
@@ -152,7 +153,13 @@ class Explore extends _base.default {
152
153
  question
153
154
  })));
154
155
  }
155
- query() {
156
+ query(args) {
157
+ if (!args.q) {
158
+ throw new Error(`q is required in query() call`);
159
+ }
160
+ this._hub.update(_index.fields.query(), args);
161
+ }
162
+ _submit() {
156
163
  let {
157
164
  q
158
165
  } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _answerBased = _interopRequireDefault(require("./answer-based.js"));
8
+ var _constants = require("../constants.js");
9
+ var _options = require("./options.js");
10
+ var _processors = require("./processors.js");
11
+ var _autocompletable = require("./autocompletable.js");
12
+ const _excluded = ["q", "qs"];
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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; }
15
+ const ROLES_OPTIONS = (0, _options.mergeRolesOptions)(_answerBased.default.ROLES_OPTIONS, {
16
+ mappings: {
17
+ [_constants.ROLE.QUESTION]: _constants.ROLE.KEYWORDS
18
+ }
19
+ });
20
+ class HybridSearchAnswer extends _answerBased.default {
21
+ constructor(superworkflow) {
22
+ super({
23
+ name: 'hybrid-search/answer',
24
+ plugin: superworkflow._plugin,
25
+ client: superworkflow._client,
26
+ options: superworkflow._options,
27
+ defaults: superworkflow._defaults,
28
+ roles: ROLES_OPTIONS,
29
+ superworkflow
30
+ });
31
+ }
32
+ _initProperties(args) {
33
+ super._initProperties(args);
34
+ this._initAutocomplete(args);
35
+ this._superworkflow = args.superworkflow;
36
+ }
37
+ _initSession() {} // no reset here, will manually reset later
38
+
39
+ restart() {
40
+ super.restart();
41
+ // cascade restart to the sibling
42
+ const results = this._superworkflow._results;
43
+ results._views.filters.reset();
44
+ results.restart();
45
+ this._resultsSession = results.session; // keep track of the session
46
+ }
47
+
48
+ // query //
49
+ _buildPayload() {
50
+ let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
51
+ let {
52
+ q,
53
+ qs
54
+ } = _ref,
55
+ payload = _objectWithoutPropertiesLoose(_ref, _excluded);
56
+ return Object.assign({}, payload, {
57
+ q,
58
+ // q, not question
59
+ _meta: Object.assign({}, payload._meta, {
60
+ question_source: qs || _constants.ORGANIC_QUESTION_SOURCE // might be null, not undefined
61
+ })
62
+ });
63
+ }
64
+
65
+ // data //
66
+ _defaultProcessData(data) {
67
+ data = super._defaultProcessData(data);
68
+ data = (0, _processors.writeKeywordsToData)(data);
69
+ return data;
70
+ }
71
+ _updateDataInHub(data) {
72
+ switch (data.status) {
73
+ case _constants.STATUS.INITIAL:
74
+ case _constants.STATUS.LOADING:
75
+ // share the initial/loading status with its sibling
76
+ this._dispatchDataToSibling(data);
77
+ break;
78
+ }
79
+ super._updateDataInHub(data);
80
+ }
81
+ _handleHeadResponse(data) {
82
+ super._handleHeadResponse(data);
83
+ // share the search results with its sibling
84
+ this._dispatchDataToSibling(data);
85
+ }
86
+ _dispatchDataToSibling(data) {
87
+ this._resultsSession && this._superworkflow._results.updateData(Object.assign({}, data, {
88
+ session: this._resultsSession
89
+ }));
90
+ }
91
+
92
+ // destroy //
93
+ _destroy(options) {
94
+ this._destroyAutocomplete();
95
+ super._destroy(options);
96
+ }
97
+ }
98
+ exports.default = HybridSearchAnswer;
99
+ (0, _autocompletable.makeAutocompletable)(HybridSearchAnswer.prototype);
@@ -0,0 +1,66 @@
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 _searchBased = _interopRequireDefault(require("./search-based.js"));
9
+ var _index = require("../actor/index.js");
10
+ var _constants = require("../constants.js");
11
+ var _options = require("./options.js");
12
+ const _excluded = ["filters"];
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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; }
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]
17
+ });
18
+ class HybridSearchResults extends _searchBased.default {
19
+ constructor(superworkflow) {
20
+ super({
21
+ name: 'hybrid-search/results',
22
+ plugin: superworkflow._plugin,
23
+ client: superworkflow._client,
24
+ options: superworkflow._options,
25
+ defaults: superworkflow._defaults,
26
+ roles: ROLES_OPTIONS,
27
+ superworkflow
28
+ });
29
+ }
30
+ _initProperties(args) {
31
+ super._initProperties(args);
32
+ this._superworkflow = args.superworkflow;
33
+ }
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);
40
+ }
41
+
42
+ // query //
43
+ _getQuery() {
44
+ // get stored query from sibling
45
+ return this._superworkflow._answer._hub.states[_index.fields.query()];
46
+ }
47
+ _buildPayload() {
48
+ let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
49
+ let payload = _objectWithoutPropertiesLoose(_ref, _excluded);
50
+ // borrow the work from the sibling
51
+ payload = this._superworkflow._answer._buildPayload(payload);
52
+ payload = _searchBased.default.prototype._buildPayload.call(this, payload);
53
+ payload = this._writeQuestionIdToPayload(payload);
54
+ return Object.assign({}, payload, {
55
+ answer: false
56
+ });
57
+ }
58
+ _writeQuestionIdToPayload(payload) {
59
+ return Object.assign({}, payload, {
60
+ _meta: (0, _commons.trimObj)(Object.assign({}, payload._meta, {
61
+ question_id: this._superworkflow._answer.questionId
62
+ }))
63
+ });
64
+ }
65
+ }
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;
@@ -5,136 +5,131 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
- var _answerBased = _interopRequireDefault(require("./answer-based.js"));
9
- var _options = require("./options.js");
10
8
  var _index = require("../actor/index.js");
9
+ var _base = _interopRequireDefault(require("./base.js"));
10
+ var _searchBased = _interopRequireDefault(require("./search-based.js"));
11
+ var _answerBased = _interopRequireDefault(require("./answer-based.js"));
11
12
  var _constants = require("../constants.js");
12
13
  var _index2 = require("../layout/index.js");
13
- var _processors = require("./processors.js");
14
- const _excluded = ["q", "qs", "filters"];
14
+ var _hybridSearchAnswer = _interopRequireDefault(require("./hybrid-search-answer.js"));
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
- 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_API_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_API_OPTIONS, {
18
+ const DEFAULT_API_OPTIONS = Object.freeze({
19
+ group: _commons.API.GROUP.ASK,
18
20
  name: _commons.API.NAME.SEARCH,
19
- payload: Object.assign({}, _answerBased.default.DEFAULT_API_OPTIONS.payload)
20
- }));
21
- const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_LAYOUTS, {
22
- [_constants.ROLE.PRODUCTS]: [_index2.ListLayout.type, {
23
- itemType: 'article'
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']
23
+ })
24
+ });
25
+ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_LAYOUTS, _searchBased.default.DEFAULT_LAYOUTS, {
26
+ [_constants.ROLE.QUERY]: [_index2.SearchBoxLayout.type, {
27
+ placeholder: ''
24
28
  }],
25
- [_constants.ROLE.KEYWORDS]: [_index2.TextLayout.type, {
29
+ [_constants.ROLE.QUESTION]: [_index2.TextLayout.type, {
26
30
  raw: true
27
- }],
28
- [_constants.ROLE.HITS]: [_index2.TextLayout.type, {
29
- raw: true,
30
- format: 'number'
31
- }],
32
- [_constants.ROLE.FACETS]: [_index2.FacetsLayout.type]
31
+ }]
32
+ }));
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
33
36
  }));
34
- const DEFAULT_TRACKERS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_TRACKERS));
35
- const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_OPTIONS, {
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
+ }
44
+ }
45
+ });
46
+ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_OPTIONS, _searchBased.default.DEFAULT_OPTIONS, {
36
47
  api: DEFAULT_API_OPTIONS,
37
48
  layouts: DEFAULT_LAYOUTS,
38
- trackers: DEFAULT_TRACKERS
49
+ trackers: DEFAULT_TRACKERS,
50
+ autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
51
+ pagination: DEFAULT_PAGINATION
39
52
  }));
40
- const ROLES_CONFIG = Object.freeze({
41
- [_constants.ROLE.QUESTION]: {
42
- mapping: _constants.ROLE.KEYWORDS
43
- },
44
- [_constants.ROLE.FACETS]: {
45
- mapping: 'facet_counts'
46
- }
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))
47
57
  });
48
- class HybridSearch extends _answerBased.default {
58
+ class HybridSearch extends _base.default {
49
59
  constructor(plugin, client) {
50
60
  super({
51
61
  name: 'hybrid-search',
52
62
  plugin,
53
63
  client,
54
- roles: Object.keys(DEFAULT_LAYOUTS),
55
- rolesConfig: ROLES_CONFIG,
64
+ roles: ROLES_OPTIONS,
56
65
  defaults: DEFAULT_OPTIONS
57
66
  });
58
67
  }
59
- _initSubscriptions(args) {
60
- super._initSubscriptions(args);
61
- this._unsubscribes = [...this._unsubscribes, this._hub.on(_index.fields.filters(), filters => this._refine(filters))];
68
+ _initProperties(args) {
69
+ super._initProperties(args);
70
+ this._subworkflows = [this._answer = new _hybridSearchAnswer.default(this), this._results = new _hybridSearchResults.default(this)];
71
+ }
72
+ _getSubworkflow(name) {
73
+ switch (name) {
74
+ case 'answer':
75
+ return this._answer;
76
+ case 'results':
77
+ return this._results;
78
+ default:
79
+ throw new Error(`Invalid subworkflow: ${name}`);
80
+ }
81
+ }
82
+ _initActors() {
83
+ const hub = this._hub;
84
+ const client = this._client;
85
+ const options = this._options;
86
+ this._views = new _hybridSearchViews.default(this);
87
+ this._interactions = new _index.InteractionsActor(hub, {
88
+ client,
89
+ options
90
+ });
91
+ }
92
+ _initSession() {
93
+ this._results._sessions.restart();
94
+ this._answer._sessions.restart();
95
+ }
96
+
97
+ // configuration //
98
+ useLink(fn) {
99
+ this._answer.useLink(fn);
100
+ return this;
101
+ }
102
+
103
+ // properties //
104
+ get questionId() {
105
+ return this._answer.questionId;
106
+ }
107
+ get filters() {
108
+ return this._results._views.filters;
109
+ }
110
+ get autocomplete() {
111
+ return this._answer.autocomplete;
62
112
  }
63
113
 
64
114
  // query //
65
- _buildPayload() {
66
- let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
67
- let {
68
- q,
69
- qs,
70
- filters
71
- } = _ref,
72
- payload = _objectWithoutPropertiesLoose(_ref, _excluded);
73
- const fq = this._buildFq(filters); // TODO: combine with fq in payload?
74
- return (0, _commons.trimObj)(Object.assign({}, payload, {
75
- q,
76
- // q, not question
77
- fq,
78
- _meta: Object.assign({}, payload._meta, {
79
- question_source: qs || _constants.ORGANIC_QUESTION_SOURCE // might be null, not undefined
80
- })
81
- }));
115
+ autoQuery(options) {
116
+ this._answer.autoQuery(options);
82
117
  }
83
- _buildFq(filters) {
84
- if (!filters) {
85
- return undefined;
86
- }
87
- const clauses = [];
88
- const {
89
- facets
90
- } = filters;
91
- for (const field in facets) {
92
- const values = facets[field];
93
- if (!values || !values.length) {
94
- continue; // just in case
95
- }
96
- clauses.push(`${field}:(${values.map(v => `"${v}"`).join(' OR ')})`);
97
- }
98
- return clauses.map(c => `(${c})`).join(' AND ');
118
+ query(args) {
119
+ this._answer.query(args);
99
120
  }
100
- _refine(filters) {
101
- const query = this._hub.states[_index.fields.query()];
102
- const payload = this._buildPayload(Object.assign({}, query, {
103
- filters,
104
- answer: false
105
- }));
106
- const {
107
- session
108
- } = this;
109
- const event = (0, _options.mergeApiOptions)(this._options.resolved.api, {
110
- payload,
111
- session,
112
- _skipLoading: true
113
- });
114
- this._request(event);
115
121
 
116
- // emulate loading status exclusively for products
117
- // TODO
122
+ // interactions //
123
+ _defaultProcessInteraction(payload, args) {
124
+ return this._answer._defaultProcessInteraction(payload, args);
118
125
  }
119
126
 
120
- // data //
121
- _defaultProcessData(data) {
122
- data = super._defaultProcessData(data);
123
- data = (0, _processors.writeKeywordsToData)(data);
124
- data = instructPartialUpdates(data);
125
- return data;
127
+ // destroy //
128
+ _destroy() {
129
+ for (const subworkflow of this._subworkflows) {
130
+ subworkflow.destroy();
131
+ }
132
+ super._destroy();
126
133
  }
127
134
  }
128
- exports.default = HybridSearch;
129
- function instructPartialUpdates(data) {
130
- if (!data.value) {
131
- return data;
132
- }
133
- return (0, _processors.addDataInstructions)(data, data.value.products ? {
134
- includes: [_constants.ROLE.PRODUCTS, _constants.ROLE.HITS, _constants.ROLE.FACETS, _constants.ROLE.KEYWORDS, _constants.ROLE.QUESTION],
135
- merge: true
136
- } : {
137
- excludes: [_constants.ROLE.PRODUCTS, _constants.ROLE.HITS, _constants.ROLE.FACETS],
138
- merge: true
139
- });
140
- }
135
+ exports.default = HybridSearch;