diff --git a/README.md b/README.md index 3965605..066ea9c 100644 --- a/README.md +++ b/README.md @@ -6,47 +6,44 @@ Demo http://repo.respo-mvc.org/markup/ . ### Usages -本次升级保留 Content 输入、Run、Reel 调试工具和原有本地存档格式。 -旧页面升级后请完整刷新一次,以加载配对的运行时和正式模块。 -这仍是现有 Demo,不新增 Markdown 解析或编辑功能。 - -当前 CLI/procs 配对正式 **0.32.1**,依赖固定到已发布的 Respo `0.17.1`、 -UI `0.9.0`、Reel `0.7.0-alpha.5`、JS-FFI `0.2.9`,传递 Router `0.9.0-alpha.4`。 -类型标注经官方 formatter 迁移;Snapshot 与原 main 经同一 formatter 规范化后的结果相同, -运行代码、公开合同、三项原测试、存档校验和 HUD 不变,不新增强转或放宽门禁。 -本轮 all-defs 210 项、完整 strict、原三项 Node 回归、immutable/toolchain、文档与构建通过; -实际首屏/刷新无 warn/error,本轮未复验编辑、存档浏览器恢复或 HMR。 -Reel/Router 仍为已发布 alpha,请重新安装完整依赖并生成 JS,避免混用旧缓存。 -Content/Run、快捷键及存档 key 保持不变,UI 升级可能有样式差异。 - -0.31 迁移显式绑定 Respo 的入口事件类型,并在发送状态事件前检查游标确为 List。 -本地 Store 保留原对象;旧存档中的同名外部 Struct 先转为 Map,经字段校验后重建本地 Store。 -名称仅用于选择解码路径,不代表名义身份或可信来源。保留原三项业务测试。 -启动仍先恢复存档,再渲染和注册保存;解析或解码失败会停止启动并保留原值。 -解码失败和 reload 的 HUD 提示保持原行为,坏存档恢复 UI 尚未实现。 - -Caps 0.1.1、Node.js 24、Yarn 4.18.0。项目版本仍为尚未发布的 0.0.5 候选。 -Canonical source and dependencies are `calcit.cirru` and `deps.cirru`; -retired compact/package snapshots are not used. Edit source with the Calcit CLI. +本次候选 **0.0.5** 配对正式 Calcit / `@calcit/procs` **0.34.2**。 +消费者需重新安装完整依赖图、生成 JS 并完整刷新页面。Content 输入、Run、Reel 调试工具、 +存档 key 和格式保持;Demo 不新增 Markdown 解析功能。UI/Reel 跨 minor 升级可能有样式差异。 +0.0.5 尚未发布,正式 tag 出现前不要将本分支当作已发布依赖。 + +依赖使用已发布的 Respo **0.19.2**、UI **0.14.1**、Reel **0.9.0**、JS-FFI **0.2.10**, +传递 Router **0.11.2**;不再使用 Reel / Router 的旧 alpha 图。 +两个 DOM 回调使用真实 RespoEvent 和单 Enum dispatch,输入值由公开 `event-value` 检查为 String。 +原 Reel 的 `read-field` 已删除;此处直接读取数据,保留 Map/Struct 字段读取及缺失值语义。 +两个间隔分别保持 8 / 8px,开发态子节点显式使用 Option。 +根渲染和原 SSR 回归均按 Respo 的公开 managed memo frame 合同包住构造与渲染。 + +应用 Op 与 Store 仍为原名义类型。开放 Enum 分发入口必须检查后转为 Op;它也承载 Reel 控制事件。 +Store.states 是应用与 Reel 共用的真实异构状态树,继续保留 Map Dynamic Dynamic;不以含 Dynamic +的 union 或伪泛型隐藏该边界。固定 Site 已是具体 Struct,不为本次升级引入无实际需要的 union。 + +启动仍先恢复成功,再渲染并注册保存。已有本地 Store 保留身份;旧同名外部 Struct 转为 Map, +验证后重建本地 Store,名称不代表来源或授权。游标只接受缺失或实际 List。 +解析异常会停止启动并保留原存档,但不会显示此处的 HUD 提示; +只有 `decode-store` 返回 :none 时才显示原 HUD 错误,然后停止启动。坏存档恢复 UI 尚未实现。 + +使用 Node 24、Yarn 4.18.0、Caps 0.1.1: ```sh caps --strict --ci yarn install --immutable caps verify --toolchain +calcit calcit.cirru --check-only --all-defs +calcit calcit.cirru fix --workflow strict --verify calcit calcit.cirru js +node --test scripts/typed-reel-render.test.mjs yarn vite ``` -CI retains strict dependency resolution, entry/type checks and the existing -typed Reel rendering tests, and checks all definitions with all-defs plus the full strict workflow. -重复的手写CLI版本断言和namespace清单已移除,保留Caps工具链配对门禁, -不添加校验脚本、concurrently、质量预算或兼容强转。 -开放的 Reel/UI 状态保留真实 Dynamic 边界;操作载荷经过检查并构造成具名 Op, -存档验证后恢复为 Store,不再依赖类型强转。DOM 挂载使用 Respo 的公开接口。 -恢复时仅接受缺失游标或真实 List 游标;旧 Struct 定义恢复到当前 Store, -已是当前 Store 的值保留原对象。既有测试文件包含由迁移前 0.27.0 格式化器生成的 -固定合成存档,经过实际 `:hydrate-storage` / Reel / Content 渲染路径,未使用用户存档。 -完整 strict workflow 同时检查渲染入口的 Enum 守卫与 reload 的实际 Unit 返回。 +只维护 calcit.cirru / deps.cirru,不提交 compact.cirru、package.cirru 或 js-out。 +编辑 Snapshot 使用官方 CLI 的受保护事务;原完整 strict 与 dynamic-method 门禁保留。 +原三项回归及其中固定的 0.27.0 合成存档保持,SSR 仅增加公开 memo frame 入口,不改断言。 +本地已验收合成中文/emoji 输入、Run、Reel 历史展示与刷新恢复;未声称所有 HMR 或坏存档 UI 已验收。 ### Deployment diff --git a/calcit.cirru b/calcit.cirru index 7789b98..b95cde2 100644 --- a/calcit.cirru +++ b/calcit.cirru @@ -19,48 +19,53 @@ (:none) ([]) (:some value) if (list? value) value $ raise "|Expected List cursor" - state $ or (reel-schema/read-field states :data) + state $ or + .unwrap-or (get states :data) nil {} $ :content | + content $ .unwrap-or + get + if (struct? state) (&struct:to-map state) (decode-map-as state 'Map) + , :content + , nil div {} $ :class-name $ str-spaced css/global css/row - textarea $ {} - :value $ reel-schema/read-field state :content - :placeholder |Content + textarea $ {} (:value content) (:placeholder |Content) :class-name $ str-spaced css/expand css/textarea :style $ {} $ :height |320px :on-input $ fn (e d!) - hint-fn $ Fn (Map Tag Dynamic) - Fn Dynamic & Dynamic $ -> Unit + hint-fn $ Fn respo.schema/RespoEvent + Fn Enum $ -> Unit -> Unit - d! $ schema/Op :states cursor $ assoc state :content (reel-schema/read-field e :value) - =< 8 $ {} + d! $ schema/Op :states cursor $ assoc state :content (event-value e) + space-x 8 div {} $ :class-name css/expand <> "|This is some content with `code`" - =< |8px $ {} + space-x |8px button $ {} (:class-name css/button) (:inner-text |Run) :on-click $ fn (e d!) - hint-fn $ Fn (Map Tag Dynamic) - Fn Dynamic & Dynamic $ -> Unit + hint-fn $ Fn respo.schema/RespoEvent + Fn Enum $ -> Unit -> Unit - println $ reel-schema/read-field state :content - when dev? $ comp-typed-reel (>> states :reel) reel $ {} + println content + if dev? + Option :some $ comp-typed-reel (>> states :reel) reel $ {} + Option :none :examples $ [] :schema $ quote $ Fn (reel.typed/State app.schema/Op app.schema/Store) (-> respo.schema/Component) :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns app.comp.container :require (respo-ui.css :as css) respo.css :refer $ defstyle - respo.core :refer $ defcomp defeffect <> >> div button textarea span input - respo.comp.space :refer $ =< + respo.core :refer $ defcomp defeffect <> >> div button textarea span input event-value + respo.comp.space :refer $ space-x reel.comp.reel :refer $ comp-typed-reel - reel.schema :as reel-schema app.config :refer $ dev? app.schema :as schema 'app.config $ %{} 'FileEntry :defs $ {} 'Site $ %{} 'CodeEntry (:doc |) - :code $ quote $ defstruct Site (:storage-key 'String) + :code $ quote $ defstruct Site (:storage-key String) :examples $ [] :schema $ quote StructDef 'dev? $ %{} 'CodeEntry (:doc |) @@ -150,7 +155,7 @@ :schema $ quote $ Fn (-> Unit) (:features :js-ffi) 'render-app! $ %{} 'CodeEntry (:doc |) :code $ quote $ defn render-app! () - render! mount-target (comp-container @*reel) + with-memo-frame $ fn () $ render! mount-target (comp-container @*reel) fn (op) hint-fn $ Fn Dynamic $ -> Unit if (enum? op) (dispatch! op) (raise "|Expected Markup operation Enum") @@ -171,6 +176,7 @@ 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 控制事件;代表值不发送。") @@ -181,8 +187,8 @@ :code $ quote $ defenum Op :states quote $ List Dynamic - , 'Dynamic - :hydrate-storage 'app.schema/Store + , Dynamic + :hydrate-storage app.schema/Store :examples $ [] :schema $ quote EnumDef 'Store $ %{} 'CodeEntry (:doc |) @@ -196,7 +202,7 @@ match op (:states cursor data) Op :states - decode-map-as cursor $ :: 'List 'Dynamic + decode-map-as cursor $ quote $ List Dynamic , data (:hydrate-storage data) match (decode-store data) @@ -242,7 +248,7 @@ (:states cursor s) assoc store :states $ decode-map-as update-state-tree (:states store) cursor s - :: 'Map 'Dynamic 'Dynamic + quote $ Map Dynamic Dynamic (:hydrate-storage data) data :examples $ [] :schema $ quote $ Fn app.schema/Store app.schema/Op String Number (-> app.schema/Store) diff --git a/deps.cirru b/deps.cirru index 0d59863..c9f2227 100644 --- a/deps.cirru +++ b/deps.cirru @@ -1,7 +1,7 @@ -{} (:calcit-version |0.32.1) +{} (:calcit-version |0.34.2) :version |0.0.5 - :dependencies $ {} (|Respo/reel.calcit |0.7.0-alpha.5) - |Respo/respo-ui.calcit |0.9.0 - |Respo/respo.calcit |0.17.1 - |calcit-lang/js-ffi |0.2.9 + :dependencies $ {} (|Respo/reel.calcit |0.9.0) + |Respo/respo-ui.calcit |0.14.1 + |Respo/respo.calcit |0.19.2 + |calcit-lang/js-ffi |0.2.10 diff --git a/package.json b/package.json index e5b82a4..40eea41 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "packageManager": "yarn@4.18.0", "dependencies": { - "@calcit/procs": "0.32.1" + "@calcit/procs": "0.34.2" }, "devDependencies": { "bottom-tip": "^0.1.5", diff --git a/scripts/typed-reel-render.test.mjs b/scripts/typed-reel-render.test.mjs index ed094ef..189cbe4 100644 --- a/scripts/typed-reel-render.test.mjs +++ b/scripts/typed-reel-render.test.mjs @@ -8,6 +8,8 @@ const { store, decode_op, decode_store } = await import('../js-out/app.schema.mj 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 clt = await import('../js-out/calcit.core.mjs'); // Fixed synthetic archive produced by the clean 0.27.0 tag's native formatter, @@ -20,7 +22,7 @@ const PRE_031_ARCHIVE = ` test('renders the typed Reel devtools with an empty history', () => { const reel = toggle_display(new_reel(store)); - const html = make_string(comp_container(reel)); + const html = renderHtml(reel); assert.match(html, /placeholder="Content"/); assert.match(html, /Merge/); @@ -33,7 +35,7 @@ test('content edits survive Reel replay and the existing saved-state format', () const reel = record_op(updater, new_reel(store), decode_op(wire), 'edit', 1); const current = field(reel, 'store'); assert.equal(field(field(field(current, 'states'), 'data'), 'content'), '中文🐈'); - assert.match(make_string(comp_container(reel)), /中文🐈/); + assert.match(renderHtml(reel), /中文🐈/); const restored = clt.option_$o_unwrap(decode_store(clt.parse_cirru_edn(clt.format_cirru_edn(current)))); assert.equal(clt.format_cirru_edn(restored), clt.format_cirru_edn(current)); assert.equal(clt.option_$o_unwrap(decode_store(current)), current); @@ -53,5 +55,5 @@ test('hydrates the fixed pre-upgrade archive through the typed Reel update path' assert.equal(clt._$n__$e_(restored, expected), true); assert.equal(field(field(field(restored, 'states'), 'data'), 'content'), '旧版合成存档🐈'); assert.equal(clt.format_cirru_edn(field(field(restored, 'states'), 'cursor')), clt.format_cirru_edn(clt.parse_cirru_edn('[]'))); - assert.match(make_string(comp_container(reel)), /旧版合成存档🐈/); + assert.match(renderHtml(reel), /旧版合成存档🐈/); }); diff --git a/yarn.lock b/yarn.lock index 4528c87..dfbd5f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,15 +12,15 @@ __metadata: languageName: node linkType: hard -"@calcit/procs@npm:0.32.1": - version: 0.32.1 - resolution: "@calcit/procs@npm:0.32.1" +"@calcit/procs@npm:0.34.2": + version: 0.34.2 + resolution: "@calcit/procs@npm:0.34.2" dependencies: "@calcit/finger-vec": "npm:0.1.1" "@calcit/ternary-tree": "npm:0.0.26" "@cirru/parser.ts": "npm:0.0.10" "@cirru/writer.ts": "npm:^0.1.9" - checksum: 10c0/54c505396a4653e643d24eaa71bf9a029b48034cabcd68ce47b2b40b565cf04a4693ac47c7feb34b8e84936621a397802743bffd3134ddeb37b08d23ef113923 + checksum: 10c0/d59000d82051a28f7929671f76c49959fd63d377e2002cf11ae59a73070d6f8f436190007033015cbf6c41245ee7aecc0289d6c081463720c93df604d9bf2d0b languageName: node linkType: hard @@ -637,7 +637,7 @@ __metadata: version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: - "@calcit/procs": "npm:0.32.1" + "@calcit/procs": "npm:0.34.2" bottom-tip: "npm:^0.1.5" vite: "npm:8.3.3" languageName: unknown