Μετάβαση στο περιεχόμενο

Πρώτα βήματα

Terminal window
pnpm add @cqrs-ddd/pipeline

Τα πακέτα απαιτούν Node.js 22.12 ή νεότερο, ή άλλο runtime με AsyncLocalStorage (Bun, Deno). Δημοσιεύονται ως ES modules· μια εφαρμογή CommonJS τα φορτώνει με require().

Ένα pipeline κρατά τα instances των behaviors και τα behaviors που ισχύουν για κάθε λειτουργία. Δημιουργήστε το μία φορά, σε δικό του module:

pipeline.ts
import { createPipeline, LoggingBehavior, logging } from '@cqrs-ddd/pipeline';
export const pipeline = createPipeline({
behaviors: [new LoggingBehavior(console)],
globalBehaviors: { before: [logging({ requestResponseLogLevel: 'log' })] },
});

Τα behaviors είναι τα instances, ένα ανά κλάση behavior· ένα behavior που τοποθετείται χωρίς instance κατασκευάζεται χωρίς ορίσματα. Το globalBehaviors τοποθετεί behaviors γύρω από κάθε λειτουργία που τυλίγεται.

Το pipeline.wrap(options, ...entries) επιστρέφει έναν wrapper. Όταν εφαρμοστεί σε μια συνάρτηση, επιστρέφει μια νέα async συνάρτηση που εκτελεί τα behaviors γύρω της:

import { pipeline } from './pipeline.js';
export const getPrice = pipeline.wrap({ name: 'getPrice', kind: 'query' })(
async (sku: string) => prices.find(sku),
);
await getPrice('apple');

Μια απλή συνάρτηση χρειάζεται ένα name, με το οποίο τα κλειδιά και τα logs ξεχωρίζουν τις λειτουργίες, και ένα kind: ένα query διαβάζει, ένα command αλλάζει κατάσταση, ένα event αντιδρά. Τα behaviors χρησιμοποιούν το kind για να αποφασίσουν τι ισχύει· το idempotency, για παράδειγμα, ισχύει για commands.

Ο ίδιος wrapper γίνεται decorator μεθόδου, με τους standard decorators της TypeScript ή με experimentalDecorators:

class Prices {
@pipeline.wrap({ kind: 'query' })
async find(sku: string) {
return this.store.get(sku);
}
}

Μια μέθοδος ονομάζεται Class.method (εδώ Prices.find), εκτός αν τα options της δίνουν όνομα.

Κάθε λειτουργία είναι ένα πακέτο. Εγκαταστήστε το, δώστε στο pipeline ένα instance και προσθέστε την καταχώρισή του εκεί που ισχύει:

Terminal window
pnpm add @cqrs-ddd/pipeline-zod zod
import { validated } from '@cqrs-ddd/pipeline-zod';
import { z } from 'zod';
export const placeOrder = pipeline.wrap(
{ name: 'placeOrder', kind: 'command' },
validated(z.object({ sku: z.string(), qty: z.coerce.number().int().positive() })),
)(async (order) => orders.place(order));