@xingwangzhe/stalux 1.55.6 → 1.55.7
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/package.json +1 -1
- package/src/pages/words.md.ts +7 -2
- package/src/utils/ai-discovery.ts +17 -3
- package/src/utils/content-index.ts +13 -4
package/package.json
CHANGED
package/src/pages/words.md.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
isMarkdownExportEnabled,
|
|
3
|
+
loadConfig,
|
|
4
|
+
renderWordsMd,
|
|
5
|
+
resolveSiteTimezone,
|
|
6
|
+
} from "@utils/ai-discovery";
|
|
2
7
|
import type { APIRoute } from "astro";
|
|
3
8
|
|
|
4
9
|
export const prerender = true;
|
|
@@ -7,7 +12,7 @@ export const GET: APIRoute = async () => {
|
|
|
7
12
|
const config = await loadConfig();
|
|
8
13
|
if (!isMarkdownExportEnabled(config)) return new Response(null, { status: 404 });
|
|
9
14
|
|
|
10
|
-
const text = await renderWordsMd();
|
|
15
|
+
const text = await renderWordsMd(resolveSiteTimezone(config));
|
|
11
16
|
return new Response(text, {
|
|
12
17
|
headers: {
|
|
13
18
|
"Content-Type": "text/markdown; charset=utf-8",
|
|
@@ -52,6 +52,17 @@ function getSiteConfig(config: ConfigMap): Record<string, unknown> {
|
|
|
52
52
|
return config.get("site") ?? {};
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* 站点 IANA 时区(site.yml 的 timezone)。
|
|
57
|
+
*
|
|
58
|
+
* 与 `getSiteData()` 的缺省值保持一致:日期排序必须按站点时区解析无时区串,
|
|
59
|
+
* 否则会在 UTC 构建机上整体偏移,混写带偏移日期时排序还会错乱。
|
|
60
|
+
*/
|
|
61
|
+
export function resolveSiteTimezone(config: ConfigMap): string {
|
|
62
|
+
const value = getSiteConfig(config).timezone;
|
|
63
|
+
return typeof value === "string" && value.length > 0 ? value : "Asia/Shanghai";
|
|
64
|
+
}
|
|
65
|
+
|
|
55
66
|
/**
|
|
56
67
|
* 解析站点根 URL。
|
|
57
68
|
*
|
|
@@ -254,9 +265,12 @@ export async function renderAboutMd(site: string): Promise<string> {
|
|
|
254
265
|
}
|
|
255
266
|
|
|
256
267
|
/** 渲染 Words 页 Markdown */
|
|
257
|
-
export async function renderWordsMd(): Promise<string> {
|
|
268
|
+
export async function renderWordsMd(timeZone = "Asia/Shanghai"): Promise<string> {
|
|
258
269
|
const words = await getCollection("words", ({ data }) => !data.draft);
|
|
259
|
-
|
|
270
|
+
// 按站点时区解析无时区日期串,避免构建机时区影响排序
|
|
271
|
+
words.sort(
|
|
272
|
+
(a, b) => toTimestamp(b.data.date || 0, timeZone) - toTimestamp(a.data.date || 0, timeZone),
|
|
273
|
+
);
|
|
260
274
|
const lines: string[] = [];
|
|
261
275
|
lines.push("# Words");
|
|
262
276
|
lines.push("");
|
|
@@ -558,7 +572,7 @@ export async function renderLlmsFullTxt(
|
|
|
558
572
|
sections.push(await renderAboutMd(site));
|
|
559
573
|
sections.push("---");
|
|
560
574
|
sections.push("");
|
|
561
|
-
sections.push(await renderWordsMd());
|
|
575
|
+
sections.push(await renderWordsMd(resolveSiteTimezone(config)));
|
|
562
576
|
sections.push("---");
|
|
563
577
|
sections.push("");
|
|
564
578
|
sections.push(renderLinksMd(config, site, t));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CollectionEntry, getCollection } from "astro:content";
|
|
2
2
|
import type { AstroRuntimeLogger } from "astro";
|
|
3
|
+
import { getSiteData } from "./config-utils";
|
|
3
4
|
import { toTimestamp } from "./dayjs";
|
|
4
5
|
import { logDetail } from "./diagnostics";
|
|
5
6
|
|
|
@@ -93,13 +94,17 @@ function finalizeTaxonomy<T extends IndexablePost>(
|
|
|
93
94
|
*/
|
|
94
95
|
export function buildPostContentIndex<T extends IndexablePost>(
|
|
95
96
|
sourcePosts: readonly T[],
|
|
97
|
+
timeZone?: string,
|
|
96
98
|
): PostContentIndex<T> {
|
|
97
99
|
const times = new Map<T, { date: number; updated: number }>();
|
|
98
100
|
for (const post of sourcePosts) {
|
|
99
|
-
|
|
101
|
+
// 无时区日期串必须按站点时区解析。漏传会按构建机器时区解释:
|
|
102
|
+
// UTC 构建机上整体偏 8 小时;一旦与带偏移的日期混写,两者相差 8 小时,
|
|
103
|
+
// 排序就会错——首页顺序、上一篇/下一篇、分类「最新」归属都跟着错。
|
|
104
|
+
const date = toTimestamp(post.data.date, timeZone);
|
|
100
105
|
times.set(post, {
|
|
101
106
|
date,
|
|
102
|
-
updated: post.data.updated == null ? date : toTimestamp(post.data.updated),
|
|
107
|
+
updated: post.data.updated == null ? date : toTimestamp(post.data.updated, timeZone),
|
|
103
108
|
});
|
|
104
109
|
}
|
|
105
110
|
const posts = sourcePosts.toSorted(
|
|
@@ -139,9 +144,13 @@ let productionIndex: Promise<PostContentIndex<PostEntry>> | undefined;
|
|
|
139
144
|
async function loadPostContentIndex(
|
|
140
145
|
logger?: AstroRuntimeLogger,
|
|
141
146
|
): Promise<PostContentIndex<PostEntry>> {
|
|
142
|
-
const posts = await
|
|
147
|
+
const [posts, configEntries] = await Promise.all([
|
|
148
|
+
getCollection("posts", ({ data }) => !data.draft),
|
|
149
|
+
getCollection("config"),
|
|
150
|
+
]);
|
|
143
151
|
const started = performance.now();
|
|
144
|
-
|
|
152
|
+
// 站点时区与 feed / semantic-time / archives 同源(site.yml,缺省 Asia/Shanghai)
|
|
153
|
+
const index = buildPostContentIndex(posts, getSiteData(configEntries).timezone);
|
|
145
154
|
logDetail(
|
|
146
155
|
logger,
|
|
147
156
|
"content-index",
|