bunsane 0.1.0 → 0.1.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.
- package/.github/workflows/deploy-docs.yml +57 -0
- package/LICENSE.md +1 -1
- package/README.md +2 -28
- package/TODO.md +8 -1
- package/bun.lock +3 -0
- package/config/upload.config.ts +135 -0
- package/core/App.ts +168 -4
- package/core/ArcheType.ts +122 -0
- package/core/BatchLoader.ts +100 -0
- package/core/ComponentRegistry.ts +4 -3
- package/core/Components.ts +2 -2
- package/core/Decorators.ts +15 -8
- package/core/Entity.ts +193 -14
- package/core/EntityCache.ts +15 -0
- package/core/EntityHookManager.ts +855 -0
- package/core/EntityManager.ts +12 -2
- package/core/ErrorHandler.ts +64 -7
- package/core/FileValidator.ts +284 -0
- package/core/Query.ts +503 -85
- package/core/RequestContext.ts +24 -0
- package/core/RequestLoaders.ts +89 -0
- package/core/SchedulerManager.ts +710 -0
- package/core/UploadManager.ts +261 -0
- package/core/components/UploadComponent.ts +206 -0
- package/core/decorators/EntityHooks.ts +190 -0
- package/core/decorators/ScheduledTask.ts +83 -0
- package/core/events/EntityLifecycleEvents.ts +177 -0
- package/core/processors/ImageProcessor.ts +423 -0
- package/core/storage/LocalStorageProvider.ts +290 -0
- package/core/storage/StorageProvider.ts +112 -0
- package/database/DatabaseHelper.ts +183 -58
- package/database/index.ts +5 -5
- package/database/sqlHelpers.ts +7 -0
- package/docs/README.md +149 -0
- package/docs/_coverpage.md +36 -0
- package/docs/_sidebar.md +23 -0
- package/docs/api/core.md +568 -0
- package/docs/api/hooks.md +554 -0
- package/docs/api/index.md +222 -0
- package/docs/api/query.md +678 -0
- package/docs/api/service.md +744 -0
- package/docs/core-concepts/archetypes.md +512 -0
- package/docs/core-concepts/components.md +498 -0
- package/docs/core-concepts/entity.md +314 -0
- package/docs/core-concepts/hooks.md +683 -0
- package/docs/core-concepts/query.md +588 -0
- package/docs/core-concepts/services.md +647 -0
- package/docs/examples/code-examples.md +425 -0
- package/docs/getting-started.md +337 -0
- package/docs/index.html +97 -0
- package/gql/Generator.ts +58 -35
- package/gql/decorators/Upload.ts +176 -0
- package/gql/helpers.ts +67 -0
- package/gql/index.ts +65 -31
- package/gql/types.ts +1 -1
- package/index.ts +79 -11
- package/package.json +19 -10
- package/rest/Generator.ts +3 -0
- package/rest/index.ts +22 -0
- package/service/Service.ts +1 -1
- package/service/ServiceRegistry.ts +10 -6
- package/service/index.ts +12 -1
- package/tests/bench/insert.bench.ts +59 -0
- package/tests/bench/relations.bench.ts +269 -0
- package/tests/bench/sorting.bench.ts +415 -0
- package/tests/component-hooks.test.ts +1409 -0
- package/tests/component.test.ts +338 -0
- package/tests/errorHandling.test.ts +155 -0
- package/tests/hooks.test.ts +666 -0
- package/tests/query-sorting.test.ts +101 -0
- package/tests/relations.test.ts +169 -0
- package/tests/scheduler.test.ts +724 -0
- package/tsconfig.json +35 -34
- package/types/graphql.types.ts +87 -0
- package/types/hooks.types.ts +141 -0
- package/types/scheduler.types.ts +165 -0
- package/types/upload.types.ts +184 -0
- package/upload/index.ts +140 -0
- package/utils/UploadHelper.ts +305 -0
- package/utils/cronParser.ts +366 -0
- package/utils/errorMessages.ts +151 -0
- package/core/Events.ts +0 -0
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
# ArcheType System
|
|
2
|
+
|
|
3
|
+
ArcheTypes are BunSane's powerful abstraction layer that provides reusable templates for creating entities with predefined sets of components. They eliminate code duplication and ensure consistency across your application by defining entity "blueprints".
|
|
4
|
+
|
|
5
|
+
## 🎯 What is an ArcheType?
|
|
6
|
+
|
|
7
|
+
An ArcheType is a template that defines a specific combination of components that should be present on an entity. Think of it as a "class" in traditional OOP, but with the flexibility of composition.
|
|
8
|
+
|
|
9
|
+
### Key Benefits
|
|
10
|
+
|
|
11
|
+
- **Consistency**: Ensures entities have the correct component combinations
|
|
12
|
+
- **Reusability**: Define once, use everywhere
|
|
13
|
+
- **Type Safety**: Full TypeScript support with compile-time guarantees
|
|
14
|
+
- **Data Integrity**: Guarantees required components are always present
|
|
15
|
+
- **Code Organization**: Clear separation of entity types and their capabilities
|
|
16
|
+
|
|
17
|
+
## 🏗️ Creating ArcheTypes
|
|
18
|
+
|
|
19
|
+
### Basic ArcheType Definition
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { ArcheType, Component, CompData, BaseComponent } from 'bunsane';
|
|
23
|
+
|
|
24
|
+
@Component
|
|
25
|
+
export class UserProfile extends BaseComponent {
|
|
26
|
+
@CompData()
|
|
27
|
+
name: string = '';
|
|
28
|
+
|
|
29
|
+
@CompData()
|
|
30
|
+
email: string = '';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Component
|
|
34
|
+
export class UserPreferences extends BaseComponent {
|
|
35
|
+
@CompData()
|
|
36
|
+
theme: 'light' | 'dark' = 'light';
|
|
37
|
+
|
|
38
|
+
@CompData()
|
|
39
|
+
notifications: boolean = true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@Component
|
|
43
|
+
export class UserStats extends BaseComponent {
|
|
44
|
+
@CompData()
|
|
45
|
+
loginCount: number = 0;
|
|
46
|
+
|
|
47
|
+
@CompData()
|
|
48
|
+
lastLogin: Date = new Date();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Create ArcheType
|
|
52
|
+
export const UserArcheType = new ArcheType([
|
|
53
|
+
UserProfile,
|
|
54
|
+
UserPreferences,
|
|
55
|
+
UserStats
|
|
56
|
+
]);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Complex ArcheType with Relationships
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
@Component
|
|
63
|
+
export class BlogPost extends BaseComponent {
|
|
64
|
+
@CompData()
|
|
65
|
+
title: string = '';
|
|
66
|
+
|
|
67
|
+
@CompData()
|
|
68
|
+
content: string = '';
|
|
69
|
+
|
|
70
|
+
@CompData({ indexed: true })
|
|
71
|
+
authorId: string = '';
|
|
72
|
+
|
|
73
|
+
@CompData()
|
|
74
|
+
tags: string[] = [];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Component
|
|
78
|
+
export class PostMetadata extends BaseComponent {
|
|
79
|
+
@CompData()
|
|
80
|
+
publishedAt: Date = new Date();
|
|
81
|
+
|
|
82
|
+
@CompData()
|
|
83
|
+
readingTime: number = 0; // in minutes
|
|
84
|
+
|
|
85
|
+
@CompData()
|
|
86
|
+
wordCount: number = 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@Component
|
|
90
|
+
export class PostStats extends BaseComponent {
|
|
91
|
+
@CompData()
|
|
92
|
+
viewCount: number = 0;
|
|
93
|
+
|
|
94
|
+
@CompData()
|
|
95
|
+
likeCount: number = 0;
|
|
96
|
+
|
|
97
|
+
@CompData()
|
|
98
|
+
commentCount: number = 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const BlogPostArcheType = new ArcheType([
|
|
102
|
+
BlogPost,
|
|
103
|
+
PostMetadata,
|
|
104
|
+
PostStats
|
|
105
|
+
]);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 🎨 Using ArcheTypes
|
|
109
|
+
|
|
110
|
+
### Creating Entities from ArcheTypes
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// Create entity with all archetype components
|
|
114
|
+
const userEntity = UserArcheType.createEntity();
|
|
115
|
+
|
|
116
|
+
// The entity now has UserProfile, UserPreferences, and UserStats components
|
|
117
|
+
console.log(userEntity.has(UserProfile)); // true
|
|
118
|
+
console.log(userEntity.has(UserPreferences)); // true
|
|
119
|
+
console.log(userEntity.has(UserStats)); // true
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Filling ArcheTypes with Data
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Fill archetype with data before creating entity
|
|
126
|
+
const userData = {
|
|
127
|
+
userProfile: {
|
|
128
|
+
name: 'John Doe',
|
|
129
|
+
email: 'john@example.com'
|
|
130
|
+
},
|
|
131
|
+
userPreferences: {
|
|
132
|
+
theme: 'dark',
|
|
133
|
+
notifications: false
|
|
134
|
+
},
|
|
135
|
+
userStats: {
|
|
136
|
+
loginCount: 1,
|
|
137
|
+
lastLogin: new Date()
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const userEntity = UserArcheType.fill(userData).createEntity();
|
|
142
|
+
await userEntity.save();
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Creating and Saving in One Step
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
// Create and save entity in one operation
|
|
149
|
+
const userEntity = await UserArcheType.fill(userData).createAndSaveEntity();
|
|
150
|
+
|
|
151
|
+
// Entity is now saved to database
|
|
152
|
+
console.log(userEntity._persisted); // true
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 🔄 ArcheType Operations
|
|
156
|
+
|
|
157
|
+
### Updating Entities
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
// Update existing entity using archetype
|
|
161
|
+
const existingUser = await Entity.FindById(userId);
|
|
162
|
+
|
|
163
|
+
const updates = {
|
|
164
|
+
userProfile: {
|
|
165
|
+
name: 'Jane Doe'
|
|
166
|
+
},
|
|
167
|
+
userPreferences: {
|
|
168
|
+
theme: 'light'
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
await UserArcheType.updateEntity(existingUser, updates);
|
|
173
|
+
await existingUser.save();
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Unwrapping Entities
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// Convert entity back to plain object
|
|
180
|
+
const userEntity = await Entity.FindById(userId);
|
|
181
|
+
const userData = await UserArcheType.Unwrap(userEntity);
|
|
182
|
+
|
|
183
|
+
console.log(userData);
|
|
184
|
+
// {
|
|
185
|
+
// userProfile: { name: 'John Doe', email: 'john@example.com' },
|
|
186
|
+
// userPreferences: { theme: 'dark', notifications: true },
|
|
187
|
+
// userStats: { loginCount: 5, lastLogin: '2025-09-17T...' }
|
|
188
|
+
// }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Unwrapping with Field Exclusion
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Exclude sensitive data when unwrapping
|
|
195
|
+
const publicUserData = await UserArcheType.Unwrap(userEntity, ['email', 'loginCount']);
|
|
196
|
+
|
|
197
|
+
console.log(publicUserData);
|
|
198
|
+
// {
|
|
199
|
+
// userProfile: { name: 'John Doe' }, // email excluded
|
|
200
|
+
// userPreferences: { theme: 'dark', notifications: true },
|
|
201
|
+
// userStats: { lastLogin: '2025-09-17T...' } // loginCount excluded
|
|
202
|
+
// }
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## 🏷️ ArcheType Inheritance and Composition
|
|
206
|
+
|
|
207
|
+
### Base ArcheTypes
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Base archetype for all content
|
|
211
|
+
export const ContentArcheType = new ArcheType([
|
|
212
|
+
BaseContent,
|
|
213
|
+
ContentMetadata
|
|
214
|
+
]);
|
|
215
|
+
|
|
216
|
+
// Extended archetypes
|
|
217
|
+
export const BlogPostArcheType = new ArcheType([
|
|
218
|
+
...ContentArcheType.getComponents(),
|
|
219
|
+
BlogPost,
|
|
220
|
+
PostStats
|
|
221
|
+
]);
|
|
222
|
+
|
|
223
|
+
export const PageArcheType = new ArcheType([
|
|
224
|
+
...ContentArcheType.getComponents(),
|
|
225
|
+
PageContent,
|
|
226
|
+
PageSettings
|
|
227
|
+
]);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Specialized ArcheTypes
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// Admin user archetype (extends regular user)
|
|
234
|
+
export const AdminUserArcheType = new ArcheType([
|
|
235
|
+
...UserArcheType.getComponents(),
|
|
236
|
+
AdminPermissions,
|
|
237
|
+
AdminStats
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
// Premium user archetype
|
|
241
|
+
export const PremiumUserArcheType = new ArcheType([
|
|
242
|
+
...UserArcheType.getComponents(),
|
|
243
|
+
PremiumFeatures,
|
|
244
|
+
BillingInfo
|
|
245
|
+
]);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## 🔍 ArcheType Queries
|
|
249
|
+
|
|
250
|
+
### Querying by ArcheType
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
import { Query } from 'bunsane';
|
|
254
|
+
|
|
255
|
+
// Find all users
|
|
256
|
+
const userQuery = new Query()
|
|
257
|
+
.with(UserProfile) // Must have UserProfile component
|
|
258
|
+
.with(UserPreferences); // Must have UserPreferences component
|
|
259
|
+
|
|
260
|
+
const users = await userQuery.exec();
|
|
261
|
+
|
|
262
|
+
// Find premium users
|
|
263
|
+
const premiumQuery = new Query()
|
|
264
|
+
.with(UserProfile)
|
|
265
|
+
.with(PremiumFeatures);
|
|
266
|
+
|
|
267
|
+
const premiumUsers = await premiumQuery.exec();
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### ArcheType-Specific Queries
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Query with archetype filtering
|
|
274
|
+
const adminUsers = await new Query()
|
|
275
|
+
.with(UserProfile)
|
|
276
|
+
.with(AdminPermissions)
|
|
277
|
+
.exec();
|
|
278
|
+
|
|
279
|
+
// Get user count
|
|
280
|
+
const userCount = await new Query()
|
|
281
|
+
.with(UserProfile)
|
|
282
|
+
.count();
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## 🎭 Advanced ArcheType Patterns
|
|
286
|
+
|
|
287
|
+
### Dynamic ArcheTypes
|
|
288
|
+
|
|
289
|
+
```typescript
|
|
290
|
+
class DynamicArcheType extends ArcheType {
|
|
291
|
+
constructor(userType: 'basic' | 'premium' | 'admin') {
|
|
292
|
+
const baseComponents = [UserProfile, UserPreferences];
|
|
293
|
+
|
|
294
|
+
const additionalComponents = {
|
|
295
|
+
basic: [],
|
|
296
|
+
premium: [PremiumFeatures, BillingInfo],
|
|
297
|
+
admin: [AdminPermissions, AdminStats, AuditLog]
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
super([...baseComponents, ...additionalComponents[userType]]);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Usage
|
|
305
|
+
const basicUserArchetype = new DynamicArcheType('basic');
|
|
306
|
+
const premiumUserArchetype = new DynamicArcheType('premium');
|
|
307
|
+
const adminUserArchetype = new DynamicArcheType('admin');
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Conditional Components
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
class ConditionalArcheType extends ArcheType {
|
|
314
|
+
constructor(includeStats: boolean = false, includeAudit: boolean = false) {
|
|
315
|
+
const components = [UserProfile, UserPreferences];
|
|
316
|
+
|
|
317
|
+
if (includeStats) {
|
|
318
|
+
components.push(UserStats);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (includeAudit) {
|
|
322
|
+
components.push(AuditLog);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
super(components);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Usage
|
|
330
|
+
const minimalUserArchetype = new ConditionalArcheType();
|
|
331
|
+
const fullUserArchetype = new ConditionalArcheType(true, true);
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### ArcheType Factories
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
class ArcheTypeFactory {
|
|
338
|
+
static createUserArchetype(userType: string): ArcheType {
|
|
339
|
+
switch (userType) {
|
|
340
|
+
case 'admin':
|
|
341
|
+
return new ArcheType([
|
|
342
|
+
UserProfile,
|
|
343
|
+
UserPreferences,
|
|
344
|
+
AdminPermissions,
|
|
345
|
+
AdminStats
|
|
346
|
+
]);
|
|
347
|
+
|
|
348
|
+
case 'premium':
|
|
349
|
+
return new ArcheType([
|
|
350
|
+
UserProfile,
|
|
351
|
+
UserPreferences,
|
|
352
|
+
PremiumFeatures,
|
|
353
|
+
BillingInfo
|
|
354
|
+
]);
|
|
355
|
+
|
|
356
|
+
default:
|
|
357
|
+
return new ArcheType([
|
|
358
|
+
UserProfile,
|
|
359
|
+
UserPreferences
|
|
360
|
+
]);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
static createContentArchetype(contentType: string): ArcheType {
|
|
365
|
+
const baseComponents = [BaseContent, ContentMetadata];
|
|
366
|
+
|
|
367
|
+
switch (contentType) {
|
|
368
|
+
case 'blog':
|
|
369
|
+
return new ArcheType([...baseComponents, BlogPost, PostStats]);
|
|
370
|
+
|
|
371
|
+
case 'page':
|
|
372
|
+
return new ArcheType([...baseComponents, PageContent, PageSettings]);
|
|
373
|
+
|
|
374
|
+
case 'product':
|
|
375
|
+
return new ArcheType([...baseComponents, ProductInfo, Inventory]);
|
|
376
|
+
|
|
377
|
+
default:
|
|
378
|
+
return new ArcheType(baseComponents);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Usage
|
|
384
|
+
const adminArchetype = ArcheTypeFactory.createUserArchetype('admin');
|
|
385
|
+
const blogArchetype = ArcheTypeFactory.createContentArchetype('blog');
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## 🔧 ArcheType Management
|
|
389
|
+
|
|
390
|
+
### ArcheType Registry
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// Register archetypes for easy access
|
|
394
|
+
class ArcheTypeRegistry {
|
|
395
|
+
private static archetypes: Map<string, ArcheType> = new Map();
|
|
396
|
+
|
|
397
|
+
static register(name: string, archetype: ArcheType) {
|
|
398
|
+
this.archetypes.set(name, archetype);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
static get(name: string): ArcheType | undefined {
|
|
402
|
+
return this.archetypes.get(name);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
static getAll(): Map<string, ArcheType> {
|
|
406
|
+
return this.archetypes;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Register common archetypes
|
|
411
|
+
ArcheTypeRegistry.register('user', UserArcheType);
|
|
412
|
+
ArcheTypeRegistry.register('admin', AdminUserArcheType);
|
|
413
|
+
ArcheTypeRegistry.register('blog-post', BlogPostArcheType);
|
|
414
|
+
|
|
415
|
+
// Usage
|
|
416
|
+
const userArchetype = ArcheTypeRegistry.get('user');
|
|
417
|
+
const adminArchetype = ArcheTypeRegistry.get('admin');
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### ArcheType Validation
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
class ValidatedArcheType extends ArcheType {
|
|
424
|
+
constructor(components: any[], requiredComponents: any[] = []) {
|
|
425
|
+
super(components);
|
|
426
|
+
this.requiredComponents = requiredComponents;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
validateEntity(entity: Entity): boolean {
|
|
430
|
+
// Check if entity has all required components
|
|
431
|
+
return this.requiredComponents.every(component =>
|
|
432
|
+
entity.has(component)
|
|
433
|
+
);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
createValidatedEntity(data?: any): Entity {
|
|
437
|
+
const entity = this.fill(data || {}).createEntity();
|
|
438
|
+
|
|
439
|
+
if (!this.validateEntity(entity)) {
|
|
440
|
+
throw new Error('Entity does not meet archetype requirements');
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
return entity;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Usage
|
|
448
|
+
const validatedUserArchetype = new ValidatedArcheType(
|
|
449
|
+
[UserProfile, UserPreferences, UserStats],
|
|
450
|
+
[UserProfile] // UserProfile is required
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
try {
|
|
454
|
+
const user = validatedUserArchetype.createValidatedEntity(userData);
|
|
455
|
+
} catch (error) {
|
|
456
|
+
console.error('Validation failed:', error);
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
## 📊 Best Practices
|
|
461
|
+
|
|
462
|
+
### ArcheType Design
|
|
463
|
+
|
|
464
|
+
- **Clear Purpose**: Each archetype should have a single, clear responsibility
|
|
465
|
+
- **Minimal Components**: Include only essential components to avoid bloat
|
|
466
|
+
- **Consistent Naming**: Use descriptive names that indicate the archetype's purpose
|
|
467
|
+
- **Versioning**: Consider versioning for archetypes that evolve over time
|
|
468
|
+
- **Documentation**: Document the purpose and usage of each archetype
|
|
469
|
+
|
|
470
|
+
### Performance Considerations
|
|
471
|
+
|
|
472
|
+
- **Component Loading**: Be mindful of the number of components in an archetype
|
|
473
|
+
- **Query Optimization**: Design archetypes to support efficient queries
|
|
474
|
+
- **Memory Usage**: Consider the memory impact of large archetypes
|
|
475
|
+
- **Caching**: Cache frequently used archetypes to improve performance
|
|
476
|
+
|
|
477
|
+
### Error Handling
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
try {
|
|
481
|
+
// Validate data before creating entity
|
|
482
|
+
if (!userData.email || !userData.name) {
|
|
483
|
+
throw new Error('Missing required user data');
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const userEntity = await UserArcheType.fill(userData).createAndSaveEntity();
|
|
487
|
+
console.log('User created successfully:', userEntity.id);
|
|
488
|
+
|
|
489
|
+
} catch (error) {
|
|
490
|
+
console.error('Failed to create user:', error);
|
|
491
|
+
|
|
492
|
+
// Log error details for debugging
|
|
493
|
+
logger.error('User creation failed', {
|
|
494
|
+
error: error.message,
|
|
495
|
+
userData: userData,
|
|
496
|
+
archetype: 'UserArcheType'
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
## 🚀 What's Next?
|
|
502
|
+
|
|
503
|
+
Now that you understand ArcheTypes, let's explore:
|
|
504
|
+
|
|
505
|
+
- **[Services](services.md)** - Business logic and GraphQL integration
|
|
506
|
+
- **[Query System](query.md)** - Efficient data retrieval
|
|
507
|
+
- **[Entity System](entity.md)** - How entities work with archetypes
|
|
508
|
+
- **[Lifecycle Hooks](hooks.md)** - Business logic integration
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
*Ready to build with archetypes? Let's look at [Services](services.md) next!* 🚀
|