@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
@@ -1,16 +1,18 @@
1
- import { trimObj, API } from '@miso.ai/commons';
1
+ import { API } from '@miso.ai/commons';
2
2
  import Workflow from './base.js';
3
- import { mergeApiOptions } from './options.js';
4
- // import * as sources from '../source.js';
5
- import { fields, FeedbackActor, AutocompleteActor } from '../actor/index.js';
6
- import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE, DATA_ASPECT } from '../constants.js';
3
+ import { fields, FeedbackActor } from '../actor/index.js';
4
+ import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
7
5
  import { SearchBoxLayout, TextLayout, ListLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
8
6
  import { processData as processAffiliationData } from '../affiliation/index.js';
9
- import { writeAnswerStageToMeta } from './processors.js';
7
+ import { mergeRolesOptions } from './options.js';
8
+ import { writeAnswerStageToMeta, mergeInteraction } from './processors.js';
9
+ import { enableUseLink } from './use-link.js';
10
10
 
11
11
  const DEFAULT_API_OPTIONS = Object.freeze({
12
+ ...Workflow.DEFAULT_API_OPTIONS,
12
13
  group: API.GROUP.ASK,
13
14
  payload: {
15
+ ...Workflow.DEFAULT_API_OPTIONS.payload,
14
16
  source_fl: ['cover_image', 'url', 'created_at', 'updated_at', 'published_at'],
15
17
  cite_link: 1,
16
18
  cite_start: '[',
@@ -27,6 +29,7 @@ const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
27
29
  });
28
30
 
29
31
  const DEFAULT_LAYOUTS = Object.freeze({
32
+ ...Workflow.DEFAULT_LAYOUTS,
30
33
  [ROLE.QUERY]: [SearchBoxLayout.type, { placeholder: 'Ask a question' }],
31
34
  [ROLE.QUESTION]: [TextLayout.type, { tag: 'h2' }],
32
35
  [ROLE.ANSWER]: TypewriterLayout.type,
@@ -36,18 +39,25 @@ const DEFAULT_LAYOUTS = Object.freeze({
36
39
  });
37
40
 
38
41
  const DEFAULT_TRACKERS = Object.freeze({
42
+ ...Workflow.DEFAULT_TRACKERS,
39
43
  [ROLE.SOURCES]: {},
40
44
  [ROLE.AFFILIATION]: {},
41
45
  [ROLE.PRODUCTS]: {},
42
46
  });
43
47
 
44
48
  const DEFAULT_OPTIONS = Object.freeze({
49
+ ...Workflow.DEFAULT_OPTIONS,
45
50
  api: DEFAULT_API_OPTIONS,
46
51
  autocomplete: DEFAULT_AUTOCOMPLETE_OPTIONS,
47
52
  layouts: DEFAULT_LAYOUTS,
48
53
  trackers: DEFAULT_TRACKERS,
49
54
  });
50
55
 
56
+ const ROLES_OPTIONS = mergeRolesOptions(Workflow.ROLES_OPTIONS, {
57
+ main: ROLE.ANSWER,
58
+ members: Object.keys(DEFAULT_LAYOUTS),
59
+ });
60
+
51
61
  export default class AnswerBasedWorkflow extends Workflow {
52
62
 
53
63
  // constructor //
@@ -60,12 +70,6 @@ export default class AnswerBasedWorkflow extends Workflow {
60
70
  _initActors(args) {
61
71
  super._initActors(args);
62
72
  this._feedback = new FeedbackActor(this._hub);
63
- /*
64
- this._autocomplete = new AutocompleteActor(this._hub, {
65
- source: sources.api(this._client),
66
- options: this._options,
67
- });
68
- */
69
73
  }
70
74
 
71
75
  _initSubscriptions(args) {
@@ -73,7 +77,6 @@ export default class AnswerBasedWorkflow extends Workflow {
73
77
  this._unsubscribes = [
74
78
  ...this._unsubscribes,
75
79
  this._hub.on(fields.query(), args => this._query(args)),
76
- this._hub.on(fields.view(ROLE.ANSWER), data => this._onAnswerViewUpdate(data)),
77
80
  this._views.get(ROLE.ANSWER).on('citation-click', event => this._onCitationClick(event)),
78
81
  ];
79
82
  }
@@ -84,19 +87,30 @@ export default class AnswerBasedWorkflow extends Workflow {
84
87
  if (this._questionId) {
85
88
  this._questionId = undefined;
86
89
  }
87
- // interrupt event
88
- // TODO: move to workflow base
89
- const { session, status, ongoing } = this._hub.states[fields.view(ROLE.ANSWER)] || {};
90
- if (session && status !== STATUS.INITIAL && (status !== STATUS.READY || ongoing)) {
91
- // it's interrupted by a new question
92
- const state = Object.freeze({ session, status, ongoing });
93
- this._emit('interrupt', state);
94
- this._emit('finally', state);
95
- }
96
90
  // restart
97
91
  super.restart();
98
92
  }
99
93
 
94
+ _emitInterruptEventIfNecessary() {
95
+ const state = this._hub.states[fields.view(this._roles.main)] || {};
96
+ if (state.session && state.status !== STATUS.INITIAL && (state.status !== STATUS.READY || state.ongoing)) {
97
+ // it's interrupted by a new question
98
+ this._emitLifecycleEvent('interrupt', state);
99
+ this._emitLifecycleEvent('finally', state);
100
+ }
101
+ }
102
+
103
+ _onMainViewUpdate(state) {
104
+ const { status } = state;
105
+ const done = status === STATUS.READY && !state.ongoing;
106
+ const erroneous = status === STATUS.ERRONEOUS;
107
+ const eventName = done ? 'done' : erroneous ? 'error' : status;
108
+ this._emitLifecycleEvent(eventName, state);
109
+ if (done || erroneous) {
110
+ this._emitLifecycleEvent('finally', state);
111
+ }
112
+ }
113
+
100
114
  // properties //
101
115
  get questionId() {
102
116
  return this._questionId;
@@ -131,44 +145,29 @@ export default class AnswerBasedWorkflow extends Workflow {
131
145
  }
132
146
 
133
147
  _query(args = {}) {
148
+ if (this._linkFn) {
149
+ this._submitToPage(args);
150
+ return;
151
+ }
134
152
  // start a new session
135
153
  this.restart();
136
154
 
137
- // TODO: move to ask workflow
138
155
  // keep track of question source on this session, for suggested questions interactions
139
156
  this._writeQuestionSourceToSession(args);
140
157
 
141
158
  // build payload and trigger request
142
- const { session } = this;
143
159
  const payload = this._buildPayload(args);
144
- const event = mergeApiOptions(this._options.resolved.api, { payload, session });
145
- this._request(event);
160
+ this._request({ payload });
146
161
  }
147
162
 
148
163
  _writeQuestionSourceToSession(args) {
149
- this.session.meta.question_source = args.questionSource || ORGANIC_QUESTION_SOURCE; // might be null, not undefined
150
- }
151
-
152
- _request(event) {
153
- this._hub.update(fields.request(), event);
164
+ this.session.meta.question_source = args.qs || ORGANIC_QUESTION_SOURCE; // might be null, not undefined
154
165
  }
155
166
 
156
167
  _buildPayload() {
157
168
  throw new Error(`Not implemented`);
158
169
  }
159
170
 
160
- // autocomplete //
161
- /*
162
- updateCompletions(event) {
163
- // TODO: verify
164
- this._hub.update(fields.data(DATA_ASPECT.AUTOCOMPLETE), {
165
- ...event,
166
- source: 'manual',
167
- });
168
- return this;
169
- }
170
- */
171
-
172
171
  // data //
173
172
  _updateData(data) {
174
173
  // if it's the head response, write question id and return
@@ -219,43 +218,32 @@ export default class AnswerBasedWorkflow extends Workflow {
219
218
  }
220
219
 
221
220
  // interactions //
222
- _preprocessInteraction(payload) {
223
- payload = super._preprocessInteraction(payload);
224
- payload = this._writeQuestionIdToInteractions(payload);
221
+ _defaultProcessInteraction(payload, args) {
222
+ payload = super._defaultProcessInteraction(payload, args);
223
+ payload = this._writeAskPropertiesToInteraction(payload, args);
225
224
  return payload;
226
225
  }
227
226
 
228
- _writeQuestionIdToInteractions(payload = {}) {
229
- const { context = {} } = payload;
230
- const { custom_context = {} } = context;
231
- let { questionId } = this;
232
- return {
233
- ...payload,
227
+ _writeAskPropertiesToInteraction(payload = {}, args) {
228
+ const question_source = this._getQuestionSourceFromViewState(args);
229
+ const question_id = this.questionId;
230
+ return mergeInteraction(payload, {
234
231
  context: {
235
- ...context,
236
- custom_context: trimObj({
237
- question_id: questionId,
238
- ...custom_context,
239
- }),
232
+ custom_context: {
233
+ question_source,
234
+ question_id,
235
+ },
240
236
  },
241
- };
237
+ });
242
238
  }
243
239
 
244
- // handlers //
245
- _onAnswerViewUpdate({ session, status, ongoing }) {
246
- if (status === STATUS.INITIAL) {
247
- return;
248
- }
249
- const done = status === STATUS.READY && !ongoing;
250
- const erroneous = status === STATUS.ERRONEOUS;
251
- const eventName = done ? 'done' : erroneous ? 'error' : status;
252
- const state = Object.freeze({ session, status, ongoing });
253
- this._emit(eventName, state);
254
- if (done || erroneous) {
255
- this._emit('finally', state);
256
- }
240
+ _getQuestionSourceFromViewState(args) {
241
+ const { request } = this._hub.states[fields.view(args.role)] || {};
242
+ const { payload } = request || {};
243
+ return (payload && payload._meta && payload._meta.question_source) || undefined;
257
244
  }
258
245
 
246
+ // handlers //
259
247
  _onCitationClick({ index }) {
260
248
  const { value } = this.states[fields.data()] || {};
261
249
  const { sources } = value || {};
@@ -289,7 +277,7 @@ export default class AnswerBasedWorkflow extends Workflow {
289
277
 
290
278
  }
291
279
 
292
- // makeConfigurable(AnswerBasedWorkflow.prototype, ['autocomplete']);
280
+ enableUseLink(AnswerBasedWorkflow.prototype);
293
281
 
294
282
  Object.assign(AnswerBasedWorkflow, {
295
283
  DEFAULT_API_OPTIONS,
@@ -297,4 +285,5 @@ Object.assign(AnswerBasedWorkflow, {
297
285
  DEFAULT_LAYOUTS,
298
286
  DEFAULT_TRACKERS,
299
287
  DEFAULT_OPTIONS,
288
+ ROLES_OPTIONS,
300
289
  });
@@ -3,6 +3,7 @@ import AnswerBasedWorkflow from './answer-based.js';
3
3
  import { fields } from '../actor/index.js';
4
4
  import { ROLE, ORGANIC_QUESTION_SOURCE } from '../constants.js';
5
5
  import { OptionListLayout, ListLayout, SearchBoxLayout } from '../layout/index.js';
6
+ import { mergeInteraction } from './processors.js';
6
7
 
7
8
  const DEFAULT_API_OPTIONS = Object.freeze({
8
9
  ...AnswerBasedWorkflow.DEFAULT_API_OPTIONS,
@@ -37,13 +38,15 @@ const DEFAULT_OPTIONS = Object.freeze({
37
38
  trackers: DEFAULT_TRACKERS,
38
39
  });
39
40
 
41
+ const ROLES_OPTIONS = AnswerBasedWorkflow.ROLES_OPTIONS;
42
+
40
43
  export default class Ask extends AnswerBasedWorkflow {
41
44
 
42
45
  constructor(context, parentQuestionId) {
43
46
  super({
44
47
  name: 'ask',
45
48
  context,
46
- roles: Object.keys(DEFAULT_LAYOUTS),
49
+ roles: ROLES_OPTIONS,
47
50
  defaults: DEFAULT_OPTIONS,
48
51
  parentQuestionId,
49
52
  });
@@ -71,11 +74,11 @@ export default class Ask extends AnswerBasedWorkflow {
71
74
  this._hub.update(fields.suggestions(), { value: value.map(text => ({ text })) });
72
75
  }
73
76
 
74
- _initReset(args) {
77
+ _initSession(args) {
75
78
  // register at context
76
79
  args.parentQuestionId && this._context._byPqid.set(args.parentQuestionId, this);
77
80
  this._context._events.emit('create', this);
78
- super._initReset(args);
81
+ super._initSession(args);
79
82
  }
80
83
 
81
84
  // lifecycle //
@@ -121,30 +124,33 @@ export default class Ask extends AnswerBasedWorkflow {
121
124
  }
122
125
 
123
126
  // interactions //
124
- _preprocessInteraction(payload) {
125
- payload = super._preprocessInteraction(payload) || {};
126
-
127
- const { context = {} } = payload;
128
- const { ...custom_context } = context.custom_context || {};
129
- let { rootQuestionId, parentQuestionId, questionId } = this;
130
-
131
- if (custom_context.property === ROLE.QUERY_SUGGESTIONS) {
132
- questionId = parentQuestionId;
133
- parentQuestionId = this.previous && this.previous.parentQuestionId;
134
- custom_context.property = 'suggested_followup_questions';
135
- custom_context.question_source = this.previous && this.previous.session.meta.question_source;
127
+ _writeAskPropertiesToInteraction(payload, args) {
128
+ const root_question_id = this.rootQuestionId;
129
+ let { property } = (payload.context && payload.context.custom_context) || {};
130
+ let question_id, parent_question_id, question_source;
131
+
132
+ if (args.role === ROLE.QUERY_SUGGESTIONS) {
133
+ property = 'suggested_followup_questions';
134
+ parent_question_id = this.previous && this.previous.parentQuestionId;
135
+ question_id = this.parentQuestionId;
136
+ question_source = this.previous && this.previous.session.meta.question_source;
137
+ } else {
138
+ parent_question_id = this.parentQuestionId;
139
+ question_id = this.questionId;
140
+ question_source = this._getQuestionSourceFromViewState(args);
136
141
  }
137
- custom_context.question_id = questionId;
138
- custom_context.root_question_id = rootQuestionId;
139
- custom_context.parent_question_id = parentQuestionId;
140
142
 
141
- return {
142
- ...payload,
143
+ return mergeInteraction(payload, {
143
144
  context: {
144
- ...context,
145
- custom_context: trimObj(custom_context),
146
- },
147
- };
145
+ custom_context: {
146
+ property,
147
+ root_question_id,
148
+ parent_question_id,
149
+ question_id,
150
+ question_source,
151
+ },
152
+ }
153
+ });
148
154
  }
149
155
 
150
156
  // helpers //
@@ -55,7 +55,7 @@ export default class Asks extends WorkflowContext {
55
55
 
56
56
  // reset root workflow
57
57
  if (root) {
58
- this._root.reset();
58
+ this._root.restart();
59
59
  }
60
60
  }
61
61
 
@@ -0,0 +1,29 @@
1
+ import { mixin } from '@miso.ai/commons';
2
+ import { fields } from '../actor/index.js';
3
+ import Autocomplete from './autocomplete.js';
4
+
5
+ export function makeAutocompletable(prototype) {
6
+ mixin(prototype, AutocompletableMixin.prototype);
7
+ }
8
+
9
+ export class AutocompletableMixin {
10
+
11
+ _initAutocomplete(args) {
12
+ this._autocomplete = new Autocomplete(this, { defaults: args.defaults.autocomplete });
13
+ }
14
+
15
+ get autocomplete() {
16
+ return this._autocomplete;
17
+ }
18
+
19
+ updateCompletions(data) {
20
+ this._hub.update(fields.completions(), data);
21
+ return this;
22
+ }
23
+
24
+ _destroyAutocomplete() {
25
+ this._autocomplete && this._autocomplete._destroy();
26
+ this._autocomplete = undefined;
27
+ }
28
+
29
+ }
@@ -0,0 +1,113 @@
1
+ import { STATUS } from '../constants.js';
2
+ import { fields } from '../actor/index.js';
3
+ import Workflow from './base.js';
4
+
5
+ const ROLES_OPTIONS = Object.freeze({
6
+ members: [],
7
+ });
8
+
9
+ function shimDefaults({ layouts, trackers, ...options } = {}) {
10
+ return {
11
+ active: false,
12
+ ...options,
13
+ layouts: {},
14
+ trackers: {},
15
+ };
16
+ }
17
+
18
+ function sameInputValue(a, b) {
19
+ return getInputValue(a) === getInputValue(b);
20
+ }
21
+
22
+ function getInputValue(args) {
23
+ return (args && args.value && args.value.trim()) || undefined;
24
+ }
25
+
26
+ export default class Autocomplete extends Workflow {
27
+
28
+ constructor(superworkflow, { defaults, ...args } = {}) {
29
+ super({
30
+ name: 'autocomplete',
31
+ plugin: superworkflow._plugin,
32
+ client: superworkflow._client,
33
+ defaults: shimDefaults(defaults),
34
+ roles: ROLES_OPTIONS,
35
+ superworkflow,
36
+ ...args,
37
+ });
38
+ }
39
+
40
+ _initProperties(args) {
41
+ super._initProperties(args);
42
+ this._superworkflow = args.superworkflow;
43
+ this._active = args.defaults.active;
44
+ }
45
+
46
+ _initSubscriptions(args) {
47
+ // TODO: how to sync options updates
48
+ super._initSubscriptions(args);
49
+ this._unsubscribes = [
50
+ ...this._unsubscribes,
51
+ args.superworkflow._hub.on(fields.input(), args => this._query(args)),
52
+ ];
53
+ }
54
+
55
+ // API //
56
+ get enabled() {
57
+ return this._active;
58
+ }
59
+
60
+ enable() {
61
+ this._active = true;
62
+ }
63
+
64
+ disable() {
65
+ this._active = false;
66
+ }
67
+
68
+ // query //
69
+ _query(args) {
70
+ if (!this._active || sameInputValue(args, this._args)) {
71
+ return;
72
+ }
73
+ this._args = args;
74
+
75
+ // start a new session
76
+ this.restart();
77
+ const { session } = this;
78
+ session.meta.input = args;
79
+
80
+ // if input value is blank, emit empty response
81
+ if (!getInputValue(args)) {
82
+ this._updateCompletions({ session, status: STATUS.INITIAL });
83
+ return;
84
+ }
85
+
86
+ // payload
87
+ const payload = this._buildPayload(args);
88
+
89
+ // request
90
+ this._request({ payload });
91
+ }
92
+
93
+ _buildPayload(args) {
94
+ return { q: getInputValue(args) };
95
+ }
96
+
97
+ // data //
98
+ _updateDataInHub(data) {
99
+ if (data.value) {
100
+ data = {
101
+ ...data,
102
+ value: data.value.completions,
103
+ };
104
+ }
105
+ // update completion field in superworkflow hub
106
+ this._updateCompletions(data);
107
+ }
108
+
109
+ _updateCompletions(data) {
110
+ this._superworkflow.updateCompletions(data);
111
+ }
112
+
113
+ }