full diff

at.meme-museum.meme

meme-museum.at +10 −2
From
bafyreieyedbzo5mvnt56wwgx6jztf7jlbvldrw5mudew5jkjwdnaumsrou indexed 2026-08-11 21:43 UTC View this version
To
bafyreigkp2unogwez6am2go2bft7uhtlawaajwta5pyuazsbpjkvpcsrpa indexed 2026-08-29 18:16 UTC View this version

Compatibility

backward compatible Backward compatible. 2 non-breaking changes.

Non-breaking changes (2)
  • AddedVertex AddedVertex { vertex_id: "at.meme-museum.meme:body.postVideo" }
  • AddedEdge AddedEdge { src: "at.meme-museum.meme:body", tgt: "at.meme-museum.meme:body.postVideo", kind: "prop", name: Some("postVideo") }

Migration guidance

Added

  • AddedVertex { vertex_id: "at.meme-museum.meme:body.postVideo" }

Notes

  • Non-breaking: AddedEdge { src: "at.meme-museum.meme:body", tgt: "at.meme-museum.meme:body.postVideo", kind: "prop", name: Some("postVideo") }

Changes

11{
22 "$type": "com.atproto.lexicon.schema",
33 "defs": {
44 "main": {
55 "description": "A single meme asset (still image, animated image, or short video clip) in a user's library.",
66 "key": "tid",
77 "record": {
88 "properties": {
99 "alt": {
1010 "description": "Accessibility alt text. Required, same convention as app.bsky.embed.images.",
1111 "maxGraphemes": 1000,
1212 "maxLength": 2000,
1313 "type": "string"
1414 },
1515 "createdAt": {
1616 "format": "datetime",
1717 "type": "string"
1818 },
1919 "duration": {
2020 "description": "Video memes only: clip length in milliseconds, read client-side at upload time. Omitted when the browser couldn't decode metadata for the picked file.",
2121 "minimum": 1,
2222 "type": "integer"
2323 },
2424 "height": {
2525 "minimum": 1,
2626 "type": "integer"
2727 },
2828 "image": {
2929 "accept": [
3030 "image/png",
3131 "image/jpeg",
3232 "image/webp",
3333 "image/gif"
3434 ],
35 "description": "The asset, when this meme is an image. Exactly one of image/video is set -- a constraint Lexicon can't express, so it's enforced client-side. Neither is required here so that adding video didn't have to break records written before it existed.",
36 "maxSize": 8000000,
35 "description": "The asset, when this meme is an image. Exactly one of image/video is set -- a constraint Lexicon can't express, so it's enforced client-side. Neither is required here so that adding video didn't have to break records written before it existed. maxSize matches the atproto PDS default blob upload cap (5 MiB) rather than exceeding it: a larger ceiling here would only describe memes that are schema-valid and impossible to store, since the PDS refuses the blob with a 413 long before the record is ever written.",
36 "maxSize": 5242880,
3737 "type": "blob"
3838 },
3939 "isAnimated": {
4040 "description": "Image memes only: set client-side from frame-count inspection at upload time, since it isn't reliably inferable from mimetype alone. Not written for video, where it would be trivially true.",
4141 "type": "boolean"
4242 },
43 "postVideo": {
44 "accept": [
45 "video/mp4"
46 ],
47 "description": "Animated images only: an mp4 rendition of `image`, so posting an animated GIF doesn't lose its animation. Bluesky serves post image embeds through a CDN that re-encodes to JPEG, flattening any animation, so an animated image is posted as app.bsky.embed.video with presentation=gif instead -- and that embed only plays blobs Bluesky's own video service produced. Transcoded once at save time, like `video`. Not the asset: `image` remains what the library displays and what this meme fundamentally is.",
48 "maxSize": 100000000,
49 "type": "blob"
50 },
4351 "source": {
4452 "ref": "#source",
4553 "type": "ref"
4654 },
4755 "tags": {
4856 "items": {
4957 "maxLength": 64,
5058 "type": "string"
5159 },
5260 "maxLength": 25,
5361 "type": "array"
5462 },
5563 "title": {
5664 "description": "Short human label for the meme, distinct from alt text (e.g. \"distracted boyfriend\").",
5765 "maxGraphemes": 100,
5866 "maxLength": 300,
5967 "type": "string"
6068 },
6169 "video": {
6270 "accept": [
6371 "video/mp4"
6472 ],
6573 "description": "The asset, when this meme is a video clip. Always mp4 regardless of what the user picked: the blob is the one Bluesky's video service transcodes and writes back to the PDS, and app.bsky.embed.video accepts nothing else.",
6674 "maxSize": 100000000,
6775 "type": "blob"
6876 },
6977 "visibility": {
7078 "default": "public",
7179 "description": "Soft signal only, not access control -- see docs/data-model.md.",
7280 "knownValues": [
7381 "public",
7482 "unlisted"
7583 ],
7684 "maxLength": 64,
7785 "type": "string"
7886 },
7987 "width": {
8088 "minimum": 1,
8189 "type": "integer"
8290 }
8391 },
8492 "required": [
8593 "alt",
8694 "createdAt"
8795 ],
8896 "type": "object"
8997 },
9098 "type": "record"
9199 },
92100 "source": {
93101 "description": "Provenance/attribution for a meme, if known.",
94102 "properties": {
95103 "importedFrom": {
96104 "description": "If copied in from another ATProto app's or user's collection, the original record's at-uri.",
97105 "format": "at-uri",
98106 "type": "string"
99107 },
100108 "note": {
101109 "description": "Free-text credit, e.g. \"via @someone.bsky.social\".",
102110 "maxLength": 500,
103111 "type": "string"
104112 },
105113 "url": {
106114 "description": "A webpage the image came from, if relevant.",
107115 "format": "uri",
108116 "type": "string"
109117 }
110118 },
111119 "type": "object"
112120 }
113121 },
114122 "id": "at.meme-museum.meme",
115123 "lexicon": 1
116124}

Compare other versions