Skip to content

Add S3 file storage submodule - #6417

Open
bradleyshep wants to merge 14 commits into
masterfrom
bradley/submodules-s3
Open

bradleyshep wants to merge 14 commits into
masterfrom
bradley/submodules-s3

Conversation

@bradleyshep

@bradleyshep bradleyshep commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Description of Changes

Adds @spacetimedb/s3, a submodule for storing user files in Amazon S3.

  • Files go straight between the browser and S3. SpacetimeDB keeps track of who owns each file and whether it's ready.
  • If the server restarts or S3 fails partway through an upload or delete, the submodule finishes the job later.
  • Adds a browser example where each user can upload, download, and delete their own files.
  • Moves the examples' "Built on SpacetimeDB" footer into @spacetimedb/example-ui so all the examples share one. Cron loses its "View source" link.

Demo

s3-example-demo.mp4

API and ABI breaking changes

None. This adds a new package.

Rollback safety impact

n/a

Expected complexity level and risk

2/5

Testing

Removed the static footer markup test (Core review tier). Shared authentication and server tests remain.

  • Lint, type checks, unit tests, and builds.
  • A local test that restarts the server and makes S3 fail partway through (16 cases).
  • Real S3, using an AWS user with only the permissions the README lists.
  • The example in a browser on real S3: upload, download, delete, and two users who can't see each other's files.
  • Installing the package in a new project with SpacetimeDB 2.12.
  • Review the API and the README.

- README: a complete quick start, publishing and credential rotation, file
  states, error codes, and the missing AWS steps. Internals trimmed.
- Raise the default S3 request timeout from 5 to 15 seconds.
- Download URLs save files under their original name.
- Example: read credentials from one snapshot, download without buffering,
  and release the reservation when an upload fails.
Ready files show download and delete icon buttons. Verifying and deleting
show a spinner, and a deleting row fades. The connection pill and the MIME
type are gone. Long file names no longer push the buttons off a phone screen.
Screen readers get the progress bar's value and each upload step.
The text "+" rendered thin and small beside the bold label.
One column at reading width with hairline rows, in place of a full-width
header card, a panel card, and a card per file. The count and the product
name are plain text, not pills. Glows and shadows are gone. Icon buttons have
no frame until hovered. Upload progress runs along the row's edge with its
percentage, so rows keep their height. Errors appear beside the Upload button,
and the count stays blank until the list loads.
Use the rate-limit and Resend footer, a Built on label and the SpacetimeDB
wordmark. The View source link pointed at the repository root, which anyone
running the example already has.
Add mountFooter() and footer.css to the package and use them in the
cron, resend and rate-limit examples instead of copied markup and CSS.
The footer reads --example-footer-border and --example-footer-label,
so each example keeps its own colors. Cron moves to the same footer as
the others and drops its "View source" link.
Replace the copied footer markup and styles with mountFooter() from
@spacetimedb/example-ui, colored from the S3 tokens.

Check a download URL with a one-byte request before opening it, so an S3
refusal shows beside Upload instead of replacing the page.
Follow the other submodule READMEs: install, AWS setup, one integration
example, and a short API list. Drop the internal terms and the sections that
explained internals.
LICENSE.txt was committed as a regular file holding the link target
text. It is now a symlink to ../../licenses/apache2.txt.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant