@muspellheim/shared 0.8.3 → 0.9.2

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.
package/dist/shared.d.ts CHANGED
@@ -4,20 +4,20 @@
4
4
  export declare class Clock {
5
5
  #private;
6
6
  /**
7
- * Creates a clock using system the clock.
7
+ * Create a clock using system the clock.
8
8
  *
9
9
  * @return A clock that uses the system clock.
10
10
  */
11
11
  static system(): Clock;
12
12
  /**
13
- * Creates a clock using a fixed date.
13
+ * Create a clock using a fixed date.
14
14
  *
15
15
  * @param date The fixed date of the clock.
16
16
  * @return A clock that always returns a fixed date.
17
17
  */
18
18
  static fixed(date: Date | string | number): Clock;
19
19
  /**
20
- * Creates a clock that returns a fixed offset from the given clock.
20
+ * Create a clock that returns a fixed offset from the given clock.
21
21
  *
22
22
  * @param clock The clock to offset from.
23
23
  * @param offsetMillis The offset in milliseconds.
@@ -26,13 +26,13 @@ export declare class Clock {
26
26
  static offset(clock: Clock, offsetMillis: number): Clock;
27
27
  private constructor();
28
28
  /**
29
- * Returns the current timestamp of the clock.
29
+ * Return the current timestamp of the clock.
30
30
  *
31
31
  * @return The current timestamp.
32
32
  */
33
33
  date(): Date;
34
34
  /**
35
- * Returns the current timestamp of the clock in milliseconds.
35
+ * Return the current timestamp of the clock in milliseconds.
36
36
  *
37
37
  * @return The current timestamp in milliseconds.
38
38
  */
@@ -138,13 +138,13 @@ export declare class ConsoleStub extends EventTarget {
138
138
  debug(...data: unknown[]): void;
139
139
  trace(...data: unknown[]): void;
140
140
  /**
141
- * Tracks console messages.
141
+ * Track the console messages.
142
142
  */
143
143
  trackMessages(): OutputTracker<unknown>;
144
144
  }
145
145
 
146
146
  /**
147
- * Creates a fetch stub.
147
+ * Create a fetch stub.
148
148
  *
149
149
  * The stub returns a response from the provided response data or throws an provided error.
150
150
  *
@@ -202,21 +202,21 @@ export declare interface Log {
202
202
  */
203
203
  export declare interface MessageClient extends EventTarget {
204
204
  /**
205
- * Returns whether the client is connected.
205
+ * Return whether the client is connected.
206
206
  */
207
207
  get isConnected(): boolean;
208
208
  /**
209
- * Returns the server URL.
209
+ * Return the server URL.
210
210
  */
211
211
  get url(): string | undefined;
212
212
  /**
213
- * Connects to the server.
213
+ * Connect to the server.
214
214
  *
215
215
  * @param url The server URL to connect to.
216
216
  */
217
217
  connect(url: string | URL): Promise<void>;
218
218
  /**
219
- * Sends a message to the server.
219
+ * Send a message to the server.
220
220
  *
221
221
  * This is an optional method for streams with bidirectional communication.
222
222
  *
@@ -225,13 +225,13 @@ export declare interface MessageClient extends EventTarget {
225
225
  */
226
226
  send(message: string, type?: string): Promise<void>;
227
227
  /**
228
- * Closes the connection.
228
+ * Close the connection.
229
229
  */
230
230
  close(): Promise<void>;
231
231
  }
232
232
 
233
233
  /**
234
- * Tracks output events.
234
+ * Track output events.
235
235
  *
236
236
  * This is one of the nullability patterns from James Shore's article on
237
237
  * [testing without mocks](https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#output-tracking).
@@ -260,33 +260,33 @@ export declare interface MessageClient extends EventTarget {
260
260
  export declare class OutputTracker<T> {
261
261
  #private;
262
262
  /**
263
- * Creates a tracker for a specific event of an event target.
263
+ * Create a tracker for a specific event of an event target.
264
264
  *
265
265
  * @param eventTarget The target to track.
266
266
  * @param event The event name to track.
267
267
  */
268
268
  static create<T>(eventTarget: EventTarget, event: string): OutputTracker<T>;
269
269
  /**
270
- * Creates a tracker for a specific event of an event target.
270
+ * Create a tracker for a specific event of an event target.
271
271
  *
272
272
  * @param eventTarget The target to track.
273
273
  * @param event The event name to track.
274
274
  */
275
275
  constructor(eventTarget: EventTarget, event: string);
276
276
  /**
277
- * Returns the tracked data.
277
+ * Return the tracked data.
278
278
  *
279
279
  * @return The tracked data.
280
280
  */
281
281
  get data(): T[];
282
282
  /**
283
- * Clears the tracked data and returns the cleared data.
283
+ * Clear the tracked data and return the cleared data.
284
284
  *
285
285
  * @return The cleared data.
286
286
  */
287
287
  clear(): T[];
288
288
  /**
289
- * Stops tracking.
289
+ * Stop tracking.
290
290
  */
291
291
  stop(): void;
292
292
  }
