@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.
- package/dist/browser/index.cjs +262 -172
- package/dist/browser/index.mjs +261 -173
- package/dist/cjs/_env-shim.js +3 -1
- package/dist/cjs/naylence/fame/config/extended-fame-config.js +2 -1
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -4
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +14 -6
- package/dist/cjs/naylence/fame/connector/broadcast-channel-listener-factory.js +3 -1
- package/dist/cjs/naylence/fame/connector/broadcast-channel-listener.js +11 -7
- package/dist/cjs/naylence/fame/connector/index.js +2 -1
- package/dist/cjs/naylence/fame/connector/inpage-connector-factory.js +2 -1
- package/dist/cjs/naylence/fame/connector/inpage-connector.js +13 -6
- package/dist/cjs/naylence/fame/connector/inpage-listener-factory.js +4 -4
- package/dist/cjs/naylence/fame/connector/inpage-listener.js +5 -2
- package/dist/cjs/naylence/fame/delivery/default-delivery-tracker.js +4 -62
- package/dist/cjs/naylence/fame/fabric/fabric-registry.js +41 -0
- package/dist/cjs/naylence/fame/fabric/in-process-fame-fabric.js +3 -0
- package/dist/cjs/naylence/fame/fabric/index.js +3 -1
- package/dist/cjs/naylence/fame/grants/broadcast-channel-connection-grant.js +6 -3
- package/dist/cjs/naylence/fame/grants/inpage-connection-grant.js +4 -2
- package/dist/cjs/naylence/fame/http/oauth2-token-router.js +9 -9
- package/dist/cjs/naylence/fame/node/admission/default-node-attach-client.js +34 -5
- package/dist/cjs/naylence/fame/node/upstream-session-manager.js +40 -8
- package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +10 -6
- package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider.js +1 -2
- package/dist/cjs/naylence/fame/security/default-security-manager.js +2 -1
- package/dist/cjs/naylence/fame/security/trust-store/noop-trust-store-provider-factory.js +2 -2
- package/dist/cjs/naylence/fame/security/trust-store/trust-store-provider-factory.js +2 -2
- package/dist/cjs/naylence/fame/util/index.js +3 -1
- package/dist/cjs/node.js +4 -1
- package/dist/cjs/runtime-isomorphic.js +4 -1
- package/dist/cjs/version.js +2 -2
- package/dist/esm/_env-shim.js +3 -1
- package/dist/esm/browser.js +2 -2
- package/dist/esm/naylence/fame/config/extended-fame-config.js +2 -1
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector-factory.js +12 -4
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +14 -6
- package/dist/esm/naylence/fame/connector/broadcast-channel-listener-factory.js +3 -1
- package/dist/esm/naylence/fame/connector/broadcast-channel-listener.js +11 -7
- package/dist/esm/naylence/fame/connector/index.js +2 -2
- package/dist/esm/naylence/fame/connector/inpage-connector-factory.js +2 -1
- package/dist/esm/naylence/fame/connector/inpage-connector.js +13 -6
- package/dist/esm/naylence/fame/connector/inpage-listener-factory.js +4 -4
- package/dist/esm/naylence/fame/connector/inpage-listener.js +5 -2
- package/dist/esm/naylence/fame/delivery/default-delivery-tracker.js +4 -62
- package/dist/esm/naylence/fame/fabric/fabric-registry.js +37 -0
- package/dist/esm/naylence/fame/fabric/in-process-fame-fabric.js +3 -0
- package/dist/esm/naylence/fame/fabric/index.js +1 -0
- package/dist/esm/naylence/fame/grants/broadcast-channel-connection-grant.js +6 -3
- package/dist/esm/naylence/fame/grants/inpage-connection-grant.js +4 -2
- package/dist/esm/naylence/fame/http/oauth2-token-router.js +9 -9
- package/dist/esm/naylence/fame/node/admission/default-node-attach-client.js +34 -5
- package/dist/esm/naylence/fame/node/upstream-session-manager.js +40 -8
- package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider-factory.js +10 -6
- package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider.js +1 -2
- package/dist/esm/naylence/fame/security/default-security-manager.js +2 -1
- package/dist/esm/naylence/fame/security/index.js +1 -1
- package/dist/esm/naylence/fame/security/trust-store/noop-trust-store-provider-factory.js +3 -3
- package/dist/esm/naylence/fame/security/trust-store/trust-store-provider-factory.js +3 -3
- package/dist/esm/naylence/fame/util/index.js +1 -0
- package/dist/esm/node.js +2 -1
- package/dist/esm/runtime-isomorphic.js +2 -0
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +259 -171
- package/dist/node/index.mjs +258 -172
- package/dist/node/node.cjs +225 -136
- package/dist/node/node.mjs +223 -137
- package/dist/types/browser.d.ts +2 -2
- package/dist/types/naylence/fame/connector/broadcast-channel-connector-factory.d.ts +1 -0
- package/dist/types/naylence/fame/connector/index.d.ts +3 -3
- package/dist/types/naylence/fame/delivery/default-delivery-tracker.d.ts +0 -6
- package/dist/types/naylence/fame/fabric/fabric-registry.d.ts +29 -0
- package/dist/types/naylence/fame/fabric/index.d.ts +1 -0
- package/dist/types/naylence/fame/node/admission/default-node-attach-client.d.ts +1 -0
- package/dist/types/naylence/fame/security/index.d.ts +1 -1
- package/dist/types/naylence/fame/security/trust-store/noop-trust-store-provider-factory.d.ts +3 -3
- package/dist/types/naylence/fame/security/trust-store/trust-store-provider-factory.d.ts +4 -4
- package/dist/types/naylence/fame/security/trust-store/trust-store-provider.d.ts +5 -5
- package/dist/types/naylence/fame/util/index.d.ts +1 -0
- package/dist/types/node.d.ts +2 -1
- package/dist/types/runtime-isomorphic.d.ts +1 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/cjs/_env-shim.js
CHANGED
|
@@ -17,7 +17,9 @@ function installProcessEnvShim() {
|
|
|
17
17
|
if (g.__ENV__ && typeof g.__ENV__ === 'object')
|
|
18
18
|
Object.assign(out, g.__ENV__);
|
|
19
19
|
try {
|
|
20
|
-
//
|
|
20
|
+
// import.meta is only available in ESM builds
|
|
21
|
+
// prettier-ignore
|
|
22
|
+
// @ts-ignore
|
|
21
23
|
const ie = (typeof import.meta !== 'undefined' && import.meta.env) || undefined;
|
|
22
24
|
if (ie && typeof ie === 'object')
|
|
23
25
|
Object.assign(out, ie);
|
|
@@ -93,7 +93,8 @@ function createFsShim() {
|
|
|
93
93
|
else if (options &&
|
|
94
94
|
typeof options === 'object' &&
|
|
95
95
|
'encoding' in options &&
|
|
96
|
-
typeof options.encoding ===
|
|
96
|
+
typeof options.encoding ===
|
|
97
|
+
'string') {
|
|
97
98
|
encoding = options.encoding;
|
|
98
99
|
}
|
|
99
100
|
const data = fsBinding.readFileUtf8(pathOrDescriptor, 0);
|
|
@@ -47,10 +47,12 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
47
47
|
type: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
48
48
|
};
|
|
49
49
|
const channelCandidate = record.channelName ?? record['channel_name'];
|
|
50
|
-
if (typeof channelCandidate === 'string' &&
|
|
50
|
+
if (typeof channelCandidate === 'string' &&
|
|
51
|
+
channelCandidate.trim().length > 0) {
|
|
51
52
|
config.channelName = channelCandidate.trim();
|
|
52
53
|
}
|
|
53
|
-
const inboxCandidate = record.inboxCapacity ??
|
|
54
|
+
const inboxCandidate = record.inboxCapacity ??
|
|
55
|
+
record['inbox_capacity'];
|
|
54
56
|
if (typeof inboxCandidate === 'number' &&
|
|
55
57
|
Number.isFinite(inboxCandidate) &&
|
|
56
58
|
inboxCandidate > 0) {
|
|
@@ -74,9 +76,11 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
74
76
|
throw new Error('BroadcastChannelConnectorFactory requires a configuration');
|
|
75
77
|
}
|
|
76
78
|
const normalized = this._normalizeConfig(config);
|
|
77
|
-
const options = (factoryArgs[0] ??
|
|
79
|
+
const options = (factoryArgs[0] ??
|
|
80
|
+
{});
|
|
78
81
|
const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
|
|
79
|
-
const localNodeId = this._normalizeNodeId(options.localNodeId) ??
|
|
82
|
+
const localNodeId = this._normalizeNodeId(options.localNodeId) ??
|
|
83
|
+
normalizedLocalNodeFromConfig;
|
|
80
84
|
if (!localNodeId) {
|
|
81
85
|
throw new Error('BroadcastChannelConnectorFactory requires a localNodeId from config or create() options');
|
|
82
86
|
}
|
|
@@ -101,6 +105,7 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
101
105
|
inboxCapacity,
|
|
102
106
|
localNodeId,
|
|
103
107
|
initialTargetNodeId: resolvedTarget,
|
|
108
|
+
passive: normalized.passive,
|
|
104
109
|
};
|
|
105
110
|
const connector = new broadcast_channel_connector_js_1.BroadcastChannelConnector(connectorConfig, baseConfig);
|
|
106
111
|
if (options.authorization) {
|
|
@@ -139,6 +144,9 @@ class BroadcastChannelConnectorFactory extends connector_factory_js_1.ConnectorF
|
|
|
139
144
|
if (normalizedLocalNodeId) {
|
|
140
145
|
normalized.localNodeId = normalizedLocalNodeId;
|
|
141
146
|
}
|
|
147
|
+
if (typeof candidate.passive === 'boolean') {
|
|
148
|
+
normalized.passive = candidate.passive;
|
|
149
|
+
}
|
|
142
150
|
if (typeof candidate.flowControl === 'boolean') {
|
|
143
151
|
normalized.flowControl = candidate.flowControl;
|
|
144
152
|
}
|
|
@@ -20,7 +20,8 @@ const ensureBroadcastEnvironment = () => {
|
|
|
20
20
|
};
|
|
21
21
|
class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
22
22
|
static generateConnectorId() {
|
|
23
|
-
const globalCrypto = globalThis
|
|
23
|
+
const globalCrypto = globalThis
|
|
24
|
+
.crypto;
|
|
24
25
|
if (globalCrypto?.randomUUID) {
|
|
25
26
|
return globalCrypto.randomUUID();
|
|
26
27
|
}
|
|
@@ -75,7 +76,8 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
75
76
|
this.listenerRegistered = false;
|
|
76
77
|
this.visibilityChangeListenerRegistered = false;
|
|
77
78
|
this.channelName =
|
|
78
|
-
typeof config.channelName === 'string' &&
|
|
79
|
+
typeof config.channelName === 'string' &&
|
|
80
|
+
config.channelName.trim().length > 0
|
|
79
81
|
? config.channelName.trim()
|
|
80
82
|
: DEFAULT_CHANNEL;
|
|
81
83
|
const preferredCapacity = typeof config.inboxCapacity === 'number' &&
|
|
@@ -99,6 +101,7 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
99
101
|
local_node_id: this.localNodeId,
|
|
100
102
|
target_node_id: this.targetNodeId ?? null,
|
|
101
103
|
inbox_capacity: preferredCapacity,
|
|
104
|
+
passive: config.passive ?? false,
|
|
102
105
|
timestamp: new Date().toISOString(),
|
|
103
106
|
});
|
|
104
107
|
this.onMsg = (event) => {
|
|
@@ -116,7 +119,8 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
116
119
|
channel: this.channelName,
|
|
117
120
|
connector_id: this.connectorId,
|
|
118
121
|
message_type: message && typeof message === 'object'
|
|
119
|
-
? message.constructor
|
|
122
|
+
? (message.constructor
|
|
123
|
+
?.name ?? typeof message)
|
|
120
124
|
: typeof message,
|
|
121
125
|
has_sender_id: Boolean(message?.senderId),
|
|
122
126
|
has_sender_node_id: Boolean(message?.senderNodeId),
|
|
@@ -346,7 +350,9 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
346
350
|
timestamp: new Date().toISOString(),
|
|
347
351
|
});
|
|
348
352
|
}
|
|
349
|
-
if (this.visibilityChangeListenerRegistered &&
|
|
353
|
+
if (this.visibilityChangeListenerRegistered &&
|
|
354
|
+
this.visibilityChangeHandler &&
|
|
355
|
+
typeof document !== 'undefined') {
|
|
350
356
|
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
351
357
|
this.visibilityChangeListenerRegistered = false;
|
|
352
358
|
this.visibilityChangeHandler = undefined;
|
|
@@ -374,7 +380,7 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
374
380
|
return rawOrEnvelope;
|
|
375
381
|
}
|
|
376
382
|
_isWildcardTarget() {
|
|
377
|
-
return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
|
|
383
|
+
return (this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined');
|
|
378
384
|
}
|
|
379
385
|
_shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
|
|
380
386
|
if (this._isWildcardTarget()) {
|
|
@@ -394,7 +400,9 @@ class BroadcastChannelConnector extends base_async_connector_js_1.BaseAsyncConne
|
|
|
394
400
|
return true;
|
|
395
401
|
}
|
|
396
402
|
const expectedSender = this.targetNodeId;
|
|
397
|
-
if (expectedSender &&
|
|
403
|
+
if (expectedSender &&
|
|
404
|
+
expectedSender !== '*' &&
|
|
405
|
+
senderNodeId !== expectedSender) {
|
|
398
406
|
logger.debug('broadcast_channel_message_rejected', {
|
|
399
407
|
channel: this.channelName,
|
|
400
408
|
connector_id: this.connectorId,
|
|
@@ -53,7 +53,9 @@ function normalizeConfig(config) {
|
|
|
53
53
|
: DEFAULT_CHANNEL;
|
|
54
54
|
const rawInbox = record.inboxCapacity ?? record['inbox_capacity'];
|
|
55
55
|
let inboxCapacity = DEFAULT_INBOX_CAPACITY;
|
|
56
|
-
if (typeof rawInbox === 'number' &&
|
|
56
|
+
if (typeof rawInbox === 'number' &&
|
|
57
|
+
Number.isFinite(rawInbox) &&
|
|
58
|
+
rawInbox > 0) {
|
|
57
59
|
inboxCapacity = Math.floor(rawInbox);
|
|
58
60
|
}
|
|
59
61
|
else if (typeof rawInbox === 'string') {
|
|
@@ -14,9 +14,7 @@ const broadcast_channel_connection_grant_js_1 = require("../grants/broadcast-cha
|
|
|
14
14
|
const logger = (0, logging_js_1.getLogger)('naylence.fame.connector.broadcast_channel_listener');
|
|
15
15
|
const DEFAULT_CHANNEL = 'naylence-fabric';
|
|
16
16
|
const DEFAULT_INBOX_CAPACITY = 2048;
|
|
17
|
-
const RESPONSE_TYPE_MASK = core_1.FameResponseType.ACK |
|
|
18
|
-
core_1.FameResponseType.REPLY |
|
|
19
|
-
core_1.FameResponseType.STREAM;
|
|
17
|
+
const RESPONSE_TYPE_MASK = core_1.FameResponseType.ACK | core_1.FameResponseType.REPLY | core_1.FameResponseType.STREAM;
|
|
20
18
|
const isBrowserEnvironment = () => typeof window !== 'undefined' &&
|
|
21
19
|
typeof BroadcastChannel !== 'undefined' &&
|
|
22
20
|
typeof MessageEvent !== 'undefined';
|
|
@@ -230,9 +228,7 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
230
228
|
return null;
|
|
231
229
|
}
|
|
232
230
|
})();
|
|
233
|
-
if (error instanceof zod_1.ZodError &&
|
|
234
|
-
decoded &&
|
|
235
|
-
decoded.length > 0) {
|
|
231
|
+
if (error instanceof zod_1.ZodError && decoded && decoded.length > 0) {
|
|
236
232
|
try {
|
|
237
233
|
const reparsed = JSON.parse(decoded);
|
|
238
234
|
const candidate = reparsed.rtype;
|
|
@@ -455,11 +451,19 @@ class BroadcastChannelListener extends transport_listener_js_1.TransportListener
|
|
|
455
451
|
? Math.floor(initialWindowCandidate)
|
|
456
452
|
: undefined;
|
|
457
453
|
const initialTargetNodeId = this._normalizeNodeId(targetCandidate) ?? targetSystemId;
|
|
454
|
+
const passive = typeof passiveCandidate === 'boolean' ? passiveCandidate : true;
|
|
455
|
+
logger.debug('broadcast_channel_listener_building_connector_config', {
|
|
456
|
+
system_id: systemId,
|
|
457
|
+
channel_name: channelName,
|
|
458
|
+
passive,
|
|
459
|
+
has_base_config: !!baseConfig,
|
|
460
|
+
passive_candidate: passiveCandidate,
|
|
461
|
+
});
|
|
458
462
|
return {
|
|
459
463
|
type: broadcast_channel_connector_js_1.BROADCAST_CHANNEL_CONNECTOR_TYPE,
|
|
460
464
|
channelName,
|
|
461
465
|
inboxCapacity,
|
|
462
|
-
passive
|
|
466
|
+
passive,
|
|
463
467
|
initialWindow,
|
|
464
468
|
localNodeId,
|
|
465
469
|
initialTargetNodeId,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getBroadcastChannelListenerInstance = exports.BroadcastChannelListener = exports.getInPageListenerInstance = exports.InPageListener = exports.getHttpListenerInstance = exports.HttpListener = exports.getWebsocketListenerInstance = exports.WebSocketListener = exports.DefaultHttpServer = exports.TRANSPORT_LISTENER_FACTORY_BASE_TYPE = exports.TransportListener = exports._NoopFlowController = exports.BROADCAST_CHANNEL_CONNECTOR_TYPE = exports.BroadcastChannelConnector = exports.INPAGE_CONNECTOR_TYPE = exports.InPageConnector = exports.BoundedAsyncQueue = exports.QueueFullError = exports.HttpStatelessConnector = exports.WebSocketState = exports.WebSocketConnector = exports.createResource = exports.ConnectorFactory = exports.createConnectorConfig = exports.isConnectorConfig = exports.ConnectorConfigDefaults = exports.BaseAsyncConnector = void 0;
|
|
3
|
+
exports.getBroadcastChannelListenerInstance = exports.BroadcastChannelListener = exports.getInPageListenerInstance = exports.InPageListener = exports.getHttpListenerInstance = exports.HttpListener = exports.getWebsocketListenerInstance = exports.WebSocketListener = exports.DefaultHttpServer = exports.TRANSPORT_LISTENER_FACTORY_BASE_TYPE = exports.TransportListenerFactory = exports.TransportListener = exports._NoopFlowController = exports.BROADCAST_CHANNEL_CONNECTOR_TYPE = exports.BroadcastChannelConnector = exports.INPAGE_CONNECTOR_TYPE = exports.InPageConnector = exports.BoundedAsyncQueue = exports.QueueFullError = exports.HttpStatelessConnector = exports.WebSocketState = exports.WebSocketConnector = exports.createResource = exports.ConnectorFactory = exports.createConnectorConfig = exports.isConnectorConfig = exports.ConnectorConfigDefaults = exports.BaseAsyncConnector = void 0;
|
|
4
4
|
require("./http-listener-factory.js");
|
|
5
5
|
require("./websocket-listener-factory.js");
|
|
6
6
|
require("./inpage-listener-factory.js");
|
|
@@ -45,6 +45,7 @@ Object.defineProperty(exports, "_NoopFlowController", { enumerable: true, get: f
|
|
|
45
45
|
var transport_listener_js_1 = require("./transport-listener.js");
|
|
46
46
|
Object.defineProperty(exports, "TransportListener", { enumerable: true, get: function () { return transport_listener_js_1.TransportListener; } });
|
|
47
47
|
var transport_listener_factory_js_1 = require("./transport-listener-factory.js");
|
|
48
|
+
Object.defineProperty(exports, "TransportListenerFactory", { enumerable: true, get: function () { return transport_listener_factory_js_1.TransportListenerFactory; } });
|
|
48
49
|
Object.defineProperty(exports, "TRANSPORT_LISTENER_FACTORY_BASE_TYPE", { enumerable: true, get: function () { return transport_listener_factory_js_1.TRANSPORT_LISTENER_FACTORY_BASE_TYPE; } });
|
|
49
50
|
var default_http_server_js_1 = require("./default-http-server.js");
|
|
50
51
|
Object.defineProperty(exports, "DefaultHttpServer", { enumerable: true, get: function () { return default_http_server_js_1.DefaultHttpServer; } });
|
|
@@ -69,7 +69,8 @@ class InPageConnectorFactory extends connector_factory_js_1.ConnectorFactory {
|
|
|
69
69
|
const normalized = this._normalizeConfig(config);
|
|
70
70
|
const options = (factoryArgs[0] ?? {});
|
|
71
71
|
const normalizedLocalNodeFromConfig = this._normalizeNodeId(normalized.localNodeId);
|
|
72
|
-
const localNodeId = this._normalizeNodeId(options.localNodeId) ??
|
|
72
|
+
const localNodeId = this._normalizeNodeId(options.localNodeId) ??
|
|
73
|
+
normalizedLocalNodeFromConfig;
|
|
73
74
|
if (!localNodeId) {
|
|
74
75
|
throw new Error('InPageConnectorFactory requires a localNodeId from config or create() options');
|
|
75
76
|
}
|
|
@@ -90,7 +90,8 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
90
90
|
this.listenerRegistered = false;
|
|
91
91
|
this.visibilityChangeListenerRegistered = false;
|
|
92
92
|
this.channelName =
|
|
93
|
-
typeof config.channelName === 'string' &&
|
|
93
|
+
typeof config.channelName === 'string' &&
|
|
94
|
+
config.channelName.trim().length > 0
|
|
94
95
|
? config.channelName.trim()
|
|
95
96
|
: DEFAULT_CHANNEL;
|
|
96
97
|
const preferredCapacity = typeof config.inboxCapacity === 'number' &&
|
|
@@ -129,7 +130,8 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
129
130
|
channel: this.channelName,
|
|
130
131
|
connector_id: this.connectorId,
|
|
131
132
|
message_type: message && typeof message === 'object'
|
|
132
|
-
? message.constructor
|
|
133
|
+
? (message.constructor
|
|
134
|
+
?.name ?? typeof message)
|
|
133
135
|
: typeof message,
|
|
134
136
|
has_sender_id: Boolean(message?.senderId),
|
|
135
137
|
has_sender_node_id: Boolean(message?.senderNodeId),
|
|
@@ -138,7 +140,8 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
138
140
|
return;
|
|
139
141
|
}
|
|
140
142
|
const busMessage = message;
|
|
141
|
-
const senderId = typeof busMessage.senderId === 'string' &&
|
|
143
|
+
const senderId = typeof busMessage.senderId === 'string' &&
|
|
144
|
+
busMessage.senderId.length > 0
|
|
142
145
|
? busMessage.senderId
|
|
143
146
|
: null;
|
|
144
147
|
const senderNodeId = InPageConnector.normalizeNodeId(busMessage.senderNodeId);
|
|
@@ -389,7 +392,9 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
389
392
|
timestamp: new Date().toISOString(),
|
|
390
393
|
});
|
|
391
394
|
}
|
|
392
|
-
if (this.visibilityChangeListenerRegistered &&
|
|
395
|
+
if (this.visibilityChangeListenerRegistered &&
|
|
396
|
+
this.visibilityChangeHandler &&
|
|
397
|
+
typeof document !== 'undefined') {
|
|
393
398
|
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
|
|
394
399
|
this.visibilityChangeListenerRegistered = false;
|
|
395
400
|
this.visibilityChangeHandler = undefined;
|
|
@@ -406,7 +411,7 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
406
411
|
return rawOrEnvelope;
|
|
407
412
|
}
|
|
408
413
|
_isWildcardTarget() {
|
|
409
|
-
return this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined';
|
|
414
|
+
return (this.targetNodeId === '*' || typeof this.targetNodeId === 'undefined');
|
|
410
415
|
}
|
|
411
416
|
_shouldAcceptMessageFromBus(senderNodeId, targetNodeId) {
|
|
412
417
|
if (this._isWildcardTarget()) {
|
|
@@ -426,7 +431,9 @@ class InPageConnector extends base_async_connector_js_1.BaseAsyncConnector {
|
|
|
426
431
|
return true;
|
|
427
432
|
}
|
|
428
433
|
const expectedSender = this.targetNodeId;
|
|
429
|
-
if (expectedSender &&
|
|
434
|
+
if (expectedSender &&
|
|
435
|
+
expectedSender !== '*' &&
|
|
436
|
+
senderNodeId !== expectedSender) {
|
|
430
437
|
logger.debug('inpage_message_rejected', {
|
|
431
438
|
channel: this.channelName,
|
|
432
439
|
connector_id: this.connectorId,
|
|
@@ -53,7 +53,9 @@ function normalizeConfig(config) {
|
|
|
53
53
|
: DEFAULT_CHANNEL;
|
|
54
54
|
const rawInbox = record.inboxCapacity ?? record['inbox_capacity'];
|
|
55
55
|
let inboxCapacity = DEFAULT_INBOX_CAPACITY;
|
|
56
|
-
if (typeof rawInbox === 'number' &&
|
|
56
|
+
if (typeof rawInbox === 'number' &&
|
|
57
|
+
Number.isFinite(rawInbox) &&
|
|
58
|
+
rawInbox > 0) {
|
|
57
59
|
inboxCapacity = Math.floor(rawInbox);
|
|
58
60
|
}
|
|
59
61
|
else if (typeof rawInbox === 'string') {
|
|
@@ -81,9 +83,7 @@ class InPageListenerFactory extends transport_listener_factory_js_1.TransportLis
|
|
|
81
83
|
}
|
|
82
84
|
async create(config, ...factoryArgs) {
|
|
83
85
|
const normalized = normalizeConfig(config);
|
|
84
|
-
const [{ InPageListener }] = await Promise.all([
|
|
85
|
-
getInPageListenerModule(),
|
|
86
|
-
]);
|
|
86
|
+
const [{ InPageListener }] = await Promise.all([getInPageListenerModule()]);
|
|
87
87
|
void factoryArgs;
|
|
88
88
|
return new InPageListener({
|
|
89
89
|
channelName: normalized.channelName,
|
|
@@ -73,7 +73,9 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
73
73
|
typeof channelCandidate === 'string' && channelCandidate.trim().length > 0
|
|
74
74
|
? channelCandidate.trim()
|
|
75
75
|
: DEFAULT_CHANNEL;
|
|
76
|
-
const normalizedCapacity = typeof inboxCandidate === 'number' &&
|
|
76
|
+
const normalizedCapacity = typeof inboxCandidate === 'number' &&
|
|
77
|
+
Number.isFinite(inboxCandidate) &&
|
|
78
|
+
inboxCandidate > 0
|
|
77
79
|
? Math.floor(inboxCandidate)
|
|
78
80
|
: DEFAULT_INBOX_CAPACITY;
|
|
79
81
|
this._inboxCapacity = normalizedCapacity;
|
|
@@ -348,7 +350,8 @@ class InPageListener extends transport_listener_js_1.TransportListener {
|
|
|
348
350
|
if (grant.type === inpage_connection_grant_js_1.INPAGE_CONNECTION_GRANT_TYPE) {
|
|
349
351
|
return (0, inpage_connection_grant_js_1.inPageGrantToConnectorConfig)(grant);
|
|
350
352
|
}
|
|
351
|
-
if (typeof grant
|
|
353
|
+
if (typeof grant
|
|
354
|
+
?.toConnectorConfig === 'function') {
|
|
352
355
|
return grant.toConnectorConfig();
|
|
353
356
|
}
|
|
354
357
|
throw new Error(`Unsupported grant type: ${grant.type}`);
|
|
@@ -149,9 +149,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
149
149
|
this.ackDoneSince = new Map();
|
|
150
150
|
this.replyDoneSince = new Map();
|
|
151
151
|
this.pendingAckDispatches = new Set();
|
|
152
|
-
this.recentlyHandled = new Map();
|
|
153
|
-
this.recentlyHandledOrder = [];
|
|
154
|
-
this.recentlyHandledTtlMs = 60000;
|
|
155
152
|
this.isPreparingToStop = false;
|
|
156
153
|
this.shutdownRequestedAtMs = null;
|
|
157
154
|
this.shutdownRetryGraceMs = 1000;
|
|
@@ -387,22 +384,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
387
384
|
}
|
|
388
385
|
}
|
|
389
386
|
else {
|
|
390
|
-
const wasRecentlyHandled = await this.lock.runExclusive(async () => this.wasRecentlyHandled(envelope.id));
|
|
391
|
-
if (wasRecentlyHandled) {
|
|
392
|
-
logger.debug('tracker_duplicate_envelope_recently_handled', {
|
|
393
|
-
envp_id: envelope.id,
|
|
394
|
-
});
|
|
395
|
-
return new tracked_envelope_js_1.TrackedEnvelope({
|
|
396
|
-
timeoutAtMs: 0,
|
|
397
|
-
overallTimeoutAtMs: 0,
|
|
398
|
-
expectedResponseType: envelope.rtype ?? core_1.FameResponseType.NONE,
|
|
399
|
-
createdAtMs: Date.now(),
|
|
400
|
-
status: tracked_envelope_js_1.EnvelopeStatus.HANDLED,
|
|
401
|
-
mailboxType: tracked_envelope_js_1.MailboxType.INBOX,
|
|
402
|
-
originalEnvelope: envelope,
|
|
403
|
-
serviceName: inboxName,
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
387
|
tracked = new tracked_envelope_js_1.TrackedEnvelope({
|
|
407
388
|
timeoutAtMs: 0,
|
|
408
389
|
overallTimeoutAtMs: 0,
|
|
@@ -424,12 +405,8 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
424
405
|
async onEnvelopeHandled(envelope) {
|
|
425
406
|
const inbox = this.ensureInbox();
|
|
426
407
|
envelope.status = tracked_envelope_js_1.EnvelopeStatus.HANDLED;
|
|
408
|
+
// Delete the envelope from inbox to prevent growth
|
|
427
409
|
await inbox.delete(envelope.originalEnvelope.id);
|
|
428
|
-
await this.lock.runExclusive(async () => {
|
|
429
|
-
this.markRecentlyHandled(envelope.originalEnvelope.id);
|
|
430
|
-
});
|
|
431
|
-
// Preserve handled envelope to prevent duplicate redelivery during shutdown drains.
|
|
432
|
-
// await inbox.set(envelope.originalEnvelope.id, envelope);
|
|
433
410
|
}
|
|
434
411
|
async onEnvelopeHandleFailed(inboxName, envelope, context, error, isFinalFailure = false) {
|
|
435
412
|
void context;
|
|
@@ -648,9 +625,9 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
648
625
|
});
|
|
649
626
|
await this.markDoneSince(this.replyFutures, trackedEnvelope.originalEnvelope.id, this.replyDoneSince);
|
|
650
627
|
await this.markDoneSince(this.ackFutures, trackedEnvelope.originalEnvelope.id, this.ackDoneSince);
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
628
|
+
// Note: ACK is already sent in onCorrelatedMessage (lines 655-657)
|
|
629
|
+
// when the reply envelope is first delivered. No need to send it again here.
|
|
630
|
+
// Removing this duplicate sendAck call fixes the duplicate DeliveryAck bug.
|
|
654
631
|
for (const handler of this.eventHandlers) {
|
|
655
632
|
await handler.onEnvelopeReplied?.(trackedEnvelope, envelope);
|
|
656
633
|
}
|
|
@@ -800,8 +777,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
800
777
|
}
|
|
801
778
|
this.streamDone.clear();
|
|
802
779
|
this.correlationToEnvelope.clear();
|
|
803
|
-
this.recentlyHandled.clear();
|
|
804
|
-
this.recentlyHandledOrder.length = 0;
|
|
805
780
|
return values;
|
|
806
781
|
});
|
|
807
782
|
for (const timer of timers) {
|
|
@@ -1383,39 +1358,6 @@ class DefaultDeliveryTracker extends task_spawner_js_1.TaskSpawner {
|
|
|
1383
1358
|
this.pendingAckDispatches.delete(ackDispatch);
|
|
1384
1359
|
}
|
|
1385
1360
|
}
|
|
1386
|
-
markRecentlyHandled(envelopeId) {
|
|
1387
|
-
const now = Date.now();
|
|
1388
|
-
this.recentlyHandled.set(envelopeId, now);
|
|
1389
|
-
this.recentlyHandledOrder.push(envelopeId);
|
|
1390
|
-
this.trimRecentlyHandled(now);
|
|
1391
|
-
}
|
|
1392
|
-
wasRecentlyHandled(envelopeId) {
|
|
1393
|
-
const now = Date.now();
|
|
1394
|
-
const timestamp = this.recentlyHandled.get(envelopeId);
|
|
1395
|
-
if (timestamp === undefined) {
|
|
1396
|
-
return false;
|
|
1397
|
-
}
|
|
1398
|
-
if (now - timestamp > this.recentlyHandledTtlMs) {
|
|
1399
|
-
this.recentlyHandled.delete(envelopeId);
|
|
1400
|
-
return false;
|
|
1401
|
-
}
|
|
1402
|
-
return true;
|
|
1403
|
-
}
|
|
1404
|
-
trimRecentlyHandled(now) {
|
|
1405
|
-
while (this.recentlyHandledOrder.length > 0) {
|
|
1406
|
-
const candidate = this.recentlyHandledOrder[0];
|
|
1407
|
-
const timestamp = this.recentlyHandled.get(candidate);
|
|
1408
|
-
if (timestamp === undefined) {
|
|
1409
|
-
this.recentlyHandledOrder.shift();
|
|
1410
|
-
continue;
|
|
1411
|
-
}
|
|
1412
|
-
if (now - timestamp <= this.recentlyHandledTtlMs) {
|
|
1413
|
-
break;
|
|
1414
|
-
}
|
|
1415
|
-
this.recentlyHandled.delete(candidate);
|
|
1416
|
-
this.recentlyHandledOrder.shift();
|
|
1417
|
-
}
|
|
1418
|
-
}
|
|
1419
1361
|
getShutdownRetryDeferDelay(nowMs) {
|
|
1420
1362
|
if (!this.isPreparingToStop || this.shutdownRequestedAtMs === null) {
|
|
1421
1363
|
return null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Fabric Registry
|
|
4
|
+
*
|
|
5
|
+
* Provides a mapping from nodes to their associated fabrics.
|
|
6
|
+
* This allows agents to retrieve the fabric they were registered on
|
|
7
|
+
* without relying on the global fabric stack.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports._setFabricForNode = _setFabricForNode;
|
|
11
|
+
exports.getFabricForNode = getFabricForNode;
|
|
12
|
+
/**
|
|
13
|
+
* WeakMap to store the node-to-fabric mapping.
|
|
14
|
+
* Using WeakMap ensures that nodes can be garbage collected
|
|
15
|
+
* when no longer referenced elsewhere.
|
|
16
|
+
*/
|
|
17
|
+
const nodeToFabric = new WeakMap();
|
|
18
|
+
/**
|
|
19
|
+
* @internal
|
|
20
|
+
* Associates a node with its fabric. This should only be called
|
|
21
|
+
* by fabric implementations when they create or adopt a node.
|
|
22
|
+
*
|
|
23
|
+
* @param node - The node to associate
|
|
24
|
+
* @param fabric - The fabric that owns the node
|
|
25
|
+
*/
|
|
26
|
+
function _setFabricForNode(node, fabric) {
|
|
27
|
+
nodeToFabric.set(node, fabric);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the fabric associated with a node.
|
|
31
|
+
*
|
|
32
|
+
* This is useful for agents that need to access the fabric they
|
|
33
|
+
* were registered on, particularly in environments where multiple
|
|
34
|
+
* fabrics exist (e.g., React with multiple FabricProviders).
|
|
35
|
+
*
|
|
36
|
+
* @param node - The node to look up
|
|
37
|
+
* @returns The fabric associated with the node, or undefined if not found
|
|
38
|
+
*/
|
|
39
|
+
function getFabricForNode(node) {
|
|
40
|
+
return nodeToFabric.get(node);
|
|
41
|
+
}
|
|
@@ -8,6 +8,7 @@ const util_js_1 = require("../util/util.js");
|
|
|
8
8
|
const runtime_version_js_1 = require("../util/runtime-version.js");
|
|
9
9
|
const sink_service_js_1 = require("../service/sink-service.js");
|
|
10
10
|
const extended_fame_config_base_js_1 = require("../config/extended-fame-config-base.js");
|
|
11
|
+
const fabric_registry_js_1 = require("./fabric-registry.js");
|
|
11
12
|
const logger = (0, logging_js_1.getLogger)('naylence.fame.fabric.in_process');
|
|
12
13
|
function normalizeNodeConfig(config) {
|
|
13
14
|
if (config && typeof config === 'object' && !Array.isArray(config)) {
|
|
@@ -69,6 +70,8 @@ class InProcessFameFabric extends core_1.FameFabric {
|
|
|
69
70
|
this._currentNode = await node_like_factory_js_1.NodeLikeFactory.createNode(nodeConfig);
|
|
70
71
|
this._ownsNode = true;
|
|
71
72
|
}
|
|
73
|
+
// Register this fabric in the registry so agents can look it up
|
|
74
|
+
(0, fabric_registry_js_1._setFabricForNode)(this._currentNode, this);
|
|
72
75
|
if (this._ownsNode && !this._nodeStarted) {
|
|
73
76
|
await this.getRequiredNode().start();
|
|
74
77
|
this._nodeStarted = true;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FAME_FABRIC_FACTORY_BASE_TYPE = exports.InProcessFameFabricFactory = exports.InProcessFameFabric = void 0;
|
|
3
|
+
exports.getFabricForNode = exports.FAME_FABRIC_FACTORY_BASE_TYPE = exports.InProcessFameFabricFactory = exports.InProcessFameFabric = void 0;
|
|
4
4
|
var in_process_fame_fabric_js_1 = require("./in-process-fame-fabric.js");
|
|
5
5
|
Object.defineProperty(exports, "InProcessFameFabric", { enumerable: true, get: function () { return in_process_fame_fabric_js_1.InProcessFameFabric; } });
|
|
6
6
|
var in_process_fame_fabric_factory_js_1 = require("./in-process-fame-fabric-factory.js");
|
|
7
7
|
Object.defineProperty(exports, "InProcessFameFabricFactory", { enumerable: true, get: function () { return in_process_fame_fabric_factory_js_1.InProcessFameFabricFactory; } });
|
|
8
8
|
Object.defineProperty(exports, "FAME_FABRIC_FACTORY_BASE_TYPE", { enumerable: true, get: function () { return in_process_fame_fabric_factory_js_1.FAME_FABRIC_FACTORY_BASE_TYPE; } });
|
|
9
|
+
var fabric_registry_js_1 = require("./fabric-registry.js");
|
|
10
|
+
Object.defineProperty(exports, "getFabricForNode", { enumerable: true, get: function () { return fabric_registry_js_1.getFabricForNode; } });
|
|
@@ -47,14 +47,16 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
47
47
|
type,
|
|
48
48
|
purpose,
|
|
49
49
|
};
|
|
50
|
-
const channelValue = candidate.channelName ??
|
|
50
|
+
const channelValue = candidate.channelName ??
|
|
51
|
+
candidate['channel_name'];
|
|
51
52
|
if (channelValue !== undefined) {
|
|
52
53
|
if (typeof channelValue !== 'string' || channelValue.trim().length === 0) {
|
|
53
54
|
throw new TypeError('BroadcastChannelConnectionGrant "channelName" must be a non-empty string when provided');
|
|
54
55
|
}
|
|
55
56
|
result.channelName = channelValue.trim();
|
|
56
57
|
}
|
|
57
|
-
const inboxValue = candidate.inboxCapacity ??
|
|
58
|
+
const inboxValue = candidate.inboxCapacity ??
|
|
59
|
+
candidate['inbox_capacity'];
|
|
58
60
|
if (inboxValue !== undefined) {
|
|
59
61
|
if (typeof inboxValue !== 'number' ||
|
|
60
62
|
!Number.isFinite(inboxValue) ||
|
|
@@ -63,7 +65,8 @@ function normalizeBroadcastChannelConnectionGrant(candidate) {
|
|
|
63
65
|
}
|
|
64
66
|
result.inboxCapacity = Math.floor(inboxValue);
|
|
65
67
|
}
|
|
66
|
-
const windowValue = candidate.initialWindow ??
|
|
68
|
+
const windowValue = candidate.initialWindow ??
|
|
69
|
+
candidate['initial_window'];
|
|
67
70
|
if (windowValue !== undefined) {
|
|
68
71
|
if (typeof windowValue !== 'number' ||
|
|
69
72
|
!Number.isFinite(windowValue) ||
|
|
@@ -42,14 +42,16 @@ function normalizeInPageConnectionGrant(candidate) {
|
|
|
42
42
|
type,
|
|
43
43
|
purpose,
|
|
44
44
|
};
|
|
45
|
-
const channelValue = candidate.channelName ??
|
|
45
|
+
const channelValue = candidate.channelName ??
|
|
46
|
+
candidate['channel_name'];
|
|
46
47
|
if (channelValue !== undefined) {
|
|
47
48
|
if (typeof channelValue !== 'string' || channelValue.trim().length === 0) {
|
|
48
49
|
throw new TypeError('InPageConnectionGrant "channelName" must be a non-empty string when provided');
|
|
49
50
|
}
|
|
50
51
|
result.channelName = channelValue.trim();
|
|
51
52
|
}
|
|
52
|
-
const inboxValue = candidate.inboxCapacity ??
|
|
53
|
+
const inboxValue = candidate.inboxCapacity ??
|
|
54
|
+
candidate['inbox_capacity'];
|
|
53
55
|
if (inboxValue !== undefined) {
|
|
54
56
|
if (typeof inboxValue !== 'number' ||
|
|
55
57
|
!Number.isFinite(inboxValue) ||
|
|
@@ -423,7 +423,9 @@ function parseCookies(cookieHeader) {
|
|
|
423
423
|
if (!cookieHeader) {
|
|
424
424
|
return {};
|
|
425
425
|
}
|
|
426
|
-
return cookieHeader
|
|
426
|
+
return cookieHeader
|
|
427
|
+
.split(';')
|
|
428
|
+
.reduce((acc, entry) => {
|
|
427
429
|
const [rawName, ...rawValueParts] = entry.split('=');
|
|
428
430
|
const name = rawName?.trim();
|
|
429
431
|
if (!name) {
|
|
@@ -571,10 +573,7 @@ function setNoCacheHeaders(res) {
|
|
|
571
573
|
res.set('Pragma', 'no-cache');
|
|
572
574
|
}
|
|
573
575
|
function respondInvalidClient(res) {
|
|
574
|
-
res
|
|
575
|
-
.status(401)
|
|
576
|
-
.set('WWW-Authenticate', 'Basic')
|
|
577
|
-
.json({
|
|
576
|
+
res.status(401).set('WWW-Authenticate', 'Basic').json({
|
|
578
577
|
error: 'invalid_client',
|
|
579
578
|
error_description: 'Invalid client credentials',
|
|
580
579
|
});
|
|
@@ -611,10 +610,10 @@ function createOAuth2TokenRouter(options) {
|
|
|
611
610
|
DEFAULT_JWT_ALGORITHM;
|
|
612
611
|
const allowedScopes = getAllowedScopes(configAllowedScopes);
|
|
613
612
|
const resolvedTokenTtlSec = tokenTtlSec ?? 3600;
|
|
614
|
-
const enablePkce = coerceBoolean(process.env[ENV_VAR_ENABLE_PKCE]) ??
|
|
615
|
-
(configEnablePkce ?? true);
|
|
613
|
+
const enablePkce = coerceBoolean(process.env[ENV_VAR_ENABLE_PKCE]) ?? configEnablePkce ?? true;
|
|
616
614
|
const allowPublicClients = coerceBoolean(process.env[ENV_VAR_ALLOW_PUBLIC_CLIENTS]) ??
|
|
617
|
-
|
|
615
|
+
configAllowPublicClients ??
|
|
616
|
+
true;
|
|
618
617
|
const authorizationCodeTtlSec = ensurePositiveInteger(coerceNumber(process.env[ENV_VAR_AUTHORIZATION_CODE_TTL]) ??
|
|
619
618
|
configAuthorizationCodeTtlSec) ?? DEFAULT_AUTHORIZATION_CODE_TTL_SEC;
|
|
620
619
|
const devLoginExplicitlyEnabled = coerceBoolean(process.env[ENV_VAR_ENABLE_DEV_LOGIN]) ??
|
|
@@ -629,7 +628,8 @@ function createOAuth2TokenRouter(options) {
|
|
|
629
628
|
configDevLoginCookieName ??
|
|
630
629
|
DEFAULT_SESSION_COOKIE_NAME;
|
|
631
630
|
const devLoginSecureCookie = coerceBoolean(process.env[ENV_VAR_SESSION_SECURE_COOKIE]) ??
|
|
632
|
-
|
|
631
|
+
configDevLoginSecureCookie ??
|
|
632
|
+
false;
|
|
633
633
|
const devLoginTitle = coerceString(process.env[ENV_VAR_LOGIN_TITLE]) ??
|
|
634
634
|
configDevLoginTitle ??
|
|
635
635
|
DEFAULT_LOGIN_TITLE;
|