@rslsp1/fa-app-tools 1.3.5 → 1.3.6

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.mts CHANGED
@@ -369,6 +369,7 @@ interface ProjectSyncTabProps {
369
369
  hfToken?: string;
370
370
  onHfLoad?: (file: File) => void;
371
371
  onProjectExportBase64?: () => Promise<string>;
372
+ onHfInitialSync?: (onProgress: (done: number, total: number) => void) => Promise<void>;
372
373
  }
373
374
  declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
374
375
 
@@ -478,6 +479,6 @@ declare function hfLoadMetadata(token: string): Promise<any[]>;
478
479
  declare function hfUploadImage(base64: string, id: string, token: string, mimeType?: string): Promise<void>;
479
480
  declare function hfLoadImageAsBase64(id: string, token: string): Promise<string | null>;
480
481
 
481
- declare const LIB_VERSION = "1.3.5";
482
+ declare const LIB_VERSION = "1.3.6";
482
483
 
483
484
  export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, type HFMetadataEntry, HistoryPanel, InspectPanel, LIB_VERSION, LabBlend, LabCompare, type LabFrame, LabImagePicker, type LabItem, LabLoop, LabRemix, type LabServices, LabsTab, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedLabImage, type SelectedTag, SetupPanel, type SyncDiff, TagManagerPanel, type TagOption, type WorkspaceTags, autoLabel, buildBlendInstruction, buildCompareInstruction, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildLoopInstruction, buildPromptTabPayload, buildReferenceImageMediaIds, buildRemixInstruction, buildScanInstruction, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, frameToGeneration, getFormattedTimestamp, getHFToken, groupGenerationsToLabItems, hfDeleteProject, hfDownloadProject, hfListProjects, hfLoadImageAsBase64, hfLoadMetadata, hfLoadTags, hfSaveMetadata, hfSaveTags, hfUploadImage, hfUploadProjectForm, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, setHFToken, useKeyboardNavigation, useOnClickOutside };
package/dist/index.d.ts CHANGED
@@ -369,6 +369,7 @@ interface ProjectSyncTabProps {
369
369
  hfToken?: string;
370
370
  onHfLoad?: (file: File) => void;
371
371
  onProjectExportBase64?: () => Promise<string>;
372
+ onHfInitialSync?: (onProgress: (done: number, total: number) => void) => Promise<void>;
372
373
  }
373
374
  declare const ProjectSyncTab: React.FC<ProjectSyncTabProps>;
374
375
 
@@ -478,6 +479,6 @@ declare function hfLoadMetadata(token: string): Promise<any[]>;
478
479
  declare function hfUploadImage(base64: string, id: string, token: string, mimeType?: string): Promise<void>;
479
480
  declare function hfLoadImageAsBase64(id: string, token: string): Promise<string | null>;
480
481
 
481
- declare const LIB_VERSION = "1.3.5";
482
+ declare const LIB_VERSION = "1.3.6";
482
483
 
483
484
  export { AvatarArchitectApp, type AvatarArchitectAppProps, CollapsibleCard, CompactDropdown, type ExtractedCharacter, FaToolsBadge, type FlowSdk, GLOBAL_STYLES, type Generation, type HFMetadataEntry, HistoryPanel, InspectPanel, LIB_VERSION, LabBlend, LabCompare, type LabFrame, LabImagePicker, type LabItem, LabLoop, LabRemix, type LabServices, LabsTab, ListView, type MediaItem, MediaLibrary, PillButton, type ProjectMeta, type ProjectSettings, ProjectSyncTab, PromptTab, SectionLabel, type SelectedLabImage, type SelectedTag, SetupPanel, type SyncDiff, TagManagerPanel, type TagOption, type WorkspaceTags, autoLabel, buildBlendInstruction, buildCompareInstruction, buildFallbackPrompt, buildGenerationPrompt, buildImageGenerationOptions, buildLoopInstruction, buildPromptTabPayload, buildReferenceImageMediaIds, buildRemixInstruction, buildScanInstruction, cleanAiResponse, createFlowServices, exportProjectToZip, formatTreeToMarkdown, frameToGeneration, getFormattedTimestamp, getHFToken, groupGenerationsToLabItems, hfDeleteProject, hfDownloadProject, hfListProjects, hfLoadImageAsBase64, hfLoadMetadata, hfLoadTags, hfSaveMetadata, hfSaveTags, hfUploadImage, hfUploadProjectForm, importProjectFromZip, injectXMPMetadata, interpretSdkError, parsePromptFile, parsePromptResponse, setHFToken, useKeyboardNavigation, useOnClickOutside };