@@ -309,13 +309,13 @@ export declare interface ResponseData {
309
309
  export declare class SseClient extends EventTarget implements MessageClient {
310
310
  #private;
311
311
  /**
312
- * Creates an SSE client.
312
+ * Create an SSE client.
313
313
  *
314
314
  * @return A new SSE client.
315
315
  */
316
316
  static create(): SseClient;
317
317
  /**
318
- * Creates a nulled SSE client.
318
+ * Create a nulled SSE client.
319
319
  *
320
320
  * @return A new SSE client.
321
321
  */
@@ -327,7 +327,7 @@ export declare class SseClient extends EventTarget implements MessageClient {
327
327
  send(_message: string, _type?: string): Promise<void>;
328
328
  close(): Promise<void>;
329
329
  /**
330
- * Simulates a message event from the server.
330
+ * Simulate a message event from the server.
331
331
  *
332
332
  * @param message The message to receive.
333
333
  * @param eventName The optional event type.
@@ -335,7 +335,7 @@ export declare class SseClient extends EventTarget implements MessageClient {
335
335
  */
336
336
  simulateMessage(message: string, eventName?: string, lastEventId?: string): void;
337
337
  /**
338
- * Simulates an error event.
338
+ * Simulate an error event.
339
339
  */
340
340
  simulateError(): void;
341
341
  }
@@ -353,32 +353,32 @@ export declare class Success {
353
353
  export declare class WebSocketClient extends EventTarget implements MessageClient {
354
354
  #private;
355
355
  /**
356
- * Creates a WebSocket client.
356
+ * Create a WebSocket client.
357
357
  *
358
358
  * @param options The options for the WebSocket client.
359
359
  * @return A new WebSocket client.
360
360
  */
361
- static create({ heartbeat }?: WebSocketOptions): WebSocketClient;
361
+ static create({ heartbeat, retry, }?: WebSocketOptions): WebSocketClient;
362
362
  /**
363
- * Creates a nulled WebSocket client.
363
+ * Create a nulled WebSocket client.
364
364
  *
365
365
  * @param options The options for the WebSocket client.
366
366
  * @return A new nulled WebSocket client.
367
367
  */
368
- static createNull({ heartbeat }?: WebSocketOptions): WebSocketClient;
368
+ static createNull({ heartbeat, retry }?: WebSocketOptions): WebSocketClient;
369
369
  private constructor();
370
370
  get isConnected(): boolean;
371
371
  get url(): string | undefined;
372
372
  connect(url: string | URL): Promise<void>;
373
373
  send(message: string): Promise<void>;
374
374
  /**
375
- * Returns a tracker for messages sent.
375
+ * Return a tracker for messages sent.
376
376
  *
377
377
  * @return A new output tracker.
378
378
  */
379
379
  trackMessageSent(): OutputTracker<string>;
380
380
  /**
381
- * Closes the connection.
381
+ * Close the connection.
382
382
  *
383
383
  * If a code is provided, also a reason should be provided.
384
384
  *
@@ -387,24 +387,24 @@ export declare class WebSocketClient extends EventTarget implements MessageClien
387
387
  */
388
388
  close(code?: number, reason?: string): Promise<void>;
389
389
  /**
390
- * Simulates a message event from the server.
390
+ * Simulate a message event from the server.
391
391
  *
392
392
  * @param message The message to receive.
393
393
  */
394
394
  simulateMessage(message: string): void;
395
395
  /**
396
- * Simulates a heartbeat.
396
+ * Simulate a heartbeat.
397
397
  */
398
398
  simulateHeartbeat(): void;
399
399
  /**
400
- * Simulates a close event.
400
+ * Simulate a close event.
401
401
  *
402
402
  * @param code An optional code.
403
403
  * @param reason An optional reason.
404
404
  */
405
405
  simulateClose(code?: number, reason?: string): void;
406
406
  /**
407
- * Simulates an error event.
407
+ * Simulate an error event.
408
408
  */
409
409
  simulateError(): void;
410
410
  }
@@ -418,6 +418,11 @@ export declare interface WebSocketOptions {
418
418
  * heartbeat.
419
419
  */
420
420
  heartbeat?: number;
421
+ /**
422
+ * The time in milliseconds to wait before retrying a connection after an
423
+ * error. A value <= 0 disables automatic retries.
424
+ */
425
+ retry?: number;
421
426
  }
422
427
 
423
428
  export { }
package/dist/shared.js CHANGED
@@ -1,6 +1,6 @@
1
1
  class c {
2
2
  /**
3
- * Creates a clock using system the clock.
3
+ * Create a clock using system the clock.
4
4
  *
5
5
  * @return A clock that uses the system clock.
6
6
  */
@@ -8,38 +8,38 @@ class c {
8
8
  return new c();
9
9
  }
10
10
  /**
11
- * Creates a clock using a fixed date.
11
+ * Create a clock using a fixed date.
12
12
  *
13
13
  * @param date The fixed date of the clock.
14
14
  * @return A clock that always returns a fixed date.
15
15
  */
16
16
  static fixed(t) {
17
- return new c(t);
17
+ return new c(new Date(t));
18
18
  }
19
19
  /**
20
- * Creates a clock that returns a fixed offset from the given clock.
20
+ * Create a clock that returns a fixed offset from the given clock.
21
21
  *
22
22
  * @param clock The clock to offset from.
23
23
  * @param offsetMillis The offset in milliseconds.
24
24
  * @return A clock that returns a fixed offset from the given clock.
25
25
  */
26
26
  static offset(t, e) {
27
- return new c(t.millis() + e);
27
+ return new c(new Date(t.millis() + e));
28
28
  }
29
- #s;
29
+ #e;
30
30
  constructor(t) {
31
- this.#s = t ? new Date(t) : void 0;
31
+ this.#e = t;
32
32
  }
33
33
  /**
34
- * Returns the current timestamp of the clock.
34
+ * Return the current timestamp of the clock.
35
35
  *
36
36
  * @return The current timestamp.
37
37
  */
38
38
  date() {
39
- return this.#s ? new Date(this.#s) : /* @__PURE__ */ new Date();
39
+ return this.#e ? new Date(this.#e) : /* @__PURE__ */ new Date();
40
40
  }
41
41
  /**
42
- * Returns the current timestamp of the clock in milliseconds.
42
+ * Return the current timestamp of the clock in milliseconds.
43
43
  *
44
44
  * @return The current timestamp in milliseconds.
45
45
  */
@@ -74,8 +74,8 @@ class h {
74
74
  });
75
75
  return Object.fromEntries(r);
76
76
  }
77
- #s;
78
77
  #e;
78
+ #t;
79
79
  /**
80
80
  * Create a list of responses (by providing an array), or a single repeating
81
81
  * response (by providing any other type). 'Name' is optional and used in
@@ -85,7 +85,7 @@ class h {
85
85
  * @param name An optional name for the responses.
86
86
  */
87
87
  constructor(t, e) {
88
- this.#s = e == null ? "" : ` in ${e}`, this.#e = Array.isArray(t) ? [...t] : t;
88
+ this.#e = e == null ? "" : ` in ${e}`, this.#t = Array.isArray(t) ? [...t] : t;
89
89
  }
90
90
  /**
91
91
  * Get the next configured response. Throws an error when configured with a list
@@ -94,15 +94,15 @@ class h {
94
94
  * @return The next response.
95
95
  */
96
96
  next() {
97
- const t = Array.isArray(this.#e) ? this.#e.shift() : this.#e;
97
+ const t = Array.isArray(this.#t) ? this.#t.shift() : this.#t;
98
98
  if (t === void 0)
99
- throw new Error(`No more responses configured${this.#s}.`);
99
+ throw new Error(`No more responses configured${this.#e}.`);
100
100
  return t;
101
101
  }
102
102
  }
103
103
  class u {
104
104
  /**
105
- * Creates a tracker for a specific event of an event target.
105
+ * Create a tracker for a specific event of an event target.
106
106
  *
107
107
  * @param eventTarget The target to track.
108
108
  * @param event The event name to track.
@@ -110,41 +110,41 @@ class u {
110
110
  static create(t, e) {
111
111
  return new u(t, e);
112
112
  }
113
- #s;
114
113
  #e;
115
114
  #t;
115
+ #s;
116
116
  #r;
117
117
  /**
118
- * Creates a tracker for a specific event of an event target.
118
+ * Create a tracker for a specific event of an event target.
119
119
  *
120
120
  * @param eventTarget The target to track.
121
121
  * @param event The event name to track.
122
122
  */
123
123
  constructor(t, e) {
124
- this.#s = t, this.#e = e, this.#t = [], this.#r = (s) => this.#t.push(s.detail), this.#s.addEventListener(this.#e, this.#r);
124
+ this.#e = t, this.#t = e, this.#s = [], this.#r = (s) => this.#s.push(s.detail), this.#e.addEventListener(this.#t, this.#r);
125
125
  }
126
126
  /**
127
- * Returns the tracked data.
127
+ * Return the tracked data.
128
128
  *
129
129
  * @return The tracked data.
130
130
  */
131
131
  get data() {
132
- return this.#t;
132
+ return this.#s;
133
133
  }
134
134
  /**
135
- * Clears the tracked data and returns the cleared data.
135
+ * Clear the tracked data and return the cleared data.
136
136
  *
137
137
  * @return The cleared data.
138
138
  */
139
139
  clear() {
140
- const t = [...this.#t];
141
- return this.#t.length = 0, t;
140
+ const t = [...this.#s];
141
+ return this.#s.length = 0, t;
142
142
  }
143
143
  /**
144
- * Stops tracking.
144
+ * Stop tracking.
145
145
  */
146
146
  stop() {
147
- this.#s.removeEventListener(this.#e, this.#r);
147
+ this.#e.removeEventListener(this.#t, this.#r);
148
148
  }
149
149
  }
150
150
  class y {
@@ -207,7 +207,7 @@ class f extends EventTarget {
207
207
  );
208
208
  }
209
209
  /**
210
- * Tracks console messages.
210
+ * Track the console messages.
211
211
  */
212
212
  trackMessages() {
213
213
  return new u(this, i);
@@ -223,39 +223,39 @@ function b(a) {
223
223
  };
224
224
  }
225
225
  class p {
226
- #s;
227
226
  #e;
228
227
  #t;
228
+ #s;
229
229
  constructor({ status: t, statusText: e, body: s = null }) {
230
- this.#s = t, this.#e = e, this.#t = s;
230
+ this.#e = t, this.#t = e, this.#s = s;
231
231
  }
232
232
  get ok() {
233
233
  return this.status >= 200 && this.status < 300;
234
234
  }
235
235
  get status() {
236
- return this.#s;
236
+ return this.#e;
237
237
  }
238
238
  get statusText() {
239
- return this.#e;
239
+ return this.#t;
240
240
  }
241
241
  async blob() {
242
- if (this.#t == null)
242
+ if (this.#s == null)
243
243
  return null;
244
- if (this.#t instanceof Blob)
245
- return this.#t;
244
+ if (this.#s instanceof Blob)
245
+ return this.#s;
246
246
  throw new TypeError("Body is not a Blob.");
247
247
  }
248
248
  async json() {
249
- const t = typeof this.#t == "string" ? this.#t : JSON.stringify(this.#t);
249
+ const t = typeof this.#s == "string" ? this.#s : JSON.stringify(this.#s);
250
250
  return Promise.resolve(JSON.parse(t));
251
251
  }
252
252
  async text() {
253
- return this.#t == null ? "" : String(this.#t);
253
+ return this.#s == null ? "" : String(this.#s);
254
254
  }
255
255
  }
256
256
  class d extends EventTarget {
257
257
  /**
258
- * Creates an SSE client.
258
+ * Create an SSE client.
259
259
  *
260
260
  * @return A new SSE client.
261
261
  */
@@ -263,23 +263,23 @@ class d extends EventTarget {
263
263
  return new d(EventSource);
264
264
  }
265
265
  /**
266
- * Creates a nulled SSE client.
266
+ * Create a nulled SSE client.
267
267
  *
268
268
  * @return A new SSE client.
269
269
  */
270
270
  static createNull() {
271
271
  return new d(o);
272
272
  }
273
- #s;
274
273
  #e;
274
+ #t;
275
275
  constructor(t) {
276
- super(), this.#s = t;
276
+ super(), this.#e = t;
277
277
  }
278
278
  get isConnected() {
279
- return this.#e?.readyState === this.#s.OPEN;
279
+ return this.#t?.readyState === this.#e.OPEN;
280
280
  }
281
281
  get url() {
282
- return this.#e?.url;
282
+ return this.#t?.url;
283
283
  }
284
284
  async connect(t, e = "message") {
285
285
  await new Promise((s, r) => {
@@ -288,12 +288,12 @@ class d extends EventTarget {
288
288
  return;
289
289
  }
290
290
  try {
291
- this.#e = new this.#s(t), this.#e.addEventListener("open", (n) => {
292
- this.#t(n), s();
293
- }), this.#e.addEventListener(
291
+ this.#t = new this.#e(t), this.#t.addEventListener("open", (n) => {
292
+ this.#s(n), s();
293
+ }), this.#t.addEventListener(
294
294
  e,
295
295
  (n) => this.#r(n)
296
- ), this.#e.addEventListener(
296
+ ), this.#t.addEventListener(
297
297
  "error",
298
298
  (n) => this.#n(n)
299
299
  );
@@ -312,14 +312,14 @@ class d extends EventTarget {
312
312
  return;
313
313
  }
314
314
  try {
315
- this.#e.close(), t();
315
+ this.#t.close(), t();
316
316
  } catch (s) {
317
317
  e(s);
318
318
  }
319
319
  });
320
320
  }
321
321
  /**
322
- * Simulates a message event from the server.
322
+ * Simulate a message event from the server.
323
323
  *
324
324
  * @param message The message to receive.
325
325
  * @param eventName The optional event type.
@@ -331,12 +331,12 @@ class d extends EventTarget {
331
331
  );
332
332
  }
333
333
  /**
334
- * Simulates an error event.
334
+ * Simulate an error event.
335
335
  */
336
336
  simulateError() {
337
337
  this.#n(new Event("error"));
338
338
  }
339
- #t(t) {
339
+ #s(t) {
340
340
  this.dispatchEvent(new t.constructor(t.type, t));
341
341
  }
342
342
  #r(t) {
@@ -365,54 +365,59 @@ class o extends EventTarget {
365
365
  }
366
366
  const g = "heartbeat", E = "message-sent";
367
367
  class l extends EventTarget {
368
- // TODO Recover connection with timeout after an error event.
369
368
  /**
370
- * Creates a WebSocket client.
369
+ * Create a WebSocket client.
371
370
  *
372
371
  * @param options The options for the WebSocket client.
373
372
  * @return A new WebSocket client.
374
373
  */
375
- static create({ heartbeat: t = 3e4 } = {}) {
376
- return new l(t, WebSocket);
374
+ static create({
375
+ heartbeat: t = 3e4,
376
+ retry: e = 1e3
377
+ } = {}) {
378
+ return new l(t, e, WebSocket);
377
379
  }
378
380
  /**
379
- * Creates a nulled WebSocket client.
381
+ * Create a nulled WebSocket client.
380
382
  *
381
383
  * @param options The options for the WebSocket client.
382
384
  * @return A new nulled WebSocket client.
383
385
  */
384
- static createNull({ heartbeat: t = -1 } = {}) {
386
+ static createNull({ heartbeat: t = 0, retry: e = 0 } = {}) {
385
387
  return new l(
386
388
  t,
389
+ e,
387
390
  m
388
391
  );
389
392
  }
390
- #s;
391
393
  #e;
392
394
  #t;
395
+ #s;
393
396
  #r;
394
- constructor(t, e) {
395
- super(), this.#s = t, this.#e = e;
397
+ #n;
398
+ #i;
399
+ constructor(t, e, s) {
400
+ super(), this.#e = t, this.#t = e, this.#s = s;
396
401
  }
397
402
  get isConnected() {
398
- return this.#t?.readyState === WebSocket.OPEN;
403
+ return this.#r?.readyState === WebSocket.OPEN;
399
404
  }
400
405
  get url() {
401
- return this.#t?.url;
406
+ return this.#r?.url;
402
407
  }
403
408
  async connect(t) {
404
409
  await new Promise((e, s) => {
405
- if (this.isConnected) {
410
+ if (this.#h(), this.isConnected) {
406
411
  s(new Error("Already connected."));
407
412
  return;
408
413
  }
409
414
  try {
410
- this.#t = new this.#e(t), this.#t.addEventListener("open", (r) => {
411
- this.#n(r), e();
412
- }), this.#t.addEventListener(
415
+ this.#r = new this.#s(t), this.#r.addEventListener("open", (r) => {
416
+ this.#d(r), e();
417
+ }), this.#r.addEventListener(
413
418
  "message",
414
- (r) => this.#i(r)
415
- ), this.#t.addEventListener("close", (r) => this.#a(r)), this.#t.addEventListener("error", (r) => this.#o(r));
419
+ (r) => this.#a(r)
420
+ ), this.#r.addEventListener("close", (r) => this.#o(r)), this.#r.addEventListener("error", (r) => this.#c(r));
416
421
  } catch (r) {
417
422
  s(r);
418
423
  }
@@ -421,12 +426,12 @@ class l extends EventTarget {
421
426
  async send(t) {
422
427
  if (!this.isConnected)
423
428
  throw new Error("Not connected.");
424
- this.#t.send(t), this.dispatchEvent(
429
+ this.#r.send(t), this.dispatchEvent(
425
430
  new CustomEvent(E, { detail: t })
426
431
  ), await Promise.resolve();
427
432
  }
428
433
  /**
429
- * Returns a tracker for messages sent.
434
+ * Return a tracker for messages sent.
430
435
  *
431
436
  * @return A new output tracker.
432
437
  */
@@ -434,7 +439,7 @@ class l extends EventTarget {
434
439
  return u.create(this, E);
435
440
  }
436
441
  /**
437
- * Closes the connection.
442
+ * Close the connection.
438
443
  *
439
444
  * If a code is provided, also a reason should be provided.
440
445
  *
@@ -443,68 +448,77 @@ class l extends EventTarget {
443
448
  */
444
449
  async close(t, e) {
445
450
  await new Promise((s) => {
446
- if (!this.isConnected) {
451
+ if (this.#h(), !this.isConnected) {
447
452
  s();
448
453
  return;
449
454
  }
450
- this.#t.addEventListener("close", () => s()), this.#t.close(t, e);
455
+ this.#r.addEventListener("close", () => s()), this.#r.close(t, e);
451
456
  });
452
457
  }
453
458
  /**
454
- * Simulates a message event from the server.
459
+ * Simulate a message event from the server.
455
460
  *
456
461
  * @param message The message to receive.
457
462
  */
458
463
  simulateMessage(t) {
459
- this.#i(new MessageEvent("message", { data: t }));
464
+ this.#a(new MessageEvent("message", { data: t }));
460
465
  }
461
466
  /**
462
- * Simulates a heartbeat.
467
+ * Simulate a heartbeat.
463
468
  */
464
469
  simulateHeartbeat() {
465
- this.#c();
470
+ this.#u();
466
471
  }
467
472
  /**
468
- * Simulates a close event.
473
+ * Simulate a close event.
469
474
  *
470
475
  * @param code An optional code.
471
476
  * @param reason An optional reason.
472
477
  */
473
478
  simulateClose(t, e) {
474
- this.#a(new CloseEvent("close", { code: t, reason: e }));
479
+ this.#o(new CloseEvent("close", { code: t, reason: e }));
475
480
  }
476
481
  /**
477
- * Simulates an error event.
482
+ * Simulate an error event.
478
483
  */
479
484
  simulateError() {
480
- this.#o(new Event("error"));
485
+ this.#r?.close(), this.#c(new Event("error"));
481
486
  }
482
- #n(t) {
483
- this.dispatchEvent(new t.constructor(t.type, t)), this.#h();
487
+ #d(t) {
488
+ this.dispatchEvent(new t.constructor(t.type, t)), this.#E();
484
489
  }
485
- #i(t) {
490
+ #a(t) {
486
491
  this.dispatchEvent(
487
492
  // @ts-expect-error create copy of event
488
493
  new t.constructor(t.type, t)
489
494
  );
490
495
  }
491
- #a(t) {
492
- this.#u(), this.dispatchEvent(new t.constructor(t.type, t));
493
- }
494
496
  #o(t) {
495
- this.dispatchEvent(new t.constructor(t.type, t));
497
+ this.#w(), this.dispatchEvent(new t.constructor(t.type, t));
498
+ }
499
+ #c(t) {
500
+ this.dispatchEvent(new t.constructor(t.type, t)), this.#l();
501
+ }
502
+ #l() {
503
+ this.#t <= 0 || (this.#i = setInterval(
504
+ () => this.connect(this.#r.url),
505
+ this.#t
506
+ ));
496
507
  }
