Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

calcit.cirru -diff linguist-generated
yarn.lock -diff linguist-generated
Agents.md -diff linguist-generated
llms/*.md -diff linguist-generated
9 changes: 7 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
- uses: actions/setup-node@v6
with:
node-version: 24
cache: yarn

- name: Enable Corepack
run: |
corepack enable
corepack prepare yarn@4.12.0 --activate
yarn --version

- uses: calcit-lang/setup-cr@0.0.8

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ yarn-error.log
tmp/

draft/

.yarn/*.gz
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nodeLinker: node-modules
746 changes: 34 additions & 712 deletions Agents.md

Large diffs are not rendered by default.

184 changes: 109 additions & 75 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,69 +29,116 @@ In `package.cirru` and run `caps`:
DOM syntax

```cirru
div
{}
:class-name "|demo-container"
:style $ {} (:color :red)
:on-click $ fn (event dispatch!)
div $ {}
ns app.demo $ :require
respo.core :refer $ div

defn comp-demo (dispatch!)
div
{}
:class-name "|demo-container"
:style $ {} (:color :red)
:on-click $ fn (event d!)
d! :clicked
div $ {}
```

More examples adapted from `compact.cirru`:

```cirru
ns app.demo $ :require
respo.core :refer $ defcomp a <>

defcomp comp-link (href text)
a
{} $ :href href
<> text
```

```cirru
ns app.demo $ :require
respo.core :refer $ list-> div

defn comp-list ()
list-> ({})
[] $ [] :a
div $ {}
```

Text Node:

```cirru
<> content
ns app.demo $ :require
respo.core :refer $ <>

; with styles
<> content $ {}
:color :red
:font-size 14})
defn comp-text (content)
<> content

; with styles
<> content $ {}
:color :red
:font-size 14
```

Component definition:

```cirru
defcomp comp-container (content)
div
{}
:class-name |demo-container
:style $ {} (:color :red)
<> content
ns app.demo $ :require
respo.core :refer $ div <>

let
comp-container $ fn (content)
div
{}
:class-name |demo-container
:style $ {} (:color :red)
<> content
```

App initialization:

```cirru
ns app.demo $ :require
respo.core :refer $ render!

; initialize store and update store
defatom *store $ {} (:point 0)
:states $ {}
defn dispatch! (op)
reset! *store (updater @*store op)

; TODO
defn updater (store op)
tag-match op
(:TODO a b) TODO
_ (do (eprintln "|Unknown op:" op) store)

; render to the DOM
render! mount-point (comp-container @*store) dispatch!
let
*store $ atom $ {} (:point 0) (:states {})
updater $ fn (store op)
tag-match op
(:TODO a b) store
_ store
dispatch! $ fn (op)
reset! *store $ updater @*store op
mount-point nil
comp-container $ fn (state) state
dispatch! $ :: :TODO 1 2

; render to the DOM
defn render-app! ()
render! mount-point (comp-container @*store) dispatch!
```

Rerender on store changes:

```cirru
defn render-app! ()
render! mount-point (comp-container @*store) dispatch!

add-watch *store :changes $ fn ()
render-app!
let
*store $ atom $ {} (:point 0)
render-app! $ fn () nil
add-watch *store :changes $ fn ()
render-app!
```

Reset virtual DOM caching during hot code swapping, and rerender:

```cirru
defn reload! ()
ns app.demo $ :require
respo.core :refer $ clear-cache!

let
*store $ atom $ {} (:point 0)
render-app! $ fn () nil
add-watch *store :changes $ fn ()
render-app!
remove-watch *store :changes
add-watch *store :changes $ fn ()
render-app!
Expand All @@ -102,29 +149,35 @@ defn reload! ()
Adding effects to component:

```cirru
defeffect effect-a (text) (action parent-element at-place?)
println action
; action could be :mount :update :amount

when (= :mount action)
do nil

defcomp comp-a (text)
[]
effect-a text
div {}
ns app.demo $ :require
respo.core :refer $ div

let
effect-a $ fn (text)
fn (action parent-element at-place?)
println action
; action could be :mount :update :amount
when (= :mount action) nil
defn comp-a (text)
[]
effect-a text
div {}
```

Define a hooks plugin based on Calcit Record, better use a pure function:

```cirru
defn plugin-x (states options)
%::
%{} PluginX
:render $ fn (self) (nth self 1)
:show $ fn (self d! ? text)
, :plugin-name
div ({}) (<> "|Demo")
ns app.demo $ :require
respo.core :refer $ div <>

let
plugin-x $ fn (states options)
%::
%{} :PluginX
:render $ fn (self) (nth self 1)
:show $ fn (self d! ? text) nil
, :plugin-name
div {} (<> "|Demo")
```

### License
Expand Down Expand Up @@ -188,25 +241,6 @@ Core macros and functions for building applications:
| `realize-ssr!` | [docs/apis/realize-ssr\_.md](docs/apis/realize-ssr_.md) | Server-side rendering |
| `list->` | [docs/apis/list->.md](docs/apis/list->.md) | Create list containers |

### Using with Calcit CLI Tools

To explore the codebase using `cr` commands:

```bash
# List all namespaces
cr query ls-ns

# Explore core APIs
cr query read-ns respo.core
cr query peek-def respo.core defcomp
cr query read-def respo.core render!

# Search for specific functionality
cr query find-symbol render!
cr query usages respo.core render!

# Check project configuration
cr query configs
```
### Agent Workflows

For more CLI tool information, see [Agents.md](./Agents.md).
Agent-oriented CLI workflows (query/check-md automation) are maintained in [Agents.md](./Agents.md).
Loading