@miso.ai/client-sdk-ui 1.9.0-beta.9 → 1.9.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.
@@ -115,6 +115,8 @@ class AskCombo extends _base.default {
115
115
  const context = client.ui.asks;
116
116
  const rootWorkflow = client.ui.ask;
117
117
 
118
+ // TODO: set placeholder is present in options
119
+
118
120
  // when a answer is fully populated, insert a new section for the follow-up question
119
121
  context.on('done', _ref => {
120
122
  let {
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _commons = require("@miso.ai/commons");
8
8
  var templates = _interopRequireWildcard(require("./templates.js"));
9
- const _excluded = ["api_key", "api_host"];
9
+ var phrases = _interopRequireWildcard(require("./phrases.js"));
10
+ const _excluded = ["api_key", "api_host", "templates", "phrases"];
10
11
  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); }
11
12
  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 && Object.prototype.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; }
12
13
  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; }
@@ -17,6 +18,7 @@ const {
17
18
  } = document;
18
19
  const DEFAULT_OPTIONS = Object.freeze({
19
20
  templates,
21
+ phrases,
20
22
  autostart: true
21
23
  });
22
24
  class AskComboOptions {
@@ -51,12 +53,16 @@ function normalizeOptions() {
51
53
  let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
52
54
  let {
53
55
  api_key: apiKey,
54
- api_host: apiHost
56
+ api_host: apiHost,
57
+ templates,
58
+ phrases
55
59
  } = _ref,
56
60
  options = _objectWithoutPropertiesLoose(_ref, _excluded);
57
61
  return (0, _commons.trimObj)(Object.assign({
58
62
  apiKey,
59
- apiHost
63
+ apiHost,
64
+ templates: templateAsFunction(templates),
65
+ phrases: templateAsFunction(phrases)
60
66
  }, options));
61
67
  }
62
68
 
@@ -98,4 +104,27 @@ function readFromPageUrl() {
98
104
  }
99
105
  function coerceValue(value) {
100
106
  return value === '' ? true : value === 'false' ? false : value;
107
+ }
108
+ function templateAsFunction(value) {
109
+ if (value === undefined || value === null) {
110
+ return value;
111
+ }
112
+ switch (typeof value) {
113
+ case 'function':
114
+ return value;
115
+ case 'string':
116
+ case 'number':
117
+ return () => value;
118
+ case 'object':
119
+ return Array.isArray(value) ? value.map(templateAsFunction) : mappingObjectValues(value, templateAsFunction);
120
+ default:
121
+ throw new Error(`Unsupported template type: ${value}`);
122
+ }
123
+ }
124
+ function mappingObjectValues(obj, fn) {
125
+ const mapped = {};
126
+ for (const [key, value] of Object.entries(obj)) {
127
+ mapped[key] = fn(value);
128
+ }
129
+ return mapped;
101
130
  }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.sources = exports.relatedResources = exports.relatedQuestions = exports.question = void 0;
7
+ const question = exports.question = 'You asked...';
8
+ const sources = exports.sources = 'My reply is based on the following';
9
+ const relatedQuestions = exports.relatedQuestions = 'Related questions you can explore';
10
+ const relatedResources = exports.relatedResources = 'Go beyond, and learn more about this topic';
@@ -17,50 +17,50 @@ const root = options => `
17
17
  <section class="${_constants.PREFIX}__section ${_constants.PREFIX}__answer">
18
18
  ${options.templates.answer(options)}
19
19
  ${options.templates.sources(options)}
20
+ <miso-ask class="${_constants.PREFIX}__bottom-spacing-container" visible-when="ongoing"></miso-ask>
20
21
  </section>
21
22
  <div id="${_constants.PREFIX}__follow-ups" class="${_constants.PREFIX}__follow-ups"></div>
22
23
  <section id="${_constants.PREFIX}__related-resources" class="${_constants.PREFIX}__section ${_constants.PREFIX}__related-resources">
23
24
  <miso-ask visible-when="nonempty" logo="true">
24
- <h2 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-resources-phrase"></h2>
25
+ <h2 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-resources-phrase">${options.phrases.relatedResources(options)}</h2>
25
26
  <miso-related-resources></miso-related-resources>
26
27
  </miso-ask>
27
28
  </section>
28
29
  `.trim();
29
30
  exports.root = root;
30
- const followUp = (options, _ref) => {
31
- let {
31
+ const followUp = function (options) {
32
+ let session = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
33
+ const {
32
34
  parentQuestionId
33
- } = _ref;
35
+ } = session;
34
36
  return `
35
37
  <section class="${_constants.PREFIX}__section ${_constants.PREFIX}__follow-up">
36
38
  <miso-ask class="${_constants.PREFIX}__query-suggestions-container" visible-when="initial+nonempty" parent-question-id="${parentQuestionId}">
37
- <h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-questions-phrase"></h3>
39
+ <h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__related-questions-phrase">${options.phrases.relatedQuestions(options, session)}</h3>
38
40
  <miso-query-suggestions></miso-query-suggestions>
39
41
  </miso-ask>
40
42
  <miso-ask class="${_constants.PREFIX}__query-container" visible-when="initial loading" parent-question-id="${parentQuestionId}">
41
43
  <miso-query></miso-query>
42
44
  </miso-ask>
43
- ${options.templates.answer(options, {
44
- parentQuestionId
45
- })}
46
- ${options.templates.sources(options, {
47
- parentQuestionId
48
- })}
45
+ ${options.templates.answer(options, session)}
46
+ ${options.templates.sources(options, session)}
47
+ <miso-ask class="${_constants.PREFIX}__bottom-spacing-container" visible-when="ongoing" parent-question-id="${parentQuestionId}"></miso-ask>
49
48
  </section>
50
49
  `.trim();
51
50
  };
52
51
  exports.followUp = followUp;
53
52
  const answer = function (options) {
54
- let {
55
- parentQuestionId
56
- } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
53
+ let session = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
57
54
  // TODO: include/omit miso-circled-citation-index by options
55
+ const {
56
+ parentQuestionId
57
+ } = session;
58
58
  const openTag = `<miso-ask class="${_constants.PREFIX}__answer-container miso-circled-citation-index" visible-when="ready" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
59
59
  const closeTag = '</miso-ask>';
60
60
  return `
61
61
  ${openTag}
62
62
  ${parentQuestionId ? '<hr>' : ''}
63
- <div class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__question-phrase"></div>
63
+ <div class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__question-phrase">${options.phrases.question(options, session)}</div>
64
64
  <miso-question></miso-question>
65
65
  <miso-answer></miso-answer>
66
66
  <miso-feedback></miso-feedback>
@@ -69,16 +69,17 @@ ${closeTag}
69
69
  };
70
70
  exports.answer = answer;
71
71
  const sources = function (options) {
72
- let {
73
- parentQuestionId
74
- } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
72
+ let session = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
75
73
  // TODO: include/omit miso-circled-citation-index by options
74
+ const {
75
+ parentQuestionId
76
+ } = session;
76
77
  const openTag = `<miso-ask class="${_constants.PREFIX}__sources-container miso-circled-citation-index" visible-when="nonempty" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
77
78
  const closeTag = '</miso-ask>';
78
79
  return `
79
80
  ${openTag}
80
81
  <hr>
81
- <h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__sources-phrase"></h3>
82
+ <h3 class="${_constants.PREFIX}__phrase ${_constants.PREFIX}__sources-phrase">${options.phrases.sources(options, session)}</h3>
82
83
  <miso-sources></miso-sources>
83
84
  ${closeTag}
84
85
  `.trim();
@@ -11,6 +11,7 @@ var _layouts = _interopRequireDefault(require("./layouts.js"));
11
11
  var elements = _interopRequireWildcard(require("./element/index.js"));
12
12
  var layouts = _interopRequireWildcard(require("./layout/index.js"));
13
13
  var sources = _interopRequireWildcard(require("./source/index.js"));
14
+ var _styles = require("./styles.js");
14
15
  var _misoContainer = _interopRequireDefault(require("./element/container/miso-container.js"));
15
16
  var _misoCombo = _interopRequireDefault(require("./element/combo/miso-combo.js"));
16
17
  const _excluded = ["containers", "roles", "combos"];
@@ -24,18 +25,13 @@ class UiPlugin extends _commons.Component {
24
25
  return PLUGIN_ID;
25
26
  }
26
27
  constructor() {
27
- let {
28
- loadStyles = true
29
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
30
28
  super('ui');
31
29
  this.layouts = new _layouts.default(this);
32
30
  this._recommendations = new WeakMap();
33
31
  this._asks = new WeakMap();
34
32
  this._extensions = new WeakMap();
35
- // TODO: load CSS
36
33
  }
37
-
38
- install(MisoClient, context) {
34
+ async install(MisoClient, context) {
39
35
  context.addSubtree(this);
40
36
  MisoClient.on('create', this._injectClient.bind(this));
41
37
  const ui = {};
@@ -75,6 +71,10 @@ class UiPlugin extends _commons.Component {
75
71
  ElementClass.MisoClient = MisoClient; // TODO: find better way
76
72
  }
77
73
 
74
+ // load styles
75
+ await (0, _styles.loadStylesIfNecessary)();
76
+
77
+ // define custom elements
78
78
  for (const ElementClass of ElementClasses) {
79
79
  (0, _commons.defineAndUpgrade)(ElementClass);
80
80
  }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.loadStyles = loadStyles;
7
+ exports.loadStylesIfNecessary = loadStylesIfNecessary;
8
+ var _version = _interopRequireDefault(require("./version.js"));
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ const {
11
+ currentScript
12
+ } = document;
13
+ let cssUrl;
14
+ let stylesLoaded;
15
+ async function loadStylesIfNecessary() {
16
+ return stylesLoaded || (stylesLoaded = loadStyles());
17
+ }
18
+ async function loadStyles() {
19
+ try {
20
+ let link = getExistedLinkElement();
21
+ if (link) {
22
+ return waitForLinkLoaded(link);
23
+ }
24
+ link = document.createElement('link');
25
+ link.rel = 'stylesheet';
26
+ link.href = getCssUrl();
27
+ return new Promise((resolve, reject) => {
28
+ link.onload = resolve;
29
+ link.onerror = reject;
30
+ document.head.appendChild(link);
31
+ });
32
+ } catch (e) {
33
+ console.error(e);
34
+ }
35
+ }
36
+
37
+ // helpers //
38
+ function getCssUrl() {
39
+ return cssUrl || (cssUrl = resolveCssUrl());
40
+ }
41
+ function resolveCssUrl() {
42
+ // TODO: refactor with getPluginScriptUrl() in core
43
+ if (_version.default === 'dev') {
44
+ const src = currentScript.src;
45
+ const searchIndex = src.indexOf('?');
46
+ const k = searchIndex < 0 ? src.length : searchIndex;
47
+ const i = src.lastIndexOf('/', k); // .../dist/umd/*.min.js
48
+ return `${src.slice(0, i - 4)}/css/ui.css`;
49
+ } else {
50
+ return `https://cdn.jsdelivr.net/npm/@miso.ai/client-sdk@${_version.default}/dist/css/ui.css`;
51
+ }
52
+ }
53
+ function getExistedLinkElement() {
54
+ return document.head.querySelector(`link[href="${getCssUrl()}"]`);
55
+ }
56
+ async function waitForLinkLoaded(element) {
57
+ if (element.sheet) {
58
+ return;
59
+ }
60
+ return new Promise((resolve, reject) => {
61
+ let intervalId;
62
+ element.onload = () => {
63
+ intervalId && clearInterval(intervalId);
64
+ resolve();
65
+ };
66
+ element.onerror = () => {
67
+ intervalId && clearInterval(intervalId);
68
+ reject();
69
+ };
70
+ intervalId = setInterval(() => {
71
+ if (element.sheet) {
72
+ intervalId && clearInterval(intervalId);
73
+ resolve();
74
+ }
75
+ }, 100);
76
+ });
77
+ }
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = exports.default = '1.9.0-beta.9';
7
+ var _default = exports.default = '1.9.0';
package/package.json CHANGED
@@ -26,7 +26,7 @@
26
26
  "url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
27
27
  },
