@inglorious/store 9.1.0 → 9.2.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
@@ -794,12 +794,75 @@ const store = createStore({
794
794
  types, // Object: entity type definitions
795
795
  entities, // Object: initial entities
796
796
  systems, // Array (optional): global state handlers
797
+ autoCreateEntities, // Boolean (optional): false (default) or true
797
798
  updateMode, // String (optional): 'auto' (default) or 'manual'
798
799
  })
799
800
  ```
800
801
 
801
802
  **Returns:** A Redux-compatible store
802
803
 
804
+ **Options:**
805
+
806
+ - **`types`** (required) - Object defining entity type behaviors
807
+ - **`entities`** (required) - Object containing initial entity instances
808
+ - **`systems`** (optional) - Array of global state handlers
809
+ - **`autoCreateEntities`** (optional) - Automatically create singleton entities for types not defined in `entities`:
810
+ - `false` (default) - Only use explicitly defined entities
811
+ - `true` - Auto-create entities matching their type name
812
+ - **`updateMode`** (optional) - Controls when React components re-render:
813
+ - `'auto'` (default) - Automatic updates after each event
814
+ - `'manual'` - Manual control via `api.update()`
815
+
816
+ #### Auto-Create Entities
817
+
818
+ When `autoCreateEntities: true`, the store automatically creates singleton entities for any type that doesn't have a corresponding entity defined. This is particularly useful for singleton-type entities that behave like components, eliminating the need to switch between type definitions and entity declarations.
819
+
820
+ ```javascript
821
+ const types = {
822
+ settings: {
823
+ setTheme(entity, theme) {
824
+ entity.theme = theme
825
+ },
826
+ },
827
+ analytics: {
828
+ track(entity, event) {
829
+ entity.events.push(event)
830
+ },
831
+ },
832
+ }
833
+
834
+ // Without autoCreateEntities (default)
835
+ const entities = {
836
+ settings: { type: "settings", theme: "dark" },
837
+ analytics: { type: "analytics", events: [] },
838
+ }
839
+
840
+ // With autoCreateEntities: true
841
+ const entities = {
842
+ // settings and analytics will be auto-created as:
843
+ // settings: { type: "settings" }
844
+ // analytics: { type: "analytics" }
845
+ }
846
+
847
+ const store = createStore({
848
+ types,
849
+ entities,
850
+ autoCreateEntities: true,
851
+ })
852
+
853
+ // Both approaches work the same way
854
+ store.notify("settings:setTheme", "light")
855
+ store.notify("analytics:track", { action: "click" })
856
+ ```
857
+
858
+ **When to use `autoCreateEntities`:**
859
+
860
+ - ✅ Building web applications with singleton services (settings, auth, analytics)
861
+ - ✅ Component-like entities that only need one instance
862
+ - ✅ Rapid prototyping where you want to add types without ceremony
863
+ - ❌ Game development with multiple entity instances (players, enemies, items)
864
+ - ❌ When you need fine control over initial entity state
865
+
803
866
  ### Types Definition
804
867
 
805
868
  ```javascript
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inglorious/store",
3
- "version": "9.1.0",
3
+ "version": "9.2.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/store.js CHANGED
@@ -13,6 +13,7 @@ import { augmentType, augmentTypes } from "./types.js"
13
13
  * @param {Object} [config.entities] - The initial entities configuration.
14
14
  * @param {Array} [config.systems] - The initial systems configuration.
15
15
  * @param {Array} [config.middlewares] - The initial middlewares configuration.
16
+ * @param {boolean} [config.autoCreateEntities] - Creates entities if not defined in `config.entities`.
16
17
  * @param {"auto" | "manual"} [config.updateMode] - The update mode (defaults to "auto").
17
18
  * @returns {Object} The store with methods to interact with state and events.
18
19
  */
@@ -21,6 +22,7 @@ export function createStore({
21
22
  entities: originalEntities = {},
22
23
  systems = [],
23
24
  middlewares = [],
25
+ autoCreateEntities = false,
24
26
  updateMode = "auto",
25
27
  } = {}) {
26
28
  const listeners = new Set()
@@ -220,8 +222,25 @@ export function createStore({
220
222
  const oldEntities = state ?? {}
221
223
  const newEntities = augmentEntities(nextState)
222
224
 
225
+ if (autoCreateEntities) {
226
+ for (const typeName of Object.keys(types)) {
227
+ // Check if entity already exists
228
+ const hasEntity = Object.values(newEntities).some(
229
+ (entity) => entity.type === typeName,
230
+ )
231
+
232
+ if (!hasEntity) {
233
+ // No entity for this type → auto-create minimal entity
234
+ newEntities[typeName] = {
235
+ id: typeName,
236
+ type: typeName,
237
+ }
238
+ }
239
+ }
240
+ }
241
+
223
242
  state = newEntities
224
- eventMap = new EventMap(types, nextState)
243
+ eventMap = new EventMap(types, newEntities)
225
244
  incomingEvents = []
226
245
  isProcessing = false
227
246
 
package/types/store.d.ts CHANGED
@@ -53,6 +53,7 @@ export interface StoreConfig<
53
53
  entities?: TState
54
54
  systems?: System<TState>[]
55
55
  middlewares?: Middleware<TEntity, TState>[]
56
+ autoCreateEntities?: boolean
56
57
  mode?: "eager" | "batched"
57
58
  }
58
59