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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miolo-react",
3
- "version": "3.0.0-beta.212",
3
+ "version": "3.0.0-beta.214",
4
4
  "description": "React utils for miolo",
5
5
  "author": "Donato Lorenzo <donato@afialapis.com>",
6
6
  "contributors": [
@@ -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
- const [socketInited, setSocketInited] = useState(false)
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
- if (cache === true) {
71
- if (typeof window !== "undefined") {
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, name, cache]
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, cache, logger])
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
- if (typeof window !== "undefined") {
155
- import("idb-keyval")
156
- .then(({ get }) => {
157
- get(`ssr-cache-${name}`)
158
- .then((cached) => {
159
- if (cached && cached.ts < backendVersion) {
160
- logger.info(
161
- `[miolo-react][ssr][${name}] ssr-versions mismatch for ${name}, invalidating`
162
- )
163
- invalidateCache(name, () => {
164
- if (autoRefresh === true) {
165
- refreshSsrData()
166
- }
167
- })
168
- } else {
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, invalidateCache, refreshSsrData, autoRefresh]
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}] loadData for ${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
- let cached = null
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 && cached.data !== undefined) {
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 (ttl !== undefined && Date.now() - cached.ts > ttl * 1000) {
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, ttl, parseData, cache, logger])
218
+ }, [status, refreshSsrData, effect, name, parseData, cacheGet, logger])
231
219
 
232
220
  useEffect(() => {
233
- if (cache === true) {
234
- if (ssrDataFromContext !== undefined && typeof window !== "undefined") {
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, name, cache])
224
+ }, [ssrDataFromContext, cacheSet])
244
225
 
245
226
  useEffect(() => {
246
- if (socket === undefined) {
227
+ if (!socket || cache !== true) {
247
228
  return
248
229
  }
249
230
 
250
- if (socketInited) {
251
- return
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
- socket.on("connect", () => {
256
- logger.verbose(`[miolo-react][ssr][${name}] Socket connected`)
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
- logger.verbose(`[miolo-react][ssr][${name}] Attaching ssr/cache socket handlers`)
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
- socket.on("ssr-versions", checkCacheVersions)
252
+ const onRefresh = async (data) => {
253
+ if (data.name !== name) return
264
254
 
265
- socket.on("ssr-invalidate", (data) => {
266
- logger.verbose(`[miolo-react][ssr][${name}] ssr-invalidate ${JSON.stringify(data)}`)
267
- if (data.exclude_socket_id && data.exclude_socket_id === socket.id) {
268
- logger.verbose(
269
- `[miolo-react][ssr][${name}] ssr-invalidate ${data.name} ignored for socketid ${socket.id}`
270
- )
271
- return
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
- name,
296
- cache,
297
- socket,
298
- socketInited,
299
- checkCacheVersions,
300
- logger,
301
- invalidateCache,
302
- refreshSsrData
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(`[miolo-react][ssr][${name}] Window focused, checking versions`)
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: (callback) => invalidateCache(name, callback),
307
+ invalidate: cacheInvalidate,
321
308
  error,
322
309
  ok: error === undefined,
323
310
  ready: status === "loaded"