@guard-rail/core 0.2.0 → 0.3.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 +86 -6
- package/dist/adapters/supabase/db.js +11 -0
- package/dist/adapters/supabase/db.js.map +1 -1
- package/dist/core/adapter-types.d.ts +35 -1
- package/dist/core/config.d.ts +7 -1
- package/dist/core/config.js +11 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/scaffold.d.ts +11 -0
- package/dist/core/scaffold.js +19 -0
- package/dist/core/scaffold.js.map +1 -0
- package/dist/core/types.d.ts +14 -1
- package/dist/index.client.d.ts +18 -0
- package/dist/index.client.js +66 -0
- package/dist/index.client.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react/Admin.d.ts +8 -3
- package/dist/react/Admin.js +14 -6
- package/dist/react/Admin.js.map +1 -1
- package/dist/react/GRail/client.js +86 -27
- package/dist/react/GRail/client.js.map +1 -1
- package/dist/react/GRail/editor.d.ts +24 -0
- package/dist/react/GRail/editor.js +9 -0
- package/dist/react/GRail/editor.js.map +1 -0
- package/dist/react/GRail/index.js +2 -2
- package/dist/react/GRail/index.js.map +1 -1
- package/dist/react/GRail/render.d.ts +3 -3
- package/dist/react/GRail/universal.d.ts +22 -0
- package/dist/react/GRail/universal.js +29 -0
- package/dist/react/GRail/universal.js.map +1 -0
- package/dist/react/Icons.d.ts +2 -1
- package/dist/react/Icons.js +5 -0
- package/dist/react/Icons.js.map +1 -1
- package/dist/react/MediaPicker.js +3 -3
- package/dist/react/MediaPicker.js.map +1 -1
- package/dist/react/Provider.d.ts +9 -5
- package/dist/react/Provider.js +10 -4
- package/dist/react/Provider.js.map +1 -1
- package/dist/react/Repeater/client.d.ts +3 -3
- package/dist/react/Repeater/client.js +2 -2
- package/dist/react/Repeater/client.js.map +1 -1
- package/dist/react/Repeater/index.d.ts +3 -3
- package/dist/react/Team.js +7 -7
- package/dist/react/Team.js.map +1 -1
- package/dist/react/styles.d.ts +104 -30
- package/dist/react/styles.js +154 -65
- package/dist/react/styles.js.map +1 -1
- package/dist/react/useAnchorRect.js +1 -0
- package/dist/react/useAnchorRect.js.map +1 -1
- package/dist/server/data.js +1 -15
- package/dist/server/data.js.map +1 -1
- package/dist/server/loader.d.ts +9 -2
- package/dist/server/loader.js +74 -11
- package/dist/server/loader.js.map +1 -1
- package/dist/server/wrapper.d.ts +2 -2
- package/dist/server/wrapper.js +6 -2
- package/dist/server/wrapper.js.map +1 -1
- package/package.json +11 -1
package/dist/server/loader.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cache } from "react";
|
|
2
|
-
import { getDB, resolveSiteId } from "../core/config";
|
|
2
|
+
import { getDB, getPrefetch, resolveSiteId } from "../core/config";
|
|
3
3
|
import { rethrowIfBailout } from "../core/bailout";
|
|
4
4
|
const getLoader = cache(() => {
|
|
5
5
|
let pending = [];
|
|
@@ -26,17 +26,52 @@ const getLoader = cache(() => {
|
|
|
26
26
|
for (const p of batch) p.reject(e);
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
const enqueue = (key) => new Promise((resolve, reject) => {
|
|
30
|
+
pending.push({ key, resolve, reject });
|
|
31
|
+
if (!scheduled) {
|
|
32
|
+
scheduled = true;
|
|
33
|
+
queueMicrotask(flush);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
let preload;
|
|
37
|
+
const runPreload = async () => {
|
|
38
|
+
try {
|
|
39
|
+
const prefetch = getPrefetch();
|
|
40
|
+
const db = getDB();
|
|
41
|
+
if (!prefetch || !db.listOverrides) return null;
|
|
42
|
+
const siteId = await resolveSiteId();
|
|
43
|
+
const started = Date.now();
|
|
44
|
+
const { rows, truncated } = await db.listOverrides(siteId, prefetch);
|
|
45
|
+
if (process.env.GUARDRAIL_DEBUG) {
|
|
46
|
+
console.log(
|
|
47
|
+
`[guardrail] preload: ${rows.length} row(s) in 1 query (${Date.now() - started}ms) site=${siteId}${prefetch.prefix ? ` prefix=${prefetch.prefix.join("|")}` : ""}${truncated ? " TRUNCATED" : ""}`
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
byKey: new Map(rows.map((r) => [r.pathKey, r])),
|
|
52
|
+
// Scoping by prefix or hitting the ceiling both mean "not every row."
|
|
53
|
+
complete: !prefetch.prefix && !truncated,
|
|
54
|
+
truncated
|
|
55
|
+
};
|
|
56
|
+
} catch (e) {
|
|
57
|
+
rethrowIfBailout(e);
|
|
58
|
+
console.error("Guardrail: content preload failed", e);
|
|
59
|
+
return null;
|
|
38
60
|
}
|
|
39
61
|
};
|
|
62
|
+
const getPreload = () => preload ??= runPreload();
|
|
63
|
+
return {
|
|
64
|
+
async load(key) {
|
|
65
|
+
const pre = await getPreload();
|
|
66
|
+
if (pre) {
|
|
67
|
+
const hit = pre.byKey.get(key);
|
|
68
|
+
if (hit) return hit;
|
|
69
|
+
if (pre.complete) return null;
|
|
70
|
+
}
|
|
71
|
+
return enqueue(key);
|
|
72
|
+
},
|
|
73
|
+
getPreload
|
|
74
|
+
};
|
|
40
75
|
});
|
|
41
76
|
async function loadOverride(pathKey) {
|
|
42
77
|
try {
|
|
@@ -47,7 +82,35 @@ async function loadOverride(pathKey) {
|
|
|
47
82
|
return null;
|
|
48
83
|
}
|
|
49
84
|
}
|
|
85
|
+
let warnedTruncated = false;
|
|
86
|
+
let warnedSize = false;
|
|
87
|
+
const SIZE_WARN_CHARS = 1e5;
|
|
88
|
+
async function loadPreloadedContent() {
|
|
89
|
+
const pre = await getLoader().getPreload();
|
|
90
|
+
if (!pre) return void 0;
|
|
91
|
+
const values = {};
|
|
92
|
+
for (const [key, row] of pre.byKey) values[key] = row.value;
|
|
93
|
+
if (process.env.NODE_ENV !== "production") {
|
|
94
|
+
if (pre.truncated && !warnedTruncated) {
|
|
95
|
+
warnedTruncated = true;
|
|
96
|
+
console.warn(
|
|
97
|
+
`Guardrail: this site has more content rows than the preload ceiling (${pre.byKey.size}). <GRail>s inside Client Components beyond it fall back to their JSX. Scope it with withGuardrail(..., { prefetch: { prefix: ["home.", "header."] } }) or raise prefetch.limit.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
if (!warnedSize) {
|
|
101
|
+
const size = JSON.stringify(values).length;
|
|
102
|
+
if (size > SIZE_WARN_CHARS) {
|
|
103
|
+
warnedSize = true;
|
|
104
|
+
console.warn(
|
|
105
|
+
`Guardrail: preloaded content for Client Components is ~${Math.round(size / 1e3)}KB and ships in every page. Consider scoping it with prefetch.prefix.`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return { values, complete: pre.complete };
|
|
111
|
+
}
|
|
50
112
|
export {
|
|
51
|
-
loadOverride
|
|
113
|
+
loadOverride,
|
|
114
|
+
loadPreloadedContent
|
|
52
115
|
};
|
|
53
116
|
//# sourceMappingURL=loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/loader.ts"],"sourcesContent":["import { cache } from \"react\";\nimport { getDB, resolveSiteId } from \"../core/config\";\nimport { rethrowIfBailout } from \"../core/bailout\";\nimport type { OverrideRow } from \"../core/types\";\n\ninterface Pending {\n key: string;\n resolve: (row: OverrideRow | null) => void;\n reject: (error: unknown) => void;\n}\n\n/**\n * Request-scoped
|
|
1
|
+
{"version":3,"sources":["../../src/server/loader.ts"],"sourcesContent":["import { cache } from \"react\";\nimport { getDB, getPrefetch, resolveSiteId } from \"../core/config\";\nimport { rethrowIfBailout } from \"../core/bailout\";\nimport type { GRContent, OverrideRow } from \"../core/types\";\n\ninterface Pending {\n key: string;\n resolve: (row: OverrideRow | null) => void;\n reject: (error: unknown) => void;\n}\n\ninterface Preloaded {\n byKey: Map<string, OverrideRow>;\n /** Every row the site has — an absent key is known to be unedited. */\n complete: boolean;\n truncated: boolean;\n}\n\n/**\n * Request-scoped content loader.\n *\n * Two jobs, one source of truth:\n *\n * 1. Batching. Every <GRail> resolves its own field, so a naive implementation\n * issues one query per field. Keys requested within a microtask are flushed\n * as a single query. React renders siblings concurrently, so a page's fields\n * land in the same batch; a field nested behind another await simply falls\n * into a later batch rather than degrading to one query each.\n *\n * 2. Preloading. <GRail>s inside Client Components cannot await anything, so\n * their content has to be handed to them up front. That preload lives *here*,\n * as one lazily-created promise per request, rather than as a separate fetch\n * in the layout — Next renders layouts and pages in parallel, so a page's\n * server fields could otherwise ask for content before the layout had\n * loaded any. Server fields read from the same preload: when it is complete,\n * every key resolves from it and no per-field query runs at all.\n *\n * cache() scopes all of it to a single request so nothing leaks between\n * concurrent renders.\n */\nconst getLoader = cache(() => {\n let pending: Pending[] = [];\n let scheduled = false;\n\n const flush = async () => {\n const batch = pending;\n pending = [];\n scheduled = false;\n if (batch.length === 0) return;\n\n // One lookup per distinct key, even if several fields share it.\n const keys = [...new Set(batch.map((p) => p.key))];\n\n try {\n const db = getDB();\n const siteId = await resolveSiteId();\n const started = Date.now();\n const rows = await db.getOverrides(keys, siteId);\n\n if (process.env.GUARDRAIL_DEBUG) {\n console.log(\n `[guardrail] batch: ${keys.length} key(s) -> ${rows.length} row(s) ` +\n `in 1 query (${Date.now() - started}ms) ` +\n `site=${siteId} keys=${keys.join(\", \")}`,\n );\n }\n const byKey = new Map(rows.map((r) => [r.pathKey, r]));\n for (const p of batch) p.resolve(byKey.get(p.key) ?? null);\n } catch (e) {\n for (const p of batch) p.reject(e);\n }\n };\n\n const enqueue = (key: string) =>\n new Promise<OverrideRow | null>((resolve, reject) => {\n pending.push({ key, resolve, reject });\n if (!scheduled) {\n scheduled = true;\n queueMicrotask(flush);\n }\n });\n\n let preload: Promise<Preloaded | null> | undefined;\n\n const runPreload = async (): Promise<Preloaded | null> => {\n try {\n const prefetch = getPrefetch();\n const db = getDB();\n // Off, or an adapter that can't list: behave exactly as before.\n if (!prefetch || !db.listOverrides) return null;\n\n const siteId = await resolveSiteId();\n const started = Date.now();\n const { rows, truncated } = await db.listOverrides(siteId, prefetch);\n\n if (process.env.GUARDRAIL_DEBUG) {\n console.log(\n `[guardrail] preload: ${rows.length} row(s) in 1 query ` +\n `(${Date.now() - started}ms) site=${siteId}` +\n `${prefetch.prefix ? ` prefix=${prefetch.prefix.join(\"|\")}` : \"\"}` +\n `${truncated ? \" TRUNCATED\" : \"\"}`,\n );\n }\n return {\n byKey: new Map(rows.map((r) => [r.pathKey, r])),\n // Scoping by prefix or hitting the ceiling both mean \"not every row.\"\n complete: !prefetch.prefix && !truncated,\n truncated,\n };\n } catch (e) {\n rethrowIfBailout(e);\n console.error(\"Guardrail: content preload failed\", e);\n return null;\n }\n };\n\n const getPreload = () => (preload ??= runPreload());\n\n return {\n async load(key: string): Promise<OverrideRow | null> {\n const pre = await getPreload();\n if (pre) {\n const hit = pre.byKey.get(key);\n if (hit) return hit;\n if (pre.complete) return null;\n }\n return enqueue(key);\n },\n getPreload,\n };\n});\n\nexport async function loadOverride(\n pathKey: string,\n): Promise<OverrideRow | null> {\n try {\n return await getLoader().load(pathKey);\n } catch (e) {\n rethrowIfBailout(e);\n console.error(\"Guardrail: failed to load override\", e);\n return null;\n }\n}\n\nlet warnedTruncated = false;\nlet warnedSize = false;\nconst SIZE_WARN_CHARS = 100_000;\n\n/**\n * The preload in the shape handed to Client Components, or undefined when\n * preloading is off or unavailable (client fields then render their JSX\n * fallback). Also where the two dev-mode nudges live, since this is the one\n * place that knows the size of what is about to be serialized into the page.\n */\nexport async function loadPreloadedContent(): Promise<GRContent | undefined> {\n const pre = await getLoader().getPreload();\n if (!pre) return undefined;\n\n const values: GRContent[\"values\"] = {};\n for (const [key, row] of pre.byKey) values[key] = row.value;\n\n if (process.env.NODE_ENV !== \"production\") {\n if (pre.truncated && !warnedTruncated) {\n warnedTruncated = true;\n console.warn(\n `Guardrail: this site has more content rows than the preload ceiling ` +\n `(${pre.byKey.size}). <GRail>s inside Client Components beyond it fall ` +\n `back to their JSX. Scope it with withGuardrail(..., { prefetch: { prefix: [\"home.\", \"header.\"] } }) ` +\n `or raise prefetch.limit.`,\n );\n }\n if (!warnedSize) {\n const size = JSON.stringify(values).length;\n if (size > SIZE_WARN_CHARS) {\n warnedSize = true;\n console.warn(\n `Guardrail: preloaded content for Client Components is ~${Math.round(size / 1000)}KB ` +\n `and ships in every page. Consider scoping it with prefetch.prefix.`,\n );\n }\n }\n }\n\n return { values, complete: pre.complete };\n}\n"],"mappings":"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","names":[]}
|
package/dist/server/wrapper.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import
|
|
2
|
+
import React__default from 'react';
|
|
3
3
|
import { GRConfig } from '../core/adapter-types.js';
|
|
4
4
|
import '../core/types.js';
|
|
5
5
|
|
|
@@ -7,6 +7,6 @@ import '../core/types.js';
|
|
|
7
7
|
* Wraps a root layout so every route carries Guardrail's edit state and admin
|
|
8
8
|
* chrome. Stays a Server Component: the provider below is the client boundary.
|
|
9
9
|
*/
|
|
10
|
-
declare function withGuardrail<P extends object>(LayoutComponent:
|
|
10
|
+
declare function withGuardrail<P extends object>(LayoutComponent: React__default.ComponentType<P>, config: GRConfig): (props: P) => Promise<react_jsx_runtime.JSX.Element>;
|
|
11
11
|
|
|
12
12
|
export { withGuardrail };
|
package/dist/server/wrapper.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
resolveSiteId
|
|
9
9
|
} from "../core/config";
|
|
10
10
|
import { getCachedViewer } from "./session";
|
|
11
|
+
import { loadPreloadedContent } from "./loader";
|
|
11
12
|
import { GR_COOKIES } from "../core/defs";
|
|
12
13
|
import { GRailProvider } from "../react/Provider";
|
|
13
14
|
import { GRailAdmin } from "../react/Admin";
|
|
@@ -16,7 +17,10 @@ function withGuardrail(LayoutComponent, config) {
|
|
|
16
17
|
return async function GuardrailLayout(props) {
|
|
17
18
|
configureGuardrail(config);
|
|
18
19
|
const cookieStore = await cookies();
|
|
19
|
-
const viewer = await
|
|
20
|
+
const [viewer, content] = await Promise.all([
|
|
21
|
+
getCachedViewer(),
|
|
22
|
+
loadPreloadedContent()
|
|
23
|
+
]);
|
|
20
24
|
const auth = getAuth();
|
|
21
25
|
const state = {
|
|
22
26
|
storage: getStorage() !== void 0,
|
|
@@ -30,7 +34,7 @@ function withGuardrail(LayoutComponent, config) {
|
|
|
30
34
|
role: viewer?.role ?? null,
|
|
31
35
|
...viewer?.email ? { email: viewer.email } : {}
|
|
32
36
|
};
|
|
33
|
-
return /* @__PURE__ */ jsxs(GRailProvider, { state, children: [
|
|
37
|
+
return /* @__PURE__ */ jsxs(GRailProvider, { state, content, children: [
|
|
34
38
|
/* @__PURE__ */ jsx(LayoutComponent, { ...props }),
|
|
35
39
|
/* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(GRailAdmin, { toolbarExtra: config.toolbarExtra }) })
|
|
36
40
|
] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/wrapper.tsx"],"sourcesContent":["import React, { Suspense } from \"react\";\nimport { cookies } from \"next/headers\";\nimport {\n configureGuardrail,\n getAuth,\n getStorage,\n resolveSiteId,\n} from \"../core/config\";\nimport { getCachedViewer } from \"./session\";\nimport type { GRConfig } from \"../core/adapter-types\";\nimport { GR_COOKIES } from \"../core/defs\";\nimport { GRailProvider } from \"../react/Provider\";\nimport { GRailAdmin } from \"../react/Admin\";\nimport type { GRState } from \"../core/types\";\n\n/**\n * Wraps a root layout so every route carries Guardrail's edit state and admin\n * chrome. Stays a Server Component: the provider below is the client boundary.\n */\nexport function withGuardrail<P extends object>(\n LayoutComponent: React.ComponentType<P>,\n config: GRConfig,\n) {\n // Applied at module evaluation so the config is present as soon as anything\n // imports the layout, and again per render because Next.js does not\n // guarantee one shared module instance across its server contexts.\n configureGuardrail(config);\n\n return async function GuardrailLayout(props: P) {\n configureGuardrail(config);\n\n const cookieStore = await cookies();\n\n // Verified against the auth provider, not inferred from a cookie.\n const viewer = await getCachedViewer();\n\n const auth = getAuth();\n\n const state: GRState = {\n storage: getStorage() !== undefined,\n auth: {\n password: typeof auth.authenticate === \"function\",\n ...(auth.signInUrl ? { signInUrl: auth.signInUrl } : {}),\n },\n isAuth: viewer !== null,\n isEditMode: cookieStore.get(GR_COOKIES.EDIT_MODE)?.value === \"true\",\n siteId: await resolveSiteId(),\n role: viewer?.role ?? null,\n ...(viewer?.email ? { email: viewer.email } : {}),\n };\n\n return (\n <GRailProvider state={state}>\n <LayoutComponent {...props} />\n <Suspense fallback={null}>\n <GRailAdmin toolbarExtra={config.toolbarExtra} />\n </Suspense>\n </GRailProvider>\n );\n };\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/server/wrapper.tsx"],"sourcesContent":["import React, { Suspense } from \"react\";\nimport { cookies } from \"next/headers\";\nimport {\n configureGuardrail,\n getAuth,\n getStorage,\n resolveSiteId,\n} from \"../core/config\";\nimport { getCachedViewer } from \"./session\";\nimport { loadPreloadedContent } from \"./loader\";\nimport type { GRConfig } from \"../core/adapter-types\";\nimport { GR_COOKIES } from \"../core/defs\";\nimport { GRailProvider } from \"../react/Provider\";\nimport { GRailAdmin } from \"../react/Admin\";\nimport type { GRState } from \"../core/types\";\n\n/**\n * Wraps a root layout so every route carries Guardrail's edit state and admin\n * chrome. Stays a Server Component: the provider below is the client boundary.\n */\nexport function withGuardrail<P extends object>(\n LayoutComponent: React.ComponentType<P>,\n config: GRConfig,\n) {\n // Applied at module evaluation so the config is present as soon as anything\n // imports the layout, and again per render because Next.js does not\n // guarantee one shared module instance across its server contexts.\n configureGuardrail(config);\n\n return async function GuardrailLayout(props: P) {\n configureGuardrail(config);\n\n const cookieStore = await cookies();\n\n // Verified against the auth provider, not inferred from a cookie. Loaded\n // alongside the content preload: independent round trips, and the preload\n // is shared with the page's own fields, so it costs them nothing extra.\n const [viewer, content] = await Promise.all([\n getCachedViewer(),\n loadPreloadedContent(),\n ]);\n\n const auth = getAuth();\n\n const state: GRState = {\n storage: getStorage() !== undefined,\n auth: {\n password: typeof auth.authenticate === \"function\",\n ...(auth.signInUrl ? { signInUrl: auth.signInUrl } : {}),\n },\n isAuth: viewer !== null,\n isEditMode: cookieStore.get(GR_COOKIES.EDIT_MODE)?.value === \"true\",\n siteId: await resolveSiteId(),\n role: viewer?.role ?? null,\n ...(viewer?.email ? { email: viewer.email } : {}),\n };\n\n return (\n <GRailProvider state={state} content={content}>\n <LayoutComponent {...props} />\n <Suspense fallback={null}>\n <GRailAdmin toolbarExtra={config.toolbarExtra} />\n </Suspense>\n </GRailProvider>\n );\n };\n}\n"],"mappings":"AA0DM,SACE,KADF;AA1DN,OAAO,SAAS,gBAAgB;AAChC,SAAS,eAAe;AACxB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAChC,SAAS,4BAA4B;AAErC,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAOpB,SAAS,cACd,iBACA,QACA;AAIA,qBAAmB,MAAM;AAEzB,SAAO,eAAe,gBAAgB,OAAU;AAC9C,uBAAmB,MAAM;AAEzB,UAAM,cAAc,MAAM,QAAQ;AAKlC,UAAM,CAAC,QAAQ,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC1C,gBAAgB;AAAA,MAChB,qBAAqB;AAAA,IACvB,CAAC;AAED,UAAM,OAAO,QAAQ;AAErB,UAAM,QAAiB;AAAA,MACrB,SAAS,WAAW,MAAM;AAAA,MAC1B,MAAM;AAAA,QACJ,UAAU,OAAO,KAAK,iBAAiB;AAAA,QACvC,GAAI,KAAK,YAAY,EAAE,WAAW,KAAK,UAAU,IAAI,CAAC;AAAA,MACxD;AAAA,MACA,QAAQ,WAAW;AAAA,MACnB,YAAY,YAAY,IAAI,WAAW,SAAS,GAAG,UAAU;AAAA,MAC7D,QAAQ,MAAM,cAAc;AAAA,MAC5B,MAAM,QAAQ,QAAQ;AAAA,MACtB,GAAI,QAAQ,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;AAAA,IACjD;AAEA,WACE,qBAAC,iBAAc,OAAc,SAC3B;AAAA,0BAAC,mBAAiB,GAAG,OAAO;AAAA,MAC5B,oBAAC,YAAS,UAAU,MAClB,8BAAC,cAAW,cAAc,OAAO,cAAc,GACjD;AAAA,OACF;AAAA,EAEJ;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guard-rail/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Lightweight inline content editing for developer-owned Next.js sites.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"type": "module",
|
|
@@ -8,9 +8,18 @@
|
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"react-server": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.client.js"
|
|
14
|
+
},
|
|
15
|
+
"./server": {
|
|
11
16
|
"types": "./dist/index.d.ts",
|
|
12
17
|
"default": "./dist/index.js"
|
|
13
18
|
},
|
|
19
|
+
"./client": {
|
|
20
|
+
"types": "./dist/index.client.d.ts",
|
|
21
|
+
"default": "./dist/index.client.js"
|
|
22
|
+
},
|
|
14
23
|
"./adapters/supabase": {
|
|
15
24
|
"types": "./dist/adapters/supabase/index.d.ts",
|
|
16
25
|
"default": "./dist/adapters/supabase/index.js"
|
|
@@ -55,6 +64,7 @@
|
|
|
55
64
|
"@supabase/supabase-js": "^2.93.3",
|
|
56
65
|
"@types/node": "^25.1.0",
|
|
57
66
|
"@types/react": "^19.2.10",
|
|
67
|
+
"@types/react-dom": "^19.3.0",
|
|
58
68
|
"next": "16.1.6",
|
|
59
69
|
"react": "^19.2.4",
|
|
60
70
|
"tsup": "^8.5.1",
|