@@ -24,9 +24,9 @@ Just define your **Data models** & **Client HTTP methods**, then leave rest of t
2424``` json
2525{
2626 "dependencies" : {
27- "koajax" : " ^3.0 .0" ,
27+ "koajax" : " ^3.1 .0" ,
2828 "mobx" : " ^6.13.5" ,
29- "mobx-restful" : " ^2.0 .0"
29+ "mobx-restful" : " ^2.1 .0"
3030 }
3131}
3232```
@@ -217,10 +217,130 @@ export class MultipleRepository extends Stream<Repository>(RepositoryModel) {
217217export default new MultipleRepository ();
218218```
219219
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
221258
222259This module has been moved to [ MobX-downloader] [ 12 ] since MobX-RESTful v2.
223260
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+
224344## Wrapper
225345
2263461 . [ 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.
233353
234354## Scaffold
235355
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
239360
240361## Limitation
241362
242- - [ ] [ ` abstract ` hint of Mixin is missing] [ 11 ]
363+ - [ ] [ ` abstract ` hint of Mixin is missing] [ 14 ]
243364
244365[ 1 ] : https://mobx.js.org/
245366[ 2 ] : https://github.com/tc39/proposal-decorators
@@ -251,5 +372,7 @@ This module has been moved to [MobX-downloader][12] since MobX-RESTful v2.
251372[ 8 ] : https://pnpm.io/
252373[ 9 ] : https://joyeecheung.github.io/blog/2024/03/18/require-esm-in-node-js/
253374[ 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
255376[ 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