@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
@@ -9,9 +9,9 @@ var _answerBased = _interopRequireDefault(require("./answer-based.js"));
9
9
  var _index = require("../actor/index.js");
10
10
  var _constants = require("../constants.js");
11
11
  var _index2 = require("../layout/index.js");
12
+ var _processors = require("./processors.js");
12
13
  const _excluded = ["q", "qs"];
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
- function _objectDestructuringEmpty(t) { if (null == t) throw new TypeError("Cannot destructure " + t); }
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
16
  const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_API_OPTIONS, {
17
17
  name: _commons.API.NAME.QUESTIONS,
@@ -20,6 +20,11 @@ const DEFAULT_API_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default
20
20
  })
21
21
  }));
22
22
  const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _answerBased.default.DEFAULT_LAYOUTS, {
23
+ [_constants.ROLE.QUERY]: [_index2.SearchBoxLayout.type, {
24
+ templates: {
25
+ buttonIcon: 'send'
26
+ }
27
+ }],
23
28
  [_constants.ROLE.RELATED_RESOURCES]: [_index2.ListLayout.type, {
24
29
  incremental: true,
25
30
  itemType: 'article'
@@ -39,12 +44,13 @@ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEF
39
44
  layouts: DEFAULT_LAYOUTS,
40
45
  trackers: DEFAULT_TRACKERS
41
46
  }));
47
+ const ROLES_OPTIONS = _answerBased.default.ROLES_OPTIONS;
42
48
  class Ask extends _answerBased.default {
43
49
  constructor(context, parentQuestionId) {
44
50
  super({
45
51
  name: 'ask',
46
52
  context,
47
- roles: Object.keys(DEFAULT_LAYOUTS),
53
+ roles: ROLES_OPTIONS,
48
54
  defaults: DEFAULT_OPTIONS,
49
55
  parentQuestionId
50
56
  });
@@ -69,6 +75,7 @@ class Ask extends _answerBased.default {
69
75
  if (!previous) {
70
76
  return;
71
77
  }
78
+ // TODO: write question_source from payload._meta, so we don't need to write it to session.meta
72
79
  const values = previous.states[_index.fields.data()].value;
73
80
  const value = values.suggested_followup_questions || values.followup_questions || [];
74
81
  this._hub.update(_index.fields.suggestions(), {
@@ -77,11 +84,11 @@ class Ask extends _answerBased.default {
77
84
  }))
78
85
  });
79
86
  }
