Repository navigation
启用 MCP 并修复热门列表和访问统计 #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { build } from 'esbuild'; | ||
| import { mkdtemp, rm } from 'node:fs/promises'; | ||
| import { tmpdir } from 'node:os'; | ||
| import { join } from 'node:path'; | ||
| import { spawnSync } from 'node:child_process'; | ||
| const dir = await mkdtemp(join(tmpdir(), 'vireo-services-')); | ||
| try { | ||
| const outfile = join(dir, 'services.test.mjs'); | ||
| await build({ entryPoints: ['tests/services.test.ts'], outfile, bundle: true, platform: 'node', format: 'esm', banner: { js: "import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);" } }); | ||
| process.exitCode = spawnSync(process.execPath, ['--test', outfile], { stdio: 'inherit' }).status ?? 1; | ||
| } finally { await rm(dir, { recursive: true, force: true }); } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import { trackPageView } from '../utils/analytics'; | ||
| import { ui } from '../i18n/server'; | ||
| import { Hono, type Context } from 'hono'; | ||
| import type { Env, Page, Revision, User } from '../types'; | ||
|
|
@@ -1537,7 +1538,13 @@ wiki.get('/w/wiki-stats', async (c) => { | |
| * - 리다이렉트 처리: 문서가 없고 리다이렉트가 존재하면 대상 문서 반환 (redirected_from 포함) | ||
| * - 비공개 문서: 관리자만 접근 가능 | ||
| */ | ||
| wiki.get('/w/:slug', async (c) => { | ||
| wiki.get('/w/:slug', async (c, next) => { | ||
| const start = Date.now(); await next(); | ||
| if (c.res.status === 200 && c.req.query('for_edit') !== 'true') { | ||
| const result = await c.res.clone().json() as {slug?:string; id?:number; is_private?:boolean; deleted_at?:number}; | ||
| if (result.id && result.slug && !result.is_private && !result.deleted_at) trackPageView(c, result.slug, Date.now()-start); | ||
|
Comment on lines
+1541
to
+1545
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When a visitor opens or refreshes Useful? React with 👍 / 👎.
Comment on lines
+1544
to
+1545
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an authorized user reads a private page that redirects to a public page, the response contains the public target's Useful? React with 👍 / 👎.
Comment on lines
+1543
to
+1545
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Checking only Useful? React with 👍 / 👎. |
||
| } | ||
| }, async (c) => { | ||
| if (c.env.WIKI_VISIBILITY === 'closed' && !c.get('user')) { | ||
| return c.json({ error: ui("m_640f50ae9c6b8e41") }, 401); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In environments without complete Analytics Engine configuration—including the checked production configuration—this branch executes the aggregate D1 query and returns
no-store, so it never populates the cache checked immediately above. Sincesrc/client/common.tsnow polls this endpoint every 30 seconds in every visible tab, every active user causes two aggregate scans per minute; traffic therefore scales directly into D1 rows-read and latency even though a shared cache with a roughly 30-second TTL would preserve the requested refresh cadence.Useful? React with 👍 / 👎.