okno 1.0.0-beta.12 → 1.0.0-beta.13

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/boot.d.ts CHANGED
@@ -1,88 +1,2 @@
1
- /**
2
- * okno client boot — production editor delivery.
3
- *
4
- * In dev the okno Vite plugin injects the editor through dev-server middleware
5
- * (`configureServer` in src/vite/plugin.ts). That middleware does not run in a
6
- * production build, and on SSG frameworks (Astro et al.) the okno runtime is
7
- * server-only — so a deployed page ships no editor at all. This module is the
8
- * client-side entry that closes that gap: a page pulls it in (via a framework
9
- * integration or a `<script>` in the layout) and it lazily boots the editor on
10
- * demand.
11
- *
12
- * The ~1 MB editor bundle is loaded only when an editor signals intent —
13
- * pressing `e`, or visiting with `?okno` / `#okno`. Public visitors download
14
- * only this tiny gate. `import("okno/editor")` is a bare specifier the
15
- * *consumer's* bundler resolves and code-splits at their build time (okno's own
16
- * build keeps it external via rollup `external`), so the editor lands as its own
17
- * chunk rather than inside this file.
18
- *
19
- * FUTURE (not now): this lazy import resolves to the consumer's OWN deployed
20
- * chunk, pinned to the okno version they built with — so an editor update needs
21
- * a consumer rebuild. An alternative is to load the editor from a hosted URL
22
- * (`https://cdn.okno.build/editor@latest`) instead of `import("okno/editor")`:
23
- * editors update everywhere with no consumer rebuild, at the cost of version
24
- * pinning and a centralized editor↔backend version contract to keep in sync.
25
- */
26
- declare const __OKNO_IS_DEV__: boolean;
27
- declare const GATE_KEY = "e";
28
- declare const g: {
29
- document?: Document;
30
- location?: Location;
31
- localStorage?: Storage;
32
- __okno_loaded?: boolean;
33
- __okno_gate_installed?: boolean;
34
- __okno_autostart?: "key" | "url" | "session" | false;
35
- __okno_ensure_vt?: () => void;
36
- };
37
- declare let loading: boolean;
38
- declare const OPENED_KEY = "okno-win-opened";
39
- declare const SHELL_ID = "okno-shadow-root";
40
- declare const VT_STYLE_ID = "okno-vt-style";
41
- declare const NAV_CLASS = "okno-nav-vt";
42
- /** The window was last left open → the editor should ride along across navigation. */
43
- declare function editorActive(): boolean;
44
- /** Cross-document View Transitions: needs the VT API + the pageswap/pagereveal
45
- * hooks (Chromium 126+, Safari 18.2+). Elsewhere we degrade to a plain reboot. */
46
- declare function crossDocVTSupported(): boolean;
47
- /** Does the HOST page already opt into cross-document View Transitions? Decides
48
- * how we coexist without interfering (see ensureVTStyle). Read before injecting
49
- * our own style; cross-origin sheets are skipped (their rules can't be read). */
50
- declare function hostHasViewTransition(): boolean;
51
- /** Inject (once) the rules that hold the editor in place across navigation. Two
52
- * hard constraints: UNIVERSAL (no host-framework assumptions — pure CSS in the
53
- * always-loaded gate) and NON-INTERFERING with the host's own transitions:
54
- * • All `okno-shell` / `root` rules are scoped to `html.okno-nav-vt` — a class
55
- * we set ONLY during a cross-document nav — so they never bleed into okno's
56
- * own same-document structural View Transitions (which run constantly).
57
- * • If the host ALREADY uses cross-document VT, we DON'T touch `root`: the page
58
- * animates exactly as the host intends; we only lift the editor out + hold it.
59
- * • If the host does NOT, we enable a minimal VT and HARD-CUT the page (suppress
60
- * the default root crossfade), so a site that never wanted page transitions
61
- * doesn't suddenly get one — only the editor is held.
62
- * Public on `window.__okno_ensure_vt` so the editor can opt the current page in
63
- * the instant it opens (boot ran here before the window was open). */
64
- declare function ensureVTStyle(): void;
65
- /** The editor host is normally a 0-size box (its UI is `position:fixed` inside
66
- * the shadow root), which would snapshot empty and make the browser SKIP the
67
- * transition. Give it a real viewport box + the group name for the capture —
68
- * pointer-events:none so it never intercepts clicks. Inline + transient (only
69
- * during the nav), so it never lingers to fight okno's structural `okno-editor`
70
- * group. Mirrors the structural-edit code in wrap.ts. */
71
- declare function pinHostForCapture(host: HTMLElement): void;
72
- /** Outgoing page: flag the nav + lift the editor into its own snapshot group. */
73
- declare function onPageSwap(e: Event): void;
74
- /** Incoming page: flag the nav (so the scoped rules apply), then stand up a
75
- * placeholder host with the box + name before first render so the new side has a
76
- * matching `okno-shell` group. `initEditor` reuses it when the bundle loads. The
77
- * flag is cleared once the transition settles. */
78
- declare function onPageReveal(e: Event): void;
79
- /** The editor sets `window.__okno_loaded` at the top of its entry module, so
80
- * this flips true the moment the bundle starts evaluating. */
81
- declare function editorPresent(): boolean;
82
- /** Don't hijack `e` while the visitor is typing in the host page. Mirrors the
83
- * editor's own focus check (modules/keys.svelte.ts), shadow DOM included. */
84
- declare function isTyping(): boolean;
85
- declare function bootEditor(reason: "key" | "url" | "session"): void;
86
- declare function urlRequestsEditor(): boolean;
87
- declare function install(): void;
1
+ export {};
88
2
  //# sourceMappingURL=boot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,CAAC,MAAM,eAAe,EAAE,OAAO,CAAA;AAEtC,QAAA,MAAM,QAAQ,MAAM,CAAA;AAEpB,QAAA,MAAM,CAAC,EAA4B;IAClC,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,gBAAgB,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,CAAA;IACpD,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAA;CAC7B,CAAA;AAED,QAAA,IAAI,OAAO,SAAQ,CAAA;AAenB,QAAA,MAAM,UAAU,oBAAoB,CAAA;AACpC,QAAA,MAAM,QAAQ,qBAAqB,CAAA;AACnC,QAAA,MAAM,WAAW,kBAAkB,CAAA;AACnC,QAAA,MAAM,SAAS,gBAAgB,CAAA;AAE/B,sFAAsF;AACtF,iBAAS,YAAY,IAAI,OAAO,CAM/B;AAED;mFACmF;AACnF,iBAAS,mBAAmB,IAAI,OAAO,CAOtC;AAED;;kFAEkF;AAClF,iBAAS,qBAAqB,IAAI,OAAO,CAgBxC;AAED;;;;;;;;;;;;uEAYuE;AACvE,iBAAS,aAAa,IAAI,IAAI,CA0B7B;AAED;;;;;0DAK0D;AAC1D,iBAAS,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAElD;AAED,iFAAiF;AACjF,iBAAS,UAAU,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAKlC;AAED;;;mDAGmD;AACnD,iBAAS,YAAY,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAgBpC;AAED;+DAC+D;AAC/D,iBAAS,aAAa,IAAI,OAAO,CAEhC;AAED;8EAC8E;AAC9E,iBAAS,QAAQ,IAAI,OAAO,CAO3B;AAED,iBAAS,UAAU,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,CAa3D;AAED,iBAAS,iBAAiB,IAAI,OAAO,CASpC;AAED,iBAAS,OAAO,IAAI,IAAI,CAgCvB"}
