@vue-skuilder/db 0.1.25 → 0.1.27
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/core/index.d.cts +51 -1
- package/dist/core/index.d.ts +51 -1
- package/dist/core/index.js +337 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +335 -2
- package/dist/core/index.mjs.map +1 -1
- package/dist/impl/couch/index.js +367 -20
- package/dist/impl/couch/index.js.map +1 -1
- package/dist/impl/couch/index.mjs +367 -20
- package/dist/impl/couch/index.mjs.map +1 -1
- package/dist/impl/static/index.js +358 -4
- package/dist/impl/static/index.js.map +1 -1
- package/dist/impl/static/index.mjs +358 -4
- package/dist/impl/static/index.mjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +337 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +335 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/core/UserDBDebugger.ts +466 -0
- package/src/core/index.ts +3 -0
- package/src/core/navigators/filters/hierarchyDefinition.ts +4 -3
package/dist/index.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ import { D as DataLayerProvider } from './dataLayerProvider-BeRXVMs5.cjs';
|
|
|
4
4
|
import { C as CardHistory, c as CardRecord } from './types-legacy-JXDxinpU.cjs';
|
|
5
5
|
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, i as QuestionRecord, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-JXDxinpU.cjs';
|
|
6
6
|
import { Loggable } from './core/index.cjs';
|
|
7
|
-
export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, FilterImpact, GeneratorContext, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, validateProcessorConfig } from './core/index.cjs';
|
|
7
|
+
export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, FilterImpact, GeneratorContext, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, mountUserDBDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, userDBDebugAPI, validateProcessorConfig } from './core/index.cjs';
|
|
8
8
|
import { TaggedPerformance, TagFilter, DataShape, CourseConfig } from '@vue-skuilder/common';
|
|
9
9
|
import { S as StaticCourseManifest } from './types-W8n-B6HG.cjs';
|
|
10
10
|
export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-W8n-B6HG.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { D as DataLayerProvider } from './dataLayerProvider-CG9GfaAY.js';
|
|
|
4
4
|
import { C as CardHistory, c as CardRecord } from './types-legacy-JXDxinpU.js';
|
|
5
5
|
export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, i as QuestionRecord, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-JXDxinpU.js';
|
|
6
6
|
import { Loggable } from './core/index.js';
|
|
7
|
-
export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, FilterImpact, GeneratorContext, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, validateProcessorConfig } from './core/index.js';
|
|
7
|
+
export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, FilterImpact, GeneratorContext, GeneratorSummary, GradientObservation, GradientResult, ImportResult, PeriodUpdateInput, PeriodUpdateResult, PipelineRunReport, SignalConfig, StrategyLearningState, StrategyStateDoc, StrategyStateId, aggregateOutcomesForGradient, areQuestionRecords, buildStrategyStateId, computeOutcomeSignal, computeStrategyGradient, docIsDeleted, getCardHistoryID, getDefaultLearnableWeight, importParsedCards, isQuestionRecord, mountPipelineDebugger, mountUserDBDebugger, parseCardHistoryID, pipelineDebugAPI, recordUserOutcome, runPeriodUpdate, scoreAccuracyInZone, updateLearningState, updateStrategyWeight, userDBDebugAPI, validateProcessorConfig } from './core/index.js';
|
|
8
8
|
import { TaggedPerformance, TagFilter, DataShape, CourseConfig } from '@vue-skuilder/common';
|
|
9
9
|
import { S as StaticCourseManifest } from './types-CJrLM1Ew.js';
|
|
10
10
|
export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-CJrLM1Ew.js';
|
package/dist/index.js
CHANGED
|
@@ -1895,7 +1895,7 @@ var init_hierarchyDefinition = __esm({
|
|
|
1895
1895
|
/**
|
|
1896
1896
|
* CardFilter.transform implementation.
|
|
1897
1897
|
*
|
|
1898
|
-
* Apply prerequisite gating to cards. Cards with locked tags receive score
|
|
1898
|
+
* Apply prerequisite gating to cards. Cards with locked tags receive score * 0.01.
|
|
1899
1899
|
*/
|
|
1900
1900
|
async transform(cards, context) {
|
|
1901
1901
|
const masteredTags = await this.getMasteredTags(context);
|
|
@@ -1908,7 +1908,8 @@ var init_hierarchyDefinition = __esm({
|
|
|
1908
1908
|
unlockedTags,
|
|
1909
1909
|
masteredTags
|
|
1910
1910
|
);
|
|
1911
|
-
const
|
|
1911
|
+
const LOCKED_PENALTY = 0.01;
|
|
1912
|
+
const finalScore = isUnlocked ? card.score : card.score * LOCKED_PENALTY;
|
|
1912
1913
|
const action = isUnlocked ? "passed" : "penalized";
|
|
1913
1914
|
gated.push({
|
|
1914
1915
|
...card,
|
|
@@ -7608,6 +7609,335 @@ var init_bulkImport = __esm({
|
|
|
7608
7609
|
}
|
|
7609
7610
|
});
|
|
7610
7611
|
|
|
7612
|
+
// src/core/UserDBDebugger.ts
|
|
7613
|
+
function getUserDB() {
|
|
7614
|
+
try {
|
|
7615
|
+
const provider = getDataLayer();
|
|
7616
|
+
return provider.getUserDB();
|
|
7617
|
+
} catch {
|
|
7618
|
+
logger.info("[UserDB Debug] Data layer not initialized yet.");
|
|
7619
|
+
return null;
|
|
7620
|
+
}
|
|
7621
|
+
}
|
|
7622
|
+
function getRawDB() {
|
|
7623
|
+
const userDB = getUserDB();
|
|
7624
|
+
if (!userDB) return null;
|
|
7625
|
+
const rawDB = userDB.localDB;
|
|
7626
|
+
if (!rawDB) {
|
|
7627
|
+
logger.info("[UserDB Debug] Unable to access raw database instance.");
|
|
7628
|
+
return null;
|
|
7629
|
+
}
|
|
7630
|
+
return rawDB;
|
|
7631
|
+
}
|
|
7632
|
+
function formatTimestamp(isoString) {
|
|
7633
|
+
const date = new Date(isoString);
|
|
7634
|
+
return date.toLocaleString();
|
|
7635
|
+
}
|
|
7636
|
+
function mountUserDBDebugger() {
|
|
7637
|
+
if (typeof window === "undefined") return;
|
|
7638
|
+
const win = window;
|
|
7639
|
+
win.skuilder = win.skuilder || {};
|
|
7640
|
+
win.skuilder.userdb = userDBDebugAPI;
|
|
7641
|
+
}
|
|
7642
|
+
var userDBDebugAPI;
|
|
7643
|
+
var init_UserDBDebugger = __esm({
|
|
7644
|
+
"src/core/UserDBDebugger.ts"() {
|
|
7645
|
+
"use strict";
|
|
7646
|
+
init_logger();
|
|
7647
|
+
init_factory();
|
|
7648
|
+
init_types_legacy();
|
|
7649
|
+
init_userDBHelpers();
|
|
7650
|
+
userDBDebugAPI = {
|
|
7651
|
+
/**
|
|
7652
|
+
* Show current user information
|
|
7653
|
+
*/
|
|
7654
|
+
showUser() {
|
|
7655
|
+
const userDB = getUserDB();
|
|
7656
|
+
if (!userDB) return;
|
|
7657
|
+
console.group("\u{1F464} User Information");
|
|
7658
|
+
logger.info(`Username: ${userDB.getUsername()}`);
|
|
7659
|
+
logger.info(`Logged in: ${userDB.isLoggedIn() ? "Yes \u2705" : "No (Guest) \u274C"}`);
|
|
7660
|
+
userDB.getConfig().then((config) => {
|
|
7661
|
+
logger.info("Configuration:");
|
|
7662
|
+
logger.info(JSON.stringify(config, null, 2));
|
|
7663
|
+
}).catch((err) => {
|
|
7664
|
+
logger.info(`Error loading config: ${err.message}`);
|
|
7665
|
+
}).finally(() => {
|
|
7666
|
+
console.groupEnd();
|
|
7667
|
+
});
|
|
7668
|
+
},
|
|
7669
|
+
/**
|
|
7670
|
+
* Show scheduled reviews
|
|
7671
|
+
*/
|
|
7672
|
+
async showScheduledReviews(courseId) {
|
|
7673
|
+
const userDB = getUserDB();
|
|
7674
|
+
if (!userDB) return;
|
|
7675
|
+
try {
|
|
7676
|
+
const reviews = await userDB.getPendingReviews(courseId);
|
|
7677
|
+
console.group(`\u{1F4C5} Scheduled Reviews${courseId ? ` (${courseId})` : ""}`);
|
|
7678
|
+
logger.info(`Total: ${reviews.length}`);
|
|
7679
|
+
if (reviews.length > 0) {
|
|
7680
|
+
const byCourse = /* @__PURE__ */ new Map();
|
|
7681
|
+
for (const review of reviews) {
|
|
7682
|
+
if (!byCourse.has(review.courseId)) {
|
|
7683
|
+
byCourse.set(review.courseId, []);
|
|
7684
|
+
}
|
|
7685
|
+
byCourse.get(review.courseId).push(review);
|
|
7686
|
+
}
|
|
7687
|
+
for (const [course, courseReviews] of byCourse) {
|
|
7688
|
+
console.group(`Course: ${course} (${courseReviews.length} reviews)`);
|
|
7689
|
+
const sorted = courseReviews.sort((a, b) => {
|
|
7690
|
+
const timeA = typeof a.reviewTime === "string" ? a.reviewTime : a.reviewTime.toISOString();
|
|
7691
|
+
const timeB = typeof b.reviewTime === "string" ? b.reviewTime : b.reviewTime.toISOString();
|
|
7692
|
+
return new Date(timeA).getTime() - new Date(timeB).getTime();
|
|
7693
|
+
});
|
|
7694
|
+
for (const review of sorted.slice(0, 10)) {
|
|
7695
|
+
const reviewTimeStr = typeof review.reviewTime === "string" ? review.reviewTime : review.reviewTime.toISOString();
|
|
7696
|
+
logger.info(
|
|
7697
|
+
` ${review.cardId.slice(0, 12)}... @ ${formatTimestamp(reviewTimeStr)} [${review.scheduledFor}/${review.schedulingAgentId}]`
|
|
7698
|
+
);
|
|
7699
|
+
}
|
|
7700
|
+
if (sorted.length > 10) {
|
|
7701
|
+
logger.info(` ... and ${sorted.length - 10} more`);
|
|
7702
|
+
}
|
|
7703
|
+
console.groupEnd();
|
|
7704
|
+
}
|
|
7705
|
+
}
|
|
7706
|
+
console.groupEnd();
|
|
7707
|
+
} catch (err) {
|
|
7708
|
+
logger.info(`Error loading scheduled reviews: ${err.message}`);
|
|
7709
|
+
}
|
|
7710
|
+
},
|
|
7711
|
+
/**
|
|
7712
|
+
* Show course registrations
|
|
7713
|
+
*/
|
|
7714
|
+
async showCourseRegistrations() {
|
|
7715
|
+
const userDB = getUserDB();
|
|
7716
|
+
if (!userDB) return;
|
|
7717
|
+
try {
|
|
7718
|
+
const registrations = await userDB.getActiveCourses();
|
|
7719
|
+
console.group("\u{1F4DA} Course Registrations");
|
|
7720
|
+
logger.info(`Total: ${registrations.length}`);
|
|
7721
|
+
if (registrations.length > 0) {
|
|
7722
|
+
console.table(
|
|
7723
|
+
registrations.map((reg) => ({
|
|
7724
|
+
courseId: reg.courseID,
|
|
7725
|
+
status: reg.status || "active",
|
|
7726
|
+
elo: typeof reg.elo === "number" ? reg.elo.toFixed(0) : reg.elo?.global?.score?.toFixed(0) || "N/A"
|
|
7727
|
+
}))
|
|
7728
|
+
);
|
|
7729
|
+
}
|
|
7730
|
+
console.groupEnd();
|
|
7731
|
+
} catch (err) {
|
|
7732
|
+
logger.info(`Error loading course registrations: ${err.message}`);
|
|
7733
|
+
}
|
|
7734
|
+
},
|
|
7735
|
+
/**
|
|
7736
|
+
* Show card history for a specific card
|
|
7737
|
+
*/
|
|
7738
|
+
async showCardHistory(cardId) {
|
|
7739
|
+
const rawDB = getRawDB();
|
|
7740
|
+
if (!rawDB) return;
|
|
7741
|
+
try {
|
|
7742
|
+
const result = await filterAllDocsByPrefix(rawDB, DocTypePrefixes["CARDRECORD" /* CARDRECORD */]);
|
|
7743
|
+
const cardHistories = result.rows.filter((row) => row.doc && row.doc.cardID === cardId).map((row) => row.doc);
|
|
7744
|
+
console.group(`\u{1F3B4} Card History: ${cardId}`);
|
|
7745
|
+
logger.info(`Total interactions: ${cardHistories.length}`);
|
|
7746
|
+
if (cardHistories.length > 0) {
|
|
7747
|
+
const sorted = cardHistories.sort(
|
|
7748
|
+
(a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
|
7749
|
+
);
|
|
7750
|
+
console.table(
|
|
7751
|
+
sorted.slice(0, 20).map((doc) => ({
|
|
7752
|
+
time: formatTimestamp(doc.timestamp),
|
|
7753
|
+
outcome: doc.outcome || "N/A",
|
|
7754
|
+
duration: doc.duration ? `${(doc.duration / 1e3).toFixed(1)}s` : "N/A",
|
|
7755
|
+
courseId: doc.courseId
|
|
7756
|
+
}))
|
|
7757
|
+
);
|
|
7758
|
+
if (sorted.length > 20) {
|
|
7759
|
+
logger.info(`... and ${sorted.length - 20} more interactions`);
|
|
7760
|
+
}
|
|
7761
|
+
}
|
|
7762
|
+
console.groupEnd();
|
|
7763
|
+
} catch (err) {
|
|
7764
|
+
logger.info(`Error loading card history: ${err.message}`);
|
|
7765
|
+
}
|
|
7766
|
+
},
|
|
7767
|
+
/**
|
|
7768
|
+
* Query documents by type
|
|
7769
|
+
*/
|
|
7770
|
+
async queryByType(docType, limit = 50) {
|
|
7771
|
+
const rawDB = getRawDB();
|
|
7772
|
+
if (!rawDB) return;
|
|
7773
|
+
try {
|
|
7774
|
+
const prefix = DocTypePrefixes[DocType[docType]];
|
|
7775
|
+
if (!prefix) {
|
|
7776
|
+
logger.info(`Unknown document type: ${docType}`);
|
|
7777
|
+
return;
|
|
7778
|
+
}
|
|
7779
|
+
const result = await filterAllDocsByPrefix(rawDB, prefix);
|
|
7780
|
+
console.group(`\u{1F4C4} Documents: ${docType}`);
|
|
7781
|
+
logger.info(`Total: ${result.rows.length}`);
|
|
7782
|
+
logger.info(`Prefix: ${prefix}`);
|
|
7783
|
+
if (result.rows.length > 0) {
|
|
7784
|
+
logger.info("Sample documents:");
|
|
7785
|
+
const samples = result.rows.slice(0, Math.min(limit, result.rows.length));
|
|
7786
|
+
for (const row of samples) {
|
|
7787
|
+
logger.info(`
|
|
7788
|
+
${row.id}:`);
|
|
7789
|
+
logger.info(JSON.stringify(row.doc, null, 2));
|
|
7790
|
+
}
|
|
7791
|
+
if (result.rows.length > limit) {
|
|
7792
|
+
logger.info(`
|
|
7793
|
+
... and ${result.rows.length - limit} more documents`);
|
|
7794
|
+
}
|
|
7795
|
+
}
|
|
7796
|
+
console.groupEnd();
|
|
7797
|
+
} catch (err) {
|
|
7798
|
+
logger.info(`Error querying documents: ${err.message}`);
|
|
7799
|
+
}
|
|
7800
|
+
},
|
|
7801
|
+
/**
|
|
7802
|
+
* Show database info and statistics
|
|
7803
|
+
*/
|
|
7804
|
+
async dbInfo() {
|
|
7805
|
+
const rawDB = getRawDB();
|
|
7806
|
+
if (!rawDB) return;
|
|
7807
|
+
try {
|
|
7808
|
+
const info = await rawDB.info();
|
|
7809
|
+
console.group("\u2139\uFE0F Database Information");
|
|
7810
|
+
logger.info(`Database name: ${info.db_name}`);
|
|
7811
|
+
logger.info(`Total documents: ${info.doc_count}`);
|
|
7812
|
+
logger.info(`Update sequence: ${info.update_seq}`);
|
|
7813
|
+
if ("disk_size" in info) {
|
|
7814
|
+
logger.info(`Disk size: ${(info.disk_size || 0) / 1024 / 1024} MB`);
|
|
7815
|
+
}
|
|
7816
|
+
logger.info("\nDocument counts by type:");
|
|
7817
|
+
const allDocs = await rawDB.allDocs({ include_docs: false });
|
|
7818
|
+
const typeCounts = /* @__PURE__ */ new Map();
|
|
7819
|
+
for (const row of allDocs.rows) {
|
|
7820
|
+
let prefix = "other";
|
|
7821
|
+
for (const [type, typePrefix] of Object.entries(DocTypePrefixes)) {
|
|
7822
|
+
if (row.id.startsWith(typePrefix)) {
|
|
7823
|
+
prefix = type;
|
|
7824
|
+
break;
|
|
7825
|
+
}
|
|
7826
|
+
}
|
|
7827
|
+
typeCounts.set(prefix, (typeCounts.get(prefix) || 0) + 1);
|
|
7828
|
+
}
|
|
7829
|
+
console.table(
|
|
7830
|
+
Array.from(typeCounts.entries()).sort((a, b) => b[1] - a[1]).map(([type, count]) => ({ type, count }))
|
|
7831
|
+
);
|
|
7832
|
+
console.groupEnd();
|
|
7833
|
+
} catch (err) {
|
|
7834
|
+
logger.info(`Error getting database info: ${err.message}`);
|
|
7835
|
+
}
|
|
7836
|
+
},
|
|
7837
|
+
/**
|
|
7838
|
+
* List all document types
|
|
7839
|
+
*/
|
|
7840
|
+
listDocTypes() {
|
|
7841
|
+
console.group("\u{1F4CB} Available Document Types");
|
|
7842
|
+
logger.info("Use with queryByType(type):");
|
|
7843
|
+
for (const [type, prefix] of Object.entries(DocTypePrefixes)) {
|
|
7844
|
+
logger.info(` ${type.padEnd(30)} \u2192 prefix: "${prefix}"`);
|
|
7845
|
+
}
|
|
7846
|
+
console.groupEnd();
|
|
7847
|
+
},
|
|
7848
|
+
/**
|
|
7849
|
+
* Export database contents (limited, for debugging)
|
|
7850
|
+
*/
|
|
7851
|
+
async export(includeContent = false) {
|
|
7852
|
+
const rawDB = getRawDB();
|
|
7853
|
+
const userDB = getUserDB();
|
|
7854
|
+
if (!rawDB || !userDB) return "{}";
|
|
7855
|
+
try {
|
|
7856
|
+
const data = {
|
|
7857
|
+
username: userDB.getUsername(),
|
|
7858
|
+
loggedIn: userDB.isLoggedIn(),
|
|
7859
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
7860
|
+
};
|
|
7861
|
+
if (includeContent) {
|
|
7862
|
+
const allDocs = await rawDB.allDocs({ include_docs: true });
|
|
7863
|
+
data.documents = allDocs.rows.map((row) => ({
|
|
7864
|
+
id: row.id,
|
|
7865
|
+
doc: row.doc
|
|
7866
|
+
}));
|
|
7867
|
+
data.totalDocs = allDocs.rows.length;
|
|
7868
|
+
} else {
|
|
7869
|
+
const allDocs = await rawDB.allDocs({ include_docs: false });
|
|
7870
|
+
data.totalDocs = allDocs.rows.length;
|
|
7871
|
+
const typeCounts = /* @__PURE__ */ new Map();
|
|
7872
|
+
for (const row of allDocs.rows) {
|
|
7873
|
+
let prefix = "other";
|
|
7874
|
+
for (const [type, typePrefix] of Object.entries(DocTypePrefixes)) {
|
|
7875
|
+
if (row.id.startsWith(typePrefix)) {
|
|
7876
|
+
prefix = type;
|
|
7877
|
+
break;
|
|
7878
|
+
}
|
|
7879
|
+
}
|
|
7880
|
+
typeCounts.set(prefix, (typeCounts.get(prefix) || 0) + 1);
|
|
7881
|
+
}
|
|
7882
|
+
data.docCounts = Object.fromEntries(typeCounts);
|
|
7883
|
+
}
|
|
7884
|
+
const json = JSON.stringify(data, null, 2);
|
|
7885
|
+
logger.info("[UserDB Debug] Database info exported. Copy the returned string or use:");
|
|
7886
|
+
logger.info(" copy(window.skuilder.userdb.export())");
|
|
7887
|
+
if (!includeContent) {
|
|
7888
|
+
logger.info(" For full content export: window.skuilder.userdb.export(true)");
|
|
7889
|
+
}
|
|
7890
|
+
return json;
|
|
7891
|
+
} catch (err) {
|
|
7892
|
+
logger.info(`Error exporting database: ${err.message}`);
|
|
7893
|
+
return "{}";
|
|
7894
|
+
}
|
|
7895
|
+
},
|
|
7896
|
+
/**
|
|
7897
|
+
* Execute raw PouchDB query
|
|
7898
|
+
*/
|
|
7899
|
+
async raw(queryFn) {
|
|
7900
|
+
const rawDB = getRawDB();
|
|
7901
|
+
if (!rawDB) return;
|
|
7902
|
+
try {
|
|
7903
|
+
const result = await queryFn(rawDB);
|
|
7904
|
+
logger.info("[UserDB Debug] Query result:");
|
|
7905
|
+
logger.info(result);
|
|
7906
|
+
} catch (err) {
|
|
7907
|
+
logger.info(`[UserDB Debug] Query error: ${err.message}`);
|
|
7908
|
+
}
|
|
7909
|
+
},
|
|
7910
|
+
/**
|
|
7911
|
+
* Show help
|
|
7912
|
+
*/
|
|
7913
|
+
help() {
|
|
7914
|
+
logger.info(`
|
|
7915
|
+
\u{1F527} UserDB Debug API
|
|
7916
|
+
|
|
7917
|
+
Commands:
|
|
7918
|
+
.showUser() Show current user info and config
|
|
7919
|
+
.showScheduledReviews(courseId?) Show scheduled reviews (optionally filter by course)
|
|
7920
|
+
.showCourseRegistrations() Show all course registrations
|
|
7921
|
+
.showCardHistory(cardId) Show interaction history for a card
|
|
7922
|
+
.queryByType(docType, limit?) Query documents by type (e.g., 'SCHEDULED_CARD')
|
|
7923
|
+
.listDocTypes() List all available document types
|
|
7924
|
+
.dbInfo() Show database info and statistics
|
|
7925
|
+
.export(includeContent?) Export database info (true = include all docs)
|
|
7926
|
+
.raw(queryFn) Execute raw PouchDB query
|
|
7927
|
+
.help() Show this help message
|
|
7928
|
+
|
|
7929
|
+
Examples:
|
|
7930
|
+
window.skuilder.userdb.showUser()
|
|
7931
|
+
window.skuilder.userdb.showScheduledReviews('course123')
|
|
7932
|
+
window.skuilder.userdb.queryByType('SCHEDULED_CARD', 10)
|
|
7933
|
+
window.skuilder.userdb.raw(db => db.allDocs({ limit: 5 }))
|
|
7934
|
+
`);
|
|
7935
|
+
}
|
|
7936
|
+
};
|
|
7937
|
+
mountUserDBDebugger();
|
|
7938
|
+
}
|
|
7939
|
+
});
|
|
7940
|
+
|
|
7611
7941
|
// src/core/index.ts
|
|
7612
7942
|
var init_core = __esm({
|
|
7613
7943
|
"src/core/index.ts"() {
|
|
@@ -7622,6 +7952,7 @@ var init_core = __esm({
|
|
|
7622
7952
|
init_navigators();
|
|
7623
7953
|
init_bulkImport();
|
|
7624
7954
|
init_orchestration();
|
|
7955
|
+
init_UserDBDebugger();
|
|
7625
7956
|
}
|
|
7626
7957
|
});
|
|
7627
7958
|
|
|
@@ -7685,6 +8016,7 @@ __export(index_exports, {
|
|
|
7685
8016
|
mountMixerDebugger: () => mountMixerDebugger,
|
|
7686
8017
|
mountPipelineDebugger: () => mountPipelineDebugger,
|
|
7687
8018
|
mountSessionDebugger: () => mountSessionDebugger,
|
|
8019
|
+
mountUserDBDebugger: () => mountUserDBDebugger,
|
|
7688
8020
|
newInterval: () => newInterval,
|
|
7689
8021
|
parseCardHistoryID: () => parseCardHistoryID,
|
|
7690
8022
|
pipelineDebugAPI: () => pipelineDebugAPI,
|
|
@@ -7707,6 +8039,7 @@ __export(index_exports, {
|
|
|
7707
8039
|
startSessionTracking: () => startSessionTracking,
|
|
7708
8040
|
updateLearningState: () => updateLearningState,
|
|
7709
8041
|
updateStrategyWeight: () => updateStrategyWeight,
|
|
8042
|
+
userDBDebugAPI: () => userDBDebugAPI,
|
|
7710
8043
|
validateMigration: () => validateMigration,
|
|
7711
8044
|
validateProcessorConfig: () => validateProcessorConfig,
|
|
7712
8045
|
validateStaticCourse: () => validateStaticCourse
|
|
@@ -11350,6 +11683,7 @@ init_factory();
|
|
|
11350
11683
|
mountMixerDebugger,
|
|
11351
11684
|
mountPipelineDebugger,
|
|
11352
11685
|
mountSessionDebugger,
|
|
11686
|
+
mountUserDBDebugger,
|
|
11353
11687
|
newInterval,
|
|
11354
11688
|
parseCardHistoryID,
|
|
11355
11689
|
pipelineDebugAPI,
|
|
@@ -11372,6 +11706,7 @@ init_factory();
|
|
|
11372
11706
|
startSessionTracking,
|
|
11373
11707
|
updateLearningState,
|
|
11374
11708
|
updateStrategyWeight,
|
|
11709
|
+
userDBDebugAPI,
|
|
11375
11710
|
validateMigration,
|
|
11376
11711
|
validateProcessorConfig,
|
|
11377
11712
|
validateStaticCourse
|