scorm-again 2.5.0 → 2.6.1

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 (87) hide show
  1. package/dist/aicc.js +657 -489
  2. package/dist/aicc.js.map +1 -1
  3. package/dist/aicc.min.js +1 -1
  4. package/dist/aicc.min.js.map +1 -1
  5. package/dist/esm/aicc.js +670 -489
  6. package/dist/esm/aicc.js.map +1 -1
  7. package/dist/esm/aicc.min.js +1 -1
  8. package/dist/esm/aicc.min.js.map +1 -1
  9. package/dist/esm/scorm-again.js +1113 -729
  10. package/dist/esm/scorm-again.js.map +1 -1
  11. package/dist/esm/scorm-again.min.js +1 -1
  12. package/dist/esm/scorm-again.min.js.map +1 -1
  13. package/dist/esm/scorm12.js +512 -394
  14. package/dist/esm/scorm12.js.map +1 -1
  15. package/dist/esm/scorm12.min.js +1 -1
  16. package/dist/esm/scorm12.min.js.map +1 -1
  17. package/dist/esm/scorm2004.js +678 -452
  18. package/dist/esm/scorm2004.js.map +1 -1
  19. package/dist/esm/scorm2004.min.js +1 -1
  20. package/dist/esm/scorm2004.min.js.map +1 -1
  21. package/dist/scorm-again.js +1100 -728
  22. package/dist/scorm-again.js.map +1 -1
  23. package/dist/scorm-again.min.js +1 -1
  24. package/dist/scorm-again.min.js.map +1 -1
  25. package/dist/scorm12.js +500 -394
  26. package/dist/scorm12.js.map +1 -1
  27. package/dist/scorm12.min.js +1 -1
  28. package/dist/scorm12.min.js.map +1 -1
  29. package/dist/scorm2004.js +665 -452
  30. package/dist/scorm2004.js.map +1 -1
  31. package/dist/scorm2004.min.js +1 -1
  32. package/dist/scorm2004.min.js.map +1 -1
  33. package/dist_test.html +208 -0
  34. package/package.json +14 -14
  35. package/src/AICC.ts +6 -3
  36. package/src/BaseAPI.ts +43 -37
  37. package/src/Scorm12API.ts +17 -23
  38. package/src/Scorm2004API.ts +99 -42
  39. package/src/ScormAgain.ts +3 -7
  40. package/src/cmi/aicc/attempts.ts +22 -12
  41. package/src/cmi/aicc/cmi.ts +2 -2
  42. package/src/cmi/aicc/core.ts +44 -26
  43. package/src/cmi/aicc/evaluation.ts +31 -12
  44. package/src/cmi/aicc/paths.ts +29 -15
  45. package/src/cmi/aicc/student_data.ts +14 -5
  46. package/src/cmi/aicc/student_demographics.ts +31 -24
  47. package/src/cmi/aicc/student_preferences.ts +11 -11
  48. package/src/cmi/aicc/tries.ts +24 -14
  49. package/src/cmi/aicc/validation.ts +3 -4
  50. package/src/cmi/common/array.ts +17 -5
  51. package/src/cmi/common/base_cmi.ts +3 -1
  52. package/src/cmi/common/score.ts +16 -13
  53. package/src/cmi/scorm12/cmi.ts +25 -10
  54. package/src/cmi/scorm12/interactions.ts +62 -28
  55. package/src/cmi/scorm12/nav.ts +13 -5
  56. package/src/cmi/scorm12/objectives.ts +28 -18
  57. package/src/cmi/scorm12/student_data.ts +15 -8
  58. package/src/cmi/scorm12/student_preference.ts +20 -13
  59. package/src/cmi/scorm12/validation.ts +7 -7
  60. package/src/cmi/scorm2004/adl.ts +141 -25
  61. package/src/cmi/scorm2004/cmi.ts +50 -55
  62. package/src/cmi/scorm2004/comments.ts +21 -20
  63. package/src/cmi/scorm2004/interactions.ts +73 -32
  64. package/src/cmi/scorm2004/learner_preference.ts +20 -13
  65. package/src/cmi/scorm2004/objectives.ts +41 -16
  66. package/src/cmi/scorm2004/score.ts +22 -11
  67. package/src/cmi/scorm2004/validation.ts +4 -4
  68. package/src/constants/api_constants.ts +8 -19
  69. package/src/constants/default_settings.ts +6 -5
  70. package/src/constants/error_codes.ts +5 -12
  71. package/src/constants/regex.ts +4 -10
  72. package/src/constants/response_constants.ts +1 -2
  73. package/src/exceptions/aicc_exceptions.ts +29 -0
  74. package/src/exceptions/scorm12_exceptions.ts +29 -0
  75. package/src/exceptions/scorm2004_exceptions.ts +29 -0
  76. package/src/exceptions.ts +0 -81
  77. package/src/types/api_types.ts +3 -2
  78. package/test/AICC.spec.ts +114 -43
  79. package/test/Scorm12API.spec.ts +60 -39
  80. package/test/Scorm2004API.spec.ts +165 -80
  81. package/test/cmi/aicc_cmi.spec.ts +6 -9
  82. package/test/cmi/scorm12_cmi.spec.ts +8 -8
  83. package/test/cmi/scorm2004_cmi.spec.ts +8 -9
  84. package/test/exceptions.spec.ts +11 -9
  85. package/test/types/api_types.spec.ts +3 -3
  86. package/test/utilities.spec.ts +1 -4
  87. package/webpack.config.js +5 -1
