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.
Files changed (82) hide show
  1. package/.github/workflows/deploy-docs.yml +57 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +2 -28
  4. package/TODO.md +8 -1
  5. package/bun.lock +3 -0
  6. package/config/upload.config.ts +135 -0
  7. package/core/App.ts +168 -4
  8. package/core/ArcheType.ts +122 -0
  9. package/core/BatchLoader.ts +100 -0
  10. package/core/ComponentRegistry.ts +4 -3
  11. package/core/Components.ts +2 -2
  12. package/core/Decorators.ts +15 -8
  13. package/core/Entity.ts +193 -14
  14. package/core/EntityCache.ts +15 -0
  15. package/core/EntityHookManager.ts +855 -0
  16. package/core/EntityManager.ts +12 -2
  17. package/core/ErrorHandler.ts +64 -7
  18. package/core/FileValidator.ts +284 -0
  19. package/core/Query.ts +503 -85
  20. package/core/RequestContext.ts +24 -0
  21. package/core/RequestLoaders.ts +89 -0
  22. package/core/SchedulerManager.ts +710 -0
  23. package/core/UploadManager.ts +261 -0
  24. package/core/components/UploadComponent.ts +206 -0
  25. package/core/decorators/EntityHooks.ts +190 -0
  26. package/core/decorators/ScheduledTask.ts +83 -0
  27. package/core/events/EntityLifecycleEvents.ts +177 -0
  28. package/core/processors/ImageProcessor.ts +423 -0
  29. package/core/storage/LocalStorageProvider.ts +290 -0
  30. package/core/storage/StorageProvider.ts +112 -0
  31. package/database/DatabaseHelper.ts +183 -58
  32. package/database/index.ts +5 -5
  33. package/database/sqlHelpers.ts +7 -0
  34. package/docs/README.md +149 -0
  35. package/docs/_coverpage.md +36 -0
  36. package/docs/_sidebar.md +23 -0
  37. package/docs/api/core.md +568 -0
  38. package/docs/api/hooks.md +554 -0
  39. package/docs/api/index.md +222 -0
  40. package/docs/api/query.md +678 -0
  41. package/docs/api/service.md +744 -0
  42. package/docs/core-concepts/archetypes.md +512 -0
  43. package/docs/core-concepts/components.md +498 -0
  44. package/docs/core-concepts/entity.md +314 -0
  45. package/docs/core-concepts/hooks.md +683 -0
  46. package/docs/core-concepts/query.md +588 -0
  47. package/docs/core-concepts/services.md +647 -0
  48. package/docs/examples/code-examples.md +425 -0
  49. package/docs/getting-started.md +337 -0
  50. package/docs/index.html +97 -0
  51. package/gql/Generator.ts +58 -35
  52. package/gql/decorators/Upload.ts +176 -0
  53. package/gql/helpers.ts +67 -0
  54. package/gql/index.ts +65 -31
  55. package/gql/types.ts +1 -1
  56. package/index.ts +79 -11
  57. package/package.json +19 -10
  58. package/rest/Generator.ts +3 -0
  59. package/rest/index.ts +22 -0
  60. package/service/Service.ts +1 -1
  61. package/service/ServiceRegistry.ts +10 -6
  62. package/service/index.ts +12 -1
  63. package/tests/bench/insert.bench.ts +59 -0
  64. package/tests/bench/relations.bench.ts +269 -0
  65. package/tests/bench/sorting.bench.ts +415 -0
  66. package/tests/component-hooks.test.ts +1409 -0
  67. package/tests/component.test.ts +338 -0
  68. package/tests/errorHandling.test.ts +155 -0
  69. package/tests/hooks.test.ts +666 -0
  70. package/tests/query-sorting.test.ts +101 -0
  71. package/tests/relations.test.ts +169 -0
  72. package/tests/scheduler.test.ts +724 -0
  73. package/tsconfig.json +35 -34
  74. package/types/graphql.types.ts +87 -0
  75. package/types/hooks.types.ts +141 -0
  76. package/types/scheduler.types.ts +165 -0
  77. package/types/upload.types.ts +184 -0
  78. package/upload/index.ts +140 -0
  79. package/utils/UploadHelper.ts +305 -0
  80. package/utils/cronParser.ts +366 -0
  81. package/utils/errorMessages.ts +151 -0
  82. package/core/Events.ts +0 -0
