mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-16 19:59:56 +02:00
Jauge de contexte, espace disque sur partage agrégé, panneau Fichiers
Trois défauts sans rapport entre eux, tous visibles à l'écran. Jauge de contexte bloquée à « 0 / N (0 %) » : le comptage exact vient de usage.prompt_tokens (include_usage), qu'un llama-server récent a cessé de renvoyer. On note désormais si l'usage est arrivé ; sinon la fin de tour publie l'estimation qui pilote déjà la compaction — approximative, mais jamais absente. Et la souscription envoie la valeur courante juste après le rattrapage : une page rechargée affichait zéro sur une discussion pourtant pleine, faute d'événement ctx_used dans la fenêtre rejouée. Espace disque : « il ne reste que 11,9 Go » sur un partage Unraid qui en a des centaines. /mnt/user est servi par shfs, un FUSE qui agrège plusieurs disques — statfs y renvoie l'espace d'un seul, et ce chiffre REFUSAIT l'installation du modèle. Les systèmes de fichiers qui approximent (FUSE, overlay, NFS, CIFS, Ceph, Gluster) sont reconnus par leur magie : leur chiffre reste affiché, précédé d'un « ~ », mais ne bloque plus rien. Panneau Fichiers : le panneau entier défilait, emportant vers le haut l'en-tête, le fil d'Ariane et le pied (occupation disque, bouton .zip) dès qu'il y avait quelques fichiers. Seule la liste défile maintenant ; le pied reste en bas et l'état vide se centre. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
895ff92ed8
commit
b405adea6c
5118 files changed
+1264007
-23
No files matched your search
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
presets: [
|
||||
["env", { targets: { node: "current" }}],
|
||||
],
|
||||
}
|
||||
+489
@@ -0,0 +1,489 @@
|
||||
"use strict";
|
||||
|
||||
const promisify = require("util.promisify");
|
||||
const gensync = require("../");
|
||||
|
||||
const TEST_ERROR = new Error("TEST_ERROR");
|
||||
|
||||
const DID_ERROR = new Error("DID_ERROR");
|
||||
|
||||
const doSuccess = gensync({
|
||||
sync: () => 42,
|
||||
async: () => Promise.resolve(42),
|
||||
});
|
||||
|
||||
const doError = gensync({
|
||||
sync: () => {
|
||||
throw DID_ERROR;
|
||||
},
|
||||
async: () => Promise.reject(DID_ERROR),
|
||||
});
|
||||
|
||||
function throwTestError() {
|
||||
throw TEST_ERROR;
|
||||
}
|
||||
|
||||
async function expectResult(
|
||||
fn,
|
||||
arg,
|
||||
{ error, value, expectSync = false, syncErrback = expectSync }
|
||||
) {
|
||||
if (!expectSync) {
|
||||
expect(() => fn.sync(arg)).toThrow(TEST_ERROR);
|
||||
} else if (error) {
|
||||
expect(() => fn.sync(arg)).toThrow(error);
|
||||
} else {
|
||||
expect(fn.sync(arg)).toBe(value);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
await expect(fn.async(arg)).rejects.toBe(error);
|
||||
} else {
|
||||
await expect(fn.async(arg)).resolves.toBe(value);
|
||||
}
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
let sync = true;
|
||||
fn.errback(arg, (err, val) => {
|
||||
try {
|
||||
expect(err).toBe(error);
|
||||
expect(val).toBe(value);
|
||||
expect(sync).toBe(syncErrback);
|
||||
|
||||
resolve();
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
sync = false;
|
||||
});
|
||||
}
|
||||
|
||||
describe("gensync({})", () => {
|
||||
describe("option validation", () => {
|
||||
test("disallow async and errback handler together", () => {
|
||||
try {
|
||||
gensync({
|
||||
sync: throwTestError,
|
||||
async: throwTestError,
|
||||
errback: throwTestError,
|
||||
});
|
||||
|
||||
throwTestError();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(
|
||||
/Expected one of either opts.async or opts.errback, but got _both_\./
|
||||
);
|
||||
expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
|
||||
}
|
||||
});
|
||||
|
||||
test("disallow missing sync handler", () => {
|
||||
try {
|
||||
gensync({
|
||||
async: throwTestError,
|
||||
});
|
||||
|
||||
throwTestError();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/Expected opts.sync to be a function./);
|
||||
expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
|
||||
}
|
||||
});
|
||||
|
||||
test("errback callback required", () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
async: throwTestError,
|
||||
});
|
||||
|
||||
try {
|
||||
fn.errback();
|
||||
|
||||
throwTestError();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/function called without callback/);
|
||||
expect(err.code).toBe("GENSYNC_ERRBACK_NO_CALLBACK");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("generator function metadata", () => {
|
||||
test("automatic naming", () => {
|
||||
expect(
|
||||
gensync({
|
||||
sync: function readFileSync() {},
|
||||
async: () => {},
|
||||
}).name
|
||||
).toBe("readFile");
|
||||
expect(
|
||||
gensync({
|
||||
sync: function readFile() {},
|
||||
async: () => {},
|
||||
}).name
|
||||
).toBe("readFile");
|
||||
expect(
|
||||
gensync({
|
||||
sync: function readFileAsync() {},
|
||||
async: () => {},
|
||||
}).name
|
||||
).toBe("readFileAsync");
|
||||
|
||||
expect(
|
||||
gensync({
|
||||
sync: () => {},
|
||||
async: function readFileSync() {},
|
||||
}).name
|
||||
).toBe("readFileSync");
|
||||
expect(
|
||||
gensync({
|
||||
sync: () => {},
|
||||
async: function readFile() {},
|
||||
}).name
|
||||
).toBe("readFile");
|
||||
expect(
|
||||
gensync({
|
||||
sync: () => {},
|
||||
async: function readFileAsync() {},
|
||||
}).name
|
||||
).toBe("readFile");
|
||||
|
||||
expect(
|
||||
gensync({
|
||||
sync: () => {},
|
||||
errback: function readFileSync() {},
|
||||
}).name
|
||||
).toBe("readFileSync");
|
||||
expect(
|
||||
gensync({
|
||||
sync: () => {},
|
||||
errback: function readFile() {},
|
||||
}).name
|
||||
).toBe("readFile");
|
||||
expect(
|
||||
gensync({
|
||||
sync: () => {},
|
||||
errback: function readFileAsync() {},
|
||||
}).name
|
||||
).toBe("readFileAsync");
|
||||
});
|
||||
|
||||
test("explicit naming", () => {
|
||||
expect(
|
||||
gensync({
|
||||
name: "readFile",
|
||||
sync: () => {},
|
||||
async: () => {},
|
||||
}).name
|
||||
).toBe("readFile");
|
||||
});
|
||||
|
||||
test("default arity", () => {
|
||||
expect(
|
||||
gensync({
|
||||
sync: function(a, b, c, d, e, f, g) {
|
||||
throwTestError();
|
||||
},
|
||||
async: throwTestError,
|
||||
}).length
|
||||
).toBe(7);
|
||||
});
|
||||
|
||||
test("explicit arity", () => {
|
||||
expect(
|
||||
gensync({
|
||||
arity: 3,
|
||||
sync: throwTestError,
|
||||
async: throwTestError,
|
||||
}).length
|
||||
).toBe(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe("'sync' handler", async () => {
|
||||
test("success", async () => {
|
||||
const fn = gensync({
|
||||
sync: (...args) => JSON.stringify(args),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { value: "[42]", expectSync: true });
|
||||
});
|
||||
|
||||
test("failure", async () => {
|
||||
const fn = gensync({
|
||||
sync: (...args) => {
|
||||
throw JSON.stringify(args);
|
||||
},
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { error: "[42]", expectSync: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe("'async' handler", async () => {
|
||||
test("success", async () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
async: (...args) => Promise.resolve(JSON.stringify(args)),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { value: "[42]" });
|
||||
});
|
||||
|
||||
test("failure", async () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
async: (...args) => Promise.reject(JSON.stringify(args)),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { error: "[42]" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("'errback' sync handler", async () => {
|
||||
test("success", async () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
errback: (...args) => args.pop()(null, JSON.stringify(args)),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { value: "[42]", syncErrback: true });
|
||||
});
|
||||
|
||||
test("failure", async () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
errback: (...args) => args.pop()(JSON.stringify(args)),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { error: "[42]", syncErrback: true });
|
||||
});
|
||||
});
|
||||
|
||||
describe("'errback' async handler", async () => {
|
||||
test("success", async () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
errback: (...args) =>
|
||||
process.nextTick(() => args.pop()(null, JSON.stringify(args))),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { value: "[42]" });
|
||||
});
|
||||
|
||||
test("failure", async () => {
|
||||
const fn = gensync({
|
||||
sync: throwTestError,
|
||||
errback: (...args) =>
|
||||
process.nextTick(() => args.pop()(JSON.stringify(args))),
|
||||
});
|
||||
|
||||
await expectResult(fn, 42, { error: "[42]" });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("gensync(function* () {})", () => {
|
||||
test("sync throw before body", async () => {
|
||||
const fn = gensync(function*(arg = throwTestError()) {});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: TEST_ERROR,
|
||||
syncErrback: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("sync throw inside body", async () => {
|
||||
const fn = gensync(function*() {
|
||||
throwTestError();
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: TEST_ERROR,
|
||||
syncErrback: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("async throw inside body", async () => {
|
||||
const fn = gensync(function*() {
|
||||
const val = yield* doSuccess();
|
||||
throwTestError();
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: TEST_ERROR,
|
||||
});
|
||||
});
|
||||
|
||||
test("error inside body", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield* doError();
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: DID_ERROR,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("successful return value", async () => {
|
||||
const fn = gensync(function*() {
|
||||
const value = yield* doSuccess();
|
||||
|
||||
expect(value).toBe(42);
|
||||
|
||||
return 84;
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
value: 84,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("successful final value", async () => {
|
||||
const fn = gensync(function*() {
|
||||
return 42;
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
value: 42,
|
||||
expectSync: true,
|
||||
});
|
||||
});
|
||||
|
||||
test("yield unexpected object", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield {};
|
||||
});
|
||||
|
||||
try {
|
||||
await fn.async();
|
||||
|
||||
throwTestError();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(
|
||||
/Got unexpected yielded value in gensync generator/
|
||||
);
|
||||
expect(err.code).toBe("GENSYNC_EXPECTED_START");
|
||||
}
|
||||
});
|
||||
|
||||
test("yield suspend yield", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield Symbol.for("gensync:v1:start");
|
||||
|
||||
// Should be "yield*" for no error.
|
||||
yield {};
|
||||
});
|
||||
|
||||
try {
|
||||
await fn.async();
|
||||
|
||||
throwTestError();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/Expected GENSYNC_SUSPEND, got {}/);
|
||||
expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
|
||||
}
|
||||
});
|
||||
|
||||
test("yield suspend return", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield Symbol.for("gensync:v1:start");
|
||||
|
||||
// Should be "yield*" for no error.
|
||||
return {};
|
||||
});
|
||||
|
||||
try {
|
||||
await fn.async();
|
||||
|
||||
throwTestError();
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/Unexpected generator completion/);
|
||||
expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("gensync.all()", () => {
|
||||
test("success", async () => {
|
||||
const fn = gensync(function*() {
|
||||
const result = yield* gensync.all([doSuccess(), doSuccess()]);
|
||||
|
||||
expect(result).toEqual([42, 42]);
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
value: undefined,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("error first", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield* gensync.all([doError(), doSuccess()]);
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: DID_ERROR,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("error last", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield* gensync.all([doSuccess(), doError()]);
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: DID_ERROR,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("empty list", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield* gensync.all([]);
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
value: undefined,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("gensync.race()", () => {
|
||||
test("success", async () => {
|
||||
const fn = gensync(function*() {
|
||||
const result = yield* gensync.race([doSuccess(), doError()]);
|
||||
|
||||
expect(result).toEqual(42);
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
value: undefined,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("error", async () => {
|
||||
const fn = gensync(function*() {
|
||||
yield* gensync.race([doError(), doSuccess()]);
|
||||
});
|
||||
|
||||
await expectResult(fn, undefined, {
|
||||
error: DID_ERROR,
|
||||
expectSync: true,
|
||||
syncErrback: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user