@rotorsoft/act 0.0.2

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 (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/act.d.ts +24 -0
  5. package/dist/act.d.ts.map +1 -0
  6. package/dist/act.js +136 -0
  7. package/dist/act.js.map +1 -0
  8. package/dist/adapters/InMemoryStore.d.ts +24 -0
  9. package/dist/adapters/InMemoryStore.d.ts.map +1 -0
  10. package/dist/adapters/InMemoryStore.js +125 -0
  11. package/dist/adapters/InMemoryStore.js.map +1 -0
  12. package/dist/builder.d.ts +30 -0
  13. package/dist/builder.d.ts.map +1 -0
  14. package/dist/builder.js +97 -0
  15. package/dist/builder.js.map +1 -0
  16. package/dist/config.d.ts +93 -0
  17. package/dist/config.d.ts.map +1 -0
  18. package/dist/config.js +41 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/event-sourcing.d.ts +5 -0
  21. package/dist/event-sourcing.d.ts.map +1 -0
  22. package/dist/event-sourcing.js +101 -0
  23. package/dist/event-sourcing.js.map +1 -0
  24. package/dist/index.d.ts +9 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +27 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/ports.d.ts +17 -0
  29. package/dist/ports.d.ts.map +1 -0
  30. package/dist/ports.js +56 -0
  31. package/dist/ports.js.map +1 -0
  32. package/dist/types/action.d.ts +57 -0
  33. package/dist/types/action.d.ts.map +1 -0
  34. package/dist/types/action.js +2 -0
  35. package/dist/types/action.js.map +1 -0
  36. package/dist/types/errors.d.ts +41 -0
  37. package/dist/types/errors.d.ts.map +1 -0
  38. package/dist/types/errors.js +44 -0
  39. package/dist/types/errors.js.map +1 -0
  40. package/dist/types/index.d.ts +11 -0
  41. package/dist/types/index.d.ts.map +1 -0
  42. package/dist/types/index.js +17 -0
  43. package/dist/types/index.js.map +1 -0
  44. package/dist/types/ports.d.ts +16 -0
  45. package/dist/types/ports.d.ts.map +1 -0
  46. package/dist/types/ports.js +2 -0
  47. package/dist/types/ports.js.map +1 -0
  48. package/dist/types/reaction.d.ts +30 -0
  49. package/dist/types/reaction.d.ts.map +1 -0
  50. package/dist/types/reaction.js +2 -0
  51. package/dist/types/reaction.js.map +1 -0
  52. package/dist/types/registry.d.ts +23 -0
  53. package/dist/types/registry.d.ts.map +1 -0
  54. package/dist/types/registry.js +2 -0
  55. package/dist/types/registry.js.map +1 -0
  56. package/dist/types/schemas.d.ts +1046 -0
  57. package/dist/types/schemas.d.ts.map +1 -0
  58. package/dist/types/schemas.js +82 -0
  59. package/dist/types/schemas.js.map +1 -0
  60. package/dist/utils.d.ts +17 -0
  61. package/dist/utils.d.ts.map +1 -0
  62. package/dist/utils.js +73 -0
  63. package/dist/utils.js.map +1 -0
  64. package/package.json +32 -0
@@ -0,0 +1,125 @@
1
+ import { ConcurrencyError } from "../types/errors";
2
+ import { sleep } from "../utils";
3
+ class InMemoryStream {
4
+ stream;
5
+ _at = -1;
6
+ _retry = -1;
7
+ _lease;
8
+ _blocked = false;
9
+ constructor(stream) {
10
+ this.stream = stream;
11
+ }
12
+ lease(lease) {
13
+ if (!this._blocked && lease.at > this._at) {
14
+ this._lease = { ...lease, retry: this._retry + 1 };
15
+ return this._lease;
16
+ }
17
+ }
18
+ ack(lease) {
19
+ if (this._lease && lease.at >= this._at) {
20
+ this._at = lease.at;
21
+ this._retry = lease.retry;
22
+ this._blocked = lease.block;
23
+ this._lease = undefined;
24
+ }
25
+ }
26
+ }
27
+ /**
28
+ * @category Adapters
29
+ * @remarks In-memory event store
30
+ */
31
+ export class InMemoryStore {
32
+ // stored events
33
+ _events = [];
34
+ // stored stream positions and other metadata
35
+ _streams = new Map();
36
+ async dispose() {
37
+ await sleep();
38
+ this._events.length = 0;
39
+ }
40
+ async seed() {
41
+ await sleep();
42
+ }
43
+ async drop() {
44
+ await sleep();
45
+ this._events.length = 0;
46
+ }
47
+ async query(callback, query) {
48
+ await sleep();
49
+ const { stream, names, before, after = -1, limit, created_before, created_after, correlation, } = query || {};
50
+ let i = after + 1, count = 0;
51
+ while (i < this._events.length) {
52
+ const e = this._events[i++];
53
+ if (stream && e.stream !== stream)
54
+ continue;
55
+ if (names && !names.includes(e.name))
56
+ continue;
57
+ if (correlation && e.meta?.correlation !== correlation)
58
+ continue;
59
+ if (created_after && e.created <= created_after)
60
+ continue;
61
+ if (before && e.id >= before)
62
+ break;
63
+ if (created_before && e.created >= created_before)
64
+ break;
65
+ callback(e);
66
+ count++;
67
+ if (limit && count >= limit)
68
+ break;
69
+ }
70
+ return count;
71
+ }
72
+ async commit(stream, msgs, meta, expectedVersion) {
73
+ await sleep();
74
+ const instance = this._events.filter((e) => e.stream === stream); // ignore state events, this is a production optimization
75
+ if (expectedVersion && instance.length - 1 !== expectedVersion)
76
+ throw new ConcurrencyError(instance.length - 1, msgs, expectedVersion);
77
+ let version = instance.length;
78
+ return msgs.map(({ name, data }) => {
79
+ const committed = {
80
+ id: this._events.length,
81
+ stream,
82
+ version,
83
+ created: new Date(),
84
+ name,
85
+ data,
86
+ meta,
87
+ };
88
+ this._events.push(committed);
89
+ version++;
90
+ return committed;
91
+ });
92
+ }
93
+ /**
94
+ * Fetches new events from stream watermarks
95
+ */
96
+ async fetch(limit) {
97
+ const streams = [...this._streams.values()]
98
+ .filter((s) => !s._blocked)
99
+ .sort((a, b) => a._at - b._at)
100
+ .slice(0, limit);
101
+ const after = streams.length
102
+ ? streams.reduce((min, s) => Math.min(min, s._at), Number.MAX_SAFE_INTEGER)
103
+ : -1;
104
+ const events = [];
105
+ await this.query((e) => events.push(e), { after, limit });
106
+ return { streams: streams.map(({ stream }) => stream), events };
107
+ }
108
+ async lease(leases) {
109
+ await sleep();
110
+ leases.forEach((lease) => {
111
+ const stream = this._streams.get(lease.stream) ||
112
+ // store new correlations
113
+ this._streams
114
+ .set(lease.stream, new InMemoryStream(lease.stream))
115
+ .get(lease.stream);
116
+ stream.lease(lease);
117
+ });
118
+ return leases;
119
+ }
120
+ async ack(leases) {
121
+ await sleep();
122
+ leases.forEach((lease) => this._streams.get(lease.stream)?.ack(lease));
123
+ }
124
+ }
125
+ //# sourceMappingURL=InMemoryStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryStore.js","sourceRoot":"","sources":["../../src/adapters/InMemoryStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { Act } from "./act";
2
+ import type { EventRegister, ReactionHandler, ReactionOptions, ReactionResolver, Registry, Schema, SchemaRegister, Schemas, StateFactory } from "./types";
3
+ export interface IActBuilder<E extends Schemas, A extends Schemas, S extends SchemaRegister<A>> {
4
+ get events(): EventRegister<E>;
5
+ with<EX extends Schemas, AX extends Schemas, SX extends Schema>(factory: StateFactory<EX, AX, SX>): IActBuilder<E & EX, A & AX, S & {
6
+ [K in keyof AX]: SX;
7
+ }>;
8
+ on<K extends keyof E>(event: K): IDoBuilder<E, A, S, K>;
9
+ build(drainLimit?: number): Act<E, A, S>;
10
+ }
11
+ interface IDoBuilder<E extends Schemas, A extends Schemas, S extends SchemaRegister<A>, K extends keyof E> extends IActBuilder<E, A, S> {
12
+ do(handler: ReactionHandler<E, K>, options?: Partial<ReactionOptions>): IToBuilder<E, A, S, K>;
13
+ }
14
+ interface IToBuilder<E extends Schemas, A extends Schemas, S extends SchemaRegister<A>, K extends keyof E> extends IDoBuilder<E, A, S, K> {
15
+ to(resolver: ReactionResolver<E, K>): IDoBuilder<E, A, S, K>;
16
+ void(): IDoBuilder<E, A, S, K>;
17
+ }
18
+ export declare class ActBuilder<E extends Schemas = {}, A extends Schemas = {}, S extends SchemaRegister<A> = {}> implements IActBuilder<E, A, S> {
19
+ protected _registry: Registry<E, A, S>;
20
+ private factories;
21
+ constructor(_registry?: Registry<E, A, S>);
22
+ get events(): EventRegister<E>;
23
+ with<EX extends Schemas, AX extends Schemas, SX extends Schema>(factory: StateFactory<EX, AX, SX>): IActBuilder<E & EX, A & AX, S & {
24
+ [K in keyof AX]: SX;
25
+ }>;
26
+ on<K extends keyof E>(event: K): IDoBuilder<E, A, S, K>;
27
+ build(drainLimit?: number): Act<E, A, S>;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { Act } from "./act";
2
+ // default resolver resolves to same event stream
3
+ const _this_ = ({ stream }) => stream;
4
+ // nothing to resolve
5
+ const _void_ = () => undefined;
6
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
7
+ export class ActBuilder {
8
+ _registry;
9
+ factories = new Set();
10
+ constructor(_registry = {
11
+ actions: {},
12
+ events: {},
13
+ }) {
14
+ this._registry = _registry;
15
+ }
16
+ get events() {
17
+ return this._registry.events;
18
+ }
19
+ with(factory) {
20
+ if (!this.factories.has(factory.name)) {
21
+ this.factories.add(factory.name);
22
+ const me = factory();
23
+ Object.keys(me.actions).forEach((name) => {
24
+ if (this._registry.actions[name])
25
+ throw Error(`Duplicate action "${name}"`);
26
+ // @ts-expect-error indexed access
27
+ this._registry.actions[name] = me;
28
+ });
29
+ Object.keys(me.events).forEach((name) => {
30
+ if (this._registry.events[name])
31
+ throw Error(`Duplicate event "${name}"`);
32
+ // @ts-expect-error indexed access
33
+ this._registry.events[name] = {
34
+ schema: me.events[name],
35
+ reactions: new Map(),
36
+ };
37
+ });
38
+ }
39
+ return this;
40
+ }
41
+ on(event) {
42
+ return new DoBuilder(this._registry, event);
43
+ }
44
+ build(drainLimit = 10) {
45
+ return new Act(this._registry, drainLimit);
46
+ }
47
+ }
48
+ class DoBuilder extends ActBuilder {
49
+ event;
50
+ constructor(registry, event) {
51
+ super(registry);
52
+ this.event = event;
53
+ }
54
+ get events() {
55
+ throw new Error("Method not implemented.");
56
+ }
57
+ do(handler, options) {
58
+ const reaction = {
59
+ handler: handler,
60
+ resolver: _this_,
61
+ options: {
62
+ blockOnError: options?.blockOnError ?? true,
63
+ maxRetries: options?.maxRetries ?? 3,
64
+ retryDelayMs: options?.retryDelayMs ?? 1000,
65
+ },
66
+ };
67
+ this._registry.events[this.event].reactions.set(handler.name, reaction);
68
+ return new ToBuilder(this._registry, this.event, reaction);
69
+ }
70
+ }
71
+ class ToBuilder extends DoBuilder {
72
+ reaction;
73
+ constructor(registry, event, reaction) {
74
+ super(registry, event);
75
+ this.reaction = reaction;
76
+ }
77
+ get events() {
78
+ throw new Error("Method not implemented.");
79
+ }
80
+ to(resolver) {
81
+ this._registry.events[this.event].reactions.set(this.reaction.handler.name, {
82
+ handler: this.reaction.handler,
83
+ resolver: resolver,
84
+ options: this.reaction.options,
85
+ });
86
+ return new DoBuilder(this._registry, this.event);
87
+ }
88
+ void() {
89
+ this._registry.events[this.event].reactions.set(this.reaction.handler.name, {
90
+ handler: this.reaction.handler,
91
+ resolver: _void_,
92
+ options: this.reaction.options,
93
+ });
94
+ return new DoBuilder(this._registry, this.event);
95
+ }
96
+ }
97
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { z } from "zod";
2
+ export declare const PackageSchema: z.ZodObject<{
3
+ name: z.ZodString;
4
+ version: z.ZodString;
5
+ description: z.ZodString;
6
+ author: z.ZodUnion<[z.ZodObject<{
7
+ name: z.ZodString;
8
+ email: z.ZodOptional<z.ZodString>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ name: string;
11
+ email?: string | undefined;
12
+ }, {
13
+ name: string;
14
+ email?: string | undefined;
15
+ }>, z.ZodString]>;
16
+ license: z.ZodString;
17
+ dependencies: z.ZodRecord<z.ZodString, z.ZodString>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ name: string;
20
+ version: string;
21
+ description: string;
22
+ author: string | {
23
+ name: string;
24
+ email?: string | undefined;
25
+ };
26
+ license: string;
27
+ dependencies: Record<string, string>;
28
+ }, {
29
+ name: string;
30
+ version: string;
31
+ description: string;
32
+ author: string | {
33
+ name: string;
34
+ email?: string | undefined;
35
+ };
36
+ license: string;
37
+ dependencies: Record<string, string>;
38
+ }>;
39
+ export type Package = z.infer<typeof PackageSchema>;
40
+ declare const BaseSchema: z.ZodObject<z.objectUtil.extendShape<{
41
+ name: z.ZodString;
42
+ version: z.ZodString;
43
+ description: z.ZodString;
44
+ author: z.ZodUnion<[z.ZodObject<{
45
+ name: z.ZodString;
46
+ email: z.ZodOptional<z.ZodString>;
47
+ }, "strip", z.ZodTypeAny, {
48
+ name: string;
49
+ email?: string | undefined;
50
+ }, {
51
+ name: string;
52
+ email?: string | undefined;
53
+ }>, z.ZodString]>;
54
+ license: z.ZodString;
55
+ dependencies: z.ZodRecord<z.ZodString, z.ZodString>;
56
+ }, {
57
+ env: z.ZodEnum<["development", "test", "staging", "production"]>;
58
+ logLevel: z.ZodEnum<["fatal", "error", "warn", "info", "debug", "trace"]>;
59
+ logSingleLine: z.ZodBoolean;
60
+ sleepMs: z.ZodNumber;
61
+ }>, "strip", z.ZodTypeAny, {
62
+ name: string;
63
+ version: string;
64
+ description: string;
65
+ author: string | {
66
+ name: string;
67
+ email?: string | undefined;
68
+ };
69
+ license: string;
70
+ dependencies: Record<string, string>;
71
+ env: "development" | "test" | "staging" | "production";
72
+ logLevel: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
73
+ logSingleLine: boolean;
74
+ sleepMs: number;
75
+ }, {
76
+ name: string;
77
+ version: string;
78
+ description: string;
79
+ author: string | {
80
+ name: string;
81
+ email?: string | undefined;
82
+ };
83
+ license: string;
84
+ dependencies: Record<string, string>;
85
+ env: "development" | "test" | "staging" | "production";
86
+ logLevel: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
87
+ logSingleLine: boolean;
88
+ sleepMs: number;
89
+ }>;
90
+ export type Config = z.infer<typeof BaseSchema>;
91
+ export declare const config: () => Config;
92
+ export {};
93
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASxB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAOpD,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKd,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAgBhD,eAAO,MAAM,MAAM,QAAO,MAEzB,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,41 @@
1
+ import * as dotenv from "dotenv";
2
+ import * as fs from "node:fs";
3
+ import { z } from "zod";
4
+ import { Environments, LogLevels } from "./types";
5
+ import { extend } from "./utils";
6
+ dotenv.config();
7
+ export const PackageSchema = z.object({
8
+ name: z.string().min(1),
9
+ version: z.string().min(1),
10
+ description: z.string().min(1),
11
+ author: z
12
+ .object({ name: z.string().min(1), email: z.string().optional() })
13
+ .or(z.string().min(1)),
14
+ license: z.string().min(1),
15
+ dependencies: z.record(z.string()),
16
+ });
17
+ const getPackage = () => {
18
+ const pkg = fs.readFileSync("package.json");
19
+ return JSON.parse(pkg.toString());
20
+ };
21
+ const BaseSchema = PackageSchema.extend({
22
+ env: z.enum(Environments),
23
+ logLevel: z.enum(LogLevels),
24
+ logSingleLine: z.boolean(),
25
+ sleepMs: z.number().int().min(0).max(5000),
26
+ });
27
+ const { NODE_ENV, LOG_LEVEL, LOG_SINGLE_LINE, SLEEP_MS } = process.env;
28
+ const env = (NODE_ENV || "development");
29
+ const logLevel = (LOG_LEVEL ||
30
+ (NODE_ENV === "test"
31
+ ? "error"
32
+ : LOG_LEVEL === "production"
33
+ ? "info"
34
+ : "trace"));
35
+ const logSingleLine = (LOG_SINGLE_LINE || "true") === "true";
36
+ const sleepMs = parseInt(NODE_ENV === "test" ? "0" : (SLEEP_MS ?? "100"));
37
+ const pkg = getPackage();
38
+ export const config = () => {
39
+ return extend({ ...pkg, env, logLevel, logSingleLine, sleepMs }, BaseSchema);
40
+ };
41
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAe,YAAY,EAAY,SAAS,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,MAAM,EAAE,CAAC;SACN,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;SACjE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;CACnC,CAAC,CAAC;AAGH,MAAM,UAAU,GAAG,GAAY,EAAE;IAC/B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAY,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC;IACtC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;IAC3B,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE;IAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;CAC3C,CAAC,CAAC;AAGH,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAEvE,MAAM,GAAG,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAgB,CAAC;AACvD,MAAM,QAAQ,GAAG,CAAC,SAAS;IACzB,CAAC,QAAQ,KAAK,MAAM;QAClB,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,SAAS,KAAK,YAAY;YAC1B,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,OAAO,CAAC,CAAa,CAAC;AAC9B,MAAM,aAAa,GAAG,CAAC,eAAe,IAAI,MAAM,CAAC,KAAK,MAAM,CAAC;AAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC;AAE1E,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;AAEzB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAW,EAAE;IACjC,OAAO,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC/E,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Committed, Schema, Schemas, Snapshot, State, Target } from "./types";
2
+ export declare function snap<E extends Schemas, S extends Schema>(snapshot: Snapshot<E, S>): Promise<void>;
3
+ export declare function load<E extends Schemas, A extends Schemas, S extends Schema>(me: State<E, A, S>, stream: string, callback?: (snapshot: Snapshot<E, S>) => void): Promise<Snapshot<E, S>>;
4
+ export declare function action<E extends Schemas, A extends Schemas, S extends Schema, K extends keyof A>(me: State<E, A, S>, action: K, target: Target, payload: Readonly<A[K]>, reactingTo?: Committed<Schemas, keyof Schemas>, skipValidation?: boolean): Promise<Snapshot<E, S>>;
5
+ //# sourceMappingURL=event-sourcing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-sourcing.d.ts","sourceRoot":"","sources":["../src/event-sourcing.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,SAAS,EAGT,MAAM,EACN,OAAO,EACP,QAAQ,EACR,KAAK,EACL,MAAM,EACP,MAAM,SAAS,CAAC;AAIjB,wBAAsB,IAAI,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,MAAM,EAC5D,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,IAAI,CACxB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,MAAM,EAEhB,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAClB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,GAC5C,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAuBzB;AAED,wBAAsB,MAAM,CAC1B,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,OAAO,EACjB,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,CAAC,EAEjB,EAAE,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAClB,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACvB,UAAU,CAAC,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,EAC9C,cAAc,UAAQ,GACrB,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CA8EzB"}
@@ -0,0 +1,101 @@
1
+ import { randomUUID } from "crypto";
2
+ import { logger, SNAP_EVENT, store } from "./ports";
3
+ import { InvariantError } from "./types/errors";
4
+ import { patch, validate } from "./utils";
5
+ export async function snap(snapshot) {
6
+ try {
7
+ const { id, stream, name, meta, version } = snapshot.event;
8
+ const snapped = await store().commit(stream, [{ name: SNAP_EVENT, data: snapshot.state }], {
9
+ correlation: meta.correlation,
10
+ causation: { event: { id, name: name, stream } },
11
+ }, version // IMPORTANT! - state events are committed right after the snapshot event
12
+ );
13
+ logger.trace(snapped, "🟠 snap");
14
+ }
15
+ catch (error) {
16
+ logger.error(error);
17
+ }
18
+ }
19
+ export async function load(me, stream, callback) {
20
+ let state = me.init();
21
+ let patches = 0;
22
+ let snaps = 0;
23
+ let event;
24
+ await store().query((e) => {
25
+ event = e;
26
+ if (e.name === SNAP_EVENT) {
27
+ state = e.data;
28
+ snaps++;
29
+ patches = 0;
30
+ }
31
+ else if (me.patch[e.name]) {
32
+ state = patch(state, me.patch[e.name](event, state));
33
+ patches++;
34
+ }
35
+ callback && callback({ event, state, patches, snaps });
36
+ }, { stream }, true);
37
+ logger.trace({ stream, patches, snaps, state }, "🟢 load");
38
+ return { event, state, patches, snaps };
39
+ }
40
+ export async function action(me, action, target, payload, reactingTo, skipValidation = false) {
41
+ const { stream, expectedVersion, actor } = target;
42
+ if (!stream)
43
+ throw new Error("Missing target stream");
44
+ payload = skipValidation
45
+ ? payload
46
+ : validate(action, payload, me.actions[action]);
47
+ logger.trace(payload, `🔵 ${action} "${stream}${expectedVersion ? `@${expectedVersion}` : ""}"`);
48
+ let snapshot = await load(me, stream);
49
+ if (me.given) {
50
+ const invariants = me.given[action] || [];
51
+ invariants.forEach(({ valid, description }) => {
52
+ if (!valid(snapshot.state, actor))
53
+ throw new InvariantError(action, payload, target, description);
54
+ });
55
+ }
56
+ let { state, patches } = snapshot;
57
+ const result = await me.on[action](payload, state, target);
58
+ if (!result)
59
+ return snapshot;
60
+ const tuples = Array.isArray(result[0])
61
+ ? result // array of tuples
62
+ : [result]; // single tuple
63
+ if (!tuples.length)
64
+ return snapshot;
65
+ const emitted = tuples.map(([name, data]) => ({
66
+ name,
67
+ data: validate(name, data, me.events[name]),
68
+ }));
69
+ const meta = {
70
+ correlation: reactingTo?.meta.correlation || randomUUID(),
71
+ causation: {
72
+ action: {
73
+ name: action,
74
+ ...target,
75
+ // payload: TODO: flag to include action payload in metadata
76
+ // not included by default to avoid large payloads
77
+ },
78
+ event: reactingTo
79
+ ? {
80
+ id: reactingTo.id,
81
+ name: reactingTo.name,
82
+ stream: reactingTo.stream,
83
+ }
84
+ : undefined,
85
+ },
86
+ };
87
+ const committed = await store().commit(stream, emitted, meta,
88
+ // TODO: review reactions not enforcing expected version
89
+ reactingTo ? undefined : expectedVersion || snapshot.event?.version);
90
+ snapshot = committed
91
+ .map((event) => {
92
+ state = patch(state, me.patch[event.name](event, state));
93
+ patches++;
94
+ logger.trace({ event, state }, "🔴 commit");
95
+ return { event, state, patches, snaps: snapshot.snaps };
96
+ })
97
+ .at(-1);
98
+ me.snap && me.snap(snapshot) && void snap(snapshot); // fire and forget snaps
99
+ return snapshot;
100
+ }
101
+ //# sourceMappingURL=event-sourcing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-sourcing.js","sourceRoot":"","sources":["../src/event-sourcing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { config } from "./config";
2
+ /** @module act */
3
+ export * from "./act";
4
+ export * from "./builder";
5
+ export * from "./ports";
6
+ export * from "./types";
7
+ export * from "./utils";
8
+ export { config };
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGlC,kBAAkB;AAClB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ import { config } from "./config";
2
+ import { disposeAndExit, logger } from "./ports";
3
+ /** @module act */
4
+ export * from "./act";
5
+ export * from "./builder";
6
+ export * from "./ports";
7
+ export * from "./types";
8
+ export * from "./utils";
9
+ export { config };
10
+ // exit on signals
11
+ process.once("SIGINT", async (arg) => {
12
+ logger.info(arg, "SIGINT");
13
+ await disposeAndExit("EXIT");
14
+ });
15
+ process.once("SIGTERM", async (arg) => {
16
+ logger.info(arg, "SIGTERM");
17
+ await disposeAndExit("EXIT");
18
+ });
19
+ process.once("uncaughtException", async (arg) => {
20
+ logger.error(arg, "Uncaught Exception");
21
+ await disposeAndExit("ERROR");
22
+ });
23
+ process.once("unhandledRejection", async (arg) => {
24
+ logger.error(arg, "Unhandled Rejection");
25
+ await disposeAndExit("ERROR");
26
+ });
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjD,kBAAkB;AAClB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,CAAC;AAElB,kBAAkB;AAClB,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAS,EAAE,EAAE;IACzC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC3B,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,GAAS,EAAE,EAAE;IAC1C,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC5B,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,EAAE,GAAS,EAAE,EAAE;IACpD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;IACxC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAS,EAAE,EAAE;IACrD,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;IACzC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Disposable, Disposer, Store } from "./types";
2
+ export declare const ExitCodes: readonly ["ERROR", "EXIT"];
3
+ export type ExitCode = (typeof ExitCodes)[number];
4
+ export declare const logger: import("pino").Logger<never, boolean>;
5
+ type Injector<Port extends Disposable> = (adapter?: Port) => Port;
6
+ export declare function port<Port extends Disposable>(injector: Injector<Port>): (adapter?: Port) => Port;
7
+ export declare function disposeAndExit(code?: ExitCode): Promise<void>;
8
+ /**
9
+ * Registers resource disposers that are triggered on process exit
10
+ * @param disposer the disposer function
11
+ * @returns a function that triggers all registered disposers and terminates the process
12
+ */
13
+ export declare function dispose(disposer?: Disposer): (code?: ExitCode) => Promise<void>;
14
+ export declare const SNAP_EVENT = "__snapshot__";
15
+ export declare const store: (adapter?: Store | undefined) => Store;
16
+ export {};
17
+ //# sourceMappingURL=ports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ports.d.ts","sourceRoot":"","sources":["../src/ports.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAE3D,eAAO,MAAM,SAAS,4BAA6B,CAAC;AACpD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,eAAO,MAAM,MAAM,uCAajB,CAAC;AAEH,KAAK,QAAQ,CAAC,IAAI,SAAS,UAAU,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,IAAI,CAAC;AAElE,wBAAgB,IAAI,CAAC,IAAI,SAAS,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,cACzC,IAAI,KAAG,IAAI,CAQvC;AAGD,wBAAsB,cAAc,CAAC,IAAI,GAAE,QAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAa3E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACrB,QAAQ,CAAC,EAAE,QAAQ,GAClB,CAAC,IAAI,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAGpC;AAGD,eAAO,MAAM,UAAU,iBAAiB,CAAC;AACzC,eAAO,MAAM,KAAK,wCAEhB,CAAC"}