@dirwell/theme-ledger 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/client.js +25 -25
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +8 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{model-B0qQsjRT.d.mts → model-BgCmoksr.d.mts} +3 -1
- package/dist/model.d.mts +1 -1
- package/dist/source/Ledger.svelte +73 -6
- package/dist/source/shared/live-search.mjs +28 -0
- package/dist/source/shared/navigation.mjs +1 -0
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { onMount, tick, untrack } from "svelte";
|
|
3
|
+
import { queryLiveArchive } from "./shared/live-search.mjs";
|
|
3
4
|
import {
|
|
4
5
|
readView,
|
|
5
6
|
createViewHistory,
|
|
@@ -346,7 +347,7 @@
|
|
|
346
347
|
if (globalOpen) {
|
|
347
348
|
if (event.key === "Escape") {
|
|
348
349
|
event.preventDefault();
|
|
349
|
-
|
|
350
|
+
closeArchive();
|
|
350
351
|
}
|
|
351
352
|
return;
|
|
352
353
|
}
|
|
@@ -401,6 +402,44 @@
|
|
|
401
402
|
localStorage.setItem("dirwell-color-scheme", value);
|
|
402
403
|
} catch {}
|
|
403
404
|
}
|
|
405
|
+
let archiveDebounce,
|
|
406
|
+
archiveTrigger,
|
|
407
|
+
archivePending = false;
|
|
408
|
+
async function closeArchive() {
|
|
409
|
+
globalOpen = false;
|
|
410
|
+
await tick();
|
|
411
|
+
archiveTrigger?.focus();
|
|
412
|
+
}
|
|
413
|
+
function scheduleArchiveSearch() {
|
|
414
|
+
archiveAbort?.abort();
|
|
415
|
+
archiveRequest++;
|
|
416
|
+
archivePending = false;
|
|
417
|
+
clearTimeout(archiveDebounce);
|
|
418
|
+
archiveDebounce = setTimeout(() => {
|
|
419
|
+
archiveDebounce = undefined;
|
|
420
|
+
searchArchive();
|
|
421
|
+
}, 300);
|
|
422
|
+
}
|
|
423
|
+
$effect(() => {
|
|
424
|
+
if (!globalOpen || !model.searchQueryHref) return;
|
|
425
|
+
const timer = setInterval(() => {
|
|
426
|
+
if (
|
|
427
|
+
document.visibilityState === "visible" &&
|
|
428
|
+
globalQuery.trim() &&
|
|
429
|
+
!archivePending &&
|
|
430
|
+
archiveDebounce === undefined
|
|
431
|
+
)
|
|
432
|
+
searchArchive();
|
|
433
|
+
}, model.searchRefreshIntervalMs ?? 2000);
|
|
434
|
+
return () => {
|
|
435
|
+
clearInterval(timer);
|
|
436
|
+
clearTimeout(archiveDebounce);
|
|
437
|
+
archiveDebounce = undefined;
|
|
438
|
+
archivePending = false;
|
|
439
|
+
archiveAbort?.abort();
|
|
440
|
+
archiveRequest++;
|
|
441
|
+
};
|
|
442
|
+
});
|
|
404
443
|
async function searchArchive() {
|
|
405
444
|
const token = ++archiveRequest;
|
|
406
445
|
archiveAbort?.abort();
|
|
@@ -413,7 +452,24 @@
|
|
|
413
452
|
return;
|
|
414
453
|
}
|
|
415
454
|
globalStatus = ui.labels.searchingArchive;
|
|
455
|
+
archivePending = true;
|
|
416
456
|
try {
|
|
457
|
+
if (model.searchQueryHref) {
|
|
458
|
+
const result = await queryLiveArchive(
|
|
459
|
+
model.searchQueryHref,
|
|
460
|
+
query,
|
|
461
|
+
local.signal,
|
|
462
|
+
);
|
|
463
|
+
if (token !== archiveRequest || local.signal.aborted) return;
|
|
464
|
+
globalRows = result.records;
|
|
465
|
+
globalStatus = result.truncated
|
|
466
|
+
? label(ui, "truncatedResults", {
|
|
467
|
+
shown: result.records.length,
|
|
468
|
+
count: result.records.length + "+",
|
|
469
|
+
})
|
|
470
|
+
: label(ui, "archiveResults", { count: result.records.length });
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
417
473
|
const url = new URL(model.searchIndexHref, document.baseURI);
|
|
418
474
|
let all =
|
|
419
475
|
archiveCacheHref === url.href && Date.now() - archiveCacheAt < 60000
|
|
@@ -488,6 +544,8 @@
|
|
|
488
544
|
globalStatus = ui.labels.archiveError;
|
|
489
545
|
archiveFailed = true;
|
|
490
546
|
}
|
|
547
|
+
} finally {
|
|
548
|
+
if (token === archiveRequest) archivePending = false;
|
|
491
549
|
}
|
|
492
550
|
}
|
|
493
551
|
onMount(() => {
|
|
@@ -681,9 +739,10 @@
|
|
|
681
739
|
><option value="dark">{ui.labels.dark}</option></select
|
|
682
740
|
></label
|
|
683
741
|
>
|
|
684
|
-
{#if model.searchIndexHref}
|
|
742
|
+
{#if model.searchIndexHref || model.searchQueryHref}
|
|
685
743
|
<button
|
|
686
|
-
|
|
744
|
+
bind:this={archiveTrigger}
|
|
745
|
+
disabled={!ready}
|
|
687
746
|
onclick={() => (globalOpen = true)}>{ui.labels.searchArchive}</button
|
|
688
747
|
>
|
|
689
748
|
{/if}
|
|
@@ -882,7 +941,15 @@
|
|
|
882
941
|
</dialog>{/if}
|
|
883
942
|
{#if globalOpen}<dialog
|
|
884
943
|
bind:this={globalDialog}
|
|
885
|
-
|
|
944
|
+
aria-label={ui.labels.searchArchive}
|
|
945
|
+
onclose={closeArchive}
|
|
946
|
+
onkeydown={(event) => {
|
|
947
|
+
if (event.key === "Escape") {
|
|
948
|
+
event.preventDefault();
|
|
949
|
+
event.stopPropagation();
|
|
950
|
+
closeArchive();
|
|
951
|
+
}
|
|
952
|
+
}}
|
|
886
953
|
>
|
|
887
954
|
<h2>{ui.labels.searchArchive}</h2>
|
|
888
955
|
<input
|
|
@@ -890,7 +957,7 @@
|
|
|
890
957
|
bind:this={globalInput}
|
|
891
958
|
type="search"
|
|
892
959
|
bind:value={globalQuery}
|
|
893
|
-
oninput={
|
|
960
|
+
oninput={scheduleArchiveSearch}
|
|
894
961
|
/>
|
|
895
962
|
<p role="status">{globalStatus}</p>
|
|
896
963
|
{#if archiveFailed}<button onclick={searchArchive}>{ui.labels.retry}</button
|
|
@@ -905,5 +972,5 @@
|
|
|
905
972
|
>{:else}{record.path}{/if}
|
|
906
973
|
</li>{/each}
|
|
907
974
|
</ul>
|
|
908
|
-
<button onclick={
|
|
975
|
+
<button onclick={closeArchive}>{ui.labels.close}</button>
|
|
909
976
|
</dialog>{/if}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// ../shared-theme/src/live-search.ts
|
|
2
|
+
async function queryLiveArchive(href, query, signal) {
|
|
3
|
+
const url = new URL(href, document.baseURI);
|
|
4
|
+
if (url.origin !== location.origin) throw new Error("Unsafe search endpoint");
|
|
5
|
+
url.searchParams.set("q", query);
|
|
6
|
+
const response = await fetch(url, { signal, cache: "no-store" });
|
|
7
|
+
if (!response.ok) throw new Error("Archive search unavailable");
|
|
8
|
+
const data = await response.json();
|
|
9
|
+
if (typeof data !== "object" || data === null || !("version" in data) || data.version !== 1 || !("results" in data) || !Array.isArray(data.results) || data.results.length > 1e4 || !("truncated" in data) || typeof data.truncated !== "boolean")
|
|
10
|
+
throw new Error("Invalid archive results");
|
|
11
|
+
const records = data.results.map((entry) => {
|
|
12
|
+
if (typeof entry !== "object" || entry === null || !("name" in entry) || typeof entry.name !== "string" || !("path" in entry) || typeof entry.path !== "string" || !("kind" in entry) || !["file", "directory"].includes(String(entry.kind)) || !("href" in entry) || entry.href !== null && typeof entry.href !== "string")
|
|
13
|
+
throw new Error("Invalid archive record");
|
|
14
|
+
const target = entry.href === null ? null : new URL(entry.href, url);
|
|
15
|
+
if (target && !["http:", "https:"].includes(target.protocol))
|
|
16
|
+
throw new Error("Unsafe archive link");
|
|
17
|
+
return {
|
|
18
|
+
name: entry.name,
|
|
19
|
+
path: entry.path,
|
|
20
|
+
href: target?.href ?? null,
|
|
21
|
+
exitsExplorer: entry.kind !== "directory"
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
return { records, truncated: data.truncated };
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
queryLiveArchive
|
|
28
|
+
};
|
|
@@ -402,6 +402,7 @@ async function fetchThemePage(dataHref, pageHref, theme, signal, fresh = false,
|
|
|
402
402
|
resolveCustomization(data.ui);
|
|
403
403
|
const result = {
|
|
404
404
|
...data,
|
|
405
|
+
searchQueryHref: link(data.searchQueryHref ?? null),
|
|
405
406
|
updatesHref: link(data.updatesHref ?? null),
|
|
406
407
|
entries,
|
|
407
408
|
dataHref: source.href,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dirwell/theme-ledger",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Svelte-owned searchable directory explorer.",
|
|
5
5
|
"homepage": "https://vp-tw.github.io/dirwell/themes/",
|
|
6
6
|
"bugs": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"tag": "latest"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@dirwell/core": "0.0.
|
|
41
|
+
"@dirwell/core": "0.0.2",
|
|
42
42
|
"svelte": "5.57.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|