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
4 changes: 2 additions & 2 deletions .github/workflows/upload.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
corepack prepare yarn@4.18.0 --activate
yarn --version

- uses: calcit-lang/setup-calcit@v1.5.0
- uses: calcit-lang/setup-calcit@v1.5.1
with:
tools: calcit,caps
caps-version: "0.1.1"
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:

- name: Upload and verify frontend assets
if: steps.cos-credentials.outputs.available == 'true'
uses: worktools/cos-upload-action@v1.2.0
uses: worktools/cos-upload-action@v1.3.0
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
with:
source-dir: dist
bucket: ${{ secrets.COS_BUCKET }}
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ Demo http://repo.respo-mvc.org/markup/ .

### Usages

本次候选 **0.0.5** 配对正式 Calcit / `@calcit/procs` **0.37.0**。
本次候选 **0.0.5** 配对正式 Calcit / `@calcit/procs` **0.38.0**。
消费者需重新安装完整依赖图、生成 JS 并完整刷新页面。Content 输入、Run、Reel 调试工具、
存档 key 和格式保持;Demo 不新增 Markdown 解析功能。UI/Reel 跨 minor 升级可能有样式差异。
0.0.5 尚未发布,正式 tag 出现前不要将本分支当作已发布依赖。

依赖使用已发布的 Respo **0.19.5**、UI **0.15.2**、Reel **0.10.0**、JS-FFI **0.2.13**,
依赖使用已发布的 Respo **0.19.5**、UI **0.15.2**、Reel **0.11.0**、JS-FFI **0.2.13**,
传递 Router **0.12.2**;不再使用 Reel / Router 的旧 alpha 图。
两个 DOM 回调使用真实 RespoEvent 和单 Enum dispatch,输入值由公开 `event-value` 检查为 String。
编辑回调派发具体 `Op`,Reel 0.11.0 面板与快捷键通过独立回调传递 `Control`。输入值由公开 `event-value` 检查为 String。
原 Reel 的 `read-field` 已删除;此处直接读取数据,保留 Map/Struct 字段读取及缺失值语义。
两个间隔分别保持 8 / 8px,开发态子节点显式使用 Option。
根渲染和原 SSR 回归均按 Respo 的公开 managed memo frame 合同包住构造与渲染。

应用 Op 与 Store 仍为原名义类型。开放 `AnyEnum` 分发入口必须检查后转为 Op;它也承载 Reel 控制事件。
应用 Op 与 Store 仍为原名义类型。存档继续在构造 `Op :hydrate-storage` 前独立校验。
Store.states 是应用与 Reel 共用的真实异构状态树,继续保留 Map Dynamic Dynamic;不以含 Dynamic
的 union 或伪泛型隐藏该边界。固定 Site 已是具体 Struct,不为本次升级引入无实际需要的 union。

Expand Down Expand Up @@ -50,13 +50,13 @@ yarn vite
Frontend build uses `VITE_BASE_URL`, pointing to
`https://cos-sh.tiye.me/Respo/markup/` on main and
`https://cos-sh.tiye.me/Respo/markup/pr/<number>/<run-id>/<attempt>/` for PR previews.
COS action v1.2.0 uploads `dist` and verifies through `public-base-url`;
COS action v1.3.0 uploads `dist` and verifies through `public-base-url`;
no separate upload verification script is needed. Production server deployment
keeps its original source and destination; PRs do not deploy to the server.

同一 PR 的上传使用独立队列,生产上传使用另一个队列;保留排队任务,
不取消正在执行的上传。每次运行及重试使用不同预览路径,生产路径不变。
Action 使用精确正式 tag v1.2.0,验证由 Action 内置能力完成。
Action 使用精确正式 tag v1.3.0,验证由 Action 内置能力完成。

部署路径、COS 内置 verify 和前端/服务端边界不变。PR 不合并或自动部署生产。

