@rslsp1/fa-app-tools 1.3.12 → 1.3.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/index.d.mts CHANGED
@@ -479,6 +479,6 @@ declare function hfLoadMetadata(token: string): Promise<any[]>;
479
479
  declare function hfUploadImage(base64: string, id: string, token: string, mimeType?: string): Promise<void>;
480
480
  declare function hfLoadImageAsBase64(id: string, token: string): Promise<string | null>;
481
481
 
482
- declare const LIB_VERSION = "1.3.12";
482
+ declare const LIB_VERSION = "1.3.13";
483
483
 
484
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
@@ -479,6 +479,6 @@ declare function hfLoadMetadata(token: string): Promise<any[]>;
479
479
  declare function hfUploadImage(base64: string, id: string, token: string, mimeType?: string): Promise<void>;
480
480
  declare function hfLoadImageAsBase64(id: string, token: string): Promise<string | null>;
481
481
 
482
- declare const LIB_VERSION = "1.3.12";
482
+ declare const LIB_VERSION = "1.3.13";
483
483
 
484
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
@@ -3474,6 +3474,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3474
3474
  const [isLoadingFromHF, setIsLoadingFromHF] = (0, import_react21.useState)(false);
3475
3475
  const [hfMetadata, setHfMetadata] = (0, import_react21.useState)([]);
3476
3476
  const hfTagSaveTimer = (0, import_react21.useRef)(null);
3477
+ const hfMetaSaveQueue = (0, import_react21.useRef)(Promise.resolve());
3477
3478
  const wsInputRef = (0, import_react21.useRef)(null);
