@miso.ai/client-sdk-codegen 1.11.6-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.
- package/dist/cjs/codegen.js +36 -0
- package/dist/cjs/features.js +12 -0
- package/dist/cjs/index.js +49 -0
- package/dist/cjs/params.js +22 -0
- package/dist/cjs/spec/features.js +40 -0
- package/dist/cjs/spec/index.js +10 -0
- package/dist/cjs/spec/workflows.js +36 -0
- package/dist/cjs/templates.js +34 -0
- package/dist/cjs/utils.js +54 -0
- package/dist/cjs/workflow/hybrid-search.js +51 -0
- package/dist/cjs/workflow/index.js +22 -0
- package/package.json +32 -0
- package/src/codegen.js +23 -0
- package/src/features.js +5 -0
- package/src/index.js +4 -0
- package/src/params.js +17 -0
- package/src/spec/features.js +43 -0
- package/src/spec/index.js +5 -0
- package/src/spec/workflows.js +39 -0
- package/src/templates.js +26 -0
- package/src/utils.js +38 -0
- package/src/workflow/hybrid-search.js +48 -0
- package/src/workflow/index.js +3 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.codegen = codegen;
|
|
7
|
+
var workflows = _interopRequireWildcard(require("./workflow/index.js"));
|
|
8
|
+
const _excluded = ["workflow"];
|
|
9
|
+
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); }
|
|
10
|
+
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; }
|
|
11
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
12
|
+
function normalizeOptions() {
|
|
13
|
+
let _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
14
|
+
let {
|
|
15
|
+
workflow
|
|
16
|
+
} = _ref,
|
|
17
|
+
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
18
|
+
// turn workflow into camel case
|
|
19
|
+
if (!workflow) {
|
|
20
|
+
throw new Error('Workflow is required');
|
|
21
|
+
}
|
|
22
|
+
workflow = workflow.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
23
|
+
return Object.assign({
|
|
24
|
+
workflow
|
|
25
|
+
}, options);
|
|
26
|
+
}
|
|
27
|
+
function codegen(options) {
|
|
28
|
+
options = normalizeOptions(options);
|
|
29
|
+
const {
|
|
30
|
+
workflow
|
|
31
|
+
} = options;
|
|
32
|
+
if (!workflows[workflow]) {
|
|
33
|
+
throw new Error(`Workflow "${workflow}" is not found`);
|
|
34
|
+
}
|
|
35
|
+
return workflows[workflow](options);
|
|
36
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.autoQuery = autoQuery;
|
|
7
|
+
var _utils = require("./utils.js");
|
|
8
|
+
function autoQuery(autoQuery) {
|
|
9
|
+
return autoQuery ? `workflow.autoQuery(${typeof autoQuery === 'object' ? (0, _utils.format)(autoQuery, {
|
|
10
|
+
multiline: true
|
|
11
|
+
}) : ''});` : '';
|
|
12
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
workflows: true
|
|
8
|
+
};
|
|
9
|
+
exports.workflows = void 0;
|
|
10
|
+
var _params = require("./params.js");
|
|
11
|
+
Object.keys(_params).forEach(function (key) {
|
|
12
|
+
if (key === "default" || key === "__esModule") return;
|
|
13
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
14
|
+
if (key in exports && exports[key] === _params[key]) return;
|
|
15
|
+
Object.defineProperty(exports, key, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () {
|
|
18
|
+
return _params[key];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
var _codegen = require("./codegen.js");
|
|
23
|
+
Object.keys(_codegen).forEach(function (key) {
|
|
24
|
+
if (key === "default" || key === "__esModule") return;
|
|
25
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
26
|
+
if (key in exports && exports[key] === _codegen[key]) return;
|
|
27
|
+
Object.defineProperty(exports, key, {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () {
|
|
30
|
+
return _codegen[key];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
var _index = require("./spec/index.js");
|
|
35
|
+
Object.keys(_index).forEach(function (key) {
|
|
36
|
+
if (key === "default" || key === "__esModule") return;
|
|
37
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
38
|
+
if (key in exports && exports[key] === _index[key]) return;
|
|
39
|
+
Object.defineProperty(exports, key, {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
get: function () {
|
|
42
|
+
return _index[key];
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
var _workflows = _interopRequireWildcard(require("./workflow/index.js"));
|
|
47
|
+
exports.workflows = _workflows;
|
|
48
|
+
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); }
|
|
49
|
+
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; }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.decodeParameters = decodeParameters;
|
|
7
|
+
exports.encodeParameters = encodeParameters;
|
|
8
|
+
function encodeParameters() {
|
|
9
|
+
let params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
10
|
+
// JSON string -> base64
|
|
11
|
+
return base64Encode(JSON.stringify(params));
|
|
12
|
+
}
|
|
13
|
+
function decodeParameters(params) {
|
|
14
|
+
// base64 -> JSON string
|
|
15
|
+
return params ? JSON.parse(base64Decode(params)) : {};
|
|
16
|
+
}
|
|
17
|
+
function base64Encode(str) {
|
|
18
|
+
return typeof window !== 'undefined' ? window.btoa(str) : Buffer.from(str).toString('base64');
|
|
19
|
+
}
|
|
20
|
+
function base64Decode(str) {
|
|
21
|
+
return typeof window !== 'undefined' ? window.atob(str) : Buffer.from(str, 'base64').toString();
|
|
22
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.FEATURES = void 0;
|
|
7
|
+
exports.getFeatures = getFeatures;
|
|
8
|
+
var _workflows = require("./workflows.js");
|
|
9
|
+
const FEATURES = exports.FEATURES = [{
|
|
10
|
+
slug: 'use-api',
|
|
11
|
+
name: 'useApi()',
|
|
12
|
+
workflows: (0, _workflows.resolveWorkflows)('*')
|
|
13
|
+
}, {
|
|
14
|
+
slug: 'use-link',
|
|
15
|
+
name: 'useLink()',
|
|
16
|
+
workflows: (0, _workflows.resolveWorkflows)('ahes')
|
|
17
|
+
}, {
|
|
18
|
+
slug: 'follow-up',
|
|
19
|
+
name: 'Follow Up',
|
|
20
|
+
workflows: (0, _workflows.resolveWorkflows)('a')
|
|
21
|
+
}, {
|
|
22
|
+
slug: 'auto-query',
|
|
23
|
+
name: 'Auto Query',
|
|
24
|
+
workflows: (0, _workflows.resolveWorkflows)('ahes')
|
|
25
|
+
}, {
|
|
26
|
+
slug: 'autocomplete',
|
|
27
|
+
name: 'Autocomplete',
|
|
28
|
+
workflows: (0, _workflows.resolveWorkflows)('hs')
|
|
29
|
+
}, {
|
|
30
|
+
slug: 'pagination',
|
|
31
|
+
name: 'Pagination',
|
|
32
|
+
workflows: (0, _workflows.resolveWorkflows)('hs')
|
|
33
|
+
}, {
|
|
34
|
+
slug: 'facets',
|
|
35
|
+
name: 'Facets',
|
|
36
|
+
workflows: (0, _workflows.resolveWorkflows)('hs')
|
|
37
|
+
}];
|
|
38
|
+
function getFeatures(workflow) {
|
|
39
|
+
return FEATURES.filter(feature => feature.workflows.includes(workflow));
|
|
40
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.presets = void 0;
|
|
7
|
+
var _hybridSearch = require("../workflow/hybrid-search.js");
|
|
8
|
+
const presets = exports.presets = Object.freeze({
|
|
9
|
+
hybridSearch: Object.keys(_hybridSearch.presets)
|
|
10
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.WORKFLOWS = void 0;
|
|
7
|
+
exports.resolveWorkflows = resolveWorkflows;
|
|
8
|
+
var _commons = require("@miso.ai/commons");
|
|
9
|
+
const WORKFLOWS = exports.WORKFLOWS = [{
|
|
10
|
+
slug: 'ask'
|
|
11
|
+
}, {
|
|
12
|
+
slug: 'hybrid-search'
|
|
13
|
+
}, {
|
|
14
|
+
slug: 'explore'
|
|
15
|
+
}, {
|
|
16
|
+
slug: 'search'
|
|
17
|
+
}, {
|
|
18
|
+
slug: 'recommendation'
|
|
19
|
+
}].map(workflow => Object.assign({}, workflow, {
|
|
20
|
+
name: (0, _commons.kebabOrSnakeToHuman)(workflow.slug)
|
|
21
|
+
}));
|
|
22
|
+
const ABV_TO_WORKFLOW = WORKFLOWS.reduce((map, workflow) => {
|
|
23
|
+
map[workflow.slug.charAt(0)] = workflow;
|
|
24
|
+
return map;
|
|
25
|
+
}, {});
|
|
26
|
+
function resolveWorkflows(abvs) {
|
|
27
|
+
if (abvs === '*') {
|
|
28
|
+
return [...WORKFLOWS];
|
|
29
|
+
}
|
|
30
|
+
return abvs.split('').map(abv => {
|
|
31
|
+
if (!ABV_TO_WORKFLOW[abv]) {
|
|
32
|
+
throw new Error(`Workflow "${abv}" is not found`);
|
|
33
|
+
}
|
|
34
|
+
return ABV_TO_WORKFLOW[abv];
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createClient = createClient;
|
|
7
|
+
exports.misocmd = misocmd;
|
|
8
|
+
var _utils = require("./utils.js");
|
|
9
|
+
function misocmd(body) {
|
|
10
|
+
return `
|
|
11
|
+
const misocmd = window.misocmd || (window.misocmd = []);
|
|
12
|
+
misocmd.push(async () => {
|
|
13
|
+
${(0, _utils.indent)(body, 2)}
|
|
14
|
+
});
|
|
15
|
+
`.trim();
|
|
16
|
+
}
|
|
17
|
+
function createClient(options) {
|
|
18
|
+
return `
|
|
19
|
+
// client
|
|
20
|
+
const MisoClient = window.MisoClient;
|
|
21
|
+
const client = new MisoClient(${clientOptions(options)});
|
|
22
|
+
`.trim();
|
|
23
|
+
}
|
|
24
|
+
function clientOptions() {
|
|
25
|
+
let {
|
|
26
|
+
apiKey,
|
|
27
|
+
apiKeyParam = false
|
|
28
|
+
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
29
|
+
if (!apiKeyParam) {
|
|
30
|
+
return `'${apiKey}'`;
|
|
31
|
+
}
|
|
32
|
+
apiKeyParam = apiKeyParam === true ? 'api-key' : apiKeyParam;
|
|
33
|
+
return `new URLSearchParams(window.location.search).get('${apiKeyParam}') || '${apiKey}'`;
|
|
34
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.format = format;
|
|
7
|
+
exports.indent = indent;
|
|
8
|
+
exports.resolvePreset = resolvePreset;
|
|
9
|
+
const _excluded = ["preset"];
|
|
10
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
11
|
+
function indent(str) {
|
|
12
|
+
let level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
|
|
13
|
+
return str.replace(/\n/g, '\n' + ' '.repeat(level));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Format a JavaScript value to literal string
|
|
18
|
+
* @param {*} value
|
|
19
|
+
* @param {Object} options
|
|
20
|
+
* @param {boolean} options.multiline - Whether to use multiline
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
23
|
+
function format(value) {
|
|
24
|
+
let {
|
|
25
|
+
multiline = false
|
|
26
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
27
|
+
// use single quote
|
|
28
|
+
// no quote for simple key in object
|
|
29
|
+
return JSON.stringify(value, null, multiline ? 2 : 0).replace(/"/g, "'").replace(/\s*:\s*/g, ': ');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Resolve preset options
|
|
34
|
+
* @param {Object} presets - Available presets
|
|
35
|
+
* @param {Object} options - Options to resolve
|
|
36
|
+
* @param {string} options.preset - Preset to use
|
|
37
|
+
* @param {Object} options - Other options
|
|
38
|
+
* @returns {Object} Resolved options
|
|
39
|
+
*/
|
|
40
|
+
function resolvePreset(presets) {
|
|
41
|
+
let _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
42
|
+
let {
|
|
43
|
+
preset
|
|
44
|
+
} = _ref,
|
|
45
|
+
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
46
|
+
if (!preset) {
|
|
47
|
+
return options;
|
|
48
|
+
}
|
|
49
|
+
if (!presets[preset]) {
|
|
50
|
+
throw new Error(`Preset "${preset}" is not found`);
|
|
51
|
+
}
|
|
52
|
+
// let rest of options override
|
|
53
|
+
return Object.assign({}, presets[preset], options);
|
|
54
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.hybridSearch = hybridSearch;
|
|
7
|
+
exports.presets = void 0;
|
|
8
|
+
var _utils = require("../utils.js");
|
|
9
|
+
var _templates = require("../templates.js");
|
|
10
|
+
var _features = require("../features.js");
|
|
11
|
+
const presets = exports.presets = Object.freeze({
|
|
12
|
+
standard: Object.freeze({
|
|
13
|
+
workflow: 'hybrid-search',
|
|
14
|
+
autoQuery: true,
|
|
15
|
+
autocomplete: true,
|
|
16
|
+
facets: ['categories'],
|
|
17
|
+
answerBox: true
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
function hybridSearch(options) {
|
|
21
|
+
options = (0, _utils.resolvePreset)(presets, options);
|
|
22
|
+
return {
|
|
23
|
+
js: js(options),
|
|
24
|
+
html: html(options)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function js(options) {
|
|
28
|
+
return (0, _templates.misocmd)(`
|
|
29
|
+
${(0, _templates.createClient)(options)}
|
|
30
|
+
|
|
31
|
+
// workflow
|
|
32
|
+
const workflow = client.ui.hybridSearch;
|
|
33
|
+
|
|
34
|
+
// setup: TODO
|
|
35
|
+
|
|
36
|
+
// render Miso elements
|
|
37
|
+
await client.ui.ready;
|
|
38
|
+
const { templates, wireAnswerBox } = MisoClient.ui.defaults.hybridSearch;
|
|
39
|
+
const rootElement = document.querySelector('#miso-hybrid-search-combo');
|
|
40
|
+
rootElement.innerHTML = templates.root();
|
|
41
|
+
wireAnswerBox(client, rootElement);
|
|
42
|
+
|
|
43
|
+
${(0, _features.autoQuery)(options.autoQuery)}
|
|
44
|
+
`);
|
|
45
|
+
}
|
|
46
|
+
function html(options) {
|
|
47
|
+
return `
|
|
48
|
+
<h1 class="hero-title">Miso Hybrid Search</h1>
|
|
49
|
+
<div id="miso-hybrid-search-combo" class="miso-hybrid-search-combo"></div>
|
|
50
|
+
`.trim();
|
|
51
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
workflows: true
|
|
8
|
+
};
|
|
9
|
+
exports.workflows = void 0;
|
|
10
|
+
var _hybridSearch = require("./hybrid-search.js");
|
|
11
|
+
Object.keys(_hybridSearch).forEach(function (key) {
|
|
12
|
+
if (key === "default" || key === "__esModule") return;
|
|
13
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
14
|
+
if (key in exports && exports[key] === _hybridSearch[key]) return;
|
|
15
|
+
Object.defineProperty(exports, key, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () {
|
|
18
|
+
return _hybridSearch[key];
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
const workflows = exports.workflows = ['hybrid-search'];
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@miso.ai/client-sdk-codegen",
|
|
3
|
+
"description": "Client SDK code generator",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "src/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
"import": "./src/index.js",
|
|
9
|
+
"require": "./dist/cjs/index.js"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build:clean": "npx rimraf dist",
|
|
16
|
+
"build:cjs": "BABEL_ENV=cjs npx babel src --root-mode upward --out-dir dist/cjs",
|
|
17
|
+
"build": "npm run build:clean && npm run build:cjs"
|
|
18
|
+
},
|
|
19
|
+
"repository": "MisoAI/miso-client-js-sdk",
|
|
20
|
+
"homepage": "https://misoai.github.io/miso-client-js-sdk/sdk",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"contributors": [
|
|
23
|
+
"simonpai <simon.pai@askmiso.com>"
|
|
24
|
+
],
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@miso.ai/commons": "1.11.6-beta.0"
|
|
30
|
+
},
|
|
31
|
+
"version": "1.11.6-beta.0"
|
|
32
|
+
}
|
package/src/codegen.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as workflows from './workflow/index.js';
|
|
2
|
+
|
|
3
|
+
function normalizeOptions({ workflow, ...options } = {}) {
|
|
4
|
+
// turn workflow into camel case
|
|
5
|
+
if (!workflow) {
|
|
6
|
+
throw new Error('Workflow is required');
|
|
7
|
+
}
|
|
8
|
+
workflow = workflow.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
workflow,
|
|
12
|
+
...options,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function codegen(options) {
|
|
17
|
+
options = normalizeOptions(options);
|
|
18
|
+
const { workflow } = options;
|
|
19
|
+
if (!workflows[workflow]) {
|
|
20
|
+
throw new Error(`Workflow "${workflow}" is not found`);
|
|
21
|
+
}
|
|
22
|
+
return workflows[workflow](options);
|
|
23
|
+
}
|
package/src/features.js
ADDED
package/src/index.js
ADDED
package/src/params.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function encodeParameters(params = {}) {
|
|
2
|
+
// JSON string -> base64
|
|
3
|
+
return base64Encode(JSON.stringify(params));
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export function decodeParameters(params) {
|
|
7
|
+
// base64 -> JSON string
|
|
8
|
+
return params ? JSON.parse(base64Decode(params)) : {};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function base64Encode(str) {
|
|
12
|
+
return typeof window !== 'undefined' ? window.btoa(str) : Buffer.from(str).toString('base64');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function base64Decode(str) {
|
|
16
|
+
return typeof window !== 'undefined' ? window.atob(str) : Buffer.from(str, 'base64').toString();
|
|
17
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { resolveWorkflows } from './workflows.js';
|
|
2
|
+
|
|
3
|
+
export const FEATURES = [
|
|
4
|
+
{
|
|
5
|
+
slug: 'use-api',
|
|
6
|
+
name: 'useApi()',
|
|
7
|
+
workflows: resolveWorkflows('*'),
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
slug: 'use-link',
|
|
11
|
+
name: 'useLink()',
|
|
12
|
+
workflows: resolveWorkflows('ahes'),
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
slug: 'follow-up',
|
|
16
|
+
name: 'Follow Up',
|
|
17
|
+
workflows: resolveWorkflows('a'),
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
slug: 'auto-query',
|
|
21
|
+
name: 'Auto Query',
|
|
22
|
+
workflows: resolveWorkflows('ahes'),
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
slug: 'autocomplete',
|
|
26
|
+
name: 'Autocomplete',
|
|
27
|
+
workflows: resolveWorkflows('hs'),
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
slug: 'pagination',
|
|
31
|
+
name: 'Pagination',
|
|
32
|
+
workflows: resolveWorkflows('hs'),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
slug: 'facets',
|
|
36
|
+
name: 'Facets',
|
|
37
|
+
workflows: resolveWorkflows('hs'),
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
export function getFeatures(workflow) {
|
|
42
|
+
return FEATURES.filter(feature => feature.workflows.includes(workflow));
|
|
43
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { kebabOrSnakeToHuman } from '@miso.ai/commons';
|
|
2
|
+
|
|
3
|
+
export const WORKFLOWS = ([
|
|
4
|
+
{
|
|
5
|
+
slug: 'ask',
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
slug: 'hybrid-search',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
slug: 'explore',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
slug: 'search',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
slug: 'recommendation',
|
|
18
|
+
},
|
|
19
|
+
]).map(workflow => ({
|
|
20
|
+
...workflow,
|
|
21
|
+
name: kebabOrSnakeToHuman(workflow.slug),
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
const ABV_TO_WORKFLOW = WORKFLOWS.reduce((map, workflow) => {
|
|
25
|
+
map[workflow.slug.charAt(0)] = workflow;
|
|
26
|
+
return map;
|
|
27
|
+
}, {});
|
|
28
|
+
|
|
29
|
+
export function resolveWorkflows(abvs) {
|
|
30
|
+
if (abvs === '*') {
|
|
31
|
+
return [...WORKFLOWS];
|
|
32
|
+
}
|
|
33
|
+
return abvs.split('').map(abv => {
|
|
34
|
+
if (!ABV_TO_WORKFLOW[abv]) {
|
|
35
|
+
throw new Error(`Workflow "${abv}" is not found`);
|
|
36
|
+
}
|
|
37
|
+
return ABV_TO_WORKFLOW[abv];
|
|
38
|
+
});
|
|
39
|
+
}
|
package/src/templates.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { indent } from './utils.js';
|
|
2
|
+
|
|
3
|
+
export function misocmd(body) {
|
|
4
|
+
return `
|
|
5
|
+
const misocmd = window.misocmd || (window.misocmd = []);
|
|
6
|
+
misocmd.push(async () => {
|
|
7
|
+
${indent(body, 2)}
|
|
8
|
+
});
|
|
9
|
+
`.trim();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createClient(options) {
|
|
13
|
+
return `
|
|
14
|
+
// client
|
|
15
|
+
const MisoClient = window.MisoClient;
|
|
16
|
+
const client = new MisoClient(${clientOptions(options)});
|
|
17
|
+
`.trim();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function clientOptions({ apiKey, apiKeyParam = false } = {}) {
|
|
21
|
+
if (!apiKeyParam) {
|
|
22
|
+
return `'${apiKey}'`;
|
|
23
|
+
}
|
|
24
|
+
apiKeyParam = apiKeyParam === true ? 'api-key' : apiKeyParam;
|
|
25
|
+
return `new URLSearchParams(window.location.search).get('${apiKeyParam}') || '${apiKey}'`;
|
|
26
|
+
}
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function indent(str, level = 1) {
|
|
2
|
+
return str.replace(/\n/g, '\n' + ' '.repeat(level));
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Format a JavaScript value to literal string
|
|
7
|
+
* @param {*} value
|
|
8
|
+
* @param {Object} options
|
|
9
|
+
* @param {boolean} options.multiline - Whether to use multiline
|
|
10
|
+
* @returns {string}
|
|
11
|
+
*/
|
|
12
|
+
export function format(value, { multiline = false } = {}) {
|
|
13
|
+
// use single quote
|
|
14
|
+
// no quote for simple key in object
|
|
15
|
+
return JSON.stringify(value, null, multiline ? 2 : 0).replace(/"/g, "'").replace(/\s*:\s*/g, ': ');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Resolve preset options
|
|
20
|
+
* @param {Object} presets - Available presets
|
|
21
|
+
* @param {Object} options - Options to resolve
|
|
22
|
+
* @param {string} options.preset - Preset to use
|
|
23
|
+
* @param {Object} options - Other options
|
|
24
|
+
* @returns {Object} Resolved options
|
|
25
|
+
*/
|
|
26
|
+
export function resolvePreset(presets, { preset, ...options } = {}) {
|
|
27
|
+
if (!preset) {
|
|
28
|
+
return options;
|
|
29
|
+
}
|
|
30
|
+
if (!presets[preset]) {
|
|
31
|
+
throw new Error(`Preset "${preset}" is not found`);
|
|
32
|
+
}
|
|
33
|
+
// let rest of options override
|
|
34
|
+
return {
|
|
35
|
+
...presets[preset],
|
|
36
|
+
...options,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { resolvePreset } from '../utils.js';
|
|
2
|
+
import { misocmd, createClient } from '../templates.js';
|
|
3
|
+
import { autoQuery } from '../features.js';
|
|
4
|
+
|
|
5
|
+
export const presets = Object.freeze({
|
|
6
|
+
standard: Object.freeze({
|
|
7
|
+
workflow: 'hybrid-search',
|
|
8
|
+
autoQuery: true,
|
|
9
|
+
autocomplete: true,
|
|
10
|
+
facets: ['categories'],
|
|
11
|
+
answerBox: true,
|
|
12
|
+
}),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export function hybridSearch(options) {
|
|
16
|
+
options = resolvePreset(presets, options);
|
|
17
|
+
return {
|
|
18
|
+
js: js(options),
|
|
19
|
+
html: html(options),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function js(options) {
|
|
24
|
+
return misocmd(`
|
|
25
|
+
${createClient(options)}
|
|
26
|
+
|
|
27
|
+
// workflow
|
|
28
|
+
const workflow = client.ui.hybridSearch;
|
|
29
|
+
|
|
30
|
+
// setup: TODO
|
|
31
|
+
|
|
32
|
+
// render Miso elements
|
|
33
|
+
await client.ui.ready;
|
|
34
|
+
const { templates, wireAnswerBox } = MisoClient.ui.defaults.hybridSearch;
|
|
35
|
+
const rootElement = document.querySelector('#miso-hybrid-search-combo');
|
|
36
|
+
rootElement.innerHTML = templates.root();
|
|
37
|
+
wireAnswerBox(client, rootElement);
|
|
38
|
+
|
|
39
|
+
${autoQuery(options.autoQuery)}
|
|
40
|
+
`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function html(options) {
|
|
44
|
+
return `
|
|
45
|
+
<h1 class="hero-title">Miso Hybrid Search</h1>
|
|
46
|
+
<div id="miso-hybrid-search-combo" class="miso-hybrid-search-combo"></div>
|
|
47
|
+
`.trim();
|
|
48
|
+
}
|