eventsourcingdb 1.8.2 → 1.8.3

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 (83) hide show
  1. package/dist/Bound.d.ts +6 -0
  2. package/dist/Bound.js +1 -0
  3. package/dist/Client.d.ts +21 -0
  4. package/dist/Client.js +484 -0
  5. package/dist/CloudEvent.d.ts +16 -0
  6. package/dist/CloudEvent.js +1 -0
  7. package/dist/Container.d.ts +20 -0
  8. package/dist/Container.js +108 -0
  9. package/dist/Event.d.ts +36 -0
  10. package/dist/Event.js +63 -0
  11. package/dist/EventCandidate.d.ts +9 -0
  12. package/dist/EventCandidate.js +1 -0
  13. package/dist/EventType.d.ts +6 -0
  14. package/dist/EventType.js +1 -0
  15. package/dist/ObserveEventsOptions.d.ts +13 -0
  16. package/dist/ObserveEventsOptions.js +1 -0
  17. package/dist/Precondition.d.ts +27 -0
  18. package/dist/Precondition.js +1 -0
  19. package/dist/ReadEventsOptions.d.ts +16 -0
  20. package/dist/ReadEventsOptions.js +1 -0
  21. package/dist/convertCloudEventToEvent.d.ts +4 -0
  22. package/dist/convertCloudEventToEvent.js +18 -0
  23. package/dist/getImageVersionFromDockerfile.d.ts +2 -0
  24. package/dist/getImageVersionFromDockerfile.js +14 -0
  25. package/dist/index.d.ts +14 -0
  26. package/dist/index.js +7 -0
  27. package/dist/isCloudEvent.d.ts +3 -0
  28. package/dist/isCloudEvent.js +21 -0
  29. package/dist/isEventQlQueryTrue.d.ts +3 -0
  30. package/dist/isEventQlQueryTrue.js +5 -0
  31. package/dist/isSubjectOnEventId.d.ts +3 -0
  32. package/dist/isSubjectOnEventId.js +5 -0
  33. package/dist/isSubjectPopulated.d.ts +3 -0
  34. package/dist/isSubjectPopulated.js +5 -0
  35. package/dist/isSubjectPristine.d.ts +3 -0
  36. package/dist/isSubjectPristine.js +5 -0
  37. package/dist/isValidServerHeader.d.ts +2 -0
  38. package/dist/isValidServerHeader.js +11 -0
  39. package/dist/ndjson/readNdJsonStream.d.ts +2 -0
  40. package/dist/ndjson/readNdJsonStream.js +43 -0
  41. package/dist/stream/StreamCloudEvent.d.ts +19 -0
  42. package/dist/stream/StreamCloudEvent.js +1 -0
  43. package/dist/stream/StreamError.d.ts +7 -0
  44. package/dist/stream/StreamError.js +1 -0
  45. package/dist/stream/StreamEventType.d.ts +9 -0
  46. package/dist/stream/StreamEventType.js +1 -0
  47. package/dist/stream/StreamHeartbeat.d.ts +4 -0
  48. package/dist/stream/StreamHeartbeat.js +1 -0
  49. package/dist/stream/StreamRow.d.ts +5 -0
  50. package/dist/stream/StreamRow.js +1 -0
  51. package/dist/stream/StreamSubject.d.ts +7 -0
  52. package/dist/stream/StreamSubject.js +1 -0
  53. package/dist/stream/isStreamCloudEvent.d.ts +3 -0
  54. package/dist/stream/isStreamCloudEvent.js +24 -0
  55. package/dist/stream/isStreamError.d.ts +3 -0
  56. package/dist/stream/isStreamError.js +9 -0
  57. package/dist/stream/isStreamEventType.d.ts +3 -0
  58. package/dist/stream/isStreamEventType.js +11 -0
  59. package/dist/stream/isStreamHeartbeat.d.ts +3 -0
  60. package/dist/stream/isStreamHeartbeat.js +5 -0
  61. package/dist/stream/isStreamRow.d.ts +3 -0
  62. package/dist/stream/isStreamRow.js +6 -0
  63. package/dist/stream/isStreamSubject.d.ts +3 -0
  64. package/dist/stream/isStreamSubject.js +9 -0
  65. package/dist/types/hasShapeOf.d.ts +6 -0
  66. package/dist/types/hasShapeOf.js +25 -0
  67. package/dist/types/isBoolean.d.ts +2 -0
  68. package/dist/types/isBoolean.js +7 -0
  69. package/dist/types/isRecord.d.ts +2 -0
  70. package/dist/types/isRecord.js +13 -0
  71. package/dist/types/isString.d.ts +2 -0
  72. package/dist/types/isString.js +7 -0
  73. package/dist/types/isStringOrNull.d.ts +2 -0
  74. package/dist/types/isStringOrNull.js +10 -0
  75. package/dist/types/isStringOrUndefined.d.ts +2 -0
  76. package/dist/types/isStringOrUndefined.js +10 -0
  77. package/package.json +13 -16
  78. package/.editorconfig +0 -22
  79. package/.nvmrc +0 -1
  80. package/dist/index.cjs +0 -3
  81. package/dist/index.d.cts +0 -182
  82. package/dist/index.d.mts +0 -182
  83. package/dist/index.mjs +0 -3