package/dist/index.js CHANGED
@@ -1883,7 +1883,8 @@ var ProjectSyncTab = ({
1883
1883
  onExecuteSync,
1884
1884
  hfToken,
1885
1885
  onHfLoad,
1886
- onProjectExportBase64
1886
+ onProjectExportBase64,
1887
+ onHfInitialSync
1887
1888
  }) => {
1888
1889
  const projectInputRef = (0, import_react13.useRef)(null);
1889
1890
  const workspaceInputRef = (0, import_react13.useRef)(null);
@@ -1943,6 +1944,8 @@ var ProjectSyncTab = ({
1943
1944
  const [hfSaving, setHfSaving] = (0, import_react13.useState)(false);
1944
1945
  const [hfError, setHfError] = (0, import_react13.useState)(null);
1945
1946
  const [hfSaveName, setHfSaveName] = (0, import_react13.useState)("");
1947
+ const [hfSyncProgress, setHfSyncProgress] = (0, import_react13.useState)(null);
1948
+ const [hfSyncing, setHfSyncing] = (0, import_react13.useState)(false);
1946
1949
  const loadHfProjects = async (token) => {
1947
1950
  setHfLoading(true);
1948
1951
  setHfError(null);
@@ -2090,6 +2093,38 @@ var ProjectSyncTab = ({
2090
2093
  }
2091
2094
  )
2092
2095
  ] }),
2096
+ onHfInitialSync && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-2", children: [
2097
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2098
+ PillButton,
2099
+ {
2100
+ variant: "outline",
2101
+ icon: "cloud_sync",
2102
+ loading: hfSyncing,
2103
+ onClick: async () => {
2104
+ setHfSyncing(true);
2105
+ setHfError(null);
2106
+ setHfSyncProgress({ done: 0, total: 0 });
2107
+ try {
2108
+ await onHfInitialSync((done, total) => setHfSyncProgress({ done, total }));
2109
+ setHfSyncProgress(null);
2110
+ } catch (e) {
2111
+ setHfError(e.message);
2112
+ setHfSyncProgress(null);
2113
+ } finally {
2114
+ setHfSyncing(false);
2115
+ }
2116
+ },
2117
+ children: hfSyncing && hfSyncProgress ? `${hfSyncProgress.done} / ${hfSyncProgress.total} Bilder` : "Initial-Sync nach HF"
2118
+ }
2119
+ ),
2120
+ hfSyncing && hfSyncProgress && hfSyncProgress.total > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "w-full h-1 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2121
+ "div",
2122
+ {
2123
+ className: "h-full bg-blue-400 rounded-full transition-all",
2124
+ style: { width: `${Math.round(hfSyncProgress.done / hfSyncProgress.total * 100)}%` }
2125
+ }
2126
+ ) })
2127
+ ] }),
2093
2128
  hfError && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-[10px] text-red-400 font-mono px-1", children: hfError }),
2094
2129
  !hfLoading && hfProjects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-[10px] text-white/20 px-2", children: "Noch nichts auf HF gespeichert." }),
2095
2130
  hfProjects.map((p) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 px-3 py-2 rounded-xl bg-white/5 border border-white/5", children: [
@@ -3924,6 +3959,32 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3924
3959
  await onServerDelete(id);
3925
3960
  await fetchServerProjects();
3926
3961
  };
