Skip to content

Commit 6bc7cdc

Browse files
committed
Convert to typescript; Update naming to follow rxfire; Support sub modules
1 parent e9f1711 commit 6bc7cdc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+667
-16712
lines changed

.babelrc.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

.eslintrc

Lines changed: 0 additions & 32 deletions
This file was deleted.

.flowconfig

Lines changed: 0 additions & 13 deletions
This file was deleted.

.gitignore

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# NPM / Yarn
2+
.rpt2_cache
23
node_modules
34
npm-debug.log
45

5-
# Build output
6-
dist
7-
lib
8-
es
6+
# Rollup build output
7+
**/dist
8+
**/*.d.ts
99

1010
# OS files
1111
.DS_Store

auth/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as useAuthState, AuthStateHook } from './useAuthState';

auth/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "react-firebase-hooks/auth",
3+
"main": "dist/index.cjs.js",
4+
"module": "dist/index.esm.js",
5+
"typings": "dist/auth/index.d.ts"
6+
}

auth/useAuthState.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { auth, User } from 'firebase';
2+
import { useEffect } from 'react';
3+
import { useDataLoader } from '../util';
4+
5+
export type AuthStateHook = {
6+
user?: firebase.User;
7+
initialising: boolean;
8+
};
9+
10+
export default (auth: auth.Auth): AuthStateHook => {
11+
const { loading, setValue, value } = useDataLoader<User>();
12+
13+
useEffect(() => {
14+
const listener = auth.onAuthStateChanged(setValue);
15+
16+
return () => {
17+
listener();
18+
};
19+
}, []);
20+
21+
return {
22+
initialising: loading,
23+
user: value,
24+
};
25+
};

database/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default as useList, ListHook } from './useList';
2+
export { default as useObject, ObjectHook } from './useObject';

database/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "react-firebase-hooks/database",
3+
"main": "dist/index.cjs.js",
4+
"module": "dist/index.esm.js",
5+
"typings": "dist/database/index.d.ts"
6+
}

database/useList.ts

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { database } from 'firebase';
2+
import { useEffect, useState } from 'react';
3+
4+
export type ListHook = {
5+
error?: Object;
6+
list: database.DataSnapshot[];
7+
loading: boolean;
8+
};
9+
10+
type KeyValueState = {
11+
keys: string[];
12+
values: database.DataSnapshot[];
13+
};
14+
15+
export default (query: database.Query): ListHook => {
16+
const [error, setError] = useState(false);
17+
const [loading, setLoading] = useState(true);
18+
// Combine keys and values in a single state hook to allow them to be manipulated together
19+
const [{ values }, setKeysValues] = useState({ keys: [], values: [] });
20+
21+
const onChildAdded = (
22+
snapshot: database.DataSnapshot | null,
23+
previousKey?: string | null
24+
) => {
25+
setKeysValues((prevKeyValueState: KeyValueState) => {
26+
return snapshot
27+
? addChild(prevKeyValueState, snapshot, previousKey)
28+
: prevKeyValueState;
29+
});
30+
};
31+
32+
const onChildChanged = (snapshot: database.DataSnapshot | null) => {
33+
setKeysValues((prevKeyValueState: KeyValueState) => {
34+
if (!snapshot || !snapshot.key) {
35+
return prevKeyValueState;
36+
}
37+
38+
const index = prevKeyValueState.keys.indexOf(snapshot.key);
39+
return {
40+
...prevKeyValueState,
41+
values: [
42+
...prevKeyValueState.values.slice(0, index),
43+
snapshot,
44+
...prevKeyValueState.values.slice(index + 1),
45+
],
46+
};
47+
});
48+
};
49+
50+
const onChildMoved = (
51+
snapshot: database.DataSnapshot | null,
52+
previousKey?: string | null
53+
) => {
54+
setKeysValues((prevKeyValueState: KeyValueState) => {
55+
if (!snapshot) {
56+
return prevKeyValueState;
57+
}
58+
// Remove the child from it's previous location
59+
const tempKeyValueState = removeChild(prevKeyValueState, snapshot);
60+
// Add the child into it's new location
61+
return addChild(tempKeyValueState, snapshot, previousKey);
62+
});
63+
};
64+
65+
const onChildRemoved = (snapshot: database.DataSnapshot | null) => {
66+
setKeysValues((prevKeyValueState: KeyValueState) => {
67+
return snapshot
68+
? removeChild(prevKeyValueState, snapshot)
69+
: prevKeyValueState;
70+
});
71+
};
72+
73+
useEffect(
74+
() => {
75+
// This is here to indicate that all the data has been successfully received
76+
query.once(
77+
'value',
78+
() => {
79+
setLoading(false);
80+
},
81+
(err: object) => {
82+
setError(err);
83+
setLoading(false);
84+
}
85+
);
86+
query.on('child_added', onChildAdded);
87+
query.on('child_changed', onChildChanged);
88+
query.on('child_moved', onChildMoved);
89+
query.on('child_removed', onChildRemoved);
90+
91+
return () => {
92+
query.off('child_added', onChildAdded);
93+
query.off('child_changed', onChildChanged);
94+
query.off('child_moved', onChildMoved);
95+
query.off('child_removed', onChildRemoved);
96+
};
97+
},
98+
// TODO: Check if this works suitably for 'query' parameters
99+
[query]
100+
);
101+
102+
return {
103+
error,
104+
list: values,
105+
loading,
106+
};
107+
};
108+
109+
const addChild = (
110+
keyValueState: KeyValueState,
111+
snapshot: firebase.database.DataSnapshot,
112+
previousKey?: string | null
113+
): KeyValueState => {
114+
if (!snapshot.key) {
115+
return keyValueState;
116+
}
117+
118+
const { keys, values } = keyValueState;
119+
if (!previousKey) {
120+
// The child has been added to the start of the list
121+
return {
122+
keys: [snapshot.key, ...keys],
123+
values: [snapshot, ...values],
124+
};
125+
}
126+
// Establish the index for the previous child in the list
127+
const index = keys.indexOf(previousKey);
128+
// Insert the item after the previous child
129+
return {
130+
keys: [...keys.slice(0, index + 1), snapshot.key, ...keys.slice(index + 1)],
131+
values: [
132+
...values.slice(0, index + 1),
133+
snapshot,
134+
...values.slice(index + 1),
135+
],
136+
};
137+
};
138+
139+
const removeChild = (
140+
keyValueState: KeyValueState,
141+
snapshot: firebase.database.DataSnapshot
142+
): KeyValueState => {
143+
if (!snapshot.key) {
144+
return keyValueState;
145+
}
146+
147+
const { keys, values } = keyValueState;
148+
const index = keys.indexOf(snapshot.key);
149+
return {
150+
keys: [...keys.slice(0, index), ...keys.slice(index + 1)],
151+
values: [...values.slice(0, index), ...values.slice(index + 1)],
152+
};
153+
};

0 commit comments

Comments
 (0)