497
508
  #h() {
498
- this.#s <= 0 || (this.#r = setInterval(
499
- () => this.#c(),
500
- this.#s
509
+ clearInterval(this.#i), this.#i = void 0;
510
+ }
511
+ #E() {
512
+ this.#e <= 0 || (this.#n = setInterval(
513
+ () => this.#u(),
514
+ this.#e
501
515
  ));
502
516
  }
503
- #u() {
504
- clearInterval(this.#r), this.#r = void 0;
517
+ #w() {
518
+ clearInterval(this.#n), this.#n = void 0;
505
519
  }
506
- #c() {
507
- this.#r != null && this.send(g);
520
+ #u() {
521
+ this.#n != null && this.send(g);
508
522
  }
509
523
  }
510
524
  class m extends EventTarget {
@@ -1 +1 @@
1
- (function(r,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(r=typeof globalThis<"u"?globalThis:r||self,a(r.Shared={}))})(this,(function(r){"use strict";class a{static system(){return new a}static fixed(t){return new a(t)}static offset(t,e){return new a(t.millis()+e)}#s;constructor(t){this.#s=t?new Date(t):void 0}date(){return this.#s?new Date(this.#s):new Date}millis(){return this.date().getTime()}}class h{static create(t,e){return new h(t,e)}static mapObject(t,e){const n=Object.entries(t).map(([i,b])=>{const C=e===void 0?void 0:`${e}: ${i}`;return[i,h.create(b,C)]});return Object.fromEntries(n)}#s;#e;constructor(t,e){this.#s=e==null?"":` in ${e}`,this.#e=Array.isArray(t)?[...t]:t}next(){const t=Array.isArray(this.#e)?this.#e.shift():this.#e;if(t===void 0)throw new Error(`No more responses configured${this.#s}.`);return t}}class u{static create(t,e){return new u(t,e)}#s;#e;#t;#r;constructor(t,e){this.#s=t,this.#e=e,this.#t=[],this.#r=s=>this.#t.push(s.detail),this.#s.addEventListener(this.#e,this.#r)}get data(){return this.#t}clear(){const t=[...this.#t];return this.#t.length=0,t}stop(){this.#s.removeEventListener(this.#e,this.#r)}}class g{isSuccess=!0}class p{isSuccess=!1;errorMessage;constructor(t){this.errorMessage=t}}const c="message";class m extends EventTarget{log(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"log",message:t}}))}error(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"error",message:t}}))}warn(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"warn",message:t}}))}info(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"info",message:t}}))}debug(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"debug",message:t}}))}trace(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"trace",message:t}}))}trackMessages(){return new u(this,c)}}function y(o){const t=h.create(o);return async function(){const e=t.next();if(e instanceof Error)throw e;return new S(e)}}class S{#s;#e;#t;constructor({status:t,statusText:e,body:s=null}){this.#s=t,this.#e=e,this.#t=s}get ok(){return this.status>=200&&this.status<300}get status(){return this.#s}get statusText(){return this.#e}async blob(){if(this.#t==null)return null;if(this.#t instanceof Blob)return this.#t;throw new TypeError("Body is not a Blob.")}async json(){const t=typeof this.#t=="string"?this.#t:JSON.stringify(this.#t);return Promise.resolve(JSON.parse(t))}async text(){return this.#t==null?"":String(this.#t)}}class l extends EventTarget{static create(){return new l(EventSource)}static createNull(){return new l(d)}#s;#e;constructor(t){super(),this.#s=t}get isConnected(){return this.#e?.readyState===this.#s.OPEN}get url(){return this.#e?.url}async connect(t,e="message"){await new Promise((s,n)=>{if(this.isConnected){n(new Error("Already connected."));return}try{this.#e=new this.#s(t),this.#e.addEventListener("open",i=>{this.#t(i),s()}),this.#e.addEventListener(e,i=>this.#r(i)),this.#e.addEventListener("error",i=>this.#n(i))}catch(i){n(i)}})}send(t,e){throw new Error("Method not implemented.")}async close(){await new Promise((t,e)=>{if(!this.isConnected){t();return}try{this.#e.close(),t()}catch(s){e(s)}})}simulateMessage(t,e="message",s){this.#r(new MessageEvent(e,{data:t,lastEventId:s}))}simulateError(){this.#n(new Event("error"))}#t(t){this.dispatchEvent(new t.constructor(t.type,t))}#r(t){this.dispatchEvent(new t.constructor(t.type,t))}#n(t){this.dispatchEvent(new t.constructor(t.type,t))}}class d extends EventTarget{static CONNECTING=0;static OPEN=1;static CLOSED=2;url;readyState=d.CONNECTING;constructor(t){super(),this.url=t.toString(),setTimeout(()=>{this.readyState=d.OPEN,this.dispatchEvent(new Event("open"))},0)}close(){this.readyState=d.CLOSED}}const w="heartbeat",v="message-sent";class E extends EventTarget{static create({heartbeat:t=3e4}={}){return new E(t,WebSocket)}static createNull({heartbeat:t=-1}={}){return new E(t,f)}#s;#e;#t;#r;constructor(t,e){super(),this.#s=t,this.#e=e}get isConnected(){return this.#t?.readyState===WebSocket.OPEN}get url(){return this.#t?.url}async connect(t){await new Promise((e,s)=>{if(this.isConnected){s(new Error("Already connected."));return}try{this.#t=new this.#e(t),this.#t.addEventListener("open",n=>{this.#n(n),e()}),this.#t.addEventListener("message",n=>this.#i(n)),this.#t.addEventListener("close",n=>this.#a(n)),this.#t.addEventListener("error",n=>this.#c(n))}catch(n){s(n)}})}async send(t){if(!this.isConnected)throw new Error("Not connected.");this.#t.send(t),this.dispatchEvent(new CustomEvent(v,{detail:t})),await Promise.resolve()}trackMessageSent(){return u.create(this,v)}async close(t,e){await new Promise(s=>{if(!this.isConnected){s();return}this.#t.addEventListener("close",()=>s()),this.#t.close(t,e)})}simulateMessage(t){this.#i(new MessageEvent("message",{data:t}))}simulateHeartbeat(){this.#o()}simulateClose(t,e){this.#a(new CloseEvent("close",{code:t,reason:e}))}simulateError(){this.#c(new Event("error"))}#n(t){this.dispatchEvent(new t.constructor(t.type,t)),this.#h()}#i(t){this.dispatchEvent(new t.constructor(t.type,t))}#a(t){this.#u(),this.dispatchEvent(new t.constructor(t.type,t))}#c(t){this.dispatchEvent(new t.constructor(t.type,t))}#h(){this.#s<=0||(this.#r=setInterval(()=>this.#o(),this.#s))}#u(){clearInterval(this.#r),this.#r=void 0}#o(){this.#r!=null&&this.send(w)}}class f extends EventTarget{url;readyState=WebSocket.CONNECTING;constructor(t){super(),this.url=t.toString(),setTimeout(()=>{this.readyState=WebSocket.OPEN,this.dispatchEvent(new Event("open"))},0)}send(){}close(){this.readyState=WebSocket.CLOSED,this.dispatchEvent(new Event("close"))}}r.Clock=a,r.ConfigurableResponses=h,r.ConsoleStub=m,r.Failure=p,r.HEARTBEAT_TYPE=w,r.OutputTracker=u,r.SseClient=l,r.Success=g,r.WebSocketClient=E,r.createFetchStub=y,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(r,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(r=typeof globalThis<"u"?globalThis:r||self,a(r.Shared={}))})(this,(function(r){"use strict";class a{static system(){return new a}static fixed(t){return new a(new Date(t))}static offset(t,e){return new a(new Date(t.millis()+e))}#e;constructor(t){this.#e=t}date(){return this.#e?new Date(this.#e):new Date}millis(){return this.date().getTime()}}class h{static create(t,e){return new h(t,e)}static mapObject(t,e){const n=Object.entries(t).map(([i,b])=>{const C=e===void 0?void 0:`${e}: ${i}`;return[i,h.create(b,C)]});return Object.fromEntries(n)}#e;#t;constructor(t,e){this.#e=e==null?"":` in ${e}`,this.#t=Array.isArray(t)?[...t]:t}next(){const t=Array.isArray(this.#t)?this.#t.shift():this.#t;if(t===void 0)throw new Error(`No more responses configured${this.#e}.`);return t}}class u{static create(t,e){return new u(t,e)}#e;#t;#s;#r;constructor(t,e){this.#e=t,this.#t=e,this.#s=[],this.#r=s=>this.#s.push(s.detail),this.#e.addEventListener(this.#t,this.#r)}get data(){return this.#s}clear(){const t=[...this.#s];return this.#s.length=0,t}stop(){this.#e.removeEventListener(this.#t,this.#r)}}class g{isSuccess=!0}class p{isSuccess=!1;errorMessage;constructor(t){this.errorMessage=t}}const c="message";class y extends EventTarget{log(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"log",message:t}}))}error(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"error",message:t}}))}warn(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"warn",message:t}}))}info(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"info",message:t}}))}debug(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"debug",message:t}}))}trace(...t){this.dispatchEvent(new CustomEvent(c,{detail:{level:"trace",message:t}}))}trackMessages(){return new u(this,c)}}function m(o){const t=h.create(o);return async function(){const e=t.next();if(e instanceof Error)throw e;return new S(e)}}class S{#e;#t;#s;constructor({status:t,statusText:e,body:s=null}){this.#e=t,this.#t=e,this.#s=s}get ok(){return this.status>=200&&this.status<300}get status(){return this.#e}get statusText(){return this.#t}async blob(){if(this.#s==null)return null;if(this.#s instanceof Blob)return this.#s;throw new TypeError("Body is not a Blob.")}async json(){const t=typeof this.#s=="string"?this.#s:JSON.stringify(this.#s);return Promise.resolve(JSON.parse(t))}async text(){return this.#s==null?"":String(this.#s)}}class l extends EventTarget{static create(){return new l(EventSource)}static createNull(){return new l(d)}#e;#t;constructor(t){super(),this.#e=t}get isConnected(){return this.#t?.readyState===this.#e.OPEN}get url(){return this.#t?.url}async connect(t,e="message"){await new Promise((s,n)=>{if(this.isConnected){n(new Error("Already connected."));return}try{this.#t=new this.#e(t),this.#t.addEventListener("open",i=>{this.#s(i),s()}),this.#t.addEventListener(e,i=>this.#r(i)),this.#t.addEventListener("error",i=>this.#n(i))}catch(i){n(i)}})}send(t,e){throw new Error("Method not implemented.")}async close(){await new Promise((t,e)=>{if(!this.isConnected){t();return}try{this.#t.close(),t()}catch(s){e(s)}})}simulateMessage(t,e="message",s){this.#r(new MessageEvent(e,{data:t,lastEventId:s}))}simulateError(){this.#n(new Event("error"))}#s(t){this.dispatchEvent(new t.constructor(t.type,t))}#r(t){this.dispatchEvent(new t.constructor(t.type,t))}#n(t){this.dispatchEvent(new t.constructor(t.type,t))}}class d extends EventTarget{static CONNECTING=0;static OPEN=1;static CLOSED=2;url;readyState=d.CONNECTING;constructor(t){super(),this.url=t.toString(),setTimeout(()=>{this.readyState=d.OPEN,this.dispatchEvent(new Event("open"))},0)}close(){this.readyState=d.CLOSED}}const w="heartbeat",v="message-sent";class E extends EventTarget{static create({heartbeat:t=3e4,retry:e=1e3}={}){return new E(t,e,WebSocket)}static createNull({heartbeat:t=0,retry:e=0}={}){return new E(t,e,f)}#e;#t;#s;#r;#n;#i;constructor(t,e,s){super(),this.#e=t,this.#t=e,this.#s=s}get isConnected(){return this.#r?.readyState===WebSocket.OPEN}get url(){return this.#r?.url}async connect(t){await new Promise((e,s)=>{if(this.#h(),this.isConnected){s(new Error("Already connected."));return}try{this.#r=new this.#s(t),this.#r.addEventListener("open",n=>{this.#d(n),e()}),this.#r.addEventListener("message",n=>this.#a(n)),this.#r.addEventListener("close",n=>this.#c(n)),this.#r.addEventListener("error",n=>this.#o(n))}catch(n){s(n)}})}async send(t){if(!this.isConnected)throw new Error("Not connected.");this.#r.send(t),this.dispatchEvent(new CustomEvent(v,{detail:t})),await Promise.resolve()}trackMessageSent(){return u.create(this,v)}async close(t,e){await new Promise(s=>{if(this.#h(),!this.isConnected){s();return}this.#r.addEventListener("close",()=>s()),this.#r.close(t,e)})}simulateMessage(t){this.#a(new MessageEvent("message",{data:t}))}simulateHeartbeat(){this.#u()}simulateClose(t,e){this.#c(new CloseEvent("close",{code:t,reason:e}))}simulateError(){this.#r?.close(),this.#o(new Event("error"))}#d(t){this.dispatchEvent(new t.constructor(t.type,t)),this.#E()}#a(t){this.dispatchEvent(new t.constructor(t.type,t))}#c(t){this.#w(),this.dispatchEvent(new t.constructor(t.type,t))}#o(t){this.dispatchEvent(new t.constructor(t.type,t)),this.#l()}#l(){this.#t<=0||(this.#i=setInterval(()=>this.connect(this.#r.url),this.#t))}#h(){clearInterval(this.#i),this.#i=void 0}#E(){this.#e<=0||(this.#n=setInterval(()=>this.#u(),this.#e))}#w(){clearInterval(this.#n),this.#n=void 0}#u(){this.#n!=null&&this.send(w)}}class f extends EventTarget{url;readyState=WebSocket.CONNECTING;constructor(t){super(),this.url=t.toString(),setTimeout(()=>{this.readyState=WebSocket.OPEN,this.dispatchEvent(new Event("open"))},0)}send(){}close(){this.readyState=WebSocket.CLOSED,this.dispatchEvent(new Event("close"))}}r.Clock=a,r.ConfigurableResponses=h,r.ConsoleStub=y,r.Failure=p,r.HEARTBEAT_TYPE=w,r.OutputTracker=u,r.SseClient=l,r.Success=g,r.WebSocketClient=E,r.createFetchStub=m,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muspellheim/shared",
3
- "version": "0.8.3",
3
+ "version": "0.9.2",
4
4
  "author": "Falko Schumann",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -25,15 +25,15 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "@eslint/js": "9.35.0",
28
- "@types/node": "22.16.5",
28
+ "@types/node": "22.18.3",
29
29
  "@vitest/coverage-v8": "3.2.4",
30
30
  "eslint": "9.35.0",
31
31
  "eslint-plugin-headers": "1.3.3",
32
32
  "jsdom": "27.0.0",
33
33
  "globals": "16.4.0",
34
34
  "prettier": "3.6.2",
35
- "typedoc": "0.28.12",
36
- "typescript": "5.8.3",
35
+ "typedoc": "0.28.13",
36
+ "typescript": "5.9.2",
37
37
  "typescript-eslint": "8.43.0",
38
38
  "vite": "7.1.5",
39
39
  "vitest": "3.2.4",