@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/index.js CHANGED
@@ -4122,58 +4122,101 @@ function generateLrsBridgeCode(options) {
4122
4122
  if (isUnknown) {
4123
4123
  log('Actor is Unknown Learner - SCORM API likely not available yet, polling for it...');
4124
4124
  var scormPollCount = 0;
4125
- var scormMaxPolls = 20; // wait up to 20 seconds
4125
+ var scormMaxPolls = 30; // wait up to 30 seconds
4126
+ var scormResolved = false;
4127
+
4128
+ // Helper: search all possible locations for SCORM API
4129
+ function findScormApiAnywhere() {
4130
+ // 1. Search parent frame hierarchy (standard approach)
4131
+ var api2004 = findAPIInFrameHierarchy('API_1484_11', 10);
4132
+ if (api2004) return { api: api2004.api, type: '2004', source: 'parent-chain level ' + api2004.level };
4133
+ var api12 = findAPIInFrameHierarchy('API', 10);
4134
+ if (api12) return { api: api12.api, type: '1.2', source: 'parent-chain level ' + api12.level };
4135
+
4136
+ // 2. Check window.opener and its parent hierarchy (LMS opens content in popup)
4137
+ try {
4138
+ if (window.opener && window.opener !== window) {
4139
+ // Direct check on opener
4140
+ if (window.opener.API_1484_11) return { api: window.opener.API_1484_11, type: '2004', source: 'window.opener' };
4141
+ if (window.opener.API) return { api: window.opener.API, type: '1.2', source: 'window.opener' };
4142
+ // Check opener's parent chain
4143
+ var openerWin = window.opener;
4144
+ var openerLevel = 0;
4145
+ while (openerLevel < 10) {
4146
+ try {
4147
+ if (openerWin.API_1484_11) return { api: openerWin.API_1484_11, type: '2004', source: 'opener-chain level ' + openerLevel };
4148
+ if (openerWin.API) return { api: openerWin.API, type: '1.2', source: 'opener-chain level ' + openerLevel };
4149
+ if (openerWin.parent && openerWin.parent !== openerWin) { openerWin = openerWin.parent; openerLevel++; }
4150
+ else break;
4151
+ } catch(e) { break; }
4152
+ }
4153
+ }
4154
+ } catch(e) { /* cross-origin opener */ }
4155
+
4156
+ // 3. Check for global LMS functions (Bravais/Xyleme mock API)
4157
+ try {
4158
+ if (typeof window.LMSInitialize === 'function') {
4159
+ 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' };
4160
+ }
4161
+ } catch(e) {}
4162
+ try {
4163
+ if (window.parent && window.parent !== window && typeof window.parent.LMSInitialize === 'function') {
4164
+ 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' };
4165
+ }
4166
+ } catch(e) {}
4167
+
4168
+ return null;
4169
+ }
4170
+
4171
+ function onScormApiFound(result, pollNum) {
4172
+ if (scormResolved) return;
4173
+ scormResolved = true;
4174
+
4175
+ LRS.scormApi = result.api;
4176
+ LRS.scormApiFound = true;
4177
+ LRS.scormApiType = result.type;
4178
+
4179
+ // Read learner_id for diagnostics
4180
+ var scormLearnerId = 'n/a', scormLearnerName = 'n/a';
4181
+ try {
4182
+ if (result.type === '2004') {
4183
+ scormLearnerId = result.api.GetValue('cmi.learner_id');
4184
+ scormLearnerName = result.api.GetValue('cmi.learner_name');
4185
+ } else {
4186
+ scormLearnerId = result.api.LMSGetValue('cmi.core.student_id');
4187
+ scormLearnerName = result.api.LMSGetValue('cmi.core.student_name');
4188
+ }
4189
+ } catch(e) { scormLearnerId = 'error'; scormLearnerName = 'error'; }
4190
+ console.info('[PA-LRS] SCORM API found (poll ' + pollNum + ', source=' + result.source +
4191
+ ', type=' + result.type + '): learner_id=' + scormLearnerId + ', learner_name=' + scormLearnerName);
4192
+
4193
+ // refreshActor re-reads learner_id from SCORM and runs employee lookup
4194
+ LRS.refreshActor(function(refreshedActor) {
4195
+ if (window.console && window.console.info) {
4196
+ console.info('[PA-LRS] Actor resolved (after SCORM wait, poll ' + pollNum + '): name=' +
4197
+ (refreshedActor ? refreshedActor.name : 'none') +
4198
+ ', mbox=' + (refreshedActor ? refreshedActor.mbox : 'none') +
4199
+ ', account=' + (refreshedActor && refreshedActor.account ? refreshedActor.account.name : 'none'));
4200
+ }
4201
+ actorReady = true;
4202
+ tryLaunchEvents();
4203
+ });
4204
+ }
4126
4205
 
4127
4206
  var scormPollTimer = setInterval(function() {
4207
+ if (scormResolved) { clearInterval(scormPollTimer); return; }
4128
4208
  scormPollCount++;
4129
4209
 
4130
- // Search parent frames for SCORM API (not just current window)
4131
- var api2004 = findAPIInFrameHierarchy('API_1484_11', 10);
4132
- var api12 = !api2004 ? findAPIInFrameHierarchy('API', 10) : null;
4133
- var foundApi = api2004 || api12;
4210
+ var result = findScormApiAnywhere();
4134
4211
 
4135
- if (foundApi) {
4212
+ if (result) {
4136
4213
  clearInterval(scormPollTimer);
4137
- var foundType = api2004 ? '2004' : '1.2';
4138
- log('SCORM API found on poll ' + scormPollCount + ' at level ' + foundApi.level);
4139
-
4140
- // Update LRS SCORM API reference
4141
- if (!LRS.scormApi) {
4142
- LRS.scormApi = foundApi.api;
4143
- LRS.scormApiFound = true;
4144
- LRS.scormApiType = foundType;
4145
- }
4146
-
4147
- // Read learner_id right now for diagnostics
4148
- var scormLearnerId = 'n/a', scormLearnerName = 'n/a';
4149
- try {
4150
- if (foundType === '2004') {
4151
- scormLearnerId = foundApi.api.GetValue('cmi.learner_id');
4152
- scormLearnerName = foundApi.api.GetValue('cmi.learner_name');
4153
- } else {
4154
- scormLearnerId = foundApi.api.LMSGetValue('cmi.core.student_id');
4155
- scormLearnerName = foundApi.api.LMSGetValue('cmi.core.student_name');
4156
- }
4157
- } catch(e) { scormLearnerId = 'error'; scormLearnerName = 'error'; }
4158
- console.info('[PA-LRS] SCORM API found (poll ' + scormPollCount + ', type=' + foundType +
4159
- ', level=' + foundApi.level + '): learner_id=' + scormLearnerId + ', learner_name=' + scormLearnerName);
4160
-
4161
- // refreshActor re-reads learner_id from SCORM and runs employee lookup
4162
- LRS.refreshActor(function(refreshedActor) {
4163
- if (window.console && window.console.info) {
4164
- console.info('[PA-LRS] Actor resolved (after SCORM wait, poll ' + scormPollCount + '): name=' +
4165
- (refreshedActor ? refreshedActor.name : 'none') +
4166
- ', mbox=' + (refreshedActor ? refreshedActor.mbox : 'none') +
4167
- ', account=' + (refreshedActor && refreshedActor.account ? refreshedActor.account.name : 'none'));
4168
- }
4169
- actorReady = true;
4170
- tryLaunchEvents();
4171
- });
4214
+ onScormApiFound(result, scormPollCount);
4172
4215
  } else if (scormPollCount >= scormMaxPolls) {
4173
4216
  clearInterval(scormPollTimer);
4174
4217
  log('SCORM API not found after ' + scormMaxPolls + 's, proceeding with Unknown Learner');
4175
4218
  if (window.console && window.console.info) {
4176
- console.info('[PA-LRS] Actor resolved (timeout): name=' + (actor ? actor.name : 'none') +
4219
+ console.info('[PA-LRS] Actor resolved (timeout ' + scormMaxPolls + 's): name=' + (actor ? actor.name : 'none') +
4177
4220
  ', account=' + (actor && actor.account ? actor.account.name : 'none'));
4178
4221
  }
4179
4222
  actorReady = true;