Giter Site home page Giter Site logo

redux-db's Introduction

logo

NPM downloads NPM package

redux-db provides a normalized redux store and easy object management.

Why

Having a normalized state is a good strategy if your data is nested in different ways. The redux documentation has a nice explanation here.

How

import db from "./schema";
 export const dbReducer = db.combineReducers(
    (session, action) => {
        const { BlogPost, Comment, User } = session;
         switch (action.type) {
            case "POSTS_FETCH_DONE":
            case "POST_FETCH_DONE":
            case "POST_UPDATE":
            case "POST_INSERT":
                // all these actions may be handled using just one statement.
                // the upsert method accepts both single objects and arrays.
                // the payload is automatically normalized and related tables are also updated.
                 BlogPost.upsert(action.payload);
                break;
             case "POST_DELETE": {
                const { id } = action.payload;
                const post = BlogPost.get(id);
                 post.comments.delete(); // Could be skipped if cascading deletes are defined.
                post.delete();
                 // or just, BlogPost.delete( id );
                break;
            }
            case "COMMENT_UPDATE":
            case "COMMENT_INSERT": {
                // assuming payload contains {id,post,author}
                const { post } = action.payload;
                 BlogPost.get(post).comments.add(action.payload);
                // or just, Comment.upsert(action.payload);
                break;
            }
            case "COMMENT_DELETE": {
                const { id } = action.payload;
                Comment.delete(id);
                break;
            }
        }
    }
);

Documentation

Head over to http://redux-db.readthedocs.io.

Examples

You will find an extensive example using redux-db to create a basic "todo" app in the /examples folder.

Contact / feedback

Feel free to create issues and PR's.

Dependencies

  • none

Performance & size

redux-db uses internal indexes to speed up lookups and is quite fast at the current state. However, optimizing performance and build size is a high priority forward. Current size is small, only ~5K minified and gzipped.

Credits

This project is inspired by libraries such as normalizr and redux-orm. redux-db is however a complete rewrite and only lends it's basic consepts.

Changelog

v0.9.0

  • Bugfixes and improvements

v0.8.0

  • Added support for providing a custom model factory.
  • BREAKING CHANGE: some exported interfaces are renamed
    • Record => TableRecord
    • RecordSet => TableRecordSet

v0.7.0

  • Added support for PK fields to also reference foreign tables.
  • Improved error handling for some cases.
  • BREAKING CHANGE: the field type "FK" is removed. Instead it is implied from the usage of the "references" definition.
  • Docs is updated to latest changes and features.

v0.6.0

  • Added support for one 2 one relationships
  • Added support for cascading deletes
  • Improved typings
  • Minor optimizations

redux-db's People

Contributors

msolvaag avatar paulspiteri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

redux-db's Issues

Comparison to redux-orm

Hi! Could you elaborate a bit on the reasoning behind creating this lib? How is it different to redux-orm? What would be a use case when one chooses this lib over redux-orm?

Typescript typings

Hi
Is there a reason why the types such as TableRecord have the value as any? Surely this should be a < T > ?

Also, it seems like one-to-one table relationships aren't really supported - is that right?

Otherwise, great project!

Id merge operation violates unique constraint for id

I am using redux-db with react-native, I have a Configuration Table so, when the app runs for the first time i need to initialize the Configuration table with some values, to achieve that i tried to insert the values in my default reducer case .
default: Configuration.insert({ phone: "1", confirmResult: '', loggedIn:false }); return session.commit();
but when the app start it's showing an error Id merge operation violates unique constraint for id: "1"
what is the problem?
and is there a better solution to initialize a table.

Upsert should accept IModelRecord properties too not just IModel

In typescript, we will get an error if we try to upsert an object literal that includes more properties than IModel.

e.g.

const bankAccount = Thing.upsert({
        name: 'Bank Account',
        description: 'Your personal bank account.',
        properties: [
            {
                name: 'IBAN',
                description: 'International Bank Account Number',
            },
            { name: 'Balance', description: 'The current balance' },
        ],
    });

