Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
blob.sx: a blob ref is {:cid :size :mime}; the blob store is a separate
injected dependency (perform in prod, mock content store in tests).
persist/blob-store puts bytes and returns only the ref; bytes live in a
content-addressed store (artdag/IPFS). Tests assert refs in log/kv never carry
the bytes + content-address dedup. 105/105.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
113 lines
3.4 KiB
Plaintext
113 lines
3.4 KiB
Plaintext
; 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"))
|