New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

fods

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fods

Frontend Operational Data Store

latest
Source
npmnpm
Version
2.3.0
Version published
Maintainers
1
Created
Source

FODS (Frontend Operational Data Store)

Make frontend data request more controllable.

Install

npm i fods

Usage

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 query emit or take, 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 store

Request 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');

FAQs

Package last updated on 23 Feb 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts