; Phase 4 — blob backend: store the ref, never the bytes. Bytes live in a ; separate content-addressed store (mock here). (persist-test "blob-ref carries cid" (persist/blob-cid (persist/blob-ref "c1" 10 "image/png")) "c1") (persist-test "blob-ref carries size" (persist/blob-size (persist/blob-ref "c1" 10 "image/png")) 10) (persist-test "blob-ref carries mime" (persist/blob-mime (persist/blob-ref "c1" 10 "image/png")) "image/png") (persist-test "blob-ref? true for a ref" (persist/blob-ref? (persist/blob-ref "c1" 1 "x")) true) (persist-test "blob-ref? false for a plain dict" (persist/blob-ref? {:n 1}) false) (persist-test "store returns a ref, not the bytes" (let ((blob (persist/mock-blob (persist/mem-backend)))) (persist/blob-ref? (persist/blob-store blob "PNGDATA" "image/png"))) true) (persist-test "store records the byte length as size" (let ((blob (persist/mock-blob (persist/mem-backend)))) (persist/blob-size (persist/blob-store blob "12345" "text/plain"))) 5) (persist-test "fetch round-trips the bytes via the ref" (let ((blob (persist/mock-blob (persist/mem-backend)))) (let ((ref (persist/blob-store blob "PAYLOAD" "text/plain"))) (persist/blob-fetch blob ref))) "PAYLOAD") (persist-test "exists? true after store" (let ((blob (persist/mock-blob (persist/mem-backend)))) (let ((ref (persist/blob-store blob "X" "text/plain"))) (persist/blob-exists? blob ref))) true) (persist-test "content addressing: same bytes dedupe to same cid" (let ((blob (persist/mock-blob (persist/mem-backend)))) (equal? (persist/blob-cid (persist/blob-store blob "SAME" "text/plain")) (persist/blob-cid (persist/blob-store blob "SAME" "text/plain")))) true) (persist-test "different bytes get different cids" (let ((blob (persist/mock-blob (persist/mem-backend)))) (equal? (persist/blob-cid (persist/blob-store blob "A" "text/plain")) (persist/blob-cid (persist/blob-store blob "B" "text/plain")))) false) ; ---------- the invariant: persist holds the ref, never the bytes ---------- (persist-test "a blob ref stored in kv is a ref" (let ((db (persist/mock-durable (persist/mem-backend))) (blob (persist/mock-blob (persist/mem-backend)))) (begin (persist/kv-put db "avatar" (persist/blob-store blob "BIGIMAGE" "image/png")) (persist/blob-ref? (persist/kv-get db "avatar")))) true) (persist-test "the kv value does not contain the bytes" (let ((db (persist/mock-durable (persist/mem-backend))) (blob (persist/mock-blob (persist/mem-backend)))) (begin (persist/kv-put db "avatar" (persist/blob-store blob "BIGIMAGE" "image/png")) (has-key? (persist/kv-get db "avatar") :bytes))) false) (persist-test "a blob ref stored in the log is a ref, bytes fetched separately" (let ((db (persist/mock-durable (persist/mem-backend))) (store (persist/mem-backend))) (let ((blob (persist/mock-blob store))) (begin (persist/append db "uploads" "added" 0 (persist/blob-store blob "FILEBYTES" "application/pdf")) (let ((ref (persist/event-data (first (persist/read db "uploads"))))) (list (persist/blob-ref? ref) (persist/blob-fetch blob ref)))))) (list true "FILEBYTES"))