@lolyjs/core 0.2.0-alpha.1 → 0.2.0-alpha.11
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/LICENCE.md +9 -0
- package/README.md +44 -31
- package/dist/{bootstrap-BiCQmSkx.d.mts → bootstrap-DgvWWDim.d.mts} +7 -0
- package/dist/{bootstrap-BiCQmSkx.d.ts → bootstrap-DgvWWDim.d.ts} +7 -0
- package/dist/cli.cjs +73 -26
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +73 -26
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +171 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +167 -31
- package/dist/index.js.map +1 -1
- package/dist/react/cache.cjs +25 -0
- package/dist/react/cache.cjs.map +1 -1
- package/dist/react/cache.js +25 -0
- package/dist/react/cache.js.map +1 -1
- package/dist/react/components.cjs.map +1 -1
- package/dist/react/components.js.map +1 -1
- package/dist/react/hooks.cjs +192 -20
- package/dist/react/hooks.cjs.map +1 -1
- package/dist/react/hooks.d.mts +75 -15
- package/dist/react/hooks.d.ts +75 -15
- package/dist/react/hooks.js +191 -19
- package/dist/react/hooks.js.map +1 -1
- package/dist/runtime.cjs +103 -9
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +99 -5
- package/dist/runtime.js.map +1 -1
- package/package.json +44 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
2
|
import { Request, Response } from 'express';
|
|
3
3
|
import { Socket, Server } from 'socket.io';
|
|
4
|
-
export { c as bootstrapClient } from './bootstrap-
|
|
4
|
+
export { c as bootstrapClient } from './bootstrap-DgvWWDim.mjs';
|
|
5
5
|
import { ZodSchema, z } from 'zod';
|
|
6
6
|
import * as express_rate_limit from 'express-rate-limit';
|
|
7
7
|
import pino, { Logger as Logger$1 } from 'pino';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
2
|
import { Request, Response } from 'express';
|
|
3
3
|
import { Socket, Server } from 'socket.io';
|
|
4
|
-
export { c as bootstrapClient } from './bootstrap-
|
|
4
|
+
export { c as bootstrapClient } from './bootstrap-DgvWWDim.js';
|
|
5
5
|
import { ZodSchema, z } from 'zod';
|
|
6
6
|
import * as express_rate_limit from 'express-rate-limit';
|
|
7
7
|
import pino, { Logger as Logger$1 } from 'pino';
|
package/dist/index.js
CHANGED
|
@@ -42,17 +42,19 @@ __export(globals_exports, {
|
|
|
42
42
|
NOT_FOUND_FILE_PREFIX: () => NOT_FOUND_FILE_PREFIX,
|
|
43
43
|
NOT_FOUND_PATTERN: () => NOT_FOUND_PATTERN,
|
|
44
44
|
PAGE_FILE_NAME: () => PAGE_FILE_NAME,
|
|
45
|
+
ROUTER_DATA_KEY: () => ROUTER_DATA_KEY,
|
|
45
46
|
STATIC_PATH: () => STATIC_PATH,
|
|
46
47
|
STYLE_FILE_NAME: () => STYLE_FILE_NAME,
|
|
47
48
|
WINDOW_DATA_KEY: () => WINDOW_DATA_KEY
|
|
48
49
|
});
|
|
49
|
-
var BUILD_FOLDER_NAME, STYLE_FILE_NAME, WINDOW_DATA_KEY, APP_CONTAINER_ID, STATIC_PATH, NOT_FOUND_PATTERN, ERROR_PATTERN, NOT_FOUND_CHUNK_KEY, ERROR_CHUNK_KEY, NOT_FOUND_FILE_PREFIX, ERROR_FILE_PREFIX, PAGE_FILE_NAME, LAYOUT_FILE_NAME, FAVICON_PATH, CLIENT_CSS_PATH, CLIENT_JS_PATH, ASSETS_BASE_DIR;
|
|
50
|
+
var BUILD_FOLDER_NAME, STYLE_FILE_NAME, WINDOW_DATA_KEY, ROUTER_DATA_KEY, APP_CONTAINER_ID, STATIC_PATH, NOT_FOUND_PATTERN, ERROR_PATTERN, NOT_FOUND_CHUNK_KEY, ERROR_CHUNK_KEY, NOT_FOUND_FILE_PREFIX, ERROR_FILE_PREFIX, PAGE_FILE_NAME, LAYOUT_FILE_NAME, FAVICON_PATH, CLIENT_CSS_PATH, CLIENT_JS_PATH, ASSETS_BASE_DIR;
|
|
50
51
|
var init_globals = __esm({
|
|
51
52
|
"constants/globals.ts"() {
|
|
52
53
|
"use strict";
|
|
53
54
|
BUILD_FOLDER_NAME = ".loly";
|
|
54
55
|
STYLE_FILE_NAME = "styles.css";
|
|
55
56
|
WINDOW_DATA_KEY = "__FW_DATA__";
|
|
57
|
+
ROUTER_DATA_KEY = "__LOLY_ROUTER_DATA__";
|
|
56
58
|
APP_CONTAINER_ID = "__app";
|
|
57
59
|
STATIC_PATH = "/static";
|
|
58
60
|
NOT_FOUND_PATTERN = "/not-found";
|
|
@@ -3835,6 +3837,7 @@ function createDocumentTree(options) {
|
|
|
3835
3837
|
const {
|
|
3836
3838
|
appTree,
|
|
3837
3839
|
initialData,
|
|
3840
|
+
routerData,
|
|
3838
3841
|
meta,
|
|
3839
3842
|
titleFallback,
|
|
3840
3843
|
descriptionFallback,
|
|
@@ -3872,6 +3875,9 @@ function createDocumentTree(options) {
|
|
|
3872
3875
|
...initialData,
|
|
3873
3876
|
theme
|
|
3874
3877
|
});
|
|
3878
|
+
const routerSerialized = JSON.stringify({
|
|
3879
|
+
...routerData
|
|
3880
|
+
});
|
|
3875
3881
|
const documentTree = React.createElement(
|
|
3876
3882
|
"html",
|
|
3877
3883
|
{ lang },
|
|
@@ -3919,6 +3925,12 @@ function createDocumentTree(options) {
|
|
|
3919
3925
|
dangerouslySetInnerHTML: {
|
|
3920
3926
|
__html: `window.${WINDOW_DATA_KEY} = ${serialized};`
|
|
3921
3927
|
}
|
|
3928
|
+
}),
|
|
3929
|
+
React.createElement("script", {
|
|
3930
|
+
nonce,
|
|
3931
|
+
dangerouslySetInnerHTML: {
|
|
3932
|
+
__html: `window.${ROUTER_DATA_KEY} = ${routerSerialized};`
|
|
3933
|
+
}
|
|
3922
3934
|
})
|
|
3923
3935
|
);
|
|
3924
3936
|
return documentTree;
|
|
@@ -3941,6 +3953,15 @@ function buildInitialData(urlPath, params, loaderResult) {
|
|
|
3941
3953
|
};
|
|
3942
3954
|
}
|
|
3943
3955
|
|
|
3956
|
+
// modules/rendering/routerData/index.ts
|
|
3957
|
+
var buildRouterData = (req) => {
|
|
3958
|
+
return {
|
|
3959
|
+
pathname: req.path,
|
|
3960
|
+
params: req.params,
|
|
3961
|
+
searchParams: req.query
|
|
3962
|
+
};
|
|
3963
|
+
};
|
|
3964
|
+
|
|
3944
3965
|
// modules/server/handlers/middleware.ts
|
|
3945
3966
|
async function runRouteMiddlewares(route, ctx) {
|
|
3946
3967
|
for (const mw of route.middlewares) {
|
|
@@ -4102,6 +4123,7 @@ async function handlePageRequestInternal(options) {
|
|
|
4102
4123
|
}
|
|
4103
4124
|
}
|
|
4104
4125
|
const matched = matchRoute(routes, urlPath);
|
|
4126
|
+
const routerData = buildRouterData(req);
|
|
4105
4127
|
if (!matched) {
|
|
4106
4128
|
if (notFoundPage) {
|
|
4107
4129
|
const ctx2 = {
|
|
@@ -4122,6 +4144,7 @@ async function handlePageRequestInternal(options) {
|
|
|
4122
4144
|
const documentTree2 = createDocumentTree({
|
|
4123
4145
|
appTree: appTree2,
|
|
4124
4146
|
initialData: initialData2,
|
|
4147
|
+
routerData,
|
|
4125
4148
|
meta: loaderResult2.metadata ?? null,
|
|
4126
4149
|
titleFallback: "Not found",
|
|
4127
4150
|
descriptionFallback: "Loly demo",
|
|
@@ -4229,6 +4252,7 @@ async function handlePageRequestInternal(options) {
|
|
|
4229
4252
|
const documentTree = createDocumentTree({
|
|
4230
4253
|
appTree,
|
|
4231
4254
|
initialData,
|
|
4255
|
+
routerData,
|
|
4232
4256
|
meta: loaderResult.metadata,
|
|
4233
4257
|
titleFallback: "Loly framework",
|
|
4234
4258
|
descriptionFallback: "Loly demo",
|
|
@@ -4286,6 +4310,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
4286
4310
|
loaderResult.theme = theme;
|
|
4287
4311
|
}
|
|
4288
4312
|
const initialData = buildInitialData(req.path, { error: String(error) }, loaderResult);
|
|
4313
|
+
const routerData = buildRouterData(req);
|
|
4289
4314
|
initialData.error = true;
|
|
4290
4315
|
if (isDataReq) {
|
|
4291
4316
|
res.statusCode = 500;
|
|
@@ -4316,6 +4341,7 @@ async function renderErrorPageWithStream(errorPage, req, res, error, routeChunks
|
|
|
4316
4341
|
const documentTree = createDocumentTree({
|
|
4317
4342
|
appTree,
|
|
4318
4343
|
initialData,
|
|
4344
|
+
routerData,
|
|
4319
4345
|
meta: loaderResult.metadata ?? null,
|
|
4320
4346
|
titleFallback: "Error",
|
|
4321
4347
|
descriptionFallback: "An error occurred",
|
|
@@ -4589,7 +4615,11 @@ var setupApplication = async ({
|
|
|
4589
4615
|
helmetConfig.contentSecurityPolicy = {
|
|
4590
4616
|
directives: {
|
|
4591
4617
|
defaultSrc: ["'self'"],
|
|
4592
|
-
styleSrc: [
|
|
4618
|
+
styleSrc: [
|
|
4619
|
+
"'self'",
|
|
4620
|
+
"'unsafe-inline'",
|
|
4621
|
+
"https://fonts.googleapis.com"
|
|
4622
|
+
],
|
|
4593
4623
|
scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
|
|
4594
4624
|
imgSrc: ["'self'", "data:", "https:"],
|
|
4595
4625
|
// Allow fetch/XHR to any HTTPS endpoint - users can restrict in their config if needed
|
|
@@ -4606,7 +4636,11 @@ var setupApplication = async ({
|
|
|
4606
4636
|
const defaultCSP = {
|
|
4607
4637
|
directives: {
|
|
4608
4638
|
defaultSrc: ["'self'"],
|
|
4609
|
-
styleSrc: [
|
|
4639
|
+
styleSrc: [
|
|
4640
|
+
"'self'",
|
|
4641
|
+
"'unsafe-inline'",
|
|
4642
|
+
"https://fonts.googleapis.com"
|
|
4643
|
+
],
|
|
4610
4644
|
scriptSrc: ["'self'", nonceFunction],
|
|
4611
4645
|
imgSrc: ["'self'", "data:", "https:"],
|
|
4612
4646
|
// Allow fetch/XHR to any HTTPS endpoint - users can restrict in their config if needed
|
|
@@ -4629,10 +4663,7 @@ var setupApplication = async ({
|
|
|
4629
4663
|
(src) => typeof src === "function"
|
|
4630
4664
|
);
|
|
4631
4665
|
if (!hasNonceSupport) {
|
|
4632
|
-
mergedDirectives.scriptSrc = [
|
|
4633
|
-
...userScriptSrc,
|
|
4634
|
-
nonceFunction
|
|
4635
|
-
];
|
|
4666
|
+
mergedDirectives.scriptSrc = [...userScriptSrc, nonceFunction];
|
|
4636
4667
|
} else {
|
|
4637
4668
|
mergedDirectives.scriptSrc = userScriptSrc;
|
|
4638
4669
|
}
|
|
@@ -4640,19 +4671,25 @@ var setupApplication = async ({
|
|
|
4640
4671
|
const userConnectSrc = userDirectives.connectSrc;
|
|
4641
4672
|
if (userConnectSrc && Array.isArray(userConnectSrc)) {
|
|
4642
4673
|
const defaultConnectSrc = defaultCSP.directives.connectSrc || [];
|
|
4643
|
-
const mergedConnectSrc = [
|
|
4674
|
+
const mergedConnectSrc = [
|
|
4675
|
+
.../* @__PURE__ */ new Set([...defaultConnectSrc, ...userConnectSrc])
|
|
4676
|
+
];
|
|
4644
4677
|
mergedDirectives.connectSrc = mergedConnectSrc;
|
|
4645
4678
|
}
|
|
4646
4679
|
const userStyleSrc = userDirectives.styleSrc;
|
|
4647
4680
|
if (userStyleSrc && Array.isArray(userStyleSrc)) {
|
|
4648
4681
|
const defaultStyleSrc = defaultCSP.directives.styleSrc || [];
|
|
4649
|
-
const mergedStyleSrc = [
|
|
4682
|
+
const mergedStyleSrc = [
|
|
4683
|
+
.../* @__PURE__ */ new Set([...defaultStyleSrc, ...userStyleSrc])
|
|
4684
|
+
];
|
|
4650
4685
|
mergedDirectives.styleSrc = mergedStyleSrc;
|
|
4651
4686
|
}
|
|
4652
4687
|
const userFontSrc = userDirectives.fontSrc;
|
|
4653
4688
|
if (userFontSrc && Array.isArray(userFontSrc)) {
|
|
4654
4689
|
const defaultFontSrc = defaultCSP.directives.fontSrc || [];
|
|
4655
|
-
const mergedFontSrc = [
|
|
4690
|
+
const mergedFontSrc = [
|
|
4691
|
+
.../* @__PURE__ */ new Set([...defaultFontSrc, ...userFontSrc])
|
|
4692
|
+
];
|
|
4656
4693
|
mergedDirectives.fontSrc = mergedFontSrc;
|
|
4657
4694
|
}
|
|
4658
4695
|
helmetConfig.contentSecurityPolicy = {
|
|
@@ -4672,23 +4709,27 @@ var setupApplication = async ({
|
|
|
4672
4709
|
helmetConfig.hsts = false;
|
|
4673
4710
|
}
|
|
4674
4711
|
if (process.env.NODE_ENV !== "development" && security?.contentSecurityPolicy !== false) {
|
|
4675
|
-
app.use(
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4712
|
+
app.use(
|
|
4713
|
+
(req, res, next) => {
|
|
4714
|
+
const nonce = crypto.randomBytes(16).toString("base64");
|
|
4715
|
+
res.locals.nonce = nonce;
|
|
4716
|
+
next();
|
|
4717
|
+
}
|
|
4718
|
+
);
|
|
4680
4719
|
}
|
|
4681
4720
|
app.use(helmet(helmetConfig));
|
|
4682
4721
|
const appLogger = createModuleLogger("framework");
|
|
4683
|
-
app.use(
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4722
|
+
app.use(
|
|
4723
|
+
requestLoggerMiddleware({
|
|
4724
|
+
logger: appLogger.child({ component: "server" }),
|
|
4725
|
+
logRequests: process.env.LOG_REQUESTS === "true",
|
|
4726
|
+
// Default to false (only errors/warnings)
|
|
4727
|
+
logResponses: process.env.LOG_RESPONSES !== "false",
|
|
4728
|
+
// Default to true (but filtered)
|
|
4729
|
+
logStaticAssets: process.env.LOG_STATIC_ASSETS === "true"
|
|
4730
|
+
// Default to false
|
|
4731
|
+
})
|
|
4732
|
+
);
|
|
4692
4733
|
const corsOptions = {
|
|
4693
4734
|
credentials: true
|
|
4694
4735
|
};
|
|
@@ -4704,7 +4745,7 @@ var setupApplication = async ({
|
|
|
4704
4745
|
corsOptions.origin = process.env.NODE_ENV === "development";
|
|
4705
4746
|
}
|
|
4706
4747
|
app.use(cors(corsOptions));
|
|
4707
|
-
if (rateLimit2) {
|
|
4748
|
+
if (rateLimit2 && process.env.NODE_ENV !== "development") {
|
|
4708
4749
|
const generalLimiter = createRateLimiter({
|
|
4709
4750
|
windowMs: rateLimit2.windowMs,
|
|
4710
4751
|
max: rateLimit2.max
|
|
@@ -4898,10 +4939,12 @@ async function renderStaticRoute(projectRoot, ssgOutDir, route, urlPath, params)
|
|
|
4898
4939
|
return;
|
|
4899
4940
|
}
|
|
4900
4941
|
const initialData = buildInitialData(urlPath, params, loaderResult);
|
|
4942
|
+
const routerData = buildRouterData(req);
|
|
4901
4943
|
const appTree = buildAppTree(route, params, initialData.props);
|
|
4902
4944
|
const documentTree = createDocumentTree({
|
|
4903
4945
|
appTree,
|
|
4904
4946
|
initialData,
|
|
4947
|
+
routerData,
|
|
4905
4948
|
meta: loaderResult.metadata,
|
|
4906
4949
|
titleFallback: "My Framework Dev",
|
|
4907
4950
|
descriptionFallback: "Static page generated by @lolyjs/core.",
|
|
@@ -5092,12 +5135,23 @@ import { hydrateRoot } from "react-dom/client";
|
|
|
5092
5135
|
|
|
5093
5136
|
// modules/runtime/client/constants.ts
|
|
5094
5137
|
var WINDOW_DATA_KEY2 = "__FW_DATA__";
|
|
5138
|
+
var ROUTER_DATA_KEY2 = "__LOLY_ROUTER_DATA__";
|
|
5095
5139
|
var APP_CONTAINER_ID2 = "__app";
|
|
5140
|
+
var ROUTER_NAVIGATE_KEY = "__LOLY_ROUTER_NAVIGATE__";
|
|
5096
5141
|
|
|
5097
5142
|
// modules/runtime/client/window-data.ts
|
|
5098
5143
|
function getWindowData() {
|
|
5144
|
+
if (typeof window === "undefined") {
|
|
5145
|
+
return null;
|
|
5146
|
+
}
|
|
5099
5147
|
return window[WINDOW_DATA_KEY2] ?? null;
|
|
5100
5148
|
}
|
|
5149
|
+
function getRouterData() {
|
|
5150
|
+
if (typeof window === "undefined") {
|
|
5151
|
+
return null;
|
|
5152
|
+
}
|
|
5153
|
+
return window[ROUTER_DATA_KEY2] ?? null;
|
|
5154
|
+
}
|
|
5101
5155
|
function setWindowData(data) {
|
|
5102
5156
|
window[WINDOW_DATA_KEY2] = data;
|
|
5103
5157
|
if (typeof window !== "undefined") {
|
|
@@ -5108,6 +5162,16 @@ function setWindowData(data) {
|
|
|
5108
5162
|
);
|
|
5109
5163
|
}
|
|
5110
5164
|
}
|
|
5165
|
+
function setRouterData(data) {
|
|
5166
|
+
window[ROUTER_DATA_KEY2] = data;
|
|
5167
|
+
if (typeof window !== "undefined") {
|
|
5168
|
+
window.dispatchEvent(
|
|
5169
|
+
new CustomEvent("fw-router-data-refresh", {
|
|
5170
|
+
detail: { data }
|
|
5171
|
+
})
|
|
5172
|
+
);
|
|
5173
|
+
}
|
|
5174
|
+
}
|
|
5111
5175
|
function getCurrentTheme() {
|
|
5112
5176
|
return getWindowData()?.theme ?? null;
|
|
5113
5177
|
}
|
|
@@ -5172,7 +5236,7 @@ function applyMetadata(md) {
|
|
|
5172
5236
|
}
|
|
5173
5237
|
|
|
5174
5238
|
// modules/runtime/client/AppShell.tsx
|
|
5175
|
-
import { useEffect, useState, useRef } from "react";
|
|
5239
|
+
import { useEffect, useState, useRef, useCallback } from "react";
|
|
5176
5240
|
|
|
5177
5241
|
// modules/runtime/client/RouterView.tsx
|
|
5178
5242
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -5369,6 +5433,13 @@ async function handleErrorRoute(nextUrl, json, errorRoute, setState) {
|
|
|
5369
5433
|
error: true
|
|
5370
5434
|
};
|
|
5371
5435
|
setWindowData(windowData);
|
|
5436
|
+
const url = new URL(nextUrl, typeof window !== "undefined" ? window.location.origin : "http://localhost");
|
|
5437
|
+
const routerData = {
|
|
5438
|
+
pathname: url.pathname,
|
|
5439
|
+
params: json.params || {},
|
|
5440
|
+
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
5441
|
+
};
|
|
5442
|
+
setRouterData(routerData);
|
|
5372
5443
|
setState({
|
|
5373
5444
|
url: nextUrl,
|
|
5374
5445
|
route: errorRoute,
|
|
@@ -5415,6 +5486,13 @@ async function handleNotFoundRoute(nextUrl, json, notFoundRoute, setState) {
|
|
|
5415
5486
|
error: false
|
|
5416
5487
|
};
|
|
5417
5488
|
setWindowData(windowData);
|
|
5489
|
+
const url = new URL(nextUrl, typeof window !== "undefined" ? window.location.origin : "http://localhost");
|
|
5490
|
+
const routerData = {
|
|
5491
|
+
pathname: url.pathname,
|
|
5492
|
+
params: {},
|
|
5493
|
+
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
5494
|
+
};
|
|
5495
|
+
setRouterData(routerData);
|
|
5418
5496
|
if (notFoundRoute) {
|
|
5419
5497
|
const components = await notFoundRoute.load();
|
|
5420
5498
|
setState({
|
|
@@ -5472,6 +5550,13 @@ async function handleNormalRoute(nextUrl, json, routes, setState) {
|
|
|
5472
5550
|
error: false
|
|
5473
5551
|
};
|
|
5474
5552
|
setWindowData(windowData);
|
|
5553
|
+
const url = new URL(nextUrl, typeof window !== "undefined" ? window.location.origin : "http://localhost");
|
|
5554
|
+
const routerData = {
|
|
5555
|
+
pathname: url.pathname,
|
|
5556
|
+
params: matched.params,
|
|
5557
|
+
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
5558
|
+
};
|
|
5559
|
+
setRouterData(routerData);
|
|
5475
5560
|
const components = await matched.route.load();
|
|
5476
5561
|
window.scrollTo({
|
|
5477
5562
|
top: 0,
|
|
@@ -5591,6 +5676,10 @@ function createPopStateHandler(navigate2) {
|
|
|
5591
5676
|
};
|
|
5592
5677
|
}
|
|
5593
5678
|
|
|
5679
|
+
// modules/runtime/client/RouterContext.tsx
|
|
5680
|
+
import { createContext, useContext } from "react";
|
|
5681
|
+
var RouterContext = createContext(null);
|
|
5682
|
+
|
|
5594
5683
|
// modules/runtime/client/AppShell.tsx
|
|
5595
5684
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
5596
5685
|
function AppShell({
|
|
@@ -5614,14 +5703,30 @@ function AppShell({
|
|
|
5614
5703
|
errorRoute
|
|
5615
5704
|
};
|
|
5616
5705
|
}, [routes, notFoundRoute, errorRoute]);
|
|
5706
|
+
const handleNavigate = useCallback(
|
|
5707
|
+
async (nextUrl, options) => {
|
|
5708
|
+
await navigate(nextUrl, handlersRef.current, {
|
|
5709
|
+
revalidate: options?.revalidate
|
|
5710
|
+
});
|
|
5711
|
+
},
|
|
5712
|
+
[]
|
|
5713
|
+
);
|
|
5714
|
+
useEffect(() => {
|
|
5715
|
+
if (typeof window !== "undefined") {
|
|
5716
|
+
window[ROUTER_NAVIGATE_KEY] = handleNavigate;
|
|
5717
|
+
return () => {
|
|
5718
|
+
delete window[ROUTER_NAVIGATE_KEY];
|
|
5719
|
+
};
|
|
5720
|
+
}
|
|
5721
|
+
}, [handleNavigate]);
|
|
5617
5722
|
useEffect(() => {
|
|
5618
5723
|
let isMounted = true;
|
|
5619
|
-
async function
|
|
5724
|
+
async function handleNavigateInternal(nextUrl, options) {
|
|
5620
5725
|
if (!isMounted) return;
|
|
5621
5726
|
await navigate(nextUrl, handlersRef.current, options);
|
|
5622
5727
|
}
|
|
5623
|
-
const handleClick = createClickHandler(
|
|
5624
|
-
const handlePopState = createPopStateHandler(
|
|
5728
|
+
const handleClick = createClickHandler(handleNavigateInternal);
|
|
5729
|
+
const handlePopState = createPopStateHandler(handleNavigateInternal);
|
|
5625
5730
|
window.addEventListener("click", handleClick, false);
|
|
5626
5731
|
window.addEventListener("popstate", handlePopState, false);
|
|
5627
5732
|
return () => {
|
|
@@ -5630,11 +5735,33 @@ function AppShell({
|
|
|
5630
5735
|
window.removeEventListener("popstate", handlePopState, false);
|
|
5631
5736
|
};
|
|
5632
5737
|
}, []);
|
|
5738
|
+
useEffect(() => {
|
|
5739
|
+
const handleDataRefresh = () => {
|
|
5740
|
+
const freshData = window?.__FW_DATA__;
|
|
5741
|
+
if (!freshData) return;
|
|
5742
|
+
const currentPathname = window.location.pathname;
|
|
5743
|
+
const freshPathname = freshData.pathname;
|
|
5744
|
+
if (freshPathname === currentPathname) {
|
|
5745
|
+
if (freshData.metadata !== void 0) {
|
|
5746
|
+
applyMetadata(freshData.metadata);
|
|
5747
|
+
}
|
|
5748
|
+
setState((prevState) => ({
|
|
5749
|
+
...prevState,
|
|
5750
|
+
props: freshData.props ?? prevState.props,
|
|
5751
|
+
params: freshData.params ?? prevState.params
|
|
5752
|
+
}));
|
|
5753
|
+
}
|
|
5754
|
+
};
|
|
5755
|
+
window.addEventListener("fw-data-refresh", handleDataRefresh);
|
|
5756
|
+
return () => {
|
|
5757
|
+
window.removeEventListener("fw-data-refresh", handleDataRefresh);
|
|
5758
|
+
};
|
|
5759
|
+
}, [state.url]);
|
|
5633
5760
|
const isError = state.route === errorRoute;
|
|
5634
5761
|
const isNotFound = state.route === notFoundRoute;
|
|
5635
5762
|
const routeType = isError ? "error" : isNotFound ? "notfound" : "normal";
|
|
5636
5763
|
const routeKey = `${state.url}:${routeType}`;
|
|
5637
|
-
return /* @__PURE__ */ jsx2(RouterView, { state }, routeKey);
|
|
5764
|
+
return /* @__PURE__ */ jsx2(RouterContext.Provider, { value: { navigate: handleNavigate }, children: /* @__PURE__ */ jsx2(RouterView, { state }, routeKey) });
|
|
5638
5765
|
}
|
|
5639
5766
|
|
|
5640
5767
|
// modules/runtime/client/bootstrap.tsx
|
|
@@ -5734,6 +5861,16 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
5734
5861
|
return;
|
|
5735
5862
|
}
|
|
5736
5863
|
const initialUrl = window.location.pathname + window.location.search;
|
|
5864
|
+
let routerData = getRouterData();
|
|
5865
|
+
if (!routerData) {
|
|
5866
|
+
const url = new URL(initialUrl, window.location.origin);
|
|
5867
|
+
routerData = {
|
|
5868
|
+
pathname: url.pathname,
|
|
5869
|
+
params: initialData?.params || {},
|
|
5870
|
+
searchParams: Object.fromEntries(url.searchParams.entries())
|
|
5871
|
+
};
|
|
5872
|
+
setRouterData(routerData);
|
|
5873
|
+
}
|
|
5737
5874
|
try {
|
|
5738
5875
|
const initialState = await loadInitialRoute(
|
|
5739
5876
|
initialUrl,
|
|
@@ -5772,7 +5909,6 @@ function bootstrapClient(routes, notFoundRoute, errorRoute = null) {
|
|
|
5772
5909
|
function withCache(fn, options) {
|
|
5773
5910
|
const ttl = options.ttl ?? 60;
|
|
5774
5911
|
return async function cachedGssp(ctx) {
|
|
5775
|
-
console.log("TTL", ttl);
|
|
5776
5912
|
return await fn(ctx);
|
|
5777
5913
|
};
|
|
5778
5914
|
}
|