@schorts/shared-kernel 1.0.4 → 1.0.5

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/CHANGELOG CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.5] - 2025-09-30
9
+
10
+ ### Added
11
+
12
+ - Introduce `DAO` concept for a related package with a `Firestore` implementation.
13
+ - Introduce `UnitOfWOrk` concept for a related package with a `Firestore` implementation.
14
+
8
15
  ## [1.0.4] - 2025-09-30
9
16
 
10
17
  ### Fixed
@@ -21,5 +28,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
21
28
 
22
29
  - Removed indirect dependencies from the `package.json`.
23
30
 
24
- [1.0.3]: https://github.com/schorts99/shared-kernel/compare/v1.0.3...v0.0.4
31
+ [1.0.5]: https://github.com/schorts99/shared-kernel/compare/v1.0.4...v0.0.5
32
+ [1.0.4]: https://github.com/schorts99/shared-kernel/compare/v1.0.3...v0.0.4
25
33
  [1.0.3]: https://github.com/schorts99/shared-kernel/releases/tag/v1.0.3
package/README.md CHANGED
@@ -44,6 +44,11 @@ npm install @schorts/shared-kernel --save
44
44
 
45
45
  - **BaseModel:** Base class for serializable, type-safe models.
46
46
 
47
+ ### 🛠 Persistence
48
+
49
+ - **DAO:** Generic interface defining data access operations for domain entities.
50
+ - **UnitOfWork:** Interface enabling transactional coordination across multiple persistence operations.
51
+
47
52
  ### 🧠 State Manager
48
53
 
49
54
  - **StateManager:** Abstract reactive state manager with listener support.
@@ -0,0 +1,116 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { DAO } from "../../src/dao";
4
+ import { Entity } from "../../src/entities";
5
+ import { Criteria } from "../../src/criteria";
6
+
7
+ type Model = {
8
+ id: string;
9
+ name: string;
10
+ };
11
+
12
+ class ModelEntity extends Entity<Model> {
13
+ toPrimitives(): Model {
14
+ throw new Error("Method not implemented.");
15
+ }
16
+ }
17
+
18
+ describe("DAO", () => {
19
+ describe('#getAll', () => {
20
+ it('should declare the method', () => {
21
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("getAll");
22
+ });
23
+
24
+ it('should no require any arguments', () => {
25
+ expectTypeOf<DAO<Model, ModelEntity>['getAll']>().parameters.toEqualTypeOf<[]>();
26
+ });
27
+
28
+ it('should return a promise with the Entity', () => {
29
+ expectTypeOf<DAO<Model, ModelEntity>['getAll']>().returns.toEqualTypeOf<Promise<ModelEntity[]>>();
30
+ });
31
+ });
32
+
33
+ describe('#findByID', () => {
34
+ it('should declare the method', () => {
35
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("findByID");
36
+ });
37
+
38
+ it('should require the ID argument', () => {
39
+ expectTypeOf<DAO<Model, ModelEntity>['findByID']>().parameters.toEqualTypeOf<[ModelEntity["id"]["value"]]>();
40
+ });
41
+
42
+ it('should return a promise with the Entity or null', () => {
43
+ expectTypeOf<DAO<Model, ModelEntity>['findByID']>().returns.toEqualTypeOf<Promise<ModelEntity | null>>();
44
+ });
45
+ });
46
+
47
+ describe('#findOneBy', () => {
48
+ it('should declare the method', () => {
49
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("findOneBy");
50
+ });
51
+
52
+ it('should receive the criteria', () => {
53
+ expectTypeOf<DAO<Model, ModelEntity>['findOneBy']>().parameters.toEqualTypeOf<[Criteria]>();
54
+ });
55
+
56
+ it('should return a promise with the Entity or null', () => {
57
+ expectTypeOf<DAO<Model, ModelEntity>['findOneBy']>().returns.toEqualTypeOf<Promise<ModelEntity | null>>();
58
+ });
59
+ });
60
+
61
+ describe('#search', () => {
62
+ it('should declare the method', () => {
63
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("search");
64
+ });
65
+
66
+ it('should receive the criteria argument', () => {
67
+ expectTypeOf<DAO<Model, ModelEntity>['search']>().parameters.toEqualTypeOf<[Criteria]>();
68
+ });
69
+
70
+ it('should return a promise with an array of entities', () => {
71
+ expectTypeOf<DAO<Model, ModelEntity>['search']>().returns.toEqualTypeOf<Promise<ModelEntity[]>>();
72
+ });
73
+ });
74
+
75
+ describe('#create', () => {
76
+ it('should declare the method', () => {
77
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("create");
78
+ });
79
+
80
+ it('should receive the entity argument', () => {
81
+ expectTypeOf<DAO<Model, ModelEntity>['create']>().parameters.toEqualTypeOf<[ModelEntity]>();
82
+ });
83
+
84
+ it('should return a promise with the created entity', () => {
85
+ expectTypeOf<DAO<Model, ModelEntity>['create']>().returns.toEqualTypeOf<Promise<ModelEntity>>();
86
+ });
87
+ });
88
+
89
+ describe('#update', () => {
90
+ it('should declare the method', () => {
91
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("update");
92
+ });
93
+
94
+ it('should receive the entity argument', () => {
95
+ expectTypeOf<DAO<Model, ModelEntity>['update']>().parameters.toEqualTypeOf<[ModelEntity]>();
96
+ });
97
+
98
+ it('should return a promise with the updated entity', () => {
99
+ expectTypeOf<DAO<Model, ModelEntity>['update']>().returns.toEqualTypeOf<Promise<ModelEntity>>();
100
+ });
101
+ });
102
+
103
+ describe('#delete', () => {
104
+ it('should declare the method', () => {
105
+ expectTypeOf<DAO<Model, ModelEntity>>().toHaveProperty("delete");
106
+ });
107
+
108
+ it('should receive the entity argument', () => {
109
+ expectTypeOf<DAO<Model, ModelEntity>['delete']>().parameters.toEqualTypeOf<[ModelEntity]>();
110
+ });
111
+
112
+ it('should return a promise with the deleted entity', () => {
113
+ expectTypeOf<DAO<Model, ModelEntity>['delete']>().returns.toEqualTypeOf<Promise<ModelEntity>>();
114
+ });
115
+ });
116
+ });
@@ -0,0 +1,47 @@
1
+ import { expectTypeOf } from "expect-type";
2
+
3
+ import { UnitOfWork } from "../../src/unit-of-work";
4
+
5
+ describe("UnitOfWork", () => {
6
+ describe('#begin', () => {
7
+ it('should declare the method', () => {
8
+ expectTypeOf<UnitOfWork>().toHaveProperty("begin");
9
+ });
10
+
11
+ it('should no require any arguments', () => {
12
+ expectTypeOf<UnitOfWork['begin']>().parameters.toEqualTypeOf<[]>();
13
+ });
14
+
15
+ it('should return a promise', () => {
16
+ expectTypeOf<UnitOfWork['begin']>().returns.toEqualTypeOf<Promise<void>>();
17
+ });
18
+ })
19
+
20
+ describe('#commit', () => {
21
+ it('should declare the method', () => {
22
+ expectTypeOf<UnitOfWork>().toHaveProperty("commit");
23
+ });
24
+
25
+ it('should no require any arguments', () => {
26
+ expectTypeOf<UnitOfWork['commit']>().parameters.toEqualTypeOf<[]>();
27
+ });
28
+
29
+ it('should return a promise', () => {
30
+ expectTypeOf<UnitOfWork['commit']>().returns.toEqualTypeOf<Promise<void>>();
31
+ });
32
+ })
33
+
34
+ describe('#rollback', () => {
35
+ it('should declare the method', () => {
36
+ expectTypeOf<UnitOfWork>().toHaveProperty("rollback");
37
+ });
38
+
39
+ it('should no require any arguments', () => {
40
+ expectTypeOf<UnitOfWork['rollback']>().parameters.toEqualTypeOf<[]>();
41
+ });
42
+
43
+ it('should return a promise', () => {
44
+ expectTypeOf<UnitOfWork['rollback']>().returns.toEqualTypeOf<Promise<void>>();
45
+ });
46
+ })
47
+ });
package/jest.config.js CHANGED
@@ -1,5 +1,5 @@
1
- // jest.config.js
2
- const { defaults: tsjPreset } = require("ts-jest/presets");
1
+ // jest.config.js
2
+ const { defaults: tsjPreset } = require("ts-jest/presets");
3
3
  const { transform } = require("typescript");
