@thanh01.pmt/interactive-quiz-kit 1.0.13 → 1.0.16

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 (3) hide show
  1. package/HEADLESS.md +126 -213
  2. package/README.md +83 -95
  3. package/package.json +1 -1
package/HEADLESS.md CHANGED
@@ -1,170 +1,63 @@
1
- # Chế độ Headless: Sử dụng Logic của `interactive-quiz-kit` không cần Giao diện
1
+ # Headless Mode: Using `interactive-quiz-kit` Logic Without the UI
2
2
 
3
- **`interactive-quiz-kit`** được thiết kế với kiến trúc module hóa, cho phép bạn sử dụng toàn bộ logic lõi của một cách độc lập mà không cần đến các thành phần giao diện người dùng React. Chế độ "headless" này tưởng cho các trường hợp sử dụng như sau:
3
+ **`interactive-quiz-kit`** is designed with a modular architecture, allowing you to use its entire core logic independently of the React UI components. This "headless" mode is ideal for use cases such as:
4
4
 
5
- * Xây dựng một backend để quản tạo quiz.
6
- * Tích hợp logic quiz vào một ứng dụng di động (React Native, Flutter,...).
7
- * Chạy các script tự động để tạo nội dung hoặc xử lý dữ liệu quiz.
8
- * Tích hợp vào các framework JavaScript khác ngoài React.
5
+ * Building a backend to manage and generate quizzes.
6
+ * Integrating quiz logic into a mobile application (React Native, Flutter, etc.).
7
+ * Running automated scripts for content creation or data processing.
8
+ * Integrating with JavaScript frameworks other than React.
9
9
 
10
- Tài liệu này sẽ hướng dẫn bạn cách import sử dụng các tính năng headless chính của thư viện.
10
+ This document will guide you on how to import and use the library's main headless features.
11
11
 
12
- ## I. Tổng quan các Thành phần Headless
12
+ ## I. Overview of Headless Components & Entry Points
13
13
 
14
- Các thành phần non-UI của thư viện được phân bổ trong các thư mục sau:
14
+ The non-UI components of the library are accessible through specific entry points for optimized, modular usage.
15
15
 
16
- | Thư mục/File | Chức năng Chính |
17
- | :-------------------- | :------------------------------------------------------------------------ |
18
- | `types.ts` | **(Cốt lõi)** Định nghĩa tất cả các cấu trúc dữ liệu (interfaces) cho quiz. |
19
- | `services/` | **(Cốt lõi)** Chứa các service để chạy, quản lý, đóng gói quiz. |
20
- | `ai/` | Chứa các flow để tạo nội dung quiz bằng Trí tuệ Nhân tạo. |
21
- | `utils/idGenerators.ts` | Các hàm tiện ích, dụ như tạo ID duy nhất. |
22
- | `schemas/` | Các file JSON Schema để xác thực cấu trúc dữ liệu của quiz. |
16
+ | Entry Point / File | Main Function |
17
+ | :----------------------------------------------- | :------------------------------------------------------------------------------ |
18
+ | `@thanh01.pmt/interactive-quiz-kit` | **(Core)** Contains all types, core services, and utilities. |
19
+ | `@thanh01.pmt/interactive-quiz-kit/ai` | **(AI)** Contains flows for generating quiz content using Artificial Intelligence. |
20
+ | `src/services/TopicDataService.ts` | **(Service)** Manages curriculum data imported from TSV files. |
21
+ | `src/services/SCORMService.ts` & related files | **(Service)** Provides tools for SCORM packaging and communication. |
23
22
 
24
- ### 1. Chế độ Headless Tại sao nó quan trọng?
23
+ ### 1. What is Headless Mode and Why is it Important?
25
24
 
26
- Hãy tưởng tượng thư viện của bạn như một chiếc xe hơi hoàn chỉnh. Giao diện người dùng (`react-ui/`) chính phần thân vỏ, nội thất, lăng, bảng điều khiểntất cả những bạn thấy và tương tác. "Chế độ headless" chính việc bạn thể lấy toàn bộ **động cơ, khung gầm, hệ thống truyền động và bộ não điều khiển (ECU)** của chiếc xe đó ra lắp vào một thân vỏ khác dụ như một chiếc xe tải, một chiếc thuyền, hoặc thậm chí một cỗ máy công nghiệp.
25
+ Imagine the library is a complete car. The UI (`react-ui/`) is the body, interior, steering wheel, and dashboardeverything you see and interact with. "Headless mode" means you can take the entire **engine, chassis, drivetrain, and control unit (ECU)** and fit it into a different bodylike a truck, a boat, or even an industrial machine.
27
26
 
28
- Nói cách khác, **chế độ headless cho phép bạn sử dụng tất cả các logic, quy trình nghiệp vụ, khả năng xử dữ liệu của thư viện mà không cần đến giao diện người dùng React đi kèm.**
27
+ In other words, **headless mode allows you to use all the logic, business processes, and data handling capabilities of the library without the bundled React UI.**
29
28
 
30
- **Tại sao quan trọng?**
29
+ **Why is this important?**
31
30
 
32
- * **Linh hoạt tối đa:** Bạn không bị trói buộc vào React. Bạn thể xây dựng giao diện bằng Vue, Svelte, Angular, hoặc thậm chí ứng dụng di động native (iOS, Android) chỉ cần gọi đến logic lõi của thư viện.
33
- * **Tự động hóa & Tích hợp Backend:** Bạn thể chạy các quy trình trên server, dụ:
34
- * Một cron job hàng đêm dùng module AI để tự động tạo ra hàng trăm câu hỏi mới lưu vào cơ sở dữ liệu.
35
- * Xây dựng một API endpoint để quản lý, chỉnh sửa, xuất bản các bài quiz.
36
- * **Tái sử dụng Logic:** Đảm bảo logic nghiệp vụ ( dụ: cách chấm điểm một câu hỏi) nhất quán mọi nơi, từ web, mobile đến các script nội bộ.
31
+ * **Maximum Flexibility:** You are not tied to React. You can build your UI with Vue, Svelte, Angular, or even native mobile apps (iOS, Android) and simply call the library's core logic.
32
+ * **Automation & Backend Integration:** You can run processes on a server, for example:
33
+ * A nightly cron job that uses the AI module to automatically generate hundreds of new questions and save them to a database.
34
+ * An API endpoint to manage, edit, and publish quizzes.
35
+ * **Logic Reusability:** Ensures that business logic (e.g., how a question is graded) is consistent everywhere, from the web and mobile to internal scripts.
37
36
 
