@meshline/sdk 0.0.0-stage → 0.1.0-alpha.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 (338) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +43 -2
  3. package/dist/channels/repository.d.ts +73 -0
  4. package/dist/channels/repository.d.ts.map +1 -0
  5. package/dist/channels/repository.js +367 -0
  6. package/dist/channels/repository.js.map +1 -0
  7. package/dist/client/account-operations.d.ts +41 -0
  8. package/dist/client/account-operations.d.ts.map +1 -0
  9. package/dist/client/account-operations.js +304 -0
  10. package/dist/client/account-operations.js.map +1 -0
  11. package/dist/client/conversations.d.ts +36 -0
  12. package/dist/client/conversations.d.ts.map +1 -0
  13. package/dist/client/conversations.js +144 -0
  14. package/dist/client/conversations.js.map +1 -0
  15. package/dist/client.d.ts +53 -0
  16. package/dist/client.d.ts.map +1 -0
  17. package/dist/client.js +162 -0
  18. package/dist/client.js.map +1 -0
  19. package/dist/components/account.d.ts +38 -0
  20. package/dist/components/account.d.ts.map +1 -0
  21. package/dist/components/account.js +243 -0
  22. package/dist/components/account.js.map +1 -0
  23. package/dist/components/channel.d.ts +78 -0
  24. package/dist/components/channel.d.ts.map +1 -0
  25. package/dist/components/channel.js +475 -0
  26. package/dist/components/channel.js.map +1 -0
  27. package/dist/components/component.d.ts +49 -0
  28. package/dist/components/component.d.ts.map +1 -0
  29. package/dist/components/component.js +194 -0
  30. package/dist/components/component.js.map +1 -0
  31. package/dist/components/device.d.ts +60 -0
  32. package/dist/components/device.d.ts.map +1 -0
  33. package/dist/components/device.js +648 -0
  34. package/dist/components/device.js.map +1 -0
  35. package/dist/components/group.d.ts +141 -0
  36. package/dist/components/group.d.ts.map +1 -0
  37. package/dist/components/group.js +933 -0
  38. package/dist/components/group.js.map +1 -0
  39. package/dist/components/message.d.ts +63 -0
  40. package/dist/components/message.d.ts.map +1 -0
  41. package/dist/components/message.js +439 -0
  42. package/dist/components/message.js.map +1 -0
  43. package/dist/components/profile.d.ts +37 -0
  44. package/dist/components/profile.d.ts.map +1 -0
  45. package/dist/components/profile.js +232 -0
  46. package/dist/components/profile.js.map +1 -0
  47. package/dist/crypto/groups.d.ts +56 -0
  48. package/dist/crypto/groups.d.ts.map +1 -0
  49. package/dist/crypto/groups.js +163 -0
  50. package/dist/crypto/groups.js.map +1 -0
  51. package/dist/crypto/messages.d.ts +52 -0
  52. package/dist/crypto/messages.d.ts.map +1 -0
  53. package/dist/crypto/messages.js +180 -0
  54. package/dist/crypto/messages.js.map +1 -0
  55. package/dist/crypto/primitives.d.ts +30 -0
  56. package/dist/crypto/primitives.d.ts.map +1 -0
  57. package/dist/crypto/primitives.js +102 -0
  58. package/dist/crypto/primitives.js.map +1 -0
  59. package/dist/errors.d.ts +11 -0
  60. package/dist/errors.d.ts.map +1 -0
  61. package/dist/errors.js +14 -0
  62. package/dist/errors.js.map +1 -0
  63. package/dist/groups/account-sync.d.ts +28 -0
  64. package/dist/groups/account-sync.d.ts.map +1 -0
  65. package/dist/groups/account-sync.js +235 -0
  66. package/dist/groups/account-sync.js.map +1 -0
  67. package/dist/groups/messages.d.ts +39 -0
  68. package/dist/groups/messages.d.ts.map +1 -0
  69. package/dist/groups/messages.js +141 -0
  70. package/dist/groups/messages.js.map +1 -0
  71. package/dist/groups/operations.d.ts +57 -0
  72. package/dist/groups/operations.d.ts.map +1 -0
  73. package/dist/groups/operations.js +225 -0
  74. package/dist/groups/operations.js.map +1 -0
  75. package/dist/groups/repository.d.ts +56 -0
  76. package/dist/groups/repository.d.ts.map +1 -0
  77. package/dist/groups/repository.js +254 -0
  78. package/dist/groups/repository.js.map +1 -0
  79. package/dist/groups/secrets.d.ts +67 -0
  80. package/dist/groups/secrets.d.ts.map +1 -0
  81. package/dist/groups/secrets.js +452 -0
  82. package/dist/groups/secrets.js.map +1 -0
  83. package/dist/groups/state.d.ts +39 -0
  84. package/dist/groups/state.d.ts.map +1 -0
  85. package/dist/groups/state.js +201 -0
  86. package/dist/groups/state.js.map +1 -0
  87. package/dist/identity/identifiers.d.ts +9 -0
  88. package/dist/identity/identifiers.d.ts.map +1 -0
  89. package/dist/identity/identifiers.js +37 -0
  90. package/dist/identity/identifiers.js.map +1 -0
  91. package/dist/identity/neo.d.ts +11 -0
  92. package/dist/identity/neo.d.ts.map +1 -0
  93. package/dist/identity/neo.js +77 -0
  94. package/dist/identity/neo.js.map +1 -0
  95. package/dist/index.d.ts +53 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +46 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/interactions.d.ts +31 -0
  100. package/dist/interactions.d.ts.map +1 -0
  101. package/dist/interactions.js +2 -0
  102. package/dist/interactions.js.map +1 -0
  103. package/dist/messages/account-sender.d.ts +9 -0
  104. package/dist/messages/account-sender.d.ts.map +1 -0
  105. package/dist/messages/account-sender.js +46 -0
  106. package/dist/messages/account-sender.js.map +1 -0
  107. package/dist/messages/contacts.d.ts +103 -0
  108. package/dist/messages/contacts.d.ts.map +1 -0
  109. package/dist/messages/contacts.js +525 -0
  110. package/dist/messages/contacts.js.map +1 -0
  111. package/dist/messages/outbox.d.ts +66 -0
  112. package/dist/messages/outbox.d.ts.map +1 -0
  113. package/dist/messages/outbox.js +167 -0
  114. package/dist/messages/outbox.js.map +1 -0
  115. package/dist/messages/receiver.d.ts +35 -0
  116. package/dist/messages/receiver.d.ts.map +1 -0
  117. package/dist/messages/receiver.js +113 -0
  118. package/dist/messages/receiver.js.map +1 -0
  119. package/dist/messages/repository.d.ts +89 -0
  120. package/dist/messages/repository.d.ts.map +1 -0
  121. package/dist/messages/repository.js +295 -0
  122. package/dist/messages/repository.js.map +1 -0
  123. package/dist/models/authentication.d.ts +37 -0
  124. package/dist/models/authentication.d.ts.map +1 -0
  125. package/dist/models/authentication.js +53 -0
  126. package/dist/models/authentication.js.map +1 -0
  127. package/dist/models/channels.d.ts +141 -0
  128. package/dist/models/channels.d.ts.map +1 -0
  129. package/dist/models/channels.js +258 -0
  130. package/dist/models/channels.js.map +1 -0
  131. package/dist/models/contacts.d.ts +68 -0
  132. package/dist/models/contacts.d.ts.map +1 -0
  133. package/dist/models/contacts.js +186 -0
  134. package/dist/models/contacts.js.map +1 -0
  135. package/dist/models/content.d.ts +37 -0
  136. package/dist/models/content.d.ts.map +1 -0
  137. package/dist/models/content.js +137 -0
  138. package/dist/models/content.js.map +1 -0
  139. package/dist/models/device-state.d.ts +8 -0
  140. package/dist/models/device-state.d.ts.map +1 -0
  141. package/dist/models/device-state.js +22 -0
  142. package/dist/models/device-state.js.map +1 -0
  143. package/dist/models/group-admission.d.ts +111 -0
  144. package/dist/models/group-admission.d.ts.map +1 -0
  145. package/dist/models/group-admission.js +153 -0
  146. package/dist/models/group-admission.js.map +1 -0
  147. package/dist/models/group-keys.d.ts +30 -0
  148. package/dist/models/group-keys.d.ts.map +1 -0
  149. package/dist/models/group-keys.js +52 -0
  150. package/dist/models/group-keys.js.map +1 -0
  151. package/dist/models/group-management.d.ts +190 -0
  152. package/dist/models/group-management.d.ts.map +1 -0
  153. package/dist/models/group-management.js +263 -0
  154. package/dist/models/group-management.js.map +1 -0
  155. package/dist/models/groups.d.ts +81 -0
  156. package/dist/models/groups.d.ts.map +1 -0
  157. package/dist/models/groups.js +127 -0
  158. package/dist/models/groups.js.map +1 -0
  159. package/dist/models/identity.d.ts +47 -0
  160. package/dist/models/identity.d.ts.map +1 -0
  161. package/dist/models/identity.js +136 -0
  162. package/dist/models/identity.js.map +1 -0
  163. package/dist/models/messages.d.ts +104 -0
  164. package/dist/models/messages.d.ts.map +1 -0
  165. package/dist/models/messages.js +168 -0
  166. package/dist/models/messages.js.map +1 -0
  167. package/dist/models/profile.d.ts +24 -0
  168. package/dist/models/profile.d.ts.map +1 -0
  169. package/dist/models/profile.js +47 -0
  170. package/dist/models/profile.js.map +1 -0
  171. package/dist/models/relay.d.ts +39 -0
  172. package/dist/models/relay.d.ts.map +1 -0
  173. package/dist/models/relay.js +160 -0
  174. package/dist/models/relay.js.map +1 -0
  175. package/dist/protocol/codec.d.ts +36 -0
  176. package/dist/protocol/codec.d.ts.map +1 -0
  177. package/dist/protocol/codec.js +144 -0
  178. package/dist/protocol/codec.js.map +1 -0
  179. package/dist/protocol/context.d.ts +14 -0
  180. package/dist/protocol/context.d.ts.map +1 -0
  181. package/dist/protocol/context.js +43 -0
  182. package/dist/protocol/context.js.map +1 -0
  183. package/dist/protocol/encoding.d.ts +15 -0
  184. package/dist/protocol/encoding.d.ts.map +1 -0
  185. package/dist/protocol/encoding.js +133 -0
  186. package/dist/protocol/encoding.js.map +1 -0
  187. package/dist/protocol/json.d.ts +16 -0
  188. package/dist/protocol/json.d.ts.map +1 -0
  189. package/dist/protocol/json.js +172 -0
  190. package/dist/protocol/json.js.map +1 -0
  191. package/dist/protocol/validation.d.ts +4 -0
  192. package/dist/protocol/validation.d.ts.map +1 -0
  193. package/dist/protocol/validation.js +18 -0
  194. package/dist/protocol/validation.js.map +1 -0
  195. package/dist/runtime/abort.d.ts +6 -0
  196. package/dist/runtime/abort.d.ts.map +1 -0
  197. package/dist/runtime/abort.js +32 -0
  198. package/dist/runtime/abort.js.map +1 -0
  199. package/dist/runtime/async-gate.d.ts +6 -0
  200. package/dist/runtime/async-gate.d.ts.map +1 -0
  201. package/dist/runtime/async-gate.js +15 -0
  202. package/dist/runtime/async-gate.js.map +1 -0
  203. package/dist/runtime/async-pulse.d.ts +7 -0
  204. package/dist/runtime/async-pulse.d.ts.map +1 -0
  205. package/dist/runtime/async-pulse.js +23 -0
  206. package/dist/runtime/async-pulse.js.map +1 -0
  207. package/dist/runtime/clock.d.ts +16 -0
  208. package/dist/runtime/clock.d.ts.map +1 -0
  209. package/dist/runtime/clock.js +62 -0
  210. package/dist/runtime/clock.js.map +1 -0
  211. package/dist/runtime/events.d.ts +11 -0
  212. package/dist/runtime/events.d.ts.map +1 -0
  213. package/dist/runtime/events.js +45 -0
  214. package/dist/runtime/events.js.map +1 -0
  215. package/dist/runtime/url.d.ts +3 -0
  216. package/dist/runtime/url.d.ts.map +1 -0
  217. package/dist/runtime/url.js +23 -0
  218. package/dist/runtime/url.js.map +1 -0
  219. package/dist/storage/signed-request.d.ts +14 -0
  220. package/dist/storage/signed-request.d.ts.map +1 -0
  221. package/dist/storage/signed-request.js +26 -0
  222. package/dist/storage/signed-request.js.map +1 -0
  223. package/dist/storage/store.d.ts +58 -0
  224. package/dist/storage/store.d.ts.map +1 -0
  225. package/dist/storage/store.js +52 -0
  226. package/dist/storage/store.js.map +1 -0
  227. package/dist/storage/transaction.d.ts +7 -0
  228. package/dist/storage/transaction.d.ts.map +1 -0
  229. package/dist/storage/transaction.js +22 -0
  230. package/dist/storage/transaction.js.map +1 -0
  231. package/dist/transport/client.d.ts +61 -0
  232. package/dist/transport/client.d.ts.map +1 -0
  233. package/dist/transport/client.js +392 -0
  234. package/dist/transport/client.js.map +1 -0
  235. package/dist/transport/discovery.d.ts +19 -0
  236. package/dist/transport/discovery.d.ts.map +1 -0
  237. package/dist/transport/discovery.js +75 -0
  238. package/dist/transport/discovery.js.map +1 -0
  239. package/dist/transport/endpoint.d.ts +6 -0
  240. package/dist/transport/endpoint.d.ts.map +1 -0
  241. package/dist/transport/endpoint.js +35 -0
  242. package/dist/transport/endpoint.js.map +1 -0
  243. package/dist/transport/http.d.ts +52 -0
  244. package/dist/transport/http.d.ts.map +1 -0
  245. package/dist/transport/http.js +128 -0
  246. package/dist/transport/http.js.map +1 -0
  247. package/dist/transport/pool.d.ts +31 -0
  248. package/dist/transport/pool.d.ts.map +1 -0
  249. package/dist/transport/pool.js +137 -0
  250. package/dist/transport/pool.js.map +1 -0
  251. package/dist/transport/relay-error.d.ts +23 -0
  252. package/dist/transport/relay-error.d.ts.map +1 -0
  253. package/dist/transport/relay-error.js +47 -0
  254. package/dist/transport/relay-error.js.map +1 -0
  255. package/dist/transport/rpc.d.ts +31 -0
  256. package/dist/transport/rpc.d.ts.map +1 -0
  257. package/dist/transport/rpc.js +56 -0
  258. package/dist/transport/rpc.js.map +1 -0
  259. package/dist/transport/session.d.ts +49 -0
  260. package/dist/transport/session.d.ts.map +1 -0
  261. package/dist/transport/session.js +169 -0
  262. package/dist/transport/session.js.map +1 -0
  263. package/dist/transport/socket.d.ts +55 -0
  264. package/dist/transport/socket.d.ts.map +1 -0
  265. package/dist/transport/socket.js +266 -0
  266. package/dist/transport/socket.js.map +1 -0
  267. package/dist/transport/subscription.d.ts +36 -0
  268. package/dist/transport/subscription.d.ts.map +1 -0
  269. package/dist/transport/subscription.js +169 -0
  270. package/dist/transport/subscription.js.map +1 -0
  271. package/package.json +35 -4
  272. package/src/channels/repository.ts +244 -0
  273. package/src/client/account-operations.ts +183 -0
  274. package/src/client/conversations.ts +95 -0
  275. package/src/client.ts +108 -0
  276. package/src/components/account.ts +206 -0
  277. package/src/components/channel.ts +253 -0
  278. package/src/components/component.ts +151 -0
  279. package/src/components/device.ts +455 -0
  280. package/src/components/group.ts +546 -0
  281. package/src/components/message.ts +253 -0
  282. package/src/components/profile.ts +179 -0
  283. package/src/crypto/groups.ts +107 -0
  284. package/src/crypto/messages.ts +129 -0
  285. package/src/crypto/primitives.ts +103 -0
  286. package/src/errors.ts +13 -0
  287. package/src/groups/account-sync.ts +144 -0
  288. package/src/groups/messages.ts +89 -0
  289. package/src/groups/operations.ts +145 -0
  290. package/src/groups/repository.ts +161 -0
  291. package/src/groups/secrets.ts +256 -0
  292. package/src/groups/state.ts +138 -0
  293. package/src/identity/identifiers.ts +41 -0
  294. package/src/identity/neo.ts +72 -0
  295. package/src/index.ts +52 -0
  296. package/src/interactions.ts +35 -0
  297. package/src/messages/account-sender.ts +33 -0
  298. package/src/messages/contacts.ts +379 -0
  299. package/src/messages/outbox.ts +152 -0
  300. package/src/messages/receiver.ts +86 -0
  301. package/src/messages/repository.ts +230 -0
  302. package/src/models/authentication.ts +63 -0
  303. package/src/models/channels.ts +155 -0
  304. package/src/models/contacts.ts +141 -0
  305. package/src/models/content.ts +105 -0
  306. package/src/models/device-state.ts +18 -0
  307. package/src/models/group-admission.ts +110 -0
  308. package/src/models/group-keys.ts +34 -0
  309. package/src/models/group-management.ts +182 -0
  310. package/src/models/groups.ts +100 -0
  311. package/src/models/identity.ts +164 -0
  312. package/src/models/messages.ts +139 -0
  313. package/src/models/profile.ts +46 -0
  314. package/src/models/relay.ts +151 -0
  315. package/src/protocol/codec.ts +144 -0
  316. package/src/protocol/context.ts +39 -0
  317. package/src/protocol/encoding.ts +106 -0
  318. package/src/protocol/json.ts +140 -0
  319. package/src/protocol/validation.ts +13 -0
  320. package/src/runtime/abort.ts +27 -0
  321. package/src/runtime/async-gate.ts +16 -0
  322. package/src/runtime/async-pulse.ts +20 -0
  323. package/src/runtime/clock.ts +63 -0
  324. package/src/runtime/events.ts +31 -0
  325. package/src/runtime/url.ts +17 -0
  326. package/src/storage/signed-request.ts +26 -0
  327. package/src/storage/store.ts +90 -0
  328. package/src/storage/transaction.ts +17 -0
  329. package/src/transport/client.ts +328 -0
  330. package/src/transport/discovery.ts +64 -0
  331. package/src/transport/endpoint.ts +32 -0
  332. package/src/transport/http.ts +129 -0
  333. package/src/transport/pool.ts +115 -0
  334. package/src/transport/relay-error.ts +46 -0
  335. package/src/transport/rpc.ts +56 -0
  336. package/src/transport/session.ts +154 -0
  337. package/src/transport/socket.ts +248 -0
  338. package/src/transport/subscription.ts +117 -0
