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.
- package/CHANGELOG.md +471 -370
- package/core/BatchLoader.ts +56 -32
- package/core/Entity.ts +93 -1020
- package/core/EntityHookManager.ts +52 -754
- package/core/Logger.ts +10 -0
- package/core/RequestContext.ts +94 -85
- package/core/RequestLoaders.ts +98 -5
- package/core/SchedulerManager.ts +28 -600
- package/core/app/cors.ts +2 -11
- package/core/app/preparedStatementWarmup.ts +9 -49
- package/core/app/requestRouter.ts +9 -8
- package/core/app/restRegistry.ts +8 -0
- package/core/archetype/fieldResolvers.ts +85 -40
- package/core/archetype/relationLoader.ts +135 -92
- package/core/cache/CacheManager.ts +91 -302
- package/core/cache/CompressionUtils.ts +34 -3
- package/core/cache/MemoryCache.ts +40 -37
- package/core/cache/RedisCache.ts +8 -7
- package/core/cache/health.ts +30 -0
- package/core/cache/invalidation.ts +96 -0
- package/core/cache/strategies/writeInvalidate.ts +111 -0
- package/core/cache/strategies/writeThrough.ts +233 -0
- package/core/components/BaseComponent.ts +25 -10
- package/core/components/ComponentRegistry.ts +28 -0
- package/core/decorators/IndexedField.ts +1 -1
- package/core/entity/cacheStrategies.ts +97 -0
- package/core/entity/componentAccess.ts +383 -0
- package/core/entity/finders.ts +202 -0
- package/core/entity/getCacheManager.ts +10 -0
- package/core/entity/pendingOps.ts +72 -0
- package/core/entity/saveEntity.ts +375 -0
- package/core/health.ts +93 -4
- package/core/hooks/dispatcher.ts +439 -0
- package/core/hooks/guards.ts +155 -0
- package/core/hooks/registry.ts +247 -0
- package/core/metadata/definitions/Component.ts +1 -1
- package/core/metadata/index.ts +15 -4
- package/core/middleware/RateLimit.ts +102 -105
- package/core/middleware/RequestId.ts +2 -9
- package/core/middleware/SecurityHeaders.ts +2 -11
- package/core/middleware/headers.ts +28 -0
- package/core/remote/OutboxWorker.ts +213 -183
- package/core/remote/RemoteManager.ts +401 -400
- package/core/remote/StreamConsumer.ts +535 -535
- package/core/remote/types.ts +153 -151
- package/core/requestScope.ts +34 -0
- package/core/scheduler/cronEvaluator.ts +174 -0
- package/core/scheduler/lifecycleHooks.ts +21 -0
- package/core/scheduler/lockCoordinator.ts +27 -0
- package/core/scheduler/metrics.ts +14 -0
- package/core/scheduler/taskRunner.ts +420 -0
- package/core/validateEnv.ts +10 -0
- package/database/DatabaseHelper.ts +128 -101
- package/database/IndexingStrategy.ts +72 -2
- package/database/PreparedStatementCache.ts +8 -2
- package/database/cancellable.ts +35 -22
- package/database/index.ts +29 -3
- package/database/instrumentedDb.ts +141 -141
- package/database/sqlHelpers.ts +3 -1
- package/endpoints/archetypes.ts +2 -8
- package/endpoints/tables.ts +6 -1
- package/gql/index.ts +1 -1
- package/gql/schema/index.ts +15 -4
- package/gql/visitors/ResolverGeneratorVisitor.ts +25 -4
- package/package.json +22 -1
- package/query/CTENode.ts +5 -3
- package/query/ComponentInclusionNode.ts +245 -14
- package/query/OrNode.ts +8 -19
- package/query/Query.ts +208 -79
- package/query/QueryContext.ts +6 -0
- package/query/QueryDAG.ts +7 -2
- package/query/membershipSource.ts +66 -0
- package/storage/LocalStorageProvider.ts +8 -3
- package/studio/dist/assets/index-BMZ67Npg.js +254 -0
- package/studio/dist/assets/index-BpbuYz9g.css +1 -0
- package/studio/{index.html → dist/index.html} +3 -2
- package/swagger/generator.ts +11 -1
- package/upload/UploadManager.ts +8 -6
- package/utils/uuid.ts +40 -10
- package/.claude/scheduled_tasks.lock +0 -1
- package/.claude/settings.local.json +0 -47
- package/.prettierrc +0 -4
- package/.serena/memories/architectural-decision-no-dependency-injection.md +0 -76
- package/.serena/memories/architecture.md +0 -154
- package/.serena/memories/cache-interface-refactoring-2026-01-24.md +0 -165
- package/.serena/memories/code_style_and_conventions.md +0 -76
- package/.serena/memories/project_overview.md +0 -43
- package/.serena/memories/schema-dsl-plan.md +0 -107
- package/.serena/memories/suggested_commands.md +0 -80
- package/.serena/memories/typescript-compilation-status.md +0 -54
- package/.serena/project.yml +0 -114
- package/BunSane.jpg +0 -0
- package/CLAUDE.md +0 -198
- package/TODO.md +0 -2
- package/bun.lock +0 -302
- package/bunfig.toml +0 -10
- package/docs/RFC_APP_REFACTOR.md +0 -248
- package/docs/RFC_REFACTOR_TARGETS.md +0 -251
- package/docs/SCALABILITY_PLAN.md +0 -175
- package/studio/bun.lock +0 -482
- package/studio/package.json +0 -39
- package/studio/postcss.config.js +0 -6
- package/studio/src/components/DataTable.tsx +0 -211
- package/studio/src/components/Layout.tsx +0 -13
- package/studio/src/components/PageContainer.tsx +0 -9
- package/studio/src/components/PageHeader.tsx +0 -13
- package/studio/src/components/SearchBar.tsx +0 -57
- package/studio/src/components/Sidebar.tsx +0 -294
- package/studio/src/components/ui/button.tsx +0 -56
- package/studio/src/components/ui/checkbox.tsx +0 -26
- package/studio/src/components/ui/input.tsx +0 -25
- package/studio/src/hooks/useDataTable.ts +0 -131
- package/studio/src/index.css +0 -36
- package/studio/src/lib/api.ts +0 -186
- package/studio/src/lib/utils.ts +0 -13
- package/studio/src/main.tsx +0 -17
- package/studio/src/pages/ArcheType.tsx +0 -239
- package/studio/src/pages/Components.tsx +0 -124
- package/studio/src/pages/EntityInspector.tsx +0 -302
- package/studio/src/pages/QueryRunner.tsx +0 -246
- package/studio/src/pages/Table.tsx +0 -94
- package/studio/src/pages/Welcome.tsx +0 -241
- package/studio/src/routes.tsx +0 -45
- package/studio/src/store/archeTypeSettings.ts +0 -30
- package/studio/src/store/studio.ts +0 -65
- package/studio/src/utils/columnHelpers.tsx +0 -114
- package/studio/studio-instructions.md +0 -81
- package/studio/tailwind.config.js +0 -77
- package/studio/utils.ts +0 -54
- package/studio/vite.config.js +0 -19
- package/tests/benchmark/BENCHMARK_DATABASES_PLAN.md +0 -338
- package/tests/benchmark/bunfig.toml +0 -9
- package/tests/benchmark/fixtures/EcommerceComponents.ts +0 -283
- package/tests/benchmark/fixtures/EcommerceDataGenerators.ts +0 -301
- package/tests/benchmark/fixtures/RelationTracker.ts +0 -159
- package/tests/benchmark/fixtures/index.ts +0 -6
- package/tests/benchmark/index.ts +0 -22
- package/tests/benchmark/noop-preload.ts +0 -3
- package/tests/benchmark/query-lateral-benchmark.test.ts +0 -372
- package/tests/benchmark/runners/BenchmarkLoader.ts +0 -132
- package/tests/benchmark/runners/index.ts +0 -4
- package/tests/benchmark/scenarios/query-benchmarks.test.ts +0 -465
- package/tests/benchmark/scripts/generate-db.ts +0 -344
- package/tests/benchmark/scripts/run-benchmarks.ts +0 -97
- package/tests/e2e/http.test.ts +0 -130
- package/tests/fixtures/archetypes/TestUserArchetype.ts +0 -21
- package/tests/fixtures/components/TestOrder.ts +0 -23
- package/tests/fixtures/components/TestProduct.ts +0 -23
- package/tests/fixtures/components/TestUser.ts +0 -20
- package/tests/fixtures/components/index.ts +0 -6
- package/tests/graphql/SchemaGeneration.test.ts +0 -90
- package/tests/graphql/builders/ResolverBuilder.test.ts +0 -223
- package/tests/graphql/builders/TypeDefBuilder.test.ts +0 -153
- package/tests/helpers/MockRedisClient.ts +0 -113
- package/tests/helpers/MockRedisStreamServer.ts +0 -448
- package/tests/integration/archetype/ArcheType.persistence.test.ts +0 -241
- package/tests/integration/cache/CacheInvalidation.test.ts +0 -259
- package/tests/integration/entity/Entity.persistence.test.ts +0 -333
- package/tests/integration/entity/Entity.saveTimeout.test.ts +0 -110
- package/tests/integration/loaders/RequestLoaders.abort.test.ts +0 -82
- package/tests/integration/query/Query.abort.test.ts +0 -66
- package/tests/integration/query/Query.complexAnalysis.test.ts +0 -557
- package/tests/integration/query/Query.edgeCases.test.ts +0 -595
- package/tests/integration/query/Query.exec.test.ts +0 -576
- package/tests/integration/query/Query.explainAnalyze.test.ts +0 -233
- package/tests/integration/query/Query.jsonbArray.test.ts +0 -214
- package/tests/integration/remote/dlq.test.ts +0 -175
- package/tests/integration/remote/event-dispatch.test.ts +0 -114
- package/tests/integration/remote/outbox.test.ts +0 -130
- package/tests/integration/remote/rpc.test.ts +0 -177
- package/tests/pglite-setup.ts +0 -62
- package/tests/setup.ts +0 -164
- package/tests/stress/BenchmarkRunner.ts +0 -203
- package/tests/stress/DataSeeder.ts +0 -190
- package/tests/stress/StressTestReporter.ts +0 -229
- package/tests/stress/cursor-perf-test.ts +0 -171
- package/tests/stress/fixtures/RealisticComponents.ts +0 -235
- package/tests/stress/fixtures/StressTestComponents.ts +0 -58
- package/tests/stress/index.ts +0 -7
- package/tests/stress/scenarios/query-benchmarks.test.ts +0 -285
- package/tests/stress/scenarios/realistic-scenarios.test.ts +0 -1081
- package/tests/stress/scenarios/timeout-investigation.test.ts +0 -522
- package/tests/unit/BatchLoader.test.ts +0 -196
- package/tests/unit/archetype/ArcheType.test.ts +0 -107
- package/tests/unit/cache/CacheManager.test.ts +0 -498
- package/tests/unit/cache/MemoryCache.test.ts +0 -260
- package/tests/unit/cache/RedisCache.test.ts +0 -411
- package/tests/unit/database/cancellable.test.ts +0 -81
- package/tests/unit/database/instrumentedDb.test.ts +0 -160
- package/tests/unit/entity/Entity.components.test.ts +0 -317
- package/tests/unit/entity/Entity.drainSideEffects.test.ts +0 -51
- package/tests/unit/entity/Entity.reload.test.ts +0 -63
- package/tests/unit/entity/Entity.requireComponents.test.ts +0 -72
- package/tests/unit/entity/Entity.test.ts +0 -345
- package/tests/unit/gql/depthLimit.test.ts +0 -203
- package/tests/unit/gql/operationMiddleware.test.ts +0 -293
- package/tests/unit/health/Health.test.ts +0 -129
- package/tests/unit/middleware/AccessLog.test.ts +0 -37
- package/tests/unit/middleware/Middleware.test.ts +0 -98
- package/tests/unit/middleware/RequestId.test.ts +0 -54
- package/tests/unit/middleware/SecurityHeaders.test.ts +0 -66
- package/tests/unit/query/FilterBuilder.test.ts +0 -111
- package/tests/unit/query/JsonbArrayBuilder.test.ts +0 -178
- package/tests/unit/query/Query.emptyString.test.ts +0 -69
- package/tests/unit/query/Query.test.ts +0 -310
- package/tests/unit/remote/CircuitBreaker.test.ts +0 -159
- package/tests/unit/remote/RemoteError.test.ts +0 -55
- package/tests/unit/remote/decorators.test.ts +0 -195
- package/tests/unit/remote/metrics.test.ts +0 -115
- package/tests/unit/remote/mockRedisStreamServer.test.ts +0 -104
- package/tests/unit/scheduler/DistributedLock.test.ts +0 -274
- package/tests/unit/scheduler/SchedulerManager.timeBased.test.ts +0 -95
- package/tests/unit/schema/schema-integration.test.ts +0 -426
- package/tests/unit/schema/schema.test.ts +0 -580
- package/tests/unit/storage/S3StorageProvider.test.ts +0 -567
- package/tests/unit/upload/RestUpload.test.ts +0 -267
- package/tests/unit/validateEnv.test.ts +0 -82
- package/tests/utils/entity-tracker.ts +0 -57
- package/tests/utils/index.ts +0 -13
- package/tests/utils/test-context.ts +0 -149
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for BatchLoader TTL behavior and bounded cache
|
|
3
|
-
*/
|
|
4
|
-
import { describe, test, expect, beforeEach } from 'bun:test';
|
|
5
|
-
import { BatchLoader } from '../../core/BatchLoader';
|
|
6
|
-
|
|
7
|
-
describe('BatchLoader', () => {
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
BatchLoader.clearCache();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
describe('getCacheStats()', () => {
|
|
13
|
-
test('returns zero stats when cache is empty', () => {
|
|
14
|
-
const stats = BatchLoader.getCacheStats();
|
|
15
|
-
expect(stats.size).toBe(0);
|
|
16
|
-
expect(stats.entries).toBe(0);
|
|
17
|
-
expect(stats.expired).toBe(0);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('includes memory estimate', () => {
|
|
21
|
-
const stats = BatchLoader.getCacheStats();
|
|
22
|
-
expect(stats.memoryEstimate).toBeDefined();
|
|
23
|
-
expect(typeof stats.memoryEstimate).toBe('string');
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
describe('clearCache()', () => {
|
|
28
|
-
test('clears all cached entries', () => {
|
|
29
|
-
// Access internal cache to set up test data
|
|
30
|
-
const cache = (BatchLoader as any).cache;
|
|
31
|
-
const now = Date.now();
|
|
32
|
-
|
|
33
|
-
// Use the cache's set method to add entries
|
|
34
|
-
cache.set('type1\x00value', 'parent1', {
|
|
35
|
-
ids: ['a', 'b'],
|
|
36
|
-
expiresAt: now + 300000,
|
|
37
|
-
lastAccessed: now
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
expect(BatchLoader.getCacheStats().entries).toBe(1);
|
|
41
|
-
|
|
42
|
-
BatchLoader.clearCache();
|
|
43
|
-
expect(BatchLoader.getCacheStats().entries).toBe(0);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('TTL expiry', () => {
|
|
48
|
-
test('getCacheStats reports expired entries', () => {
|
|
49
|
-
const cache = (BatchLoader as any).cache;
|
|
50
|
-
const now = Date.now();
|
|
51
|
-
|
|
52
|
-
// One fresh entry
|
|
53
|
-
cache.set('type1\x00value', 'parent1', {
|
|
54
|
-
ids: ['a'],
|
|
55
|
-
expiresAt: now + 300000,
|
|
56
|
-
lastAccessed: now
|
|
57
|
-
});
|
|
58
|
-
// One expired entry
|
|
59
|
-
cache.set('type1\x00value', 'parent2', {
|
|
60
|
-
ids: ['b'],
|
|
61
|
-
expiresAt: now - 1000,
|
|
62
|
-
lastAccessed: now - 1000
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const stats = BatchLoader.getCacheStats();
|
|
66
|
-
expect(stats.entries).toBe(2);
|
|
67
|
-
expect(stats.expired).toBe(1);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test('expired entries are counted correctly for multiple type keys', () => {
|
|
71
|
-
const cache = (BatchLoader as any).cache;
|
|
72
|
-
const now = Date.now();
|
|
73
|
-
|
|
74
|
-
// Type 1 entries
|
|
75
|
-
cache.set('type1\x00field', 'p1', {
|
|
76
|
-
ids: ['a'],
|
|
77
|
-
expiresAt: now - 5000,
|
|
78
|
-
lastAccessed: now - 5000
|
|
79
|
-
});
|
|
80
|
-
cache.set('type1\x00field', 'p2', {
|
|
81
|
-
ids: ['b'],
|
|
82
|
-
expiresAt: now + 300000,
|
|
83
|
-
lastAccessed: now
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// Type 2 entry
|
|
87
|
-
cache.set('type2\x00field', 'p3', {
|
|
88
|
-
ids: ['c'],
|
|
89
|
-
expiresAt: now - 1000,
|
|
90
|
-
lastAccessed: now - 1000
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const stats = BatchLoader.getCacheStats();
|
|
94
|
-
expect(stats.size).toBe(2);
|
|
95
|
-
expect(stats.entries).toBe(3);
|
|
96
|
-
expect(stats.expired).toBe(2);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
test('all entries fresh means zero expired', () => {
|
|
100
|
-
const cache = (BatchLoader as any).cache;
|
|
101
|
-
const now = Date.now();
|
|
102
|
-
|
|
103
|
-
cache.set('type\x00field', 'p1', {
|
|
104
|
-
ids: ['a'],
|
|
105
|
-
expiresAt: now + 60000,
|
|
106
|
-
lastAccessed: now
|
|
107
|
-
});
|
|
108
|
-
cache.set('type\x00field', 'p2', {
|
|
109
|
-
ids: ['b'],
|
|
110
|
-
expiresAt: now + 60000,
|
|
111
|
-
lastAccessed: now
|
|
112
|
-
});
|
|
113
|
-
cache.set('type\x00field', 'p3', {
|
|
114
|
-
ids: ['c'],
|
|
115
|
-
expiresAt: now + 60000,
|
|
116
|
-
lastAccessed: now
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
const stats = BatchLoader.getCacheStats();
|
|
120
|
-
expect(stats.entries).toBe(3);
|
|
121
|
-
expect(stats.expired).toBe(0);
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe('pruneExpiredEntries()', () => {
|
|
126
|
-
test('removes expired entries and returns count', () => {
|
|
127
|
-
const cache = (BatchLoader as any).cache;
|
|
128
|
-
const now = Date.now();
|
|
129
|
-
|
|
130
|
-
// Add mix of fresh and expired entries
|
|
131
|
-
cache.set('type\x00field', 'p1', {
|
|
132
|
-
ids: ['a'],
|
|
133
|
-
expiresAt: now - 5000,
|
|
134
|
-
lastAccessed: now - 5000
|
|
135
|
-
});
|
|
136
|
-
cache.set('type\x00field', 'p2', {
|
|
137
|
-
ids: ['b'],
|
|
138
|
-
expiresAt: now + 300000,
|
|
139
|
-
lastAccessed: now
|
|
140
|
-
});
|
|
141
|
-
cache.set('type\x00field', 'p3', {
|
|
142
|
-
ids: ['c'],
|
|
143
|
-
expiresAt: now - 1000,
|
|
144
|
-
lastAccessed: now - 1000
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
expect(BatchLoader.getCacheStats().entries).toBe(3);
|
|
148
|
-
expect(BatchLoader.getCacheStats().expired).toBe(2);
|
|
149
|
-
|
|
150
|
-
const pruned = BatchLoader.pruneExpiredEntries();
|
|
151
|
-
expect(pruned).toBe(2);
|
|
152
|
-
|
|
153
|
-
const statsAfter = BatchLoader.getCacheStats();
|
|
154
|
-
expect(statsAfter.entries).toBe(1);
|
|
155
|
-
expect(statsAfter.expired).toBe(0);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
test('returns 0 when no expired entries', () => {
|
|
159
|
-
const cache = (BatchLoader as any).cache;
|
|
160
|
-
const now = Date.now();
|
|
161
|
-
|
|
162
|
-
cache.set('type\x00field', 'p1', {
|
|
163
|
-
ids: ['a'],
|
|
164
|
-
expiresAt: now + 60000,
|
|
165
|
-
lastAccessed: now
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
const pruned = BatchLoader.pruneExpiredEntries();
|
|
169
|
-
expect(pruned).toBe(0);
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
describe('bounded cache behavior', () => {
|
|
174
|
-
test('memory estimate increases with entries', () => {
|
|
175
|
-
const cache = (BatchLoader as any).cache;
|
|
176
|
-
const now = Date.now();
|
|
177
|
-
|
|
178
|
-
const statsBefore = BatchLoader.getCacheStats();
|
|
179
|
-
|
|
180
|
-
// Add several entries
|
|
181
|
-
for (let i = 0; i < 100; i++) {
|
|
182
|
-
cache.set(`type${i}\x00field`, `parent${i}`, {
|
|
183
|
-
ids: [`id${i}`],
|
|
184
|
-
expiresAt: now + 60000,
|
|
185
|
-
lastAccessed: now
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const statsAfter = BatchLoader.getCacheStats();
|
|
190
|
-
expect(statsAfter.entries).toBe(100);
|
|
191
|
-
|
|
192
|
-
// Memory estimate should reflect the entries
|
|
193
|
-
expect(statsAfter.memoryEstimate).toBeDefined();
|
|
194
|
-
});
|
|
195
|
-
});
|
|
196
|
-
});
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit tests for ArcheType system
|
|
3
|
-
* Tests archetype definition and basic functionality
|
|
4
|
-
*/
|
|
5
|
-
import { describe, test, expect, beforeAll } from 'bun:test';
|
|
6
|
-
import { BaseArcheType, ArcheType, ArcheTypeField } from '../../../core/ArcheType';
|
|
7
|
-
import { TestUser, TestProduct, TestOrder } from '../../fixtures/components';
|
|
8
|
-
import { TestUserArchetype, TestUserWithOrdersArchetype } from '../../fixtures/archetypes/TestUserArchetype';
|
|
9
|
-
import { ensureComponentsRegistered } from '../../utils';
|
|
10
|
-
|
|
11
|
-
describe('ArcheType', () => {
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
await ensureComponentsRegistered(TestUser, TestProduct, TestOrder);
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('ArcheType definition', () => {
|
|
17
|
-
test('archetype class extends BaseArcheType', () => {
|
|
18
|
-
const archetype = new TestUserArchetype();
|
|
19
|
-
expect(archetype).toBeInstanceOf(BaseArcheType);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('archetype has componentMap', () => {
|
|
23
|
-
const archetype = new TestUserArchetype();
|
|
24
|
-
expect(archetype.componentMap).toBeDefined();
|
|
25
|
-
expect(typeof archetype.componentMap).toBe('object');
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test('componentMap contains declared fields', () => {
|
|
29
|
-
const archetype = new TestUserArchetype();
|
|
30
|
-
expect(archetype.componentMap.user).toBeDefined();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('archetype with multiple components', () => {
|
|
34
|
-
const archetype = new TestUserWithOrdersArchetype();
|
|
35
|
-
expect(archetype.componentMap.user).toBeDefined();
|
|
36
|
-
expect(archetype.componentMap.order).toBeDefined();
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
describe('createEntity()', () => {
|
|
41
|
-
test('creates entity with id', () => {
|
|
42
|
-
const archetype = new TestUserArchetype();
|
|
43
|
-
const entity = archetype.createEntity();
|
|
44
|
-
|
|
45
|
-
expect(entity).toBeDefined();
|
|
46
|
-
expect(entity.id).toBeDefined();
|
|
47
|
-
expect(entity.id.length).toBeGreaterThan(0);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('entity is dirty after creation', () => {
|
|
51
|
-
const archetype = new TestUserArchetype();
|
|
52
|
-
const entity = archetype.createEntity();
|
|
53
|
-
|
|
54
|
-
expect((entity as any)._dirty).toBe(true);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
test('entity is not persisted after creation', () => {
|
|
58
|
-
const archetype = new TestUserArchetype();
|
|
59
|
-
const entity = archetype.createEntity();
|
|
60
|
-
|
|
61
|
-
expect(entity._persisted).toBe(false);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
describe('getZodObjectSchema()', () => {
|
|
66
|
-
test('returns zod schema for archetype', () => {
|
|
67
|
-
const archetype = new TestUserArchetype();
|
|
68
|
-
const schema = archetype.getZodObjectSchema();
|
|
69
|
-
|
|
70
|
-
expect(schema).toBeDefined();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
describe('getInputSchema()', () => {
|
|
75
|
-
test('returns input schema for archetype', () => {
|
|
76
|
-
const archetype = new TestUserArchetype();
|
|
77
|
-
const schema = archetype.getInputSchema();
|
|
78
|
-
|
|
79
|
-
expect(schema).toBeDefined();
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
describe('getComponentsToLoad()', () => {
|
|
84
|
-
test('returns non-empty components array', () => {
|
|
85
|
-
const archetype = new TestUserArchetype();
|
|
86
|
-
const components = (archetype as any).getComponentsToLoad();
|
|
87
|
-
|
|
88
|
-
expect(Array.isArray(components)).toBe(true);
|
|
89
|
-
expect(components.length).toBeGreaterThan(0);
|
|
90
|
-
expect(components).toContain(TestUser);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
describe('withValidation()', () => {
|
|
95
|
-
test('returns a Zod schema with validations applied', () => {
|
|
96
|
-
const archetype = new TestUserArchetype();
|
|
97
|
-
const schema = archetype.withValidation({
|
|
98
|
-
user: { name: 'Valid', email: 'valid@test.com', age: 25 }
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
expect(schema).toBeDefined();
|
|
102
|
-
// Should return a Zod schema with a shape property
|
|
103
|
-
expect(schema.shape).toBeDefined();
|
|
104
|
-
expect(typeof schema.safeParse).toBe('function');
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
});
|