Keep the S3 sync and filesystem storage out of the updater import graph

updateAll() only runs the updaters now. The local (Node) flavour, which
also uploads to S3 when configured, lives in src/app/local.js next to the
filesystem storage wiring, and the entry points call that. The storage
barrel no longer re-exports FilesystemStorage. With both gone, the
updater tree bundles for a non-Node target with no unresolved imports.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Matt Isenhower
2026-09-05 10:31:09 -07:00
parent 899b9ff9ea
commit be6c23788f
7 changed files with 32 additions and 29 deletions

View File

@@ -1,13 +1,12 @@
import '../common/bootstrap.js';
import { CronJob } from 'cron';
import { updateAll } from './updater/index.js';
import { filesystemStorage } from './storage.js';
import { updateAllLocally } from './local.js';
import { maybePostTweets } from './twitter/index.js';
console.info('Starting periodic tasks...');
// Run every hour at 10sec after the hour
new CronJob('10 0 * * * *', async () => {
await updateAll(filesystemStorage());
await updateAllLocally();
await maybePostTweets();
}, null, true);

View File

@@ -1,12 +1,11 @@
import '../common/bootstrap.js';
import { runAction } from '../common/cli.js';
import { updateAll } from './updater/index.js';
import { filesystemStorage } from './storage.js';
import { updateAllLocally } from './local.js';
import { maybePostTweets, testScreenshots } from './twitter/index.js';
import { sync, syncUpload, syncDownload } from './sync/index.js';
await runAction({
splatnet: () => updateAll(filesystemStorage()),
splatnet: updateAllLocally,
twitter: maybePostTweets,
twitterTest: testScreenshots,
sync,

24
src/app/local.js Normal file
View File

@@ -0,0 +1,24 @@
// The local (Node) flavour of running the updaters: filesystem storage in the directories
// the site has always been built from, followed by the S3 upload when it is configured.
// The Worker entry point has its own equivalent over R2.
import FilesystemStorage from '../common/storage/FilesystemStorage.js';
import { updateAll } from './updater/index.js';
import S3Syncer from './sync/S3Syncer.js';
import { canSync } from './sync/index.js';
export function filesystemStorage() {
return {
publicStorage: new FilesystemStorage('dist'),
privateStorage: new FilesystemStorage('storage'),
};
}
export async function updateAllLocally() {
await updateAll(filesystemStorage());
if (canSync())
await new S3Syncer().upload();
return 'Done';
}

View File

@@ -1,12 +0,0 @@
import { FilesystemStorage } from '../common/storage/index.js';
/**
* The storage a local (Node) run uses: the same directories the site has always been
* built from, so `npm run splatnet` and the S3 sync keep working unchanged.
*/
export function filesystemStorage() {
return {
publicStorage: new FilesystemStorage('dist'),
privateStorage: new FilesystemStorage('storage'),
};
}

View File

@@ -4,8 +4,6 @@ import TimelineUpdater from './updaters/TimelineUpdater.js';
import OriginalGearImageUpdater from './updaters/OriginalGearImageUpdater.js';
import FestivalsUpdater from './updaters/FestivalsUpdater.js';
import MerchandisesUpdater from './updaters/MerchandisesUpdater.js';
import S3Syncer from '../sync/S3Syncer.js';
import { canSync } from '../sync/index.js';
/** @param {{ publicStorage: object, privateStorage: object }} storage */
export function createUpdaters(storage) {
@@ -26,8 +24,6 @@ export function createUpdaters(storage) {
* a Worker passes BucketStorage over its R2 bindings, a local run passes FilesystemStorage.
*/
export default async function updateAll(storage) {
const syncer = canSync() ? new S3Syncer() : null;
for (let updater of createUpdaters(storage)) {
try {
await updater.update();
@@ -36,9 +32,4 @@ export default async function updateAll(storage) {
}
}
if (syncer) {
await syncer.upload();
}
return 'Done';
}

View File

@@ -1,6 +1,7 @@
// Note: FilesystemStorage is deliberately not re-exported here; it imports node:fs, and this
// module is part of the updaters' import graph, which also has to bundle into a Worker.
export { default as MemoryBucket } from './MemoryBucket.js';
export { default as BucketStorage } from './BucketStorage.js';
export { default as FilesystemStorage } from './FilesystemStorage.js';
// What the S3 sync applied to data/ objects; the R2 objects carry it directly.
export const DATA_CACHE_CONTROL = 'no-cache, stale-while-revalidate=5, stale-if-error=86400';

View File

@@ -3,7 +3,8 @@ import assert from 'node:assert/strict';
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { MemoryBucket, BucketStorage, FilesystemStorage } from '../../src/common/storage/index.js';
import { MemoryBucket, BucketStorage } from '../../src/common/storage/index.js';
import FilesystemStorage from '../../src/common/storage/FilesystemStorage.js';
// One contract for the storage interface the updaters use, run against every implementation.
const implementations = {