@lacrous/omnicloud 0.2.27 → 0.2.29
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.cjs +15 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +15 -10
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/server/index.js +16 -11
- package/server/web/assets/{index-Dn6lUGQf.js → index-Cimv9hDI.js} +1 -1
- package/server/web/index.html +1 -1
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?(
|
|
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(
|
|
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
|
|
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(
|
|
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?(
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
1223
|
+
async findByCaption(caption, size) {
|
|
1224
1224
|
if (!this.provider.findByCaption) return null;
|
|
1225
1225
|
try {
|
|
1226
|
-
return await this.provider.findByCaption(
|
|
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
|
-
|
|
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.
|
|
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
|
|
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(
|
|
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:
|
|
3209
|
+
search: caption,
|
|
3205
3210
|
limit: 20
|
|
3206
3211
|
})) {
|
|
3207
3212
|
if (!(message instanceof Api2.Message)) continue;
|
|
3208
|
-
if (message.message !==
|
|
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;
|