Browse the Web Tiles published on the AT Protocol.

Publish blob refs with the mimeType uploadBlob returns #12

targeting main
Open opened by and assigned to center.for.cybernetic.beauty
targeting main

Two independent commits.

1. Publish blob refs with the mimeType uploadBlob returns #

The publish page writes mimeType: application/octet-stream into every blob ref, following the spec's appendix. Some PDS implementations, the reference one (bluesky-social/atproto) among them, reject that for any file whose type they can recognise from its bytes:

  • uploadBlob sniffs the bytes and stores the blob under the type it recognises (image/png, audio/wav, font/woff2, …). The declared type is kept only when nothing is recognised, which is the case for HTML, CSS, JavaScript and JSON.
  • putRecord compares each new blob ref's mimeType with the stored type and refuses the whole record if they differ.

So a tile made only of text publishes, and any tile with an image, a sound or a font fails at putRecord, for example:

Referenced Mimetype does not match stored blob. Expected: audio/wav

The page still uploads with application/octet-stream, and now writes the mimeType from the blob ref uploadBlob returns. Where the PDS sniffs, that is the type it stored; where it does not, it is application/octet-stream as before, so nothing changes for text-only tiles or for implementations that do not sniff. A blob shared by several paths is still uploaded once. The record preview shows the field as "(from the upload, at publish time)", and the developer docs describe the same steps.

atile publish doesn't hit this, because it sniffs each file itself with file-type, the same library the reference PDS uses. That only holds while the two agree.

2. Prefer a raster picture for a tile page's og:image #

A tile page's og:image is its first screenshot, or its icon. Bluesky's link cards, among others, do not show an SVG, so a tile whose first screenshot is an SVG is shared with no picture. cardPicture() now picks the first raster screenshot or icon, screenshots first, and falls back on an SVG only when there is nothing else. There is a test for it in test/tiles.test.js.

Before the first commit, a tile could not carry a PNG through this page, so tiles that wanted a picture worked around it by wrapping the PNG in an SVG. Together, the two commits let a tile ship a PNG screenshot and have it show up on Bluesky.

Testing #

  • npm test: 14/14 pass, including the new cardPicture test.
  • npm run build succeeds.
  • The publish change has not yet been run against a live PDS.

The spec's appendix gives the advice the page followed. There is a companion PR to dasl.ing (tiles.html) recommending that publishers use the blob ref uploadBlob returns, mimeType included, as the resource's src.

This pull request has no versions submitted yet.