diff --git a/README.md b/README.md index b31178d..e2a63fe 100644 --- a/README.md +++ b/README.md @@ -5,38 +5,18 @@ Text diff ### 使用者影响 -CLI 与 `@calcit/procs` 配对正式 **0.34.2**,升级后需重新安装完整精确依赖图、 -生成 JS 并完整刷新,不能跨工具链热重载保留旧 Reel 实例。目标为正式 Reel -**0.9.0**、UI **0.14.1**、Respo **0.19.2**、JS-FFI **0.2.10** 与 Markdown -**0.7.1**。已从正式 tag 完成根 Caps strict/toolchain,6 个模块的 Snapshot 与本轮 -实际验收候选逐字节相同,不使用候选链接、main/hash 或关闭 strict 代替正式图。 +升级到 Calcit 和 `@calcit/procs` **0.35.1** 后,请重新安装依赖、编译并刷新。文本输入、Run 输出、原 Map 存档和页面 HUD 继续适用。 -保留已有 `CursorKey = Tag | String | Number` union,`:states` 的 Bool 等其他 key -仍按原合同拒绝,false/0 状态 payload、原 Map 存档格式及匿名 Enum/Reel 操作入口 -保持。不为开放状态伪造有限 union,也不扩张公开 diff API。 +Reel 使用 `State`。旧操作在入口解码,业务更新器接收具名操作。状态路径沿用 `CursorKey = Tag | String | Number`,已有 Map 或 Struct 存档仍在恢复时校验。恢复成功后才注册离页保存。 -textarea 回调现在接收真实 RespoEvent,读取 `:value` 后仍检查 String,缺失/非法 -输入在修改状态前报错;根组件构建和实际渲染同处 managed memo frame。两处原 -8px 宽度保留。恢复失败保护、HUD、存档 key 和部署路径保持。官方 AST 比较只有 -两个业务代码体与两个 namespace import 改变,原 schema、CursorKey、updater -与三项测试断言保持,不放宽门禁或新增 checker。 - -Reel 保留 `State`,公共 updater 接受原 Enum,UI 输入经 Enum 检查后 -派发。存档仍输出 Map;原 Map/Struct 输入通过已有 Store 边界恢复。恢复成功后 -才注册 beforeunload 保存,解析/解码失败不会覆盖原存档;不吞错、不清空或替换数据。 -此流程没有新增定时保存。npm 安装等待一小时,无单包例外。 - -当前源码只有示例 UI 和 Store updater;历史简介中的 diff 算法仍为 WIP,本迁移 -不补写或验证不存在的算法。本轮普通可见 Chrome 使用独立回环来源与合成文本, -实际输入中文/emoji、多行、点击 run 输出当前内容、离页保存及刷新恢复通过,未见 -应用 pageerror。未重新验收坏存档保护,不把正常恢复或历史结果当作本次完整证明。 +正式依赖为 Respo **0.19.4**、Reel **0.9.2**、Markdown **0.8.1**、UI **0.15.1**、JS-FFI **0.2.13**,传递 Router **0.12.1**。 ### Workflow Use `calcit.cirru` and `deps.cirru`; do not restore the retired `compact.cirru` or `package.cirru`. Generated `js-out/` is not committed. -Use Node 24 and Yarn 4.18.0. Install Calcit 0.34.2 and Caps 0.1.1 separately +Use Node 24 and Yarn 4.18.0. Install Calcit 0.35.1 and Caps 0.1.1 separately (the latter follows [the official Caps installation](https://github.com/calcit-lang/caps)); Corepack/Yarn does not install Caps. Strict dependency installation and the original type/test gates are retained. Browser and production acceptance remain separate from successful compilation. diff --git a/calcit.cirru b/calcit.cirru index 302d409..27f626d 100644 --- a/calcit.cirru +++ b/calcit.cirru @@ -23,12 +23,12 @@ :style $ .merge ui/expand ui/textarea $ {} (:height 320) :on-input $ fn (e d!) hint-fn $ Fn respo.schema/RespoEvent - Fn Enum $ -> Unit + Fn AnyEnum $ -> Unit -> Unit let value $ :value e if (string? value) - d! $ :: :content value + d! $ text-diff.schema/Op :content value raise |Expected-string-input-value space-x 8 div @@ -39,14 +39,14 @@ :inner-text $ str |run :on-click $ fn (e d!) hint-fn $ Fn respo.schema/RespoEvent - Fn Enum $ -> Unit + Fn AnyEnum $ -> Unit -> Unit println $ :content store if dev? Option :some $ comp-typed-reel (>> states :reel) reel $ {} Option :none :examples $ [] - :schema $ quote $ Fn (reel.typed/State Enum text-diff.schema/Store) (-> respo.schema/Component) + :schema $ quote $ Fn (reel.typed/State text-diff.schema/Op text-diff.schema/Store) (-> respo.schema/Component) :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns text-diff.comp.container :require (respo-ui.core :as ui) @@ -91,30 +91,30 @@ 'text-diff.main $ %{} 'FileEntry :defs $ {} '*reel $ %{} 'CodeEntry (:doc |) - :code $ quote $ defref *reel (typed/new-reel 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 $ quote $ Ref (reel.typed/State Enum text-diff.schema/Store) + :schema $ quote $ Ref (reel.typed/State text-diff.schema/Op text-diff.schema/Store) 'dispatch! $ %{} 'CodeEntry (:doc |) :code $ quote $ defn dispatch! (op) - if (enum? op) - do - when config/dev? $ println |Dispatch: op - match (typed/decode-control op) - (:some control) - reset! *reel $ typed/apply-control updater @*reel control - (:none) - reset! *reel $ typed/record-op updater @*reel op (generate-id!) - :timestamp $ shared/date-now-snapshot - , &unit - raise "|Expected an operation enum" - :examples $ [] - :schema $ quote $ Fn Dynamic (-> Unit) (:features :js-ffi) + when config/dev? $ println |Dispatch: op + match (typed/decode-control op) + (:some control) + reset! *reel $ typed/apply-control updater @*reel control + (:none) + match (schema/decode-op op) + (:some action) + reset! *reel $ typed/record-op updater @*reel action (generate-id!) (shared/now-ms) + (:none) &unit + , &unit + :examples $ [] + :schema $ quote $ Fn AnyEnum (-> Unit) (: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) - hint-fn $ Fn (reel.typed/State Enum text-diff.schema/Store) (reel.typed/State Enum text-diff.schema/Store) (-> Unit) + hint-fn $ Fn (reel.typed/State text-diff.schema/Op text-diff.schema/Store) (reel.typed/State text-diff.schema/Op text-diff.schema/Store) (-> Unit) render-app! , &unit listen-devtools! |a dispatch! @@ -145,7 +145,7 @@ if (nil? build-errors) do (remove-watch! *reel :changes) (clear-cache!) add-watch! *reel :changes $ fn (reel prev) - hint-fn $ Fn (reel.typed/State Enum text-diff.schema/Store) (reel.typed/State Enum text-diff.schema/Store) (-> Unit) + hint-fn $ Fn (reel.typed/State text-diff.schema/Op text-diff.schema/Store) (reel.typed/State text-diff.schema/Op text-diff.schema/Store) (-> Unit) render-app! , &unit reset! *reel $ typed/refresh updater @*reel schema/store @@ -156,7 +156,9 @@ :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) dispatch! + render-with! (mount-target) + fn () $ comp-container @*reel + , dispatch! :examples $ [] :schema $ quote $ Fn (-> Unit) (:features :js-ffi) 'snippets $ %{} 'CodeEntry (:doc |) @@ -166,7 +168,7 @@ :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns text-diff.main :require - respo.core :refer $ render! clear-cache! realize-ssr! + respo.core :refer $ render-with! clear-cache! text-diff.comp.container :refer $ comp-container text-diff.updater :refer $ updater text-diff.schema :as schema @@ -178,7 +180,6 @@ reel.typed :as typed js-ffi.shared :as shared reel.util :refer $ listen-devtools! - respo.memo :refer $ with-memo-frame 'text-diff.schema $ %{} 'FileEntry :defs $ {} 'CursorKey $ %{} 'CodeEntry @@ -187,16 +188,40 @@ :examples $ [] :schema $ quote UnionDef 'DispatchOp $ %{} 'CodeEntry - :doc "|Open Enum alias for Respo dispatch-op: application operations and Reel controls retain their existing tags and payloads. This representative value is not dispatched; the explicit Enum schema supplies the slot contract. dispatch! and updater keep their existing runtime checks." + :doc "|Respo dispatch slot accepts application operations and Reel controls." :code $ quote $ def DispatchOp (:: :unhandled) :examples $ [] - :schema $ quote Enum + :schema $ quote AnyEnum + 'Op $ %{} 'CodeEntry (:doc |) + :code $ quote $ defenum Op + :states (List text-diff.schema/CursorKey) Dynamic + :content String + :hydrate-storage text-diff.schema/Store + :examples $ [] + :schema $ quote EnumDef 'Store $ %{} 'CodeEntry (:doc |) :code $ quote $ defstruct Store - :states $ quote $ Map Tag Dynamic + :states $ Map Tag Dynamic :content String :examples $ [] :schema $ quote StructDef + 'decode-op $ %{} 'CodeEntry (:doc |) + :code $ quote $ defn decode-op (op) + match op + (:states cursor data) + Option :some $ Op :states + decode-map-as cursor $ List text-diff.schema/CursorKey + , data + (:content content) + Option :some $ Op :content $ decode-map-as content String + (:hydrate-storage data) + Option :some $ Op :hydrate-storage $ decode-map-as + if (struct? data) (&struct:to-map data) data + , text-diff.schema/Store + _ $ do (eprintln "|Unknown op:" op) (Option :none) + :examples $ [] + :schema $ quote $ Fn AnyEnum + -> $ Option text-diff.schema/Op 'store $ %{} 'CodeEntry (:doc |) :code $ quote $ def store Store :states ({}) :content | @@ -209,21 +234,14 @@ %{} 'CodeEntry (:doc |) :code $ quote $ defn updater (store op op-id op-time) match op - (:states cursor s) + (:states cursor data) assoc store :states $ decode-map-as - update-state-tree (:states store) - decode-map-as cursor $ quote $ List text-diff.schema/CursorKey - , s - quote $ Map Tag Dynamic - (:content c) - assoc store :content $ decode-map-as c 'String - (:hydrate-storage d) - decode-map-as - if (struct? d) (&struct:to-map d) d - , 'text-diff.schema/Store - _ $ do (eprintln "|Unknown op:" op) store - :examples $ [] - :schema $ quote $ Fn text-diff.schema/Store Enum String Number (-> text-diff.schema/Store) + update-state-tree (:states store) cursor data + Map Tag Dynamic + (:content content) (assoc store :content content) + (:hydrate-storage stored) stored + :examples $ [] + :schema $ quote $ Fn text-diff.schema/Store text-diff.schema/Op String Number (-> text-diff.schema/Store) :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns text-diff.updater :require $ respo.cursor :refer $ update-state-tree diff --git a/deps.cirru b/deps.cirru index 910163b..1e712de 100644 --- a/deps.cirru +++ b/deps.cirru @@ -1,8 +1,8 @@ -{} (:calcit-version |0.34.2) - :version |0.1.3 - :dependencies $ {} (|Respo/reel.calcit |0.9.0) - |Respo/respo-markdown.calcit |0.7.1 - |Respo/respo-ui.calcit |0.14.1 - |Respo/respo.calcit |0.19.2 - |calcit-lang/js-ffi |0.2.10 +{} (:calcit-version |0.35.1) + :version |0.1.4 + :dependencies $ {} (|Respo/reel.calcit |0.9.2) + |Respo/respo-markdown.calcit |0.8.1 + |Respo/respo-ui.calcit |0.15.1 + |Respo/respo.calcit |0.19.4 + |calcit-lang/js-ffi |0.2.13 diff --git a/package.json b/package.json index c820b74..d98080a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calcit-workflow", - "version": "0.1.3", + "version": "0.1.4", "description": "ClojureScript workflow using Calcit Editor", "main": "index.js", "packageManager": "yarn@4.18.0", @@ -20,7 +20,7 @@ "vite": "^8.3.1" }, "dependencies": { - "@calcit/procs": "0.34.2", + "@calcit/procs": "0.35.1", "cirru-color": "^0.2.4", "copy-text-to-clipboard": "^3.2.2", "dayjs": "^1.11.20", diff --git a/scripts/upgrade.test.mjs b/scripts/upgrade.test.mjs index a442c97..1f300ec 100644 --- a/scripts/upgrade.test.mjs +++ b/scripts/upgrade.test.mjs @@ -2,11 +2,11 @@ import assert from 'node:assert/strict'; import test from 'node:test'; import * as c from '../js-out/calcit.core.mjs'; import { updater } from '../js-out/text-diff.updater.mjs'; -import { store } from '../js-out/text-diff.schema.mjs'; +import { decode_op, store } from '../js-out/text-diff.schema.mjs'; const tags = c.init_tags(['content', 'states']); const read = (value, key) => c.option_$o_unwrap(c.get(value, key)); -const apply = (source, op) => updater(source, c.parse_cirru_edn(op), 'test-op', 0); +const apply = (source, op) => updater(source, c.option_$o_unwrap(decode_op(c.parse_cirru_edn(op))), 'test-op', 0); test('content update preserves cursor state and leaves original store unchanged', () => { const updated = apply(store, ':: :content |hello'); diff --git a/yarn.lock b/yarn.lock index f4d15f2..df88b53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,15 +12,15 @@ __metadata: languageName: node linkType: hard -"@calcit/procs@npm:0.34.2": - version: 0.34.2 - resolution: "@calcit/procs@npm:0.34.2" +"@calcit/procs@npm:0.35.1": + version: 0.35.1 + resolution: "@calcit/procs@npm:0.35.1" 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/d59000d82051a28f7929671f76c49959fd63d377e2002cf11ae59a73070d6f8f436190007033015cbf6c41245ee7aecc0289d6c081463720c93df604d9bf2d0b + checksum: 10c0/c39ab807cdda677cfd9fa9f6ae8adbb468347d5dd85ac38355a27a048cc9a1b7301d4f9c73f3bbf815269ecc7a59d824f61c8c46a9d56ae6a67f3b5cb21be3de languageName: node linkType: hard @@ -278,7 +278,7 @@ __metadata: version: 0.0.0-use.local resolution: "calcit-workflow@workspace:." dependencies: - "@calcit/procs": "npm:0.34.2" + "@calcit/procs": "npm:0.35.1" bottom-tip: "npm:^0.1.5" cirru-color: "npm:^0.2.4" copy-text-to-clipboard: "npm:^3.2.2"