hadars 0.2.0 → 0.2.2-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +247 -15
- package/cli-lib.ts +184 -15
- package/dist/chunk-H72BZXOA.js +332 -0
- package/dist/cli.js +596 -23
- package/dist/cloudflare.cjs +1394 -0
- package/dist/cloudflare.d.cts +64 -0
- package/dist/cloudflare.d.ts +64 -0
- package/dist/cloudflare.js +68 -0
- package/dist/{hadars-Bh-V5YXg.d.cts → hadars-mKu5txjW.d.cts} +93 -37
- package/dist/{hadars-Bh-V5YXg.d.ts → hadars-mKu5txjW.d.ts} +93 -37
- package/dist/index.cjs +140 -164
- package/dist/index.d.cts +5 -11
- package/dist/index.d.ts +5 -11
- package/dist/index.js +140 -163
- package/dist/lambda.cjs +6 -2
- package/dist/lambda.d.cts +1 -2
- package/dist/lambda.d.ts +1 -2
- package/dist/lambda.js +10 -317
- package/dist/ssr-render-worker.js +3 -2
- package/dist/utils/Head.tsx +149 -195
- package/dist/utils/clientScript.tsx +9 -0
- package/index.ts +3 -0
- package/package.json +7 -2
- package/src/build.ts +29 -0
- package/src/cloudflare.ts +139 -0
- package/src/index.tsx +3 -3
- package/src/source/context.ts +113 -0
- package/src/source/graphiql.ts +96 -0
- package/src/source/inference.ts +188 -0
- package/src/source/runner.ts +114 -0
- package/src/source/store.ts +48 -0
- package/src/ssr-render-worker.ts +4 -1
- package/src/static.ts +106 -0
- package/src/types/hadars.ts +91 -2
- package/src/utils/Head.tsx +149 -195
- package/src/utils/clientScript.tsx +9 -0
- package/src/utils/response.tsx +10 -3
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { H as HadarsEntryModule, a as HadarsOptions } from './hadars-mKu5txjW.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cloudflare Workers adapter for hadars.
|
|
5
|
+
*
|
|
6
|
+
* After running `hadars build`, bundle your app with:
|
|
7
|
+
*
|
|
8
|
+
* hadars export cloudflare
|
|
9
|
+
*
|
|
10
|
+
* This produces a self-contained `cloudflare.mjs` that you deploy with:
|
|
11
|
+
*
|
|
12
|
+
* wrangler deploy
|
|
13
|
+
*
|
|
14
|
+
* Static assets (JS, CSS, fonts) under `.hadars/static/` must be served from
|
|
15
|
+
* R2 or another CDN — the Worker only handles HTML rendering. Route requests
|
|
16
|
+
* for static file extensions to R2 and everything else to the Worker.
|
|
17
|
+
*
|
|
18
|
+
* @example wrangler.toml
|
|
19
|
+
* name = "my-app"
|
|
20
|
+
* main = "cloudflare.mjs"
|
|
21
|
+
* compatibility_date = "2024-09-23"
|
|
22
|
+
* compatibility_flags = ["nodejs_compat"]
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Pre-loaded SSR module and HTML template for single-file Cloudflare bundles
|
|
27
|
+
* produced by `hadars export cloudflare`. All I/O is eliminated at runtime —
|
|
28
|
+
* the Worker is fully self-contained.
|
|
29
|
+
*/
|
|
30
|
+
interface CloudflareBundled {
|
|
31
|
+
/** The compiled SSR module — import it statically in your entry shim. */
|
|
32
|
+
ssrModule: HadarsEntryModule<any>;
|
|
33
|
+
/**
|
|
34
|
+
* The contents of `.hadars/static/out.html` — esbuild inlines this as a
|
|
35
|
+
* string when `hadars export cloudflare` runs.
|
|
36
|
+
*/
|
|
37
|
+
outHtml: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The shape of a Cloudflare Workers export object.
|
|
41
|
+
* Return this as the default export of your Worker entry file.
|
|
42
|
+
*/
|
|
43
|
+
interface CloudflareHandler {
|
|
44
|
+
fetch(request: Request, env: unknown, ctx: unknown): Promise<Response>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a Cloudflare Workers handler from a hadars config and a pre-bundled
|
|
48
|
+
* SSR module. Use this as the default export of your Worker entry.
|
|
49
|
+
*
|
|
50
|
+
* Unlike the Lambda adapter, Cloudflare Workers receive a standard Web
|
|
51
|
+
* `Request` and return a standard `Response` — no event format conversion is
|
|
52
|
+
* required. Static assets must be routed to R2/CDN via wrangler rules; this
|
|
53
|
+
* Worker handles only HTML rendering and API routes.
|
|
54
|
+
*
|
|
55
|
+
* @example — generated entry shim (created by `hadars export cloudflare`)
|
|
56
|
+
* import * as ssrModule from './.hadars/index.ssr.js';
|
|
57
|
+
* import outHtml from './.hadars/static/out.html';
|
|
58
|
+
* import { createCloudflareHandler } from 'hadars/cloudflare';
|
|
59
|
+
* import config from './hadars.config';
|
|
60
|
+
* export default createCloudflareHandler(config, { ssrModule, outHtml });
|
|
61
|
+
*/
|
|
62
|
+
declare function createCloudflareHandler(options: HadarsOptions, bundled: CloudflareBundled): CloudflareHandler;
|
|
63
|
+
|
|
64
|
+
export { type CloudflareBundled, type CloudflareHandler, createCloudflareHandler };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { H as HadarsEntryModule, a as HadarsOptions } from './hadars-mKu5txjW.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cloudflare Workers adapter for hadars.
|
|
5
|
+
*
|
|
6
|
+
* After running `hadars build`, bundle your app with:
|
|
7
|
+
*
|
|
8
|
+
* hadars export cloudflare
|
|
9
|
+
*
|
|
10
|
+
* This produces a self-contained `cloudflare.mjs` that you deploy with:
|
|
11
|
+
*
|
|
12
|
+
* wrangler deploy
|
|
13
|
+
*
|
|
14
|
+
* Static assets (JS, CSS, fonts) under `.hadars/static/` must be served from
|
|
15
|
+
* R2 or another CDN — the Worker only handles HTML rendering. Route requests
|
|
16
|
+
* for static file extensions to R2 and everything else to the Worker.
|
|
17
|
+
*
|
|
18
|
+
* @example wrangler.toml
|
|
19
|
+
* name = "my-app"
|
|
20
|
+
* main = "cloudflare.mjs"
|
|
21
|
+
* compatibility_date = "2024-09-23"
|
|
22
|
+
* compatibility_flags = ["nodejs_compat"]
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Pre-loaded SSR module and HTML template for single-file Cloudflare bundles
|
|
27
|
+
* produced by `hadars export cloudflare`. All I/O is eliminated at runtime —
|
|
28
|
+
* the Worker is fully self-contained.
|
|
29
|
+
*/
|
|
30
|
+
interface CloudflareBundled {
|
|
31
|
+
/** The compiled SSR module — import it statically in your entry shim. */
|
|
32
|
+
ssrModule: HadarsEntryModule<any>;
|
|
33
|
+
/**
|
|
34
|
+
* The contents of `.hadars/static/out.html` — esbuild inlines this as a
|
|
35
|
+
* string when `hadars export cloudflare` runs.
|
|
36
|
+
*/
|
|
37
|
+
outHtml: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The shape of a Cloudflare Workers export object.
|
|
41
|
+
* Return this as the default export of your Worker entry file.
|
|
42
|
+
*/
|
|
43
|
+
interface CloudflareHandler {
|
|
44
|
+
fetch(request: Request, env: unknown, ctx: unknown): Promise<Response>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Creates a Cloudflare Workers handler from a hadars config and a pre-bundled
|
|
48
|
+
* SSR module. Use this as the default export of your Worker entry.
|
|
49
|
+
*
|
|
50
|
+
* Unlike the Lambda adapter, Cloudflare Workers receive a standard Web
|
|
51
|
+
* `Request` and return a standard `Response` — no event format conversion is
|
|
52
|
+
* required. Static assets must be routed to R2/CDN via wrangler rules; this
|
|
53
|
+
* Worker handles only HTML rendering and API routes.
|
|
54
|
+
*
|
|
55
|
+
* @example — generated entry shim (created by `hadars export cloudflare`)
|
|
56
|
+
* import * as ssrModule from './.hadars/index.ssr.js';
|
|
57
|
+
* import outHtml from './.hadars/static/out.html';
|
|
58
|
+
* import { createCloudflareHandler } from 'hadars/cloudflare';
|
|
59
|
+
* import config from './hadars.config';
|
|
60
|
+
* export default createCloudflareHandler(config, { ssrModule, outHtml });
|
|
61
|
+
*/
|
|
62
|
+
declare function createCloudflareHandler(options: HadarsOptions, bundled: CloudflareBundled): CloudflareHandler;
|
|
63
|
+
|
|
64
|
+
export { type CloudflareBundled, type CloudflareHandler, createCloudflareHandler };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildHeadHtml,
|
|
3
|
+
buildSsrHtml,
|
|
4
|
+
createProxyHandler,
|
|
5
|
+
createRenderCache,
|
|
6
|
+
getReactResponse,
|
|
7
|
+
makePrecontentHtmlGetter,
|
|
8
|
+
parseRequest
|
|
9
|
+
} from "./chunk-H72BZXOA.js";
|
|
10
|
+
import "./chunk-LY5MTHFV.js";
|
|
11
|
+
import "./chunk-OS3V4CPN.js";
|
|
12
|
+
|
|
13
|
+
// src/cloudflare.ts
|
|
14
|
+
import "react";
|
|
15
|
+
function createCloudflareHandler(options, bundled) {
|
|
16
|
+
const fetchHandler = options.fetch;
|
|
17
|
+
const handleProxy = createProxyHandler(options);
|
|
18
|
+
const getPrecontentHtml = makePrecontentHtmlGetter(Promise.resolve(bundled.outHtml));
|
|
19
|
+
const { ssrModule } = bundled;
|
|
20
|
+
const runHandler = async (req) => {
|
|
21
|
+
const request = parseRequest(req);
|
|
22
|
+
if (fetchHandler) {
|
|
23
|
+
const res = await fetchHandler(request);
|
|
24
|
+
if (res) return res;
|
|
25
|
+
}
|
|
26
|
+
const proxied = await handleProxy(request);
|
|
27
|
+
if (proxied) return proxied;
|
|
28
|
+
try {
|
|
29
|
+
const { default: Component, getInitProps, getFinalProps } = ssrModule;
|
|
30
|
+
const { head, status, getAppBody, finalize } = await getReactResponse(request, {
|
|
31
|
+
document: {
|
|
32
|
+
body: Component,
|
|
33
|
+
lang: "en",
|
|
34
|
+
getInitProps,
|
|
35
|
+
getFinalProps
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (request.headers.get("Accept") === "application/json") {
|
|
39
|
+
const { clientProps: clientProps2 } = await finalize();
|
|
40
|
+
const serverData = clientProps2.__serverData ?? {};
|
|
41
|
+
return new Response(JSON.stringify({ serverData }), {
|
|
42
|
+
status,
|
|
43
|
+
headers: { "Content-Type": "application/json; charset=utf-8" }
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const bodyHtml = await getAppBody();
|
|
47
|
+
const { clientProps } = await finalize();
|
|
48
|
+
const headHtml = buildHeadHtml(head);
|
|
49
|
+
const html = await buildSsrHtml(bodyHtml, clientProps, headHtml, getPrecontentHtml);
|
|
50
|
+
return new Response(html, {
|
|
51
|
+
status,
|
|
52
|
+
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
53
|
+
});
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.error("[hadars] SSR render error:", err);
|
|
56
|
+
return new Response("Internal Server Error", { status: 500 });
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const finalFetch = options.cache ? createRenderCache(options.cache, (req) => runHandler(req)) : (req) => runHandler(req);
|
|
60
|
+
return {
|
|
61
|
+
fetch: async (request, _env, ctx) => {
|
|
62
|
+
return await finalFetch(request, ctx) ?? new Response("Not Found", { status: 404 });
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export {
|
|
67
|
+
createCloudflareHandler
|
|
68
|
+
};
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* In-process GraphQL executor passed to `getInitProps` and `paths` during
|
|
3
|
+
* `hadars export static`. Hadars is executor-agnostic — configure it in
|
|
4
|
+
* `hadars.config.ts` using any GraphQL library (e.g. `graphql-js`):
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { graphql as gql, buildSchema } from 'graphql';
|
|
8
|
+
* const schema = buildSchema(`type Query { hello: String }`);
|
|
9
|
+
* const rootValue = { hello: () => 'world' };
|
|
10
|
+
*
|
|
11
|
+
* export default {
|
|
12
|
+
* graphql: (query, variables) =>
|
|
13
|
+
* gql({ schema, rootValue, source: query, variableValues: variables }),
|
|
14
|
+
* } satisfies HadarsOptions;
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
type GraphQLExecutor = (query: string, variables?: Record<string, unknown>) => Promise<{
|
|
18
|
+
data?: any;
|
|
19
|
+
errors?: ReadonlyArray<{
|
|
20
|
+
message: string;
|
|
21
|
+
}>;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Context passed as the second argument to `getInitProps` and `paths`
|
|
25
|
+
* during `hadars export static`. Not present in dev/run mode.
|
|
26
|
+
*/
|
|
27
|
+
interface HadarsStaticContext {
|
|
28
|
+
graphql: GraphQLExecutor;
|
|
29
|
+
}
|
|
30
|
+
type HadarsGetInitialProps<T extends {}> = (req: HadarsRequest, ctx?: HadarsStaticContext) => Promise<T> | T;
|
|
4
31
|
type HadarsGetClientProps<T extends {}> = (props: T) => Promise<T> | T;
|
|
5
32
|
type HadarsGetFinalProps<T extends {}> = (props: HadarsProps<T>) => Promise<T> | T;
|
|
6
33
|
type HadarsApp<T extends {}> = React.FC<HadarsProps<T>>;
|
|
@@ -10,43 +37,10 @@ type HadarsEntryModule<T extends {}> = {
|
|
|
10
37
|
getFinalProps?: HadarsGetFinalProps<T>;
|
|
11
38
|
getClientProps?: HadarsGetClientProps<T>;
|
|
12
39
|
};
|
|
13
|
-
interface AppHead {
|
|
14
|
-
title: string;
|
|
15
|
-
status: number;
|
|
16
|
-
meta: Record<string, MetaProps>;
|
|
17
|
-
link: Record<string, LinkProps>;
|
|
18
|
-
style: Record<string, StyleProps>;
|
|
19
|
-
script: Record<string, ScriptProps>;
|
|
20
|
-
}
|
|
21
|
-
type UnsuspendEntry = {
|
|
22
|
-
status: 'pending';
|
|
23
|
-
promise: Promise<unknown>;
|
|
24
|
-
} | {
|
|
25
|
-
status: 'fulfilled';
|
|
26
|
-
value: unknown;
|
|
27
|
-
} | {
|
|
28
|
-
status: 'rejected';
|
|
29
|
-
reason: unknown;
|
|
30
|
-
};
|
|
31
|
-
/** @internal Populated by the framework's render loop — use useServerData() instead. */
|
|
32
|
-
interface AppUnsuspend {
|
|
33
|
-
cache: Map<string, UnsuspendEntry>;
|
|
34
|
-
}
|
|
35
|
-
interface AppContext {
|
|
36
|
-
path?: string;
|
|
37
|
-
head: AppHead;
|
|
38
|
-
/** @internal Framework use only — use the useServerData() hook instead. */
|
|
39
|
-
_unsuspend?: AppUnsuspend;
|
|
40
|
-
}
|
|
41
40
|
type HadarsEntryBase = {
|
|
42
41
|
location: string;
|
|
43
|
-
context: AppContext;
|
|
44
42
|
};
|
|
45
43
|
type HadarsProps<T extends {}> = T & HadarsEntryBase;
|
|
46
|
-
type MetaProps = MetaHTMLAttributes<HTMLMetaElement>;
|
|
47
|
-
type LinkProps = LinkHTMLAttributes<HTMLLinkElement>;
|
|
48
|
-
type StyleProps = StyleHTMLAttributes<HTMLStyleElement>;
|
|
49
|
-
type ScriptProps = ScriptHTMLAttributes<HTMLScriptElement>;
|
|
50
44
|
interface HadarsOptions {
|
|
51
45
|
port?: number;
|
|
52
46
|
entry: string;
|
|
@@ -183,6 +177,68 @@ interface HadarsOptions {
|
|
|
183
177
|
key: string;
|
|
184
178
|
ttl?: number;
|
|
185
179
|
} | null | undefined>;
|
|
180
|
+
/**
|
|
181
|
+
* Static export path list. Required for `hadars export static`.
|
|
182
|
+
*
|
|
183
|
+
* Return an array of URL paths (e.g. `['/', '/about', '/blog/hello']`) that
|
|
184
|
+
* should be pre-rendered to HTML files. May be async.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* paths: () => ['/', '/about', '/contact']
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* paths: async () => {
|
|
191
|
+
* const posts = await fetchBlogPosts();
|
|
192
|
+
* return ['/', ...posts.map(p => `/blog/${p.slug}`)];
|
|
193
|
+
* }
|
|
194
|
+
*/
|
|
195
|
+
/**
|
|
196
|
+
* In-process GraphQL executor. Supply this to use the GraphQL data layer
|
|
197
|
+
* in `paths` and `getInitProps` during `hadars export static`.
|
|
198
|
+
* Has no effect in `dev` / `run` mode.
|
|
199
|
+
*/
|
|
200
|
+
graphql?: GraphQLExecutor;
|
|
201
|
+
paths?: (ctx: HadarsStaticContext) => Promise<string[]> | string[];
|
|
202
|
+
/**
|
|
203
|
+
* Gatsby-compatible source plugins to run before `hadars export static`.
|
|
204
|
+
*
|
|
205
|
+
* Each entry mirrors Gatsby's `gatsby-config.js` plugin object format:
|
|
206
|
+
* `{ resolve: 'gatsby-source-contentful', options: { spaceId: '...', accessToken: '...' } }`
|
|
207
|
+
*
|
|
208
|
+
* The plugin must export a `sourceNodes` function with the standard Gatsby API.
|
|
209
|
+
* Hadars provides a thin shim covering the most-used surface:
|
|
210
|
+
* `actions.createNode`, `createNodeId`, `createContentDigest`, `cache`, `reporter`,
|
|
211
|
+
* `getNode`, `getNodes`, `getNodesByType`.
|
|
212
|
+
*
|
|
213
|
+
* After all sources have run, hadars auto-generates a GraphQL schema from the
|
|
214
|
+
* collected nodes and makes it available via `config.graphql` in `getInitProps`
|
|
215
|
+
* and `paths`. Requires `graphql` to be installed in the project.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* sources: [
|
|
219
|
+
* {
|
|
220
|
+
* resolve: 'gatsby-source-filesystem',
|
|
221
|
+
* options: { name: 'posts', path: './content/posts' },
|
|
222
|
+
* },
|
|
223
|
+
* ]
|
|
224
|
+
*/
|
|
225
|
+
sources?: HadarsSourceEntry[];
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* A Gatsby-compatible source plugin entry, matching the format used in
|
|
229
|
+
* `gatsby-config.js` / `gatsby-config.ts`.
|
|
230
|
+
*/
|
|
231
|
+
interface HadarsSourceEntry {
|
|
232
|
+
/**
|
|
233
|
+
* Package name (e.g. `'gatsby-source-contentful'`) or a pre-imported module
|
|
234
|
+
* object that exports `sourceNodes`. Using a module object lets you pass
|
|
235
|
+
* local source plugins without publishing them to npm.
|
|
236
|
+
*/
|
|
237
|
+
resolve: string | {
|
|
238
|
+
sourceNodes?: (ctx: any, opts?: any) => Promise<void> | void;
|
|
239
|
+
};
|
|
240
|
+
/** Plugin options forwarded as the second argument to `sourceNodes`. */
|
|
241
|
+
options?: Record<string, unknown>;
|
|
186
242
|
}
|
|
187
243
|
type SwcPluginItem = string | [string, Record<string, unknown>] | {
|
|
188
244
|
path: string;
|
|
@@ -196,4 +252,4 @@ interface HadarsRequest extends Request {
|
|
|
196
252
|
cookies: Record<string, string>;
|
|
197
253
|
}
|
|
198
254
|
|
|
199
|
-
export type {
|
|
255
|
+
export type { GraphQLExecutor as G, HadarsEntryModule as H, HadarsOptions as a, HadarsApp as b, HadarsGetClientProps as c, HadarsGetFinalProps as d, HadarsGetInitialProps as e, HadarsProps as f, HadarsRequest as g, HadarsSourceEntry as h, HadarsStaticContext as i };
|
|
@@ -1,6 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* In-process GraphQL executor passed to `getInitProps` and `paths` during
|
|
3
|
+
* `hadars export static`. Hadars is executor-agnostic — configure it in
|
|
4
|
+
* `hadars.config.ts` using any GraphQL library (e.g. `graphql-js`):
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { graphql as gql, buildSchema } from 'graphql';
|
|
8
|
+
* const schema = buildSchema(`type Query { hello: String }`);
|
|
9
|
+
* const rootValue = { hello: () => 'world' };
|
|
10
|
+
*
|
|
11
|
+
* export default {
|
|
12
|
+
* graphql: (query, variables) =>
|
|
13
|
+
* gql({ schema, rootValue, source: query, variableValues: variables }),
|
|
14
|
+
* } satisfies HadarsOptions;
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
type GraphQLExecutor = (query: string, variables?: Record<string, unknown>) => Promise<{
|
|
18
|
+
data?: any;
|
|
19
|
+
errors?: ReadonlyArray<{
|
|
20
|
+
message: string;
|
|
21
|
+
}>;
|
|
22
|
+
}>;
|
|
23
|
+
/**
|
|
24
|
+
* Context passed as the second argument to `getInitProps` and `paths`
|
|
25
|
+
* during `hadars export static`. Not present in dev/run mode.
|
|
26
|
+
*/
|
|
27
|
+
interface HadarsStaticContext {
|
|
28
|
+
graphql: GraphQLExecutor;
|
|
29
|
+
}
|
|
30
|
+
type HadarsGetInitialProps<T extends {}> = (req: HadarsRequest, ctx?: HadarsStaticContext) => Promise<T> | T;
|
|
4
31
|
type HadarsGetClientProps<T extends {}> = (props: T) => Promise<T> | T;
|
|
5
32
|
type HadarsGetFinalProps<T extends {}> = (props: HadarsProps<T>) => Promise<T> | T;
|
|
6
33
|
type HadarsApp<T extends {}> = React.FC<HadarsProps<T>>;
|
|
@@ -10,43 +37,10 @@ type HadarsEntryModule<T extends {}> = {
|
|
|
10
37
|
getFinalProps?: HadarsGetFinalProps<T>;
|
|
11
38
|
getClientProps?: HadarsGetClientProps<T>;
|
|
12
39
|
};
|
|
13
|
-
interface AppHead {
|
|
14
|
-
title: string;
|
|
15
|
-
status: number;
|
|
16
|
-
meta: Record<string, MetaProps>;
|
|
17
|
-
link: Record<string, LinkProps>;
|
|
18
|
-
style: Record<string, StyleProps>;
|
|
19
|
-
script: Record<string, ScriptProps>;
|
|
20
|
-
}
|
|
21
|
-
type UnsuspendEntry = {
|
|
22
|
-
status: 'pending';
|
|
23
|
-
promise: Promise<unknown>;
|
|
24
|
-
} | {
|
|
25
|
-
status: 'fulfilled';
|
|
26
|
-
value: unknown;
|
|
27
|
-
} | {
|
|
28
|
-
status: 'rejected';
|
|
29
|
-
reason: unknown;
|
|
30
|
-
};
|
|
31
|
-
/** @internal Populated by the framework's render loop — use useServerData() instead. */
|
|
32
|
-
interface AppUnsuspend {
|
|
33
|
-
cache: Map<string, UnsuspendEntry>;
|
|
34
|
-
}
|
|
35
|
-
interface AppContext {
|
|
36
|
-
path?: string;
|
|
37
|
-
head: AppHead;
|
|
38
|
-
/** @internal Framework use only — use the useServerData() hook instead. */
|
|
39
|
-
_unsuspend?: AppUnsuspend;
|
|
40
|
-
}
|
|
41
40
|
type HadarsEntryBase = {
|
|
42
41
|
location: string;
|
|
43
|
-
context: AppContext;
|
|
44
42
|
};
|
|
45
43
|
type HadarsProps<T extends {}> = T & HadarsEntryBase;
|
|
46
|
-
type MetaProps = MetaHTMLAttributes<HTMLMetaElement>;
|
|
47
|
-
type LinkProps = LinkHTMLAttributes<HTMLLinkElement>;
|
|
48
|
-
type StyleProps = StyleHTMLAttributes<HTMLStyleElement>;
|
|
49
|
-
type ScriptProps = ScriptHTMLAttributes<HTMLScriptElement>;
|
|
50
44
|
interface HadarsOptions {
|
|
51
45
|
port?: number;
|
|
52
46
|
entry: string;
|
|
@@ -183,6 +177,68 @@ interface HadarsOptions {
|
|
|
183
177
|
key: string;
|
|
184
178
|
ttl?: number;
|
|
185
179
|
} | null | undefined>;
|
|
180
|
+
/**
|
|
181
|
+
* Static export path list. Required for `hadars export static`.
|
|
182
|
+
*
|
|
183
|
+
* Return an array of URL paths (e.g. `['/', '/about', '/blog/hello']`) that
|
|
184
|
+
* should be pre-rendered to HTML files. May be async.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* paths: () => ['/', '/about', '/contact']
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* paths: async () => {
|
|
191
|
+
* const posts = await fetchBlogPosts();
|
|
192
|
+
* return ['/', ...posts.map(p => `/blog/${p.slug}`)];
|
|
193
|
+
* }
|
|
194
|
+
*/
|
|
195
|
+
/**
|
|
196
|
+
* In-process GraphQL executor. Supply this to use the GraphQL data layer
|
|
197
|
+
* in `paths` and `getInitProps` during `hadars export static`.
|
|
198
|
+
* Has no effect in `dev` / `run` mode.
|
|
199
|
+
*/
|
|
200
|
+
graphql?: GraphQLExecutor;
|
|
201
|
+
paths?: (ctx: HadarsStaticContext) => Promise<string[]> | string[];
|
|
202
|
+
/**
|
|
203
|
+
* Gatsby-compatible source plugins to run before `hadars export static`.
|
|
204
|
+
*
|
|
205
|
+
* Each entry mirrors Gatsby's `gatsby-config.js` plugin object format:
|
|
206
|
+
* `{ resolve: 'gatsby-source-contentful', options: { spaceId: '...', accessToken: '...' } }`
|
|
207
|
+
*
|
|
208
|
+
* The plugin must export a `sourceNodes` function with the standard Gatsby API.
|
|
209
|
+
* Hadars provides a thin shim covering the most-used surface:
|
|
210
|
+
* `actions.createNode`, `createNodeId`, `createContentDigest`, `cache`, `reporter`,
|
|
211
|
+
* `getNode`, `getNodes`, `getNodesByType`.
|
|
212
|
+
*
|
|
213
|
+
* After all sources have run, hadars auto-generates a GraphQL schema from the
|
|
214
|
+
* collected nodes and makes it available via `config.graphql` in `getInitProps`
|
|
215
|
+
* and `paths`. Requires `graphql` to be installed in the project.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* sources: [
|
|
219
|
+
* {
|
|
220
|
+
* resolve: 'gatsby-source-filesystem',
|
|
221
|
+
* options: { name: 'posts', path: './content/posts' },
|
|
222
|
+
* },
|
|
223
|
+
* ]
|
|
224
|
+
*/
|
|
225
|
+
sources?: HadarsSourceEntry[];
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* A Gatsby-compatible source plugin entry, matching the format used in
|
|
229
|
+
* `gatsby-config.js` / `gatsby-config.ts`.
|
|
230
|
+
*/
|
|
231
|
+
interface HadarsSourceEntry {
|
|
232
|
+
/**
|
|
233
|
+
* Package name (e.g. `'gatsby-source-contentful'`) or a pre-imported module
|
|
234
|
+
* object that exports `sourceNodes`. Using a module object lets you pass
|
|
235
|
+
* local source plugins without publishing them to npm.
|
|
236
|
+
*/
|
|
237
|
+
resolve: string | {
|
|
238
|
+
sourceNodes?: (ctx: any, opts?: any) => Promise<void> | void;
|
|
239
|
+
};
|
|
240
|
+
/** Plugin options forwarded as the second argument to `sourceNodes`. */
|
|
241
|
+
options?: Record<string, unknown>;
|
|
186
242
|
}
|
|
187
243
|
type SwcPluginItem = string | [string, Record<string, unknown>] | {
|
|
188
244
|
path: string;
|
|
@@ -196,4 +252,4 @@ interface HadarsRequest extends Request {
|
|
|
196
252
|
cookies: Record<string, string>;
|
|
197
253
|
}
|
|
198
254
|
|
|
199
|
-
export type {
|
|
255
|
+
export type { GraphQLExecutor as G, HadarsEntryModule as H, HadarsOptions as a, HadarsApp as b, HadarsGetClientProps as c, HadarsGetFinalProps as d, HadarsGetInitialProps as e, HadarsProps as f, HadarsRequest as g, HadarsSourceEntry as h, HadarsStaticContext as i };
|