@patch-adams/core 1.4.19 → 1.4.21

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.d.cts CHANGED
@@ -32,6 +32,8 @@ declare const LrsBridgeConfigSchema: z.ZodObject<{
32
32
  lrsAuth: z.ZodOptional<z.ZodString>;
33
33
  /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
34
34
  lrsProxyEndpoint: z.ZodOptional<z.ZodString>;
35
+ /** Employee API endpoint URL for user identity lookup (e.g., https://node.example.com/admin_api/users/employees/) */
36
+ employeeApiEndpoint: z.ZodOptional<z.ZodString>;
35
37
  }, "strip", z.ZodTypeAny, {
36
38
  enabled: boolean;
37
39
  trackMedia: boolean;
@@ -46,6 +48,7 @@ declare const LrsBridgeConfigSchema: z.ZodObject<{
46
48
  courseHomepage?: string | undefined;
47
49
  lrsAuth?: string | undefined;
48
50
  lrsProxyEndpoint?: string | undefined;
51
+ employeeApiEndpoint?: string | undefined;
49
52
  }, {
50
53
  enabled?: boolean | undefined;
51
54
  trackMedia?: boolean | undefined;
@@ -60,6 +63,7 @@ declare const LrsBridgeConfigSchema: z.ZodObject<{
60
63
  autoDetectLrs?: boolean | undefined;
61
64
  lrsAuth?: string | undefined;
62
65
  lrsProxyEndpoint?: string | undefined;
66
+ employeeApiEndpoint?: string | undefined;
63
67
  }>;
64
68
  /**
65
69
  * Configuration for a blocking asset (CSS before, JS before)
@@ -227,6 +231,8 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
227
231
  lrsAuth: z.ZodOptional<z.ZodString>;
228
232
  /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
229
233
  lrsProxyEndpoint: z.ZodOptional<z.ZodString>;
234
+ /** Employee API endpoint URL for user identity lookup (e.g., https://node.example.com/admin_api/users/employees/) */
235
+ employeeApiEndpoint: z.ZodOptional<z.ZodString>;
230
236
  }, "strip", z.ZodTypeAny, {
231
237
  enabled: boolean;
232
238
  trackMedia: boolean;
@@ -241,6 +247,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
241
247
  courseHomepage?: string | undefined;
242
248
  lrsAuth?: string | undefined;
243
249
  lrsProxyEndpoint?: string | undefined;
250
+ employeeApiEndpoint?: string | undefined;
244
251
  }, {
245
252
  enabled?: boolean | undefined;
246
253
  trackMedia?: boolean | undefined;
@@ -255,6 +262,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
255
262
  autoDetectLrs?: boolean | undefined;
256
263
  lrsAuth?: string | undefined;
257
264
  lrsProxyEndpoint?: string | undefined;
265
+ employeeApiEndpoint?: string | undefined;
258
266
  }>>;
259
267
  /** Plugin configurations - each plugin is keyed by its name */
260
268
  plugins: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -309,6 +317,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
309
317
  courseHomepage?: string | undefined;
310
318
  lrsAuth?: string | undefined;
311
319
  lrsProxyEndpoint?: string | undefined;
320
+ employeeApiEndpoint?: string | undefined;
312
321
  };
313
322
  plugins: Record<string, z.objectOutputType<{
314
323
  /** Whether this plugin is enabled */
@@ -356,6 +365,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
356
365
  autoDetectLrs?: boolean | undefined;
357
366
  lrsAuth?: string | undefined;
358
367
  lrsProxyEndpoint?: string | undefined;
368
+ employeeApiEndpoint?: string | undefined;
359
369
  } | undefined;
