@sogni-ai/sogni-client 5.63.2 → 5.63.4

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.
@@ -20,6 +20,7 @@ import getUUID from '../lib/getUUID.js';
20
20
  import Cache from '../lib/Cache.js';
21
21
  import { enhancementDefaults } from './Job.js';
22
22
  import { calculateVideoFrames, getEnhacementStrength, getVideoAssetRequirements, getVideoContextImageSlots, getPixal3dOrbitViewSlots, getMinimaxH3KeyframeSlots, getMinimaxH3ReferenceAudioSlots, getMinimaxH3ReferenceVideoSlots, getVideoWorkflowType, asResultMediaKind, isAudioModel, isModelArtifactModel, isMinimaxH3ReferenceModel, isSegmentationModel, isVideoModel, resultMediaEvidence, usesReferenceMask } from './utils/index.js';
23
+ import { getFileContentType } from './utils/fileContentType.js';
23
24
  import { getMaxContextImages, validateSampler, isGptImageModel } from '../lib/validation.js';
24
25
  import { isAudioTier, isComfyImageTier, isImageTier, isVideoTier } from './types/ModelTiersRaw.js';
25
26
  import { mapAudioTier, mapComfyImageTier, mapImageTier, mapVideoTier } from './types/ModelOptions.js';
@@ -148,46 +149,6 @@ function deriveLoraCapableModelIds(loras) {
148
149
  }
149
150
  return Array.from(modelIds).sort();
150
151
  }
151
- /**
152
- * Detect content type from a file object.
153
- * For File objects in browser, uses the type property.
154
- * Returns undefined if content type cannot be detected.
155
- */
156
- function getFileContentType(file) {
157
- if (file instanceof Blob && 'type' in file && file.type) {
158
- return file.type;
159
- }
160
- if (typeof Buffer !== 'undefined' && Buffer.isBuffer(file)) {
161
- if (file.length >= 12) {
162
- if (file[0] === 0xff && file[1] === 0xd8 && file[2] === 0xff)
163
- return 'image/jpeg';
164
- if (file[0] === 0x89 && file[1] === 0x50 && file[2] === 0x4e && file[3] === 0x47) {
165
- return 'image/png';
166
- }
167
- if (file.toString('ascii', 0, 4) === 'RIFF' && file.toString('ascii', 8, 12) === 'WEBP') {
168
- return 'image/webp';
169
- }
170
- if (file.toString('ascii', 0, 3) === 'GIF')
171
- return 'image/gif';
172
- if (file.toString('ascii', 4, 8) === 'ftyp') {
173
- const brand = file.toString('ascii', 8, 12).toLowerCase();
174
- if (brand.includes('m4a') || brand.includes('m4b'))
175
- return 'audio/mp4';
176
- if (brand.includes('qt'))
177
- return 'video/quicktime';
178
- return 'video/mp4';
179
- }
180
- if (file.toString('ascii', 0, 4) === 'RIFF' && file.toString('ascii', 8, 12) === 'WAVE') {
181
- return 'audio/wav';
182
- }
183
- }
184
- if (file.length >= 3 && file.toString('ascii', 0, 3) === 'ID3')
185
- return 'audio/mpeg';
186
- if (file.length >= 2 && file[0] === 0xff && (file[1] & 0xe0) === 0xe0)
187
- return 'audio/mpeg';
188
- }
189
- return undefined;
190
- }
191
152
  /**
192
153
  * Convert file to a format compatible with fetch body.
193
154
  * Converts Node.js Buffer to Blob for cross-platform compatibility.
@@ -445,6 +406,8 @@ class ProjectsApi extends ApiGroup {
445
406
  /** Projects waiting for a reconnect to be resubmitted on. */
446
407
  this._awaitingResubmit = new Set();
447
408
  this._resubmitWaiters = new Set();
409
+ /** Initial sends finish after model lookups and uploads, independently of creation time. */
410
+ this._submittedAt = new Map();
448
411
  /** When each resubmitted project was last sent, for the recently-created grace. */
449
412
  this._resubmittedAt = new Map();
450
413
  /** Bumped on every transport loss; tells a frame sent before a drop from one sent after. */
@@ -527,6 +490,7 @@ class ProjectsApi extends ApiGroup {
527
490
  for (const stopWaiting of this._resubmitWaiters)
528
491
  stopWaiting();
529
492
  this._awaitingResubmit.clear();
493
+ this._submittedAt.clear();
530
494
  this._resubmittedAt.clear();
531
495
  this._sentOnGeneration.clear();
532
496
  this._recoveredCompletedIds.clear();
@@ -961,6 +925,7 @@ class ProjectsApi extends ApiGroup {
961
925
  }
962
926
  if (project.finished) {
963
927
  this._unadmittedRequests.delete(project.id);
928
+ this._submittedAt.delete(project.id);
964
929
  this._resubmittedAt.delete(project.id);
965
930
  this._sentOnGeneration.delete(project.id);
966
931
  // Sync project data with the server and remove it from the list after some time
@@ -1248,8 +1213,8 @@ class ProjectsApi extends ApiGroup {
1248
1213
  }, Math.max(0, delayMs) + 250);
1249
1214
  }
