@slimlib/store 1.4.1 → 1.5.0

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.
package/README.md CHANGED
@@ -18,7 +18,7 @@ npm install --save-dev @slimlib/store
18
18
 
19
19
  # Usage
20
20
 
21
- React:
21
+ ### React
22
22
 
23
23
  ```javascript
24
24
  import { createStore, useStore } from '@slimlib/store/react';
@@ -39,7 +39,7 @@ function Component() {
39
39
  }
40
40
  ```
41
41
 
42
- Preact:
42
+ ### Preact
43
43
 
44
44
  ```javascript
45
45
  import { createStore, useStore } from '@slimlib/store/preact';
@@ -60,7 +60,7 @@ function Component() {
60
60
  }
61
61
  ```
62
62
 
63
- Svelte:
63
+ ### Svelte
64
64
 
65
65
  In store
66
66
 
@@ -89,6 +89,30 @@ import { storeName } from './stores/storeName';
89
89
  $storeName
90
90
  ```
91
91
 
92
+ ### Angular
93
+
94
+ In store
95
+
96
+ ```javascript
97
+ import { SlimlibStore } from '@slimlib/store/angular';
98
+
99
+ // create store
100
+ @Injectable()
101
+ export class StoreName extends SlimlibStore {
102
+ constructor() {
103
+ super(/*Initial state*/{ field: 123 }});
104
+ }
105
+
106
+ // selectors
107
+ field = this.select(state => state.field);
108
+
109
+ // actions
110
+ doSomething() {
111
+ this.state.field = value;
112
+ }
113
+ }
114
+ ```
115
+
92
116
  ## API
93
117
 
94
118
  ### `main` and `core` exports
@@ -134,6 +158,23 @@ Function to subscribe to store inside component. Returns current state.
134
158
 
135
159
  Store factory created with `notifyAfterCreation` === `true`.
136
160
 
161
+ ### `angular` export
162
+
163
+ #### `createStore<T>(initialState: T): [T, Store<T>, () => void]`
164
+
165
+ Store factory created with `notifyAfterCreation` === `false`.
166
+
167
+ #### `toSignal<T>(store: Store<T>): Signal<T>` - converts store to signal
168
+
169
+ #### `SlimlibStore`
170
+
171
+ Base class for store services.
172
+
173
+ ##### `constructor(initialState: T)` - creates store with initial state
174
+
175
+ ##### `state: T` - store state (proxy object)
176
+ ##### `select<R>(...signals: Signal[], projector: (state: T, ...signalValue: SignalValue<signals[index]>) => R): Signal<R>` - selector function that returns a signal
177
+
137
178
  ## Limitations
138
179
 
139
180
  `Map`, `Set`, `WeakMap`, `WeakSet` cannot be used as values in current implementation.
package/dist/angular.cjs CHANGED
@@ -22,6 +22,14 @@ class SlimlibStore {
22
22
  [this.state, this.store] = createStore(initialState);
23
23
  this.signal = toSignal(this.store);
24
24
  }
25
+ select(...selectors) {
26
+ // eslint-disable-next-line @typescript-eslint/ban-types
27
+ const projector = selectors.pop();
28
+ return core$1.computed(() => {
29
+ const values = selectors.map(selector => selector());
30
+ return projector(this.signal(), ...values);
31
+ });
32
+ }
25
33
  }
26
34
 
27
35
  exports.SlimlibStore = SlimlibStore;
package/dist/angular.d.ts CHANGED
@@ -7,9 +7,17 @@ export type InjectorLike = {
7
7
  };
8
8
  export declare const createStore: <T extends object>(object?: T) => [T, Store<T>, () => void];
9
9
  export declare const toSignal: <T>(store: Store<T>, injector?: InjectorLike) => Signal<T>;
10
+ type SignalValue<T extends Signal<unknown>> = T extends Signal<infer Value> ? Value : never;
11
+ type ArrayOfSignalValues<T extends Signal<unknown>[]> = {
12
+ [S in keyof T]: SignalValue<T[S]>;
13
+ };
14
+ type Prepend<I, T extends unknown[]> = [I, ...T];
15
+ type SignalsProjector<Signals extends Signal<unknown>[], Result, State> = (...values: Prepend<State, ArrayOfSignalValues<Signals>>) => Result;
10
16
  export declare class SlimlibStore<T extends object> {
11
17
  private readonly store;
12
18
  protected readonly state: T;
13
19
  readonly signal: Signal<T>;
14
20
  constructor(initialState: T);
21
+ select<P extends Signal<unknown>[], R>(...selectors: [...signals: P, projector: SignalsProjector<P, R, T>]): Signal<R>;
15
22
  }
23
+ export {};
package/dist/angular.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { inject, DestroyRef, signal, untracked } from '@angular/core';
1
+ import { inject, DestroyRef, signal, untracked, computed } from '@angular/core';
2
2
  import { createStoreFactory } from './core.mjs';
3
3
 
4
4
  const createStore = createStoreFactory(false);
@@ -20,6 +20,14 @@ class SlimlibStore {
20
20
  [this.state, this.store] = createStore(initialState);
21
21
  this.signal = toSignal(this.store);
22
22
  }
23
+ select(...selectors) {
24
+ // eslint-disable-next-line @typescript-eslint/ban-types
25
+ const projector = selectors.pop();
26
+ return computed(() => {
27
+ const values = selectors.map(selector => selector());
28
+ return projector(this.signal(), ...values);
29
+ });
30
+ }
23
31
  }
24
32
 
25
33
  export { SlimlibStore, createStore, toSignal };
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("./core")):"function"==typeof define&&define.amd?define(["exports","@angular/core","./core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).slimlibStoreAngular={},e.angularCore,e.slimlibStoreCore)}(this,(function(e,t,o){"use strict";const s=o.createStoreFactory(!1),n=(e,o)=>{const s=(o?o.get:t.inject)(t.DestroyRef),n=t.signal(e());return t.untracked((()=>{s?.onDestroy(e((e=>{n.set(e)})))})),n.asReadonly()};e.SlimlibStore=class{store;state;signal;constructor(e){[this.state,this.store]=s(e),this.signal=n(this.store)}},e.createStore=s,e.toSignal=n}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("./core")):"function"==typeof define&&define.amd?define(["exports","@angular/core","./core"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).slimlibStoreAngular={},e.angularCore,e.slimlibStoreCore)}(this,(function(e,t,o){"use strict";const s=o.createStoreFactory(!1),n=(e,o)=>{const s=(o?o.get:t.inject)(t.DestroyRef),n=t.signal(e());return t.untracked((()=>{s?.onDestroy(e((e=>{n.set(e)})))})),n.asReadonly()};e.SlimlibStore=class{store;state;signal;constructor(e){[this.state,this.store]=s(e),this.signal=n(this.store)}select(...e){const o=e.pop();return t.computed((()=>{const t=e.map((e=>e()));return o(this.signal(),...t)}))}},e.createStore=s,e.toSignal=n}));
2
2
  //# sourceMappingURL=angular.umd.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "name": "@slimlib/store",
5
5
  "description": "Simple Proxy-based store for SPA",
6
6
  "license": "MIT",