@lessonkit/lxpack 1.4.0 → 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 +35 -7
- package/dist/bridge.cjs +160 -41
- package/dist/bridge.d.cts +27 -9
- package/dist/bridge.d.ts +27 -9
- package/dist/bridge.js +96 -27
- package/dist/chunk-HTZR4CF3.js +94 -0
- package/dist/index.cjs +434 -111
- package/dist/index.d.cts +23 -5
- package/dist/index.d.ts +23 -5
- package/dist/index.js +401 -98
- package/dist/telemetry-0fIWoomS.d.cts +17 -0
- package/dist/telemetry-0fIWoomS.d.ts +17 -0
- package/package.json +5 -5
- package/dist/chunk-DYQI222N.js +0 -41
- package/dist/telemetry-gCxlwc7I.d.cts +0 -9
- package/dist/telemetry-gCxlwc7I.d.ts +0 -9
package/dist/bridge.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BRANCH_TELEMETRY_EVENTS,
|
|
3
|
+
answeredTelemetryToBridgeTrackEvent,
|
|
4
|
+
branchTelemetryToBridgeTrackEvent,
|
|
2
5
|
telemetryEventToLessonkit
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HTZR4CF3.js";
|
|
4
7
|
|
|
5
8
|
// src/bridge.ts
|
|
6
9
|
import {
|
|
@@ -11,7 +14,6 @@ import {
|
|
|
11
14
|
import {
|
|
12
15
|
createLxpackBridgeHost,
|
|
13
16
|
DEFAULT_BRIDGE_PASSING_SCORE,
|
|
14
|
-
getLxpackBridge,
|
|
15
17
|
LXPACK_BRIDGE_VERSIONS,
|
|
16
18
|
normalizePassingThreshold as normalizePassingThreshold2,
|
|
17
19
|
normalizeScore as normalizeScore2,
|
|
@@ -35,7 +37,41 @@ function normalizeAssessmentPassingScore(opts) {
|
|
|
35
37
|
maxScore: opts?.maxScore
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
|
-
function
|
|
40
|
+
function resolveParentOrigin(parentWindow) {
|
|
41
|
+
if (typeof window === "undefined") return null;
|
|
42
|
+
const parent = parentWindow ?? window.parent;
|
|
43
|
+
if (!parent || parent === window) return null;
|
|
44
|
+
try {
|
|
45
|
+
return parent.location.origin;
|
|
46
|
+
} catch {
|
|
47
|
+
const referrer = typeof document !== "undefined" ? document.referrer : "";
|
|
48
|
+
if (!referrer) return null;
|
|
49
|
+
try {
|
|
50
|
+
return new URL(referrer).origin;
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function isProductionRuntime() {
|
|
57
|
+
try {
|
|
58
|
+
if (import.meta.env?.PROD === true) return true;
|
|
59
|
+
} catch {
|
|
60
|
+
}
|
|
61
|
+
const g = globalThis;
|
|
62
|
+
return typeof g.process !== "undefined" && g.process.env?.NODE_ENV === "production";
|
|
63
|
+
}
|
|
64
|
+
function isParentOriginAllowed(allowedParentOrigins, parentWindow, mode) {
|
|
65
|
+
if (mode === "off") return false;
|
|
66
|
+
if (isProductionRuntime() && !allowedParentOrigins?.length) return false;
|
|
67
|
+
if (!allowedParentOrigins?.length) return true;
|
|
68
|
+
const origin = resolveParentOrigin(parentWindow);
|
|
69
|
+
if (!origin) return false;
|
|
70
|
+
return allowedParentOrigins.includes(origin);
|
|
71
|
+
}
|
|
72
|
+
function getBridge(parentWindow, opts) {
|
|
73
|
+
const mode = opts?.mode ?? "auto";
|
|
74
|
+
if (!isParentOriginAllowed(opts?.allowedParentOrigins, parentWindow, mode)) return null;
|
|
39
75
|
const fromSdk = getLxpackBridgeFromParent(parentWindow);
|
|
40
76
|
if (fromSdk) return fromSdk;
|
|
41
77
|
if (typeof window === "undefined") return null;
|
|
@@ -43,21 +79,33 @@ function getBridge(parentWindow) {
|
|
|
43
79
|
if (!parent || parent === window) return null;
|
|
44
80
|
return parent.lxpackBridge?.v1 ?? parent.lxpack ?? null;
|
|
45
81
|
}
|
|
82
|
+
function getLxpackBridge(parentWindow, opts) {
|
|
83
|
+
return getBridge(parentWindow, opts);
|
|
84
|
+
}
|
|
46
85
|
function isDevEnvironment() {
|
|
86
|
+
try {
|
|
87
|
+
if (import.meta.env?.DEV === true) return true;
|
|
88
|
+
if (import.meta.env?.PROD === true) return false;
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
47
91
|
const g = globalThis;
|
|
48
92
|
return typeof g.process !== "undefined" && g.process.env?.NODE_ENV !== "production";
|
|
49
93
|
}
|
|
50
|
-
function
|
|
94
|
+
function handleBridgeError(err, onBridgeError) {
|
|
95
|
+
onBridgeError?.(err);
|
|
96
|
+
if (isDevEnvironment()) {
|
|
97
|
+
console.warn(
|
|
98
|
+
"[lessonkit/lxpack] lxpack bridge action failed:",
|
|
99
|
+
err instanceof Error ? err.message : err
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function dispatchBridgeAction(bridge, action, opts) {
|
|
51
104
|
if (!action) return;
|
|
52
105
|
try {
|
|
53
106
|
dispatchBridgeActionInner(bridge, action);
|
|
54
107
|
} catch (err) {
|
|
55
|
-
|
|
56
|
-
console.warn(
|
|
57
|
-
"[lessonkit/lxpack] lxpack bridge action failed:",
|
|
58
|
-
err instanceof Error ? err.message : err
|
|
59
|
-
);
|
|
60
|
-
}
|
|
108
|
+
handleBridgeError(err, opts?.onBridgeError);
|
|
61
109
|
}
|
|
62
110
|
}
|
|
63
111
|
function dispatchBridgeActionInner(bridge, action) {
|
|
@@ -110,49 +158,69 @@ function forwardAssessmentCompletedToBridge(bridge, event) {
|
|
|
110
158
|
maxScore: data.maxScore
|
|
111
159
|
});
|
|
112
160
|
}
|
|
113
|
-
function forwardTelemetryToBridge(event, mode = "auto", parentWindow) {
|
|
161
|
+
function forwardTelemetryToBridge(event, mode = "auto", parentWindow, opts) {
|
|
114
162
|
if (mode === "off") return;
|
|
115
|
-
const bridge = getBridge(parentWindow
|
|
163
|
+
const bridge = getBridge(parentWindow, {
|
|
164
|
+
allowedParentOrigins: opts?.allowedParentOrigins,
|
|
165
|
+
mode
|
|
166
|
+
});
|
|
116
167
|
if (!bridge) return;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
168
|
+
try {
|
|
169
|
+
if (event.name === "assessment_completed") {
|
|
170
|
+
forwardAssessmentCompletedToBridge(bridge, event);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const answeredTrack = answeredTelemetryToBridgeTrackEvent(event);
|
|
174
|
+
if (answeredTrack) {
|
|
175
|
+
bridge.track?.(answeredTrack);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const branchTrack = branchTelemetryToBridgeTrackEvent(event);
|
|
179
|
+
if (branchTrack) {
|
|
180
|
+
bridge.track?.(branchTrack);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const lessonkitEvent = telemetryEventToLessonkit(event);
|
|
184
|
+
if (!lessonkitEvent) return;
|
|
185
|
+
const action = mapLessonkitTelemetryToBridgeAction2(lessonkitEvent);
|
|
186
|
+
dispatchBridgeActionInner(bridge, action);
|
|
187
|
+
} catch (err) {
|
|
188
|
+
handleBridgeError(err, opts?.onBridgeError);
|
|
120
189
|
}
|
|
121
|
-
const lessonkitEvent = telemetryEventToLessonkit(event);
|
|
122
|
-
if (!lessonkitEvent) return;
|
|
123
|
-
const action = mapLessonkitTelemetryToBridgeAction2(lessonkitEvent);
|
|
124
|
-
dispatchBridgeAction(bridge, action);
|
|
125
190
|
}
|
|
126
|
-
function createLxpackBridge() {
|
|
127
|
-
return getBridge();
|
|
191
|
+
function createLxpackBridge(opts) {
|
|
192
|
+
return getBridge(void 0, opts);
|
|
128
193
|
}
|
|
129
|
-
function notifyLxpackLessonComplete(lessonId) {
|
|
130
|
-
const bridge = getBridge();
|
|
194
|
+
function notifyLxpackLessonComplete(lessonId, opts) {
|
|
195
|
+
const bridge = getBridge(void 0, opts);
|
|
131
196
|
if (!bridge?.completeLesson) return false;
|
|
132
197
|
bridge.completeLesson(lessonId);
|
|
133
198
|
return true;
|
|
134
199
|
}
|
|
135
|
-
function notifyLxpackCourseComplete() {
|
|
136
|
-
const bridge = getBridge();
|
|
200
|
+
function notifyLxpackCourseComplete(opts) {
|
|
201
|
+
const bridge = getBridge(void 0, opts);
|
|
137
202
|
if (!bridge?.completeCourse) return false;
|
|
138
203
|
bridge.completeCourse();
|
|
139
204
|
return true;
|
|
140
205
|
}
|
|
141
|
-
function notifyLxpackAssessment(payload) {
|
|
142
|
-
const bridge = getBridge();
|
|
206
|
+
function notifyLxpackAssessment(payload, opts) {
|
|
207
|
+
const bridge = getBridge(void 0, opts);
|
|
143
208
|
if (!bridge?.submitAssessment) return false;
|
|
144
209
|
bridge.submitAssessment(payload);
|
|
145
210
|
return true;
|
|
146
211
|
}
|
|
147
212
|
export {
|
|
213
|
+
BRANCH_TELEMETRY_EVENTS,
|
|
148
214
|
DEFAULT_BRIDGE_PASSING_SCORE,
|
|
149
215
|
LESSONKIT_TELEMETRY_EVENTS,
|
|
150
216
|
LXPACK_BRIDGE_VERSIONS,
|
|
217
|
+
branchTelemetryToBridgeTrackEvent,
|
|
151
218
|
createLxpackBridge,
|
|
152
219
|
createLxpackBridgeHost,
|
|
153
220
|
dispatchBridgeAction,
|
|
154
221
|
forwardTelemetryToBridge,
|
|
155
222
|
getLxpackBridge,
|
|
223
|
+
isParentOriginAllowed,
|
|
156
224
|
mapLessonkitTelemetryToBridgeAction,
|
|
157
225
|
mapLessonkitTelemetryToLxpack,
|
|
158
226
|
normalizeAssessmentPassingScore,
|
|
@@ -162,6 +230,7 @@ export {
|
|
|
162
230
|
notifyLxpackAssessment,
|
|
163
231
|
notifyLxpackCourseComplete,
|
|
164
232
|
notifyLxpackLessonComplete,
|
|
233
|
+
resolveParentOrigin,
|
|
165
234
|
supportedBridgeVersions,
|
|
166
235
|
telemetryEventToLessonkit
|
|
167
236
|
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// src/telemetry.ts
|
|
2
|
+
import {
|
|
3
|
+
LESSONKIT_TELEMETRY_EVENTS,
|
|
4
|
+
mapLessonkitTelemetryToLxpack
|
|
5
|
+
} from "@lxpack/tracking-schema";
|
|
6
|
+
var BRANCH_TELEMETRY_EVENTS = ["branch_node_viewed", "branch_selected"];
|
|
7
|
+
var ASSESSMENT_TELEMETRY_EVENTS = ["assessment_answered"];
|
|
8
|
+
var SUPPORTED = /* @__PURE__ */ new Set([
|
|
9
|
+
...LESSONKIT_TELEMETRY_EVENTS,
|
|
10
|
+
...BRANCH_TELEMETRY_EVENTS,
|
|
11
|
+
...ASSESSMENT_TELEMETRY_EVENTS
|
|
12
|
+
]);
|
|
13
|
+
function isQuizAnsweredData(data) {
|
|
14
|
+
return typeof data === "object" && data !== null && typeof data.checkId === "string" && data.checkId.length > 0;
|
|
15
|
+
}
|
|
16
|
+
function isQuizCompletedData(data) {
|
|
17
|
+
return typeof data === "object" && data !== null && typeof data.checkId === "string" && data.checkId.length > 0;
|
|
18
|
+
}
|
|
19
|
+
function isAssessmentAnsweredData(data) {
|
|
20
|
+
return typeof data === "object" && data !== null && typeof data.checkId === "string" && data.checkId.length > 0;
|
|
21
|
+
}
|
|
22
|
+
function isInteractionData(data) {
|
|
23
|
+
return typeof data === "object" && data !== null;
|
|
24
|
+
}
|
|
25
|
+
function isBranchNodeViewedData(data) {
|
|
26
|
+
return typeof data === "object" && data !== null && typeof data.blockId === "string" && typeof data.nodeId === "string";
|
|
27
|
+
}
|
|
28
|
+
function isBranchSelectedData(data) {
|
|
29
|
+
return typeof data === "object" && data !== null && typeof data.blockId === "string" && typeof data.fromNodeId === "string" && typeof data.toNodeId === "string";
|
|
30
|
+
}
|
|
31
|
+
function telemetryEventToLessonkit(event) {
|
|
32
|
+
if (!SUPPORTED.has(event.name)) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
const mapped = {
|
|
36
|
+
name: event.name,
|
|
37
|
+
lessonId: event.lessonId
|
|
38
|
+
};
|
|
39
|
+
if (event.name === "quiz_completed" || event.name === "quiz_answered" || event.name === "assessment_answered") {
|
|
40
|
+
const data = event.data;
|
|
41
|
+
if (!isQuizAnsweredData(data) && !isQuizCompletedData(data) && !isAssessmentAnsweredData(data)) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
mapped.assessmentId = data.checkId;
|
|
45
|
+
if ("score" in data) {
|
|
46
|
+
mapped.score = data.score;
|
|
47
|
+
mapped.maxScore = data.maxScore;
|
|
48
|
+
mapped.passingScore = data.passingScore;
|
|
49
|
+
}
|
|
50
|
+
mapped.data = data;
|
|
51
|
+
} else if (mapped.name === "interaction" && event.data && isInteractionData(event.data)) {
|
|
52
|
+
mapped.data = event.data;
|
|
53
|
+
} else if (event.name === "branch_node_viewed" && isBranchNodeViewedData(event.data)) {
|
|
54
|
+
mapped.data = event.data;
|
|
55
|
+
} else if (event.name === "branch_selected" && isBranchSelectedData(event.data)) {
|
|
56
|
+
mapped.data = event.data;
|
|
57
|
+
}
|
|
58
|
+
return mapped;
|
|
59
|
+
}
|
|
60
|
+
function answeredTelemetryToBridgeTrackEvent(event) {
|
|
61
|
+
if (event.name !== "quiz_answered" && event.name !== "assessment_answered") {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const lessonkitEvent = telemetryEventToLessonkit(event);
|
|
65
|
+
if (!lessonkitEvent?.assessmentId) return null;
|
|
66
|
+
return mapLessonkitTelemetryToLxpack({
|
|
67
|
+
...lessonkitEvent,
|
|
68
|
+
name: "quiz_answered"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function branchTelemetryToBridgeTrackEvent(event) {
|
|
72
|
+
if (event.name === "branch_node_viewed" && isBranchNodeViewedData(event.data)) {
|
|
73
|
+
return {
|
|
74
|
+
type: "interaction",
|
|
75
|
+
id: "branch_node_viewed",
|
|
76
|
+
data: { ...event.data, lessonkitEvent: event.name }
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (event.name === "branch_selected" && isBranchSelectedData(event.data)) {
|
|
80
|
+
return {
|
|
81
|
+
type: "interaction",
|
|
82
|
+
id: "branch_selected",
|
|
83
|
+
data: { ...event.data, lessonkitEvent: event.name }
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
BRANCH_TELEMETRY_EVENTS,
|
|
91
|
+
telemetryEventToLessonkit,
|
|
92
|
+
answeredTelemetryToBridgeTrackEvent,
|
|
93
|
+
branchTelemetryToBridgeTrackEvent
|
|
94
|
+
};
|