@dogmatiq/protobuf 0.5.0 → 0.6.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.
package/README.md CHANGED
@@ -30,12 +30,12 @@ import "github.com/dogmatiq/protobuf/uuidpb/uuid.proto";
30
30
 
31
31
  ## Packages
32
32
 
33
- | Package | Protocol Buffers package | Contents |
34
- | --------------- | ------------------------ | ----------------------------- |
35
- | `uuidpb` | `dogma.protobuf.v1` | `UUID` |
36
- | `identitypb` | `dogma.protobuf.v1` | `Identity` |
37
- | `envelopepb` | `dogma.protobuf.v1` | `Envelope` and extensions |
38
- | `messaginggrpc` | `dogma.messaging.v1` | The event stream consumer API |
33
+ | Package | Protocol Buffers package | Contents |
34
+ | --------------- | ------------------------ | ------------------------------------------ |
35
+ | `uuidpb` | `dogma.protobuf.v1` | `UUID` |
36
+ | `identitypb` | `dogma.protobuf.v1` | `Identity` |
37
+ | `envelopepb` | `dogma.protobuf.v1` | `Envelope`, `MultiEnvelope` and extensions |
38
+ | `messaginggrpc` | `dogma.messaging.v1` | The event stream consumer API |
39
39
 
40
40
  ## Message data
41
41
 
@@ -1,4 +1,28 @@
1
- import type { Body, Envelope, Header, Message } from "./envelope_pb.js";
1
+ import { type Body, type Envelope, type Header, type Message, type MultiEnvelope } from "./envelope_pb.js";
2
+ /**
3
+ * Returns each message in a {@link MultiEnvelope} as a standalone
4
+ * {@link Envelope}.
5
+ *
6
+ * The returned envelopes share the multi-envelope's header.
7
+ */
8
+ export declare function expandMultiEnvelope(x: MultiEnvelope): Envelope[];
9
+ /**
10
+ * Returns a {@link MultiEnvelope} that contains the same header and body as
11
+ * env.
12
+ *
13
+ * The multi-envelope shares the envelope's header and body.
14
+ *
15
+ * @throws {Error} If env has no body.
16
+ */
17
+ export declare function asMultiEnvelope(env: Envelope): MultiEnvelope;
18
+ /**
19
+ * Appends the body of env to x if they have equivalent headers.
20
+ *
21
+ * It returns false, and does not modify x, if the headers differ.
22
+ *
23
+ * @throws {Error} If env has no body.
24
+ */
25
+ export declare function tryAppendEnvelope(x: MultiEnvelope, env: Envelope): boolean;
2
26
  /**
3
27
  * Throws an error if env is not well-formed.
4
28
  *
@@ -11,6 +35,12 @@ import type { Body, Envelope, Header, Message } from "./envelope_pb.js";
11
35
  * data can be decoded.
12
36
  */
13
37
  export declare function validateEnvelope(env: Envelope): void;
