@camera.ui/transport 0.1.2 → 0.1.3

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.
@@ -1,4 +1,4 @@
1
- //#region src/transports/closeCodes.ts
1
+ // src/transports/closeCodes.ts
2
2
  function classifyErrorCode(code) {
3
3
  if (code === "insufficient_role" || code === "user_not_found") return "forbidden";
4
4
  if (code === "invalid_token" || code === "unauthenticated" || code.startsWith("credentials_")) return "auth-expired";
@@ -26,5 +26,4 @@ function refusedByServer(input) {
26
26
  data
27
27
  }) === "forbidden";
28
28
  }
29
- //#endregion
30
29
  export { refusedByServer as n, classifyClose as t };
@@ -1,4 +1,4 @@
1
- //#region src/transports/contract.ts
1
+ // src/transports/contract.ts
2
2
  function isSameTarget(a, b) {
3
3
  if (a === b) return true;
4
4
  if (!a || !b) return false;
@@ -34,5 +34,4 @@ var TransportEmitter = class {
34
34
  this.listeners.clear();
35
35
  }
36
36
  };
37
- //#endregion
38
37
  export { isEndpointChange as n, isSameTarget as r, TransportEmitter as t };
@@ -29,6 +29,7 @@ export interface TransportStatus {
29
29
  readonly up: boolean;
30
30
  readonly lastError?: string;
31
31
  readonly downSince?: number;
32
+ readonly refused?: boolean;
32
33
  }
33
34
  export type ConnectionPhase = {
34
35
  readonly kind: 'idle';
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ export { attachWorkerBridge } from './effects/workerBridge.js';
14
14
  export { createConnectionJournal } from './journal.js';
15
15
  export { raceFirst } from './race.js';
16
16
  export { createConnectionSignal } from './signal.js';
17
- export { classifyClose } from './transports/closeCodes.js';
17
+ export { classifyClose, refusedByServer } from './transports/closeCodes.js';
18
18
  export { isEndpointChange, isSameTarget, TransportEmitter } from './transports/contract.js';
19
19
  export type { Kernel, KernelOptions, Listener, Unsubscribe } from './core/kernel.js';
20
20
  export type { Action, BackoffHint, ConnectionPhase, ConnectionTarget, Endpoint, EndpointMode, ReducerContext, Tokens, TransportId, TransportKind, TransportSpec, TransportStatus, } from './core/types.js';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { n as refusedByServer, t as classifyClose } from "./closeCodes-CltSRjdJ.js";
2
- import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "./contract-dt1m8U-o.js";
1
+ import { n as refusedByServer, t as classifyClose } from "./closeCodes-C0yINgIE.js";
2
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "./contract-CWxqxCKG.js";
3
3
  import { Logger } from "@camera.ui/logger";
4
- //#region src/core/reducer.ts
4
+ // src/core/reducer.ts
5
5
  var DEFAULT_BACKOFF_MS = 5e3;
6
6
  function reducer(phase, action, ctx) {
7
7
  switch (action.type) {
@@ -118,8 +118,7 @@ function withPending(next, prev) {
118
118
  function tokensEqual(a, b) {
119
119
  return a.access === b.access && a.refresh === b.refresh && a.accessExpiresAt === b.accessExpiresAt && a.refreshExpiresAt === b.refreshExpiresAt && a.proxySession === b.proxySession && a.proxySessionExpiresAt === b.proxySessionExpiresAt && a.proxyRefresh === b.proxyRefresh;
120
120
  }
121
- //#endregion
122
- //#region src/core/kernel.ts
121
+ // src/core/kernel.ts
123
122
  var log$1 = new Logger("kernel");
124
123
  function createKernel(options) {
125
124
  let current = options.initial ?? { kind: "idle" };
@@ -178,8 +177,7 @@ function createKernel(options) {
178
177
  dispose
179
178
  };
180
179
  }
181
- //#endregion
182
- //#region src/race.ts
180
+ // src/race.ts
183
181
  var DEFAULT_RACE_TIMEOUT_BY_MODE = {
184
182
  "direct-lan": 2e3,
185
183
  "direct-wan": 5e3
@@ -299,8 +297,7 @@ function raceFirst(candidates, options = {}) {
299
297
  });
300
298
  });
301
299
  }
302
- //#endregion
303
- //#region src/effects/backgroundProbe.ts
300
+ // src/effects/backgroundProbe.ts
304
301
  function createBackgroundProbe(options) {
305
302
  let inflight = null;
306
303
  let disposed = false;
@@ -381,8 +378,7 @@ function createBackgroundProbe(options) {
381
378
  }
382
379
  };
383
380
  }
384
- //#endregion
385
- //#region src/effects/backoff.ts
381
+ // src/effects/backoff.ts
386
382
  var DEFAULT_SCHEDULE = [
387
383
  5e3,
388
384
  1e4,
@@ -452,8 +448,7 @@ function attachBackoff(options) {
452
448
  unsubKernel();
453
449
  };
454
450
  }
455
- //#endregion
456
- //#region src/effects/crossTab.ts
451
+ // src/effects/crossTab.ts
457
452
  var DEFAULT_KEY$1 = "camera.ui:transport:target";
458
453
  function attachCrossTab(options) {
459
454
  const key = options.key ?? DEFAULT_KEY$1;
@@ -507,8 +502,7 @@ function attachCrossTab(options) {
507
502
  source.removeEventListener("storage", handle);
508
503
  };
509
504
  }
510
- //#endregion
511
- //#region src/effects/degradedRecovery.ts
505
+ // src/effects/degradedRecovery.ts
512
506
  var DEFAULT_GRACE_MS$1 = 1e4;
513
507
  var DEFAULT_MAX_BACKOFF_MS = 3e5;
514
508
  function attachDegradedRecovery(options) {
@@ -593,8 +587,7 @@ function attachDegradedRecovery(options) {
593
587
  unsub();
594
588
  };
595
589
  }
596
- //#endregion
597
- //#region src/effects/networkChange.ts
590
+ // src/effects/networkChange.ts
598
591
  function attachNetworkChange(options) {
599
592
  const debounceMs = options.debounceMs ?? 0;
600
593
  let detached = false;
@@ -621,8 +614,7 @@ function attachNetworkChange(options) {
621
614
  options.source.removeEventListener("change", handler);
622
615
  };
623
616
  }
624
- //#endregion
625
- //#region src/effects/persistence.ts
617
+ // src/effects/persistence.ts
626
618
  var DEFAULT_KEY = "camera.ui:transport:target";
627
619
  var DEFAULT_READY_TIMEOUT_MS = 3e3;
628
620
  function attachPersistence(options) {
@@ -771,8 +763,7 @@ function memoryStorageAdapter(initial = {}) {
771
763
  }
772
764
  };
773
765
  }
774
- //#endregion
775
- //#region src/effects/presence.ts
766
+ // src/effects/presence.ts
776
767
  var defaultOnNetworkOnline = (kernel) => {
777
768
  if (kernel.phase.kind === "offline") kernel.dispatch({ type: "USER_RETRY" });
778
769
  };
@@ -807,8 +798,7 @@ function attachPresence(options) {
807
798
  cleanups.length = 0;
808
799
  };
809
800
  }
810
- //#endregion
811
- //#region src/effects/probeLoop.ts
801
+ // src/effects/probeLoop.ts
812
802
  function makeProbeFailure(kind, message) {
813
803
  const err = new Error(message);
814
804
  err.kind = kind;
@@ -944,8 +934,7 @@ function attachProbeLoop(options) {
944
934
  unsub();
945
935
  };
946
936
  }
947
- //#endregion
948
- //#region src/effects/tokenLifecycle.ts
937
+ // src/effects/tokenLifecycle.ts
949
938
  var DEFAULT_GRACE_MS = 5e3;
950
939
  var DEFAULT_MAX_TRANSIENT_RETRIES = 3;
951
940
  var DEFAULT_TRANSIENT_RETRY_DELAY_MS = 2e3;
@@ -1289,8 +1278,7 @@ function stringifyError(err) {
1289
1278
  if (typeof err === "string") return err;
1290
1279
  return "refresh-failed";
1291
1280
  }
1292
- //#endregion
1293
- //#region src/effects/transportSync.ts
1281
+ // src/effects/transportSync.ts
1294
1282
  var SKIP = Symbol("transport-sync-skip");
1295
1283
  var DEFAULT_RETRY_MS = 2e3;
1296
1284
  function syncTargetFor(phase) {
@@ -1360,8 +1348,7 @@ function attachTransportSync(options) {
1360
1348
  unsub();
1361
1349
  };
1362
1350
  }
1363
- //#endregion
1364
- //#region src/effects/workerBridge.ts
1351
+ // src/effects/workerBridge.ts
1365
1352
  var log = new Logger("workerBridge");
1366
1353
  function attachWorkerBridge(options) {
1367
1354
  let generation = 0;
@@ -1498,8 +1485,7 @@ function attachWorkerBridge(options) {
1498
1485
  forgetHost
1499
1486
  };
1500
1487
  }
1501
- //#endregion
1502
- //#region src/journal.ts
1488
+ // src/journal.ts
1503
1489
  var DEFAULT_CAPACITY = 1e3;
1504
1490
  var MAX_DETAIL_LENGTH = 300;
1505
1491
  function stringifyDetail(detail) {
@@ -1570,8 +1556,7 @@ function createConnectionJournal(options = {}) {
1570
1556
  exportText
1571
1557
  };
1572
1558
  }
1573
- //#endregion
1574
- //#region src/signal.ts
1559
+ // src/signal.ts
1575
1560
  var DEFAULT_DEBOUNCE_MS = 1500;
1576
1561
  var DEFAULT_FIRST_CONNECT_TIMEOUT_MS = 15e3;
