gingersnap 0.22.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 (251) hide show
  1. package/_virtual/_tslib.cjs +102 -0
  2. package/_virtual/_tslib.mjs +93 -0
  3. package/data/AtomicValue.d.ts +15 -0
  4. package/data/bus.cjs +179 -0
  5. package/data/bus.d.ts +72 -0
  6. package/data/bus.mjs +177 -0
  7. package/data/decoders/index.d.ts +4 -0
  8. package/data/decoders/json.cjs +12 -0
  9. package/data/decoders/json.d.ts +7 -0
  10. package/data/decoders/json.mjs +10 -0
  11. package/data/decoders/msgpack.cjs +14 -0
  12. package/data/decoders/msgpack.d.ts +7 -0
  13. package/data/decoders/msgpack.mjs +12 -0
  14. package/data/decoders/protobuf.d.ts +13 -0
  15. package/data/decoders/string.cjs +12 -0
  16. package/data/decoders/string.d.ts +7 -0
  17. package/data/decoders/string.mjs +10 -0
  18. package/data/decoders/type.d.ts +7 -0
  19. package/data/decoders.cjs +11 -0
  20. package/data/decoders.mjs +3 -0
  21. package/data/model/credentials.cjs +114 -0
  22. package/data/model/credentials.d.ts +61 -0
  23. package/data/model/credentials.mjs +109 -0
  24. package/data/model/extra.cjs +88 -0
  25. package/data/model/extra.d.ts +5 -0
  26. package/data/model/extra.mjs +66 -0
  27. package/data/model/index.d.ts +6 -0
  28. package/data/model/model.cjs +541 -0
  29. package/data/model/model.d.ts +207 -0
  30. package/data/model/model.mjs +518 -0
  31. package/data/model/plugin.cjs +96 -0
  32. package/data/model/plugin.d.ts +38 -0
  33. package/data/model/plugin.mjs +72 -0
  34. package/data/model/property.cjs +310 -0
  35. package/data/model/property.d.ts +83 -0
  36. package/data/model/property.mjs +278 -0
  37. package/data/model/types.cjs +32 -0
  38. package/data/model/types.d.ts +28 -0
  39. package/data/model/types.mjs +32 -0
  40. package/data/model.cjs +43 -0
  41. package/data/model.mjs +6 -0
  42. package/data/signal.cjs +47 -0
  43. package/data/signal.d.ts +17 -0
  44. package/data/signal.mjs +45 -0
  45. package/data/store/index.d.ts +4 -0
  46. package/data/store/json.cjs +58 -0
  47. package/data/store/json.d.ts +18 -0
  48. package/data/store/json.mjs +56 -0
  49. package/data/store/manager.cjs +206 -0
  50. package/data/store/manager.d.ts +44 -0
  51. package/data/store/manager.mjs +203 -0
  52. package/data/store/web.cjs +92 -0
  53. package/data/store/web.d.ts +25 -0
  54. package/data/store/web.mjs +89 -0
  55. package/data/value.cjs +66 -0
  56. package/data/value.mjs +64 -0
  57. package/data-structures/array/CyclicalList.cjs +57 -0
  58. package/data-structures/array/CyclicalList.d.ts +12 -0
  59. package/data-structures/array/CyclicalList.mjs +55 -0
  60. package/data-structures/array/Pair.cjs +30 -0
  61. package/data-structures/array/Pair.d.ts +17 -0
  62. package/data-structures/array/Pair.mjs +27 -0
  63. package/data-structures/array/Stack.cjs +96 -0
  64. package/data-structures/array/Stack.d.ts +41 -0
  65. package/data-structures/array/Stack.mjs +94 -0
  66. package/data-structures/array/Triple.cjs +34 -0
  67. package/data-structures/array/Triple.d.ts +19 -0
  68. package/data-structures/array/Triple.mjs +31 -0
  69. package/data-structures/array/Tuple.d.ts +8 -0
  70. package/data-structures/array/index.d.ts +5 -0
  71. package/data-structures/array.cjs +15 -0
  72. package/data-structures/array.mjs +4 -0
  73. package/data-structures/object/BufferQueue.cjs +98 -0
  74. package/data-structures/object/BufferQueue.d.ts +21 -0
  75. package/data-structures/object/BufferQueue.mjs +77 -0
  76. package/data-structures/object/CyclicalObject.cjs +155 -0
  77. package/data-structures/object/CyclicalObject.d.ts +74 -0
  78. package/data-structures/object/CyclicalObject.mjs +134 -0
  79. package/data-structures/object/Queue.cjs +178 -0
  80. package/data-structures/object/Queue.d.ts +31 -0
  81. package/data-structures/object/Queue.mjs +176 -0
  82. package/data-structures/object/SimpleQueue.cjs +53 -0
  83. package/data-structures/object/SimpleQueue.d.ts +13 -0
  84. package/data-structures/object/SimpleQueue.mjs +51 -0
  85. package/data-structures/object/TimeableObject.cjs +73 -0
  86. package/data-structures/object/TimeableObject.d.ts +30 -0
  87. package/data-structures/object/TimeableObject.mjs +71 -0
  88. package/data-structures/object/WaitableObject.cjs +61 -0
  89. package/data-structures/object/WaitableObject.d.ts +29 -0
  90. package/data-structures/object/WaitableObject.mjs +59 -0
  91. package/data-structures/object/WatchableObject.cjs +251 -0
  92. package/data-structures/object/WatchableObject.d.ts +88 -0
  93. package/data-structures/object/WatchableObject.mjs +230 -0
  94. package/data-structures/object/index.d.ts +7 -0
  95. package/data-structures/object.cjs +23 -0
  96. package/data-structures/object.mjs +7 -0
  97. package/errors/AbortError.cjs +9 -0
  98. package/errors/AbortError.d.ts +5 -0
  99. package/errors/AbortError.mjs +7 -0
  100. package/errors/CallExecutionError.cjs +13 -0
  101. package/errors/CallExecutionError.d.ts +7 -0
  102. package/errors/CallExecutionError.mjs +11 -0
  103. package/errors/FutureCancelled.cjs +11 -0
  104. package/errors/FutureCancelled.d.ts +6 -0
  105. package/errors/FutureCancelled.mjs +9 -0
  106. package/errors/FutureError.cjs +11 -0
  107. package/errors/FutureError.d.ts +6 -0
  108. package/errors/FutureError.mjs +9 -0
  109. package/errors/IllegalArgumentsError.cjs +13 -0
  110. package/errors/IllegalArgumentsError.d.ts +7 -0
  111. package/errors/IllegalArgumentsError.mjs +11 -0
  112. package/errors/IllegalOperationError.cjs +6 -0
  113. package/errors/IllegalOperationError.d.ts +2 -0
  114. package/errors/IllegalOperationError.mjs +4 -0
  115. package/errors/InvalidType.cjs +6 -0
  116. package/errors/InvalidType.d.ts +2 -0
  117. package/errors/InvalidType.mjs +4 -0
  118. package/errors/InvalidValue.cjs +11 -0
  119. package/errors/InvalidValue.d.ts +4 -0
  120. package/errors/InvalidValue.mjs +9 -0
  121. package/errors/MissingArgumentsError.cjs +13 -0
  122. package/errors/MissingArgumentsError.d.ts +7 -0
  123. package/errors/MissingArgumentsError.mjs +11 -0
  124. package/errors/NetworkError.cjs +13 -0
  125. package/errors/NetworkError.d.ts +8 -0
  126. package/errors/NetworkError.mjs +11 -0
  127. package/errors/NoSuchElement.cjs +6 -0
  128. package/errors/NoSuchElement.d.ts +2 -0
  129. package/errors/NoSuchElement.mjs +4 -0
  130. package/errors/NotImplemented.cjs +9 -0
  131. package/errors/NotImplemented.d.ts +5 -0
  132. package/errors/NotImplemented.mjs +7 -0
  133. package/errors/ParsingError.cjs +10 -0
  134. package/errors/ParsingError.d.ts +5 -0
  135. package/errors/ParsingError.mjs +8 -0
  136. package/errors/QueueEmptyError.cjs +6 -0
  137. package/errors/QueueEmptyError.d.ts +2 -0
  138. package/errors/QueueEmptyError.mjs +4 -0
  139. package/errors/QueueFullError.cjs +6 -0
  140. package/errors/QueueFullError.d.ts +2 -0
  141. package/errors/QueueFullError.mjs +4 -0
  142. package/errors/StackEmptyError.cjs +6 -0
  143. package/errors/StackEmptyError.d.ts +2 -0
  144. package/errors/StackEmptyError.mjs +4 -0
  145. package/errors/StackFullError.cjs +6 -0
  146. package/errors/StackFullError.d.ts +2 -0
  147. package/errors/StackFullError.mjs +4 -0
  148. package/errors/StreamEnded.cjs +6 -0
  149. package/errors/StreamEnded.d.ts +2 -0
  150. package/errors/StreamEnded.mjs +4 -0
  151. package/errors/TimeoutError.cjs +11 -0
  152. package/errors/TimeoutError.d.ts +6 -0
  153. package/errors/TimeoutError.mjs +9 -0
  154. package/errors/ValueDestroyedError.cjs +6 -0
  155. package/errors/ValueDestroyedError.d.ts +2 -0
  156. package/errors/ValueDestroyedError.mjs +4 -0
  157. package/errors/VerificationError.cjs +9 -0
  158. package/errors/VerificationError.d.ts +5 -0
  159. package/errors/VerificationError.mjs +7 -0
  160. package/errors/index.d.ts +18 -0
  161. package/errors.cjs +41 -0
  162. package/errors.mjs +18 -0
  163. package/files.cjs +201 -0
  164. package/files.d.ts +31 -0
  165. package/files.mjs +180 -0
  166. package/functools/index.d.ts +31 -0
  167. package/functools.cjs +371 -0
  168. package/functools.mjs +334 -0
  169. package/future/future.cjs +570 -0
  170. package/future/future.d.ts +208 -0
  171. package/future/future.mjs +548 -0
  172. package/future/group.cjs +180 -0
  173. package/future/group.d.ts +82 -0
  174. package/future/group.mjs +159 -0
  175. package/future/index.d.ts +3 -0
  176. package/future/result.cjs +19 -0
  177. package/future/result.d.ts +18 -0
  178. package/future/result.mjs +17 -0
  179. package/future.cjs +11 -0
  180. package/future.mjs +3 -0
  181. package/managers/context.d.ts +8 -0
  182. package/managers/index.d.ts +1 -0
  183. package/managers.cjs +2 -0
  184. package/managers.mjs +1 -0
  185. package/mocks.cjs +301 -0
  186. package/mocks.d.ts +125 -0
  187. package/mocks.mjs +293 -0
  188. package/networking/EventSourceService.cjs +104 -0
  189. package/networking/EventSourceService.d.ts +11 -0
  190. package/networking/EventSourceService.mjs +83 -0
  191. package/networking/NetworkService.cjs +394 -0
  192. package/networking/NetworkService.d.ts +97 -0
  193. package/networking/NetworkService.mjs +373 -0
  194. package/networking/SocketService.cjs +218 -0
  195. package/networking/SocketService.d.ts +23 -0
  196. package/networking/SocketService.mjs +197 -0
  197. package/networking/decorators/index.d.ts +4 -0
  198. package/networking/decorators/options.cjs +289 -0
  199. package/networking/decorators/options.d.ts +148 -0
  200. package/networking/decorators/options.mjs +242 -0
  201. package/networking/decorators/requests.cjs +80 -0
  202. package/networking/decorators/requests.d.ts +34 -0
  203. package/networking/decorators/requests.mjs +52 -0
  204. package/networking/decorators/socket.cjs +81 -0
  205. package/networking/decorators/socket.d.ts +13 -0
  206. package/networking/decorators/socket.mjs +51 -0
  207. package/networking/http.cjs +69 -0
  208. package/networking/http.d.ts +66 -0
  209. package/networking/http.mjs +69 -0
  210. package/networking/index.d.ts +39 -0
  211. package/networking/request.cjs +18 -0
  212. package/networking/request.d.ts +9 -0
  213. package/networking/request.mjs +16 -0
  214. package/networking/types.cjs +37 -0
  215. package/networking/types.d.ts +132 -0
  216. package/networking/types.mjs +35 -0
  217. package/networking.cjs +91 -0
  218. package/networking.mjs +33 -0
  219. package/package.json +1 -0
  220. package/reflection/injector.cjs +43 -0
  221. package/reflection/injector.d.ts +3 -0
  222. package/reflection/injector.mjs +40 -0
  223. package/socket.cjs +239 -0
  224. package/socket.d.ts +65 -0
  225. package/socket.mjs +237 -0
  226. package/store.cjs +12 -0
  227. package/store.mjs +3 -0
  228. package/stream/call.cjs +157 -0
  229. package/stream/call.d.ts +66 -0
  230. package/stream/call.mjs +154 -0
  231. package/stream/collector.cjs +217 -0
  232. package/stream/collector.d.ts +14 -0
  233. package/stream/collector.mjs +215 -0
  234. package/stream/index.d.ts +257 -0
  235. package/stream/observable.cjs +110 -0
  236. package/stream/observable.d.ts +65 -0
  237. package/stream/observable.mjs +106 -0
  238. package/stream/state.cjs +10 -0
  239. package/stream/state.d.ts +5 -0
  240. package/stream/state.mjs +8 -0
  241. package/stream.cjs +1153 -0
  242. package/stream.mjs +1132 -0
  243. package/synchronize.cjs +106 -0
  244. package/synchronize.d.ts +54 -0
  245. package/synchronize.mjs +103 -0
  246. package/typing/types.d.ts +24 -0
  247. package/typing.cjs +2 -0
  248. package/typing.mjs +1 -0
  249. package/utils/parser.cjs +37 -0
  250. package/utils/parser.d.ts +7 -0
  251. package/utils/parser.mjs +16 -0