38
37
  ---
39
38
 
40
- ### 2. Phân tích chi tiết các Thành phần Headless
39
+ ## II. Core Headless Services
41
40
 
42
- Dưới đây từng thành phần, vai trò, và tầm quan trọng của chúng trong chế độ headless.
41
+ ### 1. Types - The Foundation
43
42
 
44
- #### **A. `types.ts` & `schemas/` - Nền tảng & Quy tắc**
45
-
46
- * **Vai trò:** Là "Hiến pháp" và "Bộ luật" của thư viện. Chúng định nghĩa cấu trúc dữ liệu và các quy tắc mà mọi thành phần khác phải tuân theo.
47
- * **Mô tả chi tiết:**
48
- * **`types.ts`:** Đây là file quan trọng nhất. Nó chứa các `interface` TypeScript như `QuizConfig`, `QuizQuestion`, `QuizResult`. Đây là "nguồn chân lý duy nhất" (single source of truth) cho hình dạng của dữ liệu. Bất kỳ hàm nào bạn viết để tương tác với quiz đều sẽ nhận và trả về các kiểu dữ liệu được định nghĩa ở đây.
49
- * **`schemas/`:** Chứa các file JSON Schema. Trong môi trường headless, chúng cực kỳ hữu ích để **xác thực (validate)** dữ liệu. Ví dụ, khi một hệ thống khác gửi cho bạn một file JSON `quiz.json`, bạn có thể dùng schema này để kiểm tra xem file đó có hợp lệ hay không trước khi xử lý.
50
- * **Tầm quan trọng:** **Nền tảng (Fundamental)**. Không thể sử dụng thư viện nếu không hiểu các kiểu dữ liệu này.
51
-
52
- ---
53
-
54
- #### **B. `services/QuizEditorService.ts` - Người Thợ Xây**
55
-
56
- * **Vai trò:** Công cụ để **tạo, sửa, xóa, và sắp xếp** các câu hỏi bên trong một đối tượng `QuizConfig`. Đây là service dành cho khâu *biên soạn (authoring)*.
57
- * **Mô tả chi tiết:**
58
- * Đây là một lớp (class) bạn khởi tạo với một đối tượng `QuizConfig` ban đầu. Nó sẽ làm việc trên một bản sao sâu (deep copy), đảm bảo không làm thay đổi đối tượng gốc một cách không mong muốn (nguyên tắc immutability).
59
- * **`createNewQuestionTemplate(type)` (Static Method):** Tạo ra một "khuôn mẫu" câu hỏi rỗng với các giá trị mặc định. Rất hữu ích khi bạn muốn thêm một câu hỏi mới.
60
- * **`addQuestion(question)`:** Thêm một câu hỏi vào danh sách.
61
- * **`updateQuestion(updatedQuestion)`:** Cập nhật một câu hỏi đã có dựa trên `id` của nó.
62
- * **`deleteQuestionByIndex(index)`:** Xóa một câu hỏi dựa trên vị trí của nó.
63
- * **`moveQuestion(fromIndex, toIndex)`:** Thay đổi thứ tự các câu hỏi.
64
- * **Tầm quan trọng:** **Cốt lõi (Core)** cho bất kỳ tác vụ nào liên quan đến việc quản lý nội dung quiz.
65
-
66
- * **Ví dụ sử dụng:**
67
-
68
- ```typescript
69
- import { QuizEditorService, emptyQuiz } from 'interactive-quiz-kit/services';
70
-
71
- // Bắt đầu với một quiz rỗng
72
- let myQuiz = emptyQuiz;
73
- const editor = new QuizEditorService(myQuiz);
74
-
75
- // Thêm một câu hỏi True/False
76
- const tfQuestion = QuizEditorService.createNewQuestionTemplate('true_false');
77
- tfQuestion.prompt = "Trái Đất có phải là một hình cầu hoàn hảo không?";
78
- if (tfQuestion.questionType === 'true_false') tfQuestion.correctAnswer = false;
79
-
80
- myQuiz = editor.addQuestion(tfQuestion);
81
-
82
- // Cập nhật lại tiêu đề quiz
83
- myQuiz.title = "Quiz đã được cập nhật bằng code";
84
-
85
- console.log(myQuiz);
86
- ```
87
-
88
- ---
89
-
90
- #### **C. `services/QuizEngine.ts` - Nhạc trưởng Điều hành**
91
-
92
- * **Vai trò:** Quản lý toàn bộ vòng đời của một **phiên làm bài quiz thực tế**. Đây là service dành cho khâu *thực thi (runtime)*.
93
- * **Mô tả chi tiết:**
94
- * Khởi tạo với một `QuizConfig` và một bộ `callbacks`. Thiết kế dựa trên callback này làm cho nó cực kỳ linh hoạt để tích hợp vào bất kỳ hệ thống nào.
95
- * Nó quản lý trạng thái nội bộ: câu hỏi hiện tại, câu trả lời của người dùng, thời gian còn lại.
96
- * Cung cấp các phương thức công khai (public methods) như `nextQuestion()`, `previousQuestion()`, `submitAnswer()`, và `calculateResults()` để điều khiển luồng làm bài.
97
- * Logic chấm điểm phức tạp cho 12 loại câu hỏi được đóng gói hoàn toàn bên trong `evaluateQuestion`.
98
- * **Tầm quan trọng:** **Cốt lõi (Core)** cho bất kỳ ứng dụng nào muốn cho người dùng *làm* bài quiz.
99
-
100
- ---
101
-
102
- #### **D. `ai/flows/` - Bộ não Sáng tạo**
103
-
104
- * **Vai trò:** Cung cấp các hàm `async` để giao tiếp với AI và tự động tạo ra nội dung quiz.
105
- * **Mô tả chi tiết:**
106
- * Mỗi file là một "flow" có thể gọi được. Chúng nhận đầu vào có cấu trúc (nhờ `zod`) và trả về kết quả cũng có cấu trúc.
107
- * **`generate...Question`:** Các flow tạo câu hỏi đơn lẻ.
108
- * **`generateQuizPlan` & `generateQuestionsFromQuizPlan`:** Một quy trình 2 giai đoạn mạnh mẽ cho phép tạo ra một bài quiz hoàn chỉnh, cân bằng về chủ đề và độ khó, thay vì chỉ là một mớ câu hỏi ngẫu nhiên.
109
- * **Tầm quan trọng:** **Tính năng nâng cao (Advanced Feature)**. Lý tưởng cho các hệ thống muốn tự động hóa việc tạo nội dung.
110
-
111
- * **Ví dụ sử dụng (trong một script backend):**
112
-
113
- ```typescript
114
- import { generateQuizPlan, generateQuestionsFromQuizPlan } from 'interactive-quiz-kit/ai';
115
-
116
- async function generateFullQuiz() {
117
- const planInput = {
118
- totalQuestions: 5,
119
- topics: [{ topic: 'Lịch sử Việt Nam', ratio: 100 }],
120
- bloomLevels: [{ level: 'remembering', ratio: 60 }, { level: 'understanding', ratio: 40 }],
121
- selectedQuestionTypes: ['multiple_choice', 'true_false']
122
- };
123
-
124
- const plan = await generateQuizPlan(planInput);
125
-
126
- const quizResult = await generateQuestionsFromQuizPlan({ quizPlan: plan.quizPlan });
127
-
128
- console.log(`${quizResult.generatedQuestions.length} câu hỏi đã được tạo.`);
129
- // => Lưu các câu hỏi này vào DB
130
- }
131
- ```
132
-
133
- ---
134
-
135
- #### **E. `services/` (các file liên quan đến SCORM) & `utils/` - Hộp Dụng cụ & Giao tiếp**
136
-
137
- * **Vai trò:** Cung cấp các công cụ chuyên biệt để hoàn thành các tác vụ cụ thể.
138
- * **Mô tả chi tiết:**
139
- * **`SCORMService.ts`:** Một lớp độc lập để nói chuyện với LMS. Nó không biết gì về quiz, chỉ biết về các lệnh SCORM. `QuizEngine` sẽ sử dụng nó.
140
- * **`generateSCORMManifest`, `generateLauncherHTML`:** Các hàm này nhận dữ liệu và trả về các chuỗi văn bản (XML, HTML). Chúng không có tác dụng phụ (side-effect) và hoàn toàn "thuần khiết" (pure), rất phù hợp cho môi trường headless.
141
- * **`idGenerators.ts`:** Cung cấp hàm `generateUniqueId`, một tiện ích nhỏ nhưng cần thiết khi bạn tạo dữ liệu mới.
142
- * **Tầm quan trọng:** **Hỗ trợ (Supporting)**. Cần thiết cho các chức năng cụ thể như SCORM hoặc khi cần tạo dữ liệu mới.
143
-
144
- Bằng cách kết hợp các thành phần này, bạn có thể xây dựng một hệ thống hoàn chỉnh ở phía backend để tạo, quản lý quiz, và thậm chí mô phỏng các phiên làm bài để kiểm thử mà không cần viết một dòng code giao diện nào.
145
-
146
- ---
147
-
148
- ## II. Các Kiểu Dữ liệu (Types) - Nền tảng của Thư viện
149
-
150
- Trước khi bắt đầu, bạn cần làm quen với các kiểu dữ liệu chính. Mọi tương tác với thư viện đều xoay quanh chúng.
43
+ Before you start, familiarize yourself with the main data types. All interactions with the library revolve around them.
151
44
 
