opencode-graphiti 0.1.11 → 0.1.12
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/esm/_dnt.polyfills.d.ts +99 -0
- package/esm/_dnt.polyfills.d.ts.map +1 -1
- package/esm/_dnt.polyfills.js +127 -1
- package/esm/_dnt.shims.d.ts +6 -0
- package/esm/_dnt.shims.d.ts.map +1 -0
- package/esm/_dnt.shims.js +61 -0
- package/esm/src/config.d.ts +14 -10
- package/esm/src/config.d.ts.map +1 -1
- package/esm/src/config.js +103 -43
- package/esm/src/index.d.ts.map +1 -1
- package/esm/src/index.js +12 -6
- package/esm/src/services/client.d.ts +15 -31
- package/esm/src/services/client.d.ts.map +1 -1
- package/esm/src/services/client.js +77 -139
- package/esm/src/services/connection-manager.d.ts +97 -0
- package/esm/src/services/connection-manager.d.ts.map +1 -0
- package/esm/src/services/connection-manager.js +535 -0
- package/esm/src/services/logger.d.ts +2 -0
- package/esm/src/services/logger.d.ts.map +1 -1
- package/esm/src/services/logger.js +29 -3
- package/esm/src/utils.d.ts.map +1 -1
- package/esm/src/utils.js +10 -2
- package/package.json +2 -2
- package/script/_dnt.polyfills.d.ts +99 -0
- package/script/_dnt.polyfills.d.ts.map +1 -1
- package/script/_dnt.polyfills.js +128 -0
- package/script/_dnt.shims.d.ts +6 -0
- package/script/_dnt.shims.d.ts.map +1 -0
- package/script/_dnt.shims.js +65 -0
- package/script/src/config.d.ts +14 -10
- package/script/src/config.d.ts.map +1 -1
- package/script/src/config.js +106 -76
- package/script/src/index.d.ts.map +1 -1
- package/script/src/index.js +12 -6
- package/script/src/services/client.d.ts +15 -31
- package/script/src/services/client.d.ts.map +1 -1
- package/script/src/services/client.js +77 -142
- package/script/src/services/connection-manager.d.ts +97 -0
- package/script/src/services/connection-manager.d.ts.map +1 -0
- package/script/src/services/connection-manager.js +549 -0
- package/script/src/services/logger.d.ts +2 -0
- package/script/src/services/logger.d.ts.map +1 -1
- package/script/src/services/logger.js +65 -7
- package/script/src/utils.d.ts.map +1 -1
- package/script/src/utils.js +10 -2
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GraphitiConnectionManager = exports.GraphitiSessionExpiredError = exports.GraphitiTransportError = exports.GraphitiRequestTimeoutError = exports.GraphitiQueueTimeoutError = exports.GraphitiOfflineError = void 0;
|
|
7
|
+
exports.isGraphitiOfflineError = isGraphitiOfflineError;
|
|
8
|
+
exports.isGraphitiTimeoutError = isGraphitiTimeoutError;
|
|
9
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
10
|
+
const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
11
|
+
const deno_js_1 = __importDefault(require("../../deno.js"));
|
|
12
|
+
const logger_js_1 = require("./logger.js");
|
|
13
|
+
class GraphitiOfflineError extends Error {
|
|
14
|
+
constructor(state, message) {
|
|
15
|
+
super(message ??
|
|
16
|
+
(state === "closing"
|
|
17
|
+
? "Graphiti connection manager is closing"
|
|
18
|
+
: "Graphiti connection manager is offline"));
|
|
19
|
+
Object.defineProperty(this, "state", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: state
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(this, "kind", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
configurable: true,
|
|
28
|
+
writable: true,
|
|
29
|
+
value: "offline"
|
|
30
|
+
});
|
|
31
|
+
this.name = "GraphitiOfflineError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.GraphitiOfflineError = GraphitiOfflineError;
|
|
35
|
+
class GraphitiQueueTimeoutError extends Error {
|
|
36
|
+
constructor(message = "Graphiti request timed out while waiting for connection") {
|
|
37
|
+
super(message);
|
|
38
|
+
Object.defineProperty(this, "kind", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: "queue-timeout"
|
|
43
|
+
});
|
|
44
|
+
this.name = "GraphitiQueueTimeoutError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.GraphitiQueueTimeoutError = GraphitiQueueTimeoutError;
|
|
48
|
+
class GraphitiRequestTimeoutError extends Error {
|
|
49
|
+
constructor(message = "Graphiti request timed out") {
|
|
50
|
+
super(message);
|
|
51
|
+
Object.defineProperty(this, "kind", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true,
|
|
55
|
+
value: "request-timeout"
|
|
56
|
+
});
|
|
57
|
+
this.name = "GraphitiRequestTimeoutError";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.GraphitiRequestTimeoutError = GraphitiRequestTimeoutError;
|
|
61
|
+
class GraphitiTransportError extends Error {
|
|
62
|
+
constructor(message = "Graphiti transport failure") {
|
|
63
|
+
super(message);
|
|
64
|
+
Object.defineProperty(this, "kind", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
configurable: true,
|
|
67
|
+
writable: true,
|
|
68
|
+
value: "transport-failure"
|
|
69
|
+
});
|
|
70
|
+
this.name = "GraphitiTransportError";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.GraphitiTransportError = GraphitiTransportError;
|
|
74
|
+
class GraphitiSessionExpiredError extends Error {
|
|
75
|
+
constructor(message = "Graphiti session expired") {
|
|
76
|
+
super(message);
|
|
77
|
+
Object.defineProperty(this, "kind", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
configurable: true,
|
|
80
|
+
writable: true,
|
|
81
|
+
value: "session-expired"
|
|
82
|
+
});
|
|
83
|
+
this.name = "GraphitiSessionExpiredError";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.GraphitiSessionExpiredError = GraphitiSessionExpiredError;
|
|
87
|
+
function isGraphitiOfflineError(err) {
|
|
88
|
+
return err instanceof GraphitiOfflineError;
|
|
89
|
+
}
|
|
90
|
+
function isGraphitiTimeoutError(err) {
|
|
91
|
+
return err instanceof GraphitiQueueTimeoutError ||
|
|
92
|
+
err instanceof GraphitiRequestTimeoutError;
|
|
93
|
+
}
|
|
94
|
+
function createMcpConnection(endpoint) {
|
|
95
|
+
const client = new index_js_1.Client({
|
|
96
|
+
name: deno_js_1.default.name,
|
|
97
|
+
version: deno_js_1.default.version,
|
|
98
|
+
});
|
|
99
|
+
const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(endpoint));
|
|
100
|
+
return {
|
|
101
|
+
connect: () => client.connect(transport),
|
|
102
|
+
close: () => client.close(),
|
|
103
|
+
callTool: (request) => client.callTool(request),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function getErrorMessage(err) {
|
|
107
|
+
if (typeof err === "string")
|
|
108
|
+
return err;
|
|
109
|
+
if (!err || typeof err !== "object")
|
|
110
|
+
return "";
|
|
111
|
+
const { message, cause } = err;
|
|
112
|
+
if (typeof message === "string")
|
|
113
|
+
return message;
|
|
114
|
+
if (cause)
|
|
115
|
+
return getErrorMessage(cause);
|
|
116
|
+
return "";
|
|
117
|
+
}
|
|
118
|
+
function isRequestTimeout(err) {
|
|
119
|
+
if (!err || typeof err !== "object") {
|
|
120
|
+
return typeof err === "string" && /request timed out/i.test(err);
|
|
121
|
+
}
|
|
122
|
+
const { code } = err;
|
|
123
|
+
return code === -32001 || /request timed out/i.test(getErrorMessage(err));
|
|
124
|
+
}
|
|
125
|
+
function isSessionExpired(err) {
|
|
126
|
+
return !!(err &&
|
|
127
|
+
typeof err === "object" &&
|
|
128
|
+
"code" in err &&
|
|
129
|
+
err.code === 404);
|
|
130
|
+
}
|
|
131
|
+
function isTransportFailure(err) {
|
|
132
|
+
if (!err)
|
|
133
|
+
return false;
|
|
134
|
+
if (isRequestTimeout(err) || isSessionExpired(err))
|
|
135
|
+
return false;
|
|
136
|
+
const message = getErrorMessage(err);
|
|
137
|
+
if (/(socket hang up|fetch failed|network|connection reset|connection refused|econnrefused|terminated|broken pipe|stream closed|unexpected end|transport)/i
|
|
138
|
+
.test(message)) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
if (typeof err === "object") {
|
|
142
|
+
const { name } = err;
|
|
143
|
+
return name === "TypeError" && message.length > 0;
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
class GraphitiConnectionManager {
|
|
148
|
+
constructor(options) {
|
|
149
|
+
Object.defineProperty(this, "endpoint", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
configurable: true,
|
|
152
|
+
writable: true,
|
|
153
|
+
value: void 0
|
|
154
|
+
});
|
|
155
|
+
Object.defineProperty(this, "requestDeadlineMs", {
|
|
156
|
+
enumerable: true,
|
|
157
|
+
configurable: true,
|
|
158
|
+
writable: true,
|
|
159
|
+
value: void 0
|
|
160
|
+
});
|
|
161
|
+
Object.defineProperty(this, "queueCapacity", {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
configurable: true,
|
|
164
|
+
writable: true,
|
|
165
|
+
value: void 0
|
|
166
|
+
});
|
|
167
|
+
Object.defineProperty(this, "startupTimeoutMs", {
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
writable: true,
|
|
171
|
+
value: void 0
|
|
172
|
+
});
|
|
173
|
+
Object.defineProperty(this, "reconnectInitialDelayMs", {
|
|
174
|
+
enumerable: true,
|
|
175
|
+
configurable: true,
|
|
176
|
+
writable: true,
|
|
177
|
+
value: void 0
|
|
178
|
+
});
|
|
179
|
+
Object.defineProperty(this, "reconnectMaxDelayMs", {
|
|
180
|
+
enumerable: true,
|
|
181
|
+
configurable: true,
|
|
182
|
+
writable: true,
|
|
183
|
+
value: void 0
|
|
184
|
+
});
|
|
185
|
+
Object.defineProperty(this, "reconnectMultiplier", {
|
|
186
|
+
enumerable: true,
|
|
187
|
+
configurable: true,
|
|
188
|
+
writable: true,
|
|
189
|
+
value: void 0
|
|
190
|
+
});
|
|
191
|
+
Object.defineProperty(this, "reconnectJitter", {
|
|
192
|
+
enumerable: true,
|
|
193
|
+
configurable: true,
|
|
194
|
+
writable: true,
|
|
195
|
+
value: void 0
|
|
196
|
+
});
|
|
197
|
+
Object.defineProperty(this, "connectionFactory", {
|
|
198
|
+
enumerable: true,
|
|
199
|
+
configurable: true,
|
|
200
|
+
writable: true,
|
|
201
|
+
value: void 0
|
|
202
|
+
});
|
|
203
|
+
Object.defineProperty(this, "random", {
|
|
204
|
+
enumerable: true,
|
|
205
|
+
configurable: true,
|
|
206
|
+
writable: true,
|
|
207
|
+
value: void 0
|
|
208
|
+
});
|
|
209
|
+
Object.defineProperty(this, "setTimerImpl", {
|
|
210
|
+
enumerable: true,
|
|
211
|
+
configurable: true,
|
|
212
|
+
writable: true,
|
|
213
|
+
value: void 0
|
|
214
|
+
});
|
|
215
|
+
Object.defineProperty(this, "clearTimerImpl", {
|
|
216
|
+
enumerable: true,
|
|
217
|
+
configurable: true,
|
|
218
|
+
writable: true,
|
|
219
|
+
value: void 0
|
|
220
|
+
});
|
|
221
|
+
Object.defineProperty(this, "state", {
|
|
222
|
+
enumerable: true,
|
|
223
|
+
configurable: true,
|
|
224
|
+
writable: true,
|
|
225
|
+
value: "offline"
|
|
226
|
+
});
|
|
227
|
+
Object.defineProperty(this, "connection", {
|
|
228
|
+
enumerable: true,
|
|
229
|
+
configurable: true,
|
|
230
|
+
writable: true,
|
|
231
|
+
value: null
|
|
232
|
+
});
|
|
233
|
+
Object.defineProperty(this, "connectPromise", {
|
|
234
|
+
enumerable: true,
|
|
235
|
+
configurable: true,
|
|
236
|
+
writable: true,
|
|
237
|
+
value: null
|
|
238
|
+
});
|
|
239
|
+
Object.defineProperty(this, "reconnectTimer", {
|
|
240
|
+
enumerable: true,
|
|
241
|
+
configurable: true,
|
|
242
|
+
writable: true,
|
|
243
|
+
value: null
|
|
244
|
+
});
|
|
245
|
+
Object.defineProperty(this, "pendingRequests", {
|
|
246
|
+
enumerable: true,
|
|
247
|
+
configurable: true,
|
|
248
|
+
writable: true,
|
|
249
|
+
value: []
|
|
250
|
+
});
|
|
251
|
+
Object.defineProperty(this, "readyWaiters", {
|
|
252
|
+
enumerable: true,
|
|
253
|
+
configurable: true,
|
|
254
|
+
writable: true,
|
|
255
|
+
value: new Set()
|
|
256
|
+
});
|
|
257
|
+
Object.defineProperty(this, "reconnectDelayMs", {
|
|
258
|
+
enumerable: true,
|
|
259
|
+
configurable: true,
|
|
260
|
+
writable: true,
|
|
261
|
+
value: void 0
|
|
262
|
+
});
|
|
263
|
+
Object.defineProperty(this, "started", {
|
|
264
|
+
enumerable: true,
|
|
265
|
+
configurable: true,
|
|
266
|
+
writable: true,
|
|
267
|
+
value: false
|
|
268
|
+
});
|
|
269
|
+
Object.defineProperty(this, "flushingQueue", {
|
|
270
|
+
enumerable: true,
|
|
271
|
+
configurable: true,
|
|
272
|
+
writable: true,
|
|
273
|
+
value: false
|
|
274
|
+
});
|
|
275
|
+
this.endpoint = options.endpoint;
|
|
276
|
+
this.requestDeadlineMs = options.requestDeadlineMs ?? 15_000;
|
|
277
|
+
this.queueCapacity = options.queueCapacity ?? 32;
|
|
278
|
+
this.startupTimeoutMs = options.startupTimeoutMs ?? this.requestDeadlineMs;
|
|
279
|
+
this.reconnectInitialDelayMs = options.reconnectInitialDelayMs ?? 1_000;
|
|
280
|
+
this.reconnectMaxDelayMs = options.reconnectMaxDelayMs ?? 60_000;
|
|
281
|
+
this.reconnectMultiplier = options.reconnectMultiplier ?? 2;
|
|
282
|
+
this.reconnectJitter = options.reconnectJitter ?? 0.25;
|
|
283
|
+
this.connectionFactory = options.connectionFactory ?? createMcpConnection;
|
|
284
|
+
this.random = options.random ?? Math.random;
|
|
285
|
+
this.setTimerImpl = options.setTimer ??
|
|
286
|
+
((callback, delayMs) => setTimeout(callback, delayMs));
|
|
287
|
+
this.clearTimerImpl = options.clearTimer ??
|
|
288
|
+
((timer) => clearTimeout(timer));
|
|
289
|
+
this.reconnectDelayMs = this.reconnectInitialDelayMs;
|
|
290
|
+
}
|
|
291
|
+
getState() {
|
|
292
|
+
return this.state;
|
|
293
|
+
}
|
|
294
|
+
start() {
|
|
295
|
+
if (this.started || this.state === "closing")
|
|
296
|
+
return;
|
|
297
|
+
this.started = true;
|
|
298
|
+
void this.reconnect();
|
|
299
|
+
}
|
|
300
|
+
async stop() {
|
|
301
|
+
if (this.state === "closing")
|
|
302
|
+
return;
|
|
303
|
+
this.started = false;
|
|
304
|
+
this.state = "closing";
|
|
305
|
+
this.cancelReconnectTimer();
|
|
306
|
+
this.rejectAllPending(new GraphitiOfflineError("closing", "Graphiti connection manager stopped"));
|
|
307
|
+
this.resolveReadyWaiters(false);
|
|
308
|
+
const connection = this.connection;
|
|
309
|
+
this.connection = null;
|
|
310
|
+
if (connection) {
|
|
311
|
+
try {
|
|
312
|
+
await connection.close();
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
// Ignore close errors while shutting down.
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
async ready(timeoutMs = this.startupTimeoutMs) {
|
|
320
|
+
if (this.state === "connected")
|
|
321
|
+
return true;
|
|
322
|
+
if (this.state === "closing")
|
|
323
|
+
return false;
|
|
324
|
+
return await new Promise((resolve) => {
|
|
325
|
+
let settled = false;
|
|
326
|
+
let timer = null;
|
|
327
|
+
const finish = (value) => {
|
|
328
|
+
if (settled)
|
|
329
|
+
return;
|
|
330
|
+
settled = true;
|
|
331
|
+
if (timer !== null)
|
|
332
|
+
this.clearTimerImpl(timer);
|
|
333
|
+
this.readyWaiters.delete(finish);
|
|
334
|
+
resolve(value);
|
|
335
|
+
};
|
|
336
|
+
this.readyWaiters.add(finish);
|
|
337
|
+
if (timeoutMs >= 0) {
|
|
338
|
+
timer = this.setTimerImpl(() => finish(false), timeoutMs);
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
async callTool(name, args, deadlineMs = this.requestDeadlineMs) {
|
|
343
|
+
const sanitizedArgs = Object.fromEntries(Object.entries(args).filter(([_, value]) => value !== null && value !== undefined));
|
|
344
|
+
if (this.state === "closing") {
|
|
345
|
+
throw new GraphitiOfflineError("closing");
|
|
346
|
+
}
|
|
347
|
+
if (this.state === "offline") {
|
|
348
|
+
throw new GraphitiOfflineError("offline");
|
|
349
|
+
}
|
|
350
|
+
if (this.state === "connecting") {
|
|
351
|
+
return await this.enqueueRequest(name, sanitizedArgs, deadlineMs);
|
|
352
|
+
}
|
|
353
|
+
return await this.executeConnectedCall(name, sanitizedArgs);
|
|
354
|
+
}
|
|
355
|
+
async reconnect() {
|
|
356
|
+
if (this.state === "closing")
|
|
357
|
+
return false;
|
|
358
|
+
if (this.connectPromise)
|
|
359
|
+
return await this.connectPromise;
|
|
360
|
+
this.cancelReconnectTimer();
|
|
361
|
+
this.state = "connecting";
|
|
362
|
+
const attempt = this.performReconnect();
|
|
363
|
+
this.connectPromise = attempt.finally(() => {
|
|
364
|
+
this.connectPromise = null;
|
|
365
|
+
});
|
|
366
|
+
return await this.connectPromise;
|
|
367
|
+
}
|
|
368
|
+
async performReconnect() {
|
|
369
|
+
const previousConnection = this.connection;
|
|
370
|
+
this.connection = null;
|
|
371
|
+
if (previousConnection) {
|
|
372
|
+
try {
|
|
373
|
+
await previousConnection.close();
|
|
374
|
+
}
|
|
375
|
+
catch {
|
|
376
|
+
// Ignore stale close failures during reconnect.
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
const nextConnection = this.connectionFactory(this.endpoint);
|
|
380
|
+
try {
|
|
381
|
+
await nextConnection.connect();
|
|
382
|
+
if (this.state === "closing") {
|
|
383
|
+
try {
|
|
384
|
+
await nextConnection.close();
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
// Ignore close failures while shutting down.
|
|
388
|
+
}
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
this.connection = nextConnection;
|
|
392
|
+
this.state = "connected";
|
|
393
|
+
this.reconnectDelayMs = this.reconnectInitialDelayMs;
|
|
394
|
+
this.resolveReadyWaiters(true);
|
|
395
|
+
logger_js_1.logger.info("Connected to Graphiti MCP server at", this.endpoint);
|
|
396
|
+
void this.flushPendingQueue();
|
|
397
|
+
return true;
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
try {
|
|
401
|
+
await nextConnection.close();
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
// Ignore close failures for failed connects.
|
|
405
|
+
}
|
|
406
|
+
if (this.state !== "closing") {
|
|
407
|
+
this.state = "offline";
|
|
408
|
+
this.rejectAllPending(new GraphitiOfflineError("offline"));
|
|
409
|
+
this.scheduleReconnect();
|
|
410
|
+
logger_js_1.logger.warn("Failed to connect to Graphiti MCP server", err);
|
|
411
|
+
}
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
async executeConnectedCall(name, args, attempt = 0) {
|
|
416
|
+
if (this.state !== "connected" || !this.connection) {
|
|
417
|
+
throw new GraphitiOfflineError("offline");
|
|
418
|
+
}
|
|
419
|
+
try {
|
|
420
|
+
return await this.connection.callTool({ name, arguments: args });
|
|
421
|
+
}
|
|
422
|
+
catch (err) {
|
|
423
|
+
if (isRequestTimeout(err)) {
|
|
424
|
+
throw new GraphitiRequestTimeoutError(getErrorMessage(err) || undefined);
|
|
425
|
+
}
|
|
426
|
+
if (isSessionExpired(err)) {
|
|
427
|
+
const typedError = new GraphitiSessionExpiredError(getErrorMessage(err) || undefined);
|
|
428
|
+
if (attempt >= 1) {
|
|
429
|
+
void this.reconnect();
|
|
430
|
+
throw typedError;
|
|
431
|
+
}
|
|
432
|
+
const connected = await this.reconnect();
|
|
433
|
+
if (!connected)
|
|
434
|
+
throw typedError;
|
|
435
|
+
return await this.executeConnectedCall(name, args, attempt + 1);
|
|
436
|
+
}
|
|
437
|
+
if (isTransportFailure(err)) {
|
|
438
|
+
const typedError = new GraphitiTransportError(getErrorMessage(err) || undefined);
|
|
439
|
+
if (attempt >= 1) {
|
|
440
|
+
void this.reconnect();
|
|
441
|
+
throw typedError;
|
|
442
|
+
}
|
|
443
|
+
const connected = await this.reconnect();
|
|
444
|
+
if (!connected)
|
|
445
|
+
throw typedError;
|
|
446
|
+
return await this.executeConnectedCall(name, args, attempt + 1);
|
|
447
|
+
}
|
|
448
|
+
throw err;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
enqueueRequest(name, args, deadlineMs) {
|
|
452
|
+
if (deadlineMs <= 0) {
|
|
453
|
+
return Promise.reject(new GraphitiQueueTimeoutError());
|
|
454
|
+
}
|
|
455
|
+
return new Promise((resolve, reject) => {
|
|
456
|
+
const pending = {
|
|
457
|
+
name,
|
|
458
|
+
args,
|
|
459
|
+
resolve,
|
|
460
|
+
reject,
|
|
461
|
+
timer: null,
|
|
462
|
+
};
|
|
463
|
+
pending.timer = this.setTimerImpl(() => {
|
|
464
|
+
this.removePendingRequest(pending);
|
|
465
|
+
reject(new GraphitiQueueTimeoutError());
|
|
466
|
+
}, deadlineMs);
|
|
467
|
+
if (this.pendingRequests.length >= this.queueCapacity) {
|
|
468
|
+
const dropped = this.pendingRequests.shift();
|
|
469
|
+
if (dropped) {
|
|
470
|
+
this.clearPendingTimer(dropped);
|
|
471
|
+
dropped.reject(new GraphitiQueueTimeoutError("Graphiti request dropped because the connecting queue is full"));
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
this.pendingRequests.push(pending);
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
async flushPendingQueue() {
|
|
478
|
+
if (this.flushingQueue || this.state !== "connected")
|
|
479
|
+
return;
|
|
480
|
+
this.flushingQueue = true;
|
|
481
|
+
try {
|
|
482
|
+
while (this.state === "connected" && this.pendingRequests.length > 0) {
|
|
483
|
+
const next = this.pendingRequests.shift();
|
|
484
|
+
if (!next)
|
|
485
|
+
continue;
|
|
486
|
+
this.clearPendingTimer(next);
|
|
487
|
+
try {
|
|
488
|
+
const result = await this.executeConnectedCall(next.name, next.args);
|
|
489
|
+
next.resolve(result);
|
|
490
|
+
}
|
|
491
|
+
catch (err) {
|
|
492
|
+
next.reject(err);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
finally {
|
|
497
|
+
this.flushingQueue = false;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
removePendingRequest(target) {
|
|
501
|
+
const index = this.pendingRequests.indexOf(target);
|
|
502
|
+
if (index >= 0) {
|
|
503
|
+
this.pendingRequests.splice(index, 1);
|
|
504
|
+
}
|
|
505
|
+
this.clearPendingTimer(target);
|
|
506
|
+
}
|
|
507
|
+
clearPendingTimer(request) {
|
|
508
|
+
if (request.timer !== null) {
|
|
509
|
+
this.clearTimerImpl(request.timer);
|
|
510
|
+
request.timer = null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
rejectAllPending(error) {
|
|
514
|
+
const pending = [...this.pendingRequests];
|
|
515
|
+
this.pendingRequests = [];
|
|
516
|
+
for (const request of pending) {
|
|
517
|
+
this.clearPendingTimer(request);
|
|
518
|
+
request.reject(error);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
scheduleReconnect() {
|
|
522
|
+
if (!this.started || this.state === "closing" || this.reconnectTimer !== null) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const jitterFactor = 1 + ((this.random() * 2) - 1) * this.reconnectJitter;
|
|
526
|
+
const delayMs = Math.max(0, Math.round(this.reconnectDelayMs * jitterFactor));
|
|
527
|
+
this.reconnectTimer = this.setTimerImpl(() => {
|
|
528
|
+
this.reconnectTimer = null;
|
|
529
|
+
if (this.state === "closing")
|
|
530
|
+
return;
|
|
531
|
+
void this.reconnect();
|
|
532
|
+
}, delayMs);
|
|
533
|
+
this.reconnectDelayMs = Math.min(this.reconnectMaxDelayMs, Math.max(this.reconnectInitialDelayMs, Math.round(this.reconnectDelayMs * this.reconnectMultiplier)));
|
|
534
|
+
}
|
|
535
|
+
cancelReconnectTimer() {
|
|
536
|
+
if (this.reconnectTimer !== null) {
|
|
537
|
+
this.clearTimerImpl(this.reconnectTimer);
|
|
538
|
+
this.reconnectTimer = null;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
resolveReadyWaiters(value) {
|
|
542
|
+
const waiters = [...this.readyWaiters];
|
|
543
|
+
this.readyWaiters.clear();
|
|
544
|
+
for (const waiter of waiters) {
|
|
545
|
+
waiter(value);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
exports.GraphitiConnectionManager = GraphitiConnectionManager;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/src/services/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/src/services/logger.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,GAAG,SAAS,KAAG,IAEnE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,OAAO,OAAO,KAAG,IAExD,CAAC;AAEF,eAAO,MAAM,MAAM;oBACD,OAAO,EAAE;oBAIT,OAAO,EAAE;qBAIR,OAAO,EAAE;qBAIT,OAAO,EAAE;CAI3B,CAAC"}
|
|
@@ -1,25 +1,83 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
5
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.logger = void 0;
|
|
7
|
-
const
|
|
36
|
+
exports.logger = exports.setLoggerSilentOverride = exports.setLoggerDebugOverride = void 0;
|
|
37
|
+
const dntShim = __importStar(require("../../_dnt.shims.js"));
|
|
8
38
|
const console = globalThis.console;
|
|
9
39
|
const PREFIX = "[graphiti]";
|
|
40
|
+
let debugOverride;
|
|
41
|
+
let silentOverride = false;
|
|
42
|
+
const isDebugEnabled = () => {
|
|
43
|
+
if (debugOverride !== undefined)
|
|
44
|
+
return debugOverride;
|
|
45
|
+
try {
|
|
46
|
+
return !!dntShim.Deno.env.get("GRAPHITI_DEBUG");
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const setLoggerDebugOverride = (value) => {
|
|
53
|
+
debugOverride = value;
|
|
54
|
+
};
|
|
55
|
+
exports.setLoggerDebugOverride = setLoggerDebugOverride;
|
|
56
|
+
const setLoggerSilentOverride = (value) => {
|
|
57
|
+
silentOverride = value;
|
|
58
|
+
};
|
|
59
|
+
exports.setLoggerSilentOverride = setLoggerSilentOverride;
|
|
10
60
|
exports.logger = {
|
|
11
61
|
info: (...args) => {
|
|
12
|
-
if (
|
|
62
|
+
if (silentOverride)
|
|
63
|
+
return;
|
|
64
|
+
if (isDebugEnabled())
|
|
13
65
|
console.log(PREFIX, ...args);
|
|
14
66
|
},
|
|
15
67
|
warn: (...args) => {
|
|
68
|
+
if (silentOverride)
|
|
69
|
+
return;
|
|
16
70
|
console.warn(PREFIX, ...args);
|
|
17
71
|
},
|
|
18
72
|
error: (...args) => {
|
|
73
|
+
if (silentOverride)
|
|
74
|
+
return;
|
|
19
75
|
console.error(PREFIX, ...args);
|
|
20
76
|
},
|
|
21
77
|
debug: (...args) => {
|
|
22
|
-
if (
|
|
78
|
+
if (silentOverride)
|
|
79
|
+
return;
|
|
80
|
+
if (isDebugEnabled())
|
|
23
81
|
console.debug(PREFIX, ...args);
|
|
24
82
|
},
|
|
25
83
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAkB7C;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,SAAS,MAAM,EACf,kBAAyB,KACxB,MAKF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,SAAS,MAAM,EACf,kBAAyB,KACxB,MAMF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,IAAI,GAAG;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAMd,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAI,OAAO,IAAI,EAAE,KAAG,MACe,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,QAAQ,MAAM,KACb,MAKF,CAAC"}
|
package/script/src/utils.js
CHANGED
|
@@ -7,7 +7,15 @@ exports.truncateAtLineBoundary = exports.extractTextFromParts = exports.isTextPa
|
|
|
7
7
|
const node_os_1 = __importDefault(require("node:os"));
|
|
8
8
|
const node_process_1 = __importDefault(require("node:process"));
|
|
9
9
|
const getProjectName = (directory) => directory.split("/").filter(Boolean).at(-1)?.trim() || "default";
|
|
10
|
-
const
|
|
10
|
+
const getHomeDirectory = () => {
|
|
11
|
+
try {
|
|
12
|
+
return node_os_1.default.homedir();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const getUserName = () => getHomeDirectory()?.split("/").filter(Boolean).at(-1)?.trim() || undefined;
|
|
11
19
|
/**
|
|
12
20
|
* Build a sanitized Graphiti group ID from a prefix and project directory.
|
|
13
21
|
*/
|
|
@@ -23,7 +31,7 @@ exports.makeGroupId = makeGroupId;
|
|
|
23
31
|
*/
|
|
24
32
|
const makeUserGroupId = (prefix, directory = node_process_1.default.cwd()) => {
|
|
25
33
|
const projectName = getProjectName(directory);
|
|
26
|
-
const userName = getUserName();
|
|
34
|
+
const userName = getUserName() ?? "unknown";
|
|
27
35
|
const prefixPart = prefix ? `${prefix}-` : "";
|
|
28
36
|
const rawGroupId = `${prefixPart}${projectName}__user-${userName}`;
|
|
29
37
|
return rawGroupId.replace(/[^A-Za-z0-9_-]/g, "_");
|