@lessonkit/xapi 1.3.1 → 1.5.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.
- package/README.md +2 -2
- package/dist/index.cjs +684 -130
- package/dist/index.d.cts +47 -2
- package/dist/index.d.ts +47 -2
- package/dist/index.js +676 -130
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -37,8 +37,10 @@ type XAPIQueue = {
|
|
|
37
37
|
flush: (transport: XAPITransport) => Promise<void>;
|
|
38
38
|
flushOnExit: (exitTransport: XAPIExitTransport) => void;
|
|
39
39
|
size: () => number;
|
|
40
|
+
/** Statement id currently being delivered via flush, if any. */
|
|
41
|
+
getHeadInFlightId?: () => string | undefined;
|
|
40
42
|
};
|
|
41
|
-
type XAPIExitTransport = (statement: XAPIStatement) => void
|
|
43
|
+
type XAPIExitTransport = (statement: XAPIStatement) => void | Promise<void>;
|
|
42
44
|
type XAPIClient = {
|
|
43
45
|
send: (statement: XAPIStatement) => void;
|
|
44
46
|
flush: () => Promise<void>;
|
|
@@ -65,24 +67,54 @@ type InMemoryXAPIQueueOptions = {
|
|
|
65
67
|
onDepth?: (size: number) => void;
|
|
66
68
|
/** Called when an oldest statement is dropped because the queue is at maxSize. */
|
|
67
69
|
onCap?: () => void;
|
|
70
|
+
/** Called when a statement cannot be enqueued because the queue is full and the head is in-flight. */
|
|
71
|
+
onOverflow?: (statement: XAPIStatement) => void;
|
|
72
|
+
/** Failures at queue head before skipping (default 10). */
|
|
73
|
+
maxHeadFailures?: number;
|
|
74
|
+
/** Called when the queue head is skipped after repeated transport failures. */
|
|
75
|
+
onHeadSkipped?: (statement: XAPIStatement, err: unknown) => void;
|
|
68
76
|
};
|
|
69
77
|
declare function createInMemoryXAPIQueue(opts?: InMemoryXAPIQueueOptions): XAPIQueue;
|
|
70
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Imperative xAPI client with in-memory queue, retry flush, and optional pagehide delivery.
|
|
81
|
+
* Prefer wiring transport via `LessonkitProvider` config from `@lessonkit/react` in React apps.
|
|
82
|
+
*/
|
|
71
83
|
declare function createXAPIClient(opts?: {
|
|
72
84
|
transport?: XAPITransport;
|
|
73
85
|
/** Keepalive transport for pagehide flush (e.g. from createFetchTransport). */
|
|
74
86
|
exitTransport?: XAPIExitTransport;
|
|
87
|
+
/** Abort in-flight transport by statement id (e.g. from createFetchTransport). */
|
|
88
|
+
abortInFlight?: (statementId: string) => void;
|
|
75
89
|
courseId?: CourseId;
|
|
76
90
|
queue?: XAPIQueue;
|
|
77
91
|
/** When creating the default in-memory queue (max size 1000 unless overridden). */
|
|
78
92
|
maxQueueSize?: number;
|
|
93
|
+
/** Consecutive head failures before skip (default queue only). */
|
|
94
|
+
maxHeadFailures?: number;
|
|
79
95
|
onQueueDepth?: (size: number) => void;
|
|
80
96
|
onQueueCap?: () => void;
|
|
97
|
+
onHeadSkipped?: (statement: XAPIStatement, err: unknown) => void;
|
|
98
|
+
/** Called when transport fails after retries (statement is re-queued). */
|
|
99
|
+
onTransportError?: (err: unknown) => void;
|
|
100
|
+
/** Called when telemetry → xAPI mapping fails. */
|
|
101
|
+
onMappingError?: (err: unknown) => void;
|
|
81
102
|
}): XAPIClient;
|
|
103
|
+
/** @internal Reset dead-letter storage between tests. */
|
|
104
|
+
declare function resetXAPIDeadLetterForTests(): void;
|
|
105
|
+
|
|
106
|
+
type AssertSafeLrsUrlOptions = {
|
|
107
|
+
/** Allow loopback, RFC1918, link-local, and metadata IPs (default false). */
|
|
108
|
+
allowPrivateHosts?: boolean;
|
|
109
|
+
};
|
|
110
|
+
/** Validate an LRS or analytics proxy URL before browser fetch transport use. */
|
|
111
|
+
declare function assertSafeLrsUrl(url: string, opts?: AssertSafeLrsUrlOptions): void;
|
|
82
112
|
|
|
83
113
|
type CreateFetchTransportOptions = {
|
|
84
114
|
/** LRS or proxy endpoint (POST). */
|
|
85
115
|
url: string;
|
|
116
|
+
/** Allow loopback and private-network hosts (default false). */
|
|
117
|
+
allowPrivateHosts?: boolean;
|
|
86
118
|
/** Per-request timeout (default 30_000 ms). Uses AbortSignal.timeout when available. */
|
|
87
119
|
timeoutMs?: number;
|
|
88
120
|
/** Static headers merged into each request (e.g. Authorization from a short-lived token). */
|
|
@@ -100,7 +132,17 @@ type FetchTransportBundle = {
|
|
|
100
132
|
transport: XAPITransport;
|
|
101
133
|
/** Best-effort synchronous delivery for pagehide (keepalive fetch). */
|
|
102
134
|
exitTransport: (statement: XAPIStatement) => void;
|
|
135
|
+
/** Abort an in-flight transport request by statement id (used on pagehide). */
|
|
136
|
+
abortInFlight: (statementId: string) => void;
|
|
103
137
|
};
|
|
138
|
+
/** HTTP error from fetch transport with status for retry policy. */
|
|
139
|
+
declare class FetchHttpError extends Error {
|
|
140
|
+
readonly status: number;
|
|
141
|
+
constructor(status: number, statusText: string, kind?: "xapi" | "batch");
|
|
142
|
+
}
|
|
143
|
+
/** Retry 429 and 5xx; do not retry other 4xx (auth/config errors). */
|
|
144
|
+
declare function isRetryableFetchHttpStatus(status: number): boolean;
|
|
145
|
+
declare function isRetryableFetchError(err: unknown): boolean;
|
|
104
146
|
/**
|
|
105
147
|
* Creates an xAPI transport backed by fetch with timeout, retry backoff, and a
|
|
106
148
|
* keepalive exit transport for pagehide delivery.
|
|
@@ -117,10 +159,13 @@ type FetchBatchSinkBundle = {
|
|
|
117
159
|
*/
|
|
118
160
|
declare function createFetchBatchSink(opts: CreateFetchBatchSinkOptions): FetchBatchSinkBundle;
|
|
119
161
|
|
|
162
|
+
declare function loadDeadLetterStatements(): XAPIStatement[];
|
|
163
|
+
declare function persistDeadLetterStatement(statement: XAPIStatement): void;
|
|
164
|
+
|
|
120
165
|
/**
|
|
121
166
|
* Map a LessonKit telemetry event to an xAPI statement, or null if the event should not emit xAPI.
|
|
122
167
|
* `lesson_time_on_task` returns null (companion metric; lesson_completed carries duration).
|
|
123
168
|
*/
|
|
124
169
|
declare function telemetryEventToXAPIStatement(event: TelemetryEvent): XAPIStatement | null;
|
|
125
170
|
|
|
126
|
-
export { type CreateFetchBatchSinkOptions, type CreateFetchTransportOptions, type FetchBatchSinkBundle, type FetchTransportBundle, type InMemoryXAPIQueueOptions, type XAPIClient, type XAPIExitTransport, type XAPIObjectDefinition, type XAPIQueue, type XAPIResult, type XAPIScore, type XAPIStatement, type XAPITransport, type XAPIVerbIri, createFetchBatchSink, createFetchTransport, createInMemoryXAPIQueue, createXAPIClient, telemetryEventToXAPIStatement };
|
|
171
|
+
export { type AssertSafeLrsUrlOptions, type CreateFetchBatchSinkOptions, type CreateFetchTransportOptions, type FetchBatchSinkBundle, FetchHttpError, type FetchTransportBundle, type InMemoryXAPIQueueOptions, type XAPIClient, type XAPIExitTransport, type XAPIObjectDefinition, type XAPIQueue, type XAPIResult, type XAPIScore, type XAPIStatement, type XAPITransport, type XAPIVerbIri, assertSafeLrsUrl, createFetchBatchSink, createFetchTransport, createInMemoryXAPIQueue, createXAPIClient, isRetryableFetchError, isRetryableFetchHttpStatus, loadDeadLetterStatements, persistDeadLetterStatement, resetXAPIDeadLetterForTests, telemetryEventToXAPIStatement };
|
package/dist/index.d.ts
CHANGED
|
@@ -37,8 +37,10 @@ type XAPIQueue = {
|
|
|
37
37
|
flush: (transport: XAPITransport) => Promise<void>;
|
|
38
38
|
flushOnExit: (exitTransport: XAPIExitTransport) => void;
|
|
39
39
|
size: () => number;
|
|
40
|
+
/** Statement id currently being delivered via flush, if any. */
|
|
41
|
+
getHeadInFlightId?: () => string | undefined;
|
|
40
42
|
};
|
|
41
|
-
type XAPIExitTransport = (statement: XAPIStatement) => void
|
|
43
|
+
type XAPIExitTransport = (statement: XAPIStatement) => void | Promise<void>;
|
|
42
44
|
type XAPIClient = {
|
|
43
45
|
send: (statement: XAPIStatement) => void;
|
|
44
46
|
flush: () => Promise<void>;
|
|
@@ -65,24 +67,54 @@ type InMemoryXAPIQueueOptions = {
|
|
|
65
67
|
onDepth?: (size: number) => void;
|
|
66
68
|
/** Called when an oldest statement is dropped because the queue is at maxSize. */
|
|
67
69
|
onCap?: () => void;
|
|
70
|
+
/** Called when a statement cannot be enqueued because the queue is full and the head is in-flight. */
|
|
71
|
+
onOverflow?: (statement: XAPIStatement) => void;
|
|
72
|
+
/** Failures at queue head before skipping (default 10). */
|
|
73
|
+
maxHeadFailures?: number;
|
|
74
|
+
/** Called when the queue head is skipped after repeated transport failures. */
|
|
75
|
+
onHeadSkipped?: (statement: XAPIStatement, err: unknown) => void;
|
|
68
76
|
};
|
|
69
77
|
declare function createInMemoryXAPIQueue(opts?: InMemoryXAPIQueueOptions): XAPIQueue;
|
|
70
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Imperative xAPI client with in-memory queue, retry flush, and optional pagehide delivery.
|
|
81
|
+
* Prefer wiring transport via `LessonkitProvider` config from `@lessonkit/react` in React apps.
|
|
82
|
+
*/
|
|
71
83
|
declare function createXAPIClient(opts?: {
|
|
72
84
|
transport?: XAPITransport;
|
|
73
85
|
/** Keepalive transport for pagehide flush (e.g. from createFetchTransport). */
|
|
74
86
|
exitTransport?: XAPIExitTransport;
|
|
87
|
+
/** Abort in-flight transport by statement id (e.g. from createFetchTransport). */
|
|
88
|
+
abortInFlight?: (statementId: string) => void;
|
|
75
89
|
courseId?: CourseId;
|
|
76
90
|
queue?: XAPIQueue;
|
|
77
91
|
/** When creating the default in-memory queue (max size 1000 unless overridden). */
|
|
78
92
|
maxQueueSize?: number;
|
|
93
|
+
/** Consecutive head failures before skip (default queue only). */
|
|
94
|
+
maxHeadFailures?: number;
|
|
79
95
|
onQueueDepth?: (size: number) => void;
|
|
80
96
|
onQueueCap?: () => void;
|
|
97
|
+
onHeadSkipped?: (statement: XAPIStatement, err: unknown) => void;
|
|
98
|
+
/** Called when transport fails after retries (statement is re-queued). */
|
|
99
|
+
onTransportError?: (err: unknown) => void;
|
|
100
|
+
/** Called when telemetry → xAPI mapping fails. */
|
|
101
|
+
onMappingError?: (err: unknown) => void;
|
|
81
102
|
}): XAPIClient;
|
|
103
|
+
/** @internal Reset dead-letter storage between tests. */
|
|
104
|
+
declare function resetXAPIDeadLetterForTests(): void;
|
|
105
|
+
|
|
106
|
+
type AssertSafeLrsUrlOptions = {
|
|
107
|
+
/** Allow loopback, RFC1918, link-local, and metadata IPs (default false). */
|
|
108
|
+
allowPrivateHosts?: boolean;
|
|
109
|
+
};
|
|
110
|
+
/** Validate an LRS or analytics proxy URL before browser fetch transport use. */
|
|
111
|
+
declare function assertSafeLrsUrl(url: string, opts?: AssertSafeLrsUrlOptions): void;
|
|
82
112
|
|
|
83
113
|
type CreateFetchTransportOptions = {
|
|
84
114
|
/** LRS or proxy endpoint (POST). */
|
|
85
115
|
url: string;
|
|
116
|
+
/** Allow loopback and private-network hosts (default false). */
|
|
117
|
+
allowPrivateHosts?: boolean;
|
|
86
118
|
/** Per-request timeout (default 30_000 ms). Uses AbortSignal.timeout when available. */
|
|
87
119
|
timeoutMs?: number;
|
|
88
120
|
/** Static headers merged into each request (e.g. Authorization from a short-lived token). */
|
|
@@ -100,7 +132,17 @@ type FetchTransportBundle = {
|
|
|
100
132
|
transport: XAPITransport;
|
|
101
133
|
/** Best-effort synchronous delivery for pagehide (keepalive fetch). */
|
|
102
134
|
exitTransport: (statement: XAPIStatement) => void;
|
|
135
|
+
/** Abort an in-flight transport request by statement id (used on pagehide). */
|
|
136
|
+
abortInFlight: (statementId: string) => void;
|
|
103
137
|
};
|
|
138
|
+
/** HTTP error from fetch transport with status for retry policy. */
|
|
139
|
+
declare class FetchHttpError extends Error {
|
|
140
|
+
readonly status: number;
|
|
141
|
+
constructor(status: number, statusText: string, kind?: "xapi" | "batch");
|
|
142
|
+
}
|
|
143
|
+
/** Retry 429 and 5xx; do not retry other 4xx (auth/config errors). */
|
|
144
|
+
declare function isRetryableFetchHttpStatus(status: number): boolean;
|
|
145
|
+
declare function isRetryableFetchError(err: unknown): boolean;
|
|
104
146
|
/**
|
|
105
147
|
* Creates an xAPI transport backed by fetch with timeout, retry backoff, and a
|
|
106
148
|
* keepalive exit transport for pagehide delivery.
|
|
@@ -117,10 +159,13 @@ type FetchBatchSinkBundle = {
|
|
|
117
159
|
*/
|
|
118
160
|
declare function createFetchBatchSink(opts: CreateFetchBatchSinkOptions): FetchBatchSinkBundle;
|
|
119
161
|
|
|
162
|
+
declare function loadDeadLetterStatements(): XAPIStatement[];
|
|
163
|
+
declare function persistDeadLetterStatement(statement: XAPIStatement): void;
|
|
164
|
+
|
|
120
165
|
/**
|
|
121
166
|
* Map a LessonKit telemetry event to an xAPI statement, or null if the event should not emit xAPI.
|
|
122
167
|
* `lesson_time_on_task` returns null (companion metric; lesson_completed carries duration).
|
|
123
168
|
*/
|
|
124
169
|
declare function telemetryEventToXAPIStatement(event: TelemetryEvent): XAPIStatement | null;
|
|
125
170
|
|
|
126
|
-
export { type CreateFetchBatchSinkOptions, type CreateFetchTransportOptions, type FetchBatchSinkBundle, type FetchTransportBundle, type InMemoryXAPIQueueOptions, type XAPIClient, type XAPIExitTransport, type XAPIObjectDefinition, type XAPIQueue, type XAPIResult, type XAPIScore, type XAPIStatement, type XAPITransport, type XAPIVerbIri, createFetchBatchSink, createFetchTransport, createInMemoryXAPIQueue, createXAPIClient, telemetryEventToXAPIStatement };
|
|
171
|
+
export { type AssertSafeLrsUrlOptions, type CreateFetchBatchSinkOptions, type CreateFetchTransportOptions, type FetchBatchSinkBundle, FetchHttpError, type FetchTransportBundle, type InMemoryXAPIQueueOptions, type XAPIClient, type XAPIExitTransport, type XAPIObjectDefinition, type XAPIQueue, type XAPIResult, type XAPIScore, type XAPIStatement, type XAPITransport, type XAPIVerbIri, assertSafeLrsUrl, createFetchBatchSink, createFetchTransport, createInMemoryXAPIQueue, createXAPIClient, isRetryableFetchError, isRetryableFetchHttpStatus, loadDeadLetterStatements, persistDeadLetterStatement, resetXAPIDeadLetterForTests, telemetryEventToXAPIStatement };
|