@coherent.js/integrations 1.1.0 → 2.0.0-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.
@@ -0,0 +1,97 @@
1
+ // Type definitions for Coherent.js Koa integration.
2
+ //
3
+ // Aligned with the runtime exports of ../../src/koa/coherent-koa.js. Koa's
4
+ // own types come from @types/koa.
5
+
6
+ import type { Middleware, Next, ParameterizedContext } from 'koa';
7
+ import type { CoherentNode } from '@coherent.js/core';
8
+
9
+ export interface CoherentKoaRenderOptions {
10
+ /**
11
+ * Enable performance monitoring for rendered components
12
+ * @default false
13
+ */
14
+ enablePerformanceMonitoring?: boolean;
15
+
16
+ /**
17
+ * HTML template with a `{{content}}` placeholder
18
+ * @default '<!DOCTYPE html>\n{{content}}'
19
+ */
20
+ template?: string;
21
+ }
22
+
23
+ export interface CoherentKoaMiddlewareOptions extends CoherentKoaRenderOptions {
24
+ /**
25
+ * Also render any component-shaped `ctx.body` once downstream middleware
26
+ * has finished.
27
+ *
28
+ * Detection is a heuristic: every single-key object qualifies, so JSON
29
+ * bodies such as `{ ok: true }` would be rendered as HTML. Use
30
+ * `ctx.coherent(component)` instead unless the app never responds with
31
+ * single-key JSON objects.
32
+ * @default false
33
+ */
34
+ autoRender?: boolean;
35
+ }
36
+
37
+ export interface SetupCoherentKoaOptions extends CoherentKoaMiddlewareOptions {
38
+ /**
39
+ * Install {@link coherentKoaMiddleware}
40
+ * @default true
41
+ */
42
+ useMiddleware?: boolean;
43
+ }
44
+
45
+ /** Anything with Koa's `use()`, i.e. a Koa application. */
46
+ export interface KoaAppLike {
47
+ use(middleware: Middleware<any, any>): unknown;
48
+ }
49
+
50
+ /**
51
+ * Koa middleware that adds `ctx.coherent(component, options?)` and, with
52
+ * `autoRender`, renders component-shaped `ctx.body` values.
53
+ */
54
+ export function coherentKoaMiddleware(options?: CoherentKoaMiddlewareOptions): Middleware;
55
+
56
+ /**
57
+ * Create a Koa middleware that renders the component returned by the factory
58
+ * into `ctx.body` as `text/html`.
59
+ */
60
+ export function createHandler<Ctx extends ParameterizedContext = ParameterizedContext>(
61
+ componentFactory: (ctx: Ctx, next: Next) => CoherentNode | Promise<CoherentNode>,
62
+ options?: CoherentKoaRenderOptions
63
+ ): (ctx: Ctx, next: Next) => Promise<void>;
64
+
65
+ /**
66
+ * Install {@link coherentKoaMiddleware} on a Koa app. Every option except
67
+ * `useMiddleware` is forwarded to the middleware.
68
+ */
69
+ export function setupCoherent(app: KoaAppLike, options?: SetupCoherentKoaOptions): void;
70
+
71
+ /**
72
+ * Verify Koa is installed, then return a function that applies
73
+ * {@link setupCoherent} to an app and returns it.
74
+ */
75
+ export function createKoaIntegration(
76
+ options?: SetupCoherentKoaOptions
77
+ ): Promise<<App extends KoaAppLike>(app: App) => App>;
78
+
79
+ declare module 'koa' {
80
+ interface DefaultContext {
81
+ /**
82
+ * Render a Coherent.js component (wrapped in the middleware's template)
83
+ * into `ctx.body` as `text/html` and return the HTML. Rendering errors
84
+ * are thrown. Added by `coherentKoaMiddleware()` / `setupCoherent()`.
85
+ */
86
+ coherent(component: CoherentNode, options?: CoherentKoaRenderOptions): string;
87
+ }
88
+ }
89
+
90
+ declare const coherentKoa: {
91
+ coherentKoaMiddleware: typeof coherentKoaMiddleware;
92
+ createHandler: typeof createHandler;
93
+ setupCoherent: typeof setupCoherent;
94
+ createKoaIntegration: typeof createKoaIntegration;
95
+ };
96
+
97
+ export default coherentKoa;
@@ -34,6 +34,21 @@ export interface CoherentNextComponentOptions {
34
34
  * @default false
35
35
  */
36
36
  enablePerformanceMonitoring?: boolean;
37
+
38
+ /**
39
+ * React module to build elements with (`import * as React from 'react'`).
40
+ * Defaults to importing `react` from `@coherent.js/integrations`, which
41
+ * resolves to the app's copy through the optional peer dependency.
42
+ */
43
+ React?: { createElement: (...args: any[]) => any } | { default: { createElement: (...args: any[]) => any } };
44
+ }
45
+
46
+ /**
47
+ * Second argument Next.js passes to App Router route handlers.
48
+ * `params` is a Promise from Next.js 15 on, a plain object before.
49
+ */
50
+ export interface CoherentAppRouteContext {
51
+ params: Record<string, string | string[]> | Promise<Record<string, string | string[]>>;
37
52
  }
