@livedesk/hub 0.1.40 → 0.1.41

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/hub",
3
- "version": "0.1.40",
3
+ "version": "0.1.41",
4
4
  "description": "LiveDesk local Hub API and browser frame bridge",
5
5
  "type": "module",
6
6
  "main": "src/server.js",
package/src/remote-hub.js CHANGED
@@ -9705,10 +9705,39 @@ export function createRemoteHub(options = {}) {
9705
9705
  liveStreamReplacementStillPending(activeLiveStream)
9706
9706
  ? 'stream-restart-superseded'
9707
9707
  : 'stream-start-timeout');
9708
- }
9709
- const commandId = safeString(options.commandId, 128) || crypto.randomUUID();
9710
- if (activeLiveStream
9711
- && options.forceRestart !== true
9708
+ }
9709
+ const commandId = safeString(options.commandId, 128) || crypto.randomUUID();
9710
+ const restartToken = safeString(options.restartToken, 128);
9711
+ if (activeLiveStream
9712
+ && options.forceRestart === true
9713
+ && restartToken
9714
+ && safeString(activeLiveStream.restartToken, 128) === restartToken
9715
+ && liveStreamMatchesOptions(activeLiveStream, normalized)
9716
+ && liveStreamIsReusable(activeLiveStream)) {
9717
+ emitRemoteEvent('RemoteLiveStreamRestartTokenReused', device, {
9718
+ streamId,
9719
+ commandId: activeLiveStream.commandId,
9720
+ restartToken,
9721
+ captureGeneration: Number(activeLiveStream.captureGeneration || 0)
9722
+ });
9723
+ return {
9724
+ ok: true,
9725
+ commandId: activeLiveStream.commandId,
9726
+ sessionId: device.sessionId,
9727
+ streamId,
9728
+ streamPurpose,
9729
+ fps: Number(activeLiveStream.fps || fps),
9730
+ mode: activeLiveStream.mode || transfer.mode,
9731
+ frameMode: activeLiveStream.frameMode || transfer.frameMode,
9732
+ monitorIndex: Number(activeLiveStream.monitorIndex ?? monitorIndex),
9733
+ captureGeneration: Number(activeLiveStream.captureGeneration || 0),
9734
+ ready: liveStreamHasCurrentFrame(activeLiveStream),
9735
+ pending: activeLiveStream.open !== true,
9736
+ reused: true
9737
+ };
9738
+ }
9739
+ if (activeLiveStream
9740
+ && options.forceRestart !== true
9712
9741
  && options.reuseExisting === true
9713
9742
  && liveStreamMatchesOptions(activeLiveStream, normalized)
9714
9743
  && liveStreamIsReusable(activeLiveStream)) {
@@ -9838,7 +9867,7 @@ export function createRemoteHub(options = {}) {
9838
9867
  monitorIndex,
9839
9868
  monitorCount: 1,
9840
9869
  startedAt: now,
9841
- restartToken: safeString(options.restartToken, 128),
9870
+ restartToken,
9842
9871
  stoppedAt: '',
9843
9872
  stopReason: '',
9844
9873
  stopPending: false,
package/src/server.js CHANGED
@@ -4430,12 +4430,13 @@ app.post('/api/auth/session', async (req, res) => {
4430
4430
  expires_at: expiresAt,
4431
4431
  user
4432
4432
  });
4433
- const hostTarget = runtimeRole === 'hub'
4434
- ? await publishHubHostTargetWithPendingRoleTakeover('session-received')
4435
- : { ok: true, active: false };
4436
- if (runtimeRole === 'hub') {
4437
- startHubHostTargetLeaseRenewal();
4438
- }
4433
+ const hostTarget = runtimeRole === 'hub'
4434
+ ? {
4435
+ ok: true,
4436
+ pending: true,
4437
+ active: remoteHub.getStatus({ includeSecrets: false }).hostTargetActive === true
4438
+ }
4439
+ : { ok: true, pending: false, active: false };
4439
4440
  const uiSession = hubUiSessionAuthority.issue(user.id);
4440
4441
  res.setHeader('Set-Cookie', serializeHubUiSessionCookie(uiSession.sessionId, uiSession.expiresAt, {
4441
4442
  secure: isSecureHubHttpRequest(req)
@@ -4452,6 +4453,9 @@ app.post('/api/auth/session', async (req, res) => {
4452
4453
  expiresAt: uiSession.expiresAt
4453
4454
  }
4454
4455
  });
4456
+ if (runtimeRole === 'hub') {
4457
+ scheduleAuthenticatedHubHostTargetPublication('session-received');
4458
+ }
4455
4459
  } catch (error) {
4456
4460
  const message = error instanceof Error ? error.message : String(error);
4457
4461
  const status = authVerificationHttpStatus(message);
@@ -4737,15 +4741,26 @@ async function clearHubHostTarget(reason = 'shutdown') {
4737
4741
  return { ok: !error, error, lease: getHubHostTargetLeaseStatus() };
4738
4742
  }
4739
4743
 
4740
- function startHubHostTargetLeaseRenewal() {
4744
+ function startHubHostTargetLeaseRenewal() {
4741
4745
  if (hubHostTargetRenewTimer || runtimeRole !== 'hub') {
4742
4746
  return;
4743
4747
  }
4744
4748
  hubHostTargetRenewTimer = setInterval(() => {
4745
4749
  void publishHubHostTargetWithPendingRoleTakeover('renewal');
4746
4750
  }, HUB_HOST_TARGET_RENEW_MS);
4747
- hubHostTargetRenewTimer.unref?.();
4748
- }
4751
+ hubHostTargetRenewTimer.unref?.();
4752
+ }
4753
+
4754
+ function scheduleAuthenticatedHubHostTargetPublication(reason = 'session-received') {
4755
+ startHubHostTargetLeaseRenewal();
4756
+ setImmediate(() => {
4757
+ void publishHubHostTargetWithPendingRoleTakeover(reason).catch(error => {
4758
+ const message = error instanceof Error ? error.message : String(error);
4759
+ updateHubHostTargetLeaseState({ state: 'error', lastError: message });
4760
+ console.error(`[LiveDesk Hub] Host target ${reason} background publish failed: ${message}`);
4761
+ });
4762
+ });
4763
+ }
4749
4764
 
4750
4765
  app.delete('/api/auth/session', async (req, res) => {
4751
4766
  noStore(res);