@lacrous/omnicloud 0.2.27 → 0.2.28

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
@@ -1106,6 +1106,8 @@ interface StorageUploadInput {
1106
1106
  size?: number;
1107
1107
  /** SHA-256 of the spooled bytes, computed while they were written. Required with `path`. */
1108
1108
  sha256?: string;
1109
+ /** Message caption that identifies this upload, so a later search can find it. */
1110
+ caption?: string;
1109
1111
  }
1110
1112
  interface StorageHealth {
1111
1113
  /** Reachable and usable. */
@@ -1142,7 +1144,7 @@ interface StorageProvider {
1142
1144
  * recover an upload whose outcome was unknown. Providers that cannot search
1143
1145
  * omit it, and the caller then treats the outcome as unresolved.
1144
1146
  */
1145
- findByCaption?(sha256: string, size: number): Promise<StoredObject[]>;
1147
+ findByCaption?(caption: string, size: number): Promise<StoredObject[]>;
1146
1148
  /** Validates that the backing store is reachable and usable. */
1147
1149
  healthCheck(): Promise<StorageHealth>;
1148
1150
  }
@@ -1193,7 +1195,7 @@ declare class StorageEngine {
1193
1195
  /** Read-only listing of stored objects, for reconciliation. Never modifies anything. */
1194
1196
  list(limit: number): Promise<StoredObject[]>;
1195
1197
  /** Read-only search for stored objects with this content hash and size. */
1196
- findByCaption(sha256: string, size: number): Promise<StoredObject[] | null>;
1198
+ findByCaption(caption: string, size: number): Promise<StoredObject[] | null>;
1197
1199
  stat(ref: StoredRef): Promise<StoredObject | null>;
1198
1200
  health(): Promise<StorageHealth>;
1199
1201
  verifyIntegrity(data: Buffer, expectedSha256: string): Promise<boolean>;
@@ -1647,10 +1649,10 @@ declare class TelegramStorageProvider implements StorageProvider {
1647
1649
  */
1648
1650
  listObjects(limit: number): Promise<StoredObject[]>;
1649
1651
  /**
1650
- * Finds stored documents whose caption equals the content hash and whose size
1652
+ * Finds stored documents whose caption equals the given caption and whose size
1651
1653
  * matches. Used to recover an upload whose outcome was unknown.
1652
1654
  */
1653
- findByCaption(sha256: string, size: number): Promise<StoredObject[]>;
1655
+ findByCaption(caption: string, size: number): Promise<StoredObject[]>;
1654
1656
  stat(ref: StoredRef): Promise<StoredObject | null>;
1655
1657
  /**
1656
1658
  * Validates that the client is connected and the storage channel is
package/dist/index.d.ts CHANGED
@@ -1106,6 +1106,8 @@ interface StorageUploadInput {
1106
1106
  size?: number;
1107
1107
  /** SHA-256 of the spooled bytes, computed while they were written. Required with `path`. */
1108
1108
  sha256?: string;
1109
+ /** Message caption that identifies this upload, so a later search can find it. */
1110
+ caption?: string;
1109
1111
  }
1110
1112
  interface StorageHealth {
1111
1113
  /** Reachable and usable. */
@@ -1142,7 +1144,7 @@ interface StorageProvider {
1142
1144
  * recover an upload whose outcome was unknown. Providers that cannot search
1143
1145
  * omit it, and the caller then treats the outcome as unresolved.
1144
1146
  */
1145
- findByCaption?(sha256: string, size: number): Promise<StoredObject[]>;
1147
+ findByCaption?(caption: string, size: number): Promise<StoredObject[]>;
1146
1148
  /** Validates that the backing store is reachable and usable. */
1147
1149
  healthCheck(): Promise<StorageHealth>;
1148
1150
  }
@@ -1193,7 +1195,7 @@ declare class StorageEngine {
1193
1195
  /** Read-only listing of stored objects, for reconciliation. Never modifies anything. */
1194
1196
  list(limit: number): Promise<StoredObject[]>;
1195
1197
  /** Read-only search for stored objects with this content hash and size. */
1196
- findByCaption(sha256: string, size: number): Promise<StoredObject[] | null>;
1198
+ findByCaption(caption: string, size: number): Promise<StoredObject[] | null>;
1197
1199
  stat(ref: StoredRef): Promise<StoredObject | null>;
1198
1200
  health(): Promise<StorageHealth>;
1199
1201
  verifyIntegrity(data: Buffer, expectedSha256: string): Promise<boolean>;
@@ -1647,10 +1649,10 @@ declare class TelegramStorageProvider implements StorageProvider {
1647
1649
  */
1648
1650
  listObjects(limit: number): Promise<StoredObject[]>;
1649
1651
  /**
1650
- * Finds stored documents whose caption equals the content hash and whose size
1652
+ * Finds stored documents whose caption equals the given caption and whose size
1651
1653
  * matches. Used to recover an upload whose outcome was unknown.
1652
1654
  */
1653
- findByCaption(sha256: string, size: number): Promise<StoredObject[]>;
1655
+ findByCaption(caption: string, size: number): Promise<StoredObject[]>;
1654
1656
  stat(ref: StoredRef): Promise<StoredObject | null>;
1655
1657
  /**
1656
1658
  * Validates that the client is connected and the storage channel is
package/dist/index.js CHANGED
@@ -1220,10 +1220,10 @@ var StorageEngine = class {
1220
1220
  }
1221
1221
  }
1222
1222
  /** Read-only search for stored objects with this content hash and size. */
1223
- async findByCaption(sha256, size) {
1223
+ async findByCaption(caption, size) {
1224
1224
  if (!this.provider.findByCaption) return null;
1225
1225
  try {
1226
- return await this.provider.findByCaption(sha256, size);
1226
+ return await this.provider.findByCaption(caption, size);
1227
1227
  } catch (error) {
1228
1228
  throw mapProviderError("Storage lookup failed", error);
1229
1229
  }
@@ -1449,6 +1449,9 @@ function uploadRequestFingerprint(input) {
1449
1449
  function contentSha256(input) {
1450
1450
  return input.spooled?.sha256 ?? sha256Hex(input.data ?? Buffer.alloc(0));
1451
1451
  }
1452
+ function uploadCaption(sha256, operationId) {
1453
+ return `${sha256}:${operationId}`;
1454
+ }
1452
1455
  function contentSize(input) {
1453
1456
  return input.spooled?.size ?? input.data?.byteLength ?? 0;
1454
1457
  }
@@ -1530,6 +1533,7 @@ var FileService = class {
1530
1533
  }
1531
1534
  try {
1532
1535
  const record = await this.performUpload(userId, input, {
1536
+ caption: uploadCaption(contentSha256(input), op.operationId),
1533
1537
  onStored: async (stored) => {
1534
1538
  await operations.update(op.id, { telegramMessageId: Number(stored.messageId) });
1535
1539
  await operations.claim(op.id, "UPLOADING", "COMMITTING");
@@ -1561,7 +1565,7 @@ var FileService = class {
1561
1565
  );
1562
1566
  }
1563
1567
  const engine = await this.engineFor(userId);
1564
- const matches = await engine.findByCaption(op.sha256, op.size);
1568
+ const matches = await engine.findByCaption(uploadCaption(op.sha256, op.operationId), op.size);
1565
1569
  if (matches === null) {
1566
1570
  throw new ConflictError(
1567
1571
  "This upload's outcome is unknown and the storage backend cannot search for it."
@@ -1666,8 +1670,9 @@ var FileService = class {
1666
1670
  mimeType,
1667
1671
  path: input.spooled.path,
1668
1672
  size: input.spooled.size,
1669
- sha256: input.spooled.sha256
1670
- } : { name, mimeType, data: input.data },
1673
+ sha256: input.spooled.sha256,
1674
+ caption: hooks.caption
1675
+ } : { name, mimeType, data: input.data, caption: hooks.caption },
1671
1676
  control
1672
1677
  );
1673
1678
  await hooks.onStored?.(stored);
@@ -3035,7 +3040,7 @@ var TelegramStorageProvider = class {
3035
3040
  file,
3036
3041
  forceDocument: true,
3037
3042
  workers: 1,
3038
- caption: input.sha256,
3043
+ caption: input.caption,
3039
3044
  // Surface transport-level progress to the caller. GramJS reports a
3040
3045
  // 0..1 fraction. `isCanceled` lets us abort an in-flight upload.
3041
3046
  progressCallback: Object.assign(
@@ -3194,18 +3199,18 @@ var TelegramStorageProvider = class {
3194
3199
  return objects;
3195
3200
  }
3196
3201
  /**
3197
- * Finds stored documents whose caption equals the content hash and whose size
3202
+ * Finds stored documents whose caption equals the given caption and whose size
3198
3203
  * matches. Used to recover an upload whose outcome was unknown.
3199
3204
  */
3200
- async findByCaption(sha256, size) {
3205
+ async findByCaption(caption, size) {
3201
3206
  const matches = [];
3202
3207
  try {
3203
3208
  for await (const message of this.client.iterMessages(this.peer, {
3204
- search: sha256,
3209
+ search: caption,
3205
3210
  limit: 20
3206
3211
  })) {
3207
3212
  if (!(message instanceof Api2.Message)) continue;
3208
- if (message.message !== sha256) continue;
3213
+ if (message.message !== caption) continue;
3209
3214
  const document = message.document;
3210
3215
  if (!(document instanceof Api2.Document)) continue;
3211
3216
  if (Number(document.size.toString()) !== size) continue;