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
package/dist_test.html ADDED
@@ -0,0 +1,208 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>SCORM-Again Distribution Test</title>
7
+ <style>
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ margin: 20px;
11
+ }
12
+
13
+ h1 {
14
+ color: #333;
15
+ }
16
+
17
+ .test-container {
18
+ display: flex;
19
+ flex-wrap: wrap;
20
+ gap: 20px;
21
+ }
22
+
23
+ .test-frame {
24
+ border: 1px solid #ccc;
25
+ padding: 15px;
26
+ width: 300px;
27
+ margin-bottom: 20px;
28
+ border-radius: 5px;
29
+ }
30
+
31
+ .test-frame h3 {
32
+ margin-top: 0;
33
+ border-bottom: 1px solid #eee;
34
+ padding-bottom: 10px;
35
+ }
36
+
37
+ .success {
38
+ background-color: #d4edda;
39
+ color: #155724;
40
+ padding: 10px;
41
+ border-radius: 4px;
42
+ margin-top: 10px;
43
+ }
44
+
45
+ .error {
46
+ background-color: #f8d7da;
47
+ color: #721c24;
48
+ padding: 10px;
49
+ border-radius: 4px;
50
+ margin-top: 10px;
51
+ }
52
+
53
+ .section {
54
+ margin-bottom: 30px;
55
+ }
56
+ </style>
57
+ </head>
58
+ <body>
59
+ <h1>SCORM-Again Distribution Test</h1>
60
+
61
+ <div class="section">
62
+ <h2>Regular JavaScript Files</h2>
63
+ <div class="test-container" id="regular-container"></div>
64
+ </div>
65
+
66
+ <div class="section">
67
+ <h2>ESM Module Files</h2>
68
+ <div class="test-container" id="esm-container"></div>
69
+ </div>
70
+
71
+ <script>
72
+ const dists = [
73
+ {
74
+ file: 'aicc.js',
75
+ api: ['AICC']
76
+ },
77
+ {
78
+ file: 'aicc.min.js',
79
+ api: ['AICC']
80
+ },
81
+ {
82
+ file: 'scorm12.js',
83
+ api: ['Scorm12API']
84
+ },
85
+ {
86
+ file: 'scorm12.min.js',
87
+ api: ['Scorm12API']
88
+ },
89
+ {
90
+ file: 'scorm2004.js',
91
+ api: ['Scorm2004API']
92
+ },
93
+ {
94
+ file: 'scorm2004.min.js',
95
+ api: ['Scorm2004API']
96
+ },
97
+ {
98
+ file: 'scorm-again.js',
99
+ api: ['Scorm12API', 'Scorm2004API', 'AICC']
100
+ },
101
+ {
102
+ file: 'scorm-again.min.js',
103
+ api: ['Scorm12API', 'Scorm2004API', 'AICC']
104
+ }
105
+ ];
106
+
107
+ // Create test frames for regular JS files
108
+ const regularContainer = document.getElementById('regular-container');
109
+ dists.forEach(dist => {
110
+ const frame = document.createElement('div');
111
+ frame.className = 'test-frame';
112
+ frame.innerHTML = `
113
+ <h3>${dist.file}</h3>
114
+ <div id="dist-${dist.file.replace(/\//g, '-').replace(/\./g, '-')}-result"></div>
115
+ `;
116
+ regularContainer.appendChild(frame);
117
+
118
+ // Create iframe to load the script
119
+ const iframe = document.createElement('iframe');
120
+ iframe.style.display = 'none';
121
+ document.body.appendChild(iframe);
122
+
123
+ // Create HTML content for the iframe with script
124
+ const html = `
125
+ <!DOCTYPE html>
126
+ <html>
127
+ <head>
128
+ <script src="dist/${dist.file}"><\/script>
129
+ <script>
130
+ try {
131
+ window.parent.postMessage({
132
+ file: "dist-${dist.file}",
133
+ success: !!(${dist.api.map(api => `window.${api}`).join(' || ')})
134
+ }, "*");
135
+ } catch (error) {
136
+ window.parent.postMessage({
137
+ file: "dist-${dist.file}",
138
+ success: false,
139
+ error: error.message
140
+ }, "*");
141
+ }
142
+ <\/script>
143
+ </head>
144
+ <body></body>
145
+ </html>
146
+ `;
147
+
148
+ iframe.srcdoc = html;
149
+ });
150
+
151
+ // Create test frames for ESM module files
152
+ const esmContainer = document.getElementById('esm-container');
153
+ dists.forEach(dist => {
154
+ const frame = document.createElement('div');
155
+ frame.className = 'test-frame';
156
+ frame.innerHTML = `
157
+ <h3>${dist.file}</h3>
158
+ <div id="dist-esm-${dist.file.replace(/\//g, '-').replace(/\./g, '-')}-result"></div>
159
+ `;
160
+ esmContainer.appendChild(frame);
161
+
162
+ // Create iframe to load the module
163
+ const iframe = document.createElement('iframe');
164
+ iframe.style.display = 'none';
165
+ document.body.appendChild(iframe);
166
+
167
+ // Create HTML content for the iframe with module import
168
+ const html = `
169
+ <!DOCTYPE html>
170
+ <html>
171
+ <head>
172
+ <script type="module">
173
+ try {
174
+ const module = await import('/dist/esm/${dist.file}');
175
+ window.parent.postMessage({
176
+ file: "dist-esm-${dist.file}",
177
+ success: !!(${dist.api.map(api => `module.${api}`).join(' || ')})
178
+ }, "*");
179
+ } catch (error) {
180
+ window.parent.postMessage({
181
+ file: "dist-esm-${dist.file}",
182
+ success: false,
183
+ error: error.message
184
+ }, "*");
185
+ }
186
+ <\/script>
187
+ </head>
188
+ <body></body>
189
+ </html>
190
+ `;
191
+
192
+ iframe.srcdoc = html;
193
+ });
194
+
195
+ // Listen for messages from iframes
196
+ window.addEventListener('message', (event) => {
197
+ const {file, success, error} = event.data;
198
+ const resultElement = document.getElementById(`${file.replace(/\//g, '-').replace(/\./g, '-')}-result`);
199
+
200
+ if (success) {
201
+ resultElement.innerHTML = `<div class="success">Successfully loaded</div>`;
202
+ } else {
203
+ resultElement.innerHTML = `<div class="error">Failed to load: ${error || 'Library objects not found'}</div>`;
204
+ }
205
+ });
206
+ </script>
207
+ </body>
208
+ </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scorm-again",
3
- "version": "2.5.0",
3
+ "version": "2.6.1",
4
4
  "description": "A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004",
