@vue-skuilder/db 0.1.3 → 0.1.5

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 (80) hide show
  1. package/dist/SyncStrategy-DnJRj-Xp.d.mts +74 -0
  2. package/dist/SyncStrategy-DnJRj-Xp.d.ts +74 -0
  3. package/dist/core/index.d.mts +90 -2
  4. package/dist/core/index.d.ts +90 -2
  5. package/dist/core/index.js +798 -650
  6. package/dist/core/index.js.map +1 -1
  7. package/dist/core/index.mjs +769 -621
  8. package/dist/core/index.mjs.map +1 -1
  9. package/dist/dataLayerProvider-B8wquRiB.d.mts +37 -0
  10. package/dist/dataLayerProvider-DRjMZMaf.d.ts +37 -0
  11. package/dist/impl/couch/index.d.mts +292 -0
  12. package/dist/impl/couch/index.d.ts +292 -0
  13. package/dist/impl/couch/index.js +8522 -0
  14. package/dist/impl/couch/index.js.map +1 -0
  15. package/dist/impl/couch/index.mjs +8474 -0
  16. package/dist/impl/couch/index.mjs.map +1 -0
  17. package/dist/impl/static/index.d.mts +204 -0
  18. package/dist/impl/static/index.d.ts +204 -0
  19. package/dist/impl/static/index.js +8499 -0
  20. package/dist/impl/static/index.js.map +1 -0
  21. package/dist/impl/static/index.mjs +8488 -0
  22. package/dist/impl/static/index.mjs.map +1 -0
  23. package/dist/index.d.mts +13 -4
  24. package/dist/index.d.ts +13 -4
  25. package/dist/index.js +3280 -2108
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.mjs +3290 -2118
  28. package/dist/index.mjs.map +1 -1
  29. package/dist/types-B0GJsjOr.d.ts +47 -0
  30. package/dist/types-DIgj8pP7.d.mts +47 -0
  31. package/dist/types-legacy-CTsJvvxI.d.mts +137 -0
  32. package/dist/types-legacy-CTsJvvxI.d.ts +137 -0
  33. package/dist/{index-QMtzQI65.d.mts → userDB-C5dcuRZs.d.ts} +3 -251
  34. package/dist/{index-QMtzQI65.d.ts → userDB-ZSwOXiYN.d.mts} +3 -251
  35. package/dist/util/packer/index.d.mts +25 -0
  36. package/dist/util/packer/index.d.ts +25 -0
  37. package/dist/util/packer/index.js +307 -0
  38. package/dist/util/packer/index.js.map +1 -0
  39. package/dist/util/packer/index.mjs +280 -0
  40. package/dist/util/packer/index.mjs.map +1 -0
  41. package/package.json +12 -2
  42. package/src/core/interfaces/contentSource.ts +8 -6
  43. package/src/core/interfaces/userDB.ts +2 -2
  44. package/src/factory.ts +10 -7
  45. package/src/impl/{pouch/userDB.ts → common/BaseUserDB.ts} +225 -260
  46. package/src/impl/common/SyncStrategy.ts +90 -0
  47. package/src/impl/common/index.ts +23 -0
  48. package/src/impl/common/types.ts +50 -0
  49. package/src/impl/common/userDBHelpers.ts +144 -0
  50. package/src/impl/couch/CouchDBSyncStrategy.ts +209 -0
  51. package/src/impl/{pouch → couch}/PouchDataLayerProvider.ts +12 -7
  52. package/src/impl/{pouch → couch}/adminDB.ts +3 -3
  53. package/src/impl/{pouch → couch}/auth.ts +2 -2
  54. package/src/impl/{pouch → couch}/classroomDB.ts +6 -6
  55. package/src/impl/{pouch → couch}/courseAPI.ts +28 -5
  56. package/src/impl/{pouch → couch}/courseDB.ts +24 -10
  57. package/src/impl/{pouch → couch}/courseLookupDB.ts +1 -1
  58. package/src/impl/{pouch → couch}/index.ts +27 -20
  59. package/src/impl/{pouch → couch}/updateQueue.ts +5 -1
  60. package/src/impl/{pouch → couch}/user-course-relDB.ts +6 -1
  61. package/src/impl/static/NoOpSyncStrategy.ts +70 -0
  62. package/src/impl/static/StaticDataLayerProvider.ts +89 -0
  63. package/src/impl/static/StaticDataUnpacker.ts +376 -0
  64. package/src/impl/static/courseDB.ts +257 -0
  65. package/src/impl/static/coursesDB.ts +37 -0
  66. package/src/impl/static/index.ts +8 -0
  67. package/src/impl/static/userDB.ts +179 -0
  68. package/src/index.ts +1 -1
  69. package/src/study/SessionController.ts +4 -4
  70. package/src/study/SpacedRepetition.ts +3 -3
  71. package/src/study/getCardDataShape.ts +2 -2
  72. package/src/util/index.ts +1 -0
  73. package/src/util/packer/CouchDBToStaticPacker.ts +349 -0
  74. package/src/util/packer/index.ts +4 -0
  75. package/src/util/packer/types.ts +52 -0
  76. package/tsconfig.json +7 -10
  77. package/tsup.config.ts +5 -3
  78. /package/src/impl/{pouch → couch}/clientCache.ts +0 -0
  79. /package/src/impl/{pouch → couch}/pouchdb-setup.ts +0 -0
  80. /package/src/impl/{pouch → couch}/types.ts +0 -0
