@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.
- package/LICENSE.md +22 -0
- package/README.md +10 -0
- package/dist/contract-d-0gfY8v.js +43 -0
- package/dist/core/kernel.d.ts +14 -0
- package/dist/core/reducer.d.ts +2 -0
- package/dist/core/resolver.d.ts +5 -0
- package/dist/core/types.d.ts +109 -0
- package/dist/effects/backoff.d.ts +14 -0
- package/dist/effects/crossTab.d.ts +14 -0
- package/dist/effects/networkChange.d.ts +10 -0
- package/dist/effects/persistence.d.ts +31 -0
- package/dist/effects/presence.d.ts +17 -0
- package/dist/effects/probeLoop.d.ts +30 -0
- package/dist/effects/tokenLifecycle.d.ts +39 -0
- package/dist/effects/transportSync.d.ts +11 -0
- package/dist/effects/transportWatchdog.d.ts +16 -0
- package/dist/effects/workerBridge.d.ts +17 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +1101 -0
- package/dist/race.d.ts +23 -0
- package/dist/testing/fakeTransport.d.ts +24 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing.js +53 -0
- package/dist/transports/contract.d.ts +29 -0
- package/dist/transports/http.d.ts +14 -0
- package/dist/transports/http.js +131 -0
- package/dist/transports/nativeHttp.d.ts +33 -0
- package/dist/transports/nativeHttp.js +119 -0
- package/dist/transports/nats.d.ts +25 -0
- package/dist/transports/nats.js +225 -0
- package/dist/transports/socketio.d.ts +19 -0
- package/dist/transports/socketio.js +160 -0
- package/dist/transports/ws.d.ts +34 -0
- package/dist/transports/ws.js +228 -0
- package/dist/worker/index.d.ts +3 -0
- package/dist/worker/mirror.d.ts +17 -0
- package/dist/worker/protocol.d.ts +23 -0
- package/dist/worker.js +66 -0
- package/package.json +95 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020-2026 seydx <hi@seydx.dev>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# @camera.ui/transport
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@camera.ui/transport)
|
|
4
|
+
[](LICENSE.md)
|
|
5
|
+
|
|
6
|
+
The camera.ui transport layer — a framework-agnostic connection kernel with pluggable transports, reducer-based state, lifecycle effects and worker bridging.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
*Part of the camera.ui ecosystem - A comprehensive camera management solution.*
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/transports/contract.ts
|
|
2
|
+
function isSameTarget(a, b) {
|
|
3
|
+
if (a === b) return true;
|
|
4
|
+
if (!a || !b) return false;
|
|
5
|
+
if (a.endpoint.url !== b.endpoint.url || a.endpoint.mode !== b.endpoint.mode) return false;
|
|
6
|
+
if (a.tokens.access !== b.tokens.access) return false;
|
|
7
|
+
if ((a.tokens.proxySession ?? null) !== (b.tokens.proxySession ?? null)) return false;
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
function isEndpointChange(a, b) {
|
|
11
|
+
if (a === b) return false;
|
|
12
|
+
if (!a || !b) return true;
|
|
13
|
+
return a.endpoint.url !== b.endpoint.url || a.endpoint.mode !== b.endpoint.mode;
|
|
14
|
+
}
|
|
15
|
+
function isTokenOnlyChange(a, b) {
|
|
16
|
+
if (!a || !b) return false;
|
|
17
|
+
if (isEndpointChange(a, b)) return false;
|
|
18
|
+
return !isSameTarget(a, b);
|
|
19
|
+
}
|
|
20
|
+
var TransportEmitter = class {
|
|
21
|
+
listeners = /* @__PURE__ */ new Map();
|
|
22
|
+
on(event, handler) {
|
|
23
|
+
let set = this.listeners.get(event);
|
|
24
|
+
if (!set) {
|
|
25
|
+
set = /* @__PURE__ */ new Set();
|
|
26
|
+
this.listeners.set(event, set);
|
|
27
|
+
}
|
|
28
|
+
set.add(handler);
|
|
29
|
+
return () => {
|
|
30
|
+
set.delete(handler);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
emit(event, payload) {
|
|
34
|
+
const set = this.listeners.get(event);
|
|
35
|
+
if (!set) return;
|
|
36
|
+
for (const fn of [...set]) fn(payload);
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
this.listeners.clear();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
//#endregion
|
|
43
|
+
export { isTokenOnlyChange as i, isEndpointChange as n, isSameTarget as r, TransportEmitter as t };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Action, ConnectionPhase, ReducerContext } from './types.js';
|
|
2
|
+
export type Listener = (phase: ConnectionPhase, prev: ConnectionPhase, action: Action) => void;
|
|
3
|
+
export type Unsubscribe = () => void;
|
|
4
|
+
export interface KernelOptions {
|
|
5
|
+
readonly context: ReducerContext;
|
|
6
|
+
readonly initial?: ConnectionPhase;
|
|
7
|
+
}
|
|
8
|
+
export interface Kernel {
|
|
9
|
+
readonly phase: ConnectionPhase;
|
|
10
|
+
dispatch(action: Action): void;
|
|
11
|
+
subscribe(listener: Listener): Unsubscribe;
|
|
12
|
+
dispose(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare function createKernel(options: KernelOptions): Kernel;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Endpoint, EndpointMode } from './types.js';
|
|
2
|
+
export declare function sortByPriority(endpoints: readonly Endpoint[]): Endpoint[];
|
|
3
|
+
export declare function isSameEndpoint(a: Endpoint, b: Endpoint): boolean;
|
|
4
|
+
export declare function endpointKey(ep: Endpoint): string;
|
|
5
|
+
export type { EndpointMode };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export type EndpointMode = 'direct-lan' | 'direct-wan';
|
|
2
|
+
export interface Endpoint {
|
|
3
|
+
readonly url: string;
|
|
4
|
+
readonly mode: EndpointMode;
|
|
5
|
+
readonly priority?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Tokens {
|
|
8
|
+
readonly access: string;
|
|
9
|
+
readonly accessExpiresAt?: number;
|
|
10
|
+
readonly refresh?: string;
|
|
11
|
+
readonly refreshExpiresAt?: number;
|
|
12
|
+
readonly proxySession?: string;
|
|
13
|
+
readonly proxySessionExpiresAt?: number;
|
|
14
|
+
readonly proxyRefresh?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ConnectionTarget {
|
|
17
|
+
readonly endpoint: Endpoint;
|
|
18
|
+
readonly tokens: Tokens;
|
|
19
|
+
readonly meta?: Readonly<Record<string, unknown>>;
|
|
20
|
+
}
|
|
21
|
+
export type TransportId = string;
|
|
22
|
+
export type TransportKind = 'persistent' | 'request' | 'per-resource';
|
|
23
|
+
export interface TransportSpec {
|
|
24
|
+
readonly id: TransportId;
|
|
25
|
+
readonly kind: TransportKind;
|
|
26
|
+
readonly phaseGating: boolean;
|
|
27
|
+
readonly graceMs?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface TransportStatus {
|
|
30
|
+
readonly up: boolean;
|
|
31
|
+
readonly lastError?: string;
|
|
32
|
+
readonly downSince?: number;
|
|
33
|
+
}
|
|
34
|
+
export type ReconnectCause = 'transport-down' | 'auth-error' | 'network-change' | 'user-retry' | 'endpoint-swap';
|
|
35
|
+
export type ConnectionPhase = {
|
|
36
|
+
readonly kind: 'idle';
|
|
37
|
+
} | {
|
|
38
|
+
readonly kind: 'discovering';
|
|
39
|
+
readonly instanceId: string;
|
|
40
|
+
readonly attempt: number;
|
|
41
|
+
} | {
|
|
42
|
+
readonly kind: 'online';
|
|
43
|
+
readonly instanceId: string;
|
|
44
|
+
readonly target: ConnectionTarget;
|
|
45
|
+
readonly transports: ReadonlyMap<TransportId, TransportStatus>;
|
|
46
|
+
} | {
|
|
47
|
+
readonly kind: 'reconnecting';
|
|
48
|
+
readonly instanceId: string;
|
|
49
|
+
readonly lastTarget: ConnectionTarget | null;
|
|
50
|
+
readonly cause: ReconnectCause;
|
|
51
|
+
readonly since: number;
|
|
52
|
+
readonly transports: ReadonlyMap<TransportId, TransportStatus>;
|
|
53
|
+
} | {
|
|
54
|
+
readonly kind: 'needs-auth';
|
|
55
|
+
readonly instanceId: string | null;
|
|
56
|
+
readonly reason: string;
|
|
57
|
+
} | {
|
|
58
|
+
readonly kind: 'offline';
|
|
59
|
+
readonly instanceId: string | null;
|
|
60
|
+
readonly lastError: string;
|
|
61
|
+
readonly nextRetryAt: number;
|
|
62
|
+
readonly backoffHint?: BackoffHint;
|
|
63
|
+
};
|
|
64
|
+
export interface BackoffHint {
|
|
65
|
+
readonly retryAfterMs: number;
|
|
66
|
+
readonly setAt: number;
|
|
67
|
+
readonly source?: string;
|
|
68
|
+
}
|
|
69
|
+
export type Action = {
|
|
70
|
+
readonly type: 'BOOT';
|
|
71
|
+
readonly instanceId: string;
|
|
72
|
+
} | {
|
|
73
|
+
readonly type: 'PROBE_SUCCEEDED';
|
|
74
|
+
readonly endpoint: Endpoint;
|
|
75
|
+
readonly tokens: Tokens;
|
|
76
|
+
} | {
|
|
77
|
+
readonly type: 'PROBE_FAILED_ALL';
|
|
78
|
+
readonly error: string;
|
|
79
|
+
} | {
|
|
80
|
+
readonly type: 'TRANSPORT_UP';
|
|
81
|
+
readonly id: TransportId;
|
|
82
|
+
} | {
|
|
83
|
+
readonly type: 'TRANSPORT_DOWN';
|
|
84
|
+
readonly id: TransportId;
|
|
85
|
+
readonly reason: string;
|
|
86
|
+
} | {
|
|
87
|
+
readonly type: 'TRANSPORT_DOWN_CONFIRMED';
|
|
88
|
+
readonly id: TransportId;
|
|
89
|
+
} | {
|
|
90
|
+
readonly type: 'TOKENS_REFRESHED';
|
|
91
|
+
readonly tokens: Tokens;
|
|
92
|
+
} | {
|
|
93
|
+
readonly type: 'TOKENS_INVALID';
|
|
94
|
+
readonly reason: string;
|
|
95
|
+
readonly transient?: boolean;
|
|
96
|
+
} | {
|
|
97
|
+
readonly type: 'USER_RETRY';
|
|
98
|
+
} | {
|
|
99
|
+
readonly type: 'RESET';
|
|
100
|
+
} | {
|
|
101
|
+
readonly type: 'BACKOFF_HINT';
|
|
102
|
+
readonly retryAfterMs: number;
|
|
103
|
+
readonly source?: string;
|
|
104
|
+
};
|
|
105
|
+
export interface ReducerContext {
|
|
106
|
+
readonly specs: ReadonlyMap<TransportId, TransportSpec>;
|
|
107
|
+
readonly now: () => number;
|
|
108
|
+
readonly retryBackoffMs?: (attempt: number) => number;
|
|
109
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
export type Detach = () => void;
|
|
3
|
+
export interface BackoffOptions {
|
|
4
|
+
readonly kernel: Kernel;
|
|
5
|
+
readonly schedule?: readonly number[];
|
|
6
|
+
readonly now?: () => number;
|
|
7
|
+
readonly setTimer?: (cb: () => void, ms: number) => unknown;
|
|
8
|
+
readonly clearTimer?: (handle: unknown) => void;
|
|
9
|
+
readonly onScheduled?: (attempt: number, delayMs: number) => void;
|
|
10
|
+
readonly onFire?: (attempt: number) => void;
|
|
11
|
+
readonly onCancelled?: (reason: 'phase-left-offline' | 'detach' | 'rescheduled') => void;
|
|
12
|
+
readonly onHintApplied?: (delayMs: number, source?: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function attachBackoff(options: BackoffOptions): Detach;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { ConnectionTarget } from '../core/types.js';
|
|
3
|
+
export type Detach = () => void;
|
|
4
|
+
export interface CrossTabSource extends EventTarget {
|
|
5
|
+
}
|
|
6
|
+
export interface CrossTabOptions {
|
|
7
|
+
readonly kernel: Kernel;
|
|
8
|
+
readonly key?: string;
|
|
9
|
+
readonly source?: CrossTabSource;
|
|
10
|
+
readonly onTokensReceived?: (tokens: ConnectionTarget['tokens']) => void;
|
|
11
|
+
readonly onResetReceived?: () => void;
|
|
12
|
+
readonly onError?: (op: 'parse', err: unknown) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function attachCrossTab(options: CrossTabOptions): Detach;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
export type Detach = () => void;
|
|
3
|
+
export interface NetworkChangeSource extends EventTarget {
|
|
4
|
+
}
|
|
5
|
+
export interface NetworkChangeOptions {
|
|
6
|
+
readonly kernel: Kernel;
|
|
7
|
+
readonly source: NetworkChangeSource;
|
|
8
|
+
readonly onChange: (kernel: Kernel, event: Event) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function attachNetworkChange(options: NetworkChangeOptions): Detach;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { ConnectionTarget } from '../core/types.js';
|
|
3
|
+
export type Detach = () => void;
|
|
4
|
+
export interface StorageAdapter {
|
|
5
|
+
get(key: string): string | null | Promise<string | null>;
|
|
6
|
+
set(key: string, value: string): void | Promise<void>;
|
|
7
|
+
del(key: string): void | Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export interface PersistedTarget {
|
|
10
|
+
readonly endpoint: ConnectionTarget['endpoint'];
|
|
11
|
+
readonly tokens: ConnectionTarget['tokens'];
|
|
12
|
+
readonly savedAt: number;
|
|
13
|
+
readonly version: 1;
|
|
14
|
+
}
|
|
15
|
+
export interface Persistence {
|
|
16
|
+
readonly detach: Detach;
|
|
17
|
+
peek(): ConnectionTarget | null;
|
|
18
|
+
seed(target: ConnectionTarget): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export interface PersistenceOptions {
|
|
21
|
+
readonly kernel: Kernel;
|
|
22
|
+
readonly storage: StorageAdapter;
|
|
23
|
+
readonly key?: string;
|
|
24
|
+
readonly onRestore?: (restored: ConnectionTarget | null) => void;
|
|
25
|
+
readonly onPersist?: (target: ConnectionTarget) => void;
|
|
26
|
+
readonly onClear?: () => void;
|
|
27
|
+
readonly onError?: (op: 'get' | 'set' | 'del' | 'parse', err: unknown) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare function attachPersistence(options: PersistenceOptions): Persistence;
|
|
30
|
+
export declare function localStorageAdapter(scope?: Storage): StorageAdapter;
|
|
31
|
+
export declare function memoryStorageAdapter(initial?: Record<string, string>): StorageAdapter;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
export type Detach = () => void;
|
|
3
|
+
export type PresenceCallback = (kernel: Kernel) => void;
|
|
4
|
+
export interface VisibilitySource extends EventTarget {
|
|
5
|
+
visibilityState?: DocumentVisibilityState;
|
|
6
|
+
}
|
|
7
|
+
export interface PresenceOptions {
|
|
8
|
+
readonly kernel: Kernel;
|
|
9
|
+
readonly networkSource?: EventTarget | null;
|
|
10
|
+
readonly visibilitySource?: VisibilitySource | null;
|
|
11
|
+
readonly onOnline?: PresenceCallback;
|
|
12
|
+
readonly onOffline?: PresenceCallback;
|
|
13
|
+
readonly onVisibilityVisible?: PresenceCallback;
|
|
14
|
+
readonly onVisibilityHidden?: PresenceCallback;
|
|
15
|
+
}
|
|
16
|
+
export declare const defaultOnNetworkOnline: PresenceCallback;
|
|
17
|
+
export declare function attachPresence(options: PresenceOptions): Detach;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { ConnectionTarget, Endpoint, Tokens } from '../core/types.js';
|
|
3
|
+
import { TimeoutByModeFn } from '../race.js';
|
|
4
|
+
export type Detach = () => void;
|
|
5
|
+
export type ProbeFailureKind = 'transient' | 'needs-auth' | 'fatal' | 'aborted';
|
|
6
|
+
export interface ProbeFailure extends Error {
|
|
7
|
+
readonly kind: ProbeFailureKind;
|
|
8
|
+
}
|
|
9
|
+
export declare function makeProbeFailure(kind: ProbeFailureKind, message: string): ProbeFailure;
|
|
10
|
+
export declare function isProbeFailure(err: unknown): err is ProbeFailure;
|
|
11
|
+
export interface ProbeContext {
|
|
12
|
+
readonly endpoint: Endpoint;
|
|
13
|
+
readonly lastTokens?: Tokens;
|
|
14
|
+
readonly signal: AbortSignal;
|
|
15
|
+
}
|
|
16
|
+
export interface ProbeLoopOptions {
|
|
17
|
+
readonly kernel: Kernel;
|
|
18
|
+
readonly discover: (signal: AbortSignal) => Promise<readonly Endpoint[]>;
|
|
19
|
+
readonly probe: (ctx: ProbeContext) => Promise<Tokens>;
|
|
20
|
+
readonly timeoutByMode?: TimeoutByModeFn;
|
|
21
|
+
readonly onDiscoverStart?: () => void;
|
|
22
|
+
readonly onDiscoverSuccess?: (pool: readonly Endpoint[]) => void;
|
|
23
|
+
readonly onDiscoverError?: (err: unknown) => void;
|
|
24
|
+
readonly onProbeStart?: (endpoint: Endpoint) => void;
|
|
25
|
+
readonly onProbeSuccess?: (endpoint: Endpoint, tokens: Tokens) => void;
|
|
26
|
+
readonly onProbeError?: (endpoint: Endpoint, err: unknown) => void;
|
|
27
|
+
readonly onAllFailed?: (reason: string) => void;
|
|
28
|
+
readonly lastTarget?: () => ConnectionTarget | null;
|
|
29
|
+
}
|
|
30
|
+
export declare function attachProbeLoop(options: ProbeLoopOptions): Detach;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { ConnectionTarget, Tokens } from '../core/types.js';
|
|
3
|
+
import { Transport } from '../transports/contract.js';
|
|
4
|
+
export type RefreshReason = 'proactive' | 'auth-error';
|
|
5
|
+
export interface TokenLifecycleOptions {
|
|
6
|
+
readonly kernel: Kernel;
|
|
7
|
+
readonly transports: readonly Transport[];
|
|
8
|
+
readonly refresh: (target: ConnectionTarget, reason: RefreshReason) => Promise<Tokens>;
|
|
9
|
+
readonly graceMs?: number;
|
|
10
|
+
readonly isTransientError?: (err: unknown) => boolean;
|
|
11
|
+
readonly maxTransientRetries?: number;
|
|
12
|
+
readonly transientRetryDelayMs?: number;
|
|
13
|
+
readonly now?: () => number;
|
|
14
|
+
readonly setTimer?: (cb: () => void, ms: number) => unknown;
|
|
15
|
+
readonly clearTimer?: (handle: unknown) => void;
|
|
16
|
+
readonly acquireRefreshLock?: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
17
|
+
readonly getLatestTokens?: () => Tokens | null;
|
|
18
|
+
readonly onRefreshStart?: (reason: RefreshReason) => void;
|
|
19
|
+
readonly onRefreshSuccess?: (reason: RefreshReason, tokens: Tokens) => void;
|
|
20
|
+
readonly onRefreshSkipped?: (reason: RefreshReason, tokens: Tokens) => void;
|
|
21
|
+
readonly onRefreshError?: (reason: RefreshReason, error: unknown, info: {
|
|
22
|
+
transient: boolean;
|
|
23
|
+
retriesLeft: number;
|
|
24
|
+
willRetry: boolean;
|
|
25
|
+
}) => void;
|
|
26
|
+
readonly onScheduled?: (delayMs: number, expiresAt: number) => void;
|
|
27
|
+
readonly onWakeChecked?: (info: {
|
|
28
|
+
decision: 'refresh-now' | 'still-fresh' | 'no-target' | 'no-expiry';
|
|
29
|
+
remainingMs?: number;
|
|
30
|
+
phase: string;
|
|
31
|
+
}) => void;
|
|
32
|
+
readonly onTriggerSkipped?: (reason: RefreshReason, why: 'detached' | 'already-inflight' | 'no-target', phase: string) => void;
|
|
33
|
+
}
|
|
34
|
+
export type Detach = () => void;
|
|
35
|
+
export interface TokenLifecycle {
|
|
36
|
+
readonly detach: () => void;
|
|
37
|
+
readonly wake: () => void;
|
|
38
|
+
}
|
|
39
|
+
export declare function attachTokenLifecycle(options: TokenLifecycleOptions): TokenLifecycle;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { ConnectionTarget } from '../core/types.js';
|
|
3
|
+
import { Transport } from '../transports/contract.js';
|
|
4
|
+
export type Detach = () => void;
|
|
5
|
+
export interface TransportSyncOptions {
|
|
6
|
+
readonly kernel: Kernel;
|
|
7
|
+
readonly transports: readonly Transport[];
|
|
8
|
+
readonly onError?: (transport: Transport, target: ConnectionTarget | null, error: unknown) => void;
|
|
9
|
+
readonly onApplied?: (target: ConnectionTarget | null) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function attachTransportSync(options: TransportSyncOptions): Detach;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { TransportId } from '../core/types.js';
|
|
3
|
+
import { Transport } from '../transports/contract.js';
|
|
4
|
+
export type Detach = () => void;
|
|
5
|
+
export type WatchdogClearReason = 'up' | 'detach' | 'phase-change';
|
|
6
|
+
export interface TransportWatchdogOptions {
|
|
7
|
+
readonly kernel: Kernel;
|
|
8
|
+
readonly transports: readonly Transport[];
|
|
9
|
+
readonly defaultGraceMs?: number;
|
|
10
|
+
readonly setTimer?: (cb: () => void, ms: number) => unknown;
|
|
11
|
+
readonly clearTimer?: (handle: unknown) => void;
|
|
12
|
+
readonly onGraceStarted?: (id: TransportId, graceMs: number) => void;
|
|
13
|
+
readonly onGraceCleared?: (id: TransportId, reason: WatchdogClearReason) => void;
|
|
14
|
+
readonly onConfirmed?: (id: TransportId) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare function attachTransportWatchdog(options: TransportWatchdogOptions): Detach;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Kernel } from '../core/kernel.js';
|
|
2
|
+
import { WorkerHost } from '../worker/protocol.js';
|
|
3
|
+
export type Detach = () => void;
|
|
4
|
+
export interface WorkerBridgeOptions {
|
|
5
|
+
readonly kernel: Kernel;
|
|
6
|
+
readonly hosts: () => Iterable<WorkerHost>;
|
|
7
|
+
readonly listenForResyncRequests?: boolean;
|
|
8
|
+
readonly onBroadcast?: (generation: number, hostCount: number) => void;
|
|
9
|
+
readonly onSyncHost?: (generation: number) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface WorkerBridge {
|
|
12
|
+
readonly detach: Detach;
|
|
13
|
+
syncHost(host: WorkerHost): void;
|
|
14
|
+
syncAll(): void;
|
|
15
|
+
revalidateWorkers(): void;
|
|
16
|
+
}
|
|
17
|
+
export declare function attachWorkerBridge(options: WorkerBridgeOptions): WorkerBridge;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export { createKernel } from './core/kernel.js';
|
|
2
|
+
export { reducer } from './core/reducer.js';
|
|
3
|
+
export { endpointKey, isSameEndpoint, sortByPriority } from './core/resolver.js';
|
|
4
|
+
export { attachBackoff } from './effects/backoff.js';
|
|
5
|
+
export { attachCrossTab } from './effects/crossTab.js';
|
|
6
|
+
export { attachNetworkChange } from './effects/networkChange.js';
|
|
7
|
+
export { attachPersistence, localStorageAdapter, memoryStorageAdapter } from './effects/persistence.js';
|
|
8
|
+
export { attachPresence, defaultOnNetworkOnline } from './effects/presence.js';
|
|
9
|
+
export { attachProbeLoop, isProbeFailure, makeProbeFailure } from './effects/probeLoop.js';
|
|
10
|
+
export { attachTokenLifecycle } from './effects/tokenLifecycle.js';
|
|
11
|
+
export { attachTransportSync } from './effects/transportSync.js';
|
|
12
|
+
export { attachTransportWatchdog } from './effects/transportWatchdog.js';
|
|
13
|
+
export { attachWorkerBridge } from './effects/workerBridge.js';
|
|
14
|
+
export { DEFAULT_RACE_TIMEOUT_BY_MODE, raceFirst, RaceFirstError } from './race.js';
|
|
15
|
+
export { isEndpointChange, isSameTarget, isTokenOnlyChange, TransportEmitter } from './transports/contract.js';
|
|
16
|
+
export type { Action, BackoffHint, ConnectionPhase, ConnectionTarget, Endpoint, EndpointMode, ReconnectCause, ReducerContext, Tokens, TransportId, TransportKind, TransportSpec, TransportStatus, } from './core/types.js';
|
|
17
|
+
export type { Kernel, KernelOptions, Listener, Unsubscribe } from './core/kernel.js';
|
|
18
|
+
export type { BackoffOptions } from './effects/backoff.js';
|
|
19
|
+
export type { CrossTabOptions, CrossTabSource } from './effects/crossTab.js';
|
|
20
|
+
export type { NetworkChangeOptions, NetworkChangeSource } from './effects/networkChange.js';
|
|
21
|
+
export type { PersistedTarget, Persistence, PersistenceOptions, StorageAdapter } from './effects/persistence.js';
|
|
22
|
+
export type { PresenceCallback, PresenceOptions, VisibilitySource } from './effects/presence.js';
|
|
23
|
+
export type { ProbeContext, ProbeFailure, ProbeFailureKind, ProbeLoopOptions } from './effects/probeLoop.js';
|
|
24
|
+
export type { Detach, RefreshReason, TokenLifecycle, TokenLifecycleOptions } from './effects/tokenLifecycle.js';
|
|
25
|
+
export type { TransportSyncOptions } from './effects/transportSync.js';
|
|
26
|
+
export type { TransportWatchdogOptions, WatchdogClearReason } from './effects/transportWatchdog.js';
|
|
27
|
+
export type { WorkerBridge, WorkerBridgeOptions } from './effects/workerBridge.js';
|
|
28
|
+
export type { RaceCandidate, RaceFirstOptions, RaceFirstResult, TimeoutByModeFn } from './race.js';
|
|
29
|
+
export type { KernelSyncMessage, KernelSyncRequestMessage, MessageSource, WorkerHost, WorkerMessage } from './worker/protocol.js';
|
|
30
|
+
export type { PerResourceTransport, Transport, TransportEvent, TransportEventHandler, TransportEventPayload } from './transports/contract.js';
|