@naylence/runtime 0.3.6 → 0.3.9

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 (82) hide show
  1. package/dist/browser/index.cjs +262 -172
  2. package/dist/browser/index.mjs +261 -173
  3. package/dist/cjs/_env-shim.js +3 -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/fabric/fabric-registry.js +41 -0
  16. package/dist/cjs/naylence/fame/fabric/in-process-fame-fabric.js +3 -0
  17. package/dist/cjs/naylence/fame/fabric/index.js +3 -1
  18. package/dist/cjs/naylence/fame/grants/broadcast-channel-connection-grant.js +6 -3
  19. package/dist/cjs/naylence/fame/grants/inpage-connection-grant.js +4 -2
  20. package/dist/cjs/naylence/fame/http/oauth2-token-router.js +9 -9
  21. package/dist/cjs/naylence/fame/node/admission/default-node-attach-client.js +34 -5
  22. package/dist/cjs/naylence/fame/node/upstream-session-manager.js +40 -8
  23. package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +10 -6
  24. package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider.js +1 -2
  25. package/dist/cjs/naylence/fame/security/default-security-manager.js +2 -1
  26. package/dist/cjs/naylence/fame/security/trust-store/noop-trust-store-provider-factory.js +2 -2
  27. package/dist/cjs/naylence/fame/security/trust-store/trust-store-provider-factory.js +2 -2
  28. package/dist/cjs/naylence/fame/util/index.js +3 -1
  29. package/dist/cjs/node.js +4 -1
  30. package/dist/cjs/runtime-isomorphic.js +4 -1
  31. package/dist/cjs/version.js +2 -2
  32. package/dist/esm/_env-shim.js +3 -1
  33. package/dist/esm/browser.js +2 -2
  34. package/dist/esm/naylence/fame/config/extended-fame-config.js +2 -1
  35. package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -4
  36. package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +14 -6
  37. package/dist/esm/naylence/fame/connector/broadcast-channel-listener-factory.js +3 -1
  38. package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +11 -7
  39. package/dist/esm/naylence/fame/connector/index.js +2 -2
  40. package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +2 -1
  41. package/dist/esm/naylence/fame/connector/inpage-connector.js +13 -6
  42. package/dist/esm/naylence/fame/connector/inpage-listener-factory.js +4 -4
  43. package/dist/esm/naylence/fame/connector/inpage-listener.js +5 -2
  44. package/dist/esm/naylence/fame/delivery/default-delivery-tracker.js +4 -62
  45. package/dist/esm/naylence/fame/fabric/fabric-registry.js +37 -0
  46. package/dist/esm/naylence/fame/fabric/in-process-fame-fabric.js +3 -0
  47. package/dist/esm/naylence/fame/fabric/index.js +1 -0
  48. package/dist/esm/naylence/fame/grants/broadcast-channel-connection-grant.js +6 -3
  49. package/dist/esm/naylence/fame/grants/inpage-connection-grant.js +4 -2
  50. package/dist/esm/naylence/fame/http/oauth2-token-router.js +9 -9
  51. package/dist/esm/naylence/fame/node/admission/default-node-attach-client.js +34 -5
  52. package/dist/esm/naylence/fame/node/upstream-session-manager.js +40 -8
  53. package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +10 -6
  54. package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider.js +1 -2
  55. package/dist/esm/naylence/fame/security/default-security-manager.js +2 -1
  56. package/dist/esm/naylence/fame/security/index.js +1 -1
  57. package/dist/esm/naylence/fame/security/trust-store/noop-trust-store-provider-factory.js +3 -3
  58. package/dist/esm/naylence/fame/security/trust-store/trust-store-provider-factory.js +3 -3
  59. package/dist/esm/naylence/fame/util/index.js +1 -0
  60. package/dist/esm/node.js +2 -1
  61. package/dist/esm/runtime-isomorphic.js +2 -0
  62. package/dist/esm/version.js +2 -2
  63. package/dist/node/index.cjs +259 -171
  64. package/dist/node/index.mjs +258 -172
  65. package/dist/node/node.cjs +225 -136
  66. package/dist/node/node.mjs +223 -137
  67. package/dist/types/browser.d.ts +2 -2
  68. package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +1 -0
  69. package/dist/types/naylence/fame/connector/index.d.ts +3 -3
  70. package/dist/types/naylence/fame/delivery/default-delivery-tracker.d.ts +0 -6
  71. package/dist/types/naylence/fame/fabric/fabric-registry.d.ts +29 -0
  72. package/dist/types/naylence/fame/fabric/index.d.ts +1 -0
  73. package/dist/types/naylence/fame/node/admission/default-node-attach-client.d.ts +1 -0
  74. package/dist/types/naylence/fame/security/index.d.ts +1 -1
  75. package/dist/types/naylence/fame/security/trust-store/noop-trust-store-provider-factory.d.ts +3 -3
  76. package/dist/types/naylence/fame/security/trust-store/trust-store-provider-factory.d.ts +4 -4
  77. package/dist/types/naylence/fame/security/trust-store/trust-store-provider.d.ts +5 -5
  78. package/dist/types/naylence/fame/util/index.d.ts +1 -0
  79. package/dist/types/node.d.ts +2 -1
  80. package/dist/types/runtime-isomorphic.d.ts +1 -0
  81. package/dist/types/version.d.ts +1 -1
  82. package/package.json +1 -1
