@vue-skuilder/db 0.2.18 → 0.2.20
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/{SyncStrategy-BJMZq3WO.d.cts → SyncStrategy-CCU1H81I.d.cts} +8 -2
- package/dist/{SyncStrategy-BJMZq3WO.d.ts → SyncStrategy-CCU1H81I.d.ts} +8 -2
- 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 +38 -7
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +38 -7
- 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 +20 -4
- package/dist/impl/couch/index.d.ts +20 -4
- package/dist/impl/couch/index.js +80 -11
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +80 -11
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +3 -3
- package/dist/impl/static/index.d.ts +3 -3
- package/dist/impl/static/index.js +38 -7
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +38 -7
- 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 +80 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +80 -11
- 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 +56 -8
- package/src/impl/common/SyncStrategy.ts +17 -4
- package/src/impl/couch/CouchDBSyncStrategy.ts +52 -4
- package/tests/impl/hydration.test.ts +49 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as ContentNavigator, R as ReplanHints, G as GeneratorResult } from '../../contentSource-
|
|
2
|
-
import { D as DataLayerProvider } from '../../dataLayerProvider-
|
|
1
|
+
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as ContentNavigator, R as ReplanHints, G as GeneratorResult } from '../../contentSource-D-LQYFyx.cjs';
|
|
2
|
+
import { D as DataLayerProvider } from '../../dataLayerProvider-Dd2UcCif.cjs';
|
|
3
3
|
import { S as StaticCourseManifest } from '../../types-BFUa1pa3.cjs';
|
|
4
4
|
import { CourseConfig, CourseElo, DataShape } from '@vue-skuilder/common';
|
|
5
5
|
import { S as SkuilderCourseData, Q as QualifiedCardID, T as TagStub, a as Tag } from '../../types-legacy-4tlwHnXo.cjs';
|
|
6
|
-
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-
|
|
6
|
+
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-CCU1H81I.cjs';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
9
9
|
interface SkuilderManifest {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as ContentNavigator, R as ReplanHints, G as GeneratorResult } from '../../contentSource-
|
|
2
|
-
import { D as DataLayerProvider } from '../../dataLayerProvider-
|
|
1
|
+
import { U as UserDBInterface, C as CourseDBInterface, b as CoursesDBInterface, c as ClassroomDBInterface, A as AdminDBInterface, a as UserDBReader, d as CourseInfo, S as StudySessionItem, D as DataLayerResult, e as ContentNavigationStrategyData, f as ContentNavigator, R as ReplanHints, G as GeneratorResult } from '../../contentSource-BDRX_YYJ.js';
|
|
2
|
+
import { D as DataLayerProvider } from '../../dataLayerProvider-Dpshuql4.js';
|
|
3
3
|
import { S as StaticCourseManifest } from '../../types-CHgpWQAY.js';
|
|
4
4
|
import { CourseConfig, CourseElo, DataShape } from '@vue-skuilder/common';
|
|
5
5
|
import { S as SkuilderCourseData, Q as QualifiedCardID, T as TagStub, a as Tag } from '../../types-legacy-4tlwHnXo.js';
|
|
6
|
-
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-
|
|
6
|
+
import { S as SyncStrategy, A as AccountCreationResult, a as AuthenticationResult } from '../../SyncStrategy-CCU1H81I.js';
|
|
7
7
|
import 'moment';
|
|
8
8
|
|
|
9
9
|
interface SkuilderManifest {
|
|
@@ -5624,16 +5624,44 @@ var init_BaseUserDB = __esm({
|
|
|
5624
5624
|
// Database to use for write operations (local-first approach)
|
|
5625
5625
|
updateQueue;
|
|
5626
5626
|
_hydration = { state: "not-required" };
|
|
5627
|
+
/** In-flight hydration, so concurrent callers can wait for a real answer. */
|
|
5628
|
+
_hydrationPromise = null;
|
|
5627
5629
|
/**
|
|
5628
|
-
*
|
|
5630
|
+
* Sequence the local mirror was filled to by a hydration that succeeded in
|
|
5631
|
+
* THIS init(), handed to startSync() so the live pull can skip history it
|
|
5632
|
+
* would otherwise re-walk. Undefined whenever there is no such guarantee —
|
|
5633
|
+
* hydration skipped, not required, or failed. Never persisted; see the
|
|
5634
|
+
* `since` note in CouchDBSyncStrategy.startSync().
|
|
5635
|
+
*/
|
|
5636
|
+
_hydratedSeq;
|
|
5637
|
+
/**
|
|
5638
|
+
* How far the local mirror can be trusted, RIGHT NOW. See
|
|
5639
|
+
* {@link UserHydrationStatus}.
|
|
5629
5640
|
*
|
|
5630
|
-
*
|
|
5631
|
-
*
|
|
5632
|
-
*
|
|
5641
|
+
* This is a snapshot, and during login it can legitimately read
|
|
5642
|
+
* `hydrating` — prefer awaitHydration() anywhere a decision hangs on the
|
|
5643
|
+
* answer.
|
|
5633
5644
|
*/
|
|
5634
5645
|
hydrationStatus() {
|
|
5635
5646
|
return { ...this._hydration };
|
|
5636
5647
|
}
|
|
5648
|
+
/**
|
|
5649
|
+
* The hydration status once it has settled — never `hydrating`.
|
|
5650
|
+
*
|
|
5651
|
+
* Resolves immediately unless a pull is in flight. Exists for callers that
|
|
5652
|
+
* must decide something (a route guard, a first-run branch) and would
|
|
5653
|
+
* otherwise sample `hydrating` and guess. Since init() is awaited by both
|
|
5654
|
+
* app startup and login(), that only happens when something navigates
|
|
5655
|
+
* concurrently with a login still in progress — a window that stretches to
|
|
5656
|
+
* HYDRATION_TIMEOUT_MS on a slow connection.
|
|
5657
|
+
*/
|
|
5658
|
+
async awaitHydration() {
|
|
5659
|
+
try {
|
|
5660
|
+
await this._hydrationPromise;
|
|
5661
|
+
} catch {
|
|
5662
|
+
}
|
|
5663
|
+
return this.hydrationStatus();
|
|
5664
|
+
}
|
|
5637
5665
|
/**
|
|
5638
5666
|
* Whether a missing document may be treated as genuinely absent, allowing
|
|
5639
5667
|
* callers to create it with defaults.
|
|
@@ -6090,8 +6118,9 @@ Currently logged-in as ${this._username}.`
|
|
|
6090
6118
|
}
|
|
6091
6119
|
this.syncStrategy.stopSync?.();
|
|
6092
6120
|
this.setDBandQ();
|
|
6093
|
-
|
|
6094
|
-
|
|
6121
|
+
this._hydrationPromise = this.hydrateLocalMirror();
|
|
6122
|
+
await this._hydrationPromise;
|
|
6123
|
+
this.syncStrategy.startSync(this.localDB, this.remoteDB, this._hydratedSeq);
|
|
6095
6124
|
this.applyDesignDocs().catch((error) => {
|
|
6096
6125
|
log3(`Error in applyDesignDocs background task: ${error}`);
|
|
6097
6126
|
if (error && typeof error === "object") {
|
|
@@ -6119,6 +6148,7 @@ Currently logged-in as ${this._username}.`
|
|
|
6119
6148
|
* ceiling). Callers decide what a failure means for them.
|
|
6120
6149
|
*/
|
|
6121
6150
|
async hydrateLocalMirror() {
|
|
6151
|
+
this._hydratedSeq = void 0;
|
|
6122
6152
|
if (this.localDB.name === this.remoteDB.name || !this.syncStrategy.hydrate) {
|
|
6123
6153
|
this._hydration = { state: "not-required" };
|
|
6124
6154
|
return;
|
|
@@ -6130,11 +6160,12 @@ Currently logged-in as ${this._username}.`
|
|
|
6130
6160
|
this._hydration = { state: "hydrating" };
|
|
6131
6161
|
const start = Date.now();
|
|
6132
6162
|
try {
|
|
6133
|
-
const { docsWritten } = await withTimeout(
|
|
6163
|
+
const { docsWritten, lastSeq } = await withTimeout(
|
|
6134
6164
|
this.syncStrategy.hydrate(this.localDB, this.remoteDB),
|
|
6135
6165
|
HYDRATION_TIMEOUT_MS,
|
|
6136
6166
|
`Hydration of local mirror for ${this._username}`
|
|
6137
6167
|
);
|
|
6168
|
+
this._hydratedSeq = lastSeq;
|
|
6138
6169
|
await this.writeHydrationMarker();
|
|
6139
6170
|
this._hydration = {
|
|
6140
6171
|
state: "hydrated",
|