Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m9s
content/diff + diff-versions enumerated ids top-level only (doc-ids/ doc-find), so diffs of documents with sections missed every nested add/ remove/change. Now via doc-tree-ids + doc-deep-find; sections excluded from :changed (no own content), still reported in :added/:removed. Flat-doc diffs unchanged. +9 store tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
209 lines
6.1 KiB
Plaintext
209 lines
6.1 KiB
Plaintext
;; Phase 2 — op log + versioning over persist. The log is the source of truth;
|
|
;; any version is a replay of the op stream up to a seq.
|
|
|
|
(st-bootstrap-classes!)
|
|
(content-bootstrap-blocks!)
|
|
(content-bootstrap-doc!)
|
|
|
|
(define B (persist/open))
|
|
(define h (mk-heading "h" 1 "Title"))
|
|
(define p (mk-text "p" "Body"))
|
|
(define img (mk-image "img" "/c.png" "cat"))
|
|
|
|
;; ── commit an op stream ──
|
|
(content/commit! B "post" (op-insert h nil) 10)
|
|
(content/commit! B "post" (op-insert p "h") 11)
|
|
(content/commit! B "post" (op-insert img "h") 12)
|
|
(content/commit! B "post" (op-update "p" "text" "Edited") 13)
|
|
(content/commit! B "post" (op-delete "img") 14)
|
|
|
|
(content-test "version-count" (content/version-count B "post") 5)
|
|
(content-test "log length" (len (content/log B "post")) 5)
|
|
|
|
;; ── head: latest materialised document ──
|
|
(content-test "head ids" (doc-ids (content/head B "post")) (list "h" "p"))
|
|
(content-test
|
|
"head p edited"
|
|
(str (blk-send (doc-find (content/head B "post") "p") "text"))
|
|
"Edited")
|
|
|
|
;; ── replay to any version ──
|
|
(content-test
|
|
"at seq1"
|
|
(doc-ids (content/at B "post" 1))
|
|
(list "h"))
|
|
(content-test
|
|
"at seq2"
|
|
(doc-ids (content/at B "post" 2))
|
|
(list "h" "p"))
|
|
(content-test
|
|
"at seq3"
|
|
(doc-ids (content/at B "post" 3))
|
|
(list "h" "img" "p"))
|
|
(content-test
|
|
"at seq3 p original"
|
|
(str (blk-send (doc-find (content/at B "post" 3) "p") "text"))
|
|
"Body")
|
|
(content-test
|
|
"at seq4 p edited"
|
|
(str (blk-send (doc-find (content/at B "post" 4) "p") "text"))
|
|
"Edited")
|
|
(content-test
|
|
"at seq5 img gone"
|
|
(doc-ids (content/at B "post" 5))
|
|
(list "h" "p"))
|
|
(content-test
|
|
"at seq0 empty"
|
|
(doc-ids (content/at B "post" 0))
|
|
(list))
|
|
|
|
;; ── ops accessor ──
|
|
(content-test
|
|
"ops kinds"
|
|
(map (fn (o) (get o :op)) (content/ops B "post"))
|
|
(list "insert" "insert" "insert" "update" "delete"))
|
|
|
|
;; ── history metadata ──
|
|
(define hist (content/history B "post"))
|
|
(content-test "history length" (len hist) 5)
|
|
(content-test "history first seq" (get (first hist) :seq) 1)
|
|
(content-test "history first type" (get (first hist) :type) "insert")
|
|
(content-test "history first at" (get (first hist) :at) 10)
|
|
(content-test
|
|
"history fourth type"
|
|
(get (nth hist 3) :type)
|
|
"update")
|
|
|
|
;; ── diff between versions ──
|
|
(define dvf (content/diff-versions B "post" 1 3))
|
|
(content-test "diff added" (get dvf :added) (list "img" "p"))
|
|
(content-test "diff removed empty" (get dvf :removed) (list))
|
|
(content-test "diff changed empty" (get dvf :changed) (list))
|
|
|
|
(define dvf2 (content/diff-versions B "post" 3 5))
|
|
(content-test "diff2 removed" (get dvf2 :removed) (list "img"))
|
|
(content-test "diff2 changed" (get dvf2 :changed) (list "p"))
|
|
(content-test "diff2 added empty" (get dvf2 :added) (list))
|
|
|
|
;; ── direct diff of two materialised docs ──
|
|
(define da (content/at B "post" 2))
|
|
(define db (content/at B "post" 5))
|
|
(content-test
|
|
"direct diff changed"
|
|
(get (content/diff da db) :changed)
|
|
(list "p"))
|
|
(content-test
|
|
"direct diff no-op"
|
|
(get (content/diff da da) :changed)
|
|
(list))
|
|
|
|
;; ── commit-all batch ──
|
|
(define B2 (persist/open))
|
|
(content/commit-all!
|
|
B2
|
|
"doc2"
|
|
(list (op-insert h nil) (op-insert p "h"))
|
|
1)
|
|
(content-test "commit-all count" (content/version-count B2 "doc2") 2)
|
|
(content-test
|
|
"commit-all head"
|
|
(doc-ids (content/head B2 "doc2"))
|
|
(list "h" "p"))
|
|
|
|
;; ── stream isolation ──
|
|
(content-test
|
|
"separate stream empty"
|
|
(content/version-count B "doc2")
|
|
0)
|
|
(content-test
|
|
"head of empty stream"
|
|
(doc-ids (content/head B "never"))
|
|
(list))
|
|
|
|
;; ── op-log carries non-core block types (callout/media) through replay ──
|
|
(content-bootstrap-callout!)
|
|
(content-bootstrap-media!)
|
|
(define B3 (persist/open))
|
|
(content/commit!
|
|
B3
|
|
"rich"
|
|
(op-insert (mk-callout "co" "note" "hi") nil)
|
|
1)
|
|
(content/commit!
|
|
B3
|
|
"rich"
|
|
(op-insert (mk-media "v" "video" "/c.mp4") "co")
|
|
2)
|
|
(content/commit! B3 "rich" (op-update "co" "text" "edited") 3)
|
|
(content-test
|
|
"op-log rich ids"
|
|
(doc-ids (content/head B3 "rich"))
|
|
(list "co" "v"))
|
|
(content-test
|
|
"op-log callout type"
|
|
(blk-type (doc-find (content/head B3 "rich") "co"))
|
|
"callout")
|
|
(content-test
|
|
"op-log callout update"
|
|
(str (blk-send (doc-find (content/head B3 "rich") "co") "text"))
|
|
"edited")
|
|
(content-test
|
|
"op-log media type"
|
|
(blk-type (doc-find (content/head B3 "rich") "v"))
|
|
"media")
|
|
|
|
;; ── op-log update/delete reach NESTED blocks (tree-wide by id) ──
|
|
(content-bootstrap-section!)
|
|
(define B4 (persist/open))
|
|
(content/commit!
|
|
B4
|
|
"nest"
|
|
(op-insert (mk-section "sec" (list (mk-text "n" "orig"))) nil)
|
|
1)
|
|
(content/commit! B4 "nest" (op-update "n" "text" "edited") 2)
|
|
(content-test
|
|
"op-log nested update"
|
|
(str (blk-send (doc-deep-find (content/head B4 "nest") "n") "text"))
|
|
"edited")
|
|
(content-test
|
|
"op-log nested update tree intact"
|
|
(doc-tree-ids (content/head B4 "nest"))
|
|
(list "sec" "n"))
|
|
(content/commit! B4 "nest" (op-delete "n") 3)
|
|
(content-test
|
|
"op-log nested delete"
|
|
(doc-tree-ids (content/head B4 "nest"))
|
|
(list "sec"))
|
|
(content-test
|
|
"op-log nested delete via content/at seq2"
|
|
(doc-tree-ids (content/at B4 "nest" 2))
|
|
(list "sec" "n"))
|
|
|
|
;; ── diff is TREE-WIDE: nested-block add/change/remove are detected, and
|
|
;; section containers never appear in :changed (a top-level-only diff would miss
|
|
;; "n" entirely and instead flag the section). ──
|
|
(define dn01 (content/diff-versions B4 "nest" 0 1))
|
|
(content-test
|
|
"diff nested added (section + child)"
|
|
(get dn01 :added)
|
|
(list "sec" "n"))
|
|
(content-test "diff nested added removed empty" (get dn01 :removed) (list))
|
|
(content-test "diff nested added changed empty" (get dn01 :changed) (list))
|
|
|
|
(define dn12 (content/diff-versions B4 "nest" 1 2))
|
|
(content-test
|
|
"diff nested changed child only"
|
|
(get dn12 :changed)
|
|
(list "n"))
|
|
(content-test "diff nested changed no add" (get dn12 :added) (list))
|
|
(content-test "diff nested changed no remove" (get dn12 :removed) (list))
|
|
|
|
(define dn23 (content/diff-versions B4 "nest" 2 3))
|
|
(content-test "diff nested removed child" (get dn23 :removed) (list "n"))
|
|
(content-test "diff nested removed no change" (get dn23 :changed) (list))
|
|
|
|
(content-test
|
|
"diff nested no-op"
|
|
(get (content/diff-versions B4 "nest" 1 1) :changed)
|
|
(list))
|