zero-trust-application-channel 0.0.0-stage → 1.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 (76) hide show
  1. package/README.md +68 -2
  2. package/dist/audit/index.d.ts +2 -0
  3. package/dist/audit/index.d.ts.map +1 -0
  4. package/dist/audit/interface.d.ts +29 -0
  5. package/dist/audit/interface.d.ts.map +1 -0
  6. package/dist/channel/index.d.ts +3 -0
  7. package/dist/channel/index.d.ts.map +1 -0
  8. package/dist/channel/interface.d.ts +63 -0
  9. package/dist/channel/interface.d.ts.map +1 -0
  10. package/dist/channel/ws-socket-client.d.ts +36 -0
  11. package/dist/channel/ws-socket-client.d.ts.map +1 -0
  12. package/dist/client/index.d.ts +3 -0
  13. package/dist/client/index.d.ts.map +1 -0
  14. package/dist/client/tunnel-client.d.ts +99 -0
  15. package/dist/client/tunnel-client.d.ts.map +1 -0
  16. package/dist/codec/frame-codec.d.ts +26 -0
  17. package/dist/codec/frame-codec.d.ts.map +1 -0
  18. package/dist/codec/index.d.ts +4 -0
  19. package/dist/codec/index.d.ts.map +1 -0
  20. package/dist/codec/types.d.ts +51 -0
  21. package/dist/codec/types.d.ts.map +1 -0
  22. package/dist/connector/index.d.ts +5 -0
  23. package/dist/connector/index.d.ts.map +1 -0
  24. package/dist/connector/reconnect-delay.d.ts +32 -0
  25. package/dist/connector/reconnect-delay.d.ts.map +1 -0
  26. package/dist/connector/tunnel-connector.d.ts +128 -0
  27. package/dist/connector/tunnel-connector.d.ts.map +1 -0
  28. package/dist/demo/hub-harness.d.ts +31 -0
  29. package/dist/demo/hub-harness.d.ts.map +1 -0
  30. package/dist/hub/index.d.ts +3 -0
  31. package/dist/hub/index.d.ts.map +1 -0
  32. package/dist/hub/registry.d.ts +45 -0
  33. package/dist/hub/registry.d.ts.map +1 -0
  34. package/dist/index.d.ts +13 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +1922 -0
  37. package/dist/logger/index.d.ts +2 -0
  38. package/dist/logger/index.d.ts.map +1 -0
  39. package/dist/logger/interface.d.ts +19 -0
  40. package/dist/logger/interface.d.ts.map +1 -0
  41. package/dist/protocol/index.d.ts +2 -0
  42. package/dist/protocol/index.d.ts.map +1 -0
  43. package/dist/protocol/messages.d.ts +226 -0
  44. package/dist/protocol/messages.d.ts.map +1 -0
  45. package/dist/proxy/hub-session-store.d.ts +55 -0
  46. package/dist/proxy/hub-session-store.d.ts.map +1 -0
  47. package/dist/proxy/index.d.ts +8 -0
  48. package/dist/proxy/index.d.ts.map +1 -0
  49. package/dist/proxy/session-gateway.d.ts +85 -0
  50. package/dist/proxy/session-gateway.d.ts.map +1 -0
  51. package/dist/proxy/stream-sink.d.ts +18 -0
  52. package/dist/proxy/stream-sink.d.ts.map +1 -0
  53. package/dist/proxy/tunnel-proxy.d.ts +126 -0
  54. package/dist/proxy/tunnel-proxy.d.ts.map +1 -0
  55. package/dist/result/domain-error.d.ts +50 -0
  56. package/dist/result/domain-error.d.ts.map +1 -0
  57. package/dist/result/index.d.ts +4 -0
  58. package/dist/result/index.d.ts.map +1 -0
  59. package/dist/result/result.d.ts +24 -0
  60. package/dist/result/result.d.ts.map +1 -0
  61. package/dist/session/__test-helpers__/jose-signer.d.ts +13 -0
  62. package/dist/session/__test-helpers__/jose-signer.d.ts.map +1 -0
  63. package/dist/session/__test-helpers__/jose-signer.js +30 -0
  64. package/dist/session/client-session-server.d.ts +23 -0
  65. package/dist/session/client-session-server.d.ts.map +1 -0
  66. package/dist/session/client-session-store.d.ts +59 -0
  67. package/dist/session/client-session-store.d.ts.map +1 -0
  68. package/dist/session/index.d.ts +4 -0
  69. package/dist/session/index.d.ts.map +1 -0
  70. package/dist/token/index.d.ts +2 -0
  71. package/dist/token/index.d.ts.map +1 -0
  72. package/dist/token/interface.d.ts +18 -0
  73. package/dist/token/interface.d.ts.map +1 -0
  74. package/dist/types.d.ts +16 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/package.json +61 -4
