@naylence/runtime 0.3.6 → 0.3.7

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.
Files changed (71) hide show
  1. package/dist/browser/index.cjs +220 -172
  2. package/dist/browser/index.mjs +220 -173
  3. package/dist/cjs/_env-shim.js +2 -1
  4. package/dist/cjs/naylence/fame/config/extended-fame-config.js +2 -1
  5. package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -4
  6. package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +14 -6
  7. package/dist/cjs/naylence/fame/connector/broadcast-channel-listener-factory.js +3 -1
  8. package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +11 -7
  9. package/dist/cjs/naylence/fame/connector/index.js +2 -1
  10. package/dist/cjs/naylence/fame/connector/inpage-connector-factory.js +2 -1
  11. package/dist/cjs/naylence/fame/connector/inpage-connector.js +13 -6
  12. package/dist/cjs/naylence/fame/connector/inpage-listener-factory.js +4 -4
  13. package/dist/cjs/naylence/fame/connector/inpage-listener.js +5 -2
  14. package/dist/cjs/naylence/fame/delivery/default-delivery-tracker.js +4 -62
  15. package/dist/cjs/naylence/fame/grants/broadcast-channel-connection-grant.js +6 -3
  16. package/dist/cjs/naylence/fame/grants/inpage-connection-grant.js +4 -2
  17. package/dist/cjs/naylence/fame/http/oauth2-token-router.js +9 -9
  18. package/dist/cjs/naylence/fame/node/admission/default-node-attach-client.js +34 -5
  19. package/dist/cjs/naylence/fame/node/upstream-session-manager.js +40 -8
  20. package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +10 -6
  21. package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider.js +1 -2
  22. package/dist/cjs/naylence/fame/security/default-security-manager.js +2 -1
  23. package/dist/cjs/naylence/fame/security/trust-store/noop-trust-store-provider-factory.js +2 -2
  24. package/dist/cjs/naylence/fame/security/trust-store/trust-store-provider-factory.js +2 -2
  25. package/dist/cjs/naylence/fame/util/index.js +3 -1
  26. package/dist/cjs/node.js +4 -1
  27. package/dist/cjs/version.js +2 -2
  28. package/dist/esm/_env-shim.js +2 -1
  29. package/dist/esm/browser.js +2 -2
  30. package/dist/esm/naylence/fame/config/extended-fame-config.js +2 -1
  31. package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -4
  32. package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +14 -6
  33. package/dist/esm/naylence/fame/connector/broadcast-channel-listener-factory.js +3 -1
  34. package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +11 -7
  35. package/dist/esm/naylence/fame/connector/index.js +2 -2
  36. package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +2 -1
  37. package/dist/esm/naylence/fame/connector/inpage-connector.js +13 -6
  38. package/dist/esm/naylence/fame/connector/inpage-listener-factory.js +4 -4
  39. package/dist/esm/naylence/fame/connector/inpage-listener.js +5 -2
  40. package/dist/esm/naylence/fame/delivery/default-delivery-tracker.js +4 -62
  41. package/dist/esm/naylence/fame/grants/broadcast-channel-connection-grant.js +6 -3
  42. package/dist/esm/naylence/fame/grants/inpage-connection-grant.js +4 -2
  43. package/dist/esm/naylence/fame/http/oauth2-token-router.js +9 -9
  44. package/dist/esm/naylence/fame/node/admission/default-node-attach-client.js +34 -5
  45. package/dist/esm/naylence/fame/node/upstream-session-manager.js +40 -8
  46. package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +10 -6
  47. package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider.js +1 -2
  48. package/dist/esm/naylence/fame/security/default-security-manager.js +2 -1
  49. package/dist/esm/naylence/fame/security/index.js +1 -1
  50. package/dist/esm/naylence/fame/security/trust-store/noop-trust-store-provider-factory.js +3 -3
  51. package/dist/esm/naylence/fame/security/trust-store/trust-store-provider-factory.js +3 -3
  52. package/dist/esm/naylence/fame/util/index.js +1 -0
  53. package/dist/esm/node.js +2 -1
  54. package/dist/esm/version.js +2 -2
  55. package/dist/node/index.cjs +218 -171
  56. package/dist/node/index.mjs +218 -172
  57. package/dist/node/node.cjs +184 -136
  58. package/dist/node/node.mjs +183 -137
  59. package/dist/types/browser.d.ts +2 -2
  60. package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +1 -0
  61. package/dist/types/naylence/fame/connector/index.d.ts +3 -3
  62. package/dist/types/naylence/fame/delivery/default-delivery-tracker.d.ts +0 -6
  63. package/dist/types/naylence/fame/node/admission/default-node-attach-client.d.ts +1 -0
  64. package/dist/types/naylence/fame/security/index.d.ts +1 -1
  65. package/dist/types/naylence/fame/security/trust-store/noop-trust-store-provider-factory.d.ts +3 -3
  66. package/dist/types/naylence/fame/security/trust-store/trust-store-provider-factory.d.ts +4 -4
  67. package/dist/types/naylence/fame/security/trust-store/trust-store-provider.d.ts +5 -5
  68. package/dist/types/naylence/fame/util/index.d.ts +1 -0
  69. package/dist/types/node.d.ts +2 -1
  70. package/dist/types/version.d.ts +1 -1
  71. package/package.json +1 -1