3962
+ const handleHfInitialSync = async (onProgress) => {
3963
+ if (!hfToken) return;
3964
+ const gens = galleryItems.filter((g) => g.base64 && g.status === "done");
3965
+ const total = gens.length;
3966
+ onProgress(0, total);
3967
+ let done = 0;
3968
+ for (const gen of gens) {
3969
+ const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
3970
+ const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
3971
+ await hfUploadImage(raw, gen.id, hfToken, mimeType);
3972
+ done++;
3973
+ onProgress(done, total);
3974
+ }
3975
+ const metaEntries = gens.map((g) => ({
3976
+ id: g.id,
3977
+ prompt: g.prompt || void 0,
3978
+ seed: g.seed,
3979
+ model: g.model,
3980
+ tags: g.tags || [],
3981
+ timestamp: g.timestamp,
3982
+ mimeType: g.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg"
3983
+ }));
3984
+ await hfSaveMetadata(metaEntries, hfToken);
3985
+ setHfMetadata(metaEntries);
3986
+ if (workspaceTags) await hfSaveTags(workspaceTags, hfToken);
3987
+ };
3927
3988
  const handleComputeSyncDiff = async () => {
3928
3989
  if (!onFetchServerProjects || !onServerLoad) throw new Error("Server nicht konfiguriert");
3929
3990
  const projects = await onFetchServerProjects();
@@ -4436,7 +4497,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4436
4497
  onProjectExportBase64: async () => {
4437
4498
  const { base64 } = await exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id));
4438
4499
  return base64;
4439
- }
4500
+ },
4501
+ onHfInitialSync: hfToken ? handleHfInitialSync : void 0
4440
4502
  }
4441
4503
  ),
4442
4504
  activeTab === "tags" && workspaceTags && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
@@ -4765,7 +4827,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4765
4827
  onProjectExportBase64: async () => {
4766
4828
  const { base64 } = await Promise.resolve().then(() => (init_project(), project_exports)).then((m) => m.exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id)));
4767
4829
  return base64;
4768
- }
4830
+ },
4831
+ onHfInitialSync: hfToken ? handleHfInitialSync : void 0
4769
4832
  }
4770
4833
  )
4771
4834
  ] })
@@ -4775,7 +4838,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4775
4838
 
4776
4839
  // src/index.ts
4777
4840
  init_hfStateService();
4778
- var LIB_VERSION = "1.3.5";
4841
+ var LIB_VERSION = "1.3.6";
4779
4842
  // Annotate the CommonJS export names for ESM import in node:
4780
4843
  0 && (module.exports = {
4781
4844
  AvatarArchitectApp,
package/dist/index.mjs CHANGED
@@ -1333,7 +1333,8 @@ var ProjectSyncTab = ({
1333
1333
  onExecuteSync,
1334
1334
  hfToken,
1335
1335
  onHfLoad,
1336
- onProjectExportBase64
1336
+ onProjectExportBase64,
1337
+ onHfInitialSync
1337
1338
  }) => {
1338
1339
  const projectInputRef = useRef5(null);
1339
1340
  const workspaceInputRef = useRef5(null);
@@ -1393,6 +1394,8 @@ var ProjectSyncTab = ({
1393
1394
  const [hfSaving, setHfSaving] = useState6(false);
1394
1395
  const [hfError, setHfError] = useState6(null);
1395
1396
  const [hfSaveName, setHfSaveName] = useState6("");
1397
+ const [hfSyncProgress, setHfSyncProgress] = useState6(null);
1398
+ const [hfSyncing, setHfSyncing] = useState6(false);
1396
1399
  const loadHfProjects = async (token) => {
1397
1400
  setHfLoading(true);
1398
1401
  setHfError(null);
@@ -1540,6 +1543,38 @@ var ProjectSyncTab = ({
1540
1543
  }
1541
1544
  )
1542
1545
  ] }),
1546
+ onHfInitialSync && /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
1547
+ /* @__PURE__ */ jsx12(
1548
+ PillButton,
1549
+ {
1550
+ variant: "outline",
1551
+ icon: "cloud_sync",
1552
+ loading: hfSyncing,
1553
+ onClick: async () => {
1554
+ setHfSyncing(true);
1555
+ setHfError(null);
1556
+ setHfSyncProgress({ done: 0, total: 0 });
1557
+ try {
1558
+ await onHfInitialSync((done, total) => setHfSyncProgress({ done, total }));
1559
+ setHfSyncProgress(null);
1560
+ } catch (e) {
1561
+ setHfError(e.message);
1562
+ setHfSyncProgress(null);
1563
+ } finally {
1564
+ setHfSyncing(false);
1565
+ }
1566
+ },
1567
+ children: hfSyncing && hfSyncProgress ? `${hfSyncProgress.done} / ${hfSyncProgress.total} Bilder` : "Initial-Sync nach HF"
1568
+ }
1569
+ ),
1570
+ hfSyncing && hfSyncProgress && hfSyncProgress.total > 0 && /* @__PURE__ */ jsx12("div", { className: "w-full h-1 bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx12(
1571
+ "div",
1572
+ {
1573
+ className: "h-full bg-blue-400 rounded-full transition-all",
1574
+ style: { width: `${Math.round(hfSyncProgress.done / hfSyncProgress.total * 100)}%` }
1575
+ }
1576
+ ) })
1577
+ ] }),
1543
1578
  hfError && /* @__PURE__ */ jsx12("p", { className: "text-[10px] text-red-400 font-mono px-1", children: hfError }),
