@vue-skuilder/db 0.2.2 → 0.2.3
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-Ht3N2f-y.d.ts → contentSource-Cplhv3bJ.d.ts} +1 -1
- package/dist/{contentSource-BMlMwSiG.d.cts → contentSource-kI9_jwTu.d.cts} +1 -1
- package/dist/core/index.d.cts +5 -5
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +2 -1
- package/dist/core/index.mjs.map +1 -1
- package/dist/{dataLayerProvider-BEqB8VBR.d.cts → dataLayerProvider-CiA2Rr0v.d.cts} +1 -1
- package/dist/{dataLayerProvider-DObSXjnf.d.ts → dataLayerProvider-DrBqOUa3.d.ts} +1 -1
- package/dist/impl/couch/index.d.cts +3 -3
- package/dist/impl/couch/index.d.ts +3 -3
- package/dist/impl/couch/index.js +2 -1
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +2 -1
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.d.cts +4 -4
- package/dist/impl/static/index.d.ts +4 -4
- package/dist/impl/static/index.js +2 -1
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +2 -1
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/{index-BWvO-_rJ.d.ts → index-BLLT5BYE.d.ts} +1 -1
- package/dist/{index-Ba7hYbHj.d.cts → index-k9NFHpS1.d.cts} +1 -1
- package/dist/index.d.cts +164 -10
- package/dist/index.d.ts +164 -10
- package/dist/index.js +141 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -8
- package/dist/index.mjs.map +1 -1
- package/dist/{types-W8n-B6HG.d.cts → types-BFUa1pa3.d.cts} +1 -1
- package/dist/{types-CJrLM1Ew.d.ts → types-CHgpWQAY.d.ts} +1 -1
- package/dist/{types-legacy-JXDxinpU.d.cts → types-legacy-4tlwHnXo.d.cts} +1 -1
- package/dist/{types-legacy-JXDxinpU.d.ts → types-legacy-4tlwHnXo.d.ts} +1 -1
- package/dist/util/packer/index.d.cts +3 -3
- package/dist/util/packer/index.d.ts +3 -3
- package/package.json +3 -3
- package/src/core/navigators/Pipeline.ts +1 -1
- package/src/study/SessionController.ts +262 -13
package/dist/index.js
CHANGED
|
@@ -4207,7 +4207,8 @@ var init_orchestration = __esm({
|
|
|
4207
4207
|
// src/core/navigators/Pipeline.ts
|
|
4208
4208
|
var Pipeline_exports = {};
|
|
4209
4209
|
__export(Pipeline_exports, {
|
|
4210
|
-
Pipeline: () => Pipeline
|
|
4210
|
+
Pipeline: () => Pipeline,
|
|
4211
|
+
mergeHints: () => mergeHints2
|
|
4211
4212
|
});
|
|
4212
4213
|
function globToRegex(pattern) {
|
|
4213
4214
|
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -11344,6 +11345,7 @@ var ItemQueue = class {
|
|
|
11344
11345
|
|
|
11345
11346
|
// src/study/SessionController.ts
|
|
11346
11347
|
init_couch();
|
|
11348
|
+
init_core();
|
|
11347
11349
|
init_recording();
|
|
11348
11350
|
|
|
11349
11351
|
// src/util/index.ts
|
|
@@ -12770,6 +12772,7 @@ init_dataDirectory();
|
|
|
12770
12772
|
|
|
12771
12773
|
// src/study/SessionController.ts
|
|
12772
12774
|
init_navigators();
|
|
12775
|
+
init_Pipeline();
|
|
12773
12776
|
|
|
12774
12777
|
// src/study/SourceMixer.ts
|
|
12775
12778
|
var QuotaRoundRobinMixer = class {
|
|
@@ -13481,6 +13484,32 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13481
13484
|
* each nextCard() draw. Set by replans that include `minFollowUpCards`.
|
|
13482
13485
|
*/
|
|
13483
13486
|
_minCardsGuarantee = 0;
|
|
13487
|
+
/**
|
|
13488
|
+
* Session-durable scoring hints. Re-merged into every pipeline run for
|
|
13489
|
+
* the rest of the session (initial plan + every replan, including bare
|
|
13490
|
+
* auto-replans and the wedge-breaker), via `_applyHintsToSources`.
|
|
13491
|
+
*
|
|
13492
|
+
* Set by `setSessionHints()` (e.g. session-start post-lesson boost) or by
|
|
13493
|
+
* any replan carrying `ReplanOptions.sessionHints` (e.g. a just-failed
|
|
13494
|
+
* concept boost). Replace semantics, no decay — lives until overwritten
|
|
13495
|
+
* or session end. See `ReplanOptions.sessionHints` for rationale.
|
|
13496
|
+
*
|
|
13497
|
+
* Note: the controller-managed auto-excludes (current card, session
|
|
13498
|
+
* record, imminent draw) are intentionally NOT folded in here — those are
|
|
13499
|
+
* recomputed per-run in `_runReplan` and would otherwise go stale.
|
|
13500
|
+
*/
|
|
13501
|
+
_sessionHints = null;
|
|
13502
|
+
/**
|
|
13503
|
+
* Consumer-supplied hooks invoked after each question response is processed.
|
|
13504
|
+
* Seeded from constructor options (threaded from
|
|
13505
|
+
* `StudySessionConfig.outcomeObservers`). See {@link OutcomeObserver}.
|
|
13506
|
+
*/
|
|
13507
|
+
_outcomeObservers = [];
|
|
13508
|
+
/**
|
|
13509
|
+
* Lazily-built, stable capability object handed to observers. Bound to
|
|
13510
|
+
* `this`; constructed once so observers can rely on referential identity.
|
|
13511
|
+
*/
|
|
13512
|
+
_sessionControls = null;
|
|
13484
13513
|
startTime;
|
|
13485
13514
|
endTime;
|
|
13486
13515
|
_secondsRemaining;
|
|
@@ -13540,6 +13569,9 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13540
13569
|
if (options?.initialReviewCap !== void 0) {
|
|
13541
13570
|
this._initialReviewCap = options.initialReviewCap;
|
|
13542
13571
|
}
|
|
13572
|
+
if (options?.outcomeObservers?.length) {
|
|
13573
|
+
this._outcomeObservers = [...options.outcomeObservers];
|
|
13574
|
+
}
|
|
13543
13575
|
this.log(`Session constructed:
|
|
13544
13576
|
startTime: ${this.startTime}
|
|
13545
13577
|
endTime: ${this.endTime}
|
|
@@ -13667,6 +13699,7 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13667
13699
|
if (opts.minFollowUpCards !== void 0) return true;
|
|
13668
13700
|
if (opts.mode && opts.mode !== "replace") return true;
|
|
13669
13701
|
if (opts.hints && Object.keys(opts.hints).length > 0) return true;
|
|
13702
|
+
if (opts.sessionHints !== void 0) return true;
|
|
13670
13703
|
return false;
|
|
13671
13704
|
}
|
|
13672
13705
|
/**
|
|
@@ -13695,12 +13728,13 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13695
13728
|
excludeSet.add(this.newQ.peek(0).cardID);
|
|
13696
13729
|
}
|
|
13697
13730
|
hints.excludeCards = [...excludeSet];
|
|
13698
|
-
if (opts.
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13731
|
+
if (opts.sessionHints !== void 0) {
|
|
13732
|
+
this._sessionHints = opts.sessionHints;
|
|
13733
|
+
this.log(
|
|
13734
|
+
`[Replan] Session hints ${opts.sessionHints ? "set" : "cleared"}: ${JSON.stringify(opts.sessionHints)}`
|
|
13735
|
+
);
|
|
13703
13736
|
}
|
|
13737
|
+
this._applyHintsToSources(opts.hints, opts.label);
|
|
13704
13738
|
const labelTag = opts.label ? ` [${opts.label}]` : "";
|
|
13705
13739
|
this.log(
|
|
13706
13740
|
`Mid-session replan requested${labelTag} (limit: ${opts.limit ?? "default"}, mode: ${opts.mode ?? "replace"}${opts.hints ? ", with hints" : ""})`
|
|
@@ -13711,6 +13745,100 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13711
13745
|
}
|
|
13712
13746
|
await this._executeReplan(opts);
|
|
13713
13747
|
}
|
|
13748
|
+
/**
|
|
13749
|
+
* Set the session-durable scoring hints (replace semantics, no decay).
|
|
13750
|
+
*
|
|
13751
|
+
* Unlike a one-shot replan hint, these are re-merged into every pipeline
|
|
13752
|
+
* run for the rest of the session — including the initial plan when set
|
|
13753
|
+
* before `prepareSession()`, every replan, the bare auto-replans, and the
|
|
13754
|
+
* wedge-breaker. Pass `null` to clear.
|
|
13755
|
+
*
|
|
13756
|
+
* Typical callers:
|
|
13757
|
+
* - `StudySession` at session start, threading `StudySessionConfig.initHints`
|
|
13758
|
+
* (e.g. a post-lesson concept boost) — so the boost outlives the first
|
|
13759
|
+
* queue rebuild instead of being clobbered by the first auto-replan.
|
|
13760
|
+
* - A consumer view on a failure, boosting the just-failed concept tag.
|
|
13761
|
+
*
|
|
13762
|
+
* Does not itself trigger a replan; the next plan/replan picks it up.
|
|
13763
|
+
*/
|
|
13764
|
+
setSessionHints(hints) {
|
|
13765
|
+
this._sessionHints = hints;
|
|
13766
|
+
this.log(`Session hints ${hints ? "set" : "cleared"}: ${JSON.stringify(hints)}`);
|
|
13767
|
+
}
|
|
13768
|
+
/**
|
|
13769
|
+
* Read the current session-durable hints (for read-modify-write callers,
|
|
13770
|
+
* e.g. an outcome observer that clamps a compounding boost).
|
|
13771
|
+
*/
|
|
13772
|
+
getSessionHints() {
|
|
13773
|
+
return this._sessionHints;
|
|
13774
|
+
}
|
|
13775
|
+
/**
|
|
13776
|
+
* Merge `hints` into the durable session hints via the pipeline's
|
|
13777
|
+
* `mergeHints` (boosts multiply, require/exclude lists concat-dedup).
|
|
13778
|
+
* Convenience over get-then-set for the common additive case. Note the
|
|
13779
|
+
* multiplicative, no-decay semantics — clamp boost factors at the call
|
|
13780
|
+
* site if a repeatedly-emphasised tag could compound unboundedly.
|
|
13781
|
+
*/
|
|
13782
|
+
mergeSessionHints(hints) {
|
|
13783
|
+
this._sessionHints = mergeHints2([this._sessionHints, hints]) ?? null;
|
|
13784
|
+
this.log(`Session hints merged: ${JSON.stringify(this._sessionHints)}`);
|
|
13785
|
+
}
|
|
13786
|
+
/**
|
|
13787
|
+
* Merge the durable `_sessionHints` with this run's one-shot hints and
|
|
13788
|
+
* push the result to every source for consumption on the next pipeline
|
|
13789
|
+
* run. Centralised so the initial plan and all replan paths apply session
|
|
13790
|
+
* emphasis identically. No-op when there are no hints of either kind.
|
|
13791
|
+
*/
|
|
13792
|
+
_applyHintsToSources(oneShot, label) {
|
|
13793
|
+
const oneShotWithLabel = oneShot && label ? { ...oneShot, _label: label } : oneShot;
|
|
13794
|
+
const merged = mergeHints2([this._sessionHints, oneShotWithLabel]);
|
|
13795
|
+
if (!merged) return;
|
|
13796
|
+
for (const source of this.sources) {
|
|
13797
|
+
source.setEphemeralHints?.(merged);
|
|
13798
|
+
}
|
|
13799
|
+
}
|
|
13800
|
+
/**
|
|
13801
|
+
* Build (once) the stable capability object handed to outcome observers.
|
|
13802
|
+
* Methods are bound to `this`; the object identity is stable across calls
|
|
13803
|
+
* so observers may key off it.
|
|
13804
|
+
*/
|
|
13805
|
+
_getSessionControls() {
|
|
13806
|
+
if (!this._sessionControls) {
|
|
13807
|
+
this._sessionControls = {
|
|
13808
|
+
getSessionHints: () => this.getSessionHints(),
|
|
13809
|
+
setSessionHints: (h) => this.setSessionHints(h),
|
|
13810
|
+
mergeSessionHints: (h) => this.mergeSessionHints(h),
|
|
13811
|
+
requestReplan: (opts) => this.requestReplan(opts)
|
|
13812
|
+
};
|
|
13813
|
+
}
|
|
13814
|
+
return this._sessionControls;
|
|
13815
|
+
}
|
|
13816
|
+
/**
|
|
13817
|
+
* Notify registered outcome observers about a processed response.
|
|
13818
|
+
*
|
|
13819
|
+
* Only question records are surfaced (non-question dismisses are skipped).
|
|
13820
|
+
* Observers run after ELO/SRS are recorded and before navigation. Each is
|
|
13821
|
+
* awaited but isolated in try/catch — a throwing observer is logged and
|
|
13822
|
+
* skipped, never wedging the session. Keep observers cheap and `void` any
|
|
13823
|
+
* long work (e.g. a triggered replan) to avoid stalling the draw.
|
|
13824
|
+
*/
|
|
13825
|
+
async _notifyOutcomeObservers(record, currentCard, result) {
|
|
13826
|
+
if (this._outcomeObservers.length === 0) return;
|
|
13827
|
+
if (!isQuestionRecord(record)) return;
|
|
13828
|
+
const outcome = {
|
|
13829
|
+
record,
|
|
13830
|
+
card: currentCard.card,
|
|
13831
|
+
result
|
|
13832
|
+
};
|
|
13833
|
+
const controls = this._getSessionControls();
|
|
13834
|
+
for (const observer of this._outcomeObservers) {
|
|
13835
|
+
try {
|
|
13836
|
+
await observer(outcome, controls);
|
|
13837
|
+
} catch (e) {
|
|
13838
|
+
this.error("[OutcomeObserver] observer threw; ignoring", e);
|
|
13839
|
+
}
|
|
13840
|
+
}
|
|
13841
|
+
}
|
|
13714
13842
|
/**
|
|
13715
13843
|
* Run a replan, bypassing requestReplan()'s coalesce logic.
|
|
13716
13844
|
*
|
|
@@ -13738,7 +13866,7 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13738
13866
|
*/
|
|
13739
13867
|
normalizeReplanOptions(input) {
|
|
13740
13868
|
if (!input) return {};
|
|
13741
|
-
const replanKeys = ["hints", "limit", "mode", "label", "minFollowUpCards"];
|
|
13869
|
+
const replanKeys = ["hints", "sessionHints", "limit", "mode", "label", "minFollowUpCards"];
|
|
13742
13870
|
const inputKeys = Object.keys(input);
|
|
13743
13871
|
if (inputKeys.some((k) => replanKeys.includes(k))) {
|
|
13744
13872
|
return input;
|
|
@@ -13890,6 +14018,9 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
13890
14018
|
const additive = options?.additive ?? false;
|
|
13891
14019
|
const newLimit = options?.limit ?? this._defaultBatchLimit;
|
|
13892
14020
|
const fetchLimit = replan ? newLimit : newLimit + this._initialReviewCap;
|
|
14021
|
+
if (!replan) {
|
|
14022
|
+
this._applyHintsToSources();
|
|
14023
|
+
}
|
|
13893
14024
|
const batches = [];
|
|
13894
14025
|
for (let i = 0; i < this.sources.length; i++) {
|
|
13895
14026
|
const source = this.sources[i];
|
|
@@ -14170,7 +14301,7 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
14170
14301
|
const studySessionItem = {
|
|
14171
14302
|
...currentCard.item
|
|
14172
14303
|
};
|
|
14173
|
-
|
|
14304
|
+
const result = await this.services.response.processResponse(
|
|
14174
14305
|
cardRecord,
|
|
14175
14306
|
cardHistory,
|
|
14176
14307
|
studySessionItem,
|
|
@@ -14182,6 +14313,8 @@ var SessionController = class _SessionController extends Loggable {
|
|
|
14182
14313
|
maxSessionViews,
|
|
14183
14314
|
sessionViews
|
|
14184
14315
|
);
|
|
14316
|
+
await this._notifyOutcomeObservers(cardRecord, currentCard, result);
|
|
14317
|
+
return result;
|
|
14185
14318
|
}
|
|
14186
14319
|
dismissCurrentCard(action = "dismiss-success") {
|
|
14187
14320
|
if (this._currentCard) {
|