152
45
  ```typescript
153
- import { QuizConfig, QuizQuestion, TrueFalseQuestion } from 'interactive-quiz-kit';
46
+ import { QuizConfig, TrueFalseQuestion } from '@thanh01.pmt/interactive-quiz-kit';
154
47
 
155
- // Tạo một câu hỏi
48
+ // Create a question
156
49
  const myQuestion: TrueFalseQuestion = {
157
50
  id: 'tf-001',
158
51
  questionType: 'true_false',
159
- prompt: 'Mặt trời mọc hướng Tây.',
52
+ prompt: 'The sun rises in the west.',
160
53
  correctAnswer: false,
161
54
  points: 10
162
55
  };
163
56
 
164
- // Tạo một cấu hình quiz hoàn chỉnh
57
+ // Create a complete quiz configuration
165
58
  const myQuizConfig: QuizConfig = {
166
59
  id: 'my-first-headless-quiz',
167
- title: 'Quiz Khoa Học Vui',
60
+ title: 'Fun Science Quiz',
168
61
  questions: [myQuestion],
169
62
  settings: {
170
63
  shuffleQuestions: true,
@@ -173,87 +66,68 @@ const myQuizConfig: QuizConfig = {
173
66
  };
174
67
  ```
175
68
 
176
- **Các kiểu dữ liệu quan trọng nhất:**
177
-
178
- * `QuizConfig`: Toàn bộ cấu hình quiz.
179
- * `QuizQuestion`: Union type của tất cả các loại câu hỏi.
180
- * Các kiểu câu hỏi cụ thể: `MultipleChoiceQuestion`, `FillInTheBlanksQuestion`, `BlocklyProgrammingQuestion`, v.v.
181
- * `QuizResult`: Cấu trúc dữ liệu kết quả trả về.
182
-
183
- ---
184
-
185
- ## III. Sử dụng Dịch vụ Lõi
69
+ **Most important types:** `QuizConfig`, `QuizQuestion`, `QuizResultType`, and specific question types like `MultipleChoiceQuestion`.
186
70
 
