From 268e91cd5d56670b192c5181c30d5b4179e1b8b2 Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 29 Jun 2026 19:53:20 +0000 Subject: [PATCH] host: relate/unrelate keep both lists in sync (add to current list, never blank the picker) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two reported bugs on the edit page's relation editor: 1. relating a candidate didn't add it to the current-relations list (the AJAX relate just deleted the candidate row; the relation only showed after a reload); 2. removing a relation could blank the relate picker. Fix (lib/host/blog.sx): both the candidate's relate form and a current relation's remove form now target #rel-editor- with sx-swap=outerHTML, and the relate/unrelate handlers return the re-rendered editor for that kind (current list + a fresh picker). So one swap keeps BOTH lists in sync: the related post moves into the current list and out of the (re-loaded) candidate pool; removing moves it back. Gated on the SX-Target header, so a plain boosted form / no-JS POST (the is-a-tag toggle) still redirects + re-renders #content. Engine fix (web/orchestration.sx): handle-html-response's non-select branch called post-swap on the OLD target, which an outerHTML swap has already REPLACED — so the swapped-in content's triggers (here the re-rendered picker's "load") never bound and the picker stayed empty. post-swap the swap result (the new node), mirroring the sx-select branch. Recompiled orchestration.sxbc for the content-addressed client. Tests: - web/tests/test-relate-picker.sx: relating re-syncs the editor (post in current list + picker re-loads); removing does likewise — both fail without the engine fix. - lib/host/tests/blog.sx: relate/unrelate return the re-rendered editor fragment (200, #rel-editor + picker), forms wire to #rel-editor-KIND/outerHTML, plain boosted POST still 303. - relate-picker.spec.js: the full in-page flow (relate adds to list, remove keeps the picker, no reload) + persistence. Verified: host conformance 277/277, web engine suite 8/8, run-picker-check 3/3, run-spa-check 3/3. Co-Authored-By: Claude Opus 4.8 --- lib/host/blog.sx | 77 +++++++----- lib/host/playwright/relate-picker.spec.js | 53 +++++--- lib/host/tests/blog.sx | 67 +++++++--- shared/static/wasm/sx/orchestration.sx | 18 ++- shared/static/wasm/sx/orchestration.sxbc | 4 +- web/orchestration.sx | 18 ++- web/tests/test-relate-picker.sx | 146 +++++++++++++--------- 7 files changed, 248 insertions(+), 135 deletions(-) diff --git a/lib/host/blog.sx b/lib/host/blog.sx index 5343eb53..528b1c79 100644 --- a/lib/host/blog.sx +++ b/lib/host/blog.sx @@ -364,16 +364,18 @@ (quasiquote (li :id (unquote (str "cand-" kind "-" (get p :slug))) :style "border-bottom:1px solid #eee" - ;; AJAX relate: sx-post the relation, then sx-swap="delete" removes THIS - ;; candidate row (its sx-target) — it's now related, so it leaves the pool - ;; without a reload or a list refetch. method+action stay for the no-JS - ;; fallback (plain POST -> 303 -> reload); the engine prevents the double - ;; submit when it handles sx-post. + ;; AJAX relate: sx-post the relation, then sx-swap="outerHTML" re-renders the + ;; WHOLE relation editor for this kind (its sx-target #rel-editor-KIND) — the + ;; just-related post moves into the current-relations list and out of the + ;; candidate pool, and the fresh picker re-loads its candidates. (A bare + ;; delete of this row added the relation server-side but never showed it in + ;; the current list; re-rendering the editor keeps BOTH lists in sync.) + ;; method+action stay for the no-JS fallback (plain POST -> 303 -> reload). (form :method "post" :style "margin:0" :action (unquote (str "/" slug "/relate")) :sx-post (unquote (str "/" slug "/relate")) - :sx-target (unquote (str "#cand-" kind "-" (get p :slug))) - :sx-swap "delete" + :sx-target (unquote (str "#rel-editor-" kind)) + :sx-swap "outerHTML" (input :type "hidden" :name "other" :value (unquote (get p :slug))) (input :type "hidden" :name "kind" :value (unquote kind)) (button :type "submit" @@ -434,11 +436,12 @@ ;; so the blog degrades gracefully to plain server-rendered pages. (define host/blog--spa-req? (fn (req) (= (dream-header req "sx-request") "true"))) -;; An AJAX in-place row delete vs. a plain boosted form. The engine sends an -;; SX-Target header for an sx-post form (the relation-editor's remove button, -;; sx-target=#cur-…), but NOT for a plain boosted form (the is-a-tag toggle). So -;; this tells "delete just this row, empty 200" apart from "redirect + re-render". -(define host/blog--row-swap-req? +;; An AJAX editor swap (the picker's relate / the editor's remove) vs. a plain +;; boosted form. The engine sends an SX-Target header for an sx-post form +;; (sx-target=#rel-editor-…), but NOT for a plain boosted form (the is-a-tag +;; toggle). So this tells "return the re-rendered editor fragment" apart from +;; "redirect + re-render #content" (the toggle / no-JS path). +(define host/blog--editor-swap-req? (fn (req) (and (host/blog--spa-req? req) (let ((t (dream-header req "sx-target"))) (and t (not (= t ""))))))) @@ -591,25 +594,30 @@ (let ((spec (host/blog--kind-spec kind)) (current (host/blog-out slug kind))) (quasiquote - (div :style "margin-top:2em;border-top:1px solid #ccc;padding-top:1em" + ;; #rel-editor-KIND wraps the WHOLE editor (current list + picker) so relate + ;; and unrelate can re-render it with one outerHTML swap — keeping the two + ;; lists in sync. The fresh picker re-loads its candidates (an explicit + ;; outerHTML swap installs a NEW form the engine binds, unlike the old + ;; redirect that morphed the stale picker and left it empty). + (div :id (unquote (str "rel-editor-" kind)) + :style "margin-top:2em;border-top:1px solid #ccc;padding-top:1em" (h3 (unquote (get spec :label))) (unquote (if (> (len current) 0) (cons (quote ul) (map (fn (s) (quasiquote - ;; AJAX unrelate: sx-post the removal, then sx-swap="delete" - ;; removes just THIS current-relation row (its sx-target) in - ;; place — NO #content re-render, so the relate picker (the - ;; "posts to relate" list) is left untouched. method+action - ;; stay for the no-JS fallback (plain POST -> 303 -> reload). - (li :id (unquote (str "cur-" kind "-" s)) - (a :href (unquote (str "/" s "/")) (unquote s)) " " + ;; remove: sx-post the unrelate, then sx-swap="outerHTML" + ;; re-renders this kind's editor (its sx-target + ;; #rel-editor-KIND) — the row leaves the current list and + ;; the post returns to the candidate pool, both in sync, + ;; with the picker NOT cleared. method+action stay for no-JS. + (li (a :href (unquote (str "/" s "/")) (unquote s)) " " (form :method "post" :style "display:inline" :action (unquote (str "/" slug "/unrelate")) :sx-post (unquote (str "/" slug "/unrelate")) - :sx-target (unquote (str "#cur-" kind "-" s)) - :sx-swap "delete" + :sx-target (unquote (str "#rel-editor-" kind)) + :sx-swap "outerHTML" (input :type "hidden" :name "other" :value (unquote s)) (input :type "hidden" :name "kind" :value (unquote kind)) (button :type "submit" "remove"))))) @@ -889,11 +897,13 @@ (when (and other (not (= other "")) (not (= other slug)) (host/blog--kind-spec kind) (host/blog-exists? other)) (host/blog-relate! slug other kind)) - ;; AJAX (the picker's sx-post): return an empty 200 so the candidate - ;; form's sx-swap="delete" removes just that one row — no full reload, - ;; no candidate-list refetch. Plain POST (no-JS) still redirects. - (if (host/blog--spa-req? req) - (dream-html "") + ;; AJAX (the picker's sx-post, carries SX-Target): return the re-rendered + ;; editor for this kind so its sx-swap="outerHTML" replaces #rel-editor-KIND + ;; — the just-related post shows in the current list and the picker refreshes + ;; its candidates. text/html so the client's DOMParser swap path renders the + ;; already-expanded fragment. Plain boosted form / no-JS still redirects. + (if (host/blog--editor-swap-req? req) + (dream-html (render-page (host/blog--relation-editor slug kind))) (dream-redirect (str "/" slug "/edit")))))))) ;; POST //unrelate — remove the relation to `other` under `kind` (default @@ -906,12 +916,13 @@ (begin (when (and other (not (= other "")) (host/blog--kind-spec kind)) (host/blog-unrelate! slug other kind)) - ;; AJAX in-place remove (the editor's sx-post, carries SX-Target): return an - ;; empty 200 so the current-relation row's sx-swap="delete" removes just that - ;; one row — no #content re-render, so the relate picker is untouched. A plain - ;; boosted form (the tag toggle) or a no-JS POST still redirects + re-renders. - (if (host/blog--row-swap-req? req) - (dream-html "") + ;; AJAX remove (the editor's sx-post, carries SX-Target): return the + ;; re-rendered editor for this kind so its sx-swap="outerHTML" replaces + ;; #rel-editor-KIND — the row leaves the current list, the post returns to the + ;; (re-loaded) candidate pool, and the picker is NOT cleared. A plain boosted + ;; form (the tag toggle) or a no-JS POST still redirects + re-renders #content. + (if (host/blog--editor-swap-req? req) + (dream-html (render-page (host/blog--relation-editor slug kind))) (dream-redirect (str "/" slug "/edit"))))))) ;; GET //edit — edit form pre-filled with the post's current title, raw diff --git a/lib/host/playwright/relate-picker.spec.js b/lib/host/playwright/relate-picker.spec.js index b7304168..dd331c71 100644 --- a/lib/host/playwright/relate-picker.spec.js +++ b/lib/host/playwright/relate-picker.spec.js @@ -50,28 +50,53 @@ async function login(page) { } test.describe('relate picker (browser-only)', () => { - test('the remove button on a current relation actually unrelates it', async ({ page }) => { + test('relating a candidate adds it to the current list AND removing keeps the picker', async ({ page }) => { + // The whole in-page flow the user reported broken — no reloads. Relating a + // candidate re-renders the editor: the post moves into the current-relations + // list and the picker re-loads its candidates (it is NOT blanked). Removing it + // re-renders the editor back: the post leaves the current list and the picker + // still offers candidates. test.setTimeout(75000); await loginTo(page, `/${HOST}/edit`); await waitReady(page); - // relate Item 13 via the picker, then reload so it shows in the current list + await page.evaluate(() => { window.__noReload = true; }); + // relate Item 13 from the picker await page.fill(RELF, 'Item 13'); await expect.poll(() => page.locator(RELROWS).count(), { timeout: 10000 }).toBe(1); await page.locator(`${RELROWS} button`).first().click(); - await expect.poll(() => page.locator(RELROWS).count(), { timeout: 10000 }).toBe(0); + const relLink = page.locator('a[href="/picker-item-13/"]'); + // ISSUE 1: it now appears in the CURRENT relations list (added, not just removed) + await expect(relLink).toHaveCount(1, { timeout: 12000 }); + // and the re-rendered picker still offers candidates (not blanked) + await expect.poll(() => page.locator(RELROWS).count(), { timeout: 12000 }).toBeGreaterThan(0); + // now remove it via its current-list remove button + await page.locator('li:has(a[href="/picker-item-13/"]) button').click(); + await expect(relLink).toHaveCount(0, { timeout: 12000 }); // left the current list + // ISSUE 2: removing must NOT clear "the list of posts to relate" + await expect.poll(() => page.locator(RELROWS).count(), { timeout: 12000 }).toBeGreaterThan(0); + expect(await page.evaluate(() => window.__noReload)).toBe(true); // all in-page, no reload + // and the relation truly persisted gone (reload shows it not present) await page.reload(); await waitReady(page); - const relLink = page.locator('a[href="/picker-item-13/"]'); - await expect(relLink).toHaveCount(1); // current relation present - // the picker is populated (empty filter -> first page of candidates) - await expect.poll(() => page.locator(RELROWS).count(), { timeout: 12000 }).toBeGreaterThan(0); - // click its remove button - await page.locator('li:has(a[href="/picker-item-13/"]) button').click(); - await expect(relLink).toHaveCount(0, { timeout: 12000 }); // relation removed - // REGRESSION: removing a relation must NOT clear "the list of posts to relate". - // (The old plain-boosted remove form redirected -> re-rendered #content and the - // picker came back empty; the AJAX in-place remove leaves the picker untouched.) - await expect.poll(() => page.locator(RELROWS).count(), { timeout: 12000 }).toBeGreaterThan(0); + await expect(page.locator('a[href="/picker-item-13/"]')).toHaveCount(0); + }); + + test('relating a candidate persists the relation', async ({ page }) => { + test.setTimeout(75000); + await loginTo(page, `/${HOST}/edit`); + await waitReady(page); + await page.fill(RELF, 'Item 07'); + await expect.poll(() => page.locator(RELROWS).count(), { timeout: 10000 }).toBe(1); + await page.locator(`${RELROWS} button`).first().click(); + await expect(page.locator('a[href="/picker-item-07/"]')).toHaveCount(1, { timeout: 12000 }); + // persisted across a reload + await page.reload(); + await waitReady(page); + await expect(page.locator('a[href="/picker-item-07/"]')).toHaveCount(1); + // and visible on the public post page + await page.goto(`/${HOST}/`); + await expect(page.getByRole('heading', { name: 'Related posts' })).toBeVisible(); + await expect(page.locator('body')).toContainText('Picker Item 07'); }); test('picker populates after a boosted SPA nav to the edit page', async ({ page }) => { diff --git a/lib/host/tests/blog.sx b/lib/host/tests/blog.sx index a3dee264..72f3cb30 100644 --- a/lib/host/tests/blog.sx +++ b/lib/host/tests/blog.sx @@ -296,34 +296,63 @@ (contains? (dream-resp-body (host-bl-app (host-bl-req "/alpha-post/relate-options"))) "rp-more") false) -;; -- unrelate: AJAX in-place row delete (regression: removing a related post must -;; NOT clear the relate picker). The remove button is now an sx-post form that -;; deletes just its own current-relation row (sx-target=#cur-…, sx-swap=delete), -;; so #content is never re-rendered and the picker is left intact. -- +;; -- relate / unrelate keep BOTH lists in sync by re-rendering the kind's editor. +;; Regressions: (1) relating a candidate must ADD it to the current-relations +;; list (not just delete the candidate row); (2) removing must NOT clear the +;; relate picker. Both the candidate's relate form and the remove form target +;; #rel-editor-KIND with sx-swap=outerHTML; the handler returns the re-rendered +;; editor, so the current list updates and the fresh picker re-loads. -- (host/blog-relate! "alpha-post" "beta-post" "related") -(host-bl-test "relation-editor remove button is an AJAX in-place delete" +;; the editor wraps current list + picker in #rel-editor-KIND; remove re-renders it +(host-bl-test "relation-editor wires remove to re-render the kind's editor" (let ((html (render-page (host/blog--relation-editor "alpha-post" "related")))) - (list (contains? html "id=\"cur-related-beta-post\"") ;; row has a target id + (list (contains? html "id=\"rel-editor-related\"") ;; the swap target (contains? html "sx-post=\"/alpha-post/unrelate\"") ;; AJAX, not plain post - (contains? html "sx-target=\"#cur-related-beta-post\"") - (contains? html "sx-swap=\"delete\""))) + (contains? html "sx-target=\"#rel-editor-related\"") + (contains? html "sx-swap=\"outerHTML\""))) (list true true true true)) -;; the AJAX remove (carries SX-Target) returns an empty 200 so only the row is -;; swapped out — no redirect, no #content re-render that would blank the picker. -(host-bl-test "unrelate (AJAX, SX-Target) returns an empty 200" +;; the candidate's relate form targets the SAME editor (so relating re-renders it) +(host-bl-test "picker candidate relate form re-renders the kind's editor" + (let ((html (render-page (host/blog--picker-item "alpha-post" {:slug "gamma-post" :title "Gamma"} "related")))) + (list (contains? html "sx-post=\"/alpha-post/relate\"") + (contains? html "sx-target=\"#rel-editor-related\"") + (contains? html "sx-swap=\"outerHTML\""))) + (list true true true)) +;; a POST request to a /:slug/… route, with the :slug route param populated (which +;; the route matcher would set) plus headers + a form body. +(define host-bl-relreq + (fn (slug action headers other kind) + (merge (dream-request "POST" (str "/" slug "/" action) headers + (str "other=" other "&kind=" kind)) + {:params {:slug slug}}))) +;; the AJAX remove (carries SX-Target) returns the re-rendered editor fragment (200, +;; with the #rel-editor wrapper + the picker) — not an empty body or a redirect. +(host-bl-test "unrelate (AJAX, SX-Target) returns the re-rendered editor fragment" (let ((resp (host/blog-unrelate-submit - (dream-request "POST" "/alpha-post/unrelate" - {:sx-request "true" :sx-target "#cur-related-beta-post"} - "other=beta-post&kind=related")))) - (list (dream-status resp) (dream-resp-body resp))) - (list 200 "")) + (host-bl-relreq "alpha-post" "unrelate" + {:sx-request "true" :sx-target "#rel-editor-related"} + "beta-post" "related")))) + (list (dream-status resp) + (contains? (dream-resp-body resp) "rel-editor-related") + (contains? (dream-resp-body resp) "relate-picker"))) + (list 200 true true)) +;; relate (AJAX, SX-Target) likewise returns the editor with the new relation listed +(host/blog-unrelate! "alpha-post" "gamma-post" "related") ;; clean state +(host-bl-test "relate (AJAX, SX-Target) returns the editor showing the new relation" + (let ((resp (host/blog-relate-submit + (host-bl-relreq "alpha-post" "relate" + {:sx-request "true" :sx-target "#rel-editor-related"} + "gamma-post" "related")))) + (list (dream-status resp) + (contains? (dream-resp-body resp) "/gamma-post/"))) ;; now in the current list + (list 200 true)) +(host/blog-unrelate! "alpha-post" "gamma-post" "related") ;; a plain boosted form / no-JS POST (no SX-Target) still redirects + re-renders, ;; so the is-a-tag toggle and graceful degradation are unaffected. -(host/blog-relate! "alpha-post" "beta-post" "related") (host-bl-test "unrelate (plain boosted / no-JS, no SX-Target) still redirects" (dream-status (host/blog-unrelate-submit - (dream-request "POST" "/alpha-post/unrelate" - {:sx-request "true"} "other=beta-post&kind=related"))) + (host-bl-relreq "alpha-post" "unrelate" + {:sx-request "true"} "beta-post" "related"))) 303) (host/blog-unrelate! "alpha-post" "beta-post" "related") (host/blog-put! "hint-post" "Hint Post" "(p \"h\")" "published") diff --git a/shared/static/wasm/sx/orchestration.sx b/shared/static/wasm/sx/orchestration.sx index fb16dc4c..b6246344 100644 --- a/shared/static/wasm/sx/orchestration.sx +++ b/shared/static/wasm/sx/orchestration.sx @@ -467,11 +467,19 @@ use-transition (fn () - (swap-dom-nodes - target - (children-to-fragment container) - swap-style) - (post-swap target)))))))))) + ;; post-swap the NEW node, not the old target — an outerHTML + ;; swap REPLACES target, so processing target would re-bind a + ;; detached node and leave the swapped-in content's triggers + ;; (e.g. a re-rendered picker's "load") unbound. Mirrors the + ;; sx-select branch above. For innerHTML swap-root falls back + ;; to target (still in the document). + (let + ((swap-root + (swap-dom-nodes + target + (children-to-fragment container) + swap-style))) + (post-swap (or swap-root target)))))))))))) (define handle-retry :effects (mutation io) diff --git a/shared/static/wasm/sx/orchestration.sxbc b/shared/static/wasm/sx/orchestration.sxbc index 008eefbb..2a13fa01 100644 --- a/shared/static/wasm/sx/orchestration.sxbc +++ b/shared/static/wasm/sx/orchestration.sxbc @@ -1,3 +1,3 @@ -(sxbc 1 "60f84680701b46f1" +(sxbc 1 "1b7458d4b0e096e7" (code - :constants ("_preload-cache" "dict" "dispatch-trigger-events" {:upvalue-count 0 :arity 2 :constants ("try-parse-json" {:upvalue-count 2 :arity 1 :constants ("dom-dispatch" "get") :bytecode (20 0 0 18 0 16 0 18 1 16 0 52 1 0 2 49 3 50)} "keys" "for-each" {:upvalue-count 1 :arity 1 :constants ("trim" "empty?" "dom-dispatch" "dict") :bytecode (16 0 52 0 0 1 17 1 16 1 52 1 0 1 167 33 16 0 20 2 0 18 0 16 1 52 3 0 0 49 3 32 1 0 2 50)} "," "split") :bytecode (16 1 33 55 0 20 0 0 16 1 48 1 17 2 16 2 33 20 0 51 1 0 1 0 1 2 16 2 52 2 0 1 52 3 0 2 32 18 0 51 4 0 1 0 16 1 1 5 0 52 6 0 2 52 3 0 2 32 1 0 2 50)} "execute-request" {:upvalue-count 0 :arity 3 :constants ("get-verb-info" "nil?" "promise-resolve" "method" "get" "url" "dom-get-attr" "sx-media" "browser-media-matches?" "sx-confirm" "browser-confirm" "sx-prompt" "browser-prompt" "validate-for-request" "do-fetch" "dict" "SX-Prompt" "assoc") :bytecode (20 0 0 16 0 48 1 6 34 3 0 5 16 1 17 3 16 3 52 1 0 1 33 9 0 20 2 0 2 49 1 32 240 0 16 3 1 3 0 52 4 0 2 17 4 16 3 1 5 0 52 4 0 2 17 5 20 6 0 16 0 1 7 0 48 2 17 6 16 6 6 33 9 0 5 20 8 0 16 6 48 1 167 33 9 0 20 2 0 2 49 1 32 179 0 20 6 0 16 0 1 9 0 48 2 17 6 16 6 6 33 9 0 5 20 10 0 16 6 48 1 167 33 9 0 20 2 0 2 49 1 32 140 0 20 6 0 16 0 1 11 0 48 2 17 6 16 6 33 10 0 20 12 0 16 6 48 1 32 1 0 2 17 7 16 6 6 33 7 0 5 16 7 52 1 0 1 33 9 0 20 2 0 2 49 1 32 85 0 16 4 52 1 0 1 6 34 20 0 5 16 5 52 1 0 1 6 34 9 0 5 20 13 0 16 0 48 1 167 33 9 0 20 2 0 2 49 1 32 43 0 20 14 0 16 0 16 4 16 4 16 5 16 7 33 23 0 16 2 6 34 5 0 5 52 15 0 0 1 16 0 16 7 52 17 0 3 32 2 0 16 2 49 5 50)} "do-fetch" {:upvalue-count 0 :arity 5 :constants ("dom-get-attr" "sx-sync" "replace" "abort-previous" "resolve-target" "identical?" "abort-previous-target" "new-abort-controller" "track-controller" "track-controller-target" "build-request-body" "url" "get" "body" "content-type" "build-request-headers" "loaded-component-names" "csrf-token" {:upvalue-count 2 :arity 1 :constants ("get" "dict-set!") :bytecode (18 0 16 0 18 1 16 0 52 0 0 2 52 1 0 3 50)} "keys" "for-each" "Content-Type" "dict-set!" "X-CSRFToken" "preload-cache-get" "_preload-cache" "apply-optimistic" "show-indicator" "disable-elements" "dom-add-class" "sx-request" "dom-set-attr" "aria-busy" "true" "dom-dispatch" "sx:beforeRequest" "method" "dict" "fetch-request" "headers" "signal" "controller-signal" "cross-origin" "cross-origin?" "preloaded" {:upvalue-count 8 :arity 4 :constants ("clear-loading-state" "revert-optimistic" "dom-dispatch" "sx:responseError" "status" "text" "dict" "dom-add-class" "sx-error" 0 "handle-fetch-success" "handle-retry" "sx:afterRequest") :bytecode (20 0 0 18 0 18 1 18 2 48 3 5 20 1 0 18 3 48 1 5 16 0 167 33 91 0 20 2 0 18 0 1 3 0 1 4 0 16 1 1 5 0 16 3 52 6 0 4 48 3 5 20 7 0 18 0 1 8 0 48 2 5 16 3 6 33 8 0 5 16 3 168 1 9 0 166 33 20 0 20 10 0 18 0 18 4 18 5 18 6 16 2 16 3 49 6 32 15 0 20 11 0 18 0 18 5 18 7 18 4 18 6 49 5 32 37 0 20 2 0 18 0 1 12 0 1 4 0 16 1 52 6 0 2 48 3 5 20 10 0 18 0 18 4 18 5 18 6 16 2 16 3 49 6 50)} {:upvalue-count 8 :arity 1 :constants ("clear-loading-state" "revert-optimistic" "abort-error?" "log-warn" "sx:fetch error " " " " — " "str" "dom-dispatch" "sx:requestError" "error" "dict" "dom-add-class" "sx-error" "handle-retry") :bytecode (20 0 0 18 0 18 1 18 2 48 3 5 20 1 0 18 3 48 1 5 20 2 0 16 0 48 1 167 33 74 0 20 3 0 1 4 0 18 4 1 5 0 18 5 1 6 0 16 0 52 7 0 6 48 1 5 20 8 0 18 0 1 9 0 1 10 0 16 0 52 11 0 2 48 3 5 20 12 0 18 0 1 13 0 48 2 5 20 14 0 18 0 18 6 18 4 18 5 18 7 49 5 32 1 0 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 5 16 5 1 2 0 164 33 10 0 20 3 0 16 0 48 1 32 1 0 2 5 20 4 0 16 0 48 1 17 6 16 6 6 33 10 0 5 16 0 16 6 52 5 0 2 167 33 10 0 20 6 0 16 6 48 1 32 1 0 2 5 20 7 0 48 0 17 6 20 8 0 16 0 16 6 48 2 5 20 4 0 16 0 48 1 17 7 16 7 33 12 0 20 9 0 16 7 16 6 48 2 32 1 0 2 5 20 10 0 16 0 16 2 16 3 48 3 17 7 16 7 1 11 0 52 12 0 2 17 8 16 7 1 13 0 52 12 0 2 17 9 16 7 1 14 0 52 12 0 2 17 10 20 15 0 16 0 20 16 0 48 0 48 2 17 11 20 17 0 48 0 17 12 16 4 33 20 0 51 18 0 1 11 1 4 16 4 52 19 0 1 52 20 0 2 32 1 0 2 5 16 10 33 14 0 16 11 1 21 0 16 10 52 22 0 3 32 1 0 2 5 16 12 33 14 0 16 11 1 23 0 16 12 52 22 0 3 32 1 0 2 5 20 24 0 20 25 0 16 8 48 2 17 13 20 26 0 16 0 48 1 17 14 20 27 0 16 0 48 1 17 15 20 28 0 16 0 48 1 17 16 20 29 0 16 0 1 30 0 48 2 5 20 31 0 16 0 1 32 0 1 33 0 48 3 5 20 34 0 16 0 1 35 0 1 11 0 16 8 1 36 0 16 2 52 37 0 4 48 3 5 20 38 0 1 11 0 16 8 1 36 0 16 2 1 39 0 16 11 1 13 0 16 9 1 40 0 20 41 0 16 6 48 1 1 42 0 20 43 0 16 8 48 1 1 44 0 16 13 52 37 0 14 51 45 0 1 0 1 15 1 16 1 14 1 8 1 1 1 4 1 2 51 46 0 1 0 1 15 1 16 1 14 1 2 1 8 1 1 1 4 49 3 50)} "handle-fetch-success" {:upvalue-count 0 :arity 6 :constants ("process-response-headers" "dom-remove-class" "sx-error" "dom-remove-attr" "data-sx-retry-ms" "dispatch-trigger-events" "trigger" "get" "process-cache-directives" "redirect" "browser-navigate" "refresh" "browser-reload" "location" "fetch-location" "retarget" "dom-query" "resolve-target" "parse-swap-spec" "reswap" "dom-get-attr" "sx-swap" "dom-has-class?" "dom-body" "sx-transitions" "style" "transition" "content-type" "" "text/sx" "contains?" "handle-sx-response" "handle-html-response" "trigger-swap" "handle-history" "set-timeout" {:upvalue-count 2 :arity 0 :constants ("trigger-settle" "get" "dispatch-trigger-events" "process-settle-hooks") :bytecode (18 0 1 0 0 52 1 0 2 33 19 0 20 2 0 18 1 18 0 1 0 0 52 1 0 2 48 2 32 1 0 2 5 20 3 0 18 1 49 1 50)} 20 "dom-dispatch" "sx:afterSwap" "target" "swap" "dict") :bytecode (20 0 0 16 4 48 1 17 6 20 1 0 16 0 1 2 0 48 2 5 20 3 0 16 0 1 4 0 48 2 5 20 5 0 16 0 16 6 1 6 0 52 7 0 2 48 2 5 20 8 0 16 0 16 6 16 5 48 3 5 16 6 1 9 0 52 7 0 2 33 17 0 20 10 0 16 6 1 9 0 52 7 0 2 49 1 32 31 1 16 6 1 11 0 52 7 0 2 33 8 0 20 12 0 49 0 32 11 1 16 6 1 13 0 52 7 0 2 33 17 0 20 14 0 16 6 1 13 0 52 7 0 2 49 1 32 238 0 16 6 1 15 0 52 7 0 2 33 17 0 20 16 0 16 6 1 15 0 52 7 0 2 48 1 32 7 0 20 17 0 16 0 48 1 17 7 20 18 0 16 6 1 19 0 52 7 0 2 6 34 11 0 5 20 20 0 16 0 1 21 0 48 2 20 22 0 20 23 0 48 0 1 24 0 48 2 48 2 17 8 16 8 1 25 0 52 7 0 2 17 9 16 8 1 26 0 52 7 0 2 17 10 16 6 1 27 0 52 7 0 2 6 34 4 0 5 1 28 0 17 11 16 11 1 29 0 52 30 0 2 33 18 0 20 31 0 16 0 16 7 16 5 16 9 16 10 48 5 32 15 0 20 32 0 16 0 16 7 16 5 16 9 16 10 48 5 5 20 5 0 16 0 16 6 1 33 0 52 7 0 2 48 2 5 20 34 0 16 0 16 1 16 6 48 3 5 20 35 0 51 36 0 1 6 1 0 1 37 0 48 2 5 20 38 0 16 0 1 39 0 1 40 0 16 7 1 41 0 16 9 52 42 0 4 49 3 50)} "flush-collected-styles" {:upvalue-count 0 :arity 0 :constants ("cssx" "collected" "empty?" "clear-collected!" "dom-create-element" "style" "dom-set-attr" "data-sx-css" "true" "dom-set-prop" "textContent" "" "join" "dom-append-to-head") :bytecode (1 0 0 52 1 0 1 17 0 16 0 52 2 0 1 167 33 63 0 1 0 0 52 3 0 1 5 20 4 0 1 5 0 2 48 2 17 1 20 6 0 16 1 1 7 0 1 8 0 48 3 5 20 9 0 16 1 1 10 0 1 11 0 16 0 52 12 0 2 48 3 5 20 13 0 16 1 49 1 32 1 0 2 50)} "handle-sx-response" {:upvalue-count 0 :arity 5 :constants ("strip-component-scripts" "extract-response-css" "trim" "empty?" "sx-render" "dom-create-element" "div" "dom-append" "process-oob-swaps" {:upvalue-count 0 :arity 3 :constants ("dispose-islands-in" "swap-dom-nodes" "innerHTML" "children-to-fragment" "post-swap") :bytecode (20 0 0 16 0 48 1 5 20 1 0 16 0 16 2 1 2 0 164 33 10 0 20 3 0 16 1 48 1 32 2 0 16 1 16 2 48 3 5 20 4 0 16 0 49 1 50)} "hoist-head-elements" "dom-get-attr" "sx-select" "select-from-container" "children-to-fragment" "dispose-islands-in" "with-transition" {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "post-swap" "outerHTML" "dom-parent") :bytecode (20 0 0 18 0 18 1 18 2 48 3 17 0 20 1 0 18 2 1 2 0 164 33 17 0 20 3 0 16 0 6 34 3 0 5 18 0 48 1 32 9 0 16 0 6 34 3 0 5 18 0 49 1 50)}) :bytecode (20 0 0 16 2 48 1 17 5 20 1 0 16 5 48 1 17 6 16 6 52 2 0 1 17 7 16 7 52 3 0 1 167 33 114 0 20 4 0 16 7 48 1 17 8 20 5 0 1 6 0 2 48 2 17 9 20 7 0 16 9 16 8 48 2 5 20 8 0 16 9 51 9 0 48 2 5 20 10 0 16 9 48 1 5 20 11 0 16 0 1 12 0 48 2 17 10 16 10 33 12 0 20 13 0 16 9 16 10 48 2 32 7 0 20 14 0 16 9 48 1 17 11 20 15 0 16 1 48 1 5 20 16 0 16 4 51 17 0 1 1 1 11 1 3 49 2 32 1 0 2 50)} "handle-html-response" {:upvalue-count 0 :arity 5 :constants ("dom-parse-html-document" "dom-get-attr" "sx-select" "dispose-islands-in" "dom-create-element" "div" "dom-set-inner-html" "dom-body-inner-html" "process-oob-swaps" {:upvalue-count 0 :arity 3 :constants ("dispose-islands-in" "swap-dom-nodes" "post-swap") :bytecode (20 0 0 16 0 48 1 5 20 1 0 16 0 16 1 16 2 48 3 5 20 2 0 16 0 49 1 50)} "hoist-head-elements" "dom-query" "script[data-sx-manifest]" "Sx" "host-global" "mergeManifest" "host-call" "select-from-container" "with-transition" {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "log-info" "swap-root: " "dom-tag-name" "nil" " target: " "str" "post-swap") :bytecode (20 0 0 18 0 18 1 18 2 48 3 17 0 20 1 0 1 2 0 16 0 33 10 0 20 3 0 16 0 48 1 32 3 0 1 4 0 1 5 0 20 3 0 18 0 48 1 52 6 0 4 48 1 5 20 7 0 16 0 6 34 3 0 5 18 0 49 1 50)} {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "children-to-fragment" "post-swap") :bytecode (20 0 0 18 0 20 1 0 18 1 48 1 18 2 48 3 5 20 2 0 18 0 49 1 50)}) :bytecode (20 0 0 16 2 48 1 17 5 16 5 33 202 0 20 1 0 16 0 1 2 0 48 2 17 6 20 3 0 16 1 48 1 5 16 6 33 113 0 20 4 0 1 5 0 2 48 2 17 7 20 6 0 16 7 20 7 0 16 5 48 1 48 2 5 20 8 0 16 7 51 9 0 48 2 5 20 10 0 16 7 48 1 5 20 11 0 16 7 1 12 0 48 2 17 8 16 8 33 19 0 1 13 0 52 14 0 1 1 15 0 16 8 52 16 0 3 32 1 0 2 5 20 17 0 16 7 16 6 48 2 17 8 20 18 0 16 4 51 19 0 1 1 1 8 1 3 49 2 32 61 0 20 4 0 1 5 0 2 48 2 17 7 20 6 0 16 7 20 7 0 16 5 48 1 48 2 5 20 8 0 16 7 51 9 0 48 2 5 20 10 0 16 7 48 1 5 20 18 0 16 4 51 20 0 1 1 1 7 1 3 49 2 32 1 0 2 50)} "handle-retry" {:upvalue-count 0 :arity 5 :constants ("dom-get-attr" "sx-retry" "parse-retry-spec" "data-sx-retry-ms" "start-ms" "get" "parse-int" "dom-set-attr" "next-retry-ms" "cap-ms" "str" "set-timeout" {:upvalue-count 5 :arity 0 :constants ("do-fetch") :bytecode (20 0 0 18 0 18 1 18 2 18 3 18 4 49 5 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 5 20 2 0 16 5 48 1 17 6 16 6 33 97 0 20 0 0 16 0 1 3 0 48 2 6 34 10 0 5 16 6 1 4 0 52 5 0 2 17 7 16 7 16 6 1 4 0 52 5 0 2 52 6 0 2 17 8 20 7 0 16 0 1 3 0 20 8 0 16 8 16 6 1 9 0 52 5 0 2 48 2 52 10 0 1 48 3 5 20 11 0 51 12 0 1 0 1 1 1 2 1 3 1 4 16 8 49 2 32 1 0 2 50)} "bind-triggers" {:upvalue-count 0 :arity 2 :constants ("parse-trigger-spec" "dom-get-attr" "sx-trigger" "default-trigger" "dom-tag-name" {:upvalue-count 2 :arity 1 :constants ("classify-trigger" "modifiers" "get" "poll" "set-interval" {:upvalue-count 2 :arity 0 :constants ("isConnected" "host-get" "execute-request" "clear-interval" "log-info" "poll stopped: element removed") :bytecode (18 0 1 0 0 52 1 0 2 33 12 0 20 2 0 18 0 2 2 49 3 32 16 0 20 3 0 18 1 48 1 5 20 4 0 1 5 0 49 1 50)} "interval" "intersect" "observe-intersection" {:upvalue-count 1 :arity 0 :constants ("execute-request") :bytecode (20 0 0 18 0 2 2 49 3 50)} "delay" "load" "set-timeout" 0 "revealed" "event" "bind-event") :bytecode (20 0 0 16 0 48 1 17 1 16 0 1 1 0 52 2 0 2 17 2 16 1 1 3 0 164 33 29 0 2 17 3 20 4 0 51 5 0 0 0 1 3 16 2 1 6 0 52 2 0 2 48 2 17 3 32 140 0 16 1 1 7 0 164 33 25 0 20 8 0 18 0 51 9 0 0 0 3 16 2 1 10 0 52 2 0 2 49 4 32 106 0 16 1 1 11 0 164 33 30 0 20 12 0 51 9 0 0 0 16 2 1 10 0 52 2 0 2 6 34 4 0 5 1 13 0 49 2 32 67 0 16 1 1 14 0 164 33 25 0 20 8 0 18 0 51 9 0 0 0 4 16 2 1 10 0 52 2 0 2 49 4 32 33 0 16 1 1 15 0 164 33 23 0 20 16 0 18 0 16 0 1 15 0 52 2 0 2 16 2 18 1 49 4 32 1 0 2 50)} "for-each") :bytecode (20 0 0 20 1 0 16 0 1 2 0 48 2 48 1 6 34 13 0 5 20 3 0 20 4 0 16 0 48 1 48 1 17 2 51 5 0 1 0 1 1 16 2 52 6 0 2 50)} "bind-event" {:upvalue-count 0 :arity 4 :constants ("from" "get" "nil?" "body" "dom-body" "document" "dom-document" "window" "dom-window" "dom-query" "dom-add-listener" {:upvalue-count 5 :arity 1 :constants ("filter" "get" "key=='" "index-of" 0 ">=" 5 6 "slice" "key" "host-get" "dom-matches?" "target" "input,textarea,select" "changed" "element-value" "click" "event-modifier-key?" "submit" "dom-has-attr?" "href" "prevent-default" "get-verb-info" "method" "GET" "delay" "try-client-route" "url-pathname" "url" "dom-get-attr" "sx-target" "save-scroll-position" "browser-push-state" "browser-scroll-to" "log-info" "sx:route server fetch " "str" "clear-timeout" "set-timeout" {:upvalue-count 1 :arity 0 :constants ("execute-request") :bytecode (20 0 0 18 0 2 2 49 3 50)} "execute-request") :bytecode (18 0 1 0 0 52 1 0 2 33 96 0 18 0 1 0 0 52 1 0 2 17 1 16 1 1 2 0 52 3 0 2 17 2 16 2 1 4 0 52 5 0 2 33 58 0 16 1 16 2 1 6 0 160 16 2 1 7 0 160 52 8 0 3 17 3 16 0 1 9 0 52 10 0 2 16 3 164 6 33 19 0 5 20 11 0 16 0 1 12 0 52 10 0 2 1 13 0 48 2 167 32 1 0 3 32 1 0 3 17 1 18 0 1 14 0 52 1 0 2 33 26 0 20 15 0 17 2 16 2 18 1 164 33 6 0 4 17 1 32 4 0 16 2 19 1 32 1 0 2 5 16 1 6 33 20 0 5 18 2 1 16 0 164 6 33 8 0 5 20 17 0 16 0 48 1 167 33 27 1 18 2 1 18 0 164 6 34 22 0 5 18 2 1 16 0 164 6 33 11 0 5 20 19 0 18 3 1 20 0 48 2 33 10 0 20 21 0 16 0 48 1 32 1 0 2 5 20 22 0 18 3 48 1 17 2 18 2 1 16 0 164 6 33 44 0 5 16 2 1 23 0 52 1 0 2 1 24 0 164 6 33 26 0 5 20 19 0 18 3 1 20 0 48 2 6 33 11 0 5 18 0 1 25 0 52 1 0 2 167 17 3 4 17 4 16 3 33 34 0 20 26 0 20 27 0 16 2 1 28 0 52 1 0 2 48 1 20 29 0 18 3 1 30 0 48 2 48 2 17 4 32 1 0 2 5 16 4 33 35 0 20 31 0 48 0 5 20 32 0 16 2 1 28 0 52 1 0 2 48 1 5 20 33 0 1 4 0 1 4 0 49 2 32 84 0 16 3 33 24 0 20 34 0 1 35 0 16 2 1 28 0 52 1 0 2 52 36 0 2 48 1 32 1 0 2 5 18 0 1 25 0 52 1 0 2 33 32 0 20 37 0 18 4 48 1 5 20 38 0 51 39 0 0 3 18 0 1 25 0 52 1 0 2 48 2 19 4 32 9 0 20 40 0 18 3 2 2 49 3 32 1 0 2 50)} "once" "dict") :bytecode (2 17 4 2 17 5 16 2 1 0 0 52 1 0 2 17 6 16 6 52 2 0 1 33 5 0 16 0 32 58 0 16 6 1 3 0 164 33 8 0 20 4 0 48 0 32 41 0 16 6 1 5 0 164 33 8 0 20 6 0 48 0 32 24 0 16 6 1 7 0 164 33 8 0 20 8 0 48 0 32 7 0 20 9 0 16 6 48 1 17 6 16 6 33 49 0 20 10 0 16 6 16 1 51 11 0 1 2 1 5 1 1 1 0 1 4 16 2 1 12 0 52 1 0 2 33 11 0 1 12 0 3 52 13 0 2 32 1 0 2 49 4 32 1 0 2 50)} "post-swap" {:upvalue-count 0 :arity 1 :constants ("log-info" "post-swap: root=" "dom-tag-name" "nil" "str" "activate-scripts" "sx-process-scripts" "sx-hydrate" "sx-hydrate-islands" "run-post-render-hooks" "flush-collected-styles" "process-elements") :bytecode (20 0 0 1 1 0 16 0 33 10 0 20 2 0 16 0 48 1 32 3 0 1 3 0 52 4 0 2 48 1 5 20 5 0 16 0 48 1 5 20 6 0 16 0 48 1 5 20 7 0 16 0 48 1 5 20 8 0 16 0 48 1 5 20 9 0 48 0 5 20 10 0 48 0 5 20 11 0 16 0 49 1 50)} "process-settle-hooks" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-on-settle" "empty?" "sx-parse" {:upvalue-count 0 :arity 1 :constants ("cek-eval") :bytecode (20 0 0 16 0 49 1 50)} "for-each") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 8 0 5 16 1 52 2 0 1 167 33 21 0 20 3 0 16 1 48 1 17 2 51 4 0 16 2 52 5 0 2 32 1 0 2 50)} "activate-scripts" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "script" {:upvalue-count 0 :arity 1 :constants ("dom-has-attr?" "data-components" "data-sx-activated" "create-script-clone" "dom-set-attr" "true" "dom-replace-child" "dom-parent") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 12 0 5 20 0 0 16 0 1 2 0 48 2 167 33 42 0 20 3 0 16 0 48 1 17 1 20 4 0 16 1 1 2 0 1 5 0 48 3 5 20 6 0 20 7 0 16 0 48 1 16 1 16 0 49 3 32 1 0 2 50)} "for-each") :bytecode (16 0 33 24 0 20 0 0 16 0 1 1 0 48 2 17 1 51 2 0 16 1 52 3 0 2 32 1 0 2 50)} "process-oob-swaps" {:upvalue-count 0 :arity 2 :constants ("find-oob-swaps" {:upvalue-count 1 :arity 1 :constants ("target-id" "get" "dom-query-by-id" "element" "swap-type" "dom-parent" "dom-remove-child") :bytecode (16 0 1 0 0 52 1 0 2 17 1 20 2 0 16 1 48 1 17 2 16 0 1 3 0 52 1 0 2 17 3 16 0 1 4 0 52 1 0 2 17 4 20 5 0 16 3 48 1 33 17 0 20 6 0 20 5 0 16 3 48 1 16 3 48 2 32 1 0 2 5 16 2 33 13 0 18 0 16 2 16 3 16 4 49 3 32 1 0 2 50)} "for-each") :bytecode (20 0 0 16 0 48 1 17 2 51 1 0 1 1 16 2 52 2 0 2 50)} "hoist-head-elements" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ("dom-parent" "dom-remove-child" "dom-append-to-head") :bytecode (20 0 0 16 0 48 1 33 17 0 20 1 0 20 0 0 16 0 48 1 16 0 48 2 32 1 0 2 5 20 2 0 16 0 49 1 50)} "dom-query-all" "style[data-sx-css]" "for-each" "link[rel=\"stylesheet\"]") :bytecode (51 0 0 20 1 0 16 0 1 2 0 48 2 52 3 0 2 5 51 0 0 20 1 0 16 0 1 4 0 48 2 52 3 0 2 50)} "process-boosted" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ("boost-descendants") :bytecode (20 0 0 16 0 49 1 50)} "dom-query-all" "dom-body" "[sx-boost]" "for-each" "dom-closest" "boost-descendants") :bytecode (51 0 0 20 1 0 16 0 6 34 6 0 5 20 2 0 48 0 1 3 0 48 2 52 4 0 2 5 16 0 33 31 0 20 5 0 16 0 1 3 0 48 2 17 1 16 1 33 10 0 20 6 0 16 1 49 1 32 1 0 2 32 1 0 2 50)} "boost-descendants" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-boost" {:upvalue-count 1 :arity 1 :constants ("is-processed?" "boost" "should-boost-link?" "mark-processed!" "dom-has-attr?" "sx-target" "true" "dom-set-attr" "sx-swap" "innerHTML" "sx-push-url" "bind-client-route-link" "dom-get-attr" "href") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 8 0 5 20 2 0 16 0 48 1 33 145 0 20 3 0 16 0 1 1 0 48 2 5 20 4 0 16 0 1 5 0 48 2 167 6 33 15 0 5 18 0 6 33 8 0 5 18 0 1 6 0 164 167 33 15 0 20 7 0 16 0 1 5 0 18 0 48 3 32 1 0 2 5 20 4 0 16 0 1 8 0 48 2 167 33 16 0 20 7 0 16 0 1 8 0 1 9 0 48 3 32 1 0 2 5 20 4 0 16 0 1 10 0 48 2 167 33 16 0 20 7 0 16 0 1 10 0 1 6 0 48 3 32 1 0 2 5 20 11 0 16 0 20 12 0 16 0 1 13 0 48 2 49 2 32 1 0 2 50)} "dom-query-all" "a[href]" "for-each" {:upvalue-count 1 :arity 1 :constants ("is-processed?" "boost" "should-boost-form?" "mark-processed!" "dom-get-attr" "method" "GET" "upper" "action" "browser-location-href" "dom-has-attr?" "sx-target" "true" "dom-set-attr" "sx-swap" "innerHTML" "bind-boost-form") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 8 0 5 20 2 0 16 0 48 1 33 153 0 20 3 0 16 0 1 1 0 48 2 5 20 4 0 16 0 1 5 0 48 2 6 34 4 0 5 1 6 0 52 7 0 1 17 1 20 4 0 16 0 1 8 0 48 2 6 34 6 0 5 20 9 0 48 0 17 2 20 10 0 16 0 1 11 0 48 2 167 6 33 15 0 5 18 0 6 33 8 0 5 18 0 1 12 0 164 167 33 15 0 20 13 0 16 0 1 11 0 18 0 48 3 32 1 0 2 5 20 10 0 16 0 1 14 0 48 2 167 33 16 0 20 13 0 16 0 1 14 0 1 15 0 48 3 32 1 0 2 5 20 16 0 16 0 16 1 16 2 49 3 32 1 0 2 50)} "form") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 51 2 0 1 1 20 3 0 16 0 1 4 0 48 2 52 5 0 2 5 51 6 0 1 1 20 3 0 16 0 1 7 0 48 2 52 5 0 2 50)} "_page-data-cache" "_page-data-cache-ttl" 30000 "page-data-cache-key" {:upvalue-count 0 :arity 2 :constants ("nil?" "keys" "empty?" "list" {:upvalue-count 2 :arity 1 :constants ("=" "get" "str" "append!") :bytecode (18 0 16 0 1 0 0 18 1 16 0 52 1 0 2 52 2 0 3 52 3 0 2 50)} "for-each" ":" "&" "join" "str") :bytecode (16 0 17 2 16 1 52 0 0 1 6 34 11 0 5 16 1 52 1 0 1 52 2 0 1 33 5 0 16 2 32 42 0 52 3 0 0 17 3 51 4 0 1 3 1 1 16 1 52 1 0 1 52 5 0 2 5 16 2 1 6 0 1 7 0 16 3 52 8 0 2 52 9 0 3 50)} "page-data-cache-get" {:upvalue-count 0 :arity 1 :constants ("_page-data-cache" "get" "nil?" "now-ms" "ts" "_page-data-cache-ttl" "dict-set!" "data") :bytecode (20 0 0 16 0 52 1 0 2 17 1 16 1 52 2 0 1 33 4 0 2 32 46 0 20 3 0 48 0 16 1 1 4 0 52 1 0 2 161 20 5 0 166 33 15 0 20 0 0 16 0 2 52 6 0 3 5 2 32 9 0 16 1 1 7 0 52 1 0 2 50)} "page-data-cache-set" {:upvalue-count 0 :arity 2 :constants ("_page-data-cache" "data" "ts" "now-ms" "dict-set!") :bytecode (20 0 0 16 0 1 1 0 16 1 1 2 0 20 3 0 48 0 65 2 0 52 4 0 3 50)} "invalidate-page-cache" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 1 :arity 1 :constants (":" "str" "starts-with?" "_page-data-cache" "dict-set!") :bytecode (16 0 18 0 164 6 34 16 0 5 16 0 18 0 1 0 0 52 1 0 2 52 2 0 2 33 13 0 20 3 0 16 0 2 52 4 0 3 32 1 0 2 50)} "_page-data-cache" "keys" "for-each" "sw-post-message" "type" "invalidate" "page" "log-info" "sx:cache invalidate " "str") :bytecode (51 0 0 1 0 20 1 0 52 2 0 1 52 3 0 2 5 20 4 0 1 5 0 1 6 0 1 7 0 16 0 65 2 0 48 1 5 20 8 0 1 9 0 16 0 52 10 0 2 49 1 50)} "invalidate-all-page-cache" {:upvalue-count 0 :arity 0 :constants ("dict" "_page-data-cache" "sw-post-message" "type" "invalidate" "page" "*" "log-info" "sx:cache invalidate *") :bytecode (52 0 0 0 21 1 0 5 20 2 0 1 3 0 1 4 0 1 5 0 1 6 0 65 2 0 48 1 5 20 7 0 1 8 0 49 1 50)} "update-page-cache" {:upvalue-count 0 :arity 2 :constants ("page-data-cache-key" "dict" "page-data-cache-set" "log-info" "sx:cache update " "str") :bytecode (20 0 0 16 0 52 1 0 0 48 2 17 2 20 2 0 16 2 16 1 48 2 5 20 3 0 1 4 0 16 0 52 5 0 2 49 1 50)} "process-cache-directives" {:upvalue-count 0 :arity 3 :constants ("dom-get-attr" "sx-cache-invalidate" "*" "invalidate-all-page-cache" "invalidate-page-cache" "cache-invalidate" "get" "cache-update" "parse-sx-data" "update-page-cache") :bytecode (20 0 0 16 0 1 1 0 48 2 17 3 16 3 33 27 0 16 3 1 2 0 164 33 8 0 20 3 0 48 0 32 7 0 20 4 0 16 3 48 1 32 1 0 2 5 16 1 1 5 0 52 6 0 2 17 3 16 3 33 27 0 16 3 1 2 0 164 33 8 0 20 3 0 48 0 32 7 0 20 4 0 16 3 48 1 32 1 0 2 5 16 1 1 7 0 52 6 0 2 17 3 16 3 33 30 0 20 8 0 16 2 48 1 17 4 16 4 33 12 0 20 9 0 16 3 16 4 49 2 32 1 0 2 32 1 0 2 50)} "_optimistic-snapshots" "optimistic-cache-update" {:upvalue-count 0 :arity 2 :constants ("page-data-cache-get" "_optimistic-snapshots" "dict-set!" "page-data-cache-set") :bytecode (20 0 0 16 0 48 1 17 2 16 2 33 35 0 16 1 16 2 48 1 17 3 20 1 0 16 0 16 2 52 2 0 3 5 20 3 0 16 0 16 3 48 2 5 16 3 32 1 0 2 50)} "optimistic-cache-revert" {:upvalue-count 0 :arity 1 :constants ("_optimistic-snapshots" "get" "page-data-cache-set" "dict-delete!") :bytecode (20 0 0 16 0 52 1 0 2 17 1 16 1 33 25 0 20 2 0 16 0 16 1 48 2 5 20 0 0 16 0 52 3 0 2 5 16 1 32 1 0 2 50)} "optimistic-cache-confirm" {:upvalue-count 0 :arity 1 :constants ("_optimistic-snapshots" "dict-delete!") :bytecode (20 0 0 16 0 52 1 0 2 50)} "submit-mutation" {:upvalue-count 0 :arity 6 :constants ("page-data-cache-key" "optimistic-cache-update" "try-rerender-page" "execute-action" {:upvalue-count 4 :arity 1 :constants ("page-data-cache-set" "optimistic-cache-confirm" "try-rerender-page" "log-info" "sx:optimistic confirmed " "str" "confirmed") :bytecode (16 0 33 12 0 20 0 0 18 0 16 0 48 2 32 1 0 2 5 20 1 0 18 0 48 1 5 16 0 33 14 0 20 2 0 18 1 18 2 16 0 48 3 32 1 0 2 5 20 3 0 1 4 0 18 1 52 5 0 2 48 1 5 18 3 33 10 0 18 3 1 6 0 49 1 32 1 0 2 50)} {:upvalue-count 4 :arity 1 :constants ("optimistic-cache-revert" "try-rerender-page" "log-warn" "sx:optimistic reverted " ": " "str" "reverted") :bytecode (20 0 0 18 0 48 1 17 1 16 1 33 14 0 20 1 0 18 1 18 2 16 1 48 3 32 1 0 2 5 20 2 0 1 3 0 18 1 1 4 0 16 0 52 5 0 4 48 1 5 18 3 33 10 0 18 3 1 6 0 49 1 32 1 0 2 50)}) :bytecode (20 0 0 16 0 16 1 48 2 17 6 20 1 0 16 6 16 4 48 2 17 7 16 7 33 14 0 20 2 0 16 0 16 1 16 7 48 3 32 1 0 2 5 20 3 0 16 2 16 3 51 4 0 1 6 1 0 1 1 1 5 51 5 0 1 6 1 0 1 1 1 5 49 4 50)} "_is-online" "_offline-queue" "list" "offline-is-online?" {:upvalue-count 0 :arity 0 :constants ("_is-online") :bytecode (20 0 0 50)} "offline-set-online!" {:upvalue-count 0 :arity 1 :constants ("_is-online") :bytecode (16 0 21 0 0 50)} "offline-queue-mutation" {:upvalue-count 0 :arity 5 :constants ("page-data-cache-key" "action" "payload" "page" "params" "timestamp" "now-ms" "status" "pending" "dict" "_offline-queue" "append!" "optimistic-cache-update" "try-rerender-page" "log-info" "sx:offline queued " " (" " pending)" "str") :bytecode (20 0 0 16 2 16 3 48 2 17 5 1 1 0 16 0 1 2 0 16 1 1 3 0 16 2 1 4 0 16 3 1 5 0 20 6 0 48 0 1 7 0 1 8 0 52 9 0 12 17 6 20 10 0 16 6 52 11 0 2 5 20 12 0 16 5 16 4 48 2 17 7 16 7 33 14 0 20 13 0 16 2 16 3 16 7 48 3 32 1 0 2 5 20 14 0 1 15 0 16 0 1 16 0 20 10 0 168 1 17 0 52 18 0 5 48 1 5 16 6 50)} "offline-sync" {:upvalue-count 0 :arity 0 :constants ({:upvalue-count 0 :arity 1 :constants ("status" "get" "pending") :bytecode (16 0 1 0 0 52 1 0 2 1 2 0 164 50)} "_offline-queue" "filter" "empty?" "log-info" "sx:offline syncing " " mutations" "str" {:upvalue-count 0 :arity 1 :constants ("execute-action" "action" "get" "payload" {:upvalue-count 1 :arity 1 :constants ("status" "synced" "dict-set!" "log-info" "sx:offline synced " "action" "get" "str") :bytecode (18 0 1 0 0 1 1 0 52 2 0 3 5 20 3 0 1 4 0 18 0 1 5 0 52 6 0 2 52 7 0 2 49 1 50)} {:upvalue-count 1 :arity 1 :constants ("status" "failed" "dict-set!" "log-warn" "sx:offline sync failed " "action" "get" ": " "str") :bytecode (18 0 1 0 0 1 1 0 52 2 0 3 5 20 3 0 1 4 0 18 0 1 5 0 52 6 0 2 1 7 0 16 0 52 8 0 4 49 1 50)}) :bytecode (20 0 0 16 0 1 1 0 52 2 0 2 16 0 1 3 0 52 2 0 2 51 4 0 1 0 51 5 0 1 0 49 4 50)} "for-each") :bytecode (51 0 0 20 1 0 52 2 0 2 17 0 16 0 52 3 0 1 167 33 31 0 20 4 0 1 5 0 16 0 168 1 6 0 52 7 0 3 48 1 5 51 8 0 16 0 52 9 0 2 32 1 0 2 50)} "offline-pending-count" {:upvalue-count 0 :arity 0 :constants ({:upvalue-count 0 :arity 1 :constants ("status" "get" "pending") :bytecode (16 0 1 0 0 52 1 0 2 1 2 0 164 50)} "_offline-queue" "filter") :bytecode (51 0 0 20 1 0 52 2 0 2 168 50)} "offline-aware-mutation" {:upvalue-count 0 :arity 6 :constants ("_is-online" "submit-mutation" "offline-queue-mutation" "queued") :bytecode (20 0 0 33 20 0 20 1 0 16 0 16 1 16 2 16 3 16 4 16 5 49 6 32 32 0 20 2 0 16 2 16 3 16 0 16 1 16 4 48 5 5 16 5 33 10 0 16 5 1 3 0 49 1 32 1 0 2 50)} "current-page-layout" {:upvalue-count 0 :arity 0 :constants ("url-pathname" "browser-location-href" "find-matching-route" "_page-routes" "nil?" "" "layout" "get") :bytecode (20 0 0 20 1 0 48 0 48 1 17 0 20 2 0 16 0 20 3 0 48 2 17 1 16 1 52 4 0 1 33 6 0 1 5 0 32 17 0 16 1 1 6 0 52 7 0 2 6 34 4 0 5 1 5 0 50)} "swap-rendered-content" {:upvalue-count 0 :arity 3 :constants ("dom-create-element" "div" "dom-append" "process-oob-swaps" {:upvalue-count 0 :arity 3 :constants ("dispose-islands-in" "swap-dom-nodes" "innerHTML" "children-to-fragment" "post-swap") :bytecode (20 0 0 16 0 48 1 5 20 1 0 16 0 16 2 1 2 0 164 33 10 0 20 3 0 16 1 48 1 32 2 0 16 1 16 2 48 3 5 20 4 0 16 0 49 1 50)} "dom-get-attr" "id" "dom-query" "#" "str" "children-to-fragment" "dispose-islands-in" "dom-set-text-content" "" "hoist-head-elements-full" "process-elements" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks" "dom-dispatch" "sx:clientRoute" "pathname" "dict" "log-info" "sx:route client ") :bytecode (20 0 0 1 1 0 2 48 2 17 3 20 2 0 16 3 16 1 48 2 5 20 3 0 16 3 51 4 0 48 2 5 20 5 0 16 0 1 6 0 48 2 17 4 16 4 33 19 0 20 7 0 16 3 1 8 0 16 4 52 9 0 2 48 2 32 1 0 2 17 5 16 5 33 10 0 20 10 0 16 5 48 1 32 7 0 20 10 0 16 3 48 1 17 6 20 11 0 16 0 48 1 5 20 12 0 16 0 1 13 0 48 2 5 20 2 0 16 0 16 6 48 2 5 20 14 0 16 0 48 1 5 20 15 0 16 0 48 1 5 20 16 0 16 0 48 1 5 20 17 0 16 0 48 1 5 20 18 0 48 0 5 20 19 0 16 0 1 20 0 1 21 0 16 2 52 22 0 2 48 3 5 20 23 0 1 24 0 16 2 52 9 0 2 49 1 50)} "resolve-route-target" {:upvalue-count 0 :arity 1 :constants ("true" "dom-query") :bytecode (16 0 6 33 8 0 5 16 0 1 0 0 164 167 33 10 0 20 1 0 16 0 49 1 32 1 0 2 50)} "deps-satisfied?" {:upvalue-count 0 :arity 1 :constants ("deps" "get" "loaded-component-names" "nil?" "empty?" {:upvalue-count 1 :arity 1 :constants ("contains?") :bytecode (18 0 16 0 52 0 0 2 50)} "every?") :bytecode (16 0 1 0 0 52 1 0 2 17 1 20 2 0 48 0 17 2 16 1 52 3 0 1 33 4 0 4 32 24 0 16 1 52 4 0 1 33 4 0 3 32 11 0 51 5 0 1 2 16 1 52 6 0 2 50)} "try-client-route" {:upvalue-count 0 :arity 2 :constants ("find-matching-route" "_page-routes" "nil?" "log-info" "sx:route no match (" " routes) " "str" "layout" "get" "" "current-page-layout" "sx:route server (layout: " " -> " ") " "content" "closure" "params" "name" "empty?" "log-warn" "sx:route no content for " "resolve-route-target" "sx:route target not found: " "deps-satisfied?" "sx:route deps miss for " "io-deps" "render-plan" "server" "list" "client" "sx:route plan " " — " " server, " " client" "register-io-deps" "stream" "sx:route streaming " "fetch-streaming" "build-request-headers" "loaded-component-names" "has-data" "page-data-cache-key" "page-data-cache-get" "merge" "sx:route client+cache+async " "try-async-eval-content" {:upvalue-count 2 :arity 1 :constants ("nil?" "log-warn" "sx:route cache+async eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (16 0 52 0 0 1 33 45 0 20 1 0 1 2 0 18 0 1 3 0 52 4 0 3 48 1 5 20 5 0 18 1 18 0 20 6 0 18 1 20 7 0 48 0 48 2 1 8 0 49 4 32 11 0 20 9 0 18 1 16 0 18 0 49 3 50)} "try-eval-content" "sx:route cached eval failed for " "sx:route client+cache " "swap-rendered-content" "sx:route client+data " "resolve-page-data" {:upvalue-count 7 :arity 1 :constants ("page-data-cache-set" "merge" "try-async-eval-content" {:upvalue-count 2 :arity 1 :constants ("nil?" "log-warn" "sx:route data+async eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (16 0 52 0 0 1 33 45 0 20 1 0 1 2 0 18 0 1 3 0 52 4 0 3 48 1 5 20 5 0 18 1 18 0 20 6 0 18 1 20 7 0 48 0 48 2 1 8 0 49 4 32 11 0 20 9 0 18 1 16 0 18 0 49 3 50)} "try-eval-content" "nil?" "log-warn" "sx:route data eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (20 0 0 18 0 16 0 48 2 5 18 1 18 2 16 0 52 1 0 3 17 1 18 3 33 19 0 20 2 0 18 4 16 1 51 3 0 0 5 0 6 49 3 32 76 0 20 4 0 18 4 16 1 48 2 17 2 16 2 52 5 0 1 33 45 0 20 6 0 1 7 0 18 5 1 8 0 52 9 0 3 48 1 5 20 10 0 18 6 18 5 20 11 0 18 6 20 12 0 48 0 48 2 1 13 0 49 4 32 11 0 20 14 0 18 6 16 2 18 5 49 3 50)} "sx:route client+async " {:upvalue-count 2 :arity 1 :constants ("nil?" "log-warn" "sx:route async eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (16 0 52 0 0 1 33 45 0 20 1 0 1 2 0 18 0 1 3 0 52 4 0 3 48 1 5 20 5 0 18 1 18 0 20 6 0 18 1 20 7 0 48 0 48 2 1 8 0 49 4 32 11 0 20 9 0 18 1 16 0 18 0 49 3 50)} "sx:route server (eval failed) ") :bytecode (20 0 0 16 0 20 1 0 48 2 17 2 16 2 52 2 0 1 33 26 0 20 3 0 1 4 0 20 1 0 168 1 5 0 16 0 52 6 0 4 48 1 5 4 32 212 2 16 2 1 7 0 52 8 0 2 6 34 4 0 5 1 9 0 17 3 20 10 0 48 0 17 4 16 3 16 4 164 167 33 29 0 20 3 0 1 11 0 16 4 1 12 0 16 3 1 13 0 16 0 52 6 0 6 48 1 5 4 32 148 2 16 2 1 14 0 52 8 0 2 17 5 16 2 1 15 0 52 8 0 2 6 34 4 0 5 65 0 0 17 6 16 2 1 16 0 52 8 0 2 17 7 16 2 1 17 0 52 8 0 2 17 8 16 5 52 2 0 1 6 34 7 0 5 16 5 52 18 0 1 33 19 0 20 19 0 1 20 0 16 0 52 6 0 2 48 1 5 4 32 57 2 20 21 0 16 1 48 1 17 9 16 9 52 2 0 1 33 19 0 20 19 0 1 22 0 16 1 52 6 0 2 48 1 5 4 32 20 2 20 23 0 16 2 48 1 167 33 19 0 20 3 0 1 24 0 16 8 52 6 0 2 48 1 5 4 32 246 1 16 2 1 25 0 52 8 0 2 17 10 16 10 6 33 8 0 5 16 10 52 18 0 1 167 17 11 16 2 1 26 0 52 8 0 2 17 12 16 12 33 72 0 16 12 1 27 0 52 8 0 2 6 34 5 0 5 52 28 0 0 17 13 16 12 1 29 0 52 8 0 2 6 34 5 0 5 52 28 0 0 17 14 20 3 0 1 30 0 16 8 1 31 0 16 13 168 1 32 0 16 14 168 1 33 0 52 6 0 7 48 1 32 1 0 2 5 16 11 33 10 0 20 34 0 16 10 48 1 32 1 0 2 5 16 2 1 35 0 52 8 0 2 33 41 0 20 3 0 1 36 0 16 0 52 6 0 2 48 1 5 20 37 0 16 9 16 0 20 38 0 16 9 20 39 0 48 0 48 2 48 3 5 3 32 59 1 16 2 1 40 0 52 8 0 2 33 194 0 20 41 0 16 8 16 7 48 2 17 13 20 42 0 16 13 48 1 17 14 16 14 33 123 0 16 6 16 7 16 14 52 43 0 3 17 15 16 11 33 36 0 20 3 0 1 44 0 16 0 52 6 0 2 48 1 5 20 45 0 16 5 16 15 51 46 0 1 0 1 9 48 3 5 3 32 67 0 20 47 0 16 5 16 15 48 2 17 16 16 16 52 2 0 1 33 19 0 20 19 0 1 48 0 16 0 52 6 0 2 48 1 5 4 32 28 0 20 3 0 1 49 0 16 0 52 6 0 2 48 1 5 20 50 0 16 9 16 16 16 0 48 3 5 3 32 43 0 20 3 0 1 51 0 16 0 52 6 0 2 48 1 5 20 52 0 16 8 16 7 51 53 0 1 13 1 6 1 7 1 11 1 5 1 0 1 9 48 3 5 3 32 109 0 16 11 33 42 0 20 3 0 1 54 0 16 0 52 6 0 2 48 1 5 20 45 0 16 5 16 6 16 7 52 43 0 2 51 55 0 1 0 1 9 48 3 5 3 32 62 0 16 6 16 7 52 43 0 2 17 13 20 47 0 16 5 16 13 48 2 17 14 16 14 52 2 0 1 33 19 0 20 3 0 1 56 0 16 0 52 6 0 2 48 1 5 4 32 13 0 20 50 0 16 9 16 14 16 0 48 3 5 3 50)} "bind-client-route-link" {:upvalue-count 0 :arity 2 :constants ("bind-client-route-click" {:upvalue-count 2 :arity 0 :constants ("bind-boost-link") :bytecode (20 0 0 18 0 18 1 49 2 50)}) :bytecode (20 0 0 16 0 16 1 51 1 0 1 0 1 1 49 3 50)} "process-sse" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ("is-processed?" "sse" "mark-processed!" "bind-sse") :bytecode (20 0 0 16 0 1 1 0 48 2 167 33 21 0 20 2 0 16 0 1 1 0 48 2 5 20 3 0 16 0 49 1 32 1 0 2 50)} "dom-query-all" "dom-body" "[sx-sse]" "for-each") :bytecode (51 0 0 20 1 0 16 0 6 34 6 0 5 20 2 0 48 0 1 3 0 48 2 52 4 0 2 50)} "bind-sse" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-sse" "event-source-connect" "parse-sse-swap" "event-source-listen" {:upvalue-count 1 :arity 1 :constants ("bind-sse-swap") :bytecode (20 0 0 18 0 16 0 49 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 37 0 20 2 0 16 1 16 0 48 2 17 2 20 3 0 16 0 48 1 17 3 20 4 0 16 2 16 3 51 5 0 1 0 49 3 32 1 0 2 50)} "bind-sse-swap" {:upvalue-count 0 :arity 2 :constants ("resolve-target" "parse-swap-spec" "dom-get-attr" "sx-swap" "dom-has-class?" "dom-body" "sx-transitions" "style" "get" "transition" "trim" "empty?" "dispose-islands-in" "(" "starts-with?" "sx-render" "dom-create-element" "div" "dom-append" "with-transition" {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "children-to-fragment" "post-swap") :bytecode (20 0 0 18 0 20 1 0 18 1 48 1 18 2 48 3 5 20 2 0 18 0 49 1 50)} {:upvalue-count 3 :arity 0 :constants ("swap-html-string" "post-swap") :bytecode (20 0 0 18 0 18 1 18 2 48 3 5 20 1 0 18 0 49 1 50)}) :bytecode (20 0 0 16 0 48 1 17 2 20 1 0 20 2 0 16 0 1 3 0 48 2 20 4 0 20 5 0 48 0 1 6 0 48 2 48 2 17 3 16 3 1 7 0 52 8 0 2 17 4 16 3 1 9 0 52 8 0 2 17 5 16 1 52 10 0 1 17 6 16 6 52 11 0 1 167 33 88 0 20 12 0 16 2 48 1 5 16 6 1 13 0 52 14 0 2 33 49 0 20 15 0 16 6 48 1 17 7 20 16 0 1 17 0 2 48 2 17 8 20 18 0 16 8 16 7 48 2 5 20 19 0 16 5 51 20 0 1 2 1 8 1 4 49 2 32 16 0 20 19 0 16 5 51 21 0 1 2 1 6 1 4 49 2 32 1 0 2 50)} "bind-inline-handlers" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ({:upvalue-count 1 :arity 1 :constants (1 "nth" "string?" "sx-on:" "starts-with?" 6 "slice" "after" "before" "sx:" "str" "is-processed?" "on:" "mark-processed!" "dom-on" "." "contains?" {:upvalue-count 2 :arity 1 :constants ("dom-window" "Function" "event" "host-call" "call") :bytecode (20 0 0 48 0 1 1 0 1 2 0 18 0 52 3 0 4 1 4 0 18 1 16 0 52 3 0 4 50)} "parse" {:upvalue-count 2 :arity 1 :constants ("make-env" "event" "env-bind!" "this" "detail" "event-detail" {:upvalue-count 1 :arity 1 :constants ("eval-expr") :bytecode (16 0 18 0 52 0 0 2 50)} "for-each") :bytecode (20 0 0 48 0 17 1 16 1 1 1 0 16 0 52 2 0 3 5 16 1 1 3 0 18 0 52 2 0 3 5 16 1 1 4 0 20 5 0 16 0 48 1 52 2 0 3 5 51 6 0 1 1 18 1 52 7 0 2 50)}) :bytecode (16 0 169 17 1 16 0 1 0 0 52 1 0 2 17 2 16 1 52 2 0 1 6 33 10 0 5 16 1 1 3 0 52 4 0 2 33 143 0 16 1 1 5 0 52 6 0 2 17 3 16 3 1 7 0 52 4 0 2 6 34 10 0 5 16 3 1 8 0 52 4 0 2 33 12 0 1 9 0 16 3 52 10 0 2 32 2 0 16 3 17 3 20 11 0 18 0 1 12 0 16 3 52 10 0 2 48 2 167 33 66 0 20 13 0 18 0 1 12 0 16 3 52 10 0 2 48 2 5 20 14 0 18 0 16 3 16 2 1 15 0 52 16 0 2 33 10 0 51 17 0 1 2 0 0 32 15 0 16 2 52 18 0 1 17 4 51 19 0 0 0 1 4 49 3 32 1 0 2 32 1 0 2 50)} "dom-attr-list" "for-each") :bytecode (51 0 0 1 0 20 1 0 16 0 48 1 52 2 0 2 50)} "dom-query-all" "dom-body" "[sx-on\\:]" "for-each") :bytecode (51 0 0 20 1 0 16 0 6 34 6 0 5 20 2 0 48 0 1 3 0 48 2 52 4 0 2 50)} "bind-preload-for" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-preload" "mousedown" "touchstart" "list" "mouseover" 0 100 "bind-preload" {:upvalue-count 1 :arity 0 :constants ("get-verb-info" "do-preload" "url" "get" "build-request-headers" "loaded-component-names") :bytecode (20 0 0 18 0 48 1 17 0 16 0 33 29 0 20 1 0 16 0 1 2 0 52 3 0 2 20 4 0 18 0 20 5 0 48 0 48 2 49 2 32 1 0 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 70 0 16 1 1 2 0 164 33 13 0 1 2 0 1 3 0 52 4 0 2 32 7 0 1 5 0 52 4 0 1 17 2 16 1 1 2 0 164 33 6 0 1 6 0 32 3 0 1 7 0 17 3 20 8 0 16 0 16 2 16 3 51 9 0 1 0 49 4 32 1 0 2 50)} "do-preload" {:upvalue-count 0 :arity 2 :constants ("preload-cache-get" "_preload-cache" "nil?" "fetch-preload") :bytecode (20 0 0 20 1 0 16 0 48 2 52 2 0 1 33 15 0 20 3 0 16 0 16 1 20 1 0 49 3 32 1 0 2 50)} "VERB_SELECTOR" "[sx-get],[sx-post],[sx-put],[sx-delete],[sx-patch]" "str" "process-elements" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "VERB_SELECTOR" {:upvalue-count 0 :arity 1 :constants ("is-processed?" "verb" "process-one" "mark-processed!") :bytecode (20 0 0 16 0 1 1 0 48 2 167 33 21 0 20 2 0 16 0 48 1 5 20 3 0 16 0 1 1 0 49 2 32 1 0 2 50)} "for-each" "process-boosted" "process-sse" "bind-inline-handlers" "process-emit-elements" "hs-boot-subtree!" "document" "host-global" "htmx-boot-subtree!") :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 20 2 0 48 2 17 1 51 3 0 16 1 52 4 0 2 5 20 5 0 16 0 48 1 5 20 6 0 16 0 48 1 5 20 7 0 16 0 48 1 5 20 8 0 16 0 48 1 5 20 9 0 16 0 6 34 8 0 5 1 10 0 52 11 0 1 48 1 5 20 12 0 16 0 6 34 8 0 5 1 10 0 52 11 0 1 49 1 50)} "process-one" {:upvalue-count 0 :arity 1 :constants ("get-verb-info" "dom-has-attr?" "sx-disable" "bind-triggers" "bind-preload-for") :bytecode (20 0 0 16 0 48 1 17 1 16 1 33 46 0 20 1 0 16 0 1 2 0 48 2 167 33 28 0 20 3 0 16 0 16 1 48 2 5 20 4 0 16 0 48 1 5 20 4 0 16 0 49 1 32 1 0 2 32 1 0 2 50)} "process-emit-elements" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "[data-sx-emit]" {:upvalue-count 0 :arity 1 :constants ("is-processed?" "emit" "mark-processed!" "dom-get-attr" "data-sx-emit" "dom-on" "click" {:upvalue-count 2 :arity 1 :constants ("dom-get-attr" "data-sx-emit-detail" "json-parse" "dict" "dom-dispatch") :bytecode (20 0 0 18 0 1 1 0 48 2 17 1 16 1 33 10 0 20 2 0 16 1 48 1 32 4 0 52 3 0 0 17 2 20 4 0 18 0 18 1 16 2 49 3 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 167 33 52 0 20 2 0 16 0 1 1 0 48 2 5 20 3 0 16 0 1 4 0 48 2 17 1 16 1 33 20 0 20 5 0 16 0 1 6 0 51 7 0 1 0 1 1 49 3 32 1 0 2 32 1 0 2 50)} "for-each") :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 1 2 0 48 2 17 1 51 3 0 16 1 52 4 0 2 50)} "save-scroll-position" {:upvalue-count 0 :arity 0 :constants ("dom-window" "scrollY" "host-get" "browser-replace-state" "dict" "" "browser-location-href") :bytecode (20 0 0 48 0 1 1 0 52 2 0 2 17 0 20 3 0 1 1 0 16 0 52 4 0 2 1 5 0 20 6 0 48 0 49 3 50)} "handle-popstate" {:upvalue-count 0 :arity 1 :constants ("browser-location-href" "dom-query" "[sx-boost]" "dom-get-attr" "sx-boost" "true" "#sx-content" "url-pathname" "try-client-route" "build-request-headers" "loaded-component-names" "fetch-and-restore") :bytecode (20 0 0 48 0 17 1 20 1 0 1 2 0 48 1 17 2 16 2 33 40 0 20 3 0 16 2 1 4 0 48 2 17 3 16 3 6 33 8 0 5 16 3 1 5 0 164 167 33 5 0 16 3 32 3 0 1 6 0 32 3 0 1 6 0 17 3 20 1 0 16 3 48 1 17 4 20 7 0 16 1 48 1 17 5 16 4 33 47 0 20 8 0 16 5 16 3 48 2 167 33 30 0 20 9 0 16 4 20 10 0 48 0 48 2 17 6 20 11 0 16 4 16 1 16 6 16 0 49 4 32 1 0 2 32 1 0 2 50)} "engine-init" {:upvalue-count 0 :arity 0 :constants ("sx-process-scripts" "sx-hydrate" "process-elements") :bytecode (20 0 0 2 48 1 5 20 1 0 2 48 1 5 20 2 0 2 49 1 50)} {:library (web orchestration) :op "import"}) :bytecode (52 1 0 0 128 0 0 5 51 3 0 128 2 0 5 51 5 0 128 4 0 5 51 7 0 128 6 0 5 51 9 0 128 8 0 5 51 11 0 128 10 0 5 51 13 0 128 12 0 5 51 15 0 128 14 0 5 51 17 0 128 16 0 5 51 19 0 128 18 0 5 51 21 0 128 20 0 5 51 23 0 128 22 0 5 51 25 0 128 24 0 5 51 27 0 128 26 0 5 51 29 0 128 28 0 5 51 31 0 128 30 0 5 51 33 0 128 32 0 5 51 35 0 128 34 0 5 52 1 0 0 128 36 0 5 1 38 0 128 37 0 5 51 40 0 128 39 0 5 51 42 0 128 41 0 5 51 44 0 128 43 0 5 51 46 0 128 45 0 5 51 48 0 128 47 0 5 51 50 0 128 49 0 5 51 52 0 128 51 0 5 52 1 0 0 128 53 0 5 51 55 0 128 54 0 5 51 57 0 128 56 0 5 51 59 0 128 58 0 5 51 61 0 128 60 0 5 3 128 62 0 5 52 64 0 0 128 63 0 5 51 66 0 128 65 0 5 51 68 0 128 67 0 5 51 70 0 128 69 0 5 51 72 0 128 71 0 5 51 74 0 128 73 0 5 51 76 0 128 75 0 5 51 78 0 128 77 0 5 51 80 0 128 79 0 5 51 82 0 128 81 0 5 51 84 0 128 83 0 5 51 86 0 128 85 0 5 51 88 0 128 87 0 5 51 90 0 128 89 0 5 51 92 0 128 91 0 5 51 94 0 128 93 0 5 51 96 0 128 95 0 5 51 98 0 128 97 0 5 51 100 0 128 99 0 5 1 102 0 52 103 0 1 128 101 0 5 51 105 0 128 104 0 5 51 107 0 128 106 0 5 51 109 0 128 108 0 5 51 111 0 128 110 0 5 51 113 0 128 112 0 5 51 115 0 128 114 0 5 1 116 0 112 50))) + :constants ("_preload-cache" "dict" "dispatch-trigger-events" {:upvalue-count 0 :arity 2 :constants ("try-parse-json" {:upvalue-count 2 :arity 1 :constants ("dom-dispatch" "get") :bytecode (20 0 0 18 0 16 0 18 1 16 0 52 1 0 2 49 3 50)} "keys" "for-each" {:upvalue-count 1 :arity 1 :constants ("trim" "empty?" "dom-dispatch" "dict") :bytecode (16 0 52 0 0 1 17 1 16 1 52 1 0 1 167 33 16 0 20 2 0 18 0 16 1 52 3 0 0 49 3 32 1 0 2 50)} "," "split") :bytecode (16 1 33 55 0 20 0 0 16 1 48 1 17 2 16 2 33 20 0 51 1 0 1 0 1 2 16 2 52 2 0 1 52 3 0 2 32 18 0 51 4 0 1 0 16 1 1 5 0 52 6 0 2 52 3 0 2 32 1 0 2 50)} "execute-request" {:upvalue-count 0 :arity 3 :constants ("get-verb-info" "nil?" "promise-resolve" "method" "get" "url" "dom-get-attr" "sx-media" "browser-media-matches?" "sx-confirm" "browser-confirm" "sx-prompt" "browser-prompt" "validate-for-request" "do-fetch" "dict" "SX-Prompt" "assoc") :bytecode (20 0 0 16 0 48 1 6 34 3 0 5 16 1 17 3 16 3 52 1 0 1 33 9 0 20 2 0 2 49 1 32 240 0 16 3 1 3 0 52 4 0 2 17 4 16 3 1 5 0 52 4 0 2 17 5 20 6 0 16 0 1 7 0 48 2 17 6 16 6 6 33 9 0 5 20 8 0 16 6 48 1 167 33 9 0 20 2 0 2 49 1 32 179 0 20 6 0 16 0 1 9 0 48 2 17 6 16 6 6 33 9 0 5 20 10 0 16 6 48 1 167 33 9 0 20 2 0 2 49 1 32 140 0 20 6 0 16 0 1 11 0 48 2 17 6 16 6 33 10 0 20 12 0 16 6 48 1 32 1 0 2 17 7 16 6 6 33 7 0 5 16 7 52 1 0 1 33 9 0 20 2 0 2 49 1 32 85 0 16 4 52 1 0 1 6 34 20 0 5 16 5 52 1 0 1 6 34 9 0 5 20 13 0 16 0 48 1 167 33 9 0 20 2 0 2 49 1 32 43 0 20 14 0 16 0 16 4 16 4 16 5 16 7 33 23 0 16 2 6 34 5 0 5 52 15 0 0 1 16 0 16 7 52 17 0 3 32 2 0 16 2 49 5 50)} "do-fetch" {:upvalue-count 0 :arity 5 :constants ("dom-get-attr" "sx-sync" "replace" "abort-previous" "resolve-target" "identical?" "abort-previous-target" "new-abort-controller" "track-controller" "track-controller-target" "build-request-body" "url" "get" "body" "content-type" "build-request-headers" "loaded-component-names" "csrf-token" {:upvalue-count 2 :arity 1 :constants ("get" "dict-set!") :bytecode (18 0 16 0 18 1 16 0 52 0 0 2 52 1 0 3 50)} "keys" "for-each" "Content-Type" "dict-set!" "X-CSRFToken" "preload-cache-get" "_preload-cache" "apply-optimistic" "show-indicator" "disable-elements" "dom-add-class" "sx-request" "dom-set-attr" "aria-busy" "true" "dom-dispatch" "sx:beforeRequest" "method" "dict" "fetch-request" "headers" "signal" "controller-signal" "cross-origin" "cross-origin?" "preloaded" {:upvalue-count 8 :arity 4 :constants ("clear-loading-state" "revert-optimistic" "dom-dispatch" "sx:responseError" "status" "text" "dict" "dom-add-class" "sx-error" 0 "handle-fetch-success" "handle-retry" "sx:afterRequest") :bytecode (20 0 0 18 0 18 1 18 2 48 3 5 20 1 0 18 3 48 1 5 16 0 167 33 91 0 20 2 0 18 0 1 3 0 1 4 0 16 1 1 5 0 16 3 52 6 0 4 48 3 5 20 7 0 18 0 1 8 0 48 2 5 16 3 6 33 8 0 5 16 3 168 1 9 0 166 33 20 0 20 10 0 18 0 18 4 18 5 18 6 16 2 16 3 49 6 32 15 0 20 11 0 18 0 18 5 18 7 18 4 18 6 49 5 32 37 0 20 2 0 18 0 1 12 0 1 4 0 16 1 52 6 0 2 48 3 5 20 10 0 18 0 18 4 18 5 18 6 16 2 16 3 49 6 50)} {:upvalue-count 8 :arity 1 :constants ("clear-loading-state" "revert-optimistic" "abort-error?" "log-warn" "sx:fetch error " " " " — " "str" "dom-dispatch" "sx:requestError" "error" "dict" "dom-add-class" "sx-error" "handle-retry") :bytecode (20 0 0 18 0 18 1 18 2 48 3 5 20 1 0 18 3 48 1 5 20 2 0 16 0 48 1 167 33 74 0 20 3 0 1 4 0 18 4 1 5 0 18 5 1 6 0 16 0 52 7 0 6 48 1 5 20 8 0 18 0 1 9 0 1 10 0 16 0 52 11 0 2 48 3 5 20 12 0 18 0 1 13 0 48 2 5 20 14 0 18 0 18 6 18 4 18 5 18 7 49 5 32 1 0 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 5 16 5 1 2 0 164 33 10 0 20 3 0 16 0 48 1 32 1 0 2 5 20 4 0 16 0 48 1 17 6 16 6 6 33 10 0 5 16 0 16 6 52 5 0 2 167 33 10 0 20 6 0 16 6 48 1 32 1 0 2 5 20 7 0 48 0 17 6 20 8 0 16 0 16 6 48 2 5 20 4 0 16 0 48 1 17 7 16 7 33 12 0 20 9 0 16 7 16 6 48 2 32 1 0 2 5 20 10 0 16 0 16 2 16 3 48 3 17 7 16 7 1 11 0 52 12 0 2 17 8 16 7 1 13 0 52 12 0 2 17 9 16 7 1 14 0 52 12 0 2 17 10 20 15 0 16 0 20 16 0 48 0 48 2 17 11 20 17 0 48 0 17 12 16 4 33 20 0 51 18 0 1 11 1 4 16 4 52 19 0 1 52 20 0 2 32 1 0 2 5 16 10 33 14 0 16 11 1 21 0 16 10 52 22 0 3 32 1 0 2 5 16 12 33 14 0 16 11 1 23 0 16 12 52 22 0 3 32 1 0 2 5 20 24 0 20 25 0 16 8 48 2 17 13 20 26 0 16 0 48 1 17 14 20 27 0 16 0 48 1 17 15 20 28 0 16 0 48 1 17 16 20 29 0 16 0 1 30 0 48 2 5 20 31 0 16 0 1 32 0 1 33 0 48 3 5 20 34 0 16 0 1 35 0 1 11 0 16 8 1 36 0 16 2 52 37 0 4 48 3 5 20 38 0 1 11 0 16 8 1 36 0 16 2 1 39 0 16 11 1 13 0 16 9 1 40 0 20 41 0 16 6 48 1 1 42 0 20 43 0 16 8 48 1 1 44 0 16 13 52 37 0 14 51 45 0 1 0 1 15 1 16 1 14 1 8 1 1 1 4 1 2 51 46 0 1 0 1 15 1 16 1 14 1 2 1 8 1 1 1 4 49 3 50)} "handle-fetch-success" {:upvalue-count 0 :arity 6 :constants ("process-response-headers" "dom-remove-class" "sx-error" "dom-remove-attr" "data-sx-retry-ms" "dispatch-trigger-events" "trigger" "get" "process-cache-directives" "redirect" "browser-navigate" "refresh" "browser-reload" "location" "fetch-location" "retarget" "dom-query" "resolve-target" "parse-swap-spec" "reswap" "dom-get-attr" "sx-swap" "dom-has-class?" "dom-body" "sx-transitions" "style" "transition" "content-type" "" "text/sx" "contains?" "handle-sx-response" "handle-html-response" "trigger-swap" "handle-history" "set-timeout" {:upvalue-count 2 :arity 0 :constants ("trigger-settle" "get" "dispatch-trigger-events" "process-settle-hooks") :bytecode (18 0 1 0 0 52 1 0 2 33 19 0 20 2 0 18 1 18 0 1 0 0 52 1 0 2 48 2 32 1 0 2 5 20 3 0 18 1 49 1 50)} 20 "dom-dispatch" "sx:afterSwap" "target" "swap" "dict") :bytecode (20 0 0 16 4 48 1 17 6 20 1 0 16 0 1 2 0 48 2 5 20 3 0 16 0 1 4 0 48 2 5 20 5 0 16 0 16 6 1 6 0 52 7 0 2 48 2 5 20 8 0 16 0 16 6 16 5 48 3 5 16 6 1 9 0 52 7 0 2 33 17 0 20 10 0 16 6 1 9 0 52 7 0 2 49 1 32 31 1 16 6 1 11 0 52 7 0 2 33 8 0 20 12 0 49 0 32 11 1 16 6 1 13 0 52 7 0 2 33 17 0 20 14 0 16 6 1 13 0 52 7 0 2 49 1 32 238 0 16 6 1 15 0 52 7 0 2 33 17 0 20 16 0 16 6 1 15 0 52 7 0 2 48 1 32 7 0 20 17 0 16 0 48 1 17 7 20 18 0 16 6 1 19 0 52 7 0 2 6 34 11 0 5 20 20 0 16 0 1 21 0 48 2 20 22 0 20 23 0 48 0 1 24 0 48 2 48 2 17 8 16 8 1 25 0 52 7 0 2 17 9 16 8 1 26 0 52 7 0 2 17 10 16 6 1 27 0 52 7 0 2 6 34 4 0 5 1 28 0 17 11 16 11 1 29 0 52 30 0 2 33 18 0 20 31 0 16 0 16 7 16 5 16 9 16 10 48 5 32 15 0 20 32 0 16 0 16 7 16 5 16 9 16 10 48 5 5 20 5 0 16 0 16 6 1 33 0 52 7 0 2 48 2 5 20 34 0 16 0 16 1 16 6 48 3 5 20 35 0 51 36 0 1 6 1 0 1 37 0 48 2 5 20 38 0 16 0 1 39 0 1 40 0 16 7 1 41 0 16 9 52 42 0 4 49 3 50)} "flush-collected-styles" {:upvalue-count 0 :arity 0 :constants ("cssx" "collected" "empty?" "clear-collected!" "dom-create-element" "style" "dom-set-attr" "data-sx-css" "true" "dom-set-prop" "textContent" "" "join" "dom-append-to-head") :bytecode (1 0 0 52 1 0 1 17 0 16 0 52 2 0 1 167 33 63 0 1 0 0 52 3 0 1 5 20 4 0 1 5 0 2 48 2 17 1 20 6 0 16 1 1 7 0 1 8 0 48 3 5 20 9 0 16 1 1 10 0 1 11 0 16 0 52 12 0 2 48 3 5 20 13 0 16 1 49 1 32 1 0 2 50)} "handle-sx-response" {:upvalue-count 0 :arity 5 :constants ("strip-component-scripts" "extract-response-css" "trim" "empty?" "sx-render" "dom-create-element" "div" "dom-append" "process-oob-swaps" {:upvalue-count 0 :arity 3 :constants ("dispose-islands-in" "swap-dom-nodes" "innerHTML" "children-to-fragment" "post-swap") :bytecode (20 0 0 16 0 48 1 5 20 1 0 16 0 16 2 1 2 0 164 33 10 0 20 3 0 16 1 48 1 32 2 0 16 1 16 2 48 3 5 20 4 0 16 0 49 1 50)} "hoist-head-elements" "dom-get-attr" "sx-select" "select-from-container" "children-to-fragment" "dispose-islands-in" "with-transition" {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "post-swap" "outerHTML" "dom-parent") :bytecode (20 0 0 18 0 18 1 18 2 48 3 17 0 20 1 0 18 2 1 2 0 164 33 17 0 20 3 0 16 0 6 34 3 0 5 18 0 48 1 32 9 0 16 0 6 34 3 0 5 18 0 49 1 50)}) :bytecode (20 0 0 16 2 48 1 17 5 20 1 0 16 5 48 1 17 6 16 6 52 2 0 1 17 7 16 7 52 3 0 1 167 33 114 0 20 4 0 16 7 48 1 17 8 20 5 0 1 6 0 2 48 2 17 9 20 7 0 16 9 16 8 48 2 5 20 8 0 16 9 51 9 0 48 2 5 20 10 0 16 9 48 1 5 20 11 0 16 0 1 12 0 48 2 17 10 16 10 33 12 0 20 13 0 16 9 16 10 48 2 32 7 0 20 14 0 16 9 48 1 17 11 20 15 0 16 1 48 1 5 20 16 0 16 4 51 17 0 1 1 1 11 1 3 49 2 32 1 0 2 50)} "handle-html-response" {:upvalue-count 0 :arity 5 :constants ("dom-parse-html-document" "dom-get-attr" "sx-select" "dispose-islands-in" "dom-create-element" "div" "dom-set-inner-html" "dom-body-inner-html" "process-oob-swaps" {:upvalue-count 0 :arity 3 :constants ("dispose-islands-in" "swap-dom-nodes" "post-swap") :bytecode (20 0 0 16 0 48 1 5 20 1 0 16 0 16 1 16 2 48 3 5 20 2 0 16 0 49 1 50)} "hoist-head-elements" "dom-query" "script[data-sx-manifest]" "Sx" "host-global" "mergeManifest" "host-call" "select-from-container" "with-transition" {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "log-info" "swap-root: " "dom-tag-name" "nil" " target: " "str" "post-swap") :bytecode (20 0 0 18 0 18 1 18 2 48 3 17 0 20 1 0 1 2 0 16 0 33 10 0 20 3 0 16 0 48 1 32 3 0 1 4 0 1 5 0 20 3 0 18 0 48 1 52 6 0 4 48 1 5 20 7 0 16 0 6 34 3 0 5 18 0 49 1 50)} {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "children-to-fragment" "post-swap") :bytecode (20 0 0 18 0 20 1 0 18 1 48 1 18 2 48 3 17 0 20 2 0 16 0 6 34 3 0 5 18 0 49 1 50)}) :bytecode (20 0 0 16 2 48 1 17 5 16 5 33 202 0 20 1 0 16 0 1 2 0 48 2 17 6 20 3 0 16 1 48 1 5 16 6 33 113 0 20 4 0 1 5 0 2 48 2 17 7 20 6 0 16 7 20 7 0 16 5 48 1 48 2 5 20 8 0 16 7 51 9 0 48 2 5 20 10 0 16 7 48 1 5 20 11 0 16 7 1 12 0 48 2 17 8 16 8 33 19 0 1 13 0 52 14 0 1 1 15 0 16 8 52 16 0 3 32 1 0 2 5 20 17 0 16 7 16 6 48 2 17 8 20 18 0 16 4 51 19 0 1 1 1 8 1 3 49 2 32 61 0 20 4 0 1 5 0 2 48 2 17 7 20 6 0 16 7 20 7 0 16 5 48 1 48 2 5 20 8 0 16 7 51 9 0 48 2 5 20 10 0 16 7 48 1 5 20 18 0 16 4 51 20 0 1 1 1 7 1 3 49 2 32 1 0 2 50)} "handle-retry" {:upvalue-count 0 :arity 5 :constants ("dom-get-attr" "sx-retry" "parse-retry-spec" "data-sx-retry-ms" "start-ms" "get" "parse-int" "dom-set-attr" "next-retry-ms" "cap-ms" "str" "set-timeout" {:upvalue-count 5 :arity 0 :constants ("do-fetch") :bytecode (20 0 0 18 0 18 1 18 2 18 3 18 4 49 5 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 5 20 2 0 16 5 48 1 17 6 16 6 33 97 0 20 0 0 16 0 1 3 0 48 2 6 34 10 0 5 16 6 1 4 0 52 5 0 2 17 7 16 7 16 6 1 4 0 52 5 0 2 52 6 0 2 17 8 20 7 0 16 0 1 3 0 20 8 0 16 8 16 6 1 9 0 52 5 0 2 48 2 52 10 0 1 48 3 5 20 11 0 51 12 0 1 0 1 1 1 2 1 3 1 4 16 8 49 2 32 1 0 2 50)} "bind-triggers" {:upvalue-count 0 :arity 2 :constants ("parse-trigger-spec" "dom-get-attr" "sx-trigger" "default-trigger" "dom-tag-name" {:upvalue-count 2 :arity 1 :constants ("classify-trigger" "modifiers" "get" "poll" "set-interval" {:upvalue-count 2 :arity 0 :constants ("isConnected" "host-get" "execute-request" "clear-interval" "log-info" "poll stopped: element removed") :bytecode (18 0 1 0 0 52 1 0 2 33 12 0 20 2 0 18 0 2 2 49 3 32 16 0 20 3 0 18 1 48 1 5 20 4 0 1 5 0 49 1 50)} "interval" "intersect" "observe-intersection" {:upvalue-count 1 :arity 0 :constants ("execute-request") :bytecode (20 0 0 18 0 2 2 49 3 50)} "delay" "load" "set-timeout" 0 "revealed" "event" "bind-event") :bytecode (20 0 0 16 0 48 1 17 1 16 0 1 1 0 52 2 0 2 17 2 16 1 1 3 0 164 33 29 0 2 17 3 20 4 0 51 5 0 0 0 1 3 16 2 1 6 0 52 2 0 2 48 2 17 3 32 140 0 16 1 1 7 0 164 33 25 0 20 8 0 18 0 51 9 0 0 0 3 16 2 1 10 0 52 2 0 2 49 4 32 106 0 16 1 1 11 0 164 33 30 0 20 12 0 51 9 0 0 0 16 2 1 10 0 52 2 0 2 6 34 4 0 5 1 13 0 49 2 32 67 0 16 1 1 14 0 164 33 25 0 20 8 0 18 0 51 9 0 0 0 4 16 2 1 10 0 52 2 0 2 49 4 32 33 0 16 1 1 15 0 164 33 23 0 20 16 0 18 0 16 0 1 15 0 52 2 0 2 16 2 18 1 49 4 32 1 0 2 50)} "for-each") :bytecode (20 0 0 20 1 0 16 0 1 2 0 48 2 48 1 6 34 13 0 5 20 3 0 20 4 0 16 0 48 1 48 1 17 2 51 5 0 1 0 1 1 16 2 52 6 0 2 50)} "bind-event" {:upvalue-count 0 :arity 4 :constants ("from" "get" "nil?" "body" "dom-body" "document" "dom-document" "window" "dom-window" "dom-query" "dom-add-listener" {:upvalue-count 5 :arity 1 :constants ("filter" "get" "key=='" "index-of" 0 ">=" 5 6 "slice" "key" "host-get" "dom-matches?" "target" "input,textarea,select" "changed" "element-value" "click" "event-modifier-key?" "submit" "dom-has-attr?" "href" "prevent-default" "get-verb-info" "method" "GET" "delay" "try-client-route" "url-pathname" "url" "dom-get-attr" "sx-target" "save-scroll-position" "browser-push-state" "browser-scroll-to" "log-info" "sx:route server fetch " "str" "clear-timeout" "set-timeout" {:upvalue-count 1 :arity 0 :constants ("execute-request") :bytecode (20 0 0 18 0 2 2 49 3 50)} "execute-request") :bytecode (18 0 1 0 0 52 1 0 2 33 96 0 18 0 1 0 0 52 1 0 2 17 1 16 1 1 2 0 52 3 0 2 17 2 16 2 1 4 0 52 5 0 2 33 58 0 16 1 16 2 1 6 0 160 16 2 1 7 0 160 52 8 0 3 17 3 16 0 1 9 0 52 10 0 2 16 3 164 6 33 19 0 5 20 11 0 16 0 1 12 0 52 10 0 2 1 13 0 48 2 167 32 1 0 3 32 1 0 3 17 1 18 0 1 14 0 52 1 0 2 33 26 0 20 15 0 17 2 16 2 18 1 164 33 6 0 4 17 1 32 4 0 16 2 19 1 32 1 0 2 5 16 1 6 33 20 0 5 18 2 1 16 0 164 6 33 8 0 5 20 17 0 16 0 48 1 167 33 27 1 18 2 1 18 0 164 6 34 22 0 5 18 2 1 16 0 164 6 33 11 0 5 20 19 0 18 3 1 20 0 48 2 33 10 0 20 21 0 16 0 48 1 32 1 0 2 5 20 22 0 18 3 48 1 17 2 18 2 1 16 0 164 6 33 44 0 5 16 2 1 23 0 52 1 0 2 1 24 0 164 6 33 26 0 5 20 19 0 18 3 1 20 0 48 2 6 33 11 0 5 18 0 1 25 0 52 1 0 2 167 17 3 4 17 4 16 3 33 34 0 20 26 0 20 27 0 16 2 1 28 0 52 1 0 2 48 1 20 29 0 18 3 1 30 0 48 2 48 2 17 4 32 1 0 2 5 16 4 33 35 0 20 31 0 48 0 5 20 32 0 16 2 1 28 0 52 1 0 2 48 1 5 20 33 0 1 4 0 1 4 0 49 2 32 84 0 16 3 33 24 0 20 34 0 1 35 0 16 2 1 28 0 52 1 0 2 52 36 0 2 48 1 32 1 0 2 5 18 0 1 25 0 52 1 0 2 33 32 0 20 37 0 18 4 48 1 5 20 38 0 51 39 0 0 3 18 0 1 25 0 52 1 0 2 48 2 19 4 32 9 0 20 40 0 18 3 2 2 49 3 32 1 0 2 50)} "once" "dict") :bytecode (2 17 4 2 17 5 16 2 1 0 0 52 1 0 2 17 6 16 6 52 2 0 1 33 5 0 16 0 32 58 0 16 6 1 3 0 164 33 8 0 20 4 0 48 0 32 41 0 16 6 1 5 0 164 33 8 0 20 6 0 48 0 32 24 0 16 6 1 7 0 164 33 8 0 20 8 0 48 0 32 7 0 20 9 0 16 6 48 1 17 6 16 6 33 49 0 20 10 0 16 6 16 1 51 11 0 1 2 1 5 1 1 1 0 1 4 16 2 1 12 0 52 1 0 2 33 11 0 1 12 0 3 52 13 0 2 32 1 0 2 49 4 32 1 0 2 50)} "post-swap" {:upvalue-count 0 :arity 1 :constants ("log-info" "post-swap: root=" "dom-tag-name" "nil" "str" "activate-scripts" "sx-process-scripts" "sx-hydrate" "sx-hydrate-islands" "run-post-render-hooks" "flush-collected-styles" "process-elements") :bytecode (20 0 0 1 1 0 16 0 33 10 0 20 2 0 16 0 48 1 32 3 0 1 3 0 52 4 0 2 48 1 5 20 5 0 16 0 48 1 5 20 6 0 16 0 48 1 5 20 7 0 16 0 48 1 5 20 8 0 16 0 48 1 5 20 9 0 48 0 5 20 10 0 48 0 5 20 11 0 16 0 49 1 50)} "process-settle-hooks" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-on-settle" "empty?" "sx-parse" {:upvalue-count 0 :arity 1 :constants ("cek-eval") :bytecode (20 0 0 16 0 49 1 50)} "for-each") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 6 33 8 0 5 16 1 52 2 0 1 167 33 21 0 20 3 0 16 1 48 1 17 2 51 4 0 16 2 52 5 0 2 32 1 0 2 50)} "activate-scripts" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "script" {:upvalue-count 0 :arity 1 :constants ("dom-has-attr?" "data-components" "data-sx-activated" "create-script-clone" "dom-set-attr" "true" "dom-replace-child" "dom-parent") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 12 0 5 20 0 0 16 0 1 2 0 48 2 167 33 42 0 20 3 0 16 0 48 1 17 1 20 4 0 16 1 1 2 0 1 5 0 48 3 5 20 6 0 20 7 0 16 0 48 1 16 1 16 0 49 3 32 1 0 2 50)} "for-each") :bytecode (16 0 33 24 0 20 0 0 16 0 1 1 0 48 2 17 1 51 2 0 16 1 52 3 0 2 32 1 0 2 50)} "process-oob-swaps" {:upvalue-count 0 :arity 2 :constants ("find-oob-swaps" {:upvalue-count 1 :arity 1 :constants ("target-id" "get" "dom-query-by-id" "element" "swap-type" "dom-parent" "dom-remove-child") :bytecode (16 0 1 0 0 52 1 0 2 17 1 20 2 0 16 1 48 1 17 2 16 0 1 3 0 52 1 0 2 17 3 16 0 1 4 0 52 1 0 2 17 4 20 5 0 16 3 48 1 33 17 0 20 6 0 20 5 0 16 3 48 1 16 3 48 2 32 1 0 2 5 16 2 33 13 0 18 0 16 2 16 3 16 4 49 3 32 1 0 2 50)} "for-each") :bytecode (20 0 0 16 0 48 1 17 2 51 1 0 1 1 16 2 52 2 0 2 50)} "hoist-head-elements" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ("dom-parent" "dom-remove-child" "dom-append-to-head") :bytecode (20 0 0 16 0 48 1 33 17 0 20 1 0 20 0 0 16 0 48 1 16 0 48 2 32 1 0 2 5 20 2 0 16 0 49 1 50)} "dom-query-all" "style[data-sx-css]" "for-each" "link[rel=\"stylesheet\"]") :bytecode (51 0 0 20 1 0 16 0 1 2 0 48 2 52 3 0 2 5 51 0 0 20 1 0 16 0 1 4 0 48 2 52 3 0 2 50)} "process-boosted" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ("boost-descendants") :bytecode (20 0 0 16 0 49 1 50)} "dom-query-all" "dom-body" "[sx-boost]" "for-each" "dom-closest" "boost-descendants") :bytecode (51 0 0 20 1 0 16 0 6 34 6 0 5 20 2 0 48 0 1 3 0 48 2 52 4 0 2 5 16 0 33 31 0 20 5 0 16 0 1 3 0 48 2 17 1 16 1 33 10 0 20 6 0 16 1 49 1 32 1 0 2 32 1 0 2 50)} "boost-descendants" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-boost" {:upvalue-count 1 :arity 1 :constants ("is-processed?" "boost" "should-boost-link?" "mark-processed!" "dom-has-attr?" "sx-target" "true" "dom-set-attr" "sx-swap" "innerHTML" "sx-push-url" "bind-client-route-link" "dom-get-attr" "href") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 8 0 5 20 2 0 16 0 48 1 33 145 0 20 3 0 16 0 1 1 0 48 2 5 20 4 0 16 0 1 5 0 48 2 167 6 33 15 0 5 18 0 6 33 8 0 5 18 0 1 6 0 164 167 33 15 0 20 7 0 16 0 1 5 0 18 0 48 3 32 1 0 2 5 20 4 0 16 0 1 8 0 48 2 167 33 16 0 20 7 0 16 0 1 8 0 1 9 0 48 3 32 1 0 2 5 20 4 0 16 0 1 10 0 48 2 167 33 16 0 20 7 0 16 0 1 10 0 1 6 0 48 3 32 1 0 2 5 20 11 0 16 0 20 12 0 16 0 1 13 0 48 2 49 2 32 1 0 2 50)} "dom-query-all" "a[href]" "for-each" {:upvalue-count 1 :arity 1 :constants ("is-processed?" "boost" "should-boost-form?" "mark-processed!" "dom-get-attr" "method" "GET" "upper" "action" "browser-location-href" "dom-has-attr?" "sx-target" "true" "dom-set-attr" "sx-swap" "innerHTML" "bind-boost-form") :bytecode (20 0 0 16 0 1 1 0 48 2 167 6 33 8 0 5 20 2 0 16 0 48 1 33 153 0 20 3 0 16 0 1 1 0 48 2 5 20 4 0 16 0 1 5 0 48 2 6 34 4 0 5 1 6 0 52 7 0 1 17 1 20 4 0 16 0 1 8 0 48 2 6 34 6 0 5 20 9 0 48 0 17 2 20 10 0 16 0 1 11 0 48 2 167 6 33 15 0 5 18 0 6 33 8 0 5 18 0 1 12 0 164 167 33 15 0 20 13 0 16 0 1 11 0 18 0 48 3 32 1 0 2 5 20 10 0 16 0 1 14 0 48 2 167 33 16 0 20 13 0 16 0 1 14 0 1 15 0 48 3 32 1 0 2 5 20 16 0 16 0 16 1 16 2 49 3 32 1 0 2 50)} "form") :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 51 2 0 1 1 20 3 0 16 0 1 4 0 48 2 52 5 0 2 5 51 6 0 1 1 20 3 0 16 0 1 7 0 48 2 52 5 0 2 50)} "_page-data-cache" "_page-data-cache-ttl" 30000 "page-data-cache-key" {:upvalue-count 0 :arity 2 :constants ("nil?" "keys" "empty?" "list" {:upvalue-count 2 :arity 1 :constants ("=" "get" "str" "append!") :bytecode (18 0 16 0 1 0 0 18 1 16 0 52 1 0 2 52 2 0 3 52 3 0 2 50)} "for-each" ":" "&" "join" "str") :bytecode (16 0 17 2 16 1 52 0 0 1 6 34 11 0 5 16 1 52 1 0 1 52 2 0 1 33 5 0 16 2 32 42 0 52 3 0 0 17 3 51 4 0 1 3 1 1 16 1 52 1 0 1 52 5 0 2 5 16 2 1 6 0 1 7 0 16 3 52 8 0 2 52 9 0 3 50)} "page-data-cache-get" {:upvalue-count 0 :arity 1 :constants ("_page-data-cache" "get" "nil?" "now-ms" "ts" "_page-data-cache-ttl" "dict-set!" "data") :bytecode (20 0 0 16 0 52 1 0 2 17 1 16 1 52 2 0 1 33 4 0 2 32 46 0 20 3 0 48 0 16 1 1 4 0 52 1 0 2 161 20 5 0 166 33 15 0 20 0 0 16 0 2 52 6 0 3 5 2 32 9 0 16 1 1 7 0 52 1 0 2 50)} "page-data-cache-set" {:upvalue-count 0 :arity 2 :constants ("_page-data-cache" "data" "ts" "now-ms" "dict-set!") :bytecode (20 0 0 16 0 1 1 0 16 1 1 2 0 20 3 0 48 0 65 2 0 52 4 0 3 50)} "invalidate-page-cache" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 1 :arity 1 :constants (":" "str" "starts-with?" "_page-data-cache" "dict-set!") :bytecode (16 0 18 0 164 6 34 16 0 5 16 0 18 0 1 0 0 52 1 0 2 52 2 0 2 33 13 0 20 3 0 16 0 2 52 4 0 3 32 1 0 2 50)} "_page-data-cache" "keys" "for-each" "sw-post-message" "type" "invalidate" "page" "log-info" "sx:cache invalidate " "str") :bytecode (51 0 0 1 0 20 1 0 52 2 0 1 52 3 0 2 5 20 4 0 1 5 0 1 6 0 1 7 0 16 0 65 2 0 48 1 5 20 8 0 1 9 0 16 0 52 10 0 2 49 1 50)} "invalidate-all-page-cache" {:upvalue-count 0 :arity 0 :constants ("dict" "_page-data-cache" "sw-post-message" "type" "invalidate" "page" "*" "log-info" "sx:cache invalidate *") :bytecode (52 0 0 0 21 1 0 5 20 2 0 1 3 0 1 4 0 1 5 0 1 6 0 65 2 0 48 1 5 20 7 0 1 8 0 49 1 50)} "update-page-cache" {:upvalue-count 0 :arity 2 :constants ("page-data-cache-key" "dict" "page-data-cache-set" "log-info" "sx:cache update " "str") :bytecode (20 0 0 16 0 52 1 0 0 48 2 17 2 20 2 0 16 2 16 1 48 2 5 20 3 0 1 4 0 16 0 52 5 0 2 49 1 50)} "process-cache-directives" {:upvalue-count 0 :arity 3 :constants ("dom-get-attr" "sx-cache-invalidate" "*" "invalidate-all-page-cache" "invalidate-page-cache" "cache-invalidate" "get" "cache-update" "parse-sx-data" "update-page-cache") :bytecode (20 0 0 16 0 1 1 0 48 2 17 3 16 3 33 27 0 16 3 1 2 0 164 33 8 0 20 3 0 48 0 32 7 0 20 4 0 16 3 48 1 32 1 0 2 5 16 1 1 5 0 52 6 0 2 17 3 16 3 33 27 0 16 3 1 2 0 164 33 8 0 20 3 0 48 0 32 7 0 20 4 0 16 3 48 1 32 1 0 2 5 16 1 1 7 0 52 6 0 2 17 3 16 3 33 30 0 20 8 0 16 2 48 1 17 4 16 4 33 12 0 20 9 0 16 3 16 4 49 2 32 1 0 2 32 1 0 2 50)} "_optimistic-snapshots" "optimistic-cache-update" {:upvalue-count 0 :arity 2 :constants ("page-data-cache-get" "_optimistic-snapshots" "dict-set!" "page-data-cache-set") :bytecode (20 0 0 16 0 48 1 17 2 16 2 33 35 0 16 1 16 2 48 1 17 3 20 1 0 16 0 16 2 52 2 0 3 5 20 3 0 16 0 16 3 48 2 5 16 3 32 1 0 2 50)} "optimistic-cache-revert" {:upvalue-count 0 :arity 1 :constants ("_optimistic-snapshots" "get" "page-data-cache-set" "dict-delete!") :bytecode (20 0 0 16 0 52 1 0 2 17 1 16 1 33 25 0 20 2 0 16 0 16 1 48 2 5 20 0 0 16 0 52 3 0 2 5 16 1 32 1 0 2 50)} "optimistic-cache-confirm" {:upvalue-count 0 :arity 1 :constants ("_optimistic-snapshots" "dict-delete!") :bytecode (20 0 0 16 0 52 1 0 2 50)} "submit-mutation" {:upvalue-count 0 :arity 6 :constants ("page-data-cache-key" "optimistic-cache-update" "try-rerender-page" "execute-action" {:upvalue-count 4 :arity 1 :constants ("page-data-cache-set" "optimistic-cache-confirm" "try-rerender-page" "log-info" "sx:optimistic confirmed " "str" "confirmed") :bytecode (16 0 33 12 0 20 0 0 18 0 16 0 48 2 32 1 0 2 5 20 1 0 18 0 48 1 5 16 0 33 14 0 20 2 0 18 1 18 2 16 0 48 3 32 1 0 2 5 20 3 0 1 4 0 18 1 52 5 0 2 48 1 5 18 3 33 10 0 18 3 1 6 0 49 1 32 1 0 2 50)} {:upvalue-count 4 :arity 1 :constants ("optimistic-cache-revert" "try-rerender-page" "log-warn" "sx:optimistic reverted " ": " "str" "reverted") :bytecode (20 0 0 18 0 48 1 17 1 16 1 33 14 0 20 1 0 18 1 18 2 16 1 48 3 32 1 0 2 5 20 2 0 1 3 0 18 1 1 4 0 16 0 52 5 0 4 48 1 5 18 3 33 10 0 18 3 1 6 0 49 1 32 1 0 2 50)}) :bytecode (20 0 0 16 0 16 1 48 2 17 6 20 1 0 16 6 16 4 48 2 17 7 16 7 33 14 0 20 2 0 16 0 16 1 16 7 48 3 32 1 0 2 5 20 3 0 16 2 16 3 51 4 0 1 6 1 0 1 1 1 5 51 5 0 1 6 1 0 1 1 1 5 49 4 50)} "_is-online" "_offline-queue" "list" "offline-is-online?" {:upvalue-count 0 :arity 0 :constants ("_is-online") :bytecode (20 0 0 50)} "offline-set-online!" {:upvalue-count 0 :arity 1 :constants ("_is-online") :bytecode (16 0 21 0 0 50)} "offline-queue-mutation" {:upvalue-count 0 :arity 5 :constants ("page-data-cache-key" "action" "payload" "page" "params" "timestamp" "now-ms" "status" "pending" "dict" "_offline-queue" "append!" "optimistic-cache-update" "try-rerender-page" "log-info" "sx:offline queued " " (" " pending)" "str") :bytecode (20 0 0 16 2 16 3 48 2 17 5 1 1 0 16 0 1 2 0 16 1 1 3 0 16 2 1 4 0 16 3 1 5 0 20 6 0 48 0 1 7 0 1 8 0 52 9 0 12 17 6 20 10 0 16 6 52 11 0 2 5 20 12 0 16 5 16 4 48 2 17 7 16 7 33 14 0 20 13 0 16 2 16 3 16 7 48 3 32 1 0 2 5 20 14 0 1 15 0 16 0 1 16 0 20 10 0 168 1 17 0 52 18 0 5 48 1 5 16 6 50)} "offline-sync" {:upvalue-count 0 :arity 0 :constants ({:upvalue-count 0 :arity 1 :constants ("status" "get" "pending") :bytecode (16 0 1 0 0 52 1 0 2 1 2 0 164 50)} "_offline-queue" "filter" "empty?" "log-info" "sx:offline syncing " " mutations" "str" {:upvalue-count 0 :arity 1 :constants ("execute-action" "action" "get" "payload" {:upvalue-count 1 :arity 1 :constants ("status" "synced" "dict-set!" "log-info" "sx:offline synced " "action" "get" "str") :bytecode (18 0 1 0 0 1 1 0 52 2 0 3 5 20 3 0 1 4 0 18 0 1 5 0 52 6 0 2 52 7 0 2 49 1 50)} {:upvalue-count 1 :arity 1 :constants ("status" "failed" "dict-set!" "log-warn" "sx:offline sync failed " "action" "get" ": " "str") :bytecode (18 0 1 0 0 1 1 0 52 2 0 3 5 20 3 0 1 4 0 18 0 1 5 0 52 6 0 2 1 7 0 16 0 52 8 0 4 49 1 50)}) :bytecode (20 0 0 16 0 1 1 0 52 2 0 2 16 0 1 3 0 52 2 0 2 51 4 0 1 0 51 5 0 1 0 49 4 50)} "for-each") :bytecode (51 0 0 20 1 0 52 2 0 2 17 0 16 0 52 3 0 1 167 33 31 0 20 4 0 1 5 0 16 0 168 1 6 0 52 7 0 3 48 1 5 51 8 0 16 0 52 9 0 2 32 1 0 2 50)} "offline-pending-count" {:upvalue-count 0 :arity 0 :constants ({:upvalue-count 0 :arity 1 :constants ("status" "get" "pending") :bytecode (16 0 1 0 0 52 1 0 2 1 2 0 164 50)} "_offline-queue" "filter") :bytecode (51 0 0 20 1 0 52 2 0 2 168 50)} "offline-aware-mutation" {:upvalue-count 0 :arity 6 :constants ("_is-online" "submit-mutation" "offline-queue-mutation" "queued") :bytecode (20 0 0 33 20 0 20 1 0 16 0 16 1 16 2 16 3 16 4 16 5 49 6 32 32 0 20 2 0 16 2 16 3 16 0 16 1 16 4 48 5 5 16 5 33 10 0 16 5 1 3 0 49 1 32 1 0 2 50)} "current-page-layout" {:upvalue-count 0 :arity 0 :constants ("url-pathname" "browser-location-href" "find-matching-route" "_page-routes" "nil?" "" "layout" "get") :bytecode (20 0 0 20 1 0 48 0 48 1 17 0 20 2 0 16 0 20 3 0 48 2 17 1 16 1 52 4 0 1 33 6 0 1 5 0 32 17 0 16 1 1 6 0 52 7 0 2 6 34 4 0 5 1 5 0 50)} "swap-rendered-content" {:upvalue-count 0 :arity 3 :constants ("dom-create-element" "div" "dom-append" "process-oob-swaps" {:upvalue-count 0 :arity 3 :constants ("dispose-islands-in" "swap-dom-nodes" "innerHTML" "children-to-fragment" "post-swap") :bytecode (20 0 0 16 0 48 1 5 20 1 0 16 0 16 2 1 2 0 164 33 10 0 20 3 0 16 1 48 1 32 2 0 16 1 16 2 48 3 5 20 4 0 16 0 49 1 50)} "dom-get-attr" "id" "dom-query" "#" "str" "children-to-fragment" "dispose-islands-in" "dom-set-text-content" "" "hoist-head-elements-full" "process-elements" "sx-hydrate-elements" "sx-hydrate-islands" "run-post-render-hooks" "dom-dispatch" "sx:clientRoute" "pathname" "dict" "log-info" "sx:route client ") :bytecode (20 0 0 1 1 0 2 48 2 17 3 20 2 0 16 3 16 1 48 2 5 20 3 0 16 3 51 4 0 48 2 5 20 5 0 16 0 1 6 0 48 2 17 4 16 4 33 19 0 20 7 0 16 3 1 8 0 16 4 52 9 0 2 48 2 32 1 0 2 17 5 16 5 33 10 0 20 10 0 16 5 48 1 32 7 0 20 10 0 16 3 48 1 17 6 20 11 0 16 0 48 1 5 20 12 0 16 0 1 13 0 48 2 5 20 2 0 16 0 16 6 48 2 5 20 14 0 16 0 48 1 5 20 15 0 16 0 48 1 5 20 16 0 16 0 48 1 5 20 17 0 16 0 48 1 5 20 18 0 48 0 5 20 19 0 16 0 1 20 0 1 21 0 16 2 52 22 0 2 48 3 5 20 23 0 1 24 0 16 2 52 9 0 2 49 1 50)} "resolve-route-target" {:upvalue-count 0 :arity 1 :constants ("true" "dom-query") :bytecode (16 0 6 33 8 0 5 16 0 1 0 0 164 167 33 10 0 20 1 0 16 0 49 1 32 1 0 2 50)} "deps-satisfied?" {:upvalue-count 0 :arity 1 :constants ("deps" "get" "loaded-component-names" "nil?" "empty?" {:upvalue-count 1 :arity 1 :constants ("contains?") :bytecode (18 0 16 0 52 0 0 2 50)} "every?") :bytecode (16 0 1 0 0 52 1 0 2 17 1 20 2 0 48 0 17 2 16 1 52 3 0 1 33 4 0 4 32 24 0 16 1 52 4 0 1 33 4 0 3 32 11 0 51 5 0 1 2 16 1 52 6 0 2 50)} "try-client-route" {:upvalue-count 0 :arity 2 :constants ("find-matching-route" "_page-routes" "nil?" "log-info" "sx:route no match (" " routes) " "str" "layout" "get" "" "current-page-layout" "sx:route server (layout: " " -> " ") " "content" "closure" "params" "name" "empty?" "log-warn" "sx:route no content for " "resolve-route-target" "sx:route target not found: " "deps-satisfied?" "sx:route deps miss for " "io-deps" "render-plan" "server" "list" "client" "sx:route plan " " — " " server, " " client" "register-io-deps" "stream" "sx:route streaming " "fetch-streaming" "build-request-headers" "loaded-component-names" "has-data" "page-data-cache-key" "page-data-cache-get" "merge" "sx:route client+cache+async " "try-async-eval-content" {:upvalue-count 2 :arity 1 :constants ("nil?" "log-warn" "sx:route cache+async eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (16 0 52 0 0 1 33 45 0 20 1 0 1 2 0 18 0 1 3 0 52 4 0 3 48 1 5 20 5 0 18 1 18 0 20 6 0 18 1 20 7 0 48 0 48 2 1 8 0 49 4 32 11 0 20 9 0 18 1 16 0 18 0 49 3 50)} "try-eval-content" "sx:route cached eval failed for " "sx:route client+cache " "swap-rendered-content" "sx:route client+data " "resolve-page-data" {:upvalue-count 7 :arity 1 :constants ("page-data-cache-set" "merge" "try-async-eval-content" {:upvalue-count 2 :arity 1 :constants ("nil?" "log-warn" "sx:route data+async eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (16 0 52 0 0 1 33 45 0 20 1 0 1 2 0 18 0 1 3 0 52 4 0 3 48 1 5 20 5 0 18 1 18 0 20 6 0 18 1 20 7 0 48 0 48 2 1 8 0 49 4 32 11 0 20 9 0 18 1 16 0 18 0 49 3 50)} "try-eval-content" "nil?" "log-warn" "sx:route data eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (20 0 0 18 0 16 0 48 2 5 18 1 18 2 16 0 52 1 0 3 17 1 18 3 33 19 0 20 2 0 18 4 16 1 51 3 0 0 5 0 6 49 3 32 76 0 20 4 0 18 4 16 1 48 2 17 2 16 2 52 5 0 1 33 45 0 20 6 0 1 7 0 18 5 1 8 0 52 9 0 3 48 1 5 20 10 0 18 6 18 5 20 11 0 18 6 20 12 0 48 0 48 2 1 13 0 49 4 32 11 0 20 14 0 18 6 16 2 18 5 49 3 50)} "sx:route client+async " {:upvalue-count 2 :arity 1 :constants ("nil?" "log-warn" "sx:route async eval failed for " " — server fallback" "str" "fetch-and-restore" "build-request-headers" "loaded-component-names" 0 "swap-rendered-content") :bytecode (16 0 52 0 0 1 33 45 0 20 1 0 1 2 0 18 0 1 3 0 52 4 0 3 48 1 5 20 5 0 18 1 18 0 20 6 0 18 1 20 7 0 48 0 48 2 1 8 0 49 4 32 11 0 20 9 0 18 1 16 0 18 0 49 3 50)} "sx:route server (eval failed) ") :bytecode (20 0 0 16 0 20 1 0 48 2 17 2 16 2 52 2 0 1 33 26 0 20 3 0 1 4 0 20 1 0 168 1 5 0 16 0 52 6 0 4 48 1 5 4 32 212 2 16 2 1 7 0 52 8 0 2 6 34 4 0 5 1 9 0 17 3 20 10 0 48 0 17 4 16 3 16 4 164 167 33 29 0 20 3 0 1 11 0 16 4 1 12 0 16 3 1 13 0 16 0 52 6 0 6 48 1 5 4 32 148 2 16 2 1 14 0 52 8 0 2 17 5 16 2 1 15 0 52 8 0 2 6 34 4 0 5 65 0 0 17 6 16 2 1 16 0 52 8 0 2 17 7 16 2 1 17 0 52 8 0 2 17 8 16 5 52 2 0 1 6 34 7 0 5 16 5 52 18 0 1 33 19 0 20 19 0 1 20 0 16 0 52 6 0 2 48 1 5 4 32 57 2 20 21 0 16 1 48 1 17 9 16 9 52 2 0 1 33 19 0 20 19 0 1 22 0 16 1 52 6 0 2 48 1 5 4 32 20 2 20 23 0 16 2 48 1 167 33 19 0 20 3 0 1 24 0 16 8 52 6 0 2 48 1 5 4 32 246 1 16 2 1 25 0 52 8 0 2 17 10 16 10 6 33 8 0 5 16 10 52 18 0 1 167 17 11 16 2 1 26 0 52 8 0 2 17 12 16 12 33 72 0 16 12 1 27 0 52 8 0 2 6 34 5 0 5 52 28 0 0 17 13 16 12 1 29 0 52 8 0 2 6 34 5 0 5 52 28 0 0 17 14 20 3 0 1 30 0 16 8 1 31 0 16 13 168 1 32 0 16 14 168 1 33 0 52 6 0 7 48 1 32 1 0 2 5 16 11 33 10 0 20 34 0 16 10 48 1 32 1 0 2 5 16 2 1 35 0 52 8 0 2 33 41 0 20 3 0 1 36 0 16 0 52 6 0 2 48 1 5 20 37 0 16 9 16 0 20 38 0 16 9 20 39 0 48 0 48 2 48 3 5 3 32 59 1 16 2 1 40 0 52 8 0 2 33 194 0 20 41 0 16 8 16 7 48 2 17 13 20 42 0 16 13 48 1 17 14 16 14 33 123 0 16 6 16 7 16 14 52 43 0 3 17 15 16 11 33 36 0 20 3 0 1 44 0 16 0 52 6 0 2 48 1 5 20 45 0 16 5 16 15 51 46 0 1 0 1 9 48 3 5 3 32 67 0 20 47 0 16 5 16 15 48 2 17 16 16 16 52 2 0 1 33 19 0 20 19 0 1 48 0 16 0 52 6 0 2 48 1 5 4 32 28 0 20 3 0 1 49 0 16 0 52 6 0 2 48 1 5 20 50 0 16 9 16 16 16 0 48 3 5 3 32 43 0 20 3 0 1 51 0 16 0 52 6 0 2 48 1 5 20 52 0 16 8 16 7 51 53 0 1 13 1 6 1 7 1 11 1 5 1 0 1 9 48 3 5 3 32 109 0 16 11 33 42 0 20 3 0 1 54 0 16 0 52 6 0 2 48 1 5 20 45 0 16 5 16 6 16 7 52 43 0 2 51 55 0 1 0 1 9 48 3 5 3 32 62 0 16 6 16 7 52 43 0 2 17 13 20 47 0 16 5 16 13 48 2 17 14 16 14 52 2 0 1 33 19 0 20 3 0 1 56 0 16 0 52 6 0 2 48 1 5 4 32 13 0 20 50 0 16 9 16 14 16 0 48 3 5 3 50)} "bind-client-route-link" {:upvalue-count 0 :arity 2 :constants ("bind-client-route-click" {:upvalue-count 2 :arity 0 :constants ("bind-boost-link") :bytecode (20 0 0 18 0 18 1 49 2 50)}) :bytecode (20 0 0 16 0 16 1 51 1 0 1 0 1 1 49 3 50)} "process-sse" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ("is-processed?" "sse" "mark-processed!" "bind-sse") :bytecode (20 0 0 16 0 1 1 0 48 2 167 33 21 0 20 2 0 16 0 1 1 0 48 2 5 20 3 0 16 0 49 1 32 1 0 2 50)} "dom-query-all" "dom-body" "[sx-sse]" "for-each") :bytecode (51 0 0 20 1 0 16 0 6 34 6 0 5 20 2 0 48 0 1 3 0 48 2 52 4 0 2 50)} "bind-sse" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-sse" "event-source-connect" "parse-sse-swap" "event-source-listen" {:upvalue-count 1 :arity 1 :constants ("bind-sse-swap") :bytecode (20 0 0 18 0 16 0 49 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 37 0 20 2 0 16 1 16 0 48 2 17 2 20 3 0 16 0 48 1 17 3 20 4 0 16 2 16 3 51 5 0 1 0 49 3 32 1 0 2 50)} "bind-sse-swap" {:upvalue-count 0 :arity 2 :constants ("resolve-target" "parse-swap-spec" "dom-get-attr" "sx-swap" "dom-has-class?" "dom-body" "sx-transitions" "style" "get" "transition" "trim" "empty?" "dispose-islands-in" "(" "starts-with?" "sx-render" "dom-create-element" "div" "dom-append" "with-transition" {:upvalue-count 3 :arity 0 :constants ("swap-dom-nodes" "children-to-fragment" "post-swap") :bytecode (20 0 0 18 0 20 1 0 18 1 48 1 18 2 48 3 5 20 2 0 18 0 49 1 50)} {:upvalue-count 3 :arity 0 :constants ("swap-html-string" "post-swap") :bytecode (20 0 0 18 0 18 1 18 2 48 3 5 20 1 0 18 0 49 1 50)}) :bytecode (20 0 0 16 0 48 1 17 2 20 1 0 20 2 0 16 0 1 3 0 48 2 20 4 0 20 5 0 48 0 1 6 0 48 2 48 2 17 3 16 3 1 7 0 52 8 0 2 17 4 16 3 1 9 0 52 8 0 2 17 5 16 1 52 10 0 1 17 6 16 6 52 11 0 1 167 33 88 0 20 12 0 16 2 48 1 5 16 6 1 13 0 52 14 0 2 33 49 0 20 15 0 16 6 48 1 17 7 20 16 0 1 17 0 2 48 2 17 8 20 18 0 16 8 16 7 48 2 5 20 19 0 16 5 51 20 0 1 2 1 8 1 4 49 2 32 16 0 20 19 0 16 5 51 21 0 1 2 1 6 1 4 49 2 32 1 0 2 50)} "bind-inline-handlers" {:upvalue-count 0 :arity 1 :constants ({:upvalue-count 0 :arity 1 :constants ({:upvalue-count 1 :arity 1 :constants (1 "nth" "string?" "sx-on:" "starts-with?" 6 "slice" "after" "before" "sx:" "str" "is-processed?" "on:" "mark-processed!" "dom-on" "." "contains?" {:upvalue-count 2 :arity 1 :constants ("dom-window" "Function" "event" "host-call" "call") :bytecode (20 0 0 48 0 1 1 0 1 2 0 18 0 52 3 0 4 1 4 0 18 1 16 0 52 3 0 4 50)} "parse" {:upvalue-count 2 :arity 1 :constants ("make-env" "event" "env-bind!" "this" "detail" "event-detail" {:upvalue-count 1 :arity 1 :constants ("eval-expr") :bytecode (16 0 18 0 52 0 0 2 50)} "for-each") :bytecode (20 0 0 48 0 17 1 16 1 1 1 0 16 0 52 2 0 3 5 16 1 1 3 0 18 0 52 2 0 3 5 16 1 1 4 0 20 5 0 16 0 48 1 52 2 0 3 5 51 6 0 1 1 18 1 52 7 0 2 50)}) :bytecode (16 0 169 17 1 16 0 1 0 0 52 1 0 2 17 2 16 1 52 2 0 1 6 33 10 0 5 16 1 1 3 0 52 4 0 2 33 143 0 16 1 1 5 0 52 6 0 2 17 3 16 3 1 7 0 52 4 0 2 6 34 10 0 5 16 3 1 8 0 52 4 0 2 33 12 0 1 9 0 16 3 52 10 0 2 32 2 0 16 3 17 3 20 11 0 18 0 1 12 0 16 3 52 10 0 2 48 2 167 33 66 0 20 13 0 18 0 1 12 0 16 3 52 10 0 2 48 2 5 20 14 0 18 0 16 3 16 2 1 15 0 52 16 0 2 33 10 0 51 17 0 1 2 0 0 32 15 0 16 2 52 18 0 1 17 4 51 19 0 0 0 1 4 49 3 32 1 0 2 32 1 0 2 50)} "dom-attr-list" "for-each") :bytecode (51 0 0 1 0 20 1 0 16 0 48 1 52 2 0 2 50)} "dom-query-all" "dom-body" "[sx-on\\:]" "for-each") :bytecode (51 0 0 20 1 0 16 0 6 34 6 0 5 20 2 0 48 0 1 3 0 48 2 52 4 0 2 50)} "bind-preload-for" {:upvalue-count 0 :arity 1 :constants ("dom-get-attr" "sx-preload" "mousedown" "touchstart" "list" "mouseover" 0 100 "bind-preload" {:upvalue-count 1 :arity 0 :constants ("get-verb-info" "do-preload" "url" "get" "build-request-headers" "loaded-component-names") :bytecode (20 0 0 18 0 48 1 17 0 16 0 33 29 0 20 1 0 16 0 1 2 0 52 3 0 2 20 4 0 18 0 20 5 0 48 0 48 2 49 2 32 1 0 2 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 17 1 16 1 33 70 0 16 1 1 2 0 164 33 13 0 1 2 0 1 3 0 52 4 0 2 32 7 0 1 5 0 52 4 0 1 17 2 16 1 1 2 0 164 33 6 0 1 6 0 32 3 0 1 7 0 17 3 20 8 0 16 0 16 2 16 3 51 9 0 1 0 49 4 32 1 0 2 50)} "do-preload" {:upvalue-count 0 :arity 2 :constants ("preload-cache-get" "_preload-cache" "nil?" "fetch-preload") :bytecode (20 0 0 20 1 0 16 0 48 2 52 2 0 1 33 15 0 20 3 0 16 0 16 1 20 1 0 49 3 32 1 0 2 50)} "VERB_SELECTOR" "[sx-get],[sx-post],[sx-put],[sx-delete],[sx-patch]" "str" "process-elements" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "VERB_SELECTOR" {:upvalue-count 0 :arity 1 :constants ("is-processed?" "verb" "process-one" "mark-processed!") :bytecode (20 0 0 16 0 1 1 0 48 2 167 33 21 0 20 2 0 16 0 48 1 5 20 3 0 16 0 1 1 0 49 2 32 1 0 2 50)} "for-each" "process-boosted" "process-sse" "bind-inline-handlers" "process-emit-elements" "hs-boot-subtree!" "document" "host-global" "htmx-boot-subtree!") :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 20 2 0 48 2 17 1 51 3 0 16 1 52 4 0 2 5 20 5 0 16 0 48 1 5 20 6 0 16 0 48 1 5 20 7 0 16 0 48 1 5 20 8 0 16 0 48 1 5 20 9 0 16 0 6 34 8 0 5 1 10 0 52 11 0 1 48 1 5 20 12 0 16 0 6 34 8 0 5 1 10 0 52 11 0 1 49 1 50)} "process-one" {:upvalue-count 0 :arity 1 :constants ("get-verb-info" "dom-has-attr?" "sx-disable" "bind-triggers" "bind-preload-for") :bytecode (20 0 0 16 0 48 1 17 1 16 1 33 46 0 20 1 0 16 0 1 2 0 48 2 167 33 28 0 20 3 0 16 0 16 1 48 2 5 20 4 0 16 0 48 1 5 20 4 0 16 0 49 1 32 1 0 2 32 1 0 2 50)} "process-emit-elements" {:upvalue-count 0 :arity 1 :constants ("dom-query-all" "dom-body" "[data-sx-emit]" {:upvalue-count 0 :arity 1 :constants ("is-processed?" "emit" "mark-processed!" "dom-get-attr" "data-sx-emit" "dom-on" "click" {:upvalue-count 2 :arity 1 :constants ("dom-get-attr" "data-sx-emit-detail" "json-parse" "dict" "dom-dispatch") :bytecode (20 0 0 18 0 1 1 0 48 2 17 1 16 1 33 10 0 20 2 0 16 1 48 1 32 4 0 52 3 0 0 17 2 20 4 0 18 0 18 1 16 2 49 3 50)}) :bytecode (20 0 0 16 0 1 1 0 48 2 167 33 52 0 20 2 0 16 0 1 1 0 48 2 5 20 3 0 16 0 1 4 0 48 2 17 1 16 1 33 20 0 20 5 0 16 0 1 6 0 51 7 0 1 0 1 1 49 3 32 1 0 2 32 1 0 2 50)} "for-each") :bytecode (20 0 0 16 0 6 34 6 0 5 20 1 0 48 0 1 2 0 48 2 17 1 51 3 0 16 1 52 4 0 2 50)} "save-scroll-position" {:upvalue-count 0 :arity 0 :constants ("dom-window" "scrollY" "host-get" "browser-replace-state" "dict" "" "browser-location-href") :bytecode (20 0 0 48 0 1 1 0 52 2 0 2 17 0 20 3 0 1 1 0 16 0 52 4 0 2 1 5 0 20 6 0 48 0 49 3 50)} "handle-popstate" {:upvalue-count 0 :arity 1 :constants ("browser-location-href" "dom-query" "[sx-boost]" "dom-get-attr" "sx-boost" "true" "#sx-content" "url-pathname" "try-client-route" "build-request-headers" "loaded-component-names" "fetch-and-restore") :bytecode (20 0 0 48 0 17 1 20 1 0 1 2 0 48 1 17 2 16 2 33 40 0 20 3 0 16 2 1 4 0 48 2 17 3 16 3 6 33 8 0 5 16 3 1 5 0 164 167 33 5 0 16 3 32 3 0 1 6 0 32 3 0 1 6 0 17 3 20 1 0 16 3 48 1 17 4 20 7 0 16 1 48 1 17 5 16 4 33 47 0 20 8 0 16 5 16 3 48 2 167 33 30 0 20 9 0 16 4 20 10 0 48 0 48 2 17 6 20 11 0 16 4 16 1 16 6 16 0 49 4 32 1 0 2 32 1 0 2 50)} "engine-init" {:upvalue-count 0 :arity 0 :constants ("sx-process-scripts" "sx-hydrate" "process-elements") :bytecode (20 0 0 2 48 1 5 20 1 0 2 48 1 5 20 2 0 2 49 1 50)} {:library (web orchestration) :op "import"}) :bytecode (52 1 0 0 128 0 0 5 51 3 0 128 2 0 5 51 5 0 128 4 0 5 51 7 0 128 6 0 5 51 9 0 128 8 0 5 51 11 0 128 10 0 5 51 13 0 128 12 0 5 51 15 0 128 14 0 5 51 17 0 128 16 0 5 51 19 0 128 18 0 5 51 21 0 128 20 0 5 51 23 0 128 22 0 5 51 25 0 128 24 0 5 51 27 0 128 26 0 5 51 29 0 128 28 0 5 51 31 0 128 30 0 5 51 33 0 128 32 0 5 51 35 0 128 34 0 5 52 1 0 0 128 36 0 5 1 38 0 128 37 0 5 51 40 0 128 39 0 5 51 42 0 128 41 0 5 51 44 0 128 43 0 5 51 46 0 128 45 0 5 51 48 0 128 47 0 5 51 50 0 128 49 0 5 51 52 0 128 51 0 5 52 1 0 0 128 53 0 5 51 55 0 128 54 0 5 51 57 0 128 56 0 5 51 59 0 128 58 0 5 51 61 0 128 60 0 5 3 128 62 0 5 52 64 0 0 128 63 0 5 51 66 0 128 65 0 5 51 68 0 128 67 0 5 51 70 0 128 69 0 5 51 72 0 128 71 0 5 51 74 0 128 73 0 5 51 76 0 128 75 0 5 51 78 0 128 77 0 5 51 80 0 128 79 0 5 51 82 0 128 81 0 5 51 84 0 128 83 0 5 51 86 0 128 85 0 5 51 88 0 128 87 0 5 51 90 0 128 89 0 5 51 92 0 128 91 0 5 51 94 0 128 93 0 5 51 96 0 128 95 0 5 51 98 0 128 97 0 5 51 100 0 128 99 0 5 1 102 0 52 103 0 1 128 101 0 5 51 105 0 128 104 0 5 51 107 0 128 106 0 5 51 109 0 128 108 0 5 51 111 0 128 110 0 5 51 113 0 128 112 0 5 51 115 0 128 114 0 5 1 116 0 112 50))) diff --git a/web/orchestration.sx b/web/orchestration.sx index fb16dc4c..b6246344 100644 --- a/web/orchestration.sx +++ b/web/orchestration.sx @@ -467,11 +467,19 @@ use-transition (fn () - (swap-dom-nodes - target - (children-to-fragment container) - swap-style) - (post-swap target)))))))))) + ;; post-swap the NEW node, not the old target — an outerHTML + ;; swap REPLACES target, so processing target would re-bind a + ;; detached node and leave the swapped-in content's triggers + ;; (e.g. a re-rendered picker's "load") unbound. Mirrors the + ;; sx-select branch above. For innerHTML swap-root falls back + ;; to target (still in the document). + (let + ((swap-root + (swap-dom-nodes + target + (children-to-fragment container) + swap-style))) + (post-swap (or swap-root target)))))))))))) (define handle-retry :effects (mutation io) diff --git a/web/tests/test-relate-picker.sx b/web/tests/test-relate-picker.sx index 2070bcfb..b4d0d895 100644 --- a/web/tests/test-relate-picker.sx +++ b/web/tests/test-relate-picker.sx @@ -24,7 +24,8 @@ (define _mock-fetch-ok true) (define _mock-fetch-status 200) (define _mock-fetch-ct "text/html; charset=utf-8") -(define _mock-fetch-body "") +(define _mock-fetch-body "") ;; the GET /relate-options (picker) response +(define _mock-editor-body "") ;; the POST /relate|/unrelate (editor) response (define _mock-fetch-fail false) (define reset-fetch-mock! @@ -34,16 +35,20 @@ (set! _mock-fetch-status 200) (set! _mock-fetch-ct "text/html; charset=utf-8") (set! _mock-fetch-body "") + (set! _mock-editor-body "") (set! _mock-fetch-fail false))) +;; URL-aware mock: the picker GETs relate-options (returns candidate rows); a relate +;; or unrelate POST returns the re-rendered editor fragment. (define fetch-request (fn (config success-fn error-fn) (set! _mock-fetch-calls (+ _mock-fetch-calls 1)) (if _mock-fetch-fail (error-fn "network error") - (success-fn _mock-fetch-ok _mock-fetch-status - (fn (name) (if (= name "content-type") _mock-fetch-ct nil)) - _mock-fetch-body)))) + (let ((url (or (get config "url") ""))) + (success-fn _mock-fetch-ok _mock-fetch-status + (fn (name) (if (= name "content-type") _mock-fetch-ct nil)) + (if (contains? url "relate-options") _mock-fetch-body _mock-editor-body)))))) ;; ── harness platform shims ────────────────────────────────────────── ;; Reactive hydration + island disposal live in web/boot.sx (the browser boot @@ -121,38 +126,57 @@ "
    " ""))) -;; One candidate row, as host/blog--picker-item renders it. +;; One candidate row, as host/blog--picker-item renders it: relating re-renders the +;; whole editor (sx-target=#rel-editor-KIND, sx-swap=outerHTML). (define row-html (fn (slug kind cand title) (str "
  • " "
    " + " sx-target=\"#rel-editor-" kind "\"" + " sx-swap=\"outerHTML\">" "" "" "" "
    " "
  • "))) -;; One CURRENT-relation row, as host/blog--relation-editor renders it: an AJAX -;; in-place remove (sx-post + sx-target=#cur-… + sx-swap=delete). +;; One CURRENT-relation row, as host/blog--relation-editor renders it: removing +;; re-renders the whole editor (sx-target=#rel-editor-KIND, sx-swap=outerHTML). (define cur-row-html (fn (slug kind other label) (str - "
  • " + "
  • " "" label " " "
    " + " sx-target=\"#rel-editor-" kind "\"" + " sx-swap=\"outerHTML\">" "" "" "" "
    " "
  • "))) +;; The kind's relation editor: #rel-editor-KIND wrapping the current-relations list +;; and the picker (with `candidates` already in its results
      ). This is what the +;; relate/unrelate handlers return and what the initial edit page renders. +(define editor-html + (fn (kind current candidates) + (str + "
      " + "

      " kind "

      " + "
        " current "
      " + "
      " + "" + "" + "
        " candidates "
      " + "
      " + "
      "))) + ;; The "load more" sentinel, as host/blog--picker-more renders it. (define sentinel-html (fn (slug kind offset) @@ -174,28 +198,38 @@ (loop (+ i 1))) acc))))) -;; ── Phase 0: relate -> delete row ─────────────────────────────────── +;; ── relating a candidate re-syncs the editor (adds to the current list) ─ +;; Regression for "adding a related post doesn't add it to the list": the candidate +;; relate form re-renders the whole #rel-editor-KIND (outerHTML), so the related +;; post moves into the current-relations list and the fresh picker re-loads — both +;; lists stay in sync, in-page, no reload. (defsuite - "relate-picker:relate-delete" + "relate-picker:relate-resyncs-editor" (deftest - "submitting a candidate's relate form deletes just that row" + "relating a candidate adds it to the current list and re-loads the picker" (reset-fetch-mock!) - ;; the AJAX relate returns an empty 200 (text/html); sx-swap=delete then - ;; removes the candidate's own
    • — this is the host's real response. + (reset-reveal!) + ;; the picker's load shows one candidate (item-07) to click + (set! _mock-fetch-body (row-html "host" "related" "item-07" "Picker Item 07")) (let - ((root (mk-root (str "
        " - (row-html "host" "related" "item-07" "Picker Item 07") - "
      "))) - (results (dom-query ".rp-results")) - (form (dom-query "form"))) + ((root (mk-root (str "
      " + (editor-html "related" "" "") + "
      "))) + (results (dom-query "#rp-related-results"))) (process-elements root) - ;; one candidate row before + ;; load populated the candidate; current list empty (assert-equal 1 (count-candidates results)) - ;; submit the relate form -> execute-request -> mock fetch -> delete swap - (fire-event! form "submit") - ;; the fetch actually ran, and the row is gone - (assert-true (> _mock-fetch-calls 0)) - (assert-equal 0 (count-candidates results)) + (assert-nil (dom-query "a[href=\"/item-07/\"]")) + ;; clicking it: the relate POST returns the re-rendered editor (item-07 now in + ;; the current list), and the fresh picker re-loads OTHER candidates. + (set! _mock-editor-body + (editor-html "related" (cur-row-html "host" "related" "item-07" "Picker Item 07") "")) + (set! _mock-fetch-body (rows-html "host" "related" 8 11)) ;; refreshed pool + (fire-event! (dom-query "#cand-related-item-07 form") "submit") + ;; the related post is now in the current list (added, not just removed)... + (assert-true (not (nil? (dom-query "a[href=\"/item-07/\"]")))) + ;; ...and the picker is NOT cleared — it re-loaded a fresh candidate page + (assert-equal 3 (count-candidates (dom-query "#rp-related-results"))) (clear-root! root)))) ;; ── Phase 1: load / filter / paging / error-retry ─────────────────── @@ -308,41 +342,39 @@ (clear-root! root)))) ;; ── regression: removing a relation must not clear the relate picker ─ -;; The remove button is an AJAX in-place delete (sx-post + sx-swap=delete on its own -;; current-relation row). Submitting it deletes ONLY that row — the sibling picker's -;; candidate list is left intact, because #content is never re-rendered. (Bug: the -;; old plain-boosted remove redirected and the re-rendered picker came back empty.) +;; The remove button re-renders the kind's editor (outerHTML #rel-editor-KIND): the +;; row leaves the current list and the FRESH picker re-loads its candidates. (Bug: +;; the old plain-boosted remove redirected and the re-rendered picker came back +;; empty — here the picker repopulates instead of clearing to 0.) (defsuite "relate-picker:unrelate-keeps-picker" (deftest - "removing a current relation deletes just that row, leaving the picker intact" + "removing a current relation re-syncs the editor and re-loads the picker" (reset-fetch-mock!) - ;; the AJAX unrelate returns an empty 200 (like the host); sx-swap=delete then - ;; removes the current-relation row in place. + (reset-reveal!) + ;; start: Beta + Gamma are related; the picker (after load) shows nothing yet + (set! _mock-fetch-body "") (let - ((root (mk-root (str - "
        " - (cur-row-html "host" "related" "beta" "Beta") - (cur-row-html "host" "related" "gamma" "Gamma") - "
      " - "
        " - (row-html "host" "related" "delta" "Picker Delta") - (row-html "host" "related" "epsilon" "Picker Epsilon") - "
      "))) - (cur-box (dom-query "#cur-box")) - (res-box (dom-query "#res-box"))) + ((root (mk-root (str "
      " + (editor-html "related" + (str (cur-row-html "host" "related" "beta" "Beta") + (cur-row-html "host" "related" "gamma" "Gamma")) + "") + "
      ")))) (process-elements root) - ;; two current relations, two picker candidates to start - (assert-equal 2 (len (dom-query-all cur-box "li"))) - (assert-equal 2 (len (dom-query-all res-box "li"))) - ;; remove Beta — submit its in-place remove form - (fire-event! (dom-query (dom-query "#cur-related-beta") "form") "submit") - ;; just Beta's row is gone; Gamma remains - (assert-nil (dom-query "#cur-related-beta")) - (assert-true (not (nil? (dom-query "#cur-related-gamma")))) - (assert-equal 1 (len (dom-query-all cur-box "li"))) - ;; and the picker's candidate list is UNTOUCHED — the bug was it cleared to 0 - (assert-equal 2 (len (dom-query-all res-box "li"))) + (assert-equal 2 (len (dom-query-all (dom-query "#rel-editor-related") "ul.rp-current li"))) + ;; remove Beta: the unrelate POST returns the editor with only Gamma current, + ;; and the fresh picker re-loads candidates (Beta is available again). + (set! _mock-editor-body + (editor-html "related" (cur-row-html "host" "related" "gamma" "Gamma") "")) + (set! _mock-fetch-body (rows-html "host" "related" 0 4)) + (fire-event! (dom-query "form") "submit") ;; Beta's remove form (first form) + ;; Beta is gone from the current list; Gamma stays + (assert-nil (dom-query "a[href=\"/beta/\"]")) + (assert-true (not (nil? (dom-query "a[href=\"/gamma/\"]")))) + (assert-equal 1 (len (dom-query-all (dom-query "#rel-editor-related") "ul.rp-current li"))) + ;; and the picker is NOT cleared — it re-loaded a fresh candidate page + (assert-equal 4 (count-candidates (dom-query "#rp-related-results"))) (clear-root! root)))) ;; ── Phase 3: the engine drives a non-browser target (the console) ───