Publish tiles that contain images, audio or fonts, and give link cards a raster picture #
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:
uploadBlobsniffs 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.putRecordcompares each new blob ref'smimeTypewith 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 newcardPicturetest.npm run buildsucceeds.- The publish change has not yet been run against a live PDS.
Related #
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.