@fireflysemantics/slice 17.0.5 → 17.0.6

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 +316 -18
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,6 +6,12 @@ Lightweight Javascript Reactive State Management for Angular Applications.
6
6
 
7
7
  If you like the [@fireflysemantics/slice API](https://fireflysemantics.github.io/slice/doc/) please star our [Github Repository](https://github.com/fireflysemantics/slice).
8
8
 
9
+ - [Install](#install)
10
+ - [Object Store Core Use Cases](#object-store-core-use-cases)
11
+ - [Entity Store Core Use Cases](#entity-store-core-use-cases)
12
+ - [Features](#features)
13
+ - [Documentatino and Media](#firefly-semantics-slice-development-center-media-and-documentation)
14
+
9
15
  # Install
10
16
 
11
17
 
@@ -129,7 +135,316 @@ console.log(`The count is ${OS.count()}`);
129
135
  console.log(`The snapshot is ${OS.snapshot(OS.S.K1)}`);
130
136
  ```
131
137
 
138
+ ## Entity Store Core Use Cases
139
+
140
+ [Here is a link to the Stackblitz demo](https://stackblitz.com/edit/typescript-akqgqg?file=index.ts) containing the below demo code. You may also wish to check out the [test cases](https://github.com/fireflysemantics/slice/blob/master/projects/slice/src/lib/EStore.spec.ts) for the entity store which also detail usage scenarios.
141
+
142
+ ```
143
+ //============================================
144
+ // Demo Utilities
145
+ //============================================
146
+
147
+ export const enum TodoSliceEnum {
148
+ COMPLETE = 'Complete',
149
+ INCOMPLETE = 'Incomplete',
150
+ }
151
+
152
+ export class Todo {
153
+ constructor(
154
+ public complete: boolean,
155
+ public title: string,
156
+ public gid?: string,
157
+ public id?: string
158
+ ) {}
159
+ }
160
+
161
+ export const extraTodo: Todo = new Todo(false, 'Do me later.');
162
+
163
+ export let todos = [
164
+ new Todo(false, 'You complete me!'),
165
+ new Todo(true, 'You completed me!'),
166
+ ];
167
+
168
+ export function todosFactory(): Todo[] {
169
+ return [
170
+ new Todo(false, 'You complete me!'),
171
+ new Todo(true, 'You completed me!'),
172
+ ];
173
+ }
174
+
175
+ export function todosClone(): Todo[] {
176
+ return todos.map((obj) => ({ ...obj }));
177
+ }
178
+
179
+ //============================================
180
+ // API: constructor()
181
+ //
182
+ // Create a Todo Entity Store
183
+ //============================================
184
+ let store: EStore<Todo> = new EStore<Todo>(todosFactory());
185
+
186
+ //============================================
187
+ // API: post, put, delete
188
+ //
189
+ // Perform post (Create), put (Update), and delete opeartions
190
+ // on the store.
191
+ //============================================
192
+ const todoLater: Todo = new Todo(false, 'Do me later.');
193
+ todoLater.id = 'findMe';
194
+ store.post(todoLater);
195
+ const postedTodo = store.findOneByID('findMe');
196
+ postedTodo.title = 'Do me sooner';
197
+ store.put(postedTodo);
198
+ store.delete(postedTodo);
199
+
200
+ //============================================
201
+ // API: allSnapshot()
202
+ //
203
+ // Take a snapshot of all the entities
204
+ // in the store
205
+ //============================================
206
+ let snapshot: Todo[] = store.allSnapshot();
207
+
208
+ //============================================
209
+ // API: obs
210
+ //
211
+ // Create a subscription to the entities in
212
+ // the store.
213
+ //============================================
214
+ let todosSubscription: Subscription = store.obs.subscribe((todos: Todo[]) => {
215
+ console.log(`The store todos ${todos}`);
216
+ });
217
+
218
+ //============================================
219
+ // API: findOne()
220
+ //
221
+ // Find a Todo instance using the
222
+ // Global ID (guid) property.
223
+ //============================================
224
+ const globalID: string = '1';
225
+ let findThisTodo = new Todo(false, 'Find this Todo', globalID);
226
+
227
+ store.post(findThisTodo);
228
+
229
+ const todo = store.findOne(globalID);
230
+ console.log(todo);
231
+
232
+ //============================================
233
+ // API: findOneByID()
234
+ //
235
+ // Find a Todo instance using the
236
+ // ID (id) property.
237
+ //============================================
238
+ const ID: string = 'id';
239
+ let todoWithID = new Todo(false, 'Find this Todo by ID');
240
+ todoWithID.id = ID;
241
+
242
+ store.post(todoWithID);
243
+ const todoFoundByID = store.findOneByID(ID);
244
+
245
+ console.log(`The Todo instance found by id is ${todoFoundByID}`);
246
+
247
+ //============================================
248
+ // API: observeLoading()
249
+ //
250
+ // Subscribe to the store loading indicator
251
+ // and toggle it to see the values change.
252
+ //============================================
253
+ store.observeLoading().subscribe((loading) => {
254
+ console.log(`Is data loading: ${loading}`);
255
+ });
256
+ store.loading = true;
257
+ store.loading = false;
258
+
259
+ //============================================
260
+ // API: observeSearching()
261
+ //
262
+ // Subscribe to the store searching indicator
263
+ // and toggle it to see the values change.
264
+ //============================================
265
+ store.observeSearching().subscribe((searching) => {
266
+ console.log(`Is the store searching: ${searching}`);
267
+ });
268
+ store.searching = true;
269
+ store.searching = false;
270
+
271
+ //============================================
272
+ // API: addActive()
273
+ // Perform active state tracking. Initially the
274
+ // number of active entities will be zero.
275
+ //============================================
276
+ console.log(`The number of active Todo instances is ${store.active.size}`);
277
+ let todo1: Todo = new Todo(false, 'The first Todo!', GUID());
278
+ let todo2: Todo = new Todo(false, 'The first Todo!', GUID());
279
+ store.addActive(todo1);
280
+ console.log(`The number of active Todo instances is ${store.active.size}`);
281
+
282
+ console.log(
283
+ `The number of active Todo instances by the activeSnapshot is ${
284
+ store.activeSnapshot().length
285
+ }`
286
+ );
287
+
288
+ //============================================
289
+ // API: observeActive()
290
+ //
291
+ // Subscribing to the observeActive() observable
292
+ // provides the map of active Todo instances.
293
+ //============================================
294
+ store.observeActive().subscribe((active) => {
295
+ console.log(`The active Todo instances are: ${active}`);
296
+ });
297
+
298
+ //============================================
299
+ // API: deleteActive()
300
+ // Delete the active Todo instance.
301
+ // This will set the number of active
302
+ // Todo instances back to zero.
303
+ //============================================
304
+ store.deleteActive(todo1);
305
+ console.log(
306
+ `The number of active Todo instances by the activeSnapshot is ${
307
+ store.activeSnapshot().length
308
+ }`
309
+ );
310
+
311
+ //============================================
312
+ // API: count()
313
+ //
314
+ // Dyanically count the Number of Entries in the Store.
315
+ //============================================
316
+ let countSubscription = store.count().subscribe((c) => {
317
+ console.log(`The number of Todo entities stored is ${c}`);
318
+ });
319
+
320
+ //============================================
321
+ // API: toggle()
322
+ //
323
+ // When we post another todo using toggle
324
+ // instance the subscribed to count
325
+ // dynamically increases by 1.
326
+ // When we call toggle again,
327
+ // removing the instance the
328
+ // count decreases by 1.
329
+ //============================================
330
+ store.toggle(extraTodo);
331
+ store.toggle(extraTodo);
332
+
333
+ //============================================
334
+ // API: contains()
335
+ //
336
+ // When we post another todo using toggle
337
+ // the store now contains it.
338
+ //============================================
339
+ console.log(
340
+ `Does the store contain the extraTodo ${store.contains(extraTodo)}`
341
+ );
342
+ store.toggle(extraTodo);
343
+ console.log(
344
+ `Does the store contain the extraTodo ${store.contains(extraTodo)}`
345
+ );
346
+ store.toggle(extraTodo);
347
+ console.log(
348
+ `Does the store contain the extraTodo ${store.contains(extraTodo)}`
349
+ );
350
+
351
+ //============================================
352
+ // API: containsbyID()
353
+ //
354
+ // When we post another todo using toggle
355
+ // the store now contains it.
356
+ //
357
+ // Note the containsByID() can be called with
358
+ // both the id property or the entire instance.
359
+ //============================================
360
+ let todoByID = new Todo(false, 'This is not in the store', undefined, '1');
361
+ store.post(todoByID);
362
+ console.log(
363
+ `Does the store contain the todoByID ${store.containsById(todoByID.id)}`
364
+ );
365
+ console.log(
366
+ `Does the store contain the todoByID ${store.containsById(todoByID)}`
367
+ );
368
+ store.toggle(todoByID);
369
+ console.log(
370
+ `Does the store contain the todoByID ${store.containsById(todoByID.id)}`
371
+ );
372
+ console.log(
373
+ `Does the store contain the todoByID ${store.containsById(todoByID)}`
374
+ );
375
+
376
+ //============================================
377
+ // API: equalsByGUID and equalsByID
378
+ //
379
+ // Compare entities by ID and Global ID (guid).
380
+ // We will assign the ID and the global ID
381
+ // instead of allowing the global ID to be
382
+ // assigned by the store on post.
383
+ //============================================
384
+ const guid = GUID();
385
+ let todoOrNotTodo1 = new Todo(false, 'Apples to Apples', guid, '1');
386
+ let todoOrNotTodo2 = new Todo(false, 'Apples to Apples', guid, '1');
387
+
388
+ const equalByID: boolean = store.equalsByID(todoOrNotTodo1, todoOrNotTodo2);
389
+ console.log(`Are the todos equal by id: ${equalByID}`);
390
+ const equalByGUID: boolean = store.equalsByGUID(todoOrNotTodo1, todoOrNotTodo2);
391
+ console.log(`Are the todos equal by global id: ${equalByGUID}`);
392
+
393
+ //============================================
394
+ // API: addSlice
395
+ //
396
+ // Add a slice for complete todo entities.
397
+ //
398
+ // We create a new store to demo with a
399
+ // consistent count.
400
+ //
401
+ // When posting the extraTodo which is
402
+ // incomplete, we see that the incomplete
403
+ // count increments.
404
+ //============================================
405
+ store.destroy();
406
+ store = new EStore<Todo>(todosFactory());
407
+ store.addSlice((todo) => todo.complete, TodoSliceEnum.COMPLETE);
408
+ store.addSlice((todo) => !todo.complete, TodoSliceEnum.INCOMPLETE);
409
+ const completeSlice = store.getSlice(TodoSliceEnum.COMPLETE);
410
+ const incompleteSlice = store.getSlice(TodoSliceEnum.INCOMPLETE);
411
+ completeSlice.count().subscribe((c) => {
412
+ console.log(`The number of entries in the complete slice is ${c}`);
413
+ });
414
+ incompleteSlice.count().subscribe((c) => {
415
+ console.log(`The number of entries in the incomplete slice is ${c}`);
416
+ });
417
+ store.post(extraTodo);
418
+ const incompleteTodos: Todo[] = incompleteSlice.allSnapshot();
419
+ console.log(`The incomplete Todo entities are ${incompleteTodos}`);
420
+
421
+ //============================================
422
+ // API: isEmpty()
423
+ //
424
+ // Check whether the store is empty.
425
+ //============================================
426
+ store.isEmpty().subscribe((empty) => {
427
+ console.log(`Is the store empty? ${empty}`);
428
+ });
429
+ ```
430
+
431
+ ## Features
132
432
 
433
+ - Live Stackblitz demoes
434
+ - [Typedoc with inlined examples](https://fireflysemantics.github.io/slice/doc/)
435
+ - [Well documented test cases run with Jest - Each file has a corresponding `.spec` file](https://github.com/fireflysemantics/slice/tree/master/src)
436
+ - Stream both Entity and Object Stores for UI Updates via RxJS
437
+ - Define entities using Typescript classes, interfaces, or types
438
+ - [Active state tracking](https://medium.com/@ole.ersoy/monitoring-the-currently-active-entity-with-slice-ff7c9b7826e8)
439
+ - [Supports for Optimistic User Interfaces](https://medium.com/@ole.ersoy/optimistic-user-identity-management-with-slice-a2b66efe780c)
440
+ - RESTful API for performing CRUD operations that stream both full and delta updates
441
+ - Dynamic creation of both object and entity stores
442
+ - Observable delta updates for Entities
443
+ - Real time application of Slice `Predicate<E>` filtering that is `Observable`
444
+ - `Predicate` based snapshots of entities
445
+ - Observable `count` of entities in the entity store. The `count` feature can also be `Predicate` filtered.
446
+ - Configurable global id (Client side id - `gid`) and server id (`id`) id property names for entities.
447
+ - The stream of entities can be sorted via an optional boolean expression passed to `observe`.
133
448
 
134
449
  # Firefly Semantics Slice Development Center Media and Documentation
135
450
 
@@ -221,26 +536,9 @@ Run `npm run c` to build the project. The build artifacts will be stored in the
221
536
 
222
537
  ## Running unit tests
223
538
 
224
- Run `ng test` to execute the unit tests via [Jest](https://jestjs.io/).
225
-
539
+ Run `npm run test` to execute the unit tests via [Jest](https://jestjs.io/).
226
540
 
227
- ## Features
228
541
 
229
- - Live Stackblitz demoes
230
- - [Typedoc with inlined examples](https://fireflysemantics.github.io/slice/doc/)
231
- - [Well documented test cases run with Jest - Each file has a corresponding `.spec` file](https://github.com/fireflysemantics/slice/tree/master/src)
232
- - Stream both Entity and Object Stores for UI Updates via RxJS
233
- - Define entities using Typescript classes, interfaces, or types
234
- - [Active state tracking](https://medium.com/@ole.ersoy/monitoring-the-currently-active-entity-with-slice-ff7c9b7826e8)
235
- - [Supports for Optimistic User Interfaces](https://medium.com/@ole.ersoy/optimistic-user-identity-management-with-slice-a2b66efe780c)
236
- - RESTful API for performing CRUD operations that stream both full and delta updates
237
- - Dynamic creation of both object and entity stores
238
- - Observable delta updates for Entities
239
- - Real time application of Slice `Predicate<E>` filtering that is `Observable`
240
- - `Predicate` based snapshots of entities
241
- - Observable `count` of entities in the entity store. The `count` feature can also be `Predicate` filtered.
242
- - Configurable global id (Client side id - `gid`) and server id (`id`) id property names for entities.
243
- - The stream of entities can be sorted via an optional boolean expression passed to `observe`.
244
542
 
245
543
  ## Tests
246
544
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fireflysemantics/slice",
3
- "version": "17.0.5",
3
+ "version": "17.0.6",
4
4
  "peerDependencies": {
5
5
  "nanoid": "^5.0.4",
6
6
  "@types/nanoid": "*",