38
+ /**
39
+ * Throws an error if x is not well-formed.
40
+ *
41
+ * See {@link validateEnvelope} for what well-formedness means.
42
+ */
43
+ export declare function validateMultiEnvelope(x: MultiEnvelope): void;
14
44
  /**
15
45
  * Throws an error if x is not well-formed.
16
46
  *
@@ -1,8 +1,55 @@
1
- import { create } from "@bufbuild/protobuf";
1
+ import { create, createRegistry, equals } from "@bufbuild/protobuf";
2
2
  import { IdentitySchema } from "../identitypb/identity_pb.js";
3
3
  import { identityToString, validateIdentity } from "../identitypb/identity.js";
4
4
  import { UUIDSchema } from "../uuidpb/uuid_pb.js";
5
5
  import { uuidToString, validateUUID } from "../uuidpb/uuid.js";
6
+ import { EnvelopeSchema, HeaderSchema, MultiEnvelopeSchema, } from "./envelope_pb.js";
7
+ /**
8
+ * Returns each message in a {@link MultiEnvelope} as a standalone
9
+ * {@link Envelope}.
10
+ *
11
+ * The returned envelopes share the multi-envelope's header.
12
+ */
13
+ export function expandMultiEnvelope(x) {
14
+ return x.bodies.map((body) => create(EnvelopeSchema, { header: x.header, body }));
15
+ }
16
+ /**
17
+ * Returns a {@link MultiEnvelope} that contains the same header and body as
18
+ * env.
19
+ *
20
+ * The multi-envelope shares the envelope's header and body.
21
+ *
22
+ * @throws {Error} If env has no body.
23
+ */
24
+ export function asMultiEnvelope(env) {
25
+ if (!env.body) {
26
+ throw new Error("envelope must have a body");
27
+ }
28
+ return create(MultiEnvelopeSchema, {
29
+ header: env.header,
30
+ bodies: [env.body],
31
+ });
32
+ }
33
+ /**
34
+ * Appends the body of env to x if they have equivalent headers.
35
+ *
36
+ * It returns false, and does not modify x, if the headers differ.
37
+ *
38
+ * @throws {Error} If env has no body.
39
+ */
40
+ export function tryAppendEnvelope(x, env) {
41
+ if (!env.body) {
42
+ throw new Error("envelope must have a body");
43
+ }
44
+ const a = x.header;
45
+ const b = env.header;
46
+ const same = a && b ? headersEqual(a, b) : a === b;
47
+ if (!same) {
48
+ return false;
49
+ }
50
+ x.bodies.push(env.body);
51
+ return true;
52
+ }
6
53
  /**
7
54
  * Throws an error if env is not well-formed.
8
55
  *
@@ -18,6 +65,15 @@ export function validateEnvelope(env) {
18
65
  check("invalid header", () => validateHeader(env.header));
19
66
  check("invalid body", () => validateBody(env.body, env.header));
20
67
  }
68
+ /**
69
+ * Throws an error if x is not well-formed.
70
+ *
71
+ * See {@link validateEnvelope} for what well-formedness means.
72
+ */
73
+ export function validateMultiEnvelope(x) {
74
+ check("invalid header", () => validateHeader(x.header));
75
+ x.bodies.forEach((body, i) => check(`invalid body at index ${i}`, () => validateBody(body, x.header)));
76
+ }
21
77
  /**
22
78
  * Throws an error if x is not well-formed.
23
79
  *
@@ -140,3 +196,20 @@ function check(prefix, fn) {
140
196
  throw new Error(`${prefix}: ${cause.message}`, { cause });
141
197
  }
142
198
  }
199
+ // headersEqual returns true if a and b are equivalent, including any unknown
200
+ // fields, as Go's proto.Equal() does. The equals() function from protobuf-es
201
+ // ignores unknown fields unless the "unknown" option is set.
202
+ //
203
+ // Unlike proto.Equal(), it compares unknown fields in the order they were
204
+ // decoded, rather than grouped by field number, so headers whose unknown fields
205
+ // arrived in a different order are not equal.
206
+ //
207
+ // The "unknown" option is marked as experimental by protobuf-es, so it may
208
+ // change in a later release. A test covers it, so that such a change is
209
+ // noticed.
210
+ function headersEqual(a, b) {
211
+ return equals(HeaderSchema, a, b, { registry: REGISTRY, unknown: true });
212
+ }
213
+ // REGISTRY is the registry passed to equals(). It's empty because Header has no
214
+ // extensions, so every unknown field is genuinely unknown.
215
+ const REGISTRY = createRegistry();
@@ -10,6 +10,10 @@ export declare const file_github_com_dogmatiq_protobuf_envelopepb_envelope: GenF
10
10
  /**
11
11
  * Envelope is a container for a Dogma message and its meta-data.
12
12
  *
13
+ * An Envelope can be decoded as a single-body [MultiEnvelope]. Decoding a
14
+ * MultiEnvelope as an Envelope is only safe when it contains exactly one body;
15
+ * multiple bodies merge when decoded into the singular body field.
16
+ *
13
17
  * @generated from message dogma.protobuf.v1.Envelope
14
18
  */
