archstone 1.3.0 → 1.4.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.
package/README.md CHANGED
@@ -224,9 +224,9 @@ export interface AuditRepository extends Creatable<AuditLog> {}
224
224
  | Import | Contents |
225
225
  |---|---|
226
226
  | `archstone` | Everything |
227
- | `archstone/core` | `Either`, `ValueObject`, `UniqueEntityId`, `WatchedList`, `Optional`, `EventHandler` |
227
+ | `archstone/core` | `Either`, `ValueObject`, `UniqueEntityId`, `WatchedList`, `Optional`, `DomainEvent`, `DomainEvents`, `EventHandler` |
228
228
  | `archstone/domain` | All domain exports |
229
- | `archstone/domain/enterprise` | `Entity`, `AggregateRoot`, `DomainEvent`, `DomainEvents` |
229
+ | `archstone/domain/enterprise` | `Entity`, `AggregateRoot` |
230
230
  | `archstone/domain/application` | `UseCase`, `UseCaseError`, repository contracts |
231
231
 
232
232
  All sub-paths share type declarations via a common chunk — mixing imports from multiple sub-paths is fully type-safe with no duplicate declaration conflicts.
@@ -242,18 +242,18 @@ src/
242
242
  │ ├── value-object.ts # Value equality base class
243
243
  │ ├── unique-entity-id.ts # UUID v7 identity wrapper
244
244
  │ ├── watched-list.ts # Change-tracked collection
245
+ │ ├── events/
246
+ │ │ ├── domain-event.ts # Marker interface for all domain events
247
+ │ │ ├── domain-events.ts # Central registry and dispatcher (singleton)
248
+ │ │ └── event-handler.ts # Generic handler interface EventHandler<T>
245
249
  │ └── types/
246
250
  │ └── optional.ts # Optional<T, K> helper type
247
251
 
248
252
  └── domain/
249
253
  ├── enterprise/ # Pure domain model — zero framework dependencies
250
- ├── entities/
251
- ├── entity.ts
252
- └── aggregate-root.ts
253
- │ └── events/
254
- │ ├── domain-event.ts
255
- │ ├── domain-events.ts
256
- │ └── event-handler.ts
254
+ └── entities/
255
+ ├── entity.ts
256
+ └── aggregate-root.ts
257
257
 
258
258
  └── application/ # Orchestration — use cases & repository contracts
259
259
  ├── use-cases/
@@ -269,6 +269,73 @@ src/
269
269
 
270
270
  ---
271
271
 