In this, properties is a problem, since it doesn't exist on the model type IThing - it's a FK relation declared on IThingRecord, instead.

But, in order to take advantage of the normalizing features, I want to upsert properties under the bank account in a denormalized way.

I wonder if Upsert accepted the record type merged with the model type, whether we could work with the denormalized data in a type safe way?

Re-think relationship with redux

I think it's interesting that redux-db and redux-orm include the word 'redux' in their name, when they're quite decoupled from it. They just handle work with normalized data structures in an immutable way.

Their goal is extremely valuable, and useful in many scenarios. In my mind, something generic like 'object-db' and a clean break from redux would make sense.

What are your thoughts?

Add support for computed properties

Computed properties could:

  • Ease deserialization through selectors.
  • Provide "MODIFIED" flag to prevent updating identical records.
  • Provide primary keys for relational tables.

Consider how to support single record data

Currently the only way to access "single record" data is to model it as a table or put it in regular redux, outside of the db.
The problem with putting it outside of the db is that the db-reducers don't receive the redux state. Perhaps that would be the simple solution.

Thanks again, really great project.

Add and use indexes automatically

When referencing many to many relations through properties current impl is slow. It should use prebuildt indexes for faster lookups. The indexes must be automatically maintained during update/insert ops.

FK reference properties in TableRecords return values of type 'any'.

All my one-to-many FK reference properties seem to return the value's type as any[]. Take this for example:

Where my schema is set up as:

interface IThingRecord extends TableRecord<IThing> {
    linksFrom: TableRecordSet<ILinkRecord>;
    linksTo: TableRecordSet<ILinkRecord>;
    properties: TableRecordSet<IPropertyRecord>;
}

interface ILinkRecord extends TableRecord<ILink> {
    fromThing: IThingRecord;
    toThing: IThingRecord;
}

export type ThingTable = Table<IThing, IThingRecord>;
export type LinkTable = Table<ILink, ILinkRecord>;
export interface ISession extends TableMap {
    Thing: ThingTable;
    Link: LinkTable;
}

export const db = createDatabase({
    Thing: {
        id: { type: 'PK' },
    },
    Link: {
        id: { type: 'PK' },
        fromThingId: { propName: 'fromThing', references: 'Thing', relationName: 'linksFrom' },
        toThingId: { propName: 'toThing', references: 'Thing', relationName: 'linksTo' },
    },
});

(IThing & ILink are just id, name and description)

Then I do:

db.selectTables<ISession>(state.schema.current).Thing.get(1).linksTo.value

And when I try to get links that belong to my 'thing', the return type of value is any[].

The linksTo property is TableRecordSet<ILinkRecord, any> where it should be TableRecordSet<ILinkRecord, ILink>.

Non-array FK properties are fine. e.g.

db.selectTables<ISession>(state.schema.current).Link.get(1).fromThing.value

Best hook to generate uids for missing PKs?

On upserts, it would be nice to have PKs generated for new records, whenever they're missing. A simple uid would suffice.

I do this currently with a custom ModelFactory/TableModel that overrides upsert and injects the PK if missing, but this still fails if I try to upsert any denormalized data -> the normalization process also requires PKs no nested entities.

If we assume that any record without a PK, should simply have a uid created for it, how could we achieve this in redux-db?

Saving with related data

Given the following schema:

const schema: ReduxDB.Schema = {
User: {
    id: { type: "PK" },
    name: { type: "ATTR" },
    modifiedDate: { type: "MODIFIED" }
  },
Post: {
    id: { type: "PK" },
    author: { references: "User", relationName: "posts" },
    modifiedDate: { type: "MODIFIED" },
  }
};

I was under the impression that creating a Post with the following structure would automatically assign the already created user to the newly created post:

Post.upsert({
id: Date.now().toString(),
        title: form.title,
        body: form.body,
        authorId: form.authorId, // --> the id of al already existing user
        createdDate: new Date,
        modifiedDate: new Date,
})

My question is if this is the proper way to create a post or if i need to fetch the user and assign it to the author property when creating the post.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.