@muspellheim/shared 0.6.1 → 0.7.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 (46) hide show
  1. package/LICENSE.txt +1 -1
  2. package/README.md +11 -13
  3. package/dist/shared.d.ts +423 -0
  4. package/dist/shared.js +535 -0
  5. package/dist/shared.umd.cjs +1 -0
  6. package/package.json +27 -23
  7. package/.prettierignore +0 -3
  8. package/.prettierrc +0 -5
  9. package/deno.json +0 -15
  10. package/deno.mk +0 -68
  11. package/eslint.config.js +0 -23
  12. package/lib/assert.js +0 -15
  13. package/lib/browser/components.js +0 -165
  14. package/lib/browser/index.js +0 -3
  15. package/lib/color.js +0 -137
  16. package/lib/configurable-responses.js +0 -69
  17. package/lib/feature-toggle.js +0 -9
  18. package/lib/health.js +0 -510
  19. package/lib/index.js +0 -23
  20. package/lib/lang.js +0 -100
  21. package/lib/logging.js +0 -599
  22. package/lib/long-polling-client.js +0 -186
  23. package/lib/message-client.js +0 -68
  24. package/lib/messages.js +0 -68
  25. package/lib/metrics.js +0 -120
  26. package/lib/node/actuator-controller.js +0 -102
  27. package/lib/node/configuration-properties.js +0 -291
  28. package/lib/node/handler.js +0 -25
  29. package/lib/node/index.js +0 -9
  30. package/lib/node/logging.js +0 -60
  31. package/lib/node/long-polling.js +0 -83
  32. package/lib/node/sse-emitter.js +0 -104
  33. package/lib/node/static-files-controller.js +0 -15
  34. package/lib/output-tracker.js +0 -89
  35. package/lib/service-locator.js +0 -44
  36. package/lib/sse-client.js +0 -163
  37. package/lib/stop-watch.js +0 -54
  38. package/lib/store.js +0 -129
  39. package/lib/time.js +0 -445
  40. package/lib/util.js +0 -380
  41. package/lib/validation.js +0 -290
  42. package/lib/vector.js +0 -194
  43. package/lib/vitest/equality-testers.js +0 -19
  44. package/lib/vitest/index.js +0 -1
  45. package/lib/web-socket-client.js +0 -262
  46. package/tsconfig.json +0 -13
