|
1 |
| -import { atom, AtomEffect, atomFamily, RecoilState } from "recoil"; |
| 1 | +import { |
| 2 | + atom, |
| 3 | + AtomEffect, |
| 4 | + atomFamily, |
| 5 | + RecoilState, |
| 6 | + type SerializableParam, |
| 7 | +} from "recoil"; |
2 | 8 | import { Database, DataSnapshot, ref, onValue, get } from "firebase/database";
|
3 | 9 | import { interpolatePathSpec, PathParameters } from "./interpolatePathSpec";
|
4 | 10 | import type { FirebaseArray } from "../firebase/types";
|
@@ -36,13 +42,86 @@ export function makeAtom<T extends FirebaseValue>(
|
36 | 42 | });
|
37 | 43 | }
|
38 | 44 |
|
| 45 | +type PP<K extends string> = { |
| 46 | + [Property in K]: string; |
| 47 | +}; |
| 48 | + |
| 49 | +function test<T extends string>(pathSpec: string, args: PP<T>): string { |
| 50 | + return "hi"; |
| 51 | +} |
| 52 | + |
| 53 | +const x = test<"key1" | "key2">("ok", { key1: "hi", key2: "hi" }); |
| 54 | + |
| 55 | +type IsParameter<Part> = Part extends `{${infer ParamName}}` |
| 56 | + ? ParamName |
| 57 | + : never; |
| 58 | +type FilteredParts<Path> = Path extends `${infer PartA}/${infer PartB}` |
| 59 | + ? IsParameter<PartA> | FilteredParts<PartB> |
| 60 | + : IsParameter<Path>; |
| 61 | +type ParamValue<Key> = Key extends `...${infer Anything}` ? string[] : string; |
| 62 | +type RemovePrefixDots<Key> = Key extends `...${infer Name}` ? Name : Key; |
| 63 | +type Params<Path> = { |
| 64 | + [Key in FilteredParts<Path> as RemovePrefixDots<Key>]: ParamValue<Key>; |
| 65 | +}; |
| 66 | +type CallbackFn<Path> = (req: { params: Params<Path> }) => void; |
| 67 | + |
| 68 | +function get2<Path extends string = string>( |
| 69 | + path: Path, |
| 70 | + callback: CallbackFn<Path> |
| 71 | +) { |
| 72 | + // TODO: implement |
| 73 | +} |
| 74 | + |
| 75 | +function make2<Path extends string = string>(path: Path): CallbackFn<Path> { |
| 76 | + return (req) => {}; |
| 77 | +} |
| 78 | + |
| 79 | +const makeCallback = make2("/hi/{there}/cool")({ params: { there: "hi" } }); |
| 80 | + |
| 81 | +get2("hi/{there}/cool", ({ params: { there } }) => {}); |
| 82 | + |
| 83 | +const db: Database = {}; |
| 84 | + |
| 85 | +const af = makeAtomFamily("/hi/{there}/cool", db); |
| 86 | +af({ there: "ok" }); |
| 87 | +af({ shouldFail: "ok" }); |
| 88 | + |
| 89 | +//https://github.com/microsoft/TypeScript/pull/26349 |
| 90 | +const af2 = makeAtomFamily<number>("/hi/{there}/cool", db); |
| 91 | +af2({ there: "ok" }); |
| 92 | +af2({ shouldFail: "ok" }); |
| 93 | + |
| 94 | +function omg<T extends string, N extends number>(t: T, n: N): { x: T; y: N } { |
| 95 | + return { x: t, y: n }; |
| 96 | +} |
| 97 | + |
| 98 | +omg("cool", 3); |
| 99 | +// omg<string>("ok", 2); |
| 100 | + |
| 101 | +export function makeAtomFamilyMaker<T extends FirebaseValue>( |
| 102 | + database: Database |
| 103 | +): <Path extends string>( |
| 104 | + pathSpec: Path, |
| 105 | + database: Database |
| 106 | +) => (pathSpec: Path) => RecoilState<T> { |
| 107 | + return (pathSpec) => makeAtomFamily(pathSpec, database); |
| 108 | +} |
| 109 | + |
| 110 | +type KnownPathSpecAtomMaker<T extends FirebaseValue> = <T>() => RecoilState<T>; |
| 111 | + |
| 112 | +export function otherWay<Path extends string>( |
| 113 | + pathSpec: Path, |
| 114 | + database: Database |
| 115 | +): KnownPathSpecAtomMaker<T> {} |
| 116 | + |
39 | 117 | export function makeAtomFamily<
|
40 | 118 | T extends FirebaseValue,
|
41 |
| - P extends PathParameters |
42 |
| ->(pathSpec: string, database: Database): (param: P) => RecoilState<T> { |
| 119 | + Path extends string |
| 120 | + // P extends Params<Path> & SerializableParam = Params<Path> |
| 121 | +>(pathSpec: Path, database: Database): (param: Params<Path>) => RecoilState<T> { |
43 | 122 | // TODO if we have some unique id for the app, we can include in the key
|
44 | 123 | // and support multiple firebase connections
|
45 |
| - return atomFamily<T, P>({ |
| 124 | + return atomFamily<T, Params<Path>>({ |
46 | 125 | key: `firebase-recoil:${pathSpec}`,
|
47 | 126 | effects: (params) => [
|
48 | 127 | // TODO what would happen if we threw an exception here?
|
|
0 commit comments