bunsane 0.1.4 → 0.2.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/.claude/settings.local.json +47 -0
- package/.claude/skills/update-memory.md +74 -0
- package/.prettierrc +4 -0
- package/.serena/memories/architectural-decision-no-dependency-injection.md +76 -0
- package/.serena/memories/architecture.md +154 -0
- package/.serena/memories/cache-interface-refactoring-2026-01-24.md +165 -0
- package/.serena/memories/code_style_and_conventions.md +76 -0
- package/.serena/memories/project_overview.md +43 -0
- package/.serena/memories/schema-dsl-plan.md +107 -0
- package/.serena/memories/suggested_commands.md +80 -0
- package/.serena/memories/typescript-compilation-status.md +54 -0
- package/.serena/project.yml +114 -0
- package/TODO.md +1 -7
- package/bun.lock +150 -4
- package/bunfig.toml +10 -0
- package/config/cache.config.ts +77 -0
- package/config/upload.config.ts +4 -5
- package/core/App.ts +870 -123
- package/core/ArcheType.ts +2268 -377
- package/core/BatchLoader.ts +181 -71
- package/core/Config.ts +153 -0
- package/core/Decorators.ts +4 -1
- package/core/Entity.ts +621 -92
- package/core/EntityHookManager.ts +1 -1
- package/core/EntityInterface.ts +3 -1
- package/core/EntityManager.ts +1 -13
- package/core/ErrorHandler.ts +8 -2
- package/core/Logger.ts +9 -0
- package/core/Middleware.ts +34 -0
- package/core/RequestContext.ts +5 -1
- package/core/RequestLoaders.ts +227 -93
- package/core/SchedulerManager.ts +193 -52
- package/core/cache/CacheAnalytics.ts +399 -0
- package/core/cache/CacheFactory.ts +145 -0
- package/core/cache/CacheManager.ts +520 -0
- package/core/cache/CacheProvider.ts +34 -0
- package/core/cache/CacheWarmer.ts +157 -0
- package/core/cache/CompressionUtils.ts +110 -0
- package/core/cache/MemoryCache.ts +251 -0
- package/core/cache/MultiLevelCache.ts +180 -0
- package/core/cache/NoOpCache.ts +53 -0
- package/core/cache/RedisCache.ts +464 -0
- package/core/cache/TTLStrategy.ts +254 -0
- package/core/cache/index.ts +6 -0
- package/core/components/BaseComponent.ts +120 -0
- package/core/{ComponentRegistry.ts → components/ComponentRegistry.ts} +148 -54
- package/core/components/Decorators.ts +88 -0
- package/core/components/Interfaces.ts +7 -0
- package/core/components/index.ts +5 -0
- package/core/decorators/EntityHooks.ts +0 -3
- package/core/decorators/IndexedField.ts +26 -0
- package/core/decorators/ScheduledTask.ts +0 -47
- package/core/events/EntityLifecycleEvents.ts +1 -1
- package/core/health.ts +112 -0
- package/core/metadata/definitions/ArcheType.ts +14 -0
- package/core/metadata/definitions/Component.ts +9 -0
- package/core/metadata/definitions/gqlObject.ts +1 -1
- package/core/metadata/index.ts +42 -1
- package/core/metadata/metadata-storage.ts +28 -2
- package/core/middleware/AccessLog.ts +59 -0
- package/core/middleware/RequestId.ts +38 -0
- package/core/middleware/SecurityHeaders.ts +62 -0
- package/core/middleware/index.ts +3 -0
- package/core/scheduler/DistributedLock.ts +266 -0
- package/core/scheduler/index.ts +15 -0
- package/core/validateEnv.ts +92 -0
- package/database/DatabaseHelper.ts +416 -40
- package/database/IndexingStrategy.ts +342 -0
- package/database/PreparedStatementCache.ts +226 -0
- package/database/index.ts +32 -7
- package/database/sqlHelpers.ts +14 -2
- package/endpoints/archetypes.ts +362 -0
- package/endpoints/components.ts +58 -0
- package/endpoints/entity.ts +80 -0
- package/endpoints/index.ts +27 -0
- package/endpoints/query.ts +93 -0
- package/endpoints/stats.ts +76 -0
- package/endpoints/tables.ts +212 -0
- package/endpoints/types.ts +155 -0
- package/gql/ArchetypeOperations.ts +32 -86
- package/gql/Generator.ts +27 -315
- package/gql/GeneratorV2.ts +37 -0
- package/gql/builders/InputTypeBuilder.ts +99 -0
- package/gql/builders/ResolverBuilder.ts +234 -0
- package/gql/builders/TypeDefBuilder.ts +105 -0
- package/gql/builders/index.ts +3 -0
- package/gql/decorators/Upload.ts +1 -1
- package/gql/depthLimit.ts +85 -0
- package/gql/graph/GraphNode.ts +224 -0
- package/gql/graph/SchemaGraph.ts +278 -0
- package/gql/helpers.ts +8 -2
- package/gql/index.ts +56 -4
- package/gql/middleware.ts +79 -0
- package/gql/orchestration/GraphQLSchemaOrchestrator.ts +241 -0
- package/gql/orchestration/index.ts +1 -0
- package/gql/scanner/ServiceScanner.ts +347 -0
- package/gql/schema/index.ts +458 -0
- package/gql/strategies/TypeGenerationStrategy.ts +329 -0
- package/gql/types.ts +1 -0
- package/gql/utils/TypeSignature.ts +220 -0
- package/gql/utils/index.ts +1 -0
- package/gql/visitors/ArchetypePreprocessorVisitor.ts +80 -0
- package/gql/visitors/DeduplicationVisitor.ts +82 -0
- package/gql/visitors/GraphVisitor.ts +78 -0
- package/gql/visitors/ResolverGeneratorVisitor.ts +122 -0
- package/gql/visitors/SchemaGeneratorVisitor.ts +851 -0
- package/gql/visitors/TypeCollectorVisitor.ts +79 -0
- package/gql/visitors/VisitorComposer.ts +96 -0
- package/gql/visitors/index.ts +7 -0
- package/package.json +59 -37
- package/plugins/index.ts +2 -2
- package/query/CTENode.ts +97 -0
- package/query/ComponentInclusionNode.ts +689 -0
- package/query/FilterBuilder.ts +127 -0
- package/query/FilterBuilderRegistry.ts +202 -0
- package/query/OrNode.ts +517 -0
- package/query/OrQuery.ts +42 -0
- package/query/Query.ts +1022 -0
- package/query/QueryContext.ts +170 -0
- package/query/QueryDAG.ts +122 -0
- package/query/QueryNode.ts +65 -0
- package/query/SourceNode.ts +53 -0
- package/query/builders/FullTextSearchBuilder.ts +236 -0
- package/query/index.ts +21 -0
- package/scheduler/index.ts +40 -8
- package/service/Service.ts +2 -1
- package/service/ServiceRegistry.ts +6 -5
- package/{core/storage → storage}/LocalStorageProvider.ts +2 -2
- package/storage/S3StorageProvider.ts +316 -0
- package/{core/storage → storage}/StorageProvider.ts +7 -3
- package/studio/bun.lock +482 -0
- package/studio/index.html +13 -0
- package/studio/package.json +39 -0
- package/studio/postcss.config.js +6 -0
- package/studio/src/components/DataTable.tsx +211 -0
- package/studio/src/components/Layout.tsx +13 -0
- package/studio/src/components/PageContainer.tsx +9 -0
- package/studio/src/components/PageHeader.tsx +13 -0
- package/studio/src/components/SearchBar.tsx +57 -0
- package/studio/src/components/Sidebar.tsx +294 -0
- package/studio/src/components/ui/button.tsx +56 -0
- package/studio/src/components/ui/checkbox.tsx +26 -0
- package/studio/src/components/ui/input.tsx +25 -0
- package/studio/src/hooks/useDataTable.ts +131 -0
- package/studio/src/index.css +36 -0
- package/studio/src/lib/api.ts +186 -0
- package/studio/src/lib/utils.ts +13 -0
- package/studio/src/main.tsx +17 -0
- package/studio/src/pages/ArcheType.tsx +239 -0
- package/studio/src/pages/Components.tsx +124 -0
- package/studio/src/pages/EntityInspector.tsx +302 -0
- package/studio/src/pages/QueryRunner.tsx +246 -0
- package/studio/src/pages/Table.tsx +94 -0
- package/studio/src/pages/Welcome.tsx +241 -0
- package/studio/src/routes.tsx +45 -0
- package/studio/src/store/archeTypeSettings.ts +30 -0
- package/studio/src/store/studio.ts +65 -0
- package/studio/src/utils/columnHelpers.tsx +114 -0
- package/studio/studio-instructions.md +81 -0
- package/studio/tailwind.config.js +77 -0
- package/studio/tsconfig.json +24 -0
- package/studio/utils.ts +54 -0
- package/studio/vite.config.js +19 -0
- package/swagger/generator.ts +1 -1
- package/tests/e2e/http.test.ts +126 -0
- package/tests/fixtures/archetypes/TestUserArchetype.ts +21 -0
- package/tests/fixtures/components/TestOrder.ts +23 -0
- package/tests/fixtures/components/TestProduct.ts +23 -0
- package/tests/fixtures/components/TestUser.ts +20 -0
- package/tests/fixtures/components/index.ts +6 -0
- package/tests/graphql/SchemaGeneration.test.ts +90 -0
- package/tests/graphql/builders/ResolverBuilder.test.ts +223 -0
- package/tests/graphql/builders/TypeDefBuilder.test.ts +153 -0
- package/tests/integration/archetype/ArcheType.persistence.test.ts +241 -0
- package/tests/integration/cache/CacheInvalidation.test.ts +259 -0
- package/tests/integration/entity/Entity.persistence.test.ts +333 -0
- package/tests/integration/query/Query.exec.test.ts +523 -0
- package/tests/pglite-setup.ts +61 -0
- package/tests/setup.ts +164 -0
- package/tests/stress/BenchmarkRunner.ts +203 -0
- package/tests/stress/DataSeeder.ts +190 -0
- package/tests/stress/StressTestReporter.ts +229 -0
- package/tests/stress/cursor-perf-test.ts +171 -0
- package/tests/stress/fixtures/StressTestComponents.ts +58 -0
- package/tests/stress/index.ts +7 -0
- package/tests/stress/scenarios/query-benchmarks.test.ts +285 -0
- package/tests/unit/BatchLoader.test.ts +82 -0
- package/tests/unit/archetype/ArcheType.test.ts +107 -0
- package/tests/unit/cache/CacheManager.test.ts +347 -0
- package/tests/unit/cache/MemoryCache.test.ts +260 -0
- package/tests/unit/cache/RedisCache.test.ts +411 -0
- package/tests/unit/entity/Entity.components.test.ts +244 -0
- package/tests/unit/entity/Entity.test.ts +345 -0
- package/tests/unit/gql/depthLimit.test.ts +203 -0
- package/tests/unit/gql/operationMiddleware.test.ts +293 -0
- package/tests/unit/health/Health.test.ts +129 -0
- package/tests/unit/middleware/AccessLog.test.ts +37 -0
- package/tests/unit/middleware/Middleware.test.ts +98 -0
- package/tests/unit/middleware/RequestId.test.ts +54 -0
- package/tests/unit/middleware/SecurityHeaders.test.ts +66 -0
- package/tests/unit/query/FilterBuilder.test.ts +111 -0
- package/tests/unit/query/Query.test.ts +308 -0
- package/tests/unit/scheduler/DistributedLock.test.ts +274 -0
- package/tests/unit/schema/schema-integration.test.ts +426 -0
- package/tests/unit/schema/schema.test.ts +580 -0
- package/tests/unit/storage/S3StorageProvider.test.ts +571 -0
- package/tests/unit/upload/RestUpload.test.ts +267 -0
- package/tests/unit/validateEnv.test.ts +82 -0
- package/tests/utils/entity-tracker.ts +57 -0
- package/tests/utils/index.ts +13 -0
- package/tests/utils/test-context.ts +149 -0
- package/tsconfig.json +5 -1
- package/types/archetype.types.ts +6 -0
- package/types/hooks.types.ts +1 -1
- package/types/query.types.ts +110 -0
- package/types/scheduler.types.ts +68 -7
- package/types/upload.types.ts +1 -0
- package/{core → upload}/FileValidator.ts +10 -1
- package/upload/RestUpload.ts +130 -0
- package/{core/components → upload}/UploadComponent.ts +11 -11
- package/{core → upload}/UploadManager.ts +3 -3
- package/upload/index.ts +23 -7
- package/utils/UploadHelper.ts +27 -6
- package/utils/cronParser.ts +16 -6
- package/.github/workflows/deploy-docs.yml +0 -57
- package/core/Components.ts +0 -202
- package/core/EntityCache.ts +0 -15
- package/core/Query.ts +0 -880
- package/docs/README.md +0 -149
- package/docs/_coverpage.md +0 -36
- package/docs/_sidebar.md +0 -23
- package/docs/api/core.md +0 -568
- package/docs/api/hooks.md +0 -554
- package/docs/api/index.md +0 -222
- package/docs/api/query.md +0 -678
- package/docs/api/service.md +0 -744
- package/docs/core-concepts/archetypes.md +0 -512
- package/docs/core-concepts/components.md +0 -498
- package/docs/core-concepts/entity.md +0 -314
- package/docs/core-concepts/hooks.md +0 -683
- package/docs/core-concepts/query.md +0 -588
- package/docs/core-concepts/services.md +0 -647
- package/docs/examples/code-examples.md +0 -425
- package/docs/getting-started.md +0 -337
- package/docs/index.html +0 -97
- package/tests/bench/insert.bench.ts +0 -60
- package/tests/bench/relations.bench.ts +0 -270
- package/tests/bench/sorting.bench.ts +0 -416
- package/tests/component-hooks-simple.test.ts +0 -117
- package/tests/component-hooks.test.ts +0 -1461
- package/tests/component.test.ts +0 -339
- package/tests/errorHandling.test.ts +0 -155
- package/tests/hooks.test.ts +0 -667
- package/tests/query-sorting.test.ts +0 -101
- package/tests/query.test.ts +0 -81
- package/tests/relations.test.ts +0 -170
- package/tests/scheduler.test.ts +0 -724
package/docs/getting-started.md
DELETED
|
@@ -1,337 +0,0 @@
|
|
|
1
|
-
# Getting Started with BunSane
|
|
2
|
-
|
|
3
|
-
This guide will walk you through installing and setting up BunSane for your first project.
|
|
4
|
-
|
|
5
|
-
## 📋 Prerequisites
|
|
6
|
-
|
|
7
|
-
Before you begin, ensure you have the following installed:
|
|
8
|
-
|
|
9
|
-
- **Bun Runtime**: Version 1.0 or later ([Download Bun](https://bun.sh/))
|
|
10
|
-
- **PostgreSQL**: Version 12 or later ([Download PostgreSQL](https://www.postgresql.org/download/))
|
|
11
|
-
- **Node.js**: Version 18+ (for some development tools, though Bun is the primary runtime)
|
|
12
|
-
|
|
13
|
-
## 🚀 Installation
|
|
14
|
-
|
|
15
|
-
### 1. Install BunSane
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
bun install bunsane
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. Verify Installation
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
bun run --version
|
|
25
|
-
# Should show Bun version 1.x.x
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## ⚙️ Configuration
|
|
29
|
-
|
|
30
|
-
### TypeScript Configuration
|
|
31
|
-
|
|
32
|
-
BunSane requires experimental decorators to be enabled. Update your `tsconfig.json`:
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"compilerOptions": {
|
|
37
|
-
"target": "ES2022",
|
|
38
|
-
"module": "ESNext",
|
|
39
|
-
"moduleResolution": "bundler",
|
|
40
|
-
"experimentalDecorators": true,
|
|
41
|
-
"emitDecoratorMetadata": true,
|
|
42
|
-
"strict": true,
|
|
43
|
-
"esModuleInterop": true,
|
|
44
|
-
"skipLibCheck": true,
|
|
45
|
-
"forceConsistentCasingInFileNames": true,
|
|
46
|
-
"allowSyntheticDefaultImports": true,
|
|
47
|
-
"resolveJsonModule": true,
|
|
48
|
-
"isolatedModules": true,
|
|
49
|
-
"noEmit": true,
|
|
50
|
-
"types": ["bun-types"]
|
|
51
|
-
},
|
|
52
|
-
"include": ["src/**/*", "index.ts"],
|
|
53
|
-
"exclude": ["node_modules"]
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Database Setup
|
|
58
|
-
|
|
59
|
-
Create a PostgreSQL database for your application:
|
|
60
|
-
|
|
61
|
-
```sql
|
|
62
|
-
-- Create database
|
|
63
|
-
CREATE DATABASE bunsane_app;
|
|
64
|
-
|
|
65
|
-
-- Create user (optional)
|
|
66
|
-
CREATE USER bunsane_user WITH PASSWORD 'your_password';
|
|
67
|
-
|
|
68
|
-
-- Grant permissions
|
|
69
|
-
GRANT ALL PRIVILEGES ON DATABASE bunsane_app TO bunsane_user;
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
### Environment Configuration
|
|
73
|
-
|
|
74
|
-
Create a `.env` file in your project root:
|
|
75
|
-
|
|
76
|
-
```env
|
|
77
|
-
# Database Configuration
|
|
78
|
-
DATABASE_URL=postgresql://username:password@localhost:5432/bunsane_app
|
|
79
|
-
|
|
80
|
-
# Application Configuration
|
|
81
|
-
NODE_ENV=development
|
|
82
|
-
PORT=3000
|
|
83
|
-
|
|
84
|
-
# Optional: Logging
|
|
85
|
-
LOG_LEVEL=info
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## 🏗️ Your First BunSane Application
|
|
89
|
-
|
|
90
|
-
### Project Structure
|
|
91
|
-
|
|
92
|
-
Create the following directory structure:
|
|
93
|
-
|
|
94
|
-
```
|
|
95
|
-
my-bunsane-app/
|
|
96
|
-
├── src/
|
|
97
|
-
│ ├── services/
|
|
98
|
-
│ └── helpers/
|
|
99
|
-
├── index.ts
|
|
100
|
-
├── package.json
|
|
101
|
-
├── tsconfig.json
|
|
102
|
-
└── .env
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### 1. Create Your First Component
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
// src/services/UserService.ts
|
|
109
|
-
import { Component, CompData, BaseComponent, ArcheType, Entity, GraphQLObjectType, GraphQLOperation, GraphQLFieldTypes, GraphQLField } from 'bunsane';
|
|
110
|
-
|
|
111
|
-
@Component
|
|
112
|
-
export class UserProfile extends BaseComponent {
|
|
113
|
-
@CompData()
|
|
114
|
-
name: string = '';
|
|
115
|
-
|
|
116
|
-
@CompData()
|
|
117
|
-
email: string = '';
|
|
118
|
-
|
|
119
|
-
@CompData({ indexed: true })
|
|
120
|
-
username: string = '';
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
@Component
|
|
124
|
-
export class UserPreferences extends BaseComponent {
|
|
125
|
-
@CompData()
|
|
126
|
-
theme: 'light' | 'dark' = 'light';
|
|
127
|
-
|
|
128
|
-
@CompData()
|
|
129
|
-
notifications: boolean = true;
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### 2. Create an ArcheType
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
// src/services/UserService.ts (continued)
|
|
137
|
-
import { ArcheType } from 'bunsane';
|
|
138
|
-
|
|
139
|
-
export const UserArcheType = new ArcheType([
|
|
140
|
-
UserProfile,
|
|
141
|
-
UserPreferences
|
|
142
|
-
]);
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### 3. Create a Service
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// src/services/UserService.ts (continued)
|
|
149
|
-
import { BaseService, GraphQLObjectType, GraphQLOperation, GraphQLFieldTypes, GraphQLField } from 'bunsane';
|
|
150
|
-
|
|
151
|
-
const userFields = {
|
|
152
|
-
id: GraphQLFieldTypes.ID_REQUIRED,
|
|
153
|
-
name: GraphQLFieldTypes.STRING_OPTIONAL,
|
|
154
|
-
email: GraphQLFieldTypes.STRING_REQUIRED,
|
|
155
|
-
username: GraphQLFieldTypes.STRING_OPTIONAL
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
const userInputs = {
|
|
159
|
-
createUser: {
|
|
160
|
-
name: GraphQLFieldTypes.STRING_REQUIRED,
|
|
161
|
-
email: GraphQLFieldTypes.STRING_REQUIRED,
|
|
162
|
-
username: GraphQLFieldTypes.STRING_REQUIRED
|
|
163
|
-
},
|
|
164
|
-
getUser: {
|
|
165
|
-
id: GraphQLFieldTypes.ID_REQUIRED
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
@GraphQLObjectType({
|
|
170
|
-
name: "User",
|
|
171
|
-
fields: userFields
|
|
172
|
-
})
|
|
173
|
-
export default class UserService extends BaseService {
|
|
174
|
-
@GraphQLOperation({
|
|
175
|
-
type: "Mutation",
|
|
176
|
-
input: userInputs.createUser,
|
|
177
|
-
output: "User"
|
|
178
|
-
})
|
|
179
|
-
async createUser(args: { name: string; email: string; username: string }) {
|
|
180
|
-
const userEntity = UserArcheType.fill(args).createEntity();
|
|
181
|
-
await userEntity.save();
|
|
182
|
-
return await UserArcheType.Unwrap(userEntity);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
@GraphQLOperation({
|
|
186
|
-
type: "Query",
|
|
187
|
-
input: userInputs.getUser,
|
|
188
|
-
output: "User"
|
|
189
|
-
})
|
|
190
|
-
async getUser(args: { id: string }) {
|
|
191
|
-
const entity = await Entity.FindById(args.id);
|
|
192
|
-
if (!entity) return null;
|
|
193
|
-
return await UserArcheType.Unwrap(entity);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
@GraphQLField({ type: "User", field: "id" })
|
|
197
|
-
idResolver(parent: Entity) {
|
|
198
|
-
return parent.id;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
@GraphQLField({ type: "User", field: "name" })
|
|
202
|
-
async nameResolver(parent: Entity) {
|
|
203
|
-
const profile = await parent.get(UserProfile);
|
|
204
|
-
return profile?.name ?? "";
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
@GraphQLField({ type: "User", field: "email" })
|
|
208
|
-
async emailResolver(parent: Entity) {
|
|
209
|
-
const profile = await parent.get(UserProfile);
|
|
210
|
-
return profile?.email ?? "";
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
@GraphQLField({ type: "User", field: "username" })
|
|
214
|
-
async usernameResolver(parent: Entity) {
|
|
215
|
-
const profile = await parent.get(UserProfile);
|
|
216
|
-
return profile?.username ?? "";
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
### 4. Set Up the Application
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
// index.ts
|
|
225
|
-
import { App } from 'bunsane';
|
|
226
|
-
import UserService from './src/services/UserService';
|
|
227
|
-
|
|
228
|
-
async function main() {
|
|
229
|
-
// Services are automatically registered when imported
|
|
230
|
-
// No manual registration needed
|
|
231
|
-
|
|
232
|
-
// Create and start the application
|
|
233
|
-
const app = new App({
|
|
234
|
-
port: 3000,
|
|
235
|
-
databaseUrl: process.env.DATABASE_URL
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
await app.start();
|
|
239
|
-
|
|
240
|
-
console.log('🚀 BunSane server running on http://localhost:3000');
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
main().catch(console.error);
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### 5. Run Your Application
|
|
247
|
-
|
|
248
|
-
```bash
|
|
249
|
-
bun run index.ts
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
## 🧪 Testing Your Setup
|
|
253
|
-
|
|
254
|
-
### GraphQL API Testing
|
|
255
|
-
|
|
256
|
-
Your service now exposes GraphQL endpoints. Visit `http://localhost:3000/graphql` to access the GraphQL playground.
|
|
257
|
-
|
|
258
|
-
**Create User Mutation:**
|
|
259
|
-
```graphql
|
|
260
|
-
mutation CreateUser($input: CreateUserInput!) {
|
|
261
|
-
createUser(input: $input) {
|
|
262
|
-
id
|
|
263
|
-
name
|
|
264
|
-
email
|
|
265
|
-
username
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
With variables:
|
|
271
|
-
```json
|
|
272
|
-
{
|
|
273
|
-
"input": {
|
|
274
|
-
"name": "John Doe",
|
|
275
|
-
"email": "john.doe@example.com",
|
|
276
|
-
"username": "johndoe"
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
**Get User Query:**
|
|
282
|
-
```graphql
|
|
283
|
-
query GetUser($id: ID!) {
|
|
284
|
-
getUser(input: { id: $id }) {
|
|
285
|
-
id
|
|
286
|
-
name
|
|
287
|
-
email
|
|
288
|
-
username
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### REST API Testing
|
|
294
|
-
|
|
295
|
-
You can also test REST endpoints using tools like curl or Postman:
|
|
296
|
-
|
|
297
|
-
```bash
|
|
298
|
-
# Example curl request
|
|
299
|
-
curl -X GET http://localhost:3000/api/users
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
## 🔍 What's Next?
|
|
303
|
-
|
|
304
|
-
Congratulations! You now have a working BunSane application. Here's what you can explore next:
|
|
305
|
-
|
|
306
|
-
- **[Entity System](core-concepts/entity.md)** - Deep dive into entity management
|
|
307
|
-
- **[Component Architecture](core-concepts/components.md)** - Advanced component patterns
|
|
308
|
-
- **[Query System](core-concepts/query.md)** - Efficient data retrieval
|
|
309
|
-
- **[Lifecycle Hooks](core-concepts/hooks.md)** - Business logic integration
|
|
310
|
-
- **[Real Examples](examples/)** - Complete application tutorials
|
|
311
|
-
|
|
312
|
-
## 🐛 Troubleshooting
|
|
313
|
-
|
|
314
|
-
### Common Issues
|
|
315
|
-
|
|
316
|
-
**"Component not registered" error**
|
|
317
|
-
- Ensure all components are properly decorated with `@Component`
|
|
318
|
-
- Check that components are imported before use
|
|
319
|
-
|
|
320
|
-
**Database connection failed**
|
|
321
|
-
- Verify PostgreSQL is running
|
|
322
|
-
- Check DATABASE_URL format and credentials
|
|
323
|
-
- Ensure database exists and user has permissions
|
|
324
|
-
|
|
325
|
-
**Service not found error**
|
|
326
|
-
- Verify services extend `BaseService`
|
|
327
|
-
- Check that services are registered with `ServiceRegistry`
|
|
328
|
-
|
|
329
|
-
### Getting Help
|
|
330
|
-
|
|
331
|
-
- [GitHub Issues](https://github.com/yaaruu/bunsane/issues) - Report bugs
|
|
332
|
-
- [GitHub Discussions](https://github.com/yaaruu/bunsane/discussions) - Ask questions
|
|
333
|
-
- [Documentation](https://yaaruu.github.io/bunsane/) - Complete reference
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
*Ready to build something amazing? Let's continue with the [Entity System](core-concepts/entity.md)!* 🚀
|
package/docs/index.html
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>BunSane Framework Documentation</title>
|
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
7
|
-
<meta name="description" content="Professional documentation for BunSane - A batteries-included TypeScript API framework for Bun">
|
|
8
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
|
9
|
-
<link rel="icon" href="https://raw.githubusercontent.com/yaaruu/bunsane/main/BunSane.jpg" type="image/x-icon">
|
|
10
|
-
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
|
|
11
|
-
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/dark.css" title="dark" disabled>
|
|
12
|
-
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/buble.css" title="buble" disabled>
|
|
13
|
-
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/pure.css" title="pure" disabled>
|
|
14
|
-
<style>
|
|
15
|
-
.sidebar-nav ul li a {
|
|
16
|
-
font-size: 14px;
|
|
17
|
-
padding: 8px 15px;
|
|
18
|
-
}
|
|
19
|
-
.sidebar-nav ul li.active > a {
|
|
20
|
-
background-color: #f0f8ff;
|
|
21
|
-
border-left: 4px solid #007acc;
|
|
22
|
-
}
|
|
23
|
-
.content {
|
|
24
|
-
max-width: 900px;
|
|
25
|
-
}
|
|
26
|
-
.markdown-section h1 {
|
|
27
|
-
border-bottom: 2px solid #007acc;
|
|
28
|
-
padding-bottom: 10px;
|
|
29
|
-
}
|
|
30
|
-
.markdown-section h2 {
|
|
31
|
-
border-bottom: 1px solid #ddd;
|
|
32
|
-
padding-bottom: 5px;
|
|
33
|
-
}
|
|
34
|
-
.markdown-section code {
|
|
35
|
-
background-color: #f6f8fa;
|
|
36
|
-
padding: 2px 6px;
|
|
37
|
-
border-radius: 3px;
|
|
38
|
-
font-size: 0.9em;
|
|
39
|
-
}
|
|
40
|
-
.markdown-section pre code {
|
|
41
|
-
background-color: transparent;
|
|
42
|
-
padding: 0;
|
|
43
|
-
}
|
|
44
|
-
.markdown-section blockquote {
|
|
45
|
-
border-left: 4px solid #007acc;
|
|
46
|
-
background-color: #f0f8ff;
|
|
47
|
-
margin: 20px 0;
|
|
48
|
-
padding: 15px 20px;
|
|
49
|
-
}
|
|
50
|
-
</style>
|
|
51
|
-
</head>
|
|
52
|
-
<body>
|
|
53
|
-
<div id="app"></div>
|
|
54
|
-
<script>
|
|
55
|
-
window.$docsify = {
|
|
56
|
-
name: 'BunSane Framework',
|
|
57
|
-
repo: 'https://github.com/yaaruu/bunsane',
|
|
58
|
-
loadSidebar: true,
|
|
59
|
-
loadNavbar: true,
|
|
60
|
-
coverpage: true,
|
|
61
|
-
themeColor: '#007acc',
|
|
62
|
-
auto2top: true,
|
|
63
|
-
search: {
|
|
64
|
-
paths: 'auto',
|
|
65
|
-
placeholder: 'Search documentation...',
|
|
66
|
-
noData: 'No results found',
|
|
67
|
-
depth: 3
|
|
68
|
-
},
|
|
69
|
-
pagination: {
|
|
70
|
-
previousText: 'Previous',
|
|
71
|
-
nextText: 'Next',
|
|
72
|
-
crossChapter: true,
|
|
73
|
-
crossChapterText: true
|
|
74
|
-
},
|
|
75
|
-
plugins: [
|
|
76
|
-
function(hook, vm) {
|
|
77
|
-
hook.beforeEach(function(html) {
|
|
78
|
-
return html + '\n\n---\n\n*Last updated: ' + new Date().toLocaleDateString() + '*';
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
]
|
|
82
|
-
}
|
|
83
|
-
</script>
|
|
84
|
-
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/docsify.min.js"></script>
|
|
85
|
-
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/plugins/search.min.js"></script>
|
|
86
|
-
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/plugins/emoji.min.js"></script>
|
|
87
|
-
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/plugins/zoom-image.min.js"></script>
|
|
88
|
-
<script src="//cdn.jsdelivr.net/npm/docsify@4/lib/plugins/external-script.min.js"></script>
|
|
89
|
-
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
|
|
90
|
-
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
|
|
91
|
-
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-json.min.js"></script>
|
|
92
|
-
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-sql.min.js"></script>
|
|
93
|
-
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-graphql.min.js"></script>
|
|
94
|
-
<script src="//cdn.jsdelivr.net/npm/prismjs@1/plugins/line-numbers/prism-line-numbers.min.js"></script>
|
|
95
|
-
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/prismjs@1/plugins/line-numbers/prism-line-numbers.css">
|
|
96
|
-
</body>
|
|
97
|
-
</html>
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import {describe, test, expect, beforeAll, beforeEach} from "bun:test"
|
|
2
|
-
import App from "core/App"
|
|
3
|
-
import { BaseComponent, CompData, Component } from "core/Components";
|
|
4
|
-
import { Entity } from "core/Entity";
|
|
5
|
-
import db from "database";
|
|
6
|
-
|
|
7
|
-
let app;
|
|
8
|
-
beforeAll(async () => {
|
|
9
|
-
app = new App();
|
|
10
|
-
app.init();
|
|
11
|
-
await app.waitForAppReady();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
beforeEach(async () => {
|
|
15
|
-
await db`TRUNCATE TABLE entities CASCADE;`;
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
@Component
|
|
19
|
-
class TestComponent extends BaseComponent {
|
|
20
|
-
@CompData()
|
|
21
|
-
value: string = "";
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
@Component
|
|
25
|
-
class AnotherComponent extends BaseComponent {
|
|
26
|
-
@CompData()
|
|
27
|
-
numberValue: number = 0;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@Component
|
|
31
|
-
class YetAnotherComponent extends BaseComponent {
|
|
32
|
-
@CompData()
|
|
33
|
-
boolValue: boolean = false;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@Component
|
|
37
|
-
class MassiveComponent extends BaseComponent {
|
|
38
|
-
@CompData()
|
|
39
|
-
value: string = "";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
describe('Insert Entity Tests', () => {
|
|
43
|
-
test('Creating 10000 entities', async () => {
|
|
44
|
-
const entities = [];
|
|
45
|
-
for(let i = 0; i < 10000; i++) {
|
|
46
|
-
const entity = Entity.Create()
|
|
47
|
-
.add(TestComponent, {value: `Test ${i}`})
|
|
48
|
-
.add(AnotherComponent, {numberValue: i})
|
|
49
|
-
.add(YetAnotherComponent, {boolValue: i % 2 === 0})
|
|
50
|
-
.add(MassiveComponent, {value: "x".repeat(1000)});
|
|
51
|
-
entities.push(entity);
|
|
52
|
-
}
|
|
53
|
-
const start = performance.now();
|
|
54
|
-
await Promise.all(entities.map(entity => entity.save()));
|
|
55
|
-
const end = performance.now();
|
|
56
|
-
console.log(`Time taken to create 10000 entities: ${end - start}ms`);
|
|
57
|
-
const countResult :any = await db<{count: number}>`SELECT COUNT(*)::int FROM entities;`;
|
|
58
|
-
expect(countResult[0].count).toBe(10000);
|
|
59
|
-
});
|
|
60
|
-
});
|