5
5
  "main": "dist/scorm-again.js",
6
6
  "types": "index.d.ts",
@@ -22,47 +22,47 @@
22
22
  "test": "test"
23
23
  },
24
24
  "devDependencies": {
25
- "@babel/cli": "^7.25.9",
25
+ "@babel/cli": "^7.26.4",
26
26
  "@babel/core": "^7.26.0",
27
27
  "@babel/eslint-parser": "^7.25.9",
28
28
  "@babel/node": "^7.26.0",
29
29
  "@babel/preset-env": "^7.26.0",
30
30
  "@babel/preset-typescript": "^7.26.0",
31
- "@eslint/eslintrc": "^3.1.0",
32
- "@eslint/js": "^9.13.0",
31
+ "@eslint/eslintrc": "^3.2.0",
32
+ "@eslint/js": "^9.16.0",
33
33
  "@istanbuljs/nyc-config-typescript": "^1.0.2",
34
34
  "@types/eslint__js": "^8.42.3",
35
- "@types/mocha": "^10.0.9",
35
+ "@types/mocha": "^10.0.10",
36
36
  "@types/sinon": "^17.0.3",
37
37
  "babel-eslint": "^11.0.0-beta.2",
38
38
  "babel-loader": "^9.2.1",
39
39
  "babelify": "^10.0.0",
40
40
  "browserify": "^17.0.1",
41
- "c8": "^10.1.2",
41
+ "c8": "^10.1.3",
42
42
  "c8-as-nyc": "^1.1.11",
43
- "eslint": "^9.13.0",
43
+ "eslint": "^9.16.0",
44
44
  "eslint-formatter-junit": "^8.40.0",
45
45
  "eslint-plugin-import": "^2.31.0",
46
- "eslint-plugin-jsdoc": "^50.4.3",
46
+ "eslint-plugin-jsdoc": "^50.6.1",
47
47
  "eslint-webpack-plugin": "^4.2.0",
48
48
  "expect": "^29.7.0",
49
49
  "fetch-pretender": "https://github.com/jcputney/fetch-pretender#master",
50
- "globals": "^15.11.0",
50
+ "globals": "^15.13.0",
51
51
  "jsdoc": "^4.0.4",
52
52
  "jsdoc-babel": "^0.5.0",
53
53
  "minimist": "^1.2.8",
54
54
  "miragejs": "^0.2.0-alpha.3",
55
- "mocha": "^10.8.2",
55
+ "mocha": "^11.0.1",
56
56
  "mocha-junit-reporter": "^2.2.1",
57
57
  "mochawesome": "^7.1.3",
58
- "prettier": "^3.3.3",
58
+ "prettier": "^3.4.2",
59
59
  "sinon": "^19.0.2",
60
60
  "terser-webpack-plugin": "^5.3.10",
61
61
  "ts-loader": "^9.5.1",
62
62
  "tsx": "^4.19.2",
63
- "typescript": "^5.6.3",
64
- "typescript-eslint": "^8.12.2",
65
- "webpack": "^5.91.0",
63
+ "typescript": "^5.7.2",
64
+ "typescript-eslint": "^8.18.0",
65
+ "webpack": "^5.97.1",
66
66
  "webpack-cli": "^5.1.4"
67
67
  },