38
53
 
39
54
  export interface CoherentNextIntegration {
@@ -59,14 +74,17 @@ export function createCoherentNextHandler(
59
74
 
60
75
  /**
61
76
  * Create a Next.js App Router route handler for Coherent.js components
62
- * @param componentFactory Function that returns a Coherent component
77
+ * @param componentFactory Function that returns a Coherent component; it
78
+ * receives the route handler's `(request, context)`
63
79
  * @param options Configuration options
64
80
  * @returns Next.js App Router handler
65
81
  */
66
- export function createCoherentAppRouterHandler(
67
- componentFactory: (request: Request) => CoherentNode | Promise<CoherentNode>,
82
+ export function createCoherentAppRouterHandler<
83
+ Context extends CoherentAppRouteContext = CoherentAppRouteContext
84
+ >(
85
+ componentFactory: (request: Request, context: Context) => CoherentNode | Promise<CoherentNode>,
68
86
  options?: CoherentNextHandlerOptions
69
- ): (request: Request) => Promise<Response>;
87
+ ): (request: Request, context: Context) => Promise<Response>;
70
88
 
71
89
  /**
72
90
  * Create a Next.js Server Component for Coherent.js
@@ -0,0 +1,68 @@
1
+ // Type definitions for Coherent.js Remix integration.
2
+ //
3
+ // Aligned with the runtime exports of ../../src/remix/index.js.
4
+
5
+ import type { ReactElement } from 'react';
6
+ import type { CoherentNode } from '@coherent.js/core';
7
+
8
+ /** A Coherent.js component: a node, or a function of props returning one. */
9
+ export type CoherentRemixComponent<Props = any> = CoherentNode | ((props: Props) => CoherentNode);
10
+
11
+ /** The arguments Remix passes to loaders and actions. */
12
+ export interface CoherentRemixDataArgs {
13
+ request: Request;
14
+ params: Record<string, string | undefined>;
15
+ context: unknown;
16
+ }
17
+
18
+ export interface CoherentRemixActionArgs extends CoherentRemixDataArgs {
19
+ /** The submitted form fields (`Object.fromEntries(await request.formData())`). */
20
+ data: Record<string, FormDataEntryValue>;
21
+ }
22
+
23
+ export interface CoherentRemixAdapterOptions {
24
+ /** Enable client-side hydration. */
25
+ hydrate?: boolean;
26
+ }
27
+
28
+ export interface CoherentRemixAdapter {
29
+ /** Render a component (or component function) to an HTML string. */
30
+ renderComponent<Props>(component: CoherentRemixComponent<Props>, props?: Props): string;
31
+
32
+ /**
33
+ * Create a loader that answers with the rendered component as `text/html`.
34
+ * Without `getProps` the component receives `{ request, params }`.
35
+ */
36
+ createLoader<Props>(
37
+ component: CoherentRemixComponent<Props>,
38
+ getProps?: (args: CoherentRemixDataArgs) => Props | Promise<Props>
39
+ ): (args: CoherentRemixDataArgs) => Promise<Response>;
40
+
41
+ /**
42
+ * Create an action that passes the submitted form to `handler` and renders
43
+ * the component with its result, unless the handler returns a Response.
44
+ */
45
+ createAction<Result>(
46
+ component: CoherentRemixComponent<Result>,
47
+ handler: (args: CoherentRemixActionArgs) => Result | Response | Promise<Result | Response>
48
+ ): (args: CoherentRemixDataArgs) => Promise<Response>;
49
+ }
50
+
51
+ export function createRemixAdapter(options?: CoherentRemixAdapterOptions): CoherentRemixAdapter;
52
+
53
+ export interface WithCoherentOptions {
54
+ /**
55
+ * Tag name of the element the markup is rendered into
56
+ * @default 'div'
57
+ */
58
+ as?: string;
59
+ }
60
+
61
+ /**
62
+ * Wrap a Coherent.js component as a React component for Remix routes. The
63
+ * markup is rendered inside a wrapper element via `dangerouslySetInnerHTML`.
64
+ */
65
+ export function withCoherent<Props = any>(
66
+ Component: CoherentRemixComponent<Props>,
67
+ options?: WithCoherentOptions
68
+ ): (props: Props) => ReactElement;
@@ -0,0 +1,68 @@
1
+ // Type definitions for Coherent.js SvelteKit integration.
2
+ //
3
+ // Aligned with the runtime exports of ../../src/sveltekit/index.js.
4
+
5
+ import type { Handle } from '@sveltejs/kit';
6
+ import type { CoherentNode } from '@coherent.js/core';
7
+
8
+ /** A Coherent.js component: a node, or a function of props returning one. */
9
+ export type CoherentSvelteKitComponent<Props = any> = CoherentNode | ((props: Props) => CoherentNode);
10
+
11
+ export interface CoherentSvelteKitLoadEvent {
12
+ params: Record<string, string>;
13
+ url: URL;
14
+ fetch: typeof fetch;
15
+ }
16
+
17
+ export interface CoherentSvelteKitAdapter {
18
+ name: string;
19
+
20
+ /** Render a component (or component function) to an HTML string. */
21
+ renderComponent<Props>(component: CoherentSvelteKitComponent<Props>, props?: Props): string;
22
+
23
+ /**
24
+ * Create a server `load` function returning the rendered HTML and the props.
25
+ * Without `getProps` the component receives `{ params }`.
26
+ */
27
+ createLoad<Props>(
28
+ component: CoherentSvelteKitComponent<Props>,
29
+ getProps?: (event: CoherentSvelteKitLoadEvent) => Props | Promise<Props>
30
+ ): (event: CoherentSvelteKitLoadEvent) => Promise<{ html: string; props: Props }>;
31
+
32
+ /** Create a form action that passes the submitted fields to `handler`. */
33
+ createAction<Result>(
34
+ handler: (args: { data: Record<string, FormDataEntryValue>; params: Record<string, string> }) => Result
35
+ ): (event: { request: Request; params: Record<string, string> }) => Promise<Awaited<Result>>;
36
+ }
37
+
38
+ export function createSvelteKitAdapter(options?: Record<string, unknown>): CoherentSvelteKitAdapter;
39
+
40
+ export interface CoherentPreprocessorOptions {
41
+ /**
42
+ * Tag whose content (a JS expression, usually an object literal) is
43
+ * rendered with Coherent.js
44
+ * @default 'coherent'
45
+ */
46
+ tag?: string;
47
+ }
48
+
49
+ /**
50
+ * Svelte markup preprocessor: replaces `<coherent>{...}</coherent>` blocks
51
+ * with `{@html ...}` of the rendered component and imports the renderer from
52
+ * `@coherent.js/core` into the component.
53
+ */
54
+ export function createPreprocessor(options?: CoherentPreprocessorOptions): {
55
+ name: string;
56
+ markup(input: { content: string; filename?: string }): { code: string; map: null };
57
+ };
58
+
59
+ /** What {@link createHandle} puts on `event.locals.coherent`. */
60
+ export interface CoherentLocals {
61
+ render<Props>(component: CoherentSvelteKitComponent<Props>, props?: Props): string;
62
+ }
63
+
64
+ /**
65
+ * SvelteKit `handle` hook that sets `event.locals.coherent` (see
66
+ * {@link CoherentLocals}; add it to `App.Locals` in your `app.d.ts`).
67
+ */
68
+ export function createHandle(options?: Record<string, unknown>): Handle;