borgmcp-shared 0.2.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/CONTRIBUTING.md +40 -0
- package/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +159 -0
- package/SECURITY.md +25 -0
- package/dist/conformance/adapter.d.ts +112 -0
- package/dist/conformance/adapter.d.ts.map +1 -0
- package/dist/conformance/adapter.js +417 -0
- package/dist/conformance/adapter.js.map +1 -0
- package/dist/conformance/index.d.ts +15 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +49 -0
- package/dist/conformance/index.js.map +1 -0
- package/dist/domain/index.d.ts +5 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +4 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/drone-address.d.ts +3 -0
- package/dist/drone-address.d.ts.map +1 -0
- package/dist/drone-address.js +7 -0
- package/dist/drone-address.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/log-stream-hwm.d.ts +6 -0
- package/dist/log-stream-hwm.d.ts.map +1 -0
- package/dist/log-stream-hwm.js +12 -0
- package/dist/log-stream-hwm.js.map +1 -0
- package/dist/protocol/contract.d.ts +127 -0
- package/dist/protocol/contract.d.ts.map +1 -0
- package/dist/protocol/contract.js +434 -0
- package/dist/protocol/contract.js.map +1 -0
- package/dist/protocol/coordination.d.ts +38 -0
- package/dist/protocol/coordination.d.ts.map +1 -0
- package/dist/protocol/coordination.js +176 -0
- package/dist/protocol/coordination.js.map +1 -0
- package/dist/protocol/errors.d.ts +33 -0
- package/dist/protocol/errors.d.ts.map +1 -0
- package/dist/protocol/errors.js +26 -0
- package/dist/protocol/errors.js.map +1 -0
- package/dist/protocol/index.d.ts +8 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +7 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/sse.d.ts +44 -0
- package/dist/protocol/sse.d.ts.map +1 -0
- package/dist/protocol/sse.js +246 -0
- package/dist/protocol/sse.js.map +1 -0
- package/dist/protocol/types.d.ts +174 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +2 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/protocol/version.d.ts +11 -0
- package/dist/protocol/version.d.ts.map +1 -0
- package/dist/protocol/version.js +14 -0
- package/dist/protocol/version.js.map +1 -0
- package/dist/role-section.d.ts +24 -0
- package/dist/role-section.d.ts.map +1 -0
- package/dist/role-section.js +114 -0
- package/dist/role-section.js.map +1 -0
- package/dist/templates.d.ts +44 -0
- package/dist/templates.d.ts.map +1 -0
- package/dist/templates.js +771 -0
- package/dist/templates.js.map +1 -0
- package/docs/compatibility.md +38 -0
- package/docs/releasing.md +220 -0
- package/package.json +89 -0
- package/src/conformance/adapter.ts +717 -0
- package/src/conformance/index.ts +68 -0
- package/src/domain/index.ts +9 -0
- package/src/drone-address.ts +25 -0
- package/src/index.ts +4 -0
- package/src/log-stream-hwm.ts +16 -0
- package/src/protocol/contract.ts +608 -0
- package/src/protocol/coordination.ts +249 -0
- package/src/protocol/errors.ts +36 -0
- package/src/protocol/index.ts +7 -0
- package/src/protocol/sse.ts +295 -0
- package/src/protocol/types.ts +201 -0
- package/src/protocol/version.ts +31 -0
- package/src/role-section.ts +270 -0
- package/src/templates.ts +953 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { ProtocolContractError, compareLogCursor, decodeCanonicalTimestamp, decodeLogCursor, decodeProtocolEnvelope, decodeUuid, utf8ByteLength, } from './contract.js';
|
|
2
|
+
import { decodeEnrichedStreamEntry } from './sse.js';
|
|
3
|
+
function object(value) {
|
|
4
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
5
|
+
throw new ProtocolContractError('Expected a coordination object.');
|
|
6
|
+
}
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
function exact(value, allowed, required) {
|
|
10
|
+
for (const key of Object.keys(value)) {
|
|
11
|
+
if (!allowed.includes(key))
|
|
12
|
+
throw new ProtocolContractError(`Unknown coordination field "${key}".`);
|
|
13
|
+
}
|
|
14
|
+
for (const key of required) {
|
|
15
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) {
|
|
16
|
+
throw new ProtocolContractError(`Missing coordination field "${key}".`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function boundedString(value, name, maximum) {
|
|
21
|
+
if (typeof value !== 'string' || value.length === 0 || utf8ByteLength(value) > maximum) {
|
|
22
|
+
throw new ProtocolContractError(`Invalid coordination field "${name}".`);
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
function nullableString(value, name, maximum) {
|
|
27
|
+
return value === null ? null : boundedString(value, name, maximum);
|
|
28
|
+
}
|
|
29
|
+
function nonNegativeInteger(value, name, maximum) {
|
|
30
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > maximum) {
|
|
31
|
+
throw new ProtocolContractError(`Invalid coordination field "${name}".`);
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
function positiveInteger(value, name, maximum) {
|
|
36
|
+
const decoded = nonNegativeInteger(value, name, maximum);
|
|
37
|
+
if (decoded === 0)
|
|
38
|
+
throw new ProtocolContractError(`Invalid coordination field "${name}".`);
|
|
39
|
+
return decoded;
|
|
40
|
+
}
|
|
41
|
+
export function decodeReadLogRequest(value) {
|
|
42
|
+
const input = object(value);
|
|
43
|
+
exact(input, ['cursor', 'limit'], ['cursor']);
|
|
44
|
+
const output = {
|
|
45
|
+
cursor: input.cursor === null ? null : decodeLogCursor(input.cursor, ['cursor']),
|
|
46
|
+
};
|
|
47
|
+
if (input.limit !== undefined)
|
|
48
|
+
output.limit = positiveInteger(input.limit, 'limit', 500);
|
|
49
|
+
return output;
|
|
50
|
+
}
|
|
51
|
+
export function decodeReadLogRequestEnvelope(value) {
|
|
52
|
+
return decodeProtocolEnvelope(value, decodeReadLogRequest);
|
|
53
|
+
}
|
|
54
|
+
function decodeClaimRecord(value) {
|
|
55
|
+
const input = object(value);
|
|
56
|
+
exact(input, [
|
|
57
|
+
'log_entry_id',
|
|
58
|
+
'claimant_drone_id',
|
|
59
|
+
'claimant_label',
|
|
60
|
+
'claimant_role',
|
|
61
|
+
'claimed_at',
|
|
62
|
+
'stale',
|
|
63
|
+
], [
|
|
64
|
+
'log_entry_id',
|
|
65
|
+
'claimant_drone_id',
|
|
66
|
+
'claimant_label',
|
|
67
|
+
'claimant_role',
|
|
68
|
+
'claimed_at',
|
|
69
|
+
'stale',
|
|
70
|
+
]);
|
|
71
|
+
if (typeof input.stale !== 'boolean')
|
|
72
|
+
throw new ProtocolContractError('Invalid claim stale flag.');
|
|
73
|
+
return {
|
|
74
|
+
log_entry_id: decodeUuid(input.log_entry_id, ['log_entry_id']),
|
|
75
|
+
claimant_drone_id: decodeUuid(input.claimant_drone_id, ['claimant_drone_id']),
|
|
76
|
+
claimant_label: nullableString(input.claimant_label, 'claimant_label', 120),
|
|
77
|
+
claimant_role: nullableString(input.claimant_role, 'claimant_role', 120),
|
|
78
|
+
claimed_at: decodeCanonicalTimestamp(input.claimed_at, ['claimed_at']),
|
|
79
|
+
stale: input.stale,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function decodeAppendLogResult(value) {
|
|
83
|
+
const input = object(value);
|
|
84
|
+
exact(input, ['entry'], ['entry']);
|
|
85
|
+
return { entry: decodeEnrichedStreamEntry(input.entry) };
|
|
86
|
+
}
|
|
87
|
+
export function decodeAppendLogResultEnvelope(value) {
|
|
88
|
+
return decodeProtocolEnvelope(value, decodeAppendLogResult);
|
|
89
|
+
}
|
|
90
|
+
export function decodeReadLogResult(value) {
|
|
91
|
+
const input = object(value);
|
|
92
|
+
exact(input, ['entries', 'cursor', 'behind_by', 'has_more', 'claims'], ['entries', 'cursor', 'behind_by', 'has_more', 'claims']);
|
|
93
|
+
if (!Array.isArray(input.entries) || input.entries.length > 500) {
|
|
94
|
+
throw new ProtocolContractError('Invalid read-log entries.');
|
|
95
|
+
}
|
|
96
|
+
if (!Array.isArray(input.claims) || input.claims.length > 500) {
|
|
97
|
+
throw new ProtocolContractError('Invalid read-log claims.');
|
|
98
|
+
}
|
|
99
|
+
if (typeof input.has_more !== 'boolean')
|
|
100
|
+
throw new ProtocolContractError('Invalid has_more flag.');
|
|
101
|
+
const entries = input.entries.map(decodeEnrichedStreamEntry);
|
|
102
|
+
const cursor = input.cursor === null ? null : decodeLogCursor(input.cursor, ['cursor']);
|
|
103
|
+
for (let index = 1; index < entries.length; index++) {
|
|
104
|
+
const previous = { id: entries[index - 1].id, created_at: entries[index - 1].created_at };
|
|
105
|
+
const current = { id: entries[index].id, created_at: entries[index].created_at };
|
|
106
|
+
if (compareLogCursor(previous, current) >= 0) {
|
|
107
|
+
throw new ProtocolContractError('Read-log entries are not strictly cursor ordered.');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (entries.length > 0) {
|
|
111
|
+
const last = entries.at(-1);
|
|
112
|
+
if (cursor === null || cursor.id !== last.id || cursor.created_at !== last.created_at) {
|
|
113
|
+
throw new ProtocolContractError('Read-log cursor must equal the final entry tuple.');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
entries,
|
|
118
|
+
cursor,
|
|
119
|
+
behind_by: nonNegativeInteger(input.behind_by, 'behind_by', Number.MAX_SAFE_INTEGER),
|
|
120
|
+
has_more: input.has_more,
|
|
121
|
+
claims: input.claims.map(decodeClaimRecord),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function decodeReadLogResultEnvelope(value) {
|
|
125
|
+
return decodeProtocolEnvelope(value, decodeReadLogResult);
|
|
126
|
+
}
|
|
127
|
+
export function decodeDecision(value) {
|
|
128
|
+
const input = object(value);
|
|
129
|
+
exact(input, [
|
|
130
|
+
'id',
|
|
131
|
+
'cube_id',
|
|
132
|
+
'topic',
|
|
133
|
+
'decision',
|
|
134
|
+
'rationale',
|
|
135
|
+
'ratified_by',
|
|
136
|
+
'status',
|
|
137
|
+
'supersedes',
|
|
138
|
+
'created_at',
|
|
139
|
+
], ['id', 'cube_id', 'topic', 'decision', 'rationale', 'status', 'supersedes', 'created_at']);
|
|
140
|
+
if (!['active', 'superseded', 'removed'].includes(String(input.status))) {
|
|
141
|
+
throw new ProtocolContractError('Invalid decision status.');
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
id: decodeUuid(input.id, ['id']),
|
|
145
|
+
cube_id: decodeUuid(input.cube_id, ['cube_id']),
|
|
146
|
+
topic: boundedString(input.topic, 'topic', 120),
|
|
147
|
+
decision: boundedString(input.decision, 'decision', 2000),
|
|
148
|
+
rationale: nullableString(input.rationale, 'rationale', 2000),
|
|
149
|
+
ratified_by: input.ratified_by === undefined
|
|
150
|
+
? undefined
|
|
151
|
+
: input.ratified_by === null
|
|
152
|
+
? null
|
|
153
|
+
: decodeUuid(input.ratified_by, ['ratified_by']),
|
|
154
|
+
status: input.status,
|
|
155
|
+
supersedes: input.supersedes === null ? null : decodeUuid(input.supersedes, ['supersedes']),
|
|
156
|
+
created_at: decodeCanonicalTimestamp(input.created_at, ['created_at']),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export function decodeDecisionResultEnvelope(value) {
|
|
160
|
+
return decodeProtocolEnvelope(value, (payload) => {
|
|
161
|
+
const input = object(payload);
|
|
162
|
+
exact(input, ['decision'], ['decision']);
|
|
163
|
+
return { decision: decodeDecision(input.decision) };
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
export function decodeDecisionsResultEnvelope(value) {
|
|
167
|
+
return decodeProtocolEnvelope(value, (payload) => {
|
|
168
|
+
const input = object(payload);
|
|
169
|
+
exact(input, ['decisions'], ['decisions']);
|
|
170
|
+
if (!Array.isArray(input.decisions) || input.decisions.length > 500) {
|
|
171
|
+
throw new ProtocolContractError('Invalid decisions list.');
|
|
172
|
+
}
|
|
173
|
+
return { decisions: input.decisions.map(decodeDecision) };
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=coordination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coordination.js","sourceRoot":"","sources":["../../src/protocol/coordination.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare enum ErrorCode {
|
|
2
|
+
AUTH_MISSING = "AUTH_MISSING",
|
|
3
|
+
AUTH_INVALID = "AUTH_INVALID",
|
|
4
|
+
AUTH_EXPIRED = "AUTH_EXPIRED",
|
|
5
|
+
SUBSCRIPTION_REQUIRED = "SUBSCRIPTION_REQUIRED",
|
|
6
|
+
ACCESS_DENIED = "ACCESS_DENIED",
|
|
7
|
+
INVALID_INPUT = "INVALID_INPUT",
|
|
8
|
+
MISSING_PARAMETER = "MISSING_PARAMETER",
|
|
9
|
+
CONTENT_TOO_LARGE = "CONTENT_TOO_LARGE",
|
|
10
|
+
RATE_LIMIT_EXCEEDED = "RATE_LIMIT_EXCEEDED",
|
|
11
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
12
|
+
DATABASE_ERROR = "DATABASE_ERROR",
|
|
13
|
+
EXTERNAL_SERVICE_ERROR = "EXTERNAL_SERVICE_ERROR",
|
|
14
|
+
NOT_FOUND = "NOT_FOUND",
|
|
15
|
+
ROLE_IN_USE = "ROLE_IN_USE",
|
|
16
|
+
ROLE_HAS_FROZEN_DRONES = "ROLE_HAS_FROZEN_DRONES",
|
|
17
|
+
DRONE_EVICTED = "DRONE_EVICTED",
|
|
18
|
+
DRONE_FROZEN = "DRONE_FROZEN",
|
|
19
|
+
UNSUPPORTED_PROTOCOL_VERSION = "UNSUPPORTED_PROTOCOL_VERSION",
|
|
20
|
+
UNSUPPORTED_CAPABILITY = "UNSUPPORTED_CAPABILITY",
|
|
21
|
+
CURSOR_INVALID = "CURSOR_INVALID",
|
|
22
|
+
CURSOR_EXPIRED = "CURSOR_EXPIRED",
|
|
23
|
+
SESSION_REVOKED = "SESSION_REVOKED"
|
|
24
|
+
}
|
|
25
|
+
export interface ErrorResponse {
|
|
26
|
+
code: ErrorCode;
|
|
27
|
+
message: string;
|
|
28
|
+
details?: string;
|
|
29
|
+
retryAfter?: number;
|
|
30
|
+
requiredCapability?: string;
|
|
31
|
+
supportedVersions?: readonly string[];
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AACA,oBAAY,SAAS;IACnB,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,qBAAqB,0BAA0B;IAC/C,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,iBAAiB,sBAAsB;IACvC,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,sBAAsB,2BAA2B;IACjD,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAC7B,4BAA4B,iCAAiC;IAC7D,sBAAsB,2BAA2B;IACjD,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,eAAe,oBAAoB;CACpC;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export var ErrorCode;
|
|
2
|
+
(function (ErrorCode) {
|
|
3
|
+
ErrorCode["AUTH_MISSING"] = "AUTH_MISSING";
|
|
4
|
+
ErrorCode["AUTH_INVALID"] = "AUTH_INVALID";
|
|
5
|
+
ErrorCode["AUTH_EXPIRED"] = "AUTH_EXPIRED";
|
|
6
|
+
ErrorCode["SUBSCRIPTION_REQUIRED"] = "SUBSCRIPTION_REQUIRED";
|
|
7
|
+
ErrorCode["ACCESS_DENIED"] = "ACCESS_DENIED";
|
|
8
|
+
ErrorCode["INVALID_INPUT"] = "INVALID_INPUT";
|
|
9
|
+
ErrorCode["MISSING_PARAMETER"] = "MISSING_PARAMETER";
|
|
10
|
+
ErrorCode["CONTENT_TOO_LARGE"] = "CONTENT_TOO_LARGE";
|
|
11
|
+
ErrorCode["RATE_LIMIT_EXCEEDED"] = "RATE_LIMIT_EXCEEDED";
|
|
12
|
+
ErrorCode["INTERNAL_ERROR"] = "INTERNAL_ERROR";
|
|
13
|
+
ErrorCode["DATABASE_ERROR"] = "DATABASE_ERROR";
|
|
14
|
+
ErrorCode["EXTERNAL_SERVICE_ERROR"] = "EXTERNAL_SERVICE_ERROR";
|
|
15
|
+
ErrorCode["NOT_FOUND"] = "NOT_FOUND";
|
|
16
|
+
ErrorCode["ROLE_IN_USE"] = "ROLE_IN_USE";
|
|
17
|
+
ErrorCode["ROLE_HAS_FROZEN_DRONES"] = "ROLE_HAS_FROZEN_DRONES";
|
|
18
|
+
ErrorCode["DRONE_EVICTED"] = "DRONE_EVICTED";
|
|
19
|
+
ErrorCode["DRONE_FROZEN"] = "DRONE_FROZEN";
|
|
20
|
+
ErrorCode["UNSUPPORTED_PROTOCOL_VERSION"] = "UNSUPPORTED_PROTOCOL_VERSION";
|
|
21
|
+
ErrorCode["UNSUPPORTED_CAPABILITY"] = "UNSUPPORTED_CAPABILITY";
|
|
22
|
+
ErrorCode["CURSOR_INVALID"] = "CURSOR_INVALID";
|
|
23
|
+
ErrorCode["CURSOR_EXPIRED"] = "CURSOR_EXPIRED";
|
|
24
|
+
ErrorCode["SESSION_REVOKED"] = "SESSION_REVOKED";
|
|
25
|
+
})(ErrorCode || (ErrorCode = {}));
|
|
26
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,SAuBX;AAvBD,WAAY,SAAS;IACnB,0CAA6B,CAAA;IAC7B,0CAA6B,CAAA;IAC7B,0CAA6B,CAAA;IAC7B,4DAA+C,CAAA;IAC/C,4CAA+B,CAAA;IAC/B,4CAA+B,CAAA;IAC/B,oDAAuC,CAAA;IACvC,oDAAuC,CAAA;IACvC,wDAA2C,CAAA;IAC3C,8CAAiC,CAAA;IACjC,8CAAiC,CAAA;IACjC,8DAAiD,CAAA;IACjD,oCAAuB,CAAA;IACvB,wCAA2B,CAAA;IAC3B,8DAAiD,CAAA;IACjD,4CAA+B,CAAA;IAC/B,0CAA6B,CAAA;IAC7B,0EAA6D,CAAA;IAC7D,8DAAiD,CAAA;IACjD,8CAAiC,CAAA;IACjC,8CAAiC,CAAA;IACjC,gDAAmC,CAAA;AACrC,CAAC,EAvBW,SAAS,KAAT,SAAS,QAuBpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './errors.js';
|
|
2
|
+
export * from './types.js';
|
|
3
|
+
export * from './version.js';
|
|
4
|
+
export * from './contract.js';
|
|
5
|
+
export * from './coordination.js';
|
|
6
|
+
export * from './sse.js';
|
|
7
|
+
export type { BroadcastHwm } from '../log-stream-hwm.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/protocol/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/protocol/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { EnrichedStreamEntry } from './types.js';
|
|
2
|
+
import { type LogCursor } from './contract.js';
|
|
3
|
+
export declare const SSE_LIMITS: {
|
|
4
|
+
readonly total_bytes: number;
|
|
5
|
+
readonly frame_bytes: 65536;
|
|
6
|
+
readonly data_bytes: 65536;
|
|
7
|
+
readonly frame_count: 1000;
|
|
8
|
+
readonly unknown_data_bytes: 4096;
|
|
9
|
+
};
|
|
10
|
+
export type StreamEvent = {
|
|
11
|
+
type: 'log';
|
|
12
|
+
cursor: LogCursor;
|
|
13
|
+
entry: EnrichedStreamEntry;
|
|
14
|
+
} | {
|
|
15
|
+
type: 'ack';
|
|
16
|
+
log_entry_id: string;
|
|
17
|
+
actor_drone_id: string;
|
|
18
|
+
occurred_at: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'claim';
|
|
21
|
+
log_entry_id: string;
|
|
22
|
+
actor_drone_id: string;
|
|
23
|
+
occurred_at: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'heartbeat';
|
|
26
|
+
at: string;
|
|
27
|
+
broadcast_hwm: LogCursor | null;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'bookmark';
|
|
30
|
+
as_of: string;
|
|
31
|
+
replay_complete: boolean;
|
|
32
|
+
next_cursor?: LogCursor;
|
|
33
|
+
cursor_status?: 'valid' | 'expired' | 'unknown';
|
|
34
|
+
} | {
|
|
35
|
+
type: 'unknown';
|
|
36
|
+
event: string;
|
|
37
|
+
raw_data: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function decodeEnrichedStreamEntry(value: unknown): EnrichedStreamEntry;
|
|
40
|
+
export declare function encodeSseEvent(event: Exclude<StreamEvent, {
|
|
41
|
+
type: 'unknown';
|
|
42
|
+
}>): string;
|
|
43
|
+
export declare function decodeSseFrames(input: string): StreamEvent[];
|
|
44
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/protocol/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,UAAU;;;;;;CAMb,CAAC;AAEX,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,mBAAmB,CAAA;CAAE,GAC9D;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,SAAS,GAAG,IAAI,CAAA;CAAE,GAClE;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;CACjD,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAmCzD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA8C7E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,GAAG,MAAM,CA0CvF;AAOD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAe5D"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { ProtocolContractError, decodeCanonicalTimestamp, decodeLogCursor, decodeOpaqueIdentifier, decodeUuid, utf8ByteLength, } from './contract.js';
|
|
2
|
+
export const SSE_LIMITS = {
|
|
3
|
+
total_bytes: 1024 * 1024,
|
|
4
|
+
frame_bytes: 65_536,
|
|
5
|
+
data_bytes: 65_536,
|
|
6
|
+
frame_count: 1000,
|
|
7
|
+
unknown_data_bytes: 4096,
|
|
8
|
+
};
|
|
9
|
+
function object(value) {
|
|
10
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
11
|
+
throw new ProtocolContractError('SSE data must be a JSON object.');
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function exactKeys(value, allowed, required) {
|
|
16
|
+
for (const key of Object.keys(value)) {
|
|
17
|
+
if (!allowed.includes(key))
|
|
18
|
+
throw new ProtocolContractError(`Unknown SSE data field "${key}".`);
|
|
19
|
+
}
|
|
20
|
+
for (const key of required) {
|
|
21
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) {
|
|
22
|
+
throw new ProtocolContractError(`Missing SSE data field "${key}".`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function boundedString(value, name, maximum) {
|
|
27
|
+
if (typeof value !== 'string' || value.length === 0 || utf8ByteLength(value) > maximum) {
|
|
28
|
+
throw new ProtocolContractError(`Invalid SSE field "${name}".`);
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function nullableString(value, name, maximum) {
|
|
33
|
+
return value === null ? null : boundedString(value, name, maximum);
|
|
34
|
+
}
|
|
35
|
+
export function decodeEnrichedStreamEntry(value) {
|
|
36
|
+
const entry = object(value);
|
|
37
|
+
exactKeys(entry, [
|
|
38
|
+
'id',
|
|
39
|
+
'cube_id',
|
|
40
|
+
'drone_id',
|
|
41
|
+
'message',
|
|
42
|
+
'visibility',
|
|
43
|
+
'created_at',
|
|
44
|
+
'drone_label',
|
|
45
|
+
'role_name',
|
|
46
|
+
'recipient_drone_ids',
|
|
47
|
+
], [
|
|
48
|
+
'id',
|
|
49
|
+
'cube_id',
|
|
50
|
+
'drone_id',
|
|
51
|
+
'message',
|
|
52
|
+
'visibility',
|
|
53
|
+
'created_at',
|
|
54
|
+
'drone_label',
|
|
55
|
+
'role_name',
|
|
56
|
+
'recipient_drone_ids',
|
|
57
|
+
]);
|
|
58
|
+
if (entry.visibility !== 'broadcast' && entry.visibility !== 'direct') {
|
|
59
|
+
throw new ProtocolContractError('Invalid SSE log visibility.');
|
|
60
|
+
}
|
|
61
|
+
if (!Array.isArray(entry.recipient_drone_ids) || entry.recipient_drone_ids.length > 100) {
|
|
62
|
+
throw new ProtocolContractError('Invalid SSE recipient list.');
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
id: decodeUuid(entry.id, ['entry', 'id']),
|
|
66
|
+
cube_id: decodeUuid(entry.cube_id, ['entry', 'cube_id']),
|
|
67
|
+
drone_id: entry.drone_id === null ? null : decodeUuid(entry.drone_id, ['entry', 'drone_id']),
|
|
68
|
+
message: boundedString(entry.message, 'message', 10_240),
|
|
69
|
+
visibility: entry.visibility,
|
|
70
|
+
created_at: decodeCanonicalTimestamp(entry.created_at, ['entry', 'created_at']),
|
|
71
|
+
drone_label: nullableString(entry.drone_label, 'drone_label', 120),
|
|
72
|
+
role_name: nullableString(entry.role_name, 'role_name', 120),
|
|
73
|
+
recipient_drone_ids: entry.recipient_drone_ids.map((id, index) => decodeUuid(id, ['entry', 'recipient_drone_ids', index])),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export function encodeSseEvent(event) {
|
|
77
|
+
const lines = [`event: ${event.type}`];
|
|
78
|
+
let data;
|
|
79
|
+
if (event.type === 'log') {
|
|
80
|
+
const cursor = decodeLogCursor(event.cursor);
|
|
81
|
+
const entry = decodeEnrichedStreamEntry(event.entry);
|
|
82
|
+
if (cursor.id !== entry.id || cursor.created_at !== entry.created_at) {
|
|
83
|
+
throw new ProtocolContractError('Log event cursor must match the entry tuple.');
|
|
84
|
+
}
|
|
85
|
+
if (/[\r\n\0]/.test(cursor.id)) {
|
|
86
|
+
throw new ProtocolContractError('SSE id contains a forbidden control character.');
|
|
87
|
+
}
|
|
88
|
+
lines.push(`id: ${cursor.id}`);
|
|
89
|
+
data = { cursor, entry };
|
|
90
|
+
}
|
|
91
|
+
else if (event.type === 'ack' || event.type === 'claim') {
|
|
92
|
+
data = {
|
|
93
|
+
log_entry_id: decodeUuid(event.log_entry_id, ['log_entry_id']),
|
|
94
|
+
actor_drone_id: decodeUuid(event.actor_drone_id, ['actor_drone_id']),
|
|
95
|
+
occurred_at: decodeCanonicalTimestamp(event.occurred_at, ['occurred_at']),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
else if (event.type === 'heartbeat') {
|
|
99
|
+
data = {
|
|
100
|
+
at: decodeCanonicalTimestamp(event.at, ['at']),
|
|
101
|
+
broadcast_hwm: event.broadcast_hwm === null ? null : decodeLogCursor(event.broadcast_hwm),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
if (typeof event.replay_complete !== 'boolean') {
|
|
106
|
+
throw new ProtocolContractError('Bookmark replay_complete must be boolean.');
|
|
107
|
+
}
|
|
108
|
+
if (event.cursor_status !== undefined &&
|
|
109
|
+
!['valid', 'expired', 'unknown'].includes(event.cursor_status)) {
|
|
110
|
+
throw new ProtocolContractError('Invalid bookmark cursor_status.');
|
|
111
|
+
}
|
|
112
|
+
data = {
|
|
113
|
+
as_of: decodeCanonicalTimestamp(event.as_of, ['as_of']),
|
|
114
|
+
replay_complete: event.replay_complete,
|
|
115
|
+
...(event.next_cursor ? { next_cursor: decodeLogCursor(event.next_cursor) } : {}),
|
|
116
|
+
...(event.cursor_status ? { cursor_status: event.cursor_status } : {}),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
lines.push(`data: ${JSON.stringify(data)}`, '', '');
|
|
120
|
+
return lines.join('\n');
|
|
121
|
+
}
|
|
122
|
+
export function decodeSseFrames(input) {
|
|
123
|
+
if (utf8ByteLength(input) > SSE_LIMITS.total_bytes) {
|
|
124
|
+
throw new ProtocolContractError('SSE input exceeds the total byte limit.');
|
|
125
|
+
}
|
|
126
|
+
const normalized = input.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
127
|
+
const frames = normalized.split(/\n\n+/).filter((frame) => frame.trim() !== '');
|
|
128
|
+
if (frames.length > SSE_LIMITS.frame_count) {
|
|
129
|
+
throw new ProtocolContractError('SSE input exceeds the frame count limit.');
|
|
130
|
+
}
|
|
131
|
+
for (const frame of frames) {
|
|
132
|
+
if (utf8ByteLength(frame) > SSE_LIMITS.frame_bytes) {
|
|
133
|
+
throw new ProtocolContractError('SSE frame exceeds the byte limit.');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return frames.map(decodeFrame);
|
|
137
|
+
}
|
|
138
|
+
function decodeFrame(frame) {
|
|
139
|
+
let eventName = 'message';
|
|
140
|
+
let id;
|
|
141
|
+
let eventSeen = false;
|
|
142
|
+
let idSeen = false;
|
|
143
|
+
const dataLines = [];
|
|
144
|
+
for (const line of frame.split('\n')) {
|
|
145
|
+
if (line === '' || line.startsWith(':'))
|
|
146
|
+
continue;
|
|
147
|
+
const colon = line.indexOf(':');
|
|
148
|
+
const field = colon === -1 ? line : line.slice(0, colon);
|
|
149
|
+
let value = colon === -1 ? '' : line.slice(colon + 1);
|
|
150
|
+
if (value.startsWith(' '))
|
|
151
|
+
value = value.slice(1);
|
|
152
|
+
if (field === 'event') {
|
|
153
|
+
if (eventSeen)
|
|
154
|
+
throw new ProtocolContractError('Duplicate SSE event field.');
|
|
155
|
+
eventSeen = true;
|
|
156
|
+
eventName = decodeOpaqueIdentifier(value, ['event']);
|
|
157
|
+
}
|
|
158
|
+
else if (field === 'id') {
|
|
159
|
+
if (idSeen)
|
|
160
|
+
throw new ProtocolContractError('Duplicate SSE id field.');
|
|
161
|
+
idSeen = true;
|
|
162
|
+
id = decodeUuid(value, ['id']);
|
|
163
|
+
}
|
|
164
|
+
else if (field === 'data')
|
|
165
|
+
dataLines.push(value);
|
|
166
|
+
else
|
|
167
|
+
throw new ProtocolContractError(`Unsupported SSE field "${field}".`);
|
|
168
|
+
}
|
|
169
|
+
const rawData = dataLines.join('\n');
|
|
170
|
+
const rawDataBytes = utf8ByteLength(rawData);
|
|
171
|
+
if (rawDataBytes > SSE_LIMITS.data_bytes) {
|
|
172
|
+
throw new ProtocolContractError('SSE data exceeds the byte limit.');
|
|
173
|
+
}
|
|
174
|
+
if (!['log', 'ack', 'claim', 'heartbeat', 'bookmark'].includes(eventName)) {
|
|
175
|
+
if (rawDataBytes > SSE_LIMITS.unknown_data_bytes) {
|
|
176
|
+
throw new ProtocolContractError('Unknown SSE event data exceeds the byte limit.');
|
|
177
|
+
}
|
|
178
|
+
return { type: 'unknown', event: eventName, raw_data: rawData };
|
|
179
|
+
}
|
|
180
|
+
let parsed;
|
|
181
|
+
try {
|
|
182
|
+
parsed = JSON.parse(rawData);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
throw new ProtocolContractError(`Invalid JSON in SSE ${eventName} event.`);
|
|
186
|
+
}
|
|
187
|
+
const data = object(parsed);
|
|
188
|
+
if (eventName === 'log') {
|
|
189
|
+
if (!id)
|
|
190
|
+
throw new ProtocolContractError('Log SSE events require an id field.');
|
|
191
|
+
exactKeys(data, ['cursor', 'entry'], ['cursor', 'entry']);
|
|
192
|
+
const cursor = decodeLogCursor(data.cursor, ['cursor']);
|
|
193
|
+
if (cursor.id !== id)
|
|
194
|
+
throw new ProtocolContractError('SSE id and cursor id differ.');
|
|
195
|
+
const entry = decodeEnrichedStreamEntry(data.entry);
|
|
196
|
+
if (entry.id !== id || entry.created_at !== cursor.created_at) {
|
|
197
|
+
throw new ProtocolContractError('SSE cursor and entry tuple differ.');
|
|
198
|
+
}
|
|
199
|
+
return { type: 'log', cursor, entry };
|
|
200
|
+
}
|
|
201
|
+
if (id !== undefined) {
|
|
202
|
+
throw new ProtocolContractError(`${eventName} SSE events must not carry a resume id.`);
|
|
203
|
+
}
|
|
204
|
+
if (eventName === 'ack' || eventName === 'claim') {
|
|
205
|
+
exactKeys(data, ['log_entry_id', 'actor_drone_id', 'occurred_at'], [
|
|
206
|
+
'log_entry_id',
|
|
207
|
+
'actor_drone_id',
|
|
208
|
+
'occurred_at',
|
|
209
|
+
]);
|
|
210
|
+
return {
|
|
211
|
+
type: eventName,
|
|
212
|
+
log_entry_id: decodeUuid(data.log_entry_id, ['log_entry_id']),
|
|
213
|
+
actor_drone_id: decodeUuid(data.actor_drone_id, ['actor_drone_id']),
|
|
214
|
+
occurred_at: decodeCanonicalTimestamp(data.occurred_at, ['occurred_at']),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
if (eventName === 'heartbeat') {
|
|
218
|
+
exactKeys(data, ['at', 'broadcast_hwm'], ['at', 'broadcast_hwm']);
|
|
219
|
+
return {
|
|
220
|
+
type: 'heartbeat',
|
|
221
|
+
at: decodeCanonicalTimestamp(data.at, ['at']),
|
|
222
|
+
broadcast_hwm: data.broadcast_hwm === null
|
|
223
|
+
? null
|
|
224
|
+
: decodeLogCursor(data.broadcast_hwm, ['broadcast_hwm']),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
exactKeys(data, ['as_of', 'replay_complete', 'next_cursor', 'cursor_status'], ['as_of', 'replay_complete']);
|
|
228
|
+
if (typeof data.replay_complete !== 'boolean') {
|
|
229
|
+
throw new ProtocolContractError('Bookmark replay_complete must be boolean.');
|
|
230
|
+
}
|
|
231
|
+
const bookmark = {
|
|
232
|
+
type: 'bookmark',
|
|
233
|
+
as_of: decodeCanonicalTimestamp(data.as_of, ['as_of']),
|
|
234
|
+
replay_complete: data.replay_complete,
|
|
235
|
+
};
|
|
236
|
+
if (data.next_cursor !== undefined)
|
|
237
|
+
bookmark.next_cursor = decodeLogCursor(data.next_cursor);
|
|
238
|
+
if (data.cursor_status !== undefined) {
|
|
239
|
+
if (!['valid', 'expired', 'unknown'].includes(String(data.cursor_status))) {
|
|
240
|
+
throw new ProtocolContractError('Invalid bookmark cursor_status.');
|
|
241
|
+
}
|
|
242
|
+
bookmark.cursor_status = data.cursor_status;
|
|
243
|
+
}
|
|
244
|
+
return bookmark;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/protocol/sse.ts"],"names":[],"mappings":"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"}
|