package/README.md CHANGED
@@ -1,3 +1,69 @@
1
- # Temporary Holding Version
1
+ # zero-trust-application-channel
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Generic, multiplexed WebSocket tunnel: HTTP/WS reverse-proxying and session
4
+ management over a single outbound connection. This package is the **core
5
+ library** — independent of any application or monorepo. Domain adapters
6
+ (Fastify/PG/container proxies) live in the consuming project.
7
+
8
+ **Two deployments, one package (v2):** the same generic package serves both
9
+ **field→container** and **field→boss** topologies — the register schema is
10
+ neutral (`peerId` + `peerType`), and session/cookie/allowlist behaviour is
11
+ injected via config (see [`../docs/CONTRACTS.md`](../docs/CONTRACTS.md)).
12
+
13
+ ## Contents
14
+
15
+ | Module | Responsibility |
16
+ |---|---|
17
+ | `codec` | Binary frame codec — 9-byte header (streamId u32 BE + seq u32 BE + flags FIN/RST/WS_OP); `decode` never throws (`Result`) |
18
+ | `protocol` | Control message types + zod schemas (register/ack — v2 `peerId` + `peerType`, heartbeat, telemetry, stream-*, open-session/*); `TUNNEL_PROTOCOL_VERSION = 2` |
19
+ | `connector` | `TunnelConnector` — outbound WS client + state machine + exponential backoff (`ReconnectDelay`) |
20
+ | `channel` | `ISocketClient`/`WsSocketClient` (ws adapter), `ITunnelChannel` (client side), `IHubChannel` (hub side, carries peerId) |
21
+ | `client` | `TunnelClient` — stream multiplexing, credit-based backpressure, dual upstream routing, WS bridge |
22
+ | `session` | `ClientSessionStore` + `ClientSessionServer` — ephemeral session JWT (`ITokenSigner` injection) |
23
+ | `proxy` | `SessionGateway` + `HubSessionStore` + `TunnelProxy` — hub-side session + HTTP/WS proxy (`IHubChannel`/`IStreamSink`/`IAuditSink` injection; cookieName + PathAllowlist config) |
24
+ | `logger` / `token` / `audit` / `snapshot` / `types` | Independence contracts — minimal `ILogger`, `ITokenSigner`, `IAuditSink`, `ISnapshotSource`, generic `TunnelRole`/`TunnelUser`/`TunnelTelemetryPoint` |
25
+
26
+ ## Dependencies
27
+
28
+ `ws` + `zod` — nothing else. (`jose` is an optional peer, used only by the
29
+ `./test-helpers` subpath; production code works through injected
30
+ `ITokenSigner`.)
31
+
32
+ ## Example — loopback end-to-end (no application code)
33
+
34
+ ```bash
35
+ bun lib/examples/loopback-demo.mjs
36
+ ```
37
+
38
+ In-package demo: `HubHarness` (hub side) ↔ `TunnelConnector` + `TunnelClient`
39
+ (client side) ↔ `SessionGateway` + `TunnelProxy` — register → session → tunnel
40
+ HTTP → WS bridge over a single real WS channel. The same flow runs as a test:
41
+
42
+ ```bash
43
+ bun run test # includes loopback.spec.ts
44
+ ```
45
+
46
+ ## Tests & quality gates
47
+
48
+ - `bun run test` — unit + spec + loopback end-to-end
49
+ - `bun run typecheck` — `tsc --noEmit` (production code, tests excluded)
50
+ - Security-critical modules (codec, connector, client, proxy) target ≥90%
51
+ branch coverage.
52
+
53
+ ## Contract summary
54
+
55
+ ```ts
56
+ // Client side: TunnelConnector already is an ITunnelChannel
57
+ const client = TunnelClient.create({ webServiceUrl, staticUrl });
58
+ client.attach(connector);
59
+
60
+ // Hub side: inject an IHubChannel adapter (e.g. the in-package HubHarness or
61
+ // the consumer's container-proxy wrapper), an IStreamSink (the consumer's
62
+ // HTTP framework adapter), an IAuditSink and an ITokenSigner
63
+ const gateway = new SessionGateway(channel, store, audit, logger);
64
+ const proxy = new TunnelProxy(channel, store, logger);
65
+ ```
66
+
67
+ The tunnel does NOT interpret roles: `TunnelRole` is a free string — mapping
68
+ and RBAC belong to the consumer. Detailed protocol: [`../docs/LIB-MIMARISI.md`](../docs/LIB-MIMARISI.md)
69
+ and [`../docs/CONTRACTS.md`](../docs/CONTRACTS.md).
@@ -0,0 +1,2 @@
1
+ export type { IAuditSink, SessionAuditOpenRecord, SessionAuditCloseRecord, } from "./interface";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audit/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { TunnelRole } from "../types";
2
+ /** Oturum açılış kaydı — audit sink'ine verilir. */
3
+ export interface SessionAuditOpenRecord {
4
+ hubId: string;
5
+ peerId: string;
6
+ sessionId: string;
7
+ username: string;
8
+ callerRole: TunnelRole;
9
+ peerRole: TunnelRole;
10
+ remoteIp?: string;
11
+ }
12
+ /** Oturum kapanış kaydı. */
13
+ export interface SessionAuditCloseRecord {
14
+ sessionId: string;
15
+ endReason: string;
16
+ bytesIn: number;
17
+ bytesOut: number;
18
+ }
19
+ /**
20
+ * IAuditSink — oturum denetim kaydı sözleşmesi (fail-closed):
21
+ * `open` hata fırlatırsa oturum AÇILMAZ; `close` kapanışta çağrılır
22
+ * (hata yutulur + logger'a bildirilir).
23
+ * Monorepo implementasyonu: `SessionAudit` (web-service, PG + TamperLogger).
24
+ */
25
+ export interface IAuditSink {
26
+ open(record: SessionAuditOpenRecord): Promise<void>;
27
+ close(record: SessionAuditCloseRecord): Promise<void>;
28
+ }
29
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/audit/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,UAAU,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,4BAA4B;AAC5B,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,KAAK,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD"}
@@ -0,0 +1,3 @@
1
+ export { WsSocketClient, WsSocketClientFactory } from "./ws-socket-client";
2
+ export type { ISocketClient, ISocketClientFactory, ITunnelChannel, IHubChannel, } from "./interface";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,WAAW,GACZ,MAAM,aAAa,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * ISocketClient — tünelin kullandığı soket görünümü (jenerik).
3
+ * `ws` paketi `WsSocketClient` adapter'iyle gerçeklenir; testlerde fake soket
4
+ * enjekte edilir (Strategy).
5
+ */
6
+ export interface ISocketClient {
7
+ /** Text frame gönderir (kontrol mesajı JSON). */
8
+ send(data: string): void;
9
+ /** Binary frame gönderir (tünel akış verisi — 9 bayt başlık + payload). */
10
+ sendBinary(data: Uint8Array): void;
11
+ /** WS protokol seviyesi ping — liveness tespiti için (pong beklenir). */
12
+ ping(): void;
13
+ /** Soketi kapatır. */
14
+ close(): void;
15
+ /** Bağlantı açıldı (upgrade tamam). */
16
+ onOpen(callback: () => void): void;
17
+ /** Text mesajı alındı. */
18
+ onMessage(callback: (raw: string) => void): void;
19
+ /** Binary mesajı alındı (tünel akış frame'leri). */
20
+ onBinaryMessage(callback: (data: Buffer) => void): void;
21
+ /** Bağlantı kapandı (her koşulda — hata sonrası dahil). */
22
+ onClose(callback: () => void): void;
23
+ /** Soket hatası — ardından onClose da tetiklenir. */
24
+ onError(callback: (error: Error) => void): void;
25
+ /** Pong alındı — liveness saati sıfırlanır. */
26
+ onPong(callback: () => void): void;
27
+ /**
28
+ * Pre-upgrade ret — sunucu upgrade'i reddetti (örn. 401 service token).
29
+ * `statusCode` HTTP yanıt kodudur.
30
+ */
31
+ onRejected(callback: (statusCode: number) => void): void;
32
+ /** Güncel hazırlık durumu. */
33
+ readyState(): "connecting" | "open" | "closing" | "closed";
34
+ }
35
+ /** Soket üretici sözleşmesi — URL + auth header'ları ile client oluşturur. */
36
+ export interface ISocketClientFactory {
37
+ create(url: string, headers: Record<string, string>, protocols?: string[]): ISocketClient;
38
+ }
39
+ /**
40
+ * ITunnelChannel — client tarafı kanal (TEK outbound bağlantı).
41
+ * TunnelConnector bu sözleşmeyi uygular; TunnelClient `attach(channel)` ile
42
+ * tünel akışlarını aynı WS üzerinden çoklar.
43
+ */
44
+ export interface ITunnelChannel {
45
+ onMessage(subscriber: (message: unknown) => void): () => void;
46
+ onBinaryFrame(subscriber: (data: Buffer) => void): () => void;
47
+ sendControl(message: unknown): void;
48
+ sendBinary(data: Buffer): void;
49
+ }
50
+ /**
51
+ * IHubChannel — hub tarafı kanal (peer başına peerId).
52
+ * Monorepo implementasyonu: `ContainerProxyFieldChannel` (ContainerProxy
53
+ * adapter'i — sendControl/sendBinary/observer + bağlantı durumu).
54
+ * İkinci deployment (boss uplink) aynı sözleşmeyi field kayıtları için uygular.
55
+ */
56
+ export interface IHubChannel {
57
+ sendControl(peerId: string, message: unknown): void;
58
+ sendBinary(peerId: string, data: Buffer): void;
59
+ onControlMessage(subscriber: (peerId: string, message: unknown) => void): () => void;
60
+ onBinaryFrame(subscriber: (peerId: string, data: Buffer) => void): () => void;
61
+ isConnected(peerId: string): boolean;
62
+ }
63
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/channel/interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,2EAA2E;IAC3E,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,yEAAyE;IACzE,IAAI,IAAI,IAAI,CAAC;IACb,sBAAsB;IACtB,KAAK,IAAI,IAAI,CAAC;IACd,uCAAuC;IACvC,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACnC,0BAA0B;IAC1B,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACjD,oDAAoD;IACpD,eAAe,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACxD,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACpC,qDAAqD;IACrD,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAChD,+CAA+C;IAC/C,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACnC;;;OAGG;IACH,UAAU,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IACzD,8BAA8B;IAC9B,UAAU,IAAI,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;CAC5D;AAED,8EAA8E;AAC9E,MAAM,WAAW,oBAAoB;IACnC,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,aAAa,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9D,aAAa,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9D,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C,gBAAgB,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACrF,aAAa,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9E,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC"}
@@ -0,0 +1,36 @@
1
+ import { WebSocket } from "ws";
2
+ import type { ISocketClient, ISocketClientFactory } from "./interface";
3
+ /**
4
+ * WsSocketClient — `ws` paketi istemcisini `ISocketClient`'a uyarlar (Adapter).
5
+ * TunnelConnector bu sözleşme üzerinden çalışır; testlerde fake soket enjekte
6
+ * edilir. `unexpected-response` (pre-upgrade ret — 401/403) `onRejected`'a
7
+ * çevrilir; statusCode yoksa 0 iletilir.
8
+ */
9
+ export declare class WsSocketClient implements ISocketClient {
10
+ private readonly raw;
11
+ constructor(raw: WebSocket);
12
+ send(data: string): void;
13
+ sendBinary(data: Uint8Array): void;
14
+ ping(): void;
15
+ close(): void;
16
+ onOpen(callback: () => void): void;
17
+ onMessage(callback: (raw: string) => void): void;
18
+ onBinaryMessage(callback: (data: Buffer) => void): void;
19
+ onClose(callback: () => void): void;
20
+ onError(callback: (error: Error) => void): void;
21
+ onPong(callback: () => void): void;
22
+ onRejected(callback: (statusCode: number) => void): void;
23
+ readyState(): "connecting" | "open" | "closing" | "closed";
24
+ }
25
+ /**
26
+ * WsSocketClientFactory — `ws` WebSocket üreticisi. Creator testlerde fake
27
+ * enjekte edilir; üretimde varsayılan creator gerçek `ws` istemcisini kurar.
28
+ */
29
+ export declare class WsSocketClientFactory implements ISocketClientFactory {
30
+ private readonly creator;
31
+ constructor(creator?: (url: string, protocols: string[], options: {
32
+ headers: Record<string, string>;
33
+ }) => WebSocket);
34
+ create(url: string, headers: Record<string, string>, protocols?: string[]): ISocketClient;
35
+ }
36
+ //# sourceMappingURL=ws-socket-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ws-socket-client.d.ts","sourceRoot":"","sources":["../../src/channel/ws-socket-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AASvE;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,aAAa;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,SAAS;IAE3C,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAIlC,IAAI,IAAI,IAAI;IAIZ,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAOhD,eAAe,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAOvD,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAInC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI/C,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAIlC,UAAU,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAMxD,UAAU,IAAI,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ;CAM3D;AAED;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAIT;gBAKb,OAAO,CAAC,EAAE,CACR,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,KACzC,SAAS;IAOhB,MAAM,CACJ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,SAAS,GAAE,MAAM,EAAO,GACvB,aAAa;CAGjB"}
@@ -0,0 +1,3 @@
1
+ export { TunnelClient } from "./tunnel-client";
2
+ export type { TunnelClientConfig } from "./tunnel-client";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,99 @@
1
+ import type { ISocketClientFactory, ITunnelChannel } from "../channel";
2
+ /** TunnelClient yapılandırması — opsiyonel alanlar testlerde enjekte edilir. */
3
+ export interface TunnelClientConfig {
4
+ /** API upstream taban URL'i (varsayılan kural: `/api/*`, `/ws/*`). */
5
+ webServiceUrl: string;
6
+ /** Statik/SPA upstream taban URL'i (varsayılan kural: diğer yollar). */
7
+ staticUrl: string;
8
+ /**
9
+ * Upstream yönlendirici — opsiyonel. Verilmezse varsayılan kural uygulanır
10
+ * (`/api/*`,`/ws/*` → webServiceUrl, diğer → staticUrl). Tüketici kendi
11
+ * yönlendirme politikasını enjekte edebilir.
12
+ */
13
+ routeUpstream?: (path: string) => string;
14
+ /** Akış kredisi pencere boyutu (tasarım §5.2: 256 KiB). */
15
+ windowSize?: number;
16
+ /** Eşzamanlı akış tavanı (tasarım §5.6: 16). */
17
+ maxStreams?: number;
18
+ /** Frame parça boyutu (tasarım §5.2: ≤64 KiB). */
19
+ chunkSize?: number;
20
+ /** İstek gövdesi tavanı (POST/PUT) — aşımı RST + kapatma. */
21
+ maxRequestBody?: number;
22
+ /** Akış boşta kalma süresi (ms) — §12.4 her stream için idle timeout. */
23
+ idleTimeoutMs?: number;
24
+ /** Akış azami yaşı (ms) — §12.4 max yaş. */
25
+ maxAgeMs?: number;
26
+ /** Sweep aralığı (ms). */
27
+ sweepIntervalMs?: number;
28
+ /** Loopback WS üretici — testlerde fake; üretimde `ws`. */
29
+ socketFactory?: ISocketClientFactory;
30
+ }
31
+ /**
32
+ * TunnelClient — client/peer tarafı akış multiplexer'ı.
33
+ *
34
+ * - `stream-open` frame'lerini alır, stream'leri upstream'e dağıtır:
35
+ * varsayılan kural `/api/*`, `/ws/*` → API upstream; diğer her şey → statik
36
+ * upstream. `routeUpstream` ile değiştirilebilir.
37
+ * - Undici fetch stream'lerini ≤64 KiB binary frame'lere böler; `stream-window`
38
+ * kredisiyle backpressure uygular (kredi yoksa gövde DURUR — §5.2).
39
+ * - `upgrade:"websocket"` → loopback WS köprüsü; mesaj sınırları ve opcode'lar
40
+ * WS_OP bayrağıyla korunur (§5.3).
41
+ * - Limitler: eşzamanlı akış tavanı → 503; boşta kalma/max yaş sweep'i;
42
+ * `stream-close` → iptal.
43
+ */
44
+ export declare class TunnelClient {
45
+ private readonly config;
46
+ private readonly codec;
47
+ private readonly socketFactory;
48
+ private readonly routeUpstream;
49
+ private readonly streams;
50
+ private sweepTimer?;
51
+ private channel?;
52
+ private constructor();
53
+ static create(config: TunnelClientConfig): TunnelClient;
54
+ /** TunnelConnector kanalına abone olur (kontrol + binary). */
55
+ attach(channel: ITunnelChannel): void;
56
+ /** Tüm akışları kapatır ve sweep'i durdurur (komut). */
57
+ stop(): void;
58
+ private handleControl;
59
+ private onStreamOpen;
60
+ private handleBinaryFrame;
61
+ private onWsDataFrame;
62
+ private onBodyFrame;
63
+ /** HTTP akışı: loopback fetch → ack → kredi kontrollü gövde frame'leri. */
64
+ private fetchStream;
65
+ /** Gövde parçasını kredi kontrollü gönderir — kredi yoksa bekler. */
66
+ private sendPayload;
67
+ private sendFin;
68
+ private openWsBridge;
69
+ private awaitCredit;
70
+ private drainWaiting;
71
+ private sendRst;
72
+ private closeStream;
73
+ private sweep;
74
+ private now;
75
+ }
76
+ /** Varsayılan yönlendirme kuralı: `/api|/ws` → API upstream, diğer → statik. */
77
+ export declare function upstreamUrl(path: string, webServiceUrl: string, staticUrl: string): string;
78
+ /** Yanıt başlıklarını hop-by-hop başlıklardan arındırır. */
79
+ export declare function filterHeaders(headers: Headers): Record<string, string>;
80
+ /**
81
+ * Upstream WS URL'inden tarayıcı-origin'i üretir (sorgu — saf):
82
+ * `wss://` → `https://`, `ws://` → `http://` (WHATWG origin ws için
83
+ * http-eşdeğerini bekler; tarayıcı da wss bağlantısında `https://` yollar).
84
+ * Upstream handshake'inde `Origin` olarak kullanılır — Host ile eşleşir.
85
+ */
86
+ export declare function wsOrigin(url: string): string;
87
+ /**
88
+ * Tarayıcının önerdiği subprotocol listesini ayrıştırır (RFC 6455):
89
+ * `Sec-WebSocket-Protocol: a, b` → `["a","b"]`. Upstream handshake'ine
90
+ * `protocols` olarak verilir (app-bağımsız — cockpit1, graphql-ws, mqtt...).
91
+ */
92
+ export declare function requestedSubprotocols(header: string | undefined): string[];
93
+ /**
94
+ * Upstream WS handshake'ine taşınacak başlıkları süzer: hop-by-hop ve el
95
+ * sıkışmasına özgü başlıklar çıkarılır (yeni handshake kendi anahtarını
96
+ * üretir); `cookie`/`authorization` gibi uygulama başlıkları geçer.
97
+ */
98
+ export declare function wsHandshakeHeaders(headers: Record<string, string> | undefined): Record<string, string>;
99
+ //# sourceMappingURL=tunnel-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-client.d.ts","sourceRoot":"","sources":["../../src/client/tunnel-client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAiB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEtF,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0BAA0B;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAuCD;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAarB;IACF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuB;IACrD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,UAAU,CAAC,CAAiC;IACpD,OAAO,CAAC,OAAO,CAAC,CAAiB;IAIjC,OAAO;IAkBP,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY;IAIvD,8DAA8D;IAC9D,MAAM,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAOrC,wDAAwD;IACxD,IAAI,IAAI,IAAI;IAQZ,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,YAAY;IA0CpB,OAAO,CAAC,iBAAiB;IAezB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,WAAW;IAenB,2EAA2E;YAC7D,WAAW;IA8DzB,qEAAqE;YACvD,WAAW;IAyBzB,OAAO,CAAC,OAAO;IAYf,OAAO,CAAC,YAAY;YAmEN,WAAW;IASzB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,GAAG;CAGZ;AAMD,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1F;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOtE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI5C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,EAAE,CAMV;AAaD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB"}
@@ -0,0 +1,26 @@
1
+ import { ValidationError, Result } from "../result";
2
+ import type { TunnelFrame } from "./types";
3
+ /** Frame çözümleme hatası — beklenen (güvenilmez WS girdisi), Result ile taşınır. */
4
+ export declare class FrameDecodeError extends ValidationError {
5
+ constructor(reason: string);
6
+ }
7
+ /**
8
+ * FrameCodec — tünel binary frame codec'i (tasarım §4.2).
9
+ *
10
+ * - `encode(frame)`: programcı hatası (aralık dışı streamId/seq, hatalı
11
+ * opcode-flag birleşimi) throw eder — bunlar protokol verisi değildir.
12
+ * - `decode(buffer, maxPayload?)`: girdi güvenilmezdir; HİÇBİR durumda throw
13
+ * etmez — kısa/çok-büyük frame `Result.err(FrameDecodeError)` döner.
14
+ * İkisi birden (throw ve Result) bilinçli hibrittir (bkz. Faz 0 ek 2).
15
+ */
16
+ export declare class FrameCodec {
17
+ /** Frame'i 9 bayt başlık + payload olarak serileştirir. */
18
+ encode(frame: TunnelFrame): Buffer;
19
+ /**
20
+ * Ham baytları frame'e çözer. Kısa girdi veya `maxPayload` aşımı → Err;
21
+ * aksi halde Ok. WS_OP yokken `opcode` undefined döner; bilinmeyen opcode
22
+ * değerleri korunur (ileri uyumluluk).
23
+ */
24
+ decode(buffer: Uint8Array, maxPayload?: number): Result<TunnelFrame, FrameDecodeError>;
25
+ }
26
+ //# sourceMappingURL=frame-codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-codec.d.ts","sourceRoot":"","sources":["../../src/codec/frame-codec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAMpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,qFAAqF;AACrF,qBAAa,gBAAiB,SAAQ,eAAe;gBACvC,MAAM,EAAE,MAAM;CAG3B;AAED;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACrB,2DAA2D;IAC3D,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM;IA6BlC;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,GAAE,MAA0B,GAAG,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC;CA+B1G"}
@@ -0,0 +1,4 @@
1
+ export { FrameCodec, FrameDecodeError } from "./frame-codec";
2
+ export { FRAME_HEADER_SIZE, MAX_CHUNK_SIZE, MAX_FRAME_PAYLOAD, FLAG_FIN, FLAG_RST, FLAG_WS_OP, WS_OPCODE, } from "./types";
3
+ export type { TunnelFrame } from "./types";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/codec/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAS,GACV,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Tünel akış frame'i tipleri — tasarım §4.2.
3
+ *
4
+ * Binary frame düzeni (9 bayt başlık + payload):
5
+ * ```
6
+ * 0 4 8 9
7
+ * ┌────────┬────────┬───┬────────────────────────┐
8
+ * │ streamId (u32 BE) │ seq (u32 BE) │flags│ payload (ham bayt)
9
+ * └────────┴────────┴───┴────────────────────────┘
10
+ * flags: 0x01 FIN · 0x02 RST · 0x04 WS_OP
11
+ * WS_OP varken sonraki 4 bit opcode: 0x0 veri, 0x1 text, 0x2 binary,
12
+ * 0x8 close, 0x9 ping, 0xA pong
13
+ * ```
14
+ *
15
+ * - `streamId`: oturum açan taraf (field) atar, monoton artan.
16
+ * - `seq`: akış içi sıra (güvenilir WS üzerinde kayıp olmaz; teşhis amaçlı).
17
+ * - `WS_OP`: tünel WS akışlarında mesaj sınırları ve opcode'lar korunur.
18
+ */
19
+ /** Başlık boyutu: streamId (4) + seq (4) + flags (1). */
20
+ export declare const FRAME_HEADER_SIZE = 9;
21
+ /** Frame başına azami payload — 64 KiB parçalar (tasarım §5.2). */
22
+ export declare const MAX_CHUNK_SIZE: number;
23
+ /** decode() güvenlik sınırı — 1 MiB üstü frame reddedilir. */
24
+ export declare const MAX_FRAME_PAYLOAD: number;
25
+ /** flags bitleri. */
26
+ export declare const FLAG_FIN = 1;
27
+ export declare const FLAG_RST = 2;
28
+ export declare const FLAG_WS_OP = 4;
29
+ /** WS_OP varken taşınan WS opcode değerleri (RFC 6455 alt kümesi). */
30
+ export declare const WS_OPCODE: {
31
+ readonly Data: 0;
32
+ readonly Text: 1;
33
+ readonly Binary: 2;
34
+ readonly Close: 8;
35
+ readonly Ping: 9;
36
+ readonly Pong: 10;
37
+ };
38
+ /** Bir tünel akış frame'i. `opcode` yalnızca WS_OP flag'i set iken anlamlıdır. */
39
+ export interface TunnelFrame {
40
+ /** Akış kimliği — 0..2^32-1. */
41
+ streamId: number;
42
+ /** Akış içi sıra numarası — 0..2^32-1. */
43
+ seq: number;
44
+ /** FIN|RST|WS_OP bitlerinin birleşimi (WS_OP varken yüksek 4 bit opcode taşır). */
45
+ flags: number;
46
+ /** WS_OP set iken WS opcode (0-15); diğer durumda undefined. */
47
+ opcode?: number;
48
+ /** Ham payload baytları. */
49
+ payload: Uint8Array;
50
+ }
51
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/codec/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,mEAAmE;AACnE,eAAO,MAAM,cAAc,QAAY,CAAC;AAExC,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,QAAc,CAAC;AAE7C,qBAAqB;AACrB,eAAO,MAAM,QAAQ,IAAO,CAAC;AAC7B,eAAO,MAAM,QAAQ,IAAO,CAAC;AAC7B,eAAO,MAAM,UAAU,IAAO,CAAC;AAE/B,sEAAsE;AACtE,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAEX,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,OAAO,EAAE,UAAU,CAAC;CACrB"}
@@ -0,0 +1,5 @@
1
+ export { TunnelConnector } from "./tunnel-connector";
2
+ export type { TunnelConnectorConfig } from "./tunnel-connector";
3
+ export { ReconnectDelay } from "./reconnect-delay";
4
+ export type { ReconnectDelayConfig } from "./reconnect-delay";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /** ReconnectDelay yapılandırması — tüm alanlar zorunlu (birincil constructor). */
2
+ export interface ReconnectDelayConfig {
3
+ /** Taban gecikme (ms) — attempt 1'deki değer. */
4
+ baseMs: number;
5
+ /** Maksimum gecikme (ms) — üstel büyüme bu değeri aşamaz. */
6
+ maxMs: number;
7
+ /** Jitter açıklığı (ms) — [0, jitterSpanMs) aralığında ekleme. */
8
+ jitterSpanMs: number;
9
+ /** [0, 1) aralığında rastgele değer üretici — testlerde deterministik enjekte edilir. */
10
+ jitter: () => number;
11
+ }
12
+ /**
13
+ * ReconnectDelay — üstel backoff hesaplayıcı (tasarım §6):
14
+ *
15
+ * `delayFor(attempt)` = `min(maxMs, baseMs · 2^(attempt-1) + jitter() · jitterSpanMs)`.
16
+ * `reset()` başarılı bağlantıda çağrılır — bir sonraki kopuş yeniden tabandan başlar
17
+ * (reconnect fırtınası önlenir, tasarım §12.4).
18
+ *
19
+ * Immutable — durum yalnızca `reset()` komutuyla değişir (Elegant Object kural 3).
20
+ */
21
+ export declare class ReconnectDelay {
22
+ private readonly baseMs;
23
+ private readonly maxMs;
24
+ private readonly jitterSpanMs;
25
+ private readonly jitter;
26
+ constructor(config: ReconnectDelayConfig);
27
+ /** `attempt` (1 tabanlı) için beklenmesi gereken gecikmeyi döndürür (ms). */
28
+ delayFor(attempt: number): number;
29
+ /** Başarılı bağlantıda çağrılır — bir sonraki kopuş tabandan başlar. */
30
+ reset(): void;
31
+ }
32
+ //# sourceMappingURL=reconnect-delay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect-delay.d.ts","sourceRoot":"","sources":["../../src/connector/reconnect-delay.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAC;IACrB,yFAAyF;IACzF,MAAM,EAAE,MAAM,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,oBAAoB;IA4BxC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAoBjC,wEAAwE;IACxE,KAAK,IAAI,IAAI;CAId"}
@@ -0,0 +1,128 @@
1
+ import type { TunnelConnectorState, ServiceAnnouncement, TunnelPeerType } from "../protocol";
2
+ import type { ILogger } from "../logger";
3
+ import type { ISocketClientFactory, ITunnelChannel } from "../channel";
4
+ import type { ReconnectDelay } from "./reconnect-delay";
5
+ /** TunnelConnector yapılandırması — bootstrap env'den türetilir (tasarım §6.1). */
6
+ export interface TunnelConnectorConfig {
7
+ /** Hub WS URL listesi — sırayla denenir (ana + yedek). */
8
+ wsUrls: readonly string[];
9
+ /** Service token — upgrade'de `Authorization: Bearer` header'ı olarak taşınır. */
10
+ token: string;
11
+ /** Peer kimliği — register mesajının `peerId` alanı. */
12
+ peerId: string;
13
+ /** Peer türü — hub kayıt/doğrulama tarafını seçer. Varsayılan: "container". */
14
+ peerType?: TunnelPeerType;
15
+ /**
16
+ * Peer'ın sunduğu OPAK servisler (opsiyonel). Register mesajına yalnızca
17
+ * doluysa eklenir; hub hedef adresi bilmez (bkz. ServiceAnnouncement).
18
+ */
19
+ services?: readonly ServiceAnnouncement[];
20
+ /** Heartbeat gönderim aralığı (ms) — operational config ile değişebilir. */
21
+ heartbeatIntervalMs: number;
22
+ /**
23
+ * Log olay kodları — nötr varsayılanlar; tüketici kendi (domain) kodlarını
24
+ * enjekte eder. Paket domain sözlüğü bilmez.
25
+ */
26
+ eventCodes?: Partial<TunnelConnectorEventCodes>;
27
+ /** Register sonrası ack bekleme süresi (ms) — aşarsa backoff. */
28
+ registerTimeoutMs: number;
29
+ /** Pong alınmazsa bağlantı yarı-ölü sayılır (ms). */
30
+ livenessTimeoutMs: number;
31
+ }
32
+ /** Connector log olay kodları — nötr varsayılanlar. */
33
+ export interface TunnelConnectorEventCodes {
34
+ connected: string;
35
+ connectionLost: string;
36
+ registerRejected: string;
37
+ configRejected: string;
38
+ }
39
+ /** Varsayılan olay kodları — transport-nötr. */
40
+ export declare const DEFAULT_TUNNEL_EVENT_CODES: Readonly<TunnelConnectorEventCodes>;
41
+ /**
42
+ * TunnelConnector — client→hub outbound WS istemcisi (tasarım §6).
43
+ *
44
+ * Sorumluluklar: register + heartbeat + PPC durumu (`state()`) + operational
45
+ * config alımı (register-ack.config / config-update — restart'sız). Tünel
46
+ * stream'leri aynı kanala eklenir.
47
+ *
48
+ * Domain mesajları (telemetri/operasyon/olay) TAŞIMAZ; bilinmeyen tipler
49
+ * `onMessage` abonelerine akar.
50
+ *
51
+ * Durum makinesi (tasarım §6 diyagramı):
52
+ * ```
53
+ * offline → connecting: start() veya backoff bitti
54
+ * connecting → registered: register-ack ok
55
+ * connecting → backoff: hata / 401 / register timeout
56
+ * registered → connected: ilk heartbeat gönderildi
57
+ * connected → backoff: WS kapandı / liveness timeout
58
+ * backoff → connecting: exp(2^n·1s)+jitter (ReconnectDelay)
59
+ * connected → offline: stop()
60
+ * ```
61
+ *
62
+ * Yan etkiler: `ws` soketi (enjekte fabrikadan), ILogger (geçiş-odaklı loglar —
63
+ * kodlar `eventCodes` ile enjekte edilir; varsayılanlar nötrdür).
64
+ */
65
+ export declare class TunnelConnector implements ITunnelChannel {
66
+ private readonly config;
67
+ private readonly socketFactory;
68
+ private readonly reconnectDelay;
69
+ private readonly logger?;
70
+ private readonly now;
71
+ private stateValue;
72
+ private socket?;
73
+ private generation;
74
+ private attempt;
75
+ private urlIndex;
76
+ private stopped;
77
+ private heartbeatTimer?;
78
+ private registerTimer?;
79
+ private reconnectTimer?;
80
+ private lastHeartbeatSentAt?;
81
+ private lastPongAt;
82
+ private operational;
83
+ private readonly eventCodes;
84
+ private readonly messageSubscribers;
85
+ private readonly binarySubscribers;
86
+ constructor(config: TunnelConnectorConfig, socketFactory: ISocketClientFactory, reconnectDelay: ReconnectDelay, logger?: ILogger | undefined, now?: () => number);
87
+ /** Bağlantı döngüsünü başlatır (komut). Çalışıyorsa no-op. */
88
+ start(): Promise<void>;
89
+ /** Bağlantıyı kapatır, yeniden bağlanmaz (komut). */
90
+ stop(): Promise<void>;
91
+ /** Güncel durum makinesi durumu (sorgu). */
92
+ state(): TunnelConnectorState;
93
+ /** Hub'a bağlı mı — PPC kaynağı (sorgu). */
94
+ connected(): boolean;
95
+ /** Son heartbeat'in gönderildiği zaman (ms epoch) — hiç gönderilmediyse undefined. */
96
+ lastHeartbeatAt(): number | undefined;
97
+ /**
98
+ * Faz 3: tünel katmanının kullandığı kontrol mesajı gönderici (komut).
99
+ * stream-open-ack / stream-window / stream-close / open-session-ack.
100
+ * WS açık değilse no-op.
101
+ */
102
+ sendControl(message: unknown): void;
103
+ /** Faz 3: ham binary frame gönderici (9 bayt başlık + payload). WS açıksa. */
104
+ sendBinary(data: Buffer): void;
105
+ /**
106
+ * Faz 3: tünel kontrol mesajı aboneliği — TunnelConnector'ın bilmediği tipler
107
+ * (open-session, stream-*, session-end) abonelere iletilir. Unsubscribe
108
+ * fonksiyonu döner (sorgu + yan etki — abonelik kurulumu).
109
+ */
110
+ onMessage(subscriber: (message: unknown) => void): () => void;
111
+ /** Faz 3: binary frame aboneliği — tünel akış verisi abonelere iletilir. */
112
+ onBinaryFrame(subscriber: (data: Buffer) => void): () => void;
113
+ private connect;
114
+ private tryUrl;
115
+ private handleMessage;
116
+ private sendHeartbeat;
117
+ private applyOperationalConfig;
118
+ private scheduleHeartbeat;
119
+ private closeAndBackoff;
120
+ private enterBackoff;
121
+ private clearTimers;
122
+ private registerFrame;
123
+ /** Peer türü — varsayılan "container" (geriye uyumluluk). */
124
+ private peerType;
125
+ private send;
126
+ private log;
127
+ }
128
+ //# sourceMappingURL=tunnel-connector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-connector.d.ts","sourceRoot":"","sources":["../../src/connector/tunnel-connector.ts"],"names":[],"mappings":"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"}