@dsh-plugin/dsh-synapse 0.0.0-stage → 0.1.0-dev.41044818627
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/LICENSE +661 -0
- package/NOTICE.md +18 -0
- package/README.md +136 -2
- package/cordis.patch.yml +3 -0
- package/lib/bot.cjs +8314 -0
- package/lib/bot.cjs.map +7 -0
- package/lib/build.json +1 -0
- package/lib/client.js +46 -0
- package/lib/host/agent.d.ts +21 -0
- package/lib/host/agent.js +151 -0
- package/lib/host/agent.js.map +1 -0
- package/lib/host/bot.d.ts +17 -0
- package/lib/host/bot.js +158 -0
- package/lib/host/bot.js.map +1 -0
- package/lib/host/client.d.ts +2 -0
- package/lib/host/client.js +19 -0
- package/lib/host/client.js.map +1 -0
- package/lib/host/config.d.ts +24 -0
- package/lib/host/config.js +192 -0
- package/lib/host/config.js.map +1 -0
- package/lib/host/files.d.ts +29 -0
- package/lib/host/files.js +188 -0
- package/lib/host/files.js.map +1 -0
- package/lib/host/gateway.d.ts +33 -0
- package/lib/host/gateway.js +237 -0
- package/lib/host/gateway.js.map +1 -0
- package/lib/host/github.d.ts +47 -0
- package/lib/host/github.js +219 -0
- package/lib/host/github.js.map +1 -0
- package/lib/host/http.d.ts +4 -0
- package/lib/host/http.js +41 -0
- package/lib/host/http.js.map +1 -0
- package/lib/host/index.d.ts +32 -0
- package/lib/host/index.js +192 -0
- package/lib/host/index.js.map +1 -0
- package/lib/host/inference-worker.d.ts +1 -0
- package/lib/host/inference-worker.js +72 -0
- package/lib/host/inference-worker.js.map +1 -0
- package/lib/host/mcp.d.ts +138 -0
- package/lib/host/mcp.js +104 -0
- package/lib/host/mcp.js.map +1 -0
- package/lib/host/memory.d.ts +26 -0
- package/lib/host/memory.js +155 -0
- package/lib/host/memory.js.map +1 -0
- package/lib/host/panel.d.ts +1 -0
- package/lib/host/panel.html +174 -0
- package/lib/host/panel.js +388 -0
- package/lib/host/panel.js.map +1 -0
- package/lib/host/runtime.d.ts +21 -0
- package/lib/host/runtime.js +145 -0
- package/lib/host/runtime.js.map +1 -0
- package/lib/host/types.d.ts +112 -0
- package/lib/host/types.js +2 -0
- package/lib/host/types.js.map +1 -0
- package/package.json +94 -4
- package/scripts/build.mjs +90 -0
- package/scripts/check.mjs +13 -0
- package/scripts/dump-npm-latest.mjs +49 -0
- package/scripts/model-smoke.mjs +25 -0
- package/src/agent.ts +203 -0
- package/src/bot.ts +173 -0
- package/src/client.ts +20 -0
- package/src/config.ts +217 -0
- package/src/files.ts +206 -0
- package/src/gateway.ts +276 -0
- package/src/github.ts +263 -0
- package/src/http.ts +41 -0
- package/src/index.ts +227 -0
- package/src/inference-worker.ts +89 -0
- package/src/mcp.ts +112 -0
- package/src/memory.ts +178 -0
- package/src/panel.html +174 -0
- package/src/panel.ts +440 -0
- package/src/runtime.ts +164 -0
- package/src/types.ts +106 -0
- package/test/core.test.mjs +279 -0
- package/test/fixtures/mcp-server.mjs +14 -0
- package/test/integration.test.mjs +253 -0
- package/test/panel.test.mjs +73 -0
- package/tsconfig.json +18 -0
- package/vendor/gugle-chat-bot/LICENSE +661 -0
- package/vendor/gugle-chat-bot/package.json +57 -0
- package/vendor/gugle-chat-bot/src/allow-rule.yml +9345 -0
- package/vendor/gugle-chat-bot/src/api.json +4285 -0
- package/vendor/gugle-chat-bot/src/command/index.ts +141 -0
- package/vendor/gugle-chat-bot/src/config/features.ts +548 -0
- package/vendor/gugle-chat-bot/src/config/index.ts +184 -0
- package/vendor/gugle-chat-bot/src/config/manager.ts +357 -0
- package/vendor/gugle-chat-bot/src/constants/index.ts +13 -0
- package/vendor/gugle-chat-bot/src/custom.ts +548 -0
- package/vendor/gugle-chat-bot/src/event/index.ts +118 -0
- package/vendor/gugle-chat-bot/src/features/admin/index.ts +414 -0
- package/vendor/gugle-chat-bot/src/features/bili/image/impl/video.ts +39 -0
- package/vendor/gugle-chat-bot/src/features/bili/image/index.ts +37 -0
- package/vendor/gugle-chat-bot/src/features/bili/index.ts +65 -0
- package/vendor/gugle-chat-bot/src/features/bili/template/style/video.css +97 -0
- package/vendor/gugle-chat-bot/src/features/bili/template/video.html +57 -0
- package/vendor/gugle-chat-bot/src/features/discord-bridge/index.ts +1128 -0
- package/vendor/gugle-chat-bot/src/features/discord-bridge/markdown.ts +105 -0
- package/vendor/gugle-chat-bot/src/features/discord-bridge/slash.ts +355 -0
- package/vendor/gugle-chat-bot/src/features/discord-bridge/source.ts +96 -0
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/message.html +14 -0
- package/vendor/gugle-chat-bot/src/features/discord-bridge/template/style/message.css +144 -0
- package/vendor/gugle-chat-bot/src/features/github/api.ts +93 -0
- package/vendor/gugle-chat-bot/src/features/github/binding.ts +161 -0
- package/vendor/gugle-chat-bot/src/features/github/image/impl/issue.ts +132 -0
- package/vendor/gugle-chat-bot/src/features/github/image/impl/pr.ts +144 -0
- package/vendor/gugle-chat-bot/src/features/github/image/impl/release.ts +160 -0
- package/vendor/gugle-chat-bot/src/features/github/image/index.ts +310 -0
- package/vendor/gugle-chat-bot/src/features/github/index.ts +302 -0
- package/vendor/gugle-chat-bot/src/features/github/template/issue.html +118 -0
- package/vendor/gugle-chat-bot/src/features/github/template/pull_request.html +125 -0
- package/vendor/gugle-chat-bot/src/features/github/template/release.html +53 -0
- package/vendor/gugle-chat-bot/src/features/github/template/style/issue.css +468 -0
- package/vendor/gugle-chat-bot/src/features/github/template/style/pull_request.css +469 -0
- package/vendor/gugle-chat-bot/src/features/github/template/style/release.css +412 -0
- package/vendor/gugle-chat-bot/src/features/hermes/client.ts +184 -0
- package/vendor/gugle-chat-bot/src/features/hermes/config.ts +210 -0
- package/vendor/gugle-chat-bot/src/features/hermes/context.ts +67 -0
- package/vendor/gugle-chat-bot/src/features/hermes/history.ts +86 -0
- package/vendor/gugle-chat-bot/src/features/hermes/index.ts +1533 -0
- package/vendor/gugle-chat-bot/src/features/hermes/message.ts +319 -0
- package/vendor/gugle-chat-bot/src/features/hermes/reaction.ts +181 -0
- package/vendor/gugle-chat-bot/src/features/hermes/render.ts +118 -0
- package/vendor/gugle-chat-bot/src/features/hermes/reply-units.ts +331 -0
- package/vendor/gugle-chat-bot/src/features/hermes/skills.ts +406 -0
- package/vendor/gugle-chat-bot/src/features/hermes/template/approval.html +30 -0
- package/vendor/gugle-chat-bot/src/features/hermes/template/progress.html +21 -0
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/approval.css +81 -0
- package/vendor/gugle-chat-bot/src/features/hermes/template/style/progress.css +120 -0
- package/vendor/gugle-chat-bot/src/features/hermes/trigger.ts +86 -0
- package/vendor/gugle-chat-bot/src/features/hermes/types.ts +327 -0
- package/vendor/gugle-chat-bot/src/features/management/index.ts +156 -0
- package/vendor/gugle-chat-bot/src/features/minecraft/index.ts +127 -0
- package/vendor/gugle-chat-bot/src/features/modrinth/index.ts +71 -0
- package/vendor/gugle-chat-bot/src/features/parentheses/index.ts +117 -0
- package/vendor/gugle-chat-bot/src/features/peak-valley-timer/index.ts +452 -0
- package/vendor/gugle-chat-bot/src/features/poke/index.ts +24 -0
- package/vendor/gugle-chat-bot/src/features/version-tracker/index.ts +78 -0
- package/vendor/gugle-chat-bot/src/features/welcome/index.ts +58 -0
- package/vendor/gugle-chat-bot/src/github-ip.json +5814 -0
- package/vendor/gugle-chat-bot/src/image/index.ts +278 -0
- package/vendor/gugle-chat-bot/src/index.ts +695 -0
- package/vendor/gugle-chat-bot/src/logger/index.ts +54 -0
- package/vendor/gugle-chat-bot/src/result.json +359 -0
- package/vendor/gugle-chat-bot/src/type/bili.d.ts +825 -0
- package/vendor/gugle-chat-bot/src/type/event.d.ts +146 -0
- package/vendor/gugle-chat-bot/src/type/github.d.ts +446 -0
- package/vendor/gugle-chat-bot/src/type/index.d.ts +254 -0
- package/vendor/gugle-chat-bot/tsconfig.json +46 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import puppeteer, { Browser, Page } from 'puppeteer';
|
|
4
|
+
import { botConfig } from '@/config';
|
|
5
|
+
|
|
6
|
+
export class Template {
|
|
7
|
+
private readonly templatePath: string;
|
|
8
|
+
private readonly templateName: string;
|
|
9
|
+
private processor: ((template: string) => string)[] = [];
|
|
10
|
+
|
|
11
|
+
public constructor(templateName: string, templatePath: string) {
|
|
12
|
+
this.templateName = templateName;
|
|
13
|
+
this.templatePath = templatePath;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public static load(templateName: string, templatePath: string = 'src/template'): Template {
|
|
17
|
+
return new Template(templateName, templatePath);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private async loadTemplate(templateName: string, templatePath: string): Promise<string> {
|
|
21
|
+
return fs.readFileSync(`${templatePath}/${templateName}.html`, 'utf8');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public arg(param: string, object: any): Template {
|
|
25
|
+
this.processor.push(template => {
|
|
26
|
+
while (template.includes(`{{${param}}}`)) {
|
|
27
|
+
template = template.replace(`{{${param}}}`, object.toString());
|
|
28
|
+
}
|
|
29
|
+
return template;
|
|
30
|
+
});
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 返回模板文件的绝对路径(用于以模板所在目录为相对路径根加载 CSS 等资源)。
|
|
36
|
+
*/
|
|
37
|
+
public file(): string {
|
|
38
|
+
return path.resolve(this.templatePath, `${this.templateName}.html`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 渲染模板:填充所有参数,返回处理后的 HTML 字符串。
|
|
43
|
+
* 注意:CSS 不再内联进 HTML(改由 file:// 相对路径加载),
|
|
44
|
+
* 但保留 {{style sheet}} 占位符兼容旧模板。
|
|
45
|
+
*/
|
|
46
|
+
public handler(): Promise<string> {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
this.loadTemplate(this.templateName, this.templatePath)
|
|
49
|
+
.then(template => {
|
|
50
|
+
try {
|
|
51
|
+
this.processor.forEach(processor => {
|
|
52
|
+
template = processor(template);
|
|
53
|
+
});
|
|
54
|
+
resolve(template);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
reject(e);
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
.catch(reject);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function imageToBase64(image: Buffer<ArrayBufferLike>) {
|
|
65
|
+
return image.toString('base64');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 串行图片生成队列:同一时刻只允许一张图片生成任务执行,
|
|
70
|
+
* 上一张生成完毕(成功或失败)后再开始下一张。
|
|
71
|
+
*/
|
|
72
|
+
let imageQueueTail: Promise<void> = Promise.resolve();
|
|
73
|
+
let imageQueueSize = 0;
|
|
74
|
+
|
|
75
|
+
function enqueueImageTask<T>(task: () => Promise<T>): Promise<T> {
|
|
76
|
+
const result = imageQueueTail.then(task);
|
|
77
|
+
// 无论任务成功还是失败,队列都必须继续流转
|
|
78
|
+
imageQueueTail = result.then(
|
|
79
|
+
() => undefined,
|
|
80
|
+
() => undefined
|
|
81
|
+
);
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
// 可复用 Chrome 实例管理
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
/** 空闲多少毫秒后关闭 Chrome 实例(默认 5 分钟,可用环境变量覆盖以便测试) */
|
|
90
|
+
const BROWSER_IDLE_TIMEOUT_MS = Number(process.env.GUGLE_IMAGE_IDLE_TIMEOUT_MS) || 5 * 60 * 1000;
|
|
91
|
+
|
|
92
|
+
let sharedBrowser: Browser | undefined = undefined;
|
|
93
|
+
let browserIdleTimer: NodeJS.Timeout | undefined = undefined;
|
|
94
|
+
/** 记录上一次完成生成的时间,用于空闲判定 */
|
|
95
|
+
let lastBrowserUseTime = 0;
|
|
96
|
+
|
|
97
|
+
function browserLaunchArgs(): string[] {
|
|
98
|
+
return [
|
|
99
|
+
'--no-sandbox',
|
|
100
|
+
'--disable-setuid-sandbox',
|
|
101
|
+
'--disable-dev-shm-usage',
|
|
102
|
+
'--disable-gpu',
|
|
103
|
+
'--disable-software-rasterizer',
|
|
104
|
+
'--disable-extensions'
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 惰性启动(或复用)共享的 Chrome 实例。
|
|
110
|
+
* 若实例已存在则直接复用,并重置空闲计时器。
|
|
111
|
+
*/
|
|
112
|
+
async function getSharedBrowser(): Promise<Browser> {
|
|
113
|
+
if (sharedBrowser && sharedBrowser.isConnected()) {
|
|
114
|
+
clearTimeout(browserIdleTimer);
|
|
115
|
+
return sharedBrowser;
|
|
116
|
+
}
|
|
117
|
+
sharedBrowser = await puppeteer.launch({
|
|
118
|
+
executablePath: botConfig.chromePath,
|
|
119
|
+
headless: true,
|
|
120
|
+
defaultViewport: { width: 820, height: 1 },
|
|
121
|
+
args: browserLaunchArgs()
|
|
122
|
+
});
|
|
123
|
+
clearTimeout(browserIdleTimer);
|
|
124
|
+
lastBrowserUseTime = Date.now();
|
|
125
|
+
return sharedBrowser;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** 关闭共享的 Chrome 实例(幂等) */
|
|
129
|
+
function closeSharedBrowser(): void {
|
|
130
|
+
clearTimeout(browserIdleTimer);
|
|
131
|
+
browserIdleTimer = undefined;
|
|
132
|
+
const browser = sharedBrowser;
|
|
133
|
+
sharedBrowser = undefined;
|
|
134
|
+
if (browser && browser.isConnected()) {
|
|
135
|
+
browser.close().catch(() => undefined);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* 空闲回收调度:当没有新的生成任务时,等待 BROWSER_IDLE_TIMEOUT_MS
|
|
141
|
+
* 后自动关闭 Chrome 实例,避免长期占用内存。
|
|
142
|
+
*/
|
|
143
|
+
function scheduleBrowserIdleClose(): void {
|
|
144
|
+
clearTimeout(browserIdleTimer);
|
|
145
|
+
lastBrowserUseTime = Date.now();
|
|
146
|
+
browserIdleTimer = setTimeout(() => {
|
|
147
|
+
// 若这段时间内又有新的任务在跑,就不关闭(任务结束后会重新调度)
|
|
148
|
+
if (imageQueueSize > 0 || Date.now() - lastBrowserUseTime < BROWSER_IDLE_TIMEOUT_MS) {
|
|
149
|
+
scheduleBrowserIdleClose();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
closeSharedBrowser();
|
|
153
|
+
}, BROWSER_IDLE_TIMEOUT_MS);
|
|
154
|
+
// 空闲定时器不应阻止进程退出(如测试/无任务时)
|
|
155
|
+
browserIdleTimer.unref?.();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 进程退出时优雅关闭共享 Chrome 实例,避免残留子进程。
|
|
159
|
+
// SIGINT/SIGTERM 下等待关闭完成后再退出;exit 事件里做同步兜底。
|
|
160
|
+
process.once('SIGINT', () => {
|
|
161
|
+
closeSharedBrowser();
|
|
162
|
+
process.exit(0);
|
|
163
|
+
});
|
|
164
|
+
process.once('SIGTERM', () => {
|
|
165
|
+
closeSharedBrowser();
|
|
166
|
+
process.exit(0);
|
|
167
|
+
});
|
|
168
|
+
process.once('exit', () => {
|
|
169
|
+
// exit 事件中无法 await,仅兜底(close 的 promise 由事件循环继续完成)
|
|
170
|
+
const browser = sharedBrowser;
|
|
171
|
+
sharedBrowser = undefined;
|
|
172
|
+
if (browser && browser.isConnected()) {
|
|
173
|
+
browser.close().catch(() => undefined);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 等待页面中所有 <img> 元素加载完成。
|
|
179
|
+
* 轮询检查:所有图片 complete 且 naturalWidth > 0(加载成功);
|
|
180
|
+
* 没有图片时立即返回。最多等待 timeoutMs,超时仍继续(不阻塞截图)。
|
|
181
|
+
*/
|
|
182
|
+
async function waitForImagesLoaded(page: Page, timeoutMs: number = 30000): Promise<void> {
|
|
183
|
+
const start = Date.now();
|
|
184
|
+
while (Date.now() - start < timeoutMs) {
|
|
185
|
+
const pending = await page.evaluate(() => {
|
|
186
|
+
const images = Array.from(document.querySelectorAll('img'));
|
|
187
|
+
if (images.length === 0) return 0;
|
|
188
|
+
return images.filter(img => !img.complete || img.naturalWidth === 0).length;
|
|
189
|
+
});
|
|
190
|
+
if (pending === 0) return;
|
|
191
|
+
await new Promise(r => setTimeout(r, 200));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 用共享 Chrome 实例渲染 HTML 并截图。
|
|
197
|
+
* 若提供 templateFile,则用 file:// 加载该文件(以模板所在目录为相对路径根,
|
|
198
|
+
* 相对路径的 CSS/资源会按此解析),并在页面内替换 {{xxx}} 占位符;
|
|
199
|
+
* 否则退回 setContent(相对路径无法解析,需内联样式)。
|
|
200
|
+
*/
|
|
201
|
+
async function renderWithSharedBrowser(
|
|
202
|
+
html: string,
|
|
203
|
+
width: number,
|
|
204
|
+
templateFile?: string
|
|
205
|
+
): Promise<Buffer> {
|
|
206
|
+
const browser = await getSharedBrowser();
|
|
207
|
+
const page = await browser.newPage();
|
|
208
|
+
try {
|
|
209
|
+
await page.setViewport({ width, height: 1 });
|
|
210
|
+
if (templateFile) {
|
|
211
|
+
const fileUrl = 'file:///' + path.resolve(templateFile).replace(/\\/g, '/');
|
|
212
|
+
await page.goto(fileUrl, { waitUntil: 'networkidle0', timeout: 60000 });
|
|
213
|
+
// 在页面内替换所有 {{xxx}} 占位符(与 Template.arg 的替换逻辑一致)
|
|
214
|
+
await page.evaluate(processedHtml => {
|
|
215
|
+
document.documentElement.innerHTML = processedHtml;
|
|
216
|
+
// 移除遗留的 {{style sheet}} 占位符
|
|
217
|
+
document.querySelectorAll('*').forEach(el => {
|
|
218
|
+
if (el.children.length === 0) {
|
|
219
|
+
el.textContent = el.textContent.replace(/\{\{style sheet\}\}/g, '');
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}, html);
|
|
223
|
+
// 等待替换后插入的图片加载完成(data URL / 相对路径),避免截图时图片缺失
|
|
224
|
+
await waitForImagesLoaded(page);
|
|
225
|
+
} else {
|
|
226
|
+
await page.setContent(html, { waitUntil: 'networkidle0', timeout: 60000 });
|
|
227
|
+
// setContent 路径同样等待图片加载完成
|
|
228
|
+
await waitForImagesLoaded(page);
|
|
229
|
+
}
|
|
230
|
+
const element = await page.$('body');
|
|
231
|
+
if (!element) {
|
|
232
|
+
throw new Error('No element matches selector: body');
|
|
233
|
+
}
|
|
234
|
+
// 默认 encoding 为 binary,返回 Uint8Array;转成 Buffer 后再 base64
|
|
235
|
+
const image = (await element.screenshot({ type: 'png' })) as Uint8Array;
|
|
236
|
+
return Buffer.from(image);
|
|
237
|
+
} finally {
|
|
238
|
+
await page.close().catch(() => undefined);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function generateImage(
|
|
243
|
+
resolve: (value: string | PromiseLike<string>) => void,
|
|
244
|
+
reject: (reason?: any) => void,
|
|
245
|
+
html: string,
|
|
246
|
+
width: number,
|
|
247
|
+
templateFile?: string
|
|
248
|
+
): Promise<void> {
|
|
249
|
+
return new Promise<void>((taskResolve, taskReject) => {
|
|
250
|
+
renderWithSharedBrowser(html, width, templateFile)
|
|
251
|
+
.then(image => {
|
|
252
|
+
resolve(imageToBase64(image));
|
|
253
|
+
taskResolve();
|
|
254
|
+
})
|
|
255
|
+
.catch(e => {
|
|
256
|
+
reject(e);
|
|
257
|
+
taskReject(e);
|
|
258
|
+
})
|
|
259
|
+
.finally(() => {
|
|
260
|
+
scheduleBrowserIdleClose();
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function tryGenerateImage(
|
|
266
|
+
resolve: (value: string | PromiseLike<string>) => void,
|
|
267
|
+
reject: (reason?: any) => void,
|
|
268
|
+
html: string,
|
|
269
|
+
width: number = 820,
|
|
270
|
+
templateFile?: string
|
|
271
|
+
) {
|
|
272
|
+
imageQueueSize++;
|
|
273
|
+
enqueueImageTask(() => generateImage(resolve, reject, html, width, templateFile))
|
|
274
|
+
.catch(() => undefined)
|
|
275
|
+
.finally(() => {
|
|
276
|
+
imageQueueSize--;
|
|
277
|
+
});
|
|
278
|
+
}
|