@miso.ai/client-sdk-core 1.8.0-beta.9 → 1.8.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 (54) hide show
  1. package/dist/cjs/api/api.js +25 -0
  2. package/dist/cjs/api/ask.js +11 -6
  3. package/dist/cjs/api/constants.js +28 -0
  4. package/dist/cjs/api/helpers.js +2 -2
  5. package/dist/cjs/api/index.js +54 -19
  6. package/dist/cjs/api/interactions.js +5 -4
  7. package/dist/cjs/api/recommendation.js +9 -8
  8. package/dist/cjs/api/search.js +6 -5
  9. package/dist/cjs/classes.js +5 -15
  10. package/dist/cjs/client.js +2 -2
  11. package/dist/cjs/constants.js +2 -2
  12. package/dist/cjs/index.js +39 -5
  13. package/dist/cjs/plugin/auto-events.js +3 -2
  14. package/dist/cjs/plugin/index.js +3 -3
  15. package/dist/cjs/plugin/plugin-root.js +13 -4
  16. package/dist/cjs/root.js +3 -2
  17. package/dist/cjs/version.js +1 -1
  18. package/package.json +9 -9
  19. package/{dist/es/api/index.js → src/api/api.js} +9 -6
  20. package/src/api/ask.js +80 -0
  21. package/src/api/base.js +47 -0
  22. package/src/api/constants.js +21 -0
  23. package/{dist/es → src}/api/helpers.js +48 -92
  24. package/src/api/index.js +8 -0
  25. package/src/api/interactions.js +55 -0
  26. package/src/api/recommendation.js +34 -0
  27. package/src/api/search.js +22 -0
  28. package/src/classes.js +7 -0
  29. package/{dist/es → src}/client.js +25 -10
  30. package/{dist/es → src}/cmd.js +7 -8
  31. package/src/constants.js +4 -0
  32. package/{dist/es → src}/context.js +4 -1
  33. package/src/index.js +4 -0
  34. package/{dist/es → src}/plugin/anonymous.js +5 -4
  35. package/{dist/es → src}/plugin/auto-events.js +27 -27
  36. package/src/plugin/index.js +3 -0
  37. package/{dist/es → src}/plugin/page-info.js +28 -24
  38. package/{dist/es → src}/plugin/plugin-root.js +48 -23
  39. package/{dist/es → src}/plugin/urls.js +2 -1
  40. package/{dist/es → src}/plugin/user.js +32 -37
  41. package/{dist/es → src}/root.js +11 -4
  42. package/src/utils.js +1 -0
  43. package/src/version.js +1 -0
  44. package/dist/es/api/ask.js +0 -85
  45. package/dist/es/api/base.js +0 -96
  46. package/dist/es/api/interactions.js +0 -82
  47. package/dist/es/api/recommendation.js +0 -24
  48. package/dist/es/api/search.js +0 -15
  49. package/dist/es/classes.js +0 -20
  50. package/dist/es/constants.js +0 -4
  51. package/dist/es/index.js +0 -2
  52. package/dist/es/plugin/index.js +0 -3
  53. package/dist/es/utils.js +0 -1
  54. package/dist/es/version.js +0 -1
@@ -1,44 +1,44 @@
1
1
  import { Component } from '@miso.ai/commons';
2
+ import { constants as API } from '../api/index.js';
3
+
2
4
  const PLUGIN_ID = 'std:auto-events';
