houdini-react 1.2.9 → 1.2.10
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/build/plugin/codegen/entries.d.ts +1 -2
- package/build/plugin/codegen/index.d.ts +1 -2
- package/build/plugin/codegen/manifest.d.ts +4 -41
- package/build/plugin/codegen/router.d.ts +1 -2
- package/build/plugin/codegen/typeRoot.d.ts +1 -2
- package/build/plugin/index.d.ts +3 -1
- package/build/plugin/vite.d.ts +38 -1
- package/build/plugin-cjs/index.js +60083 -61067
- package/build/plugin-esm/index.js +60080 -61066
- package/build/runtime/index.d.ts +6 -3
- package/build/runtime/routing/components/Router.d.ts +4 -4
- package/build/runtime/routing/components/index.d.ts +0 -1
- package/build/runtime/routing/lib/cache.d.ts +1 -1
- package/build/runtime/routing/lib/types.d.ts +0 -4
- package/build/runtime/server/compat.d.ts +7 -0
- package/build/runtime/server/index.d.ts +17 -0
- package/build/runtime/server/session.d.ts +3 -0
- package/build/runtime-cjs/index.d.ts +6 -3
- package/build/runtime-cjs/index.js +22 -18
- package/build/runtime-cjs/routing/components/Router.d.ts +4 -4
- package/build/runtime-cjs/routing/components/Router.js +69 -39
- package/build/runtime-cjs/routing/components/index.d.ts +0 -1
- package/build/runtime-cjs/routing/components/index.js +0 -3
- package/build/runtime-cjs/routing/lib/cache.d.ts +1 -1
- package/build/runtime-cjs/routing/lib/cache.js +6 -2
- package/build/runtime-cjs/routing/lib/types.d.ts +0 -4
- package/build/runtime-cjs/server/compat.js +52 -0
- package/build/runtime-cjs/server/index.js +54 -0
- package/build/runtime-cjs/{routing/components/Link.js → server/session.js} +32 -22
- package/build/runtime-esm/index.d.ts +6 -3
- package/build/runtime-esm/index.js +22 -18
- package/build/runtime-esm/routing/components/Router.d.ts +4 -4
- package/build/runtime-esm/routing/components/Router.js +69 -38
- package/build/runtime-esm/routing/components/index.d.ts +0 -1
- package/build/runtime-esm/routing/components/index.js +0 -2
- package/build/runtime-esm/routing/lib/cache.d.ts +1 -1
- package/build/runtime-esm/routing/lib/cache.js +6 -2
- package/build/runtime-esm/routing/lib/types.d.ts +0 -4
- package/build/runtime-esm/server/compat.d.ts +7 -0
- package/build/runtime-esm/server/compat.js +28 -0
- package/build/runtime-esm/server/index.d.ts +17 -0
- package/build/runtime-esm/server/index.js +30 -0
- package/build/runtime-esm/server/session.d.ts +3 -0
- package/build/runtime-esm/server/session.js +30 -0
- package/package.json +3 -12
- package/build/plugin/conventions.d.ts +0 -24
- package/build/runtime/routing/components/Link.d.ts +0 -5
- package/build/runtime-cjs/routing/components/Link.d.ts +0 -5
- package/build/runtime-esm/routing/components/Link.d.ts +0 -5
- package/build/runtime-esm/routing/components/Link.js +0 -21
- package/build/server-cjs/index.js +0 -166716
- package/build/server-cjs/package.json +0 -1
- package/build/server-esm/index.js +0 -166707
- package/build/server-esm/package.json +0 -1
- /package/build/{server → runtime-cjs/server}/compat.d.ts +0 -0
- /package/build/{server → runtime-cjs/server}/index.d.ts +0 -0
- /package/build/{server → runtime-cjs/server}/session.d.ts +0 -0
|
@@ -22,30 +22,40 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
25
|
-
var
|
|
26
|
-
__export(
|
|
27
|
-
|
|
25
|
+
var session_exports = {};
|
|
26
|
+
__export(session_exports, {
|
|
27
|
+
get_session: () => get_session,
|
|
28
|
+
set_session: () => set_session
|
|
28
29
|
});
|
|
29
|
-
module.exports = __toCommonJS(
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
30
|
+
module.exports = __toCommonJS(session_exports);
|
|
31
|
+
var import_cookie_parser = __toESM(require("cookie-parser"));
|
|
32
|
+
const session_cookie_name = "__houdini__";
|
|
33
|
+
function set_session(res, value) {
|
|
34
|
+
const today = new Date();
|
|
35
|
+
const expires = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1e3);
|
|
36
|
+
const serialized = JSON.stringify(value);
|
|
37
|
+
res.set_header(
|
|
38
|
+
"Set-Cookie",
|
|
39
|
+
`${session_cookie_name}=${serialized}; Path=/; HttpOnly; Secure; SameSite=Lax; Expires=${expires.toUTCString()} `
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
function get_session(req, secrets) {
|
|
43
|
+
const cookie = req.get("cookie");
|
|
44
|
+
if (!cookie) {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
const parsed = import_cookie_parser.default.signedCookie(cookie, secrets);
|
|
48
|
+
if (!parsed) {
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
const houdini_session_cookie = parsed.split(";").map((s) => s.trim().split("=")).filter((s) => s[0] === session_cookie_name);
|
|
52
|
+
if (houdini_session_cookie.length === 1) {
|
|
53
|
+
return JSON.parse(houdini_session_cookie[0][1]);
|
|
54
|
+
}
|
|
55
|
+
return {};
|
|
47
56
|
}
|
|
48
57
|
// Annotate the CommonJS export names for ESM import in node:
|
|
49
58
|
0 && (module.exports = {
|
|
50
|
-
|
|
59
|
+
get_session,
|
|
60
|
+
set_session
|
|
51
61
|
});
|
|
@@ -7,8 +7,8 @@ import { PendingCache } from './routing/components/Router';
|
|
|
7
7
|
import { SuspenseCache } from './routing/lib/cache';
|
|
8
8
|
export * from './hooks';
|
|
9
9
|
export * from './routing';
|
|
10
|
-
export declare function Router({ cache,
|
|
11
|
-
|
|
10
|
+
export declare function Router({ cache, initialURL, artifact_cache, component_cache, data_cache, pending_cache, last_variables, loaded_queries, loaded_artifacts, session, assetPrefix, }: {
|
|
11
|
+
initialURL: string;
|
|
12
12
|
cache: Cache;
|
|
13
13
|
loaded_queries?: Record<string, {
|
|
14
14
|
data: GraphQLObject;
|
|
@@ -16,6 +16,7 @@ export declare function Router({ cache, intialURL, artifact_cache, component_cac
|
|
|
16
16
|
}>;
|
|
17
17
|
loaded_artifacts?: Record<string, QueryArtifact>;
|
|
18
18
|
session?: App.Session;
|
|
19
|
+
assetPrefix: string;
|
|
19
20
|
} & RouterCache): JSX.Element;
|
|
20
21
|
type RouterCache = {
|
|
21
22
|
artifact_cache: SuspenseCache<QueryArtifact>;
|
|
@@ -24,8 +25,10 @@ type RouterCache = {
|
|
|
24
25
|
last_variables: LRUCache<GraphQLVariables>;
|
|
25
26
|
pending_cache: PendingCache;
|
|
26
27
|
};
|
|
27
|
-
export declare function router_cache({ pending_queries, artifacts, components, }?: {
|
|
28
|
+
export declare function router_cache({ pending_queries, artifacts, components, initialData, initialArtifacts, }?: {
|
|
28
29
|
pending_queries?: string[];
|
|
29
30
|
artifacts?: Record<string, QueryArtifact>;
|
|
30
31
|
components?: Record<string, (props: any) => React.ReactElement>;
|
|
32
|
+
initialData?: Record<string, DocumentStore<GraphQLObject, GraphQLVariables>>;
|
|
33
|
+
initialArtifacts?: Record<string, QueryArtifact>;
|
|
31
34
|
}): RouterCache;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import client from "./client";
|
|
3
3
|
import manifest from "./manifest";
|
|
4
4
|
import { Router as RouterImpl, RouterContextProvider } from "./routing";
|
|
@@ -7,7 +7,7 @@ export * from "./hooks";
|
|
|
7
7
|
export * from "./routing";
|
|
8
8
|
function Router({
|
|
9
9
|
cache,
|
|
10
|
-
|
|
10
|
+
initialURL,
|
|
11
11
|
artifact_cache,
|
|
12
12
|
component_cache,
|
|
13
13
|
data_cache,
|
|
@@ -15,9 +15,10 @@ function Router({
|
|
|
15
15
|
last_variables,
|
|
16
16
|
loaded_queries,
|
|
17
17
|
loaded_artifacts,
|
|
18
|
-
session
|
|
18
|
+
session,
|
|
19
|
+
assetPrefix
|
|
19
20
|
}) {
|
|
20
|
-
return /* @__PURE__ */
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
21
22
|
RouterContextProvider,
|
|
22
23
|
{
|
|
23
24
|
client,
|
|
@@ -27,28 +28,31 @@ function Router({
|
|
|
27
28
|
data_cache,
|
|
28
29
|
pending_cache,
|
|
29
30
|
last_variables,
|
|
30
|
-
session
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
session,
|
|
32
|
+
children: /* @__PURE__ */ jsx(
|
|
33
|
+
RouterImpl,
|
|
34
|
+
{
|
|
35
|
+
initialURL,
|
|
36
|
+
manifest,
|
|
37
|
+
loaded_queries,
|
|
38
|
+
loaded_artifacts,
|
|
39
|
+
assetPrefix
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
}
|
|
41
43
|
);
|
|
42
44
|
}
|
|
43
45
|
function router_cache({
|
|
44
46
|
pending_queries = [],
|
|
45
47
|
artifacts = {},
|
|
46
|
-
components = {}
|
|
48
|
+
components = {},
|
|
49
|
+
initialData = {},
|
|
50
|
+
initialArtifacts = {}
|
|
47
51
|
} = {}) {
|
|
48
52
|
const result = {
|
|
49
|
-
artifact_cache: suspense_cache(),
|
|
53
|
+
artifact_cache: suspense_cache(initialArtifacts),
|
|
50
54
|
component_cache: suspense_cache(),
|
|
51
|
-
data_cache: suspense_cache(),
|
|
55
|
+
data_cache: suspense_cache(initialData),
|
|
52
56
|
pending_cache: suspense_cache(),
|
|
53
57
|
last_variables: suspense_cache()
|
|
54
58
|
};
|
|
@@ -5,22 +5,22 @@ import { GraphQLObject, GraphQLVariables } from '$houdini/runtime/lib/types';
|
|
|
5
5
|
import { QueryArtifact } from '$houdini/runtime/lib/types';
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import { SuspenseCache } from '../lib/cache';
|
|
8
|
-
import type {
|
|
8
|
+
import type { RouterManifest } from '../lib/types';
|
|
9
9
|
/**
|
|
10
10
|
* Router is the top level entry point for the filesystem-based router.
|
|
11
11
|
* It is responsible for loading various page sources (including API fetches) and
|
|
12
12
|
* then rendering when appropriate.
|
|
13
13
|
*/
|
|
14
|
-
export declare function Router({ manifest,
|
|
14
|
+
export declare function Router({ manifest, initialURL, loaded_queries, loaded_artifacts, assetPrefix, }: {
|
|
15
15
|
manifest: RouterManifest;
|
|
16
|
-
|
|
16
|
+
initialURL?: string;
|
|
17
17
|
loaded_queries?: Record<string, {
|
|
18
18
|
data: GraphQLObject;
|
|
19
19
|
variables: GraphQLVariables;
|
|
20
20
|
}>;
|
|
21
21
|
loaded_artifacts?: Record<string, QueryArtifact>;
|
|
22
|
+
assetPrefix: string;
|
|
22
23
|
}): JSX.Element;
|
|
23
|
-
export declare function useNavigationContext(): NavigationContext;
|
|
24
24
|
export declare function RouterContextProvider({ children, client, cache, artifact_cache, component_cache, data_cache, pending_cache, last_variables, session: ssrSession, }: {
|
|
25
25
|
children: React.ReactElement;
|
|
26
26
|
client: HoudiniClient;
|
|
@@ -1,33 +1,32 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
1
2
|
import { deepEquals } from "$houdini/runtime/lib/deepEquals";
|
|
2
3
|
import React from "react";
|
|
3
4
|
import { useStream } from "react-streaming";
|
|
4
5
|
import { useDocumentStore } from "../../hooks/useDocumentStore";
|
|
5
6
|
import { find_match } from "../lib/match";
|
|
6
|
-
const NavContext = React.createContext({
|
|
7
|
-
currentRoute: "/",
|
|
8
|
-
goto: () => {
|
|
9
|
-
throw new Error("NOT FOUND");
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
7
|
function Router({
|
|
13
8
|
manifest,
|
|
14
|
-
|
|
9
|
+
initialURL,
|
|
15
10
|
loaded_queries,
|
|
16
|
-
loaded_artifacts
|
|
11
|
+
loaded_artifacts,
|
|
12
|
+
assetPrefix
|
|
17
13
|
}) {
|
|
18
14
|
const [current, setCurrent] = React.useState(() => {
|
|
19
|
-
return
|
|
15
|
+
return initialURL || window.location.pathname;
|
|
20
16
|
});
|
|
21
17
|
const [page, variables] = find_match(manifest, current);
|
|
22
|
-
|
|
18
|
+
usePageData({ page, variables, loaded_queries, loaded_artifacts, assetPrefix });
|
|
23
19
|
const { component_cache } = useRouterContext();
|
|
24
20
|
const PageComponent = component_cache.get(page.id);
|
|
25
21
|
React.useEffect(() => {
|
|
26
|
-
if (window.location.pathname !== current) {
|
|
22
|
+
if (globalThis.window && window.location.pathname !== current) {
|
|
27
23
|
window.history.pushState({}, "", current);
|
|
28
24
|
}
|
|
29
25
|
}, [current]);
|
|
30
26
|
React.useEffect(() => {
|
|
27
|
+
if (!globalThis.window) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
31
30
|
const onChange = (evt) => {
|
|
32
31
|
setCurrent(window.location.pathname);
|
|
33
32
|
};
|
|
@@ -36,22 +35,15 @@ function Router({
|
|
|
36
35
|
window.removeEventListener("popstate", onChange);
|
|
37
36
|
};
|
|
38
37
|
}, []);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
{
|
|
42
|
-
value: {
|
|
43
|
-
currentRoute: current,
|
|
44
|
-
goto: setCurrent
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
/* @__PURE__ */ React.createElement(VariableContext.Provider, { value: variables }, /* @__PURE__ */ React.createElement(PageComponent, { url: current }))
|
|
48
|
-
);
|
|
38
|
+
useAnchorIntercept({ goto: setCurrent });
|
|
39
|
+
return /* @__PURE__ */ jsx(VariableContext.Provider, { value: variables, children: /* @__PURE__ */ jsx(PageComponent, { url: current }) });
|
|
49
40
|
}
|
|
50
|
-
function
|
|
41
|
+
function usePageData({
|
|
51
42
|
page,
|
|
52
43
|
variables,
|
|
53
44
|
loaded_queries,
|
|
54
|
-
loaded_artifacts
|
|
45
|
+
loaded_artifacts,
|
|
46
|
+
assetPrefix
|
|
55
47
|
}) {
|
|
56
48
|
const {
|
|
57
49
|
client,
|
|
@@ -93,17 +85,38 @@ function useLoadPage({
|
|
|
93
85
|
<script>
|
|
94
86
|
window.__houdini__cache__?.hydrate(${cache.serialize()}, window.__houdini__hydration__layer)
|
|
95
87
|
|
|
96
|
-
|
|
88
|
+
const artifactName = "${artifact.name}"
|
|
89
|
+
const value = ${JSON.stringify(observer.state.data)}
|
|
90
|
+
|
|
91
|
+
// if the data is pending, we need to resolve it
|
|
92
|
+
if (window.__houdini__nav_caches__?.data_cache.has(artifactName)) {
|
|
97
93
|
// before we resolve the pending signals,
|
|
98
94
|
// fill the data cache with values we got on the server
|
|
99
95
|
const new_store = window.__houdini__client__.observe({
|
|
100
|
-
artifact: window.__houdini__nav_caches__.artifact_cache.get(
|
|
96
|
+
artifact: window.__houdini__nav_caches__.artifact_cache.get(artifactName),
|
|
101
97
|
cache: window.__houdini__cache__,
|
|
102
|
-
initialValue:
|
|
98
|
+
initialValue: value
|
|
103
99
|
})
|
|
104
100
|
|
|
105
|
-
window.__houdini__nav_caches__
|
|
101
|
+
window.__houdini__nav_caches__?.data_cache.set(artifactName, new_store)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
// if there are no data caches available we need to populate the pending one instead
|
|
106
|
+
if (!window.__houdini__nav_caches__) {
|
|
107
|
+
if (!window.__houdini__pending_data__) {
|
|
108
|
+
window.__houdini__pending_data__ = {}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!window.__houdini__pending_artifacts__) {
|
|
112
|
+
window.__houdini__pending_artifacts__ = {}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
window.__houdini__pending_data__[artifactName] = value
|
|
116
|
+
window.__houdini__pending_artifacts__[artifactName] = ${JSON.stringify(artifact)}
|
|
117
|
+
}
|
|
106
118
|
|
|
119
|
+
if (window.__houdini__nav_caches__?.pending_cache.has(artifactName)) {
|
|
107
120
|
// we're pushing this store onto the client, it should be initialized
|
|
108
121
|
new_store.send({
|
|
109
122
|
setup: true,
|
|
@@ -111,8 +124,8 @@ function useLoadPage({
|
|
|
111
124
|
})
|
|
112
125
|
|
|
113
126
|
// notify anyone waiting on the pending cache
|
|
114
|
-
window.__houdini__nav_caches__.pending_cache.get(
|
|
115
|
-
window.__houdini__nav_caches__.pending_cache.delete(
|
|
127
|
+
window.__houdini__nav_caches__.pending_cache.get(artifactName).resolve()
|
|
128
|
+
window.__houdini__nav_caches__.pending_cache.delete(artifactName)
|
|
116
129
|
}
|
|
117
130
|
<\/script>
|
|
118
131
|
`);
|
|
@@ -144,7 +157,7 @@ function useLoadPage({
|
|
|
144
157
|
loaded_artifacts[artifact.name] = artifact;
|
|
145
158
|
}
|
|
146
159
|
stream?.injectToStream(`
|
|
147
|
-
<script type="module" src="
|
|
160
|
+
<script type="module" src="${assetPrefix}/artifacts/${artifact.name}.js" async=""><\/script>
|
|
148
161
|
`);
|
|
149
162
|
load_query({ id: artifact.name, artifact });
|
|
150
163
|
}).catch((err) => {
|
|
@@ -165,9 +178,6 @@ function useLoadPage({
|
|
|
165
178
|
});
|
|
166
179
|
}
|
|
167
180
|
}
|
|
168
|
-
function useNavigationContext() {
|
|
169
|
-
return React.useContext(NavContext);
|
|
170
|
-
}
|
|
171
181
|
function RouterContextProvider({
|
|
172
182
|
children,
|
|
173
183
|
client,
|
|
@@ -189,7 +199,7 @@ function RouterContextProvider({
|
|
|
189
199
|
window.removeEventListener("_houdini_session_", handleNewSession);
|
|
190
200
|
};
|
|
191
201
|
}, []);
|
|
192
|
-
return /* @__PURE__ */
|
|
202
|
+
return /* @__PURE__ */ jsx(
|
|
193
203
|
Context.Provider,
|
|
194
204
|
{
|
|
195
205
|
value: {
|
|
@@ -201,9 +211,9 @@ function RouterContextProvider({
|
|
|
201
211
|
pending_cache,
|
|
202
212
|
last_variables,
|
|
203
213
|
session
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
|
|
214
|
+
},
|
|
215
|
+
children
|
|
216
|
+
}
|
|
207
217
|
);
|
|
208
218
|
}
|
|
209
219
|
const Context = React.createContext(null);
|
|
@@ -243,6 +253,28 @@ function useQueryResult(name) {
|
|
|
243
253
|
});
|
|
244
254
|
return [data, observer];
|
|
245
255
|
}
|
|
256
|
+
function useAnchorIntercept({ goto }) {
|
|
257
|
+
const [pending, startTransition] = React.useTransition();
|
|
258
|
+
React.useEffect(() => {
|
|
259
|
+
let onClick = (e) => {
|
|
260
|
+
let link = e.target?.closest("a");
|
|
261
|
+
if (link && link instanceof HTMLAnchorElement && link.href && (!link.target || link.target === "_self") && link.origin === location.origin && !link.hasAttribute("download") && e.button === 0 && !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.defaultPrevented) {
|
|
262
|
+
const target = link.attributes.getNamedItem("href")?.value;
|
|
263
|
+
if (!target || !target.startsWith("/")) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
e.preventDefault();
|
|
267
|
+
startTransition(() => {
|
|
268
|
+
goto(target);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
document.addEventListener("click", onClick);
|
|
273
|
+
return () => {
|
|
274
|
+
document.removeEventListener("click", onClick);
|
|
275
|
+
};
|
|
276
|
+
}, []);
|
|
277
|
+
}
|
|
246
278
|
export {
|
|
247
279
|
Router,
|
|
248
280
|
RouterContextProvider,
|
|
@@ -250,7 +282,6 @@ export {
|
|
|
250
282
|
useCache,
|
|
251
283
|
useClient,
|
|
252
284
|
useCurrentVariables,
|
|
253
|
-
useNavigationContext,
|
|
254
285
|
useQueryResult,
|
|
255
286
|
useRouterContext,
|
|
256
287
|
useSession
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LRUCache } from '$houdini/runtime/lib/lru';
|
|
2
|
-
export declare function suspense_cache<T>(): SuspenseCache<T>;
|
|
2
|
+
export declare function suspense_cache<T>(initialData?: Record<string, T>): SuspenseCache<T>;
|
|
3
3
|
export declare class SuspenseCache<_Data> extends LRUCache<_Data> {
|
|
4
4
|
#private;
|
|
5
5
|
get(key: string): _Data;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { LRUCache } from "$houdini/runtime/lib/lru";
|
|
2
|
-
function suspense_cache() {
|
|
3
|
-
|
|
2
|
+
function suspense_cache(initialData) {
|
|
3
|
+
const cache = new SuspenseCache();
|
|
4
|
+
for (const [key, value] of Object.entries(initialData ?? {})) {
|
|
5
|
+
cache.set(key, value);
|
|
6
|
+
}
|
|
7
|
+
return cache;
|
|
4
8
|
}
|
|
5
9
|
class SuspenseCache extends LRUCache {
|
|
6
10
|
#callbacks = /* @__PURE__ */ new Map();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
function dev_server({ server, config }) {
|
|
2
|
+
return {
|
|
3
|
+
use(fn) {
|
|
4
|
+
server.use((req, res, next) => {
|
|
5
|
+
fn(
|
|
6
|
+
{
|
|
7
|
+
url: req.url,
|
|
8
|
+
headers: new Headers(req.headers)
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
...res,
|
|
12
|
+
redirect(url, status = 307) {
|
|
13
|
+
res.statusCode = status;
|
|
14
|
+
res.setHeader("location", url);
|
|
15
|
+
res.setHeader("content-length", "0");
|
|
16
|
+
return res.end();
|
|
17
|
+
},
|
|
18
|
+
set_header: res.setHeader.bind(res)
|
|
19
|
+
},
|
|
20
|
+
next
|
|
21
|
+
);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
dev_server
|
|
28
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Config } from 'houdini';
|
|
2
|
+
export declare function configure_server({ server, config }: {
|
|
3
|
+
server: Server;
|
|
4
|
+
config: Config;
|
|
5
|
+
}): void;
|
|
6
|
+
export type Server = {
|
|
7
|
+
use(fn: ServerMiddleware): void;
|
|
8
|
+
};
|
|
9
|
+
export type ServerMiddleware = (req: IncomingRequest, res: ServerResponse, next: () => void) => void;
|
|
10
|
+
export type IncomingRequest = {
|
|
11
|
+
url?: string;
|
|
12
|
+
headers: Headers;
|
|
13
|
+
};
|
|
14
|
+
export type ServerResponse = {
|
|
15
|
+
redirect(url: string, status?: number): void;
|
|
16
|
+
set_header(name: string, value: string): void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { plugin_config as get_plugin_config } from "../../plugin/config";
|
|
2
|
+
import { set_session } from "./session";
|
|
3
|
+
function configure_server({ server, config }) {
|
|
4
|
+
server.use(server_handler({ config }));
|
|
5
|
+
}
|
|
6
|
+
function server_handler({ config }) {
|
|
7
|
+
const plugin_config = get_plugin_config(config);
|
|
8
|
+
return (req, res, next) => {
|
|
9
|
+
if (!req.url) {
|
|
10
|
+
next();
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (plugin_config.auth && "redirect" in plugin_config.auth && req.url.startsWith(plugin_config.auth.redirect)) {
|
|
14
|
+
return redirect_auth(req, res, next);
|
|
15
|
+
}
|
|
16
|
+
next();
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const redirect_auth = (req, res, next) => {
|
|
20
|
+
const { searchParams } = new URL(req.url, `http://${req.headers.get("host")}`);
|
|
21
|
+
const { redirectTo, ...session } = Object.fromEntries(searchParams.entries());
|
|
22
|
+
set_session(res, session);
|
|
23
|
+
if (redirectTo) {
|
|
24
|
+
return res.redirect(redirectTo);
|
|
25
|
+
}
|
|
26
|
+
next();
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
configure_server
|
|
30
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import cookieParser from "cookie-parser";
|
|
2
|
+
const session_cookie_name = "__houdini__";
|
|
3
|
+
function set_session(res, value) {
|
|
4
|
+
const today = new Date();
|
|
5
|
+
const expires = new Date(today.getTime() + 7 * 24 * 60 * 60 * 1e3);
|
|
6
|
+
const serialized = JSON.stringify(value);
|
|
7
|
+
res.set_header(
|
|
8
|
+
"Set-Cookie",
|
|
9
|
+
`${session_cookie_name}=${serialized}; Path=/; HttpOnly; Secure; SameSite=Lax; Expires=${expires.toUTCString()} `
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
function get_session(req, secrets) {
|
|
13
|
+
const cookie = req.get("cookie");
|
|
14
|
+
if (!cookie) {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
const parsed = cookieParser.signedCookie(cookie, secrets);
|
|
18
|
+
if (!parsed) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
const houdini_session_cookie = parsed.split(";").map((s) => s.trim().split("=")).filter((s) => s[0] === session_cookie_name);
|
|
22
|
+
if (houdini_session_cookie.length === 1) {
|
|
23
|
+
return JSON.parse(houdini_session_cookie[0][1]);
|
|
24
|
+
}
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
get_session,
|
|
29
|
+
set_session
|
|
30
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "houdini-react",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.10",
|
|
4
4
|
"description": "The React plugin for houdini",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"recast": "^0.23.1",
|
|
41
41
|
"rollup": "^3.7.4",
|
|
42
42
|
"use-deep-compare-effect": "^1.8.1",
|
|
43
|
-
"houdini": "^1.2.
|
|
43
|
+
"houdini": "^1.2.10"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"build"
|
|
@@ -51,19 +51,10 @@
|
|
|
51
51
|
"types": "./build/plugin/index.d.ts",
|
|
52
52
|
"import": "./build/plugin-esm/index.js",
|
|
53
53
|
"require": "./build/plugin-cjs/index.js"
|
|
54
|
-
},
|
|
55
|
-
"./server": {
|
|
56
|
-
"types": "./build/server/index.d.ts",
|
|
57
|
-
"import": "./build/server-esm/index.js",
|
|
58
|
-
"require": "./build/server-cjs/index.js"
|
|
59
54
|
}
|
|
60
55
|
},
|
|
61
56
|
"typesVersions": {
|
|
62
|
-
"*": {
|
|
63
|
-
"server": [
|
|
64
|
-
"build/server/index.d.ts"
|
|
65
|
-
]
|
|
66
|
-
}
|
|
57
|
+
"*": {}
|
|
67
58
|
},
|
|
68
59
|
"main": "./build/plugin-cjs/index.js",
|
|
69
60
|
"types": "./build/plugin/index.d.ts",
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { type Config } from 'houdini';
|
|
2
|
-
/** The location of the project's router */
|
|
3
|
-
export declare function router_path(config: Config): string;
|
|
4
|
-
/** The location of the page component */
|
|
5
|
-
export declare function page_entry_path(config: Config, id: string, base?: string): string;
|
|
6
|
-
export declare function render_client_path(config: Config, base?: string): string;
|
|
7
|
-
export declare function render_server_path(config: Config, base?: string): string;
|
|
8
|
-
export declare function render_app_path(config: Config, base?: string): string;
|
|
9
|
-
export declare function page_unit_path(config: Config, id: string, base?: string): string;
|
|
10
|
-
export declare function layout_unit_path(config: Config, id: string, base?: string): string;
|
|
11
|
-
export declare function fallback_unit_path(config: Config, which: 'page' | 'layout', id: string, base?: string): string;
|
|
12
|
-
/** Load the page query for the given route from disk */
|
|
13
|
-
export declare function read_pageQuery(base: string): Promise<(string | null)[]>;
|
|
14
|
-
/** Load the page view for the given route from disk */
|
|
15
|
-
export declare function read_pageView(base: string): Promise<string[] | null[]>;
|
|
16
|
-
/** Load the layout query for the given route from disk */
|
|
17
|
-
export declare function read_layoutQuery(base: string): Promise<(string | null)[]>;
|
|
18
|
-
/** Load the layout view for the given route from disk */
|
|
19
|
-
export declare function read_layoutView(base: string): Promise<string[] | null[]>;
|
|
20
|
-
export declare function router_index_path(config: Config): string;
|
|
21
|
-
export declare function is_layout(path: string): boolean;
|
|
22
|
-
/** Transforms paths to ids */
|
|
23
|
-
export declare function normalize_path(path: string): string;
|
|
24
|
-
export declare function page_entries_dir(config: Config, base?: string): string;
|