scorm-again 3.0.1 → 3.0.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.
Files changed (48) hide show
  1. package/dist/aicc.js.map +1 -0
  2. package/dist/aicc.min.js.map +1 -0
  3. package/dist/cross-frame-api.js +26 -11
  4. package/dist/cross-frame-api.js.map +1 -0
  5. package/dist/cross-frame-api.min.js +1 -1
  6. package/dist/cross-frame-api.min.js.map +1 -0
  7. package/dist/cross-frame-lms.js +16 -4
  8. package/dist/cross-frame-lms.js.map +1 -0
  9. package/dist/cross-frame-lms.min.js +1 -1
  10. package/dist/cross-frame-lms.min.js.map +1 -0
  11. package/dist/esm/aicc.js.map +1 -0
  12. package/dist/esm/aicc.min.js.map +1 -0
  13. package/dist/esm/cross-frame-api.js +115 -108
  14. package/dist/esm/cross-frame-api.js.map +1 -0
  15. package/dist/esm/cross-frame-api.min.js +1 -1
  16. package/dist/esm/cross-frame-api.min.js.map +1 -0
  17. package/dist/esm/cross-frame-lms.js +32 -30
  18. package/dist/esm/cross-frame-lms.js.map +1 -0
  19. package/dist/esm/cross-frame-lms.min.js +1 -1
  20. package/dist/esm/cross-frame-lms.min.js.map +1 -0
  21. package/dist/esm/scorm-again.js +761 -500
  22. package/dist/esm/scorm-again.js.map +1 -0
  23. package/dist/esm/scorm-again.min.js +1 -1
  24. package/dist/esm/scorm-again.min.js.map +1 -0
  25. package/dist/esm/scorm12.js +152 -373
  26. package/dist/esm/scorm12.js.map +1 -0
  27. package/dist/esm/scorm12.min.js +1 -1
  28. package/dist/esm/scorm12.min.js.map +1 -0
  29. package/dist/esm/scorm2004.js +539 -306
  30. package/dist/esm/scorm2004.js.map +1 -0
  31. package/dist/esm/scorm2004.min.js +1 -1
  32. package/dist/esm/scorm2004.min.js.map +1 -0
  33. package/dist/scorm-again.js +1162 -328
  34. package/dist/scorm-again.js.map +1 -0
  35. package/dist/scorm-again.min.js +1 -1
  36. package/dist/scorm-again.min.js.map +1 -0
  37. package/dist/scorm12.js +832 -71
  38. package/dist/scorm12.js.map +1 -0
  39. package/dist/scorm12.min.js +1 -1
  40. package/dist/scorm12.min.js.map +1 -0
  41. package/dist/scorm2004.js +1035 -286
  42. package/dist/scorm2004.js.map +1 -0
  43. package/dist/scorm2004.min.js +1 -1
  44. package/dist/scorm2004.min.js.map +1 -0
  45. package/dist/types/BaseAPI.d.ts +3 -3
  46. package/dist/types/interfaces/services.d.ts +3 -2
  47. package/dist/types/services/EventService.d.ts +3 -3
  48. package/package.json +30 -37
@@ -1,6 +1,6 @@
1
1
  const SECONDS_PER_MINUTE = 60;
2
2
  const SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