272
+ ## Technology Stack
273
+
274
+ | | |
275
+ |---|---|
276
+ | **Language** | TypeScript 5+ |
277
+ | **Runtime / Package Manager** | [Bun](https://bun.sh) (required) |
278
+ | **Test Framework** | `bun:test` (built-in) |
279
+ | **Build Tool** | [bunup](https://github.com/nicepkg/bunup) |
280
+ | **Linter / Formatter** | [Biome](https://biomejs.dev) via [Ultracite](https://ultracite.dev) |
281
+ | **Dependencies** | None (zero runtime dependencies) |
282
+
283
+ ---
284
+
285
+ ## Development Workflow
286
+
287
+ Requirements: **Bun >= 1.0**
288
+
289
+ ```bash
290
+ bun install # install dev dependencies
291
+ bun test # run tests
292
+ bun run build # compile to dist/
293
+ bun x ultracite fix # lint + format
294
+ ```
295
+
296
+ Branch naming: `feat/<name>`, `fix/<name>`, `docs/<name>`, `chore/<name>`
297
+
298
+ Every commit must pass `bun test` and `bun x ultracite fix` before pushing.
299
+
300
+ ---
301
+
302
+ ## Coding Standards
303
+
304
+ - **Error handling:** never throw inside use cases — always return `left(error)` with `Either`
305
+ - **Imports:** always import from a layer's index (`archstone/core`, `archstone/domain/enterprise`), never from deep paths
306
+ - **Layer boundaries:** inner layers never import outer ones — `core` has zero domain knowledge, `enterprise` never imports `application`
307
+ - **Factories:** always provide a static `create()` factory on entities and value objects — never expose constructors directly
308
+ - **Style:** no semicolons, 2-space indent, double quotes (enforced by Biome via Ultracite)
309
+ - **Commits:** [Conventional Commits](https://www.conventionalcommits.org/) — `feat`, `fix`, `chore`, `docs`, `refactor`, `test`
310
+
311
+ ---
312
+
313
+ ## Testing
314
+
315
+ Framework: `bun:test`. Test files are `*.spec.ts` co-located with the source they test.
316
+
317
+ ```ts
318
+ import { test, expect } from "bun:test"
319
+
320
+ test("example", () => {
321
+ expect(1).toBe(1)
322
+ })
323
+ ```
324
+
325
+ Use **in-memory repository implementations** for use case tests — never couple tests to a real database. Isolate domain event state between tests:
326
+
327
+ ```ts
328
+ import { DomainEvents } from "archstone/core"
329
+ import { beforeEach } from "bun:test"
330
+
331
+ beforeEach(() => {
332
+ DomainEvents.clearHandlers()
333
+ DomainEvents.clearMarkedAggregates()
334
+ })
335
+ ```
336
+
337
+ ---
338
+
272
339
  ## Agent Skills — new in v1.1.0
273
340
 
274
341
  Archstone ships with a built-in skill for AI coding agents. Once installed, your agent understands every DDD convention, layer boundary, and usage pattern — without you ever having to explain them.
@@ -297,7 +364,7 @@ cp -r node_modules/archstone/skills/use-archstone .claude/skills/
297
364
 
298
365
  <div align="center">
299
366
 
300
- **Built with care for the TypeScript community.**
367
+ **Built with ❤️ for the TypeScript community.**
301
368
 
302
369
  [Contributing](./CONTRIBUTING.md) · [Code of Conduct](./CODE_OF_CONDUCT.md) · [MIT License](./LICENSE)
303
370
 
@@ -1,2 +1,2 @@
1
- import { DomainEvent, DomainEvents, Either, EventHandler1 as EventHandler, Optional, UniqueEntityId, ValueObject, WatchedList, left, right } from "../shared/chunk-z9br464b.js";
2
- export { right, left, WatchedList, ValueObject, UniqueEntityId, Optional, EventHandler, Either, DomainEvents, DomainEvent };
1
+ import { DomainEvent, DomainEvents, Either, EventHandler1 as EventHandler, Maybe, Optional, UniqueEntityId, ValueObject, WatchedList, just, left, maybe, nothing, right } from "../shared/chunk-w9w4akh1.js";
2
+ export { right, nothing, maybe, left, just, WatchedList, ValueObject, UniqueEntityId, Optional, Maybe, EventHandler, Either, DomainEvents, DomainEvent };
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{c as a,d as b,e as c,f as d,g as e,h as f}from"../shared/chunk-8hx7pxm3.js";export{b as right,a as left,f as WatchedList,e as ValueObject,d as UniqueEntityId,c as DomainEvents};
2
+ import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h,k as i}from"../shared/chunk-q4ayz844.js";export{i as right,h as nothing,g as maybe,f as left,e as just,d as WatchedList,c as ValueObject,b as UniqueEntityId,a as DomainEvents};
@@ -1,2 +1,2 @@
1
- import { Creatable, Deletable, Findable, Repository, Saveable, UseCase, UseCaseError } from "../../shared/chunk-z9br464b.js";
1
+ import { Creatable, Deletable, Findable, Repository, Saveable, UseCase, UseCaseError } from "../../shared/chunk-w9w4akh1.js";
2
2
  export { UseCaseError, UseCase, Saveable, Repository, Findable, Deletable, Creatable };
@@ -1,2 +1,2 @@
1
- import { AggregateRoot, DomainEvent, DomainEvents, Entity, EventHandler } from "../../shared/chunk-z9br464b.js";
1
+ import { AggregateRoot, DomainEvent, DomainEvents, Entity, EventHandler } from "../../shared/chunk-w9w4akh1.js";
2
2
  export { EventHandler, Entity, DomainEvents, DomainEvent, AggregateRoot };
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{a as b,b as c}from"../../shared/chunk-k39ksk62.js";import{e as a}from"../../shared/chunk-8hx7pxm3.js";export{b as Entity,a as DomainEvents,c as AggregateRoot};
2
+ import{a as b,b as c}from"../../shared/chunk-whqnrgyf.js";import{c as a}from"../../shared/chunk-q4ayz844.js";export{b as Entity,a as DomainEvents,c as AggregateRoot};
@@ -1,2 +1,2 @@
1
- import { AggregateRoot, Creatable, Deletable, DomainEvent, DomainEvents, Entity, EventHandler, Findable, Repository, Saveable, UseCase, UseCaseError } from "../shared/chunk-z9br464b.js";
1
+ import { AggregateRoot, Creatable, Deletable, DomainEvent, DomainEvents, Entity, EventHandler, Findable, Repository, Saveable, UseCase, UseCaseError } from "../shared/chunk-w9w4akh1.js";
2
2
  export { UseCaseError, UseCase, Saveable, Repository, Findable, EventHandler, Entity, DomainEvents, DomainEvent, Deletable, Creatable, AggregateRoot };
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import"../shared/chunk-x296z7h1.js";import"../shared/chunk-wsjyhnpq.js";import{a as b,b as c}from"../shared/chunk-k39ksk62.js";import{e as a}from"../shared/chunk-8hx7pxm3.js";export{b as Entity,a as DomainEvents,c as AggregateRoot};
2
+ import"../shared/chunk-x296z7h1.js";import"../shared/chunk-wsjyhnpq.js";import{a as b,b as c}from"../shared/chunk-whqnrgyf.js";import{c as a}from"../shared/chunk-q4ayz844.js";export{b as Entity,a as DomainEvents,c as AggregateRoot};
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { AggregateRoot, Creatable, Deletable, DomainEvent, DomainEvents, Either, Entity, Findable, Optional, Repository, Saveable, UniqueEntityId, UseCase, UseCaseError, ValueObject, WatchedList, left, right } from "./shared/chunk-z9br464b.js";
2
- export { right, left, WatchedList, ValueObject, UseCaseError, UseCase, UniqueEntityId, Saveable, Repository, Optional, Findable, Entity, Either, DomainEvents, DomainEvent, Deletable, Creatable, AggregateRoot };
1
+ import { AggregateRoot, Creatable, Deletable, DomainEvent, DomainEvents, Either, Entity, Findable, Maybe, Optional, Repository, Saveable, UniqueEntityId, UseCase, UseCaseError, ValueObject, WatchedList, just, left, maybe, nothing, right } from "./shared/chunk-w9w4akh1.js";
2
+ export { right, nothing, maybe, left, just, WatchedList, ValueObject, UseCaseError, UseCase, UniqueEntityId, Saveable, Repository, Optional, Maybe, Findable, Entity, Either, DomainEvents, DomainEvent, Deletable, Creatable, AggregateRoot };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import"./shared/chunk-x296z7h1.js";import"./shared/chunk-wsjyhnpq.js";import{a as b,b as c}from"./shared/chunk-k39ksk62.js";import{c as f,d as m,e as p,f as t,g as x,h as a}from"./shared/chunk-8hx7pxm3.js";export{m as right,f as left,a as WatchedList,x as ValueObject,t as UniqueEntityId,b as Entity,p as DomainEvents,c as AggregateRoot};
2
+ import"./shared/chunk-x296z7h1.js";import"./shared/chunk-wsjyhnpq.js";import{a as g,b as h}from"./shared/chunk-whqnrgyf.js";import{c as f,d as m,e as p,f as t,g as x,h as a,i as b,j as c,k as d}from"./shared/chunk-q4ayz844.js";export{d as right,c as nothing,b as maybe,a as left,x as just,t as WatchedList,p as ValueObject,m as UniqueEntityId,g as Entity,f as DomainEvents,h as AggregateRoot};
@@ -0,0 +1,2 @@
1
+ // @bun
2
+ import{just as Q,left as X,maybe as Y,nothing as Z,right as _}from"failcraft";class O{handlersMap=new Map;markedAggregates=new Set;shouldRun=!0;markAggregateForDispatch(x){if(!this.findMarkedAggregateByID(x.id))this.markedAggregates.add(x)}dispatchEventsForAggregate(x){let E=this.findMarkedAggregateByID(x);if(E)this.dispatchAggregateEvents(E),E.clearEvents(),this.removeAggregateFromMarkedDispatchList(E)}register(x,E){if(!this.handlersMap.has(E))this.handlersMap.set(E,[]);this.handlersMap.get(E)?.push(x)}clearHandlers(){this.handlersMap.clear()}clearMarkedAggregates(){this.markedAggregates.clear()}dispatchAggregateEvents(x){for(let E of x.domainEvents)this.dispatch(E)}removeAggregateFromMarkedDispatchList(x){this.markedAggregates.delete(x)}findMarkedAggregateByID(x){return[...this.markedAggregates].find((E)=>E.id.equals(x))}dispatch(x){if(!this.shouldRun)return;let E=this.handlersMap.get(x.constructor.name)??[];for(let f of E)f(x)}}var M=new O;var{randomUUIDv7:V}=globalThis.Bun;class y{value;constructor(x){this.value=x??V()}toValue(){return this.value}toString(){return this.value}equals(x){return x.toValue()===this.value}}class H{props;constructor(x){this.props=x}equals(x){return JSON.stringify(this.props)===JSON.stringify(x.props)}}class L{currentItems;initial;new;removed;constructor(x){this.currentItems=x??[],this.initial=x??[],this.new=[],this.removed=[]}getItems(){return this.currentItems}getNewItems(){return this.new}getRemovedItems(){return this.removed}exists(x){return this.isCurrentItem(x)}add(x){if(this.isRemovedItem(x))this.removeFromRemoved(x);if(!(this.isNewItem(x)||this.wasAddedInitially(x)))this.new.push(x);if(!this.isCurrentItem(x))this.currentItems.push(x)}remove(x){if(this.removeFromCurrent(x),this.isNewItem(x)){this.removeFromNew(x);return}if(!this.isRemovedItem(x))this.removed.push(x)}update(x){this.new=x.filter((E)=>!this.getItems().some((f)=>this.compareItems(E,f))),this.removed=this.getItems().filter((E)=>!x.some((f)=>this.compareItems(E,f))),this.currentItems=x}isCurrentItem(x){return this.currentItems.some((E)=>this.compareItems(x,E))}isNewItem(x){return this.new.some((E)=>this.compareItems(x,E))}isRemovedItem(x){return this.removed.some((E)=>this.compareItems(x,E))}removeFromNew(x){this.new=this.new.filter((E)=>!this.compareItems(E,x))}removeFromCurrent(x){this.currentItems=this.currentItems.filter((E)=>!this.compareItems(x,E))}removeFromRemoved(x){this.removed=this.removed.filter((E)=>!this.compareItems(x,E))}wasAddedInitially(x){return this.initial.some((E)=>this.compareItems(x,E))}}export{M as c,y as d,H as e,L as f,Q as g,X as h,Y as i,Z as j,_ as k};
@@ -76,109 +76,7 @@ interface Saveable<T> {
76
76
  * ```
77
77
  */
78
78
  interface Repository<T> extends Findable<T>, Saveable<T>, Creatable<T>, Deletable<T> {}
79
- /**
80
- * Base contract for all use case errors.
81
- *
82
- * Implement this interface to define semantic, domain-aware errors
83
- * that can be returned as the left side of an {@link Either}.
84
- *
85
- * @example
86
- * ```ts
87
- * class UserNotFoundError implements UseCaseError {
88
- * message = "User not found."
89
- * }
90
- *
91
- * type FindUserResult = Either<UserNotFoundError, User>
92
- * ```
93
- */
94
- interface UseCaseError {
95
- message: string;
96
- }
97
- /**
98
- * Represents the left side of an {@link Either} — conventionally used for
99
- * failure or error values.
100
- *
101
- * @template L - The type of the failure value
102
- * @template R - The type of the success value
103
- */
104
- declare class Left<
105
- L,
106
- R
107
- > {
108
- readonly value: L;
109
- constructor(value: L);
110
- isRight(): this is Right<L, R>;
111
- isLeft(): this is Left<L, R>;
112
- }
113
- /**
114
- * Represents the right side of an {@link Either} — conventionally used for
115
- * success values.
116
- *
117
- * @template L - The type of the failure value
118
- * @template R - The type of the success value
119
- */
120
- declare class Right<
121
- L,
122
- R
123
- > {
124
- readonly value: R;
125
- constructor(value: R);
126
- isRight(): this is Right<L, R>;
127
- isLeft(): this is Left<L, R>;
128
- }
129
- /**
130
- * A discriminated union that represents a value of one of two possible types.
131
- *
132
- * Commonly used as a type-safe alternative to throwing exceptions — the left
133
- * side carries an error, and the right side carries a success value.
134
- *
135
- * Use the {@link left} and {@link right} helper functions to construct values,
136
- * and `isLeft()` / `isRight()` to narrow the type.
137
- *
138
- * @template L - The type of the failure value
139
- * @template R - The type of the success value
140
- *
141
- * @example
142
- * ```ts
143
- * type FindUserResult = Either<NotFoundError, User>
144
- *
145
- * function findUser(id: string): FindUserResult {
146
- * const user = db.find(id)
147
- * if (!user) return left(new NotFoundError("User", id))
148
- * return right(user)
149
- * }
150
- *
151
- * const result = findUser("123")
152
- *
153
- * if (result.isLeft()) {
154
- * console.error(result.value) // NotFoundError
155
- * } else {
156
- * console.log(result.value) // User
157
- * }
158
- * ```
159
- */
160
- type Either<
161
- L,
162
- R
163
- > = Left<L, R> | Right<L, R>;
164
- /**
165
- * Constructs a {@link Left} value, representing a failure.
166
- *
167
- * @param value - The error or failure value
168
- */
169
- declare const left: <
170
- L,
171
- R
172
- >(value: L) => Either<L, R>;
173
- /**
174
- * Constructs a {@link Right} value, representing a success.
175
- *
176
- * @param value - The success value
177
- */
178
- declare const right: <
179
- L,
180
- R
181
- >(value: R) => Either<L, R>;
79
+ import { Either, just, left, Maybe, maybe, nothing, right } from "failcraft";
182
80
  /**
183
81
  * Base contract for all domain events.
184
82
  *
@@ -346,6 +244,15 @@ declare class DomainEventsImplementation {
346
244
  private readonly handlersMap;
347
245
  private readonly markedAggregates;
348
246
  /**
247
+ * Controls whether event dispatching is active.
248
+ *
249
+ * Set to `false` in tests that construct aggregates but do not want
250
+ * side-effects to run, without having to clear and re-register handlers.
251
+ *
252
+ * @default true
253
+ */
254
+ shouldRun: boolean;
255
+ /**
349
256
  * Marks an aggregate root to have its events dispatched.
350
257
  * Called automatically by {@link AggregateRoot.addDomainEvent}.
351
258
  *
@@ -623,6 +530,24 @@ declare abstract class WatchedList<T> {
623
530
  private wasAddedInitially;
624
531
  }
625
532
  /**
533
+ * Base contract for all use case errors.
534
+ *
535
+ * Implement this interface to define semantic, domain-aware errors
536
+ * that can be returned as the left side of an {@link Either}.
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * class UserNotFoundError implements UseCaseError {
541
+ * message = "User not found."
542
+ * }
543
+ *
544
+ * type FindUserResult = Either<UserNotFoundError, User>
545
+ * ```
546
+ */
547
+ interface UseCaseError {
548
+ message: string;
549
+ }
550
+ /**
626
551
  * Represents the expected output shape of any use case.
627
552
  * Always an {@link Either} — left for errors, right for success.
628
553
  */
@@ -662,4 +587,4 @@ interface UseCase<
662
587
  > {
663
588
  execute(input: Input): Promise<Output>;
664
589
  }
665
- export { Either, left, right, DomainEvent, Creatable, Deletable, Findable, Saveable, Repository, UseCaseError, UseCase, Entity, AggregateRoot, EventHandler, DomainEvents, EventHandler2 as EventHandler1, Optional, UniqueEntityId, ValueObject, WatchedList };
590
+ export { DomainEvent, Creatable, Deletable, Findable, Saveable, Repository, UseCaseError, UseCase, Entity, AggregateRoot, EventHandler, DomainEvents, EventHandler2 as EventHandler1, Optional, UniqueEntityId, ValueObject, WatchedList, Either, just, left, Maybe, maybe, nothing, right };
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{e as j,f as k}from"./chunk-8hx7pxm3.js";class R{_id;props;get id(){return this._id}constructor(A,B){this._id=B??new k,this.props=A}equals(A){if(A===this)return!0;return A.id.equals(this._id)}}class z extends R{_domainEvents=new Set;get domainEvents(){return Array.from(this._domainEvents)}addDomainEvent(A){this._domainEvents.add(A),j.markAggregateForDispatch(this)}clearEvents(){this._domainEvents.clear()}}export{R as a,z as b};
2
+ import{c as j,d as k}from"./chunk-q4ayz844.js";class R{_id;props;get id(){return this._id}constructor(A,B){this._id=B??new k,this.props=A}equals(A){if(A===this)return!0;return A.id.equals(this._id)}}class z extends R{_domainEvents=new Set;get domainEvents(){return Array.from(this._domainEvents)}addDomainEvent(A){this._domainEvents.add(A),j.markAggregateForDispatch(this)}clearEvents(){this._domainEvents.clear()}}export{R as a,z as b};
package/package.json CHANGED
@@ -1,15 +1,25 @@
1
1
  {
2
2
  "name": "archstone",
3
- "description": "TypeScript architecture foundation for backend services based on Domain-Driven Design and Clean Architecture",
4
- "version": "1.3.0",
5
- "type": "module",
6
- "private": false,
7
- "files": [
8
- "dist",
9
- "skills"
10
- ],
3
+ "version": "1.4.0",
4
+ "author": {
5
+ "name": "João Henrique Benatti Coimbra",
6
+ "url": "https://github.com/joao-coimbra"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/joao-coimbra/archstone.git"
11
+ },
11
12
  "module": "./dist/index.js",
12
- "types": "./dist/index.d.ts",
13
+ "devDependencies": {
14
+ "@biomejs/biome": "2.4.5",
15
+ "@types/bun": "latest",
16
+ "bunup": "^0.16.31",
17
+ "husky": "^9.1.7",
18
+ "ultracite": "7.3.0"
19
+ },
20
+ "peerDependencies": {
21
+ "typescript": "^5"
22
+ },
13
23
  "exports": {
14
24
  ".": {
15
25
  "import": {
@@ -43,6 +53,15 @@
43
53
  },
44
54
  "./package.json": "./package.json"
45
55
  },
56
+ "bugs": {
57
+ "url": "https://github.com/joao-coimbra/archstone/issues"
58
+ },
59
+ "description": "TypeScript architecture foundation for backend services based on Domain-Driven Design and Clean Architecture",
60
+ "files": [
61
+ "dist",
62
+ "skills"
63
+ ],
64
+ "homepage": "https://github.com/joao-coimbra/archstone#readme",
46
65
  "keywords": [
47
66
  "ddd",
48
67
  "domain-driven-design",
@@ -57,19 +76,8 @@
57
76
  "use-case",
58
77
  "bun"
59
78
  ],
60
- "author": {
61
- "name": "João Henrique Benatti Coimbra",
62
- "url": "https://github.com/joao-coimbra"
63
- },
64
79
  "license": "MIT",
65
- "homepage": "https://github.com/joao-coimbra/archstone#readme",
66
- "repository": {
67
- "type": "git",
68
- "url": "git+https://github.com/joao-coimbra/archstone.git"
69
- },
70
- "bugs": {
71
- "url": "https://github.com/joao-coimbra/archstone/issues"
72
- },
80
+ "private": false,
73
81
  "scripts": {
74
82
  "build": "bunup",
75
83
  "dev": "bunup --watch",
@@ -80,14 +88,9 @@
80
88
  "prepublishOnly": "bun run build",
81
89
  "prepare": "bunx husky"
82
90
  },
83
- "devDependencies": {
84
- "@biomejs/biome": "2.4.5",
85
- "@types/bun": "latest",
86
- "bunup": "^0.16.31",
87
- "husky": "^9.1.7",
88
- "ultracite": "7.3.0"
89
- },
90
- "peerDependencies": {
91
- "typescript": "^5"
91
+ "type": "module",
92
+ "types": "./dist/index.d.ts",
93
+ "dependencies": {
94
+ "failcraft": "^1.3.1"
92
95
  }
93
96
  }
@@ -1,2 +0,0 @@
1
- // @bun
2
- class H{value;constructor(x){this.value=x}isRight(){return!1}isLeft(){return!0}}class V{value;constructor(x){this.value=x}isRight(){return!0}isLeft(){return!1}}var B=(x)=>new H(x),F=(x)=>new V(x);class W{handlersMap=new Map;markedAggregates=new Set;markAggregateForDispatch(x){if(!this.findMarkedAggregateByID(x.id))this.markedAggregates.add(x)}dispatchEventsForAggregate(x){let E=this.findMarkedAggregateByID(x);if(E)this.dispatchAggregateEvents(E),E.clearEvents(),this.removeAggregateFromMarkedDispatchList(E)}register(x,E){if(!this.handlersMap.has(E))this.handlersMap.set(E,[]);this.handlersMap.get(E)?.push(x)}clearHandlers(){this.handlersMap.clear()}clearMarkedAggregates(){this.markedAggregates.clear()}dispatchAggregateEvents(x){for(let E of x.domainEvents)this.dispatch(E)}removeAggregateFromMarkedDispatchList(x){this.markedAggregates.delete(x)}findMarkedAggregateByID(x){return[...this.markedAggregates].find((E)=>E.id.equals(x))}dispatch(x){let E=this.handlersMap.get(x.constructor.name)??[];for(let O of E)O(x)}}var G=new W;var{randomUUIDv7:J}=globalThis.Bun;class f{value;constructor(x){this.value=x??J()}toValue(){return this.value}toString(){return this.value}equals(x){return x.toValue()===this.value}}class z{props;constructor(x){this.props=x}equals(x){return JSON.stringify(this.props)===JSON.stringify(x.props)}}class A{currentItems;initial;new;removed;constructor(x){this.currentItems=x??[],this.initial=x??[],this.new=[],this.removed=[]}getItems(){return this.currentItems}getNewItems(){return this.new}getRemovedItems(){return this.removed}exists(x){return this.isCurrentItem(x)}add(x){if(this.isRemovedItem(x))this.removeFromRemoved(x);if(!(this.isNewItem(x)||this.wasAddedInitially(x)))this.new.push(x);if(!this.isCurrentItem(x))this.currentItems.push(x)}remove(x){if(this.removeFromCurrent(x),this.isNewItem(x)){this.removeFromNew(x);return}if(!this.isRemovedItem(x))this.removed.push(x)}update(x){this.new=x.filter((E)=>!this.getItems().some((O)=>this.compareItems(E,O))),this.removed=this.getItems().filter((E)=>!x.some((O)=>this.compareItems(E,O))),this.currentItems=x}isCurrentItem(x){return this.currentItems.some((E)=>this.compareItems(x,E))}isNewItem(x){return this.new.some((E)=>this.compareItems(x,E))}isRemovedItem(x){return this.removed.some((E)=>this.compareItems(x,E))}removeFromNew(x){this.new=this.new.filter((E)=>!this.compareItems(E,x))}removeFromCurrent(x){this.currentItems=this.currentItems.filter((E)=>!this.compareItems(x,E))}removeFromRemoved(x){this.removed=this.removed.filter((E)=>!this.compareItems(x,E))}wasAddedInitially(x){return this.initial.some((E)=>this.compareItems(x,E))}}export{B as c,F as d,G as e,f,z as g,A as h};