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.
Files changed (257) hide show
  1. package/.claude/settings.local.json +47 -0
  2. package/.claude/skills/update-memory.md +74 -0
  3. package/.prettierrc +4 -0
  4. package/.serena/memories/architectural-decision-no-dependency-injection.md +76 -0
  5. package/.serena/memories/architecture.md +154 -0
  6. package/.serena/memories/cache-interface-refactoring-2026-01-24.md +165 -0
  7. package/.serena/memories/code_style_and_conventions.md +76 -0
  8. package/.serena/memories/project_overview.md +43 -0
  9. package/.serena/memories/schema-dsl-plan.md +107 -0
  10. package/.serena/memories/suggested_commands.md +80 -0
  11. package/.serena/memories/typescript-compilation-status.md +54 -0
  12. package/.serena/project.yml +114 -0
  13. package/TODO.md +1 -7
  14. package/bun.lock +150 -4
  15. package/bunfig.toml +10 -0
  16. package/config/cache.config.ts +77 -0
  17. package/config/upload.config.ts +4 -5
  18. package/core/App.ts +870 -123
  19. package/core/ArcheType.ts +2268 -377
  20. package/core/BatchLoader.ts +181 -71
  21. package/core/Config.ts +153 -0
  22. package/core/Decorators.ts +4 -1
  23. package/core/Entity.ts +621 -92
  24. package/core/EntityHookManager.ts +1 -1
  25. package/core/EntityInterface.ts +3 -1
  26. package/core/EntityManager.ts +1 -13
  27. package/core/ErrorHandler.ts +8 -2
  28. package/core/Logger.ts +9 -0
  29. package/core/Middleware.ts +34 -0
  30. package/core/RequestContext.ts +5 -1
  31. package/core/RequestLoaders.ts +227 -93
  32. package/core/SchedulerManager.ts +193 -52
  33. package/core/cache/CacheAnalytics.ts +399 -0
  34. package/core/cache/CacheFactory.ts +145 -0
  35. package/core/cache/CacheManager.ts +520 -0
  36. package/core/cache/CacheProvider.ts +34 -0
  37. package/core/cache/CacheWarmer.ts +157 -0
  38. package/core/cache/CompressionUtils.ts +110 -0
  39. package/core/cache/MemoryCache.ts +251 -0
  40. package/core/cache/MultiLevelCache.ts +180 -0
  41. package/core/cache/NoOpCache.ts +53 -0
  42. package/core/cache/RedisCache.ts +464 -0
  43. package/core/cache/TTLStrategy.ts +254 -0
  44. package/core/cache/index.ts +6 -0
  45. package/core/components/BaseComponent.ts +120 -0
  46. package/core/{ComponentRegistry.ts → components/ComponentRegistry.ts} +148 -54
  47. package/core/components/Decorators.ts +88 -0
  48. package/core/components/Interfaces.ts +7 -0
  49. package/core/components/index.ts +5 -0
  50. package/core/decorators/EntityHooks.ts +0 -3
  51. package/core/decorators/IndexedField.ts +26 -0
  52. package/core/decorators/ScheduledTask.ts +0 -47
  53. package/core/events/EntityLifecycleEvents.ts +1 -1
  54. package/core/health.ts +112 -0
  55. package/core/metadata/definitions/ArcheType.ts +14 -0
  56. package/core/metadata/definitions/Component.ts +9 -0
  57. package/core/metadata/definitions/gqlObject.ts +1 -1
  58. package/core/metadata/index.ts +42 -1
  59. package/core/metadata/metadata-storage.ts +28 -2
  60. package/core/middleware/AccessLog.ts +59 -0
  61. package/core/middleware/RequestId.ts +38 -0
  62. package/core/middleware/SecurityHeaders.ts +62 -0
  63. package/core/middleware/index.ts +3 -0
  64. package/core/scheduler/DistributedLock.ts +266 -0
  65. package/core/scheduler/index.ts +15 -0
  66. package/core/validateEnv.ts +92 -0
  67. package/database/DatabaseHelper.ts +416 -40
  68. package/database/IndexingStrategy.ts +342 -0
  69. package/database/PreparedStatementCache.ts +226 -0
  70. package/database/index.ts +32 -7
  71. package/database/sqlHelpers.ts +14 -2
  72. package/endpoints/archetypes.ts +362 -0
  73. package/endpoints/components.ts +58 -0
  74. package/endpoints/entity.ts +80 -0
  75. package/endpoints/index.ts +27 -0
  76. package/endpoints/query.ts +93 -0
  77. package/endpoints/stats.ts +76 -0
  78. package/endpoints/tables.ts +212 -0
  79. package/endpoints/types.ts +155 -0
  80. package/gql/ArchetypeOperations.ts +32 -86
  81. package/gql/Generator.ts +27 -315
  82. package/gql/GeneratorV2.ts +37 -0
  83. package/gql/builders/InputTypeBuilder.ts +99 -0
  84. package/gql/builders/ResolverBuilder.ts +234 -0
  85. package/gql/builders/TypeDefBuilder.ts +105 -0
  86. package/gql/builders/index.ts +3 -0
  87. package/gql/decorators/Upload.ts +1 -1
  88. package/gql/depthLimit.ts +85 -0
  89. package/gql/graph/GraphNode.ts +224 -0
  90. package/gql/graph/SchemaGraph.ts +278 -0
  91. package/gql/helpers.ts +8 -2
  92. package/gql/index.ts +56 -4
  93. package/gql/middleware.ts +79 -0
  94. package/gql/orchestration/GraphQLSchemaOrchestrator.ts +241 -0
  95. package/gql/orchestration/index.ts +1 -0
  96. package/gql/scanner/ServiceScanner.ts +347 -0
  97. package/gql/schema/index.ts +458 -0
  98. package/gql/strategies/TypeGenerationStrategy.ts +329 -0
  99. package/gql/types.ts +1 -0
  100. package/gql/utils/TypeSignature.ts +220 -0
  101. package/gql/utils/index.ts +1 -0
  102. package/gql/visitors/ArchetypePreprocessorVisitor.ts +80 -0
  103. package/gql/visitors/DeduplicationVisitor.ts +82 -0
  104. package/gql/visitors/GraphVisitor.ts +78 -0
  105. package/gql/visitors/ResolverGeneratorVisitor.ts +122 -0
  106. package/gql/visitors/SchemaGeneratorVisitor.ts +851 -0
  107. package/gql/visitors/TypeCollectorVisitor.ts +79 -0
  108. package/gql/visitors/VisitorComposer.ts +96 -0
  109. package/gql/visitors/index.ts +7 -0
  110. package/package.json +59 -37
  111. package/plugins/index.ts +2 -2
  112. package/query/CTENode.ts +97 -0
  113. package/query/ComponentInclusionNode.ts +689 -0
  114. package/query/FilterBuilder.ts +127 -0
  115. package/query/FilterBuilderRegistry.ts +202 -0
  116. package/query/OrNode.ts +517 -0
  117. package/query/OrQuery.ts +42 -0
  118. package/query/Query.ts +1022 -0
  119. package/query/QueryContext.ts +170 -0
  120. package/query/QueryDAG.ts +122 -0
  121. package/query/QueryNode.ts +65 -0
  122. package/query/SourceNode.ts +53 -0
  123. package/query/builders/FullTextSearchBuilder.ts +236 -0
  124. package/query/index.ts +21 -0
  125. package/scheduler/index.ts +40 -8
  126. package/service/Service.ts +2 -1
  127. package/service/ServiceRegistry.ts +6 -5
  128. package/{core/storage → storage}/LocalStorageProvider.ts +2 -2
  129. package/storage/S3StorageProvider.ts +316 -0
  130. package/{core/storage → storage}/StorageProvider.ts +7 -3
  131. package/studio/bun.lock +482 -0
  132. package/studio/index.html +13 -0
  133. package/studio/package.json +39 -0
  134. package/studio/postcss.config.js +6 -0
  135. package/studio/src/components/DataTable.tsx +211 -0
  136. package/studio/src/components/Layout.tsx +13 -0
  137. package/studio/src/components/PageContainer.tsx +9 -0
  138. package/studio/src/components/PageHeader.tsx +13 -0
  139. package/studio/src/components/SearchBar.tsx +57 -0
  140. package/studio/src/components/Sidebar.tsx +294 -0
  141. package/studio/src/components/ui/button.tsx +56 -0
  142. package/studio/src/components/ui/checkbox.tsx +26 -0
  143. package/studio/src/components/ui/input.tsx +25 -0
  144. package/studio/src/hooks/useDataTable.ts +131 -0
  145. package/studio/src/index.css +36 -0
  146. package/studio/src/lib/api.ts +186 -0
  147. package/studio/src/lib/utils.ts +13 -0
  148. package/studio/src/main.tsx +17 -0
  149. package/studio/src/pages/ArcheType.tsx +239 -0
  150. package/studio/src/pages/Components.tsx +124 -0
  151. package/studio/src/pages/EntityInspector.tsx +302 -0
  152. package/studio/src/pages/QueryRunner.tsx +246 -0
  153. package/studio/src/pages/Table.tsx +94 -0
  154. package/studio/src/pages/Welcome.tsx +241 -0
  155. package/studio/src/routes.tsx +45 -0
  156. package/studio/src/store/archeTypeSettings.ts +30 -0
  157. package/studio/src/store/studio.ts +65 -0
  158. package/studio/src/utils/columnHelpers.tsx +114 -0
  159. package/studio/studio-instructions.md +81 -0
  160. package/studio/tailwind.config.js +77 -0
  161. package/studio/tsconfig.json +24 -0
  162. package/studio/utils.ts +54 -0
  163. package/studio/vite.config.js +19 -0
  164. package/swagger/generator.ts +1 -1
  165. package/tests/e2e/http.test.ts +126 -0
  166. package/tests/fixtures/archetypes/TestUserArchetype.ts +21 -0
  167. package/tests/fixtures/components/TestOrder.ts +23 -0
  168. package/tests/fixtures/components/TestProduct.ts +23 -0
  169. package/tests/fixtures/components/TestUser.ts +20 -0
  170. package/tests/fixtures/components/index.ts +6 -0
  171. package/tests/graphql/SchemaGeneration.test.ts +90 -0
  172. package/tests/graphql/builders/ResolverBuilder.test.ts +223 -0
  173. package/tests/graphql/builders/TypeDefBuilder.test.ts +153 -0
  174. package/tests/integration/archetype/ArcheType.persistence.test.ts +241 -0
  175. package/tests/integration/cache/CacheInvalidation.test.ts +259 -0
  176. package/tests/integration/entity/Entity.persistence.test.ts +333 -0
  177. package/tests/integration/query/Query.exec.test.ts +523 -0
  178. package/tests/pglite-setup.ts +61 -0
  179. package/tests/setup.ts +164 -0
  180. package/tests/stress/BenchmarkRunner.ts +203 -0
  181. package/tests/stress/DataSeeder.ts +190 -0
  182. package/tests/stress/StressTestReporter.ts +229 -0
  183. package/tests/stress/cursor-perf-test.ts +171 -0
  184. package/tests/stress/fixtures/StressTestComponents.ts +58 -0
  185. package/tests/stress/index.ts +7 -0
  186. package/tests/stress/scenarios/query-benchmarks.test.ts +285 -0
  187. package/tests/unit/BatchLoader.test.ts +82 -0
  188. package/tests/unit/archetype/ArcheType.test.ts +107 -0
  189. package/tests/unit/cache/CacheManager.test.ts +347 -0
  190. package/tests/unit/cache/MemoryCache.test.ts +260 -0
  191. package/tests/unit/cache/RedisCache.test.ts +411 -0
  192. package/tests/unit/entity/Entity.components.test.ts +244 -0
  193. package/tests/unit/entity/Entity.test.ts +345 -0
  194. package/tests/unit/gql/depthLimit.test.ts +203 -0
  195. package/tests/unit/gql/operationMiddleware.test.ts +293 -0
  196. package/tests/unit/health/Health.test.ts +129 -0
  197. package/tests/unit/middleware/AccessLog.test.ts +37 -0
  198. package/tests/unit/middleware/Middleware.test.ts +98 -0
  199. package/tests/unit/middleware/RequestId.test.ts +54 -0
  200. package/tests/unit/middleware/SecurityHeaders.test.ts +66 -0
  201. package/tests/unit/query/FilterBuilder.test.ts +111 -0
  202. package/tests/unit/query/Query.test.ts +308 -0
  203. package/tests/unit/scheduler/DistributedLock.test.ts +274 -0
  204. package/tests/unit/schema/schema-integration.test.ts +426 -0
  205. package/tests/unit/schema/schema.test.ts +580 -0
  206. package/tests/unit/storage/S3StorageProvider.test.ts +571 -0
  207. package/tests/unit/upload/RestUpload.test.ts +267 -0
  208. package/tests/unit/validateEnv.test.ts +82 -0
  209. package/tests/utils/entity-tracker.ts +57 -0
  210. package/tests/utils/index.ts +13 -0
  211. package/tests/utils/test-context.ts +149 -0
  212. package/tsconfig.json +5 -1
  213. package/types/archetype.types.ts +6 -0
  214. package/types/hooks.types.ts +1 -1
  215. package/types/query.types.ts +110 -0
  216. package/types/scheduler.types.ts +68 -7
  217. package/types/upload.types.ts +1 -0
  218. package/{core → upload}/FileValidator.ts +10 -1
  219. package/upload/RestUpload.ts +130 -0
  220. package/{core/components → upload}/UploadComponent.ts +11 -11
  221. package/{core → upload}/UploadManager.ts +3 -3
  222. package/upload/index.ts +23 -7
  223. package/utils/UploadHelper.ts +27 -6
  224. package/utils/cronParser.ts +16 -6
  225. package/.github/workflows/deploy-docs.yml +0 -57
  226. package/core/Components.ts +0 -202
  227. package/core/EntityCache.ts +0 -15
  228. package/core/Query.ts +0 -880
  229. package/docs/README.md +0 -149
  230. package/docs/_coverpage.md +0 -36
  231. package/docs/_sidebar.md +0 -23
  232. package/docs/api/core.md +0 -568
  233. package/docs/api/hooks.md +0 -554
  234. package/docs/api/index.md +0 -222
  235. package/docs/api/query.md +0 -678
  236. package/docs/api/service.md +0 -744
  237. package/docs/core-concepts/archetypes.md +0 -512
  238. package/docs/core-concepts/components.md +0 -498
  239. package/docs/core-concepts/entity.md +0 -314
  240. package/docs/core-concepts/hooks.md +0 -683
  241. package/docs/core-concepts/query.md +0 -588
  242. package/docs/core-concepts/services.md +0 -647
  243. package/docs/examples/code-examples.md +0 -425
  244. package/docs/getting-started.md +0 -337
  245. package/docs/index.html +0 -97
  246. package/tests/bench/insert.bench.ts +0 -60
  247. package/tests/bench/relations.bench.ts +0 -270
  248. package/tests/bench/sorting.bench.ts +0 -416
  249. package/tests/component-hooks-simple.test.ts +0 -117
  250. package/tests/component-hooks.test.ts +0 -1461
  251. package/tests/component.test.ts +0 -339
  252. package/tests/errorHandling.test.ts +0 -155
  253. package/tests/hooks.test.ts +0 -667
  254. package/tests/query-sorting.test.ts +0 -101
  255. package/tests/query.test.ts +0 -81
  256. package/tests/relations.test.ts +0 -170
  257. package/tests/scheduler.test.ts +0 -724
