miolo-react 3.0.0-beta.212 → 3.0.0-beta.214
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 +1 -1
- package/src/ssr/useSsrDataOrReload.mjs +131 -144
package/package.json
CHANGED
|
@@ -11,14 +11,6 @@ const _makeSerializable = (obj) => {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/*
|
|
15
|
-
QUE PASA CON LA DUPLICIDAD DE INVALIDACION
|
|
16
|
-
- el cliente hace un cambio
|
|
17
|
-
- setData() cambia estado y cache local
|
|
18
|
-
- la llamada en servidor provoca un ssr-refresh (necesario para otros clientes)
|
|
19
|
-
- pero se puede evitar el doble refresh en el que hace el cambio?
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
14
|
const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
23
15
|
const { fetcher, socket, logger } = miolo
|
|
24
16
|
const {
|
|
@@ -59,25 +51,57 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
59
51
|
)
|
|
60
52
|
const [status, setStatus] = useState(ssrDataFromContext !== undefined ? "loaded" : "idle")
|
|
61
53
|
const [error, setError] = useState(undefined)
|
|
62
|
-
|
|
54
|
+
|
|
55
|
+
const cacheInvalidate = useCallback(async () => {
|
|
56
|
+
if (typeof window !== "undefined") {
|
|
57
|
+
const { del } = await import("idb-keyval")
|
|
58
|
+
await del(`ssr-cache-${name}`)
|
|
59
|
+
}
|
|
60
|
+
}, [name])
|
|
61
|
+
|
|
62
|
+
const cacheSet = useCallback(
|
|
63
|
+
async (data) => {
|
|
64
|
+
if (cache === true) {
|
|
65
|
+
if (typeof window !== "undefined") {
|
|
66
|
+
try {
|
|
67
|
+
const { set } = await import("idb-keyval")
|
|
68
|
+
await set(`ssr-cache-${name}`, { data: _makeSerializable(data), ts: Date.now() })
|
|
69
|
+
} catch (err) {
|
|
70
|
+
logger.error(`[miolo-react][ssr][${name}] error setting cache for ${name}: ${err}`)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
[logger, cache, name]
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const cacheGet = useCallback(async () => {
|
|
79
|
+
if (cache === true) {
|
|
80
|
+
if (typeof window !== "undefined") {
|
|
81
|
+
try {
|
|
82
|
+
const { get } = await import("idb-keyval")
|
|
83
|
+
const cached = await get(`ssr-cache-${name}`)
|
|
84
|
+
if (cached && cached.data !== undefined) {
|
|
85
|
+
const expired = ttl !== undefined && Date.now() - cached.ts > ttl * 1000
|
|
86
|
+
return [cached.data, expired, cached.ts]
|
|
87
|
+
}
|
|
88
|
+
} catch (err) {
|
|
89
|
+
logger.error(`[miolo-react][ssr][${name}] error getting cache for ${name}: ${err}`)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return [null, false]
|
|
94
|
+
}, [logger, cache, name, ttl])
|
|
63
95
|
|
|
64
96
|
const updateSsrData = useCallback(
|
|
65
97
|
(data) => {
|
|
66
98
|
setStatus("loading")
|
|
67
99
|
setSsrData(parseData(data))
|
|
68
|
-
setStatus("loaded")
|
|
69
100
|
setError(undefined)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
import("idb-keyval").then(({ set }) => {
|
|
73
|
-
set(`ssr-cache-${name}`, { data: _makeSerializable(data), ts: Date.now() }).catch(
|
|
74
|
-
() => {}
|
|
75
|
-
)
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
}
|
|
101
|
+
setStatus("loaded")
|
|
102
|
+
/*await*/ cacheSet(data)
|
|
79
103
|
},
|
|
80
|
-
[parseData,
|
|
104
|
+
[parseData, cacheSet]
|
|
81
105
|
)
|
|
82
106
|
|
|
83
107
|
const refreshSsrData = useCallback(async () => {
|
|
@@ -108,38 +132,15 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
108
132
|
}
|
|
109
133
|
|
|
110
134
|
if (newData !== undefined) {
|
|
111
|
-
if (cache === true) {
|
|
112
|
-
if (typeof window !== "undefined") {
|
|
113
|
-
try {
|
|
114
|
-
const { set } = await import("idb-keyval")
|
|
115
|
-
await set(`ssr-cache-${name}`, { data: _makeSerializable(newData), ts: Date.now() })
|
|
116
|
-
} catch (err) {
|
|
117
|
-
console.error(err)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
135
|
setSsrData(parseData(newData))
|
|
136
|
+
/*await*/ cacheSet(newData)
|
|
122
137
|
}
|
|
123
138
|
|
|
124
139
|
setStatus("loaded")
|
|
125
|
-
}, [status, context, fetcher, loader, url, params, parseData, name,
|
|
126
|
-
|
|
127
|
-
const invalidateCache = useCallback((tName, callback = undefined) => {
|
|
128
|
-
if (typeof window !== "undefined") {
|
|
129
|
-
import("idb-keyval").then(({ del }) => {
|
|
130
|
-
del(`ssr-cache-${tName}`)
|
|
131
|
-
.catch(() => {})
|
|
132
|
-
.then(() => {
|
|
133
|
-
if (callback) {
|
|
134
|
-
callback()
|
|
135
|
-
}
|
|
136
|
-
})
|
|
137
|
-
})
|
|
138
|
-
}
|
|
139
|
-
}, [])
|
|
140
|
+
}, [status, context, fetcher, loader, url, params, parseData, name, cacheSet, logger])
|
|
140
141
|
|
|
141
142
|
const checkCacheVersions = useCallback(
|
|
142
|
-
(versions) => {
|
|
143
|
+
async (versions) => {
|
|
143
144
|
logger.verbose(
|
|
144
145
|
`[miolo-react][ssr][${name}] Backend versions received: ${JSON.stringify(versions)}`
|
|
145
146
|
)
|
|
@@ -151,31 +152,25 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
151
152
|
`[miolo-react][ssr][${name}] Backend version for ${name} is ${backendVersion}`
|
|
152
153
|
)
|
|
153
154
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
logger.verbose(`[miolo-react][ssr][${name}] ssr-versions match for ${name}`)
|
|
170
|
-
}
|
|
171
|
-
})
|
|
172
|
-
.catch(() => {})
|
|
173
|
-
})
|
|
174
|
-
.catch(() => {})
|
|
155
|
+
const [cached, expired, ts] = await cacheGet()
|
|
156
|
+
if (cached) {
|
|
157
|
+
if (expired || ts < backendVersion) {
|
|
158
|
+
logger.info(
|
|
159
|
+
`[miolo-react][ssr][${name}] ssr-versions mismatch for ${name}, invalidating`
|
|
160
|
+
)
|
|
161
|
+
await cacheInvalidate()
|
|
162
|
+
if (autoRefresh === true) {
|
|
163
|
+
refreshSsrData()
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
logger.verbose(`[miolo-react][ssr][${name}] ssr-versions match for ${name}`)
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
logger.warn(`[miolo-react][ssr][${name}] No cached data found for ${name}`)
|
|
175
170
|
}
|
|
176
171
|
}
|
|
177
172
|
},
|
|
178
|
-
[name, logger,
|
|
173
|
+
[name, logger, cacheGet, cacheInvalidate, refreshSsrData, autoRefresh]
|
|
179
174
|
)
|
|
180
175
|
|
|
181
176
|
useEffect(() => {
|
|
@@ -186,7 +181,7 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
186
181
|
|
|
187
182
|
try {
|
|
188
183
|
if (status === "idle") {
|
|
189
|
-
logger.verbose(`[miolo-react][ssr][${name}]
|
|
184
|
+
logger.verbose(`[miolo-react][ssr][${name}] getting data for ${name}...`)
|
|
190
185
|
|
|
191
186
|
const changed =
|
|
192
187
|
effect === undefined ||
|
|
@@ -194,27 +189,20 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
194
189
|
effect === true
|
|
195
190
|
|
|
196
191
|
if (changed === true) {
|
|
197
|
-
|
|
198
|
-
if (cache === true) {
|
|
199
|
-
if (typeof window !== "undefined") {
|
|
200
|
-
try {
|
|
201
|
-
const { get } = await import("idb-keyval")
|
|
202
|
-
cached = await get(`ssr-cache-${name}`)
|
|
203
|
-
} catch (err) {
|
|
204
|
-
console.error(err)
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
192
|
+
const [cached, expired, _ts] = await cacheGet()
|
|
208
193
|
|
|
209
|
-
if (cached
|
|
194
|
+
if (cached) {
|
|
195
|
+
logger.verbose(`[miolo-react][ssr][${name}] read data for ${name} from cache`)
|
|
210
196
|
setSsrData(parseData(cached.data))
|
|
211
197
|
|
|
212
|
-
if (
|
|
198
|
+
if (expired) {
|
|
199
|
+
logger.verbose(`[miolo-react][ssr][${name}] expired cache for ${name}, refreshing`)
|
|
213
200
|
refreshSsrData()
|
|
214
201
|
} else {
|
|
215
202
|
setStatus("loaded")
|
|
216
203
|
}
|
|
217
204
|
} else {
|
|
205
|
+
logger.verbose(`[miolo-react][ssr][${name}] no cached data for ${name}, refreshing`)
|
|
218
206
|
refreshSsrData()
|
|
219
207
|
}
|
|
220
208
|
}
|
|
@@ -227,80 +215,77 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
227
215
|
return () => {
|
|
228
216
|
mounted = false
|
|
229
217
|
}
|
|
230
|
-
}, [status, refreshSsrData, effect, name,
|
|
218
|
+
}, [status, refreshSsrData, effect, name, parseData, cacheGet, logger])
|
|
231
219
|
|
|
232
220
|
useEffect(() => {
|
|
233
|
-
if (
|
|
234
|
-
|
|
235
|
-
import("idb-keyval").then(({ set }) => {
|
|
236
|
-
set(`ssr-cache-${name}`, {
|
|
237
|
-
data: _makeSerializable(ssrDataFromContext),
|
|
238
|
-
ts: Date.now()
|
|
239
|
-
}).catch(() => {})
|
|
240
|
-
})
|
|
241
|
-
}
|
|
221
|
+
if (ssrDataFromContext !== undefined) {
|
|
222
|
+
/*await*/ cacheSet(ssrDataFromContext)
|
|
242
223
|
}
|
|
243
|
-
}, [ssrDataFromContext,
|
|
224
|
+
}, [ssrDataFromContext, cacheSet])
|
|
244
225
|
|
|
245
226
|
useEffect(() => {
|
|
246
|
-
if (socket
|
|
227
|
+
if (!socket || cache !== true) {
|
|
247
228
|
return
|
|
248
229
|
}
|
|
249
230
|
|
|
250
|
-
|
|
251
|
-
|
|
231
|
+
const onConnect = () => {
|
|
232
|
+
logger.verbose(`[miolo-react][ssr][${name}] Socket connected, subscribing`)
|
|
233
|
+
socket.emit("ssr-subscribe", name)
|
|
234
|
+
logger.verbose(`[miolo-react][ssr][${name}] Asking for ssr-versions`)
|
|
235
|
+
socket.emit("ssr-versions")
|
|
252
236
|
}
|
|
253
|
-
setSocketInited(true)
|
|
254
237
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (cache === true) {
|
|
258
|
-
logger.verbose(`[miolo-react][ssr][${name}] Asking for ssr-versions`)
|
|
259
|
-
socket.emit("ssr-versions")
|
|
238
|
+
const onInvalidate = async (data) => {
|
|
239
|
+
if (data.name !== name) return
|
|
260
240
|
|
|
261
|
-
|
|
241
|
+
logger.verbose(`[miolo-react][ssr][${name}] ssr-invalidate ${JSON.stringify(data)}`)
|
|
242
|
+
if (data.exclude_socket_id && data.exclude_socket_id === socket.id) {
|
|
243
|
+
logger.verbose(
|
|
244
|
+
`[miolo-react][ssr][${name}] ssr-invalidate ${data.name} ignored for socketid ${socket.id}`
|
|
245
|
+
)
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
logger.info(`[miolo-react][ssr][${name}] ssr-invalidate ${data.name}`)
|
|
249
|
+
await cacheInvalidate()
|
|
250
|
+
}
|
|
262
251
|
|
|
263
|
-
|
|
252
|
+
const onRefresh = async (data) => {
|
|
253
|
+
if (data.name !== name) return
|
|
264
254
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
logger.info(`[miolo-react][ssr][${name}] ssr-invalidate ${data.name}`)
|
|
274
|
-
invalidateCache(data.name)
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
socket.on("ssr-refresh", (data) => {
|
|
278
|
-
logger.verbose(
|
|
279
|
-
`[miolo-react][ssr][${name}] ssr-refresh ${JSON.stringify(data)} - my socket id: ${socket.id}`
|
|
280
|
-
)
|
|
281
|
-
if (data.exclude_socket_id && data.exclude_socket_id === socket.id) {
|
|
282
|
-
logger.verbose(
|
|
283
|
-
`[miolo-react][ssr][${name}] ssr-refresh ${data.name} ignored for socketid ${socket.id}`
|
|
284
|
-
)
|
|
285
|
-
return
|
|
286
|
-
}
|
|
287
|
-
logger.info(`[miolo-react][ssr][${name}] ssr-refresh ${data.name}`)
|
|
288
|
-
invalidateCache(data.name, () => {
|
|
289
|
-
refreshSsrData()
|
|
290
|
-
})
|
|
291
|
-
})
|
|
255
|
+
logger.verbose(
|
|
256
|
+
`[miolo-react][ssr][${name}] ssr-refresh ${JSON.stringify(data)} - my socket id: ${socket.id}`
|
|
257
|
+
)
|
|
258
|
+
if (data.exclude_socket_id && data.exclude_socket_id === socket.id) {
|
|
259
|
+
logger.verbose(
|
|
260
|
+
`[miolo-react][ssr][${name}] ssr-refresh ${data.name} ignored for socketid ${socket.id}`
|
|
261
|
+
)
|
|
262
|
+
return
|
|
292
263
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
264
|
+
logger.info(`[miolo-react][ssr][${name}] ssr-refresh ${data.name}`)
|
|
265
|
+
await cacheInvalidate()
|
|
266
|
+
refreshSsrData()
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
logger.verbose(`[miolo-react][ssr][${name}] Attaching ssr/cache socket handlers`)
|
|
270
|
+
|
|
271
|
+
if (socket.connected) {
|
|
272
|
+
onConnect()
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
socket.on("connect", onConnect)
|
|
276
|
+
socket.on("ssr-versions", checkCacheVersions)
|
|
277
|
+
socket.on("ssr-invalidate", onInvalidate)
|
|
278
|
+
socket.on("ssr-refresh", onRefresh)
|
|
279
|
+
|
|
280
|
+
return () => {
|
|
281
|
+
logger.verbose(`[miolo-react][ssr][${name}] Detaching ssr/cache socket handlers`)
|
|
282
|
+
socket.emit("ssr-unsubscribe", name)
|
|
283
|
+
socket.off("connect", onConnect)
|
|
284
|
+
socket.off("ssr-versions", checkCacheVersions)
|
|
285
|
+
socket.off("ssr-invalidate", onInvalidate)
|
|
286
|
+
socket.off("ssr-refresh", onRefresh)
|
|
287
|
+
}
|
|
288
|
+
}, [name, cache, socket, checkCacheVersions, logger, cacheInvalidate, refreshSsrData])
|
|
304
289
|
|
|
305
290
|
useOnWindowFocus(() => {
|
|
306
291
|
if (cache !== true) {
|
|
@@ -309,7 +294,9 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
309
294
|
if (socket === undefined) {
|
|
310
295
|
return
|
|
311
296
|
}
|
|
312
|
-
logger.verbose(
|
|
297
|
+
logger.verbose(
|
|
298
|
+
`[miolo-react][ssr][${name}] Window focused, checking versions (socket id is ${socket.id})`
|
|
299
|
+
)
|
|
313
300
|
socket.emit("ssr-versions")
|
|
314
301
|
}, [name, cache, logger, socket])
|
|
315
302
|
|
|
@@ -317,7 +304,7 @@ const useSsrDataOrReload = (context, miolo, name, options) => {
|
|
|
317
304
|
data: ssrData,
|
|
318
305
|
setData: updateSsrData,
|
|
319
306
|
refresh: refreshSsrData,
|
|
320
|
-
invalidate:
|
|
307
|
+
invalidate: cacheInvalidate,
|
|
321
308
|
error,
|
|
322
309
|
ok: error === undefined,
|
|
323
310
|
ready: status === "loaded"
|