@inglorious/store 9.3.1 → 9.4.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 +5 -1
- package/package.json +1 -1
- package/src/api.js +43 -0
- package/src/test.js +4 -0
- package/types/api.d.ts +37 -0
- package/types/async.d.ts +2 -1
- package/types/index.d.ts +1 -0
- package/types/store.d.ts +2 -40
- package/types/test.d.ts +3 -0
package/README.md
CHANGED
|
@@ -207,6 +207,7 @@ const types = {
|
|
|
207
207
|
increment(counter, value, api) {
|
|
208
208
|
api.getEntities() // access the whole state in read-only mode
|
|
209
209
|
api.getEntity(id) // access some other entity in read-only mode
|
|
210
|
+
api.select(selector) // run a selector against the whole state
|
|
210
211
|
api.notify(type, payload) // similar to dispatch. Yes, you can dispatch inside of a reducer!
|
|
211
212
|
api.dispatch(action) // optional, if you prefer Redux-style dispatching
|
|
212
213
|
},
|
|
@@ -491,6 +492,7 @@ Notice: you don't need pending/fulfilled/rejected actions. You stay in control o
|
|
|
491
492
|
|
|
492
493
|
- **`api.getEntities()`** - read entire state
|
|
493
494
|
- **`api.getEntity(id)`** - read one entity
|
|
495
|
+
- **`api.select(selector)`** - run a selector against the state
|
|
494
496
|
- **`api.notify(type, payload)`** - trigger other events (queued, not immediate)
|
|
495
497
|
- **`api.dispatch(action)`** - optional, if you prefer Redux-style dispatching
|
|
496
498
|
- **`api.getTypes()`** - access type definitions (mainly for middleware/plugins)
|
|
@@ -748,6 +750,7 @@ The mock API provides:
|
|
|
748
750
|
|
|
749
751
|
- `getEntities()`: Returns all entities (frozen).
|
|
750
752
|
- `getEntity(id)`: Returns a specific entity by ID (frozen).
|
|
753
|
+
- `select(selector)`: Runs a selector against the entities.
|
|
751
754
|
- `dispatch(event)`: Records an event for later assertions.
|
|
752
755
|
- `notify(type, payload)`: A convenience wrapper around `dispatch`.
|
|
753
756
|
- `getEvents()`: Returns all events that were dispatched.
|
|
@@ -880,7 +883,7 @@ const selectResult = compute(
|
|
|
880
883
|
The returned function is a standard selector:
|
|
881
884
|
|
|
882
885
|
```js
|
|
883
|
-
const result =
|
|
886
|
+
const result = api.select(selectResult)
|
|
884
887
|
```
|
|
885
888
|
|
|
886
889
|
And it works seamlessly with `react-redux` or `@inglorious/react-store`:
|
|
@@ -1101,6 +1104,7 @@ Each handler receives three arguments:
|
|
|
1101
1104
|
- **`api`** - access to store methods:
|
|
1102
1105
|
- `getEntities()` - entire state (read-only)
|
|
1103
1106
|
- `getEntity(id)` - single entity (read-only)
|
|
1107
|
+
- `select(selector)` - run a selector against the state
|
|
1104
1108
|
- `notify(type, payload)` - trigger other events
|
|
1105
1109
|
- `dispatch(action)` - optional, if you prefer Redux-style dispatching
|
|
1106
1110
|
- `getTypes()` - type definitions (for middleware)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/store",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.4.0",
|
|
4
4
|
"description": "A state manager for real-time, collaborative apps, inspired by game development patterns and compatible with Redux.",
|
|
5
5
|
"author": "IceOnFire <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|
package/src/api.js
CHANGED
|
@@ -1,11 +1,54 @@
|
|
|
1
1
|
export function createApi(store, extras) {
|
|
2
2
|
return {
|
|
3
|
+
/**
|
|
4
|
+
* Retrieves all registered type definitions.
|
|
5
|
+
* @returns {Object}
|
|
6
|
+
*/
|
|
3
7
|
getTypes: store.getTypes,
|
|
8
|
+
/**
|
|
9
|
+
* Retrieves a specific type definition by name.
|
|
10
|
+
* @param {string} typeName
|
|
11
|
+
* @returns {Object}
|
|
12
|
+
*/
|
|
4
13
|
getType: store.getType,
|
|
14
|
+
/**
|
|
15
|
+
* Replaces a type definition at runtime.
|
|
16
|
+
* @param {string} typeName
|
|
17
|
+
* @param {Object} type
|
|
18
|
+
* @returns {void}
|
|
19
|
+
*/
|
|
5
20
|
setType: store.setType,
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the full entities state.
|
|
23
|
+
* @returns {Object}
|
|
24
|
+
*/
|
|
6
25
|
getEntities: store.getState,
|
|
26
|
+
/**
|
|
27
|
+
* Retrieves a single entity by ID.
|
|
28
|
+
* @param {string} id
|
|
29
|
+
* @returns {Object | undefined}
|
|
30
|
+
*/
|
|
7
31
|
getEntity: (id) => store.getState()[id],
|
|
32
|
+
/**
|
|
33
|
+
* Runs a selector against the current state.
|
|
34
|
+
*
|
|
35
|
+
* @template TResult
|
|
36
|
+
* @param {(state: object) => TResult} selector
|
|
37
|
+
* @returns {TResult}
|
|
38
|
+
*/
|
|
39
|
+
select: (selector) => selector(store.getState()),
|
|
40
|
+
/**
|
|
41
|
+
* Dispatches an event object to the store.
|
|
42
|
+
* @param {{ type: string, payload?: any }} event
|
|
43
|
+
* @returns {void}
|
|
44
|
+
*/
|
|
8
45
|
dispatch: store.dispatch,
|
|
46
|
+
/**
|
|
47
|
+
* Notifies the store of an event type and optional payload.
|
|
48
|
+
* @param {string} type
|
|
49
|
+
* @param {any} [payload]
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
9
52
|
notify: store.notify,
|
|
10
53
|
...extras,
|
|
11
54
|
}
|
package/src/test.js
CHANGED
|
@@ -13,6 +13,7 @@ import { create } from "mutative"
|
|
|
13
13
|
* @returns {Object} A mock API object with methods:
|
|
14
14
|
* - `getEntities()`: Returns all entities (frozen)
|
|
15
15
|
* - `getEntity(id)`: Returns a specific entity by ID (frozen)
|
|
16
|
+
* - `select(selector)`: Runs a selector against the entities
|
|
16
17
|
* - `dispatch(event)`: Records an event (for assertions)
|
|
17
18
|
* - `notify(type, payload)`: Convenience method that calls dispatch
|
|
18
19
|
* - `getEvents()`: Returns all events that were dispatched
|
|
@@ -42,6 +43,9 @@ export function createMockApi(entities) {
|
|
|
42
43
|
getEntity(id) {
|
|
43
44
|
return frozenEntities[id]
|
|
44
45
|
},
|
|
46
|
+
select(selector) {
|
|
47
|
+
return selector(frozenEntities)
|
|
48
|
+
},
|
|
45
49
|
dispatch(event) {
|
|
46
50
|
events.push(event)
|
|
47
51
|
},
|
package/types/api.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BaseEntity,
|
|
3
|
+
EntitiesState,
|
|
4
|
+
EntityType,
|
|
5
|
+
Event,
|
|
6
|
+
Store,
|
|
7
|
+
TypesConfig,
|
|
8
|
+
} from "./store"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* API object exposed to handlers
|
|
12
|
+
*/
|
|
13
|
+
export interface Api<
|
|
14
|
+
TEntity extends BaseEntity = BaseEntity,
|
|
15
|
+
TState extends EntitiesState<TEntity> = EntitiesState<TEntity>,
|
|
16
|
+
> {
|
|
17
|
+
getTypes: () => TypesConfig<TEntity>
|
|
18
|
+
getType: (typeName: string) => EntityType<TEntity>
|
|
19
|
+
setType: (typeName: string, type: EntityType<TEntity>) => void
|
|
20
|
+
getEntities: () => TState
|
|
21
|
+
getEntity: (id: string) => TEntity | undefined
|
|
22
|
+
select: <TResult>(selector: (state: TState) => TResult) => TResult
|
|
23
|
+
dispatch: (event: Event) => void
|
|
24
|
+
notify: (type: string, payload?: any) => void
|
|
25
|
+
[key: string]: any // For middleware extras
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates an API object
|
|
30
|
+
*/
|
|
31
|
+
export function createApi<
|
|
32
|
+
TEntity extends BaseEntity = BaseEntity,
|
|
33
|
+
TState extends EntitiesState<TEntity> = EntitiesState<TEntity>,
|
|
34
|
+
>(
|
|
35
|
+
store: Store<TEntity, TState>,
|
|
36
|
+
extras?: Record<string, any>,
|
|
37
|
+
): Api<TEntity, TState>
|
package/types/async.d.ts
CHANGED
package/types/index.d.ts
CHANGED
package/types/store.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Api } from "./api"
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Base entity structure
|
|
3
5
|
*/
|
|
@@ -67,23 +69,6 @@ export type Listener = () => void
|
|
|
67
69
|
*/
|
|
68
70
|
export type Unsubscribe = () => void
|
|
69
71
|
|
|
70
|
-
/**
|
|
71
|
-
* API object exposed to handlers
|
|
72
|
-
*/
|
|
73
|
-
export interface Api<
|
|
74
|
-
TEntity extends BaseEntity = BaseEntity,
|
|
75
|
-
TState extends EntitiesState<TEntity> = EntitiesState<TEntity>,
|
|
76
|
-
> {
|
|
77
|
-
getTypes: () => TypesConfig<TEntity>
|
|
78
|
-
getType: (typeName: string) => EntityType<TEntity>
|
|
79
|
-
setType: (typeName: string, type: EntityType<TEntity>) => void
|
|
80
|
-
getEntities: () => TState
|
|
81
|
-
getEntity: (id: string) => TEntity | undefined
|
|
82
|
-
dispatch: (event: Event) => void
|
|
83
|
-
notify: (type: string, payload?: any) => void
|
|
84
|
-
[key: string]: any // For middleware extras
|
|
85
|
-
}
|
|
86
|
-
|
|
87
72
|
/**
|
|
88
73
|
* Base store interface
|
|
89
74
|
*/
|
|
@@ -135,26 +120,3 @@ export function createStore<
|
|
|
135
120
|
TEntity extends BaseEntity = BaseEntity,
|
|
136
121
|
TState extends EntitiesState<TEntity> = EntitiesState<TEntity>,
|
|
137
122
|
>(config: StoreConfig<TEntity, TState>): Store<TEntity, TState>
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Creates an API object
|
|
141
|
-
*/
|
|
142
|
-
export function createApi<
|
|
143
|
-
TEntity extends BaseEntity = BaseEntity,
|
|
144
|
-
TState extends EntitiesState<TEntity> = EntitiesState<TEntity>,
|
|
145
|
-
>(
|
|
146
|
-
store: Store<TEntity, TState>,
|
|
147
|
-
extras?: Record<string, any>,
|
|
148
|
-
): Api<TEntity, TState>
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Helper to create a set of handlers for an async operation
|
|
152
|
-
*/
|
|
153
|
-
export function handleAsync<
|
|
154
|
-
TEntity extends BaseEntity = BaseEntity,
|
|
155
|
-
TPayload = any,
|
|
156
|
-
TResult = any,
|
|
157
|
-
>(
|
|
158
|
-
type: string,
|
|
159
|
-
handlers: AsyncHandlers<TEntity, TPayload, TResult>,
|
|
160
|
-
): EntityType<TEntity>
|
package/types/test.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { BaseEntity, EntitiesState } from "./store"
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Mock API for testing (subset of full API)
|
|
3
5
|
*/
|
|
@@ -7,6 +9,7 @@ export interface MockApi<
|
|
|
7
9
|
> {
|
|
8
10
|
getEntities: () => TState
|
|
9
11
|
getEntity: (id: string) => TEntity | undefined
|
|
12
|
+
select: <TResult>(selector: (state: TState) => TResult) => TResult
|
|
10
13
|
dispatch: (event: Event) => void
|
|
11
14
|
notify: (type: string, payload?: any) => void
|
|
12
15
|
getEvents: () => Event[]
|