@pylonsync/react 0.4.29 → 0.5.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/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export { Form } from "./Form";
10
10
  export type { FormProps } from "./Form";
11
11
  export { ImageResponse, isImageResponse } from "./image-response";
12
12
  export type { ImageResponseOptions, ImageResponseFont, } from "./image-response";
13
- export type { PageProps, PageAuth, ServerData, SsrResponse, SsrCookieOptions, Metadata, GenerateMetadata, Sitemap, SitemapEntry, Robots, RobotsRule, RouteSegmentConfig, ErrorBoundaryProps, NotFoundProps, FormFields, FormDb, FormRequest, RouteHandler, RawRouteHandler, RawResponse, } from "./ssr";
13
+ export type { PageProps, PageAuth, ServerData, SsrResponse, SsrCookieOptions, Metadata, GenerateMetadata, Sitemap, SitemapEntry, Robots, RobotsRule, LlmsTxt, LlmsSection, LlmsLink, RouteSegmentConfig, ErrorBoundaryProps, NotFoundProps, FormFields, FormDb, FormRequest, RouteHandler, RawRouteHandler, RawResponse, } from "./ssr";
14
14
  export { useRouter, useSearchParams, usePathname, useParams, useRouteSeed, useRouteData, redirect, notFound, NotFoundError, } from "./useRouter";
15
15
  export type { PylonRouter } from "./useRouter";
16
16
  import { type Storage as PylonStorage } from "@pylonsync/sync";
package/dist/ssr.d.ts CHANGED
@@ -280,6 +280,47 @@ export interface Robots {
280
280
  sitemap?: string | string[];
281
281
  host?: string;
282
282
  }
283
+ /** One link in an `llms.txt` section. */
284
+ export interface LlmsLink {
285
+ title: string;
286
+ url: string;
287
+ /** Short note after the link — what an agent finds there. */
288
+ notes?: string;
289
+ }
290
+ /** An H2-delimited section of file links in `llms.txt`. */
291
+ export interface LlmsSection {
292
+ title: string;
293
+ links: LlmsLink[];
294
+ }
295
+ /**
296
+ * Return type for an `app/llms.ts` default export. The runtime serializes it
297
+ * to `/llms.txt` in <https://llmstxt.org> format — the file an agent reads
298
+ * first to decide what this site is and which pages are worth its context.
299
+ * Sync or async, like `sitemap`/`robots`.
300
+ *
301
+ * export default function llms(): LlmsTxt {
302
+ * return {
303
+ * title: "Acme",
304
+ * summary: "Invoicing for freelancers. Free tier, self-serve API keys.",
305
+ * details: "Use Acme when you need to issue an invoice and collect payment.",
306
+ * sections: [
307
+ * { title: "Docs", links: [{ title: "API", url: "https://acme.com/docs/api", notes: "REST + webhooks" }] },
308
+ * ],
309
+ * };
310
+ * }
311
+ *
312
+ * The element order is the spec's, and it matters: an H1 title, a blockquote
313
+ * summary, prose with NO headings, then H2 sections of links.
314
+ */
315
+ export interface LlmsTxt {
316
+ /** H1 — the site or project name. The one required element. */
317
+ title: string;
318
+ /** The blockquote under it: what this is, in one or two sentences. */
319
+ summary?: string;
320
+ /** Prose paragraphs before the first section. Headings are not allowed. */
321
+ details?: string | string[];
322
+ sections?: LlmsSection[];
323
+ }
283
324
  /**
284
325
  * Per-route configuration, declared as top-level `export const` in a
285
326
  * `page.tsx` (Next-shaped). All optional. The runtime reads these statically
@@ -312,6 +353,20 @@ export interface RouteSegmentConfig {
312
353
  revalidate?: number;
313
354
  dynamic?: "force-static" | "force-dynamic";
314
355
  streaming?: boolean;
356
+ /**
357
+ * Opt this route OUT of its markdown representation.
358
+ *
359
+ * Every SSR page is readable as markdown by default — through
360
+ * `Accept: text/markdown` on its own URL, or at `<path>.md`. Set `false` for
361
+ * a route whose value is the interaction rather than the prose (a dashboard,
362
+ * an editor, an app shell): a client that also accepts HTML then gets the
363
+ * HTML, one that accepts only markdown gets a 406, and the `.md` URL 404s.
364
+ *
365
+ * ```ts
366
+ * export const markdown = false;
367
+ * ```
368
+ */
369
+ markdown?: boolean;
315
370
  }
