commit - 9f9520a342c61bdd9e1a1c83f2450df405a0c5dc
commit + 63ef4f6f40c424687fa97f144c97d2f16cb88177
blob - 42c8301937d044057bcbc6ecba8c3516b144b697
blob + cd34b0c1e426b5409f77e7157d277be655b93dfb
--- docs/architecture.dot
+++ docs/architecture.dot
digraph corpus {
- rankdir=LR
- compound=true
- splines=ortho
- concentrate=true
- nodesep=0.7
- ranksep=1.6
- bgcolor=transparent
+ graph [
+ rankdir=LR
+ bgcolor="transparent"
+ nodesep=0.7
+ ranksep=1.0
+ pad=0.2
+ fontname="Atkinson Hyperlegible Mono"
+ fontcolor="#e8edf5"
+ ]
- node [fontname="Atkinson Hyperlegible Mono", fontsize=11, shape=box, style="rounded,filled", fontcolor=white]
- edge [fontname="Atkinson Hyperlegible Mono", fontsize=9, color="#aaaaaa", fontcolor="#aaaaaa", arrowhead=vee, arrowsize=0.8, penwidth=1.4]
-
- subgraph cluster_frontend {
- label="Frontend"
+ node [
+ fontname="Atkinson Hyperlegible Mono"
+ fontsize=10
+ shape=box
style="rounded,filled"
- fillcolor="#1e1533"
- color="#9b7de8"
- fontcolor=white
+ color="#8b97a8"
+ fontcolor="#ffffff"
+ margin="0.18,0.12"
+ ]
+ edge [
fontname="Atkinson Hyperlegible Mono"
- UI [label="Elm SPA\n?user=slug", fillcolor="#2d2050"]
- Client [label="Scrobble Client\n(LB-compatible)", fillcolor="#2d2050"]
+ fontsize=8
+ color="#aeb8c7"
+ fontcolor="#d5dce7"
+ arrowhead=vee
+ arrowsize=0.7
+ penwidth=1.25
+ ]
+
+ subgraph cluster_clients {
+ label="People and clients"
+ style="rounded,filled"
+ fillcolor="#201a35"
+ color="#9879dc"
+ fontcolor="#ffffff"
+ Clients [
+ label="Browser\nElm SPA\n\nScrobbler\nListenBrainz-compatible\n\nAdministrator · Prometheus (optional)"
+ fillcolor="#302550"
+ ]
}
subgraph cluster_server {
- label="Corpus Server"
+ label="Corpus server · PureScript on Node.js"
style="rounded,filled"
- fillcolor="#112611"
- color="#5aaa5a"
- fontcolor=white
- fontname="Atkinson Hyperlegible Mono"
- API [label="Web API", fillcolor="#1c3e1c"]
- Proxy [label="Cover Proxy", fillcolor="#1c3e1c"]
- LBSync [label="ListenBrainz Sync", fillcolor="#1c3e1c"]
- LFSync [label="Last.fm Sync", fillcolor="#1c3e1c"]
- Enrich [label="Enrichment Task", fillcolor="#1c3e1c"]
+ fillcolor="#11291d"
+ color="#59aa76"
+ fontcolor="#ffffff"
+ Corpus [
+ label="HTTP server and API\nSPA · proxy · stats · cover · similar\n\nPer-user background work\nListenBrainz and Last.fm sync\nmetadata enrichment · cover cache · database backup\n\nRegistration/admin workflow · optional metrics"
+ fillcolor="#1b422d"
+ ]
}
subgraph cluster_storage {
- label="Storage"
+ label="Persistent storage"
style="rounded,filled"
- fillcolor="#272000"
- color="#d4a80c"
- fontcolor=white
- fontname="Atkinson Hyperlegible Mono"
- DB [label="DuckDB", shape=cylinder, fillcolor="#3d3100"]
- S3 [label="S3 Bucket", shape=box3d, fillcolor="#3d3100"]
+ fillcolor="#302a10"
+ color="#d2aa35"
+ fontcolor="#ffffff"
+ Storage [
+ label="DuckDB files — one per user\nscrobbles · release metadata · API tokens\n\nregistrations.db — shared registration state\n\nS3-compatible bucket\ncover cache · database backups"
+ shape=cylinder
+ fillcolor="#473d15"
+ ]
}
subgraph cluster_external {
- label="External APIs"
+ label="External services"
style="rounded,filled"
- fillcolor="#0e1e38"
- color="#5a8de0"
- fontcolor=white
- fontname="Atkinson Hyperlegible Mono"
- LB [label="ListenBrainz", fillcolor="#162d52"]
- LF [label="Last.fm", fillcolor="#162d52"]
- MB [label="MusicBrainz", fillcolor="#162d52"]
- DC [label="Discogs", fillcolor="#162d52"]
- CAA [label="Cover Art Archive", fillcolor="#162d52"]
+ fillcolor="#11243e"
+ color="#6396e7"
+ fontcolor="#ffffff"
+ External [
+ label="ListenBrainz · Last.fm\nMusicBrainz · Discogs\nCover Art Archive\ncosine.club\nSMTP server (optional)"
+ fillcolor="#19365d"
+ ]
}
- // Scrobble Sync
- LB -> LBSync
- LF -> LFSync
- LBSync -> DB
- LFSync -> DB
-
- // Enrichment
- DB -> Enrich
- Enrich -> MB
- Enrich -> LF
- Enrich -> DC
- Enrich -> DB [constraint=false]
-
- // Scrobble Submission
- Client -> API [label="POST /1/submit-listens\n(token auth)"]
- API -> DB [constraint=false]
-
- // Web UI
- UI -> API
- API -> DB
-
- // Cover Art
- UI -> Proxy
- Proxy -> S3
- Proxy -> CAA
- Proxy -> LF
- Proxy -> DC
- Proxy -> S3 [constraint=false]
+ Clients -> Corpus [label="SPA, listen submission, admin, /metrics"]
+ Corpus -> Storage [label="per-user data, registrations, cached covers, backups"]
+ Corpus -> External [
+ dir=both
+ label="sync · enrichment · cover lookup\nCAA → Discogs → Last.fm · similar tracks · email"
+ ]
}
blob - 7a953bae5094219599b8002fc264a8d3bbe282d8
blob + eed80c07978d2ebc4cd56334d474bf00b2025259
--- docs/architecture.svg
+++ docs/architecture.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 12.2.1 (0)
+<!-- Generated by graphviz version 15.1.0 (0)
-->
<!-- Title: corpus Pages: 1 -->
-<svg width="784pt" height="615pt"
- viewBox="0.00 0.00 783.75 615.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 611)">
+<svg width="1571pt" height="342pt"
+ viewBox="0.00 0.00 1571.00 342.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(14.4 327.4)">
<title>corpus</title>
<g id="clust1" class="cluster">
-<title>cluster_frontend</title>
-<path fill="#1e1533" stroke="#9b7de8" d="M20,-395C20,-395 129.25,-395 129.25,-395 135.25,-395 141.25,-401 141.25,-407 141.25,-407 141.25,-544 141.25,-544 141.25,-550 135.25,-556 129.25,-556 129.25,-556 20,-556 20,-556 14,-556 8,-550 8,-544 8,-544 8,-407 8,-407 8,-401 14,-395 20,-395"/>
-<text text-anchor="middle" x="74.62" y="-538.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="white">Frontend</text>
+<title>cluster_clients</title>
+<path fill="#201a35" stroke="#9879dc" d="M20,-37C20,-37 259.92,-37 259.92,-37 265.92,-37 271.92,-43 271.92,-49 271.92,-49 271.92,-162 271.92,-162 271.92,-168 265.92,-174 259.92,-174 259.92,-174 20,-174 20,-174 14,-174 8,-168 8,-162 8,-162 8,-49 8,-49 8,-43 14,-37 20,-37"/>
+<text xml:space="preserve" text-anchor="middle" x="139.96" y="-156.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="#ffffff">People and clients</text>
</g>
<g id="clust2" class="cluster">
<title>cluster_server</title>
-<path fill="#112611" stroke="#5aaa5a" d="M385.25,-180C385.25,-180 508,-180 508,-180 514,-180 520,-186 520,-192 520,-192 520,-587 520,-587 520,-593 514,-599 508,-599 508,-599 385.25,-599 385.25,-599 379.25,-599 373.25,-593 373.25,-587 373.25,-587 373.25,-192 373.25,-192 373.25,-186 379.25,-180 385.25,-180"/>
-<text text-anchor="middle" x="446.62" y="-581.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="white">Corpus Server</text>
+<path fill="#11291d" stroke="#59aa76" d="M544.67,-32C544.67,-32 887.67,-32 887.67,-32 893.67,-32 899.67,-38 899.67,-44 899.67,-44 899.67,-167 899.67,-167 899.67,-173 893.67,-179 887.67,-179 887.67,-179 544.67,-179 544.67,-179 538.67,-179 532.67,-173 532.67,-167 532.67,-167 532.67,-44 532.67,-44 532.67,-38 538.67,-32 544.67,-32"/>
+<text xml:space="preserve" text-anchor="middle" x="716.17" y="-161.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="#ffffff">Corpus server  ·  PureScript on Node.js</text>
</g>
<g id="clust3" class="cluster">
<title>cluster_storage</title>
-<path fill="#272000" stroke="#d4a80c" d="M660,-438C660,-438 728.75,-438 728.75,-438 734.75,-438 740.75,-444 740.75,-450 740.75,-450 740.75,-587 740.75,-587 740.75,-593 734.75,-599 728.75,-599 728.75,-599 660,-599 660,-599 654,-599 648,-593 648,-587 648,-587 648,-450 648,-450 648,-444 654,-438 660,-438"/>
-<text text-anchor="middle" x="694.38" y="-581.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="white">Storage</text>
+<path fill="#302a10" stroke="#d2aa35" d="M1240.67,-132C1240.67,-132 1522.59,-132 1522.59,-132 1528.59,-132 1534.59,-138 1534.59,-144 1534.59,-144 1534.59,-293 1534.59,-293 1534.59,-299 1528.59,-305 1522.59,-305 1522.59,-305 1240.67,-305 1240.67,-305 1234.67,-305 1228.67,-299 1228.67,-293 1228.67,-293 1228.67,-144 1228.67,-144 1228.67,-138 1234.67,-132 1240.67,-132"/>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-287.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="#ffffff">Persistent storage</text>
</g>
<g id="clust4" class="cluster">
<title>cluster_external</title>
-<path fill="#0e1e38" stroke="#5a8de0" d="M633,-8C633,-8 755.75,-8 755.75,-8 761.75,-8 767.75,-14 767.75,-20 767.75,-20 767.75,-415 767.75,-415 767.75,-421 761.75,-427 755.75,-427 755.75,-427 633,-427 633,-427 627,-427 621,-421 621,-415 621,-415 621,-20 621,-20 621,-14 627,-8 633,-8"/>
-<text text-anchor="middle" x="694.38" y="-409.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="white">External APIs</text>
+<path fill="#11243e" stroke="#6396e7" d="M1306.67,-8C1306.67,-8 1456.59,-8 1456.59,-8 1462.59,-8 1468.59,-14 1468.59,-20 1468.59,-20 1468.59,-109 1468.59,-109 1468.59,-115 1462.59,-121 1456.59,-121 1456.59,-121 1306.67,-121 1306.67,-121 1300.67,-121 1294.67,-115 1294.67,-109 1294.67,-109 1294.67,-20 1294.67,-20 1294.67,-14 1300.67,-8 1306.67,-8"/>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-103.7" font-family="Atkinson Hyperlegible Mono" font-size="14.00" fill="#ffffff">External services</text>
</g>
-<!-- UI -->
+<!-- Clients -->
<g id="node1" class="node">
-<title>UI</title>
-<path fill="#2d2050" stroke="black" d="M104.38,-439C104.38,-439 44.88,-439 44.88,-439 38.88,-439 32.88,-433 32.88,-427 32.88,-427 32.88,-415 32.88,-415 32.88,-409 38.88,-403 44.88,-403 44.88,-403 104.38,-403 104.38,-403 110.38,-403 116.38,-409 116.38,-415 116.38,-415 116.38,-427 116.38,-427 116.38,-433 110.38,-439 104.38,-439"/>
-<text text-anchor="middle" x="74.62" y="-422.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Elm SPA</text>
-<text text-anchor="middle" x="74.62" y="-410.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">?user=slug</text>
+<title>Clients</title>
+<path fill="#302550" stroke="#8b97a8" d="M251.92,-142.76C251.92,-142.76 28,-142.76 28,-142.76 22,-142.76 16,-136.76 16,-130.76 16,-130.76 16,-57.23 16,-57.23 16,-51.23 22,-45.23 28,-45.23 28,-45.23 251.92,-45.23 251.92,-45.23 257.92,-45.23 263.92,-51.23 263.92,-57.23 263.92,-57.23 263.92,-130.76 263.92,-130.76 263.92,-136.76 257.92,-142.76 251.92,-142.76"/>
+<text xml:space="preserve" text-anchor="middle" x="139.96" y="-124.62" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Browser</text>
+<text xml:space="preserve" text-anchor="middle" x="139.96" y="-113.38" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Elm SPA</text>
+<text xml:space="preserve" text-anchor="middle" x="139.96" y="-90.12" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Scrobbler</text>
+<text xml:space="preserve" text-anchor="middle" x="139.96" y="-78.88" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">ListenBrainz-compatible</text>
+<text xml:space="preserve" text-anchor="middle" x="139.96" y="-55.62" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Administrator · Prometheus (optional)</text>
</g>
-<!-- API -->
-<g id="node3" class="node">
-<title>API</title>
-<path fill="#1c3e1c" stroke="black" d="M466.25,-482C466.25,-482 427,-482 427,-482 421,-482 415,-476 415,-470 415,-470 415,-458 415,-458 415,-452 421,-446 427,-446 427,-446 466.25,-446 466.25,-446 472.25,-446 478.25,-452 478.25,-458 478.25,-458 478.25,-470 478.25,-470 478.25,-476 472.25,-482 466.25,-482"/>
-<text text-anchor="middle" x="446.62" y="-459.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Web API</text>
-</g>
-<!-- UI->API -->
-<g id="edge12" class="edge">
-<title>UI->API</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M116.59,-421C213.91,-421 446.75,-421 446.75,-421 446.75,-421 446.75,-435.81 446.75,-435.81"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="446.75,-443.81 443.15,-435.81 446.55,-441.51 446.55,-435.81 446.75,-435.81 446.95,-435.81 446.95,-441.51 450.35,-435.81 446.75,-443.81"/>
-</g>
-<!-- Proxy -->
-<g id="node4" class="node">
-<title>Proxy</title>
-<path fill="#1c3e1c" stroke="black" d="M479.75,-310C479.75,-310 413.5,-310 413.5,-310 407.5,-310 401.5,-304 401.5,-298 401.5,-298 401.5,-286 401.5,-286 401.5,-280 407.5,-274 413.5,-274 413.5,-274 479.75,-274 479.75,-274 485.75,-274 491.75,-280 491.75,-286 491.75,-286 491.75,-298 491.75,-298 491.75,-304 485.75,-310 479.75,-310"/>
-<text text-anchor="middle" x="446.62" y="-287.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Cover Proxy</text>
-</g>
-<!-- UI->Proxy -->
-<g id="edge14" class="edge">
-<title>UI->Proxy</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M74.75,-402.52C74.75,-366.85 74.75,-292 74.75,-292 74.75,-292 391.32,-292 391.32,-292"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="399.32,-292 391.32,-295.6 397.03,-292.2 391.32,-292.2 391.32,-292 391.32,-291.8 397.03,-291.8 391.32,-288.4 399.32,-292"/>
-</g>
-<!-- Client -->
+<!-- Corpus -->
<g id="node2" class="node">
-<title>Client</title>
-<path fill="#2d2050" stroke="black" d="M121.25,-525C121.25,-525 28,-525 28,-525 22,-525 16,-519 16,-513 16,-513 16,-501 16,-501 16,-495 22,-489 28,-489 28,-489 121.25,-489 121.25,-489 127.25,-489 133.25,-495 133.25,-501 133.25,-501 133.25,-513 133.25,-513 133.25,-519 127.25,-525 121.25,-525"/>
-<text text-anchor="middle" x="74.62" y="-508.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Scrobble Client</text>
-<text text-anchor="middle" x="74.62" y="-496.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">(LB-compatible)</text>
+<title>Corpus</title>
+<path fill="#1b422d" stroke="#8b97a8" d="M869.63,-148.39C869.63,-148.39 561.71,-148.39 561.71,-148.39 555.71,-148.39 549.71,-142.39 549.71,-136.39 549.71,-136.39 549.71,-51.61 549.71,-51.61 549.71,-45.61 555.71,-39.61 561.71,-39.61 561.71,-39.61 869.63,-39.61 869.63,-39.61 875.63,-39.61 881.63,-45.61 881.63,-51.61 881.63,-51.61 881.63,-136.39 881.63,-136.39 881.63,-142.39 875.63,-148.39 869.63,-148.39"/>
+<text xml:space="preserve" text-anchor="middle" x="715.67" y="-130.25" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">HTTP server and API</text>
+<text xml:space="preserve" text-anchor="middle" x="715.67" y="-119" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">SPA · proxy · stats · cover · similar</text>
+<text xml:space="preserve" text-anchor="middle" x="715.67" y="-95.75" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Per-user background work</text>
+<text xml:space="preserve" text-anchor="middle" x="715.67" y="-84.5" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">ListenBrainz and Last.fm sync</text>
+<text xml:space="preserve" text-anchor="middle" x="715.67" y="-73.25" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">metadata enrichment · cover cache · database backup</text>
+<text xml:space="preserve" text-anchor="middle" x="715.67" y="-50" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Registration/admin workflow · optional metrics</text>
</g>
-<!-- Client->API -->
-<g id="edge10" class="edge">
-<title>Client->API</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M124.75,-488.51C124.75,-476.86 124.75,-464 124.75,-464 124.75,-464 404.88,-464 404.88,-464"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="412.88,-464 404.88,-467.6 410.59,-464.2 404.88,-464.2 404.88,-464 404.88,-463.8 410.59,-463.8 404.88,-460.4 412.88,-464"/>
-<text text-anchor="middle" x="257.25" y="-517.45" font-family="Atkinson Hyperlegible Mono" font-size="9.00" fill="#aaaaaa">POST /1/submit-listens</text>
-<text text-anchor="middle" x="257.25" y="-506.95" font-family="Atkinson Hyperlegible Mono" font-size="9.00" fill="#aaaaaa">(token auth)</text>
-</g>
-<!-- DB -->
-<g id="node8" class="node">
-<title>DB</title>
-<path fill="#3d3100" stroke="black" d="M722.62,-564.73C722.62,-566.53 709.96,-568 694.38,-568 678.79,-568 666.12,-566.53 666.12,-564.73 666.12,-564.73 666.12,-535.27 666.12,-535.27 666.12,-533.47 678.79,-532 694.38,-532 709.96,-532 722.62,-533.47 722.62,-535.27 722.62,-535.27 722.62,-564.73 722.62,-564.73"/>
-<path fill="none" stroke="black" d="M722.62,-564.73C722.62,-562.92 709.96,-561.45 694.38,-561.45 678.79,-561.45 666.12,-562.92 666.12,-564.73"/>
-<text text-anchor="middle" x="694.38" y="-545.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">DuckDB</text>
-</g>
-<!-- API->DB -->
-<g id="edge11" class="edge">
-<title>API->DB</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M478.75,-470C520.94,-470 589.75,-470 589.75,-470 589.75,-470 589.75,-550 589.75,-550 589.75,-550 656.08,-550 656.08,-550"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="664.08,-550 656.08,-553.6 661.79,-550.2 656.08,-550.2 656.08,-550 656.08,-549.8 661.79,-549.8 656.08,-546.4 664.08,-550"/>
-</g>
-<!-- S3 -->
-<g id="node9" class="node">
-<title>S3</title>
-<polygon fill="#3d3100" stroke="black" points="732.75,-482 660,-482 656,-478 656,-446 728.75,-446 732.75,-450 732.75,-482"/>
-<polyline fill="none" stroke="black" points="728.75,-478 656,-478"/>
-<polyline fill="none" stroke="black" points="728.75,-478 728.75,-446"/>
-<polyline fill="none" stroke="black" points="728.75,-478 732.75,-482"/>
-<text text-anchor="middle" x="694.38" y="-459.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">S3 Bucket</text>
-</g>
-<!-- Proxy->S3 -->
-<g id="edge15" class="edge">
-<title>Proxy->S3</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M492.06,-302.8C540.33,-302.8 609.75,-302.8 609.75,-302.8 609.75,-302.8 609.75,-458 609.75,-458 609.75,-458 645.82,-458 645.82,-458"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="653.82,-458 645.82,-461.6 651.53,-458.2 645.82,-458.2 645.82,-458 645.82,-457.8 651.53,-457.8 645.82,-454.4 653.82,-458"/>
-</g>
-<!-- LF -->
-<g id="node11" class="node">
-<title>LF</title>
-<path fill="#162d52" stroke="black" d="M714,-224C714,-224 674.75,-224 674.75,-224 668.75,-224 662.75,-218 662.75,-212 662.75,-212 662.75,-200 662.75,-200 662.75,-194 668.75,-188 674.75,-188 674.75,-188 714,-188 714,-188 720,-188 726,-194 726,-200 726,-200 726,-212 726,-212 726,-218 720,-224 714,-224"/>
-<text text-anchor="middle" x="694.38" y="-201.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Last.fm</text>
-</g>
-<!-- Proxy->LF -->
-<g id="edge17" class="edge">
-<title>Proxy->LF</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M491.99,-288.4C520.05,-288.4 550.75,-288.4 550.75,-288.4 550.75,-288.4 550.75,-209.6 550.75,-209.6 550.75,-209.6 652.79,-209.6 652.79,-209.6"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="660.79,-209.6 652.79,-213.2 658.5,-209.8 652.79,-209.8 652.79,-209.6 652.79,-209.4 658.5,-209.4 652.79,-206 660.79,-209.6"/>
-</g>
-<!-- DC -->
-<g id="node13" class="node">
-<title>DC</title>
-<path fill="#162d52" stroke="black" d="M714,-138C714,-138 674.75,-138 674.75,-138 668.75,-138 662.75,-132 662.75,-126 662.75,-126 662.75,-114 662.75,-114 662.75,-108 668.75,-102 674.75,-102 674.75,-102 714,-102 714,-102 720,-102 726,-108 726,-114 726,-114 726,-126 726,-126 726,-132 720,-138 714,-138"/>
-<text text-anchor="middle" x="694.38" y="-115.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Discogs</text>
-</g>
-<!-- Proxy->DC -->
-<g id="edge18" class="edge">
-<title>Proxy->DC</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M492.18,-281.2C512.42,-281.2 531.75,-281.2 531.75,-281.2 531.75,-281.2 531.75,-126 531.75,-126 531.75,-126 652.93,-126 652.93,-126"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="660.93,-126 652.93,-129.6 658.63,-126.2 652.93,-126.2 652.93,-126 652.93,-125.8 658.63,-125.8 652.93,-122.4 660.93,-126"/>
-</g>
-<!-- CAA -->
-<g id="node14" class="node">
-<title>CAA</title>
-<path fill="#162d52" stroke="black" d="M747.75,-310C747.75,-310 641,-310 641,-310 635,-310 629,-304 629,-298 629,-298 629,-286 629,-286 629,-280 635,-274 641,-274 641,-274 747.75,-274 747.75,-274 753.75,-274 759.75,-280 759.75,-286 759.75,-286 759.75,-298 759.75,-298 759.75,-304 753.75,-310 747.75,-310"/>
-<text text-anchor="middle" x="694.38" y="-287.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Cover Art Archive</text>
-</g>
-<!-- Proxy->CAA -->
-<g id="edge16" class="edge">
-<title>Proxy->CAA</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M492.07,-295.6C492.07,-295.6 618.98,-295.6 618.98,-295.6"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="626.98,-295.6 618.98,-299.2 624.68,-295.8 618.98,-295.8 618.98,-295.6 618.98,-295.4 624.68,-295.4 618.98,-292 626.98,-295.6"/>
-</g>
-<!-- LBSync -->
-<g id="node5" class="node">
-<title>LBSync</title>
-<path fill="#1c3e1c" stroke="black" d="M500,-568C500,-568 393.25,-568 393.25,-568 387.25,-568 381.25,-562 381.25,-556 381.25,-556 381.25,-544 381.25,-544 381.25,-538 387.25,-532 393.25,-532 393.25,-532 500,-532 500,-532 506,-532 512,-538 512,-544 512,-544 512,-556 512,-556 512,-562 506,-568 500,-568"/>
-<text text-anchor="middle" x="446.62" y="-545.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">ListenBrainz Sync</text>
-</g>
-<!-- LBSync->DB -->
-<g id="edge3" class="edge">
-<title>LBSync->DB</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M512.37,-559C512.37,-559 655.97,-559 655.97,-559"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="663.97,-559 655.97,-562.6 661.67,-559.2 655.97,-559.2 655.97,-559 655.97,-558.8 661.67,-558.8 655.97,-555.4 663.97,-559"/>
-</g>
-<!-- LFSync -->
-<g id="node6" class="node">
-<title>LFSync</title>
-<path fill="#1c3e1c" stroke="black" d="M483.12,-396C483.12,-396 410.12,-396 410.12,-396 404.12,-396 398.12,-390 398.12,-384 398.12,-384 398.12,-372 398.12,-372 398.12,-366 404.12,-360 410.12,-360 410.12,-360 483.12,-360 483.12,-360 489.12,-360 495.12,-366 495.12,-372 495.12,-372 495.12,-384 495.12,-384 495.12,-390 489.12,-396 483.12,-396"/>
-<text text-anchor="middle" x="446.62" y="-373.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Last.fm Sync</text>
-</g>
-<!-- LFSync->DB -->
-<g id="edge4" class="edge">
-<title>LFSync->DB</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M486.75,-396.43C486.75,-427.44 486.75,-486.67 486.75,-486.67 486.75,-486.67 684.75,-486.67 684.75,-486.67 684.75,-486.67 684.75,-521.98 684.75,-521.98"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="684.75,-529.98 681.15,-521.98 684.55,-527.68 684.55,-521.98 684.75,-521.98 684.95,-521.98 684.95,-527.68 688.35,-521.98 684.75,-529.98"/>
-</g>
-<!-- Enrich -->
-<g id="node7" class="node">
-<title>Enrich</title>
-<path fill="#1c3e1c" stroke="black" d="M493.25,-224C493.25,-224 400,-224 400,-224 394,-224 388,-218 388,-212 388,-212 388,-200 388,-200 388,-194 394,-188 400,-188 400,-188 493.25,-188 493.25,-188 499.25,-188 505.25,-194 505.25,-200 505.25,-200 505.25,-212 505.25,-212 505.25,-218 499.25,-224 493.25,-224"/>
-<text text-anchor="middle" x="446.62" y="-201.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">Enrichment Task</text>
-</g>
-<!-- Enrich->DB -->
-<g id="edge9" class="edge">
-<title>Enrich->DB</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M499.75,-224.26C499.75,-286.18 499.75,-484.33 499.75,-484.33 499.75,-484.33 703.75,-484.33 703.75,-484.33 703.75,-484.33 703.75,-522 703.75,-522"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="703.75,-530 700.15,-522 703.55,-527.71 703.55,-522 703.75,-522 703.95,-522 703.95,-527.71 707.35,-522 703.75,-530"/>
-</g>
-<!-- Enrich->LF -->
-<g id="edge7" class="edge">
-<title>Enrich->LF</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M505.65,-202.4C505.65,-202.4 652.6,-202.4 652.6,-202.4"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="660.6,-202.4 652.6,-206 658.31,-202.6 652.6,-202.6 652.6,-202.4 652.6,-202.2 658.31,-202.2 652.6,-198.8 660.6,-202.4"/>
-</g>
-<!-- MB -->
-<g id="node12" class="node">
-<title>MB</title>
-<path fill="#162d52" stroke="black" d="M727.5,-52C727.5,-52 661.25,-52 661.25,-52 655.25,-52 649.25,-46 649.25,-40 649.25,-40 649.25,-28 649.25,-28 649.25,-22 655.25,-16 661.25,-16 661.25,-16 727.5,-16 727.5,-16 733.5,-16 739.5,-22 739.5,-28 739.5,-28 739.5,-40 739.5,-40 739.5,-46 733.5,-52 727.5,-52"/>
-<text text-anchor="middle" x="694.38" y="-29.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">MusicBrainz</text>
-</g>
-<!-- Enrich->MB -->
-<g id="edge6" class="edge">
-<title>Enrich->MB</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M505.71,-195.2C567.55,-195.2 655.75,-195.2 655.75,-195.2 655.75,-195.2 655.75,-62.2 655.75,-62.2"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="655.75,-54.2 659.35,-62.2 655.95,-56.49 655.95,-62.2 655.75,-62.2 655.55,-62.2 655.55,-56.49 652.15,-62.2 655.75,-54.2"/>
-</g>
-<!-- Enrich->DC -->
-<g id="edge8" class="edge">
-<title>Enrich->DC</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M446.75,-187.82C446.75,-161.01 446.75,-114 446.75,-114 446.75,-114 652.55,-114 652.55,-114"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="660.55,-114 652.55,-117.6 658.26,-114.2 652.55,-114.2 652.55,-114 652.55,-113.8 658.26,-113.8 652.55,-110.4 660.55,-114"/>
-</g>
-<!-- LB -->
-<g id="node10" class="node">
-<title>LB</title>
-<path fill="#162d52" stroke="black" d="M730.88,-396C730.88,-396 657.88,-396 657.88,-396 651.88,-396 645.88,-390 645.88,-384 645.88,-384 645.88,-372 645.88,-372 645.88,-366 651.88,-360 657.88,-360 657.88,-360 730.88,-360 730.88,-360 736.88,-360 742.88,-366 742.88,-372 742.88,-372 742.88,-384 742.88,-384 742.88,-390 736.88,-396 730.88,-396"/>
-<text text-anchor="middle" x="694.38" y="-373.55" font-family="Atkinson Hyperlegible Mono" font-size="11.00" fill="white">ListenBrainz</text>
-</g>
-<!-- LB->LBSync -->
+<!-- Clients->Corpus -->
<g id="edge1" class="edge">
-<title>LB->LBSync</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M650.75,-396.38C650.75,-439.01 650.75,-541 650.75,-541 650.75,-541 522.04,-541 522.04,-541"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="514.04,-541 522.04,-537.4 516.34,-540.8 522.04,-540.8 522.04,-541 522.04,-541.2 516.34,-541.2 522.04,-544.6 514.04,-541"/>
+<title>Clients->Corpus</title>
+<path fill="none" stroke="#aeb8c7" stroke-width="1.25" d="M264.39,-94C345.1,-94 451.73,-94 540.96,-94"/>
+<polygon fill="#aeb8c7" stroke="#aeb8c7" stroke-width="1.25" points="547.74,-94 540.74,-97.15 545.76,-94.13 540.74,-94.13 540.74,-94 540.74,-93.88 545.76,-93.88 540.74,-90.85 547.74,-94"/>
+<text xml:space="preserve" text-anchor="middle" x="402.3" y="-95.4" font-family="Atkinson Hyperlegible Mono" font-size="8.00" fill="#d5dce7">SPA, listen submission, admin, /metrics</text>
</g>
-<!-- LF->LFSync -->
+<!-- Storage -->
+<g id="node3" class="node">
+<title>Storage</title>
+<path fill="#473d15" stroke="#8b97a8" d="M1526.59,-261.86C1526.59,-268.59 1461.62,-274.05 1381.63,-274.05 1301.64,-274.05 1236.67,-268.59 1236.67,-261.86 1236.67,-261.86 1236.67,-152.14 1236.67,-152.14 1236.67,-145.41 1301.64,-139.95 1381.63,-139.95 1461.62,-139.95 1526.59,-145.41 1526.59,-152.14 1526.59,-152.14 1526.59,-261.86 1526.59,-261.86"/>
+<path fill="none" stroke="#8b97a8" d="M1526.59,-261.86C1526.59,-255.13 1461.62,-249.67 1381.63,-249.67 1301.64,-249.67 1236.67,-255.13 1236.67,-261.86"/>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-237.62" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">DuckDB files — one per user</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-226.38" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">scrobbles · release metadata · API tokens</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-203.12" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">registrations.db — shared registration state</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-179.88" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">S3-compatible bucket</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-168.62" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">cover cache · database backups</text>
+</g>
+<!-- Corpus->Storage -->
<g id="edge2" class="edge">
-<title>LF->LFSync</title>
-<path fill="none" stroke="#aaaaaa" stroke-width="1.4" d="M662.54,-216.8C625.91,-216.8 570.75,-216.8 570.75,-216.8 570.75,-216.8 570.75,-378 570.75,-378 570.75,-378 505.03,-378 505.03,-378"/>
-<polygon fill="#aaaaaa" stroke="#aaaaaa" stroke-width="1.4" points="497.03,-378 505.03,-374.4 499.33,-377.8 505.03,-377.8 505.03,-378 505.03,-378.2 499.33,-378.2 505.03,-381.6 497.03,-378"/>
+<title>Corpus->Storage</title>
+<path fill="none" stroke="#aeb8c7" stroke-width="1.25" d="M882.08,-122.15C988.09,-140.19 1124.7,-163.44 1228.1,-181.04"/>
+<polygon fill="#aeb8c7" stroke="#aeb8c7" stroke-width="1.25" points="1234.93,-182.2 1227.5,-184.13 1232.96,-181.99 1228,-181.15 1228.03,-181.03 1228.05,-180.9 1233,-181.75 1228.55,-177.92 1234.93,-182.2"/>
+<text xml:space="preserve" text-anchor="middle" x="1064.17" y="-175.01" font-family="Atkinson Hyperlegible Mono" font-size="8.00" fill="#d5dce7">per-user data, registrations, cached covers, backups</text>
</g>
+<!-- External -->
+<g id="node4" class="node">
+<title>External</title>
+<path fill="#19365d" stroke="#8b97a8" d="M1448.59,-89.77C1448.59,-89.77 1314.67,-89.77 1314.67,-89.77 1308.67,-89.77 1302.67,-83.77 1302.67,-77.77 1302.67,-77.77 1302.67,-28.23 1302.67,-28.23 1302.67,-22.23 1308.67,-16.23 1314.67,-16.23 1314.67,-16.23 1448.59,-16.23 1448.59,-16.23 1454.59,-16.23 1460.59,-22.23 1460.59,-28.23 1460.59,-28.23 1460.59,-77.77 1460.59,-77.77 1460.59,-83.77 1454.59,-89.77 1448.59,-89.77"/>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-71.62" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">ListenBrainz · Last.fm</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-60.38" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">MusicBrainz · Discogs</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-49.12" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">Cover Art Archive</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-37.88" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">cosine.club</text>
+<text xml:space="preserve" text-anchor="middle" x="1381.63" y="-26.62" font-family="Atkinson Hyperlegible Mono" font-size="10.00" fill="#ffffff">SMTP server (optional)</text>
</g>
+<!-- Corpus->External -->
+<g id="edge3" class="edge">
+<title>Corpus->External</title>
+<path fill="none" stroke="#aeb8c7" stroke-width="1.25" d="M890.79,-83.25C1020.5,-75.24 1192.12,-64.64 1293.99,-58.35"/>
+<polygon fill="#aeb8c7" stroke="#aeb8c7" stroke-width="1.25" points="890.8,-80.79 883.96,-83.67 891.1,-85.68 890.8,-80.79"/>
+<polygon fill="#aeb8c7" stroke="#aeb8c7" stroke-width="1.25" points="1300.89,-57.92 1294.1,-61.5 1298.93,-58.17 1293.91,-58.48 1293.91,-58.36 1293.9,-58.23 1298.91,-57.92 1293.71,-55.21 1300.89,-57.92"/>
+<text xml:space="preserve" text-anchor="middle" x="1064.17" y="-91.89" font-family="Atkinson Hyperlegible Mono" font-size="8.00" fill="#d5dce7">sync · enrichment · cover lookup</text>
+<text xml:space="preserve" text-anchor="middle" x="1064.17" y="-82.89" font-family="Atkinson Hyperlegible Mono" font-size="8.00" fill="#d5dce7">CAA → Discogs → Last.fm · similar tracks · email</text>
+</g>
+</g>
</svg>
blob - 39f7a209508cf1f2778b455e20a58f5f9df7c526
blob + 5a395853ad588c850fe0ace5d4c2fcab69c48eeb
--- flake.nix
+++ flake.nix
elm2nix.packages.${system}.default
pkgs.nodejs
pkgs.elmPackages.elm
+ pkgs.elmPackages.elm-analyse
pkgs.elmPackages.elm-format
pkgs.elmPackages.elm-json
pkgs.pnpm
+ pkgs.statix
];
};
blob - 012ac271c858af922419583eecd1d0d509aef22a
blob + 35c7ed96ba1b802f5f33d8556a38708d92c0479a
--- package.json
+++ package.json
{
- "name": "corpus",
- "version": "3.1.0",
- "description": "ListenBrainz and Last.fm frontend",
- "main": "index.js",
- "type": "module",
- "scripts": {
- "build": "spago build && esbuild output/Main/index.js --bundle --platform=node --format=esm --footer:js='main();' --outfile=server.js --external:http --external:https --external:dotenv --external:url --external:@duckdb/node-api --external:@aws-sdk/client-s3 --external:@aws-sdk/s3-request-presigner --external:prom-client --external:sharp --external:uuid --external:nodemailer && elm make src/Client.elm --output=client.js",
- "release": "spago build && purs-backend-es build && esbuild output-es/Main/index.js --bundle --platform=node --format=esm --footer:js='main();' --outfile=server.js --external:http --external:https --external:dotenv --external:url --external:@duckdb/node-api --external:@aws-sdk/client-s3 --external:@aws-sdk/s3-request-presigner --external:prom-client --external:sharp --external:uuid --external:nodemailer && elm make src/Client.elm --optimize --output=client.js && uglifyjs client.js --compress \"pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe\" | uglifyjs --mangle --output client.js",
- "test": "spago test",
- "tidy": "purs-tidy format-in-place src/**/*.purs"
- },
- "devDependencies": {
- "esbuild": "^0.28.1",
- "purescript-language-server": "^0.18.5",
- "purescript-psa": "^0.9.0",
- "purs-backend-es": "^1.4.3",
- "purs-tidy": "^0.11.1",
- "spago": "^1.0.4",
- "uglify-js": "^3.19.3",
- "whine": "^0.0.34"
- },
- "dependencies": {
- "@aws-sdk/client-s3": "^3.1085.0",
- "@aws-sdk/s3-request-presigner": "^3.1085.0",
- "@duckdb/node-api": "1.5.4-r.1",
- "dotenv": "^17.4.2",
- "nodemailer": "^6.10.1",
- "prom-client": "^15.1.3",
- "purescript": "^0.15.16",
- "sharp": "^0.35.3",
- "uuid": "^14.0.1"
- }
+ "name": "corpus",
+ "version": "3.1.0",
+ "description": "ListenBrainz and Last.fm frontend",
+ "main": "index.js",
+ "type": "module",
+ "scripts": {
+ "build": "spago build && esbuild output/Main/index.js --bundle --platform=node --format=esm --footer:js='main();' --outfile=server.js --external:http --external:https --external:dotenv --external:url --external:@duckdb/node-api --external:@aws-sdk/client-s3 --external:@aws-sdk/s3-request-presigner --external:prom-client --external:sharp --external:uuid --external:nodemailer && elm make src/Client.elm --output=client.js",
+ "release": "spago build && purs-backend-es build && esbuild output-es/Main/index.js --bundle --platform=node --format=esm --footer:js='main();' --outfile=server.js --external:http --external:https --external:dotenv --external:url --external:@duckdb/node-api --external:@aws-sdk/client-s3 --external:@aws-sdk/s3-request-presigner --external:prom-client --external:sharp --external:uuid --external:nodemailer && elm make src/Client.elm --optimize --output=client.js && uglifyjs client.js --compress \"pure_funcs=[F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9],pure_getters,keep_fargs=false,unsafe_comps,unsafe\" | uglifyjs --mangle --output client.js",
+ "test": "spago test",
+ "tidy": "purs-tidy format-in-place src/**/*.purs"
+ },
+ "devDependencies": {
+ "esbuild": "^0.28.1",
+ "purescript-language-server": "^0.18.5",
+ "purescript-psa": "^0.9.0",
+ "purs-backend-es": "^1.4.3",
+ "purs-tidy": "^0.11.1",
+ "spago": "^1.0.4",
+ "uglify-js": "^3.19.3",
+ "whine": "^0.0.34"
+ },
+ "dependencies": {
+ "@aws-sdk/client-s3": "^3.1101.0",
+ "@aws-sdk/s3-request-presigner": "^3.1101.0",
+ "@duckdb/node-api": "1.5.4-r.1",
+ "dotenv": "^17.4.2",
+ "nodemailer": "^6.10.1",
+ "prom-client": "^15.1.3",
+ "purescript": "^0.15.16",
+ "sharp": "^0.35.3",
+ "uuid": "^14.0.1"
+ }
}
blob - 45c95ca5466bef353104ecd6543bfc8014fdf3ef
blob + 5c496a980ab40b83d06bf1c2e451a26e98912ac6
--- pnpm-lock.yaml
+++ pnpm-lock.yaml
.:
dependencies:
'@aws-sdk/client-s3':
- specifier: ^3.1085.0
- version: 3.1085.0
+ specifier: ^3.1101.0
+ version: 3.1101.0
'@aws-sdk/s3-request-presigner':
- specifier: ^3.1085.0
- version: 3.1085.0
+ specifier: ^3.1101.0
+ version: 3.1101.0
'@duckdb/node-api':
specifier: 1.5.4-r.1
version: 1.5.4-r.1
version: 15.1.3
purescript:
specifier: ^0.15.16
- version: 0.15.16
+ version: 0.15.16(bluebird@3.7.2)(supports-color@10.2.2)
sharp:
specifier: ^0.35.3
version: 0.35.3
packages:
- '@aws-sdk/checksums@3.1000.16':
- resolution: {integrity: sha512-EKnvkXSmz3IpA99tCNuI+dLFXyZyClSm8zns9sB/elvkU+MTuomAs6toJMPMBf98/fICG/urXDkzGz0/c3yyAQ==}
+ '@aws-sdk/checksums@3.1000.24':
+ resolution: {integrity: sha512-7TWLjypP8kk3savsDBRuhZJx7mBuFFA2136BQhwwLllsAnO4Tmq/p+SXZaNxbuulkzUFz3BZzj0bb4YzexZcNQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/client-s3@3.1085.0':
- resolution: {integrity: sha512-O0xe8sR50AYkwxlvRRsV0qytEO2dtXQTQ1CF3YBBdE5xtVkbu27H0vGa1mjQi1/+fbYM80AWEIPai5jZmXyubw==}
+ '@aws-sdk/client-s3@3.1101.0':
+ resolution: {integrity: sha512-16EFb1aTEBgPcfUAWAjjlB57IZCyn7B3rlfT+xqE7M6WoH8AMMU3vFZO0UOitwh/xvvzVx73YED1/n0PU4qBMw==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/core@3.975.1':
- resolution: {integrity: sha512-8qh/6EYb7hl/ZwVfQufhbMEZs1gQIc7GbdrIf4eprQJ7cv042+74nE6l3YDfyWNzb9iPXb8fRyYSHkNIk5eE6Q==}
+ '@aws-sdk/core@3.977.4':
+ resolution: {integrity: sha512-CEkcQlMOQJCvul60U7wdAOACjtdgFWDsfJI+6wUOGdhGNV2lGbuJpi/R50QLpFG3Tp+sQxa/RmzC3X7KHbhuTA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-env@3.972.57':
- resolution: {integrity: sha512-1RfJaF7SW1TOnvNGU7kaYjwUf5H3sfm+synGH1bHhRlqcnxCt3szebH3dmKEyY4tuGcbQ6ffzUT89cRitBV8OQ==}
+ '@aws-sdk/credential-provider-env@3.972.65':
+ resolution: {integrity: sha512-lJT2aRw9wCV8jPHyFJjdZLD4HTydL6/22AnCSOB8e/LqOc55nEJGLHkJQeSxhn8QiqyjFwPKQFtMw0ovjRUY/g==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-http@3.972.59':
- resolution: {integrity: sha512-sRCkpTiFnCdQvuaRVjQ6SVoHu6i7RUpurVo1c4F81HWhPvUJ7Wdp5MNtSdX1O29CNXc8em3O5m52hCjVtAD9SA==}
+ '@aws-sdk/credential-provider-http@3.972.67':
+ resolution: {integrity: sha512-N7fw/15hSwI/CPxe5ohOyb7O4ge9f5me1gVIn8OIkBRB0squ8OJqQyDyH/HoL+Sb1W5xdC88jVC+bHkw73iu+Q==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-ini@3.973.1':
- resolution: {integrity: sha512-6d8H6ZAh3ZPKZ6fe1nG2OWeZEZPtt9ravoD1dezPdPtsSkJRoxGAnFSHwKT3E/Te6fHE30zRzjV6TD12rvF6yQ==}
+ '@aws-sdk/credential-provider-ini@3.973.10':
+ resolution: {integrity: sha512-Zh9XRaPnDN9buO7GfWBubS22R6Nq5D6hbyYEMN05LiOnXugm/8WDjUx6y756bSPbdn3aJB2qG4zFW3bN82QhoQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-login@3.972.63':
- resolution: {integrity: sha512-GREWRrMj0XnNKMaVa/Mauoaui26qBEHu71WWqXbwZOu/jFQOnPZjTf7u0KtGKC8VGa6VUs9kDWGgocrKNLS9vw==}
+ '@aws-sdk/credential-provider-login@3.972.72':
+ resolution: {integrity: sha512-zZapIKwaHp7TdTf9hbH1I3CVUdEupmt7FXO/BoTQGC+4h6NkXKWpqF2p5WyfpjurDLHCpSyh+BzMlAg8arqWLA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-node@3.972.66':
- resolution: {integrity: sha512-f+qjRXZpz7sgzbc4QB+6nLKfyKFgRRXzWdXbsKPv/VhVRyHsDyq4yBWC/B75BAJpFIcUeI2XR/3gdWJ677zB4A==}
+ '@aws-sdk/credential-provider-node@3.972.76':
+ resolution: {integrity: sha512-1yzLmRiYSgGC25v7ZZEwJn/auhHHTIHgFOmzL2f36hf1+7jSLcX+1QrAz4760WEzPiiQl8xmlpFhHfl2OoyVzA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-process@3.972.57':
- resolution: {integrity: sha512-TiVQhuU0pbhIZAUZacbPHMyzrIdiH+lnx+PMY/Pu/b93dJrq3wdZwzUJ0TPpvNxaqbHsxJvQZW3/h/beLiKq7Q==}
+ '@aws-sdk/credential-provider-process@3.972.65':
+ resolution: {integrity: sha512-e5DbbNteOSalN58U83G6kFa4ECLEuGbGqNBHIXE7zYXA/m4GHblIGjFbSH7wYv6gBV8iNSDcRZBKfQZF5vF9nw==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-sso@3.973.1':
- resolution: {integrity: sha512-3foTZUJ4821Ij60X7K3NJroygiZLnbBmarN+T//O2cjkISan90zElN3NBmgSlDrTQ7Gs6z/yO8V7h60QNcDZHQ==}
+ '@aws-sdk/credential-provider-sso@3.973.9':
+ resolution: {integrity: sha512-0V0u4t+KBku9fbh5CPCaC5hUWwSzDafp8nCuDy817zWbp2gz80jO44rMQkiwnZ+k54B+tjAtzRy00DJRGTKGBg==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/credential-provider-web-identity@3.972.63':
- resolution: {integrity: sha512-8qZLFhM69eKcS37m459ctPR05Qimycm/74OPVioe6wNZabMT54GYhwBju0+J656RkMasNSawWQu+c8CmBe3TUQ==}
+ '@aws-sdk/credential-provider-web-identity@3.972.71':
+ resolution: {integrity: sha512-e4dwiRltGAaQ+2yxw57Hj0l/BF3BHiG14+QpYE7bGYBlpAq/fkIri2BDhjWon8c0mhhtd2txQBAkQb9BcTStFg==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/middleware-sdk-s3@3.972.62':
- resolution: {integrity: sha512-k8JJwYXVYlOOjWnPZDThQS1xDFJgi5Dokt73qFlDtrZAbdcint5aIdjB9XgJAAQVP5OoqcefQmh1FYXiPpvsvw==}
+ '@aws-sdk/middleware-sdk-s3@3.972.70':
+ resolution: {integrity: sha512-APdP0iODt39AkjCjzTFIoFrxDH/Cz3CpWRDKLcsJg7eOnfE1htkxL9BhDoe/xL7cXdoMwh2HBYv3DiT1uf64NQ==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/nested-clients@3.997.31':
- resolution: {integrity: sha512-BDHTpwcsZHEBNEJzOg/B1BkFYJxAXY50dau/NyVWs3d51F0WgIUGSWZot/Os+N3KpDhXeaXnz37mWffAvduREw==}
+ '@aws-sdk/nested-clients@3.997.39':
+ resolution: {integrity: sha512-wU5NPnj62Sb7A8xn/Zb+xThe05P3otNtDl37iOIi5DDMeCesNeCckaG+eXWGUs12Z9R34I8CD05TaTe6SIa61g==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/s3-request-presigner@3.1085.0':
- resolution: {integrity: sha512-h8fv0zGAHPCjCpmAYdCeFE6trxXxLRxza0NRIajMZdnFgugtcIWcRAdAtc7rHvRTaXsej/I5YWXbq9SgKuCKow==}
+ '@aws-sdk/s3-request-presigner@3.1101.0':
+ resolution: {integrity: sha512-2raRfiex9qYrdQ60ATeEmOVVC7Do2GEDGSTnoPbgv+xyN3oB48tZeREVw0brI7AlRRvm9fygXTHmyRR0I/LskA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/signature-v4-multi-region@3.996.39':
- resolution: {integrity: sha512-8+srXqYIF8KYMLC4FxMLEM5Ek7kUNibJu1R4m8/fUhhNYIZZz26oGtKkCr8I/HiG2fFQxBvaGgQZT4/mqRCSnA==}
+ '@aws-sdk/signature-v4-multi-region@3.996.43':
+ resolution: {integrity: sha512-lKekx8bLBXSv4O+cslk9Zfnw2XKSkWBs3uWL5QGhH2ZAQfNS7FE0vcSSN2vD/AhxX54ZTywWxR4STThoeOXlBA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/token-providers@3.1083.0':
- resolution: {integrity: sha512-s0woKnxuHrExLc5L2ArIH5BMkbonHPtt+5hSBM8oknp9M6QTuUmmAmJ2E0EdzCGONrO+8+ADPqvv6UX0nNcc7A==}
+ '@aws-sdk/token-providers@3.1100.0':
+ resolution: {integrity: sha512-THf3MkgY3fNJZ3zdgSenLqR7gSE68KccCj1RCKretlG73Ppszvues02VpCUO9NlB/tZDC483FvGCld+AiPCkvg==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/types@3.974.0':
- resolution: {integrity: sha512-QIBrw90CDm4O0UaIIzkU6DrFdeJzEb2Va5EPEVpyldj6sHJxB6cshhStJuhZxk3wR3PmjJlYsjPmY1kNb+KGBg==}
+ '@aws-sdk/types@3.974.2':
+ resolution: {integrity: sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA==}
engines: {node: '>=20.0.0'}
- '@aws-sdk/xml-builder@3.972.34':
- resolution: {integrity: sha512-wHhWL1y7sN3enBA8POrPpQM5jCcmu2ozyhbRei4c8OjVcEaEs6yLucLa/pla457ggS/ysuy7bosagz3HaJkZXA==}
+ '@aws-sdk/xml-builder@3.972.37':
+ resolution: {integrity: sha512-zKq4HQum8JwDyEuyfuI4bbiAcU0KxP6qy+9PR/IsR92IyE/DaBAikzAS50tjxip4bqIIANpCcG+Yyj6CVhXupg==}
engines: {node: '>=20.0.0'}
'@aws/lambda-invoke-store@0.3.0':
'@duckdb/node-bindings@1.5.4-r.1':
resolution: {integrity: sha512-v834OZZKQ59yAvh8GOEmM+R1foPNgdMGL0VTBgHywgblgQNyq11HvWgT4QGJIUFfo/cQ9WFyf1MFhK0+hV1aiA==}
- '@emnapi/runtime@1.11.2':
- resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==}
+ '@emnapi/runtime@1.11.3':
+ resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==}
'@esbuild/aix-ppc64@0.28.1':
resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==}
resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==}
engines: {node: '>=8.0.0'}
- '@smithy/core@3.29.3':
- resolution: {integrity: sha512-L+Ys6ecjk5vwPMAKHBpPKlJ3DkqwNcnfEISXBZIsVvWG/XKXfsAP8mwIYlTeLcd2ElHdesPI8OuOmJSFAPhm6A==}
+ '@smithy/core@3.31.1':
+ resolution: {integrity: sha512-CyogUINxvi7C7LDsh8Syo6hVJOT9ckz4rG8dRZfTJ8r91HkMY59PnNooaj7WcHyxEkxPfBAmbgztZU+xTo76lg==}
engines: {node: '>=18.0.0'}
- '@smithy/credential-provider-imds@4.4.8':
- resolution: {integrity: sha512-q9J7JTiXrAhB8sDp4px97uEPT7CwKH61Co78grdNQvU8QZAdiuaSRhP0tUVf2ogy36RZTrlMU1rBmDEH+cnkiA==}
+ '@smithy/credential-provider-imds@4.4.16':
+ resolution: {integrity: sha512-QfuLWAkLzptffFW980AFeHZFdqds2B64rpEd3uJ6lgs3xVn9QegGMUgUcj+4d7dRrAsya3r58ZKpku97WcFb4w==}
engines: {node: '>=18.0.0'}
- '@smithy/fetch-http-handler@5.6.5':
- resolution: {integrity: sha512-SuqeisTyPoiIPtIYru/sGxGyXzmZ+8nnFOhC+qRPglt06Ebd1yH//CDltZB2J/3WBNVhwfUaZ0EtHB3cm2X32g==}
+ '@smithy/fetch-http-handler@5.6.13':
+ resolution: {integrity: sha512-4fW86pEUOMbrD5nkbyl/tTvPHHWJFbuB2odl6ps9lWfHoXf9HWh3Q/Smh59qH1g7+c/BSZghX6bbUk4gsiMs8A==}
engines: {node: '>=18.0.0'}
- '@smithy/node-http-handler@4.9.5':
- resolution: {integrity: sha512-bNqdxTQTxmLbomSmlkZFz8L6B/feQ2HHzw4L2zY7Ecp2XffYAZq2uzdWDdxJHJFbEvqd+SRuluJso0P8+xPdbw==}
+ '@smithy/node-http-handler@4.9.13':
+ resolution: {integrity: sha512-Nmd/Nl35zfYrd+a6OO2cDJb3GPh9bgTjIUhcM+JFfjpp8/osCgboDV5nCT1I01Pv6R13eSKDKLSoVa5ZB6Zsfw==}
engines: {node: '>=18.0.0'}
- '@smithy/signature-v4@5.6.4':
- resolution: {integrity: sha512-B89bpf2t/y/wia6LZ+4JfHXYQT9PnVftsH05rgJKKIStS7r/4XSs9HOjtPoLtgcA6HCW9jVqX5DBbq7E0PAkiQ==}
+ '@smithy/signature-v4@5.6.12':
+ resolution: {integrity: sha512-I6KLtq3H0qqSuV9vLglfi8puHqzygzWHOnI4z/Rdoo+q50vvo18vBRdPAvvEtcaKROz7Zn6qnPa14kRfPH6PcQ==}
engines: {node: '>=18.0.0'}
'@smithy/types@4.16.1':
bowser@2.14.1:
resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==}
- brace-expansion@1.1.16:
- resolution: {integrity: sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==}
+ brace-expansion@1.1.18:
+ resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==}
- brace-expansion@2.1.2:
- resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==}
+ brace-expansion@2.1.4:
+ resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==}
- brace-expansion@5.0.7:
- resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==}
- engines: {node: 18 || 20 || >=22}
+ brace-expansion@5.0.9:
+ resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==}
+ engines: {node: 20 || >=22}
braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
from2@2.3.0:
resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==}
- fs-extra@11.3.6:
- resolution: {integrity: sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==}
+ fs-extra@11.4.0:
+ resolution: {integrity: sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==}
engines: {node: '>=14.14'}
fs-minipass@2.1.0:
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
- fuse.js@7.4.2:
- resolution: {integrity: sha512-LVbzjD4WA6UP5B1UnP8wuaXJiLnqMdM/E4fiJXTJ5haJ5b/MBNsK29h2fm6swEoQaVQjvYFWKLE2RanyZIoRVQ==}
+ fuse.js@7.5.0:
+ resolution: {integrity: sha512-sQtrEfA+ez/3G0cCZecF70oqpCRttCexYUG4mUrtWL49ULUzUyxokt5kyqwtKzj1270RaKih+hcP3qLcumccow==}
engines: {node: '>=10'}
get-stream@5.2.0:
inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
- ip-address@10.2.0:
- resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==}
+ ip-address@10.4.0:
+ resolution: {integrity: sha512-oSK96Grm3aP6OrS263xVxbNDGVL7rzBtYdpGqlDG8iQdoenDoTs/nkki+DflYbAEE8Xl6o5YxhxlrKvI3nqKXQ==}
engines: {node: '>= 12'}
is-docker@3.0.0:
resolution: {integrity: sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==}
hasBin: true
- mdurl@2.0.0:
- resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
+ mdurl@2.1.0:
+ resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==}
merge-stream@2.0.0:
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
- minimatch@10.2.5:
- resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ minimatch@10.2.6:
+ resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==}
engines: {node: 18 || 20 || >=22}
minimatch@3.1.5:
engines: {node: '>=10'}
deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
- tar@7.5.20:
- resolution: {integrity: sha512-9FcyK4PA6+WbzlTM9WhQm6vB5W7cP7dUiPsv1g7YDwEQnQ1CGpK3MGlKk/ITVWMk05kHZuBhmVhiv8LZoy/PFQ==}
+ tar@7.5.22:
+ resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==}
engines: {node: '>=18'}
tdigest@0.1.2:
snapshots:
- '@aws-sdk/checksums@3.1000.16':
+ '@aws-sdk/checksums@3.1000.24':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/client-s3@3.1085.0':
+ '@aws-sdk/client-s3@3.1101.0':
dependencies:
- '@aws-sdk/checksums': 3.1000.16
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/credential-provider-node': 3.972.66
- '@aws-sdk/middleware-sdk-s3': 3.972.62
- '@aws-sdk/signature-v4-multi-region': 3.996.39
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/node-http-handler': 4.9.5
+ '@aws-sdk/checksums': 3.1000.24
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/credential-provider-node': 3.972.76
+ '@aws-sdk/middleware-sdk-s3': 3.972.70
+ '@aws-sdk/signature-v4-multi-region': 3.996.43
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
+ '@smithy/fetch-http-handler': 5.6.13
+ '@smithy/node-http-handler': 4.9.13
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/core@3.975.1':
+ '@aws-sdk/core@3.977.4':
dependencies:
- '@aws-sdk/types': 3.974.0
- '@aws-sdk/xml-builder': 3.972.34
+ '@aws-sdk/types': 3.974.2
+ '@aws-sdk/xml-builder': 3.972.37
'@aws/lambda-invoke-store': 0.3.0
- '@smithy/core': 3.29.3
- '@smithy/signature-v4': 5.6.4
+ '@smithy/core': 3.31.1
+ '@smithy/signature-v4': 5.6.12
'@smithy/types': 4.16.1
bowser: 2.14.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-env@3.972.57':
+ '@aws-sdk/credential-provider-env@3.972.65':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-http@3.972.59':
+ '@aws-sdk/credential-provider-http@3.972.67':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/node-http-handler': 4.9.5
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
+ '@smithy/fetch-http-handler': 5.6.13
+ '@smithy/node-http-handler': 4.9.13
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-ini@3.973.1':
+ '@aws-sdk/credential-provider-ini@3.973.10':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/credential-provider-env': 3.972.57
- '@aws-sdk/credential-provider-http': 3.972.59
- '@aws-sdk/credential-provider-login': 3.972.63
- '@aws-sdk/credential-provider-process': 3.972.57
- '@aws-sdk/credential-provider-sso': 3.973.1
- '@aws-sdk/credential-provider-web-identity': 3.972.63
- '@aws-sdk/nested-clients': 3.997.31
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
- '@smithy/credential-provider-imds': 4.4.8
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/credential-provider-env': 3.972.65
+ '@aws-sdk/credential-provider-http': 3.972.67
+ '@aws-sdk/credential-provider-login': 3.972.72
+ '@aws-sdk/credential-provider-process': 3.972.65
+ '@aws-sdk/credential-provider-sso': 3.973.9
+ '@aws-sdk/credential-provider-web-identity': 3.972.71
+ '@aws-sdk/nested-clients': 3.997.39
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
+ '@smithy/credential-provider-imds': 4.4.16
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-login@3.972.63':
+ '@aws-sdk/credential-provider-login@3.972.72':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/nested-clients': 3.997.31
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/nested-clients': 3.997.39
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-node@3.972.66':
+ '@aws-sdk/credential-provider-node@3.972.76':
dependencies:
- '@aws-sdk/credential-provider-env': 3.972.57
- '@aws-sdk/credential-provider-http': 3.972.59
- '@aws-sdk/credential-provider-ini': 3.973.1
- '@aws-sdk/credential-provider-process': 3.972.57
- '@aws-sdk/credential-provider-sso': 3.973.1
- '@aws-sdk/credential-provider-web-identity': 3.972.63
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
- '@smithy/credential-provider-imds': 4.4.8
+ '@aws-sdk/credential-provider-env': 3.972.65
+ '@aws-sdk/credential-provider-http': 3.972.67
+ '@aws-sdk/credential-provider-ini': 3.973.10
+ '@aws-sdk/credential-provider-process': 3.972.65
+ '@aws-sdk/credential-provider-sso': 3.973.9
+ '@aws-sdk/credential-provider-web-identity': 3.972.71
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
+ '@smithy/credential-provider-imds': 4.4.16
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-process@3.972.57':
+ '@aws-sdk/credential-provider-process@3.972.65':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-sso@3.973.1':
+ '@aws-sdk/credential-provider-sso@3.973.9':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/nested-clients': 3.997.31
- '@aws-sdk/token-providers': 3.1083.0
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/nested-clients': 3.997.39
+ '@aws-sdk/token-providers': 3.1100.0
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/credential-provider-web-identity@3.972.63':
+ '@aws-sdk/credential-provider-web-identity@3.972.71':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/nested-clients': 3.997.31
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/nested-clients': 3.997.39
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/middleware-sdk-s3@3.972.62':
+ '@aws-sdk/middleware-sdk-s3@3.972.70':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/signature-v4-multi-region': 3.996.39
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/signature-v4-multi-region': 3.996.43
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/nested-clients@3.997.31':
+ '@aws-sdk/nested-clients@3.997.39':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/signature-v4-multi-region': 3.996.39
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
- '@smithy/fetch-http-handler': 5.6.5
- '@smithy/node-http-handler': 4.9.5
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/signature-v4-multi-region': 3.996.43
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
+ '@smithy/fetch-http-handler': 5.6.13
+ '@smithy/node-http-handler': 4.9.13
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/s3-request-presigner@3.1085.0':
+ '@aws-sdk/s3-request-presigner@3.1101.0':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/signature-v4-multi-region': 3.996.39
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/signature-v4-multi-region': 3.996.43
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/signature-v4-multi-region@3.996.39':
+ '@aws-sdk/signature-v4-multi-region@3.996.43':
dependencies:
- '@aws-sdk/types': 3.974.0
- '@smithy/signature-v4': 5.6.4
+ '@aws-sdk/types': 3.974.2
+ '@smithy/signature-v4': 5.6.12
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/token-providers@3.1083.0':
+ '@aws-sdk/token-providers@3.1100.0':
dependencies:
- '@aws-sdk/core': 3.975.1
- '@aws-sdk/nested-clients': 3.997.31
- '@aws-sdk/types': 3.974.0
- '@smithy/core': 3.29.3
+ '@aws-sdk/core': 3.977.4
+ '@aws-sdk/nested-clients': 3.997.39
+ '@aws-sdk/types': 3.974.2
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/types@3.974.0':
+ '@aws-sdk/types@3.974.2':
dependencies:
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@aws-sdk/xml-builder@3.972.34':
+ '@aws-sdk/xml-builder@3.972.37':
dependencies:
'@smithy/types': 4.16.1
tslib: 2.8.1
'@duckdb/node-bindings-win32-arm64': 1.5.4-r.1
'@duckdb/node-bindings-win32-x64': 1.5.4-r.1
- '@emnapi/runtime@1.11.2':
+ '@emnapi/runtime@1.11.3':
dependencies:
tslib: 2.8.1
optional: true
'@img/sharp-wasm32@0.35.3':
dependencies:
- '@emnapi/runtime': 1.11.2
+ '@emnapi/runtime': 1.11.3
optional: true
'@img/sharp-webcontainers-wasm32@0.35.3':
'@opentelemetry/api@1.9.1': {}
- '@smithy/core@3.29.3':
+ '@smithy/core@3.31.1':
dependencies:
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@smithy/credential-provider-imds@4.4.8':
+ '@smithy/credential-provider-imds@4.4.16':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@smithy/fetch-http-handler@5.6.5':
+ '@smithy/fetch-http-handler@5.6.13':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@smithy/node-http-handler@4.9.5':
+ '@smithy/node-http-handler@4.9.13':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
- '@smithy/signature-v4@5.6.4':
+ '@smithy/signature-v4@5.6.12':
dependencies:
- '@smithy/core': 3.29.3
+ '@smithy/core': 3.31.1
'@smithy/types': 4.16.1
tslib: 2.8.1
'@tootallnate/once@2.0.1': {}
- agent-base@6.0.2:
+ agent-base@6.0.2(supports-color@10.2.2):
dependencies:
- debug: 4.4.3
+ debug: 4.4.3(supports-color@10.2.2)
transitivePeerDependencies:
- supports-color
bowser@2.14.1: {}
- brace-expansion@1.1.16:
+ brace-expansion@1.1.18:
dependencies:
balanced-match: 1.0.2
concat-map: 0.0.1
- brace-expansion@2.1.2:
+ brace-expansion@2.1.4:
dependencies:
balanced-match: 1.0.2
- brace-expansion@5.0.7:
+ brace-expansion@5.0.9:
dependencies:
balanced-match: 4.0.4
unique-filename: 1.1.1
y18n: 4.0.3
- cacache@16.1.3:
+ cacache@16.1.3(bluebird@3.7.2):
dependencies:
'@npmcli/fs': 2.1.2
'@npmcli/move-file': 2.0.1
cyclist@1.0.2: {}
- debug@4.4.3:
+ debug@4.4.3(supports-color@10.2.2):
dependencies:
ms: 2.1.3
+ optionalDependencies:
+ supports-color: 10.2.2
default-browser-id@5.0.1: {}
inherits: 2.0.4
readable-stream: 2.3.8
- fs-extra@11.3.6:
+ fs-extra@11.4.0:
dependencies:
graceful-fs: 4.2.11
jsonfile: 6.2.1
fs.realpath@1.0.0: {}
- fuse.js@7.4.2: {}
+ fuse.js@7.5.0: {}
get-stream@5.2.0:
dependencies:
dependencies:
foreground-child: 3.3.1
jackspeak: 4.2.3
- minimatch: 10.2.5
+ minimatch: 10.2.6
minipass: 7.1.3
package-json-from-dist: 1.0.1
path-scurry: 2.0.2
http-cache-semantics@4.2.0: {}
- http-proxy-agent@5.0.0:
+ http-proxy-agent@5.0.0(supports-color@10.2.2):
dependencies:
'@tootallnate/once': 2.0.1
- agent-base: 6.0.2
- debug: 4.4.3
+ agent-base: 6.0.2(supports-color@10.2.2)
+ debug: 4.4.3(supports-color@10.2.2)
transitivePeerDependencies:
- supports-color
- https-proxy-agent@5.0.1:
+ https-proxy-agent@5.0.1(supports-color@10.2.2):
dependencies:
- agent-base: 6.0.2
- debug: 4.4.3
+ agent-base: 6.0.2(supports-color@10.2.2)
+ debug: 4.4.3(supports-color@10.2.2)
transitivePeerDependencies:
- supports-color
inherits@2.0.4: {}
- ip-address@10.2.0: {}
+ ip-address@10.4.0: {}
is-docker@3.0.0: {}
lru-cache@7.18.3: {}
- make-fetch-happen@10.2.1:
+ make-fetch-happen@10.2.1(bluebird@3.7.2)(supports-color@10.2.2):
dependencies:
agentkeepalive: 4.6.0
- cacache: 16.1.3
+ cacache: 16.1.3(bluebird@3.7.2)
http-cache-semantics: 4.2.0
- http-proxy-agent: 5.0.0
- https-proxy-agent: 5.0.1
+ http-proxy-agent: 5.0.0(supports-color@10.2.2)
+ https-proxy-agent: 5.0.1(supports-color@10.2.2)
is-lambda: 1.0.1
lru-cache: 7.18.3
minipass: 3.3.6
minipass-pipeline: 1.2.4
negotiator: 0.6.4
promise-retry: 2.0.1
- socks-proxy-agent: 7.0.0
+ socks-proxy-agent: 7.0.0(supports-color@10.2.2)
ssri: 9.0.1
transitivePeerDependencies:
- bluebird
argparse: 2.0.1
entities: 4.5.0
linkify-it: 5.0.2
- mdurl: 2.0.0
+ mdurl: 2.1.0
punycode.js: 2.3.1
uc.micro: 2.1.0
- mdurl@2.0.0: {}
+ mdurl@2.1.0: {}
merge-stream@2.0.0: {}
mimic-fn@2.1.0: {}
- minimatch@10.2.5:
+ minimatch@10.2.6:
dependencies:
- brace-expansion: 5.0.7
+ brace-expansion: 5.0.9
minimatch@3.1.5:
dependencies:
- brace-expansion: 1.1.16
+ brace-expansion: 1.1.18
minimatch@5.1.9:
dependencies:
- brace-expansion: 2.1.2
+ brace-expansion: 2.1.4
minimist@1.2.8: {}
punycode@2.3.1: {}
- purescript-installer@0.3.5:
+ purescript-installer@0.3.5(bluebird@3.7.2)(supports-color@10.2.2):
dependencies:
byline: 5.0.0
cacache: 11.3.3
is-plain-obj: 2.1.0
log-symbols: 3.0.0
log-update: 4.0.0
- make-fetch-happen: 10.2.1
+ make-fetch-happen: 10.2.1(bluebird@3.7.2)(supports-color@10.2.2)
minimist: 1.2.8
ms: 2.1.3
once: 1.4.0
purescript-psa@0.9.0: {}
- purescript@0.15.16:
+ purescript@0.15.16(bluebird@3.7.2)(supports-color@10.2.2):
dependencies:
- purescript-installer: 0.3.5
+ purescript-installer: 0.3.5(bluebird@3.7.2)(supports-color@10.2.2)
transitivePeerDependencies:
- bluebird
- supports-color
smart-buffer@4.2.0: {}
- socks-proxy-agent@7.0.0:
+ socks-proxy-agent@7.0.0(supports-color@10.2.2):
dependencies:
- agent-base: 6.0.2
- debug: 4.4.3
+ agent-base: 6.0.2(supports-color@10.2.2)
+ debug: 4.4.3(supports-color@10.2.2)
socks: 2.8.9
transitivePeerDependencies:
- supports-color
socks@2.8.9:
dependencies:
- ip-address: 10.2.0
+ ip-address: 10.4.0
smart-buffer: 4.2.0
spago@1.0.4:
dependencies:
'@nodelib/fs.walk': 3.0.1
env-paths: 3.0.0
- fs-extra: 11.3.6
- fuse.js: 7.4.2
+ fs-extra: 11.4.0
+ fuse.js: 7.5.0
glob: 11.1.0
markdown-it: 14.3.0
micromatch: 4.0.8
spdx-expression-parse: 4.0.0
ssh2: 1.17.0
supports-color: 10.2.2
- tar: 7.5.20
+ tar: 7.5.22
tmp: 0.2.7
xhr2: 0.2.1
yaml: 2.9.0
mkdirp: 1.0.4
yallist: 4.0.0
- tar@7.5.20:
+ tar@7.5.22:
dependencies:
'@isaacs/fs-minipass': 4.0.1
chownr: 3.0.0
blob - 39c343b9a4af4e29e2d61256a1efd6f142255451
blob + b1006db90f3c4d2fb6b77a20a1b5c84bd98e5688
--- src/Templates.purs
+++ src/Templates.purs
<div id="app"></div>
<script src="/client.js"></script>
<script>
- var userSlug = '""" <> userSlug <>
+ var userSlug = '""" <> userSlug
+ <>
"""';
- var allUsers = """ <> usersJson <>
+ var allUsers = """
+ <> usersJson
+ <>
""";
- var registrationEnabled = """ <> registrationEnabledJson <>
+ var registrationEnabled = """
+ <> registrationEnabledJson
+ <>
""";
var adminToken = window.localStorage.getItem('corpusAdminToken') || '';
var app = Elm.Client.init({
blob - e53876ca46d78093bcca958c0d6192f5984e0045
blob + fd4c30133d970ba4d82edb8ebbb648b0ff85be70
--- src/View.elm
+++ src/View.elm
import Browser
import Dict exposing (Dict)
-import Html exposing (Html, a, button, div, h1, h2, header, img, input, li, p, span, strong, table, tbody, td, text, th, thead, tr, ul)
+import Html exposing (Html, a, button, div, h2, header, img, input, li, p, span, strong, table, tbody, td, text, th, thead, tr, ul)
import Html.Attributes as Attr exposing (class, disabled, href, placeholder, src, style, target, type_, value)
import Html.Events exposing (on, onClick, onInput)
import Json.Decode as D
import Set exposing (Set)
-import Time
import Types exposing (Listen, Model, Msg(..), Page(..), Period(..), RegField(..), Registration, SimilarState(..), SimilarTrack, Stats, StatsEntry, Tab(..), UserInfo)
import Url
key =
String.fromInt idx ++ "\t" ++ artist ++ "\t" ++ trackName
in
- renderListen model.userSlug model.currentTime model.failedCovers model.hoveredCover model.similarStates idx listen
+ renderListen model.userSlug model.failedCovers model.hoveredCover model.similarStates idx listen
:: renderSimilarRow key model.similarStates
)
model.listens
]
-renderListen : String -> Maybe Time.Posix -> Set String -> Maybe Int -> Dict String SimilarState -> Int -> Listen -> Html Msg
-renderListen userSlug currentTime failedCovers hoveredCover similarStates idx listen =
+renderListen : String -> Set String -> Maybe Int -> Dict String SimilarState -> Int -> Listen -> Html Msg
+renderListen userSlug failedCovers hoveredCover similarStates idx listen =
let
artist =
Maybe.withDefault "" listen.artistName
)
-
--- HELPERS
-
-
-timeAgo : Maybe Time.Posix -> Maybe Int -> String
-timeAgo mNow mTimestamp =
- case ( mNow, mTimestamp ) of
- ( Just now, Just ts ) ->
- let
- nowSecs =
- Time.posixToMillis now // 1000
-
- diff =
- nowSecs - ts
- in
- if diff < 60 then
- "just now"
-
- else if diff < 3600 then
- let
- mins =
- diff // 60
- in
- String.fromInt mins
- ++ " minute"
- ++ (if mins > 1 then
- "s"
-
- else
- ""
- )
- ++ " ago"
-
- else if diff < 86400 then
- let
- hours =
- diff // 3600
- in
- String.fromInt hours
- ++ " hour"
- ++ (if hours > 1 then
- "s"
-
- else
- ""
- )
- ++ " ago"
-
- else
- let
- days =
- diff // 86400
- in
- String.fromInt days
- ++ " day"
- ++ (if days > 1 then
- "s"
-
- else
- ""
- )
- ++ " ago"
-
- _ ->
- "unknown time"
-
-
renderAboutView : String -> List UserInfo -> Html Msg
renderAboutView currentSlug allUsers =
let