@cripty2001/utils 0.0.260 → 0.0.262
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/Appserver/client/react.js +24 -34
- package/dist/Appserver/server.d.ts +2 -1
- package/dist/Appserver/server.js +25 -34
- package/dist/Appstorage.d.ts +1 -1
- package/dist/Appstorage.js +6 -10
- package/dist/Dispatcher.js +9 -13
- package/dist/Logger/Logger.js +5 -7
- package/dist/Searcher/index.js +1 -5
- package/dist/index.js +38 -70
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +1 -5
- package/dist/react/logger-display.js +12 -18
- package/dist/react-ui/button.js +9 -12
- package/dist/react-ui/copiable.js +11 -14
- package/dist/react-ui/form.d.ts +2 -2
- package/dist/react-ui/form.js +13 -19
- package/dist/react-ui/index.d.ts +8 -8
- package/dist/react-ui/index.js +9 -22
- package/dist/react-ui/input.js +11 -14
- package/dist/react-ui/loader.d.ts +1 -1
- package/dist/react-ui/loader.js +9 -12
- package/dist/react-ui/modal.js +9 -12
- package/dist/react-ui/table.js +6 -9
- package/dist/react-ui/textButton.d.ts +1 -1
- package/dist/react-ui/textButton.js +4 -10
- package/dist/react-whispr.d.ts +3 -3
- package/dist/react-whispr.js +60 -76
- package/package.json +2 -1
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports.useApi = useApi;
|
|
6
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
-
const react_1 = require("react");
|
|
8
|
-
const react_oidc_context_1 = require("react-oidc-context");
|
|
9
|
-
function ApiProvider({ children, config, templates }) {
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, createContext, useContext, useMemo, } from "react";
|
|
3
|
+
import { AuthProvider, useAuth } from "react-oidc-context";
|
|
4
|
+
export default function ApiProvider({ children, config, templates }) {
|
|
10
5
|
const oidcConfig = {
|
|
11
6
|
authority: config.issuer,
|
|
12
7
|
client_id: config.clientId,
|
|
@@ -22,11 +17,11 @@ function ApiProvider({ children, config, templates }) {
|
|
|
22
17
|
window.location.replace(state?.returnTo ?? "/");
|
|
23
18
|
},
|
|
24
19
|
};
|
|
25
|
-
return ((
|
|
20
|
+
return (_jsx(AuthProvider, { ...oidcConfig, children: _jsx(_ApiProvider, { apiUrl: config.apiUrl, children: _jsx(_LoginSheet, { config: config, templates: templates, children: children }) }) }));
|
|
26
21
|
}
|
|
27
22
|
function _LoginSheet({ children, config, templates }) {
|
|
28
|
-
const auth =
|
|
29
|
-
const login =
|
|
23
|
+
const auth = useAuth();
|
|
24
|
+
const login = useCallback(async () => {
|
|
30
25
|
sessionStorage.setItem("auth_redirect_url", window.location.href);
|
|
31
26
|
const state = {
|
|
32
27
|
returnTo: window.location.href
|
|
@@ -39,7 +34,7 @@ function _LoginSheet({ children, config, templates }) {
|
|
|
39
34
|
state
|
|
40
35
|
});
|
|
41
36
|
}, [auth]);
|
|
42
|
-
|
|
37
|
+
useEffect(() => {
|
|
43
38
|
if (auth.isLoading)
|
|
44
39
|
return;
|
|
45
40
|
if (auth.isAuthenticated && auth.user)
|
|
@@ -49,16 +44,15 @@ function _LoginSheet({ children, config, templates }) {
|
|
|
49
44
|
login();
|
|
50
45
|
}, [auth, login]);
|
|
51
46
|
if (auth.isLoading)
|
|
52
|
-
return (
|
|
47
|
+
return _jsx(templates.Loading, { message: "Restoring your session..." });
|
|
53
48
|
if (auth.isAuthenticated && auth.user)
|
|
54
|
-
return (
|
|
55
|
-
return (
|
|
49
|
+
return _jsx(_Fragment, { children: children });
|
|
50
|
+
return _jsx(templates.Error, { message: auth.error?.message ?? "An error occurred while restoring your session.", callback: login });
|
|
56
51
|
}
|
|
57
|
-
const ApiContext =
|
|
58
|
-
class ApiError extends Error {
|
|
52
|
+
const ApiContext = createContext(null);
|
|
53
|
+
export class ApiError extends Error {
|
|
59
54
|
}
|
|
60
|
-
|
|
61
|
-
class AuthApiError extends ApiError {
|
|
55
|
+
export class AuthApiError extends ApiError {
|
|
62
56
|
recoverable;
|
|
63
57
|
constructor(recoverable) {
|
|
64
58
|
super(recoverable ?
|
|
@@ -67,16 +61,14 @@ class AuthApiError extends ApiError {
|
|
|
67
61
|
this.recoverable = recoverable;
|
|
68
62
|
}
|
|
69
63
|
}
|
|
70
|
-
|
|
71
|
-
class ValidationApiError extends ApiError {
|
|
64
|
+
export class ValidationApiError extends ApiError {
|
|
72
65
|
data;
|
|
73
66
|
constructor(data) {
|
|
74
67
|
super();
|
|
75
68
|
this.data = data;
|
|
76
69
|
}
|
|
77
70
|
}
|
|
78
|
-
|
|
79
|
-
class ClientApiError extends ApiError {
|
|
71
|
+
export class ClientApiError extends ApiError {
|
|
80
72
|
code;
|
|
81
73
|
message;
|
|
82
74
|
details;
|
|
@@ -87,22 +79,20 @@ class ClientApiError extends ApiError {
|
|
|
87
79
|
this.details = details;
|
|
88
80
|
}
|
|
89
81
|
}
|
|
90
|
-
|
|
91
|
-
class UnknownApiError extends ApiError {
|
|
82
|
+
export class UnknownApiError extends ApiError {
|
|
92
83
|
constructor() {
|
|
93
84
|
super();
|
|
94
85
|
this.message = "An unknown error occurred";
|
|
95
86
|
}
|
|
96
87
|
}
|
|
97
|
-
exports.UnknownApiError = UnknownApiError;
|
|
98
88
|
function _ApiProvider({ children, apiUrl }) {
|
|
99
|
-
const auth =
|
|
100
|
-
const profile =
|
|
89
|
+
const auth = useAuth();
|
|
90
|
+
const profile = useMemo(() => {
|
|
101
91
|
if (!auth.user)
|
|
102
92
|
return undefined;
|
|
103
93
|
return auth.user.profile;
|
|
104
94
|
}, [auth]);
|
|
105
|
-
const logout =
|
|
95
|
+
const logout = useCallback(async (remote = false) => {
|
|
106
96
|
if (remote) {
|
|
107
97
|
await auth.signoutRedirect();
|
|
108
98
|
}
|
|
@@ -110,7 +100,7 @@ function _ApiProvider({ children, apiUrl }) {
|
|
|
110
100
|
auth.removeUser();
|
|
111
101
|
}
|
|
112
102
|
}, [auth]);
|
|
113
|
-
const exec =
|
|
103
|
+
const exec = useCallback(async (action, data, onError) => {
|
|
114
104
|
const res = await fetch(`${apiUrl}/exec/${action.startsWith('/') ? action.slice(1) : action}`, {
|
|
115
105
|
method: "POST",
|
|
116
106
|
headers: {
|
|
@@ -143,10 +133,10 @@ function _ApiProvider({ children, apiUrl }) {
|
|
|
143
133
|
}
|
|
144
134
|
throw new UnknownApiError();
|
|
145
135
|
}, [auth]);
|
|
146
|
-
return (
|
|
136
|
+
return _jsxs(ApiContext.Provider, { value: { exec, logout, profile }, children: [" ", children, " "] });
|
|
147
137
|
}
|
|
148
|
-
function useApi() {
|
|
149
|
-
const ctx =
|
|
138
|
+
export function useApi() {
|
|
139
|
+
const ctx = useContext(ApiContext);
|
|
150
140
|
if (!ctx)
|
|
151
141
|
throw new Error("useApi must be used within ApiProvider");
|
|
152
142
|
return ctx;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Fastify from 'fastify';
|
|
1
2
|
import { type Static, type TSchema, type TypeBoxTypeProvider, Type } from '@fastify/type-provider-typebox';
|
|
2
3
|
export { Type };
|
|
3
4
|
declare module 'fastify' {
|
|
@@ -8,7 +9,7 @@ declare module 'fastify' {
|
|
|
8
9
|
}
|
|
9
10
|
}
|
|
10
11
|
export declare class Appserver {
|
|
11
|
-
readonly fastify:
|
|
12
|
+
readonly fastify: Fastify.FastifyInstance<import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, Fastify.FastifyBaseLogger, TypeBoxTypeProvider>;
|
|
12
13
|
private readonly jwks;
|
|
13
14
|
private readonly issuer;
|
|
14
15
|
private readonly audience;
|
package/dist/Appserver/server.js
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, "Type", { enumerable: true, get: function () { return type_provider_typebox_1.Type; } });
|
|
10
|
-
const path_1 = __importDefault(require("path"));
|
|
11
|
-
const promises_1 = require("fs/promises");
|
|
12
|
-
const jose_1 = require("jose");
|
|
13
|
-
class Appserver {
|
|
14
|
-
fastify = (0, fastify_1.default)({ logger: true })
|
|
1
|
+
import Fastify from 'fastify';
|
|
2
|
+
import { Type } from '@fastify/type-provider-typebox';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { readdir } from 'fs/promises';
|
|
5
|
+
import { createRemoteJWKSet, errors, jwtVerify } from 'jose';
|
|
6
|
+
export { Type };
|
|
7
|
+
export class Appserver {
|
|
8
|
+
fastify = Fastify({ logger: true })
|
|
15
9
|
.withTypeProvider();
|
|
16
10
|
jwks;
|
|
17
11
|
issuer;
|
|
@@ -28,7 +22,7 @@ class Appserver {
|
|
|
28
22
|
throw new Error('OIDC discovery failed: issuer not found');
|
|
29
23
|
const jwksUrl = config.jwks_uri;
|
|
30
24
|
const issuer = config.issuer;
|
|
31
|
-
const jwks =
|
|
25
|
+
const jwks = createRemoteJWKSet(new URL(jwksUrl));
|
|
32
26
|
return {
|
|
33
27
|
jwks,
|
|
34
28
|
issuer
|
|
@@ -83,7 +77,7 @@ class Appserver {
|
|
|
83
77
|
throw new AppserverAuthHandledError('HEADER_MISSING', 'Missing or invalid authorization header', true);
|
|
84
78
|
const payload = await (async () => {
|
|
85
79
|
try {
|
|
86
|
-
const { payload } = await
|
|
80
|
+
const { payload } = await jwtVerify(token.slice(7), this.jwks, {
|
|
87
81
|
issuer: this.issuer,
|
|
88
82
|
audience: this.audience,
|
|
89
83
|
requiredClaims: ['sub', 'iat', 'exp'],
|
|
@@ -91,16 +85,16 @@ class Appserver {
|
|
|
91
85
|
return payload;
|
|
92
86
|
}
|
|
93
87
|
catch (err) {
|
|
94
|
-
if (err instanceof
|
|
88
|
+
if (err instanceof errors.JWTExpired)
|
|
95
89
|
throw new AppserverAuthHandledError('TOKEN_EXPIRED', 'Access token has expired.', true);
|
|
96
|
-
if (err instanceof
|
|
97
|
-
|| err instanceof
|
|
98
|
-
|| err instanceof
|
|
99
|
-
|| err instanceof
|
|
100
|
-
|| err instanceof
|
|
101
|
-
|| err instanceof
|
|
90
|
+
if (err instanceof errors.JWTInvalid
|
|
91
|
+
|| err instanceof errors.JWTClaimValidationFailed
|
|
92
|
+
|| err instanceof errors.JWSSignatureVerificationFailed
|
|
93
|
+
|| err instanceof errors.JWSInvalid
|
|
94
|
+
|| err instanceof errors.JWKSNoMatchingKey
|
|
95
|
+
|| err instanceof errors.JOSEAlgNotAllowed)
|
|
102
96
|
throw new AppserverAuthHandledError('TOKEN_INVALID', 'Access token is invalid', true);
|
|
103
|
-
if (err instanceof
|
|
97
|
+
if (err instanceof errors.JWKSTimeout || err instanceof errors.JWKSInvalid)
|
|
104
98
|
throw new Error('Failed to verify the access token against the identity provider JWKS.', { cause: err });
|
|
105
99
|
if (err instanceof Error)
|
|
106
100
|
throw err;
|
|
@@ -156,8 +150,8 @@ class Appserver {
|
|
|
156
150
|
});
|
|
157
151
|
}
|
|
158
152
|
async autoload(base) {
|
|
159
|
-
const absBase =
|
|
160
|
-
const files = await
|
|
153
|
+
const absBase = path.resolve(base);
|
|
154
|
+
const files = await readdir(absBase, {
|
|
161
155
|
recursive: true,
|
|
162
156
|
withFileTypes: true
|
|
163
157
|
});
|
|
@@ -168,11 +162,11 @@ class Appserver {
|
|
|
168
162
|
return;
|
|
169
163
|
}
|
|
170
164
|
for (const entry of jsFiles) {
|
|
171
|
-
const fullPath =
|
|
172
|
-
const action =
|
|
165
|
+
const fullPath = path.join(entry.parentPath, entry.name);
|
|
166
|
+
const action = path
|
|
173
167
|
.relative(absBase, fullPath)
|
|
174
168
|
.replace(/\.js$/, '')
|
|
175
|
-
.split(
|
|
169
|
+
.split(path.sep)
|
|
176
170
|
.join('/');
|
|
177
171
|
const ACTION_REGEX = /^([a-z0-9]+\/)*[a-z0-9]+$/;
|
|
178
172
|
if (!ACTION_REGEX.test(action))
|
|
@@ -184,7 +178,6 @@ class Appserver {
|
|
|
184
178
|
}
|
|
185
179
|
}
|
|
186
180
|
}
|
|
187
|
-
exports.Appserver = Appserver;
|
|
188
181
|
class AppserverHandledError extends Error {
|
|
189
182
|
status;
|
|
190
183
|
code;
|
|
@@ -196,15 +189,13 @@ class AppserverHandledError extends Error {
|
|
|
196
189
|
this.details = details;
|
|
197
190
|
}
|
|
198
191
|
}
|
|
199
|
-
class AppserverAuthHandledError extends AppserverHandledError {
|
|
192
|
+
export class AppserverAuthHandledError extends AppserverHandledError {
|
|
200
193
|
constructor(code, message, recoverable = false) {
|
|
201
194
|
super(code, message, recoverable ? 401 : 403, {});
|
|
202
195
|
}
|
|
203
196
|
}
|
|
204
|
-
|
|
205
|
-
class AppserverUserHandledError extends AppserverHandledError {
|
|
197
|
+
export class AppserverUserHandledError extends AppserverHandledError {
|
|
206
198
|
constructor(code, message, details) {
|
|
207
199
|
super(code, message, 400, details ?? {});
|
|
208
200
|
}
|
|
209
201
|
}
|
|
210
|
-
exports.AppserverUserHandledError = AppserverUserHandledError;
|
package/dist/Appstorage.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Whispr } from '@cripty2001/whispr';
|
|
2
|
-
import { JSONEncodable } from './index';
|
|
2
|
+
import { JSONEncodable } from './index.js';
|
|
3
3
|
export type AppstorageData = Record<string, JSONEncodable>;
|
|
4
4
|
export type AppstorageItemData<T extends AppstorageData> = {
|
|
5
5
|
key: string;
|
package/dist/Appstorage.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const whispr_1 = require("@cripty2001/whispr");
|
|
5
|
-
const Dispatcher_1 = require("./Dispatcher");
|
|
6
|
-
class Appstorage {
|
|
1
|
+
import { Whispr } from '@cripty2001/whispr';
|
|
2
|
+
import { Dispatcher } from './Dispatcher.js';
|
|
3
|
+
export class Appstorage {
|
|
7
4
|
static instances = new Map();
|
|
8
5
|
static getInstance(key) {
|
|
9
6
|
if (!this.instances.has(key))
|
|
@@ -18,7 +15,7 @@ class Appstorage {
|
|
|
18
15
|
}, 200);
|
|
19
16
|
constructor(PREFIX) {
|
|
20
17
|
this.PREFIX = PREFIX;
|
|
21
|
-
[this.index, this._setIndex] =
|
|
18
|
+
[this.index, this._setIndex] = Whispr.create({});
|
|
22
19
|
this.refresh();
|
|
23
20
|
}
|
|
24
21
|
add(key, data) {
|
|
@@ -76,7 +73,6 @@ class Appstorage {
|
|
|
76
73
|
});
|
|
77
74
|
}
|
|
78
75
|
}
|
|
79
|
-
exports.Appstorage = Appstorage;
|
|
80
76
|
class AppstorageItem {
|
|
81
77
|
PREFIX;
|
|
82
78
|
static instances = new Map();
|
|
@@ -101,7 +97,7 @@ class AppstorageItem {
|
|
|
101
97
|
constructor(PREFIX, key) {
|
|
102
98
|
this.PREFIX = PREFIX;
|
|
103
99
|
this.key = key;
|
|
104
|
-
[this.data, this._setData] =
|
|
100
|
+
[this.data, this._setData] = Whispr.create(this.loadData());
|
|
105
101
|
this.update = (data) => {
|
|
106
102
|
this._setData({
|
|
107
103
|
key: `${this.PREFIX}${this.key}`,
|
|
@@ -118,7 +114,7 @@ class AppstorageItem {
|
|
|
118
114
|
data: {}
|
|
119
115
|
});
|
|
120
116
|
};
|
|
121
|
-
new
|
|
117
|
+
new Dispatcher(this.data, async () => {
|
|
122
118
|
this.flush();
|
|
123
119
|
}, 500);
|
|
124
120
|
}
|
package/dist/Dispatcher.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const lodash_1 = require("lodash");
|
|
6
|
-
const _1 = require(".");
|
|
7
|
-
class Dispatcher {
|
|
1
|
+
import { Whispr } from "@cripty2001/whispr";
|
|
2
|
+
import isEqual from "lodash/isEqual.js";
|
|
3
|
+
import { sleep } from "./index.js";
|
|
4
|
+
export class Dispatcher {
|
|
8
5
|
state;
|
|
9
6
|
setState;
|
|
10
7
|
data;
|
|
@@ -21,7 +18,7 @@ class Dispatcher {
|
|
|
21
18
|
this.f = f;
|
|
22
19
|
this.DEBOUNCE_INTERVAL = DEBOUNCE_INTERVAL;
|
|
23
20
|
this.value = value;
|
|
24
|
-
[this.state, this.setState] =
|
|
21
|
+
[this.state, this.setState] = Whispr.create({
|
|
25
22
|
controller: new AbortController(),
|
|
26
23
|
payload: {
|
|
27
24
|
input: value.value,
|
|
@@ -33,15 +30,15 @@ class Dispatcher {
|
|
|
33
30
|
});
|
|
34
31
|
// Subscribing to input changes
|
|
35
32
|
this.value.subscribe((v) => {
|
|
36
|
-
if (this.lastValue !== null &&
|
|
33
|
+
if (this.lastValue !== null && isEqual(this.lastValue, v))
|
|
37
34
|
return;
|
|
38
35
|
this.lastValue = v;
|
|
39
36
|
this.dispatch(v);
|
|
40
37
|
});
|
|
41
38
|
// Initing public derived whisprs
|
|
42
|
-
this.data =
|
|
39
|
+
this.data = Whispr
|
|
43
40
|
.from({ state: this.state }, ({ state }) => state.payload);
|
|
44
|
-
this.filtered =
|
|
41
|
+
this.filtered = Whispr.from({
|
|
45
42
|
data: this.data
|
|
46
43
|
}, ({ data: { output: response } }) => {
|
|
47
44
|
if (response.loading)
|
|
@@ -136,7 +133,7 @@ class Dispatcher {
|
|
|
136
133
|
const toReturn = (async () => {
|
|
137
134
|
// Allow for sync operations
|
|
138
135
|
if (this.DEBOUNCE_INTERVAL > 0) {
|
|
139
|
-
await
|
|
136
|
+
await sleep(this.DEBOUNCE_INTERVAL);
|
|
140
137
|
}
|
|
141
138
|
if (signals.controller.signal.aborted)
|
|
142
139
|
throw new DOMException('Debounced', 'AbortError');
|
|
@@ -152,4 +149,3 @@ class Dispatcher {
|
|
|
152
149
|
return toReturn;
|
|
153
150
|
}
|
|
154
151
|
}
|
|
155
|
-
exports.Dispatcher = Dispatcher;
|
package/dist/Logger/Logger.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const whispr_1 = require("@cripty2001/whispr");
|
|
4
|
-
const __1 = require("..");
|
|
1
|
+
import { Whispr } from "@cripty2001/whispr";
|
|
2
|
+
import { getRandomId } from "../index.js";
|
|
5
3
|
const AUTO_DISMISS_MS = {
|
|
6
4
|
success: 5000,
|
|
7
5
|
info: 5000,
|
|
@@ -15,7 +13,7 @@ class Logger {
|
|
|
15
13
|
setLines;
|
|
16
14
|
dismissTimers = new Map();
|
|
17
15
|
constructor() {
|
|
18
|
-
[this.lines, this.setLines] =
|
|
16
|
+
[this.lines, this.setLines] = Whispr.create([]);
|
|
19
17
|
if (typeof window !== "undefined") {
|
|
20
18
|
window.addEventListener("unhandledrejection", (e) => this.log(e.reason, "error"));
|
|
21
19
|
window.addEventListener("error", (e) => this.logError(this.reconstructError(e)));
|
|
@@ -51,7 +49,7 @@ class Logger {
|
|
|
51
49
|
this.setLines(this.lines.value.filter((i) => i.id !== id));
|
|
52
50
|
}
|
|
53
51
|
log(message, severity = "info", context) {
|
|
54
|
-
const id =
|
|
52
|
+
const id = getRandomId();
|
|
55
53
|
const item = {
|
|
56
54
|
id,
|
|
57
55
|
date: new Date(),
|
|
@@ -76,4 +74,4 @@ class Logger {
|
|
|
76
74
|
return this.log("Unknown error - See Console", "error");
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
|
-
|
|
77
|
+
export default Logger.getInstance();
|
package/dist/Searcher/index.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Searcher = void 0;
|
|
4
|
-
class Searcher {
|
|
1
|
+
export class Searcher {
|
|
5
2
|
data = [];
|
|
6
3
|
constructor(data) {
|
|
7
4
|
this.data = data;
|
|
@@ -20,7 +17,6 @@ class Searcher {
|
|
|
20
17
|
}));
|
|
21
18
|
}
|
|
22
19
|
}
|
|
23
|
-
exports.Searcher = Searcher;
|
|
24
20
|
// export function useSearcher_w<T>(data: Whispr<SearcherData<T>[]>, query: Whispr<string>): Whispr<SearcherData<T>[]> {
|
|
25
21
|
// const searcher = new Searcher<T>(data.value);
|
|
26
22
|
// let unsubscribe_q: () => void = () => { }
|