316
371
  /**
317
372
  * Props an `app/.../error.tsx` boundary receives. Error boundaries are now
@@ -390,6 +445,14 @@ export interface FormDb extends ServerData {
390
445
  */
391
446
  export interface FormRequest<TParams extends Record<string, string> = Record<string, string>, TSearchParams extends Record<string, string> = Record<string, string>> {
392
447
  form: FormFields;
448
+ /**
449
+ * The raw request body, exactly as sent. Empty for GET.
450
+ *
451
+ * `form` only carries PARSED fields, which the runtime produces for
452
+ * `application/x-www-form-urlencoded` bodies. Read `body` for a JSON API, a
453
+ * JSON-RPC endpoint, or a webhook whose signature covers the exact bytes.
454
+ */
455
+ body: string;
393
456
  params: TParams;
394
457
  searchParams: TSearchParams;
395
458
  auth: PageAuth;
@@ -398,8 +461,25 @@ export interface FormRequest<TParams extends Record<string, string> = Record<str
398
461
  db: FormDb;
399
462
  response: SsrResponse;
400
463
  }
401
- /** Signature of a `route.ts` method handler export (POST/PUT/PATCH/DELETE). */
402
- export type RouteHandler<TParams extends Record<string, string> = Record<string, string>, TSearchParams extends Record<string, string> = Record<string, string>> = (req: FormRequest<TParams, TSearchParams>) => void | Promise<void>;
464
+ /**
465
+ * Signature of a `route.ts` method handler export (POST/PUT/PATCH/DELETE).
466
+ *
467
+ * Return nothing to keep POST-redirect-GET: the handler's status (303 by
468
+ * default) plus any cookies it set, with `Location` back to the route path.
469
+ *
470
+ * Return a {@link RawResponse} to answer with a body — a JSON API, a webhook
471
+ * receiver that must echo a challenge, a JSON-RPC endpoint. The status then
472
+ * defaults to 200 rather than 303.
473
+ *
474
+ * ```ts
475
+ * export const POST: RouteHandler = async ({ form }) => ({
476
+ * status: 201,
477
+ * contentType: "application/json; charset=utf-8",
478
+ * body: JSON.stringify({ id: await create(form.get("name")) }),
479
+ * });
480
+ * ```
481
+ */
482
+ export type RouteHandler<TParams extends Record<string, string> = Record<string, string>, TSearchParams extends Record<string, string> = Record<string, string>> = (req: FormRequest<TParams, TSearchParams>) => RawResponse | void | Promise<RawResponse | void>;
403
483
  /**
404
484
  * What a `route.ts` `GET` (raw) handler returns. The body is streamed verbatim
405
485
  * with `contentType` (default `text/plain; charset=utf-8`), `status` (default
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.4.29",
6
+ "version": "0.5.0",
7
7
  "type": "module",
8
8
  "main": "./src/index.ts",
9
9
  "types": "./dist/index.d.ts",
@@ -14,8 +14,8 @@
14
14
  "prepack": "bun run build"
15
15
  },
16
16
  "dependencies": {
17
- "@pylonsync/sdk": "0.4.29",
18
- "@pylonsync/sync": "0.4.29"
17
+ "@pylonsync/sdk": "0.5.0",
18
+ "@pylonsync/sync": "0.5.0"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "react": ">=19.0.0"
package/src/index.ts CHANGED
@@ -35,6 +35,9 @@ export type {
35
35
  SitemapEntry,
36
36
  Robots,
37
37
  RobotsRule,
38
+ LlmsTxt,
39
+ LlmsSection,
40
+ LlmsLink,
38
41
  RouteSegmentConfig,
39
42
  ErrorBoundaryProps,
40
43
  NotFoundProps,
package/src/ssr.ts CHANGED
@@ -320,6 +320,50 @@ export interface Robots {
320
320
  host?: string;
321
321
  }
322
322
 
323
+ /** One link in an `llms.txt` section. */
324
+ export interface LlmsLink {
325
+ title: string;
326
+ url: string;
327
+ /** Short note after the link — what an agent finds there. */
328
+ notes?: string;
329
+ }
330
+
331
+ /** An H2-delimited section of file links in `llms.txt`. */
332
+ export interface LlmsSection {
333
+ title: string;
334
+ links: LlmsLink[];
335
+ }
336
+
337
+ /**
338
+ * Return type for an `app/llms.ts` default export. The runtime serializes it
339
+ * to `/llms.txt` in <https://llmstxt.org> format — the file an agent reads
340
+ * first to decide what this site is and which pages are worth its context.
341
+ * Sync or async, like `sitemap`/`robots`.
342
+ *
343
+ * export default function llms(): LlmsTxt {
344
+ * return {
345
+ * title: "Acme",
346
+ * summary: "Invoicing for freelancers. Free tier, self-serve API keys.",
347
+ * details: "Use Acme when you need to issue an invoice and collect payment.",
348
+ * sections: [
349
+ * { title: "Docs", links: [{ title: "API", url: "https://acme.com/docs/api", notes: "REST + webhooks" }] },
350
+ * ],
351
+ * };
352
+ * }
353
+ *
354
+ * The element order is the spec's, and it matters: an H1 title, a blockquote
355
+ * summary, prose with NO headings, then H2 sections of links.
356
+ */
357
+ export interface LlmsTxt {
358
+ /** H1 — the site or project name. The one required element. */
359
+ title: string;
360
+ /** The blockquote under it: what this is, in one or two sentences. */
361
+ summary?: string;
362
+ /** Prose paragraphs before the first section. Headings are not allowed. */
363
+ details?: string | string[];
364
+ sections?: LlmsSection[];
365
+ }
366
+
323
367
  /**
324
368
  * Per-route configuration, declared as top-level `export const` in a
325
369
  * `page.tsx` (Next-shaped). All optional. The runtime reads these statically
@@ -352,6 +396,20 @@ export interface RouteSegmentConfig {
352
396
  revalidate?: number;
353
397
  dynamic?: "force-static" | "force-dynamic";
354
398
  streaming?: boolean;
399
+ /**
400
+ * Opt this route OUT of its markdown representation.
401
+ *
402
+ * Every SSR page is readable as markdown by default — through
403
+ * `Accept: text/markdown` on its own URL, or at `<path>.md`. Set `false` for
404
+ * a route whose value is the interaction rather than the prose (a dashboard,
405
+ * an editor, an app shell): a client that also accepts HTML then gets the
406
+ * HTML, one that accepts only markdown gets a 406, and the `.md` URL 404s.
407
+ *
408
+ * ```ts
409
+ * export const markdown = false;
410
+ * ```
411
+ */
412
+ markdown?: boolean;
355
413
  }
