@med1802/repository-manager 3.0.2 → 3.1.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 +214 -247
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/{workspace/modules → core}/index.js +1 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/repository.d.ts +10 -0
- package/dist/core/repository.d.ts.map +1 -0
- package/dist/core/repository.js +83 -0
- package/dist/{workspace/modules/repository → core}/types.d.ts +2 -2
- package/dist/core/types.d.ts.map +1 -0
- package/dist/{workspace/infrastructure → infrastructure}/index.d.ts +1 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/{workspace/infrastructure → infrastructure}/index.js +1 -0
- package/dist/{workspace/infrastructure → infrastructure}/logger.d.ts +2 -2
- package/dist/infrastructure/logger.d.ts.map +1 -0
- package/dist/infrastructure/observer/EventScope.d.ts +14 -0
- package/dist/infrastructure/observer/EventScope.d.ts.map +1 -0
- package/dist/infrastructure/observer/EventScope.js +38 -0
- package/dist/infrastructure/observer/index.d.ts +16 -0
- package/dist/infrastructure/observer/index.d.ts.map +1 -0
- package/dist/infrastructure/observer/index.js +52 -0
- package/dist/infrastructure/observer/types.d.ts +18 -0
- package/dist/infrastructure/observer/types.d.ts.map +1 -0
- package/dist/infrastructure/observer/types.js +1 -0
- package/dist/infrastructure/scope/index.d.ts.map +1 -0
- package/dist/infrastructure/scope/scope.d.ts.map +1 -0
- package/dist/{workspace/infrastructure → infrastructure}/scope/scope.js +3 -8
- package/dist/infrastructure/scope/types.d.ts +4 -0
- package/dist/infrastructure/scope/types.d.ts.map +1 -0
- package/dist/infrastructure/store.d.ts.map +1 -0
- package/dist/manager.d.ts +3 -5
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +8 -11
- package/dist/workspace/{modules/repository/createRepositoryModule.d.ts → client.d.ts} +5 -5
- package/dist/workspace/client.d.ts.map +1 -0
- package/dist/workspace/{modules/repository/createRepositoryModule.js → client.js} +7 -8
- package/dist/workspace/context.d.ts +13 -0
- package/dist/workspace/context.d.ts.map +1 -0
- package/dist/workspace/context.js +32 -0
- package/dist/workspace/index.d.ts +2 -12
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +2 -30
- package/dist/workspace/types/configuration.types.d.ts +6 -0
- package/dist/workspace/types/configuration.types.d.ts.map +1 -0
- package/dist/workspace/types/index.d.ts +3 -0
- package/dist/workspace/types/index.d.ts.map +1 -0
- package/dist/workspace/types/index.js +2 -0
- package/dist/workspace/types/observer.types.d.ts +15 -0
- package/dist/workspace/types/observer.types.d.ts.map +1 -0
- package/dist/workspace/types/observer.types.js +1 -0
- package/package.json +1 -1
- package/src/{workspace/modules → core}/index.ts +1 -0
- package/src/core/repository.ts +90 -0
- package/src/{workspace/modules/repository → core}/types.ts +2 -2
- package/src/{workspace/infrastructure → infrastructure}/index.ts +1 -0
- package/src/{workspace/infrastructure → infrastructure}/logger.ts +2 -2
- package/src/infrastructure/observer/EventScope.ts +51 -0
- package/src/infrastructure/observer/index.ts +91 -0
- package/src/infrastructure/observer/types.ts +23 -0
- package/src/{workspace/infrastructure → infrastructure}/scope/scope.ts +4 -9
- package/src/infrastructure/scope/types.ts +3 -0
- package/src/manager.ts +8 -15
- package/src/workspace/{modules/repository/createRepositoryModule.ts → client.ts} +11 -9
- package/src/workspace/context.ts +58 -0
- package/src/workspace/index.ts +2 -38
- package/src/workspace/types/configuration.types.ts +5 -0
- package/src/workspace/types/index.ts +2 -0
- package/src/workspace/types/observer.types.ts +18 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/workspace/infrastructure/index.d.ts.map +0 -1
- package/dist/workspace/infrastructure/logger.d.ts.map +0 -1
- package/dist/workspace/infrastructure/scope/index.d.ts.map +0 -1
- package/dist/workspace/infrastructure/scope/scope.d.ts.map +0 -1
- package/dist/workspace/infrastructure/scope/types.d.ts +0 -8
- package/dist/workspace/infrastructure/scope/types.d.ts.map +0 -1
- package/dist/workspace/infrastructure/store.d.ts.map +0 -1
- package/dist/workspace/modules/index.d.ts +0 -2
- package/dist/workspace/modules/index.d.ts.map +0 -1
- package/dist/workspace/modules/repository/createRepositoryModule.d.ts.map +0 -1
- package/dist/workspace/modules/repository/index.d.ts +0 -3
- package/dist/workspace/modules/repository/index.d.ts.map +0 -1
- package/dist/workspace/modules/repository/index.js +0 -2
- package/dist/workspace/modules/repository/middleware.d.ts.map +0 -1
- package/dist/workspace/modules/repository/repositoryAccessor.d.ts +0 -9
- package/dist/workspace/modules/repository/repositoryAccessor.d.ts.map +0 -1
- package/dist/workspace/modules/repository/repositoryAccessor.js +0 -42
- package/dist/workspace/modules/repository/types.d.ts.map +0 -1
- package/dist/workspace/providers/index.d.ts +0 -5
- package/dist/workspace/providers/index.d.ts.map +0 -1
- package/dist/workspace/providers/index.js +0 -3
- package/dist/workspace/types.d.ts +0 -5
- package/dist/workspace/types.d.ts.map +0 -1
- package/src/workspace/infrastructure/scope/types.ts +0 -8
- package/src/workspace/modules/repository/index.ts +0 -2
- package/src/workspace/modules/repository/repositoryAccessor.ts +0 -48
- package/src/workspace/providers/index.ts +0 -5
- package/src/workspace/types.ts +0 -4
- /package/dist/{workspace/modules/repository → core}/middleware.d.ts +0 -0
- /package/dist/{workspace/modules/repository → core}/middleware.js +0 -0
- /package/dist/{workspace/infrastructure/scope → core}/types.js +0 -0
- /package/dist/{workspace/infrastructure → infrastructure}/logger.js +0 -0
- /package/dist/{workspace/infrastructure → infrastructure}/scope/index.d.ts +0 -0
- /package/dist/{workspace/infrastructure → infrastructure}/scope/index.js +0 -0
- /package/dist/{workspace/infrastructure → infrastructure}/scope/scope.d.ts +0 -0
- /package/dist/{workspace/modules/repository → infrastructure/scope}/types.js +0 -0
- /package/dist/{workspace/infrastructure → infrastructure}/store.d.ts +0 -0
- /package/dist/{workspace/infrastructure → infrastructure}/store.js +0 -0
- /package/dist/workspace/{types.js → types/configuration.types.js} +0 -0
- /package/src/{workspace/modules/repository → core}/middleware.ts +0 -0
- /package/src/{workspace/infrastructure → infrastructure}/scope/index.ts +0 -0
- /package/src/{workspace/infrastructure → infrastructure}/store.ts +0 -0
package/README.md
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
# 🔄 Repository Manager
|
|
2
2
|
|
|
3
|
-
A lightweight, type-safe repository manager with dependency injection,
|
|
3
|
+
A lightweight, type-safe repository manager with dependency injection, event-driven architecture, lifecycle management, and multi-workspace support for TypeScript/JavaScript applications.
|
|
4
4
|
|
|
5
5
|
## ✨ Features
|
|
6
6
|
|
|
7
7
|
- ✅ **Dependency Injection** - Inject infrastructure dependencies into repositories
|
|
8
|
-
- ✅ **
|
|
8
|
+
- ✅ **Event-Driven Architecture** - Built-in observer pattern for inter-repository communication
|
|
9
9
|
- ✅ **Lifecycle Management** - Automatic connection/disconnection with reference counting
|
|
10
10
|
- ✅ **Multi-Workspace Support** - Manage multiple isolated workspaces with different dependencies
|
|
11
11
|
- ✅ **Type Safety** - Full TypeScript support with generics
|
|
12
12
|
- ✅ **Lazy Initialization** - Repository instances are created only when needed
|
|
13
|
-
- ✅ **Workspace Pattern** -
|
|
13
|
+
- ✅ **Workspace Pattern** - Clean API with `createWorkspace`
|
|
14
14
|
- ✅ **Logging** - Built-in logging with colored console output
|
|
15
15
|
- ✅ **Memory Efficient** - Automatic cleanup when no connections remain
|
|
16
16
|
- ✅ **Middleware Support** - Intercept and modify repository method calls
|
|
17
|
+
- ✅ **Scoped Observer** - Hierarchical event system for organized communication
|
|
17
18
|
|
|
18
19
|
## 📦 Installation
|
|
19
20
|
|
|
@@ -45,25 +46,30 @@ const infrastructure = {
|
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
// Create workspace (entry point for all operations)
|
|
48
|
-
const { defineRepository, queryRepository
|
|
49
|
+
const { defineRepository, queryRepository } = manager.createWorkspace({
|
|
50
|
+
id: "app",
|
|
51
|
+
logging: true,
|
|
49
52
|
infrastructure,
|
|
50
|
-
|
|
51
|
-
id: "app",
|
|
52
|
-
logging: true,
|
|
53
|
-
}
|
|
54
|
-
);
|
|
53
|
+
});
|
|
55
54
|
|
|
56
55
|
// Define repository
|
|
57
56
|
defineRepository<IUserRepository>({
|
|
58
57
|
id: "user-repo",
|
|
59
58
|
install({ instance }) {
|
|
60
|
-
const { infrastructure } = instance;
|
|
59
|
+
const { infrastructure, observer } = instance;
|
|
61
60
|
return {
|
|
62
61
|
async getUsers() {
|
|
63
62
|
return infrastructure.httpClient.get("/api/users");
|
|
64
63
|
},
|
|
65
64
|
async createUser(user) {
|
|
66
|
-
|
|
65
|
+
const result = await infrastructure.httpClient.post("/api/users", user);
|
|
66
|
+
// Notify other repositories about new user
|
|
67
|
+
observer.dispatch({
|
|
68
|
+
type: "user.created",
|
|
69
|
+
repositoryId: "user-repo",
|
|
70
|
+
message: result,
|
|
71
|
+
});
|
|
72
|
+
return result;
|
|
67
73
|
},
|
|
68
74
|
};
|
|
69
75
|
},
|
|
@@ -88,13 +94,17 @@ disconnect();
|
|
|
88
94
|
|
|
89
95
|
### 1. Manager → Workspace → Repository
|
|
90
96
|
|
|
91
|
-
Repository Manager follows a hierarchical pattern
|
|
97
|
+
Repository Manager follows a hierarchical pattern:
|
|
92
98
|
|
|
93
99
|
```typescript
|
|
94
|
-
const manager = repositoryManager();
|
|
95
|
-
const workspace = manager.
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
const manager = repositoryManager(); // Global manager
|
|
101
|
+
const workspace = manager.createWorkspace({ // Workspace instance
|
|
102
|
+
id: "app",
|
|
103
|
+
infrastructure,
|
|
104
|
+
logging: true
|
|
105
|
+
});
|
|
106
|
+
workspace.defineRepository({...}); // Define repositories
|
|
107
|
+
workspace.queryRepository("repo-id"); // Query repositories
|
|
98
108
|
```
|
|
99
109
|
|
|
100
110
|
### 2. Workspace Pattern
|
|
@@ -103,53 +113,62 @@ Workspace is the **entry point** for all operations. It encapsulates:
|
|
|
103
113
|
|
|
104
114
|
- Infrastructure dependencies
|
|
105
115
|
- Repository definitions
|
|
106
|
-
-
|
|
116
|
+
- Observer system for events
|
|
107
117
|
- Logging configuration
|
|
108
118
|
|
|
109
119
|
```typescript
|
|
110
|
-
const { defineRepository, queryRepository
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
const { defineRepository, queryRepository } = manager.createWorkspace({
|
|
121
|
+
id: "app-workspace",
|
|
122
|
+
logging: true,
|
|
123
|
+
infrastructure: {
|
|
124
|
+
httpClient: myHttpClient,
|
|
125
|
+
cache: myCache,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
117
128
|
```
|
|
118
129
|
|
|
119
|
-
### 3.
|
|
130
|
+
### 3. Observer System
|
|
120
131
|
|
|
121
|
-
|
|
132
|
+
The built-in observer enables **event-driven inter-repository communication**:
|
|
122
133
|
|
|
123
134
|
```typescript
|
|
124
|
-
//
|
|
125
|
-
const userScope = createScope({
|
|
126
|
-
userId: null,
|
|
127
|
-
permissions: [],
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Use in repository
|
|
135
|
+
// Define repository that dispatches events
|
|
131
136
|
defineRepository({
|
|
132
|
-
id: "
|
|
137
|
+
id: "user-repo",
|
|
133
138
|
install({ instance }) {
|
|
134
|
-
const {
|
|
139
|
+
const { observer } = instance;
|
|
135
140
|
return {
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
141
|
+
async createUser(user) {
|
|
142
|
+
const result = await saveUser(user);
|
|
143
|
+
// Notify other repositories
|
|
144
|
+
observer.dispatch({
|
|
145
|
+
type: "user.created",
|
|
146
|
+
repositoryId: "user-repo",
|
|
147
|
+
message: result,
|
|
148
|
+
});
|
|
149
|
+
return result;
|
|
139
150
|
},
|
|
140
151
|
};
|
|
141
152
|
},
|
|
142
153
|
});
|
|
143
154
|
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
155
|
+
// Another repository can subscribe to these events
|
|
156
|
+
defineRepository({
|
|
157
|
+
id: "notification-repo",
|
|
158
|
+
install({ instance }) {
|
|
159
|
+
const { observer } = instance;
|
|
160
|
+
|
|
161
|
+
// Subscribe to user events
|
|
162
|
+
observer.subscribe((payload) => {
|
|
163
|
+
if (payload.type === "user.created") {
|
|
164
|
+
console.log("New user:", payload.message);
|
|
165
|
+
// Send welcome email, etc.
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
// repository methods...
|
|
171
|
+
};
|
|
153
172
|
},
|
|
154
173
|
});
|
|
155
174
|
```
|
|
@@ -168,33 +187,33 @@ Creates a repository manager instance.
|
|
|
168
187
|
const manager = repositoryManager();
|
|
169
188
|
```
|
|
170
189
|
|
|
171
|
-
### `manager.
|
|
190
|
+
### `manager.createWorkspace<I>(config)`
|
|
172
191
|
|
|
173
192
|
Creates a workspace with infrastructure dependencies.
|
|
174
193
|
|
|
175
194
|
**Parameters:**
|
|
176
195
|
|
|
177
|
-
- `
|
|
178
|
-
- `config: IConfiguration`
|
|
196
|
+
- `config: IConfiguration<I>`
|
|
179
197
|
- `id: string` - Unique identifier for the workspace
|
|
198
|
+
- `infrastructure: I` - Infrastructure dependencies to inject into repositories
|
|
180
199
|
- `logging?: boolean` - Enable/disable logging (default: `false`)
|
|
181
200
|
|
|
182
201
|
**Returns:** Object with workspace methods:
|
|
183
202
|
|
|
184
203
|
- `defineRepository` - Define repositories
|
|
185
204
|
- `queryRepository` - Query repositories
|
|
186
|
-
- `createScope` - Create scoped state
|
|
187
205
|
|
|
188
206
|
**Example:**
|
|
189
207
|
|
|
190
208
|
```typescript
|
|
191
|
-
const { defineRepository, queryRepository
|
|
192
|
-
|
|
193
|
-
{
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
209
|
+
const { defineRepository, queryRepository } = manager.createWorkspace({
|
|
210
|
+
id: "app",
|
|
211
|
+
infrastructure: {
|
|
212
|
+
httpClient: myHttpClient,
|
|
213
|
+
database: myDb,
|
|
214
|
+
},
|
|
215
|
+
logging: true,
|
|
216
|
+
});
|
|
198
217
|
```
|
|
199
218
|
|
|
200
219
|
### `defineRepository<R>(config)`
|
|
@@ -207,7 +226,7 @@ Defines a repository within the workspace.
|
|
|
207
226
|
- `id: string` - Unique identifier for the repository
|
|
208
227
|
- `install: ({ instance }) => R` - Factory function that returns repository instance
|
|
209
228
|
- `instance.infrastructure` - Injected infrastructure
|
|
210
|
-
- `instance.
|
|
229
|
+
- `instance.observer` - Observer for event-driven communication
|
|
211
230
|
- `onConnect?: () => void` - Called when repository is first connected
|
|
212
231
|
- `onDisconnect?: () => void` - Called when repository is last disconnected
|
|
213
232
|
- `middlewares?: Middleware[]` - Array of middleware functions
|
|
@@ -218,10 +237,23 @@ Defines a repository within the workspace.
|
|
|
218
237
|
defineRepository<IUserRepository>({
|
|
219
238
|
id: "user-repo",
|
|
220
239
|
install({ instance }) {
|
|
221
|
-
const { infrastructure,
|
|
240
|
+
const { infrastructure, observer } = instance;
|
|
241
|
+
|
|
242
|
+
// Subscribe to events
|
|
243
|
+
observer.subscribe((payload) => {
|
|
244
|
+
console.log("Event received:", payload);
|
|
245
|
+
});
|
|
246
|
+
|
|
222
247
|
return {
|
|
223
|
-
|
|
224
|
-
|
|
248
|
+
async createUser(user) {
|
|
249
|
+
const result = await infrastructure.httpClient.post("/users", user);
|
|
250
|
+
// Dispatch event
|
|
251
|
+
observer.dispatch({
|
|
252
|
+
type: "user.created",
|
|
253
|
+
repositoryId: "user-repo",
|
|
254
|
+
message: result,
|
|
255
|
+
});
|
|
256
|
+
return result;
|
|
225
257
|
},
|
|
226
258
|
};
|
|
227
259
|
},
|
|
@@ -254,107 +286,142 @@ await repository.getUsers();
|
|
|
254
286
|
disconnect();
|
|
255
287
|
```
|
|
256
288
|
|
|
257
|
-
### `
|
|
289
|
+
### `observer.dispatch<P>(payload)`
|
|
258
290
|
|
|
259
|
-
|
|
291
|
+
Dispatch an event to notify other repositories.
|
|
260
292
|
|
|
261
293
|
**Parameters:**
|
|
262
294
|
|
|
263
|
-
- `
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
- `provider: (options) => void` - Provide scoped value
|
|
268
|
-
- `currentValue: V` - Current scoped value (getter)
|
|
295
|
+
- `payload: IObserverDispatch<P>`
|
|
296
|
+
- `type: string` - Event type identifier
|
|
297
|
+
- `repositoryId: string` - Source repository identifier
|
|
298
|
+
- `message?: P` - Optional payload data
|
|
269
299
|
|
|
270
300
|
**Example:**
|
|
271
301
|
|
|
272
302
|
```typescript
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Provide value
|
|
279
|
-
userScope.provider({
|
|
280
|
-
value: { userId: "123", role: "admin" },
|
|
281
|
-
children() {
|
|
282
|
-
// Code that runs with scoped value
|
|
283
|
-
},
|
|
303
|
+
observer.dispatch({
|
|
304
|
+
type: "user.created",
|
|
305
|
+
repositoryId: "user-repo",
|
|
306
|
+
message: { userId: "123", email: "user@example.com" },
|
|
284
307
|
});
|
|
285
308
|
```
|
|
286
309
|
|
|
287
|
-
### `
|
|
310
|
+
### `observer.subscribe<P>(callback)`
|
|
288
311
|
|
|
289
|
-
|
|
312
|
+
Subscribe to events from other repositories.
|
|
290
313
|
|
|
291
314
|
**Parameters:**
|
|
292
315
|
|
|
293
|
-
- `
|
|
294
|
-
|
|
295
|
-
|
|
316
|
+
- `callback: (payload: IObserverSubscribePayload<P>) => void` - Callback function
|
|
317
|
+
- `payload.type: string` - Event type
|
|
318
|
+
- `payload.source: string` - Source repository
|
|
319
|
+
- `payload.message: P` - Event payload
|
|
296
320
|
|
|
297
321
|
**Example:**
|
|
298
322
|
|
|
299
323
|
```typescript
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
getCurrentUser() {
|
|
306
|
-
return useScope(userScope);
|
|
307
|
-
},
|
|
308
|
-
};
|
|
309
|
-
},
|
|
324
|
+
observer.subscribe((payload) => {
|
|
325
|
+
if (payload.type === "user.created") {
|
|
326
|
+
console.log("User created:", payload.message);
|
|
327
|
+
console.log("From repository:", payload.source);
|
|
328
|
+
}
|
|
310
329
|
});
|
|
311
330
|
```
|
|
312
331
|
|
|
313
332
|
## 🎯 Advanced Usage
|
|
314
333
|
|
|
315
|
-
###
|
|
334
|
+
### Observer System Benefits
|
|
316
335
|
|
|
317
|
-
|
|
336
|
+
The built-in observer system enables decoupled communication between repositories:
|
|
318
337
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
338
|
+
**Benefits:**
|
|
339
|
+
|
|
340
|
+
- **Loose Coupling** - Repositories don't need to know about each other
|
|
341
|
+
- **Scalability** - Easy to add new listeners without modifying existing code
|
|
342
|
+
- **Event Sourcing** - Track all events in your system
|
|
343
|
+
- **Side Effects** - Handle cross-cutting concerns (logging, analytics, notifications)
|
|
344
|
+
|
|
345
|
+
**When to Use:**
|
|
323
346
|
|
|
347
|
+
- Cross-repository notifications
|
|
348
|
+
- Audit logging
|
|
349
|
+
- Analytics tracking
|
|
350
|
+
- Email/SMS notifications
|
|
351
|
+
- Cache invalidation
|
|
352
|
+
- Webhook triggers
|
|
353
|
+
|
|
354
|
+
### Event-Driven Communication
|
|
355
|
+
|
|
356
|
+
Repositories can communicate through the observer system:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
// User repository dispatches events
|
|
324
360
|
defineRepository({
|
|
325
|
-
id: "
|
|
361
|
+
id: "user-repo",
|
|
326
362
|
install({ instance }) {
|
|
327
|
-
const {
|
|
363
|
+
const { infrastructure, observer } = instance;
|
|
328
364
|
return {
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
365
|
+
async createUser(user) {
|
|
366
|
+
const result = await infrastructure.httpClient.post("/users", user);
|
|
367
|
+
observer.dispatch({
|
|
368
|
+
type: "user.created",
|
|
369
|
+
repositoryId: "user-repo",
|
|
370
|
+
message: result,
|
|
371
|
+
});
|
|
372
|
+
return result;
|
|
373
|
+
},
|
|
374
|
+
async deleteUser(userId) {
|
|
375
|
+
await infrastructure.httpClient.delete(`/users/${userId}`);
|
|
376
|
+
observer.dispatch({
|
|
377
|
+
type: "user.deleted",
|
|
378
|
+
repositoryId: "user-repo",
|
|
379
|
+
message: { userId },
|
|
380
|
+
});
|
|
336
381
|
},
|
|
337
382
|
};
|
|
338
383
|
},
|
|
339
384
|
});
|
|
340
|
-
```
|
|
341
385
|
|
|
342
|
-
|
|
386
|
+
// Notification repository subscribes to user events
|
|
387
|
+
defineRepository({
|
|
388
|
+
id: "notification-repo",
|
|
389
|
+
install({ instance }) {
|
|
390
|
+
const { observer, infrastructure } = instance;
|
|
391
|
+
|
|
392
|
+
observer.subscribe((payload) => {
|
|
393
|
+
if (payload.type === "user.created") {
|
|
394
|
+
infrastructure.emailService.send({
|
|
395
|
+
to: payload.message.email,
|
|
396
|
+
subject: "Welcome!",
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
if (payload.type === "user.deleted") {
|
|
400
|
+
console.log("User deleted:", payload.message.userId);
|
|
401
|
+
}
|
|
402
|
+
});
|
|
343
403
|
|
|
344
|
-
|
|
404
|
+
return {
|
|
405
|
+
// notification methods...
|
|
406
|
+
};
|
|
407
|
+
},
|
|
408
|
+
});
|
|
345
409
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
},
|
|
410
|
+
// Analytics repository also subscribes
|
|
411
|
+
defineRepository({
|
|
412
|
+
id: "analytics-repo",
|
|
413
|
+
install({ instance }) {
|
|
414
|
+
const { observer } = instance;
|
|
415
|
+
|
|
416
|
+
observer.subscribe((payload) => {
|
|
417
|
+
if (payload.type === "user.created") {
|
|
418
|
+
console.log("Track new user:", payload.message);
|
|
419
|
+
}
|
|
357
420
|
});
|
|
421
|
+
|
|
422
|
+
return {
|
|
423
|
+
// analytics methods...
|
|
424
|
+
};
|
|
358
425
|
},
|
|
359
426
|
});
|
|
360
427
|
```
|
|
@@ -365,24 +432,26 @@ Create multiple isolated workspaces with different dependencies:
|
|
|
365
432
|
|
|
366
433
|
```typescript
|
|
367
434
|
// API workspace
|
|
368
|
-
const apiWorkspace = manager.
|
|
369
|
-
|
|
435
|
+
const apiWorkspace = manager.createWorkspace({
|
|
436
|
+
id: "api",
|
|
437
|
+
infrastructure: {
|
|
370
438
|
httpClient: apiClient,
|
|
371
439
|
cache: redisCache,
|
|
372
440
|
},
|
|
373
|
-
|
|
374
|
-
);
|
|
441
|
+
logging: true,
|
|
442
|
+
});
|
|
375
443
|
|
|
376
444
|
// Database workspace
|
|
377
|
-
const dbWorkspace = manager.
|
|
378
|
-
|
|
445
|
+
const dbWorkspace = manager.createWorkspace({
|
|
446
|
+
id: "database",
|
|
447
|
+
infrastructure: {
|
|
379
448
|
db: postgresClient,
|
|
380
449
|
logger: winstonLogger,
|
|
381
450
|
},
|
|
382
|
-
|
|
383
|
-
);
|
|
451
|
+
logging: false,
|
|
452
|
+
});
|
|
384
453
|
|
|
385
|
-
// Each workspace has isolated repositories
|
|
454
|
+
// Each workspace has isolated repositories and observers
|
|
386
455
|
apiWorkspace.defineRepository({...});
|
|
387
456
|
dbWorkspace.defineRepository({...});
|
|
388
457
|
```
|
|
@@ -407,7 +476,11 @@ interface IUserRepository {
|
|
|
407
476
|
|
|
408
477
|
// Workspace with typed infrastructure
|
|
409
478
|
const { defineRepository, queryRepository } =
|
|
410
|
-
manager.
|
|
479
|
+
manager.createWorkspace<IInfrastructure>({
|
|
480
|
+
id: "app",
|
|
481
|
+
infrastructure,
|
|
482
|
+
logging: true,
|
|
483
|
+
});
|
|
411
484
|
|
|
412
485
|
// Repository with typed interface
|
|
413
486
|
defineRepository<IUserRepository>({
|
|
@@ -493,105 +566,16 @@ defineRepository({
|
|
|
493
566
|
- **Error Handling** - Centralized error handling and retry logic
|
|
494
567
|
- **Authentication** - Check permissions before execution
|
|
495
568
|
|
|
496
|
-
### Real-World Example: User Management
|
|
497
|
-
|
|
498
|
-
```typescript
|
|
499
|
-
// Define scopes
|
|
500
|
-
const authScope = createScope({ token: null, user: null });
|
|
501
|
-
const featureFlagsScope = createScope({ features: [] });
|
|
502
|
-
|
|
503
|
-
// Infrastructure
|
|
504
|
-
const infrastructure = {
|
|
505
|
-
httpClient: {
|
|
506
|
-
get: async (url) =>
|
|
507
|
-
fetch(url, {
|
|
508
|
-
headers: { Authorization: `Bearer ${useScope(authScope).token}` },
|
|
509
|
-
}).then((r) => r.json()),
|
|
510
|
-
post: async (url, data) =>
|
|
511
|
-
fetch(url, {
|
|
512
|
-
method: "POST",
|
|
513
|
-
headers: { Authorization: `Bearer ${useScope(authScope).token}` },
|
|
514
|
-
body: JSON.stringify(data),
|
|
515
|
-
}).then((r) => r.json()),
|
|
516
|
-
},
|
|
517
|
-
cache: new Map(),
|
|
518
|
-
};
|
|
519
|
-
|
|
520
|
-
// Create workspace
|
|
521
|
-
const { defineRepository, queryRepository } = manager.workspace(
|
|
522
|
-
infrastructure,
|
|
523
|
-
{ id: "app", logging: true }
|
|
524
|
-
);
|
|
525
|
-
|
|
526
|
-
// Define repositories
|
|
527
|
-
defineRepository<IUserRepository>({
|
|
528
|
-
id: "user-repo",
|
|
529
|
-
install({ instance }) {
|
|
530
|
-
const { infrastructure, useScope } = instance;
|
|
531
|
-
return {
|
|
532
|
-
async getUsers() {
|
|
533
|
-
const auth = useScope(authScope);
|
|
534
|
-
if (!auth.token) throw new Error("Not authenticated");
|
|
535
|
-
return infrastructure.httpClient.get("/api/users");
|
|
536
|
-
},
|
|
537
|
-
async createUser(user) {
|
|
538
|
-
const flags = useScope(featureFlagsScope);
|
|
539
|
-
if (!flags.features.includes("create-user")) {
|
|
540
|
-
throw new Error("Feature not enabled");
|
|
541
|
-
}
|
|
542
|
-
return infrastructure.httpClient.post("/api/users", user);
|
|
543
|
-
},
|
|
544
|
-
};
|
|
545
|
-
},
|
|
546
|
-
onConnect: () => console.log("User repo connected"),
|
|
547
|
-
onDisconnect: () => console.log("User repo disconnected"),
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
// Use with authentication
|
|
551
|
-
authScope.provider({
|
|
552
|
-
value: { token: "abc123", user: { id: "1", name: "John" } },
|
|
553
|
-
children() {
|
|
554
|
-
featureFlagsScope.provider({
|
|
555
|
-
value: { features: ["create-user", "delete-user"] },
|
|
556
|
-
async children() {
|
|
557
|
-
const { repository, disconnect } =
|
|
558
|
-
queryRepository<IUserRepository>("user-repo");
|
|
559
|
-
|
|
560
|
-
// Has access to auth and feature flags
|
|
561
|
-
const users = await repository.getUsers();
|
|
562
|
-
await repository.createUser({ name: "Jane" });
|
|
563
|
-
|
|
564
|
-
disconnect();
|
|
565
|
-
},
|
|
566
|
-
});
|
|
567
|
-
},
|
|
568
|
-
});
|
|
569
|
-
```
|
|
570
|
-
|
|
571
569
|
### Logging
|
|
572
570
|
|
|
573
|
-
Enable logging to see connection lifecycle:
|
|
571
|
+
Enable logging to see connection lifecycle and events:
|
|
574
572
|
|
|
575
573
|
```typescript
|
|
576
|
-
const { defineRepository } = manager.
|
|
574
|
+
const { defineRepository } = manager.createWorkspace({
|
|
577
575
|
id: "app",
|
|
576
|
+
infrastructure,
|
|
578
577
|
logging: true, // Enables colored console output
|
|
579
578
|
});
|
|
580
|
-
|
|
581
|
-
// Console output will show:
|
|
582
|
-
// repository.define (user-repo)
|
|
583
|
-
// ┌─────────┬───────────┐
|
|
584
|
-
// │ (index) │repository │
|
|
585
|
-
// ├─────────┼───────────┤
|
|
586
|
-
// │ 0 │ user-repo │
|
|
587
|
-
// └─────────┴───────────┘
|
|
588
|
-
//
|
|
589
|
-
// repository.connect (user-repo)
|
|
590
|
-
// ┌─────────┬───────────┬─────────────┐
|
|
591
|
-
// │ (index) │repository │ connections │
|
|
592
|
-
// ├─────────┼───────────┼─────────────┤
|
|
593
|
-
// │ 0 │ user-repo │ 1 │
|
|
594
|
-
// └─────────┴───────────┴─────────────┘
|
|
595
579
|
```
|
|
596
580
|
|
|
597
581
|
## 🏗️ Design Patterns
|
|
@@ -602,23 +586,6 @@ This library implements several design patterns:
|
|
|
602
586
|
- **Factory Pattern** - Repositories are created using factory functions
|
|
603
587
|
- **Singleton Pattern** - Each repository is a singleton per workspace (with reference counting)
|
|
604
588
|
- **Repository Pattern** - Abstracts data access logic
|
|
605
|
-
- **
|
|
606
|
-
- **
|
|
607
|
-
|
|
608
|
-
## ⚠️ Error Handling
|
|
609
|
-
|
|
610
|
-
```typescript
|
|
611
|
-
try {
|
|
612
|
-
const { repository } = queryRepository("non-existent-repo");
|
|
613
|
-
} catch (error) {
|
|
614
|
-
console.error(error.message); // Repository "non-existent-repo" not found
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// With scope
|
|
618
|
-
try {
|
|
619
|
-
const user = useScope(userScope);
|
|
620
|
-
if (!user) throw new Error("No user in scope");
|
|
621
|
-
} catch (error) {
|
|
622
|
-
console.error("Scope error:", error);
|
|
623
|
-
}
|
|
624
|
-
```
|
|
589
|
+
- **Observer Pattern** - Event-driven communication between repositories
|
|
590
|
+
- **Workspace Pattern** - Clean API for managing dependencies and lifecycle
|
|
591
|
+
- **Pub/Sub Pattern** - Repositories can publish and subscribe to events
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/core/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,wBAAgB,eAAe,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,UAAU,EAAE,OAkCzE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { scopedObserverType } from "../infrastructure";
|
|
2
|
+
import type { IRepositoryPlugin } from "./types";
|
|
3
|
+
declare function createRepository<I>(infrastructure: I, repositoryPlugin: IRepositoryPlugin<I, any>, observer: scopedObserverType): {
|
|
4
|
+
readonly repository: unknown;
|
|
5
|
+
readonly connections: number;
|
|
6
|
+
connect(): void;
|
|
7
|
+
disconnect(): void;
|
|
8
|
+
};
|
|
9
|
+
export { createRepository };
|
|
10
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/core/repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD,iBAAS,gBAAgB,CAAC,CAAC,EACzB,cAAc,EAAE,CAAC,EACjB,gBAAgB,EAAE,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,EAC3C,QAAQ,EAAE,kBAAkB;;;;;EAgF7B;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|