🧠 SCORM là một "giao thức" giao tiếp giữa nội dung và LMS
SCORM nội dung (file HTML/JS) không biết bạn dùng công nghệ gì (Next.js, Moodle, Firebase...)
Nó chỉ biết rằng khi được mở lên, nó sẽ tìm một đối tượng API gọi là window.API (SCORM 1.2) hoặc window.API_1484_11 (SCORM 2004) và gọi các hàm như:
API.LMSInitialize("")
API.LMSSetValue("cmi.core.score.raw", "85")
API.LMSCommit("")
API.LMSFinish("")
👉 Bạn – phía LMS – phải cung cấp đối tượng đó.
🎯 Nhiệm vụ của bạn:
✅ Cung cấp một "SCORM API Adapter" để nội dung học có thể nói chuyện với LMS của bạn.
🧩 1. SCORM Adapter là gì?
Là đối tượng
APImà bạn phải tạo ra, chứa đầy đủ các hàm SCORM chuẩn (nhưLMSInitialize,LMSSetValue,LMSCommit,...)
Nó đóng vai "người trung gian" giữa nội dung học và hệ thống LMS (database, tracking, Firestore,...)
🔧 Cách làm thủ công:
window.API = {
LMSInitialize: function () { console.log("Initialized"); return "true"; },
LMSSetValue: function (key, value) { console.log("Set", key, value); return "true"; },
LMSCommit: function () { /* Lưu xuống Firestore */; return "true"; },
LMSFinish: function () { return "true"; }
};
⚠️ Vấn đề:
-
Viết tay dễ sai chuẩn SCORM (cần trả về
"true"hay"false", phải cóLMSGetLastError, v.v.) -
Bạn cần implement đầy đủ đặc tả SCORM → phức tạp
🧰 2. SCORM Wrapper (ví dụ: pipwerks)
Là thư viện JavaScript phía nội dung học giúp lập trình viên dễ gọi SCORM API một cách chuẩn.
✨ Pipwerks giúp nội dung học gọi API dễ hơn:
pipwerks.SCORM.init(); // gọi LMSInitialize
pipwerks.SCORM.set("cmi.core.score.raw", 85); // gọi LMSSetValue
pipwerks.SCORM.save(); // gọi LMSCommit
✅ Lợi ích:
-
Đảm bảo gọi đúng chuẩn
-
Kiểm tra xem
APIcó tồn tại không, có gọi thành công không -
Ẩn các chi tiết thấp (check error code, fallback, debug,...)
📌 Pipwerks thường được dùng trong SCORM nội dung, không phải phía LMS.
Tức là: nội dung học dùng wrapper này để gọi đến LMS thông qua window.API.
🚀 3. SCORM Adapter hiện đại: scorm-again
Là thư viện giúp bạn – phía LMS – tạo đối tượng
APIhoặcAPI_1484_11, tuân chuẩn SCORM hoàn chỉnh.
✨ Ví dụ:
import { Scorm12API } from 'scorm-again';
const api = new Scorm12API({
lmsCommitUrl: '/api/save-progress',
autocommit: true,
});
window.API = api;
✅ Lợi ích:
-
Không cần tự implement từng hàm SCORM (đã có sẵn)
-
Dễ dàng gắn event listener để lưu data:
api.on("SetValue.cmi.core.score.raw", (key, value) => { saveToFirestore(score=value) }); -
Có phiên bản SCORM 2004 và 1.2
-
Hỗ trợ async, cross-frame, offline
🧱 So sánh ngắn gọn
SCORM Adapter (scorm-again) |
SCORM Wrapper (pipwerks) |
|
|---|---|---|
| Vai trò | Cung cấp window.API cho SCORM nội dung |
Gọi window.API từ trong SCORM nội dung |
| Chạy ở đâu? | LMS (trang chứa iframe SCORM) | SCORM nội dung (bên trong iframe) |
| Dành cho ai? | Dev xây dựng LMS | Dev xây dựng nội dung SCORM |
| Mục đích | Tiếp nhận các lệnh SCORM (Set/Get/Commit) | Gửi các lệnh SCORM đến LMS |
| Phức tạp | Khá phức tạp nếu tự viết | Đơn giản, chỉ là JS tiện ích |
| Hiện đại hóa | scorm-again: có TypeScript, modular |
pipwerks: legacy JS |
🧠 Tổng kết dễ hiểu
| Nội dung học (iframe) | gọi | pipwerks.SCORM.set(...) → window.API.LMSSetValue(...) |
|---|---|---|
| LMS (Next.js của bạn) | tạo | window.API = scorm-again.Adapter(...) |
→ Cả hai đều cần, nhưng ở hai phía khác nhau:
-
Bạn: dùng
scorm-againđể tạo ra API chuẩn cho SCORM nội dung gọi tới -
Nội dung SCORM (thường do bên thứ ba export ra): dùng
pipwerksđể gọi API
Nếu bạn muốn:
-
Gắn adapter
scorm-againvào iframe host -
Đón dữ liệu SCORM gửi về và lưu vào Firestore
→ Mình có thể viết demo cho bạn ngay, bạn chỉ cần nói muốn SCORM 1.2 hay 2004.