@patch-adams/core 1.4.28 → 1.4.31

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 CHANGED
@@ -1744,6 +1744,10 @@ function generateLrsBridgeCode(options) {
1744
1744
  log('Looking up email for employee ID:', employeeId);
1745
1745
 
1746
1746
  fetchEmployeeEmail(employeeId, function(employeeData) {
1747
+ console.info('[PA-LRS] Employee lookup result for ' + employeeId + ': ' +
1748
+ (employeeData ? 'name=' + employeeData.name + ', email=' + employeeData.email +
1749
+ ', bravaisUserId=' + employeeData.bravaisUserId + ', tenantUrl=' + employeeData.tenantUrl
1750
+ : 'NO DATA'));
1747
1751
  if (employeeData && employeeData.email) {
1748
1752
  actor.mbox = 'mailto:' + employeeData.email;
1749
1753
  log('Enhanced actor with email:', employeeData.email);
@@ -4449,14 +4453,126 @@ function generateLrsBridgeCode(options) {
4449
4453
  // Launch events will NOT be sent until this completes
4450
4454
  extractActorAsync(function(actor) {
4451
4455
  log('Actor updated after async fetch:', actor);
4452
- actorReady = true;
4453
- // Log final actor state for diagnostics
4454
- if (window.console && window.console.info) {
4455
- console.info('[PA-LRS] Actor resolved: name=' + (actor ? actor.name : 'none') +
4456
- ', mbox=' + (actor ? actor.mbox : 'none') +
4457
- ', account=' + (actor && actor.account ? actor.account.name : 'none'));
4456
+
4457
+ // Check if actor is still "Unknown Learner" - SCORM API might not be available yet
4458
+ // The SCORM API is often injected by scorm-calls.js AFTER <head> init completes
4459
+ var isUnknown = !actor || actor.name === 'Unknown Learner' ||
4460
+ !actor.account || actor.account.name === 'unknown';
4461
+
4462
+ if (isUnknown) {
4463
+ log('Actor is Unknown Learner - SCORM API likely not available yet, polling for it...');
4464
+ var scormPollCount = 0;
4465
+ var scormMaxPolls = 30; // wait up to 30 seconds
4466
+ var scormResolved = false;
4467
+
4468
+ // Helper: search all possible locations for SCORM API
4469
+ function findScormApiAnywhere() {
4470
+ // 1. Search parent frame hierarchy (standard approach)
4471
+ var api2004 = findAPIInFrameHierarchy('API_1484_11', 10);
4472
+ if (api2004) return { api: api2004.api, type: '2004', source: 'parent-chain level ' + api2004.level };
4473
+ var api12 = findAPIInFrameHierarchy('API', 10);
4474
+ if (api12) return { api: api12.api, type: '1.2', source: 'parent-chain level ' + api12.level };
4475
+
4476
+ // 2. Check window.opener and its parent hierarchy (LMS opens content in popup)
4477
+ try {
4478
+ if (window.opener && window.opener !== window) {
4479
+ // Direct check on opener
4480
+ if (window.opener.API_1484_11) return { api: window.opener.API_1484_11, type: '2004', source: 'window.opener' };
4481
+ if (window.opener.API) return { api: window.opener.API, type: '1.2', source: 'window.opener' };
4482
+ // Check opener's parent chain
4483
+ var openerWin = window.opener;
4484
+ var openerLevel = 0;
4485
+ while (openerLevel < 10) {
4486
+ try {
4487
+ if (openerWin.API_1484_11) return { api: openerWin.API_1484_11, type: '2004', source: 'opener-chain level ' + openerLevel };
4488
+ if (openerWin.API) return { api: openerWin.API, type: '1.2', source: 'opener-chain level ' + openerLevel };
4489
+ if (openerWin.parent && openerWin.parent !== openerWin) { openerWin = openerWin.parent; openerLevel++; }
4490
+ else break;
4491
+ } catch(e) { break; }
4492
+ }
4493
+ }
4494
+ } catch(e) { /* cross-origin opener */ }
4495
+
4496
+ // 3. Check for global LMS functions (Bravais/Xyleme mock API)
4497
+ try {
4498
+ if (typeof window.LMSInitialize === 'function') {
4499
+ return { api: { LMSInitialize: window.LMSInitialize, LMSGetValue: window.LMSGetValue, LMSSetValue: window.LMSSetValue, LMSCommit: window.LMSCommit, LMSFinish: window.LMSFinish, LMSGetLastError: window.LMSGetLastError, LMSGetErrorString: window.LMSGetErrorString }, type: '1.2', source: 'global-functions' };
4500
+ }
4501
+ } catch(e) {}
4502
+ try {
4503
+ if (window.parent && window.parent !== window && typeof window.parent.LMSInitialize === 'function') {
4504
+ return { api: { LMSInitialize: window.parent.LMSInitialize, LMSGetValue: window.parent.LMSGetValue, LMSSetValue: window.parent.LMSSetValue, LMSCommit: window.parent.LMSCommit, LMSFinish: window.parent.LMSFinish, LMSGetLastError: window.parent.LMSGetLastError, LMSGetErrorString: window.parent.LMSGetErrorString }, type: '1.2', source: 'parent-global-functions' };
4505
+ }
4506
+ } catch(e) {}
4507
+
4508
+ return null;
4509
+ }
4510
+
4511
+ function onScormApiFound(result, pollNum) {
4512
+ if (scormResolved) return;
4513
+ scormResolved = true;
4514
+
4515
+ LRS.scormApi = result.api;
4516
+ LRS.scormApiFound = true;
4517
+ LRS.scormApiType = result.type;
4518
+
4519
+ // Read learner_id for diagnostics
4520
+ var scormLearnerId = 'n/a', scormLearnerName = 'n/a';
4521
+ try {
4522
+ if (result.type === '2004') {
4523
+ scormLearnerId = result.api.GetValue('cmi.learner_id');
4524
+ scormLearnerName = result.api.GetValue('cmi.learner_name');
4525
+ } else {
4526
+ scormLearnerId = result.api.LMSGetValue('cmi.core.student_id');
4527
+ scormLearnerName = result.api.LMSGetValue('cmi.core.student_name');
4528
+ }
4529
+ } catch(e) { scormLearnerId = 'error'; scormLearnerName = 'error'; }
4530
+ console.info('[PA-LRS] SCORM API found (poll ' + pollNum + ', source=' + result.source +
4531
+ ', type=' + result.type + '): learner_id=' + scormLearnerId + ', learner_name=' + scormLearnerName);
4532
+
4533
+ // refreshActor re-reads learner_id from SCORM and runs employee lookup
4534
+ LRS.refreshActor(function(refreshedActor) {
4535
+ if (window.console && window.console.info) {
4536
+ console.info('[PA-LRS] Actor resolved (after SCORM wait, poll ' + pollNum + '): name=' +
4537
+ (refreshedActor ? refreshedActor.name : 'none') +
4538
+ ', mbox=' + (refreshedActor ? refreshedActor.mbox : 'none') +
4539
+ ', account=' + (refreshedActor && refreshedActor.account ? refreshedActor.account.name : 'none'));
4540
+ }
4541
+ actorReady = true;
4542
+ tryLaunchEvents();
4543
+ });
4544
+ }
4545
+
4546
+ var scormPollTimer = setInterval(function() {
4547
+ if (scormResolved) { clearInterval(scormPollTimer); return; }
4548
+ scormPollCount++;
4549
+
4550
+ var result = findScormApiAnywhere();
4551
+
4552
+ if (result) {
4553
+ clearInterval(scormPollTimer);
4554
+ onScormApiFound(result, scormPollCount);
4555
+ } else if (scormPollCount >= scormMaxPolls) {
4556
+ clearInterval(scormPollTimer);
4557
+ log('SCORM API not found after ' + scormMaxPolls + 's, proceeding with Unknown Learner');
4558
+ if (window.console && window.console.info) {
4559
+ console.info('[PA-LRS] Actor resolved (timeout ' + scormMaxPolls + 's): name=' + (actor ? actor.name : 'none') +
4560
+ ', account=' + (actor && actor.account ? actor.account.name : 'none'));
4561
+ }
4562
+ actorReady = true;
4563
+ tryLaunchEvents();
4564
+ }
4565
+ }, 1000);
4566
+ } else {
4567
+ // Actor is valid - proceed immediately
4568
+ if (window.console && window.console.info) {
4569
+ console.info('[PA-LRS] Actor resolved: name=' + (actor ? actor.name : 'none') +
4570
+ ', mbox=' + (actor ? actor.mbox : 'none') +
4571
+ ', account=' + (actor && actor.account ? actor.account.name : 'none'));
4572
+ }
4573
+ actorReady = true;
4574
+ tryLaunchEvents();
4458
4575
  }
4459
- tryLaunchEvents();
4460
4576
  });
4461
4577
  } else {
4462
4578
  warn('Bridge setup failed - operating in offline mode');
@@ -4579,32 +4695,6 @@ function generateLrsBridgeCode(options) {
4579
4695
  }, 1000);
4580
4696
  }
4581
4697
 
4582
- // If actor is still Unknown Learner, poll for SCORM API availability
4583
- // The SCORM API may not be available during <head> init but appears later
4584
- // (e.g., scorm-calls.js finds and initializes it after DOM ready)
4585
- if (!LRS.actor || LRS.actor.name === 'Unknown Learner' || !LRS.actor.account || LRS.actor.account.name === 'unknown') {
4586
- var actorRetryCount = 0;
4587
- var actorMaxRetries = 15;
4588
- var actorRetryInterval = setInterval(function() {
4589
- actorRetryCount++;
4590
- // Check if SCORM API has become available (injected by scorm-calls.js or LMS)
4591
- var hasScormApi = LRS.scormApi ||
4592
- (typeof window.API !== 'undefined' && window.API) ||
4593
- (typeof window.API_1484_11 !== 'undefined' && window.API_1484_11);
4594
-
4595
- if (hasScormApi) {
4596
- log('SCORM API now available (attempt ' + actorRetryCount + '), refreshing actor...');
4597
- clearInterval(actorRetryInterval);
4598
- LRS.refreshActor(function(actor) {
4599
- log('Actor refreshed after SCORM API detected:', actor ? actor.name : 'none');
4600
- });
4601
- } else if (actorRetryCount >= actorMaxRetries) {
4602
- log('SCORM API not found after ' + actorMaxRetries + ' attempts, actor stays as-is');
4603
- clearInterval(actorRetryInterval);
4604
- }
4605
- }, 1000);
4606
- }
4607
-
4608
4698
  log('LRS bridge setup complete');
4609
4699
  }
4610
4700