@relax.js/core 1.0.3 → 1.0.5

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.
Files changed (90) hide show
  1. package/README.md +194 -188
  2. package/dist/DependencyInjection.d.ts +45 -27
  3. package/dist/collections/LinkedList.d.ts +9 -8
  4. package/dist/collections/index.js +1 -1
  5. package/dist/collections/index.js.map +3 -3
  6. package/dist/collections/index.mjs +1 -1
  7. package/dist/collections/index.mjs.map +3 -3
  8. package/dist/di/index.js +1 -1
  9. package/dist/di/index.js.map +3 -3
  10. package/dist/di/index.mjs +1 -1
  11. package/dist/di/index.mjs.map +3 -3
  12. package/dist/elements/index.js +1 -1
  13. package/dist/elements/index.js.map +1 -1
  14. package/dist/errors.d.ts +20 -0
  15. package/dist/forms/FormValidator.d.ts +3 -22
  16. package/dist/forms/ValidationRules.d.ts +4 -6
  17. package/dist/forms/index.js +1 -1
  18. package/dist/forms/index.js.map +4 -4
  19. package/dist/forms/index.mjs +1 -1
  20. package/dist/forms/index.mjs.map +4 -4
  21. package/dist/forms/setFormData.d.ts +39 -1
  22. package/dist/html/TableRenderer.d.ts +1 -0
  23. package/dist/html/index.js +1 -1
  24. package/dist/html/index.js.map +3 -3
  25. package/dist/html/index.mjs +1 -1
  26. package/dist/html/index.mjs.map +3 -3
  27. package/dist/html/template.d.ts +4 -0
  28. package/dist/http/ServerSentEvents.d.ts +1 -1
  29. package/dist/http/SimpleWebSocket.d.ts +1 -1
  30. package/dist/http/http.d.ts +1 -0
  31. package/dist/http/index.js +1 -1
  32. package/dist/http/index.js.map +3 -3
  33. package/dist/http/index.mjs +1 -1
  34. package/dist/http/index.mjs.map +3 -3
  35. package/dist/i18n/icu.d.ts +1 -1
  36. package/dist/i18n/index.js +1 -1
  37. package/dist/i18n/index.js.map +2 -2
  38. package/dist/i18n/index.mjs +1 -1
  39. package/dist/i18n/index.mjs.map +2 -2
  40. package/dist/index.js +3 -3
  41. package/dist/index.js.map +3 -3
  42. package/dist/index.mjs +3 -3
  43. package/dist/index.mjs.map +3 -3
  44. package/dist/routing/NavigateRouteEvent.d.ts +4 -4
  45. package/dist/routing/index.js +3 -3
  46. package/dist/routing/index.js.map +3 -3
  47. package/dist/routing/index.mjs +3 -3
  48. package/dist/routing/index.mjs.map +3 -3
  49. package/dist/routing/navigation.d.ts +1 -1
  50. package/dist/routing/routeTargetRegistry.d.ts +1 -0
  51. package/dist/routing/types.d.ts +2 -1
  52. package/dist/templates/NodeTemplate.d.ts +3 -1
  53. package/dist/utils/index.d.ts +1 -1
  54. package/dist/utils/index.js +1 -1
  55. package/dist/utils/index.js.map +3 -3
  56. package/dist/utils/index.mjs +1 -1
  57. package/dist/utils/index.mjs.map +3 -3
  58. package/docs/Architecture.md +333 -333
  59. package/docs/DependencyInjection.md +277 -237
  60. package/docs/Errors.md +87 -87
  61. package/docs/GettingStarted.md +238 -231
  62. package/docs/Pipes.md +5 -5
  63. package/docs/Translations.md +167 -312
  64. package/docs/WhyRelaxjs.md +336 -336
  65. package/docs/api.json +93193 -0
  66. package/docs/elements/dom.md +102 -102
  67. package/docs/forms/creating-form-components.md +924 -924
  68. package/docs/forms/form-api.md +94 -94
  69. package/docs/forms/forms.md +99 -99
  70. package/docs/forms/patterns.md +311 -311
  71. package/docs/forms/reading-writing.md +465 -365
  72. package/docs/forms/validation.md +351 -351
  73. package/docs/html/TableRenderer.md +291 -291
  74. package/docs/html/html.md +175 -175
  75. package/docs/html/index.md +54 -54
  76. package/docs/html/template.md +422 -422
  77. package/docs/http/HttpClient.md +459 -459
  78. package/docs/http/ServerSentEvents.md +184 -184
  79. package/docs/http/index.md +109 -109
  80. package/docs/i18n/i18n.md +49 -4
  81. package/docs/i18n/intl-standard.md +178 -178
  82. package/docs/routing/RouteLink.md +98 -98
  83. package/docs/routing/Routing.md +332 -332
  84. package/docs/routing/layouts.md +207 -207
  85. package/docs/setup/bootstrapping.md +154 -0
  86. package/docs/setup/build-and-deploy.md +183 -0
  87. package/docs/setup/project-structure.md +170 -0
  88. package/docs/setup/vite.md +175 -0
  89. package/docs/utilities.md +143 -143
  90. package/package.json +4 -2
