@requence/event-sourcing 1.4.1 → 1.5.1
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 +6 -5
- package/dist/{chunk-24xjphpk.js → chunk-06anxtk6.js} +6 -6
- package/dist/{chunk-24xjphpk.js.map → chunk-06anxtk6.js.map} +2 -2
- package/dist/{chunk-263c07sn.js → chunk-1mr4cwpw.js} +8 -8
- package/dist/{chunk-263c07sn.js.map → chunk-1mr4cwpw.js.map} +2 -2
- package/dist/{chunk-3ejt4h7x.js → chunk-2wqpktzp.js} +78 -66
- package/dist/chunk-2wqpktzp.js.map +10 -0
- package/dist/{chunk-dgzw1nj9.js → chunk-467qtkth.js} +8 -3
- package/dist/chunk-467qtkth.js.map +10 -0
- package/dist/chunk-6dn6wxg7.js +11 -0
- package/dist/{chunk-jd4q8fcf.js.map → chunk-6dn6wxg7.js.map} +2 -2
- package/dist/{chunk-pc1q4se9.js → chunk-9qtjz725.js} +2 -2
- package/dist/{chunk-pc1q4se9.js.map → chunk-9qtjz725.js.map} +2 -2
- package/dist/{chunk-tfy01fah.js → chunk-c7sytwpp.js} +4 -4
- package/dist/{chunk-tfy01fah.js.map → chunk-c7sytwpp.js.map} +2 -2
- package/dist/{chunk-vvv14qxy.js → chunk-d6jqbrq2.js} +33 -31
- package/dist/{chunk-vvv14qxy.js.map → chunk-d6jqbrq2.js.map} +3 -3
- package/dist/{chunk-vep2byx4.js → chunk-f95c3da4.js} +77 -64
- package/dist/chunk-f95c3da4.js.map +10 -0
- package/dist/chunk-fpjnk143.js +13 -0
- package/dist/{chunk-6q8mr1sg.js.map → chunk-fpjnk143.js.map} +2 -2
- package/dist/{chunk-8qn1nqnh.js → chunk-fxb9fbvz.js} +9 -9
- package/dist/{chunk-8qn1nqnh.js.map → chunk-fxb9fbvz.js.map} +2 -2
- package/dist/chunk-hmvwn02w.js +22 -0
- package/dist/{chunk-6yrb30rx.js.map → chunk-hmvwn02w.js.map} +2 -2
- package/dist/{chunk-ty9bhdvx.js → chunk-j4mwjx07.js} +5 -3
- package/dist/chunk-j4mwjx07.js.map +10 -0
- package/dist/{chunk-391m4mfp.js → chunk-jw9e0fr0.js} +13 -13
- package/dist/{chunk-391m4mfp.js.map → chunk-jw9e0fr0.js.map} +2 -2
- package/dist/chunk-mbxxvskx.js +67 -0
- package/dist/chunk-mbxxvskx.js.map +10 -0
- package/dist/{chunk-yn2sjcg3.js → chunk-nrhw3kde.js} +57 -8
- package/dist/chunk-nrhw3kde.js.map +10 -0
- package/dist/{chunk-57b88rt5.js → chunk-pcggjrxr.js} +32 -32
- package/dist/{chunk-57b88rt5.js.map → chunk-pcggjrxr.js.map} +2 -2
- package/dist/chunk-tkwe4r0y.js +22 -0
- package/dist/{chunk-2fe8jjdc.js.map → chunk-tkwe4r0y.js.map} +2 -2
- package/dist/{chunk-z388cd25.js → chunk-zkz6ew8c.js} +5 -5
- package/dist/{chunk-z388cd25.js.map → chunk-zkz6ew8c.js.map} +2 -2
- package/dist/createAggregateRoot.d.ts +1 -1
- package/dist/createAggregateRoot.d.ts.map +1 -1
- package/dist/createAggregateRoot.js +15 -14
- package/dist/createAggregateRoot.js.map +1 -1
- package/dist/createCheckpointApi.d.ts +30 -0
- package/dist/createCheckpointApi.d.ts.map +1 -1
- package/dist/createCheckpointApi.js +5 -5
- package/dist/createCheckpointApi.js.map +1 -1
- package/dist/createEventListener.js +8 -8
- package/dist/createEventListener.js.map +1 -1
- package/dist/createEventStore.js +16 -16
- package/dist/createEventStore.js.map +1 -1
- package/dist/createProcessManager.d.ts.map +1 -1
- package/dist/createProcessManager.js +12 -12
- package/dist/createProcessManager.js.map +1 -1
- package/dist/createProjection.d.ts.map +1 -1
- package/dist/createProjection.js +12 -12
- package/dist/createProjection.js.map +1 -1
- package/dist/drizzle/index.js +132 -132
- package/dist/drizzle/index.js.map +2 -2
- package/dist/drizzle/postgres.js +14 -14
- package/dist/drizzle/postgres.js.map +1 -1
- package/dist/errors.js +24 -24
- package/dist/errors.js.map +1 -1
- package/dist/index.js +63 -63
- package/dist/index.js.map +1 -1
- package/dist/lock.d.ts +11 -3
- package/dist/lock.d.ts.map +1 -1
- package/dist/lock.js +4 -2
- package/dist/lock.js.map +1 -1
- package/dist/memory/index.d.ts +14 -3
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +52 -45
- package/dist/memory/index.js.map +3 -3
- package/dist/memory/index.spec.d.ts +2 -0
- package/dist/memory/index.spec.d.ts.map +1 -0
- package/dist/redis/index.js +5 -4
- package/dist/redis/index.js.map +1 -1
- package/dist/redis/redisLock.d.ts +1 -1
- package/dist/redis/redisLock.d.ts.map +1 -1
- package/dist/redis/redisLock.js +5 -4
- package/dist/redis/redisLock.js.map +1 -1
- package/dist/refresh.js +9 -9
- package/dist/refresh.js.map +1 -1
- package/dist/replay.js +9 -9
- package/dist/replay.js.map +1 -1
- package/dist/snapshotGenerator.js +2 -2
- package/dist/superjson.js +8 -8
- package/dist/superjson.js.map +1 -1
- package/dist/surreal/index.d.ts +35 -0
- package/dist/surreal/index.d.ts.map +1 -0
- package/dist/surreal/index.js +415 -0
- package/dist/surreal/index.js.map +10 -0
- package/dist/surreal/index.spec.d.ts +2 -0
- package/dist/surreal/index.spec.d.ts.map +1 -0
- package/dist/surreal/schema.d.ts +12 -0
- package/dist/surreal/schema.d.ts.map +1 -0
- package/dist/surreal/schema.js +12 -0
- package/dist/surreal/schema.js.map +9 -0
- package/dist/tests/projectionMultiInstance.spec.d.ts +2 -0
- package/dist/tests/projectionMultiInstance.spec.d.ts.map +1 -0
- package/dist/tests/storageDriverContract.d.ts +19 -0
- package/dist/tests/storageDriverContract.d.ts.map +1 -0
- package/dist/transaction.js +1 -1
- package/dist/utils.js +6 -6
- package/dist/utils.js.map +1 -1
- package/dist/wrappedEventBuilder.js +8 -8
- package/dist/wrappedEventBuilder.js.map +1 -1
- package/package.json +19 -10
- package/src/createAggregateRoot.ts +24 -5
- package/src/createCheckpointApi.ts +98 -0
- package/src/createProcessManager.ts +7 -6
- package/src/createProjection.ts +91 -65
- package/src/lock.ts +17 -3
- package/src/memory/index.spec.ts +4 -0
- package/src/memory/index.ts +55 -29
- package/src/redis/redisLock.ts +6 -2
- package/src/surreal/index.spec.ts +152 -0
- package/src/surreal/index.ts +604 -0
- package/src/surreal/schema.ts +68 -0
- package/src/tests/aggregateRoot.spec.ts +48 -3
- package/src/tests/eventStore.spec.ts +1 -3
- package/src/tests/processManagerMultiInstance.spec.ts +18 -7
- package/src/tests/projectionMultiInstance.spec.ts +283 -0
- package/src/tests/storageDriverContract.ts +612 -0
- package/dist/chunk-2fe8jjdc.js +0 -22
- package/dist/chunk-3ejt4h7x.js.map +0 -10
- package/dist/chunk-6q8mr1sg.js +0 -13
- package/dist/chunk-6yrb30rx.js +0 -22
- package/dist/chunk-dgzw1nj9.js.map +0 -10
- package/dist/chunk-jd4q8fcf.js +0 -11
- package/dist/chunk-ty9bhdvx.js.map +0 -10
- package/dist/chunk-vep2byx4.js.map +0 -10
- package/dist/chunk-yn2sjcg3.js.map +0 -10
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Build resilient, auditable systems by storing every state change as an immutable
|
|
|
13
13
|
- **Projections** — build query-optimized read models from events, with full replay support.
|
|
14
14
|
- **Process Managers** — coordinate workflows across multiple aggregates.
|
|
15
15
|
- **Event Listeners** — react to events with lightweight, stateless side effects.
|
|
16
|
-
- **Storage Adapters** — swap between an in-memory store (great for testing), PostgreSQL via Drizzle, or
|
|
16
|
+
- **Storage Adapters** — swap between an in-memory store (great for testing), PostgreSQL via Drizzle, or SurrealDB.
|
|
17
17
|
- **Type-Safe Events** — leverage Zod schemas and TypeScript for compile-time and runtime guarantees on every event shape.
|
|
18
18
|
|
|
19
19
|
## Install
|
|
@@ -66,10 +66,11 @@ console.log(totals.get(stream.streamId)) // 6
|
|
|
66
66
|
|
|
67
67
|
## Storage Adapters
|
|
68
68
|
|
|
69
|
-
| Adapter
|
|
70
|
-
|
|
71
|
-
| In-Memory
|
|
72
|
-
| PostgreSQL (Drizzle) | `@requence/event-sourcing/drizzle/postgres` | Production
|
|
69
|
+
| Adapter | Import Path | Use Case |
|
|
70
|
+
| -------------------- | ------------------------------------------- | --------------------- |
|
|
71
|
+
| In-Memory | `@requence/event-sourcing/memory` | Testing & prototyping |
|
|
72
|
+
| PostgreSQL (Drizzle) | `@requence/event-sourcing/drizzle/postgres` | Production |
|
|
73
|
+
| SurrealDB | `@requence/event-sourcing/surreal` | Production |
|
|
73
74
|
|
|
74
75
|
## Documentation
|
|
75
76
|
|
|
@@ -4,13 +4,13 @@ var eventListenerInfoStore = new AsyncLocalStorage;
|
|
|
4
4
|
function withEventListenerInfo(info, handler) {
|
|
5
5
|
return eventListenerInfoStore.run(info, handler);
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function getEventListenerInfo2() {
|
|
8
8
|
return eventListenerInfoStore.getStore();
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
return Boolean(
|
|
10
|
+
function isInsideEventListener2() {
|
|
11
|
+
return Boolean(getEventListenerInfo2());
|
|
12
12
|
}
|
|
13
|
-
function
|
|
13
|
+
function createEventListener2(name = null) {
|
|
14
14
|
let eventHandlers = {};
|
|
15
15
|
let afterEffectHandlers = {};
|
|
16
16
|
let globalEventHandler;
|
|
@@ -46,6 +46,6 @@ function createEventListener(name = null) {
|
|
|
46
46
|
return api;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export {
|
|
49
|
+
export { getEventListenerInfo2, isInsideEventListener2, createEventListener2 };
|
|
50
50
|
|
|
51
|
-
//# debugId=
|
|
51
|
+
//# debugId=BB11C5A947B15D5D64756E2164756E21
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport type {\n AfterEffectHandlers,\n AllEvents,\n BaseOutputEvent,\n EventHandlers,\n EventTemplate,\n Keys,\n MaybePromise,\n Merge,\n} from './utilityTypes.js'\n\nexport type InternalEventListener = {\n apply: (event: BaseOutputEvent) => Promise<void>\n applyAfter: (event: BaseOutputEvent) => Promise<void>\n}\n\ntype EventListenerInfo = {\n name: string | null\n event: BaseOutputEvent\n}\nconst eventListenerInfoStore = new AsyncLocalStorage<EventListenerInfo>()\n\nfunction withEventListenerInfo(\n info: EventListenerInfo,\n handler: () => Promise<void>,\n) {\n return eventListenerInfoStore.run(info, handler)\n}\n\nexport function getEventListenerInfo() {\n return eventListenerInfoStore.getStore()\n}\n\nexport function isInsideEventListener() {\n return Boolean(getEventListenerInfo())\n}\n\nexport type EventListenerApi<\n Events extends EventTemplate = never,\n Flags extends {\n withEventHandlers: boolean\n withGlobalEventHandler: boolean\n withAfterEffects: boolean\n withGlobalAfterEffect: boolean\n } = {\n withEventHandlers: false\n withGlobalEventHandler: false\n withAfterEffects: false\n withGlobalAfterEffect: false\n },\n> = {\n withEventHandlers: (\n handlers: EventHandlers<Events>,\n ) => Omit<\n EventListenerApi<Events, Merge<Flags, { withEventHandlers: true }>>,\n Keys<Merge<Flags, { withEventHandlers: true }>>\n >\n withGlobalEventHandler: (\n handler: (event: AllEvents<Events>) => MaybePromise<void>,\n ) => Omit<\n EventListenerApi<Events, Merge<Flags, { withGlobalEventHandler: true }>>,\n Keys<Merge<Flags, { withGlobalEventHandler: true }>>\n >\n withAfterEffects: (\n handlers: AfterEffectHandlers<Events>,\n ) => Omit<\n EventListenerApi<Events, Merge<Flags, { withAfterEffects: true }>>,\n Keys<Merge<Flags, { withAfterEffects: true }>>\n >\n withGlobalAfterEffect: (\n handler: (event: AllEvents<Events>) => MaybePromise<void>,\n ) => Omit<\n EventListenerApi<Events, Merge<Flags, { withGlobalAfterEffect: true }>>,\n Keys<Merge<Flags, { withGlobalAfterEffect: true }>>\n >\n}\n\nexport function createEventListener(\n name: string | null = null,\n): EventListenerApi {\n let eventHandlers: EventHandlers<any> = {}\n let afterEffectHandlers: AfterEffectHandlers<any> = {}\n let globalEventHandler: (event: BaseOutputEvent) => MaybePromise<void>\n let globalAfterEffect: (event: BaseOutputEvent) => MaybePromise<void>\n const api = {\n async apply(event) {\n withEventListenerInfo({ name, event }, async () => {\n await eventHandlers[`on${event.type}`]?.(event)\n await globalEventHandler?.(event)\n })\n },\n\n async applyAfter(event) {\n await afterEffectHandlers[`after${event.type}`]?.(event)\n await globalAfterEffect?.(event)\n },\n withEventHandlers(handlers) {\n eventHandlers = handlers\n return api\n },\n withGlobalEventHandler(handler) {\n globalEventHandler = handler as any\n return api\n },\n withAfterEffects(handlers) {\n afterEffectHandlers = handlers\n return api\n },\n withGlobalAfterEffect(handler) {\n globalAfterEffect = handler as any\n return api\n },\n } as EventListenerApi & InternalEventListener\n\n return api\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA;AAsBA,IAAM,yBAAyB,IAAI;AAEnC,SAAS,qBAAqB,CAC5B,MACA,SACA;AAAA,EACA,OAAO,uBAAuB,IAAI,MAAM,OAAO;AAAA;AAG1C,SAAS,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAAA;AAsBA,IAAM,yBAAyB,IAAI;AAEnC,SAAS,qBAAqB,CAC5B,MACA,SACA;AAAA,EACA,OAAO,uBAAuB,IAAI,MAAM,OAAO;AAAA;AAG1C,SAAS,qBAAoB,GAAG;AAAA,EACrC,OAAO,uBAAuB,SAAS;AAAA;AAGlC,SAAS,sBAAqB,GAAG;AAAA,EACtC,OAAO,QAAQ,sBAAqB,CAAC;AAAA;AA2ChC,SAAS,oBAAmB,CACjC,OAAsB,MACJ;AAAA,EAClB,IAAI,gBAAoC,CAAC;AAAA,EACzC,IAAI,sBAAgD,CAAC;AAAA,EACrD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,MAAM,MAAM;AAAA,SACJ,MAAK,CAAC,OAAO;AAAA,MACjB,sBAAsB,EAAE,MAAM,MAAM,GAAG,YAAY;AAAA,QACjD,MAAM,cAAc,KAAK,MAAM,UAAU,KAAK;AAAA,QAC9C,MAAM,qBAAqB,KAAK;AAAA,OACjC;AAAA;AAAA,SAGG,WAAU,CAAC,OAAO;AAAA,MACtB,MAAM,oBAAoB,QAAQ,MAAM,UAAU,KAAK;AAAA,MACvD,MAAM,oBAAoB,KAAK;AAAA;AAAA,IAEjC,iBAAiB,CAAC,UAAU;AAAA,MAC1B,gBAAgB;AAAA,MAChB,OAAO;AAAA;AAAA,IAET,sBAAsB,CAAC,SAAS;AAAA,MAC9B,qBAAqB;AAAA,MACrB,OAAO;AAAA;AAAA,IAET,gBAAgB,CAAC,UAAU;AAAA,MACzB,sBAAsB;AAAA,MACtB,OAAO;AAAA;AAAA,IAET,qBAAqB,CAAC,SAAS;AAAA,MAC7B,oBAAoB;AAAA,MACpB,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "BB11C5A947B15D5D64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -12,8 +12,8 @@ import {
|
|
|
12
12
|
unique,
|
|
13
13
|
uuid
|
|
14
14
|
} from "drizzle-orm/pg-core";
|
|
15
|
-
var
|
|
16
|
-
var
|
|
15
|
+
var eventSourcing2 = pgSchema("event_sourcing");
|
|
16
|
+
var events2 = eventSourcing2.table("events", {
|
|
17
17
|
position: bigint({ mode: "number" }).generatedByDefaultAsIdentity().primaryKey(),
|
|
18
18
|
id: uuid().unique().notNull().defaultRandom(),
|
|
19
19
|
streamId: text().notNull(),
|
|
@@ -37,7 +37,7 @@ var events = eventSourcing.table("events", {
|
|
|
37
37
|
withCheck: sql`true`
|
|
38
38
|
})
|
|
39
39
|
]);
|
|
40
|
-
var
|
|
40
|
+
var aggregateRootSnapshots2 = eventSourcing2.table("aggregate_root_snapshots", {
|
|
41
41
|
id: uuid().primaryKey().defaultRandom(),
|
|
42
42
|
streamId: text().notNull(),
|
|
43
43
|
streamType: text().notNull(),
|
|
@@ -51,7 +51,7 @@ var aggregateRootSnapshots = eventSourcing.table("aggregate_root_snapshots", {
|
|
|
51
51
|
unique().on(table.streamType, table.streamId, table.streamVersion),
|
|
52
52
|
index().on(table.streamType, table.streamId, table.streamVersion.desc())
|
|
53
53
|
]);
|
|
54
|
-
var
|
|
54
|
+
var projectionSnapshots2 = eventSourcing2.table("projection_snapshots", {
|
|
55
55
|
id: uuid().primaryKey().defaultRandom(),
|
|
56
56
|
projectionId: text().notNull(),
|
|
57
57
|
projectionType: text().notNull(),
|
|
@@ -64,7 +64,7 @@ var projectionSnapshots = eventSourcing.table("projection_snapshots", {
|
|
|
64
64
|
unique().on(table.projectionId, table.projectionType, table.lastEventPosition),
|
|
65
65
|
index().on(table.projectionId, table.projectionType, table.lastEventPosition.desc())
|
|
66
66
|
]);
|
|
67
|
-
var
|
|
67
|
+
var checkpoints2 = eventSourcing2.table("checkpoints", {
|
|
68
68
|
id: uuid().defaultRandom().primaryKey(),
|
|
69
69
|
type: text({ enum: ["projection", "processManager"] }).notNull(),
|
|
70
70
|
name: text().notNull(),
|
|
@@ -75,7 +75,7 @@ var checkpoints = eventSourcing.table("checkpoints", {
|
|
|
75
75
|
unique().on(table.type, table.name),
|
|
76
76
|
index().on(table.type, table.name)
|
|
77
77
|
]);
|
|
78
|
-
var
|
|
78
|
+
var projectionAppliedEvents2 = eventSourcing2.table("projection_applied_events", {
|
|
79
79
|
projectionId: uuid().notNull(),
|
|
80
80
|
projectionType: text().notNull(),
|
|
81
81
|
appliedEvents: integer().notNull()
|
|
@@ -84,6 +84,6 @@ var projectionAppliedEvents = eventSourcing.table("projection_applied_events", {
|
|
|
84
84
|
index().on(table.projectionId, table.projectionType)
|
|
85
85
|
]);
|
|
86
86
|
|
|
87
|
-
export {
|
|
87
|
+
export { eventSourcing2, events2, aggregateRootSnapshots2, projectionSnapshots2, checkpoints2, projectionAppliedEvents2 };
|
|
88
88
|
|
|
89
|
-
//# debugId=
|
|
89
|
+
//# debugId=851371226DD3C06B64756E2164756E21
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { sql } from 'drizzle-orm'\nimport {\n bigint,\n index,\n integer,\n jsonb,\n pgPolicy,\n pgSchema,\n text,\n timestamp,\n unique,\n uuid,\n} from 'drizzle-orm/pg-core'\nimport type { SuperJSONResult } from 'superjson'\n\nexport const eventSourcing = pgSchema('event_sourcing')\n\nexport const events = eventSourcing.table(\n 'events',\n {\n position: bigint({ mode: 'number' })\n .generatedByDefaultAsIdentity()\n .primaryKey(),\n id: uuid().unique().notNull().defaultRandom(),\n streamId: text().notNull(),\n streamType: text().notNull(),\n streamVersion: bigint({ mode: 'number' }).notNull(),\n type: text().notNull(),\n createdAt: timestamp().defaultNow().notNull(),\n payload: text().notNull(),\n metadata: jsonb().$type<SuperJSONResult>().notNull(),\n causationId: uuid(),\n correlationId: uuid(),\n actorId: text(),\n schemaVersion: integer().notNull(),\n },\n (table) => [\n unique().on(table.streamId, table.streamVersion, table.streamType),\n index().on(table.streamId, table.streamVersion.desc()),\n index('metadata').using('gin', sql`${table.metadata} jsonb_path_ops`),\n pgPolicy('insert only', {\n for: 'insert',\n to: 'public',\n withCheck: sql`true`,\n }),\n ],\n)\n\nexport const aggregateRootSnapshots = eventSourcing.table(\n 'aggregate_root_snapshots',\n {\n id: uuid().primaryKey().defaultRandom(),\n streamId: text().notNull(),\n streamType: text().notNull(),\n streamVersion: bigint({ mode: 'number' }).notNull(),\n state: text().notNull(),\n metadata: text().notNull(),\n createdAt: timestamp().defaultNow().notNull(),\n lastEventPosition: bigint({ mode: 'number' }).notNull(),\n schemaVersion: integer().notNull(),\n },\n (table) => [\n unique().on(table.streamType, table.streamId, table.streamVersion),\n index().on(table.streamType, table.streamId, table.streamVersion.desc()),\n ],\n)\n\nexport const projectionSnapshots = eventSourcing.table(\n 'projection_snapshots',\n {\n id: uuid().primaryKey().defaultRandom(),\n projectionId: text().notNull(),\n projectionType: text().notNull(),\n state: text().notNull(),\n metadata: text().notNull(),\n createdAt: timestamp().defaultNow().notNull(),\n lastEventPosition: bigint({ mode: 'number' }).notNull(),\n schemaVersion: integer().notNull(),\n },\n (table) => [\n unique().on(\n table.projectionId,\n table.projectionType,\n table.lastEventPosition,\n ),\n index().on(\n table.projectionId,\n table.projectionType,\n table.lastEventPosition.desc(),\n ),\n ],\n)\n\nexport const checkpoints = eventSourcing.table(\n 'checkpoints',\n {\n id: uuid().defaultRandom().primaryKey(),\n type: text({ enum: ['projection', 'processManager'] }).notNull(),\n name: text().notNull(),\n lastEventPosition: bigint({ mode: 'number' }).notNull(),\n metadata: text().notNull(),\n // Optimistic-concurrency guard: bumped on every write so concurrent\n // instances can detect when they raced on the same checkpoint.\n version: bigint({ mode: 'number' }).notNull().default(0),\n },\n (table) => [\n unique().on(table.type, table.name),\n index().on(table.type, table.name),\n ],\n)\n\nexport const projectionAppliedEvents = eventSourcing.table(\n 'projection_applied_events',\n {\n projectionId: uuid().notNull(),\n projectionType: text().notNull(),\n appliedEvents: integer().notNull(),\n },\n (table) => [\n unique().on(table.projectionId, table.projectionType),\n index().on(table.projectionId, table.projectionType),\n ],\n)\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,IAAM,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "851371226DD3C06B64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ValidationError2,
|
|
3
|
+
ProjectionReplayLoopError2,
|
|
4
|
+
ReplaySkipError2,
|
|
5
|
+
ProjectionEventHandlerExecutionError2
|
|
6
|
+
} from "./chunk-jw9e0fr0.js";
|
|
4
7
|
import {
|
|
5
|
-
|
|
6
|
-
} from "./chunk-
|
|
8
|
+
createCheckpointApi2
|
|
9
|
+
} from "./chunk-nrhw3kde.js";
|
|
7
10
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
isReplaying2,
|
|
12
|
+
withReplaying2
|
|
13
|
+
} from "./chunk-tkwe4r0y.js";
|
|
11
14
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
ReplaySkipError,
|
|
15
|
-
ValidationError
|
|
16
|
-
} from "./chunk-391m4mfp.js";
|
|
15
|
+
createSnapshotGenerator
|
|
16
|
+
} from "./chunk-fxb9fbvz.js";
|
|
17
17
|
|
|
18
18
|
// src/createProjection.ts
|
|
19
19
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -29,11 +29,11 @@ var projectionInfoStore = new AsyncLocalStorage;
|
|
|
29
29
|
function withProjectionInfo(info, handler) {
|
|
30
30
|
return projectionInfoStore.run(info, handler);
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function getProjectionInfo2() {
|
|
33
33
|
return projectionInfoStore.getStore();
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
return Boolean(
|
|
35
|
+
function isInsideProjection2() {
|
|
36
|
+
return Boolean(getProjectionInfo2());
|
|
37
37
|
}
|
|
38
38
|
var snapshotSchema = z.object({
|
|
39
39
|
projectionId: z.string(),
|
|
@@ -44,7 +44,7 @@ var snapshotSchema = z.object({
|
|
|
44
44
|
schemaVersion: z.int(),
|
|
45
45
|
createdAt: z.date()
|
|
46
46
|
});
|
|
47
|
-
function
|
|
47
|
+
function buildProjectionCreator2(params) {
|
|
48
48
|
return (name) => {
|
|
49
49
|
let idle = true;
|
|
50
50
|
let replaying = false;
|
|
@@ -75,57 +75,69 @@ function buildProjectionCreator(params) {
|
|
|
75
75
|
const unlocked = !exclusive ? Promise.resolve() : locks.get(event.streamId)?.catch(() => {}) ?? Promise.resolve();
|
|
76
76
|
const runner = (async () => {
|
|
77
77
|
await unlocked;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
const claimed = isReplaying2() ? null : await checkpointApi.claim(event);
|
|
79
|
+
if (claimed && !claimed.claimed) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const release = claimed?.claimed ? claimed.release : null;
|
|
83
|
+
try {
|
|
84
|
+
await withProjectionInfo({ name, event }, async () => {
|
|
85
|
+
try {
|
|
86
|
+
await handler?.(event, {
|
|
87
|
+
replaying,
|
|
88
|
+
async replayUntil(position, filterEvents) {
|
|
89
|
+
if (position >= event.position) {
|
|
90
|
+
throw new ProjectionReplayLoopError2(`Event handler on${event.type} of projection ${name} tried to replay to the future`, { name, eventHandler: `on${event.type}` }, event);
|
|
91
|
+
}
|
|
92
|
+
locks.delete(event.streamId);
|
|
93
|
+
return api.replayUntil(event.streamId, position, filterEvents);
|
|
85
94
|
}
|
|
86
|
-
|
|
87
|
-
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error instanceof ReplaySkipError2) {
|
|
98
|
+
if (isReplaying2()) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
throw new Error("ReplaySkipError should never be thrown outside replay");
|
|
88
102
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (error instanceof ReplaySkipError) {
|
|
92
|
-
if (isReplaying()) {
|
|
93
|
-
return;
|
|
103
|
+
if (!(error instanceof Error) || error instanceof ProjectionReplayLoopError2) {
|
|
104
|
+
throw error;
|
|
94
105
|
}
|
|
95
|
-
throw new
|
|
96
|
-
}
|
|
97
|
-
if (!(error instanceof Error) || error instanceof ProjectionReplayLoopError) {
|
|
98
|
-
throw error;
|
|
106
|
+
throw new ProjectionEventHandlerExecutionError2(name, `on${event.type}`, event, error);
|
|
99
107
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
throw error;
|
|
108
|
+
try {
|
|
109
|
+
await globalEventHandler?.(event);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (!(error instanceof Error)) {
|
|
112
|
+
throw error;
|
|
113
|
+
}
|
|
114
|
+
throw new ProjectionEventHandlerExecutionError2(name, "GLOBAL", event, error);
|
|
107
115
|
}
|
|
108
|
-
throw new ProjectionEventHandlerExecutionError(name, "GLOBAL", event, error);
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
if (params.snapshot && snapshotting) {
|
|
112
|
-
const appliedEvents = await params.snapshot.incrementAppliedCount({
|
|
113
|
-
projection: name,
|
|
114
|
-
id: event.streamId
|
|
115
116
|
});
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
projectionId: event.streamId,
|
|
121
|
-
lastEventPosition: event.position,
|
|
122
|
-
state: snapshot.state,
|
|
123
|
-
schemaVersion: snapshot.version,
|
|
124
|
-
createdAt: new Date
|
|
117
|
+
if (params.snapshot && snapshotting) {
|
|
118
|
+
const appliedEvents = await params.snapshot.incrementAppliedCount({
|
|
119
|
+
projection: name,
|
|
120
|
+
id: event.streamId
|
|
125
121
|
});
|
|
122
|
+
const snapshot = await snapshotting.internalCapture(event, appliedEvents);
|
|
123
|
+
if (snapshot) {
|
|
124
|
+
await params.snapshot.put({
|
|
125
|
+
projectionType: name,
|
|
126
|
+
projectionId: event.streamId,
|
|
127
|
+
lastEventPosition: event.position,
|
|
128
|
+
state: snapshot.state,
|
|
129
|
+
schemaVersion: snapshot.version,
|
|
130
|
+
createdAt: new Date
|
|
131
|
+
});
|
|
132
|
+
}
|
|
126
133
|
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
await release?.();
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
if (!release) {
|
|
139
|
+
await checkpointApi.upsert(event);
|
|
127
140
|
}
|
|
128
|
-
await checkpointApi.upsert(event);
|
|
129
141
|
})();
|
|
130
142
|
if (exclusive) {
|
|
131
143
|
locks.set(event.streamId, runner);
|
|
@@ -204,7 +216,7 @@ function buildProjectionCreator(params) {
|
|
|
204
216
|
await replayConfig.deleteAll();
|
|
205
217
|
},
|
|
206
218
|
async progressReplay(index, event) {
|
|
207
|
-
await
|
|
219
|
+
await withReplaying2(() => withHydrating(() => apply(event)));
|
|
208
220
|
if (!checkpointApi.relatedStreamEvents || checkpointApi.relatedStreamEvents.some((streamEvent) => streamEvent.events.includes(event.type))) {
|
|
209
221
|
params.onReplay?.progress?.(name, index, event);
|
|
210
222
|
}
|
|
@@ -221,7 +233,7 @@ function buildProjectionCreator(params) {
|
|
|
221
233
|
if (snapshot) {
|
|
222
234
|
const result = snapshotSchema.safeParse(snapshot);
|
|
223
235
|
if (!result.success) {
|
|
224
|
-
throw new
|
|
236
|
+
throw new ValidationError2("loaded projection snapshot does not comply with schema", result.error);
|
|
225
237
|
}
|
|
226
238
|
snapshotting.internalApply(result.data);
|
|
227
239
|
startPosition = result.data.lastEventPosition + 1;
|
|
@@ -235,7 +247,7 @@ function buildProjectionCreator(params) {
|
|
|
235
247
|
to: position
|
|
236
248
|
});
|
|
237
249
|
replaying = true;
|
|
238
|
-
await
|
|
250
|
+
await withReplaying2(async () => {
|
|
239
251
|
for await (const event of events) {
|
|
240
252
|
if (filterEvents(event)) {
|
|
241
253
|
await apply(event);
|
|
@@ -247,7 +259,7 @@ function buildProjectionCreator(params) {
|
|
|
247
259
|
async init(catchUp) {
|
|
248
260
|
idle = false;
|
|
249
261
|
relatedStreamEvents = globalEventHandler ? null : generateRelatedStreamEvents(handlers);
|
|
250
|
-
checkpointApi =
|
|
262
|
+
checkpointApi = createCheckpointApi2({
|
|
251
263
|
...params.checkpoint,
|
|
252
264
|
name,
|
|
253
265
|
relatedStreamEvents,
|
|
@@ -283,7 +295,7 @@ function buildProjectionCreator(params) {
|
|
|
283
295
|
})) : null;
|
|
284
296
|
const events = params.loadEvents(streamIds);
|
|
285
297
|
replaying = true;
|
|
286
|
-
await
|
|
298
|
+
await withReplaying2(async () => {
|
|
287
299
|
for await (const event of events) {
|
|
288
300
|
await withHydrating(() => apply(event));
|
|
289
301
|
}
|
|
@@ -295,7 +307,7 @@ function buildProjectionCreator(params) {
|
|
|
295
307
|
const events = params.loadEvents(relatedStreamEvents);
|
|
296
308
|
let index = 0;
|
|
297
309
|
replaying = true;
|
|
298
|
-
await
|
|
310
|
+
await withReplaying2(async () => {
|
|
299
311
|
for await (const event of events) {
|
|
300
312
|
await api.progressReplay(index, event);
|
|
301
313
|
index++;
|
|
@@ -308,6 +320,6 @@ function buildProjectionCreator(params) {
|
|
|
308
320
|
};
|
|
309
321
|
}
|
|
310
322
|
|
|
311
|
-
export {
|
|
323
|
+
export { getProjectionInfo2, isInsideProjection2, buildProjectionCreator2 };
|
|
312
324
|
|
|
313
|
-
//# debugId=
|
|
325
|
+
//# debugId=91F75EEEF7189F7964756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/createProjection.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport z from 'zod/v4'\n\nimport {\n type CheckpointApi,\n type CheckpointMethods,\n createCheckpointApi,\n} from './createCheckpointApi.ts'\nimport type { LoadEvents, OnProgress } from './createEventStore.ts'\nimport {\n ProjectionEventHandlerExecutionError,\n ProjectionReplayLoopError,\n ReplaySkipError,\n ValidationError,\n} from './errors.ts'\nimport { isReplaying, withReplaying } from './replay.ts'\nimport type {\n CompleteSnapshotGenerator,\n InternalSnapshotGenerator,\n SnapshotGenerator,\n} from './snapshotGenerator.ts'\nimport createSnapshotGenerator from './snapshotGenerator.ts'\nimport type {\n AllEvents,\n BaseOutputEvent,\n EventHandlers,\n EventTemplate,\n Keys,\n MaybePromise,\n Merge,\n OutputEvent,\n StreamEvents,\n} from './utilityTypes.d.ts'\n\nconst hydratingStore = new AsyncLocalStorage<boolean>()\n\nfunction isHydrating() {\n return hydratingStore.getStore() ?? false\n}\n\nasync function withHydrating(handler: () => Promise<void>) {\n await hydratingStore.run(true, handler)\n}\n\ntype ProjectionInfo = {\n name: string\n event: BaseOutputEvent\n}\nconst projectionInfoStore = new AsyncLocalStorage<ProjectionInfo>()\n\nfunction withProjectionInfo(\n info: ProjectionInfo,\n handler: () => Promise<void>,\n) {\n return projectionInfoStore.run(info, handler)\n}\n\nexport function getProjectionInfo() {\n return projectionInfoStore.getStore()\n}\n\nexport function isInsideProjection() {\n return Boolean(getProjectionInfo())\n}\n\ntype ReplayConfig = {\n deleteOne?: (id: string) => MaybePromise<void>\n deleteAll?: () => MaybePromise<void>\n}\n\ntype ProjectionEventHandlers<Events extends EventTemplate> = EventHandlers<\n Events,\n {\n replaying: boolean\n replayUntil: (\n position: number,\n filterEvents?: (event: OutputEvent<Events>) => boolean,\n ) => Promise<void>\n }\n>\n\ntype ReplayProjection<Events extends EventTemplate> = {\n replayOne: (streamId: string) => Promise<void>\n replayUntil: (\n streamId: string,\n position: number,\n filterEvents?: (event: OutputEvent<Events>) => boolean,\n ) => Promise<void>\n replay: () => Promise<void>\n}\n\nexport type InternalProjection = {\n apply: (event: BaseOutputEvent) => Promise<void>\n setRelatedStreamEvents: (\n generateRelatedStreamEvents: (\n eventHandlers: EventHandlers<EventTemplate>,\n ) => StreamEvents[],\n ) => void\n isReady(): Promise<void>\n canReplay(): boolean\n beginReplay(): Promise<void>\n progressReplay(index: number, event: BaseOutputEvent): Promise<void>\n endReplay(): void\n init(catchUp: boolean): Promise<void>\n}\n\nexport type ProjectionApi<\n Events extends EventTemplate = never,\n RConfig extends ReplayConfig = never,\n Flags extends {\n withEventHandlers: boolean\n withGlobalEventHandler: boolean\n concurrent: boolean\n withReplay: boolean\n withSnapshots: boolean\n } = {\n withEventHandlers: false\n withGlobalEventHandler: false\n concurrent: false\n withReplay: false\n withSnapshots: true\n },\n> = {\n withEventHandlers: (\n handlers: ProjectionEventHandlers<Events>,\n ) => Omit<\n ProjectionApi<Events, RConfig, Merge<Flags, { withEventHandlers: true }>>,\n Keys<Merge<Flags, { withEventHandlers: true }>>\n >\n withGlobalEventHandler: (\n handler: (\n event: AllEvents<Events>,\n methods: ReplayProjection<Events>,\n ) => MaybePromise<void>,\n ) => Omit<\n ProjectionApi<\n Events,\n RConfig,\n Merge<Flags, { withGlobalEventHandler: true }>\n >,\n Keys<Merge<Flags, { withGlobalEventHandler: true }>>\n >\n concurrent: () => Omit<\n ProjectionApi<Events, RConfig, Merge<Flags, { concurrent: true }>>,\n Keys<Merge<Flags, { concurrent: true }>>\n >\n withReplay: <Config extends ReplayConfig>(\n config: Config,\n ) => Omit<\n ProjectionApi<Events, Config, Merge<Flags, { withReplay: true }>>,\n Keys<Merge<Flags, { withReplay: true }>>\n >\n withSnapshots: (\n handler: (\n generator: SnapshotGenerator<Omit<Snapshot, 'schemaVersion' | 'state'>>,\n ) => CompleteSnapshotGenerator,\n ) => Omit<\n ProjectionApi<Events, RConfig, Merge<Flags, { withSnapshots: true }>>,\n Keys<Merge<Flags, { withSnapshots: true }>>\n >\n isReady(): Promise<void>\n} & ('deleteOne' extends keyof RConfig\n ? Pick<ReplayProjection<Events>, 'replayOne' | 'replayUntil'>\n : {}) &\n ('deleteAll' extends keyof RConfig\n ? Pick<ReplayProjection<Events>, 'replay'>\n : {})\n\nexport type ProjectionApiWithSnapshots<\n Events extends EventTemplate = never,\n RConfig extends ReplayConfig = never,\n Flags extends {\n withEventHandlers: boolean\n withGlobalEventHandler: boolean\n concurrent: boolean\n withReplay: boolean\n withSnapshots: boolean\n } = {\n withEventHandlers: false\n withGlobalEventHandler: false\n concurrent: false\n withReplay: false\n withSnapshots: false\n },\n> = ProjectionApi<Events, RConfig, Flags>\n\nconst snapshotSchema = z.object({\n projectionId: z.string(),\n projectionType: z.string(),\n lastEventPosition: z.int(),\n state: z.unknown(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n schemaVersion: z.int(),\n createdAt: z.date(),\n})\n\nexport type Snapshot = z.output<typeof snapshotSchema>\n\nexport type ProjectionSnapshotMethods = {\n get: (select: {\n projection: string\n id: string\n }) => MaybePromise<Snapshot | null | undefined>\n put: (snapshot: Snapshot) => MaybePromise<void>\n delete: (\n target: { id?: string; projection: string },\n fromPosition?: number,\n ) => MaybePromise<void>\n incrementAppliedCount: (target: {\n projection: string\n id: string\n }) => MaybePromise<number>\n}\n\nexport function buildProjectionCreator(params: {\n loadEvents: LoadEvents\n checkpoint: CheckpointMethods\n onReplay?: OnProgress\n snapshot?: ProjectionSnapshotMethods\n}): (name: string) => ProjectionApi {\n return (name) => {\n let idle = true\n let replaying = false\n let handlers: ProjectionEventHandlers<any> = {}\n let globalEventHandler:\n | ((event: BaseOutputEvent) => MaybePromise<void>)\n | null = null\n let generateRelatedStreamEvents: (\n eventHandlers: EventHandlers<any>,\n ) => StreamEvents[]\n let relatedStreamEvents: StreamEvents[] | null = null\n let exclusive = true\n let checkpointApi: CheckpointApi\n let lastEventPosition = -1\n\n let replayConfig: ReplayConfig | null = null\n\n let snapshotting:\n | (CompleteSnapshotGenerator & InternalSnapshotGenerator)\n | null = null\n\n const { promise: hydrated, resolve: resolveHydrated } =\n Promise.withResolvers<void>()\n\n const locks = new Map<string, Promise<void>>()\n const apply = async (event: BaseOutputEvent) => {\n const handler = handlers[`on${event.type}`]\n if (!handler && !globalEventHandler) {\n return Promise.resolve()\n }\n\n if (isHydrating()) {\n lastEventPosition = event.position\n } else {\n await hydrated\n // event was already applied through hydration\n if (event.position <= lastEventPosition) {\n return\n }\n }\n\n const unlocked = !exclusive\n ? Promise.resolve()\n : (locks.get(event.streamId)?.catch(() => {}) ?? Promise.resolve())\n\n const runner = (async () => {\n await unlocked\n\n // Take ownership of the event before anything observable happens, so a\n // peer applying the same event does not apply it twice. `claimed` is\n // null while replaying: a replay deliberately re-applies everything and\n // `beginReplay` leaves the stored cursor where it was, so a claim would\n // read that not-yet-rewound position and skip the whole run.\n const claimed = isReplaying() ? null : await checkpointApi.claim(event)\n\n if (claimed && !claimed.claimed) {\n return\n }\n\n const release = claimed?.claimed ? claimed.release : null\n\n try {\n await withProjectionInfo({ name, event }, async () => {\n try {\n await handler?.(event, {\n replaying,\n async replayUntil(position, filterEvents) {\n if (position >= event.position) {\n throw new ProjectionReplayLoopError(\n `Event handler on${event.type} of projection ${name} tried to replay to the future`,\n { name, eventHandler: `on${event.type}` },\n event,\n )\n }\n\n locks.delete(event.streamId)\n return api.replayUntil(event.streamId, position, filterEvents)\n },\n })\n } catch (error) {\n if (error instanceof ReplaySkipError) {\n if (isReplaying()) {\n return\n }\n\n throw new Error(\n 'ReplaySkipError should never be thrown outside replay',\n )\n }\n\n if (\n !(error instanceof Error) ||\n error instanceof ProjectionReplayLoopError\n ) {\n throw error\n }\n throw new ProjectionEventHandlerExecutionError(\n name,\n `on${event.type}`,\n event,\n error,\n )\n }\n try {\n await globalEventHandler?.(event)\n } catch (error) {\n if (!(error instanceof Error)) {\n throw error\n }\n\n throw new ProjectionEventHandlerExecutionError(\n name,\n 'GLOBAL',\n event,\n error,\n )\n }\n })\n\n if (params.snapshot && snapshotting) {\n const appliedEvents = await params.snapshot.incrementAppliedCount({\n projection: name,\n id: event.streamId,\n })\n const snapshot = await snapshotting.internalCapture(\n event,\n appliedEvents,\n )\n\n if (snapshot) {\n await params.snapshot.put({\n projectionType: name,\n projectionId: event.streamId,\n lastEventPosition: event.position,\n state: snapshot.state,\n schemaVersion: snapshot.version,\n createdAt: new Date(),\n })\n }\n }\n } catch (error) {\n // The cursor was moved before this work ran, so it has to go back or\n // the event would never be retried — a claim must not turn a failing\n // handler into a silently skipped one.\n await release?.()\n throw error\n }\n\n // A claim already wrote the cursor. A replay did not take one, so it\n // still advances the cursor the ordinary way.\n if (!release) {\n await checkpointApi.upsert(event)\n }\n })()\n\n if (exclusive) {\n locks.set(event.streamId, runner)\n\n runner\n .finally(() => {\n if (locks.get(event.streamId) === runner) {\n locks.delete(event.streamId)\n }\n })\n .catch(() => {})\n return runner\n }\n\n return Promise.resolve()\n }\n\n let resolveReplay: null | (() => void) = null\n let resolveReplayOne: null | (() => void) = null\n let replayOneStreamId: null | string = null\n\n const api = {\n name: 'projection ' + name,\n async isReady() {\n await hydrated\n },\n withEventHandlers(h) {\n handlers = h\n return api\n },\n withGlobalEventHandler(handler) {\n globalEventHandler = handler as any\n return api\n },\n concurrent() {\n exclusive = false\n return api\n },\n setRelatedStreamEvents(generate) {\n generateRelatedStreamEvents = generate\n },\n withReplay(config) {\n replayConfig = config\n return api as any\n },\n\n withSnapshots(handler) {\n snapshotting = handler(createSnapshotGenerator() as any) as any\n return api\n },\n\n async apply(event) {\n await apply(event)\n },\n\n async replayOne(streamId: string) {\n if (!idle) {\n await replayOne(streamId)\n return\n }\n\n const { promise, resolve } = Promise.withResolvers<void>()\n resolveReplayOne = resolve\n replayOneStreamId = streamId\n return promise\n },\n\n async replay() {\n if (!idle) {\n await replay()\n return\n }\n const { promise, resolve } = Promise.withResolvers<void>()\n resolveReplay = resolve\n return promise\n },\n\n canReplay() {\n return Boolean(replayConfig)\n },\n\n async beginReplay() {\n if (!replayConfig?.deleteAll) {\n throw new Error(\n 'this projection does not support replay all. withReplay({ deleteAll }) not implemented.',\n )\n }\n\n lastEventPosition = -1\n params.onReplay?.begin?.(name)\n await params.snapshot?.delete({ projection: name })\n await replayConfig.deleteAll()\n },\n\n async progressReplay(index, event) {\n await withReplaying(() => withHydrating(() => apply(event)))\n if (\n !checkpointApi.relatedStreamEvents ||\n checkpointApi.relatedStreamEvents.some((streamEvent) =>\n streamEvent.events.includes(event.type),\n )\n ) {\n params.onReplay?.progress?.(name, index, event)\n }\n },\n\n endReplay() {\n params.onReplay?.end?.(name)\n resolveHydrated()\n },\n\n async replayUntil(id, position, filterEvents = () => true) {\n let startPosition = 0\n if (snapshotting) {\n await params.snapshot?.delete({ id, projection: name }, position)\n const snapshot = await params.snapshot?.get({ id, projection: name })\n if (snapshot) {\n const result = snapshotSchema.safeParse(snapshot)\n\n if (!result.success) {\n throw new ValidationError(\n 'loaded projection snapshot does not comply with schema',\n result.error,\n )\n }\n snapshotting.internalApply(result.data)\n startPosition = result.data.lastEventPosition + 1\n }\n }\n\n const events = params.loadEvents(\n relatedStreamEvents?.map((relatedStreamEvent) => ({\n ...relatedStreamEvent,\n id,\n })) ?? null,\n {\n from: startPosition,\n to: position,\n },\n )\n\n replaying = true\n await withReplaying(async () => {\n for await (const event of events) {\n if ((filterEvents as (event: BaseOutputEvent) => boolean)(event)) {\n await apply(event)\n }\n }\n })\n replaying = false\n },\n async init(catchUp) {\n idle = false\n relatedStreamEvents = globalEventHandler\n ? null\n : generateRelatedStreamEvents(handlers as EventHandlers<any>)\n checkpointApi = createCheckpointApi({\n ...params.checkpoint,\n name,\n relatedStreamEvents,\n type: 'projection',\n loadEvents: params.loadEvents,\n apply: (event) => withHydrating(() => apply(event)),\n })\n\n if (resolveReplay) {\n await replay()\n resolveReplay()\n return\n }\n\n if (resolveReplayOne && replayOneStreamId) {\n await replayOne(replayOneStreamId)\n }\n\n if (!catchUp) {\n return\n }\n\n await checkpointApi.rehydrated()\n resolveHydrated()\n resolveReplayOne?.()\n },\n } as ProjectionApi & InternalProjection & ReplayProjection<any>\n\n async function replayOne(id: string) {\n if (!replayConfig?.deleteOne) {\n throw new Error(\n 'this projection does not support replay one. withReplay({ deleteOne }) not implemented.',\n )\n }\n await params.snapshot?.delete({ id, projection: name })\n await replayConfig.deleteOne(id)\n const streamIds = relatedStreamEvents\n ? relatedStreamEvents.map((relatedStreamEvent) => ({\n ...relatedStreamEvent,\n id,\n }))\n : null\n const events = params.loadEvents(streamIds)\n\n replaying = true\n await withReplaying(async () => {\n for await (const event of events) {\n await withHydrating(() => apply(event))\n }\n })\n replaying = false\n }\n\n async function replay() {\n await api.beginReplay()\n const events = params.loadEvents(relatedStreamEvents)\n let index = 0\n replaying = true\n await withReplaying(async () => {\n for await (const event of events) {\n await api.progressReplay(index, event)\n index++\n }\n })\n replaying = false\n api.endReplay()\n }\n\n return api\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "91F75EEEF7189F7964756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_LOCK_TTL2
|
|
3
|
+
} from "./chunk-j4mwjx07.js";
|
|
4
|
+
|
|
1
5
|
// src/redis/redisLock.ts
|
|
2
6
|
var extendScript = `
|
|
3
7
|
if redis.call("get", KEYS[1]) == ARGV[1] then
|
|
@@ -13,7 +17,7 @@ var deleteScript = `
|
|
|
13
17
|
return 0
|
|
14
18
|
end
|
|
15
19
|
`;
|
|
16
|
-
function
|
|
20
|
+
function redisLock2(client, defaultTtl = DEFAULT_LOCK_TTL2) {
|
|
17
21
|
return async (rawKey) => {
|
|
18
22
|
const key = Array.isArray(rawKey) ? rawKey.join(":") : rawKey;
|
|
19
23
|
const token = crypto.randomUUID();
|
|
@@ -25,6 +29,7 @@ function redisLock(client, defaultTtl = 5000) {
|
|
|
25
29
|
}
|
|
26
30
|
let isReleased = false;
|
|
27
31
|
return {
|
|
32
|
+
ttl: defaultTtl,
|
|
28
33
|
async extend(ttl) {
|
|
29
34
|
const extended = await client.eval(extendScript, 1, key, token, ttl ?? defaultTtl / 2);
|
|
30
35
|
if (extended === 0) {
|
|
@@ -45,6 +50,6 @@ function redisLock(client, defaultTtl = 5000) {
|
|
|
45
50
|
};
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
export {
|
|
53
|
+
export { redisLock2 };
|
|
49
54
|
|
|
50
|
-
//# debugId=
|
|
55
|
+
//# debugId=E8718AD637E0295764756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/redis/redisLock.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Redis } from 'ioredis'\n\nimport { DEFAULT_LOCK_TTL, type LockCreator } from '../lock.ts'\n\nconst extendScript = `\n if redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"pexpire\", KEYS[1], ARGV[2])\n else\n return 0\n end\n`\n\nconst deleteScript = `\n if redis.call(\"get\", KEYS[1]) == ARGV[1] then\n return redis.call(\"del\", KEYS[1])\n else\n return 0\n end\n`\n\nexport function redisLock(\n client: Redis,\n defaultTtl = DEFAULT_LOCK_TTL,\n): LockCreator {\n return async (rawKey) => {\n const key = Array.isArray(rawKey) ? rawKey.join(':') : rawKey\n const token = crypto.randomUUID()\n\n while (true) {\n const acquired = await client.set(key, token, 'PX', defaultTtl, 'NX')\n\n if (acquired !== 'OK') {\n await new Promise((resolve) => setTimeout(resolve, 100))\n continue\n }\n\n let isReleased = false\n return {\n ttl: defaultTtl,\n async extend(ttl) {\n const extended = await client.eval(\n extendScript,\n 1,\n key,\n token,\n ttl ?? defaultTtl / 2,\n )\n if (extended === 0) {\n isReleased = true\n return false\n }\n return true\n },\n async release() {\n if (isReleased) {\n return\n }\n\n isReleased = true\n await client.eval(deleteScript, 1, key, token)\n },\n }\n }\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;;;;AAIA,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQrB,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQd,SAAS,UAAS,CACvB,QACA,aAAa,mBACA;AAAA,EACb,OAAO,OAAO,WAAW;AAAA,IACvB,MAAM,MAAM,MAAM,QAAQ,MAAM,IAAI,OAAO,KAAK,GAAG,IAAI;AAAA,IACvD,MAAM,QAAQ,OAAO,WAAW;AAAA,IAEhC,OAAO,MAAM;AAAA,MACX,MAAM,WAAW,MAAM,OAAO,IAAI,KAAK,OAAO,MAAM,YAAY,IAAI;AAAA,MAEpE,IAAI,aAAa,MAAM;AAAA,QACrB,MAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,MAEA,IAAI,aAAa;AAAA,MACjB,OAAO;AAAA,QACL,KAAK;AAAA,aACC,OAAM,CAAC,KAAK;AAAA,UAChB,MAAM,WAAW,MAAM,OAAO,KAC5B,cACA,GACA,KACA,OACA,OAAO,aAAa,CACtB;AAAA,UACA,IAAI,aAAa,GAAG;AAAA,YAClB,aAAa;AAAA,YACb,OAAO;AAAA,UACT;AAAA,UACA,OAAO;AAAA;AAAA,aAEH,QAAO,GAAG;AAAA,UACd,IAAI,YAAY;AAAA,YACd;AAAA,UACF;AAAA,UAEA,aAAa;AAAA,UACb,MAAM,OAAO,KAAK,cAAc,GAAG,KAAK,KAAK;AAAA;AAAA,MAEjD;AAAA,IACF;AAAA;AAAA;",
|
|
8
|
+
"debugId": "E8718AD637E0295764756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function isStreamId2(stream) {
|
|
3
|
+
return "id" in stream;
|
|
4
|
+
}
|
|
5
|
+
function isStreamEvents2(stream) {
|
|
6
|
+
return "events" in stream && Array.isArray(stream.events);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export { isStreamId2, isStreamEvents2 };
|
|
10
|
+
|
|
11
|
+
//# debugId=D51E31DE9DBDEB6664756E2164756E21
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type {\n Stream,\n StreamEvents,\n StreamId,\n StreamIdEvents,\n} from './utilityTypes.ts'\n\nexport { createEventStore } from './createEventStore.ts'\nexport type { BaseOutputEvent as Event } from './utilityTypes.d.ts'\nexport {\n type Snapshot as ProjectionSnapshot,\n isInsideProjection,\n getProjectionInfo,\n} from './createProjection.ts'\nexport type { Checkpoint } from './createCheckpointApi.ts'\nexport {\n type ProcessManagerOptions,\n isInsideProcessManager,\n getProcessManagerInfo,\n} from './createProcessManager.ts'\nexport {\n isInsideEventListener,\n getEventListenerInfo,\n} from './createEventListener.ts'\nexport * from './errors.ts'\nexport {\n type Snapshot as AggregateRootSnapshot,\n type AnyAggregateRoot,\n type AnyStream,\n type SettledOptions,\n createAggregateRoot,\n} from './createAggregateRoot.ts'\n\nexport type { TransactionOptions } from './transaction.ts'\nexport { skipRefreshing } from './refresh.ts'\nexport { skipReplay } from './replay.ts'\n\nexport function isStreamId(\n stream: Stream,\n): stream is StreamId | StreamIdEvents {\n return 'id' in stream\n}\nexport function isStreamEvents(\n stream: Stream,\n): stream is StreamEvents | StreamIdEvents {\n return 'events' in stream && Array.isArray(stream.events)\n}\nexport type { WrappedEvent } from './wrappedEventBuilder.ts'\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAqCO,SAAS,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAqCO,SAAS,WAAU,CACxB,QACqC;AAAA,EACrC,OAAO,QAAQ;AAAA;AAEV,SAAS,eAAc,CAC5B,QACyC;AAAA,EACzC,OAAO,YAAY,UAAU,MAAM,QAAQ,OAAO,MAAM;AAAA;",
|
|
8
|
+
"debugId": "D51E31DE9DBDEB6664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -70,7 +70,7 @@ function createTransaction() {
|
|
|
70
70
|
reject(error);
|
|
71
71
|
}
|
|
72
72
|
await awaitAll(() => delayPromises);
|
|
73
|
-
await Promise.all(afterHandlers.map((
|
|
73
|
+
await Promise.all(afterHandlers.map((handler) => handler()));
|
|
74
74
|
return result;
|
|
75
75
|
}
|
|
76
76
|
};
|
|
@@ -78,4 +78,4 @@ function createTransaction() {
|
|
|
78
78
|
|
|
79
79
|
export { createTransaction };
|
|
80
80
|
|
|
81
|
-
//# debugId=
|
|
81
|
+
//# debugId=3FB0CCFDAF6DF4F164756E2164756E21
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport type { SettledOptions } from './createAggregateRoot.ts'\n\nasync function awaitAll(getPromises: () => Promise<any>[]) {\n let promises = getPromises()\n\n while (true) {\n await Promise.all(promises)\n const nextPromises = getPromises()\n if (nextPromises.length > promises.length) {\n promises = nextPromises\n } else {\n break\n }\n }\n}\n\nexport type TransactionDelay = {\n resolve: () => void\n reject: (error: Error) => void\n commit: () => Promise<void>\n}\n\n/**\n * Options for a transaction run.\n *\n * `settled` — default {@link SettledOptions} applied when the transaction\n * auto-settles the streams whose commands were dispatched inside the handler\n * (explicit `settled()` calls are not allowed there).\n */\nexport type TransactionOptions = {\n settled?: SettledOptions\n}\n\nexport default function createTransaction() {\n const transactionStore = new AsyncLocalStorage<{\n delayPromises: Promise<void>[]\n commitPromises: Promise<void>[]\n afterHandlers: Array<() => Promise<any>>\n settledDefaults?: SettledOptions\n }>()\n\n return {\n get active() {\n return Boolean(transactionStore.getStore())\n },\n\n get settledDefaults() {\n return transactionStore.getStore()?.settledDefaults\n },\n\n /**\n * Runs the handler outside the transaction scope. Used by the settle\n * retry: a retried append already passed the transaction gate on its\n * first attempt and must not re-enter the (committed) transaction.\n */\n exit<T>(handler: () => T): T {\n return transactionStore.exit(handler)\n },\n\n delay(): TransactionDelay {\n const store = transactionStore.getStore()\n if (!store) {\n return {\n resolve: () => {},\n reject: () => {},\n commit: () => Promise.resolve(),\n }\n }\n\n const idx = store.commitPromises.length\n const { resolve, reject, promise } = Promise.withResolvers<void>()\n store.delayPromises.push(promise)\n\n const { promise: commitPromise, resolve: resolveCommitPromise } =\n Promise.withResolvers<void>()\n store.commitPromises.push(commitPromise)\n\n return {\n resolve,\n reject,\n async commit() {\n if (idx > 0) {\n await store.commitPromises.at(idx - 1)\n }\n\n resolveCommitPromise()\n await awaitAll(() => store.delayPromises)\n },\n }\n },\n\n after(onAfter: () => Promise<any>) {\n transactionStore.getStore()?.afterHandlers.push(onAfter)\n },\n\n async run<T extends () => any>(handler: T, options?: TransactionOptions) {\n const { resolve, reject, promise } = Promise.withResolvers<void>()\n const delayPromises = [promise]\n const afterHandlers: Array<() => Promise<any>> = []\n let result\n try {\n result = await transactionStore.run(\n {\n delayPromises,\n afterHandlers,\n commitPromises: [],\n settledDefaults: options?.settled,\n },\n handler,\n )\n resolve()\n } catch (error) {\n reject(error)\n }\n await awaitAll(() => delayPromises)\n await Promise.all(afterHandlers.map((handler) => handler()))\n\n return result\n },\n }\n}\n\nexport type Transaction = ReturnType<typeof createTransaction>\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA;AAIA,eAAe,QAAQ,CAAC,aAAmC;AAAA,EACzD,IAAI,WAAW,YAAY;AAAA,EAE3B,OAAO,MAAM;AAAA,IACX,MAAM,QAAQ,IAAI,QAAQ;AAAA,IAC1B,MAAM,eAAe,YAAY;AAAA,IACjC,IAAI,aAAa,SAAS,SAAS,QAAQ;AAAA,MACzC,WAAW;AAAA,IACb,EAAO;AAAA,MACL;AAAA;AAAA,EAEJ;AAAA;AAoBF,SAAwB,iBAAiB,GAAG;AAAA,EAC1C,MAAM,mBAAmB,IAAI;AAAA,EAO7B,OAAO;AAAA,QACD,MAAM,GAAG;AAAA,MACX,OAAO,QAAQ,iBAAiB,SAAS,CAAC;AAAA;AAAA,QAGxC,eAAe,GAAG;AAAA,MACpB,OAAO,iBAAiB,SAAS,GAAG;AAAA;AAAA,IAQtC,IAAO,CAAC,SAAqB;AAAA,MAC3B,OAAO,iBAAiB,KAAK,OAAO;AAAA;AAAA,IAGtC,KAAK,GAAqB;AAAA,MACxB,MAAM,QAAQ,iBAAiB,SAAS;AAAA,MACxC,IAAI,CAAC,OAAO;AAAA,QACV,OAAO;AAAA,UACL,SAAS,MAAM;AAAA,UACf,QAAQ,MAAM;AAAA,UACd,QAAQ,MAAM,QAAQ,QAAQ;AAAA,QAChC;AAAA,MACF;AAAA,MAEA,MAAM,MAAM,MAAM,eAAe;AAAA,MACjC,QAAQ,SAAS,QAAQ,YAAY,QAAQ,cAAoB;AAAA,MACjE,MAAM,cAAc,KAAK,OAAO;AAAA,MAEhC,QAAQ,SAAS,eAAe,SAAS,yBACvC,QAAQ,cAAoB;AAAA,MAC9B,MAAM,eAAe,KAAK,aAAa;AAAA,MAEvC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,aACM,OAAM,GAAG;AAAA,UACb,IAAI,MAAM,GAAG;AAAA,YACX,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAAA,UACvC;AAAA,UAEA,qBAAqB;AAAA,UACrB,MAAM,SAAS,MAAM,MAAM,aAAa;AAAA;AAAA,MAE5C;AAAA;AAAA,IAGF,KAAK,CAAC,SAA6B;AAAA,MACjC,iBAAiB,SAAS,GAAG,cAAc,KAAK,OAAO;AAAA;AAAA,SAGnD,IAAwB,CAAC,SAAY,SAA8B;AAAA,MACvE,QAAQ,SAAS,QAAQ,YAAY,QAAQ,cAAoB;AAAA,MACjE,MAAM,gBAAgB,CAAC,OAAO;AAAA,MAC9B,MAAM,gBAA2C,CAAC;AAAA,MAClD,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,SAAS,MAAM,iBAAiB,IAC9B;AAAA,UACE;AAAA,UACA;AAAA,UACA,gBAAgB,CAAC;AAAA,UACjB,iBAAiB,SAAS;AAAA,QAC5B,GACA,OACF;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,OAAO;AAAA,QACd,OAAO,KAAK;AAAA;AAAA,MAEd,MAAM,SAAS,MAAM,aAAa;AAAA,MAClC,MAAM,QAAQ,IAAI,cAAc,IAAI,CAAC,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAAA;AAIA,eAAe,QAAQ,CAAC,aAAmC;AAAA,EACzD,IAAI,WAAW,YAAY;AAAA,EAE3B,OAAO,MAAM;AAAA,IACX,MAAM,QAAQ,IAAI,QAAQ;AAAA,IAC1B,MAAM,eAAe,YAAY;AAAA,IACjC,IAAI,aAAa,SAAS,SAAS,QAAQ;AAAA,MACzC,WAAW;AAAA,IACb,EAAO;AAAA,MACL;AAAA;AAAA,EAEJ;AAAA;AAoBF,SAAwB,iBAAiB,GAAG;AAAA,EAC1C,MAAM,mBAAmB,IAAI;AAAA,EAO7B,OAAO;AAAA,QACD,MAAM,GAAG;AAAA,MACX,OAAO,QAAQ,iBAAiB,SAAS,CAAC;AAAA;AAAA,QAGxC,eAAe,GAAG;AAAA,MACpB,OAAO,iBAAiB,SAAS,GAAG;AAAA;AAAA,IAQtC,IAAO,CAAC,SAAqB;AAAA,MAC3B,OAAO,iBAAiB,KAAK,OAAO;AAAA;AAAA,IAGtC,KAAK,GAAqB;AAAA,MACxB,MAAM,QAAQ,iBAAiB,SAAS;AAAA,MACxC,IAAI,CAAC,OAAO;AAAA,QACV,OAAO;AAAA,UACL,SAAS,MAAM;AAAA,UACf,QAAQ,MAAM;AAAA,UACd,QAAQ,MAAM,QAAQ,QAAQ;AAAA,QAChC;AAAA,MACF;AAAA,MAEA,MAAM,MAAM,MAAM,eAAe;AAAA,MACjC,QAAQ,SAAS,QAAQ,YAAY,QAAQ,cAAoB;AAAA,MACjE,MAAM,cAAc,KAAK,OAAO;AAAA,MAEhC,QAAQ,SAAS,eAAe,SAAS,yBACvC,QAAQ,cAAoB;AAAA,MAC9B,MAAM,eAAe,KAAK,aAAa;AAAA,MAEvC,OAAO;AAAA,QACL;AAAA,QACA;AAAA,aACM,OAAM,GAAG;AAAA,UACb,IAAI,MAAM,GAAG;AAAA,YACX,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC;AAAA,UACvC;AAAA,UAEA,qBAAqB;AAAA,UACrB,MAAM,SAAS,MAAM,MAAM,aAAa;AAAA;AAAA,MAE5C;AAAA;AAAA,IAGF,KAAK,CAAC,SAA6B;AAAA,MACjC,iBAAiB,SAAS,GAAG,cAAc,KAAK,OAAO;AAAA;AAAA,SAGnD,IAAwB,CAAC,SAAY,SAA8B;AAAA,MACvE,QAAQ,SAAS,QAAQ,YAAY,QAAQ,cAAoB;AAAA,MACjE,MAAM,gBAAgB,CAAC,OAAO;AAAA,MAC9B,MAAM,gBAA2C,CAAC;AAAA,MAClD,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,SAAS,MAAM,iBAAiB,IAC9B;AAAA,UACE;AAAA,UACA;AAAA,UACA,gBAAgB,CAAC;AAAA,UACjB,iBAAiB,SAAS;AAAA,QAC5B,GACA,OACF;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,OAAO;AAAA,QACd,OAAO,KAAK;AAAA;AAAA,MAEd,MAAM,SAAS,MAAM,aAAa;AAAA,MAClC,MAAM,QAAQ,IAAI,cAAc,IAAI,CAAC,YAAY,QAAQ,CAAC,CAAC;AAAA,MAE3D,OAAO;AAAA;AAAA,EAEX;AAAA;",
|
|
8
|
+
"debugId": "3FB0CCFDAF6DF4F164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/utils.ts
|
|
2
|
-
async function
|
|
2
|
+
async function normalizeArray2(result, onItem) {
|
|
3
3
|
const awaited = await result;
|
|
4
4
|
if (typeof awaited === "undefined") {
|
|
5
5
|
return [];
|
|
@@ -17,7 +17,7 @@ async function normalizeArray(result, onItem) {
|
|
|
17
17
|
}
|
|
18
18
|
return [awaited];
|
|
19
19
|
}
|
|
20
|
-
async function
|
|
20
|
+
async function awaitAll2(getPromise) {
|
|
21
21
|
let currentPromise = getPromise();
|
|
22
22
|
while (true) {
|
|
23
23
|
await currentPromise;
|
|
@@ -29,6 +29,6 @@ async function awaitAll(getPromise) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export {
|
|
32
|
+
export { normalizeArray2, awaitAll2 };
|
|
33
33
|
|
|
34
|
-
//# debugId=
|
|
34
|
+
//# debugId=3D261C023C96EB8664756E2164756E21
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import type { MaybePromise } from './utilityTypes.js'\n\nexport async function normalizeArray<T>(\n result: MaybePromise<void | T | T[]> | Iterable<T> | AsyncIterable<T>,\n onItem?: (item: T) => void,\n): Promise<T[]> {\n const awaited = (await result) as any\n\n // If it's explicitly void/undefined, normalize to empty array\n if (typeof awaited === 'undefined') {\n return []\n }\n\n // Async iterable\n if (typeof awaited[Symbol.asyncIterator] === 'function') {\n const out: T[] = []\n for await (const item of awaited as AsyncIterable<T>) {\n out.push(item)\n onItem?.(item)\n }\n return out\n }\n\n // Sync iterable (this also covers arrays)\n if (typeof awaited[Symbol.iterator] === 'function') {\n return Array.from(awaited as Iterable<T>)\n }\n\n // Plain single value\n return [awaited as T]\n}\n\nexport async function awaitAll(getPromise: () => Promise<any>) {\n let currentPromise = getPromise()\n while (true) {\n await currentPromise\n const nextPromise = getPromise()\n if (nextPromise === currentPromise) {\n break\n }\n currentPromise = nextPromise\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAEA,eAAsB,
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";AAEA,eAAsB,eAAiB,CACrC,QACA,QACc;AAAA,EACd,MAAM,UAAW,MAAM;AAAA,EAGvB,IAAI,OAAO,YAAY,aAAa;AAAA,IAClC,OAAO,CAAC;AAAA,EACV;AAAA,EAGA,IAAI,OAAO,QAAQ,OAAO,mBAAmB,YAAY;AAAA,IACvD,MAAM,MAAW,CAAC;AAAA,IAClB,iBAAiB,QAAQ,SAA6B;AAAA,MACpD,IAAI,KAAK,IAAI;AAAA,MACb,SAAS,IAAI;AAAA,IACf;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,OAAO,QAAQ,OAAO,cAAc,YAAY;AAAA,IAClD,OAAO,MAAM,KAAK,OAAsB;AAAA,EAC1C;AAAA,EAGA,OAAO,CAAC,OAAY;AAAA;AAGtB,eAAsB,SAAQ,CAAC,YAAgC;AAAA,EAC7D,IAAI,iBAAiB,WAAW;AAAA,EAChC,OAAO,MAAM;AAAA,IACX,MAAM;AAAA,IACN,MAAM,cAAc,WAAW;AAAA,IAC/B,IAAI,gBAAgB,gBAAgB;AAAA,MAClC;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,EACnB;AAAA;",
|
|
8
|
+
"debugId": "3D261C023C96EB8664756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|