@bleedingdev/modern-js-renderer-solid 0.0.0-stage → 3.9.3-ultramodern.2
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/dist/esm/actions.js +283 -0
- package/dist/esm/application-router.js +25 -0
- package/dist/esm/client.js +49 -0
- package/dist/esm/entry-application.js +60 -0
- package/dist/esm/entry-client.js +23 -0
- package/dist/esm/federation-context.js +25 -0
- package/dist/esm/federation-ssr.js +84 -0
- package/dist/esm/federation.js +83 -0
- package/dist/esm/i18n/I18nProvider.js +33 -0
- package/dist/esm/i18n/LocalizedLink.js +74 -0
- package/dist/esm/i18n/context.js +3 -0
- package/dist/esm/i18n/index.js +8 -0
- package/dist/esm/i18n/languageSync.js +50 -0
- package/dist/esm/i18n/types.js +0 -0
- package/dist/esm/i18n/useI18n.js +74 -0
- package/dist/esm/index.js +58 -0
- package/dist/esm/manifest.js +150 -0
- package/dist/esm/route-completion.js +150 -0
- package/dist/esm/route-data-error.js +108 -0
- package/dist/esm/router-binding/Asset.js +201 -0
- package/dist/esm/router-binding/CatchBoundary.js +94 -0
- package/dist/esm/router-binding/ClientOnly.js +26 -0
- package/dist/esm/router-binding/HeadContent.js +8 -0
- package/dist/esm/router-binding/LICENSE +21 -0
- package/dist/esm/router-binding/Match.js +319 -0
- package/dist/esm/router-binding/Matches.js +117 -0
- package/dist/esm/router-binding/PROVENANCE.json +94 -0
- package/dist/esm/router-binding/RouterProvider.js +51 -0
- package/dist/esm/router-binding/SafeFragment.js +5 -0
- package/dist/esm/router-binding/ScriptOnce.js +15 -0
- package/dist/esm/router-binding/Scripts.js +30 -0
- package/dist/esm/router-binding/ScrollRestoration.js +16 -0
- package/dist/esm/router-binding/Transitioner.js +103 -0
- package/dist/esm/router-binding/awaited.js +48 -0
- package/dist/esm/router-binding/fileRoute.js +83 -0
- package/dist/esm/router-binding/flightData.js +23 -0
- package/dist/esm/router-binding/headContentUtils.js +162 -0
- package/dist/esm/router-binding/history.js +0 -0
- package/dist/esm/router-binding/index.js +35 -0
- package/dist/esm/router-binding/lazyRouteComponent.js +30 -0
- package/dist/esm/router-binding/link.js +389 -0
- package/dist/esm/router-binding/matchContext.js +7 -0
- package/dist/esm/router-binding/nonRouteComponentContext.js +13 -0
- package/dist/esm/router-binding/not-found.js +35 -0
- package/dist/esm/router-binding/publicMatchData.js +447 -0
- package/dist/esm/router-binding/registryTransfer.js +210 -0
- package/dist/esm/router-binding/renderRouteNotFound.js +23 -0
- package/dist/esm/router-binding/route.js +143 -0
- package/dist/esm/router-binding/router.js +13 -0
- package/dist/esm/router-binding/routerContext.js +3 -0
- package/dist/esm/router-binding/routerStores.js +50 -0
- package/dist/esm/router-binding/scroll-restoration.js +13 -0
- package/dist/esm/router-binding/typePrimitives.js +0 -0
- package/dist/esm/router-binding/useBlocker.js +152 -0
- package/dist/esm/router-binding/useCanGoBack.js +7 -0
- package/dist/esm/router-binding/useLoaderData.js +9 -0
- package/dist/esm/router-binding/useLoaderDeps.js +8 -0
- package/dist/esm/router-binding/useLocation.js +14 -0
- package/dist/esm/router-binding/useMatch.js +28 -0
- package/dist/esm/router-binding/useNavigate.js +19 -0
- package/dist/esm/router-binding/useParams.js +13 -0
- package/dist/esm/router-binding/useRouteContext.js +8 -0
- package/dist/esm/router-binding/useRouter.js +10 -0
- package/dist/esm/router-binding/useRouterState.js +19 -0
- package/dist/esm/router-binding/useSearch.js +13 -0
- package/dist/esm/router-binding/utils.js +23 -0
- package/dist/esm/router.js +187 -0
- package/dist/esm-node/actions.js +263 -0
- package/dist/esm-node/application-router.js +25 -0
- package/dist/esm-node/client.js +49 -0
- package/dist/esm-node/entry-application.js +110 -0
- package/dist/esm-node/entry-client.js +23 -0
- package/dist/esm-node/entry-server.js +47 -0
- package/dist/esm-node/federation-context.js +25 -0
- package/dist/esm-node/federation-ssr.js +84 -0
- package/dist/esm-node/federation.js +83 -0
- package/dist/esm-node/i18n/I18nProvider.js +42 -0
- package/dist/esm-node/i18n/LocalizedLink.js +142 -0
- package/dist/esm-node/i18n/context.js +3 -0
- package/dist/esm-node/i18n/index.js +8 -0
- package/dist/esm-node/i18n/languageSync.js +50 -0
- package/dist/esm-node/i18n/types.js +1 -0
- package/dist/esm-node/i18n/useI18n.js +74 -0
- package/dist/esm-node/index.js +58 -0
- package/dist/esm-node/manifest.js +150 -0
- package/dist/esm-node/native-promise-serialization.js +113 -0
- package/dist/esm-node/plugin/compiler.js +209 -0
- package/dist/esm-node/plugin/create.js +235 -0
- package/dist/esm-node/plugin/index.js +73 -0
- package/dist/esm-node/plugin/profile.js +52 -0
- package/dist/esm-node/route-completion.js +160 -0
- package/dist/esm-node/route-data-error.js +108 -0
- package/dist/esm-node/router-binding/Asset.js +171 -0
- package/dist/esm-node/router-binding/CatchBoundary.js +136 -0
- package/dist/esm-node/router-binding/ClientOnly.js +46 -0
- package/dist/esm-node/router-binding/HeadContent.js +8 -0
- package/dist/esm-node/router-binding/LICENSE +21 -0
- package/dist/esm-node/router-binding/Match.js +660 -0
- package/dist/esm-node/router-binding/Matches.js +161 -0
- package/dist/esm-node/router-binding/PROVENANCE.json +94 -0
- package/dist/esm-node/router-binding/RouterProvider.js +87 -0
- package/dist/esm-node/router-binding/SafeFragment.js +5 -0
- package/dist/esm-node/router-binding/ScriptOnce.js +16 -0
- package/dist/esm-node/router-binding/Scripts.js +49 -0
- package/dist/esm-node/router-binding/ScrollRestoration.js +16 -0
- package/dist/esm-node/router-binding/Transitioner.js +103 -0
- package/dist/esm-node/router-binding/awaited.js +75 -0
- package/dist/esm-node/router-binding/fileRoute.js +83 -0
- package/dist/esm-node/router-binding/flightData.js +23 -0
- package/dist/esm-node/router-binding/headContentUtils.js +162 -0
- package/dist/esm-node/router-binding/history.js +1 -0
- package/dist/esm-node/router-binding/index.js +35 -0
- package/dist/esm-node/router-binding/lazyRouteComponent.js +30 -0
- package/dist/esm-node/router-binding/link.js +399 -0
- package/dist/esm-node/router-binding/matchContext.js +7 -0
- package/dist/esm-node/router-binding/nonRouteComponentContext.js +22 -0
- package/dist/esm-node/router-binding/not-found.js +49 -0
- package/dist/esm-node/router-binding/publicMatchData.js +447 -0
- package/dist/esm-node/router-binding/registryTransfer.js +210 -0
- package/dist/esm-node/router-binding/renderRouteNotFound.js +22 -0
- package/dist/esm-node/router-binding/route.js +162 -0
- package/dist/esm-node/router-binding/router.js +13 -0
- package/dist/esm-node/router-binding/routerContext.js +3 -0
- package/dist/esm-node/router-binding/routerStores.js +50 -0
- package/dist/esm-node/router-binding/scroll-restoration.js +12 -0
- package/dist/esm-node/router-binding/typePrimitives.js +1 -0
- package/dist/esm-node/router-binding/useBlocker.js +152 -0
- package/dist/esm-node/router-binding/useCanGoBack.js +7 -0
- package/dist/esm-node/router-binding/useLoaderData.js +9 -0
- package/dist/esm-node/router-binding/useLoaderDeps.js +8 -0
- package/dist/esm-node/router-binding/useLocation.js +14 -0
- package/dist/esm-node/router-binding/useMatch.js +28 -0
- package/dist/esm-node/router-binding/useNavigate.js +19 -0
- package/dist/esm-node/router-binding/useParams.js +13 -0
- package/dist/esm-node/router-binding/useRouteContext.js +8 -0
- package/dist/esm-node/router-binding/useRouter.js +10 -0
- package/dist/esm-node/router-binding/useRouterState.js +19 -0
- package/dist/esm-node/router-binding/useSearch.js +13 -0
- package/dist/esm-node/router-binding/utils.js +23 -0
- package/dist/esm-node/router.js +187 -0
- package/dist/esm-node/server.js +396 -0
- package/dist/types/actions.d.ts +45 -0
- package/dist/types/application-router.d.ts +5 -0
- package/dist/types/client.d.ts +23 -0
- package/dist/types/entry-application.d.ts +10 -0
- package/dist/types/entry-client.d.ts +5 -0
- package/dist/types/entry-server.d.ts +5 -0
- package/dist/types/federation-context.d.ts +16 -0
- package/dist/types/federation-ssr.d.ts +21 -0
- package/dist/types/federation.d.ts +30 -0
- package/dist/types/i18n/I18nProvider.d.ts +21 -0
- package/dist/types/i18n/LocalizedLink.d.ts +43 -0
- package/dist/types/i18n/context.d.ts +11 -0
- package/dist/types/i18n/index.d.ts +9 -0
- package/dist/types/i18n/languageSync.d.ts +31 -0
- package/dist/types/i18n/types.d.ts +33 -0
- package/dist/types/i18n/useI18n.d.ts +24 -0
- package/dist/types/index.d.ts +41 -0
- package/dist/types/manifest.d.ts +55 -0
- package/dist/types/native-promise-serialization.d.ts +9 -0
- package/dist/types/plugin/compiler.d.ts +6 -0
- package/dist/types/plugin/create.d.ts +21 -0
- package/dist/types/plugin/index.d.ts +3 -0
- package/dist/types/plugin/lazy-modules.d.cts +15 -0
- package/dist/types/plugin/preserve-import-loader.d.cts +3 -0
- package/dist/types/plugin/profile.d.ts +2 -0
- package/dist/types/plugin/solid-loader.d.cts +2 -0
- package/dist/types/plugin/svg-component-template.d.cts +6 -0
- package/dist/types/route-completion.d.ts +21 -0
- package/dist/types/route-data-error.d.ts +17 -0
- package/dist/types/router-binding/Asset.d.ts +3 -0
- package/dist/types/router-binding/CatchBoundary.d.ts +13 -0
- package/dist/types/router-binding/ClientOnly.d.ts +31 -0
- package/dist/types/router-binding/HeadContent.d.ts +13 -0
- package/dist/types/router-binding/Match.d.ts +6 -0
- package/dist/types/router-binding/Matches.d.ts +26 -0
- package/dist/types/router-binding/RouterProvider.d.ts +10 -0
- package/dist/types/router-binding/SafeFragment.d.ts +2 -0
- package/dist/types/router-binding/ScriptOnce.d.ts +6 -0
- package/dist/types/router-binding/Scripts.d.ts +2 -0
- package/dist/types/router-binding/ScrollRestoration.d.ts +14 -0
- package/dist/types/router-binding/Transitioner.d.ts +2 -0
- package/dist/types/router-binding/awaited.d.ts +11 -0
- package/dist/types/router-binding/fileRoute.d.ts +54 -0
- package/dist/types/router-binding/flightData.d.ts +38 -0
- package/dist/types/router-binding/headContentUtils.d.ts +15 -0
- package/dist/types/router-binding/history.d.ts +8 -0
- package/dist/types/router-binding/index.d.ts +45 -0
- package/dist/types/router-binding/lazyRouteComponent.d.ts +2 -0
- package/dist/types/router-binding/link.d.ts +43 -0
- package/dist/types/router-binding/matchContext.d.ts +7 -0
- package/dist/types/router-binding/nonRouteComponentContext.d.ts +5 -0
- package/dist/types/router-binding/not-found.d.ts +11 -0
- package/dist/types/router-binding/publicMatchData.d.ts +19 -0
- package/dist/types/router-binding/registryTransfer.d.ts +47 -0
- package/dist/types/router-binding/renderRouteNotFound.d.ts +11 -0
- package/dist/types/router-binding/route.d.ts +105 -0
- package/dist/types/router-binding/router.d.ts +70 -0
- package/dist/types/router-binding/routerContext.d.ts +3 -0
- package/dist/types/router-binding/routerStores.d.ts +2 -0
- package/dist/types/router-binding/scroll-restoration.d.ts +2 -0
- package/dist/types/router-binding/typePrimitives.d.ts +10 -0
- package/dist/types/router-binding/useBlocker.d.ts +70 -0
- package/dist/types/router-binding/useCanGoBack.d.ts +2 -0
- package/dist/types/router-binding/useLoaderData.d.ts +8 -0
- package/dist/types/router-binding/useLoaderDeps.d.ts +8 -0
- package/dist/types/router-binding/useLocation.d.ts +7 -0
- package/dist/types/router-binding/useMatch.d.ts +10 -0
- package/dist/types/router-binding/useNavigate.d.ts +5 -0
- package/dist/types/router-binding/useParams.d.ts +9 -0
- package/dist/types/router-binding/useRouteContext.d.ts +4 -0
- package/dist/types/router-binding/useRouter.d.ts +4 -0
- package/dist/types/router-binding/useRouterState.d.ts +8 -0
- package/dist/types/router-binding/useSearch.d.ts +9 -0
- package/dist/types/router-binding/utils.d.ts +25 -0
- package/dist/types/router.d.ts +31 -0
- package/dist/types/server.d.ts +47 -0
- package/package.json +123 -4
- package/src/actions.tsx +437 -0
- package/src/application-router.tsx +41 -0
- package/src/client.ts +106 -0
- package/src/entry-application.tsx +73 -0
- package/src/entry-client.tsx +48 -0
- package/src/entry-server.tsx +85 -0
- package/src/federation-context.ts +47 -0
- package/src/federation-ssr.ts +117 -0
- package/src/federation.tsx +193 -0
- package/src/i18n/I18nProvider.tsx +54 -0
- package/src/i18n/LocalizedLink.tsx +122 -0
- package/src/i18n/context.ts +13 -0
- package/src/i18n/index.ts +35 -0
- package/src/i18n/languageSync.ts +113 -0
- package/src/i18n/types.ts +35 -0
- package/src/i18n/useI18n.ts +121 -0
- package/src/index.ts +41 -0
- package/src/manifest.ts +337 -0
- package/src/native-promise-serialization.ts +167 -0
- package/src/plugin/compiler.ts +320 -0
- package/src/plugin/create.ts +270 -0
- package/src/plugin/index.ts +72 -0
- package/src/plugin/lazy-modules.cjs +146 -0
- package/src/plugin/preserve-import-loader.cjs +46 -0
- package/src/plugin/profile.ts +42 -0
- package/src/plugin/solid-loader.cjs +83 -0
- package/src/plugin/svg-component-template.cjs +19 -0
- package/src/route-completion.tsx +222 -0
- package/src/route-data-error.ts +175 -0
- package/src/router-binding/Asset.tsx +283 -0
- package/src/router-binding/CatchBoundary.tsx +130 -0
- package/src/router-binding/ClientOnly.tsx +76 -0
- package/src/router-binding/HeadContent.tsx +23 -0
- package/src/router-binding/LICENSE +21 -0
- package/src/router-binding/Match.tsx +397 -0
- package/src/router-binding/Matches.tsx +242 -0
- package/src/router-binding/PROVENANCE.json +94 -0
- package/src/router-binding/RouterProvider.tsx +129 -0
- package/src/router-binding/SafeFragment.tsx +5 -0
- package/src/router-binding/ScriptOnce.tsx +23 -0
- package/src/router-binding/Scripts.tsx +44 -0
- package/src/router-binding/ScrollRestoration.tsx +49 -0
- package/src/router-binding/Transitioner.tsx +172 -0
- package/src/router-binding/awaited.tsx +71 -0
- package/src/router-binding/fileRoute.ts +268 -0
- package/src/router-binding/flightData.ts +90 -0
- package/src/router-binding/headContentUtils.tsx +290 -0
- package/src/router-binding/history.ts +9 -0
- package/src/router-binding/index.tsx +318 -0
- package/src/router-binding/lazyRouteComponent.tsx +70 -0
- package/src/router-binding/link.tsx +865 -0
- package/src/router-binding/matchContext.tsx +15 -0
- package/src/router-binding/nonRouteComponentContext.tsx +23 -0
- package/src/router-binding/not-found.tsx +65 -0
- package/src/router-binding/publicMatchData.ts +674 -0
- package/src/router-binding/registryTransfer.ts +383 -0
- package/src/router-binding/renderRouteNotFound.tsx +53 -0
- package/src/router-binding/route.tsx +665 -0
- package/src/router-binding/router.ts +121 -0
- package/src/router-binding/routerContext.tsx +6 -0
- package/src/router-binding/routerStores.ts +85 -0
- package/src/router-binding/scroll-restoration.tsx +15 -0
- package/src/router-binding/typePrimitives.ts +74 -0
- package/src/router-binding/useBlocker.tsx +359 -0
- package/src/router-binding/useCanGoBack.ts +9 -0
- package/src/router-binding/useLoaderData.tsx +50 -0
- package/src/router-binding/useLoaderDeps.tsx +46 -0
- package/src/router-binding/useLocation.tsx +43 -0
- package/src/router-binding/useMatch.tsx +111 -0
- package/src/router-binding/useNavigate.tsx +43 -0
- package/src/router-binding/useParams.tsx +72 -0
- package/src/router-binding/useRouteContext.ts +30 -0
- package/src/router-binding/useRouter.tsx +17 -0
- package/src/router-binding/useRouterState.tsx +50 -0
- package/src/router-binding/useSearch.tsx +72 -0
- package/src/router-binding/utils.ts +59 -0
- package/src/router.ts +376 -0
- package/src/server.ts +645 -0
- package/README.md +0 -3
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { claimElement, getNextElement, getRequestEvent, runHydrationEvents, spread, template } from "@solidjs/web";
|
|
2
|
+
import { createDataClient } from "@modern-js/renderer-core/data";
|
|
3
|
+
import { assertRendererIdentity, identityCacheKey } from "@modern-js/renderer-core/identity";
|
|
4
|
+
import { createSignal, getOwner, omit, onCleanup, untrack } from "solid-js";
|
|
5
|
+
import { redirect, useMatch, useRouter } from "./router-binding/index.js";
|
|
6
|
+
import { preparePublicLoaderData, preparePublicMatchError } from "./router-binding/publicMatchData.js";
|
|
7
|
+
var _tmpl$ = /* @__PURE__ */ template("<form>");
|
|
8
|
+
class RouteActionError extends Error {
|
|
9
|
+
constructor(routeId, outcome){
|
|
10
|
+
super("error" === outcome.kind ? outcome.error.message : "Action route not found");
|
|
11
|
+
this.name = "error" === outcome.kind ? outcome.error.name : "RouteNotFound";
|
|
12
|
+
this.routeId = routeId;
|
|
13
|
+
this.status = outcome.status;
|
|
14
|
+
this.data = "error" === outcome.kind ? outcome.data : outcome.value;
|
|
15
|
+
this.outcome = outcome;
|
|
16
|
+
Reflect.deleteProperty(this, "stack");
|
|
17
|
+
const stack = "error" === outcome.kind ? Object.getOwnPropertyDescriptor(outcome.error, "stack")?.value : void 0;
|
|
18
|
+
if ("string" == typeof stack) this.stack = stack;
|
|
19
|
+
Object.freeze(this);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function actionFailure(cause, owner, privateContexts = []) {
|
|
23
|
+
let projection;
|
|
24
|
+
try {
|
|
25
|
+
projection = preparePublicMatchError(cause instanceof Error ? cause : new Error("The Solid route action failed", {
|
|
26
|
+
cause
|
|
27
|
+
}), owner, privateContexts);
|
|
28
|
+
} catch {
|
|
29
|
+
projection = Object.freeze({
|
|
30
|
+
name: "DataProtocolError",
|
|
31
|
+
message: "Invalid public Solid action error"
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const nested = "error" in projection ? projection.error : void 0;
|
|
35
|
+
const diagnostic = nested && "object" == typeof nested ? nested : projection;
|
|
36
|
+
const failure = new Error("string" == typeof diagnostic.message && "Unexpected Server Error" !== diagnostic.message ? diagnostic.message : "The Solid route action failed", Object.hasOwn(diagnostic, "cause") ? {
|
|
37
|
+
cause: diagnostic.cause
|
|
38
|
+
} : void 0);
|
|
39
|
+
failure.name = "string" == typeof diagnostic.name ? diagnostic.name : "Error";
|
|
40
|
+
Reflect.deleteProperty(failure, "stack");
|
|
41
|
+
if ("string" == typeof diagnostic.stack) failure.stack = diagnostic.stack;
|
|
42
|
+
return Object.freeze(failure);
|
|
43
|
+
}
|
|
44
|
+
function actionOutcome(result, owner, privateContexts) {
|
|
45
|
+
if ("success" !== result.kind) return preparePublicLoaderData(result, owner, privateContexts);
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
kind: "success",
|
|
48
|
+
value: preparePublicLoaderData(result.value, owner, privateContexts),
|
|
49
|
+
status: result.status
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function routerIdentity(router) {
|
|
53
|
+
const context = router.options.context;
|
|
54
|
+
if (context?.ultramodern === void 0) return;
|
|
55
|
+
const identity = context.ultramodern?.rendererIdentity;
|
|
56
|
+
if (!identity) throw new Error("Solid router context requires its renderer identity");
|
|
57
|
+
identityCacheKey(identity);
|
|
58
|
+
return identity;
|
|
59
|
+
}
|
|
60
|
+
function createRouteAction(options) {
|
|
61
|
+
const { router, routeId } = options;
|
|
62
|
+
if (!routeId) throw new Error("A Solid action requires its filesystem route ID");
|
|
63
|
+
identityCacheKey(options.rendererIdentity);
|
|
64
|
+
if ("solid" !== options.rendererIdentity.renderer) throw new Error("A Solid action requires the Solid renderer identity");
|
|
65
|
+
const configuredIdentity = routerIdentity(router);
|
|
66
|
+
if (configuredIdentity) assertRendererIdentity(options.rendererIdentity, configuredIdentity);
|
|
67
|
+
const identity = Object.freeze({
|
|
68
|
+
...options.rendererIdentity
|
|
69
|
+
});
|
|
70
|
+
const client = createDataClient(routeId, identity, {
|
|
71
|
+
fetch: options.fetch
|
|
72
|
+
});
|
|
73
|
+
const requestURL = getRequestEvent()?.request.url;
|
|
74
|
+
const url = ()=>{
|
|
75
|
+
const base = "u" < typeof window ? requestURL : window.location.href;
|
|
76
|
+
const location = options.url ?? router.state.location.publicHref;
|
|
77
|
+
if (!base && !URL.canParse(String(location))) throw new Error("A server Solid action requires its native request URL");
|
|
78
|
+
return new URL(location, base).href;
|
|
79
|
+
};
|
|
80
|
+
const [pending, setPending] = createSignal(false);
|
|
81
|
+
const [outcome, setOutcome] = createSignal();
|
|
82
|
+
const [error, setError] = createSignal();
|
|
83
|
+
let active;
|
|
84
|
+
let disposed = false;
|
|
85
|
+
function cancel() {
|
|
86
|
+
const current = active;
|
|
87
|
+
if (!current) return;
|
|
88
|
+
active = void 0;
|
|
89
|
+
current.abort(new DOMException("The action was cancelled", "AbortError"));
|
|
90
|
+
setPending(false);
|
|
91
|
+
}
|
|
92
|
+
function dispose() {
|
|
93
|
+
if (disposed) return;
|
|
94
|
+
disposed = true;
|
|
95
|
+
cancel();
|
|
96
|
+
}
|
|
97
|
+
function submit(request) {
|
|
98
|
+
if (disposed) throw new Error("The Solid action owner has been disposed");
|
|
99
|
+
if ("GET" === request.method || "HEAD" === request.method) throw new Error("A Solid action requires a mutation Request");
|
|
100
|
+
cancel();
|
|
101
|
+
const controller = new AbortController();
|
|
102
|
+
active = controller;
|
|
103
|
+
const signal = controller.signal;
|
|
104
|
+
const abortRequest = ()=>controller.abort(request.signal.reason);
|
|
105
|
+
if (request.signal.aborted) abortRequest();
|
|
106
|
+
else request.signal.addEventListener("abort", abortRequest, {
|
|
107
|
+
once: true
|
|
108
|
+
});
|
|
109
|
+
const current = ()=>active === controller && !signal.aborted && !disposed;
|
|
110
|
+
const privateContexts = [
|
|
111
|
+
router.options.context,
|
|
112
|
+
request
|
|
113
|
+
];
|
|
114
|
+
const owner = {
|
|
115
|
+
signal,
|
|
116
|
+
fail (failure) {
|
|
117
|
+
if (!current()) return;
|
|
118
|
+
setError(actionFailure(failure, owner, privateContexts));
|
|
119
|
+
controller.abort(failure);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
setOutcome(void 0);
|
|
123
|
+
setError(void 0);
|
|
124
|
+
setPending(true);
|
|
125
|
+
const cancelled = Symbol("cancelled action");
|
|
126
|
+
let resolveCancellation;
|
|
127
|
+
const cancellation = new Promise((resolve)=>{
|
|
128
|
+
resolveCancellation = resolve;
|
|
129
|
+
});
|
|
130
|
+
const abort = ()=>{
|
|
131
|
+
if (active === controller) {
|
|
132
|
+
active = void 0;
|
|
133
|
+
setPending(false);
|
|
134
|
+
}
|
|
135
|
+
resolveCancellation(cancelled);
|
|
136
|
+
};
|
|
137
|
+
if (signal.aborted) abort();
|
|
138
|
+
else signal.addEventListener("abort", abort, {
|
|
139
|
+
once: true
|
|
140
|
+
});
|
|
141
|
+
return (async ()=>{
|
|
142
|
+
try {
|
|
143
|
+
if (!current()) return;
|
|
144
|
+
const result = await Promise.race([
|
|
145
|
+
client.action({
|
|
146
|
+
request: new Request(request, {
|
|
147
|
+
signal
|
|
148
|
+
})
|
|
149
|
+
}),
|
|
150
|
+
cancellation
|
|
151
|
+
]);
|
|
152
|
+
if (result === cancelled || !current()) return;
|
|
153
|
+
const publicResult = actionOutcome(result, owner, privateContexts);
|
|
154
|
+
setOutcome(publicResult);
|
|
155
|
+
if (await Promise.race([
|
|
156
|
+
Promise.resolve(result.completion),
|
|
157
|
+
cancellation
|
|
158
|
+
]) === cancelled || !current()) return;
|
|
159
|
+
if ("error" === publicResult.kind || "not-found" === publicResult.kind) setError(new RouteActionError(routeId, publicResult));
|
|
160
|
+
else if ("redirect" === result.kind) {
|
|
161
|
+
if (307 === result.status || 308 === result.status || (301 === result.status || 302 === result.status) && "POST" !== request.method) throw new Error(`A native action redirect must not preserve the method (HTTP ${result.status} after ${request.method}); redirect with 303 to navigate after the mutation`);
|
|
162
|
+
const resolved = router.resolveRedirect(redirect({
|
|
163
|
+
href: new URL(result.location, request.url).href,
|
|
164
|
+
statusCode: result.status
|
|
165
|
+
}));
|
|
166
|
+
const navigation = router.navigate({
|
|
167
|
+
...resolved.options,
|
|
168
|
+
replace: true
|
|
169
|
+
});
|
|
170
|
+
const refresh = resolved.options.reloadDocument ? Promise.resolve() : router.invalidate({
|
|
171
|
+
sync: true
|
|
172
|
+
});
|
|
173
|
+
await Promise.race([
|
|
174
|
+
Promise.all([
|
|
175
|
+
navigation,
|
|
176
|
+
refresh
|
|
177
|
+
]),
|
|
178
|
+
cancellation
|
|
179
|
+
]);
|
|
180
|
+
} else if (result.status < 400) await Promise.race([
|
|
181
|
+
router.invalidate({
|
|
182
|
+
sync: true
|
|
183
|
+
}),
|
|
184
|
+
cancellation
|
|
185
|
+
]);
|
|
186
|
+
return current() ? publicResult : void 0;
|
|
187
|
+
} catch (failure) {
|
|
188
|
+
owner.fail(failure);
|
|
189
|
+
return;
|
|
190
|
+
} finally{
|
|
191
|
+
request.signal.removeEventListener("abort", abortRequest);
|
|
192
|
+
signal.removeEventListener("abort", abort);
|
|
193
|
+
if (active === controller) {
|
|
194
|
+
active = void 0;
|
|
195
|
+
setPending(false);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
})();
|
|
199
|
+
}
|
|
200
|
+
async function submitForm(form, submitter) {
|
|
201
|
+
try {
|
|
202
|
+
const button = submitter instanceof HTMLButtonElement || submitter instanceof HTMLInputElement ? submitter : void 0;
|
|
203
|
+
const method = button?.hasAttribute("formmethod") ? button.formMethod : form.method;
|
|
204
|
+
if ("post" !== method.toLowerCase()) throw new Error("A Solid action form requires method=\"post\"");
|
|
205
|
+
const target = button?.hasAttribute("formtarget") ? button.formTarget : form.target;
|
|
206
|
+
if (target && "_self" !== target.toLowerCase()) throw new Error("A Solid action form requires the current browsing context");
|
|
207
|
+
const destination = button?.hasAttribute("formaction") ? button.formAction : form.action;
|
|
208
|
+
const formData = new FormData(form, button);
|
|
209
|
+
const encoding = button?.hasAttribute("formenctype") ? button.formEnctype : form.enctype;
|
|
210
|
+
let body;
|
|
211
|
+
if ("multipart/form-data" === encoding) body = formData;
|
|
212
|
+
else if ("application/x-www-form-urlencoded" === encoding) {
|
|
213
|
+
const encoded = new URLSearchParams();
|
|
214
|
+
for (const [name, value] of formData)encoded.append(name, "string" == typeof value ? value : value.name);
|
|
215
|
+
body = encoded;
|
|
216
|
+
} else throw new Error(`Unsupported Solid action form encoding: ${encoding}`);
|
|
217
|
+
return await submit(new Request(new URL(destination || url(), url()), {
|
|
218
|
+
method: "POST",
|
|
219
|
+
body,
|
|
220
|
+
credentials: "same-origin"
|
|
221
|
+
}));
|
|
222
|
+
} catch (failure) {
|
|
223
|
+
if (!disposed) setError(actionFailure(failure, void 0, [
|
|
224
|
+
router.options.context
|
|
225
|
+
]));
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (getOwner()) onCleanup(dispose);
|
|
230
|
+
return Object.freeze({
|
|
231
|
+
routeId,
|
|
232
|
+
pending,
|
|
233
|
+
outcome,
|
|
234
|
+
error,
|
|
235
|
+
url,
|
|
236
|
+
submit,
|
|
237
|
+
submitForm,
|
|
238
|
+
cancel,
|
|
239
|
+
dispose
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function useRouteAction() {
|
|
243
|
+
const router = useRouter();
|
|
244
|
+
if (!router) throw new Error("useRouteAction requires a native Solid router");
|
|
245
|
+
const identity = routerIdentity(router);
|
|
246
|
+
if (!identity) throw new Error("useRouteAction requires the application renderer identity");
|
|
247
|
+
const match = useMatch({
|
|
248
|
+
strict: false
|
|
249
|
+
});
|
|
250
|
+
const routeMatch = untrack(match);
|
|
251
|
+
const route = router.routesById[routeMatch.routeId];
|
|
252
|
+
const routeId = route?.options.staticData?.ultramodernRouteId;
|
|
253
|
+
if (!routeId) throw new Error("useRouteAction requires a native filesystem route");
|
|
254
|
+
return createRouteAction({
|
|
255
|
+
router,
|
|
256
|
+
routeId,
|
|
257
|
+
rendererIdentity: identity
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function ActionForm(props) {
|
|
261
|
+
const submit = (event)=>{
|
|
262
|
+
event.preventDefault();
|
|
263
|
+
props.action.submitForm(event.currentTarget, event.submitter);
|
|
264
|
+
};
|
|
265
|
+
var _el$ = getNextElement(_tmpl$);
|
|
266
|
+
claimElement(_el$);
|
|
267
|
+
spread(_el$, [
|
|
268
|
+
()=>omit(props, "action"),
|
|
269
|
+
{
|
|
270
|
+
get action () {
|
|
271
|
+
return props.action.url();
|
|
272
|
+
},
|
|
273
|
+
method: "post",
|
|
274
|
+
get enctype () {
|
|
275
|
+
return props.enctype ?? "application/x-www-form-urlencoded";
|
|
276
|
+
},
|
|
277
|
+
onSubmit: submit
|
|
278
|
+
}
|
|
279
|
+
], false);
|
|
280
|
+
runHydrationEvents();
|
|
281
|
+
return _el$;
|
|
282
|
+
}
|
|
283
|
+
export { ActionForm, RouteActionError, createRouteAction, useRouteAction };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createComponent, mergeProps, useHead } from "@solidjs/web";
|
|
2
|
+
import { DataProtocolError } from "@modern-js/renderer-core/data";
|
|
3
|
+
import { ownApplicationRouteData } from "./route-completion.js";
|
|
4
|
+
import { toHeadTags, useTags } from "./router-binding/headContentUtils.js";
|
|
5
|
+
import { Matches } from "./router-binding/Matches.js";
|
|
6
|
+
import { RouterContextProvider } from "./router-binding/RouterProvider.js";
|
|
7
|
+
function ApplicationHead() {
|
|
8
|
+
const tags = useTags();
|
|
9
|
+
useHead(()=>toHeadTags(tags()));
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
function ApplicationRouter(props) {
|
|
13
|
+
if (Object.hasOwn(props, "context")) throw new DataProtocolError("Set public Solid router context in createApplicationRouter; ApplicationRouter context overrides are unsupported");
|
|
14
|
+
const { router, ...rest } = props;
|
|
15
|
+
ownApplicationRouteData(router);
|
|
16
|
+
return createComponent(RouterContextProvider, mergeProps({
|
|
17
|
+
router
|
|
18
|
+
}, rest, {
|
|
19
|
+
children: ()=>[
|
|
20
|
+
createComponent(ApplicationHead, {}),
|
|
21
|
+
createComponent(Matches, {})
|
|
22
|
+
]
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
export { ApplicationRouter };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { readDocumentBootstrap } from "@modern-js/renderer-core/document";
|
|
2
|
+
import { hydrate, render } from "@solidjs/web";
|
|
3
|
+
import { runWithOwner } from "solid-js";
|
|
4
|
+
import { createFederationScope, provideFederation } from "./federation-context.js";
|
|
5
|
+
function readSolidDocumentBootstrap(document, expectedIdentity) {
|
|
6
|
+
if ("solid" !== expectedIdentity.renderer) throw new Error("The Solid document requires a Solid renderer identity");
|
|
7
|
+
const { identity, documentId, hydrating } = readDocumentBootstrap(document, expectedIdentity);
|
|
8
|
+
return {
|
|
9
|
+
identity,
|
|
10
|
+
documentId,
|
|
11
|
+
hydrating
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const applications = new WeakSet();
|
|
15
|
+
function createApplication(view, element, options, hydrating) {
|
|
16
|
+
if (applications.has(element)) throw new Error("A Solid application already owns this mount element");
|
|
17
|
+
let nativeDispose;
|
|
18
|
+
let disposed = false;
|
|
19
|
+
applications.add(element);
|
|
20
|
+
const dispose = ()=>{
|
|
21
|
+
if (disposed) return;
|
|
22
|
+
disposed = true;
|
|
23
|
+
try {
|
|
24
|
+
nativeDispose?.();
|
|
25
|
+
} finally{
|
|
26
|
+
applications.delete(element);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
try {
|
|
30
|
+
const nativeOptions = {
|
|
31
|
+
renderId: options.renderId,
|
|
32
|
+
onError: options.onError
|
|
33
|
+
};
|
|
34
|
+
const root = provideFederation(createFederationScope(options.federation), view);
|
|
35
|
+
nativeDispose = runWithOwner(null, ()=>hydrating ? hydrate(root, element, nativeOptions) : render(root, element, void 0, nativeOptions));
|
|
36
|
+
options.hot?.dispose(dispose);
|
|
37
|
+
return dispose;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
dispose();
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function mountApplication(view, element, options = {}) {
|
|
44
|
+
return createApplication(view, element, options, false);
|
|
45
|
+
}
|
|
46
|
+
function hydrateApplication(view, element, options = {}) {
|
|
47
|
+
return createApplication(view, element, options, true);
|
|
48
|
+
}
|
|
49
|
+
export { hydrateApplication, mountApplication, readSolidDocumentBootstrap };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createComponent } from "@solidjs/web";
|
|
2
|
+
import { ApplicationRouter } from "./application-router.js";
|
|
3
|
+
import { I18nProvider } from "./i18n/I18nProvider.js";
|
|
4
|
+
import { createApplicationRouter } from "./route-completion.js";
|
|
5
|
+
import { createFileSystemRouteTree } from "./router.js";
|
|
6
|
+
import { createMemoryHistory } from "./router-binding/index.js";
|
|
7
|
+
const solidRouterFactory = {
|
|
8
|
+
routeTree: (routes, modules, options)=>createFileSystemRouteTree(routes, modules, options),
|
|
9
|
+
router: ({ location, ...options })=>createApplicationRouter({
|
|
10
|
+
...options,
|
|
11
|
+
...location ? {
|
|
12
|
+
origin: location.origin,
|
|
13
|
+
history: createMemoryHistory({
|
|
14
|
+
initialEntries: [
|
|
15
|
+
location.href
|
|
16
|
+
]
|
|
17
|
+
})
|
|
18
|
+
} : {}
|
|
19
|
+
})
|
|
20
|
+
};
|
|
21
|
+
function componentView(component, i18n) {
|
|
22
|
+
const App = component;
|
|
23
|
+
if (!i18n) return ()=>createComponent(App, {});
|
|
24
|
+
return ()=>createComponent(I18nProvider, {
|
|
25
|
+
get instance () {
|
|
26
|
+
return i18n.instance;
|
|
27
|
+
},
|
|
28
|
+
get languages () {
|
|
29
|
+
return i18n.languages;
|
|
30
|
+
},
|
|
31
|
+
get localisedUrls () {
|
|
32
|
+
return i18n.localisedUrls;
|
|
33
|
+
},
|
|
34
|
+
get children () {
|
|
35
|
+
return createComponent(App, {});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function routerView(router, i18n) {
|
|
40
|
+
if (!i18n) return ()=>createComponent(ApplicationRouter, {
|
|
41
|
+
router
|
|
42
|
+
});
|
|
43
|
+
return ()=>createComponent(I18nProvider, {
|
|
44
|
+
get instance () {
|
|
45
|
+
return i18n.instance;
|
|
46
|
+
},
|
|
47
|
+
get languages () {
|
|
48
|
+
return i18n.languages;
|
|
49
|
+
},
|
|
50
|
+
get localisedUrls () {
|
|
51
|
+
return i18n.localisedUrls;
|
|
52
|
+
},
|
|
53
|
+
get children () {
|
|
54
|
+
return createComponent(ApplicationRouter, {
|
|
55
|
+
router
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export { componentView, routerView, solidRouterFactory };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { startNativeClientEntry } from "@modern-js/renderer-core/entry-client";
|
|
2
|
+
import { createNativeRouter } from "@modern-js/renderer-core/router";
|
|
3
|
+
import { hydrateApplication, mountApplication, readSolidDocumentBootstrap } from "./client.js";
|
|
4
|
+
import { componentView, routerView, solidRouterFactory } from "./entry-application.js";
|
|
5
|
+
function startNativeClient(options) {
|
|
6
|
+
startNativeClientEntry(options, {
|
|
7
|
+
readBootstrap: readSolidDocumentBootstrap,
|
|
8
|
+
createRouter: (application, routerOptions)=>createNativeRouter(application, routerOptions, solidRouterFactory),
|
|
9
|
+
async prepareRouter (router, hydrating) {
|
|
10
|
+
if (!hydrating) await router.load();
|
|
11
|
+
},
|
|
12
|
+
async start ({ root, bootstrap, load }) {
|
|
13
|
+
const view = await load();
|
|
14
|
+
return (bootstrap?.hydrating ? hydrateApplication : mountApplication)("component" === view.kind ? componentView(view.component, view.i18n) : routerView(view.router, view.i18n), root, {
|
|
15
|
+
...bootstrap ? {
|
|
16
|
+
renderId: bootstrap.documentId
|
|
17
|
+
} : {},
|
|
18
|
+
federation: options.federation
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export { startNativeClient };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getFederationHost } from "@modern-js/renderer-core/federation";
|
|
2
|
+
import { createComponent, createContext } from "solid-js";
|
|
3
|
+
const FederationContext = createContext(Object.freeze({
|
|
4
|
+
instance: void 0
|
|
5
|
+
}));
|
|
6
|
+
function createFederationScope(binding) {
|
|
7
|
+
if (void 0 === binding) return;
|
|
8
|
+
const instance = getFederationHost(binding);
|
|
9
|
+
return void 0 === binding.hydrationModule ? {
|
|
10
|
+
instance
|
|
11
|
+
} : {
|
|
12
|
+
instance,
|
|
13
|
+
hydrationModule: binding.hydrationModule
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function provideFederation(scope, view) {
|
|
17
|
+
if (!scope) return view;
|
|
18
|
+
return ()=>createComponent(FederationContext, {
|
|
19
|
+
value: scope,
|
|
20
|
+
get children () {
|
|
21
|
+
return view();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export { FederationContext, createFederationScope, provideFederation };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { remoteBrowserAssets } from "@modern-js/renderer-core/federation";
|
|
2
|
+
const FEDERATED_ASSET_PREFIX = "ultramodern-federation:";
|
|
3
|
+
function federatedServerAssets(scope, id) {
|
|
4
|
+
const instance = scope?.instance;
|
|
5
|
+
const assets = instance && remoteBrowserAssets(instance, id);
|
|
6
|
+
if (!assets || !scope?.hydrationModule || !instance.name) return;
|
|
7
|
+
const hydration = `${scope.hydrationModule}?id=${encodeURIComponent(id)}&host=${encodeURIComponent(instance.name)}`;
|
|
8
|
+
return {
|
|
9
|
+
hydration,
|
|
10
|
+
assets
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function federatedAssetKey(id) {
|
|
14
|
+
return `${FEDERATED_ASSET_PREFIX}${id}`;
|
|
15
|
+
}
|
|
16
|
+
function joinAssetPath(base, file) {
|
|
17
|
+
if (/^(?:[a-z][a-z0-9+.-]*:)?\/\//iu.test(file)) return file;
|
|
18
|
+
let prefix = "string" == typeof base && base ? base : "/";
|
|
19
|
+
if (!prefix.endsWith("/")) prefix += "/";
|
|
20
|
+
return prefix + (file.startsWith("/") ? file.slice(1) : file);
|
|
21
|
+
}
|
|
22
|
+
function resolveStaticAssets(manifest, key) {
|
|
23
|
+
if ("_base" === key || !Object.hasOwn(manifest, key)) return null;
|
|
24
|
+
const base = manifest._base;
|
|
25
|
+
const js = [];
|
|
26
|
+
const css = [];
|
|
27
|
+
let preloads;
|
|
28
|
+
const visited = new Set();
|
|
29
|
+
const walk = (name)=>{
|
|
30
|
+
if (visited.has(name) || "_base" === name) return;
|
|
31
|
+
visited.add(name);
|
|
32
|
+
const chunk = manifest[name];
|
|
33
|
+
if (!chunk) return;
|
|
34
|
+
js.push(joinAssetPath(base, chunk.file));
|
|
35
|
+
for (const file of chunk.css ?? [])css.push(joinAssetPath(base, file));
|
|
36
|
+
for (const link of chunk.preloads ?? []){
|
|
37
|
+
const href = "string" == typeof link.href && link.href;
|
|
38
|
+
if (href || "string" == typeof link.imagesrcset) {
|
|
39
|
+
preloads ??= [];
|
|
40
|
+
if (href) preloads.push({
|
|
41
|
+
...link,
|
|
42
|
+
href: joinAssetPath(base, href)
|
|
43
|
+
});
|
|
44
|
+
else {
|
|
45
|
+
const { href: _ignored, ...rest } = link;
|
|
46
|
+
preloads.push(rest);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const dependency of chunk.imports ?? [])walk(dependency);
|
|
51
|
+
};
|
|
52
|
+
walk(key);
|
|
53
|
+
return preloads ? {
|
|
54
|
+
js,
|
|
55
|
+
css,
|
|
56
|
+
preloads
|
|
57
|
+
} : {
|
|
58
|
+
js,
|
|
59
|
+
css
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
function withFederatedAssets(manifest, scope) {
|
|
63
|
+
if (!scope?.hydrationModule || null === manifest || "object" != typeof manifest || "function" == typeof manifest.resolve) return manifest;
|
|
64
|
+
const modules = manifest;
|
|
65
|
+
const resolve = (key)=>{
|
|
66
|
+
if (!key.startsWith(FEDERATED_ASSET_PREFIX)) return resolveStaticAssets(modules, key);
|
|
67
|
+
const remote = federatedServerAssets(scope, key.slice(FEDERATED_ASSET_PREFIX.length));
|
|
68
|
+
if (!remote) return null;
|
|
69
|
+
return {
|
|
70
|
+
js: [
|
|
71
|
+
joinAssetPath(modules._base, remote.hydration),
|
|
72
|
+
...remote.assets.js
|
|
73
|
+
],
|
|
74
|
+
css: [
|
|
75
|
+
...remote.assets.css
|
|
76
|
+
]
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
resolve,
|
|
81
|
+
resolveSync: resolve
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export { FEDERATED_ASSET_PREFIX, federatedAssetKey, federatedServerAssets, withFederatedAssets };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { loadFederatedModule } from "@modern-js/renderer-core/federation";
|
|
2
|
+
import { isServer } from "@solidjs/web";
|
|
3
|
+
import { FederationContext } from "./federation-context.js";
|
|
4
|
+
import { federatedAssetKey, federatedServerAssets } from "./federation-ssr.js";
|
|
5
|
+
import * as __rspack_external_solid_js_0ac0db99 from "solid-js";
|
|
6
|
+
const DEFAULT_SERVER_TIMEOUT = 3e3;
|
|
7
|
+
function withTimeout(promise, timeout, label) {
|
|
8
|
+
if (void 0 === timeout) return promise;
|
|
9
|
+
return new Promise((resolve, reject)=>{
|
|
10
|
+
const timer = setTimeout(()=>reject(new Error(`Remote module ${label} did not load within ${timeout}ms`)), timeout);
|
|
11
|
+
timer.unref?.();
|
|
12
|
+
promise.then((value)=>{
|
|
13
|
+
clearTimeout(timer);
|
|
14
|
+
resolve(value);
|
|
15
|
+
}, (error)=>{
|
|
16
|
+
clearTimeout(timer);
|
|
17
|
+
reject(error);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function afterHydration(callback) {
|
|
22
|
+
const { sharedConfig } = __rspack_external_solid_js_0ac0db99;
|
|
23
|
+
const onHydrationEnd = sharedConfig?.onHydrationEnd;
|
|
24
|
+
if (onHydrationEnd) onHydrationEnd(callback);
|
|
25
|
+
else queueMicrotask(callback);
|
|
26
|
+
}
|
|
27
|
+
function federatedComponent(remote, options = {}) {
|
|
28
|
+
if ("string" == typeof remote ? !/^[^/]+\/.+/u.test(remote) : "function" != typeof remote) throw new TypeError("federatedComponent requires a remote id such as 'remote/Widget' or a loader");
|
|
29
|
+
if (void 0 !== options.timeout && (!Number.isFinite(options.timeout) || options.timeout <= 0)) throw new TypeError("federatedComponent timeout must be a positive number of milliseconds");
|
|
30
|
+
const id = "string" == typeof remote ? remote : void 0;
|
|
31
|
+
const timeout = options.timeout ?? (isServer ? DEFAULT_SERVER_TIMEOUT : void 0);
|
|
32
|
+
const load = (scope)=>(0, __rspack_external_solid_js_0ac0db99.lazy)(async ()=>{
|
|
33
|
+
if (isServer && !id) throw new Error("A federatedComponent loader renders in the browser only; use a remote id to server-render it");
|
|
34
|
+
const module = await withTimeout(Promise.resolve().then(()=>id ? loadFederatedModule(scope.instance, id) : remote()), timeout, id ?? "loader");
|
|
35
|
+
const component = module?.default;
|
|
36
|
+
if ("function" != typeof component) throw new TypeError("A federated Solid module must default-export a component");
|
|
37
|
+
if (!isServer || !id) return {
|
|
38
|
+
default: component
|
|
39
|
+
};
|
|
40
|
+
if (!federatedServerAssets(scope, id)) throw new Error(`Cannot server-render ${id}: the host has no server federation state for its browser assets`);
|
|
41
|
+
return {
|
|
42
|
+
default: component,
|
|
43
|
+
$$moduleUrl: federatedAssetKey(id)
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
const remotes = new WeakMap();
|
|
47
|
+
const fallback = ()=>options.fallback?.();
|
|
48
|
+
return (props)=>{
|
|
49
|
+
const scope = (0, __rspack_external_solid_js_0ac0db99.useContext)(FederationContext);
|
|
50
|
+
const Remote = remotes.get(scope) ?? load(scope);
|
|
51
|
+
remotes.set(scope, Remote);
|
|
52
|
+
const remoteView = ()=>(0, __rspack_external_solid_js_0ac0db99.createComponent)(Remote, props);
|
|
53
|
+
const [retried, retry] = (0, __rspack_external_solid_js_0ac0db99.createSignal)(false);
|
|
54
|
+
const recover = (error)=>{
|
|
55
|
+
if (isServer) return fallback();
|
|
56
|
+
if ((0, __rspack_external_solid_js_0ac0db99.isHydrating)()) {
|
|
57
|
+
let active = true;
|
|
58
|
+
(0, __rspack_external_solid_js_0ac0db99.onCleanup)(()=>{
|
|
59
|
+
active = false;
|
|
60
|
+
});
|
|
61
|
+
afterHydration(()=>{
|
|
62
|
+
if (active) retry(true);
|
|
63
|
+
});
|
|
64
|
+
return fallback();
|
|
65
|
+
}
|
|
66
|
+
throw error();
|
|
67
|
+
};
|
|
68
|
+
return (0, __rspack_external_solid_js_0ac0db99.createComponent)(__rspack_external_solid_js_0ac0db99.Loading, {
|
|
69
|
+
get fallback () {
|
|
70
|
+
return fallback();
|
|
71
|
+
},
|
|
72
|
+
get children () {
|
|
73
|
+
return retried() ? remoteView() : (0, __rspack_external_solid_js_0ac0db99.createComponent)(__rspack_external_solid_js_0ac0db99.Errored, {
|
|
74
|
+
fallback: recover,
|
|
75
|
+
get children () {
|
|
76
|
+
return remoteView();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export { federatedComponent };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createComponent } from "@solidjs/web";
|
|
2
|
+
import { I18nContext } from "./context.js";
|
|
3
|
+
import * as __rspack_external_solid_js_0ac0db99 from "solid-js";
|
|
4
|
+
function I18nProvider(props) {
|
|
5
|
+
const [language, setLanguage] = __rspack_external_solid_js_0ac0db99.createSignal(props.instance.language);
|
|
6
|
+
__rspack_external_solid_js_0ac0db99.createEffect(()=>props.instance, (instance)=>{
|
|
7
|
+
setLanguage(instance.language);
|
|
8
|
+
const handleLanguageChanged = (lng)=>setLanguage(lng);
|
|
9
|
+
instance.on?.("languageChanged", handleLanguageChanged);
|
|
10
|
+
return ()=>{
|
|
11
|
+
instance.off?.("languageChanged", handleLanguageChanged);
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
const value = {
|
|
15
|
+
get instance () {
|
|
16
|
+
return props.instance;
|
|
17
|
+
},
|
|
18
|
+
get languages () {
|
|
19
|
+
return props.languages;
|
|
20
|
+
},
|
|
21
|
+
get localisedUrls () {
|
|
22
|
+
return props.localisedUrls;
|
|
23
|
+
},
|
|
24
|
+
language
|
|
25
|
+
};
|
|
26
|
+
return createComponent(I18nContext, {
|
|
27
|
+
value,
|
|
28
|
+
get children () {
|
|
29
|
+
return props.children;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export { I18nProvider };
|