@@ -11,15 +11,30 @@ class DefaultNodeAttachClient {
11
11
  constructor(options = {}) {
12
12
  this.buffer = [];
13
13
  this.inHandshake = false;
14
+ this.expectedSystemId = null;
14
15
  this.timeoutMs = options.timeoutMs ?? 10000;
15
16
  this.attachmentKeyValidator = options.attachmentKeyValidator;
16
17
  this.replicaStickinessManager = options.replicaStickinessManager ?? null;
17
18
  }
18
19
  async attach(node, originType, connector, welcomeFrame, finalHandler, keys, callbackGrants) {
19
20
  this.inHandshake = true;
21
+ this.expectedSystemId = welcomeFrame.systemId;
20
22
  const interimHandler = async (envelope, context) => {
21
23
  if (this.inHandshake) {
22
- this.buffer.push(envelope);
24
+ // Filter: only buffer frames related to our systemId or frames without systemId info
25
+ const frameSystemId = envelope.frame
26
+ ?.systemId;
27
+ if (!frameSystemId || frameSystemId === this.expectedSystemId) {
28
+ this.buffer.push(envelope);
29
+ }
30
+ else {
31
+ // Silently ignore frames from other agents during concurrent handshakes
32
+ logger.debug('handshake_ignoring_frame_from_different_system', {
33
+ frame_type: envelope.frame.type,
34
+ frame_system_id: frameSystemId,
35
+ expected_system_id: this.expectedSystemId,
36
+ });
37
+ }
23
38
  return null;
24
39
  }
25
40
  return finalHandler(envelope, context);
@@ -146,6 +161,7 @@ class DefaultNodeAttachClient {
146
161
  parent_id: ackFrame.targetSystemId,
147
162
  });
148
163
  this.inHandshake = false;
164
+ this.expectedSystemId = null;
149
165
  await connector.replaceHandler(finalHandler);
150
166
  while (this.buffer.length > 0) {
151
167
  const bufferedEnvelope = this.buffer.shift();
@@ -203,7 +219,8 @@ class DefaultNodeAttachClient {
203
219
  const deadline = Date.now() + this.timeoutMs;
204
220
  while (Date.now() < deadline) {
205
221
  // Allow both STARTED and PAUSED states (PAUSED = tab hidden but connection alive)
206
- if (connector.state !== core_1.ConnectorState.STARTED && connector.state !== core_1.ConnectorState.PAUSED) {
222
+ if (connector.state !== core_1.ConnectorState.STARTED &&
223
+ connector.state !== core_1.ConnectorState.PAUSED) {
207
224
  let errorMessage = 'Connector closed while waiting for NodeAttachAck';
208
225
  if (connector.closeCode !== undefined) {
209
226
  errorMessage += ` (code=${connector.closeCode}`;
@@ -222,9 +239,21 @@ class DefaultNodeAttachClient {
222
239
  if (envelope.frame.type === 'NodeAttachAck') {
223
240
  return envelope;
224
241
  }
225
- logger.error('unexpected_frame_during_handshake', {
226
- frame_type: envelope.frame.type,
227
- });
242
+ // NodeAttach frames during handshake are expected in multi-agent scenarios
243
+ // where multiple agents attach concurrently to the same channel
244
+ if (envelope.frame.type === 'NodeAttach') {
245
+ logger.debug('handshake_ignoring_concurrent_attach', {
246
+ frame_type: envelope.frame.type,
247
+ frame_system_id: envelope.frame?.systemId ??
248
+ 'unknown',
249
+ });
250
+ }
251
+ else {
252
+ // Other unexpected frames are still logged as errors
253
+ logger.error('unexpected_frame_during_handshake', {
254
+ frame_type: envelope.frame.type,
255
+ });
256
+ }
228
257
  }
229
258
  await (0, task_utils_js_1.delay)(HANDSHAKE_POLL_INTERVAL_MS);
230
259
  }
@@ -321,25 +321,56 @@ class UpstreamSessionManager extends task_spawner_js_1.TaskSpawner {
321
321
  await connector.start(this.wrappedHandler);
322
322
  this.connector = connector;
323
323
  const callbackGrants = this.node.gatherSupportedCallbackGrants();
324
+ logger.debug('callback_grants_before_augmentation', {
325
+ count: callbackGrants.length,
326
+ types: callbackGrants.map((g) => g.type),
327
+ });
328
+ // Check if we should create a broadcast callback grant before processing connection grants
329
+ // This prevents adding duplicate broadcast grants
330
+ const shouldAddBroadcastGrant = this.shouldAdvertiseBroadcastGrant(grant, callbackGrants);
331
+ const broadcastCallbackGrant = shouldAddBroadcastGrant
332
+ ? this.createBroadcastCallbackGrant(grant)
333
+ : null;
334
+ logger.debug('broadcast_callback_grant_check', {
335
+ should_add: shouldAddBroadcastGrant,
336
+ grant_created: !!broadcastCallbackGrant,
337
+ });
324
338
  // Include admission client's connection grants as callback grants
325
339
  // This ensures DirectAdmissionClient grants are available for grant selection
326
- if (welcome.frame.connectionGrants && Array.isArray(welcome.frame.connectionGrants)) {
340
+ if (welcome.frame.connectionGrants &&
341
+ Array.isArray(welcome.frame.connectionGrants)) {
327
342
  for (const grant of welcome.frame.connectionGrants) {
328
343
  if (grant && typeof grant === 'object') {
329
344
  // Avoid duplicates by checking if grant already exists
330
- const isDuplicate = callbackGrants.some(existing => JSON.stringify(existing) === JSON.stringify(grant));
345
+ const isDuplicate = callbackGrants.some((existing) => JSON.stringify(existing) === JSON.stringify(grant));
331
346
  if (!isDuplicate) {
332
347
  callbackGrants.push(grant);
348
+ logger.debug('added_connection_grant_as_callback', {
349
+ type: grant.type,
350
+ });
351
+ }
352
+ else {
353
+ logger.debug('skipped_duplicate_connection_grant', {
354
+ type: grant.type,
355
+ });
333
356
  }
334
357
  }
335
358
  }
336
359
  }
337
- if (this.shouldAdvertiseBroadcastGrant(grant, callbackGrants)) {
338
- const augmented = this.createBroadcastCallbackGrant(grant);
339
- if (augmented) {
340
- callbackGrants.push(augmented);
341
- }
360
+ // Add broadcast grant after connection grants to ensure we don't duplicate
361
+ // any broadcast grants that may have been in connectionGrants
362
+ if (broadcastCallbackGrant &&
363
+ this.shouldAdvertiseBroadcastGrant(grant, callbackGrants)) {
364
+ callbackGrants.push(broadcastCallbackGrant);
365
+ logger.debug('added_broadcast_callback_grant');
366
+ }
367
+ else if (broadcastCallbackGrant) {
368
+ logger.debug('skipped_duplicate_broadcast_callback_grant');
342
369
  }
370
+ logger.debug('callback_grants_after_augmentation', {
371
+ count: callbackGrants.length,
372
+ types: callbackGrants.map((g) => g.type),
373
+ });
343
374
  const attachInfo = await this.attachClient.attach(this.node, this.outboundOriginType, connector, welcome.frame, this.wrappedHandler, this.getKeys() ?? undefined, callbackGrants);
344
375
  this.targetSystemId = attachInfo.targetSystemId ?? null;
345
376
  if (this.targetSystemId) {
@@ -580,7 +611,8 @@ class UpstreamSessionManager extends task_spawner_js_1.TaskSpawner {
580
611
  continue;
581
612
  }
582
613
  // Reset ack time if just resumed from pause (prevents immediate timeout)
583
- if (previousState === core_1.ConnectorState.PAUSED && currentState === core_1.ConnectorState.STARTED) {
614
+ if (previousState === core_1.ConnectorState.PAUSED &&
615
+ currentState === core_1.ConnectorState.STARTED) {
584
616
  logger.debug('connector_just_resumed_resetting_ack_time', {
585
617
  previous_state: previousState,
586
618
  current_state: currentState,
@@ -94,19 +94,23 @@ function normalizeConfig(config) {
94
94
  normalized.clientSecretConfig = (0, secret_source_js_1.normalizeSecretSource)(clientSecretSource);
95
95
  }
96
96
  const audienceCandidate = candidate.audience ?? candidate.aud;
97
- if (typeof audienceCandidate === 'string' && audienceCandidate.trim().length > 0) {
97
+ if (typeof audienceCandidate === 'string' &&
98
+ audienceCandidate.trim().length > 0) {
98
99
  normalized.audience = audienceCandidate.trim();
99
100
  }
100
101
  const codeChallengeMethod = candidate.codeChallengeMethod ?? candidate.code_challenge_method;
101
- if (typeof codeChallengeMethod === 'string' && codeChallengeMethod.trim().length > 0) {
102
+ if (typeof codeChallengeMethod === 'string' &&
103
+ codeChallengeMethod.trim().length > 0) {
102
104
  normalized.codeChallengeMethod = codeChallengeMethod.trim();
103
105
  }
104
106
  const codeVerifierLength = candidate.codeVerifierLength ?? candidate.code_verifier_length;
105
- if (typeof codeVerifierLength === 'number' && Number.isFinite(codeVerifierLength)) {
107
+ if (typeof codeVerifierLength === 'number' &&
108
+ Number.isFinite(codeVerifierLength)) {
106
109
  normalized.codeVerifierLength = codeVerifierLength;
107
110
  }
108
111
  const clockSkewSeconds = candidate.clockSkewSeconds ?? candidate.clock_skew_seconds;
109
- if (typeof clockSkewSeconds === 'number' && Number.isFinite(clockSkewSeconds)) {
112
+ if (typeof clockSkewSeconds === 'number' &&
113
+ Number.isFinite(clockSkewSeconds)) {
110
114
  normalized.clockSkewSeconds = clockSkewSeconds;
111
115
  }
112
116
  const loginHintParam = candidate.loginHintParam ?? candidate.login_hint_param;
@@ -151,8 +155,8 @@ class OAuth2PkceTokenProviderFactory extends token_provider_factory_js_1.TokenPr
151
155
  options.audience = normalized.audience;
152
156
  }
153
157
  if (normalized.codeChallengeMethod) {
154
- options.codeChallengeMethod = normalized.codeChallengeMethod
155
- .toUpperCase();
158
+ options.codeChallengeMethod =
159
+ normalized.codeChallengeMethod.toUpperCase();
156
160
  }
157
161
  if (normalized.codeVerifierLength) {
158
162
  options.codeVerifierLength = normalized.codeVerifierLength;
@@ -67,8 +67,7 @@ function normalizeOptions(raw) {
67
67
  const scopes = normalizeScopes(camel.scopes) ??
68
68
  normalizeScopes(snake.scopes ?? snake.scope) ??
69
69
  DEFAULT_SCOPES.slice();
70
- const audience = coerceString(camel.audience) ??
71
- coerceString(snake.audience ?? snake.aud);
70
+ const audience = coerceString(camel.audience) ?? coerceString(snake.audience ?? snake.aud);
72
71
  const fetchImpl = (camel.fetchImpl ?? snake.fetch_impl);
73
72
  const clockSkewSeconds = coerceNumber(camel.clockSkewSeconds) ??
74
73
  coerceNumber(snake.clock_skew_seconds) ??
@@ -507,7 +507,8 @@ class DefaultSecurityManager {
507
507
  const hasSignature = Boolean(envelope.sec?.sig);
508
508
  if (!hasSignature) {
509
509
  const nodeSid = node.sid;
510
- const envelopeSid = envelope.sid;
510
+ const envelopeSid = envelope
511
+ .sid;
511
512
  const isLocalUnsignedSelfEnvelope = localContext.originType === core_1.DeliveryOriginType.LOCAL &&
512
513
  typeof nodeSid === 'string' &&
513
514
  nodeSid.length > 0 &&
@@ -4,14 +4,14 @@ exports.NoopTrustStoreProviderFactory = exports.FACTORY_META = void 0;
4
4
  const trust_store_provider_factory_js_1 = require("./trust-store-provider-factory.js");
5
5
  exports.FACTORY_META = {
6
6
  base: trust_store_provider_factory_js_1.TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE,
7
- key: "NoopTrustStoreProvider",
7
+ key: 'NoopTrustStoreProvider',
8
8
  isDefault: true,
9
9
  priority: 10,
10
10
  };
11
11
  class NoopTrustStoreProviderFactory extends trust_store_provider_factory_js_1.TrustStoreProviderFactory {
12
12
  constructor() {
13
13
  super(...arguments);
14
- this.type = "NoopTrustStoreProvider";
14
+ this.type = 'NoopTrustStoreProvider';
15
15
  this.isDefault = true;
16
16
  this.priority = 10;
17
17
  }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NoopTrustStoreProvider = exports.TrustStoreProviderFactory = exports.TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE = void 0;
4
4
  const factory_1 = require("@naylence/factory");
5
- 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.";
6
- exports.TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE = "TrustStoreProviderFactory";
5
+ 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.';
6
+ exports.TRUST_STORE_PROVIDER_FACTORY_BASE_TYPE = 'TrustStoreProviderFactory';
7
7
  class TrustStoreProviderFactory extends factory_1.AbstractResourceFactory {
8
8
  createUnconfiguredProvider(reason) {
9
9
  return new NoopTrustStoreProvider(reason ?? DEFAULT_UNCONFIGURED_MESSAGE);
@@ -5,7 +5,7 @@
5
5
  * Cross-platform structured logging, async task management, and general utilities for Naylence Fame runtime
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.normalizeEnvelopeSnapshot = exports.throttle = exports.debounce = exports.retryWithBackoff = exports.withTimeout = exports.delay = exports.waitForAllSettled = exports.waitForAll = exports.waitForAny = exports.withLock = exports.AsyncLock = exports.TaskSpawner = exports.EnvelopeContext = exports.withEnvelopeContextAsync = exports.withEnvelopeContext = exports.currentTraceId = exports.getCurrentEnvelope = exports.pinoTransport = exports.consoleTransport = exports.stringifyNonPrimitives = exports.dropEmpty = exports.addEnvelopeFields = exports.addLogLevel = exports.addTimestamp = exports.LogLevelNames = exports.LogLevel = exports.enableLogging = exports.basicConfig = exports.getLogger = void 0;
8
+ exports.normalizeEnvelopeSnapshot = exports.safeImport = exports.throttle = exports.debounce = exports.retryWithBackoff = exports.withTimeout = exports.delay = exports.waitForAllSettled = exports.waitForAll = exports.waitForAny = exports.withLock = exports.AsyncLock = exports.TaskSpawner = exports.EnvelopeContext = exports.withEnvelopeContextAsync = exports.withEnvelopeContext = exports.currentTraceId = exports.getCurrentEnvelope = exports.pinoTransport = exports.consoleTransport = exports.stringifyNonPrimitives = exports.dropEmpty = exports.addEnvelopeFields = exports.addLogLevel = exports.addTimestamp = exports.LogLevelNames = exports.LogLevel = exports.enableLogging = exports.basicConfig = exports.getLogger = void 0;
9
9
  const tslib_1 = require("tslib");
10
10
  // Export the main logging API
11
11
  var logging_js_1 = require("./logging.js");
@@ -55,5 +55,7 @@ tslib_1.__exportStar(require("./metrics-emitter.js"), exports);
55
55
  tslib_1.__exportStar(require("./util.js"), exports);
56
56
  tslib_1.__exportStar(require("./logicals.js"), exports);
57
57
  tslib_1.__exportStar(require("./ttl-validation.js"), exports);
58
+ var lazy_import_js_1 = require("./lazy-import.js");
59
+ Object.defineProperty(exports, "safeImport", { enumerable: true, get: function () { return lazy_import_js_1.safeImport; } });
58
60
  var logging_types_js_1 = require("./logging-types.js");
59
61
  Object.defineProperty(exports, "normalizeEnvelopeSnapshot", { enumerable: true, get: function () { return logging_types_js_1.normalizeEnvelopeSnapshot; } });
package/dist/cjs/node.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.runOAuth2Server = exports.createOAuth2ServerApp = exports.createOpenIDConfigurationRouter = exports.createOAuth2TokenRouter = exports.createJwksRouter = exports.normalizeExtendedFameConfig = exports.FAME_FABRIC_FACTORY_BASE_TYPE = exports.InProcessFameFabricFactory = exports.InProcessFameFabric = exports.getInPageListenerInstance = exports.InPageListener = exports.getHttpListenerInstance = exports.HttpListener = exports.WebSocketListener = exports.TRANSPORT_LISTENER_FACTORY_BASE_TYPE = exports.TransportListener = exports.getWebsocketListenerInstance = exports.DefaultHttpServer = exports.QueueFullError = exports.HttpStatelessConnector = void 0;
3
+ exports.runOAuth2Server = exports.createOAuth2ServerApp = exports.createOpenIDConfigurationRouter = exports.createOAuth2TokenRouter = exports.createJwksRouter = exports.normalizeExtendedFameConfig = exports.FAME_FABRIC_FACTORY_BASE_TYPE = exports.InProcessFameFabricFactory = exports.InProcessFameFabric = exports.safeImport = exports.getInPageListenerInstance = exports.InPageListener = exports.getHttpListenerInstance = exports.HttpListener = exports.WebSocketListener = exports.TRANSPORT_LISTENER_FACTORY_BASE_TYPE = exports.TransportListenerFactory = exports.TransportListener = exports.getWebsocketListenerInstance = exports.DefaultHttpServer = exports.QueueFullError = exports.HttpStatelessConnector = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  require("./naylence/fame/connector/websocket-connector-node-ssl.js");
6
6
  // Ensure Node-specific registrations (storage, sqlite, etc.) happen before
@@ -25,12 +25,15 @@ Object.defineProperty(exports, "QueueFullError", { enumerable: true, get: functi
25
25
  Object.defineProperty(exports, "DefaultHttpServer", { enumerable: true, get: function () { return index_js_1.DefaultHttpServer; } });
26
26
  Object.defineProperty(exports, "getWebsocketListenerInstance", { enumerable: true, get: function () { return index_js_1.getWebsocketListenerInstance; } });
27
27
  Object.defineProperty(exports, "TransportListener", { enumerable: true, get: function () { return index_js_1.TransportListener; } });
28
+ Object.defineProperty(exports, "TransportListenerFactory", { enumerable: true, get: function () { return index_js_1.TransportListenerFactory; } });
28
29
  Object.defineProperty(exports, "TRANSPORT_LISTENER_FACTORY_BASE_TYPE", { enumerable: true, get: function () { return index_js_1.TRANSPORT_LISTENER_FACTORY_BASE_TYPE; } });
29
30
  Object.defineProperty(exports, "WebSocketListener", { enumerable: true, get: function () { return index_js_1.WebSocketListener; } });
30
31
  Object.defineProperty(exports, "HttpListener", { enumerable: true, get: function () { return index_js_1.HttpListener; } });
31
32
  Object.defineProperty(exports, "getHttpListenerInstance", { enumerable: true, get: function () { return index_js_1.getHttpListenerInstance; } });
32
33
  Object.defineProperty(exports, "InPageListener", { enumerable: true, get: function () { return index_js_1.InPageListener; } });
33
34
  Object.defineProperty(exports, "getInPageListenerInstance", { enumerable: true, get: function () { return index_js_1.getInPageListenerInstance; } });
35
+ var lazy_import_js_1 = require("./naylence/fame/util/lazy-import.js");
36
+ Object.defineProperty(exports, "safeImport", { enumerable: true, get: function () { return lazy_import_js_1.safeImport; } });
34
37
  var index_js_2 = require("./naylence/fame/fabric/index.js");
35
38
  Object.defineProperty(exports, "InProcessFameFabric", { enumerable: true, get: function () { return index_js_2.InProcessFameFabric; } });
36
39
  Object.defineProperty(exports, "InProcessFameFabricFactory", { enumerable: true, get: function () { return index_js_2.InProcessFameFabricFactory; } });
@@ -8,7 +8,7 @@
8
8
  * expect access to the Node.js standard library.
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.__runtimePluginLoader = exports.ensureRuntimeFactoriesRegistered = exports.registerRuntimeFactories = exports.registerDefaultFactories = exports.isRegisterable = exports.operation = exports.RpcMixin = exports.createRpcProxy = exports.RpcProxy = exports.INPAGE_CONNECTOR_TYPE = exports.InPageConnector = exports._NoopFlowController = exports.WebSocketState = exports.WebSocketConnector = exports.createResource = exports.ConnectorFactory = exports.createConnectorConfig = exports.isConnectorConfig = exports.ConnectorConfigDefaults = exports.BaseAsyncConnector = exports.VERSION = void 0;
11
+ exports.__runtimePluginLoader = exports.getFabricForNode = exports.ensureRuntimeFactoriesRegistered = exports.registerRuntimeFactories = exports.registerDefaultFactories = exports.isRegisterable = exports.operation = exports.RpcMixin = exports.createRpcProxy = exports.RpcProxy = exports.INPAGE_CONNECTOR_TYPE = exports.InPageConnector = exports._NoopFlowController = exports.WebSocketState = exports.WebSocketConnector = exports.createResource = exports.ConnectorFactory = exports.createConnectorConfig = exports.isConnectorConfig = exports.ConnectorConfigDefaults = exports.BaseAsyncConnector = exports.VERSION = void 0;
12
12
  const tslib_1 = require("tslib");
13
13
  // Re-export everything from naylence-core for protocol primitives
14
14
  tslib_1.__exportStar(require("@naylence/core"), exports);
@@ -69,6 +69,9 @@ tslib_1.__exportStar(require("./naylence/fame/placement/node-placement-strategy-
69
69
  tslib_1.__exportStar(require("./naylence/fame/transport/transport-provisioner.js"), exports);
70
70
  // Welcome service (isomorphic)
71
71
  tslib_1.__exportStar(require("./naylence/fame/welcome/index.js"), exports);
72
+ // Fabric registry (for looking up fabric from node)
73
+ var fabric_registry_js_1 = require("./naylence/fame/fabric/fabric-registry.js");
74
+ Object.defineProperty(exports, "getFabricForNode", { enumerable: true, get: function () { return fabric_registry_js_1.getFabricForNode; } });
72
75
  const runtimePluginModulePromise = Promise.resolve().then(() => tslib_1.__importStar(require('./plugin.js')));
73
76
  const globalScope = globalThis;
74
77
  const FACTORY_MODULE_PREFIX = '@naylence/runtime/naylence/fame/';
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  // This file is auto-generated during build - do not edit manually
3
- // Generated from package.json version: 0.3.6
3
+ // Generated from package.json version: 0.3.9
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.VERSION = void 0;
6
6
  /**
7
7
  * The package version, injected at build time.
8
8
  * @internal
9
9
  */
10
- exports.VERSION = '0.3.6';
10
+ exports.VERSION = '0.3.9';
@@ -14,7 +14,9 @@ export function installProcessEnvShim() {
14
14
  if (g.__ENV__ && typeof g.__ENV__ === 'object')
15
15
  Object.assign(out, g.__ENV__);
16
16
  try {
17
- // @ts-ignore -- import.meta is only available in ESM builds
17
+ // import.meta is only available in ESM builds
18
+ // prettier-ignore
19
+ // @ts-ignore
18
20
  const ie = (typeof import.meta !== 'undefined' && import.meta.env) || undefined;
19
21
  if (ie && typeof ie === 'object')
20
22
  Object.assign(out, ie);
@@ -6,7 +6,7 @@ export { InPageConnector, INPAGE_CONNECTOR_TYPE, } from './naylence/fame/connect
6
6
  export { BroadcastChannelConnector, BROADCAST_CHANNEL_CONNECTOR_TYPE, } from './naylence/fame/connector/broadcast-channel-connector.js';
7
7
  export { InPageConnectorFactory, FACTORY_META as INPAGE_CONNECTOR_FACTORY_META, } from './naylence/fame/connector/inpage-connector-factory.js';
8
8
  export { BroadcastChannelConnectorFactory, FACTORY_META as BROADCAST_CHANNEL_CONNECTOR_FACTORY_META, } from './naylence/fame/connector/broadcast-channel-connector-factory.js';
9
- export { InPageListener, } from './naylence/fame/connector/inpage-listener.js';
9
+ export { InPageListener } from './naylence/fame/connector/inpage-listener.js';
10
10
  export { InPageListenerFactory, FACTORY_META as INPAGE_LISTENER_FACTORY_META, } from './naylence/fame/connector/inpage-listener-factory.js';
11
- export { BroadcastChannelListener, } from './naylence/fame/connector/broadcast-channel-listener.js';
11
+ export { BroadcastChannelListener } from './naylence/fame/connector/broadcast-channel-listener.js';
12
12
  export { BroadcastChannelListenerFactory, FACTORY_META as BROADCAST_CHANNEL_LISTENER_FACTORY_META, } from './naylence/fame/connector/broadcast-channel-listener-factory.js';
@@ -50,7 +50,8 @@ function createFsShim() {
50
50
  else if (options &&
51
51
  typeof options === 'object' &&
52
52
  'encoding' in options &&
53
- typeof options.encoding === 'string') {
53
+ typeof options.encoding ===
54
+ 'string') {
54
55
  encoding = options.encoding;
55
56
  }
56
57
  const data = fsBinding.readFileUtf8(pathOrDescriptor, 0);
@@ -44,10 +44,12 @@ export class BroadcastChannelConnectorFactory extends ConnectorFactory {
44
44
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
45
45
  };
46
46
  const channelCandidate = record.channelName ?? record['channel_name'];
47
- if (typeof channelCandidate === 'string' && channelCandidate.trim().length > 0) {
47
+ if (typeof channelCandidate === 'string' &&
48
+ channelCandidate.trim().length > 0) {
48
49
  config.channelName = channelCandidate.trim();
49
50
  }
50
- const inboxCandidate = record.inboxCapacity ?? record['inbox_capacity'];
51
+ const inboxCandidate = record.inboxCapacity ??
52
+ record['inbox_capacity'];
51
53
  if (typeof inboxCandidate === 'number' &&
52
54
  Number.isFinite(inboxCandidate) &&
53
55
  inboxCandidate > 0) {
@@ -71,9 +73,11 @@ export class BroadcastChannelConnectorFactory extends ConnectorFactory {
71
73
  throw new Error('BroadcastChannelConnectorFactory requires a configuration');
72
74
  }
73
75
  const normalized = this._normalizeConfig(config);
74
- const options = (factoryArgs[0] ?? {});
76
+ const options = (factoryArgs[0] ??
77
+ {});
75
78
  const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
76
- const localNodeId = this._normalizeNodeId(options.localNodeId) ?? normalizedLocalNodeFromConfig;
79
+ const localNodeId = this._normalizeNodeId(options.localNodeId) ??
80
+ normalizedLocalNodeFromConfig;
77
81
  if (!localNodeId) {
78
82
  throw new Error('BroadcastChannelConnectorFactory requires a localNodeId from config or create() options');
79
83
  }
@@ -98,6 +102,7 @@ export class BroadcastChannelConnectorFactory extends ConnectorFactory {
98
102
  inboxCapacity,
99
103
  localNodeId,
100
104
  initialTargetNodeId: resolvedTarget,
105
+ passive: normalized.passive,
101
106
  };
102
107
  const connector = new BroadcastChannelConnector(connectorConfig, baseConfig);
103
108
  if (options.authorization) {
@@ -136,6 +141,9 @@ export class BroadcastChannelConnectorFactory extends ConnectorFactory {
136
141
  if (normalizedLocalNodeId) {
137
142
  normalized.localNodeId = normalizedLocalNodeId;
138
143
  }
144
+ if (typeof candidate.passive === 'boolean') {
145
+ normalized.passive = candidate.passive;
146
+ }
139
147
  if (typeof candidate.flowControl === 'boolean') {
140
148
  normalized.flowControl = candidate.flowControl;
141
149
  }
@@ -17,7 +17,8 @@ const ensureBroadcastEnvironment = () => {
17
17
  };
18
18
  export class BroadcastChannelConnector extends BaseAsyncConnector {
19
19
  static generateConnectorId() {
20
- const globalCrypto = globalThis.crypto;
20
+ const globalCrypto = globalThis
21
+ .crypto;
21
22
  if (globalCrypto?.randomUUID) {
22
23
  return globalCrypto.randomUUID();
23
24
  }
@@ -72,7 +73,8 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
72
73
  this.listenerRegistered = false;
73
74
  this.visibilityChangeListenerRegistered = false;
74
75
  this.channelName =
75
- typeof config.channelName === 'string' && config.channelName.trim().length > 0
76
+ typeof config.channelName === 'string' &&
77
+ config.channelName.trim().length > 0
76
78
  ? config.channelName.trim()
77
79
  : DEFAULT_CHANNEL;
78
80
  const preferredCapacity = typeof config.inboxCapacity === 'number' &&
@@ -96,6 +98,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
96
98
  local_node_id: this.localNodeId,
97
99
  target_node_id: this.targetNodeId ?? null,
98
100
  inbox_capacity: preferredCapacity,
101
+ passive: config.passive ?? false,
99
102
  timestamp: new Date().toISOString(),
100
103
  });
101
104
  this.onMsg = (event) => {
@@ -113,7 +116,8 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
113
116
  channel: this.channelName,
114
117
  connector_id: this.connectorId,
115
118
  message_type: message && typeof message === 'object'
116
- ? message.constructor?.name ?? typeof message
119
+ ? (message.constructor
120
+ ?.name ?? typeof message)
117
121
  : typeof message,
118
122
  has_sender_id: Boolean(message?.senderId),
119
123
  has_sender_node_id: Boolean(message?.senderNodeId),
@@ -343,7 +347,9 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
343
347
  timestamp: new Date().toISOString(),
344
348
  });
345
349
  }
346
- if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
350
+ if (this.visibilityChangeListenerRegistered &&
351
+ this.visibilityChangeHandler &&
352
+ typeof document !== 'undefined') {
347
353
  document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
348
354
  this.visibilityChangeListenerRegistered = false;
349
355
  this.visibilityChangeHandler = undefined;
@@ -371,7 +377,7 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
371
377
  return rawOrEnvelope;
372
378
  }
373
379
  _isWildcardTarget() {
374
- return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
380
+ return (this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined');
375
381
  }
376
382
  _shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
377
383
  if (this._isWildcardTarget()) {
@@ -391,7 +397,9 @@ export class BroadcastChannelConnector extends BaseAsyncConnector {
391
397
  return true;
392
398
  }
393
399
  const expectedSender = this.targetNodeId;
394
- if (expectedSender && expectedSender !== '*' && senderNodeId !== expectedSender) {
400
+ if (expectedSender &&
401
+ expectedSender !== '*' &&
402
+ senderNodeId !== expectedSender) {
395
403
  logger.debug('broadcast_channel_message_rejected', {
396
404
  channel: this.channelName,
397
405
  connector_id: this.connectorId,
@@ -17,7 +17,9 @@ function normalizeConfig(config) {
17
17
  : DEFAULT_CHANNEL;
18
18
  const rawInbox = record.inboxCapacity ?? record['inbox_capacity'];
19
19
  let inboxCapacity = DEFAULT_INBOX_CAPACITY;
20
- if (typeof rawInbox === 'number' && Number.isFinite(rawInbox) && rawInbox > 0) {
20
+ if (typeof rawInbox === 'number' &&
21
+ Number.isFinite(rawInbox) &&
22
+ rawInbox > 0) {
21
23
  inboxCapacity = Math.floor(rawInbox);
22
24
  }
23
25
  else if (typeof rawInbox === 'string') {
@@ -10,9 +10,7 @@ import { BROADCAST_CHANNEL_CONNECTION_GRANT_TYPE, broadcastChannelGrantToConnect
10
10
  const logger = getLogger('naylence.fame.connector.broadcast_channel_listener');
11
11
  const DEFAULT_CHANNEL = 'naylence-fabric';
12
12
  const DEFAULT_INBOX_CAPACITY = 2048;
13
- const RESPONSE_TYPE_MASK = FameResponseType.ACK |
14
- FameResponseType.REPLY |
15
- FameResponseType.STREAM;
13
+ const RESPONSE_TYPE_MASK = FameResponseType.ACK | FameResponseType.REPLY | FameResponseType.STREAM;
16
14
  const isBrowserEnvironment = () => typeof window !== 'undefined' &&
17
15
  typeof BroadcastChannel !== 'undefined' &&
18
16
  typeof MessageEvent !== 'undefined';
@@ -226,9 +224,7 @@ export class BroadcastChannelListener extends TransportListener {
226
224
  return null;
227
225
  }
228
226
  })();
229
- if (error instanceof ZodError &&
230
- decoded &&
231
- decoded.length > 0) {
227
+ if (error instanceof ZodError && decoded && decoded.length > 0) {
232
228
  try {
233
229
  const reparsed = JSON.parse(decoded);
234
230
  const candidate = reparsed.rtype;
@@ -451,11 +447,19 @@ export class BroadcastChannelListener extends TransportListener {
451
447
  ? Math.floor(initialWindowCandidate)
452
448
  : undefined;
453
449
  const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
450
+ const passive = typeof passiveCandidate === 'boolean' ? passiveCandidate : true;
451
+ logger.debug('broadcast_channel_listener_building_connector_config', {
452
+ system_id: systemId,
453
+ channel_name: channelName,
454
+ passive,
455
+ has_base_config: !!baseConfig,
456
+ passive_candidate: passiveCandidate,
457
+ });
454
458
  return {
455
459
  type: BROADCAST_CHANNEL_CONNECTOR_TYPE,
456
460
  channelName,
457
461
  inboxCapacity,
458
- passive: typeof passiveCandidate === 'boolean' ? passiveCandidate : true,
462
+ passive,
459
463
  initialWindow,
460
464
  localNodeId,
461
465
  initialTargetNodeId,
@@ -24,9 +24,9 @@ export { BroadcastChannelConnector, BROADCAST_CHANNEL_CONNECTOR_TYPE, } from './
24
24
  export { _NoopFlowController } from './noop-flow-controller.js';
25
25
  // Transport listener
26
26
  export { TransportListener } from './transport-listener.js';
27
- export { TRANSPORT_LISTENER_FACTORY_BASE_TYPE } from './transport-listener-factory.js';
27
+ export { TransportListenerFactory, TRANSPORT_LISTENER_FACTORY_BASE_TYPE, } from './transport-listener-factory.js';
28
28
  export { DefaultHttpServer } from './default-http-server.js';
29
29
  export { WebSocketListener, getWebsocketListenerInstance, } from './websocket-listener.js';
30
30
  export { HttpListener, getHttpListenerInstance } from './http-listener.js';
31
- export { InPageListener, getInPageListenerInstance } from './inpage-listener.js';
31
+ export { InPageListener, getInPageListenerInstance, } from './inpage-listener.js';
32
32
  export { BroadcastChannelListener, getBroadcastChannelListenerInstance, } from './broadcast-channel-listener.js';
@@ -66,7 +66,8 @@ export class InPageConnectorFactory extends ConnectorFactory {
66
66
  const normalized = this._normalizeConfig(config);
67
67
  const options = (factoryArgs[0] ?? {});
68
68
  const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
69
- const localNodeId = this._normalizeNodeId(options.localNodeId) ?? normalizedLocalNodeFromConfig;
69
+ const localNodeId = this._normalizeNodeId(options.localNodeId) ??
70
+ normalizedLocalNodeFromConfig;
70
71
  if (!localNodeId) {
71
72
  throw new Error('InPageConnectorFactory requires a localNodeId from config or create() options');
72
73
  }
@@ -87,7 +87,8 @@ export class InPageConnector extends BaseAsyncConnector {
87
87
  this.listenerRegistered = false;
88
88
  this.visibilityChangeListenerRegistered = false;
89
89
  this.channelName =
90
- typeof config.channelName === 'string' && config.channelName.trim().length > 0
90
+ typeof config.channelName === 'string' &&
91
+ config.channelName.trim().length > 0
91
92
  ? config.channelName.trim()
92
93
  : DEFAULT_CHANNEL;
93
94
  const preferredCapacity = typeof config.inboxCapacity === 'number' &&
@@ -126,7 +127,8 @@ export class InPageConnector extends BaseAsyncConnector {
126
127
  channel: this.channelName,
127
128
  connector_id: this.connectorId,
128
129
  message_type: message && typeof message === 'object'
129
- ? message.constructor?.name ?? typeof message
130
+ ? (message.constructor
131
+ ?.name ?? typeof message)
130
132
  : typeof message,
131
133
  has_sender_id: Boolean(message?.senderId),
132
134
  has_sender_node_id: Boolean(message?.senderNodeId),
@@ -135,7 +137,8 @@ export class InPageConnector extends BaseAsyncConnector {
135
137
  return;
136
138
  }
137
139
  const busMessage = message;
138
- const senderId = typeof busMessage.senderId === 'string' && busMessage.senderId.length > 0
140
+ const senderId = typeof busMessage.senderId === 'string' &&
141
+ busMessage.senderId.length > 0
139
142
  ? busMessage.senderId
140
143
  : null;
141
144
  const senderNodeId = InPageConnector.normalizeNodeId(busMessage.senderNodeId);
@@ -386,7 +389,9 @@ export class InPageConnector extends BaseAsyncConnector {
386
389
  timestamp: new Date().toISOString(),
387
390
  });
388
391
  }
389
- if (this.visibilityChangeListenerRegistered && this.visibilityChangeHandler && typeof document !== 'undefined') {
392
+ if (this.visibilityChangeListenerRegistered &&
393
+ this.visibilityChangeHandler &&
394
+ typeof document !== 'undefined') {
390
395
  document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
391
396
  this.visibilityChangeListenerRegistered = false;
392
397
  this.visibilityChangeHandler = undefined;
@@ -403,7 +408,7 @@ export class InPageConnector extends BaseAsyncConnector {
403
408
  return rawOrEnvelope;
404
409
  }
405
410
  _isWildcardTarget() {
406
- return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
411
+ return (this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined');
407
412
  }
408
413
  _shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
409
414
  if (this._isWildcardTarget()) {
@@ -423,7 +428,9 @@ export class InPageConnector extends BaseAsyncConnector {
423
428
  return true;
424
429
  }
425
430
  const expectedSender = this.targetNodeId;
426
- if (expectedSender && expectedSender !== '*' && senderNodeId !== expectedSender) {
431
+ if (expectedSender &&
432
+ expectedSender !== '*' &&
433
+ senderNodeId !== expectedSender) {
427
434
  logger.debug('inpage_message_rejected', {
428
435
  channel: this.channelName,
429
436
  connector_id: this.connectorId,