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,32 @@
|
|
|
1
|
+
import { addOnWindowFocusListener } from "vorma/kit/listeners";
|
|
2
|
+
import {
|
|
3
|
+
getLastTriggeredNavOrRevalidateTimestampMS,
|
|
4
|
+
getStatus,
|
|
5
|
+
revalidate,
|
|
6
|
+
} from "../client.ts";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* If called, will setup listeners to revalidate the current route when
|
|
10
|
+
* the window regains focus and at least `staleTimeMS` has passed since
|
|
11
|
+
* the last revalidation. The `staleTimeMS` option defaults to 5,000
|
|
12
|
+
* (5 seconds). Returns a cleanup function.
|
|
13
|
+
*/
|
|
14
|
+
export function revalidateOnWindowFocus(options?: { staleTimeMS?: number }) {
|
|
15
|
+
const staleTimeMS = options?.staleTimeMS ?? 5_000;
|
|
16
|
+
return addOnWindowFocusListener(() => {
|
|
17
|
+
const status = getStatus();
|
|
18
|
+
if (
|
|
19
|
+
!status.isNavigating &&
|
|
20
|
+
!status.isSubmitting &&
|
|
21
|
+
!status.isRevalidating
|
|
22
|
+
) {
|
|
23
|
+
if (
|
|
24
|
+
Date.now() - getLastTriggeredNavOrRevalidateTimestampMS() <
|
|
25
|
+
staleTimeMS
|
|
26
|
+
) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
revalidate();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
cancel,
|
|
5
|
+
confirm,
|
|
6
|
+
intro,
|
|
7
|
+
isCancel,
|
|
8
|
+
log,
|
|
9
|
+
select,
|
|
10
|
+
spinner,
|
|
11
|
+
text,
|
|
12
|
+
} from "@clack/prompts";
|
|
13
|
+
import { execSync } from "node:child_process";
|
|
14
|
+
import * as fs from "node:fs";
|
|
15
|
+
import * as os from "node:os";
|
|
16
|
+
import * as path from "node:path";
|
|
17
|
+
import { dirname } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
const isLocalTest = args.includes("--local-test");
|
|
26
|
+
|
|
27
|
+
console.log();
|
|
28
|
+
intro("Welcome to the Vorma new app creator!");
|
|
29
|
+
|
|
30
|
+
// Check Go installation
|
|
31
|
+
let goVersion = "";
|
|
32
|
+
try {
|
|
33
|
+
goVersion = execSync("go version", { encoding: "utf8" }).trim();
|
|
34
|
+
const versionMatch = goVersion.match(/go(\d+)\.(\d+)/);
|
|
35
|
+
if (versionMatch) {
|
|
36
|
+
if (!versionMatch[1] || !versionMatch[2]) {
|
|
37
|
+
cancel(
|
|
38
|
+
"Go version not recognized. Please ensure Go is installed correctly. See https://go.dev/doc/install for installation instructions.",
|
|
39
|
+
);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const major = parseInt(versionMatch[1]);
|
|
43
|
+
const minor = parseInt(versionMatch[2]);
|
|
44
|
+
if (major < 1 || (major === 1 && minor < 24)) {
|
|
45
|
+
cancel(
|
|
46
|
+
"Go version 1.24 or higher is required. See https://go.dev/doc/install for installation instructions.",
|
|
47
|
+
);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} catch {
|
|
52
|
+
cancel(
|
|
53
|
+
"Go is not installed. See https://go.dev/doc/install for installation instructions.",
|
|
54
|
+
);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Check Node version
|
|
59
|
+
const nodeVersion = process.version;
|
|
60
|
+
const firstPart = nodeVersion.split(".")[0];
|
|
61
|
+
if (!firstPart || firstPart.length < 2 || !firstPart.startsWith("v")) {
|
|
62
|
+
cancel(
|
|
63
|
+
"Node.js version not recognized. Please ensure Node.js is installed correctly.",
|
|
64
|
+
);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const nodeMajor = parseInt(firstPart.substring(1));
|
|
68
|
+
if (nodeMajor < 22) {
|
|
69
|
+
cancel("Node.js version 22.11 or higher is required");
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Option to create a new directory at start if not already in desired location
|
|
74
|
+
const createNewDir = await confirm({
|
|
75
|
+
message: "Create a new directory for your Vorma app?",
|
|
76
|
+
initialValue: true,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (isCancel(createNewDir)) {
|
|
80
|
+
cancel("Operation cancelled");
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let targetDir = process.cwd();
|
|
85
|
+
|
|
86
|
+
if (createNewDir) {
|
|
87
|
+
const dirName = await text({
|
|
88
|
+
message: "Enter directory name:",
|
|
89
|
+
validate: (value) => {
|
|
90
|
+
if (!value || value.trim() === "")
|
|
91
|
+
return "Directory name is required";
|
|
92
|
+
// Check for invalid characters in directory name
|
|
93
|
+
if (!/^[a-zA-Z0-9-_]+$/.test(value)) {
|
|
94
|
+
return "Directory name can only contain letters, numbers, hyphens, and underscores";
|
|
95
|
+
}
|
|
96
|
+
// Check if directory already exists
|
|
97
|
+
const proposedPath = path.join(process.cwd(), value);
|
|
98
|
+
if (fs.existsSync(proposedPath)) {
|
|
99
|
+
return `Directory "${value}" already exists`;
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (isCancel(dirName)) {
|
|
106
|
+
cancel("Operation cancelled");
|
|
107
|
+
process.exit(0);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Create the directory and change to it
|
|
111
|
+
targetDir = path.join(process.cwd(), dirName as string);
|
|
112
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
113
|
+
process.chdir(targetDir);
|
|
114
|
+
log.success(`Created directory: ${dirName}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Find go.mod and determine import path
|
|
118
|
+
let goModPath: string | null = null;
|
|
119
|
+
let moduleRoot: string | null = null;
|
|
120
|
+
let moduleName: string | null = null;
|
|
121
|
+
let createNewModule = false;
|
|
122
|
+
|
|
123
|
+
// Search for go.mod
|
|
124
|
+
let currentDir = process.cwd();
|
|
125
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
126
|
+
const modPath = path.join(currentDir, "go.mod");
|
|
127
|
+
if (fs.existsSync(modPath)) {
|
|
128
|
+
goModPath = modPath;
|
|
129
|
+
moduleRoot = currentDir;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
currentDir = path.dirname(currentDir);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Parse module name if found
|
|
136
|
+
if (goModPath) {
|
|
137
|
+
const modContent = fs.readFileSync(goModPath, "utf8");
|
|
138
|
+
const moduleMatch = modContent.match(/^module\s+(.+)$/m);
|
|
139
|
+
if (moduleMatch && moduleMatch[1]) {
|
|
140
|
+
moduleName = moduleMatch[1].trim();
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// When module is found, give option to use it or create nested module
|
|
144
|
+
const moduleChoice = await select({
|
|
145
|
+
message: `Found parent Go module: ${moduleName}`,
|
|
146
|
+
options: [
|
|
147
|
+
{ value: "new", label: "Create new go.mod" },
|
|
148
|
+
{ value: "use", label: "Use parent go.mod" },
|
|
149
|
+
],
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
if (isCancel(moduleChoice)) {
|
|
153
|
+
cancel("Operation cancelled");
|
|
154
|
+
process.exit(0);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (moduleChoice === "new") {
|
|
158
|
+
createNewModule = true;
|
|
159
|
+
// Reset module info since we're creating a new one
|
|
160
|
+
goModPath = null;
|
|
161
|
+
moduleRoot = null;
|
|
162
|
+
moduleName = null;
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
// No module found, we need to create one
|
|
166
|
+
createNewModule = true;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Handle go.mod initialization if needed
|
|
170
|
+
if (createNewModule) {
|
|
171
|
+
const modNameInput = await text({
|
|
172
|
+
message:
|
|
173
|
+
'Enter module name (e.g., "myapp" or "github.com/user/myapp"):',
|
|
174
|
+
validate: (value) => {
|
|
175
|
+
if (!value || value.trim() === "")
|
|
176
|
+
return "Module name is required";
|
|
177
|
+
return undefined;
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
if (isCancel(modNameInput)) {
|
|
182
|
+
cancel("Operation cancelled");
|
|
183
|
+
process.exit(0);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
moduleName = modNameInput as string;
|
|
187
|
+
moduleRoot = process.cwd();
|
|
188
|
+
|
|
189
|
+
const s = spinner();
|
|
190
|
+
s.start("Initializing Go module");
|
|
191
|
+
try {
|
|
192
|
+
execSync(`go mod init ${moduleName}`, { cwd: moduleRoot });
|
|
193
|
+
if (isLocalTest) {
|
|
194
|
+
const vormaPath = path.resolve(__dirname, "../../../../../");
|
|
195
|
+
execSync(
|
|
196
|
+
`go mod edit -replace github.com/vormadev/vorma=${vormaPath}`,
|
|
197
|
+
{ cwd: moduleRoot },
|
|
198
|
+
);
|
|
199
|
+
log.info("Using local Vorma code for testing");
|
|
200
|
+
}
|
|
201
|
+
s.stop("Go module initialized");
|
|
202
|
+
} catch (error) {
|
|
203
|
+
s.stop("Failed to initialize module");
|
|
204
|
+
cancel(`Error: ${error}`);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Check for underscore directories from module root to current directory
|
|
210
|
+
const pathFromModuleRoot = moduleRoot
|
|
211
|
+
? path.relative(moduleRoot, process.cwd())
|
|
212
|
+
: "";
|
|
213
|
+
const pathSegments = pathFromModuleRoot
|
|
214
|
+
.split(path.sep)
|
|
215
|
+
.filter((seg) => seg.length > 0);
|
|
216
|
+
const underscoreSegments = pathSegments.filter((seg) =>
|
|
217
|
+
seg.startsWith("_"),
|
|
218
|
+
);
|
|
219
|
+
if (underscoreSegments.length > 0) {
|
|
220
|
+
cancel(
|
|
221
|
+
`Cannot create Vorma app in a path containing directories that start with underscores:\n ${underscoreSegments.join(", ")}\n` +
|
|
222
|
+
` Go ignores directories starting with underscores, which will cause build issues.`,
|
|
223
|
+
);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Calculate import path automatically
|
|
228
|
+
let importPath = moduleName!;
|
|
229
|
+
if (moduleRoot !== process.cwd()) {
|
|
230
|
+
const relativePath = path.relative(moduleRoot!, process.cwd());
|
|
231
|
+
importPath = path.posix.join(
|
|
232
|
+
moduleName!,
|
|
233
|
+
...relativePath.split(path.sep),
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Collect options
|
|
238
|
+
const uiVariant = await select({
|
|
239
|
+
message: "Choose frontend UI library:",
|
|
240
|
+
options: [
|
|
241
|
+
{ value: "react", label: "React" },
|
|
242
|
+
{ value: "preact", label: "Preact" },
|
|
243
|
+
{ value: "solid", label: "Solid" },
|
|
244
|
+
],
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (isCancel(uiVariant)) {
|
|
248
|
+
cancel("Operation cancelled");
|
|
249
|
+
process.exit(0);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const packageManager = (await select({
|
|
253
|
+
message: "Choose JS package manager:",
|
|
254
|
+
options: [
|
|
255
|
+
{ value: "npm", label: "npm" },
|
|
256
|
+
{ value: "pnpm", label: "pnpm" },
|
|
257
|
+
{ value: "yarn", label: "yarn" },
|
|
258
|
+
{ value: "bun", label: "bun" },
|
|
259
|
+
],
|
|
260
|
+
})) as string;
|
|
261
|
+
|
|
262
|
+
if (isCancel(packageManager)) {
|
|
263
|
+
cancel("Operation cancelled");
|
|
264
|
+
process.exit(0);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const deploymentTarget = await select({
|
|
268
|
+
message: "Choose deployment target:",
|
|
269
|
+
options: [
|
|
270
|
+
{
|
|
271
|
+
value: "docker",
|
|
272
|
+
label: "Docker",
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
value: "vercel",
|
|
276
|
+
label: "Vercel",
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
value: "none",
|
|
280
|
+
label: "None (I'll figure it out myself)",
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
if (isCancel(deploymentTarget)) {
|
|
286
|
+
cancel("Operation cancelled");
|
|
287
|
+
process.exit(0);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Ask about Tailwind CSS
|
|
291
|
+
const includeTailwind = await confirm({
|
|
292
|
+
message: "Include Tailwind CSS?",
|
|
293
|
+
initialValue: false,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
if (isCancel(includeTailwind)) {
|
|
297
|
+
cancel("Operation cancelled");
|
|
298
|
+
process.exit(0);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
console.log();
|
|
302
|
+
console.log("🛠️ Preparing bootstrapper...");
|
|
303
|
+
|
|
304
|
+
// Create temporary directory
|
|
305
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "create-vorma-"));
|
|
306
|
+
const bootstrapFile = path.join(tempDir, "main.go");
|
|
307
|
+
|
|
308
|
+
// Extract Go version string (e.g., "go1.24.0")
|
|
309
|
+
const goVersionMatch = goVersion.match(/go\d+\.\d+\.\d+/);
|
|
310
|
+
const goVersionString = goVersionMatch ? goVersionMatch[0] : "";
|
|
311
|
+
|
|
312
|
+
try {
|
|
313
|
+
// Write bootstrap Go file
|
|
314
|
+
const goCode = `package main
|
|
315
|
+
|
|
316
|
+
import "github.com/vormadev/vorma/bootstrap"
|
|
317
|
+
|
|
318
|
+
func main() {
|
|
319
|
+
bootstrap.Init(bootstrap.Options{
|
|
320
|
+
GoImportBase: "${importPath}",
|
|
321
|
+
UIVariant: "${uiVariant}",
|
|
322
|
+
JSPackageManager: "${packageManager}",
|
|
323
|
+
DeploymentTarget: "${deploymentTarget}",
|
|
324
|
+
IncludeTailwind: ${includeTailwind},
|
|
325
|
+
NodeMajorVersion: "${nodeMajor}",
|
|
326
|
+
GoVersion: "${goVersionString}",
|
|
327
|
+
${createNewDir ? `CreatedInDir: "${path.basename(targetDir)}",` : ""}
|
|
328
|
+
ModuleRoot: "${moduleRoot || process.cwd()}",
|
|
329
|
+
CurrentDir: "${process.cwd()}",
|
|
330
|
+
HasParentModule: ${moduleRoot !== null && moduleRoot !== process.cwd()},
|
|
331
|
+
})
|
|
332
|
+
}
|
|
333
|
+
`;
|
|
334
|
+
fs.writeFileSync(bootstrapFile, goCode);
|
|
335
|
+
|
|
336
|
+
// Install Vorma dependency
|
|
337
|
+
const packageJsonPath = path.join(__dirname, "../package.json");
|
|
338
|
+
const packageJson = JSON.parse(
|
|
339
|
+
fs.readFileSync(packageJsonPath, "utf8"),
|
|
340
|
+
);
|
|
341
|
+
const version = packageJson.version;
|
|
342
|
+
const usingExistingModule = !createNewModule;
|
|
343
|
+
const skipVormaGet = isLocalTest && usingExistingModule;
|
|
344
|
+
if (!skipVormaGet) {
|
|
345
|
+
execSync(`go get github.com/vormadev/vorma@v${version}`, {
|
|
346
|
+
cwd: process.cwd(),
|
|
347
|
+
stdio: "pipe",
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Run bootstrap
|
|
352
|
+
console.log("🛠️ Running bootstrapper...");
|
|
353
|
+
try {
|
|
354
|
+
execSync(`go run ${bootstrapFile}`, {
|
|
355
|
+
cwd: process.cwd(),
|
|
356
|
+
stdio: "inherit",
|
|
357
|
+
});
|
|
358
|
+
} catch (error) {
|
|
359
|
+
console.error("Failed to create app");
|
|
360
|
+
throw error;
|
|
361
|
+
}
|
|
362
|
+
} catch (error) {
|
|
363
|
+
cancel(`Error: ${error}`);
|
|
364
|
+
process.exit(1);
|
|
365
|
+
} finally {
|
|
366
|
+
// Clean up temp directory
|
|
367
|
+
try {
|
|
368
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
369
|
+
} catch {
|
|
370
|
+
// Ignore cleanup errors
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
main().catch((error) => {
|
|
376
|
+
console.error("Unexpected error:", error);
|
|
377
|
+
process.exit(1);
|
|
378
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-vorma",
|
|
3
|
+
"version": "0.83.0",
|
|
4
|
+
"description": "CLI for creating new Vorma applications.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "BSD-3-Clause",
|
|
7
|
+
"repository": {
|
|
8
|
+
"url": "https://github.com/vormadev/vorma",
|
|
9
|
+
"type": "git",
|
|
10
|
+
"directory": "internal/framework/_typescript/create"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/vormadev/vorma/issues"
|
|
14
|
+
},
|
|
15
|
+
"homepage": "https://vorma.dev",
|
|
16
|
+
"author": "Samuel J. Cook",
|
|
17
|
+
"bin": {
|
|
18
|
+
"create-vorma": "./dist/main.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@clack/prompts": "^0.11.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^24.2.1",
|
|
28
|
+
"typescript": "^5.9.2"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=22.11.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
lockfileVersion: '9.0'
|
|
2
|
+
|
|
3
|
+
settings:
|
|
4
|
+
autoInstallPeers: true
|
|
5
|
+
excludeLinksFromLockfile: false
|
|
6
|
+
|
|
7
|
+
importers:
|
|
8
|
+
|
|
9
|
+
.:
|
|
10
|
+
dependencies:
|
|
11
|
+
'@clack/prompts':
|
|
12
|
+
specifier: ^0.11.0
|
|
13
|
+
version: 0.11.0
|
|
14
|
+
devDependencies:
|
|
15
|
+
'@types/node':
|
|
16
|
+
specifier: ^24.2.1
|
|
17
|
+
version: 24.2.1
|
|
18
|
+
typescript:
|
|
19
|
+
specifier: ^5.9.2
|
|
20
|
+
version: 5.9.2
|
|
21
|
+
|
|
22
|
+
packages:
|
|
23
|
+
|
|
24
|
+
'@clack/core@0.5.0':
|
|
25
|
+
resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==}
|
|
26
|
+
|
|
27
|
+
'@clack/prompts@0.11.0':
|
|
28
|
+
resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==}
|
|
29
|
+
|
|
30
|
+
'@types/node@24.2.1':
|
|
31
|
+
resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==}
|
|
32
|
+
|
|
33
|
+
picocolors@1.1.1:
|
|
34
|
+
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
|
35
|
+
|
|
36
|
+
sisteransi@1.0.5:
|
|
37
|
+
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
|
38
|
+
|
|
39
|
+
typescript@5.9.2:
|
|
40
|
+
resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==}
|
|
41
|
+
engines: {node: '>=14.17'}
|
|
42
|
+
hasBin: true
|
|
43
|
+
|
|
44
|
+
undici-types@7.10.0:
|
|
45
|
+
resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==}
|
|
46
|
+
|
|
47
|
+
snapshots:
|
|
48
|
+
|
|
49
|
+
'@clack/core@0.5.0':
|
|
50
|
+
dependencies:
|
|
51
|
+
picocolors: 1.1.1
|
|
52
|
+
sisteransi: 1.0.5
|
|
53
|
+
|
|
54
|
+
'@clack/prompts@0.11.0':
|
|
55
|
+
dependencies:
|
|
56
|
+
'@clack/core': 0.5.0
|
|
57
|
+
picocolors: 1.1.1
|
|
58
|
+
sisteransi: 1.0.5
|
|
59
|
+
|
|
60
|
+
'@types/node@24.2.1':
|
|
61
|
+
dependencies:
|
|
62
|
+
undici-types: 7.10.0
|
|
63
|
+
|
|
64
|
+
picocolors@1.1.1: {}
|
|
65
|
+
|
|
66
|
+
sisteransi@1.0.5: {}
|
|
67
|
+
|
|
68
|
+
typescript@5.9.2: {}
|
|
69
|
+
|
|
70
|
+
undici-types@7.10.0: {}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export {
|
|
2
|
+
makeTypedAddClientLoader,
|
|
3
|
+
makeTypedUseLoaderData,
|
|
4
|
+
makeTypedUsePatternLoaderData,
|
|
5
|
+
makeTypedUseRouterData,
|
|
6
|
+
type VormaRoute,
|
|
7
|
+
type VormaRouteProps,
|
|
8
|
+
} from "./src/helpers.ts";
|
|
9
|
+
export { VormaLink, makeTypedLink } from "./src/link.tsx";
|
|
10
|
+
export { VormaRootOutlet, location } from "./src/preact.tsx";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "preact/hooks";
|
|
4
|
+
import type { JSX } from "preact/jsx-runtime";
|
|
5
|
+
import {
|
|
6
|
+
__registerClientLoaderPattern,
|
|
7
|
+
__runClientLoadersAfterHMRUpdate,
|
|
8
|
+
__vormaClientGlobal,
|
|
9
|
+
type ClientLoaderAwaitedServerData,
|
|
10
|
+
type ParamsForPattern,
|
|
11
|
+
type UseRouterDataFunction,
|
|
12
|
+
type VormaAppBase,
|
|
13
|
+
type VormaLoaderOutput,
|
|
14
|
+
type VormaLoaderPattern,
|
|
15
|
+
type VormaRouteGeneric,
|
|
16
|
+
type VormaRoutePropsGeneric,
|
|
17
|
+
} from "vorma/client";
|
|
18
|
+
import { clientLoadersData, loadersData, routerData } from "./preact.tsx";
|
|
19
|
+
|
|
20
|
+
export type VormaRouteProps<
|
|
21
|
+
App extends VormaAppBase = any,
|
|
22
|
+
Pattern extends VormaLoaderPattern<App> = string,
|
|
23
|
+
> = VormaRoutePropsGeneric<JSX.Element, App, Pattern>;
|
|
24
|
+
|
|
25
|
+
export type VormaRoute<
|
|
26
|
+
App extends VormaAppBase = any,
|
|
27
|
+
Pattern extends VormaLoaderPattern<App> = string,
|
|
28
|
+
> = VormaRouteGeneric<JSX.Element, App, Pattern>;
|
|
29
|
+
|
|
30
|
+
export function makeTypedUseRouterData<App extends VormaAppBase>() {
|
|
31
|
+
return (() => {
|
|
32
|
+
return routerData.value;
|
|
33
|
+
}) as UseRouterDataFunction<App, false>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function makeTypedUseLoaderData<App extends VormaAppBase>() {
|
|
37
|
+
return function useLoaderData<Pattern extends VormaLoaderPattern<App>>(
|
|
38
|
+
props: VormaRouteProps<App, Pattern>,
|
|
39
|
+
): VormaLoaderOutput<App, Pattern> {
|
|
40
|
+
return loadersData.value[props.idx];
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function makeTypedUsePatternLoaderData<App extends VormaAppBase>() {
|
|
45
|
+
return function usePatternLoaderData<
|
|
46
|
+
Pattern extends VormaLoaderPattern<App>,
|
|
47
|
+
>(pattern: Pattern): VormaLoaderOutput<App, Pattern> | undefined {
|
|
48
|
+
const idx = useMemo(() => {
|
|
49
|
+
return routerData.value.matchedPatterns.findIndex(
|
|
50
|
+
(p) => p === pattern,
|
|
51
|
+
);
|
|
52
|
+
}, [pattern]);
|
|
53
|
+
|
|
54
|
+
if (idx === -1) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return loadersData.value[idx];
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function makeTypedAddClientLoader<App extends VormaAppBase>() {
|
|
62
|
+
const m = __vormaClientGlobal.get("patternToWaitFnMap");
|
|
63
|
+
return function addClientLoader<
|
|
64
|
+
Pattern extends VormaLoaderPattern<App>,
|
|
65
|
+
LoaderData extends VormaLoaderOutput<App, Pattern>,
|
|
66
|
+
T = any,
|
|
67
|
+
>(props: {
|
|
68
|
+
pattern: Pattern;
|
|
69
|
+
clientLoader: (props: {
|
|
70
|
+
params: Record<ParamsForPattern<App, Pattern>, string>;
|
|
71
|
+
splatValues: string[];
|
|
72
|
+
serverDataPromise: Promise<
|
|
73
|
+
ClientLoaderAwaitedServerData<App["rootData"], LoaderData>
|
|
74
|
+
>;
|
|
75
|
+
signal: AbortSignal;
|
|
76
|
+
}) => Promise<T>;
|
|
77
|
+
reRunOnModuleChange?: ImportMeta;
|
|
78
|
+
}) {
|
|
79
|
+
const p = props.pattern;
|
|
80
|
+
const fn = props.clientLoader;
|
|
81
|
+
|
|
82
|
+
__registerClientLoaderPattern(p as string).catch((error) => {
|
|
83
|
+
console.error("Failed to register client loader pattern:", error);
|
|
84
|
+
});
|
|
85
|
+
(m as any)[p] = fn;
|
|
86
|
+
|
|
87
|
+
if (import.meta.env.DEV && props.reRunOnModuleChange) {
|
|
88
|
+
__runClientLoadersAfterHMRUpdate(props.reRunOnModuleChange, p);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
type Res = Awaited<ReturnType<typeof fn>>;
|
|
92
|
+
|
|
93
|
+
const useClientLoaderData = (
|
|
94
|
+
props?: VormaRouteProps<App, Pattern>,
|
|
95
|
+
): Res | undefined => {
|
|
96
|
+
const idx = useMemo(() => {
|
|
97
|
+
if (props) {
|
|
98
|
+
return props.idx;
|
|
99
|
+
}
|
|
100
|
+
const matched = routerData.value.matchedPatterns;
|
|
101
|
+
return matched.findIndex((pattern) => pattern === p);
|
|
102
|
+
}, [props]);
|
|
103
|
+
|
|
104
|
+
if (idx === -1) return undefined;
|
|
105
|
+
return clientLoadersData.value[idx];
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
return useClientLoaderData as {
|
|
109
|
+
(props: VormaRouteProps<App, Pattern>): Res;
|
|
110
|
+
(): Res | undefined;
|
|
111
|
+
};
|
|
112
|
+
};
|
|
113
|
+
}
|