28
28
  "dependencies": {
29
- "@miso.ai/commons": "1.9.0-beta.9"
29
+ "@miso.ai/commons": "1.9.0"
30
30
  },
31
- "version": "1.9.0-beta.9"
31
+ "version": "1.9.0"
32
32
  }
@@ -105,6 +105,8 @@ export default class AskCombo extends Combo {
105
105
  const context = client.ui.asks;
106
106
  const rootWorkflow = client.ui.ask;
107
107
 
108
+ // TODO: set placeholder is present in options
109
+
108
110
  // when a answer is fully populated, insert a new section for the follow-up question
109
111
  context.on('done', ({ workflow }) => {
110
112
  elements.followUpsSection.insertAdjacentHTML('beforeend', templates.followUp(options, { parentQuestionId: workflow.questionId }));
@@ -1,5 +1,6 @@
1
1
  import { trimObj } from '@miso.ai/commons';
2
2
  import * as templates from './templates.js';
3
+ import * as phrases from './phrases.js';
3
4
 
4
5
  // TODO: generalize
5
6
 
@@ -7,6 +8,7 @@ const { currentScript } = document;
7
8
 
8
9
  const DEFAULT_OPTIONS = Object.freeze({
9
10
  templates,
11
+ phrases,
10
12
  autostart: true,
11
13
  });
12
14
 
@@ -41,10 +43,12 @@ function mergeTwoOptions(merged, overrides) {
41
43
  });
42
44
  }
43
45
 
44
- function normalizeOptions({ api_key: apiKey, api_host: apiHost, ...options } = {}) {
46
+ function normalizeOptions({ api_key: apiKey, api_host: apiHost, templates, phrases, ...options } = {}) {
45
47
  return trimObj({
46
48
  apiKey,
47
49
  apiHost,
50
+ templates: templateAsFunction(templates),
51
+ phrases: templateAsFunction(phrases),
48
52
  ...options,
49
53
  });
50
54
  }
@@ -90,3 +94,28 @@ function readFromPageUrl() {
90
94
  function coerceValue(value) {
91
95
  return value === '' ? true : value === 'false' ? false : value;
92
96
  }
97
+
98
+ function templateAsFunction(value) {
99
+ if (value === undefined || value === null) {
100
+ return value;
101
+ }
102
+ switch (typeof value) {
103
+ case 'function':
104
+ return value;
105
+ case 'string':
106
+ case 'number':
107
+ return () => value;
108
+ case 'object':
109
+ return Array.isArray(value) ? value.map(templateAsFunction) : mappingObjectValues(value, templateAsFunction);
110
+ default:
111
+ throw new Error(`Unsupported template type: ${value}`);
112
+ }
113
+ }
114
+
115
+ function mappingObjectValues(obj, fn) {
116
+ const mapped = {};
117
+ for (const [key, value] of Object.entries(obj)) {
118
+ mapped[key] = fn(value);
119
+ }
120
+ return mapped;
121
+ }
@@ -0,0 +1,7 @@
1
+ export const question = 'You asked...';
2
+
3
+ export const sources = 'My reply is based on the following';
4
+
5
+ export const relatedQuestions = 'Related questions you can explore';
6
+
7
+ export const relatedResources = 'Go beyond, and learn more about this topic';
@@ -12,38 +12,44 @@ export const root = (options) => `
12
12
  <section class="${PREFIX}__section ${PREFIX}__answer">
13
13
  ${options.templates.answer(options)}
14
14
  ${options.templates.sources(options)}
15
+ <miso-ask class="${PREFIX}__bottom-spacing-container" visible-when="ongoing"></miso-ask>
15
16
  </section>
16
17
  <div id="${PREFIX}__follow-ups" class="${PREFIX}__follow-ups"></div>
17
18
  <section id="${PREFIX}__related-resources" class="${PREFIX}__section ${PREFIX}__related-resources">
18
19
  <miso-ask visible-when="nonempty" logo="true">
19
- <h2 class="${PREFIX}__phrase ${PREFIX}__related-resources-phrase"></h2>
20
+ <h2 class="${PREFIX}__phrase ${PREFIX}__related-resources-phrase">${options.phrases.relatedResources(options)}</h2>
20
21
  <miso-related-resources></miso-related-resources>
21
22
  </miso-ask>
22
23
  </section>
23
24
  `.trim();
24
25
 
25
- export const followUp = (options, { parentQuestionId }) => `
26
+ export const followUp = (options, session = {}) => {
27
+ const { parentQuestionId } = session;
28
+ return `
26
29
  <section class="${PREFIX}__section ${PREFIX}__follow-up">
27
30
  <miso-ask class="${PREFIX}__query-suggestions-container" visible-when="initial+nonempty" parent-question-id="${parentQuestionId}">
28
- <h3 class="${PREFIX}__phrase ${PREFIX}__related-questions-phrase"></h3>
31
+ <h3 class="${PREFIX}__phrase ${PREFIX}__related-questions-phrase">${options.phrases.relatedQuestions(options, session)}</h3>
29
32
  <miso-query-suggestions></miso-query-suggestions>
30
33
  </miso-ask>
31
34
  <miso-ask class="${PREFIX}__query-container" visible-when="initial loading" parent-question-id="${parentQuestionId}">
32
35
  <miso-query></miso-query>
33
36
  </miso-ask>
34
- ${options.templates.answer(options, { parentQuestionId })}
35
- ${options.templates.sources(options, { parentQuestionId })}
37
+ ${options.templates.answer(options, session)}
38
+ ${options.templates.sources(options, session)}
39
+ <miso-ask class="${PREFIX}__bottom-spacing-container" visible-when="ongoing" parent-question-id="${parentQuestionId}"></miso-ask>
36
40
  </section>
37
41
  `.trim();
42
+ };
38
43
 
39
- export const answer = (options, { parentQuestionId } = {}) => {
44
+ export const answer = (options, session = {}) => {
40
45
  // TODO: include/omit miso-circled-citation-index by options
46
+ const { parentQuestionId } = session;
41
47
  const openTag = `<miso-ask class="${PREFIX}__answer-container miso-circled-citation-index" visible-when="ready" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
42
48
  const closeTag = '</miso-ask>';
43
49
  return `
44
50
  ${openTag}
45
51
  ${ parentQuestionId ? '<hr>' : '' }
46
- <div class="${PREFIX}__phrase ${PREFIX}__question-phrase"></div>
52
+ <div class="${PREFIX}__phrase ${PREFIX}__question-phrase">${options.phrases.question(options, session)}</div>
47
53
  <miso-question></miso-question>
48
54
  <miso-answer></miso-answer>
49
55
  <miso-feedback></miso-feedback>
@@ -51,14 +57,15 @@ ${closeTag}
51
57
  `.trim();
52
58
  };
53
59
 
54
- export const sources = (options, { parentQuestionId } = {}) => {
60
+ export const sources = (options, session = {}) => {
55
61
  // TODO: include/omit miso-circled-citation-index by options
62
+ const { parentQuestionId } = session;
56
63
  const openTag = `<miso-ask class="${PREFIX}__sources-container miso-circled-citation-index" visible-when="nonempty" logo="false"${parentQuestionId ? ` parent-question-id="${parentQuestionId}"` : ''}>`;
57
64
  const closeTag = '</miso-ask>';
58
65
  return `
59
66
  ${openTag}
60
67
  <hr>
61
- <h3 class="${PREFIX}__phrase ${PREFIX}__sources-phrase"></h3>
68
+ <h3 class="${PREFIX}__phrase ${PREFIX}__sources-phrase">${options.phrases.sources(options, session)}</h3>
62
69
  <miso-sources></miso-sources>
63
70
  ${closeTag}
64
71
  `.trim();
package/src/plugin.js CHANGED
@@ -5,6 +5,7 @@ import Layouts from './layouts.js';
5
5
  import * as elements from './element/index.js';
6
6
  import * as layouts from './layout/index.js';
7
7
  import * as sources from './source/index.js';
8
+ import { loadStylesIfNecessary } from './styles.js';
8
9
 
9
10
  import MisoContainerElement from './element/container/miso-container.js';
10
11
  import MisoComboElement from './element/combo/miso-combo.js';
@@ -17,16 +18,15 @@ export default class UiPlugin extends Component {
17
18
  return PLUGIN_ID;
18
19
  }
19
20
 
20
- constructor({ loadStyles = true } = {}) {
21
+ constructor() {
21
22
  super('ui');
22
23
  this.layouts = new Layouts(this);
23
24
  this._recommendations = new WeakMap();
24
25
  this._asks = new WeakMap();
25
26
  this._extensions = new WeakMap();
26
- // TODO: load CSS
27
27
  }
28
28
 
29
- install(MisoClient, context) {
29
+ async install(MisoClient, context) {
30
30
  context.addSubtree(this);
31
31
  MisoClient.on('create', this._injectClient.bind(this));
32
32
 
@@ -61,6 +61,11 @@ export default class UiPlugin extends Component {
61
61
  for (const ElementClass of ElementClasses) {
62
62
  ElementClass.MisoClient = MisoClient; // TODO: find better way
63
63
  }
64
+
65
+ // load styles
66
+ await loadStylesIfNecessary();
67
+
68
+ // define custom elements
64
69
  for (const ElementClass of ElementClasses) {
65
70
  defineAndUpgrade(ElementClass);
66
71
  }
package/src/styles.js ADDED
@@ -0,0 +1,74 @@
1
+ import version from './version.js';
2
+
3
+ const { currentScript } = document;
4
+
5
+ let cssUrl;
6
+ let stylesLoaded;
7
+
8
+ export async function loadStylesIfNecessary() {
9
+ return stylesLoaded || (stylesLoaded = loadStyles());
10
+ }
11
+
12
+ export async function loadStyles() {
13
+ try {
14
+ let link = getExistedLinkElement();
15
+ if (link) {
16
+ return waitForLinkLoaded(link)
17
+ }
18
+ link = document.createElement('link');
19
+ link.rel = 'stylesheet';
20
+ link.href = getCssUrl();
21
+ return new Promise((resolve, reject) => {
22
+ link.onload = resolve;
23
+ link.onerror = reject;
24
+ document.head.appendChild(link);
25
+ });
26
+ } catch(e) {
27
+ console.error(e);
28
+ }
29
+ }
30
+
31
+ // helpers //
32
+ function getCssUrl() {
33
+ return cssUrl || (cssUrl = resolveCssUrl());
34
+ }
35
+
36
+ function resolveCssUrl() {
37
+ // TODO: refactor with getPluginScriptUrl() in core
38
+ if (version === 'dev') {
39
+ const src = currentScript.src;
40
+ const searchIndex = src.indexOf('?');
41
+ const k = searchIndex < 0 ? src.length : searchIndex;
42
+ const i = src.lastIndexOf('/', k); // .../dist/umd/*.min.js
43
+ return `${src.slice(0, i - 4)}/css/ui.css`;
44
+ } else {
45
+ return `https://cdn.jsdelivr.net/npm/@miso.ai/client-sdk@${version}/dist/css/ui.css`;
46
+ }
47
+ }
48
+
49
+ function getExistedLinkElement() {
50
+ return document.head.querySelector(`link[href="${getCssUrl()}"]`);
51
+ }
52
+
53
+ async function waitForLinkLoaded(element) {
54
+ if (element.sheet) {
55
+ return;
56
+ }
57
+ return new Promise((resolve, reject) => {
58
+ let intervalId;
59
+ element.onload = () => {
60
+ intervalId && clearInterval(intervalId);
61
+ resolve();
62
+ };
63
+ element.onerror = () => {
64
+ intervalId && clearInterval(intervalId);
65
+ reject();
66
+ };
67
+ intervalId = setInterval(() => {
68
+ if (element.sheet) {
69
+ intervalId && clearInterval(intervalId);
70
+ resolve();
71
+ }
72
+ }, 100);
73
+ });
74
+ }
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export default '1.9.0-beta.9';
1
+ export default '1.9.0';