@@ -0,0 +1,47 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(bun test:*)",
5
+ "mcp__serena__check_onboarding_performed",
6
+ "mcp__serena__activate_project",
7
+ "mcp__serena__onboarding",
8
+ "mcp__serena__list_dir",
9
+ "mcp__serena__find_file",
10
+ "mcp__serena__get_symbols_overview",
11
+ "mcp__serena__find_symbol",
12
+ "mcp__serena__think_about_collected_information",
13
+ "mcp__serena__write_memory",
14
+ "mcp__serena__list_memories",
15
+ "Bash(grep:*)",
16
+ "mcp__serena__initial_instructions",
17
+ "mcp__serena__read_memory",
18
+ "mcp__serena__search_for_pattern",
19
+ "mcp__serena__think_about_whether_you_are_done",
20
+ "mcp__serena__replace_symbol_body",
21
+ "Bash(find:*)",
22
+ "mcp__serena__get_current_config",
23
+ "mcp__serena__think_about_task_adherence",
24
+ "Bash(bun run tsc:*)",
25
+ "mcp__serena__insert_after_symbol",
26
+ "Bash(npx tsc:*)",
27
+ "Bash(STRESS_RECORD_COUNT=10000 bun test:*)",
28
+ "Bash(STRESS_RECORD_COUNT=1000 bun test:*)",
29
+ "mcp__serena__find_referencing_symbols",
30
+ "Bash(bun tsc:*)",
31
+ "mcp__serena__edit_memory",
32
+ "Bash(bunx tsc:*)",
33
+ "Bash(wc:*)",
34
+ "Bash(bun run:*)",
35
+ "Bash(BUN_CONFIG_FILE=/dev/null bun test:*)",
36
+ "Bash(echo:*)",
37
+ "WebSearch",
38
+ "Bash(bun:*)",
39
+ "Bash(tsc:*)",
40
+ "Bash(SKIP_TEST_DB_SETUP=true bun test:*)"
41
+ ]
42
+ },
43
+ "statusLine": {
44
+ "type": "command",
45
+ "command": "input=$(cat); model=$(echo \"$input\" | jq -r '.model.display_name'); used=$(echo \"$input\" | jq -r '.context_window.used_percentage // empty'); remaining=$(echo \"$input\" | jq -r '.context_window.remaining_percentage // empty'); if [ -n \"$remaining\" ]; then printf \"%s | Context: %.1f%% used, %.1f%% remaining\" \"$model\" \"$used\" \"$remaining\"; else echo \"$model\"; fi"
46
+ }
47
+ }
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: update-memory
3
+ description: Updating project memories with new information
4
+ disable-model-invocation: false
5
+ allowed-tools: Read, Grep
6
+ ---
7
+
8
+ # Update Memory Skill
9
+
10
+ This skill helps you update Serena project memories with new or changed information.
11
+
12
+ ## When to Use
13
+
14
+ Use `/update-memory` when you need to:
15
+ - Record architectural decisions or patterns discovered during work
16
+ - Update project conventions based on new practices
17
+ - Document important findings from code exploration
18
+ - Add new information to existing memory files
19
+ - Create new memory files for undocumented aspects
20
+
21
+ ## Instructions
22
+
23
+ 1. **List existing memories** first to see what's available:
24
+ - Use `mcp__serena__list_memories` to see all memory files
25
+
26
+ 2. **Read the relevant memory** (if updating existing):
27
+ - Use `mcp__serena__read_memory` with the memory file name
28
+ - Understand the current content and structure
29
+
30
+ 3. **Determine the action**:
31
+ - **Update existing**: Use `mcp__serena__edit_memory` for targeted changes
32
+ - **Create new**: Use `mcp__serena__write_memory` for new topics
33
+ - **Delete obsolete**: Use `mcp__serena__delete_memory` (only if user confirms)
34
+
35
+ 4. **For updates**, use `edit_memory` with:
36
+ - `mode: "literal"` for exact string replacement
37
+ - `mode: "regex"` for pattern-based changes
38
+ - Keep the existing format and style
39
+
40
+ 5. **For new memories**, use descriptive kebab-case names:
41
+ - `project_overview` - General project info
42
+ - `architecture` - System architecture
43
+ - `code_style_and_conventions` - Coding standards
44
+ - `{feature}-implementation` - Feature-specific docs
45
+
46
+ ## Memory Naming Conventions
47
+
48
+ | Pattern | Purpose |
49
+ |---------|---------|
50
+ | `project_overview` | High-level project description |
51
+ | `architecture` | Directory structure, core concepts |
52
+ | `code_style_and_conventions` | Formatting, naming, patterns |
53
+ | `{topic}-decisions` | Architectural decisions on topic |
54
+ | `{feature}-implementation` | How a feature works |
55
+ | `suggested_commands` | Useful commands for the project |
56
+ | `task_completion_checklist` | Steps to verify work is complete |
57
+
58
+ ## Example Usage
59
+
60
+ ```
61
+ User: /update-memory Add that we use Bun for testing
62
+ Assistant: [Lists memories, reads code_style_and_conventions, updates with new testing info]
63
+
64
+ User: /update-memory Create a memory about the caching system
65
+ Assistant: [Creates new memory file: caching-system.md with relevant information]
66
+ ```
67
+
68
+ ## Important Notes
69
+
70
+ - Always read existing content before editing to preserve context
71
+ - Use markdown format for memory content
72
+ - Keep memories focused and organized
73
+ - Ask for confirmation before deleting memories
74
+ - After updating, summarize what was changed
package/.prettierrc ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "tabWidth": 4,
3
+ "useTabs": false
4
+ }
@@ -0,0 +1,76 @@
1
+ # Architectural Decision: No Dependency Injection (For Now)
2
+
3
+ **Date:** 2026-01-21
4
+ **Status:** Decided
5
+ **Context:** Framework v0.1.5 (experimental)
6
+
7
+ ## Decision
8
+
9
+ BunSane will NOT implement a formal Dependency Injection (DI) container at this stage.
10
+
11
+ ## Current Approach
12
+
13
+ The framework uses:
14
+ - **Singleton patterns** for shared services (`CacheManager.getInstance()`, `EntityManager.instance`, `ComponentRegistry`)
15
+ - **Global exports** for database (`import db from "database"`) and logger
16
+ - **ApplicationLifecycle phases** for managing initialization order
17
+ - **Metadata-driven decorators** for component/service registration
18
+
19
+ ## Rationale
20
+
21
+ ### Why DI Was Considered
22
+ - Testing pain points: type-unsafe hacks like `(EntityManager as any).dbReady = true`
23
+ - Hard to mock/swap implementations in tests
24
+ - Singletons share global state between tests
25
+
26
+ ### Why DI Was Rejected (For Now)
27
+
28
+ 1. **Framework is experimental (v0.1.5)** - Too early for such fundamental architectural changes
29
+
30
+ 2. **Added complexity outweighs benefits** - DI adds another abstraction layer to an already complex ECS + GraphQL framework
31
+
32
+ 3. **Current approach works** - ApplicationLifecycle phases already manage dependency initialization order effectively
33
+
34
+ 4. **Users don't need to swap implementations** - Extensions happen via Components, Services, and Plugins, none of which benefit significantly from DI
35
+
36
+ 5. **Testing pain can be solved simpler** - Lightweight patterns like `reset()` methods or optional instance injection suffice
37
+
38
+ 6. **Bun ecosystem norms** - DI isn't a common pattern in modern Bun/TypeScript frameworks
39
+
40
+ 7. **Runtime overhead** - Relevant concern for a performance-focused framework
41
+
42
+ ## Alternative: Lightweight Testability Pattern
43
+
44
+ Instead of full DI, use optional instance injection for testability:
45
+
46
+ ```typescript
47
+ class CacheManager {
48
+ private static _instance: CacheManager | null = null;
49
+
50
+ static getInstance(): CacheManager {
51
+ return this._instance ??= new CacheManager();
52
+ }
53
+
54
+ // For testing only
55
+ static setInstance(instance: CacheManager | null): void {
56
+ this._instance = instance;
57
+ }
58
+ }
59
+ ```
60
+
61
+ ## When to Revisit
62
+
63
+ Consider DI if/when:
64
+ - Framework reaches v1.0 with stable APIs
65
+ - Users request ability to swap implementations
66
+ - Codebase grows significantly larger (200+ files)
67
+ - Multiple database/cache backends become first-class options
68
+
69
+ ## Related Files
70
+
71
+ - `core/cache/CacheManager.ts` - Singleton cache manager
72
+ - `core/EntityManager.ts` - Singleton entity manager
73
+ - `core/components/ComponentRegistry.ts` - Singleton component registry
74
+ - `service/ServiceRegistry.ts` - Singleton service registry
75
+ - `core/ApplicationLifecycle.ts` - Lifecycle phase management
76
+ - `database/index.ts` - Global database export
@@ -0,0 +1,154 @@
1
+ # Project Architecture
2
+
3
+ ## Directory Structure
4
+
5
+ ```
6
+ bunsane/
7
+ ├── core/ # Core framework
8
+ │ ├── App.ts # Main application entry point
9
+ │ ├── Entity.ts # Entity class (base data unit)
10
+ │ ├── EntityManager.ts # Entity lifecycle management
11
+ │ ├── ArcheType.ts # Entity templates with component definitions
12
+ │ ├── BatchLoader.ts # DataLoader for batching DB queries
13
+ │ ├── Config.ts # Configuration management
14
+ │ ├── Logger.ts # Pino logging setup
15
+ │ ├── ErrorHandler.ts # Error handling utilities
16
+ │ ├── RequestContext.ts # Request-scoped context
17
+ │ ├── ApplicationLifecycle.ts # App state management
18
+ │ ├── cache/ # Caching system
19
+ │ │ ├── CacheManager.ts # Main cache orchestration
20
+ │ │ ├── CacheProvider.ts # Standard interface (all providers implement this)
21
+ │ │ ├── MemoryCache.ts # In-memory cache provider
22
+ │ │ ├── RedisCache.ts # Redis cache provider
23
+ │ │ ├── MultiLevelCache.ts # L1/L2 cache strategy (wrapper)
24
+ │ │ ├── CacheAnalytics.ts # Analytics wrapper provider
25
+ │ │ ├── TTLStrategy.ts # Adaptive TTL wrapper provider
26
+ │ │ └── ...
27
+ │ ├── components/ # Component system
28
+ │ │ ├── BaseComponent.ts # Base class for components
29
+ │ │ ├── ComponentRegistry.ts # Component registration
30
+ │ │ ├── Decorators.ts # @Component, @CompData decorators
31
+ │ │ └── ...
32
+ │ ├── decorators/ # Additional decorators
33
+ │ ├── events/ # Event system
34
+ │ └── metadata/ # Metadata utilities
35
+ ├── database/ # Database layer
36
+ │ ├── index.ts # PostgreSQL connection (postgres.js)
37
+ │ ├── DatabaseHelper.ts # DB setup and migrations
38
+ │ ├── PreparedStatementCache.ts # Query caching
39
+ │ └── IndexingStrategy.ts # Index management
40
+ ├── query/ # Query builder
41
+ │ ├── Query.ts # Main query class
42
+ │ ├── FilterBuilder.ts # Filter construction
43
+ │ ├── QueryDAG.ts # Query execution graph
44
+ │ └── ...
45
+ ├── gql/ # GraphQL generation
46
+ │ ├── Generator.ts # Schema generation
47
+ │ ├── builders/ # Type/resolver builders
48
+ │ ├── decorators/ # GQL decorators
49
+ │ ├── strategies/ # Type generation strategies
50
+ │ └── visitors/ # Schema visitors
51
+ ├── service/ # Service layer
52
+ │ ├── Service.ts # Base service class
53
+ │ └── ServiceRegistry.ts # Service registration
54
+ ├── plugins/ # Plugin system
55
+ ├── scheduler/ # Task scheduling
56
+ ├── storage/ # File storage
57
+ ├── upload/ # File upload handling
58
+ ├── rest/ # REST endpoint support
59
+ ├── swagger/ # OpenAPI documentation
60
+ ├── studio/ # BunSane Studio (web UI)
61
+ ├── test/ # Tests
62
+ │ ├── setup.ts # Test environment setup
63
+ │ ├── integration/ # Integration tests
64
+ │ └── gql/ # GraphQL tests
65
+ ├── types/ # Type definitions
66
+ └── utils/ # Utility functions
67
+ ```
68
+
69
+ ## Core Concepts Flow
70
+
71
+ 1. **App** initializes the application, sets up GraphQL Yoga server
72
+ 2. **Components** are registered via `@Component` decorator
73
+ 3. **Entities** are created and manipulated, storing component data
74
+ 4. **ArcheTypes** define entity templates for type-safe component access
75
+ 5. **Query** builder retrieves entities with filters and component population
76
+ 6. **Services** define business logic and auto-generate GraphQL resolvers
77
+ 7. **CacheManager** handles caching at entity/component/query levels
78
+
79
+ ## Cache System Architecture
80
+
81
+ All cache providers implement the standardized `CacheProvider` interface:
82
+
83
+ ```typescript
84
+ interface CacheProvider {
85
+ get<T>(key: string): Promise<T | null>;
86
+ set<T>(key: string, value: T, ttl?: number): Promise<void>;
87
+ delete(key: string | string[]): Promise<void>; // Supports single or multiple
88
+ clear(): Promise<void>;
89
+ getMany<T>(keys: string[]): Promise<(T | null)[]>; // Returns ordered array
90
+ setMany<T>(entries: Array<{key, value, ttl?}>): Promise<void>; // Per-entry TTL
91
+ deleteMany(keys: string[]): Promise<void>;
92
+ invalidatePattern(pattern: string): Promise<void>;
93
+ ping(): Promise<boolean>; // Health check
94
+ getStats(): Promise<CacheStats>; // Metrics
95
+ }
96
+ ```
97
+
98
+ **Cache Providers**:
99
+ - **MemoryCache**: In-memory LRU cache (base implementation)
100
+ - **RedisCache**: Redis-backed cache (base implementation)
101
+ - **MultiLevelCacheProvider**: L1 (memory) + L2 (Redis) wrapper
102
+ - **AnalyticsCacheProvider**: Metrics and latency tracking wrapper
103
+ - **AdaptiveTTLProvider**: Dynamic TTL adjustment wrapper
104
+
105
+ **Key Design Decisions** (as of 2026-01-24):
106
+ - Batch operations use arrays instead of Maps for ordering and flexibility
107
+ - `delete()` accepts both single string and string array for convenience
108
+ - `ping()` replaces `healthCheck()` for conventional naming
109
+ - All wrappers maintain full interface compliance
110
+
111
+ ## Import Resolution (as of 2026-02-05)
112
+
113
+ All internal imports use **relative paths** (`./`, `../`). Bare imports like `from "core/Logger"` that rely on `baseUrl` are NOT allowed because they break TypeScript type checking for consumers who install bunsane as a dependency (their tsconfig does not have baseUrl pointing to bunsane root).
114
+
115
+ ## Data Model
116
+
117
+ - **Entity**: UUID-identified record in `entities` table
118
+ - **Component**: JSONB data in `components` table, linked to entity
119
+ - Components are identified by `entity_id` + `component_type`
120
+ - Supports indexing specific component fields for queries
121
+
122
+ ## CORS System (as of 2026-02-04)
123
+
124
+ The App class (`core/App.ts`) provides comprehensive CORS support with proper spec compliance.
125
+
126
+ **CorsConfig Type**:
127
+ ```typescript
128
+ type CorsConfig = {
129
+ origin?: string | string[] | ((origin: string) => boolean);
130
+ credentials?: boolean;
131
+ allowedHeaders?: string[];
132
+ exposedHeaders?: string[]; // For Access-Control-Expose-Headers
133
+ methods?: string[];
134
+ maxAge?: number; // Preflight cache duration in seconds
135
+ };
136
+ ```
137
+
138
+ **Key Features**:
139
+ - **Origin Validation**: Validates request Origin header against configured origins
140
+ - **Array Origins**: Returns the matching origin (not comma-joined) per spec
141
+ - **Function Origins**: Supports `(origin: string) => boolean` for dynamic validation
142
+ - **Credentials + Wildcard**: When credentials=true with origin="*", reflects actual origin instead of wildcard
143
+ - **Vary Header**: Always includes `Vary: Origin` for proper caching
144
+ - **All Endpoints**: CORS headers applied to all response paths (health, docs, openapi, studio, errors)
145
+
146
+ **Usage**:
147
+ ```typescript
148
+ app.setCors({
149
+ origin: ["http://localhost:3000", "https://myapp.com"],
150
+ credentials: true,
151
+ maxAge: 86400,
152
+ exposedHeaders: ["X-Custom-Header"]
153
+ });
154
+ ```
@@ -0,0 +1,165 @@
1
+ # Cache Interface Refactoring - January 24, 2026
2
+
3
+ ## Status: COMPLETED
4
+ **Completion Date**: 2026-01-24
5
+ **Outcome**: Successfully standardized CacheProvider interface implementation across all cache-related files
6
+
7
+ ## Summary
8
+ Fixed TypeScript compilation errors caused by mismatches between the `CacheProvider` interface and its implementations. The interface was correct, but several wrapper classes and test files had outdated method signatures.
9
+
10
+ ## Impact
11
+ - **Errors Reduced**: From 100+ TypeScript errors to 69
12
+ - **Cache Errors**: Fully resolved (0 remaining)
13
+ - **Remaining Errors**: Unrelated to cache (SchedulerManager, GraphQL builders, test access to private members)
14
+
15
+ ## Files Modified
16
+
17
+ ### Core Cache Files (3 files)
18
+
19
+ #### 1. `core/cache/CacheAnalytics.ts`
20
+ **Class**: `AnalyticsCacheProvider`
21
+
22
+ Changes:
23
+ - Changed import to type-only import: `import type { CacheProvider } from './CacheProvider'`
24
+ - Made `recordLatency` method public
25
+ - Fixed method signatures:
26
+ - `delete(key: string | string[]): Promise<void>` (was single key only)
27
+ - `getMany<T>(keys: string[]): Promise<(T | null)[]>` (was returning Map)
28
+ - `setMany<T>(entries: Array<{key, value, ttl?}>): Promise<void>` (was using Map)
29
+ - `deleteMany(keys: string[]): Promise<void>` (added proper typing)
30
+ - `ping(): Promise<boolean>` (replaced `healthCheck()`)
31
+ - `getStats(): Promise<CacheStats>` (was async but not typed correctly)
32
+ - Removed `has()` method (not in interface)
33
+
34
+ #### 2. `core/cache/MultiLevelCache.ts`
35
+ **Class**: `MultiLevelCacheProvider`
36
+
37
+ Changes:
38
+ - Fixed import path and made type-only
39
+ - Applied same method signature fixes as CacheAnalytics
40
+ - Added proper type guards for array access in `delete()` method
41
+ - Ensured L1/L2 cache coordination respects new interface
42
+
43
+ #### 3. `core/cache/TTLStrategy.ts`
44
+ **Class**: `AdaptiveTTLProvider`
45
+
46
+ Changes:
47
+ - Applied same method signature fixes as above
48
+ - Ensured TTL adaptation logic works with updated interface
49
+
50
+ ### Config Files (1 file)
51
+
52
+ #### 4. `config/cache.config.ts`
53
+
54
+ Changes:
55
+ - Added `'multilevel'` to provider type union
56
+ - Added `query` property with structure:
57
+ ```typescript
58
+ query: {
59
+ enabled: boolean;
60
+ ttl: number;
61
+ maxSize: number;
62
+ }
63
+ ```
64
+
65
+ ### Test Files (7 files)
66
+
67
+ #### 5. `tests/unit/cache/MemoryCache.test.ts`
68
+ - Added explicit type parameters to `cache.get<T>()` calls
69
+ - Ensures type safety in test assertions
70
+
71
+ #### 6. `tests/unit/cache/RedisCache.test.ts`
72
+ - Added explicit type parameters to `cache.get<T>()` calls
73
+
74
+ #### 7-11. Test Configuration Files
75
+ Added `maxSize` to query config objects in:
76
+ - `tests/integration/cache/CacheInvalidation.test.ts`
77
+ - `tests/setup.ts`
78
+ - `tests/stress/cursor-perf-test.ts`
79
+ - `tests/unit/cache/CacheManager.test.ts`
80
+ - `tests/utils/test-context.ts`
81
+
82
+ ## Key Interface Contract
83
+
84
+ ```typescript
85
+ interface CacheProvider {
86
+ // Single operations
87
+ get<T>(key: string): Promise<T | null>;
88
+ set<T>(key: string, value: T, ttl?: number): Promise<void>;
89
+ delete(key: string | string[]): Promise<void>;
90
+ clear(): Promise<void>;
91
+
92
+ // Batch operations
93
+ getMany<T>(keys: string[]): Promise<(T | null)[]>;
94
+ setMany<T>(entries: Array<{key: string, value: T, ttl?: number}>): Promise<void>;
95
+ deleteMany(keys: string[]): Promise<void>;
96
+
97
+ // Pattern operations
98
+ invalidatePattern(pattern: string): Promise<void>;
99
+
100
+ // Health and metrics
101
+ ping(): Promise<boolean>;
102
+ getStats(): Promise<CacheStats>;
103
+ }
104
+ ```
105
+
106
+ ## Critical Design Decisions
107
+
108
+ ### 1. Array Return for getMany
109
+ **Decision**: `getMany` returns `Promise<(T | null)[]>` instead of `Map<string, T | null>`
110
+ **Rationale**:
111
+ - Maintains order of requested keys
112
+ - Simpler type handling
113
+ - Better performance for indexed access
114
+
115
+ ### 2. Entry Array for setMany
116
+ **Decision**: `setMany` takes `Array<{key, value, ttl?}>` instead of `Map`
117
+ **Rationale**:
118
+ - Supports per-entry TTL configuration
119
+ - More flexible than Map-based approach
120
+ - Aligns with common cache API patterns
121
+
122
+ ### 3. Flexible Delete
123
+ **Decision**: `delete(key: string | string[])` accepts both single and multiple keys
124
+ **Rationale**:
125
+ - Reduces API surface area (no need for separate deleteOne/deleteMany)
126
+ - Convenience for common use cases
127
+ - Backward compatible with single-key usage
128
+
129
+ ### 4. Ping Instead of HealthCheck
130
+ **Decision**: Renamed `healthCheck()` to `ping()`
131
+ **Rationale**:
132
+ - Shorter, more conventional name
133
+ - Matches Redis and memcached naming
134
+ - Clearer intent (simple connectivity check)
135
+
136
+ ## Verification
137
+
138
+ ### TypeScript Compilation
139
+ - All cache-related files now compile without errors
140
+ - Type safety enforced across all implementations
141
+ - No type assertions or `any` types introduced
142
+
143
+ ### Interface Compliance
144
+ All three wrapper implementations now fully comply:
145
+ - AnalyticsCacheProvider (wraps any provider with metrics)
146
+ - MultiLevelCacheProvider (L1/L2 cache coordination)
147
+ - AdaptiveTTLProvider (dynamic TTL adjustment)
148
+
149
+ ## Follow-Up Items
150
+
151
+ None for cache. Remaining TypeScript errors are in:
152
+ 1. **SchedulerManager**: Unrelated to cache
153
+ 2. **GraphQL builders**: Schema generation issues
154
+ 3. **Test files**: Access to private members (test-specific issues)
155
+
156
+ ## Lessons Learned
157
+
158
+ 1. **Interface-First Design**: Having a well-defined interface is only half the battle; keeping implementations in sync is critical
159
+ 2. **Type-Only Imports**: Using `import type` helps clarify when you're only referencing types vs. runtime values
160
+ 3. **Batch Operations**: The switch from Map to Array for batch ops required careful consideration of ordering and flexibility
161
+ 4. **Test Coverage**: Tests that use explicit type parameters catch more type mismatches earlier
162
+
163
+ ## Related Memories
164
+ - See `architecture` for overall cache system design
165
+ - See `code_style_and_conventions` for TypeScript patterns used
@@ -0,0 +1,76 @@
1
+ # Code Style and Conventions
2
+
3
+ ## Formatting
4
+ - **Indentation**: 4 spaces (configured in `.prettierrc`)
5
+ - **No tabs**: Spaces only
6
+ - **Prettier**: Used for formatting
7
+
8
+ ## TypeScript Configuration
9
+ - **Strict mode**: Enabled
10
+ - **Experimental decorators**: Enabled
11
+ - **Emit decorator metadata**: Enabled
12
+ - **Module**: ESNext/Preserve
13
+ - **Path alias**: `@/*` maps to `./*`
14
+
15
+ ## Naming Conventions
16
+ - **Classes**: PascalCase (e.g., `Entity`, `BaseComponent`, `CacheManager`)
17
+ - **Methods/Functions**: camelCase (e.g., `createEntity`, `getEntityWithID`)
18
+ - **Variables**: camelCase
19
+ - **Constants**: camelCase or UPPER_SNAKE_CASE for environment-like values
20
+ - **Private properties**: Prefix with underscore (e.g., `_dirty`, `_persisted`)
21
+ - **Interfaces**: PascalCase, often prefixed with `I` (e.g., `IEntity`)
22
+ - **Types**: PascalCase
23
+
24
+ ## Decorators Usage
25
+ The framework heavily uses TypeScript decorators:
26
+
27
+ ```typescript
28
+ // Component definition
29
+ @Component
30
+ class MyComponent extends BaseComponent {
31
+ @CompData()
32
+ myField!: string;
33
+ }
34
+
35
+ // ArcheType definition
36
+ class MyArcheType extends BaseArcheType {
37
+ @ArcheTypeField(MyComponent)
38
+ myComponent!: MyComponent;
39
+ }
40
+ ```
41
+
42
+ ## Import Style
43
+ - **ALWAYS use relative imports** (`./`, `../`) for all internal modules
44
+ - Do NOT use bare imports like `from "core/Logger"` - they rely on `baseUrl` and break consumer typechecking
45
+ - The `@/` path alias is configured but not used in practice; prefer relative imports
46
+ - Group imports: external packages first, then internal modules
47
+ - **Type-only imports**: Use `import type` for interface/type imports when only used for type checking:
48
+ ```typescript
49
+ import type { CacheProvider } from './CacheProvider';
50
+ ```
51
+ Benefits: Clearer intent, reduced runtime dependencies, better tree-shaking
52
+
53
+ ## Testing Conventions
54
+ - Test files: `*.test.ts`
55
+ - Use Bun's built-in test runner (`bun:test`)
56
+ - Structure: `describe` blocks for grouping, `test` for individual cases
57
+ - Use `beforeAll`/`afterAll` for setup/cleanup
58
+ - Integration tests should clean up created entities
59
+
60
+ ```typescript
61
+ import { describe, test, expect, beforeAll, afterAll } from 'bun:test';
62
+
63
+ describe('FeatureName', () => {
64
+ beforeAll(async () => { /* setup */ });
65
+ afterAll(async () => { /* cleanup */ });
66
+
67
+ test('should do something', async () => {
68
+ expect(result).toBe(expected);
69
+ });
70
+ });
71
+ ```
72
+
73
+ ## Documentation
74
+ - Use JSDoc comments for public APIs
75
+ - Block comments for file headers explaining purpose
76
+ - Inline comments sparingly, only when logic is complex
@@ -0,0 +1,43 @@
1
+ # BunSane Project Overview
2
+
3
+ ## Purpose
4
+ BunSane is a batteries-included TypeScript API framework for Bun with:
5
+ - Entity–Component storage on PostgreSQL (auto-migrates base tables on first run)
6
+ - Fluent, performant Query builder
7
+ - Zero-boilerplate GraphQL with GraphQL Yoga
8
+ - Declarative Components with decorators and indexed fields
9
+
10
+ **Status**: EXPERIMENTAL - Not Production Ready
11
+
12
+ ## Tech Stack
13
+ - **Runtime**: Bun
14
+ - **Language**: TypeScript 5.9+ (strict mode, experimental decorators)
15
+ - **Database**: PostgreSQL
16
+ - **GraphQL**: GraphQL Yoga + GQLoom (@gqloom/core, @gqloom/zod)
17
+ - **Validation**: Zod 4.x
18
+ - **Logging**: Pino (with pino-pretty for development)
19
+ - **Cache**: Memory and Redis support (ioredis)
20
+ - **Data Loading**: dataloader for batching
21
+
22
+ ## Key Concepts
23
+ 1. **Entity**: Base unit of data storage, identified by UUID
24
+ 2. **Component**: Data attached to entities (decorators: @Component, @CompData)
25
+ 3. **ArcheType**: Defines a template of components an entity should have
26
+ 4. **Query**: Fluent query builder for retrieving entities with components
27
+ 5. **Service**: Business logic layer with auto-generated GraphQL schema
28
+
29
+ ## Environment Variables
30
+ Database configuration via environment variables:
31
+ - `POSTGRES_HOST`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`
32
+ - `POSTGRES_MAX_CONNECTIONS`
33
+ - `LOG_LEVEL`, `LOG_PRETTY`
34
+
35
+ ## Cache Configuration
36
+ Cache system supports multiple providers (configured in `config/cache.config.ts`):
37
+ - **Providers**: `memory`, `redis`, `multilevel`
38
+ - **Query cache**: Can be enabled with configurable TTL and max size
39
+ - All providers implement standardized `CacheProvider` interface
40
+ - Wrapper providers available: Analytics, MultiLevel, AdaptiveTTL
41
+
42
+ ## Repository
43
+ https://github.com/yaaruu/bunsane