356
414
 
357
415
  /**
@@ -442,6 +500,14 @@ export interface FormRequest<
442
500
  TSearchParams extends Record<string, string> = Record<string, string>,
443
501
  > {
444
502
  form: FormFields;
503
+ /**
504
+ * The raw request body, exactly as sent. Empty for GET.
505
+ *
506
+ * `form` only carries PARSED fields, which the runtime produces for
507
+ * `application/x-www-form-urlencoded` bodies. Read `body` for a JSON API, a
508
+ * JSON-RPC endpoint, or a webhook whose signature covers the exact bytes.
509
+ */
510
+ body: string;
445
511
  params: TParams;
446
512
  searchParams: TSearchParams;
447
513
  auth: PageAuth;
@@ -451,11 +517,30 @@ export interface FormRequest<
451
517
  response: SsrResponse;
452
518
  }
453
519
 
454
- /** Signature of a `route.ts` method handler export (POST/PUT/PATCH/DELETE). */
520
+ /**
521
+ * Signature of a `route.ts` method handler export (POST/PUT/PATCH/DELETE).
522
+ *
523
+ * Return nothing to keep POST-redirect-GET: the handler's status (303 by
524
+ * default) plus any cookies it set, with `Location` back to the route path.
525
+ *
526
+ * Return a {@link RawResponse} to answer with a body — a JSON API, a webhook
527
+ * receiver that must echo a challenge, a JSON-RPC endpoint. The status then
528
+ * defaults to 200 rather than 303.
529
+ *
530
+ * ```ts
531
+ * export const POST: RouteHandler = async ({ form }) => ({
532
+ * status: 201,
533
+ * contentType: "application/json; charset=utf-8",
534
+ * body: JSON.stringify({ id: await create(form.get("name")) }),
535
+ * });
536
+ * ```
537
+ */
455
538
  export type RouteHandler<
456
539
  TParams extends Record<string, string> = Record<string, string>,
457
540
  TSearchParams extends Record<string, string> = Record<string, string>,
458
- > = (req: FormRequest<TParams, TSearchParams>) => void | Promise<void>;
541
+ > = (
542
+ req: FormRequest<TParams, TSearchParams>,
543
+ ) => RawResponse | void | Promise<RawResponse | void>;
459
544
 
460
545
  /**
461
546
  * What a `route.ts` `GET` (raw) handler returns. The body is streamed verbatim