NOT MAINTAINED – A small, simple and immutable ORM to manage relational data in your Redux store.
orm.<Model>
selectors only returning array elements for existing IDs (when passing an ID array):const publishers = createSelector(orm.Publisher);
publishers(orm.getEmptyState(), [1, 2, 3]); // before: []
publishers(orm.getEmptyState(), [1, 2, 3]); // after: [null, null, null]
This allows you to know which of the publishers exist and which don't.
createSelector
. Pass it to the ORM
constructor instead:-const someSelector = createSelector(orm, state => state.orm, …);
+const someSelector = createSelector(orm, …);
-const orm = new ORM();
+const orm = new ORM({
+ stateSelector: state => state.orm,
+});
const movies = createSelector(orm.Movie);
movies(state); // ref array of all movies
movies(state, 1); // ref of movie with ID 1
movies(state, [1, 2, 3]); // ref array of movies with ID 1, 2 and 3
const moviePublisher = createSelector(orm.Movie.publisher);
moviePublisher(state); // ref array of each movie's publisher
moviePublisher(state, 1); // ref of the first movie's publisher
moviePublisher(state, [1, 2, 3]); // publisher ref array of each of the movies with ID 1, 2 and 3
const coverBookAuthors = createSelector(orm.Cover.book.authors);
// If the cover or its book don't exist, null is returned:
coverBookAuthors(orm.getEmptyState()); // []
coverBookAuthors(orm.getEmptyState(), 1); // null
coverBookAuthors(orm.getEmptyState(), [1, 2, 3]); // [null, null, null]
const bookAuthors = createSelector(orm.Book.authors);
const genreAuthors = createSelector(orm.Genre.books.map(bookAuthors));
The following would work as well and is equivalent:
const genreAuthors = createSelector(orm.Genre.books.map(orm.Book.authors));
const avg = arr => arr.reduce((a, b) => a + b, 0) / arr.length;
const publisherAverageRating = createSelector(
orm.Publisher.movies.map(orm.Movie.rating),
ratings => ratings && (ratings.length ? avg(ratings) : 'no movies')
);
ORM
instance at any position of createSelector
and get a session at the corresponding position in the result function's argument list:const someSelector = createSelector(
[ a, b, orm, d], // a, b and d being selectors
(_a, _b, session, _d) => session.User.count()
);
orm
to createSelector()
as a replacement for passing the previous state selector function.const publisherAverageRating = createSelector(
orm.Publisher.movies.map(orm.Movie.rating),
(state, idArg) => idArg,
(ratingsArg, idArg) => {
if (typeof idArg === 'undefined' || Array.isArray(idArg)) {
// only state was passed, or an array of IDs
return ratingsArg.map(
ratings => ratings && ratings.length ? avg(ratings) : 'no movies'
);
}
// single publisher ID was passed
return ratingsArg && (ratingsArg.length ? avg(ratingsArg) : 'no movies');
}
);
lodash/mapValues
by ES8 Object.entries.reduce
.Optimized full bundles using babel-plugin-lodash
and lodash-webpack-plugin
:
dist/redux-orm.min.js
decreased from 67.7 kB to 48.5 kB.Removed tests, coverage reports and other unneeded files from NPM package builds. This decreased our NPM package size to around 700 kB.
book.authors
will be optimized if the Author
model has a fk({ to: 'Book', 'relatedName': 'authors' })
field. (#250, b9c16359f018dacfaaea8b5450693eea3263ffe9)This release should be non-breaking, however it does slightly decrease performance of writes. Many-to-many queries (e.g. child.parents
) are also less performant, but in theory it is now possible to optimize them by an order of magnitude (similar to SQL joins).
mapName
using Model.options
. (0fb2aca3a46c7fd653bf3f0d9c8c4f937b745e7c)Object.keys()
instead of Object.entries()
. (e371ac7161a541be41bfdaf22cd4689f1c486349)sideEffects: false
in package.json
for tree-shaking.Thanks to @Chris-Congenica and @abilicz for improving Redux-ORM's user experience!
modelName
set. (#231)session
. (#237)es/
(pkg.module
) is now ES5 compatible. (#216, #221)as
option to foreign key fields (fk()
) to have Redux-ORM create a separate field for their accessors so as to not override foreign key references (#219):class Movie extends Model {};
Movie.fields = {
publisherId: fk({
to: 'Publisher',
as: 'publisher',
relatedName: 'movies',
}),
};
Publisher.create({ id: 123 });
const movie = Movie.create({ publisherId: 123 });
movie.publisherId // 123
movie.publisher.id === movie.publisherId // true