3478
3479
  const startApp = (choice) => {
3479
3480
  try {
@@ -3747,15 +3748,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3747
3748
  };
3748
3749
  hfUploadImage(base64, genId, hfToken).catch(() => {
3749
3750
  });
3750
- hfLoadMetadata(hfToken).then((existing) => {
3751
- const ids = new Set((existing || []).map((e) => e.id));
3752
- if (!ids.has(genId)) {
3753
- const next = [...existing || [], entry];
3754
- hfSaveMetadata(next, hfToken).catch(() => {
3755
- });
3756
- setHfMetadata(next);
3751
+ const token = hfToken;
3752
+ hfMetaSaveQueue.current = hfMetaSaveQueue.current.then(async () => {
3753
+ try {
3754
+ const existing = await hfLoadMetadata(token);
3755
+ const ids = new Set((existing || []).map((e) => e.id));
3756
+ if (!ids.has(genId)) {
3757
+ const next = [...existing || [], entry];
3758
+ await hfSaveMetadata(next, token);
3759
+ setHfMetadata(next);
3760
+ }
3761
+ } catch {
3757
3762
  }
3758
- }).catch(() => {
3759
3763
  });
3760
3764
  }
3761
3765
  } catch (err) {
@@ -4048,7 +4052,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4048
4052
  const entries = await hfLoadMetadata(token);
4049
4053
  if (!Array.isArray(entries) || entries.length === 0) return;
4050
4054
  setHfMetadata(entries);
4051
- const skeletons = entries.map((e) => ({
4055
+ const hfIds = new Set(entries.map((e) => e.id));
4056
+ const hfSkeletons = entries.map((e) => ({
4052
4057
  id: e.id,
4053
4058
  nodeId: e.id,
4054
4059
  prompt: e.prompt,
@@ -4058,15 +4063,22 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4058
4063
  timestamp: e.timestamp,
4059
4064
  status: "done"
4060
4065
  }));
4061
- setGalleryItems(skeletons);
4062
- setHistory(skeletons);
4063
- if (skeletons.length > 0) setCurrentResult(skeletons[0]);
4066
+ setGalleryItems((prev) => {
4067
+ const localOnly = prev.filter((g) => !hfIds.has(g.id));
4068
+ const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
4069
+ return [...localOnly, ...merged];
4070
+ });
4071
+ setHistory((prev) => {
4072
+ const localOnly = prev.filter((g) => !hfIds.has(g.id));
4073
+ const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
4074
+ return [...localOnly, ...merged];
4075
+ });
4064
4076
  for (const entry of entries) {
4065
4077
  hfLoadImageAsBase64(entry.id, token).then((b64) => {
4066
4078
  if (!b64) return;
4067
4079
  const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
4068
- setGalleryItems((prev) => prev.map((g) => g.id === entry.id ? { ...g, base64: prefix + b64 } : g));
4069
- setHistory((prev) => prev.map((g) => g.id === entry.id ? { ...g, base64: prefix + b64 } : g));
4080
+ setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
4081
+ setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
4070
4082
  }).catch(() => {
4071
4083
  });
4072
4084
  }
@@ -4908,7 +4920,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4908
4920
 
4909
4921
  // src/index.ts
4910
4922
  init_hfStateService();
4911
- var LIB_VERSION = "1.3.12";
4923
+ var LIB_VERSION = "1.3.13";
4912
4924
  // Annotate the CommonJS export names for ESM import in node:
4913
4925
  0 && (module.exports = {
4914
4926
  AvatarArchitectApp,
package/dist/index.mjs CHANGED
@@ -2917,6 +2917,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
2917
2917
  const [isLoadingFromHF, setIsLoadingFromHF] = useState14(false);
2918
2918
  const [hfMetadata, setHfMetadata] = useState14([]);
2919
2919
  const hfTagSaveTimer = useRef6(null);
2920
+ const hfMetaSaveQueue = useRef6(Promise.resolve());
2920
2921
  const wsInputRef = useRef6(null);
2921
2922
  const startApp = (choice) => {
2922
2923
  try {
@@ -3190,15 +3191,18 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3190
3191
  };
3191
3192
  hfUploadImage(base64, genId, hfToken).catch(() => {
3192
3193
  });
3193
- hfLoadMetadata(hfToken).then((existing) => {
3194
- const ids = new Set((existing || []).map((e) => e.id));
3195
- if (!ids.has(genId)) {
3196
- const next = [...existing || [], entry];
3197
- hfSaveMetadata(next, hfToken).catch(() => {
3198
- });
3199
- setHfMetadata(next);
3194
+ const token = hfToken;
3195
+ hfMetaSaveQueue.current = hfMetaSaveQueue.current.then(async () => {
3196
+ try {
3197
+ const existing = await hfLoadMetadata(token);
3198
+ const ids = new Set((existing || []).map((e) => e.id));
3199
+ if (!ids.has(genId)) {
3200
+ const next = [...existing || [], entry];
3201
+ await hfSaveMetadata(next, token);
3202
+ setHfMetadata(next);
3203
+ }
3204
+ } catch {
3200
3205
  }
3201
- }).catch(() => {
3202
3206
  });
3203
3207
  }
3204
3208
  } catch (err) {
@@ -3491,7 +3495,8 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3491
3495
  const entries = await hfLoadMetadata(token);
3492
3496
  if (!Array.isArray(entries) || entries.length === 0) return;
3493
3497
  setHfMetadata(entries);
3494
- const skeletons = entries.map((e) => ({
3498
+ const hfIds = new Set(entries.map((e) => e.id));
3499
+ const hfSkeletons = entries.map((e) => ({
3495
3500
  id: e.id,
3496
3501
  nodeId: e.id,
3497
3502
  prompt: e.prompt,
@@ -3501,15 +3506,22 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
3501
3506
  timestamp: e.timestamp,
3502
3507
  status: "done"
3503
3508
  }));
3504
- setGalleryItems(skeletons);
3505
- setHistory(skeletons);
3506
- if (skeletons.length > 0) setCurrentResult(skeletons[0]);
3509
+ setGalleryItems((prev) => {
3510
+ const localOnly = prev.filter((g) => !hfIds.has(g.id));
3511
+ const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
3512
+ return [...localOnly, ...merged];
3513
+ });
3514
+ setHistory((prev) => {
3515
+ const localOnly = prev.filter((g) => !hfIds.has(g.id));
3516
+ const merged = hfSkeletons.map((s) => prev.find((g) => g.id === s.id) ?? s);
3517
+ return [...localOnly, ...merged];
3518
+ });
3507
3519
  for (const entry of entries) {
3508
3520
  hfLoadImageAsBase64(entry.id, token).then((b64) => {
3509
3521
  if (!b64) return;
3510
3522
  const prefix = `data:${entry.mimeType || "image/jpeg"};base64,`;
3511
- setGalleryItems((prev) => prev.map((g) => g.id === entry.id ? { ...g, base64: prefix + b64 } : g));
3512
- setHistory((prev) => prev.map((g) => g.id === entry.id ? { ...g, base64: prefix + b64 } : g));
3523
+ setGalleryItems((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
3524
+ setHistory((prev) => prev.map((g) => g.id === entry.id && !g.base64 ? { ...g, base64: prefix + b64 } : g));
3513
3525
  }).catch(() => {
3514
3526
  });
3515
3527
  }
@@ -4350,7 +4362,7 @@ function AvatarArchitectApp({ onGenerateImage, onGeneratePrompt, onDownload, onS
4350
4362
  }
4351
4363
 
4352
4364
  // src/index.ts
4353
- var LIB_VERSION = "1.3.12";
4365
+ var LIB_VERSION = "1.3.13";
4354
4366
  export {
4355
4367
  AvatarArchitectApp,
4356
4368
  CollapsibleCard,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rslsp1/fa-app-tools",
3
- "version": "1.3.12",
3
+ "version": "1.3.13",
4
4
  "description": "Shared tools and hooks for Fine Art flow apps",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",