@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/README.md
CHANGED
|
@@ -4,9 +4,15 @@
|
|
|
4
4
|
[](https://lessonkit.readthedocs.io/en/latest/reference/packaging.html)
|
|
5
5
|
[](https://github.com/eddiethedean/lessonkit/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
Package Vite SPAs for LMS delivery — SCORM 1.2/2004, standalone, xAPI, and cmi5.
|
|
7
|
+
Package Vite SPAs for LMS delivery — SCORM 1.2/2004, standalone, xAPI, and cmi5. Bundles [`@lxpack/*`](https://www.npmjs.com/org/lxpack) as direct dependencies.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## When to install
|
|
10
|
+
|
|
11
|
+
- Custom packaging pipelines without the CLI
|
|
12
|
+
- Validating `lessonkit.json` / course descriptors in CI
|
|
13
|
+
- Programmatic LMS export from your own build tools
|
|
14
|
+
|
|
15
|
+
Most authors use `lessonkit package` (CLI) which calls this package internally.
|
|
10
16
|
|
|
11
17
|
## Install
|
|
12
18
|
|
|
@@ -14,13 +20,18 @@ Requires Node.js **18+**.
|
|
|
14
20
|
npm install @lessonkit/lxpack
|
|
15
21
|
```
|
|
16
22
|
|
|
23
|
+
Requires Node.js **18+** minimum; **20.19+** recommended for CLI scaffold workflows.
|
|
24
|
+
|
|
17
25
|
## Usage
|
|
18
26
|
|
|
19
27
|
```typescript
|
|
20
|
-
import { packageLessonkitCourse } from "@lessonkit/lxpack";
|
|
28
|
+
import { packageLessonkitCourse, parseLessonkitManifest } from "@lessonkit/lxpack";
|
|
29
|
+
|
|
30
|
+
const manifest = parseLessonkitManifest(await readFile("lessonkit.json", "utf8"));
|
|
31
|
+
if (!manifest.ok) throw manifest.error;
|
|
21
32
|
|
|
22
33
|
const result = await packageLessonkitCourse({
|
|
23
|
-
descriptor:
|
|
34
|
+
descriptor: manifest.value,
|
|
24
35
|
outDir: ".lxpack/course",
|
|
25
36
|
spaDistDir: "dist",
|
|
26
37
|
target: "scorm12",
|
|
@@ -30,19 +41,36 @@ const result = await packageLessonkitCourse({
|
|
|
30
41
|
if (!result.ok) throw new Error("packaging failed");
|
|
31
42
|
```
|
|
32
43
|
|
|
33
|
-
Prefer the CLI: `lessonkit package --target scorm12` reads `lessonkit.json` and runs the same pipeline.
|
|
44
|
+
Prefer the CLI: `lessonkit package --target scorm12` reads `lessonkit.json` and runs the same staged pipeline.
|
|
45
|
+
|
|
46
|
+
## Layouts
|
|
47
|
+
|
|
48
|
+
| Layout | Use case |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| `single-spa` | One Vite SPA for the whole course (CLI default) |
|
|
51
|
+
| `per-lesson-spa` | One dist per lesson (advanced; see packaging reference) |
|
|
34
52
|
|
|
35
53
|
## Browser bridge
|
|
36
54
|
|
|
37
|
-
When embedded in an LXPack iframe, `@lessonkit/react` forwards completion events to `window.parent.lxpackBridge.v1
|
|
55
|
+
When embedded in an LXPack iframe, `@lessonkit/react` forwards completion events to `window.parent.lxpackBridge.v1`:
|
|
38
56
|
|
|
39
57
|
```typescript
|
|
40
58
|
import { forwardTelemetryToBridge } from "@lessonkit/lxpack/bridge";
|
|
41
59
|
```
|
|
42
60
|
|
|
61
|
+
Production builds require `allowedParentOrigins` when `bridge: "auto"`.
|
|
62
|
+
|
|
63
|
+
## Common issues
|
|
64
|
+
|
|
65
|
+
| Symptom | Fix |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| React/manifest ID mismatch | Run strict parity validation; align IDs in `App.tsx` and `lessonkit.json` |
|
|
68
|
+
| xAPI/cmi5 validation failure | Set HTTPS `activityIri` in manifest |
|
|
69
|
+
| Empty `dist/` | Run `lessonkit build` before `package` (or omit `--no-build`) |
|
|
70
|
+
|
|
43
71
|
## Docs
|
|
44
72
|
|
|
45
|
-
[Packaging reference](https://lessonkit.readthedocs.io/en/latest/reference/packaging.html) · [LXPack bridge](https://lessonkit.readthedocs.io/en/latest/reference/lxpack-bridge.html) · [Golden example](https://github.com/eddiethedean/lessonkit/tree/main/examples/lxpack-golden)
|
|
73
|
+
[Packaging reference](https://lessonkit.readthedocs.io/en/latest/reference/packaging.html) · [LXPack bridge](https://lessonkit.readthedocs.io/en/latest/reference/lxpack-bridge.html) · [Manifest](https://lessonkit.readthedocs.io/en/latest/reference/manifest.html) · [Golden example](https://github.com/eddiethedean/lessonkit/tree/main/examples/lxpack-golden) · [TypeDoc API index](https://lessonkit.readthedocs.io/en/latest/reference/api.html)
|
|
46
74
|
|
|
47
75
|
## License
|
|
48
76
|
|
package/dist/bridge.cjs
CHANGED
|
@@ -20,14 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/bridge.ts
|
|
21
21
|
var bridge_exports = {};
|
|
22
22
|
__export(bridge_exports, {
|
|
23
|
+
BRANCH_TELEMETRY_EVENTS: () => BRANCH_TELEMETRY_EVENTS,
|
|
23
24
|
DEFAULT_BRIDGE_PASSING_SCORE: () => import_spa_bridge2.DEFAULT_BRIDGE_PASSING_SCORE,
|
|
24
25
|
LESSONKIT_TELEMETRY_EVENTS: () => import_tracking_schema2.LESSONKIT_TELEMETRY_EVENTS,
|
|
25
26
|
LXPACK_BRIDGE_VERSIONS: () => import_spa_bridge2.LXPACK_BRIDGE_VERSIONS,
|
|
27
|
+
branchTelemetryToBridgeTrackEvent: () => branchTelemetryToBridgeTrackEvent,
|
|
26
28
|
createLxpackBridge: () => createLxpackBridge,
|
|
27
29
|
createLxpackBridgeHost: () => import_spa_bridge2.createLxpackBridgeHost,
|
|
28
30
|
dispatchBridgeAction: () => dispatchBridgeAction,
|
|
29
31
|
forwardTelemetryToBridge: () => forwardTelemetryToBridge,
|
|
30
|
-
getLxpackBridge: () =>
|
|
32
|
+
getLxpackBridge: () => getLxpackBridge,
|
|
33
|
+
isParentOriginAllowed: () => isParentOriginAllowed,
|
|
31
34
|
mapLessonkitTelemetryToBridgeAction: () => import_tracking_schema2.mapLessonkitTelemetryToBridgeAction,
|
|
32
35
|
mapLessonkitTelemetryToLxpack: () => import_tracking_schema2.mapLessonkitTelemetryToLxpack,
|
|
33
36
|
normalizeAssessmentPassingScore: () => normalizeAssessmentPassingScore,
|
|
@@ -37,6 +40,7 @@ __export(bridge_exports, {
|
|
|
37
40
|
notifyLxpackAssessment: () => notifyLxpackAssessment,
|
|
38
41
|
notifyLxpackCourseComplete: () => notifyLxpackCourseComplete,
|
|
39
42
|
notifyLxpackLessonComplete: () => notifyLxpackLessonComplete,
|
|
43
|
+
resolveParentOrigin: () => resolveParentOrigin,
|
|
40
44
|
supportedBridgeVersions: () => import_spa_bridge2.supportedBridgeVersions,
|
|
41
45
|
telemetryEventToLessonkit: () => telemetryEventToLessonkit
|
|
42
46
|
});
|
|
@@ -48,43 +52,91 @@ var import_tracking_schema3 = require("@lxpack/tracking-schema");
|
|
|
48
52
|
|
|
49
53
|
// src/telemetry.ts
|
|
50
54
|
var import_tracking_schema = require("@lxpack/tracking-schema");
|
|
51
|
-
var
|
|
55
|
+
var BRANCH_TELEMETRY_EVENTS = ["branch_node_viewed", "branch_selected"];
|
|
56
|
+
var ASSESSMENT_TELEMETRY_EVENTS = ["assessment_answered"];
|
|
57
|
+
var SUPPORTED = /* @__PURE__ */ new Set([
|
|
58
|
+
...import_tracking_schema.LESSONKIT_TELEMETRY_EVENTS,
|
|
59
|
+
...BRANCH_TELEMETRY_EVENTS,
|
|
60
|
+
...ASSESSMENT_TELEMETRY_EVENTS
|
|
61
|
+
]);
|
|
52
62
|
function isQuizAnsweredData(data) {
|
|
53
|
-
return typeof data === "object" && data !== null && typeof data.checkId === "string";
|
|
63
|
+
return typeof data === "object" && data !== null && typeof data.checkId === "string" && data.checkId.length > 0;
|
|
54
64
|
}
|
|
55
65
|
function isQuizCompletedData(data) {
|
|
56
|
-
return typeof data === "object" && data !== null && typeof data.checkId === "string";
|
|
66
|
+
return typeof data === "object" && data !== null && typeof data.checkId === "string" && data.checkId.length > 0;
|
|
67
|
+
}
|
|
68
|
+
function isAssessmentAnsweredData(data) {
|
|
69
|
+
return typeof data === "object" && data !== null && typeof data.checkId === "string" && data.checkId.length > 0;
|
|
57
70
|
}
|
|
58
71
|
function isInteractionData(data) {
|
|
59
72
|
return typeof data === "object" && data !== null;
|
|
60
73
|
}
|
|
74
|
+
function isBranchNodeViewedData(data) {
|
|
75
|
+
return typeof data === "object" && data !== null && typeof data.blockId === "string" && typeof data.nodeId === "string";
|
|
76
|
+
}
|
|
77
|
+
function isBranchSelectedData(data) {
|
|
78
|
+
return typeof data === "object" && data !== null && typeof data.blockId === "string" && typeof data.fromNodeId === "string" && typeof data.toNodeId === "string";
|
|
79
|
+
}
|
|
61
80
|
function telemetryEventToLessonkit(event) {
|
|
62
81
|
if (!SUPPORTED.has(event.name)) {
|
|
63
82
|
return null;
|
|
64
83
|
}
|
|
65
|
-
const name = event.name;
|
|
66
84
|
const mapped = {
|
|
67
|
-
name,
|
|
85
|
+
name: event.name,
|
|
68
86
|
lessonId: event.lessonId
|
|
69
87
|
};
|
|
70
|
-
if (name === "quiz_completed" || name === "quiz_answered") {
|
|
88
|
+
if (event.name === "quiz_completed" || event.name === "quiz_answered" || event.name === "assessment_answered") {
|
|
71
89
|
const data = event.data;
|
|
72
|
-
if (isQuizAnsweredData(data)
|
|
73
|
-
|
|
74
|
-
if ("score" in data) {
|
|
75
|
-
mapped.score = data.score;
|
|
76
|
-
mapped.maxScore = data.maxScore;
|
|
77
|
-
mapped.passingScore = data.passingScore;
|
|
78
|
-
}
|
|
79
|
-
mapped.data = data;
|
|
90
|
+
if (!isQuizAnsweredData(data) && !isQuizCompletedData(data) && !isAssessmentAnsweredData(data)) {
|
|
91
|
+
return null;
|
|
80
92
|
}
|
|
81
|
-
|
|
93
|
+
mapped.assessmentId = data.checkId;
|
|
94
|
+
if ("score" in data) {
|
|
95
|
+
mapped.score = data.score;
|
|
96
|
+
mapped.maxScore = data.maxScore;
|
|
97
|
+
mapped.passingScore = data.passingScore;
|
|
98
|
+
}
|
|
99
|
+
mapped.data = data;
|
|
100
|
+
} else if (mapped.name === "interaction" && event.data && isInteractionData(event.data)) {
|
|
101
|
+
mapped.data = event.data;
|
|
102
|
+
} else if (event.name === "branch_node_viewed" && isBranchNodeViewedData(event.data)) {
|
|
103
|
+
mapped.data = event.data;
|
|
104
|
+
} else if (event.name === "branch_selected" && isBranchSelectedData(event.data)) {
|
|
82
105
|
mapped.data = event.data;
|
|
83
106
|
}
|
|
84
107
|
return mapped;
|
|
85
108
|
}
|
|
109
|
+
function answeredTelemetryToBridgeTrackEvent(event) {
|
|
110
|
+
if (event.name !== "quiz_answered" && event.name !== "assessment_answered") {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
const lessonkitEvent = telemetryEventToLessonkit(event);
|
|
114
|
+
if (!lessonkitEvent?.assessmentId) return null;
|
|
115
|
+
return (0, import_tracking_schema.mapLessonkitTelemetryToLxpack)({
|
|
116
|
+
...lessonkitEvent,
|
|
117
|
+
name: "quiz_answered"
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
function branchTelemetryToBridgeTrackEvent(event) {
|
|
121
|
+
if (event.name === "branch_node_viewed" && isBranchNodeViewedData(event.data)) {
|
|
122
|
+
return {
|
|
123
|
+
type: "interaction",
|
|
124
|
+
id: "branch_node_viewed",
|
|
125
|
+
data: { ...event.data, lessonkitEvent: event.name }
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (event.name === "branch_selected" && isBranchSelectedData(event.data)) {
|
|
129
|
+
return {
|
|
130
|
+
type: "interaction",
|
|
131
|
+
id: "branch_selected",
|
|
132
|
+
data: { ...event.data, lessonkitEvent: event.name }
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
86
137
|
|
|
87
138
|
// src/bridge.ts
|
|
139
|
+
var import_meta = {};
|
|
88
140
|
function normalizeAssessmentScore(opts) {
|
|
89
141
|
if (typeof opts.score !== "number" || !Number.isFinite(opts.score)) {
|
|
90
142
|
return null;
|
|
@@ -97,7 +149,41 @@ function normalizeAssessmentPassingScore(opts) {
|
|
|
97
149
|
maxScore: opts?.maxScore
|
|
98
150
|
});
|
|
99
151
|
}
|
|
100
|
-
function
|
|
152
|
+
function resolveParentOrigin(parentWindow) {
|
|
153
|
+
if (typeof window === "undefined") return null;
|
|
154
|
+
const parent = parentWindow ?? window.parent;
|
|
155
|
+
if (!parent || parent === window) return null;
|
|
156
|
+
try {
|
|
157
|
+
return parent.location.origin;
|
|
158
|
+
} catch {
|
|
159
|
+
const referrer = typeof document !== "undefined" ? document.referrer : "";
|
|
160
|
+
if (!referrer) return null;
|
|
161
|
+
try {
|
|
162
|
+
return new URL(referrer).origin;
|
|
163
|
+
} catch {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function isProductionRuntime() {
|
|
169
|
+
try {
|
|
170
|
+
if (import_meta.env?.PROD === true) return true;
|
|
171
|
+
} catch {
|
|
172
|
+
}
|
|
173
|
+
const g = globalThis;
|
|
174
|
+
return typeof g.process !== "undefined" && g.process.env?.NODE_ENV === "production";
|
|
175
|
+
}
|
|
176
|
+
function isParentOriginAllowed(allowedParentOrigins, parentWindow, mode) {
|
|
177
|
+
if (mode === "off") return false;
|
|
178
|
+
if (isProductionRuntime() && !allowedParentOrigins?.length) return false;
|
|
179
|
+
if (!allowedParentOrigins?.length) return true;
|
|
180
|
+
const origin = resolveParentOrigin(parentWindow);
|
|
181
|
+
if (!origin) return false;
|
|
182
|
+
return allowedParentOrigins.includes(origin);
|
|
183
|
+
}
|
|
184
|
+
function getBridge(parentWindow, opts) {
|
|
185
|
+
const mode = opts?.mode ?? "auto";
|
|
186
|
+
if (!isParentOriginAllowed(opts?.allowedParentOrigins, parentWindow, mode)) return null;
|
|
101
187
|
const fromSdk = (0, import_spa_bridge.getLxpackBridge)(parentWindow);
|
|
102
188
|
if (fromSdk) return fromSdk;
|
|
103
189
|
if (typeof window === "undefined") return null;
|
|
@@ -105,21 +191,33 @@ function getBridge(parentWindow) {
|
|
|
105
191
|
if (!parent || parent === window) return null;
|
|
106
192
|
return parent.lxpackBridge?.v1 ?? parent.lxpack ?? null;
|
|
107
193
|
}
|
|
194
|
+
function getLxpackBridge(parentWindow, opts) {
|
|
195
|
+
return getBridge(parentWindow, opts);
|
|
196
|
+
}
|
|
108
197
|
function isDevEnvironment() {
|
|
198
|
+
try {
|
|
199
|
+
if (import_meta.env?.DEV === true) return true;
|
|
200
|
+
if (import_meta.env?.PROD === true) return false;
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
109
203
|
const g = globalThis;
|
|
110
204
|
return typeof g.process !== "undefined" && g.process.env?.NODE_ENV !== "production";
|
|
111
205
|
}
|
|
112
|
-
function
|
|
206
|
+
function handleBridgeError(err, onBridgeError) {
|
|
207
|
+
onBridgeError?.(err);
|
|
208
|
+
if (isDevEnvironment()) {
|
|
209
|
+
console.warn(
|
|
210
|
+
"[lessonkit/lxpack] lxpack bridge action failed:",
|
|
211
|
+
err instanceof Error ? err.message : err
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function dispatchBridgeAction(bridge, action, opts) {
|
|
113
216
|
if (!action) return;
|
|
114
217
|
try {
|
|
115
218
|
dispatchBridgeActionInner(bridge, action);
|
|
116
219
|
} catch (err) {
|
|
117
|
-
|
|
118
|
-
console.warn(
|
|
119
|
-
"[lessonkit/lxpack] lxpack bridge action failed:",
|
|
120
|
-
err instanceof Error ? err.message : err
|
|
121
|
-
);
|
|
122
|
-
}
|
|
220
|
+
handleBridgeError(err, opts?.onBridgeError);
|
|
123
221
|
}
|
|
124
222
|
}
|
|
125
223
|
function dispatchBridgeActionInner(bridge, action) {
|
|
@@ -172,50 +270,70 @@ function forwardAssessmentCompletedToBridge(bridge, event) {
|
|
|
172
270
|
maxScore: data.maxScore
|
|
173
271
|
});
|
|
174
272
|
}
|
|
175
|
-
function forwardTelemetryToBridge(event, mode = "auto", parentWindow) {
|
|
273
|
+
function forwardTelemetryToBridge(event, mode = "auto", parentWindow, opts) {
|
|
176
274
|
if (mode === "off") return;
|
|
177
|
-
const bridge = getBridge(parentWindow
|
|
275
|
+
const bridge = getBridge(parentWindow, {
|
|
276
|
+
allowedParentOrigins: opts?.allowedParentOrigins,
|
|
277
|
+
mode
|
|
278
|
+
});
|
|
178
279
|
if (!bridge) return;
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
280
|
+
try {
|
|
281
|
+
if (event.name === "assessment_completed") {
|
|
282
|
+
forwardAssessmentCompletedToBridge(bridge, event);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const answeredTrack = answeredTelemetryToBridgeTrackEvent(event);
|
|
286
|
+
if (answeredTrack) {
|
|
287
|
+
bridge.track?.(answeredTrack);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const branchTrack = branchTelemetryToBridgeTrackEvent(event);
|
|
291
|
+
if (branchTrack) {
|
|
292
|
+
bridge.track?.(branchTrack);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const lessonkitEvent = telemetryEventToLessonkit(event);
|
|
296
|
+
if (!lessonkitEvent) return;
|
|
297
|
+
const action = (0, import_tracking_schema3.mapLessonkitTelemetryToBridgeAction)(lessonkitEvent);
|
|
298
|
+
dispatchBridgeActionInner(bridge, action);
|
|
299
|
+
} catch (err) {
|
|
300
|
+
handleBridgeError(err, opts?.onBridgeError);
|
|
182
301
|
}
|
|
183
|
-
const lessonkitEvent = telemetryEventToLessonkit(event);
|
|
184
|
-
if (!lessonkitEvent) return;
|
|
185
|
-
const action = (0, import_tracking_schema3.mapLessonkitTelemetryToBridgeAction)(lessonkitEvent);
|
|
186
|
-
dispatchBridgeAction(bridge, action);
|
|
187
302
|
}
|
|
188
|
-
function createLxpackBridge() {
|
|
189
|
-
return getBridge();
|
|
303
|
+
function createLxpackBridge(opts) {
|
|
304
|
+
return getBridge(void 0, opts);
|
|
190
305
|
}
|
|
191
|
-
function notifyLxpackLessonComplete(lessonId) {
|
|
192
|
-
const bridge = getBridge();
|
|
306
|
+
function notifyLxpackLessonComplete(lessonId, opts) {
|
|
307
|
+
const bridge = getBridge(void 0, opts);
|
|
193
308
|
if (!bridge?.completeLesson) return false;
|
|
194
309
|
bridge.completeLesson(lessonId);
|
|
195
310
|
return true;
|
|
196
311
|
}
|
|
197
|
-
function notifyLxpackCourseComplete() {
|
|
198
|
-
const bridge = getBridge();
|
|
312
|
+
function notifyLxpackCourseComplete(opts) {
|
|
313
|
+
const bridge = getBridge(void 0, opts);
|
|
199
314
|
if (!bridge?.completeCourse) return false;
|
|
200
315
|
bridge.completeCourse();
|
|
201
316
|
return true;
|
|
202
317
|
}
|
|
203
|
-
function notifyLxpackAssessment(payload) {
|
|
204
|
-
const bridge = getBridge();
|
|
318
|
+
function notifyLxpackAssessment(payload, opts) {
|
|
319
|
+
const bridge = getBridge(void 0, opts);
|
|
205
320
|
if (!bridge?.submitAssessment) return false;
|
|
206
321
|
bridge.submitAssessment(payload);
|
|
207
322
|
return true;
|
|
208
323
|
}
|
|
209
324
|
// Annotate the CommonJS export names for ESM import in node:
|
|
210
325
|
0 && (module.exports = {
|
|
326
|
+
BRANCH_TELEMETRY_EVENTS,
|
|
211
327
|
DEFAULT_BRIDGE_PASSING_SCORE,
|
|
212
328
|
LESSONKIT_TELEMETRY_EVENTS,
|
|
213
329
|
LXPACK_BRIDGE_VERSIONS,
|
|
330
|
+
branchTelemetryToBridgeTrackEvent,
|
|
214
331
|
createLxpackBridge,
|
|
215
332
|
createLxpackBridgeHost,
|
|
216
333
|
dispatchBridgeAction,
|
|
217
334
|
forwardTelemetryToBridge,
|
|
218
335
|
getLxpackBridge,
|
|
336
|
+
isParentOriginAllowed,
|
|
219
337
|
mapLessonkitTelemetryToBridgeAction,
|
|
220
338
|
mapLessonkitTelemetryToLxpack,
|
|
221
339
|
normalizeAssessmentPassingScore,
|
|
@@ -225,6 +343,7 @@ function notifyLxpackAssessment(payload) {
|
|
|
225
343
|
notifyLxpackAssessment,
|
|
226
344
|
notifyLxpackCourseComplete,
|
|
227
345
|
notifyLxpackLessonComplete,
|
|
346
|
+
resolveParentOrigin,
|
|
228
347
|
supportedBridgeVersions,
|
|
229
348
|
telemetryEventToLessonkit
|
|
230
349
|
});
|
package/dist/bridge.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LmsBridgeMode, TelemetryEvent, CheckId, LessonId } from '@lessonkit/core';
|
|
2
2
|
import { LxpackBridgeV1, LxpackBridgeSubmitAssessmentPayload } from '@lxpack/spa-bridge';
|
|
3
|
-
export { DEFAULT_BRIDGE_PASSING_SCORE, LXPACK_BRIDGE_VERSIONS, LxpackBridgeSubmitAssessmentPayload, LxpackBridgeV1, createLxpackBridgeHost,
|
|
3
|
+
export { DEFAULT_BRIDGE_PASSING_SCORE, LXPACK_BRIDGE_VERSIONS, LxpackBridgeSubmitAssessmentPayload, LxpackBridgeV1, createLxpackBridgeHost, normalizePassingThreshold, normalizeScore, supportedBridgeVersions } from '@lxpack/spa-bridge';
|
|
4
4
|
import { mapLessonkitTelemetryToBridgeAction } from '@lxpack/tracking-schema';
|
|
5
5
|
export { LESSONKIT_TELEMETRY_EVENTS, LessonkitBridgeAction, LessonkitTelemetryEvent, LessonkitTelemetryEventName, TrackingSchemaEvent, mapLessonkitTelemetryToBridgeAction, mapLessonkitTelemetryToLxpack } from '@lxpack/tracking-schema';
|
|
6
|
-
export { t as telemetryEventToLessonkit } from './telemetry-
|
|
6
|
+
export { B as BRANCH_TELEMETRY_EVENTS, b as branchTelemetryToBridgeTrackEvent, t as telemetryEventToLessonkit } from './telemetry-0fIWoomS.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Scale a raw quiz score to 0–1 for the LXPack parent bridge.
|
|
@@ -21,20 +21,38 @@ declare function normalizeAssessmentPassingScore(opts?: {
|
|
|
21
21
|
passingScore?: number;
|
|
22
22
|
maxScore?: number;
|
|
23
23
|
}): number;
|
|
24
|
+
type BridgeAccessOptions = {
|
|
25
|
+
/** Allowed parent-frame origins (scheme + host + port). When set, bridge calls require a matching origin. */
|
|
26
|
+
allowedParentOrigins?: string[];
|
|
27
|
+
/** LMS bridge mode; `"auto"` in production requires `allowedParentOrigins`. */
|
|
28
|
+
mode?: LxpackBridgeMode;
|
|
29
|
+
};
|
|
30
|
+
/** Resolve the parent frame origin when embedded (same-origin parent or document.referrer fallback). */
|
|
31
|
+
declare function resolveParentOrigin(parentWindow?: Window): string | null;
|
|
32
|
+
/** Returns true when no allowlist is configured or the resolved parent origin is listed. */
|
|
33
|
+
declare function isParentOriginAllowed(allowedParentOrigins: string[] | undefined, parentWindow?: Window, mode?: LxpackBridgeMode): boolean;
|
|
34
|
+
/** Resolve the LXPack parent bridge when the parent origin passes validation. */
|
|
35
|
+
declare function getLxpackBridge(parentWindow?: Window, opts?: BridgeAccessOptions): LxpackBridgeV1 | null;
|
|
24
36
|
/** @deprecated Use `LmsBridgeMode` from `@lessonkit/core`. */
|
|
25
37
|
type LxpackBridgeMode = LmsBridgeMode;
|
|
26
38
|
/** Apply a mapped bridge action to an LXPack bridge instance. */
|
|
27
|
-
declare function dispatchBridgeAction(bridge: LxpackBridgeV1, action: ReturnType<typeof mapLessonkitTelemetryToBridgeAction
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
declare function dispatchBridgeAction(bridge: LxpackBridgeV1, action: ReturnType<typeof mapLessonkitTelemetryToBridgeAction>, opts?: {
|
|
40
|
+
onBridgeError?: (err: unknown) => void;
|
|
41
|
+
}): void;
|
|
42
|
+
type ForwardTelemetryToBridgeOptions = {
|
|
43
|
+
onBridgeError?: (err: unknown) => void;
|
|
44
|
+
allowedParentOrigins?: string[];
|
|
45
|
+
};
|
|
46
|
+
declare function forwardTelemetryToBridge(event: TelemetryEvent, mode?: LxpackBridgeMode, parentWindow?: Window, opts?: ForwardTelemetryToBridgeOptions): void;
|
|
47
|
+
declare function createLxpackBridge(opts?: BridgeAccessOptions): LxpackBridgeV1 | null;
|
|
48
|
+
declare function notifyLxpackLessonComplete(lessonId: LessonId, opts?: BridgeAccessOptions): boolean;
|
|
49
|
+
declare function notifyLxpackCourseComplete(opts?: BridgeAccessOptions): boolean;
|
|
32
50
|
/**
|
|
33
51
|
* Submit assessment results to the parent LXPack bridge.
|
|
34
52
|
* `score` must already be on a 0–1 scale (use `normalizeAssessmentScore` for raw points).
|
|
35
53
|
*/
|
|
36
54
|
declare function notifyLxpackAssessment(payload: LxpackBridgeSubmitAssessmentPayload & {
|
|
37
55
|
id: CheckId;
|
|
38
|
-
}): boolean;
|
|
56
|
+
}, opts?: BridgeAccessOptions): boolean;
|
|
39
57
|
|
|
40
|
-
export { type LxpackBridgeMode, createLxpackBridge, dispatchBridgeAction, forwardTelemetryToBridge, normalizeAssessmentPassingScore, normalizeAssessmentScore, notifyLxpackAssessment, notifyLxpackCourseComplete, notifyLxpackLessonComplete };
|
|
58
|
+
export { type BridgeAccessOptions, type ForwardTelemetryToBridgeOptions, type LxpackBridgeMode, createLxpackBridge, dispatchBridgeAction, forwardTelemetryToBridge, getLxpackBridge, isParentOriginAllowed, normalizeAssessmentPassingScore, normalizeAssessmentScore, notifyLxpackAssessment, notifyLxpackCourseComplete, notifyLxpackLessonComplete, resolveParentOrigin };
|
package/dist/bridge.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { LmsBridgeMode, TelemetryEvent, CheckId, LessonId } from '@lessonkit/core';
|
|
2
2
|
import { LxpackBridgeV1, LxpackBridgeSubmitAssessmentPayload } from '@lxpack/spa-bridge';
|
|
3
|
-
export { DEFAULT_BRIDGE_PASSING_SCORE, LXPACK_BRIDGE_VERSIONS, LxpackBridgeSubmitAssessmentPayload, LxpackBridgeV1, createLxpackBridgeHost,
|
|
3
|
+
export { DEFAULT_BRIDGE_PASSING_SCORE, LXPACK_BRIDGE_VERSIONS, LxpackBridgeSubmitAssessmentPayload, LxpackBridgeV1, createLxpackBridgeHost, normalizePassingThreshold, normalizeScore, supportedBridgeVersions } from '@lxpack/spa-bridge';
|
|
4
4
|
import { mapLessonkitTelemetryToBridgeAction } from '@lxpack/tracking-schema';
|
|
5
5
|
export { LESSONKIT_TELEMETRY_EVENTS, LessonkitBridgeAction, LessonkitTelemetryEvent, LessonkitTelemetryEventName, TrackingSchemaEvent, mapLessonkitTelemetryToBridgeAction, mapLessonkitTelemetryToLxpack } from '@lxpack/tracking-schema';
|
|
6
|
-
export { t as telemetryEventToLessonkit } from './telemetry-
|
|
6
|
+
export { B as BRANCH_TELEMETRY_EVENTS, b as branchTelemetryToBridgeTrackEvent, t as telemetryEventToLessonkit } from './telemetry-0fIWoomS.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Scale a raw quiz score to 0–1 for the LXPack parent bridge.
|
|
@@ -21,20 +21,38 @@ declare function normalizeAssessmentPassingScore(opts?: {
|
|
|
21
21
|
passingScore?: number;
|
|
22
22
|
maxScore?: number;
|
|
23
23
|
}): number;
|
|
24
|
+
type BridgeAccessOptions = {
|
|
25
|
+
/** Allowed parent-frame origins (scheme + host + port). When set, bridge calls require a matching origin. */
|
|
26
|
+
allowedParentOrigins?: string[];
|
|
27
|
+
/** LMS bridge mode; `"auto"` in production requires `allowedParentOrigins`. */
|
|
28
|
+
mode?: LxpackBridgeMode;
|
|
29
|
+
};
|
|
30
|
+
/** Resolve the parent frame origin when embedded (same-origin parent or document.referrer fallback). */
|
|
31
|
+
declare function resolveParentOrigin(parentWindow?: Window): string | null;
|
|
32
|
+
/** Returns true when no allowlist is configured or the resolved parent origin is listed. */
|
|
33
|
+
declare function isParentOriginAllowed(allowedParentOrigins: string[] | undefined, parentWindow?: Window, mode?: LxpackBridgeMode): boolean;
|
|
34
|
+
/** Resolve the LXPack parent bridge when the parent origin passes validation. */
|
|
35
|
+
declare function getLxpackBridge(parentWindow?: Window, opts?: BridgeAccessOptions): LxpackBridgeV1 | null;
|
|
24
36
|
/** @deprecated Use `LmsBridgeMode` from `@lessonkit/core`. */
|
|
25
37
|
type LxpackBridgeMode = LmsBridgeMode;
|
|
26
38
|
/** Apply a mapped bridge action to an LXPack bridge instance. */
|
|
27
|
-
declare function dispatchBridgeAction(bridge: LxpackBridgeV1, action: ReturnType<typeof mapLessonkitTelemetryToBridgeAction
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
declare function dispatchBridgeAction(bridge: LxpackBridgeV1, action: ReturnType<typeof mapLessonkitTelemetryToBridgeAction>, opts?: {
|
|
40
|
+
onBridgeError?: (err: unknown) => void;
|
|
41
|
+
}): void;
|
|
42
|
+
type ForwardTelemetryToBridgeOptions = {
|
|
43
|
+
onBridgeError?: (err: unknown) => void;
|
|
44
|
+
allowedParentOrigins?: string[];
|
|
45
|
+
};
|
|
46
|
+
declare function forwardTelemetryToBridge(event: TelemetryEvent, mode?: LxpackBridgeMode, parentWindow?: Window, opts?: ForwardTelemetryToBridgeOptions): void;
|
|
47
|
+
declare function createLxpackBridge(opts?: BridgeAccessOptions): LxpackBridgeV1 | null;
|
|
48
|
+
declare function notifyLxpackLessonComplete(lessonId: LessonId, opts?: BridgeAccessOptions): boolean;
|
|
49
|
+
declare function notifyLxpackCourseComplete(opts?: BridgeAccessOptions): boolean;
|
|
32
50
|
/**
|
|
33
51
|
* Submit assessment results to the parent LXPack bridge.
|
|
34
52
|
* `score` must already be on a 0–1 scale (use `normalizeAssessmentScore` for raw points).
|
|
35
53
|
*/
|
|
36
54
|
declare function notifyLxpackAssessment(payload: LxpackBridgeSubmitAssessmentPayload & {
|
|
37
55
|
id: CheckId;
|
|
38
|
-
}): boolean;
|
|
56
|
+
}, opts?: BridgeAccessOptions): boolean;
|
|
39
57
|
|
|
40
|
-
export { type LxpackBridgeMode, createLxpackBridge, dispatchBridgeAction, forwardTelemetryToBridge, normalizeAssessmentPassingScore, normalizeAssessmentScore, notifyLxpackAssessment, notifyLxpackCourseComplete, notifyLxpackLessonComplete };
|
|
58
|
+
export { type BridgeAccessOptions, type ForwardTelemetryToBridgeOptions, type LxpackBridgeMode, createLxpackBridge, dispatchBridgeAction, forwardTelemetryToBridge, getLxpackBridge, isParentOriginAllowed, normalizeAssessmentPassingScore, normalizeAssessmentScore, notifyLxpackAssessment, notifyLxpackCourseComplete, notifyLxpackLessonComplete, resolveParentOrigin };
|