15
19
  export type Envelope = Message$1<"dogma.protobuf.v1.Envelope"> & {
@@ -27,6 +31,27 @@ export type Envelope = Message$1<"dogma.protobuf.v1.Envelope"> & {
27
31
  * Use `create(EnvelopeSchema)` to create a new message.
28
32
  */
29
33
  export declare const EnvelopeSchema: GenMessage<Envelope>;
34
+ /**
35
+ * MultiEnvelope is an efficient encoding of an ordered sequence of [Envelope]
36
+ * values that share common header context.
37
+ *
38
+ * @generated from message dogma.protobuf.v1.MultiEnvelope
39
+ */
40
+ export type MultiEnvelope = Message$1<"dogma.protobuf.v1.MultiEnvelope"> & {
41
+ /**
42
+ * @generated from field: dogma.protobuf.v1.Header header = 1;
43
+ */
44
+ header?: Header | undefined;
45
+ /**
46
+ * @generated from field: repeated dogma.protobuf.v1.Body bodies = 2;
47
+ */
48
+ bodies: Body[];
49
+ };
50
+ /**
51
+ * Describes the message dogma.protobuf.v1.MultiEnvelope.
52
+ * Use `create(MultiEnvelopeSchema)` to create a new message.
53
+ */
54
+ export declare const MultiEnvelopeSchema: GenMessage<MultiEnvelope>;
30
55
  /**
31
56
  * Source identifies where a message originated.
32
57
  *
@@ -127,7 +152,7 @@ export declare const MessageSchema: GenMessage<Message>;
127
152
  export type Header = Message$1<"dogma.protobuf.v1.Header"> & {
128
153
  /**
129
154
  * CausationId is the ID of the message that was the direct cause of the
130
- * message.
155
+ * messages.
131
156
  *
132
157
  * It is required. A message that was not caused by any other message is its
133
158
  * own cause, so its causation ID is its own message ID.
@@ -136,9 +161,9 @@ export type Header = Message$1<"dogma.protobuf.v1.Header"> & {
136
161
  */
137
162
  causationId?: UUID | undefined;
138
163
  /**
139
- * CorrelationId is the ID of the first ancestor of the message that was
164
+ * CorrelationId is the ID of the first ancestor of the messages that was
140
165
  * itself not caused by another message, that is, it's the root of the message
141
- * chain that ultimately resulted in this message.
166
+ * chain that ultimately resulted in these messages.
142
167
  *
143
168
  * It is required. A message that was not caused by any other message is the
144
169
  * root of its own chain, so its correlation ID is its own message ID.
@@ -147,14 +172,14 @@ export type Header = Message$1<"dogma.protobuf.v1.Header"> & {
147
172
  */
148
173
  correlationId?: UUID | undefined;
149
174
  /**
150
- * Source identifies the origin of the message.
175
+ * Source identifies the origin of the messages.
151
176
  *
152
177
  * @generated from field: dogma.protobuf.v1.Source source = 3;
153
178
  */
154
179
  source?: Source | undefined;
155
180
  /**
156
- * Extensions is a set of extension values associated with the message,
157
- * its causal chain, or the envelope itself.
181
+ * Extensions is a set of extension values associated with the messages,
182
+ * their causal chain, or the envelope itself.
158
183
  *
159
184
  * @generated from field: repeated google.protobuf.Any extensions = 4;
160
185
  */
@@ -174,7 +199,7 @@ export type Header = Message$1<"dogma.protobuf.v1.Header"> & {
174
199
  export declare const HeaderSchema: GenMessage<Header>;
175
200
  /**
176
201
  * Body contains the metadata and encoded form of a single message in an
177
- * [Envelope].
202
+ * [Envelope] or [MultiEnvelope].
178
203
  *
179
204
  * @generated from message dogma.protobuf.v1.Body
180
205
  */
@@ -8,29 +8,34 @@ import { file_github_com_dogmatiq_protobuf_uuidpb_uuid } from "../uuidpb/uuid_pb
8
8
  /**
9
9
  * Describes the file github.com/dogmatiq/protobuf/envelopepb/envelope.proto.
10
10
  */
11
- export const file_github_com_dogmatiq_protobuf_envelopepb_envelope = /*@__PURE__*/ fileDesc("CjZnaXRodWIuY29tL2RvZ21hdGlxL3Byb3RvYnVmL2VudmVsb3BlcGIvZW52ZWxvcGUucHJvdG8SEWRvZ21hLnByb3RvYnVmLnYxIlwKCEVudmVsb3BlEikKBmhlYWRlchgBIAEoCzIZLmRvZ21hLnByb3RvYnVmLnYxLkhlYWRlchIlCgRib2R5GAIgASgLMhcuZG9nbWEucHJvdG9idWYudjEuQm9keSKvAQoGU291cmNlEikKBHNpdGUYASABKAsyGy5kb2dtYS5wcm90b2J1Zi52MS5JZGVudGl0eRIwCgthcHBsaWNhdGlvbhgCIAEoCzIbLmRvZ21hLnByb3RvYnVmLnYxLklkZW50aXR5EiwKB2hhbmRsZXIYAyABKAsyGy5kb2dtYS5wcm90b2J1Zi52MS5JZGVudGl0eRIaCgtpbnN0YW5jZV9pZBgEIAEoCUIFqgECCAIiZAoHTWVzc2FnZRIoCgd0eXBlX2lkGAEgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIaCgtkZXNjcmlwdGlvbhgCIAEoCUIFqgECCAISEwoEZGF0YRgDIAEoDEIFqgECCAIi5AEKBkhlYWRlchItCgxjYXVzYXRpb25faWQYASABKAsyFy5kb2dtYS5wcm90b2J1Zi52MS5VVUlEEi8KDmNvcnJlbGF0aW9uX2lkGAIgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIpCgZzb3VyY2UYAyABKAsyGS5kb2dtYS5wcm90b2J1Zi52MS5Tb3VyY2USKAoKZXh0ZW5zaW9ucxgEIAMoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkSJQoHYmFnZ2FnZRgFIAMoCzIULmdvb2dsZS5wcm90b2J1Zi5BbnkitAIKBEJvZHkSKwoKbWVzc2FnZV9pZBgBIAEoCzIXLmRvZ21hLnByb3RvYnVmLnYxLlVVSUQSHgoPaWRlbXBvdGVuY3lfa2V5GAIgASgJQgWqAQIIAhIuCgpjcmVhdGVkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIxCg1zY2hlZHVsZWRfZm9yGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIrCgdtZXNzYWdlGAUgASgLMhouZG9nbWEucHJvdG9idWYudjEuTWVzc2FnZRIoCgpleHRlbnNpb25zGAYgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueRIlCgdiYWdnYWdlGAcgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueUIpWidnaXRodWIuY29tL2RvZ21hdGlxL3Byb3RvYnVmL2VudmVsb3BlcGJiCGVkaXRpb25zcOkH", [file_google_protobuf_timestamp, file_google_protobuf_any, file_github_com_dogmatiq_protobuf_identitypb_identity, file_github_com_dogmatiq_protobuf_uuidpb_uuid]);
11
+ export const file_github_com_dogmatiq_protobuf_envelopepb_envelope = /*@__PURE__*/ fileDesc("CjZnaXRodWIuY29tL2RvZ21hdGlxL3Byb3RvYnVmL2VudmVsb3BlcGIvZW52ZWxvcGUucHJvdG8SEWRvZ21hLnByb3RvYnVmLnYxIlwKCEVudmVsb3BlEikKBmhlYWRlchgBIAEoCzIZLmRvZ21hLnByb3RvYnVmLnYxLkhlYWRlchIlCgRib2R5GAIgASgLMhcuZG9nbWEucHJvdG9idWYudjEuQm9keSJjCg1NdWx0aUVudmVsb3BlEikKBmhlYWRlchgBIAEoCzIZLmRvZ21hLnByb3RvYnVmLnYxLkhlYWRlchInCgZib2RpZXMYAiADKAsyFy5kb2dtYS5wcm90b2J1Zi52MS5Cb2R5Iq8BCgZTb3VyY2USKQoEc2l0ZRgBIAEoCzIbLmRvZ21hLnByb3RvYnVmLnYxLklkZW50aXR5EjAKC2FwcGxpY2F0aW9uGAIgASgLMhsuZG9nbWEucHJvdG9idWYudjEuSWRlbnRpdHkSLAoHaGFuZGxlchgDIAEoCzIbLmRvZ21hLnByb3RvYnVmLnYxLklkZW50aXR5EhoKC2luc3RhbmNlX2lkGAQgASgJQgWqAQIIAiJkCgdNZXNzYWdlEigKB3R5cGVfaWQYASABKAsyFy5kb2dtYS5wcm90b2J1Zi52MS5VVUlEEhoKC2Rlc2NyaXB0aW9uGAIgASgJQgWqAQIIAhITCgRkYXRhGAMgASgMQgWqAQIIAiLkAQoGSGVhZGVyEi0KDGNhdXNhdGlvbl9pZBgBIAEoCzIXLmRvZ21hLnByb3RvYnVmLnYxLlVVSUQSLwoOY29ycmVsYXRpb25faWQYAiABKAsyFy5kb2dtYS5wcm90b2J1Zi52MS5VVUlEEikKBnNvdXJjZRgDIAEoCzIZLmRvZ21hLnByb3RvYnVmLnYxLlNvdXJjZRIoCgpleHRlbnNpb25zGAQgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueRIlCgdiYWdnYWdlGAUgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueSK0AgoEQm9keRIrCgptZXNzYWdlX2lkGAEgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIeCg9pZGVtcG90ZW5jeV9rZXkYAiABKAlCBaoBAggCEi4KCmNyZWF0ZWRfYXQYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEjEKDXNjaGVkdWxlZF9mb3IYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEisKB21lc3NhZ2UYBSABKAsyGi5kb2dtYS5wcm90b2J1Zi52MS5NZXNzYWdlEigKCmV4dGVuc2lvbnMYBiADKAsyFC5nb29nbGUucHJvdG9idWYuQW55EiUKB2JhZ2dhZ2UYByADKAsyFC5nb29nbGUucHJvdG9idWYuQW55QilaJ2dpdGh1Yi5jb20vZG9nbWF0aXEvcHJvdG9idWYvZW52ZWxvcGVwYmIIZWRpdGlvbnNw6Qc", [file_google_protobuf_timestamp, file_google_protobuf_any, file_github_com_dogmatiq_protobuf_identitypb_identity, file_github_com_dogmatiq_protobuf_uuidpb_uuid]);
12
12
  /**
13
13
  * Describes the message dogma.protobuf.v1.Envelope.
14
14
  * Use `create(EnvelopeSchema)` to create a new message.
15
15
  */
16
16
  export const EnvelopeSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 0);
17
+ /**
18
+ * Describes the message dogma.protobuf.v1.MultiEnvelope.
19
+ * Use `create(MultiEnvelopeSchema)` to create a new message.
20
+ */
21
+ export const MultiEnvelopeSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 1);
17
22
  /**
18
23
  * Describes the message dogma.protobuf.v1.Source.
19
24
  * Use `create(SourceSchema)` to create a new message.
20
25
  */
21
- export const SourceSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 1);
26
+ export const SourceSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 2);
22
27
  /**
23
28
  * Describes the message dogma.protobuf.v1.Message.
24
29
  * Use `create(MessageSchema)` to create a new message.
25
30
  */
