@xeno-js/core 0.1.11 → 0.1.13
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 +43 -23
- package/dist/index.cjs +7 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -111,9 +111,9 @@ Request-scoped dependencies are resolved inside an explicit application scope,
|
|
|
111
111
|
while request metadata can be carried through asynchronous execution using
|
|
112
112
|
`AsyncLocalStorage`.
|
|
113
113
|
|
|
114
|
-
Database transaction state is scoped to the same application boundary,
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
Database transaction state is scoped to the same application boundary, allowing
|
|
115
|
+
`UnitOfWork` and `DbContext` to operate against the transaction associated with
|
|
116
|
+
the current scope.
|
|
117
117
|
|
|
118
118
|
### 05 — Infrastructure Stays Outside the Domain
|
|
119
119
|
|
|
@@ -198,9 +198,11 @@ npm install zod pino cockatiel drizzle-orm
|
|
|
198
198
|
The composition root is explicit:
|
|
199
199
|
|
|
200
200
|
```typescript
|
|
201
|
+
// src/bootstrap.ts
|
|
201
202
|
import { AppBuilder } from '@xeno-js/core'
|
|
202
203
|
|
|
203
|
-
const app = new AppBuilder()
|
|
204
|
+
const app = new AppBuilder()
|
|
205
|
+
.addServices((services) => {
|
|
204
206
|
services.addScoped('USER_REPOSITORY', (container) => {
|
|
205
207
|
return new UserRepository(container.resolve('USER_DATA_SOURCE'))
|
|
206
208
|
})
|
|
@@ -210,31 +212,49 @@ const app = new AppBuilder().addServices((services) => {
|
|
|
210
212
|
})
|
|
211
213
|
|
|
212
214
|
services.addTransient('FIND_USER_CONTROLLER', (c) => {
|
|
213
|
-
return new
|
|
215
|
+
return new FindUserController(
|
|
216
|
+
c.resolve(TOKENS.REQUEST_CONTEXT),
|
|
217
|
+
c.resolve(TOKENS.MEDIATOR),
|
|
218
|
+
)
|
|
214
219
|
})
|
|
215
220
|
})
|
|
221
|
+
|
|
222
|
+
await app.build()
|
|
216
223
|
```
|
|
217
224
|
|
|
218
225
|
The transport remains outside the application composition:
|
|
219
226
|
|
|
220
|
-
> ⚠️ **Implementation note: Example using Fastify**
|
|
221
|
-
>
|
|
227
|
+
> ⚠️ **Implementation note: Example using Fastify** The following snippet uses
|
|
228
|
+
> **Fastify** solely for demonstration purposes to illustrate the transport
|
|
229
|
+
> layer. Thanks to the framework's agnostic architecture, the underlying logic
|
|
230
|
+
> (`container` and `handler`) remains unchanged regardless of the chosen HTTP
|
|
231
|
+
> system (e.g., Express, Koa) or interface (CLI, gRPC).
|
|
222
232
|
|
|
223
233
|
```typescript
|
|
224
|
-
import Fastify from 'fastify'
|
|
225
|
-
import {
|
|
234
|
+
import Fastify from 'fastify'
|
|
235
|
+
import { app } from './bootstrap'
|
|
226
236
|
|
|
227
|
-
const
|
|
237
|
+
const fastify = Fastify({ logger: true })
|
|
228
238
|
|
|
229
|
-
|
|
239
|
+
fastify.get('/users/:id', async (req, reply) => {
|
|
230
240
|
const endpoint = req.url
|
|
231
|
-
|
|
241
|
+
|
|
232
242
|
const action = async () => {
|
|
233
|
-
|
|
234
|
-
|
|
243
|
+
const controller = ContainerUtils.resolveServiceScoped(
|
|
244
|
+
'FIND_USER_CONTROLLER',
|
|
245
|
+
app,
|
|
246
|
+
)
|
|
247
|
+
return await controller.handle()
|
|
235
248
|
}
|
|
236
249
|
|
|
237
|
-
const result = await ContainerUtils.runExecute(
|
|
250
|
+
const result = await ContainerUtils.runExecute(
|
|
251
|
+
endpoint,
|
|
252
|
+
req.method,
|
|
253
|
+
req.headers,
|
|
254
|
+
{ reply, req },
|
|
255
|
+
app,
|
|
256
|
+
action,
|
|
257
|
+
)
|
|
238
258
|
|
|
239
259
|
return reply.send(result)
|
|
240
260
|
})
|
|
@@ -319,13 +339,13 @@ The documentation hub contains the architecture and integration guides:
|
|
|
319
339
|
Recommended starting points:
|
|
320
340
|
|
|
321
341
|
- [Introduction](https://www.xeno-js.it/introduction)
|
|
322
|
-
- [
|
|
323
|
-
- [Dependency Injection](https://www.xeno-js.it/
|
|
324
|
-
- [CQRS](https://www.xeno-js.it/
|
|
325
|
-
- [Pipelines](https://www.xeno-js.it/
|
|
326
|
-
- [Request Lifecycle](https://www.xeno-js.it/
|
|
327
|
-
- [
|
|
328
|
-
- [CLI](https://www.xeno-js.it/cli/overview)
|
|
342
|
+
- [Fundamentals](https://www.xeno-js.it/docs/core/overview)
|
|
343
|
+
- [Dependency Injection](https://www.xeno-js.it/docs/core/fundamentals/app-builder)
|
|
344
|
+
- [CQRS](https://www.xeno-js.it/docs/core/fundamentals/command-query)
|
|
345
|
+
- [Pipelines](https://www.xeno-js.it/docs/core/cqrs/overview)
|
|
346
|
+
- [Request Lifecycle](https://www.xeno-js.it/docs/core/fundamentals/service-container)
|
|
347
|
+
- [Middleware](https://www.xeno-js.it/docs/core/fundamentals/middleware)
|
|
348
|
+
- [CLI](https://www.xeno-js.it/docs/cli/overview)
|
|
329
349
|
|
|
330
350
|
---
|
|
331
351
|
|
|
@@ -426,7 +446,7 @@ npm run check
|
|
|
426
446
|
If Xeno is useful to you, you can support the project through the community and
|
|
427
447
|
sponsorship channels documented on the website:
|
|
428
448
|
|
|
429
|
-
**[Support Xeno](https://www.xeno-js.it/support-us)**
|
|
449
|
+
**[Support Xeno](https://www.xeno-js.it/docs/support-us)**
|
|
430
450
|
|
|
431
451
|
---
|
|
432
452
|
|
package/dist/index.cjs
CHANGED
|
@@ -2419,9 +2419,7 @@ var init_cockatiel_resilience_factory = __esm({
|
|
|
2419
2419
|
}
|
|
2420
2420
|
}
|
|
2421
2421
|
if (isNetworkError) return true;
|
|
2422
|
-
if (import_shared53.Guards.isDefined(status))
|
|
2423
|
-
return status === 408 || status === 429 || status >= 500 && status < 600;
|
|
2424
|
-
}
|
|
2422
|
+
if (import_shared53.Guards.isDefined(status)) return status === 408 || status >= 500 && status < 600;
|
|
2425
2423
|
return false;
|
|
2426
2424
|
}
|
|
2427
2425
|
isTransientAndIdempotent(error) {
|
|
@@ -3324,8 +3322,8 @@ var init_cqrs_module = __esm({
|
|
|
3324
3322
|
);
|
|
3325
3323
|
if (Guards46.isDefined(validationPipelines)) pipelines.push(validationPipelines);
|
|
3326
3324
|
}
|
|
3327
|
-
const commandPipelines = pipelines;
|
|
3328
|
-
const queryPipelines = pipelines;
|
|
3325
|
+
const commandPipelines = [...pipelines];
|
|
3326
|
+
const queryPipelines = [...pipelines];
|
|
3329
3327
|
if (Guards46.isDefined(opts.commandBus.idempotency) || Guards46.isDefined(opts.commandBus.concurrency)) {
|
|
3330
3328
|
const { PipelineUtils: PipelineUtils2 } = await Promise.resolve().then(() => (init_pipeline_utils(), pipeline_utils_exports));
|
|
3331
3329
|
const newCommandPipelines = await PipelineUtils2.addCommand(container, opts.commandBus);
|
|
@@ -3875,7 +3873,7 @@ var init_rate_limiter_middleware = __esm({
|
|
|
3875
3873
|
error: {
|
|
3876
3874
|
code: import_shared69.ERROR_CODES.TOO_MANY_REQUESTS,
|
|
3877
3875
|
message: import_shared69.ERROR_CODE_MESSAGES[import_shared69.ERROR_CODES.TOO_MANY_REQUESTS],
|
|
3878
|
-
details: `Rate limit exceeded
|
|
3876
|
+
details: `Rate limit exceeded.`,
|
|
3879
3877
|
path: req.path
|
|
3880
3878
|
},
|
|
3881
3879
|
correlationId: tracing?.correlationId ?? import_shared69.GuidHelper.generate(),
|
|
@@ -4598,6 +4596,7 @@ var isDisposable = Object.freeze({
|
|
|
4598
4596
|
var AppBuilder = class {
|
|
4599
4597
|
_container = new ServiceContainer();
|
|
4600
4598
|
_configuration;
|
|
4599
|
+
_isBuilded = false;
|
|
4601
4600
|
constructor(container) {
|
|
4602
4601
|
this._container = container ?? new ServiceContainer();
|
|
4603
4602
|
this._container.addSingleton(
|
|
@@ -4965,6 +4964,7 @@ var AppBuilder = class {
|
|
|
4965
4964
|
* @link https://github.com/xeno-js/xeno-js
|
|
4966
4965
|
*/
|
|
4967
4966
|
async build() {
|
|
4967
|
+
if (this._isBuilded) return this._container;
|
|
4968
4968
|
console.info("\u2699\uFE0F Bootstrapping application modules...");
|
|
4969
4969
|
const sortedModules = this._modules.sort((a, b) => a.priority - b.priority);
|
|
4970
4970
|
for (const queued of sortedModules) {
|
|
@@ -4985,6 +4985,7 @@ var AppBuilder = class {
|
|
|
4985
4985
|
}
|
|
4986
4986
|
}
|
|
4987
4987
|
console.info("\u2705 Application modules bootstrapped successfully.");
|
|
4988
|
+
this._isBuilded = true;
|
|
4988
4989
|
return this._container;
|
|
4989
4990
|
}
|
|
4990
4991
|
// ─────────────────────────────────────────────────────────────────────────────
|