VFS now loads on first has()/getMtime() call rather than requiring
explicit initialization in sync/index.mjs. This ensures it works
regardless of entry point (sync:download, splatnet:quick, etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
exists() and olderThan() now check the local filesystem first and only
consult the VFS as a fallback. This means freshly written files are
found naturally without callers needing to register them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Uses S3 ListObjectsV2 to build an in-memory file listing at startup,
allowing exists() and olderThan() to resolve from the listing instead
of requiring files on disk. sync:download now skips assets/splatnet/,
data/xrank/, data/festivals.ranking.*, and status-screenshots/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
jsonpath v1.2.1 (published Feb 2025) fixed the security vulnerability
that prompted the switch to jsonpath-plus. Reverting to the original
package simplifies the code by removing the jsonpathQuery/jsonpathApply
wrapper functions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added mkdirp() helper to app/common/fs.mjs that wraps
fs.mkdir(dir, { recursive: true }). Updated all call sites to use it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Deduplicate identical _calculateCacheExpiry methods from
SplatNet3Client and NsoClient into a shared calculateCacheExpiry
function in util.mjs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This now strips out the domain and query string from the URL before hashing it. This way, we can help ensure the hashes will stay the same when those parameters change.