@venizia/ignis-docs 0.0.1-7 → 0.0.1-9
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/package.json +12 -12
- package/wiki/changelogs/2025-12-17-refactor.md +22 -0
- package/wiki/changelogs/2025-12-18-performance-optimizations.md +192 -0
- package/wiki/changelogs/2025-12-18-repository-validation-security.md +445 -0
- package/wiki/changelogs/index.md +22 -0
- package/wiki/changelogs/v0.0.1-7-initial-architecture.md +137 -0
- package/wiki/changelogs/v0.0.1-8-model-repo-datasource-refactor.md +278 -0
- package/wiki/get-started/5-minute-quickstart.md +1 -1
- package/wiki/get-started/best-practices/api-usage-examples.md +12 -8
- package/wiki/get-started/best-practices/common-pitfalls.md +2 -2
- package/wiki/get-started/best-practices/data-modeling.md +14 -20
- package/wiki/get-started/building-a-crud-api.md +60 -75
- package/wiki/get-started/core-concepts/controllers.md +14 -14
- package/wiki/get-started/core-concepts/persistent.md +110 -130
- package/wiki/get-started/quickstart.md +1 -1
- package/wiki/references/base/controllers.md +40 -16
- package/wiki/references/base/datasources.md +195 -33
- package/wiki/references/base/dependency-injection.md +5 -5
- package/wiki/references/base/models.md +398 -28
- package/wiki/references/base/repositories.md +475 -22
- package/wiki/references/components/authentication.md +224 -7
- package/wiki/references/components/health-check.md +1 -1
- package/wiki/references/components/swagger.md +1 -1
- package/wiki/references/helpers/inversion.md +8 -3
- package/wiki/references/src-details/core.md +6 -5
- package/wiki/references/src-details/inversion.md +4 -4
- package/wiki/references/utilities/request.md +16 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@venizia/ignis-docs",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-9",
|
|
4
4
|
"description": "Documentation and MCP Server for Ignis Framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ignis",
|
|
@@ -27,28 +27,28 @@
|
|
|
27
27
|
"framework",
|
|
28
28
|
"venizia"
|
|
29
29
|
],
|
|
30
|
-
"main": "./mcp-server/
|
|
31
|
-
"types": "./mcp-server/
|
|
30
|
+
"main": "./dist/mcp-server/index.js",
|
|
31
|
+
"types": "./dist/mcp-server/index.d.ts",
|
|
32
32
|
"exports": {
|
|
33
33
|
".": {
|
|
34
|
-
"types": "./mcp-server/
|
|
35
|
-
"default": "./mcp-server/
|
|
34
|
+
"types": "./dist/mcp-server/index.d.ts",
|
|
35
|
+
"default": "./dist/mcp-server/index.js"
|
|
36
36
|
},
|
|
37
37
|
"./tools": {
|
|
38
|
-
"types": "./mcp-server/
|
|
39
|
-
"default": "./mcp-server/
|
|
38
|
+
"types": "./dist/mcp-server/tools/index.d.ts",
|
|
39
|
+
"default": "./dist/mcp-server/tools/index.js"
|
|
40
40
|
},
|
|
41
41
|
"./helpers": {
|
|
42
|
-
"types": "./mcp-server/
|
|
43
|
-
"default": "./mcp-server/
|
|
42
|
+
"types": "./dist/mcp-server/helpers/index.d.ts",
|
|
43
|
+
"default": "./dist/mcp-server/helpers/index.js"
|
|
44
44
|
},
|
|
45
45
|
"./common": {
|
|
46
|
-
"types": "./mcp-server/
|
|
47
|
-
"default": "./mcp-server/
|
|
46
|
+
"types": "./dist/mcp-server/common/index.d.ts",
|
|
47
|
+
"default": "./dist/mcp-server/common/index.js"
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"bin": {
|
|
51
|
-
"ignis-docs-mcp": "./mcp-server/
|
|
51
|
+
"ignis-docs-mcp": "./dist/mcp-server/index.js"
|
|
52
52
|
},
|
|
53
53
|
"files": [
|
|
54
54
|
"README.md",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog - 2025-12-17
|
|
2
|
+
|
|
3
|
+
## Major Refactor: Inversion of Control
|
|
4
|
+
|
|
5
|
+
The Dependency Injection (DI) system has been extracted from `packages/helpers` into a standalone package `@venizia/ignis-inversion`.
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
|
|
9
|
+
- **New Package**: `@venizia/ignis-inversion` created.
|
|
10
|
+
- **Removed**: `packages/helpers/src/helpers/inversion` deleted.
|
|
11
|
+
- **Updated**: `packages/core` now imports DI primitives from `@venizia/ignis-inversion`.
|
|
12
|
+
- **Refactored**: `packages/core/src/helpers/inversion` now re-exports from the new package and adds core-specific extensions.
|
|
13
|
+
|
|
14
|
+
### Impact
|
|
15
|
+
|
|
16
|
+
- **Imports**: Imports from `@venizia/ignis` or `@venizia/ignis-helpers` relating to `Binding`, `Container`, `inject` should generally remain compatible via re-exports, but deep imports to `helpers/inversion` will break.
|
|
17
|
+
- **Structure**: Clearer separation of concerns. `inversion` package has zero dependencies on the rest of the framework (except `lodash`, `reflect-metadata`, `zod`).
|
|
18
|
+
|
|
19
|
+
## Other Changes
|
|
20
|
+
|
|
21
|
+
- **Mixins**: `server-config.mixin.ts` removed from `packages/core`.
|
|
22
|
+
- **Examples**: `examples/vert` updated to reflect latest core changes.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Changelog - 2025-12-18
|
|
2
|
+
|
|
3
|
+
## Performance Optimizations
|
|
4
|
+
|
|
5
|
+
This update focuses on performance improvements for the repository layer, reducing GC pressure and improving query execution speed.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
- **WeakMap Cache**: `DrizzleFilterBuilder` now caches `getTableColumns()` results
|
|
10
|
+
- **Core API for Flat Queries**: `ReadableRepository` uses faster Drizzle Core API when possible
|
|
11
|
+
- **Static schemaFactory Singleton**: `BaseEntity` shares a single `schemaFactory` instance across all entities
|
|
12
|
+
- **Async/Await Refactor**: Removed redundant Promise wrappers from repository methods
|
|
13
|
+
|
|
14
|
+
## Performance Improvements
|
|
15
|
+
|
|
16
|
+
### 1. WeakMap Cache for Filter Builder
|
|
17
|
+
|
|
18
|
+
**File:** `packages/core/src/base/repositories/operators/filter.ts`
|
|
19
|
+
|
|
20
|
+
**Problem:** `getTableColumns()` was called on every filter operation, causing repeated reflection overhead.
|
|
21
|
+
|
|
22
|
+
**Solution:** Added static WeakMap cache that stores column metadata per schema:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
export class DrizzleFilterBuilder extends BaseHelper {
|
|
26
|
+
// Static cache shared across all instances
|
|
27
|
+
private static columnCache = new WeakMap<
|
|
28
|
+
TTableSchemaWithId,
|
|
29
|
+
ReturnType<typeof getTableColumns>
|
|
30
|
+
>();
|
|
31
|
+
|
|
32
|
+
private getColumns<Schema extends TTableSchemaWithId>(schema: Schema) {
|
|
33
|
+
let columns = DrizzleFilterBuilder.columnCache.get(schema);
|
|
34
|
+
if (!columns) {
|
|
35
|
+
columns = getTableColumns(schema);
|
|
36
|
+
DrizzleFilterBuilder.columnCache.set(schema, columns);
|
|
37
|
+
}
|
|
38
|
+
return columns;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Benefits:**
|
|
44
|
+
- First call: `getTableColumns(schema)` → cached
|
|
45
|
+
- Subsequent calls: Retrieved from WeakMap (O(1) lookup)
|
|
46
|
+
- WeakMap allows garbage collection when schema is no longer referenced
|
|
47
|
+
- Especially beneficial for:
|
|
48
|
+
- High-concurrency environments
|
|
49
|
+
- Queries with nested AND/OR conditions (each recursion reuses cache)
|
|
50
|
+
- Multiple queries to the same table
|
|
51
|
+
|
|
52
|
+
### 2. Core API for Flat Queries (~15-20% Faster)
|
|
53
|
+
|
|
54
|
+
**File:** `packages/core/src/base/repositories/core/readable.ts`
|
|
55
|
+
|
|
56
|
+
**Problem:** All queries used Drizzle's Query API, which has overhead for relational mapping even when not needed.
|
|
57
|
+
|
|
58
|
+
**Solution:** Automatically use Drizzle Core API for flat queries (no relations, no field selection):
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// Automatic optimization - no code changes needed
|
|
62
|
+
const users = await repo.find({
|
|
63
|
+
filter: {
|
|
64
|
+
where: { status: 'active' },
|
|
65
|
+
limit: 10,
|
|
66
|
+
order: ['createdAt DESC'],
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
// Uses: db.select().from(table).where(...).orderBy(...).limit(10)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**When Core API is used:**
|
|
73
|
+
|
|
74
|
+
| Filter Options | API Used | Reason |
|
|
75
|
+
|----------------|----------|--------|
|
|
76
|
+
| `where`, `limit`, `order`, `offset` only | Core API | Flat query, no overhead |
|
|
77
|
+
| Has `include` (relations) | Query API | Needs relational mapper |
|
|
78
|
+
| Has `fields` selection | Query API | Core API field syntax differs |
|
|
79
|
+
|
|
80
|
+
**New Protected Methods:**
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// Check if Core API can be used
|
|
84
|
+
protected canUseCoreAPI(filter: TFilter<DataObject>): boolean;
|
|
85
|
+
|
|
86
|
+
// Execute flat query using Core API
|
|
87
|
+
protected async findWithCoreAPI(opts: {
|
|
88
|
+
filter: TFilter<DataObject>;
|
|
89
|
+
findOne?: boolean;
|
|
90
|
+
}): Promise<Array<DataObject>>;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Static schemaFactory Singleton
|
|
94
|
+
|
|
95
|
+
**File:** `packages/core/src/base/models/base.ts`
|
|
96
|
+
|
|
97
|
+
**Problem:** New `schemaFactory` was created for every `BaseEntity` instance:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// Before - created on every instantiation
|
|
101
|
+
constructor(opts?: { name?: string; schema?: Schema }) {
|
|
102
|
+
this.schemaFactory = createSchemaFactory(); // Memory overhead!
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Solution:** Lazy singleton pattern shared across all instances:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
// After - shared singleton
|
|
110
|
+
private static _schemaFactory?: ReturnType<typeof createSchemaFactory>;
|
|
111
|
+
protected static get schemaFactory(): ReturnType<typeof createSchemaFactory> {
|
|
112
|
+
return (BaseEntity._schemaFactory ??= createSchemaFactory());
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Benefits:**
|
|
117
|
+
- Single instance for all entities
|
|
118
|
+
- Lazy initialization (created on first use)
|
|
119
|
+
- Reduced memory footprint
|
|
120
|
+
|
|
121
|
+
### 4. Async/Await Refactor
|
|
122
|
+
|
|
123
|
+
**Files:**
|
|
124
|
+
- `packages/core/src/base/repositories/core/readable.ts`
|
|
125
|
+
- `packages/core/src/base/repositories/core/persistable.ts`
|
|
126
|
+
|
|
127
|
+
**Problem:** Every CRUD method wrapped existing promises in `new Promise()`:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Before - Anti-pattern
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
this.connector.$count(this.entity.schema, where)
|
|
133
|
+
.then((count: number) => resolve({ count }))
|
|
134
|
+
.catch(reject);
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Solution:** Direct async/await:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// After - Clean and efficient
|
|
142
|
+
const count = await this.connector.$count(this.entity.schema, where);
|
|
143
|
+
return { count };
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Benefits:**
|
|
147
|
+
- Eliminates extra microtask queue entries
|
|
148
|
+
- Reduces ~200-400 bytes memory per Promise on V8
|
|
149
|
+
- Cleaner stack traces for debugging
|
|
150
|
+
- For bulk operations, overhead reduction multiplies
|
|
151
|
+
|
|
152
|
+
## Implementation Details
|
|
153
|
+
|
|
154
|
+
### Type Safety in Core API
|
|
155
|
+
|
|
156
|
+
The Core API implementation uses a controlled type assertion at the boundary:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// Type assertion to PgTable is safe: EntitySchema extends TTableSchemaWithId which extends PgTable
|
|
160
|
+
const table = schema as unknown as PgTable;
|
|
161
|
+
let query = this.connector.select().from(table).$dynamic();
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This approach:
|
|
165
|
+
- Maintains type safety within the method
|
|
166
|
+
- Uses `$dynamic()` for query building with proper types
|
|
167
|
+
- Returns correctly typed `Promise<Array<DataObject>>`
|
|
168
|
+
|
|
169
|
+
## Files Changed
|
|
170
|
+
|
|
171
|
+
### Core Package - Repositories
|
|
172
|
+
- `packages/core/src/base/repositories/operators/filter.ts` - WeakMap cache for `getTableColumns()`
|
|
173
|
+
- `packages/core/src/base/repositories/core/readable.ts` - Core API optimization, async/await refactor
|
|
174
|
+
- `packages/core/src/base/repositories/core/persistable.ts` - Async/await refactor
|
|
175
|
+
|
|
176
|
+
### Core Package - Models
|
|
177
|
+
- `packages/core/src/base/models/base.ts` - Static schemaFactory singleton
|
|
178
|
+
|
|
179
|
+
## Benchmarks
|
|
180
|
+
|
|
181
|
+
These optimizations target the following scenarios:
|
|
182
|
+
|
|
183
|
+
| Scenario | Improvement |
|
|
184
|
+
|----------|-------------|
|
|
185
|
+
| Simple `find()` queries | ~15-20% faster (Core API) |
|
|
186
|
+
| Repeated filter builds | Eliminates reflection overhead (WeakMap) |
|
|
187
|
+
| Entity instantiation | Reduced memory per instance (schemaFactory) |
|
|
188
|
+
| All CRUD operations | Reduced GC pressure (async/await) |
|
|
189
|
+
|
|
190
|
+
## No Breaking Changes
|
|
191
|
+
|
|
192
|
+
All changes are internal optimizations. No API changes or migration required.
|