koishi-plugin-aka-ai-generator 0.7.7 → 0.7.8
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/lib/index.js +181 -82
- package/lib/services/UserManager.d.ts +20 -0
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -1185,7 +1185,9 @@ var UserManager = class {
|
|
|
1185
1185
|
usersCache = null;
|
|
1186
1186
|
pendingVideoCache = null;
|
|
1187
1187
|
activeTasks = /* @__PURE__ */ new Map();
|
|
1188
|
-
// userId -> requestId
|
|
1188
|
+
// userId -> requestId (图像任务锁)
|
|
1189
|
+
activeVideoTasks = /* @__PURE__ */ new Map();
|
|
1190
|
+
// userId -> requestId (视频任务锁,独立于图像任务)
|
|
1189
1191
|
rateLimitMap = /* @__PURE__ */ new Map();
|
|
1190
1192
|
// userId -> timestamps
|
|
1191
1193
|
securityBlockMap = /* @__PURE__ */ new Map();
|
|
@@ -1204,6 +1206,7 @@ var UserManager = class {
|
|
|
1204
1206
|
}
|
|
1205
1207
|
}
|
|
1206
1208
|
// --- 任务管理 ---
|
|
1209
|
+
// 图像任务锁(原有逻辑保持不变)
|
|
1207
1210
|
startTask(userId) {
|
|
1208
1211
|
if (this.activeTasks.has(userId)) return false;
|
|
1209
1212
|
this.activeTasks.set(userId, "processing");
|
|
@@ -1215,6 +1218,18 @@ var UserManager = class {
|
|
|
1215
1218
|
isTaskActive(userId) {
|
|
1216
1219
|
return this.activeTasks.has(userId);
|
|
1217
1220
|
}
|
|
1221
|
+
// 视频任务锁(独立于图像任务,不影响图像生成)
|
|
1222
|
+
startVideoTask(userId) {
|
|
1223
|
+
if (this.activeVideoTasks.has(userId)) return false;
|
|
1224
|
+
this.activeVideoTasks.set(userId, "processing");
|
|
1225
|
+
return true;
|
|
1226
|
+
}
|
|
1227
|
+
endVideoTask(userId) {
|
|
1228
|
+
this.activeVideoTasks.delete(userId);
|
|
1229
|
+
}
|
|
1230
|
+
isVideoTaskActive(userId) {
|
|
1231
|
+
return this.activeVideoTasks.has(userId);
|
|
1232
|
+
}
|
|
1218
1233
|
// --- 权限管理 ---
|
|
1219
1234
|
isAdmin(userId, config) {
|
|
1220
1235
|
return config.adminUsers && config.adminUsers.includes(userId);
|
|
@@ -1349,6 +1364,49 @@ var UserManager = class {
|
|
|
1349
1364
|
});
|
|
1350
1365
|
return tasks[0] || null;
|
|
1351
1366
|
}
|
|
1367
|
+
/**
|
|
1368
|
+
* 统计某个用户未扣费的待结算视频任务数量
|
|
1369
|
+
*/
|
|
1370
|
+
async countPendingVideoTasksForUser(userId) {
|
|
1371
|
+
const data = await this.loadPendingVideoTasks();
|
|
1372
|
+
return Object.values(data.tasks).filter((t) => t.userId === userId && !t.charged).length;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* 列出某个用户所有未扣费的待结算视频任务
|
|
1376
|
+
*/
|
|
1377
|
+
async listPendingVideoTasksForUser(userId) {
|
|
1378
|
+
const data = await this.loadPendingVideoTasks();
|
|
1379
|
+
return Object.values(data.tasks).filter((t) => t.userId === userId && !t.charged).sort((a, b) => {
|
|
1380
|
+
const ta = Date.parse(a.createdAt || "") || 0;
|
|
1381
|
+
const tb = Date.parse(b.createdAt || "") || 0;
|
|
1382
|
+
return tb - ta;
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
/**
|
|
1386
|
+
* 添加待结算视频任务,并检查上限(默认max=1)
|
|
1387
|
+
* @returns {Promise<{success: boolean, message?: string}>} 成功返回 {success: true},失败返回 {success: false, message: '错误信息'}
|
|
1388
|
+
*/
|
|
1389
|
+
async addPendingVideoTaskWithLimit(task, max = 1) {
|
|
1390
|
+
await this.loadPendingVideoTasks();
|
|
1391
|
+
return await this.pendingLock.acquire(async () => {
|
|
1392
|
+
if (!this.pendingVideoCache) {
|
|
1393
|
+
this.pendingVideoCache = { version: "1.0.0", lastUpdate: (/* @__PURE__ */ new Date()).toISOString(), tasks: {} };
|
|
1394
|
+
}
|
|
1395
|
+
const currentCount = Object.values(this.pendingVideoCache.tasks).filter((t) => t.userId === task.userId && !t.charged).length;
|
|
1396
|
+
if (currentCount >= max) {
|
|
1397
|
+
return {
|
|
1398
|
+
success: false,
|
|
1399
|
+
message: `您当前已有 ${currentCount} 个视频正在生成中(最多允许 ${max} 个),请先使用"查询视频"查看进度或等待完成`
|
|
1400
|
+
};
|
|
1401
|
+
}
|
|
1402
|
+
if (this.pendingVideoCache.tasks[task.taskId]) {
|
|
1403
|
+
return { success: true };
|
|
1404
|
+
}
|
|
1405
|
+
this.pendingVideoCache.tasks[task.taskId] = task;
|
|
1406
|
+
await this.savePendingVideoTasksInternal();
|
|
1407
|
+
return { success: true };
|
|
1408
|
+
});
|
|
1409
|
+
}
|
|
1352
1410
|
// 获取特定用户数据
|
|
1353
1411
|
async getUserData(userId, userName) {
|
|
1354
1412
|
await this.loadUsersData();
|
|
@@ -2339,8 +2397,8 @@ ${infoParts.join("\n")}`;
|
|
|
2339
2397
|
if (!limitCheck.allowed) {
|
|
2340
2398
|
return limitCheck.message;
|
|
2341
2399
|
}
|
|
2342
|
-
if (!userManager.
|
|
2343
|
-
return "
|
|
2400
|
+
if (!userManager.startVideoTask(userId)) {
|
|
2401
|
+
return "您有一个视频任务正在进行中,请等待完成";
|
|
2344
2402
|
}
|
|
2345
2403
|
let createdTaskId = null;
|
|
2346
2404
|
try {
|
|
@@ -2375,15 +2433,6 @@ ${infoParts.join("\n")}`;
|
|
|
2375
2433
|
if (!validRatios.includes(ratio)) {
|
|
2376
2434
|
return `宽高比必须是以下之一: ${validRatios.join(", ")}`;
|
|
2377
2435
|
}
|
|
2378
|
-
await session.send(
|
|
2379
|
-
`🎬 开始生成视频...
|
|
2380
|
-
📝 描述:${prompt}
|
|
2381
|
-
⏱️ 时长:${duration}秒
|
|
2382
|
-
📐 宽高比:${ratio}
|
|
2383
|
-
⚠️ 预计需要 1-3 分钟,请耐心等待
|
|
2384
|
-
💡 提示:生成过程中可继续使用其他功能`
|
|
2385
|
-
);
|
|
2386
|
-
const startTime = Date.now();
|
|
2387
2436
|
const taskId = await videoProvider.createVideoTask(
|
|
2388
2437
|
prompt,
|
|
2389
2438
|
imageUrls[0],
|
|
@@ -2393,7 +2442,7 @@ ${infoParts.join("\n")}`;
|
|
|
2393
2442
|
}
|
|
2394
2443
|
);
|
|
2395
2444
|
createdTaskId = taskId;
|
|
2396
|
-
await userManager.
|
|
2445
|
+
const addResult = await userManager.addPendingVideoTaskWithLimit({
|
|
2397
2446
|
taskId,
|
|
2398
2447
|
userId,
|
|
2399
2448
|
userName,
|
|
@@ -2401,64 +2450,119 @@ ${infoParts.join("\n")}`;
|
|
|
2401
2450
|
credits: videoCredits,
|
|
2402
2451
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2403
2452
|
charged: false
|
|
2404
|
-
});
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
const totalTime = Math.floor((Date.now() - startTime) / 1e3);
|
|
2412
|
-
await session.send(`✅ 视频生成完成!(耗时 ${totalTime} 秒)`);
|
|
2413
|
-
} catch (error) {
|
|
2414
|
-
logger.error("视频生成失败", { userId, error: sanitizeError(error) });
|
|
2415
|
-
const errorMsg = error.message || "";
|
|
2416
|
-
if (errorMsg.includes("任务ID:")) {
|
|
2417
|
-
return "⏳ 视频生成超时(任务仍在后台继续生成),请稍后发送“查询视频”获取结果";
|
|
2453
|
+
}, 1);
|
|
2454
|
+
if (!addResult.success) {
|
|
2455
|
+
try {
|
|
2456
|
+
await userManager.deletePendingVideoTask(taskId);
|
|
2457
|
+
} catch {
|
|
2458
|
+
}
|
|
2459
|
+
return addResult.message || "队列已满,请先查询已有任务";
|
|
2418
2460
|
}
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2461
|
+
await session.send("开始生成视频...");
|
|
2462
|
+
} catch (error) {
|
|
2463
|
+
logger.error("视频生成任务提交失败", { userId, error: sanitizeError(error) });
|
|
2464
|
+
if (createdTaskId) {
|
|
2465
|
+
try {
|
|
2466
|
+
await userManager.deletePendingVideoTask(createdTaskId);
|
|
2467
|
+
} catch {
|
|
2468
|
+
}
|
|
2422
2469
|
}
|
|
2423
|
-
|
|
2470
|
+
const errorMsg = error.message || "";
|
|
2471
|
+
return `视频生成任务提交失败:${sanitizeString(errorMsg)}`;
|
|
2424
2472
|
} finally {
|
|
2425
|
-
userManager.
|
|
2473
|
+
userManager.endVideoTask(userId);
|
|
2426
2474
|
}
|
|
2427
2475
|
});
|
|
2428
2476
|
}
|
|
2429
2477
|
if (config.enableVideoGeneration && videoProvider) {
|
|
2430
|
-
ctx.command("查询视频 [taskId:string]", "查询视频生成状态(不传任务ID
|
|
2478
|
+
ctx.command("查询视频 [taskId:string]", "查询视频生成状态(不传任务ID则查询自己所有待生成任务)").action(async ({ session }, taskId) => {
|
|
2431
2479
|
if (!session?.userId) return "会话无效";
|
|
2432
2480
|
const trimmedTaskId = (taskId || "").trim();
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
await session.send("🔍 正在查询视频生成状态...");
|
|
2439
|
-
const status = await videoProvider.queryTaskStatus(resolvedTaskId);
|
|
2440
|
-
if (status.status === "completed" && status.videoUrl) {
|
|
2441
|
-
const pending = await userManager.getPendingVideoTask(resolvedTaskId);
|
|
2481
|
+
if (trimmedTaskId) {
|
|
2482
|
+
try {
|
|
2483
|
+
await session.send("正在查询视频生成状态...");
|
|
2484
|
+
const status = await videoProvider.queryTaskStatus(trimmedTaskId);
|
|
2485
|
+
const pending = await userManager.getPendingVideoTask(trimmedTaskId);
|
|
2442
2486
|
if (pending && pending.userId && pending.userId !== session.userId) {
|
|
2443
2487
|
return "该任务ID不属于当前用户,无法查询";
|
|
2444
2488
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2489
|
+
if (status.status === "completed" && status.videoUrl) {
|
|
2490
|
+
await session.send(import_koishi2.h.video(status.videoUrl));
|
|
2491
|
+
if (pending && !pending.charged) {
|
|
2492
|
+
await recordUserUsage(session, pending.commandName, pending.credits, false);
|
|
2493
|
+
await userManager.markPendingVideoTaskCharged(trimmedTaskId);
|
|
2494
|
+
await userManager.deletePendingVideoTask(trimmedTaskId);
|
|
2495
|
+
}
|
|
2496
|
+
return "视频生成完成!";
|
|
2497
|
+
} else if (status.status === "processing" || status.status === "pending") {
|
|
2498
|
+
const progressText = status.progress ? `(进度:${status.progress}%)` : "";
|
|
2499
|
+
return `视频正在生成中${progressText},请稍后再次查询`;
|
|
2500
|
+
} else if (status.status === "failed") {
|
|
2501
|
+
if (pending && !pending.charged) {
|
|
2502
|
+
await userManager.deletePendingVideoTask(trimmedTaskId);
|
|
2503
|
+
}
|
|
2504
|
+
return `视频生成失败:${status.error || "未知错误"}`;
|
|
2505
|
+
} else {
|
|
2506
|
+
return `❓ 未知状态:${status.status}`;
|
|
2507
|
+
}
|
|
2508
|
+
} catch (error) {
|
|
2509
|
+
logger.error("查询视频任务失败", { taskId: trimmedTaskId, error: sanitizeError(error) });
|
|
2510
|
+
return `查询失败:${sanitizeString(error.message)}`;
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
try {
|
|
2514
|
+
const pendingTasks = await userManager.listPendingVideoTasksForUser(session.userId);
|
|
2515
|
+
if (pendingTasks.length === 0) {
|
|
2516
|
+
return "你当前没有可查询的待生成视频任务";
|
|
2517
|
+
}
|
|
2518
|
+
await session.send(`正在查询 ${pendingTasks.length} 个视频任务状态...`);
|
|
2519
|
+
let completedCount = 0;
|
|
2520
|
+
let processingCount = 0;
|
|
2521
|
+
let failedCount = 0;
|
|
2522
|
+
const messages = [];
|
|
2523
|
+
for (const task of pendingTasks) {
|
|
2524
|
+
try {
|
|
2525
|
+
const status = await videoProvider.queryTaskStatus(task.taskId);
|
|
2526
|
+
if (status.status === "completed" && status.videoUrl) {
|
|
2527
|
+
await session.send(import_koishi2.h.video(status.videoUrl));
|
|
2528
|
+
if (!task.charged) {
|
|
2529
|
+
await recordUserUsage(session, task.commandName, task.credits, false);
|
|
2530
|
+
await userManager.markPendingVideoTaskCharged(task.taskId);
|
|
2531
|
+
await userManager.deletePendingVideoTask(task.taskId);
|
|
2532
|
+
}
|
|
2533
|
+
completedCount++;
|
|
2534
|
+
messages.push(`任务 ${task.taskId.substring(0, 20)}... 已完成`);
|
|
2535
|
+
} else if (status.status === "processing" || status.status === "pending") {
|
|
2536
|
+
processingCount++;
|
|
2537
|
+
const progressText = status.progress ? `(进度:${status.progress}%)` : "";
|
|
2538
|
+
messages.push(`任务 ${task.taskId.substring(0, 20)}... 生成中${progressText}`);
|
|
2539
|
+
} else if (status.status === "failed") {
|
|
2540
|
+
if (!task.charged) {
|
|
2541
|
+
await userManager.deletePendingVideoTask(task.taskId);
|
|
2542
|
+
}
|
|
2543
|
+
failedCount++;
|
|
2544
|
+
messages.push(`任务 ${task.taskId.substring(0, 20)}... 失败:${status.error || "未知错误"}`);
|
|
2545
|
+
} else {
|
|
2546
|
+
messages.push(`❓ 任务 ${task.taskId.substring(0, 20)}... 状态:${status.status}`);
|
|
2547
|
+
}
|
|
2548
|
+
} catch (error) {
|
|
2549
|
+
logger.error("查询单个视频任务失败", { taskId: task.taskId, error: sanitizeError(error) });
|
|
2550
|
+
messages.push(`⚠️ 任务 ${task.taskId.substring(0, 20)}... 查询失败:${sanitizeString(error.message)}`);
|
|
2450
2551
|
}
|
|
2451
|
-
return "✅ 视频已生成完成!";
|
|
2452
|
-
} else if (status.status === "processing" || status.status === "pending") {
|
|
2453
|
-
const progressText = status.progress ? `(进度:${status.progress}%)` : "";
|
|
2454
|
-
return `⏳ 视频正在生成中${progressText},请稍后再次查询`;
|
|
2455
|
-
} else if (status.status === "failed") {
|
|
2456
|
-
return `❌ 视频生成失败:${status.error || "未知错误"}`;
|
|
2457
|
-
} else {
|
|
2458
|
-
return `❓ 未知状态:${status.status}`;
|
|
2459
2552
|
}
|
|
2553
|
+
let summary = `查询结果汇总:
|
|
2554
|
+
`;
|
|
2555
|
+
if (completedCount > 0) summary += `已完成:${completedCount} 个
|
|
2556
|
+
`;
|
|
2557
|
+
if (processingCount > 0) summary += `生成中:${processingCount} 个
|
|
2558
|
+
`;
|
|
2559
|
+
if (failedCount > 0) summary += `失败:${failedCount} 个
|
|
2560
|
+
`;
|
|
2561
|
+
summary += `
|
|
2562
|
+
${messages.join("\n")}`;
|
|
2563
|
+
return summary;
|
|
2460
2564
|
} catch (error) {
|
|
2461
|
-
logger.error("
|
|
2565
|
+
logger.error("查询视频任务列表失败", { userId: session.userId, error: sanitizeError(error) });
|
|
2462
2566
|
return `查询失败:${sanitizeString(error.message)}`;
|
|
2463
2567
|
}
|
|
2464
2568
|
});
|
|
@@ -2480,8 +2584,8 @@ ${infoParts.join("\n")}`;
|
|
|
2480
2584
|
if (!limitCheck.allowed) {
|
|
2481
2585
|
return limitCheck.message;
|
|
2482
2586
|
}
|
|
2483
|
-
if (!userManager.
|
|
2484
|
-
return "
|
|
2587
|
+
if (!userManager.startVideoTask(userId)) {
|
|
2588
|
+
return "您有一个视频任务正在进行中,请等待完成";
|
|
2485
2589
|
}
|
|
2486
2590
|
let createdTaskId = null;
|
|
2487
2591
|
try {
|
|
@@ -2497,11 +2601,6 @@ ${infoParts.join("\n")}`;
|
|
|
2497
2601
|
if (extraText) {
|
|
2498
2602
|
finalPrompt += " - " + extraText;
|
|
2499
2603
|
}
|
|
2500
|
-
await session.send(
|
|
2501
|
-
`🎬 开始生成视频(${style.commandName})...
|
|
2502
|
-
📝 描述:${finalPrompt}
|
|
2503
|
-
⏱️ 预计需要 1-3 分钟`
|
|
2504
|
-
);
|
|
2505
2604
|
const taskId = await videoProvider.createVideoTask(
|
|
2506
2605
|
finalPrompt,
|
|
2507
2606
|
imageUrls[0],
|
|
@@ -2511,7 +2610,7 @@ ${infoParts.join("\n")}`;
|
|
|
2511
2610
|
}
|
|
2512
2611
|
);
|
|
2513
2612
|
createdTaskId = taskId;
|
|
2514
|
-
await userManager.
|
|
2613
|
+
const addResult = await userManager.addPendingVideoTaskWithLimit({
|
|
2515
2614
|
taskId,
|
|
2516
2615
|
userId,
|
|
2517
2616
|
userName,
|
|
@@ -2519,27 +2618,27 @@ ${infoParts.join("\n")}`;
|
|
|
2519
2618
|
credits: videoCredits,
|
|
2520
2619
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2521
2620
|
charged: false
|
|
2522
|
-
});
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
await session.send(`✅ 视频生成完成!`);
|
|
2530
|
-
} catch (error) {
|
|
2531
|
-
logger.error("视频风格转换失败", { userId, style: style.commandName, error: sanitizeError(error) });
|
|
2532
|
-
const errorMsg = error.message || "";
|
|
2533
|
-
if (errorMsg.includes("任务ID:")) {
|
|
2534
|
-
return "⏳ 视频生成超时(任务仍在后台继续生成),请稍后发送“查询视频”获取结果";
|
|
2621
|
+
}, 1);
|
|
2622
|
+
if (!addResult.success) {
|
|
2623
|
+
try {
|
|
2624
|
+
await userManager.deletePendingVideoTask(taskId);
|
|
2625
|
+
} catch {
|
|
2626
|
+
}
|
|
2627
|
+
return addResult.message || "队列已满,请先查询已有任务";
|
|
2535
2628
|
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2629
|
+
await session.send(`开始生成视频(${style.commandName})...`);
|
|
2630
|
+
} catch (error) {
|
|
2631
|
+
logger.error("视频风格转换任务提交失败", { userId, style: style.commandName, error: sanitizeError(error) });
|
|
2632
|
+
if (createdTaskId) {
|
|
2633
|
+
try {
|
|
2634
|
+
await userManager.deletePendingVideoTask(createdTaskId);
|
|
2635
|
+
} catch {
|
|
2636
|
+
}
|
|
2539
2637
|
}
|
|
2540
|
-
|
|
2638
|
+
const errorMsg = error.message || "";
|
|
2639
|
+
return `视频生成任务提交失败:${sanitizeString(errorMsg)}`;
|
|
2541
2640
|
} finally {
|
|
2542
|
-
userManager.
|
|
2641
|
+
userManager.endVideoTask(userId);
|
|
2543
2642
|
}
|
|
2544
2643
|
});
|
|
2545
2644
|
logger.info(`已注册视频风格命令: ${style.commandName}`);
|
|
@@ -67,6 +67,7 @@ export declare class UserManager {
|
|
|
67
67
|
private usersCache;
|
|
68
68
|
private pendingVideoCache;
|
|
69
69
|
private activeTasks;
|
|
70
|
+
private activeVideoTasks;
|
|
70
71
|
private rateLimitMap;
|
|
71
72
|
private securityBlockMap;
|
|
72
73
|
private securityWarningMap;
|
|
@@ -74,6 +75,9 @@ export declare class UserManager {
|
|
|
74
75
|
startTask(userId: string): boolean;
|
|
75
76
|
endTask(userId: string): void;
|
|
76
77
|
isTaskActive(userId: string): boolean;
|
|
78
|
+
startVideoTask(userId: string): boolean;
|
|
79
|
+
endVideoTask(userId: string): void;
|
|
80
|
+
isVideoTaskActive(userId: string): boolean;
|
|
77
81
|
isAdmin(userId: string, config: Config): boolean;
|
|
78
82
|
private loadUsersData;
|
|
79
83
|
private saveUsersDataInternal;
|
|
@@ -90,6 +94,22 @@ export declare class UserManager {
|
|
|
90
94
|
* 获取某个用户最近一次未扣费的待结算视频任务
|
|
91
95
|
*/
|
|
92
96
|
getLatestPendingVideoTaskForUser(userId: string): Promise<PendingVideoTask | null>;
|
|
97
|
+
/**
|
|
98
|
+
* 统计某个用户未扣费的待结算视频任务数量
|
|
99
|
+
*/
|
|
100
|
+
countPendingVideoTasksForUser(userId: string): Promise<number>;
|
|
101
|
+
/**
|
|
102
|
+
* 列出某个用户所有未扣费的待结算视频任务
|
|
103
|
+
*/
|
|
104
|
+
listPendingVideoTasksForUser(userId: string): Promise<PendingVideoTask[]>;
|
|
105
|
+
/**
|
|
106
|
+
* 添加待结算视频任务,并检查上限(默认max=1)
|
|
107
|
+
* @returns {Promise<{success: boolean, message?: string}>} 成功返回 {success: true},失败返回 {success: false, message: '错误信息'}
|
|
108
|
+
*/
|
|
109
|
+
addPendingVideoTaskWithLimit(task: PendingVideoTask, max?: number): Promise<{
|
|
110
|
+
success: boolean;
|
|
111
|
+
message?: string;
|
|
112
|
+
}>;
|
|
93
113
|
getUserData(userId: string, userName: string): Promise<UserData>;
|
|
94
114
|
getAllUsers(): Promise<UsersData>;
|
|
95
115
|
updateUsersBatch(updates: (data: UsersData) => void): Promise<void>;
|