@arbidocs/blocks 0.3.114 → 0.3.115

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.cts CHANGED
@@ -1113,6 +1113,12 @@ interface StudioPersistence {
1113
1113
  */
1114
1114
  savePublished: (arbi: Arbi | null, live: boolean, slug: string, data: unknown) => Promise<PersistVia>;
1115
1115
  loadPublished: <T>(arbi: Arbi | null, live: boolean, slug: string) => Promise<LoadResult<T>>;
1116
+ /**
1117
+ * Delete a slug's stored authoring + published pages (backend and localStorage
1118
+ * mirror). Lets a page be reset to empty; also the deterministic-reset hook a
1119
+ * test/demo needs, since backend content otherwise wins over a fresh seed.
1120
+ */
1121
+ deletePage: (arbi: Arbi | null, live: boolean, slug: string) => Promise<void>;
1116
1122
  saveTheme: (arbi: Arbi | null, live: boolean, theme: unknown) => Promise<PersistVia>;
1117
1123
  loadTheme: <T>(arbi: Arbi | null, live: boolean) => Promise<LoadResult<T>>;
1118
1124
  }
@@ -1174,6 +1180,13 @@ interface StudioEditorProps {
1174
1180
  live: boolean;
1175
1181
  initialSlug?: string;
1176
1182
  testIdPrefix?: string;
1183
+ /**
1184
+ * Install a DEV-only `window.__studioResetSlug(slug)` hook that clears a slug's
1185
+ * stored page so a fresh seed governs the canvas. For tests/demos only — it can
1186
+ * delete pages, so keep it off in production (pass `import.meta.env.DEV`). The
1187
+ * package stays env-agnostic; the consumer owns the flag.
1188
+ */
1189
+ resetSeam?: boolean;
1177
1190
  /**
1178
1191
  * Optional sink for published image bytes. When omitted, publishing inlines
1179
1192
  * each asset as a `data:` URI (self-contained, no backend). Provide this to
@@ -1181,7 +1194,7 @@ interface StudioEditorProps {
1181
1194
  */
1182
1195
  publishAsset?: MaterializeOptions['publishAsset'];
1183
1196
  }
1184
- declare function StudioEditor({ config, pages, persistence, themeBundle, defaultTheme, brandLabel, backHref, backLabel, live, initialSlug, testIdPrefix, publishAsset, }: StudioEditorProps): react.JSX.Element;
1197
+ declare function StudioEditor({ config, pages, persistence, themeBundle, defaultTheme, brandLabel, backHref, backLabel, live, initialSlug, testIdPrefix, publishAsset, resetSeam, }: StudioEditorProps): react.JSX.Element;
1185
1198
 