360
370
  plugins?: Record<string, z.objectInputType<{
361
371
  /** Whether this plugin is enabled */
package/dist/index.d.ts CHANGED
@@ -32,6 +32,8 @@ declare const LrsBridgeConfigSchema: z.ZodObject<{
32
32
  lrsAuth: z.ZodOptional<z.ZodString>;
33
33
  /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
34
34
  lrsProxyEndpoint: z.ZodOptional<z.ZodString>;
35
+ /** Employee API endpoint URL for user identity lookup (e.g., https://node.example.com/admin_api/users/employees/) */
36
+ employeeApiEndpoint: z.ZodOptional<z.ZodString>;
35
37
  }, "strip", z.ZodTypeAny, {
36
38
  enabled: boolean;
37
39
  trackMedia: boolean;
@@ -46,6 +48,7 @@ declare const LrsBridgeConfigSchema: z.ZodObject<{
46
48
  courseHomepage?: string | undefined;
47
49
  lrsAuth?: string | undefined;
48
50
  lrsProxyEndpoint?: string | undefined;
51
+ employeeApiEndpoint?: string | undefined;
49
52
  }, {
50
53
  enabled?: boolean | undefined;
51
54
  trackMedia?: boolean | undefined;
@@ -60,6 +63,7 @@ declare const LrsBridgeConfigSchema: z.ZodObject<{
60
63
  autoDetectLrs?: boolean | undefined;
61
64
  lrsAuth?: string | undefined;
62
65
  lrsProxyEndpoint?: string | undefined;
66
+ employeeApiEndpoint?: string | undefined;
63
67
  }>;
64
68
  /**
65
69
  * Configuration for a blocking asset (CSS before, JS before)
@@ -227,6 +231,8 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
227
231
  lrsAuth: z.ZodOptional<z.ZodString>;
228
232
  /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
229
233
  lrsProxyEndpoint: z.ZodOptional<z.ZodString>;
234
+ /** Employee API endpoint URL for user identity lookup (e.g., https://node.example.com/admin_api/users/employees/) */
235
+ employeeApiEndpoint: z.ZodOptional<z.ZodString>;
230
236
  }, "strip", z.ZodTypeAny, {
231
237
  enabled: boolean;
232
238
  trackMedia: boolean;
@@ -241,6 +247,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
241
247
  courseHomepage?: string | undefined;
242
248
  lrsAuth?: string | undefined;
243
249
  lrsProxyEndpoint?: string | undefined;
250
+ employeeApiEndpoint?: string | undefined;
244
251
  }, {
245
252
  enabled?: boolean | undefined;
246
253
  trackMedia?: boolean | undefined;
@@ -255,6 +262,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
255
262
  autoDetectLrs?: boolean | undefined;
256
263
  lrsAuth?: string | undefined;
257
264
  lrsProxyEndpoint?: string | undefined;
265
+ employeeApiEndpoint?: string | undefined;
258
266
  }>>;
259
267
  /** Plugin configurations - each plugin is keyed by its name */
260
268
  plugins: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -309,6 +317,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
309
317
  courseHomepage?: string | undefined;
310
318
  lrsAuth?: string | undefined;
311
319
  lrsProxyEndpoint?: string | undefined;
320
+ employeeApiEndpoint?: string | undefined;
312
321
  };
313
322
  plugins: Record<string, z.objectOutputType<{
314
323
  /** Whether this plugin is enabled */
@@ -356,6 +365,7 @@ declare const PatchAdamsConfigSchema: z.ZodObject<{
356
365
  autoDetectLrs?: boolean | undefined;
357
366
  lrsAuth?: string | undefined;
358
367
  lrsProxyEndpoint?: string | undefined;
368
+ employeeApiEndpoint?: string | undefined;
359
369
  } | undefined;
360
370
  plugins?: Record<string, z.objectInputType<{
361
371
  /** Whether this plugin is enabled */
package/dist/index.js CHANGED
@@ -35,7 +35,9 @@ var LrsBridgeConfigSchema = z.object({
35
35
  /** Basic auth credentials for LRS (Base64 encoded "username:password") - used when no cookie session exists */
36
36
  lrsAuth: z.string().optional(),
37
37
  /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
38
- lrsProxyEndpoint: z.string().optional()
38
+ lrsProxyEndpoint: z.string().optional(),
39
+ /** Employee API endpoint URL for user identity lookup (e.g., https://node.example.com/admin_api/users/employees/) */
40
+ employeeApiEndpoint: z.string().optional()
39
41
  });
40
42
  var BlockingAssetConfigSchema = z.object({
41
43
  /** Filename for the asset */
@@ -1270,12 +1272,32 @@ function generateLrsBridgeCode(options) {
1270
1272
  return;
1271
1273
  }
1272
1274
 
1273
- // Cache check
1275
+ // In-memory cache check
1274
1276
  if (employeeLookupFetched && employeeLookupData) {
1275
1277
  callback(employeeLookupData);
1276
1278
  return;
1277
1279
  }
1278
1280
 
1281
+ // localStorage cache check (persists across page loads / sessions)
1282
+ var cacheKey = 'pa_employee_' + employeeId;
1283
+ try {
1284
+ var cached = localStorage.getItem(cacheKey);
1285
+ if (cached) {
1286
+ var parsed = JSON.parse(cached);
1287
+ // TTL: 7 days = 604800000 ms
1288
+ if (parsed.timestamp && (Date.now() - parsed.timestamp) < 604800000) {
1289
+ log('Employee data from localStorage cache');
1290
+ employeeLookupData = parsed;
1291
+ employeeLookupFetched = true;
1292
+ callback(parsed);
1293
+ return;
1294
+ }
1295
+ localStorage.removeItem(cacheKey);
1296
+ }
1297
+ } catch (e) {
1298
+ // localStorage unavailable (private browsing, iframe restrictions)
1299
+ }
1300
+
1279
1301
  // Build URL: endpoint should end with ? or include query param structure
1280
1302
  var apiUrl = EMPLOYEE_API_ENDPOINT + (EMPLOYEE_API_ENDPOINT.indexOf('?') >= 0 ? '&' : '?') + 'q=' + encodeURIComponent(employeeId);
1281
1303
  log('Fetching employee data from:', apiUrl);
@@ -1307,6 +1329,14 @@ function generateLrsBridgeCode(options) {
1307
1329
  employeeId: employee.emp_id || employee.employeeId || employee.employee_id || employeeId
1308
1330
  };
1309
1331
  log('Parsed employee data:', employeeLookupData);
1332
+ // Persist to localStorage for cross-session caching
1333
+ try {
1334
+ var cacheData = {};
1335
+ for (var k in employeeLookupData) { if (employeeLookupData.hasOwnProperty(k)) cacheData[k] = employeeLookupData[k]; }
1336
+ cacheData.timestamp = Date.now();
1337
+ localStorage.setItem(cacheKey, JSON.stringify(cacheData));
1338
+ log('Employee data cached in localStorage');
1339
+ } catch (e) { /* localStorage unavailable */ }
1310
1340
  callback(employeeLookupData);
1311
1341
  } else {
1312
1342
  callback(null);
@@ -3251,6 +3281,34 @@ function generateLrsBridgeCode(options) {
3251
3281
  sendStatement(statement);
3252
3282
  };
3253
3283
 
3284
+ /**
3285
+ * Re-extract actor from SCORM after LMSInitialize has been called.
3286
+ * Call this from the SCORM wrapper after scormInit() succeeds,
3287
+ * because the bridge initializes in <head> before LMSInitialize runs.
3288
+ */
3289
+ LRS.refreshActor = function(callback) {
3290
+ log('refreshActor called - re-extracting from SCORM...');
3291
+ var previousName = LRS.actor ? LRS.actor.name : 'none';
3292
+
3293
+ // Re-run sync extraction (SCORM data should now be available)
3294
+ var newActor = extractActor();
3295
+
3296
+ if (isValidActor(newActor) && newActor.account && newActor.account.name !== 'unknown') {
3297
+ log('refreshActor: got valid actor:', newActor.name, newActor.account ? newActor.account.name : '');
3298
+ // Enhance with email lookup (async)
3299
+ extractActorAsync(function(enhancedActor) {
3300
+ if (window.console && window.console.info) {
3301
+ console.info('[PA-LRS] Actor refreshed: ' + previousName + ' -> ' + enhancedActor.name +
3302
+ (enhancedActor.mbox ? ' (' + enhancedActor.mbox + ')' : ''));
3303
+ }
3304
+ if (callback) callback(enhancedActor);
3305
+ });
3306
+ } else {
3307
+ log('refreshActor: no valid actor found after re-extraction');
3308
+ if (callback) callback(LRS.actor);
3309
+ }
3310
+ };
3311
+
3254
3312
  // Course terminated/exited
3255
3313
  LRS.courseTerminated = function() {
3256
3314
  // Calculate duration
@@ -4255,7 +4313,8 @@ function buildJsBeforeOptions(config, metadata) {
4255
4313
  courseHomepage: lrsBridgeConfig.courseHomepage,
4256
4314
  autoDetectLrs: lrsBridgeConfig.autoDetectLrs,
4257
4315
  lrsAuth: lrsBridgeConfig.lrsAuth,
4258
- lrsProxyEndpoint: lrsBridgeConfig.lrsProxyEndpoint
4316
+ lrsProxyEndpoint: lrsBridgeConfig.lrsProxyEndpoint,
4317
+ employeeApiEndpoint: lrsBridgeConfig.employeeApiEndpoint
4259
4318
  };
4260
4319
  return {
4261
4320
  remoteUrl: `${config.remoteDomain}/${config.localFolders.js}/${config.jsBefore.filename}`,