xAPI reference (@lessonkit/xapi)¶
Statement generation, in-memory queueing, and telemetry-to-xAPI mapping for LessonKit courses.
For event names and when they fire, see the telemetry reference. For React wiring (Course config, transports), see Telemetry & xAPI.
Install¶
npm install @lessonkit/xapi
Peer usage: @lessonkit/core (telemetry types and URNs).
Public API¶
Export |
Purpose |
|---|---|
|
Canonical mapper from |
|
Imperative lifecycle helpers + queued send; optional |
|
Production fetch transport with timeout, retry backoff, keepalive |
|
Batch analytics POST with matching |
|
Default queue when transport fails or is async (max 1000 statements; oldest dropped when full) |
|
Types |
Recommended transport (production)¶
import { createFetchTransport, createXAPIClient } from "@lessonkit/xapi";
const { transport, exitTransport, abortInFlight } = createFetchTransport({
url: "/api/xapi/statements",
timeoutMs: 30_000,
headers: () => ({ Authorization: `Bearer ${getShortLivedToken()}` }),
});
const client = createXAPIClient({
courseId: "my-course",
transport,
exitTransport,
abortInFlight,
});
await client.flush();
client.flushOnExit?.(); // pagehide keepalive drain
Custom fetch transports should use AbortSignal.timeout(ms) and handle non-OK responses by throwing so statements re-queue.
Telemetry → xAPI mapping¶
Canonical mapper: telemetryEventToXAPIStatement(event) in @lessonkit/xapi.
Telemetry |
xAPI verb |
Object URN |
|---|---|---|
|
initialized |
|
|
completed |
|
|
initialized |
|
|
completed |
|
|
(none) |
Returns |
|
answered |
|
|
completed |
|
|
answered |
|
|
completed |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
completed |
|
|
experienced |
|
|
experienced |
|
|
experienced |
|
|
completed |
|
|
experienced |
|
|
experienced |
|
For block-level interaction events, set blockId on Scenario / Reflection and ensure an active lessonId. See telemetry reference for the full event catalog.
React runtime¶
LessonkitProvider / Course call telemetryEventToXAPIStatement after each tracked event when config.xapi.transport or config.xapi.client is set. Pass exitTransport and abortInFlight alongside transport (from createFetchTransport) for pagehide delivery. If you pass a prebuilt config.xapi.client, wire queue observability hooks yourself — the provider only attaches onXapiQueueDepth / onXapiQueueCap when it builds the client from transport. Course-level initialized is sent once per session when both tracking and xAPI are enabled.
Direct createXAPIClient usage is optional for non-React tooling; prefer the mapper for parity with telemetry URNs.
Transport errors¶
If transport throws or rejects, statements are retained in the in-memory queue. Call await client.flush() to retry. The React provider calls flushOnExit() then flush() when the tab is hidden (visibilitychange / pagehide).
When the queue exceeds maxSize (default 1000), the oldest statement is dropped and onCap runs (wire via config.observability.onXapiQueueCap in React). Under prolonged LRS outage, statements are lost silently unless you monitor queue depth via onXapiQueueDepth or handle onXapiQueueCap. See production checklist and LRS operations.
Dead-letter and URL safety (advanced)¶
Export |
Purpose |
|---|---|
|
Persist a statement that exceeded retry/cap to |
|
Read persisted dead-letter statements |
|
Clear dead-letter storage in tests ( |
|
Reject unsafe LRS URLs (credentials in URL, private hosts in production) |
|
Whether a transport error should retry |
|
HTTP statuses eligible for retry (429, 5xx) |
|
Typed error from fetch transport with |
Ops pattern: Wire onXapiTransportError and onXapiQueueCap in config.observability. On cap, export dead letters with loadDeadLetterStatements and replay through your backend proxy when the LRS recovers. Never point production courses at a public LRS with embedded credentials — use assertSafeLrsUrl in custom transports.