-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathutils.ts
85 lines (78 loc) · 2.08 KB
/
utils.ts
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
import type { Path } from "@textea/json-viewer";
import * as Y from "yjs";
const decoders = [
{
name: "binary update",
decode: async (file: File) => {
return new Uint8Array(await file.arrayBuffer());
},
},
{
name: "binary string",
decode: async (file: File) => {
const text = await file.text();
// Parse binary string
// `Buffer.from(encodeUpdate).toString("binary")`
return Uint8Array.from(text, (c) => c.charCodeAt(0));
},
},
// TODO handle base64 encoding
// https://docs.yjs.dev/api/document-updates#example-base64-encoding
];
export async function fileToYDoc(file: File) {
for (const decoder of decoders) {
try {
const yDocUpdate = await decoder.decode(file);
const newYDoc = new Y.Doc();
Y.applyUpdate(newYDoc, yDocUpdate);
Y.logUpdate(yDocUpdate);
return newYDoc;
} catch (error) {
console.warn(`Failed to decode ${decoder.name}`, error);
}
}
throw new Error("Failed to decode file");
}
export function getPathValue<T = object, R = object>(
obj: T,
path: Path,
getter: (obj: T, key: string | number) => unknown = (obj, key) =>
(obj as any)[key],
) {
return path.reduce(
(acc, key) => getter(acc, key) as any,
obj,
) as unknown as R;
}
export const and =
<T extends (...args: any[]) => boolean>(...fnArray: NoInfer<T>[]) =>
(...args: Parameters<T>) =>
fnArray.every((fn) => fn(...args));
export const or =
<T extends (...args: any[]) => boolean>(...fnArray: NoInfer<T>[]) =>
(...args: Parameters<T>) =>
fnArray.some((fn) => fn(...args));
export function getHumanReadablePath(path: Path) {
return ["root", ...path].join(".");
}
/**
* This function should never be called. If it is called, it means that the
* code has reached a point that should be unreachable.
*
* @example
* ```ts
* function f(val: 'a' | 'b') {
* if (val === 'a') {
* return 1;
* } else if (val === 'b') {
* return 2;
* }
* unreachable(val);
* ```
*/
export function unreachable(
_val: never,
message = "Unreachable code reached",
): never {
throw new Error(message);
}