yamlover 0.3.52 → 0.3.54
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/bin/request-url.js +36 -0
- package/bin/yamlover.js +83 -22
- package/dist/client/assets/{decoded-DIrynyA3.js → decoded-KRSe1Ox5.js} +1 -1
- package/dist/client/assets/{djvu-nd21Uprr.js → djvu-c9aWUIZW.js} +1 -1
- package/dist/client/assets/{docx-Vop1BSUJ.js → docx-B48n12Bl.js} +1 -1
- package/dist/client/assets/{heic-CsSwcPBN.js → heic-D3pAcx6p.js} +1 -1
- package/dist/client/assets/{imagemap-zS65hQz-.js → imagemap-Ds1NE2Nn.js} +1 -1
- package/dist/client/assets/{index-DosWj0lR.js → index-ClqLHTPo.js} +238 -238
- package/dist/client/assets/{index-CJnH1FIn.css → index-LQ8HtMcq.css} +1 -1
- package/dist/client/assets/{map-CWLpLgs5.js → map-oyN2mpRV.js} +1 -1
- package/dist/client/assets/{openable-DE9jbyAc.js → openable-p-21av4H.js} +2 -2
- package/dist/client/assets/{paged-B9vOXGFT.js → paged-DfgVaRzA.js} +1 -1
- package/dist/client/assets/{pdf-BlhT_YB6.js → pdf-BcMAT7rt.js} +1 -1
- package/dist/client/assets/{psd-DqFDBsP9.js → psd-C1Ig3mOj.js} +1 -1
- package/dist/client/assets/{spreadsheet-C1PFD0U5.js → spreadsheet-BrlnDTM_.js} +1 -1
- package/dist/client/assets/{tiff-BhJNM15B.js → tiff-d9N0BOap.js} +1 -1
- package/dist/client/assets/{xyflow-CAiiOrwd.js → xyflow-BLLCQJoB.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server.js +121 -4
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -39804,7 +39804,7 @@ var require_builder = __commonJS({
|
|
|
39804
39804
|
}
|
|
39805
39805
|
render = /* @__PURE__ */ function(_this) {
|
|
39806
39806
|
return function(element, obj) {
|
|
39807
|
-
var
|
|
39807
|
+
var attr2, child, entry, index, key, value;
|
|
39808
39808
|
if (typeof obj !== "object") {
|
|
39809
39809
|
if (_this.options.cdata && requiresCDATA(obj)) {
|
|
39810
39810
|
element.raw(wrapCDATA(obj));
|
|
@@ -39826,9 +39826,9 @@ var require_builder = __commonJS({
|
|
|
39826
39826
|
child = obj[key];
|
|
39827
39827
|
if (key === attrkey) {
|
|
39828
39828
|
if (typeof child === "object") {
|
|
39829
|
-
for (
|
|
39830
|
-
value = child[
|
|
39831
|
-
element = element.att(
|
|
39829
|
+
for (attr2 in child) {
|
|
39830
|
+
value = child[attr2];
|
|
39831
|
+
element = element.att(attr2, value);
|
|
39832
39832
|
}
|
|
39833
39833
|
}
|
|
39834
39834
|
} else if (key === charkey) {
|
|
@@ -69277,6 +69277,90 @@ function allowedInReadOnly(method, pathname) {
|
|
|
69277
69277
|
}
|
|
69278
69278
|
var READ_ONLY_ERROR = { error: "server is read-only", readOnly: true };
|
|
69279
69279
|
|
|
69280
|
+
// src/server/seo.ts
|
|
69281
|
+
function isChapter(format) {
|
|
69282
|
+
return format === "x-yamlover-chapter" || format === "x-yamlover-task";
|
|
69283
|
+
}
|
|
69284
|
+
function slashOfStorePath(p2) {
|
|
69285
|
+
return segsOfPath(p2).map((s2) => encodeURIComponent(segToken(s2))).join("/");
|
|
69286
|
+
}
|
|
69287
|
+
var SITEMAP_MAX_URLS = 5e4;
|
|
69288
|
+
function collectPages(s2, meta, max = SITEMAP_MAX_URLS) {
|
|
69289
|
+
const pages = [];
|
|
69290
|
+
const page = (path12) => ({
|
|
69291
|
+
path: path12,
|
|
69292
|
+
slash: slashOfStorePath(path12),
|
|
69293
|
+
title: meta.title(path12),
|
|
69294
|
+
description: meta.description(path12)
|
|
69295
|
+
});
|
|
69296
|
+
pages.push(page(":"));
|
|
69297
|
+
let truncated = false;
|
|
69298
|
+
const walk = (rows, inBook) => {
|
|
69299
|
+
for (const r2 of rows) {
|
|
69300
|
+
if (pages.length >= max) {
|
|
69301
|
+
truncated = true;
|
|
69302
|
+
return;
|
|
69303
|
+
}
|
|
69304
|
+
const chapter = isChapter(r2.format);
|
|
69305
|
+
if (chapter) pages.push(page(r2.path));
|
|
69306
|
+
if (chapter || !inBook) walk(r2.children, inBook || chapter);
|
|
69307
|
+
}
|
|
69308
|
+
};
|
|
69309
|
+
walk(s2.toc(":"), isChapter(meta.format(":")));
|
|
69310
|
+
return { pages, truncated };
|
|
69311
|
+
}
|
|
69312
|
+
var XML_ESC = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
69313
|
+
var xml = (t3) => t3.replace(/[&<>"']/g, (c3) => XML_ESC[c3]);
|
|
69314
|
+
function pageUrl(origin, basePath, slash) {
|
|
69315
|
+
return `${origin}${basePath}/${slash}`.replace(/\/+$/, "/");
|
|
69316
|
+
}
|
|
69317
|
+
function sitemapXml(origin, basePath, pages, truncated = false) {
|
|
69318
|
+
const urls = pages.map((p2) => ` <url><loc>${xml(pageUrl(origin, basePath, p2.slash))}</loc></url>`).join("\n");
|
|
69319
|
+
const note = truncated ? `
|
|
69320
|
+
<!-- truncated at ${SITEMAP_MAX_URLS} URLs, the sitemap protocol's per-file limit -->` : "";
|
|
69321
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
69322
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
69323
|
+
${urls}${note}
|
|
69324
|
+
</urlset>
|
|
69325
|
+
`;
|
|
69326
|
+
}
|
|
69327
|
+
function robotsTxt(sitemapUrl) {
|
|
69328
|
+
return [
|
|
69329
|
+
"# Do NOT disallow /api/ \u2014 this is a single-page app and its text is fetched from",
|
|
69330
|
+
"# /api/content at render time. A crawler denied that endpoint indexes blank pages.",
|
|
69331
|
+
"User-agent: *",
|
|
69332
|
+
"Allow: /",
|
|
69333
|
+
"",
|
|
69334
|
+
`Sitemap: ${sitemapUrl}`,
|
|
69335
|
+
""
|
|
69336
|
+
].join("\n");
|
|
69337
|
+
}
|
|
69338
|
+
var HTML_ESC = { "&": "&", "<": "<", ">": ">", '"': """ };
|
|
69339
|
+
var attr = (t3) => t3.replace(/[&<>"]/g, (c3) => HTML_ESC[c3]);
|
|
69340
|
+
var DESC_MAX = 300;
|
|
69341
|
+
function pageTitle(title, tokens, siteName) {
|
|
69342
|
+
const own = title?.trim() || tokens[tokens.length - 1] || siteName;
|
|
69343
|
+
if (tokens.length === 0) return own;
|
|
69344
|
+
return `${own} - ${siteName}${tokens.slice(0, -1).map((t3) => `: ${t3}`).join("")}`;
|
|
69345
|
+
}
|
|
69346
|
+
function headTags(opts) {
|
|
69347
|
+
const full = opts.title;
|
|
69348
|
+
const desc = opts.description?.trim().replace(/\s+/g, " ").slice(0, DESC_MAX);
|
|
69349
|
+
const tags = [
|
|
69350
|
+
`<title>${attr(full)}</title>`,
|
|
69351
|
+
`<link rel="canonical" href="${attr(opts.canonical)}">`,
|
|
69352
|
+
`<meta property="og:title" content="${attr(full)}">`,
|
|
69353
|
+
`<meta property="og:url" content="${attr(opts.canonical)}">`,
|
|
69354
|
+
`<meta property="og:type" content="article">`,
|
|
69355
|
+
`<meta property="og:site_name" content="${attr(opts.siteName)}">`
|
|
69356
|
+
];
|
|
69357
|
+
if (desc) {
|
|
69358
|
+
tags.splice(1, 0, `<meta name="description" content="${attr(desc)}">`);
|
|
69359
|
+
tags.push(`<meta property="og:description" content="${attr(desc)}">`);
|
|
69360
|
+
}
|
|
69361
|
+
return tags.join("");
|
|
69362
|
+
}
|
|
69363
|
+
|
|
69280
69364
|
// src/server/engine-api.ts
|
|
69281
69365
|
var LINK_KEY = "$yamloverLink";
|
|
69282
69366
|
var REF_KEY = "$yamloverRef";
|
|
@@ -70073,8 +70157,41 @@ function createHandlers(dataRoot, opts = {}) {
|
|
|
70073
70157
|
sendJson(res, 400, { error: exc.message || String(exc) });
|
|
70074
70158
|
}
|
|
70075
70159
|
};
|
|
70160
|
+
const pageMeta = {
|
|
70161
|
+
title: (p2) => titleOf(store0, p2),
|
|
70162
|
+
description: (p2) => descriptionOf(store0, p2),
|
|
70163
|
+
format: (p2) => store0.node(p2)?.format ?? null
|
|
70164
|
+
};
|
|
70165
|
+
const seo = {
|
|
70166
|
+
robots: (sitemapUrl) => robotsTxt(sitemapUrl),
|
|
70167
|
+
sitemap: (origin, basePath) => {
|
|
70168
|
+
const { pages, truncated } = collectPages(store0, pageMeta);
|
|
70169
|
+
return sitemapXml(origin, basePath, pages, truncated);
|
|
70170
|
+
},
|
|
70171
|
+
/** The `<head>` tags for ONE client route (a slash URL path, base already stripped), or ""
|
|
70172
|
+
* when the path names no node — the common case, and not an error: the shell answers every
|
|
70173
|
+
* path, `/.browser/settings.yo` included, which has no node by design. */
|
|
70174
|
+
head: (pathname, canonical) => {
|
|
70175
|
+
try {
|
|
70176
|
+
const segs = canonSegs(store0, slashToSegs(pathname), false);
|
|
70177
|
+
const p2 = storePath(segs);
|
|
70178
|
+
if (!store0.node(p2)) return "";
|
|
70179
|
+
const siteName = titleOf(store0, ":") || rootName;
|
|
70180
|
+
return headTags({
|
|
70181
|
+
// the same tokens the client's own title effect walks — segToken, not the raw segment
|
|
70182
|
+
title: pageTitle(titleOf(store0, p2), segs.map((g) => segToken(g)), siteName),
|
|
70183
|
+
description: descriptionOf(store0, p2),
|
|
70184
|
+
canonical,
|
|
70185
|
+
siteName
|
|
70186
|
+
});
|
|
70187
|
+
} catch {
|
|
70188
|
+
return "";
|
|
70189
|
+
}
|
|
70190
|
+
}
|
|
70191
|
+
};
|
|
70076
70192
|
return Object.assign(handler, {
|
|
70077
70193
|
ready,
|
|
70194
|
+
seo,
|
|
70078
70195
|
close: () => {
|
|
70079
70196
|
if (closed) return;
|
|
70080
70197
|
closed = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yamlover",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.54",
|
|
4
4
|
"description": "A local-first, editable knowledge graph for humans and LLMs: npx yamlover <root> serves a browser UI over a plain-text directory, with an editor, live queries, pointers, and an LLM-agent API.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|