@louise-toolkit/astro 0.1.0 → 0.1.2

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
@@ -2,4 +2,5 @@ export { type ActionErrorCtor, type EditorActionContext, type EditorActionDeps,
2
2
  export { type CatalogLoaderConfig, defineCatalogLoader } from "./catalog.js";
3
3
  export { collectionToAstroSchema, louiseLoader, type LouiseLoaderConfig, type LouiseRow, } from "./content-loader.js";
4
4
  export { formToAstroSchema } from "./form-schema.js";
5
+ export { type ResumeReadSession, resumeReadSession } from "./resume.js";
5
6
  export { createLouiseMiddleware, type LouiseMiddlewareConfig, type LouiseMiddlewareRateLimit, } from "./middleware.js";
package/dist/index.js CHANGED
@@ -8,4 +8,5 @@ export { louiseSaveAction, louiseSaveDraftAction, louiseSettingsAction, } from "
8
8
  export { defineCatalogLoader } from "./catalog.js";
9
9
  export { collectionToAstroSchema, louiseLoader, } from "./content-loader.js";
10
10
  export { formToAstroSchema } from "./form-schema.js";
11
+ export { resumeReadSession } from "./resume.js";
11
12
  export { createLouiseMiddleware, } from "./middleware.js";
@@ -35,6 +35,12 @@ export interface LouiseMiddlewareConfig<TEditor = unknown> {
35
35
  /** Apply {@link louiseSecurityHeaders} (HSTS, nosniff, referrer, …) to the
36
36
  * response. Default `true`. */
37
37
  securityHeaders?: boolean;
38
+ /**
39
+ * Hosts to keep out of search indexes — sent as `X-Robots-Tag: noindex`.
40
+ * E.g. `(host) => isNoindexHost(host, { prefixes: ["preview."] })`. Set here
41
+ * rather than in a page, because a streamed page's headers are already gone.
42
+ */
43
+ noindex?: (hostname: string) => boolean;
38
44
  /**
39
45
  * Extra per-request work after editor resolution, before `next()` — e.g.
40
46
  * resolve a second session (a shop customer) onto `locals`. Runs inside the
@@ -131,8 +131,12 @@ export function createLouiseMiddleware(config) {
131
131
  // every edit surface), so guarantee the CSP permits data: fonts — no-op
132
132
  // without a CSP header or when already allowed. Saves consumers a font-src edit.
133
133
  allowCspDataFonts(response);
134
+ const noindex = config.noindex?.(context.url.hostname) ?? false;
134
135
  if (config.securityHeaders !== false) {
135
- louiseSecurityHeaders(response, { hostname: context.url.hostname });
136
+ louiseSecurityHeaders(response, { hostname: context.url.hostname, noindex });
137
+ }
138
+ else if (noindex) {
139
+ response.headers.set("X-Robots-Tag", "noindex");
136
140
  }
137
141
  return response;
138
142
  };
@@ -0,0 +1,20 @@
1
+ import type { AstroCookies } from "astro";
2
+ import { type D1Client } from "louise-toolkit/db";
3
+ export interface ResumeReadSession {
4
+ /** Pass to `resumeDraft` (or any read that must see the editor's writes). */
5
+ client: D1Client;
6
+ /** Persist the bookmark the reads advanced to. Call once, after them. */
7
+ commit: () => void;
8
+ }
9
+ /**
10
+ * Open a D1 session anchored at the editor's persisted bookmark, for the
11
+ * edit-mode resume read. On a database without read replication — or a
12
+ * runtime without the Sessions API — `client` is the raw binding and nothing
13
+ * changes, so this is safe to wire before replication is on.
14
+ *
15
+ * Edit mode only: a view-mode render should stay session-free and cookie-free,
16
+ * so public pages remain cacheable.
17
+ */
18
+ export declare function resumeReadSession(DB: D1Database, cookies: AstroCookies, options?: {
19
+ maxAgeSeconds?: number;
20
+ }): ResumeReadSession;
package/dist/resume.js ADDED
@@ -0,0 +1,36 @@
1
+ // Copyright (c) 2026 BowenLabs. Louise Toolkit is MIT licensed.
2
+ //
3
+ // The edit-mode resume read's D1 session, over Astro's cookie API. The draft
4
+ // WRITE (auto-save) persists its D1 bookmark in the `louise_d1_bookmark` cookie;
5
+ // the page load that follows must read at or past that bookmark, or behind read
6
+ // replication the draft just saved can be missing ("my edit vanished").
7
+ import { D1_BOOKMARK_COOKIE, D1_BOOKMARK_MAX_AGE, d1Bookmark, openD1Session, } from "louise-toolkit/db";
8
+ /**
9
+ * Open a D1 session anchored at the editor's persisted bookmark, for the
10
+ * edit-mode resume read. On a database without read replication — or a
11
+ * runtime without the Sessions API — `client` is the raw binding and nothing
12
+ * changes, so this is safe to wire before replication is on.
13
+ *
14
+ * Edit mode only: a view-mode render should stay session-free and cookie-free,
15
+ * so public pages remain cacheable.
16
+ */
17
+ export function resumeReadSession(DB, cookies, options = {}) {
18
+ const bookmark = cookies.get(D1_BOOKMARK_COOKIE)?.value ?? null;
19
+ const client = openD1Session(DB, bookmark ?? "first-unconstrained");
20
+ return {
21
+ client,
22
+ commit() {
23
+ const next = d1Bookmark(client);
24
+ if (next && next !== bookmark) {
25
+ // The same attributes `serializeD1BookmarkCookie` writes on the save path.
26
+ cookies.set(D1_BOOKMARK_COOKIE, next, {
27
+ path: "/",
28
+ httpOnly: true,
29
+ sameSite: "lax",
30
+ secure: true,
31
+ maxAge: options.maxAgeSeconds ?? D1_BOOKMARK_MAX_AGE,
32
+ });
33
+ }
34
+ },
35
+ };
36
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@louise-toolkit/astro",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Astro adapter for louise-toolkit: middleware, Actions, content-layer loaders, and the forms schema bridge.",
5
5
  "keywords": [
6
6
  "astro",
@@ -9,7 +9,10 @@
9
9
  "louise",
10
10
  "louise-toolkit"
11
11
  ],
12
+ "homepage": "https://louisetoolkit.com",
13
+ "bugs": "https://github.com/bowenlabs/louise-toolkit/issues",
12
14
  "license": "MIT",
15
+ "author": "BowenLabs",
13
16
  "repository": {
14
17
  "type": "git",
15
18
  "url": "git+https://github.com/bowenlabs/louise-toolkit.git",
@@ -19,6 +22,7 @@
19
22
  "dist"
20
23
  ],
21
24
  "type": "module",
25
+ "sideEffects": false,
22
26
  "exports": {
23
27
  ".": {
24
28
  "types": "./dist/index.d.ts",
@@ -31,7 +35,7 @@
31
35
  "access": "public"
32
36
  },
33
37
  "dependencies": {
34
- "louise-toolkit": "0.27.0"
38
+ "louise-toolkit": "0.29.0"
35
39
  },
36
40
  "devDependencies": {
37
41
  "@cloudflare/workers-types": "^5.20260829.1",
@@ -49,6 +53,9 @@
49
53
  "optional": true
50
54
  }
51
55
  },
56
+ "engines": {
57
+ "node": ">=24.0.0"
58
+ },
52
59
  "scripts": {
53
60
  "build": "tsgo -p tsconfig.build.json",
54
61
  "check": "vp check",