26
- export const MessageSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 2);
31
+ export const MessageSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 3);
27
32
  /**
28
33
  * Describes the message dogma.protobuf.v1.Header.
29
34
  * Use `create(HeaderSchema)` to create a new message.
30
35
  */
31
- export const HeaderSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 3);
36
+ export const HeaderSchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 4);
32
37
  /**
33
38
  * Describes the message dogma.protobuf.v1.Body.
34
39
  * Use `create(BodySchema)` to create a new message.
35
40
  */
36
- export const BodySchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 4);
41
+ export const BodySchema = /*@__PURE__*/ messageDesc(file_github_com_dogmatiq_protobuf_envelopepb_envelope, 5);
@@ -1,5 +1,5 @@
1
1
  import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2";
2
- import type { Envelope } from "../envelopepb/envelope_pb.js";
2
+ import type { MultiEnvelope } from "../envelopepb/envelope_pb.js";
3
3
  import type { UUID } from "../uuidpb/uuid_pb.js";
4
4
  import type { MessageFilter } from "./filter_pb.js";
5
5
  import type { Message } from "@bufbuild/protobuf";
@@ -92,18 +92,19 @@ export type EventStreamSegment = Message<"dogma.messaging.v1.EventStreamSegment"
92
92
  */
93
93
  endOffset: bigint;
