fods v2.3.0
FODS (Frontend Operational Data Store)
Make frontend data request more controllable.
Install
npm i fodsUsage
import { source, query } from 'fods';
// import { source, query } from 'https://unpkg.com/fods';
// define a source
const UserBooks = source((uid) => {
    // return user' books
});
// query data from source
const userBooks = await query(UserBooks, '123');
// update data in source
renew(UserBooks, '123');Idea
- same source with same params should return same output until the source is renewed
- same request should not be send again when the request is runing
- multiple relative data should have their lifecycle management
A store is a place to put data in local, when we invoke
queryemitortake, we find some thing in local store and reuse them, so that we can reduce the real request count, and share data amoung requests.
API
source & query
Define a SOURCE_TYPE store by source and consume it by query.
import { source, query } from 'fods';
// define a source
const UserBooks = source((uid) => {
    // return user' books
});
// query data from source
const userBooks = await query(UserBooks, '123');
// update data in source
renew(UserBooks, '123');compose
Define a COMPOSE_TYPE store by compose and consume it by query.
import { compose, query } from 'fods';
const MyList = compose(
    (ids: string[]) => {
        // return result list array
    },
    // find value in result list to record cache
    // if undefined, ignored
    (res, id: string) => res.find(item => item.id === id),
);
const lite = await query(MyList, [1, 2]);
const all = await query(MyList, [1, 2, 3, 4]);
// here, we query 1, 2 twice, however, in fact same id will be query only once inside fods
renew(MyList, [2, 3]);Notice, the first parameter should be an array, and all of items should be same data type. The rest parameters will be passed.
const MyList = compose(
    (ids: string[], ...params: any[]) => {
        return Promise.all(ids.map(id => fetchData(id, ...params)))
    },
    (res, id: string) => res.find(item => item.id === id),
);
const lite = await query(MyList, [1, 2], 'var1', 'var2');action & take
Define a ACTION_TYPE store by action and consume it by take.
import { action, take } from 'fods';
const AddUserBook = action(async (book) => {
    // send save book request
    // after we add a new book, we should renew the UserBookList in store
    await renew(UserBookList);
});stream & subscribe
import { stream, subscribe } from 'fods';
const UserBookRepo = stream(({ ondata, onend, onerror }) => (uid) => {
    const stream = requestUserBooksStream(uid);
    stream.on('data', ondata);
    stream.on('end', onend);
    stream.on('error', onerror);
});
const emit = subscribe(UserBookRepo, {
    ondata(chunk) {},
    onend(chunks) {},
    onerror(e) {},
});
emit('123');renew
Clear store and request again.
const newData = await renew(SomeSource, '123');
const newSubscribe = await renew(SomeStream, '123');Renew stream will not request again, only clear store.
clear
Clear store.
clear(SomeSource, '123');read
Read from store without request.
const data = read(SomeSource, 123); // notice, without `await`request
Send a request with given source or stream outside the store.
const data = await request(SomeSource, 123); // without any affect to the storeRequest stream will return a Promise resolved when the end event be triggered.
isTypeOf
Check whether the given object is type of a usable type.
import { isTypeOf, SOURCE_TYPE, STREAM_TYPE, ACTION_TYPE } from 'fods';
if (isTypeOf(obj, SOURCE_TYPE, STREAM_TYPE)) {
    // ...
}addListener & removeListener
Watch store data change.
const listener = (params, data) => {
    const [uid] = params;
    if (uid === 123) {
        // do some thing with data
    }
};
const unlisten = addListener(SomeSource, 'change', listener);
removeListener(SomeSource, 'change', listener);
// or
unlisten();Events:
- Source & Compose: 'change' | 'beforeRenew' | 'afterRenew' | 'beforeClear' | 'afterClear'
- Stream: 'data' | 'end' | 'error' | 'beforeClear' | 'afterClear'
Quick Use
const queryBook = source((id) => {
    // ...
});
const book = await queryBook(123);
renew(queryBook, 123);const BookSource = source((id) => {
    // ...
});
const book = await BookSource.query(id);
BookSource.renew(id);- source, compose => query { query, request, renew, read, clear }
- stream => subscribe { subscribe, request, renew, read, clear }
- action => take { take, request }
const subscribeSomeStream = stream(({ ondata, onend, onerror }) => {
    // ...
});
const emit = subscribeSomeStream({
    ondata: () => {},
    onend: () => {},
    onerror: () => {},
});
emit('arg');8 months ago
8 months ago
12 months ago
12 months ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago