@camera.ui/transport 0.0.1

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.
Files changed (39) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +10 -0
  3. package/dist/contract-d-0gfY8v.js +43 -0
  4. package/dist/core/kernel.d.ts +14 -0
  5. package/dist/core/reducer.d.ts +2 -0
  6. package/dist/core/resolver.d.ts +5 -0
  7. package/dist/core/types.d.ts +109 -0
  8. package/dist/effects/backoff.d.ts +14 -0
  9. package/dist/effects/crossTab.d.ts +14 -0
  10. package/dist/effects/networkChange.d.ts +10 -0
  11. package/dist/effects/persistence.d.ts +31 -0
  12. package/dist/effects/presence.d.ts +17 -0
  13. package/dist/effects/probeLoop.d.ts +30 -0
  14. package/dist/effects/tokenLifecycle.d.ts +39 -0
  15. package/dist/effects/transportSync.d.ts +11 -0
  16. package/dist/effects/transportWatchdog.d.ts +16 -0
  17. package/dist/effects/workerBridge.d.ts +17 -0
  18. package/dist/index.d.ts +30 -0
  19. package/dist/index.js +1101 -0
  20. package/dist/race.d.ts +23 -0
  21. package/dist/testing/fakeTransport.d.ts +24 -0
  22. package/dist/testing/index.d.ts +2 -0
  23. package/dist/testing.js +53 -0
  24. package/dist/transports/contract.d.ts +29 -0
  25. package/dist/transports/http.d.ts +14 -0
  26. package/dist/transports/http.js +131 -0
  27. package/dist/transports/nativeHttp.d.ts +33 -0
  28. package/dist/transports/nativeHttp.js +119 -0
  29. package/dist/transports/nats.d.ts +25 -0
  30. package/dist/transports/nats.js +225 -0
  31. package/dist/transports/socketio.d.ts +19 -0
  32. package/dist/transports/socketio.js +160 -0
  33. package/dist/transports/ws.d.ts +34 -0
  34. package/dist/transports/ws.js +228 -0
  35. package/dist/worker/index.d.ts +3 -0
  36. package/dist/worker/mirror.d.ts +17 -0
  37. package/dist/worker/protocol.d.ts +23 -0
  38. package/dist/worker.js +66 -0
  39. package/package.json +95 -0
@@ -0,0 +1,19 @@
1
+ import { Manager, Socket } from 'socket.io-client';
2
+ import { TransportSpec } from '../core/types.js';
3
+ import { Transport } from './contract.js';
4
+ export type { Socket };
5
+ export interface SocketioTransportOptions {
6
+ readonly spec?: Partial<TransportSpec>;
7
+ readonly path?: string;
8
+ readonly mainNamespace?: string;
9
+ readonly reconnection?: boolean;
10
+ readonly reconnectionDelay?: number;
11
+ readonly reconnectionDelayMax?: number;
12
+ readonly timeout?: number;
13
+ }
14
+ export interface SocketioTransport extends Transport {
15
+ readonly manager: Manager | null;
16
+ socket(namespace?: string): Socket | null;
17
+ ensureSocket(namespace: string): Socket | null;
18
+ }
19
+ export declare function createSocketioTransport(options?: SocketioTransportOptions): SocketioTransport;
@@ -0,0 +1,160 @@
1
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-d-0gfY8v.js";
2
+ import { Manager, io } from "socket.io-client";
3
+ //#region src/transports/socketio.ts
4
+ var SOCKETIO_SPEC = {
5
+ id: "socketio",
6
+ kind: "persistent",
7
+ phaseGating: true,
8
+ graceMs: 4e3
9
+ };
10
+ function createSocketioTransport(options = {}) {
11
+ const spec = {
12
+ ...SOCKETIO_SPEC,
13
+ ...options.spec
14
+ };
15
+ const path = options.path ?? "/api/socket.io";
16
+ const mainNs = options.mainNamespace ?? "/camera.ui";
17
+ const reconnection = options.reconnection ?? true;
18
+ const reconnectionDelay = options.reconnectionDelay ?? 1e3;
19
+ const reconnectionDelayMax = options.reconnectionDelayMax ?? 5e3;
20
+ const timeout = options.timeout ?? 2e4;
21
+ const emitter = new TransportEmitter();
22
+ const sockets = /* @__PURE__ */ new Map();
23
+ let manager = null;
24
+ let currentTarget = null;
25
+ let status = { up: false };
26
+ let disposed = false;
27
+ function buildAuth(target) {
28
+ const auth = { token: `Bearer ${target.tokens.access}` };
29
+ if (target.tokens.proxySession) auth.session = target.tokens.proxySession;
30
+ return auth;
31
+ }
32
+ function buildQuery(target) {
33
+ const q = {};
34
+ if (target.tokens.proxySession) q.session = target.tokens.proxySession;
35
+ return q;
36
+ }
37
+ function markUp() {
38
+ if (status.up) return;
39
+ status = { up: true };
40
+ emitter.emit("up", void 0);
41
+ }
42
+ function markDown(reason) {
43
+ if (!status.up && status.lastError === reason) return;
44
+ status = {
45
+ up: false,
46
+ lastError: reason
47
+ };
48
+ emitter.emit("down", { reason });
49
+ }
50
+ function bindMainSocketEvents(socket) {
51
+ socket.on("connect", () => markUp());
52
+ socket.on("disconnect", (reason) => markDown(reason));
53
+ socket.on("connect_error", (err) => {
54
+ const msg = err?.message ?? "connect_error";
55
+ if (msg.toLowerCase().includes("auth") || msg.toLowerCase().includes("unauthorized")) {
56
+ emitter.emit("auth-error", { message: msg });
57
+ return;
58
+ }
59
+ markDown(msg);
60
+ });
61
+ }
62
+ function openSocket(namespace, target) {
63
+ const sock = io(`${target.endpoint.url}${namespace}`, {
64
+ path,
65
+ auth: buildAuth(target),
66
+ query: buildQuery(target),
67
+ reconnection,
68
+ reconnectionDelay,
69
+ reconnectionDelayMax,
70
+ timeout,
71
+ rejectUnauthorized: false,
72
+ transports: ["websocket"]
73
+ });
74
+ sockets.set(namespace, sock);
75
+ return sock;
76
+ }
77
+ function rebuildManager(target) {
78
+ closeAllSockets();
79
+ manager = new Manager(target.endpoint.url, {
80
+ path,
81
+ autoConnect: false,
82
+ reconnection,
83
+ reconnectionDelay,
84
+ reconnectionDelayMax,
85
+ timeout,
86
+ rejectUnauthorized: false,
87
+ transports: ["websocket"]
88
+ });
89
+ bindMainSocketEvents(openSocket(mainNs, target));
90
+ }
91
+ function closeAllSockets() {
92
+ for (const sock of sockets.values()) {
93
+ sock.removeAllListeners();
94
+ sock.disconnect();
95
+ }
96
+ sockets.clear();
97
+ if (manager) {
98
+ manager._close();
99
+ manager = null;
100
+ }
101
+ }
102
+ function rebindAuth(target) {
103
+ const auth = buildAuth(target);
104
+ for (const sock of sockets.values()) sock.auth = auth;
105
+ }
106
+ async function apply(target) {
107
+ if (disposed) throw new Error("socketio-transport disposed");
108
+ if (isSameTarget(currentTarget, target)) return;
109
+ const endpointChanged = isEndpointChange(currentTarget, target);
110
+ currentTarget = target;
111
+ if (!target) {
112
+ closeAllSockets();
113
+ markDown("detached");
114
+ return;
115
+ }
116
+ if (endpointChanged || !manager) {
117
+ rebuildManager(target);
118
+ return;
119
+ }
120
+ rebindAuth(target);
121
+ }
122
+ function health() {
123
+ return status;
124
+ }
125
+ function on(event, handler) {
126
+ return emitter.on(event, handler);
127
+ }
128
+ async function dispose() {
129
+ disposed = true;
130
+ closeAllSockets();
131
+ currentTarget = null;
132
+ status = { up: false };
133
+ emitter.clear();
134
+ }
135
+ function socket(namespace = mainNs) {
136
+ return sockets.get(namespace) ?? null;
137
+ }
138
+ function ensureSocket(namespace) {
139
+ if (!currentTarget) return null;
140
+ let sock = sockets.get(namespace);
141
+ if (!sock) sock = openSocket(namespace, currentTarget);
142
+ return sock;
143
+ }
144
+ return {
145
+ get spec() {
146
+ return spec;
147
+ },
148
+ get manager() {
149
+ return manager;
150
+ },
151
+ apply,
152
+ health,
153
+ on,
154
+ dispose,
155
+ socket,
156
+ ensureSocket
157
+ };
158
+ }
159
+ //#endregion
160
+ export { createSocketioTransport };
@@ -0,0 +1,34 @@
1
+ import { TransportSpec } from '../core/types.js';
2
+ import { PerResourceTransport, Unsubscribe } from './contract.js';
3
+ export interface WsHandleSpec {
4
+ readonly path: string;
5
+ readonly query?: Record<string, string>;
6
+ readonly protocols?: string | readonly string[];
7
+ readonly binaryType?: 'arraybuffer' | 'blob';
8
+ }
9
+ export type WsEvent = 'open' | 'close' | 'message' | 'error';
10
+ export interface WsCloseInfo {
11
+ readonly code: number;
12
+ readonly reason: string;
13
+ readonly wasClean: boolean;
14
+ }
15
+ export type WsEventPayload<E extends WsEvent> = E extends 'open' ? void : E extends 'close' ? WsCloseInfo : E extends 'message' ? MessageEvent : E extends 'error' ? Event : never;
16
+ export type WsEventHandler<E extends WsEvent> = (payload: WsEventPayload<E>) => void;
17
+ export interface WsHandle {
18
+ readonly readyState: number;
19
+ readonly url: string | null;
20
+ send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
21
+ close(code?: number, reason?: string): void;
22
+ on<E extends WsEvent>(event: E, handler: WsEventHandler<E>): Unsubscribe;
23
+ dispose(): void;
24
+ }
25
+ export interface WsTransportOptions {
26
+ readonly spec?: Partial<TransportSpec>;
27
+ readonly webSocketCtor?: typeof WebSocket;
28
+ readonly tokenParam?: string;
29
+ readonly sessionParam?: string;
30
+ }
31
+ export interface WsTransport extends PerResourceTransport<WsHandle, WsHandleSpec> {
32
+ readonly handleCount: number;
33
+ }
34
+ export declare function createWsTransport(options?: WsTransportOptions): WsTransport;
@@ -0,0 +1,228 @@
1
+ import { n as isEndpointChange, r as isSameTarget, t as TransportEmitter } from "../contract-d-0gfY8v.js";
2
+ //#region src/transports/ws.ts
3
+ var WS_SPEC = {
4
+ id: "ws",
5
+ kind: "per-resource",
6
+ phaseGating: false
7
+ };
8
+ var WS_CLOSE_TARGET_CHANGED = 4e3;
9
+ var WS_CLOSE_DETACHED = 4001;
10
+ var WS_CLOSE_DISPOSED = 4002;
11
+ function createWsTransport(options = {}) {
12
+ const spec = {
13
+ ...WS_SPEC,
14
+ ...options.spec
15
+ };
16
+ const tokenParam = options.tokenParam ?? "token";
17
+ const sessionParam = options.sessionParam ?? "session";
18
+ const WsCtor = options.webSocketCtor ?? (typeof WebSocket !== "undefined" ? WebSocket : void 0);
19
+ const emitter = new TransportEmitter();
20
+ const handles = /* @__PURE__ */ new Set();
21
+ let currentTarget = null;
22
+ let status = { up: false };
23
+ let disposed = false;
24
+ function ensureCtor() {
25
+ if (!WsCtor) throw new Error("ws-transport: no WebSocket constructor available; pass webSocketCtor in non-browser environments");
26
+ return WsCtor;
27
+ }
28
+ function buildUrl(target, handleSpec) {
29
+ const base = new URL(target.endpoint.url);
30
+ const wsProtocol = base.protocol === "https:" ? "wss:" : "ws:";
31
+ const port = base.port || (base.protocol === "https:" ? "443" : "80");
32
+ const params = new URLSearchParams();
33
+ for (const [k, v] of Object.entries(handleSpec.query ?? {})) if (v !== void 0 && v !== null && v !== "") params.set(k, v);
34
+ params.set(tokenParam, target.tokens.access);
35
+ if (target.tokens.proxySession) params.set(sessionParam, target.tokens.proxySession);
36
+ return `${wsProtocol}//${base.hostname}:${port}${handleSpec.path}?${params.toString()}`;
37
+ }
38
+ function isAuthCloseEvent(event) {
39
+ if (event.code === 1008 || event.code === 4401) return true;
40
+ if (!event.reason) return false;
41
+ const lower = event.reason.toLowerCase();
42
+ return lower.includes("unauthorized") || lower.includes("forbidden") || lower.includes("401") || lower.includes("403");
43
+ }
44
+ function bindWs(handle, ws) {
45
+ ws.onopen = () => {
46
+ if (handle.disposed || handle.ws !== ws) return;
47
+ if (!status.up) {
48
+ status = { up: true };
49
+ emitter.emit("up", void 0);
50
+ }
51
+ for (const fn of [...handle.listeners.open]) fn();
52
+ };
53
+ ws.onclose = (event) => {
54
+ if (handle.ws === ws) {
55
+ handle.ws = null;
56
+ handle.url = null;
57
+ }
58
+ if (isAuthCloseEvent(event)) emitter.emit("auth-error", { message: event.reason || `ws close code ${event.code}` });
59
+ const info = {
60
+ code: event.code,
61
+ reason: event.reason,
62
+ wasClean: event.wasClean
63
+ };
64
+ for (const fn of [...handle.listeners.close]) fn(info);
65
+ };
66
+ ws.onmessage = (event) => {
67
+ if (handle.disposed || handle.ws !== ws) return;
68
+ for (const fn of [...handle.listeners.message]) fn(event);
69
+ };
70
+ ws.onerror = (event) => {
71
+ if (handle.disposed || handle.ws !== ws) return;
72
+ for (const fn of [...handle.listeners.error]) fn(event);
73
+ };
74
+ }
75
+ function closeWs(handle, code, reason) {
76
+ const ws = handle.ws;
77
+ if (!ws) return;
78
+ const Ctor = ensureCtor();
79
+ if (ws.readyState === Ctor.OPEN || ws.readyState === Ctor.CONNECTING) {
80
+ try {
81
+ ws.close(code, reason);
82
+ } catch {}
83
+ return;
84
+ }
85
+ if (handle.ws === ws) {
86
+ handle.ws = null;
87
+ handle.url = null;
88
+ }
89
+ const info = {
90
+ code,
91
+ reason,
92
+ wasClean: false
93
+ };
94
+ for (const fn of [...handle.listeners.close]) fn(info);
95
+ }
96
+ function openWs(handle) {
97
+ if (handle.disposed) return;
98
+ if (!currentTarget) return;
99
+ const url = buildUrl(currentTarget, handle.spec);
100
+ const ws = new (ensureCtor())(url, handle.spec.protocols);
101
+ if (handle.spec.binaryType) ws.binaryType = handle.spec.binaryType;
102
+ handle.ws = ws;
103
+ handle.url = url;
104
+ bindWs(handle, ws);
105
+ }
106
+ function recycleAll(code, reason) {
107
+ const snapshot = [...handles];
108
+ for (const handle of snapshot) closeWs(handle, code, reason);
109
+ if (status.up) {
110
+ status = {
111
+ up: false,
112
+ lastError: reason
113
+ };
114
+ emitter.emit("down", { reason });
115
+ }
116
+ if (!currentTarget) return;
117
+ for (const handle of handles) if (!handle.disposed) openWs(handle);
118
+ }
119
+ async function apply(target) {
120
+ if (disposed) throw new Error("ws-transport disposed");
121
+ if (isSameTarget(currentTarget, target)) return;
122
+ const endpointChanged = isEndpointChange(currentTarget, target);
123
+ currentTarget = target;
124
+ if (!target) {
125
+ const snapshot = [...handles];
126
+ for (const handle of snapshot) closeWs(handle, WS_CLOSE_DETACHED, "detached");
127
+ status = { up: false };
128
+ emitter.emit("down", { reason: "detached" });
129
+ return;
130
+ }
131
+ if (endpointChanged) recycleAll(WS_CLOSE_TARGET_CHANGED, "endpoint-changed");
132
+ }
133
+ function health() {
134
+ return status;
135
+ }
136
+ function on(event, handler) {
137
+ return emitter.on(event, handler);
138
+ }
139
+ async function dispose() {
140
+ disposed = true;
141
+ const snapshot = [...handles];
142
+ for (const handle of snapshot) {
143
+ handle.disposed = true;
144
+ handle.listeners.open.clear();
145
+ handle.listeners.close.clear();
146
+ handle.listeners.message.clear();
147
+ handle.listeners.error.clear();
148
+ closeWs(handle, WS_CLOSE_DISPOSED, "disposed");
149
+ }
150
+ handles.clear();
151
+ currentTarget = null;
152
+ status = { up: false };
153
+ emitter.clear();
154
+ }
155
+ function open(handleSpec) {
156
+ if (disposed) throw new Error("ws-transport disposed");
157
+ const handle = {
158
+ api: void 0,
159
+ spec: handleSpec,
160
+ listeners: {
161
+ open: /* @__PURE__ */ new Set(),
162
+ close: /* @__PURE__ */ new Set(),
163
+ message: /* @__PURE__ */ new Set(),
164
+ error: /* @__PURE__ */ new Set()
165
+ },
166
+ ws: null,
167
+ url: null,
168
+ disposed: false
169
+ };
170
+ function send(data) {
171
+ if (handle.disposed) throw new Error("ws-handle disposed");
172
+ const ws = handle.ws;
173
+ if (!ws) throw new Error("ws-handle: no active socket");
174
+ if (ws.readyState !== WsCtor.OPEN) throw new Error("ws-handle: socket not open");
175
+ ws.send(data);
176
+ }
177
+ function close(code, reason) {
178
+ closeWs(handle, code ?? 1e3, reason ?? "");
179
+ }
180
+ function onHandle(event, handler) {
181
+ const set = handle.listeners[event];
182
+ set.add(handler);
183
+ return () => {
184
+ set.delete(handler);
185
+ };
186
+ }
187
+ function disposeHandle() {
188
+ if (handle.disposed) return;
189
+ handle.disposed = true;
190
+ handle.listeners.open.clear();
191
+ handle.listeners.close.clear();
192
+ handle.listeners.message.clear();
193
+ handle.listeners.error.clear();
194
+ closeWs(handle, WS_CLOSE_DISPOSED, "disposed");
195
+ handles.delete(handle);
196
+ }
197
+ handle.api = {
198
+ get readyState() {
199
+ return handle.ws?.readyState ?? WsCtor?.CLOSED ?? 3;
200
+ },
201
+ get url() {
202
+ return handle.url;
203
+ },
204
+ send,
205
+ close,
206
+ on: onHandle,
207
+ dispose: disposeHandle
208
+ };
209
+ handles.add(handle);
210
+ if (currentTarget) openWs(handle);
211
+ return handle.api;
212
+ }
213
+ return {
214
+ get spec() {
215
+ return spec;
216
+ },
217
+ get handleCount() {
218
+ return handles.size;
219
+ },
220
+ apply,
221
+ health,
222
+ on,
223
+ dispose,
224
+ open
225
+ };
226
+ }
227
+ //#endregion
228
+ export { createWsTransport };
@@ -0,0 +1,3 @@
1
+ export { createWorkerKernelMirror } from './mirror.js';
2
+ export type { MirrorListener, Unsubscribe, WorkerKernelMirror, WorkerKernelMirrorOptions } from './mirror.js';
3
+ export type { KernelSyncMessage, KernelSyncRequestMessage, MessageSource, WorkerHost, WorkerMessage } from './protocol.js';
@@ -0,0 +1,17 @@
1
+ import { ConnectionPhase, ConnectionTarget } from '../core/types.js';
2
+ import { MessageSource } from './protocol.js';
3
+ export type Unsubscribe = () => void;
4
+ export type MirrorListener = (next: ConnectionPhase, prev: ConnectionPhase) => void;
5
+ export interface WorkerKernelMirror {
6
+ readonly phase: ConnectionPhase;
7
+ readonly target: ConnectionTarget | null;
8
+ subscribe(listener: MirrorListener): Unsubscribe;
9
+ onRevalidate(listener: () => void): Unsubscribe;
10
+ requestSync(): void;
11
+ dispose(): void;
12
+ }
13
+ export interface WorkerKernelMirrorOptions {
14
+ readonly source: MessageSource;
15
+ readonly initial?: ConnectionPhase;
16
+ }
17
+ export declare function createWorkerKernelMirror(options: WorkerKernelMirrorOptions): WorkerKernelMirror;
@@ -0,0 +1,23 @@
1
+ import { ConnectionPhase } from '../core/types.js';
2
+ export interface KernelSyncMessage {
3
+ readonly type: 'kernel-sync';
4
+ readonly generation: number;
5
+ readonly phase: ConnectionPhase;
6
+ }
7
+ export interface KernelSyncRequestMessage {
8
+ readonly type: 'kernel-sync-request';
9
+ }
10
+ export interface KernelRevalidateMessage {
11
+ readonly type: 'kernel-revalidate';
12
+ }
13
+ export type WorkerMessage = KernelSyncMessage | KernelSyncRequestMessage | KernelRevalidateMessage;
14
+ export interface MessageSource {
15
+ postMessage(message: WorkerMessage): void;
16
+ addEventListener(type: 'message', listener: (event: MessageEvent<WorkerMessage>) => void): void;
17
+ removeEventListener(type: 'message', listener: (event: MessageEvent<WorkerMessage>) => void): void;
18
+ }
19
+ export interface WorkerHost {
20
+ postMessage(message: WorkerMessage): void;
21
+ addEventListener?(type: 'message', listener: (event: MessageEvent<WorkerMessage>) => void): void;
22
+ removeEventListener?(type: 'message', listener: (event: MessageEvent<WorkerMessage>) => void): void;
23
+ }
package/dist/worker.js ADDED
@@ -0,0 +1,66 @@
1
+ //#region src/worker/mirror.ts
2
+ function createWorkerKernelMirror(options) {
3
+ let current = options.initial ?? { kind: "idle" };
4
+ let lastGeneration = -1;
5
+ const listeners = /* @__PURE__ */ new Set();
6
+ const revalidateListeners = /* @__PURE__ */ new Set();
7
+ let disposed = false;
8
+ function handler(event) {
9
+ if (disposed) return;
10
+ const msg = event.data;
11
+ if (!msg) return;
12
+ if (msg.type === "kernel-revalidate") {
13
+ for (const l of [...revalidateListeners]) try {
14
+ l();
15
+ } catch {}
16
+ return;
17
+ }
18
+ if (msg.type !== "kernel-sync") return;
19
+ if (msg.generation <= lastGeneration) return;
20
+ lastGeneration = msg.generation;
21
+ const prev = current;
22
+ current = msg.phase;
23
+ if (prev === current) return;
24
+ for (const l of [...listeners]) try {
25
+ l(current, prev);
26
+ } catch {}
27
+ }
28
+ options.source.addEventListener("message", handler);
29
+ function targetOf(p) {
30
+ if (p.kind === "online") return p.target;
31
+ if (p.kind === "reconnecting") return p.lastTarget;
32
+ return null;
33
+ }
34
+ return {
35
+ get phase() {
36
+ return current;
37
+ },
38
+ get target() {
39
+ return targetOf(current);
40
+ },
41
+ subscribe(listener) {
42
+ listeners.add(listener);
43
+ return () => {
44
+ listeners.delete(listener);
45
+ };
46
+ },
47
+ onRevalidate(listener) {
48
+ revalidateListeners.add(listener);
49
+ return () => {
50
+ revalidateListeners.delete(listener);
51
+ };
52
+ },
53
+ requestSync() {
54
+ if (disposed) return;
55
+ options.source.postMessage({ type: "kernel-sync-request" });
56
+ },
57
+ dispose() {
58
+ disposed = true;
59
+ options.source.removeEventListener("message", handler);
60
+ listeners.clear();
61
+ revalidateListeners.clear();
62
+ }
63
+ };
64
+ }
65
+ //#endregion
66
+ export { createWorkerKernelMirror };
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@camera.ui/transport",
3
+ "version": "0.0.1",
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
+ "author": "seydx (https://github.com/cameraui/clients)",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./transports/http": {
18
+ "types": "./dist/transports/http.d.ts",
19
+ "import": "./dist/transports/http.js"
20
+ },
21
+ "./transports/socketio": {
22
+ "types": "./dist/transports/socketio.d.ts",
23
+ "import": "./dist/transports/socketio.js"
24
+ },
25
+ "./transports/nats": {
26
+ "types": "./dist/transports/nats.d.ts",
27
+ "import": "./dist/transports/nats.js"
28
+ },
29
+ "./transports/ws": {
30
+ "types": "./dist/transports/ws.d.ts",
31
+ "import": "./dist/transports/ws.js"
32
+ },
33
+ "./transports/nativeHttp": {
34
+ "types": "./dist/transports/nativeHttp.d.ts",
35
+ "import": "./dist/transports/nativeHttp.js"
36
+ },
37
+ "./worker": {
38
+ "types": "./dist/worker/index.d.ts",
39
+ "import": "./dist/worker.js"
40
+ },
41
+ "./testing": {
42
+ "types": "./dist/testing.d.ts",
43
+ "import": "./dist/testing.js"
44
+ }
45
+ },
46
+ "scripts": {
47
+ "build": "rimraf dist && vite build",
48
+ "format": "prettier --write 'src/' --ignore-unknown --no-error-on-unmatched-pattern",
49
+ "lint": "eslint .",
50
+ "lint:fix": "eslint --fix .",
51
+ "install-updates": "npm i --save",
52
+ "prepublishOnly": "npm i --package-lock-only && npm run lint:fix && npm run format && npm run build",
53
+ "test": "vitest run",
54
+ "test:watch": "vitest",
55
+ "type-check": "tsc --noEmit",
56
+ "update": "updates --update ./"
57
+ },
58
+ "dependencies": {
59
+ "@camera.ui/rpc": "file:../../externals/rpc/node",
60
+ "axios": "^1.18.0",
61
+ "socket.io-client": "^4.8.3"
62
+ },
63
+ "devDependencies": {
64
+ "@eslint/js": "9.39.4",
65
+ "@stylistic/eslint-plugin": "^5.10.0",
66
+ "@typescript-eslint/parser": "^8.61.1",
67
+ "@vue/language-core": "^3.1.8",
68
+ "eslint": "9.39.2",
69
+ "globals": "^17.6.0",
70
+ "jiti": "^2.7.0",
71
+ "prettier": "^3.8.4",
72
+ "rimraf": "^6.1.3",
73
+ "typescript": "5.9.3",
74
+ "typescript-eslint": "^8.61.1",
75
+ "unplugin-dts": "^1.0.2",
76
+ "updates": "^17.18.0",
77
+ "vite": "^8.0.16",
78
+ "vitest": "^4.1.9"
79
+ },
80
+ "bugs": {
81
+ "url": "https://github.com/cameraui/clients/issues"
82
+ },
83
+ "homepage": "https://github.com/cameraui/clients/tree/main/packages/transport#readme",
84
+ "keywords": [
85
+ "camera.ui",
86
+ "transport",
87
+ "connection"
88
+ ],
89
+ "license": "MIT",
90
+ "repository": {
91
+ "type": "git",
92
+ "url": "git+https://github.com/cameraui/clients.git",
93
+ "directory": "packages/transport"
94
+ }
95
+ }