@@ -0,0 +1,169 @@
1
+ import { createAbortController } from '../runtime/abort.js';
2
+ import { verifyAccount, verifyDevice } from '../crypto/primitives.js';
3
+ import { ProtocolError } from '../errors.js';
4
+ import { matchesAccount, validateRelayId } from '../identity/neo.js';
5
+ import { accountAuthenticationCodec, accountAuthenticationInput, authenticationChallengeCodec, deviceAuthenticationCodec, deviceAuthenticationInput, sessionCredentialsCodec, validateChallenge, validateSession, } from '../models/authentication.js';
6
+ import { certificateId, deviceCertificateCodec, validateCertificate } from '../models/identity.js';
7
+ import { NetworkContext } from '../protocol/context.js';
8
+ import { equalBytes } from '../protocol/encoding.js';
9
+ import { abortScope, awaitWithSignal, systemClock, throwIfAborted } from '../runtime/clock.js';
10
+ import { relayOrigin } from './endpoint.js';
11
+ /** Keeps bearer credentials out of ordinary object enumeration and diagnostic serialization. */
12
+ export class RelaySession {
13
+ origin;
14
+ #credentials;
15
+ #clock;
16
+ #started;
17
+ #lifetimeMilliseconds;
18
+ constructor(credentials, origin, challengeCreatedAt, started, clock) {
19
+ this.origin = origin;
20
+ this.#credentials = sessionCredentialsCodec.decode(sessionCredentialsCodec.encode(credentials));
21
+ this.#started = started;
22
+ this.#clock = clock;
23
+ this.#lifetimeMilliseconds = (credentials.expiresAt - challengeCreatedAt - 1) * 1000;
24
+ }
25
+ get mode() { return this.#credentials.mode; }
26
+ get lifetimeSeconds() { return this.#lifetimeMilliseconds / 1000; }
27
+ get remainingSeconds() { return (this.#lifetimeMilliseconds - (this.#clock.monotonicMilliseconds() - this.#started)) / 1000; }
28
+ /** Return only for sending a request to origin. Do not log or persist. */
29
+ getToken(endpoint) {
30
+ if (relayOrigin(endpoint) !== this.origin)
31
+ throw new ProtocolError('invalid_origin', 'A session cannot be sent to a different origin.');
32
+ if (this.remainingSeconds <= 0)
33
+ throw new ProtocolError('expired_session', 'The relay session has expired.');
34
+ return this.#credentials.token;
35
+ }
36
+ }
37
+ /** Captures immutable identity at binding time; certificate renewal for the same device is allowed. */
38
+ export class RelayAuthenticator {
39
+ relayId;
40
+ context;
41
+ clock;
42
+ #identity;
43
+ #publicKey;
44
+ accountId;
45
+ deviceId;
46
+ mode;
47
+ constructor(relayId, context, identity, clock = systemClock) {
48
+ this.relayId = relayId;
49
+ this.context = context;
50
+ this.clock = clock;
51
+ validateRelayId(relayId);
52
+ this.#identity = { ...identity };
53
+ this.mode = identity.mode;
54
+ if (identity.mode === 'account') {
55
+ this.accountId = identity.signer.accountId;
56
+ this.#publicKey = identity.signer.publicKey.slice();
57
+ if (!matchesAccount(this.accountId, this.#publicKey))
58
+ throw new ProtocolError('invalid_identity', 'The signer public key does not identify its account.');
59
+ }
60
+ else {
61
+ const certificate = identity.signer.certificate;
62
+ validateCertificate(certificate, context);
63
+ this.accountId = certificate.account;
64
+ this.deviceId = certificateId(certificate, context);
65
+ }
66
+ }
67
+ assertIdentity() {
68
+ const identity = this.#identity;
69
+ if (identity.mode === 'account') {
70
+ if (identity.signer.accountId !== this.accountId || !equalBytes(identity.signer.publicKey, this.#publicKey))
71
+ throw new ProtocolError('identity_changed', 'The account signer identity has changed.');
72
+ }
73
+ else {
74
+ const certificate = identity.signer.certificate;
75
+ if (certificate.account !== this.accountId || certificateId(certificate, this.context) !== this.deviceId)
76
+ throw new ProtocolError('identity_changed', 'The device signer identity has changed.');
77
+ }
78
+ }
79
+ async authenticate(endpoint, send, signal) {
80
+ throwIfAborted(signal);
81
+ this.assertIdentity();
82
+ const origin = relayOrigin(endpoint);
83
+ // Clone before awaits: a mutable application object must not change the signed proof in flight.
84
+ const identity = this.#identity;
85
+ const certificate = identity.mode === 'device' ? deviceCertificateCodec.decode(deviceCertificateCodec.encode(identity.signer.certificate)) : undefined;
86
+ if (certificate)
87
+ validateCertificate(certificate, this.context);
88
+ const started = this.clock.monotonicMilliseconds();
89
+ const challengeWire = await send('auth.challenge', { account: this.accountId }, signal);
90
+ if (challengeWire === undefined)
91
+ throw new ProtocolError('missing_result', 'Authentication challenge has no result.');
92
+ const challenge = authenticationChallengeCodec.decode(challengeWire);
93
+ validateChallenge(challenge);
94
+ this.assertIdentity();
95
+ let method;
96
+ let proof;
97
+ if (identity.mode === 'device') {
98
+ const request = { nonce: challenge.nonce, timestamp: this.clock.nowSeconds(), signerCertificate: certificate, deviceSignature: new Uint8Array(64) };
99
+ const input = deviceAuthenticationInput(request, this.relayId, endpoint, this.context);
100
+ const signature = await identity.signer.sign(input.slice(), signal);
101
+ if (!verifyDevice(input, signature, certificate.signingPublicKey))
102
+ throw new ProtocolError('invalid_signature', 'The device signer returned an invalid signature.');
103
+ proof = deviceAuthenticationCodec.encode({ ...request, deviceSignature: signature });
104
+ method = 'auth.device.verify';
105
+ }
106
+ else {
107
+ const request = { nonce: challenge.nonce, accountPublicKey: this.#publicKey.slice(), accountSignature: new Uint8Array(64) };
108
+ const input = accountAuthenticationInput(request, this.accountId, this.relayId, endpoint, this.context);
109
+ const signature = await identity.signer.sign(input.slice(), signal);
110
+ if (!verifyAccount(input, signature, this.#publicKey))
111
+ throw new ProtocolError('invalid_signature', 'The account signer returned an invalid signature.');
112
+ proof = accountAuthenticationCodec.encode({ ...request, accountSignature: signature });
113
+ method = 'auth.account.verify';
114
+ }
115
+ throwIfAborted(signal);
116
+ this.assertIdentity();
117
+ if (this.clock.monotonicMilliseconds() - started >= (challenge.expiresAt - challenge.createdAt) * 1000)
118
+ throw new ProtocolError('expired_challenge', 'The challenge expired before the proof could be submitted.');
119
+ const sessionWire = await send(method, proof, signal);
120
+ throwIfAborted(signal);
121
+ this.assertIdentity();
122
+ if (sessionWire === undefined)
123
+ throw new ProtocolError('missing_result', 'Authentication verification has no result.');
124
+ const credentials = sessionCredentialsCodec.decode(sessionWire);
125
+ validateSession(credentials);
126
+ const session = new RelaySession(credentials, origin, challenge.createdAt, started, this.clock);
127
+ if (session.mode !== this.mode || session.remainingSeconds <= 0)
128
+ throw new ProtocolError('invalid_session', 'Relay returned an expired session or a different authentication mode.');
129
+ return session;
130
+ }
131
+ }
132
+ /** Shares only authentication work. Canceling a waiter never cancels another caller's refresh. */
133
+ export class HttpRelaySessions {
134
+ authenticator;
135
+ transport;
136
+ #lifetime = createAbortController();
137
+ #session;
138
+ #pending;
139
+ constructor(authenticator, transport) {
140
+ this.authenticator = authenticator;
141
+ this.transport = transport;
142
+ }
143
+ get(endpoint, signal) {
144
+ throwIfAborted(signal);
145
+ throwIfAborted(this.#lifetime.signal);
146
+ this.authenticator.assertIdentity();
147
+ const origin = relayOrigin(endpoint);
148
+ if (this.#session?.origin === origin && this.#session.remainingSeconds > Math.min(5, this.#session.lifetimeSeconds * 0.2))
149
+ return Promise.resolve(this.#session);
150
+ if (this.#pending?.origin === origin)
151
+ return awaitWithSignal(this.#pending.promise, signal);
152
+ const scope = abortScope([this.#lifetime.signal]);
153
+ const pending = { origin, promise: this.authenticator.authenticate(endpoint, (name, parameters, token) => this.transport.request(endpoint, 'POST', name, parameters, undefined, token), scope.signal) };
154
+ this.#pending = pending;
155
+ pending.promise.then(session => {
156
+ scope.dispose();
157
+ if (this.#pending === pending) {
158
+ this.#session = session;
159
+ this.#pending = undefined;
160
+ }
161
+ }, () => { scope.dispose(); if (this.#pending === pending)
162
+ this.#pending = undefined; });
163
+ return awaitWithSignal(pending.promise, signal);
164
+ }
165
+ invalidate(session) { if (session === undefined || this.#session === session)
166
+ this.#session = undefined; }
167
+ dispose() { this.#session = undefined; this.#pending = undefined; this.#lifetime.abort(new DOMException('Relay sessions were disposed.', 'AbortError')); }
168
+ }
169
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/transport/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { type RandomSource } from '../crypto/primitives.js';
2
+ import { type SessionMode } from '../models/authentication.js';
3
+ import type { JsonObject, JsonValue } from '../protocol/json.js';
4
+ import { type RuntimeClock } from '../runtime/clock.js';
5
+ import { RelayBackoff } from './http.js';
6
+ import { type RpcNotification } from './rpc.js';
7
+ export interface RelaySocketEvents {
8
+ open: undefined;
9
+ message: unknown;
10
+ error: Error;
11
+ close: {
12
+ readonly code: number;
13
+ readonly reason: string;
14
+ };
15
+ }
16
+ /** Platform socket adapters normalize events and report the actual close code they can send. */
17
+ export interface RelaySocket {
18
+ readonly readyState: number;
19
+ readonly bufferedAmount: number;
20
+ send(text: string): void;
21
+ close(code: number, reason: string): number;
22
+ on<K extends keyof RelaySocketEvents>(event: K, listener: (value: RelaySocketEvents[K]) => void): () => void;
23
+ }
24
+ export type RelaySocketFactory = (endpoint: string) => RelaySocket;
25
+ /** Browsers only allow 1000 or application codes in close(); 3003/3009 report the corresponding local rejection. */
26
+ export declare const browserSocketFactory: RelaySocketFactory;
27
+ export interface SocketFailure {
28
+ readonly error: unknown;
29
+ readonly requestedCloseCode: number;
30
+ readonly sentCloseCode: number | undefined;
31
+ }
32
+ export interface RpcConnectionOptions {
33
+ readonly socketFactory?: RelaySocketFactory;
34
+ readonly clock?: RuntimeClock;
35
+ readonly random?: RandomSource;
36
+ readonly backoff?: RelayBackoff;
37
+ readonly requestTimeoutMilliseconds?: number;
38
+ }
39
+ /** One connection only. Pool/session owners handle reconnect, renewal and notification catch-up. */
40
+ export declare class RpcConnection {
41
+ #private;
42
+ readonly endpoint: string;
43
+ readonly closed: Promise<SocketFailure>;
44
+ constructor(endpoint: string, options?: RpcConnectionOptions);
45
+ get failure(): SocketFailure | undefined;
46
+ get establishedMode(): SessionMode | undefined;
47
+ connect(signal?: AbortSignal): Promise<void>;
48
+ request(method: string, parameters?: JsonObject, signal?: AbortSignal): Promise<JsonValue>;
49
+ /** A single consumer normally drains this into the client notification dispatcher. */
50
+ nextNotification(signal?: AbortSignal): Promise<RpcNotification>;
51
+ dispose(): void;
52
+ /** Retires this exact connection when authentication or subscription outcome is uncertain. */
53
+ fail(error: unknown): void;
54
+ }
55
+ //# sourceMappingURL=socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/transport/socket.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE1E,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAEzG,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAA4D,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAElH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAoF,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAElI,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED,gGAAgG;AAChG,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAChH;AACD,MAAM,MAAM,kBAAkB,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,WAAW,CAAC;AAEnE,oHAAoH;AACpH,eAAO,MAAM,oBAAoB,EAAE,kBAmBlC,CAAC;AAEF,MAAM,WAAW,aAAa;IAAG,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE;AAE3I,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,MAAM,CAAC;CAChD;AAED,oGAAoG;AACpG,qBAAa,aAAa;;IAqBV,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAFrC,QAAQ,CAAC,MAAM,yBAA6E;IAE5F,YAAqB,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,EAQxE;IAED,IAAI,OAAO,IAAI,aAAa,GAAG,SAAS,CAA0B;IAClE,IAAI,eAAe,IAAI,WAAW,GAAG,SAAS,CAAuB;IAErE,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC3C;IAEK,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAmC/F;IAED,sFAAsF;IACtF,gBAAgB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAgB/D;IA4DD,OAAO,IAAI,IAAI,CAAoF;IACnG,8FAA8F;IAC9F,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAuB;CACpD"}
@@ -0,0 +1,266 @@
1
+ import { createAbortController, abortReason } from '../runtime/abort.js';
2
+ import { systemRandom } from '../crypto/primitives.js';
3
+ import { ProtocolError } from '../errors.js';
4
+ import { sessionCredentialsCodec, validateSession } from '../models/authentication.js';
5
+ import { encodeBase64Url } from '../protocol/encoding.js';
6
+ import { abortScope, awaitWithSignal, systemClock, throwIfAborted } from '../runtime/clock.js';
7
+ import { webEndpoint } from './endpoint.js';
8
+ import { RelayBackoff } from './http.js';
9
+ import { RelayError } from './relay-error.js';
10
+ import { decodeRpcMessage, encodeRpcRequest, rpcFailureError } from './rpc.js';
11
+ /** Browsers only allow 1000 or application codes in close(); 3003/3009 report the corresponding local rejection. */
12
+ export const browserSocketFactory = endpoint => {
13
+ const socket = new WebSocket(endpoint);
14
+ socket.binaryType = 'arraybuffer';
15
+ return {
16
+ get readyState() { return socket.readyState; },
17
+ get bufferedAmount() { return socket.bufferedAmount; },
18
+ send(text) { socket.send(text); },
19
+ close(code, reason) { const actual = code === 1000 ? code : 3000 + code - 1000; socket.close(actual, reason); return actual; },
20
+ on(event, listener) {
21
+ const handler = (value) => {
22
+ const normalized = event === 'open' ? undefined : event === 'message' ? value.data
23
+ : event === 'close' ? { code: value.code, reason: value.reason }
24
+ : new Error('The browser WebSocket failed; inspect the browser network diagnostics.');
25
+ listener(normalized);
26
+ };
27
+ socket.addEventListener(event, handler);
28
+ return () => socket.removeEventListener(event, handler);
29
+ },
30
+ };
31
+ };
32
+ /** One connection only. Pool/session owners handle reconnect, renewal and notification catch-up. */
33
+ export class RpcConnection {
34
+ endpoint;
35
+ #factory;
36
+ #clock;
37
+ #random;
38
+ #backoff;
39
+ #timeout;
40
+ #lifetime = createAbortController();
41
+ #pending = new Map();
42
+ #queue = [];
43
+ #waiters = [];
44
+ #socket;
45
+ #opening;
46
+ #rejectOpening;
47
+ #mode;
48
+ #sequence = 0;
49
+ #requestPrefix;
50
+ #failure;
51
+ #resolveClosed;
52
+ #unlisten = [];
53
+ closed = new Promise(resolve => { this.#resolveClosed = resolve; });
54
+ constructor(endpoint, options = {}) {
55
+ this.endpoint = endpoint;
56
+ webEndpoint(endpoint, 'wss:');
57
+ this.#factory = options.socketFactory ?? browserSocketFactory;
58
+ this.#clock = options.clock ?? systemClock;
59
+ this.#random = options.random ?? systemRandom;
60
+ this.#backoff = options.backoff ?? new RelayBackoff(this.#clock);
61
+ this.#timeout = options.requestTimeoutMilliseconds ?? 60000;
62
+ if (!Number.isSafeInteger(this.#timeout) || this.#timeout < 1 || this.#timeout > 2_147_483_647)
63
+ throw new RangeError('Invalid socket timeout.');
64
+ }
65
+ get failure() { return this.#failure; }
66
+ get establishedMode() { return this.#mode; }
67
+ connect(signal) {
68
+ throwIfAborted(signal);
69
+ throwIfAborted(this.#lifetime.signal);
70
+ if (this.#opening)
71
+ return awaitWithSignal(this.#opening, signal);
72
+ this.#requestPrefix = encodeBase64Url(this.#random.bytes(16));
73
+ const scope = abortScope([this.#lifetime.signal], this.#timeout);
74
+ this.#opening = new Promise((resolve, reject) => {
75
+ this.#rejectOpening = reject;
76
+ let socket;
77
+ try {
78
+ socket = this.#factory(this.endpoint);
79
+ this.#socket = socket;
80
+ }
81
+ catch (error) {
82
+ this.#stop(error);
83
+ reject(error);
84
+ return;
85
+ }
86
+ const onAbort = () => { this.#stop(abortReason(scope.signal)); reject(abortReason(scope.signal)); };
87
+ scope.signal.addEventListener('abort', onAbort, { once: true });
88
+ this.#unlisten.push(() => scope.signal.removeEventListener('abort', onAbort));
89
+ this.#unlisten.push(socket.on('open', () => {
90
+ if (this.#failure)
91
+ return;
92
+ scope.dispose();
93
+ scope.signal.removeEventListener('abort', onAbort);
94
+ this.#rejectOpening = undefined;
95
+ resolve();
96
+ }));
97
+ this.#unlisten.push(socket.on('message', value => this.#receive(value)));
98
+ this.#unlisten.push(socket.on('error', cause => {
99
+ const error = new ProtocolError('socket_error', 'The relay WebSocket transport failed.', { cause });
100
+ this.#stop(error);
101
+ reject(error);
102
+ }));
103
+ this.#unlisten.push(socket.on('close', event => {
104
+ const error = new ProtocolError('socket_closed', `Relay closed the WebSocket (${event.code}): ${event.reason}`);
105
+ this.#stop(error);
106
+ reject(error);
107
+ this.#detach();
108
+ }));
109
+ });
110
+ // Both branches handle cleanup; the original rejection remains visible to every waiter.
111
+ this.#opening.then(() => scope.dispose(), () => scope.dispose());
112
+ return awaitWithSignal(this.#opening, signal);
113
+ }
114
+ async request(method, parameters, signal) {
115
+ throwIfAborted(signal);
116
+ throwIfAborted(this.#lifetime.signal);
117
+ const scope = abortScope([signal, this.#lifetime.signal], this.#timeout);
118
+ let id;
119
+ let sent = false;
120
+ const authentication = method === 'auth.account.verify' || method === 'auth.device.verify';
121
+ try {
122
+ await this.connect(scope.signal);
123
+ await this.#backoff.wait(scope.signal);
124
+ if (this.#sequence === Number.MAX_SAFE_INTEGER)
125
+ throw new ProtocolError('counter_overflow', 'Socket request sequence is exhausted.');
126
+ id = `${this.#requestPrefix}:${++this.#sequence}`;
127
+ const text = encodeRpcRequest(id, method, parameters);
128
+ while (this.#socket.bufferedAmount > 1_048_576)
129
+ await this.#clock.delay(10, scope.signal);
130
+ throwIfAborted(scope.signal);
131
+ if (this.#socket.readyState !== 1)
132
+ throw new ProtocolError('socket_closed', 'WebSocket is not open.');
133
+ const response = new Promise((resolve, reject) => this.#pending.set(id, { method, resolve, reject }));
134
+ // Register a rejection handler before send, which may synchronously emit an error.
135
+ const completion = awaitWithSignal(response, scope.signal);
136
+ try {
137
+ this.#socket.send(text);
138
+ sent = true;
139
+ }
140
+ catch (error) {
141
+ this.#stop(error);
142
+ }
143
+ const message = await completion;
144
+ if (message.kind === 'failure') {
145
+ const error = rpcFailureError(message.error);
146
+ if (error instanceof RelayError) {
147
+ this.#backoff.apply(error.failure);
148
+ if (error.code === 'unauthorized')
149
+ this.#stop(error);
150
+ }
151
+ throw error;
152
+ }
153
+ return message.result;
154
+ }
155
+ catch (error) {
156
+ if (authentication && sent && scope.signal.aborted)
157
+ this.#stop(error);
158
+ throw error;
159
+ }
160
+ finally {
161
+ if (id !== undefined)
162
+ this.#pending.delete(id);
163
+ scope.dispose();
164
+ }
165
+ }
166
+ /** A single consumer normally drains this into the client notification dispatcher. */
167
+ nextNotification(signal) {
168
+ throwIfAborted(signal);
169
+ throwIfAborted(this.#lifetime.signal);
170
+ const queued = this.#queue.shift();
171
+ if (queued)
172
+ return Promise.resolve(queued);
173
+ return new Promise((resolve, reject) => {
174
+ const waiter = { resolve: (value) => { signal?.removeEventListener('abort', onAbort); resolve(value); },
175
+ reject: (error) => { signal?.removeEventListener('abort', onAbort); reject(error); } };
176
+ const onAbort = () => {
177
+ const index = this.#waiters.indexOf(waiter);
178
+ if (index >= 0)
179
+ this.#waiters.splice(index, 1);
180
+ waiter.reject(abortReason(signal));
181
+ };
182
+ signal?.addEventListener('abort', onAbort, { once: true });
183
+ this.#waiters.push(waiter);
184
+ });
185
+ }
186
+ #receive(value) {
187
+ if (this.#failure)
188
+ return;
189
+ try {
190
+ if (typeof value !== 'string') {
191
+ this.#stop(new ProtocolError('binary_message', 'Relay WebSocket messages must use text.'), 1003);
192
+ return;
193
+ }
194
+ const message = decodeRpcMessage(value);
195
+ if (message.kind === 'notification') {
196
+ if (this.#mode !== 'device')
197
+ throw new ProtocolError('unauthorized_notification', 'Only an authenticated device connection can receive notifications.');
198
+ const waiting = this.#waiters.shift();
199
+ if (waiting)
200
+ waiting.resolve(message.notification);
201
+ else {
202
+ if (this.#queue.length >= 256)
203
+ throw new ProtocolError('notification_overflow', 'Notification queue is full; reconnect and synchronize to recover missed updates.');
204
+ this.#queue.push(message.notification);
205
+ }
206
+ return;
207
+ }
208
+ if (message.id === null)
209
+ throw new ProtocolError('uncorrelated_response', 'Relay response has no correlatable request ID.');
210
+ const pending = this.#pending.get(message.id);
211
+ // Late responses to canceled requests remain valid frames but have no waiting caller.
212
+ if (!pending)
213
+ return;
214
+ if (message.kind === 'success' && (pending.method === 'auth.account.verify' || pending.method === 'auth.device.verify')) {
215
+ const credentials = sessionCredentialsCodec.decode(message.result);
216
+ validateSession(credentials);
217
+ const mode = pending.method === 'auth.account.verify' ? 'account' : 'device';
218
+ if (credentials.mode !== mode || this.#mode !== undefined && this.#mode !== mode)
219
+ throw new ProtocolError('invalid_session', 'The relay changed the socket session mode.');
220
+ // Set before resolving so a same-tick notification cannot race authentication.
221
+ this.#mode = mode;
222
+ }
223
+ this.#pending.delete(message.id);
224
+ pending.resolve(message);
225
+ }
226
+ catch (error) {
227
+ this.#stop(error, error instanceof ProtocolError && error.code === 'message_too_large' ? 1009 : 1000);
228
+ }
229
+ }
230
+ #stop(error, code = 1000) {
231
+ if (this.#failure)
232
+ return;
233
+ // Set before abort: abort handlers can reenter stop.
234
+ this.#failure = { error, requestedCloseCode: code, sentCloseCode: undefined };
235
+ this.#rejectOpening?.(error);
236
+ this.#rejectOpening = undefined;
237
+ this.#lifetime.abort(error);
238
+ for (const pending of this.#pending.values())
239
+ pending.reject(error);
240
+ this.#pending.clear();
241
+ for (const waiter of this.#waiters.splice(0))
242
+ waiter.reject(error);
243
+ this.#queue.length = 0;
244
+ try {
245
+ if (this.#socket && this.#socket.readyState < 2) {
246
+ const sentCloseCode = this.#socket.close(code, code === 1003 ? 'Only text messages are supported.' : code === 1009 ? 'Message exceeds 1 MiB.' : 'Meshline connection ended.');
247
+ this.#failure = { error, requestedCloseCode: code, sentCloseCode };
248
+ }
249
+ }
250
+ catch (closeError) {
251
+ this.#failure = { error: new AggregateError([error, closeError], 'Socket failure and close failure.'), requestedCloseCode: code, sentCloseCode: undefined };
252
+ }
253
+ if (!this.#socket || this.#socket.readyState === 3)
254
+ this.#detach();
255
+ this.#resolveClosed(this.#failure);
256
+ }
257
+ #detach() {
258
+ for (const unlisten of this.#unlisten)
259
+ unlisten();
260
+ this.#unlisten = [];
261
+ }
262
+ dispose() { this.#stop(new DOMException('The RPC connection was disposed.', 'AbortError')); }
263
+ /** Retires this exact connection when authentication or subscription outcome is uncertain. */
264
+ fail(error) { this.#stop(error); }
265
+ }
266
+ //# sourceMappingURL=socket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.js","sourceRoot":"","sources":["../../src/transport/socket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { type JsonObject, type JsonValue } from '../protocol/json.js';
2
+ import { type RuntimeClock } from '../runtime/clock.js';
3
+ export type SubscriptionMethod = 'channel.subscribe' | 'group.subscribe';
4
+ export interface RelaySubscriptionOptions {
5
+ /** Quiesces new attempts. The owner still calls dispose() after its producers stop. */
6
+ readonly signal?: AbortSignal;
7
+ readonly onSubscribed?: () => void | Promise<void>;
8
+ readonly onError?: (error: unknown) => void | Promise<void>;
9
+ }
10
+ export interface SubscriptionConnection {
11
+ readonly generation: number;
12
+ readonly failure: unknown;
13
+ request(method: string, parameters: JsonObject, signal: AbortSignal): Promise<JsonValue>;
14
+ retire(error: unknown): void;
15
+ }
16
+ export interface SubscriptionTransport {
17
+ readonly clock: RuntimeClock;
18
+ readonly lifetime: AbortSignal;
19
+ ready(signal: AbortSignal): Promise<SubscriptionConnection>;
20
+ onConnected(listener: () => void): () => void;
21
+ closed(): void;
22
+ }
23
+ /** One full-replacement stream for one method and relay. Created through RelayClient. */
24
+ export declare class RelaySubscription {
25
+ #private;
26
+ readonly method: SubscriptionMethod;
27
+ readonly options: RelaySubscriptionOptions;
28
+ readonly transport: SubscriptionTransport;
29
+ constructor(method: SubscriptionMethod, empty: JsonObject, options: RelaySubscriptionOptions, transport: SubscriptionTransport);
30
+ get lastError(): unknown;
31
+ /** Snapshots and coalesces updates, including empty sets; it does not wait for remote acknowledgement. */
32
+ update(request: JsonObject): void;
33
+ /** Drains the in-flight replacement and clears this exact connection within one shared five-second budget. */
34
+ dispose(): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../src/transport/subscription.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2C,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE/G,OAAO,EAA8B,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGpF,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AACzE,MAAM,WAAW,wBAAwB;IACrC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AACD,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IACzF,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CAChC;AACD,MAAM,WAAW,qBAAqB;IAClC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC5D,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC9C,MAAM,IAAI,IAAI,CAAC;CAClB;AAOD,yFAAyF;AACzF,qBAAa,iBAAiB;;IAMd,QAAQ,CAAC,MAAM,EAAE,kBAAkB;IAAqB,QAAQ,CAAC,OAAO,EAAE,wBAAwB;IAAE,QAAQ,CAAC,SAAS,EAAE,qBAAqB;IAAzJ,YAAqB,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,UAAU,EAAW,OAAO,EAAE,wBAAwB,EAAW,SAAS,EAAE,qBAAqB,EAKxJ;IACD,IAAI,SAAS,IAAI,OAAO,CAA4B;IACpD,0GAA0G;IAC1G,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAIhC;IA4CD,8GAA8G;IAC9G,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBvB;CACJ"}