11import  useSWR ,  {  useSWRConfig  }  from  'swr' ; 
2- import  type  {  ScopedMutator  }  from  'swr/dist/types' ; 
2+ import  type  {  MutatorCallback ,   MutatorOptions  }  from  'swr/dist/types' ; 
33
44const  fetcher  =  async  ( url : string ,  options ?: RequestInit )  =>  { 
55    const  res  =  await  fetch ( url ,  options ) ; 
@@ -15,17 +15,17 @@ const fetcher = async (url: string, options?: RequestInit) => {
1515} ; 
1616
1717function  makeUrl ( url : string ,  args : unknown )  { 
18-     return  args  ? url  +  `q=${ encodeURIComponent ( JSON . stringify ( args ) ) }   : url ; 
18+     return  args  ? url  +  `? q=${ encodeURIComponent ( JSON . stringify ( args ) ) }   : url ; 
1919} 
2020
21- export  function  get < Data ,  Error  =  any > ( url : string ,  args ?: unknown )  { 
22-     return  useSWR < Data ,  Error > ( makeUrl ( url ,  args ) ,  fetcher ) ; 
21+ export  function  get < Data ,  Error  =  any > ( url : string   |   null ,  args ?: unknown )  { 
22+     return  useSWR < Data ,  Error > ( url   &&   makeUrl ( url ,  args ) ,  fetcher ) ; 
2323} 
2424
2525export  async  function  post < Data ,  Result > ( 
2626    url : string , 
2727    data : Data , 
28-     mutate : ScopedMutator < any > 
28+     mutate : Mutator 
2929)  { 
3030    const  r : Result  =  await  fetcher ( url ,  { 
3131        method : 'POST' , 
@@ -34,14 +34,14 @@ export async function post<Data, Result>(
3434        } , 
3535        body : JSON . stringify ( data ) , 
3636    } ) ; 
37-     mutate ( url ) ; 
37+     mutate ( url ,   true ) ; 
3838    return  r ; 
3939} 
4040
4141export  async  function  put < Data ,  Result > ( 
4242    url : string , 
4343    data : Data , 
44-     mutate : ScopedMutator < any > 
44+     mutate : Mutator 
4545)  { 
4646    const  r : Result  =  await  fetcher ( url ,  { 
4747        method : 'PUT' , 
@@ -50,26 +50,52 @@ export async function put<Data, Result>(
5050        } , 
5151        body : JSON . stringify ( data ) , 
5252    } ) ; 
53-     mutate ( url ,  r ) ; 
53+     mutate ( url ,  true ) ; 
5454    return  r ; 
5555} 
5656
57- export  async  function  del < Result > ( 
58-     url : string , 
59-     args : unknown , 
60-     mutate : ScopedMutator < any > 
61- )  { 
57+ export  async  function  del < Result > ( url : string ,  args : unknown ,  mutate : Mutator )  { 
6258    const  reqUrl  =  makeUrl ( url ,  args ) ; 
6359    const  r : Result  =  await  fetcher ( reqUrl ,  { 
6460        method : 'DELETE' , 
6561    } ) ; 
6662    const  path  =  url . split ( '/' ) ; 
6763    path . pop ( ) ; 
68-     mutate ( path . join ( '/' ) ) ; 
64+     mutate ( path . join ( '/' ) ,   true ) ; 
6965    return  r ; 
7066} 
7167
72- export  function  getMutate ( )  { 
73-     const  {  mutate }  =  useSWRConfig ( ) ; 
74-     return  mutate ; 
68+ type  Mutator  =  ( 
69+     key : string , 
70+     prefix : boolean , 
71+     data ?: any  |  Promise < any >  |  MutatorCallback , 
72+     opts ?: boolean  |  MutatorOptions 
73+ )  =>  Promise < any [ ] > ; 
74+ 
75+ export  function  getMutate ( ) : Mutator  { 
76+     // https://swr.vercel.app/docs/advanced/cache#mutate-multiple-keys-from-regex 
77+     const  {  cache,  mutate }  =  useSWRConfig ( ) ; 
78+     return  ( 
79+         key : string , 
80+         prefix : boolean , 
81+         data ?: any  |  Promise < any >  |  MutatorCallback , 
82+         opts ?: boolean  |  MutatorOptions 
83+     )  =>  { 
84+         if  ( ! prefix )  { 
85+             return  mutate ( key ,  data ,  opts ) ; 
86+         } 
87+ 
88+         if  ( ! ( cache  instanceof  Map ) )  { 
89+             throw  new  Error ( 
90+                 'mutate requires the cache provider to be a Map instance' 
91+             ) ; 
92+         } 
93+ 
94+         const  keys  =  Array . from ( cache . keys ( ) ) . filter ( 
95+             ( k )  =>  typeof  k  ===  'string'  &&  k . startsWith ( key ) 
96+         )  as  string [ ] ; 
97+         console . log ( 'Mutating keys:' ,  JSON . stringify ( keys ) ) ; 
98+         const  mutations  =  keys . map ( ( key )  =>  mutate ( key ,  data ,  opts ) ) ; 
99+         return  Promise . all ( mutations ) ; 
100+     } ; 
75101} 
0 commit comments