1
+ {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"AAyQA,OAAO,EAAE,CAAA"}
@@ -2,8 +2,12 @@ import type { OknoConfig } from "../types/schema.ts";
2
2
  export interface WithOknoOptions {
3
3
  /** okno content dir name, relative to the project root (default "okno"). */
4
4
  dir?: OknoConfig["dir"];
5
+ /** Routable folder the dev API is mounted at — must NOT start with `_`
6
+ * (App Router private folder). Default "oknoapi"; match your route file
7
+ * `app/<apiMount>/[...okno]/route.ts`. */
8
+ apiMount?: string;
5
9
  }
6
- /** Wrap a Next config so okno's codegen runs alongside it. `nextConfig` is
7
- * passed through unchanged; okno's work happens as a boot side effect. */
10
+ /** Wrap a Next config so okno's dev API is reachable and its codegen runs. The
11
+ * user's config is preserved; okno adds the rewrite + a boot side effect. */
8
12
  export declare function withOkno<T>(nextConfig?: T, options?: WithOknoOptions): T;
9
13
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/next/config.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,4EAA4E;IAC5E,GAAG,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAA;CACvB;AAMD;2EAC2E;AAC3E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,GAAE,CAAW,EAAE,OAAO,GAAE,eAAoB,GAAG,CAAC,CAwBrF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/next/config.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,4EAA4E;IAC5E,GAAG,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAA;IACvB;;+CAE2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAA;CACjB;AAqBD;8EAC8E;AAC9E,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,GAAE,CAAW,EAAE,OAAO,GAAE,eAAoB,GAAG,CAAC,CA6BrF"}
@@ -4,12 +4,18 @@ export interface OknoRouteOptions {
4
4
  /** Project root the dir resolves against (default `process.cwd()`). */
5
5
  root?: string;
6
6
  }
