@camera.ui/transport 0.0.5 → 0.0.6

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/README.md CHANGED
@@ -7,4 +7,4 @@ The camera.ui transport layer — a framework-agnostic connection kernel with pl
7
7
 
8
8
  ---
9
9
 
10
- *Part of the camera.ui ecosystem - A comprehensive camera management solution.*
10
+ _Part of the camera.ui ecosystem - A comprehensive camera management solution._
@@ -0,0 +1,10 @@
1
+ import { Kernel } from '../core/kernel.js';
2
+ export type Detach = () => void;
3
+ export interface ReconnectWatchdogOptions {
4
+ readonly kernel: Kernel;
5
+ readonly escalateAfterMs?: number;
6
+ readonly setTimer?: (cb: () => void, ms: number) => unknown;
7
+ readonly clearTimer?: (handle: unknown) => void;
8
+ readonly onEscalate?: (attempt: number) => void;
9
+ }
10
+ export declare function attachReconnectWatchdog(options: ReconnectWatchdogOptions): Detach;
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ export { attachNetworkChange } from './effects/networkChange.js';
7
7
  export { attachPersistence, localStorageAdapter, memoryStorageAdapter } from './effects/persistence.js';
8
8
  export { attachPresence, defaultOnNetworkOnline } from './effects/presence.js';
9
9
  export { attachProbeLoop, isProbeFailure, makeProbeFailure } from './effects/probeLoop.js';
10
+ export { attachReconnectWatchdog } from './effects/reconnectWatchdog.js';
10
11
  export { attachTokenLifecycle } from './effects/tokenLifecycle.js';
11
12
  export { attachTransportSync } from './effects/transportSync.js';
12
13
  export { attachTransportWatchdog } from './effects/transportWatchdog.js';
@@ -21,6 +22,7 @@ export type { NetworkChangeOptions, NetworkChangeSource } from './effects/networ
21
22
  export type { PersistedTarget, Persistence, PersistenceOptions, StorageAdapter } from './effects/persistence.js';
22
23
  export type { PresenceCallback, PresenceOptions, VisibilitySource } from './effects/presence.js';
23
24
  export type { ProbeContext, ProbeFailure, ProbeFailureKind, ProbeLoopOptions } from './effects/probeLoop.js';
25
+ export type { ReconnectWatchdogOptions } from './effects/reconnectWatchdog.js';
24
26
  export type { Detach, RefreshReason, TokenLifecycle, TokenLifecycleOptions } from './effects/tokenLifecycle.js';
25
27
  export type { TransportSyncOptions } from './effects/transportSync.js';
26
28
  export type { TransportWatchdogOptions, WatchdogClearReason } from './effects/transportWatchdog.js';
package/dist/index.js CHANGED
@@ -717,6 +717,45 @@ function attachProbeLoop(options) {
717
717
  };
718
718
  }
719
719
  //#endregion
720
+ //#region src/effects/reconnectWatchdog.ts
721
+ var DEFAULT_ESCALATE_AFTER_MS = 12e3;
722
+ function attachReconnectWatchdog(options) {
723
+ const escalateAfterMs = options.escalateAfterMs ?? DEFAULT_ESCALATE_AFTER_MS;
724
+ const setTimer = options.setTimer ?? ((cb, ms) => setTimeout(cb, ms));
725
+ const clearTimer = options.clearTimer ?? ((h) => clearTimeout(h));
726
+ let timer;
727
+ let attempt = 0;
728
+ let detached = false;
729
+ function cancelTimer() {
730
+ if (timer !== void 0) {
731
+ clearTimer(timer);
732
+ timer = void 0;
733
+ }
734
+ }
735
+ function arm() {
736
+ cancelTimer();
737
+ timer = setTimer(() => {
738
+ timer = void 0;
739
+ if (detached) return;
740
+ if (options.kernel.phase.kind !== "reconnecting") return;
741
+ attempt += 1;
742
+ options.onEscalate?.(attempt);
743
+ options.kernel.dispatch({ type: "USER_RETRY" });
744
+ }, escalateAfterMs);
745
+ }
746
+ const unsubKernel = options.kernel.subscribe((next, prev) => {
747
+ if (next.kind === "reconnecting" && prev.kind !== "reconnecting") arm();
748
+ else if (next.kind !== "reconnecting" && prev.kind === "reconnecting") cancelTimer();
749
+ if (next.kind === "online" || next.kind === "idle") attempt = 0;
750
+ });
751
+ if (options.kernel.phase.kind === "reconnecting") arm();
752
+ return () => {
753
+ detached = true;
754
+ cancelTimer();
755
+ unsubKernel();
756
+ };
757
+ }
758
+ //#endregion
720
759
  //#region src/effects/tokenLifecycle.ts
