miolo-react 3.0.0-beta.222 → 3.0.0-beta.224
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miolo-react",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.224",
|
|
4
4
|
"description": "React utils for miolo",
|
|
5
5
|
"author": "Donato Lorenzo <donato@afialapis.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"prepublishOnly": "npm run lint"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"idb-keyval": "^6.
|
|
33
|
+
"idb-keyval": "^6.3.0",
|
|
34
34
|
"miolo-cli": "../miolo-cli"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
@@ -3,6 +3,26 @@ import { useCallback, /*useEffect,*/ useState } from "react"
|
|
|
3
3
|
import { useSsrDataOrReload } from "../ssr/useSsrDataOrReload.mjs"
|
|
4
4
|
import Context from "./MioloContext.mjs"
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('../ssr/useSsrDataOrReload.mjs').MioloSSRData} MioloSSRData
|
|
8
|
+
* @typedef {import('../ssr/useSsrDataOrReload.mjs').MioloSSRDataOptions} MioloSSRDataOptions
|
|
9
|
+
*
|
|
10
|
+
* @typedef {Object} MioloContextData
|
|
11
|
+
* @property {Object} user - session's data as in app.ctx
|
|
12
|
+
* @property {boolean} authenticated - authenticated flag as in app.ctx
|
|
13
|
+
* @property {Function} updateUser - function to update user
|
|
14
|
+
* @property {Function} googleLogin - function to login with google
|
|
15
|
+
* @property {Function} localLogin - function to login with local
|
|
16
|
+
* @property {Function} logout - function to logout
|
|
17
|
+
* @property {(name: string, options: MioloSSRDataOptions) => MioloSSRData} useSsrData - function to handle some ssr data
|
|
18
|
+
* @property {string} authMethod - authentication method
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {Object} context - Miolo's app.ctx object
|
|
23
|
+
* @param {React.ReactNode} children - React children
|
|
24
|
+
* @returns {React.ReactNode}
|
|
25
|
+
*/
|
|
6
26
|
const MioloContextProvider = ({ context, children }) => {
|
|
7
27
|
const [innerContext, setInnerContext] = useState(context)
|
|
8
28
|
const [mioloObj, _setMioloObj] = useState(miolo_client(context))
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
let _historyPatched = false
|
|
2
|
+
|
|
3
|
+
export default function patchHistory() {
|
|
4
|
+
if (typeof window === "undefined" || _historyPatched) return
|
|
5
|
+
|
|
6
|
+
const originalPushState = window.history.pushState
|
|
7
|
+
window.history.pushState = function (...args) {
|
|
8
|
+
const ret = originalPushState.apply(this, args)
|
|
9
|
+
window.dispatchEvent(new Event("miolo-navigation"))
|
|
10
|
+
return ret
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const originalReplaceState = window.history.replaceState
|
|
14
|
+
window.history.replaceState = function (...args) {
|
|
15
|
+
const ret = originalReplaceState.apply(this, args)
|
|
16
|
+
window.dispatchEvent(new Event("miolo-navigation"))
|
|
17
|
+
return ret
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
window.addEventListener("popstate", () => {
|
|
21
|
+
window.dispatchEvent(new Event("miolo-navigation"))
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
_historyPatched = true
|
|
25
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useCallback } from "react"
|
|
2
|
+
|
|
3
|
+
const _makeSerializable = (obj) => {
|
|
4
|
+
try {
|
|
5
|
+
return JSON.parse(JSON.stringify(obj))
|
|
6
|
+
} catch (_) {
|
|
7
|
+
return obj
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function useIndexedDb(name, logger, cache, ttl) {
|
|
12
|
+
const cacheInvalidate = useCallback(async () => {
|
|
13
|
+
if (typeof window !== "undefined") {
|
|
14
|
+
const { del } = await import("idb-keyval")
|
|
15
|
+
await del(`ssr-cache-${name}`)
|
|
16
|
+
}
|
|
17
|
+
}, [name])
|
|
18
|
+
|
|
19
|
+
const cacheSet = useCallback(
|
|
20
|
+
async (data) => {
|
|
21
|
+
if (cache === true) {
|
|
22
|
+
if (typeof window !== "undefined") {
|
|
23
|
+
try {
|
|
24
|
+
const { set } = await import("idb-keyval")
|
|
25
|
+
await set(`ssr-cache-${name}`, { data: _makeSerializable(data), ts: Date.now() })
|
|
26
|
+
} catch (err) {
|
|
27
|
+
logger.error(`[miolo-react][ssr][${name}] error setting cache for ${name}: ${err}`)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
[logger, cache, name]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const cacheGet = useCallback(async () => {
|
|
36
|
+
if (cache === true) {
|
|
37
|
+
if (typeof window !== "undefined") {
|
|
38
|
+
try {
|
|
39
|
+
const { get } = await import("idb-keyval")
|
|
40
|
+
const cached = await get(`ssr-cache-${name}`)
|
|
41
|
+
if (cached && cached.data !== undefined) {
|
|
42
|
+
const expired = ttl !== undefined && Date.now() - cached.ts > ttl * 1000
|
|
43
|
+
return [cached.data, expired, cached.ts]
|
|
44
|
+
}
|
|
45
|
+
} catch (err) {
|
|
46
|
+
logger.error(`[miolo-react][ssr][${name}] error getting cache for ${name}: ${err}`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return [null, false]
|
|
51
|
+
}, [logger, cache, name, ttl])
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
cacheInvalidate,
|
|
55
|
+
cacheSet,
|
|
56
|
+
cacheGet
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -1,40 +1,39 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
|
|
2
2
|
import getSsrDataFromContext from "./getSsrDataFromContext.mjs"
|
|
3
|
+
import patchHistory from "./patchHistory.mjs"
|
|
4
|
+
import useIndexedDb from "./useIndexedDb.mjs"
|
|
3
5
|
import useOnWindowFocus from "./useOnWindowFocus.mjs"
|
|
4
6
|
import usePropsCheck from "./usePropsCheck.mjs"
|
|
5
7
|
|
|
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
|
-
_historyPatched = true
|
|
37
|
-
}
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import('miolo-model').MioloModel} MioloModel
|
|
10
|
+
* @typedef {import('miolo-model').MioloArray} MioloArray
|
|
11
|
+
*
|
|
12
|
+
*
|
|
13
|
+
*
|
|
14
|
+
* @typedef {Object} MioloSSRDataOptions
|
|
15
|
+
* @property {any} [defval=[]] - The default value for the data.
|
|
16
|
+
* @property {Function} [loader] - A function that loads the data remotely. You need either @loader or @url.
|
|
17
|
+
* @property {string} [url] - The URL to load the data from. You need either @loader or @url.
|
|
18
|
+
* @property {Object} [params] - The parameters to pass to the @loader.
|
|
19
|
+
* @property {MioloModel} [model] - A MioloModel class for the data.
|
|
20
|
+
* @property {Function} [modifier] - A function that modifies the data (after ssr'ed or loaded, and after instantiated @model if any).
|
|
21
|
+
* @property {Function} [effect] - A function that is called when the data is loaded. The @effect function should return true if the data needs to be reloaded.
|
|
22
|
+
* @property {boolean} [cache=false] - Whether to cache the data.
|
|
23
|
+
* @property {number} [ttl] - The time to live for the cached data in seconds.
|
|
24
|
+
* @property {boolean} [autoRefresh=true] - Whether to automatically refresh the data on cache expiration.
|
|
25
|
+
*
|
|
26
|
+
*
|
|
27
|
+
* @typedef {Object} MioloSSRData
|
|
28
|
+
* @property {MioloModel | MioloArray | any} data - The data state. Generaly defined by @model and/or @modifier options.
|
|
29
|
+
* @property {Function} setData - Set the data state directly.
|
|
30
|
+
* @property {Function} refresh - If needed, remotely reload data (by calling @loader or @url).
|
|
31
|
+
* @property {Function} invalidate - Invalidate the data cache (requires @cache to be true).
|
|
32
|
+
* @property {string|undefined} error - The error message if any.
|
|
33
|
+
*
|
|
34
|
+
* @property {boolean} ok - Status of SSR data, true if everything was ssr'ed or remotely loaded ok.
|
|
35
|
+
* @property {boolean} ready - true when @data is loaded (either ssr'ed or remotely).
|
|
36
|
+
*/
|
|
38
37
|
|
|
39
38
|
const globalSocketState = {
|
|
40
39
|
rooms: new Map(),
|
|
@@ -43,6 +42,18 @@ const globalSocketState = {
|
|
|
43
42
|
versionsRequestedAt: 0
|
|
44
43
|
}
|
|
45
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Hook to get some ssr data or reload it if needed.
|
|
47
|
+
*
|
|
48
|
+
* @param {Object} context - The miolo context's state object.
|
|
49
|
+
* @param {Object} miolo - The miolo client object, that is:
|
|
50
|
+
* - @prop {Object} fetcher - The fetcher object.
|
|
51
|
+
* - @prop {Object} socket - The socket object.
|
|
52
|
+
* - @prop {Object} logger - The logger object.
|
|
53
|
+
* @param {string} name - The name of the data.
|
|
54
|
+
* @param {MioloSSRDataOptions} options - The options object:
|
|
55
|
+
* @returns {MioloSSRData}
|
|
56
|
+
*/
|
|
46
57
|
const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
47
58
|
const { fetcher, socket, logger } = miolo
|
|
48
59
|
const {
|
|
@@ -85,46 +96,7 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
85
96
|
const [error, setError] = useState(undefined)
|
|
86
97
|
const pendingLazyRefreshRef = useRef(false)
|
|
87
98
|
|
|
88
|
-
const cacheInvalidate =
|
|
89
|
-
if (typeof window !== "undefined") {
|
|
90
|
-
const { del } = await import("idb-keyval")
|
|
91
|
-
await del(`ssr-cache-${name}`)
|
|
92
|
-
}
|
|
93
|
-
}, [name])
|
|
94
|
-
|
|
95
|
-
const cacheSet = useCallback(
|
|
96
|
-
async (data) => {
|
|
97
|
-
if (cache === true) {
|
|
98
|
-
if (typeof window !== "undefined") {
|
|
99
|
-
try {
|
|
100
|
-
const { set } = await import("idb-keyval")
|
|
101
|
-
await set(`ssr-cache-${name}`, { data: _makeSerializable(data), ts: Date.now() })
|
|
102
|
-
} catch (err) {
|
|
103
|
-
logger.error(`[miolo-react][ssr][${name}] error setting cache for ${name}: ${err}`)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
[logger, cache, name]
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
const cacheGet = useCallback(async () => {
|
|
112
|
-
if (cache === true) {
|
|
113
|
-
if (typeof window !== "undefined") {
|
|
114
|
-
try {
|
|
115
|
-
const { get } = await import("idb-keyval")
|
|
116
|
-
const cached = await get(`ssr-cache-${name}`)
|
|
117
|
-
if (cached && cached.data !== undefined) {
|
|
118
|
-
const expired = ttl !== undefined && Date.now() - cached.ts > ttl * 1000
|
|
119
|
-
return [cached.data, expired, cached.ts]
|
|
120
|
-
}
|
|
121
|
-
} catch (err) {
|
|
122
|
-
logger.error(`[miolo-react][ssr][${name}] error getting cache for ${name}: ${err}`)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return [null, false]
|
|
127
|
-
}, [logger, cache, name, ttl])
|
|
99
|
+
const { cacheInvalidate, cacheSet, cacheGet } = useIndexedDb(name, logger, cache, ttl)
|
|
128
100
|
|
|
129
101
|
const updateSsrData = useCallback(
|
|
130
102
|
(data) => {
|