@@ -2,36 +2,30 @@ import BaseAPI from "./BaseAPI";
2
2
  import { CMI } from "./cmi/scorm2004/cmi";
3
3
  import * as Utilities from "./utilities";
4
4
  import { stringMatches } from "./utilities";
5
- import APIConstants from "./constants/api_constants";
6
- import ErrorCodes from "./constants/error_codes";
5
+ import { global_constants, scorm2004_constants } from "./constants/api_constants";
6
+ import { scorm2004_errors } from "./constants/error_codes";
7
7
  import { CorrectResponses, ResponseType } from "./constants/response_constants";
8
8
  import ValidLanguages from "./constants/language_constants";
9
- import Regex from "./constants/regex";
10
- import regex from "./constants/regex";
11
9
  import { CMIArray } from "./cmi/common/array";
12
10
  import { BaseCMI } from "./cmi/common/base_cmi";
13
11
  import {
14
12
  CMIInteractionsCorrectResponsesObject,
15
13
  CMIInteractionsObject,
16
- CMIInteractionsObjectivesObject,
14
+ CMIInteractionsObjectivesObject
17
15
  } from "./cmi/scorm2004/interactions";
18
16
  import { CMICommentsObject } from "./cmi/scorm2004/comments";
19
17
  import { CMIObjectivesObject } from "./cmi/scorm2004/objectives";
20
- import { ADL } from "./cmi/scorm2004/adl";
21
- import {
22
- CommitObject,
23
- RefObject,
24
- ResultObject,
25
- ScoreObject,
26
- Settings,
27
- } from "./types/api_types";
18
+ import { ADL, ADLDataObject } from "./cmi/scorm2004/adl";
19
+ import { CommitObject, RefObject, ResultObject, ScoreObject, Settings } from "./types/api_types";
28
20
  import { CompletionStatus, SuccessStatus } from "./constants/enums";
21
+ import { scorm2004_regex } from "./constants/regex";
29
22
 
30
23
  /**
31
24
  * API class for SCORM 2004
32
25
  */
