1 | # Daux
|
2 |
|
3 | An immutable model-based state management solution for your JavaScript apps.
|
4 |
|
5 | ## Design
|
6 |
|
7 | The library was built by combining some of the concepts of [Ember Data](https://github.com/emberjs/data) and [Redux](https://github.com/reduxjs/redux).
|
8 |
|
9 | Most apps have a model-based state that might look like this:
|
10 |
|
11 | ```json
|
12 | {
|
13 | "user": {
|
14 | "user_a": {
|
15 | "name": "John Doe",
|
16 | "country": "country_a",
|
17 | "groups": [
|
18 | "group_a"
|
19 | ],
|
20 | "posts": [
|
21 | "post_a"
|
22 | ]
|
23 | }
|
24 | },
|
25 | "country": {
|
26 | "country_a": {
|
27 | "name": "United States of America"
|
28 | }
|
29 | },
|
30 | "group": {
|
31 | "group_a": {
|
32 | "name": "Hikers Club",
|
33 | "members": [
|
34 | "user_a"
|
35 | ]
|
36 | }
|
37 | },
|
38 | "post": {
|
39 | "post_a": {
|
40 | "title": "When is the next hike?",
|
41 | "author": "user_a"
|
42 | }
|
43 | }
|
44 | }
|
45 | ```
|
46 |
|
47 | In Daux, these kind of states are managed by the `Store`. With it, you'll be able to create, read, update, and delete model records.
|
48 |
|
49 | ## Installation
|
50 |
|
51 | Assuming that you're using [npm](https://www.npmjs.com/) as your package manager:
|
52 |
|
53 | ```
|
54 | npm install daux
|
55 | ```
|
56 |
|
57 | If you're not using any module bundler, you can use the precompiled production and development [UMD](https://github.com/umdjs/umd) builds in the `dist` folder. For this build, `Daux` would be available as a `window.Daux` global variable. You can download the files at [unpkg](https://unpkg.com/daux/).
|
58 |
|
59 | ## Usage
|
60 |
|
61 | Check out the [API reference](API.md)
|
62 |
|
63 | ### Setup your models
|
64 |
|
65 | Create your models
|
66 |
|
67 | ```javascript
|
68 | import { Model, Store } from 'daux';
|
69 |
|
70 | class User extends Model {
|
71 | static get attributes() {
|
72 | return ['name'];
|
73 | }
|
74 |
|
75 | static get relationship() {
|
76 | return {
|
77 | country: {
|
78 | type: 'country',
|
79 | kind: 'belongsTo',
|
80 | inverse: null,
|
81 | },
|
82 | groups: {
|
83 | type: 'group',
|
84 | kind: 'hasMany',
|
85 | inverse: 'members',
|
86 | },
|
87 | posts: {
|
88 | type: 'post',
|
89 | kind: 'hasMany',
|
90 | inverse: 'author',
|
91 | },
|
92 | };
|
93 | }
|
94 |
|
95 | /**
|
96 | * Optional hook to deserialize a record
|
97 | */
|
98 | static deserialize(record) {
|
99 | const deserializedRecord = {};
|
100 |
|
101 | Object.keys(record).forEach((key) => {
|
102 | // Use name instead of display_name to match the model attributes
|
103 | if (key === 'display_name') {
|
104 | deserializedRecord['name'] = record[key];
|
105 | }
|
106 | });
|
107 |
|
108 | return deserializedRecord;
|
109 | }
|
110 | }
|
111 | ```
|
112 |
|
113 | Next, we pass-in those models to the `Store`:
|
114 |
|
115 | ```javascript
|
116 | const store = new Store({
|
117 | user: User
|
118 | });
|
119 | ```
|
120 |
|
121 | ### Fetching states
|
122 |
|
123 | ```javascript
|
124 | async function fetchUsers() {
|
125 | return store.getAll('user', {
|
126 | fetch() {
|
127 | return fetch('example.com/api/users').then((response) => {
|
128 | return response.json();
|
129 | });
|
130 | }
|
131 | });
|
132 | }
|
133 | ```
|
134 |
|
135 | ### Changing states
|
136 |
|
137 | ```javascript
|
138 | async function createUser(newUser) {
|
139 | await fetch('example.com/api/users', {
|
140 | method: 'POST',
|
141 | body: JSON.stringify(newUser)
|
142 | });
|
143 | store.set('user', newUser);
|
144 | }
|
145 | ```
|
146 |
|
147 | ### Subscribing to state changes
|
148 |
|
149 | ```javascript
|
150 | // Log "Foo" everytime a state changes
|
151 | const unsubscribe = store.subscribe(() => console.log('Foo'));
|
152 |
|
153 | // Stop listening to state changes
|
154 | unsubscribe();
|
155 | ```
|
156 |
|
157 | ## Contributing
|
158 |
|
159 | ### Installation
|
160 |
|
161 | * `git clone <repository-url>`
|
162 | * `cd daux`
|
163 | * `npm install`
|
164 |
|
165 | ### Running tests
|
166 |
|
167 | * `npm test`
|
168 |
|
169 | ## License
|
170 |
|
171 | This project is licensed under the [MIT License](LICENSE.md).
|