@hashtree/worker 0.1.26 → 0.2.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 (258) hide show
  1. package/README.md +16 -16
  2. package/package.json +23 -19
  3. package/src/app-runtime.ts +393 -0
  4. package/src/capabilities/blossomBandwidthTracker.ts +74 -0
  5. package/src/capabilities/blossomTransport.ts +179 -0
  6. package/src/capabilities/connectivity.ts +54 -0
  7. package/src/capabilities/idbStorage.ts +94 -0
  8. package/src/capabilities/meshRouterStore.ts +426 -0
  9. package/src/capabilities/rootResolver.ts +497 -0
  10. package/src/client-id.ts +137 -0
  11. package/src/client.ts +501 -0
  12. package/{dist/entry.js → src/entry.ts} +1 -1
  13. package/src/htree-path.ts +53 -0
  14. package/src/htree-url.ts +156 -0
  15. package/src/index.ts +76 -0
  16. package/src/mediaStreaming.ts +64 -0
  17. package/src/p2p/boundedQueue.ts +168 -0
  18. package/src/p2p/errorMessage.ts +6 -0
  19. package/src/p2p/index.ts +48 -0
  20. package/src/p2p/lruCache.ts +78 -0
  21. package/src/p2p/meshQueryRouter.ts +361 -0
  22. package/src/p2p/protocol.ts +11 -0
  23. package/src/p2p/queryForwardingMachine.ts +197 -0
  24. package/src/p2p/signaling.ts +284 -0
  25. package/src/p2p/uploadRateLimiter.ts +85 -0
  26. package/src/p2p/webrtcController.ts +1168 -0
  27. package/src/p2p/webrtcProxy.ts +519 -0
  28. package/src/privacyGuards.ts +31 -0
  29. package/src/protocol.ts +124 -0
  30. package/src/relay/identity.ts +86 -0
  31. package/src/relay/mediaHandler.ts +1633 -0
  32. package/src/relay/ndk.ts +590 -0
  33. package/{dist/iris/nostr-wasm.js → src/relay/nostr-wasm.ts} +4 -1
  34. package/src/relay/nostr.ts +249 -0
  35. package/src/relay/protocol.ts +361 -0
  36. package/src/relay/publicAssetUrl.ts +25 -0
  37. package/src/relay/rootPathResolver.ts +50 -0
  38. package/src/relay/shims.d.ts +17 -0
  39. package/src/relay/signing.ts +332 -0
  40. package/src/relay/treeRootCache.ts +354 -0
  41. package/src/relay/treeRootSubscription.ts +577 -0
  42. package/src/relay/utils/constants.ts +139 -0
  43. package/src/relay/utils/errorMessage.ts +7 -0
  44. package/src/relay/utils/lruCache.ts +79 -0
  45. package/src/relay/webrtc.ts +5 -0
  46. package/src/relay/webrtcSignaling.ts +108 -0
  47. package/src/relay/worker.ts +1787 -0
  48. package/src/relay-client.ts +265 -0
  49. package/src/relay-entry.ts +1 -0
  50. package/src/runtime-network.ts +134 -0
  51. package/src/runtime.ts +153 -0
  52. package/src/transferableBytes.ts +5 -0
  53. package/src/tree-root.ts +851 -0
  54. package/src/types.ts +8 -0
  55. package/src/worker.ts +975 -0
  56. package/LICENSE +0 -21
  57. package/dist/app-runtime.d.ts +0 -60
  58. package/dist/app-runtime.d.ts.map +0 -1
  59. package/dist/app-runtime.js +0 -271
  60. package/dist/app-runtime.js.map +0 -1
  61. package/dist/capabilities/blossomBandwidthTracker.d.ts +0 -26
  62. package/dist/capabilities/blossomBandwidthTracker.d.ts.map +0 -1
  63. package/dist/capabilities/blossomBandwidthTracker.js +0 -53
  64. package/dist/capabilities/blossomBandwidthTracker.js.map +0 -1
  65. package/dist/capabilities/blossomTransport.d.ts +0 -22
  66. package/dist/capabilities/blossomTransport.d.ts.map +0 -1
  67. package/dist/capabilities/blossomTransport.js +0 -144
  68. package/dist/capabilities/blossomTransport.js.map +0 -1
  69. package/dist/capabilities/connectivity.d.ts +0 -3
  70. package/dist/capabilities/connectivity.d.ts.map +0 -1
  71. package/dist/capabilities/connectivity.js +0 -49
  72. package/dist/capabilities/connectivity.js.map +0 -1
  73. package/dist/capabilities/idbStorage.d.ts +0 -25
  74. package/dist/capabilities/idbStorage.d.ts.map +0 -1
  75. package/dist/capabilities/idbStorage.js +0 -73
  76. package/dist/capabilities/idbStorage.js.map +0 -1
  77. package/dist/capabilities/meshRouterStore.d.ts +0 -71
  78. package/dist/capabilities/meshRouterStore.d.ts.map +0 -1
  79. package/dist/capabilities/meshRouterStore.js +0 -316
  80. package/dist/capabilities/meshRouterStore.js.map +0 -1
  81. package/dist/capabilities/rootResolver.d.ts +0 -10
  82. package/dist/capabilities/rootResolver.d.ts.map +0 -1
  83. package/dist/capabilities/rootResolver.js +0 -393
  84. package/dist/capabilities/rootResolver.js.map +0 -1
  85. package/dist/client-id.d.ts +0 -18
  86. package/dist/client-id.d.ts.map +0 -1
  87. package/dist/client-id.js +0 -98
  88. package/dist/client-id.js.map +0 -1
  89. package/dist/client.d.ts +0 -61
  90. package/dist/client.d.ts.map +0 -1
  91. package/dist/client.js +0 -417
  92. package/dist/client.js.map +0 -1
  93. package/dist/entry.d.ts +0 -2
  94. package/dist/entry.d.ts.map +0 -1
  95. package/dist/entry.js.map +0 -1
  96. package/dist/htree-path.d.ts +0 -13
  97. package/dist/htree-path.d.ts.map +0 -1
  98. package/dist/htree-path.js +0 -38
  99. package/dist/htree-path.js.map +0 -1
  100. package/dist/htree-url.d.ts +0 -22
  101. package/dist/htree-url.d.ts.map +0 -1
  102. package/dist/htree-url.js +0 -118
  103. package/dist/htree-url.js.map +0 -1
  104. package/dist/index.d.ts +0 -17
  105. package/dist/index.d.ts.map +0 -1
  106. package/dist/index.js +0 -8
  107. package/dist/index.js.map +0 -1
  108. package/dist/iris/identity.d.ts +0 -36
  109. package/dist/iris/identity.d.ts.map +0 -1
  110. package/dist/iris/identity.js +0 -78
  111. package/dist/iris/identity.js.map +0 -1
  112. package/dist/iris/mediaHandler.d.ts +0 -64
  113. package/dist/iris/mediaHandler.d.ts.map +0 -1
  114. package/dist/iris/mediaHandler.js +0 -1285
  115. package/dist/iris/mediaHandler.js.map +0 -1
  116. package/dist/iris/ndk.d.ts +0 -96
  117. package/dist/iris/ndk.d.ts.map +0 -1
  118. package/dist/iris/ndk.js +0 -502
  119. package/dist/iris/ndk.js.map +0 -1
  120. package/dist/iris/nostr-wasm.d.ts +0 -14
  121. package/dist/iris/nostr-wasm.d.ts.map +0 -1
  122. package/dist/iris/nostr-wasm.js.map +0 -1
  123. package/dist/iris/nostr.d.ts +0 -60
  124. package/dist/iris/nostr.d.ts.map +0 -1
  125. package/dist/iris/nostr.js +0 -207
  126. package/dist/iris/nostr.js.map +0 -1
  127. package/dist/iris/protocol.d.ts +0 -583
  128. package/dist/iris/protocol.d.ts.map +0 -1
  129. package/dist/iris/protocol.js +0 -16
  130. package/dist/iris/protocol.js.map +0 -1
  131. package/dist/iris/publicAssetUrl.d.ts +0 -6
  132. package/dist/iris/publicAssetUrl.d.ts.map +0 -1
  133. package/dist/iris/publicAssetUrl.js +0 -14
  134. package/dist/iris/publicAssetUrl.js.map +0 -1
  135. package/dist/iris/rootPathResolver.d.ts +0 -9
  136. package/dist/iris/rootPathResolver.d.ts.map +0 -1
  137. package/dist/iris/rootPathResolver.js +0 -32
  138. package/dist/iris/rootPathResolver.js.map +0 -1
  139. package/dist/iris/signing.d.ts +0 -50
  140. package/dist/iris/signing.d.ts.map +0 -1
  141. package/dist/iris/signing.js +0 -299
  142. package/dist/iris/signing.js.map +0 -1
  143. package/dist/iris/treeRootCache.d.ts +0 -86
  144. package/dist/iris/treeRootCache.d.ts.map +0 -1
  145. package/dist/iris/treeRootCache.js +0 -269
  146. package/dist/iris/treeRootCache.js.map +0 -1
  147. package/dist/iris/treeRootSubscription.d.ts +0 -55
  148. package/dist/iris/treeRootSubscription.d.ts.map +0 -1
  149. package/dist/iris/treeRootSubscription.js +0 -479
  150. package/dist/iris/treeRootSubscription.js.map +0 -1
  151. package/dist/iris/utils/constants.d.ts +0 -76
  152. package/dist/iris/utils/constants.d.ts.map +0 -1
  153. package/dist/iris/utils/constants.js +0 -113
  154. package/dist/iris/utils/constants.js.map +0 -1
  155. package/dist/iris/utils/errorMessage.d.ts +0 -5
  156. package/dist/iris/utils/errorMessage.d.ts.map +0 -1
  157. package/dist/iris/utils/errorMessage.js +0 -8
  158. package/dist/iris/utils/errorMessage.js.map +0 -1
  159. package/dist/iris/utils/lruCache.d.ts +0 -26
  160. package/dist/iris/utils/lruCache.d.ts.map +0 -1
  161. package/dist/iris/utils/lruCache.js +0 -66
  162. package/dist/iris/utils/lruCache.js.map +0 -1
  163. package/dist/iris/webrtc.d.ts +0 -2
  164. package/dist/iris/webrtc.d.ts.map +0 -1
  165. package/dist/iris/webrtc.js +0 -3
  166. package/dist/iris/webrtc.js.map +0 -1
  167. package/dist/iris/webrtcSignaling.d.ts +0 -37
  168. package/dist/iris/webrtcSignaling.d.ts.map +0 -1
  169. package/dist/iris/webrtcSignaling.js +0 -86
  170. package/dist/iris/webrtcSignaling.js.map +0 -1
  171. package/dist/iris/worker.d.ts +0 -12
  172. package/dist/iris/worker.d.ts.map +0 -1
  173. package/dist/iris/worker.js +0 -1529
  174. package/dist/iris/worker.js.map +0 -1
  175. package/dist/iris-client.d.ts +0 -31
  176. package/dist/iris-client.d.ts.map +0 -1
  177. package/dist/iris-client.js +0 -197
  178. package/dist/iris-client.js.map +0 -1
  179. package/dist/iris-entry.d.ts +0 -2
  180. package/dist/iris-entry.d.ts.map +0 -1
  181. package/dist/iris-entry.js +0 -2
  182. package/dist/iris-entry.js.map +0 -1
  183. package/dist/mediaStreaming.d.ts +0 -7
  184. package/dist/mediaStreaming.d.ts.map +0 -1
  185. package/dist/mediaStreaming.js +0 -48
  186. package/dist/mediaStreaming.js.map +0 -1
  187. package/dist/p2p/boundedQueue.d.ts +0 -79
  188. package/dist/p2p/boundedQueue.d.ts.map +0 -1
  189. package/dist/p2p/boundedQueue.js +0 -134
  190. package/dist/p2p/boundedQueue.js.map +0 -1
  191. package/dist/p2p/errorMessage.d.ts +0 -5
  192. package/dist/p2p/errorMessage.d.ts.map +0 -1
  193. package/dist/p2p/errorMessage.js +0 -7
  194. package/dist/p2p/errorMessage.js.map +0 -1
  195. package/dist/p2p/index.d.ts +0 -8
  196. package/dist/p2p/index.d.ts.map +0 -1
  197. package/dist/p2p/index.js +0 -6
  198. package/dist/p2p/index.js.map +0 -1
  199. package/dist/p2p/lruCache.d.ts +0 -26
  200. package/dist/p2p/lruCache.d.ts.map +0 -1
  201. package/dist/p2p/lruCache.js +0 -65
  202. package/dist/p2p/lruCache.js.map +0 -1
  203. package/dist/p2p/meshQueryRouter.d.ts +0 -44
  204. package/dist/p2p/meshQueryRouter.d.ts.map +0 -1
  205. package/dist/p2p/meshQueryRouter.js +0 -228
  206. package/dist/p2p/meshQueryRouter.js.map +0 -1
  207. package/dist/p2p/protocol.d.ts +0 -10
  208. package/dist/p2p/protocol.d.ts.map +0 -1
  209. package/dist/p2p/protocol.js +0 -2
  210. package/dist/p2p/protocol.js.map +0 -1
  211. package/dist/p2p/queryForwardingMachine.d.ts +0 -46
  212. package/dist/p2p/queryForwardingMachine.d.ts.map +0 -1
  213. package/dist/p2p/queryForwardingMachine.js +0 -144
  214. package/dist/p2p/queryForwardingMachine.js.map +0 -1
  215. package/dist/p2p/signaling.d.ts +0 -63
  216. package/dist/p2p/signaling.d.ts.map +0 -1
  217. package/dist/p2p/signaling.js +0 -185
  218. package/dist/p2p/signaling.js.map +0 -1
  219. package/dist/p2p/uploadRateLimiter.d.ts +0 -21
  220. package/dist/p2p/uploadRateLimiter.d.ts.map +0 -1
  221. package/dist/p2p/uploadRateLimiter.js +0 -62
  222. package/dist/p2p/uploadRateLimiter.js.map +0 -1
  223. package/dist/p2p/webrtcController.d.ts +0 -168
  224. package/dist/p2p/webrtcController.d.ts.map +0 -1
  225. package/dist/p2p/webrtcController.js +0 -902
  226. package/dist/p2p/webrtcController.js.map +0 -1
  227. package/dist/p2p/webrtcProxy.d.ts +0 -62
  228. package/dist/p2p/webrtcProxy.d.ts.map +0 -1
  229. package/dist/p2p/webrtcProxy.js +0 -447
  230. package/dist/p2p/webrtcProxy.js.map +0 -1
  231. package/dist/privacyGuards.d.ts +0 -14
  232. package/dist/privacyGuards.d.ts.map +0 -1
  233. package/dist/privacyGuards.js +0 -27
  234. package/dist/privacyGuards.js.map +0 -1
  235. package/dist/protocol.d.ts +0 -225
  236. package/dist/protocol.d.ts.map +0 -1
  237. package/dist/protocol.js +0 -2
  238. package/dist/protocol.js.map +0 -1
  239. package/dist/runtime-network.d.ts +0 -23
  240. package/dist/runtime-network.d.ts.map +0 -1
  241. package/dist/runtime-network.js +0 -105
  242. package/dist/runtime-network.js.map +0 -1
  243. package/dist/runtime.d.ts +0 -23
  244. package/dist/runtime.d.ts.map +0 -1
  245. package/dist/runtime.js +0 -122
  246. package/dist/runtime.js.map +0 -1
  247. package/dist/tree-root.d.ts +0 -201
  248. package/dist/tree-root.d.ts.map +0 -1
  249. package/dist/tree-root.js +0 -632
  250. package/dist/tree-root.js.map +0 -1
  251. package/dist/types.d.ts +0 -2
  252. package/dist/types.d.ts.map +0 -1
  253. package/dist/types.js +0 -2
  254. package/dist/types.js.map +0 -1
  255. package/dist/worker.d.ts +0 -9
  256. package/dist/worker.d.ts.map +0 -1
  257. package/dist/worker.js +0 -797
  258. package/dist/worker.js.map +0 -1
