@requence/event-sourcing 0.0.1 → 1.0.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.
Files changed (154) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunk-24xjphpk.js +51 -0
  3. package/dist/chunk-24xjphpk.js.map +10 -0
  4. package/dist/chunk-3t1vzbab.js +88 -0
  5. package/dist/chunk-3t1vzbab.js.map +10 -0
  6. package/dist/chunk-6q8mr1sg.js +13 -0
  7. package/dist/chunk-6q8mr1sg.js.map +10 -0
  8. package/dist/chunk-9psg50cb.js +22 -0
  9. package/dist/chunk-9psg50cb.js.map +10 -0
  10. package/dist/chunk-dgzw1nj9.js +50 -0
  11. package/dist/chunk-dgzw1nj9.js.map +10 -0
  12. package/dist/chunk-gq80tgvf.js +70 -0
  13. package/dist/chunk-gq80tgvf.js.map +10 -0
  14. package/dist/chunk-jd4q8fcf.js +11 -0
  15. package/dist/chunk-jd4q8fcf.js.map +10 -0
  16. package/dist/chunk-m07vf8q9.js +210 -0
  17. package/dist/chunk-m07vf8q9.js.map +10 -0
  18. package/dist/chunk-ncpk70p4.js +313 -0
  19. package/dist/chunk-ncpk70p4.js.map +10 -0
  20. package/dist/chunk-pmfzjavb.js +49 -0
  21. package/dist/chunk-pmfzjavb.js.map +10 -0
  22. package/dist/chunk-qdczt68t.js +84 -0
  23. package/dist/chunk-qdczt68t.js.map +10 -0
  24. package/dist/chunk-tfy01fah.js +34 -0
  25. package/dist/chunk-tfy01fah.js.map +10 -0
  26. package/dist/chunk-tkvj6x8k.js +389 -0
  27. package/dist/chunk-tkvj6x8k.js.map +10 -0
  28. package/dist/chunk-ty9bhdvx.js +53 -0
  29. package/dist/chunk-ty9bhdvx.js.map +10 -0
  30. package/dist/chunk-wmz6a1jk.js +233 -0
  31. package/dist/chunk-wmz6a1jk.js.map +10 -0
  32. package/dist/chunk-x90g388y.js +22 -0
  33. package/dist/chunk-x90g388y.js.map +10 -0
  34. package/dist/chunk-z388cd25.js +91 -0
  35. package/dist/chunk-z388cd25.js.map +10 -0
  36. package/dist/chunk-zf3x573k.js +65 -0
  37. package/dist/chunk-zf3x573k.js.map +10 -0
  38. package/dist/createAggregateRoot.d.ts +191 -0
  39. package/dist/createAggregateRoot.d.ts.map +1 -0
  40. package/dist/createAggregateRoot.js +18 -0
  41. package/dist/createAggregateRoot.js.map +9 -0
  42. package/dist/createCheckpointApi.d.ts +38 -0
  43. package/dist/createCheckpointApi.d.ts.map +1 -0
  44. package/dist/createCheckpointApi.js +9 -0
  45. package/dist/createCheckpointApi.js.map +9 -0
  46. package/dist/createEventListener.d.ts +46 -0
  47. package/dist/createEventListener.d.ts.map +1 -0
  48. package/dist/createEventListener.js +12 -0
  49. package/dist/createEventListener.js.map +9 -0
  50. package/dist/createEventStore.d.ts +57 -0
  51. package/dist/createEventStore.d.ts.map +1 -0
  52. package/dist/createEventStore.js +20 -0
  53. package/dist/createEventStore.js.map +9 -0
  54. package/dist/createProcessManager.d.ts +70 -0
  55. package/dist/createProcessManager.d.ts.map +1 -0
  56. package/dist/createProcessManager.js +16 -0
  57. package/dist/createProcessManager.js.map +9 -0
  58. package/dist/createProjection.d.ts +120 -0
  59. package/dist/createProjection.d.ts.map +1 -0
  60. package/dist/createProjection.js +16 -0
  61. package/dist/createProjection.js.map +9 -0
  62. package/dist/drizzle/index.d.ts +449 -0
  63. package/dist/drizzle/index.d.ts.map +1 -0
  64. package/dist/drizzle/index.js +325 -0
  65. package/dist/drizzle/index.js.map +10 -0
  66. package/dist/drizzle/postgres.d.ts +686 -0
  67. package/dist/drizzle/postgres.d.ts.map +1 -0
  68. package/dist/drizzle/postgres.js +18 -0
  69. package/dist/drizzle/postgres.js.map +9 -0
  70. package/dist/errors.d.ts +53 -0
  71. package/dist/errors.d.ts.map +1 -0
  72. package/dist/errors.js +26 -0
  73. package/dist/errors.js.map +9 -0
  74. package/dist/index.d.ts +15 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +73 -0
  77. package/dist/index.js.map +9 -0
  78. package/dist/lock.d.ts +6 -0
  79. package/dist/lock.d.ts.map +1 -0
  80. package/dist/lock.js +8 -0
  81. package/dist/lock.js.map +9 -0
  82. package/dist/memory/index.d.ts +15 -0
  83. package/dist/memory/index.d.ts.map +1 -0
  84. package/dist/memory/index.js +178 -0
  85. package/dist/memory/index.js.map +10 -0
  86. package/dist/redis/index.d.ts +2 -0
  87. package/dist/redis/index.d.ts.map +1 -0
  88. package/dist/redis/index.js +8 -0
  89. package/dist/redis/index.js.map +9 -0
  90. package/dist/redis/redisLock.d.ts +4 -0
  91. package/dist/redis/redisLock.d.ts.map +1 -0
  92. package/dist/redis/redisLock.js +8 -0
  93. package/dist/redis/redisLock.js.map +9 -0
  94. package/dist/refresh.d.ts +4 -0
  95. package/dist/refresh.d.ts.map +1 -0
  96. package/dist/refresh.js +13 -0
  97. package/dist/refresh.js.map +9 -0
  98. package/dist/replay.d.ts +4 -0
  99. package/dist/replay.d.ts.map +1 -0
  100. package/dist/replay.js +13 -0
  101. package/dist/replay.js.map +9 -0
  102. package/dist/snapshotGenerator.d.ts +79 -0
  103. package/dist/snapshotGenerator.d.ts.map +1 -0
  104. package/dist/snapshotGenerator.js +9 -0
  105. package/dist/snapshotGenerator.js.map +9 -0
  106. package/dist/superjson.d.ts +5 -0
  107. package/dist/superjson.d.ts.map +1 -0
  108. package/dist/superjson.js +12 -0
  109. package/dist/superjson.js.map +9 -0
  110. package/dist/transaction.d.ts +13 -0
  111. package/dist/transaction.d.ts.map +1 -0
  112. package/dist/transaction.js +8 -0
  113. package/dist/transaction.js.map +9 -0
  114. package/dist/utilityTypes.d.js +2 -0
  115. package/dist/utilityTypes.d.js.map +9 -0
  116. package/dist/utils.d.ts +4 -0
  117. package/dist/utils.d.ts.map +1 -0
  118. package/dist/utils.js +10 -0
  119. package/dist/utils.js.map +9 -0
  120. package/dist/wrappedEventBuilder.d.ts +37 -0
  121. package/dist/wrappedEventBuilder.d.ts.map +1 -0
  122. package/dist/wrappedEventBuilder.js +12 -0
  123. package/dist/wrappedEventBuilder.js.map +9 -0
  124. package/package.json +85 -1
  125. package/src/createAggregateRoot.ts +902 -0
  126. package/src/createCheckpointApi.ts +106 -0
  127. package/src/createEventListener.ts +118 -0
  128. package/src/createEventStore.ts +446 -0
  129. package/src/createProcessManager.ts +363 -0
  130. package/src/createProjection.ts +577 -0
  131. package/src/drizzle/index.ts +449 -0
  132. package/src/drizzle/postgres.ts +120 -0
  133. package/src/errors.ts +85 -0
  134. package/src/index.ts +45 -0
  135. package/src/lock.ts +58 -0
  136. package/src/memory/index.ts +224 -0
  137. package/src/redis/index.ts +1 -0
  138. package/src/redis/redisLock.ts +61 -0
  139. package/src/refresh.ts +19 -0
  140. package/src/replay.ts +19 -0
  141. package/src/snapshotGenerator.ts +190 -0
  142. package/src/superjson.ts +11 -0
  143. package/src/tests/aggregateRoot.spec.ts +532 -0
  144. package/src/tests/eventListener.spec.ts +57 -0
  145. package/src/tests/eventStore.spec.ts +86 -0
  146. package/src/tests/processManager.spec.ts +185 -0
  147. package/src/tests/projection.spec.ts +511 -0
  148. package/src/tests/projectionProcessManager.spec.ts +203 -0
  149. package/src/tests/setup.ts +230 -0
  150. package/src/tests/transaction.spec.ts +185 -0
  151. package/src/transaction.ts +93 -0
  152. package/src/utilityTypes.d.ts +110 -0
  153. package/src/utils.ts +43 -0
  154. package/src/wrappedEventBuilder.ts +181 -0
