@embassys/ambassador 0.0.0 → 0.2.7

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 (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +69 -2
  3. package/dist/agent-capabilities.d.ts +35 -0
  4. package/dist/agent-capabilities.js +221 -0
  5. package/dist/agent-capabilities.js.map +1 -0
  6. package/dist/ambassador-options.d.ts +6 -0
  7. package/dist/ambassador-options.js +13 -0
  8. package/dist/ambassador-options.js.map +1 -0
  9. package/dist/central-credential.d.ts +41 -0
  10. package/dist/central-credential.js +355 -0
  11. package/dist/central-credential.js.map +1 -0
  12. package/dist/central-enrollment.d.ts +31 -0
  13. package/dist/central-enrollment.js +278 -0
  14. package/dist/central-enrollment.js.map +1 -0
  15. package/dist/central-json.d.ts +8 -0
  16. package/dist/central-json.js +259 -0
  17. package/dist/central-json.js.map +1 -0
  18. package/dist/central-protected-transport.d.ts +21 -0
  19. package/dist/central-protected-transport.js +217 -0
  20. package/dist/central-protected-transport.js.map +1 -0
  21. package/dist/central-rest.d.ts +50 -0
  22. package/dist/central-rest.js +401 -0
  23. package/dist/central-rest.js.map +1 -0
  24. package/dist/cli.d.ts +26 -0
  25. package/dist/cli.js +129 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/credential-store.d.ts +18 -0
  28. package/dist/credential-store.js +617 -0
  29. package/dist/credential-store.js.map +1 -0
  30. package/dist/delivery-profile.d.ts +43 -0
  31. package/dist/delivery-profile.js +253 -0
  32. package/dist/delivery-profile.js.map +1 -0
  33. package/dist/direct-delivery.d.ts +37 -0
  34. package/dist/direct-delivery.js +312 -0
  35. package/dist/direct-delivery.js.map +1 -0
  36. package/dist/dpop.d.ts +28 -0
  37. package/dist/dpop.js +119 -0
  38. package/dist/dpop.js.map +1 -0
  39. package/dist/errors.d.ts +5 -0
  40. package/dist/errors.js +11 -0
  41. package/dist/errors.js.map +1 -0
  42. package/dist/gateway-application.d.ts +32 -0
  43. package/dist/gateway-application.js +255 -0
  44. package/dist/gateway-application.js.map +1 -0
  45. package/dist/gateway-paths.d.ts +11 -0
  46. package/dist/gateway-paths.js +29 -0
  47. package/dist/gateway-paths.js.map +1 -0
  48. package/dist/guided-registration.d.ts +23 -0
  49. package/dist/guided-registration.js +117 -0
  50. package/dist/guided-registration.js.map +1 -0
  51. package/dist/identity.d.ts +20 -0
  52. package/dist/identity.js +54 -0
  53. package/dist/identity.js.map +1 -0
  54. package/dist/local-mcp.d.ts +28 -0
  55. package/dist/local-mcp.js +410 -0
  56. package/dist/local-mcp.js.map +1 -0
  57. package/dist/local-tool-result.d.ts +4 -0
  58. package/dist/local-tool-result.js +17 -0
  59. package/dist/local-tool-result.js.map +1 -0
  60. package/dist/mcp-contract.d.ts +10 -0
  61. package/dist/mcp-contract.js +63 -0
  62. package/dist/mcp-contract.js.map +1 -0
  63. package/dist/notification-journal.d.ts +24 -0
  64. package/dist/notification-journal.js +194 -0
  65. package/dist/notification-journal.js.map +1 -0
  66. package/dist/notification-relay.d.ts +31 -0
  67. package/dist/notification-relay.js +203 -0
  68. package/dist/notification-relay.js.map +1 -0
  69. package/dist/process-lock.d.ts +8 -0
  70. package/dist/process-lock.js +122 -0
  71. package/dist/process-lock.js.map +1 -0
  72. package/dist/sqlite-artifact.d.ts +7 -0
  73. package/dist/sqlite-artifact.js +121 -0
  74. package/dist/sqlite-artifact.js.map +1 -0
  75. package/dist/webhook-delivery.d.ts +23 -0
  76. package/dist/webhook-delivery.js +122 -0
  77. package/dist/webhook-delivery.js.map +1 -0
  78. package/docs/getting-started-claude.md +33 -0
  79. package/docs/getting-started-codex.md +36 -0
  80. package/docs/getting-started-gemini.md +31 -0
  81. package/docs/getting-started-hermes.md +47 -0
  82. package/docs/getting-started-openclaw.md +48 -0
  83. package/docs/live-qualification.md +174 -0
  84. package/package.json +48 -7
  85. package/index.js +0 -1
@@ -0,0 +1,4 @@
1
+ export declare class LocalToolResultTooLarge extends Error {
2
+ constructor();
3
+ }
4
+ export declare function serializeLocalToolResult(result: Record<string, unknown>): string;
@@ -0,0 +1,17 @@
1
+ // The MCP SDK mirrors this JSON as structured content and an escaped text item.
2
+ // This cap keeps both copies and a maximum-size request ID below the 4 MiB transport limit.
3
+ const MAX_LOCAL_TOOL_RESULT_BYTES = 512 * 1024;
4
+ export class LocalToolResultTooLarge extends Error {
5
+ constructor() {
6
+ super("Local tool result exceeded its size limit");
7
+ this.name = "LocalToolResultTooLarge";
8
+ }
9
+ }
10
+ export function serializeLocalToolResult(result) {
11
+ const serialized = JSON.stringify(result);
12
+ if (Buffer.byteLength(serialized, "utf8") > MAX_LOCAL_TOOL_RESULT_BYTES) {
13
+ throw new LocalToolResultTooLarge();
14
+ }
15
+ return serialized;
16
+ }
17
+ //# sourceMappingURL=local-tool-result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-tool-result.js","sourceRoot":"","sources":["../src/local-tool-result.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,4FAA4F;AAC5F,MAAM,2BAA2B,GAAG,GAAG,GAAG,IAAI,CAAC;AAE/C,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAChD;QACE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AAED,MAAM,UAAU,wBAAwB,CAAC,MAA+B;IACtE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,2BAA2B,EAAE,CAAC;QACxE,MAAM,IAAI,uBAAuB,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare class McpContractError extends Error {
2
+ constructor();
3
+ }
4
+ export interface CentralToolDefinition {
5
+ readonly name: string;
6
+ readonly description?: string;
7
+ readonly inputSchema: Record<string, unknown>;
8
+ }
9
+ export declare function safeLocalToolArguments(value: unknown): Record<string, unknown>;
10
+ export declare function assertSafeUpstreamResult(value: unknown, centralToken?: string): void;
@@ -0,0 +1,63 @@
1
+ const FORBIDDEN_LOCAL_NAMES = new Set([
2
+ "access_token",
3
+ "authorization",
4
+ "dpop",
5
+ "jwt",
6
+ "private_key",
7
+ "proof",
8
+ "token",
9
+ ]);
10
+ const FORBIDDEN_RESULT_NAMES = new Set([
11
+ "access_token",
12
+ "authorization",
13
+ "dpop",
14
+ "jwt",
15
+ "private_key",
16
+ "proof",
17
+ "token",
18
+ ]);
19
+ export class McpContractError extends Error {
20
+ constructor() {
21
+ super("The local MCP contract is invalid");
22
+ this.name = "McpContractError";
23
+ }
24
+ }
25
+ function isRecord(value) {
26
+ return value !== null && typeof value === "object" && !Array.isArray(value);
27
+ }
28
+ function assertNoNames(value, forbidden) {
29
+ if (Array.isArray(value)) {
30
+ for (const item of value)
31
+ assertNoNames(item, forbidden);
32
+ return;
33
+ }
34
+ if (!isRecord(value))
35
+ return;
36
+ for (const [name, nested] of Object.entries(value)) {
37
+ if (forbidden.has(name.toLowerCase()))
38
+ throw new McpContractError();
39
+ assertNoNames(nested, forbidden);
40
+ }
41
+ }
42
+ function containsBytes(value, bytes) {
43
+ if (typeof value === "string")
44
+ return value.includes(bytes);
45
+ if (Array.isArray(value))
46
+ return value.some((item) => containsBytes(item, bytes));
47
+ if (!isRecord(value))
48
+ return false;
49
+ return Object.entries(value).some(([name, nested]) => name.includes(bytes) || containsBytes(nested, bytes));
50
+ }
51
+ export function safeLocalToolArguments(value) {
52
+ if (!isRecord(value))
53
+ throw new McpContractError();
54
+ assertNoNames(value, FORBIDDEN_LOCAL_NAMES);
55
+ return value;
56
+ }
57
+ export function assertSafeUpstreamResult(value, centralToken) {
58
+ assertNoNames(value, FORBIDDEN_RESULT_NAMES);
59
+ if (centralToken !== undefined && containsBytes(value, centralToken)) {
60
+ throw new McpContractError();
61
+ }
62
+ }
63
+ //# sourceMappingURL=mcp-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-contract.js","sourceRoot":"","sources":["../src/mcp-contract.ts"],"names":[],"mappings":"AAAA,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,cAAc;IACd,eAAe;IACf,MAAM;IACN,KAAK;IACL,aAAa;IACb,OAAO;IACP,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACrC,cAAc;IACd,eAAe;IACf,MAAM;IACN,KAAK;IACL,aAAa;IACb,OAAO;IACP,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC;QACE,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAQD,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,SAA8B;IACnE,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO;IAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACpE,aAAa,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc,EAAE,KAAa;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAClF,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAC/B,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CACzE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC;IACnD,aAAa,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC5C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc,EAAE,YAAqB;IAC5E,aAAa,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;IAC7C,IAAI,YAAY,KAAK,SAAS,IAAI,aAAa,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,gBAAgB,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ export type NotificationDeliveryState = "pending" | "delivering" | "accepted" | "completed" | "acknowledging";
2
+ export interface NotificationDeliveryRecord {
3
+ readonly messageId: string;
4
+ readonly deliveryState: NotificationDeliveryState;
5
+ }
6
+ export interface NotificationIngestResult {
7
+ readonly inserted: number;
8
+ readonly duplicates: number;
9
+ }
10
+ export declare function validateNotificationId(value: unknown): string;
11
+ export declare class NotificationJournal {
12
+ #private;
13
+ constructor(path: string);
14
+ close(): void;
15
+ ingest(messageIds: readonly string[]): NotificationIngestResult;
16
+ get(messageId: string): NotificationDeliveryRecord | undefined;
17
+ count(): number;
18
+ discardUndelivered(): number;
19
+ recoverableAcknowledgements(): NotificationDeliveryRecord[];
20
+ beginDelivery(messageId: string): void;
21
+ recordDelivered(messageId: string, state: "accepted" | "completed"): void;
22
+ beginAcknowledgement(messageId: string): void;
23
+ removeAcknowledged(messageId: string): void;
24
+ }
@@ -0,0 +1,194 @@
1
+ import Database from "better-sqlite3";
2
+ import { preparePrivateSqliteArtifact } from "./sqlite-artifact.js";
3
+ const SCHEMA_VERSION = 1;
4
+ const BUSY_TIMEOUT_MS = 5_000;
5
+ const TABLE_SQL = `
6
+ CREATE TABLE notification_delivery (
7
+ message_id TEXT PRIMARY KEY CHECK (
8
+ length(message_id) BETWEEN 1 AND 128
9
+ AND message_id NOT GLOB '*[^A-Za-z0-9._~-]*'
10
+ ),
11
+ delivery_state TEXT NOT NULL CHECK (
12
+ delivery_state IN ('pending', 'delivering', 'accepted', 'completed', 'acknowledging')
13
+ )
14
+ ) STRICT
15
+ `;
16
+ const journalResources = new WeakMap();
17
+ export function validateNotificationId(value) {
18
+ if (typeof value !== "string" ||
19
+ value.length < 1 ||
20
+ value.length > 128 ||
21
+ !/^[A-Za-z0-9._~-]+$/u.test(value)) {
22
+ throw new TypeError("notification ID must use 1 to 128 URI-unreserved ASCII characters");
23
+ }
24
+ return value;
25
+ }
26
+ function resourcesFor(journal) {
27
+ const resources = journalResources.get(journal);
28
+ if (resources === undefined)
29
+ throw new Error("notification journal is not initialized");
30
+ return resources;
31
+ }
32
+ function safeInteger(value) {
33
+ if (typeof value === "bigint") {
34
+ if (value < 0n || value > BigInt(Number.MAX_SAFE_INTEGER))
35
+ throw new Error("invalid count");
36
+ return Number(value);
37
+ }
38
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
39
+ throw new Error("invalid count");
40
+ }
41
+ return value;
42
+ }
43
+ function deliveryState(value) {
44
+ if (["pending", "delivering", "accepted", "completed", "acknowledging"].includes(value)) {
45
+ return value;
46
+ }
47
+ throw new Error("notification journal contains an invalid delivery state");
48
+ }
49
+ function record(row) {
50
+ return {
51
+ messageId: validateNotificationId(row.message_id),
52
+ deliveryState: deliveryState(row.delivery_state),
53
+ };
54
+ }
55
+ function normalizedSql(value) {
56
+ return value.replaceAll(/\s+/gu, " ").trim().toLowerCase();
57
+ }
58
+ function initialize(database) {
59
+ database
60
+ .transaction(() => {
61
+ const version = safeInteger(database.pragma("user_version", { simple: true }));
62
+ if (version > SCHEMA_VERSION)
63
+ throw new Error("notification journal schema is too new");
64
+ if (version === 0) {
65
+ const row = database
66
+ .prepare("SELECT count(*) AS count FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%'")
67
+ .get();
68
+ if (row === undefined || safeInteger(row.count) !== 0) {
69
+ throw new Error("notification journal has an obsolete or unversioned schema");
70
+ }
71
+ database.exec(`${TABLE_SQL};`);
72
+ database.pragma(`user_version = ${SCHEMA_VERSION}`);
73
+ }
74
+ const rows = database
75
+ .prepare("SELECT name, sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%' ORDER BY name")
76
+ .all();
77
+ if (rows.length !== 1 ||
78
+ rows[0]?.name !== "notification_delivery" ||
79
+ rows[0].sql === null ||
80
+ normalizedSql(rows[0].sql) !== normalizedSql(TABLE_SQL)) {
81
+ throw new Error("notification journal schema is invalid");
82
+ }
83
+ })
84
+ .immediate();
85
+ }
86
+ export class NotificationJournal {
87
+ constructor(path) {
88
+ const artifact = preparePrivateSqliteArtifact(path, () => new Error("Invalid journal path"));
89
+ let database;
90
+ try {
91
+ database = new Database(path, { timeout: BUSY_TIMEOUT_MS });
92
+ artifact.validate();
93
+ artifact.releaseFile();
94
+ database.defaultSafeIntegers(true);
95
+ database.pragma("journal_mode = WAL");
96
+ database.pragma("synchronous = FULL");
97
+ database.pragma("foreign_keys = ON");
98
+ database.pragma(`busy_timeout = ${BUSY_TIMEOUT_MS}`);
99
+ database.pragma("trusted_schema = OFF");
100
+ initialize(database);
101
+ artifact.validateDirectory();
102
+ journalResources.set(this, { database });
103
+ }
104
+ catch (error) {
105
+ database?.close();
106
+ throw error;
107
+ }
108
+ finally {
109
+ artifact.close();
110
+ }
111
+ }
112
+ close() {
113
+ const { database } = resourcesFor(this);
114
+ if (database.open)
115
+ database.close();
116
+ }
117
+ ingest(messageIds) {
118
+ const unique = new Set();
119
+ let duplicates = 0;
120
+ for (const value of messageIds) {
121
+ const id = validateNotificationId(value);
122
+ if (unique.has(id))
123
+ duplicates += 1;
124
+ else
125
+ unique.add(id);
126
+ }
127
+ const database = resourcesFor(this).database;
128
+ return database
129
+ .transaction(() => {
130
+ const insert = database.prepare("INSERT INTO notification_delivery (message_id, delivery_state) VALUES (?, 'pending') ON CONFLICT(message_id) DO NOTHING");
131
+ let inserted = 0;
132
+ for (const id of unique) {
133
+ const changes = safeInteger(insert.run(id).changes);
134
+ inserted += changes;
135
+ if (changes === 0)
136
+ duplicates += 1;
137
+ }
138
+ return { inserted, duplicates };
139
+ })
140
+ .immediate();
141
+ }
142
+ get(messageId) {
143
+ const row = resourcesFor(this)
144
+ .database.prepare("SELECT message_id, delivery_state FROM notification_delivery WHERE message_id = ?")
145
+ .get(validateNotificationId(messageId));
146
+ return row === undefined ? undefined : record(row);
147
+ }
148
+ count() {
149
+ const row = resourcesFor(this)
150
+ .database.prepare("SELECT count(*) AS count FROM notification_delivery")
151
+ .get();
152
+ if (row === undefined)
153
+ throw new Error("notification journal count failed");
154
+ return safeInteger(row.count);
155
+ }
156
+ discardUndelivered() {
157
+ return safeInteger(resourcesFor(this)
158
+ .database.prepare("DELETE FROM notification_delivery WHERE delivery_state IN ('pending', 'delivering')")
159
+ .run().changes);
160
+ }
161
+ recoverableAcknowledgements() {
162
+ return resourcesFor(this)
163
+ .database.prepare("SELECT message_id, delivery_state FROM notification_delivery WHERE delivery_state IN ('accepted', 'completed') ORDER BY message_id")
164
+ .all()
165
+ .map(record);
166
+ }
167
+ beginDelivery(messageId) {
168
+ this.#transition(messageId, ["pending"], "delivering");
169
+ }
170
+ recordDelivered(messageId, state) {
171
+ this.#transition(messageId, ["delivering"], state);
172
+ }
173
+ beginAcknowledgement(messageId) {
174
+ this.#transition(messageId, ["accepted", "completed"], "acknowledging");
175
+ }
176
+ removeAcknowledged(messageId) {
177
+ const id = validateNotificationId(messageId);
178
+ const changes = safeInteger(resourcesFor(this)
179
+ .database.prepare("DELETE FROM notification_delivery WHERE message_id = ? AND delivery_state = 'acknowledging'")
180
+ .run(id).changes);
181
+ if (changes !== 1)
182
+ throw new Error("notification acknowledgement removal failed");
183
+ }
184
+ #transition(messageId, from, to) {
185
+ const id = validateNotificationId(messageId);
186
+ const placeholders = from.map(() => "?").join(", ");
187
+ const changes = safeInteger(resourcesFor(this)
188
+ .database.prepare(`UPDATE notification_delivery SET delivery_state = ? WHERE message_id = ? AND delivery_state IN (${placeholders})`)
189
+ .run(to, id, ...from).changes);
190
+ if (changes !== 1)
191
+ throw new Error("notification journal transition failed");
192
+ }
193
+ }
194
+ //# sourceMappingURL=notification-journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-journal.js","sourceRoot":"","sources":["../src/notification-journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { CentralMessage } from "./central-rest.js";
2
+ import { type NotificationJournal } from "./notification-journal.js";
3
+ export type DeliveryResult = {
4
+ readonly status: "accepted" | "completed";
5
+ };
6
+ export interface DeliveryTarget {
7
+ deliver(message: CentralMessage, signal: AbortSignal): Promise<DeliveryResult>;
8
+ close(): Promise<void>;
9
+ }
10
+ export type NotificationRelayErrorCode = "already_running" | "invalid_configuration" | "invalid_notification_response" | "journal_failed" | "relay_failed";
11
+ export declare class NotificationRelayError extends Error {
12
+ readonly code: NotificationRelayErrorCode;
13
+ constructor(code: NotificationRelayErrorCode);
14
+ }
15
+ export declare class RetryableNotificationReceiveError extends Error {
16
+ readonly retryAfterMs?: number | undefined;
17
+ constructor(retryAfterMs?: number | undefined);
18
+ }
19
+ export interface NotificationRelayOptions {
20
+ readonly journal: NotificationJournal;
21
+ readonly deliveryTarget: DeliveryTarget;
22
+ readonly receiveMessages: (signal: AbortSignal) => Promise<readonly CentralMessage[]>;
23
+ readonly acknowledgeMessage: (messageId: string, signal: AbortSignal) => Promise<void>;
24
+ readonly retryDelayMs?: number;
25
+ }
26
+ export declare class NotificationRelay {
27
+ #private;
28
+ constructor(options: NotificationRelayOptions);
29
+ run(signal: AbortSignal): Promise<void>;
30
+ shutdown(): Promise<void>;
31
+ }
@@ -0,0 +1,203 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
2
+ import { validateNotificationId } from "./notification-journal.js";
3
+ const MAX_MESSAGES = 256;
4
+ const MAX_RESULT_BYTES = 512 * 1024;
5
+ const DEFAULT_RETRY_DELAY_MS = 250;
6
+ export class NotificationRelayError extends Error {
7
+ code;
8
+ constructor(code) {
9
+ super("Notification relay failed");
10
+ this.code = code;
11
+ this.name = "NotificationRelayError";
12
+ }
13
+ }
14
+ export class RetryableNotificationReceiveError extends Error {
15
+ retryAfterMs;
16
+ constructor(retryAfterMs) {
17
+ super("Central receive may be retried");
18
+ this.retryAfterMs = retryAfterMs;
19
+ this.name = "RetryableNotificationReceiveError";
20
+ }
21
+ }
22
+ function validateMessage(value) {
23
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
24
+ throw new NotificationRelayError("invalid_notification_response");
25
+ }
26
+ if (value.id !== undefined) {
27
+ try {
28
+ validateNotificationId(value.id);
29
+ }
30
+ catch {
31
+ throw new NotificationRelayError("invalid_notification_response");
32
+ }
33
+ }
34
+ let serialized;
35
+ try {
36
+ serialized = JSON.stringify(value);
37
+ }
38
+ catch {
39
+ throw new NotificationRelayError("invalid_notification_response");
40
+ }
41
+ if (Buffer.byteLength(serialized, "utf8") > MAX_RESULT_BYTES) {
42
+ throw new NotificationRelayError("invalid_notification_response");
43
+ }
44
+ return { message: value, serialized };
45
+ }
46
+ export class NotificationRelay {
47
+ #journal;
48
+ #deliveryTarget;
49
+ #receiveMessages;
50
+ #acknowledgeMessage;
51
+ #retryDelayMs;
52
+ #controller;
53
+ #running;
54
+ #closingTarget;
55
+ #shutdownRequested = false;
56
+ constructor(options) {
57
+ this.#journal = options.journal;
58
+ this.#deliveryTarget = options.deliveryTarget;
59
+ this.#receiveMessages = options.receiveMessages;
60
+ this.#acknowledgeMessage = options.acknowledgeMessage;
61
+ this.#retryDelayMs = options.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;
62
+ if (!Number.isSafeInteger(this.#retryDelayMs) || this.#retryDelayMs < 1) {
63
+ throw new NotificationRelayError("invalid_configuration");
64
+ }
65
+ }
66
+ run(signal) {
67
+ if (this.#running !== undefined)
68
+ throw new NotificationRelayError("already_running");
69
+ const controller = new AbortController();
70
+ this.#controller = controller;
71
+ this.#shutdownRequested = false;
72
+ const combined = AbortSignal.any([signal, controller.signal]);
73
+ const running = this.#execute(combined).finally(async () => {
74
+ await this.#closeTarget();
75
+ if (this.#running === running) {
76
+ this.#running = undefined;
77
+ this.#controller = undefined;
78
+ }
79
+ });
80
+ this.#running = running;
81
+ return running;
82
+ }
83
+ async shutdown() {
84
+ this.#shutdownRequested = true;
85
+ this.#controller?.abort();
86
+ await this.#closeTarget();
87
+ await this.#running;
88
+ }
89
+ #closeTarget() {
90
+ this.#closingTarget ??= this.#deliveryTarget.close().catch(() => undefined);
91
+ return this.#closingTarget;
92
+ }
93
+ async #execute(signal) {
94
+ try {
95
+ this.#journal.discardUndelivered();
96
+ for (const item of this.#journal.recoverableAcknowledgements()) {
97
+ if (signal.aborted)
98
+ return;
99
+ await this.#acknowledge(item.messageId, signal);
100
+ }
101
+ while (!signal.aborted) {
102
+ let messages;
103
+ try {
104
+ messages = await this.#receiveMessages(signal);
105
+ }
106
+ catch (error) {
107
+ if (signal.aborted)
108
+ return;
109
+ if (!(error instanceof RetryableNotificationReceiveError))
110
+ throw error;
111
+ const retryAfter = error.retryAfterMs ?? this.#retryDelayMs;
112
+ if (!Number.isSafeInteger(retryAfter) || retryAfter < 1) {
113
+ throw new NotificationRelayError("invalid_configuration");
114
+ }
115
+ await delay(retryAfter, undefined, { signal }).catch(() => undefined);
116
+ continue;
117
+ }
118
+ if (messages.length > MAX_MESSAGES) {
119
+ throw new NotificationRelayError("invalid_notification_response");
120
+ }
121
+ const queue = messages.map(validateMessage);
122
+ if (Buffer.byteLength(JSON.stringify({ messages: queue.map(({ message }) => message) }), "utf8") > MAX_RESULT_BYTES) {
123
+ throw new NotificationRelayError("invalid_notification_response");
124
+ }
125
+ const byId = new Map();
126
+ const deliveryQueue = [];
127
+ for (const item of queue) {
128
+ if (item.message.id === undefined) {
129
+ deliveryQueue.push(item);
130
+ continue;
131
+ }
132
+ const prior = byId.get(item.message.id);
133
+ if (prior !== undefined && prior !== item.serialized) {
134
+ throw new NotificationRelayError("invalid_notification_response");
135
+ }
136
+ if (prior === undefined)
137
+ deliveryQueue.push(item);
138
+ byId.set(item.message.id, item.serialized);
139
+ }
140
+ try {
141
+ this.#journal.ingest([...byId.keys()]);
142
+ }
143
+ catch {
144
+ throw new NotificationRelayError("journal_failed");
145
+ }
146
+ for (const item of deliveryQueue) {
147
+ if (signal.aborted)
148
+ return;
149
+ await this.#deliver(item.message, signal);
150
+ }
151
+ }
152
+ }
153
+ catch (error) {
154
+ if (signal.aborted || this.#shutdownRequested)
155
+ return;
156
+ if (error instanceof NotificationRelayError)
157
+ throw error;
158
+ throw new NotificationRelayError("relay_failed");
159
+ }
160
+ }
161
+ async #deliver(message, signal) {
162
+ const id = message.id;
163
+ if (id !== undefined) {
164
+ const existing = this.#journal.get(id);
165
+ if (existing?.deliveryState === "accepted" || existing?.deliveryState === "completed") {
166
+ await this.#acknowledge(id, signal);
167
+ return;
168
+ }
169
+ try {
170
+ this.#journal.beginDelivery(id);
171
+ }
172
+ catch {
173
+ throw new NotificationRelayError("journal_failed");
174
+ }
175
+ }
176
+ const result = await this.#deliveryTarget.deliver(message, signal);
177
+ if (id === undefined)
178
+ return;
179
+ try {
180
+ this.#journal.recordDelivered(id, result.status);
181
+ }
182
+ catch {
183
+ throw new NotificationRelayError("journal_failed");
184
+ }
185
+ await this.#acknowledge(id, signal);
186
+ }
187
+ async #acknowledge(messageId, signal) {
188
+ try {
189
+ this.#journal.beginAcknowledgement(messageId);
190
+ }
191
+ catch {
192
+ throw new NotificationRelayError("journal_failed");
193
+ }
194
+ await this.#acknowledgeMessage(messageId, signal);
195
+ try {
196
+ this.#journal.removeAcknowledged(messageId);
197
+ }
198
+ catch {
199
+ throw new NotificationRelayError("journal_failed");
200
+ }
201
+ }
202
+ }
203
+ //# sourceMappingURL=notification-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-relay.js","sourceRoot":"","sources":["../src/notification-relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare class ProcessLock {
2
+ private readonly database;
3
+ private readonly keys;
4
+ private released;
5
+ private constructor();
6
+ static acquire(path: string): Promise<ProcessLock>;
7
+ release(): Promise<void>;
8
+ }