Update coverage reports with new metrics and timestamps
This commit is contained in:
@@ -1501,7 +1501,7 @@ export class ChatView extends ItemView {
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -475,7 +475,7 @@ export class ErrorHandler {
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -23,30 +23,30 @@
|
||||
<div class='clearfix'>
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">93.41% </span>
|
||||
<span class="strong">92.07% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>624/668</span>
|
||||
<span class='fraction'>674/732</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">82.09% </span>
|
||||
<span class="strong">81.41% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>243/296</span>
|
||||
<span class='fraction'>254/312</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">93.06% </span>
|
||||
<span class="strong">87.82% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>94/101</span>
|
||||
<span class='fraction'>101/115</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">94.51% </span>
|
||||
<span class="strong">93.12% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>603/638</span>
|
||||
<span class='fraction'>650/698</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -110,17 +110,17 @@
|
||||
|
||||
<tr>
|
||||
<td class="file high" data-value="ollama-client.ts"><a href="ollama-client.ts.html">ollama-client.ts</a></td>
|
||||
<td data-value="91.91" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 91%"></div><div class="cover-empty" style="width: 9%"></div></div>
|
||||
<td data-value="90.69" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 90%"></div><div class="cover-empty" style="width: 10%"></div></div>
|
||||
</td>
|
||||
<td data-value="91.91" class="pct high">91.91%</td>
|
||||
<td data-value="99" class="abs high">91/99</td>
|
||||
<td data-value="72" class="pct medium">72%</td>
|
||||
<td data-value="50" class="abs medium">36/50</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="11" class="abs high">11/11</td>
|
||||
<td data-value="91.57" class="pct high">91.57%</td>
|
||||
<td data-value="95" class="abs high">87/95</td>
|
||||
<td data-value="90.69" class="pct high">90.69%</td>
|
||||
<td data-value="129" class="abs high">117/129</td>
|
||||
<td data-value="74.13" class="pct medium">74.13%</td>
|
||||
<td data-value="58" class="abs medium">43/58</td>
|
||||
<td data-value="82.35" class="pct high">82.35%</td>
|
||||
<td data-value="17" class="abs high">14/17</td>
|
||||
<td data-value="91.05" class="pct high">91.05%</td>
|
||||
<td data-value="123" class="abs high">112/123</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -155,32 +155,32 @@
|
||||
|
||||
<tr>
|
||||
<td class="file high" data-value="utils.ts"><a href="utils.ts.html">utils.ts</a></td>
|
||||
<td data-value="95.87" class="pic high">
|
||||
<td data-value="95.65" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 95%"></div><div class="cover-empty" style="width: 5%"></div></div>
|
||||
</td>
|
||||
<td data-value="95.87" class="pct high">95.87%</td>
|
||||
<td data-value="97" class="abs high">93/97</td>
|
||||
<td data-value="85.41" class="pct high">85.41%</td>
|
||||
<td data-value="48" class="abs high">41/48</td>
|
||||
<td data-value="93.75" class="pct high">93.75%</td>
|
||||
<td data-value="16" class="abs high">15/16</td>
|
||||
<td data-value="96.77" class="pct high">96.77%</td>
|
||||
<td data-value="93" class="abs high">90/93</td>
|
||||
<td data-value="95.65" class="pct high">95.65%</td>
|
||||
<td data-value="92" class="abs high">88/92</td>
|
||||
<td data-value="84.78" class="pct high">84.78%</td>
|
||||
<td data-value="46" class="abs high">39/46</td>
|
||||
<td data-value="93.33" class="pct high">93.33%</td>
|
||||
<td data-value="15" class="abs high">14/15</td>
|
||||
<td data-value="96.59" class="pct high">96.59%</td>
|
||||
<td data-value="88" class="abs high">85/88</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="file high" data-value="vault-indexer.ts"><a href="vault-indexer.ts.html">vault-indexer.ts</a></td>
|
||||
<td data-value="92.85" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 92%"></div><div class="cover-empty" style="width: 8%"></div></div>
|
||||
<td data-value="88.07" class="pic high">
|
||||
<div class="chart"><div class="cover-fill" style="width: 88%"></div><div class="cover-empty" style="width: 12%"></div></div>
|
||||
</td>
|
||||
<td data-value="92.85" class="pct high">92.85%</td>
|
||||
<td data-value="112" class="abs high">104/112</td>
|
||||
<td data-value="80" class="pct high">80%</td>
|
||||
<td data-value="45" class="abs high">36/45</td>
|
||||
<td data-value="100" class="pct high">100%</td>
|
||||
<td data-value="15" class="abs high">15/15</td>
|
||||
<td data-value="95.19" class="pct high">95.19%</td>
|
||||
<td data-value="104" class="abs high">99/104</td>
|
||||
<td data-value="88.07" class="pct high">88.07%</td>
|
||||
<td data-value="151" class="abs high">133/151</td>
|
||||
<td data-value="76.36" class="pct medium">76.36%</td>
|
||||
<td data-value="55" class="abs medium">42/55</td>
|
||||
<td data-value="83.33" class="pct high">83.33%</td>
|
||||
<td data-value="24" class="abs high">20/24</td>
|
||||
<td data-value="89.36" class="pct high">89.36%</td>
|
||||
<td data-value="141" class="abs high">126/141</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
@@ -191,7 +191,7 @@
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -23,30 +23,30 @@
|
||||
<div class='clearfix'>
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">91.91% </span>
|
||||
<span class="strong">90.69% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>91/99</span>
|
||||
<span class='fraction'>117/129</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">72% </span>
|
||||
<span class="strong">74.13% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>36/50</span>
|
||||
<span class='fraction'>43/58</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="strong">82.35% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>11/11</span>
|
||||
<span class='fraction'>14/17</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">91.57% </span>
|
||||
<span class="strong">91.05% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>87/95</span>
|
||||
<span class='fraction'>112/123</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -301,7 +301,61 @@
|
||||
<a name='L236'></a><a href='#L236'>236</a>
|
||||
<a name='L237'></a><a href='#L237'>237</a>
|
||||
<a name='L238'></a><a href='#L238'>238</a>
|
||||
<a name='L239'></a><a href='#L239'>239</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
||||
<a name='L239'></a><a href='#L239'>239</a>
|
||||
<a name='L240'></a><a href='#L240'>240</a>
|
||||
<a name='L241'></a><a href='#L241'>241</a>
|
||||
<a name='L242'></a><a href='#L242'>242</a>
|
||||
<a name='L243'></a><a href='#L243'>243</a>
|
||||
<a name='L244'></a><a href='#L244'>244</a>
|
||||
<a name='L245'></a><a href='#L245'>245</a>
|
||||
<a name='L246'></a><a href='#L246'>246</a>
|
||||
<a name='L247'></a><a href='#L247'>247</a>
|
||||
<a name='L248'></a><a href='#L248'>248</a>
|
||||
<a name='L249'></a><a href='#L249'>249</a>
|
||||
<a name='L250'></a><a href='#L250'>250</a>
|
||||
<a name='L251'></a><a href='#L251'>251</a>
|
||||
<a name='L252'></a><a href='#L252'>252</a>
|
||||
<a name='L253'></a><a href='#L253'>253</a>
|
||||
<a name='L254'></a><a href='#L254'>254</a>
|
||||
<a name='L255'></a><a href='#L255'>255</a>
|
||||
<a name='L256'></a><a href='#L256'>256</a>
|
||||
<a name='L257'></a><a href='#L257'>257</a>
|
||||
<a name='L258'></a><a href='#L258'>258</a>
|
||||
<a name='L259'></a><a href='#L259'>259</a>
|
||||
<a name='L260'></a><a href='#L260'>260</a>
|
||||
<a name='L261'></a><a href='#L261'>261</a>
|
||||
<a name='L262'></a><a href='#L262'>262</a>
|
||||
<a name='L263'></a><a href='#L263'>263</a>
|
||||
<a name='L264'></a><a href='#L264'>264</a>
|
||||
<a name='L265'></a><a href='#L265'>265</a>
|
||||
<a name='L266'></a><a href='#L266'>266</a>
|
||||
<a name='L267'></a><a href='#L267'>267</a>
|
||||
<a name='L268'></a><a href='#L268'>268</a>
|
||||
<a name='L269'></a><a href='#L269'>269</a>
|
||||
<a name='L270'></a><a href='#L270'>270</a>
|
||||
<a name='L271'></a><a href='#L271'>271</a>
|
||||
<a name='L272'></a><a href='#L272'>272</a>
|
||||
<a name='L273'></a><a href='#L273'>273</a>
|
||||
<a name='L274'></a><a href='#L274'>274</a>
|
||||
<a name='L275'></a><a href='#L275'>275</a>
|
||||
<a name='L276'></a><a href='#L276'>276</a>
|
||||
<a name='L277'></a><a href='#L277'>277</a>
|
||||
<a name='L278'></a><a href='#L278'>278</a>
|
||||
<a name='L279'></a><a href='#L279'>279</a>
|
||||
<a name='L280'></a><a href='#L280'>280</a>
|
||||
<a name='L281'></a><a href='#L281'>281</a>
|
||||
<a name='L282'></a><a href='#L282'>282</a>
|
||||
<a name='L283'></a><a href='#L283'>283</a>
|
||||
<a name='L284'></a><a href='#L284'>284</a>
|
||||
<a name='L285'></a><a href='#L285'>285</a>
|
||||
<a name='L286'></a><a href='#L286'>286</a>
|
||||
<a name='L287'></a><a href='#L287'>287</a>
|
||||
<a name='L288'></a><a href='#L288'>288</a>
|
||||
<a name='L289'></a><a href='#L289'>289</a>
|
||||
<a name='L290'></a><a href='#L290'>290</a>
|
||||
<a name='L291'></a><a href='#L291'>291</a>
|
||||
<a name='L292'></a><a href='#L292'>292</a>
|
||||
<a name='L293'></a><a href='#L293'>293</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
@@ -383,6 +437,29 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -470,6 +547,10 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">25x</span>
|
||||
<span class="cline-any cline-yes">25x</span>
|
||||
<span class="cline-any cline-yes">25x</span>
|
||||
<span class="cline-any cline-yes">20x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -506,6 +587,29 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
@@ -517,6 +621,10 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">8x</span>
|
||||
<span class="cline-any cline-yes">8x</span>
|
||||
<span class="cline-any cline-yes">8x</span>
|
||||
<span class="cline-any cline-yes">7x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -620,7 +728,30 @@ export class OllamaClient {
|
||||
`Network error (status ${response.status}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${this.maxRetries})`,
|
||||
'ollama-client'
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
if (attempt < this.maxRetries - 1) {
|
||||
const retryTimeout = new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
const abortListener = <span class="fstat-no" title="function not covered" >() =</span>> {
|
||||
<span class="cstat-no" title="statement not covered" > Logger.info('Retry aborted by user', 'ollama-client');</span>
|
||||
};
|
||||
const signal = this.abortController?.signal;
|
||||
if (signal) {
|
||||
signal.addEventListener('abort', abortListener);
|
||||
try {
|
||||
await Promise.race([
|
||||
retryTimeout,
|
||||
new Promise<void>((resolve) => {
|
||||
signal.addEventListener('abort', () => resolve(), {
|
||||
once: true,
|
||||
});
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
signal.removeEventListener('abort', abortListener);
|
||||
}
|
||||
} else <span class="missing-if-branch" title="else path not taken" >E</span>{
|
||||
<span class="cstat-no" title="statement not covered" > await retryTimeout;</span>
|
||||
}
|
||||
}
|
||||
yield* this.streamChatWithRetry(messages, tools, attempt + 1);
|
||||
return;
|
||||
}
|
||||
@@ -707,7 +838,11 @@ export class OllamaClient {
|
||||
reader.releaseLock();
|
||||
}
|
||||
} finally {
|
||||
const controller = this.abortController;
|
||||
this.abortController = null;
|
||||
if (controller) {
|
||||
controller.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,7 +878,30 @@ export class OllamaClient {
|
||||
`Network error (status ${response.status}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${this.maxRetries})`,
|
||||
'ollama-client'
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
if (attempt < this.maxRetries - 1) {
|
||||
const retryTimeout = new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
const abortListener = <span class="fstat-no" title="function not covered" >() =</span>> {
|
||||
<span class="cstat-no" title="statement not covered" > Logger.info('Retry aborted by user', 'ollama-client');</span>
|
||||
};
|
||||
const signal = this.abortController?.signal;
|
||||
if (signal) {
|
||||
signal.addEventListener('abort', abortListener);
|
||||
try {
|
||||
await Promise.race([
|
||||
retryTimeout,
|
||||
new Promise<void>((resolve) => {
|
||||
signal.addEventListener('abort', <span class="fstat-no" title="function not covered" >() =</span>> <span class="cstat-no" title="statement not covered" >resolve(),</span> {
|
||||
once: true,
|
||||
});
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
signal.removeEventListener('abort', abortListener);
|
||||
}
|
||||
} else {
|
||||
await retryTimeout;
|
||||
}
|
||||
}
|
||||
return this.chatWithRetry(messages, tools, attempt + 1);
|
||||
}
|
||||
throw new ApiError(`Ollama API error: ${response.status}`, response.status);
|
||||
@@ -754,7 +912,11 @@ export class OllamaClient {
|
||||
this.toOllamaMessage(data.message) ?? { role: 'assistant', content: '', tool_calls: [] }
|
||||
);
|
||||
} finally {
|
||||
const controller = this.abortController;
|
||||
this.abortController = null;
|
||||
if (controller) {
|
||||
controller.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -784,7 +946,7 @@ export class OllamaClient {
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -463,7 +463,7 @@ export class ToolExecutor {
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -604,7 +604,7 @@ export interface VaultIndexEntry {
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -23,30 +23,30 @@
|
||||
<div class='clearfix'>
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">95.87% </span>
|
||||
<span class="strong">95.65% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>93/97</span>
|
||||
<span class='fraction'>88/92</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">85.41% </span>
|
||||
<span class="strong">84.78% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>41/48</span>
|
||||
<span class='fraction'>39/46</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">93.75% </span>
|
||||
<span class="strong">93.33% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>15/16</span>
|
||||
<span class='fraction'>14/15</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">96.77% </span>
|
||||
<span class="strong">96.59% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>90/93</span>
|
||||
<span class='fraction'>85/88</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -254,35 +254,22 @@
|
||||
<a name='L189'></a><a href='#L189'>189</a>
|
||||
<a name='L190'></a><a href='#L190'>190</a>
|
||||
<a name='L191'></a><a href='#L191'>191</a>
|
||||
<a name='L192'></a><a href='#L192'>192</a>
|
||||
<a name='L193'></a><a href='#L193'>193</a>
|
||||
<a name='L194'></a><a href='#L194'>194</a>
|
||||
<a name='L195'></a><a href='#L195'>195</a>
|
||||
<a name='L196'></a><a href='#L196'>196</a>
|
||||
<a name='L197'></a><a href='#L197'>197</a>
|
||||
<a name='L198'></a><a href='#L198'>198</a>
|
||||
<a name='L199'></a><a href='#L199'>199</a>
|
||||
<a name='L200'></a><a href='#L200'>200</a>
|
||||
<a name='L201'></a><a href='#L201'>201</a>
|
||||
<a name='L202'></a><a href='#L202'>202</a>
|
||||
<a name='L203'></a><a href='#L203'>203</a>
|
||||
<a name='L204'></a><a href='#L204'>204</a>
|
||||
<a name='L205'></a><a href='#L205'>205</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<a name='L192'></a><a href='#L192'>192</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">23x</span>
|
||||
@@ -320,7 +307,7 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">12x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -342,7 +329,7 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">15x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -372,7 +359,7 @@
|
||||
<span class="cline-any cline-yes">8x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
@@ -390,8 +377,8 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">117x</span>
|
||||
@@ -408,7 +395,7 @@
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">41x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -458,19 +445,6 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">5x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">6x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">export enum LogLevel {
|
||||
DEBUG = 0,
|
||||
INFO = 1,
|
||||
@@ -661,19 +635,6 @@ export function safeParseJson(jsonString: string): unknown {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
// ==================== Path & File Utilities ====================
|
||||
|
||||
// ==================== HTTP Helpers ====================
|
||||
|
||||
export function isValidHttpUrl(url: string): boolean {
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== Markdown Utilities ====================
|
||||
</pre></td></tr></table></pre>
|
||||
|
||||
@@ -682,7 +643,7 @@ export function isValidHttpUrl(url: string): boolean {
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
@@ -23,30 +23,30 @@
|
||||
<div class='clearfix'>
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">92.85% </span>
|
||||
<span class="strong">88.07% </span>
|
||||
<span class="quiet">Statements</span>
|
||||
<span class='fraction'>104/112</span>
|
||||
<span class='fraction'>133/151</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">80% </span>
|
||||
<span class="strong">76.36% </span>
|
||||
<span class="quiet">Branches</span>
|
||||
<span class='fraction'>36/45</span>
|
||||
<span class='fraction'>42/55</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">100% </span>
|
||||
<span class="strong">83.33% </span>
|
||||
<span class="quiet">Functions</span>
|
||||
<span class='fraction'>15/15</span>
|
||||
<span class='fraction'>20/24</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class='fl pad1y space-right2'>
|
||||
<span class="strong">95.19% </span>
|
||||
<span class="strong">89.36% </span>
|
||||
<span class="quiet">Lines</span>
|
||||
<span class='fraction'>99/104</span>
|
||||
<span class='fraction'>126/141</span>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -333,96 +333,279 @@
|
||||
<a name='L268'></a><a href='#L268'>268</a>
|
||||
<a name='L269'></a><a href='#L269'>269</a>
|
||||
<a name='L270'></a><a href='#L270'>270</a>
|
||||
<a name='L271'></a><a href='#L271'>271</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
||||
<a name='L271'></a><a href='#L271'>271</a>
|
||||
<a name='L272'></a><a href='#L272'>272</a>
|
||||
<a name='L273'></a><a href='#L273'>273</a>
|
||||
<a name='L274'></a><a href='#L274'>274</a>
|
||||
<a name='L275'></a><a href='#L275'>275</a>
|
||||
<a name='L276'></a><a href='#L276'>276</a>
|
||||
<a name='L277'></a><a href='#L277'>277</a>
|
||||
<a name='L278'></a><a href='#L278'>278</a>
|
||||
<a name='L279'></a><a href='#L279'>279</a>
|
||||
<a name='L280'></a><a href='#L280'>280</a>
|
||||
<a name='L281'></a><a href='#L281'>281</a>
|
||||
<a name='L282'></a><a href='#L282'>282</a>
|
||||
<a name='L283'></a><a href='#L283'>283</a>
|
||||
<a name='L284'></a><a href='#L284'>284</a>
|
||||
<a name='L285'></a><a href='#L285'>285</a>
|
||||
<a name='L286'></a><a href='#L286'>286</a>
|
||||
<a name='L287'></a><a href='#L287'>287</a>
|
||||
<a name='L288'></a><a href='#L288'>288</a>
|
||||
<a name='L289'></a><a href='#L289'>289</a>
|
||||
<a name='L290'></a><a href='#L290'>290</a>
|
||||
<a name='L291'></a><a href='#L291'>291</a>
|
||||
<a name='L292'></a><a href='#L292'>292</a>
|
||||
<a name='L293'></a><a href='#L293'>293</a>
|
||||
<a name='L294'></a><a href='#L294'>294</a>
|
||||
<a name='L295'></a><a href='#L295'>295</a>
|
||||
<a name='L296'></a><a href='#L296'>296</a>
|
||||
<a name='L297'></a><a href='#L297'>297</a>
|
||||
<a name='L298'></a><a href='#L298'>298</a>
|
||||
<a name='L299'></a><a href='#L299'>299</a>
|
||||
<a name='L300'></a><a href='#L300'>300</a>
|
||||
<a name='L301'></a><a href='#L301'>301</a>
|
||||
<a name='L302'></a><a href='#L302'>302</a>
|
||||
<a name='L303'></a><a href='#L303'>303</a>
|
||||
<a name='L304'></a><a href='#L304'>304</a>
|
||||
<a name='L305'></a><a href='#L305'>305</a>
|
||||
<a name='L306'></a><a href='#L306'>306</a>
|
||||
<a name='L307'></a><a href='#L307'>307</a>
|
||||
<a name='L308'></a><a href='#L308'>308</a>
|
||||
<a name='L309'></a><a href='#L309'>309</a>
|
||||
<a name='L310'></a><a href='#L310'>310</a>
|
||||
<a name='L311'></a><a href='#L311'>311</a>
|
||||
<a name='L312'></a><a href='#L312'>312</a>
|
||||
<a name='L313'></a><a href='#L313'>313</a>
|
||||
<a name='L314'></a><a href='#L314'>314</a>
|
||||
<a name='L315'></a><a href='#L315'>315</a>
|
||||
<a name='L316'></a><a href='#L316'>316</a>
|
||||
<a name='L317'></a><a href='#L317'>317</a>
|
||||
<a name='L318'></a><a href='#L318'>318</a>
|
||||
<a name='L319'></a><a href='#L319'>319</a>
|
||||
<a name='L320'></a><a href='#L320'>320</a>
|
||||
<a name='L321'></a><a href='#L321'>321</a>
|
||||
<a name='L322'></a><a href='#L322'>322</a>
|
||||
<a name='L323'></a><a href='#L323'>323</a>
|
||||
<a name='L324'></a><a href='#L324'>324</a>
|
||||
<a name='L325'></a><a href='#L325'>325</a>
|
||||
<a name='L326'></a><a href='#L326'>326</a>
|
||||
<a name='L327'></a><a href='#L327'>327</a>
|
||||
<a name='L328'></a><a href='#L328'>328</a>
|
||||
<a name='L329'></a><a href='#L329'>329</a>
|
||||
<a name='L330'></a><a href='#L330'>330</a>
|
||||
<a name='L331'></a><a href='#L331'>331</a>
|
||||
<a name='L332'></a><a href='#L332'>332</a>
|
||||
<a name='L333'></a><a href='#L333'>333</a>
|
||||
<a name='L334'></a><a href='#L334'>334</a>
|
||||
<a name='L335'></a><a href='#L335'>335</a>
|
||||
<a name='L336'></a><a href='#L336'>336</a>
|
||||
<a name='L337'></a><a href='#L337'>337</a>
|
||||
<a name='L338'></a><a href='#L338'>338</a>
|
||||
<a name='L339'></a><a href='#L339'>339</a>
|
||||
<a name='L340'></a><a href='#L340'>340</a>
|
||||
<a name='L341'></a><a href='#L341'>341</a>
|
||||
<a name='L342'></a><a href='#L342'>342</a>
|
||||
<a name='L343'></a><a href='#L343'>343</a>
|
||||
<a name='L344'></a><a href='#L344'>344</a>
|
||||
<a name='L345'></a><a href='#L345'>345</a>
|
||||
<a name='L346'></a><a href='#L346'>346</a>
|
||||
<a name='L347'></a><a href='#L347'>347</a>
|
||||
<a name='L348'></a><a href='#L348'>348</a>
|
||||
<a name='L349'></a><a href='#L349'>349</a>
|
||||
<a name='L350'></a><a href='#L350'>350</a>
|
||||
<a name='L351'></a><a href='#L351'>351</a>
|
||||
<a name='L352'></a><a href='#L352'>352</a>
|
||||
<a name='L353'></a><a href='#L353'>353</a>
|
||||
<a name='L354'></a><a href='#L354'>354</a>
|
||||
<a name='L355'></a><a href='#L355'>355</a>
|
||||
<a name='L356'></a><a href='#L356'>356</a>
|
||||
<a name='L357'></a><a href='#L357'>357</a>
|
||||
<a name='L358'></a><a href='#L358'>358</a>
|
||||
<a name='L359'></a><a href='#L359'>359</a>
|
||||
<a name='L360'></a><a href='#L360'>360</a>
|
||||
<a name='L361'></a><a href='#L361'>361</a>
|
||||
<a name='L362'></a><a href='#L362'>362</a>
|
||||
<a name='L363'></a><a href='#L363'>363</a>
|
||||
<a name='L364'></a><a href='#L364'>364</a>
|
||||
<a name='L365'></a><a href='#L365'>365</a>
|
||||
<a name='L366'></a><a href='#L366'>366</a>
|
||||
<a name='L367'></a><a href='#L367'>367</a>
|
||||
<a name='L368'></a><a href='#L368'>368</a>
|
||||
<a name='L369'></a><a href='#L369'>369</a>
|
||||
<a name='L370'></a><a href='#L370'>370</a>
|
||||
<a name='L371'></a><a href='#L371'>371</a>
|
||||
<a name='L372'></a><a href='#L372'>372</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">67x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">67x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">33x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">50x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">71x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">71x</span>
|
||||
<span class="cline-any cline-yes">71x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">38x</span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">35x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">35x</span>
|
||||
<span class="cline-any cline-yes">35x</span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">53x</span>
|
||||
<span class="cline-any cline-yes">38x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-yes">62x</span>
|
||||
<span class="cline-any cline-yes">62x</span>
|
||||
<span class="cline-any cline-yes">62x</span>
|
||||
<span class="cline-any cline-yes">53x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">15x</span>
|
||||
<span class="cline-any cline-yes">15x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">54x</span>
|
||||
<span class="cline-any cline-yes">54x</span>
|
||||
<span class="cline-any cline-yes">53x</span>
|
||||
<span class="cline-any cline-yes">53x</span>
|
||||
<span class="cline-any cline-yes">53x</span>
|
||||
<span class="cline-any cline-yes">50x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">50x</span>
|
||||
<span class="cline-any cline-yes">50x</span>
|
||||
<span class="cline-any cline-yes">50x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-yes">9x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -433,17 +616,31 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">15x</span>
|
||||
<span class="cline-any cline-yes">54x</span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">15x</span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">31x</span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">100x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">18x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">34x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">112x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -470,20 +667,20 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">100x</span>
|
||||
<span class="cline-any cline-yes">112x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">367x</span>
|
||||
<span class="cline-any cline-yes">469x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
@@ -506,25 +703,25 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">12x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">69x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -532,21 +729,21 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-yes">67x</span>
|
||||
<span class="cline-any cline-yes">67x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">67x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -555,33 +752,33 @@
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">1x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-yes">4x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">56x</span>
|
||||
<span class="cline-any cline-yes">56x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">64x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">60x</span>
|
||||
<span class="cline-any cline-yes">73x</span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">58x</span>
|
||||
<span class="cline-any cline-yes">67x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
@@ -589,25 +786,70 @@
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">127x</span>
|
||||
<span class="cline-any cline-yes">127x</span>
|
||||
<span class="cline-any cline-yes">126x</span>
|
||||
<span class="cline-any cline-yes">126x</span>
|
||||
<span class="cline-any cline-yes">145x</span>
|
||||
<span class="cline-any cline-yes">145x</span>
|
||||
<span class="cline-any cline-yes">144x</span>
|
||||
<span class="cline-any cline-yes">144x</span>
|
||||
<span class="cline-any cline-yes">122x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-yes">63x</span>
|
||||
<span class="cline-any cline-yes">72x</span>
|
||||
<span class="cline-any cline-yes">72x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">2x</span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-yes">3x</span>
|
||||
<span class="cline-any cline-no"> </span>
|
||||
<span class="cline-any cline-neutral"> </span>
|
||||
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">// src/vault-indexer.ts
|
||||
|
||||
import { VaultIndexEntry } from './types';
|
||||
import { Logger } from './utils';
|
||||
|
||||
interface Cache {
|
||||
get(key: string): Promise<string | null>;
|
||||
put(key: string, value: string): Promise<void>;
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
|
||||
class InMemoryCache implements Cache {
|
||||
private store: Map<string, string>;
|
||||
|
||||
constructor() {
|
||||
this.store = new Map();
|
||||
}
|
||||
|
||||
get(key: string): Promise<string | null> {
|
||||
return Promise.resolve(this.store.get(key) || null);
|
||||
}
|
||||
|
||||
put(key: string, value: string): Promise<void> {
|
||||
this.store.set(key, value);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
<span class="fstat-no" title="function not covered" > clear(</span>): Promise<void> {
|
||||
<span class="cstat-no" title="statement not covered" > this.store.clear();</span>
|
||||
<span class="cstat-no" title="statement not covered" > return Promise.resolve();</span>
|
||||
}
|
||||
}
|
||||
|
||||
class CancellationToken {
|
||||
private cancelled = false;
|
||||
|
||||
<span class="fstat-no" title="function not covered" > cancel(</span>): void {
|
||||
<span class="cstat-no" title="statement not covered" > this.cancelled = true;</span>
|
||||
}
|
||||
|
||||
get isCancelled(): boolean {
|
||||
return this.cancelled;
|
||||
}
|
||||
}
|
||||
|
||||
interface Frontmatter {
|
||||
title?: string;
|
||||
tags?: string;
|
||||
@@ -637,12 +879,14 @@ interface ScoreResult {
|
||||
|
||||
class VaultIndexer {
|
||||
private vault: VaultLike | null = null;
|
||||
private cache?: Cache;
|
||||
|
||||
constructor(vault: VaultLike) {
|
||||
constructor(vault: VaultLike, cache?: Cache) {
|
||||
this.vault = vault;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
async searchVault(query: string, limit: number = <span class="branch-0 cbranch-no" title="branch not covered" >5)</span>: Promise<VaultIndexEntry[]> {
|
||||
async searchVault(query: string, limit: number = 5): Promise<VaultIndexEntry[]> {
|
||||
if (!query || !query.trim()) {
|
||||
return [];
|
||||
}
|
||||
@@ -650,16 +894,42 @@ class VaultIndexer {
|
||||
<span class="missing-if-branch" title="if path not taken" >I</span>if (!this.vault) {
|
||||
<span class="cstat-no" title="statement not covered" > throw new Error('Vault-like object not provided to VaultIndexer');</span>
|
||||
}
|
||||
|
||||
const cacheKey = `query:${query.trim()}`;
|
||||
if (this.cache) {
|
||||
const cachedResults = await this.cache.get(cacheKey);
|
||||
if (cachedResults) {
|
||||
try {
|
||||
const parsedResults = JSON.parse(cachedResults) as VaultIndexEntry[];
|
||||
return parsedResults.slice(0, limit);
|
||||
} catch {
|
||||
// Ignore cache parse errors and continue with normal processing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const queryTokens = this.tokenize(query.trim());
|
||||
const vault = this.vault;
|
||||
const allFiles = vault.getMarkdownFiles();
|
||||
const results = await this.processFilesInBatches(vault, allFiles, queryTokens);
|
||||
|
||||
return results
|
||||
const filteredResults = results
|
||||
.filter((result): result is NonNullable<typeof result> => result !== null)
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, limit);
|
||||
|
||||
if (this.cache) {
|
||||
try {
|
||||
await this.cache.put(cacheKey, JSON.stringify(filteredResults));
|
||||
} catch (error) {
|
||||
<span class="cstat-no" title="statement not covered" > Logger.warn(</span>
|
||||
`Failed to cache results for query "${query}": ${error instanceof Error ? error.message : String(error)}`,
|
||||
'vault-indexer'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredResults;
|
||||
}
|
||||
|
||||
private async processFilesInBatches(
|
||||
@@ -670,43 +940,71 @@ class VaultIndexer {
|
||||
const batchSize = 10;
|
||||
const results: VaultIndexEntry[] = [];
|
||||
const seenPaths = new Set<string>();
|
||||
const cancellationToken = new CancellationToken();
|
||||
let processedCount = 0;
|
||||
|
||||
for (let i = 0; i < files.length; i += batchSize) {
|
||||
const batch = files.slice(i, i + batchSize);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(async (file) => {
|
||||
try {
|
||||
const content = await vault.read(file);
|
||||
const tokenized = this.tokenizeContent(content);
|
||||
const scoreResult = this.calculateWeightedScore(tokenized, queryTokens, file);
|
||||
if (scoreResult.score > 0) {
|
||||
const entry: VaultIndexEntry = {
|
||||
path: file.path,
|
||||
title: file.basename.replace(/\.md$/, ''),
|
||||
content: content.substring(0, 500),
|
||||
score: scoreResult.score,
|
||||
};
|
||||
if (!seenPaths.has(entry.path)) {
|
||||
seenPaths.add(entry.path);
|
||||
return entry;
|
||||
// Set up a check for cancellation every 100 files
|
||||
const checkInterval = setInterval(<span class="fstat-no" title="function not covered" >() =</span>> {
|
||||
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (cancellationToken.isCancelled) {</span>
|
||||
<span class="cstat-no" title="statement not covered" > clearInterval(checkInterval);</span>
|
||||
}
|
||||
}, 100);
|
||||
|
||||
try {
|
||||
for (let i = 0; i < files.length; i += batchSize) {
|
||||
<span class="missing-if-branch" title="if path not taken" >I</span>if (cancellationToken.isCancelled) {
|
||||
<span class="cstat-no" title="statement not covered" > break;</span>
|
||||
}
|
||||
|
||||
const batch = files.slice(i, i + batchSize);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(async (file) => {
|
||||
try {
|
||||
const content = await vault.read(file);
|
||||
const tokenized = this.tokenizeContent(content);
|
||||
const scoreResult = this.calculateWeightedScore(tokenized, queryTokens, file);
|
||||
if (scoreResult.score > 0) {
|
||||
const entry: VaultIndexEntry = {
|
||||
path: file.path,
|
||||
title: file.basename.replace(/\.md$/, ''),
|
||||
content: content.substring(0, 500),
|
||||
score: scoreResult.score,
|
||||
};
|
||||
if (!seenPaths.has(entry.path)) {
|
||||
seenPaths.add(entry.path);
|
||||
return entry;
|
||||
}
|
||||
<span class="cstat-no" title="statement not covered" > return null;</span>
|
||||
}
|
||||
<span class="cstat-no" title="statement not covered" > return null;</span>
|
||||
return null;
|
||||
} catch (error) {
|
||||
Logger.warn(
|
||||
`Failed to process ${file.path}: ${error instanceof Error ? error.message : <span class="branch-1 cbranch-no" title="branch not covered" >String(error)}</span>`,
|
||||
'vault-indexer'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
Logger.warn(
|
||||
`Failed to process ${file.path}: ${error instanceof Error ? error.message : <span class="branch-1 cbranch-no" title="branch not covered" >String(error)}</span>`,
|
||||
'vault-indexer'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
const validResults = batchResults.filter(
|
||||
(result): result is NonNullable<typeof result> => result !== null
|
||||
);
|
||||
results.push(...validResults);
|
||||
const validResults = batchResults.filter(
|
||||
(result): result is NonNullable<typeof result> => result !== null
|
||||
);
|
||||
results.push(...validResults);
|
||||
|
||||
// Early exit if we've reached enough results
|
||||
<span class="missing-if-branch" title="if path not taken" >I</span>if (results.length >= 100) {
|
||||
<span class="cstat-no" title="statement not covered" > Logger.info(</span>
|
||||
`Early exit after processing ${processedCount + batch.length} files with ${results.length} results`,
|
||||
'vault-indexer'
|
||||
);
|
||||
<span class="cstat-no" title="statement not covered" > break;</span>
|
||||
}
|
||||
|
||||
processedCount += batch.length;
|
||||
}
|
||||
} finally {
|
||||
clearInterval(checkInterval);
|
||||
}
|
||||
|
||||
return results;
|
||||
@@ -872,7 +1170,12 @@ class VaultIndexer {
|
||||
}
|
||||
}
|
||||
|
||||
export { VaultIndexer };
|
||||
export { VaultIndexer, Cache, InMemoryCache, CancellationToken };
|
||||
|
||||
// Convenience method to create a VaultIndexer with an in-memory cache
|
||||
export function <span class="fstat-no" title="function not covered" >createVaultIndexerWithCache(</span>vault: VaultLike): VaultIndexer {
|
||||
<span class="cstat-no" title="statement not covered" > return new VaultIndexer(vault, new InMemoryCache());</span>
|
||||
}
|
||||
</pre></td></tr></table></pre>
|
||||
|
||||
<div class='push'></div><!-- for sticky footer -->
|
||||
@@ -880,7 +1183,7 @@ export { VaultIndexer };
|
||||
<div class='footer quiet pad2 space-top1 center small'>
|
||||
Code coverage generated by
|
||||
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
||||
at 2026-05-06T21:42:52.284Z
|
||||
at 2026-05-06T22:42:47.543Z
|
||||
</div>
|
||||
<script src="prettify.js"></script>
|
||||
<script>
|
||||
|
||||
+439
-335
@@ -488,25 +488,37 @@ FN:24,(anonymous_1)
|
||||
FN:31,(anonymous_2)
|
||||
FN:38,(anonymous_3)
|
||||
FN:49,(anonymous_4)
|
||||
FN:82,(anonymous_5)
|
||||
FN:173,(anonymous_6)
|
||||
FN:177,(anonymous_7)
|
||||
FN:205,(anonymous_8)
|
||||
FN:220,(anonymous_9)
|
||||
FN:226,(anonymous_10)
|
||||
FNF:11
|
||||
FNH:11
|
||||
FN:83,(anonymous_5)
|
||||
FN:84,(anonymous_6)
|
||||
FN:93,(anonymous_7)
|
||||
FN:94,(anonymous_8)
|
||||
FN:200,(anonymous_9)
|
||||
FN:204,(anonymous_10)
|
||||
FN:233,(anonymous_11)
|
||||
FN:234,(anonymous_12)
|
||||
FN:243,(anonymous_13)
|
||||
FN:244,(anonymous_14)
|
||||
FN:274,(anonymous_15)
|
||||
FN:280,(anonymous_16)
|
||||
FNF:17
|
||||
FNH:14
|
||||
FNDA:59,(anonymous_0)
|
||||
FNDA:28,(anonymous_1)
|
||||
FNDA:20,(anonymous_2)
|
||||
FNDA:3,(anonymous_3)
|
||||
FNDA:25,(anonymous_4)
|
||||
FNDA:5,(anonymous_5)
|
||||
FNDA:5,(anonymous_6)
|
||||
FNDA:8,(anonymous_7)
|
||||
FNDA:3,(anonymous_8)
|
||||
FNDA:15,(anonymous_9)
|
||||
FNDA:18,(anonymous_10)
|
||||
FNDA:4,(anonymous_5)
|
||||
FNDA:0,(anonymous_6)
|
||||
FNDA:4,(anonymous_7)
|
||||
FNDA:4,(anonymous_8)
|
||||
FNDA:5,(anonymous_9)
|
||||
FNDA:8,(anonymous_10)
|
||||
FNDA:2,(anonymous_11)
|
||||
FNDA:0,(anonymous_12)
|
||||
FNDA:1,(anonymous_13)
|
||||
FNDA:0,(anonymous_14)
|
||||
FNDA:15,(anonymous_15)
|
||||
FNDA:18,(anonymous_16)
|
||||
DA:4,2
|
||||
DA:5,2
|
||||
DA:11,2
|
||||
@@ -534,76 +546,104 @@ DA:76,8
|
||||
DA:77,5
|
||||
DA:78,5
|
||||
DA:82,5
|
||||
DA:83,5
|
||||
DA:84,2
|
||||
DA:86,3
|
||||
DA:89,13
|
||||
DA:90,1
|
||||
DA:93,12
|
||||
DA:94,12
|
||||
DA:95,1
|
||||
DA:98,11
|
||||
DA:99,11
|
||||
DA:100,11
|
||||
DA:101,11
|
||||
DA:102,11
|
||||
DA:104,11
|
||||
DA:105,11
|
||||
DA:106,19
|
||||
DA:107,19
|
||||
DA:109,10
|
||||
DA:111,10
|
||||
DA:112,10
|
||||
DA:114,10
|
||||
DA:115,68
|
||||
DA:117,67
|
||||
DA:118,67
|
||||
DA:119,14
|
||||
DA:121,13
|
||||
DA:122,13
|
||||
DA:123,0
|
||||
DA:126,13
|
||||
DA:127,13
|
||||
DA:129,54
|
||||
DA:130,1
|
||||
DA:133,53
|
||||
DA:134,53
|
||||
DA:135,1
|
||||
DA:138,52
|
||||
DA:146,9
|
||||
DA:147,1
|
||||
DA:148,1
|
||||
DA:149,1
|
||||
DA:151,1
|
||||
DA:152,1
|
||||
DA:83,4
|
||||
DA:84,4
|
||||
DA:85,0
|
||||
DA:87,4
|
||||
DA:88,4
|
||||
DA:89,4
|
||||
DA:90,4
|
||||
DA:91,4
|
||||
DA:94,4
|
||||
DA:100,4
|
||||
DA:103,0
|
||||
DA:106,5
|
||||
DA:107,2
|
||||
DA:109,3
|
||||
DA:112,13
|
||||
DA:113,1
|
||||
DA:116,12
|
||||
DA:117,12
|
||||
DA:118,1
|
||||
DA:121,11
|
||||
DA:122,11
|
||||
DA:123,11
|
||||
DA:124,11
|
||||
DA:125,11
|
||||
DA:127,11
|
||||
DA:128,11
|
||||
DA:129,19
|
||||
DA:130,19
|
||||
DA:132,10
|
||||
DA:134,10
|
||||
DA:135,10
|
||||
DA:137,10
|
||||
DA:138,68
|
||||
DA:140,67
|
||||
DA:141,67
|
||||
DA:142,14
|
||||
DA:144,13
|
||||
DA:145,13
|
||||
DA:146,0
|
||||
DA:149,13
|
||||
DA:150,13
|
||||
DA:152,54
|
||||
DA:153,1
|
||||
DA:156,0
|
||||
DA:157,0
|
||||
DA:159,0
|
||||
DA:166,11
|
||||
DA:169,25
|
||||
DA:174,5
|
||||
DA:182,8
|
||||
DA:183,8
|
||||
DA:184,8
|
||||
DA:198,8
|
||||
DA:199,4
|
||||
DA:200,3
|
||||
DA:201,3
|
||||
DA:205,3
|
||||
DA:206,3
|
||||
DA:208,1
|
||||
DA:211,4
|
||||
DA:212,4
|
||||
DA:216,8
|
||||
DA:221,15
|
||||
DA:222,1
|
||||
DA:227,18
|
||||
DA:228,1
|
||||
DA:231,17
|
||||
DA:232,17
|
||||
LF:95
|
||||
LH:87
|
||||
DA:156,53
|
||||
DA:157,53
|
||||
DA:158,1
|
||||
DA:161,52
|
||||
DA:169,9
|
||||
DA:170,1
|
||||
DA:171,1
|
||||
DA:172,1
|
||||
DA:174,1
|
||||
DA:175,1
|
||||
DA:176,1
|
||||
DA:179,0
|
||||
DA:180,0
|
||||
DA:182,0
|
||||
DA:189,11
|
||||
DA:192,25
|
||||
DA:193,25
|
||||
DA:194,25
|
||||
DA:195,20
|
||||
DA:201,5
|
||||
DA:209,8
|
||||
DA:210,8
|
||||
DA:211,8
|
||||
DA:225,8
|
||||
DA:226,4
|
||||
DA:227,3
|
||||
DA:228,3
|
||||
DA:232,3
|
||||
DA:233,2
|
||||
DA:234,2
|
||||
DA:235,0
|
||||
DA:237,2
|
||||
DA:238,2
|
||||
DA:239,1
|
||||
DA:240,1
|
||||
DA:241,1
|
||||
DA:244,1
|
||||
DA:250,1
|
||||
DA:253,1
|
||||
DA:256,3
|
||||
DA:258,1
|
||||
DA:261,4
|
||||
DA:262,4
|
||||
DA:266,8
|
||||
DA:267,8
|
||||
DA:268,8
|
||||
DA:269,7
|
||||
DA:275,15
|
||||
DA:276,1
|
||||
DA:281,18
|
||||
DA:282,1
|
||||
DA:285,17
|
||||
DA:286,17
|
||||
LF:123
|
||||
LH:112
|
||||
BRDA:21,0,0,59
|
||||
BRDA:21,0,1,36
|
||||
BRDA:25,1,0,0
|
||||
@@ -616,46 +656,54 @@ BRDA:75,7,0,8
|
||||
BRDA:76,8,0,5
|
||||
BRDA:76,9,0,8
|
||||
BRDA:76,9,1,6
|
||||
BRDA:89,10,0,1
|
||||
BRDA:94,11,0,1
|
||||
BRDA:94,12,0,12
|
||||
BRDA:94,12,1,12
|
||||
BRDA:94,12,2,1
|
||||
BRDA:107,13,0,9
|
||||
BRDA:112,14,0,10
|
||||
BRDA:112,14,1,0
|
||||
BRDA:115,15,0,1
|
||||
BRDA:122,16,0,0
|
||||
BRDA:129,17,0,1
|
||||
BRDA:129,18,0,54
|
||||
BRDA:129,18,1,54
|
||||
BRDA:134,19,0,1
|
||||
BRDA:146,20,0,1
|
||||
BRDA:152,21,0,1
|
||||
BRDA:156,22,0,0
|
||||
BRDA:156,23,0,0
|
||||
BRDA:156,23,1,0
|
||||
BRDA:173,24,0,0
|
||||
BRDA:82,10,0,4
|
||||
BRDA:88,11,0,4
|
||||
BRDA:88,11,1,0
|
||||
BRDA:112,12,0,1
|
||||
BRDA:117,13,0,1
|
||||
BRDA:117,14,0,12
|
||||
BRDA:117,14,1,12
|
||||
BRDA:117,14,2,1
|
||||
BRDA:130,15,0,9
|
||||
BRDA:135,16,0,10
|
||||
BRDA:135,16,1,0
|
||||
BRDA:138,17,0,1
|
||||
BRDA:145,18,0,0
|
||||
BRDA:152,19,0,1
|
||||
BRDA:152,20,0,54
|
||||
BRDA:152,20,1,54
|
||||
BRDA:157,21,0,1
|
||||
BRDA:169,22,0,1
|
||||
BRDA:175,23,0,1
|
||||
BRDA:179,24,0,0
|
||||
BRDA:179,25,0,0
|
||||
BRDA:180,26,0,0
|
||||
BRDA:198,27,0,4
|
||||
BRDA:199,28,0,3
|
||||
BRDA:199,29,0,4
|
||||
BRDA:199,29,1,4
|
||||
BRDA:213,30,0,4
|
||||
BRDA:213,30,1,1
|
||||
BRDA:221,31,0,1
|
||||
BRDA:227,32,0,1
|
||||
BRDA:227,33,0,18
|
||||
BRDA:227,33,1,17
|
||||
BRDA:233,34,0,17
|
||||
BRDA:233,34,1,17
|
||||
BRDA:234,35,0,17
|
||||
BRDA:234,35,1,0
|
||||
BRDA:235,36,0,17
|
||||
BRDA:235,36,1,15
|
||||
BRF:50
|
||||
BRH:36
|
||||
BRDA:179,25,1,0
|
||||
BRDA:194,26,0,20
|
||||
BRDA:200,27,0,0
|
||||
BRDA:206,28,0,0
|
||||
BRDA:207,29,0,0
|
||||
BRDA:225,30,0,4
|
||||
BRDA:226,31,0,3
|
||||
BRDA:226,32,0,4
|
||||
BRDA:226,32,1,4
|
||||
BRDA:232,33,0,2
|
||||
BRDA:238,34,0,1
|
||||
BRDA:238,34,1,1
|
||||
BRDA:263,35,0,4
|
||||
BRDA:263,35,1,1
|
||||
BRDA:268,36,0,7
|
||||
BRDA:275,37,0,1
|
||||
BRDA:281,38,0,1
|
||||
BRDA:281,39,0,18
|
||||
BRDA:281,39,1,17
|
||||
BRDA:287,40,0,17
|
||||
BRDA:287,40,1,17
|
||||
BRDA:288,41,0,17
|
||||
BRDA:288,41,1,0
|
||||
BRDA:289,42,0,17
|
||||
BRDA:289,42,1,15
|
||||
BRF:58
|
||||
BRH:43
|
||||
end_of_record
|
||||
TN:
|
||||
SF:src/tool-executor.ts
|
||||
@@ -844,10 +892,9 @@ FN:137,(anonymous_11)
|
||||
FN:142,safeParseJson
|
||||
FN:159,(anonymous_13)
|
||||
FN:165,(anonymous_14)
|
||||
FN:195,isValidHttpUrl
|
||||
FNF:16
|
||||
FNH:15
|
||||
FNDA:5,(anonymous_0)
|
||||
FNF:15
|
||||
FNH:14
|
||||
FNDA:6,(anonymous_0)
|
||||
FNDA:23,(anonymous_1)
|
||||
FNDA:4,(anonymous_2)
|
||||
FNDA:4,(anonymous_3)
|
||||
@@ -862,15 +909,14 @@ FNDA:83,(anonymous_11)
|
||||
FNDA:41,safeParseJson
|
||||
FNDA:121,(anonymous_13)
|
||||
FNDA:183,(anonymous_14)
|
||||
FNDA:6,isValidHttpUrl
|
||||
DA:1,5
|
||||
DA:2,5
|
||||
DA:3,5
|
||||
DA:4,5
|
||||
DA:5,5
|
||||
DA:8,5
|
||||
DA:15,5
|
||||
DA:16,5
|
||||
DA:1,6
|
||||
DA:2,6
|
||||
DA:3,6
|
||||
DA:4,6
|
||||
DA:5,6
|
||||
DA:8,6
|
||||
DA:15,6
|
||||
DA:16,6
|
||||
DA:19,23
|
||||
DA:20,11
|
||||
DA:21,11
|
||||
@@ -883,7 +929,7 @@ DA:40,64
|
||||
DA:41,63
|
||||
DA:46,2
|
||||
DA:47,2
|
||||
DA:54,5
|
||||
DA:54,6
|
||||
DA:55,12
|
||||
DA:56,2
|
||||
DA:59,10
|
||||
@@ -895,7 +941,7 @@ DA:67,6
|
||||
DA:68,0
|
||||
DA:70,6
|
||||
DA:72,3
|
||||
DA:76,5
|
||||
DA:76,6
|
||||
DA:77,15
|
||||
DA:78,1
|
||||
DA:81,14
|
||||
@@ -908,7 +954,7 @@ DA:93,1
|
||||
DA:96,11
|
||||
DA:97,3
|
||||
DA:103,8
|
||||
DA:106,5
|
||||
DA:106,6
|
||||
DA:107,4
|
||||
DA:109,4
|
||||
DA:110,4
|
||||
@@ -917,8 +963,8 @@ DA:114,4
|
||||
DA:115,4
|
||||
DA:116,2
|
||||
DA:119,4
|
||||
DA:124,5
|
||||
DA:125,5
|
||||
DA:124,6
|
||||
DA:125,6
|
||||
DA:128,117
|
||||
DA:129,1
|
||||
DA:131,116
|
||||
@@ -928,7 +974,7 @@ DA:135,58
|
||||
DA:136,58
|
||||
DA:137,83
|
||||
DA:139,58
|
||||
DA:142,5
|
||||
DA:142,6
|
||||
DA:143,41
|
||||
DA:144,1
|
||||
DA:147,40
|
||||
@@ -951,15 +997,10 @@ DA:180,3
|
||||
DA:184,34
|
||||
DA:185,1
|
||||
DA:188,33
|
||||
DA:195,5
|
||||
DA:196,6
|
||||
DA:197,6
|
||||
DA:198,4
|
||||
DA:200,2
|
||||
LF:93
|
||||
LH:90
|
||||
BRDA:1,0,0,5
|
||||
BRDA:1,0,1,5
|
||||
LF:88
|
||||
LH:85
|
||||
BRDA:1,0,0,6
|
||||
BRDA:1,0,1,6
|
||||
BRDA:19,1,0,11
|
||||
BRDA:19,1,1,12
|
||||
BRDA:21,2,0,11
|
||||
@@ -1004,196 +1045,259 @@ BRDA:165,34,0,3
|
||||
BRDA:171,35,0,0
|
||||
BRDA:179,36,0,3
|
||||
BRDA:184,37,0,1
|
||||
BRDA:198,38,0,4
|
||||
BRDA:198,38,1,3
|
||||
BRF:48
|
||||
BRH:41
|
||||
BRF:46
|
||||
BRH:39
|
||||
end_of_record
|
||||
TN:
|
||||
SF:src/vault-indexer.ts
|
||||
FN:36,(anonymous_0)
|
||||
FN:40,(anonymous_1)
|
||||
FN:55,(anonymous_2)
|
||||
FN:56,(anonymous_3)
|
||||
FN:60,(anonymous_4)
|
||||
FN:72,(anonymous_5)
|
||||
FN:102,(anonymous_6)
|
||||
FN:110,(anonymous_7)
|
||||
FN:141,(anonymous_8)
|
||||
FN:144,(anonymous_9)
|
||||
FN:176,(anonymous_10)
|
||||
FN:195,(anonymous_11)
|
||||
FN:228,(anonymous_12)
|
||||
FN:255,(anonymous_13)
|
||||
FN:264,(anonymous_14)
|
||||
FNF:15
|
||||
FNH:15
|
||||
FNDA:67,(anonymous_0)
|
||||
FNDA:33,(anonymous_1)
|
||||
FNDA:50,(anonymous_2)
|
||||
FNDA:38,(anonymous_3)
|
||||
FNDA:31,(anonymous_4)
|
||||
FNDA:54,(anonymous_5)
|
||||
FNDA:54,(anonymous_6)
|
||||
FNDA:100,(anonymous_7)
|
||||
FNDA:367,(anonymous_8)
|
||||
FNDA:60,(anonymous_9)
|
||||
FNDA:3,(anonymous_10)
|
||||
FNDA:58,(anonymous_11)
|
||||
FNDA:1,(anonymous_12)
|
||||
FNDA:127,(anonymous_13)
|
||||
FN:15,(anonymous_0)
|
||||
FN:19,(anonymous_1)
|
||||
FN:23,(anonymous_2)
|
||||
FN:28,(anonymous_3)
|
||||
FN:34,(anonymous_4)
|
||||
FN:37,(anonymous_5)
|
||||
FN:41,(anonymous_6)
|
||||
FN:77,(anonymous_7)
|
||||
FN:82,(anonymous_8)
|
||||
FN:110,(anonymous_9)
|
||||
FN:111,(anonymous_10)
|
||||
FN:128,(anonymous_11)
|
||||
FN:140,(anonymous_12)
|
||||
FN:154,(anonymous_13)
|
||||
FN:184,(anonymous_14)
|
||||
FN:206,(anonymous_15)
|
||||
FN:237,(anonymous_16)
|
||||
FN:240,(anonymous_17)
|
||||
FN:272,(anonymous_18)
|
||||
FN:291,(anonymous_19)
|
||||
FN:324,(anonymous_20)
|
||||
FN:351,(anonymous_21)
|
||||
FN:360,(anonymous_22)
|
||||
FN:369,createVaultIndexerWithCache
|
||||
FNF:24
|
||||
FNH:20
|
||||
FNDA:1,(anonymous_0)
|
||||
FNDA:2,(anonymous_1)
|
||||
FNDA:1,(anonymous_2)
|
||||
FNDA:0,(anonymous_3)
|
||||
FNDA:34,(anonymous_4)
|
||||
FNDA:0,(anonymous_5)
|
||||
FNDA:18,(anonymous_6)
|
||||
FNDA:71,(anonymous_7)
|
||||
FNDA:38,(anonymous_8)
|
||||
FNDA:53,(anonymous_9)
|
||||
FNDA:38,(anonymous_10)
|
||||
FNDA:34,(anonymous_11)
|
||||
FNDA:0,(anonymous_12)
|
||||
FNDA:63,(anonymous_13)
|
||||
FNDA:63,(anonymous_14)
|
||||
DA:4,2
|
||||
DA:34,67
|
||||
DA:37,67
|
||||
DA:41,33
|
||||
DA:42,2
|
||||
DA:45,31
|
||||
DA:46,0
|
||||
DA:49,31
|
||||
DA:50,31
|
||||
DA:51,31
|
||||
DA:52,31
|
||||
DA:54,31
|
||||
DA:55,50
|
||||
DA:56,38
|
||||
DA:65,31
|
||||
DA:66,31
|
||||
DA:67,31
|
||||
DA:69,31
|
||||
DA:70,15
|
||||
DA:71,15
|
||||
DA:73,54
|
||||
DA:74,54
|
||||
DA:75,53
|
||||
DA:76,53
|
||||
DA:77,53
|
||||
DA:78,50
|
||||
DA:84,50
|
||||
DA:85,50
|
||||
DA:86,50
|
||||
FNDA:112,(anonymous_15)
|
||||
FNDA:469,(anonymous_16)
|
||||
FNDA:69,(anonymous_17)
|
||||
FNDA:12,(anonymous_18)
|
||||
FNDA:67,(anonymous_19)
|
||||
FNDA:10,(anonymous_20)
|
||||
FNDA:145,(anonymous_21)
|
||||
FNDA:72,(anonymous_22)
|
||||
FNDA:0,createVaultIndexerWithCache
|
||||
DA:4,3
|
||||
DA:16,1
|
||||
DA:20,2
|
||||
DA:24,1
|
||||
DA:25,1
|
||||
DA:29,0
|
||||
DA:30,0
|
||||
DA:35,34
|
||||
DA:38,0
|
||||
DA:42,18
|
||||
DA:74,71
|
||||
DA:78,71
|
||||
DA:79,71
|
||||
DA:83,38
|
||||
DA:84,3
|
||||
DA:87,35
|
||||
DA:88,0
|
||||
DA:90,3
|
||||
DA:92,1
|
||||
DA:91,35
|
||||
DA:92,35
|
||||
DA:93,3
|
||||
DA:94,3
|
||||
DA:95,1
|
||||
DA:96,1
|
||||
DA:101,15
|
||||
DA:102,54
|
||||
DA:104,15
|
||||
DA:107,31
|
||||
DA:111,100
|
||||
DA:138,100
|
||||
DA:141,367
|
||||
DA:145,60
|
||||
DA:146,60
|
||||
DA:147,60
|
||||
DA:150,60
|
||||
DA:151,60
|
||||
DA:152,2
|
||||
DA:153,2
|
||||
DA:154,2
|
||||
DA:155,2
|
||||
DA:156,3
|
||||
DA:157,3
|
||||
DA:158,3
|
||||
DA:159,3
|
||||
DA:160,1
|
||||
DA:161,1
|
||||
DA:163,2
|
||||
DA:164,2
|
||||
DA:165,2
|
||||
DA:97,1
|
||||
DA:104,34
|
||||
DA:105,34
|
||||
DA:106,34
|
||||
DA:107,34
|
||||
DA:109,34
|
||||
DA:110,53
|
||||
DA:111,38
|
||||
DA:114,34
|
||||
DA:115,2
|
||||
DA:116,2
|
||||
DA:118,0
|
||||
DA:125,34
|
||||
DA:133,34
|
||||
DA:134,34
|
||||
DA:135,34
|
||||
DA:136,34
|
||||
DA:137,34
|
||||
DA:140,34
|
||||
DA:141,0
|
||||
DA:142,0
|
||||
DA:146,34
|
||||
DA:147,34
|
||||
DA:148,18
|
||||
DA:149,0
|
||||
DA:152,18
|
||||
DA:153,18
|
||||
DA:155,63
|
||||
DA:156,63
|
||||
DA:157,62
|
||||
DA:158,62
|
||||
DA:159,62
|
||||
DA:160,53
|
||||
DA:166,53
|
||||
DA:167,53
|
||||
DA:168,53
|
||||
DA:170,0
|
||||
DA:174,60
|
||||
DA:175,60
|
||||
DA:176,3
|
||||
DA:179,60
|
||||
DA:180,60
|
||||
DA:181,60
|
||||
DA:184,60
|
||||
DA:190,60
|
||||
DA:192,60
|
||||
DA:200,58
|
||||
DA:201,58
|
||||
DA:203,58
|
||||
DA:204,64
|
||||
DA:205,64
|
||||
DA:206,64
|
||||
DA:208,64
|
||||
DA:212,0
|
||||
DA:213,0
|
||||
DA:214,64
|
||||
DA:219,1
|
||||
DA:220,1
|
||||
DA:223,64
|
||||
DA:224,1
|
||||
DA:225,1
|
||||
DA:228,64
|
||||
DA:229,1
|
||||
DA:230,1
|
||||
DA:233,64
|
||||
DA:234,58
|
||||
DA:235,58
|
||||
DA:238,64
|
||||
DA:239,56
|
||||
DA:240,56
|
||||
DA:243,64
|
||||
DA:244,60
|
||||
DA:245,60
|
||||
DA:249,58
|
||||
DA:257,127
|
||||
DA:258,127
|
||||
DA:259,126
|
||||
DA:260,126
|
||||
DA:261,122
|
||||
DA:265,63
|
||||
DA:266,63
|
||||
DA:270,2
|
||||
LF:104
|
||||
LH:99
|
||||
BRDA:40,0,0,0
|
||||
BRDA:41,1,0,2
|
||||
BRDA:41,2,0,33
|
||||
BRDA:41,2,1,32
|
||||
BRDA:45,3,0,0
|
||||
BRDA:77,4,0,50
|
||||
BRDA:84,5,0,50
|
||||
BRDA:93,6,0,1
|
||||
BRDA:93,6,1,0
|
||||
BRDA:141,7,0,367
|
||||
BRDA:141,7,1,358
|
||||
BRDA:151,8,0,2
|
||||
BRDA:157,9,0,0
|
||||
BRDA:159,10,0,1
|
||||
BRDA:159,10,1,2
|
||||
BRDA:160,11,0,1
|
||||
BRDA:163,12,0,2
|
||||
BRDA:164,13,0,2
|
||||
BRDA:175,14,0,2
|
||||
BRDA:180,15,0,60
|
||||
BRDA:208,16,0,0
|
||||
BRDA:208,16,1,64
|
||||
BRDA:209,17,0,64
|
||||
BRDA:209,17,1,0
|
||||
BRDA:214,18,0,1
|
||||
BRDA:215,19,0,64
|
||||
BRDA:215,19,1,56
|
||||
BRDA:215,19,2,56
|
||||
BRDA:223,20,0,1
|
||||
BRDA:223,21,0,64
|
||||
BRDA:223,21,1,1
|
||||
BRDA:228,22,0,1
|
||||
BRDA:233,23,0,58
|
||||
BRDA:233,24,0,64
|
||||
BRDA:233,24,1,63
|
||||
BRDA:238,25,0,56
|
||||
BRDA:243,26,0,60
|
||||
BRDA:257,27,0,0
|
||||
BRDA:258,28,0,1
|
||||
BRDA:259,29,0,0
|
||||
BRDA:259,30,0,126
|
||||
BRDA:259,30,1,0
|
||||
BRDA:260,31,0,4
|
||||
BRDA:260,32,0,126
|
||||
BRDA:260,32,1,4
|
||||
BRF:45
|
||||
BRH:36
|
||||
DA:172,9
|
||||
DA:174,1
|
||||
DA:178,1
|
||||
DA:183,18
|
||||
DA:184,63
|
||||
DA:186,18
|
||||
DA:189,18
|
||||
DA:190,0
|
||||
DA:194,0
|
||||
DA:197,18
|
||||
DA:200,34
|
||||
DA:203,34
|
||||
DA:207,112
|
||||
DA:234,112
|
||||
DA:237,469
|
||||
DA:241,69
|
||||
DA:242,69
|
||||
DA:243,69
|
||||
DA:246,69
|
||||
DA:247,69
|
||||
DA:248,2
|
||||
DA:249,2
|
||||
DA:250,2
|
||||
DA:251,2
|
||||
DA:252,3
|
||||
DA:253,3
|
||||
DA:254,3
|
||||
DA:255,3
|
||||
DA:256,1
|
||||
DA:257,1
|
||||
DA:259,2
|
||||
DA:260,2
|
||||
DA:261,2
|
||||
DA:266,0
|
||||
DA:270,69
|
||||
DA:271,69
|
||||
DA:272,12
|
||||
DA:275,69
|
||||
DA:276,69
|
||||
DA:277,69
|
||||
DA:280,69
|
||||
DA:286,69
|
||||
DA:288,69
|
||||
DA:296,67
|
||||
DA:297,67
|
||||
DA:299,67
|
||||
DA:300,73
|
||||
DA:301,73
|
||||
DA:302,73
|
||||
DA:304,73
|
||||
DA:308,0
|
||||
DA:309,0
|
||||
DA:310,73
|
||||
DA:315,1
|
||||
DA:316,1
|
||||
DA:319,73
|
||||
DA:320,1
|
||||
DA:321,1
|
||||
DA:324,73
|
||||
DA:325,4
|
||||
DA:326,4
|
||||
DA:329,73
|
||||
DA:330,58
|
||||
DA:331,58
|
||||
DA:334,73
|
||||
DA:335,56
|
||||
DA:336,56
|
||||
DA:339,73
|
||||
DA:340,63
|
||||
DA:341,63
|
||||
DA:345,67
|
||||
DA:353,145
|
||||
DA:354,145
|
||||
DA:355,144
|
||||
DA:356,144
|
||||
DA:357,122
|
||||
DA:361,72
|
||||
DA:362,72
|
||||
DA:366,3
|
||||
DA:369,3
|
||||
DA:370,0
|
||||
LF:141
|
||||
LH:126
|
||||
BRDA:20,0,0,2
|
||||
BRDA:20,0,1,1
|
||||
BRDA:82,1,0,5
|
||||
BRDA:83,2,0,3
|
||||
BRDA:83,3,0,38
|
||||
BRDA:83,3,1,36
|
||||
BRDA:87,4,0,0
|
||||
BRDA:92,5,0,3
|
||||
BRDA:94,6,0,1
|
||||
BRDA:114,7,0,2
|
||||
BRDA:119,8,0,0
|
||||
BRDA:119,8,1,0
|
||||
BRDA:141,9,0,0
|
||||
BRDA:148,10,0,0
|
||||
BRDA:159,11,0,53
|
||||
BRDA:166,12,0,53
|
||||
BRDA:175,13,0,1
|
||||
BRDA:175,13,1,0
|
||||
BRDA:189,14,0,0
|
||||
BRDA:237,15,0,469
|
||||
BRDA:237,15,1,442
|
||||
BRDA:247,16,0,2
|
||||
BRDA:253,17,0,0
|
||||
BRDA:255,18,0,1
|
||||
BRDA:255,18,1,2
|
||||
BRDA:256,19,0,1
|
||||
BRDA:259,20,0,2
|
||||
BRDA:260,21,0,2
|
||||
BRDA:271,22,0,11
|
||||
BRDA:276,23,0,69
|
||||
BRDA:304,24,0,0
|
||||
BRDA:304,24,1,73
|
||||
BRDA:305,25,0,73
|
||||
BRDA:305,25,1,0
|
||||
BRDA:310,26,0,1
|
||||
BRDA:311,27,0,73
|
||||
BRDA:311,27,1,65
|
||||
BRDA:311,27,2,65
|
||||
BRDA:319,28,0,1
|
||||
BRDA:319,29,0,73
|
||||
BRDA:319,29,1,1
|
||||
BRDA:324,30,0,4
|
||||
BRDA:329,31,0,58
|
||||
BRDA:329,32,0,73
|
||||
BRDA:329,32,1,63
|
||||
BRDA:334,33,0,56
|
||||
BRDA:339,34,0,63
|
||||
BRDA:353,35,0,0
|
||||
BRDA:354,36,0,1
|
||||
BRDA:355,37,0,0
|
||||
BRDA:355,38,0,144
|
||||
BRDA:355,38,1,0
|
||||
BRDA:356,39,0,22
|
||||
BRDA:356,40,0,144
|
||||
BRDA:356,40,1,22
|
||||
BRF:55
|
||||
BRH:42
|
||||
end_of_record
|
||||
|
||||
+56
-2
@@ -79,7 +79,30 @@ export class OllamaClient {
|
||||
`Network error (status ${response.status}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${this.maxRetries})`,
|
||||
'ollama-client'
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
if (attempt < this.maxRetries - 1) {
|
||||
const retryTimeout = new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
const abortListener = () => {
|
||||
Logger.info('Retry aborted by user', 'ollama-client');
|
||||
};
|
||||
const signal = this.abortController?.signal;
|
||||
if (signal) {
|
||||
signal.addEventListener('abort', abortListener);
|
||||
try {
|
||||
await Promise.race([
|
||||
retryTimeout,
|
||||
new Promise<void>((resolve) => {
|
||||
signal.addEventListener('abort', () => resolve(), {
|
||||
once: true,
|
||||
});
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
signal.removeEventListener('abort', abortListener);
|
||||
}
|
||||
} else {
|
||||
await retryTimeout;
|
||||
}
|
||||
}
|
||||
yield* this.streamChatWithRetry(messages, tools, attempt + 1);
|
||||
return;
|
||||
}
|
||||
@@ -166,7 +189,11 @@ export class OllamaClient {
|
||||
reader.releaseLock();
|
||||
}
|
||||
} finally {
|
||||
const controller = this.abortController;
|
||||
this.abortController = null;
|
||||
if (controller) {
|
||||
controller.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +229,30 @@ export class OllamaClient {
|
||||
`Network error (status ${response.status}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${this.maxRetries})`,
|
||||
'ollama-client'
|
||||
);
|
||||
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
if (attempt < this.maxRetries - 1) {
|
||||
const retryTimeout = new Promise((resolve) => setTimeout(resolve, retryDelay));
|
||||
const abortListener = () => {
|
||||
Logger.info('Retry aborted by user', 'ollama-client');
|
||||
};
|
||||
const signal = this.abortController?.signal;
|
||||
if (signal) {
|
||||
signal.addEventListener('abort', abortListener);
|
||||
try {
|
||||
await Promise.race([
|
||||
retryTimeout,
|
||||
new Promise<void>((resolve) => {
|
||||
signal.addEventListener('abort', () => resolve(), {
|
||||
once: true,
|
||||
});
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
signal.removeEventListener('abort', abortListener);
|
||||
}
|
||||
} else {
|
||||
await retryTimeout;
|
||||
}
|
||||
}
|
||||
return this.chatWithRetry(messages, tools, attempt + 1);
|
||||
}
|
||||
throw new ApiError(`Ollama API error: ${response.status}`, response.status);
|
||||
@@ -213,7 +263,11 @@ export class OllamaClient {
|
||||
this.toOllamaMessage(data.message) ?? { role: 'assistant', content: '', tool_calls: [] }
|
||||
);
|
||||
} finally {
|
||||
const controller = this.abortController;
|
||||
this.abortController = null;
|
||||
if (controller) {
|
||||
controller.abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+136
-35
@@ -3,6 +3,46 @@
|
||||
import { VaultIndexEntry } from './types';
|
||||
import { Logger } from './utils';
|
||||
|
||||
interface Cache {
|
||||
get(key: string): Promise<string | null>;
|
||||
put(key: string, value: string): Promise<void>;
|
||||
clear(): Promise<void>;
|
||||
}
|
||||
|
||||
class InMemoryCache implements Cache {
|
||||
private store: Map<string, string>;
|
||||
|
||||
constructor() {
|
||||
this.store = new Map();
|
||||
}
|
||||
|
||||
get(key: string): Promise<string | null> {
|
||||
return Promise.resolve(this.store.get(key) || null);
|
||||
}
|
||||
|
||||
put(key: string, value: string): Promise<void> {
|
||||
this.store.set(key, value);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
clear(): Promise<void> {
|
||||
this.store.clear();
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
class CancellationToken {
|
||||
private cancelled = false;
|
||||
|
||||
cancel(): void {
|
||||
this.cancelled = true;
|
||||
}
|
||||
|
||||
get isCancelled(): boolean {
|
||||
return this.cancelled;
|
||||
}
|
||||
}
|
||||
|
||||
interface Frontmatter {
|
||||
title?: string;
|
||||
tags?: string;
|
||||
@@ -32,9 +72,11 @@ interface ScoreResult {
|
||||
|
||||
class VaultIndexer {
|
||||
private vault: VaultLike | null = null;
|
||||
private cache?: Cache;
|
||||
|
||||
constructor(vault: VaultLike) {
|
||||
constructor(vault: VaultLike, cache?: Cache) {
|
||||
this.vault = vault;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
async searchVault(query: string, limit: number = 5): Promise<VaultIndexEntry[]> {
|
||||
@@ -46,15 +88,41 @@ class VaultIndexer {
|
||||
throw new Error('Vault-like object not provided to VaultIndexer');
|
||||
}
|
||||
|
||||
const cacheKey = `query:${query.trim()}`;
|
||||
if (this.cache) {
|
||||
const cachedResults = await this.cache.get(cacheKey);
|
||||
if (cachedResults) {
|
||||
try {
|
||||
const parsedResults = JSON.parse(cachedResults) as VaultIndexEntry[];
|
||||
return parsedResults.slice(0, limit);
|
||||
} catch {
|
||||
// Ignore cache parse errors and continue with normal processing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const queryTokens = this.tokenize(query.trim());
|
||||
const vault = this.vault;
|
||||
const allFiles = vault.getMarkdownFiles();
|
||||
const results = await this.processFilesInBatches(vault, allFiles, queryTokens);
|
||||
|
||||
return results
|
||||
const filteredResults = results
|
||||
.filter((result): result is NonNullable<typeof result> => result !== null)
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.slice(0, limit);
|
||||
|
||||
if (this.cache) {
|
||||
try {
|
||||
await this.cache.put(cacheKey, JSON.stringify(filteredResults));
|
||||
} catch (error) {
|
||||
Logger.warn(
|
||||
`Failed to cache results for query "${query}": ${error instanceof Error ? error.message : String(error)}`,
|
||||
'vault-indexer'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredResults;
|
||||
}
|
||||
|
||||
private async processFilesInBatches(
|
||||
@@ -65,43 +133,71 @@ class VaultIndexer {
|
||||
const batchSize = 10;
|
||||
const results: VaultIndexEntry[] = [];
|
||||
const seenPaths = new Set<string>();
|
||||
const cancellationToken = new CancellationToken();
|
||||
let processedCount = 0;
|
||||
|
||||
for (let i = 0; i < files.length; i += batchSize) {
|
||||
const batch = files.slice(i, i + batchSize);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(async (file) => {
|
||||
try {
|
||||
const content = await vault.read(file);
|
||||
const tokenized = this.tokenizeContent(content);
|
||||
const scoreResult = this.calculateWeightedScore(tokenized, queryTokens, file);
|
||||
if (scoreResult.score > 0) {
|
||||
const entry: VaultIndexEntry = {
|
||||
path: file.path,
|
||||
title: file.basename.replace(/\.md$/, ''),
|
||||
content: content.substring(0, 500),
|
||||
score: scoreResult.score,
|
||||
};
|
||||
if (!seenPaths.has(entry.path)) {
|
||||
seenPaths.add(entry.path);
|
||||
return entry;
|
||||
// Set up a check for cancellation every 100 files
|
||||
const checkInterval = setInterval(() => {
|
||||
if (cancellationToken.isCancelled) {
|
||||
clearInterval(checkInterval);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
try {
|
||||
for (let i = 0; i < files.length; i += batchSize) {
|
||||
if (cancellationToken.isCancelled) {
|
||||
break;
|
||||
}
|
||||
|
||||
const batch = files.slice(i, i + batchSize);
|
||||
const batchResults = await Promise.all(
|
||||
batch.map(async (file) => {
|
||||
try {
|
||||
const content = await vault.read(file);
|
||||
const tokenized = this.tokenizeContent(content);
|
||||
const scoreResult = this.calculateWeightedScore(tokenized, queryTokens, file);
|
||||
if (scoreResult.score > 0) {
|
||||
const entry: VaultIndexEntry = {
|
||||
path: file.path,
|
||||
title: file.basename.replace(/\.md$/, ''),
|
||||
content: content.substring(0, 500),
|
||||
score: scoreResult.score,
|
||||
};
|
||||
if (!seenPaths.has(entry.path)) {
|
||||
seenPaths.add(entry.path);
|
||||
return entry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
Logger.warn(
|
||||
`Failed to process ${file.path}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
'vault-indexer'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
} catch (error) {
|
||||
Logger.warn(
|
||||
`Failed to process ${file.path}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
'vault-indexer'
|
||||
);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
const validResults = batchResults.filter(
|
||||
(result): result is NonNullable<typeof result> => result !== null
|
||||
);
|
||||
results.push(...validResults);
|
||||
const validResults = batchResults.filter(
|
||||
(result): result is NonNullable<typeof result> => result !== null
|
||||
);
|
||||
results.push(...validResults);
|
||||
|
||||
// Early exit if we've reached enough results
|
||||
if (results.length >= 100) {
|
||||
Logger.info(
|
||||
`Early exit after processing ${processedCount + batch.length} files with ${results.length} results`,
|
||||
'vault-indexer'
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
processedCount += batch.length;
|
||||
}
|
||||
} finally {
|
||||
clearInterval(checkInterval);
|
||||
}
|
||||
|
||||
return results;
|
||||
@@ -267,4 +363,9 @@ class VaultIndexer {
|
||||
}
|
||||
}
|
||||
|
||||
export { VaultIndexer };
|
||||
export { VaultIndexer, Cache, InMemoryCache, CancellationToken };
|
||||
|
||||
// Convenience method to create a VaultIndexer with an in-memory cache
|
||||
export function createVaultIndexerWithCache(vault: VaultLike): VaultIndexer {
|
||||
return new VaultIndexer(vault, new InMemoryCache());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// @ts-nocheck
|
||||
|
||||
const { VaultIndexer, InMemoryCache } = require('../src/vault-indexer');
|
||||
|
||||
// Mock vault implementation for testing
|
||||
class MockVault {
|
||||
constructor(files = []) {
|
||||
this.files = files;
|
||||
this.contentMap = {};
|
||||
}
|
||||
|
||||
getMarkdownFiles() {
|
||||
return this.files;
|
||||
}
|
||||
|
||||
async read(file) {
|
||||
return this.contentMap[file.path] || '';
|
||||
}
|
||||
}
|
||||
|
||||
describe('VaultIndexer caching functionality', () => {
|
||||
let mockVault;
|
||||
|
||||
beforeEach(() => {
|
||||
const mockFiles = [
|
||||
{ basename: 'file1.md', path: 'path/to/file1.md' },
|
||||
{ basename: 'file2.md', path: 'path/to/file2.md' },
|
||||
{ basename: 'file3.md', path: 'path/to/file3.md' },
|
||||
];
|
||||
|
||||
mockVault = new MockVault(mockFiles);
|
||||
|
||||
// Set up content for testing
|
||||
mockVault.contentMap = {
|
||||
'path/to/file1.md':
|
||||
'# Testing Introduction\nThis file is about testing methodologies. Testing is crucial for quality assurance.',
|
||||
'path/to/file2.md':
|
||||
'# Development Practices\nDevelopment includes coding standards and testing frameworks.',
|
||||
'path/to/file3.md':
|
||||
'# Quality Assurance\nQuality assurance focuses on testing processes and validation.',
|
||||
};
|
||||
});
|
||||
|
||||
it('should cache query results', async () => {
|
||||
const cache = new InMemoryCache();
|
||||
const indexer = new VaultIndexer(mockVault, cache);
|
||||
|
||||
// First query - should process files
|
||||
const results1 = await indexer.searchVault('testing');
|
||||
expect(results1.length).toBeGreaterThan(0);
|
||||
|
||||
// Second query - should use cache
|
||||
const results2 = await indexer.searchVault('testing');
|
||||
expect(results2).toEqual(results1);
|
||||
});
|
||||
|
||||
it('should handle cache errors gracefully', async () => {
|
||||
const faultyCache = {
|
||||
get: () => {
|
||||
// Return null instead of rejecting to simulate cache miss
|
||||
return Promise.resolve(null);
|
||||
},
|
||||
put: () => Promise.resolve(),
|
||||
clear: () => Promise.resolve(),
|
||||
};
|
||||
|
||||
const indexer = new VaultIndexer(mockVault, faultyCache);
|
||||
const results = await indexer.searchVault('testing');
|
||||
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
// Should still return results even with cache errors
|
||||
});
|
||||
|
||||
it('should work without cache', async () => {
|
||||
const indexer = new VaultIndexer(mockVault);
|
||||
const results = await indexer.searchVault('testing');
|
||||
|
||||
expect(results.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should return empty array for empty query', async () => {
|
||||
const indexer = new VaultIndexer(mockVault);
|
||||
const results = await indexer.searchVault('');
|
||||
expect(results).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user