@patch-adams/core 1.4.30 → 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.js CHANGED
@@ -4453,58 +4453,101 @@ function generateLrsBridgeCode(options) {
4453
4453
  if (isUnknown) {
4454
4454
  log('Actor is Unknown Learner - SCORM API likely not available yet, polling for it...');
4455
4455
  var scormPollCount = 0;
4456
- var scormMaxPolls = 20; // wait up to 20 seconds
4456
+ var scormMaxPolls = 30; // wait up to 30 seconds
4457
+ var scormResolved = false;
4458
+
4459
+ // Helper: search all possible locations for SCORM API
4460
+ function findScormApiAnywhere() {
4461
+ // 1. Search parent frame hierarchy (standard approach)
4462
+ var api2004 = findAPIInFrameHierarchy('API_1484_11', 10);
4463
+ if (api2004) return { api: api2004.api, type: '2004', source: 'parent-chain level ' + api2004.level };
4464
+ var api12 = findAPIInFrameHierarchy('API', 10);
4465
+ if (api12) return { api: api12.api, type: '1.2', source: 'parent-chain level ' + api12.level };
4466
+
4467
+ // 2. Check window.opener and its parent hierarchy (LMS opens content in popup)
4468
+ try {
4469
+ if (window.opener && window.opener !== window) {
4470
+ // Direct check on opener
4471
+ if (window.opener.API_1484_11) return { api: window.opener.API_1484_11, type: '2004', source: 'window.opener' };
4472
+ if (window.opener.API) return { api: window.opener.API, type: '1.2', source: 'window.opener' };
4473
+ // Check opener's parent chain
4474
+ var openerWin = window.opener;
4475
+ var openerLevel = 0;
4476
+ while (openerLevel < 10) {
4477
+ try {
4478
+ if (openerWin.API_1484_11) return { api: openerWin.API_1484_11, type: '2004', source: 'opener-chain level ' + openerLevel };
4479
+ if (openerWin.API) return { api: openerWin.API, type: '1.2', source: 'opener-chain level ' + openerLevel };
4480
+ if (openerWin.parent && openerWin.parent !== openerWin) { openerWin = openerWin.parent; openerLevel++; }
4481
+ else break;
4482
+ } catch(e) { break; }
4483
+ }
4484
+ }
4485
+ } catch(e) { /* cross-origin opener */ }
4486
+
4487
+ // 3. Check for global LMS functions (Bravais/Xyleme mock API)
4488
+ try {
4489
+ if (typeof window.LMSInitialize === 'function') {
4490
+ 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' };
4491
+ }
4492
+ } catch(e) {}
4493
+ try {
4494
+ if (window.parent && window.parent !== window && typeof window.parent.LMSInitialize === 'function') {
4495
+ 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' };
4496
+ }
4497
+ } catch(e) {}
4498
+
4499
+ return null;
4500
+ }
4501
+
4502
+ function onScormApiFound(result, pollNum) {
4503
+ if (scormResolved) return;
4504
+ scormResolved = true;
4505
+
4506
+ LRS.scormApi = result.api;
4507
+ LRS.scormApiFound = true;
4508
+ LRS.scormApiType = result.type;
4509
+
4510
+ // Read learner_id for diagnostics
4511
+ var scormLearnerId = 'n/a', scormLearnerName = 'n/a';
4512
+ try {
4513
+ if (result.type === '2004') {
4514
+ scormLearnerId = result.api.GetValue('cmi.learner_id');
4515
+ scormLearnerName = result.api.GetValue('cmi.learner_name');
4516
+ } else {
4517
+ scormLearnerId = result.api.LMSGetValue('cmi.core.student_id');
4518
+ scormLearnerName = result.api.LMSGetValue('cmi.core.student_name');
4519
+ }
4520
+ } catch(e) { scormLearnerId = 'error'; scormLearnerName = 'error'; }
4521
+ console.info('[PA-LRS] SCORM API found (poll ' + pollNum + ', source=' + result.source +
4522
+ ', type=' + result.type + '): learner_id=' + scormLearnerId + ', learner_name=' + scormLearnerName);
4523
+
4524
+ // refreshActor re-reads learner_id from SCORM and runs employee lookup
4525
+ LRS.refreshActor(function(refreshedActor) {
4526
+ if (window.console && window.console.info) {
4527
+ console.info('[PA-LRS] Actor resolved (after SCORM wait, poll ' + pollNum + '): name=' +
4528
+ (refreshedActor ? refreshedActor.name : 'none') +
4529
+ ', mbox=' + (refreshedActor ? refreshedActor.mbox : 'none') +
4530
+ ', account=' + (refreshedActor && refreshedActor.account ? refreshedActor.account.name : 'none'));
4531
+ }
4532
+ actorReady = true;
4533
+ tryLaunchEvents();
4534
+ });
4535
+ }
4457
4536
 
4458
4537
  var scormPollTimer = setInterval(function() {
4538
+ if (scormResolved) { clearInterval(scormPollTimer); return; }
4459
4539
  scormPollCount++;
4460
4540
 
4461
- // Search parent frames for SCORM API (not just current window)
4462
- var api2004 = findAPIInFrameHierarchy('API_1484_11', 10);
4463
- var api12 = !api2004 ? findAPIInFrameHierarchy('API', 10) : null;
4464
- var foundApi = api2004 || api12;
4541
+ var result = findScormApiAnywhere();
4465
4542
 
4466
- if (foundApi) {
4543
+ if (result) {
4467
4544
  clearInterval(scormPollTimer);
4468
- var foundType = api2004 ? '2004' : '1.2';
4469
- log('SCORM API found on poll ' + scormPollCount + ' at level ' + foundApi.level);
4470
-
4471
- // Update LRS SCORM API reference
4472
- if (!LRS.scormApi) {
4473
- LRS.scormApi = foundApi.api;
4474
- LRS.scormApiFound = true;
4475
- LRS.scormApiType = foundType;
4476
- }
4477
-
4478
- // Read learner_id right now for diagnostics
4479
- var scormLearnerId = 'n/a', scormLearnerName = 'n/a';
4480
- try {
4481
- if (foundType === '2004') {
4482
- scormLearnerId = foundApi.api.GetValue('cmi.learner_id');
4483
- scormLearnerName = foundApi.api.GetValue('cmi.learner_name');
4484
- } else {
4485
- scormLearnerId = foundApi.api.LMSGetValue('cmi.core.student_id');
4486
- scormLearnerName = foundApi.api.LMSGetValue('cmi.core.student_name');
4487
- }
4488
- } catch(e) { scormLearnerId = 'error'; scormLearnerName = 'error'; }
4489
- console.info('[PA-LRS] SCORM API found (poll ' + scormPollCount + ', type=' + foundType +
4490
- ', level=' + foundApi.level + '): learner_id=' + scormLearnerId + ', learner_name=' + scormLearnerName);
4491
-
4492
- // refreshActor re-reads learner_id from SCORM and runs employee lookup
4493
- LRS.refreshActor(function(refreshedActor) {
4494
- if (window.console && window.console.info) {
4495
- console.info('[PA-LRS] Actor resolved (after SCORM wait, poll ' + scormPollCount + '): name=' +
4496
- (refreshedActor ? refreshedActor.name : 'none') +
4497
- ', mbox=' + (refreshedActor ? refreshedActor.mbox : 'none') +
4498
- ', account=' + (refreshedActor && refreshedActor.account ? refreshedActor.account.name : 'none'));
4499
- }
4500
- actorReady = true;
4501
- tryLaunchEvents();
4502
- });
4545
+ onScormApiFound(result, scormPollCount);
4503
4546
  } else if (scormPollCount >= scormMaxPolls) {
4504
4547
  clearInterval(scormPollTimer);
4505
4548
  log('SCORM API not found after ' + scormMaxPolls + 's, proceeding with Unknown Learner');
4506
4549
  if (window.console && window.console.info) {
4507
- console.info('[PA-LRS] Actor resolved (timeout): name=' + (actor ? actor.name : 'none') +
4550
+ console.info('[PA-LRS] Actor resolved (timeout ' + scormMaxPolls + 's): name=' + (actor ? actor.name : 'none') +
4508
4551
  ', account=' + (actor && actor.account ? actor.account.name : 'none'));
4509
4552
  }
4510
4553
  actorReady = true;