@milaboratories/pl-drivers 1.5.10 → 1.5.12
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/clients/constructors.d.ts.map +1 -1
- package/dist/clients/download.d.ts.map +1 -1
- package/dist/clients/logs.d.ts.map +1 -1
- package/dist/clients/ls_api.d.ts.map +1 -1
- package/dist/clients/progress.d.ts.map +1 -1
- package/dist/clients/upload.d.ts.map +1 -1
- package/dist/drivers/download_blob.d.ts +2 -2
- package/dist/drivers/download_blob.d.ts.map +1 -1
- package/dist/drivers/download_blob_task.d.ts +2 -2
- package/dist/drivers/download_blob_task.d.ts.map +1 -1
- package/dist/drivers/download_blob_url/driver.d.ts +46 -0
- package/dist/drivers/download_blob_url/driver.d.ts.map +1 -0
- package/dist/drivers/download_blob_url/driver_id.d.ts +6 -0
- package/dist/drivers/download_blob_url/driver_id.d.ts.map +1 -0
- package/dist/drivers/download_blob_url/snapshot.d.ts +7 -0
- package/dist/drivers/download_blob_url/snapshot.d.ts.map +1 -0
- package/dist/drivers/download_blob_url/task.d.ts +64 -0
- package/dist/drivers/download_blob_url/task.d.ts.map +1 -0
- package/dist/drivers/download_blob_url/url.d.ts +6 -0
- package/dist/drivers/download_blob_url/url.d.ts.map +1 -0
- package/dist/drivers/download_url.d.ts +2 -2
- package/dist/drivers/download_url.d.ts.map +1 -1
- package/dist/drivers/helpers/download_local_handle.d.ts.map +1 -1
- package/dist/drivers/helpers/download_remote_handle.d.ts.map +1 -1
- package/dist/drivers/helpers/files_cache.d.ts.map +1 -1
- package/dist/drivers/helpers/logs_handle.d.ts +1 -1
- package/dist/drivers/helpers/logs_handle.d.ts.map +1 -1
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts +1 -1
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts.map +1 -1
- package/dist/drivers/helpers/ls_storage_entry.d.ts +1 -1
- package/dist/drivers/helpers/ls_storage_entry.d.ts.map +1 -1
- package/dist/drivers/logs.d.ts +2 -2
- package/dist/drivers/logs.d.ts.map +1 -1
- package/dist/drivers/logs_stream.d.ts +2 -2
- package/dist/drivers/logs_stream.d.ts.map +1 -1
- package/dist/drivers/ls.d.ts +1 -1
- package/dist/drivers/ls.d.ts.map +1 -1
- package/dist/drivers/types.d.ts.map +1 -1
- package/dist/drivers/upload.d.ts +1 -1
- package/dist/drivers/upload.d.ts.map +1 -1
- package/dist/drivers/upload_task.d.ts +1 -1
- package/dist/drivers/upload_task.d.ts.map +1 -1
- package/dist/drivers/virtual_storages.d.ts.map +1 -1
- package/dist/helpers/download.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2312 -2067
- package/dist/index.mjs.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts.map +1 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +1 -1
- package/dist/proto/google/api/http.d.ts +28 -28
- package/dist/proto/google/api/http.d.ts.map +1 -1
- package/dist/proto/google/protobuf/descriptor.d.ts.map +1 -1
- package/dist/proto/google/protobuf/duration.d.ts.map +1 -1
- package/dist/proto/google/protobuf/timestamp.d.ts.map +1 -1
- package/package.json +9 -4
- package/src/clients/constructors.ts +11 -11
- package/src/clients/download.test.ts +11 -10
- package/src/clients/download.ts +15 -14
- package/src/clients/logs.ts +13 -12
- package/src/clients/ls_api.ts +7 -7
- package/src/clients/progress.ts +15 -13
- package/src/clients/upload.test.ts +6 -5
- package/src/clients/upload.ts +28 -26
- package/src/drivers/download_blob.test.ts +21 -20
- package/src/drivers/download_blob.ts +47 -42
- package/src/drivers/download_blob_task.ts +25 -21
- package/src/drivers/download_blob_url/driver.ts +225 -0
- package/src/drivers/download_blob_url/driver_id.ts +11 -0
- package/src/drivers/download_blob_url/snapshot.ts +20 -0
- package/src/drivers/download_blob_url/task.ts +230 -0
- package/src/drivers/download_blob_url/url.test.ts +39 -0
- package/src/drivers/download_blob_url/url.ts +43 -0
- package/src/drivers/download_url.test.ts +3 -3
- package/src/drivers/download_url.ts +21 -20
- package/src/drivers/helpers/download_local_handle.ts +2 -2
- package/src/drivers/helpers/download_remote_handle.ts +8 -8
- package/src/drivers/helpers/files_cache.test.ts +7 -6
- package/src/drivers/helpers/files_cache.ts +2 -1
- package/src/drivers/helpers/helpers.ts +1 -1
- package/src/drivers/helpers/logs_handle.ts +7 -7
- package/src/drivers/helpers/ls_remote_import_handle.ts +7 -7
- package/src/drivers/helpers/ls_storage_entry.ts +6 -5
- package/src/drivers/logs.test.ts +23 -22
- package/src/drivers/logs.ts +13 -12
- package/src/drivers/logs_stream.ts +42 -37
- package/src/drivers/ls.test.ts +2 -2
- package/src/drivers/ls.ts +38 -35
- package/src/drivers/types.ts +12 -11
- package/src/drivers/upload.test.ts +19 -17
- package/src/drivers/upload.ts +30 -25
- package/src/drivers/upload_task.ts +23 -19
- package/src/drivers/virtual_storages.ts +6 -6
- package/src/helpers/download.ts +8 -8
- package/src/index.ts +2 -0
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.ts +4 -4
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.ts +88 -73
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.ts +2 -2
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.ts +71 -56
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.ts +6 -5
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.ts +130 -106
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.ts +14 -10
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.ts +142 -121
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.ts +11 -8
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.ts +216 -174
- package/src/proto/google/api/http.ts +95 -86
- package/src/proto/google/protobuf/descriptor.ts +674 -593
- package/src/proto/google/protobuf/duration.ts +31 -26
- package/src/proto/google/protobuf/timestamp.ts +52 -44
package/src/clients/download.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { addRTypeToMetadata } from '@milaboratories/pl-client';
|
|
2
|
-
import { ResourceInfo } from '@milaboratories/pl-tree';
|
|
3
|
-
import { MiLogger } from '@milaboratories/ts-helpers';
|
|
4
|
-
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
2
|
+
import type { ResourceInfo } from '@milaboratories/pl-tree';
|
|
3
|
+
import type { MiLogger } from '@milaboratories/ts-helpers';
|
|
4
|
+
import type { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
5
5
|
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
6
6
|
import * as fs from 'node:fs';
|
|
7
7
|
import * as fsp from 'node:fs/promises';
|
|
8
8
|
import * as path from 'node:path';
|
|
9
9
|
import { Readable } from 'node:stream';
|
|
10
|
-
import { Dispatcher } from 'undici';
|
|
11
|
-
import { LocalStorageProjection } from '../drivers/types';
|
|
12
|
-
import { DownloadResponse
|
|
10
|
+
import type { Dispatcher } from 'undici';
|
|
11
|
+
import type { LocalStorageProjection } from '../drivers/types';
|
|
12
|
+
import type { DownloadResponse } from '../helpers/download';
|
|
13
|
+
import { RemoteFileDownloader } from '../helpers/download';
|
|
13
14
|
import { validateAbsolute } from '../helpers/validate';
|
|
14
|
-
import { DownloadAPI_GetDownloadURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol';
|
|
15
|
+
import type { DownloadAPI_GetDownloadURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol';
|
|
15
16
|
import { DownloadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client';
|
|
16
17
|
import { toHeadersMap } from './helpers';
|
|
17
18
|
|
|
@@ -29,7 +30,7 @@ export class ClientDownload {
|
|
|
29
30
|
public readonly httpClient: Dispatcher,
|
|
30
31
|
public readonly logger: MiLogger,
|
|
31
32
|
/** Pl storages available locally */
|
|
32
|
-
localProjections: LocalStorageProjection[]
|
|
33
|
+
localProjections: LocalStorageProjection[],
|
|
33
34
|
) {
|
|
34
35
|
this.grpcClient = new DownloadClient(this.grpcTransport);
|
|
35
36
|
this.remoteFileDownloader = new RemoteFileDownloader(httpClient);
|
|
@@ -41,7 +42,7 @@ export class ClientDownload {
|
|
|
41
42
|
async downloadBlob(
|
|
42
43
|
info: ResourceInfo,
|
|
43
44
|
options?: RpcOptions,
|
|
44
|
-
signal?: AbortSignal
|
|
45
|
+
signal?: AbortSignal,
|
|
45
46
|
): Promise<DownloadResponse> {
|
|
46
47
|
const { downloadUrl, headers } = await this.grpcGetDownloadUrl(info, options, signal);
|
|
47
48
|
|
|
@@ -58,21 +59,21 @@ export class ClientDownload {
|
|
|
58
59
|
|
|
59
60
|
return {
|
|
60
61
|
content: Readable.toWeb(fs.createReadStream(fullPath)),
|
|
61
|
-
size: (await fsp.stat(fullPath)).size
|
|
62
|
+
size: (await fsp.stat(fullPath)).size,
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
private async grpcGetDownloadUrl(
|
|
66
67
|
{ id, type }: ResourceInfo,
|
|
67
68
|
options?: RpcOptions,
|
|
68
|
-
signal?: AbortSignal
|
|
69
|
+
signal?: AbortSignal,
|
|
69
70
|
): Promise<DownloadAPI_GetDownloadURL_Response> {
|
|
70
71
|
const withAbort = options ?? {};
|
|
71
72
|
withAbort.abort = signal;
|
|
72
73
|
|
|
73
74
|
return await this.grpcClient.getDownloadURL(
|
|
74
75
|
{ resourceId: id },
|
|
75
|
-
addRTypeToMetadata(type, withAbort)
|
|
76
|
+
addRTypeToMetadata(type, withAbort),
|
|
76
77
|
).response;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
@@ -84,14 +85,14 @@ export function parseLocalUrl(url: string) {
|
|
|
84
85
|
|
|
85
86
|
return {
|
|
86
87
|
storageId: parsed.host,
|
|
87
|
-
relativePath: decodeURIComponent(parsed.pathname.slice(1))
|
|
88
|
+
relativePath: decodeURIComponent(parsed.pathname.slice(1)),
|
|
88
89
|
};
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
export function getFullPath(
|
|
92
93
|
storageId: string,
|
|
93
94
|
localStorageIdsToRoot: Map<string, string>,
|
|
94
|
-
relativePath: string
|
|
95
|
+
relativePath: string,
|
|
95
96
|
) {
|
|
96
97
|
const root = localStorageIdsToRoot.get(storageId);
|
|
97
98
|
if (root === undefined) throw new UnknownStorageError(`Unknown storage location: ${storageId}`);
|
package/src/clients/logs.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { StreamingClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client';
|
|
2
|
-
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
2
|
+
import type { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
3
3
|
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
4
|
-
import { MiLogger
|
|
5
|
-
import {
|
|
4
|
+
import type { MiLogger } from '@milaboratories/ts-helpers';
|
|
5
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
6
|
+
import type { Dispatcher } from 'undici';
|
|
6
7
|
import { addRTypeToMetadata } from '@milaboratories/pl-client';
|
|
7
|
-
import { StreamingAPI_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol';
|
|
8
|
-
import { ResourceInfo } from '@milaboratories/pl-tree';
|
|
8
|
+
import type { StreamingAPI_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol';
|
|
9
|
+
import type { ResourceInfo } from '@milaboratories/pl-tree';
|
|
9
10
|
|
|
10
11
|
export class ClientLogs {
|
|
11
12
|
public readonly grpcClient: StreamingClient;
|
|
@@ -13,7 +14,7 @@ export class ClientLogs {
|
|
|
13
14
|
constructor(
|
|
14
15
|
public readonly grpcTransport: GrpcTransport,
|
|
15
16
|
public readonly httpClient: Dispatcher,
|
|
16
|
-
public readonly logger: MiLogger
|
|
17
|
+
public readonly logger: MiLogger,
|
|
17
18
|
) {
|
|
18
19
|
this.grpcClient = new StreamingClient(this.grpcTransport);
|
|
19
20
|
}
|
|
@@ -28,7 +29,7 @@ export class ClientLogs {
|
|
|
28
29
|
lineCount: number,
|
|
29
30
|
offsetBytes: bigint = 0n, // if 0n, then start from the end.
|
|
30
31
|
searchStr?: string,
|
|
31
|
-
options?: RpcOptions
|
|
32
|
+
options?: RpcOptions,
|
|
32
33
|
): Promise<StreamingAPI_Response> {
|
|
33
34
|
return (
|
|
34
35
|
await this.grpcClient.lastLines(
|
|
@@ -36,9 +37,9 @@ export class ClientLogs {
|
|
|
36
37
|
resourceId: rId,
|
|
37
38
|
lineCount: lineCount,
|
|
38
39
|
offset: offsetBytes,
|
|
39
|
-
search: searchStr
|
|
40
|
+
search: searchStr,
|
|
40
41
|
},
|
|
41
|
-
addRTypeToMetadata(rType, options)
|
|
42
|
+
addRTypeToMetadata(rType, options),
|
|
42
43
|
)
|
|
43
44
|
).response;
|
|
44
45
|
}
|
|
@@ -51,7 +52,7 @@ export class ClientLogs {
|
|
|
51
52
|
lineCount: number,
|
|
52
53
|
offsetBytes: bigint = 0n, // if 0n, then start from the beginning.
|
|
53
54
|
searchStr?: string,
|
|
54
|
-
options?: RpcOptions
|
|
55
|
+
options?: RpcOptions,
|
|
55
56
|
): Promise<StreamingAPI_Response> {
|
|
56
57
|
return (
|
|
57
58
|
await this.grpcClient.readText(
|
|
@@ -59,9 +60,9 @@ export class ClientLogs {
|
|
|
59
60
|
resourceId: notEmpty(rId),
|
|
60
61
|
readLimit: BigInt(lineCount),
|
|
61
62
|
offset: offsetBytes,
|
|
62
|
-
search: searchStr
|
|
63
|
+
search: searchStr,
|
|
63
64
|
},
|
|
64
|
-
addRTypeToMetadata(rType, options)
|
|
65
|
+
addRTypeToMetadata(rType, options),
|
|
65
66
|
)
|
|
66
67
|
).response;
|
|
67
68
|
}
|
package/src/clients/ls_api.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { MiLogger } from '@milaboratories/ts-helpers';
|
|
1
|
+
import type { MiLogger } from '@milaboratories/ts-helpers';
|
|
2
2
|
import type { LsAPI_List_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol';
|
|
3
3
|
import { LSClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client';
|
|
4
|
-
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
4
|
+
import type { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
5
5
|
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
6
6
|
import { addRTypeToMetadata } from '@milaboratories/pl-client';
|
|
7
|
-
import { ResourceInfo } from '@milaboratories/pl-tree';
|
|
7
|
+
import type { ResourceInfo } from '@milaboratories/pl-tree';
|
|
8
8
|
|
|
9
9
|
export class ClientLs {
|
|
10
10
|
private readonly grpcClient: LSClient;
|
|
11
11
|
|
|
12
12
|
constructor(
|
|
13
13
|
grpcTransport: GrpcTransport,
|
|
14
|
-
private readonly logger: MiLogger
|
|
14
|
+
private readonly logger: MiLogger,
|
|
15
15
|
) {
|
|
16
16
|
this.grpcClient = new LSClient(grpcTransport);
|
|
17
17
|
}
|
|
@@ -21,14 +21,14 @@ export class ClientLs {
|
|
|
21
21
|
public async list(
|
|
22
22
|
rInfo: ResourceInfo,
|
|
23
23
|
path: string,
|
|
24
|
-
options?: RpcOptions
|
|
24
|
+
options?: RpcOptions,
|
|
25
25
|
): Promise<LsAPI_List_Response> {
|
|
26
26
|
return await this.grpcClient.list(
|
|
27
27
|
{
|
|
28
28
|
resourceId: rInfo.id,
|
|
29
|
-
location: path
|
|
29
|
+
location: path,
|
|
30
30
|
},
|
|
31
|
-
addRTypeToMetadata(rInfo.type, options)
|
|
31
|
+
addRTypeToMetadata(rInfo.type, options),
|
|
32
32
|
).response;
|
|
33
33
|
}
|
|
34
34
|
}
|
package/src/clients/progress.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ProgressClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client';
|
|
2
|
-
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
2
|
+
import type { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
3
3
|
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
4
4
|
import { Duration } from '../proto/google/protobuf/duration';
|
|
5
|
-
import { PlClient
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
5
|
+
import type { PlClient } from '@milaboratories/pl-client';
|
|
6
|
+
import { addRTypeToMetadata } from '@milaboratories/pl-client';
|
|
7
|
+
import type { MiLogger } from '@milaboratories/ts-helpers';
|
|
8
|
+
import { notEmpty } from '@milaboratories/ts-helpers';
|
|
9
|
+
import type { Dispatcher } from 'undici';
|
|
10
|
+
import type { ResourceInfo } from '@milaboratories/pl-tree';
|
|
9
11
|
|
|
10
12
|
export type ProgressStatus = {
|
|
11
13
|
done: boolean;
|
|
@@ -25,7 +27,7 @@ export class ClientProgress {
|
|
|
25
27
|
public readonly grpcTransport: GrpcTransport,
|
|
26
28
|
_: Dispatcher,
|
|
27
29
|
public readonly client: PlClient,
|
|
28
|
-
public readonly logger: MiLogger
|
|
30
|
+
public readonly logger: MiLogger,
|
|
29
31
|
) {
|
|
30
32
|
this.grpcClient = new ProgressClient(this.grpcTransport);
|
|
31
33
|
}
|
|
@@ -36,7 +38,7 @@ export class ClientProgress {
|
|
|
36
38
|
async getStatus({ id, type }: ResourceInfo, options?: RpcOptions): Promise<ProgressStatus> {
|
|
37
39
|
const status = await this.grpcClient.getStatus(
|
|
38
40
|
{ resourceId: id },
|
|
39
|
-
addRTypeToMetadata(type, options)
|
|
41
|
+
addRTypeToMetadata(type, options),
|
|
40
42
|
);
|
|
41
43
|
|
|
42
44
|
const report = notEmpty(status.response.report);
|
|
@@ -45,7 +47,7 @@ export class ClientProgress {
|
|
|
45
47
|
done: report.done,
|
|
46
48
|
progress: report.progress,
|
|
47
49
|
bytesProcessed: String(report.bytesProcessed),
|
|
48
|
-
bytesTotal: String(report.bytesTotal)
|
|
50
|
+
bytesTotal: String(report.bytesTotal),
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
53
|
|
|
@@ -54,7 +56,7 @@ export class ClientProgress {
|
|
|
54
56
|
async *realtimeStatus(
|
|
55
57
|
{ id, type }: ResourceInfo,
|
|
56
58
|
updateIntervalMs: number = 100,
|
|
57
|
-
options?: RpcOptions
|
|
59
|
+
options?: RpcOptions,
|
|
58
60
|
) {
|
|
59
61
|
options = addRTypeToMetadata(type, options);
|
|
60
62
|
|
|
@@ -62,19 +64,19 @@ export class ClientProgress {
|
|
|
62
64
|
const nanos = (updateIntervalMs - secs * 1000) * 1000000;
|
|
63
65
|
const updateInterval = Duration.create({
|
|
64
66
|
seconds: BigInt(secs),
|
|
65
|
-
nanos: nanos
|
|
67
|
+
nanos: nanos,
|
|
66
68
|
});
|
|
67
69
|
|
|
68
70
|
try {
|
|
69
71
|
const { responses } = this.grpcClient.realtimeStatus(
|
|
70
72
|
{
|
|
71
73
|
resourceId: id,
|
|
72
|
-
updateInterval: updateInterval
|
|
74
|
+
updateInterval: updateInterval,
|
|
73
75
|
},
|
|
74
|
-
options
|
|
76
|
+
options,
|
|
75
77
|
);
|
|
76
78
|
|
|
77
|
-
yield* responses;
|
|
79
|
+
yield * responses;
|
|
78
80
|
} catch (e) {
|
|
79
81
|
this.logger.warn('Failed to get realtime status' + e);
|
|
80
82
|
throw e;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { PlClient, ResourceId
|
|
1
|
+
import type { PlClient, ResourceId } from '@milaboratories/pl-client';
|
|
2
|
+
import { TestHelpers } from '@milaboratories/pl-client';
|
|
2
3
|
import { ClientUpload } from '../clients/upload';
|
|
3
|
-
import { Dispatcher } from 'undici';
|
|
4
|
-
import { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
4
|
+
import type { Dispatcher } from 'undici';
|
|
5
|
+
import type { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
5
6
|
import { ConsoleLoggerAdapter } from '@milaboratories/ts-helpers';
|
|
6
7
|
|
|
7
8
|
test.skip('integration test, grpc upload blob should throw error on NOT_FOUND', async () => {
|
|
@@ -10,13 +11,13 @@ test.skip('integration test, grpc upload blob should throw error on NOT_FOUND',
|
|
|
10
11
|
const clientBlob = client.getDriver({
|
|
11
12
|
name: 'UploadBlob',
|
|
12
13
|
init: (pl: PlClient, grpcTransport: GrpcTransport, httpDispatcher: Dispatcher) =>
|
|
13
|
-
new ClientUpload(grpcTransport, httpDispatcher, client, logger)
|
|
14
|
+
new ClientUpload(grpcTransport, httpDispatcher, client, logger),
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
try {
|
|
17
18
|
await clientBlob.initUpload({
|
|
18
19
|
id: 1n as ResourceId,
|
|
19
|
-
type: { name: 'BlobUpload/main', version: '1' }
|
|
20
|
+
type: { name: 'BlobUpload/main', version: '1' },
|
|
20
21
|
});
|
|
21
22
|
fail('should throw NOT_FOUND');
|
|
22
23
|
} catch (e) {
|
package/src/clients/upload.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { PlClient, ResourceId, ResourceType
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import type { PlClient, ResourceId, ResourceType } from '@milaboratories/pl-client';
|
|
2
|
+
import { addRTypeToMetadata } from '@milaboratories/pl-client';
|
|
3
|
+
import type { ResourceInfo } from '@milaboratories/pl-tree';
|
|
4
|
+
import type { MiLogger } from '@milaboratories/ts-helpers';
|
|
5
|
+
import type { GrpcTransport } from '@protobuf-ts/grpc-transport';
|
|
5
6
|
import type { RpcOptions } from '@protobuf-ts/runtime-rpc';
|
|
6
7
|
import * as fs from 'node:fs/promises';
|
|
7
|
-
import { Dispatcher
|
|
8
|
-
import {
|
|
8
|
+
import type { Dispatcher } from 'undici';
|
|
9
|
+
import { request } from 'undici';
|
|
10
|
+
import type { uploadapi_GetPartURL_Response } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol';
|
|
9
11
|
import { UploadClient } from '../proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client';
|
|
10
12
|
import { toHeadersMap } from './helpers';
|
|
11
|
-
import { IncomingHttpHeaders } from 'undici/types/header';
|
|
13
|
+
import type { IncomingHttpHeaders } from 'undici/types/header';
|
|
12
14
|
|
|
13
15
|
export class MTimeError extends Error {}
|
|
14
16
|
|
|
@@ -29,7 +31,7 @@ export class ClientUpload {
|
|
|
29
31
|
public readonly grpcTransport: GrpcTransport,
|
|
30
32
|
public readonly httpClient: Dispatcher,
|
|
31
33
|
_: PlClient,
|
|
32
|
-
public readonly logger: MiLogger
|
|
34
|
+
public readonly logger: MiLogger,
|
|
33
35
|
) {
|
|
34
36
|
this.grpcClient = new UploadClient(this.grpcTransport);
|
|
35
37
|
}
|
|
@@ -38,15 +40,15 @@ export class ClientUpload {
|
|
|
38
40
|
|
|
39
41
|
public async initUpload(
|
|
40
42
|
{ id, type }: ResourceInfo,
|
|
41
|
-
options?: RpcOptions
|
|
43
|
+
options?: RpcOptions,
|
|
42
44
|
): Promise<{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
overall: bigint;
|
|
46
|
+
toUpload: bigint[];
|
|
47
|
+
}> {
|
|
46
48
|
const init = await this.grpcInit(id, type, options);
|
|
47
49
|
return {
|
|
48
50
|
overall: init.partsCount,
|
|
49
|
-
toUpload: this.partsToUpload(init.partsCount, init.uploadedParts)
|
|
51
|
+
toUpload: this.partsToUpload(init.partsCount, init.uploadedParts),
|
|
50
52
|
};
|
|
51
53
|
}
|
|
52
54
|
|
|
@@ -55,13 +57,13 @@ export class ClientUpload {
|
|
|
55
57
|
path: string,
|
|
56
58
|
expectedMTimeUnix: bigint,
|
|
57
59
|
partNumber: bigint,
|
|
58
|
-
options?: RpcOptions
|
|
60
|
+
options?: RpcOptions,
|
|
59
61
|
) {
|
|
60
62
|
const info = await this.grpcGetPartUrl(
|
|
61
63
|
{ id, type },
|
|
62
64
|
partNumber,
|
|
63
65
|
0n, // we update progress as a separate call later.
|
|
64
|
-
options
|
|
66
|
+
options,
|
|
65
67
|
);
|
|
66
68
|
|
|
67
69
|
const chunk = await readFileChunk(path, info.chunkStart, info.chunkEnd);
|
|
@@ -70,12 +72,12 @@ export class ClientUpload {
|
|
|
70
72
|
const {
|
|
71
73
|
body: rawBody,
|
|
72
74
|
statusCode,
|
|
73
|
-
headers
|
|
75
|
+
headers,
|
|
74
76
|
} = await request(info.uploadUrl, {
|
|
75
77
|
dispatcher: this.httpClient,
|
|
76
78
|
body: chunk,
|
|
77
79
|
headers: toHeadersMap(info.headers),
|
|
78
|
-
method: info.method.toUpperCase() as Dispatcher.HttpMethod
|
|
80
|
+
method: info.method.toUpperCase() as Dispatcher.HttpMethod,
|
|
79
81
|
});
|
|
80
82
|
|
|
81
83
|
// always read the body for resources to be garbage collected.
|
|
@@ -111,25 +113,25 @@ export class ClientUpload {
|
|
|
111
113
|
{ id, type }: ResourceInfo,
|
|
112
114
|
partNumber: bigint,
|
|
113
115
|
uploadedPartSize: bigint,
|
|
114
|
-
options?: RpcOptions
|
|
116
|
+
options?: RpcOptions,
|
|
115
117
|
) {
|
|
116
118
|
return await this.grpcClient.getPartURL(
|
|
117
119
|
{ resourceId: id, partNumber, uploadedPartSize },
|
|
118
|
-
addRTypeToMetadata(type, options)
|
|
120
|
+
addRTypeToMetadata(type, options),
|
|
119
121
|
).response;
|
|
120
122
|
}
|
|
121
123
|
|
|
122
124
|
private async grpcUpdateProgress(
|
|
123
125
|
{ id, type }: ResourceInfo,
|
|
124
126
|
bytesProcessed: bigint,
|
|
125
|
-
options?: RpcOptions
|
|
127
|
+
options?: RpcOptions,
|
|
126
128
|
) {
|
|
127
129
|
await this.grpcClient.updateProgress(
|
|
128
130
|
{
|
|
129
131
|
resourceId: id,
|
|
130
|
-
bytesProcessed
|
|
132
|
+
bytesProcessed,
|
|
131
133
|
},
|
|
132
|
-
addRTypeToMetadata(type, options)
|
|
134
|
+
addRTypeToMetadata(type, options),
|
|
133
135
|
).response;
|
|
134
136
|
}
|
|
135
137
|
|
|
@@ -166,7 +168,7 @@ async function readBytesFromPosition(f: fs.FileHandle, b: Buffer, len: number, p
|
|
|
166
168
|
b,
|
|
167
169
|
bytesReadTotal,
|
|
168
170
|
len - bytesReadTotal,
|
|
169
|
-
position + bytesReadTotal
|
|
171
|
+
position + bytesReadTotal,
|
|
170
172
|
);
|
|
171
173
|
if (bytesRead === 0) {
|
|
172
174
|
throw new UnexpectedEOF('file ended earlier than expected.');
|
|
@@ -188,12 +190,12 @@ function checkStatusCodeOk(
|
|
|
188
190
|
statusCode: number,
|
|
189
191
|
body: string,
|
|
190
192
|
headers: IncomingHttpHeaders,
|
|
191
|
-
info: uploadapi_GetPartURL_Response
|
|
193
|
+
info: uploadapi_GetPartURL_Response,
|
|
192
194
|
) {
|
|
193
195
|
if (statusCode != 200) {
|
|
194
196
|
throw new NetworkError(
|
|
195
|
-
`response is not ok, status code: ${statusCode},`
|
|
196
|
-
|
|
197
|
+
`response is not ok, status code: ${statusCode},`
|
|
198
|
+
+ ` body: ${body}, headers: ${headers}, url: ${info.uploadUrl}`,
|
|
197
199
|
);
|
|
198
200
|
}
|
|
199
201
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { expect, test } from '@jest/globals';
|
|
2
|
-
import {
|
|
2
|
+
import type {
|
|
3
3
|
FieldId,
|
|
4
4
|
FieldRef,
|
|
5
|
-
jsonToData,
|
|
6
5
|
PlClient,
|
|
7
6
|
PlTransaction,
|
|
7
|
+
PollTxAccessor } from '@milaboratories/pl-client';
|
|
8
|
+
import {
|
|
9
|
+
jsonToData,
|
|
8
10
|
poll,
|
|
9
|
-
|
|
10
|
-
TestHelpers
|
|
11
|
+
TestHelpers,
|
|
11
12
|
} from '@milaboratories/pl-client';
|
|
12
13
|
import { ConsoleLoggerAdapter, HmacSha256Signer } from '@milaboratories/ts-helpers';
|
|
13
14
|
import * as fsp from 'node:fs/promises';
|
|
@@ -16,7 +17,7 @@ import * as path from 'node:path';
|
|
|
16
17
|
import { scheduler } from 'node:timers/promises';
|
|
17
18
|
import { createDownloadClient, createLogsClient } from '../clients/constructors';
|
|
18
19
|
import { DownloadDriver } from './download_blob';
|
|
19
|
-
import { OnDemandBlobResourceSnapshot } from './types';
|
|
20
|
+
import type { OnDemandBlobResourceSnapshot } from './types';
|
|
20
21
|
|
|
21
22
|
const fileName = 'answer_to_the_ultimate_question.txt';
|
|
22
23
|
|
|
@@ -31,7 +32,7 @@ test('should download a blob and read its content', async () => {
|
|
|
31
32
|
createLogsClient(client, logger),
|
|
32
33
|
dir,
|
|
33
34
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
34
|
-
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 }
|
|
35
|
+
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 },
|
|
35
36
|
);
|
|
36
37
|
const downloadable = await makeDownloadableBlobFromAssets(client, fileName);
|
|
37
38
|
|
|
@@ -62,7 +63,7 @@ test('should not redownload a blob a file already exists', async () => {
|
|
|
62
63
|
createLogsClient(client, logger),
|
|
63
64
|
dir,
|
|
64
65
|
signer,
|
|
65
|
-
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 }
|
|
66
|
+
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 },
|
|
66
67
|
);
|
|
67
68
|
|
|
68
69
|
console.log('Download the first time');
|
|
@@ -83,7 +84,7 @@ test('should not redownload a blob a file already exists', async () => {
|
|
|
83
84
|
createLogsClient(client, logger),
|
|
84
85
|
dir,
|
|
85
86
|
signer,
|
|
86
|
-
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 }
|
|
87
|
+
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 },
|
|
87
88
|
);
|
|
88
89
|
|
|
89
90
|
console.log('Download the second time');
|
|
@@ -107,7 +108,7 @@ test('should get on demand blob without downloading a blob', async () => {
|
|
|
107
108
|
createLogsClient(client, logger),
|
|
108
109
|
dir,
|
|
109
110
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
110
|
-
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 }
|
|
111
|
+
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 },
|
|
111
112
|
);
|
|
112
113
|
|
|
113
114
|
const downloadable = await makeDownloadableBlobFromAssets(client, fileName);
|
|
@@ -132,7 +133,7 @@ test('should get undefined when releasing a blob from a small cache and the blob
|
|
|
132
133
|
createLogsClient(client, logger),
|
|
133
134
|
dir,
|
|
134
135
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
135
|
-
{ cacheSoftSizeBytes: 1, nConcurrentDownloads: 10 }
|
|
136
|
+
{ cacheSoftSizeBytes: 1, nConcurrentDownloads: 10 },
|
|
136
137
|
);
|
|
137
138
|
const downloadable = await makeDownloadableBlobFromAssets(client, fileName);
|
|
138
139
|
|
|
@@ -169,7 +170,7 @@ test('should get the blob when releasing a blob, but a cache is big enough and i
|
|
|
169
170
|
createLogsClient(client, logger),
|
|
170
171
|
dir,
|
|
171
172
|
new HmacSha256Signer(HmacSha256Signer.generateSecret()),
|
|
172
|
-
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 }
|
|
173
|
+
{ cacheSoftSizeBytes: 700 * 1024, nConcurrentDownloads: 10 },
|
|
173
174
|
);
|
|
174
175
|
const downloadable = await makeDownloadableBlobFromAssets(client, fileName);
|
|
175
176
|
|
|
@@ -202,30 +203,30 @@ async function makeDownloadableBlobFromAssets(client: PlClient, fileName: string
|
|
|
202
203
|
await client.withWriteTx('MakeAssetDownloadable', async (tx: PlTransaction) => {
|
|
203
204
|
const importSettings = jsonToData({
|
|
204
205
|
path: fileName,
|
|
205
|
-
storageId: 'library'
|
|
206
|
+
storageId: 'library',
|
|
206
207
|
});
|
|
207
208
|
const importer = tx.createStruct({ name: 'BlobImportInternal', version: '1' }, importSettings);
|
|
208
209
|
const importerBlob: FieldRef = {
|
|
209
210
|
resourceId: importer,
|
|
210
|
-
fieldName: 'blob'
|
|
211
|
+
fieldName: 'blob',
|
|
211
212
|
};
|
|
212
213
|
|
|
213
214
|
const download = tx.createStruct({
|
|
214
215
|
name: 'BlobDownload',
|
|
215
|
-
version: '2'
|
|
216
|
+
version: '2',
|
|
216
217
|
});
|
|
217
218
|
const downloadBlob: FieldRef = {
|
|
218
219
|
resourceId: download,
|
|
219
|
-
fieldName: 'blob'
|
|
220
|
+
fieldName: 'blob',
|
|
220
221
|
};
|
|
221
222
|
const downloadDownloadable: FieldRef = {
|
|
222
223
|
resourceId: download,
|
|
223
|
-
fieldName: 'downloadable'
|
|
224
|
+
fieldName: 'downloadable',
|
|
224
225
|
};
|
|
225
226
|
|
|
226
227
|
const dynamicId: FieldId = {
|
|
227
228
|
resourceId: client.clientRoot,
|
|
228
|
-
fieldName: 'result'
|
|
229
|
+
fieldName: 'result',
|
|
229
230
|
};
|
|
230
231
|
|
|
231
232
|
tx.setField(downloadBlob, importerBlob);
|
|
@@ -247,8 +248,8 @@ async function makeDownloadableBlobFromAssets(client: PlClient, fileName: string
|
|
|
247
248
|
fields: undefined,
|
|
248
249
|
kv: {
|
|
249
250
|
'ctl/file/blobInfo': {
|
|
250
|
-
sizeBytes: Number(kv.sizeBytes)
|
|
251
|
-
}
|
|
252
|
-
}
|
|
251
|
+
sizeBytes: Number(kv.sizeBytes),
|
|
252
|
+
},
|
|
253
|
+
},
|
|
253
254
|
} as OnDemandBlobResourceSnapshot;
|
|
254
255
|
}
|