@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
@@ -1,4 +1,4 @@
1
- import { ROLE, STATUS, LAYOUT_CATEGORY } from '../../constants.js';
1
+ import { ROLE, STATUS } from '../../constants.js';
2
2
  import RafLayout from '../raf.js';
3
3
  import MisoBannerElement from '../../element/miso-banner.js';
4
4
  import Viewables from '../../util/viewables.js';
@@ -7,10 +7,6 @@ const TYPE = 'container';
7
7
 
8
8
  export default class ContainerLayout extends RafLayout {
9
9
 
10
- static get category() {
11
- return LAYOUT_CATEGORY.CONTAINER;
12
- }
13
-
14
10
  static get type() {
15
11
  return TYPE;
16
12
  }
@@ -1,4 +1,3 @@
1
- import { LAYOUT_CATEGORY } from '../../constants.js';
2
1
  import TemplateBasedLayout from '../template.js';
3
2
 
4
3
  const TYPE = 'error';
@@ -24,10 +23,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
24
23
 
25
24
  export default class ErrorLayout extends TemplateBasedLayout {
26
25
 
27
- static get category() {
28
- return LAYOUT_CATEGORY.ERROR;
29
- }
30
-
31
26
  static get type() {
32
27
  return TYPE;
33
28
  }
@@ -12,4 +12,5 @@ export { default as FeedbackLayout } from './radio/feedback.js';
12
12
  export { default as TextLayout } from './text/text.js';
13
13
  export { default as TypewriterLayout } from './text/typewriter/index.js';
14
14
  export { default as AffiliationLayout } from './affiliation/affiliation.js';
15
- export { default as FacetsLayout } from './input/facets.js';
15
+ export { default as FacetsLayout } from './input/facets.js';
16
+ export { default as MoreButtonLayout } from './button/more-button.js';
@@ -1,5 +1,4 @@
1
1
  import { escapeHtml } from '@miso.ai/commons';
2
- import { LAYOUT_CATEGORY } from '../../constants.js';
3
2
  import TemplateBasedLayout from '../template.js';
4
3
  import Bindings from '../../util/bindings.js';
5
4
 
@@ -88,10 +87,6 @@ function getSelectedValues(facets) {
88
87
 
89
88
  export default class FacetsLayout extends TemplateBasedLayout {
90
89
 
91
- static get category() {
92
- return LAYOUT_CATEGORY.FILTERS;
93
- }
94
-
95
90
  static get type() {
96
91
  return TYPE;
97
92
  }
@@ -125,11 +120,11 @@ export default class FacetsLayout extends TemplateBasedLayout {
125
120
 
126
121
  _render(element, data, controls) {
127
122
  super._render(element, data, controls);
128
- this._syncSelections();
129
123
  }
130
124
 
131
125
  _afterRender(element, state) {
132
126
  this._syncBindings(element, state);
127
+ this._syncSelections();
133
128
  }
134
129
 
135
130
  _unrender() {
@@ -220,6 +215,10 @@ export default class FacetsLayout extends TemplateBasedLayout {
220
215
  }
221
216
 
222
217
  _handleClick(event) {
218
+ // only left click
219
+ if (event.button !== 0) {
220
+ return;
221
+ }
223
222
  const element = event.target.closest(`[data-role="option"]`);
224
223
  if (!element) {
225
224
  return;
@@ -1,5 +1,4 @@
1
1
  import { escapeHtml } from '@miso.ai/commons';
2
- import { LAYOUT_CATEGORY } from '../../constants.js';
3
2
  import { fields } from '../../actor/index.js';
4
3
  import TemplateBasedLayout from '../template.js';
5
4
  import { makeTrackable } from '../trackable.js';
@@ -41,10 +40,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
41
40
 
42
41
  export default class OptionListLayout extends TemplateBasedLayout {
43
42
 
44
- static get category() {
45
- return LAYOUT_CATEGORY.QUERY;
46
- }
47
-
48
43
  static get type() {
49
44
  return TYPE;
50
45
  }
@@ -1,29 +1,39 @@
1
1
  import { defineValues, escapeHtml, findInAncestors, debounce } from '@miso.ai/commons';
2
- import { LAYOUT_CATEGORY, STATUS, EVENT_TYPE, DATA_ASPECT } from '../../constants.js';
2
+ import { STATUS, EVENT_TYPE } from '../../constants.js';
3
3
  import { fields } from '../../actor/index.js';
4
4
  import TemplateBasedLayout from '../template.js';
5
5
  import { imageBlock, productInfoBlock } from '../templates.js';
6
- import { SEND, SEARCH } from '../../asset/svgs.js';
6
+ import { getIcon } from '../../asset/svgs.js';
7
7
 
8
8
  const TYPE = 'search-box';
9
9
  const DEFAULT_CLASSNAME = 'miso-search-box';
10
10
  const DEFAULT_AUTOCOMPLETE_CLASSNAME = 'miso-autocomplete';
11
11
 
12
12
  function root(layout) {
13
- const { className, role, options, workflow, autocomplete } = layout;
14
- const { placeholder, buttonText } = options;
13
+ const { className, templates, role, options, autocomplete } = layout;
14
+ const { placeholder } = options;
15
15
  const roleAttr = role ? `data-role="${role}"` : '';
16
- const buttonContent = buttonText || workflow === 'search' ? SEARCH : SEND;
17
16
  return `
18
17
  <div class="${className}" ${roleAttr}>
19
18
  <div class="${className}__input-group">
20
19
  <input class="${className}__input" type="text" data-role="input" ${placeholder ? `placeholder="${placeholder}"` : ''}>
21
- <button class="${className}__button" type="submit" data-role="submit">${buttonContent}</button>
20
+ <button class="${className}__button" type="submit" data-role="submit">${templates.buttonContent(layout)}</button>
22
21
  </div>
23
22
  <div class="${autocomplete.className}" data-role="autocomplete"></div>
24
23
  </div>`.trim();
25
24
  }
26
25
 
26
+ function buttonContent(layout) {
27
+ const { templates, options } = layout;
28
+ if (options.buttonText) {
29
+ return options.buttonText; // legacy
30
+ }
31
+ const { buttonText, buttonIcon } = templates;
32
+ const text = typeof buttonText === 'function' ? buttonText(layout) : `${buttonText}`;
33
+ const icon = typeof buttonIcon === 'function' ? buttonIcon(layout) : (getIcon(buttonIcon) || `${buttonIcon}`);
34
+ return text + icon;
35
+ }
36
+
27
37
  function completions(layout, items) {
28
38
  const { templates, workflow, autocomplete } = layout;
29
39
  // use options under layout.autocomplete from now on
@@ -68,10 +78,7 @@ function product(layout, { product }) {
68
78
 
69
79
  function completionList(layout, type, items) {
70
80
  const { className, templates } = layout;
71
- return `
72
- <ul class="${className}__${type}-list" data-role="${type}-list">
73
- ${items.map(item => templates.completionItem(layout, type, item)).join('')}
74
- </ul>`.trim();
81
+ return `<ul class="${className}__${type}-list" data-role="${type}-list">${items.map(item => templates.completionItem(layout, type, item)).join('')}</ul>`;
75
82
  }
76
83
 
77
84
  function completionItem(layout, type, item) {
@@ -84,6 +91,9 @@ function completionItem(layout, type, item) {
84
91
 
85
92
  const DEFAULT_TEMPLATES = Object.freeze({
86
93
  root,
94
+ buttonContent,
95
+ buttonText: '',
96
+ buttonIcon: 'search',
87
97
  completions,
88
98
  completionList,
89
99
  completionItem,
@@ -102,10 +112,6 @@ const DEFAULT_AUTOCOMPLETE_OPTIONS = Object.freeze({
102
112
 
103
113
  export default class SearchBoxLayout extends TemplateBasedLayout {
104
114
 
105
- static get category() {
106
- return LAYOUT_CATEGORY.QUERY;
107
- }
108
-
109
115
  static get type() {
110
116
  return TYPE;
111
117
  }
@@ -141,7 +147,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
141
147
  proxyElement.on('click', (e) => this._handleClick(e)),
142
148
  proxyElement.on('focusin', (e) => this._handleFocusIn(e)),
143
149
  proxyElement.on('focusout', (e) => this._handleFocusOut(e)),
144
- hub.on(fields.data(DATA_ASPECT.AUTOCOMPLETE), () => view.refresh({ force: true })),
150
+ hub.on(fields.completions(), () => view.refresh({ force: true })),
145
151
  ];
146
152
  }
147
153
 
@@ -175,7 +181,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
175
181
  state = super._preprocess({ state });
176
182
  return {
177
183
  ...state,
178
- completions: this._view.hub.states[fields.data(DATA_ASPECT.AUTOCOMPLETE)],
184
+ completions: this._view.hub.states[fields.completions()],
179
185
  };
180
186
  }
181
187
 
@@ -185,6 +191,9 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
185
191
  super._render(element, data, controls);
186
192
  }
187
193
  this._updateCompletions(element, data, controls);
194
+ }
195
+
196
+ _afterRender(element, state) {
188
197
  this._fullfillFocusRequest(element);
189
198
  this._fullfillValueRequest(element);
190
199
  }
@@ -193,7 +202,8 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
193
202
  if (!state.completions) {
194
203
  return;
195
204
  }
196
- const { status = STATUS.INITIAL, index, value: completions } = state.completions;
205
+ const { status = STATUS.INITIAL, session, value: completions } = state.completions;
206
+ const { index } = session;
197
207
  if (rendered && rendered.completions.index === index && rendered.completions.status === status) {
198
208
  return;
199
209
  }
@@ -276,7 +286,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
276
286
  }
277
287
 
278
288
  _handleKeyDown({ key, target, isComposing }) {
279
- if (!isComposing && key === 'Enter' && target.matches('input')) {
289
+ if (!isComposing && key === 'Enter' && target.matches('[data-role="input"]')) {
280
290
  this._submit(target.value);
281
291
  target.blur();
282
292
  }
@@ -332,7 +342,7 @@ export default class SearchBoxLayout extends TemplateBasedLayout {
332
342
  if (!options) {
333
343
  return;
334
344
  }
335
- this._view.tracker.submit(value);
345
+ this._view.tracker.submit({ value }); // not array
336
346
  }
337
347
 
338
348
  }
@@ -5,10 +5,6 @@ const DEFAULT_CLASSNAME = 'miso-cards';
5
5
 
6
6
  export default class CardsLayout extends CollectionLayout {
7
7
 
8
- static get category() {
9
- return super.category;
10
- }
11
-
12
8
  static get type() {
13
9
  return TYPE;
14
10
  }
@@ -35,10 +35,6 @@ function chevron(layout) {
35
35
 
36
36
  export default class CarouselLayout extends CollectionLayout {
37
37
 
38
- static get category() {
39
- return super.category;
40
- }
41
-
42
38
  static get type() {
43
39
  return TYPE;
44
40
  }
@@ -1,13 +1,14 @@
1
- import { STATUS, LAYOUT_CATEGORY } from '../../constants.js';
1
+ import { STATUS } from '../../constants.js';
2
2
  import TemplateBasedLayout from '../template.js';
3
3
  import { makeTrackable } from '../trackable.js';
4
+ import { makeTriggerable } from '../triggerable.js';
4
5
  import { product, article, question, productInfoBlock, articleInfoBlock, titleBlock, brandBlock, descriptionBlock, dateBlock, priceBlock, discountRateText, ctaBlock, cta, imageBlock, indexBlock } from '../templates.js';
5
6
 
6
7
  function root(layout, state) {
7
8
  const { className, role, templates } = layout;
8
9
  const { status } = state;
9
10
  const roleAttr = role ? `data-role="${role}"` : '';
10
- return `<div class="${className} ${status}" ${roleAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}</div>`;
11
+ return `<div class="${className} ${status}" ${roleAttr}>${status === STATUS.READY ? templates[status](layout, state) : ''}${templates.trigger(layout, state)}${templates.loading(layout, state)}</div>`;
11
12
  }
12
13
 
13
14
  function ready(layout, state) {
@@ -15,7 +16,7 @@ function ready(layout, state) {
15
16
  const values = layout._getItems(state);
16
17
 
17
18
  // TODO: handle categories, attributes, etc. by introducing sublayout
18
- if ((values && values.length > 0) || state.ongoing) {
19
+ if ((values && values.length > 0) || state.ongoing) { // TODO: ad-hoc ongoing?
19
20
  return templates.list(layout, state, values);
20
21
  } else {
21
22
  return templates.empty(layout, state);
@@ -42,6 +43,15 @@ function item(layout, state, value, index) {
42
43
  return `<li class="${className}__item">${body}</li>`;
43
44
  }
44
45
 
46
+ function trigger(layout, state) {
47
+ const { className } = layout;
48
+ return `<div class="${className}__trigger" data-role="trigger"></div>`;
49
+ }
50
+
51
+ function loading() {
52
+ return `<div class="miso-loading" aria-label="Loading" data-role="loading"></div>`;
53
+ }
54
+
45
55
  // TODO: let templates.js control what to be included here
46
56
 
47
57
  const DEFAULT_TEMPLATES = Object.freeze({
@@ -67,14 +77,12 @@ const DEFAULT_TEMPLATES = Object.freeze({
67
77
  cta,
68
78
  imageBlock,
69
79
  indexBlock,
80
+ trigger,
81
+ loading,
70
82
  });
71
83
 
72
84
  export default class CollectionLayout extends TemplateBasedLayout {
73
85
 
74
- static get category() {
75
- return LAYOUT_CATEGORY.LIST;
76
- }
77
-
78
86
  static get defaultTemplates() {
79
87
  return DEFAULT_TEMPLATES;
80
88
  }
@@ -86,6 +94,7 @@ export default class CollectionLayout extends TemplateBasedLayout {
86
94
  ...options,
87
95
  });
88
96
  this._initTrackable();
97
+ this._initTriggerable();
89
98
  }
90
99
 
91
100
  initialize(view) {
@@ -106,8 +115,7 @@ export default class CollectionLayout extends TemplateBasedLayout {
106
115
  // TODO: compare item ids as well
107
116
  return this.options.incremental &&
108
117
  rendered && rendered.value && rendered.value.length > 0 &&
109
- state.status === STATUS.READY &&
110
- rendered.status === STATUS.READY &&
118
+ state.value && state.value.length >= rendered.value.length &&
111
119
  state.session && rendered.session &&
112
120
  state.session.id === rendered.session.id;
113
121
  }
@@ -138,10 +146,12 @@ export default class CollectionLayout extends TemplateBasedLayout {
138
146
 
139
147
  _afterRender(element, state) {
140
148
  this._syncBindings(element, state);
149
+ this._syncTrigger(element, state);
141
150
  }
142
151
 
143
152
  _unrender() {
144
153
  this._clearBindings();
154
+ this._untrackTrigger();
145
155
  }
146
156
 
147
157
  _getItems(state) {
@@ -177,6 +187,7 @@ export default class CollectionLayout extends TemplateBasedLayout {
177
187
 
178
188
  destroy() {
179
189
  this._destroyTrackable();
190
+ this._destroyTriggerable();
180
191
  this._view = undefined;
181
192
  super.destroy();
182
193
  }
@@ -184,3 +195,4 @@ export default class CollectionLayout extends TemplateBasedLayout {
184
195
  }
185
196
 
186
197
  makeTrackable(CollectionLayout.prototype);
198
+ makeTriggerable(CollectionLayout.prototype);
@@ -5,10 +5,6 @@ const DEFAULT_CLASSNAME = 'miso-list';
5
5
 
6
6
  export default class ListLayout extends CollectionLayout {
7
7
 
8
- static get category() {
9
- return super.category;
10
- }
11
-
12
8
  static get type() {
13
9
  return TYPE;
14
10
  }
@@ -50,10 +50,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
50
50
 
51
51
  export default class FeedbackLayout extends RadioLayout {
52
52
 
53
- static get category() {
54
- return super.category;
55
- }
56
-
57
53
  static get type() {
58
54
  return TYPE;
59
55
  }
@@ -1,5 +1,4 @@
1
1
  import { findInAncestors, requestAnimationFrame as raf } from '@miso.ai/commons';
2
- import { LAYOUT_CATEGORY } from '../../constants.js';
3
2
  import TemplateBasedLayout from '../template.js';
4
3
  import { requiresImplementation } from '../templates.js';
5
4
 
@@ -30,10 +29,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
30
29
 
31
30
  export default class RadioLayout extends TemplateBasedLayout {
32
31
 
33
- static get category() {
34
- return LAYOUT_CATEGORY.RADIO;
35
- }
36
-
37
32
  static get defaultTemplates() {
38
33
  return DEFAULT_TEMPLATES;
39
34
  }
package/src/layout/raf.js CHANGED
@@ -2,8 +2,8 @@ import { defineValues, requestAnimationFrame as raf, capture } from '@miso.ai/co
2
2
 
3
3
  export default class RafLayout {
4
4
 
5
- constructor({ role, workflow, ...options } = {}) {
6
- defineValues(this, { role, workflow, options });
5
+ constructor({ role, workflow, workflowOptions, ...options } = {}) {
6
+ defineValues(this, { role, workflow, workflowOptions, options });
7
7
  this._unsubscribes = [];
8
8
  this._rendered = new WeakMap();
9
9
  this._element = undefined;
@@ -1,5 +1,4 @@
1
1
  import { escapeHtml } from '@miso.ai/commons';
2
- import { LAYOUT_CATEGORY } from '../../constants.js';
3
2
  import TemplateBasedLayout from '../template.js';
4
3
 
5
4
  const TYPE = 'text';
@@ -42,10 +41,6 @@ const DEFAULT_TEMPLATES = Object.freeze({
42
41
 
43
42
  export default class TextLayout extends TemplateBasedLayout {
44
43
 
45
- static get category() {
46
- return LAYOUT_CATEGORY.TEXT;
47
- }
48
-
49
44
  static get type() {
50
45
  return TYPE;
51
46
  }
@@ -1,5 +1,5 @@
1
1
  import { trimObj, defineValues, Resolution, pacer } from '@miso.ai/commons';
2
- import { LAYOUT_CATEGORY, STATUS } from '../../../constants.js';
2
+ import { STATUS } from '../../../constants.js';
3
3
  import ProgressiveLayout from '../../progressive.js';
4
4
  import PlaintextRenderer from './plaintext.js';
5
5
  import { containerElement, cursorClassName, fromSameSession, normalizeOnDebug } from './utils.js';
@@ -9,10 +9,6 @@ const DEFAULT_CLASSNAME = 'miso-typewriter';
9
9
 
10
10
  export default class TypewriterLayout extends ProgressiveLayout {
11
11
 
12
- static get category() {
13
- return LAYOUT_CATEGORY.TEXT;
14
- }
15
-
16
12
  static get type() {
17
13
  return TYPE;
18
14
  }
@@ -1,4 +1,4 @@
1
- import { mixin } from '@miso.ai/commons';
1
+ import { mixin } from '@miso.ai/commons';
2
2
  import Bindings from '../util/bindings.js';
3
3
  import Viewables from '../util/viewables.js';
4
4
  import { validateClick } from '../util/trackers.js';
@@ -0,0 +1,76 @@
1
+ import { mixin, viewable as whenViewable } from '@miso.ai/commons';
2
+ import { STATUS } from '../constants.js';
3
+ import { fields } from '../actor/index.js';
4
+
5
+ export function makeTriggerable(prototype) {
6
+ mixin(prototype, TriggerableMixin.prototype);
7
+ }
8
+
9
+ export class TriggerableMixin {
10
+
11
+ _initTriggerable() {
12
+ this._trigger = undefined;
13
+ }
14
+
15
+ _syncTrigger(element, state) {
16
+ if (!this.options.infiniteScroll) {
17
+ return;
18
+ }
19
+ const workflowPaginationOptions = this.workflowOptions.pagination;
20
+ if (!workflowPaginationOptions.active || workflowPaginationOptions.mode !== 'infiniteScroll') {
21
+ return;
22
+ }
23
+ // only track trigger when ready
24
+ if (state.status === STATUS.READY) {
25
+ this._trackTrigger(element);
26
+ } else {
27
+ this._untrackTrigger();
28
+ }
29
+ }
30
+
31
+ async _trackTrigger(element) {
32
+ if (this._trigger) {
33
+ return;
34
+ }
35
+ const triggerElement = element.querySelector('[data-role="trigger"]');
36
+ if (!triggerElement) {
37
+ return;
38
+ }
39
+ const ac = new AbortController();
40
+ this._trigger = Object.freeze({
41
+ element: triggerElement,
42
+ ac,
43
+ });
44
+ let result = false;
45
+ try {
46
+ await whenViewable(triggerElement, { area: 1, duration: 0, signal: ac.signal });
47
+ result = true;
48
+ } catch (e) {
49
+ if (e.name !== 'AbortError') {
50
+ throw e;
51
+ }
52
+ } finally {
53
+ this._trigger = undefined;
54
+ }
55
+ if (result) {
56
+ this._onTrigger();
57
+ }
58
+ }
59
+
60
+ _onTrigger() {
61
+ this._view.hub.trigger(fields.more());
62
+ }
63
+
64
+ _untrackTrigger() {
65
+ if (!this._trigger) {
66
+ return;
67
+ }
68
+ this._trigger.ac && this._trigger.ac.abort();
69
+ this._trigger = undefined;
70
+ }
71
+
72
+ _destroyTriggerable() {
73
+ this._untrackTrigger();
74
+ }
75
+
76
+ }
@@ -4,20 +4,6 @@ import { EVENT_TYPE, TRACKING_STATUS, validateEventType, validateTrackingStatus
4
4
  const { IMPRESSION, VIEWABLE, CLICK } = EVENT_TYPE;
5
5
  const { UNTRACKED, TRIGGERED } = TRACKING_STATUS;
6
6
 
7
- /*
8
- const STATES = {
9
- NEW: Object.freeze({
10
- [IMPRESSION]: UNTRACKED,
11
- [VIEWABLE]: UNTRACKED,
12
- }),
13
- UNTRACKED: Object.freeze({
14
- [IMPRESSION]: UNTRACKED,
15
- [VIEWABLE]: UNTRACKED,
16
- [CLICK]: UNTRACKED,
17
- }),
18
- };
19
- */
20
-
21
7
  const UNTRACKED_STATES = Object.freeze({
22
8
  [IMPRESSION]: UNTRACKED,
23
9
  [VIEWABLE]: UNTRACKED,
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export default '1.11.0-beta.1';
1
+ export default '1.11.0-beta.11';