3
- const getSecondsAsHHMMSS = memoize((totalSeconds) => {
3
+ const getSecondsAsHHMMSS = (totalSeconds) => {
4
4
  if (!totalSeconds || totalSeconds <= 0) {
5
5
  return "00:00:00";
6
6
  }
@@ -19,7 +19,7 @@ const getSecondsAsHHMMSS = memoize((totalSeconds) => {
19
19
  msStr = "." + msStr.split(".")[1];
20
20
  }
21
21
  return (hours + ":" + minutes + ":" + seconds).replace(/\b\d\b/g, "0$&") + msStr;
22
- });
22
+ };
23
23
  const getTimeAsSeconds = memoize(
24
24
  (timeString, timeRegex) => {
25
25
  if (typeof timeString === "number" || typeof timeString === "boolean") {
@@ -162,18 +162,19 @@ function memoize(fn, keyFn) {
162
162
  }
163
163
 
164
164
  class BaseCMI {
165
+ /**
166
+ * Flag used during JSON serialization to allow getter access without initialization checks.
167
+ * When true, getters can be accessed before the API is initialized, which is necessary
168
+ * for serializing the CMI data structure to JSON format.
169
+ */
170
+ jsonString = false;
171
+ _cmi_element;
172
+ _initialized = false;
165
173
  /**
166
174
  * Constructor for BaseCMI
167
175
  * @param {string} cmi_element
168
176
  */
169
177
  constructor(cmi_element) {
170
- /**
171
- * Flag used during JSON serialization to allow getter access without initialization checks.
172
- * When true, getters can be accessed before the API is initialized, which is necessary
173
- * for serializing the CMI data structure to JSON format.
174
- */
175
- this.jsonString = false;
176
- this._initialized = false;
177
178
  this._cmi_element = cmi_element;
178
179
  }
179
180
  /**
@@ -191,6 +192,7 @@ class BaseCMI {
191
192
  }
192
193
  }
193
194
  class BaseRootCMI extends BaseCMI {
195
+ _start_time;
194
196
  /**
195
197
  * Start time of the session
196
198
  * @type {number | undefined}
@@ -217,6 +219,7 @@ class BaseScormValidationError extends Error {
217
219
  this._errorCode = errorCode;
218
220
  Object.setPrototypeOf(this, BaseScormValidationError.prototype);
219
221
  }
222
+ _errorCode;
220
223
  /**
221
224
  * Getter for _errorCode
222
225
  * @return {number}
@@ -235,7 +238,6 @@ class ValidationError extends BaseScormValidationError {
235
238
  */
236
239
  constructor(CMIElement, errorCode, errorMessage, detailedMessage) {
237
240
  super(CMIElement, errorCode);
238
- this._detailedMessage = "";
239
241
  this.message = `${CMIElement} : ${errorMessage}`;
240
242
  this._errorMessage = errorMessage;
241
243
  if (detailedMessage) {
@@ -243,6 +245,8 @@ class ValidationError extends BaseScormValidationError {
243
245
  }
244
246
  Object.setPrototypeOf(this, ValidationError.prototype);
245
247
  }
248
+ _errorMessage;
249
+ _detailedMessage = "";
246
250
  /**
247
251
  * Getter for _errorMessage
248
252
  * @return {string}
@@ -409,6 +413,10 @@ const scorm12_errors = {
409
413
  };
410
414
 
411
415
  class CMIArray extends BaseCMI {
416
+ _errorCode;
417
+ _errorClass;
418
+ __children;
419
+ childArray;
412
420
  /**
413
421
  * Constructor cmi *.n arrays
414
422
  * @param {object} params
@@ -869,6 +877,10 @@ const scorm2004_regex = {
869
877
  };
870
878
 
871
879
  class ScheduledCommit {
880
+ _API;
881
+ _cancelled = false;
882
+ _timeout;
883
+ _callback;
872
884
  /**
873
885
  * Constructor for ScheduledCommit
874
886
  * @param {BaseAPI} API
@@ -876,7 +888,6 @@ class ScheduledCommit {
876
888
  * @param {string} callback
877
889
  */
878
890
  constructor(API, when, callback) {
879
- this._cancelled = false;
880
891
  this._API = API;
881
892
  this._timeout = setTimeout(this.wrapper.bind(this), when);
882
893
  this._callback = callback;
@@ -902,299 +913,9 @@ class ScheduledCommit {
902
913
  }
903
914
  }
904
915
 
905
- class RuleCondition extends BaseCMI {
906
- /**
907
- * Constructor for RuleCondition
908
- * @param {RuleConditionType} condition - The condition type
909
- * @param {RuleConditionOperator | null} operator - The operator (null for no operator)
910
- * @param {Map<string, any>} parameters - Additional parameters for the condition
911
- */
912
- constructor(condition = "always" /* ALWAYS */, operator = null, parameters = /* @__PURE__ */ new Map()) {
913
- super("ruleCondition");
914
- this._condition = "always" /* ALWAYS */;
915
- this._operator = null;
916
- this._parameters = /* @__PURE__ */ new Map();
917
- this._referencedObjective = null;
918
- this._condition = condition;
919
- this._operator = operator;
920
- this._parameters = parameters;
921
- }
922
- static {
923
- // Optional, overridable provider for current time (LMS may set via SequencingService)
924
- this._now = () => /* @__PURE__ */ new Date();
925
- }
926
- static {
927
- // Optional, overridable hook for getting elapsed seconds
928
- this._getElapsedSecondsHook = void 0;
929
- }
930
- /**
931
- * Allow integrators to override the clock used for time-based rules.
932
- */
933
- static setNowProvider(now) {
934
- if (typeof now === "function") {
935
- RuleCondition._now = now;
936
- }
937
- }
938
- /**
939
- * Allow integrators to set an elapsed seconds hook for time limit calculations
940
- */
941
- static setElapsedSecondsHook(hook) {
942
- RuleCondition._getElapsedSecondsHook = hook;
943
- }
944
- /**
945
- * Called when the API needs to be reset
946
- */
947
- reset() {
948
- this._initialized = false;
949
- this._condition = "always" /* ALWAYS */;
950
- this._operator = null;
951
- this._parameters = /* @__PURE__ */ new Map();
952
- }
953
- /**
954
- * Getter for condition
955
- * @return {RuleConditionType}
956
- */
957
- get condition() {
958
- return this._condition;
959
- }
960
- /**
961
- * Setter for condition
962
- * @param {RuleConditionType} condition
963
- */
964
- set condition(condition) {
965
- this._condition = condition;
966
- }
967
- /**
968
- * Getter for operator
969
- * @return {RuleConditionOperator | null}
970
- */
971
- get operator() {
972
- return this._operator;
973
- }
974
- /**
975
- * Setter for operator
976
- * @param {RuleConditionOperator | null} operator
977
- */
978
- set operator(operator) {
979
- this._operator = operator;
980
- }
981
- /**
982
- * Getter for parameters
983
- * @return {Map<string, any>}
984
- */
985
- get parameters() {
986
- return this._parameters;
987
- }
988
- /**
989
- * Setter for parameters
990
- * @param {Map<string, any>} parameters
991
- */
992
- set parameters(parameters) {
993
- this._parameters = parameters;
994
- }
995
- get referencedObjective() {
996
- return this._referencedObjective;
997
- }
998
- set referencedObjective(objectiveId) {
999
- this._referencedObjective = objectiveId;
1000
- }
1001
- resolveReferencedObjective(activity) {
1002
- if (!this._referencedObjective) {
1003
- return null;
1004
- }
1005
- if (activity.primaryObjective?.id === this._referencedObjective) {
1006
- return activity.primaryObjective;
1007
- }
1008
- const objectives = activity.objectives || [];
1009
- return objectives.find((obj) => obj.id === this._referencedObjective) || null;
1010
- }
1011
- /**
1012
- * Evaluate the condition for an activity
1013
- * @param {Activity} activity - The activity to evaluate the condition for
1014
- * @return {boolean} - True if the condition is met, false otherwise
1015
- */
1016
- evaluate(activity) {
1017
- let result;
1018
- const referencedObjective = this.resolveReferencedObjective(activity);
1019
- switch (this._condition) {
1020
- case "satisfied" /* SATISFIED */:
1021
- case "objectiveSatisfied" /* OBJECTIVE_SATISFIED */:
1022
- if (referencedObjective) {
1023
- result = referencedObjective.satisfiedStatus === true;
1024
- } else {
1025
- result = activity.successStatus === SuccessStatus.PASSED || activity.objectiveSatisfiedStatus === true;
1026
- }
1027
- break;
1028
- case "objectiveStatusKnown" /* OBJECTIVE_STATUS_KNOWN */:
1029
- result = referencedObjective ? !!referencedObjective.measureStatus : !!activity.objectiveMeasureStatus;
1030
- break;
1031
- case "objectiveMeasureKnown" /* OBJECTIVE_MEASURE_KNOWN */:
1032
- result = referencedObjective ? !!referencedObjective.measureStatus : !!activity.objectiveMeasureStatus;
1033
- break;
1034
- case "objectiveMeasureGreaterThan" /* OBJECTIVE_MEASURE_GREATER_THAN */: {
1035
- const greaterThanValue = this._parameters.get("threshold") || 0;
1036
- const measureStatus = referencedObjective ? referencedObjective.measureStatus : activity.objectiveMeasureStatus;
1037
- const measureValue = referencedObjective ? referencedObjective.normalizedMeasure : activity.objectiveNormalizedMeasure;
1038
- result = !!measureStatus && measureValue > greaterThanValue;
1039
- break;
1040
- }
1041
- case "objectiveMeasureLessThan" /* OBJECTIVE_MEASURE_LESS_THAN */: {
1042
- const lessThanValue = this._parameters.get("threshold") || 0;
1043
- const measureStatus = referencedObjective ? referencedObjective.measureStatus : activity.objectiveMeasureStatus;
1044
- const measureValue = referencedObjective ? referencedObjective.normalizedMeasure : activity.objectiveNormalizedMeasure;
1045
- result = !!measureStatus && measureValue < lessThanValue;
1046
- break;
1047
- }
1048
- case "completed" /* COMPLETED */:
1049
- case "activityCompleted" /* ACTIVITY_COMPLETED */:
1050
- if (referencedObjective) {
1051
- result = referencedObjective.completionStatus === CompletionStatus.COMPLETED;
1052
- } else {
1053
- result = activity.isCompleted;
1054
- }
1055
- break;
1056
- case "progressKnown" /* PROGRESS_KNOWN */:
1057
- case "activityProgressKnown" /* ACTIVITY_PROGRESS_KNOWN */:
1058
- if (referencedObjective) {
1059
- result = referencedObjective.completionStatus !== CompletionStatus.UNKNOWN;
1060
- } else {
1061
- result = activity.completionStatus !== "unknown";
1062
- }
1063
- break;
1064
- case "attempted" /* ATTEMPTED */:
1065
- result = activity.attemptCount > 0;
1066
- break;
1067
- case "attemptLimitExceeded" /* ATTEMPT_LIMIT_EXCEEDED */:
1068
- result = activity.hasAttemptLimitExceeded();
1069
- break;
1070
- case "timeLimitExceeded" /* TIME_LIMIT_EXCEEDED */:
1071
- result = this.evaluateTimeLimitExceeded(activity);
1072
- break;
1073
- case "outsideAvailableTimeRange" /* OUTSIDE_AVAILABLE_TIME_RANGE */:
1074
- result = this.evaluateOutsideAvailableTimeRange(activity);
1075
- break;
1076
- case "always" /* ALWAYS */:
1077
- result = true;
1078
- break;
1079
- case "never" /* NEVER */:
1080
- result = false;
1081
- break;
1082
- default:
1083
- result = false;
1084
- break;
1085
- }
1086
- if (this._operator === "not" /* NOT */) {
1087
- result = !result;
1088
- }
1089
- return result;
1090
- }
1091
- /**
1092
- * Evaluate if time limit has been exceeded
1093
- * @param {Activity} activity - The activity to evaluate
1094
- * @return {boolean}
1095
- * @private
1096
- */
1097
- evaluateTimeLimitExceeded(activity) {
1098
- let limit = activity.timeLimitDuration;
1099
- if (!limit && activity.attemptAbsoluteDurationLimit) {
1100
- limit = activity.attemptAbsoluteDurationLimit;
1101
- }
1102
- if (!limit) {
1103
- return false;
1104
- }
1105
- const limitSeconds = getDurationAsSeconds(limit, scorm2004_regex.CMITimespan);
1106
- if (limitSeconds <= 0) {
1107
- return false;
1108
- }
1109
- let elapsedSeconds = 0;
1110
- if (RuleCondition._getElapsedSecondsHook) {
1111
- try {
1112
- const hookResult = RuleCondition._getElapsedSecondsHook(activity);
1113
- if (typeof hookResult === "number" && !Number.isNaN(hookResult) && hookResult >= 0) {
1114
- elapsedSeconds = hookResult;
1115
- }
1116
- } catch {
1117
- elapsedSeconds = 0;
1118
- }
1119
- }
1120
- if (elapsedSeconds === 0 && activity.attemptExperiencedDuration) {
1121
- const attemptDurationSeconds = getDurationAsSeconds(
1122
- activity.attemptExperiencedDuration,
1123
- scorm2004_regex.CMITimespan
1124
- );
1125
- if (attemptDurationSeconds > 0) {
1126
- elapsedSeconds = attemptDurationSeconds;
1127
- }
1128
- }
1129
- if (elapsedSeconds === 0 && activity.attemptAbsoluteStartTime) {
1130
- try {
1131
- const start = new Date(activity.attemptAbsoluteStartTime).getTime();
1132
- const nowMs = RuleCondition._now().getTime();
1133
- if (!Number.isNaN(start) && !Number.isNaN(nowMs) && nowMs >= start) {
1134
- elapsedSeconds = (nowMs - start) / 1e3;
1135
- }
1136
- } catch {
1137
- elapsedSeconds = 0;
1138
- }
1139
- }
1140
- return elapsedSeconds > limitSeconds;
1141
- }
1142
- /**
1143
- * Evaluate if activity is outside available time range
1144
- * @param {Activity} activity - The activity to evaluate
1145
- * @return {boolean}
1146
- * @private
1147
- */
1148
- evaluateOutsideAvailableTimeRange(activity) {
1149
- const beginTime = activity.beginTimeLimit;
1150
- const endTime = activity.endTimeLimit;
1151
- if (!beginTime && !endTime) {
1152
- return false;
1153
- }
1154
- const now = RuleCondition._now();
1155
- if (beginTime) {
1156
- const beginDate = new Date(beginTime);
1157
- if (now < beginDate) {
1158
- return true;
1159
- }
1160
- }
1161
- if (endTime) {
1162
- const endDate = new Date(endTime);
1163
- if (now > endDate) {
1164
- return true;
1165
- }
1166
- }
1167
- return false;
1168
- }
1169
- /**
1170
- * Parse ISO 8601 duration to milliseconds
1171
- * Uses the standard getDurationAsSeconds utility which supports full ISO 8601 format
1172
- * including date components (years, months, weeks, days) and time components (hours, minutes, seconds).
1173
- * @param {string} duration - ISO 8601 duration string (e.g., "PT1H30M", "P1D", "P1Y2M3DT4H5M6S")
1174
- * @return {number} - Duration in milliseconds
1175
- * @private
1176
- */
1177
- parseISO8601Duration(duration) {
1178
- const seconds = getDurationAsSeconds(duration, scorm2004_regex.CMITimespan);
1179
- return seconds * 1e3;
1180
- }
1181
- /**
1182
- * toJSON for RuleCondition
1183
- * @return {object}
1184
- */
1185
- toJSON() {
1186
- this.jsonString = true;
1187
- const result = {
1188
- condition: this._condition,
1189
- operator: this._operator,
1190
- parameters: Object.fromEntries(this._parameters)
1191
- };
1192
- this.jsonString = false;
1193
- return result;
1194
- }
1195
- }
1196
-
1197
916
  class AsynchronousHttpService {
917
+ settings;
918
+ error_codes;
1198
919
  /**
1199
920
  * Constructor for AsynchronousHttpService
1200
921
  * @param {Settings} settings - The settings object
@@ -1390,6 +1111,7 @@ function getErrorCode(errorCodes, key) {
1390
1111
  return code;
1391
1112
  }
1392
1113
  class CMIValueAccessService {
1114
+ context;
1393
1115
  constructor(context) {
1394
1116
  this.context = context;
1395
1117
  }
@@ -1754,11 +1476,13 @@ class CMIValueAccessService {
1754
1476
  }
1755
1477
 
1756
1478
  class LoggingService {
1479
+ static _instance;
1480
+ _logLevel = LogLevelEnum.ERROR;
1481
+ _logHandler;
1757
1482
  /**
1758
1483
  * Private constructor to prevent direct instantiation
1759
1484
  */
1760
1485
  constructor() {
1761
- this._logLevel = LogLevelEnum.ERROR;
1762
1486
  this._logHandler = defaultLogHandler;
1763
1487
  }
1764
1488
  /**
@@ -1912,6 +1636,12 @@ function getLoggingService() {
1912
1636
  }
1913
1637
 
1914
1638
  class ErrorHandlingService {
1639
+ _lastErrorCode = "0";
1640
+ _lastDiagnostic = "";
1641
+ _errorCodes;
1642
+ _apiLog;
1643
+ _getLmsErrorMessageDetails;
1644
+ _loggingService;
1915
1645
  /**
1916
1646
  * Constructor for ErrorHandlingService
1917
1647
  *
@@ -1921,8 +1651,6 @@ class ErrorHandlingService {
1921
1651
  * @param {ILoggingService} loggingService - Optional logging service instance
1922
1652
  */
1923
1653
  constructor(errorCodes, apiLog, getLmsErrorMessageDetails, loggingService) {
1924
- this._lastErrorCode = "0";
1925
- this._lastDiagnostic = "";
1926
1654
  this._errorCodes = errorCodes;
1927
1655
  this._apiLog = apiLog;
1928
1656
  this._getLmsErrorMessageDetails = getLmsErrorMessageDetails;
@@ -2069,15 +1797,17 @@ function createErrorHandlingService(errorCodes, apiLog, getLmsErrorMessageDetail
2069
1797
  }
2070
1798
 
2071
1799
  class EventService {
1800
+ // Map of function names to listeners for faster lookups
1801
+ listenerMap = /* @__PURE__ */ new Map();
1802
+ // Total count of listeners for logging
1803
+ listenerCount = 0;
1804
+ // Function to log API messages
1805
+ apiLog;
2072
1806
  /**
2073
1807
  * Constructor for EventService
2074
1808
  * @param {Function} apiLog - Function to log API messages
2075
1809
  */
2076
1810
  constructor(apiLog) {
2077
- // Map of function names to listeners for faster lookups
2078
- this.listenerMap = /* @__PURE__ */ new Map();
2079
- // Total count of listeners for logging
2080
- this.listenerCount = 0;
2081
1811
  this.apiLog = apiLog;
2082
1812
  }
2083
1813
  /**
@@ -2245,10 +1975,6 @@ class OfflineStorageService {
2245
1975
  */
2246
1976
  constructor(settings, error_codes, apiLog) {
2247
1977
  this.apiLog = apiLog;
2248
- this.storeName = "scorm_again_offline_data";
2249
- this.syncQueue = "scorm_again_sync_queue";
2250
- this.isOnline = navigator.onLine;
2251
- this.syncInProgress = false;
2252
1978
  this.settings = settings;
2253
1979
  this.error_codes = error_codes;
2254
1980
  this.boundOnlineStatusChangeHandler = this.handleOnlineStatusChange.bind(this);
@@ -2257,6 +1983,14 @@ class OfflineStorageService {
2257
1983
  window.addEventListener("offline", this.boundOnlineStatusChangeHandler);
2258
1984
  window.addEventListener("scorm-again:network-status", this.boundCustomNetworkStatusHandler);
2259
1985
  }
1986
+ settings;
1987
+ error_codes;
1988
+ storeName = "scorm_again_offline_data";
1989
+ syncQueue = "scorm_again_sync_queue";
1990
+ isOnline = navigator.onLine;
1991
+ syncInProgress = false;
1992
+ boundOnlineStatusChangeHandler;
1993
+ boundCustomNetworkStatusHandler;
2260
1994
  /**
2261
1995
  * Handle changes in online status
2262
1996
  */
@@ -2568,7 +2302,7 @@ class OfflineStorageService {
2568
2302
  localStorage.setItem(key, JSON.stringify(data));
2569
2303
  } catch (error) {
2570
2304
  if (error instanceof DOMException && error.name === "QuotaExceededError") {
2571
- throw new Error("storage quota exceeded - localStorage is full");
2305
+ throw new Error("storage quota exceeded - localStorage is full", { cause: error });
2572
2306
  }
2573
2307
  throw error;
2574
2308
  }
@@ -2886,6 +2620,8 @@ class SerializationService {
2886
2620
  }
2887
2621
 
2888
2622
  class SynchronousHttpService {
2623
+ settings;
2624
+ error_codes;
2889
2625
  /**
2890
2626
  * Constructor for SynchronousHttpService
2891
2627
  * @param {InternalSettings} settings - The settings object
@@ -3088,6 +2824,17 @@ class ValidationService {
3088
2824
  const validationService = new ValidationService();
3089
2825
 
3090
2826
  class BaseAPI {
2827
+ _timeout;
2828
+ _error_codes;
2829
+ _settings = DefaultSettings;
2830
+ _httpService;
2831
+ _eventService;
2832
+ _serializationService;
2833
+ _errorHandlingService;
2834
+ _loggingService;
2835
+ _offlineStorageService;
2836
+ _cmiValueAccessService;
2837
+ _courseId = "";
3091
2838
  /**
3092
2839
  * Constructor for Base API class. Sets some shared API fields, as well as
3093
2840
  * sets up options for the API.
@@ -3102,8 +2849,6 @@ class BaseAPI {
3102
2849
  * @param {IOfflineStorageService} offlineStorageService - Optional Offline Storage service instance
3103
2850
  */
3104
2851
  constructor(error_codes, settings, httpService, eventService, serializationService, cmiDataService, errorHandlingService, loggingService, offlineStorageService) {
3105
- this._settings = DefaultSettings;
3106
- this._courseId = "";
3107
2852
  if (new.target === BaseAPI) {
3108
2853
  throw new TypeError("Cannot construct BaseAPI instances directly");
3109
2854
  }
@@ -3230,6 +2975,8 @@ class BaseAPI {
3230
2975
  };
3231
2976
  this._cmiValueAccessService = new CMIValueAccessService(cmiValueAccessContext);
3232
2977
  }
2978
+ startingData;
2979
+ currentState;
3233
2980
  /**
3234
2981
  * Get the last error code
3235
2982
  * @return {string}
@@ -4142,6 +3889,21 @@ class BaseAPI {
4142
3889
  }
4143
3890
 
4144
3891
  class CMIScore extends BaseCMI {
3892
+ __children;
3893
+ /**
3894
+ * Score range validation pattern (e.g., "0#100" for SCORM 1.2).
3895
+ * Set to `false` to disable range validation (e.g., for SCORM 2004 where scores have no upper bound).
3896
+ * This property is intentionally unused in the base class but provides subclass flexibility.
3897
+ */
3898
+ __score_range;
3899
+ __invalid_error_code;
3900
+ __invalid_type_code;
3901
+ __invalid_range_code;
3902
+ __decimal_regex;
3903
+ __error_class;
3904
+ _raw = "";
3905
+ _min = "";
3906
+ _max;
4145
3907
  /**
4146
3908
  * Constructor for *.score
4147
3909
  *
@@ -4165,8 +3927,6 @@ class CMIScore extends BaseCMI {
4165
3927
  */
4166
3928
  constructor(params) {
4167
3929
  super(params.CMIElement);
4168
- this._raw = "";
4169
- this._min = "";
4170
3930
  this.__children = params.score_children || scorm12_constants.score_children;
4171
3931
  this.__score_range = !params.score_range ? false : scorm12_regex.score_range;
4172
3932
  this._max = params.max || params.max === "" ? params.max : "100";
@@ -4319,18 +4079,6 @@ class CMICore extends BaseCMI {
4319
4079
  */
4320
4080
  constructor() {
4321
4081
  super("cmi.core");
4322
- this.__children = scorm12_constants.core_children;
4323
- this._student_id = "";
4324
- this._student_name = "";
4325
- this._lesson_location = "";
4326
- this._credit = "";
4327
- this._lesson_status = "not attempted";
4328
- this._entry = "";
4329
- this._total_time = "";
4330
- this._lesson_mode = "normal";
4331
- this._exit = "";
4332
- this._session_time = "00:00:00";
4333
- this._suspend_data = "";
4334
4082
  this.score = new CMIScore({
4335
4083
  CMIElement: "cmi.core.score",
4336
4084
  score_children: scorm12_constants.score_children,
@@ -4341,6 +4089,7 @@ class CMICore extends BaseCMI {
4341
4089
  errorClass: Scorm12ValidationError
4342
4090
  });
4343
4091
  }
4092
+ score;
4344
4093
  /**
4345
4094
  * Called when the API has been initialized after the CMI has been created
4346
4095
  */
@@ -4348,6 +4097,18 @@ class CMICore extends BaseCMI {
4348
4097
  super.initialize();
4349
4098
  this.score?.initialize();
4350
4099
  }
4100
+ __children = scorm12_constants.core_children;
4101
+ _student_id = "";
4102
+ _student_name = "";
4103
+ _lesson_location = "";
4104
+ _credit = "";
4105
+ _lesson_status = "not attempted";
4106
+ _entry = "";
4107
+ _total_time = "";
4108
+ _lesson_mode = "normal";
4109
+ _exit = "";
4110
+ _session_time = "00:00:00";
4111
+ _suspend_data = "";
4351
4112
  /**
4352
4113
  * Called when the API has been reset
4353
4114
  */
@@ -4748,8 +4509,6 @@ class CMIObjectivesObject extends BaseCMI {
4748
4509
  */
4749
4510
  constructor() {
4750
4511
  super("cmi.objectives.n");
4751
- this._id = "";
4752
- this._status = "";
4753
4512
  this.score = new CMIScore({
4754
4513
  CMIElement: "cmi.objectives.n.score",
4755
4514
  score_children: scorm12_constants.score_children,
@@ -4760,6 +4519,9 @@ class CMIObjectivesObject extends BaseCMI {
4760
4519
  errorClass: Scorm12ValidationError
4761
4520
  });
4762
4521
  }
4522
+ score;
4523
+ _id = "";
4524
+ _status = "";
4763
4525
  /**
4764
4526
  * Called when the API has been reset
4765
4527
  */
@@ -4851,15 +4613,16 @@ function parseTimeAllowed(value, fieldName) {
4851
4613
  throw new Scorm12ValidationError(fieldName, scorm12_errors.TYPE_MISMATCH);
4852
4614
  }
4853
4615
  class CMIStudentData extends BaseCMI {
4616
+ __children;
4617
+ _mastery_score = "";
4618
+ _max_time_allowed = "";
4619
+ _time_limit_action = "";
4854
4620
  /**
4855
4621
  * Constructor for cmi.student_data
4856
4622
  * @param {string} student_data_children
4857
4623
  */
4858
4624
  constructor(student_data_children) {
4859
4625
  super("cmi.student_data");
4860
- this._mastery_score = "";
4861
- this._max_time_allowed = "";
4862
- this._time_limit_action = "";
4863
4626
  this.__children = student_data_children ? student_data_children : scorm12_constants.student_data_children;
4864
4627
  }
4865
4628
  /**
@@ -4999,18 +4762,19 @@ class CMIStudentData extends BaseCMI {
4999
4762
  }
5000
4763
 
5001
4764
  class CMIStudentPreference extends BaseCMI {
4765
+ __children;
5002
4766
  /**
5003
4767
  * Constructor for cmi.student_preference
5004
4768
  * @param {string} student_preference_children
5005
4769
  */
5006
4770
  constructor(student_preference_children) {
5007
4771
  super("cmi.student_preference");
5008
- this._audio = "";
5009
- this._language = "";
5010
- this._speed = "";
5011
- this._text = "";
5012
4772
  this.__children = student_preference_children ? student_preference_children : scorm12_constants.student_preference_children;
5013
4773
  }
4774
+ _audio = "";
4775
+ _language = "";
4776
+ _speed = "";
4777
+ _text = "";
5014
4778
  /**
5015
4779
  * Called when the API has been reset
5016
4780
  */
@@ -5152,13 +4916,6 @@ class CMIInteractionsObject extends BaseCMI {
5152
4916
  */
5153
4917
  constructor() {
5154
4918
  super("cmi.interactions.n");
5155
- this._id = "";
5156
- this._time = "";
5157
- this._type = "";
5158
- this._weighting = "";
5159
- this._student_response = "";
5160
- this._result = "";
5161
- this._latency = "";
5162
4919
  this.objectives = new CMIArray({
5163
4920
  CMIElement: "cmi.interactions.n.objectives",
5164
4921
  errorCode: scorm12_errors.INVALID_SET_VALUE,
@@ -5172,6 +4929,8 @@ class CMIInteractionsObject extends BaseCMI {
5172
4929
  children: scorm12_constants.correct_responses_children
5173
4930
  });
5174
4931
  }
4932
+ objectives;
4933
+ correct_responses;
5175
4934
  /**
5176
4935
  * Called when the API has been initialized after the CMI has been created
5177
4936
  */
@@ -5180,6 +4939,13 @@ class CMIInteractionsObject extends BaseCMI {
5180
4939
  this.objectives?.initialize();
5181
4940
  this.correct_responses?.initialize();
5182
4941
  }
4942
+ _id = "";
4943
+ _time = "";
4944
+ _type = "";
4945
+ _weighting = "";
4946
+ _student_response = "";
4947
+ _result = "";
4948
+ _latency = "";
5183
4949
  /**
5184
4950
  * Called when the API has been reset
5185
4951
  */
@@ -5409,8 +5175,8 @@ class CMIInteractionsObjectivesObject extends BaseCMI {
5409
5175
  */
5410
5176
  constructor() {
5411
5177
  super("cmi.interactions.n.objectives.n");
5412
- this._id = "";
5413
5178
  }
5179
+ _id = "";
5414
5180
  /**
5415
5181
  * Called when the API has been reset
5416
5182
  */
@@ -5463,8 +5229,8 @@ class CMIInteractionsCorrectResponsesObject extends BaseCMI {
5463
5229
  */
5464
5230
  constructor() {
5465
5231
  super("cmi.interactions.correct_responses.n");
5466
- this._pattern = "";
5467
5232
  }
5233
+ _pattern = "";
5468
5234
  /**
5469
5235
  * Called when the API has been reset
5470
5236
  */
@@ -5513,6 +5279,11 @@ class CMIInteractionsCorrectResponsesObject extends BaseCMI {
5513
5279
  }
5514
5280
 
5515
5281
  class CMI extends BaseRootCMI {
5282
+ __children = "";
5283
+ __version = "3.4";
5284
+ _launch_data = "";
5285
+ _comments = "";
5286
+ _comments_from_lms = "";
5516
5287
  /**
5517
5288
  * Constructor for the SCORM 1.2 cmi object
5518
5289
  * @param {string} cmi_children
@@ -5521,11 +5292,6 @@ class CMI extends BaseRootCMI {
5521
5292
  */
5522
5293
  constructor(cmi_children, student_data, initialized) {
5523
5294
  super("cmi");
5524
- this.__children = "";
5525
- this.__version = "3.4";
5526
- this._launch_data = "";
5527
- this._comments = "";
5528
- this._comments_from_lms = "";
5529
5295
  if (initialized) this.initialize();
5530
5296
  this.__children = cmi_children ? cmi_children : scorm12_constants.cmi_children;
5531
5297
  this.core = new CMICore();
@@ -5534,6 +5300,11 @@ class CMI extends BaseRootCMI {
5534
5300
  this.student_preference = new CMIStudentPreference();
5535
5301
  this.interactions = new CMIInteractions();
5536
5302
  }
5303
+ core;
5304
+ objectives;
5305
+ student_data;
5306
+ student_preference;
5307
+ interactions;
5537
5308
  /**
5538
5309
  * Called when the API has been reset
5539
5310
  *
@@ -5738,7 +5509,6 @@ class NAV extends BaseCMI {
5738
5509
  */
5739
5510
  constructor() {
5740
5511
  super("cmi.nav");
5741
- this._event = "";
5742
5512
  }
5743
5513
  /**
5744
5514
  * Called when the API has been reset
@@ -5755,6 +5525,7 @@ class NAV extends BaseCMI {
5755
5525
  this._event = "";
5756
5526
  this._initialized = false;
5757
5527
  }
5528
+ _event = "";
5758
5529
  /**
5759
5530
  * Getter for _event
5760
5531
  * @return {string}
@@ -5790,6 +5561,19 @@ class NAV extends BaseCMI {
5790
5561
  }
5791
5562
 
5792
5563
  class Scorm12API extends BaseAPI {
5564
+ /**
5565
+ * Static global storage for learner preferences
5566
+ * When globalStudentPreferences is enabled, preferences persist across SCO instances
5567
+ * @private
5568
+ */
5569
+ static _globalLearnerPrefs = null;
5570
+ /**
5571
+ * Clear the global learner preferences storage
5572
+ * @public
5573
+ */
5574
+ static clearGlobalPreferences() {
5575
+ Scorm12API._globalLearnerPrefs = null;
5576
+ }
5793
5577
  /**
5794
5578
  * Constructor for SCORM 1.2 API
5795
5579
  * @param {object} settings
@@ -5803,7 +5587,6 @@ class Scorm12API extends BaseAPI {
5803
5587
  }
5804
5588
  }
5805
5589
  super(scorm12_errors, settingsCopy, httpService);
5806
- this.statusSetByModule = false;
5807
5590
  this.cmi = new CMI();
5808
5591
  this.nav = new NAV();
5809
5592
  if (this.settings.globalStudentPreferences && Scorm12API._globalLearnerPrefs) {
@@ -5829,21 +5612,17 @@ class Scorm12API extends BaseAPI {
5829
5612
  this.LMSGetErrorString = this.lmsGetErrorString;
5830
5613
  this.LMSGetDiagnostic = this.lmsGetDiagnostic;
5831
5614
  }
5832
- static {
5833
- /**
5834
- * Static global storage for learner preferences
5835
- * When globalStudentPreferences is enabled, preferences persist across SCO instances
5836
- * @private
5837
- */
5838
- this._globalLearnerPrefs = null;
5839
- }
5840
- /**
5841
- * Clear the global learner preferences storage
5842
- * @public
5843
- */
5844
- static clearGlobalPreferences() {
5845
- Scorm12API._globalLearnerPrefs = null;
5846
- }
5615
+ statusSetByModule = false;
5616
+ cmi;
5617
+ nav;
5618
+ LMSInitialize;
5619
+ LMSFinish;
5620
+ LMSGetValue;
5621
+ LMSSetValue;
5622
+ LMSCommit;
5623
+ LMSGetLastError;
5624
+ LMSGetErrorString;
5625
+ LMSGetDiagnostic;
5847
5626
  /**
5848
5627
  * Called when the API needs to be reset
5849
5628
  */
@@ -6039,7 +5818,7 @@ class Scorm12API extends BaseAPI {
6039
5818
  */
6040
5819
  setCMIValue(CMIElement, value) {
6041
5820
  const result = this._commonSetCMIValue("LMSSetValue", false, CMIElement, value);
6042
- if (this.settings.globalStudentPreferences) {
5821
+ if (result === global_constants.SCORM_TRUE && this.settings.globalStudentPreferences) {
6043
5822
  if (CMIElement === "cmi.student_preference.audio") {
6044
5823
  this._updateGlobalPreference("audio", value);
6045
5824
  } else if (CMIElement === "cmi.student_preference.language") {
@@ -6142,7 +5921,7 @@ class Scorm12API extends BaseAPI {
6142
5921
  const flattened = flatten(cmiExport);
6143
5922
  switch (this.settings.dataCommitFormat) {
6144
5923
  case "flattened":
6145
- return flatten(cmiExport);
5924
+ return flattened;
6146
5925
  case "params":
6147
5926
  for (const item in flattened) {
6148
5927
  if ({}.hasOwnProperty.call(flattened, item)) {