7
+ /** The App-Router context object (Next 15 makes `params` a Promise; 14 doesn't). */
8
+ type RouteContext = {
9
+ params?: Promise<Record<string, string | string[]>> | Record<string, string | string[]>;
10
+ };
7
11
  /**
8
12
  * Build the `{ GET, POST }` handlers for the okno dev API. Mount at a Next
9
- * App-Router catch-all: `app/__okno/api/[...okno]/route.ts`.
13
+ * App-Router catch-all: `app/oknoapi/[...okno]/route.ts` (paired with the
14
+ * `withOkno` rewrite from `/__okno/api/*`).
10
15
  */
11
16
  export declare function createOknoRouteHandler(opts?: OknoRouteOptions): {
12
- GET: (req: Request) => Promise<Response>;
13
- POST: (req: Request) => Promise<Response>;
17
+ GET: (req: Request, ctx?: RouteContext) => Promise<Response>;
18
+ POST: (req: Request, ctx?: RouteContext) => Promise<Response>;
14
19
  };
20
+ export {};
15
21
  //# sourceMappingURL=handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/next/handler.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,gBAAgB;IAChC,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAUD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG;IAChE,GAAG,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxC,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CACzC,CA2CA"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/next/handler.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,gBAAgB;IAChC,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,oFAAoF;AACpF,KAAK,YAAY,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAA;CAAE,CAAA;AA6B/G;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG;IAChE,GAAG,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC5D,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CAC7D,CAyCA"}