80
- _initReset(args) {
87
+ _initSession(args) {
81
88
  // register at context
82
89
  args.parentQuestionId && this._context._byPqid.set(args.parentQuestionId, this);
83
90
  this._context._events.emit('create', this);
84
- super._initReset(args);
91
+ super._initSession(args);
85
92
  }
86
93
 
87
94
  // lifecycle //
@@ -139,31 +146,32 @@ class Ask extends _answerBased.default {
139
146
  }
140
147
 
141
148
  // interactions //
142
- _preprocessInteraction(payload) {
143
- payload = super._preprocessInteraction(payload) || {};
144
- const {
145
- context = {}
146
- } = payload;
147
- const _ref2 = context.custom_context || {},
148
- custom_context = Object.assign({}, (_objectDestructuringEmpty(_ref2), _ref2));
149
+ _writeAskPropertiesToInteraction(payload, args) {
150
+ const root_question_id = this.rootQuestionId;
149
151
  let {
150
- rootQuestionId,
151
- parentQuestionId,
152
- questionId
153
- } = this;
154
- if (custom_context.property === _constants.ROLE.QUERY_SUGGESTIONS) {
155
- questionId = parentQuestionId;
156
- parentQuestionId = this.previous && this.previous.parentQuestionId;
157
- custom_context.property = 'suggested_followup_questions';
158
- custom_context.question_source = this.previous && this.previous.session.meta.question_source;
152
+ property
153
+ } = payload.context && payload.context.custom_context || {};
154
+ let question_id, parent_question_id, question_source;
155
+ if (args.role === _constants.ROLE.QUERY_SUGGESTIONS) {
156
+ property = 'suggested_followup_questions';
157
+ parent_question_id = this.previous && this.previous.parentQuestionId;
158
+ question_id = this.parentQuestionId;
159
+ question_source = this.previous && this.previous.session.meta.question_source;
160
+ } else {
161
+ parent_question_id = this.parentQuestionId;
162
+ question_id = this.questionId;
163
+ question_source = this._getQuestionSourceFromViewState(args);
159
164
  }
160
- custom_context.question_id = questionId;
161
- custom_context.root_question_id = rootQuestionId;
162
- custom_context.parent_question_id = parentQuestionId;
163
- return Object.assign({}, payload, {
164
- context: Object.assign({}, context, {
165
- custom_context: (0, _commons.trimObj)(custom_context)
166
- })
165
+ return (0, _processors.mergeInteraction)(payload, {
166
+ context: {
167
+ custom_context: {
168
+ property,
169
+ root_question_id,
170
+ parent_question_id,
171
+ question_id,
172
+ question_source
173
+ }
174
+ }
167
175
  });
168
176
  }
169
177
 
@@ -66,7 +66,7 @@ class Asks extends _context.default {
66
66
 
67
67
  // reset root workflow
68
68
  if (root) {
69
- this._root.reset();
69
+ this._root.restart();
70
70
  }
71
71
  }
72
72
  }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.AutocompletableMixin = void 0;
7
+ exports.makeAutocompletable = makeAutocompletable;
8
+ var _commons = require("@miso.ai/commons");
9
+ var _index = require("../actor/index.js");
10
+ var _autocomplete = _interopRequireDefault(require("./autocomplete.js"));
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ function makeAutocompletable(prototype) {
13
+ (0, _commons.mixin)(prototype, AutocompletableMixin.prototype);
14
+ }
15
+ class AutocompletableMixin {
16
+ _initAutocomplete(args) {
17
+ this._autocomplete = new _autocomplete.default(this, {
18
+ defaults: args.defaults.autocomplete
19
+ });
20
+ }
21
+ get autocomplete() {
22
+ return this._autocomplete;
23
+ }
24
+ updateCompletions(data) {
25
+ this._hub.update(_index.fields.completions(), data);
26
+ return this;
27
+ }
28
+ _destroyAutocomplete() {
29
+ this._autocomplete && this._autocomplete._destroy();
30
+ this._autocomplete = undefined;
31
+ }
32
+ }
33
+ exports.AutocompletableMixin = AutocompletableMixin;
@@ -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
+ var _index = require("../actor/index.js");
9
+ var _base = _interopRequireDefault(require("./base.js"));
10
+ const _excluded = ["layouts", "trackers"],
11
+ _excluded2 = ["defaults"];
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ 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; }
14
+ const ROLES_OPTIONS = Object.freeze({
15
+ members: []
16
+ });
17
+ function shimDefaults() {
18
+ let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
19
+ let options = _objectWithoutPropertiesLoose(_ref, _excluded);
20
+ return Object.assign({
21
+ active: false
22
+ }, options, {
23
+ layouts: {},
24
+ trackers: {}
25
+ });
26
+ }
27
+ function sameInputValue(a, b) {
28
+ return getInputValue(a) === getInputValue(b);
29
+ }
30
+ function getInputValue(args) {
31
+ return args && args.value && args.value.trim() || undefined;
32
+ }
33
+ class Autocomplete extends _base.default {
34
+ constructor(superworkflow) {
35
+ let _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
36
+ let {
37
+ defaults
38
+ } = _ref2,
39
+ args = _objectWithoutPropertiesLoose(_ref2, _excluded2);
40
+ super(Object.assign({
41
+ name: 'autocomplete',
42
+ plugin: superworkflow._plugin,
43
+ client: superworkflow._client,
44
+ defaults: shimDefaults(defaults),
45
+ roles: ROLES_OPTIONS,
46
+ superworkflow
47
+ }, args));
48
+ }
49
+ _initProperties(args) {
50
+ super._initProperties(args);
51
+ this._superworkflow = args.superworkflow;
52
+ this._active = args.defaults.active;
53
+ }
54
+ _initSubscriptions(args) {
55
+ // TODO: how to sync options updates
56
+ super._initSubscriptions(args);
57
+ this._unsubscribes = [...this._unsubscribes, args.superworkflow._hub.on(_index.fields.input(), args => this._query(args))];
58
+ }
59
+
60
+ // API //
61
+ get enabled() {
62
+ return this._active;
63
+ }
64
+ enable() {
65
+ this._active = true;
66
+ }
67
+ disable() {
68
+ this._active = false;
69
+ }
70
+
71
+ // query //
72
+ _query(args) {
73
+ if (!this._active || sameInputValue(args, this._args)) {
74
+ return;
75
+ }
76
+ this._args = args;
77
+
78
+ // start a new session
79
+ this.restart();
80
+ const {
81
+ session
82
+ } = this;
83
+ session.meta.input = args;
84
+
85
+ // if input value is blank, emit empty response
86
+ if (!getInputValue(args)) {
87
+ this._updateCompletions({
88
+ session,
89
+ status: _constants.STATUS.INITIAL
90
+ });
91
+ return;
92
+ }
93
+
94
+ // payload
95
+ const payload = this._buildPayload(args);
96
+
97
+ // request
98
+ this._request({
99
+ payload
100
+ });
101
+ }
102
+ _buildPayload(args) {
103
+ return {
104
+ q: getInputValue(args)
105
+ };
106
+ }
107
+
108
+ // data //
109
+ _updateDataInHub(data) {
110
+ if (data.value) {
111
+ data = Object.assign({}, data, {
112
+ value: data.value.completions
113
+ });
114
+ }
115
+ // update completion field in superworkflow hub
116
+ this._updateCompletions(data);
117
+ }
118
+ _updateCompletions(data) {
119
+ this._superworkflow.updateCompletions(data);
120
+ }
121
+ }
122
+ exports.default = Autocomplete;
@@ -9,42 +9,47 @@ var _index = require("../actor/index.js");
9
9
  var sources = _interopRequireWildcard(require("../source.js"));
10
10
  var _constants = require("../constants.js");
11
11
  var _index2 = require("../layout/index.js");
12
- var _utils = require("./utils.js");
13
12
  var _options = require("./options.js");
14
13
  var _processors = require("./processors.js");
15
- const _excluded = ["layouts", "interactions"],
16
- _excluded2 = ["custom_context"],
17
- _excluded3 = ["context"];
18
14
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
19
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
20
- 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
+ // TODO: just bury this into hub
17
+ function injectLogger(hub, callback) {
18
+ const {
19
+ update,
20
+ trigger
21
+ } = hub;
22
+ hub.update = (name, state, options) => {
23
+ if (!options || !options.silent) {
24
+ callback('update', name, state, options);
25
+ }
26
+ return update.call(hub, name, state, options);
27
+ };
28
+ hub.trigger = function () {
29
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
30
+ args[_key] = arguments[_key];
31
+ }
32
+ callback('trigger', ...args);
33
+ return trigger.apply(hub, args);
34
+ };
35
+ return hub;
36
+ }
37
+ const DEFAULT_API_OPTIONS = Object.freeze({});
21
38
  const DEFAULT_LAYOUTS = Object.freeze({
22
39
  [_constants.ROLE.CONTAINER]: _index2.ContainerLayout.type,
23
40
  [_constants.ROLE.ERROR]: _index2.ErrorLayout.type
24
41
  });
25
- const ROLES_CONFIG = Object.freeze({
26
- [_constants.ROLE.ERROR]: {
27
- mapping: data => data.error
42
+ const DEFAULT_TRACKERS = Object.freeze({});
43
+ const DEFAULT_OPTIONS = Object.freeze({
44
+ api: DEFAULT_API_OPTIONS,
45
+ layouts: DEFAULT_LAYOUTS,
46
+ trackers: DEFAULT_TRACKERS
47
+ });
48
+ const ROLES_OPTIONS = Object.freeze({
49
+ mappings: {
50
+ [_constants.ROLE.ERROR]: data => data.error
28
51
  }
29
52
  });
30
- function mergeDefaults(workflow) {
31
- let _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
32
- let {
33
- layouts,
34
- interactions
35
- } = _ref,
36
- defaults = _objectWithoutPropertiesLoose(_ref, _excluded);
37
- const DEFAULT_INTERACTIONS = {
38
- preprocess: [payload => workflow._preprocessInteraction(payload)]
39
- };
40
- return Object.assign({}, defaults, {
41
- layouts: (0, _options.mergeLayoutsOptions)(DEFAULT_LAYOUTS, layouts),
42
- interactions: (0, _options.mergeInteractionsOptions)(DEFAULT_INTERACTIONS, interactions)
43
- });
44
- }
45
- function getRevision(data) {
46
- return data && data.value && data.value.revision;
47
- }
48
53
  class Workflow extends _commons.Component {
49
54
  constructor(args) {
50
55
  var _this;
@@ -53,7 +58,8 @@ class Workflow extends _commons.Component {
53
58
  let {
54
59
  context,
55
60
  plugin,
56
- client
61
+ client,
62
+ options
57
63
  } = args;
58
64
  this._context = context;
59
65
  this._plugin = plugin = plugin || context._plugin;
@@ -64,23 +70,25 @@ class Workflow extends _commons.Component {
64
70
  }));
65
71
  this._name = args.name;
66
72
  this._roles = args.roles;
67
- this._rolesConfig = Object.assign({}, ROLES_CONFIG, args.rolesConfig);
68
73
  this._extensions = plugin._getExtensions(client);
69
- this._options = new _options.WorkflowOptions(context && context._options, mergeDefaults(this, args.defaults));
70
- this._hub = (0, _utils.injectLogger)(new _index.Hub(), function () {
74
+ this._defaults = args.defaults;
75
+ this._options = options || new _options.WorkflowOptions(context && context._options, args.defaults);
76
+ this._hub = injectLogger(new _index.Hub(), function () {
71
77
  return _this._log(...arguments);
72
78
  });
73
79
  this._initProperties(args);
74
80
  this._initActors(args);
75
81
  this._initSubscriptions(args);
76
- this._initReset(args);
82
+ this._initSession(args);
77
83
  }
78
84
  _initProperties() {}
79
- _initActors() {
85
+ _initActors(_ref) {
86
+ let {
87
+ name,
88
+ roles
89
+ } = _ref;
80
90
  const hub = this._hub;
81
91
  const client = this._client;
82
- const roles = this._roles;
83
- const rolesConfig = this._rolesConfig;
84
92
  const options = this._options;
85
93
  const extensions = this._extensions;
86
94
  const layouts = this._plugin.layouts;
@@ -93,32 +101,31 @@ class Workflow extends _commons.Component {
93
101
  extensions,
94
102
  layouts,
95
103
  roles,
96
- rolesConfig,
97
104
  options,
98
- workflow: this._name
105
+ workflow: name
99
106
  });
100
107
  this._interactions = new _index.InteractionsActor(hub, {
101
108
  client,
102
109
  options
103
110
  });
104
111
  }
105
- _initSubscriptions() {
106
- this._unsubscribes = [this._hub.on(_index.fields.response(), data => this.updateData(data))];
112
+ _initSubscriptions(_ref2) {
113
+ let {
114
+ roles
115
+ } = _ref2;
116
+ this._unsubscribes = [this._hub.on(_index.fields.response(), data => this.updateData(data)), this._hub.on(_index.fields.tracker(), args => this._onTracker(args))];
117
+ if (roles.main) {
118
+ this._unsubscribes.push(this._hub.on(_index.fields.view(roles.main), state => this._onMainViewUpdate(state)));
119
+ }
107
120
  }
108
- _initReset() {
109
- this.reset();
121
+ _initSession() {
122
+ this.restart();
110
123
  }
111
124
  get uuid() {
112
125
  return this.session && this.session.uuid;
113
126
  }
114
127
  get session() {
115
- return this._hub.states.session;
116
- }
117
- get active() {
118
- const {
119
- session
120
- } = this;
121
- return !!session && session.active;
128
+ return this._hub.states[_index.fields.session()];
122
129
  }
123
130
  get states() {
124
131
  return this._hub.states;
@@ -132,24 +139,58 @@ class Workflow extends _commons.Component {
132
139
  }
133
140
 
134
141
  // lifecycle //
135
- reset() {
136
- this._sessions.new();
137
- return this;
138
- }
139
- start() {
140
- this._sessions.start();
141
- return this;
142
- }
143
142
  restart() {
143
+ this._emitInterruptEventIfNecessary();
144
144
  this._sessions.restart();
145
145
  return this;
146
146
  }
147
+ _emitInterruptEventIfNecessary() {
148
+ const {
149
+ main
150
+ } = this._roles;
151
+ if (!main) {
152
+ return;
153
+ }
154
+ const state = this._hub.states[_index.fields.view(main)] || {};
155
+ if (state.session && state.status === _constants.STATUS.LOADING) {
156
+ // it's interrupted by a new question
157
+ this._emitLifecycleEvent('interrupt', state);
158
+ this._emitLifecycleEvent('finally', state);
159
+ }
160
+ }
161
+ _onMainViewUpdate(state) {
162
+ const {
163
+ status
164
+ } = state;
165
+ const done = status === _constants.STATUS.READY;
166
+ const erroneous = status === _constants.STATUS.ERRONEOUS;
167
+ const eventName = erroneous ? 'error' : status;
168
+ this._emitLifecycleEvent(eventName, state);
169
+ if (done) {
170
+ this._emitLifecycleEvent('done', state);
171
+ }
172
+ if (done || erroneous) {
173
+ this._emitLifecycleEvent('finally', state);
174
+ }
175
+ }
176
+ _emitLifecycleEvent(name, event) {
177
+ this._emit(name, event);
178
+ }
179
+
180
+ // request //
181
+ _request() {
182
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
183
+ const {
184
+ session
185
+ } = this;
186
+ const event = (0, _options.mergeApiOptions)(this._options.resolved.api, Object.assign({}, options, {
187
+ session
188
+ }));
189
+ this._hub.update(_index.fields.request(), event);
190
+ }
147
191
 
148
- // states //
192
+ // data //
149
193
  updateData(data) {
150
- let {
151
- instructions
152
- } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
153
194
  if (!data) {
154
195
  throw new Error(`Data is required.`);
155
196
  }
@@ -167,42 +208,35 @@ class Workflow extends _commons.Component {
167
208
  }
168
209
 
169
210
  // compare revision to omit outdated data, if any
170
- const revision = getRevision(data);
211
+ const revision = (0, _processors.getRevision)(data);
171
212
  if (!(0, _commons.isNullLike)(revision)) {
172
- const currentRevision = getRevision(this._hub.states[_index.fields.data()]);
213
+ const currentRevision = (0, _processors.getRevision)(this._hub.states[_index.fields.data()]);
173
214
  if (!(0, _commons.isNullLike)(currentRevision) && revision <= currentRevision) {
174
215
  return;
175
216
  }
176
217
  }
177
- this._sessions.start(); // in case session not started yet
178
-
179
- data = (0, _processors.writeDataStatus)(data);
218
+ this._updateData(data);
219
+ return this;
220
+ }
221
+ _updateData(data) {
180
222
  data = this._defaultProcessData(data);
181
223
  for (const process of this._options.resolved.dataProcessor) {
182
224
  data = process(data);
183
225
  }
184
-
185
- // write data instructions from function args
186
- data = (0, _processors.addDataInstructions)(data, instructions);
187
- data = this._mergeDataIfNecessary(data);
188
- this._hub.update(_index.fields.data(), data);
189
- return this;
226
+ this._updateDataInHub(data);
190
227
  }
191
228
  _defaultProcessData(data) {
192
- return (0, _processors.writeMisoIdToMeta)(data);
229
+ data = (0, _processors.writeDataStatus)(data);
230
+ data = (0, _processors.writeMisoIdToMeta)(data);
231
+ return data;
193
232
  }
194
- _mergeDataIfNecessary(data) {
195
- if (!data._inst || !data._inst.merge) {
196
- return data;
197
- }
198
- return Object.assign({}, this._hub.states[_index.fields.data()], data);
233
+ _updateDataInHub(data) {
234
+ this._hub.update(_index.fields.data(), data);
199
235
  }
200
- _handleResponseObject() {}
201
236
 
202
237
  // TODO: notifyViewUpdateAll()
203
238
 
204
239
  notifyViewUpdate(role, state) {
205
- this._assertActive();
206
240
  state = Object.assign({
207
241
  status: _constants.STATUS.READY,
208
242
  session: this.session
@@ -215,28 +249,59 @@ class Workflow extends _commons.Component {
215
249
  get trackers() {
216
250
  return this._views.trackers;
217
251
  }
218
- _preprocessInteraction() {
219
- let _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
220
- let {
221
- context: {
222
- custom_context
223
- } = {}
224
- } = _ref2,
225
- context = _objectWithoutPropertiesLoose(_ref2.context, _excluded2),
226
- payload = _objectWithoutPropertiesLoose(_ref2, _excluded3);
252
+ _onTracker(args) {
253
+ const payload = this._buildInteraction(args);
254
+ this._sendInteraction(payload);
255
+ }
256
+ _buildInteraction(args) {
257
+ let payload = (0, _processors.buildBaseInteraction)(args);
258
+ payload = this._defaultProcessInteraction(payload, args);
259
+ const {
260
+ preprocess = []
261
+ } = this._options.resolved.interactions;
262
+ for (const p of preprocess) {
263
+ payload = p(payload, args);
264
+ }
265
+ return payload;
266
+ }
267
+ _defaultProcessInteraction(payload, args) {
268
+ payload = this._writeApiInfoToInteraction(payload, args);
269
+ payload = this._writeMisoIdToInteraction(payload, args);
270
+ payload = (0, _processors.writeAffiliationInfoToInteraction)(payload, args);
271
+ return payload;
272
+ }
273
+ _writeApiInfoToInteraction(payload) {
227
274
  const {
228
- group: api_group,
229
- name: api_name
275
+ group,
276
+ name
230
277
  } = this._options.resolved.api;
231
- return Object.assign({}, payload, {
232
- context: Object.assign({}, context, {
233
- custom_context: Object.assign({
234
- api_group,
235
- api_name
236
- }, custom_context)
237
- })
278
+ return (0, _processors.mergeInteraction)(payload, {
279
+ context: {
280
+ custom_context: {
281
+ api_group: group,
282
+ api_name: name
283
+ }
284
+ }
238
285
  });
239
286
  }
287
+ _writeMisoIdToInteraction(payload, args) {
288
+ // TODO: ad-hoc, try to pass info from tracker
289
+ const state = this._hub.states[_index.fields.view(args.role)] || {};
290
+ const miso_id = state.meta && state.meta.miso_id || undefined;
291
+ return miso_id ? (0, _processors.mergeInteraction)(payload, {
292
+ miso_id
293
+ }) : payload;
294
+ }
295
+ _sendInteraction(payload) {
296
+ const {
297
+ handle
298
+ } = this._options.resolved.interactions;
299
+ if (typeof handle === 'function') {
300
+ handle(payload);
301
+ } else {
302
+ this._hub.trigger(_index.fields.interaction(), payload);
303
+ }
304
+ }
240
305
 
241
306
  // destroy //
242
307
  destroy(options) {
@@ -271,11 +336,13 @@ class Workflow extends _commons.Component {
271
336
  }, data));
272
337
  }
273
338
  }
274
- _assertActive() {
275
- if (!this.active) {
276
- throw new Error(`Unit is not active yet. Call unit.start() to activate it.`);
277
- }
278
- }
279
339
  }
280
340
  exports.default = Workflow;
281
- (0, _options.makeConfigurable)(Workflow.prototype);
341
+ (0, _options.makeConfigurable)(Workflow.prototype);
342
+ Object.assign(Workflow, {
343
+ DEFAULT_API_OPTIONS,
344
+ DEFAULT_LAYOUTS,
345
+ DEFAULT_TRACKERS,
346
+ DEFAULT_OPTIONS,
347
+ ROLES_OPTIONS
348
+ });