@cripty2001/utils 0.0.6 → 0.0.7
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/Dispatcher.d.ts +36 -0
- package/{src/Dispatcher.ts → dist/Dispatcher.js} +123 -163
- package/dist/index.d.ts +11 -0
- package/dist/index.js +59 -0
- package/dist/react-whispr.d.ts +26 -0
- package/{src/react-whispr.ts → dist/react-whispr.js} +52 -69
- package/package.json +4 -1
- package/src/index.ts +0 -73
- package/tsconfig.json +0 -14
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Whispr } from "@cripty2001/whispr";
|
|
2
|
+
export type DispatcherStatePayload<T> = {
|
|
3
|
+
loading: true;
|
|
4
|
+
progress: number;
|
|
5
|
+
} | ({
|
|
6
|
+
loading: false;
|
|
7
|
+
} & ({
|
|
8
|
+
ok: true;
|
|
9
|
+
data: T;
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
error: Error;
|
|
13
|
+
}));
|
|
14
|
+
type DispatcherFunction<I, O> = (data: I, setProgress: (p: number) => void, signal: AbortSignal) => Promise<O>;
|
|
15
|
+
export declare class Dispatcher<I, O> {
|
|
16
|
+
private state;
|
|
17
|
+
private setState;
|
|
18
|
+
data: Whispr<DispatcherStatePayload<O>>;
|
|
19
|
+
filtered: Whispr<O | null>;
|
|
20
|
+
readonly DEBOUNCE_INTERVAL: number;
|
|
21
|
+
private readonly f;
|
|
22
|
+
private value;
|
|
23
|
+
private lastValue;
|
|
24
|
+
/**
|
|
25
|
+
* Create a new dispatcher
|
|
26
|
+
* @param value The whispr value that will trigger f call when changed. Using this pattern instead of exposing a dispatch method allow to return the full dispatcher to anyone, without having to worry about them messing it
|
|
27
|
+
* @param f The async function to call. It should return a promise that resolves to the data.
|
|
28
|
+
* @param DEBOUNCE_INTERVAL
|
|
29
|
+
*
|
|
30
|
+
* @remarks The value is deep checked for equality. The function will be called only if the value changed deeply
|
|
31
|
+
*/
|
|
32
|
+
constructor(value: Whispr<I>, f: DispatcherFunction<I, O>, DEBOUNCE_INTERVAL?: number);
|
|
33
|
+
private reset;
|
|
34
|
+
private dispatch;
|
|
35
|
+
}
|
|
36
|
+
export {};
|
|
@@ -1,163 +1,123 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
raise: (error: Error) => {
|
|
126
|
-
updateState({
|
|
127
|
-
loading: false,
|
|
128
|
-
ok: false,
|
|
129
|
-
error,
|
|
130
|
-
});
|
|
131
|
-
},
|
|
132
|
-
progress: (p: number) => {
|
|
133
|
-
updateState({
|
|
134
|
-
loading: true,
|
|
135
|
-
progress: p,
|
|
136
|
-
});
|
|
137
|
-
},
|
|
138
|
-
controller
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
private dispatch(data: I): Promise<void> {
|
|
143
|
-
const signals = this.reset();
|
|
144
|
-
|
|
145
|
-
const toReturn = (async () => {
|
|
146
|
-
// Debouncing rapid changes
|
|
147
|
-
await sleep(this.DEBOUNCE_INTERVAL);
|
|
148
|
-
if (signals.controller.signal.aborted)
|
|
149
|
-
throw new DOMException('Debounced', 'AbortError');
|
|
150
|
-
|
|
151
|
-
// Scheduling function execution
|
|
152
|
-
return await this.f(data, signals.progress, signals.controller.signal)
|
|
153
|
-
})()
|
|
154
|
-
.then((res) => {
|
|
155
|
-
signals.commit(res);
|
|
156
|
-
})
|
|
157
|
-
.catch((e) => {
|
|
158
|
-
signals.raise(e instanceof Error ? e : new Error(JSON.stringify(e)));
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
return toReturn;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Dispatcher = void 0;
|
|
4
|
+
const whispr_1 = require("@cripty2001/whispr");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
7
|
+
class Dispatcher {
|
|
8
|
+
state;
|
|
9
|
+
setState;
|
|
10
|
+
data;
|
|
11
|
+
filtered;
|
|
12
|
+
DEBOUNCE_INTERVAL;
|
|
13
|
+
f;
|
|
14
|
+
value; // Value is a whispr that we are subscribed to. We must keep a reference to it to avoid the subscription being automatically canceled
|
|
15
|
+
lastValue = null; // Last value, to avoid useless dispatches
|
|
16
|
+
/**
|
|
17
|
+
* Create a new dispatcher
|
|
18
|
+
* @param value The whispr value that will trigger f call when changed. Using this pattern instead of exposing a dispatch method allow to return the full dispatcher to anyone, without having to worry about them messing it
|
|
19
|
+
* @param f The async function to call. It should return a promise that resolves to the data.
|
|
20
|
+
* @param DEBOUNCE_INTERVAL
|
|
21
|
+
*
|
|
22
|
+
* @remarks The value is deep checked for equality. The function will be called only if the value changed deeply
|
|
23
|
+
*/
|
|
24
|
+
constructor(value, f, DEBOUNCE_INTERVAL = 200) {
|
|
25
|
+
// Initing state
|
|
26
|
+
this.f = f;
|
|
27
|
+
this.DEBOUNCE_INTERVAL = DEBOUNCE_INTERVAL;
|
|
28
|
+
this.value = value;
|
|
29
|
+
[this.state, this.setState] = whispr_1.Whispr.create({
|
|
30
|
+
controller: new AbortController(),
|
|
31
|
+
payload: {
|
|
32
|
+
loading: true,
|
|
33
|
+
progress: 0,
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
// Subscribing to input changes
|
|
37
|
+
this.value.subscribe((v) => {
|
|
38
|
+
if (this.lastValue !== null && (0, lodash_1.isEqual)(this.lastValue, v))
|
|
39
|
+
return;
|
|
40
|
+
this.lastValue = v;
|
|
41
|
+
this.dispatch(v);
|
|
42
|
+
});
|
|
43
|
+
// Initing public derived whisprs
|
|
44
|
+
this.data = whispr_1.Whispr
|
|
45
|
+
.from({ state: this.state }, ({ state }) => state.payload);
|
|
46
|
+
this.filtered = whispr_1.Whispr.from({
|
|
47
|
+
data: this.data
|
|
48
|
+
}, ({ data }) => {
|
|
49
|
+
if (data.loading)
|
|
50
|
+
return null;
|
|
51
|
+
if (!data.ok)
|
|
52
|
+
return null;
|
|
53
|
+
return data.data;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
reset() {
|
|
57
|
+
// Aborting previous request
|
|
58
|
+
this.state.value.controller.abort();
|
|
59
|
+
// Initing new abort controller
|
|
60
|
+
const controller = new AbortController();
|
|
61
|
+
// Resetting response state
|
|
62
|
+
this.setState({
|
|
63
|
+
controller,
|
|
64
|
+
payload: {
|
|
65
|
+
loading: true,
|
|
66
|
+
progress: 0,
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// Creating generic state update function
|
|
70
|
+
const updateState = (value) => {
|
|
71
|
+
if (controller.signal.aborted) // Working on local controller, not global one. Old controller will change and be aborted on reset, global one will always be running
|
|
72
|
+
return;
|
|
73
|
+
this.setState({
|
|
74
|
+
controller: this.state.value.controller, // Keeping the effective controller, not the internal old one (even if, in practice, they should be the same, if everything worked well),
|
|
75
|
+
payload: value,
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
// Returning state update function
|
|
79
|
+
return {
|
|
80
|
+
commit: (data) => {
|
|
81
|
+
updateState({
|
|
82
|
+
loading: false,
|
|
83
|
+
ok: true,
|
|
84
|
+
data,
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
raise: (error) => {
|
|
88
|
+
updateState({
|
|
89
|
+
loading: false,
|
|
90
|
+
ok: false,
|
|
91
|
+
error,
|
|
92
|
+
});
|
|
93
|
+
},
|
|
94
|
+
progress: (p) => {
|
|
95
|
+
updateState({
|
|
96
|
+
loading: true,
|
|
97
|
+
progress: p,
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
controller
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
;
|
|
104
|
+
dispatch(data) {
|
|
105
|
+
const signals = this.reset();
|
|
106
|
+
const toReturn = (async () => {
|
|
107
|
+
// Debouncing rapid changes
|
|
108
|
+
await (0, _1.sleep)(this.DEBOUNCE_INTERVAL);
|
|
109
|
+
if (signals.controller.signal.aborted)
|
|
110
|
+
throw new DOMException('Debounced', 'AbortError');
|
|
111
|
+
// Scheduling function execution
|
|
112
|
+
return await this.f(data, signals.progress, signals.controller.signal);
|
|
113
|
+
})()
|
|
114
|
+
.then((res) => {
|
|
115
|
+
signals.commit(res);
|
|
116
|
+
})
|
|
117
|
+
.catch((e) => {
|
|
118
|
+
signals.raise(e instanceof Error ? e : new Error(JSON.stringify(e)));
|
|
119
|
+
});
|
|
120
|
+
return toReturn;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
exports.Dispatcher = Dispatcher;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type JSONEncodable = number | string | boolean | JSONEncodable[] | {
|
|
2
|
+
[key: string]: JSONEncodable;
|
|
3
|
+
};
|
|
4
|
+
export type TypeofArray<T extends any[]> = T extends (infer U)[] ? U : never;
|
|
5
|
+
export type TypeofRecord<T extends Record<string, any>> = T extends Record<string, infer U> ? U : never;
|
|
6
|
+
export declare function getRandom(_alphabeth: string, length: number): string;
|
|
7
|
+
export declare function getRandomId(length?: number): string;
|
|
8
|
+
export declare function getRandomOtp(length?: number, char?: boolean): string;
|
|
9
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
10
|
+
export declare function parseHash(fields: string[]): URLSearchParams;
|
|
11
|
+
export declare function loop(cb: () => Promise<void>, interval: number, onError?: (e: any) => Promise<void>): Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRandom = getRandom;
|
|
4
|
+
exports.getRandomId = getRandomId;
|
|
5
|
+
exports.getRandomOtp = getRandomOtp;
|
|
6
|
+
exports.sleep = sleep;
|
|
7
|
+
exports.parseHash = parseHash;
|
|
8
|
+
exports.loop = loop;
|
|
9
|
+
function getRandom(_alphabeth, length) {
|
|
10
|
+
const alphabeth = _alphabeth.split("");
|
|
11
|
+
const toReturn = [];
|
|
12
|
+
while (toReturn.length < length) {
|
|
13
|
+
toReturn.push(alphabeth[Math.floor(Math.random() * alphabeth.length)]);
|
|
14
|
+
}
|
|
15
|
+
return toReturn.join("");
|
|
16
|
+
}
|
|
17
|
+
function getRandomId(length = 20) {
|
|
18
|
+
const ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
19
|
+
return getRandom(ALPHABET, length);
|
|
20
|
+
}
|
|
21
|
+
function getRandomOtp(length = 6, char = false) {
|
|
22
|
+
const ALPHABET = "0123456789" + (char ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "");
|
|
23
|
+
return getRandom(ALPHABET, length);
|
|
24
|
+
}
|
|
25
|
+
function sleep(ms) {
|
|
26
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
27
|
+
}
|
|
28
|
+
function parseHash(fields) {
|
|
29
|
+
// Checking empty hash
|
|
30
|
+
if (window.location.hash === "")
|
|
31
|
+
return new URLSearchParams();
|
|
32
|
+
// Parsing hash
|
|
33
|
+
const data = new URLSearchParams(window.location.hash.replace(/^#/, "?"));
|
|
34
|
+
// Extracting fields
|
|
35
|
+
const toReturn = new URLSearchParams();
|
|
36
|
+
for (const field of fields) {
|
|
37
|
+
if (data.has(field)) {
|
|
38
|
+
toReturn.set(field, data.get(field));
|
|
39
|
+
data.delete(field);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Reencoding hash without extracted fields
|
|
43
|
+
window.location.hash = `#${data.toString()}`;
|
|
44
|
+
// Returning extracted fields
|
|
45
|
+
return toReturn;
|
|
46
|
+
}
|
|
47
|
+
async function loop(cb, interval, onError = async (e) => { console.error(e); }) {
|
|
48
|
+
while (true) {
|
|
49
|
+
try {
|
|
50
|
+
await cb();
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
await onError(e);
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
await sleep(interval);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Whispr } from "@cripty2001/whispr";
|
|
2
|
+
/**
|
|
3
|
+
* Convert a Whispr value into a reactive react value, usable in function components with the standard react reactive system.
|
|
4
|
+
* If the value is not a Whispr, it is returned as is, thus allowing for progressive migration and adoption
|
|
5
|
+
* @param w A reactive react value or a Whispr containing it
|
|
6
|
+
* @param computer An optional function to compute the returned value. This is useful to extract a part of a larger whispr, or to compute a derived value. It is the analog of useMemo with a single dependency (the whispr itself)
|
|
7
|
+
* @returns A reactive react value
|
|
8
|
+
*
|
|
9
|
+
* @remarks The value is NOT REACTIVE, and the same applies to the computer, if any. Only changes to its content will trigger a change, not changes to the object itself.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* export default function MyComponent(props: { value: Whispr<string> }) {
|
|
13
|
+
* const value = useWhisprValue(props.value);
|
|
14
|
+
*
|
|
15
|
+
* return <div>{value}</div>;
|
|
16
|
+
* }
|
|
17
|
+
*/
|
|
18
|
+
export declare function useWhisprValue<I, O = I>(w: Whispr<I>, computer?: (data: I) => O): O;
|
|
19
|
+
/**
|
|
20
|
+
* Wrap a (react) value into a Whispr, if it is not one already.
|
|
21
|
+
* @param data A Whispr or a normal (react reactable) value
|
|
22
|
+
* @returns The whispr'd value, or the original whispr if it was one (allow for incremental adoption)
|
|
23
|
+
*
|
|
24
|
+
* @remarks The returned whispr has already been ref-fed, so it can be directly used without worrying about react recreating it or similar bad things
|
|
25
|
+
*/
|
|
26
|
+
export declare function useWhispr<T>(data: T | Whispr<T>): Whispr<T>;
|
|
@@ -1,69 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* @
|
|
12
|
-
*
|
|
13
|
-
* @
|
|
14
|
-
*
|
|
15
|
-
* @
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
)
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
)
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const [w, setW] = useRef(Whispr.create(
|
|
54
|
-
data instanceof Whispr ?
|
|
55
|
-
data.value :
|
|
56
|
-
data
|
|
57
|
-
)).current;
|
|
58
|
-
|
|
59
|
-
useEffect(() => {
|
|
60
|
-
setW(data instanceof Whispr ? data.value : data);
|
|
61
|
-
}, [data, setW]);
|
|
62
|
-
|
|
63
|
-
// Hooks can't be called conditionally, so we need to do this check at the end
|
|
64
|
-
if (data instanceof Whispr)
|
|
65
|
-
return data;
|
|
66
|
-
|
|
67
|
-
return w;
|
|
68
|
-
}
|
|
69
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useWhisprValue = useWhisprValue;
|
|
4
|
+
exports.useWhispr = useWhispr;
|
|
5
|
+
const whispr_1 = require("@cripty2001/whispr");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const lodash_1 = require("lodash");
|
|
8
|
+
/**
|
|
9
|
+
* Convert a Whispr value into a reactive react value, usable in function components with the standard react reactive system.
|
|
10
|
+
* If the value is not a Whispr, it is returned as is, thus allowing for progressive migration and adoption
|
|
11
|
+
* @param w A reactive react value or a Whispr containing it
|
|
12
|
+
* @param computer An optional function to compute the returned value. This is useful to extract a part of a larger whispr, or to compute a derived value. It is the analog of useMemo with a single dependency (the whispr itself)
|
|
13
|
+
* @returns A reactive react value
|
|
14
|
+
*
|
|
15
|
+
* @remarks The value is NOT REACTIVE, and the same applies to the computer, if any. Only changes to its content will trigger a change, not changes to the object itself.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* export default function MyComponent(props: { value: Whispr<string> }) {
|
|
19
|
+
* const value = useWhisprValue(props.value);
|
|
20
|
+
*
|
|
21
|
+
* return <div>{value}</div>;
|
|
22
|
+
* }
|
|
23
|
+
*/
|
|
24
|
+
function useWhisprValue(w, computer = (d) => d) {
|
|
25
|
+
const value_w = (0, react_1.useRef)(whispr_1.Whispr.from({ w }, ({ w }) => computer(w))).current;
|
|
26
|
+
const [value, setValue] = (0, react_1.useState)(value_w.value);
|
|
27
|
+
value_w.subscribe((newValue) => {
|
|
28
|
+
if ((0, lodash_1.isEqual)(newValue, value))
|
|
29
|
+
return;
|
|
30
|
+
setValue(newValue);
|
|
31
|
+
}, false); // Already got the initial value, and this will call syncronously generate a react warning as called on an not yet mounted component
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Wrap a (react) value into a Whispr, if it is not one already.
|
|
36
|
+
* @param data A Whispr or a normal (react reactable) value
|
|
37
|
+
* @returns The whispr'd value, or the original whispr if it was one (allow for incremental adoption)
|
|
38
|
+
*
|
|
39
|
+
* @remarks The returned whispr has already been ref-fed, so it can be directly used without worrying about react recreating it or similar bad things
|
|
40
|
+
*/
|
|
41
|
+
function useWhispr(data) {
|
|
42
|
+
const [w, setW] = (0, react_1.useRef)(whispr_1.Whispr.create(data instanceof whispr_1.Whispr ?
|
|
43
|
+
data.value :
|
|
44
|
+
data)).current;
|
|
45
|
+
(0, react_1.useEffect)(() => {
|
|
46
|
+
setW(data instanceof whispr_1.Whispr ? data.value : data);
|
|
47
|
+
}, [data, setW]);
|
|
48
|
+
// Hooks can't be called conditionally, so we need to do this check at the end
|
|
49
|
+
if (data instanceof whispr_1.Whispr)
|
|
50
|
+
return data;
|
|
51
|
+
return w;
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cripty2001/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Internal Set of utils. If you need them use them, otherwise go to the next package ;)",
|
|
5
5
|
"homepage": "https://github.com/cripty2001/utils#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
19
19
|
"build": "tsc"
|
|
20
20
|
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
21
24
|
"devDependencies": {
|
|
22
25
|
"@types/react": "^19.1.8",
|
|
23
26
|
"react": "^19.1.8",
|
package/src/index.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
export type JSONEncodable = number | string | boolean | JSONEncodable[] | { [key: string]: JSONEncodable };
|
|
2
|
-
|
|
3
|
-
export type TypeofArray<T extends any[]> = T extends (infer U)[] ? U : never;
|
|
4
|
-
export type TypeofRecord<T extends Record<string, any>> = T extends Record<
|
|
5
|
-
string,
|
|
6
|
-
infer U
|
|
7
|
-
>
|
|
8
|
-
? U
|
|
9
|
-
: never;
|
|
10
|
-
|
|
11
|
-
export function getRandom(_alphabeth: string, length: number): string {
|
|
12
|
-
const alphabeth = _alphabeth.split("");
|
|
13
|
-
const toReturn: string[] = [];
|
|
14
|
-
while (toReturn.length < length) {
|
|
15
|
-
toReturn.push(alphabeth[Math.floor(Math.random() * alphabeth.length)]);
|
|
16
|
-
}
|
|
17
|
-
return toReturn.join("");
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getRandomId(length: number = 20): string {
|
|
21
|
-
const ALPHABET =
|
|
22
|
-
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
23
|
-
return getRandom(ALPHABET, length);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getRandomOtp(
|
|
27
|
-
length: number = 6,
|
|
28
|
-
char: boolean = false
|
|
29
|
-
): string {
|
|
30
|
-
const ALPHABET = "0123456789" + (char ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : "");
|
|
31
|
-
return getRandom(ALPHABET, length);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function sleep(ms: number): Promise<void> {
|
|
35
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function parseHash(fields: string[]): URLSearchParams {
|
|
39
|
-
// Checking empty hash
|
|
40
|
-
if (window.location.hash === "") return new URLSearchParams();
|
|
41
|
-
|
|
42
|
-
// Parsing hash
|
|
43
|
-
const data = new URLSearchParams(window.location.hash.replace(/^#/, "?"));
|
|
44
|
-
|
|
45
|
-
// Extracting fields
|
|
46
|
-
const toReturn: URLSearchParams = new URLSearchParams();
|
|
47
|
-
for (const field of fields) {
|
|
48
|
-
if (data.has(field)) {
|
|
49
|
-
toReturn.set(field, data.get(field) as string);
|
|
50
|
-
data.delete(field);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Reencoding hash without extracted fields
|
|
55
|
-
window.location.hash = `#${data.toString()}`;
|
|
56
|
-
|
|
57
|
-
// Returning extracted fields
|
|
58
|
-
return toReturn;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export async function loop(cb: () => Promise<void>, interval: number, onError: (e: any) => Promise<void> = async (e) => { console.error(e) }): Promise<void> {
|
|
62
|
-
while (true) {
|
|
63
|
-
try {
|
|
64
|
-
await cb();
|
|
65
|
-
} catch (e) {
|
|
66
|
-
await onError(e);
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
await sleep(interval);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
package/tsconfig.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ESNext",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"rootDir": "./src",
|
|
6
|
-
"moduleResolution": "NodeNext",
|
|
7
|
-
"declaration": true,
|
|
8
|
-
"outDir": "./dist",
|
|
9
|
-
"esModuleInterop": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"strict": true,
|
|
12
|
-
"skipLibCheck": true
|
|
13
|
-
}
|
|
14
|
-
}
|