@vue-skuilder/db 0.2.18 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{contentSource-CudEz5Tm.d.ts → contentSource-BDRX_YYJ.d.ts} +13 -1
- package/dist/{contentSource-CBqZCoGU.d.cts → contentSource-D-LQYFyx.d.cts} +13 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +26 -5
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +26 -5
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-BBA8tJNx.d.cts → dataLayerProvider-Dd2UcCif.d.cts} +1 -1
- package/dist/{dataLayerProvider-C9WgkBzR.d.ts → dataLayerProvider-Dpshuql4.d.ts} +1 -1
- package/dist/impl/couch/index.d.cts +2 -2
- package/dist/impl/couch/index.d.ts +2 -2
- package/dist/impl/couch/index.js +26 -5
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +26 -5
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +2 -2
- package/dist/impl/static/index.d.ts +2 -2
- package/dist/impl/static/index.js +26 -5
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +26 -5
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +26 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +26 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/core/interfaces/userDB.ts +14 -1
- package/src/impl/common/BaseUserDB.ts +36 -5
- package/tests/impl/hydration.test.ts +49 -0
|
@@ -514,14 +514,26 @@ interface UserDBReader {
|
|
|
514
514
|
getUsername(): string;
|
|
515
515
|
isLoggedIn(): boolean;
|
|
516
516
|
/**
|
|
517
|
-
* How far this device's local mirror of the user's data can be trusted
|
|
517
|
+
* How far this device's local mirror of the user's data can be trusted,
|
|
518
|
+
* as of right now.
|
|
518
519
|
*
|
|
519
520
|
* Reads answer from the local mirror, so on a device that has never synced
|
|
520
521
|
* this account "document not found" does not mean "no such data". Anything
|
|
521
522
|
* that would otherwise interpret an empty read as a new user should check
|
|
522
523
|
* for `failed` first. See {@link UserHydrationStatus}.
|
|
524
|
+
*
|
|
525
|
+
* Can return `hydrating`; use {@link awaitHydration} to decide on a settled
|
|
526
|
+
* answer instead of a snapshot.
|
|
523
527
|
*/
|
|
524
528
|
hydrationStatus(): UserHydrationStatus;
|
|
529
|
+
/**
|
|
530
|
+
* The hydration status once settled — never `hydrating`.
|
|
531
|
+
*
|
|
532
|
+
* Resolves immediately unless a pull is in flight. Prefer this over
|
|
533
|
+
* hydrationStatus() wherever the answer gates behaviour, such as a route
|
|
534
|
+
* guard that may run while a login is still completing.
|
|
535
|
+
*/
|
|
536
|
+
awaitHydration(): Promise<UserHydrationStatus>;
|
|
525
537
|
/**
|
|
526
538
|
* Get user configuration
|
|
527
539
|
*/
|
|
@@ -514,14 +514,26 @@ interface UserDBReader {
|
|
|
514
514
|
getUsername(): string;
|
|
515
515
|
isLoggedIn(): boolean;
|
|
516
516
|
/**
|
|
517
|
-
* How far this device's local mirror of the user's data can be trusted
|
|
517
|
+
* How far this device's local mirror of the user's data can be trusted,
|
|
518
|
+
* as of right now.
|
|
518
519
|
*
|
|
519
520
|
* Reads answer from the local mirror, so on a device that has never synced
|
|
520
521
|
* this account "document not found" does not mean "no such data". Anything
|
|
521
522
|
* that would otherwise interpret an empty read as a new user should check
|
|
522
523
|
* for `failed` first. See {@link UserHydrationStatus}.
|
|
524
|
+
*
|
|
525
|
+
* Can return `hydrating`; use {@link awaitHydration} to decide on a settled
|
|
526
|
+
* answer instead of a snapshot.
|
|
523
527
|
*/
|
|
524
528
|
hydrationStatus(): UserHydrationStatus;
|
|
529
|
+
/**
|
|
530
|
+
* The hydration status once settled — never `hydrating`.
|
|
531
|
+
*
|
|
532
|
+
* Resolves immediately unless a pull is in flight. Prefer this over
|
|
533
|
+
* hydrationStatus() wherever the answer gates behaviour, such as a route
|
|
534
|
+
* guard that may run while a login is still completing.
|
|
535
|
+
*/
|
|
536
|
+
awaitHydration(): Promise<UserHydrationStatus>;
|
|
525
537
|
/**
|
|
526
538
|
* Get user configuration
|
|
527
539
|
*/
|
package/dist/core/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ab as LearnableWeight, M as UserOutcomeRecord, ac as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface, R as ReplanHints, a1 as StrategyContribution } from '../contentSource-
|
|
2
|
-
export { K as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, a8 as CardGenerator, aa as CardGeneratorFactory, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, H as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, L as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, a9 as GeneratorContext, G as GeneratorResult, P as HYDRATION_MARKER_ID, Q as HydrationMarker, V as NavigatorConstructor, a4 as NavigatorRole, a5 as NavigatorRoles, a3 as Navigators, j as ScheduledCard, I as SessionTrackingData, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, J as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, N as UserHydrationState, O as UserHydrationStatus, B as UsrCrsDataInterface, ad as computeDeviation, af as computeEffectiveWeight, ae as computeSpread, ag as createOrchestrationContext, a2 as getCardOrigin, Y as getRegisteredNavigator, $ as getRegisteredNavigatorNames, _ as getRegisteredNavigatorRole, r as getStudySource, Z as hasRegisteredNavigator, a0 as initializeNavigatorRegistry, a7 as isFilter, a6 as isGenerator, p as isReview, X as registerNavigator } from '../contentSource-
|
|
3
|
-
export { D as DataLayerProvider } from '../dataLayerProvider-
|
|
1
|
+
import { ab as LearnableWeight, M as UserOutcomeRecord, ac as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface, R as ReplanHints, a1 as StrategyContribution } from '../contentSource-D-LQYFyx.cjs';
|
|
2
|
+
export { K as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, a8 as CardGenerator, aa as CardGeneratorFactory, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, H as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, L as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, a9 as GeneratorContext, G as GeneratorResult, P as HYDRATION_MARKER_ID, Q as HydrationMarker, V as NavigatorConstructor, a4 as NavigatorRole, a5 as NavigatorRoles, a3 as Navigators, j as ScheduledCard, I as SessionTrackingData, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, J as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, N as UserHydrationState, O as UserHydrationStatus, B as UsrCrsDataInterface, ad as computeDeviation, af as computeEffectiveWeight, ae as computeSpread, ag as createOrchestrationContext, a2 as getCardOrigin, Y as getRegisteredNavigator, $ as getRegisteredNavigatorNames, _ as getRegisteredNavigatorRole, r as getStudySource, Z as hasRegisteredNavigator, a0 as initializeNavigatorRegistry, a7 as isFilter, a6 as isGenerator, p as isReview, X as registerNavigator } from '../contentSource-D-LQYFyx.cjs';
|
|
3
|
+
export { D as DataLayerProvider } from '../dataLayerProvider-Dd2UcCif.cjs';
|
|
4
4
|
import { D as DocType, d as QuestionRecord, b as DocTypePrefixes, C as CardHistory, c as CardRecord } from '../types-legacy-4tlwHnXo.cjs';
|
|
5
5
|
export { e as CardData, f as CourseListData, h as DataShapeData, g as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, i as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-4tlwHnXo.cjs';
|
|
6
6
|
import { DataShape, ParsedCard } from '@vue-skuilder/common';
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ab as LearnableWeight, M as UserOutcomeRecord, ac as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface, R as ReplanHints, a1 as StrategyContribution } from '../contentSource-
|
|
2
|
-
export { K as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, a8 as CardGenerator, aa as CardGeneratorFactory, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, H as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, L as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, a9 as GeneratorContext, G as GeneratorResult, P as HYDRATION_MARKER_ID, Q as HydrationMarker, V as NavigatorConstructor, a4 as NavigatorRole, a5 as NavigatorRoles, a3 as Navigators, j as ScheduledCard, I as SessionTrackingData, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, J as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, N as UserHydrationState, O as UserHydrationStatus, B as UsrCrsDataInterface, ad as computeDeviation, af as computeEffectiveWeight, ae as computeSpread, ag as createOrchestrationContext, a2 as getCardOrigin, Y as getRegisteredNavigator, $ as getRegisteredNavigatorNames, _ as getRegisteredNavigatorRole, r as getStudySource, Z as hasRegisteredNavigator, a0 as initializeNavigatorRegistry, a7 as isFilter, a6 as isGenerator, p as isReview, X as registerNavigator } from '../contentSource-
|
|
3
|
-
export { D as DataLayerProvider } from '../dataLayerProvider-
|
|
1
|
+
import { ab as LearnableWeight, M as UserOutcomeRecord, ac as OrchestrationContext, W as WeightedCard, U as UserDBInterface, C as CourseDBInterface, R as ReplanHints, a1 as StrategyContribution } from '../contentSource-BDRX_YYJ.js';
|
|
2
|
+
export { K as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, a8 as CardGenerator, aa as CardGeneratorFactory, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, H as ClassroomRegistrationDoc, e as ContentNavigationStrategyData, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, L as CourseRegistration, s as CourseRegistrationDoc, b as CoursesDBInterface, a9 as GeneratorContext, G as GeneratorResult, P as HYDRATION_MARKER_ID, Q as HydrationMarker, V as NavigatorConstructor, a4 as NavigatorRole, a5 as NavigatorRoles, a3 as Navigators, j as ScheduledCard, I as SessionTrackingData, i as StudentClassroomDBInterface, h as StudyContentSource, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, S as StudySessionItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, J as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, N as UserHydrationState, O as UserHydrationStatus, B as UsrCrsDataInterface, ad as computeDeviation, af as computeEffectiveWeight, ae as computeSpread, ag as createOrchestrationContext, a2 as getCardOrigin, Y as getRegisteredNavigator, $ as getRegisteredNavigatorNames, _ as getRegisteredNavigatorRole, r as getStudySource, Z as hasRegisteredNavigator, a0 as initializeNavigatorRegistry, a7 as isFilter, a6 as isGenerator, p as isReview, X as registerNavigator } from '../contentSource-BDRX_YYJ.js';
|
|
3
|
+
export { D as DataLayerProvider } from '../dataLayerProvider-Dpshuql4.js';
|
|
4
4
|
import { D as DocType, d as QuestionRecord, b as DocTypePrefixes, C as CardHistory, c as CardRecord } from '../types-legacy-4tlwHnXo.js';
|
|
5
5
|
export { e as CardData, f as CourseListData, h as DataShapeData, g as DisplayableData, F as Field, G as GuestUsername, Q as QualifiedCardID, i as QuestionData, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from '../types-legacy-4tlwHnXo.js';
|
|
6
6
|
import { DataShape, ParsedCard } from '@vue-skuilder/common';
|
package/dist/core/index.js
CHANGED
|
@@ -6919,16 +6919,36 @@ var init_BaseUserDB = __esm({
|
|
|
6919
6919
|
// Database to use for write operations (local-first approach)
|
|
6920
6920
|
updateQueue;
|
|
6921
6921
|
_hydration = { state: "not-required" };
|
|
6922
|
+
/** In-flight hydration, so concurrent callers can wait for a real answer. */
|
|
6923
|
+
_hydrationPromise = null;
|
|
6922
6924
|
/**
|
|
6923
|
-
* How far the local mirror can be trusted. See
|
|
6925
|
+
* How far the local mirror can be trusted, RIGHT NOW. See
|
|
6926
|
+
* {@link UserHydrationStatus}.
|
|
6924
6927
|
*
|
|
6925
|
-
*
|
|
6926
|
-
*
|
|
6927
|
-
*
|
|
6928
|
+
* This is a snapshot, and during login it can legitimately read
|
|
6929
|
+
* `hydrating` — prefer awaitHydration() anywhere a decision hangs on the
|
|
6930
|
+
* answer.
|
|
6928
6931
|
*/
|
|
6929
6932
|
hydrationStatus() {
|
|
6930
6933
|
return { ...this._hydration };
|
|
6931
6934
|
}
|
|
6935
|
+
/**
|
|
6936
|
+
* The hydration status once it has settled — never `hydrating`.
|
|
6937
|
+
*
|
|
6938
|
+
* Resolves immediately unless a pull is in flight. Exists for callers that
|
|
6939
|
+
* must decide something (a route guard, a first-run branch) and would
|
|
6940
|
+
* otherwise sample `hydrating` and guess. Since init() is awaited by both
|
|
6941
|
+
* app startup and login(), that only happens when something navigates
|
|
6942
|
+
* concurrently with a login still in progress — a window that stretches to
|
|
6943
|
+
* HYDRATION_TIMEOUT_MS on a slow connection.
|
|
6944
|
+
*/
|
|
6945
|
+
async awaitHydration() {
|
|
6946
|
+
try {
|
|
6947
|
+
await this._hydrationPromise;
|
|
6948
|
+
} catch {
|
|
6949
|
+
}
|
|
6950
|
+
return this.hydrationStatus();
|
|
6951
|
+
}
|
|
6932
6952
|
/**
|
|
6933
6953
|
* Whether a missing document may be treated as genuinely absent, allowing
|
|
6934
6954
|
* callers to create it with defaults.
|
|
@@ -7385,7 +7405,8 @@ Currently logged-in as ${this._username}.`
|
|
|
7385
7405
|
}
|
|
7386
7406
|
this.syncStrategy.stopSync?.();
|
|
7387
7407
|
this.setDBandQ();
|
|
7388
|
-
|
|
7408
|
+
this._hydrationPromise = this.hydrateLocalMirror();
|
|
7409
|
+
await this._hydrationPromise;
|
|
7389
7410
|
this.syncStrategy.startSync(this.localDB, this.remoteDB);
|
|
7390
7411
|
this.applyDesignDocs().catch((error) => {
|
|
7391
7412
|
log3(`Error in applyDesignDocs background task: ${error}`);
|