94
94
  /**
95
- * Envelopes is a (possibly empty) list of envelopes containing the
95
+ * Envelopes is a (possibly empty) list of multi-envelopes containing the
96
96
  * events in the range that match the requested message types.
97
97
  *
98
98
  * Each envelope includes the [envelopepb.EventStreamPosition] extension.
99
99
  *
100
- * The events appear in ascending offset order. Their offsets may have gaps,
101
- * because events of other types are omitted. There is no additional
102
- * relationship implied between envelopes that appear in the same segment.
100
+ * The events appear in ascending offset order, both within each
101
+ * multi-envelope and across the list. Their offsets may have gaps, because
102
+ * events of other types are omitted. There is no additional relationship
103
+ * implied between envelopes that appear in the same segment.
103
104
  *
104
- * @generated from field: repeated dogma.protobuf.v1.Envelope envelopes = 4;
105
+ * @generated from field: repeated dogma.protobuf.v1.MultiEnvelope envelopes = 4;
105
106
  */
106
- envelopes: Envelope[];
107
+ envelopes: MultiEnvelope[];
107
108
  };
108
109
  /**
109
110
  * Describes the message dogma.messaging.v1.EventStreamSegment.
@@ -8,7 +8,7 @@ import { file_github_com_dogmatiq_protobuf_messaginggrpc_filter } from "./filter
8
8
  /**
9
9
  * Describes the file github.com/dogmatiq/protobuf/messaginggrpc/eventstreamconsumer.proto.
10
10
  */
