muya 2.3.2 → 2.3.3
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
import{STATE_SCHEDULER as
|
|
1
|
+
import{STATE_SCHEDULER as f}from"../create";import{getId as P}from"../utils/id";import{shallow as v}from"../utils/shallow";import{selectSql as O}from"./select-sql";import{createTable as R,DEFAULT_STEP_SIZE as M}from"./table/table";function K(g){const k=P();function m(e){return`state-${k}-search-${e}`}let h;async function o(){if(!h){const{backend:e,...n}=g,t=e instanceof Promise?await e:e;h=await R({backend:t,...n})}return h}const c=new Map,i=new Map,S=new Map;async function p(e,n){const t=S.get(e),{options:a={}}=n,{stepSize:s=M}=a;if(!t)return!1;const r=[];for(let l=0;l<s;l++){const u=await t.next();if(u.done){S.delete(e);break}n.keys.has(String(u.value.rowId))||(r.push(u.value.document),n.keys.add(String(u.value.rowId)))}return r.length===0||v(n.items,r)?!1:(n.items=[...n.items,...r],!0)}function b(e){const n=i.get(e);n&&n()}async function x(e){const n=await o(),t=c.get(e);if(!t)return;const{options:a}=t,s=n.search({...a,select:(r,{rowId:l})=>({document:r,rowId:l})});S.set(e,s),t.keys=new Set,t.items=[],await p(e,t)}async function y(e){await x(e),b(e)}function T(e){const{key:n,op:t}=e,a=new Set;for(const[s,{keys:r}]of c)switch(t){case"delete":case"update":{r.has(String(n))&&a.add(s);break}case"insert":{a.add(s);break}}return a}async function d(e){const n=new Set;for(const t of e){const a=T(t);for(const s of a)n.add(s)}for(const t of n){const a=m(t);f.schedule(a,{searchId:t})}}const w=new Set;function D(e,n){c.has(e)||(c.set(e,{items:[],options:n,keys:new Set}),n&&y(e));const t=c.get(e);return n&&(t.options=n),t}const I={clear(e){c.delete(e)},async set(e){const t=await(await o()).set(e);return await d([t]),t},async batchSet(e){const t=await(await o()).batchSet(e);return await d(t),t},async delete(e){const t=await(await o()).delete(e);return t&&await d([t]),t},async deleteBy(e){const t=await(await o()).deleteBy(e);return await d(t),t},async get(e,n){return(await o()).get(e,n)},async*search(e={}){const n=await o();for await(const t of n.search(e))yield t},async count(e){return await(await o()).count(e)},updateSearchOptions(e,n){const t=D(e,n);t.options=n;const a=m(e);f.schedule(a,{searchId:e})},subscribe(e,n){const t=m(e),a=f.add(t,{onScheduleDone(){y(e)}});return w.add(a),i.has(e)||i.set(e,n),()=>{i.delete(e),a()}},getSnapshot(e){return D(e).items},refresh:y,destroy(){for(const e of w)e();c.clear(),i.clear()},async next(e){const n=c.get(e);if(n){const t=await p(e,n);return t&&b(e),t}return!1},select(e){return O(I,e)}};return I}export{K as createSqliteState};
|
package/esm/sqlite/use-sqlite.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useCallback as r,useDebugValue as S,
|
|
1
|
+
import{useCallback as r,useDebugValue as S,useEffect as p,useId as a,useLayoutEffect as f,useMemo as D}from"react";import{isError as y,isPromise as x}from"../utils/is";import{useSyncExternalStoreWithSelector as b}from"use-sync-external-store/shim/with-selector";function O(e,s={},u=[]){const{select:c}=s,t=a();f(()=>{e.updateSearchOptions(t,{...s,select:void 0})},u),p(()=>()=>{e.clear(t)},[]);const l=r(o=>c?o.map(c):o,[c]),d=r(o=>e.subscribe(t,o),[e,t]),i=r(()=>e.getSnapshot(t),[e,t]),n=b(d,i,i,l);if(S(n),x(n)||y(n))throw n;const m=D(()=>({next:()=>e.next(t),reset:()=>e.refresh(t)}),[t,e]);return[n,m]}export{O as useSqliteValue};
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import { createSqliteState } from '../create-sqlite'
|
|
|
4
4
|
import { useSqliteValue } from '../use-sqlite'
|
|
5
5
|
import { waitFor } from '@testing-library/react'
|
|
6
6
|
import { bunMemoryBackend } from '../table/bun-backend'
|
|
7
|
-
import { Suspense, useState } from 'react'
|
|
7
|
+
import { StrictMode, Suspense, useState } from 'react'
|
|
8
8
|
import { DEFAULT_STEP_SIZE } from '../table/table'
|
|
9
9
|
|
|
10
10
|
const backend = bunMemoryBackend()
|
|
@@ -15,13 +15,17 @@ interface Person {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function Wrapper({ children }: Readonly<{ children: React.ReactNode }>) {
|
|
18
|
-
return
|
|
18
|
+
return (
|
|
19
|
+
<StrictMode>
|
|
20
|
+
<Suspense fallback={<div>Loading...</div>}>{children}</Suspense>
|
|
21
|
+
</StrictMode>
|
|
22
|
+
)
|
|
19
23
|
}
|
|
20
24
|
describe('use-sqlite-state', () => {
|
|
21
25
|
it('should get basic value states', async () => {
|
|
22
26
|
const sql = createSqliteState<Person>({ backend, tableName: 'State1', key: 'id' })
|
|
23
27
|
let reRenders = 0
|
|
24
|
-
const { result } = renderHook(
|
|
28
|
+
const { result, rerender } = renderHook(
|
|
25
29
|
() => {
|
|
26
30
|
reRenders++
|
|
27
31
|
const aha = useSqliteValue(sql, {}, [])
|
|
@@ -66,6 +70,14 @@ describe('use-sqlite-state', () => {
|
|
|
66
70
|
expect(result.current[0].length).toBe(2)
|
|
67
71
|
expect(reRenders).toBe(6)
|
|
68
72
|
})
|
|
73
|
+
|
|
74
|
+
act(() => {
|
|
75
|
+
rerender()
|
|
76
|
+
})
|
|
77
|
+
await waitFor(() => {
|
|
78
|
+
expect(reRenders).toBe(7)
|
|
79
|
+
expect(result.current[0].length).toBe(2)
|
|
80
|
+
})
|
|
69
81
|
})
|
|
70
82
|
|
|
71
83
|
it('should use where clause changed via state', async () => {
|
|
@@ -31,6 +31,7 @@ export interface SyncTable<Document extends DocType> {
|
|
|
31
31
|
readonly deleteBy: (where: Where<Document>) => Promise<MutationResult[]>
|
|
32
32
|
readonly destroy: () => void
|
|
33
33
|
readonly next: (searchId: SearchId) => Promise<boolean>
|
|
34
|
+
readonly clear: (searchId: SearchId) => void
|
|
34
35
|
|
|
35
36
|
readonly select: <Params extends unknown[]>(
|
|
36
37
|
compute: (...args: Params) => SearchOptions<Document>,
|
|
@@ -221,6 +222,9 @@ export function createSqliteState<Document extends DocType>(options: CreateSqlit
|
|
|
221
222
|
}
|
|
222
223
|
|
|
223
224
|
const state: SyncTable<Document> = {
|
|
225
|
+
clear(searchId: SearchId) {
|
|
226
|
+
cachedData.delete(searchId)
|
|
227
|
+
},
|
|
224
228
|
async set(document) {
|
|
225
229
|
const table = await getTable()
|
|
226
230
|
const changes = await table.set(document)
|
|
@@ -271,20 +275,19 @@ export function createSqliteState<Document extends DocType>(options: CreateSqlit
|
|
|
271
275
|
|
|
272
276
|
subscribe(searchId, listener) {
|
|
273
277
|
const scheduleId = getScheduleId(searchId)
|
|
274
|
-
const
|
|
278
|
+
const clearScheduler = STATE_SCHEDULER.add(scheduleId, {
|
|
275
279
|
onScheduleDone() {
|
|
276
280
|
refresh(searchId)
|
|
277
281
|
},
|
|
278
282
|
})
|
|
279
|
-
clearSchedulers.add(
|
|
283
|
+
clearSchedulers.add(clearScheduler)
|
|
280
284
|
|
|
281
285
|
if (!listeners.has(searchId)) {
|
|
282
286
|
listeners.set(searchId, listener)
|
|
283
287
|
}
|
|
284
288
|
return () => {
|
|
285
289
|
listeners.delete(searchId)
|
|
286
|
-
|
|
287
|
-
cachedData.delete(searchId)
|
|
290
|
+
clearScheduler()
|
|
288
291
|
}
|
|
289
292
|
},
|
|
290
293
|
getSnapshot(searchId) {
|
package/src/sqlite/use-sqlite.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useDebugValue, useId, useLayoutEffect, useMemo, type DependencyList } from 'react'
|
|
1
|
+
import { useCallback, useDebugValue, useEffect, useId, useLayoutEffect, useMemo, type DependencyList } from 'react'
|
|
2
2
|
import type { SyncTable } from './create-sqlite'
|
|
3
3
|
import type { DocType } from './table/table.types'
|
|
4
4
|
import { isError, isPromise } from '../utils/is'
|
|
@@ -39,6 +39,13 @@ export function useSqliteValue<Document extends DocType, Selected = Document>(
|
|
|
39
39
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
40
40
|
}, deps)
|
|
41
41
|
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
return () => {
|
|
44
|
+
state.clear(id)
|
|
45
|
+
}
|
|
46
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
+
}, [])
|
|
48
|
+
|
|
42
49
|
const selector = useCallback(
|
|
43
50
|
(documents: Document[]) => {
|
|
44
51
|
// eslint-disable-next-line unicorn/no-array-callback-reference
|
|
@@ -22,6 +22,7 @@ export interface SyncTable<Document extends DocType> {
|
|
|
22
22
|
readonly deleteBy: (where: Where<Document>) => Promise<MutationResult[]>;
|
|
23
23
|
readonly destroy: () => void;
|
|
24
24
|
readonly next: (searchId: SearchId) => Promise<boolean>;
|
|
25
|
+
readonly clear: (searchId: SearchId) => void;
|
|
25
26
|
readonly select: <Params extends unknown[]>(compute: (...args: Params) => SearchOptions<Document>) => CreateState<Document, Params>;
|
|
26
27
|
}
|
|
27
28
|
/**
|