5
+
3
6
  export default class AutoEventsPlugin extends Component {
7
+
4
8
  static get id() {
5
9
  return PLUGIN_ID;
6
10
  }
11
+
7
12
  constructor() {
8
13
  super('auto-events');
9
14
  this._contexts = new WeakMap();
10
15
  }
16
+
11
17
  install(MisoClient, context) {
12
18
  context.addSubtree(this);
13
19
  MisoClient.on('create', this._injectClient.bind(this));
14
20
  context.addPayloadPass(this._captureApiRequest.bind(this));
15
21
  }
22
+
16
23
  _injectClient(client) {
17
24
  const context = new AutoEventsContext(this);
18
25
  this._contexts.set(client, context);
19
26
  client.autoEvents = context.interface;
20
27
  }
21
- _captureApiRequest(_ref) {
22
- let {
23
- client,
24
- apiGroup,
25
- apiName,
26
- payload
27
- } = _ref;
28
+
29
+ _captureApiRequest({ client, apiGroup, apiName, payload }) {
28
30
  switch (apiGroup) {
29
- case 'search':
31
+ case API.GROUP.SEARCH:
30
32
  switch (apiName) {
31
- case 'search':
33
+ case API.NAME.SEARCH:
32
34
  this._captureSearchApiRequest(client, payload);
33
35
  break;
34
36
  }
35
37
  break;
36
38
  }
37
39
  }
38
- _captureSearchApiRequest(client, _ref2) {
39
- let {
40
- q: keywords
41
- } = _ref2;
40
+
41
+ _captureSearchApiRequest(client, { q: keywords }) {
42
42
  if (!keywords || keywords === '*') {
43
43
  // might be a facet search without real keywords
44
44
  return;
@@ -49,29 +49,26 @@ export default class AutoEventsPlugin extends Component {
49
49
  }
50
50
  client.api.interactions.upload({
51
51
  type: 'search',
52
- search: {
53
- keywords
54
- },
55
- context: {
56
- custom_context: {
57
- channel: 'miso_api'
58
- }
59
- }
52
+ search: { keywords },
53
+ context: { custom_context: { channel: 'miso_api' } },
60
54
  });
61
55
  }
56
+
62
57
  }
58
+
63
59
  class AutoEventsContext {
60
+
64
61
  constructor(plugin) {
65
62
  this._plugin = plugin;
66
63
  this._config = {
67
- search: true
64
+ search: true,
68
65
  };
69
66
  this.interface = Object.freeze({
70
- config: this.config.bind(this)
67
+ config: this.config.bind(this),
71
68
  });
72
69
  }
73
- config() {
74
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
70
+
71
+ config(options = {}) {
75
72
  if (typeof options !== 'object') {
76
73
  throw new Error(`Config options must be an object or undefined: ${options}`);
77
74
  }
@@ -86,6 +83,9 @@ class AutoEventsContext {
86
83
  this._plugin._events.emit('config', `${key}: ${oldValue} -> ${newValue}`);
87
84
  }
88
85
  }
89
- return Object.freeze(Object.assign({}, this._config));
86
+ return Object.freeze({
87
+ ...this._config,
88
+ });
90
89
  }
91
- }
90
+
91
+ }
@@ -0,0 +1,3 @@
1
+ export { default as UserPlugin } from './user.js';
2
+ export { default as PageInfoPlugin } from './page-info.js';
3
+ export { default as AutoEventsPlugin } from './auto-events.js';
@@ -1,49 +1,53 @@
1
1
  import { trimObj } from '@miso.ai/commons';
2
+
2
3
  const ID = 'std:page-info';
4
+
3
5
  export default class PageInfoPlugin {
6
+
4
7
  static get id() {
5
8
  return ID;
6
9
  }
7
- constructor() {}
8
- install(_, _ref) {
9
- let {
10
- addPayloadPass
11
- } = _ref;
10
+
11
+ constructor() {
12
+ }
13
+
14
+ install(_, { addPayloadPass }) {
12
15
  addPayloadPass(this._modifyPayload.bind(this));
13
16
  }
14
- _modifyPayload(_ref2) {
15
- let {
16
- apiGroup,
17
- apiName,
18
- payload
19
- } = _ref2;
20
- return apiGroup === 'interactions' && apiName === 'upload' ? this._modifyPayloadForInteractions(payload) : payload;
17
+
18
+ _modifyPayload({ apiGroup, apiName, payload }) {
19
+ return apiGroup === 'interactions' && apiName === 'upload' ?
20
+ this._modifyPayloadForInteractions(payload) : payload;
21
21
  }
22
- _modifyPayloadForInteractions(_ref3) {
23
- let {
24
- data
25
- } = _ref3;
26
- data = data.map(obj => Object.assign({}, obj, {
27
- context: Object.assign({}, getPayloadContext(), obj.context)
22
+
23
+ _modifyPayloadForInteractions({ data }) {
24
+ data = data.map(obj => ({
25
+ ...obj,
26
+ context: {
27
+ ...getPayloadContext(),
28
+ ...obj.context,
29
+ },
28
30
  }));
29
- return {
30
- data
31
- };
31
+ return { data };
32
32
  }
33
+
33
34
  }
35
+
34
36
  function getPayloadContext() {
35
37
  return trimObj({
36
38
  page: readPageInfo(),
37
39
  campaign: readUtm()
38
40
  });
39
41
  }
42
+
40
43
  function readPageInfo() {
41
44
  return trimObj({
42
45
  url: window.location.href,
43
46
  referrer: document.referrer,
44
- title: document.title
47
+ title: document.title,
45
48
  });
46
49
  }
50
+
47
51
  function readUtm() {
48
52
  const params = new URLSearchParams(window.location.search);
49
53
  let utm = trimObj({
@@ -51,7 +55,7 @@ function readUtm() {
51
55
  medium: params.get('utm_medium') || undefined,
52
56
  name: params.get('utm_campaign') || undefined,
53
57
  term: params.get('utm_term') || undefined,
54
- content: params.get('utm_content') || undefined
58
+ content: params.get('utm_content') || undefined,
55
59
  });
56
60
  return Object.keys(utm).length === 0 ? undefined : utm;
57
- }
61
+ }
@@ -1,12 +1,14 @@
1
- import { delegateGetters, defineValues, Registry, Resolution, Resources, uuidv4 } from '@miso.ai/commons';
2
- import classes from '../classes';
3
- import AnonymousPlugin from './anonymous';
4
- import { getPluginScriptUrl } from './urls';
1
+ import { delegateGetters, defineValues, Registry, Resolution, Resources } from '@miso.ai/commons';
2
+ import classes from '../classes.js';
3
+ import AnonymousPlugin from './anonymous.js';
4
+ import { getPluginScriptUrl } from './urls.js';
5
+
5
6
  export default class PluginRoot extends Registry {
7
+
6
8
  constructor(root) {
7
9
  super('plugins', root, {
8
10
  libName: 'plugin class',
9
- keyName: 'id'
11
+ keyName: 'id',
10
12
  });
11
13
  this._root = root;
12
14
  this._currentScript = document.currentScript;
@@ -18,16 +20,20 @@ export default class PluginRoot extends Registry {
18
20
  this.context = new PluginContext(this, classes);
19
21
  this.plugins = new Plugins(this);
20
22
  }
23
+
21
24
  isInstalled(id) {
22
25
  this._checkKey(id);
23
26
  return !!this._installed[id];
24
27
  }
28
+
25
29
  get installed() {
26
30
  return Object.values(this._installed);
27
31
  }
32
+
28
33
  get(id) {
29
34
  return this._installed[id];
30
35
  }
36
+
31
37
  getPluginClass(id) {
32
38
  return this._libraries[id];
33
39
  }
@@ -56,6 +62,7 @@ export default class PluginRoot extends Registry {
56
62
  instance = this._instantiate(plugin, options);
57
63
  this._install(instance);
58
64
  }
65
+
59
66
  async install(plugin, options) {
60
67
  this.use(plugin, options);
61
68
  if (typeof plugin === 'string' && !this.isRegistered(plugin)) {
@@ -63,31 +70,44 @@ export default class PluginRoot extends Registry {
63
70
  }
64
71
  return this.whenInstalled(plugin);
65
72
  }
73
+
66
74
  async whenInstalled(id) {
75
+ if (typeof id === 'function' && id.id && typeof id.id === 'string') {
76
+ id = id.id;
77
+ }
67
78
  if (this.isInstalled(id)) {
68
79
  return this.get(id);
69
80
  }
70
- const {
71
- promise
72
- } = this._installedResolutions[id] || (this._installedResolutions[id] = new Resolution());
81
+ const { promise } = this._installedResolutions[id] || (this._installedResolutions[id] = new Resolution());
73
82
  return promise;
74
83
  }
84
+
75
85
  addSubtree(component) {
76
86
  this._subtrees.push(component);
77
87
  this._events.emit('subtree', component);
78
88
  }
89
+
79
90
  addPayloadPass(pass) {
80
91
  if (typeof pass !== 'function') {
81
92
  throw new Error(`Expect parameter to be a function: ${pass}`);
82
93
  }
83
94
  this._root._payloadPasses.push(pass);
84
95
  }
96
+
85
97
  addUrlPass(pass) {
86
98
  if (typeof pass !== 'function') {
87
99
  throw new Error(`Expect parameter to be a function: ${pass}`);
88
100
  }
89
101
  this._root._urlPasses.push(pass);
90
102
  }
103
+
104
+ setCustomFetch(fetch) {
105
+ if (typeof fetch !== 'function') {
106
+ throw new Error(`Expect parameter to be a function: ${fetch}`);
107
+ }
108
+ this._root._customFetch = fetch;
109
+ }
110
+
91
111
  _tryConfig(instance, options) {
92
112
  if (options === undefined) {
93
113
  return;
@@ -99,6 +119,7 @@ export default class PluginRoot extends Registry {
99
119
  this._warn(`Attempt to pass options to plugin "${instance.id}", which offers no config() method.`);
100
120
  }
101
121
  }
122
+
102
123
  _instantiate(plugin, options) {
103
124
  switch (typeof plugin) {
104
125
  case 'string':
@@ -108,9 +129,7 @@ export default class PluginRoot extends Registry {
108
129
  throw new Error(`Plugin class not found: ${plugin}`);
109
130
  }
110
131
  const instance = new pluginClass();
111
- defineValues(instance, {
112
- id: plugin
113
- });
132
+ defineValues(instance, { id: plugin });
114
133
  this._tryConfig(instance, options);
115
134
  return instance;
116
135
  case 'function':
@@ -118,6 +137,7 @@ export default class PluginRoot extends Registry {
118
137
  }
119
138
  throw new Error(`Unexpected parameters: ${plugin}`);
120
139
  }
140
+
121
141
  _install(instance) {
122
142
  if (typeof instance.install !== 'function') {
123
143
  // TODO: introduce PluginError
@@ -127,7 +147,7 @@ export default class PluginRoot extends Registry {
127
147
  instance.installed = false;
128
148
  instance.install(this.MisoClient, this.context);
129
149
  instance.installed = true;
130
- } catch (e) {
150
+ } catch(e) {
131
151
  // TODO: introduce PluginError
132
152
  throw e;
133
153
  }
@@ -141,39 +161,41 @@ export default class PluginRoot extends Registry {
141
161
  }
142
162
  this._events.emit('install', instance);
143
163
  }
164
+
144
165
  _register(lib) {
145
166
  super._register(lib);
146
167
  this._fulfillUseRequests(lib.id);
147
168
  }
169
+
148
170
  _fulfillUseRequests(id) {
149
171
  const requests = this._useRequests[id];
150
172
  if (requests) {
151
173
  for (const options of requests) {
152
174
  try {
153
175
  this.use(id, options);
154
- } catch (e) {
176
+ } catch(e) {
155
177
  this._error(e);
156
178
  }
157
179
  }
158
180
  delete this._useRequests[id];
159
181
  }
160
182
  }
183
+
161
184
  async _tryRegisterRemotely(id) {
162
185
  if (id.startsWith('std:')) {
163
186
  try {
164
187
  await this._registerStdRemotely(id);
165
188
  return;
166
- } catch (e) {
189
+ } catch(e) {
167
190
  console.error(e);
168
191
  }
169
192
  }
170
193
  // TODO: try as URL
171
194
  throw new Error(`Cannot register plugin remotely: ${id}`);
172
195
  }
196
+
173
197
  async _registerStdRemotely(id) {
174
- const {
175
- version
176
- } = this._root;
198
+ const { version } = this._root;
177
199
  const request = version === 'dev' ? `plugin:${id}@dev:${MisoClient.uuid}` : `plugin:${id}@${version}`;
178
200
 
179
201
  // check if such script already exists
@@ -191,25 +213,28 @@ export default class PluginRoot extends Registry {
191
213
  const Plugin = await new Resources().get(request);
192
214
  !this.isRegistered(id) && this.register(Plugin);
193
215
  }
216
+
194
217
  }
195
218
 
196
219
  /**
197
220
  * The interface of extended features only for plugin developers.
198
221
  */
199
222
  class PluginContext {
223
+
200
224
  constructor(root, classes) {
201
- delegateGetters(this, root, ['getPluginClass', 'addSubtree', 'addPayloadPass', 'addUrlPass', 'whenInstalled', 'whenRegistered']);
202
- defineValues(this, {
203
- classes
204
- });
225
+ delegateGetters(this, root, ['getPluginClass', 'addSubtree', 'addPayloadPass', 'addUrlPass', 'setCustomFetch', 'whenInstalled', 'whenRegistered']);
226
+ defineValues(this, { classes });
205
227
  }
228
+
206
229
  }
207
230
 
208
231
  /**
209
232
  * The interface of plugin features exposed to MisoClient.
210
233
  */
211
- class Plugins {
234
+ class Plugins {
235
+
212
236
  constructor(root) {
213
237
  delegateGetters(this, root, ['installed', 'registered', 'isInstalled', 'isRegistered', 'whenInstalled', 'whenRegistered', 'get', 'register', 'use', 'install']);
214
238
  }
215
- }
239
+
240
+ }
@@ -1,6 +1,7 @@
1
1
  export function getPluginScriptUrl(id, version, currentScript) {
2
2
  // TODO: look up by manifest
3
3
  const pkgName = id.slice(4);
4
+
4
5
  if (version === 'dev') {
5
6
  const src = currentScript.src;
6
7
  const searchIndex = src.indexOf('?');
@@ -12,4 +13,4 @@ export function getPluginScriptUrl(id, version, currentScript) {
12
13
  } else {
13
14
  return `https://cdn.jsdelivr.net/npm/@miso.ai/client-sdk@${version}/dist/umd/plugins/${pkgName}.min.js`;
14
15
  }
15
- }
16
+ }
@@ -1,90 +1,84 @@
1
1
  import { uuidv4, asString, trimObj, Component, delegateProperties, getOrComputeFromStorage } from '@miso.ai/commons';
2
+
2
3
  const PLUGIN_ID = 'std:user';
4
+
3
5
  export default class UserPlugin extends Component {
6
+
4
7
  static get id() {
5
8
  return PLUGIN_ID;
6
9
  }
10
+
7
11
  constructor() {
8
12
  super('user');
9
13
  this._contexts = new WeakMap();
10
14
  }
15
+
11
16
  install(MisoClient, context) {
12
17
  context.addSubtree(this);
13
18
  MisoClient.on('create', this._injectClient.bind(this));
14
19
  context.addPayloadPass(this._modifyPayload.bind(this));
15
20
  }
21
+
16
22
  _injectClient(client) {
17
23
  const context = new UserContext(this);
18
24
  this._contexts.set(client, context);
19
25
  delegateProperties(client.context, context, ['anonymous_id', 'user_id', 'user_hash']);
20
26
  }
21
- _modifyPayload(_ref) {
22
- let {
23
- client,
24
- apiGroup,
25
- apiName,
26
- payload
27
- } = _ref;
28
- return apiGroup === 'interactions' && apiName === 'upload' ? this._modifyPayloadForInteractions(client, payload) : this._modifyPayloadForOthers(client, payload);
27
+
28
+ _modifyPayload({ client, apiGroup, apiName, payload }) {
29
+ return apiGroup === 'interactions' && apiName === 'upload' ?
30
+ this._modifyPayloadForInteractions(client, payload) : this._modifyPayloadForOthers(client, payload);
29
31
  }
32
+
30
33
  _modifyPayloadForOthers(client, payload) {
31
- const {
32
- user_id,
33
- user_hash,
34
- anonymous_id
35
- } = client.context;
36
- const userInfo = user_id ? {
37
- user_id,
38
- user_hash
39
- } : {
40
- anonymous_id
41
- };
42
- return Object.assign({}, userInfo, payload);
34
+ const { user_id, user_hash, anonymous_id } = client.context;
35
+ const userInfo = user_id ? { user_id, user_hash } : { anonymous_id };
36
+ return { ...userInfo, ...payload };
43
37
  }
44
- _modifyPayloadForInteractions(client, _ref2) {
45
- let {
46
- data
47
- } = _ref2;
48
- const {
49
- anonymous_id,
50
- user_id
51
- } = client.context;
52
- const baseObj = trimObj({
53
- anonymous_id,
54
- user_id
55
- });
56
- data = data.map(obj => Object.assign({}, baseObj, obj));
57
- return {
58
- data
59
- };
38
+
39
+ _modifyPayloadForInteractions(client, { data }) {
40
+ const { anonymous_id, user_id } = client.context;
41
+ const baseObj = trimObj({ anonymous_id, user_id });
42
+ data = data.map(obj => ({ ...baseObj, ...obj }));
43
+ return { data };
60
44
  }
45
+
61
46
  }
47
+
62
48
  function getAutoAnonymousId() {
63
49
  return getOrComputeFromStorage('miso_anonymous_id', uuidv4);
64
50
  }
51
+
65
52
  class UserContext {
53
+
66
54
  constructor(plugin) {
67
55
  this._plugin = plugin;
68
56
  }
57
+
69
58
  get anonymous_id() {
70
59
  return this._anonymousId || this._autoAnonymousId || (this._autoAnonymousId = getAutoAnonymousId());
71
60
  }
61
+
72
62
  set anonymous_id(value) {
73
63
  value = asString(value);
74
64
  this._anonymousId = value;
75
65
  this._plugin._events.emit('set', `anonymous_id = '${value}'`);
76
66
  }
67
+
77
68
  get user_id() {
78
69
  return this._userId;
79
70
  }
71
+
80
72
  set user_id(value) {
81
73
  value = asString(value);
82
74
  this._userId = value;
83
75
  this._plugin._events.emit('set', `user_id = '${value}'`);
84
76
  }
77
+
85
78
  get user_hash() {
86
79
  return this._userHash;
87
80
  }
81
+
88
82
  set user_hash(value) {
89
83
  if (typeof value !== 'string' && typeof value !== 'undefined') {
90
84
  throw new Error(`User hash must be a string`);
@@ -92,4 +86,5 @@ class UserContext {
92
86
  this._userHash = value;
93
87
  this._plugin._events.emit('set', `user_hash = '${value}'`);
94
88
  }
95
- }
89
+
90
+ }
@@ -1,11 +1,12 @@
1
1
  import { delegateGetters, Component } from '@miso.ai/commons';
2
- import version from './version';
3
- import PluginRoot from './plugin/plugin-root';
2
+ import version from './version.js';
3
+ import PluginRoot from './plugin/plugin-root.js';
4
4
 
5
5
  /**
6
6
  * The hidden singleton root component that oversees all client components.
7
7
  */
8
8
  class Root extends Component {
9
+
9
10
  constructor() {
10
11
  super();
11
12
  this._events._replays.add('create');
@@ -13,17 +14,22 @@ class Root extends Component {
13
14
  this._clients = [];
14
15
  this._payloadPasses = [];
15
16
  this._urlPasses = [];
17
+ this._customFetch = undefined;
16
18
  this.version = version || 'dev';
17
19
  }
20
+
18
21
  get instances() {
19
- return [...this._clients]; // write protection
22
+ return [ ...this._clients]; // write protection
20
23
  }
21
24
 
22
25
  async any() {
23
26
  return this._clients[0] || this._any || (this._any = (await this._events.once('create')).data);
24
27
  }
28
+
25
29
  }
30
+
26
31
  export const root = new Root();
32
+
27
33
  export function init(MisoClient) {
28
34
  const pluginRoot = root._pluginRoot;
29
35
  root.MisoClient = pluginRoot.MisoClient = MisoClient;
@@ -31,7 +37,8 @@ export function init(MisoClient) {
31
37
  delegateGetters(MisoClient, pluginRoot, ['plugins']);
32
38
  return MisoClient;
33
39
  }
40
+
34
41
  export function register(client) {
35
42
  root._clients.push(client);
36
43
  root._events.emit('create', client);
37
- }
44
+ }
package/src/utils.js ADDED
@@ -0,0 +1 @@
1
+ export { viewable } from '@miso.ai/commons';
package/src/version.js ADDED
@@ -0,0 +1 @@
1
+ export default '1.8.1-beta.0';
@@ -1,85 +0,0 @@
1
- const _excluded = ["pollingInterval", "signal", "stallTimeout"];
2
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
3
- import { polling, signals, StallTimeoutAbortController } from '@miso.ai/commons';
4
- import ApiBase from './base';
5
- export default class Ask extends ApiBase {
6
- constructor(api) {
7
- super(api, 'ask');
8
- }
9
- async questions(payload) {
10
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
11
- if (typeof payload === 'string' && payload.charAt(0) !== '{') {
12
- return new Answer(this, {
13
- question_id: payload
14
- }, options);
15
- }
16
- const response = await this._run('questions', payload, options);
17
- return new Answer(this, response, options);
18
- }
19
- async _questions(payload, options) {
20
- return this._run('questions', payload, options);
21
- }
22
- async _get(questionId, options) {
23
- return this._run(`questions/${questionId}/answer`, undefined, Object.assign({}, options, {
24
- method: 'GET'
25
- }));
26
- }
27
- }
28
- class Answer {
29
- constructor(api, _ref) {
30
- let {
31
- question_id
32
- } = _ref;
33
- let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
34
- this._api = api;
35
- this._questionId = question_id;
36
- this._ac = new AbortController();
37
- this._options = options;
38
- }
39
- get questionId() {
40
- return this._questionId;
41
- }
42
- async get(options) {
43
- return this._api._get(this._questionId, Object.assign({}, this._options, options));
44
- }
45
- abort(reason) {
46
- this._ac.abort(reason);
47
- }
48
- [Symbol.asyncIterator]() {
49
- var _this = this;
50
- const fetch = async function () {
51
- let {
52
- signal
53
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
54
- // TODO: pass signal
55
- const response = await _this.get();
56
- return [response, response.finished];
57
- };
58
- let _this$_options = this._options,
59
- {
60
- pollingInterval: interval,
61
- signal,
62
- stallTimeout = 30000
63
- } = _this$_options,
64
- options = _objectWithoutPropertiesLoose(_this$_options, _excluded);
65
- const stac = new StallTimeoutAbortController(stallTimeout);
66
- signal = signals.any(this._ac.signal, stac.signal, signal);
67
- let prevResponse;
68
- const onResponse = (response, finished) => {
69
- if (finished) {
70
- stac.clear();
71
- } else if (isUpdated(prevResponse, response)) {
72
- stac.touch();
73
- }
74
- prevResponse = response;
75
- };
76
- return polling(fetch, Object.assign({
77
- interval,
78
- signal,
79
- onResponse
80
- }, options))[Symbol.asyncIterator]();
81
- }
82
- }
83
- function isUpdated(prev, curr) {
84
- return !prev || prev.answer_stage !== curr.answer_stage || prev.answer.length !== curr.answer.length;
85
- }