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
6 changes: 4 additions & 2 deletions .github/workflows/upload.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ jobs:
test ! -e package.cirru
calcit calcit.cirru edit format
git diff --exit-code -- calcit.cirru
calcit calcit.cirru --check-only
calcit calcit.cirru analyze check-public --ns app.comp.container --ns app.config --ns app.main --ns app.schema --ns app.updater --summary-only
calcit calcit.cirru --check-only --all-defs
calcit calcit.cirru --check-only --ns app.comp.container --ns app.config --ns app.main --ns app.schema --ns app.updater --summary-only --format json
calcit calcit.cirru fix --workflow strict --verify --format edn
calcit calcit.cirru test --require-match --summary-only --format json

- name: Select frontend CDN path
id: asset-path
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ js-out/
node_modules/
dist/
.yarn/*.gz
.calcit/
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ https://github.com/calcit-lang/respo-calcit-workflow

### Development and deployment

Use Calcit 0.27.0, Node.js 24, and Yarn 4.18.0. The canonical source files are
本轮验收使用配对 Calcit/procs 0.30.1-alpha.5,以及正式 Reel 0.6.39、Respo 0.16.122、
js-ffi 0.2.3,不等于正式 0.30.1 二进制验收。站点链接、存储键与部署路径不变。
自动保存从误用的 60 毫秒修正为 60 秒;存档恢复成功后才安装定时器与卸载保存监听。
损坏存档仍明确报告错误,但不会被后续自动保存覆盖;页面静态链接仍可用。
Use Node.js 24 and Yarn 4.18.0. The canonical source files are
`calcit.cirru` and `deps.cirru`; do not recreate `compact.cirru` or `package.cirru`.

```sh
caps --strict --ci
yarn install --immutable
caps verify --toolchain
calcit calcit.cirru --check-only
calcit calcit.cirru --check-only --all-defs
calcit calcit.cirru fix --workflow strict --verify --format edn
calcit calcit.cirru test --require-match --summary-only --format json
yarn build
```

Expand All @@ -36,6 +42,16 @@ in another terminal while editing Calcit, without a process-management dependenc

The browser app uses typed Reel state, one Enum per dispatch, and validates
legacy Map/new Store data when hydrating the original `map.clj.im` storage key.
空 Reel 使用公开 State 构造器与 Ref 的泛型上下文,不再对 `new-reel` 作强断言。
实际 DOM dispatch 边界检查 Enum;采用 `render-with!`、当前 ref/watch API 和 Respo DOM 查询适配。
旧 Struct 存档仅在读取边界转换为字段 Map,再验证构造成当前 Store;
保留一处实际 `&struct:to-map` 转换,不以类型断言或 Dynamic 擦除伪造身份。
移除无引用的模板 `repeat!` / `snippets`,不引入新的定时器框架。

本次本地验收未运行 Caps;开发者仍须执行上述安装步骤以生成模块链接,CI 独立 strict 解析。
两项定义附着业务测试覆盖旧 Map/Struct 存档往返、局部状态更新及 content 保留,
不新增检查脚本。浏览器用隔离合成存档验收恢复、保存重载、热更新回放及损坏存档卸载不覆盖;
临时观察页不提交。外部历史链接可达性及移动端未验收,本 PR 不授权合并或生产部署。

`VITE_BASE_URL` controls asset URLs (default `./`). CI builds against
`https://cos-sh.tiye.me/clojure-china/map.clojure-china.org/`, with
Expand Down
114 changes: 58 additions & 56 deletions calcit.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -163,55 +163,55 @@
'app.main $ %{} 'FileEntry
:defs $ {}
'*reel $ %{} 'CodeEntry (:doc |)
:code $ quote $ defatom *reel
assert-type (typed/new-reel schema/store) (:: 'reel.typed/State 'Enum 'app.schema/Store)
:code $ quote $ defref *reel
typed/State :base schema/store :store schema/store :records ([]) :pointer (Option :none) :stopped? false :display? false :merged? false
:examples $ []
:schema $ :: 'Ref $ :: 'reel.typed/State 'Enum 'app.schema/Store
'dispatch! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn dispatch! (op)
when config/dev? $ println |Dispatch: op
reset! *reel $ match (typed/decode-control op)
(:some control) (typed/apply-control updater @*reel control)
(:none)
typed/record-op updater @*reel op (generate-id!) (now-ms)
:code $ quote $ defn dispatch! (raw-op)
if (enum? raw-op)
let
op raw-op
when config/dev? $ println |Dispatch: op
reset! *reel $ match (typed/decode-control op)
(:some control) (typed/apply-control updater @*reel control)
(:none)
typed/record-op updater @*reel op (generate-id!) (now-ms)
raise |Dispatch-expected-an-Enum
, &unit
:examples $ []
:schema $ :: 'Fn $ {} (:return 'Unit)
:args $ [] 'Enum
:args $ [] 'Dynamic
:features $ #{} :js-ffi
'main! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn main! ()
println "|Running mode:" $ if config/dev? |dev |release
render-app!
add-watch *reel :changes $ fn (r p)
add-watch! *reel :changes $ fn (r p)
hint-fn $ {}
:args $ [] (:: 'reel.typed/State 'Enum 'app.schema/Store) (:: 'reel.typed/State 'Enum 'app.schema/Store)
:return 'Unit
render-app!
listen-devtools! |a dispatch!
js/window.addEventListener |beforeunload $ fn (event)
hint-fn $ {}
:args $ [] 'Dynamic
:return 'Unit
:features $ #{} :js-ffi
persist-storage!
browser/set-interval! persist-storage! 60
match
browser/storage-get $
get config/site :storage-key
, .unwrap
(:some raw)
dispatch! $ :: :hydrate-storage $ parse-cirru-edn raw
(:none) &unit
browser/add-event-listener! |beforeunload $ fn (event) (persist-storage!)
browser/set-interval! persist-storage! 60000
println "|App started."
:examples $ []
:schema $ :: 'Fn $ {} (:return 'Unit)
:args $ []
:features $ #{} :js-ffi
'mount-target $ %{} 'CodeEntry (:doc |)
:code $ quote $ def mount-target
(browser/query-selector |.app) .unwrap
option:unwrap $ dom/query-selector |.app
:examples $ []
:schema $ :: 'js-ffi.browser/DomElementHost
:schema $ :: 'respo.dom/DomElement
'persist-storage! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn persist-storage! ()
browser/storage-set!
Expand All @@ -225,8 +225,8 @@
'reload! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn reload! ()
if (js-nullish? build-errors)
do (remove-watch *reel :changes) (clear-cache!)
add-watch *reel :changes $ fn (reel prev)
do (remove-watch! *reel :changes) (clear-cache!)
add-watch! *reel :changes $ fn (reel prev)
hint-fn $ {}
:args $ [] (:: 'reel.typed/State 'Enum 'app.schema/Store) (:: 'reel.typed/State 'Enum 'app.schema/Store)
:return 'Unit
Expand All @@ -241,39 +241,17 @@
:features $ #{} :js-ffi
'render-app! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn render-app! ()
render! mount-target (comp-container @*reel) dispatch!
:examples $ []
:schema $ :: 'Fn $ {} (:return 'Unit)
:args $ []
:features $ #{} :js-ffi
'repeat! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn repeat! (duration cb)
js/setTimeout
fn ()
hint-fn $ {}
:args $ []
:return 'Unit
:features $ #{} :js-ffi
cb
repeat! (* 1000 duration) cb
* 1000 duration
, &unit
:examples $ []
:schema $ :: 'Fn $ {} (:return 'Unit)
:args $ [] 'Number $ :: 'Fn
{} (:return 'Unit)
:args $ []
:features $ #{} :js-ffi
'snippets $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn snippets () (println config/cdn?)
render-with! mount-target
fn () $ comp-container @*reel
, dispatch!
:examples $ []
:schema $ :: 'Fn $ {} (:return 'Unit)
:args $ []
:features $ #{} :js-ffi
:ns $ %{} 'NsEntry (:doc |)
:code $ quote $ ns app.main
:require
respo.core :refer $ render! clear-cache!
respo.core :refer $ render-with! clear-cache!
app.comp.container :refer $ comp-container
app.updater :refer $ updater
app.schema :as schema
Expand All @@ -284,6 +262,7 @@
app.config :as config
|./calcit.build-errors.mjs :default build-errors
|bottom-tip :default hud!
respo.ffi.browser :as dom
'app.schema $ %{} 'FileEntry
:defs $ {}
'StatesInput $ %{} 'CodeEntry (:doc |)
Expand All @@ -298,16 +277,29 @@
:content 'String
:examples $ []
:schema $ :: 'StructDef
'decode-store $ %{} 'CodeEntry (:doc |)
'decode-store $ %{} 'CodeEntry
:doc "|Restore legacy Maps or parsed Struct archives by validating named fields into the current Store constructor. The single struct-to-map conversion is an actual archive boundary, not a type assertion; unrelated legacy keys remain ignored."
:code $ quote $ defn decode-store (raw)
decode-map-as
{}
:states $ option:unwrap $ get raw :states
:content $ option:unwrap $ get raw :content
, Store
let
fields $ if (map? raw) raw $ if (struct? raw) (&struct:to-map raw) (raise |Saved-store-must-be-a-Map-or-Struct)
decode-map-as
{}
:states $ option:unwrap $ get fields :states
:content $ option:unwrap $ get fields :content
, Store
:examples $ []
:schema $ :: 'Fn $ {} (:return 'app.schema/Store)
:args $ [] 'Dynamic
:tests $ [] $ %{} 'TestEntry (:name |legacy-map-and-struct-archive)
:code $ quote $ let
decoded $ decode-store $ {}
:states $ {}
:content "|历史存档 🐈"
:unused |legacy-extra
restored $ decode-store $ parse-cirru-edn (format-cirru-edn decoded)
assert= "|历史存档 🐈" $ :content decoded
assert= "|历史存档 🐈" $ :content restored
assert= ({}) (:states restored)
'store $ %{} 'CodeEntry (:doc |)
:code $ quote $ def store
Store :states ({}) :content |
Expand All @@ -325,9 +317,9 @@
input $ decode-map-as
{} (:cursor cursor) (:data data)
, app.schema/StatesInput
struct-with store $ :states $ assoc-in (:states store)
concat (:cursor input) ([] :data)
:data input
struct-with store $ :states $ decode-map-as
update-state-tree (:states store) (:cursor input) (:data input)
:: 'Map 'Tag 'Dynamic
(:content content)
struct-with store $ :content $ expect-string |content content
(:hydrate-storage data) (decode-store data)
Expand All @@ -336,8 +328,18 @@
:schema $ :: 'Fn $ {} (:return 'app.schema/Store)
:args $ [] 'app.schema/Store 'Enum 'String 'Number
:features $ #{} :js-ffi
:tests $ [] $ %{} 'TestEntry (:name |cursor-preserves-content)
:code $ quote $ let
base $ app.schema/Store :states ({}) :content |keep
next $ updater base
:: :states ([] :editor) |draft
, |test 0
assert= |keep $ :content next
assert= |draft $ option:unwrap $ get-in (:states next) ([] :editor :data)
assert= ({}) (:states base)
:ns $ %{} 'NsEntry (:doc |)
:code $ quote $ ns app.updater
:require
app.schema :refer $ Store StatesInput decode-store
js-ffi.contract :refer $ expect-string
respo.cursor :refer $ update-state-tree
8 changes: 4 additions & 4 deletions deps.cirru
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{} (:calcit-version |0.27.0)
{} (:calcit-version |0.30.1-alpha.5)
:version |0.0.1
:dependencies $ {}
|Respo/reel.calcit |0.6.33-alpha.2
|Respo/respo.calcit |0.16.114-alpha.5
|calcit-lang/js-ffi |0.2.1-alpha.4
|Respo/reel.calcit |0.6.39
|Respo/respo.calcit |0.16.122
|calcit-lang/js-ffi |0.2.3
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"vite": "^8.3.1"
},
"dependencies": {
"@calcit/procs": "0.27.0",
"@calcit/procs": "0.30.1-alpha.5",
"bottom-tip": "^0.1.5",
"feather-icons": "^4.29.1",
"shortid": "^2.2.16"
Expand Down
28 changes: 18 additions & 10 deletions yarn.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.