@@ -1,184 +1,184 @@
1
- # Server-Sent Events
2
-
3
- SSE client that dispatches received server events as DOM events.
4
-
5
- ## Quick Start
6
-
7
- ```typescript
8
- import { SSEClient, SSEDataEvent } from 'relaxjs/http';
9
-
10
- const sse = new SSEClient('/api/events', {
11
- eventTypes: ['user-updated', 'notification']
12
- });
13
-
14
- sse.connect();
15
-
16
- document.addEventListener('user-updated', (e: SSEDataEvent) => {
17
- console.log('User updated:', e.data);
18
- });
19
-
20
- // When done
21
- sse.disconnect();
22
- ```
23
-
24
- ## Configuration
25
-
26
- ```typescript
27
- interface SSEOptions {
28
- target?: string | Element; // CSS selector or element (default: document)
29
- withCredentials?: boolean; // Send credentials (default: false)
30
- eventTypes?: string[]; // SSE event types to listen for
31
- eventFactory?: SSEEventFactory; // Custom event factory
32
- onConnect?: (client: SSEClient) => void;
33
- onError?: (client: SSEClient, error: Event) => void;
34
- }
35
-
36
- type SSEEventFactory = (eventName: string, data: unknown) => Event;
37
- ```
38
-
39
- ## Event Types
40
-
41
- ### Default (message)
42
-
43
- Without `eventTypes`, listens to the default `message` event:
44
-
45
- ```typescript
46
- // Server sends: data: {"text": "hello"}
47
- const sse = new SSEClient('/api/events');
48
- sse.connect();
49
-
50
- document.addEventListener('message', (e: SSEDataEvent) => {
51
- console.log(e.data); // { text: 'hello' }
52
- });
53
- ```
54
-
55
- ### Named Events
56
-
57
- With `eventTypes`, listens to specific SSE event types:
58
-
59
- ```typescript
60
- // Server sends: event: notification\ndata: {"text": "hello"}
61
- const sse = new SSEClient('/api/events', {
62
- eventTypes: ['notification', 'alert']
63
- });
64
- sse.connect();
65
-
66
- document.addEventListener('notification', (e: SSEDataEvent) => {
67
- console.log(e.data);
68
- });
69
- ```
70
-
71
- ## Target Element
72
-
73
- Dispatch events to a specific element instead of document:
74
-
75
- ```typescript
76
- const sse = new SSEClient('/api/events', {
77
- target: '#notifications',
78
- eventTypes: ['notification']
79
- });
80
-
81
- sse.connect();
82
-
83
- document.querySelector('#notifications')
84
- .addEventListener('notification', (e: SSEDataEvent) => {
85
- showNotification(e.data);
86
- });
87
- ```
88
-
89
- ## Event Factory
90
-
91
- Use `eventFactory` to create custom event instances:
92
-
93
- ```typescript
94
- class UserUpdatedEvent extends Event {
95
- constructor(public user: User) {
96
- super('user-updated', { bubbles: true });
97
- }
98
- }
99
-
100
- class OrderCreatedEvent extends Event {
101
- constructor(public order: Order) {
102
- super('order-created', { bubbles: true });
103
- }
104
- }
105
-
106
- const sse = new SSEClient('/api/events', {
107
- eventTypes: ['user-updated', 'order-created'],
108
- eventFactory: (eventName, data) => {
109
- switch (eventName) {
110
- case 'user-updated':
111
- return new UserUpdatedEvent(data as User);
112
- case 'order-created':
113
- return new OrderCreatedEvent(data as Order);
114
- default:
115
- return new SSEDataEvent(eventName, data);
116
- }
117
- }
118
- });
119
-
120
- sse.connect();
121
-
122
- // Now events are properly typed
123
- document.addEventListener('user-updated', (e: UserUpdatedEvent) => {
124
- console.log(e.user);
125
- });
126
- ```
127
-
128
- ## Type Registration
129
-
130
- Register event types for TypeScript support:
131
-
132
- ```typescript
133
- declare global {
134
- interface DocumentEventMap {
135
- 'user-updated': UserUpdatedEvent;
136
- 'order-created': OrderCreatedEvent;
137
- }
138
- }
139
-
140
- // TypeScript now knows the event type
141
- document.addEventListener('user-updated', (e) => {
142
- console.log(e.user); // Typed as User
143
- });
144
- ```
145
-
146
- ## Reconnection
147
-
148
- EventSource has built-in automatic reconnection. The `onError` callback fires when errors occur, but the browser handles reconnection automatically.
149
-
150
- ```typescript
151
- const sse = new SSEClient('/api/events', {
152
- onConnect: () => console.log('Connected'),
153
- onError: () => console.log('Error (will auto-reconnect)')
154
- });
155
- ```
156
-
157
- ## API Reference
158
-
159
- ### SSEClient
160
-
161
- | Method/Property | Description |
162
- |-----------------|-------------|
163
- | `connect()` | Establish SSE connection |
164
- | `disconnect()` | Close connection |
165
- | `connected` | `boolean` - Current connection state |
166
-
167
- ### SSEDataEvent
168
-
169
- | Property | Type | Description |
170
- |----------|------|-------------|
171
- | `type` | `string` | Event name from SSE |
172
- | `data` | `unknown` | Parsed data (JSON auto-parsed) |
173
- | `bubbles` | `boolean` | Always `true` |
174
-
175
- ### Exports
176
-
177
- ```typescript
178
- import {
179
- SSEClient,
180
- SSEOptions,
181
- SSEDataEvent,
182
- SSEEventFactory
183
- } from 'relaxjs/http';
184
- ```
1
+ # Server-Sent Events
2
+
3
+ SSE client that dispatches received server events as DOM events.
4
+
5
+ ## Quick Start
6
+
7
+ ```typescript
8
+ import { SSEClient, SSEDataEvent } from '@relax.js/core/http';
9
+
10
+ const sse = new SSEClient('/api/events', {
11
+ eventTypes: ['user-updated', 'notification']
12
+ });
13
+
14
+ sse.connect();
15
+
16
+ document.addEventListener('user-updated', (e: SSEDataEvent) => {
17
+ console.log('User updated:', e.data);
18
+ });
19
+
20
+ // When done
21
+ sse.disconnect();
22
+ ```
23
+
24
+ ## Configuration
25
+
26
+ ```typescript
27
+ interface SSEOptions {
28
+ target?: string | Element; // CSS selector or element (default: document)
29
+ withCredentials?: boolean; // Send credentials (default: false)
30
+ eventTypes?: string[]; // SSE event types to listen for
31
+ eventFactory?: SSEEventFactory; // Custom event factory
32
+ onConnect?: (client: SSEClient) => void;
33
+ onError?: (client: SSEClient, error: Event) => void;
34
+ }
35
+
36
+ type SSEEventFactory = (eventName: string, data: unknown) => Event;
37
+ ```
38
+
39
+ ## Event Types
40
+
41
+ ### Default (message)
42
+
43
+ Without `eventTypes`, listens to the default `message` event:
44
+
45
+ ```typescript
46
+ // Server sends: data: {"text": "hello"}
47
+ const sse = new SSEClient('/api/events');
48
+ sse.connect();
49
+
50
+ document.addEventListener('message', (e: SSEDataEvent) => {
51
+ console.log(e.data); // { text: 'hello' }
52
+ });
53
+ ```
54
+
55
+ ### Named Events
56
+
57
+ With `eventTypes`, listens to specific SSE event types:
58
+
59
+ ```typescript
60
+ // Server sends: event: notification\ndata: {"text": "hello"}
61
+ const sse = new SSEClient('/api/events', {
62
+ eventTypes: ['notification', 'alert']
63
+ });
64
+ sse.connect();
65
+
66
+ document.addEventListener('notification', (e: SSEDataEvent) => {
67
+ console.log(e.data);
68
+ });
69
+ ```
70
+
71
+ ## Target Element
72
+
73
+ Dispatch events to a specific element instead of document:
74
+
75
+ ```typescript
76
+ const sse = new SSEClient('/api/events', {
77
+ target: '#notifications',
78
+ eventTypes: ['notification']
79
+ });
80
+
81
+ sse.connect();
82
+
83
+ document.querySelector('#notifications')
84
+ .addEventListener('notification', (e: SSEDataEvent) => {
85
+ showNotification(e.data);
86
+ });
87
+ ```
88
+
89
+ ## Event Factory
90
+
91
+ Use `eventFactory` to create custom event instances:
92
+
93
+ ```typescript
94
+ class UserUpdatedEvent extends Event {
95
+ constructor(public user: User) {
96
+ super('user-updated', { bubbles: true });
97
+ }
98
+ }
99
+
100
+ class OrderCreatedEvent extends Event {
101
+ constructor(public order: Order) {
102
+ super('order-created', { bubbles: true });
103
+ }
104
+ }
105
+
106
+ const sse = new SSEClient('/api/events', {
107
+ eventTypes: ['user-updated', 'order-created'],
108
+ eventFactory: (eventName, data) => {
109
+ switch (eventName) {
110
+ case 'user-updated':
111
+ return new UserUpdatedEvent(data as User);
112
+ case 'order-created':
113
+ return new OrderCreatedEvent(data as Order);
114
+ default:
115
+ return new SSEDataEvent(eventName, data);
116
+ }
117
+ }
118
+ });
119
+
120
+ sse.connect();
121
+
122
+ // Now events are properly typed
123
+ document.addEventListener('user-updated', (e: UserUpdatedEvent) => {
124
+ console.log(e.user);
125
+ });
126
+ ```
127
+
128
+ ## Type Registration
129
+
130
+ Register event types for TypeScript support:
131
+
132
+ ```typescript
133
+ declare global {
134
+ interface DocumentEventMap {
135
+ 'user-updated': UserUpdatedEvent;
136
+ 'order-created': OrderCreatedEvent;
137
+ }
138
+ }
139
+
140
+ // TypeScript now knows the event type
141
+ document.addEventListener('user-updated', (e) => {
142
+ console.log(e.user); // Typed as User
143
+ });
144
+ ```
145
+
146
+ ## Reconnection
147
+
148
+ EventSource has built-in automatic reconnection. The `onError` callback fires when errors occur, but the browser handles reconnection automatically.
149
+
150
+ ```typescript
151
+ const sse = new SSEClient('/api/events', {
152
+ onConnect: () => console.log('Connected'),
153
+ onError: () => console.log('Error (will auto-reconnect)')
154
+ });
155
+ ```
156
+
157
+ ## API Reference
158
+
159
+ ### SSEClient
160
+
161
+ | Method/Property | Description |
162
+ |-----------------|-------------|
163
+ | `connect()` | Establish SSE connection |
164
+ | `disconnect()` | Close connection |
165
+ | `connected` | `boolean` - Current connection state |
166
+
167
+ ### SSEDataEvent
168
+
169
+ | Property | Type | Description |
170
+ |----------|------|-------------|
171
+ | `type` | `string` | Event name from SSE |
172
+ | `data` | `unknown` | Parsed data (JSON auto-parsed) |
173
+ | `bubbles` | `boolean` | Always `true` |
174
+
175
+ ### Exports
176
+
177
+ ```typescript
178
+ import {
179
+ SSEClient,
180
+ SSEOptions,
181
+ SSEDataEvent,
182
+ SSEEventFactory
183
+ } from '@relax.js/core/http';
184
+ ```
@@ -1,109 +1,109 @@
1
- # HTTP, WebSocket & SSE
2
-
3
- This module provides HTTP, WebSocket, and Server-Sent Events clients for network communication.
4
-
5
- ## Available Features
6
-
7
- | Feature | Description | Use Case |
8
- |---------|-------------|----------|
9
- | [HTTP Client](HttpClient.md#http-client) | Type-safe HTTP functions | REST API calls with JWT handling |
10
- | [WebSocketClient](HttpClient.md#websocket-client) | WebSocket client with auto-reconnect | Real-time bidirectional messaging |
11
- | [SSEClient](ServerSentEvents.md) | Server-Sent Events as DOM events | Server push notifications |
12
-
13
- ## Quick Start
14
-
15
- ### HTTP Requests
16
-
17
- ```typescript
18
- import { configure, get, post } from 'relaxjs/http';
19
-
20
- configure({ baseUrl: '/api/v1' });
21
-
22
- // GET with query parameters
23
- const response = await get('/users', { status: 'active' });
24
- if (response.success) {
25
- const users = response.as<User[]>();
26
- }
27
-
28
- // POST with JSON body
29
- const result = await post('/users', JSON.stringify({ name: 'John' }));
30
- ```
31
-
32
- ### WebSocket Messaging
33
-
34
- ```typescript
35
- import { WebSocketClient } from 'relaxjs/http';
36
-
37
- const ws = new WebSocketClient<Message>('wss://api.example.com');
38
- ws.connect();
39
-
40
- // Check connection state
41
- console.log(ws.connected); // true when connected
42
-
43
- // Send (queued if disconnected)
44
- ws.send({ type: 'chat', text: 'Hello' });
45
-
46
- // Receive (rejects if connection closes)
47
- try {
48
- const message = await ws.receive();
49
- } catch (e) {
50
- console.log('Connection closed');
51
- }
52
-
53
- // Disconnect when done
54
- ws.disconnect();
55
- ```
56
-
57
- ### Server-Sent Events
58
-
59
- ```typescript
60
- import { SSEClient } from 'relaxjs/http';
61
-
62
- const sse = new SSEClient('/api/events', {
63
- eventTypes: ['user-updated', 'notification']
64
- });
65
- sse.connect();
66
-
67
- // Events dispatch to document by default
68
- document.addEventListener('notification', (e: SSEMessageEvent) => {
69
- showNotification(e.data);
70
- });
71
-
72
- // Disconnect when done
73
- sse.disconnect();
74
- ```
75
-
76
- ## Key Features
77
-
78
- ### HTTP Client
79
-
80
- - Standalone functions (`get`, `post`, `put`, `del`, `request`)
81
- - Module-wide configuration via `configure()`
82
- - Automatic base URL prefixing
83
- - JWT token from localStorage (configurable)
84
- - Query string building
85
- - Type-safe response casting
86
- - Replaceable fetch for testing via `setFetch()`
87
-
88
- ### WebSocketClient
89
-
90
- - Auto-reconnect with exponential backoff
91
- - Message queuing when disconnected
92
- - Custom message codecs
93
- - Type-safe generic messages
94
- - Connection state tracking
95
- - Graceful disconnect support
96
-
97
- ### SSEClient
98
-
99
- - Dispatches SSE events as DOM events
100
- - Configurable target element or document
101
- - Auto-reconnect with exponential backoff
102
- - Automatic JSON parsing
103
-
104
- ## Choosing the Right Tool
105
-
106
- - **REST API calls?** → Use `get`, `post`, `put`, `del`
107
- - **Bidirectional real-time?** → Use `WebSocketClient`
108
- - **Server push only?** → Use `SSEClient`
109
- - **Both?** → Use `HttpClient` for requests, `WebSocketClient` or `SSEClient` for subscriptions
1
+ # HTTP, WebSocket & SSE
2
+
3
+ This module provides HTTP, WebSocket, and Server-Sent Events clients for network communication.
4
+
5
+ ## Available Features
6
+
7
+ | Feature | Description | Use Case |
8
+ |---------|-------------|----------|
9
+ | [HTTP Client](HttpClient.md#http-client) | Type-safe HTTP functions | REST API calls with JWT handling |
10
+ | [WebSocketClient](HttpClient.md#websocket-client) | WebSocket client with auto-reconnect | Real-time bidirectional messaging |
11
+ | [SSEClient](ServerSentEvents.md) | Server-Sent Events as DOM events | Server push notifications |
12
+
13
+ ## Quick Start
14
+
15
+ ### HTTP Requests
16
+
17
+ ```typescript
18
+ import { configure, get, post } from '@relax.js/core/http';
19
+
20
+ configure({ baseUrl: '/api/v1' });
21
+
22
+ // GET with query parameters
23
+ const response = await get('/users', { status: 'active' });
24
+ if (response.success) {
25
+ const users = response.as<User[]>();
26
+ }
27
+
28
+ // POST with JSON body
29
+ const result = await post('/users', JSON.stringify({ name: 'John' }));
30
+ ```
31
+
32
+ ### WebSocket Messaging
33
+
34
+ ```typescript
35
+ import { WebSocketClient } from '@relax.js/core/http';
36
+
37
+ const ws = new WebSocketClient<Message>('wss://api.example.com');
38
+ ws.connect();
39
+
40
+ // Check connection state
41
+ console.log(ws.connected); // true when connected
42
+
43
+ // Send (queued if disconnected)
44
+ ws.send({ type: 'chat', text: 'Hello' });
45
+
46
+ // Receive (rejects if connection closes)
47
+ try {
48
+ const message = await ws.receive();
49
+ } catch (e) {
50
+ console.log('Connection closed');
51
+ }
52
+
53
+ // Disconnect when done
54
+ ws.disconnect();
55
+ ```
56
+
57
+ ### Server-Sent Events
58
+
59
+ ```typescript
60
+ import { SSEClient } from '@relax.js/core/http';
61
+
62
+ const sse = new SSEClient('/api/events', {
63
+ eventTypes: ['user-updated', 'notification']
64
+ });
65
+ sse.connect();
66
+
67
+ // Events dispatch to document by default
68
+ document.addEventListener('notification', (e: SSEMessageEvent) => {
69
+ showNotification(e.data);
70
+ });
71
+
72
+ // Disconnect when done
73
+ sse.disconnect();
74
+ ```
75
+
76
+ ## Key Features
77
+
78
+ ### HTTP Client
79
+
80
+ - Standalone functions (`get`, `post`, `put`, `del`, `request`)
81
+ - Module-wide configuration via `configure()`
82
+ - Automatic base URL prefixing
83
+ - JWT token from localStorage (configurable)
84
+ - Query string building
85
+ - Type-safe response casting
86
+ - Replaceable fetch for testing via `setFetch()`
87
+
88
+ ### WebSocketClient
89
+
90
+ - Auto-reconnect with exponential backoff
91
+ - Message queuing when disconnected
92
+ - Custom message codecs
93
+ - Type-safe generic messages
94
+ - Connection state tracking
95
+ - Graceful disconnect support
96
+
97
+ ### SSEClient
98
+
99
+ - Dispatches SSE events as DOM events
100
+ - Configurable target element or document
101
+ - Auto-reconnect with exponential backoff
102
+ - Automatic JSON parsing
103
+
104
+ ## Choosing the Right Tool
105
+
106
+ - **REST API calls?** → Use `get`, `post`, `put`, `del`
107
+ - **Bidirectional real-time?** → Use `WebSocketClient`
108
+ - **Server push only?** → Use `SSEClient`
109
+ - **Both?** → Use `HttpClient` for requests, `WebSocketClient` or `SSEClient` for subscriptions
package/docs/i18n/i18n.md CHANGED
@@ -5,7 +5,7 @@ Namespace-based translations with ICU message format, lazy loading, and locale c
5
5
  ## Quick Start
6
6
 
7
7
  ```typescript
8
- import { setLocale, loadNamespaces, t } from 'relaxjs/i18n';
8
+ import { setLocale, loadNamespaces, t } from '@relax.js/core/i18n';
9
9
 
10
10
  await setLocale('sv');
11
11
  await loadNamespaces(['r-pipes', 'r-validation']);
@@ -106,6 +106,51 @@ t('status', { role: 'editor' }); // "Can edit"
106
106
  t('status', { role: 'viewer' }); // "Read only" (other)
107
107
  ```
108
108
 
109
+ ### Number and Date Formatting
110
+
111
+ ICU format supports locale-aware number and date formatting:
112
+
113
+ ```json
114
+ {
115
+ "price": "Price: {amount, number, currency}",
116
+ "date": "Date: {date, date, medium}"
117
+ }
118
+ ```
119
+
120
+ ## Example Translation Files
121
+
122
+ **`src/i18n/locales/en/r-common.json`**:
123
+
124
+ ```json
125
+ {
126
+ "welcome": "Welcome to our site!",
127
+ "greeting": "Hello, {name}!",
128
+ "items": "{count, plural, =0 {No items} one {# item} other {# items}}",
129
+ "goodbye": "Goodbye!"
130
+ }
131
+ ```
132
+
133
+ **`src/i18n/locales/en/errors.json`**:
134
+
135
+ ```json
136
+ {
137
+ "notFound": "Page not found",
138
+ "unauthorized": "You are not authorized to view this page",
139
+ "serverError": "An unexpected error occurred"
140
+ }
141
+ ```
142
+
143
+ **`src/i18n/locales/sv/r-common.json`**:
144
+
145
+ ```json
146
+ {
147
+ "welcome": "Välkommen till vår sida!",
148
+ "greeting": "Hej, {name}!",
149
+ "items": "{count, plural, =0 {Inga föremål} one {# föremål} other {# föremål}}",
150
+ "goodbye": "Hejdå!"
151
+ }
152
+ ```
153
+
109
154
  ## Built-in Namespaces
110
155
 
111
156
  ### r-common
@@ -173,7 +218,7 @@ The event has a typed `locale` property (the normalized locale code) and is regi
173
218
  Register a callback for when `t()` encounters a missing key. Useful for development tooling, logging, or collecting untranslated strings:
174
219
 
175
220
  ```typescript
176
- import { onMissingTranslation } from 'relaxjs/i18n';
221
+ import { onMissingTranslation } from '@relax.js/core/i18n';
177
222
 
178
223
  onMissingTranslation((key, namespace, locale) => {
179
224
  console.warn(`Missing: ${namespace}:${key} [${locale}]`);
@@ -197,7 +242,7 @@ onMissingTranslation(null);
197
242
  The built-in formatter supports interpolation, pluralization, and select. For advanced ICU features (nested arguments, date/time formatting in messages), use an external library:
198
243
 
199
244
  ```typescript
200
- import { setMessageFormatter } from 'relaxjs/i18n';
245
+ import { setMessageFormatter } from '@relax.js/core/i18n';
201
246
  import { IntlMessageFormat } from 'intl-messageformat';
202
247
 
203
248
  setMessageFormatter((message, values, locale) => {
@@ -284,7 +329,7 @@ type MissingTranslationHandler = (
284
329
  import {
285
330
  setLocale, loadNamespaces, t,
286
331
  getCurrentLocale, onMissingTranslation,
287
- } from 'relaxjs/i18n';
332
+ } from '@relax.js/core/i18n';
288
333
 
289
334
  async function initI18n() {
290
335
  // Dev-time missing key logging