lightnode-sdk 0.8.9 → 0.8.10
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/dist/inference.js +32 -17
- package/package.json +1 -1
package/dist/inference.js
CHANGED
|
@@ -293,6 +293,8 @@ async function runOneAttempt(args, attempt) {
|
|
|
293
293
|
setTimeout(() => reject(new Error("relay WebSocket open timeout")), 20000);
|
|
294
294
|
});
|
|
295
295
|
const chunks = [];
|
|
296
|
+
let streamDone = false;
|
|
297
|
+
let streamDoneAt = null;
|
|
296
298
|
const handleMessage = async (rawData) => {
|
|
297
299
|
const raw = typeof rawData === "string"
|
|
298
300
|
? rawData
|
|
@@ -308,20 +310,26 @@ async function runOneAttempt(args, attempt) {
|
|
|
308
310
|
catch {
|
|
309
311
|
return;
|
|
310
312
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
313
|
+
// "complete" marks end-of-stream (it may or may not carry a payload).
|
|
314
|
+
// Record it so the JobCompleted wait can stop promptly instead of polling
|
|
315
|
+
// the full grace window after the answer is already in hand.
|
|
316
|
+
if (frame.type === "complete") {
|
|
317
|
+
streamDone = true;
|
|
318
|
+
streamDoneAt = Date.now();
|
|
319
|
+
if (chunks.length === 0 && frame.payload) {
|
|
320
|
+
try {
|
|
321
|
+
const piece = await decryptResponse(prepared.sessionKey, frame.payload);
|
|
322
|
+
chunks.push(piece);
|
|
323
|
+
if (onChunk)
|
|
324
|
+
onChunk(piece, chunks.join(""));
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
/* ignore */
|
|
328
|
+
}
|
|
322
329
|
}
|
|
330
|
+
return;
|
|
323
331
|
}
|
|
324
|
-
|
|
332
|
+
if (frame.type === "chunk" && frame.payload) {
|
|
325
333
|
try {
|
|
326
334
|
const piece = await decryptResponse(prepared.sessionKey, frame.payload);
|
|
327
335
|
chunks.push(piece);
|
|
@@ -329,7 +337,7 @@ async function runOneAttempt(args, attempt) {
|
|
|
329
337
|
onChunk(piece, chunks.join(""));
|
|
330
338
|
}
|
|
331
339
|
catch {
|
|
332
|
-
/*
|
|
340
|
+
/* control frame */
|
|
333
341
|
}
|
|
334
342
|
}
|
|
335
343
|
};
|
|
@@ -376,7 +384,8 @@ async function runOneAttempt(args, attempt) {
|
|
|
376
384
|
// answer with txs.jobCompleted=null (the answer is still session-key
|
|
377
385
|
// authentic; the on-chain proof can be polled for separately by callers).
|
|
378
386
|
const deadline = Date.now() + jobCompletedTimeoutMs;
|
|
379
|
-
const POST_CHUNKS_GRACE_MS = 45000;
|
|
387
|
+
const POST_CHUNKS_GRACE_MS = 45000; // fallback if the relay never sends a 'complete' frame
|
|
388
|
+
const POST_DONE_GRACE_MS = 8000; // once the answer is fully in, the worker commits JobCompleted within ~seconds
|
|
380
389
|
const waitStart = Date.now();
|
|
381
390
|
let firstChunkAt = chunks.length > 0 ? waitStart : null;
|
|
382
391
|
const jobIdTopic = (`0x${jobId.toString(16).padStart(64, "0")}`);
|
|
@@ -385,9 +394,14 @@ async function runOneAttempt(args, attempt) {
|
|
|
385
394
|
const now = Date.now();
|
|
386
395
|
if (now >= deadline)
|
|
387
396
|
break;
|
|
397
|
+
// Answer fully received (relay sent 'complete'): wait only briefly for the
|
|
398
|
+
// on-chain proof, then return. The answer is already session-key authentic;
|
|
399
|
+
// callers get txs.jobCompleted=null and can poll the proof later if needed.
|
|
400
|
+
if (streamDone && now - (streamDoneAt ?? now) >= POST_DONE_GRACE_MS)
|
|
401
|
+
break;
|
|
388
402
|
if (firstChunkAt != null && now - firstChunkAt >= POST_CHUNKS_GRACE_MS)
|
|
389
403
|
break;
|
|
390
|
-
await new Promise((res) => setTimeout(res,
|
|
404
|
+
await new Promise((res) => setTimeout(res, 1500));
|
|
391
405
|
if (firstChunkAt == null && chunks.length > 0)
|
|
392
406
|
firstChunkAt = Date.now();
|
|
393
407
|
const logs = await publicClient.getLogs({
|
|
@@ -414,8 +428,9 @@ async function runOneAttempt(args, attempt) {
|
|
|
414
428
|
feeLcai: fee,
|
|
415
429
|
});
|
|
416
430
|
}
|
|
417
|
-
// 7. grace period for the last relay frame, then close
|
|
418
|
-
|
|
431
|
+
// 7. grace period for the last relay frame, then close. If the stream already
|
|
432
|
+
// signaled 'complete', no more frames are coming - skip the wait.
|
|
433
|
+
await new Promise((res) => setTimeout(res, streamDone ? 300 : 4000));
|
|
419
434
|
try {
|
|
420
435
|
ws.close();
|
|
421
436
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightnode-sdk",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.10",
|
|
4
4
|
"description": "Read-only TypeScript client for LightChain AI: workers, jobs, models, on-chain registration, and per-model network analytics. Independent, community-built (not an official LightChain package).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|