11
- export const file_github_com_dogmatiq_protobuf_messaginggrpc_eventstreamconsumer = /*@__PURE__*/ fileDesc("CkRnaXRodWIuY29tL2RvZ21hdGlxL3Byb3RvYnVmL21lc3NhZ2luZ2dycGMvZXZlbnRzdHJlYW1jb25zdW1lci5wcm90bxISZG9nbWEubWVzc2FnaW5nLnYxIkcKEldhdGNoRXZlbnRzUmVxdWVzdBIxCgZmaWx0ZXIYASABKAsyIS5kb2dtYS5tZXNzYWdpbmcudjEuTWVzc2FnZUZpbHRlciKVAQoRUmVhZEV2ZW50c1JlcXVlc3QSMAoPZXZlbnRfc3RyZWFtX2lkGAEgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIbCgxiZWdpbl9vZmZzZXQYAiABKARCBaoBAggCEjEKBmZpbHRlchgDIAEoCzIhLmRvZ21hLm1lc3NhZ2luZy52MS5NZXNzYWdlRmlsdGVyIq4BChJFdmVudFN0cmVhbVNlZ21lbnQSMAoPZXZlbnRfc3RyZWFtX2lkGAEgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIbCgxiZWdpbl9vZmZzZXQYAiABKARCBaoBAggCEhkKCmVuZF9vZmZzZXQYAyABKARCBaoBAggCEi4KCWVudmVsb3BlcxgEIAMoCzIbLmRvZ21hLnByb3RvYnVmLnYxLkVudmVsb3BlMtgBChZFdmVudFN0cmVhbUNvbnN1bWVyQVBJEl8KC1dhdGNoRXZlbnRzEiYuZG9nbWEubWVzc2FnaW5nLnYxLldhdGNoRXZlbnRzUmVxdWVzdBomLmRvZ21hLm1lc3NhZ2luZy52MS5FdmVudFN0cmVhbVNlZ21lbnQwARJdCgpSZWFkRXZlbnRzEiUuZG9nbWEubWVzc2FnaW5nLnYxLlJlYWRFdmVudHNSZXF1ZXN0GiYuZG9nbWEubWVzc2FnaW5nLnYxLkV2ZW50U3RyZWFtU2VnbWVudDABQixaKmdpdGh1Yi5jb20vZG9nbWF0aXEvcHJvdG9idWYvbWVzc2FnaW5nZ3JwY2IIZWRpdGlvbnNw6Qc", [file_github_com_dogmatiq_protobuf_envelopepb_envelope, file_github_com_dogmatiq_protobuf_uuidpb_uuid, file_github_com_dogmatiq_protobuf_messaginggrpc_filter]);
11
+ export const file_github_com_dogmatiq_protobuf_messaginggrpc_eventstreamconsumer = /*@__PURE__*/ fileDesc("CkRnaXRodWIuY29tL2RvZ21hdGlxL3Byb3RvYnVmL21lc3NhZ2luZ2dycGMvZXZlbnRzdHJlYW1jb25zdW1lci5wcm90bxISZG9nbWEubWVzc2FnaW5nLnYxIkcKEldhdGNoRXZlbnRzUmVxdWVzdBIxCgZmaWx0ZXIYASABKAsyIS5kb2dtYS5tZXNzYWdpbmcudjEuTWVzc2FnZUZpbHRlciKVAQoRUmVhZEV2ZW50c1JlcXVlc3QSMAoPZXZlbnRfc3RyZWFtX2lkGAEgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIbCgxiZWdpbl9vZmZzZXQYAiABKARCBaoBAggCEjEKBmZpbHRlchgDIAEoCzIhLmRvZ21hLm1lc3NhZ2luZy52MS5NZXNzYWdlRmlsdGVyIrMBChJFdmVudFN0cmVhbVNlZ21lbnQSMAoPZXZlbnRfc3RyZWFtX2lkGAEgASgLMhcuZG9nbWEucHJvdG9idWYudjEuVVVJRBIbCgxiZWdpbl9vZmZzZXQYAiABKARCBaoBAggCEhkKCmVuZF9vZmZzZXQYAyABKARCBaoBAggCEjMKCWVudmVsb3BlcxgEIAMoCzIgLmRvZ21hLnByb3RvYnVmLnYxLk11bHRpRW52ZWxvcGUy2AEKFkV2ZW50U3RyZWFtQ29uc3VtZXJBUEkSXwoLV2F0Y2hFdmVudHMSJi5kb2dtYS5tZXNzYWdpbmcudjEuV2F0Y2hFdmVudHNSZXF1ZXN0GiYuZG9nbWEubWVzc2FnaW5nLnYxLkV2ZW50U3RyZWFtU2VnbWVudDABEl0KClJlYWRFdmVudHMSJS5kb2dtYS5tZXNzYWdpbmcudjEuUmVhZEV2ZW50c1JlcXVlc3QaJi5kb2dtYS5tZXNzYWdpbmcudjEuRXZlbnRTdHJlYW1TZWdtZW50MAFCLFoqZ2l0aHViLmNvbS9kb2dtYXRpcS9wcm90b2J1Zi9tZXNzYWdpbmdncnBjYghlZGl0aW9uc3DpBw", [file_github_com_dogmatiq_protobuf_envelopepb_envelope, file_github_com_dogmatiq_protobuf_uuidpb_uuid, file_github_com_dogmatiq_protobuf_messaginggrpc_filter]);
12
12
  /**
13
13
  * Describes the message dogma.messaging.v1.WatchEventsRequest.
14
14
  * Use `create(WatchEventsRequestSchema)` to create a new message.
@@ -9,11 +9,22 @@ import "github.com/dogmatiq/protobuf/identitypb/identity.proto";
9
9
  import "github.com/dogmatiq/protobuf/uuidpb/uuid.proto";
10
10
 
11
11
  // Envelope is a container for a Dogma message and its meta-data.
12
+ //
13
+ // An Envelope can be decoded as a single-body [MultiEnvelope]. Decoding a
14
+ // MultiEnvelope as an Envelope is only safe when it contains exactly one body;
15
+ // multiple bodies merge when decoded into the singular body field.
12
16
  message Envelope {
13
17
  Header header = 1;
14
18
  Body body = 2;
15
19
  }
16
20
 
21
+ // MultiEnvelope is an efficient encoding of an ordered sequence of [Envelope]
22
+ // values that share common header context.
23
+ message MultiEnvelope {
24
+ Header header = 1;
25
+ repeated Body bodies = 2;
26
+ }
27
+
17
28
  // Source identifies where a message originated.
18
29
  message Source {
19
30
  // Site is the (optional) identity of the "site" that the source
@@ -70,25 +81,25 @@ message Message {
70
81
  // type. Body values take precedence over header values of the same type.
71
82
  message Header {
72
83
  // CausationId is the ID of the message that was the direct cause of the
73
- // message.
84
+ // messages.
74
85
  //
75
86
  // It is required. A message that was not caused by any other message is its
76
87
  // own cause, so its causation ID is its own message ID.
77
88
  UUID causation_id = 1;
78
89
 
79
- // CorrelationId is the ID of the first ancestor of the message that was
90
+ // CorrelationId is the ID of the first ancestor of the messages that was
80
91
  // itself not caused by another message, that is, it's the root of the message
81
- // chain that ultimately resulted in this message.
92
+ // chain that ultimately resulted in these messages.
82
93
  //
83
94
  // It is required. A message that was not caused by any other message is the
84
95
  // root of its own chain, so its correlation ID is its own message ID.
85
96
  UUID correlation_id = 2;
86
97
 
87
- // Source identifies the origin of the message.
98
+ // Source identifies the origin of the messages.
88
99
  Source source = 3;
89
100
 
90
- // Extensions is a set of extension values associated with the message,
91
- // its causal chain, or the envelope itself.
101
+ // Extensions is a set of extension values associated with the messages,
102
+ // their causal chain, or the envelope itself.
92
103
  repeated google.protobuf.Any extensions = 4;
93
104
 
94
105
  // Baggage is a set of extension values that are propagated through the
@@ -97,7 +108,7 @@ message Header {
97
108
  }
98
109
 
99
110
  // Body contains the metadata and encoded form of a single message in an
100
- // [Envelope].
111
+ // [Envelope] or [MultiEnvelope].
101
112
  message Body {
102
113
  // MessageId is a unique identifier for the message in this envelope.
103
114
  UUID message_id = 1;
@@ -86,13 +86,14 @@ message EventStreamSegment {
86
86
  // EndOffset is the offset immediately after the range, exclusive.
87
87
  uint64 end_offset = 3 [features.field_presence = IMPLICIT];
88
88
 
89
- // Envelopes is a (possibly empty) list of envelopes containing the
89
+ // Envelopes is a (possibly empty) list of multi-envelopes containing the
90
90
  // events in the range that match the requested message types.
91
91
  //
92
92
  // Each envelope includes the [envelopepb.EventStreamPosition] extension.
93
93
  //
94
- // The events appear in ascending offset order. Their offsets may have gaps,
95
- // because events of other types are omitted. There is no additional
96
- // relationship implied between envelopes that appear in the same segment.
97
- repeated dogma.protobuf.v1.Envelope envelopes = 4;
94
+ // The events appear in ascending offset order, both within each
95
+ // multi-envelope and across the list. Their offsets may have gaps, because
96
+ // events of other types are omitted. There is no additional relationship
97
+ // implied between envelopes that appear in the same segment.
98
+ repeated dogma.protobuf.v1.MultiEnvelope envelopes = 4;
98
99
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dogmatiq/protobuf",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Protocol Buffers and gRPC definitions for Dogma",
5
5
  "keywords": [
6
6
  "dogma",