@vanyamate/sec 0.0.7 → 0.0.9

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 ADDED
@@ -0,0 +1,20 @@
1
+ # SEC (Store, Effect, Combine)
2
+
3
+ Tiny state manager
4
+
5
+ ```typescript
6
+ import { store, effect, combine } from './index';
7
+
8
+
9
+ const sum = async (a, b) => a + b;
10
+
11
+ // Create effect
12
+ const sumEffect = effect(sum);
13
+
14
+ // Create stores
15
+ const allSums = store(0).on(sumEffect, 'onSuccess', (state, { result }) => state + result);
16
+ const lastSum = store(0).on(sumEffect, 'onSuccess', (_, { result }) => result);
17
+
18
+ // Create combine
19
+ const bothSum = combine([ allSums, lastSum ], (...args) => args.reduce((acc, item) => acc + item.get(), 0));
20
+ ```
package/index.d.ts CHANGED
@@ -20,6 +20,8 @@ export type Store<State> = {
20
20
  subscribe: (listener: Listener<State>) => () => void;
21
21
  };
22
22
  export declare function store<State>(initialState: State): Store<State>;
23
- export declare function combine<States extends any[]>(...stores: {
23
+ export declare function combine<States extends any[], Result>(stores: {
24
24
  [K in keyof States]: Store<States[K]>;
25
- }): Store<States>;
25
+ }, callback: (...stores: {
26
+ [K in keyof States]: Store<States[K]>;
27
+ }) => Result): Store<Result>;
package/index.ts CHANGED
@@ -121,28 +121,43 @@ export function store<State> (initialState: State): Store<State> {
121
121
  return storeApi;
122
122
  }
123
123
 
124
- export function combine<States extends any[]> (...stores: { [K in keyof States]: Store<States[K]> }): Store<States> {
125
- let combinedState = stores.map(store => store.get()) as States;
126
- let combinedListeners: Listener<States>[] = [];
124
+ export function combine<States extends any[], Result> (
125
+ stores: { [K in keyof States]: Store<States[K]> },
126
+ callback: (...stores: { [K in keyof States]: Store<States[K]> }) => Result,
127
+ ): Store<Result> {
128
+ let combinedState: Result = callback(...stores);
127
129
 
128
130
  stores.forEach((store, index) => {
129
- store.subscribe((state) => {
130
- combinedState[index] = state;
131
- combinedListeners.forEach(listener => listener(combinedState));
131
+ store.subscribe(() => {
132
+ combinedState = callback(...stores);
133
+ listeners.forEach(listener => listener(combinedState));
132
134
  });
133
135
  });
134
136
 
135
- return {
136
- get : () => combinedState,
137
- set : (newState) => {
138
- newState.forEach((state, index) => stores[index].set(state));
137
+ const listeners: Listener<Result>[] = [];
138
+
139
+ const get = () => combinedState;
140
+
141
+ const subscribe = (listener: Listener<Result>) => {
142
+ listeners.push(listener);
143
+ return () => {
144
+ const index = listeners.indexOf(listener);
145
+ if (index !== -1) {
146
+ listeners.splice(index, 1);
147
+ }
148
+ };
149
+ };
150
+
151
+ const storeApi: Store<Result> = {
152
+ get,
153
+ set: () => {
154
+ throw new Error('Cannot call \'set\' on combined store');
139
155
  },
140
- on : () => {
156
+ on : () => {
141
157
  throw new Error('Cannot call \'on\' on combined store');
142
158
  },
143
- subscribe: (listener) => {
144
- combinedListeners.push(listener);
145
- return () => combinedListeners = combinedListeners.filter((l) => l !== listener);
146
- },
159
+ subscribe,
147
160
  };
161
+
162
+ return storeApi;
148
163
  }
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@vanyamate/sec",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "SEC. Store, Effect, Combine. Tiny state manager",
5
5
  "scripts": {
6
6
  "g:type": "tsc index.ts --declaration --emitDeclarationOnly"
7
7
  },
8
+ "main": "./index.ts",
8
9
  "types": "./index.d.ts",
9
10
  "repository": {
10
11
  "type": "git",