@floegence/flowersec-core 0.27.0 → 2.0.0

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 (268) hide show
  1. package/README.md +91 -22
  2. package/THIRD_PARTY_NOTICES.md +141 -0
  3. package/dist/browser/connectSession.d.ts +13 -0
  4. package/dist/browser/connectSession.js +40 -0
  5. package/dist/browser/index.d.ts +3 -10
  6. package/dist/browser/index.js +2 -5
  7. package/dist/browser/runtimeCapability.d.ts +13 -0
  8. package/dist/browser/runtimeCapability.js +27 -0
  9. package/dist/browser/sessionRuntime.d.ts +2 -0
  10. package/dist/browser/sessionRuntime.js +21 -0
  11. package/dist/browser/webTransportClient.d.ts +8 -0
  12. package/dist/browser/webTransportClient.js +55 -0
  13. package/dist/cli.d.ts +2 -0
  14. package/dist/cli.js +126 -0
  15. package/dist/cliSpendMarker.d.ts +1 -0
  16. package/dist/cliSpendMarker.js +22 -0
  17. package/dist/connectionController.d.ts +54 -0
  18. package/dist/connectionController.js +438 -0
  19. package/dist/connector/adapters/webSocketCandidate.d.ts +7 -0
  20. package/dist/connector/adapters/webSocketCandidate.js +116 -0
  21. package/dist/connector/adapters/webTransportCandidate.d.ts +5 -0
  22. package/dist/connector/adapters/webTransportCandidate.js +73 -0
  23. package/dist/connector/admissionCommit.d.ts +31 -0
  24. package/dist/connector/admissionCommit.js +239 -0
  25. package/dist/connector/sessionAcceptor.d.ts +16 -0
  26. package/dist/connector/sessionAcceptor.js +114 -0
  27. package/dist/connector/sessionConfig.d.ts +3 -0
  28. package/dist/connector/sessionConfig.js +30 -0
  29. package/dist/connector/sessionConnector.d.ts +45 -0
  30. package/dist/connector/sessionConnector.js +603 -0
  31. package/dist/defaults.d.ts +7 -7
  32. package/dist/defaults.js +7 -7
  33. package/dist/facade.d.ts +12 -27
  34. package/dist/facade.js +6 -24
  35. package/dist/node/connectSession.d.ts +21 -0
  36. package/dist/node/connectSession.js +62 -0
  37. package/dist/node/index.d.ts +3 -11
  38. package/dist/node/index.js +2 -8
  39. package/dist/node/runtimeCapability.d.ts +7 -0
  40. package/dist/node/runtimeCapability.js +10 -0
  41. package/dist/node/sessionRuntime.d.ts +2 -0
  42. package/dist/node/sessionRuntime.js +13 -0
  43. package/dist/node/webTransportClient.d.ts +9 -0
  44. package/dist/node/webTransportClient.js +56 -0
  45. package/dist/node/webTransportServer.d.ts +22 -0
  46. package/dist/node/webTransportServer.js +100 -0
  47. package/dist/node/wsFactory.d.ts +3 -1
  48. package/dist/node/wsFactory.js +4 -3
  49. package/dist/proxy/controllerGuard.d.ts +4 -4
  50. package/dist/proxy/controllerGuard.js +83 -177
  51. package/dist/proxy/disableUpstreamServiceWorkerRegister.d.ts +3 -1
  52. package/dist/proxy/disableUpstreamServiceWorkerRegister.js +19 -17
  53. package/dist/proxy/index.d.ts +16 -15
  54. package/dist/proxy/index.js +8 -14
  55. package/dist/proxy/integration.d.ts +23 -71
  56. package/dist/proxy/integration.js +37 -340
  57. package/dist/proxy/registerServiceWorker.d.ts +1 -10
  58. package/dist/proxy/registerServiceWorker.js +43 -105
  59. package/dist/proxy/runtime.d.ts +3 -63
  60. package/dist/proxy/runtime.js +349 -462
  61. package/dist/proxy/scope.d.ts +6 -0
  62. package/dist/proxy/scope.js +131 -0
  63. package/dist/proxy/serviceWorker.d.ts +5 -16
  64. package/dist/proxy/serviceWorker.js +230 -617
  65. package/dist/proxy/stream.d.ts +9 -0
  66. package/dist/proxy/stream.js +40 -0
  67. package/dist/proxy/types.d.ts +78 -30
  68. package/dist/proxy/windowBridge.d.ts +61 -0
  69. package/dist/proxy/windowBridge.js +344 -0
  70. package/dist/proxy/wsPatch.d.ts +4 -14
  71. package/dist/proxy/wsPatch.js +173 -268
  72. package/dist/public/artifact.d.ts +11 -0
  73. package/dist/public/artifact.js +44 -0
  74. package/dist/public/artifactLease.d.ts +10 -0
  75. package/dist/public/artifactLease.js +48 -0
  76. package/dist/public/connectError.d.ts +6 -0
  77. package/dist/public/connectError.js +9 -0
  78. package/dist/public/contract.d.ts +83 -0
  79. package/dist/public/contract.js +17 -0
  80. package/dist/public/streamMetadata.d.ts +10 -0
  81. package/dist/public/streamMetadata.js +40 -0
  82. package/dist/rpc/caller.d.ts +1 -1
  83. package/dist/rpc/client.d.ts +1 -4
  84. package/dist/rpc/client.js +0 -21
  85. package/dist/rpc/rpcProxy.d.ts +1 -1
  86. package/dist/rpc/server.d.ts +1 -1
  87. package/dist/rpc/validate.d.ts +1 -1
  88. package/dist/rpc/wire.d.ts +15 -0
  89. package/dist/runtime/errors.d.ts +6 -0
  90. package/dist/runtime/errors.js +10 -0
  91. package/dist/transport/webSocketAdapter.d.ts +24 -0
  92. package/dist/transport/webSocketAdapter.js +234 -0
  93. package/dist/transport/webTransportAdapter.d.ts +27 -0
  94. package/dist/transport/webTransportAdapter.js +519 -0
  95. package/dist/utils/errors.d.ts +2 -20
  96. package/dist/utils/errors.js +73 -20
  97. package/dist/v2/admissionError.d.ts +4 -0
  98. package/dist/v2/admissionError.js +8 -0
  99. package/dist/v2/artifact.d.ts +128 -0
  100. package/dist/v2/artifact.js +1126 -0
  101. package/dist/v2/artifactLease.d.ts +1 -0
  102. package/dist/v2/artifactLease.js +7 -0
  103. package/dist/v2/capability.d.ts +29 -0
  104. package/dist/v2/capability.js +190 -0
  105. package/dist/v2/carrier.d.ts +79 -0
  106. package/dist/v2/carrier.js +405 -0
  107. package/dist/v2/contract.d.ts +37 -0
  108. package/dist/v2/contract.js +1 -0
  109. package/dist/v2/handshake.d.ts +80 -0
  110. package/dist/v2/handshake.js +470 -0
  111. package/dist/v2/opaqueArtifact.d.ts +1 -0
  112. package/dist/v2/opaqueArtifact.js +2 -0
  113. package/dist/v2/protocol.d.ts +99 -0
  114. package/dist/v2/protocol.js +739 -0
  115. package/dist/v2/publicSession.d.ts +1 -0
  116. package/dist/v2/publicSession.js +179 -0
  117. package/dist/v2/retryDisposition.d.ts +16 -0
  118. package/dist/v2/retryDisposition.js +30 -0
  119. package/dist/v2/session.d.ts +277 -0
  120. package/dist/v2/session.js +1879 -0
  121. package/dist/v2/streamLifetimeLedger.d.ts +31 -0
  122. package/dist/v2/streamLifetimeLedger.js +131 -0
  123. package/dist/v2/streamMetadata.d.ts +1 -0
  124. package/dist/v2/streamMetadata.js +7 -0
  125. package/dist/v2/unreliableMessage.d.ts +43 -0
  126. package/dist/v2/unreliableMessage.js +252 -0
  127. package/dist/vendor/tr46.d.ts +10 -0
  128. package/dist/vendor/tr46.js +501 -0
  129. package/dist/ws-client/binaryTransport.d.ts +0 -3
  130. package/dist/ws-client/binaryTransport.js +15 -39
  131. package/dist/yamux/errors.d.ts +0 -4
  132. package/dist/yamux/errors.js +0 -9
  133. package/dist/yamux/session.d.ts +0 -5
  134. package/dist/yamux/session.js +4 -70
  135. package/dist/yamux/stream.d.ts +1 -0
  136. package/dist/yamux/stream.js +4 -0
  137. package/package.json +29 -81
  138. package/sbom/cyclonedx.json +2764 -0
  139. package/sbom/spdx.json +1947 -0
  140. package/YAMUX_ALIGNMENT.md +0 -127
  141. package/dist/_examples/flowersec/demo/v1.facade.gen.d.ts +0 -12
  142. package/dist/_examples/flowersec/demo/v1.facade.gen.js +0 -15
  143. package/dist/_examples/flowersec/demo/v1.gen.d.ts +0 -16
  144. package/dist/_examples/flowersec/demo/v1.gen.js +0 -86
  145. package/dist/_examples/flowersec/demo/v1.rpc.gen.d.ts +0 -11
  146. package/dist/_examples/flowersec/demo/v1.rpc.gen.js +0 -22
  147. package/dist/browser/connect.d.ts +0 -13
  148. package/dist/browser/connect.js +0 -31
  149. package/dist/browser/reconnectConfig.d.ts +0 -15
  150. package/dist/browser/reconnectConfig.js +0 -20
  151. package/dist/client-connect/common.d.ts +0 -26
  152. package/dist/client-connect/common.js +0 -167
  153. package/dist/client-connect/connectCore.d.ts +0 -61
  154. package/dist/client-connect/connectCore.js +0 -572
  155. package/dist/client-connect/contract.d.ts +0 -8
  156. package/dist/client-connect/contract.js +0 -51
  157. package/dist/client-connect/termination.d.ts +0 -6
  158. package/dist/client-connect/termination.js +0 -7
  159. package/dist/client-connect/transportSecurity.d.ts +0 -27
  160. package/dist/client-connect/transportSecurity.js +0 -199
  161. package/dist/client-connect/tunnelAttachCloseReason.d.ts +0 -3
  162. package/dist/client-connect/tunnelAttachCloseReason.js +0 -23
  163. package/dist/client.d.ts +0 -23
  164. package/dist/connect/artifact.d.ts +0 -36
  165. package/dist/connect/artifact.js +0 -213
  166. package/dist/connect/resolveArtifact.d.ts +0 -22
  167. package/dist/connect/resolveArtifact.js +0 -87
  168. package/dist/controlplane/channelInit.d.ts +0 -27
  169. package/dist/controlplane/channelInit.js +0 -116
  170. package/dist/controlplane/http.d.ts +0 -16
  171. package/dist/controlplane/http.js +0 -59
  172. package/dist/controlplane/index.d.ts +0 -6
  173. package/dist/controlplane/index.js +0 -5
  174. package/dist/controlplane/issuer.d.ts +0 -18
  175. package/dist/controlplane/issuer.js +0 -113
  176. package/dist/controlplane/request.d.ts +0 -51
  177. package/dist/controlplane/request.js +0 -273
  178. package/dist/controlplane/token.d.ts +0 -33
  179. package/dist/controlplane/token.js +0 -119
  180. package/dist/direct-client/connect.d.ts +0 -9
  181. package/dist/direct-client/connect.js +0 -90
  182. package/dist/direct-client/index.d.ts +0 -1
  183. package/dist/direct-client/index.js +0 -1
  184. package/dist/e2ee/constants.d.ts +0 -9
  185. package/dist/e2ee/constants.js +0 -18
  186. package/dist/e2ee/errors.d.ts +0 -5
  187. package/dist/e2ee/errors.js +0 -8
  188. package/dist/e2ee/framing.d.ts +0 -12
  189. package/dist/e2ee/framing.js +0 -57
  190. package/dist/e2ee/handshake.d.ts +0 -88
  191. package/dist/e2ee/handshake.js +0 -353
  192. package/dist/e2ee/index.d.ts +0 -7
  193. package/dist/e2ee/index.js +0 -7
  194. package/dist/e2ee/kdf.d.ts +0 -15
  195. package/dist/e2ee/kdf.js +0 -39
  196. package/dist/e2ee/record.d.ts +0 -11
  197. package/dist/e2ee/record.js +0 -80
  198. package/dist/e2ee/secureChannel.d.ts +0 -93
  199. package/dist/e2ee/secureChannel.js +0 -342
  200. package/dist/e2ee/transcript.d.ts +0 -23
  201. package/dist/e2ee/transcript.js +0 -31
  202. package/dist/endpoint/index.d.ts +0 -84
  203. package/dist/endpoint/index.js +0 -557
  204. package/dist/endpoint/node.d.ts +0 -9
  205. package/dist/endpoint/node.js +0 -51
  206. package/dist/gen/flowersec/controlplane/v1.gen.d.ts +0 -36
  207. package/dist/gen/flowersec/controlplane/v1.gen.js +0 -135
  208. package/dist/gen/flowersec/direct/v1.gen.d.ts +0 -21
  209. package/dist/gen/flowersec/direct/v1.gen.js +0 -101
  210. package/dist/gen/flowersec/e2ee/v1.gen.d.ts +0 -68
  211. package/dist/gen/flowersec/e2ee/v1.gen.js +0 -194
  212. package/dist/gen/flowersec/rpc/v1.gen.d.ts +0 -30
  213. package/dist/gen/flowersec/rpc/v1.gen.js +0 -107
  214. package/dist/gen/flowersec/tunnel/v1.gen.d.ts +0 -23
  215. package/dist/gen/flowersec/tunnel/v1.gen.js +0 -104
  216. package/dist/index.d.ts +0 -22
  217. package/dist/index.js +0 -22
  218. package/dist/node/connect.d.ts +0 -10
  219. package/dist/node/connect.js +0 -29
  220. package/dist/node/reconnectConfig.d.ts +0 -16
  221. package/dist/node/reconnectConfig.js +0 -20
  222. package/dist/observability/index.d.ts +0 -1
  223. package/dist/observability/index.js +0 -1
  224. package/dist/observability/observer.d.ts +0 -52
  225. package/dist/observability/observer.js +0 -314
  226. package/dist/proxy/appWindow.d.ts +0 -37
  227. package/dist/proxy/appWindow.js +0 -273
  228. package/dist/proxy/bootstrap.d.ts +0 -35
  229. package/dist/proxy/bootstrap.js +0 -119
  230. package/dist/proxy/constants.d.ts +0 -7
  231. package/dist/proxy/constants.js +0 -8
  232. package/dist/proxy/controllerWindow.d.ts +0 -12
  233. package/dist/proxy/controllerWindow.js +0 -384
  234. package/dist/proxy/cookieJar.d.ts +0 -7
  235. package/dist/proxy/cookieJar.js +0 -136
  236. package/dist/proxy/headerPolicy.d.ts +0 -14
  237. package/dist/proxy/headerPolicy.js +0 -134
  238. package/dist/proxy/portStream.d.ts +0 -5
  239. package/dist/proxy/portStream.js +0 -256
  240. package/dist/proxy/preset.d.ts +0 -29
  241. package/dist/proxy/preset.js +0 -111
  242. package/dist/proxy/runtimeScope.d.ts +0 -57
  243. package/dist/proxy/runtimeScope.js +0 -218
  244. package/dist/proxy/server.d.ts +0 -28
  245. package/dist/proxy/server.js +0 -833
  246. package/dist/proxy/windowBridgeProtocol.d.ts +0 -65
  247. package/dist/proxy/windowBridgeProtocol.js +0 -11
  248. package/dist/reconnect/artifactControlplane.d.ts +0 -16
  249. package/dist/reconnect/artifactControlplane.js +0 -35
  250. package/dist/reconnect/index.d.ts +0 -36
  251. package/dist/reconnect/index.js +0 -388
  252. package/dist/rpc-proxy/index.d.ts +0 -1
  253. package/dist/rpc-proxy/index.js +0 -1
  254. package/dist/rpc-proxy/rpcProxy.d.ts +0 -1
  255. package/dist/rpc-proxy/rpcProxy.js +0 -1
  256. package/dist/streamhello/index.d.ts +0 -1
  257. package/dist/streamhello/index.js +0 -1
  258. package/dist/streamhello/streamHello.d.ts +0 -3
  259. package/dist/streamhello/streamHello.js +0 -13
  260. package/dist/streamio/index.d.ts +0 -32
  261. package/dist/streamio/index.js +0 -87
  262. package/dist/tunnel-client/connect.d.ts +0 -9
  263. package/dist/tunnel-client/connect.js +0 -147
  264. package/dist/tunnel-client/index.d.ts +0 -1
  265. package/dist/tunnel-client/index.js +0 -1
  266. package/dist/ws/index.d.ts +0 -1
  267. package/dist/ws/index.js +0 -1
  268. /package/dist/{client.js → rpc/wire.js} +0 -0