1250
1215
  _lastSubmittedAt(project) {
1251
- var _a;
1252
- return Math.max(project.startedAt.getTime(), (_a = this._resubmittedAt.get(project.id)) !== null && _a !== void 0 ? _a : 0);
1216
+ var _a, _b;
1217
+ return Math.max((_a = this._submittedAt.get(project.id)) !== null && _a !== void 0 ? _a : project.startedAt.getTime(), (_b = this._resubmittedAt.get(project.id)) !== null && _b !== void 0 ? _b : 0);
1253
1218
  }
1254
1219
  handleServerConnected() {
1255
1220
  this.transportDisconnected = false;
@@ -1969,6 +1934,7 @@ class ProjectsApi extends ApiGroup {
1969
1934
  _trackSubmitted(project) {
1970
1935
  const tracked = this.projects.find((candidate) => candidate.id === project.id);
1971
1936
  if (!tracked) {
1937
+ this._submittedAt.set(project.id, Date.now());
1972
1938
  this.projects.push(project);
1973
1939
  return project;
1974
1940
  }
@@ -2028,7 +1994,7 @@ class ProjectsApi extends ApiGroup {
2028
1994
  if (!keyFrame)
2029
1995
  return;
2030
1996
  if (data.referenceAudio && data.referenceAudio !== true) {
2031
- keyFrame.referenceAudioContentType = getFileContentType(data.referenceAudio);
1997
+ keyFrame.referenceAudioContentType = getFileContentType(data.referenceAudio, 'audio');
2032
1998
  }
2033
1999
  }
2034
2000
  _processVideoAssets(project, data) {
@@ -2092,25 +2058,25 @@ class ProjectsApi extends ApiGroup {
2092
2058
  }
2093
2059
  const isMinimaxH3R2v = isMinimaxH3ReferenceModel(data.modelId);
2094
2060
  if (!isMinimaxH3R2v && data.referenceAudio && data.referenceAudio !== true) {
2095
- keyFrame.referenceAudioContentType = getFileContentType(data.referenceAudio);
2061
+ keyFrame.referenceAudioContentType = getFileContentType(data.referenceAudio, 'audio');
2096
2062
  }
2097
2063
  if (data.referenceAudioIdentity && data.referenceAudioIdentity !== true) {
2098
- const contentType = getFileContentType(data.referenceAudioIdentity);
2064
+ const contentType = getFileContentType(data.referenceAudioIdentity, 'audio');
2099
2065
  keyFrame.referenceAudioIdentityContentType = contentType;
2100
2066
  (_b = keyFrame.referenceAudioContentType) !== null && _b !== void 0 ? _b : (keyFrame.referenceAudioContentType = contentType);
2101
2067
  }
2102
2068
  if (!isMinimaxH3R2v && data.referenceVideo && data.referenceVideo !== true) {
2103
- keyFrame.referenceVideoContentType = getFileContentType(data.referenceVideo);
2069
+ keyFrame.referenceVideoContentType = getFileContentType(data.referenceVideo, 'video');
2104
2070
  }
2105
2071
  if (isMinimaxH3R2v) {
2106
2072
  for (const { slot, media } of getMinimaxH3ReferenceAudioSlots(data)) {
2107
2073
  if (typeof media !== 'boolean') {
2108
- keyFrame[`referenceAudio${slot}ContentType`] = getFileContentType(media);
2074
+ keyFrame[`referenceAudio${slot}ContentType`] = getFileContentType(media, 'audio');
2109
2075
  }
2110
2076
  }
2111
2077
  for (const { slot, media } of getMinimaxH3ReferenceVideoSlots(data)) {
2112
2078
  if (typeof media !== 'boolean') {
2113
- keyFrame[`referenceVideo${slot}ContentType`] = getFileContentType(media);
2079
+ keyFrame[`referenceVideo${slot}ContentType`] = getFileContentType(media, 'video');
2114
2080
  }
2115
2081
  }
2116
2082
  }
@@ -2731,7 +2697,7 @@ class ProjectsApi extends ApiGroup {
2731
2697
  var _a;
2732
2698
  const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : captureRequestSession(this.client.auth);
2733
2699
  assertSession();
2734
- const contentType = getFileContentType(file);
2700
+ const contentType = getFileContentType(file, 'audio');
2735
2701
  if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceAudio', id }))
2736
2702
  return;
2737
2703
  assertSession();
@@ -2771,7 +2737,7 @@ class ProjectsApi extends ApiGroup {
2771
2737
  var _a;
2772
2738
  const assertSession = (_a = this._preparingSessions.get(projectId)) !== null && _a !== void 0 ? _a : captureRequestSession(this.client.auth);
2773
2739
  assertSession();
2774
- const contentType = getFileContentType(file);
2740
+ const contentType = getFileContentType(file, 'video');
2775
2741
  if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceVideo', id }))
2776
2742
  return;
2777
2743
  assertSession();