bunsane 0.3.2 → 0.5.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 (220) hide show
  1. package/CHANGELOG.md +471 -370
  2. package/core/BatchLoader.ts +56 -32
  3. package/core/Entity.ts +93 -1020
  4. package/core/EntityHookManager.ts +52 -754
  5. package/core/Logger.ts +10 -0
  6. package/core/RequestContext.ts +94 -85
  7. package/core/RequestLoaders.ts +98 -5
  8. package/core/SchedulerManager.ts +28 -600
  9. package/core/app/cors.ts +2 -11
  10. package/core/app/preparedStatementWarmup.ts +9 -49
  11. package/core/app/requestRouter.ts +9 -8
  12. package/core/app/restRegistry.ts +8 -0
  13. package/core/archetype/fieldResolvers.ts +85 -40
  14. package/core/archetype/relationLoader.ts +135 -92
  15. package/core/cache/CacheManager.ts +91 -302
  16. package/core/cache/CompressionUtils.ts +34 -3
  17. package/core/cache/MemoryCache.ts +40 -37
  18. package/core/cache/RedisCache.ts +8 -7
  19. package/core/cache/health.ts +30 -0
  20. package/core/cache/invalidation.ts +96 -0
  21. package/core/cache/strategies/writeInvalidate.ts +111 -0
  22. package/core/cache/strategies/writeThrough.ts +233 -0
  23. package/core/components/BaseComponent.ts +25 -10
  24. package/core/components/ComponentRegistry.ts +28 -0
  25. package/core/decorators/IndexedField.ts +1 -1
  26. package/core/entity/cacheStrategies.ts +97 -0
  27. package/core/entity/componentAccess.ts +383 -0
  28. package/core/entity/finders.ts +202 -0
  29. package/core/entity/getCacheManager.ts +10 -0
  30. package/core/entity/pendingOps.ts +72 -0
  31. package/core/entity/saveEntity.ts +375 -0
  32. package/core/health.ts +93 -4
  33. package/core/hooks/dispatcher.ts +439 -0
  34. package/core/hooks/guards.ts +155 -0
  35. package/core/hooks/registry.ts +247 -0
  36. package/core/metadata/definitions/Component.ts +1 -1
  37. package/core/metadata/index.ts +15 -4
  38. package/core/middleware/RateLimit.ts +102 -105
  39. package/core/middleware/RequestId.ts +2 -9
  40. package/core/middleware/SecurityHeaders.ts +2 -11
  41. package/core/middleware/headers.ts +28 -0
  42. package/core/remote/OutboxWorker.ts +213 -183
  43. package/core/remote/RemoteManager.ts +401 -400
  44. package/core/remote/StreamConsumer.ts +535 -535
  45. package/core/remote/types.ts +153 -151
  46. package/core/requestScope.ts +34 -0
  47. package/core/scheduler/cronEvaluator.ts +174 -0
  48. package/core/scheduler/lifecycleHooks.ts +21 -0
  49. package/core/scheduler/lockCoordinator.ts +27 -0
  50. package/core/scheduler/metrics.ts +14 -0
  51. package/core/scheduler/taskRunner.ts +420 -0
  52. package/core/validateEnv.ts +10 -0
  53. package/database/DatabaseHelper.ts +128 -101
  54. package/database/IndexingStrategy.ts +72 -2
  55. package/database/PreparedStatementCache.ts +8 -2
  56. package/database/cancellable.ts +35 -22
  57. package/database/index.ts +29 -3
  58. package/database/instrumentedDb.ts +141 -141
  59. package/database/sqlHelpers.ts +3 -1
  60. package/endpoints/archetypes.ts +2 -8
  61. package/endpoints/tables.ts +6 -1
  62. package/gql/index.ts +1 -1
  63. package/gql/schema/index.ts +15 -4
  64. package/gql/visitors/ResolverGeneratorVisitor.ts +25 -4
  65. package/package.json +22 -1
  66. package/query/CTENode.ts +5 -3
  67. package/query/ComponentInclusionNode.ts +245 -14
  68. package/query/OrNode.ts +8 -19
  69. package/query/Query.ts +208 -79
  70. package/query/QueryContext.ts +6 -0
  71. package/query/QueryDAG.ts +7 -2
  72. package/query/membershipSource.ts +66 -0
  73. package/storage/LocalStorageProvider.ts +8 -3
  74. package/studio/dist/assets/index-BMZ67Npg.js +254 -0
  75. package/studio/dist/assets/index-BpbuYz9g.css +1 -0
  76. package/studio/{index.html → dist/index.html} +3 -2
  77. package/swagger/generator.ts +11 -1
  78. package/upload/UploadManager.ts +8 -6
  79. package/utils/uuid.ts +40 -10
  80. package/.claude/scheduled_tasks.lock +0 -1
  81. package/.claude/settings.local.json +0 -47
  82. package/.prettierrc +0 -4
  83. package/.serena/memories/architectural-decision-no-dependency-injection.md +0 -76
  84. package/.serena/memories/architecture.md +0 -154
  85. package/.serena/memories/cache-interface-refactoring-2026-01-24.md +0 -165
  86. package/.serena/memories/code_style_and_conventions.md +0 -76
  87. package/.serena/memories/project_overview.md +0 -43
  88. package/.serena/memories/schema-dsl-plan.md +0 -107
  89. package/.serena/memories/suggested_commands.md +0 -80
  90. package/.serena/memories/typescript-compilation-status.md +0 -54
  91. package/.serena/project.yml +0 -114
  92. package/BunSane.jpg +0 -0
  93. package/CLAUDE.md +0 -198
  94. package/TODO.md +0 -2
  95. package/bun.lock +0 -302
  96. package/bunfig.toml +0 -10
  97. package/docs/RFC_APP_REFACTOR.md +0 -248
  98. package/docs/RFC_REFACTOR_TARGETS.md +0 -251
  99. package/docs/SCALABILITY_PLAN.md +0 -175
  100. package/studio/bun.lock +0 -482
  101. package/studio/package.json +0 -39
  102. package/studio/postcss.config.js +0 -6
  103. package/studio/src/components/DataTable.tsx +0 -211
  104. package/studio/src/components/Layout.tsx +0 -13
  105. package/studio/src/components/PageContainer.tsx +0 -9
  106. package/studio/src/components/PageHeader.tsx +0 -13
  107. package/studio/src/components/SearchBar.tsx +0 -57
  108. package/studio/src/components/Sidebar.tsx +0 -294
  109. package/studio/src/components/ui/button.tsx +0 -56
  110. package/studio/src/components/ui/checkbox.tsx +0 -26
  111. package/studio/src/components/ui/input.tsx +0 -25
  112. package/studio/src/hooks/useDataTable.ts +0 -131
  113. package/studio/src/index.css +0 -36
  114. package/studio/src/lib/api.ts +0 -186
  115. package/studio/src/lib/utils.ts +0 -13
  116. package/studio/src/main.tsx +0 -17
  117. package/studio/src/pages/ArcheType.tsx +0 -239
  118. package/studio/src/pages/Components.tsx +0 -124
  119. package/studio/src/pages/EntityInspector.tsx +0 -302
  120. package/studio/src/pages/QueryRunner.tsx +0 -246
  121. package/studio/src/pages/Table.tsx +0 -94
  122. package/studio/src/pages/Welcome.tsx +0 -241
  123. package/studio/src/routes.tsx +0 -45
  124. package/studio/src/store/archeTypeSettings.ts +0 -30
  125. package/studio/src/store/studio.ts +0 -65
  126. package/studio/src/utils/columnHelpers.tsx +0 -114
  127. package/studio/studio-instructions.md +0 -81
  128. package/studio/tailwind.config.js +0 -77
  129. package/studio/utils.ts +0 -54
  130. package/studio/vite.config.js +0 -19
  131. package/tests/benchmark/BENCHMARK_DATABASES_PLAN.md +0 -338
  132. package/tests/benchmark/bunfig.toml +0 -9
  133. package/tests/benchmark/fixtures/EcommerceComponents.ts +0 -283
  134. package/tests/benchmark/fixtures/EcommerceDataGenerators.ts +0 -301
  135. package/tests/benchmark/fixtures/RelationTracker.ts +0 -159
  136. package/tests/benchmark/fixtures/index.ts +0 -6
  137. package/tests/benchmark/index.ts +0 -22
  138. package/tests/benchmark/noop-preload.ts +0 -3
  139. package/tests/benchmark/query-lateral-benchmark.test.ts +0 -372
  140. package/tests/benchmark/runners/BenchmarkLoader.ts +0 -132
  141. package/tests/benchmark/runners/index.ts +0 -4
  142. package/tests/benchmark/scenarios/query-benchmarks.test.ts +0 -465
  143. package/tests/benchmark/scripts/generate-db.ts +0 -344
  144. package/tests/benchmark/scripts/run-benchmarks.ts +0 -97
  145. package/tests/e2e/http.test.ts +0 -130
  146. package/tests/fixtures/archetypes/TestUserArchetype.ts +0 -21
  147. package/tests/fixtures/components/TestOrder.ts +0 -23
  148. package/tests/fixtures/components/TestProduct.ts +0 -23
  149. package/tests/fixtures/components/TestUser.ts +0 -20
  150. package/tests/fixtures/components/index.ts +0 -6
  151. package/tests/graphql/SchemaGeneration.test.ts +0 -90
  152. package/tests/graphql/builders/ResolverBuilder.test.ts +0 -223
  153. package/tests/graphql/builders/TypeDefBuilder.test.ts +0 -153
  154. package/tests/helpers/MockRedisClient.ts +0 -113
  155. package/tests/helpers/MockRedisStreamServer.ts +0 -448
  156. package/tests/integration/archetype/ArcheType.persistence.test.ts +0 -241
  157. package/tests/integration/cache/CacheInvalidation.test.ts +0 -259
  158. package/tests/integration/entity/Entity.persistence.test.ts +0 -333
  159. package/tests/integration/entity/Entity.saveTimeout.test.ts +0 -110
  160. package/tests/integration/loaders/RequestLoaders.abort.test.ts +0 -82
  161. package/tests/integration/query/Query.abort.test.ts +0 -66
  162. package/tests/integration/query/Query.complexAnalysis.test.ts +0 -557
  163. package/tests/integration/query/Query.edgeCases.test.ts +0 -595
  164. package/tests/integration/query/Query.exec.test.ts +0 -576
  165. package/tests/integration/query/Query.explainAnalyze.test.ts +0 -233
  166. package/tests/integration/query/Query.jsonbArray.test.ts +0 -214
  167. package/tests/integration/remote/dlq.test.ts +0 -175
  168. package/tests/integration/remote/event-dispatch.test.ts +0 -114
  169. package/tests/integration/remote/outbox.test.ts +0 -130
  170. package/tests/integration/remote/rpc.test.ts +0 -177
  171. package/tests/pglite-setup.ts +0 -62
  172. package/tests/setup.ts +0 -164
  173. package/tests/stress/BenchmarkRunner.ts +0 -203
  174. package/tests/stress/DataSeeder.ts +0 -190
  175. package/tests/stress/StressTestReporter.ts +0 -229
  176. package/tests/stress/cursor-perf-test.ts +0 -171
  177. package/tests/stress/fixtures/RealisticComponents.ts +0 -235
  178. package/tests/stress/fixtures/StressTestComponents.ts +0 -58
  179. package/tests/stress/index.ts +0 -7
  180. package/tests/stress/scenarios/query-benchmarks.test.ts +0 -285
  181. package/tests/stress/scenarios/realistic-scenarios.test.ts +0 -1081
  182. package/tests/stress/scenarios/timeout-investigation.test.ts +0 -522
  183. package/tests/unit/BatchLoader.test.ts +0 -196
  184. package/tests/unit/archetype/ArcheType.test.ts +0 -107
  185. package/tests/unit/cache/CacheManager.test.ts +0 -498
  186. package/tests/unit/cache/MemoryCache.test.ts +0 -260
  187. package/tests/unit/cache/RedisCache.test.ts +0 -411
  188. package/tests/unit/database/cancellable.test.ts +0 -81
  189. package/tests/unit/database/instrumentedDb.test.ts +0 -160
  190. package/tests/unit/entity/Entity.components.test.ts +0 -317
  191. package/tests/unit/entity/Entity.drainSideEffects.test.ts +0 -51
  192. package/tests/unit/entity/Entity.reload.test.ts +0 -63
  193. package/tests/unit/entity/Entity.requireComponents.test.ts +0 -72
  194. package/tests/unit/entity/Entity.test.ts +0 -345
  195. package/tests/unit/gql/depthLimit.test.ts +0 -203
  196. package/tests/unit/gql/operationMiddleware.test.ts +0 -293
  197. package/tests/unit/health/Health.test.ts +0 -129
  198. package/tests/unit/middleware/AccessLog.test.ts +0 -37
  199. package/tests/unit/middleware/Middleware.test.ts +0 -98
  200. package/tests/unit/middleware/RequestId.test.ts +0 -54
  201. package/tests/unit/middleware/SecurityHeaders.test.ts +0 -66
  202. package/tests/unit/query/FilterBuilder.test.ts +0 -111
  203. package/tests/unit/query/JsonbArrayBuilder.test.ts +0 -178
  204. package/tests/unit/query/Query.emptyString.test.ts +0 -69
  205. package/tests/unit/query/Query.test.ts +0 -310
  206. package/tests/unit/remote/CircuitBreaker.test.ts +0 -159
  207. package/tests/unit/remote/RemoteError.test.ts +0 -55
  208. package/tests/unit/remote/decorators.test.ts +0 -195
  209. package/tests/unit/remote/metrics.test.ts +0 -115
  210. package/tests/unit/remote/mockRedisStreamServer.test.ts +0 -104
  211. package/tests/unit/scheduler/DistributedLock.test.ts +0 -274
  212. package/tests/unit/scheduler/SchedulerManager.timeBased.test.ts +0 -95
  213. package/tests/unit/schema/schema-integration.test.ts +0 -426
  214. package/tests/unit/schema/schema.test.ts +0 -580
  215. package/tests/unit/storage/S3StorageProvider.test.ts +0 -567
  216. package/tests/unit/upload/RestUpload.test.ts +0 -267
  217. package/tests/unit/validateEnv.test.ts +0 -82
  218. package/tests/utils/entity-tracker.ts +0 -57
  219. package/tests/utils/index.ts +0 -13
  220. package/tests/utils/test-context.ts +0 -149
