@miso.ai/client-sdk-codegen 1.11.6-beta.0 → 1.11.6-beta.1
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 +11 -24
- package/dist/cjs/index.js +8 -18
- package/dist/cjs/output.js +37 -0
- package/dist/cjs/params.js +11 -3
- package/dist/cjs/spec/features.js +30 -26
- package/dist/cjs/spec/index.js +15 -5
- package/dist/cjs/spec/presets.js +29 -0
- package/dist/cjs/spec/utils.js +10 -0
- package/dist/cjs/spec/workflows.js +25 -29
- package/dist/cjs/spec/workflows.slug.js +23 -0
- package/dist/cjs/template/client.js +29 -0
- package/dist/cjs/template/entrypoints.js +15 -0
- package/dist/cjs/template/features.js +19 -0
- package/dist/cjs/{utils.js → template/helpers.js} +26 -8
- package/dist/cjs/template/index.js +39 -0
- package/dist/cjs/ui/hybrid-search.js +74 -0
- package/dist/cjs/ui/index.js +38 -0
- package/dist/cjs/ui/search.js +91 -0
- package/dist/cjs/ui/ui.js +36 -0
- package/package.json +2 -2
- package/src/codegen.js +8 -20
- package/src/index.js +2 -2
- package/src/output.js +33 -0
- package/src/params.js +11 -2
- package/src/spec/features.js +24 -26
- package/src/spec/index.js +2 -5
- package/src/spec/presets.js +24 -0
- package/src/spec/utils.js +5 -0
- package/src/spec/workflows.js +23 -35
- package/src/spec/workflows.slug.js +24 -0
- package/src/template/client.js +25 -0
- package/src/template/entrypoints.js +10 -0
- package/src/template/features.js +10 -0
- package/src/{utils.js → template/helpers.js} +19 -0
- package/src/template/index.js +4 -0
- package/src/ui/hybrid-search.js +71 -0
- package/src/ui/index.js +3 -0
- package/src/ui/search.js +91 -0
- package/src/ui/ui.js +26 -0
- package/dist/cjs/features.js +0 -12
- package/dist/cjs/templates.js +0 -34
- package/dist/cjs/workflow/hybrid-search.js +0 -51
- package/dist/cjs/workflow/index.js +0 -22
- package/src/features.js +0 -5
- package/src/templates.js +0 -26
- package/src/workflow/hybrid-search.js +0 -48
- package/src/workflow/index.js +0 -3
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.search = search;
|
|
7
|
+
var _presets = require("../spec/presets.js");
|
|
8
|
+
var _helpers = require("../template/helpers.js");
|
|
9
|
+
var _index = require("../template/index.js");
|
|
10
|
+
var _features = require("../template/features.js");
|
|
11
|
+
const _excluded = ["facets"];
|
|
12
|
+
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; }
|
|
13
|
+
function normalizeOptions(_ref = {}) {
|
|
14
|
+
let {
|
|
15
|
+
facets
|
|
16
|
+
} = _ref,
|
|
17
|
+
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
18
|
+
if (facets === true) {
|
|
19
|
+
facets = ['categories'];
|
|
20
|
+
}
|
|
21
|
+
return Object.assign({}, options, {
|
|
22
|
+
facets
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function search(options) {
|
|
26
|
+
options = normalizeOptions((0, _helpers.resolvePreset)(_presets.search, options));
|
|
27
|
+
// TODO: extra styles for concatenate format
|
|
28
|
+
const items = [];
|
|
29
|
+
if (options.elements !== false) {
|
|
30
|
+
items.push({
|
|
31
|
+
type: 'html',
|
|
32
|
+
name: 'HTML (Search box)',
|
|
33
|
+
content: htmlSearchBox(options)
|
|
34
|
+
}, {
|
|
35
|
+
type: 'html',
|
|
36
|
+
name: 'HTML (Results)',
|
|
37
|
+
content: htmlResults(options)
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
items.push({
|
|
41
|
+
type: 'js',
|
|
42
|
+
name: 'JavaScript',
|
|
43
|
+
content: js(options)
|
|
44
|
+
});
|
|
45
|
+
return items;
|
|
46
|
+
}
|
|
47
|
+
function js(options) {
|
|
48
|
+
// TODO: support loading from Node module
|
|
49
|
+
return (0, _index.misocmd)(`
|
|
50
|
+
// client
|
|
51
|
+
${(0, _index.createClient)(options)}
|
|
52
|
+
|
|
53
|
+
// workflow
|
|
54
|
+
const workflow = client.ui.search;
|
|
55
|
+
|
|
56
|
+
// setup: TODO
|
|
57
|
+
${(0, _features.facets)(options.facets)}
|
|
58
|
+
|
|
59
|
+
${(0, _features.autoQuery)(options.autoQuery)}
|
|
60
|
+
`);
|
|
61
|
+
}
|
|
62
|
+
function html(options) {
|
|
63
|
+
if (options.elements === false) {
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
return `
|
|
67
|
+
${htmlSearchBox(options)}
|
|
68
|
+
<hr>
|
|
69
|
+
${htmlResults(options)}
|
|
70
|
+
`.trim();
|
|
71
|
+
}
|
|
72
|
+
function htmlSearchBox(options) {
|
|
73
|
+
return `
|
|
74
|
+
<miso-search>
|
|
75
|
+
<miso-query></miso-query>
|
|
76
|
+
</miso-search>
|
|
77
|
+
`.trim();
|
|
78
|
+
}
|
|
79
|
+
function htmlResults(options) {
|
|
80
|
+
// TODO: useLink
|
|
81
|
+
return `
|
|
82
|
+
<miso-search visible-when="loading ready">
|
|
83
|
+
<div class="info">
|
|
84
|
+
<div class="keywords">You searched for “<miso-keywords></miso-keywords>”</div>
|
|
85
|
+
<div class="total"><miso-total></miso-total> Results</div>
|
|
86
|
+
</div>
|
|
87
|
+
<miso-facets></miso-facets>
|
|
88
|
+
<miso-products></miso-products>
|
|
89
|
+
</miso-search>
|
|
90
|
+
`.trim();
|
|
91
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ui = ui;
|
|
7
|
+
var _hybridSearch = require("./hybrid-search.js");
|
|
8
|
+
var _search = require("./search.js");
|
|
9
|
+
const _excluded = ["workflow"];
|
|
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
|
+
const workflows = {
|
|
12
|
+
['hybrid-search']: _hybridSearch.hybridSearch,
|
|
13
|
+
search: _search.search
|
|
14
|
+
};
|
|
15
|
+
function normalizeOptions(_ref = {}) {
|
|
16
|
+
let {
|
|
17
|
+
workflow
|
|
18
|
+
} = _ref,
|
|
19
|
+
options = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
20
|
+
if (!workflow) {
|
|
21
|
+
throw new Error('Workflow is required');
|
|
22
|
+
}
|
|
23
|
+
return Object.assign({
|
|
24
|
+
workflow
|
|
25
|
+
}, options);
|
|
26
|
+
}
|
|
27
|
+
function ui(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
|
+
}
|
package/package.json
CHANGED
package/src/codegen.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ui } from './ui/index.js';
|
|
2
|
+
import Output from './output.js';
|
|
2
3
|
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export function codegen({ schema = 'ui', ...options } = {}) {
|
|
5
|
+
switch (schema) {
|
|
6
|
+
case 'ui':
|
|
7
|
+
return new Output(ui(options));
|
|
8
|
+
default:
|
|
9
|
+
throw new Error(`Unrecognized schema: "${schema}"`);
|
|
7
10
|
}
|
|
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
11
|
}
|
package/src/index.js
CHANGED
package/src/output.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export default class Output {
|
|
2
|
+
|
|
3
|
+
constructor(items) {
|
|
4
|
+
this._items = items;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
get items() {
|
|
8
|
+
return this._items;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
[Symbol.iterator]() {
|
|
12
|
+
return this._items[Symbol.iterator]();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
concat() {
|
|
16
|
+
return this._items.filter(item => item).map(item => asHtml(item)).join('\n');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function asHtml({ type, content } = {}) {
|
|
22
|
+
// TODO: minify
|
|
23
|
+
switch (type) {
|
|
24
|
+
case 'html':
|
|
25
|
+
return content;
|
|
26
|
+
case 'js':
|
|
27
|
+
return `<script async>\n${content}\n</script>`;
|
|
28
|
+
case 'css':
|
|
29
|
+
return `<style>\n${content}\n</style>`;
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(`Unrecognized type: "${type}"`);
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/params.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
|
-
export function encodeParameters(params
|
|
1
|
+
export function encodeParameters(params) {
|
|
2
|
+
if (params === undefined || params === null) {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
if (typeof params !== 'object') {
|
|
6
|
+
throw new Error('params must be an object');
|
|
7
|
+
}
|
|
2
8
|
// JSON string -> base64
|
|
3
9
|
return base64Encode(JSON.stringify(params));
|
|
4
10
|
}
|
|
5
11
|
|
|
6
12
|
export function decodeParameters(params) {
|
|
13
|
+
if (params === undefined || params === null) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
7
16
|
// base64 -> JSON string
|
|
8
|
-
return
|
|
17
|
+
return JSON.parse(base64Decode(params));
|
|
9
18
|
}
|
|
10
19
|
|
|
11
20
|
function base64Encode(str) {
|
package/src/spec/features.js
CHANGED
|
@@ -1,43 +1,41 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toName } from './utils.js';
|
|
2
|
+
import { resolveWorkflows } from './workflows.slug.js';
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
+
export default [
|
|
4
5
|
{
|
|
5
6
|
slug: 'use-api',
|
|
6
|
-
|
|
7
|
-
workflows: resolveWorkflows('*'),
|
|
7
|
+
workflows: '*',
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
slug: 'use-link',
|
|
11
|
-
|
|
12
|
-
workflows: resolveWorkflows('ahes'),
|
|
11
|
+
workflows: 'ahes',
|
|
13
12
|
},
|
|
14
13
|
{
|
|
15
|
-
slug: '
|
|
16
|
-
|
|
17
|
-
workflows: resolveWorkflows('a'),
|
|
14
|
+
slug: 'autocomplete',
|
|
15
|
+
workflows: 'hs',
|
|
18
16
|
},
|
|
19
17
|
{
|
|
20
|
-
slug: '
|
|
21
|
-
|
|
22
|
-
workflows: resolveWorkflows('ahes'),
|
|
18
|
+
slug: 'pagination',
|
|
19
|
+
workflows: 'hs',
|
|
23
20
|
},
|
|
24
21
|
{
|
|
25
|
-
slug: '
|
|
26
|
-
|
|
27
|
-
workflows: resolveWorkflows('hs'),
|
|
22
|
+
slug: 'facets',
|
|
23
|
+
workflows: 'hs',
|
|
28
24
|
},
|
|
29
25
|
{
|
|
30
|
-
slug: '
|
|
31
|
-
|
|
32
|
-
workflows: resolveWorkflows('hs'),
|
|
26
|
+
slug: 'follow-up',
|
|
27
|
+
workflows: 'a',
|
|
33
28
|
},
|
|
34
29
|
{
|
|
35
|
-
slug: '
|
|
36
|
-
|
|
37
|
-
workflows: resolveWorkflows('hs'),
|
|
30
|
+
slug: 'auto-query',
|
|
31
|
+
workflows: 'ahes',
|
|
38
32
|
},
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
].reduce((map, { slug, workflows, ...rest }) => {
|
|
34
|
+
map[slug] = Object.freeze({
|
|
35
|
+
slug,
|
|
36
|
+
name: toName(slug),
|
|
37
|
+
workflows: resolveWorkflows(workflows),
|
|
38
|
+
...rest,
|
|
39
|
+
});
|
|
40
|
+
return map;
|
|
41
|
+
}, {});
|
package/src/spec/index.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export const presets = Object.freeze({
|
|
4
|
-
hybridSearch: Object.keys(hybridSearchPresets),
|
|
5
|
-
});
|
|
1
|
+
export { default as workflows } from './workflows.js';
|
|
2
|
+
export { default as features } from './features.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const hybridSearch = Object.freeze({
|
|
2
|
+
standard: Object.freeze({
|
|
3
|
+
workflow: 'hybrid-search',
|
|
4
|
+
autoQuery: true,
|
|
5
|
+
autocomplete: true,
|
|
6
|
+
facets: ['categories'],
|
|
7
|
+
answerBox: true,
|
|
8
|
+
}),
|
|
9
|
+
minimal: Object.freeze({
|
|
10
|
+
workflow: 'hybrid-search',
|
|
11
|
+
}),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const search = Object.freeze({
|
|
15
|
+
standard: Object.freeze({
|
|
16
|
+
workflow: 'search',
|
|
17
|
+
autoQuery: true,
|
|
18
|
+
autocomplete: true,
|
|
19
|
+
//facets: ['categories'],
|
|
20
|
+
}),
|
|
21
|
+
minimal: Object.freeze({
|
|
22
|
+
workflow: 'search',
|
|
23
|
+
}),
|
|
24
|
+
});
|
package/src/spec/workflows.js
CHANGED
|
@@ -1,39 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { kebabToLowerCamel } from '@miso.ai/commons';
|
|
2
|
+
import { toName } from './utils.js';
|
|
3
|
+
import { WORKFLOW_SLUGS } from './workflows.slug.js';
|
|
4
|
+
import features from './features.js';
|
|
5
|
+
import * as presets from './presets.js';
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
}));
|
|
7
|
+
function getFeatures(features, slug) {
|
|
8
|
+
return Object.values(features).filter(feature => feature.workflows.includes(slug));
|
|
9
|
+
}
|
|
23
10
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
11
|
+
function getPresets(presets, slug) {
|
|
12
|
+
return Object.entries(presets[kebabToLowerCamel(slug)] || {}).map(([key, value]) => Object.freeze({
|
|
13
|
+
slug: key,
|
|
14
|
+
name: toName(key),
|
|
15
|
+
value,
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
28
18
|
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
throw new Error(`Workflow "${abv}" is not found`);
|
|
36
|
-
}
|
|
37
|
-
return ABV_TO_WORKFLOW[abv];
|
|
19
|
+
export default WORKFLOW_SLUGS.reduce((obj, slug) => {
|
|
20
|
+
obj[slug] = Object.freeze({
|
|
21
|
+
slug,
|
|
22
|
+
name: toName(slug),
|
|
23
|
+
features: getFeatures(features, slug),
|
|
24
|
+
presets: getPresets(presets, slug),
|
|
38
25
|
});
|
|
39
|
-
|
|
26
|
+
return obj;
|
|
27
|
+
}, {});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const WORKFLOW_SLUGS = [
|
|
2
|
+
'ask',
|
|
3
|
+
'hybrid-search',
|
|
4
|
+
'explore',
|
|
5
|
+
'search',
|
|
6
|
+
'recommendation',
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const ABV_TO_WORKFLOW = WORKFLOW_SLUGS.reduce((map, slug) => {
|
|
10
|
+
map[slug.charAt(0)] = slug;
|
|
11
|
+
return map;
|
|
12
|
+
}, {});
|
|
13
|
+
|
|
14
|
+
export function resolveWorkflows(abvs) {
|
|
15
|
+
if (abvs === '*') {
|
|
16
|
+
return [...WORKFLOW_SLUGS];
|
|
17
|
+
}
|
|
18
|
+
return abvs.split('').map(abv => {
|
|
19
|
+
if (!ABV_TO_WORKFLOW[abv]) {
|
|
20
|
+
throw new Error(`Workflow "${abv}" is not found`);
|
|
21
|
+
}
|
|
22
|
+
return ABV_TO_WORKFLOW[abv];
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { indent, blocks } from './helpers.js';
|
|
2
|
+
|
|
3
|
+
export function createClient(options) {
|
|
4
|
+
return blocks(
|
|
5
|
+
`const MisoClient = window.MisoClient;`,
|
|
6
|
+
...clientPlugins(options),
|
|
7
|
+
`const client = new MisoClient(${clientOptions(options)});`
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function clientPlugins({ dryRun } = {}) {
|
|
12
|
+
const blocks = [];
|
|
13
|
+
if (dryRun) {
|
|
14
|
+
blocks.push(`MisoClient.plugins.use("std:dry-run");`);
|
|
15
|
+
}
|
|
16
|
+
return blocks;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function clientOptions({ apiKey, apiKeyParam = false } = {}) {
|
|
20
|
+
if (!apiKeyParam) {
|
|
21
|
+
return `'${apiKey}'`;
|
|
22
|
+
}
|
|
23
|
+
apiKeyParam = apiKeyParam === true ? 'api-key' : apiKeyParam;
|
|
24
|
+
return `new URLSearchParams(window.location.search).get('${apiKeyParam}') || '${apiKey}'`;
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { format } from './helpers.js';
|
|
2
|
+
|
|
3
|
+
export function facets(options) {
|
|
4
|
+
return options ? `workflow.useFacets(${format(options, { multiline: true })});` : '';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function autoQuery(options) {
|
|
8
|
+
// TODO: consider when options === false
|
|
9
|
+
return options ? `workflow.autoQuery(${typeof options === 'object' ? format(options, { multiline: true }) : ''});` : '';
|
|
10
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export function indent(str, level = 1) {
|
|
2
|
+
// TODO: trim and deal with blank lines
|
|
2
3
|
return str.replace(/\n/g, '\n' + ' '.repeat(level));
|
|
3
4
|
}
|
|
4
5
|
|
|
@@ -15,6 +16,24 @@ export function format(value, { multiline = false } = {}) {
|
|
|
15
16
|
return JSON.stringify(value, null, multiline ? 2 : 0).replace(/"/g, "'").replace(/\s*:\s*/g, ': ');
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Join blocks with proper newlines
|
|
21
|
+
* @param {string[]} blocks - Blocks to join
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
export function blocks(...blocks) {
|
|
25
|
+
return blocks.map(block => block.trim()).filter(block => block).join('\n');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Join paragraphs with proper newlines
|
|
30
|
+
* @param {string[]} paragraphs - Paragraphs to join
|
|
31
|
+
* @returns {string}
|
|
32
|
+
*/
|
|
33
|
+
export function paragraphs(...paragraphs) {
|
|
34
|
+
return paragraphs.map(paragraph => paragraph.trim()).filter(paragraph => paragraph).join('\n\n');
|
|
35
|
+
}
|
|
36
|
+
|
|
18
37
|
/**
|
|
19
38
|
* Resolve preset options
|
|
20
39
|
* @param {Object} presets - Available presets
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { hybridSearch as presets } from '../spec/presets.js';
|
|
2
|
+
import { resolvePreset } from '../template/helpers.js';
|
|
3
|
+
import { misocmd, createClient } from '../template/index.js';
|
|
4
|
+
import { autoQuery } from '../template/features.js';
|
|
5
|
+
|
|
6
|
+
// TODO: refactor these
|
|
7
|
+
function normalizeOptions({ facets, ...options } = {}) {
|
|
8
|
+
if (facets === true) {
|
|
9
|
+
facets = ['categories'];
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
...options,
|
|
13
|
+
facets,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function hybridSearch(options) {
|
|
18
|
+
options = normalizeOptions(resolvePreset(presets, options));
|
|
19
|
+
const items = [
|
|
20
|
+
{
|
|
21
|
+
type: 'html',
|
|
22
|
+
name: 'HTML',
|
|
23
|
+
content: html(options),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: 'js',
|
|
27
|
+
name: 'JavaScript',
|
|
28
|
+
content: js(options),
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
return items;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function js(options) {
|
|
35
|
+
// TODO: support loading from Node module
|
|
36
|
+
// TODO: useLink
|
|
37
|
+
return misocmd(`
|
|
38
|
+
// client
|
|
39
|
+
${createClient(options)}
|
|
40
|
+
|
|
41
|
+
// workflow
|
|
42
|
+
const workflow = client.ui.hybridSearch;
|
|
43
|
+
|
|
44
|
+
// setup: TODO
|
|
45
|
+
|
|
46
|
+
${jsElements(options)}
|
|
47
|
+
|
|
48
|
+
${autoQuery(options.autoQuery)}
|
|
49
|
+
`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function jsElements(options) {
|
|
53
|
+
if (options.elements === false) {
|
|
54
|
+
return '';
|
|
55
|
+
}
|
|
56
|
+
return `
|
|
57
|
+
// render Miso elements
|
|
58
|
+
await client.ui.ready;
|
|
59
|
+
const { templates, wireAnswerBox } = MisoClient.ui.defaults.hybridSearch;
|
|
60
|
+
const rootElement = document.querySelector('#miso-hybrid-search-combo');
|
|
61
|
+
rootElement.innerHTML = templates.root();
|
|
62
|
+
wireAnswerBox(client, rootElement);
|
|
63
|
+
`.trim();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function html(options) {
|
|
67
|
+
if (options.elements === false) {
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
70
|
+
return `<div id="miso-hybrid-search-combo" class="miso-hybrid-search-combo"></div>`.trim();
|
|
71
|
+
}
|
package/src/ui/index.js
ADDED