wikimem 0.8.2 → 0.8.3
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/dist/cli/commands/improve.d.ts.map +1 -1
- package/dist/cli/commands/improve.js +4 -2
- package/dist/cli/commands/improve.js.map +1 -1
- package/dist/core/improve.js +151 -20
- package/dist/core/improve.js.map +1 -1
- package/dist/core/ingest.js +18 -18
- package/dist/core/ingest.js.map +1 -1
- package/dist/core/observer.d.ts.map +1 -1
- package/dist/core/observer.js +6 -12
- package/dist/core/observer.js.map +1 -1
- package/dist/core/query.d.ts.map +1 -1
- package/dist/core/query.js +4 -13
- package/dist/core/query.js.map +1 -1
- package/dist/core/scrape.js +44 -7
- package/dist/core/scrape.js.map +1 -1
- package/dist/providers/index.d.ts +10 -1
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +38 -3
- package/dist/providers/index.js.map +1 -1
- package/dist/web/public/index.html +44 -24
- package/package.json +1 -1
- package/src/web/public/index.html +44 -24
package/dist/core/query.js
CHANGED
|
@@ -45,19 +45,10 @@ ${pageContents.join('\n\n---\n\n').substring(0, 20000)}
|
|
|
45
45
|
## Instructions
|
|
46
46
|
Answer the question based on the wiki content above. Use [[wikilinks]] when referencing pages. Cite your sources. If the wiki doesn't contain enough information, say so clearly.`;
|
|
47
47
|
const systemPrompt = 'You are a knowledgeable wiki assistant. Answer questions by synthesizing information from the wiki pages provided. Always cite sources using [[wikilinks]]. Be concise and accurate.';
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const { runClaudeCode } = await import('./claude-code.js');
|
|
53
|
-
responseContent = await runClaudeCode(systemPrompt, prompt, { maxTokens: 4096 });
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
const response = await provider.chat([
|
|
57
|
-
{ role: 'user', content: prompt },
|
|
58
|
-
], { systemPrompt, maxTokens: 4096 });
|
|
59
|
-
responseContent = response.content;
|
|
60
|
-
}
|
|
48
|
+
const response = await provider.chat([
|
|
49
|
+
{ role: 'user', content: prompt },
|
|
50
|
+
], { systemPrompt, maxTokens: 4096 });
|
|
51
|
+
const responseContent = response.content;
|
|
61
52
|
// Step 4: Optionally file the answer back into the wiki
|
|
62
53
|
let filedAs;
|
|
63
54
|
if (options.fileBack) {
|
package/dist/core/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/core/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAc7C,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAgB,EAChB,MAAmB,EACnB,QAAqB,EACrB,OAAqB;IAErB,0CAA0C;IAC1C,MAAM,YAAY,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC;QAC/C,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC;QACzC,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE;QAC1D,IAAI,EAAE,OAAO,CAAC,UAAU,IAAI,MAAM;QAClC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC;IAEH,kDAAkD;IAClD,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,MAAM,gBAAgB,GAAa,EAAE,CAAC;IAEtC,KAAK,MAAM,QAAQ,IAAI,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACpC,YAAY,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACvD,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,wBAAwB;QAC1B,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC;QAC1C,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC;QAC1C,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,MAAM,GAAG;;;EAGf,QAAQ;;;EAGR,YAAY,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;;;EAG/B,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC;;;kLAG4H,CAAC;IAEjL,MAAM,YAAY,GAAG,sLAAsL,CAAC;IAE5M,MAAM,
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../src/core/query.ts"],"names":[],"mappings":"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"}
|
package/dist/core/scrape.js
CHANGED
|
@@ -47,16 +47,32 @@ async function scrapeRss(source, destDir) {
|
|
|
47
47
|
throw new Error(`HTTP ${response.status} from ${source.url}`);
|
|
48
48
|
}
|
|
49
49
|
const text = await response.text();
|
|
50
|
-
//
|
|
51
|
-
const items = text.match(/<item>[\s\S]*?<\/item>/g)
|
|
50
|
+
// Parse RSS/Atom items — supports <item> (RSS 2.0) and <entry> (Atom)
|
|
51
|
+
const items = text.match(/<item>[\s\S]*?<\/item>/g)
|
|
52
|
+
?? text.match(/<entry>[\s\S]*?<\/entry>/g)
|
|
53
|
+
?? [];
|
|
52
54
|
let count = 0;
|
|
53
55
|
for (const item of items.slice(0, 10)) {
|
|
54
56
|
const rawTitle = item.match(/<title>([\s\S]*?)<\/title>/)?.[1] ?? 'Untitled';
|
|
55
57
|
const title = stripCdata(rawTitle).trim();
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
// RSS uses <link>url</link>, Atom uses <link href="url"/>
|
|
59
|
+
const link = item.match(/<link>\s*([\s\S]*?)\s*<\/link>/)?.[1]
|
|
60
|
+
?? item.match(/<link[^>]+href="([^"]+)"/)?.[1]
|
|
61
|
+
?? '';
|
|
62
|
+
// Prefer <content:encoded> (full article) over <description> (summary)
|
|
63
|
+
const rawBody = item.match(/<content:encoded>([\s\S]*?)<\/content:encoded>/)?.[1]
|
|
64
|
+
?? item.match(/<content[^>]*>([\s\S]*?)<\/content>/)?.[1]
|
|
65
|
+
?? item.match(/<description>([\s\S]*?)<\/description>/)?.[1]
|
|
66
|
+
?? '';
|
|
67
|
+
const body = stripHtml(stripCdata(rawBody));
|
|
68
|
+
const pubDate = item.match(/<pubDate>([\s\S]*?)<\/pubDate>/)?.[1]
|
|
69
|
+
?? item.match(/<published>([\s\S]*?)<\/published>/)?.[1]
|
|
70
|
+
?? '';
|
|
71
|
+
const header = [`# ${title}`, '', `Source: ${link}`];
|
|
72
|
+
if (pubDate)
|
|
73
|
+
header.push(`Date: ${pubDate.trim()}`);
|
|
74
|
+
header.push('');
|
|
75
|
+
const content = header.join('\n') + body;
|
|
60
76
|
const fileName = `${slugify(title.substring(0, 60))}.md`;
|
|
61
77
|
writeFileSync(join(destDir, fileName), content, 'utf-8');
|
|
62
78
|
count++;
|
|
@@ -109,7 +125,28 @@ async function scrapeUrl(source, destDir) {
|
|
|
109
125
|
function stripCdata(text) {
|
|
110
126
|
return text.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, '$1').trim();
|
|
111
127
|
}
|
|
128
|
+
const HTML_ENTITIES = {
|
|
129
|
+
'&': '&', '<': '<', '>': '>', '"': '"', ''': "'",
|
|
130
|
+
''': "'", ' ': ' ', '—': '—', '–': '–',
|
|
131
|
+
'“': '\u201C', '”': '\u201D', '‘': '\u2018', '’': '\u2019',
|
|
132
|
+
'…': '…', '•': '•', '©': '©', '®': '®', '™': '™',
|
|
133
|
+
};
|
|
112
134
|
function stripHtml(html) {
|
|
113
|
-
|
|
135
|
+
let text = html;
|
|
136
|
+
// Remove script, style, and noscript blocks entirely
|
|
137
|
+
text = text.replace(/<(script|style|noscript)[^>]*>[\s\S]*?<\/\1>/gi, '');
|
|
138
|
+
// Convert <br>, <p>, <div>, <li>, headings to newlines
|
|
139
|
+
text = text.replace(/<\/?(br|p|div|li|h[1-6]|tr|blockquote)[^>]*>/gi, '\n');
|
|
140
|
+
// Remove remaining HTML tags
|
|
141
|
+
text = text.replace(/<[^>]*>/g, '');
|
|
142
|
+
// Decode numeric entities ({ and {)
|
|
143
|
+
text = text.replace(/&#x([0-9a-f]+);/gi, (_, hex) => String.fromCharCode(parseInt(hex, 16)));
|
|
144
|
+
text = text.replace(/&#(\d+);/g, (_, dec) => String.fromCharCode(parseInt(dec, 10)));
|
|
145
|
+
// Decode named entities
|
|
146
|
+
text = text.replace(/&[a-z]+;/gi, (ent) => HTML_ENTITIES[ent.toLowerCase()] ?? ent);
|
|
147
|
+
// Normalize whitespace: collapse runs of spaces, trim blank lines
|
|
148
|
+
text = text.replace(/[ \t]+/g, ' ');
|
|
149
|
+
text = text.replace(/\n{3,}/g, '\n\n');
|
|
150
|
+
return text.trim();
|
|
114
151
|
}
|
|
115
152
|
//# sourceMappingURL=scrape.js.map
|
package/dist/core/scrape.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scrape.js","sourceRoot":"","sources":["../../src/core/scrape.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"scrape.js","sourceRoot":"","sources":["../../src/core/scrape.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import type { LLMProvider, ProviderChainConfig, ProviderChainId } from './types.js';
|
|
1
|
+
import type { LLMProvider, LLMOptions, LLMMessage, LLMResponse, ProviderChainConfig, ProviderChainId } from './types.js';
|
|
2
2
|
import type { UserConfig } from '../core/config.js';
|
|
3
|
+
/**
|
|
4
|
+
* LLMProvider backed by the Claude Code CLI (`claude -p`).
|
|
5
|
+
* Uses the caller's Claude Code subscription — no API key needed.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ClaudeCodeProvider implements LLMProvider {
|
|
8
|
+
readonly name = "claude-code";
|
|
9
|
+
chat(messages: LLMMessage[], options?: LLMOptions): Promise<LLMResponse>;
|
|
10
|
+
isAvailable(): Promise<boolean>;
|
|
11
|
+
}
|
|
3
12
|
export declare function normalizeProviderId(name: string): ProviderChainId | null;
|
|
4
13
|
/**
|
|
5
14
|
* Build a fallback chain: try `primary`, then each entry in `fallback`, skipping providers without keys.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,eAAe,EAChB,MAAM,YAAY,CAAC;AAIpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD;;;GAGG;AACH,qBAAa,kBAAmB,YAAW,WAAW;IACpD,QAAQ,CAAC,IAAI,iBAAiB;IAExB,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBxE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAGtC;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAMxE;AA4ED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,WAAW,CAY5E;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D,WAAW,CAyBb;AAaD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,UAAU,EACtB,IAAI,CAAC,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,WAAW,CA0Cb"}
|
package/dist/providers/index.js
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
import { ClaudeProvider } from './claude.js';
|
|
2
2
|
import { OpenAIProvider } from './openai.js';
|
|
3
3
|
import { OllamaProvider } from './ollama.js';
|
|
4
|
+
import { runClaudeCode, isClaudeCodeAvailable } from '../core/claude-code.js';
|
|
5
|
+
/**
|
|
6
|
+
* LLMProvider backed by the Claude Code CLI (`claude -p`).
|
|
7
|
+
* Uses the caller's Claude Code subscription — no API key needed.
|
|
8
|
+
*/
|
|
9
|
+
export class ClaudeCodeProvider {
|
|
10
|
+
name = 'claude-code';
|
|
11
|
+
async chat(messages, options) {
|
|
12
|
+
const systemPrompt = options?.systemPrompt ??
|
|
13
|
+
messages.find((m) => m.role === 'system')?.content ??
|
|
14
|
+
'';
|
|
15
|
+
const userContent = messages
|
|
16
|
+
.filter((m) => m.role === 'user')
|
|
17
|
+
.map((m) => m.content)
|
|
18
|
+
.join('\n\n');
|
|
19
|
+
const text = await runClaudeCode(systemPrompt, userContent, {
|
|
20
|
+
maxTokens: options?.maxTokens,
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
content: text,
|
|
24
|
+
model: 'claude-code-cli',
|
|
25
|
+
tokensUsed: { input: 0, output: 0 },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async isAvailable() {
|
|
29
|
+
return isClaudeCodeAvailable();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
4
32
|
export function normalizeProviderId(name) {
|
|
5
33
|
const n = name.trim().toLowerCase();
|
|
6
34
|
if (n === 'claude' || n === 'anthropic')
|
|
@@ -107,12 +135,16 @@ export function createProvider(name, options) {
|
|
|
107
135
|
case 'ollama':
|
|
108
136
|
case 'local':
|
|
109
137
|
return new OllamaProvider(options?.model, options?.baseUrl);
|
|
138
|
+
case 'claude-code':
|
|
139
|
+
case 'cc':
|
|
140
|
+
return new ClaudeCodeProvider();
|
|
110
141
|
default:
|
|
111
142
|
throw new Error(`Unknown provider: "${name}".\n` +
|
|
112
143
|
'Supported providers:\n' +
|
|
113
|
-
' claude
|
|
114
|
-
' openai
|
|
115
|
-
' ollama
|
|
144
|
+
' claude — Anthropic (requires ANTHROPIC_API_KEY)\n' +
|
|
145
|
+
' openai — OpenAI (requires OPENAI_API_KEY)\n' +
|
|
146
|
+
' ollama — Local models (requires Ollama running)\n' +
|
|
147
|
+
' claude-code — Claude Code CLI (uses your subscription)\n' +
|
|
116
148
|
'Set in config.yaml: provider: claude');
|
|
117
149
|
}
|
|
118
150
|
}
|
|
@@ -133,6 +165,9 @@ function legacyApiKeyForProvider(provider, apiKey) {
|
|
|
133
165
|
* @param opts.providerOverride — e.g. CLI `-p openai` forces a single provider (no chain).
|
|
134
166
|
*/
|
|
135
167
|
export function createProviderFromUserConfig(userConfig, opts) {
|
|
168
|
+
if (userConfig.llm_mode === 'claude-code' && !opts?.providerOverride) {
|
|
169
|
+
return new ClaudeCodeProvider();
|
|
170
|
+
}
|
|
136
171
|
const model = opts?.model ?? userConfig.model;
|
|
137
172
|
if (opts?.providerOverride) {
|
|
138
173
|
return createProvider(opts.providerOverride, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2633,7 +2633,7 @@
|
|
|
2633
2633
|
.tl-play-btn.playing { background:var(--accent); color:var(--bg-deep); border-color:var(--accent); }
|
|
2634
2634
|
.tl-speed { background:var(--bg-card); border:1px solid var(--border); color:var(--text); padding:4px 6px; border-radius:var(--radius); font-size:11px; cursor:pointer; }
|
|
2635
2635
|
.tl-slider-wrap { flex:1; display:flex; flex-direction:column; gap:2px; }
|
|
2636
|
-
.tl-slider { width:100%; height:6px; -webkit-appearance:none; appearance:none; background:linear-gradient(to right, var(--accent) 0%, var(--accent) var(--slider-pct, 0%), var(--border) var(--slider-pct, 0%), var(--border) 100%); border-radius:3px; outline:none; cursor:pointer;
|
|
2636
|
+
.tl-slider { width:100%; height:6px; -webkit-appearance:none; appearance:none; background:linear-gradient(to right, var(--accent) 0%, var(--accent) var(--slider-pct, 0%), var(--border) var(--slider-pct, 0%), var(--border) 100%); border-radius:3px; outline:none; cursor:pointer; }
|
|
2637
2637
|
.tl-slider::-webkit-slider-thumb { -webkit-appearance:none; width:16px; height:16px; border-radius:50%; background:var(--text-bright); cursor:grab; box-shadow:0 1px 6px rgba(0,0,0,0.4), 0 0 0 2px var(--accent); transition:transform 0.1s ease, box-shadow 0.15s ease; }
|
|
2638
2638
|
.tl-slider::-webkit-slider-thumb:hover { transform:scale(1.2); box-shadow:0 1px 8px rgba(0,0,0,0.5), 0 0 0 3px var(--accent); }
|
|
2639
2639
|
.tl-slider::-webkit-slider-thumb:active { cursor:grabbing; transform:scale(1.1); }
|
|
@@ -8897,6 +8897,7 @@
|
|
|
8897
8897
|
_tlPlayRaf: null,
|
|
8898
8898
|
_tlDragging: false,
|
|
8899
8899
|
_tlRenderDebounce: null,
|
|
8900
|
+
_tlJustScrubbed: false,
|
|
8900
8901
|
};
|
|
8901
8902
|
|
|
8902
8903
|
function railTimelapseClick() {
|
|
@@ -9454,8 +9455,8 @@
|
|
|
9454
9455
|
if(o) {
|
|
9455
9456
|
n.x = o.x;
|
|
9456
9457
|
n.y = o.y;
|
|
9457
|
-
n.vx = (o.vx || 0) * 0.32;
|
|
9458
|
-
n.vy = (o.vy || 0) * 0.32;
|
|
9458
|
+
n.vx = (o.vx || 0) * (tlState.playing ? 0.1 : 0.32);
|
|
9459
|
+
n.vy = (o.vy || 0) * (tlState.playing ? 0.1 : 0.32);
|
|
9459
9460
|
} else if(p) {
|
|
9460
9461
|
n.x = p.x;
|
|
9461
9462
|
n.y = p.y;
|
|
@@ -9469,7 +9470,10 @@
|
|
|
9469
9470
|
sim.force('charge', d3.forceManyBody().strength(-220));
|
|
9470
9471
|
sim.force('center', d3.forceCenter(width/2, height/2));
|
|
9471
9472
|
sim.force('collision', d3.forceCollide().radius(d => isHub(d)?26:18));
|
|
9472
|
-
|
|
9473
|
+
const scrubAlpha = tlState.playing ? 0.08 : (tlState._tlJustScrubbed ? 0.15 : 0.3);
|
|
9474
|
+
const scrubDecay = tlState.playing ? 0.04 : (tlState._tlJustScrubbed ? 0.035 : 0.0228);
|
|
9475
|
+
sim.alpha(scrubAlpha).alphaDecay(scrubDecay).restart();
|
|
9476
|
+
tlState._tlJustScrubbed = false;
|
|
9473
9477
|
} else {
|
|
9474
9478
|
if(tlState._tlGraphSim) {
|
|
9475
9479
|
tlState._tlGraphSim.stop();
|
|
@@ -9486,13 +9490,16 @@
|
|
|
9486
9490
|
}
|
|
9487
9491
|
|
|
9488
9492
|
const soft = reuseSim;
|
|
9493
|
+
const fast = tlState.playing; // ultra-fast transitions during playback
|
|
9489
9494
|
|
|
9490
9495
|
const lk = g.select('g.tl-links').selectAll('line').data(data.links, linkKey);
|
|
9491
|
-
lk.exit().transition().duration(soft ? 200 : 300).attr('stroke-opacity',0).remove();
|
|
9496
|
+
lk.exit().transition().duration(fast ? 80 : soft ? 200 : 300).attr('stroke-opacity',0).remove();
|
|
9492
9497
|
const lkE = lk.enter().append('line')
|
|
9493
9498
|
.attr('stroke',cs('--border-subtle')).attr('stroke-width',0.8)
|
|
9494
|
-
.attr('stroke-opacity', soft ? 0.2 : 0.4);
|
|
9495
|
-
if(
|
|
9499
|
+
.attr('stroke-opacity', fast ? 0.35 : soft ? 0.2 : 0.4);
|
|
9500
|
+
if(fast) {
|
|
9501
|
+
lkE.transition().duration(120).attr('stroke-opacity',0.4);
|
|
9502
|
+
} else if(soft) {
|
|
9496
9503
|
lkE.transition().duration(380).attr('stroke-opacity',0.4);
|
|
9497
9504
|
} else {
|
|
9498
9505
|
lkE.attr('stroke-dasharray','500').attr('stroke-dashoffset','500')
|
|
@@ -9500,26 +9507,27 @@
|
|
|
9500
9507
|
.on('end', function(){ d3.select(this).attr('stroke-dasharray',null); });
|
|
9501
9508
|
}
|
|
9502
9509
|
const links = lkE.merge(lk);
|
|
9503
|
-
lk.transition().duration(soft ? 320 : 300).attr('stroke-opacity',0.4);
|
|
9510
|
+
lk.transition().duration(fast ? 100 : soft ? 320 : 300).attr('stroke-opacity',0.4);
|
|
9504
9511
|
|
|
9505
9512
|
const rg = g.select('g.tl-rings').selectAll('circle').data(data.nodes.filter(isHub), d=>d.id);
|
|
9506
|
-
rg.exit().transition().duration(soft ? 200 : 300).attr('opacity',0).remove();
|
|
9513
|
+
rg.exit().transition().duration(fast ? 60 : soft ? 200 : 300).attr('opacity',0).remove();
|
|
9507
9514
|
const rgE = rg.enter().append('circle')
|
|
9508
|
-
.attr('r',d=>nR(d)+5).attr('fill','none').attr('stroke','#d4a843').attr('stroke-width',1.5).attr('opacity', soft ? 0.35 : 0);
|
|
9509
|
-
rgE.transition().duration(soft ? 260 : 300).delay(soft ? 0 : 100).attr('opacity',0.5);
|
|
9515
|
+
.attr('r',d=>nR(d)+5).attr('fill','none').attr('stroke','#d4a843').attr('stroke-width',1.5).attr('opacity', fast ? 0.4 : soft ? 0.35 : 0);
|
|
9516
|
+
rgE.transition().duration(fast ? 100 : soft ? 260 : 300).delay(fast ? 0 : soft ? 0 : 100).attr('opacity',0.5);
|
|
9510
9517
|
const rings = rgE.merge(rg);
|
|
9511
|
-
rg.transition().duration(soft ? 300 : 300).attr('r',d=>nR(d)+5);
|
|
9518
|
+
rg.transition().duration(fast ? 80 : soft ? 300 : 300).attr('r',d=>nR(d)+5);
|
|
9512
9519
|
|
|
9513
9520
|
const nd = g.select('g.tl-nodes').selectAll('circle').data(data.nodes, d=>d.id);
|
|
9514
|
-
nd.exit().transition().duration(soft ? 220 : 300).attr('opacity',0).attr('r',0).remove();
|
|
9521
|
+
nd.exit().transition().duration(fast ? 60 : soft ? 220 : 300).attr('opacity',0).attr('r',0).remove();
|
|
9515
9522
|
const ndE = nd.enter().append('circle')
|
|
9516
|
-
.attr('r',
|
|
9523
|
+
.attr('r', fast ? d=>nR(d)*0.7 : soft ? d=>nR(d) : 0)
|
|
9524
|
+
.attr('opacity', fast ? 0.85 : soft ? 0.75 : 0)
|
|
9517
9525
|
.attr('fill',d=>cColor(d.community))
|
|
9518
9526
|
.attr('stroke',d=>isHub(d)?'#d4a843':cs('--bg'))
|
|
9519
9527
|
.attr('stroke-width',d=>isHub(d)?2:1.5)
|
|
9520
9528
|
.attr('cursor','pointer');
|
|
9521
|
-
ndE.transition().duration(soft ? 420 : 300).attr('r',d=>nR(d)).attr('opacity',1);
|
|
9522
|
-
nd.transition().duration(soft ? 450 : 300)
|
|
9529
|
+
ndE.transition().duration(fast ? 100 : soft ? 420 : 300).attr('r',d=>nR(d)).attr('opacity',1);
|
|
9530
|
+
nd.transition().duration(fast ? 120 : soft ? 450 : 300)
|
|
9523
9531
|
.attr('r',d=>nR(d)).attr('fill',d=>cColor(d.community))
|
|
9524
9532
|
.attr('stroke',d=>isHub(d)?'#d4a843':cs('--bg'));
|
|
9525
9533
|
const nodes = ndE.merge(nd);
|
|
@@ -9539,7 +9547,7 @@
|
|
|
9539
9547
|
.attr('fill',d=>isHub(d)?cs('--text-bright'):cs('--text-dim'))
|
|
9540
9548
|
.attr('text-anchor','middle').attr('dy',d=>nR(d)+13)
|
|
9541
9549
|
.attr('pointer-events','none').attr('opacity',0);
|
|
9542
|
-
lbE.transition().duration(300).delay(soft ? 40 : 200).attr('opacity',d=>isHub(d)?1:0);
|
|
9550
|
+
lbE.transition().duration(fast ? 80 : 300).delay(fast ? 0 : soft ? 40 : 200).attr('opacity',d=>isHub(d)?1:0);
|
|
9543
9551
|
const labels = lbE.merge(lb);
|
|
9544
9552
|
labels.text(d=>d.title.length>22?d.title.slice(0,20)+'\u2026':d.title);
|
|
9545
9553
|
|
|
@@ -9593,6 +9601,7 @@
|
|
|
9593
9601
|
|
|
9594
9602
|
let lastTime = null;
|
|
9595
9603
|
let fractionalIdx = tlState.currentIdx;
|
|
9604
|
+
let rendering = false;
|
|
9596
9605
|
|
|
9597
9606
|
function animate(ts) {
|
|
9598
9607
|
if(!tlState.playing || tlState._tlDragging) return;
|
|
@@ -9609,14 +9618,16 @@
|
|
|
9609
9618
|
slider.style.setProperty('--slider-pct', `${pct}%`);
|
|
9610
9619
|
slider.value = String(Math.min(Math.round(fractionalIdx), max));
|
|
9611
9620
|
|
|
9612
|
-
// Only render at integer commit boundaries
|
|
9621
|
+
// Only render at integer commit boundaries — skip if prior render still in flight
|
|
9613
9622
|
const targetIdx = Math.floor(fractionalIdx);
|
|
9614
|
-
if(targetIdx > tlState.currentIdx && targetIdx <= max) {
|
|
9615
|
-
|
|
9623
|
+
if(targetIdx > tlState.currentIdx && targetIdx <= max && !rendering) {
|
|
9624
|
+
rendering = true;
|
|
9625
|
+
renderTimelapseAt(targetIdx, { crossfade: false }).finally(() => { rendering = false; });
|
|
9616
9626
|
}
|
|
9617
9627
|
|
|
9618
9628
|
if(fractionalIdx >= max) {
|
|
9619
|
-
|
|
9629
|
+
rendering = true;
|
|
9630
|
+
renderTimelapseAt(max, { crossfade: false }).finally(() => { rendering = false; });
|
|
9620
9631
|
tlPause();
|
|
9621
9632
|
return;
|
|
9622
9633
|
}
|
|
@@ -9737,6 +9748,7 @@
|
|
|
9737
9748
|
cancelAnimationFrame(tlState._tlSliderRaf);
|
|
9738
9749
|
tlState._tlSliderRaf = null;
|
|
9739
9750
|
}
|
|
9751
|
+
tlState._tlJustScrubbed = true;
|
|
9740
9752
|
renderTimelapseAt(tlState._tlSliderPendingIdx != null ? tlState._tlSliderPendingIdx : tlState.currentIdx, { crossfade: true });
|
|
9741
9753
|
}
|
|
9742
9754
|
document.getElementById('tl-slider').addEventListener('pointerup', tlSliderPointerUp);
|
|
@@ -9750,18 +9762,26 @@
|
|
|
9750
9762
|
e.target.style.setProperty('--slider-pct', `${(val / max) * 100}%`);
|
|
9751
9763
|
tlState._tlSliderPendingIdx = val;
|
|
9752
9764
|
|
|
9753
|
-
// Update commit info
|
|
9765
|
+
// Update commit info + counter immediately (lightweight DOM updates, no debounce)
|
|
9754
9766
|
const commit = tlState.commits[val];
|
|
9755
9767
|
if(commit) {
|
|
9756
9768
|
document.getElementById('tl-label-current').textContent = `${val + 1} / ${tlState.commits.length}`;
|
|
9769
|
+
const date = new Date(commit.date);
|
|
9770
|
+
const dateStr = date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour:'2-digit',minute:'2-digit'});
|
|
9771
|
+
const badge = commit.isWiki ? '<span class="commit-badge wiki">wiki</span>' : '<span class="commit-badge code">code</span>';
|
|
9772
|
+
document.getElementById('tl-commit-info').innerHTML =
|
|
9773
|
+
`<span class="tl-hash">${commit.hashShort}</span>${badge}<span>${esc(commit.message)}</span><span style="margin-left:auto;color:var(--text-muted)">${dateStr} · ${commit.author}</span>`;
|
|
9757
9774
|
}
|
|
9758
9775
|
|
|
9759
|
-
//
|
|
9776
|
+
// In graph mode, skip heavy renders during drag — only render on release
|
|
9777
|
+
if(tlState.mode === 'graph') return;
|
|
9778
|
+
|
|
9779
|
+
// Debounce the expensive tree render (100ms) to avoid blocking the UI thread
|
|
9760
9780
|
if(tlState._tlRenderDebounce != null) clearTimeout(tlState._tlRenderDebounce);
|
|
9761
9781
|
tlState._tlRenderDebounce = setTimeout(() => {
|
|
9762
9782
|
tlState._tlRenderDebounce = null;
|
|
9763
9783
|
renderTimelapseAt(val, { crossfade: false });
|
|
9764
|
-
},
|
|
9784
|
+
}, 100);
|
|
9765
9785
|
});
|
|
9766
9786
|
|
|
9767
9787
|
// change: fires once on slider release (mouse up / touch end) — final authoritative render
|
package/package.json
CHANGED
|
@@ -2633,7 +2633,7 @@
|
|
|
2633
2633
|
.tl-play-btn.playing { background:var(--accent); color:var(--bg-deep); border-color:var(--accent); }
|
|
2634
2634
|
.tl-speed { background:var(--bg-card); border:1px solid var(--border); color:var(--text); padding:4px 6px; border-radius:var(--radius); font-size:11px; cursor:pointer; }
|
|
2635
2635
|
.tl-slider-wrap { flex:1; display:flex; flex-direction:column; gap:2px; }
|
|
2636
|
-
.tl-slider { width:100%; height:6px; -webkit-appearance:none; appearance:none; background:linear-gradient(to right, var(--accent) 0%, var(--accent) var(--slider-pct, 0%), var(--border) var(--slider-pct, 0%), var(--border) 100%); border-radius:3px; outline:none; cursor:pointer;
|
|
2636
|
+
.tl-slider { width:100%; height:6px; -webkit-appearance:none; appearance:none; background:linear-gradient(to right, var(--accent) 0%, var(--accent) var(--slider-pct, 0%), var(--border) var(--slider-pct, 0%), var(--border) 100%); border-radius:3px; outline:none; cursor:pointer; }
|
|
2637
2637
|
.tl-slider::-webkit-slider-thumb { -webkit-appearance:none; width:16px; height:16px; border-radius:50%; background:var(--text-bright); cursor:grab; box-shadow:0 1px 6px rgba(0,0,0,0.4), 0 0 0 2px var(--accent); transition:transform 0.1s ease, box-shadow 0.15s ease; }
|
|
2638
2638
|
.tl-slider::-webkit-slider-thumb:hover { transform:scale(1.2); box-shadow:0 1px 8px rgba(0,0,0,0.5), 0 0 0 3px var(--accent); }
|
|
2639
2639
|
.tl-slider::-webkit-slider-thumb:active { cursor:grabbing; transform:scale(1.1); }
|
|
@@ -8897,6 +8897,7 @@
|
|
|
8897
8897
|
_tlPlayRaf: null,
|
|
8898
8898
|
_tlDragging: false,
|
|
8899
8899
|
_tlRenderDebounce: null,
|
|
8900
|
+
_tlJustScrubbed: false,
|
|
8900
8901
|
};
|
|
8901
8902
|
|
|
8902
8903
|
function railTimelapseClick() {
|
|
@@ -9454,8 +9455,8 @@
|
|
|
9454
9455
|
if(o) {
|
|
9455
9456
|
n.x = o.x;
|
|
9456
9457
|
n.y = o.y;
|
|
9457
|
-
n.vx = (o.vx || 0) * 0.32;
|
|
9458
|
-
n.vy = (o.vy || 0) * 0.32;
|
|
9458
|
+
n.vx = (o.vx || 0) * (tlState.playing ? 0.1 : 0.32);
|
|
9459
|
+
n.vy = (o.vy || 0) * (tlState.playing ? 0.1 : 0.32);
|
|
9459
9460
|
} else if(p) {
|
|
9460
9461
|
n.x = p.x;
|
|
9461
9462
|
n.y = p.y;
|
|
@@ -9469,7 +9470,10 @@
|
|
|
9469
9470
|
sim.force('charge', d3.forceManyBody().strength(-220));
|
|
9470
9471
|
sim.force('center', d3.forceCenter(width/2, height/2));
|
|
9471
9472
|
sim.force('collision', d3.forceCollide().radius(d => isHub(d)?26:18));
|
|
9472
|
-
|
|
9473
|
+
const scrubAlpha = tlState.playing ? 0.08 : (tlState._tlJustScrubbed ? 0.15 : 0.3);
|
|
9474
|
+
const scrubDecay = tlState.playing ? 0.04 : (tlState._tlJustScrubbed ? 0.035 : 0.0228);
|
|
9475
|
+
sim.alpha(scrubAlpha).alphaDecay(scrubDecay).restart();
|
|
9476
|
+
tlState._tlJustScrubbed = false;
|
|
9473
9477
|
} else {
|
|
9474
9478
|
if(tlState._tlGraphSim) {
|
|
9475
9479
|
tlState._tlGraphSim.stop();
|
|
@@ -9486,13 +9490,16 @@
|
|
|
9486
9490
|
}
|
|
9487
9491
|
|
|
9488
9492
|
const soft = reuseSim;
|
|
9493
|
+
const fast = tlState.playing; // ultra-fast transitions during playback
|
|
9489
9494
|
|
|
9490
9495
|
const lk = g.select('g.tl-links').selectAll('line').data(data.links, linkKey);
|
|
9491
|
-
lk.exit().transition().duration(soft ? 200 : 300).attr('stroke-opacity',0).remove();
|
|
9496
|
+
lk.exit().transition().duration(fast ? 80 : soft ? 200 : 300).attr('stroke-opacity',0).remove();
|
|
9492
9497
|
const lkE = lk.enter().append('line')
|
|
9493
9498
|
.attr('stroke',cs('--border-subtle')).attr('stroke-width',0.8)
|
|
9494
|
-
.attr('stroke-opacity', soft ? 0.2 : 0.4);
|
|
9495
|
-
if(
|
|
9499
|
+
.attr('stroke-opacity', fast ? 0.35 : soft ? 0.2 : 0.4);
|
|
9500
|
+
if(fast) {
|
|
9501
|
+
lkE.transition().duration(120).attr('stroke-opacity',0.4);
|
|
9502
|
+
} else if(soft) {
|
|
9496
9503
|
lkE.transition().duration(380).attr('stroke-opacity',0.4);
|
|
9497
9504
|
} else {
|
|
9498
9505
|
lkE.attr('stroke-dasharray','500').attr('stroke-dashoffset','500')
|
|
@@ -9500,26 +9507,27 @@
|
|
|
9500
9507
|
.on('end', function(){ d3.select(this).attr('stroke-dasharray',null); });
|
|
9501
9508
|
}
|
|
9502
9509
|
const links = lkE.merge(lk);
|
|
9503
|
-
lk.transition().duration(soft ? 320 : 300).attr('stroke-opacity',0.4);
|
|
9510
|
+
lk.transition().duration(fast ? 100 : soft ? 320 : 300).attr('stroke-opacity',0.4);
|
|
9504
9511
|
|
|
9505
9512
|
const rg = g.select('g.tl-rings').selectAll('circle').data(data.nodes.filter(isHub), d=>d.id);
|
|
9506
|
-
rg.exit().transition().duration(soft ? 200 : 300).attr('opacity',0).remove();
|
|
9513
|
+
rg.exit().transition().duration(fast ? 60 : soft ? 200 : 300).attr('opacity',0).remove();
|
|
9507
9514
|
const rgE = rg.enter().append('circle')
|
|
9508
|
-
.attr('r',d=>nR(d)+5).attr('fill','none').attr('stroke','#d4a843').attr('stroke-width',1.5).attr('opacity', soft ? 0.35 : 0);
|
|
9509
|
-
rgE.transition().duration(soft ? 260 : 300).delay(soft ? 0 : 100).attr('opacity',0.5);
|
|
9515
|
+
.attr('r',d=>nR(d)+5).attr('fill','none').attr('stroke','#d4a843').attr('stroke-width',1.5).attr('opacity', fast ? 0.4 : soft ? 0.35 : 0);
|
|
9516
|
+
rgE.transition().duration(fast ? 100 : soft ? 260 : 300).delay(fast ? 0 : soft ? 0 : 100).attr('opacity',0.5);
|
|
9510
9517
|
const rings = rgE.merge(rg);
|
|
9511
|
-
rg.transition().duration(soft ? 300 : 300).attr('r',d=>nR(d)+5);
|
|
9518
|
+
rg.transition().duration(fast ? 80 : soft ? 300 : 300).attr('r',d=>nR(d)+5);
|
|
9512
9519
|
|
|
9513
9520
|
const nd = g.select('g.tl-nodes').selectAll('circle').data(data.nodes, d=>d.id);
|
|
9514
|
-
nd.exit().transition().duration(soft ? 220 : 300).attr('opacity',0).attr('r',0).remove();
|
|
9521
|
+
nd.exit().transition().duration(fast ? 60 : soft ? 220 : 300).attr('opacity',0).attr('r',0).remove();
|
|
9515
9522
|
const ndE = nd.enter().append('circle')
|
|
9516
|
-
.attr('r',
|
|
9523
|
+
.attr('r', fast ? d=>nR(d)*0.7 : soft ? d=>nR(d) : 0)
|
|
9524
|
+
.attr('opacity', fast ? 0.85 : soft ? 0.75 : 0)
|
|
9517
9525
|
.attr('fill',d=>cColor(d.community))
|
|
9518
9526
|
.attr('stroke',d=>isHub(d)?'#d4a843':cs('--bg'))
|
|
9519
9527
|
.attr('stroke-width',d=>isHub(d)?2:1.5)
|
|
9520
9528
|
.attr('cursor','pointer');
|
|
9521
|
-
ndE.transition().duration(soft ? 420 : 300).attr('r',d=>nR(d)).attr('opacity',1);
|
|
9522
|
-
nd.transition().duration(soft ? 450 : 300)
|
|
9529
|
+
ndE.transition().duration(fast ? 100 : soft ? 420 : 300).attr('r',d=>nR(d)).attr('opacity',1);
|
|
9530
|
+
nd.transition().duration(fast ? 120 : soft ? 450 : 300)
|
|
9523
9531
|
.attr('r',d=>nR(d)).attr('fill',d=>cColor(d.community))
|
|
9524
9532
|
.attr('stroke',d=>isHub(d)?'#d4a843':cs('--bg'));
|
|
9525
9533
|
const nodes = ndE.merge(nd);
|
|
@@ -9539,7 +9547,7 @@
|
|
|
9539
9547
|
.attr('fill',d=>isHub(d)?cs('--text-bright'):cs('--text-dim'))
|
|
9540
9548
|
.attr('text-anchor','middle').attr('dy',d=>nR(d)+13)
|
|
9541
9549
|
.attr('pointer-events','none').attr('opacity',0);
|
|
9542
|
-
lbE.transition().duration(300).delay(soft ? 40 : 200).attr('opacity',d=>isHub(d)?1:0);
|
|
9550
|
+
lbE.transition().duration(fast ? 80 : 300).delay(fast ? 0 : soft ? 40 : 200).attr('opacity',d=>isHub(d)?1:0);
|
|
9543
9551
|
const labels = lbE.merge(lb);
|
|
9544
9552
|
labels.text(d=>d.title.length>22?d.title.slice(0,20)+'\u2026':d.title);
|
|
9545
9553
|
|
|
@@ -9593,6 +9601,7 @@
|
|
|
9593
9601
|
|
|
9594
9602
|
let lastTime = null;
|
|
9595
9603
|
let fractionalIdx = tlState.currentIdx;
|
|
9604
|
+
let rendering = false;
|
|
9596
9605
|
|
|
9597
9606
|
function animate(ts) {
|
|
9598
9607
|
if(!tlState.playing || tlState._tlDragging) return;
|
|
@@ -9609,14 +9618,16 @@
|
|
|
9609
9618
|
slider.style.setProperty('--slider-pct', `${pct}%`);
|
|
9610
9619
|
slider.value = String(Math.min(Math.round(fractionalIdx), max));
|
|
9611
9620
|
|
|
9612
|
-
// Only render at integer commit boundaries
|
|
9621
|
+
// Only render at integer commit boundaries — skip if prior render still in flight
|
|
9613
9622
|
const targetIdx = Math.floor(fractionalIdx);
|
|
9614
|
-
if(targetIdx > tlState.currentIdx && targetIdx <= max) {
|
|
9615
|
-
|
|
9623
|
+
if(targetIdx > tlState.currentIdx && targetIdx <= max && !rendering) {
|
|
9624
|
+
rendering = true;
|
|
9625
|
+
renderTimelapseAt(targetIdx, { crossfade: false }).finally(() => { rendering = false; });
|
|
9616
9626
|
}
|
|
9617
9627
|
|
|
9618
9628
|
if(fractionalIdx >= max) {
|
|
9619
|
-
|
|
9629
|
+
rendering = true;
|
|
9630
|
+
renderTimelapseAt(max, { crossfade: false }).finally(() => { rendering = false; });
|
|
9620
9631
|
tlPause();
|
|
9621
9632
|
return;
|
|
9622
9633
|
}
|
|
@@ -9737,6 +9748,7 @@
|
|
|
9737
9748
|
cancelAnimationFrame(tlState._tlSliderRaf);
|
|
9738
9749
|
tlState._tlSliderRaf = null;
|
|
9739
9750
|
}
|
|
9751
|
+
tlState._tlJustScrubbed = true;
|
|
9740
9752
|
renderTimelapseAt(tlState._tlSliderPendingIdx != null ? tlState._tlSliderPendingIdx : tlState.currentIdx, { crossfade: true });
|
|
9741
9753
|
}
|
|
9742
9754
|
document.getElementById('tl-slider').addEventListener('pointerup', tlSliderPointerUp);
|
|
@@ -9750,18 +9762,26 @@
|
|
|
9750
9762
|
e.target.style.setProperty('--slider-pct', `${(val / max) * 100}%`);
|
|
9751
9763
|
tlState._tlSliderPendingIdx = val;
|
|
9752
9764
|
|
|
9753
|
-
// Update commit info
|
|
9765
|
+
// Update commit info + counter immediately (lightweight DOM updates, no debounce)
|
|
9754
9766
|
const commit = tlState.commits[val];
|
|
9755
9767
|
if(commit) {
|
|
9756
9768
|
document.getElementById('tl-label-current').textContent = `${val + 1} / ${tlState.commits.length}`;
|
|
9769
|
+
const date = new Date(commit.date);
|
|
9770
|
+
const dateStr = date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour:'2-digit',minute:'2-digit'});
|
|
9771
|
+
const badge = commit.isWiki ? '<span class="commit-badge wiki">wiki</span>' : '<span class="commit-badge code">code</span>';
|
|
9772
|
+
document.getElementById('tl-commit-info').innerHTML =
|
|
9773
|
+
`<span class="tl-hash">${commit.hashShort}</span>${badge}<span>${esc(commit.message)}</span><span style="margin-left:auto;color:var(--text-muted)">${dateStr} · ${commit.author}</span>`;
|
|
9757
9774
|
}
|
|
9758
9775
|
|
|
9759
|
-
//
|
|
9776
|
+
// In graph mode, skip heavy renders during drag — only render on release
|
|
9777
|
+
if(tlState.mode === 'graph') return;
|
|
9778
|
+
|
|
9779
|
+
// Debounce the expensive tree render (100ms) to avoid blocking the UI thread
|
|
9760
9780
|
if(tlState._tlRenderDebounce != null) clearTimeout(tlState._tlRenderDebounce);
|
|
9761
9781
|
tlState._tlRenderDebounce = setTimeout(() => {
|
|
9762
9782
|
tlState._tlRenderDebounce = null;
|
|
9763
9783
|
renderTimelapseAt(val, { crossfade: false });
|
|
9764
|
-
},
|
|
9784
|
+
}, 100);
|
|
9765
9785
|
});
|
|
9766
9786
|
|
|
9767
9787
|
// change: fires once on slider release (mouse up / touch end) — final authoritative render
|