@@ -0,0 +1,90 @@
1
+ // packages/db/src/impl/common/SyncStrategy.ts
2
+
3
+ import type { AccountCreationResult, AuthenticationResult } from './types';
4
+
5
+ /**
6
+ * Strategy interface for handling user data synchronization
7
+ * Different implementations handle remote sync vs local-only storage
8
+ */
9
+ export interface SyncStrategy {
10
+ /**
11
+ * Set up the remote database for a user
12
+ * @param username The username to set up remote DB for
13
+ * @returns PouchDB database instance (may be same as local for no-op)
14
+ */
15
+ setupRemoteDB(username: string): PouchDB.Database;
16
+
17
+ /**
18
+ * Start synchronization between local and remote databases
19
+ * @param localDB The local PouchDB instance
20
+ * @param remoteDB The remote PouchDB instance
21
+ */
22
+ startSync(localDB: PouchDB.Database, remoteDB: PouchDB.Database): void;
23
+
24
+ /**
25
+ * Stop synchronization (optional - for cleanup)
26
+ */
27
+ stopSync?(): void;
28
+
29
+ /**
30
+ * Whether this strategy supports account creation
31
+ */
32
+ canCreateAccount(): boolean;
33
+
34
+ /**
35
+ * Whether this strategy supports authentication
36
+ */
37
+ canAuthenticate(): boolean;
38
+
39
+ /**
40
+ * Create a new user account (if supported)
41
+ * @param username The username for the new account
42
+ * @param password The password for the new account
43
+ */
44
+ createAccount?(username: string, password: string): Promise<AccountCreationResult>;
45
+
46
+ /**
47
+ * Authenticate a user (if supported)
48
+ * @param username The username to authenticate
49
+ * @param password The password to authenticate with
50
+ */
51
+ authenticate?(username: string, password: string): Promise<AuthenticationResult>;
52
+
53
+ /**
54
+ * Log out the current user (if supported)
55
+ */
56
+ logout?(): Promise<AuthenticationResult>;
57
+
58
+ /**
59
+ * Get the current logged-in username
60
+ * Returns the username if logged in, or a default guest username
61
+ */
62
+ getCurrentUsername(): Promise<string>;
63
+ }
64
+
65
+ /**
66
+ * Base class for sync strategies with common functionality
67
+ */
68
+ export abstract class BaseSyncStrategy implements SyncStrategy {
69
+ abstract setupRemoteDB(username: string): PouchDB.Database;
70
+ abstract startSync(localDB: PouchDB.Database, remoteDB: PouchDB.Database): void;
71
+ abstract canCreateAccount(): boolean;
72
+ abstract canAuthenticate(): boolean;
73
+ abstract getCurrentUsername(): Promise<string>;
74
+
75
+ stopSync?(): void {
76
+ // Default no-op implementation
77
+ }
78
+
79
+ async createAccount(_username: string, _password: string): Promise<AccountCreationResult> {
80
+ throw new Error('Account creation not supported by this sync strategy');
81
+ }
82
+
83
+ async authenticate(_username: string, _password: string): Promise<AuthenticationResult> {
84
+ throw new Error('Authentication not supported by this sync strategy');
85
+ }
86
+
87
+ async logout(): Promise<AuthenticationResult> {
88
+ throw new Error('Logout not supported by this sync strategy');
89
+ }
90
+ }
@@ -0,0 +1,23 @@
1
+ // packages/db/src/impl/common/index.ts
2
+
3
+ export type { SyncStrategy } from './SyncStrategy';
4
+ export { BaseSyncStrategy } from './SyncStrategy';
5
+ export type {
6
+ AccountCreationResult,
7
+ AuthenticationResult,
8
+ UserSession,
9
+ SyncConfig,
10
+ SyncStatus,
11
+ } from './types';
12
+ export { BaseUser } from './BaseUserDB';
13
+ export {
14
+ REVIEW_PREFIX,
15
+ REVIEW_TIME_FORMAT,
16
+ hexEncode,
17
+ filterAllDocsByPrefix,
18
+ getStartAndEndKeys,
19
+ updateGuestAccountExpirationDate,
20
+ getLocalUserDB,
21
+ scheduleCardReviewLocal,
22
+ removeScheduledCardReviewLocal,
23
+ } from './userDBHelpers';
@@ -0,0 +1,50 @@
1
+ // packages/db/src/impl/common/types.ts
2
+
3
+ /**
4
+ * Common types used by UserDB implementations across different sync strategies
5
+ */
6
+
7
+ import { Status } from '@vue-skuilder/common';
8
+
9
+ /**
10
+ * Result type for account creation operations
11
+ */
12
+ export interface AccountCreationResult {
13
+ status: Status;
14
+ error?: string;
15
+ }
16
+
17
+ /**
18
+ * Result type for authentication operations
19
+ */
20
+ export interface AuthenticationResult {
21
+ ok: boolean;
22
+ error?: string;
23
+ }
24
+
25
+ /**
26
+ * User session information
27
+ */
28
+ export interface UserSession {
29
+ username: string;
30
+ isLoggedIn: boolean;
31
+ isGuest: boolean;
32
+ }
33
+
34
+ /**
35
+ * Configuration for sync behavior
36
+ */
37
+ export interface SyncConfig {
38
+ live?: boolean;
39
+ retry?: boolean;
40
+ continuous?: boolean;
41
+ }
42
+
43
+ /**
44
+ * Sync status information
45
+ */
46
+ export interface SyncStatus {
47
+ active: boolean;
48
+ lastSync?: Date;
49
+ error?: string;
50
+ }
@@ -0,0 +1,144 @@
1
+ // packages/db/src/impl/common/userDBHelpers.ts
2
+
3
+ import moment from 'moment';
4
+ import { logger } from '../../util/logger';
5
+ import { ScheduledCard } from '@db/core/types/user';
6
+
7
+ export const REVIEW_PREFIX: string = 'card_review_';
8
+ export const REVIEW_TIME_FORMAT: string = 'YYYY-MM-DD--kk:mm:ss-SSS';
9
+
10
+ import pouch from '../couch/pouchdb-setup';
11
+
12
+ const log = (s: any) => {
13
+ logger.info(s);
14
+ };
15
+
16
+ export function hexEncode(str: string): string {
17
+ let hex: string;
18
+ let returnStr: string = '';
19
+
20
+ for (let i = 0; i < str.length; i++) {
21
+ hex = str.charCodeAt(i).toString(16);
22
+ returnStr += ('000' + hex).slice(3);
23
+ }
24
+
25
+ return returnStr;
26
+ }
27
+
28
+ export function filterAllDocsByPrefix<T>(
29
+ db: PouchDB.Database,
30
+ prefix: string,
31
+ opts?: PouchDB.Core.AllDocsOptions
32
+ ) {
33
+ // see couchdb docs 6.2.2:
34
+ // Guide to Views -> Views Collation -> String Ranges
35
+ const options: PouchDB.Core.AllDocsWithinRangeOptions = {
36
+ startkey: prefix,
37
+ endkey: prefix + '\ufff0',
38
+ include_docs: true,
39
+ };
40
+
41
+ if (opts) {
42
+ Object.assign(options, opts);
43
+ }
44
+ return db.allDocs<T>(options);
45
+ }
46
+
47
+ export function getStartAndEndKeys(key: string): {
48
+ startkey: string;
49
+ endkey: string;
50
+ } {
51
+ return {
52
+ startkey: key,
53
+ endkey: key + '\ufff0',
54
+ };
55
+ }
56
+
57
+ export function updateGuestAccountExpirationDate(guestDB: PouchDB.Database<object>) {
58
+ const currentTime = moment.utc();
59
+ const expirationDate: string = currentTime.add(2, 'months').toISOString();
60
+ const expiryDocID: string = 'GuestAccountExpirationDate';
61
+
62
+ void guestDB
63
+ .get(expiryDocID)
64
+ .then((doc) => {
65
+ return guestDB.put({
66
+ _id: expiryDocID,
67
+ _rev: doc._rev,
68
+ date: expirationDate,
69
+ });
70
+ })
71
+ .catch(() => {
72
+ return guestDB.put({
73
+ _id: expiryDocID,
74
+ date: expirationDate,
75
+ });
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Get local user database with appropriate adapter for environment
81
+ */
82
+ export function getLocalUserDB(username: string): PouchDB.Database {
83
+ // // Choose adapter based on environment
84
+ //
85
+ // Not certain of this is required. Let's let pouch's auto detection
86
+ // handle it until we specifically know we need to intervene.
87
+ //
88
+ // let adapter: string;
89
+ // if (typeof window !== 'undefined') {
90
+ // // Browser environment - use IndexedDB
91
+ // adapter = 'idb';
92
+ // } else {
93
+ // // Node.js environment (tests) - use memory adapter
94
+ // adapter = 'memory';
95
+ // }
96
+
97
+ return new pouch(`userdb-${username}`, {});
98
+ }
99
+
100
+ /**
101
+ * Schedule a card review (strategy-agnostic version)
102
+ */
103
+ export function scheduleCardReviewLocal(
104
+ userDB: PouchDB.Database,
105
+ review: {
106
+ card_id: PouchDB.Core.DocumentId;
107
+ time: moment.Moment;
108
+ course_id: string;
109
+ scheduledFor: ScheduledCard['scheduledFor'];
110
+ schedulingAgentId: ScheduledCard['schedulingAgentId'];
111
+ }
112
+ ) {
113
+ const now = moment.utc();
114
+ logger.info(`Scheduling for review in: ${review.time.diff(now, 'h') / 24} days`);
115
+ void userDB.put<ScheduledCard>({
116
+ _id: REVIEW_PREFIX + review.time.format(REVIEW_TIME_FORMAT),
117
+ cardId: review.card_id,
118
+ reviewTime: review.time,
119
+ courseId: review.course_id,
120
+ scheduledAt: now,
121
+ scheduledFor: review.scheduledFor,
122
+ schedulingAgentId: review.schedulingAgentId,
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Remove a scheduled card review (strategy-agnostic version)
128
+ */
129
+ export async function removeScheduledCardReviewLocal(
130
+ userDB: PouchDB.Database,
131
+ reviewDocID: string
132
+ ) {
133
+ const reviewDoc = await userDB.get(reviewDocID);
134
+ userDB
135
+ .remove(reviewDoc)
136
+ .then((res) => {
137
+ if (res.ok) {
138
+ log(`Removed Review Doc: ${reviewDocID}`);
139
+ }
140
+ })
141
+ .catch((err) => {
142
+ log(`Failed to remove Review Doc: ${reviewDocID},\n${JSON.stringify(err)}`);
143
+ });
144
+ }
@@ -0,0 +1,209 @@
1
+ // packages/db/src/impl/couch/CouchDBSyncStrategy.ts
2
+
3
+ import { ENV } from '@db/factory';
4
+ import { GuestUsername } from '../../core/types/types-legacy';
5
+ import { logger } from '../../util/logger';
6
+ import { Status } from '@vue-skuilder/common';
7
+ import type { SyncStrategy } from '../common/SyncStrategy';
8
+ import type { AccountCreationResult, AuthenticationResult } from '../common/types';
9
+ import { getLocalUserDB, hexEncode, updateGuestAccountExpirationDate } from '../common';
10
+ import pouch from './pouchdb-setup';
11
+ import { pouchDBincludeCredentialsConfig } from './index';
12
+ import { getLoggedInUsername } from './auth';
13
+
14
+ const log = (s: any) => {
15
+ logger.info(s);
16
+ };
17
+
18
+ /**
19
+ * Sync strategy that implements full CouchDB remote synchronization
20
+ * Handles account creation, authentication, and live sync with remote CouchDB server
21
+ */
22
+ export class CouchDBSyncStrategy implements SyncStrategy {
23
+ private syncHandle?: any; // Handle to cancel sync if needed
24
+
25
+ setupRemoteDB(username: string): PouchDB.Database {
26
+ if (username === GuestUsername || username.startsWith(GuestUsername)) {
27
+ // For guest users, remote is same as local (no remote sync)
28
+ return getLocalUserDB(username);
29
+ } else {
30
+ // For real users, connect to remote CouchDB
31
+ return this.getUserDB(username);
32
+ }
33
+ }
34
+
35
+ startSync(localDB: PouchDB.Database, remoteDB: PouchDB.Database): void {
36
+ // Only sync if local and remote are different instances
37
+ if (localDB !== remoteDB) {
38
+ this.syncHandle = pouch.sync(localDB, remoteDB, {
39
+ live: true,
40
+ retry: true,
41
+ });
42
+ }
43
+ // If they're the same (guest mode), no sync needed
44
+ }
45
+
46
+ stopSync?(): void {
47
+ if (this.syncHandle) {
48
+ this.syncHandle.cancel();
49
+ this.syncHandle = undefined;
50
+ }
51
+ }
52
+
53
+ canCreateAccount(): boolean {
54
+ return true;
55
+ }
56
+
57
+ canAuthenticate(): boolean {
58
+ return true;
59
+ }
60
+
61
+ async createAccount(username: string, password: string): Promise<AccountCreationResult> {
62
+ try {
63
+ const signupRequest = await this.getRemoteCouchRootDB().signUp(username, password);
64
+
65
+ if (signupRequest.ok) {
66
+ log(`CREATEACCOUNT: Successfully created account for ${username}`);
67
+
68
+ // Log out any existing session
69
+ try {
70
+ const logoutResult = await this.getRemoteCouchRootDB().logOut();
71
+ log(`CREATEACCOUNT: logged out: ${logoutResult.ok}`);
72
+ } catch {
73
+ // Ignore logout errors - might not be logged in
74
+ }
75
+
76
+ // Log in as the new user
77
+ const loginResult = await this.getRemoteCouchRootDB().logIn(username, password);
78
+ log(`CREATEACCOUNT: logged in as new user: ${loginResult.ok}`);
79
+
80
+ if (loginResult.ok) {
81
+ // TODO: Handle guest data migration here if needed
82
+ // Set up databases for the new user:
83
+ // const newLocal = getLocalUserDB(username);
84
+ // const newRemote = this.getUserDB(username);
85
+
86
+ // For now, just return success
87
+ return {
88
+ status: Status.ok,
89
+ error: undefined,
90
+ };
91
+ } else {
92
+ return {
93
+ status: Status.error,
94
+ error: 'Failed to log in after account creation',
95
+ };
96
+ }
97
+ } else {
98
+ logger.warn(`Signup not OK: ${JSON.stringify(signupRequest)}`);
99
+ return {
100
+ status: Status.error,
101
+ error: 'Account creation failed',
102
+ };
103
+ }
104
+ } catch (e: any) {
105
+ if (e.reason === 'Document update conflict.') {
106
+ return {
107
+ status: Status.error,
108
+ error: 'This username is taken!',
109
+ };
110
+ }
111
+ logger.error(`Error on signup: ${JSON.stringify(e)}`);
112
+ return {
113
+ status: Status.error,
114
+ error: e.message || 'Unknown error during account creation',
115
+ };
116
+ }
117
+ }
118
+
119
+ async authenticate(username: string, password: string): Promise<AuthenticationResult> {
120
+ try {
121
+ const loginResult = await this.getRemoteCouchRootDB().logIn(username, password);
122
+
123
+ if (loginResult.ok) {
124
+ log(`Successfully logged in as ${username}`);
125
+ return {
126
+ ok: true,
127
+ };
128
+ } else {
129
+ log(`Login failed for ${username}`);
130
+ return {
131
+ ok: false,
132
+ error: 'Invalid username or password',
133
+ };
134
+ }
135
+ } catch (error: any) {
136
+ logger.error(`Authentication error for ${username}:`, error);
137
+ return {
138
+ ok: false,
139
+ error: error.message || 'Authentication failed',
140
+ };
141
+ }
142
+ }
143
+
144
+ async logout(): Promise<AuthenticationResult> {
145
+ try {
146
+ const result = await this.getRemoteCouchRootDB().logOut();
147
+ return {
148
+ ok: result.ok,
149
+ error: result.ok ? undefined : 'Logout failed',
150
+ };
151
+ } catch (error: any) {
152
+ logger.error('Logout error:', error);
153
+ return {
154
+ ok: false,
155
+ error: error.message || 'Logout failed',
156
+ };
157
+ }
158
+ }
159
+
160
+ async getCurrentUsername(): Promise<string> {
161
+ try {
162
+ return await getLoggedInUsername();
163
+ } catch {
164
+ return GuestUsername;
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Get remote CouchDB root database for authentication operations
170
+ */
171
+ private getRemoteCouchRootDB(): PouchDB.Database {
172
+ const remoteStr: string =
173
+ ENV.COUCHDB_SERVER_PROTOCOL + '://' + ENV.COUCHDB_SERVER_URL + 'skuilder';
174
+
175
+ try {
176
+ return new pouch(remoteStr, {
177
+ skip_setup: true,
178
+ });
179
+ } catch (error) {
180
+ logger.error('Failed to initialize remote CouchDB connection:', error);
181
+ throw new Error(`Failed to initialize CouchDB: ${JSON.stringify(error)}`);
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Get remote user database for a specific user
187
+ */
188
+ private getUserDB(username: string): PouchDB.Database {
189
+ const guestAccount: boolean = false;
190
+
191
+ const hexName = hexEncode(username);
192
+ const dbName = `userdb-${hexName}`;
193
+ log(`Fetching user database: ${dbName} (${username})`);
194
+
195
+ // Odd construction here the result of a bug in the
196
+ // interaction between pouch, pouch-auth.
197
+ // see: https://github.com/pouchdb-community/pouchdb-authentication/issues/239
198
+ const ret = new pouch(
199
+ ENV.COUCHDB_SERVER_PROTOCOL + '://' + ENV.COUCHDB_SERVER_URL + dbName,
200
+ pouchDBincludeCredentialsConfig
201
+ );
202
+
203
+ if (guestAccount) {
204
+ updateGuestAccountExpirationDate(ret);
205
+ }
206
+
207
+ return ret;
208
+ }
209
+ }
@@ -1,4 +1,4 @@
1
- // db/src/impl/pouch/PouchDataLayerProvider.ts
1
+ // db/src/impl/couch/PouchDataLayerProvider.ts
2
2
 
3
3
  import {
4
4
  AdminDBInterface,
@@ -16,9 +16,10 @@ import { AdminDB } from './adminDB';
16
16
  import { StudentClassroomDB, TeacherClassroomDB } from './classroomDB';
17
17
  import { CourseDB, CoursesDB } from './courseDB';
18
18
 
19
- import { User } from './userDB';
19
+ import { BaseUser } from '../common';
20
+ import { CouchDBSyncStrategy } from './CouchDBSyncStrategy';
20
21
 
21
- export class PouchDataLayerProvider implements DataLayerProvider {
22
+ export class CouchDataLayerProvider implements DataLayerProvider {
22
23
  private initialized: boolean = false;
23
24
  private userDB!: UserDBInterface;
24
25
  private currentUsername: string = '';
@@ -42,8 +43,11 @@ export class PouchDataLayerProvider implements DataLayerProvider {
42
43
 
43
44
  if (isNodeEnvironment) {
44
45
  logger.info(
45
- 'PouchDataLayerProvider: Running in Node.js environment, skipping user session check and user DB initialization.'
46
+ 'CouchDataLayerProvider: Running in Node.js environment, creating guest UserDB for testing.'
46
47
  );
48
+ // In Node.js (testing) environment, create a guest user instance
49
+ const syncStrategy = new CouchDBSyncStrategy();
50
+ this.userDB = await BaseUser.instance(syncStrategy);
47
51
  } else {
48
52
  // Assume browser-like environment, proceed with user session logic
49
53
  try {
@@ -53,13 +57,14 @@ export class PouchDataLayerProvider implements DataLayerProvider {
53
57
 
54
58
  // Create the user db instance if a username was found
55
59
  if (this.currentUsername) {
56
- this.userDB = await User.instance(this.currentUsername);
60
+ const syncStrategy = new CouchDBSyncStrategy();
61
+ this.userDB = await BaseUser.instance(syncStrategy, this.currentUsername);
57
62
  } else {
58
- logger.warn('PouchDataLayerProvider: No logged-in username found in session.');
63
+ logger.warn('CouchDataLayerProvider: No logged-in username found in session.');
59
64
  }
60
65
  } catch (error) {
61
66
  logger.error(
62
- 'PouchDataLayerProvider: Error during user session check or user DB initialization:',
67
+ 'CouchDataLayerProvider: Error during user session check or user DB initialization:',
63
68
  error
64
69
  );
65
70
  }
@@ -1,5 +1,5 @@
1
1
  import pouch from './pouchdb-setup';
2
- import { ENV } from '@/factory';
2
+ import { ENV } from '@db/factory';
3
3
  import {
4
4
  pouchDBincludeCredentialsConfig,
5
5
  getStartAndEndKeys,
@@ -9,9 +9,9 @@ import {
9
9
  import { TeacherClassroomDB, ClassroomLookupDB } from './classroomDB';
10
10
  import { PouchError } from './types';
11
11
 
12
- import { AdminDBInterface } from '@/core';
12
+ import { AdminDBInterface } from '@db/core';
13
13
  import CourseLookup from './courseLookupDB';
14
- import { logger } from '@/util/logger';
14
+ import { logger } from '@db/util/logger';
15
15
 
16
16
  export class AdminDB implements AdminDBInterface {
17
17
  private usersDB!: PouchDB.Database;
@@ -1,6 +1,6 @@
1
- import { ENV } from '@/factory';
1
+ import { ENV } from '@db/factory';
2
2
  import { GuestUsername } from '../../core/types/types-legacy';
3
- import { logger } from '@/util/logger';
3
+ import { logger } from '@db/util/logger';
4
4
 
5
5
  interface SessionResponse {
6
6
  info: unknown;
@@ -2,10 +2,10 @@ import {
2
2
  StudyContentSource,
3
3
  StudySessionNewItem,
4
4
  StudySessionReviewItem,
5
- } from '@/core/interfaces/contentSource';
5
+ } from '@db/core/interfaces/contentSource';
6
6
  import { ClassroomConfig } from '@vue-skuilder/common';
7
- import { ENV } from '@/factory';
8
- import { logger } from '@/util/logger';
7
+ import { ENV } from '@db/factory';
8
+ import { logger } from '@db/util/logger';
9
9
  import moment from 'moment';
10
10
  import pouch from './pouchdb-setup';
11
11
  import {
@@ -16,15 +16,15 @@ import {
16
16
  } from '.';
17
17
  import { CourseDB, getTag } from './courseDB';
18
18
 
19
- import { UserDBInterface } from '@/core';
19
+ import { UserDBInterface } from '@db/core';
20
20
  import {
21
21
  AssignedContent,
22
22
  AssignedCourse,
23
23
  AssignedTag,
24
24
  StudentClassroomDBInterface,
25
25
  TeacherClassroomDBInterface,
26
- } from '@/core/interfaces/classroomDB';
27
- import { ScheduledCard } from '@/core/types/user';
26
+ } from '@db/core/interfaces/classroomDB';
27
+ import { ScheduledCard } from '@db/core/types/user';
28
28
 
29
29
  const classroomLookupDBTitle = 'classdb-lookup';
30
30
  export const CLASSROOM_CONFIG = 'ClassroomConfig';