@med1802/repository-manager 3.1.2 → 3.2.0
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 +138 -197
- package/dist/core/createSignalBroadcaster.d.ts +8 -0
- package/dist/core/createSignalBroadcaster.d.ts.map +1 -0
- package/dist/core/{messenger.js → createSignalBroadcaster.js} +5 -9
- package/dist/core/index.d.ts +8 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +58 -1
- package/dist/infrastructure/logger.d.ts +1 -1
- package/dist/infrastructure/logger.d.ts.map +1 -1
- package/dist/manager.d.ts +1 -1
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +8 -5
- package/dist/types/observer.types.d.ts +5 -5
- package/dist/types/observer.types.d.ts.map +1 -1
- package/dist/types/repository.types.d.ts +3 -2
- package/dist/types/repository.types.d.ts.map +1 -1
- package/dist/types/workspace.types.d.ts +3 -1
- package/dist/types/workspace.types.d.ts.map +1 -1
- package/dist/workspace/{mount.d.ts → createWorkspace.d.ts} +10 -12
- package/dist/workspace/createWorkspace.d.ts.map +1 -0
- package/dist/workspace/createWorkspace.js +19 -0
- package/dist/workspace/{client.d.ts → createWorkspaceClient.d.ts} +1 -1
- package/dist/workspace/createWorkspaceClient.d.ts.map +1 -0
- package/dist/workspace/{client.js → createWorkspaceClient.js} +1 -1
- package/dist/workspace/index.d.ts +3 -3
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +3 -3
- package/dist/workspace/{context.d.ts → providers/client.d.ts} +4 -4
- package/dist/workspace/providers/client.d.ts.map +1 -0
- package/dist/workspace/{context.js → providers/client.js} +1 -1
- package/dist/workspace/providers/index.d.ts +3 -0
- package/dist/workspace/providers/index.d.ts.map +1 -0
- package/dist/workspace/providers/index.js +2 -0
- package/dist/workspace/providers/setup.d.ts +19 -0
- package/dist/workspace/providers/setup.d.ts.map +1 -0
- package/dist/workspace/providers/setup.js +42 -0
- package/package.json +1 -1
- package/src/core/{messenger.ts → createSignalBroadcaster.ts} +7 -12
- package/src/core/index.ts +65 -1
- package/src/infrastructure/logger.ts +1 -1
- package/src/manager.ts +15 -6
- package/src/types/observer.types.ts +6 -6
- package/src/types/repository.types.ts +3 -2
- package/src/types/workspace.types.ts +3 -1
- package/src/workspace/createWorkspace.ts +23 -0
- package/src/workspace/{client.ts → createWorkspaceClient.ts} +1 -1
- package/src/workspace/index.ts +3 -3
- package/src/workspace/providers/client.ts +39 -0
- package/src/workspace/providers/index.ts +2 -0
- package/src/workspace/providers/setup.ts +59 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/core/messenger.d.ts +0 -9
- package/dist/core/messenger.d.ts.map +0 -1
- package/dist/core/repository.d.ts +0 -10
- package/dist/core/repository.d.ts.map +0 -1
- package/dist/core/repository.js +0 -51
- package/dist/workspace/client.d.ts.map +0 -1
- package/dist/workspace/context.d.ts.map +0 -1
- package/dist/workspace/mount.d.ts.map +0 -1
- package/dist/workspace/mount.js +0 -33
- package/src/core/repository.ts +0 -58
- package/src/workspace/context.ts +0 -43
- package/src/workspace/mount.ts +0 -38
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ A lightweight, type-safe repository manager with dependency injection, event-dri
|
|
|
5
5
|
## ✨ Features
|
|
6
6
|
|
|
7
7
|
- ✅ **Dependency Injection** - Inject dependencies into repositories
|
|
8
|
-
- ✅ **Event-Driven Architecture** - Built-in
|
|
8
|
+
- ✅ **Event-Driven Architecture** - Built-in signal broadcasting for inter-repository communication
|
|
9
9
|
- ✅ **Plugin System** - Define repositories as plugins
|
|
10
10
|
- ✅ **Lifecycle Management** - Automatic connection/disconnection with reference counting
|
|
11
11
|
- ✅ **Multi-Workspace Support** - Manage multiple isolated workspaces with different dependencies
|
|
@@ -15,7 +15,7 @@ A lightweight, type-safe repository manager with dependency injection, event-dri
|
|
|
15
15
|
- ✅ **Logging** - Built-in logging with colored console output
|
|
16
16
|
- ✅ **Memory Efficient** - Automatic cleanup when no connections remain
|
|
17
17
|
- ✅ **Middleware Support** - Intercept and modify repository method calls
|
|
18
|
-
- ✅ **
|
|
18
|
+
- ✅ **Signal Broadcasting** - Fire-and-forget event system for decoupled communication
|
|
19
19
|
|
|
20
20
|
## 📦 Installation
|
|
21
21
|
|
|
@@ -47,25 +47,25 @@ const dependencies = {
|
|
|
47
47
|
};
|
|
48
48
|
|
|
49
49
|
// Create workspace with repositories
|
|
50
|
-
const { queryRepository } = manager.
|
|
50
|
+
const { queryRepository } = manager.workspaceClient({
|
|
51
51
|
id: "app",
|
|
52
52
|
logging: true,
|
|
53
53
|
dependencies,
|
|
54
|
-
|
|
55
|
-
{
|
|
54
|
+
onSetup({ useRepository }) {
|
|
55
|
+
useRepository<IUserRepository>({
|
|
56
56
|
id: "user-repo",
|
|
57
57
|
install({ instance }): IUserRepository {
|
|
58
|
-
const { dependencies,
|
|
58
|
+
const { dependencies, signal } = instance;
|
|
59
59
|
return {
|
|
60
60
|
async getUsers() {
|
|
61
61
|
return dependencies.httpClient.get("/api/users");
|
|
62
62
|
},
|
|
63
63
|
async createUser(user) {
|
|
64
64
|
const result = await dependencies.httpClient.post("/api/users", user);
|
|
65
|
-
//
|
|
66
|
-
|
|
65
|
+
// Broadcast signal to other repositories
|
|
66
|
+
signal({
|
|
67
67
|
type: "user.created",
|
|
68
|
-
repositoryId: "
|
|
68
|
+
repositoryId: "notification-repo",
|
|
69
69
|
message: result,
|
|
70
70
|
});
|
|
71
71
|
return result;
|
|
@@ -78,8 +78,8 @@ const { queryRepository } = manager.createWorkspace({
|
|
|
78
78
|
onDisconnect: () => {
|
|
79
79
|
console.log("User repository cleaned up");
|
|
80
80
|
},
|
|
81
|
-
}
|
|
82
|
-
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
// Query and use repository
|
|
@@ -99,11 +99,13 @@ Repository Manager follows a hierarchical pattern:
|
|
|
99
99
|
|
|
100
100
|
```typescript
|
|
101
101
|
const manager = repositoryManager(); // Global manager
|
|
102
|
-
const workspace = manager.
|
|
102
|
+
const workspace = manager.workspaceClient({ // Workspace instance
|
|
103
103
|
id: "app",
|
|
104
104
|
dependencies,
|
|
105
105
|
logging: true,
|
|
106
|
-
|
|
106
|
+
onSetup({ useRepository }) { // Define repositories
|
|
107
|
+
useRepository({...});
|
|
108
|
+
}
|
|
107
109
|
});
|
|
108
110
|
workspace.queryRepository("repo-id"); // Query repositories
|
|
109
111
|
```
|
|
@@ -113,72 +115,70 @@ workspace.queryRepository("repo-id"); // Query repositories
|
|
|
113
115
|
Workspace is the **entry point** for all operations. It encapsulates:
|
|
114
116
|
|
|
115
117
|
- Dependencies (shared services/infrastructure)
|
|
116
|
-
- Repository definitions
|
|
117
|
-
-
|
|
118
|
+
- Repository definitions via `onSetup`
|
|
119
|
+
- Signal broadcasting for events
|
|
118
120
|
- Logging configuration
|
|
119
121
|
|
|
120
122
|
```typescript
|
|
121
|
-
const { queryRepository } = manager.
|
|
123
|
+
const { queryRepository } = manager.workspaceClient({
|
|
122
124
|
id: "app-workspace",
|
|
123
125
|
logging: true,
|
|
124
126
|
dependencies: {
|
|
125
127
|
httpClient: myHttpClient,
|
|
126
128
|
cache: myCache,
|
|
127
129
|
},
|
|
128
|
-
|
|
129
|
-
//
|
|
130
|
-
|
|
130
|
+
onSetup({ useRepository }) {
|
|
131
|
+
// Register repositories here
|
|
132
|
+
useRepository({...});
|
|
133
|
+
},
|
|
131
134
|
});
|
|
132
135
|
```
|
|
133
136
|
|
|
134
|
-
### 3.
|
|
137
|
+
### 3. Signal Broadcasting System
|
|
135
138
|
|
|
136
|
-
The built-in
|
|
139
|
+
The built-in signal broadcaster enables **fire-and-forget inter-repository communication**:
|
|
137
140
|
|
|
138
141
|
```typescript
|
|
139
|
-
const { queryRepository } = manager.
|
|
142
|
+
const { queryRepository } = manager.workspaceClient({
|
|
140
143
|
id: "app",
|
|
141
144
|
dependencies,
|
|
142
|
-
|
|
143
|
-
// Repository that
|
|
144
|
-
{
|
|
145
|
+
onSetup({ useRepository }) {
|
|
146
|
+
// Repository that broadcasts signals
|
|
147
|
+
useRepository({
|
|
145
148
|
id: "user-repo",
|
|
146
149
|
install({ instance }) {
|
|
147
|
-
const {
|
|
150
|
+
const { signal } = instance;
|
|
148
151
|
return {
|
|
149
152
|
async createUser(user) {
|
|
150
153
|
const result = await saveUser(user);
|
|
151
|
-
//
|
|
152
|
-
|
|
154
|
+
// Broadcast signal to other repositories
|
|
155
|
+
signal({
|
|
153
156
|
type: "user.created",
|
|
154
|
-
repositoryId: "
|
|
157
|
+
repositoryId: "notification-repo",
|
|
155
158
|
message: result,
|
|
156
159
|
});
|
|
157
160
|
return result;
|
|
158
161
|
},
|
|
159
162
|
};
|
|
160
163
|
},
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
// Repository that listens to signals
|
|
167
|
+
useRepository({
|
|
164
168
|
id: "notification-repo",
|
|
169
|
+
onSignal(event, repo) {
|
|
170
|
+
if (event.type === "user.created") {
|
|
171
|
+
console.log("New user:", event.message);
|
|
172
|
+
// Send welcome email, etc.
|
|
173
|
+
}
|
|
174
|
+
},
|
|
165
175
|
install({ instance }) {
|
|
166
|
-
const { messenger } = instance;
|
|
167
|
-
|
|
168
|
-
// Subscribe to user events
|
|
169
|
-
messenger.subscribe((payload) => {
|
|
170
|
-
if (payload.type === "user.created") {
|
|
171
|
-
console.log("New user:", payload.message);
|
|
172
|
-
// Send welcome email, etc.
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
176
|
return {
|
|
177
177
|
// repository methods...
|
|
178
178
|
};
|
|
179
179
|
},
|
|
180
|
-
}
|
|
181
|
-
|
|
180
|
+
});
|
|
181
|
+
},
|
|
182
182
|
});
|
|
183
183
|
```
|
|
184
184
|
|
|
@@ -196,16 +196,16 @@ Creates a repository manager instance.
|
|
|
196
196
|
const manager = repositoryManager();
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
-
### `manager.
|
|
199
|
+
### `manager.workspaceClient<D>(config)`
|
|
200
200
|
|
|
201
|
-
Creates a workspace with dependencies and
|
|
201
|
+
Creates a workspace client with dependencies and repositories.
|
|
202
202
|
|
|
203
203
|
**Parameters:**
|
|
204
204
|
|
|
205
205
|
- `config: IWorkspaceConfig<D>`
|
|
206
206
|
- `id: string` - Unique identifier for the workspace
|
|
207
207
|
- `dependencies: D` - Dependencies to inject into repositories
|
|
208
|
-
- `
|
|
208
|
+
- `onSetup: ({ useRepository }) => void` - Setup function to register repositories
|
|
209
209
|
- `logging?: boolean` - Enable/disable logging (default: `false`)
|
|
210
210
|
|
|
211
211
|
**Returns:** Object with workspace methods:
|
|
@@ -215,20 +215,20 @@ Creates a workspace with dependencies and plugins.
|
|
|
215
215
|
**Example:**
|
|
216
216
|
|
|
217
217
|
```typescript
|
|
218
|
-
const { queryRepository } = manager.
|
|
218
|
+
const { queryRepository } = manager.workspaceClient({
|
|
219
219
|
id: "app",
|
|
220
220
|
dependencies: {
|
|
221
221
|
httpClient: myHttpClient,
|
|
222
222
|
database: myDb,
|
|
223
223
|
},
|
|
224
|
-
|
|
225
|
-
{
|
|
224
|
+
onSetup({ useRepository }) {
|
|
225
|
+
useRepository({
|
|
226
226
|
id: "user-repo",
|
|
227
227
|
install({ instance }) {
|
|
228
228
|
// repository implementation
|
|
229
229
|
},
|
|
230
|
-
}
|
|
231
|
-
|
|
230
|
+
});
|
|
231
|
+
},
|
|
232
232
|
logging: true,
|
|
233
233
|
});
|
|
234
234
|
```
|
|
@@ -243,7 +243,8 @@ Defines a repository within the workspace.
|
|
|
243
243
|
- `id: string` - Unique identifier for the repository
|
|
244
244
|
- `install: ({ instance }) => R` - Factory function that returns repository instance
|
|
245
245
|
- `instance.dependencies` - Injected dependencies
|
|
246
|
-
- `instance.
|
|
246
|
+
- `instance.signal` - Function to broadcast signals to other repositories
|
|
247
|
+
- `onSignal?: (event, repo) => void` - Called when a signal is received
|
|
247
248
|
- `onConnect?: () => void` - Called when repository is first connected
|
|
248
249
|
- `onDisconnect?: () => void` - Called when repository is last disconnected
|
|
249
250
|
- `middlewares?: Middleware[]` - Array of middleware functions
|
|
@@ -251,34 +252,32 @@ Defines a repository within the workspace.
|
|
|
251
252
|
**Example:**
|
|
252
253
|
|
|
253
254
|
```typescript
|
|
254
|
-
|
|
255
|
-
{
|
|
255
|
+
onSetup({ useRepository }) {
|
|
256
|
+
useRepository<IUserRepository>({
|
|
256
257
|
id: "user-repo",
|
|
257
258
|
install({ instance }): IUserRepository {
|
|
258
|
-
const { dependencies,
|
|
259
|
-
|
|
260
|
-
// Subscribe to events
|
|
261
|
-
messenger.subscribe((payload) => {
|
|
262
|
-
console.log("Event received:", payload);
|
|
263
|
-
});
|
|
259
|
+
const { dependencies, signal } = instance;
|
|
264
260
|
|
|
265
261
|
return {
|
|
266
262
|
async createUser(user) {
|
|
267
263
|
const result = await dependencies.httpClient.post("/users", user);
|
|
268
|
-
//
|
|
269
|
-
|
|
264
|
+
// Broadcast signal
|
|
265
|
+
signal({
|
|
270
266
|
type: "user.created",
|
|
271
|
-
repositoryId: "
|
|
267
|
+
repositoryId: "notification-repo",
|
|
272
268
|
message: result,
|
|
273
269
|
});
|
|
274
270
|
return result;
|
|
275
271
|
},
|
|
276
272
|
};
|
|
277
273
|
},
|
|
274
|
+
onSignal(event, repo) {
|
|
275
|
+
console.log("Signal received:", event);
|
|
276
|
+
},
|
|
278
277
|
onConnect: () => console.log("Connected"),
|
|
279
278
|
onDisconnect: () => console.log("Disconnected"),
|
|
280
|
-
}
|
|
281
|
-
|
|
279
|
+
});
|
|
280
|
+
}
|
|
282
281
|
```
|
|
283
282
|
|
|
284
283
|
### `queryRepository<R>(id)`
|
|
@@ -305,54 +304,57 @@ await repository.getUsers();
|
|
|
305
304
|
disconnect();
|
|
306
305
|
```
|
|
307
306
|
|
|
308
|
-
### `
|
|
307
|
+
### `signal<P>(payload)`
|
|
309
308
|
|
|
310
|
-
|
|
309
|
+
Broadcast a signal to notify a target repository (fire-and-forget).
|
|
311
310
|
|
|
312
311
|
**Parameters:**
|
|
313
312
|
|
|
314
|
-
- `payload:
|
|
315
|
-
- `type: string` -
|
|
313
|
+
- `payload: ISignalPayload<P>`
|
|
314
|
+
- `type: string` - Signal type identifier
|
|
316
315
|
- `repositoryId: string` - Target repository identifier
|
|
317
316
|
- `message?: P` - Optional payload data
|
|
318
317
|
|
|
319
318
|
**Example:**
|
|
320
319
|
|
|
321
320
|
```typescript
|
|
322
|
-
|
|
321
|
+
signal({
|
|
323
322
|
type: "user.created",
|
|
324
323
|
repositoryId: "notification-repo",
|
|
325
324
|
message: { userId: "123", email: "user@example.com" },
|
|
326
325
|
});
|
|
327
326
|
```
|
|
328
327
|
|
|
329
|
-
### `
|
|
328
|
+
### `onSignal<P>(event, repo)`
|
|
330
329
|
|
|
331
|
-
|
|
330
|
+
Handle incoming signals from other repositories.
|
|
332
331
|
|
|
333
332
|
**Parameters:**
|
|
334
333
|
|
|
335
|
-
- `
|
|
336
|
-
- `
|
|
337
|
-
- `
|
|
338
|
-
- `
|
|
334
|
+
- `event: ISignalSubscribePayload<P>` - Signal payload
|
|
335
|
+
- `type: string` - Signal type
|
|
336
|
+
- `source: string` - Source repository
|
|
337
|
+
- `message: P` - Signal data
|
|
338
|
+
- `repo: R` - Repository instance with all methods
|
|
339
339
|
|
|
340
340
|
**Example:**
|
|
341
341
|
|
|
342
342
|
```typescript
|
|
343
|
-
|
|
344
|
-
if (
|
|
345
|
-
console.log("User created:",
|
|
346
|
-
console.log("From repository:",
|
|
343
|
+
onSignal(event, repo) {
|
|
344
|
+
if (event.type === "user.created") {
|
|
345
|
+
console.log("User created:", event.message);
|
|
346
|
+
console.log("From repository:", event.source);
|
|
347
|
+
// Call repository methods
|
|
348
|
+
repo.sendEmail(event.message.email);
|
|
347
349
|
}
|
|
348
|
-
}
|
|
350
|
+
}
|
|
349
351
|
```
|
|
350
352
|
|
|
351
353
|
## 🎯 Advanced Usage
|
|
352
354
|
|
|
353
|
-
###
|
|
355
|
+
### Signal Broadcasting Benefits
|
|
354
356
|
|
|
355
|
-
The built-in
|
|
357
|
+
The built-in signal broadcasting system enables decoupled communication between repositories:
|
|
356
358
|
|
|
357
359
|
**Benefits:**
|
|
358
360
|
|
|
@@ -372,25 +374,25 @@ The built-in messenger system enables decoupled communication between repositori
|
|
|
372
374
|
|
|
373
375
|
### Event-Driven Communication
|
|
374
376
|
|
|
375
|
-
Repositories can communicate through the
|
|
377
|
+
Repositories can communicate through the signal broadcasting system:
|
|
376
378
|
|
|
377
379
|
```typescript
|
|
378
|
-
const { queryRepository } = manager.
|
|
380
|
+
const { queryRepository } = manager.workspaceClient({
|
|
379
381
|
id: "app",
|
|
380
382
|
dependencies: {
|
|
381
383
|
httpClient: myHttpClient,
|
|
382
384
|
emailService: myEmailService,
|
|
383
385
|
},
|
|
384
|
-
|
|
385
|
-
// User repository
|
|
386
|
-
{
|
|
386
|
+
onSetup({ useRepository }) {
|
|
387
|
+
// User repository broadcasts signals
|
|
388
|
+
useRepository({
|
|
387
389
|
id: "user-repo",
|
|
388
390
|
install({ instance }) {
|
|
389
|
-
const { dependencies,
|
|
391
|
+
const { dependencies, signal } = instance;
|
|
390
392
|
return {
|
|
391
393
|
async createUser(user) {
|
|
392
394
|
const result = await dependencies.httpClient.post("/users", user);
|
|
393
|
-
|
|
395
|
+
signal({
|
|
394
396
|
type: "user.created",
|
|
395
397
|
repositoryId: "notification-repo",
|
|
396
398
|
message: result,
|
|
@@ -399,7 +401,7 @@ const { queryRepository } = manager.createWorkspace({
|
|
|
399
401
|
},
|
|
400
402
|
async deleteUser(userId) {
|
|
401
403
|
await dependencies.httpClient.delete(`/users/${userId}`);
|
|
402
|
-
|
|
404
|
+
signal({
|
|
403
405
|
type: "user.deleted",
|
|
404
406
|
repositoryId: "notification-repo",
|
|
405
407
|
message: { userId },
|
|
@@ -407,48 +409,47 @@ const { queryRepository } = manager.createWorkspace({
|
|
|
407
409
|
},
|
|
408
410
|
};
|
|
409
411
|
},
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
// Notification repository listens to signals
|
|
415
|
+
useRepository({
|
|
413
416
|
id: "notification-repo",
|
|
417
|
+
onSignal(event, repo) {
|
|
418
|
+
if (event.type === "user.created") {
|
|
419
|
+
repo.sendWelcomeEmail(event.message.email);
|
|
420
|
+
}
|
|
421
|
+
if (event.type === "user.deleted") {
|
|
422
|
+
console.log("User deleted:", event.message.userId);
|
|
423
|
+
}
|
|
424
|
+
},
|
|
414
425
|
install({ instance }) {
|
|
415
|
-
const {
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
if (payload.type === "user.created") {
|
|
426
|
+
const { dependencies } = instance;
|
|
427
|
+
return {
|
|
428
|
+
sendWelcomeEmail(email) {
|
|
419
429
|
dependencies.emailService.send({
|
|
420
|
-
to:
|
|
430
|
+
to: email,
|
|
421
431
|
subject: "Welcome!",
|
|
422
432
|
});
|
|
423
|
-
}
|
|
424
|
-
if (payload.type === "user.deleted") {
|
|
425
|
-
console.log("User deleted:", payload.message.userId);
|
|
426
|
-
}
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
return {
|
|
430
|
-
// notification methods...
|
|
433
|
+
},
|
|
431
434
|
};
|
|
432
435
|
},
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// Analytics repository also listens to signals
|
|
439
|
+
useRepository({
|
|
436
440
|
id: "analytics-repo",
|
|
441
|
+
onSignal(event, repo) {
|
|
442
|
+
if (event.type === "user.created") {
|
|
443
|
+
console.log("Track new user:", event.message);
|
|
444
|
+
}
|
|
445
|
+
},
|
|
437
446
|
install({ instance }) {
|
|
438
|
-
const { messenger } = instance;
|
|
439
|
-
|
|
440
|
-
messenger.subscribe((payload) => {
|
|
441
|
-
if (payload.type === "user.created") {
|
|
442
|
-
console.log("Track new user:", payload.message);
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
|
|
446
447
|
return {
|
|
447
448
|
// analytics methods...
|
|
448
449
|
};
|
|
449
450
|
},
|
|
450
|
-
}
|
|
451
|
-
|
|
451
|
+
});
|
|
452
|
+
},
|
|
452
453
|
});
|
|
453
454
|
```
|
|
454
455
|
|
|
@@ -458,80 +459,32 @@ Create multiple isolated workspaces with different dependencies:
|
|
|
458
459
|
|
|
459
460
|
```typescript
|
|
460
461
|
// API workspace
|
|
461
|
-
const apiWorkspace = manager.
|
|
462
|
+
const apiWorkspace = manager.workspaceClient({
|
|
462
463
|
id: "api",
|
|
463
464
|
dependencies: {
|
|
464
465
|
httpClient: apiClient,
|
|
465
466
|
cache: redisCache,
|
|
466
467
|
},
|
|
467
|
-
|
|
468
|
+
onSetup({ useRepository }) {
|
|
468
469
|
// API repositories
|
|
469
|
-
|
|
470
|
+
},
|
|
470
471
|
logging: true,
|
|
471
472
|
});
|
|
472
473
|
|
|
473
474
|
// Database workspace
|
|
474
|
-
const dbWorkspace = manager.
|
|
475
|
+
const dbWorkspace = manager.workspaceClient({
|
|
475
476
|
id: "database",
|
|
476
477
|
dependencies: {
|
|
477
478
|
db: postgresClient,
|
|
478
479
|
logger: winstonLogger,
|
|
479
480
|
},
|
|
480
|
-
|
|
481
|
+
onSetup({ useRepository }) {
|
|
481
482
|
// Database repositories
|
|
482
|
-
|
|
483
|
+
},
|
|
483
484
|
logging: false,
|
|
484
485
|
});
|
|
485
486
|
|
|
486
|
-
// Each workspace has isolated repositories and
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
### TypeScript Best Practices
|
|
490
|
-
|
|
491
|
-
Define clear interfaces for type safety:
|
|
492
|
-
|
|
493
|
-
```typescript
|
|
494
|
-
// Dependencies interface
|
|
495
|
-
interface IDependencies {
|
|
496
|
-
httpClient: IHttpClient;
|
|
497
|
-
cache: ICache;
|
|
498
|
-
logger: ILogger;
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
// Repository interface
|
|
502
|
-
interface IUserRepository {
|
|
503
|
-
getUsers(): Promise<User[]>;
|
|
504
|
-
createUser(user: User): Promise<User>;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// Workspace with typed dependencies
|
|
508
|
-
const { queryRepository } = manager.createWorkspace<IDependencies>({
|
|
509
|
-
id: "app",
|
|
510
|
-
dependencies,
|
|
511
|
-
repositories: () => [
|
|
512
|
-
{
|
|
513
|
-
id: "user-repo",
|
|
514
|
-
install({ instance }): IUserRepository {
|
|
515
|
-
const { dependencies } = instance;
|
|
516
|
-
return {
|
|
517
|
-
async getUsers() {
|
|
518
|
-
// TypeScript knows dependencies type
|
|
519
|
-
return dependencies.httpClient.get("/users");
|
|
520
|
-
},
|
|
521
|
-
async createUser(user) {
|
|
522
|
-
// TypeScript validates User type
|
|
523
|
-
return dependencies.httpClient.post("/users", user);
|
|
524
|
-
},
|
|
525
|
-
};
|
|
526
|
-
},
|
|
527
|
-
},
|
|
528
|
-
],
|
|
529
|
-
logging: true,
|
|
530
|
-
});
|
|
531
|
-
|
|
532
|
-
// Query with typed repository
|
|
533
|
-
const { repository } = queryRepository<IUserRepository>("user-repo");
|
|
534
|
-
// TypeScript knows all repository methods
|
|
487
|
+
// Each workspace has isolated repositories and signal broadcasters
|
|
535
488
|
```
|
|
536
489
|
|
|
537
490
|
### Lifecycle Management
|
|
@@ -575,10 +528,10 @@ const cacheMiddleware: Middleware = (method, args, next) => {
|
|
|
575
528
|
return result;
|
|
576
529
|
};
|
|
577
530
|
|
|
578
|
-
const { queryRepository } = manager.
|
|
531
|
+
const { queryRepository } = manager.workspaceClient({
|
|
579
532
|
dependencies,
|
|
580
|
-
|
|
581
|
-
{
|
|
533
|
+
onSetup({ useRepository }) {
|
|
534
|
+
useRepository({
|
|
582
535
|
id: "user-repo",
|
|
583
536
|
install({ instance }) {
|
|
584
537
|
return {
|
|
@@ -586,8 +539,8 @@ const { queryRepository } = manager.createWorkspace({
|
|
|
586
539
|
};
|
|
587
540
|
},
|
|
588
541
|
middlewares: [loggingMiddleware, cacheMiddleware],
|
|
589
|
-
}
|
|
590
|
-
|
|
542
|
+
});
|
|
543
|
+
},
|
|
591
544
|
});
|
|
592
545
|
```
|
|
593
546
|
|
|
@@ -605,24 +558,12 @@ const { queryRepository } = manager.createWorkspace({
|
|
|
605
558
|
Enable logging to see connection lifecycle and events:
|
|
606
559
|
|
|
607
560
|
```typescript
|
|
608
|
-
const { queryRepository } = manager.
|
|
561
|
+
const { queryRepository } = manager.workspaceClient({
|
|
609
562
|
id: "app",
|
|
610
563
|
dependencies,
|
|
611
|
-
|
|
564
|
+
onSetup({ useRepository }) {
|
|
612
565
|
// repositories here
|
|
613
|
-
|
|
566
|
+
},
|
|
614
567
|
logging: true, // Enables colored console output
|
|
615
568
|
});
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
## 🏗️ Design Patterns
|
|
619
|
-
|
|
620
|
-
This library implements several design patterns:
|
|
621
|
-
|
|
622
|
-
- **Dependency Injection** - Dependencies are injected into repositories
|
|
623
|
-
- **Factory Pattern** - Repositories are created using factory functions
|
|
624
|
-
- **Singleton Pattern** - Each repository is a singleton per workspace (with reference counting)
|
|
625
|
-
- **Repository Pattern** - Abstracts data access logic
|
|
626
|
-
- **Messenger Pattern** - Fire-and-forget communication between repositories
|
|
627
|
-
- **Workspace Pattern** - Clean API for managing dependencies and lifecycle
|
|
628
|
-
- **Pub/Sub Pattern** - Repositories can publish and subscribe to events
|
|
569
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { scopedObserverType } from "../infrastructure";
|
|
2
|
+
import type { ISignalBroadcaster, IRepositoryConfig } from "../types";
|
|
3
|
+
declare function createSignalBroadcaster(config: {
|
|
4
|
+
observer: scopedObserverType;
|
|
5
|
+
repositoryConfig: IRepositoryConfig;
|
|
6
|
+
}): ISignalBroadcaster;
|
|
7
|
+
export { createSignalBroadcaster };
|
|
8
|
+
//# sourceMappingURL=createSignalBroadcaster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createSignalBroadcaster.d.ts","sourceRoot":"","sources":["../../src/core/createSignalBroadcaster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEtE,iBAAS,uBAAuB,CAAE,MAAM,EAAE;IACtC,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,gBAAgB,EAAE,iBAAiB,CAAC;CACvC,GAAG,kBAAkB,CAkCnB;AAEH,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
function
|
|
2
|
-
const { observer,
|
|
1
|
+
function createSignalBroadcaster(config) {
|
|
2
|
+
const { observer, repositoryConfig } = config;
|
|
3
3
|
return {
|
|
4
|
-
|
|
4
|
+
signal({ repositoryId, type, message }) {
|
|
5
5
|
if (repositoryId === repositoryConfig.id) {
|
|
6
6
|
console.warn("WARNING: DISPATCHING TO SELF");
|
|
7
7
|
return;
|
|
@@ -17,10 +17,6 @@ function createMessenger(config) {
|
|
|
17
17
|
});
|
|
18
18
|
},
|
|
19
19
|
subscribe(handler) {
|
|
20
|
-
if (subscriptions.length > 0) {
|
|
21
|
-
console.warn("WARNING: SUBSCRIBED ALREADY");
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
20
|
const unsubscribe = observer.subscribe({
|
|
25
21
|
scope: repositoryConfig.id,
|
|
26
22
|
eventName: "dispatch",
|
|
@@ -33,8 +29,8 @@ function createMessenger(config) {
|
|
|
33
29
|
});
|
|
34
30
|
},
|
|
35
31
|
});
|
|
36
|
-
|
|
32
|
+
return unsubscribe;
|
|
37
33
|
},
|
|
38
34
|
};
|
|
39
35
|
}
|
|
40
|
-
export {
|
|
36
|
+
export { createSignalBroadcaster };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import type { IRepositoryConfig } from "../types";
|
|
2
|
+
declare function createRepository<D>(repositoryConfig: IRepositoryConfig<D, any>): {
|
|
3
|
+
readonly repository: unknown;
|
|
4
|
+
readonly connections: number;
|
|
5
|
+
connect(): void;
|
|
6
|
+
disconnect(): void;
|
|
7
|
+
};
|
|
8
|
+
export { createRepository };
|
|
2
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAMlD,iBAAS,gBAAgB,CAAC,CAAC,EACzB,gBAAgB,EAAE,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC;;;;;EAuD5C;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|