@@ -0,0 +1,110 @@
1
+ import type z from 'zod/v4'
2
+
3
+ export type Prettify<T> = {
4
+ [K in keyof T]: T[K]
5
+ } & {}
6
+
7
+ interface Stream {
8
+ stream: string
9
+ }
10
+
11
+ interface StreamEvents extends Stream {
12
+ events: string[]
13
+ }
14
+
15
+ interface StreamId extends Stream {
16
+ id: string
17
+ }
18
+
19
+ interface StreamIdEvents extends StreamEvents {
20
+ id: string
21
+ }
22
+
23
+ export type BaseInputEvent<Type extends string = string, Payload = unknown> = {
24
+ type: Type
25
+ payload: Payload
26
+ metadata?: Record<string, unknown>
27
+ causationId?: string
28
+ correlationId?: string
29
+ actorId?: string
30
+ schemaVersion: number
31
+ }
32
+
33
+ type LatestEvent<
34
+ Event extends EventTemplate,
35
+ LatestVersion = Max<Event['version']>,
36
+ Schema = Event extends { version: LatestVersion } ? Event['schema'] : never,
37
+ > = LatestVersion extends number
38
+ ? BaseOutputEvent<Event['type'], LatestVersion, z.output<Schema>>
39
+ : never
40
+
41
+ export type AllEvents<Event extends EventTemplate> = {
42
+ [E in Event as E['type']]: LatestEvent<E>
43
+ }[Event['type']]
44
+
45
+ export type BaseOutputEvent<
46
+ Type extends string = string,
47
+ Version extends number = number,
48
+ Payload = unknown,
49
+ > = {
50
+ position: number
51
+ type: Type
52
+ schemaVersion: Version
53
+ payload: Payload
54
+ metadata?: Record<string, any>
55
+ causationId?: string | null
56
+ actorId?: string | null
57
+ correlationId?: string | null
58
+ streamId: string
59
+ streamType: string
60
+ streamVersion: number
61
+ createdAt: Date
62
+ }
63
+
64
+ export type EventTemplate = { type: string; schema: z.ZodType; version: number }
65
+ export type OutputEvent<Event extends EventTemplate> = Prettify<
66
+ {
67
+ [K in Event as K['version']]: BaseOutputEvent<
68
+ K['type'],
69
+ K['version'],
70
+ z.output<K['schema']>
71
+ >
72
+ }[Event['version']]
73
+ >
74
+
75
+ export type OutputEvents<Event extends EventTemplate> = Prettify<
76
+ {
77
+ [E in Event as E['type']]: OutputEvent<E>
78
+ }[Event['type']]
79
+ >
80
+
81
+ export type Max<N extends number, A extends any[] = []> = [N] extends [
82
+ Partial<A>['length'],
83
+ ]
84
+ ? A['length']
85
+ : Max<N, [0, ...A]>
86
+
87
+ export type EventHandlers<Events extends EventTemplate, Helpers = never> = {
88
+ [K in Events as `on${K['type']}`]?: (
89
+ ...args: [Helpers] extends [never]
90
+ ? [event: OutputEvent<K>]
91
+ : [event: OutputEvent<K>, helpers: Helpers]
92
+ ) => MaybePromise<void>
93
+ }
94
+
95
+ export type AfterEffectHandlers<
96
+ Events extends EventTemplate,
97
+ Helpers = never,
98
+ > = {
99
+ [K in Events as `after${K['type']}`]?: (
100
+ ...args: [Helpers] extends [never]
101
+ ? [event: OutputEvent<K>]
102
+ : [event: OutputEvent<K>, helpers: Helpers]
103
+ ) => MaybePromise<void>
104
+ }
105
+
106
+ export type Merge<A, B> = Prettify<Omit<A, keyof B> & B>
107
+ export type Keys<T> = {
108
+ [K in keyof T]: T[K] extends true ? K : never
109
+ }[keyof T]
110
+ export type MaybePromise<T> = T | Promise<T>
package/src/utils.ts ADDED
@@ -0,0 +1,43 @@
1
+ import type { MaybePromise } from './utilityTypes.js'
2
+
3
+ export async function normalizeArray<T>(
4
+ result: MaybePromise<void | T | T[]> | Iterable<T> | AsyncIterable<T>,
5
+ onItem?: (item: T) => void,
6
+ ): Promise<T[]> {
7
+ const awaited = (await result) as any
8
+
9
+ // If it's explicitly void/undefined, normalize to empty array
10
+ if (typeof awaited === 'undefined') {
11
+ return []
12
+ }
13
+
14
+ // Async iterable
15
+ if (typeof awaited[Symbol.asyncIterator] === 'function') {
16
+ const out: T[] = []
17
+ for await (const item of awaited as AsyncIterable<T>) {
18
+ out.push(item)
19
+ onItem?.(item)
20
+ }
21
+ return out
22
+ }
23
+
24
+ // Sync iterable (this also covers arrays)
25
+ if (typeof awaited[Symbol.iterator] === 'function') {
26
+ return Array.from(awaited as Iterable<T>)
27
+ }
28
+
29
+ // Plain single value
30
+ return [awaited as T]
31
+ }
32
+
33
+ export async function awaitAll(getPromise: () => Promise<any>) {
34
+ let currentPromise = getPromise()
35
+ while (true) {
36
+ await currentPromise
37
+ const nextPromise = getPromise()
38
+ if (nextPromise === currentPromise) {
39
+ break
40
+ }
41
+ currentPromise = nextPromise
42
+ }
43
+ }
@@ -0,0 +1,181 @@
1
+ import type { z } from 'zod/v4'
2
+
3
+ import type { EventValidationError } from './errors.ts'
4
+ import type {
5
+ BaseInputEvent,
6
+ EventTemplate,
7
+ Max,
8
+ MaybePromise,
9
+ } from './utilityTypes.js'
10
+
11
+ export type WrappedEvent<E extends EventTemplate = EventTemplate> = {
12
+ withCausationId(causationId: string | null | undefined): WrappedEvent<E>
13
+ withDefaultCausationId(
14
+ causationId: string | null | undefined,
15
+ ): WrappedEvent<E>
16
+ withCorrelationId(correlationId: string | null | undefined): WrappedEvent<E>
17
+ withDefaultCorrelationId(
18
+ correlationId: string | null | undefined,
19
+ ): WrappedEvent<E>
20
+ withActorId(actorId: string | null | undefined): WrappedEvent<E>
21
+ withDefaultActorId(actorId: string | null | undefined): WrappedEvent<E>
22
+ withMetadata(
23
+ metadata: Record<string, any> | null | undefined,
24
+ ): WrappedEvent<E>
25
+ withDefaultMetadata(
26
+ metadata: Record<string, any> | null | undefined,
27
+ ): WrappedEvent<E>
28
+ withAdditionalMetadata(
29
+ metadata: Record<string, any> | null | undefined,
30
+ ): WrappedEvent<E>
31
+ onValidationError(
32
+ errorHandler: (error: EventValidationError) => MaybePromise<void>,
33
+ ): WrappedEvent<E>
34
+ readonly type: string
35
+ }
36
+
37
+ const eventInternalsSymbol = Symbol.for('event-internals')
38
+
39
+ function getInternals(event: WrappedEvent) {
40
+ return (event as any)[eventInternalsSymbol] as {
41
+ event: Omit<BaseInputEvent, 'schemaVersion'>
42
+ errorHandler?: (error: EventValidationError) => MaybePromise<void>
43
+ }
44
+ }
45
+
46
+ export function unwrapEvent<E extends EventTemplate = EventTemplate>(
47
+ event: WrappedEvent<E>,
48
+ ) {
49
+ return getInternals(event).event as {
50
+ [K in E as K['type']]: Omit<
51
+ BaseInputEvent<K['type'], z.output<K['schema']>>,
52
+ 'schemaVersion'
53
+ >
54
+ }[E['type']]
55
+ }
56
+
57
+ export async function handleEventError(
58
+ event: WrappedEvent,
59
+ error: EventValidationError,
60
+ ) {
61
+ await getInternals(event).errorHandler?.(error)
62
+ }
63
+
64
+ type LatestSchema<
65
+ Event extends EventTemplate,
66
+ LatestVersion = Max<Event['version']>,
67
+ Schema = Event extends { version: LatestVersion } ? Event['schema'] : never,
68
+ > = LatestVersion extends number ? z.input<Schema> : never
69
+
70
+ type EventMap<T extends EventTemplate> = {
71
+ [K in T as K['type']]: LatestSchema<K>
72
+ }
73
+
74
+ export type WrappedEventBuilder<Event extends EventTemplate> = {
75
+ <
76
+ Type extends Event['type'],
77
+ LatestVersion = Max<
78
+ Event extends { type: Type } ? Event['version'] : never
79
+ >,
80
+ Schema = Event extends { type: Type; version: LatestVersion }
81
+ ? Event['schema']
82
+ : never,
83
+ >(
84
+ ...args: z.input<Schema> extends null
85
+ ? [type: Type, payload?: null]
86
+ : [type: Type, payload: z.input<Schema>]
87
+ ): WrappedEvent
88
+ $inferPayload: EventMap<Event>
89
+ }
90
+
91
+ export function wrappedEventBuilder(
92
+ type: string,
93
+ payload: unknown,
94
+ ): WrappedEvent
95
+ export function wrappedEventBuilder(event: BaseInputEvent): WrappedEvent
96
+ export function wrappedEventBuilder(
97
+ type: string | BaseInputEvent,
98
+ payload?: unknown,
99
+ ): WrappedEvent {
100
+ let errorHandler: (error: EventValidationError) => MaybePromise<void>
101
+ const event: Omit<BaseInputEvent, 'schemaVersion'> =
102
+ typeof type === 'string'
103
+ ? {
104
+ type,
105
+ payload: payload ?? null,
106
+ }
107
+ : type
108
+
109
+ return {
110
+ withCausationId(causationId) {
111
+ if (causationId) {
112
+ event.causationId = causationId
113
+ }
114
+ return this
115
+ },
116
+ withDefaultCausationId(causationId) {
117
+ if (causationId && !event.causationId) {
118
+ event.causationId = causationId
119
+ }
120
+ return this
121
+ },
122
+ withCorrelationId(correlationId) {
123
+ if (correlationId) {
124
+ event.correlationId = correlationId
125
+ }
126
+ return this
127
+ },
128
+ withDefaultCorrelationId(correlationId) {
129
+ if (correlationId && !event.correlationId) {
130
+ event.correlationId = correlationId
131
+ }
132
+ return this
133
+ },
134
+ withActorId(actorId) {
135
+ if (actorId) {
136
+ event.actorId = actorId
137
+ }
138
+ return this
139
+ },
140
+ withDefaultActorId(actorId) {
141
+ if (actorId && !event.actorId) {
142
+ event.actorId = actorId
143
+ }
144
+ return this
145
+ },
146
+ withMetadata(metadata) {
147
+ if (metadata) {
148
+ event.metadata = metadata
149
+ }
150
+ return this
151
+ },
152
+ withDefaultMetadata(metadata) {
153
+ if (metadata && !event.metadata) {
154
+ event.metadata = metadata
155
+ }
156
+ return this
157
+ },
158
+ withAdditionalMetadata(metadata) {
159
+ if (!metadata) {
160
+ return this
161
+ }
162
+ if (!event.metadata) {
163
+ event.metadata = metadata
164
+ } else {
165
+ event.metadata = Object.assign(event.metadata, metadata)
166
+ }
167
+
168
+ return this
169
+ },
170
+ onValidationError(handler) {
171
+ errorHandler = handler
172
+ return this
173
+ },
174
+
175
+ get [eventInternalsSymbol]() {
176
+ return { event, errorHandler }
177
+ },
178
+
179
+ type,
180
+ } as WrappedEvent
181
+ }