@stonyx/events 0.1.1-beta.1 → 0.1.1-beta.10
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/.claude/improvements.md +21 -0
- package/.claude/project-structure.md +36 -195
- package/.claude/testing.md +44 -0
- package/.github/workflows/publish.yml +17 -1
- package/.npmignore +3 -0
- package/README.md +57 -18
- package/package.json +2 -2
- package/pnpm-lock.yaml +5 -5
- package/src/main.js +12 -0
- package/stonyx-bootstrap.cjs +0 -9
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @stonyx/events - Improvement Opportunities
|
|
2
|
+
|
|
3
|
+
## Orphaned config/environment.js reference
|
|
4
|
+
|
|
5
|
+
**Status**: Documentation / .gitignore reference with no actual file
|
|
6
|
+
|
|
7
|
+
The `.gitignore` includes `config/environment.js`, and the old `.claude/index.md` documented an `EVENTS_LOG` env var and a `config/environment.js` file. However, neither the file nor the directory exists, and no source code reads `EVENTS_LOG` or any configuration.
|
|
8
|
+
|
|
9
|
+
**Options**:
|
|
10
|
+
1. **Remove the reference** -- delete the `config/environment.js` line from `.gitignore` since there is nothing to ignore.
|
|
11
|
+
2. **Create the file** -- if debug logging is planned, implement `config/environment.js` and wire it into `src/main.js`.
|
|
12
|
+
|
|
13
|
+
## Overly broad `"files"` field in package.json
|
|
14
|
+
|
|
15
|
+
**Current**: `"files": ["*"]`
|
|
16
|
+
|
|
17
|
+
This tells npm to publish every file in the repo (except those in `.npmignore`). The `.npmignore` only excludes `test/` and `.nvmrc`, so the published package will include `.github/`, `.claude/`, `.gitignore`, `pnpm-lock.yaml`, and other development-only files.
|
|
18
|
+
|
|
19
|
+
**Options**:
|
|
20
|
+
1. **Use more specific globs** -- e.g., `"files": ["src/", "LICENSE.md", "README.md"]` to ship only what consumers need.
|
|
21
|
+
2. **Remove the field entirely** -- npm's default behavior already includes `package.json`, `README.md`, `LICENSE.md`, and the `main`/`exports` entry points, which is likely sufficient.
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# @stonyx/events - Project Structure & Architecture
|
|
2
2
|
|
|
3
|
+
## Detailed Guides
|
|
4
|
+
|
|
5
|
+
- [Testing Guidelines](./testing.md) — Test structure, patterns, and coverage areas
|
|
6
|
+
- [Improvements](./improvements.md) — Documented improvement opportunities
|
|
7
|
+
|
|
3
8
|
## Project Overview
|
|
4
9
|
|
|
5
10
|
**@stonyx/events** is a lightweight pub/sub event system for the Stonyx framework. It provides a singleton-based event management system with error isolation, async support, and type-safe event registration.
|
|
@@ -46,24 +51,23 @@
|
|
|
46
51
|
stonyx-events/
|
|
47
52
|
├── .github/
|
|
48
53
|
│ └── workflows/
|
|
49
|
-
│
|
|
54
|
+
│ ├── ci.yml # GitHub Actions CI pipeline
|
|
55
|
+
│ └── publish.yml # NPM publish workflow (alpha + stable)
|
|
50
56
|
├── .claude/
|
|
51
|
-
│ ├──
|
|
52
|
-
│
|
|
53
|
-
|
|
54
|
-
│ └── environment.js # Environment configuration
|
|
57
|
+
│ ├── project-structure.md # This file
|
|
58
|
+
│ ├── testing.md # Testing guidelines
|
|
59
|
+
│ └── improvements.md # Improvement opportunities
|
|
55
60
|
├── src/
|
|
56
|
-
│ └── main.js
|
|
61
|
+
│ └── main.js # Events class implementation
|
|
57
62
|
├── test/
|
|
58
63
|
│ └── unit/
|
|
59
|
-
│ └── events-test.js
|
|
60
|
-
├── .gitignore
|
|
61
|
-
├── .npmignore
|
|
62
|
-
├── .nvmrc
|
|
63
|
-
├── LICENSE.md
|
|
64
|
-
├── README.md
|
|
65
|
-
|
|
66
|
-
└── stonyx-bootstrap.cjs # CommonJS bootstrap for testing
|
|
64
|
+
│ └── events-test.js # QUnit tests for Events
|
|
65
|
+
├── .gitignore # Git ignore patterns
|
|
66
|
+
├── .npmignore # NPM ignore patterns
|
|
67
|
+
├── .nvmrc # Node version specification
|
|
68
|
+
├── LICENSE.md # Apache 2.0 license
|
|
69
|
+
├── README.md # User-facing documentation
|
|
70
|
+
└── package.json # NPM package configuration
|
|
67
71
|
```
|
|
68
72
|
|
|
69
73
|
## Core Components Deep Dive
|
|
@@ -134,12 +138,8 @@ The Events class is the heart of the module, providing all pub/sub functionality
|
|
|
134
138
|
|
|
135
139
|
## Dependencies & Integration
|
|
136
140
|
|
|
137
|
-
###
|
|
138
|
-
|
|
139
|
-
**stonyx** (file:../stonyx)
|
|
140
|
-
- Core Stonyx framework
|
|
141
|
-
- Provides base configuration and bootstrapping
|
|
142
|
-
- Required for module initialization
|
|
141
|
+
### Production Dependencies
|
|
142
|
+
None. This module has zero production dependencies.
|
|
143
143
|
|
|
144
144
|
### Dev Dependencies
|
|
145
145
|
|
|
@@ -148,7 +148,7 @@ The Events class is the heart of the module, providing all pub/sub functionality
|
|
|
148
148
|
|
|
149
149
|
**qunit** (^2.24.1)
|
|
150
150
|
- Testing framework
|
|
151
|
-
- Runs via
|
|
151
|
+
- Runs via `pnpm test` (which invokes `qunit`)
|
|
152
152
|
|
|
153
153
|
**sinon** (^21.0.0)
|
|
154
154
|
- Mocking/stubbing library
|
|
@@ -166,122 +166,35 @@ The Events class is the heart of the module, providing all pub/sub functionality
|
|
|
166
166
|
### Module System
|
|
167
167
|
- ES Modules throughout
|
|
168
168
|
- Default export for Events class
|
|
169
|
-
-
|
|
169
|
+
- Named convenience exports: `setup`, `subscribe`, `once`, `unsubscribe`, `emit`, `clear`, `reset`
|
|
170
170
|
|
|
171
171
|
### Error Handling
|
|
172
172
|
- Validation errors throw immediately
|
|
173
173
|
- Runtime errors in handlers are caught and logged
|
|
174
174
|
- No silent failures
|
|
175
175
|
|
|
176
|
-
### Logging
|
|
177
|
-
- Environment variable: `EVENTS_LOG` (currently unused in implementation)
|
|
178
|
-
- Configuration prepared in `config/environment.js`
|
|
179
|
-
- Future: Could add debug logging for emit/subscribe events
|
|
180
|
-
|
|
181
176
|
### Naming Conventions
|
|
182
177
|
- Event names: camelCase strings (e.g., 'userLogin', 'dataChange')
|
|
183
178
|
- Method names: lowercase verbs (setup, subscribe, emit)
|
|
184
179
|
- Private instance variables: None (all properties public for testing)
|
|
185
180
|
|
|
186
|
-
##
|
|
187
|
-
|
|
188
|
-
### Test Structure
|
|
189
|
-
- All tests in `test/unit/events-test.js`
|
|
190
|
-
- QUnit module: `[Unit] Events`
|
|
191
|
-
- 18 test cases covering all functionality
|
|
192
|
-
- Each test calls `events.reset()` before and after
|
|
193
|
-
|
|
194
|
-
### Test Patterns
|
|
195
|
-
|
|
196
|
-
**Singleton Isolation**
|
|
197
|
-
```javascript
|
|
198
|
-
const events = new Events();
|
|
199
|
-
events.reset(); // Clear any previous state
|
|
200
|
-
// ... test code ...
|
|
201
|
-
events.reset(); // Clean up after test
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
**Async Testing**
|
|
205
|
-
```javascript
|
|
206
|
-
test('description', async function (assert) {
|
|
207
|
-
// Use async/await for emit()
|
|
208
|
-
await events.emit('event');
|
|
209
|
-
assert.ok(condition);
|
|
210
|
-
});
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**Error Suppression**
|
|
214
|
-
```javascript
|
|
215
|
-
const originalConsoleError = console.error;
|
|
216
|
-
console.error = () => {}; // Suppress expected errors
|
|
217
|
-
// ... test code ...
|
|
218
|
-
console.error = originalConsoleError; // Restore
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### Coverage Areas
|
|
222
|
-
1. Event registration (setup)
|
|
223
|
-
2. Subscription management (subscribe, unsubscribe)
|
|
224
|
-
3. Event emission (emit)
|
|
225
|
-
4. One-time subscriptions (once)
|
|
226
|
-
5. Error isolation
|
|
227
|
-
6. Async support
|
|
228
|
-
7. Singleton behavior
|
|
229
|
-
8. Edge cases (unregistered events, no subscribers)
|
|
230
|
-
|
|
231
|
-
## Extension Points
|
|
232
|
-
|
|
233
|
-
While the Events system is intentionally minimal, potential future enhancements include:
|
|
234
|
-
|
|
235
|
-
### Event Priorities
|
|
236
|
-
- Add priority levels for subscribers
|
|
237
|
-
- Execute high-priority handlers first
|
|
238
|
-
- Use case: Logging before business logic
|
|
239
|
-
|
|
240
|
-
### Wildcard Events
|
|
241
|
-
- Support pattern matching (e.g., 'user:*')
|
|
242
|
-
- Subscribe to multiple events at once
|
|
243
|
-
- Use case: Debugging, logging all events
|
|
244
|
-
|
|
245
|
-
### Event History
|
|
246
|
-
- Optional recording of emitted events
|
|
247
|
-
- Replay functionality for debugging
|
|
248
|
-
- Use case: Time-travel debugging, audit logs
|
|
249
|
-
|
|
250
|
-
### Middleware
|
|
251
|
-
- Pre/post-emit hooks
|
|
252
|
-
- Event transformation pipeline
|
|
253
|
-
- Use case: Validation, logging, metrics
|
|
254
|
-
|
|
255
|
-
## Configuration Reference
|
|
256
|
-
|
|
257
|
-
### Environment Variables
|
|
258
|
-
|
|
259
|
-
**EVENTS_LOG**
|
|
260
|
-
- Type: Boolean (truthy/falsy)
|
|
261
|
-
- Default: `false`
|
|
262
|
-
- Purpose: Enable debug logging (not yet implemented)
|
|
263
|
-
- Usage: `EVENTS_LOG=true npm test`
|
|
181
|
+
## Package Exports
|
|
264
182
|
|
|
265
|
-
###
|
|
183
|
+
### Default Export
|
|
266
184
|
|
|
267
185
|
```javascript
|
|
268
|
-
|
|
269
|
-
log: EVENTS_LOG ?? false, // Debug logging flag
|
|
270
|
-
logColor: '#888', // Color for log output
|
|
271
|
-
}
|
|
186
|
+
import Events from '@stonyx/events';
|
|
272
187
|
```
|
|
273
188
|
|
|
274
|
-
|
|
189
|
+
The Events class.
|
|
275
190
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
### Main Export
|
|
191
|
+
### Named Convenience Exports
|
|
279
192
|
|
|
280
193
|
```javascript
|
|
281
|
-
import
|
|
194
|
+
import { setup, subscribe, once, unsubscribe, emit, clear, reset } from '@stonyx/events';
|
|
282
195
|
```
|
|
283
196
|
|
|
284
|
-
|
|
197
|
+
All convenience functions use a singleton Events instance internally, providing a cleaner API without needing to instantiate the class.
|
|
285
198
|
|
|
286
199
|
### Usage Pattern
|
|
287
200
|
|
|
@@ -304,59 +217,14 @@ events.emit('userLogin', { id: 1, name: 'Alice' });
|
|
|
304
217
|
await events.emit('userLogin', { id: 1, name: 'Alice' });
|
|
305
218
|
```
|
|
306
219
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
### Local Development
|
|
310
|
-
|
|
311
|
-
1. **Install dependencies**
|
|
312
|
-
```bash
|
|
313
|
-
cd /Users/mstonepc/Repos/abofs
|
|
314
|
-
./linker.sh local # Link all local Stonyx modules
|
|
315
|
-
cd stonyx-events
|
|
316
|
-
npm install
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
2. **Run tests**
|
|
320
|
-
```bash
|
|
321
|
-
npm test
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
3. **Make changes**
|
|
325
|
-
- Edit `src/main.js` for implementation
|
|
326
|
-
- Edit `test/unit/events-test.js` for tests
|
|
327
|
-
- Follow TDD: Write failing test, implement feature, verify
|
|
328
|
-
|
|
329
|
-
### Test-Driven Development
|
|
330
|
-
|
|
331
|
-
The module follows TDD principles:
|
|
332
|
-
1. Write a failing test for new functionality
|
|
333
|
-
2. Implement the minimum code to pass the test
|
|
334
|
-
3. Refactor while keeping tests green
|
|
335
|
-
4. Ensure all tests pass before committing
|
|
336
|
-
|
|
337
|
-
### CI/CD Pipeline
|
|
220
|
+
### Convenience Exports Usage
|
|
338
221
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
### Publishing Workflow
|
|
346
|
-
|
|
347
|
-
1. **Version bump**
|
|
348
|
-
```bash
|
|
349
|
-
npm version patch|minor|major
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
2. **Publish to NPM**
|
|
353
|
-
```bash
|
|
354
|
-
npm publish
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
3. **Update dependents**
|
|
358
|
-
- Update `@stonyx/orm` to use published version
|
|
359
|
-
- Update other modules as needed
|
|
222
|
+
```javascript
|
|
223
|
+
import { setup, subscribe, emit } from '@stonyx/events';
|
|
224
|
+
setup(['myEvent']);
|
|
225
|
+
subscribe('myEvent', handler);
|
|
226
|
+
emit('myEvent', data);
|
|
227
|
+
```
|
|
360
228
|
|
|
361
229
|
## Common Pitfalls & Gotchas
|
|
362
230
|
|
|
@@ -385,29 +253,6 @@ The module follows TDD principles:
|
|
|
385
253
|
- **Solution**: Use different function instances for multiple subscriptions
|
|
386
254
|
- **Note**: This is by design to prevent accidental duplicate subscriptions
|
|
387
255
|
|
|
388
|
-
## Future Enhancement Opportunities
|
|
389
|
-
|
|
390
|
-
### Performance Optimizations
|
|
391
|
-
- Lazy initialization of event subscriber sets
|
|
392
|
-
- Debouncing/throttling for high-frequency events
|
|
393
|
-
- Event batching for bulk updates
|
|
394
|
-
|
|
395
|
-
### Developer Experience
|
|
396
|
-
- TypeScript definitions for type-safe event names and payloads
|
|
397
|
-
- Debug mode with detailed logging
|
|
398
|
-
- Event visualization/monitoring tools
|
|
399
|
-
|
|
400
|
-
### Advanced Features
|
|
401
|
-
- Event namespacing (e.g., 'user:login:success')
|
|
402
|
-
- Event bubbling/capturing (DOM-like event propagation)
|
|
403
|
-
- Async middleware pipeline
|
|
404
|
-
- Event replay for debugging
|
|
405
|
-
|
|
406
|
-
### Integration
|
|
407
|
-
- Automatic event logging to @stonyx/logger (when it exists)
|
|
408
|
-
- Metrics/telemetry integration
|
|
409
|
-
- Event persistence for audit trails
|
|
410
|
-
|
|
411
256
|
## Related Resources
|
|
412
257
|
|
|
413
258
|
- [Stonyx Framework](https://github.com/abofs/stonyx)
|
|
@@ -415,7 +260,3 @@ The module follows TDD principles:
|
|
|
415
260
|
- [Sinon.js Documentation](https://sinonjs.org/)
|
|
416
261
|
- [Node.js ES Modules](https://nodejs.org/api/esm.html)
|
|
417
262
|
- [Apache 2.0 License](https://www.apache.org/licenses/LICENSE-2.0)
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
This document is maintained by the Stonyx team and should be updated whenever architectural changes are made to the @stonyx/events module.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @stonyx/events - Testing Guidelines
|
|
2
|
+
|
|
3
|
+
## Test Structure
|
|
4
|
+
- All tests in `test/unit/events-test.js`
|
|
5
|
+
- QUnit module: `[Unit] Events`
|
|
6
|
+
- 17 test cases covering all functionality
|
|
7
|
+
- Each test calls `events.reset()` before and after
|
|
8
|
+
|
|
9
|
+
## Test Patterns
|
|
10
|
+
|
|
11
|
+
### Singleton Isolation
|
|
12
|
+
```javascript
|
|
13
|
+
const events = new Events();
|
|
14
|
+
events.reset(); // Clear any previous state
|
|
15
|
+
// ... test code ...
|
|
16
|
+
events.reset(); // Clean up after test
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Async Testing
|
|
20
|
+
```javascript
|
|
21
|
+
test('description', async function (assert) {
|
|
22
|
+
// Use async/await for emit()
|
|
23
|
+
await events.emit('event');
|
|
24
|
+
assert.ok(condition);
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Error Suppression
|
|
29
|
+
```javascript
|
|
30
|
+
const originalConsoleError = console.error;
|
|
31
|
+
console.error = () => {}; // Suppress expected errors
|
|
32
|
+
// ... test code ...
|
|
33
|
+
console.error = originalConsoleError; // Restore
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Coverage Areas
|
|
37
|
+
1. Event registration (setup)
|
|
38
|
+
2. Subscription management (subscribe, unsubscribe)
|
|
39
|
+
3. Event emission (emit)
|
|
40
|
+
4. One-time subscriptions (once)
|
|
41
|
+
5. Error isolation
|
|
42
|
+
6. Async support
|
|
43
|
+
7. Singleton behavior
|
|
44
|
+
8. Edge cases (unregistered events, no subscribers)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
name: Publish to NPM
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
+
repository_dispatch:
|
|
5
|
+
types: [cascade-publish]
|
|
4
6
|
workflow_dispatch:
|
|
5
7
|
inputs:
|
|
6
8
|
version-type:
|
|
@@ -17,10 +19,14 @@ on:
|
|
|
17
19
|
type: string
|
|
18
20
|
pull_request:
|
|
19
21
|
types: [opened, synchronize, reopened]
|
|
20
|
-
branches: [main
|
|
22
|
+
branches: [main]
|
|
21
23
|
push:
|
|
22
24
|
branches: [main]
|
|
23
25
|
|
|
26
|
+
concurrency:
|
|
27
|
+
group: ${{ github.event_name == 'repository_dispatch' && 'cascade-update' || format('publish-{0}', github.ref) }}
|
|
28
|
+
cancel-in-progress: false
|
|
29
|
+
|
|
24
30
|
permissions:
|
|
25
31
|
contents: write
|
|
26
32
|
id-token: write
|
|
@@ -28,8 +34,18 @@ permissions:
|
|
|
28
34
|
|
|
29
35
|
jobs:
|
|
30
36
|
publish:
|
|
37
|
+
if: "!contains(github.event.head_commit.message, '[skip ci]')"
|
|
31
38
|
uses: abofs/stonyx-workflows/.github/workflows/npm-publish.yml@main
|
|
32
39
|
with:
|
|
33
40
|
version-type: ${{ github.event.inputs.version-type }}
|
|
34
41
|
custom-version: ${{ github.event.inputs.custom-version }}
|
|
42
|
+
cascade-source: ${{ github.event.client_payload.source_package || '' }}
|
|
43
|
+
secrets: inherit
|
|
44
|
+
|
|
45
|
+
cascade:
|
|
46
|
+
needs: publish
|
|
47
|
+
uses: abofs/stonyx-workflows/.github/workflows/cascade.yml@main
|
|
48
|
+
with:
|
|
49
|
+
package-name: ${{ needs.publish.outputs.package-name }}
|
|
50
|
+
published-version: ${{ needs.publish.outputs.published-version }}
|
|
35
51
|
secrets: inherit
|
package/README.md
CHANGED
|
@@ -19,36 +19,65 @@ npm install @stonyx/events
|
|
|
19
19
|
|
|
20
20
|
## Usage
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
import Events from '@stonyx/events';
|
|
22
|
+
### Option 1: Convenience Functions (Recommended)
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
The package exports convenience functions that use a singleton instance:
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import { setup, subscribe, emit, once } from '@stonyx/events';
|
|
26
28
|
|
|
27
29
|
// Register available events
|
|
28
|
-
|
|
30
|
+
setup(['userLogin', 'userLogout', 'dataChange']);
|
|
29
31
|
|
|
30
32
|
// Subscribe to events
|
|
31
|
-
|
|
33
|
+
subscribe('userLogin', (user) => {
|
|
32
34
|
console.log(`${user.name} logged in`);
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
// Subscribe once (auto-unsubscribe after first fire)
|
|
36
|
-
|
|
38
|
+
once('dataChange', () => {
|
|
37
39
|
console.log('Data changed for the first time');
|
|
38
40
|
});
|
|
39
41
|
|
|
40
42
|
// Emit events
|
|
41
|
-
|
|
43
|
+
emit('userLogin', { name: 'Alice' });
|
|
42
44
|
|
|
43
45
|
// Unsubscribe
|
|
44
|
-
const unsub =
|
|
46
|
+
const unsub = subscribe('userLogout', handler);
|
|
45
47
|
unsub(); // Remove subscription
|
|
46
48
|
```
|
|
47
49
|
|
|
50
|
+
### Option 2: Class-based (Advanced)
|
|
51
|
+
|
|
52
|
+
You can also instantiate the Events class directly for more control:
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
import Events from '@stonyx/events';
|
|
56
|
+
|
|
57
|
+
const events = new Events();
|
|
58
|
+
|
|
59
|
+
// Register available events
|
|
60
|
+
events.setup(['userLogin', 'userLogout', 'dataChange']);
|
|
61
|
+
|
|
62
|
+
// Subscribe to events
|
|
63
|
+
events.subscribe('userLogin', (user) => {
|
|
64
|
+
console.log(`${user.name} logged in`);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Emit events
|
|
68
|
+
events.emit('userLogin', { name: 'Alice' });
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Note:** The Events class uses a singleton pattern, so all instances share the same event registry.
|
|
72
|
+
|
|
48
73
|
## API Reference
|
|
49
74
|
|
|
50
|
-
|
|
51
|
-
|
|
75
|
+
### Convenience Functions (Exported)
|
|
76
|
+
|
|
77
|
+
All functions use a singleton Events instance:
|
|
78
|
+
|
|
79
|
+
| Function | Parameters | Description |
|
|
80
|
+
|----------|-----------|-------------|
|
|
52
81
|
| `setup()` | `eventNames: string[]` | Register available event names. Events must be registered before subscribing. |
|
|
53
82
|
| `subscribe()` | `event: string, callback: Function` | Subscribe to an event. Returns an unsubscribe function. |
|
|
54
83
|
| `once()` | `event: string, callback: Function` | Subscribe to an event once. Auto-unsubscribes after first emit. |
|
|
@@ -57,16 +86,26 @@ unsub(); // Remove subscription
|
|
|
57
86
|
| `clear()` | `event: string` | Remove all subscriptions for an event. |
|
|
58
87
|
| `reset()` | none | Clear all subscriptions and events. Useful for testing. |
|
|
59
88
|
|
|
60
|
-
|
|
89
|
+
### Events Class Methods
|
|
61
90
|
|
|
62
|
-
|
|
91
|
+
If using the class directly, all methods above are available as instance methods:
|
|
63
92
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
93
|
+
```javascript
|
|
94
|
+
import Events from '@stonyx/events';
|
|
95
|
+
const events = new Events();
|
|
96
|
+
|
|
97
|
+
events.setup(['myEvent']);
|
|
98
|
+
events.subscribe('myEvent', handler);
|
|
99
|
+
events.emit('myEvent', data);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## How It Works
|
|
103
|
+
|
|
104
|
+
- The `Events` class uses a static `instance` property to enforce a singleton -- every `new Events()` returns the same object
|
|
105
|
+
- Event names are held in a `registeredEvents` Set; subscribing to an unregistered name throws immediately, catching typos early
|
|
106
|
+
- Subscribers are stored in a `Map<string, Set<Function>>`, so duplicate function references are automatically deduplicated
|
|
107
|
+
- `emit()` is async: it maps every subscriber into a `Promise`, wraps each in a try/catch for error isolation, and awaits them all with `Promise.all()`
|
|
108
|
+
- `once()` wraps the callback in a self-removing wrapper that calls `unsubscribe` before invoking the original handler
|
|
70
109
|
|
|
71
110
|
## License
|
|
72
111
|
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"keywords": [
|
|
4
4
|
"stonyx-module"
|
|
5
5
|
],
|
|
6
|
-
"version": "0.1.1-beta.
|
|
6
|
+
"version": "0.1.1-beta.10",
|
|
7
7
|
"description": "Lightweight pub/sub event system for the Stonyx framework",
|
|
8
8
|
"main": "src/main.js",
|
|
9
9
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/abofs/stonyx-events#readme",
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@stonyx/utils": "
|
|
34
|
+
"@stonyx/utils": "0.2.3-beta.7",
|
|
35
35
|
"qunit": "^2.24.1",
|
|
36
36
|
"sinon": "^21.0.0"
|
|
37
37
|
},
|
package/pnpm-lock.yaml
CHANGED
|
@@ -9,8 +9,8 @@ importers:
|
|
|
9
9
|
.:
|
|
10
10
|
devDependencies:
|
|
11
11
|
'@stonyx/utils':
|
|
12
|
-
specifier:
|
|
13
|
-
version: 0.2.
|
|
12
|
+
specifier: 0.2.3-beta.7
|
|
13
|
+
version: 0.2.3-beta.7
|
|
14
14
|
qunit:
|
|
15
15
|
specifier: ^2.24.1
|
|
16
16
|
version: 2.25.0
|
|
@@ -29,8 +29,8 @@ packages:
|
|
|
29
29
|
'@sinonjs/samsam@8.0.3':
|
|
30
30
|
resolution: {integrity: sha512-hw6HbX+GyVZzmaYNh82Ecj1vdGZrqVIn/keDTg63IgAwiQPO+xCz99uG6Woqgb4tM0mUiFENKZ4cqd7IX94AXQ==}
|
|
31
31
|
|
|
32
|
-
'@stonyx/utils@0.2.
|
|
33
|
-
resolution: {integrity: sha512-
|
|
32
|
+
'@stonyx/utils@0.2.3-beta.7':
|
|
33
|
+
resolution: {integrity: sha512-SF6ZZZJ/f1n/+SJJDj8BJdlgvv+WDLGWGUMIkwTpruA5jv/AYJqSoVIgTpYfuMTnYDIsp3KoruaIKy/qd2ETPQ==}
|
|
34
34
|
|
|
35
35
|
commander@7.2.0:
|
|
36
36
|
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
|
@@ -92,7 +92,7 @@ snapshots:
|
|
|
92
92
|
'@sinonjs/commons': 3.0.1
|
|
93
93
|
type-detect: 4.1.0
|
|
94
94
|
|
|
95
|
-
'@stonyx/utils@0.2.
|
|
95
|
+
'@stonyx/utils@0.2.3-beta.7': {}
|
|
96
96
|
|
|
97
97
|
commander@7.2.0: {}
|
|
98
98
|
|
package/src/main.js
CHANGED
|
@@ -165,3 +165,15 @@ class Events {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
export default Events;
|
|
168
|
+
|
|
169
|
+
// Create singleton instance
|
|
170
|
+
const events = new Events();
|
|
171
|
+
|
|
172
|
+
// Export convenience functions that use the singleton
|
|
173
|
+
export const setup = (...args) => events.setup(...args);
|
|
174
|
+
export const subscribe = (...args) => events.subscribe(...args);
|
|
175
|
+
export const once = (...args) => events.once(...args);
|
|
176
|
+
export const unsubscribe = (...args) => events.unsubscribe(...args);
|
|
177
|
+
export const emit = (...args) => events.emit(...args);
|
|
178
|
+
export const clear = (...args) => events.clear(...args);
|
|
179
|
+
export const reset = (...args) => events.reset(...args);
|
package/stonyx-bootstrap.cjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* commonJS Bootstrap loading - Stonyx must be loaded first, prior to the rest of the application
|
|
3
|
-
*/
|
|
4
|
-
const { default:Stonyx } = require('stonyx');
|
|
5
|
-
const { default:config } = require('./config/environment.js');
|
|
6
|
-
|
|
7
|
-
new Stonyx(config, __dirname);
|
|
8
|
-
|
|
9
|
-
module.exports = Stonyx;
|