From 3ba3dc6e9dadd86b537cbc5843efacce4eddd525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martynas=20Jusevi=C4=8Dius?= Date: Sat, 6 Jun 2026 00:00:47 +0200 Subject: [PATCH 1/6] Convert modal-form metadata fetches to async load/set pairs The five modal/typeahead form rendering paths each fetched type-metadata, property-metadata, constraints, and object-metadata synchronously via document() inside their terminal render functions, blocking the UI thread on 3-4 sequential round-trips per render. Promote each fetch to an async load/set pair invoked as steps in the existing ixsl:promise chains: - ldh:load-type-metadata / ldh:set-type-metadata (set-type-metadata stripped of its sync work, now just extracts response body) - ldh:load-constraints / ldh:set-constraints (new pair) - Reuse the existing ldh:load-property-metadata and ldh:load-object-metadata in client/block.xsl, extended to accept pre-computed URIs from context (backward-compatible) Each of the five chains (btn-edit, btn-app-settings, add-constructor, typeahead-row-form, row-form-submit-violation) is extended with the new load/set steps before its terminal render function. The render functions are correspondingly stripped of sync work and now just read metadata from context. ldh:modal-form-submit-violation was sync; converted to start a promise chain and terminate in a new ldh:render-modal-form-violation. To uniformly identify the resource being edited across all three modal flows in the submit-violation re-render path, the Container/Item creation modal now also carries @about on its wrapper div (the new resource URL), matching btn-edit and btn-app-settings. The submit handlers read $block/@about directly without a fallback. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../xsl/bootstrap/2.3.2/client/block.xsl | 22 +- .../xsl/bootstrap/2.3.2/client/form.xsl | 250 ++++++++++-------- .../xsl/bootstrap/2.3.2/client/modal.xsl | 222 +++++++++------- .../xsl/bootstrap/2.3.2/document.xsl | 48 ++-- 4 files changed, 309 insertions(+), 233 deletions(-) diff --git a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/block.xsl b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/block.xsl index 8bb025c9a..dd377cc65 100644 --- a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/block.xsl +++ b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/block.xsl @@ -653,12 +653,15 @@ exclude-result-prefixes="#all" - + + if (map:contains($context, 'object-uris')) then $context('object-uris') + else + let $response := $context($response-key) + return if ($response?status = 200 and $response?media-type = 'application/rdf+xml') + then distinct-values($response?body/rdf:RDF/rdf:Description/*/@rdf:resource[not(key('resources', .))]) + else ()"/> @@ -704,11 +707,14 @@ exclude-result-prefixes="#all" - + + if (map:contains($context, 'property-uris')) then $context('property-uris') + else + let $response := $context($response-key) + return if ($response?status = 200 and $response?media-type = 'application/rdf+xml') + then distinct-values($response?body/rdf:RDF/rdf:Description/*/concat(namespace-uri(), local-name())) + else ()"/> diff --git a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/form.xsl b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/form.xsl index 300ab0355..33b362de9 100644 --- a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/form.xsl +++ b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/form.xsl @@ -282,6 +282,42 @@ WHERE " on-failure="ldh:promise-failure#1"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -306,11 +342,16 @@ WHERE + + 'types': $types, + 'property-uris': distinct-values($resource/*/concat(namespace-uri(), local-name())), + 'object-uris': distinct-values($resource/*/@rdf:resource[not(key('resources', .))]), + 'document': ., + 'action': if (map:contains($context, 'action')) then $context('action') else ldh:href(ac:absolute-path(ldh:base-uri(.)), map{}) + }), map{ 'duplicates': 'use-last' })"/> @@ -331,34 +372,8 @@ WHERE - - - - - - - - - - - - - - - - - - + - @@ -366,23 +381,6 @@ WHERE - - - - - - - - - - - - - - @@ -522,7 +520,7 @@ WHERE - + @@ -563,35 +561,9 @@ WHERE - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -603,7 +575,53 @@ WHERE - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -679,10 +697,12 @@ WHERE + @@ -957,15 +980,29 @@ WHERE ixsl:then(ldh:http-request-threaded(?, 'shapes-request', 'shapes-response')) => ixsl:then(ldh:handle-response(?, 'shapes-response')) => ixsl:then(ldh:set-shapes#1) => + ixsl:then(ldh:load-type-metadata#1) => + ixsl:then(ldh:http-request-threaded(?, 'type-metadata-request', 'type-metadata-response')) => + ixsl:then(ldh:handle-response(?, 'type-metadata-response')) => + ixsl:then(ldh:set-type-metadata#1) => + ixsl:then(ldh:load-property-metadata#1) => + ixsl:then(ldh:http-request-threaded(?, 'property-metadata-request', 'property-metadata-response')) => + ixsl:then(ldh:handle-response(?, 'property-metadata-response')) => + ixsl:then(ldh:set-property-metadata#1) => + ixsl:then(ldh:load-constraints#1) => + ixsl:then(ldh:http-request-threaded(?, 'constraints-request', 'constraints-response')) => + ixsl:then(ldh:handle-response(?, 'constraints-response')) => + ixsl:then(ldh:set-constraints#1) => + ixsl:then(ldh:load-object-metadata#1) => + ixsl:then(ldh:http-request-threaded(?, 'metadata-request', 'metadata-response')) => + ixsl:then(ldh:handle-response(?, 'metadata-response')) => + ixsl:then(ldh:set-object-metadata#1) => ixsl:then(ldh:render-row-form-violation#1)" on-failure="ldh:promise-failure#1"/> + All metadata is fetched async by the upstream chain steps; this function just reads from context. --> @@ -975,25 +1012,10 @@ WHERE - - - - - - - - - - - - - - - - - - - + + + + @@ -1292,7 +1314,8 @@ WHERE 'constructed-doc': $merged-doc, 'shapes': $shapes, 'resource': $resource, - 'types': $types + 'types': $types, + 'property-uris': distinct-values($resource/*/concat(namespace-uri(), local-name())) }), map{ 'duplicates': 'use-last' })"/> @@ -1307,26 +1330,15 @@ WHERE + + + - - - - - - - - - - - - - - @@ -1416,6 +1428,18 @@ WHERE ixsl:then(ldh:http-request-threaded(?, 'constructors-request', 'constructors-response')) => ixsl:then(ldh:handle-response(?, 'constructors-response')) => ixsl:then(ldh:set-constructors#1) => + ixsl:then(ldh:load-type-metadata#1) => + ixsl:then(ldh:http-request-threaded(?, 'type-metadata-request', 'type-metadata-response')) => + ixsl:then(ldh:handle-response(?, 'type-metadata-response')) => + ixsl:then(ldh:set-type-metadata#1) => + ixsl:then(ldh:load-property-metadata#1) => + ixsl:then(ldh:http-request-threaded(?, 'property-metadata-request', 'property-metadata-response')) => + ixsl:then(ldh:handle-response(?, 'property-metadata-response')) => + ixsl:then(ldh:set-property-metadata#1) => + ixsl:then(ldh:load-constraints#1) => + ixsl:then(ldh:http-request-threaded(?, 'constraints-request', 'constraints-response')) => + ixsl:then(ldh:handle-response(?, 'constraints-response')) => + ixsl:then(ldh:set-constraints#1) => ixsl:then(ldh:render-typeahead-row-form#1)" on-failure="ldh:promise-failure#1"/> diff --git a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/modal.xsl b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/modal.xsl index 13ff91b6f..b636f5540 100644 --- a/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/modal.xsl +++ b/src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/modal.xsl @@ -732,6 +732,20 @@ LIMIT 10 Reads context('constructed-doc') as the async-fetched SPIN-construction; the remaining sync document() calls for type-metadata/property-metadata/constraints are scope for a follow-up refactor. --> + + + + + + + + + + @@ -739,26 +753,13 @@ LIMIT 10 + + + - - - - - - - - - - - - - - - - @@ -777,7 +778,7 @@ LIMIT 10 -