187
- ### 1. `QuizEditorService`: Tạo Chỉnh sửa Quiz
71
+ ### 2. `QuizEditorService`: The Quiz Builder
188
72
 
189
- Service này cho phép bạn thực hiện các thao tác CRUD (Create, Read, Update, Delete) trên một đối tượng `QuizConfig`.
73
+ This service allows you to perform CRUD (Create, Read, Update, Delete) operations on a `QuizConfig` object.
190
74
 
191
75
  ```typescript
192
- import { QuizEditorService, emptyQuiz } from 'interactive-quiz-kit/services';
193
- import type { QuestionTypeStrings } from 'interactive-quiz-kit';
76
+ import { QuizEditorService, emptyQuiz } from '@thanh01.pmt/interactive-quiz-kit';
77
+ import type { TrueFalseQuestion } from '@thanh01.pmt/interactive-quiz-kit';
194
78
 
195
- // Bắt đầu với một quiz rỗng
79
+ // Start with an empty quiz
196
80
  const editor = new QuizEditorService(emptyQuiz);
197
81
 
198
- // Tạo một template câu hỏi trắc nghiệm mới
199
- const mcqTemplate = QuizEditorService.createNewQuestionTemplate('multiple_choice');
200
-
201
- // Cập nhật thông tin cho câu hỏi
202
- mcqTemplate.prompt = "Hành tinh nào gần mặt trời nhất?";
203
- if (mcqTemplate.questionType === 'multiple_choice') {
204
- mcqTemplate.options = [
205
- { id: 'opt1', text: 'Trái Đất' },
206
- { id: 'opt2', text: 'Sao Hỏa' },
207
- { id: 'opt3', text: 'Sao Thủy' },
208
- ];
209
- mcqTemplate.correctAnswerId = 'opt3';
210
- }
82
+ // Create a new True/False question template
83
+ const tfQuestion = QuizEditorService.createNewQuestionTemplate('true_false') as TrueFalseQuestion;
211
84
 
212
- // Thêm câu hỏi vào quiz
213
- editor.addQuestion(mcqTemplate);
85
+ // Update the question's details
86
+ tfQuestion.prompt = "Is the Earth a perfect sphere?";
87
+ tfQuestion.correctAnswer = false;
214
88
 
215
- // Xóa câu hỏi (nếu cần, ví dụ tại index 0)
216
- // editor.deleteQuestionByIndex(0);
89
+ // Add the question to the quiz
90
+ editor.addQuestion(tfQuestion);
217
91
 
218
- // Lấy đối tượng QuizConfig cuối cùng
92
+ // Get the final QuizConfig object
219
93
  const finalQuizConfig = editor.getQuiz();
220
94
 
221
95
  console.log(JSON.stringify(finalQuizConfig, null, 2));
222
96
  ```
223
97
 
224
- ### 2. `QuizEngine`: Chạy một Phiên làm bài Quiz
98
+ ### 3. `QuizEngine`: The Runtime Conductor
225
99
 
226
- Service này bộ não xử logic khi một người dùng đang làm bài quiz.
100
+ This service is the brain that processes the logic when a user is taking a quiz.
227
101
 
228
102
  ```typescript
229
- import { QuizEngine } from 'interactive-quiz-kit/services';
230
- import type { QuizConfig, QuizResult } from 'interactive-quiz-kit';
103
+ import { QuizEngine } from '@thanh01.pmt/interactive-quiz-kit';
104
+ import type { QuizConfig, QuizResultType } from '@thanh01.pmt/interactive-quiz-kit';
231
105
 
232
- // Giả sử bạn đã một đối tượng myQuizConfig
106
+ // Assume you have a myQuizConfig object
233
107
  const myQuizConfig: QuizConfig = /* ... */;
234
108
 
235
- console.log("Bắt đầu quiz...");
109
+ console.log("Starting quiz...");
236
110
 
237
111
  const engine = new QuizEngine({
238
112
  config: myQuizConfig,
239
113
  callbacks: {
240
114
  onQuestionChange: (question, qNum, total) => {
241
- console.log(`\n--- Câu hỏi ${qNum}/${total} ---`);
115
+ console.log(`\n--- Question ${qNum}/${total} ---`);
242
116
  console.log(question?.prompt);
243
117
  },
244
- onQuizFinish: (result: QuizResult) => {
245
- console.log("\n--- KẾT QUẢ ---");
246
- console.log(`Điểm số: ${result.score}/${result.maxScore}`);
247
- console.log(`Phần trăm: ${result.percentage.toFixed(2)}%`);
248
- console.log(`Trạng thái: ${result.passed ? 'Đạt' : 'Không đạt'}`);
118
+ onQuizFinish: (result: QuizResultType) => {
119
+ console.log("\n--- RESULTS ---");
120
+ console.log(`Score: ${result.score}/${result.maxScore}`);
121
+ console.log(`Percentage: ${result.percentage.toFixed(2)}%`);
122
+ console.log(`Status: ${result.passed ? 'Passed' : 'Failed'}`);
249
123
  }
250
124
  }
251
125
  });
252
126
 
253
- // phỏng quá trình làm bài
127
+ // Simulate the quiz-taking process
254
128
  const question1 = engine.getCurrentQuestion();
255
129
  if (question1) {
256
- // Giả sử câu 1 True/False
130
+ // Assuming question 1 is True/False
257
131
  engine.submitAnswer(question1.id, false);
258
132
  }
259
133
 
@@ -261,73 +135,112 @@ engine.nextQuestion();
261
135
 
262
136
  const question2 = engine.getCurrentQuestion();
263
137
  if (question2) {
264
- // Giả sử câu 2 Multiple Choice
265
- engine.submitAnswer(question2.id, 'id_cua_dap_an_dung');
138
+ // Assuming question 2 is Multiple Choice
139
+ engine.submitAnswer(question2.id, 'id_of_the_correct_answer');
266
140
  }
267
141
 
268
- // Kết thúc quiz
142
+ // Finish the quiz
269
143
  engine.calculateResults();
270
144
  ```