@@ -146,9 +146,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
146
146
  this.ackDoneSince = new Map();
147
147
  this.replyDoneSince = new Map();
148
148
  this.pendingAckDispatches = new Set();
149
- this.recentlyHandled = new Map();
150
- this.recentlyHandledOrder = [];
151
- this.recentlyHandledTtlMs = 60000;
152
149
  this.isPreparingToStop = false;
153
150
  this.shutdownRequestedAtMs = null;
154
151
  this.shutdownRetryGraceMs = 1000;
@@ -384,22 +381,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
384
381
  }
385
382
  }
386
383
  else {
387
- const wasRecentlyHandled = await this.lock.runExclusive(async () => this.wasRecentlyHandled(envelope.id));
388
- if (wasRecentlyHandled) {
389
- logger.debug('tracker_duplicate_envelope_recently_handled', {
390
- envp_id: envelope.id,
391
- });
392
- return new TrackedEnvelope({
393
- timeoutAtMs: 0,
394
- overallTimeoutAtMs: 0,
395
- expectedResponseType: envelope.rtype ?? FameResponseType.NONE,
396
- createdAtMs: Date.now(),
397
- status: EnvelopeStatus.HANDLED,
398
- mailboxType: MailboxType.INBOX,
399
- originalEnvelope: envelope,
400
- serviceName: inboxName,
401
- });
402
- }
403
384
  tracked = new TrackedEnvelope({
404
385
  timeoutAtMs: 0,
405
386
  overallTimeoutAtMs: 0,
@@ -421,12 +402,8 @@ export class DefaultDeliveryTracker extends TaskSpawner {
421
402
  async onEnvelopeHandled(envelope) {
422
403
  const inbox = this.ensureInbox();
423
404
  envelope.status = EnvelopeStatus.HANDLED;
405
+ // Delete the envelope from inbox to prevent growth
424
406
  await inbox.delete(envelope.originalEnvelope.id);
425
- await this.lock.runExclusive(async () => {
426
- this.markRecentlyHandled(envelope.originalEnvelope.id);
427
- });
428
- // Preserve handled envelope to prevent duplicate redelivery during shutdown drains.
429
- // await inbox.set(envelope.originalEnvelope.id, envelope);
430
407
  }
431
408
  async onEnvelopeHandleFailed(inboxName, envelope, context, error, isFinalFailure = false) {
432
409
  void context;
@@ -645,9 +622,9 @@ export class DefaultDeliveryTracker extends TaskSpawner {
645
622
  });
646
623
  await this.markDoneSince(this.replyFutures, trackedEnvelope.originalEnvelope.id, this.replyDoneSince);
647
624
  await this.markDoneSince(this.ackFutures, trackedEnvelope.originalEnvelope.id, this.ackDoneSince);
648
- if (envelope.rtype && Boolean(envelope.rtype & FameResponseType.ACK)) {
649
- await this.sendAck(envelope);
650
- }
625
+ // Note: ACK is already sent in onCorrelatedMessage (lines 655-657)
626
+ // when the reply envelope is first delivered. No need to send it again here.
627
+ // Removing this duplicate sendAck call fixes the duplicate DeliveryAck bug.
651
628
  for (const handler of this.eventHandlers) {
652
629
  await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
653
630
  }
@@ -797,8 +774,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
797
774
  }
798
775
  this.streamDone.clear();
799
776
  this.correlationToEnvelope.clear();
800
- this.recentlyHandled.clear();
801
- this.recentlyHandledOrder.length = 0;
802
777
  return values;
803
778
  });
804
779
  for (const timer of timers) {
@@ -1380,39 +1355,6 @@ export class DefaultDeliveryTracker extends TaskSpawner {
1380
1355
  this.pendingAckDispatches.delete(ackDispatch);
1381
1356
  }
1382
1357
  }
1383
- markRecentlyHandled(envelopeId) {
1384
- const now = Date.now();
1385
- this.recentlyHandled.set(envelopeId, now);
1386
- this.recentlyHandledOrder.push(envelopeId);
1387
- this.trimRecentlyHandled(now);
1388
- }
1389
- wasRecentlyHandled(envelopeId) {
1390
- const now = Date.now();
1391
- const timestamp = this.recentlyHandled.get(envelopeId);
1392
- if (timestamp === undefined) {
1393
- return false;
1394
- }
1395
- if (now - timestamp > this.recentlyHandledTtlMs) {
1396
- this.recentlyHandled.delete(envelopeId);
1397
- return false;
1398
- }
1399
- return true;
1400
- }
1401
- trimRecentlyHandled(now) {
1402
- while (this.recentlyHandledOrder.length > 0) {
1403
- const candidate = this.recentlyHandledOrder[0];
1404
- const timestamp = this.recentlyHandled.get(candidate);
1405
- if (timestamp === undefined) {
1406
- this.recentlyHandledOrder.shift();
1407
- continue;
1408
- }
1409
- if (now - timestamp <= this.recentlyHandledTtlMs) {
1410
- break;
1411
- }
1412
- this.recentlyHandled.delete(candidate);
1413
- this.recentlyHandledOrder.shift();
1414
- }
1415
- }
1416
1358
  getShutdownRetryDeferDelay(nowMs) {
1417
1359
  if (!this.isPreparingToStop || this.shutdownRequestedAtMs === null) {
1418
1360
  return null;
@@ -41,14 +41,16 @@ export function normalizeBroadcastChannelConnectionGrant(candidate) {
41
41
  type,
42
42
  purpose,
43
43
  };
44
- const channelValue = candidate.channelName ?? candidate['channel_name'];
44
+ const channelValue = candidate.channelName ??
45
+ candidate['channel_name'];
45
46
  if (channelValue !== undefined) {
46
47
  if (typeof channelValue !== 'string' || channelValue.trim().length === 0) {
47
48
  throw new TypeError('BroadcastChannelConnectionGrant "channelName" must be a non-empty string when provided');
48
49
  }
49
50
  result.channelName = channelValue.trim();
50
51
  }
51
- const inboxValue = candidate.inboxCapacity ?? candidate['inbox_capacity'];
52
+ const inboxValue = candidate.inboxCapacity ??
53
+ candidate['inbox_capacity'];
52
54
  if (inboxValue !== undefined) {
53
55
  if (typeof inboxValue !== 'number' ||
54
56
  !Number.isFinite(inboxValue) ||
@@ -57,7 +59,8 @@ export function normalizeBroadcastChannelConnectionGrant(candidate) {
57
59
  }
58
60
  result.inboxCapacity = Math.floor(inboxValue);
59
61
  }
60
- const windowValue = candidate.initialWindow ?? candidate['initial_window'];
62
+ const windowValue = candidate.initialWindow ??
63
+ candidate['initial_window'];
61
64
  if (windowValue !== undefined) {
62
65
  if (typeof windowValue !== 'number' ||
63
66
  !Number.isFinite(windowValue) ||
@@ -36,14 +36,16 @@ export function normalizeInPageConnectionGrant(candidate) {
36
36
  type,
37
37
  purpose,
38
38
  };
39
- const channelValue = candidate.channelName ?? candidate['channel_name'];
39
+ const channelValue = candidate.channelName ??
40
+ candidate['channel_name'];
40
41
  if (channelValue !== undefined) {
41
42
  if (typeof channelValue !== 'string' || channelValue.trim().length === 0) {
42
43
  throw new TypeError('InPageConnectionGrant "channelName" must be a non-empty string when provided');
43
44
  }
44
45
  result.channelName = channelValue.trim();
45
46
  }
46
- const inboxValue = candidate.inboxCapacity ?? candidate['inbox_capacity'];
47
+ const inboxValue = candidate.inboxCapacity ??
48
+ candidate['inbox_capacity'];
47
49
  if (inboxValue !== undefined) {
48
50
  if (typeof inboxValue !== 'number' ||
49
51
  !Number.isFinite(inboxValue) ||
@@ -419,7 +419,9 @@ function parseCookies(cookieHeader) {
419
419
  if (!cookieHeader) {
420
420
  return {};
421
421
  }
422
- return cookieHeader.split(';').reduce((acc, entry) => {
422
+ return cookieHeader
423
+ .split(';')
424
+ .reduce((acc, entry) => {
423
425
  const [rawName, ...rawValueParts] = entry.split('=');
424
426
  const name = rawName?.trim();
425
427
  if (!name) {
@@ -567,10 +569,7 @@ function setNoCacheHeaders(res) {
567
569
  res.set('Pragma', 'no-cache');
568
570
  }
569
571
  function respondInvalidClient(res) {
570
- res
571
- .status(401)
572
- .set('WWW-Authenticate', 'Basic')
573
- .json({
572
+ res.status(401).set('WWW-Authenticate', 'Basic').json({
574
573
  error: 'invalid_client',
575
574
  error_description: 'Invalid client credentials',
576
575
  });
@@ -607,10 +606,10 @@ export function createOAuth2TokenRouter(options) {
607
606
  DEFAULT_JWT_ALGORITHM;
608
607
  const allowedScopes = getAllowedScopes(configAllowedScopes);
609
608
  const resolvedTokenTtlSec = tokenTtlSec ?? 3600;
610
- const enablePkce = coerceBoolean(process.env[ENV_VAR_ENABLE_PKCE]) ??
611
- (configEnablePkce ?? true);
609
+ const enablePkce = coerceBoolean(process.env[ENV_VAR_ENABLE_PKCE]) ?? configEnablePkce ?? true;
612
610
  const allowPublicClients = coerceBoolean(process.env[ENV_VAR_ALLOW_PUBLIC_CLIENTS]) ??
613
- (configAllowPublicClients ?? true);
611
+ configAllowPublicClients ??
612
+ true;
614
613
  const authorizationCodeTtlSec = ensurePositiveInteger(coerceNumber(process.env[ENV_VAR_AUTHORIZATION_CODE_TTL]) ??
615
614
  configAuthorizationCodeTtlSec) ?? DEFAULT_AUTHORIZATION_CODE_TTL_SEC;
616
615
  const devLoginExplicitlyEnabled = coerceBoolean(process.env[ENV_VAR_ENABLE_DEV_LOGIN]) ??
@@ -625,7 +624,8 @@ export function createOAuth2TokenRouter(options) {
625
624
  configDevLoginCookieName ??
626
625
  DEFAULT_SESSION_COOKIE_NAME;
627
626
  const devLoginSecureCookie = coerceBoolean(process.env[ENV_VAR_SESSION_SECURE_COOKIE]) ??
628
- (configDevLoginSecureCookie ?? false);
627
+ configDevLoginSecureCookie ??
628
+ false;
629
629
  const devLoginTitle = coerceString(process.env[ENV_VAR_LOGIN_TITLE]) ??
630
630
  configDevLoginTitle ??
631
631
  DEFAULT_LOGIN_TITLE;
@@ -8,15 +8,30 @@ export class DefaultNodeAttachClient {
8
8
  constructor(options = {}) {
9
9
  this.buffer = [];
10
10
  this.inHandshake = false;
11
+ this.expectedSystemId = null;
11
12
  this.timeoutMs = options.timeoutMs ?? 10000;
12
13
  this.attachmentKeyValidator = options.attachmentKeyValidator;
13
14
  this.replicaStickinessManager = options.replicaStickinessManager ?? null;
14
15
  }
15
16
  async attach(node, originType, connector, welcomeFrame, finalHandler, keys, callbackGrants) {
16
17
  this.inHandshake = true;
18
+ this.expectedSystemId = welcomeFrame.systemId;
17
19
  const interimHandler = async (envelope, context) => {
18
20
  if (this.inHandshake) {
19
- this.buffer.push(envelope);
21
+ // Filter: only buffer frames related to our systemId or frames without systemId info
22
+ const frameSystemId = envelope.frame
23
+ ?.systemId;
24
+ if (!frameSystemId || frameSystemId === this.expectedSystemId) {
25
+ this.buffer.push(envelope);
26
+ }
27
+ else {
28
+ // Silently ignore frames from other agents during concurrent handshakes
29
+ logger.debug('handshake_ignoring_frame_from_different_system', {
30
+ frame_type: envelope.frame.type,
31
+ frame_system_id: frameSystemId,
32
+ expected_system_id: this.expectedSystemId,
33
+ });
34
+ }
20
35
  return null;
21
36
  }
22
37
  return finalHandler(envelope, context);
@@ -143,6 +158,7 @@ export class DefaultNodeAttachClient {
143
158
  parent_id: ackFrame.targetSystemId,
144
159
  });
145
160
  this.inHandshake = false;
161
+ this.expectedSystemId = null;
146
162
  await connector.replaceHandler(finalHandler);
147
163
  while (this.buffer.length > 0) {
148
164
  const bufferedEnvelope = this.buffer.shift();
@@ -200,7 +216,8 @@ export class DefaultNodeAttachClient {
200
216
  const deadline = Date.now() + this.timeoutMs;
201
217
  while (Date.now() < deadline) {
202
218
  // Allow both STARTED and PAUSED states (PAUSED = tab hidden but connection alive)
203
- if (connector.state !== ConnectorState.STARTED && connector.state !== ConnectorState.PAUSED) {
219
+ if (connector.state !== ConnectorState.STARTED &&
220
+ connector.state !== ConnectorState.PAUSED) {
204
221
  let errorMessage = 'Connector closed while waiting for NodeAttachAck';
205
222
  if (connector.closeCode !== undefined) {
206
223
  errorMessage += ` (code=${connector.closeCode}`;
@@ -219,9 +236,21 @@ export class DefaultNodeAttachClient {
219
236
  if (envelope.frame.type === 'NodeAttachAck') {
220
237
  return envelope;
221
238
  }
222
- logger.error('unexpected_frame_during_handshake', {
223
- frame_type: envelope.frame.type,
224
- });
239
+ // NodeAttach frames during handshake are expected in multi-agent scenarios
240
+ // where multiple agents attach concurrently to the same channel
241
+ if (envelope.frame.type === 'NodeAttach') {
242
+ logger.debug('handshake_ignoring_concurrent_attach', {
243
+ frame_type: envelope.frame.type,
244
+ frame_system_id: envelope.frame?.systemId ??
245
+ 'unknown',
246
+ });
247
+ }
248
+ else {
249
+ // Other unexpected frames are still logged as errors
250
+ logger.error('unexpected_frame_during_handshake', {
251
+ frame_type: envelope.frame.type,
252
+ });
253
+ }
225
254
  }
226
255
  await delay(HANDSHAKE_POLL_INTERVAL_MS);
227
256
  }
@@ -318,25 +318,56 @@ export class UpstreamSessionManager extends TaskSpawner {
318
318
  await connector.start(this.wrappedHandler);
319
319
  this.connector = connector;
320
320
  const callbackGrants = this.node.gatherSupportedCallbackGrants();
321
+ logger.debug('callback_grants_before_augmentation', {
322
+ count: callbackGrants.length,
323
+ types: callbackGrants.map((g) => g.type),
324
+ });
325
+ // Check if we should create a broadcast callback grant before processing connection grants
326
+ // This prevents adding duplicate broadcast grants
327
+ const shouldAddBroadcastGrant = this.shouldAdvertiseBroadcastGrant(grant, callbackGrants);
328
+ const broadcastCallbackGrant = shouldAddBroadcastGrant
329
+ ? this.createBroadcastCallbackGrant(grant)
330
+ : null;
331
+ logger.debug('broadcast_callback_grant_check', {
332
+ should_add: shouldAddBroadcastGrant,
333
+ grant_created: !!broadcastCallbackGrant,
334
+ });
321
335
  // Include admission client's connection grants as callback grants
322
336
  // This ensures DirectAdmissionClient grants are available for grant selection
323
- if (welcome.frame.connectionGrants && Array.isArray(welcome.frame.connectionGrants)) {
337
+ if (welcome.frame.connectionGrants &&
338
+ Array.isArray(welcome.frame.connectionGrants)) {
324
339
  for (const grant of welcome.frame.connectionGrants) {
325
340
  if (grant && typeof grant === 'object') {
326
341
  // Avoid duplicates by checking if grant already exists
327
- const isDuplicate = callbackGrants.some(existing => JSON.stringify(existing) === JSON.stringify(grant));
342
+ const isDuplicate = callbackGrants.some((existing) => JSON.stringify(existing) === JSON.stringify(grant));
328
343
  if (!isDuplicate) {
329
344
  callbackGrants.push(grant);
345
+ logger.debug('added_connection_grant_as_callback', {
346
+ type: grant.type,
347
+ });
348
+ }
349
+ else {
350
+ logger.debug('skipped_duplicate_connection_grant', {
351
+ type: grant.type,
352
+ });
330
353
  }
331
354
  }
332
355
  }
333
356
  }
334
- if (this.shouldAdvertiseBroadcastGrant(grant, callbackGrants)) {
335
- const augmented = this.createBroadcastCallbackGrant(grant);
336
- if (augmented) {
337
- callbackGrants.push(augmented);
338
- }
357
+ // Add broadcast grant after connection grants to ensure we don't duplicate
358
+ // any broadcast grants that may have been in connectionGrants
359
+ if (broadcastCallbackGrant &&
360
+ this.shouldAdvertiseBroadcastGrant(grant, callbackGrants)) {
361
+ callbackGrants.push(broadcastCallbackGrant);
362
+ logger.debug('added_broadcast_callback_grant');
363
+ }
364
+ else if (broadcastCallbackGrant) {
365
+ logger.debug('skipped_duplicate_broadcast_callback_grant');
339
366
  }
367
+ logger.debug('callback_grants_after_augmentation', {
368
+ count: callbackGrants.length,
369
+ types: callbackGrants.map((g) => g.type),
370
+ });
340
371
  const attachInfo = await this.attachClient.attach(this.node, this.outboundOriginType, connector, welcome.frame, this.wrappedHandler, this.getKeys() ?? undefined, callbackGrants);
341
372
  this.targetSystemId = attachInfo.targetSystemId ?? null;
342
373
  if (this.targetSystemId) {
@@ -577,7 +608,8 @@ export class UpstreamSessionManager extends TaskSpawner {
577
608
  continue;
578
609
  }
579
610
  // Reset ack time if just resumed from pause (prevents immediate timeout)
580
- if (previousState === ConnectorState.PAUSED && currentState === ConnectorState.STARTED) {
611
+ if (previousState === ConnectorState.PAUSED &&
612
+ currentState === ConnectorState.STARTED) {
581
613
  logger.debug('connector_just_resumed_resetting_ack_time', {
582
614
  previous_state: previousState,
583
615
  current_state: currentState,
@@ -58,19 +58,23 @@ function normalizeConfig(config) {
58
58
  normalized.clientSecretConfig = normalizeSecretSource(clientSecretSource);
59
59
  }
60
60
  const audienceCandidate = candidate.audience ?? candidate.aud;
61
- if (typeof audienceCandidate === 'string' && audienceCandidate.trim().length > 0) {
61
+ if (typeof audienceCandidate === 'string' &&
62
+ audienceCandidate.trim().length > 0) {
62
63
  normalized.audience = audienceCandidate.trim();
63
64
  }
64
65
  const codeChallengeMethod = candidate.codeChallengeMethod ?? candidate.code_challenge_method;
65
- if (typeof codeChallengeMethod === 'string' && codeChallengeMethod.trim().length > 0) {
66
+ if (typeof codeChallengeMethod === 'string' &&
67
+ codeChallengeMethod.trim().length > 0) {
66
68
  normalized.codeChallengeMethod = codeChallengeMethod.trim();
67
69
  }
68
70
  const codeVerifierLength = candidate.codeVerifierLength ?? candidate.code_verifier_length;
69
- if (typeof codeVerifierLength === 'number' && Number.isFinite(codeVerifierLength)) {
71
+ if (typeof codeVerifierLength === 'number' &&
72
+ Number.isFinite(codeVerifierLength)) {
70
73
  normalized.codeVerifierLength = codeVerifierLength;
71
74
  }
72
75
  const clockSkewSeconds = candidate.clockSkewSeconds ?? candidate.clock_skew_seconds;
73
- if (typeof clockSkewSeconds === 'number' && Number.isFinite(clockSkewSeconds)) {
76
+ if (typeof clockSkewSeconds === 'number' &&
77
+ Number.isFinite(clockSkewSeconds)) {
74
78
  normalized.clockSkewSeconds = clockSkewSeconds;
75
79
  }
76
80
  const loginHintParam = candidate.loginHintParam ?? candidate.login_hint_param;
@@ -115,8 +119,8 @@ export class OAuth2PkceTokenProviderFactory extends TokenProviderFactory {
115
119
  options.audience = normalized.audience;
116
120
  }
117
121
  if (normalized.codeChallengeMethod) {
118
- options.codeChallengeMethod = normalized.codeChallengeMethod
119
- .toUpperCase();
122
+ options.codeChallengeMethod =
123
+ normalized.codeChallengeMethod.toUpperCase();
120
124
  }
121
125
  if (normalized.codeVerifierLength) {
122
126
  options.codeVerifierLength = normalized.codeVerifierLength;
@@ -64,8 +64,7 @@ function normalizeOptions(raw) {
64
64
  const scopes = normalizeScopes(camel.scopes) ??
65
65
  normalizeScopes(snake.scopes ?? snake.scope) ??
66
66
  DEFAULT_SCOPES.slice();
67
- const audience = coerceString(camel.audience) ??
68
- coerceString(snake.audience ?? snake.aud);
67
+ const audience = coerceString(camel.audience) ?? coerceString(snake.audience ?? snake.aud);
69
68
  const fetchImpl = (camel.fetchImpl ?? snake.fetch_impl);
70
69
  const clockSkewSeconds = coerceNumber(camel.clockSkewSeconds) ??
71
70
  coerceNumber(snake.clock_skew_seconds) ??
@@ -504,7 +504,8 @@ export class DefaultSecurityManager {
504
504
  const hasSignature = Boolean(envelope.sec?.sig);
505
505
  if (!hasSignature) {
506
506
  const nodeSid = node.sid;
507
- const envelopeSid = envelope.sid;
507
+ const envelopeSid = envelope
508
+ .sid;
508
509
  const isLocalUnsignedSelfEnvelope = localContext.originType === DeliveryOriginType.LOCAL &&
509
510
  typeof nodeSid === 'string' &&
510
511
  nodeSid.length > 0 &&
@@ -47,7 +47,7 @@ export * from './signing/envelope-signer.js';
47
47
  export * from './signing/envelope-verifier.js';
48
48
  export { SigningConfig as SigningConfigClass, } from './signing/signing-config.js';
49
49
  export { canonicalJson, decodeBase64Url, frameDigest, immutableHeaders, } from './signing/eddsa-signer-verifier.js';
50
- export { encodeUtf8, } from './signing/eddsa-utils.js';
50
+ export { encodeUtf8 } from './signing/eddsa-utils.js';
51
51
  export { EdDSAEnvelopeSigner, } from './signing/eddsa-envelope-signer.js';
52
52
  export * from './crypto/providers/crypto-provider.js';
53
53
  export * from './crypto/providers/default-crypto-provider.js';
@@ -1,14 +1,14 @@
1
- import { NoopTrustStoreProvider, TrustStoreProviderFactory, TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE, } from "./trust-store-provider-factory.js";
1
+ import { NoopTrustStoreProvider, TrustStoreProviderFactory, TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE, } from './trust-store-provider-factory.js';
2
2
  export const FACTORY_META = {
3
3
  base: TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE,
4
- key: "NoopTrustStoreProvider",
4
+ key: 'NoopTrustStoreProvider',
5
5
  isDefault: true,
6
6
  priority: 10,
7
7
  };
8
8
  export class NoopTrustStoreProviderFactory extends TrustStoreProviderFactory {
9
9
  constructor() {
10
10
  super(...arguments);
11
- this.type = "NoopTrustStoreProvider";
11
+ this.type = 'NoopTrustStoreProvider';
12
12
  this.isDefault = true;
13
13
  this.priority = 10;
14
14
  }
@@ -1,6 +1,6 @@
1
- import { AbstractResourceFactory, createDefaultResource, createResource, } from "@naylence/factory";
2
- const DEFAULT_UNCONFIGURED_MESSAGE = "Trust store is not configured. Set FAME_CA_CERTS to a PEM value, a file path, a data URI, or an HTTPS bundle URL.";
3
- export const TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE = "TrustStoreProviderFactory";
1
+ import { AbstractResourceFactory, createDefaultResource, createResource, } from '@naylence/factory';
2
+ const DEFAULT_UNCONFIGURED_MESSAGE = 'Trust store is not configured. Set FAME_CA_CERTS to a PEM value, a file path, a data URI, or an HTTPS bundle URL.';
3
+ export const TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE = 'TrustStoreProviderFactory';
4
4
  export class TrustStoreProviderFactory extends AbstractResourceFactory {
5
5
  createUnconfiguredProvider(reason) {
6
6
  return new NoopTrustStoreProvider(reason ?? DEFAULT_UNCONFIGURED_MESSAGE);
@@ -25,4 +25,5 @@ export * from './metrics-emitter.js';
25
25
  export * from './util.js';
26
26
  export * from './logicals.js';
27
27
  export * from './ttl-validation.js';
28
+ export { safeImport } from './lazy-import.js';
28
29
  export { normalizeEnvelopeSnapshot } from './logging-types.js';
package/dist/esm/node.js CHANGED
@@ -15,7 +15,8 @@ export * from './naylence/fame/placement/node-placement-strategy-factory.js';
15
15
  export * from './naylence/fame/transport/transport-provisioner.js';
16
16
  export * from './naylence/fame/welcome/index.js';
17
17
  export * from './naylence/fame/sentinel/index.js';
18
- export { HttpStatelessConnector, QueueFullError, DefaultHttpServer, getWebsocketListenerInstance, TransportListener, TRANSPORT_LISTENER_FACTORY_BASE_TYPE, WebSocketListener, HttpListener, getHttpListenerInstance, InPageListener, getInPageListenerInstance, } from './naylence/fame/connector/index.js';
18
+ export { HttpStatelessConnector, QueueFullError, DefaultHttpServer, getWebsocketListenerInstance, TransportListener, TransportListenerFactory, TRANSPORT_LISTENER_FACTORY_BASE_TYPE, WebSocketListener, HttpListener, getHttpListenerInstance, InPageListener, getInPageListenerInstance, } from './naylence/fame/connector/index.js';
19
+ export { safeImport } from './naylence/fame/util/lazy-import.js';
19
20
  export { InProcessFameFabric, InProcessFameFabricFactory, FAME_FABRIC_FACTORY_BASE_TYPE, } from './naylence/fame/fabric/index.js';
20
21
  export { normalizeExtendedFameConfig, } from './naylence/fame/config/index.js';
21
22
  export { createJwksRouter, } from './naylence/fame/http/jwks-api-router.js';
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated during build - do not edit manually
2
- // Generated from package.json version: 0.3.6
2
+ // Generated from package.json version: 0.3.7
3
3
  /**
4
4
  * The package version, injected at build time.
5
5
  * @internal
6
6
  */
7
- export const VERSION = '0.3.6';
7
+ export const VERSION = '0.3.7';