. Uses key reconciliation for efficient updates.")
+ |list-> $ %{} :CodeEntry (:doc "|Render keyed children inside a `
`.\n\nPass an optional props map and a keyed children collection of `[key child]` pairs so diffing can reconcile inserts, removals, and reordering by key.")
:code $ quote
defn list-> (props children) (create-list-element :div props children)
:examples $ []
@@ -1244,13 +1243,13 @@
; assert "|2nd argument should be a component" $ component? element
let
deliver-event $ build-deliver-event *global-element *dispatch-fn
- *changes $ atom ([])
- collect! $ fn (op) (swap! *changes conj op)
+ changes $ &buf-list:new
+ collect! $ fn (op) (&buf-list:push changes op)
; println "|mount app"
activate-instance! element target deliver-event
collect-mounting collect! ([]) ([]) element true
- patch-instance! @*changes target deliver-event
reset! *global-element element
+ patch-instance! (&buf-list:to-list changes) target deliver-event
:examples $ []
quote $ mount-app! mount-target (comp-app) *dispatch-fn
:schema $ :: :fn
@@ -1290,29 +1289,29 @@
:schema $ :: :fn
{} (:rest :dynamic) (:return 'respo.schema/Element)
:args $ [] (:: :optional 'respo.schema/DomProps)
- |realize-ssr! $ %{} :CodeEntry (:doc |)
+ |realize-ssr! $ %{} :CodeEntry (:doc "|Adopt server-rendered DOM before the first client render.\n\nIt compares the incoming component tree to the existing HTML, mounts effects, registers listeners, and records a muted virtual tree in `*global-element` so later `render!` calls can patch instead of remounting.")
:code $ quote
defn realize-ssr! (target element dispatch!)
assert (instance? element-type target) "|1st argument should be an element"
assert (component? element) "|2nd argument should be a component"
let
app-element $ .-firstElementChild target
- *changes $ atom ([])
+ changes $ &buf-list:new
collect! $ fn (op coord n-coord v)
- swap! *changes conj $ [] op coord n-coord v
+ &buf-list:push changes $ [] op coord n-coord v
deliver-event $ build-deliver-event *global-element dispatch!
if (nil? app-element) (raise "|Detected no element from SSR!")
compare-to-dom! (purify-element element) app-element
collect-mounting collect! ([]) ([]) element true
- patch-instance! @*changes target deliver-event
reset! *global-element $ mute-element element
+ patch-instance! (&buf-list:to-list changes) target deliver-event
:examples $ []
:schema $ :: :fn
{} (:return :unit)
:args $ [] :dynamic 'respo.schema/Component
:: :fn $ {} (:return :unit)
:args $ [] :tuple
- |render! $ %{} :CodeEntry (:doc "|sync virtual DOM to real DOM. newly creating for the first time, and diff/patch for reset of calls:\n\ntakes arguments:\n- `target`, the mount point,\n- `markup` which is the virtual DOM,\n- `dispatch!` the dispatcher function for handling actions.")
+ |render! $ %{} :CodeEntry (:doc "|Synchronize a component tree to a mount target.\n\nThe first call mounts the app. Later calls diff against `*global-element` and patch the existing DOM. `dispatch!` is stored internally and used by generated event listeners to deliver action tuples.")
:code $ quote
defn render! (target markup dispatch!) (reset! *dispatch-fn dispatch!)
if (some? @*global-element) (rerender-app! target markup *dispatch-fn) (mount-app! target markup *dispatch-fn)
@@ -1328,14 +1327,15 @@
defn rerender-app! (target element *dispatch-fn)
let
deliver-event $ build-deliver-event *global-element *dispatch-fn
- *changes $ atom ([])
- collect! $ fn (op) (swap! *changes conj op)
+ changes $ &buf-list:new
+ collect! $ fn (op) (&buf-list:push changes op)
; println @*global-element
find-element-diffs collect! ([]) ([]) @*global-element element
- if-let (logger @*changes-logger) (logger @*global-element element @*changes)
+ if-let (logger @*changes-logger)
+ logger @*global-element element $ &buf-list:to-list changes
; js/console.log |Changes: @*changes
- patch-instance! @*changes target deliver-event
reset! *global-element element
+ patch-instance! (&buf-list:to-list changes) target deliver-event
:examples $ []
quote $ rerender-app! mount-target (comp-demo) *dispatch-fn
:schema $ :: :fn
@@ -1776,7 +1776,7 @@
:schema $ :: :fn
{} (:return :unit)
:args $ [] :fn :list :list :number :list :list
- |find-element-diffs $ %{} :CodeEntry (:doc "|Core algorithm to find differences between old and new virtual DOM trees. `collect!` is a callback for effects.")
+ |find-element-diffs $ %{} :CodeEntry (:doc "|Internal diff algorithm for comparing old and new virtual DOM trees.\n\nIt collects patch operations via `collect!`, handling components, plain elements, styles, events, keyed children, and effect lifecycle transitions.")
:code $ quote
defn find-element-diffs (collect! coord n-coord old-tree new-tree) (; js/console.log "|element diffing:" n-coord old-tree new-tree) (; echo "|element coord" coord)
cond
@@ -1791,7 +1791,7 @@
find-element-diffs collect! next-coord n-coord (:tree old-tree) (:tree new-tree)
collect-updating collect! :update coord n-coord old-tree new-tree
do (collect-unmounting collect! coord n-coord old-tree true)
- find-element-diffs collect! next-coord n-coord (:tree old-tree) (:tree new-tree)
+ collect! $ :: :replace-element coord n-coord new-tree
collect-mounting collect! coord n-coord new-tree true
(and (component? old-tree) (element? new-tree))
do
@@ -1983,8 +1983,7 @@
event-name $ first entry
name-in-string $ event->prop event-name
aset element name-in-string $ fn (event)
- listener-builder event-name
- , event coord
+ (listener-builder event-name) event coord
.!stopPropagation event
each child-elements $ fn (child-element)
if (some? child-element) (.!appendChild element child-element)
@@ -2185,7 +2184,7 @@
{}
:args $ [] (:: :optional :string)
:return $ :: :optional :string
- |make-string $ %{} :CodeEntry (:doc |)
+ |make-string $ %{} :CodeEntry (:doc "|Render a component tree to an HTML string for SSR.\n\nIt strips live event handlers and serializes a purified tree so the output stays stable across environments. This is the current HTML output API that replaces older `make-html` references.")
:code $ quote
defn make-string (element)
element->string $ purify-element (mute-element element)
@@ -2252,8 +2251,7 @@
&let
event-prop $ event->prop event-name
aset target event-prop $ fn (event)
- listener-builder event-name
- , event coord
+ (listener-builder event-name) event coord
.!stopPropagation event
:examples $ []
:schema $ :: :fn
@@ -2295,7 +2293,7 @@
:schema $ :: :fn
{} (:return :unit)
:args $ [] :dynamic :dynamic :fn :list
- |apply-dom-changes $ %{} :CodeEntry (:doc |)
+ |apply-dom-changes $ %{} :CodeEntry (:doc "|Internal DOM patch executor.\n\nIt walks collected diff operations, finds the target node by DOM coordinate, and applies prop, style, event, element, and effect changes in order.")
:code $ quote
defn apply-dom-changes (changes mount-point listener-builder)
let
@@ -2305,7 +2303,7 @@
n-coord $ nth op 2
target $ find-target root n-coord
match op
- :replace-prop _coord _n-coord op-data
+ (:replace-prop _coord _n-coord op-data)
replace-prop target (nth op-data 0) (nth op-data 1)
(:add-prop _coord _n-coord op-data)
add-prop target (nth op-data 0) (nth op-data 1)
@@ -2493,10 +2491,14 @@
:on-keydown $ :: :optional 'respo.schema/EventHandler
:on-keyup $ :: :optional 'respo.schema/EventHandler
:on-change $ :: :optional 'respo.schema/EventHandler
+ :on-mousedown $ :: :optional 'respo.schema/EventHandler
+ :on-mouseup $ :: :optional 'respo.schema/EventHandler
:innerHTML $ :: :optional :string
:rel $ :: :optional :string
:defer $ :: :optional :bool
:on $ :: :optional :map
+ :alt $ :: :optional :string
+ :draggable $ :: :optional :bool
:examples $ []
|Effect $ %{} :CodeEntry (:doc |) (:schema :dynamic)
:code $ quote
@@ -2968,7 +2970,7 @@
:schema $ :: :fn
{} (:return :map)
:args $ [] :dynamic
- |mute-element $ %{} :CodeEntry (:doc |)
+ |mute-element $ %{} :CodeEntry (:doc "|Recursively remove event handlers from a component or element tree.\n\nThis is used in SSR-related flows where the initial HTML should not carry live client event functions.")
:code $ quote
defn mute-element (element)
if (component? element) (update element :tree mute-element)
@@ -2992,7 +2994,7 @@
:schema $ :: :fn
{} (:return :string)
:args $ [] :string
- |purify-element $ %{} :CodeEntry (:doc |)
+ |purify-element $ %{} :CodeEntry (:doc "|Recursively normalize a component or element tree into serializable data.\n\nEvent handlers are purified, component wrappers are unwrapped to their rendered tree, and children are processed recursively. This is useful before HTML serialization or DOM comparison.")
:code $ quote
defn purify-element (markup)
cond
diff --git a/deps.cirru b/deps.cirru
index 5684562..dd5e7dc 100644
--- a/deps.cirru
+++ b/deps.cirru
@@ -1,4 +1,4 @@
-{} (:calcit-version |0.12.24)
+{} (:calcit-version |0.12.35)
:dependencies $ {} (|calcit-lang/calcit-test |0.0.6)
|calcit-lang/memof |0.0.23
diff --git a/docs/Respo-Agent.md b/docs/Respo-Agent.md
index ebbc8a5..cdfd27d 100644
--- a/docs/Respo-Agent.md
+++ b/docs/Respo-Agent.md
@@ -118,16 +118,16 @@ cr tree show respo.app.updater/updater -p "" -d 1 # View root level
# Step 3: Dive deeper into specific indices
cr tree show respo.app.updater/updater -p "2" -d 1 # Check 3rd element
-cr tree show respo.app.updater/updater -p "2,1" -d 1 # Check 2nd child of 3rd element
+cr tree show respo.app.updater/updater -p "2.1" -d 1 # Check 2nd child of 3rd element
# Step 4: Confirm target location before editing
-cr tree show respo.app.updater/updater -p "2,1,0" # Final confirmation
+cr tree show respo.app.updater/updater -p "2.1.0" # Final confirmation
# Step 5: Use tree commands for surgical modifications
# JSON inline (recommended)
-cr tree replace respo.app.updater/updater -p "2,1,0" -j '"new-value"'
+cr tree replace respo.app.updater/updater -p "2.1.0" -j '"new-value"'
# Or from stdin
-echo '"new-value"' | cr tree replace respo.app.updater/updater -p "2,1,0" -s -J
+echo '"new-value"' | cr tree replace respo.app.updater/updater -p "2.1.0" -s -J
```
echo '["defn", "hello", [], ["println", "|Hello"]]' | cr edit def respo.app.core/hello -s -J
@@ -185,12 +185,12 @@ cr cirru parse -O 'defn f (x) (+ x 1)'
```bash
# Get project configuration (init-fn, reload-fn, version)
-cr query config
+cr config show
# Set project configuration
-cr edit config version "0.16.22"
-cr edit config init-fn "respo.main/main!"
-cr edit config reload-fn "respo.main/reload!"
+cr config version "0.16.22"
+cr config init-fn "respo.main/main!"
+cr config reload-fn "respo.main/reload!"
```
### 5. Workflow: Building From Scratch
@@ -347,16 +347,16 @@ cr query def namespace/function-name
cr tree show namespace/function-name -p "" -d 1
# 3. Navigate to target position
-cr tree show namespace/function-name -p "2,1" -d 1
+cr tree show namespace/function-name -p "2.1" -d 1
# 4. Make the change (JSON inline recommended)
-cr tree replace namespace/function-name -p "2,1,0" -j '["new", "code"]'
+cr tree replace namespace/function-name -p "2.1.0" -j '["new", "code"]'
# Or from stdin (JSON format)
-echo '["new", "code"]' | cr tree replace namespace/function-name -p "2,1,0" -s -J
+echo '["new", "code"]' | cr tree replace namespace/function-name -p "2.1.0" -s -J
# 5. Verify
-cr tree show namespace/function-name -p "2,1"
+cr tree show namespace/function-name -p "2.1"
```
### Step 3: Test and Validate
@@ -886,22 +886,22 @@ defn reload! ()
```bash
cr tree show namespace-name/def-name -p "" -d 2 # Overview
cr tree show namespace-name/def-name -p "2" -d 2 # Check section
- cr tree show namespace-name/def-name -p "2,1" -d 2 # Precise location
+ cr tree show namespace-name/def-name -p "2.1" -d 2 # Precise location
```
3. **Make surgical change**
```bash
# JSON inline (recommended)
-cr tree replace namespace-name/def-name -p "2,1,0" -j '"new-value"'
+cr tree replace namespace-name/def-name -p "2.1.0" -j '"new-value"'
# Or from stdin (JSON format)
-echo '"new-value"' | cr tree replace namespace-name/def-name -p "2,1,0" -s -J
+echo '"new-value"' | cr tree replace namespace-name/def-name -p "2.1.0" -s -J
```
4. **Verify immediately**
```bash
- cr tree show namespace-name/def-name -p "2,1" # Confirm change
+ cr tree show namespace-name/def-name -p "2.1" # Confirm change
cr --check-only # Verify syntax
```
@@ -909,22 +909,22 @@ echo '"new-value"' | cr tree replace namespace-name/def-name -p "2,1,0" -s -J
```bash
# Replace a value (JSON inline)
-cr tree replace ns/def -p "2,1,0" -j '"new-value"'
+cr tree replace ns/def -p "2.1.0" -j '"new-value"'
# Insert before a position (JSON)
-cr tree insert-before ns/def -p "2,1" -j '["new", "element"]'
+cr tree insert-before ns/def -p "2.1" -j '["new", "element"]'
# Insert after a position (JSON)
-cr tree insert-after ns/def -p "2,1" -j '["new", "element"]'
+cr tree insert-after ns/def -p "2.1" -j '["new", "element"]'
# Delete a node
-cr tree delete ns/def -p "2,1,0"
+cr tree delete ns/def -p "2.1.0"
# Insert as child (first child)
-cr tree insert-child ns/def -p "2,1" -j '"child-value"'
+cr tree insert-child ns/def -p "2.1" -j '"child-value"'
# Append as child (last child, from stdin)
-echo '"child-value"' | cr tree append-child ns/def -p "2,1" -s -J
+echo '"child-value"' | cr tree append-child ns/def -p "2.1" -s -J
```
---
@@ -1020,9 +1020,9 @@ cr query defs respo.app.updater # Quick list
cr query def respo.app.updater/updater # Full JSON AST
# Use -d flag to limit JSON depth
-cr tree show ns/def -p "2,1" -d 1 # Shallow
-cr tree show ns/def -p "2,1" -d 3 # Medium
-cr tree show ns/def -p "2,1" # Full (default)
+cr tree show ns/def -p "2.1" -d 1 # Shallow
+cr tree show ns/def -p "2.1" -d 3 # Medium
+cr tree show ns/def -p "2.1" # Full (default)
# Search before diving deep
cr query find my-function # Find location first
@@ -1059,12 +1059,12 @@ cr query usages respo.core/render! # Find usages
# Navigation (precise editing)
cr tree show ns/def -p "" -d 1 # View structure
-cr tree show ns/def -p "2,1" -d 1 # Drill down
-cr tree show ns/def -p "2,1,0" # Confirm target
+cr tree show ns/def -p "2.1" -d 1 # Drill down
+cr tree show ns/def -p "2.1.0" # Confirm target
# Modification (careful!)
cr edit def ns/def -j '["defn", "func", [], "body"]'
-cr tree replace ns/def -p "2,1,0" -j '"value"'
+cr tree replace ns/def -p "2.1.0" -j '"value"'
cr edit rm-def ns/def
# Validation
@@ -1079,12 +1079,12 @@ When referring to files from within `docs/`:
- `./` - same directory
- `../` - parent (docs/ to root)
-- `../../` - grandparent (docs/apis/ to root)
+- `../../` - grandparent (for example from `docs/guide/` back to project root)
-Example from `docs/apis/defcomp.md`:
+Example from `docs/guide/server-rendering.md`:
```markdown
-- [Back to README](../../README.md)
-- [API Overview](../api.md)
-- [Another API](./render!.md)
+- [← Back to README](../../README.md)
+- [Beginner Guide](../beginner-guide.md)
+- [API Reference](../api.md)
```
diff --git a/docs/api.md b/docs/api.md
index c9518aa..64fc8ea 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -25,42 +25,51 @@ entry_for:
- [Guide Topics](guide/)
- [CLI Tools Reference](../Agents.md)
+Detailed API descriptions now live in source doc strings inside `compact.cirru`.
+Use Calcit CLI to inspect them:
+
+```bash
+cr query def respo.core/defcomp
+cr query def respo.core/render!
+cr query def respo.render.html/make-string
+```
+
+`cr query examples
` is also useful when an API has runnable examples.
+
### User APIs
-| Namespace | Function |
-| -------------------- | ------------------------------------------ |
-| `respo.core` | [`defcomp`](apis/defcomp.md) |
-| | [`div`](apis/div.md) |
-| | [`<>`](apis/expand-tag.md) |
-| | [`defeffect`](apis/defeffect.md) |
-| | [`create-element`](apis/create-element.md) |
-| | [`render!`](apis/render_.md) |
-| | [`clear-cache!`](apis/clear-cache_.md) |
-| | [`realize-ssr!`](apis/realize-ssr_.md) |
-| | [`list->`](apis/list-_.md) |
-| | [`>>`](apis/pick-states.md) |
-| `respo.comp.space` | [`comp-space` or `=<`](apis/comp-space.md) |
-| `respo.comp.inspect` | [`comp-inspect`](apis/comp-inspect.md) |
-| `respo.render.html` | [`make-string`](apis/make-string.md) |
+| Namespace | Function |
+| -------------------- | ----------------- |
+| `respo.core` | `defcomp` |
+| | `div` |
+| | `<>` |
+| | `defeffect` |
+| | `create-element` |
+| | `render!` |
+| | `clear-cache!` |
+| | `realize-ssr!` |
+| | `list->` |
+| | `>>` |
+| `respo.comp.space` | `comp-space` `=<` |
+| `respo.comp.inspect` | `comp-inspect` |
+| `respo.render.html` | `make-string` |
### Lower level APIs
-Normally you don't need low level APIs, and the basic APIs are enough for building a apps.
+Normally you do not need these lower level APIs for everyday component work, but they are useful for understanding the rendering pipeline.
-I documented the APIs that can be useful.
-It's possible to discover new features we have't noticed yet.
+| Namespace | Function |
+| ------------------------- | -------------------- |
+| `respo.util.format` | `purify-element` |
+| | `mute-element` |
+| `respo.util.list` | `map-val` |
+| | `map-with-idx` |
+| `respo.render.diff` | `find-element-diffs` |
+| `respo.render.patch` | `apply-dom-changes` |
+| `respo.controller.client` | `activate-instance!` |
+| | `patch-instance!` |
-| Namespace | Function |
-| ------------------------- | -------------------------------------------------- |
-| `respo.render.expand` | [`render-app`](apis/render-app.md) |
-| `respo.util.format` | [`purify-element`](apis/purify-element.md) |
-| | [`mute-element`](apis/mute-element.md) |
-| `respo.util.list` | [`map-val`](#map-val) |
-| | [`map-with-idx`](#map-with-idx) |
-| `respo.render.diff` | [`find-element-diffs`](apis/find-element-diffs.md) |
-| `respo.render.patch` | [`apply-dom-changes`](apis/apply-dom-changes.md) |
-| `respo.controller.client` | [`activate-instance!`](apis/activate-instance.md) |
-| | [`patch-instance!`](apis/patch-instance.md) |
+Legacy standalone API pages were merged into source doc strings. Older names such as `make-html` and `render-app` are no longer separate API pages.
### APIs
diff --git a/docs/apis/activate-instance.md b/docs/apis/activate-instance.md
deleted file mode 100644
index b534c20..0000000
--- a/docs/apis/activate-instance.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-title: "activate-instance"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/activate-instance"
-entry_for:
- - "initialize app"
- - "mount app"
----
-
-## `activate-instance`
-
-Function for initializing app:
-
-- setup event listeners the mount point element
-- render and mount element
diff --git a/docs/apis/apply-dom-changes.md b/docs/apis/apply-dom-changes.md
deleted file mode 100644
index 5022200..0000000
--- a/docs/apis/apply-dom-changes.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: "apply-dom-changes"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/apply-dom-changes"
-entry_for:
- - "patch real dom"
----
-
-## `apply-dom-changes`
-
-Apply patches on the real DOM.
diff --git a/docs/apis/clear-cache!.md b/docs/apis/clear-cache!.md
deleted file mode 100644
index 0e975e9..0000000
--- a/docs/apis/clear-cache!.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "clear-cache!"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/clear-cache!"
- - "clear cache"
-entry_for:
- - "hot reload"
- - "clear render cache"
----
-
-## `clear-cache!`
-
-**📚 Documentation Index**
-
-- [← Back to README](../../README.md)
-- [🤖 Respo-Agent Guide](../Respo-Agent.md) - Hot reload debugging
-- [API Overview](../api.md)
-- [Beginner Guide](../beginner-guide.md)
-- [Related APIs](../api.md): [`render!`](render!.md) | [Hot Swapping](../guide/hot-swapping.md)
-
-```cirru
-clear-cache!
-```
-
-Respo has two copies of caches inside for the purpose of:
-
-1. DOM diffing
-2. speed up rendering
-
-The first one is easy to understand since virtual DOM is corresponding to the DOM we currently see in the page. That's why it's cached.
-
-The second one is for rendering, maybe I should explain it in `shouldComponentUpdate`-like process. Most times this virtual DOM is same with the previous one for diffing. But during hot code swapping, it's not. DOM state is updated, however, caches should be removed. That's why there's a second one.
-
-`clear-cache!` is to clear the second cache, during hot swapping.
diff --git a/docs/apis/comp-inspect.md b/docs/apis/comp-inspect.md
deleted file mode 100644
index 91096aa..0000000
--- a/docs/apis/comp-inspect.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "comp-inspect"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.comp/comp-inspect"
-entry_for:
- - "inspect component"
- - "debug value"
----
-
-## `comp-inspect`
-
-This component is similiar to `comp-text`, it shows data in string with styles.
-The difference is, `x` can be any type (formatted with `pr-str`):
-
-```cirru
-comp-inspect "|a tip" x
- {}
- :color "|red"
-```
-
-This component also comes with special styles to show it in an absolute position.
-When clicked, it will print data with `(to-js-data x)`.
-
-Disable component in production:
-
-```cirru
-comment (comp-inspect x nil)
-```
diff --git a/docs/apis/comp-space.md b/docs/apis/comp-space.md
deleted file mode 100644
index d3fc083..0000000
--- a/docs/apis/comp-space.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: "comp-space"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.comp/comp-space"
-entry_for:
- - "spacing component"
- - "horizontal space"
----
-
-## `comp-space`
-
-This is the component to add spaces.
-It decouples whitespaces from margins of elements, so I consider it a good practice.
-
-```cirru
-; "for horizontal space"
-comp-space 8 nil
-
-; "for vertical space"
-comp-space nil 8
-```
-
-Make sure that one of them left `nil` so the component may fill it.
-
-It's also okay to use strings:
-
-```cirru
-; for vertical space
-comp-space nil "|8px"
-```
-
-The bad aspect is every `` actually costs.
-And margin is still an alternative solution.
-
-> Notice, margin is more performant than an extra element.
-> Make you choice when you feel your app is slower.
diff --git a/docs/apis/create-element.md b/docs/apis/create-element.md
deleted file mode 100644
index 3b55eb0..0000000
--- a/docs/apis/create-element.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "create-element"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/create-element"
-entry_for:
- - "virtual dom element"
- - "create vnode"
----
-
-## `create-element`
-
-**📚 Documentation Index**
-
-- [← Back to README](../../README.md)
-- [🤖 Respo-Agent Guide](../Respo-Agent.md) - DOM patterns
-- [API Overview](../api.md)
-- [Beginner Guide](../beginner-guide.md)
-- [Related APIs](../api.md): [`div`](div.md) | [DOM Elements](../guide/dom-elements.md) | [DOM Properties](../guide/dom-properties.md)
-
-Function to create virtual element. Pass to it a name, a HashMap, and some children:
-
-```cirru
-defmacro a (props & children)
- create-element :a ~props ~@children
-```
-
-`children` is normally a list. But in some cases we need dynamic children element, then it can be a HashMap.
diff --git a/docs/apis/defcomp.md b/docs/apis/defcomp.md
deleted file mode 100644
index 9223836..0000000
--- a/docs/apis/defcomp.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "defcomp"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "defcomp"
- - "respo.core/defcomp"
- - "defcomp macro"
- - "component definition"
- - "component component"
-entry_for:
- - "defcomp"
- - "define component"
- - "component macro"
- - "props component"
----
-
-## `defcomp`
-
-## Define a component
-
-Use `defcomp` to declare a reusable component that receives props and renders virtual DOM.
-
-**📚 Documentation Index**
-
-- [← Back to README](../../README.md)
-- [🤖 Respo-Agent Guide](../Respo-Agent.md) - Component patterns & debugging
-- [API Overview](../api.md)
-- [Beginner Guide](../beginner-guide.md)
-- [Related APIs](../api.md): [`div`](div.md) | [`defeffect`](defeffect.md) | [`create-element`](create-element.md)
-
-```cirru
-defcomp comp-demo (content)
- div
- {}
- :class-name "|demo-container"
- :style $ {}
- :color :red
- <> content
-```
-
-`defcomp` is a Macro(https://github.com/Respo/respo.calcit/blob/master/compact.cirru#L1295) transforming code to another function with effects extracted.
diff --git a/docs/apis/defeffect.md b/docs/apis/defeffect.md
deleted file mode 100644
index 33bc815..0000000
--- a/docs/apis/defeffect.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-title: "defeffect"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/defeffect"
-entry_for:
- - "define effect"
- - "effect hook"
----
-
-## `defeffect`
-
-**📚 Documentation Index**
-
-- [← Back to README](../../README.md)
-- [🤖 Respo-Agent Guide](../Respo-Agent.md) - Effect patterns & debugging
-- [API Overview](../api.md)
-- [Beginner Guide](../beginner-guide.md)
-- [Related APIs](../api.md): [`defcomp`](defcomp.md) | [Component States](../guide/component-states.md) | [Hot Swapping](../guide/hot-swapping.md)
-
-Add effects:
-
-```cirru
-defeffect effect-a (a b) (action el at-place?)
- case-default action
- do
- :mount (println "|mounted")
- :before-update (println "|before update")
- :update (println "|updated")
- :unmount (println "|will unmount")
-
-defcomp comp-a (x y z)
- []
- effect-a a b
- div {}
- <> "|DEMO"
-```
-
-- `[] a b` are arguments. they can also be old arguments during unmounting,
-- `action` can be `:mount` `:before-update` `:update` or `:unmount`,
-- `el` refers to root element of component.
-- `at-place?` being `true` if change happen exactly from this component, rather than from parents.
-
-Notice that to add effects into component, we need to use a vector.
-So it's also possible to add multiple effects here:
-
-```cirru
-[]
- defeffect-a a b
- defeffect-b c d
- div $ {}
-```
-
-Respo is different from React. You can not dispatch action during rendering, or inside effects.
-So there will be no access to `dispatch!`, and should not have actions.
diff --git a/docs/apis/div.md b/docs/apis/div.md
deleted file mode 100644
index 978f998..0000000
--- a/docs/apis/div.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "div"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/div"
-entry_for:
- - "div element"
- - "dom macro"
----
-
-## `div`
-
-**📚 Documentation Index**
-
-- [← Back to README](../../README.md)
-- [🤖 Respo-Agent Guide](../Respo-Agent.md) - DOM element patterns
-- [API Overview](../api.md)
-- [Beginner Guide](../beginner-guide.md)
-- [Related APIs](../api.md): [`create-element`](create-element.md) | [`defcomp`](defcomp.md) | [DOM Guide](../guide/dom-elements.md)
-
-Here's how you use `div` macro to create a tree of `
`s:
-
-```cirru
-div
- {}
- :class-name "|example"
- :style $ {}
- :on $ {}
- div $ {}
- div $ {}
-```
-
-Its first argument is a HashMap consists of `:style` `:on` and other properties. For property like `el.className`, you write in `:class-name`.
-
-Find more in [DOM elements](../guide/dom-elements.md).
diff --git a/docs/apis/expand-tag.md b/docs/apis/expand-tag.md
deleted file mode 100644
index 54c5ed5..0000000
--- a/docs/apis/expand-tag.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "<>"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "expand-tag"
- - "respo.core/<>"
- - "<>"
- - "text component"
-entry_for:
- - "text macro"
- - "span shorthand"
- - "render text"
----
-
-## `<>`
-
-This macro expands
-
-```cirru
-<> text style
-```
-
-into
-
-```cirru
-span $ {}
- :inner-text text
- :style style
-```
diff --git a/docs/apis/find-element-diffs.md b/docs/apis/find-element-diffs.md
deleted file mode 100644
index ab5efc1..0000000
--- a/docs/apis/find-element-diffs.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-title: "find-element-diffs"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/find-element-diffs"
-entry_for:
- - "virtual dom diff"
----
-
-## `find-element-diffs`
-
-Find diffs of virtual DOMs.
diff --git a/docs/apis/list->.md b/docs/apis/list->.md
deleted file mode 100644
index 397295f..0000000
--- a/docs/apis/list->.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "list->"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/list->"
-entry_for:
- - "render list"
- - "keyed children"
----
-
-## `list->`
-
-A macro for rendering lists:
-
-```cirru
-list->
- {}
- :style $ {}
- [] 1 (<> "|1")
- [] 2 (<> "|2")
-```
-
-The first argument should be a keyword. The last argument should be a collection.
diff --git a/docs/apis/make-html.md b/docs/apis/make-html.md
deleted file mode 100644
index 5fd46c6..0000000
--- a/docs/apis/make-html.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "make-html"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/make-html"
-entry_for:
- - "html output"
- - "template engine"
----
-
-## `make-html`
-
-Generate HTML from virtual DOM:
-
-```cirru
-make-html (div $ {})
-; "
"
-```
-
-This feature makes Respo a simple template engine.
-``, `` and `` are supported, so it's capable of rendering the entry HTML file.
diff --git a/docs/apis/make-string.md b/docs/apis/make-string.md
deleted file mode 100644
index a67a121..0000000
--- a/docs/apis/make-string.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "make-string"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/make-string"
-entry_for:
- - "stringify html"
- - "ssr markup"
----
-
-## `make-string`
-
-Generate HTML from a virtual DOM. Stringified HTML contains a lot of markups, such as `:data-coord`:
-
-```cirru
-make-string (div $ {})
-; "
"
-```
-
-It's quite limited, so the only use case is server side rendering.
-It doesn't have to be a real web server, scripts on Node.js is also fine.
-
-And it's also called "universal rendering", or I would call it "progressive rendering".
-The rendering process started in Gulp, then in server, and last last in a browser.
-So it's **progressive**. Respo needs to make sure the HTML is identical rendered anywhere.
diff --git a/docs/apis/mute-element.md b/docs/apis/mute-element.md
deleted file mode 100644
index 79428a7..0000000
--- a/docs/apis/mute-element.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "mute-element"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/mute-element"
-entry_for:
- - "remove events"
- - "mute vnode"
----
-
-## `mute-element`
-
-This function removes events from a virtual DOM tree:
-
-```cirru
-mute-element element
-```
-
-When server side rendering is used, the first screen does not respond to events.
-That can be seen as rendered with a virtual DOM with no events.
-So `mute-element` is used to simulate such a virtual DOM tree.
diff --git a/docs/apis/patch-instance.md b/docs/apis/patch-instance.md
deleted file mode 100644
index f6d5842..0000000
--- a/docs/apis/patch-instance.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: "patch-instance"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/patch-instance"
-entry_for:
- - "update instance"
- - "patch vnode"
----
-
-## `patch-instance`
-
-Update based on virtual DOM.
diff --git a/docs/apis/pick-states.md b/docs/apis/pick-states.md
deleted file mode 100644
index 305f44c..0000000
--- a/docs/apis/pick-states.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: ">>"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "pick-states"
- - "respo.core/>>"
- - ">>"
- - "states cursor"
- - "state cursor"
- - "local state"
- - ">> states"
-entry_for:
- - "state cursor"
- - "branch states"
- - "local states"
- - "cursor path"
----
-
-## `>>`
-
-## State cursor
-
-`>>` creates a state cursor for a nested branch so a child component can manage its own local state.
-
-Creating a branch of states, as well as a new cursor:
-
-```cirru
-comp-x (>> states branch-key) p1 p2
-```
-
-Notice that the structure of `states` is a tree of data and cursor:
-
-```cirru
-{}
- :cursor $ [] :a
- :data $ {}
-
- :b $ {}
- :data $ {}
- :c $ {}
- :data $ {}
-```
-
-When `(>> states :b)` is evaluated, new piece of data is generated:
-
-```cirru
-{}
- :cursor $ [] :a :b
- :c $ {}
- :data $ {}
-```
-
-In an older version, `cursor` and `states` are two separated variables, but now combined for convenience.
diff --git a/docs/apis/purify-element.md b/docs/apis/purify-element.md
deleted file mode 100644
index 56d2158..0000000
--- a/docs/apis/purify-element.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: "purify-element"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/purify-element"
-entry_for:
- - "flatten events"
- - "serialize vnode"
----
-
-## `purify-element`
-
-This function flattens `:data-events` in the virtual DOM tree:
-
-```cirru
-purify-element element
-```
-
-Event handlers in the virtual DOM tree can not be stringified.
-`purify-element` will turn the functions into a `true`.
diff --git a/docs/apis/realize-ssr_.md b/docs/apis/realize-ssr_.md
deleted file mode 100644
index db5e8e4..0000000
--- a/docs/apis/realize-ssr_.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "realize-ssr!"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "realize-ssr_"
- - "respo.core/realize-ssr!"
-entry_for:
- - "progressive ssr"
- - "hydrate ssr"
----
-
-## `realize-ssr!`
-
-This one is complicated. I wrote [a long post before trying to explain this new feature][progressive].
-The code looks like this:
-
-[progressive]: https://medium.com/@jiyinyiyong/progressive-server-side-rendering-that-we-may-need-8980e7c4d61a
-
-```cirru
-def ssr? (some? (.!querySelector js/document "|meta.respo-ssr"))
-def mount-target (.!querySelector js/document "|.app"))
-
-if ssr?
- realize-ssr! mount-target
- comp-container @*store ssr-stages
- , dispatch!
-```
-
-The job of `realize-ssr!` function is to simulate a virtual DOM of currently rendered HTML from server, so that the followed virtual DOM rendering steps can run a little easier.
diff --git a/docs/apis/render!.md b/docs/apis/render!.md
deleted file mode 100644
index 8781377..0000000
--- a/docs/apis/render!.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "render!"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/render!"
- - "rerender app"
- - "mount app"
-entry_for:
- - "render app"
- - "mount pointer"
- - "update dom"
----
-
-## `render!`
-
-**📚 Documentation Index**
-
-- [← Back to README](../../README.md)
-- [🤖 Respo-Agent Guide](../Respo-Agent.md) - Rendering patterns & debugging
-- [API Overview](../api.md)
-- [Beginner Guide](../beginner-guide.md)
-- [Related APIs](../api.md): [`clear-cache!`](clear-cache!.md) | [`render-app`](render-app.md) | [`mount-app!`](../guide/)
-
-`render!` comes with side effects, it renders virtual to the mount pointer:
-
-```cirru
-render! target
- comp-container @global-store
- , dispatch!
-```
-
-`target` is the mount pointer. `global-states` is the reference to the atom of states.
-
-Internally there's a mutable state tracking the DOM state.
-And the state `realize-ssr!` changes is this one.
diff --git a/docs/apis/render-app.md b/docs/apis/render-app.md
deleted file mode 100644
index 149fbe0..0000000
--- a/docs/apis/render-app.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "render-app"
-scope: "module"
-kind: "reference"
-category: "reference"
-aliases:
- - "respo.core/render-app"
-entry_for:
- - "render virtual dom"
- - "cached render"
----
-
-## `render-app`
-
-This function renders virtual DOM markups into virtual DOM data:
-
-```cirru
-render-app markup states build-mutate old-element
-```
-
-`old-element` is a caches of the old virtual DOM.
-It can help speed up rendering since arguments and results are cached.
-
-Each component comes with a `render` function defined with `defcomp`.
-So those `render` functions needs to be rendered with `render-app`.
-
-it's usually used inside Respo.
diff --git a/docs/guide/dom-elements.md b/docs/guide/dom-elements.md
index 595d764..0c20a23 100644
--- a/docs/guide/dom-elements.md
+++ b/docs/guide/dom-elements.md
@@ -20,7 +20,7 @@ entry_for:
- [API Reference](../api.md)
- [All Guides](./): [Why Respo](./why-respo.md) | [Base Components](./base-components.md) | [Virtual DOM](./virtual-dom.md) | [Component States](./component-states.md)
-An element is defined with [`create-element`](../apis/create-element.md) like:
+An element is defined with `respo.core/create-element` like:
```cirru
defmacro a (props & children)
@@ -75,4 +75,4 @@ a body br button canvas code div footer
ul
```
-Some are not, but you can create them very quickly with [`create-element`](../apis/create-element.md).
+Some are not, but you can create them very quickly with `respo.core/create-element`. For details, run `cr query def respo.core/create-element`.
diff --git a/docs/guide/server-rendering.md b/docs/guide/server-rendering.md
index 7a5865a..54f6c05 100644
--- a/docs/guide/server-rendering.md
+++ b/docs/guide/server-rendering.md
@@ -51,11 +51,10 @@ And note that the HTML transferred over the network does not bind events, and we
Virtual DOM can be rendered on a server, use it like in JavaScript.
-[`make-string`](../apis/make-string.md) is the function to render HTML. [`realize-ssr!`](../apis/realize-ssr_.md) is also useful to make first screen look smoother, make sure it's called before `render!`.
+`respo.render.html/make-string` is the function to render HTML. `respo.core/realize-ssr!` is also useful to make first screen look smoother; make sure it is called before `respo.core/render!`.
-Notice that when rendering on server, events are not bound,
-internally we use [`mute-element`](../apis/mute-element.md) to remove events before rendering.
-Without [`realize-ssr!`](../apis/realize-ssr_.md), [`render!`](../apis/render_.md) function will remove existing DOM and mount the whole tree.
+Notice that when rendering on server, events are not bound, and internally Respo uses `respo.util.format/mute-element` to remove events before rendering.
+Without `respo.core/realize-ssr!`, `respo.core/render!` will remove existing DOM and mount the whole tree.
### `realize-ssr!` solution
diff --git a/package.json b/package.json
index 5533ad2..bdbc070 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"dependencies": {
- "@calcit/procs": "^0.12.24"
+ "@calcit/procs": "^0.12.35"
},
"scripts": {
"test": "cr --init-fn 'respo.test.main/main!' js && node test.mjs"
diff --git a/yarn.lock b/yarn.lock
index ae6fbc1..7b53ac4 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5,21 +5,21 @@ __metadata:
version: 8
cacheKey: 10c0
-"@calcit/procs@npm:^0.12.24":
- version: 0.12.24
- resolution: "@calcit/procs@npm:0.12.24"
+"@calcit/procs@npm:^0.12.35":
+ version: 0.12.35
+ resolution: "@calcit/procs@npm:0.12.35"
dependencies:
- "@calcit/ternary-tree": "npm:0.0.25"
+ "@calcit/ternary-tree": "npm:0.0.26"
"@cirru/parser.ts": "npm:^0.0.9"
- "@cirru/writer.ts": "npm:^0.1.7"
- checksum: 10c0/bf562bca83a2f481434764fa73dd6f0574b130595745f0804fa62b9b4d3394b0a10198a7baaa3748c78a657246923603d171179e6e4d2bbff02e11f07c97c27f
+ "@cirru/writer.ts": "npm:^0.1.9"
+ checksum: 10c0/b9d8e2926911e81e56635653c596c2b217fe260ae768a132df49dfd2e7f4ee7707882802e06be0f191a4b5e7df6c415f78abb8d8fb8fb06176611139badc2fde
languageName: node
linkType: hard
-"@calcit/ternary-tree@npm:0.0.25":
- version: 0.0.25
- resolution: "@calcit/ternary-tree@npm:0.0.25"
- checksum: 10c0/49f01d526dec87810cc45f4e92dfa9043c07ecf64e03e2fa99c8ceca09724e8ec11308118599beffd62852f8594f8944f2c8101bc7e551ae64d421d27f91202b
+"@calcit/ternary-tree@npm:0.0.26":
+ version: 0.0.26
+ resolution: "@calcit/ternary-tree@npm:0.0.26"
+ checksum: 10c0/53fee664f72e25f3512f3a61c917fe7926e2620caab1fed68e030ee4ddf905be68b4249c2e644a4db7cadb96b23594059f73fa9c475af8a79526e8d145736563
languageName: node
linkType: hard
@@ -30,10 +30,10 @@ __metadata:
languageName: node
linkType: hard
-"@cirru/writer.ts@npm:^0.1.7":
- version: 0.1.7
- resolution: "@cirru/writer.ts@npm:0.1.7"
- checksum: 10c0/3548f596abef52f8d4cfe95b25fc1ded0d059869eafb403e3e340c1bcdc50fe59af9fd75f1b6d9f828129c847965f378945ed370ff9aeec9ddcc89172afad92a
+"@cirru/writer.ts@npm:^0.1.9":
+ version: 0.1.9
+ resolution: "@cirru/writer.ts@npm:0.1.9"
+ checksum: 10c0/df2672837d1bf61ee1a83b8b77ea17b9c241cb8135323567992749ee26daf3abccf43ab75d8698d67c36c8b8469f9a66c235a809a60484d71133592a9161a054
languageName: node
linkType: hard
@@ -984,7 +984,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
- "@calcit/procs": "npm:^0.12.24"
+ "@calcit/procs": "npm:^0.12.35"
bottom-tip: "npm:^0.1.5"
vite: "npm:^8.0.3"
languageName: unknown