package/socket.cjs ADDED
@@ -0,0 +1,239 @@
1
+ 'use strict';
2
+
3
+ var _tslib = require('./_virtual/_tslib.cjs');
4
+ var AbortError = require('./errors/AbortError.cjs');
5
+ var FutureCancelled = require('./errors/FutureCancelled.cjs');
6
+ var NetworkError = require('./errors/NetworkError.cjs');
7
+ require('./networking/decorators/options.cjs');
8
+ require('./networking/decorators/requests.cjs');
9
+ var http = require('./networking/http.cjs');
10
+ require('ramda');
11
+ require('uuid');
12
+ var stream = require('./stream.cjs');
13
+ var future = require('./future/future.cjs');
14
+ var synchronize = require('./synchronize.cjs');
15
+ var stream_state = require('./stream/state.cjs');
16
+ var WebSocket = require('modern-isomorphic-ws');
17
+ require('./data-structures/object/WatchableObject.cjs');
18
+ require('object-hash');
19
+ var Queue = require('./data-structures/object/Queue.cjs');
20
+ var Pair = require('./data-structures/array/Pair.cjs');
21
+
22
+ /**
23
+ * Future-based web sockets
24
+ */
25
+ class StreamableWebSocket {
26
+ constructor(url, decoder, { retryOnDisconnect, cacheSize, cacheExpiryPeriod, exponentialFactor, backoffPeriodMs, } = {}, maxReconnectAttempt = 3) {
27
+ this.maxReconnectAttempt = maxReconnectAttempt;
28
+ this.connectionAttemptCount = 0;
29
+ this.signal = new AbortController().signal;
30
+ this.decoder = decoder;
31
+ this.socketListeners = [];
32
+ this.url = url;
33
+ this.cacheSize = cacheSize !== null && cacheSize !== void 0 ? cacheSize : 10000;
34
+ this.manuallyClosed = false;
35
+ this.retryOnDisconnect = retryOnDisconnect !== null && retryOnDisconnect !== void 0 ? retryOnDisconnect : true;
36
+ this.exponentialFactor = exponentialFactor !== null && exponentialFactor !== void 0 ? exponentialFactor : 2;
37
+ this.backoffPeriodMs = backoffPeriodMs !== null && backoffPeriodMs !== void 0 ? backoffPeriodMs : 10;
38
+ this.backoffPeriods = -1;
39
+ this.messageQueues = [];
40
+ this.evt = new EventTarget();
41
+ this.dataReadyEvent = new synchronize.FutureEvent();
42
+ this.dataProcessingLock = new synchronize.Lock();
43
+ }
44
+ get opened() {
45
+ return this.socket && this.socket.readyState === WebSocket.OPEN;
46
+ }
47
+ get closed() {
48
+ return this.socket && this.socket.readyState === WebSocket.CLOSED;
49
+ }
50
+ /**
51
+ * opens the current web socket connection
52
+ */
53
+ open() {
54
+ var _a;
55
+ if (!this.openFuture || ((_a = this.openFuture) === null || _a === void 0 ? void 0 : _a.failed)) {
56
+ this.closeFuture = new future.Future((resolve, reject, signal) => {
57
+ this.signal.addEventListener("abort", () => {
58
+ resolve();
59
+ });
60
+ signal.onabort = () => {
61
+ this.signal.removeEventListener("abort", resolve);
62
+ reject(new AbortError.AbortError());
63
+ };
64
+ }).schedule();
65
+ this.openFuture = new future.Future((resolve, reject, signal) => {
66
+ const functor = () => {
67
+ this.close();
68
+ };
69
+ signal.addEventListener("abort", functor);
70
+ let retrying = false;
71
+ const cancelError = this.addEventListener("error", () => _tslib.__awaiter(this, void 0, void 0, function* () {
72
+ var _a, _b;
73
+ if (this.retryOnDisconnect && !signal.aborted && this.connectionAttemptCount < this.maxReconnectAttempt) {
74
+ this.connectionAttemptCount++;
75
+ retrying = true;
76
+ (_a = this.getSocket()) === null || _a === void 0 ? void 0 : _a.close();
77
+ yield future.Future.sleep({
78
+ milliseconds: this.backoffPeriodMs * Math.pow(this.exponentialFactor, ++this.backoffPeriods),
79
+ });
80
+ this.createSocket();
81
+ }
82
+ else {
83
+ this.connectionAttemptCount = 0;
84
+ retrying = false;
85
+ cancelError();
86
+ cancelOpen();
87
+ reject(new NetworkError.NetworkError(http.HTTPStatus.EXPECTATION_FAILED));
88
+ (_b = this.getSocket()) === null || _b === void 0 ? void 0 : _b.close();
89
+ }
90
+ }));
91
+ const cancelOpen = this.addEventListener("open", () => {
92
+ this.connectionAttemptCount = 0;
93
+ this.backoffPeriods = -1;
94
+ retrying = false;
95
+ resolve();
96
+ signal.removeEventListener("abort", functor);
97
+ cancelError();
98
+ cancelOpen();
99
+ });
100
+ const cancelClose = this.addEventListener("close", () => {
101
+ if (retrying)
102
+ return;
103
+ if (!this.manuallyClosed && this.retryOnDisconnect && !signal.aborted) {
104
+ delete this.openFuture;
105
+ cancelError();
106
+ cancelOpen();
107
+ cancelClose();
108
+ this.open()
109
+ .thenApply(() => resolve())
110
+ .catch(reject);
111
+ }
112
+ else {
113
+ retrying = false;
114
+ this.signal.dispatchEvent(new CustomEvent("abort"));
115
+ cancelQueue();
116
+ reject(new NetworkError.NetworkError(http.HTTPStatus.EXPECTATION_FAILED));
117
+ }
118
+ });
119
+ const cancelQueue = this.addEventListener("message", (evt) => {
120
+ const data = evt.data instanceof ArrayBuffer ? evt.data : new TextEncoder().encode(evt.data).buffer;
121
+ const result = this.decoder.decode(data);
122
+ for (const value of this.messageQueues) {
123
+ if (value instanceof Pair.Pair && value.second(result)) {
124
+ value.first.enqueue(result);
125
+ }
126
+ else if (Array.isArray(value)) {
127
+ value.push(result);
128
+ }
129
+ }
130
+ this.dataReadyEvent.set();
131
+ });
132
+ this.createSocket();
133
+ });
134
+ }
135
+ return this.openFuture;
136
+ }
137
+ /**
138
+ * Wait for the socket connection closed.
139
+ * @remark
140
+ * This doesn't actually attempt to close the socket, only waits for the connection to close
141
+ */
142
+ closedFuture() {
143
+ if (this.closeFuture)
144
+ return this.closeFuture;
145
+ throw new NetworkError.NetworkError(http.HTTPStatus.FORBIDDEN, "Stream not opened");
146
+ }
147
+ /**
148
+ * Closes the socket if currently open
149
+ */
150
+ close() {
151
+ var _a;
152
+ this.manuallyClosed = true;
153
+ (_a = this.getSocket()) === null || _a === void 0 ? void 0 : _a.close();
154
+ this.messageQueues = [];
155
+ this.signal.dispatchEvent(new CustomEvent("abort"));
156
+ }
157
+ /**
158
+ * Sends data via socket
159
+ * @param data
160
+ */
161
+ send(data) {
162
+ var _a;
163
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
164
+ (_a = this.getSocket()) === null || _a === void 0 ? void 0 : _a.send(data instanceof Blob ? yield data.arrayBuffer() : data);
165
+ });
166
+ }
167
+ streamView(lens, objectMaxSize, expiryPeriod) {
168
+ const queue = new Queue.Queue(objectMaxSize, expiryPeriod);
169
+ const tuple = Pair.pair(queue, lens);
170
+ this.messageQueues.push(tuple);
171
+ return queue.streamEntries.cancelOnSignal(this.signal).onCompletion(() => {
172
+ this.messageQueues = this.messageQueues.filter((v) => v !== tuple);
173
+ });
174
+ }
175
+ /**
176
+ * Gets the stream for messages received via this socket
177
+ */
178
+ stream() {
179
+ const queue = [];
180
+ this.messageQueues.push(queue);
181
+ return new stream.Stream((signal) => {
182
+ const data = queue.shift();
183
+ if (data === undefined) {
184
+ this.dataReadyEvent.clear();
185
+ return this.dataReadyEvent
186
+ .wait()
187
+ .thenApply(() => queue.shift())
188
+ .catch((error) => {
189
+ if (error instanceof FutureCancelled.FutureCancelled) {
190
+ return new stream_state.ExecutorState(true);
191
+ }
192
+ throw error;
193
+ })
194
+ .registerSignal(signal);
195
+ }
196
+ return data;
197
+ })
198
+ .cancelOnSignal(this.signal)
199
+ .onCompletion(() => {
200
+ this.messageQueues = this.messageQueues.filter((v) => v !== queue);
201
+ });
202
+ }
203
+ addEventListener(type, functor) {
204
+ this.socketListeners.push([type, functor]);
205
+ if (this.socket) {
206
+ this.socket.addEventListener(type, functor);
207
+ }
208
+ return () => {
209
+ this.socketListeners = this.socketListeners.filter(([t, f]) => f !== functor && t !== type);
210
+ if (this.socket)
211
+ this.socket.removeEventListener(type, functor);
212
+ };
213
+ }
214
+ createSocket() {
215
+ const socket = new WebSocket(this.url);
216
+ socket.binaryType = "arraybuffer";
217
+ this.socketListeners.forEach(([type, functor]) => socket.addEventListener(type, functor));
218
+ this.socket = socket;
219
+ future.Future.sleep(2)
220
+ .thenApply(() => {
221
+ if (socket.readyState === 0) {
222
+ socket.close();
223
+ const evt = new Event("error");
224
+ this.socketListeners.forEach(([type, functor]) => {
225
+ if (type === "error") {
226
+ functor(evt);
227
+ }
228
+ });
229
+ }
230
+ })
231
+ .schedule();
232
+ return socket;
233
+ }
234
+ getSocket() {
235
+ return this.socket;
236
+ }
237
+ }
238
+
239
+ exports.StreamableWebSocket = StreamableWebSocket;
package/socket.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ import { Stream } from "./stream";
2
+ import { Future, WaitPeriod } from "./future";
3
+ import { Decoder } from "./data/decoders";
4
+ interface WebSocketConfiguration {
5
+ retryOnDisconnect?: boolean;
6
+ cacheSize?: number;
7
+ cacheExpiryPeriod?: WaitPeriod;
8
+ exponentialFactor?: number;
9
+ backoffPeriodMs?: number;
10
+ }
11
+ /**
12
+ * Future-based web sockets
13
+ */
14
+ export declare class StreamableWebSocket<T> {
15
+ private readonly maxReconnectAttempt;
16
+ private readonly retryOnDisconnect;
17
+ private openFuture?;
18
+ private closeFuture?;
19
+ private socketListeners;
20
+ private messageQueues;
21
+ private readonly url;
22
+ private socket?;
23
+ private manuallyClosed;
24
+ private readonly cacheSize;
25
+ private readonly backoffPeriodMs;
26
+ private readonly exponentialFactor;
27
+ private readonly signal;
28
+ private backoffPeriods;
29
+ private readonly evt;
30
+ private readonly dataReadyEvent;
31
+ private readonly dataProcessingLock;
32
+ readonly decoder: Decoder<T>;
33
+ private connectionAttemptCount;
34
+ constructor(url: string, decoder: Decoder<T>, { retryOnDisconnect, cacheSize, cacheExpiryPeriod, exponentialFactor, backoffPeriodMs, }?: WebSocketConfiguration, maxReconnectAttempt?: number);
35
+ get opened(): boolean;
36
+ get closed(): boolean;
37
+ /**
38
+ * opens the current web socket connection
39
+ */
40
+ open(): Future<void>;
41
+ /**
42
+ * Wait for the socket connection closed.
43
+ * @remark
44
+ * This doesn't actually attempt to close the socket, only waits for the connection to close
45
+ */
46
+ closedFuture(): Future<void>;
47
+ /**
48
+ * Closes the socket if currently open
49
+ */
50
+ close(): void;
51
+ /**
52
+ * Sends data via socket
53
+ * @param data
54
+ */
55
+ send(data: string | ArrayBufferView | Blob | ArrayBufferLike): Promise<void>;
56
+ streamView(lens: (v: T) => boolean, objectMaxSize?: number, expiryPeriod?: WaitPeriod): Stream<T>;
57
+ /**
58
+ * Gets the stream for messages received via this socket
59
+ */
60
+ stream(): Stream<T>;
61
+ private addEventListener;
62
+ private createSocket;
63
+ private getSocket;
64
+ }
65
+ export {};
package/socket.mjs ADDED
@@ -0,0 +1,237 @@
1
+ import { __awaiter } from './_virtual/_tslib.mjs';
2
+ import { AbortError } from './errors/AbortError.mjs';
3
+ import { FutureCancelled } from './errors/FutureCancelled.mjs';
4
+ import { NetworkError } from './errors/NetworkError.mjs';
5
+ import './networking/decorators/options.mjs';
6
+ import './networking/decorators/requests.mjs';
7
+ import { HTTPStatus } from './networking/http.mjs';
8
+ import 'ramda';
9
+ import 'uuid';
10
+ import { Stream } from './stream.mjs';
11
+ import { Future } from './future/future.mjs';
12
+ import { FutureEvent, Lock } from './synchronize.mjs';
13
+ import { ExecutorState } from './stream/state.mjs';
14
+ import WebSocket from 'modern-isomorphic-ws';
15
+ import './data-structures/object/WatchableObject.mjs';
16
+ import 'object-hash';
17
+ import { Queue } from './data-structures/object/Queue.mjs';
18
+ import { Pair, pair } from './data-structures/array/Pair.mjs';
19
+
20
+ /**
21
+ * Future-based web sockets
22
+ */
23
+ class StreamableWebSocket {
24
+ constructor(url, decoder, { retryOnDisconnect, cacheSize, cacheExpiryPeriod, exponentialFactor, backoffPeriodMs, } = {}, maxReconnectAttempt = 3) {
25
+ this.maxReconnectAttempt = maxReconnectAttempt;
26
+ this.connectionAttemptCount = 0;
27
+ this.signal = new AbortController().signal;
28
+ this.decoder = decoder;
29
+ this.socketListeners = [];
30
+ this.url = url;
31
+ this.cacheSize = cacheSize !== null && cacheSize !== void 0 ? cacheSize : 10000;
32
+ this.manuallyClosed = false;
33
+ this.retryOnDisconnect = retryOnDisconnect !== null && retryOnDisconnect !== void 0 ? retryOnDisconnect : true;
34
+ this.exponentialFactor = exponentialFactor !== null && exponentialFactor !== void 0 ? exponentialFactor : 2;
35
+ this.backoffPeriodMs = backoffPeriodMs !== null && backoffPeriodMs !== void 0 ? backoffPeriodMs : 10;
36
+ this.backoffPeriods = -1;
37
+ this.messageQueues = [];
38
+ this.evt = new EventTarget();
39
+ this.dataReadyEvent = new FutureEvent();
40
+ this.dataProcessingLock = new Lock();
41
+ }
42
+ get opened() {
43
+ return this.socket && this.socket.readyState === WebSocket.OPEN;
44
+ }
45
+ get closed() {
46
+ return this.socket && this.socket.readyState === WebSocket.CLOSED;
47
+ }
48
+ /**
49
+ * opens the current web socket connection
50
+ */
51
+ open() {
52
+ var _a;
53
+ if (!this.openFuture || ((_a = this.openFuture) === null || _a === void 0 ? void 0 : _a.failed)) {
54
+ this.closeFuture = new Future((resolve, reject, signal) => {
55
+ this.signal.addEventListener("abort", () => {
56
+ resolve();
57
+ });
58
+ signal.onabort = () => {
59
+ this.signal.removeEventListener("abort", resolve);
60
+ reject(new AbortError());
61
+ };
62
+ }).schedule();
63
+ this.openFuture = new Future((resolve, reject, signal) => {
64
+ const functor = () => {
65
+ this.close();
66
+ };
67
+ signal.addEventListener("abort", functor);
68
+ let retrying = false;
69
+ const cancelError = this.addEventListener("error", () => __awaiter(this, void 0, void 0, function* () {
70
+ var _a, _b;
71
+ if (this.retryOnDisconnect && !signal.aborted && this.connectionAttemptCount < this.maxReconnectAttempt) {
72
+ this.connectionAttemptCount++;
73
+ retrying = true;
74
+ (_a = this.getSocket()) === null || _a === void 0 ? void 0 : _a.close();
75
+ yield Future.sleep({
76
+ milliseconds: this.backoffPeriodMs * Math.pow(this.exponentialFactor, ++this.backoffPeriods),
77
+ });
78
+ this.createSocket();
79
+ }
80
+ else {
81
+ this.connectionAttemptCount = 0;
82
+ retrying = false;
83
+ cancelError();
84
+ cancelOpen();
85
+ reject(new NetworkError(HTTPStatus.EXPECTATION_FAILED));
86
+ (_b = this.getSocket()) === null || _b === void 0 ? void 0 : _b.close();
87
+ }
88
+ }));
89
+ const cancelOpen = this.addEventListener("open", () => {
90
+ this.connectionAttemptCount = 0;
91
+ this.backoffPeriods = -1;
92
+ retrying = false;
93
+ resolve();
94
+ signal.removeEventListener("abort", functor);
95
+ cancelError();
96
+ cancelOpen();
97
+ });
98
+ const cancelClose = this.addEventListener("close", () => {
99
+ if (retrying)
100
+ return;
101
+ if (!this.manuallyClosed && this.retryOnDisconnect && !signal.aborted) {
102
+ delete this.openFuture;
103
+ cancelError();
104
+ cancelOpen();
105
+ cancelClose();
106
+ this.open()
107
+ .thenApply(() => resolve())
108
+ .catch(reject);
109
+ }
110
+ else {
111
+ retrying = false;
112
+ this.signal.dispatchEvent(new CustomEvent("abort"));
113
+ cancelQueue();
114
+ reject(new NetworkError(HTTPStatus.EXPECTATION_FAILED));
115
+ }
116
+ });
117
+ const cancelQueue = this.addEventListener("message", (evt) => {
118
+ const data = evt.data instanceof ArrayBuffer ? evt.data : new TextEncoder().encode(evt.data).buffer;
119
+ const result = this.decoder.decode(data);
120
+ for (const value of this.messageQueues) {
121
+ if (value instanceof Pair && value.second(result)) {
122
+ value.first.enqueue(result);
123
+ }
124
+ else if (Array.isArray(value)) {
125
+ value.push(result);
126
+ }
127
+ }
128
+ this.dataReadyEvent.set();
129
+ });
130
+ this.createSocket();
131
+ });
132
+ }
133
+ return this.openFuture;
134
+ }
135
+ /**
136
+ * Wait for the socket connection closed.
137
+ * @remark
138
+ * This doesn't actually attempt to close the socket, only waits for the connection to close
139
+ */
140
+ closedFuture() {
141
+ if (this.closeFuture)
142
+ return this.closeFuture;
143
+ throw new NetworkError(HTTPStatus.FORBIDDEN, "Stream not opened");
144
+ }
145
+ /**
146
+ * Closes the socket if currently open
147
+ */
148
+ close() {
149
+ var _a;
150
+ this.manuallyClosed = true;
151
+ (_a = this.getSocket()) === null || _a === void 0 ? void 0 : _a.close();
152
+ this.messageQueues = [];
153
+ this.signal.dispatchEvent(new CustomEvent("abort"));
154
+ }
155
+ /**
156
+ * Sends data via socket
157
+ * @param data
158
+ */
159
+ send(data) {
160
+ var _a;
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ (_a = this.getSocket()) === null || _a === void 0 ? void 0 : _a.send(data instanceof Blob ? yield data.arrayBuffer() : data);
163
+ });
164
+ }
165
+ streamView(lens, objectMaxSize, expiryPeriod) {
166
+ const queue = new Queue(objectMaxSize, expiryPeriod);
167
+ const tuple = pair(queue, lens);
168
+ this.messageQueues.push(tuple);
169
+ return queue.streamEntries.cancelOnSignal(this.signal).onCompletion(() => {
170
+ this.messageQueues = this.messageQueues.filter((v) => v !== tuple);
171
+ });
172
+ }
173
+ /**
174
+ * Gets the stream for messages received via this socket
175
+ */
176
+ stream() {
177
+ const queue = [];
178
+ this.messageQueues.push(queue);
179
+ return new Stream((signal) => {
180
+ const data = queue.shift();
181
+ if (data === undefined) {
182
+ this.dataReadyEvent.clear();
183
+ return this.dataReadyEvent
184
+ .wait()
185
+ .thenApply(() => queue.shift())
186
+ .catch((error) => {
187
+ if (error instanceof FutureCancelled) {
188
+ return new ExecutorState(true);
189
+ }
190
+ throw error;
191
+ })
192
+ .registerSignal(signal);
193
+ }
194
+ return data;
195
+ })
196
+ .cancelOnSignal(this.signal)
197
+ .onCompletion(() => {
198
+ this.messageQueues = this.messageQueues.filter((v) => v !== queue);
199
+ });
200
+ }
201
+ addEventListener(type, functor) {
202
+ this.socketListeners.push([type, functor]);
203
+ if (this.socket) {
204
+ this.socket.addEventListener(type, functor);
205
+ }
206
+ return () => {
207
+ this.socketListeners = this.socketListeners.filter(([t, f]) => f !== functor && t !== type);
208
+ if (this.socket)
209
+ this.socket.removeEventListener(type, functor);
210
+ };
211
+ }
212
+ createSocket() {
213
+ const socket = new WebSocket(this.url);
214
+ socket.binaryType = "arraybuffer";
215
+ this.socketListeners.forEach(([type, functor]) => socket.addEventListener(type, functor));
216
+ this.socket = socket;
217
+ Future.sleep(2)
218
+ .thenApply(() => {
219
+ if (socket.readyState === 0) {
220
+ socket.close();
221
+ const evt = new Event("error");
222
+ this.socketListeners.forEach(([type, functor]) => {
223
+ if (type === "error") {
224
+ functor(evt);
225
+ }
226
+ });
227
+ }
228
+ })
229
+ .schedule();
230
+ return socket;
231
+ }
232
+ getSocket() {
233
+ return this.socket;
234
+ }
235
+ }
236
+
237
+ export { StreamableWebSocket };
package/store.cjs ADDED
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ var manager = require('./data/store/manager.cjs');
4
+ var web = require('./data/store/web.cjs');
5
+ var json = require('./data/store/json.cjs');
6
+
7
+
8
+
9
+ exports.CacheManager = manager.CacheManager;
10
+ exports.LocalWebStore = web.LocalWebStore;
11
+ exports.SessionWebStore = web.SessionWebStore;
12
+ exports.JSONFileStore = json.JSONFileStore;
package/store.mjs ADDED
@@ -0,0 +1,3 @@
1
+ export { CacheManager } from './data/store/manager.mjs';
2
+ export { LocalWebStore, SessionWebStore } from './data/store/web.mjs';
3
+ export { JSONFileStore } from './data/store/json.mjs';