271
145
 
146
+ ### 4. `TopicDataService`: The Curriculum Manager
147
+
148
+ This service manages learning objective data imported from TSV files, powering the "Practice with AI" feature.
149
+
150
+ ```typescript
151
+ import { TopicDataService } from '@thanh01.pmt/interactive-quiz-kit';
152
+ import type { LearningObjective } from '@thanh01.pmt/interactive-quiz-kit';
153
+ // In a browser environment:
154
+ // import tsvContent from './my_curriculum.tsv?raw';
155
+
156
+ // const { data, errors } = TopicDataService.parseTSV(tsvContent);
157
+ // if (errors.length === 0) {
158
+ // TopicDataService.saveData(data);
159
+ // }
160
+
161
+ // const subjects = TopicDataService.getSubjects();
162
+ // console.log('Available Subjects:', subjects);
163
+ ```
164
+
272
165
  ---
273
166
 
274
- ## IV. Tạo Nội dung bằng AI
167
+ ## III. AI-Powered Content Generation
275
168
 
276
- Bạn thể sử dụng các flow AI để tự động tạo câu hỏi. Các hàm này `async`.
169
+ You can use the AI flows to automatically generate quiz content. These functions are `async`.
277
170
 
278
- *Lưu ý: Để sử dụng, bạn cần môi trường đã cấu hình Google Genkit các biến môi trường cần thiết ( dụ: `GOOGLE_API_KEY`).*
171
+ *Note: To use these, you need a configured Google Genkit environment and the necessary environment variables (e.g., `GOOGLE_API_KEY`).*
279
172
 
280
173
  ```typescript
281
- import { generateMCQQuestion, generateQuizPlan } from 'interactive-quiz-kit/ai';
174
+ import { generateMCQQuestion, generatePracticeQuiz } from '@thanh01.pmt/interactive-quiz-kit/ai';
175
+ import type { LearningObjective } from '@thanh01.pmt/interactive-quiz-kit';
282
176
 
283
177
  async function createAIQuestion() {
284
178
  try {
285
- console.log('Đang tạo câu hỏi trắc nghiệm về Hệ Mặt Trời...');
179
+ console.log('Generating a Multiple Choice question about the Solar System...');
286
180
  const result = await generateMCQQuestion({
287
- topic: 'Hệ Mặt Trời',
288
- difficulty: 'easy'
289
- });
181
+ topic: 'The Solar System',
182
+ difficulty: 'easy',
183
+ language: 'English'
184
+ }, 'YOUR_API_KEY');
290
185
 
291
186
  if (result.question) {
292
- console.log('Câu hỏi đã được tạo:');
293
- console.log(JSON.stringify(result.question, null, 2));
294
- } else {
295
- console.log('AI không thể tạo câu hỏi.');
187
+ console.log('Generated Question:', JSON.stringify(result.question, null, 2));
296
188
  }
297
-
298
189
  } catch (error) {
299
- console.error('Lỗi khi tạo câu hỏi AI:', error);
190
+ console.error('Error generating AI question:', error);
300
191
  }
301
192
  }
302
193
 
194
+ async function createAIPracticeQuiz() {
195
+ try {
196
+ // Assume 'selectedLOs' is an array of LearningObjective objects
197
+ const selectedLOs: LearningObjective[] = /* ... from TopicDataService ... */;
198
+ const result = await generatePracticeQuiz({
199
+ learningObjectives: selectedLOs,
200
+ quizDifficulty: 'Medium',
201
+ language: 'English'
202
+ }, 'YOUR_API_KEY');
203
+
204
+ console.log(`Generated ${result.generatedQuestions?.length || 0} practice questions.`);
205
+ } catch (error) {
206
+ console.error('Error generating practice quiz:', error);
207
+ }
208
+ }
209
+
303
210
  // createAIQuestion();
304
211
  ```
305
212
 
306
213
  ---
307
214
 
308
- ## V. Đóng gói và Xuất bản
215
+ ## IV. Packaging and Publishing
309
216
 
310
- Các hàm này giúp tạo ra các thành phần của một gói SCORM. Chúng trả về nội dung dạng chuỗi (string) bạn thể ghi ra file.
217
+ These functions help create the components of a SCORM package. They return string content that you can write to files.
311
218
 
