@naylence/runtime 0.3.12 → 0.3.13
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 +1479 -926
- package/dist/browser/index.mjs +1472 -927
- package/dist/cjs/naylence/fame/connector/broadcast-channel-connector.browser.js +1 -1
- package/dist/cjs/naylence/fame/factory-manifest.js +6 -0
- package/dist/cjs/naylence/fame/grants/grant-materializer.js +59 -0
- package/dist/cjs/naylence/fame/node/admission/admission-profile-factory.js +4 -2
- package/dist/cjs/naylence/fame/node/admission/direct-admission-client-factory.js +3 -1
- package/dist/cjs/naylence/fame/node/admission/direct-admission-client.js +12 -9
- package/dist/cjs/naylence/fame/node/default-node-identity-policy-factory.js +21 -0
- package/dist/cjs/naylence/fame/node/default-node-identity-policy.js +60 -0
- package/dist/cjs/naylence/fame/node/factory-commons.js +31 -7
- package/dist/cjs/naylence/fame/node/index.js +11 -1
- package/dist/cjs/naylence/fame/node/node-config.js +4 -0
- package/dist/cjs/naylence/fame/node/node-identity-policy-factory.js +22 -0
- package/dist/cjs/naylence/fame/node/node-identity-policy-profile-factory.js +67 -0
- package/dist/cjs/naylence/fame/node/node-identity-policy.js +2 -0
- package/dist/cjs/naylence/fame/node/node.js +45 -9
- package/dist/cjs/naylence/fame/node/root-session-manager.js +1 -11
- package/dist/cjs/naylence/fame/node/rpc-client-manager.js +10 -3
- package/dist/cjs/naylence/fame/node/token-subject-node-identity-policy-factory.js +55 -0
- package/dist/cjs/naylence/fame/node/token-subject-node-identity-policy.js +84 -0
- package/dist/cjs/naylence/fame/node/upstream-session-manager.js +87 -9
- package/dist/cjs/naylence/fame/security/auth/auth-identity.js +2 -0
- package/dist/cjs/naylence/fame/security/auth/materializable-token-provider.js +9 -0
- package/dist/cjs/naylence/fame/security/auth/oauth2-pkce-token-provider.js +9 -0
- package/dist/cjs/naylence/fame/security/auth/static-token-provider.js +44 -0
- package/dist/cjs/naylence/fame/security/auth/token-provider.js +6 -0
- package/dist/cjs/naylence/fame/security/default-security-manager.js +4 -2
- package/dist/cjs/naylence/fame/security/index.js +1 -0
- package/dist/cjs/naylence/fame/security/keys/default-key-manager.js +1 -1
- package/dist/cjs/naylence/fame/util/task-spawner.js +8 -0
- package/dist/cjs/version.js +2 -2
- package/dist/esm/naylence/fame/connector/broadcast-channel-connector.browser.js +1 -1
- package/dist/esm/naylence/fame/factory-manifest.js +6 -0
- package/dist/esm/naylence/fame/grants/grant-materializer.js +55 -0
- package/dist/esm/naylence/fame/node/admission/admission-profile-factory.js +4 -2
- package/dist/esm/naylence/fame/node/admission/direct-admission-client-factory.js +3 -1
- package/dist/esm/naylence/fame/node/admission/direct-admission-client.js +13 -10
- package/dist/esm/naylence/fame/node/default-node-identity-policy-factory.js +17 -0
- package/dist/esm/naylence/fame/node/default-node-identity-policy.js +56 -0
- package/dist/esm/naylence/fame/node/factory-commons.js +31 -7
- package/dist/esm/naylence/fame/node/index.js +7 -0
- package/dist/esm/naylence/fame/node/node-config.js +4 -0
- package/dist/esm/naylence/fame/node/node-identity-policy-factory.js +18 -0
- package/dist/esm/naylence/fame/node/node-identity-policy-profile-factory.js +63 -0
- package/dist/esm/naylence/fame/node/node-identity-policy.js +1 -0
- package/dist/esm/naylence/fame/node/node.js +45 -9
- package/dist/esm/naylence/fame/node/root-session-manager.js +1 -11
- package/dist/esm/naylence/fame/node/rpc-client-manager.js +10 -3
- package/dist/esm/naylence/fame/node/token-subject-node-identity-policy-factory.js +18 -0
- package/dist/esm/naylence/fame/node/token-subject-node-identity-policy.js +80 -0
- package/dist/esm/naylence/fame/node/upstream-session-manager.js +87 -9
- package/dist/esm/naylence/fame/security/auth/auth-identity.js +1 -0
- package/dist/esm/naylence/fame/security/auth/materializable-token-provider.js +6 -0
- package/dist/esm/naylence/fame/security/auth/oauth2-pkce-token-provider.js +9 -0
- package/dist/esm/naylence/fame/security/auth/static-token-provider.js +44 -0
- package/dist/esm/naylence/fame/security/auth/token-provider.js +5 -0
- package/dist/esm/naylence/fame/security/default-security-manager.js +4 -2
- package/dist/esm/naylence/fame/security/index.js +1 -0
- package/dist/esm/naylence/fame/security/keys/default-key-manager.js +1 -1
- package/dist/esm/naylence/fame/util/task-spawner.js +8 -0
- package/dist/esm/version.js +2 -2
- package/dist/node/index.cjs +1432 -879
- package/dist/node/index.mjs +1425 -880
- package/dist/node/node.cjs +1560 -1007
- package/dist/node/node.mjs +1553 -1008
- package/dist/types/naylence/fame/factory-manifest.d.ts +1 -1
- package/dist/types/naylence/fame/grants/grant-materializer.d.ts +4 -0
- package/dist/types/naylence/fame/node/admission/admission-profile-factory.d.ts +1 -1
- package/dist/types/naylence/fame/node/admission/direct-admission-client-factory.d.ts +1 -1
- package/dist/types/naylence/fame/node/admission/direct-admission-client.d.ts +3 -0
- package/dist/types/naylence/fame/node/default-node-identity-policy-factory.d.ts +15 -0
- package/dist/types/naylence/fame/node/default-node-identity-policy.d.ts +5 -0
- package/dist/types/naylence/fame/node/factory-commons.d.ts +2 -0
- package/dist/types/naylence/fame/node/index.d.ts +7 -0
- package/dist/types/naylence/fame/node/node-config.d.ts +2 -0
- package/dist/types/naylence/fame/node/node-identity-policy-factory.d.ts +12 -0
- package/dist/types/naylence/fame/node/node-identity-policy-profile-factory.d.ts +15 -0
- package/dist/types/naylence/fame/node/node-identity-policy.d.ts +26 -0
- package/dist/types/naylence/fame/node/node-like.d.ts +3 -1
- package/dist/types/naylence/fame/node/node.d.ts +4 -1
- package/dist/types/naylence/fame/node/root-session-manager.d.ts +0 -1
- package/dist/types/naylence/fame/node/rpc-client-manager.d.ts +2 -0
- package/dist/types/naylence/fame/node/token-subject-node-identity-policy-factory.d.ts +14 -0
- package/dist/types/naylence/fame/node/token-subject-node-identity-policy.d.ts +5 -0
- package/dist/types/naylence/fame/node/upstream-session-manager.d.ts +4 -0
- package/dist/types/naylence/fame/security/auth/auth-identity.d.ts +6 -0
- package/dist/types/naylence/fame/security/auth/materializable-token-provider.d.ts +12 -0
- package/dist/types/naylence/fame/security/auth/oauth2-pkce-token-provider.d.ts +4 -2
- package/dist/types/naylence/fame/security/auth/static-token-provider.d.ts +4 -2
- package/dist/types/naylence/fame/security/auth/token-provider.d.ts +5 -0
- package/dist/types/naylence/fame/security/index.d.ts +1 -0
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -100,6 +100,7 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
100
100
|
super();
|
|
101
101
|
this.readyEvent = new AsyncEvent();
|
|
102
102
|
this.stopEvent = new AsyncEvent();
|
|
103
|
+
this.wakeEvent = new AsyncEvent();
|
|
103
104
|
this.queueEvent = new AsyncEvent();
|
|
104
105
|
this.currentStopSubtasks = null;
|
|
105
106
|
this.messageQueue = [];
|
|
@@ -111,6 +112,7 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
111
112
|
this.hadSuccessfulAttach = false;
|
|
112
113
|
this.lastConnectorState = null;
|
|
113
114
|
this.connectEpoch = 0;
|
|
115
|
+
this._visibilityHandler = null;
|
|
114
116
|
const options = normalizeOptions(optionsInput);
|
|
115
117
|
this.node = options.node;
|
|
116
118
|
this.attachClient = options.attachClient;
|
|
@@ -130,6 +132,34 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
130
132
|
get systemId() {
|
|
131
133
|
return this.targetSystemId;
|
|
132
134
|
}
|
|
135
|
+
setupVisibilityListener() {
|
|
136
|
+
logger.debug('setup_visibility_listener_called', {
|
|
137
|
+
has_document: typeof document !== 'undefined',
|
|
138
|
+
});
|
|
139
|
+
if (typeof document !== 'undefined' && document.addEventListener) {
|
|
140
|
+
this._visibilityHandler = () => {
|
|
141
|
+
logger.debug('visibility_change_event_fired', {
|
|
142
|
+
state: document.visibilityState,
|
|
143
|
+
});
|
|
144
|
+
if (document.visibilityState === 'visible') {
|
|
145
|
+
logger.debug('visibility_change_detected_waking_up');
|
|
146
|
+
this.wakeEvent.set();
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
document.addEventListener('visibilitychange', this._visibilityHandler);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
logger.debug('setup_visibility_listener_skipped_no_document');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
teardownVisibilityListener() {
|
|
156
|
+
if (this._visibilityHandler &&
|
|
157
|
+
typeof document !== 'undefined' &&
|
|
158
|
+
document.removeEventListener) {
|
|
159
|
+
document.removeEventListener('visibilitychange', this._visibilityHandler);
|
|
160
|
+
this._visibilityHandler = null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
133
163
|
async start(options = {}) {
|
|
134
164
|
const { waitUntilReady = true } = options;
|
|
135
165
|
if (this.fsmTask) {
|
|
@@ -137,6 +167,8 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
137
167
|
}
|
|
138
168
|
this.stopEvent.clear();
|
|
139
169
|
this.readyEvent.clear();
|
|
170
|
+
this.wakeEvent.clear();
|
|
171
|
+
this.setupVisibilityListener();
|
|
140
172
|
const taskName = `upstream-fsm-${this.connectEpoch}`;
|
|
141
173
|
this.fsmTask = this.spawn(() => this.fsmLoop(), { name: taskName });
|
|
142
174
|
if (!waitUntilReady) {
|
|
@@ -157,6 +189,7 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
157
189
|
}
|
|
158
190
|
async stop() {
|
|
159
191
|
logger.debug('upstream_session_manager_stopping');
|
|
192
|
+
this.teardownVisibilityListener();
|
|
160
193
|
this.stopEvent.set();
|
|
161
194
|
this.currentStopSubtasks?.set();
|
|
162
195
|
if (this.fsmTask) {
|
|
@@ -210,11 +243,16 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
210
243
|
async fsmLoop() {
|
|
211
244
|
let delay = UpstreamSessionManager.BACKOFF_INITIAL;
|
|
212
245
|
while (!this.stopEvent.isSet()) {
|
|
246
|
+
const startTime = Date.now();
|
|
213
247
|
try {
|
|
214
248
|
await this.connectCycle();
|
|
215
249
|
delay = UpstreamSessionManager.BACKOFF_INITIAL;
|
|
216
250
|
}
|
|
217
251
|
catch (error) {
|
|
252
|
+
// Reset backoff if the connection was alive for more than 10 seconds
|
|
253
|
+
if (Date.now() - startTime > 10000) {
|
|
254
|
+
delay = UpstreamSessionManager.BACKOFF_INITIAL;
|
|
255
|
+
}
|
|
218
256
|
if (error instanceof TaskCancelledError) {
|
|
219
257
|
throw error;
|
|
220
258
|
}
|
|
@@ -229,11 +267,20 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
229
267
|
}
|
|
230
268
|
}
|
|
231
269
|
else {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
270
|
+
const err = error;
|
|
271
|
+
if (err.name === 'OAuth2PkceRedirectInitiatedError') {
|
|
272
|
+
logger.info('upstream_link_redirecting', {
|
|
273
|
+
error: err.message,
|
|
274
|
+
will_retry: true,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
logger.warning('upstream_link_closed', {
|
|
279
|
+
error: err.message,
|
|
280
|
+
will_retry: true,
|
|
281
|
+
exc_info: true,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
237
284
|
if (!this.hadSuccessfulAttach) {
|
|
238
285
|
throw error;
|
|
239
286
|
}
|
|
@@ -251,14 +298,40 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
251
298
|
if (delaySeconds <= 0) {
|
|
252
299
|
return;
|
|
253
300
|
}
|
|
301
|
+
// If the document is visible, cap the backoff delay to improve UX
|
|
302
|
+
// This ensures that if the user is watching, we retry quickly (e.g. 1s)
|
|
303
|
+
// instead of waiting for the full exponential backoff (up to 30s).
|
|
304
|
+
let effectiveDelay = delaySeconds;
|
|
305
|
+
if (typeof document !== 'undefined' &&
|
|
306
|
+
document.visibilityState === 'visible') {
|
|
307
|
+
effectiveDelay = Math.min(delaySeconds, 1.0);
|
|
308
|
+
if (effectiveDelay < delaySeconds) {
|
|
309
|
+
logger.debug('sleep_reduced_document_visible', {
|
|
310
|
+
original: delaySeconds,
|
|
311
|
+
new: effectiveDelay,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (this.wakeEvent.isSet()) {
|
|
316
|
+
this.wakeEvent.clear();
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
254
319
|
let timeout;
|
|
255
320
|
const sleepPromise = new Promise((resolve) => {
|
|
256
321
|
timeout = setTimeout(() => {
|
|
257
322
|
timeout = undefined;
|
|
258
323
|
resolve();
|
|
259
|
-
},
|
|
324
|
+
}, effectiveDelay * 1000);
|
|
260
325
|
});
|
|
261
|
-
await Promise.race([
|
|
326
|
+
await Promise.race([
|
|
327
|
+
sleepPromise,
|
|
328
|
+
this.stopEvent.wait(),
|
|
329
|
+
this.wakeEvent.wait(),
|
|
330
|
+
]);
|
|
331
|
+
if (this.wakeEvent.isSet()) {
|
|
332
|
+
logger.debug('sleep_interrupted_by_wake_event');
|
|
333
|
+
this.wakeEvent.clear();
|
|
334
|
+
}
|
|
262
335
|
if (timeout !== undefined) {
|
|
263
336
|
clearTimeout(timeout);
|
|
264
337
|
}
|
|
@@ -278,7 +351,7 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
278
351
|
return signal ? event.wait({ signal }) : event.wait();
|
|
279
352
|
}
|
|
280
353
|
_getLocalNodeId() {
|
|
281
|
-
const normalized = this._normalizeNodeId(this.node.
|
|
354
|
+
const normalized = this._normalizeNodeId(this.node.provisionalId);
|
|
282
355
|
if (!normalized) {
|
|
283
356
|
throw new Error('UpstreamSessionManager requires node with a stable identifier');
|
|
284
357
|
}
|
|
@@ -296,7 +369,7 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
296
369
|
throw new FameConnectError('Admission client is required to attach upstream');
|
|
297
370
|
}
|
|
298
371
|
this.connectEpoch += 1;
|
|
299
|
-
const welcome = await this.admissionClient.hello(this.node.
|
|
372
|
+
const welcome = await this.admissionClient.hello(this.node.provisionalId, generateId(), this.requestedLogicals);
|
|
300
373
|
const connectionGrants = welcome.frame.connectionGrants;
|
|
301
374
|
if (!connectionGrants?.length) {
|
|
302
375
|
throw new Error('Welcome frame missing connection grants');
|
|
@@ -338,6 +411,11 @@ export class UpstreamSessionManager extends TaskSpawner {
|
|
|
338
411
|
Array.isArray(welcome.frame.connectionGrants)) {
|
|
339
412
|
for (const grant of welcome.frame.connectionGrants) {
|
|
340
413
|
if (grant && typeof grant === 'object') {
|
|
414
|
+
const grantType = grant.type;
|
|
415
|
+
if (grantType === 'WebSocketConnectionGrant' ||
|
|
416
|
+
grantType === 'HttpConnectionGrant') {
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
341
419
|
// Avoid duplicates by checking if grant already exists
|
|
342
420
|
const isDuplicate = callbackGrants.some((existing) => JSON.stringify(existing) === JSON.stringify(grant));
|
|
343
421
|
if (!isDuplicate) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -271,6 +271,15 @@ export class OAuth2PkceTokenProvider {
|
|
|
271
271
|
constructor(rawOptions) {
|
|
272
272
|
this.options = normalizeOptions(rawOptions);
|
|
273
273
|
}
|
|
274
|
+
async materialize() {
|
|
275
|
+
const token = await this.getToken();
|
|
276
|
+
return {
|
|
277
|
+
type: 'StaticTokenProvider',
|
|
278
|
+
token: token.value,
|
|
279
|
+
expiresAt: token.expiresAt,
|
|
280
|
+
expires_at: token.expiresAt,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
274
283
|
async getToken() {
|
|
275
284
|
if (!isBrowserEnvironment()) {
|
|
276
285
|
throw new Error('OAuth2PkceTokenProvider requires a browser environment with sessionStorage support');
|
|
@@ -41,6 +41,50 @@ export class StaticTokenProvider {
|
|
|
41
41
|
async getToken() {
|
|
42
42
|
return { ...this.token };
|
|
43
43
|
}
|
|
44
|
+
async getIdentity() {
|
|
45
|
+
const tokenValue = this.token.value;
|
|
46
|
+
const parts = tokenValue.split('.');
|
|
47
|
+
if (parts.length !== 3) {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const payloadSegment = parts[1];
|
|
52
|
+
// Fix padding for base64url
|
|
53
|
+
const padding = '='.repeat((4 - (payloadSegment.length % 4)) % 4);
|
|
54
|
+
const base64 = (payloadSegment + padding)
|
|
55
|
+
.replace(/-/g, '+')
|
|
56
|
+
.replace(/_/g, '/');
|
|
57
|
+
let jsonString;
|
|
58
|
+
if (typeof Buffer !== 'undefined') {
|
|
59
|
+
jsonString = Buffer.from(base64, 'base64').toString('utf-8');
|
|
60
|
+
}
|
|
61
|
+
else if (typeof atob === 'function') {
|
|
62
|
+
jsonString = atob(base64);
|
|
63
|
+
try {
|
|
64
|
+
jsonString = decodeURIComponent(jsonString
|
|
65
|
+
.split('')
|
|
66
|
+
.map(function (c) {
|
|
67
|
+
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
|
68
|
+
})
|
|
69
|
+
.join(''));
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// ignore
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const payload = JSON.parse(jsonString);
|
|
79
|
+
if (payload && typeof payload.sub === 'string') {
|
|
80
|
+
return { subject: payload.sub, claims: payload };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// ignore decoding errors
|
|
85
|
+
}
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
44
88
|
}
|
|
45
89
|
function normalizeOptions(input) {
|
|
46
90
|
if (input === null || input === undefined) {
|
|
@@ -3,3 +3,8 @@ export function isTokenProvider(candidate) {
|
|
|
3
3
|
candidate !== null &&
|
|
4
4
|
typeof candidate.getToken === 'function');
|
|
5
5
|
}
|
|
6
|
+
export function isIdentityExposingTokenProvider(candidate) {
|
|
7
|
+
return (isTokenProvider(candidate) &&
|
|
8
|
+
typeof candidate.getIdentity ===
|
|
9
|
+
'function');
|
|
10
|
+
}
|
|
@@ -377,7 +377,7 @@ export class DefaultSecurityManager {
|
|
|
377
377
|
async onNodeInitialized(node) {
|
|
378
378
|
this._node = node;
|
|
379
379
|
logger.debug('security_manager_node_initialized', {
|
|
380
|
-
node_id: node.
|
|
380
|
+
node_id: node.provisionalId,
|
|
381
381
|
has_node_crypto_provider: Boolean(node.cryptoProvider),
|
|
382
382
|
provider_type: node.cryptoProvider
|
|
383
383
|
? (node.cryptoProvider.constructor?.name ?? 'unknown')
|
|
@@ -401,7 +401,9 @@ export class DefaultSecurityManager {
|
|
|
401
401
|
if (encryption && hasNodeListenerMethod(encryption, 'onNodeInitialized')) {
|
|
402
402
|
await encryption.onNodeInitialized(node);
|
|
403
403
|
}
|
|
404
|
-
logger.debug('node_security_initialization_complete', {
|
|
404
|
+
logger.debug('node_security_initialization_complete', {
|
|
405
|
+
node_id: node.provisionalId,
|
|
406
|
+
});
|
|
405
407
|
}
|
|
406
408
|
async onNodeAttachToPeer(node, attachInfo, connector) {
|
|
407
409
|
const attachRecord = attachInfo;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './auth/authorizer.js';
|
|
2
|
+
export * from './auth/auth-identity.js';
|
|
2
3
|
export { AUTHORIZER_FACTORY_BASE_TYPE, AuthorizerFactory, } from './auth/authorizer-factory.js';
|
|
3
4
|
export * from './auth/auth-injection-strategy.js';
|
|
4
5
|
export { AUTH_INJECTION_STRATEGY_FACTORY_BASE_TYPE, AuthInjectionStrategyFactory, } from './auth/auth-injection-strategy-factory.js';
|
|
@@ -92,7 +92,7 @@ export class DefaultKeyManager {
|
|
|
92
92
|
this.node = node;
|
|
93
93
|
this.routingNode = isRoutingNode(node) ? node : null;
|
|
94
94
|
logger.debug('key_manager_started', {
|
|
95
|
-
node_id:
|
|
95
|
+
node_id: node.provisionalId,
|
|
96
96
|
physical_path: this.physicalPath,
|
|
97
97
|
has_upstream: this.hasUpstream,
|
|
98
98
|
});
|
|
@@ -275,6 +275,14 @@ export class TaskSpawner {
|
|
|
275
275
|
});
|
|
276
276
|
return;
|
|
277
277
|
}
|
|
278
|
+
// Handle PKCE redirect "errors" as info
|
|
279
|
+
if (error.name === 'OAuth2PkceRedirectInitiatedError') {
|
|
280
|
+
logger.debug('background_task_redirecting', {
|
|
281
|
+
task_name: taskName,
|
|
282
|
+
note: 'Task interrupted for PKCE redirect',
|
|
283
|
+
});
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
278
286
|
// Check if this is a retriable connection error (will be logged and retried by FSM)
|
|
279
287
|
const isRetriableError = error.name === 'FameConnectError' ||
|
|
280
288
|
error.message.includes('missed heartbeat') ||
|
package/dist/esm/version.js
CHANGED
|
@@ -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.
|
|
2
|
+
// Generated from package.json version: 0.3.13
|
|
3
3
|
/**
|
|
4
4
|
* The package version, injected at build time.
|
|
5
5
|
* @internal
|
|
6
6
|
*/
|
|
7
|
-
export const VERSION = '0.3.
|
|
7
|
+
export const VERSION = '0.3.13';
|