From 7408542401b80c5c247c082797dc53d14b07f3a1 Mon Sep 17 00:00:00 2001 From: tiye Date: Tue, 27 Oct 2026 13:00:42 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=20Data=20Former=20=E8=87=B3?= =?UTF-8?q?=20Calcit=200.31=20=E5=B9=B6=E6=A3=80=E6=9F=A5=E6=81=A2?= =?UTF-8?q?=E5=A4=8D=E4=B8=8E=E5=9B=9E=E8=B0=83=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/upload.yaml | 5 +- .yarnrc.yml | 3 +- README.md | 19 ++- calcit.cirru | 213 +++++++++++++++++++---------- deps.cirru | 10 +- package.json | 2 +- scripts/former-regression.test.mjs | 22 +-- yarn.lock | 28 ++-- 8 files changed, 198 insertions(+), 104 deletions(-) diff --git a/.github/workflows/upload.yaml b/.github/workflows/upload.yaml index b9c322b..de06c73 100644 --- a/.github/workflows/upload.yaml +++ b/.github/workflows/upload.yaml @@ -49,8 +49,9 @@ jobs: caps verify --toolchain 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.button --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 fix --workflow strict --verify --format json | jq -e '.data.workflow.status == "passed" and .diagnostics == []' + calcit --check-only --ns app.comp.button --ns app.comp.container --ns app.config --ns app.main --ns app.schema --ns app.updater --summary-only calcit calcit.cirru test --require-match calcit calcit.cirru analyze quality --baseline config/calcit-quality.cirru diff --git a/.yarnrc.yml b/.yarnrc.yml index a51b2bc..3b0a072 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,4 +1,3 @@ nodeLinker: node-modules -npmPreapprovedPackages: - - "@calcit/procs@0.27.0" +npmMinimalAgeGate: 60 diff --git a/README.md b/README.md index a74f73a..257072b 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,28 @@ Data former _TODO_ -Development requires Calcit 0.27.0, Caps 0.1.1, Node.js 24 and Yarn 4.18.0: +本轮迁移要求 Calcit 与 `@calcit/procs` 同为正式版 0.31.0。页面的 Run、两处文本输入和按钮 400ms 反馈保持原行为;恢复旧存档成功后才注册自动保存,坏存档会中止启动,原文不会被默认状态覆盖。`hud!` 仍负责显示热更新状态与错误。 + +Store 的 `data` 仍允许原有的任意数据,嵌套 UI 状态仍允许异构 key;存档恢复会检查 Store 字段并重建本地记录。Copy 仅接受内置 `ToString` 标量(字符串、数字、布尔、Tag、Symbol 与 nil),不会把集合改为调试文本后复制。非法存档和不符合事件合同的值会在入口报错。 + +Development requires Calcit 0.31.0, Caps 0.1.1, Node.js 24 and Yarn 4.18.0: ```sh caps --strict --ci yarn install --immutable caps verify --toolchain +calcit --check-only --all-defs +calcit fix --workflow strict --verify +calcit test --require-match +calcit analyze quality --baseline config/calcit-quality.cirru yarn build node --test scripts/former-regression.test.mjs ``` +`deps.cirru` pins published module tags. Reel, Respo and UI still use their +published alpha tags; pairing the CLI/runtime at 0.31.0 does not imply those +libraries have a stable release. Yarn retains a one-hour package age gate. + Use only `calcit.cirru` and `deps.cirru`; do not restore retired `compact.cirru` and `package.cirru` snapshots. CI uploads and publicly verifies only frontend `dist/` at `https://cos-sh.tiye.me/Cirru/data-former/`, with a @@ -27,8 +39,9 @@ server destination are unchanged. `yarn build` compiles the default JS browser entry and builds once; `yarn dev` compiles initially and starts Vite. Run `calcit calcit.cirru -w` in another -terminal for live edits. Canonical/entry/public, original quality baseline and -business tests remain; repeated migration and diagnostic reports are removed. +terminal for live edits. CI checks canonical formatting, all definitions, the +strict workflow, public namespaces, the unchanged quality baseline and business +tests. No additional project-specific verification runner is required. - Demo of S-Expressions http://repo.cirru.org/data-former diff --git a/calcit.cirru b/calcit.cirru index 03a449a..b138052 100644 --- a/calcit.cirru +++ b/calcit.cirru @@ -6,16 +6,17 @@ {} (: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 $ {} + :type-slots $ {} $ :dispatch-op |app.schema/Op :files $ {} 'app.comp.button $ %{} 'FileEntry :defs $ {} $ 'comp-live-button %{} 'CodeEntry (:doc |) :code $ quote $ defcomp comp-live-button (states text on-click) let - cursor $ - get states :cursor - , .unwrap-or $ [] + cursor $ decode-map-as + get states :cursor + , .unwrap-or $ [] + :: 'List 'Dynamic state $ get states :data , .unwrap-or $ {} (:darken? false) @@ -28,34 +29,41 @@ {} :: 'Map 'Tag 'Dynamic :inner-text text - :on-click $ fn (e d!) (on-click e d!) + :on-click $ fn (e d!) + hint-fn $ {} + :args $ [] (:: 'Map 'Tag 'Dynamic) + :: 'Fn $ {} + :args $ [] 'app.schema/Op + :return 'Unit + :return 'Unit + on-click e d! d! $ Op :states cursor $ assoc state :darken? true browser/set-timeout! fn () $ d! $ Op :states cursor (assoc state :darken? false) , 400 + , &unit :examples $ [] :schema $ :: 'Fn $ {} (:return 'respo.schema/Component) - :args $ [] (:: 'Map 'Tag 'Dynamic) 'String 'respo.schema/EventHandler + :args $ [] (:: 'Map 'Dynamic 'Dynamic) 'String 'respo.schema/EventHandler :features $ #{} :js-ffi :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns app.comp.button :require - [] respo-ui.core :refer $ [] hsl - [] respo-ui.core :as ui - [] respo.core :refer $ [] defcomp >> <> div button textarea span - [] respo.comp.space :refer $ [] =< - [] app.config :refer $ [] dev? + respo-ui.core :refer $ hsl + respo-ui.core :as ui + respo.core :refer $ defcomp >> <> div button textarea span + respo.comp.space :refer $ =< + app.config :refer $ dev? js-ffi.browser :as browser - app.schema :refer $ [] Op + app.schema :refer $ Op 'app.comp.container $ %{} 'FileEntry - :defs $ {} $ 'comp-container - %{} 'CodeEntry (:doc |) + :defs $ {} + 'comp-container $ %{} 'CodeEntry (:doc |) :code $ quote $ defcomp comp-container (reel) let - store $ assert-type - get reel :store - , .unwrap - , 'app.schema/Store + store $ app.schema/restore-store $ + get reel :store + , .unwrap states $ :states store content $ :content store data $ :data store @@ -70,16 +78,18 @@ d! $ Op :data $ format-to-lisp (parse-cirru-edn content) =< 8 nil comp-live-button (>> states :copy) |Copy $ fn (e d!) - copy! $ turn-string data + copy! $ scalar-copy-text data + , &unit div {} $ :style $ merge ui/flex ui/row textarea $ {} (:value content) (:placeholder |Content) :style $ merge (merge ui/flex ui/textarea) {} $ :font-family ui/font-code :on-input $ fn (e d!) - d! $ Op :content $ - get e :value - , .unwrap-or | + d! $ Op :content $ decode-map-as + get e :value + , .unwrap-or | + , 'String textarea $ {} (:value data) (:placeholder |data) :style $ merge (merge ui/flex ui/textarea) {} $ :font-family ui/font-code @@ -91,18 +101,33 @@ :examples $ [] :schema $ :: 'Fn $ {} (:return 'respo.schema/Component) :args $ [] $ :: 'Map 'Tag 'Dynamic + 'scalar-copy-text $ %{} 'CodeEntry (:doc |) + :code $ quote $ defn scalar-copy-text (value) + cond + nil? value + , | + (string? value) value + (number? value) (to-string value) + (bool? value) (to-string value) + (tag? value) (to-string value) + (symbol? value) (to-string value) + true $ raise "|Only scalar data can be copied" + :examples $ [] + :schema $ :: 'Fn $ {} (:return 'String) + :args $ [] 'T + :generics $ [] 'T :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns app.comp.container :require - respo-ui.core :refer $ [] hsl + respo-ui.core :refer $ hsl respo-ui.core :as ui - respo.core :refer $ [] defcomp >> <> div button textarea span - respo.comp.space :refer $ [] =< - reel.comp.reel :refer $ [] comp-reel - app.config :refer $ [] dev? + respo.core :refer $ defcomp >> <> div button textarea span + respo.comp.space :refer $ =< + reel.comp.reel :refer $ comp-reel + app.config :refer $ dev? |copy-text-to-clipboard :default copy! - app.comp.button :refer $ [] comp-live-button - app.schema :refer $ [] Op Store + app.comp.button :refer $ comp-live-button + app.schema :refer $ Op Store 'app.config $ %{} 'FileEntry :defs $ {} 'cdn? $ %{} 'CodeEntry (:doc |) @@ -119,7 +144,9 @@ exists? js/window , false (exists? js/process) - = |true $ option:unwrap-or (get-env |cdn) |false + = |true $ + get-env |cdn + , .unwrap-or |false true false :examples $ [] :schema $ :: 'Fn $ {} (:return 'Bool) @@ -136,32 +163,30 @@ :code $ quote $ def site {} (:dev-ui |http://localhost:8100/main.css) (:release-ui |http://cdn.tiye.me/favored-fonts/main.css) (:cdn-url |http://cdn.tiye.me/data-former/) (:cdn-folder |tiye.me:cdn/data-former) (:title "|Data former") (:icon |http://cdn.tiye.me/logo/cirru.png) (:storage-key |data-former) (:upload-folder |tiye.me:repo/Cirru/data-former/) :examples $ [] - :schema $ :: 'Dynamic + :schema $ :: 'Map 'Tag 'String :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns app.config 'app.main $ %{} 'FileEntry :defs $ {} '*reel $ %{} 'CodeEntry (:doc |) - :code $ quote $ defatom *reel + :code $ quote $ defref *reel -> reel-schema/reel (assoc :base schema/store) (assoc :store schema/store) :examples $ [] - :schema $ :: 'Dynamic + :schema $ :: 'Ref $ :: 'Map 'Tag 'Dynamic 'dispatch! $ %{} 'CodeEntry (:doc |) :code $ quote $ defn dispatch! (op) when config/dev? $ println |Dispatch: op - reset! *reel $ reel-updater updater @*reel op + reset! *reel $ reel-updater + fn (saved operation op-id op-time) + updater (schema/restore-store saved) (decode-map-as operation 'app.schema/Op) (decode-map-as op-id 'String) (decode-map-as op-time 'Number) + , @*reel op + , &unit :examples $ [] :schema $ :: 'Fn $ {} (:return 'Unit) :args $ [] 'app.schema/Op 'main! $ %{} 'CodeEntry (:doc |) :code $ quote $ defn main! () println "|Running mode:" $ if config/dev? |dev |release - render-app! - add-watch *reel :changes $ fn (r p) (render-app!) - browser/add-event-listener! |beforeunload $ fn (event) (persist-storage!) - browser/set-interval! - fn () $ persist-storage! - , 60000 let raw $ browser/storage-get-or get config/site :storage-key @@ -169,8 +194,14 @@ , | when (not= raw |) let - restored $ assert-type (parse-cirru-edn raw) 'app.schema/Store + restored $ schema/restore-store $ parse-cirru-edn raw dispatch! $ schema/Op :hydrate-storage restored + render-app! + add-watch! *reel :changes $ fn (r p) (render-app!) + browser/add-event-listener! |beforeunload $ fn (event) (persist-storage!) + browser/set-interval! + fn () $ persist-storage! + , 60000 println "|App started." :examples $ [] :schema $ :: 'Fn $ {} (:return 'Unit) @@ -178,19 +209,20 @@ :features $ #{} :js-ffi 'mount-target $ %{} 'CodeEntry (:doc |) :code $ quote $ defn mount-target () - (browser/query-selector |.app) .unwrap + respo-browser/narrow-element $ + browser/query-selector |.app + , .unwrap :examples $ [] - :schema $ :: 'Fn $ {} (:return 'js-ffi.browser/DomElementHost) + :schema $ :: 'Fn $ {} (:return 'respo.dom/DomElement) :args $ [] :features $ #{} :js-ffi 'persist-storage! $ %{} 'CodeEntry (:doc |) :code $ quote $ defn persist-storage! () let - reel-value $ assert-type @*reel $ :: 'Map 'Tag 'Dynamic - store $ assert-type - get reel-value :store - , .unwrap - , 'app.schema/Store + reel-value @*reel + store $ schema/restore-store $ + get reel-value :store + , .unwrap browser/storage-set! get config/site :storage-key , .unwrap-or |data-former @@ -202,11 +234,12 @@ 'reload! $ %{} 'CodeEntry (:doc |) :code $ quote $ defn reload! () if (nil? build-errors) - do (remove-watch *reel :changes) (clear-cache!) - add-watch *reel :changes $ fn (reel prev) (render-app!) - reset! *reel $ assert-type (refresh-reel @*reel schema/store updater) (:: 'Map 'Tag 'Dynamic) + do (remove-watch! *reel :changes) (clear-cache!) + add-watch! *reel :changes $ fn (reel prev) (render-app!) + reset! *reel $ decode-map-as (refresh-reel @*reel schema/store updater) (:: 'Map 'Tag 'Dynamic) hud! |ok~ |Ok hud! |error build-errors + , &unit :examples $ [] :schema $ :: 'Fn $ {} (:return 'Unit) :args $ [] @@ -221,18 +254,19 @@ :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns app.main :require - [] respo.core :refer $ [] render! clear-cache! realize-ssr! - [] app.comp.container :refer $ [] comp-container - [] app.updater :refer $ [] updater - [] app.schema :as schema - [] reel.util :refer $ [] listen-devtools! - [] reel.core :refer $ [] reel-updater refresh-reel - [] reel.schema :as reel-schema - [] cljs.reader :refer $ [] read-string - [] app.config :as config + respo.core :refer $ render! clear-cache! realize-ssr! + app.comp.container :refer $ comp-container + app.updater :refer $ updater + app.schema :as schema + reel.util :refer $ listen-devtools! + reel.core :refer $ reel-updater refresh-reel + reel.schema :as reel-schema + cljs.reader :refer $ read-string + app.config :as config |./calcit.build-errors :default build-errors |bottom-tip :default hud! js-ffi.browser :as browser + respo.ffi.browser :as respo-browser 'app.schema $ %{} 'FileEntry :defs $ {} 'Op $ %{} 'CodeEntry (:doc |) @@ -250,6 +284,47 @@ :data 'Dynamic :examples $ [] :schema $ :: 'StructDef + 'restore-store $ %{} 'CodeEntry (:doc |) + :code $ quote $ defn restore-store (data) + if (struct? data) + struct-match data (Store checked checked) + _ other $ let + wire-template $ parse-cirru-edn $ format-cirru-edn store + if (struct? wire-template) + if + = (struct-definition other) (struct-definition wire-template) + decode-map-as (&struct:to-map other) 'app.schema/Store + raise "|Expected Data Former Store" + raise "|Expected Data Former Store" + decode-map-as data 'app.schema/Store + :examples $ [] + :schema $ :: 'Fn $ {} (:return 'app.schema/Store) + :args $ [] 'T + :generics $ [] 'T + :tests $ [] $ %{} 'TestEntry (:name |legacy-map-and-store-roundtrip) + :code $ quote $ let + legacy $ {} + :states $ {} $ 7 + {} $ :data false + :content "|saved 🐈" + :data 42 + saved $ restore-store legacy + roundtrip $ restore-store $ parse-cirru-edn (format-cirru-edn saved) + bad? $ ref false + assert= saved roundtrip + assert= (:data saved) 42 + assert= (:states saved) + {} $ 7 $ {} (:data false) + assert= + identical? saved $ restore-store saved + , true + try + restore-store $ {} + :states $ {} + :content 42 + :data nil + fn (error) (reset! bad? true) + assert= @bad? true 'store $ %{} 'CodeEntry (:doc |) :code $ quote $ def store Store :states ({}) :content | :data nil @@ -263,7 +338,9 @@ :code $ quote $ defn updater (store op op-id op-time) match op (:states cursor s) - assert-type (update-states store cursor s) 'app.schema/Store + assoc store :states $ decode-map-as + respo.cursor/update-state-tree (:states store) cursor s + :: 'Map 'Dynamic 'Dynamic (:content data) (assoc store :content data) (:data data) (assoc store :data data) (:hydrate-storage data) data @@ -273,18 +350,12 @@ :args $ [] 'app.schema/Store 'app.schema/Op 'String 'Number :tests $ [] $ %{} 'TestEntry (:name |nominal-store-operations) :code $ quote $ let - initial $ %{} Store - :states $ {} - :content | - :data nil + initial $ Store :states ({}) :content | :data nil content-store $ updater initial (Op :content |hello) |content-op 1 data-store $ updater content-store Op :data $ {} $ :ok true , |data-op 2 - hydrated $ %{} Store - :states $ {} - :content |restored - :data 42 + hydrated $ Store :states ({}) :content |restored :data 42 assert= (assoc initial :content |hello) content-store assert= assoc content-store :data $ {} $ :ok true @@ -293,5 +364,5 @@ :ns $ %{} 'NsEntry (:doc |) :code $ quote $ ns app.updater :require - [] respo.cursor :refer $ [] update-states - app.schema :refer $ [] Op Store + respo.cursor :refer $ update-states + app.schema :refer $ Op Store diff --git a/deps.cirru b/deps.cirru index 49756ee..aee96b6 100644 --- a/deps.cirru +++ b/deps.cirru @@ -1,7 +1,7 @@ -{} (:calcit-version |0.27.0) +{} (:calcit-version |0.31.0) :version |0.1.0 - :dependencies $ {} (|Respo/reel.calcit |0.6.33-alpha.2) - |Respo/respo-ui.calcit |0.7.32-alpha.3 - |Respo/respo.calcit |0.16.114-alpha.5 - |calcit-lang/js-ffi |0.2.1-alpha.4 + :dependencies $ {} (|Respo/reel.calcit |0.7.0-alpha.1) + |Respo/respo-ui.calcit |0.9.0-alpha.1 + |Respo/respo.calcit |0.17.0-alpha.2 + |calcit-lang/js-ffi |0.2.5 diff --git a/package.json b/package.json index b55ddb6..d7c4a61 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "vite": "8.3.1" }, "dependencies": { - "@calcit/procs": "0.27.0", + "@calcit/procs": "0.31.0", "copy-text-to-clipboard": "^3.1.0", "feather-icons": "^4.29.0", "shortid": "^2.2.16" diff --git a/scripts/former-regression.test.mjs b/scripts/former-regression.test.mjs index 64411fa..0b59bb1 100644 --- a/scripts/former-regression.test.mjs +++ b/scripts/former-regression.test.mjs @@ -3,10 +3,10 @@ import test from 'node:test'; import * as c from '../js-out/calcit.core.mjs'; import { comp_live_button } from '../js-out/app.comp.button.mjs'; import { comp_container } from '../js-out/app.comp.container.mjs'; -import { store, Op } from '../js-out/app.schema.mjs'; +import { store, Op, restore_store } from '../js-out/app.schema.mjs'; import { updater } from '../js-out/app.updater.mjs'; import { detect_cdn_$q_ } from '../js-out/app.config.mjs'; -import { component_$q_, component_tree } from '../js-out/respo.util.detect.mjs'; +import { component_$q_, component_tree, as_element, element_event, element_children, child_pair_value } from '../js-out/respo.util.detect.mjs'; import { make_string } from '../js-out/respo.render.html.mjs'; const t = c.init_tags(['event', 'children', 'click', 'input', 'some', 'content', 'data', 'value', 'store', 'states', 'cursor', 'run', 'darken?']); @@ -16,16 +16,13 @@ const nth = (v, i) => c.option_$o_unwrap(c.nth(v, i)); const en = c._$n_enum_$o_nth; function handlers(node, kind, label = '', result = []) { if (component_$q_(node)) return handlers(c.option_$o_unwrap(component_tree(node)), kind, label, result); - const event = c.get(node, t.event); - if (en(event, 0) === t.some && (!label || make_string(node).includes(`>${label}<`))) { - const fn = c.get(c.option_$o_unwrap(event), kind); + const element = as_element(node); + if (!label || make_string(node).includes(`>${label}<`)) { + const fn = c.get(element_event(element), kind); if (en(fn, 0) === t.some) result.push(c.option_$o_unwrap(fn)); } - const children = c.get(node, t.children); - if (en(children, 0) === t.some) { - const pairs = c.option_$o_unwrap(children); - for (let i = 0; i < c.count(pairs); i++) handlers(nth(nth(pairs, i), 1), kind, label, result); - } + const children = element_children(element); + for (let i = 0; i < c.count(children); i++) handlers(child_pair_value(nth(children, i)), kind, label, result); return result; } function withTimer(fn) { @@ -77,6 +74,11 @@ test('missing input value is explicitly unwrapped to empty string', () => { }); test('typed hydrate-storage operation preserves the exact Store', () => { const saved = c.assoc(store, t.content, 'saved'); + assert.equal(restore_store(saved), saved); + const wire = c.parse_cirru_edn(c.format_cirru_edn(saved)); + assert.ok(c._$e_(restore_store(wire), saved)); + assert.ok(c._$e_(restore_store(map(t.states, map(), t.content, 'saved', t.data, field(saved, t.data))), saved)); + assert.throws(() => restore_store(map(t.states, map(), t.content, 42, t.data, 'saved'))); assert.ok(c._$e_(updater(store, c._PCT__$o__$o_(Op, c.newTag('hydrate-storage'), saved), 'hydrate', 1), saved)); }); test('CDN environment adapter returns a Bool and preserves exact true semantics', () => { diff --git a/yarn.lock b/yarn.lock index 99c3250..8c2d2f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,14 +5,22 @@ __metadata: version: 10 cacheKey: 10c0 -"@calcit/procs@npm:0.27.0": - version: 0.27.0 - resolution: "@calcit/procs@npm:0.27.0" +"@calcit/finger-vec@npm:0.1.1": + version: 0.1.1 + resolution: "@calcit/finger-vec@npm:0.1.1" + checksum: 10c0/c75e7f58924a7bb226ca4a47f6b0702021796b096c04d7fb7e9a92cb49b11ca64d654ea10d78bde29a8ac2d2d05ef9e7865efd2b358af2ca989d950b04d529a8 + languageName: node + linkType: hard + +"@calcit/procs@npm:0.31.0": + version: 0.31.0 + resolution: "@calcit/procs@npm:0.31.0" dependencies: + "@calcit/finger-vec": "npm:0.1.1" "@calcit/ternary-tree": "npm:0.0.26" - "@cirru/parser.ts": "npm:^0.0.9" + "@cirru/parser.ts": "npm:0.0.10" "@cirru/writer.ts": "npm:^0.1.9" - checksum: 10c0/85edf1724beaf5e3b895f456b9d81ae93100316802b19bc20ab7cbcc61e295892e787c2f9cca0c9c231ba1cc3c3d320ae158d3f8c9fd39eda24500c56ebe99b1 + checksum: 10c0/daa73d722acd302be00f5f83eb91f742025a5323fac01b84222bed0fffef688761c1285637f9d672b74c2b1bb4513b170d4b5dfcc51bd65f1396390bd526ac77 languageName: node linkType: hard @@ -23,10 +31,10 @@ __metadata: languageName: node linkType: hard -"@cirru/parser.ts@npm:^0.0.9": - version: 0.0.9 - resolution: "@cirru/parser.ts@npm:0.0.9" - checksum: 10c0/3b13623b8f627ac81adae0cb6a4e3664f0da09115a997ca9b78b8d5d0b0f9b9b18c1ad847e068831cb1052c7da2a00329d2af04421b1024a004eef0ddca5fd7a +"@cirru/parser.ts@npm:0.0.10": + version: 0.0.10 + resolution: "@cirru/parser.ts@npm:0.0.10" + checksum: 10c0/d66a16bcf49c60865fb8e733a5c219289a7c755c6400dea7e7a8d3166ee7841a623030f35f8ee96e232bc40f974f1b79a0ccdf089947fc5779699485102b5995 languageName: node linkType: hard @@ -228,7 +236,7 @@ __metadata: version: 0.0.0-use.local resolution: "data-former@workspace:." dependencies: - "@calcit/procs": "npm:0.27.0" + "@calcit/procs": "npm:0.31.0" bottom-tip: "npm:^0.1.5" copy-text-to-clipboard: "npm:^3.1.0" feather-icons: "npm:^4.29.0"