Expand Down
56 changes: 20 additions & 36 deletions calcit.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
{} (:description |) (:init-fn 'app.main/main!) (:mode :js) (:reload-fn 'app.main/reload!) (:target :browser)
:feature-policy $ {}
:modules $ [] |respo.calcit/ |respo-ui.calcit/ |reel.calcit/ |js-ffi/
:type-slots $ {} $ :dispatch-op 'app.schema/DispatchOp
:type-slots $ {} $ :dispatch-op 'app.schema/Op
:files $ {}
'app.comp.container $ %{} 'FileEntry
:defs $ {} $ 'comp-container
%{} 'CodeEntry (:doc |)
:code $ quote $ defcomp comp-container (reel)
:code $ quote $ defcomp comp-container (reel on-control!)
let
store $ :store reel
states $ :states store
Expand Down Expand Up @@ -54,10 +54,12 @@
-> Unit
println content
if dev?
Option :some $ comp-typed-reel (>> states :reel) reel $ {}
Option :some $ comp-typed-reel (>> states :reel) reel ({}) on-control!
Option :none
:examples $ []
:schema $ quote $ Fn (reel.typed/State app.schema/Op app.schema/Store) (-> respo.schema/Component)
:schema $ quote $ Fn (reel.typed/State app.schema/Op app.schema/Store)
Fn reel.typed/Control $ -> Unit
-> respo.schema/Component
:ns $ %{} 'NsEntry (:doc |)
:code $ quote $ ns app.comp.container
:require (respo-ui.css :as css)
Expand Down Expand Up @@ -93,14 +95,11 @@
'dispatch! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn dispatch! (op)
when config/dev? $ js/console.log |Dispatch: op
reset! *reel $ match (typed/decode-control op)
(:some action) (typed/apply-control updater @*reel action)
(:none)
typed/record-op updater @*reel (schema/decode-op op) (generate-id!)
:timestamp $ date-now-snapshot
reset! *reel $ typed/record-op updater @*reel op (generate-id!)
:timestamp $ date-now-snapshot
, &unit
:examples $ []
:schema $ quote $ Fn AnyEnum (-> Unit) (:features :js-ffi)
:schema $ quote $ Fn app.schema/Op (-> Unit) (:features :js-ffi)
'main! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn main! ()
println "|Running mode:" $ if config/dev? |dev |release
Expand All @@ -120,7 +119,7 @@
add-watch! *reel :changes $ fn (reel prev)
hint-fn $ Fn (reel.typed/State app.schema/Op app.schema/Store) (reel.typed/State app.schema/Op app.schema/Store) (-> Unit)
render-app!
listen-devtools! |k dispatch!
listen-devtools! |k on-control!
set-before-unload! $ fn (event)
hint-fn $ Fn js-ffi.browser/EventHost $ -> Unit
persist-storage!
Expand All @@ -138,6 +137,12 @@
.unwrap $ query-selector |.app
:examples $ []
:schema $ quote respo.dom/DomElement
'on-control! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn on-control! (control)
reset! *reel $ typed/apply-control updater @*reel control
, &unit
:examples $ []
:schema $ quote $ Fn reel.typed/Control (-> Unit)
'persist-storage! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn persist-storage! ()
println "|Saved at" $ :iso $ date-now-snapshot
Expand All @@ -160,16 +165,15 @@
:schema $ quote $ Fn (-> Unit) (:features :js-ffi)
'render-app! $ %{} 'CodeEntry (:doc |)
:code $ quote $ defn render-app! ()
with-memo-frame $ fn () $ render! mount-target (comp-container @*reel)
fn (op)
hint-fn $ Fn AnyEnum $ -> Unit
if (enum? op) (dispatch! op) (raise "|Expected Markup operation Enum")
render-with! mount-target
fn () $ comp-container @*reel on-control!
, dispatch!
:examples $ []
:schema $ quote $ Fn (-> Unit) (: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 @@ -181,13 +185,8 @@
reel.typed :as typed
js-ffi.browser :refer $ add-event-listener! set-before-unload! set-interval! storage-get storage-set! visibility-state
respo.ffi.browser :refer $ query-selector
respo.memo :refer $ with-memo-frame
'app.schema $ %{} 'FileEntry
:defs $ {}
'DispatchOp $ %{} 'CodeEntry (:doc "|Respo 入口事件合同,容纳应用和 Reel 控制事件;代表值不发送。")
:code $ quote $ def DispatchOp (:: :unhandled)
:examples $ []
:schema $ quote AnyEnum
'Op $ %{} 'CodeEntry (:doc |)
:code $ quote $ defenum Op
:states (List respo.schema/CoordKey) Dynamic
Expand All @@ -199,21 +198,6 @@
:states $ Map Dynamic Dynamic
:examples $ []
:schema $ quote StructDef
'decode-op $ %{} 'CodeEntry
:doc "|将 Respo/Reel 传入的单 Enum 规范为应用 Op,检查游标列表与存档载荷;不直接断言 nominal 类型。"
:code $ quote $ defn decode-op (op)
match op
(:states cursor data)
Op :states
decode-map-as cursor $ List respo.schema/CoordKey
, data
(:hydrate-storage data)
match (decode-store data)
(:some stored) (Op :hydrate-storage stored)
(:none) (raise "|Invalid saved Markup state")
_ $ raise "|Unknown Markup operation"
:examples $ []
:schema $ quote $ Fn AnyEnum (-> app.schema/Op)
'decode-store $ %{} 'CodeEntry
:doc "|本地存档/旧存档的开放入口:已有 Store 保留身份,Map 验证后构造成 Store。states 是应用与 Reel 共用的异构 UI 状态树,不伪装成泛型关系。"
:code $ quote $ defn decode-store (data)
Expand Down
4 changes: 2 additions & 2 deletions deps.cirru
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

{} (:calcit-version |0.37.0)
{} (:calcit-version |0.38.0)
:version |0.0.5
:dependencies $ {} (|Respo/reel.calcit |0.10.0)
:dependencies $ {} (|Respo/reel.calcit |0.11.0)
|Respo/respo-ui.calcit |0.15.2
|Respo/respo.calcit |0.19.5
|calcit-lang/js-ffi |0.2.13
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"packageManager": "yarn@4.18.0",
"dependencies": {
"@calcit/procs": "0.37.0"
"@calcit/procs": "0.38.0"
},
"devDependencies": {
"bottom-tip": "^0.1.5",
Expand Down
14 changes: 8 additions & 6 deletions scripts/typed-reel-render.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import test from 'node:test';
process.env.mode = 'dev';

const { comp_container } = await import('../js-out/app.comp.container.mjs');
const { store, decode_op, decode_store } = await import('../js-out/app.schema.mjs');
const { Op, store, decode_store } = await import('../js-out/app.schema.mjs');
const { updater } = await import('../js-out/app.updater.mjs');
const { new_reel, toggle_display, record_op, refresh } = await import('../js-out/reel.typed.mjs');
const { make_string } = await import('../js-out/respo.render.html.mjs');
const { with_memo_frame } = await import('../js-out/respo.memo.mjs');
const renderHtml = (reel) => with_memo_frame(() => make_string(comp_container(reel)));
const renderHtml = (reel) => with_memo_frame(() => make_string(comp_container(reel, () => {})));
const clt = await import('../js-out/calcit.core.mjs');

// Fixed synthetic archive produced by the clean 0.27.0 tag's native formatter,
Expand All @@ -31,8 +31,9 @@ test('renders the typed Reel devtools with an empty history', () => {

test('content edits survive Reel replay and the existing saved-state format', () => {
const field = (value, key) => clt.get(value, clt.init_tags([key])[key]).extra[0];
const wire = clt.parse_cirru_edn(':: :states ([]) ({} (:content |中文🐈))');
const reel = record_op(updater, new_reel(store), decode_op(wire), 'edit', 1);
const t = clt.init_tags(['states', 'content']);
const edit = clt._PCT__$o__$o_(Op, t.states, clt._$L_(), clt._$n__$M_(t.content, '中文🐈'));
const reel = record_op(updater, new_reel(store), edit, 'edit', 1);
const current = field(reel, 'store');
assert.equal(field(field(field(current, 'states'), 'data'), 'content'), '中文🐈');
assert.match(renderHtml(reel), /中文🐈/);
Expand All @@ -48,8 +49,9 @@ test('content edits survive Reel replay and the existing saved-state format', ()
test('hydrates the fixed pre-upgrade archive through the typed Reel update path', () => {
const field = (value, key) => clt.get(value, clt.init_tags([key])[key]).extra[0];
const legacy = clt.parse_cirru_edn(PRE_031_ARCHIVE);
const hydrate = clt._$o__$o_(clt.init_tags(['hydrate-storage'])['hydrate-storage'], legacy);
const reel = record_op(updater, new_reel(store), decode_op(hydrate), 'legacy-archive', 1);
const stored = clt.option_$o_unwrap(decode_store(legacy));
const hydrate = clt._PCT__$o__$o_(Op, clt.init_tags(['hydrate-storage'])['hydrate-storage'], stored);
const reel = record_op(updater, new_reel(store), hydrate, 'legacy-archive', 1);
const restored = field(reel, 'store');
const expected = clt.assoc(store, clt.init_tags(['states']).states, field(legacy, 'states'));
assert.equal(clt._$n__$e_(restored, expected), true);
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock

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