@fett/sql-translator 0.0.1-beta
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 +191 -0
- package/lib/client/client.d.ts +59 -0
- package/lib/client/client.d.ts.map +1 -0
- package/lib/client/client.js +201 -0
- package/lib/client/client.js.map +1 -0
- package/lib/client/index.d.ts +15 -0
- package/lib/client/index.d.ts.map +1 -0
- package/lib/client/index.js +15 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client/manager.d.ts +27 -0
- package/lib/client/manager.d.ts.map +1 -0
- package/lib/client/manager.js +73 -0
- package/lib/client/manager.js.map +1 -0
- package/lib/client/registry.d.ts +31 -0
- package/lib/client/registry.d.ts.map +1 -0
- package/lib/client/registry.js +128 -0
- package/lib/client/registry.js.map +1 -0
- package/lib/core/cache.d.ts +28 -0
- package/lib/core/cache.d.ts.map +1 -0
- package/lib/core/cache.js +58 -0
- package/lib/core/cache.js.map +1 -0
- package/lib/core/config.d.ts +16 -0
- package/lib/core/config.d.ts.map +1 -0
- package/lib/core/config.js +47 -0
- package/lib/core/config.js.map +1 -0
- package/lib/core/field-mapper/mysql.d.ts +42 -0
- package/lib/core/field-mapper/mysql.d.ts.map +1 -0
- package/lib/core/field-mapper/mysql.js +129 -0
- package/lib/core/field-mapper/mysql.js.map +1 -0
- package/lib/core/field-mapper/postgresql.d.ts +25 -0
- package/lib/core/field-mapper/postgresql.d.ts.map +1 -0
- package/lib/core/field-mapper/postgresql.js +121 -0
- package/lib/core/field-mapper/postgresql.js.map +1 -0
- package/lib/core/sql/normalize.d.ts +10 -0
- package/lib/core/sql/normalize.d.ts.map +1 -0
- package/lib/core/sql/normalize.js +121 -0
- package/lib/core/sql/normalize.js.map +1 -0
- package/lib/core/sql/pagination.d.ts +22 -0
- package/lib/core/sql/pagination.d.ts.map +1 -0
- package/lib/core/sql/pagination.js +61 -0
- package/lib/core/sql/pagination.js.map +1 -0
- package/lib/core/sql/statement.d.ts +28 -0
- package/lib/core/sql/statement.d.ts.map +1 -0
- package/lib/core/sql/statement.js +155 -0
- package/lib/core/sql/statement.js.map +1 -0
- package/lib/core/sql/table-mapper.d.ts +24 -0
- package/lib/core/sql/table-mapper.d.ts.map +1 -0
- package/lib/core/sql/table-mapper.js +113 -0
- package/lib/core/sql/table-mapper.js.map +1 -0
- package/lib/core/task-queue.d.ts +31 -0
- package/lib/core/task-queue.d.ts.map +1 -0
- package/lib/core/task-queue.js +185 -0
- package/lib/core/task-queue.js.map +1 -0
- package/lib/core/worker/bun-worker.d.ts +21 -0
- package/lib/core/worker/bun-worker.d.ts.map +1 -0
- package/lib/core/worker/bun-worker.js +93 -0
- package/lib/core/worker/bun-worker.js.map +1 -0
- package/lib/core/worker/index.d.ts +16 -0
- package/lib/core/worker/index.d.ts.map +1 -0
- package/lib/core/worker/index.js +16 -0
- package/lib/core/worker/index.js.map +1 -0
- package/lib/core/worker/node-worker.d.ts +19 -0
- package/lib/core/worker/node-worker.d.ts.map +1 -0
- package/lib/core/worker/node-worker.js +94 -0
- package/lib/core/worker/node-worker.js.map +1 -0
- package/lib/core/worker/task-runner-bun.d.ts +2 -0
- package/lib/core/worker/task-runner-bun.d.ts.map +1 -0
- package/lib/core/worker/task-runner-bun.js +18 -0
- package/lib/core/worker/task-runner-bun.js.map +1 -0
- package/lib/core/worker/task-runner.d.ts +2 -0
- package/lib/core/worker/task-runner.d.ts.map +1 -0
- package/lib/core/worker/task-runner.js +21 -0
- package/lib/core/worker/task-runner.js.map +1 -0
- package/lib/driver/index.d.ts +3 -0
- package/lib/driver/index.d.ts.map +1 -0
- package/lib/driver/index.js +16 -0
- package/lib/driver/index.js.map +1 -0
- package/lib/driver/interface.d.ts +39 -0
- package/lib/driver/interface.d.ts.map +1 -0
- package/lib/driver/interface.js +2 -0
- package/lib/driver/interface.js.map +1 -0
- package/lib/driver/mongodb/dml-translator.d.ts +21 -0
- package/lib/driver/mongodb/dml-translator.d.ts.map +1 -0
- package/lib/driver/mongodb/dml-translator.js +127 -0
- package/lib/driver/mongodb/dml-translator.js.map +1 -0
- package/lib/driver/mongodb/index.d.ts +27 -0
- package/lib/driver/mongodb/index.d.ts.map +1 -0
- package/lib/driver/mongodb/index.js +263 -0
- package/lib/driver/mongodb/index.js.map +1 -0
- package/lib/driver/mongodb/pool.d.ts +31 -0
- package/lib/driver/mongodb/pool.d.ts.map +1 -0
- package/lib/driver/mongodb/pool.js +96 -0
- package/lib/driver/mongodb/pool.js.map +1 -0
- package/lib/driver/mongodb/schema.d.ts +37 -0
- package/lib/driver/mongodb/schema.d.ts.map +1 -0
- package/lib/driver/mongodb/schema.js +238 -0
- package/lib/driver/mongodb/schema.js.map +1 -0
- package/lib/driver/mongodb/sql-translator.d.ts +19 -0
- package/lib/driver/mongodb/sql-translator.d.ts.map +1 -0
- package/lib/driver/mongodb/sql-translator.js +30 -0
- package/lib/driver/mongodb/sql-translator.js.map +1 -0
- package/lib/driver/mysql/index.d.ts +41 -0
- package/lib/driver/mysql/index.d.ts.map +1 -0
- package/lib/driver/mysql/index.js +338 -0
- package/lib/driver/mysql/index.js.map +1 -0
- package/lib/driver/mysql/pool.d.ts +46 -0
- package/lib/driver/mysql/pool.d.ts.map +1 -0
- package/lib/driver/mysql/pool.js +141 -0
- package/lib/driver/mysql/pool.js.map +1 -0
- package/lib/driver/mysql/version.d.ts +27 -0
- package/lib/driver/mysql/version.d.ts.map +1 -0
- package/lib/driver/mysql/version.js +77 -0
- package/lib/driver/mysql/version.js.map +1 -0
- package/lib/driver/postgresql/index.d.ts +34 -0
- package/lib/driver/postgresql/index.d.ts.map +1 -0
- package/lib/driver/postgresql/index.js +383 -0
- package/lib/driver/postgresql/index.js.map +1 -0
- package/lib/driver/postgresql/pool.d.ts +33 -0
- package/lib/driver/postgresql/pool.d.ts.map +1 -0
- package/lib/driver/postgresql/pool.js +104 -0
- package/lib/driver/postgresql/pool.js.map +1 -0
- package/lib/driver/registry.d.ts +16 -0
- package/lib/driver/registry.d.ts.map +1 -0
- package/lib/driver/registry.js +27 -0
- package/lib/driver/registry.js.map +1 -0
- package/lib/driver/sqlite/backend.d.ts +19 -0
- package/lib/driver/sqlite/backend.d.ts.map +1 -0
- package/lib/driver/sqlite/backend.js +5 -0
- package/lib/driver/sqlite/backend.js.map +1 -0
- package/lib/driver/sqlite/bun.d.ts +10 -0
- package/lib/driver/sqlite/bun.d.ts.map +1 -0
- package/lib/driver/sqlite/bun.js +36 -0
- package/lib/driver/sqlite/bun.js.map +1 -0
- package/lib/driver/sqlite/index.d.ts +49 -0
- package/lib/driver/sqlite/index.d.ts.map +1 -0
- package/lib/driver/sqlite/index.js +421 -0
- package/lib/driver/sqlite/index.js.map +1 -0
- package/lib/driver/sqlite/node.d.ts +10 -0
- package/lib/driver/sqlite/node.d.ts.map +1 -0
- package/lib/driver/sqlite/node.js +37 -0
- package/lib/driver/sqlite/node.js.map +1 -0
- package/lib/driver/sqlite/store.d.ts +13 -0
- package/lib/driver/sqlite/store.d.ts.map +1 -0
- package/lib/driver/sqlite/store.js +57 -0
- package/lib/driver/sqlite/store.js.map +1 -0
- package/lib/errors.d.ts +18 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +24 -0
- package/lib/errors.js.map +1 -0
- package/lib/facade/engine.d.ts +29 -0
- package/lib/facade/engine.d.ts.map +1 -0
- package/lib/facade/engine.js +107 -0
- package/lib/facade/engine.js.map +1 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +40 -0
- package/lib/index.js.map +1 -0
- package/lib/optional/static-source.d.ts +36 -0
- package/lib/optional/static-source.d.ts.map +1 -0
- package/lib/optional/static-source.js +141 -0
- package/lib/optional/static-source.js.map +1 -0
- package/lib/runtime.d.ts +12 -0
- package/lib/runtime.d.ts.map +1 -0
- package/lib/runtime.js +26 -0
- package/lib/runtime.js.map +1 -0
- package/lib/types/config.d.ts +146 -0
- package/lib/types/config.d.ts.map +1 -0
- package/lib/types/config.js +5 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/index.d.ts +7 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +7 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/manager.d.ts +37 -0
- package/lib/types/manager.d.ts.map +1 -0
- package/lib/types/manager.js +5 -0
- package/lib/types/manager.js.map +1 -0
- package/lib/types/queue.d.ts +45 -0
- package/lib/types/queue.d.ts.map +1 -0
- package/lib/types/queue.js +5 -0
- package/lib/types/queue.js.map +1 -0
- package/lib/types/result.d.ts +61 -0
- package/lib/types/result.d.ts.map +1 -0
- package/lib/types/result.js +16 -0
- package/lib/types/result.js.map +1 -0
- package/lib/types/schema.d.ts +51 -0
- package/lib/types/schema.d.ts.map +1 -0
- package/lib/types/schema.js +5 -0
- package/lib/types/schema.js.map +1 -0
- package/lib/types/task.d.ts +48 -0
- package/lib/types/task.d.ts.map +1 -0
- package/lib/types/task.js +136 -0
- package/lib/types/task.js.map +1 -0
- package/lib/types/transaction.d.ts +13 -0
- package/lib/types/transaction.d.ts.map +1 -0
- package/lib/types/transaction.js +2 -0
- package/lib/types/transaction.js.map +1 -0
- package/package.json +93 -0
- package/patches/bson@7.3.2.patch +105 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 任务队列:并发上限 / 优先级 / 超时 / 取消 / worker 多线程 offload
|
|
3
|
+
*/
|
|
4
|
+
import { SqlEngineError } from '../errors.js';
|
|
5
|
+
import { availableParallelism } from 'node:os';
|
|
6
|
+
import { createTask } from '../types/task.js';
|
|
7
|
+
import { createWorkerBackend } from './worker/index.js';
|
|
8
|
+
export class TaskQueueImpl {
|
|
9
|
+
options;
|
|
10
|
+
queue = [];
|
|
11
|
+
active = 0;
|
|
12
|
+
closed = false;
|
|
13
|
+
seq = 0;
|
|
14
|
+
idleWaiters = [];
|
|
15
|
+
workerBackend = null;
|
|
16
|
+
workerBackendPromise = null;
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
this.options = options;
|
|
19
|
+
}
|
|
20
|
+
/** 默认并发 = CPU 数 */
|
|
21
|
+
get concurrency() {
|
|
22
|
+
return this.options.concurrency ?? defaultConcurrency();
|
|
23
|
+
}
|
|
24
|
+
size() {
|
|
25
|
+
return this.queue.length + this.active;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 入队执行
|
|
29
|
+
* - 传函数:进程内异步执行(I/O 密集任务默认方式)
|
|
30
|
+
* - 传 WorkerTaskSpec + opts.worker=true:offload 到 worker 线程(CPU 密集任务)
|
|
31
|
+
*/
|
|
32
|
+
enqueue(fn, opts = {}) {
|
|
33
|
+
if (this.closed) {
|
|
34
|
+
return Promise.reject(new SqlEngineError('TASK_QUEUE_CLOSED', 'task queue has been closed'));
|
|
35
|
+
}
|
|
36
|
+
if (opts.worker && typeof fn === 'function') {
|
|
37
|
+
return Promise.reject(new SqlEngineError('WORKER_UNAVAILABLE', 'worker 任务必须是可序列化的 WorkerTaskSpec({ module, fn, args }),闭包无法跨线程执行'));
|
|
38
|
+
}
|
|
39
|
+
if (opts.signal?.aborted) {
|
|
40
|
+
return Promise.reject(new SqlEngineError('TASK_CANCELLED', 'task cancelled before run'));
|
|
41
|
+
}
|
|
42
|
+
const priority = opts.priority ?? 0;
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const item = {
|
|
45
|
+
id: ++this.seq,
|
|
46
|
+
fn: fn,
|
|
47
|
+
opts,
|
|
48
|
+
resolve: resolve,
|
|
49
|
+
reject,
|
|
50
|
+
priority,
|
|
51
|
+
};
|
|
52
|
+
// 按优先级降序插入(稳定排序:同优先级按入队顺序)
|
|
53
|
+
let lo = 0;
|
|
54
|
+
let hi = this.queue.length;
|
|
55
|
+
while (lo < hi) {
|
|
56
|
+
const mid = (lo + hi) >> 1;
|
|
57
|
+
if (this.queue[mid].priority < priority)
|
|
58
|
+
hi = mid;
|
|
59
|
+
else
|
|
60
|
+
lo = mid + 1;
|
|
61
|
+
}
|
|
62
|
+
this.queue.splice(lo, 0, item);
|
|
63
|
+
this.pump();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/** 长任务形态:支持进度上报与取消 */
|
|
67
|
+
introspect(runner) {
|
|
68
|
+
return createTask((ctx) => this.enqueue(() => runner(ctx), { signal: ctx.signal }));
|
|
69
|
+
}
|
|
70
|
+
waitIdle() {
|
|
71
|
+
if (this.active === 0 && this.queue.length === 0)
|
|
72
|
+
return Promise.resolve();
|
|
73
|
+
return new Promise((resolve) => {
|
|
74
|
+
this.idleWaiters.push(resolve);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
if (this.closed)
|
|
79
|
+
return;
|
|
80
|
+
this.closed = true;
|
|
81
|
+
// 拒绝所有排队任务
|
|
82
|
+
const pending = this.queue.splice(0);
|
|
83
|
+
for (const item of pending) {
|
|
84
|
+
item.reject(new SqlEngineError('TASK_QUEUE_CLOSED', 'task queue has been closed'));
|
|
85
|
+
}
|
|
86
|
+
await this.waitIdle();
|
|
87
|
+
if (this.workerBackend) {
|
|
88
|
+
await this.workerBackend.close();
|
|
89
|
+
this.workerBackend = null;
|
|
90
|
+
this.workerBackendPromise = null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
pump() {
|
|
94
|
+
while (this.active < this.concurrency && this.queue.length > 0 && !this.closed) {
|
|
95
|
+
const item = this.queue.shift();
|
|
96
|
+
this.active++;
|
|
97
|
+
void this.execute(item).finally(() => {
|
|
98
|
+
this.active--;
|
|
99
|
+
this.pump();
|
|
100
|
+
if (this.active === 0 && this.queue.length === 0) {
|
|
101
|
+
const waiters = this.idleWaiters.splice(0);
|
|
102
|
+
for (const w of waiters)
|
|
103
|
+
w();
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async execute(item) {
|
|
109
|
+
const { opts } = item;
|
|
110
|
+
if (opts?.signal?.aborted) {
|
|
111
|
+
item.reject(new SqlEngineError('TASK_CANCELLED', 'task cancelled'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
// 排队期间被取消(signal 触发)
|
|
115
|
+
const abortHandler = () => {
|
|
116
|
+
item.reject(new SqlEngineError('TASK_CANCELLED', 'task cancelled'));
|
|
117
|
+
};
|
|
118
|
+
opts?.signal?.addEventListener('abort', abortHandler, { once: true });
|
|
119
|
+
try {
|
|
120
|
+
const exec = opts?.worker
|
|
121
|
+
? this.runInWorker(item.fn)
|
|
122
|
+
: Promise.resolve().then(() => item.fn());
|
|
123
|
+
const timeoutMs = opts?.timeoutMs ?? this.options.timeoutMs;
|
|
124
|
+
const result = await withTimeout(exec, timeoutMs, item.id);
|
|
125
|
+
item.resolve(result);
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
item.reject(err);
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
opts?.signal?.removeEventListener('abort', abortHandler);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
runInWorker(spec) {
|
|
135
|
+
return this.getWorkerBackend().then((backend) => backend.run(spec));
|
|
136
|
+
}
|
|
137
|
+
getWorkerBackend() {
|
|
138
|
+
if (this.options.useWorkers === false) {
|
|
139
|
+
return Promise.reject(new SqlEngineError('WORKER_UNAVAILABLE', 'worker 已被禁用(useWorkers: false)'));
|
|
140
|
+
}
|
|
141
|
+
if (!this.workerBackend) {
|
|
142
|
+
this.workerBackendPromise ??= Promise.resolve().then(() => createWorkerBackend({ workerCount: this.options.workerCount }));
|
|
143
|
+
this.workerBackendPromise
|
|
144
|
+
.then((backend) => {
|
|
145
|
+
this.workerBackend = backend;
|
|
146
|
+
})
|
|
147
|
+
.catch(() => {
|
|
148
|
+
this.workerBackendPromise = null;
|
|
149
|
+
});
|
|
150
|
+
return this.workerBackendPromise;
|
|
151
|
+
}
|
|
152
|
+
return Promise.resolve(this.workerBackend);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function defaultConcurrency() {
|
|
156
|
+
if (typeof globalThis !== 'undefined' && 'navigator' in globalThis) {
|
|
157
|
+
const nav = globalThis.navigator;
|
|
158
|
+
const hw = nav?.hardwareConcurrency;
|
|
159
|
+
if (typeof hw === 'number' && hw > 0)
|
|
160
|
+
return hw;
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
return Math.max(1, availableParallelism?.() ?? 4);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return 4;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function withTimeout(promise, timeoutMs, id) {
|
|
170
|
+
if (!timeoutMs || timeoutMs <= 0)
|
|
171
|
+
return promise;
|
|
172
|
+
return new Promise((resolve, reject) => {
|
|
173
|
+
const timer = setTimeout(() => {
|
|
174
|
+
reject(new SqlEngineError('QUERY_FAILED', `task #${id} timed out after ${timeoutMs}ms`));
|
|
175
|
+
}, timeoutMs);
|
|
176
|
+
promise.then((v) => {
|
|
177
|
+
clearTimeout(timer);
|
|
178
|
+
resolve(v);
|
|
179
|
+
}, (e) => {
|
|
180
|
+
clearTimeout(timer);
|
|
181
|
+
reject(e);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=task-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-queue.js","sourceRoot":"","sources":["../../src/core/task-queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worker 线程池(Bun Worker 实现)
|
|
3
|
+
* bun 的 Worker 是全局 web-worker 风格构造器:new Worker(url, {type:'module'})
|
|
4
|
+
* 消息事件:addEventListener('message', e => e.data)
|
|
5
|
+
*/
|
|
6
|
+
import type { WorkerTaskSpec } from '../../types/queue.js';
|
|
7
|
+
import type { WorkerBackend } from './node-worker.js';
|
|
8
|
+
export declare class BunWorkerPool implements WorkerBackend {
|
|
9
|
+
private count;
|
|
10
|
+
private workers;
|
|
11
|
+
private pending;
|
|
12
|
+
private seq;
|
|
13
|
+
private closed;
|
|
14
|
+
constructor(count: number);
|
|
15
|
+
get size(): number;
|
|
16
|
+
private get WorkerCtor();
|
|
17
|
+
private spawn;
|
|
18
|
+
run<T>(spec: WorkerTaskSpec): Promise<T>;
|
|
19
|
+
close(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=bun-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-worker.d.ts","sourceRoot":"","sources":["../../../src/core/worker/bun-worker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAkBtD,qBAAa,aAAc,YAAW,aAAa;IAMrC,OAAO,CAAC,KAAK;IALzB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,MAAM,CAAS;gBAEH,KAAK,EAAE,MAAM;IAEjC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,OAAO,KAAK,UAAU,GAQrB;IAED,OAAO,CAAC,KAAK;IAuBb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAyClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const RUNNER_URL = new URL(`./task-runner-bun${import.meta.url.endsWith('.ts') ? '.ts' : '.js'}`, import.meta.url);
|
|
2
|
+
export class BunWorkerPool {
|
|
3
|
+
count;
|
|
4
|
+
workers = [];
|
|
5
|
+
pending = [];
|
|
6
|
+
seq = 0;
|
|
7
|
+
closed = false;
|
|
8
|
+
constructor(count) {
|
|
9
|
+
this.count = count;
|
|
10
|
+
}
|
|
11
|
+
get size() {
|
|
12
|
+
return this.workers.length;
|
|
13
|
+
}
|
|
14
|
+
get WorkerCtor() {
|
|
15
|
+
const ctor = globalThis.Worker;
|
|
16
|
+
if (typeof ctor !== 'function') {
|
|
17
|
+
throw new Error('当前运行时无 Worker 全局构造器(需要 Bun ≥ 1.1)');
|
|
18
|
+
}
|
|
19
|
+
return ctor;
|
|
20
|
+
}
|
|
21
|
+
spawn(index) {
|
|
22
|
+
const worker = new this.WorkerCtor(RUNNER_URL, { type: 'module' });
|
|
23
|
+
worker.addEventListener('message', (e) => {
|
|
24
|
+
const msg = e.data;
|
|
25
|
+
const task = this.pending[index];
|
|
26
|
+
this.pending[index] = undefined;
|
|
27
|
+
if (!task)
|
|
28
|
+
return;
|
|
29
|
+
if (msg.ok)
|
|
30
|
+
task.resolve(msg.result);
|
|
31
|
+
else
|
|
32
|
+
task.reject(new Error(msg.error ?? 'bun worker task failed'));
|
|
33
|
+
});
|
|
34
|
+
worker.addEventListener('error', (err) => {
|
|
35
|
+
const task = this.pending[index];
|
|
36
|
+
this.pending[index] = undefined;
|
|
37
|
+
if (task) {
|
|
38
|
+
const e = err?.message ? new Error(String(err.message)) : new Error('bun worker error');
|
|
39
|
+
task.reject(e);
|
|
40
|
+
}
|
|
41
|
+
this.workers[index] = undefined;
|
|
42
|
+
});
|
|
43
|
+
this.workers[index] = worker;
|
|
44
|
+
return worker;
|
|
45
|
+
}
|
|
46
|
+
run(spec) {
|
|
47
|
+
if (this.closed)
|
|
48
|
+
return Promise.reject(new Error('worker pool closed'));
|
|
49
|
+
// 找空闲 worker
|
|
50
|
+
let index = -1;
|
|
51
|
+
for (let i = 0; i < this.workers.length; i++) {
|
|
52
|
+
if (!this.pending[i]) {
|
|
53
|
+
index = i;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (index === -1) {
|
|
58
|
+
if (this.workers.length >= this.count) {
|
|
59
|
+
// 池满:等一个空闲
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const timer = setInterval(() => {
|
|
62
|
+
if (this.closed) {
|
|
63
|
+
clearInterval(timer);
|
|
64
|
+
reject(new Error('worker pool closed'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
for (let i = 0; i < this.workers.length; i++) {
|
|
68
|
+
if (!this.pending[i]) {
|
|
69
|
+
clearInterval(timer);
|
|
70
|
+
this.run(spec).then(resolve, reject);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}, 1);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
index = this.workers.length;
|
|
78
|
+
this.spawn(index);
|
|
79
|
+
}
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
this.pending[index] = { resolve: resolve, reject };
|
|
82
|
+
this.workers[index].postMessage({ id: ++this.seq, ...spec });
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async close() {
|
|
86
|
+
this.closed = true;
|
|
87
|
+
const workers = this.workers;
|
|
88
|
+
this.workers = [];
|
|
89
|
+
this.pending = [];
|
|
90
|
+
workers.forEach((w) => w.terminate?.());
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=bun-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-worker.js","sourceRoot":"","sources":["../../../src/core/worker/bun-worker.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,GAAG,IAAI,GAAG,CACxB,oBAAoB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EACrE,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CAAC;AAaF,MAAM,OAAO,aAAa;IAMJ;IALZ,OAAO,GAAoB,EAAE,CAAC;IAC9B,OAAO,GAAgC,EAAE,CAAC;IAC1C,GAAG,GAAG,CAAC,CAAC;IACR,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAoB,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAErC,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED,IAAY,UAAU;QACpB,MAAM,IAAI,GAAI,UAAkB,CAAC,MAEpB,CAAC;QACd,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,KAAa;QACzB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnE,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAM,EAAE,EAAE;YAC5C,MAAM,GAAG,GAAG,CAAC,CAAC,IAAyD,CAAC;YACxE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;YAChC,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,GAAG,CAAC,EAAE;gBAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;;gBAChC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAQ,EAAE,EAAE;YAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;YAChC,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBACxF,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAqC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,GAAG,CAAI,IAAoB;QACzB,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QAExE,aAAa;QACb,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;QACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gBACrB,KAAK,GAAG,CAAC,CAAC;gBACV,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtC,WAAW;gBACX,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBACxC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;wBAC7B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;4BAChB,aAAa,CAAC,KAAK,CAAC,CAAC;4BACrB,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;4BACxC,OAAO;wBACT,CAAC;wBACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC7C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;gCACrB,aAAa,CAAC,KAAK,CAAC,CAAC;gCACrB,IAAI,CAAC,GAAG,CAAI,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gCACxC,OAAO;4BACT,CAAC;wBACH,CAAC;oBACH,CAAC,EAAE,CAAC,CAAC,CAAC;gBACR,CAAC,CAAC,CAAC;YACL,CAAC;YACD,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QAED,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,IAAI,CAAC,OAAO,CAAC,KAAM,CAAC,GAAG,EAAE,OAAO,EAAE,OAA+B,EAAE,MAAM,EAAE,CAAC;YAC5E,IAAI,CAAC,OAAO,CAAC,KAAM,CAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QAClB,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worker 后端选择:按运行时创建
|
|
3
|
+
*/
|
|
4
|
+
import { type RuntimeName } from '../../runtime.js';
|
|
5
|
+
import type { WorkerTaskSpec } from '../../types/queue.js';
|
|
6
|
+
import { type WorkerBackend } from './node-worker.js';
|
|
7
|
+
export type { WorkerBackend } from './node-worker.js';
|
|
8
|
+
export interface WorkerPoolOptions {
|
|
9
|
+
/** worker 线程数,默认 min(4, cpu) */
|
|
10
|
+
workerCount?: number;
|
|
11
|
+
runtime?: RuntimeName;
|
|
12
|
+
}
|
|
13
|
+
/** 创建 worker 后端(Node worker_threads / Bun Worker) */
|
|
14
|
+
export declare function createWorkerBackend(options?: WorkerPoolOptions): WorkerBackend;
|
|
15
|
+
export type { WorkerTaskSpec };
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/worker/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AAED,qDAAqD;AACrD,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,iBAAsB,GAAG,aAAa,CAOlF;AAED,YAAY,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worker 后端选择:按运行时创建
|
|
3
|
+
*/
|
|
4
|
+
import { detectRuntime } from '../../runtime.js';
|
|
5
|
+
import { NodeWorkerPool } from './node-worker.js';
|
|
6
|
+
import { BunWorkerPool } from './bun-worker.js';
|
|
7
|
+
/** 创建 worker 后端(Node worker_threads / Bun Worker) */
|
|
8
|
+
export function createWorkerBackend(options = {}) {
|
|
9
|
+
const runtime = options.runtime ?? detectRuntime();
|
|
10
|
+
const count = Math.max(1, Math.min(options.workerCount ?? 4, 32));
|
|
11
|
+
if (runtime === 'bun') {
|
|
12
|
+
return new BunWorkerPool(count);
|
|
13
|
+
}
|
|
14
|
+
return new NodeWorkerPool(count);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/worker/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,aAAa,EAAoB,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAsB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAUhD,qDAAqD;AACrD,MAAM,UAAU,mBAAmB,CAAC,UAA6B,EAAE;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACtB,OAAO,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { WorkerTaskSpec } from '../../types/queue.js';
|
|
2
|
+
export interface WorkerBackend {
|
|
3
|
+
readonly size: number;
|
|
4
|
+
run<T>(spec: WorkerTaskSpec): Promise<T>;
|
|
5
|
+
close(): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare class NodeWorkerPool implements WorkerBackend {
|
|
8
|
+
private count;
|
|
9
|
+
private workers;
|
|
10
|
+
private pending;
|
|
11
|
+
private seq;
|
|
12
|
+
private closed;
|
|
13
|
+
constructor(count: number);
|
|
14
|
+
get size(): number;
|
|
15
|
+
private spawn;
|
|
16
|
+
run<T>(spec: WorkerTaskSpec): Promise<T>;
|
|
17
|
+
close(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=node-worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-worker.d.ts","sourceRoot":"","sources":["../../../src/core/worker/node-worker.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAYD,qBAAa,cAAe,YAAW,aAAa;IAMtC,OAAO,CAAC,KAAK;IALzB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,MAAM,CAAS;gBAEH,KAAK,EAAE,MAAM;IAEjC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,OAAO,CAAC,KAAK;IAoBb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IA6ClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS7B"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worker 线程池(Node worker_threads 实现)
|
|
3
|
+
* 固定数量 worker,每个 worker 同一时刻只处理一个任务,结果经 postMessage 回传
|
|
4
|
+
*/
|
|
5
|
+
import { Worker } from 'node:worker_threads';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
const RUNNER_URL = new URL(`./task-runner${import.meta.url.endsWith('.ts') ? '.ts' : '.js'}`, import.meta.url);
|
|
8
|
+
export class NodeWorkerPool {
|
|
9
|
+
count;
|
|
10
|
+
workers = [];
|
|
11
|
+
pending = [];
|
|
12
|
+
seq = 0;
|
|
13
|
+
closed = false;
|
|
14
|
+
constructor(count) {
|
|
15
|
+
this.count = count;
|
|
16
|
+
}
|
|
17
|
+
get size() {
|
|
18
|
+
return this.workers.length;
|
|
19
|
+
}
|
|
20
|
+
spawn(index) {
|
|
21
|
+
const worker = new Worker(fileURLToPath(RUNNER_URL));
|
|
22
|
+
worker.on('message', (msg) => {
|
|
23
|
+
const task = this.pending[index];
|
|
24
|
+
this.pending[index] = undefined;
|
|
25
|
+
if (!task)
|
|
26
|
+
return;
|
|
27
|
+
if (msg.ok)
|
|
28
|
+
task.resolve(msg.result);
|
|
29
|
+
else
|
|
30
|
+
task.reject(new Error(msg.error ?? 'worker task failed'));
|
|
31
|
+
});
|
|
32
|
+
worker.on('error', (err) => {
|
|
33
|
+
const task = this.pending[index];
|
|
34
|
+
this.pending[index] = undefined;
|
|
35
|
+
if (task)
|
|
36
|
+
task.reject(err);
|
|
37
|
+
// 崩溃的 worker 移除,下次 run 时重建
|
|
38
|
+
this.workers[index] = undefined;
|
|
39
|
+
});
|
|
40
|
+
this.workers[index] = worker;
|
|
41
|
+
return worker;
|
|
42
|
+
}
|
|
43
|
+
run(spec) {
|
|
44
|
+
if (this.closed) {
|
|
45
|
+
return Promise.reject(new Error('worker pool closed'));
|
|
46
|
+
}
|
|
47
|
+
// 找空闲 worker(无 pending 任务)
|
|
48
|
+
let index = -1;
|
|
49
|
+
for (let i = 0; i < this.workers.length; i++) {
|
|
50
|
+
if (!this.pending[i]) {
|
|
51
|
+
index = i;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (index === -1) {
|
|
56
|
+
if (this.workers.length >= this.count) {
|
|
57
|
+
// 池满:等一个空闲(简单轮询等待——用 setTimeout 退避)
|
|
58
|
+
return new Promise((resolve, reject) => {
|
|
59
|
+
const tryRun = () => {
|
|
60
|
+
this.run(spec).then(resolve, reject);
|
|
61
|
+
};
|
|
62
|
+
const timer = setInterval(() => {
|
|
63
|
+
if (this.closed) {
|
|
64
|
+
clearInterval(timer);
|
|
65
|
+
reject(new Error('worker pool closed'));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
for (let i = 0; i < this.workers.length; i++) {
|
|
69
|
+
if (!this.pending[i]) {
|
|
70
|
+
clearInterval(timer);
|
|
71
|
+
tryRun();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}, 1);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
index = this.workers.length;
|
|
79
|
+
this.spawn(index);
|
|
80
|
+
}
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
this.pending[index] = { resolve: resolve, reject };
|
|
83
|
+
this.workers[index].postMessage({ id: ++this.seq, ...spec });
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async close() {
|
|
87
|
+
this.closed = true;
|
|
88
|
+
const workers = this.workers;
|
|
89
|
+
this.workers = [];
|
|
90
|
+
this.pending = [];
|
|
91
|
+
await Promise.all(workers.map((w) => (w ? w.terminate().catch(() => undefined) : Promise.resolve())));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=node-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-worker.js","sourceRoot":"","sources":["../../../src/core/worker/node-worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-runner-bun.d.ts","sourceRoot":"","sources":["../../../src/core/worker/task-runner-bun.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
self.onmessage = async (e) => {
|
|
2
|
+
const msg = e.data;
|
|
3
|
+
try {
|
|
4
|
+
const mod = await import(msg.module);
|
|
5
|
+
const fn = mod[msg.fn];
|
|
6
|
+
if (typeof fn !== 'function') {
|
|
7
|
+
throw new Error(`module "${msg.module}" 未导出函数 "${msg.fn}"`);
|
|
8
|
+
}
|
|
9
|
+
const result = await fn(...(msg.args ?? []));
|
|
10
|
+
self.postMessage({ ok: true, result });
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
const e2 = err;
|
|
14
|
+
self.postMessage({ ok: false, error: e2?.stack || String(err) });
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=task-runner-bun.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-runner-bun.js","sourceRoot":"","sources":["../../../src/core/worker/task-runner-bun.ts"],"names":[],"mappings":"AAcA,IAAI,CAAC,SAAS,GAAG,KAAK,EAAE,CAA0B,EAAE,EAAE;IACpD,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,EAAE,GAAI,GAA+B,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpD,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,MAAM,GAAG,MAAO,EAAsC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAClF,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,GAAG,GAAY,CAAC;QACxB,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-runner.d.ts","sourceRoot":"","sources":["../../../src/core/worker/task-runner.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* worker 线程执行入口(Node worker_threads 侧)
|
|
3
|
+
* 收到 { module, fn, args } → 动态 import 模块 → 调用导出函数 → 回传结果
|
|
4
|
+
*/
|
|
5
|
+
import { parentPort } from 'node:worker_threads';
|
|
6
|
+
parentPort?.on('message', async (msg) => {
|
|
7
|
+
try {
|
|
8
|
+
const mod = await import(msg.module);
|
|
9
|
+
const fn = mod[msg.fn];
|
|
10
|
+
if (typeof fn !== 'function') {
|
|
11
|
+
throw new Error(`module "${msg.module}" 未导出函数 "${msg.fn}"`);
|
|
12
|
+
}
|
|
13
|
+
const result = await fn(...(msg.args ?? []));
|
|
14
|
+
parentPort?.postMessage({ ok: true, result });
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
const e = err;
|
|
18
|
+
parentPort?.postMessage({ ok: false, error: e?.stack || String(err) });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=task-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-runner.js","sourceRoot":"","sources":["../../../src/core/worker/task-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAQjD,UAAU,EAAE,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,GAAkB,EAAE,EAAE;IACrD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,EAAE,GAAI,GAA+B,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpD,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,MAAM,GAAG,MAAO,EAAsC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;QAClF,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,GAAY,CAAC;QACvB,UAAU,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACzE,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/driver/index.ts"],"names":[],"mappings":"AAeA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 驱动注册入口:内置方言在此注册
|
|
3
|
+
*/
|
|
4
|
+
import { registerDriver } from './registry.js';
|
|
5
|
+
import { sqliteDriver } from './sqlite/index.js';
|
|
6
|
+
import { mysqlDriver, mariadbDriver } from './mysql/index.js';
|
|
7
|
+
import { postgresqlDriver } from './postgresql/index.js';
|
|
8
|
+
import { mongodbDriver } from './mongodb/index.js';
|
|
9
|
+
registerDriver(sqliteDriver);
|
|
10
|
+
registerDriver(mysqlDriver);
|
|
11
|
+
registerDriver(mariadbDriver);
|
|
12
|
+
registerDriver(postgresqlDriver);
|
|
13
|
+
registerDriver(mongodbDriver);
|
|
14
|
+
export * from './registry.js';
|
|
15
|
+
export * from './interface.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/driver/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,cAAc,CAAC,YAAY,CAAC,CAAC;AAC7B,cAAc,CAAC,WAAW,CAAC,CAAC;AAC5B,cAAc,CAAC,aAAa,CAAC,CAAC;AAC9B,cAAc,CAAC,gBAAgB,CAAC,CAAC;AACjC,cAAc,CAAC,aAAa,CAAC,CAAC;AAE9B,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 驱动接口:各数据库方言适配器的统一契约
|
|
3
|
+
* 连接池由 PoolHandle 持有(由 client/registry 统一管理生命周期),
|
|
4
|
+
* driver 方法只接收已绑定 config 的 handle,不做重复缓存
|
|
5
|
+
*/
|
|
6
|
+
import type { ConnectionConfig, SchemaOptions } from '../types/config.js';
|
|
7
|
+
import type { ExecResult, Field, RunSqlRequest, TestResult } from '../types/result.js';
|
|
8
|
+
import type { TableSchema } from '../types/schema.js';
|
|
9
|
+
import type { IntrospectTask } from '../types/task.js';
|
|
10
|
+
import type { TransactionHandle } from '../types/transaction.js';
|
|
11
|
+
import type { PoolStats } from '../types/manager.js';
|
|
12
|
+
/** 连接池句柄(registry 生命周期管理单元) */
|
|
13
|
+
export interface PoolHandle {
|
|
14
|
+
readonly fingerprint: string;
|
|
15
|
+
readonly config: ConnectionConfig;
|
|
16
|
+
readonly stats: PoolStats;
|
|
17
|
+
/** 已销毁标记(invalidate/destroy 后为 true) */
|
|
18
|
+
readonly destroyed: boolean;
|
|
19
|
+
ping(): Promise<void>;
|
|
20
|
+
destroy(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export interface SqlDriver {
|
|
23
|
+
readonly dialect: string;
|
|
24
|
+
/** 创建连接池(纯工厂,registry 负责缓存与销毁) */
|
|
25
|
+
createPool(config: ConnectionConfig): Promise<PoolHandle>;
|
|
26
|
+
/** 连接测试:一次性连接,不入池 */
|
|
27
|
+
testConnection(config: ConnectionConfig): Promise<TestResult>;
|
|
28
|
+
runSql(pool: PoolHandle, request: RunSqlRequest): Promise<ExecResult>;
|
|
29
|
+
getTableList(pool: PoolHandle): Promise<string[]>;
|
|
30
|
+
getTableDDL?(pool: PoolHandle, table: string): Promise<string>;
|
|
31
|
+
getPreviewRows(pool: PoolHandle, table: string, offset: number, limit: number, whereClause?: string): Promise<any[]>;
|
|
32
|
+
getColumns(pool: PoolHandle, table: string): Promise<Field[]>;
|
|
33
|
+
getRowsCount(pool: PoolHandle, table: string, whereClause?: string): Promise<number>;
|
|
34
|
+
getTableSchema(pool: PoolHandle, table: string, opts?: SchemaOptions): Promise<TableSchema>;
|
|
35
|
+
getAllTableSchemas?(pool: PoolHandle, opts?: SchemaOptions): IntrospectTask<TableSchema[]>;
|
|
36
|
+
/** 事务:fn 内所有查询在同一事务/连接内执行;fn 抛错自动回滚 */
|
|
37
|
+
withTransaction?<T>(pool: PoolHandle, fn: (tx: TransactionHandle) => Promise<T>): Promise<T>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/driver/interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,kCAAkC;IAClC,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE1D,qBAAqB;IACrB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE9D,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEtE,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClD,WAAW,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D,cAAc,CACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAClB,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9D,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrF,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5F,kBAAkB,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3F,uCAAuC;IACvC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/driver/interface.ts"],"names":[],"mappings":""}
|