@@ -0,0 +1,83 @@
1
+ import type { StreamMetadata } from "./streamMetadata.js";
2
+ export type CarrierKind = "websocket" | "raw_quic" | "webtransport";
3
+ export type PathKind = "direct" | "tunnel";
4
+ export type JsonPrimitive = null | boolean | number | string;
5
+ export type JsonValue = JsonPrimitive | JsonObject | readonly JsonValue[];
6
+ export type JsonObject = Readonly<{
7
+ [key: string]: JsonValue;
8
+ }>;
9
+ export type OperationOptions = Readonly<{
10
+ signal?: AbortSignal;
11
+ }>;
12
+ export type UnreliableMessageSendOptions = OperationOptions & Readonly<{
13
+ expiresAtUnixMs: number;
14
+ }>;
15
+ export type UnreliableMessageSendResult = "accepted" | "dropped_budget" | "dropped_expired" | "dropped_carrier";
16
+ export interface UnreliableMessageChannel {
17
+ readonly maxMessageSize: 976;
18
+ send(message: Uint8Array, options: UnreliableMessageSendOptions): Promise<UnreliableMessageSendResult>;
19
+ receive(options?: OperationOptions): Promise<Uint8Array>;
20
+ }
21
+ export declare class UnreliableMessageError extends Error {
22
+ readonly code: "invalid_message" | "closed" | "operation_failed";
23
+ constructor(code: "invalid_message" | "closed" | "operation_failed");
24
+ }
25
+ export type StreamOpenOptions = OperationOptions & Readonly<{
26
+ metadata?: StreamMetadata;
27
+ }>;
28
+ export type SessionErrorCode = "canceled" | "timeout" | "closed" | "going_away" | "resource_exhausted" | "stream_rejected" | "stream_reset" | "rekey_failed" | "liveness_failed" | "unreliable_unavailable" | "unreliable_too_large" | "unreliable_dropped" | "operation_failed";
29
+ /** A closed, carrier-neutral session failure with no internal cause or peer detail. */
30
+ export declare class SessionError extends Error {
31
+ readonly code: SessionErrorCode;
32
+ constructor(code: SessionErrorCode);
33
+ }
34
+ export type RpcResult<Response = unknown> = Readonly<{
35
+ ok: true;
36
+ payload: Response;
37
+ }> | Readonly<{
38
+ ok: false;
39
+ error: Readonly<{
40
+ code: number;
41
+ message?: string;
42
+ }>;
43
+ }>;
44
+ export interface RpcPeer {
45
+ call<Request = unknown, Response = unknown>(typeId: number, payload: Request, decodeResponse: (payload: JsonValue) => Response, signal?: AbortSignal): Promise<RpcResult<Response>>;
46
+ notify<Payload = unknown>(typeId: number, payload: Payload): Promise<void>;
47
+ onNotify<Payload = unknown>(typeId: number, handler: (payload: Payload) => void): () => void;
48
+ }
49
+ export interface ByteStream {
50
+ readonly kind: string;
51
+ readonly terminalError: SessionError | undefined;
52
+ read(options?: OperationOptions): Promise<Uint8Array | null>;
53
+ write(data: Uint8Array, options?: OperationOptions): Promise<number>;
54
+ closeWrite(): Promise<void>;
55
+ reset(): Promise<void>;
56
+ close(): Promise<void>;
57
+ }
58
+ export interface IncomingStream {
59
+ readonly kind: string;
60
+ readonly metadata: StreamMetadata;
61
+ readonly stream: ByteStream;
62
+ }
63
+ export type SessionTermination = Readonly<{
64
+ error: SessionError;
65
+ }>;
66
+ export interface Session {
67
+ readonly rpc: RpcPeer;
68
+ readonly unreliableMessages?: UnreliableMessageChannel;
69
+ openStream(kind: string, options?: StreamOpenOptions): Promise<ByteStream>;
70
+ acceptStream(options?: OperationOptions): Promise<IncomingStream>;
71
+ rekey(options?: OperationOptions): Promise<void>;
72
+ probeLiveness(options?: OperationOptions): Promise<number>;
73
+ waitTermination(): Promise<SessionTermination>;
74
+ close(): Promise<void>;
75
+ }
76
+ export type RetryDisposition = Readonly<{
77
+ kind: "terminal";
78
+ }> | Readonly<{
79
+ kind: "retryable";
80
+ }> | Readonly<{
81
+ kind: "retry_after";
82
+ notBeforeUnixMilliseconds: number;
83
+ }>;
@@ -0,0 +1,17 @@
1
+ export class UnreliableMessageError extends Error {
2
+ code;
3
+ constructor(code) {
4
+ super(`Flowersec unreliable message failed (code=${code})`);
5
+ this.code = code;
6
+ this.name = "UnreliableMessageError";
7
+ }
8
+ }
9
+ /** A closed, carrier-neutral session failure with no internal cause or peer detail. */
10
+ export class SessionError extends Error {
11
+ code;
12
+ constructor(code) {
13
+ super(`Flowersec session failed (code=${code})`);
14
+ this.code = code;
15
+ this.name = "SessionError";
16
+ }
17
+ }
@@ -0,0 +1,10 @@
1
+ import type { JsonObject } from "./contract.js";
2
+ export declare class StreamMetadataError extends Error {
3
+ constructor();
4
+ }
5
+ export declare class StreamMetadata {
6
+ readonly values: JsonObject;
7
+ private readonly streamMetadataBrand;
8
+ private constructor();
9
+ }
10
+ export declare function createStreamMetadata(values: JsonObject): StreamMetadata;
@@ -0,0 +1,40 @@
1
+ import { canonicalStreamMetadataJSONV2Internal } from "../v2/protocol.js";
2
+ export class StreamMetadataError extends Error {
3
+ constructor() {
4
+ super("invalid Flowersec stream metadata");
5
+ this.name = "StreamMetadataError";
6
+ }
7
+ }
8
+ export class StreamMetadata {
9
+ values;
10
+ constructor(values) {
11
+ this.values = values;
12
+ Object.freeze(this);
13
+ }
14
+ /** @internal */
15
+ static fromCanonicalValues(values) {
16
+ return new StreamMetadata(values);
17
+ }
18
+ }
19
+ export function createStreamMetadata(values) {
20
+ try {
21
+ const canonical = canonicalStreamMetadataJSONV2Internal(values);
22
+ return StreamMetadata.fromCanonicalValues(deepFreeze(JSON.parse(canonical)));
23
+ }
24
+ catch {
25
+ throw new StreamMetadataError();
26
+ }
27
+ }
28
+ /** @internal */
29
+ export function streamMetadataValues(metadata) {
30
+ if (!(metadata instanceof StreamMetadata))
31
+ throw new StreamMetadataError();
32
+ return metadata.values;
33
+ }
34
+ function deepFreeze(value) {
35
+ if (typeof value !== "object" || value === null || Object.isFrozen(value))
36
+ return value;
37
+ for (const child of Object.values(value))
38
+ deepFreeze(child);
39
+ return Object.freeze(value);
40
+ }
@@ -1,4 +1,4 @@
1
- import type { RpcError } from "../gen/flowersec/rpc/v1.gen.js";
1
+ import type { RpcError } from "./wire.js";
2
2
  export type RpcCaller = {
3
3
  call(typeId: number, payload: unknown, signal?: AbortSignal): Promise<{
4
4
  payload: unknown;
@@ -1,5 +1,4 @@
1
- import type { RpcError } from "../gen/flowersec/rpc/v1.gen.js";
2
- import { type ClientObserverLike } from "../observability/observer.js";
1
+ import type { RpcError } from "./wire.js";
3
2
  export declare class RpcClient {
4
3
  private readonly readExactly;
5
4
  private readonly write;
@@ -7,10 +6,8 @@ export declare class RpcClient {
7
6
  private readonly pending;
8
7
  private readonly notifyHandlers;
9
8
  private closed;
10
- private readonly observer;
11
9
  private readonly onTerminal;
12
10
  constructor(readExactly: (n: number) => Promise<Uint8Array>, write: (b: Uint8Array) => Promise<void>, opts?: Readonly<{
13
- observer?: ClientObserverLike;
14
11
  onTerminal?: (error: Error) => void;
15
12
  }>);
16
13
  call(typeId: number, payload: unknown, signal?: AbortSignal): Promise<{
@@ -1,4 +1,3 @@
1
- import { normalizeObserver, nowSeconds } from "../observability/observer.js";
2
1
  import { DEFAULT_MAX_JSON_FRAME_BYTES, readJsonFrame, writeJsonFrame } from "../framing/jsonframe.js";
3
2
  import { assertRpcEnvelope } from "./validate.js";
4
3
  // Guard against precision loss when encoding request IDs as numbers.
@@ -15,13 +14,10 @@ export class RpcClient {
15
14
  notifyHandlers = new Map();
16
15
  // Closed state to stop the read loop and reject calls.
17
16
  closed = false;
18
- // Observer for RPC events.
19
- observer;
20
17
  onTerminal;
21
18
  constructor(readExactly, write, opts = {}) {
22
19
  this.readExactly = readExactly;
23
20
  this.write = write;
24
- this.observer = normalizeObserver(opts.observer);
25
21
  this.onTerminal = opts.onTerminal;
26
22
  void this.readLoop();
27
23
  }
@@ -31,10 +27,6 @@ export class RpcClient {
31
27
  throw new Error("rpc client closed");
32
28
  if (this.nextId > MAX_SAFE_REQUEST_ID)
33
29
  throw new Error("request id overflow");
34
- const start = nowSeconds();
35
- const record = (result) => {
36
- this.observer.onRpcCall(result, nowSeconds() - start);
37
- };
38
30
  const requestId = this.nextId;
39
31
  this.nextId += 1n;
40
32
  const env = {
@@ -51,12 +43,10 @@ export class RpcClient {
51
43
  }
52
44
  catch (e) {
53
45
  this.pending.delete(requestId);
54
- record("transport_error");
55
46
  throw e;
56
47
  }
57
48
  if (signal?.aborted) {
58
49
  this.pending.delete(requestId);
59
- record("canceled");
60
50
  throw signal.reason ?? new Error("aborted");
61
51
  }
62
52
  let resp;
@@ -65,11 +55,8 @@ export class RpcClient {
65
55
  }
66
56
  catch (e) {
67
57
  this.pending.delete(requestId);
68
- record(signal?.aborted ? "canceled" : "transport_error");
69
58
  throw e;
70
59
  }
71
- const result = rpcResultFromError(resp.error);
72
- record(result);
73
60
  if (resp.error == null)
74
61
  return { payload: resp.payload };
75
62
  return { payload: resp.payload, error: resp.error };
@@ -114,7 +101,6 @@ export class RpcClient {
114
101
  if (v.response_to === 0) {
115
102
  // Notification: response_to=0 and request_id=0.
116
103
  if (v.request_id === 0) {
117
- this.observer.onRpcNotify();
118
104
  const set = this.notifyHandlers.get(v.type_id >>> 0);
119
105
  if (set != null) {
120
106
  for (const h of set) {
@@ -172,10 +158,3 @@ async function raceAbort(p, signal) {
172
158
  });
173
159
  });
174
160
  }
175
- function rpcResultFromError(err) {
176
- if (err == null)
177
- return "ok";
178
- if (err.code === 404)
179
- return "handler_not_found";
180
- return "rpc_error";
181
- }
@@ -10,7 +10,7 @@ export declare class RpcProxy {
10
10
  onNotify(typeId: number, handler: (payload: unknown) => void): () => void;
11
11
  call(typeId: number, payload: unknown, signal?: AbortSignal): Promise<{
12
12
  payload: unknown;
13
- error?: import("../gen/flowersec/rpc/v1.gen.js").RpcError;
13
+ error?: import("./wire.js").RpcError;
14
14
  }>;
15
15
  notify(typeId: number, payload: unknown): Promise<void>;
16
16
  }
@@ -1,4 +1,4 @@
1
- import type { RpcError } from "../gen/flowersec/rpc/v1.gen.js";
1
+ import type { RpcError } from "./wire.js";
2
2
  export type RpcHandler = (payload: unknown) => Promise<{
3
3
  payload: unknown;
4
4
  error?: RpcError;
@@ -1,2 +1,2 @@
1
- import type { RpcEnvelope } from "../gen/flowersec/rpc/v1.gen.js";
1
+ import type { RpcEnvelope } from "./wire.js";
2
2
  export declare function assertRpcEnvelope(v: unknown): RpcEnvelope;
@@ -0,0 +1,15 @@
1
+ export interface RpcEnvelope {
2
+ type_id: number;
3
+ request_id: number;
4
+ response_to: number;
5
+ payload: unknown;
6
+ error?: RpcError;
7
+ }
8
+ export interface RpcError {
9
+ code: number;
10
+ message?: string;
11
+ }
12
+ export interface StreamHello {
13
+ kind: string;
14
+ v: number;
15
+ }
@@ -0,0 +1,6 @@
1
+ export type RuntimeErrorCode = "runtime_unsupported" | "runtime_start_failed" | "runtime_crashed";
2
+ export declare class RuntimeError extends Error {
3
+ readonly code: RuntimeErrorCode;
4
+ readonly cause?: unknown | undefined;
5
+ constructor(code: RuntimeErrorCode, message: string, cause?: unknown | undefined);
6
+ }
@@ -0,0 +1,10 @@
1
+ export class RuntimeError extends Error {
2
+ code;
3
+ cause;
4
+ constructor(code, message, cause) {
5
+ super(message);
6
+ this.code = code;
7
+ this.cause = cause;
8
+ this.name = "RuntimeError";
9
+ }
10
+ }
@@ -0,0 +1,24 @@
1
+ import { type CarrierSessionV2 } from "../v2/carrier.js";
2
+ import type { OperationOptionsV2, PathKind } from "../v2/contract.js";
3
+ export type WebSocketBinaryTransportV2 = Readonly<{
4
+ readBinary(options?: Readonly<{
5
+ signal?: AbortSignal;
6
+ timeoutMs?: number;
7
+ }>): Promise<Uint8Array>;
8
+ writeBinary(data: Uint8Array, options?: OperationOptionsV2): Promise<void>;
9
+ close(): void;
10
+ }>;
11
+ export type WebSocketResourcePolicyV2 = Readonly<{
12
+ maxConcurrentStreams?: number;
13
+ maxFrameBytes?: number;
14
+ preferredWriteBytes?: number;
15
+ maxStreamWriteQueueBytes?: number;
16
+ maxStreamReceiveBytes?: number;
17
+ maxSessionReceiveBytes?: number;
18
+ }>;
19
+ export declare function createWebSocketCarrierSessionV2(transport: WebSocketBinaryTransportV2, options: Readonly<{
20
+ path: PathKind;
21
+ client: boolean;
22
+ inboundBidirectionalStreamCapacity: number;
23
+ resourcePolicy?: WebSocketResourcePolicyV2;
24
+ }>): CarrierSessionV2;
@@ -0,0 +1,234 @@
1
+ import { YamuxSession } from "../yamux/session.js";
2
+ import { CarrierError } from "../v2/carrier.js";
3
+ export function createWebSocketCarrierSessionV2(transport, options) {
4
+ return new WebSocketYamuxCarrierSession(transport, options);
5
+ }
6
+ class WebSocketYamuxCarrierSession {
7
+ kind = "websocket";
8
+ path;
9
+ inboundBidirectionalStreamCapacity;
10
+ unreliableDatagrams = undefined;
11
+ incoming = new IncomingStreamQueue();
12
+ yamux;
13
+ termination = deferred();
14
+ terminalError;
15
+ closed = false;
16
+ constructor(transport, options) {
17
+ requireCapacity(options.inboundBidirectionalStreamCapacity);
18
+ this.path = options.path;
19
+ this.inboundBidirectionalStreamCapacity = options.inboundBidirectionalStreamCapacity;
20
+ const duplex = {
21
+ read: async () => await transport.readBinary(),
22
+ write: async (chunk) => await transport.writeBinary(chunk),
23
+ close: () => transport.close(),
24
+ };
25
+ const policy = options.resourcePolicy ?? {};
26
+ this.yamux = new YamuxSession(duplex, {
27
+ client: options.client,
28
+ limits: {
29
+ maxActiveStreams: Math.max(policy.maxConcurrentStreams ?? this.inboundBidirectionalStreamCapacity, this.inboundBidirectionalStreamCapacity),
30
+ maxInboundStreams: this.inboundBidirectionalStreamCapacity,
31
+ ...(policy.maxFrameBytes === undefined ? {} : { maxFrameBytes: policy.maxFrameBytes }),
32
+ ...(policy.preferredWriteBytes === undefined ? {} : { preferredOutboundFrameBytes: policy.preferredWriteBytes }),
33
+ ...(policy.maxStreamWriteQueueBytes === undefined ? {} : { maxStreamWriteQueueBytes: policy.maxStreamWriteQueueBytes }),
34
+ ...(policy.maxStreamReceiveBytes === undefined ? {} : { maxStreamReceiveBytes: policy.maxStreamReceiveBytes }),
35
+ ...(policy.maxSessionReceiveBytes === undefined ? {} : { maxSessionReceiveBytes: policy.maxSessionReceiveBytes }),
36
+ },
37
+ onIncomingStream: (stream) => this.incoming.push(new YamuxCarrierStreamAdapter(stream)),
38
+ onTerminal: (error) => {
39
+ const failure = error instanceof CarrierError
40
+ ? error
41
+ : new CarrierError("closed", "WebSocket carrier terminated", error);
42
+ this.closed = true;
43
+ this.terminalError = failure;
44
+ this.incoming.fail(failure);
45
+ this.termination.resolve();
46
+ },
47
+ });
48
+ }
49
+ async openStream(options = {}) {
50
+ this.assertOpen();
51
+ try {
52
+ return new YamuxCarrierStreamAdapter(await this.yamux.openStream(options));
53
+ }
54
+ catch (error) {
55
+ throw error instanceof CarrierError ? error : new CarrierError("closed", "WebSocket stream open failed", error);
56
+ }
57
+ }
58
+ async acceptStream(options = {}) {
59
+ this.assertOpen();
60
+ return await this.incoming.shift(options.signal);
61
+ }
62
+ async close() {
63
+ this.closeLocally();
64
+ }
65
+ abort() {
66
+ this.closeLocally();
67
+ }
68
+ async waitTermination() {
69
+ await this.termination.promise;
70
+ if (this.terminalError !== undefined)
71
+ throw this.terminalError;
72
+ }
73
+ assertOpen() {
74
+ if (this.terminalError !== undefined)
75
+ throw this.terminalError;
76
+ if (this.closed)
77
+ throw new CarrierError("closed", "WebSocket carrier is closed");
78
+ }
79
+ closeLocally() {
80
+ if (this.closed)
81
+ return;
82
+ this.closed = true;
83
+ const failure = new CarrierError("closed", "WebSocket carrier is closed");
84
+ this.incoming.fail(failure);
85
+ this.yamux.close();
86
+ this.termination.resolve();
87
+ }
88
+ }
89
+ class YamuxCarrierStreamAdapter {
90
+ stream;
91
+ constructor(stream) {
92
+ this.stream = stream;
93
+ }
94
+ async read(options = {}) {
95
+ try {
96
+ return await abortable(this.stream.read(), options.signal, () => this.stream.abort());
97
+ }
98
+ catch (error) {
99
+ throw error instanceof CarrierError ? error : new CarrierError("reset", "WebSocket stream read failed", error);
100
+ }
101
+ }
102
+ async write(data, options = {}) {
103
+ throwIfAborted(options.signal);
104
+ try {
105
+ await abortable(this.stream.write(data), options.signal, () => this.stream.abort());
106
+ }
107
+ catch (error) {
108
+ throw error instanceof CarrierError ? error : new CarrierError("reset", "WebSocket stream write failed", error);
109
+ }
110
+ return data.length;
111
+ }
112
+ async closeWrite() {
113
+ await this.stream.close();
114
+ }
115
+ async reset() {
116
+ await this.stream.reset();
117
+ }
118
+ async stopSending() {
119
+ throw new CarrierError("stop_sending_unavailable", "WebSocket/Yamux cannot stop only the receive side of a bidirectional stream");
120
+ }
121
+ abort(error) {
122
+ this.stream.abort(error);
123
+ }
124
+ }
125
+ class IncomingStreamQueue {
126
+ values = [];
127
+ waiters = new Set();
128
+ terminalError;
129
+ push(value) {
130
+ if (this.terminalError !== undefined) {
131
+ value.abort(this.terminalError);
132
+ return;
133
+ }
134
+ const waiter = this.waiters.values().next().value;
135
+ if (waiter === undefined)
136
+ this.values.push(value);
137
+ else {
138
+ this.waiters.delete(waiter);
139
+ waiter.deliver(value);
140
+ }
141
+ }
142
+ shift(signal) {
143
+ throwIfAborted(signal);
144
+ if (this.terminalError !== undefined)
145
+ return Promise.reject(this.terminalError);
146
+ const value = this.values.shift();
147
+ if (value !== undefined)
148
+ return Promise.resolve(value);
149
+ return new Promise((resolve, reject) => {
150
+ let settled = false;
151
+ const cleanup = () => {
152
+ this.waiters.delete(waiter);
153
+ signal?.removeEventListener("abort", abort);
154
+ };
155
+ const waiter = {
156
+ deliver: (stream) => {
157
+ if (settled)
158
+ return;
159
+ settled = true;
160
+ cleanup();
161
+ resolve(stream);
162
+ },
163
+ fail: (error) => {
164
+ if (settled)
165
+ return;
166
+ settled = true;
167
+ cleanup();
168
+ reject(error);
169
+ },
170
+ };
171
+ const abort = () => waiter.fail(new CarrierError("aborted", "carrier operation aborted"));
172
+ this.waiters.add(waiter);
173
+ signal?.addEventListener("abort", abort, { once: true });
174
+ if (signal?.aborted === true)
175
+ abort();
176
+ });
177
+ }
178
+ fail(error) {
179
+ if (this.terminalError !== undefined)
180
+ return;
181
+ this.terminalError = error;
182
+ for (const stream of this.values)
183
+ stream.abort(error);
184
+ this.values.length = 0;
185
+ for (const waiter of this.waiters)
186
+ waiter.fail(error);
187
+ this.waiters.clear();
188
+ }
189
+ }
190
+ function deferred() {
191
+ let resolve;
192
+ const promise = new Promise((resolvePromise) => { resolve = resolvePromise; });
193
+ return { promise, resolve };
194
+ }
195
+ function requireCapacity(value) {
196
+ if (!Number.isInteger(value) || value < 3 || value > 130) {
197
+ throw new RangeError("inboundBidirectionalStreamCapacity must be an integer from 3 to 130");
198
+ }
199
+ }
200
+ function throwIfAborted(signal) {
201
+ if (signal?.aborted === true)
202
+ throw new CarrierError("aborted", "carrier operation aborted");
203
+ }
204
+ async function abortable(promise, signal, onAbort) {
205
+ if (signal === undefined)
206
+ return await promise;
207
+ throwIfAborted(signal);
208
+ return await new Promise((resolve, reject) => {
209
+ let settled = false;
210
+ const cleanup = () => signal.removeEventListener("abort", abort);
211
+ const abort = () => {
212
+ if (settled)
213
+ return;
214
+ settled = true;
215
+ cleanup();
216
+ onAbort();
217
+ reject(new CarrierError("aborted", "carrier operation aborted"));
218
+ };
219
+ signal.addEventListener("abort", abort, { once: true });
220
+ void promise.then((value) => {
221
+ if (settled)
222
+ return;
223
+ settled = true;
224
+ cleanup();
225
+ resolve(value);
226
+ }, (error) => {
227
+ if (settled)
228
+ return;
229
+ settled = true;
230
+ cleanup();
231
+ reject(error);
232
+ });
233
+ });
234
+ }
@@ -0,0 +1,27 @@
1
+ import { type NativeCarrierSessionV2 } from "../v2/carrier.js";
2
+ import type { PathKind } from "../v2/contract.js";
3
+ export type WebTransportBidirectionalLikeV2 = Readonly<{
4
+ readable: ReadableStream<Uint8Array>;
5
+ writable: WritableStream<Uint8Array>;
6
+ }>;
7
+ export type WebTransportDatagramsLikeV2 = Readonly<{
8
+ readable: ReadableStream<Uint8Array>;
9
+ writable: WritableStream<Uint8Array>;
10
+ maxDatagramSize?: number;
11
+ }>;
12
+ export type WebTransportSessionLikeV2 = Readonly<{
13
+ closed: Promise<unknown>;
14
+ incomingBidirectionalStreams: ReadableStream<WebTransportBidirectionalLikeV2>;
15
+ datagrams: WebTransportDatagramsLikeV2;
16
+ createBidirectionalStream(): Promise<WebTransportBidirectionalLikeV2>;
17
+ close(info?: Readonly<{
18
+ closeCode: number;
19
+ reason: string;
20
+ }>): void;
21
+ }>;
22
+ export declare function adaptWebTransportCarrierSessionV2(native: WebTransportSessionLikeV2, options: Readonly<{
23
+ path: PathKind;
24
+ inboundBidirectionalStreamCapacity: number;
25
+ datagramMaxSize?: number;
26
+ }>): NativeCarrierSessionV2;
27
+ export declare function hasWebTransportConstructorSurfaceV2(value: unknown): boolean;