@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.cjs CHANGED
@@ -4462,58 +4462,101 @@ function generateLrsBridgeCode(options) {
4462
4462
  if (isUnknown) {
4463
4463
  log('Actor is Unknown Learner - SCORM API likely not available yet, polling for it...');
4464
4464
  var scormPollCount = 0;
4465
- var scormMaxPolls = 20; // wait up to 20 seconds
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
+ }
4466
4545
 
4467
4546
  var scormPollTimer = setInterval(function() {
4547
+ if (scormResolved) { clearInterval(scormPollTimer); return; }
4468
4548
  scormPollCount++;
4469
4549
 
4470
- // Search parent frames for SCORM API (not just current window)
4471
- var api2004 = findAPIInFrameHierarchy('API_1484_11', 10);
4472
- var api12 = !api2004 ? findAPIInFrameHierarchy('API', 10) : null;
4473
- var foundApi = api2004 || api12;
4550
+ var result = findScormApiAnywhere();
4474
4551
 
4475
- if (foundApi) {
4552
+ if (result) {
4476
4553
  clearInterval(scormPollTimer);
4477
- var foundType = api2004 ? '2004' : '1.2';
4478
- log('SCORM API found on poll ' + scormPollCount + ' at level ' + foundApi.level);
4479
-
4480
- // Update LRS SCORM API reference
4481
- if (!LRS.scormApi) {
4482
- LRS.scormApi = foundApi.api;
4483
- LRS.scormApiFound = true;
4484
- LRS.scormApiType = foundType;
4485
- }
4486
-
4487
- // Read learner_id right now for diagnostics
4488
- var scormLearnerId = 'n/a', scormLearnerName = 'n/a';
4489
- try {
4490
- if (foundType === '2004') {
4491
- scormLearnerId = foundApi.api.GetValue('cmi.learner_id');
4492
- scormLearnerName = foundApi.api.GetValue('cmi.learner_name');
4493
- } else {
4494
- scormLearnerId = foundApi.api.LMSGetValue('cmi.core.student_id');
4495
- scormLearnerName = foundApi.api.LMSGetValue('cmi.core.student_name');
4496
- }
4497
- } catch(e) { scormLearnerId = 'error'; scormLearnerName = 'error'; }
4498
- console.info('[PA-LRS] SCORM API found (poll ' + scormPollCount + ', type=' + foundType +
4499
- ', level=' + foundApi.level + '): learner_id=' + scormLearnerId + ', learner_name=' + scormLearnerName);
4500
-
4501
- // refreshActor re-reads learner_id from SCORM and runs employee lookup
4502
- LRS.refreshActor(function(refreshedActor) {
4503
- if (window.console && window.console.info) {
4504
- console.info('[PA-LRS] Actor resolved (after SCORM wait, poll ' + scormPollCount + '): name=' +
4505
- (refreshedActor ? refreshedActor.name : 'none') +
4506
- ', mbox=' + (refreshedActor ? refreshedActor.mbox : 'none') +
4507
- ', account=' + (refreshedActor && refreshedActor.account ? refreshedActor.account.name : 'none'));
4508
- }
4509
- actorReady = true;
4510
- tryLaunchEvents();
4511
- });
4554
+ onScormApiFound(result, scormPollCount);
4512
4555
  } else if (scormPollCount >= scormMaxPolls) {
4513
4556
  clearInterval(scormPollTimer);
4514
4557
  log('SCORM API not found after ' + scormMaxPolls + 's, proceeding with Unknown Learner');
4515
4558
  if (window.console && window.console.info) {
4516
- console.info('[PA-LRS] Actor resolved (timeout): name=' + (actor ? actor.name : 'none') +
4559
+ console.info('[PA-LRS] Actor resolved (timeout ' + scormMaxPolls + 's): name=' + (actor ? actor.name : 'none') +
4517
4560
  ', account=' + (actor && actor.account ? actor.account.name : 'none'));
4518
4561
  }
4519
4562
  actorReady = true;