@@ -24,9 +24,9 @@ Just define your **Data models** & **Client HTTP methods**, then leave rest of t
24
24
``` json
25
25
{
26
26
"dependencies" : {
27
- "koajax" : " ^3.0 .0" ,
27
+ "koajax" : " ^3.1 .0" ,
28
28
"mobx" : " ^6.13.5" ,
29
- "mobx-restful" : " ^2.0 .0"
29
+ "mobx-restful" : " ^2.1 .0"
30
30
}
31
31
}
32
32
```
@@ -217,10 +217,130 @@ export class MultipleRepository extends Stream<Repository>(RepositoryModel) {
217
217
export default new MultipleRepository ();
218
218
```
219
219
220
- ### File Downloader
220
+ ### Data Persistence
221
+
222
+ ` @persist() ` & ` restore() ` functions give us a declarative way to save & restore data to/from [ IndexedBD] [ 11 ] , such as these following examples:
223
+
224
+ #### User Session
225
+
226
+ ``` ts
227
+ import { observable } from ' mobx' ;
228
+ import { BaseModel , persist , restore , toggle } from ' mobx-restful' ;
229
+ import { Day } from ' web-utility' ;
230
+
231
+ import { client } from ' ./client' ;
232
+ import { User } from ' ./User' ;
233
+
234
+ export class SessionModel extends BaseModel {
235
+ baseURI = ' session' ;
236
+ client = client ;
237
+
238
+ @persist ({ expireIn: 15 * Day })
239
+ @observable
240
+ user? : User ;
241
+
242
+ restored = restore (this , ' Session' );
243
+
244
+ @toggle (' uploading' )
245
+ async signIn(username : string , password : string ) {
246
+ const { body } = await this .client .post <User >(' session' , {
247
+ username ,
248
+ password
249
+ });
250
+ return (this .user = body );
251
+ }
252
+ }
253
+
254
+ export default new Session ();
255
+ ```
256
+
257
+ #### File Downloader
221
258
222
259
This module has been moved to [ MobX-downloader] [ 12 ] since MobX-RESTful v2.
223
260
261
+ #### List Cache
262
+
263
+ ##### ` model/Party/Gift.ts `
264
+
265
+ ``` ts
266
+ import { ListModel , persistList } from ' mobx-restful' ;
267
+
268
+ import { Gift } from ' @my-scope/service-type' ;
269
+
270
+ import { client } from ' ./client' ;
271
+
272
+ @persistList ({
273
+ storeKey : ({ partyId }) => ` PartyGift-${partyId } ` ,
274
+ expireIn: 2 * Day
275
+ })
276
+ export class PartyGiftModel extends ListModel <Gift > {
277
+ baseURI = ' party' ;
278
+ client = client ;
279
+
280
+ constructor (public partyId : number ) {
281
+ super ();
282
+ this .baseURI += ` /${partyId }/gift ` ;
283
+ }
284
+
285
+ protected async loadPage(pageIndex : number , pageSize : number ) {
286
+ const { body } = await this .client .get <{
287
+ count: number ;
288
+ list: Gift [];
289
+ }>(` ${this .baseURI }?${buildURLData ({ pageIndex , pageSize })} ` );
290
+
291
+ return { pageData: body .list , totalCount: body .count };
292
+ }
293
+ }
294
+ ```
295
+
296
+ ##### ` page/Party/Gift.tsx `
297
+
298
+ This example page uses [ Cell Router] [ 13 ] to pass in ` partyId ` route parameter:
299
+
300
+ ``` tsx
301
+ import { observable } from ' mobx' ;
302
+ import { component , observer , attribute } from ' web-cell' ;
303
+
304
+ import { PartyGiftModel } from ' ../../model/Party/Gift' ;
305
+
306
+ @component ({ tagName: ' party-gift-page' })
307
+ @observer
308
+ export class PartyGiftPage extends HTMLElement {
309
+ @attribute
310
+ @observable
311
+ accessor partyId = 0 ;
312
+
313
+ @observable
314
+ accessor store: PartyGiftModel | undefined ;
315
+
316
+ async connectedCallback() {
317
+ this .store = new PartyGiftModel (this .partyId );
318
+
319
+ await this .store .restored ;
320
+ // this calling will do nothing after the first loading
321
+ // in list cache period
322
+ await this .store .getAll ();
323
+ }
324
+
325
+ render() {
326
+ const { allItem } = this .store || {};
327
+
328
+ return (
329
+ <>
330
+ <h1 >Gift wall</h1 >
331
+ <ol >
332
+ { allItem .map (({ name , price }) => (
333
+ <li key = { name } >
334
+ { name } - { price }
335
+ </li >
336
+ ))}
337
+ </ol >
338
+ </>
339
+ );
340
+ }
341
+ }
342
+ ```
343
+
224
344
## Wrapper
225
345
226
346
1 . [ Strapi v4] ( https://github.com/idea2app/MobX-RESTful/blob/main/wrapper/Strapi )
@@ -233,13 +353,14 @@ This module has been moved to [MobX-downloader][12] since MobX-RESTful v2.
233
353
234
354
## Scaffold
235
355
236
- 1 . Client-side Rendering (React): https://github.com/idea2app/Next-Bootstrap-ts
237
- 2 . Server-side Rendering (React): https://github.com/idea2app/React-MobX-Bootstrap-ts
238
- 3 . Cross-end App (React): https://github.com/idea2app/Taro-Vant-MobX-ts
356
+ 1 . Client-side Rendering (React): https://github.com/idea2app/React-MobX-Bootstrap-ts
357
+ 2 . Client-side Rendering (Vue): https://github.com/idea2app/Vue-MobX-Prime-ts
358
+ 3 . Server-side Rendering (React): https://github.com/idea2app/Next-Bootstrap-ts
359
+ 4 . Cross-end App (React): https://github.com/idea2app/Taro-Vant-MobX-ts
239
360
240
361
## Limitation
241
362
242
- - [ ] [ ` abstract ` hint of Mixin is missing] [ 11 ]
363
+ - [ ] [ ` abstract ` hint of Mixin is missing] [ 14 ]
243
364
244
365
[ 1 ] : https://mobx.js.org/
245
366
[ 2 ] : https://github.com/tc39/proposal-decorators
@@ -251,5 +372,7 @@ This module has been moved to [MobX-downloader][12] since MobX-RESTful v2.
251
372
[ 8 ] : https://pnpm.io/
252
373
[ 9 ] : https://joyeecheung.github.io/blog/2024/03/18/require-esm-in-node-js/
253
374
[ 10 ] : https://github.com/EasyWebApp/WebCell
254
- [ 11 ] : https://github.com/microsoft/TypeScript/issues/39752#issuecomment-1239810720
375
+ [ 11 ] : https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API
255
376
[ 12 ] : https://github.com/idea2app/MobX-downloader
377
+ [ 13 ] : https://github.com/EasyWebApp/cell-router
378
+ [ 14 ] : https://github.com/microsoft/TypeScript/issues/39752#issuecomment-1239810720
0 commit comments