@@ -0,0 +1,314 @@
1
+ # Entity System
2
+
3
+ The Entity system is the foundation of BunSane's architecture. Unlike traditional objects or database rows, Entities in BunSane are dynamic containers composed of multiple Components, providing unparalleled flexibility in data modeling.
4
+
5
+ ## 🎯 What is an Entity?
6
+
7
+ An Entity represents a single "thing" in your application - a user, a product, a blog post, etc. However, unlike traditional models, Entities don't have a fixed structure. Instead, they're composed of Components that define their properties and behavior.
8
+
9
+ ### Key Characteristics
10
+
11
+ - **Dynamic Composition**: Entities can have any combination of components
12
+ - **Type-Safe**: Full TypeScript support with compile-time guarantees
13
+ - **Database-Backed**: Automatically persisted to PostgreSQL
14
+ - **Event-Driven**: Supports lifecycle hooks for business logic
15
+ - **Relationship-Aware**: Can reference other entities through components
16
+
17
+ ## 🏗️ Creating Entities
18
+
19
+ ### Basic Entity Creation
20
+
21
+ ```typescript
22
+ import { Entity } from 'bunsane';
23
+
24
+ // Create a new empty entity
25
+ const user = Entity.Create();
26
+
27
+ // The entity gets a unique ID automatically
28
+ console.log(user.id); // "01HXXXXXXXXXXXXXXXXXXXXX"
29
+ ```
30
+
31
+ ### Adding Components to Entities
32
+
33
+ ```typescript
34
+ import { Entity, Component, CompData, BaseComponent } from 'bunsane';
35
+
36
+ @Component
37
+ class UserProfile extends BaseComponent {
38
+ @CompData()
39
+ name: string = '';
40
+
41
+ @CompData()
42
+ email: string = '';
43
+ }
44
+
45
+ @Component
46
+ class UserPreferences extends BaseComponent {
47
+ @CompData()
48
+ theme: 'light' | 'dark' = 'light';
49
+
50
+ @CompData()
51
+ notifications: boolean = true;
52
+ }
53
+
54
+ // Create entity and add components
55
+ const user = Entity.Create();
56
+ user.add(UserProfile, {
57
+ name: 'John Doe',
58
+ email: 'john@example.com'
59
+ });
60
+
61
+ user.add(UserPreferences, {
62
+ theme: 'dark',
63
+ notifications: false
64
+ });
65
+ ```
66
+
67
+ ## 💾 Persisting Entities
68
+
69
+ ### Saving to Database
70
+
71
+ ```typescript
72
+ // Save the entity to database
73
+ await user.save();
74
+
75
+ // The entity is now persisted
76
+ console.log(user._persisted); // true
77
+ ```
78
+
79
+ ### Loading from Database
80
+
81
+ ```typescript
82
+ // Load entity by ID
83
+ const loadedUser = await Entity.FindById(user.id);
84
+
85
+ // Load multiple entities
86
+ const userIds = ['01HXXX...', '01HYYY...'];
87
+ const users = await Entity.LoadMultiple(userIds);
88
+ ```
89
+
90
+ ## 🔍 Accessing Component Data
91
+
92
+ ### Getting Component Data
93
+
94
+ ```typescript
95
+ // Get component data
96
+ const profile = user.get(UserProfile);
97
+ console.log(profile.data()); // { name: 'John Doe', email: 'john@example.com' }
98
+
99
+ // Direct property access
100
+ const userName = profile.name; // 'John Doe'
101
+ const userEmail = profile.email; // 'john@example.com'
102
+ ```
103
+
104
+ ### Checking Component Existence
105
+
106
+ ```typescript
107
+ // Check if entity has a component
108
+ if (user.has(UserProfile)) {
109
+ const profile = user.get(UserProfile);
110
+ console.log('User has profile:', profile.name);
111
+ }
112
+
113
+ // Get all components
114
+ const allComponents = user.componentList();
115
+ console.log('Entity has', allComponents.length, 'components');
116
+ ```
117
+
118
+ ## 🔄 Updating Entities
119
+
120
+ ### Updating Component Data
121
+
122
+ ```typescript
123
+ // Update existing component
124
+ user.set(UserProfile, {
125
+ name: 'Jane Doe',
126
+ email: 'jane@example.com'
127
+ });
128
+
129
+ // Add new component
130
+ @Component
131
+ class UserStats extends BaseComponent {
132
+ @CompData()
133
+ loginCount: number = 0;
134
+
135
+ @CompData()
136
+ lastLogin: Date = new Date();
137
+ }
138
+
139
+ user.add(UserStats, {
140
+ loginCount: 1,
141
+ lastLogin: new Date()
142
+ });
143
+
144
+ // Save changes
145
+ await user.save();
146
+ ```
147
+
148
+ ### Bulk Updates
149
+
150
+ ```typescript
151
+ // Update multiple components at once
152
+ await user.set(UserProfile, { name: 'Updated Name' });
153
+ await user.set(UserStats, { loginCount: 2 });
154
+
155
+ // Save all changes
156
+ await user.save();
157
+ ```
158
+
159
+ ## 🗑️ Deleting Entities
160
+
161
+ ### Soft Delete
162
+
163
+ ```typescript
164
+ // Mark entity as deleted (soft delete)
165
+ await user.delete();
166
+
167
+ // Entity is marked as deleted but still exists
168
+ console.log(user._persisted); // false
169
+ ```
170
+
171
+ ### Force Delete
172
+
173
+ ```typescript
174
+ // Permanently delete entity and all its components
175
+ await user.delete(true);
176
+ ```
177
+
178
+ ## 🔗 Entity Relationships
179
+
180
+ ### Referencing Other Entities
181
+
182
+ ```typescript
183
+ @Component
184
+ class BlogPost extends BaseComponent {
185
+ @CompData()
186
+ title: string = '';
187
+
188
+ @CompData()
189
+ content: string = '';
190
+
191
+ @CompData()
192
+ authorId: string = ''; // Reference to User entity
193
+ }
194
+
195
+ @Component
196
+ class Comment extends BaseComponent {
197
+ @CompData()
198
+ content: string = '';
199
+
200
+ @CompData()
201
+ postId: string = ''; // Reference to BlogPost entity
202
+
203
+ @CompData()
204
+ authorId: string = ''; // Reference to User entity
205
+ }
206
+
207
+ // Create related entities
208
+ const author = Entity.Create();
209
+ author.add(UserProfile, { name: 'Author Name', email: 'author@example.com' });
210
+ await author.save();
211
+
212
+ const post = Entity.Create();
213
+ post.add(BlogPost, {
214
+ title: 'My First Post',
215
+ content: 'Post content...',
216
+ authorId: author.id
217
+ });
218
+ await post.save();
219
+
220
+ const comment = Entity.Create();
221
+ comment.add(Comment, {
222
+ content: 'Great post!',
223
+ postId: post.id,
224
+ authorId: author.id
225
+ });
226
+ await comment.save();
227
+ ```
228
+
229
+ ## 📊 Advanced Entity Operations
230
+
231
+ ### Entity Metadata
232
+
233
+ ```typescript
234
+ // Check if entity is dirty (has unsaved changes)
235
+ console.log(user._dirty); // true/false
236
+
237
+ // Get entity creation timestamp (if available)
238
+ console.log(user.createdAt);
239
+
240
+ // Get list of dirty components
241
+ const dirtyComponents = user.getDirtyComponents();
242
+ console.log('Dirty components:', dirtyComponents);
243
+ ```
244
+
245
+ ### Batch Operations
246
+
247
+ ```typescript
248
+ // Create multiple entities efficiently
249
+ const entities = [];
250
+ for (let i = 0; i < 100; i++) {
251
+ const entity = Entity.Create();
252
+ entity.add(UserProfile, {
253
+ name: `User ${i}`,
254
+ email: `user${i}@example.com`
255
+ });
256
+ entities.push(entity);
257
+ }
258
+
259
+ // Save all at once (more efficient)
260
+ await Promise.all(entities.map(entity => entity.save()));
261
+ ```
262
+
263
+ ## 🎣 Entity Lifecycle
264
+
265
+ Entities go through several lifecycle stages:
266
+
267
+ 1. **Created**: Entity instantiated with `Entity.Create()`
268
+ 2. **Composed**: Components added to entity
269
+ 3. **Persisted**: Entity saved to database
270
+ 4. **Loaded**: Entity retrieved from database
271
+ 5. **Updated**: Entity modified and re-saved
272
+ 6. **Deleted**: Entity marked as deleted or force-deleted
273
+
274
+ ## 🔧 Best Practices
275
+
276
+ ### Entity Design
277
+
278
+ - **Keep Entities Focused**: Each entity should represent one logical concept
279
+ - **Use Components Wisely**: Break down data into logical, reusable components
280
+ - **Plan Relationships**: Design entity references carefully to avoid circular dependencies
281
+ - **Index Strategically**: Use `@CompData({ indexed: true })` for frequently queried fields
282
+
283
+ ### Performance Considerations
284
+
285
+ - **Batch Operations**: Use `Entity.LoadMultiple()` for loading multiple entities
286
+ - **Lazy Loading**: Only load components when needed
287
+ - **Efficient Queries**: Use the Query system for complex data retrieval
288
+ - **Monitor Entity Size**: Large entities with many components can impact performance
289
+
290
+ ### Error Handling
291
+
292
+ ```typescript
293
+ try {
294
+ const entity = Entity.Create();
295
+ entity.add(UserProfile, userData);
296
+ await entity.save();
297
+ } catch (error) {
298
+ console.error('Failed to create user:', error);
299
+ // Handle error appropriately
300
+ }
301
+ ```
302
+
303
+ ## 🚀 What's Next?
304
+
305
+ Now that you understand Entities, let's explore:
306
+
307
+ - **[Components](components.md)** - The building blocks of entities
308
+ - **[ArcheTypes](archetypes.md)** - Reusable entity templates
309
+ - **[Query System](query.md)** - Efficient data retrieval
310
+ - **[Services](services.md)** - Business logic and GraphQL integration
311
+
312
+ ---
313
+
314
+ *Ready to dive deeper? Let's look at [Components](components.md) next!* 🚀