@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,41 @@
1
+ {
2
+ "name": "angular-demo-app",
3
+ "version": "0.0.0",
4
+ "scripts": {
5
+ "ng": "ng",
6
+ "start": "ng serve",
7
+ "build": "ng build",
8
+ "watch": "ng build --watch --configuration development",
9
+ "test": "ng test"
10
+ },
11
+ "private": true,
12
+ "dependencies": {
13
+ "@angular/animations": "^17.0.0",
14
+ "@angular/cdk": "^17.0.0",
15
+ "@angular/common": "^17.0.0",
16
+ "@angular/compiler": "^17.0.0",
17
+ "@angular/core": "^17.0.0",
18
+ "@angular/forms": "^17.0.0",
19
+ "@angular/material": "^17.0.0",
20
+ "@angular/platform-browser": "^17.0.0",
21
+ "@angular/platform-browser-dynamic": "^17.0.0",
22
+ "@angular/router": "^17.0.0",
23
+ "idb-orm": "^0.0.1",
24
+ "rxjs": "~7.8.0",
25
+ "tslib": "^2.3.0",
26
+ "zone.js": "~0.14.0"
27
+ },
28
+ "devDependencies": {
29
+ "@angular-devkit/build-angular": "^17.0.0",
30
+ "@angular/cli": "^17.0.0",
31
+ "@angular/compiler-cli": "^17.0.0",
32
+ "@types/jasmine": "~5.1.0",
33
+ "jasmine-core": "~5.1.0",
34
+ "karma": "~6.4.0",
35
+ "karma-chrome-launcher": "~3.2.0",
36
+ "karma-coverage": "~2.2.0",
37
+ "karma-jasmine": "~5.1.0",
38
+ "karma-jasmine-html-reporter": "~2.1.0",
39
+ "typescript": "~5.2.0"
40
+ }
41
+ }
@@ -0,0 +1,481 @@
1
+ import { BreakpointObserver } from '@angular/cdk/layout';
2
+ import { CommonModule } from '@angular/common';
3
+ import {
4
+ Component, OnDestroy,OnInit,
5
+ } from '@angular/core';
6
+ import { MatButtonModule } from '@angular/material/button';
7
+ import { MatCardModule } from '@angular/material/card';
8
+ import { MatIconModule } from '@angular/material/icon';
9
+ import { MatListModule } from '@angular/material/list';
10
+ import { MatSidenavModule } from '@angular/material/sidenav';
11
+ import { MatToolbarModule } from '@angular/material/toolbar';
12
+ import {
13
+ Subject, takeUntil,
14
+ } from 'rxjs';
15
+ import { PostEntity } from 'src/entities/post.entity';
16
+ import { ProfileEntity } from 'src/entities/profile.entity';
17
+ import { UserEntity } from 'src/entities/user.entity';
18
+
19
+ import { AppLogicService } from '../services/app-logic.service';
20
+ import { CloudSyncService } from '../services/cloud-sync.service';
21
+ import { LiveQueryService } from '../services/live-query.service';
22
+ import { PostsLiveQueryService } from '../services/posts-live-query.service';
23
+ import { TypeScriptDemoService } from '../services/typescript-demo.service';
24
+ import { ActionsComponent } from './components/actions.component';
25
+ import { CloudSyncDemoComponent } from './components/cloud-sync-demo.component';
26
+ import { LiveQueryDemoComponent } from './components/live-query-demo.component';
27
+ import { PostsLiveQueryDemoComponent } from './components/posts-live-query-demo.component';
28
+ import { TypeScriptDemoComponent } from './components/typescript-demo.component';
29
+
30
+ @Component({
31
+ selector: 'app-root',
32
+ standalone: true,
33
+ imports: [
34
+ CommonModule,
35
+ MatButtonModule,
36
+ MatCardModule,
37
+ MatIconModule,
38
+ MatSidenavModule,
39
+ MatToolbarModule,
40
+ MatListModule,
41
+ ActionsComponent,
42
+ LiveQueryDemoComponent,
43
+ TypeScriptDemoComponent,
44
+ PostsLiveQueryDemoComponent,
45
+ CloudSyncDemoComponent,
46
+ ],
47
+ template: `
48
+ <div class="app-container">
49
+ <!-- App Bar -->
50
+ <mat-toolbar color="primary" class="app-bar">
51
+ <button mat-icon-button
52
+ (click)="toggleMobileSidenav()"
53
+ class="mobile-menu-button">
54
+ <mat-icon>menu</mat-icon>
55
+ </button>
56
+ <span class="app-title">Dexie ORM Demo</span>
57
+ <span class="spacer"></span>
58
+ </mat-toolbar>
59
+
60
+ <div class="app-content">
61
+ <!-- Mobile Sidenav -->
62
+ <mat-sidenav-container class="mobile-sidenav-container">
63
+ <mat-sidenav #mobileSidenav
64
+ mode="over"
65
+ [opened]="mobileOpen"
66
+ (openedChange)="mobileOpen = $event"
67
+ class="mobile-sidenav">
68
+ <mat-nav-list>
69
+ <a mat-list-item (click)=
70
+ "setTabIndex(0); mobileSidenav.close()"
71
+ [class.active]="tabIndex === 0">
72
+ <mat-icon matListItemIcon>admin_panel_settings</mat-icon>
73
+ <span matListItemTitle>Admin</span>
74
+ </a>
75
+ <a mat-list-item (click)=
76
+ "setTabIndex(1); mobileSidenav.close()"
77
+ [class.active]="tabIndex === 1">
78
+ <mat-icon matListItemIcon>cloud_sync</mat-icon>
79
+ <span matListItemTitle>Cloud Sync</span>
80
+ </a>
81
+ </mat-nav-list>
82
+ </mat-sidenav>
83
+
84
+ <!-- Desktop Sidenav -->
85
+ <mat-sidenav #desktopSidenav
86
+ mode="side"
87
+ opened="true"
88
+ class="desktop-sidenav">
89
+ <mat-nav-list>
90
+ <a mat-list-item (click)=
91
+ "setTabIndex(0)" [class.active]="tabIndex === 0">
92
+ <mat-icon matListItemIcon>admin_panel_settings</mat-icon>
93
+ <span matListItemTitle>Admin</span>
94
+ </a>
95
+ <a mat-list-item (click)=
96
+ "setTabIndex(1)" [class.active]="tabIndex === 1">
97
+ <mat-icon matListItemIcon>cloud_sync</mat-icon>
98
+ <span matListItemTitle>Cloud Sync</span>
99
+ </a>
100
+ </mat-nav-list>
101
+ </mat-sidenav>
102
+
103
+ <mat-sidenav-content class="main-content">
104
+ <!-- Admin Tab Content -->
105
+ <div *ngIf="tabIndex === 0" class="tab-content">
106
+ <app-actions
107
+ [users]="users"
108
+ [addUser]="addUser.bind(this)"
109
+ [testZodValidation]="testZodValidation.bind(this)"
110
+ [testSchemaMigration]="testSchemaMigration.bind(this)"
111
+ [toggleAutoReset]="toggleAutoReset.bind(this)"
112
+ [testRelations]="testRelations.bind(this)"
113
+ [testTransactions]="testTransactions.bind(this)"
114
+ [testCompoundIndexes]="testCompoundIndexes.bind(this)"
115
+ [testAggregations]="testAggregations.bind(this)"
116
+ [clearAll]="clearAll.bind(this)">
117
+ </app-actions>
118
+
119
+ <div class="section">
120
+ <app-live-query-demo
121
+ [usersWithProfiles]="usersWithProfiles"
122
+ [allUsers]="allUsers"
123
+ [userStats]="userStats">
124
+ </app-live-query-demo>
125
+ </div>
126
+
127
+ <div class="section">
128
+ <app-typescript-demo
129
+ [users]="typescriptUsers"
130
+ [posts]="typescriptPosts"
131
+ [profiles]="typescriptProfiles"
132
+ [onUserClick]="onUserClick.bind(this)"
133
+ [onPostClick]="onPostClick.bind(this)"
134
+ [onProfileClick]="onProfileClick.bind(this)">
135
+ </app-typescript-demo>
136
+ </div>
137
+
138
+ <div class="section">
139
+ <app-posts-live-query-demo
140
+ [allPosts]="allPosts"
141
+ [topPosts]="topPosts"
142
+ [publishedPosts]="publishedPosts"
143
+ [postStats]="postStats"
144
+ [addSamplePost]="addSamplePost.bind(this)">
145
+ </app-posts-live-query-demo>
146
+ </div>
147
+ </div>
148
+
149
+ <!-- Cloud Sync Tab Content -->
150
+ <div *ngIf="tabIndex === 1" class="tab-content">
151
+ <app-cloud-sync-demo
152
+ [syncStatus]="syncStatus"
153
+ [isLoading]="isLoading"
154
+ [handleManualSync]="handleManualSync.bind(this)"
155
+ [handleEnableCloudSync]="handleEnableCloudSync.bind(this)"
156
+ [handleDisableCloudSync]="handleDisableCloudSync.bind(this)"
157
+ [handleSyncTables]="handleSyncTables.bind(this)">
158
+ </app-cloud-sync-demo>
159
+ </div>
160
+ </mat-sidenav-content>
161
+ </mat-sidenav-container>
162
+ </div>
163
+ </div>
164
+ `,
165
+ styles: [`
166
+ .app-container {
167
+ display: flex;
168
+ flex-direction: column;
169
+ min-height: 100vh;
170
+ }
171
+
172
+ .app-bar {
173
+ position: sticky;
174
+ top: 0;
175
+ z-index: 1000;
176
+ }
177
+
178
+ .app-content {
179
+ display: flex;
180
+ flex: 1;
181
+ }
182
+
183
+ .mobile-sidenav-container {
184
+ display: flex;
185
+ flex: 1;
186
+ position: relative;
187
+ }
188
+
189
+ .mobile-sidenav {
190
+ display: block;
191
+ position: fixed;
192
+ top: 0;
193
+ left: 0;
194
+ height: 100vh;
195
+ z-index: 1000;
196
+ padding-top: 64px;
197
+ }
198
+
199
+ .desktop-sidenav {
200
+ display: none;
201
+ }
202
+
203
+ @media (min-width: 960px) {
204
+ .mobile-sidenav {
205
+ display: none;
206
+ }
207
+
208
+ .desktop-sidenav {
209
+ display: block;
210
+ }
211
+ }
212
+
213
+ .mobile-menu-button {
214
+ display: block;
215
+ }
216
+
217
+ @media (min-width: 960px) {
218
+ .mobile-menu-button {
219
+ display: none;
220
+ }
221
+ }
222
+
223
+ .spacer {
224
+ flex: 1 1 auto;
225
+ }
226
+
227
+ .main-content {
228
+ flex-grow: 1;
229
+ padding: 24px;
230
+ width: calc(100% - 240px);
231
+ max-width: 100%;
232
+ }
233
+
234
+ @media (max-width: 959px) {
235
+ .main-content {
236
+ width: 100%;
237
+ padding: 16px;
238
+ }
239
+ }
240
+
241
+ .tab-content {
242
+ max-width: 1200px;
243
+ margin: 0 auto;
244
+ }
245
+
246
+ .section {
247
+ margin-top: 24px;
248
+ }
249
+
250
+ .active {
251
+ background-color: rgba(0, 0, 0, 0.04);
252
+ }
253
+
254
+ mat-nav-list a {
255
+ text-decoration: none;
256
+ color: inherit;
257
+ }
258
+ `],
259
+ })
260
+ export class AppComponent implements OnInit, OnDestroy {
261
+ private destroy$ = new Subject<void>();
262
+
263
+ // App state
264
+ users: UserEntity[] = [];
265
+ tabIndex = 0;
266
+ mobileOpen = false;
267
+
268
+ // Live query data
269
+ usersWithProfiles: UserEntity[] = [];
270
+ allUsers: UserEntity[] = [];
271
+ userStats = { totalUsers: 0, adultUsers: 0, firstUser: '' };
272
+
273
+ // TypeScript demo data
274
+ typescriptUsers: UserEntity[] = [];
275
+ typescriptPosts: PostEntity[] = [];
276
+ typescriptProfiles: ProfileEntity[] = [];
277
+
278
+ // Posts live query data
279
+ allPosts: PostEntity[] = [];
280
+ topPosts: PostEntity[] = [];
281
+ publishedPosts: PostEntity[] = [];
282
+ postStats = { total: 0, published: 0, totalLikes: 0 };
283
+
284
+ // Cloud sync data
285
+ syncStatus: {
286
+ enabled: boolean;
287
+ isOnline?: boolean;
288
+ lastSync?: Date;
289
+ } = {
290
+ enabled: false,
291
+ isOnline: undefined,
292
+ lastSync: undefined,
293
+ };
294
+ isLoading = false;
295
+
296
+ constructor(
297
+ private _appLogicService: AppLogicService,
298
+ private _liveQueryService: LiveQueryService,
299
+ private _typescriptDemoService: TypeScriptDemoService,
300
+ private _postsLiveQueryService: PostsLiveQueryService,
301
+ private _cloudSyncService: CloudSyncService,
302
+ private _breakpointObserver: BreakpointObserver,
303
+ ) {}
304
+
305
+ ngOnInit(): void {
306
+ // Subscribe to app logic
307
+ this._appLogicService.users$.pipe(takeUntil(this.destroy$)).subscribe(users => {
308
+ this.users = users;
309
+ });
310
+
311
+ this._appLogicService
312
+ .tabIndex$.pipe(takeUntil(this.destroy$)).subscribe(index => {
313
+ this.tabIndex = index;
314
+ });
315
+
316
+ this._appLogicService
317
+ .mobileOpen$.pipe(takeUntil(this.destroy$)).subscribe(open => {
318
+ this.mobileOpen = open;
319
+ });
320
+
321
+ // Subscribe to live query service
322
+ this._liveQueryService.usersWithProfiles$
323
+ .pipe(takeUntil(this.destroy$)).subscribe(users => {
324
+ this.usersWithProfiles = users;
325
+ });
326
+
327
+ this._liveQueryService.allUsers$
328
+ .pipe(takeUntil(this.destroy$)).subscribe(users => {
329
+ this.allUsers = users;
330
+ });
331
+
332
+ this._liveQueryService.userStats$
333
+ .pipe(takeUntil(this.destroy$)).subscribe(stats => {
334
+ this.userStats = stats;
335
+ });
336
+
337
+ // Subscribe to TypeScript demo service
338
+ this._typescriptDemoService.users$
339
+ .pipe(takeUntil(this.destroy$)).subscribe(users => {
340
+ this.typescriptUsers = users;
341
+ });
342
+
343
+ this._typescriptDemoService.posts$
344
+ .pipe(takeUntil(this.destroy$)).subscribe(posts => {
345
+ this.typescriptPosts = posts;
346
+ });
347
+
348
+ this._typescriptDemoService.profiles$
349
+ .pipe(takeUntil(this.destroy$)).subscribe(profiles => {
350
+ this.typescriptProfiles = profiles;
351
+ });
352
+
353
+ // Subscribe to posts live query service
354
+ this._postsLiveQueryService.allPosts$
355
+ .pipe(takeUntil(this.destroy$)).subscribe(posts => {
356
+ this.allPosts = posts;
357
+ });
358
+
359
+ this._postsLiveQueryService.topPosts$
360
+ .pipe(takeUntil(this.destroy$)).subscribe(posts => {
361
+ this.topPosts = posts;
362
+ });
363
+
364
+ this._postsLiveQueryService.publishedPosts$
365
+ .pipe(takeUntil(this.destroy$)).subscribe(posts => {
366
+ this.publishedPosts = posts;
367
+ });
368
+
369
+ this._postsLiveQueryService.postStats$
370
+ .pipe(takeUntil(this.destroy$)).subscribe(stats => {
371
+ this.postStats = stats;
372
+ });
373
+
374
+ // Subscribe to cloud sync service
375
+ this._cloudSyncService.syncStatus$
376
+ .pipe(takeUntil(this.destroy$)).subscribe(status => {
377
+ this.syncStatus = status;
378
+ });
379
+
380
+ this._cloudSyncService.isLoading$
381
+ .pipe(takeUntil(this.destroy$)).subscribe(loading => {
382
+ this.isLoading = loading;
383
+ });
384
+ }
385
+
386
+ ngOnDestroy(): void {
387
+ this.destroy$.next();
388
+ this.destroy$.complete();
389
+ }
390
+
391
+ // App logic methods
392
+ async addUser(): Promise<void> {
393
+ await this._appLogicService.addUser();
394
+ this.refreshAllData();
395
+ }
396
+
397
+ async testZodValidation(): Promise<void> {
398
+ await this._appLogicService.testZodValidation();
399
+ }
400
+
401
+ async testSchemaMigration(): Promise<void> {
402
+ await this._appLogicService.testSchemaMigration();
403
+ }
404
+
405
+ async testRelations(): Promise<void> {
406
+ await this._appLogicService.testRelations();
407
+ this.refreshAllData();
408
+ }
409
+
410
+ async testTransactions(): Promise<void> {
411
+ await this._appLogicService.testTransactions();
412
+ this.refreshAllData();
413
+ }
414
+
415
+ async testCompoundIndexes(): Promise<void> {
416
+ await this._appLogicService.testCompoundIndexes();
417
+ }
418
+
419
+ async testAggregations(): Promise<void> {
420
+ await this._appLogicService.testAggregations();
421
+ }
422
+
423
+ async clearAll(): Promise<void> {
424
+ await this._appLogicService.clearAll();
425
+ this.refreshAllData();
426
+ }
427
+
428
+ setTabIndex(index: number): void {
429
+ this._appLogicService.setTabIndex(index);
430
+ }
431
+
432
+ toggleMobileSidenav(): void {
433
+ this._appLogicService.toggleMobileOpen();
434
+ }
435
+
436
+ // TypeScript demo methods
437
+ onUserClick(user: UserEntity): void {
438
+ this._typescriptDemoService.onUserClick(user);
439
+ }
440
+
441
+ onPostClick(post: PostEntity): void {
442
+ this._typescriptDemoService.onPostClick(post);
443
+ }
444
+
445
+ onProfileClick(profile: ProfileEntity): void {
446
+ this._typescriptDemoService.onProfileClick(profile);
447
+ }
448
+
449
+ // Posts live query methods
450
+ async addSamplePost(): Promise<void> {
451
+ await this._postsLiveQueryService.addSamplePost();
452
+ }
453
+
454
+ // Cloud sync methods
455
+ async handleManualSync(): Promise<void> {
456
+ await this._cloudSyncService.handleManualSync();
457
+ }
458
+
459
+ async handleEnableCloudSync(): Promise<void> {
460
+ await this._cloudSyncService.handleEnableCloudSync();
461
+ }
462
+
463
+ async handleDisableCloudSync(): Promise<void> {
464
+ await this._cloudSyncService.handleDisableCloudSync();
465
+ }
466
+
467
+ async handleSyncTables(): Promise<void> {
468
+ await this._cloudSyncService.handleSyncTables();
469
+ }
470
+
471
+ async toggleAutoReset(): Promise<void> {
472
+ await this._appLogicService.toggleAutoReset();
473
+ }
474
+
475
+ // Helper method to refresh all data
476
+ private refreshAllData(): void {
477
+ this._liveQueryService.refresh();
478
+ this._typescriptDemoService.refresh();
479
+ this._postsLiveQueryService.refresh();
480
+ }
481
+ }
@@ -0,0 +1,8 @@
1
+ import { Routes } from '@angular/router';
2
+
3
+ export const routes: Routes = [
4
+ { path: '', redirectTo: '/admin', pathMatch: 'full' },
5
+ { path: 'admin', component: undefined }, // Handled by tabs
6
+ { path: 'cloud-sync', component: undefined }, // Handled by tabs
7
+ { path: '**', redirectTo: '/admin' },
8
+ ];