@miurajs/miura-data-flow 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/README.md ADDED
@@ -0,0 +1,565 @@
1
+ # miura Data Flow
2
+
3
+ Modern, reactive state management for miura applications. Combines the best of Redux, Zustand, and modern patterns with zero boilerplate and maximum performance.
4
+
5
+ ## Features
6
+
7
+ - **🚀 Reactive State Management** - Automatic updates when state changes
8
+ - **🔧 Middleware System** - Extensible with logging, persistence, API integration
9
+ - **🌍 Global State** - Application-wide state management
10
+ - **💾 Built-in Caching** - Intelligent caching with TTL
11
+ - **🔌 API Integration** - Automatic API calls with state updates
12
+ - **🛠️ DevTools Support** - Redux DevTools integration
13
+ - **📝 TypeScript First** - Full type safety and IntelliSense
14
+ - **⚡ Performance Optimized** - Efficient subscriptions and updates
15
+
16
+ ## Quick Start
17
+
18
+ ```typescript
19
+ import { Store, globalState, createLoggerMiddleware } from '@miura/miura-data-flow';
20
+
21
+ // Create a store
22
+ const store = new Store({ count: 0, user: null });
23
+
24
+ // Add middleware
25
+ store.use(createLoggerMiddleware());
26
+
27
+ // Define actions
28
+ store.defineActions({
29
+ increment: (state) => ({ count: state.count + 1 }),
30
+ setUser: (state, user) => ({ user })
31
+ });
32
+
33
+ // Subscribe to changes
34
+ const unsubscribe = store.subscribe((state, prevState) => {
35
+ console.log('State changed:', state);
36
+ });
37
+
38
+ // Dispatch actions
39
+ await store.dispatch('increment');
40
+ await store.dispatch('setUser', { id: '1', name: 'John' });
41
+ ```
42
+
43
+ ## Core Concepts
44
+
45
+ ### Store
46
+
47
+ The main state container that manages your application state.
48
+
49
+ ```typescript
50
+ import { Store } from '@miura/miura-data-flow';
51
+
52
+ interface AppState {
53
+ count: number;
54
+ user: User | null;
55
+ todos: Todo[];
56
+ }
57
+
58
+ const store = new Store<AppState>({
59
+ count: 0,
60
+ user: null,
61
+ todos: []
62
+ });
63
+ ```
64
+
65
+ ### Actions
66
+
67
+ Define how your state can be updated.
68
+
69
+ ```typescript
70
+ store.defineActions({
71
+ // Simple state update
72
+ increment: (state) => ({ count: state.count + 1 }),
73
+
74
+ // With parameters
75
+ setUser: (state, user: User) => ({ user }),
76
+
77
+ // Async actions
78
+ async fetchUser: async (state, userId: string) => {
79
+ const user = await fetch(`/api/users/${userId}`).then(r => r.json());
80
+ return { user };
81
+ },
82
+
83
+ // Complex updates
84
+ addTodo: (state, todo: Todo) => ({
85
+ todos: [...state.todos, todo]
86
+ })
87
+ });
88
+ ```
89
+
90
+ ### Subscriptions
91
+
92
+ React to state changes automatically.
93
+
94
+ ```typescript
95
+ // Subscribe to all changes
96
+ const unsubscribe = store.subscribe((state, prevState) => {
97
+ console.log('State changed:', state);
98
+ });
99
+
100
+ // Subscribe to specific property
101
+ const unsubscribeCount = store.subscribeTo('count', (count, prevCount) => {
102
+ console.log(`Count changed from ${prevCount} to ${count}`);
103
+ });
104
+
105
+ // Subscribe with selector
106
+ const unsubscribeUser = store.subscribe(
107
+ (state, prevState) => {
108
+ console.log('User changed:', state.user);
109
+ },
110
+ (state) => state.user // Only trigger when user changes
111
+ );
112
+ ```
113
+
114
+ ## Middleware System
115
+
116
+ ### Built-in Middleware
117
+
118
+ #### Logger Middleware
119
+
120
+ ```typescript
121
+ import { createLoggerMiddleware } from '@miura/miura-data-flow';
122
+
123
+ store.use(createLoggerMiddleware());
124
+ // Logs all actions and state changes to console
125
+ ```
126
+
127
+ #### Persistence Middleware
128
+
129
+ ```typescript
130
+ import { createPersistenceMiddleware } from '@miura/miura-data-flow';
131
+
132
+ store.use(createPersistenceMiddleware(['user', 'settings']));
133
+ // Automatically saves/loads specified properties to localStorage
134
+ ```
135
+
136
+ #### API Middleware
137
+
138
+ ```typescript
139
+ import { createApiMiddleware } from '@miura/miura-data-flow';
140
+
141
+ store.use(createApiMiddleware({
142
+ baseURL: 'https://api.example.com',
143
+ headers: {
144
+ 'Authorization': 'Bearer token'
145
+ },
146
+ timeout: 5000
147
+ }));
148
+
149
+ // Now you can dispatch API actions
150
+ store.defineActions({
151
+ api_fetchUsers: () => {}, // Will automatically fetch /fetchUsers
152
+ api_createUser: () => {} // Will automatically POST to /createUser
153
+ });
154
+
155
+ await store.dispatch('api_fetchUsers');
156
+ await store.dispatch('api_createUser', { method: 'POST', data: userData });
157
+ ```
158
+
159
+ #### Cache Middleware
160
+
161
+ ```typescript
162
+ import { createCacheMiddleware } from '@miura/miura-data-flow';
163
+
164
+ store.use(createCacheMiddleware(5 * 60 * 1000)); // 5 minutes TTL
165
+ // Caches API responses for 5 minutes
166
+ ```
167
+
168
+ #### DevTools Middleware
169
+
170
+ ```typescript
171
+ import { createDevToolsMiddleware } from '@miura/miura-data-flow';
172
+
173
+ store.use(createDevToolsMiddleware('MyApp'));
174
+ // Enables Redux DevTools integration
175
+ ```
176
+
177
+ ### Redux DevTools Integration
178
+
179
+ Redux DevTools is a powerful browser extension that provides real-time debugging for state management. Even though miura Data Flow isn't Redux, we integrate with it because it's the industry standard for state debugging.
180
+
181
+ #### What Redux DevTools Provides:
182
+
183
+ - **🔍 State Inspector** - Real-time visualization of your entire state tree
184
+ - **📜 Action Monitor** - Complete log of all dispatched actions with timing
185
+ - **⏰ Time-travel Debugging** - Jump back to any previous state
186
+ - **📊 Diff View** - Before/after comparison with highlighted changes
187
+ - **⚡ Performance Metrics** - Action timing and state size monitoring
188
+
189
+ #### Setup Instructions:
190
+
191
+ 1. **Install the Browser Extension:**
192
+ - **Chrome**: [Redux DevTools Extension](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd)
193
+ - **Firefox**: [Redux DevTools Extension](https://addons.mozilla.org/en-US/firefox/addon/reduxdevtools/)
194
+
195
+ 2. **Enable in Your Code:**
196
+ ```typescript
197
+ import { createDevToolsMiddleware } from '@miura/miura-data-flow';
198
+
199
+ store.use(createDevToolsMiddleware('MyApp'));
200
+ ```
201
+
202
+ 3. **Open DevTools:**
203
+ - Press `F12` → Click the **Redux** tab
204
+ - Or right-click → **Inspect** → **Redux** tab
205
+
206
+ #### What You'll See:
207
+
208
+ When you dispatch actions, they appear in DevTools like this:
209
+
210
+ ```
211
+ Action: increment
212
+ Payload: []
213
+ State Before: { count: 0, user: null }
214
+ State After: { count: 1, user: null }
215
+
216
+ Action: setUser
217
+ Payload: [{ id: '1', name: 'John' }]
218
+ State Before: { count: 1, user: null }
219
+ State After: { count: 1, user: { id: '1', name: 'John' } }
220
+ ```
221
+
222
+ #### Complete Example:
223
+
224
+ ```typescript
225
+ import { Store, createDevToolsMiddleware } from '@miura/miura-data-flow';
226
+
227
+ // Create store
228
+ const store = new Store({
229
+ user: null,
230
+ todos: [],
231
+ theme: 'light'
232
+ });
233
+
234
+ // Enable DevTools integration
235
+ store.use(createDevToolsMiddleware('TodoApp'));
236
+
237
+ // Define actions
238
+ store.defineActions({
239
+ login: (state, user) => ({ user }),
240
+ addTodo: (state, todo) => ({ todos: [...state.todos, todo] }),
241
+ toggleTheme: (state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })
242
+ });
243
+
244
+ // These actions will now be visible in Redux DevTools:
245
+ await store.dispatch('login', { id: '1', name: 'John' });
246
+ await store.dispatch('addTodo', { id: '1', text: 'Buy milk' });
247
+ await store.dispatch('toggleTheme');
248
+ ```
249
+
250
+ #### DevTools Features:
251
+
252
+ **State Inspector:**
253
+ - View your entire state tree in real-time
254
+ - Expand/collapse nested objects
255
+ - Search through state properties
256
+
257
+ **Action Monitor:**
258
+ - See all dispatched actions with timestamps
259
+ - Inspect action payloads and arguments
260
+ - Monitor action execution time
261
+
262
+ **Time-travel Debugging:**
263
+ - Jump to any previous state
264
+ - Replay actions step by step
265
+ - Compare states at different points in time
266
+
267
+ **Performance Monitoring:**
268
+ - Track action execution time
269
+ - Monitor state size changes
270
+ - Identify performance bottlenecks
271
+
272
+ #### Why Use Redux DevTools?
273
+
274
+ Even though we're not using Redux, Redux DevTools has become the **de facto standard** for state debugging because:
275
+
276
+ - **Universal Adoption** - Most developers are familiar with it
277
+ - **Rich Features** - Time-travel, diff view, performance metrics
278
+ - **Browser Integration** - No additional setup required
279
+ - **Community Support** - Well-maintained and documented
280
+
281
+ It's like having a **super-powered console.log** that shows you exactly what's happening with your state in real-time! 🚀
282
+
283
+ ### Debug Information
284
+
285
+ ```typescript
286
+ // Get debug info about your store
287
+ console.log(store.getDebugInfo());
288
+ console.log(globalState.getDebugInfo());
289
+ ```
290
+
291
+ ## API Reference
292
+
293
+ ### Store
294
+
295
+ - `new Store<T>(initialState: T)` - Create a new store
296
+ - `store.getState(): T` - Get current state
297
+ - `store.get<K>(key: K): T[K]` - Get specific property
298
+ - `store.setState(updater)` - Update state
299
+ - `store.defineActions(actions)` - Define actions
300
+ - `store.dispatch(action, ...args)` - Execute action
301
+ - `store.subscribe(callback, selector?)` - Subscribe to changes
302
+ - `store.subscribeTo(key, callback)` - Subscribe to specific property
303
+ - `store.use(middleware)` - Add middleware
304
+
305
+ ### Global State
306
+
307
+ - `globalState.get(key)` - Get global property
308
+ - `globalState.set(key, value)` - Set global property
309
+ - `globalState.subscribe(componentId, properties, callback)` - Subscribe
310
+ - `globalState.subscribeTo(componentId, key, callback)` - Subscribe to property
311
+ - `globalState.dispatch(action, ...args)` - Dispatch global action
312
+
313
+ ### Middleware
314
+
315
+ - `createLoggerMiddleware()` - Console logging
316
+ - `createPersistenceMiddleware(keys, storageKey)` - localStorage persistence
317
+ - `createApiMiddleware(config)` - API integration
318
+ - `createCacheMiddleware(ttl)` - Response caching
319
+ - `createDevToolsMiddleware(name)` - Redux DevTools
320
+
321
+ ## Best Practices
322
+
323
+ 1. **Use TypeScript** - Define interfaces for your state
324
+ 2. **Subscribe Selectively** - Only subscribe to what you need
325
+ 3. **Unsubscribe Always** - Prevent memory leaks
326
+ 4. **Use Actions** - Don't mutate state directly
327
+ 5. **Middleware for Side Effects** - Keep actions pure
328
+ 6. **Global State Sparingly** - Use for truly global data
329
+ 7. **Batch Updates** - Group related state changes
330
+
331
+ ## Examples
332
+
333
+ See the [examples directory](./examples) for complete working examples.
334
+
335
+ ---
336
+
337
+ **miura Data Flow** - Modern state management that just works! 🚀
338
+
339
+ ### Custom Middleware
340
+
341
+ ```typescript
342
+ import { StoreMiddleware } from '@miura/miura-data-flow';
343
+
344
+ const analyticsMiddleware: StoreMiddleware = {
345
+ name: 'analytics',
346
+ before: (action, args, state) => {
347
+ // Track action before execution
348
+ analytics.track('action_started', { action, args });
349
+ },
350
+ after: (action, args, state, result) => {
351
+ // Track action completion
352
+ analytics.track('action_completed', { action, result });
353
+ },
354
+ error: (action, args, error) => {
355
+ // Track errors
356
+ analytics.track('action_error', { action, error });
357
+ }
358
+ };
359
+
360
+ store.use(analyticsMiddleware);
361
+ ```
362
+
363
+ ## Global State Management
364
+
365
+ ### Using Global State
366
+
367
+ ```typescript
368
+ import { globalState } from '@miura/miura-data-flow';
369
+
370
+ // Set global properties
371
+ globalState.set('theme', 'dark');
372
+ globalState.set('user', { id: '1', name: 'John' });
373
+
374
+ // Get global properties
375
+ const theme = globalState.get('theme');
376
+ const user = globalState.get('user');
377
+
378
+ // Subscribe to global state changes
379
+ const unsubscribe = globalState.subscribeTo('my-component', 'theme', (theme) => {
380
+ console.log('Theme changed:', theme);
381
+ });
382
+ ```
383
+
384
+ ### Global State in Components
385
+
386
+ ```typescript
387
+ import { MiuraElement, html } from '@miura/miura-element';
388
+ import { globalState } from '@miura/miura-data-flow';
389
+
390
+ class ThemeToggle extends MiuraElement {
391
+ static properties = {
392
+ theme: { type: String, default: 'light' }
393
+ };
394
+
395
+ connectedCallback() {
396
+ super.connectedCallback();
397
+
398
+ // Subscribe to global theme changes
399
+ this.unsubscribeTheme = globalState.subscribeTo(
400
+ this.tagName,
401
+ 'theme',
402
+ (theme) => {
403
+ this.theme = theme;
404
+ this.requestUpdate();
405
+ }
406
+ );
407
+ }
408
+
409
+ disconnectedCallback() {
410
+ super.disconnectedCallback();
411
+ this.unsubscribeTheme?.();
412
+ }
413
+
414
+ toggleTheme() {
415
+ const newTheme = this.theme === 'light' ? 'dark' : 'light';
416
+ globalState.set('theme', newTheme);
417
+ }
418
+
419
+ render() {
420
+ return html`
421
+ <button @click=${this.toggleTheme}>
422
+ Current theme: ${this.theme}
423
+ </button>
424
+ `;
425
+ }
426
+ }
427
+ ```
428
+
429
+ ## Integration with miura Framework
430
+
431
+ ### Framework Setup
432
+
433
+ ```typescript
434
+ import { Store, createApiMiddleware, createCacheMiddleware } from '@miura/miura-data-flow';
435
+
436
+ class miuraFramework {
437
+ private store: Store;
438
+
439
+ constructor() {
440
+ // Initialize store with app state
441
+ this.store = new Store({
442
+ user: null,
443
+ settings: {},
444
+ notifications: []
445
+ });
446
+
447
+ // Add middleware for API and caching
448
+ this.store.use(createApiMiddleware({
449
+ baseURL: process.env.API_URL,
450
+ headers: {
451
+ 'Content-Type': 'application/json'
452
+ }
453
+ }));
454
+
455
+ this.store.use(createCacheMiddleware());
456
+
457
+ // Define global actions
458
+ this.store.defineActions({
459
+ setUser: (state, user) => ({ user }),
460
+ addNotification: (state, notification) => ({
461
+ notifications: [...state.notifications, notification]
462
+ })
463
+ });
464
+ }
465
+
466
+ // Expose store to components
467
+ getStore() {
468
+ return this.store;
469
+ }
470
+ }
471
+ ```
472
+
473
+ ### Component Integration
474
+
475
+ ```typescript
476
+ class MyComponent extends MiuraElement {
477
+ // Define global properties this component uses
478
+ global() {
479
+ return {
480
+ user: null,
481
+ theme: 'light'
482
+ };
483
+ }
484
+
485
+ connected() {
486
+ // Subscribe to global state
487
+ this.unsubscribeUser = globalState.subscribeTo(
488
+ this.tagName,
489
+ 'user',
490
+ (user) => this.handleUserChange(user)
491
+ );
492
+ }
493
+
494
+ disconnected() {
495
+ this.unsubscribeUser?.();
496
+ }
497
+
498
+ handleUserChange(user) {
499
+ // React to global user changes
500
+ this.requestUpdate();
501
+ }
502
+ }
503
+ ```
504
+
505
+ ## Performance Optimization
506
+
507
+ ### Selective Subscriptions
508
+
509
+ ```typescript
510
+ // Only subscribe to what you need
511
+ const unsubscribe = store.subscribe(
512
+ (state, prevState) => {
513
+ // Only trigger when user.todos changes
514
+ },
515
+ (state) => state.user?.todos
516
+ );
517
+ ```
518
+
519
+ ### Batch Updates
520
+
521
+ ```typescript
522
+ // Multiple updates in one action
523
+ store.defineActions({
524
+ updateUserProfile: (state, updates) => ({
525
+ user: { ...state.user, ...updates },
526
+ lastUpdated: Date.now()
527
+ })
528
+ });
529
+ ```
530
+
531
+ ### Memory Management
532
+
533
+ ```typescript
534
+ // Always unsubscribe to prevent memory leaks
535
+ class MyComponent {
536
+ connectedCallback() {
537
+ this.unsubscribe = store.subscribe(this.handleStateChange);
538
+ }
539
+
540
+ disconnectedCallback() {
541
+ this.unsubscribe(); // Important!
542
+ }
543
+ }
544
+ ```
545
+
546
+ ## Debugging
547
+
548
+ ### Enable Debug Logging
549
+
550
+ ```typescript
551
+ import { enableDebug } from '@miura/miura-render';
552
+
553
+ enableDebug({
554
+ element: true, // Shows data flow logs
555
+ });
556
+ ```
557
+
558
+ ### DevTools Integration
559
+
560
+ ```typescript
561
+ // Install Redux DevTools browser extension
562
+ store.use(createDevToolsMiddleware('MyApp'));
563
+ ```
564
+
565
+ ### Debug Information
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './src/miura-data-flow';
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@miurajs/miura-data-flow",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./index.d.ts",
10
+ "import": "./index.ts",
11
+ "require": "./index.ts"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "test": "vitest",
17
+ "dev": "vitest watch"
18
+ },
19
+ "dependencies": {
20
+ "@miura/miura-debugger": "workspace:*"
21
+ },
22
+ "optionalDependencies": {
23
+ "@aws-sdk/client-s3": "^3.1005.0",
24
+ "graphql-request": "^6.1.0"
25
+ },
26
+ "devDependencies": {
27
+ "typescript": "^5.0.0",
28
+ "vitest": "^1.0.0"
29
+ }
30
+ }