312
219
  ```typescript
313
- import { generateSCORMManifest, generateLauncherHTML } from 'interactive-quiz-kit/services';
314
- import type { QuizConfig } from 'interactive-quiz-kit';
315
- // import * as fs from 'fs'; // Dùng trong môi trường Node.js
220
+ import { generateSCORMManifest, generateLauncherHTML } from '@thanh01.pmt/interactive-quiz-kit';
221
+ import type { QuizConfig } from '@thanh01.pmt/interactive-quiz-kit';
222
+ // import * as fs from 'fs'; // For use in a Node.js environment
316
223
 
317
- // Giả sử bạn đã một đối tượng myQuizConfig
224
+ // Assume you have a myQuizConfig object
318
225
  const myQuizConfig: QuizConfig = /* ... */;
319
226
 
320
- // Tạo nội dung manifest
227
+ // Generate manifest content
321
228
  const manifestXML = generateSCORMManifest(myQuizConfig, "1.2");
322
229
  console.log('--- imsmanifest.xml ---');
323
230
  console.log(manifestXML);
324
231
  // fs.writeFileSync('dist/imsmanifest.xml', manifestXML);
325
232
 
326
- // Tạo nội dung file HTML launcher
327
- const launcherHTML = generateLauncherHTML(myQuizConfig);
233
+ // Generate HTML launcher content
234
+ const launcherHTML = generateLauncherHTML(
235
+ myQuizConfig,
236
+ 'player.js', // Path to the JS bundle inside the ZIP
237
+ 'quiz_data.json', // Path to the quiz data inside the ZIP
238
+ 'blockly-styles.css', // Path to blockly css
239
+ 'styles.css' // Path to main css
240
+ );
328
241
  console.log('\n--- index.html ---');
329
242
  console.log(launcherHTML);
330
243
  // fs.writeFileSync('dist/index.html', launcherHTML);
331
244
  ```
332
245
 
333
- **Lưu ý:** Hàm `exportQuizAsSCORMZip` được thiết kế để chạy trên trình duyệt tương tác với DOM để kích hoạt tải file. Nếu bạn muốn đóng gói ZIP phía backend, bạn cần sử dụng một thư viện như `jszip` tự mình thực hiện các bước tương tự như trong file `services/scormPackaging.ts`.
246
+ **Note:** The `exportQuizAsSCORMZip` function is designed to run in the browser as it interacts with the DOM to trigger a file download. To package a ZIP on the backend, you would use a library like `jszip` and follow the steps outlined in `services/scormPackaging.ts`.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Interactive Quiz Kit
2
2
 
