vorma 0.0.0-pre.0 → 0.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.md +48 -0
- package/internal/framework/_typescript/client/index.ts +64 -0
- package/internal/framework/_typescript/client/src/asset_manager.ts +67 -0
- package/internal/framework/_typescript/client/src/client.ts +1201 -0
- package/internal/framework/_typescript/client/src/client_loaders.ts +249 -0
- package/internal/framework/_typescript/client/src/component_loader.ts +105 -0
- package/internal/framework/_typescript/client/src/error_boundary.ts +7 -0
- package/internal/framework/_typescript/client/src/events.ts +54 -0
- package/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.ts +125 -0
- package/internal/framework/_typescript/client/src/hard_reload.ts +1 -0
- package/internal/framework/_typescript/client/src/head_elements/head_elements.ts +193 -0
- package/internal/framework/_typescript/client/src/history/history.ts +118 -0
- package/internal/framework/_typescript/client/src/history/npm_history_types.ts +83 -0
- package/internal/framework/_typescript/client/src/hmr/hmr.ts +71 -0
- package/internal/framework/_typescript/client/src/init_client.ts +134 -0
- package/internal/framework/_typescript/client/src/links.ts +218 -0
- package/internal/framework/_typescript/client/src/redirects/redirects.ts +203 -0
- package/internal/framework/_typescript/client/src/rendering.ts +135 -0
- package/internal/framework/_typescript/client/src/resolve_public_href.ts +15 -0
- package/internal/framework/_typescript/client/src/scroll_state_manager.ts +100 -0
- package/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.ts +22 -0
- package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.ts +131 -0
- package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.ts +56 -0
- package/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.ts +58 -0
- package/internal/framework/_typescript/client/src/utils/errors.ts +10 -0
- package/internal/framework/_typescript/client/src/utils/logging.ts +7 -0
- package/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.ts +290 -0
- package/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.ts +128 -0
- package/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.ts +32 -0
- package/internal/framework/_typescript/client/tsconfig.json +3 -0
- package/internal/framework/_typescript/create/main.ts +378 -0
- package/internal/framework/_typescript/create/package.json +33 -0
- package/internal/framework/_typescript/create/pnpm-lock.yaml +70 -0
- package/internal/framework/_typescript/create/tsconfig.json +3 -0
- package/internal/framework/_typescript/preact/index.tsx +10 -0
- package/internal/framework/_typescript/preact/src/helpers.ts +113 -0
- package/internal/framework/_typescript/preact/src/link.tsx +107 -0
- package/internal/framework/_typescript/preact/src/preact.tsx +191 -0
- package/internal/framework/_typescript/preact/tsconfig.json +7 -0
- package/internal/framework/_typescript/react/index.tsx +10 -0
- package/internal/framework/_typescript/react/src/helpers.ts +118 -0
- package/internal/framework/_typescript/react/src/link.tsx +115 -0
- package/internal/framework/_typescript/react/src/react.tsx +299 -0
- package/internal/framework/_typescript/react/tsconfig.json +6 -0
- package/internal/framework/_typescript/solid/index.tsx +10 -0
- package/internal/framework/_typescript/solid/src/helpers.ts +114 -0
- package/internal/framework/_typescript/solid/src/link.tsx +104 -0
- package/internal/framework/_typescript/solid/src/solid.tsx +204 -0
- package/internal/framework/_typescript/solid/tsconfig.json +7 -0
- package/internal/framework/_typescript/vite/tsconfig.json +3 -0
- package/internal/framework/_typescript/vite/vite.ts +93 -0
- package/internal/site/frontend/assets/vorma-banner.webp +0 -0
- package/kit/_typescript/converters/converters.ts +152 -0
- package/kit/_typescript/cookies/cookies.ts +18 -0
- package/kit/_typescript/csrf/csrf.ts +10 -0
- package/kit/_typescript/debounce/debounce.ts +17 -0
- package/kit/_typescript/fmt/fmt.ts +3 -0
- package/kit/_typescript/json/deep_equals.ts +54 -0
- package/kit/_typescript/json/json.ts +3 -0
- package/kit/_typescript/json/search_param_serializer.ts +49 -0
- package/kit/_typescript/json/stringify_stable.ts +43 -0
- package/kit/_typescript/listeners/listeners.ts +16 -0
- package/kit/_typescript/matcher/find_best_match.ts +205 -0
- package/kit/_typescript/matcher/find_nested_matches.ts +357 -0
- package/kit/_typescript/matcher/parse_segments.ts +30 -0
- package/kit/_typescript/matcher/register.ts +271 -0
- package/kit/_typescript/theme/theme.ts +177 -0
- package/kit/_typescript/tsconfig.json +3 -0
- package/kit/_typescript/url/url.ts +132 -0
- package/npm_dist/internal/framework/_typescript/client/index.d.ts +17 -0
- package/npm_dist/internal/framework/_typescript/client/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/index.js +2489 -0
- package/npm_dist/internal/framework/_typescript/client/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/client/src/asset_manager.d.ts +6 -0
- package/npm_dist/internal/framework/_typescript/client/src/asset_manager.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/client.d.ts +119 -0
- package/npm_dist/internal/framework/_typescript/client/src/client.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/client_loaders.d.ts +18 -0
- package/npm_dist/internal/framework/_typescript/client/src/client_loaders.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/component_loader.d.ts +10 -0
- package/npm_dist/internal/framework/_typescript/client/src/component_loader.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/error_boundary.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/error_boundary.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/events.d.ts +26 -0
- package/npm_dist/internal/framework/_typescript/client/src/events.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.d.ts +12 -0
- package/npm_dist/internal/framework/_typescript/client/src/global_loading_indicator/global_loading_indicator.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/hard_reload.d.ts +2 -0
- package/npm_dist/internal/framework/_typescript/client/src/hard_reload.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/head_elements/head_elements.d.ts +7 -0
- package/npm_dist/internal/framework/_typescript/client/src/head_elements/head_elements.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/history.d.ts +14 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/history.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/npm_history_types.d.ts +84 -0
- package/npm_dist/internal/framework/_typescript/client/src/history/npm_history_types.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/hmr/hmr.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/hmr/hmr.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/init_client.d.ts +9 -0
- package/npm_dist/internal/framework/_typescript/client/src/init_client.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/links.d.ts +33 -0
- package/npm_dist/internal/framework/_typescript/client/src/links.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/redirects/redirects.d.ts +26 -0
- package/npm_dist/internal/framework/_typescript/client/src/redirects/redirects.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/rendering.d.ts +18 -0
- package/npm_dist/internal/framework/_typescript/client/src/rendering.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/resolve_public_href.d.ts +2 -0
- package/npm_dist/internal/framework/_typescript/client/src/resolve_public_href.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/scroll_state_manager.d.ts +22 -0
- package/npm_dist/internal/framework/_typescript/client/src/scroll_state_manager.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.d.ts +12 -0
- package/npm_dist/internal/framework/_typescript/client/src/static_route_defs/route_def_helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.d.ts +28 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/link_components.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.d.ts +18 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/route_components.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/client/src/ui_lib_impl_helpers/typed_navigate.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/errors.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/errors.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/logging.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/client/src/utils/logging.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.d.ts +119 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_app_helpers/vorma_app_helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.d.ts +88 -0
- package/npm_dist/internal/framework/_typescript/client/src/vorma_ctx/vorma_ctx.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.d.ts +10 -0
- package/npm_dist/internal/framework/_typescript/client/src/window_focus_revalidation/window_focus_revalidation.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/create/main.d.ts +3 -0
- package/npm_dist/internal/framework/_typescript/create/main.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/index.d.ts +4 -0
- package/npm_dist/internal/framework/_typescript/preact/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/index.js +283 -0
- package/npm_dist/internal/framework/_typescript/preact/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/preact/src/helpers.d.ts +21 -0
- package/npm_dist/internal/framework/_typescript/preact/src/helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/src/link.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/preact/src/link.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/preact/src/preact.d.ts +21 -0
- package/npm_dist/internal/framework/_typescript/preact/src/preact.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/index.d.ts +4 -0
- package/npm_dist/internal/framework/_typescript/react/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/index.js +370 -0
- package/npm_dist/internal/framework/_typescript/react/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/react/src/helpers.d.ts +21 -0
- package/npm_dist/internal/framework/_typescript/react/src/helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/src/link.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/react/src/link.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/react/src/react.d.ts +20 -0
- package/npm_dist/internal/framework/_typescript/react/src/react.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/index.d.ts +4 -0
- package/npm_dist/internal/framework/_typescript/solid/index.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/index.js +314 -0
- package/npm_dist/internal/framework/_typescript/solid/index.js.map +7 -0
- package/npm_dist/internal/framework/_typescript/solid/src/helpers.d.ts +22 -0
- package/npm_dist/internal/framework/_typescript/solid/src/helpers.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/src/link.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/solid/src/link.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/solid/src/solid.d.ts +22 -0
- package/npm_dist/internal/framework/_typescript/solid/src/solid.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.d.ts +11 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.d.ts.map +1 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.js +82 -0
- package/npm_dist/internal/framework/_typescript/vite/vite.js.map +7 -0
- package/npm_dist/kit/_typescript/chunk-YBAPNBS2.js +202 -0
- package/npm_dist/kit/_typescript/chunk-YBAPNBS2.js.map +7 -0
- package/npm_dist/kit/_typescript/converters/converters.d.ts +26 -0
- package/npm_dist/kit/_typescript/converters/converters.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/converters/converters.js +99 -0
- package/npm_dist/kit/_typescript/converters/converters.js.map +7 -0
- package/npm_dist/kit/_typescript/cookies/cookies.d.ts +13 -0
- package/npm_dist/kit/_typescript/cookies/cookies.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/cookies/cookies.js +13 -0
- package/npm_dist/kit/_typescript/cookies/cookies.js.map +7 -0
- package/npm_dist/kit/_typescript/csrf/csrf.d.ts +5 -0
- package/npm_dist/kit/_typescript/csrf/csrf.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/csrf/csrf.js +11 -0
- package/npm_dist/kit/_typescript/csrf/csrf.js.map +7 -0
- package/npm_dist/kit/_typescript/debounce/debounce.d.ts +4 -0
- package/npm_dist/kit/_typescript/debounce/debounce.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/debounce/debounce.js +16 -0
- package/npm_dist/kit/_typescript/debounce/debounce.js.map +7 -0
- package/npm_dist/kit/_typescript/fmt/fmt.d.ts +2 -0
- package/npm_dist/kit/_typescript/fmt/fmt.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/fmt/fmt.js +8 -0
- package/npm_dist/kit/_typescript/fmt/fmt.js.map +7 -0
- package/npm_dist/kit/_typescript/json/deep_equals.d.ts +7 -0
- package/npm_dist/kit/_typescript/json/deep_equals.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/json/json.d.ts +4 -0
- package/npm_dist/kit/_typescript/json/json.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/json/json.js +110 -0
- package/npm_dist/kit/_typescript/json/json.js.map +7 -0
- package/npm_dist/kit/_typescript/json/search_param_serializer.d.ts +2 -0
- package/npm_dist/kit/_typescript/json/search_param_serializer.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/json/stringify_stable.d.ts +7 -0
- package/npm_dist/kit/_typescript/json/stringify_stable.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/listeners/listeners.d.ts +2 -0
- package/npm_dist/kit/_typescript/listeners/listeners.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/listeners/listeners.js +20 -0
- package/npm_dist/kit/_typescript/listeners/listeners.js.map +7 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.d.ts +10 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.js +146 -0
- package/npm_dist/kit/_typescript/matcher/find_best_match.js.map +7 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.d.ts +14 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.js +248 -0
- package/npm_dist/kit/_typescript/matcher/find_nested_matches.js.map +7 -0
- package/npm_dist/kit/_typescript/matcher/parse_segments.d.ts +2 -0
- package/npm_dist/kit/_typescript/matcher/parse_segments.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/register.d.ts +54 -0
- package/npm_dist/kit/_typescript/matcher/register.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/matcher/register.js +21 -0
- package/npm_dist/kit/_typescript/matcher/register.js.map +7 -0
- package/npm_dist/kit/_typescript/theme/theme.d.ts +24 -0
- package/npm_dist/kit/_typescript/theme/theme.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/theme/theme.js +133 -0
- package/npm_dist/kit/_typescript/theme/theme.js.map +7 -0
- package/npm_dist/kit/_typescript/url/url.d.ts +30 -0
- package/npm_dist/kit/_typescript/url/url.d.ts.map +1 -0
- package/npm_dist/kit/_typescript/url/url.js +100 -0
- package/npm_dist/kit/_typescript/url/url.js.map +7 -0
- package/package.json +135 -3
- package/tsconfig.base.json +17 -0
- package/index.js +0 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { panic } from "../utils/errors.ts";
|
|
2
|
+
import type { HeadEl } from "../vorma_ctx/vorma_ctx.ts";
|
|
3
|
+
|
|
4
|
+
export function getStartAndEndComments(type: "meta" | "rest"): {
|
|
5
|
+
startComment: Comment | null;
|
|
6
|
+
endComment: Comment | null;
|
|
7
|
+
} {
|
|
8
|
+
const startMarker = `data-vorma="${type}-start"`;
|
|
9
|
+
const endMarker = `data-vorma="${type}-end"`;
|
|
10
|
+
const start = findComment(startMarker);
|
|
11
|
+
const end = findComment(endMarker);
|
|
12
|
+
return { startComment: start, endComment: end };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function findComment(matchingText: string): Comment | null {
|
|
16
|
+
const walker = document.createTreeWalker(
|
|
17
|
+
document.head,
|
|
18
|
+
NodeFilter.SHOW_COMMENT,
|
|
19
|
+
{
|
|
20
|
+
acceptNode(node: Comment) {
|
|
21
|
+
return node.nodeValue?.trim() === matchingText.trim()
|
|
22
|
+
? NodeFilter.FILTER_ACCEPT
|
|
23
|
+
: NodeFilter.FILTER_REJECT;
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
return walker.nextNode() as Comment | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function updateHeadEls(type: "meta" | "rest", blocks: Array<HeadEl>) {
|
|
31
|
+
const { startComment, endComment } = getStartAndEndComments(type);
|
|
32
|
+
if (!startComment || !endComment || !endComment.parentNode) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const parent = endComment.parentNode;
|
|
36
|
+
|
|
37
|
+
// Collect all current nodes between start and end comments
|
|
38
|
+
const currentNodes: Array<Node> = [];
|
|
39
|
+
let nodePtr = startComment.nextSibling;
|
|
40
|
+
while (nodePtr != null && nodePtr !== endComment) {
|
|
41
|
+
currentNodes.push(nodePtr);
|
|
42
|
+
nodePtr = nodePtr.nextSibling;
|
|
43
|
+
}
|
|
44
|
+
const currentElements = currentNodes.filter(
|
|
45
|
+
(node): node is Element => node.nodeType === Node.ELEMENT_NODE,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Create new elements from blocks
|
|
49
|
+
const newElements: Array<Element> = [];
|
|
50
|
+
const newElementFingerprints = new Map<string, Element>();
|
|
51
|
+
for (const block of blocks) {
|
|
52
|
+
if (!block.tag) {
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const newEl = document.createElement(block.tag);
|
|
56
|
+
if (block.attributesKnownSafe) {
|
|
57
|
+
for (const key of Object.keys(block.attributesKnownSafe)) {
|
|
58
|
+
const value = block.attributesKnownSafe[key];
|
|
59
|
+
if (value === null || value === undefined) {
|
|
60
|
+
panic(
|
|
61
|
+
`Attribute value for '${key}' in tag '${block.tag}' cannot be null or undefined.`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
newEl.setAttribute(key, value);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (block.booleanAttributes) {
|
|
68
|
+
for (const key of block.booleanAttributes) {
|
|
69
|
+
newEl.setAttribute(key, "");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (block.dangerousInnerHTML) {
|
|
73
|
+
newEl.innerHTML = block.dangerousInnerHTML;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const fingerprint = createElementFingerprint(newEl);
|
|
77
|
+
if (newElementFingerprints.has(fingerprint)) {
|
|
78
|
+
const elementToRemove = newElementFingerprints.get(fingerprint);
|
|
79
|
+
if (elementToRemove) {
|
|
80
|
+
const indexToRemove = newElements.indexOf(elementToRemove);
|
|
81
|
+
if (indexToRemove > -1) {
|
|
82
|
+
newElements.splice(indexToRemove, 1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
newElements.push(newEl);
|
|
87
|
+
newElementFingerprints.set(fingerprint, newEl);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Build a map of current elements by fingerprint
|
|
91
|
+
const currentElementsMap = new Map<string, Array<Element>>();
|
|
92
|
+
for (const el of currentElements) {
|
|
93
|
+
const fingerprint = createElementFingerprint(el);
|
|
94
|
+
if (!currentElementsMap.has(fingerprint)) {
|
|
95
|
+
currentElementsMap.set(fingerprint, []);
|
|
96
|
+
}
|
|
97
|
+
currentElementsMap.get(fingerprint)?.push(el);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Match new elements with existing ones when possible
|
|
101
|
+
const finalElements: Array<Element> = [];
|
|
102
|
+
const usedCurrentElements = new Set<Element>();
|
|
103
|
+
|
|
104
|
+
for (const newEl of newElements) {
|
|
105
|
+
const fingerprint = createElementFingerprint(newEl);
|
|
106
|
+
const matchingCurrentElementsList =
|
|
107
|
+
currentElementsMap.get(fingerprint) || [];
|
|
108
|
+
|
|
109
|
+
// Find the first matching element that hasn't been used yet
|
|
110
|
+
const matchingElement = matchingCurrentElementsList.find(
|
|
111
|
+
(el) => !usedCurrentElements.has(el),
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
if (matchingElement) {
|
|
115
|
+
usedCurrentElements.add(matchingElement);
|
|
116
|
+
finalElements.push(matchingElement);
|
|
117
|
+
} else {
|
|
118
|
+
finalElements.push(newEl);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Create a map to track which elements are in the correct position
|
|
123
|
+
// and which need to be moved or added
|
|
124
|
+
const desiredPositions = new Map<Element, number>();
|
|
125
|
+
finalElements.forEach((el, index) => {
|
|
126
|
+
desiredPositions.set(el, index);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Track elements still in the DOM
|
|
130
|
+
const remainingCurrentElements = new Set(currentElements);
|
|
131
|
+
|
|
132
|
+
// First pass: remove elements that are no longer needed
|
|
133
|
+
for (const currentElement of currentElements) {
|
|
134
|
+
if (!usedCurrentElements.has(currentElement)) {
|
|
135
|
+
parent.removeChild(currentElement);
|
|
136
|
+
remainingCurrentElements.delete(currentElement);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Second pass: position elements in the correct order with minimal DOM operations
|
|
141
|
+
let lastProcessedElement: Element | null = null;
|
|
142
|
+
|
|
143
|
+
for (let i = 0; i < finalElements.length; i++) {
|
|
144
|
+
const element = finalElements[i];
|
|
145
|
+
if (!element) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const isExistingElement = usedCurrentElements.has(element);
|
|
149
|
+
|
|
150
|
+
if (isExistingElement) {
|
|
151
|
+
// Check if this element is already in the correct position
|
|
152
|
+
const nextElementInDOM = (
|
|
153
|
+
lastProcessedElement
|
|
154
|
+
? lastProcessedElement.nextElementSibling
|
|
155
|
+
: startComment.nextElementSibling
|
|
156
|
+
) as Element | null;
|
|
157
|
+
|
|
158
|
+
if (nextElementInDOM !== element) {
|
|
159
|
+
// Element exists but is in the wrong position, move it
|
|
160
|
+
parent.insertBefore(element, nextElementInDOM || endComment);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Mark as processed
|
|
164
|
+
remainingCurrentElements.delete(element);
|
|
165
|
+
lastProcessedElement = element;
|
|
166
|
+
} else {
|
|
167
|
+
// This is a new element, insert it
|
|
168
|
+
const insertBefore = lastProcessedElement
|
|
169
|
+
? lastProcessedElement.nextSibling
|
|
170
|
+
: startComment.nextSibling;
|
|
171
|
+
|
|
172
|
+
parent.insertBefore(element, insertBefore || endComment);
|
|
173
|
+
lastProcessedElement = element;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function createElementFingerprint(element: Element): string {
|
|
179
|
+
const attributes: Array<string> = [];
|
|
180
|
+
for (let i = 0; i < element.attributes.length; i++) {
|
|
181
|
+
const attr = element.attributes[i];
|
|
182
|
+
if (!attr) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const value =
|
|
186
|
+
element.hasAttribute(attr.name) && attr.value === ""
|
|
187
|
+
? ""
|
|
188
|
+
: attr.value;
|
|
189
|
+
attributes.push(`${attr.name}="${value}"`);
|
|
190
|
+
}
|
|
191
|
+
attributes.sort();
|
|
192
|
+
return `${element.tagName.toUpperCase()}|${attributes.join(",")}|${(element.innerHTML || "").trim()}`;
|
|
193
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { createBrowserHistory, type Update as NPMHistoryUpdate } from "history";
|
|
2
|
+
import { navigationStateManager } from "../client.ts";
|
|
3
|
+
import { dispatchLocationEvent } from "../events.ts";
|
|
4
|
+
import {
|
|
5
|
+
__applyScrollState,
|
|
6
|
+
saveScrollState,
|
|
7
|
+
scrollStateManager,
|
|
8
|
+
} from "../scroll_state_manager.ts";
|
|
9
|
+
import { logError } from "../utils/logging.ts";
|
|
10
|
+
import type { historyInstance, historyListener } from "./npm_history_types.ts";
|
|
11
|
+
|
|
12
|
+
export class HistoryManager {
|
|
13
|
+
private static instance: historyInstance;
|
|
14
|
+
private static lastKnownLocation: typeof HistoryManager.instance.location;
|
|
15
|
+
|
|
16
|
+
static getInstance(): historyInstance {
|
|
17
|
+
if (!this.instance) {
|
|
18
|
+
this.instance =
|
|
19
|
+
createBrowserHistory() as unknown as historyInstance;
|
|
20
|
+
this.lastKnownLocation = this.instance.location;
|
|
21
|
+
}
|
|
22
|
+
return this.instance;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static getLastKnownLocation() {
|
|
26
|
+
return this.lastKnownLocation;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static updateLastKnownLocation(
|
|
30
|
+
location: typeof HistoryManager.instance.location,
|
|
31
|
+
) {
|
|
32
|
+
this.lastKnownLocation = location;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static init(): void {
|
|
36
|
+
const instance = this.getInstance();
|
|
37
|
+
instance.listen(customHistoryListener as unknown as historyListener);
|
|
38
|
+
this.setManualScrollRestoration();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private static setManualScrollRestoration(): void {
|
|
42
|
+
if (
|
|
43
|
+
history.scrollRestoration &&
|
|
44
|
+
history.scrollRestoration !== "manual"
|
|
45
|
+
) {
|
|
46
|
+
history.scrollRestoration = "manual";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function initCustomHistory(): void {
|
|
52
|
+
HistoryManager.init();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function customHistoryListener({
|
|
56
|
+
action,
|
|
57
|
+
location,
|
|
58
|
+
}: NPMHistoryUpdate): Promise<void> {
|
|
59
|
+
const lastKnownLocation = HistoryManager.getLastKnownLocation();
|
|
60
|
+
|
|
61
|
+
if (location.key !== lastKnownLocation.key) {
|
|
62
|
+
dispatchLocationEvent();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const popWithinSameDoc =
|
|
66
|
+
action === "POP" &&
|
|
67
|
+
location.pathname === lastKnownLocation.pathname &&
|
|
68
|
+
location.search === lastKnownLocation.search;
|
|
69
|
+
|
|
70
|
+
const removingHash =
|
|
71
|
+
popWithinSameDoc && lastKnownLocation.hash && !location.hash;
|
|
72
|
+
const addingHash =
|
|
73
|
+
popWithinSameDoc && !lastKnownLocation.hash && location.hash;
|
|
74
|
+
const updatingHash = popWithinSameDoc && location.hash;
|
|
75
|
+
|
|
76
|
+
if (!popWithinSameDoc) {
|
|
77
|
+
saveScrollState();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let navigationSucceeded = true;
|
|
81
|
+
|
|
82
|
+
if (action === "POP") {
|
|
83
|
+
const newHash = location.hash.slice(1);
|
|
84
|
+
|
|
85
|
+
if (addingHash || updatingHash) {
|
|
86
|
+
__applyScrollState({ hash: newHash });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (removingHash) {
|
|
90
|
+
const stored = scrollStateManager.getState(location.key);
|
|
91
|
+
__applyScrollState(stored ?? { x: 0, y: 0 });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!popWithinSameDoc) {
|
|
95
|
+
const result = await navigationStateManager.navigate({
|
|
96
|
+
href: window.location.href,
|
|
97
|
+
navigationType: "browserHistory",
|
|
98
|
+
scrollStateToRestore: scrollStateManager.getState(location.key),
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
if (!result.didNavigate) {
|
|
102
|
+
navigationSucceeded = false;
|
|
103
|
+
logError(
|
|
104
|
+
"Browser POP navigation failed, attempting hard reload of the destination.",
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// This just reloads the current (failed) URL.
|
|
108
|
+
// It preserves the history stack and ensures no UI/URL mismatch,
|
|
109
|
+
// which could otherwise happen if a browser forward/back navigation fails
|
|
110
|
+
window.location.reload();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (navigationSucceeded) {
|
|
116
|
+
HistoryManager.updateLastKnownLocation(location);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/******************************************************************************
|
|
2
|
+
|
|
3
|
+
This file is a condensed, comment-stripped, and prefixed-type version of
|
|
4
|
+
npm:history's index.d.ts file as of v5.3.0. npm:history is licensed under the
|
|
5
|
+
MIT license. It is used under the hood by vorma/client.
|
|
6
|
+
|
|
7
|
+
The npm:history repository is located at: https://github.com/remix-run/history
|
|
8
|
+
|
|
9
|
+
It's only purpose is to re-export a minimal version of the types needed by
|
|
10
|
+
vorma/client's "getHistoryInstance" function, which simply returns an
|
|
11
|
+
instance of npm:history's BrowserHistory.
|
|
12
|
+
|
|
13
|
+
Original license:
|
|
14
|
+
|
|
15
|
+
MIT License
|
|
16
|
+
|
|
17
|
+
Copyright (c) React Training 2016-2020
|
|
18
|
+
Copyright (c) Remix Software 2020-2021
|
|
19
|
+
|
|
20
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
21
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
22
|
+
in the Software without restriction, including without limitation the rights
|
|
23
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
24
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
25
|
+
furnished to do so, subject to the following conditions:
|
|
26
|
+
|
|
27
|
+
The above copyright notice and this permission notice shall be included in all
|
|
28
|
+
copies or substantial portions of the Software.
|
|
29
|
+
|
|
30
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
31
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
32
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
33
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
34
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
35
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
36
|
+
SOFTWARE.
|
|
37
|
+
|
|
38
|
+
******************************************************************************/
|
|
39
|
+
|
|
40
|
+
declare enum historyAction {
|
|
41
|
+
Pop = "POP",
|
|
42
|
+
Push = "PUSH",
|
|
43
|
+
Replace = "REPLACE",
|
|
44
|
+
}
|
|
45
|
+
declare type historyPathname = string;
|
|
46
|
+
declare type historySearch = string;
|
|
47
|
+
declare type historyHash = string;
|
|
48
|
+
declare type historyKey = string;
|
|
49
|
+
interface historyPath {
|
|
50
|
+
pathname: historyPathname;
|
|
51
|
+
search: historySearch;
|
|
52
|
+
hash: historyHash;
|
|
53
|
+
}
|
|
54
|
+
export interface historyLocation extends historyPath {
|
|
55
|
+
state: unknown;
|
|
56
|
+
key: historyKey;
|
|
57
|
+
}
|
|
58
|
+
interface historyUpdate {
|
|
59
|
+
action: historyAction;
|
|
60
|
+
location: historyLocation;
|
|
61
|
+
}
|
|
62
|
+
export interface historyListener {
|
|
63
|
+
(update: historyUpdate): void;
|
|
64
|
+
}
|
|
65
|
+
interface historyTransition extends historyUpdate {
|
|
66
|
+
retry(): void;
|
|
67
|
+
}
|
|
68
|
+
interface historyBlocker {
|
|
69
|
+
(tx: historyTransition): void;
|
|
70
|
+
}
|
|
71
|
+
declare type historyTo = string | Partial<historyPath>;
|
|
72
|
+
export interface historyInstance {
|
|
73
|
+
readonly action: historyAction;
|
|
74
|
+
readonly location: historyLocation;
|
|
75
|
+
createHref(to: historyTo): string;
|
|
76
|
+
push(to: historyTo, state?: any): void;
|
|
77
|
+
replace(to: historyTo, state?: any): void;
|
|
78
|
+
go(delta: number): void;
|
|
79
|
+
back(): void;
|
|
80
|
+
forward(): void;
|
|
81
|
+
listen(listener: historyListener): () => void;
|
|
82
|
+
block(blocker: historyBlocker): () => void;
|
|
83
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { debounce } from "vorma/kit/debounce";
|
|
2
|
+
import { revalidate } from "../client.ts";
|
|
3
|
+
import { setupClientLoaders } from "../client_loaders.ts";
|
|
4
|
+
import { dispatchRouteChangeEvent } from "../events.ts";
|
|
5
|
+
import { logInfo } from "../utils/logging.ts";
|
|
6
|
+
import { __vormaClientGlobal } from "../vorma_ctx/vorma_ctx.ts";
|
|
7
|
+
|
|
8
|
+
let devTimeSetupClientLoadersDebounced: () => Promise<void> = () =>
|
|
9
|
+
Promise.resolve();
|
|
10
|
+
|
|
11
|
+
let hmrRevalidateSet: Set<string>;
|
|
12
|
+
|
|
13
|
+
export let __runClientLoadersAfterHMRUpdate: (
|
|
14
|
+
importMeta: ImportMeta,
|
|
15
|
+
pattern: string,
|
|
16
|
+
) => void = () => {};
|
|
17
|
+
|
|
18
|
+
export function initHMR() {
|
|
19
|
+
if (import.meta.env.DEV) {
|
|
20
|
+
(window as any).__waveRevalidate = revalidate;
|
|
21
|
+
|
|
22
|
+
devTimeSetupClientLoadersDebounced = debounce(async () => {
|
|
23
|
+
await setupClientLoaders();
|
|
24
|
+
dispatchRouteChangeEvent({});
|
|
25
|
+
}, 10);
|
|
26
|
+
|
|
27
|
+
__runClientLoadersAfterHMRUpdate = (importMeta, pattern) => {
|
|
28
|
+
if (hmrRevalidateSet === undefined) {
|
|
29
|
+
hmrRevalidateSet = new Set();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (import.meta.env.DEV && import.meta.hot) {
|
|
33
|
+
const thisURL = new URL(importMeta.url, location.href);
|
|
34
|
+
thisURL.search = "";
|
|
35
|
+
const thisPathname = thisURL.pathname;
|
|
36
|
+
|
|
37
|
+
const alreadyRegistered = hmrRevalidateSet.has(thisPathname);
|
|
38
|
+
if (alreadyRegistered) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
hmrRevalidateSet.add(thisPathname);
|
|
43
|
+
|
|
44
|
+
import.meta.hot.on("vite:afterUpdate", (props) => {
|
|
45
|
+
for (const update of props.updates) {
|
|
46
|
+
if (update.type === "js-update") {
|
|
47
|
+
const updateURL = new URL(
|
|
48
|
+
update.path,
|
|
49
|
+
location.href,
|
|
50
|
+
);
|
|
51
|
+
updateURL.search = "";
|
|
52
|
+
if (updateURL.pathname === thisURL.pathname) {
|
|
53
|
+
if (
|
|
54
|
+
__vormaClientGlobal
|
|
55
|
+
.get("matchedPatterns")
|
|
56
|
+
.includes(pattern)
|
|
57
|
+
) {
|
|
58
|
+
logInfo(
|
|
59
|
+
"Refreshing client loaders due to change in pattern:",
|
|
60
|
+
pattern,
|
|
61
|
+
);
|
|
62
|
+
devTimeSetupClientLoadersDebounced();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPatternRegistry,
|
|
3
|
+
registerPattern,
|
|
4
|
+
} from "vorma/kit/matcher/register";
|
|
5
|
+
import { setupClientLoaders } from "./client_loaders.ts";
|
|
6
|
+
import { ComponentLoader } from "./component_loader.ts";
|
|
7
|
+
import { defaultErrorBoundary } from "./error_boundary.ts";
|
|
8
|
+
import { VORMA_HARD_RELOAD_QUERY_PARAM } from "./hard_reload.ts";
|
|
9
|
+
import { HistoryManager } from "./history/history.ts";
|
|
10
|
+
import { initHMR } from "./hmr/hmr.ts";
|
|
11
|
+
import { scrollStateManager } from "./scroll_state_manager.ts";
|
|
12
|
+
import type { VormaAppConfig } from "./vorma_app_helpers/vorma_app_helpers.ts";
|
|
13
|
+
import {
|
|
14
|
+
__vormaClientGlobal,
|
|
15
|
+
type RouteErrorComponent,
|
|
16
|
+
type VormaClientGlobal,
|
|
17
|
+
} from "./vorma_ctx/vorma_ctx.ts";
|
|
18
|
+
|
|
19
|
+
export async function initClient(options: {
|
|
20
|
+
vormaAppConfig: VormaAppConfig;
|
|
21
|
+
renderFn: () => void;
|
|
22
|
+
defaultErrorBoundary?: RouteErrorComponent;
|
|
23
|
+
useViewTransitions?: boolean;
|
|
24
|
+
}): Promise<void> {
|
|
25
|
+
initHMR();
|
|
26
|
+
|
|
27
|
+
// Setup beforeunload handler for scroll restoration
|
|
28
|
+
window.addEventListener("beforeunload", () => {
|
|
29
|
+
scrollStateManager.savePageRefreshState();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
__vormaClientGlobal.set("vormaAppConfig", options.vormaAppConfig);
|
|
33
|
+
const clientModuleMap: VormaClientGlobal["clientModuleMap"] = {};
|
|
34
|
+
|
|
35
|
+
// Populate client module map with initial page's modules
|
|
36
|
+
const initialMatchedPatterns =
|
|
37
|
+
__vormaClientGlobal.get("matchedPatterns") || [];
|
|
38
|
+
const initialImportURLs = __vormaClientGlobal.get("importURLs") || [];
|
|
39
|
+
const initialExportKeys = __vormaClientGlobal.get("exportKeys") || [];
|
|
40
|
+
const initialErrorExportKeys =
|
|
41
|
+
__vormaClientGlobal.get("errorExportKeys") || [];
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < initialMatchedPatterns.length; i++) {
|
|
44
|
+
const pattern = initialMatchedPatterns[i];
|
|
45
|
+
const importURL = initialImportURLs[i];
|
|
46
|
+
const exportKey = initialExportKeys[i];
|
|
47
|
+
const errorExportKey = initialErrorExportKeys[i];
|
|
48
|
+
|
|
49
|
+
if (pattern && importURL) {
|
|
50
|
+
clientModuleMap[pattern] = {
|
|
51
|
+
importURL,
|
|
52
|
+
exportKey: exportKey || "default",
|
|
53
|
+
errorExportKey: errorExportKey || "",
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
__vormaClientGlobal.set("clientModuleMap", clientModuleMap);
|
|
58
|
+
|
|
59
|
+
const patternRegistry = createPatternRegistry({
|
|
60
|
+
dynamicParamPrefixRune: options.vormaAppConfig.loadersDynamicRune,
|
|
61
|
+
splatSegmentRune: options.vormaAppConfig.loadersSplatRune,
|
|
62
|
+
explicitIndexSegment:
|
|
63
|
+
options.vormaAppConfig.loadersExplicitIndexSegment,
|
|
64
|
+
});
|
|
65
|
+
__vormaClientGlobal.set("patternRegistry", patternRegistry);
|
|
66
|
+
|
|
67
|
+
const manifestURL = __vormaClientGlobal.get("routeManifestURL");
|
|
68
|
+
if (manifestURL) {
|
|
69
|
+
fetch(manifestURL)
|
|
70
|
+
.then((response) => response.json())
|
|
71
|
+
.then((manifest) => {
|
|
72
|
+
__vormaClientGlobal.set("routeManifest", manifest);
|
|
73
|
+
|
|
74
|
+
// Register all patterns from manifest into the existing registry
|
|
75
|
+
for (const pattern of Object.keys(manifest)) {
|
|
76
|
+
registerPattern(patternRegistry, pattern);
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.catch((error) => {
|
|
80
|
+
// This is no biggie -- it's a progressive enhancement
|
|
81
|
+
console.warn("Failed to load route manifest:", error);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Set options
|
|
86
|
+
if (options.defaultErrorBoundary) {
|
|
87
|
+
__vormaClientGlobal.set(
|
|
88
|
+
"defaultErrorBoundary",
|
|
89
|
+
options.defaultErrorBoundary,
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
__vormaClientGlobal.set("defaultErrorBoundary", defaultErrorBoundary);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (options.useViewTransitions) {
|
|
96
|
+
__vormaClientGlobal.set("useViewTransitions", true);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Initialize history
|
|
100
|
+
HistoryManager.init();
|
|
101
|
+
|
|
102
|
+
// Clean URL
|
|
103
|
+
const url = new URL(window.location.href);
|
|
104
|
+
if (url.searchParams.has(VORMA_HARD_RELOAD_QUERY_PARAM)) {
|
|
105
|
+
url.searchParams.delete(VORMA_HARD_RELOAD_QUERY_PARAM);
|
|
106
|
+
HistoryManager.getInstance().replace(url.href);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const importURLs = __vormaClientGlobal.get("importURLs");
|
|
110
|
+
|
|
111
|
+
// Load initial components
|
|
112
|
+
await ComponentLoader.handleComponents(importURLs);
|
|
113
|
+
|
|
114
|
+
// Setup client loaders
|
|
115
|
+
await setupClientLoaders();
|
|
116
|
+
|
|
117
|
+
// Handle error boundary component (must come after setupClientLoaders)
|
|
118
|
+
await ComponentLoader.handleErrorBoundaryComponent(importURLs);
|
|
119
|
+
|
|
120
|
+
// Render
|
|
121
|
+
options.renderFn();
|
|
122
|
+
|
|
123
|
+
// Restore scroll
|
|
124
|
+
scrollStateManager.restorePageRefreshState();
|
|
125
|
+
|
|
126
|
+
// Touch detection
|
|
127
|
+
window.addEventListener(
|
|
128
|
+
"touchstart",
|
|
129
|
+
() => {
|
|
130
|
+
__vormaClientGlobal.set("isTouchDevice", true);
|
|
131
|
+
},
|
|
132
|
+
{ once: true },
|
|
133
|
+
);
|
|
134
|
+
}
|