@context-action/core 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,187 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity granting the License.
13
+
14
+ "Legal Entity" shall mean the union of the acting entity and all
15
+ other entities that control, are controlled by, or are under common
16
+ control with that entity. For the purposes of this definition,
17
+ "control" means (i) the power, direct or indirect, to cause the
18
+ direction or management of such entity, whether by contract or
19
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
20
+ outstanding shares, or (iii) beneficial ownership of such entity.
21
+
22
+ "You" (or "Your") shall mean an individual or Legal Entity
23
+ exercising permissions granted by this License.
24
+
25
+ "Source" shall mean the preferred form for making modifications,
26
+ including but not limited to software source code, documentation
27
+ source, and configuration files.
28
+
29
+ "Object" shall mean any form resulting from mechanical
30
+ transformation or translation of a Source form, including but
31
+ not limited to compiled object code, generated documentation,
32
+ and conversions to other media types.
33
+
34
+ "Work" shall mean the work of authorship, whether in Source or
35
+ Object form, made available under the License, as indicated by a
36
+ copyright notice that is included in or attached to the work
37
+ (which shall not include communications that are marked or
38
+ otherwise designated in writing by the copyright owner as
39
+ "Not a Work").
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based upon (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and derivative works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control
58
+ systems, and issue tracking systems that are managed by, or on behalf
59
+ of, the Licensor for the purpose of discussing and improving the Work,
60
+ but excluding communication that is marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to use, reproduce, modify, distribute, prepare
71
+ Derivative Works of, and perform and display the Work and such
72
+ Derivative Works in all media and formats now known or hereafter
73
+ developed.
74
+
75
+ 3. Grant of Patent License. Subject to the terms and conditions of
76
+ this License, each Contributor hereby grants to You a perpetual,
77
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78
+ (except as stated in this section) patent license to make, have made,
79
+ use, offer to sell, sell, import, and otherwise transfer the Work,
80
+ where such license applies only to those patent claims licensable
81
+ by such Contributor that are necessarily infringed by their
82
+ Contribution(s) alone or by combination of their Contribution(s)
83
+ with the Work to which such Contribution(s) was submitted. If You
84
+ institute patent litigation against any entity (including a
85
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
86
+ or a Contribution incorporated within the Work constitutes direct
87
+ or contributory patent infringement, then any patent licenses
88
+ granted to You under this License for that Work shall terminate
89
+ as of the date such litigation is filed.
90
+
91
+ 4. Redistribution. You may reproduce and distribute copies of the
92
+ Work or Derivative Works thereof in any medium, with or without
93
+ modifications, and in Source or Object form, provided that You
94
+ meet the following conditions:
95
+
96
+ (a) You must give any other recipients of the Work or
97
+ Derivative Works a copy of this License; and
98
+
99
+ (b) You must cause any modified files to carry prominent notices
100
+ stating that You changed the files; and
101
+
102
+ (c) You must retain, in the Source form of any Derivative Works
103
+ that You distribute, all copyright, trademark, patent,
104
+ attribution and other notices from the Source form of the Work,
105
+ excluding those notices that do not pertain to any part of
106
+ the Derivative Works; and
107
+
108
+ (d) If the Work includes a "NOTICE" text file as part of its
109
+ distribution, then any Derivative Works that You distribute must
110
+ include a readable copy of the attribution notices contained
111
+ within such NOTICE file, excluding those notices that do not
112
+ pertain to any part of the Derivative Works, in at least one
113
+ of the following places: within a NOTICE text file distributed
114
+ as part of the Derivative Works; within the Source form or
115
+ documentation, if provided along with the Derivative Works; or,
116
+ within a display generated by the Derivative Works, if and
117
+ wherever such third-party notices normally appear. The contents
118
+ of the NOTICE file are for informational purposes only and
119
+ do not modify the License. You may add Your own attribution
120
+ notices within Derivative Works that You distribute, alongside
121
+ or as an addendum to the NOTICE text from the Work, provided
122
+ that such additional attribution notices cannot be construed
123
+ as modifying the License.
124
+
125
+ You may add Your own copyright notice as an addendum to the copyright
126
+ notice on the Work.
127
+
128
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
129
+ any Contribution intentionally submitted for inclusion in the Work
130
+ by You to the Licensor shall be under the terms and conditions of
131
+ this License, without any additional terms or conditions.
132
+ Notwithstanding the above, nothing herein shall supersede or modify
133
+ the terms of any separate license agreement you may have executed
134
+ with Licensor regarding such Contributions.
135
+
136
+ 6. Trademarks. This License does not grant permission to use the trade
137
+ names, trademarks, service marks, or product names of the Licensor,
138
+ except as required for reasonable and customary use in describing the
139
+ origin of the Work and reproducing the content of the NOTICE file.
140
+
141
+ 7. Disclaimer of Warranty. Unless required by applicable law or
142
+ agreed to in writing, Licensor provides the Work (and each
143
+ Contributor provides its Contributions) on an "AS IS" BASIS,
144
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
145
+ implied, including, without limitation, any warranties or conditions
146
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
147
+ PARTICULAR PURPOSE. You are solely responsible for determining the
148
+ appropriateness of using or redistributing the Work and assume any
149
+ risks associated with Your exercise of permissions under this License.
150
+
151
+ 8. Limitation of Liability. In no event and under no legal theory,
152
+ whether in tort (including negligence), contract, or otherwise,
153
+ unless required by applicable law (such as deliberate and grossly
154
+ negligent acts) or agreed to in writing, shall any Contributor be
155
+ liable to You for damages, including any direct, indirect, special,
156
+ incidental, or consequential damages of any character arising as a
157
+ result of this License or out of the use or inability to use the
158
+ Work (including but not limited to damages for loss of goodwill,
159
+ work stoppage, computer failure or malfunction, or any and all
160
+ other commercial damages or losses), even if such Contributor
161
+ has been advised of the possibility of such damages.
162
+
163
+ 9. Accepting Warranty or Support. You may choose to offer, and to
164
+ charge a fee for, warranty, support, indemnity or other liability
165
+ obligations and/or rights consistent with this License. However, in
166
+ accepting such obligations, You may act only on Your own behalf and on
167
+ Your sole responsibility, not on behalf of any other Contributor, and
168
+ only if You agree to indemnify, defend, and hold each Contributor
169
+ harmless for any liability incurred by, or claims asserted against,
170
+ such Contributor by reason of your accepting any such warranty or
171
+ support.
172
+
173
+ END OF TERMS AND CONDITIONS
174
+
175
+ Copyright 2025 mineclover
176
+
177
+ Licensed under the Apache License, Version 2.0 (the "License");
178
+ you may not use this file except in compliance with the License.
179
+ You may obtain a copy of the License at
180
+
181
+ http://www.apache.org/licenses/LICENSE-2.0
182
+
183
+ Unless required by applicable law or agreed to in writing, software
184
+ distributed under the License is distributed on an "AS IS" BASIS,
185
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
186
+ See the License for the specific language governing permissions and
187
+ limitations under the License.
package/README.ko.md ADDED
@@ -0,0 +1,328 @@
1
+ # @context-action/core
2
+
3
+ React 통합을 지원하는 타입 안전한 액션 파이프라인 관리 TypeScript 라이브러리입니다.
4
+
5
+ ## 주요 기능
6
+
7
+ - 🔒 **타입 안전성**: 엄격한 타입 검사를 지원하는 완전한 TypeScript 지원
8
+ - ⚡ **파이프라인 시스템**: 우선순위 제어를 통한 다중 핸들러 체이닝
9
+ - 🎯 **Context 통합**: React Context와의 원활한 통합
10
+ - 🔄 **비동기 지원**: 동기 및 비동기 작업 모두 처리
11
+ - 🛡️ **에러 처리**: 내장된 에러 처리 및 중단 메커니즘
12
+ - 📦 **경량화**: 제로 의존성으로 최소 번들 크기
13
+
14
+ ## 설치
15
+
16
+ ```bash
17
+ npm install @context-action/core
18
+ # 또는
19
+ yarn add @context-action/core
20
+ # 또는
21
+ pnpm add @context-action/core
22
+ ```
23
+
24
+ ## 빠른 시작
25
+
26
+ ### 1. 액션 타입 정의
27
+
28
+ ```typescript
29
+ import { ActionPayloadMap } from '@context-action/core';
30
+
31
+ interface AppActions extends ActionPayloadMap {
32
+ increment: void;
33
+ decrement: void;
34
+ setCount: number;
35
+ reset: void;
36
+ }
37
+ ```
38
+
39
+ ### 2. 액션 컨텍스트 생성
40
+
41
+ ```typescript
42
+ import { createActionContext } from '@context-action/core';
43
+
44
+ const { Provider, useAction, useActionHandler } = createActionContext<AppActions>();
45
+ ```
46
+
47
+ ### 3. React 컴포넌트에서 사용
48
+
49
+ ```typescript
50
+ function Counter() {
51
+ const [count, setCount] = useState(0);
52
+ const action = useAction();
53
+
54
+ // 액션 핸들러 등록
55
+ useActionHandler('increment', () => {
56
+ setCount(prev => prev + 1);
57
+ }, { priority: 1 });
58
+
59
+ useActionHandler('setCount', (payload) => {
60
+ setCount(payload);
61
+ });
62
+
63
+ return (
64
+ <div>
65
+ <p>카운트: {count}</p>
66
+ <button onClick={() => action.dispatch('increment')}>+1</button>
67
+ <button onClick={() => action.dispatch('setCount', 10)}>10으로 설정</button>
68
+ </div>
69
+ );
70
+ }
71
+
72
+ function App() {
73
+ return (
74
+ <Provider>
75
+ <Counter />
76
+ </Provider>
77
+ );
78
+ }
79
+ ```
80
+
81
+ ## API 참조
82
+
83
+ ### `createActionContext<T>()`
84
+
85
+ 지정된 액션 타입 맵으로 새로운 액션 컨텍스트를 생성합니다.
86
+
87
+ **반환값:**
88
+ - `Provider`: React 컨텍스트 프로바이더 컴포넌트
89
+ - `useAction()`: 액션 디스패처를 가져오는 훅
90
+ - `useActionHandler()`: 액션 핸들러를 등록하는 훅
91
+ - `useActionContext()`: 원시 컨텍스트에 접근하는 훅
92
+
93
+ ### `ActionRegister<T>`
94
+
95
+ 액션 파이프라인을 관리하는 핵심 클래스입니다.
96
+
97
+ #### 메서드
98
+
99
+ - `register(action, handler, config?)`: 액션 핸들러 등록
100
+ - `dispatch(action, payload?)`: 파이프라인을 통해 액션 디스패치
101
+
102
+ #### 핸들러 설정
103
+
104
+ ```typescript
105
+ interface HandlerConfig {
106
+ priority?: number; // 우선순위가 높은 핸들러가 먼저 실행 (기본값: 0)
107
+ id?: string; // 핸들러의 고유 식별자
108
+ blocking?: boolean; // 비동기 핸들러를 기다릴지 여부 (기본값: false)
109
+ }
110
+ ```
111
+
112
+ #### 파이프라인 컨트롤러
113
+
114
+ 각 핸들러는 컨트롤러 객체를 받습니다:
115
+
116
+ ```typescript
117
+ interface PipelineController<T> {
118
+ next(): void; // 다음 핸들러로 진행
119
+ abort(reason?: string): void; // 파이프라인 중단
120
+ modifyPayload(modifier: (payload: T) => T): void; // 후속 핸들러를 위한 페이로드 수정
121
+ }
122
+ ```
123
+
124
+ ## 고급 사용법
125
+
126
+ ### 우선순위 기반 실행
127
+
128
+ ```typescript
129
+ useActionHandler('saveData', () => {
130
+ console.log('검증');
131
+ }, { priority: 10 }); // 첫 번째 실행
132
+
133
+ useActionHandler('saveData', () => {
134
+ console.log('데이터베이스에 저장');
135
+ }, { priority: 5 }); // 두 번째 실행
136
+
137
+ useActionHandler('saveData', () => {
138
+ console.log('UI 업데이트');
139
+ }, { priority: 1 }); // 마지막 실행
140
+ ```
141
+
142
+ ### 비동기 핸들러
143
+
144
+ ```typescript
145
+ useActionHandler('fetchData', async (payload, controller) => {
146
+ try {
147
+ const data = await api.fetch(payload.url);
148
+ controller.modifyPayload(prev => ({ ...prev, data }));
149
+ } catch (error) {
150
+ controller.abort('데이터 가져오기 실패');
151
+ }
152
+ }, { blocking: true }); // 이 핸들러가 완료될 때까지 대기
153
+ ```
154
+
155
+ ### 에러 처리
156
+
157
+ ```typescript
158
+ useActionHandler('riskyOperation', (payload, controller) => {
159
+ if (!payload.isValid) {
160
+ controller.abort('유효하지 않은 페이로드');
161
+ return;
162
+ }
163
+ // 처리 계속...
164
+ controller.next();
165
+ });
166
+ ```
167
+
168
+ ## 실제 사용 예제
169
+
170
+ ### 알림 시스템
171
+
172
+ ```typescript
173
+ interface NotificationActions extends ActionPayloadMap {
174
+ showSuccess: { message: string };
175
+ showError: { message: string };
176
+ hideNotification: void;
177
+ }
178
+
179
+ const { Provider, useAction, useActionHandler } = createActionContext<NotificationActions>();
180
+
181
+ function NotificationProvider({ children }: { children: ReactNode }) {
182
+ const [notification, setNotification] = useState<{
183
+ message: string;
184
+ type: 'success' | 'error';
185
+ } | null>(null);
186
+
187
+ useActionHandler('showSuccess', ({ message }) => {
188
+ setNotification({ message, type: 'success' });
189
+ });
190
+
191
+ useActionHandler('showError', ({ message }) => {
192
+ setNotification({ message, type: 'error' });
193
+ });
194
+
195
+ useActionHandler('hideNotification', () => {
196
+ setNotification(null);
197
+ });
198
+
199
+ return (
200
+ <Provider>
201
+ {children}
202
+ {notification && (
203
+ <div className={`notification ${notification.type}`}>
204
+ {notification.message}
205
+ <button onClick={() => useAction().dispatch('hideNotification')}>
206
+ ×
207
+ </button>
208
+ </div>
209
+ )}
210
+ </Provider>
211
+ );
212
+ }
213
+ ```
214
+
215
+ ### 사용자 관리 시스템
216
+
217
+ ```typescript
218
+ interface UserActions extends ActionPayloadMap {
219
+ loginUser: { email: string; password: string };
220
+ logoutUser: void;
221
+ updateProfile: { name: string; avatar?: File };
222
+ }
223
+
224
+ function UserManager() {
225
+ const [user, setUser] = useState<User | null>(null);
226
+ const [loading, setLoading] = useState(false);
227
+ const action = useAction();
228
+
229
+ // 로그인 검증
230
+ useActionHandler('loginUser', ({ email, password }, controller) => {
231
+ if (!email || !password) {
232
+ controller.abort('이메일과 비밀번호를 입력해주세요');
233
+ return;
234
+ }
235
+ }, { priority: 10 });
236
+
237
+ // 로그인 API 호출
238
+ useActionHandler('loginUser', async ({ email, password }, controller) => {
239
+ setLoading(true);
240
+ try {
241
+ const userData = await authAPI.login(email, password);
242
+ controller.modifyPayload(prev => ({ ...prev, userData }));
243
+ } catch (error) {
244
+ controller.abort('로그인 실패');
245
+ } finally {
246
+ setLoading(false);
247
+ }
248
+ }, { priority: 5, blocking: true });
249
+
250
+ // 사용자 상태 업데이트
251
+ useActionHandler('loginUser', (payload: any) => {
252
+ setUser(payload.userData);
253
+ localStorage.setItem('user', JSON.stringify(payload.userData));
254
+ }, { priority: 1 });
255
+
256
+ // 로그아웃
257
+ useActionHandler('logoutUser', () => {
258
+ setUser(null);
259
+ localStorage.removeItem('user');
260
+ });
261
+
262
+ return (
263
+ <div>
264
+ {user ? (
265
+ <div>
266
+ <p>환영합니다, {user.name}님!</p>
267
+ <button onClick={() => action.dispatch('logoutUser')}>
268
+ 로그아웃
269
+ </button>
270
+ </div>
271
+ ) : (
272
+ <LoginForm onLogin={(email, password) =>
273
+ action.dispatch('loginUser', { email, password })
274
+ } />
275
+ )}
276
+ </div>
277
+ );
278
+ }
279
+ ```
280
+
281
+ ## TypeScript 지원
282
+
283
+ 이 라이브러리는 TypeScript로 작성되었으며 완전한 타입 안전성을 제공합니다:
284
+
285
+ ```typescript
286
+ // ✅ 타입 안전한 액션 디스패치
287
+ action.dispatch('setCount', 42); // 정상
288
+ action.dispatch('setCount', 'invalid'); // ❌ 타입 에러
289
+
290
+ // ✅ 타입 안전한 핸들러 등록
291
+ useActionHandler('setCount', (count: number) => {
292
+ // count는 자동으로 number 타입으로 추론됩니다
293
+ });
294
+ ```
295
+
296
+ ## 성능 고려사항
297
+
298
+ - **경량화**: 라이브러리는 매우 작으며 제로 의존성을 가집니다
299
+ - **메모화**: 불필요한 리렌더링을 방지하기 위해 적절한 메모화를 사용하세요
300
+ - **핸들러 등록**: 가능한 한 컴포넌트 외부에서 핸들러를 정의하세요
301
+
302
+ ```typescript
303
+ // ✅ 좋은 예
304
+ const handleIncrement = useCallback(() => {
305
+ setCount(prev => prev + 1);
306
+ }, []);
307
+
308
+ useActionHandler('increment', handleIncrement);
309
+
310
+ // ❌ 피해야 할 예 (매번 새로운 함수 생성)
311
+ useActionHandler('increment', () => {
312
+ setCount(prev => prev + 1);
313
+ });
314
+ ```
315
+
316
+ ## 기여하기
317
+
318
+ 기여를 환영합니다! Pull Request를 자유롭게 제출해 주세요.
319
+
320
+ ## 라이선스
321
+
322
+ Apache-2.0 © [mineclover](https://github.com/mineclover)
323
+
324
+ ## 관련 링크
325
+
326
+ - [English README](./README.md) - 영문 버전
327
+ - [GitHub Repository](https://github.com/mineclover/context-action) - 소스 코드
328
+ - [Issues](https://github.com/mineclover/context-action/issues) - 버그 리포트 및 기능 요청
package/README.md ADDED
@@ -0,0 +1,195 @@
1
+ # @context-action/core
2
+
3
+ A TypeScript library for type-safe action pipeline management with React integration.
4
+
5
+ ## Features
6
+
7
+ - 🔒 **Type-safe**: Full TypeScript support with strict type checking
8
+ - ⚡ **Pipeline System**: Chain multiple handlers with priority control
9
+ - 🎯 **Context Integration**: Seamless React Context integration
10
+ - 🔄 **Async Support**: Handle both sync and async operations
11
+ - 🛡️ **Error Handling**: Built-in error handling and abort mechanisms
12
+ - 📦 **Lightweight**: Minimal bundle size with zero dependencies
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @context-action/core
18
+ # or
19
+ yarn add @context-action/core
20
+ # or
21
+ pnpm add @context-action/core
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ### 1. Define your action types
27
+
28
+ ```typescript
29
+ import { ActionPayloadMap } from '@context-action/core';
30
+
31
+ interface AppActions extends ActionPayloadMap {
32
+ increment: void;
33
+ decrement: void;
34
+ setCount: number;
35
+ reset: void;
36
+ }
37
+ ```
38
+
39
+ ### 2. Create action context
40
+
41
+ ```typescript
42
+ import { createActionContext } from '@context-action/core';
43
+
44
+ const { Provider, useAction, useActionHandler } = createActionContext<AppActions>();
45
+ ```
46
+
47
+ ### 3. Use in your React components
48
+
49
+ ```typescript
50
+ function Counter() {
51
+ const [count, setCount] = useState(0);
52
+ const action = useAction();
53
+
54
+ // Register action handlers
55
+ useActionHandler('increment', () => {
56
+ setCount(prev => prev + 1);
57
+ }, { priority: 1 });
58
+
59
+ useActionHandler('setCount', (payload) => {
60
+ setCount(payload);
61
+ });
62
+
63
+ return (
64
+ <div>
65
+ <p>Count: {count}</p>
66
+ <button onClick={() => action.dispatch('increment')}>+1</button>
67
+ <button onClick={() => action.dispatch('setCount', 10)}>Set to 10</button>
68
+ </div>
69
+ );
70
+ }
71
+
72
+ function App() {
73
+ return (
74
+ <Provider>
75
+ <Counter />
76
+ </Provider>
77
+ );
78
+ }
79
+ ```
80
+
81
+ ## API Reference
82
+
83
+ ### `createActionContext<T>()`
84
+
85
+ Creates a new action context with the specified action type map.
86
+
87
+ **Returns:**
88
+ - `Provider`: React context provider component
89
+ - `useAction()`: Hook to get the action dispatcher
90
+ - `useActionHandler()`: Hook to register action handlers
91
+ - `useActionContext()`: Hook to access the raw context
92
+
93
+ ### `ActionRegister<T>`
94
+
95
+ Core class for managing action pipelines.
96
+
97
+ #### Methods
98
+
99
+ - `register(action, handler, config?)`: Register an action handler
100
+ - `dispatch(action, payload?)`: Dispatch an action through the pipeline
101
+
102
+ #### Handler Configuration
103
+
104
+ ```typescript
105
+ interface HandlerConfig {
106
+ priority?: number; // Higher priority handlers run first (default: 0)
107
+ id?: string; // Unique identifier for the handler
108
+ blocking?: boolean; // Whether to wait for async handlers (default: false)
109
+ }
110
+ ```
111
+
112
+ #### Pipeline Controller
113
+
114
+ Each handler receives a controller object:
115
+
116
+ ```typescript
117
+ interface PipelineController<T> {
118
+ next(): void; // Continue to next handler
119
+ abort(reason?: string): void; // Abort the pipeline
120
+ modifyPayload(modifier: (payload: T) => T): void; // Modify payload for subsequent handlers
121
+ }
122
+ ```
123
+
124
+ ## Advanced Usage
125
+
126
+ ### Priority-based Execution
127
+
128
+ ```typescript
129
+ useActionHandler('saveData', () => {
130
+ console.log('Validation');
131
+ }, { priority: 10 }); // Runs first
132
+
133
+ useActionHandler('saveData', () => {
134
+ console.log('Save to database');
135
+ }, { priority: 5 }); // Runs second
136
+
137
+ useActionHandler('saveData', () => {
138
+ console.log('Update UI');
139
+ }, { priority: 1 }); // Runs last
140
+ ```
141
+
142
+ ### Async Handlers
143
+
144
+ ```typescript
145
+ useActionHandler('fetchData', async (payload, controller) => {
146
+ try {
147
+ const data = await api.fetch(payload.url);
148
+ controller.modifyPayload(prev => ({ ...prev, data }));
149
+ } catch (error) {
150
+ controller.abort('Failed to fetch data');
151
+ }
152
+ }, { blocking: true }); // Wait for this handler to complete
153
+ ```
154
+
155
+ ### Error Handling
156
+
157
+ ```typescript
158
+ useActionHandler('riskyOperation', (payload, controller) => {
159
+ if (!payload.isValid) {
160
+ controller.abort('Invalid payload');
161
+ return;
162
+ }
163
+ // Continue processing...
164
+ controller.next();
165
+ });
166
+ ```
167
+
168
+ ## TypeScript Support
169
+
170
+ This library is written in TypeScript and provides full type safety:
171
+
172
+ ```typescript
173
+ // ✅ Type-safe action dispatching
174
+ action.dispatch('setCount', 42); // OK
175
+ action.dispatch('setCount', 'invalid'); // ❌ Type error
176
+
177
+ // ✅ Type-safe handler registration
178
+ useActionHandler('setCount', (count: number) => {
179
+ // count is automatically typed as number
180
+ });
181
+ ```
182
+
183
+ ## Contributing
184
+
185
+ Contributions are welcome! Please feel free to submit a Pull Request.
186
+
187
+ ## License
188
+
189
+ Apache-2.0 © [mineclover](https://github.com/mineclover)
190
+
191
+ ## Links
192
+
193
+ - [한국어 README](./README.ko.md) - Korean version
194
+ - [GitHub Repository](https://github.com/mineclover/context-action) - Source code
195
+ - [Issues](https://github.com/mineclover/context-action/issues) - Bug reports and feature requests