@tsproxy/js 0.0.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/index.d.ts +54 -0
- package/dist/index.js +61 -0
- package/package.json +40 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InstantSearch-compatible SearchClient interface.
|
|
3
|
+
* Can be passed directly to InstantSearch's searchClient prop.
|
|
4
|
+
*/
|
|
5
|
+
interface SearchClient {
|
|
6
|
+
search(requests: readonly SearchRequest[]): Promise<SearchResponse>;
|
|
7
|
+
searchForFacetValues?(requests: readonly SearchRequest[]): Promise<SearchResponse>;
|
|
8
|
+
clearCache?(): void;
|
|
9
|
+
}
|
|
10
|
+
interface SearchRequest {
|
|
11
|
+
indexName: string;
|
|
12
|
+
params?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
interface Hit {
|
|
15
|
+
objectID: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
interface FacetValue {
|
|
19
|
+
value: string;
|
|
20
|
+
count: number;
|
|
21
|
+
highlighted: string;
|
|
22
|
+
isRefined: boolean;
|
|
23
|
+
}
|
|
24
|
+
interface SearchResponseResult {
|
|
25
|
+
hits: Hit[];
|
|
26
|
+
nbHits: number;
|
|
27
|
+
page: number;
|
|
28
|
+
nbPages: number;
|
|
29
|
+
hitsPerPage: number;
|
|
30
|
+
exhaustiveNbHits: boolean;
|
|
31
|
+
query: string;
|
|
32
|
+
params: string;
|
|
33
|
+
index: string;
|
|
34
|
+
processingTimeMS: number;
|
|
35
|
+
facets?: Record<string, Record<string, number>>;
|
|
36
|
+
}
|
|
37
|
+
interface SearchResponse {
|
|
38
|
+
results: SearchResponseResult[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface CreateSearchClientOptions {
|
|
42
|
+
url: string;
|
|
43
|
+
locale?: string;
|
|
44
|
+
cache?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates an InstantSearch-compatible searchClient that proxies requests
|
|
48
|
+
* through the tsproxy server.
|
|
49
|
+
*
|
|
50
|
+
* Includes built-in request deduplication and result caching.
|
|
51
|
+
*/
|
|
52
|
+
declare function createSearchClient(options: CreateSearchClientOptions): SearchClient;
|
|
53
|
+
|
|
54
|
+
export { type FacetValue, type Hit, type SearchClient, type SearchRequest, type SearchResponse, type SearchResponseResult, createSearchClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/adapter/index.ts
|
|
2
|
+
function createSearchClient(options) {
|
|
3
|
+
const { url, cache: enableCache = true } = options;
|
|
4
|
+
let locale = options.locale;
|
|
5
|
+
const resultCache = /* @__PURE__ */ new Map();
|
|
6
|
+
const pendingRequests = /* @__PURE__ */ new Map();
|
|
7
|
+
function getCacheKey(requests) {
|
|
8
|
+
return JSON.stringify({ requests, locale });
|
|
9
|
+
}
|
|
10
|
+
async function performSearch(requests) {
|
|
11
|
+
const cacheKey = getCacheKey(requests);
|
|
12
|
+
if (enableCache) {
|
|
13
|
+
const cached = resultCache.get(cacheKey);
|
|
14
|
+
if (cached) {
|
|
15
|
+
return cached;
|
|
16
|
+
}
|
|
17
|
+
const pending = pendingRequests.get(cacheKey);
|
|
18
|
+
if (pending) {
|
|
19
|
+
return pending;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const promise = (async () => {
|
|
23
|
+
const response = await fetch(`${url}/api/search`, {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
...locale ? { "X-Locale": locale } : {}
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify({ requests })
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
throw new Error(`Search request failed: ${response.status} ${response.statusText}`);
|
|
33
|
+
}
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
if (enableCache) {
|
|
36
|
+
resultCache.set(cacheKey, data);
|
|
37
|
+
}
|
|
38
|
+
return data;
|
|
39
|
+
})();
|
|
40
|
+
if (enableCache) {
|
|
41
|
+
pendingRequests.set(cacheKey, promise);
|
|
42
|
+
promise.finally(() => {
|
|
43
|
+
pendingRequests.delete(cacheKey);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return promise;
|
|
47
|
+
}
|
|
48
|
+
function clearCache() {
|
|
49
|
+
resultCache.clear();
|
|
50
|
+
pendingRequests.clear();
|
|
51
|
+
}
|
|
52
|
+
const client = {
|
|
53
|
+
search: performSearch,
|
|
54
|
+
searchForFacetValues: performSearch,
|
|
55
|
+
clearCache
|
|
56
|
+
};
|
|
57
|
+
return client;
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
createSearchClient
|
|
61
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tsproxy/js",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "InstantSearch-compatible searchClient adapter for tsproxy",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/akshitkrnagpal/tsproxy.git",
|
|
23
|
+
"directory": "packages/js"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"keywords": [
|
|
27
|
+
"typesense",
|
|
28
|
+
"instantsearch",
|
|
29
|
+
"search",
|
|
30
|
+
"proxy"
|
|
31
|
+
],
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"tsup": "^8.4.0",
|
|
34
|
+
"typescript": "^5.5.3"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup src/index.ts --format esm --dts",
|
|
38
|
+
"typecheck": "tsc --noEmit"
|
|
39
|
+
}
|
|
40
|
+
}
|