muya 2.4.2 → 2.4.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 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 A(k){const g=P();function m(e){return`state-${g}-search-${e}`}let h;async function o(){if(!h){const{backend:e,...n}=k,t=e instanceof Promise?await e:e;h=await R({backend:t,...n})}return h}const c=new Map,d=new Map,y=new Map;async function p(e,n){const t=y.get(e),{options:a={}}=n,{stepSize:s=M}=a;if(!t)return!1;const r=[];for(let u=0;u<s;u++){const i=await t.next();if(i.done){y.delete(e);break}n.keys.has(String(i.value.key))||(r.push(i.value.document),n.keys.add(String(i.value.key)))}return r.length===0||v(n.items,r)?!1:(n.items=[...n.items,...r],!0)}function b(e){const n=d.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:u,key:i})=>({document:r,rowId:u,key:i})});y.set(e,s),t.keys=new Set,t.items=[],await p(e,t)}async function S(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 l(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 D=new Set;function w(e,n){c.has(e)||(c.set(e,{items:[],options:n,keys:new Set}),n&&S(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 l([t]),t},async batchSet(e){const t=await(await o()).batchSet(e);return await l(t),t},async delete(e){const t=await(await o()).delete(e);return t&&await l([t]),t},async deleteBy(e){const t=await(await o()).deleteBy(e);return await l(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=w(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(){S(e)}});return D.add(a),d.has(e)||d.set(e,n),()=>{d.delete(e),a()}},getSnapshot(e){return w(e).items},refresh:S,destroy(){for(const e of D)e();c.clear(),d.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{A as createSqliteState};
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 M}from"./select-sql";import{createTable as O,DEFAULT_STEP_SIZE as R}from"./table/table";function q(g){const k=P();function m(e){return`state-${k}-search-${e}`}let h;async function s(){if(!h){const{backend:e,...n}=g,t=e instanceof Promise?await e:e;h=await O({backend:t,...n})}return h}const r=new Map,i=new Map,y=new Map;async function p(e,n){const t=y.get(e),{options:a={}}=n,{stepSize:c=R}=a;if(!t)return!1;const o=[];for(let u=0;u<c;u++){const d=await t.next();if(d.done){y.delete(e);break}n.keys.has(String(d.value.key))||(o.push(d.value.document),n.keys.add(String(d.value.key)))}return o.length===0||v(n.items,o)?!1:(n.items=[...n.items,...o],!0)}function b(e){const n=i.get(e);if(n)for(const[,t]of n)t()}async function x(e){const n=await s(),t=r.get(e);if(!t)return;const{options:a}=t,c=n.search({...a,select:(o,{rowId:u,key:d})=>({document:o,rowId:u,key:d})});y.set(e,c),t.keys=new Set,t.items=[],await p(e,t)}async function S(e){await x(e),b(e)}function T(e){const{key:n,op:t}=e,a=new Set;for(const[c,{keys:o}]of r)switch(t){case"delete":case"update":{o.has(String(n))&&a.add(c);break}case"insert":{a.add(c);break}}return a}async function l(e){const n=new Set;for(const t of e){const a=T(t);for(const c of a)n.add(c)}for(const t of n){const a=m(t);f.schedule(a,{searchId:t})}}const w=new Set;function D(e,n){r.has(e)||(r.set(e,{items:[],options:n,keys:new Set}),n&&S(e));const t=r.get(e);return n&&(t.options=n),t}const I={clear(e){r.delete(e)},async set(e){const t=await(await s()).set(e);return await l([t]),t},async batchSet(e){const t=await(await s()).batchSet(e);return await l(t),t},async delete(e){const t=await(await s()).delete(e);return t&&await l([t]),t},async deleteBy(e){const t=await(await s()).deleteBy(e);return await l(t),t},async get(e,n){return(await s()).get(e,n)},async*search(e={}){const n=await s();for await(const t of n.search(e))yield t},async count(e){return await(await s()).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,t){const a=m(e),c=f.add(a,{onScheduleDone(){S(e)}});w.add(c),i.has(e)||i.set(e,new Map);const o=i.get(e);return o.set(n,t),()=>{o.delete(n),o.size===0&&i.delete(e),c()}},getSnapshot(e){return D(e).items},refresh:S,destroy(){for(const e of w)e();r.clear(),i.clear()},async next(e){const n=r.get(e);if(n){const t=await p(e,n);return t&&b(e),t}return!1},select(e){return M(I,e)}};return I}export{q as createSqliteState};
@@ -1 +1 @@
1
- import{createState as p}from"../create-state";let n=0;function i(){return n++,`${n.toString(36)}-sql`}function S(r,o){const{subscribe:a,updateSearchOptions:s}=r;return(...c)=>{const e=i(),m=a(e,()=>{t.emitter.emit()}),u=o(...c),t=p({destroy(){m(),t.emitter.clear(),t.cache.current=void 0},get(){return r.getSnapshot(e)},getSnapshot(){return r.getSnapshot(e)}});return s(e,u),t}}export{S as selectSql};
1
+ import{createState as l}from"../create-state";let n=0;function o(){return n++,`${n.toString(36)}-sql`}function S(r,a){const{subscribe:c,updateSearchOptions:s}=r,m=o();return(...u)=>{const e=o(),p=c(e,m,()=>{t.emitter.emit()}),i=a(...u),t=l({destroy(){p(),t.emitter.clear(),t.cache.current=void 0},get(){return r.getSnapshot(e)},getSnapshot(){return r.getSnapshot(e)}});return s(e,i),t}}export{S as selectSql};
@@ -1 +1 @@
1
- import{useCallback as l,useDebugValue as m,useEffect as a,useLayoutEffect as p,useMemo as f}from"react";import{isError as y,isPromise as D}from"../utils/is";import{useSyncExternalStoreWithSelector as h}from"use-sync-external-store/shim/with-selector";function x(n){const{limit:o,offset:i,order:c,sortBy:t,where:s,stepSize:u,select:r}=n;let e="";return o!==void 0&&(e+=`l${o}`),i!==void 0&&(e+=`o${i}`),c!==void 0&&(e+=`r${c}`),t!==void 0&&(e+=`s${t}`),s!==void 0&&(e+=`w${JSON.stringify(s)}`),u!==void 0&&(e+=`t${u}`),r!==void 0&&(e+=`f${r.toString()}`),e}function O(n,o={},i=[]){const{select:c}=o,t=f(()=>x({...o,select:void 0}),[o]);p(()=>{n.updateSearchOptions(t,{...o,select:void 0})},i),a(()=>()=>{n.clear(t)},[]);const s=l(d=>c?d.map(c):d,[c]),u=l(d=>n.subscribe(t,d),[n,t]),r=l(()=>n.getSnapshot(t),[n,t]),e=h(u,r,r,s);if(m(e),D(e)||y(e))throw e;const S=f(()=>({next:()=>n.next(t),reset:()=>n.refresh(t)}),[t,n]);return[e,S]}export{O as useSqliteValue};
1
+ import{useCallback as f,useDebugValue as p,useEffect as a,useId as y,useLayoutEffect as D,useMemo as S}from"react";import{isError as h,isPromise as x}from"../utils/is";import{useSyncExternalStoreWithSelector as b}from"use-sync-external-store/shim/with-selector";function q(t){const{limit:o,offset:s,order:c,sortBy:e,where:i,stepSize:u,select:d}=t;let n="";return o!==void 0&&(n+=`l${o}`),s!==void 0&&(n+=`o${s}`),c!==void 0&&(n+=`r${c}`),e!==void 0&&(n+=`s${e}`),i!==void 0&&(n+=`w${JSON.stringify(i)}`),u!==void 0&&(n+=`t${u}`),d!==void 0&&(n+=`f${d.toString()}`),n}function w(t,o={},s=[]){const{select:c}=o,e=S(()=>q({...o,select:void 0}),[o]),i=y();D(()=>{t.updateSearchOptions(e,{...o,select:void 0})},s),a(()=>()=>{t.clear(e)},[]);const u=f(l=>c?l.map(c):l,[c]),d=f(l=>t.subscribe(e,i,l),[t,e,i]),n=f(()=>t.getSnapshot(e),[t,e]),r=b(d,n,n,u);if(p(r),x(r)||h(r))throw r;const m=S(()=>({next:()=>t.next(e),reset:()=>t.refresh(e)}),[e,t]);return[r,m]}export{w as useSqliteValue};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muya",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "author": "samuel.gjabel@gmail.com",
5
5
  "repository": "https://github.com/samuelgjabel/muya",
6
6
  "main": "cjs/index.js",
@@ -17,7 +17,7 @@ export interface CreateSqliteOptions<Document extends DocType> extends Omit<DbOp
17
17
  export interface SyncTable<Document extends DocType> {
18
18
  // readonly registerSearch: <Selected = Document>(searchId: SearchId, options: SearchOptions<Document, Selected>) => () => void
19
19
  readonly updateSearchOptions: <Selected = Document>(searchId: SearchId, options: SearchOptions<Document, Selected>) => void
20
- readonly subscribe: (searchId: SearchId, listener: () => void) => () => void
20
+ readonly subscribe: (searchId: SearchId, componentId: string, listener: () => void) => () => void
21
21
  readonly getSnapshot: (searchId: SearchId) => Document[]
22
22
  readonly refresh: (searchId: SearchId) => Promise<void>
23
23
 
@@ -81,7 +81,7 @@ export function createSqliteState<Document extends DocType>(options: CreateSqlit
81
81
  }
82
82
  // const emitter = createEmitter<Table<Document>>()
83
83
  const cachedData = new Map<SearchId, DataItems<Document>>()
84
- const listeners = new Map<SearchId, () => void>()
84
+ const listeners = new Map<SearchId, Map<string, () => void>>()
85
85
  const iterators = new Map<SearchId, AsyncIterableIterator<NextResult>>()
86
86
 
87
87
  /**
@@ -123,7 +123,9 @@ export function createSqliteState<Document extends DocType>(options: CreateSqlit
123
123
  function notifyListeners(searchId: SearchId) {
124
124
  const searchListeners = listeners.get(searchId)
125
125
  if (searchListeners) {
126
- searchListeners()
126
+ for (const [, listener] of searchListeners) {
127
+ listener()
128
+ }
127
129
  }
128
130
  }
129
131
 
@@ -273,7 +275,7 @@ export function createSqliteState<Document extends DocType>(options: CreateSqlit
273
275
  STATE_SCHEDULER.schedule(scheduleId, { searchId })
274
276
  },
275
277
 
276
- subscribe(searchId, listener) {
278
+ subscribe(searchId, componentId, listener) {
277
279
  const scheduleId = getScheduleId(searchId)
278
280
  const clearScheduler = STATE_SCHEDULER.add(scheduleId, {
279
281
  onScheduleDone() {
@@ -283,10 +285,15 @@ export function createSqliteState<Document extends DocType>(options: CreateSqlit
283
285
  clearSchedulers.add(clearScheduler)
284
286
 
285
287
  if (!listeners.has(searchId)) {
286
- listeners.set(searchId, listener)
288
+ listeners.set(searchId, new Map())
287
289
  }
290
+ const searchListeners = listeners.get(searchId)!
291
+ searchListeners.set(componentId, listener)
288
292
  return () => {
289
- listeners.delete(searchId)
293
+ searchListeners.delete(componentId)
294
+ if (searchListeners.size === 0) {
295
+ listeners.delete(searchId)
296
+ }
290
297
  clearScheduler()
291
298
  }
292
299
  },
@@ -36,10 +36,10 @@ export function selectSql<Document extends DocType, Params extends unknown[] = [
36
36
  compute: (...args: Params) => SqlSeachOptions<Document>,
37
37
  ): CreateState<Document, Params> {
38
38
  const { subscribe, updateSearchOptions } = state
39
-
39
+ const componentId = getStateId()
40
40
  const result: CreateState<Document, Params> = (...params) => {
41
41
  const searchId = getStateId()
42
- const destroy = subscribe(searchId, () => {
42
+ const destroy = subscribe(searchId, componentId, () => {
43
43
  getState.emitter.emit()
44
44
  })
45
45
 
@@ -1,4 +1,4 @@
1
- import { useCallback, useDebugValue, useEffect, 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'
@@ -65,6 +65,7 @@ export function useSqliteValue<Document extends DocType, Selected = Document>(
65
65
  const { select } = options
66
66
 
67
67
  const searchId = useMemo(() => generateCacheKey({ ...options, select: undefined }), [options])
68
+ const componentId = useId()
68
69
 
69
70
  useLayoutEffect(() => {
70
71
  state.updateSearchOptions(searchId, { ...options, select: undefined })
@@ -88,9 +89,9 @@ export function useSqliteValue<Document extends DocType, Selected = Document>(
88
89
 
89
90
  const subscribe = useCallback(
90
91
  (onStorageChange: () => void) => {
91
- return state.subscribe(searchId, onStorageChange)
92
+ return state.subscribe(searchId, componentId, onStorageChange)
92
93
  },
93
- [state, searchId],
94
+ [state, searchId, componentId],
94
95
  )
95
96
 
96
97
  const getSnapshot = useCallback(() => {
@@ -8,7 +8,7 @@ export interface CreateSqliteOptions<Document extends DocType> extends Omit<DbOp
8
8
  }
9
9
  export interface SyncTable<Document extends DocType> {
10
10
  readonly updateSearchOptions: <Selected = Document>(searchId: SearchId, options: SearchOptions<Document, Selected>) => void;
11
- readonly subscribe: (searchId: SearchId, listener: () => void) => () => void;
11
+ readonly subscribe: (searchId: SearchId, componentId: string, listener: () => void) => () => void;
12
12
  readonly getSnapshot: (searchId: SearchId) => Document[];
13
13
  readonly refresh: (searchId: SearchId) => Promise<void>;
14
14
  readonly set: (document: Document) => Promise<MutationResult>;