@milaboratories/pl-drivers 1.9.0 → 1.10.0
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.cjs +45 -0
- package/dist/clients/constructors.cjs.map +1 -0
- package/dist/clients/constructors.d.ts +0 -1
- package/dist/clients/constructors.js +39 -0
- package/dist/clients/constructors.js.map +1 -0
- package/dist/clients/download.cjs +149 -0
- package/dist/clients/download.cjs.map +1 -0
- package/dist/clients/download.d.ts +0 -1
- package/dist/clients/download.js +121 -0
- package/dist/clients/download.js.map +1 -0
- package/dist/clients/logs.cjs +44 -0
- package/dist/clients/logs.cjs.map +1 -0
- package/dist/clients/logs.d.ts +0 -1
- package/dist/clients/logs.js +42 -0
- package/dist/clients/logs.js.map +1 -0
- package/dist/clients/ls_api.cjs +23 -0
- package/dist/clients/ls_api.cjs.map +1 -0
- package/dist/clients/ls_api.d.ts +0 -1
- package/dist/clients/ls_api.js +21 -0
- package/dist/clients/ls_api.js.map +1 -0
- package/dist/clients/progress.cjs +58 -0
- package/dist/clients/progress.cjs.map +1 -0
- package/dist/clients/progress.d.ts +1 -3
- package/dist/clients/progress.js +56 -0
- package/dist/clients/progress.js.map +1 -0
- package/dist/clients/upload.cjs +209 -0
- package/dist/clients/upload.cjs.map +1 -0
- package/dist/clients/upload.d.ts +8 -4
- package/dist/clients/upload.js +183 -0
- package/dist/clients/upload.js.map +1 -0
- package/dist/drivers/download_blob/blob_key.cjs +34 -0
- package/dist/drivers/download_blob/blob_key.cjs.map +1 -0
- package/dist/drivers/download_blob/blob_key.d.ts +0 -1
- package/dist/drivers/download_blob/blob_key.js +12 -0
- package/dist/drivers/download_blob/blob_key.js.map +1 -0
- package/dist/drivers/download_blob/download_blob.cjs +442 -0
- package/dist/drivers/download_blob/download_blob.cjs.map +1 -0
- package/dist/drivers/download_blob/download_blob.d.ts +0 -1
- package/dist/drivers/download_blob/download_blob.js +417 -0
- package/dist/drivers/download_blob/download_blob.js.map +1 -0
- package/dist/drivers/download_blob/download_blob_task.cjs +170 -0
- package/dist/drivers/download_blob/download_blob_task.cjs.map +1 -0
- package/dist/drivers/download_blob/download_blob_task.d.ts +0 -1
- package/dist/drivers/download_blob/download_blob_task.js +146 -0
- package/dist/drivers/download_blob/download_blob_task.js.map +1 -0
- package/dist/drivers/download_blob/sparse_cache/cache.cjs +202 -0
- package/dist/drivers/download_blob/sparse_cache/cache.cjs.map +1 -0
- package/dist/drivers/download_blob/sparse_cache/cache.d.ts +0 -1
- package/dist/drivers/download_blob/sparse_cache/cache.js +197 -0
- package/dist/drivers/download_blob/sparse_cache/cache.js.map +1 -0
- package/dist/drivers/download_blob/sparse_cache/file.cjs +61 -0
- package/dist/drivers/download_blob/sparse_cache/file.cjs.map +1 -0
- package/dist/drivers/download_blob/sparse_cache/file.d.ts +0 -1
- package/dist/drivers/download_blob/sparse_cache/file.js +39 -0
- package/dist/drivers/download_blob/sparse_cache/file.js.map +1 -0
- package/dist/drivers/download_blob/sparse_cache/ranges.cjs +104 -0
- package/dist/drivers/download_blob/sparse_cache/ranges.cjs.map +1 -0
- package/dist/drivers/download_blob/sparse_cache/ranges.d.ts +0 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.js +76 -0
- package/dist/drivers/download_blob/sparse_cache/ranges.js.map +1 -0
- package/dist/drivers/download_blob_url/driver.cjs +169 -0
- package/dist/drivers/download_blob_url/driver.cjs.map +1 -0
- package/dist/drivers/download_blob_url/driver.d.ts +0 -1
- package/dist/drivers/download_blob_url/driver.js +148 -0
- package/dist/drivers/download_blob_url/driver.js.map +1 -0
- package/dist/drivers/download_blob_url/driver_id.cjs +9 -0
- package/dist/drivers/download_blob_url/driver_id.cjs.map +1 -0
- package/dist/drivers/download_blob_url/driver_id.d.ts +0 -1
- package/dist/drivers/download_blob_url/driver_id.js +7 -0
- package/dist/drivers/download_blob_url/driver_id.js.map +1 -0
- package/dist/drivers/download_blob_url/snapshot.cjs +18 -0
- package/dist/drivers/download_blob_url/snapshot.cjs.map +1 -0
- package/dist/drivers/download_blob_url/snapshot.d.ts +2 -3
- package/dist/drivers/download_blob_url/snapshot.js +15 -0
- package/dist/drivers/download_blob_url/snapshot.js.map +1 -0
- package/dist/drivers/download_blob_url/task.cjs +209 -0
- package/dist/drivers/download_blob_url/task.cjs.map +1 -0
- package/dist/drivers/download_blob_url/task.d.ts +0 -1
- package/dist/drivers/download_blob_url/task.js +184 -0
- package/dist/drivers/download_blob_url/task.js.map +1 -0
- package/dist/drivers/download_blob_url/url.d.ts +1 -1
- package/dist/drivers/download_url/driver.cjs +149 -0
- package/dist/drivers/download_url/driver.cjs.map +1 -0
- package/dist/drivers/download_url/driver.d.ts +0 -1
- package/dist/drivers/download_url/driver.js +128 -0
- package/dist/drivers/download_url/driver.js.map +1 -0
- package/dist/drivers/download_url/task.cjs +150 -0
- package/dist/drivers/download_url/task.cjs.map +1 -0
- package/dist/drivers/download_url/task.d.ts +0 -1
- package/dist/drivers/download_url/task.js +124 -0
- package/dist/drivers/download_url/task.js.map +1 -0
- package/dist/drivers/helpers/download_local_handle.cjs +26 -0
- package/dist/drivers/helpers/download_local_handle.cjs.map +1 -0
- package/dist/drivers/helpers/download_local_handle.d.ts +0 -1
- package/dist/drivers/helpers/download_local_handle.js +22 -0
- package/dist/drivers/helpers/download_local_handle.js.map +1 -0
- package/dist/drivers/helpers/download_remote_handle.cjs +36 -0
- package/dist/drivers/helpers/download_remote_handle.cjs.map +1 -0
- package/dist/drivers/helpers/download_remote_handle.d.ts +0 -1
- package/dist/drivers/helpers/download_remote_handle.js +32 -0
- package/dist/drivers/helpers/download_remote_handle.js.map +1 -0
- package/dist/drivers/helpers/files_cache.cjs +68 -0
- package/dist/drivers/helpers/files_cache.cjs.map +1 -0
- package/dist/drivers/helpers/files_cache.d.ts +0 -1
- package/dist/drivers/helpers/files_cache.js +66 -0
- package/dist/drivers/helpers/files_cache.js.map +1 -0
- package/dist/drivers/helpers/helpers.cjs +34 -0
- package/dist/drivers/helpers/helpers.cjs.map +1 -0
- package/dist/drivers/helpers/helpers.d.ts +0 -1
- package/dist/drivers/helpers/helpers.js +31 -0
- package/dist/drivers/helpers/helpers.js.map +1 -0
- package/dist/drivers/helpers/logs_handle.cjs +50 -0
- package/dist/drivers/helpers/logs_handle.cjs.map +1 -0
- package/dist/drivers/helpers/logs_handle.d.ts +0 -1
- package/dist/drivers/helpers/logs_handle.js +43 -0
- package/dist/drivers/helpers/logs_handle.js.map +1 -0
- package/dist/drivers/helpers/ls_remote_import_handle.cjs +34 -0
- package/dist/drivers/helpers/ls_remote_import_handle.cjs.map +1 -0
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts +0 -1
- package/dist/drivers/helpers/ls_remote_import_handle.js +29 -0
- package/dist/drivers/helpers/ls_remote_import_handle.js.map +1 -0
- package/dist/drivers/helpers/ls_storage_entry.cjs +64 -0
- package/dist/drivers/helpers/ls_storage_entry.cjs.map +1 -0
- package/dist/drivers/helpers/ls_storage_entry.d.ts +0 -1
- package/dist/drivers/helpers/ls_storage_entry.js +58 -0
- package/dist/drivers/helpers/ls_storage_entry.js.map +1 -0
- package/dist/drivers/helpers/polling_ops.d.ts +0 -1
- package/dist/drivers/helpers/read_file.cjs +54 -0
- package/dist/drivers/helpers/read_file.cjs.map +1 -0
- package/dist/drivers/helpers/read_file.d.ts +0 -1
- package/dist/drivers/helpers/read_file.js +33 -0
- package/dist/drivers/helpers/read_file.js.map +1 -0
- package/dist/drivers/helpers/test_helpers.d.ts +0 -1
- package/dist/drivers/logs.cjs +118 -0
- package/dist/drivers/logs.cjs.map +1 -0
- package/dist/drivers/logs.d.ts +0 -1
- package/dist/drivers/logs.js +116 -0
- package/dist/drivers/logs.js.map +1 -0
- package/dist/drivers/logs_stream.cjs +238 -0
- package/dist/drivers/logs_stream.cjs.map +1 -0
- package/dist/drivers/logs_stream.d.ts +0 -1
- package/dist/drivers/logs_stream.js +236 -0
- package/dist/drivers/logs_stream.js.map +1 -0
- package/dist/drivers/ls.cjs +236 -0
- package/dist/drivers/ls.cjs.map +1 -0
- package/dist/drivers/ls.d.ts +0 -1
- package/dist/drivers/ls.js +214 -0
- package/dist/drivers/ls.js.map +1 -0
- package/dist/drivers/types.cjs +72 -0
- package/dist/drivers/types.cjs.map +1 -0
- package/dist/drivers/types.d.ts +4 -5
- package/dist/drivers/types.js +64 -0
- package/dist/drivers/types.js.map +1 -0
- package/dist/drivers/upload.cjs +154 -0
- package/dist/drivers/upload.cjs.map +1 -0
- package/dist/drivers/upload.d.ts +0 -1
- package/dist/drivers/upload.js +151 -0
- package/dist/drivers/upload.js.map +1 -0
- package/dist/drivers/upload_task.cjs +297 -0
- package/dist/drivers/upload_task.cjs.map +1 -0
- package/dist/drivers/upload_task.d.ts +2 -3
- package/dist/drivers/upload_task.js +289 -0
- package/dist/drivers/upload_task.js.map +1 -0
- package/dist/drivers/urls/url.cjs +59 -0
- package/dist/drivers/urls/url.cjs.map +1 -0
- package/dist/drivers/urls/url.d.ts +0 -1
- package/dist/drivers/urls/url.js +54 -0
- package/dist/drivers/urls/url.js.map +1 -0
- package/dist/drivers/virtual_storages.cjs +53 -0
- package/dist/drivers/virtual_storages.cjs.map +1 -0
- package/dist/drivers/virtual_storages.d.ts +0 -1
- package/dist/drivers/virtual_storages.js +51 -0
- package/dist/drivers/virtual_storages.js.map +1 -0
- package/dist/helpers/download.cjs +63 -0
- package/dist/helpers/download.cjs.map +1 -0
- package/dist/helpers/download.d.ts +0 -1
- package/dist/helpers/download.js +60 -0
- package/dist/helpers/download.js.map +1 -0
- package/dist/helpers/validate.cjs +12 -0
- package/dist/helpers/validate.cjs.map +1 -0
- package/dist/helpers/validate.d.ts +0 -1
- package/dist/helpers/validate.js +10 -0
- package/dist/helpers/validate.js.map +1 -0
- package/dist/index.cjs +73 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +19 -2
- package/dist/index.js.map +1 -1
- package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs +261 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs +31 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +3 -5
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js +29 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js +256 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs +301 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs +34 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts +3 -5
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js +32 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js +296 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs +410 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs +38 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +3 -5
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js +36 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js +403 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs +486 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs +86 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +3 -5
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js +84 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js +478 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs +758 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs +71 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts +3 -5
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js +69 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts +36 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js +747 -0
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js.map +1 -0
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts +3 -5
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts +0 -1
- package/dist/proto/google/api/http.d.ts +0 -1
- package/dist/proto/google/protobuf/any.d.ts +0 -1
- package/dist/proto/google/protobuf/descriptor.d.ts +0 -1
- package/dist/proto/google/protobuf/duration.cjs +105 -0
- package/dist/proto/google/protobuf/duration.cjs.map +1 -0
- package/dist/proto/google/protobuf/duration.d.ts +0 -1
- package/dist/proto/google/protobuf/duration.js +103 -0
- package/dist/proto/google/protobuf/duration.js.map +1 -0
- package/dist/proto/google/protobuf/empty.d.ts +0 -1
- package/dist/proto/google/protobuf/struct.d.ts +0 -1
- package/dist/proto/google/protobuf/timestamp.cjs +133 -0
- package/dist/proto/google/protobuf/timestamp.cjs.map +1 -0
- package/dist/proto/google/protobuf/timestamp.d.ts +0 -1
- package/dist/proto/google/protobuf/timestamp.js +131 -0
- package/dist/proto/google/protobuf/timestamp.js.map +1 -0
- package/dist/proto/google/protobuf/wrappers.d.ts +0 -1
- package/dist/test_env.d.ts +0 -1
- package/package.json +17 -15
- package/src/clients/upload.ts +38 -14
- package/src/drivers/upload_task.ts +10 -3
- package/src/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.ts +69 -1
- package/dist/clients/constructors.d.ts.map +0 -1
- package/dist/clients/download.d.ts.map +0 -1
- package/dist/clients/logs.d.ts.map +0 -1
- package/dist/clients/ls_api.d.ts.map +0 -1
- package/dist/clients/progress.d.ts.map +0 -1
- package/dist/clients/upload.d.ts.map +0 -1
- package/dist/drivers/download_blob/blob_key.d.ts.map +0 -1
- package/dist/drivers/download_blob/download_blob.d.ts.map +0 -1
- package/dist/drivers/download_blob/download_blob_task.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/cache.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/file.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/driver.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/driver_id.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/snapshot.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/task.d.ts.map +0 -1
- package/dist/drivers/download_blob_url/url.d.ts.map +0 -1
- package/dist/drivers/download_url/driver.d.ts.map +0 -1
- package/dist/drivers/download_url/task.d.ts.map +0 -1
- package/dist/drivers/helpers/download_local_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/download_remote_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/files_cache.d.ts.map +0 -1
- package/dist/drivers/helpers/helpers.d.ts.map +0 -1
- package/dist/drivers/helpers/logs_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/ls_storage_entry.d.ts.map +0 -1
- package/dist/drivers/helpers/polling_ops.d.ts.map +0 -1
- package/dist/drivers/helpers/read_file.d.ts.map +0 -1
- package/dist/drivers/helpers/test_helpers.d.ts.map +0 -1
- package/dist/drivers/logs.d.ts.map +0 -1
- package/dist/drivers/logs_stream.d.ts.map +0 -1
- package/dist/drivers/ls.d.ts.map +0 -1
- package/dist/drivers/types.d.ts.map +0 -1
- package/dist/drivers/upload.d.ts.map +0 -1
- package/dist/drivers/upload_task.d.ts.map +0 -1
- package/dist/drivers/urls/url.d.ts.map +0 -1
- package/dist/drivers/virtual_storages.d.ts.map +0 -1
- package/dist/helpers/download.d.ts.map +0 -1
- package/dist/helpers/validate.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.mjs +0 -4892
- package/dist/index.mjs.map +0 -1
- package/dist/proto/github.com/googleapis/googleapis/google/rpc/status.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.client.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/api_types.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/base_types.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/import.d.ts.map +0 -1
- package/dist/proto/github.com/milaboratory/pl/plapi/plapiproto/resource_types.d.ts.map +0 -1
- package/dist/proto/google/api/http.d.ts.map +0 -1
- package/dist/proto/google/protobuf/any.d.ts.map +0 -1
- package/dist/proto/google/protobuf/descriptor.d.ts.map +0 -1
- package/dist/proto/google/protobuf/duration.d.ts.map +0 -1
- package/dist/proto/google/protobuf/empty.d.ts.map +0 -1
- package/dist/proto/google/protobuf/struct.d.ts.map +0 -1
- package/dist/proto/google/protobuf/timestamp.d.ts.map +0 -1
- package/dist/proto/google/protobuf/wrappers.d.ts.map +0 -1
- package/dist/test_env.d.ts.map +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Computable } from '@milaboratories/computable';
|
|
2
|
+
import { TaskProcessor } from '@milaboratories/ts-helpers';
|
|
3
|
+
import { randomUUID } from 'node:crypto';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { FilesCache } from '../helpers/files_cache.js';
|
|
6
|
+
import { stringifyWithResourceId, resourceIdToString } from '@milaboratories/pl-client';
|
|
7
|
+
import { isFolderURL } from '@milaboratories/pl-model-common';
|
|
8
|
+
import { makeDownloadableBlobSnapshot } from './snapshot.js';
|
|
9
|
+
import { isPlTreeEntry } from '@milaboratories/pl-tree';
|
|
10
|
+
import { rmRFDir, DownloadAndUnarchiveTask } from './task.js';
|
|
11
|
+
import { getPathForFolderURL } from '../urls/url.js';
|
|
12
|
+
import { newId } from './driver_id.js';
|
|
13
|
+
import { nonRecoverableError } from '../download_blob/download_blob_task.js';
|
|
14
|
+
|
|
15
|
+
/** Downloads .tar, .tar.gz or zip archives,
|
|
16
|
+
* extracts them into saveDir and gets a url for it. */
|
|
17
|
+
class DownloadBlobToURLDriver {
|
|
18
|
+
logger;
|
|
19
|
+
signer;
|
|
20
|
+
clientDownload;
|
|
21
|
+
saveDir;
|
|
22
|
+
opts;
|
|
23
|
+
idToDownload = new Map();
|
|
24
|
+
downloadQueue;
|
|
25
|
+
/** Writes and removes files to a hard drive and holds a counter for every
|
|
26
|
+
* file that should be kept. */
|
|
27
|
+
cache;
|
|
28
|
+
constructor(logger, signer, clientDownload, saveDir, opts = {
|
|
29
|
+
cacheSoftSizeBytes: 50 * 1024 * 1024,
|
|
30
|
+
nConcurrentDownloads: 50,
|
|
31
|
+
}) {
|
|
32
|
+
this.logger = logger;
|
|
33
|
+
this.signer = signer;
|
|
34
|
+
this.clientDownload = clientDownload;
|
|
35
|
+
this.saveDir = saveDir;
|
|
36
|
+
this.opts = opts;
|
|
37
|
+
this.downloadQueue = new TaskProcessor(this.logger, this.opts.nConcurrentDownloads, {
|
|
38
|
+
type: 'exponentialWithMaxDelayBackoff',
|
|
39
|
+
initialDelay: 10000,
|
|
40
|
+
maxDelay: 30000,
|
|
41
|
+
backoffMultiplier: 1.5,
|
|
42
|
+
jitter: 0.5,
|
|
43
|
+
});
|
|
44
|
+
this.cache = new FilesCache(this.opts.cacheSoftSizeBytes);
|
|
45
|
+
}
|
|
46
|
+
info() {
|
|
47
|
+
return {
|
|
48
|
+
saveDir: this.saveDir,
|
|
49
|
+
opts: this.opts,
|
|
50
|
+
idToDownloadSize: this.idToDownload.size,
|
|
51
|
+
idToDownloadKeys: this.idToDownload.keys(),
|
|
52
|
+
idToDownload: Array.from(this.idToDownload.entries()).map(([id, task]) => [id, task.info()]),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @returns full path to the referenced file
|
|
57
|
+
*/
|
|
58
|
+
getPathForCustomProtocol(url) {
|
|
59
|
+
if (isFolderURL(url)) {
|
|
60
|
+
return getPathForFolderURL(this.signer, url, this.saveDir);
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`getPathForCustomProtocol: ${url} is invalid`);
|
|
63
|
+
}
|
|
64
|
+
extractArchiveAndGetURL(res, format, ctx) {
|
|
65
|
+
// wrap result as computable, if we were not given an existing computable context
|
|
66
|
+
if (ctx === undefined)
|
|
67
|
+
return Computable.make((c) => this.extractArchiveAndGetURL(res, format, c));
|
|
68
|
+
const rInfo = isPlTreeEntry(res)
|
|
69
|
+
? makeDownloadableBlobSnapshot(res, ctx)
|
|
70
|
+
: res;
|
|
71
|
+
const callerId = randomUUID();
|
|
72
|
+
ctx.addOnDestroy(() => this.releasePath(rInfo.id, format, callerId));
|
|
73
|
+
const result = this.extractArchiveAndGetURLNoCtx(rInfo, format, ctx.watcher, callerId);
|
|
74
|
+
if (result?.url === undefined)
|
|
75
|
+
ctx.markUnstable(`a path to the downloaded archive might be undefined. The current result: ${result}`);
|
|
76
|
+
if (result?.error !== undefined)
|
|
77
|
+
throw result?.error;
|
|
78
|
+
return result?.url;
|
|
79
|
+
}
|
|
80
|
+
extractArchiveAndGetURLNoCtx(rInfo, format, w, callerId) {
|
|
81
|
+
const task = this.idToDownload.get(newId(rInfo.id, format));
|
|
82
|
+
if (task != undefined) {
|
|
83
|
+
task.attach(w, callerId);
|
|
84
|
+
return task.getURL();
|
|
85
|
+
}
|
|
86
|
+
const newTask = this.setNewTask(w, rInfo, format, callerId);
|
|
87
|
+
this.downloadQueue.push({
|
|
88
|
+
fn: async () => this.downloadUrl(newTask, callerId),
|
|
89
|
+
recoverableErrorPredicate: (e) => !nonRecoverableError(e),
|
|
90
|
+
});
|
|
91
|
+
return newTask.getURL();
|
|
92
|
+
}
|
|
93
|
+
/** Downloads and extracts a tar archive if it wasn't downloaded yet. */
|
|
94
|
+
async downloadUrl(task, callerId) {
|
|
95
|
+
await task.download();
|
|
96
|
+
// Might be undefined if a error happened
|
|
97
|
+
if (task.getURL()?.url != undefined)
|
|
98
|
+
this.cache.addCache(task, callerId);
|
|
99
|
+
}
|
|
100
|
+
/** Removes a directory and aborts a downloading task when all callers
|
|
101
|
+
* are not interested in it. */
|
|
102
|
+
async releasePath(id, format, callerId) {
|
|
103
|
+
const task = this.idToDownload.get(newId(id, format));
|
|
104
|
+
if (task == undefined)
|
|
105
|
+
return;
|
|
106
|
+
if (this.cache.existsFile(task.path)) {
|
|
107
|
+
const toDelete = this.cache.removeFile(task.path, callerId);
|
|
108
|
+
await Promise.all(toDelete.map(async (task) => {
|
|
109
|
+
await rmRFDir(task.path);
|
|
110
|
+
this.cache.removeCache(task);
|
|
111
|
+
this.removeTask(task, `the task ${stringifyWithResourceId(task.info())} was removed`
|
|
112
|
+
+ `from cache along with ${stringifyWithResourceId(toDelete.map((t) => t.info()))}`);
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// The task is still in a downloading queue.
|
|
117
|
+
const deleted = task.counter.dec(callerId);
|
|
118
|
+
if (deleted)
|
|
119
|
+
this.removeTask(task, `the task ${stringifyWithResourceId(task.info())} was removed from cache`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Removes all files from a hard drive. */
|
|
123
|
+
async releaseAll() {
|
|
124
|
+
this.downloadQueue.stop();
|
|
125
|
+
await Promise.all(Array.from(this.idToDownload.entries()).map(async ([_, task]) => {
|
|
126
|
+
await rmRFDir(task.path);
|
|
127
|
+
this.cache.removeCache(task);
|
|
128
|
+
this.removeTask(task, `the task ${stringifyWithResourceId(task.info())} was released when the driver was closed`);
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
setNewTask(w, rInfo, format, callerId) {
|
|
132
|
+
const result = new DownloadAndUnarchiveTask(this.logger, this.signer, this.saveDir, this.getFilePath(rInfo.id, format), rInfo, format, this.clientDownload);
|
|
133
|
+
result.attach(w, callerId);
|
|
134
|
+
this.idToDownload.set(newId(rInfo.id, format), result);
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
removeTask(task, reason) {
|
|
138
|
+
task.abort(reason);
|
|
139
|
+
task.change.markChanged(`task for ${resourceIdToString(task.rInfo.id)} removed: ${reason}`);
|
|
140
|
+
this.idToDownload.delete(newId(task.rInfo.id, task.format));
|
|
141
|
+
}
|
|
142
|
+
getFilePath(id, format) {
|
|
143
|
+
return path.join(this.saveDir, `${String(BigInt(id))}_${format}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { DownloadBlobToURLDriver };
|
|
148
|
+
//# sourceMappingURL=driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sources":["../../../src/drivers/download_blob_url/driver.ts"],"sourcesContent":["import type { ComputableCtx, Watcher } from '@milaboratories/computable';\nimport { Computable } from '@milaboratories/computable';\nimport type {\n MiLogger,\n Signer } from '@milaboratories/ts-helpers';\nimport {\n TaskProcessor,\n} from '@milaboratories/ts-helpers';\nimport { randomUUID } from 'node:crypto';\nimport * as path from 'node:path';\nimport { FilesCache } from '../helpers/files_cache';\nimport type { ResourceId } from '@milaboratories/pl-client';\nimport { resourceIdToString, stringifyWithResourceId } from '@milaboratories/pl-client';\nimport { type ArchiveFormat, type BlobToURLDriver, type FolderURL, isFolderURL } from '@milaboratories/pl-model-common';\nimport type { DownloadableBlobSnapshot } from './snapshot';\nimport { makeDownloadableBlobSnapshot } from './snapshot';\nimport type { PlTreeEntry } from '@milaboratories/pl-tree';\nimport { isPlTreeEntry } from '@milaboratories/pl-tree';\nimport { DownloadAndUnarchiveTask, rmRFDir } from './task';\nimport type { ClientDownload } from '../../clients/download';\nimport { getPathForFolderURL } from '../urls/url';\nimport type { Id } from './driver_id';\nimport { newId } from './driver_id';\nimport { nonRecoverableError } from '../download_blob/download_blob_task';\n\nexport type DownloadBlobToURLDriverOps = {\n cacheSoftSizeBytes: number;\n nConcurrentDownloads: number;\n};\n\n/** Downloads .tar, .tar.gz or zip archives,\n * extracts them into saveDir and gets a url for it. */\nexport class DownloadBlobToURLDriver implements BlobToURLDriver {\n private idToDownload: Map<Id, DownloadAndUnarchiveTask> = new Map();\n private downloadQueue: TaskProcessor;\n\n /** Writes and removes files to a hard drive and holds a counter for every\n * file that should be kept. */\n private cache: FilesCache<DownloadAndUnarchiveTask>;\n\n constructor(\n private readonly logger: MiLogger,\n private readonly signer: Signer,\n private readonly clientDownload: ClientDownload,\n private readonly saveDir: string,\n private readonly opts: DownloadBlobToURLDriverOps = {\n cacheSoftSizeBytes: 50 * 1024 * 1024,\n nConcurrentDownloads: 50,\n },\n ) {\n this.downloadQueue = new TaskProcessor(this.logger, this.opts.nConcurrentDownloads, {\n type: 'exponentialWithMaxDelayBackoff',\n initialDelay: 10000,\n maxDelay: 30000,\n backoffMultiplier: 1.5,\n jitter: 0.5,\n });\n this.cache = new FilesCache(this.opts.cacheSoftSizeBytes);\n }\n\n public info(): any {\n return {\n saveDir: this.saveDir,\n opts: this.opts,\n idToDownloadSize: this.idToDownload.size,\n idToDownloadKeys: this.idToDownload.keys(),\n idToDownload: Array.from(this.idToDownload.entries()).map(([id, task]) => [id, task.info()]),\n };\n }\n\n /**\n * @returns full path to the referenced file\n */\n getPathForCustomProtocol(url: FolderURL): string {\n if (isFolderURL(url)) {\n return getPathForFolderURL(this.signer, url, this.saveDir);\n }\n\n throw new Error(`getPathForCustomProtocol: ${url} is invalid`);\n }\n\n extractArchiveAndGetURL(\n res: DownloadableBlobSnapshot | PlTreeEntry,\n format: ArchiveFormat,\n ctx: ComputableCtx,\n ): FolderURL | undefined;\n\n extractArchiveAndGetURL(\n res: DownloadableBlobSnapshot | PlTreeEntry,\n format: ArchiveFormat,\n ): Computable<FolderURL | undefined>;\n\n extractArchiveAndGetURL(\n res: DownloadableBlobSnapshot | PlTreeEntry,\n format: ArchiveFormat,\n ctx?: ComputableCtx,\n ): Computable<FolderURL | undefined> | FolderURL | undefined {\n // wrap result as computable, if we were not given an existing computable context\n if (ctx === undefined)\n return Computable.make((c) => this.extractArchiveAndGetURL(res, format, c));\n\n const rInfo: DownloadableBlobSnapshot = isPlTreeEntry(res)\n ? makeDownloadableBlobSnapshot(res, ctx)\n : res;\n\n const callerId = randomUUID();\n\n ctx.addOnDestroy(() => this.releasePath(rInfo.id, format, callerId));\n\n const result = this.extractArchiveAndGetURLNoCtx(rInfo, format, ctx.watcher, callerId);\n if (result?.url === undefined)\n ctx.markUnstable(\n `a path to the downloaded archive might be undefined. The current result: ${result}`,\n );\n\n if (result?.error !== undefined)\n throw result?.error;\n\n return result?.url;\n }\n\n private extractArchiveAndGetURLNoCtx(\n rInfo: DownloadableBlobSnapshot,\n format: ArchiveFormat,\n w: Watcher,\n callerId: string,\n ) {\n const task = this.idToDownload.get(newId(rInfo.id, format));\n\n if (task != undefined) {\n task.attach(w, callerId);\n return task.getURL();\n }\n\n const newTask = this.setNewTask(w, rInfo, format, callerId);\n this.downloadQueue.push({\n fn: async () => this.downloadUrl(newTask, callerId),\n recoverableErrorPredicate: (e) => !nonRecoverableError(e),\n });\n\n return newTask.getURL();\n }\n\n /** Downloads and extracts a tar archive if it wasn't downloaded yet. */\n async downloadUrl(task: DownloadAndUnarchiveTask, callerId: string) {\n await task.download();\n // Might be undefined if a error happened\n if (task.getURL()?.url != undefined) this.cache.addCache(task, callerId);\n }\n\n /** Removes a directory and aborts a downloading task when all callers\n * are not interested in it. */\n async releasePath(id: ResourceId, format: ArchiveFormat, callerId: string): Promise<void> {\n const task = this.idToDownload.get(newId(id, format));\n if (task == undefined) return;\n\n if (this.cache.existsFile(task.path)) {\n const toDelete = this.cache.removeFile(task.path, callerId);\n\n await Promise.all(\n toDelete.map(async (task: DownloadAndUnarchiveTask) => {\n await rmRFDir(task.path);\n this.cache.removeCache(task);\n\n this.removeTask(\n task,\n `the task ${stringifyWithResourceId(task.info())} was removed`\n + `from cache along with ${stringifyWithResourceId(toDelete.map((t) => t.info()))}`,\n );\n }),\n );\n } else {\n // The task is still in a downloading queue.\n const deleted = task.counter.dec(callerId);\n if (deleted)\n this.removeTask(\n task,\n `the task ${stringifyWithResourceId(task.info())} was removed from cache`,\n );\n }\n }\n\n /** Removes all files from a hard drive. */\n async releaseAll() {\n this.downloadQueue.stop();\n\n await Promise.all(\n Array.from(this.idToDownload.entries()).map(async ([_, task]) => {\n await rmRFDir(task.path);\n this.cache.removeCache(task);\n\n this.removeTask(\n task,\n `the task ${stringifyWithResourceId(task.info())} was released when the driver was closed`,\n );\n }),\n );\n }\n\n private setNewTask(w: Watcher, rInfo: DownloadableBlobSnapshot, format: ArchiveFormat, callerId: string) {\n const result = new DownloadAndUnarchiveTask(\n this.logger,\n this.signer,\n this.saveDir,\n this.getFilePath(rInfo.id, format),\n rInfo,\n format,\n this.clientDownload,\n );\n result.attach(w, callerId);\n this.idToDownload.set(newId(rInfo.id, format), result);\n\n return result;\n }\n\n private removeTask(task: DownloadAndUnarchiveTask, reason: string) {\n task.abort(reason);\n task.change.markChanged(`task for ${resourceIdToString(task.rInfo.id)} removed: ${reason}`);\n this.idToDownload.delete(newId(task.rInfo.id, task.format));\n }\n\n private getFilePath(id: ResourceId, format: ArchiveFormat): string {\n return path.join(this.saveDir, `${String(BigInt(id))}_${format}`);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver_id.cjs","sources":["../../../src/drivers/download_blob_url/driver_id.ts"],"sourcesContent":["import type { ResourceId } from '@milaboratories/pl-client';\nimport type { ArchiveFormat } from '@milaboratories/pl-model-common';\n\n/** A key in the driver task queue. */\nexport type Id = string;\n\nexport function newId(id: ResourceId, format: ArchiveFormat): Id {\n return `id:${String(BigInt(id))}-${format}`;\n}\n\n// export function\n"],"names":[],"mappings":";;AAMM,SAAU,KAAK,CAAC,EAAc,EAAE,MAAqB,EAAA;IACzD,OAAO,CAAA,GAAA,EAAM,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE;AAC7C;AAEA;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver_id.js","sources":["../../../src/drivers/download_blob_url/driver_id.ts"],"sourcesContent":["import type { ResourceId } from '@milaboratories/pl-client';\nimport type { ArchiveFormat } from '@milaboratories/pl-model-common';\n\n/** A key in the driver task queue. */\nexport type Id = string;\n\nexport function newId(id: ResourceId, format: ArchiveFormat): Id {\n return `id:${String(BigInt(id))}-${format}`;\n}\n\n// export function\n"],"names":[],"mappings":"AAMM,SAAU,KAAK,CAAC,EAAc,EAAE,MAAqB,EAAA;IACzD,OAAO,CAAA,GAAA,EAAM,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE;AAC7C;AAEA;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var plTree = require('@milaboratories/pl-tree');
|
|
4
|
+
|
|
5
|
+
/** We need only resource type for this driver. */
|
|
6
|
+
const DownloadableBlobSnapshot = plTree.rsSchema({});
|
|
7
|
+
function makeDownloadableBlobSnapshot(entryOrAccessor, ctx) {
|
|
8
|
+
const node = plTree.isPlTreeEntry(entryOrAccessor)
|
|
9
|
+
? ctx.accessor(entryOrAccessor).node()
|
|
10
|
+
: plTree.isPlTreeEntryAccessor(entryOrAccessor)
|
|
11
|
+
? entryOrAccessor.node()
|
|
12
|
+
: entryOrAccessor;
|
|
13
|
+
return plTree.makeResourceSnapshot(node, DownloadableBlobSnapshot);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.DownloadableBlobSnapshot = DownloadableBlobSnapshot;
|
|
17
|
+
exports.makeDownloadableBlobSnapshot = makeDownloadableBlobSnapshot;
|
|
18
|
+
//# sourceMappingURL=snapshot.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.cjs","sources":["../../../src/drivers/download_blob_url/snapshot.ts"],"sourcesContent":["import type { ComputableCtx } from '@milaboratories/computable';\nimport type { InferSnapshot, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor } from '@milaboratories/pl-tree';\nimport { isPlTreeEntry, isPlTreeEntryAccessor, makeResourceSnapshot, rsSchema } from '@milaboratories/pl-tree';\n\n/** We need only resource type for this driver. */\nexport const DownloadableBlobSnapshot = rsSchema({});\nexport type DownloadableBlobSnapshot = InferSnapshot<typeof DownloadableBlobSnapshot>;\n\nexport function makeDownloadableBlobSnapshot(\n entryOrAccessor: PlTreeEntry | PlTreeNodeAccessor | PlTreeEntryAccessor,\n ctx: ComputableCtx,\n): DownloadableBlobSnapshot {\n const node = isPlTreeEntry(entryOrAccessor)\n ? ctx.accessor(entryOrAccessor).node()\n : isPlTreeEntryAccessor(entryOrAccessor)\n ? entryOrAccessor.node()\n : entryOrAccessor;\n\n return makeResourceSnapshot(node, DownloadableBlobSnapshot);\n}\n"],"names":["rsSchema","isPlTreeEntry","isPlTreeEntryAccessor","makeResourceSnapshot"],"mappings":";;;;AAIA;MACa,wBAAwB,GAAGA,eAAQ,CAAC,EAAE;AAG7C,SAAU,4BAA4B,CAC1C,eAAuE,EACvE,GAAkB,EAAA;AAElB,IAAA,MAAM,IAAI,GAAGC,oBAAa,CAAC,eAAe;UACtC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,IAAI;AACpC,UAAEC,4BAAqB,CAAC,eAAe;AACrC,cAAE,eAAe,CAAC,IAAI;cACpB,eAAe;AAErB,IAAA,OAAOC,2BAAoB,CAAC,IAAI,EAAE,wBAAwB,CAAC;AAC7D;;;;;"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ComputableCtx } from '@milaboratories/computable';
|
|
2
|
-
import { InferSnapshot, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor
|
|
2
|
+
import { InferSnapshot, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor } from '@milaboratories/pl-tree';
|
|
3
3
|
/** We need only resource type for this driver. */
|
|
4
|
-
export declare const DownloadableBlobSnapshot: ResourceSnapshotSchema<undefined, undefined, undefined>;
|
|
4
|
+
export declare const DownloadableBlobSnapshot: import('@milaboratories/pl-tree').ResourceSnapshotSchema<undefined, undefined, undefined>;
|
|
5
5
|
export type DownloadableBlobSnapshot = InferSnapshot<typeof DownloadableBlobSnapshot>;
|
|
6
6
|
export declare function makeDownloadableBlobSnapshot(entryOrAccessor: PlTreeEntry | PlTreeNodeAccessor | PlTreeEntryAccessor, ctx: ComputableCtx): DownloadableBlobSnapshot;
|
|
7
|
-
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { rsSchema, isPlTreeEntry, isPlTreeEntryAccessor, makeResourceSnapshot } from '@milaboratories/pl-tree';
|
|
2
|
+
|
|
3
|
+
/** We need only resource type for this driver. */
|
|
4
|
+
const DownloadableBlobSnapshot = rsSchema({});
|
|
5
|
+
function makeDownloadableBlobSnapshot(entryOrAccessor, ctx) {
|
|
6
|
+
const node = isPlTreeEntry(entryOrAccessor)
|
|
7
|
+
? ctx.accessor(entryOrAccessor).node()
|
|
8
|
+
: isPlTreeEntryAccessor(entryOrAccessor)
|
|
9
|
+
? entryOrAccessor.node()
|
|
10
|
+
: entryOrAccessor;
|
|
11
|
+
return makeResourceSnapshot(node, DownloadableBlobSnapshot);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { DownloadableBlobSnapshot, makeDownloadableBlobSnapshot };
|
|
15
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sources":["../../../src/drivers/download_blob_url/snapshot.ts"],"sourcesContent":["import type { ComputableCtx } from '@milaboratories/computable';\nimport type { InferSnapshot, PlTreeEntry, PlTreeEntryAccessor, PlTreeNodeAccessor } from '@milaboratories/pl-tree';\nimport { isPlTreeEntry, isPlTreeEntryAccessor, makeResourceSnapshot, rsSchema } from '@milaboratories/pl-tree';\n\n/** We need only resource type for this driver. */\nexport const DownloadableBlobSnapshot = rsSchema({});\nexport type DownloadableBlobSnapshot = InferSnapshot<typeof DownloadableBlobSnapshot>;\n\nexport function makeDownloadableBlobSnapshot(\n entryOrAccessor: PlTreeEntry | PlTreeNodeAccessor | PlTreeEntryAccessor,\n ctx: ComputableCtx,\n): DownloadableBlobSnapshot {\n const node = isPlTreeEntry(entryOrAccessor)\n ? ctx.accessor(entryOrAccessor).node()\n : isPlTreeEntryAccessor(entryOrAccessor)\n ? entryOrAccessor.node()\n : entryOrAccessor;\n\n return makeResourceSnapshot(node, DownloadableBlobSnapshot);\n}\n"],"names":[],"mappings":";;AAIA;MACa,wBAAwB,GAAG,QAAQ,CAAC,EAAE;AAG7C,SAAU,4BAA4B,CAC1C,eAAuE,EACvE,GAAkB,EAAA;AAElB,IAAA,MAAM,IAAI,GAAG,aAAa,CAAC,eAAe;UACtC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,IAAI;AACpC,UAAE,qBAAqB,CAAC,eAAe;AACrC,cAAE,eAAe,CAAC,IAAI;cACpB,eAAe;AAErB,IAAA,OAAO,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,CAAC;AAC7D;;;;"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var node_stream = require('node:stream');
|
|
4
|
+
var zlib = require('node:zlib');
|
|
5
|
+
var tar = require('tar-fs');
|
|
6
|
+
var path = require('node:path');
|
|
7
|
+
var fs = require('node:fs');
|
|
8
|
+
var fsp = require('node:fs/promises');
|
|
9
|
+
var download = require('../../helpers/download.cjs');
|
|
10
|
+
var computable = require('@milaboratories/computable');
|
|
11
|
+
var tsHelpers = require('@milaboratories/ts-helpers');
|
|
12
|
+
var download$1 = require('../../clients/download.cjs');
|
|
13
|
+
var url = require('../urls/url.cjs');
|
|
14
|
+
var decompress = require('decompress');
|
|
15
|
+
var runtime = require('@protobuf-ts/runtime');
|
|
16
|
+
var plClient = require('@milaboratories/pl-client');
|
|
17
|
+
|
|
18
|
+
function _interopNamespaceDefault(e) {
|
|
19
|
+
var n = Object.create(null);
|
|
20
|
+
if (e) {
|
|
21
|
+
Object.keys(e).forEach(function (k) {
|
|
22
|
+
if (k !== 'default') {
|
|
23
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
24
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return e[k]; }
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
n.default = e;
|
|
32
|
+
return Object.freeze(n);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
var zlib__namespace = /*#__PURE__*/_interopNamespaceDefault(zlib);
|
|
36
|
+
var tar__namespace = /*#__PURE__*/_interopNamespaceDefault(tar);
|
|
37
|
+
var fsp__namespace = /*#__PURE__*/_interopNamespaceDefault(fsp);
|
|
38
|
+
|
|
39
|
+
/** Downloads and extracts an archive to a directory. */
|
|
40
|
+
class DownloadAndUnarchiveTask {
|
|
41
|
+
logger;
|
|
42
|
+
signer;
|
|
43
|
+
saveDir;
|
|
44
|
+
path;
|
|
45
|
+
rInfo;
|
|
46
|
+
format;
|
|
47
|
+
clientDownload;
|
|
48
|
+
counter = new tsHelpers.CallersCounter();
|
|
49
|
+
change = new computable.ChangeSource();
|
|
50
|
+
signalCtl = new AbortController();
|
|
51
|
+
error;
|
|
52
|
+
done = false;
|
|
53
|
+
size = 0;
|
|
54
|
+
url;
|
|
55
|
+
state;
|
|
56
|
+
constructor(logger, signer, saveDir, path, rInfo, format, clientDownload) {
|
|
57
|
+
this.logger = logger;
|
|
58
|
+
this.signer = signer;
|
|
59
|
+
this.saveDir = saveDir;
|
|
60
|
+
this.path = path;
|
|
61
|
+
this.rInfo = rInfo;
|
|
62
|
+
this.format = format;
|
|
63
|
+
this.clientDownload = clientDownload;
|
|
64
|
+
}
|
|
65
|
+
/** A debug info of the task. */
|
|
66
|
+
info() {
|
|
67
|
+
return {
|
|
68
|
+
rInfo: this.rInfo,
|
|
69
|
+
format: this.format,
|
|
70
|
+
path: this.path,
|
|
71
|
+
done: this.done,
|
|
72
|
+
size: this.size,
|
|
73
|
+
error: this.error,
|
|
74
|
+
taskHistory: this.state,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
attach(w, callerId) {
|
|
78
|
+
this.counter.inc(callerId);
|
|
79
|
+
if (!this.done)
|
|
80
|
+
this.change.attachWatcher(w);
|
|
81
|
+
}
|
|
82
|
+
async download() {
|
|
83
|
+
try {
|
|
84
|
+
const size = await this.downloadAndDecompress(this.signalCtl.signal);
|
|
85
|
+
this.setDone(size);
|
|
86
|
+
this.change.markChanged(`download and decompress for ${plClient.resourceIdToString(this.rInfo.id)} finished`);
|
|
87
|
+
this.logger.info(`blob to URL task is done: ${plClient.stringifyWithResourceId(this.info())}`);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
this.logger.warn(`a error was produced: ${e} for blob to URL task: ${plClient.stringifyWithResourceId(this.info())}`);
|
|
91
|
+
if (nonRecoverableError(e)) {
|
|
92
|
+
this.setError(e);
|
|
93
|
+
this.change.markChanged(`download and decompress for ${plClient.resourceIdToString(this.rInfo.id)} failed`);
|
|
94
|
+
// Just in case we were half-way extracting an archive.
|
|
95
|
+
await rmRFDir(this.path);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** Does the download part and keeps a state of the process. */
|
|
102
|
+
async downloadAndDecompress(signal) {
|
|
103
|
+
this.state = {};
|
|
104
|
+
this.state.parentDir = path.dirname(this.path);
|
|
105
|
+
await tsHelpers.ensureDirExists(this.state.parentDir);
|
|
106
|
+
this.state.fileExisted = await tsHelpers.fileExists(this.path);
|
|
107
|
+
if (this.state.fileExisted) {
|
|
108
|
+
return await dirSize(this.path);
|
|
109
|
+
}
|
|
110
|
+
const size = await this.clientDownload.withBlobContent(this.rInfo, {}, { signal }, async (content, size) => {
|
|
111
|
+
this.state.downloaded = true;
|
|
112
|
+
await tsHelpers.createPathAtomically(this.logger, this.path, async (fPath) => {
|
|
113
|
+
this.state.tempPath = fPath;
|
|
114
|
+
this.state.archiveFormat = this.format;
|
|
115
|
+
switch (this.format) {
|
|
116
|
+
case 'tar':
|
|
117
|
+
await fsp__namespace.mkdir(fPath); // throws if a directory already exists.
|
|
118
|
+
const simpleUntar = node_stream.Writable.toWeb(tar__namespace.extract(fPath));
|
|
119
|
+
await content.pipeTo(simpleUntar, { signal });
|
|
120
|
+
return;
|
|
121
|
+
case 'tgz':
|
|
122
|
+
await fsp__namespace.mkdir(fPath); // throws if a directory already exists.
|
|
123
|
+
const gunzip = node_stream.Transform.toWeb(zlib__namespace.createGunzip());
|
|
124
|
+
const untar = node_stream.Writable.toWeb(tar__namespace.extract(fPath));
|
|
125
|
+
await content
|
|
126
|
+
.pipeThrough(gunzip, { signal })
|
|
127
|
+
.pipeTo(untar, { signal });
|
|
128
|
+
return;
|
|
129
|
+
case 'zip':
|
|
130
|
+
this.state.zipPath = this.path + '.zip';
|
|
131
|
+
const f = node_stream.Writable.toWeb(fs.createWriteStream(this.state.zipPath));
|
|
132
|
+
await content.pipeTo(f, { signal });
|
|
133
|
+
this.state.zipPathCreated = true;
|
|
134
|
+
// Without this filter it fails with
|
|
135
|
+
// "EISDIR: illegal operation on a directory".
|
|
136
|
+
// The workaround is from
|
|
137
|
+
// https://github.com/kevva/decompress/issues/46#issuecomment-525048104
|
|
138
|
+
await decompress(this.state.zipPath, fPath, {
|
|
139
|
+
filter: file => !file.path.endsWith('/'),
|
|
140
|
+
});
|
|
141
|
+
this.state.zipDecompressed = true;
|
|
142
|
+
await fs.promises.rm(this.state.zipPath);
|
|
143
|
+
this.state.zipPathDeleted = true;
|
|
144
|
+
return;
|
|
145
|
+
default:
|
|
146
|
+
runtime.assertNever(this.format);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
this.state.pathCreated = true;
|
|
150
|
+
return size;
|
|
151
|
+
});
|
|
152
|
+
return size;
|
|
153
|
+
}
|
|
154
|
+
getURL() {
|
|
155
|
+
if (this.done)
|
|
156
|
+
return { url: tsHelpers.notEmpty(this.url) };
|
|
157
|
+
if (this.error)
|
|
158
|
+
return { error: this.error };
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
setDone(size) {
|
|
162
|
+
this.done = true;
|
|
163
|
+
this.size = size;
|
|
164
|
+
this.url = url.newFolderURL(this.signer, this.saveDir, this.path);
|
|
165
|
+
}
|
|
166
|
+
setError(e) {
|
|
167
|
+
this.error = String(e);
|
|
168
|
+
}
|
|
169
|
+
abort(reason) {
|
|
170
|
+
this.signalCtl.abort(new URLAborted(reason));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/** Gets a directory size by calculating sizes recursively. */
|
|
174
|
+
async function dirSize(dir) {
|
|
175
|
+
const files = await fsp__namespace.readdir(dir, { withFileTypes: true });
|
|
176
|
+
const sizes = await Promise.all(files.map(async (file) => {
|
|
177
|
+
const fPath = path.join(dir, file.name);
|
|
178
|
+
if (file.isDirectory())
|
|
179
|
+
return await dirSize(fPath);
|
|
180
|
+
const stat = await fsp__namespace.stat(fPath);
|
|
181
|
+
return stat.size;
|
|
182
|
+
}));
|
|
183
|
+
return sizes.reduce((sum, size) => sum + size, 0);
|
|
184
|
+
}
|
|
185
|
+
/** Do rm -rf on dir. */
|
|
186
|
+
async function rmRFDir(path) {
|
|
187
|
+
await fsp__namespace.rm(path, { recursive: true, force: true });
|
|
188
|
+
}
|
|
189
|
+
/** Throws when a downloading aborts. */
|
|
190
|
+
class URLAborted extends Error {
|
|
191
|
+
name = 'URLAborted';
|
|
192
|
+
}
|
|
193
|
+
function nonRecoverableError(e) {
|
|
194
|
+
return (e instanceof URLAborted
|
|
195
|
+
|| e instanceof download.NetworkError400
|
|
196
|
+
|| e instanceof download$1.UnknownStorageError
|
|
197
|
+
|| e instanceof download$1.WrongLocalFileUrl
|
|
198
|
+
// file that we downloads from was moved or deleted.
|
|
199
|
+
|| e?.code == 'ENOENT'
|
|
200
|
+
// A resource was deleted.
|
|
201
|
+
|| (e.name == 'RpcError' && (e.code == 'NOT_FOUND' || e.code == 'ABORTED'))
|
|
202
|
+
// wrong archive format
|
|
203
|
+
|| (String(e).includes('incorrect header check')));
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
exports.DownloadAndUnarchiveTask = DownloadAndUnarchiveTask;
|
|
207
|
+
exports.nonRecoverableError = nonRecoverableError;
|
|
208
|
+
exports.rmRFDir = rmRFDir;
|
|
209
|
+
//# sourceMappingURL=task.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task.cjs","sources":["../../../src/drivers/download_blob_url/task.ts"],"sourcesContent":["import { Transform, Writable } from 'node:stream';\nimport * as zlib from 'node:zlib';\nimport * as tar from 'tar-fs';\nimport path from 'path';\nimport fs from 'fs';\nimport * as fsp from 'fs/promises';\nimport { NetworkError400 } from '../../helpers/download';\nimport type { Watcher } from '@milaboratories/computable';\nimport { ChangeSource } from '@milaboratories/computable';\nimport type { MiLogger, Signer } from '@milaboratories/ts-helpers';\nimport { CallersCounter, createPathAtomically, ensureDirExists, fileExists, notEmpty } from '@milaboratories/ts-helpers';\nimport type { DownloadableBlobSnapshot } from './snapshot';\nimport { UnknownStorageError, WrongLocalFileUrl, type ClientDownload } from '../../clients/download';\nimport type { ArchiveFormat, FolderURL } from '@milaboratories/pl-model-common';\nimport { newFolderURL } from '../urls/url';\nimport decompress from 'decompress';\nimport { assertNever } from '@protobuf-ts/runtime';\nimport { resourceIdToString, stringifyWithResourceId } from '@milaboratories/pl-client';\n\nexport type URLResult = {\n url?: FolderURL;\n error?: string;\n};\n\n/** Downloads and extracts an archive to a directory. */\nexport class DownloadAndUnarchiveTask {\n readonly counter = new CallersCounter();\n readonly change = new ChangeSource();\n private readonly signalCtl = new AbortController();\n error: string | undefined;\n done = false;\n size = 0;\n private url: FolderURL | undefined;\n private state: DownloadCtx | undefined;\n\n constructor(\n private readonly logger: MiLogger,\n private readonly signer: Signer,\n readonly saveDir: string,\n readonly path: string,\n readonly rInfo: DownloadableBlobSnapshot,\n readonly format: ArchiveFormat,\n private readonly clientDownload: ClientDownload,\n ) {}\n\n /** A debug info of the task. */\n public info() {\n return {\n rInfo: this.rInfo,\n format: this.format,\n path: this.path,\n done: this.done,\n size: this.size,\n error: this.error,\n taskHistory: this.state,\n };\n }\n\n attach(w: Watcher, callerId: string) {\n this.counter.inc(callerId);\n if (!this.done) this.change.attachWatcher(w);\n }\n\n async download() {\n try {\n const size = await this.downloadAndDecompress(this.signalCtl.signal);\n this.setDone(size);\n this.change.markChanged(`download and decompress for ${resourceIdToString(this.rInfo.id)} finished`);\n\n this.logger.info(`blob to URL task is done: ${stringifyWithResourceId(this.info())}`);\n } catch (e: any) {\n this.logger.warn(`a error was produced: ${e} for blob to URL task: ${stringifyWithResourceId(this.info())}`);\n\n if (nonRecoverableError(e)) {\n this.setError(e);\n this.change.markChanged(`download and decompress for ${resourceIdToString(this.rInfo.id)} failed`);\n // Just in case we were half-way extracting an archive.\n await rmRFDir(this.path);\n return;\n }\n\n throw e;\n }\n }\n\n /** Does the download part and keeps a state of the process. */\n private async downloadAndDecompress(signal: AbortSignal): Promise<number> {\n this.state = {};\n\n this.state.parentDir = path.dirname(this.path);\n await ensureDirExists(this.state.parentDir);\n\n this.state.fileExisted = await fileExists(this.path);\n if (this.state.fileExisted) {\n return await dirSize(this.path);\n }\n\n const size = await this.clientDownload.withBlobContent(\n this.rInfo, \n {}, \n { signal },\n async (content, size) => {\n this.state!.downloaded = true;\n\n await createPathAtomically(this.logger, this.path, async (fPath: string) => {\n this.state!.tempPath = fPath;\n this.state!.archiveFormat = this.format;\n\n switch (this.format) {\n case 'tar':\n await fsp.mkdir(fPath); // throws if a directory already exists.\n const simpleUntar = Writable.toWeb(tar.extract(fPath));\n await content.pipeTo(simpleUntar, { signal });\n return;\n\n case 'tgz':\n await fsp.mkdir(fPath); // throws if a directory already exists.\n const gunzip = Transform.toWeb(zlib.createGunzip());\n const untar = Writable.toWeb(tar.extract(fPath));\n\n await content\n .pipeThrough(gunzip, { signal })\n .pipeTo(untar, { signal });\n return;\n\n case 'zip':\n this.state!.zipPath = this.path + '.zip';\n\n const f = Writable.toWeb(fs.createWriteStream(this.state!.zipPath));\n await content.pipeTo(f, { signal });\n this.state!.zipPathCreated = true;\n\n // Without this filter it fails with\n // \"EISDIR: illegal operation on a directory\".\n // The workaround is from\n // https://github.com/kevva/decompress/issues/46#issuecomment-525048104\n await decompress(this.state!.zipPath, fPath, {\n filter: file => !file.path.endsWith('/'),\n });\n this.state!.zipDecompressed = true;\n\n await fs.promises.rm(this.state!.zipPath);\n this.state!.zipPathDeleted = true;\n\n return;\n\n default:\n assertNever(this.format);\n }\n });\n\n this.state!.pathCreated = true;\n return size;\n }\n );\n\n return size;\n }\n\n getURL(): URLResult | undefined {\n if (this.done) return { url: notEmpty(this.url) };\n\n if (this.error) return { error: this.error };\n\n return undefined;\n }\n\n private setDone(size: number) {\n this.done = true;\n this.size = size;\n this.url = newFolderURL(this.signer, this.saveDir, this.path);\n }\n\n private setError(e: any) {\n this.error = String(e);\n }\n\n abort(reason: string) {\n this.signalCtl.abort(new URLAborted(reason));\n }\n}\n\n/** Gets a directory size by calculating sizes recursively. */\nasync function dirSize(dir: string): Promise<number> {\n const files = await fsp.readdir(dir, { withFileTypes: true });\n const sizes = await Promise.all(\n files.map(async (file: any) => {\n const fPath = path.join(dir, file.name);\n\n if (file.isDirectory()) return await dirSize(fPath);\n\n const stat = await fsp.stat(fPath);\n return stat.size;\n }),\n );\n\n return sizes.reduce((sum: any, size: any) => sum + size, 0);\n}\n\n/** Do rm -rf on dir. */\nexport async function rmRFDir(path: string) {\n await fsp.rm(path, { recursive: true, force: true });\n}\n\n/** Just a type that adds lots of context when the error happens. */\ntype DownloadCtx = {\n parentDir?: string;\n fileExisted?: boolean;\n downloaded?: boolean;\n archiveFormat?: ArchiveFormat;\n tempPath?: string;\n zipPath?: string;\n zipPathCreated?: boolean;\n zipDecompressed?: boolean;\n zipPathDeleted?: boolean;\n pathCreated?: boolean;\n};\n\n/** Throws when a downloading aborts. */\nclass URLAborted extends Error {\n name = 'URLAborted';\n}\n\nexport function nonRecoverableError(e: any) {\n return (\n e instanceof URLAborted\n || e instanceof NetworkError400\n || e instanceof UnknownStorageError\n || e instanceof WrongLocalFileUrl\n // file that we downloads from was moved or deleted.\n || e?.code == 'ENOENT'\n // A resource was deleted.\n || (e.name == 'RpcError' && (e.code == 'NOT_FOUND' || e.code == 'ABORTED'))\n // wrong archive format\n || (String(e).includes('incorrect header check'))\n );\n}\n"],"names":["CallersCounter","ChangeSource","resourceIdToString","stringifyWithResourceId","ensureDirExists","fileExists","createPathAtomically","fsp","Writable","tar","Transform","zlib","assertNever","notEmpty","newFolderURL","NetworkError400","UnknownStorageError","WrongLocalFileUrl"],"mappings":"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"}
|