react-firebase-ql 4.1.7 → 4.2.0
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/client/useCountdown.hooks.d.ts +4 -0
- package/dist/client/useCountdown.hooks.js +37 -0
- package/dist/client/useCountdown.hooks.js.map +1 -0
- package/esm/client/useCountdown.hooks.js +33 -0
- package/esm/client/useCountdown.hooks.js.map +1 -0
- package/package.json +1 -1
- package/src/client/AuthProvider.provider.tsx +96 -96
- package/src/client/useAuth.ts +13 -13
- package/src/client/useCountdown.hooks.tsx +42 -0
- package/src/client/useCounter.ts +38 -38
- package/src/client/useFetch.ts +57 -57
- package/src/client/useStream.ts +74 -74
- package/src/index.ts +5 -5
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useCountdown = void 0;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const useCountdown = (key) => {
|
|
7
|
+
const [remaining, setRemaining] = (0, react_1.useState)(0);
|
|
8
|
+
const [endTime, setEndTime] = (0, react_1.useState)(null);
|
|
9
|
+
(0, react_1.useEffect)(() => {
|
|
10
|
+
if (typeof window === 'undefined')
|
|
11
|
+
return;
|
|
12
|
+
const stored = window.localStorage.getItem(key);
|
|
13
|
+
setEndTime(stored ? Number(stored) : null);
|
|
14
|
+
}, [key]);
|
|
15
|
+
(0, react_1.useEffect)(() => {
|
|
16
|
+
if (!endTime) {
|
|
17
|
+
setRemaining(0);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const tick = () => {
|
|
21
|
+
const diff = Math.max(0, endTime - Date.now());
|
|
22
|
+
setRemaining(diff);
|
|
23
|
+
if (diff === 0) {
|
|
24
|
+
localStorage.removeItem(key);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
tick();
|
|
28
|
+
const interval = setInterval(tick, 1000);
|
|
29
|
+
return () => clearInterval(interval);
|
|
30
|
+
}, [endTime, key]);
|
|
31
|
+
return {
|
|
32
|
+
isActive: remaining > 0,
|
|
33
|
+
seconds: Math.ceil(remaining / 1000),
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
exports.useCountdown = useCountdown;
|
|
37
|
+
//# sourceMappingURL=useCountdown.hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCountdown.hooks.js","sourceRoot":"","sources":["../../src/client/useCountdown.hooks.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;AAEb,iCAA4C;AAErC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,EAAE;IAC1C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,IAAA,gBAAQ,EAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAgB,IAAI,CAAC,CAAC;IAG5D,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAE1C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,YAAY,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/C,YAAY,CAAC,IAAI,CAAC,CAAC;YAEnB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,EAAE,CAAC;QACP,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEzC,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAEnB,OAAO;QACL,QAAQ,EAAE,SAAS,GAAG,CAAC;QACvB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;KACrC,CAAC;AACJ,CAAC,CAAC;AArCW,QAAA,YAAY,gBAqCvB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
export const useCountdown = (key) => {
|
|
4
|
+
const [remaining, setRemaining] = useState(0);
|
|
5
|
+
const [endTime, setEndTime] = useState(null);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (typeof window === 'undefined')
|
|
8
|
+
return;
|
|
9
|
+
const stored = window.localStorage.getItem(key);
|
|
10
|
+
setEndTime(stored ? Number(stored) : null);
|
|
11
|
+
}, [key]);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (!endTime) {
|
|
14
|
+
setRemaining(0);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const tick = () => {
|
|
18
|
+
const diff = Math.max(0, endTime - Date.now());
|
|
19
|
+
setRemaining(diff);
|
|
20
|
+
if (diff === 0) {
|
|
21
|
+
localStorage.removeItem(key);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
tick();
|
|
25
|
+
const interval = setInterval(tick, 1000);
|
|
26
|
+
return () => clearInterval(interval);
|
|
27
|
+
}, [endTime, key]);
|
|
28
|
+
return {
|
|
29
|
+
isActive: remaining > 0,
|
|
30
|
+
seconds: Math.ceil(remaining / 1000),
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=useCountdown.hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCountdown.hooks.js","sourceRoot":"","sources":["../../src/client/useCountdown.hooks.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,EAAE;IAC1C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAG5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAE1C,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChD,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,YAAY,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC/C,YAAY,CAAC,IAAI,CAAC,CAAC;YAEnB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,EAAE,CAAC;QACP,MAAM,QAAQ,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEzC,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAEnB,OAAO;QACL,QAAQ,EAAE,SAAS,GAAG,CAAC;QACvB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;KACrC,CAAC;AACJ,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
Dispatch,
|
|
5
|
-
ReactNode,
|
|
6
|
-
useReducer,
|
|
7
|
-
Context,
|
|
8
|
-
createContext,
|
|
9
|
-
useEffect,
|
|
10
|
-
} from 'react';
|
|
11
|
-
|
|
12
|
-
import { Auth, onAuthStateChanged } from 'firebase/auth';
|
|
13
|
-
|
|
14
|
-
enum AUTHACTIONTYPE {
|
|
15
|
-
SETUID = "SETFBUSER",
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* AUTH state maintained accross
|
|
20
|
-
* all components
|
|
21
|
-
*/
|
|
22
|
-
interface AUTHSTATE {
|
|
23
|
-
UID?: string
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface AUTHACTION {
|
|
27
|
-
type: AUTHACTIONTYPE,
|
|
28
|
-
payload: string | undefined
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const initialAUTHState: AUTHSTATE = {}
|
|
33
|
-
|
|
34
|
-
const AUTHReducer = (state: AUTHSTATE, action: AUTHACTION): AUTHSTATE => {
|
|
35
|
-
switch (action.type) {
|
|
36
|
-
case AUTHACTIONTYPE.SETUID: {
|
|
37
|
-
const nextUser = action.payload;
|
|
38
|
-
|
|
39
|
-
if (state.UID === nextUser) {
|
|
40
|
-
return state;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
...state,
|
|
45
|
-
UID: nextUser,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
default:
|
|
50
|
-
return state;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const initialDispatch: Dispatch<AUTHACTION> = () => {};
|
|
57
|
-
|
|
58
|
-
export const AUTHContext: Context<AUTHSTATE> =
|
|
59
|
-
createContext(initialAUTHState);
|
|
60
|
-
|
|
61
|
-
const AUTHDispatch: Context<Dispatch<AUTHACTION>> =
|
|
62
|
-
createContext(initialDispatch);
|
|
63
|
-
|
|
64
|
-
type AUTHProviderProps = {
|
|
65
|
-
children: ReactNode;
|
|
66
|
-
auth: Auth;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
export const AUTHProvider = ({ children, auth }: AUTHProviderProps) => {
|
|
70
|
-
const [AUTHState, dispatch] = useReducer(
|
|
71
|
-
AUTHReducer,
|
|
72
|
-
initialAUTHState
|
|
73
|
-
);
|
|
74
|
-
|
|
75
|
-
useEffect(() => {
|
|
76
|
-
const unsubscribe = onAuthStateChanged(auth, (authUser) => {
|
|
77
|
-
|
|
78
|
-
if(!authUser) return;
|
|
79
|
-
|
|
80
|
-
dispatch({
|
|
81
|
-
type: AUTHACTIONTYPE.SETUID,
|
|
82
|
-
payload: authUser.uid ?? undefined,
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
return () => unsubscribe();
|
|
87
|
-
}, []);
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<AUTHContext.Provider value={AUTHState}>
|
|
91
|
-
<AUTHDispatch.Provider value={dispatch}>
|
|
92
|
-
{children}
|
|
93
|
-
</AUTHDispatch.Provider>
|
|
94
|
-
</AUTHContext.Provider>
|
|
95
|
-
);
|
|
96
|
-
};
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Dispatch,
|
|
5
|
+
ReactNode,
|
|
6
|
+
useReducer,
|
|
7
|
+
Context,
|
|
8
|
+
createContext,
|
|
9
|
+
useEffect,
|
|
10
|
+
} from 'react';
|
|
11
|
+
|
|
12
|
+
import { Auth, onAuthStateChanged } from 'firebase/auth';
|
|
13
|
+
|
|
14
|
+
enum AUTHACTIONTYPE {
|
|
15
|
+
SETUID = "SETFBUSER",
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* AUTH state maintained accross
|
|
20
|
+
* all components
|
|
21
|
+
*/
|
|
22
|
+
interface AUTHSTATE {
|
|
23
|
+
UID?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface AUTHACTION {
|
|
27
|
+
type: AUTHACTIONTYPE,
|
|
28
|
+
payload: string | undefined
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
const initialAUTHState: AUTHSTATE = {}
|
|
33
|
+
|
|
34
|
+
const AUTHReducer = (state: AUTHSTATE, action: AUTHACTION): AUTHSTATE => {
|
|
35
|
+
switch (action.type) {
|
|
36
|
+
case AUTHACTIONTYPE.SETUID: {
|
|
37
|
+
const nextUser = action.payload;
|
|
38
|
+
|
|
39
|
+
if (state.UID === nextUser) {
|
|
40
|
+
return state;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
...state,
|
|
45
|
+
UID: nextUser,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
default:
|
|
50
|
+
return state;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
const initialDispatch: Dispatch<AUTHACTION> = () => {};
|
|
57
|
+
|
|
58
|
+
export const AUTHContext: Context<AUTHSTATE> =
|
|
59
|
+
createContext(initialAUTHState);
|
|
60
|
+
|
|
61
|
+
const AUTHDispatch: Context<Dispatch<AUTHACTION>> =
|
|
62
|
+
createContext(initialDispatch);
|
|
63
|
+
|
|
64
|
+
type AUTHProviderProps = {
|
|
65
|
+
children: ReactNode;
|
|
66
|
+
auth: Auth;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const AUTHProvider = ({ children, auth }: AUTHProviderProps) => {
|
|
70
|
+
const [AUTHState, dispatch] = useReducer(
|
|
71
|
+
AUTHReducer,
|
|
72
|
+
initialAUTHState
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const unsubscribe = onAuthStateChanged(auth, (authUser) => {
|
|
77
|
+
|
|
78
|
+
if(!authUser) return;
|
|
79
|
+
|
|
80
|
+
dispatch({
|
|
81
|
+
type: AUTHACTIONTYPE.SETUID,
|
|
82
|
+
payload: authUser.uid ?? undefined,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return () => unsubscribe();
|
|
87
|
+
}, []);
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<AUTHContext.Provider value={AUTHState}>
|
|
91
|
+
<AUTHDispatch.Provider value={dispatch}>
|
|
92
|
+
{children}
|
|
93
|
+
</AUTHDispatch.Provider>
|
|
94
|
+
</AUTHContext.Provider>
|
|
95
|
+
);
|
|
96
|
+
};
|
package/src/client/useAuth.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { useEffect } from 'react';
|
|
3
|
-
import { Auth, onAuthStateChanged, User } from 'firebase/auth';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export function useAuth(auth: Auth, callback: (user: User | null)=>void) {
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
const unsubscribe = onAuthStateChanged(auth, async (authUser) => {
|
|
9
|
-
callback(authUser)
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
return () => unsubscribe();
|
|
13
|
-
}, []);
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { Auth, onAuthStateChanged, User } from 'firebase/auth';
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export function useAuth(auth: Auth, callback: (user: User | null)=>void) {
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
const unsubscribe = onAuthStateChanged(auth, async (authUser) => {
|
|
9
|
+
callback(authUser)
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return () => unsubscribe();
|
|
13
|
+
}, []);
|
|
14
14
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export const useCountdown = (key: string) => {
|
|
6
|
+
const [remaining, setRemaining] = useState(0);
|
|
7
|
+
const [endTime, setEndTime] = useState<number | null>(null);
|
|
8
|
+
|
|
9
|
+
// runs only on client after mount
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (typeof window === 'undefined') return;
|
|
12
|
+
|
|
13
|
+
const stored = window.localStorage.getItem(key);
|
|
14
|
+
setEndTime(stored ? Number(stored) : null);
|
|
15
|
+
}, [key]);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!endTime) {
|
|
19
|
+
setRemaining(0);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const tick = () => {
|
|
24
|
+
const diff = Math.max(0, endTime - Date.now());
|
|
25
|
+
setRemaining(diff);
|
|
26
|
+
|
|
27
|
+
if (diff === 0) {
|
|
28
|
+
localStorage.removeItem(key);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
tick();
|
|
33
|
+
const interval = setInterval(tick, 1000);
|
|
34
|
+
|
|
35
|
+
return () => clearInterval(interval);
|
|
36
|
+
}, [endTime, key]);
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
isActive: remaining > 0,
|
|
40
|
+
seconds: Math.ceil(remaining / 1000),
|
|
41
|
+
};
|
|
42
|
+
};
|
package/src/client/useCounter.ts
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { BaseModel, errorLogger, whereClause } from "firebase-client-ql";
|
|
4
|
-
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from "react"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// Count firestore data
|
|
8
|
-
export const useCount = <T extends BaseModel >(param: {
|
|
9
|
-
model: T | any,
|
|
10
|
-
where?: whereClause[],
|
|
11
|
-
}): [number, boolean, Dispatch<SetStateAction<boolean>>] => {
|
|
12
|
-
|
|
13
|
-
const [data, setData] = useState<number>(0);
|
|
14
|
-
const [loading, setLoading] = useState(true);
|
|
15
|
-
|
|
16
|
-
const fetcher = useCallback(async () => {
|
|
17
|
-
if ( !param.where) return;
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
const model = param.model;
|
|
21
|
-
const found = await model.countData(param.where)
|
|
22
|
-
setData(found);
|
|
23
|
-
} catch (error) {
|
|
24
|
-
errorLogger("useCount: ", error);
|
|
25
|
-
} finally {
|
|
26
|
-
setLoading(false);
|
|
27
|
-
}
|
|
28
|
-
}, [
|
|
29
|
-
JSON.stringify(param.where),
|
|
30
|
-
loading
|
|
31
|
-
]);
|
|
32
|
-
|
|
33
|
-
useEffect(() => {
|
|
34
|
-
fetcher();
|
|
35
|
-
}, [fetcher]);
|
|
36
|
-
|
|
37
|
-
return [data, loading, setLoading];
|
|
38
|
-
}
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { BaseModel, errorLogger, whereClause } from "firebase-client-ql";
|
|
4
|
+
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from "react"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// Count firestore data
|
|
8
|
+
export const useCount = <T extends BaseModel >(param: {
|
|
9
|
+
model: T | any,
|
|
10
|
+
where?: whereClause[],
|
|
11
|
+
}): [number, boolean, Dispatch<SetStateAction<boolean>>] => {
|
|
12
|
+
|
|
13
|
+
const [data, setData] = useState<number>(0);
|
|
14
|
+
const [loading, setLoading] = useState(true);
|
|
15
|
+
|
|
16
|
+
const fetcher = useCallback(async () => {
|
|
17
|
+
if ( !param.where) return;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const model = param.model;
|
|
21
|
+
const found = await model.countData(param.where)
|
|
22
|
+
setData(found);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
errorLogger("useCount: ", error);
|
|
25
|
+
} finally {
|
|
26
|
+
setLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}, [
|
|
29
|
+
JSON.stringify(param.where),
|
|
30
|
+
loading
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
fetcher();
|
|
35
|
+
}, [fetcher]);
|
|
36
|
+
|
|
37
|
+
return [data, loading, setLoading];
|
|
38
|
+
}
|
package/src/client/useFetch.ts
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { BaseModel, errorLogger, whereClause } from "firebase-client-ql"
|
|
4
|
-
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from "react"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// 👇 Hook is now generic
|
|
8
|
-
export const useFetch = <T extends BaseModel >(param: {
|
|
9
|
-
model: T | any
|
|
10
|
-
where?: whereClause[],
|
|
11
|
-
reference?: string,
|
|
12
|
-
filter?: {
|
|
13
|
-
orderBy?: { parameter: string, direction?: 'asc' | 'desc' };
|
|
14
|
-
offset?: string;
|
|
15
|
-
limit?: number;
|
|
16
|
-
}
|
|
17
|
-
}): [typeof param.model.data, boolean, Dispatch<SetStateAction<boolean>>] => {
|
|
18
|
-
|
|
19
|
-
const [data, setData] = useState<unknown>();
|
|
20
|
-
const [loading, setLoading] = useState(true);
|
|
21
|
-
|
|
22
|
-
const fetcher = useCallback(async () => {
|
|
23
|
-
if (!param.reference && !param.where) return;
|
|
24
|
-
|
|
25
|
-
try {
|
|
26
|
-
const model = param.model;
|
|
27
|
-
|
|
28
|
-
if (param.reference) {
|
|
29
|
-
const found = await model.find(param.reference);
|
|
30
|
-
if (found) setData(model.data);
|
|
31
|
-
} else if (param.where) {
|
|
32
|
-
const found = await model.findWhere({
|
|
33
|
-
wh: param.where,
|
|
34
|
-
lim: param.filter?.limit ?? 100,
|
|
35
|
-
order: param.filter?.orderBy,
|
|
36
|
-
offset: param.filter?.offset
|
|
37
|
-
});
|
|
38
|
-
setData(found);
|
|
39
|
-
}
|
|
40
|
-
} catch (error) {
|
|
41
|
-
errorLogger("useFetch: ", error);
|
|
42
|
-
} finally {
|
|
43
|
-
setLoading(false);
|
|
44
|
-
}
|
|
45
|
-
}, [
|
|
46
|
-
param.reference,
|
|
47
|
-
JSON.stringify(param.where),
|
|
48
|
-
JSON.stringify(param.filter),
|
|
49
|
-
loading
|
|
50
|
-
]);
|
|
51
|
-
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
fetcher();
|
|
54
|
-
}, [fetcher]);
|
|
55
|
-
|
|
56
|
-
return [data, loading, setLoading];
|
|
57
|
-
}
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { BaseModel, errorLogger, whereClause } from "firebase-client-ql"
|
|
4
|
+
import { Dispatch, SetStateAction, useCallback, useEffect, useState } from "react"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// 👇 Hook is now generic
|
|
8
|
+
export const useFetch = <T extends BaseModel >(param: {
|
|
9
|
+
model: T | any
|
|
10
|
+
where?: whereClause[],
|
|
11
|
+
reference?: string,
|
|
12
|
+
filter?: {
|
|
13
|
+
orderBy?: { parameter: string, direction?: 'asc' | 'desc' };
|
|
14
|
+
offset?: string;
|
|
15
|
+
limit?: number;
|
|
16
|
+
}
|
|
17
|
+
}): [typeof param.model.data, boolean, Dispatch<SetStateAction<boolean>>] => {
|
|
18
|
+
|
|
19
|
+
const [data, setData] = useState<unknown>();
|
|
20
|
+
const [loading, setLoading] = useState(true);
|
|
21
|
+
|
|
22
|
+
const fetcher = useCallback(async () => {
|
|
23
|
+
if (!param.reference && !param.where) return;
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const model = param.model;
|
|
27
|
+
|
|
28
|
+
if (param.reference) {
|
|
29
|
+
const found = await model.find(param.reference);
|
|
30
|
+
if (found) setData(model.data);
|
|
31
|
+
} else if (param.where) {
|
|
32
|
+
const found = await model.findWhere({
|
|
33
|
+
wh: param.where,
|
|
34
|
+
lim: param.filter?.limit ?? 100,
|
|
35
|
+
order: param.filter?.orderBy,
|
|
36
|
+
offset: param.filter?.offset
|
|
37
|
+
});
|
|
38
|
+
setData(found);
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
errorLogger("useFetch: ", error);
|
|
42
|
+
} finally {
|
|
43
|
+
setLoading(false);
|
|
44
|
+
}
|
|
45
|
+
}, [
|
|
46
|
+
param.reference,
|
|
47
|
+
JSON.stringify(param.where),
|
|
48
|
+
JSON.stringify(param.filter),
|
|
49
|
+
loading
|
|
50
|
+
]);
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
fetcher();
|
|
54
|
+
}, [fetcher]);
|
|
55
|
+
|
|
56
|
+
return [data, loading, setLoading];
|
|
57
|
+
}
|
package/src/client/useStream.ts
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { BaseModel, errorLogger, whereClause } from 'firebase-client-ql';
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
|
-
|
|
6
|
-
type UseStreamResult = {
|
|
7
|
-
data: any;
|
|
8
|
-
loading: boolean;
|
|
9
|
-
error: unknown;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export const useStream = <T extends BaseModel>(
|
|
13
|
-
param: {
|
|
14
|
-
model: any;
|
|
15
|
-
where?: whereClause[];
|
|
16
|
-
reference?: string;
|
|
17
|
-
filter?: {
|
|
18
|
-
orderBy?: { parameter: string; direction?: 'asc' | 'desc' };
|
|
19
|
-
offset?: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
): UseStreamResult => {
|
|
23
|
-
const [data, setData] = useState<any>();
|
|
24
|
-
const [loading, setLoading] = useState(true);
|
|
25
|
-
const [error, setError] = useState<unknown>(null);
|
|
26
|
-
|
|
27
|
-
useEffect(() => {
|
|
28
|
-
let unsubscribe: (() => void) | undefined;
|
|
29
|
-
setLoading(true);
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
const { model, reference, where, filter } = param;
|
|
33
|
-
|
|
34
|
-
if (reference) {
|
|
35
|
-
unsubscribe = model.stream((result: T) => {
|
|
36
|
-
setData(result);
|
|
37
|
-
setLoading(false);
|
|
38
|
-
}, reference);
|
|
39
|
-
}
|
|
40
|
-
else if (where) {
|
|
41
|
-
if (where.length > 0 && where.every(w => w.value === undefined)) {
|
|
42
|
-
setData([]);
|
|
43
|
-
setLoading(false);
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
unsubscribe = model.streamWhere(
|
|
48
|
-
where,
|
|
49
|
-
(result: any[]) => {
|
|
50
|
-
setData(result ?? []);
|
|
51
|
-
setLoading(false);
|
|
52
|
-
},
|
|
53
|
-
100,
|
|
54
|
-
filter?.orderBy,
|
|
55
|
-
filter?.offset
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
} catch (err) {
|
|
59
|
-
errorLogger('useStream error:', err);
|
|
60
|
-
setError(err);
|
|
61
|
-
setLoading(false);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return () => {
|
|
65
|
-
if (typeof unsubscribe === 'function') unsubscribe();
|
|
66
|
-
};
|
|
67
|
-
}, [
|
|
68
|
-
JSON.stringify(param.where),
|
|
69
|
-
JSON.stringify(param.filter),
|
|
70
|
-
param.reference,
|
|
71
|
-
]);
|
|
72
|
-
|
|
73
|
-
return { data, loading, error };
|
|
74
|
-
};
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { BaseModel, errorLogger, whereClause } from 'firebase-client-ql';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
type UseStreamResult = {
|
|
7
|
+
data: any;
|
|
8
|
+
loading: boolean;
|
|
9
|
+
error: unknown;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const useStream = <T extends BaseModel>(
|
|
13
|
+
param: {
|
|
14
|
+
model: any;
|
|
15
|
+
where?: whereClause[];
|
|
16
|
+
reference?: string;
|
|
17
|
+
filter?: {
|
|
18
|
+
orderBy?: { parameter: string; direction?: 'asc' | 'desc' };
|
|
19
|
+
offset?: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
): UseStreamResult => {
|
|
23
|
+
const [data, setData] = useState<any>();
|
|
24
|
+
const [loading, setLoading] = useState(true);
|
|
25
|
+
const [error, setError] = useState<unknown>(null);
|
|
26
|
+
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
let unsubscribe: (() => void) | undefined;
|
|
29
|
+
setLoading(true);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const { model, reference, where, filter } = param;
|
|
33
|
+
|
|
34
|
+
if (reference) {
|
|
35
|
+
unsubscribe = model.stream((result: T) => {
|
|
36
|
+
setData(result);
|
|
37
|
+
setLoading(false);
|
|
38
|
+
}, reference);
|
|
39
|
+
}
|
|
40
|
+
else if (where) {
|
|
41
|
+
if (where.length > 0 && where.every(w => w.value === undefined)) {
|
|
42
|
+
setData([]);
|
|
43
|
+
setLoading(false);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
unsubscribe = model.streamWhere(
|
|
48
|
+
where,
|
|
49
|
+
(result: any[]) => {
|
|
50
|
+
setData(result ?? []);
|
|
51
|
+
setLoading(false);
|
|
52
|
+
},
|
|
53
|
+
100,
|
|
54
|
+
filter?.orderBy,
|
|
55
|
+
filter?.offset
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
errorLogger('useStream error:', err);
|
|
60
|
+
setError(err);
|
|
61
|
+
setLoading(false);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return () => {
|
|
65
|
+
if (typeof unsubscribe === 'function') unsubscribe();
|
|
66
|
+
};
|
|
67
|
+
}, [
|
|
68
|
+
JSON.stringify(param.where),
|
|
69
|
+
JSON.stringify(param.filter),
|
|
70
|
+
param.reference,
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
return { data, loading, error };
|
|
74
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ⚠️ Client-only exports
|
|
3
|
-
* These hooks must NOT be imported in Server Components
|
|
4
|
-
*/
|
|
5
|
-
export * from './client';
|
|
1
|
+
/**
|
|
2
|
+
* ⚠️ Client-only exports
|
|
3
|
+
* These hooks must NOT be imported in Server Components
|
|
4
|
+
*/
|
|
5
|
+
export * from './client';
|