1577
1562
  function signalEquals(a, b) {
@@ -1580,6 +1565,9 @@ function signalEquals(a, b) {
1580
1565
  if (a.kind === "offline" && b.kind === "offline") return a.retryAt === b.retryAt;
1581
1566
  return true;
1582
1567
  }
1568
+ function isDegraded(status) {
1569
+ return !status.up && !status.refused;
1570
+ }
1583
1571
  function createConnectionSignal(options) {
1584
1572
  const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
1585
1573
  const firstConnectTimeoutMs = options.firstConnectTimeoutMs ?? DEFAULT_FIRST_CONNECT_TIMEOUT_MS;
@@ -1603,7 +1591,7 @@ function createConnectionSignal(options) {
1603
1591
  };
1604
1592
  case "discovering": return hasBeenOnline ? { kind: "offline" } : { kind: "connecting" };
1605
1593
  case "online": {
1606
- const channels = options.transports.filter((t) => t.spec.phaseGating && !t.health().up).map((t) => t.spec.id);
1594
+ const channels = options.transports.filter((t) => t.spec.phaseGating && isDegraded(t.health())).map((t) => t.spec.id);
1607
1595
  if (channels.length === 0) return { kind: "online" };
1608
1596
  if (anyChannelEverUp) return {
1609
1597
  kind: "degraded",
@@ -1712,5 +1700,4 @@ function createConnectionSignal(options) {
1712
1700
  }
1713
1701
  };
1714
1702
  }
1715
- //#endregion
1716
- export { TransportEmitter, attachBackoff, attachCrossTab, attachDegradedRecovery, attachNetworkChange, attachPersistence, attachPresence, attachProbeLoop, attachTokenLifecycle, attachTransportSync, attachWorkerBridge, classifyClose, createBackgroundProbe, createConnectionJournal, createConnectionSignal, createKernel, isEndpointChange, isProbeFailure, isSameTarget, localAccessExpiry, localStorageAdapter, makeProbeFailure, memoryStorageAdapter, raceFirst, reducer };
1703
+ export { TransportEmitter, attachBackoff, attachCrossTab, attachDegradedRecovery, attachNetworkChange, attachPersistence, attachPresence, attachProbeLoop, attachTokenLifecycle, attachTransportSync, attachWorkerBridge, classifyClose, createBackgroundProbe, createConnectionJournal, createConnectionSignal, createKernel, isEndpointChange, isProbeFailure, isSameTarget, localAccessExpiry, localStorageAdapter, makeProbeFailure, memoryStorageAdapter, raceFirst, reducer, refusedByServer };
@@ -22,6 +22,7 @@ export declare class FakeTransport implements Transport {
22
22
  on<E extends TransportEvent>(event: E, handler: TransportEventHandler<E>): Unsubscribe;
23
23
  dispose(): Promise<void>;
24
24
  emitDown(reason: string): void;
25
+ emitRefused(reason: string): void;
25
26
  emitUp(): void;
26
27
  emitAuthError(status?: number, access?: string): void;
27
28
  get target(): ConnectionTarget | null;
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
- import { t as TransportEmitter } from "./contract-dt1m8U-o.js";
2
- //#region src/testing/fakeTransport.ts
1
+ import { t as TransportEmitter } from "./contract-CWxqxCKG.js";
2
+ // src/testing/fakeTransport.ts
3
3
  var FakeTransport = class {
4
4
  spec;
5
5
  applyCalls = [];
@@ -53,6 +53,14 @@ var FakeTransport = class {
53
53
  };
54
54
  this.emitter.emit("down", { reason });
55
55
  }
56
+ emitRefused(reason) {
57
+ this.currentStatus = {
58
+ up: false,
59
+ lastError: reason,
60
+ refused: true
61
+ };
62
+ this.emitter.emit("down", { reason });
63
+ }
56
64
  emitUp() {
57
65
  this.currentStatus = { up: true };
58
66
  this.emitter.emit("up", void 0);
@@ -67,5 +75,4 @@ var FakeTransport = class {
67
75
  return this.currentTarget;
68
76
  }
69
77
  };
70
- //#endregion
71
78
  export { FakeTransport };
@@ -1,6 +1,6 @@
1
- import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-dt1m8U-o.js";
1
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-CWxqxCKG.js";
2
2
  import axios from "axios";
3
- //#region src/transports/http.ts
3
+ // src/transports/http.ts
4
4
  var HTTP_SPEC = {
5
5
  id: "http",
6
6
  kind: "request",
@@ -201,5 +201,4 @@ function extractMessage(error) {
201
201
  if (data && typeof data === "object" && "message" in data && typeof data.message === "string") return data.message;
202
202
  return error.message;
203
203
  }
204
- //#endregion
205
204
  export { createHttpTransport };
@@ -1,5 +1,5 @@
1
1
  import axios, { AxiosError, AxiosHeaders, CanceledError } from "axios";
2
- //#region src/transports/nativeHttp.ts
2
+ // src/transports/nativeHttp.ts
3
3
  var BASE64_CHUNK = 24576;
4
4
  function isAbsoluteURL(url) {
5
5
  return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
@@ -220,5 +220,4 @@ function mapResponseType(type) {
220
220
  default: return "text";
221
221
  }
222
222
  }
223
- //#endregion
224
223
  export { applyNativeHttp, buildFullUrl, createNativeHttpAdapter, isAbsoluteURL, isPublicFqdnUrl, mapResponseType, normalizeBody, shouldUseNativeHttp };
@@ -1,7 +1,7 @@
1
- import { n as refusedByServer, t as classifyClose } from "../closeCodes-CltSRjdJ.js";
2
- import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-dt1m8U-o.js";
1
+ import { n as refusedByServer, t as classifyClose } from "../closeCodes-C0yINgIE.js";
2
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-CWxqxCKG.js";
3
3
  import { createRPCClient } from "@camera.ui/rpc";
4
- //#region src/transports/nats.ts
4
+ // src/transports/nats.ts
5
5
  var NATS_SPEC = {
6
6
  id: "nats",
7
7
  kind: "persistent",
@@ -132,9 +132,13 @@ function createNatsTransport(options = {}) {
132
132
  logger?.debug("markUp");
133
133
  emitter.emit("up", void 0);
134
134
  }
135
- function markDown(reason) {
135
+ function markDown(reason, refused = false) {
136
136
  if (!status.up && status.lastError === reason) return;
137
- status = {
137
+ status = refused ? {
138
+ up: false,
139
+ lastError: reason,
140
+ refused
141
+ } : {
138
142
  up: false,
139
143
  lastError: reason
140
144
  };
@@ -222,7 +226,7 @@ function createNatsTransport(options = {}) {
222
226
  } catch {}
223
227
  }
224
228
  logger?.warn(`forbidden by server: ${message}`);
225
- markDown(forbiddenError(message));
229
+ markDown(forbiddenError(message), true);
226
230
  if (dropped) notifyClient();
227
231
  }
228
232
  async function rebuildClient(target, epoch) {
@@ -508,5 +512,4 @@ function stringifyError(value) {
508
512
  return String(value);
509
513
  }
510
514
  }
511
- //#endregion
512
515
  export { createNatsTransport };
@@ -1,7 +1,7 @@
1
- import { t as classifyClose } from "../closeCodes-CltSRjdJ.js";
2
- import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-dt1m8U-o.js";
1
+ import { t as classifyClose } from "../closeCodes-C0yINgIE.js";
2
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-CWxqxCKG.js";
3
3
  import { Manager } from "socket.io-client";
4
- //#region src/transports/socketio.ts
4
+ // src/transports/socketio.ts
5
5
  var RESOLVE_RETRY_MIN_MS = 3e3;
6
6
  var PROBE_TIMEOUT_MS = 3e3;
7
7
  var RELEASE_GRACE_MS = 1e4;
@@ -394,5 +394,4 @@ function createSocketioTransport(options = {}) {
394
394
  ensureAlive
395
395
  };
396
396
  }
397
- //#endregion
398
397
  export { createSocketioTransport };
@@ -1,6 +1,6 @@
1
- import { t as classifyClose } from "../closeCodes-CltSRjdJ.js";
2
- import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-dt1m8U-o.js";
3
- //#region src/transports/ws.ts
1
+ import { t as classifyClose } from "../closeCodes-C0yINgIE.js";
2
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-CWxqxCKG.js";
3
+ // src/transports/ws.ts
4
4
  var WS_SPEC = {
5
5
  id: "ws",
6
6
  kind: "per-resource",
@@ -293,5 +293,4 @@ function createWsTransport(options = {}) {
293
293
  open
294
294
  };
295
295
  }
296
- //#endregion
297
296
  export { createWsTransport };
package/dist/worker.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/worker/mirror.ts
1
+ // src/worker/mirror.ts
2
2
  function createWorkerKernelMirror(options) {
3
3
  let current = options.initial ?? { kind: "idle" };
4
4
  let lastGeneration = -1;
@@ -107,5 +107,4 @@ function createWorkerKernelMirror(options) {
107
107
  }
108
108
  };
109
109
  }
110
- //#endregion
111
110
  export { createWorkerKernelMirror };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camera.ui/transport",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
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",
@@ -56,26 +56,26 @@
56
56
  },
57
57
  "dependencies": {
58
58
  "@camera.ui/logger": ">=0.0.3",
59
- "@camera.ui/rpc": ">=1.1.2",
60
- "axios": ">=1.21.0",
59
+ "@camera.ui/rpc": ">=1.1.3",
60
+ "axios": ">=1.21.1",
61
61
  "socket.io-client": ">=4.8.4"
62
62
  },
63
63
  "devDependencies": {
64
64
  "@eslint/js": "9.39.4",
65
- "@stylistic/eslint-plugin": "^5.10.0",
66
- "@typescript-eslint/parser": "^8.72.1",
65
+ "@stylistic/eslint-plugin": "^6.0.0",
66
+ "@typescript-eslint/parser": "^8.72.2",
67
67
  "@vue/language-core": "^3.3.14",
68
68
  "eslint": "9.39.2",
69
69
  "globals": "^17.14.0",
70
70
  "jiti": "^2.7.0",
71
- "prettier": "^3.9.10",
72
- "rimraf": "^6.1.3",
71
+ "prettier": "^3.10.1",
72
+ "rimraf": "^6.1.4",
73
73
  "socket.io": "^4.8.4",
74
74
  "typescript": "5.9.3",
75
- "typescript-eslint": "^8.72.1",
75
+ "typescript-eslint": "^8.72.2",
76
76
  "unplugin-dts": "^1.1.2",
77
- "updates": "^20.0.0",
78
- "vite": "^8.3.5",
77
+ "updates": "^20.0.1",
78
+ "vite": "^8.3.8",
79
79
  "vitest": "^5.1.0"
80
80
  },
81
81
  "overrides": {