@indexeddb-orm/idb-orm 0.0.1

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 (216) hide show
  1. package/.vscode/extensions.json +5 -0
  2. package/README.md +1280 -0
  3. package/angular-demo-app/README.md +84 -0
  4. package/angular-demo-app/angular.json +109 -0
  5. package/angular-demo-app/package-lock.json +14215 -0
  6. package/angular-demo-app/package.json +41 -0
  7. package/angular-demo-app/src/app/app.component.ts +481 -0
  8. package/angular-demo-app/src/app/app.routes.ts +8 -0
  9. package/angular-demo-app/src/app/components/actions.component.ts +202 -0
  10. package/angular-demo-app/src/app/components/cloud-sync-demo.component.ts +296 -0
  11. package/angular-demo-app/src/app/components/live-query-demo.component.ts +307 -0
  12. package/angular-demo-app/src/app/components/main-info.component.ts +148 -0
  13. package/angular-demo-app/src/app/components/posts-live-query-demo.component.ts +336 -0
  14. package/angular-demo-app/src/app/components/typescript-demo.component.ts +268 -0
  15. package/angular-demo-app/src/entities/post-tag.entity.ts +25 -0
  16. package/angular-demo-app/src/entities/post.entity.ts +49 -0
  17. package/angular-demo-app/src/entities/profile.entity.ts +42 -0
  18. package/angular-demo-app/src/entities/tag.entity.ts +36 -0
  19. package/angular-demo-app/src/entities/user.entity.ts +59 -0
  20. package/angular-demo-app/src/favicon.ico +1 -0
  21. package/angular-demo-app/src/index.html +16 -0
  22. package/angular-demo-app/src/main.ts +13 -0
  23. package/angular-demo-app/src/services/app-logic.service.ts +449 -0
  24. package/angular-demo-app/src/services/cloud-sync.service.ts +95 -0
  25. package/angular-demo-app/src/services/database.service.ts +26 -0
  26. package/angular-demo-app/src/services/live-query.service.ts +63 -0
  27. package/angular-demo-app/src/services/posts-live-query.service.ts +86 -0
  28. package/angular-demo-app/src/services/typescript-demo.service.ts +59 -0
  29. package/angular-demo-app/src/styles.scss +50 -0
  30. package/angular-demo-app/tsconfig.app.json +13 -0
  31. package/angular-demo-app/tsconfig.json +34 -0
  32. package/angular-demo-app/tsconfig.spec.json +13 -0
  33. package/dist/Database.d.ts +206 -0
  34. package/dist/Database.js +288 -0
  35. package/dist/decorators/Column.d.ts +79 -0
  36. package/dist/decorators/Column.js +236 -0
  37. package/dist/decorators/Entity.d.ts +32 -0
  38. package/dist/decorators/Entity.js +44 -0
  39. package/dist/decorators/Relation.d.ts +70 -0
  40. package/dist/decorators/Relation.js +120 -0
  41. package/dist/decorators/index.d.ts +3 -0
  42. package/dist/decorators/index.js +3 -0
  43. package/dist/errors/ValidationError.d.ts +4 -0
  44. package/dist/errors/ValidationError.js +8 -0
  45. package/dist/index.d.ts +8 -0
  46. package/dist/index.js +7 -0
  47. package/dist/metadata/Column.d.ts +8 -0
  48. package/dist/metadata/Column.js +44 -0
  49. package/dist/metadata/Entity.d.ts +11 -0
  50. package/dist/metadata/Entity.js +21 -0
  51. package/dist/metadata/Relation.d.ts +20 -0
  52. package/dist/metadata/Relation.js +74 -0
  53. package/dist/metadata/index.d.ts +3 -0
  54. package/dist/metadata/index.js +3 -0
  55. package/dist/services/AggregationService.d.ts +38 -0
  56. package/dist/services/AggregationService.js +229 -0
  57. package/dist/services/BaseEntity.d.ts +32 -0
  58. package/dist/services/BaseEntity.js +62 -0
  59. package/dist/services/CloudSyncService.d.ts +100 -0
  60. package/dist/services/CloudSyncService.js +196 -0
  61. package/dist/services/DecoratorUtils.d.ts +12 -0
  62. package/dist/services/DecoratorUtils.js +10 -0
  63. package/dist/services/EntityFactory.d.ts +25 -0
  64. package/dist/services/EntityFactory.js +27 -0
  65. package/dist/services/EntityRegistry.d.ts +61 -0
  66. package/dist/services/EntityRegistry.js +56 -0
  67. package/dist/services/EntitySchema.d.ts +56 -0
  68. package/dist/services/EntitySchema.js +125 -0
  69. package/dist/services/MigrationManager.d.ts +70 -0
  70. package/dist/services/MigrationManager.js +181 -0
  71. package/dist/services/RelationLoader.d.ts +66 -0
  72. package/dist/services/RelationLoader.js +310 -0
  73. package/dist/services/SchemaBuilder.d.ts +68 -0
  74. package/dist/services/SchemaBuilder.js +191 -0
  75. package/dist/services/index.d.ts +7 -0
  76. package/dist/services/index.js +7 -0
  77. package/dist/types.d.ts +152 -0
  78. package/dist/types.js +1 -0
  79. package/dist/utils/logger.d.ts +12 -0
  80. package/dist/utils/logger.js +16 -0
  81. package/eslint.config.js +49 -0
  82. package/homepage/favicon.svg +36 -0
  83. package/homepage/index.html +1725 -0
  84. package/package.json +78 -0
  85. package/react-demo-app/README.md +61 -0
  86. package/react-demo-app/eslint.config.js +60 -0
  87. package/react-demo-app/index.html +13 -0
  88. package/react-demo-app/package-lock.json +4955 -0
  89. package/react-demo-app/package.json +39 -0
  90. package/react-demo-app/src/App.tsx +172 -0
  91. package/react-demo-app/src/assets/react.svg +1 -0
  92. package/react-demo-app/src/components/Actions.tsx +171 -0
  93. package/react-demo-app/src/components/CloudSyncDemo.tsx +191 -0
  94. package/react-demo-app/src/components/LiveQueryDemo.tsx +122 -0
  95. package/react-demo-app/src/components/MainInfo.tsx +75 -0
  96. package/react-demo-app/src/components/PostsLiveQueryDemo.tsx +185 -0
  97. package/react-demo-app/src/components/TypeScriptDemo.tsx +190 -0
  98. package/react-demo-app/src/database/Database.ts +30 -0
  99. package/react-demo-app/src/entities/Post.ts +48 -0
  100. package/react-demo-app/src/entities/PostTag.ts +26 -0
  101. package/react-demo-app/src/entities/Profile.ts +41 -0
  102. package/react-demo-app/src/entities/Tag.ts +35 -0
  103. package/react-demo-app/src/entities/User.ts +61 -0
  104. package/react-demo-app/src/hooks/useAppLogic.ts +565 -0
  105. package/react-demo-app/src/hooks/useCloudSyncDemo.ts +84 -0
  106. package/react-demo-app/src/hooks/useLiveQueryDemo.ts +68 -0
  107. package/react-demo-app/src/hooks/usePostsLiveQueryDemo.ts +64 -0
  108. package/react-demo-app/src/hooks/useTypeScriptDemo.ts +43 -0
  109. package/react-demo-app/src/index.css +26 -0
  110. package/react-demo-app/src/main.tsx +18 -0
  111. package/react-demo-app/src/migrations/001-add-user-email-index.ts +17 -0
  112. package/react-demo-app/src/migrations/002-add-post-category.ts +37 -0
  113. package/react-demo-app/src/migrations/index.ts +8 -0
  114. package/react-demo-app/src/vite-env.d.ts +1 -0
  115. package/react-demo-app/tsconfig.app.json +22 -0
  116. package/react-demo-app/tsconfig.json +6 -0
  117. package/react-demo-app/vite.config.ts +10 -0
  118. package/src/Database.ts +405 -0
  119. package/src/errors/ValidationError.ts +9 -0
  120. package/src/index.ts +13 -0
  121. package/src/metadata/Column.ts +74 -0
  122. package/src/metadata/Entity.ts +42 -0
  123. package/src/metadata/Relation.ts +121 -0
  124. package/src/metadata/index.ts +5 -0
  125. package/src/services/AggregationService.ts +348 -0
  126. package/src/services/BaseEntity.ts +77 -0
  127. package/src/services/CloudSyncService.ts +248 -0
  128. package/src/services/EntityFactory.ts +35 -0
  129. package/src/services/EntityRegistry.ts +109 -0
  130. package/src/services/EntitySchema.ts +154 -0
  131. package/src/services/MigrationManager.ts +276 -0
  132. package/src/services/RelationLoader.ts +532 -0
  133. package/src/services/SchemaBuilder.ts +237 -0
  134. package/src/services/index.ts +7 -0
  135. package/src/types.d.ts +1 -0
  136. package/src/types.ts +169 -0
  137. package/src/utils/logger.ts +40 -0
  138. package/svelte-demo-app/README.md +61 -0
  139. package/svelte-demo-app/package-lock.json +3000 -0
  140. package/svelte-demo-app/package.json +30 -0
  141. package/svelte-demo-app/src/app.d.ts +12 -0
  142. package/svelte-demo-app/src/app.html +13 -0
  143. package/svelte-demo-app/src/components/Actions.svelte +121 -0
  144. package/svelte-demo-app/src/components/CloudSyncDemo.svelte +333 -0
  145. package/svelte-demo-app/src/components/LiveQueryDemo.svelte +191 -0
  146. package/svelte-demo-app/src/components/MainInfo.svelte +133 -0
  147. package/svelte-demo-app/src/components/PostsLiveQueryDemo.svelte +330 -0
  148. package/svelte-demo-app/src/components/TypeScriptDemo.svelte +251 -0
  149. package/svelte-demo-app/src/database/Database.ts +29 -0
  150. package/svelte-demo-app/src/entities/Post.ts +46 -0
  151. package/svelte-demo-app/src/entities/PostTag.ts +22 -0
  152. package/svelte-demo-app/src/entities/Profile.ts +39 -0
  153. package/svelte-demo-app/src/entities/Tag.ts +33 -0
  154. package/svelte-demo-app/src/entities/User.ts +62 -0
  155. package/svelte-demo-app/src/lib/database/Database.ts +30 -0
  156. package/svelte-demo-app/src/lib/entities/Post.ts +47 -0
  157. package/svelte-demo-app/src/lib/entities/PostTag.ts +23 -0
  158. package/svelte-demo-app/src/lib/entities/Profile.ts +40 -0
  159. package/svelte-demo-app/src/lib/entities/Tag.ts +34 -0
  160. package/svelte-demo-app/src/lib/entities/User.ts +59 -0
  161. package/svelte-demo-app/src/lib/index.ts +7 -0
  162. package/svelte-demo-app/src/lib/migrations/001-add-user-email-index.ts +17 -0
  163. package/svelte-demo-app/src/lib/migrations/002-add-post-category.ts +37 -0
  164. package/svelte-demo-app/src/lib/migrations/index.ts +8 -0
  165. package/svelte-demo-app/src/migrations/001-add-user-email-index.ts +17 -0
  166. package/svelte-demo-app/src/migrations/002-add-post-category.ts +37 -0
  167. package/svelte-demo-app/src/migrations/index.ts +8 -0
  168. package/svelte-demo-app/src/routes/+layout.js +3 -0
  169. package/svelte-demo-app/src/routes/+layout.svelte +228 -0
  170. package/svelte-demo-app/src/routes/+page.js +3 -0
  171. package/svelte-demo-app/src/routes/+page.svelte +1305 -0
  172. package/svelte-demo-app/src/stores/appStore.js +603 -0
  173. package/svelte-demo-app/svelte.config.js +18 -0
  174. package/svelte-demo-app/tsconfig.json +14 -0
  175. package/svelte-demo-app/vite.config.ts +6 -0
  176. package/tests/aggregation.e2e.test.ts +87 -0
  177. package/tests/base-entity.e2e.test.ts +47 -0
  178. package/tests/database-api.e2e.test.ts +177 -0
  179. package/tests/decorators.e2e.test.ts +40 -0
  180. package/tests/entity-schema.e2e.test.ts +58 -0
  181. package/tests/relation-loader-table-names.test.ts +192 -0
  182. package/tests/relations.e2e.test.ts +178 -0
  183. package/tests/zod-runtime.e2e.test.ts +69 -0
  184. package/tsconfig.json +21 -0
  185. package/vitest.config.ts +21 -0
  186. package/vitest.setup.ts +27 -0
  187. package/vue-demo-app/README.md +61 -0
  188. package/vue-demo-app/index.html +13 -0
  189. package/vue-demo-app/package-lock.json +1537 -0
  190. package/vue-demo-app/package.json +27 -0
  191. package/vue-demo-app/src/App.vue +100 -0
  192. package/vue-demo-app/src/components/Actions.vue +135 -0
  193. package/vue-demo-app/src/components/CloudSyncDemo.vue +139 -0
  194. package/vue-demo-app/src/components/LiveQueryDemo.vue +122 -0
  195. package/vue-demo-app/src/components/MainInfo.vue +80 -0
  196. package/vue-demo-app/src/components/PostsLiveQueryDemo.vue +136 -0
  197. package/vue-demo-app/src/components/TypeScriptDemo.vue +133 -0
  198. package/vue-demo-app/src/database/Database.ts +29 -0
  199. package/vue-demo-app/src/entities/Post.ts +48 -0
  200. package/vue-demo-app/src/entities/PostTag.ts +24 -0
  201. package/vue-demo-app/src/entities/Profile.ts +41 -0
  202. package/vue-demo-app/src/entities/Tag.ts +35 -0
  203. package/vue-demo-app/src/entities/User.ts +61 -0
  204. package/vue-demo-app/src/main.ts +29 -0
  205. package/vue-demo-app/src/migrations/001-add-user-email-index.ts +23 -0
  206. package/vue-demo-app/src/migrations/002-add-post-category.ts +46 -0
  207. package/vue-demo-app/src/migrations/index.ts +14 -0
  208. package/vue-demo-app/src/services/useAppLogic.ts +565 -0
  209. package/vue-demo-app/src/services/useCloudSyncDemo.ts +84 -0
  210. package/vue-demo-app/src/services/useLiveQueryDemo.ts +82 -0
  211. package/vue-demo-app/src/services/usePostsLiveQueryDemo.ts +77 -0
  212. package/vue-demo-app/src/services/useTypeScriptDemo.ts +56 -0
  213. package/vue-demo-app/src/vite-env.d.ts +1 -0
  214. package/vue-demo-app/tsconfig.json +25 -0
  215. package/vue-demo-app/tsconfig.node.json +10 -0
  216. package/vue-demo-app/vite.config.ts +16 -0