1544
1579
  !hfLoading && hfProjects.length === 0 && /* @__PURE__ */ jsx12("p", { className: "text-[10px] text-white/20 px-2", children: "Noch nichts auf HF gespeichert." }),
1545
1580
  hfProjects.map((p) => /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 px-3 py-2 rounded-xl bg-white/5 border border-white/5", children: [
@@ -3367,6 +3402,32 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3367
3402
  await onServerDelete(id);
3368
3403
  await fetchServerProjects();
3369
3404
  };
3405
+ const handleHfInitialSync = async (onProgress) => {
3406
+ if (!hfToken) return;
3407
+ const gens = galleryItems.filter((g) => g.base64 && g.status === "done");
3408
+ const total = gens.length;
3409
+ onProgress(0, total);
3410
+ let done = 0;
3411
+ for (const gen of gens) {
3412
+ const raw = gen.base64.includes(",") ? gen.base64.split(",")[1] : gen.base64;
3413
+ const mimeType = gen.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg";
3414
+ await hfUploadImage(raw, gen.id, hfToken, mimeType);
3415
+ done++;
3416
+ onProgress(done, total);
3417
+ }
3418
+ const metaEntries = gens.map((g) => ({
3419
+ id: g.id,
3420
+ prompt: g.prompt || void 0,
3421
+ seed: g.seed,
3422
+ model: g.model,
3423
+ tags: g.tags || [],
3424
+ timestamp: g.timestamp,
3425
+ mimeType: g.base64.startsWith("data:image/png") ? "image/png" : "image/jpeg"
3426
+ }));
3427
+ await hfSaveMetadata(metaEntries, hfToken);
3428
+ setHfMetadata(metaEntries);
3429
+ if (workspaceTags) await hfSaveTags(workspaceTags, hfToken);
3430
+ };
3370
3431
  const handleComputeSyncDiff = async () => {
3371
3432
  if (!onFetchServerProjects || !onServerLoad) throw new Error("Server nicht konfiguriert");
3372
3433
  const projects = await onFetchServerProjects();
@@ -3879,7 +3940,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3879
3940
  onProjectExportBase64: async () => {
3880
3941
  const { base64 } = await exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id));
3881
3942
  return base64;
3882
- }
3943
+ },
3944
+ onHfInitialSync: hfToken ? handleHfInitialSync : void 0
3883
3945
  }
3884
3946
  ),
3885
3947
  activeTab === "tags" && workspaceTags && /* @__PURE__ */ jsx20(
@@ -4208,7 +4270,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4208
4270
  onProjectExportBase64: async () => {
4209
4271
  const { base64 } = await import("./project-O4ORKXY5.mjs").then((m) => m.exportProjectToZip(nodes, edges, history, galleryItems, { aspectRatio, selectedModel, seed, seedMode }, workspaceTags, recentLabItems.map((i) => i.id)));
4210
4272
  return base64;
4211
- }
4273
+ },
4274
+ onHfInitialSync: hfToken ? handleHfInitialSync : void 0
4212
4275
  }
4213
4276
  )
4214
4277
  ] })
@@ -4217,7 +4280,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4217
4280
  }
4218
4281
 
4219
4282
  // src/index.ts
4220
- var LIB_VERSION = "1.3.5";
4283
+ var LIB_VERSION = "1.3.6";
4221
4284
  export {
4222
4285
  AvatarArchitectApp,
4223
4286
  CollapsibleCard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "1.3.5",
3
+ "version": "1.3.6",
4
4
  "description": "Shared tools and hooks for Fine Art flow apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",