1186
1199
  interface PageRendererProps {
1187
1200
  config: Config;
package/dist/index.d.ts CHANGED
@@ -1113,6 +1113,12 @@ interface StudioPersistence {
1113
1113
  */
1114
1114
  savePublished: (arbi: Arbi | null, live: boolean, slug: string, data: unknown) => Promise<PersistVia>;
1115
1115
  loadPublished: <T>(arbi: Arbi | null, live: boolean, slug: string) => Promise<LoadResult<T>>;
1116
+ /**
1117
+ * Delete a slug's stored authoring + published pages (backend and localStorage
1118
+ * mirror). Lets a page be reset to empty; also the deterministic-reset hook a
1119
+ * test/demo needs, since backend content otherwise wins over a fresh seed.
1120
+ */
1121
+ deletePage: (arbi: Arbi | null, live: boolean, slug: string) => Promise<void>;
1116
1122
  saveTheme: (arbi: Arbi | null, live: boolean, theme: unknown) => Promise<PersistVia>;
1117
1123
  loadTheme: <T>(arbi: Arbi | null, live: boolean) => Promise<LoadResult<T>>;
1118
1124
  }
@@ -1174,6 +1180,13 @@ interface StudioEditorProps {
1174
1180
  live: boolean;
1175
1181
  initialSlug?: string;
1176
1182
  testIdPrefix?: string;
1183
+ /**
1184
+ * Install a DEV-only `window.__studioResetSlug(slug)` hook that clears a slug's
1185
+ * stored page so a fresh seed governs the canvas. For tests/demos only — it can
1186
+ * delete pages, so keep it off in production (pass `import.meta.env.DEV`). The
1187
+ * package stays env-agnostic; the consumer owns the flag.
1188
+ */
1189
+ resetSeam?: boolean;
1177
1190
  /**
1178
1191
  * Optional sink for published image bytes. When omitted, publishing inlines
1179
1192
  * each asset as a `data:` URI (self-contained, no backend). Provide this to
@@ -1181,7 +1194,7 @@ interface StudioEditorProps {
1181
1194
  */
1182
1195
  publishAsset?: MaterializeOptions['publishAsset'];
1183
1196
  }
1184
- declare function StudioEditor({ config, pages, persistence, themeBundle, defaultTheme, brandLabel, backHref, backLabel, live, initialSlug, testIdPrefix, publishAsset, }: StudioEditorProps): react.JSX.Element;
1197
+ declare function StudioEditor({ config, pages, persistence, themeBundle, defaultTheme, brandLabel, backHref, backLabel, live, initialSlug, testIdPrefix, publishAsset, resetSeam, }: StudioEditorProps): react.JSX.Element;
1185
1198
 
1186
1199
  interface PageRendererProps {
1187
1200
  config: Config;
package/dist/index.js CHANGED
@@ -2375,7 +2375,8 @@ function StudioEditor({
2375
2375
  live,
2376
2376
  initialSlug,
2377
2377
  testIdPrefix = "studio",
2378
- publishAsset
2378
+ publishAsset,
2379
+ resetSeam = false
2379
2380
  }) {
2380
2381
  const arbi = useArbi();
2381
2382
  const materialize = useMemo(
@@ -2406,6 +2407,14 @@ function StudioEditor({
2406
2407
  cancelled = true;
2407
2408
  };
2408
2409
  }, [slug, live]);
2410
+ useEffect(() => {
2411
+ if (!resetSeam) return;
2412
+ const w = window;
2413
+ w.__studioResetSlug = (s) => persistence.deletePage(arbi, live, s);
2414
+ return () => {
2415
+ delete w.__studioResetSlug;
2416
+ };
2417
+ }, [resetSeam, arbi, live, persistence]);
2409
2418
  const persist4 = useCallback(
2410
2419
  async (toSave) => {
2411
2420
  setSaving(true);
@@ -2691,6 +2700,26 @@ function createStudioPersistence(cfg) {
2691
2700
  function loadPublished(arbi, live, slug) {
2692
2701
  return readPage(arbi, live, publishedKey(slug), publishedFile(slug));
2693
2702
  }
2703
+ async function deletePage(arbi, live, slug) {
2704
+ try {
2705
+ localStorage.removeItem(pageKey(slug));
2706
+ localStorage.removeItem(publishedKey(slug));
2707
+ } catch {
2708
+ }
2709
+ if (!canUseArbi(arbi, live)) return;
2710
+ try {
2711
+ await arbi.selectWorkspace(WORKSPACE_ID);
2712
+ const docs = await arbi.documents.list();
2713
+ const names = [pageFile(slug), publishedFile(slug)];
2714
+ const ids = docs.filter(
2715
+ (d) => (d.folder ?? "").includes(FOLDER) && names.some((n) => (d.file_name ?? "").endsWith(n))
2716
+ ).map((d) => d.external_id);
2717
+ if (ids.length) await arbi.documents.delete(ids);
2718
+ console.info(`[studio] deleted ${ids.length} doc(s) for "${slug}" from ARBI`);
2719
+ } catch (e) {
2720
+ console.warn(`[studio] ARBI delete failed for "${slug}"`, e);
2721
+ }
2722
+ }
2694
2723
  async function saveTheme(arbi, live, theme) {
2695
2724
  try {
2696
2725
  localStorage.setItem(THEME_KEY, JSON.stringify(theme));
@@ -2727,7 +2756,7 @@ function createStudioPersistence(cfg) {
2727
2756
  return null;
2728
2757
  }
2729
2758
  }
2730
- return { savePage, loadPage, savePublished, loadPublished, saveTheme, loadTheme };
2759
+ return { savePage, loadPage, savePublished, loadPublished, deletePage, saveTheme, loadTheme };
2731
2760
  }
2732
2761
  function AiTextField({
2733
2762
  value,
@@ -2967,7 +2996,7 @@ function ImageFieldControl({
2967
2996
  {
2968
2997
  src: thumb,
2969
2998
  alt: d.file_name ?? "",
2970
- className: "aspect-square w-full object-cover"
2999
+ className: "aspect-square w-full bg-muted object-contain"
2971
3000
  }
2972
3001
  ) : /* @__PURE__ */ jsx("span", { className: "flex aspect-square w-full items-center justify-center bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx(ImagePlus, { className: "size-4" }) })
2973
3002
  },