@@ -25,12 +25,12 @@ import localforage from 'localforage';
2525 * @example // initialize with no data
2626 *
2727 * import localForageDataProvider from 'ra-data-local-forage';
28- * const dataProvider = await localForageDataProvider();
28+ * const dataProvider = localForageDataProvider();
2929 *
3030 * @example // initialize with default data (will be ignored if data has been modified by user)
3131 *
3232 * import localForageDataProvider from 'ra-data-local-forage';
33- * const dataProvider = await localForageDataProvider({
33+ * const dataProvider = localForageDataProvider({
3434 * defaultData: {
3535 * posts: [
3636 * { id: 0, title: 'Hello, world!' },
@@ -43,15 +43,17 @@ import localforage from 'localforage';
4343 * }
4444 * });
4545 */
46- export default async (
47- params ?: LocalForageDataProviderParams
48- ) : Promise < DataProvider > => {
46+ export default ( params ?: LocalForageDataProviderParams ) : DataProvider => {
4947 const {
5048 defaultData = { } ,
5149 prefixLocalForageKey = 'ra-data-local-forage-' ,
5250 loggingEnabled = false ,
5351 } = params || { } ;
5452
53+ let data : Record < string , any > | undefined ;
54+ let baseDataProvider : DataProvider | undefined ;
55+ let initializePromise : Promise < void > | undefined ;
56+
5557 const getLocalForageData = async ( ) : Promise < any > => {
5658 const keys = await localforage . keys ( ) ;
5759 const keyFiltered = keys . filter ( key => {
@@ -71,28 +73,44 @@ export default async (
7173 return localForageData ;
7274 } ;
7375
74- const localForageData = await getLocalForageData ( ) ;
75- const data = localForageData ?? defaultData ;
76+ const initialize = async ( ) => {
77+ if ( ! initializePromise ) {
78+ initializePromise = initializeProvider ( ) ;
79+ }
80+ return initializePromise ;
81+ } ;
82+
83+ const initializeProvider = async ( ) => {
84+ const localForageData = await getLocalForageData ( ) ;
85+ data = localForageData ?? defaultData ;
86+
87+ baseDataProvider = fakeRestProvider (
88+ data ,
89+ loggingEnabled
90+ ) as DataProvider ;
91+ } ;
7692
7793 // Persist in localForage
7894 const updateLocalForage = ( resource : string ) => {
95+ if ( ! data ) {
96+ throw new Error ( 'The dataProvider is not initialized.' ) ;
97+ }
7998 localforage . setItem (
8099 `${ prefixLocalForageKey } ${ resource } ` ,
81100 data [ resource ]
82101 ) ;
83102 } ;
84103
85- const baseDataProvider = fakeRestProvider (
86- data ,
87- loggingEnabled
88- ) as DataProvider ;
89-
90104 return {
91105 // read methods are just proxies to FakeRest
92- getList : < RecordType extends RaRecord = any > (
106+ getList : async < RecordType extends RaRecord = any > (
93107 resource : string ,
94108 params : GetListParams
95109 ) => {
110+ await initialize ( ) ;
111+ if ( ! baseDataProvider ) {
112+ throw new Error ( 'The dataProvider is not initialized.' ) ;
113+ }
96114 return baseDataProvider
97115 . getList < RecordType > ( resource , params )
98116 . catch ( error => {
@@ -104,19 +122,35 @@ export default async (
104122 }
105123 } ) ;
106124 } ,
107- getOne : < RecordType extends RaRecord = any > (
125+ getOne : async < RecordType extends RaRecord = any > (
108126 resource : string ,
109127 params : GetOneParams < any >
110- ) => baseDataProvider . getOne < RecordType > ( resource , params ) ,
111- getMany : < RecordType extends RaRecord = any > (
128+ ) => {
129+ await initialize ( ) ;
130+ if ( ! baseDataProvider ) {
131+ throw new Error ( 'The dataProvider is not initialized.' ) ;
132+ }
133+ return baseDataProvider . getOne < RecordType > ( resource , params ) ;
134+ } ,
135+ getMany : async < RecordType extends RaRecord = any > (
112136 resource : string ,
113137 params : GetManyParams < RecordType >
114- ) => baseDataProvider . getMany < RecordType > ( resource , params ) ,
115- getManyReference : < RecordType extends RaRecord = any > (
138+ ) => {
139+ await initialize ( ) ;
140+ if ( ! baseDataProvider ) {
141+ throw new Error ( 'The dataProvider is not initialized.' ) ;
142+ }
143+ return baseDataProvider . getMany < RecordType > ( resource , params ) ;
144+ } ,
145+ getManyReference : async < RecordType extends RaRecord = any > (
116146 resource : string ,
117147 params : GetManyReferenceParams
118- ) =>
119- baseDataProvider
148+ ) => {
149+ await initialize ( ) ;
150+ if ( ! baseDataProvider ) {
151+ throw new Error ( 'The dataProvider is not initialized.' ) ;
152+ }
153+ return baseDataProvider
120154 . getManyReference < RecordType > ( resource , params )
121155 . catch ( error => {
122156 if ( error . code === 1 ) {
@@ -125,13 +159,22 @@ export default async (
125159 } else {
126160 throw error ;
127161 }
128- } ) ,
162+ } ) ;
163+ } ,
129164
130165 // update methods need to persist changes in localForage
131- update : < RecordType extends RaRecord = any > (
166+ update : async < RecordType extends RaRecord = any > (
132167 resource : string ,
133168 params : UpdateParams < any >
134169 ) => {
170+ await initialize ( ) ;
171+ if ( ! data ) {
172+ throw new Error ( 'The dataProvider is not initialized.' ) ;
173+ }
174+ if ( ! baseDataProvider ) {
175+ throw new Error ( 'The dataProvider is not initialized.' ) ;
176+ }
177+
135178 const index = data [ resource ] . findIndex (
136179 ( record : { id : any } ) => record . id === params . id
137180 ) ;
@@ -142,8 +185,16 @@ export default async (
142185 updateLocalForage ( resource ) ;
143186 return baseDataProvider . update < RecordType > ( resource , params ) ;
144187 } ,
145- updateMany : ( resource : string , params : UpdateManyParams < any > ) => {
188+ updateMany : async ( resource : string , params : UpdateManyParams < any > ) => {
189+ await initialize ( ) ;
190+ if ( ! baseDataProvider ) {
191+ throw new Error ( 'The dataProvider is not initialized.' ) ;
192+ }
193+
146194 params . ids . forEach ( ( id : Identifier ) => {
195+ if ( ! data ) {
196+ throw new Error ( 'The dataProvider is not initialized.' ) ;
197+ }
147198 const index = data [ resource ] . findIndex (
148199 ( record : { id : Identifier } ) => record . id === id
149200 ) ;
@@ -155,14 +206,21 @@ export default async (
155206 updateLocalForage ( resource ) ;
156207 return baseDataProvider . updateMany ( resource , params ) ;
157208 } ,
158- create : < RecordType extends Omit < RaRecord , 'id' > = any > (
209+ create : async < RecordType extends Omit < RaRecord , 'id' > = any > (
159210 resource : string ,
160211 params : CreateParams < any >
161212 ) => {
213+ await initialize ( ) ;
214+ if ( ! baseDataProvider ) {
215+ throw new Error ( 'The dataProvider is not initialized.' ) ;
216+ }
162217 // we need to call the fakerest provider first to get the generated id
163218 return baseDataProvider
164219 . create < RecordType > ( resource , params )
165220 . then ( response => {
221+ if ( ! data ) {
222+ throw new Error ( 'The dataProvider is not initialized.' ) ;
223+ }
166224 if ( ! data . hasOwnProperty ( resource ) ) {
167225 data [ resource ] = [ ] ;
168226 }
@@ -171,21 +229,40 @@ export default async (
171229 return response ;
172230 } ) ;
173231 } ,
174- delete : < RecordType extends RaRecord = any > (
232+ delete : async < RecordType extends RaRecord = any > (
175233 resource : string ,
176234 params : DeleteParams < RecordType >
177235 ) => {
236+ await initialize ( ) ;
237+ if ( ! baseDataProvider ) {
238+ throw new Error ( 'The dataProvider is not initialized.' ) ;
239+ }
240+ if ( ! data ) {
241+ throw new Error ( 'The dataProvider is not initialized.' ) ;
242+ }
178243 const index = data [ resource ] . findIndex (
179244 ( record : { id : any } ) => record . id === params . id
180245 ) ;
181246 pullAt ( data [ resource ] , [ index ] ) ;
182247 updateLocalForage ( resource ) ;
183248 return baseDataProvider . delete < RecordType > ( resource , params ) ;
184249 } ,
185- deleteMany : ( resource : string , params : DeleteManyParams < any > ) => {
186- const indexes = params . ids . map ( ( id : any ) =>
187- data [ resource ] . findIndex ( ( record : any ) => record . id === id )
188- ) ;
250+ deleteMany : async ( resource : string , params : DeleteManyParams < any > ) => {
251+ await initialize ( ) ;
252+ if ( ! baseDataProvider ) {
253+ throw new Error ( 'The dataProvider is not initialized.' ) ;
254+ }
255+ if ( ! data ) {
256+ throw new Error ( 'The dataProvider is not initialized.' ) ;
257+ }
258+ const indexes = params . ids . map ( ( id : any ) => {
259+ if ( ! data ) {
260+ throw new Error ( 'The dataProvider is not initialized.' ) ;
261+ }
262+ return data [ resource ] . findIndex (
263+ ( record : any ) => record . id === id
264+ ) ;
265+ } ) ;
189266 pullAt ( data [ resource ] , indexes ) ;
190267 updateLocalForage ( resource ) ;
191268 return baseDataProvider . deleteMany ( resource , params ) ;
0 commit comments