@lxpack/runtime 0.1.0 → 0.2.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/dist/runtime.js CHANGED
@@ -1,8 +1,8 @@
1
- var R = Object.defineProperty;
2
- var _ = (e, s, t) => s in e ? R(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t;
3
- var i = (e, s, t) => _(e, typeof s != "symbol" ? s + "" : s, t);
4
- const u = "lxpack_scorm12_preview";
5
- function f(e = 500) {
1
+ var E = Object.defineProperty;
2
+ var O = (e, s, t) => s in e ? E(e, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[s] = t;
3
+ var i = (e, s, t) => O(e, typeof s != "symbol" ? s + "" : s, t);
4
+ const g = "lxpack_scorm12_preview";
5
+ function M(e = 500) {
6
6
  let s = window, t = 0;
7
7
  for (; s && t < e; ) {
8
8
  try {
@@ -25,7 +25,7 @@ function f(e = 500) {
25
25
  }
26
26
  return null;
27
27
  }
28
- class E {
28
+ class A {
29
29
  constructor(s) {
30
30
  i(this, "api");
31
31
  i(this, "initialized", !1);
@@ -71,14 +71,14 @@ class E {
71
71
  this.LMSSetValue("cmi.core.score.raw", String(s)), this.LMSSetValue("cmi.core.score.max", String(t)), this.LMSSetValue("cmi.core.score.min", "0");
72
72
  }
73
73
  setSuspendData(s) {
74
- const t = l(s);
74
+ const t = d(s);
75
75
  this.LMSSetValue("cmi.suspend_data", t);
76
76
  }
77
77
  setLessonLocation(s) {
78
78
  this.LMSSetValue("cmi.core.lesson_location", s);
79
79
  }
80
80
  }
81
- class h {
81
+ class u {
82
82
  constructor(s = {}) {
83
83
  i(this, "data", {
84
84
  lessonStatus: "not attempted",
@@ -150,7 +150,7 @@ class h {
150
150
  this.data.scoreMax = Number(t);
151
151
  break;
152
152
  case "cmi.suspend_data":
153
- this.data.suspendData = l(t);
153
+ this.data.suspendData = d(t);
154
154
  break;
155
155
  case "cmi.core.lesson_location":
156
156
  this.data.lessonLocation = t;
@@ -186,14 +186,14 @@ class h {
186
186
  this.data.scoreRaw = s, this.data.scoreMax = t, this.data.scoreMin = 0, this.saveToStorage();
187
187
  }
188
188
  setSuspendData(s) {
189
- this.data.suspendData = l(s), this.saveToStorage();
189
+ this.data.suspendData = d(s), this.saveToStorage();
190
190
  }
191
191
  setLessonLocation(s) {
192
192
  this.data.lessonLocation = s, this.saveToStorage();
193
193
  }
194
194
  loadFromStorage() {
195
195
  try {
196
- const s = localStorage.getItem(u);
196
+ const s = localStorage.getItem(g);
197
197
  s && (this.data = { ...this.data, ...JSON.parse(s) });
198
198
  } catch {
199
199
  }
@@ -201,102 +201,340 @@ class h {
201
201
  saveToStorage() {
202
202
  if (this.persistToStorage)
203
203
  try {
204
- localStorage.setItem(u, JSON.stringify(this.data));
204
+ localStorage.setItem(g, JSON.stringify(this.data));
205
205
  } catch {
206
206
  }
207
207
  }
208
208
  }
209
- class L extends h {
209
+ class F extends u {
210
210
  constructor() {
211
211
  super({ persistToStorage: !0 });
212
212
  }
213
213
  }
214
- function l(e) {
214
+ function d(e) {
215
215
  return e.length <= 4096 ? e : (console.warn(
216
216
  "[lxpack] suspend_data exceeds 4096 chars; truncating"
217
217
  ), e.slice(0, 4096));
218
218
  }
219
- function p(e) {
219
+ function L(e) {
220
220
  if (e === "preview")
221
- return new h({ persistToStorage: !0 });
221
+ return new u({ persistToStorage: !0 });
222
222
  if (e === "scorm12") {
223
- const s = f();
224
- return s ? new E(s) : (console.warn(
223
+ const s = M();
224
+ return s ? new A(s) : (console.warn(
225
225
  "[lxpack] No LMS SCORM API found; using in-memory simulator (progress will not persist to LMS)"
226
- ), new h({ persistToStorage: !1 }));
226
+ ), new u({ persistToStorage: !1 }));
227
227
  }
228
- return new h({ persistToStorage: !1 });
228
+ return new u({ persistToStorage: !1 });
229
229
  }
230
- function M(e = "preview") {
231
- const s = p(e);
230
+ function j(e = "preview") {
231
+ const s = L(e);
232
232
  if (e === "preview") {
233
233
  const t = window;
234
234
  t.API = s;
235
235
  }
236
236
  return s;
237
237
  }
238
- function g(e) {
238
+ const I = "0", R = "lxpack_scorm2004_preview";
239
+ function N(e = 500) {
240
+ let s = window, t = 0;
241
+ for (; s && t < e; ) {
242
+ try {
243
+ const r = s.API_1484_11;
244
+ if (r && typeof r.Initialize == "function")
245
+ return r;
246
+ } catch {
247
+ }
248
+ try {
249
+ if (s.parent && s.parent !== s)
250
+ s = s.parent;
251
+ else if (s.opener && !s.opener.closed)
252
+ s = s.opener;
253
+ else
254
+ break;
255
+ } catch {
256
+ break;
257
+ }
258
+ t++;
259
+ }
260
+ return null;
261
+ }
262
+ class T {
263
+ constructor(s) {
264
+ i(this, "initialized", !1);
265
+ i(this, "terminated", !1);
266
+ i(this, "data", {
267
+ "cmi.completion_status": "unknown",
268
+ "cmi.success_status": "unknown",
269
+ "cmi.score.scaled": "",
270
+ "cmi.suspend_data": "",
271
+ "cmi.location": "",
272
+ "cmi.entry": "ab-initio"
273
+ });
274
+ i(this, "persistToStorage");
275
+ if (this.persistToStorage = (s == null ? void 0 : s.persistToStorage) ?? !1, this.persistToStorage)
276
+ try {
277
+ const t = localStorage.getItem(R);
278
+ t && (this.data = { ...this.data, ...JSON.parse(t) });
279
+ } catch {
280
+ }
281
+ }
282
+ save() {
283
+ if (this.persistToStorage)
284
+ try {
285
+ localStorage.setItem(R, JSON.stringify(this.data));
286
+ } catch {
287
+ }
288
+ }
289
+ Initialize() {
290
+ return this.initialized ? "false" : (this.initialized = !0, this.terminated = !1, "true");
291
+ }
292
+ Terminate() {
293
+ return !this.initialized || this.terminated ? "false" : (this.terminated = !0, this.save(), "true");
294
+ }
295
+ GetValue(s) {
296
+ return !this.initialized || this.terminated ? "" : this.data[s] ?? "";
297
+ }
298
+ SetValue(s, t) {
299
+ return !this.initialized || this.terminated ? "false" : (this.data[s] = t, this.save(), "true");
300
+ }
301
+ Commit() {
302
+ return !this.initialized || this.terminated ? "false" : (this.save(), "true");
303
+ }
304
+ GetLastError() {
305
+ return I;
306
+ }
307
+ GetErrorString() {
308
+ return "No error";
309
+ }
310
+ GetDiagnostic() {
311
+ return "";
312
+ }
313
+ setSuspendData(s) {
314
+ this.data["cmi.suspend_data"] = s;
315
+ }
316
+ setLocation(s) {
317
+ this.data["cmi.location"] = s;
318
+ }
319
+ setCompletionStatus(s) {
320
+ this.data["cmi.completion_status"] = s;
321
+ }
322
+ setSuccessStatus(s) {
323
+ this.data["cmi.success_status"] = s;
324
+ }
325
+ setScoreScaled(s) {
326
+ this.data["cmi.score.scaled"] = String(Math.max(0, Math.min(1, s)));
327
+ }
328
+ }
329
+ class D {
330
+ constructor(s) {
331
+ i(this, "api");
332
+ this.api = s;
333
+ }
334
+ Initialize() {
335
+ return this.api.Initialize("");
336
+ }
337
+ Terminate() {
338
+ return this.api.Terminate("");
339
+ }
340
+ GetValue(s) {
341
+ return this.api.GetValue(s);
342
+ }
343
+ SetValue(s, t) {
344
+ return this.api.SetValue(s, t);
345
+ }
346
+ Commit() {
347
+ return this.api.Commit("");
348
+ }
349
+ GetLastError() {
350
+ return this.api.GetLastError();
351
+ }
352
+ GetErrorString(s) {
353
+ return this.api.GetErrorString(s);
354
+ }
355
+ GetDiagnostic(s) {
356
+ return this.api.GetDiagnostic(s);
357
+ }
358
+ setSuspendData(s) {
359
+ this.api.SetValue("cmi.suspend_data", s);
360
+ }
361
+ setLocation(s) {
362
+ this.api.SetValue("cmi.location", s);
363
+ }
364
+ setCompletionStatus(s) {
365
+ this.api.SetValue("cmi.completion_status", s);
366
+ }
367
+ setSuccessStatus(s) {
368
+ this.api.SetValue("cmi.success_status", s);
369
+ }
370
+ setScoreScaled(s) {
371
+ this.api.SetValue("cmi.score.scaled", String(Math.max(0, Math.min(1, s))));
372
+ }
373
+ }
374
+ function C(e) {
375
+ const s = N();
376
+ return s ? new D(s) : (console.warn(
377
+ "[lxpack] No SCORM 2004 API found; using in-memory simulator"
378
+ ), new T({ persistToStorage: !1 }));
379
+ }
380
+ function p(e) {
381
+ var t;
382
+ const s = {
383
+ c: e.currentLessonId,
384
+ l: e.completedLessons,
385
+ a: e.assessmentScores,
386
+ s: e.suspendData
387
+ };
388
+ return (t = s.l) != null && t.length || delete s.l, (!s.a || !Object.keys(s.a).length) && delete s.a, (!s.s || !Object.keys(s.s).length) && delete s.s, s;
389
+ }
390
+ function y(e, s) {
391
+ return {
392
+ currentLessonId: e.c ?? s.currentLessonId,
393
+ completedLessons: Array.isArray(e.l) ? e.l : s.completedLessons,
394
+ assessmentScores: e.a && typeof e.a == "object" ? e.a : s.assessmentScores,
395
+ suspendData: e.s && typeof e.s == "object" ? e.s : s.suspendData
396
+ };
397
+ }
398
+ function b(e) {
399
+ const s = { ...e.suspendData }, t = Object.keys(s).filter((r) => r.startsWith("interaction_")).sort();
400
+ for (const r of t)
401
+ if (delete s[r], JSON.stringify(p({ ...e, suspendData: s })).length <= 4096)
402
+ return { ...e, suspendData: s };
403
+ return { ...e, suspendData: s };
404
+ }
405
+ function P(e) {
406
+ let s = JSON.stringify(p(e));
407
+ if (s.length <= 4096)
408
+ return s;
409
+ const t = b(e);
410
+ return s = JSON.stringify(p(t)), s.length <= 4096 ? s : (console.warn(
411
+ "[lxpack] suspend_data exceeds 4096 chars; truncating"
412
+ ), s.slice(0, 4096));
413
+ }
414
+ function w(e) {
415
+ if (!e || typeof e != "object") return !1;
416
+ const s = e;
417
+ return "currentLessonId" in s || "completedLessons" in s || "assessmentScores" in s;
418
+ }
419
+ function V(e, s) {
420
+ return {
421
+ currentLessonId: e.currentLessonId ?? s.currentLessonId,
422
+ completedLessons: Array.isArray(e.completedLessons) ? e.completedLessons : s.completedLessons,
423
+ assessmentScores: e.assessmentScores && typeof e.assessmentScores == "object" ? e.assessmentScores : s.assessmentScores,
424
+ suspendData: e.suspendData && typeof e.suspendData == "object" ? e.suspendData : s.suspendData
425
+ };
426
+ }
427
+ function m(e, s) {
428
+ try {
429
+ const t = JSON.parse(e);
430
+ return w(t) ? {
431
+ progress: V(t, s),
432
+ parsed: !0
433
+ } : { progress: y(t, s), parsed: !0 };
434
+ } catch {
435
+ return { progress: s, parsed: !1 };
436
+ }
437
+ }
438
+ const z = "v:";
439
+ function f(e) {
440
+ return `${z}${e}`;
441
+ }
442
+ function k(e, s) {
443
+ for (const [t, r] of Object.entries(e.variables ?? {})) {
444
+ const a = f(t);
445
+ s[a] === void 0 && (s[a] = r.default);
446
+ }
447
+ }
448
+ function _(e, s) {
449
+ return e[f(s)];
450
+ }
451
+ function x(e, s, t) {
452
+ e[f(s)] = t;
453
+ }
454
+ function S(e, s) {
455
+ var t, r, a;
456
+ if ("variable" in e && ((t = e.variable) != null && t.eq)) {
457
+ const [n, o] = e.variable.eq;
458
+ return s.getVariable(n) === o;
459
+ }
460
+ return "assessment" in e && ((r = e.assessment) != null && r.passed) ? s.isAssessmentPassed(e.assessment.passed) : "interaction" in e && ((a = e.interaction) != null && a.done) ? s.isInteractionDone(e.interaction.done) : "all" in e && e.all ? e.all.every((n) => S(n, s)) : "any" in e && e.any ? e.any.some((n) => S(n, s)) : !1;
461
+ }
462
+ function G(e, s) {
463
+ const t = e.flow;
464
+ if (!(t != null && t.length)) return null;
465
+ for (const r of t)
466
+ if (S(r.when, s))
467
+ return r.goto;
468
+ return null;
469
+ }
470
+ function $(e) {
239
471
  const s = `${e.title}::${e.version}`;
240
472
  let t = 0;
241
473
  for (let r = 0; r < s.length; r++)
242
474
  t = (t << 5) - t + s.charCodeAt(r), t |= 0;
243
475
  return `lxpack_progress_${Math.abs(t)}`;
244
476
  }
245
- function S(e, s) {
246
- return {
247
- ...e,
248
- ...s,
249
- completedLessons: s.completedLessons ?? e.completedLessons,
250
- assessmentScores: {
251
- ...e.assessmentScores,
252
- ...s.assessmentScores
253
- },
254
- suspendData: {
255
- ...e.suspendData,
256
- ...s.suspendData
257
- }
258
- };
259
- }
260
- class N {
477
+ class U {
261
478
  constructor(s) {
262
479
  i(this, "manifest");
263
480
  i(this, "progress");
264
481
  i(this, "scorm", null);
482
+ i(this, "scorm2004", null);
265
483
  i(this, "completionThreshold");
266
484
  i(this, "storageKey");
267
485
  i(this, "mode");
268
486
  i(this, "passedAssessments", /* @__PURE__ */ new Set());
269
- var r, a, o;
270
- this.manifest = s.manifest, this.mode = s.mode, this.completionThreshold = ((a = (r = s.manifest.tracking) == null ? void 0 : r.completion) == null ? void 0 : a.threshold) ?? 0.9, this.storageKey = g(s.manifest);
271
- const t = ((o = s.manifest.lessons[0]) == null ? void 0 : o.id) ?? "";
487
+ i(this, "defaultPassingScores");
488
+ i(this, "terminated", !1);
489
+ var r, a, n;
490
+ this.manifest = s.manifest, this.mode = s.mode, this.completionThreshold = ((a = (r = s.manifest.tracking) == null ? void 0 : r.completion) == null ? void 0 : a.threshold) ?? 0.9, this.storageKey = $(s.manifest), this.defaultPassingScores = {};
491
+ for (const [o, c] of Object.entries(s.assessments ?? {}))
492
+ this.defaultPassingScores[o] = c.passingScore;
493
+ const t = s.activityId ?? ((n = s.manifest.lessons[0]) == null ? void 0 : n.id) ?? "";
272
494
  this.progress = s.progress ?? {
273
495
  currentLessonId: t,
274
496
  completedLessons: [],
275
497
  assessmentScores: {},
276
498
  suspendData: {}
277
- }, s.mode === "scorm12" ? (this.scorm = p("scorm12"), this.scorm.LMSInitialize(), this.restoreScormProgress()) : (s.mode === "preview" || s.mode === "standalone") && this.restoreLocalProgress();
499
+ }, k(this.manifest, this.progress.suspendData), s.mode === "scorm12" ? (this.scorm = L("scorm12"), this.scorm.LMSInitialize(), this.restoreScormProgress()) : s.mode === "scorm2004" ? (this.scorm2004 = C(), this.scorm2004.Initialize(), this.restoreScorm2004Progress()) : (s.mode === "preview" || s.mode === "standalone") && this.restoreLocalProgress(), s.activityId && (this.progress.currentLessonId = s.activityId);
500
+ }
501
+ restoreLessonLocation() {
502
+ if (this.scorm) {
503
+ const s = this.scorm.LMSGetValue("cmi.core.lesson_location");
504
+ s && (this.progress.currentLessonId = s);
505
+ return;
506
+ }
507
+ if (this.scorm2004) {
508
+ const s = this.scorm2004.GetValue("cmi.location");
509
+ s && (this.progress.currentLessonId = s);
510
+ }
511
+ }
512
+ restoreScorm2004Progress() {
513
+ if (!this.scorm2004) return;
514
+ const s = this.scorm2004.GetValue("cmi.suspend_data");
515
+ if (s) {
516
+ const { progress: t, parsed: r } = m(s, this.progress);
517
+ r ? this.progress = t : this.restoreLessonLocation();
518
+ } else
519
+ this.restoreLessonLocation();
520
+ this.syncPassedAssessments();
278
521
  }
279
522
  restoreScormProgress() {
280
523
  if (!this.scorm) return;
281
524
  const s = this.scorm.LMSGetValue("cmi.suspend_data");
282
- if (s)
283
- try {
284
- const t = JSON.parse(s);
285
- this.progress = S(this.progress, t);
286
- } catch {
287
- }
288
- else {
289
- const t = this.scorm.LMSGetValue("cmi.core.lesson_location");
290
- t && (this.progress.currentLessonId = t);
291
- }
525
+ if (s) {
526
+ const { progress: t, parsed: r } = m(s, this.progress);
527
+ r ? this.progress = t : this.restoreLessonLocation();
528
+ } else
529
+ this.restoreLessonLocation();
292
530
  this.syncPassedAssessments();
293
531
  }
294
532
  restoreLocalProgress() {
295
533
  try {
296
534
  const s = localStorage.getItem(this.storageKey);
297
535
  if (s) {
298
- const t = JSON.parse(s);
299
- this.progress = S(this.progress, t);
536
+ const { progress: t, parsed: r } = m(s, this.progress);
537
+ r && (this.progress = t);
300
538
  }
301
539
  } catch {
302
540
  }
@@ -308,46 +546,51 @@ class N {
308
546
  t >= this.getAssessmentPassingScore(s) && this.passedAssessments.add(s);
309
547
  }
310
548
  getAssessmentPassingScore(s) {
311
- var a;
312
- if (!((a = this.manifest.assessments) == null ? void 0 : a.find((o) => o.id === s))) return 0.7;
313
- const r = this.progress.suspendData[`assessment_passing_${s}`];
314
- return typeof r == "number" ? r : 0.7;
549
+ const t = this.progress.suspendData[`assessment_passing_${s}`];
550
+ return typeof t == "number" ? t : s in this.defaultPassingScores ? this.defaultPassingScores[s] : 0.7;
315
551
  }
316
552
  getAPI() {
317
553
  return {
318
554
  track: (s) => this.track(s),
319
555
  completeLesson: (s) => this.completeLesson(s),
320
- getProgress: () => ({ ...this.progress }),
556
+ getProgress: () => ({
557
+ ...this.progress,
558
+ completedLessons: [...this.progress.completedLessons],
559
+ assessmentScores: { ...this.progress.assessmentScores },
560
+ suspendData: { ...this.progress.suspendData }
561
+ }),
321
562
  setVariable: (s, t) => {
322
- this.progress.suspendData[s] = t, this.persist();
563
+ this.manifest.variables && s in this.manifest.variables ? x(this.progress.suspendData, s, t) : this.progress.suspendData[s] = t, this.persist();
323
564
  },
324
- getVariable: (s) => this.progress.suspendData[s],
565
+ getVariable: (s) => this.manifest.variables && s in this.manifest.variables ? _(this.progress.suspendData, s) : this.progress.suspendData[s],
325
566
  submitAssessment: (s, t, r) => this.submitAssessment(s, t, r)
326
567
  };
327
568
  }
328
- track(s) {
329
- var t;
330
- if (s.type === "interaction" && s.id && (this.progress.suspendData[`interaction_${s.id}`] = s.data ?? !0, console.debug("[lxpack] interaction:", s.id, s.data)), s.type === "assessment" && s.id && ((t = s.data) == null ? void 0 : t.score) != null) {
331
- const r = Number(s.data.score);
332
- this.progress.assessmentScores[s.id] = r;
569
+ track(s, t) {
570
+ var r, a;
571
+ if (s.type === "interaction" && s.id && (this.progress.suspendData[`interaction_${s.id}`] = s.data ?? !0, console.debug("[lxpack] interaction:", s.id, s.data)), s.type === "assessment" && s.id) {
572
+ const n = typeof ((r = s.data) == null ? void 0 : r.passingScore) == "number" ? Number(s.data.passingScore) : this.getAssessmentPassingScore(s.id), o = ((a = s.data) == null ? void 0 : a.score) != null ? Number(s.data.score) : void 0;
573
+ if (o != null && !Number.isNaN(o)) {
574
+ this.applyAssessmentResult(s.id, o, n), (t == null ? void 0 : t.persist) !== !1 && (this.updateCompletion(), this.persist());
575
+ return;
576
+ }
333
577
  }
334
- this.persist();
578
+ (t == null ? void 0 : t.persist) !== !1 && this.persist();
579
+ }
580
+ applyAssessmentResult(s, t, r) {
581
+ this.progress.assessmentScores[s] = t, this.progress.suspendData[`assessment_passing_${s}`] = r, t >= r ? this.passedAssessments.add(s) : this.passedAssessments.delete(s);
335
582
  }
336
583
  submitAssessment(s, t, r) {
337
- this.progress.assessmentScores[s] = t, this.progress.suspendData[`assessment_passing_${s}`] = r, t >= r ? this.passedAssessments.add(s) : this.passedAssessments.delete(s), this.track({
338
- type: "assessment",
339
- id: s,
340
- data: { score: t, passingScore: r, passed: t >= r }
341
- }), this.updateCompletion();
584
+ this.applyAssessmentResult(s, t, r), this.updateCompletion(), this.persist();
342
585
  }
343
586
  completeLesson(s) {
344
587
  new Set(this.manifest.lessons.map((r) => r.id)).has(s) && (this.progress.completedLessons.includes(s) || this.progress.completedLessons.push(s), this.updateCompletion(), this.persist());
345
588
  }
346
589
  setCurrentLesson(s) {
347
- this.progress.currentLessonId = s, this.scorm && this.scorm.setLessonLocation(s), this.persist();
590
+ this.progress.currentLessonId = s, this.scorm && this.scorm.setLessonLocation(s), this.scorm2004 && this.scorm2004.setLocation(s), this.persist();
348
591
  }
349
592
  getProgress() {
350
- return { ...this.progress };
593
+ return this.getAPI().getProgress();
351
594
  }
352
595
  getManifest() {
353
596
  return this.manifest;
@@ -364,48 +607,54 @@ class N {
364
607
  return this.manifest.lessons.length + s;
365
608
  }
366
609
  getCompletionRatio() {
367
- var c;
610
+ var o;
368
611
  if (this.getTotalUnits() === 0) return 0;
369
- const t = this.manifest.lessons.length, r = ((c = this.manifest.assessments) == null ? void 0 : c.length) ?? 0, a = this.progress.completedLessons.filter(
370
- (m) => this.manifest.lessons.some((d) => d.id === m)
371
- ).length, o = this.passedAssessments.size;
372
- return (a + o) / (t + r);
612
+ const t = this.manifest.lessons.length, r = ((o = this.manifest.assessments) == null ? void 0 : o.length) ?? 0, a = this.progress.completedLessons.filter(
613
+ (c) => this.manifest.lessons.some((h) => h.id === c)
614
+ ).length, n = this.passedAssessments.size;
615
+ return (a + n) / (t + r);
373
616
  }
374
617
  updateCompletion() {
375
- var r, a, o;
376
- const s = this.getCompletionRatio(), t = Math.round(s * 100);
377
- if (this.scorm) {
378
- this.scorm.setScore(t);
379
- const c = this.manifest.lessons.every(
380
- (n) => this.progress.completedLessons.includes(n.id)
381
- ), m = !((r = this.manifest.assessments) != null && r.length) || this.manifest.assessments.every((n) => this.passedAssessments.has(n.id));
382
- ((a = this.manifest.assessments) == null ? void 0 : a.some(
383
- (n) => n.id in this.progress.assessmentScores && !this.passedAssessments.has(n.id)
384
- )) ? this.scorm.setLessonStatus("failed") : s >= this.completionThreshold && c && m ? this.scorm.setLessonStatus(
385
- (((o = this.manifest.assessments) == null ? void 0 : o.length) ?? 0) > 0 ? "passed" : "completed"
386
- ) : t > 0 && this.scorm.setLessonStatus("incomplete");
387
- }
618
+ var o, c, h;
619
+ const s = this.getCompletionRatio(), t = Math.round(s * 100), r = this.manifest.lessons.every(
620
+ (l) => this.progress.completedLessons.includes(l.id)
621
+ ), a = !((o = this.manifest.assessments) != null && o.length) || this.manifest.assessments.every((l) => this.passedAssessments.has(l.id)), n = (c = this.manifest.assessments) == null ? void 0 : c.some(
622
+ (l) => l.id in this.progress.assessmentScores && !this.passedAssessments.has(l.id)
623
+ );
624
+ this.scorm && (this.scorm.setScore(t), n ? this.scorm.setLessonStatus("failed") : s >= this.completionThreshold && r && a ? this.scorm.setLessonStatus(
625
+ (((h = this.manifest.assessments) == null ? void 0 : h.length) ?? 0) > 0 ? "passed" : "completed"
626
+ ) : t > 0 && this.scorm.setLessonStatus("incomplete")), this.scorm2004 && (this.scorm2004.setScoreScaled(s), n ? (this.scorm2004.setSuccessStatus("failed"), this.scorm2004.setCompletionStatus("completed")) : s >= this.completionThreshold && r && a ? (this.scorm2004.setSuccessStatus("passed"), this.scorm2004.setCompletionStatus("completed")) : s > 0 && (this.scorm2004.setCompletionStatus("incomplete"), this.scorm2004.setSuccessStatus("unknown")));
388
627
  }
389
628
  persist() {
390
- const s = l(JSON.stringify(this.progress));
629
+ const s = P(this.progress);
391
630
  if (this.mode === "preview" || this.mode === "standalone")
392
631
  try {
393
632
  localStorage.setItem(this.storageKey, s);
394
633
  } catch {
395
634
  }
396
- this.scorm && (this.scorm.setSuspendData(s), this.scorm.LMSCommit());
635
+ this.scorm && (this.scorm.setSuspendData(s), this.scorm.LMSCommit()), this.scorm2004 && (this.scorm2004.setSuspendData(s), this.scorm2004.Commit());
636
+ }
637
+ getFlowContext() {
638
+ return {
639
+ getVariable: (s) => _(this.progress.suspendData, s),
640
+ isAssessmentPassed: (s) => this.isAssessmentPassed(s),
641
+ isInteractionDone: (s) => this.progress.suspendData[`interaction_${s}`] !== void 0
642
+ };
643
+ }
644
+ resolveFlowNavigation() {
645
+ return G(this.manifest, this.getFlowContext());
397
646
  }
398
647
  terminate() {
399
- this.scorm && this.scorm.LMSFinish();
648
+ this.terminated || (this.terminated = !0, this.scorm && this.scorm.LMSFinish(), this.scorm2004 && this.scorm2004.Terminate());
400
649
  }
401
650
  }
402
651
  export {
403
- N as LxpackRuntime,
404
- L as Scorm12API,
405
- E as Scorm12Adapter,
406
- h as Scorm12Simulator,
407
- p as createScormConnection,
408
- f as findLmsApi,
409
- M as installScormAPI,
410
- l as trimSuspendData
652
+ U as LxpackRuntime,
653
+ F as Scorm12API,
654
+ A as Scorm12Adapter,
655
+ u as Scorm12Simulator,
656
+ L as createScormConnection,
657
+ M as findLmsApi,
658
+ j as installScormAPI,
659
+ d as trimSuspendData
411
660
  };
@@ -0,0 +1,57 @@
1
+ /**
2
+ * SCORM 2004 4th Edition Run-Time API subset.
3
+ */
4
+ export interface Scorm2004ApiLike {
5
+ Initialize(param?: string): string;
6
+ Terminate(param?: string): string;
7
+ GetValue(element: string): string;
8
+ SetValue(element: string, value: string): string;
9
+ Commit(param?: string): string;
10
+ GetLastError(): string;
11
+ GetErrorString(errorCode?: string): string;
12
+ GetDiagnostic(errorCode?: string): string;
13
+ }
14
+ export declare function findScorm2004Api(maxDepth?: number): Scorm2004ApiLike | null;
15
+ export declare class Scorm2004Simulator implements Scorm2004ApiLike {
16
+ private initialized;
17
+ private terminated;
18
+ private data;
19
+ private persistToStorage;
20
+ constructor(options?: {
21
+ persistToStorage?: boolean;
22
+ });
23
+ private save;
24
+ Initialize(): string;
25
+ Terminate(): string;
26
+ GetValue(element: string): string;
27
+ SetValue(element: string, value: string): string;
28
+ Commit(): string;
29
+ GetLastError(): string;
30
+ GetErrorString(): string;
31
+ GetDiagnostic(): string;
32
+ setSuspendData(data: string): void;
33
+ setLocation(location: string): void;
34
+ setCompletionStatus(status: string): void;
35
+ setSuccessStatus(status: string): void;
36
+ setScoreScaled(scaled: number): void;
37
+ }
38
+ export declare class Scorm2004Adapter implements Scorm2004ApiLike {
39
+ private api;
40
+ constructor(api: Scorm2004ApiLike);
41
+ Initialize(): string;
42
+ Terminate(): string;
43
+ GetValue(element: string): string;
44
+ SetValue(element: string, value: string): string;
45
+ Commit(): string;
46
+ GetLastError(): string;
47
+ GetErrorString(errorCode?: string): string;
48
+ GetDiagnostic(errorCode?: string): string;
49
+ setSuspendData(data: string): void;
50
+ setLocation(location: string): void;
51
+ setCompletionStatus(status: string): void;
52
+ setSuccessStatus(status: string): void;
53
+ setScoreScaled(scaled: number): void;
54
+ }
55
+ export type Scorm2004Connection = Scorm2004Simulator | Scorm2004Adapter;
56
+ export declare function createScorm2004Connection(mode: "preview" | "scorm2004"): Scorm2004Connection;
57
+ //# sourceMappingURL=scorm2004-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorm2004-api.d.ts","sourceRoot":"","sources":["../src/scorm2004-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,YAAY,IAAI,MAAM,CAAC;IACvB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3C;AAKD,wBAAgB,gBAAgB,CAAC,QAAQ,SAAM,GAAG,gBAAgB,GAAG,IAAI,CA8BxE;AAED,qBAAa,kBAAmB,YAAW,gBAAgB;IACzD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,IAAI,CAOV;IACF,OAAO,CAAC,gBAAgB,CAAU;gBAEtB,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE;IAcpD,OAAO,CAAC,IAAI;IASZ,UAAU,IAAI,MAAM;IAOpB,SAAS,IAAI,MAAM;IAOnB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAKjC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAOhD,MAAM,IAAI,MAAM;IAMhB,YAAY,IAAI,MAAM;IAItB,cAAc,IAAI,MAAM;IAIxB,aAAa,IAAI,MAAM;IAIvB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAInC,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIzC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGrC;AAED,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,OAAO,CAAC,GAAG,CAAmB;gBAElB,GAAG,EAAE,gBAAgB;IAIjC,UAAU,IAAI,MAAM;IAIpB,SAAS,IAAI,MAAM;IAInB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAIjC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAIhD,MAAM,IAAI,MAAM;IAIhB,YAAY,IAAI,MAAM;IAItB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAI1C,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAIzC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAInC,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIzC,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGrC;AAED,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAExE,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,SAAS,GAAG,WAAW,GAC5B,mBAAmB,CAarB"}