@lxpack/runtime 0.2.1 → 0.2.2

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.
@@ -0,0 +1,137 @@
1
+ const y = 4096;
2
+ function c(s) {
3
+ var n;
4
+ const e = {
5
+ c: s.currentLessonId,
6
+ l: s.completedLessons,
7
+ a: s.assessmentScores,
8
+ s: s.suspendData
9
+ };
10
+ return (n = e.l) != null && n.length || delete e.l, (!e.a || !Object.keys(e.a).length) && delete e.a, (!e.s || !Object.keys(e.s).length) && delete e.s, e;
11
+ }
12
+ function u(s, e) {
13
+ return {
14
+ currentLessonId: s.c ?? e.currentLessonId,
15
+ completedLessons: Array.isArray(s.l) ? s.l : e.completedLessons,
16
+ assessmentScores: s.a && typeof s.a == "object" ? s.a : e.assessmentScores,
17
+ suspendData: s.s && typeof s.s == "object" ? s.s : e.suspendData
18
+ };
19
+ }
20
+ function l(s) {
21
+ if (!s || typeof s != "object") return !1;
22
+ const e = s;
23
+ return "currentLessonId" in e || "completedLessons" in e || "assessmentScores" in e;
24
+ }
25
+ function d(s, e) {
26
+ return {
27
+ currentLessonId: s.currentLessonId ?? e.currentLessonId,
28
+ completedLessons: Array.isArray(s.completedLessons) ? s.completedLessons : e.completedLessons,
29
+ assessmentScores: s.assessmentScores && typeof s.assessmentScores == "object" ? s.assessmentScores : e.assessmentScores,
30
+ suspendData: s.suspendData && typeof s.suspendData == "object" ? s.suspendData : e.suspendData
31
+ };
32
+ }
33
+ function f(s, e) {
34
+ try {
35
+ const n = JSON.parse(s);
36
+ return l(n) ? {
37
+ progress: d(n, e),
38
+ parsed: !0
39
+ } : { progress: u(n, e), parsed: !0 };
40
+ } catch {
41
+ return { progress: e, parsed: !1 };
42
+ }
43
+ }
44
+ function r(s, e) {
45
+ return JSON.stringify(c(s)).length <= e;
46
+ }
47
+ function p(s, e) {
48
+ const n = { ...s.suspendData }, o = Object.keys(n).filter((i) => i.startsWith("interaction_")).sort();
49
+ for (const i of o) {
50
+ delete n[i];
51
+ const t = { ...s, suspendData: n };
52
+ if (r(t, e))
53
+ return t;
54
+ }
55
+ return { ...s, suspendData: n };
56
+ }
57
+ function S(s) {
58
+ return s.startsWith("interaction_") || s.startsWith("v:") || s.startsWith("assessment_attempts_") || s.startsWith("assessment_passing_");
59
+ }
60
+ function L(s, e) {
61
+ const n = { ...s.suspendData }, o = Object.keys(n).filter((t) => !S(t)).sort();
62
+ for (const t of o) {
63
+ delete n[t];
64
+ const a = { ...s, suspendData: n };
65
+ if (r(a, e))
66
+ return a;
67
+ }
68
+ const i = Object.keys(n).filter((t) => t.startsWith("v:")).sort();
69
+ for (const t of i) {
70
+ delete n[t];
71
+ const a = { ...s, suspendData: n };
72
+ if (r(a, e))
73
+ return a;
74
+ }
75
+ return { ...s, suspendData: n };
76
+ }
77
+ function g(s, e) {
78
+ let n = {
79
+ currentLessonId: s.currentLessonId,
80
+ completedLessons: [...s.completedLessons],
81
+ assessmentScores: { ...s.assessmentScores },
82
+ suspendData: {}
83
+ };
84
+ if (r(n, e))
85
+ return JSON.stringify(c(n));
86
+ for (; n.completedLessons.length > 0; )
87
+ if (n.completedLessons.pop(), r(n, e))
88
+ return JSON.stringify(c(n));
89
+ const o = Object.keys(n.assessmentScores);
90
+ for (; o.length > 0; )
91
+ if (delete n.assessmentScores[o.pop()], r(n, e))
92
+ return JSON.stringify(c(n));
93
+ n = {
94
+ currentLessonId: s.currentLessonId,
95
+ completedLessons: [],
96
+ assessmentScores: {},
97
+ suspendData: {}
98
+ };
99
+ const i = JSON.stringify(c(n));
100
+ if (i.length <= e)
101
+ return i;
102
+ const t = JSON.stringify({
103
+ c: s.currentLessonId.slice(0, Math.max(0, e - 20))
104
+ });
105
+ return t.length <= e ? t : JSON.stringify({ c: "" });
106
+ }
107
+ function h(s, e = 4096) {
108
+ if (r(s, e))
109
+ return JSON.stringify(c(s));
110
+ let n = p(s, e);
111
+ return r(n, e) || (n = L(n, e), r(n, e)) ? JSON.stringify(c(n)) : (console.warn(
112
+ `[lxpack] suspend_data exceeds ${e} chars; using minimal progress snapshot`
113
+ ), g(s, e));
114
+ }
115
+ function m(s, e = 4096) {
116
+ if (s.length <= e) return s;
117
+ console.warn(
118
+ `[lxpack] suspend_data exceeds ${e} chars; using minimal progress snapshot`
119
+ );
120
+ try {
121
+ const n = {
122
+ currentLessonId: "",
123
+ completedLessons: [],
124
+ assessmentScores: {},
125
+ suspendData: {}
126
+ }, { progress: o } = f(s, n);
127
+ return h(o, e);
128
+ } catch {
129
+ return JSON.stringify({ c: "" });
130
+ }
131
+ }
132
+ export {
133
+ y as S,
134
+ f as p,
135
+ h as s,
136
+ m as t
137
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lxpack/runtime",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Web-native course runtime for LXPack",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "marked": "^15.0.7",
49
49
  "yaml": "^2.7.0",
50
- "@lxpack/validators": "0.2.1"
50
+ "@lxpack/validators": "0.2.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "^22.13.10",
@@ -1,375 +0,0 @@
1
- var p = Object.defineProperty;
2
- var L = (e, t, s) => t in e ? p(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s;
3
- var a = (e, t, s) => L(e, typeof t != "symbol" ? t + "" : t, s);
4
- const A = 4096;
5
- function u(e) {
6
- var s;
7
- const t = {
8
- c: e.currentLessonId,
9
- l: e.completedLessons,
10
- a: e.assessmentScores,
11
- s: e.suspendData
12
- };
13
- return (s = t.l) != null && s.length || delete t.l, (!t.a || !Object.keys(t.a).length) && delete t.a, (!t.s || !Object.keys(t.s).length) && delete t.s, t;
14
- }
15
- function g(e, t) {
16
- return {
17
- currentLessonId: e.c ?? t.currentLessonId,
18
- completedLessons: Array.isArray(e.l) ? e.l : t.completedLessons,
19
- assessmentScores: e.a && typeof e.a == "object" ? e.a : t.assessmentScores,
20
- suspendData: e.s && typeof e.s == "object" ? e.s : t.suspendData
21
- };
22
- }
23
- function M(e) {
24
- if (!e || typeof e != "object") return !1;
25
- const t = e;
26
- return "currentLessonId" in t || "completedLessons" in t || "assessmentScores" in t;
27
- }
28
- function E(e, t) {
29
- return {
30
- currentLessonId: e.currentLessonId ?? t.currentLessonId,
31
- completedLessons: Array.isArray(e.completedLessons) ? e.completedLessons : t.completedLessons,
32
- assessmentScores: e.assessmentScores && typeof e.assessmentScores == "object" ? e.assessmentScores : t.assessmentScores,
33
- suspendData: e.suspendData && typeof e.suspendData == "object" ? e.suspendData : t.suspendData
34
- };
35
- }
36
- function y(e, t) {
37
- try {
38
- const s = JSON.parse(e);
39
- return M(s) ? {
40
- progress: E(s, t),
41
- parsed: !0
42
- } : { progress: g(s, t), parsed: !0 };
43
- } catch {
44
- return { progress: t, parsed: !1 };
45
- }
46
- }
47
- function c(e, t) {
48
- return JSON.stringify(u(e)).length <= t;
49
- }
50
- function _(e, t) {
51
- const s = { ...e.suspendData }, i = Object.keys(s).filter((l) => l.startsWith("interaction_")).sort();
52
- for (const l of i) {
53
- delete s[l];
54
- const r = { ...e, suspendData: s };
55
- if (c(r, t))
56
- return r;
57
- }
58
- return { ...e, suspendData: s };
59
- }
60
- function D(e, t) {
61
- const s = { ...e.suspendData }, i = Object.keys(s).filter((r) => !r.startsWith("interaction_") && !r.startsWith("v:")).sort();
62
- for (const r of i) {
63
- delete s[r];
64
- const d = { ...e, suspendData: s };
65
- if (c(d, t))
66
- return d;
67
- }
68
- const l = Object.keys(s).filter((r) => r.startsWith("v:")).sort();
69
- for (const r of l) {
70
- delete s[r];
71
- const d = { ...e, suspendData: s };
72
- if (c(d, t))
73
- return d;
74
- }
75
- return { ...e, suspendData: s };
76
- }
77
- function O(e, t) {
78
- let s = {
79
- currentLessonId: e.currentLessonId,
80
- completedLessons: [...e.completedLessons],
81
- assessmentScores: { ...e.assessmentScores },
82
- suspendData: {}
83
- };
84
- if (c(s, t))
85
- return JSON.stringify(u(s));
86
- for (; s.completedLessons.length > 0; )
87
- if (s.completedLessons.pop(), c(s, t))
88
- return JSON.stringify(u(s));
89
- const i = Object.keys(s.assessmentScores);
90
- for (; i.length > 0; )
91
- if (delete s.assessmentScores[i.pop()], c(s, t))
92
- return JSON.stringify(u(s));
93
- s = {
94
- currentLessonId: e.currentLessonId,
95
- completedLessons: [],
96
- assessmentScores: {},
97
- suspendData: {}
98
- };
99
- const l = JSON.stringify(u(s));
100
- if (l.length <= t)
101
- return l;
102
- const r = JSON.stringify({
103
- c: e.currentLessonId.slice(0, Math.max(0, t - 20))
104
- });
105
- return r.length <= t ? r : JSON.stringify({ c: "" });
106
- }
107
- function I(e, t = 4096) {
108
- if (c(e, t))
109
- return JSON.stringify(u(e));
110
- let s = _(e, t);
111
- return c(s, t) || (s = D(s, t), c(s, t)) ? JSON.stringify(u(s)) : (console.warn(
112
- `[lxpack] suspend_data exceeds ${t} chars; using minimal progress snapshot`
113
- ), O(e, t));
114
- }
115
- function w(e, t = 4096) {
116
- if (e.length <= t) return e;
117
- console.warn(
118
- `[lxpack] suspend_data exceeds ${t} chars; using minimal progress snapshot`
119
- );
120
- try {
121
- const s = {
122
- currentLessonId: "",
123
- completedLessons: [],
124
- assessmentScores: {},
125
- suspendData: {}
126
- }, { progress: i } = y(e, s);
127
- return I(i, t);
128
- } catch {
129
- return JSON.stringify({ c: "" });
130
- }
131
- }
132
- const n = "0", o = "301", S = "302", m = "lxpack_scorm12_preview";
133
- function N(e = 500) {
134
- let t = window, s = 0;
135
- for (; t && s < e; ) {
136
- try {
137
- const i = t.API;
138
- if (i && typeof i.LMSInitialize == "function")
139
- return i;
140
- } catch {
141
- }
142
- try {
143
- if (t.parent && t.parent !== t)
144
- t = t.parent;
145
- else if (t.opener && !t.opener.closed)
146
- t = t.opener;
147
- else
148
- break;
149
- } catch {
150
- break;
151
- }
152
- s++;
153
- }
154
- return null;
155
- }
156
- class b {
157
- constructor(t) {
158
- a(this, "api");
159
- a(this, "initialized", !1);
160
- a(this, "terminated", !1);
161
- a(this, "lastError", n);
162
- this.api = t;
163
- }
164
- LMSInitialize() {
165
- if (this.initialized)
166
- return this.lastError = o, "false";
167
- const t = this.api.LMSInitialize("");
168
- return t === "true" && (this.initialized = !0, this.terminated = !1, this.lastError = n), t;
169
- }
170
- LMSFinish() {
171
- if (!this.initialized || this.terminated)
172
- return this.lastError = S, "false";
173
- const t = this.api.LMSFinish("");
174
- return t === "true" && (this.terminated = !0, this.lastError = n), t;
175
- }
176
- LMSGetValue(t) {
177
- return !this.initialized || this.terminated ? (this.lastError = o, "") : (this.lastError = n, this.api.LMSGetValue(t));
178
- }
179
- LMSSetValue(t, s) {
180
- return !this.initialized || this.terminated ? (this.lastError = o, "false") : (this.lastError = n, this.api.LMSSetValue(t, s));
181
- }
182
- LMSCommit() {
183
- return !this.initialized || this.terminated ? (this.lastError = o, "false") : (this.lastError = n, this.api.LMSCommit(""));
184
- }
185
- LMSGetLastError() {
186
- return this.lastError;
187
- }
188
- LMSGetErrorString(t) {
189
- const s = t ?? this.lastError;
190
- return s === o ? "Not initialized" : s === S ? "Already terminated" : this.api.LMSGetErrorString(s);
191
- }
192
- LMSGetDiagnostic(t) {
193
- return this.api.LMSGetDiagnostic(t ?? this.lastError);
194
- }
195
- setLessonStatus(t) {
196
- this.LMSSetValue("cmi.core.lesson_status", t);
197
- }
198
- setScore(t, s = 100) {
199
- this.LMSSetValue("cmi.core.score.raw", String(t)), this.LMSSetValue("cmi.core.score.max", String(s)), this.LMSSetValue("cmi.core.score.min", "0");
200
- }
201
- setSuspendData(t) {
202
- const s = f(t);
203
- this.LMSSetValue("cmi.suspend_data", s);
204
- }
205
- setLessonLocation(t) {
206
- this.LMSSetValue("cmi.core.lesson_location", t);
207
- }
208
- }
209
- class h {
210
- constructor(t = {}) {
211
- a(this, "data", {
212
- lessonStatus: "not attempted",
213
- scoreRaw: 0,
214
- scoreMin: 0,
215
- scoreMax: 100,
216
- suspendData: "",
217
- lessonLocation: "",
218
- entry: "ab-initio",
219
- exit: "",
220
- sessionTime: "00:00:00"
221
- });
222
- a(this, "initialized", !1);
223
- a(this, "terminated", !1);
224
- a(this, "lastError", n);
225
- a(this, "persistToStorage");
226
- this.persistToStorage = t.persistToStorage ?? !1, t.initialData && (this.data = { ...this.data, ...t.initialData }), this.persistToStorage && this.loadFromStorage();
227
- }
228
- LMSInitialize() {
229
- return this.initialized ? (this.lastError = o, "false") : (this.initialized = !0, this.terminated = !1, this.lastError = n, "true");
230
- }
231
- LMSFinish() {
232
- return !this.initialized || this.terminated ? (this.lastError = S, "false") : (this.data.exit = "suspend", this.terminated = !0, this.saveToStorage(), this.lastError = n, "true");
233
- }
234
- LMSGetValue(t) {
235
- if (!this.initialized || this.terminated)
236
- return this.lastError = o, "";
237
- switch (this.lastError = n, t) {
238
- case "cmi.core.lesson_status":
239
- return this.data.lessonStatus;
240
- case "cmi.core.score.raw":
241
- return String(this.data.scoreRaw);
242
- case "cmi.core.score.min":
243
- return String(this.data.scoreMin);
244
- case "cmi.core.score.max":
245
- return String(this.data.scoreMax);
246
- case "cmi.suspend_data":
247
- return this.data.suspendData;
248
- case "cmi.core.lesson_location":
249
- return this.data.lessonLocation;
250
- case "cmi.core.student_id":
251
- return "lxpack-learner";
252
- case "cmi.core.student_name":
253
- return "LXPack Learner";
254
- case "cmi.core.entry":
255
- return this.data.entry;
256
- case "cmi.core.exit":
257
- return this.data.exit;
258
- case "cmi.core.session_time":
259
- return this.data.sessionTime;
260
- default:
261
- return "";
262
- }
263
- }
264
- LMSSetValue(t, s) {
265
- if (!this.initialized || this.terminated)
266
- return this.lastError = o, "false";
267
- switch (this.lastError = n, t) {
268
- case "cmi.core.lesson_status":
269
- this.data.lessonStatus = s;
270
- break;
271
- case "cmi.core.score.raw":
272
- this.data.scoreRaw = Number(s);
273
- break;
274
- case "cmi.core.score.min":
275
- this.data.scoreMin = Number(s);
276
- break;
277
- case "cmi.core.score.max":
278
- this.data.scoreMax = Number(s);
279
- break;
280
- case "cmi.suspend_data":
281
- this.data.suspendData = f(s);
282
- break;
283
- case "cmi.core.lesson_location":
284
- this.data.lessonLocation = s;
285
- break;
286
- case "cmi.core.exit":
287
- this.data.exit = s;
288
- break;
289
- case "cmi.core.session_time":
290
- this.data.sessionTime = s;
291
- break;
292
- default:
293
- return "false";
294
- }
295
- return this.saveToStorage(), "true";
296
- }
297
- LMSCommit() {
298
- return !this.initialized || this.terminated ? (this.lastError = o, "false") : (this.saveToStorage(), this.lastError = n, "true");
299
- }
300
- LMSGetLastError() {
301
- return this.lastError;
302
- }
303
- LMSGetErrorString(t) {
304
- const s = t ?? this.lastError;
305
- return s === o ? "Not initialized" : s === S ? "Already terminated" : "No error";
306
- }
307
- LMSGetDiagnostic() {
308
- return "";
309
- }
310
- setLessonStatus(t) {
311
- this.data.lessonStatus = t, this.saveToStorage();
312
- }
313
- setScore(t, s = 100) {
314
- this.data.scoreRaw = t, this.data.scoreMax = s, this.data.scoreMin = 0, this.saveToStorage();
315
- }
316
- setSuspendData(t) {
317
- this.data.suspendData = f(t), this.saveToStorage();
318
- }
319
- setLessonLocation(t) {
320
- this.data.lessonLocation = t, this.saveToStorage();
321
- }
322
- loadFromStorage() {
323
- try {
324
- const t = localStorage.getItem(m);
325
- t && (this.data = { ...this.data, ...JSON.parse(t) });
326
- } catch {
327
- }
328
- }
329
- saveToStorage() {
330
- if (this.persistToStorage)
331
- try {
332
- localStorage.setItem(m, JSON.stringify(this.data));
333
- } catch {
334
- }
335
- }
336
- }
337
- class z extends h {
338
- constructor() {
339
- super({ persistToStorage: !0 });
340
- }
341
- }
342
- function f(e) {
343
- return w(e);
344
- }
345
- function T(e) {
346
- if (e === "preview")
347
- return new h({ persistToStorage: !0 });
348
- if (e === "scorm12") {
349
- const t = N();
350
- return t ? new b(t) : (console.warn(
351
- "[lxpack] No LMS SCORM API found; using in-memory simulator (progress will not persist to LMS)"
352
- ), new h({ persistToStorage: !1 }));
353
- }
354
- return new h({ persistToStorage: !1 });
355
- }
356
- function R(e = "preview") {
357
- const t = T(e);
358
- if (e === "preview") {
359
- const s = window;
360
- s.API = t;
361
- }
362
- return t;
363
- }
364
- export {
365
- A as S,
366
- z as a,
367
- b,
368
- h as c,
369
- T as d,
370
- N as f,
371
- R as i,
372
- y as p,
373
- I as s,
374
- f as t
375
- };