package/src/index.ts ADDED
@@ -0,0 +1,76 @@
1
+ export { HashtreeWorkerClient } from './client.js';
2
+ export type { WorkerFactory, P2PFetchHandler } from './client.js';
3
+ export { RelayWorkerClient } from './relay-client.js';
4
+ export type {
5
+ TreeRootInfo as RelayTreeRootInfo,
6
+ TreeRootUpdate as RelayTreeRootUpdate,
7
+ RelayWorkerConfig,
8
+ RelayWorkerRequest,
9
+ RelayWorkerResponse,
10
+ } from './relay-client.js';
11
+ export {
12
+ canUseInjectedHtreeServerUrl,
13
+ canUseSameOriginHtreeProtocolStreaming,
14
+ getInjectedHtreeServerUrl,
15
+ resolveRuntimeHtreeBaseUrl,
16
+ shouldEagerLoadMediaInNativeChildRuntime,
17
+ shouldPreferSameOriginHtreeRoutes,
18
+ } from './runtime.js';
19
+ export type {
20
+ HtreeRuntimeLocationLike,
21
+ HtreeRuntimeWindowLike,
22
+ ResolveRuntimeHtreeBaseUrlOptions,
23
+ } from './runtime.js';
24
+ export {
25
+ resolveRuntimeEndpoints,
26
+ } from './runtime-network.js';
27
+ export type {
28
+ ResolveRuntimeEndpointsOptions,
29
+ RuntimeEndpoints,
30
+ } from './runtime-network.js';
31
+ export { createHtreeRuntime } from './app-runtime.js';
32
+ export type {
33
+ HtreeRuntime,
34
+ HtreeRuntimeEndpointOverrides,
35
+ HtreeRuntimeMediaPortOptions,
36
+ HtreeRuntimeMediaUrlOptions,
37
+ HtreeRuntimeOptions,
38
+ HtreeRuntimeRequestUrlOptions,
39
+ HtreeRuntimeWorkerConfigOptions,
40
+ RuntimeValueSource,
41
+ } from './app-runtime.js';
42
+ export {
43
+ buildHtreeRequestPath,
44
+ parseHtreeUrl,
45
+ resolveHtreeRequestUrl,
46
+ } from './htree-url.js';
47
+ export type {
48
+ MutableHtreeRequestStyle,
49
+ ParsedHtreeUrl,
50
+ ResolveHtreeRequestUrlOptions,
51
+ } from './htree-url.js';
52
+ export type { HtreeClientIdStorageLike } from './client-id.js';
53
+ export type {
54
+ BlossomServerConfig,
55
+ WorkerConfig,
56
+ WorkerRequest,
57
+ WorkerResponse,
58
+ RootResolveOptions,
59
+ ConnectivityState,
60
+ UploadProgressState,
61
+ WorkerDiagnosticEvent,
62
+ WorkerDiagnosticLevel,
63
+ BlossomBandwidthState,
64
+ BlossomBandwidthServerStats,
65
+ BlobSource,
66
+ } from './protocol.js';
67
+
68
+ export {
69
+ WebRTCController,
70
+ WebRTCProxy,
71
+ initWebRTCProxy,
72
+ getWebRTCProxy,
73
+ closeWebRTCProxy,
74
+ } from './p2p/index.js';
75
+
76
+ export type { WebRTCControllerConfig } from './p2p/index.js';
@@ -0,0 +1,64 @@
1
+ import type { CID, HashTree } from '@hashtree/core';
2
+
3
+ const DEFAULT_PREFETCH = 2;
4
+
5
+ /**
6
+ * Stream a bounded byte range from a CID without materializing the whole range in memory.
7
+ * Output chunks are capped at `chunkSize` bytes.
8
+ */
9
+ export async function* streamFileRangeChunks(
10
+ tree: Pick<HashTree, 'readFileStream'>,
11
+ cid: CID,
12
+ start: number,
13
+ endInclusive: number,
14
+ chunkSize: number,
15
+ prefetch: number = DEFAULT_PREFETCH
16
+ ): AsyncGenerator<Uint8Array> {
17
+ if (chunkSize <= 0) {
18
+ throw new Error('chunkSize must be > 0');
19
+ }
20
+ if (endInclusive < start) {
21
+ return;
22
+ }
23
+
24
+ let remaining = endInclusive - start + 1;
25
+ let pending = new Uint8Array(chunkSize);
26
+ let pendingLength = 0;
27
+
28
+ for await (const sourceChunk of tree.readFileStream(cid, { offset: start, prefetch })) {
29
+ if (remaining <= 0) break;
30
+ if (sourceChunk.byteLength === 0) continue;
31
+
32
+ const consumed = Math.min(sourceChunk.byteLength, remaining);
33
+ const source = consumed === sourceChunk.byteLength ? sourceChunk : sourceChunk.subarray(0, consumed);
34
+ remaining -= consumed;
35
+
36
+ let cursor = 0;
37
+ while (cursor < source.byteLength) {
38
+ const available = source.byteLength - cursor;
39
+
40
+ if (pendingLength === 0 && available >= chunkSize) {
41
+ // Emit direct full-size chunks with independent buffers for transfer.
42
+ yield source.slice(cursor, cursor + chunkSize);
43
+ cursor += chunkSize;
44
+ continue;
45
+ }
46
+
47
+ const toCopy = Math.min(chunkSize - pendingLength, available);
48
+ pending.set(source.subarray(cursor, cursor + toCopy), pendingLength);
49
+ pendingLength += toCopy;
50
+ cursor += toCopy;
51
+
52
+ if (pendingLength === chunkSize) {
53
+ yield pending;
54
+ pending = new Uint8Array(chunkSize);
55
+ pendingLength = 0;
56
+ }
57
+ }
58
+ }
59
+
60
+ if (pendingLength > 0) {
61
+ yield pending.slice(0, pendingLength);
62
+ }
63
+ }
64
+
@@ -0,0 +1,168 @@
1
+ /**
2
+ * BoundedQueue - Memory-safe queue with size limits
3
+ *
4
+ * Prevents memory blowup by enforcing both item count and byte limits.
5
+ * When limits are exceeded, oldest items are dropped (FIFO eviction).
6
+ *
7
+ * Use this instead of plain arrays for queues that could grow unbounded,
8
+ * especially for network buffers, send queues, and work queues.
9
+ */
10
+
11
+ export interface BoundedQueueOptions<T> {
12
+ /** Maximum number of items in queue */
13
+ maxItems: number;
14
+ /** Maximum total bytes in queue */
15
+ maxBytes: number;
16
+ /** Function to get byte size of an item */
17
+ getBytes: (item: T) => number;
18
+ /** Optional callback when items are dropped due to overflow */
19
+ onDrop?: (item: T, reason: 'items' | 'bytes') => void;
20
+ }
21
+
22
+ export class BoundedQueue<T> {
23
+ private items: T[] = [];
24
+ private bytesUsed = 0;
25
+ private readonly maxItems: number;
26
+ private readonly maxBytes: number;
27
+ private readonly getBytes: (item: T) => number;
28
+ private readonly onDrop?: (item: T, reason: 'items' | 'bytes') => void;
29
+
30
+ constructor(options: BoundedQueueOptions<T>) {
31
+ this.maxItems = options.maxItems;
32
+ this.maxBytes = options.maxBytes;
33
+ this.getBytes = options.getBytes;
34
+ this.onDrop = options.onDrop;
35
+ }
36
+
37
+ /**
38
+ * Add item to queue, dropping oldest items if limits exceeded
39
+ * @returns Number of items dropped to make room
40
+ */
41
+ push(item: T): number {
42
+ const itemBytes = this.getBytes(item);
43
+ let dropped = 0;
44
+
45
+ // Drop oldest items until we have room
46
+ while (
47
+ this.items.length > 0 &&
48
+ (this.items.length >= this.maxItems || this.bytesUsed + itemBytes > this.maxBytes)
49
+ ) {
50
+ const droppedItem = this.items.shift()!;
51
+ const droppedBytes = this.getBytes(droppedItem);
52
+ this.bytesUsed -= droppedBytes;
53
+ dropped++;
54
+
55
+ if (this.onDrop) {
56
+ const reason = this.items.length >= this.maxItems ? 'items' : 'bytes';
57
+ this.onDrop(droppedItem, reason);
58
+ }
59
+ }
60
+
61
+ this.items.push(item);
62
+ this.bytesUsed += itemBytes;
63
+ return dropped;
64
+ }
65
+
66
+ /**
67
+ * Add item to the front of the queue, dropping items from the back if limits are exceeded.
68
+ * Useful for urgent control messages that should overtake bulk background traffic.
69
+ */
70
+ unshift(item: T): number {
71
+ const itemBytes = this.getBytes(item);
72
+ let dropped = 0;
73
+
74
+ while (
75
+ this.items.length > 0 &&
76
+ (this.items.length >= this.maxItems || this.bytesUsed + itemBytes > this.maxBytes)
77
+ ) {
78
+ const droppedItem = this.items.pop()!;
79
+ const droppedBytes = this.getBytes(droppedItem);
80
+ this.bytesUsed -= droppedBytes;
81
+ dropped++;
82
+
83
+ if (this.onDrop) {
84
+ const reason = this.items.length >= this.maxItems ? 'items' : 'bytes';
85
+ this.onDrop(droppedItem, reason);
86
+ }
87
+ }
88
+
89
+ this.items.unshift(item);
90
+ this.bytesUsed += itemBytes;
91
+ return dropped;
92
+ }
93
+
94
+ /**
95
+ * Remove and return oldest item, or undefined if empty
96
+ */
97
+ shift(): T | undefined {
98
+ const item = this.items.shift();
99
+ if (item !== undefined) {
100
+ this.bytesUsed -= this.getBytes(item);
101
+ }
102
+ return item;
103
+ }
104
+
105
+ /**
106
+ * Peek at oldest item without removing
107
+ */
108
+ peek(): T | undefined {
109
+ return this.items[0];
110
+ }
111
+
112
+ /**
113
+ * Clear all items
114
+ */
115
+ clear(): void {
116
+ this.items = [];
117
+ this.bytesUsed = 0;
118
+ }
119
+
120
+ /**
121
+ * Get current item count
122
+ */
123
+ get length(): number {
124
+ return this.items.length;
125
+ }
126
+
127
+ /**
128
+ * Get current byte usage
129
+ */
130
+ get bytes(): number {
131
+ return this.bytesUsed;
132
+ }
133
+
134
+ /**
135
+ * Check if queue is empty
136
+ */
137
+ get isEmpty(): boolean {
138
+ return this.items.length === 0;
139
+ }
140
+
141
+ /**
142
+ * Check if queue is at item capacity
143
+ */
144
+ get isFullItems(): boolean {
145
+ return this.items.length >= this.maxItems;
146
+ }
147
+
148
+ /**
149
+ * Check if queue is at byte capacity
150
+ */
151
+ get isFullBytes(): boolean {
152
+ return this.bytesUsed >= this.maxBytes;
153
+ }
154
+
155
+ /**
156
+ * Iterate over items (does not remove them)
157
+ */
158
+ *[Symbol.iterator](): Iterator<T> {
159
+ yield* this.items;
160
+ }
161
+
162
+ /**
163
+ * Get all items as array (for iteration/reduce operations)
164
+ */
165
+ toArray(): T[] {
166
+ return [...this.items];
167
+ }
168
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Extract error message from unknown error type
3
+ */
4
+ export function getErrorMessage(err: unknown): string {
5
+ return err instanceof Error ? err.message : String(err);
6
+ }
@@ -0,0 +1,48 @@
1
+ export {
2
+ WebRTCController,
3
+ type WebRTCControllerConfig,
4
+ } from './webrtcController.js';
5
+
6
+ export {
7
+ MeshQueryRouter,
8
+ encodeForwardRequest,
9
+ type MeshQueryRouterConfig,
10
+ type MeshQueryRouterPeer,
11
+ } from './meshQueryRouter.js';
12
+
13
+ export {
14
+ QueryForwardingMachine,
15
+ type QueryForwardingMachineConfig,
16
+ type ForwardDecision,
17
+ type ForwardTimeoutEvent,
18
+ } from './queryForwardingMachine.js';
19
+
20
+ export {
21
+ WebRTCProxy,
22
+ initWebRTCProxy,
23
+ getWebRTCProxy,
24
+ closeWebRTCProxy,
25
+ } from './webrtcProxy.js';
26
+
27
+ export type {
28
+ WebRTCCommand,
29
+ WebRTCEvent,
30
+ } from './protocol.js';
31
+
32
+ export {
33
+ SIGNALING_KIND,
34
+ HELLO_TAG,
35
+ MAX_EVENT_AGE_SEC,
36
+ createSignalingFilters,
37
+ sendSignalingMessage,
38
+ decodeSignalingEvent,
39
+ } from './signaling.js';
40
+
41
+ export type {
42
+ SignalingEventLike,
43
+ GiftSeal,
44
+ SignalingTemplate,
45
+ SignalingInnerEvent,
46
+ SignalingFilters,
47
+ DecodedSignalingEvent,
48
+ } from './signaling.js';
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Simple LRU Cache implementation
3
+ */
4
+ export class LRUCache<K, V> {
5
+ private cache = new Map<K, V>();
6
+ private maxSize: number;
7
+
8
+ constructor(maxSize: number = 100) {
9
+ this.maxSize = maxSize;
10
+ }
11
+
12
+ get(key: K): V | undefined {
13
+ const value = this.cache.get(key);
14
+ if (value !== undefined) {
15
+ // Move to end (most recently used)
16
+ this.cache.delete(key);
17
+ this.cache.set(key, value);
18
+ }
19
+ return value;
20
+ }
21
+
22
+ set(key: K, value: V): void {
23
+ // Delete first to reset position if exists
24
+ this.cache.delete(key);
25
+
26
+ // Evict oldest if at capacity
27
+ if (this.cache.size >= this.maxSize) {
28
+ const oldest = this.cache.keys().next().value;
29
+ if (oldest !== undefined) {
30
+ this.cache.delete(oldest);
31
+ }
32
+ }
33
+
34
+ this.cache.set(key, value);
35
+ }
36
+
37
+ has(key: K): boolean {
38
+ return this.cache.has(key);
39
+ }
40
+
41
+ delete(key: K): boolean {
42
+ return this.cache.delete(key);
43
+ }
44
+
45
+ clear(): void {
46
+ this.cache.clear();
47
+ }
48
+
49
+ get size(): number {
50
+ return this.cache.size;
51
+ }
52
+
53
+ keys(): IterableIterator<K> {
54
+ return this.cache.keys();
55
+ }
56
+
57
+ values(): IterableIterator<V> {
58
+ return this.cache.values();
59
+ }
60
+
61
+ /**
62
+ * Iterate over all entries (note: does not update LRU order)
63
+ */
64
+ *entries(): IterableIterator<[K, V]> {
65
+ yield* this.cache.entries();
66
+ }
67
+
68
+ forEach(callback: (value: V, key: K) => void): void {
69
+ this.cache.forEach(callback);
70
+ }
71
+
72
+ /**
73
+ * Make the cache iterable
74
+ */
75
+ [Symbol.iterator](): IterableIterator<[K, V]> {
76
+ return this.entries();
77
+ }
78
+ }