@kensai/quiz-core 0.1.0

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +99 -0
  3. package/dist/evaluate.d.ts +47 -0
  4. package/dist/evaluate.d.ts.map +1 -0
  5. package/dist/evaluate.js +149 -0
  6. package/dist/evaluate.js.map +1 -0
  7. package/dist/events.d.ts +10 -0
  8. package/dist/events.d.ts.map +1 -0
  9. package/dist/events.js +26 -0
  10. package/dist/events.js.map +1 -0
  11. package/dist/index.d.ts +26 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +19 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/load.d.ts +22 -0
  16. package/dist/load.d.ts.map +1 -0
  17. package/dist/load.js +31 -0
  18. package/dist/load.js.map +1 -0
  19. package/dist/resolve.d.ts +9 -0
  20. package/dist/resolve.d.ts.map +1 -0
  21. package/dist/resolve.js +22 -0
  22. package/dist/resolve.js.map +1 -0
  23. package/dist/runtime.d.ts +118 -0
  24. package/dist/runtime.d.ts.map +1 -0
  25. package/dist/runtime.js +245 -0
  26. package/dist/runtime.js.map +1 -0
  27. package/dist/schema.generated.d.ts +503 -0
  28. package/dist/schema.generated.d.ts.map +1 -0
  29. package/dist/schema.generated.js +626 -0
  30. package/dist/schema.generated.js.map +1 -0
  31. package/dist/settings.d.ts +19 -0
  32. package/dist/settings.d.ts.map +1 -0
  33. package/dist/settings.js +32 -0
  34. package/dist/settings.js.map +1 -0
  35. package/dist/stats.d.ts +33 -0
  36. package/dist/stats.d.ts.map +1 -0
  37. package/dist/stats.js +79 -0
  38. package/dist/stats.js.map +1 -0
  39. package/dist/text.d.ts +5 -0
  40. package/dist/text.d.ts.map +1 -0
  41. package/dist/text.js +11 -0
  42. package/dist/text.js.map +1 -0
  43. package/dist/types.d.ts +136 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +9 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/validate.d.ts +28 -0
  48. package/dist/validate.d.ts.map +1 -0
  49. package/dist/validate.js +170 -0
  50. package/dist/validate.js.map +1 -0
  51. package/package.json +60 -0