33
26
  class Scorm2004Impl extends BaseAPI {
34
27
  private _version: string = "1.0";
28
+ private _globalObjectives: CMIObjectivesObject[] = [];
35
29
 
36
30
  /**
37
31
  * Constructor for SCORM 2004 API
@@ -44,7 +38,7 @@ class Scorm2004Impl extends BaseAPI {
44
38
  }
45
39
  }
46
40
 
47
- super(ErrorCodes.scorm2004, settings);
41
+ super(scorm2004_errors, settings);
48
42
 
49
43
  this.cmi = new CMI();
50
44
  this.adl = new ADL();
@@ -78,8 +72,8 @@ class Scorm2004Impl extends BaseAPI {
78
72
  reset(settings?: Settings) {
79
73
  this.commonReset(settings);
80
74
 
81
- this.cmi = new CMI();
82
- this.adl = new ADL();
75
+ this.cmi?.reset();
76
+ this.adl?.reset();
83
77
  }
84
78
 
85
79
  /**
@@ -90,6 +84,13 @@ class Scorm2004Impl extends BaseAPI {
90
84
  return this._version;
91
85
  }
92
86
 
87
+ /**
88
+ * Getter for _globalObjectives
89
+ */
90
+ get globalObjectives(): CMIObjectivesObject[] {
91
+ return this._globalObjectives;
92
+ }
93
+
93
94
  /**
94
95
  * @return {string} bool
95
96
  */
@@ -105,13 +106,13 @@ class Scorm2004Impl extends BaseAPI {
105
106
  (async () => {
106
107
  await this.internalFinish();
107
108
  })();
108
- return APIConstants.global.SCORM_TRUE;
109
+ return global_constants.SCORM_TRUE;
109
110
  }
110
111
 
111
112
  async internalFinish(): Promise<string> {
112
113
  const result = await this.terminate("Terminate", true);
113
114
 
114
- if (result === APIConstants.global.SCORM_TRUE) {
115
+ if (result === global_constants.SCORM_TRUE) {
115
116
  if (this.adl.nav.request !== "_none_") {
116
117
  const navActions: { [key: string]: string } = {
117
118
  continue: "SequenceNext",
@@ -125,7 +126,7 @@ class Scorm2004Impl extends BaseAPI {
125
126
  };
126
127
 
127
128
  let request = this.adl.nav.request;
128
- const choiceJumpRegex = new RegExp(regex.scorm2004.NAVEvent);
129
+ const choiceJumpRegex = new RegExp(scorm2004_regex.NAVEvent);
129
130
  const matches = request.match(choiceJumpRegex);
130
131
  let target = "";
131
132
  if (matches) {
@@ -176,6 +177,7 @@ class Scorm2004Impl extends BaseAPI {
176
177
  * @return {string}
177
178
  */
178
179
  lmsSetValue(CMIElement: string, value: any): string {
180
+ // Proceed with regular setting for non-objective elements or fallback behavior
179
181
  return this.setValue("SetValue", "Commit", true, CMIElement, value);
180
182
  }
181
183
 
@@ -192,7 +194,7 @@ class Scorm2004Impl extends BaseAPI {
192
194
  await this.commit("LMSCommit", false);
193
195
  })();
194
196
  }
195
- return APIConstants.global.SCORM_TRUE;
197
+ return global_constants.SCORM_TRUE;
196
198
  }
197
199
 
198
200
  /**
@@ -232,6 +234,57 @@ class Scorm2004Impl extends BaseAPI {
232
234
  * @return {string}
233
235
  */
234
236
  override setCMIValue(CMIElement: string, value: any): string {
237
+ // Check if we're updating a global or local objective
238
+ if (stringMatches(CMIElement, "cmi\\.objectives\\.\\d+")) {
239
+ const parts = CMIElement.split(".");
240
+ const index = Number(parts[2]);
241
+ const element_base = `cmi.objectives.${index}`;
242
+
243
+ let objective_id;
244
+ const setting_id = stringMatches(
245
+ CMIElement,
246
+ "cmi\\.objectives\\.\\d+\\.id",
247
+ );
248
+
249
+ if (setting_id) {
250
+ // If we're setting the objective ID, capture it directly
251
+ objective_id = value;
252
+ } else {
253
+ // Find existing objective ID if available
254
+ const objective = this.cmi.objectives.findObjectiveByIndex(index);
255
+ objective_id = objective ? objective.id : undefined;
256
+ }
257
+
258
+ // Check if the objective ID matches a global objective
259
+ const is_global =
260
+ objective_id && this.settings.globalObjectiveIds.includes(objective_id);
261
+
262
+ if (is_global) {
263
+ // Locate or create an entry in _globalObjectives for the global objective
264
+ let global_index = this._globalObjectives.findIndex(
265
+ (obj) => obj.id === objective_id,
266
+ );
267
+
268
+ if (global_index === -1) {
269
+ global_index = this._globalObjectives.length;
270
+ const newGlobalObjective = new CMIObjectivesObject();
271
+ newGlobalObjective.id = objective_id;
272
+ this._globalObjectives.push(newGlobalObjective);
273
+ }
274
+
275
+ // Update the global objective
276
+ const global_element = CMIElement.replace(
277
+ element_base,
278
+ `_globalObjectives.${global_index}`,
279
+ );
280
+ this._commonSetCMIValue(
281
+ "SetGlobalObjectiveValue",
282
+ true,
283
+ global_element,
284
+ value,
285
+ );
286
+ }
287
+ }
235
288
  return this._commonSetCMIValue("SetValue", true, CMIElement, value);
236
289
  }
237
290
 
@@ -278,6 +331,10 @@ class Scorm2004Impl extends BaseAPI {
278
331
  return new CMICommentsObject(true);
279
332
  }
280
333
 
334
+ if (stringMatches(CMIElement, "adl\\.data\\.\\d+")) {
335
+ return new ADLDataObject();
336
+ }
337
+
281
338
  return null;
282
339
  }
283
340
 
@@ -291,7 +348,7 @@ class Scorm2004Impl extends BaseAPI {
291
348
 
292
349
  if (this.isInitialized()) {
293
350
  if (!interaction.type) {
294
- this.throwSCORMError(ErrorCodes.scorm2004.DEPENDENCY_NOT_ESTABLISHED);
351
+ this.throwSCORMError(scorm2004_errors.DEPENDENCY_NOT_ESTABLISHED);
295
352
  } else {
296
353
  this.checkDuplicateChoiceResponse(interaction, value);
297
354
  const response_type = CorrectResponses[interaction.type];
@@ -299,7 +356,7 @@ class Scorm2004Impl extends BaseAPI {
299
356
  this.checkValidResponseType(response_type, value, interaction.type);
300
357
  } else {
301
358
  this.throwSCORMError(
302
- ErrorCodes.scorm2004.GENERAL_SET_FAILURE,
359
+ scorm2004_errors.GENERAL_SET_FAILURE,
303
360
  "Incorrect Response Type: " + interaction.type,
304
361
  );
305
362
  }
@@ -335,7 +392,7 @@ class Scorm2004Impl extends BaseAPI {
335
392
  this.checkCorrectResponseValue(interaction_type, nodes, value);
336
393
  } else if (nodes.length > response_type.max) {
337
394
  this.throwSCORMError(
338
- ErrorCodes.scorm2004.GENERAL_SET_FAILURE,
395
+ scorm2004_errors.GENERAL_SET_FAILURE,
339
396
  "Data Model Element Pattern Too Long",
340
397
  );
341
398
  }
@@ -356,7 +413,7 @@ class Scorm2004Impl extends BaseAPI {
356
413
  ) {
357
414
  const response = interaction.correct_responses.childArray[i];
358
415
  if (response.pattern === value) {
359
- this.throwSCORMError(ErrorCodes.scorm2004.GENERAL_SET_FAILURE);
416
+ this.throwSCORMError(scorm2004_errors.GENERAL_SET_FAILURE);
360
417
  }
361
418
  }
362
419
  }
@@ -397,14 +454,14 @@ class Scorm2004Impl extends BaseAPI {
397
454
  } else {
398
455
  if (this.lastErrorCode === "0") {
399
456
  this.throwSCORMError(
400
- ErrorCodes.scorm2004.GENERAL_SET_FAILURE,
457
+ scorm2004_errors.GENERAL_SET_FAILURE,
401
458
  "Data Model Element Pattern Already Exists",
402
459
  );
403
460
  }
404
461
  }
405
462
  } else {
406
463
  this.throwSCORMError(
407
- ErrorCodes.scorm2004.GENERAL_SET_FAILURE,
464
+ scorm2004_errors.GENERAL_SET_FAILURE,
408
465
  "Data Model Element Collection Limit Reached",
409
466
  );
410
467
  }
@@ -436,11 +493,11 @@ class Scorm2004Impl extends BaseAPI {
436
493
 
437
494
  // Set error number to string since inconsistent from modules if string or number
438
495
  errorNumber = String(errorNumber);
439
- if (APIConstants.scorm2004.error_descriptions[errorNumber]) {
496
+ if (scorm2004_constants.error_descriptions[errorNumber]) {
440
497
  basicMessage =
441
- APIConstants.scorm2004.error_descriptions[errorNumber].basicMessage;
498
+ scorm2004_constants.error_descriptions[errorNumber].basicMessage;
442
499
  detailMessage =
443
- APIConstants.scorm2004.error_descriptions[errorNumber].detailMessage;
500
+ scorm2004_constants.error_descriptions[errorNumber].detailMessage;
444
501
  }
445
502
 
446
503
  return detail ? detailMessage : basicMessage;
@@ -495,17 +552,17 @@ class Scorm2004Impl extends BaseAPI {
495
552
  if (values.length === 2) {
496
553
  const matches = values[0].match(formatRegex);
497
554
  if (!matches) {
498
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
555
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
499
556
  } else {
500
557
  if (
501
558
  !response.format2 ||
502
559
  !values[1].match(new RegExp(response.format2))
503
560
  ) {
504
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
561
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
505
562
  }
506
563
  }
507
564
  } else {
508
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
565
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
509
566
  }
510
567
  } else {
511
568
  const matches = nodes[i].match(formatRegex);
@@ -513,17 +570,17 @@ class Scorm2004Impl extends BaseAPI {
513
570
  (!matches && value !== "") ||
514
571
  (!matches && interaction_type === "true-false")
515
572
  ) {
516
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
573
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
517
574
  } else {
518
575
  if (interaction_type === "numeric" && nodes.length > 1) {
519
576
  if (Number(nodes[0]) > Number(nodes[1])) {
520
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
577
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
521
578
  }
522
579
  } else {
523
580
  if (nodes[i] !== "" && response.unique) {
524
581
  for (let j = 0; j < i && this.lastErrorCode === "0"; j++) {
525
582
  if (nodes[i] === nodes[j]) {
526
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
583
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
527
584
  }
528
585
  }
529
586
  }
@@ -551,12 +608,12 @@ class Scorm2004Impl extends BaseAPI {
551
608
  while (matches) {
552
609
  switch (matches[2]) {
553
610
  case "lang":
554
- langMatches = node.match(Regex.scorm2004.CMILangcr);
611
+ langMatches = node.match(scorm2004_regex.CMILangcr);
555
612
  if (langMatches) {
556
613
  const lang = langMatches[3];
557
614
  if (lang !== undefined && lang.length > 0) {
558
615
  if (!ValidLanguages.includes(lang.toLowerCase())) {
559
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
616
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
560
617
  }
561
618
  }
562
619
  }
@@ -565,7 +622,7 @@ class Scorm2004Impl extends BaseAPI {
565
622
  case "case_matters":
566
623
  if (!seenLang && !seenOrder && !seenCase) {
567
624
  if (matches[3] !== "true" && matches[3] !== "false") {
568
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
625
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
569
626
  }
570
627
  }
571
628
 
@@ -574,7 +631,7 @@ class Scorm2004Impl extends BaseAPI {
574
631
  case "order_matters":
575
632
  if (!seenCase && !seenLang && !seenOrder) {
576
633
  if (matches[3] !== "true" && matches[3] !== "false") {
577
- this.throwSCORMError(ErrorCodes.scorm2004.TYPE_MISMATCH);
634
+ this.throwSCORMError(scorm2004_errors.TYPE_MISMATCH);
578
635
  }
579
636
  }
580
637
 
@@ -639,7 +696,7 @@ class Scorm2004Impl extends BaseAPI {
639
696
  const totalTimeDuration = this.cmi.getCurrentTotalTime();
640
697
  const totalTimeSeconds = Utilities.getDurationAsSeconds(
641
698
  totalTimeDuration,
642
- Regex.scorm2004.CMITimespan,
699
+ scorm2004_regex.CMITimespan,
643
700
  );
644
701
 
645
702
  let completionStatus = CompletionStatus.unknown;
@@ -747,11 +804,11 @@ class Scorm2004Impl extends BaseAPI {
747
804
  return result;
748
805
  } else {
749
806
  return {
750
- result: APIConstants.global.SCORM_TRUE,
807
+ result: global_constants.SCORM_TRUE,
751
808
  errorCode: 0,
752
809
  };
753
810
  }
754
811
  }
755
812
  }
756
813
 
757
- export { Scorm2004Impl };
814
+ export { Scorm2004Impl as Scorm2004API };
package/src/ScormAgain.ts CHANGED
@@ -1,9 +1,5 @@
1
- import { AICCImpl } from "./AICC";
2
- import { Scorm12Impl } from "./Scorm12API";
3
- import { Scorm2004Impl } from "./Scorm2004API";
4
-
5
- const Scorm12API = Scorm12Impl;
6
- const Scorm2004API = Scorm2004Impl;
7
- const AICC = AICCImpl;
1
+ import { AICC } from "./AICC";
2
+ import { Scorm12API } from "./Scorm12API";
3
+ import { Scorm2004API } from "./Scorm2004API";
8
4
 
9
5
  export { Scorm12API, Scorm2004API, AICC };
@@ -1,9 +1,9 @@
1
1
  import { BaseCMI } from "../common/base_cmi";
2
2
  import { CMIScore } from "../common/score";
3
- import APIConstants from "../../constants/api_constants";
4
- import Regex from "../../constants/regex";
5
- import ErrorCodes from "../../constants/error_codes";
6
- import { AICCValidationError } from "../../exceptions";
3
+ import { aicc_constants } from "../../constants/api_constants";
4
+ import { aicc_regex } from "../../constants/regex";
5
+ import { scorm12_errors } from "../../constants/error_codes";
6
+ import { AICCValidationError } from "../../exceptions/aicc_exceptions";
7
7
  import { checkAICCValidFormat } from "./validation";
8
8
  import { CMIArray } from "../common/array";
9
9
 
@@ -16,7 +16,7 @@ export class CMIAttemptRecords extends CMIArray {
16
16
  */
17
17
  constructor() {
18
18
  super({
19
- children: APIConstants.aicc.attempt_records_children,
19
+ children: aicc_constants.attempt_records_children,
20
20
  });
21
21
  }
22
22
  }
@@ -25,17 +25,19 @@ export class CMIAttemptRecords extends CMIArray {
25
25
  * Class for AICC Attempt Records
26
26
  */
27
27
  export class CMIAttemptRecordsObject extends BaseCMI {
28
+ private _lesson_status = "";
29
+
28
30
  /**
29
31
  * Constructor for AICC Attempt Records object
30
32
  */
31
33
  constructor() {
32
34
  super();
33
35
  this.score = new CMIScore({
34
- score_children: APIConstants.aicc.score_children,
35
- score_range: Regex.aicc.score_range,
36
- invalidErrorCode: ErrorCodes.scorm12.INVALID_SET_VALUE,
37
- invalidTypeCode: ErrorCodes.scorm12.TYPE_MISMATCH,
38
- invalidRangeCode: ErrorCodes.scorm12.VALUE_OUT_OF_RANGE,
36
+ score_children: aicc_constants.score_children,
37
+ score_range: aicc_regex.score_range,
38
+ invalidErrorCode: scorm12_errors.INVALID_SET_VALUE,
39
+ invalidTypeCode: scorm12_errors.TYPE_MISMATCH,
40
+ invalidRangeCode: scorm12_errors.VALUE_OUT_OF_RANGE,
39
41
  errorClass: AICCValidationError,
40
42
  });
41
43
  }
@@ -47,10 +49,18 @@ export class CMIAttemptRecordsObject extends BaseCMI {
47
49
  */
48
50
  override initialize() {
49
51
  super.initialize();
52
+
53
+ this._lesson_status = "";
50
54
  this.score?.initialize();
51
55
  }
52
56
 
53
- private _lesson_status = "";
57
+ /**
58
+ * Called when the API has been reset
59
+ */
60
+ reset(): void {
61
+ this._initialized = false;
62
+ this.score?.reset();
63
+ }
54
64
 
55
65
  /**
56
66
  * Getter for _lesson_status
@@ -65,7 +75,7 @@ export class CMIAttemptRecordsObject extends BaseCMI {
65
75
  * @param {string} lesson_status
66
76
  */
67
77
  set lesson_status(lesson_status: string) {
68
- if (checkAICCValidFormat(lesson_status, Regex.aicc.CMIStatus2)) {
78
+ if (checkAICCValidFormat(lesson_status, aicc_regex.CMIStatus2)) {
69
79
  this._lesson_status = lesson_status;
70
80
  }
71
81
  }
@@ -1,5 +1,5 @@
1
1
  import * as Scorm12CMI from "../scorm12/cmi";
2
- import APIConstants from "../../constants/api_constants";
2
+ import { aicc_constants } from "../../constants/api_constants";
3
3
  import { CMIEvaluation } from "./evaluation";
4
4
  import { AICCStudentPreferences } from "./student_preferences";
5
5
  import { CMIStudentDemographics } from "./student_demographics";
@@ -20,7 +20,7 @@ export class CMI extends Scorm12CMI.CMI {
20
20
  * @param {boolean} initialized
21
21
  */
22
22
  constructor(initialized: boolean = false) {
23
- super(APIConstants.aicc.cmi_children);
23
+ super(aicc_constants.cmi_children);
24
24
  if (initialized) this.initialize();
25
25
  this.student_preference = new AICCStudentPreferences();
26
26
  this.student_data = new AICCCMIStudentData();
@@ -1,9 +1,9 @@
1
1
  import { BaseCMI } from "../common/base_cmi";
2
2
  import { CMIScore } from "../common/score";
3
- import APIConstants from "../../constants/api_constants";
4
- import Regex from "../../constants/regex";
5
- import ErrorCodes from "../../constants/error_codes";
6
- import { Scorm12ValidationError } from "../../exceptions";
3
+ import { scorm12_constants } from "../../constants/api_constants";
4
+ import { scorm12_regex } from "../../constants/regex";
5
+ import { scorm12_errors } from "../../constants/error_codes";
6
+ import { Scorm12ValidationError } from "../../exceptions/scorm12_exceptions";
7
7
  import { check12ValidFormat } from "../scorm12/validation";
8
8
  import * as Util from "../../utilities";
9
9
 
@@ -18,11 +18,11 @@ export class CMICore extends BaseCMI {
18
18
  constructor() {
19
19
  super();
20
20
  this.score = new CMIScore({
21
- score_children: APIConstants.scorm12.score_children,
22
- score_range: Regex.scorm12.score_range,
23
- invalidErrorCode: ErrorCodes.scorm12.INVALID_SET_VALUE,
24
- invalidTypeCode: ErrorCodes.scorm12.TYPE_MISMATCH,
25
- invalidRangeCode: ErrorCodes.scorm12.VALUE_OUT_OF_RANGE,
21
+ score_children: scorm12_constants.score_children,
22
+ score_range: scorm12_regex.score_range,
23
+ invalidErrorCode: scorm12_errors.INVALID_SET_VALUE,
24
+ invalidTypeCode: scorm12_errors.TYPE_MISMATCH,
25
+ invalidRangeCode: scorm12_errors.VALUE_OUT_OF_RANGE,
26
26
  errorClass: Scorm12ValidationError,
27
27
  });
28
28
  }
@@ -37,7 +37,7 @@ export class CMICore extends BaseCMI {
37
37
  this.score?.initialize();
38
38
  }
39
39
 
40
- private __children = APIConstants.scorm12.core_children;
40
+ private __children = scorm12_constants.core_children;
41
41
  private _student_id = "";
42
42
  private _student_name = "";
43
43
  private _lesson_location = "";
@@ -50,6 +50,24 @@ export class CMICore extends BaseCMI {
50
50
  private _session_time = "00:00:00";
51
51
  private _suspend_data = "";
52
52
 
53
+ /**
54
+ * Called when the API has been reset
55
+ */
56
+ reset(): void {
57
+ this._initialized = false;
58
+
59
+ this._exit = "";
60
+ this._entry = "";
61
+
62
+ /**
63
+ * Resetting ensures we accurately track the time spent on each individual SCO session independently. Each new
64
+ * session should start from zero, so we can reset cmi.core.session_time at the beginning of each session.
65
+ */
66
+ this._session_time = "00:00:00";
67
+
68
+ this.score?.reset();
69
+ }
70
+
53
71
  /**
54
72
  * Getter for __children
55
73
  * @return {string}
@@ -65,7 +83,7 @@ export class CMICore extends BaseCMI {
65
83
  * @private
66
84
  */
67
85
  set _children(_children: string) {
68
- throw new Scorm12ValidationError(ErrorCodes.scorm12.INVALID_SET_VALUE);
86
+ throw new Scorm12ValidationError(scorm12_errors.INVALID_SET_VALUE);
69
87
  }
70
88
 
71
89
  /**
@@ -82,7 +100,7 @@ export class CMICore extends BaseCMI {
82
100
  */
83
101
  set student_id(student_id: string) {
84
102
  if (this.initialized) {
85
- throw new Scorm12ValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
103
+ throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
86
104
  } else {
87
105
  this._student_id = student_id;
88
106
  }
@@ -102,7 +120,7 @@ export class CMICore extends BaseCMI {
102
120
  */
103
121
  set student_name(student_name: string) {
104
122
  if (this.initialized) {
105
- throw new Scorm12ValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
123
+ throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
106
124
  } else {
107
125
  this._student_name = student_name;
108
126
  }
@@ -121,7 +139,7 @@ export class CMICore extends BaseCMI {
121
139
  * @param {string} lesson_location
122
140
  */
123
141
  set lesson_location(lesson_location: string) {
124
- if (check12ValidFormat(lesson_location, Regex.scorm12.CMIString256, true)) {
142
+ if (check12ValidFormat(lesson_location, scorm12_regex.CMIString256, true)) {
125
143
  this._lesson_location = lesson_location;
126
144
  }
127
145
  }
@@ -140,7 +158,7 @@ export class CMICore extends BaseCMI {
140
158
  */
141
159
  set credit(credit: string) {
142
160
  if (this.initialized) {
143
- throw new Scorm12ValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
161
+ throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
144
162
  } else {
145
163
  this._credit = credit;
146
164
  }
@@ -160,11 +178,11 @@ export class CMICore extends BaseCMI {
160
178
  */
161
179
  set lesson_status(lesson_status: string) {
162
180
  if (this.initialized) {
163
- if (check12ValidFormat(lesson_status, Regex.scorm12.CMIStatus)) {
181
+ if (check12ValidFormat(lesson_status, scorm12_regex.CMIStatus)) {
164
182
  this._lesson_status = lesson_status;
165
183
  }
166
184
  } else {
167
- if (check12ValidFormat(lesson_status, Regex.scorm12.CMIStatus2)) {
185
+ if (check12ValidFormat(lesson_status, scorm12_regex.CMIStatus2)) {
168
186
  this._lesson_status = lesson_status;
169
187
  }
170
188
  }
@@ -184,7 +202,7 @@ export class CMICore extends BaseCMI {
184
202
  */
185
203
  set entry(entry: string) {
186
204
  if (this.initialized) {
187
- throw new Scorm12ValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
205
+ throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
188
206
  } else {
189
207
  this._entry = entry;
190
208
  }
@@ -204,7 +222,7 @@ export class CMICore extends BaseCMI {
204
222
  */
205
223
  set total_time(total_time: string) {
206
224
  if (this.initialized) {
207
- throw new Scorm12ValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
225
+ throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
208
226
  } else {
209
227
  this._total_time = total_time;
210
228
  }
@@ -224,7 +242,7 @@ export class CMICore extends BaseCMI {
224
242
  */
225
243
  set lesson_mode(lesson_mode: string) {
226
244
  if (this.initialized) {
227
- throw new Scorm12ValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
245
+ throw new Scorm12ValidationError(scorm12_errors.READ_ONLY_ELEMENT);
228
246
  } else {
229
247
  this._lesson_mode = lesson_mode;
230
248
  }
@@ -236,7 +254,7 @@ export class CMICore extends BaseCMI {
236
254
  */
237
255
  get exit(): string {
238
256
  if (!this.jsonString) {
239
- throw new Scorm12ValidationError(ErrorCodes.scorm12.WRITE_ONLY_ELEMENT);
257
+ throw new Scorm12ValidationError(scorm12_errors.WRITE_ONLY_ELEMENT);
240
258
  }
241
259
  return this._exit;
242
260
  }
@@ -246,7 +264,7 @@ export class CMICore extends BaseCMI {
246
264
  * @param {string} exit
247
265
  */
248
266
  set exit(exit: string) {
249
- if (check12ValidFormat(exit, Regex.scorm12.CMIExit, true)) {
267
+ if (check12ValidFormat(exit, scorm12_regex.CMIExit, true)) {
250
268
  this._exit = exit;
251
269
  }
252
270
  }
@@ -257,7 +275,7 @@ export class CMICore extends BaseCMI {
257
275
  */
258
276
  get session_time(): string {
259
277
  if (!this.jsonString) {
260
- throw new Scorm12ValidationError(ErrorCodes.scorm12.WRITE_ONLY_ELEMENT);
278
+ throw new Scorm12ValidationError(scorm12_errors.WRITE_ONLY_ELEMENT);
261
279
  }
262
280
  return this._session_time;
263
281
  }
@@ -267,7 +285,7 @@ export class CMICore extends BaseCMI {
267
285
  * @param {string} session_time
268
286
  */
269
287
  set session_time(session_time: string) {
270
- if (check12ValidFormat(session_time, Regex.scorm12.CMITimespan)) {
288
+ if (check12ValidFormat(session_time, scorm12_regex.CMITimespan)) {
271
289
  this._session_time = session_time;
272
290
  }
273
291
  }
@@ -285,7 +303,7 @@ export class CMICore extends BaseCMI {
285
303
  * @param {string} suspend_data
286
304
  */
287
305
  set suspend_data(suspend_data: string) {
288
- if (check12ValidFormat(suspend_data, Regex.scorm12.CMIString4096, true)) {
306
+ if (check12ValidFormat(suspend_data, scorm12_regex.CMIString4096, true)) {
289
307
  this._suspend_data = suspend_data;
290
308
  }
291
309
  }
@@ -307,7 +325,7 @@ export class CMICore extends BaseCMI {
307
325
  return Util.addHHMMSSTimeStrings(
308
326
  this._total_time,
309
327
  sessionTime,
310
- new RegExp(Regex.scorm12.CMITimespan),
328
+ new RegExp(scorm12_regex.CMITimespan),
311
329
  );
312
330
  }
313
331