scorm-again 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/.github/workflows/stale.yml +14 -0
  2. package/.run/{Mocha Unit Tests.run.xml → Mocha Unit Tests (watch).run.xml } +1 -1
  3. package/.run/Template Mocha.run.xml +17 -0
  4. package/README.md +171 -72
  5. package/dist/aicc.js +1441 -1140
  6. package/dist/aicc.js.map +1 -1
  7. package/dist/aicc.min.js +1 -1
  8. package/dist/aicc.min.js.map +1 -1
  9. package/dist/scorm-again.js +2703 -2212
  10. package/dist/scorm-again.js.map +1 -1
  11. package/dist/scorm-again.min.js +1 -1
  12. package/dist/scorm-again.min.js.map +1 -1
  13. package/dist/scorm12.js +1069 -852
  14. package/dist/scorm12.js.map +1 -1
  15. package/dist/scorm12.min.js +1 -1
  16. package/dist/scorm12.min.js.map +1 -1
  17. package/dist/scorm2004.js +1861 -1571
  18. package/dist/scorm2004.js.map +1 -1
  19. package/dist/scorm2004.min.js +1 -1
  20. package/dist/scorm2004.min.js.map +1 -1
  21. package/package.json +10 -6
  22. package/src/AICC.ts +15 -17
  23. package/src/BaseAPI.ts +268 -417
  24. package/src/Scorm12API.ts +65 -38
  25. package/src/Scorm2004API.ts +151 -117
  26. package/src/cmi/aicc/attempts.ts +94 -0
  27. package/src/cmi/aicc/cmi.ts +100 -0
  28. package/src/cmi/aicc/core.ts +360 -0
  29. package/src/cmi/aicc/evaluation.ts +157 -0
  30. package/src/cmi/aicc/paths.ts +180 -0
  31. package/src/cmi/aicc/student_data.ts +86 -0
  32. package/src/cmi/aicc/student_demographics.ts +367 -0
  33. package/src/cmi/aicc/student_preferences.ts +176 -0
  34. package/src/cmi/aicc/tries.ts +116 -0
  35. package/src/cmi/aicc/validation.ts +25 -0
  36. package/src/cmi/common/array.ts +77 -0
  37. package/src/cmi/common/base_cmi.ts +46 -0
  38. package/src/cmi/common/score.ts +203 -0
  39. package/src/cmi/common/validation.ts +60 -0
  40. package/src/cmi/scorm12/cmi.ts +224 -0
  41. package/src/cmi/scorm12/interactions.ts +368 -0
  42. package/src/cmi/scorm12/nav.ts +54 -0
  43. package/src/cmi/scorm12/objectives.ts +112 -0
  44. package/src/cmi/scorm12/student_data.ts +130 -0
  45. package/src/cmi/scorm12/student_preference.ts +158 -0
  46. package/src/cmi/scorm12/validation.ts +48 -0
  47. package/src/cmi/scorm2004/adl.ts +272 -0
  48. package/src/cmi/scorm2004/cmi.ts +599 -0
  49. package/src/cmi/scorm2004/comments.ts +163 -0
  50. package/src/cmi/scorm2004/interactions.ts +466 -0
  51. package/src/cmi/scorm2004/learner_preference.ts +152 -0
  52. package/src/cmi/scorm2004/objectives.ts +212 -0
  53. package/src/cmi/scorm2004/score.ts +78 -0
  54. package/src/cmi/scorm2004/validation.ts +42 -0
  55. package/src/constants/default_settings.ts +81 -0
  56. package/src/constants/enums.ts +5 -0
  57. package/src/constants/regex.ts +2 -2
  58. package/src/constants/response_constants.ts +2 -0
  59. package/src/exceptions.ts +22 -1
  60. package/src/helpers/scheduled_commit.ts +42 -0
  61. package/src/interfaces/IBaseAPI.ts +35 -0
  62. package/src/types/api_types.ts +32 -0
  63. package/src/utilities/debounce.ts +31 -0
  64. package/src/utilities.ts +56 -0
  65. package/test/AICC.spec.ts +11 -1
  66. package/test/Scorm12API.spec.ts +262 -9
  67. package/test/Scorm2004API.spec.ts +488 -2
  68. package/test/cmi/aicc_cmi.spec.ts +188 -11
  69. package/test/cmi/scorm12_cmi.spec.ts +5 -5
  70. package/test/cmi/scorm2004_cmi.spec.ts +8 -8
  71. package/test/cmi_helpers.ts +1 -1
  72. package/test/types/api_types.spec.ts +126 -0
  73. package/test/utilities/debounce.spec.ts +56 -0
  74. package/src/cmi/aicc_cmi.ts +0 -1248
  75. package/src/cmi/common.ts +0 -411
  76. package/src/cmi/scorm12_cmi.ts +0 -1426
  77. package/src/cmi/scorm2004_cmi.ts +0 -1874