package/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023-2024 Falko Schumann
3
+ Copyright (c) 2025 Falko Schumann
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -3,32 +3,30 @@
3
3
  [![Build](https://github.com/falkoschumann/muspellheim-utils-javascript/actions/workflows/build.yml/badge.svg)](https://github.com/falkoschumann/muspellheim-utils-javascript/actions/workflows/build.yml)
4
4
  [![NPM Version](https://img.shields.io/npm/v/%40muspellheim%2Fshared)](https://www.npmjs.com/package/@muspellheim/shared)
5
5
 
6
- Some shared modules for the browser and Node from my projects.
6
+ Some shared modules from my projects.
7
7
 
8
8
  ## Installation
9
9
 
10
- npm install @muspellheim/shared
10
+ ```bash
11
+ npm install @muspellheim/shared
12
+ ```
11
13
 
12
14
  ## Usage
13
15
 
14
- import { XXX } from '@muspellheim/shared';
15
- import { XXX } from '@muspellheim/shared/browser';
16
- import { XXX } from '@muspellheim/shared/node';
16
+ ```typescript
17
+ import { ConfigurableResponses, OutputTracker } from "@muspellheim/shared";
18
+ ```
17
19
 
18
- See https://falkoschumann.github.io/muspellheim-shared-javascript/
20
+ See more at https://falkoschumann.github.io/muspellheim-shared-js/
19
21
 
20
22
  ## Contributing
21
23
 
22
- The `Makefile` runs the build as default task. Other tasks are
24
+ The `Makefile` runs the build as the default task. Other tasks are
23
25
 
24
26
  - `test`: run all tests,
25
27
  - `format`: format source code
26
28
 
27
29
  ## Credits
28
30
 
29
- ## Open issues
30
-
31
- - [ ] Add missing docs
32
- - [ ] Use asserts for parameters
33
- - [ ] Rename project to `muspellheim-shared-js`
34
- - [ ] Use equatable protocol for value objects
31
+ - [Testing Without Mocks](https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks),
32
+ Copyright 2023 Titanium I.T. LLC. MIT License.
@@ -0,0 +1,423 @@
1
+ /**
2
+ * A clock provides access to the current timestamp.
3
+ */
4
+ export declare class Clock {
5
+ #private;
6
+ /**
7
+ * Creates a clock using system the clock.
8
+ *
9
+ * @return A clock that uses the system clock.
10
+ */
11
+ static system(): Clock;
12
+ /**
13
+ * Creates a clock using a fixed date.
14
+ *
15
+ * @param date The fixed date of the clock.
16
+ * @return A clock that always returns a fixed date.
17
+ */
18
+ static fixed(date: Date | string | number): Clock;
19
+ /**
20
+ * Creates a clock that returns a fixed offset from the given clock.
21
+ *
22
+ * @param clock The clock to offset from.
23
+ * @param offsetMillis The offset in milliseconds.
24
+ * @return A clock that returns a fixed offset from the given clock.
25
+ */
26
+ static offset(clock: Clock, offsetMillis: number): Clock;
27
+ private constructor();
28
+ /**
29
+ * Returns the current timestamp of the clock.
30
+ *
31
+ * @return The current timestamp.
32
+ */
33
+ date(): Date;
34
+ /**
35
+ * Returns the current timestamp of the clock in milliseconds.
36
+ *
37
+ * @return The current timestamp in milliseconds.
38
+ */
39
+ millis(): number;
40
+ }
41
+
42
+ /**
43
+ * Provides CQNS features.
44
+ *
45
+ * The Command Query Notification Separation principle is a software design
46
+ * principle that separates the concerns of commands, queries, and
47
+ * notifications.
48
+ *
49
+ * Message hierarchy:
50
+ *
51
+ * - Message
52
+ * - Incoming / outgoing
53
+ * - Request (outgoing) -> response (incoming)
54
+ * - Command -> command status
55
+ * - Query -> query result
56
+ * - Notification
57
+ * - Incoming: notification -> commands
58
+ * - Outgoing
59
+ * - Event (internal)
60
+ *
61
+ * @see https://ralfw.de/command-query-notification-separation-cqns/
62
+ * @module
63
+ */
64
+ /**
65
+ * The status returned by a command handler.
66
+ */
67
+ export declare type CommandStatus = Success | Failure;
68
+
69
+ /**
70
+ * Handle returning pre-configured responses.
71
+ *
72
+ * This is one of the nullability patterns from James Shore's article on
73
+ * [testing without mocks](https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#configurable-responses).
74
+ *
75
+ * Example usage for stubbing `fetch` function:
76
+ *
77
+ * ```javascript
78
+ * function createFetchStub(responses) {
79
+ * const configurableResponses = ConfigurableResponses.create(responses);
80
+ * return async function () {
81
+ * const response = configurableResponses.next();
82
+ * return {
83
+ * status: response.status,
84
+ * json: async () => response.body,
85
+ * };
86
+ * };
87
+ * }
88
+ * ```
89
+ */
90
+ export declare class ConfigurableResponses<T> {
91
+ #private;
92
+ /**
93
+ * Create a list of responses (by providing an array), or a single repeating
94
+ * response (by providing any other type). 'Name' is optional and used in
95
+ * error messages.
96
+ *
97
+ * @param responses A single response or an array of responses.
98
+ * @param name An optional name for the responses.
99
+ */
100
+ static create<T>(responses?: T | T[], name?: string): ConfigurableResponses<T>;
101
+ /**
102
+ * Convert all properties in an object into ConfigurableResponse instances.
103
+ * For example, { a: 1 } becomes { a: ConfigurableResponses.create(1) }.
104
+ * 'Name' is optional and used in error messages.
105
+ *
106
+ * @param responseObject An object with single response or an array of responses.
107
+ * @param name An optional name for the responses.
108
+ */
109
+ static mapObject<T extends Record<string, unknown>>(responseObject: T, name?: string): any;
110
+ /**
111
+ * Create a list of responses (by providing an array), or a single repeating
112
+ * response (by providing any other type). 'Name' is optional and used in
113
+ * error messages.
114
+ *
115
+ * @param responses A single response or an array of responses.
116
+ * @param name An optional name for the responses.
117
+ */
118
+ constructor(responses?: T | T[], name?: string);
119
+ /**
120
+ * Get the next configured response. Throws an error when configured with a list
121
+ * of responses and no more responses remain.
122
+ *
123
+ * @return The next response.
124
+ */
125
+ next(): T;
126
+ }
127
+
128
+ /**
129
+ * A stub for the console interface.
130
+ *
131
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Console_API
132
+ */
133
+ export declare class ConsoleStub extends EventTarget {
134
+ log(...data: unknown[]): void;
135
+ error(...data: unknown[]): void;
136
+ warn(...data: unknown[]): void;
137
+ info(...data: unknown[]): void;
138
+ debug(...data: unknown[]): void;
139
+ trace(...data: unknown[]): void;
140
+ /**
141
+ * Tracks console messages.
142
+ */
143
+ trackMessages(): OutputTracker<unknown>;
144
+ }
145
+
146
+ /**
147
+ * Creates a fetch stub.
148
+ *
149
+ * The stub returns a response from the provided response data or throws an provided error.
150
+ *
151
+ * @param responses A single response or an array of responses.
152
+ * @returns The fetch stub.
153
+ */
154
+ export declare function createFetchStub(responses?: ResponseData | Error | (ResponseData | Error)[]): () => Promise<Response>;
155
+
156
+ /**
157
+ * A failed status.
158
+ */
159
+ export declare class Failure {
160
+ readonly isSuccess = false;
161
+ errorMessage: string;
162
+ /**
163
+ * Creates a failed status.
164
+ *
165
+ * @param errorMessage
166
+ */
167
+ constructor(errorMessage: string);
168
+ }
169
+
170
+ export declare const HEARTBEAT_TYPE = "heartbeat";
171
+
172
+ /**
173
+ * A simple logging facade.
174
+ *
175
+ * This is a subset of the `console` interface.
176
+ *
177
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/Console_API
178
+ */
179
+ export declare interface Log {
180
+ log(...data: unknown[]): void;
181
+ error(...data: unknown[]): void;
182
+ warn(...data: unknown[]): void;
183
+ info(...data: unknown[]): void;
184
+ debug(...data: unknown[]): void;
185
+ trace(...data: unknown[]): void;
186
+ }
187
+
188
+ /**
189
+ * An interface for a streaming message client.
190
+ *
191
+ * Emits the following events:
192
+ *
193
+ * - open, {@link Event}
194
+ * - message, {@link MessageEvent}
195
+ * - error, {@link Event}
196
+ * - close, optional {@link CloseEvent}
197
+ *
198
+ * It is used for wrappers around {@link EventSource} and {@link WebSocket}.
199
+ *
200
+ * @see {@link SseClient}
201
+ * @see {@link WebSocketClient}
202
+ */
203
+ export declare interface MessageClient extends EventTarget {
204
+ /**
205
+ * Returns whether the client is connected.
206
+ */
207
+ get isConnected(): boolean;
208
+ /**
209
+ * Returns the server URL.
210
+ */
211
+ get url(): string | undefined;
212
+ /**
213
+ * Connects to the server.
214
+ *
215
+ * @param url The server URL to connect to.
216
+ */
217
+ connect(url: string | URL): Promise<void>;
218
+ /**
219
+ * Sends a message to the server.
220
+ *
221
+ * This is an optional method for streams with bidirectional communication.
222
+ *
223
+ * @param message The message to send.
224
+ * @param type The optional message type.
225
+ */
226
+ send(message: string, type?: string): Promise<void>;
227
+ /**
228
+ * Closes the connection.
229
+ */
230
+ close(): Promise<void>;
231
+ }
232
+
233
+ /**
234
+ * Tracks output events.
235
+ *
236
+ * This is one of the nullability patterns from James Shore's article on
237
+ * [testing without mocks](https://www.jamesshore.com/v2/projects/nullables/testing-without-mocks#output-tracking).
238
+ *
239
+ * Example implementation of an event store:
240
+ *
241
+ * ```javascript
242
+ * async record(event) {
243
+ * // ...
244
+ * this.dispatchEvent(new CustomEvent("eventRecorded", { detail: event }));
245
+ * }
246
+ *
247
+ * trackEventsRecorded() {
248
+ * return new OutputTracker(this, "eventRecorded");
249
+ * }
250
+ * ```
251
+ *
252
+ * Example usage:
253
+ *
254
+ * ```javascript
255
+ * const eventsRecorded = eventStore.trackEventsRecorded();
256
+ * // ...
257
+ * const data = eventsRecorded.data(); // [event1, event2, ...]
258
+ * ```
259
+ */
260
+ export declare class OutputTracker<T> {
261
+ #private;
262
+ /**
263
+ * Creates a tracker for a specific event of an event target.
264
+ *
265
+ * @param eventTarget The target to track.
266
+ * @param event The event name to track.
267
+ */
268
+ static create<T>(eventTarget: EventTarget, event: string): OutputTracker<T>;
269
+ /**
270
+ * Creates a tracker for a specific event of an event target.
271
+ *
272
+ * @param eventTarget The target to track.
273
+ * @param event The event name to track.
274
+ */
275
+ constructor(eventTarget: EventTarget, event: string);
276
+ /**
277
+ * Returns the tracked data.
278
+ *
279
+ * @return The tracked data.
280
+ */
281
+ get data(): T[];
282
+ /**
283
+ * Clears the tracked data and returns the cleared data.
284
+ *
285
+ * @return The cleared data.
286
+ */
287
+ clear(): T[];
288
+ /**
289
+ * Stops tracking.
290
+ */
291
+ stop(): void;
292
+ }
293
+
294
+ /**
295
+ * This data object configures the response of a fetch stub call.
296
+ */
297
+ export declare interface ResponseData {
298
+ /** The HTTP status code. */
299
+ status: number;
300
+ /** The HTTP status text. */
301
+ statusText: string;
302
+ /** The optional response body. */
303
+ body?: Blob | object | string | null;
304
+ }
305
+
306
+ /**
307
+ * A client for the server-sent events protocol.
308
+ */
309
+ export declare class SseClient extends EventTarget implements MessageClient {
310
+ #private;
311
+ /**
312
+ * Creates an SSE client.
313
+ *
314
+ * @return A new SSE client.
315
+ */
316
+ static create(): SseClient;
317
+ /**
318
+ * Creates a nulled SSE client.
319
+ *
320
+ * @return A new SSE client.
321
+ */
322
+ static createNull(): SseClient;
323
+ private constructor();
324
+ get isConnected(): boolean;
325
+ get url(): string | undefined;
326
+ connect(url: string | URL, eventName?: string): Promise<void>;
327
+ send(_message: string, _type?: string): Promise<void>;
328
+ close(): Promise<void>;
329
+ /**
330
+ * Simulates a message event from the server.
331
+ *
332
+ * @param message The message to receive.
333
+ * @param eventName The optional event type.
334
+ * @param lastEventId The optional last event ID.
335
+ */
336
+ simulateMessage(message: string, eventName?: string, lastEventId?: string): void;
337
+ /**
338
+ * Simulates an error event.
339
+ */
340
+ simulateError(): void;
341
+ }
342
+
343
+ /**
344
+ * A successful status.
345
+ */
346
+ export declare class Success {
347
+ readonly isSuccess = true;
348
+ }
349
+
350
+ /**
351
+ * A client for the WebSocket protocol.
352
+ */
353
+ export declare class WebSocketClient extends EventTarget implements MessageClient {
354
+ #private;
355
+ /**
356
+ * Creates a WebSocket client.
357
+ *
358
+ * @param options The options for the WebSocket client.
359
+ * @return A new WebSocket client.
360
+ */
361
+ static create({ heartbeat }?: WebSocketOptions): WebSocketClient;
362
+ /**
363
+ * Creates a nulled WebSocket client.
364
+ *
365
+ * @param options The options for the WebSocket client.
366
+ * @return A new nulled WebSocket client.
367
+ */
368
+ static createNull({ heartbeat }?: WebSocketOptions): WebSocketClient;
369
+ private constructor();
370
+ get isConnected(): boolean;
371
+ get url(): string | undefined;
372
+ connect(url: string | URL): Promise<void>;
373
+ send(message: string): Promise<void>;
374
+ /**
375
+ * Returns a tracker for messages sent.
376
+ *
377
+ * @return A new output tracker.
378
+ */
379
+ trackMessageSent(): OutputTracker<string>;
380
+ /**
381
+ * Closes the connection.
382
+ *
383
+ * If a code is provided, also a reason should be provided.
384
+ *
385
+ * @param code An optional code.
386
+ * @param reason An optional reason.
387
+ */
388
+ close(code?: number, reason?: string): Promise<void>;
389
+ /**
390
+ * Simulates a message event from the server.
391
+ *
392
+ * @param message The message to receive.
393
+ */
394
+ simulateMessage(message: string): void;
395
+ /**
396
+ * Simulates a heartbeat.
397
+ */
398
+ simulateHeartbeat(): void;
399
+ /**
400
+ * Simulates a close event.
401
+ *
402
+ * @param code An optional code.
403
+ * @param reason An optional reason.
404
+ */
405
+ simulateClose(code?: number, reason?: string): void;
406
+ /**
407
+ * Simulates an error event.
408
+ */
409
+ simulateError(): void;
410
+ }
411
+
412
+ /**
413
+ * Options for the WebSocket client.
414
+ */
415
+ export declare interface WebSocketOptions {
416
+ /**
417
+ * The heartbeat interval in milliseconds. A value <= 0 disables the
418
+ * heartbeat.
419
+ */
420
+ heartbeat?: number;
421
+ }
422
+
423
+ export { }