68
68
  "scripts": {
package/src/AICC.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Scorm12Impl } from "./Scorm12API";
1
+ import { Scorm12API } from "./Scorm12API";
2
2
  import { CMI } from "./cmi/aicc/cmi";
3
3
 
4
4
  import { BaseCMI } from "./cmi/common/base_cmi";
@@ -13,7 +13,7 @@ import { stringMatches } from "./utilities";
13
13
  /**
14
14
  * The AICC API class
15
15
  */
16
- class AICCImpl extends Scorm12Impl {
16
+ class AICCImpl extends Scorm12API {
17
17
  /**
18
18
  * Constructor to create AICC API object
19
19
  * @param {Settings} settings
@@ -25,6 +25,9 @@ class AICCImpl extends Scorm12Impl {
25
25
  this.nav = new NAV();
26
26
  }
27
27
 
28
+ override cmi: CMI;
29
+ override nav: NAV;
30
+
28
31
  /**
29
32
  * Gets or builds a new child element to add to the array.
30
33
  *
@@ -71,4 +74,4 @@ class AICCImpl extends Scorm12Impl {
71
74
  }
72
75
  }
73
76
 
74
- export { AICCImpl };
77
+ export { AICCImpl as AICC };
package/src/BaseAPI.ts CHANGED
@@ -1,16 +1,10 @@
1
1
  import { CMIArray } from "./cmi/common/array";
2
2
  import { ValidationError } from "./exceptions";
3
- import ErrorCodes, { ErrorCode } from "./constants/error_codes";
4
- import APIConstants from "./constants/api_constants";
3
+ import { ErrorCode } from "./constants/error_codes";
4
+ import { global_constants } from "./constants/api_constants";
5
5
  import { formatMessage, stringMatches, unflatten } from "./utilities";
6
6
  import { BaseCMI } from "./cmi/common/base_cmi";
7
- import {
8
- CommitObject,
9
- LogLevel,
10
- RefObject,
11
- ResultObject,
12
- Settings,
13
- } from "./types/api_types";
7
+ import { CommitObject, LogLevel, RefObject, ResultObject, Settings } from "./types/api_types";
14
8
  import { DefaultSettings } from "./constants/default_settings";
15
9
  import { IBaseAPI } from "./interfaces/IBaseAPI";
16
10
  import { ScheduledCommit } from "./helpers/scheduled_commit";
@@ -35,7 +29,7 @@ export default abstract class BaseAPI implements IBaseAPI {
35
29
  if (new.target === BaseAPI) {
36
30
  throw new TypeError("Cannot construct BaseAPI instances directly");
37
31
  }
38
- this.currentState = APIConstants.global.STATE_NOT_INITIALIZED;
32
+ this.currentState = global_constants.STATE_NOT_INITIALIZED;
39
33
  this.lastErrorCode = "0";
40
34
  this.listenerArray = [];
41
35
 
@@ -69,11 +63,15 @@ export default abstract class BaseAPI implements IBaseAPI {
69
63
  * @protected
70
64
  */
71
65
  commonReset(settings?: Settings): void {
66
+ this.apiLog("reset", "Called", LogLevelEnum.INFO);
67
+
72
68
  this.settings = { ...this.settings, ...settings };
73
69
 
74
- this.currentState = APIConstants.global.STATE_NOT_INITIALIZED;
70
+ this.clearScheduledCommit();
71
+ this.currentState = global_constants.STATE_NOT_INITIALIZED;
75
72
  this.lastErrorCode = "0";
76
73
  this.listenerArray = [];
74
+ this.startingData = undefined;
77
75
  }
78
76
 
79
77
  /**
@@ -88,7 +86,7 @@ export default abstract class BaseAPI implements IBaseAPI {
88
86
  initializeMessage?: string,
89
87
  terminationMessage?: string,
90
88
  ): string {
91
- let returnValue = APIConstants.global.SCORM_FALSE;
89
+ let returnValue = global_constants.SCORM_FALSE;
92
90
 
93
91
  if (this.isInitialized()) {
94
92
  this.throwSCORMError(this._error_codes.INITIALIZED, initializeMessage);
@@ -99,9 +97,9 @@ export default abstract class BaseAPI implements IBaseAPI {
99
97
  this.cmi.setStartTime();
100
98
  }
101
99
 
102
- this.currentState = APIConstants.global.STATE_INITIALIZED;
100
+ this.currentState = global_constants.STATE_INITIALIZED;
103
101
  this.lastErrorCode = "0";
104
- returnValue = APIConstants.global.SCORM_TRUE;
102
+ returnValue = global_constants.SCORM_TRUE;
105
103
  this.processListeners(callbackName);
106
104
  }
107
105
 
@@ -233,7 +231,7 @@ export default abstract class BaseAPI implements IBaseAPI {
233
231
  callbackName: string,
234
232
  checkTerminated: boolean,
235
233
  ): Promise<string> {
236
- let returnValue = APIConstants.global.SCORM_FALSE;
234
+ let returnValue = global_constants.SCORM_FALSE;
237
235
 
238
236
  if (
239
237
  this.checkState(
@@ -242,7 +240,7 @@ export default abstract class BaseAPI implements IBaseAPI {
242
240
  this._error_codes.MULTIPLE_TERMINATION,
243
241
  )
244
242
  ) {
245
- this.currentState = APIConstants.global.STATE_TERMINATED;
243
+ this.currentState = global_constants.STATE_TERMINATED;
246
244
 
247
245
  const result: ResultObject = await this.storeData(true);
248
246
  if (typeof result.errorCode !== "undefined" && result.errorCode > 0) {
@@ -251,11 +249,11 @@ export default abstract class BaseAPI implements IBaseAPI {
251
249
  returnValue =
252
250
  typeof result !== "undefined" && result.result
253
251
  ? result.result
254
- : APIConstants.global.SCORM_FALSE;
252
+ : global_constants.SCORM_FALSE;
255
253
 
256
254
  if (checkTerminated) this.lastErrorCode = "0";
257
255
 
258
- returnValue = APIConstants.global.SCORM_TRUE;
256
+ returnValue = global_constants.SCORM_TRUE;
259
257
  this.processListeners(callbackName);
260
258
  }
261
259
 
@@ -332,7 +330,7 @@ export default abstract class BaseAPI implements IBaseAPI {
332
330
  if (value !== undefined) {
333
331
  value = String(value);
334
332
  }
335
- let returnValue: string = APIConstants.global.SCORM_FALSE;
333
+ let returnValue: string = global_constants.SCORM_FALSE;
336
334
 
337
335
  if (
338
336
  this.checkState(
@@ -351,7 +349,7 @@ export default abstract class BaseAPI implements IBaseAPI {
351
349
  }
352
350
 
353
351
  if (returnValue === undefined) {
354
- returnValue = APIConstants.global.SCORM_FALSE;
352
+ returnValue = global_constants.SCORM_FALSE;
355
353
  }
356
354
 
357
355
  // If we didn't have any errors while setting the data, go ahead and
@@ -388,7 +386,7 @@ export default abstract class BaseAPI implements IBaseAPI {
388
386
  ): Promise<string> {
389
387
  this.clearScheduledCommit();
390
388
 
391
- let returnValue = APIConstants.global.SCORM_FALSE;
389
+ let returnValue = global_constants.SCORM_FALSE;
392
390
 
393
391
  if (
394
392
  this.checkState(
@@ -404,7 +402,7 @@ export default abstract class BaseAPI implements IBaseAPI {
404
402
  returnValue =
405
403
  typeof result !== "undefined" && result.result
406
404
  ? result.result
407
- : APIConstants.global.SCORM_FALSE;
405
+ : global_constants.SCORM_FALSE;
408
406
 
409
407
  this.apiLog(
410
408
  callbackName,
@@ -562,12 +560,12 @@ export default abstract class BaseAPI implements IBaseAPI {
562
560
  value: any,
563
561
  ): string {
564
562
  if (!CMIElement || CMIElement === "") {
565
- return APIConstants.global.SCORM_FALSE;
563
+ return global_constants.SCORM_FALSE;
566
564
  }
567
565
 
568
566
  const structure = CMIElement.split(".");
569
567
  let refObject: RefObject = this;
570
- let returnValue = APIConstants.global.SCORM_FALSE;
568
+ let returnValue = global_constants.SCORM_FALSE;
571
569
  let foundFirstIndex = false;
572
570
 
573
571
  const invalidErrorMessage = `The data model element passed to ${methodName} (${CMIElement}) is not a valid SCORM data model element.`;
@@ -600,7 +598,7 @@ export default abstract class BaseAPI implements IBaseAPI {
600
598
 
601
599
  if (!scorm2004 || this.lastErrorCode === "0") {
602
600
  refObject[attribute] = value;
603
- returnValue = APIConstants.global.SCORM_TRUE;
601
+ returnValue = global_constants.SCORM_TRUE;
604
602
  }
605
603
  }
606
604
  } else {
@@ -645,7 +643,7 @@ export default abstract class BaseAPI implements IBaseAPI {
645
643
  }
646
644
  }
647
645
 
648
- if (returnValue === APIConstants.global.SCORM_FALSE) {
646
+ if (returnValue === global_constants.SCORM_FALSE) {
649
647
  this.apiLog(
650
648
  methodName,
651
649
  `There was an error setting the value for: ${CMIElement}, value of: ${value}`,
@@ -741,9 +739,9 @@ export default abstract class BaseAPI implements IBaseAPI {
741
739
  if (refObject === null || refObject === undefined) {
742
740
  if (!scorm2004) {
743
741
  if (attribute === "_children") {
744
- this.throwSCORMError(ErrorCodes.scorm12.CHILDREN_ERROR);
742
+ this.throwSCORMError(this._error_codes.CHILDREN_ERROR);
745
743
  } else if (attribute === "_count") {
746
- this.throwSCORMError(ErrorCodes.scorm12.COUNT_ERROR);
744
+ this.throwSCORMError(this._error_codes.COUNT_ERROR);
747
745
  }
748
746
  }
749
747
  } else {
@@ -757,7 +755,7 @@ export default abstract class BaseAPI implements IBaseAPI {
757
755
  * @return {boolean}
758
756
  */
759
757
  isInitialized(): boolean {
760
- return this.currentState === APIConstants.global.STATE_INITIALIZED;
758
+ return this.currentState === global_constants.STATE_INITIALIZED;
761
759
  }
762
760
 
763
761
  /**
@@ -766,7 +764,7 @@ export default abstract class BaseAPI implements IBaseAPI {
766
764
  * @return {boolean}
767
765
  */
768
766
  isNotInitialized(): boolean {
769
- return this.currentState === APIConstants.global.STATE_NOT_INITIALIZED;
767
+ return this.currentState === global_constants.STATE_NOT_INITIALIZED;
770
768
  }
771
769
 
772
770
  /**
@@ -775,7 +773,7 @@ export default abstract class BaseAPI implements IBaseAPI {
775
773
  * @return {boolean}
776
774
  */
777
775
  isTerminated(): boolean {
778
- return this.currentState === APIConstants.global.STATE_TERMINATED;
776
+ return this.currentState === global_constants.STATE_TERMINATED;
779
777
  }
780
778
 
781
779
  /**
@@ -943,7 +941,7 @@ export default abstract class BaseAPI implements IBaseAPI {
943
941
  * @param {string} success
944
942
  */
945
943
  clearSCORMError(success: string) {
946
- if (success !== undefined && success !== APIConstants.global.SCORM_FALSE) {
944
+ if (success !== undefined && success !== global_constants.SCORM_FALSE) {
947
945
  this.lastErrorCode = "0";
948
946
  }
949
947
  }
@@ -1044,6 +1042,15 @@ export default abstract class BaseAPI implements IBaseAPI {
1044
1042
  * @param {string} CMIElement
1045
1043
  */
1046
1044
  loadFromJSON(json: RefObject, CMIElement: string = "") {
1045
+ if (
1046
+ (!CMIElement || CMIElement === "") &&
1047
+ !Object.hasOwnProperty.call(json, "cmi") &&
1048
+ !Object.hasOwnProperty.call(json, "adl")
1049
+ ) {
1050
+ // providing a backward compatibility for the old v1 API
1051
+ CMIElement = "cmi";
1052
+ }
1053
+
1047
1054
  if (!this.isNotInitialized()) {
1048
1055
  console.error(
1049
1056
  "loadFromJSON can only be called before the call to lmsInitialize.",
@@ -1113,7 +1120,7 @@ export default abstract class BaseAPI implements IBaseAPI {
1113
1120
  ): Promise<ResultObject> {
1114
1121
  const api = this;
1115
1122
  const genericError: ResultObject = {
1116
- result: APIConstants.global.SCORM_FALSE,
1123
+ result: global_constants.SCORM_FALSE,
1117
1124
  errorCode: this.error_codes.GENERAL,
1118
1125
  };
1119
1126
 
@@ -1124,7 +1131,7 @@ export default abstract class BaseAPI implements IBaseAPI {
1124
1131
  await this.transformResponse(response);
1125
1132
  });
1126
1133
  return {
1127
- result: APIConstants.global.SCORM_TRUE,
1134
+ result: global_constants.SCORM_TRUE,
1128
1135
  errorCode: 0,
1129
1136
  };
1130
1137
  }
@@ -1204,7 +1211,7 @@ export default abstract class BaseAPI implements IBaseAPI {
1204
1211
  private handleValueAccessException(e: any, returnValue: string): string {
1205
1212
  if (e instanceof ValidationError) {
1206
1213
  this.lastErrorCode = String(e.errorCode);
1207
- returnValue = APIConstants.global.SCORM_FALSE;
1214
+ returnValue = global_constants.SCORM_FALSE;
1208
1215
  } else {
1209
1216
  if (e instanceof Error && e.message) {
1210
1217
  console.error(e.message);
@@ -1279,8 +1286,7 @@ export default abstract class BaseAPI implements IBaseAPI {
1279
1286
  if (
1280
1287
  response.status >= 200 &&
1281
1288
  response.status <= 299 &&
1282
- (result.result === true ||
1283
- result.result === APIConstants.global.SCORM_TRUE)
1289
+ (result.result === true || result.result === global_constants.SCORM_TRUE)
1284
1290
  ) {
1285
1291
  this.processListeners("CommitSuccess");
1286
1292
  } else {
package/src/Scorm12API.ts CHANGED
@@ -1,27 +1,21 @@
1
1
  import { CMI } from "./cmi/scorm12/cmi";
2
2
  import * as Utilities from "./utilities";
3
3
  import { stringMatches } from "./utilities";
4
- import APIConstants from "./constants/api_constants";
5
- import ErrorCodes from "./constants/error_codes";
4
+ import { global_constants, scorm12_constants } from "./constants/api_constants";
5
+ import { scorm12_errors } from "./constants/error_codes";
6
6
 
7
7
  import { BaseCMI } from "./cmi/common/base_cmi";
8
8
  import { CMIObjectivesObject } from "./cmi/scorm12/objectives";
9
9
  import {
10
10
  CMIInteractionsCorrectResponsesObject,
11
11
  CMIInteractionsObject,
12
- CMIInteractionsObjectivesObject,
12
+ CMIInteractionsObjectivesObject
13
13
  } from "./cmi/scorm12/interactions";
14
14
  import { NAV } from "./cmi/scorm12/nav";
15
- import {
16
- CommitObject,
17
- RefObject,
18
- ResultObject,
19
- ScoreObject,
20
- Settings,
21
- } from "./types/api_types";
22
- import Regex from "./constants/regex";
15
+ import { CommitObject, RefObject, ResultObject, ScoreObject, Settings } from "./types/api_types";
23
16
  import { CompletionStatus, SuccessStatus } from "./constants/enums";
24
17
  import BaseAPI from "./BaseAPI";
18
+ import { scorm12_regex } from "./constants/regex";
25
19
 
26
20
  /**
27
21
  * API class for SCORM 1.2
@@ -38,7 +32,7 @@ class Scorm12Impl extends BaseAPI {
38
32
  }
39
33
  }
40
34
 
41
- super(ErrorCodes.scorm12, settings);
35
+ super(scorm12_errors, settings);
42
36
 
43
37
  this.cmi = new CMI();
44
38
  this.nav = new NAV();
@@ -74,8 +68,8 @@ class Scorm12Impl extends BaseAPI {
74
68
  reset(settings?: Settings) {
75
69
  this.commonReset(settings);
76
70
 
77
- this.cmi = new CMI();
78
- this.nav = new NAV();
71
+ this.cmi?.reset();
72
+ this.nav?.reset();
79
73
  }
80
74
 
81
75
  /**
@@ -106,13 +100,13 @@ class Scorm12Impl extends BaseAPI {
106
100
  (async () => {
107
101
  await this.internalFinish();
108
102
  })();
109
- return APIConstants.global.SCORM_TRUE;
103
+ return global_constants.SCORM_TRUE;
110
104
  }
111
105
 
112
106
  async internalFinish(): Promise<string> {
113
107
  const result = await this.terminate("LMSFinish", true);
114
108
 
115
- if (result === APIConstants.global.SCORM_TRUE) {
109
+ if (result === global_constants.SCORM_TRUE) {
116
110
  if (this.nav.event !== "") {
117
111
  if (this.nav.event === "continue") {
118
112
  this.processListeners("SequenceNext");
@@ -164,7 +158,7 @@ class Scorm12Impl extends BaseAPI {
164
158
  await this.commit("LMSCommit", false);
165
159
  })();
166
160
  }
167
- return APIConstants.global.SCORM_TRUE;
161
+ return global_constants.SCORM_TRUE;
168
162
  }
169
163
 
170
164
  /**
@@ -281,11 +275,11 @@ class Scorm12Impl extends BaseAPI {
281
275
 
282
276
  // Set error number to string since inconsistent from modules if string or number
283
277
  errorNumber = String(errorNumber);
284
- if (APIConstants.scorm12.error_descriptions[errorNumber]) {
278
+ if (scorm12_constants.error_descriptions[errorNumber]) {
285
279
  basicMessage =
286
- APIConstants.scorm12.error_descriptions[errorNumber].basicMessage;
280
+ scorm12_constants.error_descriptions[errorNumber].basicMessage;
287
281
  detailMessage =
288
- APIConstants.scorm12.error_descriptions[errorNumber].detailMessage;
282
+ scorm12_constants.error_descriptions[errorNumber].detailMessage;
289
283
  }
290
284
 
291
285
  return detail ? detailMessage : basicMessage;
@@ -342,7 +336,7 @@ class Scorm12Impl extends BaseAPI {
342
336
  const totalTimeHHMMSS = this.cmi.getCurrentTotalTime();
343
337
  const totalTimeSeconds = Utilities.getTimeAsSeconds(
344
338
  totalTimeHHMMSS,
345
- Regex.scorm12.CMITimespan,
339
+ scorm12_regex.CMITimespan,
346
340
  );
347
341
  const lessonStatus = this.cmi.core.lesson_status;
348
342
  let completionStatus = CompletionStatus.unknown;
@@ -437,11 +431,11 @@ class Scorm12Impl extends BaseAPI {
437
431
  );
438
432
  } else {
439
433
  return {
440
- result: APIConstants.global.SCORM_TRUE,
434
+ result: global_constants.SCORM_TRUE,
441
435
  errorCode: 0,
442
436
  };
443
437
  }
444
438
  }
445
439
  }
446
440
 
447
- export { Scorm12Impl };
441
+ export { Scorm12Impl as Scorm12API };