scorm-again 3.1.2 → 3.1.4
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/esm/scorm-again.js +185 -55
- package/dist/esm/scorm-again.js.map +1 -1
- package/dist/esm/scorm-again.min.js +1 -1
- package/dist/esm/scorm-again.min.js.map +1 -1
- package/dist/esm/scorm12.js +1 -0
- package/dist/esm/scorm12.js.map +1 -1
- package/dist/esm/scorm12.min.js +1 -1
- package/dist/esm/scorm12.min.js.map +1 -1
- package/dist/esm/scorm2004.js +184 -55
- package/dist/esm/scorm2004.js.map +1 -1
- package/dist/esm/scorm2004.min.js +1 -1
- package/dist/esm/scorm2004.min.js.map +1 -1
- package/dist/scorm-again.js +219 -43
- package/dist/scorm-again.js.map +1 -1
- package/dist/scorm-again.min.js +1 -1
- package/dist/scorm12.js +1 -0
- package/dist/scorm12.js.map +1 -1
- package/dist/scorm12.min.js +1 -1
- package/dist/scorm2004.js +218 -43
- package/dist/scorm2004.js.map +1 -1
- package/dist/scorm2004.min.js +1 -1
- package/dist/types/Scorm2004API.d.ts +1 -0
- package/dist/types/cmi/scorm2004/completion_status_evaluation.d.ts +7 -0
- package/dist/types/cmi/scorm2004/sequencing/handlers/termination_handler.d.ts +1 -0
- package/dist/types/types/sequencing_types.d.ts +6 -0
- package/package.json +1 -1
package/dist/esm/scorm2004.js
CHANGED
|
@@ -10426,6 +10426,26 @@ class RollupProcess {
|
|
|
10426
10426
|
}
|
|
10427
10427
|
}
|
|
10428
10428
|
|
|
10429
|
+
function evaluateCompletionStatusFromThreshold({
|
|
10430
|
+
completionThreshold,
|
|
10431
|
+
progressMeasure,
|
|
10432
|
+
storedCompletionStatus
|
|
10433
|
+
}) {
|
|
10434
|
+
if (completionThreshold !== "" && completionThreshold !== null && completionThreshold !== void 0) {
|
|
10435
|
+
const thresholdValue = parseFloat(String(completionThreshold));
|
|
10436
|
+
if (!isNaN(thresholdValue)) {
|
|
10437
|
+
if (progressMeasure !== "" && progressMeasure !== null && progressMeasure !== void 0) {
|
|
10438
|
+
const progressValue = parseFloat(String(progressMeasure));
|
|
10439
|
+
if (!isNaN(progressValue)) {
|
|
10440
|
+
return progressValue >= thresholdValue ? CompletionStatus.COMPLETED : CompletionStatus.INCOMPLETE;
|
|
10441
|
+
}
|
|
10442
|
+
}
|
|
10443
|
+
return CompletionStatus.UNKNOWN;
|
|
10444
|
+
}
|
|
10445
|
+
}
|
|
10446
|
+
return storedCompletionStatus || CompletionStatus.UNKNOWN;
|
|
10447
|
+
}
|
|
10448
|
+
|
|
10429
10449
|
const VALID_COMPLETION_STATUSES = [
|
|
10430
10450
|
CompletionStatus.COMPLETED,
|
|
10431
10451
|
CompletionStatus.INCOMPLETE,
|
|
@@ -10480,10 +10500,38 @@ class RteDataTransferService {
|
|
|
10480
10500
|
* @param {CMIDataForTransfer} cmiData - CMI data from runtime
|
|
10481
10501
|
*/
|
|
10482
10502
|
transferPrimaryObjective(activity, cmiData) {
|
|
10483
|
-
|
|
10484
|
-
if (
|
|
10485
|
-
|
|
10486
|
-
|
|
10503
|
+
let hasProgressMeasure = false;
|
|
10504
|
+
if (cmiData.progress_measure && cmiData.progress_measure !== "") {
|
|
10505
|
+
const progressMeasure = parseFloat(cmiData.progress_measure);
|
|
10506
|
+
if (!isNaN(progressMeasure)) {
|
|
10507
|
+
hasProgressMeasure = true;
|
|
10508
|
+
activity.progressMeasure = progressMeasure;
|
|
10509
|
+
activity.progressMeasureStatus = true;
|
|
10510
|
+
activity.attemptCompletionAmount = progressMeasure;
|
|
10511
|
+
activity.attemptCompletionAmountStatus = true;
|
|
10512
|
+
if (activity.primaryObjective) {
|
|
10513
|
+
activity.primaryObjective.progressMeasure = progressMeasure;
|
|
10514
|
+
activity.primaryObjective.progressMeasureStatus = true;
|
|
10515
|
+
}
|
|
10516
|
+
}
|
|
10517
|
+
}
|
|
10518
|
+
if (!hasProgressMeasure) {
|
|
10519
|
+
activity.attemptCompletionAmountStatus = false;
|
|
10520
|
+
}
|
|
10521
|
+
if (activity.completedByMeasure) {
|
|
10522
|
+
const completionStatus = evaluateCompletionStatusFromThreshold({
|
|
10523
|
+
completionThreshold: activity.minProgressMeasure,
|
|
10524
|
+
progressMeasure: cmiData.progress_measure,
|
|
10525
|
+
storedCompletionStatus: CompletionStatus.UNKNOWN
|
|
10526
|
+
});
|
|
10527
|
+
activity.completionStatus = completionStatus;
|
|
10528
|
+
activity.attemptProgressStatus = completionStatus !== CompletionStatus.UNKNOWN;
|
|
10529
|
+
} else {
|
|
10530
|
+
const validatedCompletionStatus = validateCompletionStatus(cmiData.completion_status);
|
|
10531
|
+
if (validatedCompletionStatus && validatedCompletionStatus !== CompletionStatus.UNKNOWN) {
|
|
10532
|
+
activity.completionStatus = validatedCompletionStatus;
|
|
10533
|
+
activity.attemptProgressStatus = true;
|
|
10534
|
+
}
|
|
10487
10535
|
}
|
|
10488
10536
|
let hasSuccessStatus = false;
|
|
10489
10537
|
let successStatus = false;
|
|
@@ -10517,17 +10565,6 @@ class RteDataTransferService {
|
|
|
10517
10565
|
activity.primaryObjective.progressStatus = true;
|
|
10518
10566
|
}
|
|
10519
10567
|
}
|
|
10520
|
-
if (cmiData.progress_measure && cmiData.progress_measure !== "") {
|
|
10521
|
-
const progressMeasure = parseFloat(cmiData.progress_measure);
|
|
10522
|
-
if (!isNaN(progressMeasure)) {
|
|
10523
|
-
activity.progressMeasure = progressMeasure;
|
|
10524
|
-
activity.progressMeasureStatus = true;
|
|
10525
|
-
if (activity.primaryObjective) {
|
|
10526
|
-
activity.primaryObjective.progressMeasure = progressMeasure;
|
|
10527
|
-
activity.primaryObjective.progressMeasureStatus = true;
|
|
10528
|
-
}
|
|
10529
|
-
}
|
|
10530
|
-
}
|
|
10531
10568
|
}
|
|
10532
10569
|
/**
|
|
10533
10570
|
* Transfer non-primary objective data from CMI to activity objectives
|
|
@@ -10732,6 +10769,18 @@ class TerminationHandler {
|
|
|
10732
10769
|
this.endAttempt(this.activityTree.currentActivity);
|
|
10733
10770
|
}
|
|
10734
10771
|
}
|
|
10772
|
+
const ancestorExitResult = this.applyAncestorExitActionRules(currentActivity);
|
|
10773
|
+
if (ancestorExitResult.action === "EXIT_ALL") {
|
|
10774
|
+
return this.handleExitAll(ancestorExitResult.activity || currentActivity);
|
|
10775
|
+
}
|
|
10776
|
+
if (ancestorExitResult.exception) {
|
|
10777
|
+
return {
|
|
10778
|
+
terminationRequest: SequencingRequestType.EXIT,
|
|
10779
|
+
sequencingRequest: null,
|
|
10780
|
+
exception: ancestorExitResult.exception,
|
|
10781
|
+
valid: false
|
|
10782
|
+
};
|
|
10783
|
+
}
|
|
10735
10784
|
let processedExit;
|
|
10736
10785
|
let postConditionResult;
|
|
10737
10786
|
do {
|
|
@@ -10959,16 +11008,14 @@ class TerminationHandler {
|
|
|
10959
11008
|
for (const rule of exitRules) {
|
|
10960
11009
|
let conditionsMet;
|
|
10961
11010
|
if (rule.conditionCombination === "all") {
|
|
10962
|
-
conditionsMet = rule.conditions.every(
|
|
10963
|
-
(condition) => condition.evaluate(activity)
|
|
10964
|
-
);
|
|
11011
|
+
conditionsMet = rule.conditions.every((condition) => condition.evaluate(activity));
|
|
10965
11012
|
} else {
|
|
10966
|
-
conditionsMet = rule.conditions.some(
|
|
10967
|
-
(condition) => condition.evaluate(activity)
|
|
10968
|
-
);
|
|
11013
|
+
conditionsMet = rule.conditions.some((condition) => condition.evaluate(activity));
|
|
10969
11014
|
}
|
|
10970
11015
|
if (conditionsMet) {
|
|
10971
|
-
if (rule.action === RuleActionType.
|
|
11016
|
+
if (rule.action === RuleActionType.EXIT) {
|
|
11017
|
+
return { action: "EXIT", recursionDepth };
|
|
11018
|
+
} else if (rule.action === RuleActionType.EXIT_PARENT) {
|
|
10972
11019
|
return { action: "EXIT_PARENT", recursionDepth };
|
|
10973
11020
|
} else if (rule.action === RuleActionType.EXIT_ALL) {
|
|
10974
11021
|
return { action: "EXIT_ALL", recursionDepth };
|
|
@@ -11002,6 +11049,55 @@ class TerminationHandler {
|
|
|
11002
11049
|
this.processExitAtLevel(rootActivity, 0);
|
|
11003
11050
|
this.terminateAll(rootActivity);
|
|
11004
11051
|
}
|
|
11052
|
+
/**
|
|
11053
|
+
* Sequencing Exit Action Rules Subprocess (TB.2.1) ancestor walk
|
|
11054
|
+
* @spec SN Book: TB.2.1 (Sequencing Exit Action Rules Subprocess)
|
|
11055
|
+
* @param {Activity} terminatingActivity - The activity whose attempt just ended
|
|
11056
|
+
* @return {{action: string | null, activity?: Activity, exception?: string}}
|
|
11057
|
+
*/
|
|
11058
|
+
applyAncestorExitActionRules(terminatingActivity) {
|
|
11059
|
+
const activityPath = [];
|
|
11060
|
+
let current = terminatingActivity.parent;
|
|
11061
|
+
while (current) {
|
|
11062
|
+
activityPath.unshift(current);
|
|
11063
|
+
current = current.parent;
|
|
11064
|
+
}
|
|
11065
|
+
for (const activity of activityPath) {
|
|
11066
|
+
const exitAction = this.exitActionRulesSubprocess(activity);
|
|
11067
|
+
if (exitAction === "EXIT_ALL") {
|
|
11068
|
+
this.fireEvent("onAncestorExitAction", {
|
|
11069
|
+
activity: activity.id,
|
|
11070
|
+
action: exitAction
|
|
11071
|
+
});
|
|
11072
|
+
return { action: "EXIT_ALL", activity };
|
|
11073
|
+
}
|
|
11074
|
+
if (exitAction === "EXIT_PARENT") {
|
|
11075
|
+
if (!activity.parent) {
|
|
11076
|
+
return { action: "EXIT_PARENT", activity, exception: "TB.2.3-4" };
|
|
11077
|
+
}
|
|
11078
|
+
this.terminateDescendants(activity.parent);
|
|
11079
|
+
this.activityTree.currentActivity = activity.parent;
|
|
11080
|
+
this.endAttempt(activity.parent);
|
|
11081
|
+
this.fireEvent("onAncestorExitAction", {
|
|
11082
|
+
activity: activity.id,
|
|
11083
|
+
action: exitAction,
|
|
11084
|
+
currentActivity: activity.parent.id
|
|
11085
|
+
});
|
|
11086
|
+
return { action: "EXIT_PARENT", activity: activity.parent };
|
|
11087
|
+
}
|
|
11088
|
+
if (exitAction === "EXIT") {
|
|
11089
|
+
this.terminateDescendants(activity);
|
|
11090
|
+
this.activityTree.currentActivity = activity;
|
|
11091
|
+
this.endAttempt(activity);
|
|
11092
|
+
this.fireEvent("onAncestorExitAction", {
|
|
11093
|
+
activity: activity.id,
|
|
11094
|
+
action: exitAction
|
|
11095
|
+
});
|
|
11096
|
+
return { action: "EXIT", activity };
|
|
11097
|
+
}
|
|
11098
|
+
}
|
|
11099
|
+
return { action: null };
|
|
11100
|
+
}
|
|
11005
11101
|
/**
|
|
11006
11102
|
* Process exit actions at specific level
|
|
11007
11103
|
* @param {Activity} activity - Activity to process
|
|
@@ -11084,16 +11180,14 @@ class TerminationHandler {
|
|
|
11084
11180
|
for (const rule of exitRules) {
|
|
11085
11181
|
let conditionsMet;
|
|
11086
11182
|
if (rule.conditionCombination === "all") {
|
|
11087
|
-
conditionsMet = rule.conditions.every(
|
|
11088
|
-
(condition) => condition.evaluate(activity)
|
|
11089
|
-
);
|
|
11183
|
+
conditionsMet = rule.conditions.every((condition) => condition.evaluate(activity));
|
|
11090
11184
|
} else {
|
|
11091
|
-
conditionsMet = rule.conditions.some(
|
|
11092
|
-
(condition) => condition.evaluate(activity)
|
|
11093
|
-
);
|
|
11185
|
+
conditionsMet = rule.conditions.some((condition) => condition.evaluate(activity));
|
|
11094
11186
|
}
|
|
11095
11187
|
if (conditionsMet) {
|
|
11096
|
-
if (rule.action === RuleActionType.
|
|
11188
|
+
if (rule.action === RuleActionType.EXIT) {
|
|
11189
|
+
return "EXIT";
|
|
11190
|
+
} else if (rule.action === RuleActionType.EXIT_PARENT) {
|
|
11097
11191
|
return "EXIT_PARENT";
|
|
11098
11192
|
} else if (rule.action === RuleActionType.EXIT_ALL) {
|
|
11099
11193
|
return "EXIT_ALL";
|
|
@@ -14647,7 +14741,29 @@ class SequencingService {
|
|
|
14647
14741
|
* Update activity properties from current CMI values
|
|
14648
14742
|
*/
|
|
14649
14743
|
updateActivityFromCMI(activity) {
|
|
14650
|
-
|
|
14744
|
+
let hasProgressMeasure = false;
|
|
14745
|
+
if (this.cmi.progress_measure !== "") {
|
|
14746
|
+
const progressMeasure = parseFloat(this.cmi.progress_measure);
|
|
14747
|
+
if (!isNaN(progressMeasure)) {
|
|
14748
|
+
hasProgressMeasure = true;
|
|
14749
|
+
activity.progressMeasure = progressMeasure;
|
|
14750
|
+
activity.progressMeasureStatus = true;
|
|
14751
|
+
activity.attemptCompletionAmount = progressMeasure;
|
|
14752
|
+
activity.attemptCompletionAmountStatus = true;
|
|
14753
|
+
}
|
|
14754
|
+
}
|
|
14755
|
+
if (!hasProgressMeasure) {
|
|
14756
|
+
activity.attemptCompletionAmountStatus = false;
|
|
14757
|
+
}
|
|
14758
|
+
if (activity.completedByMeasure) {
|
|
14759
|
+
const completionStatus = evaluateCompletionStatusFromThreshold({
|
|
14760
|
+
completionThreshold: activity.minProgressMeasure,
|
|
14761
|
+
progressMeasure: this.cmi.progress_measure,
|
|
14762
|
+
storedCompletionStatus: CompletionStatus.UNKNOWN
|
|
14763
|
+
});
|
|
14764
|
+
activity.completionStatus = completionStatus;
|
|
14765
|
+
activity.attemptProgressStatus = completionStatus !== CompletionStatus.UNKNOWN;
|
|
14766
|
+
} else if (this.cmi.completion_status !== "unknown") {
|
|
14651
14767
|
activity.completionStatus = this.cmi.completion_status;
|
|
14652
14768
|
activity.attemptProgressStatus = true;
|
|
14653
14769
|
}
|
|
@@ -14659,13 +14775,6 @@ class SequencingService {
|
|
|
14659
14775
|
activity.primaryObjective.progressStatus = true;
|
|
14660
14776
|
}
|
|
14661
14777
|
}
|
|
14662
|
-
if (this.cmi.progress_measure !== "") {
|
|
14663
|
-
const progressMeasure = parseFloat(this.cmi.progress_measure);
|
|
14664
|
-
if (!isNaN(progressMeasure)) {
|
|
14665
|
-
activity.progressMeasure = progressMeasure;
|
|
14666
|
-
activity.progressMeasureStatus = true;
|
|
14667
|
-
}
|
|
14668
|
-
}
|
|
14669
14778
|
if (this.cmi.score && this.cmi.score.scaled !== "") {
|
|
14670
14779
|
const scaledScore = parseFloat(this.cmi.score.scaled);
|
|
14671
14780
|
if (!isNaN(scaledScore)) {
|
|
@@ -18859,6 +18968,7 @@ class CMI extends BaseRootCMI {
|
|
|
18859
18968
|
*/
|
|
18860
18969
|
reset() {
|
|
18861
18970
|
this._initialized = false;
|
|
18971
|
+
this._start_time = void 0;
|
|
18862
18972
|
this.metadata?.reset();
|
|
18863
18973
|
this.learner?.reset();
|
|
18864
18974
|
this.status?.reset();
|
|
@@ -20822,22 +20932,11 @@ class Scorm2004CMIHandler {
|
|
|
20822
20932
|
* @returns {string} The evaluated completion status
|
|
20823
20933
|
*/
|
|
20824
20934
|
evaluateCompletionStatus() {
|
|
20825
|
-
|
|
20826
|
-
|
|
20827
|
-
|
|
20828
|
-
|
|
20829
|
-
|
|
20830
|
-
if (!isNaN(thresholdValue)) {
|
|
20831
|
-
if (progressMeasure !== "" && progressMeasure !== null && progressMeasure !== void 0) {
|
|
20832
|
-
const progressValue = parseFloat(String(progressMeasure));
|
|
20833
|
-
if (!isNaN(progressValue)) {
|
|
20834
|
-
return progressValue >= thresholdValue ? CompletionStatus.COMPLETED : CompletionStatus.INCOMPLETE;
|
|
20835
|
-
}
|
|
20836
|
-
}
|
|
20837
|
-
return CompletionStatus.UNKNOWN;
|
|
20838
|
-
}
|
|
20839
|
-
}
|
|
20840
|
-
return storedStatus || CompletionStatus.UNKNOWN;
|
|
20935
|
+
return evaluateCompletionStatusFromThreshold({
|
|
20936
|
+
completionThreshold: this.context.cmi.completion_threshold,
|
|
20937
|
+
progressMeasure: this.context.cmi.progress_measure,
|
|
20938
|
+
storedCompletionStatus: this.context.cmi.completion_status
|
|
20939
|
+
});
|
|
20841
20940
|
}
|
|
20842
20941
|
/**
|
|
20843
20942
|
* Evaluates success_status per SCORM 2004 RTE Table 4.2.21.1a
|
|
@@ -21497,6 +21596,21 @@ class ActivityTreeBuilder {
|
|
|
21497
21596
|
if (activitySettings.rollupConsiderations) {
|
|
21498
21597
|
activity.applyRollupConsiderations(activitySettings.rollupConsiderations);
|
|
21499
21598
|
}
|
|
21599
|
+
if (activitySettings.completionThreshold) {
|
|
21600
|
+
const threshold = activitySettings.completionThreshold;
|
|
21601
|
+
if (threshold.completedByMeasure !== void 0) {
|
|
21602
|
+
activity.completedByMeasure = threshold.completedByMeasure;
|
|
21603
|
+
}
|
|
21604
|
+
if (threshold.minProgressMeasure !== void 0) {
|
|
21605
|
+
activity.minProgressMeasure = threshold.minProgressMeasure;
|
|
21606
|
+
activity.completionThreshold = threshold.minProgressMeasure.toString();
|
|
21607
|
+
} else if (threshold.completedByMeasure) {
|
|
21608
|
+
activity.completionThreshold = activity.minProgressMeasure.toString();
|
|
21609
|
+
}
|
|
21610
|
+
if (threshold.progressWeight !== void 0) {
|
|
21611
|
+
activity.progressWeight = threshold.progressWeight;
|
|
21612
|
+
}
|
|
21613
|
+
}
|
|
21500
21614
|
if (activitySettings.hideLmsUi) {
|
|
21501
21615
|
const mergedHide = this.sequencingConfigBuilder.mergeHideLmsUi(
|
|
21502
21616
|
activity.hideLmsUi,
|
|
@@ -22540,8 +22654,23 @@ class Scorm2004API extends BaseAPI {
|
|
|
22540
22654
|
reset(settings) {
|
|
22541
22655
|
this.commonReset(settings);
|
|
22542
22656
|
this.cmi?.reset();
|
|
22657
|
+
this.applyCurrentActivityLaunchData();
|
|
22543
22658
|
this.adl?.reset();
|
|
22544
22659
|
}
|
|
22660
|
+
/**
|
|
22661
|
+
* Apply launch-static activity data to CMI while the new SCO is pre-initialize.
|
|
22662
|
+
*
|
|
22663
|
+
* @spec SCORM 2004 4th Ed. RTE 4.2.9 - cmi.completion_threshold
|
|
22664
|
+
*/
|
|
22665
|
+
applyCurrentActivityLaunchData() {
|
|
22666
|
+
const currentActivity = this._sequencing?.getCurrentActivity();
|
|
22667
|
+
if (!this.cmi || !currentActivity) {
|
|
22668
|
+
return;
|
|
22669
|
+
}
|
|
22670
|
+
const contentActivityData = this._sequencing.overallSequencingProcess?.getContentActivityData(currentActivity);
|
|
22671
|
+
const completionThreshold = contentActivityData?.completionThreshold ?? currentActivity.completionThreshold?.toString() ?? "";
|
|
22672
|
+
this.cmi.completion_threshold = completionThreshold;
|
|
22673
|
+
}
|
|
22545
22674
|
/**
|
|
22546
22675
|
* Getter for _version
|
|
22547
22676
|
* @return {string}
|
|
@@ -23052,14 +23181,14 @@ class Scorm2004API extends BaseAPI {
|
|
|
23052
23181
|
if (this.cmi.mode === "normal") {
|
|
23053
23182
|
if (this.cmi.credit === "credit") {
|
|
23054
23183
|
if (this.cmi.completion_threshold && this.cmi.progress_measure) {
|
|
23055
|
-
if (this.cmi.progress_measure >= this.cmi.completion_threshold) {
|
|
23184
|
+
if (parseFloat(this.cmi.progress_measure) >= parseFloat(this.cmi.completion_threshold)) {
|
|
23056
23185
|
this.cmi.completion_status = "completed";
|
|
23057
23186
|
} else {
|
|
23058
23187
|
this.cmi.completion_status = "incomplete";
|
|
23059
23188
|
}
|
|
23060
23189
|
}
|
|
23061
23190
|
if (this.cmi.scaled_passing_score && this.cmi.score.scaled) {
|
|
23062
|
-
if (this.cmi.score.scaled >= this.cmi.scaled_passing_score) {
|
|
23191
|
+
if (parseFloat(this.cmi.score.scaled) >= parseFloat(this.cmi.scaled_passing_score)) {
|
|
23063
23192
|
this.cmi.success_status = "passed";
|
|
23064
23193
|
} else {
|
|
23065
23194
|
this.cmi.success_status = "failed";
|