4
4
 
5
5
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schorts/shared-kernel",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A modular, type-safe foundation for building expressive, maintainable applications. This package provides core abstractions for domain modeling, HTTP integration, authentication, state management, and more — designed to be framework-agnostic and highly extensible.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,6 +13,10 @@
13
13
  "import": "./dist/criteria/index.js",
14
14
  "types": "./dist/criteria/index.d.ts"
15
15
  },
16
+ "./dao": {
17
+ "import": "./dist/dao/index.js",
18
+ "types": "./dist/dao/index.d.ts"
19
+ },
16
20
  "./domain-events": {
17
21
  "import": "./dist/domain-events/index.js",
18
22
  "types": "./dist/domain-events/index.d.ts"
@@ -41,6 +45,10 @@
41
45
  "import": "./dist/models/index.js",
42
46
  "types": "./dist/models/index.d.ts"
43
47
  },
48
+ "./unit-of-work": {
49
+ "import": "./dist/unit-of-work/index.js",
50
+ "types": "./dist/unit-of-work/index.d.ts"
51
+ },
44
52
  "./utils": {
45
53
  "import": "./dist/utils/index.js",
46
54
  "types": "./dist/utils/index.d.ts"
@@ -81,6 +89,7 @@
81
89
  "shared-kernel",
82
90
  "auth",
83
91
  "jsonapi",
92
+ "dao",
84
93
  "kernel",
85
94
  "value-objects",
86
95
  "criteria",
package/src/dao/dao.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { BaseModel } from "../models";
2
+ import { Entity as BaseEntity } from "../entities";
3
+ import { Criteria } from "../criteria";
4
+
5
+ export interface DAO<Model extends BaseModel, Entity extends BaseEntity<Model>> {
6
+ getAll(): Promise<Entity[]>;
7
+ findByID(id: Entity["id"]["value"]): Promise<Entity | null>;
8
+ findOneBy(criteria: Criteria): Promise<Entity | null>;
9
+ search(criteria: Criteria): Promise<Entity[]>;
10
+ create(entity: Entity): Promise<Entity>;
11
+ update(entity: Entity): Promise<Entity>;
12
+ delete(entity: Entity): Promise<Entity>;
13
+ }
@@ -0,0 +1 @@
1
+ export type { DAO } from "./dao";
@@ -0,0 +1 @@
1
+ export type { UnitOfWork } from "./unit-of-work";
@@ -0,0 +1,5 @@
1
+ export interface UnitOfWork {
2
+ begin(): Promise<void>;
3
+ commit(): Promise<void>;
4
+ rollback(): Promise<void>;
5
+ }