weifuwu 0.91.0 → 0.93.0
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 +1 -1
- package/dist/client/components/index.d.ts +3 -0
- package/dist/client/components/style.css +1 -12219
- package/dist/client/layout/bundle.d.ts +42 -0
- package/dist/client/layout/weifuwu-layout.css +1 -1495
- package/dist/client/vdom/core/protocol.d.ts +62 -7
- package/dist/client/vdom/index.js +3 -3
- package/dist/server/db/http.d.ts +4 -4
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +295 -174
- package/dist/server/response.d.ts +17 -0
- package/docs/client.md +128 -7
- package/docs/layout.md +243 -0
- package/docs/server.md +229 -9
- package/package.json +5 -3
package/dist/server/index.js
CHANGED
|
@@ -270,8 +270,8 @@ async function sendResponse(res, response, opts) {
|
|
|
270
270
|
res.writeHead(response.status, response.statusText, headers);
|
|
271
271
|
if (response.body) {
|
|
272
272
|
const reader = response.body.getReader();
|
|
273
|
-
const closed = new Promise((
|
|
274
|
-
res.once("close", () =>
|
|
273
|
+
const closed = new Promise((resolve4) => {
|
|
274
|
+
res.once("close", () => resolve4("closed"));
|
|
275
275
|
});
|
|
276
276
|
res.on("error", () => {
|
|
277
277
|
});
|
|
@@ -291,7 +291,7 @@ async function sendResponse(res, response, opts) {
|
|
|
291
291
|
if (done) break;
|
|
292
292
|
if (!res.write(value)) {
|
|
293
293
|
const drained = new Promise(
|
|
294
|
-
(
|
|
294
|
+
(resolve4) => res.once("drain", () => resolve4("drain"))
|
|
295
295
|
);
|
|
296
296
|
if (await Promise.race([drained, closed]) === "closed") {
|
|
297
297
|
await cancelStream();
|
|
@@ -457,6 +457,101 @@ function serve(router, options) {
|
|
|
457
457
|
// src/server/core/router.ts
|
|
458
458
|
import { WebSocketServer } from "ws";
|
|
459
459
|
|
|
460
|
+
// src/server/db/errors.ts
|
|
461
|
+
var DbError = class extends Error {
|
|
462
|
+
kind;
|
|
463
|
+
code;
|
|
464
|
+
cause;
|
|
465
|
+
constructor(kind, message, options) {
|
|
466
|
+
super(message);
|
|
467
|
+
this.name = "DbError";
|
|
468
|
+
this.kind = kind;
|
|
469
|
+
this.code = options?.code;
|
|
470
|
+
this.cause = options?.cause;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
var ProtocolError = class extends DbError {
|
|
474
|
+
constructor(feature, message) {
|
|
475
|
+
super("protocol", message ?? `${feature} is not supported by weifuwu/db`, { code: "UNSUPPORTED" });
|
|
476
|
+
this.name = "ProtocolError";
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
var ConnectionError = class extends DbError {
|
|
480
|
+
attempts;
|
|
481
|
+
constructor(message, attempts = 1, cause) {
|
|
482
|
+
super("connection", message, { cause });
|
|
483
|
+
this.name = "ConnectionError";
|
|
484
|
+
this.attempts = attempts;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
var TimeoutError = class extends DbError {
|
|
488
|
+
operation;
|
|
489
|
+
ms;
|
|
490
|
+
constructor(operation, ms) {
|
|
491
|
+
super("timeout", `${operation} timed out after ${ms}ms`);
|
|
492
|
+
this.name = "TimeoutError";
|
|
493
|
+
this.operation = operation;
|
|
494
|
+
this.ms = ms;
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
var ValidationError = class extends DbError {
|
|
498
|
+
constructor(message) {
|
|
499
|
+
super("validation", message);
|
|
500
|
+
this.name = "ValidationError";
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// src/server/response.ts
|
|
505
|
+
function ok(data, init) {
|
|
506
|
+
return Response.json(data, { status: 200, ...init });
|
|
507
|
+
}
|
|
508
|
+
function created(data, init) {
|
|
509
|
+
return Response.json(data, { status: 201, ...init });
|
|
510
|
+
}
|
|
511
|
+
function noContent(init) {
|
|
512
|
+
return new Response(null, { status: 204, ...init });
|
|
513
|
+
}
|
|
514
|
+
function badRequest(message) {
|
|
515
|
+
return Response.json({ error: message ?? "Bad Request" }, { status: 400 });
|
|
516
|
+
}
|
|
517
|
+
function unauthorized(message) {
|
|
518
|
+
return Response.json({ error: message ?? "Unauthorized" }, { status: 401 });
|
|
519
|
+
}
|
|
520
|
+
function forbidden(message) {
|
|
521
|
+
return Response.json({ error: message ?? "Forbidden" }, { status: 403 });
|
|
522
|
+
}
|
|
523
|
+
function notFound(message) {
|
|
524
|
+
return Response.json({ error: message ?? "Not Found" }, { status: 404 });
|
|
525
|
+
}
|
|
526
|
+
function conflict(message) {
|
|
527
|
+
return Response.json({ error: message ?? "Conflict" }, { status: 409 });
|
|
528
|
+
}
|
|
529
|
+
function unprocessable(message) {
|
|
530
|
+
return Response.json({ error: message ?? "Unprocessable Entity" }, { status: 422 });
|
|
531
|
+
}
|
|
532
|
+
function tooManyRequests(message) {
|
|
533
|
+
return Response.json({ error: message ?? "Too Many Requests" }, { status: 429 });
|
|
534
|
+
}
|
|
535
|
+
function serverError(message) {
|
|
536
|
+
return Response.json({ error: message ?? "Internal Server Error" }, { status: 500 });
|
|
537
|
+
}
|
|
538
|
+
function redirect(url, status = 302) {
|
|
539
|
+
return new Response(null, { status, headers: { Location: url } });
|
|
540
|
+
}
|
|
541
|
+
function errorResponse(e, status) {
|
|
542
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
543
|
+
let code;
|
|
544
|
+
if (e instanceof HttpError) {
|
|
545
|
+
return Response.json({ error: msg }, { status: status ?? e.status });
|
|
546
|
+
}
|
|
547
|
+
if (e instanceof DbError) {
|
|
548
|
+
const st = status ?? (e.code === "23505" ? 409 : 400);
|
|
549
|
+
code = e.code === "23505" ? "conflict" : e.kind;
|
|
550
|
+
return Response.json({ error: msg, code }, { status: st });
|
|
551
|
+
}
|
|
552
|
+
return Response.json({ error: msg }, { status: status ?? 400 });
|
|
553
|
+
}
|
|
554
|
+
|
|
460
555
|
// src/server/core/ws.ts
|
|
461
556
|
function safeHook(hookName, fn, onError) {
|
|
462
557
|
if (!fn) return () => {
|
|
@@ -995,12 +1090,12 @@ async function runChain(mws, finalHandler, req, ctx) {
|
|
|
995
1090
|
}
|
|
996
1091
|
|
|
997
1092
|
// src/shared/router/pipeline.ts
|
|
998
|
-
function
|
|
1093
|
+
function badRequest2(reason) {
|
|
999
1094
|
return Response.json({ error: "Bad Request", reason }, { status: 400 });
|
|
1000
1095
|
}
|
|
1001
1096
|
async function dispatchRouter(root, pipeline, req, ctx) {
|
|
1002
1097
|
const target = parseRequestTarget(req);
|
|
1003
|
-
if (!target.ok) return
|
|
1098
|
+
if (!target.ok) return badRequest2(target.reason);
|
|
1004
1099
|
const m = trieMatch(root, target.segments);
|
|
1005
1100
|
const match = m ? { value: m.value, params: freshParams(m), wildcard: m.wildcard } : null;
|
|
1006
1101
|
pipeline.enrichCtx?.(ctx, match, target.pathname, target.query);
|
|
@@ -1356,11 +1451,8 @@ var Router = class _Router {
|
|
|
1356
1451
|
async handleError(e, req, ctx, path) {
|
|
1357
1452
|
const err = e instanceof Error ? e : new Error(String(e));
|
|
1358
1453
|
if (this.errorHandler) return this.errorHandler(err, req, ctx);
|
|
1359
|
-
if (err instanceof HttpError) {
|
|
1360
|
-
return
|
|
1361
|
-
status: err.status,
|
|
1362
|
-
headers: { "Content-Type": "application/json" }
|
|
1363
|
-
});
|
|
1454
|
+
if (err instanceof HttpError || err instanceof DbError || err instanceof ValidationError) {
|
|
1455
|
+
return errorResponse(err);
|
|
1364
1456
|
}
|
|
1365
1457
|
noteHandlerError(`${req.method} ${path ?? new URL(req.url).pathname}`, e);
|
|
1366
1458
|
return Response.json({ error: "Internal Server Error" }, { status: 500 });
|
|
@@ -1394,15 +1486,15 @@ var Router = class _Router {
|
|
|
1394
1486
|
} catch {
|
|
1395
1487
|
}
|
|
1396
1488
|
}
|
|
1397
|
-
await new Promise((
|
|
1489
|
+
await new Promise((resolve4) => {
|
|
1398
1490
|
let remaining = clients.length;
|
|
1399
1491
|
const done = () => {
|
|
1400
1492
|
if (--remaining === 0) {
|
|
1401
1493
|
clearTimeout(timer);
|
|
1402
|
-
|
|
1494
|
+
resolve4();
|
|
1403
1495
|
}
|
|
1404
1496
|
};
|
|
1405
|
-
const timer = setTimeout(
|
|
1497
|
+
const timer = setTimeout(resolve4, 500);
|
|
1406
1498
|
for (const c of clients) c.once("close", done);
|
|
1407
1499
|
});
|
|
1408
1500
|
}
|
|
@@ -1920,7 +2012,7 @@ async function MemoryEmailServer(options = {}) {
|
|
|
1920
2012
|
res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
|
|
1921
2013
|
});
|
|
1922
2014
|
});
|
|
1923
|
-
await new Promise((
|
|
2015
|
+
await new Promise((resolve4) => server.listen(options.port ?? 0, "127.0.0.1", resolve4));
|
|
1924
2016
|
const port = server.address().port;
|
|
1925
2017
|
return {
|
|
1926
2018
|
port,
|
|
@@ -1928,7 +2020,7 @@ async function MemoryEmailServer(options = {}) {
|
|
|
1928
2020
|
emails,
|
|
1929
2021
|
requests,
|
|
1930
2022
|
closeAllConnections: () => server.closeAllConnections(),
|
|
1931
|
-
close: () => new Promise((
|
|
2023
|
+
close: () => new Promise((resolve4, reject) => server.close((e) => e ? reject(e) : resolve4()))
|
|
1932
2024
|
};
|
|
1933
2025
|
}
|
|
1934
2026
|
|
|
@@ -2521,44 +2613,6 @@ function hashRefreshToken(token) {
|
|
|
2521
2613
|
return createHash("sha256").update(token).digest("hex");
|
|
2522
2614
|
}
|
|
2523
2615
|
|
|
2524
|
-
// src/server/response.ts
|
|
2525
|
-
function ok(data, init) {
|
|
2526
|
-
return Response.json(data, { status: 200, ...init });
|
|
2527
|
-
}
|
|
2528
|
-
function created(data, init) {
|
|
2529
|
-
return Response.json(data, { status: 201, ...init });
|
|
2530
|
-
}
|
|
2531
|
-
function noContent(init) {
|
|
2532
|
-
return new Response(null, { status: 204, ...init });
|
|
2533
|
-
}
|
|
2534
|
-
function badRequest2(message) {
|
|
2535
|
-
return Response.json({ error: message ?? "Bad Request" }, { status: 400 });
|
|
2536
|
-
}
|
|
2537
|
-
function unauthorized(message) {
|
|
2538
|
-
return Response.json({ error: message ?? "Unauthorized" }, { status: 401 });
|
|
2539
|
-
}
|
|
2540
|
-
function forbidden(message) {
|
|
2541
|
-
return Response.json({ error: message ?? "Forbidden" }, { status: 403 });
|
|
2542
|
-
}
|
|
2543
|
-
function notFound(message) {
|
|
2544
|
-
return Response.json({ error: message ?? "Not Found" }, { status: 404 });
|
|
2545
|
-
}
|
|
2546
|
-
function conflict(message) {
|
|
2547
|
-
return Response.json({ error: message ?? "Conflict" }, { status: 409 });
|
|
2548
|
-
}
|
|
2549
|
-
function unprocessable(message) {
|
|
2550
|
-
return Response.json({ error: message ?? "Unprocessable Entity" }, { status: 422 });
|
|
2551
|
-
}
|
|
2552
|
-
function tooManyRequests(message) {
|
|
2553
|
-
return Response.json({ error: message ?? "Too Many Requests" }, { status: 429 });
|
|
2554
|
-
}
|
|
2555
|
-
function serverError(message) {
|
|
2556
|
-
return Response.json({ error: message ?? "Internal Server Error" }, { status: 500 });
|
|
2557
|
-
}
|
|
2558
|
-
function redirect(url, status = 302) {
|
|
2559
|
-
return new Response(null, { status, headers: { Location: url } });
|
|
2560
|
-
}
|
|
2561
|
-
|
|
2562
2616
|
// src/server/user/index.ts
|
|
2563
2617
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
2564
2618
|
var USER_TABLES = {
|
|
@@ -3116,13 +3170,13 @@ function userSystem(options) {
|
|
|
3116
3170
|
});
|
|
3117
3171
|
if (!excluded.has("login")) app.post(`${p}/login`, async (req, ctx) => {
|
|
3118
3172
|
const body = await req.json().catch(() => ({}));
|
|
3119
|
-
if (!body.email || !body.password) return
|
|
3173
|
+
if (!body.email || !body.password) return badRequest("email and password are required");
|
|
3120
3174
|
const result = await ctx.auth.login(body.email, body.password);
|
|
3121
3175
|
return ok(result);
|
|
3122
3176
|
});
|
|
3123
3177
|
if (!excluded.has("logout")) app.post(`${p}/logout`, async (req, ctx) => {
|
|
3124
3178
|
const body = await req.json().catch(() => ({}));
|
|
3125
|
-
if (!body.refreshToken) return
|
|
3179
|
+
if (!body.refreshToken) return badRequest("refreshToken is required");
|
|
3126
3180
|
await ctx.auth.logout(body.refreshToken);
|
|
3127
3181
|
return noContent();
|
|
3128
3182
|
});
|
|
@@ -3224,13 +3278,13 @@ function userSystem(options) {
|
|
|
3224
3278
|
});
|
|
3225
3279
|
app.post(`${p}/apps/:appSlug/auth/login`, async (req, ctx) => {
|
|
3226
3280
|
const body = await req.json().catch(() => ({}));
|
|
3227
|
-
if (!body.email || !body.password) return
|
|
3281
|
+
if (!body.email || !body.password) return badRequest("email and password are required");
|
|
3228
3282
|
const result = await ctx.auth.loginApp(ctx.params.appSlug, body.email, body.password);
|
|
3229
3283
|
return ok(result);
|
|
3230
3284
|
});
|
|
3231
3285
|
app.patch(`${p}/apps/:appSlug/auth/registration`, async (req, ctx) => {
|
|
3232
3286
|
const body = await req.json().catch(() => ({}));
|
|
3233
|
-
if (typeof body.open !== "boolean") return
|
|
3287
|
+
if (typeof body.open !== "boolean") return badRequest("open is required (boolean)");
|
|
3234
3288
|
const appId = await findAppIdBySlug(ctx.params.appSlug);
|
|
3235
3289
|
if (!appId) throw new HttpError("Application not found", 404);
|
|
3236
3290
|
await ctx.auth.setOpenRegistration(appId, body.open);
|
|
@@ -3239,7 +3293,7 @@ function userSystem(options) {
|
|
|
3239
3293
|
app.post(`${p}/apps/:appSlug/auth/verify`, async (req, ctx) => {
|
|
3240
3294
|
const appId = req.headers.get("x-wf-app-id");
|
|
3241
3295
|
const appKey = req.headers.get("x-wf-app-key");
|
|
3242
|
-
if (!appId || !appKey) return
|
|
3296
|
+
if (!appId || !appKey) return badRequest("X-Wf-App-Id / X-Wf-App-Key required");
|
|
3243
3297
|
const rows = await A.select("id", "slug", "name").where({ id: { eq: appId }, app_key: { eq: appKey } }).run();
|
|
3244
3298
|
if (!rows.length) throw new HttpError("Invalid app credentials", 403);
|
|
3245
3299
|
const a = rows[0];
|
|
@@ -3390,50 +3444,6 @@ function appAuth(options) {
|
|
|
3390
3444
|
return mw;
|
|
3391
3445
|
}
|
|
3392
3446
|
|
|
3393
|
-
// src/server/db/errors.ts
|
|
3394
|
-
var DbError = class extends Error {
|
|
3395
|
-
kind;
|
|
3396
|
-
code;
|
|
3397
|
-
cause;
|
|
3398
|
-
constructor(kind, message, options) {
|
|
3399
|
-
super(message);
|
|
3400
|
-
this.name = "DbError";
|
|
3401
|
-
this.kind = kind;
|
|
3402
|
-
this.code = options?.code;
|
|
3403
|
-
this.cause = options?.cause;
|
|
3404
|
-
}
|
|
3405
|
-
};
|
|
3406
|
-
var ProtocolError = class extends DbError {
|
|
3407
|
-
constructor(feature, message) {
|
|
3408
|
-
super("protocol", message ?? `${feature} is not supported by weifuwu/db`, { code: "UNSUPPORTED" });
|
|
3409
|
-
this.name = "ProtocolError";
|
|
3410
|
-
}
|
|
3411
|
-
};
|
|
3412
|
-
var ConnectionError = class extends DbError {
|
|
3413
|
-
attempts;
|
|
3414
|
-
constructor(message, attempts = 1, cause) {
|
|
3415
|
-
super("connection", message, { cause });
|
|
3416
|
-
this.name = "ConnectionError";
|
|
3417
|
-
this.attempts = attempts;
|
|
3418
|
-
}
|
|
3419
|
-
};
|
|
3420
|
-
var TimeoutError = class extends DbError {
|
|
3421
|
-
operation;
|
|
3422
|
-
ms;
|
|
3423
|
-
constructor(operation, ms) {
|
|
3424
|
-
super("timeout", `${operation} timed out after ${ms}ms`);
|
|
3425
|
-
this.name = "TimeoutError";
|
|
3426
|
-
this.operation = operation;
|
|
3427
|
-
this.ms = ms;
|
|
3428
|
-
}
|
|
3429
|
-
};
|
|
3430
|
-
var ValidationError = class extends DbError {
|
|
3431
|
-
constructor(message) {
|
|
3432
|
-
super("validation", message);
|
|
3433
|
-
this.name = "ValidationError";
|
|
3434
|
-
}
|
|
3435
|
-
};
|
|
3436
|
-
|
|
3437
3447
|
// src/server/db/body.ts
|
|
3438
3448
|
function shapeOf(s) {
|
|
3439
3449
|
const sh = s.__shape;
|
|
@@ -3510,11 +3520,6 @@ function listQuery(url, shapeDef, opts = {}) {
|
|
|
3510
3520
|
const offset = Math.max(0, parseInt(search.get("offset") ?? "0", 10) || 0);
|
|
3511
3521
|
return { filter: filter2, sort, limit, offset };
|
|
3512
3522
|
}
|
|
3513
|
-
function errorResponse(e, status) {
|
|
3514
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
3515
|
-
const st = status ?? (e instanceof DbError ? e.code === "23505" ? 409 : 400 : 400);
|
|
3516
|
-
return Response.json({ error: msg }, { status: st });
|
|
3517
|
-
}
|
|
3518
3523
|
|
|
3519
3524
|
// src/server/db/schema.ts
|
|
3520
3525
|
function innerOf(t) {
|
|
@@ -5332,7 +5337,7 @@ function messager(options) {
|
|
|
5332
5337
|
function sendTo(userId, event) {
|
|
5333
5338
|
broadcast(`user:${userId}`, event);
|
|
5334
5339
|
}
|
|
5335
|
-
function
|
|
5340
|
+
function join2(room, ws2) {
|
|
5336
5341
|
let members = rooms.get(room);
|
|
5337
5342
|
if (!members) {
|
|
5338
5343
|
members = /* @__PURE__ */ new Set();
|
|
@@ -5390,7 +5395,7 @@ function messager(options) {
|
|
|
5390
5395
|
return;
|
|
5391
5396
|
}
|
|
5392
5397
|
}
|
|
5393
|
-
|
|
5398
|
+
join2(msg.room, ws2);
|
|
5394
5399
|
ws2.send(JSON.stringify({ type: "subscribed", room: msg.room }));
|
|
5395
5400
|
} else if (msg.type === "unsubscribe" && msg.room) {
|
|
5396
5401
|
leave(msg.room, ws2);
|
|
@@ -5423,7 +5428,7 @@ function messager(options) {
|
|
|
5423
5428
|
handler,
|
|
5424
5429
|
broadcast,
|
|
5425
5430
|
sendTo,
|
|
5426
|
-
join,
|
|
5431
|
+
join: join2,
|
|
5427
5432
|
leave,
|
|
5428
5433
|
close,
|
|
5429
5434
|
createConversation,
|
|
@@ -5462,7 +5467,7 @@ function messager(options) {
|
|
|
5462
5467
|
const conv = await createConversation(ctx.user.id, { type: "group", memberIds: body.memberIds });
|
|
5463
5468
|
return created(conv);
|
|
5464
5469
|
}
|
|
5465
|
-
return
|
|
5470
|
+
return badRequest("conversation input invalid");
|
|
5466
5471
|
});
|
|
5467
5472
|
app.get(`${p}/conversations`, async (_req, ctx) => {
|
|
5468
5473
|
if (!ctx.user) throw new HttpError("Unauthorized", 401);
|
|
@@ -5482,7 +5487,7 @@ function messager(options) {
|
|
|
5482
5487
|
const convId = ctx.params.id;
|
|
5483
5488
|
await requireMember(convId, ctx);
|
|
5484
5489
|
const body = await req.json().catch(() => ({}));
|
|
5485
|
-
if (!body.content?.trim()) return
|
|
5490
|
+
if (!body.content?.trim()) return badRequest("content is required");
|
|
5486
5491
|
const message = await sendMessage(convId, {
|
|
5487
5492
|
senderType: "user",
|
|
5488
5493
|
senderId: ctx.user.id,
|
|
@@ -5503,15 +5508,15 @@ function messager(options) {
|
|
|
5503
5508
|
if (!ctx.user) throw new HttpError("Unauthorized", 401);
|
|
5504
5509
|
const messageId = ctx.params.id;
|
|
5505
5510
|
const body = await req.json().catch(() => ({}));
|
|
5506
|
-
if (!body.content?.trim()) return
|
|
5511
|
+
if (!body.content?.trim()) return badRequest("content is required");
|
|
5507
5512
|
const rows = await orm.query.from(`${MESSAGES} m`).join(`${MEMBERS} mem`, { "mem.conversation_id": { col: "m.conversation_id" } }).where({ "m.id": { eq: messageId }, "mem.user_id": { eq: String(ctx.user.id) } }).select("m.conversation_id", "m.sender_type", "m.sender_id").run();
|
|
5508
|
-
if (!rows.length) return
|
|
5513
|
+
if (!rows.length) return badRequest("message not found");
|
|
5509
5514
|
const row = rows[0];
|
|
5510
5515
|
if (row.sender_type === "user" && row.sender_id !== ctx.user.id) {
|
|
5511
5516
|
throw new HttpError("Forbidden: not your message", 403);
|
|
5512
5517
|
}
|
|
5513
5518
|
const edited = await editMessage(messageId, body.content);
|
|
5514
|
-
if (!edited) return
|
|
5519
|
+
if (!edited) return badRequest("message not found");
|
|
5515
5520
|
broadcast(`conv:${edited.conversation_id}`, { type: "message_edited", message: edited });
|
|
5516
5521
|
return ok(edited);
|
|
5517
5522
|
});
|
|
@@ -5519,7 +5524,7 @@ function messager(options) {
|
|
|
5519
5524
|
if (!ctx.user) throw new HttpError("Unauthorized", 401);
|
|
5520
5525
|
const messageId = ctx.params.id;
|
|
5521
5526
|
const rows = await orm.query.from(`${MESSAGES} m`).join(`${MEMBERS} mem`, { "mem.conversation_id": { col: "m.conversation_id" } }).where({ "m.id": { eq: messageId }, "mem.user_id": { eq: String(ctx.user.id) } }).select("m.conversation_id", "m.sender_type", "m.sender_id").run();
|
|
5522
|
-
if (!rows.length) return
|
|
5527
|
+
if (!rows.length) return badRequest("message not found");
|
|
5523
5528
|
const row = rows[0];
|
|
5524
5529
|
if (row.sender_type === "user" && row.sender_id !== ctx.user.id) {
|
|
5525
5530
|
throw new HttpError("Forbidden: not your message", 403);
|
|
@@ -8230,6 +8235,7 @@ function createScheduler(orm, execute, opts = {}) {
|
|
|
8230
8235
|
start: () => {
|
|
8231
8236
|
if (timer) return;
|
|
8232
8237
|
timer = setInterval(() => void tick(), intervalMs);
|
|
8238
|
+
timer.unref?.();
|
|
8233
8239
|
void tick();
|
|
8234
8240
|
},
|
|
8235
8241
|
stop: () => {
|
|
@@ -9481,23 +9487,23 @@ function createAiClient(opts) {
|
|
|
9481
9487
|
}
|
|
9482
9488
|
const approvals = /* @__PURE__ */ new Map();
|
|
9483
9489
|
function approve(response) {
|
|
9484
|
-
const
|
|
9485
|
-
if (!
|
|
9490
|
+
const resolve4 = approvals.get(response.id);
|
|
9491
|
+
if (!resolve4) return false;
|
|
9486
9492
|
approvals.delete(response.id);
|
|
9487
|
-
|
|
9493
|
+
resolve4(response);
|
|
9488
9494
|
return true;
|
|
9489
9495
|
}
|
|
9490
9496
|
async function waitApproval(req, emit, timeoutMs = DEFAULT_APPROVAL_TIMEOUT, signal) {
|
|
9491
9497
|
const expiresAt = Date.now() + timeoutMs;
|
|
9492
9498
|
emit("wf:approval_request", { ...req, expiresAt });
|
|
9493
|
-
return new Promise((
|
|
9499
|
+
return new Promise((resolve4) => {
|
|
9494
9500
|
let settled = false;
|
|
9495
9501
|
const finish = (resp) => {
|
|
9496
9502
|
if (settled) return;
|
|
9497
9503
|
settled = true;
|
|
9498
9504
|
clearTimeout(timer);
|
|
9499
9505
|
signal?.removeEventListener("abort", onAbort);
|
|
9500
|
-
|
|
9506
|
+
resolve4(resp);
|
|
9501
9507
|
};
|
|
9502
9508
|
const timer = setTimeout(() => {
|
|
9503
9509
|
if (approvals.has(req.id)) approvals.delete(req.id);
|
|
@@ -9969,23 +9975,23 @@ function createApprovalHub(timeoutMs = DEFAULT_APPROVAL_TIMEOUT2) {
|
|
|
9969
9975
|
const approvals = /* @__PURE__ */ new Map();
|
|
9970
9976
|
return {
|
|
9971
9977
|
approve(response) {
|
|
9972
|
-
const
|
|
9973
|
-
if (!
|
|
9978
|
+
const resolve4 = approvals.get(response.id);
|
|
9979
|
+
if (!resolve4) return false;
|
|
9974
9980
|
approvals.delete(response.id);
|
|
9975
|
-
|
|
9981
|
+
resolve4(response);
|
|
9976
9982
|
return true;
|
|
9977
9983
|
},
|
|
9978
9984
|
async waitApproval(req, emit, timeout = timeoutMs, signal) {
|
|
9979
9985
|
const expiresAt = Date.now() + timeout;
|
|
9980
9986
|
emit("wf:approval_request", { ...req, expiresAt });
|
|
9981
|
-
return new Promise((
|
|
9987
|
+
return new Promise((resolve4) => {
|
|
9982
9988
|
let settled = false;
|
|
9983
9989
|
const finish = (resp) => {
|
|
9984
9990
|
if (settled) return;
|
|
9985
9991
|
settled = true;
|
|
9986
9992
|
clearTimeout(timer);
|
|
9987
9993
|
signal?.removeEventListener("abort", onAbort);
|
|
9988
|
-
|
|
9994
|
+
resolve4(resp);
|
|
9989
9995
|
};
|
|
9990
9996
|
const timer = setTimeout(() => {
|
|
9991
9997
|
if (approvals.has(req.id)) approvals.delete(req.id);
|
|
@@ -10199,7 +10205,7 @@ async function MemoryAiServer(options = {}) {
|
|
|
10199
10205
|
}
|
|
10200
10206
|
});
|
|
10201
10207
|
});
|
|
10202
|
-
await new Promise((
|
|
10208
|
+
await new Promise((resolve4) => server.listen(options.port ?? 0, "127.0.0.1", resolve4));
|
|
10203
10209
|
const addr = server.address();
|
|
10204
10210
|
const port = typeof addr === "object" && addr ? addr.port : 0;
|
|
10205
10211
|
return {
|
|
@@ -10207,7 +10213,7 @@ async function MemoryAiServer(options = {}) {
|
|
|
10207
10213
|
url: `http://127.0.0.1:${port}`,
|
|
10208
10214
|
requests,
|
|
10209
10215
|
closeAllConnections: () => server.closeAllConnections(),
|
|
10210
|
-
close: () => new Promise((
|
|
10216
|
+
close: () => new Promise((resolve4) => server.close(() => resolve4()))
|
|
10211
10217
|
};
|
|
10212
10218
|
}
|
|
10213
10219
|
async function readJson(req) {
|
|
@@ -10298,11 +10304,98 @@ async function handle(ai, method, url, req, res, preBody) {
|
|
|
10298
10304
|
|
|
10299
10305
|
// src/server/ui/index.ts
|
|
10300
10306
|
import { build } from "esbuild";
|
|
10301
|
-
import { readFile, stat as stat2 } from "node:fs/promises";
|
|
10307
|
+
import { readFile as readFile2, stat as stat2 } from "node:fs/promises";
|
|
10302
10308
|
import { createHash as createHash2 } from "node:crypto";
|
|
10303
|
-
import { resolve as
|
|
10309
|
+
import { resolve as resolve3, dirname, basename } from "node:path";
|
|
10304
10310
|
import { fileURLToPath } from "node:url";
|
|
10305
10311
|
|
|
10312
|
+
// src/client/layout/bundle.ts
|
|
10313
|
+
import { readFile, readdir } from "node:fs/promises";
|
|
10314
|
+
import { join, resolve as resolve2 } from "node:path";
|
|
10315
|
+
var LAYER_ORDER = ["tokens", "base", "layout", "components", "utilities"];
|
|
10316
|
+
var LAYER_OF = {
|
|
10317
|
+
_tokens: "tokens",
|
|
10318
|
+
_dark: "tokens",
|
|
10319
|
+
_presets: "tokens",
|
|
10320
|
+
_props: "tokens",
|
|
10321
|
+
_base: "base",
|
|
10322
|
+
_stack: "layout",
|
|
10323
|
+
_row: "layout",
|
|
10324
|
+
_split: "layout",
|
|
10325
|
+
_center: "layout",
|
|
10326
|
+
_justify: "layout",
|
|
10327
|
+
_fill: "layout",
|
|
10328
|
+
_grid: "layout",
|
|
10329
|
+
_cluster: "layout",
|
|
10330
|
+
_cover: "layout",
|
|
10331
|
+
_position: "layout",
|
|
10332
|
+
_sticky: "layout",
|
|
10333
|
+
_overflow: "layout",
|
|
10334
|
+
"_safe-area": "layout",
|
|
10335
|
+
_layer: "layout",
|
|
10336
|
+
"_align-self": "layout",
|
|
10337
|
+
_nowrap: "layout",
|
|
10338
|
+
_shrink: "layout",
|
|
10339
|
+
_container: "layout",
|
|
10340
|
+
"_app-shell": "layout",
|
|
10341
|
+
_surface: "utilities",
|
|
10342
|
+
_spacing: "utilities",
|
|
10343
|
+
_border: "utilities",
|
|
10344
|
+
_text: "utilities",
|
|
10345
|
+
_hidden: "utilities",
|
|
10346
|
+
_block: "utilities",
|
|
10347
|
+
_flex: "utilities",
|
|
10348
|
+
// display 工具族(基类 :where() 零优先级 + @media 变体正常优先级——变体恒胜基类,零 !important)
|
|
10349
|
+
_popup: "layout"
|
|
10350
|
+
// 框架内部浮层基类(popup-manager 消费——非用户词汇)
|
|
10351
|
+
};
|
|
10352
|
+
var TOKENS_LAYER = "tokens";
|
|
10353
|
+
var stripImports = (css) => css.replace(/@import\s+['"][^'"]+['"]\s*;?\s*\n?/g, "");
|
|
10354
|
+
async function layoutEntryFiles(layoutDir) {
|
|
10355
|
+
const entry = await readFile(join(layoutDir, "weifuwu-layout.css"), "utf-8");
|
|
10356
|
+
const files = [];
|
|
10357
|
+
for (const line of entry.split("\n")) {
|
|
10358
|
+
const m = line.match(/@import\s+['"]([^'"]+)['"]/);
|
|
10359
|
+
if (m) files.push(m[1].replace(/^\.\//, ""));
|
|
10360
|
+
}
|
|
10361
|
+
if (!files.length) throw new Error(`layout \u5165\u53E3\u65E0 @import\uFF08${layoutDir}/weifuwu-layout.css\uFF09\u2014\u2014\u88C5\u914D\u5355\u6E90\u5931\u6548`);
|
|
10362
|
+
return files;
|
|
10363
|
+
}
|
|
10364
|
+
async function isLayoutSourceDir(dir) {
|
|
10365
|
+
try {
|
|
10366
|
+
const entries = await readdir(dir);
|
|
10367
|
+
return entries.includes("weifuwu-layout.css") && entries.some((f2) => /^_[a-z-]+\.css$/.test(f2));
|
|
10368
|
+
} catch {
|
|
10369
|
+
return false;
|
|
10370
|
+
}
|
|
10371
|
+
}
|
|
10372
|
+
async function bundleLayout(layoutDir) {
|
|
10373
|
+
const dir = resolve2(layoutDir);
|
|
10374
|
+
const files = await layoutEntryFiles(dir);
|
|
10375
|
+
const inputs = [join(dir, "weifuwu-layout.css")];
|
|
10376
|
+
const chunks = [];
|
|
10377
|
+
for (const f2 of files) {
|
|
10378
|
+
const abs = join(dir, f2);
|
|
10379
|
+
inputs.push(abs);
|
|
10380
|
+
const content = stripImports(await readFile(abs, "utf-8")).trim();
|
|
10381
|
+
const name = f2.replace(/\.css$/, "");
|
|
10382
|
+
const layer = LAYER_OF[name];
|
|
10383
|
+
if (!layer) {
|
|
10384
|
+
throw new Error(`layout \u6587\u4EF6\u672A\u767B\u8BB0 @layer \u6620\u5C04: ${f2}\uFF08\u5728 src/client/layout/bundle.ts LAYER_OF \u4E2D\u767B\u8BB0\uFF09`);
|
|
10385
|
+
}
|
|
10386
|
+
chunks.push(layer === TOKENS_LAYER ? content : `@layer ${layer} {
|
|
10387
|
+
${content}
|
|
10388
|
+
}`);
|
|
10389
|
+
}
|
|
10390
|
+
const css = `/* weifuwu/layout \u2014 CSS \u5E03\u5C40\u539F\u8BED + \u8BBE\u8BA1 Token\uFF08\u88C5\u914D\u5355\u6E90\uFF1Asrc/client/layout/bundle.ts\uFF09 */
|
|
10391
|
+
|
|
10392
|
+
@layer ${LAYER_ORDER.join(", ")};
|
|
10393
|
+
|
|
10394
|
+
${chunks.join("\n\n")}
|
|
10395
|
+
`;
|
|
10396
|
+
return { css, inputs };
|
|
10397
|
+
}
|
|
10398
|
+
|
|
10306
10399
|
// src/server/ui/html-safe.ts
|
|
10307
10400
|
var HtmlSafe = class {
|
|
10308
10401
|
value;
|
|
@@ -12886,11 +12979,11 @@ function openPopup(env, opts) {
|
|
|
12886
12979
|
const registry = applier.registry;
|
|
12887
12980
|
if (!registry) return;
|
|
12888
12981
|
const ctx = env.getSharedContext() ?? {};
|
|
12889
|
-
const cmds = await new Promise((
|
|
12982
|
+
const cmds = await new Promise((resolve4, reject) => {
|
|
12890
12983
|
const out = [];
|
|
12891
12984
|
const req = () => env.requestRender?.();
|
|
12892
12985
|
const obs = prev ? diffV2(prev, content, ctx, state2.segments, registry, req) : renderV2(content, ctx, registry, state2.segments, req);
|
|
12893
|
-
obs.subscribe({ next: (c) => out.push(c), error: reject, complete: () =>
|
|
12986
|
+
obs.subscribe({ next: (c) => out.push(c), error: reject, complete: () => resolve4(out) });
|
|
12894
12987
|
});
|
|
12895
12988
|
for (const value of cmds) {
|
|
12896
12989
|
if (state2.disposed || v !== state2.version) return;
|
|
@@ -14166,9 +14259,9 @@ function concatWith(tail) {
|
|
|
14166
14259
|
|
|
14167
14260
|
// src/client/vdom/core/v2/integrate.ts
|
|
14168
14261
|
function collectCommands(obs) {
|
|
14169
|
-
return new Promise((
|
|
14262
|
+
return new Promise((resolve4, reject) => {
|
|
14170
14263
|
const out = [];
|
|
14171
|
-
obs.subscribe({ next: (c) => out.push(c), error: reject, complete: () =>
|
|
14264
|
+
obs.subscribe({ next: (c) => out.push(c), error: reject, complete: () => resolve4(out) });
|
|
14172
14265
|
});
|
|
14173
14266
|
}
|
|
14174
14267
|
async function v2ToHtml(root, ctx, registry) {
|
|
@@ -14205,6 +14298,35 @@ function unsafe(s) {
|
|
|
14205
14298
|
return new HtmlSafe(s);
|
|
14206
14299
|
}
|
|
14207
14300
|
var MAX_CACHE_ENTRIES = 32;
|
|
14301
|
+
async function statAll(paths) {
|
|
14302
|
+
const out = {};
|
|
14303
|
+
for (const p of paths) {
|
|
14304
|
+
try {
|
|
14305
|
+
const st = await stat2(p);
|
|
14306
|
+
out[p] = { mtimeMs: st.mtimeMs, size: st.size };
|
|
14307
|
+
} catch {
|
|
14308
|
+
out[p] = { mtimeMs: -1, size: -1 };
|
|
14309
|
+
}
|
|
14310
|
+
}
|
|
14311
|
+
return out;
|
|
14312
|
+
}
|
|
14313
|
+
async function importClosure(absPath, seen = /* @__PURE__ */ new Set()) {
|
|
14314
|
+
if (seen.has(absPath)) return [];
|
|
14315
|
+
seen.add(absPath);
|
|
14316
|
+
let css;
|
|
14317
|
+
try {
|
|
14318
|
+
css = await readFile2(absPath, "utf-8");
|
|
14319
|
+
} catch {
|
|
14320
|
+
return [];
|
|
14321
|
+
}
|
|
14322
|
+
const dir = dirname(absPath);
|
|
14323
|
+
const out = [];
|
|
14324
|
+
for (const m of css.matchAll(/@import\s+['"](\.[^'"]+\.css)['"]/g)) {
|
|
14325
|
+
const dep = resolve3(dir, m[1]);
|
|
14326
|
+
out.push(dep, ...await importClosure(dep, seen));
|
|
14327
|
+
}
|
|
14328
|
+
return out;
|
|
14329
|
+
}
|
|
14208
14330
|
var postcssAvailable;
|
|
14209
14331
|
async function checkPostcss() {
|
|
14210
14332
|
if (postcssAvailable !== void 0) return postcssAvailable;
|
|
@@ -14219,12 +14341,12 @@ async function checkPostcss() {
|
|
|
14219
14341
|
}
|
|
14220
14342
|
function resolveEntry(entryPath) {
|
|
14221
14343
|
if (entryPath.startsWith(".") || entryPath.startsWith("/")) {
|
|
14222
|
-
return
|
|
14344
|
+
return resolve3(entryPath);
|
|
14223
14345
|
}
|
|
14224
14346
|
try {
|
|
14225
14347
|
return fileURLToPath(import.meta.resolve(entryPath));
|
|
14226
14348
|
} catch {
|
|
14227
|
-
return
|
|
14349
|
+
return resolve3(entryPath);
|
|
14228
14350
|
}
|
|
14229
14351
|
}
|
|
14230
14352
|
function ui(options = {}) {
|
|
@@ -14330,7 +14452,7 @@ function ui(options = {}) {
|
|
|
14330
14452
|
});
|
|
14331
14453
|
const inputs = {};
|
|
14332
14454
|
for (const key of Object.keys(result.metafile?.inputs ?? {})) {
|
|
14333
|
-
const abs =
|
|
14455
|
+
const abs = resolve3(key);
|
|
14334
14456
|
try {
|
|
14335
14457
|
const st = await stat2(abs);
|
|
14336
14458
|
inputs[abs] = { mtimeMs: st.mtimeMs, size: st.size };
|
|
@@ -14345,14 +14467,13 @@ function ui(options = {}) {
|
|
|
14345
14467
|
async css(entryPath) {
|
|
14346
14468
|
const absPath = resolveEntry(entryPath);
|
|
14347
14469
|
const { code, etag } = await compile2("css", absPath, async () => {
|
|
14348
|
-
|
|
14349
|
-
|
|
14350
|
-
|
|
14351
|
-
|
|
14352
|
-
inputs[absPath] = { mtimeMs: st.mtimeMs, size: st.size };
|
|
14353
|
-
} catch {
|
|
14354
|
-
inputs[absPath] = { mtimeMs: -1, size: -1 };
|
|
14470
|
+
const dir = dirname(absPath);
|
|
14471
|
+
if (basename(absPath) === "weifuwu-layout.css" && await isLayoutSourceDir(dir)) {
|
|
14472
|
+
const bundle = await bundleLayout(dir);
|
|
14473
|
+
return { code: bundle.css, inputs: await statAll(bundle.inputs) };
|
|
14355
14474
|
}
|
|
14475
|
+
let code2 = await readFile2(absPath, "utf-8");
|
|
14476
|
+
const inputs = await statAll([absPath, ...await importClosure(absPath)]);
|
|
14356
14477
|
if (await checkPostcss()) {
|
|
14357
14478
|
try {
|
|
14358
14479
|
const postcss = await import("postcss");
|
|
@@ -14695,7 +14816,7 @@ var PgConnection = class _PgConnection {
|
|
|
14695
14816
|
/** 池空闲回收用:最近一次查询完成时间戳(pool release 时更新) */
|
|
14696
14817
|
lastUsed = 0;
|
|
14697
14818
|
connect() {
|
|
14698
|
-
return new Promise((
|
|
14819
|
+
return new Promise((resolve4, reject) => {
|
|
14699
14820
|
this.status = "connecting";
|
|
14700
14821
|
const sock = net.connect(this.opts.port, this.opts.host);
|
|
14701
14822
|
this.socket = sock;
|
|
@@ -14727,7 +14848,7 @@ var PgConnection = class _PgConnection {
|
|
|
14727
14848
|
this.onReady = () => {
|
|
14728
14849
|
clearTimeout(timeout);
|
|
14729
14850
|
this.status = "ready";
|
|
14730
|
-
|
|
14851
|
+
resolve4();
|
|
14731
14852
|
};
|
|
14732
14853
|
this.onAuthFail = (err) => {
|
|
14733
14854
|
clearTimeout(timeout);
|
|
@@ -15024,7 +15145,7 @@ var PgConnection = class _PgConnection {
|
|
|
15024
15145
|
}
|
|
15025
15146
|
/** 查询:无参数走简单协议(Q),有参数走扩展查询(Parse/Bind/Execute/Sync) */
|
|
15026
15147
|
query(sql, params) {
|
|
15027
|
-
return new Promise((
|
|
15148
|
+
return new Promise((resolve4, reject) => {
|
|
15028
15149
|
if (this.status !== "ready" || !this.socket) {
|
|
15029
15150
|
reject(new ConnectionError("postgres: not connected"));
|
|
15030
15151
|
return;
|
|
@@ -15037,7 +15158,7 @@ var PgConnection = class _PgConnection {
|
|
|
15037
15158
|
this.currentQuery = {
|
|
15038
15159
|
columns: [],
|
|
15039
15160
|
rows: [],
|
|
15040
|
-
resolve:
|
|
15161
|
+
resolve: resolve4,
|
|
15041
15162
|
reject
|
|
15042
15163
|
};
|
|
15043
15164
|
if (process.env.PGDBG2) console.error("[cquery]", JSON.stringify(sql.slice(0, 120)));
|
|
@@ -15047,12 +15168,12 @@ var PgConnection = class _PgConnection {
|
|
|
15047
15168
|
let stmtEntry = this.getPrepared(sig);
|
|
15048
15169
|
const encoded = encodeParams(params);
|
|
15049
15170
|
if (!stmtEntry) {
|
|
15050
|
-
this.issueExtendedQuery(sql, encoded,
|
|
15171
|
+
this.issueExtendedQuery(sql, encoded, resolve4, reject);
|
|
15051
15172
|
} else {
|
|
15052
15173
|
this.currentQuery = {
|
|
15053
15174
|
columns: [...stmtEntry.columns],
|
|
15054
15175
|
rows: [],
|
|
15055
|
-
resolve:
|
|
15176
|
+
resolve: resolve4,
|
|
15056
15177
|
reject,
|
|
15057
15178
|
sql,
|
|
15058
15179
|
params: encoded,
|
|
@@ -15071,12 +15192,12 @@ var PgConnection = class _PgConnection {
|
|
|
15071
15192
|
* 扩展查询首次准备:Parse + Describe + Flush(无 Sync——错误时由调用方发 Sync 复位)。
|
|
15072
15193
|
* retry 路径复用:新语句名强制服务器按当前 schema 重新解析(DDL 失效恢复)。
|
|
15073
15194
|
*/
|
|
15074
|
-
issueExtendedQuery(sql, params,
|
|
15195
|
+
issueExtendedQuery(sql, params, resolve4, reject, retried) {
|
|
15075
15196
|
const name = `wf_s${++this.stmtSeq}`;
|
|
15076
15197
|
this.currentQuery = {
|
|
15077
15198
|
columns: [],
|
|
15078
15199
|
rows: [],
|
|
15079
|
-
resolve:
|
|
15200
|
+
resolve: resolve4,
|
|
15080
15201
|
reject,
|
|
15081
15202
|
sql,
|
|
15082
15203
|
params,
|
|
@@ -15100,7 +15221,7 @@ var PgConnection = class _PgConnection {
|
|
|
15100
15221
|
/** 等待连接空闲(事务/多语句流程用) */
|
|
15101
15222
|
waitIdle() {
|
|
15102
15223
|
if (!this.currentQuery) return Promise.resolve();
|
|
15103
|
-
return new Promise((
|
|
15224
|
+
return new Promise((resolve4) => this.waiters.push(resolve4));
|
|
15104
15225
|
}
|
|
15105
15226
|
/** 终止连接 */
|
|
15106
15227
|
async close() {
|
|
@@ -15321,9 +15442,9 @@ var PgPool = class _PgPool {
|
|
|
15321
15442
|
);
|
|
15322
15443
|
}
|
|
15323
15444
|
const timeoutMs = this.opts.acquireTimeoutMs ?? 3e4;
|
|
15324
|
-
return new Promise((
|
|
15445
|
+
return new Promise((resolve4, reject) => {
|
|
15325
15446
|
const waiter = {
|
|
15326
|
-
resolve:
|
|
15447
|
+
resolve: resolve4,
|
|
15327
15448
|
reject
|
|
15328
15449
|
};
|
|
15329
15450
|
if (timeoutMs > 0) {
|
|
@@ -16773,9 +16894,9 @@ var RedisConnection = class {
|
|
|
16773
16894
|
connect() {
|
|
16774
16895
|
if (this.connectPromise) return this.connectPromise;
|
|
16775
16896
|
this.closed = false;
|
|
16776
|
-
this.connectPromise = new Promise((
|
|
16897
|
+
this.connectPromise = new Promise((resolve4, reject) => {
|
|
16777
16898
|
this.openSocket();
|
|
16778
|
-
this.onceReady = () =>
|
|
16899
|
+
this.onceReady = () => resolve4();
|
|
16779
16900
|
this.onceFailed = (err) => reject(err);
|
|
16780
16901
|
}).finally(() => {
|
|
16781
16902
|
this.connectPromise = null;
|
|
@@ -16883,15 +17004,15 @@ var RedisConnection = class {
|
|
|
16883
17004
|
if (this.offlineQueue.length >= this.opts.maxOfflineQueue) {
|
|
16884
17005
|
return Promise.reject(new ConnectionError(`redis: offline queue full (${this.opts.maxOfflineQueue})`));
|
|
16885
17006
|
}
|
|
16886
|
-
return new Promise((
|
|
16887
|
-
this.offlineQueue.push({ name, args, resolve:
|
|
17007
|
+
return new Promise((resolve4, reject) => {
|
|
17008
|
+
this.offlineQueue.push({ name, args, resolve: resolve4, reject, asBuffer: opts?.asBuffer });
|
|
16888
17009
|
});
|
|
16889
17010
|
}
|
|
16890
17011
|
sendNow(name, args, asBuffer) {
|
|
16891
17012
|
const start = performance.now();
|
|
16892
|
-
return new Promise((
|
|
17013
|
+
return new Promise((resolve4, reject) => {
|
|
16893
17014
|
const p = {
|
|
16894
|
-
resolve:
|
|
17015
|
+
resolve: resolve4,
|
|
16895
17016
|
reject,
|
|
16896
17017
|
asBuffer,
|
|
16897
17018
|
blocking: BLOCKING_COMMANDS.has(name.toUpperCase())
|
|
@@ -16961,7 +17082,7 @@ var RedisConnection = class {
|
|
|
16961
17082
|
if (this.status !== "ready" || !this.socket) {
|
|
16962
17083
|
return Promise.reject(new ConnectionError("redis: not connected"));
|
|
16963
17084
|
}
|
|
16964
|
-
return new Promise((
|
|
17085
|
+
return new Promise((resolve4, reject) => {
|
|
16965
17086
|
const results = [];
|
|
16966
17087
|
const batchPending = [];
|
|
16967
17088
|
let settled = false;
|
|
@@ -16970,7 +17091,7 @@ var RedisConnection = class {
|
|
|
16970
17091
|
if (results.length === count) {
|
|
16971
17092
|
settled = true;
|
|
16972
17093
|
if (batchTimer) clearTimeout(batchTimer);
|
|
16973
|
-
|
|
17094
|
+
resolve4(results);
|
|
16974
17095
|
}
|
|
16975
17096
|
};
|
|
16976
17097
|
for (let i = 0; i < count; i++) {
|
|
@@ -17361,9 +17482,9 @@ var RedisPool = class _RedisPool {
|
|
|
17361
17482
|
});
|
|
17362
17483
|
this.replenish();
|
|
17363
17484
|
}
|
|
17364
|
-
return new Promise((
|
|
17485
|
+
return new Promise((resolve4, reject) => {
|
|
17365
17486
|
const waiter = () => {
|
|
17366
|
-
if (this.clients.length > 0 && this.clients[0].connected)
|
|
17487
|
+
if (this.clients.length > 0 && this.clients[0].connected) resolve4(this.clients[0]);
|
|
17367
17488
|
else reject(new ConnectionError("redis: pool exhausted after reconnect wait"));
|
|
17368
17489
|
};
|
|
17369
17490
|
this.replenishWaiters.push(waiter);
|
|
@@ -18494,13 +18615,13 @@ var MemoryRedisServer = class {
|
|
|
18494
18615
|
}
|
|
18495
18616
|
async start() {
|
|
18496
18617
|
if (this.server) return;
|
|
18497
|
-
await new Promise((
|
|
18618
|
+
await new Promise((resolve4) => {
|
|
18498
18619
|
this.server = net3.createServer((sock) => this.handleSocket(sock));
|
|
18499
18620
|
this.server.listen(this.opts.port, "127.0.0.1", () => {
|
|
18500
18621
|
const addr = this.server.address();
|
|
18501
18622
|
this.port = addr.port;
|
|
18502
18623
|
this.url = `redis://127.0.0.1:${addr.port}`;
|
|
18503
|
-
|
|
18624
|
+
resolve4();
|
|
18504
18625
|
});
|
|
18505
18626
|
});
|
|
18506
18627
|
}
|
|
@@ -18512,9 +18633,9 @@ var MemoryRedisServer = class {
|
|
|
18512
18633
|
ctx.sock.destroy();
|
|
18513
18634
|
}
|
|
18514
18635
|
this.conns.clear();
|
|
18515
|
-
await new Promise((
|
|
18516
|
-
if (!this.server) return
|
|
18517
|
-
this.server.close(() =>
|
|
18636
|
+
await new Promise((resolve4) => {
|
|
18637
|
+
if (!this.server) return resolve4();
|
|
18638
|
+
this.server.close(() => resolve4());
|
|
18518
18639
|
this.server = null;
|
|
18519
18640
|
});
|
|
18520
18641
|
}
|
|
@@ -18600,14 +18721,14 @@ var MemoryRedisServer = class {
|
|
|
18600
18721
|
const v = await this.engine.command("LPOP", k);
|
|
18601
18722
|
if (v !== null && v !== void 0) return encodeReply([k, v]);
|
|
18602
18723
|
}
|
|
18603
|
-
return await new Promise((
|
|
18604
|
-
const waiter = { keys, resolve:
|
|
18724
|
+
return await new Promise((resolve4) => {
|
|
18725
|
+
const waiter = { keys, resolve: resolve4, timer: null, owner: ctx.id };
|
|
18605
18726
|
this.blpopWaiters.push(waiter);
|
|
18606
18727
|
if (timeout > 0) {
|
|
18607
18728
|
waiter.timer = setTimeout(() => {
|
|
18608
18729
|
const i = this.blpopWaiters.indexOf(waiter);
|
|
18609
18730
|
if (i >= 0) this.blpopWaiters.splice(i, 1);
|
|
18610
|
-
|
|
18731
|
+
resolve4(encodeReply(null));
|
|
18611
18732
|
}, timeout * 1e3);
|
|
18612
18733
|
}
|
|
18613
18734
|
});
|
|
@@ -18729,7 +18850,7 @@ export {
|
|
|
18729
18850
|
WEIFUWU_WORKFLOW_SCHEMA,
|
|
18730
18851
|
and,
|
|
18731
18852
|
appAuth,
|
|
18732
|
-
|
|
18853
|
+
badRequest,
|
|
18733
18854
|
between,
|
|
18734
18855
|
bodyOf,
|
|
18735
18856
|
buildQuery,
|