@@ -0,0 +1,118 @@
1
+ import type { AnswerInput, Option, Question, Quiz } from "./types.js";
2
+ import { type ResolvedSettings } from "./settings.js";
3
+ import { type QuestionResult, type QuizResult } from "./evaluate.js";
4
+ import { Emitter } from "./events.js";
5
+ export type AttemptStatus = "not_started" | "in_progress" | "finished";
6
+ export type AttemptEvents = {
7
+ started: {
8
+ at: number;
9
+ };
10
+ answered: {
11
+ questionIndex: number;
12
+ questionId?: string;
13
+ /** Present only when feedback is `immediate`. */
14
+ result: QuestionResult | null;
15
+ };
16
+ navigated: {
17
+ position: number;
18
+ questionIndex: number;
19
+ };
20
+ time_up: {
21
+ at: number;
22
+ };
23
+ finished: {
24
+ at: number;
25
+ result: QuizResult;
26
+ };
27
+ };
28
+ export interface AttemptOptions {
29
+ /** Per-attempt settings overrides (a player choosing order/feedback/time, etc.). */
30
+ settings?: Partial<ResolvedSettings>;
31
+ /** Clock source (ms epoch). Injectable for testing/SSR. Default: `Date.now`. */
32
+ now?: () => number;
33
+ /** RNG in [0,1). Injectable for deterministic shuffles. Default: `Math.random`. */
34
+ rng?: () => number;
35
+ }
36
+ /** Serializable attempt state, for persistence and resume. */
37
+ export interface AttemptSnapshot {
38
+ status: AttemptStatus;
39
+ order: number[];
40
+ position: number;
41
+ answers: Record<string, AnswerInput>;
42
+ startedAt: number | null;
43
+ finishedAt: number | null;
44
+ /** Per-question shuffled option order (question index → ordered option ids). */
45
+ optionOrder?: Record<number, string[]>;
46
+ }
47
+ export interface CurrentQuestion {
48
+ question: Question;
49
+ /** Index into `quiz.questions`. */
50
+ index: number;
51
+ /** Index into the presentation `order`. */
52
+ position: number;
53
+ total: number;
54
+ answer: AnswerInput | undefined;
55
+ }
56
+ /**
57
+ * A headless quiz attempt: a UI-agnostic state machine over navigation, answers,
58
+ * feedback timing, and an optional time limit. It never touches the DOM or timers —
59
+ * a UI subscribes to events and drives the clock. All scoring delegates to
60
+ * `evaluate`. Time is checked lazily on interaction via the injected `now()`.
61
+ */
62
+ export declare class Attempt extends Emitter<AttemptEvents> {
63
+ readonly quiz: Quiz;
64
+ readonly settings: ResolvedSettings;
65
+ private readonly now;
66
+ private readonly rng;
67
+ private status;
68
+ private order;
69
+ private optionOrder;
70
+ private position;
71
+ private answers;
72
+ private startedAt;
73
+ private finishedAt;
74
+ private lastResult;
75
+ constructor(quiz: Quiz, options?: AttemptOptions);
76
+ private buildOrder;
77
+ /**
78
+ * Precompute a stable shuffled option order per choice question, once, so options
79
+ * don't jump around between renders. Honors the per-question `shuffle_options`
80
+ * opt-out (default allowed) and only runs when the setting is enabled.
81
+ */
82
+ private buildOptionOrder;
83
+ private keyFor;
84
+ getStatus(): AttemptStatus;
85
+ start(): void;
86
+ current(): CurrentQuestion;
87
+ /**
88
+ * Options in presentation order for a choice question at `index`. Uses the stable
89
+ * per-attempt shuffle when enabled; otherwise the authored order. Returns `[]` for
90
+ * non-choice questions.
91
+ */
92
+ optionsFor(question: Question, index: number): Option[];
93
+ /** Remaining seconds, or `null` when there is no time limit. */
94
+ remainingTime(): number | null;
95
+ /** If the time limit has elapsed, emit `time_up` and finish. Returns true if it did. */
96
+ private enforceTime;
97
+ /** Answer the current question. Returns a result only under `immediate` feedback. */
98
+ answer(answer: AnswerInput): QuestionResult | null;
99
+ /** Answer an arbitrary question by its index in `quiz.questions`. */
100
+ answerAt(index: number, answer: AnswerInput): QuestionResult | null;
101
+ private setAnswer;
102
+ canGoNext(): boolean;
103
+ canGoPrev(): boolean;
104
+ next(): CurrentQuestion | null;
105
+ prev(): CurrentQuestion | null;
106
+ goto(position: number): CurrentQuestion | null;
107
+ private emitNavigated;
108
+ getAnswers(): Record<string, AnswerInput>;
109
+ /** Finalize the attempt, evaluate all answers, and emit `finished`. Idempotent. */
110
+ finish(): QuizResult;
111
+ /** Live result snapshot without finishing (e.g. for progress display). */
112
+ peekResult(): QuizResult;
113
+ /** Serializable snapshot for persistence. */
114
+ toJSON(): AttemptSnapshot;
115
+ /** Rebuild an attempt from a snapshot (preserves order, answers, and progress). */
116
+ static resume(quiz: Quiz, snapshot: AttemptSnapshot, options?: AttemptOptions): Attempt;
117
+ }
118
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,245 @@
1
+ import { resolveSettings } from "./settings.js";
2
+ import { evaluateQuestion, evaluateQuiz, } from "./evaluate.js";
3
+ import { resolveChoiceOptions } from "./resolve.js";
4
+ import { Emitter } from "./events.js";
5
+ /**
6
+ * A headless quiz attempt: a UI-agnostic state machine over navigation, answers,
7
+ * feedback timing, and an optional time limit. It never touches the DOM or timers —
8
+ * a UI subscribes to events and drives the clock. All scoring delegates to
9
+ * `evaluate`. Time is checked lazily on interaction via the injected `now()`.
10
+ */
11
+ export class Attempt extends Emitter {
12
+ quiz;
13
+ settings;
14
+ now;
15
+ rng;
16
+ status = "not_started";
17
+ order;
18
+ optionOrder;
19
+ position = 0;
20
+ answers = {};
21
+ startedAt = null;
22
+ finishedAt = null;
23
+ lastResult = null;
24
+ constructor(quiz, options = {}) {
25
+ super();
26
+ this.quiz = quiz;
27
+ this.settings = resolveSettings(quiz.settings, options.settings);
28
+ this.now = options.now ?? (() => Date.now());
29
+ this.rng = options.rng ?? (() => Math.random());
30
+ this.order = this.buildOrder();
31
+ this.optionOrder = this.buildOptionOrder();
32
+ }
33
+ buildOrder() {
34
+ const indices = this.quiz.questions.map((_, i) => i);
35
+ if (this.settings.order === "random")
36
+ shuffle(indices, this.rng);
37
+ return indices;
38
+ }
39
+ /**
40
+ * Precompute a stable shuffled option order per choice question, once, so options
41
+ * don't jump around between renders. Honors the per-question `shuffle_options`
42
+ * opt-out (default allowed) and only runs when the setting is enabled.
43
+ */
44
+ buildOptionOrder() {
45
+ const map = {};
46
+ if (!this.settings.shuffle_options)
47
+ return map;
48
+ this.quiz.questions.forEach((question, index) => {
49
+ if (question.type !== "choice" || question.shuffle_options === false)
50
+ return;
51
+ const ids = resolveChoiceOptions(this.quiz, question).map((o) => o.id);
52
+ shuffle(ids, this.rng);
53
+ map[index] = ids;
54
+ });
55
+ return map;
56
+ }
57
+ keyFor(index) {
58
+ return this.quiz.questions[index].id ?? String(index);
59
+ }
60
+ getStatus() {
61
+ return this.status;
62
+ }
63
+ start() {
64
+ if (this.status !== "not_started")
65
+ return;
66
+ this.status = "in_progress";
67
+ this.startedAt = this.now();
68
+ this.emit("started", { at: this.startedAt });
69
+ }
70
+ current() {
71
+ const index = this.order[this.position];
72
+ return {
73
+ question: this.quiz.questions[index],
74
+ index,
75
+ position: this.position,
76
+ total: this.order.length,
77
+ answer: this.answers[this.keyFor(index)],
78
+ };
79
+ }
80
+ /**
81
+ * Options in presentation order for a choice question at `index`. Uses the stable
82
+ * per-attempt shuffle when enabled; otherwise the authored order. Returns `[]` for
83
+ * non-choice questions.
84
+ */
85
+ optionsFor(question, index) {
86
+ if (question.type !== "choice")
87
+ return [];
88
+ const options = resolveChoiceOptions(this.quiz, question);
89
+ const order = this.optionOrder[index];
90
+ if (!order)
91
+ return options.slice();
92
+ const byId = new Map(options.map((o) => [o.id, o]));
93
+ const ordered = order.map((id) => byId.get(id)).filter((o) => o !== undefined);
94
+ // Defensive: keep any option missing from the stored order (appended at the end).
95
+ for (const option of options)
96
+ if (!order.includes(option.id))
97
+ ordered.push(option);
98
+ return ordered;
99
+ }
100
+ /** Remaining seconds, or `null` when there is no time limit. */
101
+ remainingTime() {
102
+ if (this.settings.time_limit == null)
103
+ return null;
104
+ if (this.startedAt == null)
105
+ return this.settings.time_limit;
106
+ const elapsed = (this.now() - this.startedAt) / 1000;
107
+ return Math.max(0, this.settings.time_limit - elapsed);
108
+ }
109
+ /** If the time limit has elapsed, emit `time_up` and finish. Returns true if it did. */
110
+ enforceTime() {
111
+ const remaining = this.remainingTime();
112
+ if (remaining !== null && remaining <= 0 && this.status === "in_progress") {
113
+ this.emit("time_up", { at: this.now() });
114
+ this.finish();
115
+ return true;
116
+ }
117
+ return false;
118
+ }
119
+ /** Answer the current question. Returns a result only under `immediate` feedback. */
120
+ answer(answer) {
121
+ if (this.status === "not_started")
122
+ this.start();
123
+ if (this.enforceTime())
124
+ return null;
125
+ if (this.status !== "in_progress")
126
+ return null;
127
+ return this.setAnswer(this.current().index, answer);
128
+ }
129
+ /** Answer an arbitrary question by its index in `quiz.questions`. */
130
+ answerAt(index, answer) {
131
+ if (this.status === "not_started")
132
+ this.start();
133
+ if (this.enforceTime())
134
+ return null;
135
+ if (this.status !== "in_progress")
136
+ return null;
137
+ if (index < 0 || index >= this.quiz.questions.length)
138
+ return null;
139
+ return this.setAnswer(index, answer);
140
+ }
141
+ setAnswer(index, answer) {
142
+ const question = this.quiz.questions[index];
143
+ this.answers[this.keyFor(index)] = answer;
144
+ const result = this.settings.feedback === "immediate"
145
+ ? evaluateQuestion(this.quiz, question, index, answer)
146
+ : null;
147
+ this.emit("answered", { questionIndex: index, questionId: question.id, result });
148
+ return result;
149
+ }
150
+ canGoNext() {
151
+ return this.position < this.order.length - 1;
152
+ }
153
+ canGoPrev() {
154
+ return this.position > 0;
155
+ }
156
+ next() {
157
+ if (this.enforceTime())
158
+ return null;
159
+ if (!this.canGoNext())
160
+ return null;
161
+ this.position++;
162
+ this.emitNavigated();
163
+ return this.current();
164
+ }
165
+ prev() {
166
+ if (!this.canGoPrev())
167
+ return null;
168
+ this.position--;
169
+ this.emitNavigated();
170
+ return this.current();
171
+ }
172
+ goto(position) {
173
+ if (position < 0 || position >= this.order.length)
174
+ return null;
175
+ this.position = position;
176
+ this.emitNavigated();
177
+ return this.current();
178
+ }
179
+ emitNavigated() {
180
+ this.emit("navigated", {
181
+ position: this.position,
182
+ questionIndex: this.order[this.position],
183
+ });
184
+ }
185
+ getAnswers() {
186
+ return { ...this.answers };
187
+ }
188
+ /** Finalize the attempt, evaluate all answers, and emit `finished`. Idempotent. */
189
+ finish() {
190
+ if (this.status === "finished" && this.lastResult)
191
+ return this.lastResult;
192
+ this.status = "finished";
193
+ this.finishedAt = this.now();
194
+ const result = evaluateQuiz(this.quiz, this.answers, { settingsOverride: this.settings });
195
+ this.lastResult = result;
196
+ this.emit("finished", { at: this.finishedAt, result });
197
+ return result;
198
+ }
199
+ /** Live result snapshot without finishing (e.g. for progress display). */
200
+ peekResult() {
201
+ return evaluateQuiz(this.quiz, this.answers, { settingsOverride: this.settings });
202
+ }
203
+ /** Serializable snapshot for persistence. */
204
+ toJSON() {
205
+ return {
206
+ status: this.status,
207
+ order: this.order.slice(),
208
+ position: this.position,
209
+ answers: { ...this.answers },
210
+ startedAt: this.startedAt,
211
+ finishedAt: this.finishedAt,
212
+ optionOrder: cloneOptionOrder(this.optionOrder),
213
+ };
214
+ }
215
+ /** Rebuild an attempt from a snapshot (preserves order, answers, and progress). */
216
+ static resume(quiz, snapshot, options = {}) {
217
+ const attempt = new Attempt(quiz, options);
218
+ attempt.status = snapshot.status;
219
+ attempt.order = snapshot.order.slice();
220
+ attempt.position = snapshot.position;
221
+ attempt.answers = { ...snapshot.answers };
222
+ attempt.startedAt = snapshot.startedAt;
223
+ attempt.finishedAt = snapshot.finishedAt;
224
+ if (snapshot.optionOrder)
225
+ attempt.optionOrder = cloneOptionOrder(snapshot.optionOrder);
226
+ return attempt;
227
+ }
228
+ }
229
+ /** Deep-clone the question-index → option-ids map. */
230
+ function cloneOptionOrder(order) {
231
+ const out = {};
232
+ for (const [key, ids] of Object.entries(order))
233
+ out[Number(key)] = ids.slice();
234
+ return out;
235
+ }
236
+ /** In-place Fisher–Yates shuffle using an injectable RNG. */
237
+ function shuffle(array, rng) {
238
+ for (let i = array.length - 1; i > 0; i--) {
239
+ const j = Math.floor(rng() * (i + 1));
240
+ const tmp = array[i];
241
+ array[i] = array[j];
242
+ array[j] = tmp;
243
+ }
244
+ }
245
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}