@robinmalfait/event-source 0.0.4 → 0.0.6

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/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- interface EventType<T extends string, P> {
1
+ interface EventType<T extends string = any, P = any> {
2
2
  aggregateId: string;
3
3
  eventId: string;
4
4
  eventName: T;
@@ -8,20 +8,29 @@ interface EventType<T extends string, P> {
8
8
  }
9
9
  declare function Event<const T extends string, P = null>(eventName: T, aggregateId: string, payload?: P): EventType<T, P>;
10
10
 
11
- declare class Aggregate {
12
- private version;
13
- private recordedEvents;
14
- replayEvents<T extends string>(events?: EventType<T, any>[]): this;
11
+ type ApplyConcreteEvents<Events extends EventType> = Events extends EventType<infer EventName, any> ? {
12
+ [T in EventName]: (event: Extract<Events, {
13
+ eventName: T;
14
+ }>) => void;
15
+ } : never;
16
+ type Lazy<T> = (...args: any[]) => T;
17
+ type ApplyLazyEvents<Events extends Lazy<EventType>> = ApplyConcreteEvents<ReturnType<Events>>;
18
+ type MaybeLazy<T> = T | Lazy<T>;
19
+ type ApplyEvents<Events extends MaybeLazy<EventType> = any> = Events extends Lazy<EventType> ? ApplyLazyEvents<Events> : Events extends EventType ? ApplyConcreteEvents<Events> : never;
20
+ declare abstract class Aggregate {
21
+ #private;
22
+ abstract apply: ApplyEvents;
23
+ replayEvents(events?: EventType[]): this;
15
24
  private applyAnEvent;
16
- protected recordThat<const T extends string>(event: EventType<T, any>): this;
17
- releaseEvents(): EventType<string, any>[];
25
+ protected recordThat<T extends EventType>(event: T): this;
26
+ releaseEvents(): EventType<any, any>[];
18
27
  }
19
28
 
20
- interface CommandType<T> {
21
- type: string;
22
- payload: T;
29
+ interface CommandType<T extends string = any, P = any> {
30
+ type: T;
31
+ payload: P;
23
32
  }
24
- declare function Command<const T extends string, P>(type: T, payload: P): CommandType<P>;
33
+ declare function Command<const T extends string, P = null>(type: T, payload?: P): CommandType<T, P>;
25
34
 
26
35
  type PayloadOf<T extends (...args: any) => {
27
36
  payload: unknown;
@@ -36,48 +45,58 @@ declare function objectToYaml<T extends Object>(object: T): string;
36
45
 
37
46
  type MaybePromise<T> = T | Promise<T>;
38
47
  interface EventStore {
39
- persist<const T extends string>(events: EventType<T, unknown>[]): MaybePromise<void>;
40
- load<const T extends string>(aggregateId: string): MaybePromise<EventType<T, string>[]>;
41
- loadEvents<const T extends string>(): MaybePromise<EventType<T, string>[]>;
42
- }
43
- interface EventSourceConfig<Handlers = any> {
44
- store: EventStore | Promise<EventStore>;
45
- commandHandlers: Record<string, CommandHandler<Handlers>>;
46
- projectors?: Projector[];
47
- eventHandlers?: EventHandler[];
48
+ persist(events: EventType[]): MaybePromise<void>;
49
+ load(aggregateId: string): MaybePromise<EventType[]>;
50
+ loadEvents(): MaybePromise<EventType[]>;
48
51
  }
49
52
  interface EventHandler {
50
- (event: EventType<string, string>, es: EventSource): MaybePromise<unknown>;
53
+ (event: EventType, es: EventSource): MaybePromise<unknown>;
51
54
  }
52
- interface Projector<T extends string = any, P = any> {
55
+ interface Projector {
53
56
  name: string;
54
57
  init: (es: EventSource) => MaybePromise<void>;
55
- update: (event: EventType<T, P>) => MaybePromise<unknown>;
58
+ update: (event: EventType) => MaybePromise<unknown>;
56
59
  }
57
- interface CommandHandler<T> {
58
- (command: CommandType<T>, es: EventSource): MaybePromise<void>;
60
+ interface CommandHandler {
61
+ (command: CommandType, es: EventSource): MaybePromise<void>;
59
62
  }
60
- type EventSource = ReturnType<typeof createEventSource>;
61
- declare function createEventSource(config: EventSourceConfig): {
62
- resetProjections(): Promise<void>;
63
- dispatch<T>(command: CommandType<T>): Promise<CommandType<T>>;
64
- loadEvents<const T_1 extends string>(): Promise<EventType<T_1, string>[]>;
65
- load<T_2 extends Aggregate>(aggregate: T_2, aggregateId: string): Promise<T_2>;
63
+ declare class EventSource {
64
+ private store;
65
+ private commandHandlers;
66
+ private projectors;
67
+ private eventHandlers;
68
+ private constructor();
69
+ static builder(store: EventStore): EventSourceBuilder;
70
+ static new(store: EventStore, commandHandlers: Map<string, CommandHandler>, projectors: Projector[], eventHandlers: EventHandler[]): EventSource;
71
+ dispatch<T extends CommandType>(command: T): Promise<T>;
72
+ loadEvents(): Promise<EventType<any, any>[]>;
73
+ load<T extends Aggregate>(aggregate: T, aggregateId: string): Promise<T>;
66
74
  persist(aggregate: Aggregate): Promise<void>;
67
- loadPersist<T_3 extends Aggregate>(aggregate: T_3, aggregateId: string, handle: (aggregate: T_3) => Promise<void> | void): Promise<void>;
68
- };
75
+ loadPersist<T extends Aggregate>(aggregate: T, aggregateId: string, handle: (aggregate: T) => Promise<void> | void): Promise<void>;
76
+ }
77
+ declare class EventSourceBuilder {
78
+ private store;
79
+ private commandHandlers;
80
+ private projectors;
81
+ private eventHandlers;
82
+ constructor(store: EventStore);
83
+ build(): EventSource;
84
+ addCommandHandler(commandType: string, handler: CommandHandler): void;
85
+ addProjector(projector: Projector): void;
86
+ addEventHandler(eventHandler: EventHandler): void;
87
+ }
69
88
 
70
- type EventMapper$1 = Record<string, (event: EventType<any, any>, es: EventSource) => void>;
71
- declare function createEventMapper(mapper: EventMapper$1): (event: EventType<any, any>, es: EventSource) => void;
89
+ type EventMapper$1 = Record<string, (event: EventType, es: EventSource) => void>;
90
+ declare function createEventMapper(mapper: EventMapper$1): (event: EventType, es: EventSource) => void;
72
91
 
73
- type EventMapper<Ctx, T extends string, P> = Record<string, (event: EventType<T, P>, ctx?: Ctx) => void>;
74
- declare function createProjector<Ctx, T extends string, P>(name: string, mapper: EventMapper<Ctx, T, P>, initializer?: (ctx?: Ctx) => Promise<void> | void, createContext?: () => Ctx): Projector;
92
+ type EventMapper<Ctx, T extends EventType> = Record<string, (event: T, ctx?: Ctx) => void>;
93
+ declare function createProjector<Ctx, T extends EventType>(name: string, mapper: EventMapper<Ctx, T>, initializer?: (ctx?: Ctx) => Promise<void> | void, createContext?: () => Ctx): Projector;
75
94
 
76
- declare function createTestEventStore(commandHandlers: Record<string, CommandHandler<any>>, projectors?: Projector[]): {
95
+ declare function createTestEventStore(commandHandlers: Record<string, CommandHandler>, projectors?: Projector[]): {
77
96
  ___: any;
78
- given(events?: EventType<any, any>[]): Promise<void>;
79
- when<T>(command: CommandType<T> | (() => CommandType<T>)): Promise<CommandType<T>>;
80
- then<const T_1 extends string>(expectation: Error | EventType<T_1, any>[]): Promise<void>;
97
+ given(events?: EventType[]): Promise<void>;
98
+ when<T extends CommandType<any, any>>(command: T | (() => T)): Promise<T>;
99
+ then(expectation: EventType[] | Error): Promise<void>;
81
100
  };
82
101
 
83
- export { Aggregate, Command, type CommandHandler, type CommandType, Event, type EventHandler, type EventSource, type EventSourceConfig, type EventStore, type EventType, type PayloadOf, type Projector, type TypeOf, abort, createEventMapper, createEventSource, createProjector, createTestEventStore, objectToYaml };
102
+ export { Aggregate, type ApplyEvents, Command, type CommandHandler, type CommandType, Event, type EventHandler, EventSource, type EventStore, type EventType, type PayloadOf, type Projector, type TypeOf, abort, createEventMapper, createProjector, createTestEventStore, objectToYaml };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- interface EventType<T extends string, P> {
1
+ interface EventType<T extends string = any, P = any> {
2
2
  aggregateId: string;
3
3
  eventId: string;
4
4
  eventName: T;
@@ -8,20 +8,29 @@ interface EventType<T extends string, P> {
8
8
  }
9
9
  declare function Event<const T extends string, P = null>(eventName: T, aggregateId: string, payload?: P): EventType<T, P>;
10
10
 
11
- declare class Aggregate {
12
- private version;
13
- private recordedEvents;
14
- replayEvents<T extends string>(events?: EventType<T, any>[]): this;
11
+ type ApplyConcreteEvents<Events extends EventType> = Events extends EventType<infer EventName, any> ? {
12
+ [T in EventName]: (event: Extract<Events, {
13
+ eventName: T;
14
+ }>) => void;
15
+ } : never;
16
+ type Lazy<T> = (...args: any[]) => T;
17
+ type ApplyLazyEvents<Events extends Lazy<EventType>> = ApplyConcreteEvents<ReturnType<Events>>;
18
+ type MaybeLazy<T> = T | Lazy<T>;
19
+ type ApplyEvents<Events extends MaybeLazy<EventType> = any> = Events extends Lazy<EventType> ? ApplyLazyEvents<Events> : Events extends EventType ? ApplyConcreteEvents<Events> : never;
20
+ declare abstract class Aggregate {
21
+ #private;
22
+ abstract apply: ApplyEvents;
23
+ replayEvents(events?: EventType[]): this;
15
24
  private applyAnEvent;
16
- protected recordThat<const T extends string>(event: EventType<T, any>): this;
17
- releaseEvents(): EventType<string, any>[];
25
+ protected recordThat<T extends EventType>(event: T): this;
26
+ releaseEvents(): EventType<any, any>[];
18
27
  }
19
28
 
20
- interface CommandType<T> {
21
- type: string;
22
- payload: T;
29
+ interface CommandType<T extends string = any, P = any> {
30
+ type: T;
31
+ payload: P;
23
32
  }
24
- declare function Command<const T extends string, P>(type: T, payload: P): CommandType<P>;
33
+ declare function Command<const T extends string, P = null>(type: T, payload?: P): CommandType<T, P>;
25
34
 
26
35
  type PayloadOf<T extends (...args: any) => {
27
36
  payload: unknown;
@@ -36,48 +45,58 @@ declare function objectToYaml<T extends Object>(object: T): string;
36
45
 
37
46
  type MaybePromise<T> = T | Promise<T>;
38
47
  interface EventStore {
39
- persist<const T extends string>(events: EventType<T, unknown>[]): MaybePromise<void>;
40
- load<const T extends string>(aggregateId: string): MaybePromise<EventType<T, string>[]>;
41
- loadEvents<const T extends string>(): MaybePromise<EventType<T, string>[]>;
42
- }
43
- interface EventSourceConfig<Handlers = any> {
44
- store: EventStore | Promise<EventStore>;
45
- commandHandlers: Record<string, CommandHandler<Handlers>>;
46
- projectors?: Projector[];
47
- eventHandlers?: EventHandler[];
48
+ persist(events: EventType[]): MaybePromise<void>;
49
+ load(aggregateId: string): MaybePromise<EventType[]>;
50
+ loadEvents(): MaybePromise<EventType[]>;
48
51
  }
49
52
  interface EventHandler {
50
- (event: EventType<string, string>, es: EventSource): MaybePromise<unknown>;
53
+ (event: EventType, es: EventSource): MaybePromise<unknown>;
51
54
  }
52
- interface Projector<T extends string = any, P = any> {
55
+ interface Projector {
53
56
  name: string;
54
57
  init: (es: EventSource) => MaybePromise<void>;
55
- update: (event: EventType<T, P>) => MaybePromise<unknown>;
58
+ update: (event: EventType) => MaybePromise<unknown>;
56
59
  }
57
- interface CommandHandler<T> {
58
- (command: CommandType<T>, es: EventSource): MaybePromise<void>;
60
+ interface CommandHandler {
61
+ (command: CommandType, es: EventSource): MaybePromise<void>;
59
62
  }
60
- type EventSource = ReturnType<typeof createEventSource>;
61
- declare function createEventSource(config: EventSourceConfig): {
62
- resetProjections(): Promise<void>;
63
- dispatch<T>(command: CommandType<T>): Promise<CommandType<T>>;
64
- loadEvents<const T_1 extends string>(): Promise<EventType<T_1, string>[]>;
65
- load<T_2 extends Aggregate>(aggregate: T_2, aggregateId: string): Promise<T_2>;
63
+ declare class EventSource {
64
+ private store;
65
+ private commandHandlers;
66
+ private projectors;
67
+ private eventHandlers;
68
+ private constructor();
69
+ static builder(store: EventStore): EventSourceBuilder;
70
+ static new(store: EventStore, commandHandlers: Map<string, CommandHandler>, projectors: Projector[], eventHandlers: EventHandler[]): EventSource;
71
+ dispatch<T extends CommandType>(command: T): Promise<T>;
72
+ loadEvents(): Promise<EventType<any, any>[]>;
73
+ load<T extends Aggregate>(aggregate: T, aggregateId: string): Promise<T>;
66
74
  persist(aggregate: Aggregate): Promise<void>;
67
- loadPersist<T_3 extends Aggregate>(aggregate: T_3, aggregateId: string, handle: (aggregate: T_3) => Promise<void> | void): Promise<void>;
68
- };
75
+ loadPersist<T extends Aggregate>(aggregate: T, aggregateId: string, handle: (aggregate: T) => Promise<void> | void): Promise<void>;
76
+ }
77
+ declare class EventSourceBuilder {
78
+ private store;
79
+ private commandHandlers;
80
+ private projectors;
81
+ private eventHandlers;
82
+ constructor(store: EventStore);
83
+ build(): EventSource;
84
+ addCommandHandler(commandType: string, handler: CommandHandler): void;
85
+ addProjector(projector: Projector): void;
86
+ addEventHandler(eventHandler: EventHandler): void;
87
+ }
69
88
 
70
- type EventMapper$1 = Record<string, (event: EventType<any, any>, es: EventSource) => void>;
71
- declare function createEventMapper(mapper: EventMapper$1): (event: EventType<any, any>, es: EventSource) => void;
89
+ type EventMapper$1 = Record<string, (event: EventType, es: EventSource) => void>;
90
+ declare function createEventMapper(mapper: EventMapper$1): (event: EventType, es: EventSource) => void;
72
91
 
73
- type EventMapper<Ctx, T extends string, P> = Record<string, (event: EventType<T, P>, ctx?: Ctx) => void>;
74
- declare function createProjector<Ctx, T extends string, P>(name: string, mapper: EventMapper<Ctx, T, P>, initializer?: (ctx?: Ctx) => Promise<void> | void, createContext?: () => Ctx): Projector;
92
+ type EventMapper<Ctx, T extends EventType> = Record<string, (event: T, ctx?: Ctx) => void>;
93
+ declare function createProjector<Ctx, T extends EventType>(name: string, mapper: EventMapper<Ctx, T>, initializer?: (ctx?: Ctx) => Promise<void> | void, createContext?: () => Ctx): Projector;
75
94
 
76
- declare function createTestEventStore(commandHandlers: Record<string, CommandHandler<any>>, projectors?: Projector[]): {
95
+ declare function createTestEventStore(commandHandlers: Record<string, CommandHandler>, projectors?: Projector[]): {
77
96
  ___: any;
78
- given(events?: EventType<any, any>[]): Promise<void>;
79
- when<T>(command: CommandType<T> | (() => CommandType<T>)): Promise<CommandType<T>>;
80
- then<const T_1 extends string>(expectation: Error | EventType<T_1, any>[]): Promise<void>;
97
+ given(events?: EventType[]): Promise<void>;
98
+ when<T extends CommandType<any, any>>(command: T | (() => T)): Promise<T>;
99
+ then(expectation: EventType[] | Error): Promise<void>;
81
100
  };
82
101
 
83
- export { Aggregate, Command, type CommandHandler, type CommandType, Event, type EventHandler, type EventSource, type EventSourceConfig, type EventStore, type EventType, type PayloadOf, type Projector, type TypeOf, abort, createEventMapper, createEventSource, createProjector, createTestEventStore, objectToYaml };
102
+ export { Aggregate, type ApplyEvents, Command, type CommandHandler, type CommandType, Event, type EventHandler, EventSource, type EventStore, type EventType, type PayloadOf, type Projector, type TypeOf, abort, createEventMapper, createProjector, createTestEventStore, objectToYaml };
package/dist/index.js CHANGED
@@ -1,24 +1,30 @@
1
- "use strict";var $=Object.create;var f=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var q=(t,e)=>{for(var r in e)f(t,r,{get:e[r],enumerable:!0})},A=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of R(e))!Q.call(t,o)&&o!==r&&f(t,o,{get:()=>e[o],enumerable:!(s=O(e,o))||s.enumerable});return t};var F=(t,e,r)=>(r=t!=null?$(L(t)):{},A(e||!t||!t.__esModule?f(r,"default",{value:t,enumerable:!0}):r,t)),V=t=>A(f({},"__esModule",{value:!0}),t);var B={};q(B,{Aggregate:()=>S,Command:()=>Y,Event:()=>J,abort:()=>d,createEventMapper:()=>_,createEventSource:()=>j,createProjector:()=>D,createTestEventStore:()=>Z,objectToYaml:()=>E});module.exports=V(B);function w(t,e){let r=Object.assign(new Error(t),e);return r.stack,Error.captureStackTrace&&Error.captureStackTrace(r,w),r}function d(t,e){let r=w(t,e);throw Error.captureStackTrace&&Error.captureStackTrace(r,d),r}function b(t){Object.freeze(t);for(let e of Object.getOwnPropertyNames(t))t.hasOwnProperty(e)&&t[e]!==null&&(typeof t[e]=="object"||typeof t[e]=="function")&&!Object.isFrozen(t[e])&&b(t[e]);return t}var z={NODE_ENV:process.env.NODE_ENV},S=class{version=0;recordedEvents=[];replayEvents(e=[]){for(let r of e)this.applyAnEvent(r);return this}applyAnEvent(e){z.NODE_ENV==="test"&&b(e),this[e.eventName]===void 0&&(e.eventName.match(/^[$A-Z_][0-9A-Z_$]*$/i)?d(`Aggregate "${this.constructor.name}" has no method:
1
+ "use strict";var L=Object.create;var y=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,q=Object.prototype.hasOwnProperty;var F=(r,e)=>{for(var t in e)y(r,t,{get:e[t],enumerable:!0})},N=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Q(e))!q.call(r,o)&&o!==t&&y(r,o,{get:()=>e[o],enumerable:!(n=z(e,o))||n.enumerable});return r};var V=(r,e,t)=>(t=r!=null?L(R(r)):{},N(e||!r||!r.__esModule?y(t,"default",{value:r,enumerable:!0}):t,r)),Y=r=>N(y({},"__esModule",{value:!0}),r);var K={};F(K,{Aggregate:()=>j,Command:()=>U,Event:()=>W,EventSource:()=>v,abort:()=>l,createEventMapper:()=>I,createProjector:()=>$,createTestEventStore:()=>G,objectToYaml:()=>f});module.exports=Y(K);function w(r,e){let t=Object.assign(new Error(r),e);return t.stack,Error.captureStackTrace&&Error.captureStackTrace(t,w),t}function l(r,e){let t=w(r,e);throw Error.captureStackTrace&&Error.captureStackTrace(t,l),t}function P(r){Object.freeze(r);for(let e of Object.getOwnPropertyNames(r))r.hasOwnProperty(e)&&r[e]!==null&&(typeof r[e]=="object"||typeof r[e]=="function")&&!Object.isFrozen(r[e])&&P(r[e]);return r}var J={NODE_ENV:process.env.NODE_ENV},j=class{#e=0;#t=[];replayEvents(e=[]){for(let t of e)this.applyAnEvent(t);return this}applyAnEvent(e){J.NODE_ENV==="test"&&P(e);let t=this.apply[e.eventName];t==null&&(e.eventName.match(/^[$A-Z_][0-9A-Z_$]*$/i)?l(`Aggregate "${this.constructor.name}" has no method:
2
2
 
3
- ${e.eventName}(event) {
4
- // Code goes here...
5
- }`):d(`Aggregate "${this.constructor.name}" has no method:
3
+ apply = {
4
+ ${e.eventName}(event) {
5
+ // Code goes here...
6
+ }
7
+ // ...
8
+ }`):l(`Aggregate "${this.constructor.name}" has no method:
6
9
 
7
- ['${e.eventName}'](event) {
8
- // Code goes here...
9
- }`));try{this[e.eventName](e)}catch(r){r instanceof Error&&console.error(`An error occurred inside your "%s" function:
10
- `,e.eventName,r.stack?.split(`
11
- `).map(s=>` ${s}`).join(`
12
- `))}finally{this.version++}return this}recordThat(e){let r={...e,version:this.version};return this.applyAnEvent(r),this.recordedEvents.push(r),this}releaseEvents(){return this.recordedEvents.splice(0)}};function Y(t,e){return{type:t,payload:e}}var I=require("crypto");function J(t,e,r=null){return{aggregateId:e,eventId:(0,I.randomUUID)(),eventName:t,payload:r,recordedAt:new Date,version:-1}}var H=F(require("yamlify-object")),U={indent:" ",colors:{date:m,error:m,symbol:m,string:m,number:m,boolean:m,null:m,undefined:m}};function m(t){return t}function E(t){return t instanceof Error?E({...t}):(0,H.default)(t,U).split(`
10
+ apply = {
11
+ ['${e.eventName}'](event) {
12
+ // Code goes here...
13
+ }
14
+ // ...
15
+ }`));try{t(e)}catch(n){n instanceof Error&&console.error(`An error occurred inside your "%s" function:
16
+ `,e.eventName,n.stack?.split(`
17
+ `).map(o=>` ${o}`).join(`
18
+ `))}finally{this.#e++}return this}recordThat(e){let t={...e,version:this.#e};return this.applyAnEvent(t),this.#t.push(t),this}releaseEvents(){return this.#t.splice(0)}};function U(r,e=null){return{type:r,payload:e}}var k=require("crypto");function W(r,e,t=null){return{aggregateId:e,eventId:(0,k.randomUUID)(),eventName:r,payload:t,recordedAt:new Date,version:-1}}var M=V(require("yamlify-object")),Z={indent:" ",colors:{date:d,error:d,symbol:d,string:d,number:d,boolean:d,null:d,undefined:d}};function d(r){return r}function f(r){return r instanceof Error?f({...r}):(0,M.default)(r,Z).split(`
13
19
  `).slice(1).join(`
14
- `)}function j(t){let{commandHandlers:e,eventHandlers:r=[],projectors:s=[],store:o}=t,l=[],a={async resetProjections(){await Promise.all(l),await Promise.all(s.map(n=>n.init(a)))},async dispatch(n){e[n.type]===void 0&&d(`There is no command handler for the "${n.type}" command`);let i=e[n.type];return await i(n,a),n},async loadEvents(){return await(await o).loadEvents()},async load(n,i){let v=await(await o).load(i);return v.length<=0&&d(`Aggregate(${n.constructor.name}) with ID(${i}) does not exist.`,{aggregate:n.constructor.name,aggregateId:i}),n.replayEvents(v)},async persist(n){await Promise.all(l);let i=await o,c=n.releaseEvents();await i.persist(c);for(let v of c)await Promise.all(s.map(async T=>{try{await T.update(v)}catch(p){throw p instanceof Error&&console.error(`An error occurred in one of your projections: ${T.name}, given an event`,p.stack?.split(`
15
- `).map(u=>` ${u}`).join(`
16
- `)),p}})),await Promise.all(r.map(async T=>{try{await T(v,a)}catch(p){throw p instanceof Error&&console.error(`An error occurred in one of your event handlers: ${T.name}, given an event`,p.stack?.split(`
17
- `).map(u=>` ${u}`).join(`
18
- `)),p}}))},async loadPersist(n,i,c){return await this.load(n,i),await c(n),this.persist(n)}};for(let n of s)l.push(n.init(a));return a}function _(t){return(e,r)=>t[e.eventName]?.(e,r)}var h=new WeakMap;function g(t,e){if(h.has(t)){let r=h.get(t);for(let s in e)r[s]=e[s]}else h.set(t,e)}function x(t){return h.get(t)}var P=class{constructor(){g(this,{jobs:[],state:0})}get length(){return x(this).jobs.length}async start(){let{state:e,jobs:r}=x(this);if(!(e===1||r.length<=0)){for(g(this,{state:1});r.length>0;){let s=r.shift();await Promise.resolve().then(s.handle).then(s.resolve,s.reject)}g(this,{state:0})}}push(e){return new Promise((r,s)=>{let{jobs:o}=x(this);o.push({handle:e,resolve:r,reject:s}),setImmediate(()=>this.start())})}};function W(){}function D(t,e,r=W,s){let o=new P,l=s?.();return{name:t,async init(a){await o.push(()=>r(l));let n=await a.loadEvents();await Promise.all(n.map(i=>o.push(()=>e[i.eventName]?.(i,l))))},update(a){return o.push(()=>e[a.eventName]?.(a,l))}}}var C=Symbol("__placeholder__"),y={usedTestEventStoreInTest:!1,calledThenHandler:!1};process.env.NODE_ENV==="test"&&(beforeEach(()=>{y.usedTestEventStoreInTest=!1,y.calledThenHandler=!1}),afterEach(()=>{y.usedTestEventStoreInTest&&!y.calledThenHandler&&d("It seems like you used `createTestEventStore()`\nwithout using the `await then([expected, events, go, here, ...])`")}));function M(t,e){try{return t()}catch(r){throw Error.captureStackTrace&&r instanceof Error&&Error.captureStackTrace(r,e),r}}var k=class{constructor(e=[],r=[]){this.db=e;this.producedEvents=r}name="test-recording-projector";init(){this.db.splice(0)}update(e){this.producedEvents.push(e)}};function Z(t,e=[]){y.usedTestEventStoreInTest=!0;let r=new k,s=j({store:{async load(a){return r.db.filter(n=>n.aggregateId===a)},loadEvents(){return r.db},persist(a){r.db.push(...a)}},commandHandlers:t,projectors:[...e,r]}),o,l={___:C,async given(a=[]){r.db.push(...a)},async when(a){try{return await s.dispatch(typeof a=="function"?a():a)}catch(n){return n instanceof Error&&(o=n),n}},async then(a){if(y.calledThenHandler=!0,a instanceof Error){let i=a;M(()=>expect(o).toEqual(i),l.then);return}let n=a;if(o)throw Object.keys(o).length>0&&(o.message=["With properties:",`
19
- ${E(o)}
20
+ `)}var v=class r{constructor(e,t,n,o){this.store=e;this.commandHandlers=t;this.projectors=n;this.eventHandlers=o}static builder(e){return new S(e)}static new(e,t,n,o){return new r(e,t,n,o)}async dispatch(e){return this.commandHandlers.has(e.type)||l(`There is no command handler for the "${e.type}" command`),await this.commandHandlers.get(e.type)(e,this),e}async loadEvents(){return this.store.loadEvents()}async load(e,t){let n=await this.store.load(t);return n.length<=0&&l(`Aggregate(${e.constructor.name}) with ID(${t}) does not exist.`,{aggregate:e.constructor.name,aggregateId:t}),e.replayEvents(n)}async persist(e){let t=e.releaseEvents();await this.store.persist(t);for(let n of t)await Promise.all(this.projectors.map(async o=>{try{await o.update(n)}catch(a){throw a instanceof Error&&console.error(`An error occurred in one of your projections: ${o.name}, given an event`,a.stack?.split(`
21
+ `).map(p=>` ${p}`).join(`
22
+ `)),a}})),await Promise.all(this.eventHandlers.map(async o=>{try{await o(n,this)}catch(a){throw a instanceof Error&&console.error(`An error occurred in one of your event handlers: ${o.name}, given an event`,a.stack?.split(`
23
+ `).map(p=>` ${p}`).join(`
24
+ `)),a}}))}async loadPersist(e,t,n){return await this.load(e,t),await n(e),this.persist(e)}},S=class{constructor(e){this.store=e}commandHandlers=new Map;projectors=[];eventHandlers=[];build(){return v.new(this.store,this.commandHandlers,this.projectors,this.eventHandlers)}addCommandHandler(e,t){this.commandHandlers.has(e)&&l(`A command handler for the "${e}" command already exists`),this.commandHandlers.set(e,t)}addProjector(e){this.projectors.push(e)}addEventHandler(e){this.eventHandlers.push(e)}};function I(r){return(e,t)=>r[e.eventName]?.(e,t)}var T=new WeakMap;function h(r,e){if(T.has(r)){let t=T.get(r);for(let n in e)t[n]=e[n]}else T.set(r,e)}function g(r){return T.get(r)}var x=class{constructor(){h(this,{jobs:[],state:0})}get length(){return g(this).jobs.length}async start(){let{state:e,jobs:t}=g(this);if(!(e===1||t.length<=0)){for(h(this,{state:1});t.length>0;){let n=t.shift();await Promise.resolve().then(n.handle).then(n.resolve,n.reject)}h(this,{state:0})}}push(e){return new Promise((t,n)=>{let{jobs:o}=g(this);o.push({handle:e,resolve:t,reject:n}),setImmediate(()=>this.start())})}};function B(){}function $(r,e,t=B,n){let o=new x,a=n?.();return{name:r,async init(p){await o.push(()=>t(a));let s=await p.loadEvents();await Promise.all(s.map(i=>o.push(()=>e[i.eventName]?.(i,a))))},update(p){return o.push(()=>e[p.eventName]?.(p,a))}}}var H=Symbol("__placeholder__"),u={usedTestEventStoreInTest:!1,calledThenHandler:!1};process.env.NODE_ENV==="test"&&(beforeEach(()=>{u.usedTestEventStoreInTest=!1,u.calledThenHandler=!1}),afterEach(()=>{u.usedTestEventStoreInTest&&!u.calledThenHandler&&l("It seems like you used `createTestEventStore()`\nwithout using the `await then([expected, events, go, here, ...])`")}));function D(r,e){try{return r()}catch(t){throw Error.captureStackTrace&&t instanceof Error&&Error.captureStackTrace(t,e),t}}var A=class{constructor(e=[],t=[]){this.db=e;this.producedEvents=t}name="test-recording-projector";init(){this.db.splice(0)}update(e){this.producedEvents.push(e)}};function G(r,e=[]){u.usedTestEventStoreInTest=!0;let t=new A,n=v.builder({load(s){return t.db.filter(i=>i.aggregateId===s)},loadEvents(){return t.db},persist(s){t.db.push(...s)}});for(let s of e)n.addProjector(s);n.addProjector(t);for(let[s,i]of Object.entries(r))n.addCommandHandler(s,i);let o=n.build(),a,p={___:H,async given(s=[]){t.db.push(...s)},async when(s){try{return await o.dispatch(typeof s=="function"?s():s)}catch(i){return i instanceof Error&&(a=i),i}},async then(s){if(u.calledThenHandler=!0,s instanceof Error){let b=s;D(()=>expect(a).toEqual(b),p.then);return}let i=s;if(a)throw Object.keys(a).length>0&&(a.message=["With properties:",`
25
+ ${f(a)}
20
26
 
21
27
  ---
22
28
 
23
29
  `].join(`
24
- `)),o;M(()=>{expect(n).toHaveLength(r.producedEvents.length);for(let[i,c]of n.entries()){let{aggregateId:v,eventName:T,payload:p}=r.producedEvents[i];if(c.aggregateId===C)throw new Error("Expected an `aggregateId`, but got `___` instead.");expect(c.aggregateId).toEqual(v),expect(c.eventName).toEqual(T),(c.payload===null||c.payload===void 0)&&expect(c.payload).toEqual(p);for(let u in c.payload){let N=c.payload[u];N===C?(expect(p).toHaveProperty(u),expect(p[u]).toBeDefined()):expect(p[u]).toEqual(N)}}},l.then)}};return l}0&&(module.exports={Aggregate,Command,Event,abort,createEventMapper,createEventSource,createProjector,createTestEventStore,objectToYaml});
30
+ `)),a;D(()=>{expect(i).toHaveLength(t.producedEvents.length);for(let[b,c]of i.entries()){let{aggregateId:O,eventName:_,payload:m}=t.producedEvents[b];if(c.aggregateId===H)throw new Error("Expected an `aggregateId`, but got `___` instead.");expect(c.aggregateId).toEqual(O),expect(c.eventName).toEqual(_),(c.payload===null||c.payload===void 0)&&expect(c.payload).toEqual(m);for(let E in c.payload){let C=c.payload[E];C===H?(expect(m).toHaveProperty(E),expect(m[E]).toBeDefined()):expect(m[E]).toEqual(C)}}},p.then)}};return p}0&&(module.exports={Aggregate,Command,Event,EventSource,abort,createEventMapper,createProjector,createTestEventStore,objectToYaml});
package/dist/index.mjs CHANGED
@@ -1,24 +1,30 @@
1
- function x(r,e){let t=Object.assign(new Error(r),e);return t.stack,Error.captureStackTrace&&Error.captureStackTrace(t,x),t}function d(r,e){let t=x(r,e);throw Error.captureStackTrace&&Error.captureStackTrace(t,d),t}function P(r){Object.freeze(r);for(let e of Object.getOwnPropertyNames(r))r.hasOwnProperty(e)&&r[e]!==null&&(typeof r[e]=="object"||typeof r[e]=="function")&&!Object.isFrozen(r[e])&&P(r[e]);return r}var A={NODE_ENV:process.env.NODE_ENV},C=class{version=0;recordedEvents=[];replayEvents(e=[]){for(let t of e)this.applyAnEvent(t);return this}applyAnEvent(e){A.NODE_ENV==="test"&&P(e),this[e.eventName]===void 0&&(e.eventName.match(/^[$A-Z_][0-9A-Z_$]*$/i)?d(`Aggregate "${this.constructor.name}" has no method:
1
+ function x(r,e){let t=Object.assign(new Error(r),e);return t.stack,Error.captureStackTrace&&Error.captureStackTrace(t,x),t}function l(r,e){let t=x(r,e);throw Error.captureStackTrace&&Error.captureStackTrace(t,l),t}function b(r){Object.freeze(r);for(let e of Object.getOwnPropertyNames(r))r.hasOwnProperty(e)&&r[e]!==null&&(typeof r[e]=="object"||typeof r[e]=="function")&&!Object.isFrozen(r[e])&&b(r[e]);return r}var M={NODE_ENV:process.env.NODE_ENV},A=class{#e=0;#t=[];replayEvents(e=[]){for(let t of e)this.applyAnEvent(t);return this}applyAnEvent(e){M.NODE_ENV==="test"&&b(e);let t=this.apply[e.eventName];t==null&&(e.eventName.match(/^[$A-Z_][0-9A-Z_$]*$/i)?l(`Aggregate "${this.constructor.name}" has no method:
2
2
 
3
- ${e.eventName}(event) {
4
- // Code goes here...
5
- }`):d(`Aggregate "${this.constructor.name}" has no method:
3
+ apply = {
4
+ ${e.eventName}(event) {
5
+ // Code goes here...
6
+ }
7
+ // ...
8
+ }`):l(`Aggregate "${this.constructor.name}" has no method:
6
9
 
7
- ['${e.eventName}'](event) {
8
- // Code goes here...
9
- }`));try{this[e.eventName](e)}catch(t){t instanceof Error&&console.error(`An error occurred inside your "%s" function:
10
- `,e.eventName,t.stack?.split(`
11
- `).map(a=>` ${a}`).join(`
12
- `))}finally{this.version++}return this}recordThat(e){let t={...e,version:this.version};return this.applyAnEvent(t),this.recordedEvents.push(t),this}releaseEvents(){return this.recordedEvents.splice(0)}};function z(r,e){return{type:r,payload:e}}import{randomUUID as I}from"crypto";function U(r,e,t=null){return{aggregateId:e,eventId:I(),eventName:r,payload:t,recordedAt:new Date,version:-1}}import H from"yamlify-object";var _={indent:" ",colors:{date:m,error:m,symbol:m,string:m,number:m,boolean:m,null:m,undefined:m}};function m(r){return r}function w(r){return r instanceof Error?w({...r}):H(r,_).split(`
10
+ apply = {
11
+ ['${e.eventName}'](event) {
12
+ // Code goes here...
13
+ }
14
+ // ...
15
+ }`));try{t(e)}catch(n){n instanceof Error&&console.error(`An error occurred inside your "%s" function:
16
+ `,e.eventName,n.stack?.split(`
17
+ `).map(o=>` ${o}`).join(`
18
+ `))}finally{this.#e++}return this}recordThat(e){let t={...e,version:this.#e};return this.applyAnEvent(t),this.#t.push(t),this}releaseEvents(){return this.#t.splice(0)}};function J(r,e=null){return{type:r,payload:e}}import{randomUUID as I}from"crypto";function Z(r,e,t=null){return{aggregateId:e,eventId:I(),eventName:r,payload:t,recordedAt:new Date,version:-1}}import $ from"yamlify-object";var D={indent:" ",colors:{date:d,error:d,symbol:d,string:d,number:d,boolean:d,null:d,undefined:d}};function d(r){return r}function w(r){return r instanceof Error?w({...r}):$(r,D).split(`
13
19
  `).slice(1).join(`
14
- `)}function k(r){let{commandHandlers:e,eventHandlers:t=[],projectors:a=[],store:s}=r,l=[],o={async resetProjections(){await Promise.all(l),await Promise.all(a.map(n=>n.init(o)))},async dispatch(n){e[n.type]===void 0&&d(`There is no command handler for the "${n.type}" command`);let i=e[n.type];return await i(n,o),n},async loadEvents(){return await(await s).loadEvents()},async load(n,i){let v=await(await s).load(i);return v.length<=0&&d(`Aggregate(${n.constructor.name}) with ID(${i}) does not exist.`,{aggregate:n.constructor.name,aggregateId:i}),n.replayEvents(v)},async persist(n){await Promise.all(l);let i=await s,c=n.releaseEvents();await i.persist(c);for(let v of c)await Promise.all(a.map(async T=>{try{await T.update(v)}catch(p){throw p instanceof Error&&console.error(`An error occurred in one of your projections: ${T.name}, given an event`,p.stack?.split(`
15
- `).map(u=>` ${u}`).join(`
16
- `)),p}})),await Promise.all(t.map(async T=>{try{await T(v,o)}catch(p){throw p instanceof Error&&console.error(`An error occurred in one of your event handlers: ${T.name}, given an event`,p.stack?.split(`
17
- `).map(u=>` ${u}`).join(`
18
- `)),p}}))},async loadPersist(n,i,c){return await this.load(n,i),await c(n),this.persist(n)}};for(let n of a)l.push(n.init(o));return o}function D(r){return(e,t)=>r[e.eventName]?.(e,t)}var f=new WeakMap;function E(r,e){if(f.has(r)){let t=f.get(r);for(let a in e)t[a]=e[a]}else f.set(r,e)}function h(r){return f.get(r)}var g=class{constructor(){E(this,{jobs:[],state:0})}get length(){return h(this).jobs.length}async start(){let{state:e,jobs:t}=h(this);if(!(e===1||t.length<=0)){for(E(this,{state:1});t.length>0;){let a=t.shift();await Promise.resolve().then(a.handle).then(a.resolve,a.reject)}E(this,{state:0})}}push(e){return new Promise((t,a)=>{let{jobs:s}=h(this);s.push({handle:e,resolve:t,reject:a}),setImmediate(()=>this.start())})}};function M(){}function $(r,e,t=M,a){let s=new g,l=a?.();return{name:r,async init(o){await s.push(()=>t(l));let n=await o.loadEvents();await Promise.all(n.map(i=>s.push(()=>e[i.eventName]?.(i,l))))},update(o){return s.push(()=>e[o.eventName]?.(o,l))}}}var b=Symbol("__placeholder__"),y={usedTestEventStoreInTest:!1,calledThenHandler:!1};process.env.NODE_ENV==="test"&&(beforeEach(()=>{y.usedTestEventStoreInTest=!1,y.calledThenHandler=!1}),afterEach(()=>{y.usedTestEventStoreInTest&&!y.calledThenHandler&&d("It seems like you used `createTestEventStore()`\nwithout using the `await then([expected, events, go, here, ...])`")}));function N(r,e){try{return r()}catch(t){throw Error.captureStackTrace&&t instanceof Error&&Error.captureStackTrace(t,e),t}}var S=class{constructor(e=[],t=[]){this.db=e;this.producedEvents=t}name="test-recording-projector";init(){this.db.splice(0)}update(e){this.producedEvents.push(e)}};function le(r,e=[]){y.usedTestEventStoreInTest=!0;let t=new S,a=k({store:{async load(o){return t.db.filter(n=>n.aggregateId===o)},loadEvents(){return t.db},persist(o){t.db.push(...o)}},commandHandlers:r,projectors:[...e,t]}),s,l={___:b,async given(o=[]){t.db.push(...o)},async when(o){try{return await a.dispatch(typeof o=="function"?o():o)}catch(n){return n instanceof Error&&(s=n),n}},async then(o){if(y.calledThenHandler=!0,o instanceof Error){let i=o;N(()=>expect(s).toEqual(i),l.then);return}let n=o;if(s)throw Object.keys(s).length>0&&(s.message=["With properties:",`
19
- ${w(s)}
20
+ `)}var u=class r{constructor(e,t,n,o){this.store=e;this.commandHandlers=t;this.projectors=n;this.eventHandlers=o}static builder(e){return new P(e)}static new(e,t,n,o){return new r(e,t,n,o)}async dispatch(e){return this.commandHandlers.has(e.type)||l(`There is no command handler for the "${e.type}" command`),await this.commandHandlers.get(e.type)(e,this),e}async loadEvents(){return this.store.loadEvents()}async load(e,t){let n=await this.store.load(t);return n.length<=0&&l(`Aggregate(${e.constructor.name}) with ID(${t}) does not exist.`,{aggregate:e.constructor.name,aggregateId:t}),e.replayEvents(n)}async persist(e){let t=e.releaseEvents();await this.store.persist(t);for(let n of t)await Promise.all(this.projectors.map(async o=>{try{await o.update(n)}catch(a){throw a instanceof Error&&console.error(`An error occurred in one of your projections: ${o.name}, given an event`,a.stack?.split(`
21
+ `).map(p=>` ${p}`).join(`
22
+ `)),a}})),await Promise.all(this.eventHandlers.map(async o=>{try{await o(n,this)}catch(a){throw a instanceof Error&&console.error(`An error occurred in one of your event handlers: ${o.name}, given an event`,a.stack?.split(`
23
+ `).map(p=>` ${p}`).join(`
24
+ `)),a}}))}async loadPersist(e,t,n){return await this.load(e,t),await n(e),this.persist(e)}},P=class{constructor(e){this.store=e}commandHandlers=new Map;projectors=[];eventHandlers=[];build(){return u.new(this.store,this.commandHandlers,this.projectors,this.eventHandlers)}addCommandHandler(e,t){this.commandHandlers.has(e)&&l(`A command handler for the "${e}" command already exists`),this.commandHandlers.set(e,t)}addProjector(e){this.projectors.push(e)}addEventHandler(e){this.eventHandlers.push(e)}};function O(r){return(e,t)=>r[e.eventName]?.(e,t)}var y=new WeakMap;function f(r,e){if(y.has(r)){let t=y.get(r);for(let n in e)t[n]=e[n]}else y.set(r,e)}function T(r){return y.get(r)}var h=class{constructor(){f(this,{jobs:[],state:0})}get length(){return T(this).jobs.length}async start(){let{state:e,jobs:t}=T(this);if(!(e===1||t.length<=0)){for(f(this,{state:1});t.length>0;){let n=t.shift();await Promise.resolve().then(n.handle).then(n.resolve,n.reject)}f(this,{state:0})}}push(e){return new Promise((t,n)=>{let{jobs:o}=T(this);o.push({handle:e,resolve:t,reject:n}),setImmediate(()=>this.start())})}};function _(){}function L(r,e,t=_,n){let o=new h,a=n?.();return{name:r,async init(p){await o.push(()=>t(a));let s=await p.loadEvents();await Promise.all(s.map(i=>o.push(()=>e[i.eventName]?.(i,a))))},update(p){return o.push(()=>e[p.eventName]?.(p,a))}}}var j=Symbol("__placeholder__"),v={usedTestEventStoreInTest:!1,calledThenHandler:!1};process.env.NODE_ENV==="test"&&(beforeEach(()=>{v.usedTestEventStoreInTest=!1,v.calledThenHandler=!1}),afterEach(()=>{v.usedTestEventStoreInTest&&!v.calledThenHandler&&l("It seems like you used `createTestEventStore()`\nwithout using the `await then([expected, events, go, here, ...])`")}));function C(r,e){try{return r()}catch(t){throw Error.captureStackTrace&&t instanceof Error&&Error.captureStackTrace(t,e),t}}var S=class{constructor(e=[],t=[]){this.db=e;this.producedEvents=t}name="test-recording-projector";init(){this.db.splice(0)}update(e){this.producedEvents.push(e)}};function ve(r,e=[]){v.usedTestEventStoreInTest=!0;let t=new S,n=u.builder({load(s){return t.db.filter(i=>i.aggregateId===s)},loadEvents(){return t.db},persist(s){t.db.push(...s)}});for(let s of e)n.addProjector(s);n.addProjector(t);for(let[s,i]of Object.entries(r))n.addCommandHandler(s,i);let o=n.build(),a,p={___:j,async given(s=[]){t.db.push(...s)},async when(s){try{return await o.dispatch(typeof s=="function"?s():s)}catch(i){return i instanceof Error&&(a=i),i}},async then(s){if(v.calledThenHandler=!0,s instanceof Error){let g=s;C(()=>expect(a).toEqual(g),p.then);return}let i=s;if(a)throw Object.keys(a).length>0&&(a.message=["With properties:",`
25
+ ${w(a)}
20
26
 
21
27
  ---
22
28
 
23
29
  `].join(`
24
- `)),s;N(()=>{expect(n).toHaveLength(t.producedEvents.length);for(let[i,c]of n.entries()){let{aggregateId:v,eventName:T,payload:p}=t.producedEvents[i];if(c.aggregateId===b)throw new Error("Expected an `aggregateId`, but got `___` instead.");expect(c.aggregateId).toEqual(v),expect(c.eventName).toEqual(T),(c.payload===null||c.payload===void 0)&&expect(c.payload).toEqual(p);for(let u in c.payload){let j=c.payload[u];j===b?(expect(p).toHaveProperty(u),expect(p[u]).toBeDefined()):expect(p[u]).toEqual(j)}}},l.then)}};return l}export{C as Aggregate,z as Command,U as Event,d as abort,D as createEventMapper,k as createEventSource,$ as createProjector,le as createTestEventStore,w as objectToYaml};
30
+ `)),a;C(()=>{expect(i).toHaveLength(t.producedEvents.length);for(let[g,c]of i.entries()){let{aggregateId:N,eventName:k,payload:m}=t.producedEvents[g];if(c.aggregateId===j)throw new Error("Expected an `aggregateId`, but got `___` instead.");expect(c.aggregateId).toEqual(N),expect(c.eventName).toEqual(k),(c.payload===null||c.payload===void 0)&&expect(c.payload).toEqual(m);for(let E in c.payload){let H=c.payload[E];H===j?(expect(m).toHaveProperty(E),expect(m[E]).toBeDefined()):expect(m[E]).toEqual(H)}}},p.then)}};return p}export{A as Aggregate,J as Command,Z as Event,u as EventSource,l as abort,O as createEventMapper,L as createProjector,ve as createTestEventStore,w as objectToYaml};
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.4",
2
+ "version": "0.0.6",
3
3
  "name": "@robinmalfait/event-source",
4
4
  "publishConfig": {
5
5
  "access": "public"