@@ -1,171 +0,0 @@
1
- /**
2
- * Quick cursor pagination performance test
3
- * Run with: bun tests/stress/cursor-perf-test.ts
4
- */
5
-
6
- // Load env first
7
- import { file } from 'bun';
8
- const envTestPath = new URL('../../.env.test', import.meta.url).pathname.replace(/^\/([A-Z]:)/, '$1');
9
- const envFile = file(envTestPath);
10
- if (await envFile.exists()) {
11
- const envContent = await envFile.text();
12
- for (const line of envContent.split('\n')) {
13
- const trimmed = line.trim();
14
- if (trimmed && !trimmed.startsWith('#')) {
15
- const [key, ...valueParts] = trimmed.split('=');
16
- if (key) {
17
- const value = valueParts.join('=');
18
- process.env[key.trim()] = value.trim();
19
- }
20
- }
21
- }
22
- }
23
- process.env.LOG_LEVEL = 'warn';
24
-
25
- import { Query } from '../../query/Query';
26
- import db from '../../database';
27
- import { PrepareDatabase, HasValidBaseTable } from '../../database/DatabaseHelper';
28
- import ApplicationLifecycle, { ApplicationPhase } from '../../core/ApplicationLifecycle';
29
- import EntityManager from '../../core/EntityManager';
30
- import { CacheManager } from '../../core/cache';
31
- import { StressUser } from './fixtures/StressTestComponents';
32
- import { ensureComponentsRegistered } from '../utils';
33
-
34
- async function init() {
35
- // Verify database
36
- await db`SELECT 1`;
37
-
38
- // Ensure tables
39
- if (!(await HasValidBaseTable())) {
40
- await PrepareDatabase();
41
- }
42
-
43
- // Set app ready
44
- ApplicationLifecycle.setPhase(ApplicationPhase.DATABASE_READY);
45
- (EntityManager as any).dbReady = true;
46
-
47
- // Init cache
48
- await CacheManager.getInstance().initialize({
49
- enabled: true,
50
- provider: 'memory',
51
- strategy: 'write-through',
52
- defaultTTL: 3600000,
53
- entity: { enabled: true, ttl: 3600000 },
54
- component: { enabled: true, ttl: 1800000 },
55
- query: { enabled: false, ttl: 300000, maxSize: 10000 }
56
- });
57
-
58
- // Ensure StressUser component is registered
59
- await ensureComponentsRegistered(StressUser);
60
- }
61
-
62
- async function main() {
63
- console.log('Initializing...');
64
- await init();
65
-
66
- // Get total count
67
- const count = await new Query().with(StressUser).count();
68
- console.log(`Total StressUser records: ${count}`);
69
-
70
- if (count < 100) {
71
- console.log('\nNot enough records for test.');
72
- console.log('Run: STRESS_RECORD_COUNT=100000 bun test tests/stress --test-name-pattern "indexed"');
73
- console.log('Then run this script again.');
74
- process.exit(0);
75
- }
76
-
77
- const iterations = 10;
78
-
79
- // Test 1: First page with offset 0
80
- console.log('\n=== Offset-based pagination ===');
81
- let times: number[] = [];
82
- for (let i = 0; i < iterations; i++) {
83
- const start = performance.now();
84
- await new Query().with(StressUser).take(100).offset(0).exec();
85
- times.push(performance.now() - start);
86
- }
87
- console.log(`Offset 0: p50=${percentile(times, 50).toFixed(2)}ms, p95=${percentile(times, 95).toFixed(2)}ms`);
88
-
89
- // Test 2: Offset at 50%
90
- const midOffset = Math.floor(count / 2);
91
- times = [];
92
- for (let i = 0; i < iterations; i++) {
93
- const start = performance.now();
94
- await new Query().with(StressUser).take(100).offset(midOffset).exec();
95
- times.push(performance.now() - start);
96
- }
97
- console.log(`Offset ${midOffset.toLocaleString().padStart(7)}: p50=${percentile(times, 50).toFixed(2)}ms, p95=${percentile(times, 95).toFixed(2)}ms`);
98
-
99
- // Test 3: Offset at 90%
100
- const deepOffset = Math.floor(count * 0.9);
101
- times = [];
102
- for (let i = 0; i < iterations; i++) {
103
- const start = performance.now();
104
- await new Query().with(StressUser).take(100).offset(deepOffset).exec();
105
- times.push(performance.now() - start);
106
- }
107
- console.log(`Offset ${deepOffset.toLocaleString().padStart(7)}: p50=${percentile(times, 50).toFixed(2)}ms, p95=${percentile(times, 95).toFixed(2)}ms`);
108
-
109
- // Get cursor IDs
110
- const midResults = await new Query().with(StressUser).take(1).offset(midOffset).exec();
111
- const midId = midResults[0]?.id;
112
- const deepResults = await new Query().with(StressUser).take(1).offset(deepOffset).exec();
113
- const deepId = deepResults[0]?.id;
114
-
115
- if (!midId || !deepId) {
116
- console.log('Could not get cursor IDs');
117
- process.exit(1);
118
- }
119
-
120
- // Cursor tests
121
- console.log('\n=== Cursor-based pagination ===');
122
-
123
- // First page cursor (page 2)
124
- const firstPage = await new Query().with(StressUser).take(100).exec();
125
- const page1LastId = firstPage[firstPage.length - 1]?.id;
126
-
127
- if (page1LastId) {
128
- times = [];
129
- for (let i = 0; i < iterations; i++) {
130
- const start = performance.now();
131
- await new Query().with(StressUser).cursor(page1LastId).take(100).exec();
132
- times.push(performance.now() - start);
133
- }
134
- console.log(`Cursor page 2: p50=${percentile(times, 50).toFixed(2)}ms, p95=${percentile(times, 95).toFixed(2)}ms`);
135
- }
136
-
137
- // Cursor from middle
138
- times = [];
139
- for (let i = 0; i < iterations; i++) {
140
- const start = performance.now();
141
- await new Query().with(StressUser).cursor(midId).take(100).exec();
142
- times.push(performance.now() - start);
143
- }
144
- console.log(`Cursor @ 50%: p50=${percentile(times, 50).toFixed(2)}ms, p95=${percentile(times, 95).toFixed(2)}ms`);
145
-
146
- // Cursor from 90%
147
- times = [];
148
- for (let i = 0; i < iterations; i++) {
149
- const start = performance.now();
150
- await new Query().with(StressUser).cursor(deepId).take(100).exec();
151
- times.push(performance.now() - start);
152
- }
153
- console.log(`Cursor @ 90%: p50=${percentile(times, 50).toFixed(2)}ms, p95=${percentile(times, 95).toFixed(2)}ms`);
154
-
155
- console.log('\n=== Summary ===');
156
- console.log('Offset: O(offset) - gets slower as position increases');
157
- console.log('Cursor: O(1) - consistent speed at any position');
158
-
159
- process.exit(0);
160
- }
161
-
162
- function percentile(arr: number[], p: number): number {
163
- const sorted = [...arr].sort((a, b) => a - b);
164
- const idx = Math.ceil((p / 100) * sorted.length) - 1;
165
- return sorted[Math.max(0, idx)] ?? 0;
166
- }
167
-
168
- main().catch(e => {
169
- console.error(e);
170
- process.exit(1);
171
- });
@@ -1,235 +0,0 @@
1
- /**
2
- * Realistic E-commerce Components for Stress Testing
3
- *
4
- * These components simulate a real-world e-commerce scenario with:
5
- * - Products with metadata
6
- * - Inventory tracking
7
- * - Pricing with discounts
8
- * - Vendor relationships
9
- * - Analytics/metrics
10
- */
11
- import { BaseComponent } from '../../../core/components/BaseComponent';
12
- import { Component, CompData } from '../../../core/components/Decorators';
13
- import { IndexedField } from '../../../core/decorators/IndexedField';
14
-
15
- /**
16
- * Product component - core product information
17
- */
18
- @Component
19
- export class Product extends BaseComponent {
20
- @CompData({ indexed: true })
21
- @IndexedField('btree')
22
- name!: string;
23
-
24
- @CompData({ indexed: true })
25
- @IndexedField('btree')
26
- sku!: string;
27
-
28
- @CompData()
29
- description!: string;
30
-
31
- @CompData({ indexed: true })
32
- @IndexedField('btree')
33
- category!: string;
34
-
35
- @CompData()
36
- @IndexedField('btree')
37
- subcategory!: string;
38
-
39
- @CompData()
40
- tags!: string[];
41
-
42
- @CompData({ indexed: true })
43
- @IndexedField('btree')
44
- status!: 'active' | 'inactive' | 'discontinued' | 'pending';
45
-
46
- @CompData()
47
- @IndexedField('numeric')
48
- rating!: number;
49
-
50
- @CompData()
51
- @IndexedField('numeric')
52
- reviewCount!: number;
53
-
54
- @CompData()
55
- @IndexedField('btree', true)
56
- createdAt!: Date;
57
-
58
- @CompData()
59
- @IndexedField('btree', true)
60
- updatedAt!: Date;
61
- }
62
-
63
- /**
64
- * Inventory component - stock tracking
65
- */
66
- @Component
67
- export class Inventory extends BaseComponent {
68
- @CompData()
69
- @IndexedField('numeric')
70
- quantity!: number;
71
-
72
- @CompData()
73
- @IndexedField('numeric')
74
- reservedQuantity!: number;
75
-
76
- @CompData()
77
- @IndexedField('btree')
78
- warehouseId!: string;
79
-
80
- @CompData()
81
- @IndexedField('numeric')
82
- reorderPoint!: number;
83
-
84
- @CompData()
85
- @IndexedField('numeric')
86
- maxStock!: number;
87
-
88
- @CompData({ indexed: true })
89
- @IndexedField('btree')
90
- stockStatus!: 'in_stock' | 'low_stock' | 'out_of_stock' | 'backordered';
91
-
92
- @CompData()
93
- @IndexedField('btree', true)
94
- lastRestocked!: Date;
95
- }
96
-
97
- /**
98
- * Pricing component - price and discount information
99
- */
100
- @Component
101
- export class Pricing extends BaseComponent {
102
- @CompData()
103
- @IndexedField('numeric')
104
- basePrice!: number;
105
-
106
- @CompData()
107
- @IndexedField('numeric')
108
- salePrice!: number;
109
-
110
- @CompData()
111
- @IndexedField('numeric')
112
- costPrice!: number;
113
-
114
- @CompData()
115
- @IndexedField('btree')
116
- currency!: string;
117
-
118
- @CompData()
119
- @IndexedField('numeric')
120
- discountPercent!: number;
121
-
122
- @CompData({ indexed: true })
123
- @IndexedField('gin')
124
- isOnSale!: boolean;
125
-
126
- @CompData()
127
- @IndexedField('btree', true)
128
- saleStartDate!: Date | null;
129
-
130
- @CompData()
131
- @IndexedField('btree', true)
132
- saleEndDate!: Date | null;
133
-
134
- @CompData()
135
- @IndexedField('numeric')
136
- profit!: number;
137
- }
138
-
139
- /**
140
- * Vendor component - supplier/seller information
141
- */
142
- @Component
143
- export class Vendor extends BaseComponent {
144
- @CompData({ indexed: true })
145
- @IndexedField('btree')
146
- vendorId!: string;
147
-
148
- @CompData({ indexed: true })
149
- @IndexedField('btree')
150
- vendorName!: string;
151
-
152
- @CompData()
153
- @IndexedField('btree')
154
- region!: string;
155
-
156
- @CompData()
157
- @IndexedField('numeric')
158
- vendorRating!: number;
159
-
160
- @CompData({ indexed: true })
161
- @IndexedField('gin')
162
- isVerified!: boolean;
163
-
164
- @CompData()
165
- @IndexedField('numeric')
166
- totalSales!: number;
167
-
168
- @CompData()
169
- @IndexedField('btree')
170
- tier!: 'bronze' | 'silver' | 'gold' | 'platinum';
171
- }
172
-
173
- /**
174
- * ProductMetrics component - analytics data
175
- */
176
- @Component
177
- export class ProductMetrics extends BaseComponent {
178
- @CompData()
179
- @IndexedField('numeric')
180
- viewCount!: number;
181
-
182
- @CompData()
183
- @IndexedField('numeric')
184
- purchaseCount!: number;
185
-
186
- @CompData()
187
- @IndexedField('numeric')
188
- cartAddCount!: number;
189
-
190
- @CompData()
191
- @IndexedField('numeric')
192
- wishlistCount!: number;
193
-
194
- @CompData()
195
- @IndexedField('numeric')
196
- returnCount!: number;
197
-
198
- @CompData()
199
- @IndexedField('numeric')
200
- conversionRate!: number;
201
-
202
- @CompData()
203
- @IndexedField('btree', true)
204
- lastPurchased!: Date | null;
205
-
206
- @CompData()
207
- @IndexedField('btree')
208
- popularityScore!: string;
209
- }
210
-
211
- // Categories for realistic data generation
212
- export const CATEGORIES = [
213
- 'Electronics', 'Clothing', 'Home & Garden', 'Sports', 'Books',
214
- 'Toys', 'Beauty', 'Automotive', 'Food', 'Health'
215
- ] as const;
216
-
217
- export const SUBCATEGORIES: Record<string, string[]> = {
218
- 'Electronics': ['Smartphones', 'Laptops', 'Tablets', 'Accessories', 'Audio'],
219
- 'Clothing': ['Men', 'Women', 'Kids', 'Shoes', 'Accessories'],
220
- 'Home & Garden': ['Furniture', 'Decor', 'Kitchen', 'Garden', 'Bedding'],
221
- 'Sports': ['Fitness', 'Outdoor', 'Team Sports', 'Water Sports', 'Winter'],
222
- 'Books': ['Fiction', 'Non-Fiction', 'Technical', 'Children', 'Comics'],
223
- 'Toys': ['Action Figures', 'Board Games', 'Educational', 'Outdoor', 'Puzzles'],
224
- 'Beauty': ['Skincare', 'Makeup', 'Haircare', 'Fragrance', 'Tools'],
225
- 'Automotive': ['Parts', 'Accessories', 'Tools', 'Care', 'Electronics'],
226
- 'Food': ['Snacks', 'Beverages', 'Organic', 'International', 'Specialty'],
227
- 'Health': ['Vitamins', 'Supplements', 'Personal Care', 'Medical', 'Fitness']
228
- };
229
-
230
- export const REGIONS = ['North', 'South', 'East', 'West', 'Central', 'International'];
231
- export const WAREHOUSES = ['WH-001', 'WH-002', 'WH-003', 'WH-004', 'WH-005'];
232
- export const CURRENCIES = ['USD', 'EUR', 'GBP', 'JPY', 'CAD'];
233
- export const VENDOR_TIERS = ['bronze', 'silver', 'gold', 'platinum'] as const;
234
- export const PRODUCT_STATUSES = ['active', 'inactive', 'discontinued', 'pending'] as const;
235
- export const STOCK_STATUSES = ['in_stock', 'low_stock', 'out_of_stock', 'backordered'] as const;
@@ -1,58 +0,0 @@
1
- /**
2
- * Stress test components with indexed fields for benchmarking
3
- */
4
- import { BaseComponent } from '../../../core/components/BaseComponent';
5
- import { Component, CompData } from '../../../core/components/Decorators';
6
- import { IndexedField } from '../../../core/decorators/IndexedField';
7
-
8
- @Component
9
- export class StressUser extends BaseComponent {
10
- @CompData({ indexed: true })
11
- @IndexedField('btree')
12
- name!: string;
13
-
14
- @CompData({ indexed: true })
15
- @IndexedField('btree')
16
- email!: string;
17
-
18
- @CompData()
19
- @IndexedField('numeric')
20
- age!: number;
21
-
22
- @CompData()
23
- @IndexedField('btree')
24
- status!: string;
25
-
26
- @CompData()
27
- @IndexedField('numeric')
28
- score!: number;
29
-
30
- @CompData()
31
- @IndexedField('btree', true)
32
- createdAt!: Date;
33
- }
34
-
35
- @Component
36
- export class StressProfile extends BaseComponent {
37
- @CompData()
38
- bio!: string;
39
-
40
- @CompData()
41
- avatarUrl!: string;
42
-
43
- @CompData()
44
- @IndexedField('gin')
45
- verified!: boolean;
46
- }
47
-
48
- @Component
49
- export class StressSettings extends BaseComponent {
50
- @CompData()
51
- theme!: string;
52
-
53
- @CompData()
54
- notifications!: boolean;
55
-
56
- @CompData()
57
- language!: string;
58
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Stress testing module exports
3
- */
4
- export { DataSeeder, type SeederOptions, type SeederResult } from './DataSeeder';
5
- export { BenchmarkRunner, type BenchmarkResult, type BenchmarkOptions, type ConcurrentResult } from './BenchmarkRunner';
6
- export { StressTestReporter, type ReportMetadata } from './StressTestReporter';
7
- export { StressUser, StressProfile, StressSettings } from './fixtures/StressTestComponents';