@patch-adams/core 1.5.11 → 1.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +88 -19
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +88 -19
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +88 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +88 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3406,11 +3406,11 @@ function generateLrsBridgeCode(options) {
|
|
|
3406
3406
|
// Send a course completion statement \u2014 called by skin or auto-detected via SCORM
|
|
3407
3407
|
LRS.sendCompletionStatement = function(data) {
|
|
3408
3408
|
data = data || {};
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3409
|
+
// Cancel any pending SCORM auto-detection to avoid double-fire for same attempt
|
|
3410
|
+
if (scormCompletionDebounce) {
|
|
3411
|
+
clearTimeout(scormCompletionDebounce);
|
|
3412
|
+
scormCompletionDebounce = null;
|
|
3412
3413
|
}
|
|
3413
|
-
scormCompletionSent = true;
|
|
3414
3414
|
|
|
3415
3415
|
var status = data.status || 'completed';
|
|
3416
3416
|
var courseTitle = data.courseTitle || (LRS.courseInfo && LRS.courseInfo.title ? decodeEntities(LRS.courseInfo.title) : decodeEntities(document.title) || 'Course');
|
|
@@ -3440,11 +3440,58 @@ function generateLrsBridgeCode(options) {
|
|
|
3440
3440
|
};
|
|
3441
3441
|
if (data.employeeName) activityDetails.employeeName = data.employeeName;
|
|
3442
3442
|
|
|
3443
|
-
|
|
3444
|
-
|
|
3443
|
+
// 1. Always send "completed" statement
|
|
3444
|
+
log('Sending completed statement, score:', result.score, 'title:', courseTitle);
|
|
3445
|
+
var completedStatement = buildStatement('completed', ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
3446
|
+
sendStatement(completedStatement);
|
|
3447
|
+
|
|
3448
|
+
// 2. Send "passed" or "failed" statement (assessment outcome)
|
|
3449
|
+
if (status === 'passed' || status === 'failed') {
|
|
3450
|
+
log('Sending', status, 'statement');
|
|
3451
|
+
var outcomeStatement = buildStatement(status, ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
3452
|
+
sendStatement(outcomeStatement);
|
|
3453
|
+
}
|
|
3454
|
+
};
|
|
3455
|
+
|
|
3456
|
+
// Send a "terminated" statement \u2014 called by skin close button or auto on page unload
|
|
3457
|
+
var exitStatementSent = false;
|
|
3458
|
+
LRS.sendExitStatement = function(data) {
|
|
3459
|
+
if (exitStatementSent) return;
|
|
3460
|
+
exitStatementSent = true;
|
|
3461
|
+
data = data || {};
|
|
3462
|
+
|
|
3463
|
+
var courseTitle = (LRS.courseInfo && LRS.courseInfo.title) ? decodeEntities(LRS.courseInfo.title) : decodeEntities(document.title) || 'Course';
|
|
3464
|
+
var duration = null;
|
|
3465
|
+
if (LRS.launchTime) {
|
|
3466
|
+
var ms = new Date().getTime() - new Date(LRS.launchTime).getTime();
|
|
3467
|
+
var secs = Math.floor(ms / 1000);
|
|
3468
|
+
var mins = Math.floor(secs / 60);
|
|
3469
|
+
var hrs = Math.floor(mins / 60);
|
|
3470
|
+
duration = 'PT' + (hrs > 0 ? hrs + 'H' : '') + (mins % 60) + 'M' + (secs % 60) + 'S';
|
|
3471
|
+
}
|
|
3472
|
+
|
|
3473
|
+
var activityDetails = {
|
|
3474
|
+
courseTitle: courseTitle,
|
|
3475
|
+
exitSource: data.source || 'page-unload',
|
|
3476
|
+
employeeEmail: LRS.actor && LRS.actor.mbox ? LRS.actor.mbox.replace('mailto:', '') : undefined,
|
|
3477
|
+
employeeId: LRS.employeeId || undefined,
|
|
3478
|
+
sessionDuration: duration,
|
|
3479
|
+
statementsSent: LRS.stats.statementsSent
|
|
3480
|
+
};
|
|
3481
|
+
|
|
3482
|
+
var result = duration ? { duration: duration } : null;
|
|
3483
|
+
log('Sending exit statement, duration:', duration);
|
|
3484
|
+
var statement = buildStatement('terminated', ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
3445
3485
|
sendStatement(statement);
|
|
3446
3486
|
};
|
|
3447
3487
|
|
|
3488
|
+
// Auto-send exit statement on page unload
|
|
3489
|
+
window.addEventListener('beforeunload', function() {
|
|
3490
|
+
if (!exitStatementSent && LRS.actor) {
|
|
3491
|
+
LRS.sendExitStatement({ source: 'page-unload' });
|
|
3492
|
+
}
|
|
3493
|
+
});
|
|
3494
|
+
|
|
3448
3495
|
/**
|
|
3449
3496
|
* Re-extract actor from SCORM after LMSInitialize has been called.
|
|
3450
3497
|
* Call this from the SCORM wrapper after scormInit() succeeds,
|
|
@@ -3551,6 +3598,23 @@ function generateLrsBridgeCode(options) {
|
|
|
3551
3598
|
LRS.interacted({ type: 'choice-branch', id: data.id, name: 'Choice Branch Discarded' });
|
|
3552
3599
|
};
|
|
3553
3600
|
|
|
3601
|
+
// ========================================================================
|
|
3602
|
+
// PUBLIC API \u2014 expose core internals for skin scripts
|
|
3603
|
+
// Usage: window.pa_patcher.lrs.api.sendStatement(stmt)
|
|
3604
|
+
// ========================================================================
|
|
3605
|
+
LRS.api = {
|
|
3606
|
+
sendStatement: sendStatement,
|
|
3607
|
+
buildStatement: buildStatement,
|
|
3608
|
+
buildCourseActivityObject: buildCourseActivityObject,
|
|
3609
|
+
buildXylemeContext: buildXylemeContext,
|
|
3610
|
+
generateUUID: generateUUID,
|
|
3611
|
+
decodeEntities: decodeEntities,
|
|
3612
|
+
extractActor: extractActor,
|
|
3613
|
+
getCachedLessonInfo: getCachedLessonInfo,
|
|
3614
|
+
VERBS: VERBS,
|
|
3615
|
+
ACTIVITY_TYPES: ACTIVITY_TYPES
|
|
3616
|
+
};
|
|
3617
|
+
|
|
3554
3618
|
// ========================================================================
|
|
3555
3619
|
// 8. RISE EVENT INTERCEPTORS
|
|
3556
3620
|
// ========================================================================
|
|
@@ -4116,7 +4180,7 @@ function generateLrsBridgeCode(options) {
|
|
|
4116
4180
|
var scormInteractionsSent = {}; // Track which interactions were already sent
|
|
4117
4181
|
var scormTrackerActive = false; // Set true when SCORM tracker wraps SetValue \u2014 KC handler defers
|
|
4118
4182
|
var scormCourseData = {}; // Accumulates course-level SCORM data (score, status)
|
|
4119
|
-
var
|
|
4183
|
+
var scormCompletionDebounce = null; // Debounce timer \u2014 prevents duplicate fires within same completion event
|
|
4120
4184
|
|
|
4121
4185
|
function interceptScormSetValue(key, value) {
|
|
4122
4186
|
if (typeof key !== 'string') return;
|
|
@@ -4136,12 +4200,15 @@ function generateLrsBridgeCode(options) {
|
|
|
4136
4200
|
if (key === 'cmi.success_status') { scormCourseData.successStatus = String(value).toLowerCase(); }
|
|
4137
4201
|
|
|
4138
4202
|
// Fire course completion statement when status indicates pass/fail/complete
|
|
4139
|
-
|
|
4203
|
+
// Uses debounce (not one-time flag) so retries/new attempts are captured
|
|
4204
|
+
if (key === 'cmi.core.lesson_status' || key === 'cmi.success_status' || key === 'cmi.completion_status') {
|
|
4140
4205
|
var status = String(value).toLowerCase();
|
|
4141
4206
|
if (status === 'passed' || status === 'failed' || status === 'completed') {
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4207
|
+
if (scormCompletionDebounce) clearTimeout(scormCompletionDebounce);
|
|
4208
|
+
scormCompletionDebounce = setTimeout(function() {
|
|
4209
|
+
scormCompletionDebounce = null;
|
|
4210
|
+
sendCourseCompletionStatement(status);
|
|
4211
|
+
}, 500);
|
|
4145
4212
|
}
|
|
4146
4213
|
}
|
|
4147
4214
|
|
|
@@ -4252,11 +4319,6 @@ function generateLrsBridgeCode(options) {
|
|
|
4252
4319
|
|
|
4253
4320
|
var courseTitle = (LRS.courseInfo && LRS.courseInfo.title) ? decodeEntities(LRS.courseInfo.title) : decodeEntities(document.title) || 'Course';
|
|
4254
4321
|
|
|
4255
|
-
// Determine verb
|
|
4256
|
-
var verbKey = 'completed';
|
|
4257
|
-
if (status === 'passed') verbKey = 'passed';
|
|
4258
|
-
if (status === 'failed') verbKey = 'failed';
|
|
4259
|
-
|
|
4260
4322
|
// Build result with score
|
|
4261
4323
|
var result = { completion: true };
|
|
4262
4324
|
|
|
@@ -4282,10 +4344,17 @@ function generateLrsBridgeCode(options) {
|
|
|
4282
4344
|
employeeId: LRS.employeeId || undefined
|
|
4283
4345
|
};
|
|
4284
4346
|
|
|
4285
|
-
|
|
4347
|
+
// 1. Send "completed" statement (course was finished)
|
|
4348
|
+
log('Sending completed statement, score:', result.score, 'title:', courseTitle);
|
|
4349
|
+
var completedStatement = buildStatement('completed', ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
4350
|
+
sendStatement(completedStatement);
|
|
4286
4351
|
|
|
4287
|
-
|
|
4288
|
-
|
|
4352
|
+
// 2. Send "passed" or "failed" statement (assessment outcome)
|
|
4353
|
+
if (status === 'passed' || status === 'failed') {
|
|
4354
|
+
log('Sending', status, 'statement');
|
|
4355
|
+
var outcomeStatement = buildStatement(status, ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
4356
|
+
sendStatement(outcomeStatement);
|
|
4357
|
+
}
|
|
4289
4358
|
|
|
4290
4359
|
logGroupEnd();
|
|
4291
4360
|
}
|