721
760
  var DEFAULT_GRACE_MS$1 = 5e3;
722
761
  var DEFAULT_MAX_TRANSIENT_RETRIES = 3;
@@ -1098,4 +1137,4 @@ function attachWorkerBridge(options) {
1098
1137
  };
1099
1138
  }
1100
1139
  //#endregion
1101
- export { DEFAULT_RACE_TIMEOUT_BY_MODE, RaceFirstError, TransportEmitter, attachBackoff, attachCrossTab, attachNetworkChange, attachPersistence, attachPresence, attachProbeLoop, attachTokenLifecycle, attachTransportSync, attachTransportWatchdog, attachWorkerBridge, createKernel, defaultOnNetworkOnline, endpointKey, isEndpointChange, isProbeFailure, isSameEndpoint, isSameTarget, isTokenOnlyChange, localStorageAdapter, makeProbeFailure, memoryStorageAdapter, raceFirst, reducer, sortByPriority };
1140
+ export { DEFAULT_RACE_TIMEOUT_BY_MODE, RaceFirstError, TransportEmitter, attachBackoff, attachCrossTab, attachNetworkChange, attachPersistence, attachPresence, attachProbeLoop, attachReconnectWatchdog, attachTokenLifecycle, attachTransportSync, attachTransportWatchdog, attachWorkerBridge, createKernel, defaultOnNetworkOnline, endpointKey, isEndpointChange, isProbeFailure, isSameEndpoint, isSameTarget, isTokenOnlyChange, localStorageAdapter, makeProbeFailure, memoryStorageAdapter, raceFirst, reducer, sortByPriority };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camera.ui/transport",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "camera.ui transport layer — framework-agnostic connection kernel, reducer state, pluggable transports (HTTP/WS/Socket.IO/NATS), lifecycle effects and worker bridge",
5
5
  "author": "seydx (https://github.com/cameraui/clients)",
6
6
  "type": "module",
@@ -57,21 +57,21 @@
57
57
  },
58
58
  "dependencies": {
59
59
  "@camera.ui/rpc": ">=1.0.4",
60
- "axios": ">=1.18.0",
60
+ "axios": ">=1.18.1",
61
61
  "socket.io-client": ">=4.8.3"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@eslint/js": "9.39.4",
65
65
  "@stylistic/eslint-plugin": "^5.10.0",
66
- "@typescript-eslint/parser": "^8.61.1",
66
+ "@typescript-eslint/parser": "^8.62.0",
67
67
  "@vue/language-core": "^3.3.5",
68
68
  "eslint": "9.39.2",
69
- "globals": "^17.6.0",
69
+ "globals": "^17.7.0",
70
70
  "jiti": "^2.7.0",
71
71
  "prettier": "^3.8.4",
72
72
  "rimraf": "^6.1.3",
73
73
  "typescript": "5.9.3",
74
- "typescript-eslint": "^8.61.1",
74
+ "typescript-eslint": "^8.62.0",
75
75
  "unplugin-dts": "^1.0.2",
76
76
  "updates": "^17.18.0",
77
77
  "vite": "^8.0.16",