@rubixstudios/payload-typesense 1.2.3 → 1.3.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/README.md +55 -20
- package/dist/components/HeadlessSearchInput.d.ts.map +1 -1
- package/dist/components/HeadlessSearchInput.js +4 -3
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/render/Header.d.ts +2 -1
- package/dist/components/render/Header.d.ts.map +1 -1
- package/dist/components/render/Header.js +1 -0
- package/dist/components/render/NoResults.d.ts +2 -1
- package/dist/components/render/NoResults.d.ts.map +1 -1
- package/dist/components/render/NoResults.js +1 -0
- package/dist/components/render/ResultError.d.ts +2 -1
- package/dist/components/render/ResultError.d.ts.map +1 -1
- package/dist/components/render/ResultError.js +1 -0
- package/dist/components/render/Results.d.ts +2 -1
- package/dist/components/render/Results.d.ts.map +1 -1
- package/dist/components/render/Results.js +3 -2
- package/dist/components/themes/utils.js +1 -1
- package/dist/endpoints/handler/createSearch.d.ts.map +1 -1
- package/dist/endpoints/handler/createSearch.js +32 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -6
- package/dist/lib/cache.d.ts +8 -2
- package/dist/lib/cache.d.ts.map +1 -1
- package/dist/lib/cache.js +60 -28
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +9 -16
- package/dist/lib/headlessSearch.d.ts +8 -3
- package/dist/lib/headlessSearch.d.ts.map +1 -1
- package/dist/lib/hooks.d.ts +2 -2
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +4 -3
- package/dist/lib/initialization.d.ts.map +1 -1
- package/dist/lib/initialization.js +9 -15
- package/dist/lib/schema-mapper.d.ts +3 -19
- package/dist/lib/schema-mapper.d.ts.map +1 -1
- package/dist/lib/schema-mapper.js +41 -9
- package/dist/types.d.ts +49 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/ensureCollection.d.ts +2 -1
- package/dist/utils/ensureCollection.d.ts.map +1 -1
- package/dist/utils/extractText.d.ts +1 -1
- package/dist/utils/extractText.d.ts.map +1 -1
- package/dist/utils/extractText.js +4 -6
- package/dist/utils/getAllCollections.d.ts +2 -0
- package/dist/utils/getAllCollections.d.ts.map +1 -1
- package/dist/utils/getAllCollections.js +33 -14
- package/dist/utils/keyboard.d.ts +1 -1
- package/dist/utils/keyboard.d.ts.map +1 -1
- package/dist/utils/keyboard.js +2 -6
- package/dist/utils/useSearch.d.ts +2 -1
- package/dist/utils/useSearch.d.ts.map +1 -1
- package/dist/utils/useSearch.js +25 -37
- package/dist/utils/vectorSearch.d.ts +7 -0
- package/dist/utils/vectorSearch.d.ts.map +1 -0
- package/dist/utils/vectorSearch.js +12 -0
- package/package.json +3 -3
package/dist/lib/client.js
CHANGED
|
@@ -1,48 +1,41 @@
|
|
|
1
1
|
import Typesense from 'typesense';
|
|
2
|
+
const offline = new Error('Typesense offline');
|
|
2
3
|
let client = null;
|
|
3
4
|
const isOffline = ()=>{
|
|
4
5
|
const evt = process.env.npm_lifecycle_event || '';
|
|
5
|
-
if (evt.includes('build') || evt === 'tsc')
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (process.argv.some((a)=>/(?:^|:|\/)(?:build|tsc)(?::|$)/i.test(a))) {
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
if (process.env.CI === 'true') {
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
6
|
+
if (evt.includes('build') || evt === 'tsc') return true;
|
|
7
|
+
if (process.argv.some((a)=>/(?:^|:|\/)(?:build|tsc)(?::|$)/i.test(a))) return true;
|
|
8
|
+
if (process.env.CI === 'true') return true;
|
|
14
9
|
return false;
|
|
15
10
|
};
|
|
16
11
|
const createOfflineClient = ()=>{
|
|
17
12
|
return {
|
|
18
13
|
analytics: {
|
|
19
14
|
retrieve: ()=>{
|
|
20
|
-
return Promise.reject(
|
|
15
|
+
return Promise.reject(offline);
|
|
21
16
|
}
|
|
22
17
|
},
|
|
23
18
|
collections: ()=>{
|
|
24
19
|
return {
|
|
25
20
|
retrieve: ()=>{
|
|
26
|
-
return Promise.reject(
|
|
21
|
+
return Promise.reject(offline);
|
|
27
22
|
}
|
|
28
23
|
};
|
|
29
24
|
},
|
|
30
25
|
health: {
|
|
31
26
|
retrieve: ()=>{
|
|
32
|
-
return Promise.reject(
|
|
27
|
+
return Promise.reject(offline);
|
|
33
28
|
}
|
|
34
29
|
},
|
|
35
30
|
operations: {
|
|
36
31
|
get: ()=>{
|
|
37
|
-
return Promise.reject(
|
|
32
|
+
return Promise.reject(offline);
|
|
38
33
|
}
|
|
39
34
|
}
|
|
40
35
|
};
|
|
41
36
|
};
|
|
42
37
|
export const createClient = (typesenseConfig)=>{
|
|
43
|
-
if (client)
|
|
44
|
-
return client;
|
|
45
|
-
}
|
|
38
|
+
if (client) return client;
|
|
46
39
|
if (isOffline()) {
|
|
47
40
|
client = createOfflineClient();
|
|
48
41
|
return client;
|
|
@@ -5,7 +5,7 @@ export interface HeadlessSearchInputProps<T = Record<string, unknown>> extends B
|
|
|
5
5
|
/**
|
|
6
6
|
* Collections to search in
|
|
7
7
|
*/
|
|
8
|
-
collections?: string
|
|
8
|
+
collections?: string[];
|
|
9
9
|
/**
|
|
10
10
|
* Enable suggestions
|
|
11
11
|
*/
|
|
@@ -27,10 +27,10 @@ export interface HeadlessSearchInputProps<T = Record<string, unknown>> extends B
|
|
|
27
27
|
*/
|
|
28
28
|
renderInput?: (props: {
|
|
29
29
|
className: string;
|
|
30
|
-
onBlur: (e: React.FocusEvent) => void;
|
|
30
|
+
onBlur: (e: React.FocusEvent<HTMLInputElement>) => void;
|
|
31
31
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
32
32
|
onFocus: () => void;
|
|
33
|
-
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
33
|
+
onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
34
34
|
placeholder: string;
|
|
35
35
|
ref: React.RefObject<HTMLInputElement | null>;
|
|
36
36
|
value: string;
|
|
@@ -48,6 +48,7 @@ export interface HeadlessSearchInputProps<T = Record<string, unknown>> extends B
|
|
|
48
48
|
*/
|
|
49
49
|
renderResult?: (result: SearchResult<T>, index: number, handlers: {
|
|
50
50
|
onClick: (result: SearchResult<T>) => void;
|
|
51
|
+
onHover?: (result: SearchResult<T>) => void;
|
|
51
52
|
}) => React.ReactNode;
|
|
52
53
|
/**
|
|
53
54
|
* Custom render function for results header
|
|
@@ -77,5 +78,9 @@ export interface HeadlessSearchInputProps<T = Record<string, unknown>> extends B
|
|
|
77
78
|
* Theme configuration
|
|
78
79
|
*/
|
|
79
80
|
theme?: string | ThemeConfig;
|
|
81
|
+
/**
|
|
82
|
+
* Enable vector search mode (replaces text search)
|
|
83
|
+
*/
|
|
84
|
+
vector?: boolean;
|
|
80
85
|
}
|
|
81
86
|
//# sourceMappingURL=headlessSearch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headlessSearch.d.ts","sourceRoot":"","sources":["../../src/lib/headlessSearch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1E,MAAM,WAAW,wBAAwB,CACvC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3B,SAAQ,oBAAoB,CAAC,CAAC,CAAC;IAC/B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"headlessSearch.d.ts","sourceRoot":"","sources":["../../src/lib/headlessSearch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1E,MAAM,WAAW,wBAAwB,CACvC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC3B,SAAQ,oBAAoB,CAAC,CAAC,CAAC;IAC/B;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IAChD;;OAEG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE;QACpB,SAAS,EAAE,MAAM,CAAA;QACjB,MAAM,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAA;QACvD,QAAQ,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAA;QAC1D,OAAO,EAAE,MAAM,IAAI,CAAA;QACnB,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAA;QAC7D,WAAW,EAAE,MAAM,CAAA;QACnB,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;QAC7C,KAAK,EAAE,MAAM,CAAA;KACd,KAAK,KAAK,CAAC,SAAS,CAAA;IACrB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;IACrC;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IACpD;;OAEG;IACH,YAAY,CAAC,EAAE,CACb,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;QAC1C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;KAC5C,KACE,KAAK,CAAC,SAAS,CAAA;IACpB;;OAEG;IACH,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IACxD;;OAEG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IAC5B;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB"}
|
package/dist/lib/hooks.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type Typesense from 'typesense';
|
|
2
2
|
import { type CollectionAfterChangeHook, type CollectionAfterDeleteHook } from 'payload';
|
|
3
|
-
import { type TypesenseConfig } from '../types.js';
|
|
3
|
+
import { type BaseDocument, type TypesenseConfig } from '../types.js';
|
|
4
4
|
export declare const setupHooks: (typesenseClient: Typesense.Client, pluginOptions: TypesenseConfig, existingHooks?: {
|
|
5
5
|
afterChange?: Record<string, CollectionAfterChangeHook[]>;
|
|
6
6
|
afterDelete?: Record<string, CollectionAfterDeleteHook[]>;
|
|
@@ -8,6 +8,6 @@ export declare const setupHooks: (typesenseClient: Typesense.Client, pluginOptio
|
|
|
8
8
|
afterChange?: Record<string, CollectionAfterChangeHook[]>;
|
|
9
9
|
afterDelete?: Record<string, CollectionAfterDeleteHook[]>;
|
|
10
10
|
};
|
|
11
|
-
export declare const syncDocumentToTypesense: (typesenseClient: Typesense.Client, collectionSlug: string, doc:
|
|
11
|
+
export declare const syncDocumentToTypesense: (typesenseClient: Typesense.Client, collectionSlug: string, doc: BaseDocument, _operation: "create" | "update", config: NonNullable<TypesenseConfig["collections"]>[string] | undefined, vector?: NonNullable<TypesenseConfig["vectorSearch"]>) => Promise<void>;
|
|
12
12
|
export declare const deleteDocumentFromTypesense: (typesenseClient: Typesense.Client, collectionSlug: string, docId: string) => Promise<void>;
|
|
13
13
|
//# sourceMappingURL=hooks.d.ts.map
|
package/dist/lib/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAExF,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/lib/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAExF,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAIrE,eAAO,MAAM,UAAU,GACrB,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,eAAe,EAC9B,gBAAe;IACb,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAA;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAA;CACrD;kBAFU,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC;kBAC3C,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC;CAiC5D,CAAA;AAED,eAAO,MAAM,uBAAuB,GAClC,iBAAiB,SAAS,CAAC,MAAM,EACjC,gBAAgB,MAAM,EACtB,KAAK,YAAY,EACjB,YAAY,QAAQ,GAAG,QAAQ,EAC/B,QAAQ,WAAW,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,EACvE,SAAS,WAAW,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,kBAatD,CAAA;AAED,eAAO,MAAM,2BAA2B,GACtC,iBAAiB,SAAS,CAAC,MAAM,EACjC,gBAAgB,MAAM,EACtB,OAAO,MAAM,kBAOd,CAAA"}
|
package/dist/lib/hooks.js
CHANGED
|
@@ -4,12 +4,13 @@ export const setupHooks = (typesenseClient, pluginOptions, existingHooks = {})=>
|
|
|
4
4
|
const hooks = {
|
|
5
5
|
...existingHooks
|
|
6
6
|
};
|
|
7
|
+
const vector = pluginOptions.vectorSearch;
|
|
7
8
|
for (const [collectionSlug, config] of Object.entries(pluginOptions.collections || {})){
|
|
8
9
|
if (!config?.enabled) {
|
|
9
10
|
continue;
|
|
10
11
|
}
|
|
11
12
|
const changeHook = async ({ doc, operation })=>{
|
|
12
|
-
await syncDocumentToTypesense(typesenseClient, collectionSlug, doc, operation, config);
|
|
13
|
+
await syncDocumentToTypesense(typesenseClient, collectionSlug, doc, operation, config, vector);
|
|
13
14
|
};
|
|
14
15
|
hooks.afterChange = {
|
|
15
16
|
...hooks.afterChange,
|
|
@@ -33,9 +34,9 @@ export const setupHooks = (typesenseClient, pluginOptions, existingHooks = {})=>
|
|
|
33
34
|
}
|
|
34
35
|
return hooks;
|
|
35
36
|
};
|
|
36
|
-
export const syncDocumentToTypesense = async (typesenseClient, collectionSlug, doc, _operation, config)=>{
|
|
37
|
+
export const syncDocumentToTypesense = async (typesenseClient, collectionSlug, doc, _operation, config, vector)=>{
|
|
37
38
|
try {
|
|
38
|
-
const schema = mapCollectionToTypesense(collectionSlug, config);
|
|
39
|
+
const schema = mapCollectionToTypesense(collectionSlug, config, vector);
|
|
39
40
|
await ensureCollection(typesenseClient, collectionSlug, schema);
|
|
40
41
|
const typesenseDoc = mapToTypesense(doc, collectionSlug, config);
|
|
41
42
|
await typesenseClient.collections(collectionSlug).documents().upsert(typesenseDoc);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialization.d.ts","sourceRoot":"","sources":["../../src/lib/initialization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAuC,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAMvF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,eAAe,
|
|
1
|
+
{"version":3,"file":"initialization.d.ts","sourceRoot":"","sources":["../../src/lib/initialization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAuC,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAMvF,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,eAAe,kBAqB/B,CAAA"}
|
|
@@ -9,25 +9,23 @@ export const initializeTypesense = async (payload, typesenseClient, pluginOption
|
|
|
9
9
|
}
|
|
10
10
|
const isConnected = await testConnection(typesenseClient);
|
|
11
11
|
if (!isConnected) {
|
|
12
|
+
payload.logger.warn('Typesense connection failed.');
|
|
12
13
|
return;
|
|
13
14
|
}
|
|
14
15
|
const entries = Object.entries(pluginOptions.collections || {});
|
|
16
|
+
const vector = pluginOptions.vectorSearch;
|
|
15
17
|
for (const [slug, cfg] of entries){
|
|
16
18
|
if (cfg?.enabled) {
|
|
17
|
-
await initializeCollection(payload, typesenseClient, slug, cfg);
|
|
19
|
+
await initializeCollection(payload, typesenseClient, slug, cfg, vector);
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
};
|
|
21
|
-
const initializeCollection = async (payload, typesenseClient, collectionSlug, config)=>{
|
|
23
|
+
const initializeCollection = async (payload, typesenseClient, collectionSlug, config, vector)=>{
|
|
22
24
|
const collection = payload.collections[collectionSlug];
|
|
23
|
-
if (!collection)
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
const schema = mapCollectionToTypesense(collectionSlug, config);
|
|
25
|
+
if (!collection) return;
|
|
26
|
+
const schema = mapCollectionToTypesense(collectionSlug, config, vector);
|
|
27
27
|
const exists = await ensureCollection(typesenseClient, collectionSlug, schema);
|
|
28
|
-
if (!exists)
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
28
|
+
if (!exists) return;
|
|
31
29
|
await syncExistingDocuments(payload, typesenseClient, collectionSlug, config);
|
|
32
30
|
};
|
|
33
31
|
const syncExistingDocuments = async (payload, typesenseClient, collectionSlug, config)=>{
|
|
@@ -53,12 +51,8 @@ const syncExistingDocuments = async (payload, typesenseClient, collectionSlug, c
|
|
|
53
51
|
for(let i = 0; i < docs.length; i += batchSize){
|
|
54
52
|
const batch = docs.slice(i, i + batchSize);
|
|
55
53
|
const mapped = batch.filter((doc)=>{
|
|
56
|
-
if (typeof doc !== 'object' || doc === null)
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
if (!('id' in doc)) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
54
|
+
if (typeof doc !== 'object' || doc === null) return false;
|
|
55
|
+
if (!('id' in doc)) return false;
|
|
62
56
|
const id = doc.id;
|
|
63
57
|
return typeof id === 'string';
|
|
64
58
|
}).map((doc)=>mapToTypesense(doc, collectionSlug, config));
|
|
@@ -1,23 +1,7 @@
|
|
|
1
|
-
import { type BaseDocument, type TypesenseConfig } from '../types.js';
|
|
2
|
-
export declare const mapCollectionToTypesense: (collectionSlug: string, config: NonNullable<TypesenseConfig["collections"]>[string] | undefined) => {
|
|
1
|
+
import { type BaseDocument, type CollectionFieldSchema, type TypesenseConfig } from '../types.js';
|
|
2
|
+
export declare const mapCollectionToTypesense: (collectionSlug: string, config: NonNullable<TypesenseConfig["collections"]>[string] | undefined, vector?: NonNullable<TypesenseConfig["vectorSearch"]>) => {
|
|
3
3
|
name: string;
|
|
4
|
-
fields:
|
|
5
|
-
readonly name: "id";
|
|
6
|
-
readonly type: "string";
|
|
7
|
-
} | {
|
|
8
|
-
readonly name: "slug";
|
|
9
|
-
readonly type: "string";
|
|
10
|
-
} | {
|
|
11
|
-
readonly name: "createdAt";
|
|
12
|
-
readonly type: "int64";
|
|
13
|
-
} | {
|
|
14
|
-
readonly name: "updatedAt";
|
|
15
|
-
readonly type: "int64";
|
|
16
|
-
} | {
|
|
17
|
-
name: string;
|
|
18
|
-
type: "string";
|
|
19
|
-
facet: boolean;
|
|
20
|
-
})[];
|
|
4
|
+
fields: CollectionFieldSchema[];
|
|
21
5
|
};
|
|
22
6
|
export declare const mapToTypesense: (doc: BaseDocument, _collectionSlug: string, config: NonNullable<TypesenseConfig["collections"]>[string] | undefined) => Record<string, string | number>;
|
|
23
7
|
//# sourceMappingURL=schema-mapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-mapper.d.ts","sourceRoot":"","sources":["../../src/lib/schema-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"schema-mapper.d.ts","sourceRoot":"","sources":["../../src/lib/schema-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAGjG,eAAO,MAAM,wBAAwB,GACnC,gBAAgB,MAAM,EACtB,QAAQ,WAAW,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,EACvE,SAAS,WAAW,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;;;CAkDtD,CAAA;AAED,eAAO,MAAM,cAAc,GACzB,KAAK,YAAY,EACjB,iBAAiB,MAAM,EACvB,QAAQ,WAAW,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,oCA6FxE,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { extractText } from '../utils/extractText.js';
|
|
2
|
-
export const mapCollectionToTypesense = (collectionSlug, config)=>{
|
|
2
|
+
export const mapCollectionToTypesense = (collectionSlug, config, vector)=>{
|
|
3
3
|
const searchableFields = config?.searchFields || [
|
|
4
4
|
'title',
|
|
5
5
|
'content',
|
|
@@ -34,13 +34,28 @@ export const mapCollectionToTypesense = (collectionSlug, config)=>{
|
|
|
34
34
|
type: 'string',
|
|
35
35
|
facet: true
|
|
36
36
|
}));
|
|
37
|
+
const fields = [
|
|
38
|
+
...baseFields,
|
|
39
|
+
...searchFields,
|
|
40
|
+
...facetOnlyFields
|
|
41
|
+
];
|
|
42
|
+
if (vector?.enabled) {
|
|
43
|
+
const embedFromFields = vector.embedFrom ?? searchableFields;
|
|
44
|
+
const embeddingModel = vector.embeddingModel ?? 'ts/all-MiniLM-L12-v2';
|
|
45
|
+
fields.push({
|
|
46
|
+
name: 'embedding',
|
|
47
|
+
type: 'float[]',
|
|
48
|
+
embed: {
|
|
49
|
+
from: embedFromFields,
|
|
50
|
+
model_config: {
|
|
51
|
+
model_name: embeddingModel
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
}
|
|
37
56
|
const schema = {
|
|
38
57
|
name: collectionSlug,
|
|
39
|
-
fields
|
|
40
|
-
...baseFields,
|
|
41
|
-
...searchFields,
|
|
42
|
-
...facetOnlyFields
|
|
43
|
-
]
|
|
58
|
+
fields
|
|
44
59
|
};
|
|
45
60
|
return schema;
|
|
46
61
|
};
|
|
@@ -66,7 +81,18 @@ export const mapToTypesense = (doc, _collectionSlug, config)=>{
|
|
|
66
81
|
if (field.includes('.')) {
|
|
67
82
|
const [arrayField, subField] = field.split('.', 2);
|
|
68
83
|
if (arrayField && subField && Array.isArray(doc[arrayField])) {
|
|
69
|
-
const joined = doc[arrayField].map((item)=>
|
|
84
|
+
const joined = doc[arrayField].map((item)=>{
|
|
85
|
+
if (!item || typeof item !== 'object' || !(subField in item)) return '';
|
|
86
|
+
const raw = item[subField];
|
|
87
|
+
if (raw == null) return '';
|
|
88
|
+
if (typeof raw === 'string' || typeof raw === 'number') {
|
|
89
|
+
return String(raw);
|
|
90
|
+
}
|
|
91
|
+
if (typeof raw === 'object' && 'root' in raw) {
|
|
92
|
+
return extractText(raw) || '';
|
|
93
|
+
}
|
|
94
|
+
return '';
|
|
95
|
+
}).filter(Boolean).join(' ');
|
|
70
96
|
typesenseDoc[field] = joined;
|
|
71
97
|
} else {
|
|
72
98
|
typesenseDoc[field] = '';
|
|
@@ -80,13 +106,19 @@ export const mapToTypesense = (doc, _collectionSlug, config)=>{
|
|
|
80
106
|
}
|
|
81
107
|
if ((field === 'content' || field === 'description') && typeof value === 'object' && value !== null && 'root' in value) {
|
|
82
108
|
typesenseDoc[field] = extractText(value) || '';
|
|
83
|
-
} else {
|
|
109
|
+
} else if (typeof value === 'string' || typeof value === 'number') {
|
|
84
110
|
typesenseDoc[field] = String(value);
|
|
111
|
+
} else {
|
|
112
|
+
typesenseDoc[field] = '';
|
|
85
113
|
}
|
|
86
114
|
}
|
|
87
115
|
for (const field of facetFields){
|
|
88
116
|
const value = doc[field];
|
|
89
|
-
|
|
117
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
118
|
+
typesenseDoc[field] = String(value);
|
|
119
|
+
} else {
|
|
120
|
+
typesenseDoc[field] = 'unknown';
|
|
121
|
+
}
|
|
90
122
|
}
|
|
91
123
|
const hasSearchableContent = searchableFields.some((field)=>{
|
|
92
124
|
const value = typesenseDoc[field];
|
package/dist/types.d.ts
CHANGED
|
@@ -19,7 +19,9 @@ export interface SearchResult<T = any> {
|
|
|
19
19
|
collection?: string;
|
|
20
20
|
content?: string;
|
|
21
21
|
displayName?: string;
|
|
22
|
-
document:
|
|
22
|
+
document: {
|
|
23
|
+
id?: string;
|
|
24
|
+
} & T;
|
|
23
25
|
highlight?: {
|
|
24
26
|
[field: string]: {
|
|
25
27
|
matched_tokens: string[];
|
|
@@ -123,6 +125,11 @@ export type TypesenseConfig = {
|
|
|
123
125
|
protocol: 'http' | 'https';
|
|
124
126
|
}>;
|
|
125
127
|
};
|
|
128
|
+
vectorSearch?: {
|
|
129
|
+
embeddingModel?: string;
|
|
130
|
+
embedFrom?: string[];
|
|
131
|
+
enabled?: boolean;
|
|
132
|
+
};
|
|
126
133
|
};
|
|
127
134
|
export interface TypesenseSearchConfig<T = Record<string, any>> {
|
|
128
135
|
collections: Record<string, CollectionConfig<T>>;
|
|
@@ -160,8 +167,9 @@ export interface SearchParams {
|
|
|
160
167
|
export interface BaseSearchInputProps<T = any> {
|
|
161
168
|
baseUrl: string;
|
|
162
169
|
className?: string;
|
|
163
|
-
collections?: string
|
|
170
|
+
collections?: string[];
|
|
164
171
|
debounceMs?: number;
|
|
172
|
+
enableSuggestions?: boolean;
|
|
165
173
|
errorClassName?: string;
|
|
166
174
|
inputClassName?: string;
|
|
167
175
|
inputWrapperClassName?: string;
|
|
@@ -175,6 +183,7 @@ export interface BaseSearchInputProps<T = any> {
|
|
|
175
183
|
onResults?: (results: SearchResponse<T>) => void;
|
|
176
184
|
onSearch?: (query: string, results: SearchResponse<T>) => void;
|
|
177
185
|
placeholder?: string;
|
|
186
|
+
renderDate?: boolean;
|
|
178
187
|
resultsHeaderClassName?: string;
|
|
179
188
|
resultsListClassName?: string;
|
|
180
189
|
}
|
|
@@ -187,6 +196,10 @@ export interface CacheOptions {
|
|
|
187
196
|
maxSize?: number;
|
|
188
197
|
ttl?: number;
|
|
189
198
|
}
|
|
199
|
+
export interface CacheStats {
|
|
200
|
+
hits: number;
|
|
201
|
+
misses: number;
|
|
202
|
+
}
|
|
190
203
|
export interface HealthCheckResponse {
|
|
191
204
|
cache?: {
|
|
192
205
|
maxSize: number;
|
|
@@ -224,4 +237,38 @@ export interface ApiResponse<T = any> {
|
|
|
224
237
|
};
|
|
225
238
|
success: boolean;
|
|
226
239
|
}
|
|
240
|
+
export type FieldType = 'auto' | 'bool' | 'bool[]' | 'float' | 'float[]' | 'geopoint' | 'geopoint[]' | 'geopolygon' | 'image' | 'int32' | 'int32[]' | 'int64' | 'int64[]' | 'object' | 'object[]' | 'string' | 'string*' | 'string[]';
|
|
241
|
+
export interface CollectionFieldSchema {
|
|
242
|
+
[t: string]: unknown;
|
|
243
|
+
embed?: {
|
|
244
|
+
from: string[];
|
|
245
|
+
model_config: {
|
|
246
|
+
model_name: string;
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
facet?: boolean;
|
|
250
|
+
index?: boolean;
|
|
251
|
+
infix?: boolean;
|
|
252
|
+
locale?: string;
|
|
253
|
+
name: string;
|
|
254
|
+
num_dim?: number;
|
|
255
|
+
optional?: boolean;
|
|
256
|
+
range_index?: boolean;
|
|
257
|
+
sort?: boolean;
|
|
258
|
+
stem?: boolean;
|
|
259
|
+
store?: boolean;
|
|
260
|
+
type: FieldType;
|
|
261
|
+
}
|
|
262
|
+
export type CollectionSchema = {
|
|
263
|
+
default_sorting_field?: string;
|
|
264
|
+
enable_nested_fields?: boolean;
|
|
265
|
+
fields: CollectionFieldSchema[];
|
|
266
|
+
metadata?: object;
|
|
267
|
+
name: string;
|
|
268
|
+
symbols_to_index?: string[];
|
|
269
|
+
token_separators?: string[];
|
|
270
|
+
voice_query_model?: {
|
|
271
|
+
model_name?: string;
|
|
272
|
+
};
|
|
273
|
+
};
|
|
227
274
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;IAC/B,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;IACxB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,IAAI,GAAG,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAA;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,QAAQ;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACtB,IAAI,CAAC,EAAE,YAAY,CAAA;CACpB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,GAAG;IACnC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type Typesense from 'typesense';
|
|
2
|
-
|
|
2
|
+
import { type CollectionSchema } from '../types.js';
|
|
3
|
+
export declare const ensureCollection: (typesenseClient: Typesense.Client, collectionSlug: string, schema: CollectionSchema) => Promise<boolean>;
|
|
3
4
|
//# sourceMappingURL=ensureCollection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensureCollection.d.ts","sourceRoot":"","sources":["../../src/utils/ensureCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,SAAS,CAAC,MAAM,EACjC,gBAAgB,MAAM,EACtB,QAAQ,
|
|
1
|
+
{"version":3,"file":"ensureCollection.d.ts","sourceRoot":"","sources":["../../src/utils/ensureCollection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD,eAAO,MAAM,gBAAgB,GAC3B,iBAAiB,SAAS,CAAC,MAAM,EACjC,gBAAgB,MAAM,EACtB,QAAQ,gBAAgB,KACvB,OAAO,CAAC,OAAO,CAYjB,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const extractText: (richText:
|
|
1
|
+
export declare const extractText: (richText: unknown) => string;
|
|
2
2
|
//# sourceMappingURL=extractText.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractText.d.ts","sourceRoot":"","sources":["../../src/utils/extractText.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,GAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"extractText.d.ts","sourceRoot":"","sources":["../../src/utils/extractText.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,GAAI,UAAU,OAAO,KAAG,MAsB/C,CAAA"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
export const extractText = (richText)=>{
|
|
2
|
-
if (!richText || !richText
|
|
2
|
+
if (!richText || typeof richText !== 'object' || !('root' in richText)) {
|
|
3
3
|
return '';
|
|
4
4
|
}
|
|
5
5
|
const extract = (node)=>{
|
|
6
|
-
if (typeof node === 'string')
|
|
7
|
-
return node;
|
|
8
|
-
}
|
|
6
|
+
if (typeof node === 'string') return node;
|
|
9
7
|
if (node && typeof node === 'object') {
|
|
10
|
-
if (node.text) {
|
|
8
|
+
if ('text' in node && typeof node.text === 'string') {
|
|
11
9
|
return node.text;
|
|
12
10
|
}
|
|
13
|
-
if (
|
|
11
|
+
if ('children' in node && Array.isArray(node.children)) {
|
|
14
12
|
return node.children.map(extract).join('');
|
|
15
13
|
}
|
|
16
14
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type Typesense from 'typesense';
|
|
2
2
|
import { type TypesenseConfig } from '../types.js';
|
|
3
3
|
export declare const getAllCollections: (typesenseClient: Typesense.Client, pluginOptions: TypesenseConfig, query: string, options: {
|
|
4
|
+
collections?: string[];
|
|
4
5
|
filters: Record<string, unknown>;
|
|
5
6
|
page: number;
|
|
6
7
|
per_page: number;
|
|
7
8
|
sort_by?: string;
|
|
9
|
+
vector?: boolean;
|
|
8
10
|
}) => Promise<Response>;
|
|
9
11
|
//# sourceMappingURL=getAllCollections.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getAllCollections.d.ts","sourceRoot":"","sources":["../../src/utils/getAllCollections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAGtC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"getAllCollections.d.ts","sourceRoot":"","sources":["../../src/utils/getAllCollections.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAGtC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAA;AAGlD,eAAO,MAAM,iBAAiB,GAC5B,iBAAiB,SAAS,CAAC,MAAM,EACjC,eAAe,eAAe,EAC9B,OAAO,MAAM,EACb,SAAS;IACP,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,sBAmHF,CAAA"}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { searchCache } from '../lib/cache.js';
|
|
2
|
+
import { performVectorSearch } from './vectorSearch.js';
|
|
2
3
|
export const getAllCollections = async (typesenseClient, pluginOptions, query, options)=>{
|
|
3
4
|
try {
|
|
4
|
-
const
|
|
5
|
+
const cacheKey = {
|
|
6
|
+
...options,
|
|
7
|
+
collections: options.collections ? [
|
|
8
|
+
...options.collections
|
|
9
|
+
].sort().join(',') : undefined
|
|
10
|
+
};
|
|
11
|
+
const cachedResult = searchCache.get(query, 'universal', cacheKey);
|
|
5
12
|
if (cachedResult) {
|
|
6
13
|
return Response.json(cachedResult);
|
|
7
14
|
}
|
|
8
|
-
|
|
15
|
+
let enabledCollections = Object.entries(pluginOptions.collections || {}).filter(([_, config])=>config?.enabled);
|
|
16
|
+
if (options.collections && options.collections.length > 0) {
|
|
17
|
+
enabledCollections = enabledCollections.filter(([collectionName])=>options.collections.includes(collectionName));
|
|
18
|
+
}
|
|
9
19
|
if (enabledCollections.length === 0) {
|
|
10
20
|
return Response.json({
|
|
11
21
|
error: 'No collections enabled for search'
|
|
@@ -15,17 +25,26 @@ export const getAllCollections = async (typesenseClient, pluginOptions, query, o
|
|
|
15
25
|
}
|
|
16
26
|
const searchPromises = enabledCollections.map(async ([collectionName, config])=>{
|
|
17
27
|
try {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
let results;
|
|
29
|
+
if (options.vector) {
|
|
30
|
+
results = await performVectorSearch(typesenseClient, query, {
|
|
31
|
+
collection: collectionName,
|
|
32
|
+
page: options.page,
|
|
33
|
+
per_page: options.per_page
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
const searchParameters = {
|
|
37
|
+
highlight_full_fields: config?.searchFields?.join(',') || 'title,content',
|
|
38
|
+
num_typos: 0,
|
|
39
|
+
page: options.page,
|
|
40
|
+
per_page: options.per_page,
|
|
41
|
+
q: query,
|
|
42
|
+
query_by: config?.searchFields?.join(',') || 'title,content',
|
|
43
|
+
snippet_threshold: 30,
|
|
44
|
+
typo_tokens_threshold: 1
|
|
45
|
+
};
|
|
46
|
+
results = await typesenseClient.collections(collectionName).documents().search(searchParameters);
|
|
47
|
+
}
|
|
29
48
|
return {
|
|
30
49
|
collection: collectionName,
|
|
31
50
|
displayName: config?.displayName || collectionName,
|
|
@@ -71,7 +90,7 @@ export const getAllCollections = async (typesenseClient, pluginOptions, query, o
|
|
|
71
90
|
search_cutoff: false,
|
|
72
91
|
search_time_ms: 0
|
|
73
92
|
};
|
|
74
|
-
searchCache.set(query, searchResult, 'universal',
|
|
93
|
+
searchCache.set(query, searchResult, 'universal', cacheKey);
|
|
75
94
|
return Response.json(searchResult);
|
|
76
95
|
} catch (error) {
|
|
77
96
|
return Response.json({
|
package/dist/utils/keyboard.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type React from 'react';
|
|
|
2
2
|
export declare function handleKeyboard(e: React.KeyboardEvent, options: {
|
|
3
3
|
inputRef: React.RefObject<HTMLInputElement | null>;
|
|
4
4
|
isOpen: boolean;
|
|
5
|
-
results:
|
|
5
|
+
results: unknown;
|
|
6
6
|
resultsRef: React.RefObject<HTMLDivElement | null>;
|
|
7
7
|
}): void;
|
|
8
8
|
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/utils/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,wBAAgB,cAAc,CAC5B,CAAC,EAAE,KAAK,CAAC,aAAa,EACtB,OAAO,EAAE;IACP,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAClD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/utils/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,wBAAgB,cAAc,CAC5B,CAAC,EAAE,KAAK,CAAC,aAAa,EACtB,OAAO,EAAE;IACP,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAA;IAClD,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;CACnD,QAuCF"}
|
package/dist/utils/keyboard.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
export function handleKeyboard(e, options) {
|
|
2
2
|
const { inputRef, isOpen, results, resultsRef } = options;
|
|
3
|
-
if (!isOpen || !results)
|
|
4
|
-
return;
|
|
5
|
-
}
|
|
3
|
+
if (!isOpen || !results) return;
|
|
6
4
|
const resultItems = resultsRef.current?.querySelectorAll('[data-result-item]');
|
|
7
|
-
if (!resultItems)
|
|
8
|
-
return;
|
|
9
|
-
}
|
|
5
|
+
if (!resultItems) return;
|
|
10
6
|
const currentIndex = Array.from(resultItems).findIndex((item)=>item === document.activeElement);
|
|
11
7
|
switch(e.key){
|
|
12
8
|
case 'ArrowDown':
|
|
@@ -6,8 +6,9 @@ type UseSearchOptions<T> = {
|
|
|
6
6
|
onResults?: (results: SearchResponse<T>) => void;
|
|
7
7
|
onSearch?: (query: string, results: SearchResponse<T>) => void;
|
|
8
8
|
perPage: number;
|
|
9
|
+
vector?: boolean;
|
|
9
10
|
};
|
|
10
|
-
export declare function useSearch<T = Record<string, unknown>>({ baseUrl, collections, minQueryLength, onResults, onSearch, perPage, }: UseSearchOptions<T>): {
|
|
11
|
+
export declare function useSearch<T = Record<string, unknown>>({ baseUrl, collections, minQueryLength, onResults, onSearch, perPage, vector, }: UseSearchOptions<T>): {
|
|
11
12
|
error: string | null;
|
|
12
13
|
isLoading: boolean;
|
|
13
14
|
results: SearchResponse<T> | null;
|