@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
@@ -0,0 +1,178 @@
1
+ import {
2
+ beforeEach, describe, expect, it,
3
+ } from 'vitest';
4
+
5
+ import {
6
+ defineEntity, newEntity,
7
+ } from '../src';
8
+ import { Database } from '../src/Database';
9
+ import { BaseEntity } from '../src/services/BaseEntity';
10
+
11
+ class User extends BaseEntity<number> {
12
+ name: string;
13
+ profile?: Profile;
14
+ posts?: Post[];
15
+ }
16
+
17
+ defineEntity(User, {
18
+ tableName: 'users',
19
+ columns: { name: { required: true } },
20
+ relations: {
21
+ profile: { type: 'one-to-one', target: 'profiles', foreignKey: 'userId', cascade: true },
22
+ posts: { type: 'one-to-many', target: 'posts', foreignKey: 'authorId', cascade: true },
23
+ },
24
+ });
25
+
26
+ class Profile extends BaseEntity<number> {
27
+ bio?: string;
28
+ userId?: number;
29
+ }
30
+
31
+ defineEntity(Profile, {
32
+ tableName: 'profiles',
33
+ columns: {
34
+ bio: {},
35
+ userId: { indexed: true },
36
+ },
37
+ });
38
+
39
+ class Post extends BaseEntity<number> {
40
+ title!: string;
41
+ tags?: Tag[];
42
+ authorId?: number;
43
+ }
44
+
45
+ defineEntity(Post, {
46
+ tableName: 'posts',
47
+ columns: {
48
+ title: { required: true },
49
+ authorId: { indexed: true },
50
+ },
51
+ relations: {
52
+ tags: { type: 'many-to-many', target: 'tags', joinTable: 'post_tags', cascade: true },
53
+ },
54
+ });
55
+
56
+ class Tag extends BaseEntity<number> {
57
+ name!: string;
58
+ }
59
+
60
+ defineEntity(Tag, {
61
+ tableName: 'tags',
62
+ columns: { name: { required: true } },
63
+ });
64
+
65
+ class PostTag extends BaseEntity<number> {
66
+ sourceId!: number;
67
+ targetId!: number;
68
+ }
69
+
70
+ defineEntity(PostTag, {
71
+ tableName: 'post_tags',
72
+ columns: {
73
+ sourceId: { indexed: true },
74
+ targetId: { indexed: true },
75
+ },
76
+ });
77
+
78
+ const ENTITIES = [User, Profile, Post, Tag, PostTag];
79
+
80
+ describe('Relations', () => {
81
+ let db: Database;
82
+
83
+ beforeEach(async () => {
84
+ db = Database.createDatabase({
85
+ name: `rel-db-${Date.now()}-${Math.random()}`,
86
+ version: 1,
87
+ entities: ENTITIES,
88
+ config: { onSchemaChangeStrategy: 'all' },
89
+ });
90
+
91
+ await db.clearAllData();
92
+ });
93
+
94
+ it('one-to-one: load and cascade delete', async () => {
95
+ const users = db.getRepository(User);
96
+ const profiles = db.getRepository(Profile);
97
+
98
+ const u = newEntity(User, { name: 'U' });
99
+ const userId = await users.add(u);
100
+
101
+ const profile = newEntity(Profile, { bio: 'Bio', userId });
102
+ const saved = await db
103
+ .saveWithRelations({ entity: profile, entityClass: Profile });
104
+
105
+ const loaded = await db.loadRelationByName({
106
+ entity: { id: userId },
107
+ entityClass: User,
108
+ relationName: 'profile',
109
+ });
110
+ expect(loaded!.bio).toBe('Bio');
111
+
112
+ await db.deleteWithRelations({ entity: saved, entityClass: Profile });
113
+ const after = await profiles.get(saved.id!);
114
+ expect(after).toBeUndefined();
115
+ });
116
+
117
+ it('one-to-many: load and cascade delete', async () => {
118
+ const users = db.getRepository(User);
119
+ const posts = db.getRepository(Post);
120
+
121
+ const u = newEntity(User, { name: 'U' });
122
+ const userId = await users.add(u);
123
+
124
+ const p1 = newEntity(Post, { title: 'P1', authorId: userId });
125
+ const p2 = newEntity(Post, { title: 'P2', authorId: userId });
126
+
127
+ await db.saveWithRelations({ entity: p1, entityClass: Post });
128
+ await db.saveWithRelations({ entity: p2, entityClass: Post });
129
+
130
+ const loaded = await db.loadRelationByName({
131
+ entity: { id: userId },
132
+ entityClass: User,
133
+ relationName: 'posts',
134
+ });
135
+ expect((loaded as Post[]).length).toBe(2);
136
+
137
+ const first = await posts.where('authorId').equals(userId).first();
138
+ await db.deleteWithRelations({ entity: first!, entityClass: Post });
139
+
140
+ const remaining = await posts.where('authorId').equals(userId).toArray();
141
+ expect(remaining.length).toBe(1);
142
+ });
143
+
144
+ it('many-to-many: load and cascade delete removes join links', async () => {
145
+ const posts = db.getRepository(Post);
146
+ const tags = db.getRepository(Tag);
147
+ const join = db.table('post_tags');
148
+
149
+ const pNew = newEntity(Post, { title: 'P' });
150
+ const postId = await posts.add(pNew);
151
+
152
+ const tA = newEntity(Tag, { name: 'a' });
153
+ const tagAId = await tags.add(tA);
154
+
155
+ const tB = newEntity(Tag, { name: 'b' });
156
+ const tagBId = await tags.add(tB);
157
+
158
+ const p = newEntity(Post, {
159
+ id: postId,
160
+ title: 'P',
161
+ tags: [{ id: tagAId } as Tag, { id: tagBId } as Tag],
162
+ });
163
+ await db.saveWithRelations({ entity: p, entityClass: Post });
164
+
165
+ const loaded = await db.loadRelationByName({
166
+ entity: { id: postId } as Post,
167
+ entityClass: Post,
168
+ relationName: 'tags',
169
+ });
170
+ expect((loaded as Tag[]).length).toBe(2);
171
+
172
+ await db
173
+ .deleteWithRelations({ entity: { id: postId } as Post, entityClass: Post });
174
+
175
+ const links = await join.where('sourceId').equals(postId).toArray();
176
+ expect(links.length).toBe(0);
177
+ });
178
+ });
@@ -0,0 +1,69 @@
1
+ import {
2
+ beforeEach, describe, expect, it,
3
+ } from 'vitest';
4
+ import { z } from 'zod';
5
+
6
+ import { defineEntity } from '../src';
7
+ import { Database } from '../src/Database';
8
+ import { BaseEntity } from '../src/services/BaseEntity';
9
+ import { EntitySchema } from '../src/services/EntitySchema';
10
+
11
+ class Product extends BaseEntity<number> {
12
+ name?: string;
13
+ price?: number;
14
+ static schema = z.object({
15
+ name: z.string(),
16
+ price: z.number().positive(),
17
+ });
18
+ }
19
+
20
+ defineEntity(Product, { tableName: 'products' });
21
+
22
+ describe('Zod runtime validation', () => {
23
+ let db: Database;
24
+
25
+ beforeEach(async () => {
26
+ db = Database.createDatabase({
27
+ name: `zod-db-${Date.now()}-${Math.random()}`,
28
+ version: 1,
29
+ entities: [Product],
30
+ config: { onSchemaChangeStrategy: 'all' },
31
+ });
32
+
33
+ await db.clearAllData();
34
+ });
35
+
36
+ it('BaseEntity.validate and validateOrThrow (registered entity)', () => {
37
+ const entityCtor = db.getEntity('products')!;
38
+ expect(entityCtor).toBe(Product);
39
+
40
+ const ok = new Product();
41
+ Object.assign(ok, { name: 'X', price: 1 });
42
+
43
+ const okRes = ok.validate();
44
+ expect(okRes.isValid).toBe(true);
45
+
46
+ const bad = new Product();
47
+ Object.assign(bad, { name: 'Y', price: -2 });
48
+
49
+ const badRes = bad.validate();
50
+ expect(badRes.isValid).toBe(false);
51
+ expect(() => bad.validateOrThrow()).toThrowError();
52
+ });
53
+
54
+ it('EntitySchema.validate with schema and create', () => {
55
+ const schema = new EntitySchema(Product, Product.schema);
56
+
57
+ const valid = schema.validate({ name: 'A', price: 2 });
58
+ expect(valid.isValid).toBe(true);
59
+
60
+ const invalid = schema
61
+ .validate({ name: 'A', price: -1 } as Partial<Product>);
62
+
63
+ expect(invalid.isValid).toBe(false);
64
+
65
+ const p = schema.create({ name: 'B', price: 3 });
66
+ expect(p.name).toBe('B');
67
+ expect(p.price).toBe(3);
68
+ });
69
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "lib": ["ES2022", "DOM"],
6
+ "declaration": true,
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "experimentalDecorators": false,
14
+ "emitDecoratorMetadata": false,
15
+ "moduleResolution": "bundler",
16
+ "allowSyntheticDefaultImports": true,
17
+ "resolveJsonModule": true
18
+ },
19
+ "include": ["src/**/*"],
20
+ "exclude": ["node_modules", "dist", "demo-app"]
21
+ }
@@ -0,0 +1,21 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'node',
6
+ setupFiles: ['./vitest.setup.ts'],
7
+ include: ['tests/**/*.test.ts'],
8
+ globals: true,
9
+ },
10
+ esbuild: {
11
+ tsconfigRaw: {
12
+ compilerOptions: {
13
+ experimentalDecorators: true,
14
+ useDefineForClassFields: false,
15
+ target: 'ES2022',
16
+ },
17
+ },
18
+ },
19
+ });
20
+
21
+
@@ -0,0 +1,27 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
3
+ import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
4
+ import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
5
+
6
+ if (!(globalThis as any).indexedDB) {
7
+ (globalThis as any).indexedDB = new FDBFactory();
8
+ }
9
+
10
+ if (!(globalThis as any).IDBKeyRange) {
11
+ (globalThis as any).IDBKeyRange = FDBKeyRange;
12
+ }
13
+
14
+ class MemoryLocalStorage {
15
+ private store = new Map<string, string>();
16
+ getItem(key: string):
17
+ string | null { return this.store.has(key) ? this.store.get(key)! : null; }
18
+ setItem(key: string, value: string): void { this.store.set(key, String(value)); }
19
+ removeItem(key: string): void { this.store.delete(key); }
20
+ clear(): void { this.store.clear(); }
21
+ }
22
+
23
+ if (!(globalThis as any).localStorage) {
24
+ (globalThis as any).localStorage = new MemoryLocalStorage();
25
+ }
26
+
27
+
@@ -0,0 +1,61 @@
1
+ # Dexie ORM Demo App
2
+
3
+ A demonstration app showcasing the capabilities of the **Dexie ORM for IndexedDB** library.
4
+
5
+ ## Library Features
6
+
7
+ - **Entity Configuration** - define entities using `defineEntity()`
8
+ - **Automatic Schema** - automatic schema generation with primary keys and indexes
9
+ - **Relations** - entity relationships with helpers
10
+ - **Zod Validation** - runtime validation
11
+ - **Aggregations** - aggregate functions (count, avg, sum)
12
+ - **Live Queries** - reactive queries with `useLiveQuery()`
13
+ - **TypeScript** - full type safety
14
+ - **Cloud Sync** - synchronization with Dexie Cloud
15
+
16
+ ## Quick Start
17
+
18
+ ### Requirements
19
+ - Node.js 18+
20
+ - npm or yarn
21
+
22
+ ### Installation and Running
23
+
24
+ 1. **Install dependencies:**
25
+ ```bash
26
+ npm install
27
+ ```
28
+
29
+ 2. **Run in development mode:**
30
+ ```bash
31
+ npm run dev
32
+ ```
33
+
34
+ 3. **Open in browser:**
35
+ ```
36
+ http://localhost:5173
37
+ ```
38
+
39
+ ### Production Build
40
+
41
+ ```bash
42
+ npm run build
43
+ ```
44
+
45
+ ## App Features
46
+
47
+ ### Admin Tab
48
+ - **Overview** - library capabilities overview
49
+ - **Admin Actions** - function testing buttons
50
+ - **Live Query Demo** - reactive queries demonstration
51
+ - **TypeScript Demo** - type safety testing
52
+ - **Posts Demo** - advanced queries and aggregations
53
+
54
+ ### Cloud Sync Tab
55
+ - **Sync Status** - synchronization status
56
+ - **Sync Controls** - synchronization management buttons
57
+ - **Instructions** - configuration instructions
58
+
59
+ ## More Information
60
+
61
+ For more information visit our official [page](https://idb-orm.com).
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Dexie ORM Vue Demo</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>