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
30 changes: 16 additions & 14 deletions .github/workflows/upload.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ on:
permissions:
contents: read

concurrency:
group: cos-upload-${{ github.repository }}-${{ github.event_name == 'pull_request' && github.run_id || 'production' }}
cancel-in-progress: false

jobs:
test:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
Expand All @@ -33,36 +37,34 @@ jobs:
corepack prepare yarn@4.18.0 --activate
yarn --version

# Current Respo modules still request preceding compatible releases, so
# strict Caps resolution rejects the highest SemVer set selected here.
- name: Install and validate dependencies
run: |
caps --ci
set -euo pipefail
caps --ci --strict
yarn install --immutable
caps verify --toolchain

- name: Validate Calcit snapshot
run: |
calcit calcit.cirru fix --workflow strict --verify --format edn
set -euo pipefail
test -f calcit.cirru
test -f deps.cirru
test ! -e compact.cirru
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-types --summary-only --format json
calcit calcit.cirru analyze weak-types --only schema-dynamic,code-dynamic --intent unresolved --summary-only --format json
calcit calcit.cirru analyze deprecated --summary-only --format json
calcit calcit.cirru analyze dynamic-methods --summary-only --format json | jq -e '.data.summary.findings == 0'

- name: Build client with CDN asset URLs
id: asset-path
env:
CDN_ORIGIN: https://cos-sh.tiye.me
PR_NUMBER: ${{ github.event.pull_request.number }}
run: |
set -euo pipefail
if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
asset_prefix="${GITHUB_REPOSITORY}/pr/"
elif [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
asset_prefix="${GITHUB_REPOSITORY}/"
asset_prefix="${GITHUB_REPOSITORY}/pr/${PR_NUMBER}/${GITHUB_RUN_ID}/"
else
asset_prefix="${GITHUB_REPOSITORY}/branches/${GITHUB_REF_NAME}/"
asset_prefix="${GITHUB_REPOSITORY}/"
fi
export VITE_BASE_URL="${CDN_ORIGIN}/${asset_prefix}"
echo "VITE_BASE_URL=${VITE_BASE_URL}" >> "$GITHUB_ENV"
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

.compact-inc.cirru
.calcit-error.cirru
compact.cirru
package.cirru

js-out/
node_modules/
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ Diffview

http://r.tiye.me/Memkits/diffview/

Use Calcit 0.27.0 and the canonical `calcit.cirru` / `deps.cirru` files.
Retired `compact.cirru` and `package.cirru` snapshots are ignored and rejected
by CI. Dependencies are resolved with `caps --ci --strict`.

The COS action verifies uploaded resources with its built-in verify settings;
no extra CDN checker is needed. Existing external fonts and server paths remain
unchanged.
Each PR run uses its own preview prefix (`pr/<number>/<run-id>/`) and concurrency
group. The six runtime checks do not claim to validate generated CDN URLs.

### Workflow

Workflow https://github.com/calcit-lang/respo-calcit-workflow
Expand Down
9 changes: 4 additions & 5 deletions calcit.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
:about "|Machine-generated snapshot. Do not edit directly — changes will be overwritten. Use `calcit query` to inspect and `calcit edit`/`calcit tree` to modify. Run `calcit docs agents --contract` before mutations; use `--full` for first orientation or changed contract digest. Manual edits must follow format and schema conventions, then run `calcit edit format`."
:package |app
:entries $ {} $ :default
{} (:description |) (:init-fn 'app.main/main!) (:mode :native) (:reload-fn 'app.main/reload!)
{} (:description |) (:init-fn 'app.main/main!) (:mode :js) (:reload-fn 'app.main/reload!) (:target :browser)
:feature-policy $ {}
:modules $ [] |respo.calcit/ |respo-ui.calcit/ |respo-markdown.calcit/ |reel.calcit/ |js-ffi/
:modules $ [] |respo.calcit/ |respo-ui.calcit/ |reel.calcit/ |js-ffi/
:type-slots $ {}
:files $ {}
'app.comp.container $ %{} 'FileEntry
Expand Down Expand Up @@ -84,11 +84,11 @@
[] idx $ let
tok $ :value chunk
cond
option:some? $ :removed chunk
option:unwrap-or (:removed chunk) false
div $ {} (:inner-text tok)
:class-name $ str-spaced style-line style-removed $ if by-word? style-word-mode
:title $ str "|Removed " (:count chunk) "| chunks"
(option:some? (:added chunk))
(option:unwrap-or (:added chunk) false)
div $ {} (:inner-text tok)
:class-name $ str-spaced style-line style-added $ if by-word? style-word-mode
:title $ str "|Added " (:count chunk) "| chunks"
Expand Down Expand Up @@ -198,7 +198,6 @@
respo.comp.inspect :refer $ comp-inspect
reel.comp.reel :refer $ comp-reel
reel.schema :as reel-schema
respo-md.comp.md :refer $ comp-md
app.config :refer $ dev?
|diff :as diff
'app.config $ %{} 'FileEntry
Expand Down
5 changes: 2 additions & 3 deletions deps.cirru
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

{} (:calcit-version |0.27.0)
:version |0.1.3
:dependencies $ {} (|Respo/reel.calcit |0.6.33-alpha.1)
|Respo/respo-markdown.calcit |0.4.46
|Respo/respo-ui.calcit |0.7.32-alpha.2
: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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"packageManager": "yarn@4.18.0",
"devDependencies": {
"bottom-tip": "^0.1.5",
"vite": "^7.3.1"
"vite": "8.3.1"
},
"dependencies": {
"@calcit/procs": "0.27.0",
Expand Down
85 changes: 85 additions & 0 deletions scripts/upgrade.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,33 @@ import { assoc, init_tags } from "../js-out/calcit.core.mjs";
import { comp_container } from "../js-out/app.comp.container.mjs";
import { store as defaultStore } from "../js-out/app.schema.mjs";
import { reel as reelSchema } from "../js-out/reel.schema.mjs";
import * as clt from "../js-out/calcit.core.mjs";
import { updater } from "../js-out/app.updater.mjs";
import { sort_by_line } from "../js-out/app.comp.container.mjs";
import { make_string } from "../js-out/respo.render.html.mjs";
import { component_$q_, component_tree } from "../js-out/respo.util.detect.mjs";

const t = init_tags(["base", "store", "states", "old-text", "new-text", "show-result?", "sorted?", "by-word?", "children", "event", "input", "click", "value", "data", "editor"]);
const unwrap = clt.option_$o_unwrap;
const read = (value, key) => unwrap(clt.get(value, key));
const op = (name, ...args) => clt._$o__$o_(init_tags([name])[name], ...args);
const apply = (store, name, ...args) => updater(store, op(name, ...args), "test", 0);
const render = (store) => comp_container(assoc(assoc(reelSchema, t.base, store), t.store, store));

function handlers(node, kind) {
if (component_$q_(node)) return handlers(unwrap(component_tree(node)), kind);
const result = [];
const events = clt.get(node, t.event);
if (clt.option_$o_some_$q_(events)) {
const handler = clt.get(unwrap(events), kind);
if (clt.option_$o_some_$q_(handler)) result.push(unwrap(handler));
}
const children = clt.get(node, t.children);
if (clt.option_$o_some_$q_(children)) {
for (const pair of unwrap(children).toArray()) result.push(...handlers(unwrap(clt.nth(pair, 1)), kind));
}
return result;
}

test("npm diff chunks decode into typed Calcit data", () => {
const tags = init_tags(["base", "new-text", "old-text", "store"]);
Expand All @@ -17,3 +44,61 @@ test("npm diff chunks decode into typed Calcit data", () => {

assert.ok(comp_container(reel));
});

test("line and word differences render added and removed content", () => {
Comment thread
tiye marked this conversation as resolved.
for (const words of [false, true]) {
const store = assoc(assoc(assoc(assoc(defaultStore, t["old-text"], "one two"), t["new-text"], "one three"), t["show-result?"], true), t["by-word?"], words);
const html = make_string(render(store));
assert.match(html, /Removed/);
assert.match(html, /Added/);
assert.match(html, /two/);
assert.match(html, /three/);
}
});

test("textarea callbacks dispatch one Enum and preserve missing-value fallback", () => {
const inputs = handlers(render(defaultStore), t.input);
assert.equal(inputs.length, 2);
for (const [index, handler] of inputs.entries()) {
let store = defaultStore;
const dispatch = (...args) => {
assert.equal(args.length, 1);
store = updater(store, args[0], "test", 0);
};
handler(clt._$n__$M_(t.value, `text-${index}`), dispatch);
const field = index === 0 ? t["old-text"] : t["new-text"];
assert.equal(read(store, field), `text-${index}`);
handler(clt._$n__$M_(), dispatch);
assert.equal(read(store, field), "");
}
});

test("toggle, swap and clear operations preserve their intended fields", () => {
let store = apply(apply(defaultStore, "write-old", "before"), "write-new", "after");
for (const [operation, field] of [["toggle-result", "show-result?"], ["toggle-sorted", "sorted?"], ["toggle-word", "by-word?"]]) {
store = apply(store, operation);
assert.equal(read(store, t[field]), true);
}
store = apply(store, "swap-text");
assert.equal(read(store, t["old-text"]), "after");
assert.equal(read(store, t["new-text"]), "before");
store = apply(store, "clear-text");
assert.equal(read(store, t["old-text"]), "");
assert.equal(read(store, t["new-text"]), "");
assert.equal(read(store, t["show-result?"]), false);
assert.equal(read(store, t["sorted?"]), true);
});

test("sorting lines makes reordered texts equivalent", () => {
assert.equal(sort_by_line("z\na"), sort_by_line("a\nz"));
const store = assoc(assoc(assoc(assoc(defaultStore, t["old-text"], "z\na"), t["new-text"], "a\nz"), t["show-result?"], true), t["sorted?"], true);
const html = make_string(render(store));
assert.doesNotMatch(html, /Added|Removed/);
});

test("nested states update preserves application text", () => {
const original = apply(defaultStore, "write-old", "untouched");
const changed = apply(original, "states", clt._$L_(t.editor), "nested");
assert.equal(read(changed, t["old-text"]), "untouched");
assert.equal(read(read(read(changed, t.states), t.editor), t.data), "nested");
});
Loading