kimu-core 0.4.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/.editorconfig +30 -0
- package/.gitattributes +11 -0
- package/.github/FUNDING.yml +8 -0
- package/.github/copilot-instructions.md +103 -0
- package/.github/kimu-copilot-instructions.md +3779 -0
- package/.github/workflows/deploy-demo.yml +39 -0
- package/AUTHORS.md +20 -0
- package/CHANGELOG.md +20 -0
- package/CODE_GUIDELINES.md +165 -0
- package/CODE_OF_CONDUCT.md +47 -0
- package/CONTRIBUTING.md +62 -0
- package/FUNDING.md +31 -0
- package/ISSUE_GUIDELINES.md +74 -0
- package/LICENSE +17 -0
- package/LICENSE.it.md +17 -0
- package/MPL-2.0.txt +373 -0
- package/NOTICE +65 -0
- package/README-KIMU.md +40 -0
- package/README.it.md +208 -0
- package/README.md +266 -0
- package/SECURITY.md +64 -0
- package/docs/get-started-en.md +207 -0
- package/docs/images/icon.svg +64 -0
- package/docs/images/logo_kimu.png +0 -0
- package/docs/index.md +29 -0
- package/env/dev.config.json +6 -0
- package/env/local.config.json +6 -0
- package/env/prod.config.json +6 -0
- package/env/staging.config.json +6 -0
- package/env/test.config.json +4 -0
- package/icon.svg +10 -0
- package/logo_kimu.png +0 -0
- package/package.json +79 -0
- package/public/favicon.svg +64 -0
- package/public/logo_kimu.svg +1 -0
- package/scripts/build-all-config.js +59 -0
- package/scripts/build-all-core.js +65 -0
- package/scripts/build-all-extensions.js +64 -0
- package/scripts/build-all-modules.js +99 -0
- package/scripts/build-extension.js +60 -0
- package/scripts/clear-kimu-build.js +31 -0
- package/scripts/generate-kimu-build-config.js +79 -0
- package/scripts/install-module.js +162 -0
- package/scripts/list-modules.js +109 -0
- package/scripts/minify-css-assets.js +82 -0
- package/scripts/remove-module.js +122 -0
- package/scripts/utils/fix-imports.js +85 -0
- package/src/assets/index.css +43 -0
- package/src/assets/kimu-style.css +84 -0
- package/src/assets/style.css +116 -0
- package/src/config/kimu-base-config.json +5 -0
- package/src/core/index.ts +47 -0
- package/src/core/kimu-app.ts +76 -0
- package/src/core/kimu-asset-manager.ts +167 -0
- package/src/core/kimu-component-element.ts +325 -0
- package/src/core/kimu-component.ts +33 -0
- package/src/core/kimu-engine.ts +188 -0
- package/src/core/kimu-extension-manager.ts +281 -0
- package/src/core/kimu-global-styles.ts +136 -0
- package/src/core/kimu-module-manager.ts +69 -0
- package/src/core/kimu-module.ts +21 -0
- package/src/core/kimu-path-config.ts +127 -0
- package/src/core/kimu-reactive.ts +196 -0
- package/src/core/kimu-render.ts +91 -0
- package/src/core/kimu-store.ts +147 -0
- package/src/core/kimu-types.ts +65 -0
- package/src/extensions/.gitkeep +0 -0
- package/src/extensions/extensions-manifest.json +13 -0
- package/src/extensions/kimu-home/component.ts +80 -0
- package/src/extensions/kimu-home/lang/en.json +5 -0
- package/src/extensions/kimu-home/lang/it.json +5 -0
- package/src/extensions/kimu-home/style.css +61 -0
- package/src/extensions/kimu-home/view.html +51 -0
- package/src/index.html +26 -0
- package/src/main.ts +68 -0
- package/src/modules/.gitkeep +0 -0
- package/src/modules/README.md +79 -0
- package/src/modules/i18n/README.it.md +63 -0
- package/src/modules/i18n/README.md +63 -0
- package/src/modules/i18n/kimu-global-lang.ts +26 -0
- package/src/modules/i18n/kimu-i18n-service.ts +108 -0
- package/src/modules/i18n/manifest.json +22 -0
- package/src/modules/i18n/module.ts +39 -0
- package/src/modules/modules-manifest.json +12 -0
- package/src/modules-repository/README.md +108 -0
- package/src/modules-repository/api-axios/CHANGELOG.md +48 -0
- package/src/modules-repository/api-axios/QUICK-REFERENCE.md +178 -0
- package/src/modules-repository/api-axios/README.md +304 -0
- package/src/modules-repository/api-axios/api-axios-service.ts +355 -0
- package/src/modules-repository/api-axios/examples.ts +293 -0
- package/src/modules-repository/api-axios/index.ts +19 -0
- package/src/modules-repository/api-axios/interfaces.ts +71 -0
- package/src/modules-repository/api-axios/module.ts +41 -0
- package/src/modules-repository/api-core/CHANGELOG.md +42 -0
- package/src/modules-repository/api-core/QUICK-REFERENCE.md +192 -0
- package/src/modules-repository/api-core/README.md +435 -0
- package/src/modules-repository/api-core/api-core-service.ts +289 -0
- package/src/modules-repository/api-core/examples.ts +432 -0
- package/src/modules-repository/api-core/index.ts +8 -0
- package/src/modules-repository/api-core/interfaces.ts +83 -0
- package/src/modules-repository/api-core/module.ts +30 -0
- package/src/modules-repository/event-bus/README.md +273 -0
- package/src/modules-repository/event-bus/event-bus-service.ts +176 -0
- package/src/modules-repository/event-bus/module.ts +30 -0
- package/src/modules-repository/i18n/README.it.md +63 -0
- package/src/modules-repository/i18n/README.md +63 -0
- package/src/modules-repository/i18n/kimu-global-lang.ts +26 -0
- package/src/modules-repository/i18n/kimu-i18n-service.ts +108 -0
- package/src/modules-repository/i18n/manifest.json +22 -0
- package/src/modules-repository/i18n/module.ts +39 -0
- package/src/modules-repository/notification/README.md +423 -0
- package/src/modules-repository/notification/module.ts +30 -0
- package/src/modules-repository/notification/notification-service.ts +436 -0
- package/src/modules-repository/router/README.it.md +39 -0
- package/src/modules-repository/router/README.md +39 -0
- package/src/modules-repository/router/manifest.json +21 -0
- package/src/modules-repository/router/module.ts +23 -0
- package/src/modules-repository/router/router.ts +144 -0
- package/src/modules-repository/state/README.md +409 -0
- package/src/modules-repository/state/module.ts +30 -0
- package/src/modules-repository/state/state-service.ts +296 -0
- package/src/modules-repository/theme/README.md +267 -0
- package/src/modules-repository/theme/module.ts +30 -0
- package/src/modules-repository/theme/pre-build.js +40 -0
- package/src/modules-repository/theme/theme-service.ts +389 -0
- package/src/modules-repository/theme/themes/theme-cherry-blossom.css +78 -0
- package/src/modules-repository/theme/themes/theme-cozy.css +111 -0
- package/src/modules-repository/theme/themes/theme-cyberpunk.css +150 -0
- package/src/modules-repository/theme/themes/theme-dark.css +79 -0
- package/src/modules-repository/theme/themes/theme-forest.css +171 -0
- package/src/modules-repository/theme/themes/theme-gold.css +100 -0
- package/src/modules-repository/theme/themes/theme-high-contrast.css +126 -0
- package/src/modules-repository/theme/themes/theme-lava.css +101 -0
- package/src/modules-repository/theme/themes/theme-lavender.css +90 -0
- package/src/modules-repository/theme/themes/theme-light.css +79 -0
- package/src/modules-repository/theme/themes/theme-matrix.css +103 -0
- package/src/modules-repository/theme/themes/theme-midnight.css +81 -0
- package/src/modules-repository/theme/themes/theme-nord.css +94 -0
- package/src/modules-repository/theme/themes/theme-ocean.css +84 -0
- package/src/modules-repository/theme/themes/theme-retro80s.css +343 -0
- package/src/modules-repository/theme/themes/theme-sunset.css +62 -0
- package/src/modules-repository/theme/themes-config.d.ts +27 -0
- package/src/modules-repository/theme/themes-config.json +213 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +33 -0
- package/vite.config.ts +99 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Event Bus Module
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
The Event Bus module provides a global publish/subscribe mechanism for component communication in KIMU-Core applications. It enables loose coupling between components by allowing them to emit and listen to custom events without direct references.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
- ✅ **Global event bus** - Centralized communication hub
|
|
8
|
+
- ✅ **Type-safe callbacks** - TypeScript support for event handlers
|
|
9
|
+
- ✅ **Auto-unsubscribe** - Subscription objects with cleanup
|
|
10
|
+
- ✅ **Once subscriptions** - Auto-unsubscribe after first event
|
|
11
|
+
- ✅ **Debug mode** - Optional logging for development
|
|
12
|
+
- ✅ **Error handling** - Isolated callback errors don't affect other subscribers
|
|
13
|
+
- ✅ **Event introspection** - Query registered events and subscriber counts
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
The Event Bus module is included in KIMU-Core. No additional installation required.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### Basic Example
|
|
21
|
+
```typescript
|
|
22
|
+
import { eventBusService } from './modules/event-bus/event-bus-service';
|
|
23
|
+
|
|
24
|
+
// Subscribe to an event
|
|
25
|
+
const subscription = eventBusService.on('user:login', (user) => {
|
|
26
|
+
console.log('User logged in:', user);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Emit an event
|
|
30
|
+
eventBusService.emit('user:login', { id: 1, name: 'John Doe' });
|
|
31
|
+
|
|
32
|
+
// Unsubscribe when done
|
|
33
|
+
subscription.unsubscribe();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### In a Component
|
|
37
|
+
```typescript
|
|
38
|
+
import { KimuComponent } from '../core/kimu-component';
|
|
39
|
+
import { KimuComponentElement } from '../core/kimu-component-element';
|
|
40
|
+
import { eventBusService } from '../modules/event-bus/event-bus-service';
|
|
41
|
+
|
|
42
|
+
@KimuComponent({
|
|
43
|
+
tag: 'my-component',
|
|
44
|
+
name: 'My Component',
|
|
45
|
+
// ...
|
|
46
|
+
})
|
|
47
|
+
export class MyComponent extends KimuComponentElement {
|
|
48
|
+
private subscriptions: any[] = [];
|
|
49
|
+
|
|
50
|
+
onInit() {
|
|
51
|
+
// Subscribe to events
|
|
52
|
+
this.subscriptions.push(
|
|
53
|
+
eventBusService.on('data:updated', this.handleDataUpdate.bind(this))
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
this.subscriptions.push(
|
|
57
|
+
eventBusService.on('theme:changed', this.handleThemeChange.bind(this))
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
handleDataUpdate(data: any) {
|
|
62
|
+
console.log('Data updated:', data);
|
|
63
|
+
this.onRender();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
handleThemeChange(theme: string) {
|
|
67
|
+
console.log('Theme changed:', theme);
|
|
68
|
+
// Update UI based on theme
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Emit events
|
|
72
|
+
saveData() {
|
|
73
|
+
// ... save logic
|
|
74
|
+
eventBusService.emit('data:saved', { timestamp: Date.now() });
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Clean up on component destroy
|
|
78
|
+
disconnectedCallback() {
|
|
79
|
+
this.subscriptions.forEach(sub => sub.unsubscribe());
|
|
80
|
+
super.disconnectedCallback();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### One-time Events
|
|
86
|
+
```typescript
|
|
87
|
+
// Subscribe only once
|
|
88
|
+
eventBusService.once('app:initialized', () => {
|
|
89
|
+
console.log('App initialized!');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// This will trigger the callback and auto-unsubscribe
|
|
93
|
+
eventBusService.emit('app:initialized');
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Debug Mode
|
|
97
|
+
```typescript
|
|
98
|
+
// Enable debug logging
|
|
99
|
+
eventBusService.setDebugMode(true);
|
|
100
|
+
|
|
101
|
+
// All subscriptions, emissions, and unsubscriptions will be logged
|
|
102
|
+
eventBusService.on('test:event', () => {});
|
|
103
|
+
// Console: [EventBus] Subscribed to: test:event
|
|
104
|
+
|
|
105
|
+
eventBusService.emit('test:event', 'data');
|
|
106
|
+
// Console: [EventBus] Emitting: test:event ['data']
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Event Introspection
|
|
110
|
+
```typescript
|
|
111
|
+
// Get list of all registered events
|
|
112
|
+
const events = eventBusService.getEventList();
|
|
113
|
+
console.log('Active events:', events);
|
|
114
|
+
|
|
115
|
+
// Check subscriber count
|
|
116
|
+
const count = eventBusService.getSubscriberCount('user:login');
|
|
117
|
+
console.log(`Subscribers for user:login: ${count}`);
|
|
118
|
+
|
|
119
|
+
// Check if event has subscribers
|
|
120
|
+
if (eventBusService.hasSubscribers('data:updated')) {
|
|
121
|
+
console.log('Someone is listening to data:updated');
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## API Reference
|
|
126
|
+
|
|
127
|
+
### `eventBusService.on(event, callback)`
|
|
128
|
+
Subscribe to an event.
|
|
129
|
+
- **event**: `string` - Event name
|
|
130
|
+
- **callback**: `Function` - Handler function
|
|
131
|
+
- **Returns**: `EventSubscription` - Subscription object with `unsubscribe()` method
|
|
132
|
+
|
|
133
|
+
### `eventBusService.once(event, callback)`
|
|
134
|
+
Subscribe to an event once (auto-unsubscribe after first emission).
|
|
135
|
+
- **event**: `string` - Event name
|
|
136
|
+
- **callback**: `Function` - Handler function
|
|
137
|
+
- **Returns**: `EventSubscription` - Subscription object
|
|
138
|
+
|
|
139
|
+
### `eventBusService.emit(event, ...args)`
|
|
140
|
+
Emit an event to all subscribers.
|
|
141
|
+
- **event**: `string` - Event name
|
|
142
|
+
- **args**: `any[]` - Arguments to pass to callbacks
|
|
143
|
+
|
|
144
|
+
### `eventBusService.off(event, callback)`
|
|
145
|
+
Unsubscribe from an event.
|
|
146
|
+
- **event**: `string` - Event name
|
|
147
|
+
- **callback**: `Function` - Callback to remove
|
|
148
|
+
|
|
149
|
+
### `eventBusService.clear(event?)`
|
|
150
|
+
Remove all subscribers for a specific event or all events.
|
|
151
|
+
- **event**: `string` (optional) - Event name
|
|
152
|
+
|
|
153
|
+
### `eventBusService.setDebugMode(enabled)`
|
|
154
|
+
Enable or disable debug logging.
|
|
155
|
+
- **enabled**: `boolean` - Debug mode state
|
|
156
|
+
|
|
157
|
+
### `eventBusService.getEventList()`
|
|
158
|
+
Get list of all registered events.
|
|
159
|
+
- **Returns**: `string[]` - Array of event names
|
|
160
|
+
|
|
161
|
+
### `eventBusService.getSubscriberCount(event)`
|
|
162
|
+
Get number of subscribers for a specific event.
|
|
163
|
+
- **event**: `string` - Event name
|
|
164
|
+
- **Returns**: `number` - Subscriber count
|
|
165
|
+
|
|
166
|
+
### `eventBusService.hasSubscribers(event)`
|
|
167
|
+
Check if an event has any subscribers.
|
|
168
|
+
- **event**: `string` - Event name
|
|
169
|
+
- **Returns**: `boolean` - True if event has subscribers
|
|
170
|
+
|
|
171
|
+
## Event Naming Conventions
|
|
172
|
+
Use namespaced event names for better organization:
|
|
173
|
+
- `user:login`, `user:logout`, `user:updated`
|
|
174
|
+
- `data:loaded`, `data:saved`, `data:error`
|
|
175
|
+
- `ui:theme-changed`, `ui:modal-opened`, `ui:notification`
|
|
176
|
+
- `app:initialized`, `app:ready`, `app:shutdown`
|
|
177
|
+
|
|
178
|
+
## Best Practices
|
|
179
|
+
|
|
180
|
+
### 1. Always Unsubscribe
|
|
181
|
+
```typescript
|
|
182
|
+
class MyComponent extends KimuComponentElement {
|
|
183
|
+
private subscriptions: any[] = [];
|
|
184
|
+
|
|
185
|
+
onInit() {
|
|
186
|
+
this.subscriptions.push(
|
|
187
|
+
eventBusService.on('event', this.handler.bind(this))
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
disconnectedCallback() {
|
|
192
|
+
this.subscriptions.forEach(sub => sub.unsubscribe());
|
|
193
|
+
super.disconnectedCallback();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 2. Use Namespaced Events
|
|
199
|
+
```typescript
|
|
200
|
+
// Good
|
|
201
|
+
eventBusService.emit('user:profile:updated', userData);
|
|
202
|
+
eventBusService.emit('notification:success', message);
|
|
203
|
+
|
|
204
|
+
// Avoid generic names
|
|
205
|
+
eventBusService.emit('update', data); // Too generic!
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### 3. Document Event Payloads
|
|
209
|
+
```typescript
|
|
210
|
+
/**
|
|
211
|
+
* Event: user:login
|
|
212
|
+
* Payload: { id: number, name: string, email: string }
|
|
213
|
+
*/
|
|
214
|
+
eventBusService.emit('user:login', { id: 1, name: 'John', email: 'john@example.com' });
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 4. Handle Errors
|
|
218
|
+
```typescript
|
|
219
|
+
eventBusService.on('data:process', (data) => {
|
|
220
|
+
try {
|
|
221
|
+
processData(data);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
eventBusService.emit('data:error', error);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Common Use Cases
|
|
229
|
+
|
|
230
|
+
### 1. Component Communication
|
|
231
|
+
```typescript
|
|
232
|
+
// Component A emits
|
|
233
|
+
eventBusService.emit('cart:item-added', { id: 123, name: 'Product' });
|
|
234
|
+
|
|
235
|
+
// Component B listens
|
|
236
|
+
eventBusService.on('cart:item-added', (item) => {
|
|
237
|
+
updateCartCount();
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### 2. State Synchronization
|
|
242
|
+
```typescript
|
|
243
|
+
// When state changes
|
|
244
|
+
eventBusService.emit('state:updated', newState);
|
|
245
|
+
|
|
246
|
+
// Components react to state changes
|
|
247
|
+
eventBusService.on('state:updated', (state) => {
|
|
248
|
+
this.updateUI(state);
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 3. User Actions
|
|
253
|
+
```typescript
|
|
254
|
+
// Button click
|
|
255
|
+
eventBusService.emit('button:save-clicked', { form: 'userProfile' });
|
|
256
|
+
|
|
257
|
+
// Multiple handlers can react
|
|
258
|
+
eventBusService.on('button:save-clicked', validateForm);
|
|
259
|
+
eventBusService.on('button:save-clicked', showLoadingIndicator);
|
|
260
|
+
eventBusService.on('button:save-clicked', trackAnalytics);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Performance Considerations
|
|
264
|
+
- Event bus is synchronous - handlers execute immediately
|
|
265
|
+
- Use wisely for frequently emitted events (e.g., scroll, mousemove)
|
|
266
|
+
- Consider debouncing or throttling for high-frequency events
|
|
267
|
+
- Always clean up subscriptions to prevent memory leaks
|
|
268
|
+
|
|
269
|
+
## License
|
|
270
|
+
This module is part of KIMU-Core and follows the same license (MPL-2.0).
|
|
271
|
+
|
|
272
|
+
## Version History
|
|
273
|
+
- **1.0.0** - Initial release with core event bus functionality
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Bus Service for KIMU-Core
|
|
3
|
+
*
|
|
4
|
+
* Provides a global publish/subscribe mechanism for component communication.
|
|
5
|
+
* Components can emit and listen to custom events without direct coupling.
|
|
6
|
+
*
|
|
7
|
+
* @module EventBusService
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export type EventCallback = (...args: any[]) => void;
|
|
12
|
+
|
|
13
|
+
export interface EventSubscription {
|
|
14
|
+
event: string;
|
|
15
|
+
callback: EventCallback;
|
|
16
|
+
unsubscribe: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* EventBusService - Global event bus for component communication
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { eventBusService } from './modules/event-bus/event-bus-service';
|
|
25
|
+
*
|
|
26
|
+
* // Subscribe to an event
|
|
27
|
+
* const subscription = eventBusService.on('user:login', (user) => {
|
|
28
|
+
* console.log('User logged in:', user);
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // Emit an event
|
|
32
|
+
* eventBusService.emit('user:login', { id: 1, name: 'John' });
|
|
33
|
+
*
|
|
34
|
+
* // Unsubscribe
|
|
35
|
+
* subscription.unsubscribe();
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export class EventBusService {
|
|
39
|
+
private events: Map<string, Set<EventCallback>> = new Map();
|
|
40
|
+
private debugMode: boolean = false;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Enable or disable debug mode for event logging
|
|
44
|
+
*/
|
|
45
|
+
setDebugMode(enabled: boolean): void {
|
|
46
|
+
this.debugMode = enabled;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Subscribe to an event
|
|
51
|
+
*
|
|
52
|
+
* @param event - Event name (e.g., 'user:login', 'data:updated')
|
|
53
|
+
* @param callback - Function to call when event is emitted
|
|
54
|
+
* @returns Subscription object with unsubscribe method
|
|
55
|
+
*/
|
|
56
|
+
on(event: string, callback: EventCallback): EventSubscription {
|
|
57
|
+
if (!this.events.has(event)) {
|
|
58
|
+
this.events.set(event, new Set());
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this.events.get(event)!.add(callback);
|
|
62
|
+
|
|
63
|
+
if (this.debugMode) {
|
|
64
|
+
console.log(`[EventBus] Subscribed to: ${event}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
event,
|
|
69
|
+
callback,
|
|
70
|
+
unsubscribe: () => this.off(event, callback)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Subscribe to an event only once (auto-unsubscribe after first emit)
|
|
76
|
+
*
|
|
77
|
+
* @param event - Event name
|
|
78
|
+
* @param callback - Function to call when event is emitted
|
|
79
|
+
* @returns Subscription object
|
|
80
|
+
*/
|
|
81
|
+
once(event: string, callback: EventCallback): EventSubscription {
|
|
82
|
+
const wrappedCallback = (...args: any[]) => {
|
|
83
|
+
callback(...args);
|
|
84
|
+
this.off(event, wrappedCallback);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return this.on(event, wrappedCallback);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Unsubscribe from an event
|
|
92
|
+
*
|
|
93
|
+
* @param event - Event name
|
|
94
|
+
* @param callback - Callback to remove
|
|
95
|
+
*/
|
|
96
|
+
off(event: string, callback: EventCallback): void {
|
|
97
|
+
if (this.events.has(event)) {
|
|
98
|
+
this.events.get(event)!.delete(callback);
|
|
99
|
+
|
|
100
|
+
// Clean up empty event sets
|
|
101
|
+
if (this.events.get(event)!.size === 0) {
|
|
102
|
+
this.events.delete(event);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (this.debugMode) {
|
|
106
|
+
console.log(`[EventBus] Unsubscribed from: ${event}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Emit an event to all subscribers
|
|
113
|
+
*
|
|
114
|
+
* @param event - Event name
|
|
115
|
+
* @param args - Arguments to pass to callbacks
|
|
116
|
+
*/
|
|
117
|
+
emit(event: string, ...args: any[]): void {
|
|
118
|
+
if (this.debugMode) {
|
|
119
|
+
console.log(`[EventBus] Emitting: ${event}`, args);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (this.events.has(event)) {
|
|
123
|
+
const callbacks = Array.from(this.events.get(event)!);
|
|
124
|
+
callbacks.forEach(callback => {
|
|
125
|
+
try {
|
|
126
|
+
callback(...args);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.error(`[EventBus] Error in event handler for "${event}":`, error);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Remove all subscribers for a specific event or all events
|
|
136
|
+
*
|
|
137
|
+
* @param event - Event name (optional, if not provided clears all)
|
|
138
|
+
*/
|
|
139
|
+
clear(event?: string): void {
|
|
140
|
+
if (event) {
|
|
141
|
+
this.events.delete(event);
|
|
142
|
+
if (this.debugMode) {
|
|
143
|
+
console.log(`[EventBus] Cleared event: ${event}`);
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
this.events.clear();
|
|
147
|
+
if (this.debugMode) {
|
|
148
|
+
console.log('[EventBus] Cleared all events');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get list of all registered events
|
|
155
|
+
*/
|
|
156
|
+
getEventList(): string[] {
|
|
157
|
+
return Array.from(this.events.keys());
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Get number of subscribers for a specific event
|
|
162
|
+
*/
|
|
163
|
+
getSubscriberCount(event: string): number {
|
|
164
|
+
return this.events.get(event)?.size || 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Check if an event has any subscribers
|
|
169
|
+
*/
|
|
170
|
+
hasSubscribers(event: string): boolean {
|
|
171
|
+
return this.getSubscriberCount(event) > 0;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Export singleton instance
|
|
176
|
+
export const eventBusService = new EventBusService();
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Bus Module for KIMU-Core
|
|
3
|
+
*
|
|
4
|
+
* Provides global event bus for component communication.
|
|
5
|
+
*
|
|
6
|
+
* @module EventBusModule
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { KimuModule } from '../../core/kimu-module';
|
|
10
|
+
import { eventBusService } from './event-bus-service';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* EventBusModule - Module class for event bus integration
|
|
14
|
+
*/
|
|
15
|
+
export default class EventBusModule extends KimuModule {
|
|
16
|
+
constructor(name = 'event-bus', version = '1.0.0', options?: any) {
|
|
17
|
+
super(name, version, options);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get the event bus service instance
|
|
22
|
+
*/
|
|
23
|
+
getService() {
|
|
24
|
+
return eventBusService;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Re-export for convenience
|
|
29
|
+
export { eventBusService } from './event-bus-service';
|
|
30
|
+
export { EventBusService } from './event-bus-service';
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Kimu I18n Module
|
|
2
|
+
|
|
3
|
+
Il modulo `i18n` di kimu-core fornisce un sistema di internazionalizzazione (internationalization) per applicazioni ed estensioni basate su kimu-core. Permette di gestire facilmente interfacce multilingua, traduzioni di stringhe e cambio dinamico della lingua.
|
|
4
|
+
|
|
5
|
+
## Scopo
|
|
6
|
+
- Abilitare la localizzazione di tutte le stringhe visibili all’utente.
|
|
7
|
+
- Gestire più lingue in modo centralizzato e modulare.
|
|
8
|
+
- Fornire API semplici per accedere alle traduzioni e cambiare lingua a runtime.
|
|
9
|
+
|
|
10
|
+
## Struttura del modulo
|
|
11
|
+
```
|
|
12
|
+
src/modules/i18n/
|
|
13
|
+
├── kimu-i18n-service.ts # Servizio principale per traduzioni e gestione lingua
|
|
14
|
+
├── kimu-global-lang.ts # Definizione delle lingue globali e risorse
|
|
15
|
+
├── module.ts # Esportazione del modulo come KimuModule
|
|
16
|
+
└── README.md # Questa documentazione
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Come funziona
|
|
20
|
+
- Il servizio `KimuI18nService` gestisce la lingua corrente e fornisce il metodo `translate(key)` per ottenere la stringa tradotta.
|
|
21
|
+
- Le risorse delle lingue sono definite in oggetti o file separati (es. `en`, `it`, ecc.).
|
|
22
|
+
- È possibile cambiare lingua a runtime e aggiornare dinamicamente l’interfaccia.
|
|
23
|
+
|
|
24
|
+
## Utilizzo base
|
|
25
|
+
```typescript
|
|
26
|
+
import I18nModule from 'src/modules/i18n/module';
|
|
27
|
+
|
|
28
|
+
// Istanzia il modulo e imposta la lingua di default
|
|
29
|
+
const i18nModule = new I18nModule('i18n', '1.0.0', { lang: 'it' });
|
|
30
|
+
const i18n = i18nModule.getService();
|
|
31
|
+
|
|
32
|
+
// Traduci una chiave
|
|
33
|
+
console.log(i18n.translate('hello'));
|
|
34
|
+
|
|
35
|
+
// Cambia lingua
|
|
36
|
+
i18n.setLang('en');
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Integrazione in un’estensione
|
|
40
|
+
```typescript
|
|
41
|
+
// Nel componente
|
|
42
|
+
getData() {
|
|
43
|
+
return {
|
|
44
|
+
translate: this.i18n.translate,
|
|
45
|
+
// ...altri dati
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Nel template HTML: <span>${translate('welcome')}</span>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Best practice
|
|
52
|
+
- Definisci tutte le stringhe utente tramite chiavi, mai testo hardcoded.
|
|
53
|
+
- Mantieni le risorse delle lingue aggiornate e documentate.
|
|
54
|
+
- Fornisci sempre l’inglese come fallback.
|
|
55
|
+
- Documenta come aggiungere nuove lingue.
|
|
56
|
+
|
|
57
|
+
## Vantaggi
|
|
58
|
+
- UI multilingua pronta all’uso.
|
|
59
|
+
- Cambi di lingua reattivi e centralizzati.
|
|
60
|
+
- Facilmente estendibile per nuove lingue o domini.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
Autore: UnicoVerso
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Kimu I18n Module
|
|
2
|
+
|
|
3
|
+
The `i18n` module in kimu-core provides an internationalization system for kimu-core-based applications and extensions. It allows you to easily manage multilingual interfaces, string translations, and dynamic language switching.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
- Enable localization of all user-visible strings.
|
|
7
|
+
- Manage multiple languages in a centralized and modular way.
|
|
8
|
+
- Provide simple APIs to access translations and change language at runtime.
|
|
9
|
+
|
|
10
|
+
## Module Structure
|
|
11
|
+
```
|
|
12
|
+
src/modules/i18n/
|
|
13
|
+
├── kimu-i18n-service.ts # Main service for translations and language management
|
|
14
|
+
├── kimu-global-lang.ts # Definition of global languages and resources
|
|
15
|
+
├── module.ts # Module export as KimuModule
|
|
16
|
+
└── README.md # This documentation
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## How it works
|
|
20
|
+
- The `KimuI18nService` manages the current language and provides the `translate(key)` method to get the translated string.
|
|
21
|
+
- Language resources are defined in separate objects or files (e.g., `en`, `it`, etc.).
|
|
22
|
+
- You can change language at runtime and dynamically update the interface.
|
|
23
|
+
|
|
24
|
+
## Basic usage
|
|
25
|
+
```typescript
|
|
26
|
+
import I18nModule from 'src/modules/i18n/module';
|
|
27
|
+
|
|
28
|
+
// Instantiate the module and set the default language
|
|
29
|
+
const i18nModule = new I18nModule('i18n', '1.0.0', { lang: 'it' });
|
|
30
|
+
const i18n = i18nModule.getService();
|
|
31
|
+
|
|
32
|
+
// Translate a key
|
|
33
|
+
console.log(i18n.translate('hello'));
|
|
34
|
+
|
|
35
|
+
// Change language
|
|
36
|
+
i18n.setLang('en');
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Integration in an extension
|
|
40
|
+
```typescript
|
|
41
|
+
// In the component
|
|
42
|
+
getData() {
|
|
43
|
+
return {
|
|
44
|
+
translate: this.i18n.translate,
|
|
45
|
+
// ...other data
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// In the HTML template: <span>${translate('welcome')}</span>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Best practices
|
|
52
|
+
- Define all user strings using keys, never hardcoded text.
|
|
53
|
+
- Keep language resources updated and documented.
|
|
54
|
+
- Always provide English as a fallback.
|
|
55
|
+
- Document how to add new languages.
|
|
56
|
+
|
|
57
|
+
## Advantages
|
|
58
|
+
- Ready-to-use multilingual UI.
|
|
59
|
+
- Reactive and centralized language changes.
|
|
60
|
+
- Easily extendable for new languages or domains.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
Author: UnicoVerso
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type LangChangeCallback = (lang: string) => void;
|
|
2
|
+
|
|
3
|
+
export class KimuGlobalLang {
|
|
4
|
+
private static currentLang: string = 'it';
|
|
5
|
+
private static listeners: LangChangeCallback[] = [];
|
|
6
|
+
|
|
7
|
+
static set(lang: string) {
|
|
8
|
+
//console.log(`[KimuGlobalLang] set language: ${lang}`);
|
|
9
|
+
if (lang !== this.currentLang) {
|
|
10
|
+
this.currentLang = lang;
|
|
11
|
+
this.listeners.forEach(fn => fn(lang));
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static get(): string {
|
|
16
|
+
return this.currentLang;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static onChange(cb: LangChangeCallback) {
|
|
20
|
+
this.listeners.push(cb);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static off(cb: LangChangeCallback) {
|
|
24
|
+
this.listeners = this.listeners.filter(fn => fn !== cb);
|
|
25
|
+
}
|
|
26
|
+
}
|