@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.js
CHANGED
|
@@ -3397,11 +3397,11 @@ function generateLrsBridgeCode(options) {
|
|
|
3397
3397
|
// Send a course completion statement \u2014 called by skin or auto-detected via SCORM
|
|
3398
3398
|
LRS.sendCompletionStatement = function(data) {
|
|
3399
3399
|
data = data || {};
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3400
|
+
// Cancel any pending SCORM auto-detection to avoid double-fire for same attempt
|
|
3401
|
+
if (scormCompletionDebounce) {
|
|
3402
|
+
clearTimeout(scormCompletionDebounce);
|
|
3403
|
+
scormCompletionDebounce = null;
|
|
3403
3404
|
}
|
|
3404
|
-
scormCompletionSent = true;
|
|
3405
3405
|
|
|
3406
3406
|
var status = data.status || 'completed';
|
|
3407
3407
|
var courseTitle = data.courseTitle || (LRS.courseInfo && LRS.courseInfo.title ? decodeEntities(LRS.courseInfo.title) : decodeEntities(document.title) || 'Course');
|
|
@@ -3431,11 +3431,58 @@ function generateLrsBridgeCode(options) {
|
|
|
3431
3431
|
};
|
|
3432
3432
|
if (data.employeeName) activityDetails.employeeName = data.employeeName;
|
|
3433
3433
|
|
|
3434
|
-
|
|
3435
|
-
|
|
3434
|
+
// 1. Always send "completed" statement
|
|
3435
|
+
log('Sending completed statement, score:', result.score, 'title:', courseTitle);
|
|
3436
|
+
var completedStatement = buildStatement('completed', ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
3437
|
+
sendStatement(completedStatement);
|
|
3438
|
+
|
|
3439
|
+
// 2. Send "passed" or "failed" statement (assessment outcome)
|
|
3440
|
+
if (status === 'passed' || status === 'failed') {
|
|
3441
|
+
log('Sending', status, 'statement');
|
|
3442
|
+
var outcomeStatement = buildStatement(status, ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
3443
|
+
sendStatement(outcomeStatement);
|
|
3444
|
+
}
|
|
3445
|
+
};
|
|
3446
|
+
|
|
3447
|
+
// Send a "terminated" statement \u2014 called by skin close button or auto on page unload
|
|
3448
|
+
var exitStatementSent = false;
|
|
3449
|
+
LRS.sendExitStatement = function(data) {
|
|
3450
|
+
if (exitStatementSent) return;
|
|
3451
|
+
exitStatementSent = true;
|
|
3452
|
+
data = data || {};
|
|
3453
|
+
|
|
3454
|
+
var courseTitle = (LRS.courseInfo && LRS.courseInfo.title) ? decodeEntities(LRS.courseInfo.title) : decodeEntities(document.title) || 'Course';
|
|
3455
|
+
var duration = null;
|
|
3456
|
+
if (LRS.launchTime) {
|
|
3457
|
+
var ms = new Date().getTime() - new Date(LRS.launchTime).getTime();
|
|
3458
|
+
var secs = Math.floor(ms / 1000);
|
|
3459
|
+
var mins = Math.floor(secs / 60);
|
|
3460
|
+
var hrs = Math.floor(mins / 60);
|
|
3461
|
+
duration = 'PT' + (hrs > 0 ? hrs + 'H' : '') + (mins % 60) + 'M' + (secs % 60) + 'S';
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
var activityDetails = {
|
|
3465
|
+
courseTitle: courseTitle,
|
|
3466
|
+
exitSource: data.source || 'page-unload',
|
|
3467
|
+
employeeEmail: LRS.actor && LRS.actor.mbox ? LRS.actor.mbox.replace('mailto:', '') : undefined,
|
|
3468
|
+
employeeId: LRS.employeeId || undefined,
|
|
3469
|
+
sessionDuration: duration,
|
|
3470
|
+
statementsSent: LRS.stats.statementsSent
|
|
3471
|
+
};
|
|
3472
|
+
|
|
3473
|
+
var result = duration ? { duration: duration } : null;
|
|
3474
|
+
log('Sending exit statement, duration:', duration);
|
|
3475
|
+
var statement = buildStatement('terminated', ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
3436
3476
|
sendStatement(statement);
|
|
3437
3477
|
};
|
|
3438
3478
|
|
|
3479
|
+
// Auto-send exit statement on page unload
|
|
3480
|
+
window.addEventListener('beforeunload', function() {
|
|
3481
|
+
if (!exitStatementSent && LRS.actor) {
|
|
3482
|
+
LRS.sendExitStatement({ source: 'page-unload' });
|
|
3483
|
+
}
|
|
3484
|
+
});
|
|
3485
|
+
|
|
3439
3486
|
/**
|
|
3440
3487
|
* Re-extract actor from SCORM after LMSInitialize has been called.
|
|
3441
3488
|
* Call this from the SCORM wrapper after scormInit() succeeds,
|
|
@@ -3542,6 +3589,23 @@ function generateLrsBridgeCode(options) {
|
|
|
3542
3589
|
LRS.interacted({ type: 'choice-branch', id: data.id, name: 'Choice Branch Discarded' });
|
|
3543
3590
|
};
|
|
3544
3591
|
|
|
3592
|
+
// ========================================================================
|
|
3593
|
+
// PUBLIC API \u2014 expose core internals for skin scripts
|
|
3594
|
+
// Usage: window.pa_patcher.lrs.api.sendStatement(stmt)
|
|
3595
|
+
// ========================================================================
|
|
3596
|
+
LRS.api = {
|
|
3597
|
+
sendStatement: sendStatement,
|
|
3598
|
+
buildStatement: buildStatement,
|
|
3599
|
+
buildCourseActivityObject: buildCourseActivityObject,
|
|
3600
|
+
buildXylemeContext: buildXylemeContext,
|
|
3601
|
+
generateUUID: generateUUID,
|
|
3602
|
+
decodeEntities: decodeEntities,
|
|
3603
|
+
extractActor: extractActor,
|
|
3604
|
+
getCachedLessonInfo: getCachedLessonInfo,
|
|
3605
|
+
VERBS: VERBS,
|
|
3606
|
+
ACTIVITY_TYPES: ACTIVITY_TYPES
|
|
3607
|
+
};
|
|
3608
|
+
|
|
3545
3609
|
// ========================================================================
|
|
3546
3610
|
// 8. RISE EVENT INTERCEPTORS
|
|
3547
3611
|
// ========================================================================
|
|
@@ -4107,7 +4171,7 @@ function generateLrsBridgeCode(options) {
|
|
|
4107
4171
|
var scormInteractionsSent = {}; // Track which interactions were already sent
|
|
4108
4172
|
var scormTrackerActive = false; // Set true when SCORM tracker wraps SetValue \u2014 KC handler defers
|
|
4109
4173
|
var scormCourseData = {}; // Accumulates course-level SCORM data (score, status)
|
|
4110
|
-
var
|
|
4174
|
+
var scormCompletionDebounce = null; // Debounce timer \u2014 prevents duplicate fires within same completion event
|
|
4111
4175
|
|
|
4112
4176
|
function interceptScormSetValue(key, value) {
|
|
4113
4177
|
if (typeof key !== 'string') return;
|
|
@@ -4127,12 +4191,15 @@ function generateLrsBridgeCode(options) {
|
|
|
4127
4191
|
if (key === 'cmi.success_status') { scormCourseData.successStatus = String(value).toLowerCase(); }
|
|
4128
4192
|
|
|
4129
4193
|
// Fire course completion statement when status indicates pass/fail/complete
|
|
4130
|
-
|
|
4194
|
+
// Uses debounce (not one-time flag) so retries/new attempts are captured
|
|
4195
|
+
if (key === 'cmi.core.lesson_status' || key === 'cmi.success_status' || key === 'cmi.completion_status') {
|
|
4131
4196
|
var status = String(value).toLowerCase();
|
|
4132
4197
|
if (status === 'passed' || status === 'failed' || status === 'completed') {
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4198
|
+
if (scormCompletionDebounce) clearTimeout(scormCompletionDebounce);
|
|
4199
|
+
scormCompletionDebounce = setTimeout(function() {
|
|
4200
|
+
scormCompletionDebounce = null;
|
|
4201
|
+
sendCourseCompletionStatement(status);
|
|
4202
|
+
}, 500);
|
|
4136
4203
|
}
|
|
4137
4204
|
}
|
|
4138
4205
|
|
|
@@ -4243,11 +4310,6 @@ function generateLrsBridgeCode(options) {
|
|
|
4243
4310
|
|
|
4244
4311
|
var courseTitle = (LRS.courseInfo && LRS.courseInfo.title) ? decodeEntities(LRS.courseInfo.title) : decodeEntities(document.title) || 'Course';
|
|
4245
4312
|
|
|
4246
|
-
// Determine verb
|
|
4247
|
-
var verbKey = 'completed';
|
|
4248
|
-
if (status === 'passed') verbKey = 'passed';
|
|
4249
|
-
if (status === 'failed') verbKey = 'failed';
|
|
4250
|
-
|
|
4251
4313
|
// Build result with score
|
|
4252
4314
|
var result = { completion: true };
|
|
4253
4315
|
|
|
@@ -4273,10 +4335,17 @@ function generateLrsBridgeCode(options) {
|
|
|
4273
4335
|
employeeId: LRS.employeeId || undefined
|
|
4274
4336
|
};
|
|
4275
4337
|
|
|
4276
|
-
|
|
4338
|
+
// 1. Send "completed" statement (course was finished)
|
|
4339
|
+
log('Sending completed statement, score:', result.score, 'title:', courseTitle);
|
|
4340
|
+
var completedStatement = buildStatement('completed', ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
4341
|
+
sendStatement(completedStatement);
|
|
4277
4342
|
|
|
4278
|
-
|
|
4279
|
-
|
|
4343
|
+
// 2. Send "passed" or "failed" statement (assessment outcome)
|
|
4344
|
+
if (status === 'passed' || status === 'failed') {
|
|
4345
|
+
log('Sending', status, 'statement');
|
|
4346
|
+
var outcomeStatement = buildStatement(status, ACTIVITY_TYPES.course, activityDetails, result, null);
|
|
4347
|
+
sendStatement(outcomeStatement);
|
|
4348
|
+
}
|
|
4280
4349
|
|
|
4281
4350
|
logGroupEnd();
|
|
4282
4351
|
}
|