@inglorious/store 9.3.0 → 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 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 = selectResult(api.getEntities())
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.0",
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",
@@ -53,18 +53,19 @@
53
53
  "publishConfig": {
54
54
  "access": "public"
55
55
  },
56
+ "sideEffects": false,
56
57
  "dependencies": {
57
58
  "mutative": "^1.3.0",
58
- "@inglorious/utils": "3.7.2"
59
+ "@inglorious/utils": "3.7.3"
59
60
  },
60
61
  "peerDependencies": {
61
- "@inglorious/utils": "3.7.2"
62
+ "@inglorious/utils": "3.7.3"
62
63
  },
63
64
  "devDependencies": {
64
65
  "prettier": "^3.6.2",
65
66
  "vite": "^7.1.3",
66
67
  "vitest": "^1.6.1",
67
- "@inglorious/eslint-config": "1.1.1"
68
+ "@inglorious/eslint-config": "1.1.2"
68
69
  },
69
70
  "engines": {
70
71
  "node": ">= 22"
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
@@ -1,4 +1,5 @@
1
- import { Api, BaseEntity } from "./store"
1
+ import { Api } from "./api"
2
+ import { BaseEntity } from "./store"
2
3
 
3
4
  /**
4
5
  * Scope option for async handler events
package/types/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from "./api"
1
2
  export * from "./async"
2
3
  export * from "./select"
3
4
  export * from "./store"
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[]