Export template source from 488f7e229afed8f03fc3bfa4abe707da0c613460:examples/local-first/packages/gutenberg-runtime

This commit is contained in:
Quixos Template Publisher
2000-01-01 00:00:00 +00:00
commit a9f25b30ad
14 changed files with 627 additions and 0 deletions
+128
View File
@@ -0,0 +1,128 @@
import assert from "node:assert/strict";
import { test, after } from "node:test";
import { stripTypeScriptTypes } from "node:module";
import { readFile, mkdtemp, writeFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { pathToFileURL } from "node:url";
const directory = await mkdtemp(join(tmpdir(), "gutenberg-test-"));
for (const name of ["catalog", "download"]) {
const source = await readFile(new URL("../src/" + name + ".ts", import.meta.url), "utf8");
await writeFile(
join(directory, name + ".mjs"),
stripTypeScriptTypes(source).replace("./catalog.js", "./catalog.mjs"),
);
}
after(() => rm(directory, { recursive: true, force: true }));
const { parseIndex, searchIndex, openingExcerpt } = await import(pathToFileURL(join(directory, "catalog.mjs")));
const { createBookLoader, bookURL, fetchBook } = await import(pathToFileURL(join(directory, "download.mjs")));
test("CSV preserves quoted/multiline titles and selects text editions", () => {
const books = parseIndex(
'Text#,Type,Title,Language,Authors\r\n1342,Text,"Pride, and\r\nPrejudice",en,"Austen, Jane"\r\n11,Text,"Alice and ""friends""",en,Carroll\r\n12,Sound,Audio,en,Someone\r\n',
);
assert.deepEqual(books, [
{ ebook: 1342, title: "Pride, and Prejudice", language: "en", author: "Austen, Jane" },
{ ebook: 11, title: 'Alice and "friends"', language: "en", author: "Carroll" },
]);
assert.throws(() => parseIndex('Text#,Type,Title,Language,Authors\n1,Text,"broken'), /Unclosed/);
});
test("fuzzy titles and diacritics work, with a bounded result list", () => {
const books = [
{ ebook: 1342, title: "Pride and Prejudice", author: "Austen, Jane", language: "en" },
{ ebook: 11, title: "Alice in Wonderland", author: "Carroll", language: "en" },
...Array.from({ length: 40 }, (_, i) => ({
ebook: 100 + i,
title: "Émile " + i,
author: "Rousseau",
language: "fr",
})),
];
const search = searchIndex(books);
assert.equal(search("prde and prejudi").at(0).ebook, 1342);
assert.equal(search("austen").at(0).ebook, 1342);
assert.equal(search("emile").length, 20);
assert.deepEqual(search("a"), []);
});
test("opening excerpt keeps paragraph boundaries and excludes Gutenberg framing", () => {
const body =
"license\n*** START OF THE PROJECT GUTENBERG EBOOK TEST ***\n\nFirst\nline\n\nSecond\n\n*** END OF THE PROJECT GUTENBERG EBOOK TEST ***\nlicense";
assert.deepEqual(openingExcerpt(body), { text: "First\nline\n\nSecond", words: 3 });
const first = "word ".repeat(600).trim(),
second = "more ".repeat(450).trim();
const text = "*** START OF THE PROJECT GUTENBERG EBOOK TEST ***\n\n" + first + "\n\n" + second;
assert.equal(openingExcerpt(text), null, "Wait for the whole final paragraph");
assert.deepEqual(openingExcerpt(text + "\n\nignored"), { text: first + "\n\n" + second, words: 1050 });
assert.deepEqual(openingExcerpt("short book", true), { text: "short book", words: 2 });
const long = "😀".repeat(30000);
const bounded = openingExcerpt(long, true);
assert(bounded.text.length <= 56000);
assert(!/[\uD800-\uDBFF]$/.test(bounded.text));
});
test("streaming fetch stops at the excerpt and releases the remaining download", async () => {
const original = globalThis.fetch;
let cancelled = false,
reads = 0;
const chunks = [
"licence\n*** START OF THE PROJECT GUTEN",
"BERG EBOOK TEST ***\n\n",
"word ".repeat(600) + "\n\n",
"more ".repeat(450) + "\n\n",
"unused rest of the book",
];
globalThis.fetch = async () =>
new Response(
new ReadableStream(
{
pull(controller) {
reads++;
const chunk = chunks.shift();
if (chunk) controller.enqueue(new TextEncoder().encode(chunk));
else controller.close();
},
cancel() {
cancelled = true;
},
},
{ highWaterMark: 0 },
),
);
try {
const text = await fetchBook(1342);
assert.equal(reads, 4);
assert.equal(cancelled, true);
assert.equal(openingExcerpt(text, true).words, 1050);
assert(!text.includes("unused"));
} finally {
globalThis.fetch = original;
}
});
test("downloads coalesce, cache, serialize, and permit retries after failure", async () => {
let calls = 0,
active = 0,
maximum = 0,
fail = true;
const load = createBookLoader(async (ebook) => {
calls++;
active++;
maximum = Math.max(maximum, active);
await new Promise((r) => setTimeout(r, 2));
active--;
if (ebook === 3 && fail) {
fail = false;
throw Error("offline");
}
return "Book " + ebook;
}, 1);
assert.deepEqual(await Promise.all([load(1), load(1), load(2)]), [
{ text: "Book 1", words: 2 },
{ text: "Book 1", words: 2 },
{ text: "Book 2", words: 2 },
]);
assert.equal(calls, 2);
assert.equal(maximum, 1);
await load(1);
assert.equal(calls, 2);
await assert.rejects(load(3), /offline/);
assert.deepEqual(await load(3), { text: "Book 3", words: 2 });
assert.equal(bookURL(1342), "https://gutenberg.pglaf.org/cache/epub/1342/pg1342.txt");
});