package/README.md ADDED
@@ -0,0 +1,1280 @@
1
+ # Dexie ORM
2
+
3
+ TypeScript ORM wrapper for indexed-db with Zod runtime validation, built on the top of dexie.js.
4
+
5
+ **[View Homepage](https://idb-orm.com)** - Interactive documentation and examples
6
+
7
+ ## Features
8
+
9
+ - **TypeScript Support** - Full type safety with generics
10
+ - **Zod Validation** - Runtime validation with Zod schemas
11
+ - **Config-based entities** - Define entities with a simple `defineEntity(...)` API
12
+
13
+ - **Dexie Compatibility** - All Dexie.js operations supported
14
+ - **Clean API** - Simple and intuitive API design
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install idb-orm dexie zod
20
+ ```
21
+
22
+ ## Important Notes
23
+
24
+ ### Dexie Dependencies
25
+ This library includes Dexie.js internally. To ensure that `liveQuery` works properly, you need to configure Vite to dedupe Dexie.
26
+
27
+ ```typescript
28
+ // In your vite.config.ts, add:
29
+ import { defineConfig } from 'vite';
30
+
31
+ export default defineConfig({
32
+ resolve: {
33
+ dedupe: ['dexie'],
34
+ },
35
+ // ... other config
36
+ });
37
+
38
+ // This ensures liveQuery works correctly
39
+ // Without dedupe, liveQuery may not function properly
40
+ ```
41
+
42
+ ### Built on Dexie.js
43
+ This library is built on top of [Dexie.js](https://dexie.org) - a powerful wrapper for IndexedDB. All Dexie.js methods and features are available through the `db` object.
44
+
45
+ ```typescript
46
+ // All Dexie.js methods work with our library
47
+ const db = await Database.createDatabase({...});
48
+
49
+ // Direct Dexie.js operations
50
+ await db.transaction('rw', db.users, async () => {
51
+ await db.users.add({ name: 'John', email: 'john@example.com' });
52
+ });
53
+
54
+ // Dexie.js query methods
55
+ const users = await db.users
56
+ .where('age')
57
+ .above(18)
58
+ .and(user => user.name.startsWith('J'))
59
+ .toArray();
60
+
61
+ // Dexie.js liveQuery (reactive queries)
62
+ import { liveQuery } from 'dexie';
63
+ const observableUsers = liveQuery(() =>
64
+ db.users.where('active').equals(true).toArray()
65
+ );
66
+ ```
67
+
68
+ **Benefits:** You get all the power of Dexie.js plus our ORM features like entity validation, relations, and cloud sync.
69
+
70
+ ### Index Requirements for Queries
71
+ **Critical:** When searching by any field, you MUST create an index on that field. Queries without proper indexes will fail.
72
+
73
+ ```typescript
74
+ const UserSchema = z.object({
75
+ id: z.number(),
76
+ name: z.string(),
77
+ email: z.string(),
78
+ age: z.number()
79
+ });
80
+
81
+ defineEntity(User, {
82
+ schema: UserSchema,
83
+ indexes: [
84
+ { key: 'email' }, // Required for email queries
85
+ { key: 'age' }, // Required for age queries
86
+ { key: 'name' } // Required for name queries
87
+ ]
88
+ });
89
+ ```
90
+
91
+ ### Compound Indexes for Complex Queries
92
+ For queries involving multiple fields, you need compound indexes. Single field indexes won't work for multi-field queries.
93
+
94
+ ```typescript
95
+ defineEntity(Post, {
96
+ schema: PostSchema,
97
+ compoundIndexes: [
98
+ { key: ['category', 'status'] },
99
+ { key: ['authorId', 'createdAt'] }
100
+ ]
101
+ });
102
+ ```
103
+
104
+ ## Usage
105
+
106
+ ### 1. Define Entities
107
+
108
+ ```typescript
109
+ import { BaseEntity, defineEntity } from 'idb-orm';
110
+ import { z } from 'zod';
111
+
112
+ // Zod schema for validation
113
+ const UserSchema = z.object({
114
+ id: z.number().optional(),
115
+ name: z.string().min(2, 'Name must be at least 2 characters'),
116
+ email: z.string().email('Invalid email format'),
117
+ age: z.number().min(18, 'Must be at least 18 years old'),
118
+ createdAt: z.number(),
119
+ updatedAt: z.number(),
120
+ isActive: z.boolean().default(true),
121
+ tags: z.array(z.string()).default([]),
122
+ metadata: z.record(z.string(), z.unknown()).default({}),
123
+ });
124
+
125
+ export class UserEntity extends BaseEntity<number> {
126
+ name!: string;
127
+ email!: string;
128
+ age!: number;
129
+ createdAt!: number;
130
+ updatedAt!: number;
131
+ isActive!: boolean;
132
+ tags!: string[];
133
+ metadata!: Record<string, unknown>;
134
+ }
135
+
136
+ defineEntity(UserEntity, {
137
+ tableName: 'users',
138
+ schema: UserSchema,
139
+ columns: {
140
+ name: { required: true, indexed: true },
141
+ email: { required: true, unique: true },
142
+ age: { indexed: true },
143
+ createdAt: { indexed: true },
144
+ updatedAt: { indexed: true },
145
+ isActive: { indexed: true },
146
+ tags: {},
147
+ metadata: {},
148
+ },
149
+ // Example relations (optional)
150
+ // relations: {
151
+ // posts: { type: 'one-to-many', target: PostEntity, foreignKey: 'authorId' },
152
+ // },
153
+ });
154
+ ```
155
+
156
+ ### 2. Create Database
157
+
158
+ ```typescript
159
+ import { Database } from 'idb-orm';
160
+ import { UserEntity } from './entities/User';
161
+ import { PostEntity } from './entities/Post';
162
+
163
+ export const db = Database.createDatabase({
164
+ name: 'MyApp',
165
+ version: 1,
166
+ entities: [UserEntity, PostEntity],
167
+ config: {
168
+ onSchemaChangeStrategy: 'all',
169
+ cloudSync: {
170
+ databaseUrl: 'https://your-sync-server.com',
171
+ enableOfflineQueue: true,
172
+ syncInterval: 30000
173
+ }
174
+ },
175
+ });
176
+ ```
177
+
178
+ ### Database Configuration Options
179
+
180
+ The `createDatabase()` method accepts the following configuration options:
181
+
182
+ #### Basic Configuration
183
+ ```typescript
184
+ const db = Database.createDatabase({
185
+ name: string, // Required: Database name
186
+ version: number, // Required: Schema version
187
+ entities: EntityConstructor[], // Required: Array of entity classes
188
+ config?: { // Optional: Additional configuration
189
+ // Schema change handling
190
+ onSchemaChangeStrategy?: 'selective' | 'all',
191
+
192
+ // Migrations list
193
+ migrations?: Migration[],
194
+
195
+ // Cloud synchronization
196
+ cloudSync?: CloudSyncConfig
197
+ }
198
+ });
199
+ ```
200
+
201
+ #### Schema Change Strategy Options
202
+
203
+ **`onSchemaChangeStrategy`** - Defines how to handle database schema changes:
204
+
205
+ - **`'selective'`** (recommended for production): Only resets tables that have schema changes, preserving data in unchanged tables
206
+ - **`'all'`**: Resets the entire database when any schema change is detected, useful for development
207
+
208
+ #### Cloud Sync Configuration Options
209
+
210
+ **`CloudSyncConfig`** - Configuration for cloud synchronization:
211
+
212
+ ```typescript
213
+ interface CloudSyncConfig {
214
+ databaseUrl: string; // Required: Base URL of the sync server
215
+ enableOfflineSupport?: boolean; // Optional: Queue changes when offline (default: false)
216
+ syncInterval?: number; // Optional: Auto-sync interval in milliseconds (default: 30000)
217
+ // Note: Authentication is handled by Dexie Cloud addon configuration
218
+ }
219
+ ```
220
+
221
+ **Cloud Sync Options:**
222
+ - **`databaseUrl`** (required): The base URL of your synchronization server
223
+ - **`enableOfflineSupport`** (optional): If `true`, changes are queued when offline and synced when connection is restored
224
+ - **`syncInterval`** (optional): Automatic synchronization interval in milliseconds (default: 30 seconds)
225
+
226
+ **Authentication Note:**
227
+ Authentication for cloud sync is handled by the Dexie Cloud addon configuration, not through this interface. You need to configure authentication separately when setting up the Dexie Cloud addon.
228
+
229
+ #### Schema Change Strategy Examples
230
+ ```typescript
231
+ // Option 1: Reset only changed tables (recommended for production)
232
+ const db = Database.createDatabase({
233
+ name: 'MyApp',
234
+ version: 1,
235
+ entities: [UserEntity, PostEntity],
236
+ config: {
237
+ onSchemaChangeStrategy: 'selective' // Only reset tables that changed
238
+ }
239
+ });
240
+
241
+ // Option 2: Reset entire database on schema changes
242
+ const db = Database.createDatabase({
243
+ name: 'MyApp',
244
+ version: 1,
245
+ entities: [UserEntity, PostEntity],
246
+ config: {
247
+ onSchemaChangeStrategy: 'all' // Reset all data when schema changes
248
+ }
249
+ });
250
+ ```
251
+
252
+ #### Migration Configuration
253
+ ```typescript
254
+ const db = Database.createDatabase({
255
+ name: 'MyApp',
256
+ version: 2,
257
+ entities: [UserEntity, PostEntity],
258
+ config: {
259
+ migrations: [
260
+ {
261
+ version: 2,
262
+ name: 'Add fullName field',
263
+ up: async (db) => {
264
+ await db.getRepository(UserEntity).toCollection().modify(user => {
265
+ user.fullName = `${user.firstName} ${user.lastName}`;
266
+ });
267
+ },
268
+ down: async (db) => {
269
+ await db.getRepository(UserEntity).toCollection().modify(user => {
270
+ delete user.fullName;
271
+ });
272
+ }
273
+ }
274
+ ]
275
+ }
276
+ });
277
+ ```
278
+
279
+ #### Cloud Synchronization Configuration
280
+ ```typescript
281
+ const db = Database.createDatabase({
282
+ name: 'MyApp',
283
+ version: 1,
284
+ entities: [UserEntity, PostEntity],
285
+ config: {
286
+ cloudSync: {
287
+ databaseUrl: 'https://your-sync-server.com', // Required: Sync server URL
288
+ enableOfflineSupport: true, // Optional: Queue changes when offline
289
+ syncInterval: 30000 // Optional: Auto-sync interval (30s)
290
+ }
291
+ }
292
+ });
293
+ ```
294
+
295
+ #### Complete Configuration Example
296
+ ```typescript
297
+ const db = Database.createDatabase({
298
+ name: 'MyApp',
299
+ version: 3,
300
+ entities: [UserEntity, PostEntity, CommentEntity],
301
+ config: {
302
+ // Handle schema changes by resetting only affected tables
303
+ onSchemaChangeStrategy: 'selective',
304
+
305
+ // Define migrations for version upgrades
306
+ migrations: [
307
+ {
308
+ version: 2,
309
+ name: 'Add user profiles',
310
+ up: async (db) => {
311
+ // Migration logic for version 2
312
+ }
313
+ },
314
+ {
315
+ version: 3,
316
+ name: 'Add comment system',
317
+ up: async (db) => {
318
+ // Migration logic for version 3
319
+ }
320
+ }
321
+ ],
322
+
323
+ // Enable cloud synchronization
324
+ cloudSync: {
325
+ databaseUrl: 'https://api.myapp.com/sync',
326
+ enableOfflineSupport: true,
327
+ syncInterval: 60000 // Sync every minute
328
+ }
329
+ }
330
+ });
331
+ ```
332
+
333
+ ### 3. Basic CRUD Operations
334
+
335
+ ```typescript
336
+ // Prefer explicit repositories for strict typing
337
+ const users = await db.getRepository(UserEntity).toArray(); // Type: UserEntity[]
338
+ const posts = await db.getRepository(PostEntity).toArray(); // Type: PostEntity[]
339
+
340
+ // Create new entity with validation in one call
341
+ import { newEntity } from 'idb-orm';
342
+
343
+ const newUser = newEntity(UserEntity, {
344
+ name: 'John Doe',
345
+ email: 'john@example.com',
346
+ age: 25,
347
+ createdAt: Date.now(),
348
+ updatedAt: Date.now(),
349
+ tags: ['developer'],
350
+ metadata: { source: 'manual' },
351
+ });
352
+
353
+ // Save to database
354
+ await db.getRepository(UserEntity).add(newUser);
355
+
356
+ // Query with full Dexie.js API
357
+ const activeUsers = await db.getRepository(UserEntity)
358
+ .where('isActive')
359
+ .equals(true)
360
+ .toArray();
361
+ ```
362
+
363
+ ### 4. Entity Relations
364
+
365
+ ```typescript
366
+ // Define entities with relations
367
+ defineEntity(UserEntity, {
368
+ tableName: 'users',
369
+ schema: UserSchema,
370
+ columns: { /* ... */ },
371
+ relations: {
372
+ posts: {
373
+ type: 'one-to-many',
374
+ target: PostEntity,
375
+ foreignKey: 'authorId'
376
+ },
377
+ profile: {
378
+ type: 'one-to-one',
379
+ target: ProfileEntity,
380
+ foreignKey: 'userId'
381
+ }
382
+ }
383
+ });
384
+
385
+ defineEntity(PostEntity, {
386
+ tableName: 'posts',
387
+ schema: PostSchema,
388
+ columns: { /* ... */ },
389
+ relations: {
390
+ author: {
391
+ type: 'many-to-one',
392
+ target: UserEntity,
393
+ foreignKey: 'authorId'
394
+ },
395
+ tags: {
396
+ type: 'many-to-many',
397
+ target: TagEntity,
398
+ joinTable: 'post_tags'
399
+ }
400
+ }
401
+ });
402
+
403
+ // Load relations
404
+ const userWithPosts = await db.loadRelations({
405
+ entity: user,
406
+ entityClass: UserEntity,
407
+ relationNames: ['posts', 'profile']
408
+ });
409
+
410
+ // Load specific relation
411
+ const userPosts = await db.loadRelationByName({
412
+ entity: user,
413
+ entityClass: UserEntity,
414
+ relationName: 'posts'
415
+ });
416
+
417
+ // Save entity with all its relations
418
+ const savedUser = await db.saveWithRelations({
419
+ entity: user,
420
+ entityClass: UserEntity
421
+ });
422
+
423
+ // Delete entity with cascade handling for relations
424
+ await db.deleteWithRelations({
425
+ entity: user,
426
+ entityClass: UserEntity
427
+ });
428
+ ```
429
+
430
+ ### 5. Reactive Queries with liveQuery
431
+
432
+ Use Dexie's `liveQuery` for reactive data that automatically updates when the database changes. Works with all major frameworks:
433
+
434
+ #### React Example
435
+ ```typescript
436
+ import { liveQuery } from 'dexie';
437
+ import { useObservable } from 'dexie-react-hooks';
438
+ import { Database } from 'indexed-db-orm';
439
+ import { User } from './entities/User';
440
+
441
+ function UserList() {
442
+ const users = useObservable(
443
+ liveQuery(() => {
444
+ const userRepo = db.getRepository(User);
445
+ return userRepo.where('active').equals(true).toArray();
446
+ })
447
+ );
448
+
449
+ return (
450
+ <div>
451
+ {users?.map(user => (
452
+ <div key={user.id}>{user.name}</div>
453
+ ))}
454
+ </div>
455
+ );
456
+ }
457
+ ```
458
+
459
+ #### Vue Example
460
+ ```typescript
461
+ import { liveQuery } from 'dexie';
462
+ import { ref, onMounted, onUnmounted } from 'vue';
463
+ import { Database } from 'indexed-db-orm';
464
+ import { User } from './entities/User';
465
+
466
+ export default {
467
+ setup() {
468
+ const users = ref<User[]>([]);
469
+ let subscription;
470
+
471
+ onMounted(() => {
472
+ subscription = liveQuery(() => {
473
+ const userRepo = db.getRepository(User);
474
+ return userRepo.where('active').equals(true).toArray();
475
+ }).subscribe(result => {
476
+ users.value = result;
477
+ });
478
+ });
479
+
480
+ onUnmounted(() => {
481
+ subscription?.unsubscribe();
482
+ });
483
+
484
+ return { users };
485
+ }
486
+ };
487
+ ```
488
+
489
+ #### Svelte Example
490
+ ```typescript
491
+ import { liveQuery } from 'dexie';
492
+ import { onMount, onDestroy } from 'svelte';
493
+ import { Database } from 'indexed-db-orm';
494
+ import { User } from './entities/User';
495
+
496
+ let users: User[] = [];
497
+ let subscription;
498
+
499
+ onMount(() => {
500
+ subscription = liveQuery(() => {
501
+ const userRepo = db.getRepository(User);
502
+ return userRepo.where('active').equals(true).toArray();
503
+ }).subscribe(result => {
504
+ users = result;
505
+ });
506
+ });
507
+
508
+ onDestroy(() => {
509
+ subscription?.unsubscribe();
510
+ });
511
+ ```
512
+
513
+ #### Angular Example
514
+ ```typescript
515
+ import { liveQuery } from 'dexie';
516
+ import { Component, OnInit, OnDestroy } from '@angular/core';
517
+ import { Subscription } from 'rxjs';
518
+ import { Database } from 'indexed-db-orm';
519
+ import { User } from './entities/User';
520
+
521
+ @Component({
522
+ selector: 'app-user-list',
523
+ template: '<div *ngFor="let user of users">{{user.name}}</div>'
524
+ })
525
+ export class UserListComponent implements OnInit, OnDestroy {
526
+ users: User[] = [];
527
+ private subscription?: Subscription;
528
+
529
+ ngOnInit() {
530
+ this.subscription = liveQuery(() => {
531
+ const userRepo = db.getRepository(User);
532
+ return userRepo.where('active').equals(true).toArray();
533
+ }).subscribe(result => {
534
+ this.users = result;
535
+ });
536
+ }
537
+
538
+ ngOnDestroy() {
539
+ this.subscription?.unsubscribe();
540
+ }
541
+ }
542
+ ```
543
+
544
+ ### 6. Advanced Queries and Aggregation
545
+
546
+ ```typescript
547
+ // Aggregation operations
548
+ const result = await db.aggregate({
549
+ entityClass: PostEntity,
550
+ options: {
551
+ where: { category: 'tech' },
552
+ sort: { field: 'views', direction: 'desc' },
553
+ limit: 10,
554
+ count: true,
555
+ sum: ['views'],
556
+ avg: ['likes'],
557
+ groupBy: ['category']
558
+ }
559
+ });
560
+
561
+ // Complex filtering and sorting
562
+ const topPosts = await db.getRepository(PostEntity)
563
+ .where('published')
564
+ .equals(true)
565
+ .and(post => post.views > 100)
566
+ .orderBy('views')
567
+ .reverse()
568
+ .limit(5)
569
+ .toArray();
570
+ ```
571
+
572
+ ### 6. Entity Validation
573
+
574
+ ```typescript
575
+ // Manual validation
576
+ const user = new UserEntity();
577
+ user.name = 'A'; // Too short
578
+ user.email = 'invalid-email'; // Invalid format
579
+
580
+ const result = user.validate();
581
+ if (!result.isValid) {
582
+ console.log(result.errors);
583
+ // ['name: Name must be at least 2 characters', 'email: Invalid email format']
584
+ }
585
+
586
+ // Validation with error throwing
587
+ try {
588
+ user.validateOrThrow();
589
+ } catch (error) {
590
+ console.log('Validation failed:', error.message);
591
+ }
592
+
593
+ // Initialize with validation
594
+ const validUser = new UserEntity().init({
595
+ name: 'John Doe',
596
+ email: 'john@example.com',
597
+ age: 25
598
+ });
599
+ ```
600
+
601
+ ### 7. Database Management
602
+
603
+ ```typescript
604
+ // Check for schema changes
605
+ const hasChanges = await db.checkSchemaChanges();
606
+ if (hasChanges) {
607
+ await db.performSelectiveReset(); // Reset only changed tables
608
+ // or
609
+ await db.resetDatabase(); // Reset entire database
610
+ }
611
+
612
+ // Clear all data
613
+ await db.clearAllData();
614
+
615
+ // Run migrations
616
+ await db.runMigrations([
617
+ {
618
+ version: 2,
619
+ up: async (db) => {
620
+ await db.getRepository(UserEntity).toCollection().modify(user => {
621
+ user.fullName = `${user.firstName} ${user.lastName}`;
622
+ });
623
+ }
624
+ }
625
+ ]);
626
+ ```
627
+
628
+ ### 8. Cloud Synchronization
629
+
630
+ #### Installation
631
+ ```bash
632
+ npm install dexie-cloud-addon
633
+ ```
634
+
635
+ #### Configuration
636
+ ```typescript
637
+ // Basic cloud sync configuration
638
+ const db = Database.createDatabase({
639
+ name: 'MyApp',
640
+ version: 1,
641
+ entities: [UserEntity, PostEntity],
642
+ config: {
643
+ cloudSync: {
644
+ databaseUrl: 'https://your-database-url.dexie.cloud',
645
+ enableOfflineSupport: true,
646
+ syncInterval: 30000 // 30 seconds
647
+ }
648
+ }
649
+ });
650
+
651
+ // Enable cloud sync manually
652
+ await db.enableCloudSync({
653
+ databaseUrl: 'https://your-sync-server.com',
654
+ enableOfflineSupport: true,
655
+ syncInterval: 30000
656
+ });
657
+ ```
658
+
659
+ #### Cloud Sync API
660
+ ```typescript
661
+ // Check sync status
662
+ const status = db.getSyncStatus();
663
+ console.log('Sync enabled:', status.enabled);
664
+ console.log('Last sync:', status.lastSync);
665
+ console.log('Online:', status.isOnline);
666
+
667
+ // Manual sync
668
+ await db.sync();
669
+
670
+ // Sync specific tables
671
+ await db.syncTables(['users', 'posts']);
672
+
673
+ // Check if cloud sync is enabled
674
+ const isEnabled = db.isCloudSyncEnabled();
675
+
676
+ // Get cloud sync configuration
677
+ const config = db.getCloudSyncConfig();
678
+
679
+ // Disable cloud sync
680
+ db.disableCloudSync();
681
+ ```
682
+
683
+ #### Automatic Synchronization
684
+ ```typescript
685
+ // Configure automatic sync with interval
686
+ const db = Database.createDatabase({
687
+ name: 'MyApp',
688
+ version: 1,
689
+ entities: [UserEntity, PostEntity],
690
+ config: {
691
+ cloudSync: {
692
+ databaseUrl: 'https://your-database-url.dexie.cloud',
693
+ syncInterval: 60000 // Sync every minute
694
+ }
695
+ }
696
+ });
697
+ ```
698
+
699
+ #### React Integration Example
700
+ ```typescript
701
+ import { useState, useEffect } from 'react';
702
+ import { useLiveQuery } from 'dexie-react-hooks';
703
+
704
+ function MyComponent() {
705
+ const [syncStatus, setSyncStatus] = useState({ enabled: false });
706
+
707
+ // Data with automatic synchronization
708
+ const users = useLiveQuery(() => db.getRepository(UserEntity).toArray());
709
+
710
+ useEffect(() => {
711
+ const status = db.getSyncStatus();
712
+ setSyncStatus(status);
713
+ }, []);
714
+
715
+ const handleSync = async () => {
716
+ try {
717
+ await db.sync();
718
+ alert('Synchronization completed!');
719
+ } catch (error) {
720
+ alert(`Sync error: ${error.message}`);
721
+ }
722
+ };
723
+
724
+ return (
725
+ <div>
726
+ <h2>Status: {syncStatus.enabled ? 'Enabled' : 'Disabled'}</h2>
727
+ <button onClick={handleSync}>Sync Now</button>
728
+
729
+ {users?.map(user => (
730
+ <div key={user.id}>{user.name}</div>
731
+ ))}
732
+ </div>
733
+ );
734
+ }
735
+ ```
736
+
737
+ #### Troubleshooting
738
+ ```typescript
739
+ // Check if cloud sync is configured
740
+ const config = db.getCloudSyncConfig();
741
+
742
+ if (!config) {
743
+ await db.enableCloudSync({
744
+ databaseUrl: 'https://your-database-url.dexie.cloud'
745
+ });
746
+ }
747
+
748
+ // Check sync status for debugging
749
+ const status = db.getSyncStatus();
750
+ console.log('Online:', status.isOnline);
751
+ console.log('Last sync:', status.lastSync);
752
+
753
+ // Try manual sync if automatic sync fails
754
+ await db.sync();
755
+
756
+ ```
757
+
758
+ ### 9. Compound Indexes
759
+
760
+ Compound indexes allow you to create indexes on multiple columns for better query performance.
761
+
762
+ #### Defining Compound Indexes
763
+
764
+ ```typescript
765
+ import { BaseEntity, defineEntity } from 'idb-orm';
766
+ import { z } from 'zod';
767
+
768
+ // Zod schema for validation
769
+ const UserSchema = z.object({
770
+ id: z.number().optional(),
771
+ name: z.string(),
772
+ email: z.string().email(),
773
+ age: z.number(),
774
+ isActive: z.boolean(),
775
+ });
776
+
777
+ export class UserEntity extends BaseEntity {
778
+ name!: string;
779
+ email!: string;
780
+ age!: number;
781
+ isActive!: boolean;
782
+ }
783
+
784
+ // Define entity with compound indexes
785
+ defineEntity(UserEntity, {
786
+ tableName: 'users',
787
+ schema: UserSchema,
788
+ columns: {
789
+ name: { indexed: true },
790
+ email: { indexed: true, unique: true },
791
+ age: { indexed: true },
792
+ isActive: { indexed: true },
793
+ },
794
+ compoundIndexes: [
795
+ {
796
+ columns: ['name', 'email'],
797
+ unique: false,
798
+ name: 'name_email_index'
799
+ },
800
+ {
801
+ columns: ['age', 'isActive'],
802
+ unique: false,
803
+ name: 'age_active_index'
804
+ },
805
+ {
806
+ columns: ['email'],
807
+ unique: true,
808
+ name: 'unique_email_index'
809
+ }
810
+ ]
811
+ });
812
+ ```
813
+
814
+ #### Querying with Compound Indexes
815
+
816
+ ```typescript
817
+ // Query using compound index (name + email)
818
+ const users = await db.getRepository(UserEntity)
819
+ .where(['name', 'email'])
820
+ .equals(['John Doe', 'john@example.com'])
821
+ .toArray();
822
+
823
+ // Query using compound index (age + isActive)
824
+ const activeAdults = await db.getRepository(UserEntity)
825
+ .where(['age', 'isActive'])
826
+ .above([18, 1]) // age > 18, isActive = true
827
+ .toArray();
828
+
829
+ // Query using unique compound index
830
+ const user = await db.getRepository(UserEntity)
831
+ .where('email')
832
+ .equals('john@example.com')
833
+ .first();
834
+ ```
835
+
836
+ #### Different Query Operators
837
+
838
+ ```typescript
839
+ // equals - exact match
840
+ const users = await db.getRepository(UserEntity)
841
+ .where(['name', 'email'])
842
+ .equals(['John', 'john@example.com'])
843
+ .toArray();
844
+
845
+ // above - greater than
846
+ const adults = await db.getRepository(UserEntity)
847
+ .where(['age', 'isActive'])
848
+ .above([18, 1])
849
+ .toArray();
850
+
851
+ // below - less than
852
+ const youngUsers = await db.getRepository(UserEntity)
853
+ .where(['age'])
854
+ .below([25])
855
+ .toArray();
856
+
857
+ // between - between values
858
+ const middleAged = await db.getRepository(UserEntity)
859
+ .where(['age'])
860
+ .between([25, 50])
861
+ .toArray();
862
+ ```
863
+
864
+ #### Real-world Examples
865
+
866
+ ```typescript
867
+ // 1. User search by name and email
868
+ defineEntity(UserEntity, {
869
+ tableName: 'users',
870
+ schema: UserSchema,
871
+ columns: {
872
+ name: { indexed: true },
873
+ email: { indexed: true },
874
+ },
875
+ compoundIndexes: [
876
+ { columns: ['name', 'email'], name: 'name_email_index' }
877
+ ]
878
+ });
879
+ // Usage: Find user by exact name and email
880
+ const user = await db.getRepository(UserEntity)
881
+ .where(['name', 'email'])
882
+ .equals(['John Doe', 'john@example.com'])
883
+ .first();
884
+
885
+ // 2. Active adults filter
886
+ defineEntity(UserEntity, {
887
+ tableName: 'users',
888
+ schema: UserSchema,
889
+ columns: {
890
+ age: { indexed: true },
891
+ isActive: { indexed: true },
892
+ },
893
+ compoundIndexes: [
894
+ { columns: ['age', 'isActive'], name: 'age_active_index' }
895
+ ]
896
+ });
897
+ // Usage: Find active adults
898
+ const activeAdults = await db.getRepository(UserEntity)
899
+ .where(['age', 'isActive'])
900
+ .above([18, 1])
901
+ .toArray();
902
+
903
+ // 3. Posts by date and category
904
+ defineEntity(PostEntity, {
905
+ tableName: 'posts',
906
+ schema: PostSchema,
907
+ columns: {
908
+ createdAt: { indexed: true },
909
+ category: { indexed: true },
910
+ },
911
+ compoundIndexes: [
912
+ { columns: ['createdAt', 'category'], name: 'date_category_index' }
913
+ ]
914
+ });
915
+ // Usage: Find recent posts in specific category
916
+ const recentTechPosts = await db.getRepository(PostEntity)
917
+ .where(['createdAt', 'category'])
918
+ .above([Date.now() - 7 * 24 * 60 * 60 * 1000, 'tech'])
919
+ .toArray();
920
+ ```
921
+
922
+ #### Compound Index Benefits
923
+
924
+ - **Query Performance**: Faster searches on multiple columns
925
+ - **Uniqueness**: Guarantee unique combinations of values
926
+ - **Flexibility**: Create indexes on any column combinations
927
+ - **Optimization**: Better performance for complex queries
928
+
929
+ ### Vite note: ensure a single Dexie instance for live queries
930
+
931
+ If `useLiveQuery` doesn't re-render with this library's `Database`, make sure Vite bundles a single Dexie copy by deduping Dexie:
932
+
933
+ ```ts
934
+ // vite.config.ts
935
+ import react from '@vitejs/plugin-react';
936
+ import { defineConfig } from 'vite';
937
+
938
+ export default defineConfig({
939
+ plugins: [react()],
940
+ resolve: { dedupe: ['dexie'] },
941
+ });
942
+ ```
943
+
944
+ This ensures the app and the library share the same Dexie singleton so reactivity works correctly.
945
+
946
+ ### Indexing Note
947
+
948
+ When querying with `where('field')` or sorting with `orderBy('field')`, ensure the field is indexed in your entity definition:
949
+
950
+ ```ts
951
+ defineEntity(PostEntity, {
952
+ tableName: 'posts',
953
+ columns: {
954
+ createdAt: { indexed: true },
955
+ published: { indexed: true },
956
+ likes: { indexed: true },
957
+ },
958
+ });
959
+ ```
960
+
961
+ If you change indexes, bump your database `version` or run a migration so Dexie can apply the schema update.
962
+
963
+ ## Example Applications
964
+
965
+ The library includes comprehensive demo applications showcasing all features across different frameworks:
966
+
967
+ ### Available Demo Apps
968
+
969
+ #### **React Demo App**
970
+ - **Framework**: React 19 + TypeScript
971
+ - **UI Library**: Material-UI (MUI)
972
+ - **Features**: Live queries, TypeScript demo, Cloud sync, Aggregations
973
+ - **Run**: `cd react-demo-app && npm install && npm run dev`
974
+ - **URL**: `http://localhost:5173`
975
+
976
+ #### **Vue Demo App**
977
+ - **Framework**: Vue 3 + TypeScript
978
+ - **UI Library**: Vuetify 3
979
+ - **Features**: Reactive components, Cloud sync, Entity management
980
+ - **Run**: `cd vue-demo-app && npm install && npm run dev`
981
+ - **URL**: `http://localhost:5173`
982
+
983
+ #### **Svelte Demo App**
984
+ - **Framework**: SvelteKit + TypeScript
985
+ - **UI Library**: Material-UI (MUI)
986
+ - **Features**: Server-side rendering, Live queries, TypeScript integration
987
+ - **Run**: `cd svelte-demo-app && npm install && npm run dev`
988
+ - **URL**: `http://localhost:5173`
989
+
990
+ #### **Angular Demo App**
991
+ - **Framework**: Angular 17 + TypeScript
992
+ - **UI Library**: Angular Material
993
+ - **Features**: Services, Dependency injection, Reactive forms
994
+ - **Run**: `cd angular-demo-app && npm install && npm start`
995
+ - **URL**: `http://localhost:4200`
996
+
997
+ ### Demo App Features
998
+
999
+ All demo applications showcase:
1000
+
1001
+ #### **Core Features**
1002
+ - **Entity Definition** - Using `defineEntity()` API
1003
+ - **Zod Validation** - Runtime validation with error handling
1004
+ - **Relations** - One-to-one, one-to-many, many-to-many relationships
1005
+ - **Aggregations** - Count, sum, average, min, max operations
1006
+ - **Live Queries** - Reactive data with `useLiveQuery()`
1007
+ - **TypeScript** - Full type safety and IntelliSense
1008
+
1009
+ #### **Advanced Features**
1010
+ - **Cloud Sync** - Dexie Cloud synchronization
1011
+ - **Migrations** - Database schema migrations
1012
+ - **Compound Indexes** - Multi-column indexing
1013
+ - **Entity Management** - CRUD operations with relations
1014
+ - **Error Handling** - Validation errors and user feedback
1015
+
1016
+ ### Demo App Structure
1017
+
1018
+ Each demo app follows similar structure:
1019
+
1020
+ ```
1021
+ demo-app/
1022
+ ├── src/
1023
+ │ ├── entities/ # Entity definitions
1024
+ │ ├── database/ # Database configuration
1025
+ │ └── migrations/ # Database migrations
1026
+ ├── package.json
1027
+ └── README.md
1028
+ ```
1029
+
1030
+ Each demo is fully functional and can serve as a starting point for your own applications!
1031
+
1032
+ ## API Reference
1033
+
1034
+ ### Core Classes
1035
+
1036
+ #### `Database`
1037
+ Main database class extending Dexie with ORM capabilities.
1038
+
1039
+ **Static Methods:**
1040
+ - `Database.createDatabase(params)` - Create database with entity registration
1041
+
1042
+ **Instance Methods:**
1043
+ - `getRepository<T>(entityClass)` - Get typed repository for entity
1044
+ - `aggregate<T>(params)` - Perform aggregation operations
1045
+ - `clearAllData()` - Clear all data from database
1046
+ - `resetDatabase()` - Reset database when schema changes
1047
+ - `checkSchemaChanges()` - Check if schema has changed
1048
+ - `performSelectiveReset()` - Reset only changed tables
1049
+ - `runMigrations(migrations)` - Run database migrations
1050
+ - `getTypedTable<T>(entityClass)` - Get typed table for entity
1051
+ - `getTableForEntity<T>(entityClass)` - Get table with proper typing
1052
+ - `getEntities()` - Get all registered entities
1053
+ - `getEntity(tableName)` - Get entity by table name
1054
+ - `loadRelations<T>(params)` - Load relations for entity
1055
+ - `loadRelationByName<T, K>(params)` - Load specific relation
1056
+ - `saveWithRelations<T>(params)` - Save entity with relations
1057
+ - `deleteWithRelations<T>(params)` - Delete entity with cascade
1058
+ - `sync()` - Manual cloud sync
1059
+ - `getSyncStatus()` - Get cloud sync status
1060
+ - `enableCloudSync(config)` - Enable cloud synchronization
1061
+ - `disableCloudSync()` - Disable cloud sync
1062
+ - `isCloudSyncEnabled()` - Check if cloud sync is enabled
1063
+ - `getCloudSyncConfig()` - Get cloud sync configuration
1064
+ - `syncTables(tableNames)` - Sync specific tables
1065
+
1066
+ #### `BaseEntity<TKey>`
1067
+ Base class for all entities with validation capabilities.
1068
+
1069
+ **Methods:**
1070
+ - `validate(): ValidationResult` - Validate entity against schema
1071
+ - `validateOrThrow(): void` - Validate and throw error if invalid
1072
+ - `init(data): this` - Initialize entity with data and validate
1073
+
1074
+ #### `EntitySchema<T>`
1075
+ Schema management for entities.
1076
+
1077
+ **Methods:**
1078
+ - `getTableName(): string` - Get table name for entity
1079
+ - `getSchema(): ZodSchema | undefined` - Get Zod schema
1080
+ - `getColumns(): Record<string, ColumnOptions>` - Get column metadata
1081
+ - `validate(data): ValidationResult` - Validate data against schema
1082
+ - `create(data?): T` - Create new entity instance
1083
+
1084
+ ### Entity Definition
1085
+
1086
+ #### `defineEntity(EntityClass, options)`
1087
+ Define entity with metadata and configuration.
1088
+
1089
+ **Parameters:**
1090
+ - `EntityClass` - Entity constructor class
1091
+ - `options` - Entity configuration object
1092
+
1093
+ **Options:**
1094
+ ```typescript
1095
+ interface EntityOptions {
1096
+ tableName?: string; // Custom table name
1097
+ schema?: ZodSchema; // Zod validation schema
1098
+ timestamps?: boolean; // Enable timestamps
1099
+ columns?: Record<string, ColumnOptions>;
1100
+ relations?: Record<string, RelationOptions>;
1101
+ compoundIndexes?: CompoundIndexOptions[];
1102
+ }
1103
+ ```
1104
+
1105
+ #### `newEntity(EntityClass, data)`
1106
+ Create new entity instance with validation.
1107
+
1108
+ **Parameters:**
1109
+ - `EntityClass` - Entity constructor
1110
+ - `data` - Partial entity data
1111
+
1112
+ **Returns:** Fully initialized and validated entity instance
1113
+
1114
+ ### Decorators
1115
+
1116
+ #### `@Entity(options?)`
1117
+ Class decorator for entity definition.
1118
+
1119
+ #### `@Column(options?)`
1120
+ Property decorator for column configuration.
1121
+
1122
+ #### `@Relation(options)`
1123
+ Property decorator for relation definition.
1124
+
1125
+ **Relation Types:**
1126
+ - `@OneToOne(target, options?)` - One-to-one relation
1127
+ - `@OneToMany(target, foreignKey)` - One-to-many relation
1128
+ - `@ManyToMany(target, joinTable)` - Many-to-many relation
1129
+
1130
+ ### Type Definitions
1131
+
1132
+ #### `EntityConstructor<T>`
1133
+ ```typescript
1134
+ interface EntityConstructor<T extends BaseEntity = BaseEntity> {
1135
+ new (): T;
1136
+ schema?: ZodSchema;
1137
+ tableName?: string;
1138
+ }
1139
+ ```
1140
+
1141
+ #### `ColumnOptions`
1142
+ ```typescript
1143
+ interface ColumnOptions {
1144
+ kind?: 'string' | 'number' | 'boolean' | 'array' | 'object';
1145
+ unique?: boolean;
1146
+ indexed?: boolean;
1147
+ required?: boolean;
1148
+ default?: unknown;
1149
+ primaryKey?: boolean;
1150
+ autoIncrement?: boolean;
1151
+ }
1152
+ ```
1153
+
1154
+ #### `RelationOptions`
1155
+ ```typescript
1156
+ interface RelationOptions {
1157
+ type: 'one-to-one' | 'one-to-many' | 'many-to-many';
1158
+ target: EntityConstructor | string;
1159
+ foreignKey?: string;
1160
+ joinTable?: string;
1161
+ cascade?: boolean;
1162
+ eager?: boolean;
1163
+ }
1164
+ ```
1165
+
1166
+ #### `ValidationResult`
1167
+ ```typescript
1168
+ interface ValidationResult {
1169
+ isValid: boolean;
1170
+ errors: string[];
1171
+ }
1172
+ ```
1173
+
1174
+ #### `DatabaseConfig`
1175
+ ```typescript
1176
+ interface DatabaseConfig {
1177
+ name: string;
1178
+ version: number;
1179
+ entities: EntityConstructor[];
1180
+ onSchemaChangeStrategy?: 'selective' | 'all';
1181
+ migrations?: Migration[];
1182
+ cloudSync?: CloudSyncConfig;
1183
+ }
1184
+ ```
1185
+
1186
+ #### `CloudSyncConfig`
1187
+ ```typescript
1188
+ interface CloudSyncConfig {
1189
+ databaseUrl: string;
1190
+ enableOfflineSupport?: boolean;
1191
+ syncInterval?: number;
1192
+ }
1193
+ ```
1194
+
1195
+ #### `Migration`
1196
+ ```typescript
1197
+ interface Migration {
1198
+ version: number;
1199
+ name: string;
1200
+ up: (db: Dexie) => Promise<void>;
1201
+ down?: (db: Dexie) => Promise<void>;
1202
+ }
1203
+ ```
1204
+
1205
+ #### `AggregationOptions<T>`
1206
+ ```typescript
1207
+ interface AggregationOptions<T extends BaseEntity> {
1208
+ where?: Partial<T>;
1209
+ count?: boolean;
1210
+ sum?: (keyof T)[];
1211
+ avg?: (keyof T)[];
1212
+ min?: (keyof T)[];
1213
+ max?: (keyof T)[];
1214
+ groupBy?: keyof T;
1215
+ include?: string[];
1216
+ limit?: number;
1217
+ sort?: {
1218
+ field: keyof T;
1219
+ direction: 'asc' | 'desc';
1220
+ };
1221
+ }
1222
+ ```
1223
+
1224
+ #### `AggregationResult`
1225
+ ```typescript
1226
+ interface AggregationResult {
1227
+ count?: number;
1228
+ sum?: Record<string, number>;
1229
+ avg?: Record<string, number>;
1230
+ min?: Record<string, number>;
1231
+ max?: Record<string, number>;
1232
+ groups?: Array<{
1233
+ key: unknown;
1234
+ count: number;
1235
+ sum?: Record<string, number>;
1236
+ avg?: Record<string, number>;
1237
+ min?: Record<string, number>;
1238
+ max?: Record<string, number>;
1239
+ }>;
1240
+ data?: unknown[];
1241
+ }
1242
+ ```
1243
+
1244
+ ### Error Classes
1245
+
1246
+ #### `ValidationError`
1247
+ Error thrown when entity validation fails.
1248
+
1249
+ **Properties:**
1250
+ - `message: string` - Error message
1251
+ - `errors: string[]` - Array of validation errors
1252
+
1253
+ ### Utility Functions
1254
+
1255
+ #### `newEntity(EntityClass, data)`
1256
+ Factory function for creating validated entities.
1257
+
1258
+ #### `defineEntity(EntityClass, options)`
1259
+ Function for defining entity metadata.
1260
+
1261
+ ### Schema Change Strategies
1262
+
1263
+ #### `'selective'`
1264
+ Only resets tables that have schema changes, preserving data in unchanged tables.
1265
+
1266
+ #### `'all'`
1267
+ Resets the entire database when any schema change is detected.
1268
+
1269
+ ### Cloud Sync Status
1270
+
1271
+ ```typescript
1272
+ interface SyncStatus {
1273
+ enabled: boolean;
1274
+ lastSync?: Date;
1275
+ isOnline?: boolean;
1276
+ }
1277
+ ```
1278
+
1279
+ ## License
1280
+ MIT