3
- [![NPM version](https://img.shields.io/npm/v/@thanh01pmt/interactive-quiz-kit.svg)](https://www.npmjs.com/package/@thanh01pmt/interactive-quiz-kit)
3
+ [![NPM version](https://img.shields.io/npm/v/@thanh01.pmt/interactive-quiz-kit.svg)](https://www.npmjs.com/package/@thanh01.pmt/interactive-quiz-kit)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
6
  **Interactive Quiz Kit** is a comprehensive TypeScript library built with React, designed to effortlessly create, manage, play, and distribute interactive quizzes. It provides a robust core logic (`QuizEngine`), reusable React UI components, and support for a wide variety of question types.
@@ -9,43 +9,51 @@ The library is architected for easy extension and integration, featuring a power
9
9
 
10
10
  ## ✨ Features
11
11
 
12
- * **Robust Core Engine**: Handles state management, navigation, automatic grading, and time tracking.
13
- * **Rich Question Support**: Includes 12+ question types, from Multiple Choice to complex ones like Blockly/Scratch Programming and Hotspot.
14
- * **React-based UI Kit**: A full suite of components to build quiz players and authoring tools.
15
- * `<QuizPlayer>`: The main component for taking quizzes.
16
- * `<QuizAuthoringTool>`: A powerful interface for creating and editing quizzes.
17
- * **Headless Mode**: Use all core logic, services, and AI flows independently of the React UI. Ideal for backend integrations, custom frontends, or automation scripts.
18
- * **AI-Powered Generation**:
19
- * Generate individual questions based on topic, context, and difficulty.
20
- * Generate entire, well-structured quizzes using a two-stage planning and generation process.
21
- * **SCORM & Webhook Integration**:
22
- * Package quizzes as SCORM 1.2 or 2004 compliant ZIP files.
23
- * Send detailed quiz results to a specified webhook URL.
12
+ * **Robust Core Engine**: Handles state management, navigation, automatic grading, and time tracking.
13
+ * **Rich Question Support**: Includes 12+ question types, from Multiple Choice to complex ones like Blockly/Scratch Programming and Hotspot.
14
+ * **Modular React UI Kit**: A full suite of components to build quiz players and authoring tools, organized into logical entry points.
15
+ * **Headless Mode**: Use all core logic, services, and AI flows independently of the React UI. Ideal for backend integrations, custom frontends, or automation scripts.
16
+ * **Advanced AI Capabilities**:
17
+ * **Single Question Generation**: Create individual questions based on topic, context, and difficulty.
18
+ * **Full Quiz Generation**: Generate entire, well-structured quizzes using a two-stage planning process.
19
+ * **AI-Powered Practice Mode**: Generate personalized 10-question quizzes on-the-fly from a user-provided curriculum.
20
+ * **Flexible Content Import**: Import curriculum data and learning objectives from TSV files to power the AI Practice Mode.
21
+ * **SCORM & Webhook Integration**:
22
+ * Package quizzes as SCORM 1.2 compliant ZIP files.
23
+ * Send detailed quiz results to a specified webhook URL.
24
24
 
25
25
  ## 🚀 Installation
26
26
 
27
27
  ```bash
28
- npm install @thanh01pmt/interactive-quiz-kit
28
+ npm install @thanh01.pmt/interactive-quiz-kit
29
29
  # or
30
- yarn add @thanh01pmt/interactive-quiz-kit
30
+ yarn add @thanh01.pmt/interactive-quiz-kit
31
31
  ```
32
32
 
33
33
  **Peer Dependencies:** This library requires `react` and `react-dom` as peer dependencies. Ensure they are installed in your project.
34
34
 
35
35
  ## 📚 Usage
36
36
 
37
- This library supports two primary modes of usage: with the built-in React UI, or in a "headless" mode using only the core logic.
37
+ This library is modular, allowing you to import only the parts you need.
38
38
 
39
- ### 1. Standard Mode (with React UI)
39
+ ### Understanding the Entry Points
40
40
 
41
- This is the quickest way to get a fully functional quiz application up and running.
41
+ The package is split into several entry points for optimized usage:
42
42
 
43
- #### Example: Displaying a Quiz with `<QuizPlayer>`
43
+ * `@thanh01.pmt/interactive-quiz-kit`: The core "headless" library. Contains all types, services (`QuizEngine`, `QuizEditorService`), and utilities. Use this for backend logic or custom UIs.
44
+ * `@thanh01.pmt/interactive-quiz-kit/react-ui`: General-purpose UI components like `<QuizPlayer>` and `<QuizResult>`.
45
+ * `@thanh01.pmt/interactive-quiz-kit/authoring`: The complete UI suite for creating and editing quizzes, centered around the `<QuizAuthoringTool>` component.
46
+ * `@thanh01.pmt/interactive-quiz-kit/ai`: The headless functions for AI-powered content generation.
47
+ * `@thanh01.pmt/interactive-quiz-kit/player`: A dedicated entry point for the player bundle, useful for SCORM packaging.
48
+
49
+ ### 1. Displaying a Quiz (Player Mode)
50
+
51
+ Use the `<QuizPlayer>` component for the test-taker's experience.
44
52
 
45
53
  ```tsx
46
- import React, { useState } from 'react';
47
- import { QuizPlayer } from '@thanh01pmt/interactive-quiz-kit/react-ui';
48
- import type { QuizConfig, QuizResult } from '@thanh01pmt/interactive-quiz-kit';
54
+ import React from 'react';
55
+ import { QuizPlayer } from '@thanh01.pmt/interactive-quiz-kit/react-ui';
56
+ import type { QuizConfig, QuizResultType } from '@thanh01.pmt/interactive-quiz-kit';
49
57
 
50
58
  // 1. Define or load your quiz configuration
51
59
  const myQuiz: QuizConfig = {
@@ -59,7 +67,7 @@ const myQuiz: QuizConfig = {
59
67
  };
60
68
 
61
69
  const MyQuizPage = () => {
62
- const handleQuizComplete = (result: QuizResult) => {
70
+ const handleQuizComplete = (result: QuizResultType) => {
63
71
  console.log("Quiz Complete!", result);
64
72
  // Send result to your backend, or display a summary
65
73
  };
@@ -75,14 +83,15 @@ const MyQuizPage = () => {
75
83
  };
76
84
  ```
77
85
 
78
- #### Example: Using the `<QuizAuthoringTool>`
86
+ ### 2. Creating Quizzes (Authoring Mode)
79
87
 
80
- Embed the complete authoring experience to allow users to create and edit quizzes.
88
+ Use the `<QuizAuthoringTool>` for a complete content creation interface.
81
89
 
82
90
  ```tsx
83
91
  import React from 'react';
84
- import { QuizAuthoringTool, emptyQuiz } from '@thanh01pmt/interactive-quiz-kit/react-ui';
85
- import type { QuizConfig } from '@thanh01pmt/interactive-quiz-kit';
92
+ import { QuizAuthoringTool } from '@thanh01.pmt/interactive-quiz-kit/authoring';
93
+ import { emptyQuiz } from '@thanh01.pmt/interactive-quiz-kit';
94
+ import type { QuizConfig } from '@thanh01.pmt/interactive-quiz-kit';
86
95
 
87
96
  const MyAuthoringPage = () => {
88
97
  const handleSave = (quiz: QuizConfig) => {
@@ -100,80 +109,59 @@ const MyAuthoringPage = () => {
100
109
  };
101
110
  ```
102
111
 
103
- ### 2. Headless Mode (Core Logic Only)
112
+ ### 3. Using the "Practice with AI" Feature
104
113
 
105
- Use the library's services, types, and AI flows in any JavaScript/TypeScript environment (e.g., Node.js backend, other frontend frameworks, scripts).
114
+ The library includes a complete application flow for AI-powered practice sessions.
106
115
 
107
- > For detailed examples and a full component list, see [**HEADLESS.md**](./HEADLESS.md).
116
+ ```tsx
117
+ import React from 'react';
118
+ // AppController is a conceptual component you would build
119
+ // using the blocks provided by the library.
120
+ import { AppController } from './components/AppController';
121
+
122
+ // This component would render the main menu, allowing users to switch
123
+ // between Authoring, Practice Mode, and Managing Topics.
124
+ const FullApplication = () => {
125
+ return <AppController />;
126
+ };
127
+ ```
128
+
129
+ ### 4. Headless Mode (Core Logic Only)
130
+
131
+ Use the library's services in any JavaScript/TypeScript environment.
108
132
 
109
- #### Example: Creating a Quiz Programmatically with `QuizEditorService`
133
+ > For detailed examples and a full component list, see [**HEADLESS.md**](./HEADLESS.md).
110
134
 
111
- This service allows you to safely manipulate a `QuizConfig` object.
135
+ #### Example: Creating a Quiz Programmatically
112
136
 
113
137
  ```typescript
114
- import { QuizEditorService, emptyQuiz } from '@thanh01pmt/interactive-quiz-kit';
115
- import type { MultipleChoiceQuestion } from '@thanh01pmt/interactive-quiz-kit';
138
+ import { QuizEditorService, emptyQuiz } from '@thanh01.pmt/interactive-quiz-kit';
139
+ import type { MultipleChoiceQuestion } from '@thanh01.pmt/interactive-quiz-kit';
116
140
 
117
141
  // Start with an empty quiz config
118
142
  const editor = new QuizEditorService(emptyQuiz);
119
143
 
120
- // Create a question template
144
+ // Create and populate a question
121
145
  const mcqTemplate = QuizEditorService.createNewQuestionTemplate('multiple_choice') as MultipleChoiceQuestion;
122
-
123
- // Populate the question details
124
146
  mcqTemplate.prompt = "What is the capital of France?";
125
147
  mcqTemplate.options = [
126
148
  { id: 'opt1', text: 'Berlin' },
127
149
  { id: 'opt2', text: 'Paris' },
128
- { id: 'opt3', text: 'Madrid' },
129
150
  ];
130
151
  mcqTemplate.correctAnswerId = 'opt2';
131
152
 
132
- // Add the question to the quiz
133
153
  editor.addQuestion(mcqTemplate);
134
-
135
- // Get the final, updated quiz configuration
136
154
  const finalQuizConfig = editor.getQuiz();
137
155
 
138
- // Now you can save `finalQuizConfig` to your database
139
156
  console.log(finalQuizConfig);
140
157
  ```
141
158
 
142
- #### Example: Running a Quiz Session with `QuizEngine`
143
-
144
- This is useful for backend-driven quizzes or for running simulations.
145
-
146
- ```typescript
147
- import { QuizEngine } from '@thanh01pmt/interactive-quiz-kit';
148
- import type { QuizConfig, QuizResult } from '@thanh01pmt/interactive-quiz-kit';
149
-
150
- const myQuizConfig: QuizConfig = /* ... load your quiz config ... */;
151
-
152
- const engine = new QuizEngine({
153
- config: myQuizConfig,
154
- callbacks: {
155
- onQuizFinish: (result: QuizResult) => {
156
- console.log(`Quiz finished! Final score: ${result.score}`);
157
- }
158
- }
159
- });
160
-
161
- // Simulate answering the first question
162
- const firstQuestion = engine.getCurrentQuestion();
163
- if (firstQuestion) {
164
- engine.submitAnswer(firstQuestion.id, 'id_of_the_user_answer');
165
- }
166
-
167
- // Finalize the quiz
168
- engine.calculateResults();
169
- ```
170
-
171
159
  #### Example: Generating a Question with AI
172
160
 
173
- Leverage Google Gemini to create quiz content on the fly. *Requires Genkit environment setup.*
161
+ *Requires Genkit environment setup.*
174
162
 
175
163
  ```typescript
176
- import { generateTrueFalseQuestion } from '@thanh01pmt/interactive-quiz-kit/ai';
164
+ import { generateTrueFalseQuestion } from '@thanh01.pmt/interactive-quiz-kit/ai';
177
165
 
178
166
  async function createNewQuestion() {
179
167
  try {
@@ -184,7 +172,6 @@ async function createNewQuestion() {
184
172
 
185
173
  if (question) {
186
174
  console.log("AI-generated question:", question);
187
- // Save to your database
188
175
  }
189
176
  } catch (error) {
190
177
  console.error("Failed to generate question:", error);
@@ -195,35 +182,36 @@ async function createNewQuestion() {
195
182
  ## Supported Question Types
196
183
 
197
184
  The library supports a wide array of 12+ question types, including:
198
- - `multiple_choice`
199
- - `multiple_response`
200
- - `true_false`
201
- - `short_answer`
202
- - `numeric`
203
- - `fill_in_the_blanks`
204
- - `sequence`
205
- - `matching`
206
- - `drag_and_drop`
207
- - `hotspot`
208
- - `blockly_programming`
209
- - `scratch_programming`
185
+
186
+ * `multiple_choice`
187
+ * `multiple_response`
188
+ * `true_false`
189
+ * `short_answer`
190
+ * `numeric`
191
+ * `fill_in_the_blanks`
192
+ * `sequence`
193
+ * `matching`
194
+ * `drag_and_drop`
195
+ * `hotspot`
196
+ * `blockly_programming`
197
+ * `scratch_programming`
210
198
 
211
199
  ## Known Issues
212
200
 
213
- * **Blockly/Scratch Integration**: Requires manual copying of assets (`js`, `css`, `media`) from the `blockly` or `scratch-blocks` packages into your project's `public` folder for the UI components to render correctly.
214
- * **SCORM Packaging**: The `exportQuizAsSCORMZip` function generates a nearly complete package. However, you **must manually** add the library's JavaScript bundle and any necessary CSS (like for Blockly) to the ZIP archive for it to function in an LMS.
215
- * **AI Generation Limits**: AI generation is not yet supported for `Drag and Drop`, `Hotspot`, `Blockly`, or `Scratch` question types due to their complexity.
201
+ * **Asset Integration for Programming Questions**: Using `Blockly` or `Scratch` questions requires manually copying assets (`js`, `css`, `media`) from their respective `node_modules` folders into your project's `public` directory for the UI components to render correctly.
202
+ * **SCORM Packaging**: The SCORM export function relies on fetching the player assets (`player.js`, `styles.css`) from your `public` folder at the time of packaging. Ensure these files are present and accessible.
203
+ * **AI Generation Limits**: AI generation is not yet supported for visually complex types like `Drag and Drop`, `Hotspot`, `Blockly`, or `Scratch`.
216
204
 
217
205
  ## 🤝 Contributing
218
206
 
219
207
  Contributions are welcome! Please feel free to submit a pull request or open an issue if you have ideas for improvements or find a bug.
220
208
 
221
- 1. Fork the repository.
222
- 2. Create your feature branch (`git checkout -b feature/AmazingFeature`).
223
- 3. Commit your changes (`git commit -m 'feat: Add some AmazingFeature'`).
224
- 4. Push to the branch (`git push origin feature/AmazingFeature`).
225
- 5. Open a Pull Request.
209
+ 1. Fork the repository.
210
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`).
211
+ 3. Commit your changes (`git commit -m 'feat: Add some AmazingFeature'`).
212
+ 4. Push to the branch (`git push origin feature/AmazingFeature`).
213
+ 5. Open a Pull Request.
226
214
 
227
215
  ## 📄 License
228
216
 
229
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
217
+ This project is licensed under the MIT License.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thanh01.pmt/interactive-quiz-kit",
3
- "version": "1.0.13",
3
+ "version": "1.0.16",
4
4
  "description": "A comprehensive library for creating, managing, and playing interactive quizzes, with AI generation and SCORM support.",
5
5
  "keywords": [
6
6
  "react",