@@ -0,0 +1,180 @@
1
+ import { BaseCMI } from "../common/base_cmi";
2
+ import { checkAICCValidFormat } from "./validation";
3
+ import { CMIArray } from "../common/array";
4
+ import Regex from "../../constants/regex";
5
+ import APIConstants from "../../constants/api_constants";
6
+
7
+ /**
8
+ * Class representing the AICC `cmi.paths` object
9
+ */
10
+ export class CMIPaths extends CMIArray {
11
+ /**
12
+ * Constructor for inline Paths Array class
13
+ */
14
+ constructor() {
15
+ super({
16
+ children: APIConstants.aicc.paths_children,
17
+ });
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Class for AICC Paths
23
+ */
24
+ export class CMIPathsObject extends BaseCMI {
25
+ /**
26
+ * Constructor for AICC Paths objects
27
+ */
28
+ constructor() {
29
+ super();
30
+ }
31
+
32
+ private _location_id = "";
33
+ private _date = "";
34
+ private _time = "";
35
+ private _status = "";
36
+ private _why_left = "";
37
+ private _time_in_element = "";
38
+
39
+ /**
40
+ * Getter for _location_id
41
+ * @return {string}
42
+ */
43
+ get location_id(): string {
44
+ return this._location_id;
45
+ }
46
+
47
+ /**
48
+ * Setter for _location_id
49
+ * @param {string} location_id
50
+ */
51
+ set location_id(location_id: string) {
52
+ if (checkAICCValidFormat(location_id, Regex.aicc.CMIString256)) {
53
+ this._location_id = location_id;
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Getter for _date
59
+ * @return {string}
60
+ */
61
+ get date(): string {
62
+ return this._date;
63
+ }
64
+
65
+ /**
66
+ * Setter for _date
67
+ * @param {string} date
68
+ */
69
+ set date(date: string) {
70
+ if (checkAICCValidFormat(date, Regex.aicc.CMIString256)) {
71
+ this._date = date;
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Getter for _time
77
+ * @return {string}
78
+ */
79
+ get time(): string {
80
+ return this._time;
81
+ }
82
+
83
+ /**
84
+ * Setter for _time
85
+ * @param {string} time
86
+ */
87
+ set time(time: string) {
88
+ if (checkAICCValidFormat(time, Regex.aicc.CMITime)) {
89
+ this._time = time;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Getter for _status
95
+ * @return {string}
96
+ */
97
+ get status(): string {
98
+ return this._status;
99
+ }
100
+
101
+ /**
102
+ * Setter for _status
103
+ * @param {string} status
104
+ */
105
+ set status(status: string) {
106
+ if (checkAICCValidFormat(status, Regex.aicc.CMIStatus2)) {
107
+ this._status = status;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Getter for _why_left
113
+ * @return {string}
114
+ */
115
+ get why_left(): string {
116
+ return this._why_left;
117
+ }
118
+
119
+ /**
120
+ * Setter for _why_left
121
+ * @param {string} why_left
122
+ */
123
+ set why_left(why_left: string) {
124
+ if (checkAICCValidFormat(why_left, Regex.aicc.CMIString256)) {
125
+ this._why_left = why_left;
126
+ }
127
+ }
128
+
129
+ /**
130
+ * Getter for _time_in_element
131
+ * @return {string}
132
+ */
133
+ get time_in_element(): string {
134
+ return this._time_in_element;
135
+ }
136
+
137
+ /**
138
+ * Setter for _time_in_element
139
+ * @param {string} time_in_element
140
+ */
141
+ set time_in_element(time_in_element: string) {
142
+ if (checkAICCValidFormat(time_in_element, Regex.aicc.CMITime)) {
143
+ this._time_in_element = time_in_element;
144
+ }
145
+ }
146
+
147
+ /**
148
+ * toJSON for cmi.paths.n object
149
+ * @return {
150
+ * {
151
+ * location_id: string,
152
+ * date: string,
153
+ * time: string,
154
+ * status: string,
155
+ * why_left: string,
156
+ * time_in_element: string
157
+ * }
158
+ * }
159
+ */
160
+ toJSON(): {
161
+ location_id: string;
162
+ date: string;
163
+ time: string;
164
+ status: string;
165
+ why_left: string;
166
+ time_in_element: string;
167
+ } {
168
+ this.jsonString = true;
169
+ const result = {
170
+ location_id: this.location_id,
171
+ date: this.date,
172
+ time: this.time,
173
+ status: this.status,
174
+ why_left: this.why_left,
175
+ time_in_element: this.time_in_element,
176
+ };
177
+ delete this.jsonString;
178
+ return result;
179
+ }
180
+ }
@@ -0,0 +1,86 @@
1
+ import { AICCValidationError } from "../../exceptions";
2
+ import ErrorCodes from "../../constants/error_codes";
3
+ import APIConstants from "../../constants/api_constants";
4
+ import { CMITries } from "./tries";
5
+ import { CMIStudentData } from "../scorm12/student_data";
6
+ import { CMIAttemptRecords } from "./attempts";
7
+
8
+ /**
9
+ * StudentData class for AICC
10
+ */
11
+ export class AICCCMIStudentData extends CMIStudentData {
12
+ /**
13
+ * Constructor for AICC StudentData object
14
+ */
15
+ constructor() {
16
+ super(APIConstants.aicc.student_data_children);
17
+ this.tries = new CMITries();
18
+ this.attempt_records = new CMIAttemptRecords();
19
+ }
20
+
21
+ public tries: CMITries;
22
+ public attempt_records: CMIAttemptRecords;
23
+
24
+ /**
25
+ * Called when the API has been initialized after the CMI has been created
26
+ */
27
+ initialize() {
28
+ super.initialize();
29
+ this.tries?.initialize();
30
+ this.attempt_records?.initialize();
31
+ }
32
+
33
+ private _tries_during_lesson = "";
34
+
35
+ /**
36
+ * Getter for tries_during_lesson
37
+ * @return {string}
38
+ */
39
+ get tries_during_lesson(): string {
40
+ return this._tries_during_lesson;
41
+ }
42
+
43
+ /**
44
+ * Setter for _tries_during_lesson. Sets an error if trying to set after
45
+ * initialization.
46
+ * @param {string} tries_during_lesson
47
+ */
48
+ set tries_during_lesson(tries_during_lesson: string) {
49
+ if (this.initialized) {
50
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
51
+ } else {
52
+ this._tries_during_lesson = tries_during_lesson;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * toJSON for cmi.student_data object
58
+ * @return {
59
+ * {
60
+ * mastery_score: string,
61
+ * max_time_allowed: string,
62
+ * time_limit_action: string,
63
+ * tries: CMITries,
64
+ * attempt_records: CMIAttemptRecords
65
+ * }
66
+ * }
67
+ */
68
+ toJSON(): {
69
+ mastery_score: string;
70
+ max_time_allowed: string;
71
+ time_limit_action: string;
72
+ tries: CMITries;
73
+ attempt_records: CMIAttemptRecords;
74
+ } {
75
+ this.jsonString = true;
76
+ const result = {
77
+ mastery_score: this.mastery_score,
78
+ max_time_allowed: this.max_time_allowed,
79
+ time_limit_action: this.time_limit_action,
80
+ tries: this.tries,
81
+ attempt_records: this.attempt_records,
82
+ };
83
+ delete this.jsonString;
84
+ return result;
85
+ }
86
+ }
@@ -0,0 +1,367 @@
1
+ import { BaseCMI } from "../common/base_cmi";
2
+ import { AICCValidationError } from "../../exceptions";
3
+ import APIConstants from "../../constants/api_constants";
4
+ import ErrorCodes from "../../constants/error_codes";
5
+
6
+ /**
7
+ * Class representing the AICC cmi.student_demographics object
8
+ */
9
+ export class CMIStudentDemographics extends BaseCMI {
10
+ /**
11
+ * Constructor for AICC StudentDemographics object
12
+ */
13
+ constructor() {
14
+ super();
15
+ }
16
+
17
+ private __children = APIConstants.aicc.student_demographics_children;
18
+ private _city = "";
19
+ private _class = "";
20
+ private _company = "";
21
+ private _country = "";
22
+ private _experience = "";
23
+ private _familiar_name = "";
24
+ private _instructor_name = "";
25
+ private _title = "";
26
+ private _native_language = "";
27
+ private _state = "";
28
+ private _street_address = "";
29
+ private _telephone = "";
30
+ private _years_experience = "";
31
+
32
+ /**
33
+ * Getter for _children
34
+ * @return {string}
35
+ */
36
+ get _children(): string {
37
+ return this.__children;
38
+ }
39
+
40
+ /**
41
+ * Getter for city
42
+ * @return {string}
43
+ */
44
+ get city(): string {
45
+ return this._city;
46
+ }
47
+
48
+ /**
49
+ * Setter for _city. Sets an error if trying to set after
50
+ * initialization.
51
+ * @param {string} city
52
+ */
53
+ set city(city: string) {
54
+ if (this.initialized) {
55
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
56
+ } else {
57
+ this._city = city;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Getter for class
63
+ * @return {string}
64
+ */
65
+ get class(): string {
66
+ return this._class;
67
+ }
68
+
69
+ /**
70
+ * Setter for _class. Sets an error if trying to set after
71
+ * initialization.
72
+ * @param {string} clazz
73
+ */
74
+ set class(clazz: string) {
75
+ if (this.initialized) {
76
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
77
+ } else {
78
+ this._class = clazz;
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Getter for company
84
+ * @return {string}
85
+ */
86
+ get company(): string {
87
+ return this._company;
88
+ }
89
+
90
+ /**
91
+ * Setter for _company. Sets an error if trying to set after
92
+ * initialization.
93
+ * @param {string} company
94
+ */
95
+ set company(company: string) {
96
+ if (this.initialized) {
97
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
98
+ } else {
99
+ this._company = company;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Getter for country
105
+ * @return {string}
106
+ */
107
+ get country(): string {
108
+ return this._country;
109
+ }
110
+
111
+ /**
112
+ * Setter for _country. Sets an error if trying to set after
113
+ * initialization.
114
+ * @param {string} country
115
+ */
116
+ set country(country: string) {
117
+ if (this.initialized) {
118
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
119
+ } else {
120
+ this._country = country;
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Getter for experience
126
+ * @return {string}
127
+ */
128
+ get experience(): string {
129
+ return this._experience;
130
+ }
131
+
132
+ /**
133
+ * Setter for _experience. Sets an error if trying to set after
134
+ * initialization.
135
+ * @param {string} experience
136
+ */
137
+ set experience(experience: string) {
138
+ if (this.initialized) {
139
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
140
+ } else {
141
+ this._experience = experience;
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Getter for familiar_name
147
+ * @return {string}
148
+ */
149
+ get familiar_name(): string {
150
+ return this._familiar_name;
151
+ }
152
+
153
+ /**
154
+ * Setter for _familiar_name. Sets an error if trying to set after
155
+ * initialization.
156
+ * @param {string} familiar_name
157
+ */
158
+ set familiar_name(familiar_name: string) {
159
+ if (this.initialized) {
160
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
161
+ } else {
162
+ this._familiar_name = familiar_name;
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Getter for instructor_name
168
+ * @return {string}
169
+ */
170
+ get instructor_name(): string {
171
+ return this._instructor_name;
172
+ }
173
+
174
+ /**
175
+ * Setter for _instructor_name. Sets an error if trying to set after
176
+ * initialization.
177
+ * @param {string} instructor_name
178
+ */
179
+ set instructor_name(instructor_name: string) {
180
+ if (this.initialized) {
181
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
182
+ } else {
183
+ this._instructor_name = instructor_name;
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Getter for title
189
+ * @return {string}
190
+ */
191
+ get title(): string {
192
+ return this._title;
193
+ }
194
+
195
+ /**
196
+ * Setter for _title. Sets an error if trying to set after
197
+ * initialization.
198
+ * @param {string} title
199
+ */
200
+ set title(title: string) {
201
+ if (this.initialized) {
202
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
203
+ } else {
204
+ this._title = title;
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Getter for native_language
210
+ * @return {string}
211
+ */
212
+ get native_language(): string {
213
+ return this._native_language;
214
+ }
215
+
216
+ /**
217
+ * Setter for _native_language. Sets an error if trying to set after
218
+ * initialization.
219
+ * @param {string} native_language
220
+ */
221
+ set native_language(native_language: string) {
222
+ if (this.initialized) {
223
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
224
+ } else {
225
+ this._native_language = native_language;
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Getter for state
231
+ * @return {string}
232
+ */
233
+ get state(): string {
234
+ return this._state;
235
+ }
236
+
237
+ /**
238
+ * Setter for _state. Sets an error if trying to set after
239
+ * initialization.
240
+ * @param {string} state
241
+ */
242
+ set state(state: string) {
243
+ if (this.initialized) {
244
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
245
+ } else {
246
+ this._state = state;
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Getter for street_address
252
+ * @return {string}
253
+ */
254
+ get street_address(): string {
255
+ return this._street_address;
256
+ }
257
+
258
+ /**
259
+ * Setter for _street_address. Sets an error if trying to set after
260
+ * initialization.
261
+ * @param {string} street_address
262
+ */
263
+ set street_address(street_address: string) {
264
+ if (this.initialized) {
265
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
266
+ } else {
267
+ this._street_address = street_address;
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Getter for telephone
273
+ * @return {string}
274
+ */
275
+ get telephone(): string {
276
+ return this._telephone;
277
+ }
278
+
279
+ /**
280
+ * Setter for _telephone. Sets an error if trying to set after
281
+ * initialization.
282
+ * @param {string} telephone
283
+ */
284
+ set telephone(telephone: string) {
285
+ if (this.initialized) {
286
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
287
+ } else {
288
+ this._telephone = telephone;
289
+ }
290
+ }
291
+
292
+ /**
293
+ * Getter for years_experience
294
+ * @return {string}
295
+ */
296
+ get years_experience(): string {
297
+ return this._years_experience;
298
+ }
299
+
300
+ /**
301
+ * Setter for _years_experience. Sets an error if trying to set after
302
+ * initialization.
303
+ * @param {string} years_experience
304
+ */
305
+ set years_experience(years_experience: string) {
306
+ if (this.initialized) {
307
+ throw new AICCValidationError(ErrorCodes.scorm12.READ_ONLY_ELEMENT);
308
+ } else {
309
+ this._years_experience = years_experience;
310
+ }
311
+ }
312
+
313
+ /**
314
+ * toJSON for cmi.student_demographics object
315
+ * @return {
316
+ * {
317
+ * city: string,
318
+ * class: string,
319
+ * company: string,
320
+ * country: string,
321
+ * experience: string,
322
+ * familiar_name: string,
323
+ * instructor_name: string,
324
+ * title: string,
325
+ * native_language: string,
326
+ * state: string,
327
+ * street_address: string,
328
+ * telephone: string,
329
+ * years_experience: string
330
+ * }
331
+ * }
332
+ */
333
+ toJSON(): {
334
+ city: string;
335
+ class: string;
336
+ company: string;
337
+ country: string;
338
+ experience: string;
339
+ familiar_name: string;
340
+ instructor_name: string;
341
+ title: string;
342
+ native_language: string;
343
+ state: string;
344
+ street_address: string;
345
+ telephone: string;
346
+ years_experience: string;
347
+ } {
348
+ this.jsonString = true;
349
+ const result = {
350
+ city: this.city,
351
+ class: this.class,
352
+ company: this.company,
353
+ country: this.country,
354
+ experience: this.experience,
355
+ familiar_name: this.familiar_name,
356
+ instructor_name: this.instructor_name,
357
+ title: this.title,
358
+ native_language: this.native_language,
359
+ state: this.state,
360
+ street_address: this.street_address,
361
+ telephone: this.telephone,
362
+ years_experience: this.years_experience,
363
+ };
364
+ delete this.jsonString;
365
+ return result;
366
+ }
367
+ }