@hotmeshio/long-tail 0.25.4 → 0.27.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 +1 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +36 -7
- package/build/lib/events/nats.d.ts +11 -0
- package/build/lib/events/nats.js +33 -2
- package/build/lib/machines/index.d.ts +6 -0
- package/build/lib/machines/index.js +22 -0
- package/build/lib/machines/line.d.ts +44 -0
- package/build/lib/machines/line.js +114 -0
- package/build/lib/machines/protocol/codec.d.ts +108 -0
- package/build/lib/machines/protocol/codec.js +80 -0
- package/build/lib/machines/protocol/constants.d.ts +120 -0
- package/build/lib/machines/protocol/constants.js +97 -0
- package/build/lib/machines/protocol/contract.d.ts +19 -0
- package/build/lib/machines/protocol/contract.js +141 -0
- package/build/lib/machines/protocol/envelope.d.ts +14 -0
- package/build/lib/machines/protocol/envelope.js +43 -0
- package/build/lib/machines/protocol/index.d.ts +5 -0
- package/build/lib/machines/protocol/index.js +21 -0
- package/build/lib/machines/protocol/topics.d.ts +33 -0
- package/build/lib/machines/protocol/topics.js +79 -0
- package/build/lib/machines/site/edge-account.d.ts +11 -0
- package/build/lib/machines/site/edge-account.js +24 -0
- package/build/lib/machines/site/mosquitto-conf.d.ts +27 -0
- package/build/lib/machines/site/mosquitto-conf.js +81 -0
- package/build/lib/machines/site/site-conf.d.ts +23 -0
- package/build/lib/machines/site/site-conf.js +62 -0
- package/build/lib/machines/transport/callback-feed.d.ts +18 -0
- package/build/lib/machines/transport/callback-feed.js +31 -0
- package/build/lib/machines/transport/delivery.d.ts +20 -0
- package/build/lib/machines/transport/delivery.js +37 -0
- package/build/lib/machines/transport/index.d.ts +13 -0
- package/build/lib/machines/transport/index.js +29 -0
- package/build/lib/machines/transport/memory-broker.d.ts +35 -0
- package/build/lib/machines/transport/memory-broker.js +145 -0
- package/build/lib/machines/transport/memory.d.ts +40 -0
- package/build/lib/machines/transport/memory.js +79 -0
- package/build/lib/machines/transport/mqtt-bus.d.ts +24 -0
- package/build/lib/machines/transport/mqtt-bus.js +43 -0
- package/build/lib/machines/transport/mqtt-link.d.ts +16 -0
- package/build/lib/machines/transport/mqtt-link.js +37 -0
- package/build/lib/machines/transport/mqtt-session.d.ts +34 -0
- package/build/lib/machines/transport/mqtt-session.js +127 -0
- package/build/lib/machines/transport/nats-bus.d.ts +36 -0
- package/build/lib/machines/transport/nats-bus.js +47 -0
- package/build/lib/machines/transport/nats-feed.d.ts +26 -0
- package/build/lib/machines/transport/nats-feed.js +49 -0
- package/build/lib/machines/transport/pubsub-feed.d.ts +17 -0
- package/build/lib/machines/transport/pubsub-feed.js +39 -0
- package/build/lib/machines/transport/serial.d.ts +21 -0
- package/build/lib/machines/transport/serial.js +54 -0
- package/build/lib/machines/transport/stream-bus.d.ts +40 -0
- package/build/lib/machines/transport/stream-bus.js +57 -0
- package/build/lib/machines/transport/streams.d.ts +24 -0
- package/build/lib/machines/transport/streams.js +49 -0
- package/build/lib/messaging/config.d.ts +25 -0
- package/build/lib/messaging/config.js +55 -0
- package/build/lib/messaging/constants.d.ts +26 -0
- package/build/lib/messaging/constants.js +26 -0
- package/build/lib/messaging/index.d.ts +24 -0
- package/build/lib/messaging/index.js +65 -0
- package/build/lib/messaging/memory.d.ts +16 -0
- package/build/lib/messaging/memory.js +147 -0
- package/build/lib/messaging/nats/permissions.d.ts +13 -0
- package/build/lib/messaging/nats/permissions.js +22 -0
- package/build/lib/messaging/nats/provider.d.ts +30 -0
- package/build/lib/messaging/nats/provider.js +77 -0
- package/build/lib/messaging/nats/render-conf.d.ts +68 -0
- package/build/lib/messaging/nats/render-conf.js +58 -0
- package/build/lib/messaging/nats/streams.d.ts +26 -0
- package/build/lib/messaging/nats/streams.js +97 -0
- package/build/lib/messaging/subjects.d.ts +8 -0
- package/build/lib/messaging/subjects.js +25 -0
- package/build/scripts/bambu-boat.d.ts +17 -0
- package/build/scripts/bambu-boat.js +134 -0
- package/build/scripts/bambu-print.d.ts +18 -0
- package/build/scripts/bambu-print.js +114 -0
- package/build/scripts/machine-line.d.ts +33 -0
- package/build/scripts/machine-line.js +301 -0
- package/build/services/machines/commands.d.ts +29 -0
- package/build/services/machines/commands.js +37 -0
- package/build/services/machines/config.d.ts +49 -0
- package/build/services/machines/config.js +94 -0
- package/build/services/machines/contracts.d.ts +210 -0
- package/build/services/machines/contracts.js +124 -0
- package/build/services/machines/forms.d.ts +55 -0
- package/build/services/machines/forms.js +37 -0
- package/build/services/machines/gateway/actions.d.ts +111 -0
- package/build/services/machines/gateway/actions.js +8 -0
- package/build/services/machines/gateway/address-book.d.ts +16 -0
- package/build/services/machines/gateway/address-book.js +24 -0
- package/build/services/machines/gateway/admission.d.ts +35 -0
- package/build/services/machines/gateway/admission.js +66 -0
- package/build/services/machines/gateway/api-escalations.d.ts +23 -0
- package/build/services/machines/gateway/api-escalations.js +101 -0
- package/build/services/machines/gateway/dispatcher.d.ts +76 -0
- package/build/services/machines/gateway/dispatcher.js +197 -0
- package/build/services/machines/gateway/escalations.d.ts +51 -0
- package/build/services/machines/gateway/escalations.js +40 -0
- package/build/services/machines/gateway/executor.d.ts +60 -0
- package/build/services/machines/gateway/executor.js +221 -0
- package/build/services/machines/gateway/gateway.d.ts +88 -0
- package/build/services/machines/gateway/gateway.js +270 -0
- package/build/services/machines/gateway/index.d.ts +10 -0
- package/build/services/machines/gateway/index.js +26 -0
- package/build/services/machines/gateway/jobs.d.ts +16 -0
- package/build/services/machines/gateway/jobs.js +24 -0
- package/build/services/machines/gateway/lifecycle.d.ts +21 -0
- package/build/services/machines/gateway/lifecycle.js +89 -0
- package/build/services/machines/gateway/log.d.ts +41 -0
- package/build/services/machines/gateway/log.js +42 -0
- package/build/services/machines/gateway/lt-http.d.ts +51 -0
- package/build/services/machines/gateway/lt-http.js +120 -0
- package/build/services/machines/gateway/pacing.d.ts +43 -0
- package/build/services/machines/gateway/pacing.js +158 -0
- package/build/services/machines/gateway/plan-escalation.d.ts +19 -0
- package/build/services/machines/gateway/plan-escalation.js +210 -0
- package/build/services/machines/gateway/plan-machine.d.ts +17 -0
- package/build/services/machines/gateway/plan-machine.js +283 -0
- package/build/services/machines/gateway/plan-shared.d.ts +18 -0
- package/build/services/machines/gateway/plan-shared.js +36 -0
- package/build/services/machines/gateway/provision.d.ts +22 -0
- package/build/services/machines/gateway/provision.js +79 -0
- package/build/services/machines/gateway/receipts.d.ts +33 -0
- package/build/services/machines/gateway/receipts.js +65 -0
- package/build/services/machines/gateway/reconcile.d.ts +35 -0
- package/build/services/machines/gateway/reconcile.js +99 -0
- package/build/services/machines/gateway/registration.d.ts +38 -0
- package/build/services/machines/gateway/registration.js +121 -0
- package/build/services/machines/gateway/reply-waiter.d.ts +24 -0
- package/build/services/machines/gateway/reply-waiter.js +65 -0
- package/build/services/machines/gateway/state.d.ts +145 -0
- package/build/services/machines/gateway/state.js +241 -0
- package/build/services/machines/gateway/trace.d.ts +16 -0
- package/build/services/machines/gateway/trace.js +43 -0
- package/build/services/machines/identities.d.ts +25 -0
- package/build/services/machines/identities.js +77 -0
- package/build/services/machines/index.d.ts +11 -0
- package/build/services/machines/index.js +27 -0
- package/build/services/machines/leadership.d.ts +35 -0
- package/build/services/machines/leadership.js +100 -0
- package/build/services/machines/roles.d.ts +13 -0
- package/build/services/machines/roles.js +62 -0
- package/build/services/machines/rows.d.ts +30 -0
- package/build/services/machines/rows.js +71 -0
- package/build/services/machines/select.d.ts +25 -0
- package/build/services/machines/select.js +76 -0
- package/build/services/machines/surface.d.ts +33 -0
- package/build/services/machines/surface.js +104 -0
- package/build/services/machines/testing/fake-long-tail.d.ts +79 -0
- package/build/services/machines/testing/fake-long-tail.js +158 -0
- package/build/services/machines/testing/index.d.ts +3 -0
- package/build/services/machines/testing/index.js +19 -0
- package/build/services/machines/testing/recording-log.d.ts +14 -0
- package/build/services/machines/testing/recording-log.js +22 -0
- package/build/services/machines/testing/wait.d.ts +3 -0
- package/build/services/machines/testing/wait.js +17 -0
- package/build/services/mcp/db-server/schemas.d.ts +2 -2
- package/build/start/adapters.js +11 -2
- package/build/start/index.js +20 -1
- package/build/system/mcp-servers/admin/schemas.d.ts +221 -221
- package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
- package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/index.d.ts +3 -1
- package/build/types/machines.d.ts +167 -0
- package/build/types/machines.js +7 -0
- package/build/types/messaging.d.ts +72 -0
- package/build/types/messaging.js +11 -0
- package/build/types/startup.d.ts +49 -1
- package/docs/events.md +50 -4
- package/docs/machines.md +322 -0
- package/package.json +13 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* An in-memory Long Tail for the machine gateway: escalation rows with the
|
|
4
|
+
* claim / accumulate / resolve / create verbs, each publishing the lifecycle
|
|
5
|
+
* event Long Tail publishes, plus helpers that play the unit workflow and the
|
|
6
|
+
* people (exit, operator).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FakeLongTail = void 0;
|
|
10
|
+
const actions_1 = require("../gateway/actions");
|
|
11
|
+
const escalations_1 = require("../gateway/escalations");
|
|
12
|
+
const contracts_1 = require("../contracts");
|
|
13
|
+
const wait_1 = require("./wait");
|
|
14
|
+
class FakeLongTail {
|
|
15
|
+
/** The next `times` calls of `verb` fail as a Long Tail outage would (5xx). */
|
|
16
|
+
failNext(verb, times = 1) {
|
|
17
|
+
this.failing.set(verb, times);
|
|
18
|
+
}
|
|
19
|
+
hidden(as, row) {
|
|
20
|
+
const roles = this.holds.get(as);
|
|
21
|
+
return !!row && !!roles && !roles.has(row.role);
|
|
22
|
+
}
|
|
23
|
+
outage(verb) {
|
|
24
|
+
const left = this.failing.get(verb) ?? 0;
|
|
25
|
+
if (left <= 0)
|
|
26
|
+
return;
|
|
27
|
+
this.failing.set(verb, left - 1);
|
|
28
|
+
throw new Error(`Long Tail unavailable (${verb})`);
|
|
29
|
+
}
|
|
30
|
+
constructor(feed) {
|
|
31
|
+
this.feed = feed;
|
|
32
|
+
this.rows = new Map();
|
|
33
|
+
this.calls = [];
|
|
34
|
+
this.seq = 0;
|
|
35
|
+
this.failing = new Map();
|
|
36
|
+
/** Roles each actor holds; an actor outside a row's role gets not found, as Long Tail's RBAC answers. */
|
|
37
|
+
this.holds = new Map();
|
|
38
|
+
}
|
|
39
|
+
emit(row, verb, extra = {}) {
|
|
40
|
+
this.feed.emit({
|
|
41
|
+
type: `system.escalation.${row.role}.${row.id}.${verb}`, escalationId: row.id, role: row.role,
|
|
42
|
+
data: { id: row.id, type: row.type, subtype: row.subtype, role: row.role, status: row.status, assigned_to: row.assigned_to, metadata: row.metadata, ...extra },
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
add(input) {
|
|
46
|
+
const row = { ...input, id: `e${++this.seq}`, status: 'pending', items: [], created_at: new Date().toISOString() };
|
|
47
|
+
this.rows.set(row.id, row);
|
|
48
|
+
this.emit(row, 'created');
|
|
49
|
+
return row;
|
|
50
|
+
}
|
|
51
|
+
/** What the unit workflow's conditionalAccumulator does: park a handoff row. */
|
|
52
|
+
park(role, facets) {
|
|
53
|
+
return this.add({ type: contracts_1.ROW_TYPE.HANDOFF, role, metadata: { ...facets } });
|
|
54
|
+
}
|
|
55
|
+
/** Park any row, as a host workflow parks its own. */
|
|
56
|
+
parkRow(input) {
|
|
57
|
+
return this.add({ ...input, metadata: { ...input.metadata } });
|
|
58
|
+
}
|
|
59
|
+
/** A person resolving a row on the dashboard. */
|
|
60
|
+
personResolves(id, payload, person = 'person-1') {
|
|
61
|
+
const row = this.rows.get(id);
|
|
62
|
+
row.status = 'resolved';
|
|
63
|
+
row.resolver_payload = payload;
|
|
64
|
+
row.resolved_by = person;
|
|
65
|
+
this.emit(row, 'resolved', { resolved_by: person });
|
|
66
|
+
}
|
|
67
|
+
/** A person or the workflow cancelling the row. */
|
|
68
|
+
cancel(id) {
|
|
69
|
+
const row = this.rows.get(id);
|
|
70
|
+
row.status = 'cancelled';
|
|
71
|
+
this.emit(row, 'cancelled');
|
|
72
|
+
}
|
|
73
|
+
/** The row's timeout firing (conditional `timeout`). */
|
|
74
|
+
expire(id) {
|
|
75
|
+
const row = this.rows.get(id);
|
|
76
|
+
row.status = 'expired';
|
|
77
|
+
this.emit(row, 'expired');
|
|
78
|
+
}
|
|
79
|
+
async claim(as, id) {
|
|
80
|
+
this.outage('claim');
|
|
81
|
+
this.calls.push({ verb: 'claim', as, id });
|
|
82
|
+
const row = this.rows.get(id);
|
|
83
|
+
if (!row || row.status !== 'pending')
|
|
84
|
+
return { outcome: escalations_1.VERB_OUTCOME.ALREADY };
|
|
85
|
+
row.assigned_to = as;
|
|
86
|
+
this.emit(row, 'claimed');
|
|
87
|
+
return { outcome: escalations_1.VERB_OUTCOME.DONE };
|
|
88
|
+
}
|
|
89
|
+
async accumulate(as, id, itemKey, payload, metadata) {
|
|
90
|
+
this.outage('accumulate');
|
|
91
|
+
this.calls.push({ verb: 'accumulate', as, id, payload: { itemKey, ...payload } });
|
|
92
|
+
const row = this.rows.get(id);
|
|
93
|
+
if (this.hidden(as, row))
|
|
94
|
+
return { outcome: escalations_1.VERB_OUTCOME.ALREADY, status: 404 };
|
|
95
|
+
if (!row || row.status !== 'pending')
|
|
96
|
+
return { outcome: escalations_1.VERB_OUTCOME.ALREADY };
|
|
97
|
+
if (row.items.some((i) => i.itemKey === itemKey))
|
|
98
|
+
return { outcome: escalations_1.VERB_OUTCOME.ALREADY };
|
|
99
|
+
row.items.push({ itemKey, payload, actor: as });
|
|
100
|
+
if (metadata)
|
|
101
|
+
row.metadata = { ...row.metadata, ...metadata };
|
|
102
|
+
return { outcome: escalations_1.VERB_OUTCOME.DONE, itemKeys: row.items.map((i) => i.itemKey) };
|
|
103
|
+
}
|
|
104
|
+
async resolve(as, id, payload) {
|
|
105
|
+
this.outage('resolve');
|
|
106
|
+
this.calls.push({ verb: 'resolve', as, id, payload });
|
|
107
|
+
const row = this.rows.get(id);
|
|
108
|
+
if (!row || row.status !== 'pending')
|
|
109
|
+
return { outcome: escalations_1.VERB_OUTCOME.ALREADY };
|
|
110
|
+
// Long Tail refuses a resolve by id while someone else holds a live claim (409).
|
|
111
|
+
if (row.assigned_to && row.assigned_to !== as)
|
|
112
|
+
return { outcome: escalations_1.VERB_OUTCOME.ALREADY, detail: 'claimed by another' };
|
|
113
|
+
row.status = 'resolved';
|
|
114
|
+
row.resolver_payload = payload;
|
|
115
|
+
row.resolved_by = as;
|
|
116
|
+
this.emit(row, 'resolved', { resolved_by: as });
|
|
117
|
+
return { outcome: escalations_1.VERB_OUTCOME.DONE };
|
|
118
|
+
}
|
|
119
|
+
async create(_as, input) {
|
|
120
|
+
this.outage('create');
|
|
121
|
+
return { id: this.add({ ...input }).id };
|
|
122
|
+
}
|
|
123
|
+
async itemKeys(id) {
|
|
124
|
+
return (this.rows.get(id)?.items ?? []).map((i) => i.itemKey);
|
|
125
|
+
}
|
|
126
|
+
async items(id) {
|
|
127
|
+
return (this.rows.get(id)?.items ?? []).map((i) => ({ itemKey: i.itemKey, payload: i.payload }));
|
|
128
|
+
}
|
|
129
|
+
async get(id) {
|
|
130
|
+
const row = this.rows.get(id);
|
|
131
|
+
if (!row || this.hidden(actions_1.CONTROLLER, row))
|
|
132
|
+
return null;
|
|
133
|
+
return {
|
|
134
|
+
id: row.id, type: row.type, subtype: row.subtype, role: row.role, status: row.status,
|
|
135
|
+
assigned_to: row.assigned_to ?? null, resolved_by: row.resolved_by ?? null, metadata: { ...row.metadata }, created_at: row.created_at ?? null,
|
|
136
|
+
// Stored serialized, as Long Tail returns it.
|
|
137
|
+
resolver_payload: row.resolver_payload ? JSON.stringify(row.resolver_payload) : null,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
async listOpen(query) {
|
|
141
|
+
return [...this.rows.values()]
|
|
142
|
+
.filter((r) => r.status === 'pending' && (!query.type || r.type === query.type) && (!query.role || r.role === query.role))
|
|
143
|
+
.map((r) => ({
|
|
144
|
+
id: r.id, type: r.type, subtype: r.subtype, role: r.role, status: r.status, assigned_to: r.assigned_to ?? null, metadata: r.metadata,
|
|
145
|
+
created_at: r.created_at ?? null,
|
|
146
|
+
}));
|
|
147
|
+
}
|
|
148
|
+
ofType(type) {
|
|
149
|
+
return [...this.rows.values()].filter((r) => r.type === type);
|
|
150
|
+
}
|
|
151
|
+
ended(id, ms = 1_000) {
|
|
152
|
+
return (0, wait_1.until)(() => {
|
|
153
|
+
const row = this.rows.get(id);
|
|
154
|
+
return row && row.status !== 'pending' ? row : undefined;
|
|
155
|
+
}, ms);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.FakeLongTail = FakeLongTail;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./fake-long-tail"), exports);
|
|
18
|
+
__exportStar(require("./wait"), exports);
|
|
19
|
+
__exportStar(require("./recording-log"), exports);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GatewayLog, GatewayLogEvent } from '../gateway/log';
|
|
2
|
+
export interface LogEntry {
|
|
3
|
+
level: 'info' | 'warn' | 'error';
|
|
4
|
+
event: GatewayLogEvent;
|
|
5
|
+
context: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
/** A gateway log that keeps every entry, for assertions. */
|
|
8
|
+
export declare class RecordingLog implements GatewayLog {
|
|
9
|
+
readonly entries: LogEntry[];
|
|
10
|
+
info(event: GatewayLogEvent, context?: Record<string, unknown>): void;
|
|
11
|
+
warn(event: GatewayLogEvent, context?: Record<string, unknown>): void;
|
|
12
|
+
error(event: GatewayLogEvent, context?: Record<string, unknown>): void;
|
|
13
|
+
of(event: GatewayLogEvent): Record<string, unknown>[];
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RecordingLog = void 0;
|
|
4
|
+
/** A gateway log that keeps every entry, for assertions. */
|
|
5
|
+
class RecordingLog {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.entries = [];
|
|
8
|
+
}
|
|
9
|
+
info(event, context = {}) {
|
|
10
|
+
this.entries.push({ level: 'info', event, context });
|
|
11
|
+
}
|
|
12
|
+
warn(event, context = {}) {
|
|
13
|
+
this.entries.push({ level: 'warn', event, context });
|
|
14
|
+
}
|
|
15
|
+
error(event, context = {}) {
|
|
16
|
+
this.entries.push({ level: 'error', event, context });
|
|
17
|
+
}
|
|
18
|
+
of(event) {
|
|
19
|
+
return this.entries.filter((e) => e.event === event).map((e) => e.context);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.RecordingLog = RecordingLog;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sleep = void 0;
|
|
4
|
+
exports.until = until;
|
|
5
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
6
|
+
exports.sleep = sleep;
|
|
7
|
+
/** Resolve with the first truthy value `check` returns, or throw after `ms`. */
|
|
8
|
+
async function until(check, ms = 500) {
|
|
9
|
+
const end = Date.now() + ms;
|
|
10
|
+
while (Date.now() < end) {
|
|
11
|
+
const value = check();
|
|
12
|
+
if (value)
|
|
13
|
+
return value;
|
|
14
|
+
await (0, exports.sleep)(2);
|
|
15
|
+
}
|
|
16
|
+
throw new Error('condition not met in time');
|
|
17
|
+
}
|
|
@@ -8,13 +8,13 @@ export declare const findTasksSchema: z.ZodObject<{
|
|
|
8
8
|
}, "strip", z.ZodTypeAny, {
|
|
9
9
|
limit: number;
|
|
10
10
|
status?: "completed" | "pending" | "in_progress" | "needs_intervention" | "failed" | undefined;
|
|
11
|
-
workflow_type?: string | undefined;
|
|
12
11
|
workflow_id?: string | undefined;
|
|
12
|
+
workflow_type?: string | undefined;
|
|
13
13
|
origin_id?: string | undefined;
|
|
14
14
|
}, {
|
|
15
15
|
status?: "completed" | "pending" | "in_progress" | "needs_intervention" | "failed" | undefined;
|
|
16
|
-
workflow_type?: string | undefined;
|
|
17
16
|
workflow_id?: string | undefined;
|
|
17
|
+
workflow_type?: string | undefined;
|
|
18
18
|
origin_id?: string | undefined;
|
|
19
19
|
limit?: number | undefined;
|
|
20
20
|
}>;
|
package/build/start/adapters.js
CHANGED
|
@@ -6,6 +6,8 @@ const pino_1 = require("../lib/logger/pino");
|
|
|
6
6
|
const telemetry_1 = require("../lib/telemetry");
|
|
7
7
|
const honeycomb_1 = require("../lib/telemetry/honeycomb");
|
|
8
8
|
const events_1 = require("../lib/events");
|
|
9
|
+
const messaging_1 = require("../lib/messaging");
|
|
10
|
+
const config_1 = require("../lib/messaging/config");
|
|
9
11
|
const nats_1 = require("../lib/events/nats");
|
|
10
12
|
const socketio_1 = require("../lib/events/socketio");
|
|
11
13
|
const maintenance_1 = require("../services/maintenance");
|
|
@@ -44,6 +46,10 @@ function registerAdapters(startConfig) {
|
|
|
44
46
|
else if (startConfig.telemetry?.honeycomb) {
|
|
45
47
|
telemetry_1.telemetryRegistry.register(new honeycomb_1.HoneycombTelemetryAdapter(startConfig.telemetry.honeycomb));
|
|
46
48
|
}
|
|
49
|
+
// Messaging: one provider shared by events and the machine surface.
|
|
50
|
+
const messaging = (0, config_1.resolveMessaging)(startConfig);
|
|
51
|
+
if (messaging.provider)
|
|
52
|
+
messaging_1.messagingRegistry.register(messaging.provider);
|
|
47
53
|
// Events — register the configured transport.
|
|
48
54
|
// Socket.IO is the default for single-container ("nothing but Postgres").
|
|
49
55
|
// When NATS or custom adapters are configured, Socket.IO is NOT registered —
|
|
@@ -54,8 +60,11 @@ function registerAdapters(startConfig) {
|
|
|
54
60
|
events_1.eventRegistry.register(adapter);
|
|
55
61
|
}
|
|
56
62
|
}
|
|
57
|
-
else if (
|
|
58
|
-
events_1.eventRegistry.register(new nats_1.NatsEventAdapter(
|
|
63
|
+
else if (messaging.provider?.name === config_1.MESSAGING_KIND.NATS) {
|
|
64
|
+
events_1.eventRegistry.register(new nats_1.NatsEventAdapter({
|
|
65
|
+
messaging: messaging.provider, wsUrl: messaging.ws.url, wsProxy: messaging.ws.proxy, token: messaging.ws.token,
|
|
66
|
+
subjectPrefix: startConfig.events?.nats?.subjectPrefix,
|
|
67
|
+
}));
|
|
59
68
|
}
|
|
60
69
|
else {
|
|
61
70
|
events_1.eventRegistry.register(new socketio_1.SocketIOEventAdapter({
|
package/build/start/index.js
CHANGED
|
@@ -5,6 +5,10 @@ const hotmesh_1 = require("@hotmeshio/hotmesh");
|
|
|
5
5
|
const logger_1 = require("../lib/logger");
|
|
6
6
|
const telemetry_1 = require("../lib/telemetry");
|
|
7
7
|
const events_1 = require("../lib/events");
|
|
8
|
+
const messaging_1 = require("../lib/messaging");
|
|
9
|
+
const callback_1 = require("../lib/events/callback");
|
|
10
|
+
const surface_1 = require("../services/machines/surface");
|
|
11
|
+
const roles_1 = require("../services/machines/roles");
|
|
8
12
|
const maintenance_1 = require("../services/maintenance");
|
|
9
13
|
const cron_1 = require("../services/cron");
|
|
10
14
|
const mcp_1 = require("../services/mcp");
|
|
@@ -63,12 +67,23 @@ async function start(startConfig) {
|
|
|
63
67
|
(0, config_1.applyDatabaseConfig)(startConfig.database);
|
|
64
68
|
// 2. Apply server/auth config
|
|
65
69
|
await (0, config_1.applyServerAuthConfig)(startConfig);
|
|
66
|
-
// 3. Register adapters
|
|
70
|
+
// 3. Register adapters; messaging connects first, since events and machines use it.
|
|
71
|
+
// An unreachable NATS is logged and Long Tail starts, as events always have; what needs streams fails then.
|
|
67
72
|
(0, adapters_1.registerAdapters)(startConfig);
|
|
73
|
+
await messaging_1.messagingRegistry.connect().catch((err) => {
|
|
74
|
+
logger_1.loggerRegistry.error(`${messaging_1.MESSAGING_LOG.CONNECT_FAILED} ${err instanceof Error ? err.message : String(err)}`);
|
|
75
|
+
});
|
|
68
76
|
logger_1.loggerRegistry.info('[long-tail] starting...');
|
|
69
77
|
// 4-5. Collect workers, run migrations, start workers, seed data
|
|
78
|
+
if (startConfig.machines && startConfig.machines.declareRoles !== false) {
|
|
79
|
+
startConfig = { ...startConfig, roles: (0, roles_1.withMachineRoles)(startConfig.roles, startConfig.machines.lines) };
|
|
80
|
+
}
|
|
70
81
|
const { workers, builtinMcpServerFactories } = await (0, workers_1.collectWorkers)(startConfig);
|
|
71
82
|
const { adminUserId } = await (0, workers_1.startWorkers)(startConfig, workers, builtinMcpServerFactories);
|
|
83
|
+
// 5b. Machines, after the workers exist so their rows publish lifecycle events
|
|
84
|
+
const machines = startConfig.machines
|
|
85
|
+
? surface_1.MachineSurface.start({ ...startConfig.machines, callbacks: events_1.eventRegistry.getAdapter(callback_1.CallbackEventAdapter) })
|
|
86
|
+
: null;
|
|
72
87
|
// 6. Start embedded server (if enabled)
|
|
73
88
|
const serverEnabled = startConfig.server?.enabled !== false;
|
|
74
89
|
let httpServer = null;
|
|
@@ -85,6 +100,9 @@ async function start(startConfig) {
|
|
|
85
100
|
if (httpServer) {
|
|
86
101
|
await new Promise((resolve) => httpServer.close(() => resolve()));
|
|
87
102
|
}
|
|
103
|
+
if (machines) {
|
|
104
|
+
await machines.stop();
|
|
105
|
+
}
|
|
88
106
|
if (mcp_1.mcpRegistry.hasAdapter) {
|
|
89
107
|
await mcp_1.mcpRegistry.disconnect();
|
|
90
108
|
}
|
|
@@ -97,6 +115,7 @@ async function start(startConfig) {
|
|
|
97
115
|
if (events_1.eventRegistry.hasAdapters) {
|
|
98
116
|
await events_1.eventRegistry.disconnect();
|
|
99
117
|
}
|
|
118
|
+
await messaging_1.messagingRegistry.disconnect();
|
|
100
119
|
if (telemetry_1.telemetryRegistry.hasAdapter) {
|
|
101
120
|
await telemetry_1.telemetryRegistry.disconnect();
|
|
102
121
|
}
|