@context-action/core 0.8.4 → 0.8.8
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 +126 -12
- package/dist/index.cjs +916 -188
- package/dist/index.d.cts +184 -16
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +184 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +905 -188
- package/dist/index.js.map +1 -1
- package/package.json +42 -28
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @context-action/core
|
|
2
2
|
|
|
3
|
-
Type-safe action pipeline management library for JavaScript/TypeScript applications with advanced filtering, performance optimizations, and React integration support.
|
|
3
|
+
Type-safe action pipeline management library for **vanilla JavaScript/TypeScript** applications with advanced filtering, performance optimizations, and optional React integration support.
|
|
4
|
+
|
|
5
|
+
> **✨ Framework-Agnostic**: Works with vanilla JavaScript, React, Vue, Svelte, or any JavaScript environment. No framework dependencies required!
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -10,6 +12,15 @@ npm install @context-action/core
|
|
|
10
12
|
pnpm install @context-action/core
|
|
11
13
|
```
|
|
12
14
|
|
|
15
|
+
### CDN (for quick prototyping)
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<script type="module">
|
|
19
|
+
import { ActionRegister } from 'https://esm.sh/@context-action/core@latest';
|
|
20
|
+
// Your code here
|
|
21
|
+
</script>
|
|
22
|
+
```
|
|
23
|
+
|
|
13
24
|
## Quick Start
|
|
14
25
|
|
|
15
26
|
```typescript
|
|
@@ -42,6 +53,94 @@ await actions.dispatch('increment');
|
|
|
42
53
|
await actions.dispatch('setCount', 42);
|
|
43
54
|
```
|
|
44
55
|
|
|
56
|
+
## 🌟 Vanilla JavaScript Support
|
|
57
|
+
|
|
58
|
+
**@context-action/core works perfectly with vanilla JavaScript!** No React, Vue, or any framework required.
|
|
59
|
+
|
|
60
|
+
### Browser Example (HTML + JavaScript)
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<!DOCTYPE html>
|
|
64
|
+
<html>
|
|
65
|
+
<head>
|
|
66
|
+
<title>Context-Action Example</title>
|
|
67
|
+
</head>
|
|
68
|
+
<body>
|
|
69
|
+
<div id="counter">0</div>
|
|
70
|
+
<button id="increment">Increment</button>
|
|
71
|
+
|
|
72
|
+
<script type="module">
|
|
73
|
+
import { ActionRegister } from 'https://esm.sh/@context-action/core@latest';
|
|
74
|
+
|
|
75
|
+
// Simple store
|
|
76
|
+
class Store {
|
|
77
|
+
constructor(initialState) {
|
|
78
|
+
this.state = initialState;
|
|
79
|
+
this.listeners = new Set();
|
|
80
|
+
}
|
|
81
|
+
getValue() { return this.state; }
|
|
82
|
+
setValue(newState) {
|
|
83
|
+
this.state = newState;
|
|
84
|
+
this.listeners.forEach(fn => fn(this.state));
|
|
85
|
+
}
|
|
86
|
+
subscribe(listener) {
|
|
87
|
+
this.listeners.add(listener);
|
|
88
|
+
return () => this.listeners.delete(listener);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Create store and actions
|
|
93
|
+
const counterStore = new Store({ count: 0 });
|
|
94
|
+
const actions = new ActionRegister({ name: 'Counter' });
|
|
95
|
+
|
|
96
|
+
// Register handler
|
|
97
|
+
actions.register('increment', () => {
|
|
98
|
+
const current = counterStore.getValue();
|
|
99
|
+
counterStore.setValue({ count: current.count + 1 });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Subscribe to updates
|
|
103
|
+
counterStore.subscribe(state => {
|
|
104
|
+
document.getElementById('counter').textContent = state.count;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Wire up button
|
|
108
|
+
document.getElementById('increment').onclick = () => {
|
|
109
|
+
actions.dispatch('increment');
|
|
110
|
+
};
|
|
111
|
+
</script>
|
|
112
|
+
</body>
|
|
113
|
+
</html>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Node.js Example
|
|
117
|
+
|
|
118
|
+
```javascript
|
|
119
|
+
import { ActionRegister } from '@context-action/core';
|
|
120
|
+
|
|
121
|
+
const actions = new ActionRegister({ name: 'MyApp' });
|
|
122
|
+
|
|
123
|
+
actions.register('processData', async (data, controller) => {
|
|
124
|
+
console.log('Processing:', data);
|
|
125
|
+
|
|
126
|
+
// Business logic here
|
|
127
|
+
const result = await someAsyncOperation(data);
|
|
128
|
+
|
|
129
|
+
controller.setResult(result);
|
|
130
|
+
}, { priority: 100 });
|
|
131
|
+
|
|
132
|
+
// Dispatch action
|
|
133
|
+
const result = await actions.dispatchWithResult('processData', {
|
|
134
|
+
input: 'example'
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
console.log('Result:', result.successResults);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**📚 Learn More:**
|
|
141
|
+
- [Vanilla JavaScript Guide](../../docs/en/guide/vanilla-js-guide.md) - Complete guide with examples
|
|
142
|
+
- [Live Examples](../../examples/vanilla-js/) - Interactive HTML examples (counter, todo app)
|
|
143
|
+
|
|
45
144
|
### Memory Management
|
|
46
145
|
|
|
47
146
|
```typescript
|
|
@@ -126,12 +225,21 @@ await actions.dispatch('backgroundTask', data, {
|
|
|
126
225
|
queuePriority: 5
|
|
127
226
|
});
|
|
128
227
|
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
});
|
|
228
|
+
// Wall-clock timeout (queue wait + retry delay included).
|
|
229
|
+
// Rejects with ActionTimeoutError while the internal operation drains safely.
|
|
230
|
+
await actions.dispatch('timedAction', data, { timeout: 5000 });
|
|
133
231
|
```
|
|
134
232
|
|
|
233
|
+
The default queue is single-slot. When a handler awaits another dispatch on
|
|
234
|
+
the **same** register, make that nested call explicit with `{ immediate: true }`
|
|
235
|
+
so it can run inside the current queue turn. Likewise, do not set
|
|
236
|
+
`queuePriority` on an awaited nested `dispatchWithResult` call. Independent
|
|
237
|
+
top-level dispatches should keep the queue defaults.
|
|
238
|
+
|
|
239
|
+
Handlers that perform cancellable I/O can observe `controller.signal`. It is
|
|
240
|
+
aborted for caller cancellation, timeout, provider teardown, and register
|
|
241
|
+
shutdown.
|
|
242
|
+
|
|
135
243
|
### Result Collection with Strategies
|
|
136
244
|
|
|
137
245
|
```typescript
|
|
@@ -307,7 +415,7 @@ actions.register('riskyOperation', async (data, controller) => {
|
|
|
307
415
|
// With retry configuration
|
|
308
416
|
await actions.dispatch('apiCall', data, {
|
|
309
417
|
retryOnError: {
|
|
310
|
-
maxAttempts: 3,
|
|
418
|
+
maxAttempts: 3, // Total attempts, including the first call
|
|
311
419
|
delay: 1000
|
|
312
420
|
}
|
|
313
421
|
});
|
|
@@ -341,8 +449,11 @@ const registry = new ActionRegister({ name: 'MyApp' });
|
|
|
341
449
|
|
|
342
450
|
// Use the registry...
|
|
343
451
|
|
|
344
|
-
//
|
|
345
|
-
registry.destroy();
|
|
452
|
+
// Begin terminal cleanup. New work is rejected immediately.
|
|
453
|
+
registry.destroy();
|
|
454
|
+
|
|
455
|
+
// Or await proof that started handlers settled and cleanup callbacks ran.
|
|
456
|
+
await registry.destroyAsync();
|
|
346
457
|
```
|
|
347
458
|
|
|
348
459
|
## API Reference
|
|
@@ -373,7 +484,8 @@ registry.destroy(); // Cleans up pipelines, guards, queues, stats
|
|
|
373
484
|
#### Utility Methods
|
|
374
485
|
- `getName()` - Get registry name
|
|
375
486
|
- `isDebugEnabled()` - Check if debug mode is enabled
|
|
376
|
-
- `destroy()` -
|
|
487
|
+
- `destroy()` - Begin terminal cleanup without waiting
|
|
488
|
+
- `destroyAsync()` - Resolve after started handlers settle and cleanup completes
|
|
377
489
|
|
|
378
490
|
### Configuration Interfaces
|
|
379
491
|
|
|
@@ -477,7 +589,7 @@ actions.destroy();
|
|
|
477
589
|
1. **Use handler IDs** for better debugging and filtering
|
|
478
590
|
2. **Enable replaceExisting** for React components to prevent duplicates
|
|
479
591
|
3. **Use immediate: false** (default) to benefit from queue optimizations
|
|
480
|
-
4. **
|
|
592
|
+
4. **Await destroyAsync()** when shutdown completion must be guaranteed
|
|
481
593
|
5. **Use priority filtering** instead of excludeHandlerIds for better performance
|
|
482
594
|
6. **Cache ActionRegister instances** - don't create new ones frequently
|
|
483
595
|
|
|
@@ -489,5 +601,7 @@ Apache-2.0
|
|
|
489
601
|
|
|
490
602
|
- [Main Repository](https://github.com/mineclover/context-action)
|
|
491
603
|
- [Documentation](https://mineclover.github.io/context-action/)
|
|
492
|
-
- [
|
|
493
|
-
- [Examples](../../
|
|
604
|
+
- [Vanilla JS Guide](../../docs/en/guide/vanilla-js-guide.md) - Complete vanilla JavaScript guide
|
|
605
|
+
- [Vanilla JS Examples](../../examples/vanilla-js/) - Interactive examples (counter, todo app)
|
|
606
|
+
- [React Package](../react/README.md) - React integration
|
|
607
|
+
- [Examples](../../example/README.md) - React example application
|