@@ -1,41 +1,63 @@
1
- import { resolve as h } from "node:path";
2
- import { existsSync as m, watch as k } from "node:fs";
3
- import { g as O, d as v } from "../dispatch-bnmIdH8E.js";
4
- let d = !1;
5
- function j(t = {}, s = {}) {
6
- if (d) return t;
7
- d = !0;
8
- const n = process.cwd(), e = h(n, s.dir ?? "okno");
9
- if (!m(e)) return t;
10
- const o = () => {
11
- O(e, n).catch((r) => console.warn("[okno] codegen failed:", r));
1
+ import { resolve as l } from "node:path";
2
+ import { existsSync as m, watch as w } from "node:fs";
3
+ import { g as k, d as v } from "../dispatch-bnmIdH8E.js";
4
+ function g(r, o) {
5
+ const n = { source: "/__okno/api/:path*", destination: `/${o}/:path*` };
6
+ return async () => {
7
+ const e = typeof r == "function" ? await r() : void 0;
8
+ return e ? Array.isArray(e) ? [n, ...e] : { ...e, beforeFiles: [n, ...e.beforeFiles ?? []] } : [n];
12
9
  };
13
- if (o(), process.env.NODE_ENV !== "production")
14
- try {
15
- k(e, { recursive: !0 }, () => o());
16
- } catch {
10
+ }
11
+ let f = !1;
12
+ function S(r = {}, o = {}) {
13
+ const n = o.apiMount ?? "oknoapi", e = {
14
+ ...r,
15
+ rewrites: g(r.rewrites, n)
16
+ };
17
+ if (!f) {
18
+ f = !0;
19
+ const s = process.cwd(), t = l(s, o.dir ?? "okno");
20
+ if (m(t)) {
21
+ const a = () => {
22
+ k(t, s).catch((i) => console.warn("[okno] codegen failed:", i));
23
+ };
24
+ if (a(), process.env.NODE_ENV !== "production")
25
+ try {
26
+ w(t, { recursive: !0 }, () => a());
27
+ } catch {
28
+ }
17
29
  }
18
- return t;
30
+ }
31
+ return e;
32
+ }
33
+ const p = { "Content-Type": "application/json", "Cache-Control": "no-store" };
34
+ function O(r) {
35
+ return l(r?.root ?? process.cwd(), r?.dir ?? "okno");
19
36
  }
20
- const l = { "Content-Type": "application/json", "Cache-Control": "no-store" };
21
- function R(t) {
22
- return h(t?.root ?? process.cwd(), t?.dir ?? "okno");
37
+ function d() {
38
+ return new Response(JSON.stringify({ error: "Not found" }), { status: 404, headers: p });
23
39
  }
24
- function f() {
25
- return new Response(JSON.stringify({ error: "Not found" }), { status: 404, headers: l });
40
+ async function R(r, o) {
41
+ const n = o?.params ? await o.params : void 0;
42
+ if (n) {
43
+ const t = n.okno ?? Object.values(n)[0];
44
+ if (Array.isArray(t)) return t.join("/");
45
+ if (typeof t == "string") return t;
46
+ }
47
+ const e = "/__okno/api/", s = new URL(r.url).pathname.indexOf(e);
48
+ return s === -1 ? null : new URL(r.url).pathname.slice(s + e.length);
26
49
  }
27
- function D(t) {
28
- const s = R(t), n = async (e) => {
29
- const o = "/__okno/api/", r = new URL(e.url).pathname.indexOf(o);
30
- if (r === -1) return f();
31
- const p = new URL(e.url).pathname.slice(r + o.length);
32
- let a, u = !1, c;
33
- const w = {
50
+ function _(r) {
51
+ const o = O(r), n = async (e, s) => {
52
+ const t = await R(e, s);
53
+ if (t == null) return d();
54
+ let a, i = !1, c;
55
+ const h = {
34
56
  method: e.method,
35
- route: p,
57
+ route: t,
36
58
  json: async () => {
37
- if (!u) {
38
- u = !0;
59
+ if (!i) {
60
+ i = !0;
39
61
  try {
40
62
  a = await e.json();
41
63
  } catch {
@@ -46,12 +68,12 @@ function D(t) {
46
68
  },
47
69
  binary: async () => (c === void 0 && (c = Buffer.from(await e.arrayBuffer())), c),
48
70
  header: (y) => e.headers.get(y) ?? void 0
49
- }, i = await v(s, w);
50
- return i ? new Response(JSON.stringify(i.body), { status: i.status, headers: l }) : f();
71
+ }, u = await v(o, h);
72
+ return u ? new Response(JSON.stringify(u.body), { status: u.status, headers: p }) : d();
51
73
  };
52
74
  return { GET: n, POST: n };
53
75
  }
54
76
  export {
55
- D as createOknoRouteHandler,
56
- j as withOkno
77
+ _ as createOknoRouteHandler,
78
+ S as withOkno
57
79
  };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "okno",
3
3
  "description": "Git-backed CMS with live editing for any Vite framework",
4
4
  "author": "Gabriel Uhlíř",
5
- "version": "1.0.0-beta.12",
5
+ "version": "1.0.0-beta.13",
6
6
  "homepage": "https://okno.build",
7
7
  "type": "module",
8
8
  "types": "./dist/index.d.ts",