@anfenn/zync 0.1.17 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +89 -0
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,10 +6,12 @@ Unopinionated, bullet-proof, offline-first sync middleware for Zustand.
6
6
 
7
7
  ## Benefits
8
8
 
9
+ - Simple to sync any state with a backend
9
10
  - Uses the official persist middleware as the local storage (localStorage, IndexedDB, etc.)
10
11
  - Zync's persistWithSync() is a drop-in replacement for Zustand's persist()
11
12
  - Allows for idiomatic use of Zustand
12
13
  - Leaves the api requests up to you (RESTful, GraphQL, etc.), just provide add(), update(), remove() and list()
14
+ - **_Coming soon_**: Customisable conflict resolution. Currently last-write-wins.
13
15
 
14
16
  ## Requirements
15
17
 
@@ -123,6 +125,89 @@ useStore.sync.enable(true | false);
123
125
  useStore.sync.startFirstLoad();
124
126
  ```
125
127
 
128
+ ### In your API:
129
+ *(Supabase example, but could be fetch, GraphQL, etc.)*
130
+
131
+ ```ts
132
+ import { ApiFunctions } from '@anfenn/zync';
133
+ import { supabase } from './supabase';
134
+
135
+ export type Fact = {
136
+ _localId: string;
137
+ fact: string;
138
+ // Server assigned fields
139
+ id?: number;
140
+ updated_at?: string;
141
+ };
142
+
143
+ export const factApi: ApiFunctions = { add, update, remove, list, firstLoad };
144
+
145
+ async function add(item: any): Promise<any | undefined> {
146
+ const { data, error } = await supabase.from('fact').insert(item).select();
147
+
148
+ if (error) {
149
+ // Throw errors to cause Zync to retry
150
+ throw new Error(error.message);
151
+ }
152
+
153
+ if (data && data.length > 0) {
154
+ // Must return server id, and any other fields you want merged in
155
+ return { id: data[0].id };
156
+ }
157
+ }
158
+
159
+ async function update(id: number, changes: any): Promise<boolean> {
160
+ const { status, statusText, data } = await supabase.from('fact').update(changes).eq('id', id).select();
161
+
162
+ if (status !== 200) {
163
+ throw new Error(statusText);
164
+ }
165
+
166
+ // Must return success boolean to tell Zync to dequeue update
167
+ const changed = !!data?.[0];
168
+ return changed;
169
+ }
170
+
171
+ // Soft delete
172
+ async function remove(id: number) {
173
+ const payload = {
174
+ deleted: true,
175
+ };
176
+
177
+ const { status, statusText } = await supabase.from('fact').update(payload).eq('id', id);
178
+
179
+ if (status !== 204) {
180
+ throw new Error(statusText);
181
+ }
182
+ }
183
+
184
+ async function list(lastUpdatedAt: Date) {
185
+ const { data, error } = await supabase.from('fact').select().gt('updated_at', lastUpdatedAt.toISOString());
186
+
187
+ if (error) {
188
+ throw new Error(error.message);
189
+ }
190
+
191
+ return data;
192
+ }
193
+
194
+ // Optional, for if you want to download all data when your app is first used
195
+ // Called until no more records are returned
196
+ async function firstLoad(lastId: any) {
197
+ // Initially undefined, so you can choose the datatype (e.g. numeric or string id)
198
+ // Zync will remember the last id returned, having sorted in ascending order, and passes it in as lastId next time
199
+ if (!lastId) lastId = 0;
200
+
201
+ const { data, error } = await supabase.from('fact').select().limit(1000).order('id', { ascending: true }).gt('id', lastId);
202
+
203
+ if (error) {
204
+ throw new Error(error.message);
205
+ }
206
+
207
+ return data;
208
+ }
209
+ ```
210
+
126
211
  ## Optional IndexedDB storage
127
212
 
128
213
  When using IndexedDB Zustand saves the whole store under one key, which means indexes cannot be used to accelerate querying. However, if this becomes a performance issue due to the size of the store, then libraries like dexie.js instead of Zustand would be a better solution and provide the syntax for high performance queries.
@@ -142,3 +227,7 @@ npm install --save-optional idb
142
227
  ```
143
228
 
144
229
  The library will throw a helpful runtime error if `idb` isn't installed when `createIndexedDBStorage()` is invoked.
230
+
231
+ ## Community
232
+
233
+ PRs are welcome! [pnpm](https://pnpm.io) is used as a package manager. Run `pnpm install` to install local dependencies. Thank you for contributing!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anfenn/zync",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "private": false,
5
5
  "description": "Sync middleware for zustand",
6
6
  "keywords": [],