@@ -0,0 +1,36 @@
1
+ import crypto from 'node:crypto';
2
+ declare class Event {
3
+ #private;
4
+ specversion: string;
5
+ id: string;
6
+ time: Date;
7
+ source: string;
8
+ subject: string;
9
+ type: string;
10
+ datacontenttype: string;
11
+ data: Record<string, unknown>;
12
+ hash: string;
13
+ predecessorhash: string;
14
+ traceparent?: string;
15
+ tracestate?: string;
16
+ signature: string | null;
17
+ constructor({ specversion, id, time, timeFromServer, source, subject, type, datacontenttype, data, hash, predecessorhash, traceparent, tracestate, signature, }: {
18
+ specversion: string;
19
+ id: string;
20
+ time: Date;
21
+ timeFromServer: string;
22
+ source: string;
23
+ subject: string;
24
+ type: string;
25
+ datacontenttype: string;
26
+ data: Record<string, unknown>;
27
+ hash: string;
28
+ predecessorhash: string;
29
+ traceparent?: string;
30
+ tracestate?: string;
31
+ signature: string | null;
32
+ });
33
+ verifyHash(): void;
34
+ verifySignature(verificationKey: crypto.KeyObject): void;
35
+ }
36
+ export { Event };
package/dist/Event.js ADDED
@@ -0,0 +1,63 @@
1
+ import crypto from 'node:crypto';
2
+ class Event {
3
+ specversion;
4
+ id;
5
+ time;
6
+ #timeFromServer;
7
+ source;
8
+ subject;
9
+ type;
10
+ datacontenttype;
11
+ data;
12
+ hash;
13
+ predecessorhash;
14
+ traceparent;
15
+ tracestate;
16
+ signature;
17
+ constructor({ specversion, id, time, timeFromServer, source, subject, type, datacontenttype, data, hash, predecessorhash, traceparent, tracestate, signature, }) {
18
+ this.specversion = specversion;
19
+ this.id = id;
20
+ this.time = time;
21
+ this.#timeFromServer = timeFromServer;
22
+ this.source = source;
23
+ this.subject = subject;
24
+ this.type = type;
25
+ this.datacontenttype = datacontenttype;
26
+ this.data = data;
27
+ this.hash = hash;
28
+ this.predecessorhash = predecessorhash;
29
+ this.traceparent = traceparent;
30
+ this.tracestate = tracestate;
31
+ this.signature = signature;
32
+ }
33
+ verifyHash() {
34
+ const metadata = `${this.specversion}|${this.id}|${this.predecessorhash}|${this.#timeFromServer}|${this.source}|${this.subject}|${this.type}|${this.datacontenttype}`;
35
+ const metadataHash = crypto.createHash('sha256').update(metadata).digest('hex');
36
+ const dataHash = crypto.createHash('sha256').update(JSON.stringify(this.data)).digest('hex');
37
+ const finalHash = crypto
38
+ .createHash('sha256')
39
+ .update(`${metadataHash}${dataHash}`)
40
+ .digest('hex');
41
+ if (finalHash !== this.hash) {
42
+ throw new Error('Failed to verify hash.');
43
+ }
44
+ }
45
+ verifySignature(verificationKey) {
46
+ if (this.signature === null) {
47
+ throw new Error('Signature must not be null.');
48
+ }
49
+ this.verifyHash();
50
+ const signaturePrefix = 'esdb:signature:v1:';
51
+ if (!this.signature.startsWith(signaturePrefix)) {
52
+ throw new Error(`Signature must start with '${signaturePrefix}'`);
53
+ }
54
+ const signature = this.signature.slice(signaturePrefix.length);
55
+ const signatureBytes = Buffer.from(signature, 'hex');
56
+ const hashBytes = Buffer.from(this.hash, 'utf8');
57
+ const isSignatureValid = crypto.verify(null, hashBytes, verificationKey, signatureBytes);
58
+ if (!isSignatureValid) {
59
+ throw new Error('Signature verification failed.');
60
+ }
61
+ }
62
+ }
63
+ export { Event };
@@ -0,0 +1,9 @@
1
+ interface EventCandidate {
2
+ source: string;
3
+ subject: string;
4
+ type: string;
5
+ data: Record<string, unknown>;
6
+ traceparent?: string;
7
+ tracestate?: string;
8
+ }
9
+ export type { EventCandidate };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ interface EventType {
2
+ eventType: string;
3
+ isPhantom: boolean;
4
+ schema?: Record<string, unknown>;
5
+ }
6
+ export type { EventType };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { Bound } from './Bound.js';
2
+ type ObserveIfEventIsMissing = 'read-everything' | 'wait-for-event';
3
+ interface ObserveFromLatestEvent {
4
+ subject: string;
5
+ type: string;
6
+ ifEventIsMissing: ObserveIfEventIsMissing;
7
+ }
8
+ interface ObserveEventsOptions {
9
+ recursive: boolean;
10
+ lowerBound?: Bound;
11
+ fromLatestEvent?: ObserveFromLatestEvent;
12
+ }
13
+ export type { ObserveEventsOptions, ObserveFromLatestEvent, ObserveIfEventIsMissing };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ interface IsSubjectPristinePrecondition {
2
+ subject: string;
3
+ }
4
+ interface IsSubjectPopulatedPrecondition {
5
+ subject: string;
6
+ }
7
+ interface IsSubjectOnEventIdPrecondition {
8
+ subject: string;
9
+ eventId: string;
10
+ }
11
+ interface IsEventQlQueryTruePrecondition {
12
+ query: string;
13
+ }
14
+ type Precondition = {
15
+ type: 'isSubjectPristine';
16
+ payload: IsSubjectPristinePrecondition;
17
+ } | {
18
+ type: 'isSubjectOnEventId';
19
+ payload: IsSubjectOnEventIdPrecondition;
20
+ } | {
21
+ type: 'isSubjectPopulated';
22
+ payload: IsSubjectPopulatedPrecondition;
23
+ } | {
24
+ type: 'isEventQlQueryTrue';
25
+ payload: IsEventQlQueryTruePrecondition;
26
+ };
27
+ export type { Precondition };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { Bound } from './Bound.js';
2
+ type Order = 'chronological' | 'antichronological';
3
+ type ReadIfEventIsMissing = 'read-nothing' | 'read-everything';
4
+ interface ReadFromLatestEvent {
5
+ subject: string;
6
+ type: string;
7
+ ifEventIsMissing: ReadIfEventIsMissing;
8
+ }
9
+ interface ReadEventsOptions {
10
+ recursive: boolean;
11
+ order?: Order;
12
+ lowerBound?: Bound;
13
+ upperBound?: Bound;
14
+ fromLatestEvent?: ReadFromLatestEvent;
15
+ }
16
+ export type { Order, ReadEventsOptions, ReadFromLatestEvent, ReadIfEventIsMissing };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { CloudEvent } from './CloudEvent.js';
2
+ import { Event } from './Event.js';
3
+ declare const convertCloudEventToEvent: (cloudEvent: CloudEvent) => Event;
4
+ export { convertCloudEventToEvent };
@@ -0,0 +1,18 @@
1
+ import { Event } from './Event.js';
2
+ const convertCloudEventToEvent = (cloudEvent) => new Event({
3
+ specversion: cloudEvent.specversion,
4
+ id: cloudEvent.id,
5
+ time: new Date(cloudEvent.time),
6
+ timeFromServer: cloudEvent.time,
7
+ source: cloudEvent.source,
8
+ subject: cloudEvent.subject,
9
+ type: cloudEvent.type,
10
+ datacontenttype: cloudEvent.datacontenttype,
11
+ data: cloudEvent.data,
12
+ hash: cloudEvent.hash,
13
+ predecessorhash: cloudEvent.predecessorhash,
14
+ traceparent: cloudEvent.traceparent,
15
+ tracestate: cloudEvent.tracestate,
16
+ signature: cloudEvent.signature,
17
+ });
18
+ export { convertCloudEventToEvent };
@@ -0,0 +1,2 @@
1
+ declare const getImageVersionFromDockerfile: () => string;
2
+ export { getImageVersionFromDockerfile };
@@ -0,0 +1,14 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ const versionRegex = /^FROM\sthenativeweb\/eventsourcingdb:(.+)$/mu;
4
+ const getImageVersionFromDockerfile = () => {
5
+ const dockerfile = path.join(import.meta.dirname, '..', 'docker', 'Dockerfile');
6
+ const data = fs.readFileSync(dockerfile, 'utf-8');
7
+ const matches = data.match(versionRegex);
8
+ const version = matches?.[1];
9
+ if (version === undefined) {
10
+ throw new Error('Failed to find image version in Dockerfile.');
11
+ }
12
+ return version;
13
+ };
14
+ export { getImageVersionFromDockerfile };
@@ -0,0 +1,14 @@
1
+ import { Client } from './Client.js';
2
+ import { Container } from './Container.js';
3
+ import type { Event } from './Event.js';
4
+ import type { EventCandidate } from './EventCandidate.js';
5
+ import type { EventType } from './EventType.js';
6
+ import { isEventQlQueryTrue } from './isEventQlQueryTrue.js';
7
+ import { isSubjectOnEventId } from './isSubjectOnEventId.js';
8
+ import { isSubjectPopulated } from './isSubjectPopulated.js';
9
+ import { isSubjectPristine } from './isSubjectPristine.js';
10
+ import type { ObserveEventsOptions } from './ObserveEventsOptions.js';
11
+ import type { Precondition } from './Precondition.js';
12
+ import type { ReadEventsOptions } from './ReadEventsOptions.js';
13
+ export type { Event, EventCandidate, EventType, ObserveEventsOptions, Precondition, ReadEventsOptions, };
14
+ export { Client, Container, isEventQlQueryTrue, isSubjectOnEventId, isSubjectPopulated, isSubjectPristine, };
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import { Client } from './Client.js';
2
+ import { Container } from './Container.js';
3
+ import { isEventQlQueryTrue } from './isEventQlQueryTrue.js';
4
+ import { isSubjectOnEventId } from './isSubjectOnEventId.js';
5
+ import { isSubjectPopulated } from './isSubjectPopulated.js';
6
+ import { isSubjectPristine } from './isSubjectPristine.js';
7
+ export { Client, Container, isEventQlQueryTrue, isSubjectOnEventId, isSubjectPopulated, isSubjectPristine, };
@@ -0,0 +1,3 @@
1
+ import type { CloudEvent } from './CloudEvent.js';
2
+ declare const isCloudEvent: (value: unknown) => value is CloudEvent;
3
+ export { isCloudEvent };
@@ -0,0 +1,21 @@
1
+ import { hasShapeOf } from './types/hasShapeOf.js';
2
+ import { isRecord } from './types/isRecord.js';
3
+ import { isString } from './types/isString.js';
4
+ import { isStringOrNull } from './types/isStringOrNull.js';
5
+ import { isStringOrUndefined } from './types/isStringOrUndefined.js';
6
+ const isCloudEvent = (value) => hasShapeOf(value, {
7
+ specversion: isString,
8
+ id: isString,
9
+ time: isString,
10
+ source: isString,
11
+ subject: isString,
12
+ type: isString,
13
+ datacontenttype: isString,
14
+ data: isRecord,
15
+ hash: isString,
16
+ predecessorhash: isString,
17
+ traceparent: isStringOrUndefined,
18
+ tracestate: isStringOrUndefined,
19
+ signature: isStringOrNull,
20
+ });
21
+ export { isCloudEvent };
@@ -0,0 +1,3 @@
1
+ import type { Precondition } from './Precondition.js';
2
+ declare const isEventQlQueryTrue: (query: string) => Precondition;
3
+ export { isEventQlQueryTrue };
@@ -0,0 +1,5 @@
1
+ const isEventQlQueryTrue = (query) => ({
2
+ type: 'isEventQlQueryTrue',
3
+ payload: { query },
4
+ });
5
+ export { isEventQlQueryTrue };
@@ -0,0 +1,3 @@
1
+ import type { Precondition } from './Precondition.js';
2
+ declare const isSubjectOnEventId: (subject: string, eventId: string) => Precondition;
3
+ export { isSubjectOnEventId };
@@ -0,0 +1,5 @@
1
+ const isSubjectOnEventId = (subject, eventId) => ({
2
+ type: 'isSubjectOnEventId',
3
+ payload: { subject, eventId },
4
+ });
5
+ export { isSubjectOnEventId };
@@ -0,0 +1,3 @@
1
+ import type { Precondition } from './Precondition.js';
2
+ declare const isSubjectPopulated: (subject: string) => Precondition;
3
+ export { isSubjectPopulated };
@@ -0,0 +1,5 @@
1
+ const isSubjectPopulated = (subject) => ({
2
+ type: 'isSubjectPopulated',
3
+ payload: { subject },
4
+ });
5
+ export { isSubjectPopulated };
@@ -0,0 +1,3 @@
1
+ import type { Precondition } from './Precondition.js';
2
+ declare const isSubjectPristine: (subject: string) => Precondition;
3
+ export { isSubjectPristine };
@@ -0,0 +1,5 @@
1
+ const isSubjectPristine = (subject) => ({
2
+ type: 'isSubjectPristine',
3
+ payload: { subject },
4
+ });
5
+ export { isSubjectPristine };
@@ -0,0 +1,2 @@
1
+ declare const isValidServerHeader: (response: Response) => boolean;
2
+ export { isValidServerHeader };
@@ -0,0 +1,11 @@
1
+ const isValidServerHeader = (response) => {
2
+ const serverHeader = response.headers.get('Server');
3
+ if (!serverHeader) {
4
+ return false;
5
+ }
6
+ if (!serverHeader.startsWith('EventSourcingDB/')) {
7
+ return false;
8
+ }
9
+ return true;
10
+ };
11
+ export { isValidServerHeader };
@@ -0,0 +1,2 @@
1
+ declare const readNdJsonStream: (stream: ReadableStream<Uint8Array>, signal: AbortSignal) => AsyncGenerator<Record<string, unknown>, void, void>;
2
+ export { readNdJsonStream };
@@ -0,0 +1,43 @@
1
+ const readNdJsonStream = async function* (stream, signal) {
2
+ const reader = stream.getReader();
3
+ const decoder = new TextDecoder('utf-8');
4
+ let buffer = '';
5
+ const onAbort = () => {
6
+ reader.cancel().catch(() => {
7
+ // Intentionally left blank.
8
+ });
9
+ };
10
+ if (signal.aborted) {
11
+ await reader.cancel().catch(() => {
12
+ // Intentionally left blank.
13
+ });
14
+ return;
15
+ }
16
+ signal.addEventListener('abort', onAbort);
17
+ try {
18
+ while (!signal.aborted) {
19
+ // biome-ignore lint/performance/noAwaitInLoops: Awaiting the result is fine here, although we are in a loop.
20
+ const { done, value } = await reader.read();
21
+ if (done) {
22
+ break;
23
+ }
24
+ buffer += decoder.decode(value, { stream: true });
25
+ let index = buffer.indexOf('\n');
26
+ while (index !== -1) {
27
+ const line = buffer.slice(0, index).trim();
28
+ buffer = buffer.slice(index + 1);
29
+ if (line) {
30
+ yield JSON.parse(line);
31
+ }
32
+ index = buffer.indexOf('\n');
33
+ }
34
+ }
35
+ }
36
+ finally {
37
+ signal.removeEventListener('abort', onAbort);
38
+ await reader.cancel().catch(() => {
39
+ // Intentionally left blank.
40
+ });
41
+ }
42
+ };
43
+ export { readNdJsonStream };
@@ -0,0 +1,19 @@
1
+ interface StreamCloudEvent {
2
+ type: 'event';
3
+ payload: {
4
+ specversion: string;
5
+ id: string;
6
+ time: string;
7
+ source: string;
8
+ subject: string;
9
+ type: string;
10
+ datacontenttype: string;
11
+ data: Record<string, unknown>;
12
+ hash: string;
13
+ predecessorhash: string;
14
+ traceparent?: string;
15
+ tracestate?: string;
16
+ signature: string | null;
17
+ };
18
+ }
19
+ export type { StreamCloudEvent };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ interface StreamError {
2
+ type: 'error';
3
+ payload: {
4
+ error: string;
5
+ };
6
+ }
7
+ export type { StreamError };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ interface StreamEventType {
2
+ type: 'eventType';
3
+ payload: {
4
+ eventType: string;
5
+ isPhantom: boolean;
6
+ schema?: Record<string, unknown>;
7
+ };
8
+ }
9
+ export type { StreamEventType };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ interface StreamHeartbeat {
2
+ type: 'heartbeat';
3
+ }
4
+ export type { StreamHeartbeat };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ interface StreamRow {
2
+ type: 'row';
3
+ payload: unknown;
4
+ }
5
+ export type { StreamRow };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ interface StreamSubject {
2
+ type: 'subject';
3
+ payload: {
4
+ subject: string;
5
+ };
6
+ }
7
+ export type { StreamSubject };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { StreamCloudEvent } from './StreamCloudEvent.js';
2
+ declare const isStreamCloudEvent: (line: unknown) => line is StreamCloudEvent;
3
+ export { isStreamCloudEvent };
@@ -0,0 +1,24 @@
1
+ import { hasShapeOf } from '../types/hasShapeOf.js';
2
+ import { isRecord } from '../types/isRecord.js';
3
+ import { isString } from '../types/isString.js';
4
+ import { isStringOrNull } from '../types/isStringOrNull.js';
5
+ import { isStringOrUndefined } from '../types/isStringOrUndefined.js';
6
+ const isStreamCloudEvent = (line) => hasShapeOf(line, {
7
+ type: (value) => value === 'event',
8
+ payload: {
9
+ specversion: isString,
10
+ id: isString,
11
+ time: isString,
12
+ source: isString,
13
+ subject: isString,
14
+ type: isString,
15
+ datacontenttype: isString,
16
+ data: isRecord,
17
+ hash: isString,
18
+ predecessorhash: isString,
19
+ traceparent: isStringOrUndefined,
20
+ tracestate: isStringOrUndefined,
21
+ signature: isStringOrNull,
22
+ },
23
+ });
24
+ export { isStreamCloudEvent };
@@ -0,0 +1,3 @@
1
+ import type { StreamError } from './StreamError.js';
2
+ declare const isStreamError: (line: unknown) => line is StreamError;
3
+ export { isStreamError };
@@ -0,0 +1,9 @@
1
+ import { hasShapeOf } from '../types/hasShapeOf.js';
2
+ import { isString } from '../types/isString.js';
3
+ const isStreamError = (line) => hasShapeOf(line, {
4
+ type: (value) => value === 'error',
5
+ payload: {
6
+ error: isString,
7
+ },
8
+ });
9
+ export { isStreamError };
@@ -0,0 +1,3 @@
1
+ import type { StreamEventType } from './StreamEventType.js';
2
+ declare const isStreamEventType: (line: unknown) => line is StreamEventType;
3
+ export { isStreamEventType };
@@ -0,0 +1,11 @@
1
+ import { hasShapeOf } from '../types/hasShapeOf.js';
2
+ import { isBoolean } from '../types/isBoolean.js';
3
+ import { isString } from '../types/isString.js';
4
+ const isStreamEventType = (line) => hasShapeOf(line, {
5
+ type: (value) => value === 'eventType',
6
+ payload: {
7
+ eventType: isString,
8
+ isPhantom: isBoolean,
9
+ },
10
+ });
11
+ export { isStreamEventType };
@@ -0,0 +1,3 @@
1
+ import type { StreamHeartbeat } from './StreamHeartbeat.js';
2
+ declare const isStreamHeartbeat: (line: unknown) => line is StreamHeartbeat;
3
+ export { isStreamHeartbeat };
@@ -0,0 +1,5 @@
1
+ import { hasShapeOf } from '../types/hasShapeOf.js';
2
+ const isStreamHeartbeat = (line) => hasShapeOf(line, {
3
+ type: (value) => value === 'heartbeat',
4
+ });
5
+ export { isStreamHeartbeat };
@@ -0,0 +1,3 @@
1
+ import type { StreamRow } from './StreamRow.js';
2
+ declare const isStreamRow: (line: unknown) => line is StreamRow;
3
+ export { isStreamRow };
@@ -0,0 +1,6 @@
1
+ import { hasShapeOf } from '../types/hasShapeOf.js';
2
+ const isStreamRow = (line) => hasShapeOf(line, {
3
+ type: (value) => value === 'row',
4
+ payload: (value) => value !== undefined,
5
+ });
6
+ export { isStreamRow };
@@ -0,0 +1,3 @@
1
+ import type { StreamSubject } from './StreamSubject.js';
2
+ declare const isStreamSubject: (line: unknown) => line is StreamSubject;
3
+ export { isStreamSubject };
@@ -0,0 +1,9 @@
1
+ import { hasShapeOf } from '../types/hasShapeOf.js';
2
+ import { isString } from '../types/isString.js';
3
+ const isStreamSubject = (line) => hasShapeOf(line, {
4
+ type: (value) => value === 'subject',
5
+ payload: {
6
+ subject: isString,
7
+ },
8
+ });
9
+ export { isStreamSubject };
@@ -0,0 +1,6 @@
1
+ type Guard<T> = (x: unknown) => x is T;
2
+ type Shape<T> = {
3
+ [K in keyof T]: T[K] extends object ? Shape<T[K]> | Guard<T[K]> : Guard<T[K]>;
4
+ };
5
+ declare const hasShapeOf: <T extends object>(value: unknown, shape: Shape<T>) => value is T;
6
+ export { hasShapeOf };
@@ -0,0 +1,25 @@
1
+ import { isRecord } from './isRecord.js';
2
+ const hasShapeOf = (value, shape) => {
3
+ if (!isRecord(value)) {
4
+ return false;
5
+ }
6
+ for (const key of Object.keys(shape)) {
7
+ const spec = shape[key];
8
+ const val = value[key];
9
+ if (typeof spec === 'function') {
10
+ const guard = spec;
11
+ if (!guard(val)) {
12
+ return false;
13
+ }
14
+ continue;
15
+ }
16
+ if (!isRecord(val)) {
17
+ return false;
18
+ }
19
+ if (!hasShapeOf(val, spec)) {
20
+ return false;
21
+ }
22
+ }
23
+ return true;
24
+ };
25
+ export { hasShapeOf };
@@ -0,0 +1,2 @@
1
+ declare const isBoolean: (value: unknown) => value is boolean;
2
+ export { isBoolean };
@@ -0,0 +1,7 @@
1
+ const isBoolean = (value) => {
2
+ if (typeof value !== 'boolean') {
3
+ return false;
4
+ }
5
+ return true;
6
+ };
7
+ export { isBoolean };
@@ -0,0 +1,2 @@
1
+ declare const isRecord: (value: unknown) => value is Record<string, unknown>;
2
+ export { isRecord };