orchestore 0.1.8 → 0.1.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 CHANGED
@@ -25,9 +25,9 @@ Stay tuned for updates.
25
25
 
26
26
  ## About
27
27
 
28
- > 🧩 A function-oriented state orchestration architecture built on top of Redux Toolkit.
28
+ > 🧩 A function-oriented state orchestration architecture built on top of Redux Toolkit, inspired by Vuex.
29
29
 
30
- OrcheStore simplifies and automates common state management patterns in React, Redux Toolkit, and TypeScript applications by unifying state and behavior into directly callable runtime modules.
30
+ OrcheStore brings a Vuex-inspired developer experience to React and Redux Toolkit applications by unifying state and behavior into directly callable runtime modules.
31
31
 
32
32
  Instead of distributing logic across reducers, actions, thunks, selectors, hooks, middleware, and utility files, OrcheStore organizes related functionality into cohesive slice modules.
33
33
 
@@ -35,133 +35,124 @@ The goal is simple:
35
35
 
36
36
  > ⚡ Spend less time wiring state management infrastructure and more time building application features.
37
37
 
38
- ## Table of Contents
38
+ ## Installation
39
39
 
40
- - [Introduction](#orchestore)
41
- - [Core Principles](#core-principles)
42
- - [Why OrcheStore?](#why-orchestore)
43
- - [Redux Toolkit Comparison](#redux-toolkit-comparison)
44
- - [Architecture Overview](#architecture-overview)
45
-
46
- - [Quick Example](#quick-example)
47
-
48
- - [Slice Layers](#slice-layers)
49
- - [name](#name)
50
- - [state](#state)
51
- - [Mutations](#mutations)
52
- - [Methods](#methods)
53
- - [Computed State (Planned)](#computed-state-planned)
54
- - [Nested Slices](#nested-slices)
55
- - [Reusing Slices](#reusing-slices)
56
- - [Runtime Paths](#runtime-paths)
57
-
58
- - [State Access & Subscriptions](#state-access--subscriptions)
59
- - [State Snapshots](#state-snapshots)
60
- - [State Subscriptions](#state-subscriptions)
61
- - [Draft State](#draft-state)
62
-
63
- - [Store Integration](#store-integration)
64
- - [Creating the Store](#creating-the-store)
65
- - [Store Provider](#store-provider)
66
- - [Accessing Slices through Store](#accessing-slices-through-store)
67
- - [Accessing Store from Slices](#accessing-store-from-slices)
68
- - [Root Store Type Extension (Planned)](#root-store-type-extension-planned)
69
-
70
- - [Lineage & Clones](#lineage--clones)
71
- - [Automatic Cloning](#automatic-cloning)
72
- - [Manual Cloning](#manual-cloning)
73
- - [Inspecting a Lineage](#inspecting-a-lineage)
74
- - [Definition Type Checking](#definition-type-checking)
75
-
76
- - [Global Utilities](#global-utilities)
77
- - [Accessing Global Utilities](#accessing-global-utilities)
78
- - [Utilities Type Extension](#utilities-type-extension)
79
- - [Providing Runtime Utilities](#providing-runtime-utilities)
80
- - [Using Global Utilities in Slices](#using-global-utilities-in-slices)
81
-
82
- - [TypeScript Inference](#typescript-inference)
83
-
84
- - [Status](#status)
40
+ With npm:
85
41
 
86
- ---
42
+ ```bash
43
+ npm install orchestore
44
+ ```
87
45
 
88
- ## Core Principles
46
+ Or with Yarn:
89
47
 
90
- - Simplify state management architecture
91
- - Automate repetitive Redux patterns
92
- - Reduce infrastructure code
93
- - Centralize state and application logic
94
- - Provide direct and intuitive APIs
95
- - Preserve predictable state transitions
96
- - Maintain strong TypeScript inference
97
- - Scale naturally through composition
48
+ ```bash
49
+ yarn add orchestore
50
+ ```
98
51
 
99
- ## Why OrcheStore?
52
+ Or with pnpm:
100
53
 
101
- Redux Toolkit significantly improves the Redux developer experience, but many applications still require developers to coordinate logic across multiple concepts:
54
+ ```bash
55
+ pnpm add orchestore
56
+ ```
57
+
58
+ **Peer Dependencies**
102
59
 
103
- - reducers
104
- - action creators
105
- - thunks
106
- - selectors
107
- - middleware
108
- - hooks
109
- - utility functions
60
+ OrcheStore requires:
110
61
 
111
- As applications grow, state management often becomes less about solving business problems and more about connecting infrastructure.
62
+ * React 16.9+
63
+ * React DOM 16.9+
112
64
 
113
- OrcheStore reduces that coordination overhead by exposing state management through unified slice modules.
65
+ **Included Dependencies**
114
66
 
115
- A slice is more than a state container. It is a runtime module that can encapsulate:
67
+ `@reduxjs/toolkit` and `react-redux` are installed automatically with OrcheStore.
116
68
 
117
- - state
118
- - computed state
119
- - mutations
120
- - methods
121
- - selectors
122
- - child slices
123
- - shared utilities
69
+ ## Table of Contents
124
70
 
125
- This allows state and application logic to evolve together within the same domain boundary.
71
+ * [Introduction](#orchestore)
72
+ * [Installation](#installation)
73
+ * [Core Principles](#core-principles)
74
+ * [Why OrcheStore?](#why-orchestore)
75
+ * [Architecture Overview](#architecture-overview)
76
+
77
+ * [Quick Example](#quick-example)
78
+
79
+ * [Slice Layers](#slice-layers)
80
+ * [name](#name)
81
+ * [state](#state)
82
+ * [Mutations](#mutations)
83
+ * [Methods](#methods)
84
+ * [Computed State (Planned)](#computed-state-planned)
85
+ * [Nested Slices](#nested-slices)
86
+ * [Accessing Children through Parent Slice](#accessing-children-through-parent-slice)
87
+ * [Accessing Parent Slice from Children](#accessing-parent-slice-from-children)
88
+ * [Reusing Slices](#reusing-slices)
89
+ * [Runtime Paths](#runtime-paths)
90
+
91
+ * [State Access & Subscriptions](#state-access--subscriptions)
92
+ * [State Snapshots](#state-snapshots)
93
+ * [State Subscriptions](#state-subscriptions)
94
+ * [Draft State](#draft-state)
95
+
96
+ * [Store Integration](#store-integration)
97
+ * [Creating the Store](#creating-the-store)
98
+ * [Store Provider](#store-provider)
99
+ * [Accessing Slices through Store](#accessing-slices-through-store)
100
+ * [Accessing Store from Slices](#accessing-store-from-slices)
101
+
102
+ * [Lineage & Clones](#lineage--clones)
103
+ * [Manual Cloning](#manual-cloning)
104
+ * [Automatic Cloning](#automatic-cloning)
105
+ * [Inspecting a Lineage](#inspecting-a-lineage)
106
+ * [Definition Type Checking](#definition-type-checking)
107
+
108
+ * [Utilities](#utilities)
109
+ * [Accessing Utilities](#accessing-utilities)
110
+ * [Utilities Type Extension](#utilities-type-extension)
111
+ * [Providing Runtime Utilities](#providing-runtime-utilities)
112
+ * [Using Utilities in Slices](#using-utilities-in-slices)
113
+
114
+ * [TypeScript Inference](#typescript-inference)
115
+
116
+ * [Status](#status)
117
+
118
+ ---
126
119
 
127
- Many common Redux patterns are automated by default:
120
+ ## Core Principles
128
121
 
129
- | Traditional Redux Pattern | OrcheStore |
130
- | ----------------------------- | ----------------------------------------------- |
131
- | Action creators | Direct callable mutations |
132
- | Thunks | Built-in methods |
133
- | Dispatch calls | Direct function calls |
134
- | `PayloadAction` wrappers | Native function arguments |
135
- | Cross-slice imports | Root store access |
136
- | Shared service wiring | Global utilities |
137
- | Manual state tree composition | Nested slices with automatic cloning & isolation |
138
- | Complex type declarations | Automatic inference |
139
- | Instance identity management | Lineage-based slice model (shared definition, isolated mounts) |
122
+ * Simplify state management architecture
123
+ * Automate repetitive Redux patterns
124
+ * Reduce infrastructure code
125
+ * Centralize state and application logic
126
+ * Provide direct and intuitive APIs
127
+ * Preserve predictable state transitions
128
+ * Maintain strong TypeScript inference
129
+ * Scale naturally through composition
140
130
 
141
- The result is a simpler architecture with fewer moving parts, less boilerplate, and a more direct development experience.
131
+ ## Why OrcheStore?
142
132
 
143
- Developers can focus on application behavior rather than framework plumbing.
133
+ Redux Toolkit greatly improves the Redux experience, but applications still often require developers to coordinate reducers, actions, selectors, thunks, hooks, utilities, and state composition.
144
134
 
145
- ## Redux Toolkit Comparison
135
+ OrcheStore builds on top of Redux Toolkit and combines these patterns into a unified slice model. A slice can encapsulate state, mutations, methods, computed values, child slices, and shared application utilities within a single module.
146
136
 
147
- OrcheStore builds on top of Redux Toolkit while providing a higher-level API for organizing state and behavior.
137
+ The goal is to reduce framework plumbing and allow application behavior to remain close to the state it operates on.
148
138
 
149
- | Feature | OrcheStore | Redux Toolkit |
150
- | ------------------------------ | ---------- | ------------- |
151
- | Multiple mutation arguments | | |
152
- | Direct callable mutations | | |
153
- | `PayloadAction` wrappers | | |
154
- | Dispatch required | | |
155
- | Built-in orchestration methods | | |
156
- | Nested slice composition | (isolated context) | ⚠️ Manual (shared state) |
157
- | Automatic path generation | | ⚠️ Manual |
158
- | Global utilities | | |
159
- | Unified slice API | ✅ | |
160
- | Per-slice React hooks | | ❌ |
161
- | Deep TypeScript inference | | ⚠️ Partial |
162
- | Lineage & cloning model | | |
139
+ | Concern | Redux Toolkit | OrcheStore |
140
+ | ------------------ | ---------------------------------------- | ----------------------------------------------- |
141
+ | State updates | Actions + dispatch | Direct callable mutations |
142
+ | Mutation arguments | `PayloadAction` wrappers | Native function arguments |
143
+ | Async logic | Separate thunks | Built-in methods |
144
+ | State selection | Global store selector hooks | Global + slice-scoped selection hooks |
145
+ | Cross-slice access | Imports & wiring | Runtime tree access (Root / Parent / Children) |
146
+ | Shared services | Manual integration | Application-wide utilities |
147
+ | State composition | Manual reducer composition | Nested slices |
148
+ | Identity model | Singleton-like slice definition | Lineage-based identity system |
149
+ | Instance reuse | Function-level reuse of slice reducers | Reused slices create isolated runtime instances |
150
+ | Cloning model | Factory pattern required for re-creation | Built-in cloning with lineage tracking |
151
+ | Exposed API | Reducers, actions and some helpers | Direct usable slice APIs |
152
+ | Type inference | Strong | Deep end-to-end inference |
153
+ | Developer focus | Connect infrastructure | Implement behavior |
163
154
 
164
- OrcheStore does not replace Redux Toolkit. Instead, it builds on top of it by automating common patterns and providing a more cohesive developer experience.
155
+ OrcheStore does not replace Redux Toolkit. It builds on top of it, providing a higher-level API for organizing state and application behavior with stronger automation of Redux patterns and reduced coordination overhead for developers.
165
156
 
166
157
  ## Architecture Overview
167
158
 
@@ -230,6 +221,15 @@ export const counter = createSlice({
230
221
  ```tsx
231
222
  import { createSlice, createAsyncThunk, type PayloadAction } from "@reduxjs/toolkit";
232
223
 
224
+ // Separate APIs for async workflows
225
+ export const incrementAfter = createAsyncThunk(
226
+ "counter/incrementAfter",
227
+ async ({ amount, delay }: { amount: number; delay: number }) => {
228
+ await new Promise((resolve) => setTimeout(resolve, delay));
229
+ return amount;
230
+ }
231
+ );
232
+
233
233
  export const counter = createSlice({
234
234
  name: "counter",
235
235
 
@@ -251,20 +251,14 @@ export const counter = createSlice({
251
251
  );
252
252
  },
253
253
  },
254
- });
255
-
256
- // Separate APIs for async workflows
257
- export const incrementAfter = createAsyncThunk(
258
- "counter/incrementAfter",
259
- async (
260
- { amount, delay }: { amount: number; delay: number },
261
- { dispatch }
262
- ) => {
263
- await new Promise((resolve) => setTimeout(resolve, delay));
264
254
 
265
- dispatch(counter.actions.increment(amount));
266
- }
267
- );
255
+ extraReducers: (builder) => {
256
+ // Handles fulfilled async thunk result
257
+ builder.addCase(incrementAfter.fulfilled, (state, action) => {
258
+ state.value += action.payload;
259
+ });
260
+ },
261
+ });
268
262
  ```
269
263
 
270
264
  ## Slice Usage
@@ -526,8 +520,10 @@ Methods are the orchestration layer of a slice.
526
520
  - receive any number of arguments
527
521
  - can return synchronous values or Promises
528
522
  - can access:
529
- - state, mutations, slibling methods, nested slices (through `this`)
530
- - Application-wide utilities (`this.global`)
523
+ - state, mutations, slibling methods, nested slices (through `this`)
524
+ - Root store (`this.root`)
525
+ - Parent slice (`this.parent`)
526
+ - Application-wide utilities (`this.utils`)
531
527
 
532
528
  Methods are not serialized, replayable, or represented in Redux DevTools action history.
533
529
 
@@ -547,20 +543,9 @@ Methods are designed for centralizing any slice-related logic:
547
543
  Methods should NOT:
548
544
 
549
545
  - include slice-unrelated logic.
546
+ - include UI layer logic.
550
547
  - mutate state directly. use mutations instead.
551
548
 
552
- Prefer:
553
-
554
- ```ts
555
- this.increment(1);
556
- ```
557
-
558
- Instead of:
559
-
560
- ```ts
561
- this.getState().value++;
562
- ```
563
-
564
549
  **Example:**
565
550
 
566
551
  ```ts
@@ -581,7 +566,7 @@ const counter = createSlice({
581
566
  async incrementAfter(amount: number, delay = 1000) {
582
567
  await new Promise((resolve) => setTimeout(resolve, delay));
583
568
  this.increment(amount);
584
- this.global.logger.info("Counter incremented");
569
+ this.utils.logger.info("Counter incremented");
585
570
  },
586
571
  },
587
572
  });
@@ -621,27 +606,27 @@ This currently not supported
621
606
 
622
607
  Slices can be composed by registering other slice instances through the `children` property.
623
608
 
624
- This allows related state and behavior to be organized into a hierarchical structure while preserving full type inference and ownership isolation.
609
+ This allows related state and behavior to be structured into a hierarchical ownership tree, while preserving full type inference, runtime path resolution, and instance isolation.
625
610
 
626
611
  ```ts
627
612
  import { products } from "./productsSlice";
628
613
  import { categories } from "./categoriesSlice";
629
614
 
630
615
  export const shop = createSlice({
631
- name: "shop",
616
+ name: "shop",
632
617
 
633
- state: {},
618
+ state: {},
634
619
 
635
- children: {
636
- products,
637
- categories,
638
- },
620
+ children: {
621
+ products,
622
+ categories,
623
+ },
639
624
  });
640
625
  ```
641
626
 
642
- **Accessing Child Slices:**
627
+ ### Accessing Children through Parent Slice
643
628
 
644
- Child slices are exposed directly on their parent slice.
629
+ Child slices are exposed directly on their parent slice instance.
645
630
 
646
631
  ```ts
647
632
  shop.products.add(...)
@@ -650,7 +635,7 @@ shop.categories.create(...)
650
635
  console.log(shop.products.getState());
651
636
  ```
652
637
 
653
- Deeply nested slice hierarchies are fully supported.
638
+ Deeply nested slice trees are fully supported, including recursive composition.
654
639
 
655
640
  ```ts
656
641
  admin.users.permissions.grant(...);
@@ -658,6 +643,16 @@ admin.users.permissions.grant(...);
658
643
  console.log(admin.users.permissions.getState());
659
644
  ```
660
645
 
646
+ ### Accessing Parent Slice from Children
647
+
648
+ Every slice instance has a runtime reference to its parent via `slice.parent`.
649
+
650
+ This allows also child slices to interact with sibling slices through the parent ownership scope.
651
+
652
+ ```ts
653
+ this.parent.categories.getState().list;
654
+ ```
655
+
661
656
  ### Reusing Slices
662
657
 
663
658
  A slice can be mounted multiple times within the same tree.
@@ -915,7 +910,7 @@ console.log(store.counter.getState());
915
910
 
916
911
  ## Accessing Store from Slices
917
912
 
918
- Every slice has access to the root store instance through `this.root`.
913
+ Every slice has access to the root store instance via `slice.root`.
919
914
 
920
915
  ```ts
921
916
  this.root.auth.getState().isAuthenticated;
@@ -927,68 +922,103 @@ this.root.auth.getState().isAuthenticated;
927
922
  - avoiding circular imports
928
923
  - application-wide orchestration
929
924
 
930
- ## Root Store Type Extension (Planned)
925
+ ---
931
926
 
932
- Overriding `OrcheStore.Slots.root` provides full root store typing throughout the application.
927
+ # Lineage & Clones
933
928
 
934
- > 🐞 Under active development: this currently causes a circular type inference limitation.
929
+ OrcheStore uses a lineage-based model for slice identity.
935
930
 
936
- ```ts
937
- import { createStore } from "orchestore";
931
+ **Why?**
938
932
 
939
- export const store = createStore({
940
- slices: {
941
- counter,
942
- },
943
- });
933
+ Slices can be used in multiple places in the store tree.
944
934
 
945
- declare module "orchestore" {
946
- namespace OrcheStore {
947
- interface Slots {
948
- root: typeof store; // Bugfix: Causes a circular type inference
949
- }
950
- }
951
- }
952
- ```
935
+ When this happens, OrcheStore creates a separate runtime instance for each usage. These instances are called **clones**.
936
+
937
+ A clone is an independent instance of a slice at runtime. It has its own state and runs separately from other clones, while still remaining part of a shared lineage.
938
+
939
+ A lineage (or family) is the set of all runtime instances that originate from the same slice definition.
940
+
941
+ **This means:**
942
+
943
+ - slices are not singletons
944
+ - a slice can appear multiple times in a tree
945
+ - each clone is fully isolated
946
+ - all instances created from the same definition are linked through lineage
947
+
948
+ ## Manual Cloning
949
+
950
+ A new detached clone can be created manually from any slice instance.
951
+
952
+ ### 1. Clone without state transformation
953
953
 
954
954
  ```ts
955
- this.root; // Before: any
956
- this.root; // After: fully typed store
955
+ const clone = slice.prototype.clone();
957
956
  ```
958
957
 
959
- **Rules:**
958
+ The new instance:
960
959
 
961
- - `root` must be a store instance created using `createStore`
962
- - `null` and `undefined` are excluded automatically
963
- - `typeof store | null | undefined` is equivalent to `typeof store`
964
- - Invalid types fall back to `any`
960
+ - belongs to the same lineage
961
+ - starts detached from the tree
962
+ - has no mounted path initially
963
+ - has its own ownership context
964
+ - uses the exact initial state of the source slice
965
965
 
966
- ---
966
+ ### 2. Clone with state transformation
967
967
 
968
- # Lineage & Clones
968
+ ```ts
969
+ const clone = slice.prototype.clone((state) => newState);
970
+ ```
969
971
 
970
- OrcheStore uses a lineage-based model for slice identity.
972
+ The provided function receives the fully resolved initial state (including nested slices) and returns the modified state for the new instance.
971
973
 
972
- **Why?**
974
+ The state transformer:
973
975
 
974
- Slices can be used in multiple places in the store tree.
976
+ - does not affect other lineage members
977
+ - supports nested slice state updates
978
+ - supports immutable updates (returning a new state object)
979
+ - supports mutable updates (Immer-style — no return required)
975
980
 
976
- When this happens, OrcheStore creates a separate runtime instance for each usage. These instances are called **clones**.
981
+ **Example:**
977
982
 
978
- A clone is an independent instance copy of a slice at runtime. It has its own state and runs separately from other clones, while still remaining part of a shared lineage.
983
+ ```ts
984
+ const crudSlice = createSlice({
985
+ name: "CRUD-Slice",
979
986
 
980
- A lineage (or family) is the set of all instances that come from the same slice definition.
987
+ state: {
988
+ endpoint: "",
989
+ },
981
990
 
982
- **This means:**
991
+ children: {
992
+ pagination: paginationSlice,
993
+ dropdown: searchDropdownSlice,
994
+ },
995
+ });
983
996
 
984
- - slices are not singletons
985
- - a slice can appear multiple times in a tree
986
- - each clone is fully isolated
987
- - all instances cloned from the same slice are linked through lineage
997
+ // Immutable style (returns new state object)
998
+ const productsSlice = crudSlice.prototype.clone((state) => ({
999
+ ...state,
1000
+ endpoint: "api/v1/products",
1001
+
1002
+ dropdown: {
1003
+ ...state.dropdown,
1004
+ supported: false,
1005
+ },
1006
+ }));
1007
+
1008
+ // Immer-style mutation (no return needed)
1009
+ const categoriesSlice = crudSlice.prototype.clone((state) => {
1010
+ state.endpoint = "api/v1/categories";
1011
+ state.pagination.supported = false;
1012
+ });
1013
+ ```
988
1014
 
989
1015
  ## Automatic Cloning
990
1016
 
991
- When a slice is reused through `children` or `slices`, OrcheStore automatically creates a new mounted instance for each usage.
1017
+ OrcheStore creates slice instances automatically in two cases:
1018
+
1019
+ ### 1. Reuse through `children` / `slices`
1020
+
1021
+ When a slice is reused through `children` (or `slices`), OrcheStore creates a new mounted instance for each usage.
992
1022
 
993
1023
  ```ts
994
1024
  const paginationSlice = createSlice({ ... });
@@ -1023,36 +1053,49 @@ shopSlice.a !== adminSlice.a;
1023
1053
  shopSlice.b !== adminSlice.a;
1024
1054
  ```
1025
1055
 
1026
- Each instance also receives its own path and its own ownership context:
1056
+ Each instance has its own ownership context:
1027
1057
 
1028
1058
  ```ts
1029
- shopSlice.a.path; // "shop.a"
1030
- shopSlice.b.path; // "shop.b"
1031
- adminSlice.a.path; // "admin.a"
1059
+ shopSlice.a.path; // "shop.a"
1060
+ shopSlice.b.path; // "shop.b"
1061
+ adminSlice.a.path; // "admin.a"
1032
1062
  ```
1033
1063
 
1034
- Although these instances are independent at runtime, they still belong to the same lineage.
1035
-
1036
- ## Manual Cloning
1064
+ ### 2. Cloning a parent slice (cascade cloning)
1037
1065
 
1038
- A new detached clone can be created manually from any slice instance:
1066
+ When a parent slice is cloned or reused, all its nested children are automatically cloned as well.
1039
1067
 
1040
1068
  ```ts
1041
- const clone = slice.prototype.clone();
1069
+ const crudSlice = createSlice({
1070
+ name: "CRUD-Slice",
1071
+
1072
+ state: {
1073
+ endpoint: "",
1074
+ },
1075
+
1076
+ children: {
1077
+ pagination: paginationSlice,
1078
+ dropdown: searchDropdownSlice,
1079
+ },
1080
+ });
1081
+
1082
+ const productsSlice = crudSlice.prototype.clone();
1083
+ const categoriesSlice = crudSlice.prototype.clone();
1042
1084
  ```
1043
1085
 
1044
- The new instance:
1086
+ Each clone receives its own independent subtree:
1045
1087
 
1046
- - belongs to the same lineage
1047
- - starts detached from the tree
1048
- - has no mounted path initially
1049
- - has its own ownership context
1088
+ ```ts
1089
+ productsSlice.pagination !== categoriesSlice.pagination;
1090
+ ```
1091
+
1092
+ This ensures that both parent and child slices remain fully isolated across all clone instances.
1050
1093
 
1051
1094
  ## Inspecting a Lineage
1052
1095
 
1053
1096
  **Get All Related Instances:**
1054
1097
 
1055
- Returns every instance in the lineage, **including** the current one.
1098
+ Returns every instance in the lineage, **including** the current instance.
1056
1099
 
1057
1100
  ```ts
1058
1101
  const lineage = slice.prototype.getLineage();
@@ -1064,9 +1107,9 @@ Useful for:
1064
1107
  - inspecting mounted instances
1065
1108
  - understanding tree distribution
1066
1109
 
1067
- **Get Clones:**
1110
+ **Get Sibling Clones:**
1068
1111
 
1069
- Returns all lineage members **except** the current instance.
1112
+ Returns every sibling in the lineage, **except** the current instance.
1070
1113
 
1071
1114
  ```ts
1072
1115
  const siblings = slice.prototype.getClones();
@@ -1080,8 +1123,6 @@ Useful for:
1080
1123
 
1081
1124
  ## Definition Type Checking
1082
1125
 
1083
- You can determine whether two slices belong to the same lineage:
1084
-
1085
1126
  You can check whether two slices belong to the same lineage:
1086
1127
 
1087
1128
  ```ts
@@ -1107,19 +1148,20 @@ slice2.prototype.isTypeOf(clone1); // false
1107
1148
 
1108
1149
  ## Summary
1109
1150
 
1110
- - Reusing a slice automatically creates mounted clones.
1111
1151
  - `clone()` creates a new detached lineage member.
1152
+ - `clone(stateTransformer)` allows per-instance state customization at creation time.
1153
+ - Reusing a slice automatically creates mounted clones.
1112
1154
  - Every clone is isolated at runtime.
1113
1155
  - All clones from the same definition belong to a shared lineage.
1114
1156
  - `getLineage()` returns all instances in a lineage.
1115
- - `getClones()` returns all related instances except the current one.
1157
+ - `getClones()` returns all related instances except the current instance.
1116
1158
  - `isTypeOf()` checks whether two instances belong to the same lineage.
1117
1159
 
1118
1160
  ---
1119
1161
 
1120
- # Global Utilities
1162
+ # Utilities
1121
1163
 
1122
- Global utilities allow slices and the root store to access shared runtime services through `global`.
1164
+ Application-wide utilities allow slices and stores to access shared runtime services through `utils`.
1123
1165
 
1124
1166
  Common use cases include:
1125
1167
 
@@ -1130,28 +1172,33 @@ Common use cases include:
1130
1172
  - runtime values that are difficult to access directly from slices
1131
1173
  - integrations with React hooks and third-party libraries
1132
1174
 
1133
- Utilities are registered using `provideGlobalUtils` and are accessible from any slice or the root store.
1175
+ Utilities are registered using `setUtils` and are accessible from any slice or the root store.
1134
1176
 
1135
- ## Accessing Global Utilities
1177
+ ## Accessing Utilities
1136
1178
 
1137
1179
  **Available:**
1138
1180
 
1139
- - Through the exposed store or slice instances
1181
+ - Through exposed store and slice instances
1140
1182
 
1141
1183
  ```ts
1142
- store.global;
1143
- slice.global;
1184
+ store.utils;
1185
+ slice.utils;
1186
+ this.utils; // Inside slice methods and mutations
1144
1187
  ```
1145
1188
 
1146
- - Inside slice methods
1189
+ - Through `getUtils`
1147
1190
 
1148
1191
  ```ts
1149
- this.global.notify("success", "Saved!");
1192
+ import { getUtils } from "orchestore";
1193
+
1194
+ const utils = getUtils();
1150
1195
  ```
1151
1196
 
1152
1197
  ## Utilities Type Extension
1153
1198
 
1154
- Overriding `OrcheStore.Slots.global` provides full typing everywhere.
1199
+ OrcheStore exposes user-definable type slots through `OrcheStore.Slots`.
1200
+
1201
+ By overriding `OrcheStore.Slots.utils`, application-specific utilities become available throughout the framework with full type safety.
1155
1202
 
1156
1203
  ```ts
1157
1204
  import type { NavigateFunction } from "react-router";
@@ -1159,7 +1206,7 @@ import type { NavigateFunction } from "react-router";
1159
1206
  declare module "orchestore" {
1160
1207
  namespace OrcheStore {
1161
1208
  interface Slots {
1162
- global: {
1209
+ utils: {
1163
1210
  navigate: NavigateFunction;
1164
1211
 
1165
1212
  notify(type: "info" | "error" | "success", message: string): void;
@@ -1169,30 +1216,43 @@ declare module "orchestore" {
1169
1216
  }
1170
1217
  ```
1171
1218
 
1172
- ```ts
1173
- this.global; // Before: any
1174
- this.global; // After: fully typed
1175
- ```
1219
+ **Notes:**
1176
1220
 
1177
- **Rules:**
1221
+ * `OrcheStore.Slots` can be extended using either `declare module "orchestore"` or `declare global`, depending on your project's type organization preferences.
1222
+ * If your project uses JavaScript without TypeScript, you can still extend these types by creating a separate declaration file (for example, `orchestore.d.ts`). This allows editors and tooling to provide type checking and IntelliSense while keeping your application code in JavaScript.
1223
+
1224
+ **Rules**
1225
+
1226
+ * `utils` must resolve to an object type; otherwise, it falls back to `any`.
1227
+ * `null` and `undefined` are automatically excluded. For example, `object | null | undefined` resolves to `object`.
1228
+
1229
+ **Type Safety**
1230
+
1231
+ Before extending `OrcheStore.Slots.utils`, all utility-related APIs are typed as `any`.
1232
+
1233
+ After extending `OrcheStore.Slots.utils`, the inferred type is automatically applied throughout the framework, including:
1234
+
1235
+ * `store.utils`
1236
+ * `slice.utils`
1237
+ * `this.utils` inside mutations and methods
1238
+ * `getUtils()`
1239
+ * `setUtils()`
1240
+ * `type Utils`
1178
1241
 
1179
- - `global` must be an object
1180
- - `null` and `undefined` are excluded automatically
1181
- - `object | null | undefined` is equivalent to `object`
1182
- - Invalid types fall back to `any`
1242
+ This provides consistent type safety and IntelliSense across all utility access points without requiring additional type declarations.
1183
1243
 
1184
1244
  ## Providing Runtime Utilities
1185
1245
 
1186
- Global utility values can be registered or updated at runtime.
1246
+ Application-wide utility values can be registered or updated at runtime.
1187
1247
 
1188
1248
  ```ts
1189
1249
  import { useEffect } from "react";
1190
1250
  import { useNavigate } from "react-router";
1191
- import { provideGlobalUtils } from "orchestore";
1251
+ import { setUtils } from "orchestore";
1192
1252
  import { feedbacks } from "./ui-feedbacks";
1193
1253
  import { store } from "./store";
1194
1254
 
1195
- provideGlobalUtils({
1255
+ setUtils({
1196
1256
  notify(type, message) {
1197
1257
  feedbacks.notify(type, message);
1198
1258
  },
@@ -1202,7 +1262,7 @@ export default function App() {
1202
1262
  const navigate = useNavigate();
1203
1263
 
1204
1264
  useEffect(() => {
1205
- provideGlobalUtils({ navigate });
1265
+ setUtils({ navigate });
1206
1266
  }, [navigate]);
1207
1267
 
1208
1268
  return (
@@ -1213,9 +1273,9 @@ export default function App() {
1213
1273
  }
1214
1274
  ```
1215
1275
 
1216
- ## Using Global Utilities in Slices
1276
+ ## Using Utilities in Slices
1217
1277
 
1218
- Global utilities can be used anywhere a slice instance is available.
1278
+ Application-wide utilities can be used anywhere a slice instance is available.
1219
1279
 
1220
1280
  ```ts
1221
1281
  methods: {
@@ -1225,13 +1285,13 @@ methods: {
1225
1285
 
1226
1286
  const response = await api.users.add(data);
1227
1287
 
1228
- this.global.notify("success", "User added successfully!");
1288
+ this.utils.notify("success", "User added successfully!");
1229
1289
 
1230
1290
  this.setLoading(false);
1231
1291
 
1232
- this.global.navigate("/users/" + response.id);
1292
+ this.utils.navigate("/users/" + response.id);
1233
1293
  } catch (error) {
1234
- this.global.notify("error", "Failed to add user");
1294
+ this.utils.notify("error", "Failed to add user");
1235
1295
 
1236
1296
  console.error(error);
1237
1297
  }
@@ -1267,13 +1327,13 @@ const counter = createSlice({
1267
1327
  },
1268
1328
 
1269
1329
  children: {
1270
- subCounter: createSlice({
1271
- name: "subCounter",
1330
+ subCounter: createSlice({
1331
+ name: "subCounter",
1272
1332
 
1273
- state: {
1274
- value: 0,
1275
- },
1276
- }),
1333
+ state: {
1334
+ value: 0,
1335
+ },
1336
+ }),
1277
1337
  },
1278
1338
  });
1279
1339
  ```
@@ -1294,42 +1354,6 @@ counter.incrementAfter(amount: number, delay?: number): Promise<number>;
1294
1354
 
1295
1355
  No manual type declarations required.
1296
1356
 
1297
- ## Framework Type Extensions
1298
-
1299
- OrcheStore also exposes user-definable type slots through `OrcheStore.Slots`.
1300
-
1301
- These slots allow application-specific types to be injected into the framework and become available everywhere with full type safety.
1302
-
1303
- | Slot | Purpose |
1304
- | -------------------------- | ----------------------- |
1305
- | `OrcheStore.Slots.root` | Root store typing |
1306
- | `OrcheStore.Slots.global` | Global utilities typing |
1307
-
1308
- ```ts
1309
- declare module "orhestore" {
1310
- namespace OrcheStore {
1311
- interface Slots {
1312
- root: typeof store; // Bugfix: Causes a circular type inference
1313
-
1314
- global: {
1315
- navigate: NavigateFunction;
1316
- notify(type: "info" | "error" | "success", message: string): void;
1317
- };
1318
- }
1319
- }
1320
- }
1321
- ```
1322
-
1323
- This provides full typing for APIs such as:
1324
-
1325
- ```ts
1326
- this.root;
1327
- this.global;
1328
-
1329
- store.global;
1330
- counter.global;
1331
- ```
1332
-
1333
1357
  ---
1334
1358
 
1335
1359
  # Status