@milaboratories/pl-drivers 1.11.58 → 1.11.60
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/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/clients/constructors.cjs +28 -28
- package/dist/clients/constructors.cjs.map +1 -1
- package/dist/clients/constructors.d.ts +17 -13
- package/dist/clients/constructors.js +28 -26
- package/dist/clients/constructors.js.map +1 -1
- package/dist/clients/crc32c.cjs +8 -13
- package/dist/clients/crc32c.cjs.map +1 -1
- package/dist/clients/crc32c.js +8 -12
- package/dist/clients/crc32c.js.map +1 -1
- package/dist/clients/download.cjs +119 -160
- package/dist/clients/download.cjs.map +1 -1
- package/dist/clients/download.d.ts +45 -41
- package/dist/clients/download.js +115 -137
- package/dist/clients/download.js.map +1 -1
- package/dist/clients/logs.cjs +78 -82
- package/dist/clients/logs.cjs.map +1 -1
- package/dist/clients/logs.d.ts +34 -24
- package/dist/clients/logs.js +77 -80
- package/dist/clients/logs.js.map +1 -1
- package/dist/clients/ls_api.cjs +62 -68
- package/dist/clients/ls_api.cjs.map +1 -1
- package/dist/clients/ls_api.d.ts +15 -11
- package/dist/clients/ls_api.js +61 -66
- package/dist/clients/ls_api.js.map +1 -1
- package/dist/clients/progress.cjs +49 -59
- package/dist/clients/progress.cjs.map +1 -1
- package/dist/clients/progress.d.ts +27 -20
- package/dist/clients/progress.js +48 -57
- package/dist/clients/progress.js.map +1 -1
- package/dist/clients/upload.cjs +189 -250
- package/dist/clients/upload.cjs.map +1 -1
- package/dist/clients/upload.d.ts +44 -34
- package/dist/clients/upload.js +187 -229
- package/dist/clients/upload.js.map +1 -1
- package/dist/drivers/download_blob/blob_key.cjs +9 -26
- package/dist/drivers/download_blob/blob_key.cjs.map +1 -1
- package/dist/drivers/download_blob/blob_key.js +7 -5
- package/dist/drivers/download_blob/blob_key.js.map +1 -1
- package/dist/drivers/download_blob/download_blob.cjs +395 -478
- package/dist/drivers/download_blob/download_blob.cjs.map +1 -1
- package/dist/drivers/download_blob/download_blob.d.ts +102 -100
- package/dist/drivers/download_blob/download_blob.js +388 -453
- package/dist/drivers/download_blob/download_blob.js.map +1 -1
- package/dist/drivers/download_blob/download_blob_task.cjs +128 -163
- package/dist/drivers/download_blob/download_blob_task.cjs.map +1 -1
- package/dist/drivers/download_blob/download_blob_task.js +125 -141
- package/dist/drivers/download_blob/download_blob_task.js.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/cache.cjs +166 -195
- package/dist/drivers/download_blob/sparse_cache/cache.cjs.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/cache.js +164 -193
- package/dist/drivers/download_blob/sparse_cache/cache.js.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/file.cjs +29 -50
- package/dist/drivers/download_blob/sparse_cache/file.cjs.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/file.js +28 -29
- package/dist/drivers/download_blob/sparse_cache/file.js.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.cjs +48 -76
- package/dist/drivers/download_blob/sparse_cache/ranges.cjs.map +1 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.js +47 -54
- package/dist/drivers/download_blob/sparse_cache/ranges.js.map +1 -1
- package/dist/drivers/download_blob_url/driver.cjs +125 -165
- package/dist/drivers/download_blob_url/driver.cjs.map +1 -1
- package/dist/drivers/download_blob_url/driver.d.ts +45 -42
- package/dist/drivers/download_blob_url/driver.js +123 -144
- package/dist/drivers/download_blob_url/driver.js.map +1 -1
- package/dist/drivers/download_blob_url/driver_id.cjs +4 -4
- package/dist/drivers/download_blob_url/driver_id.cjs.map +1 -1
- package/dist/drivers/download_blob_url/driver_id.js +4 -3
- package/dist/drivers/download_blob_url/driver_id.js.map +1 -1
- package/dist/drivers/download_blob_url/snapshot.cjs +7 -11
- package/dist/drivers/download_blob_url/snapshot.cjs.map +1 -1
- package/dist/drivers/download_blob_url/snapshot.d.ts +10 -5
- package/dist/drivers/download_blob_url/snapshot.js +5 -8
- package/dist/drivers/download_blob_url/snapshot.js.map +1 -1
- package/dist/drivers/download_blob_url/task.cjs +147 -194
- package/dist/drivers/download_blob_url/task.cjs.map +1 -1
- package/dist/drivers/download_blob_url/task.d.ts +55 -57
- package/dist/drivers/download_blob_url/task.js +140 -170
- package/dist/drivers/download_blob_url/task.js.map +1 -1
- package/dist/drivers/download_url/driver.cjs +109 -146
- package/dist/drivers/download_url/driver.cjs.map +1 -1
- package/dist/drivers/download_url/driver.d.ts +59 -57
- package/dist/drivers/download_url/driver.js +107 -125
- package/dist/drivers/download_url/driver.js.map +1 -1
- package/dist/drivers/download_url/task.cjs +104 -137
- package/dist/drivers/download_url/task.cjs.map +1 -1
- package/dist/drivers/download_url/task.d.ts +33 -37
- package/dist/drivers/download_url/task.js +99 -113
- package/dist/drivers/download_url/task.js.map +1 -1
- package/dist/drivers/helpers/download_local_handle.cjs +13 -14
- package/dist/drivers/helpers/download_local_handle.cjs.map +1 -1
- package/dist/drivers/helpers/download_local_handle.js +13 -13
- package/dist/drivers/helpers/download_local_handle.js.map +1 -1
- package/dist/drivers/helpers/download_remote_handle.cjs +23 -24
- package/dist/drivers/helpers/download_remote_handle.cjs.map +1 -1
- package/dist/drivers/helpers/download_remote_handle.js +22 -22
- package/dist/drivers/helpers/download_remote_handle.js.map +1 -1
- package/dist/drivers/helpers/files_cache.cjs +53 -64
- package/dist/drivers/helpers/files_cache.cjs.map +1 -1
- package/dist/drivers/helpers/files_cache.js +52 -62
- package/dist/drivers/helpers/files_cache.js.map +1 -1
- package/dist/drivers/helpers/helpers.cjs +24 -28
- package/dist/drivers/helpers/helpers.cjs.map +1 -1
- package/dist/drivers/helpers/helpers.d.ts +10 -7
- package/dist/drivers/helpers/helpers.js +24 -27
- package/dist/drivers/helpers/helpers.js.map +1 -1
- package/dist/drivers/helpers/logs_handle.cjs +24 -33
- package/dist/drivers/helpers/logs_handle.cjs.map +1 -1
- package/dist/drivers/helpers/logs_handle.js +24 -29
- package/dist/drivers/helpers/logs_handle.js.map +1 -1
- package/dist/drivers/helpers/ls_remote_import_handle.cjs +20 -20
- package/dist/drivers/helpers/ls_remote_import_handle.cjs.map +1 -1
- package/dist/drivers/helpers/ls_remote_import_handle.js +20 -18
- package/dist/drivers/helpers/ls_remote_import_handle.js.map +1 -1
- package/dist/drivers/helpers/ls_storage_entry.cjs +36 -40
- package/dist/drivers/helpers/ls_storage_entry.cjs.map +1 -1
- package/dist/drivers/helpers/ls_storage_entry.js +36 -37
- package/dist/drivers/helpers/ls_storage_entry.js.map +1 -1
- package/dist/drivers/helpers/polling_ops.d.ts +6 -5
- package/dist/drivers/helpers/read_file.cjs +34 -57
- package/dist/drivers/helpers/read_file.cjs.map +1 -1
- package/dist/drivers/helpers/read_file.js +30 -34
- package/dist/drivers/helpers/read_file.js.map +1 -1
- package/dist/drivers/logs.cjs +94 -112
- package/dist/drivers/logs.cjs.map +1 -1
- package/dist/drivers/logs.d.ts +35 -32
- package/dist/drivers/logs.js +93 -110
- package/dist/drivers/logs.js.map +1 -1
- package/dist/drivers/logs_stream.cjs +210 -242
- package/dist/drivers/logs_stream.cjs.map +1 -1
- package/dist/drivers/logs_stream.d.ts +55 -53
- package/dist/drivers/logs_stream.js +209 -240
- package/dist/drivers/logs_stream.js.map +1 -1
- package/dist/drivers/ls.cjs +151 -238
- package/dist/drivers/ls.cjs.map +1 -1
- package/dist/drivers/ls.d.ts +53 -49
- package/dist/drivers/ls.js +148 -216
- package/dist/drivers/ls.js.map +1 -1
- package/dist/drivers/types.cjs +25 -53
- package/dist/drivers/types.cjs.map +1 -1
- package/dist/drivers/types.d.ts +91 -106
- package/dist/drivers/types.js +23 -50
- package/dist/drivers/types.js.map +1 -1
- package/dist/drivers/upload.cjs +127 -153
- package/dist/drivers/upload.cjs.map +1 -1
- package/dist/drivers/upload.d.ts +52 -50
- package/dist/drivers/upload.js +126 -151
- package/dist/drivers/upload.js.map +1 -1
- package/dist/drivers/upload_task.cjs +223 -260
- package/dist/drivers/upload_task.cjs.map +1 -1
- package/dist/drivers/upload_task.d.ts +54 -52
- package/dist/drivers/upload_task.js +221 -258
- package/dist/drivers/upload_task.js.map +1 -1
- package/dist/drivers/urls/url.cjs +30 -35
- package/dist/drivers/urls/url.cjs.map +1 -1
- package/dist/drivers/urls/url.js +28 -33
- package/dist/drivers/urls/url.js.map +1 -1
- package/dist/drivers/virtual_storages.cjs +36 -48
- package/dist/drivers/virtual_storages.cjs.map +1 -1
- package/dist/drivers/virtual_storages.d.ts +6 -2
- package/dist/drivers/virtual_storages.js +32 -46
- package/dist/drivers/virtual_storages.js.map +1 -1
- package/dist/helpers/download.cjs +72 -95
- package/dist/helpers/download.cjs.map +1 -1
- package/dist/helpers/download.d.ts +13 -9
- package/dist/helpers/download.js +71 -93
- package/dist/helpers/download.js.map +1 -1
- package/dist/helpers/download_errors.cjs +28 -27
- package/dist/helpers/download_errors.cjs.map +1 -1
- package/dist/helpers/download_errors.d.ts +16 -13
- package/dist/helpers/download_errors.js +28 -26
- package/dist/helpers/download_errors.js.map +1 -1
- package/dist/helpers/validate.cjs +8 -7
- package/dist/helpers/validate.cjs.map +1 -1
- package/dist/helpers/validate.d.ts +4 -1
- package/dist/helpers/validate.js +6 -5
- package/dist/helpers/validate.js.map +1 -1
- package/dist/index.cjs +75 -79
- package/dist/index.d.ts +22 -22
- package/dist/index.js +22 -21
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs +238 -249
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs +27 -27
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +25 -23
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js +26 -25
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts +51 -87
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js +238 -245
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs +295 -289
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs +30 -30
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js +29 -28
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts +86 -150
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js +295 -285
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs +385 -393
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs +34 -34
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +33 -34
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js +33 -32
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts +78 -129
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js +385 -387
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs +570 -468
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs +82 -82
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +109 -112
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js +81 -80
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts +243 -264
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js +569 -460
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs +751 -729
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs +67 -67
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js +66 -65
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js.map +1 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts +15 -381
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js +749 -718
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js.map +1 -1
- package/dist/proto-grpc/google/protobuf/duration.cjs +92 -100
- package/dist/proto-grpc/google/protobuf/duration.cjs.map +1 -1
- package/dist/proto-grpc/google/protobuf/duration.d.ts +38 -43
- package/dist/proto-grpc/google/protobuf/duration.js +91 -98
- package/dist/proto-grpc/google/protobuf/duration.js.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.cjs +117 -128
- package/dist/proto-grpc/google/protobuf/timestamp.cjs.map +1 -1
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts +50 -55
- package/dist/proto-grpc/google/protobuf/timestamp.js +116 -126
- package/dist/proto-grpc/google/protobuf/timestamp.js.map +1 -1
- package/dist/proto-rest/downloadapi.d.ts +85 -91
- package/dist/proto-rest/index.d.ts +11 -16
- package/dist/proto-rest/progressapi.d.ts +130 -140
- package/dist/proto-rest/streamingapi.d.ts +413 -434
- package/package.json +12 -12
- package/dist/clients/constructors.d.ts.map +0 -1
- package/dist/clients/crc32c.d.ts +0 -2
- package/dist/clients/crc32c.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 +0 -5
- 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 +0 -56
- package/dist/drivers/download_blob/download_blob_task.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/cache.d.ts +0 -82
- package/dist/drivers/download_blob/sparse_cache/cache.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/file.d.ts +0 -8
- package/dist/drivers/download_blob/sparse_cache/file.d.ts.map +0 -1
- package/dist/drivers/download_blob/sparse_cache/ranges.d.ts +0 -46
- 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 +0 -6
- 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_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 +0 -11
- package/dist/drivers/helpers/download_local_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/download_remote_handle.d.ts +0 -13
- package/dist/drivers/helpers/download_remote_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/files_cache.d.ts +0 -29
- 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 +0 -15
- package/dist/drivers/helpers/logs_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts +0 -8
- package/dist/drivers/helpers/ls_remote_import_handle.d.ts.map +0 -1
- package/dist/drivers/helpers/ls_storage_entry.d.ts +0 -23
- 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 +0 -12
- package/dist/drivers/helpers/read_file.d.ts.map +0 -1
- package/dist/drivers/helpers/test_helpers.d.ts +0 -2
- 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 +0 -13
- 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/download_errors.d.ts.map +0 -1
- package/dist/helpers/validate.d.ts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts +0 -46
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts +0 -108
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.d.ts.map +0 -1
- package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +0 -1
- package/dist/proto-grpc/google/api/http.d.ts +0 -460
- package/dist/proto-grpc/google/api/http.d.ts.map +0 -1
- package/dist/proto-grpc/google/protobuf/descriptor.d.ts +0 -2340
- package/dist/proto-grpc/google/protobuf/descriptor.d.ts.map +0 -1
- package/dist/proto-grpc/google/protobuf/duration.d.ts.map +0 -1
- package/dist/proto-grpc/google/protobuf/timestamp.d.ts.map +0 -1
- package/dist/proto-rest/downloadapi.d.ts.map +0 -1
- package/dist/proto-rest/index.d.ts.map +0 -1
- package/dist/proto-rest/lsapi.d.ts +0 -148
- package/dist/proto-rest/lsapi.d.ts.map +0 -1
- package/dist/proto-rest/progressapi.d.ts.map +0 -1
- package/dist/proto-rest/streamingapi.d.ts.map +0 -1
- package/dist/proto-rest/uploadapi.d.ts +0 -355
- package/dist/proto-rest/uploadapi.d.ts.map +0 -1
- package/dist/test_env.d.ts +0 -6
- package/dist/test_env.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs_stream.js","sources":["../../src/drivers/logs_stream.ts"],"sourcesContent":["import type { ComputableCtx, Watcher } from \"@milaboratories/computable\";\nimport { ChangeSource, Computable, PollingComputableHooks } from \"@milaboratories/computable\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport {\n isNotFoundError,\n resourceIdToString,\n stringifyWithResourceId,\n} from \"@milaboratories/pl-client\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\nimport { asyncPool, CallersCounter } from \"@milaboratories/ts-helpers\";\nimport type { ClientLogs } from \"../clients/logs\";\nimport { randomUUID } from \"node:crypto\";\nimport type { PlTreeEntry, ResourceInfo } from \"@milaboratories/pl-tree\";\nimport { treeEntryToResourceInfo } from \"@milaboratories/pl-tree\";\nimport { scheduler } from \"node:timers/promises\";\nimport type { StreamingAPI_Response } from \"../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport type { PollingOps } from \"./helpers/polling_ops\";\nimport { getResourceInfoFromLogHandle, isLiveLogHandle, newLogHandle } from \"./helpers/logs_handle\";\nimport { WrongResourceTypeError } from \"./helpers/helpers\";\n\nexport type LogsStreamDriverOps = PollingOps & {\n /** Max number of concurrent requests to log streaming backend while calculating computable states */\n nConcurrentGetLogs: number;\n};\n\nexport class LogsStreamDriver implements sdk.LogsDriver {\n /** Holds a map of StreamManager Resource Id to all logs of this stream. */\n private readonly idToLastLines: Map<ResourceId, LogGetter> = new Map();\n\n /** Holds a map of StreamManager Resource Id to the last log line of this stream. */\n private readonly idToProgressLog: Map<ResourceId, LogGetter> = new Map();\n\n /** Holds a map of StreamManager Resource Id to log id smart object. */\n private readonly hooks: PollingComputableHooks;\n\n constructor(\n private readonly logger: MiLogger,\n private readonly clientLogs: ClientLogs,\n private readonly opts: LogsStreamDriverOps = {\n nConcurrentGetLogs: 10,\n pollingInterval: 1000,\n stopPollingDelay: 1000,\n },\n ) {\n this.hooks = new PollingComputableHooks(\n () => this.startUpdating(),\n () => this.stopUpdating(),\n { stopDebounce: opts.stopPollingDelay },\n (resolve, reject) => this.scheduleOnNextState(resolve, reject),\n );\n }\n\n getLastLogs(res: ResourceInfo | PlTreeEntry, lines: number): Computable<string | undefined>;\n getLastLogs(\n res: ResourceInfo | PlTreeEntry,\n lines: number,\n ctx: ComputableCtx,\n ): Computable<string | undefined>;\n getLastLogs(\n res: ResourceInfo | PlTreeEntry,\n lines: number,\n ctx?: ComputableCtx,\n ): Computable<string | undefined> | string | undefined {\n if (ctx == undefined) return Computable.make((ctx) => this.getLastLogs(res, lines, ctx));\n\n const r = treeEntryToResourceInfo(res, ctx);\n const callerId = randomUUID();\n ctx.attacheHooks(this.hooks);\n ctx.addOnDestroy(() => this.releaseLastLogs(r.id, callerId));\n\n const result = this.getLastLogsNoCtx(ctx.watcher, r, lines, callerId);\n ctx.markUnstable(\n \"The logs are from stream, so we consider them unstable. Final values will be got from blobs.\",\n );\n\n return result;\n }\n\n private getLastLogsNoCtx(\n w: Watcher,\n rInfo: ResourceInfo,\n lines: number,\n callerId: string,\n ): string | undefined {\n validateResourceType(\"getLastLogs\", rInfo.type);\n\n let logGetter = this.idToLastLines.get(rInfo.id);\n\n if (logGetter == undefined) {\n const newLogGetter = new LogGetter(this.logger, this.clientLogs, rInfo, lines);\n this.idToLastLines.set(rInfo.id, newLogGetter);\n\n logGetter = newLogGetter;\n }\n\n logGetter.attach(w, callerId);\n const result = logGetter.getLog();\n if (result.error != undefined) throw result.error;\n\n return result.log;\n }\n\n /** Returns a last line that has patternToSearch.\n * Notifies when a new line appeared or EOF reached. */\n getProgressLog(\n res: ResourceInfo | PlTreeEntry,\n patternToSearch: string,\n ): Computable<string | undefined>;\n getProgressLog(\n res: ResourceInfo | PlTreeEntry,\n patternToSearch: string,\n ctx: ComputableCtx,\n ): string | undefined;\n getProgressLog(\n res: ResourceInfo | PlTreeEntry,\n patternToSearch: string,\n ctx?: ComputableCtx,\n ): Computable<string | undefined> | string | undefined {\n if (ctx == undefined)\n return Computable.make((ctx) => this.getProgressLog(res, patternToSearch, ctx));\n\n const r = treeEntryToResourceInfo(res, ctx);\n const callerId = randomUUID();\n ctx.attacheHooks(this.hooks);\n ctx.addOnDestroy(() => this.releaseProgressLog(r.id, callerId));\n\n const result = this.getProgressLogNoCtx(ctx.watcher, r, patternToSearch, callerId);\n ctx.markUnstable(\n \"The progress log is from the stream, so we consider it unstable. Final value will be got from blobs.\",\n );\n\n return result;\n }\n\n private getProgressLogNoCtx(\n w: Watcher,\n rInfo: ResourceInfo,\n patternToSearch: string,\n callerId: string,\n ): string | undefined {\n validateResourceType(\"getProgressLog\", rInfo.type);\n\n let logGetter = this.idToProgressLog.get(rInfo.id);\n\n if (logGetter == undefined) {\n const newLogGetter = new LogGetter(this.logger, this.clientLogs, rInfo, 1, patternToSearch);\n this.idToProgressLog.set(rInfo.id, newLogGetter);\n\n logGetter = newLogGetter;\n }\n\n logGetter.attach(w, callerId);\n const result = logGetter.getLog();\n if (result.error) throw result.error;\n\n return result.log;\n }\n\n getLogHandle(res: ResourceInfo | PlTreeEntry): Computable<sdk.AnyLogHandle>;\n getLogHandle(res: ResourceInfo | PlTreeEntry, ctx: ComputableCtx): sdk.AnyLogHandle;\n getLogHandle(\n res: ResourceInfo | PlTreeEntry,\n ctx?: ComputableCtx,\n ): Computable<sdk.AnyLogHandle> | sdk.AnyLogHandle {\n if (ctx == undefined) return Computable.make((ctx) => this.getLogHandle(res, ctx));\n\n const r = treeEntryToResourceInfo(res, ctx);\n\n const result = this.getLogHandleNoCtx(r);\n\n // All logs from streams should be considered unstable,\n // final value will be got from blobs.\n ctx.markUnstable(`live_log:${resourceIdToString(r.id)}`);\n\n return result;\n }\n\n private getLogHandleNoCtx(rInfo: ResourceInfo): sdk.AnyLogHandle {\n validateResourceType(\"getLogHandle\", rInfo.type);\n\n return newLogHandle(true, rInfo);\n }\n\n async lastLines(\n handle: sdk.AnyLogHandle,\n lineCount: number,\n offsetBytes?: number,\n searchStr?: string | undefined,\n ) {\n return await this.tryWithNotFound(handle, () =>\n this.clientLogs.lastLines(\n getResourceInfoFromLogHandle(handle),\n lineCount,\n BigInt(offsetBytes ?? 0),\n searchStr,\n ),\n );\n }\n\n async readText(\n handle: sdk.AnyLogHandle,\n lineCount: number,\n offsetBytes?: number,\n searchStr?: string | undefined,\n ) {\n return await this.tryWithNotFound(handle, () =>\n this.clientLogs.readText(\n getResourceInfoFromLogHandle(handle),\n lineCount,\n BigInt(offsetBytes ?? 0),\n searchStr,\n ),\n );\n }\n\n private async tryWithNotFound(\n handle: sdk.AnyLogHandle,\n method: () => Promise<StreamingAPI_Response>,\n ): Promise<sdk.StreamingApiResponse> {\n if (!isLiveLogHandle(handle))\n throw new Error(`Not live log handle was passed to live log driver, handle: ${handle}`);\n\n try {\n const resp = await method();\n return {\n live: true,\n shouldUpdateHandle: false,\n data: resp.data,\n size: Number(resp.size),\n newOffset: Number(resp.newOffset),\n };\n } catch (e: any) {\n if (isNotFoundError(e)) {\n return { shouldUpdateHandle: true };\n }\n\n throw e;\n }\n }\n\n private async releaseLastLogs(rId: ResourceId, callerId: string) {\n const deleted = this.idToLastLines.get(rId)?.release(callerId);\n if (deleted) this.idToLastLines.delete(rId);\n }\n\n private async releaseProgressLog(rId: ResourceId, callerId: string) {\n const deleted = this.idToProgressLog.get(rId)?.release(callerId);\n if (deleted) this.idToProgressLog.delete(rId);\n }\n\n async releaseAll() {}\n\n private scheduledOnNextState: ScheduledRefresh[] = [];\n\n private scheduleOnNextState(resolve: () => void, reject: (err: any) => void): void {\n this.scheduledOnNextState.push({ resolve, reject });\n }\n\n /** Called from observer */\n private startUpdating(): void {\n this.keepRunning = true;\n if (this.currentLoop === undefined) this.currentLoop = this.mainLoop();\n }\n\n /** Called from observer */\n private stopUpdating(): void {\n this.keepRunning = false;\n }\n\n /** Stops polling loop and waits for it to finish */\n public async terminate(): Promise<void> {\n this.stopUpdating();\n if (this.currentLoop !== undefined) {\n await this.currentLoop;\n }\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.terminate();\n }\n\n /** If true, main loop will continue polling pl state. */\n private keepRunning = false;\n /** Actual state of main loop. */\n private currentLoop: Promise<void> | undefined = undefined;\n\n private async mainLoop() {\n while (this.keepRunning) {\n const toNotify = this.scheduledOnNextState;\n this.scheduledOnNextState = [];\n\n try {\n const logs = this.getAllLogs();\n await asyncPool(\n this.opts.nConcurrentGetLogs,\n logs.map((getter) => async () => await getter.update()),\n );\n\n toNotify.forEach((n) => n.resolve());\n } catch (e: any) {\n console.error(e);\n toNotify.forEach((n) => n.reject(e));\n }\n\n if (!this.keepRunning) break;\n await scheduler.wait(this.opts.pollingInterval);\n }\n\n this.currentLoop = undefined;\n }\n\n private getAllLogs(): Array<LogGetter> {\n return Array.from(this.idToLastLines.entries())\n .concat(Array.from(this.idToProgressLog.entries()))\n .map(([_, getter]) => getter);\n }\n}\n\n/** A job that gets last lines from a StreamWorkdir resource. */\nclass LogGetter {\n private logs: string | undefined;\n private error: any | undefined = undefined;\n\n private readonly change: ChangeSource = new ChangeSource();\n private readonly counter: CallersCounter = new CallersCounter();\n\n constructor(\n private readonly logger: MiLogger,\n private readonly clientLogs: ClientLogs,\n private readonly rInfo: ResourceInfo,\n private readonly lines: number,\n private readonly patternToSearch?: string,\n ) {}\n\n getLog(): {\n log: string | undefined;\n error?: any | undefined;\n } {\n return {\n log: this.logs,\n error: this.error,\n };\n }\n\n attach(w: Watcher, callerId: string) {\n this.change.attachWatcher(w);\n this.counter.inc(callerId);\n }\n\n release(callerId: string): boolean {\n return this.counter.dec(callerId);\n }\n\n async update() {\n try {\n const resp = await this.clientLogs.lastLines(\n this.rInfo,\n this.lines,\n 0n,\n this.patternToSearch,\n );\n\n const newLogs = new TextDecoder().decode(resp.data);\n if (this.logs != newLogs)\n this.change.markChanged(`logs for ${resourceIdToString(this.rInfo.id)} updated`);\n this.logs = newLogs;\n this.error = undefined;\n\n return;\n } catch (e: any) {\n if (isNotFoundError(e)) {\n // No resource\n this.logs = \"\";\n this.error = e;\n this.change.markChanged();\n return;\n }\n\n this.logger.error(\n `Stream log lines for ${stringifyWithResourceId(this.rInfo.id)} failed, reason: ${JSON.stringify(e)}`,\n );\n throw e;\n }\n }\n}\n\ntype ScheduledRefresh = {\n resolve: () => void;\n reject: (err: any) => void;\n};\n\nfunction validateResourceType(methodName: string, rType: ResourceType) {\n if (!rType.name.startsWith(\"StreamWorkdir\")) {\n throw new WrongResourceTypeError(\n `${methodName}: wrong resource type: ${rType.name}, ` +\n `expected: a resource of type 'StreamWorkdir'.`,\n );\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logs_stream.js","names":[],"sources":["../../src/drivers/logs_stream.ts"],"sourcesContent":["import type { ComputableCtx, Watcher } from \"@milaboratories/computable\";\nimport { ChangeSource, Computable, PollingComputableHooks } from \"@milaboratories/computable\";\nimport type { ResourceId, ResourceType } from \"@milaboratories/pl-client\";\nimport {\n isNotFoundError,\n resourceIdToString,\n stringifyWithResourceId,\n} from \"@milaboratories/pl-client\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\nimport { asyncPool, CallersCounter } from \"@milaboratories/ts-helpers\";\nimport type { ClientLogs } from \"../clients/logs\";\nimport { randomUUID } from \"node:crypto\";\nimport type { PlTreeEntry, ResourceInfo } from \"@milaboratories/pl-tree\";\nimport { treeEntryToResourceInfo } from \"@milaboratories/pl-tree\";\nimport { scheduler } from \"node:timers/promises\";\nimport type { StreamingAPI_Response } from \"../proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport type { PollingOps } from \"./helpers/polling_ops\";\nimport { getResourceInfoFromLogHandle, isLiveLogHandle, newLogHandle } from \"./helpers/logs_handle\";\nimport { WrongResourceTypeError } from \"./helpers/helpers\";\n\nexport type LogsStreamDriverOps = PollingOps & {\n /** Max number of concurrent requests to log streaming backend while calculating computable states */\n nConcurrentGetLogs: number;\n};\n\nexport class LogsStreamDriver implements sdk.LogsDriver {\n /** Holds a map of StreamManager Resource Id to all logs of this stream. */\n private readonly idToLastLines: Map<ResourceId, LogGetter> = new Map();\n\n /** Holds a map of StreamManager Resource Id to the last log line of this stream. */\n private readonly idToProgressLog: Map<ResourceId, LogGetter> = new Map();\n\n /** Holds a map of StreamManager Resource Id to log id smart object. */\n private readonly hooks: PollingComputableHooks;\n\n constructor(\n private readonly logger: MiLogger,\n private readonly clientLogs: ClientLogs,\n private readonly opts: LogsStreamDriverOps = {\n nConcurrentGetLogs: 10,\n pollingInterval: 1000,\n stopPollingDelay: 1000,\n },\n ) {\n this.hooks = new PollingComputableHooks(\n () => this.startUpdating(),\n () => this.stopUpdating(),\n { stopDebounce: opts.stopPollingDelay },\n (resolve, reject) => this.scheduleOnNextState(resolve, reject),\n );\n }\n\n getLastLogs(res: ResourceInfo | PlTreeEntry, lines: number): Computable<string | undefined>;\n getLastLogs(\n res: ResourceInfo | PlTreeEntry,\n lines: number,\n ctx: ComputableCtx,\n ): Computable<string | undefined>;\n getLastLogs(\n res: ResourceInfo | PlTreeEntry,\n lines: number,\n ctx?: ComputableCtx,\n ): Computable<string | undefined> | string | undefined {\n if (ctx == undefined) return Computable.make((ctx) => this.getLastLogs(res, lines, ctx));\n\n const r = treeEntryToResourceInfo(res, ctx);\n const callerId = randomUUID();\n ctx.attacheHooks(this.hooks);\n ctx.addOnDestroy(() => this.releaseLastLogs(r.id, callerId));\n\n const result = this.getLastLogsNoCtx(ctx.watcher, r, lines, callerId);\n ctx.markUnstable(\n \"The logs are from stream, so we consider them unstable. Final values will be got from blobs.\",\n );\n\n return result;\n }\n\n private getLastLogsNoCtx(\n w: Watcher,\n rInfo: ResourceInfo,\n lines: number,\n callerId: string,\n ): string | undefined {\n validateResourceType(\"getLastLogs\", rInfo.type);\n\n let logGetter = this.idToLastLines.get(rInfo.id);\n\n if (logGetter == undefined) {\n const newLogGetter = new LogGetter(this.logger, this.clientLogs, rInfo, lines);\n this.idToLastLines.set(rInfo.id, newLogGetter);\n\n logGetter = newLogGetter;\n }\n\n logGetter.attach(w, callerId);\n const result = logGetter.getLog();\n if (result.error != undefined) throw result.error;\n\n return result.log;\n }\n\n /** Returns a last line that has patternToSearch.\n * Notifies when a new line appeared or EOF reached. */\n getProgressLog(\n res: ResourceInfo | PlTreeEntry,\n patternToSearch: string,\n ): Computable<string | undefined>;\n getProgressLog(\n res: ResourceInfo | PlTreeEntry,\n patternToSearch: string,\n ctx: ComputableCtx,\n ): string | undefined;\n getProgressLog(\n res: ResourceInfo | PlTreeEntry,\n patternToSearch: string,\n ctx?: ComputableCtx,\n ): Computable<string | undefined> | string | undefined {\n if (ctx == undefined)\n return Computable.make((ctx) => this.getProgressLog(res, patternToSearch, ctx));\n\n const r = treeEntryToResourceInfo(res, ctx);\n const callerId = randomUUID();\n ctx.attacheHooks(this.hooks);\n ctx.addOnDestroy(() => this.releaseProgressLog(r.id, callerId));\n\n const result = this.getProgressLogNoCtx(ctx.watcher, r, patternToSearch, callerId);\n ctx.markUnstable(\n \"The progress log is from the stream, so we consider it unstable. Final value will be got from blobs.\",\n );\n\n return result;\n }\n\n private getProgressLogNoCtx(\n w: Watcher,\n rInfo: ResourceInfo,\n patternToSearch: string,\n callerId: string,\n ): string | undefined {\n validateResourceType(\"getProgressLog\", rInfo.type);\n\n let logGetter = this.idToProgressLog.get(rInfo.id);\n\n if (logGetter == undefined) {\n const newLogGetter = new LogGetter(this.logger, this.clientLogs, rInfo, 1, patternToSearch);\n this.idToProgressLog.set(rInfo.id, newLogGetter);\n\n logGetter = newLogGetter;\n }\n\n logGetter.attach(w, callerId);\n const result = logGetter.getLog();\n if (result.error) throw result.error;\n\n return result.log;\n }\n\n getLogHandle(res: ResourceInfo | PlTreeEntry): Computable<sdk.AnyLogHandle>;\n getLogHandle(res: ResourceInfo | PlTreeEntry, ctx: ComputableCtx): sdk.AnyLogHandle;\n getLogHandle(\n res: ResourceInfo | PlTreeEntry,\n ctx?: ComputableCtx,\n ): Computable<sdk.AnyLogHandle> | sdk.AnyLogHandle {\n if (ctx == undefined) return Computable.make((ctx) => this.getLogHandle(res, ctx));\n\n const r = treeEntryToResourceInfo(res, ctx);\n\n const result = this.getLogHandleNoCtx(r);\n\n // All logs from streams should be considered unstable,\n // final value will be got from blobs.\n ctx.markUnstable(`live_log:${resourceIdToString(r.id)}`);\n\n return result;\n }\n\n private getLogHandleNoCtx(rInfo: ResourceInfo): sdk.AnyLogHandle {\n validateResourceType(\"getLogHandle\", rInfo.type);\n\n return newLogHandle(true, rInfo);\n }\n\n async lastLines(\n handle: sdk.AnyLogHandle,\n lineCount: number,\n offsetBytes?: number,\n searchStr?: string | undefined,\n ) {\n return await this.tryWithNotFound(handle, () =>\n this.clientLogs.lastLines(\n getResourceInfoFromLogHandle(handle),\n lineCount,\n BigInt(offsetBytes ?? 0),\n searchStr,\n ),\n );\n }\n\n async readText(\n handle: sdk.AnyLogHandle,\n lineCount: number,\n offsetBytes?: number,\n searchStr?: string | undefined,\n ) {\n return await this.tryWithNotFound(handle, () =>\n this.clientLogs.readText(\n getResourceInfoFromLogHandle(handle),\n lineCount,\n BigInt(offsetBytes ?? 0),\n searchStr,\n ),\n );\n }\n\n private async tryWithNotFound(\n handle: sdk.AnyLogHandle,\n method: () => Promise<StreamingAPI_Response>,\n ): Promise<sdk.StreamingApiResponse> {\n if (!isLiveLogHandle(handle))\n throw new Error(`Not live log handle was passed to live log driver, handle: ${handle}`);\n\n try {\n const resp = await method();\n return {\n live: true,\n shouldUpdateHandle: false,\n data: resp.data,\n size: Number(resp.size),\n newOffset: Number(resp.newOffset),\n };\n } catch (e: any) {\n if (isNotFoundError(e)) {\n return { shouldUpdateHandle: true };\n }\n\n throw e;\n }\n }\n\n private async releaseLastLogs(rId: ResourceId, callerId: string) {\n const deleted = this.idToLastLines.get(rId)?.release(callerId);\n if (deleted) this.idToLastLines.delete(rId);\n }\n\n private async releaseProgressLog(rId: ResourceId, callerId: string) {\n const deleted = this.idToProgressLog.get(rId)?.release(callerId);\n if (deleted) this.idToProgressLog.delete(rId);\n }\n\n async releaseAll() {}\n\n private scheduledOnNextState: ScheduledRefresh[] = [];\n\n private scheduleOnNextState(resolve: () => void, reject: (err: any) => void): void {\n this.scheduledOnNextState.push({ resolve, reject });\n }\n\n /** Called from observer */\n private startUpdating(): void {\n this.keepRunning = true;\n if (this.currentLoop === undefined) this.currentLoop = this.mainLoop();\n }\n\n /** Called from observer */\n private stopUpdating(): void {\n this.keepRunning = false;\n }\n\n /** Stops polling loop and waits for it to finish */\n public async terminate(): Promise<void> {\n this.stopUpdating();\n if (this.currentLoop !== undefined) {\n await this.currentLoop;\n }\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.terminate();\n }\n\n /** If true, main loop will continue polling pl state. */\n private keepRunning = false;\n /** Actual state of main loop. */\n private currentLoop: Promise<void> | undefined = undefined;\n\n private async mainLoop() {\n while (this.keepRunning) {\n const toNotify = this.scheduledOnNextState;\n this.scheduledOnNextState = [];\n\n try {\n const logs = this.getAllLogs();\n await asyncPool(\n this.opts.nConcurrentGetLogs,\n logs.map((getter) => async () => await getter.update()),\n );\n\n toNotify.forEach((n) => n.resolve());\n } catch (e: any) {\n console.error(e);\n toNotify.forEach((n) => n.reject(e));\n }\n\n if (!this.keepRunning) break;\n await scheduler.wait(this.opts.pollingInterval);\n }\n\n this.currentLoop = undefined;\n }\n\n private getAllLogs(): Array<LogGetter> {\n return Array.from(this.idToLastLines.entries())\n .concat(Array.from(this.idToProgressLog.entries()))\n .map(([_, getter]) => getter);\n }\n}\n\n/** A job that gets last lines from a StreamWorkdir resource. */\nclass LogGetter {\n private logs: string | undefined;\n private error: any | undefined = undefined;\n\n private readonly change: ChangeSource = new ChangeSource();\n private readonly counter: CallersCounter = new CallersCounter();\n\n constructor(\n private readonly logger: MiLogger,\n private readonly clientLogs: ClientLogs,\n private readonly rInfo: ResourceInfo,\n private readonly lines: number,\n private readonly patternToSearch?: string,\n ) {}\n\n getLog(): {\n log: string | undefined;\n error?: any | undefined;\n } {\n return {\n log: this.logs,\n error: this.error,\n };\n }\n\n attach(w: Watcher, callerId: string) {\n this.change.attachWatcher(w);\n this.counter.inc(callerId);\n }\n\n release(callerId: string): boolean {\n return this.counter.dec(callerId);\n }\n\n async update() {\n try {\n const resp = await this.clientLogs.lastLines(\n this.rInfo,\n this.lines,\n 0n,\n this.patternToSearch,\n );\n\n const newLogs = new TextDecoder().decode(resp.data);\n if (this.logs != newLogs)\n this.change.markChanged(`logs for ${resourceIdToString(this.rInfo.id)} updated`);\n this.logs = newLogs;\n this.error = undefined;\n\n return;\n } catch (e: any) {\n if (isNotFoundError(e)) {\n // No resource\n this.logs = \"\";\n this.error = e;\n this.change.markChanged();\n return;\n }\n\n this.logger.error(\n `Stream log lines for ${stringifyWithResourceId(this.rInfo.id)} failed, reason: ${JSON.stringify(e)}`,\n );\n throw e;\n }\n }\n}\n\ntype ScheduledRefresh = {\n resolve: () => void;\n reject: (err: any) => void;\n};\n\nfunction validateResourceType(methodName: string, rType: ResourceType) {\n if (!rType.name.startsWith(\"StreamWorkdir\")) {\n throw new WrongResourceTypeError(\n `${methodName}: wrong resource type: ${rType.name}, ` +\n `expected: a resource of type 'StreamWorkdir'.`,\n );\n }\n}\n"],"mappings":"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"}
|
package/dist/drivers/ls.cjs
CHANGED
|
@@ -1,245 +1,158 @@
|
|
|
1
|
-
|
|
1
|
+
const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_validate = require('../helpers/validate.cjs');
|
|
3
|
+
const require_constructors = require('../clients/constructors.cjs');
|
|
4
|
+
const require_ls_remote_import_handle = require('./helpers/ls_remote_import_handle.cjs');
|
|
5
|
+
const require_ls_storage_entry = require('./helpers/ls_storage_entry.cjs');
|
|
6
|
+
const require_virtual_storages = require('./virtual_storages.cjs');
|
|
7
|
+
let _milaboratories_pl_client = require("@milaboratories/pl-client");
|
|
8
|
+
let node_fs_promises = require("node:fs/promises");
|
|
9
|
+
node_fs_promises = require_runtime.__toESM(node_fs_promises);
|
|
10
|
+
let node_path = require("node:path");
|
|
11
|
+
node_path = require_runtime.__toESM(node_path);
|
|
12
|
+
let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
|
|
2
13
|
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
async getStorageList() {
|
|
136
|
-
const virtualStorages = [...this.virtualStoragesMap.values()].map((s) => ({
|
|
137
|
-
name: s.name,
|
|
138
|
-
handle: ls_storage_entry.createLocalStorageHandle(s.name, s.root),
|
|
139
|
-
initialFullPath: s.initialPath,
|
|
140
|
-
}));
|
|
141
|
-
const otherStorages = Object.entries(this.storageIdToResourceId).map(([storageId, resourceId]) => ({
|
|
142
|
-
name: storageId,
|
|
143
|
-
handle: ls_storage_entry.createRemoteStorageHandle(storageId, resourceId),
|
|
144
|
-
initialFullPath: "", // we don't have any additional information from where to start browsing remote storages
|
|
145
|
-
isInitialPathHome: false,
|
|
146
|
-
}));
|
|
147
|
-
// root must be a storage so we can index any file,
|
|
148
|
-
// but for UI it's enough
|
|
149
|
-
// to have local virtual storage on *nix,
|
|
150
|
-
// and local_disk_${drive} on Windows.
|
|
151
|
-
const noRoot = otherStorages.filter((it) => it.name !== "root");
|
|
152
|
-
return [...virtualStorages, ...noRoot];
|
|
153
|
-
}
|
|
154
|
-
async listFiles(storageHandle, fullPath) {
|
|
155
|
-
const storageData = ls_storage_entry.parseStorageHandle(storageHandle);
|
|
156
|
-
if (storageData.isRemote) {
|
|
157
|
-
const response = await this.lsClient.list(storageData, fullPath);
|
|
158
|
-
return {
|
|
159
|
-
entries: response.items.map((e) => ({
|
|
160
|
-
type: e.isDir ? "dir" : "file",
|
|
161
|
-
name: e.name,
|
|
162
|
-
fullPath: e.fullName,
|
|
163
|
-
handle: ls_remote_import_handle.createIndexImportHandle(storageData.name, e.fullName),
|
|
164
|
-
})),
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
if (path__namespace.sep === "/" && fullPath === "")
|
|
168
|
-
fullPath = "/";
|
|
169
|
-
if (storageData.rootPath === "") {
|
|
170
|
-
validate.validateAbsolute(fullPath);
|
|
171
|
-
}
|
|
172
|
-
const lsRoot = path__namespace.isAbsolute(fullPath) ? fullPath : path__namespace.join(storageData.rootPath, fullPath);
|
|
173
|
-
const entries = [];
|
|
174
|
-
for await (const dirent of await fsp__namespace.opendir(lsRoot)) {
|
|
175
|
-
if (!dirent.isFile() && !dirent.isDirectory())
|
|
176
|
-
continue;
|
|
177
|
-
// We cannot use no dirent.fullPath no dirent.parentPath,
|
|
178
|
-
// since the former is deprecated
|
|
179
|
-
// and the later works differently on different versions.
|
|
180
|
-
const absolutePath = path__namespace.join(lsRoot, dirent.name);
|
|
181
|
-
entries.push({
|
|
182
|
-
type: dirent.isFile() ? "file" : "dir",
|
|
183
|
-
name: dirent.name,
|
|
184
|
-
fullPath: absolutePath,
|
|
185
|
-
handle: await this.getLocalFileHandle(absolutePath),
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
return { entries };
|
|
189
|
-
}
|
|
190
|
-
async listRemoteFilesWithAdditionalInfo(storageHandle, fullPath) {
|
|
191
|
-
const storageData = ls_storage_entry.parseStorageHandle(storageHandle);
|
|
192
|
-
if (!storageData.isRemote) {
|
|
193
|
-
throw new Error(`Storage ${storageData.name} is not remote`);
|
|
194
|
-
}
|
|
195
|
-
const response = await this.lsClient.list(storageData, fullPath);
|
|
196
|
-
return {
|
|
197
|
-
entries: response.items.map((e) => ({
|
|
198
|
-
type: e.isDir ? "dir" : "file",
|
|
199
|
-
name: e.name,
|
|
200
|
-
fullPath: e.fullName,
|
|
201
|
-
handle: ls_remote_import_handle.createIndexImportHandle(storageData.name, e.fullName),
|
|
202
|
-
size: Number(e.size),
|
|
203
|
-
})),
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
async fileToImportHandle(_file) {
|
|
207
|
-
throw new Error("Not implemented. This method must be implemented and intercepted in desktop preload script.");
|
|
208
|
-
}
|
|
209
|
-
static async init(logger, client, signer,
|
|
210
|
-
/** Pl storages available locally */
|
|
211
|
-
localProjections, openFileDialogCallback, virtualStorages) {
|
|
212
|
-
const lsClient = constructors.createLsFilesClient(client, logger);
|
|
213
|
-
if (!virtualStorages)
|
|
214
|
-
virtualStorages = await virtual_storages.DefaultVirtualLocalStorages();
|
|
215
|
-
// validating inputs
|
|
216
|
-
for (const vp of virtualStorages)
|
|
217
|
-
validate.validateAbsolute(vp.root);
|
|
218
|
-
for (const lp of localProjections)
|
|
219
|
-
if (lp.localPath !== "")
|
|
220
|
-
validate.validateAbsolute(lp.localPath);
|
|
221
|
-
// creating indexed maps for quick access
|
|
222
|
-
const virtualStoragesMap = new Map(virtualStorages.map((s) => [s.name, s]));
|
|
223
|
-
const localProjectionsMap = new Map(localProjections.map((s) => [s.storageId, s]));
|
|
224
|
-
// validating there is no intersection
|
|
225
|
-
if (new Set([...virtualStoragesMap.keys(), ...localProjectionsMap.keys()]).size !==
|
|
226
|
-
virtualStoragesMap.size + localProjectionsMap.size)
|
|
227
|
-
throw new Error("Intersection between local projection storage ids and virtual storages names detected.");
|
|
228
|
-
return new LsDriver(logger, lsClient, await doGetAvailableStorageIds(client), signer, virtualStoragesMap, localProjectionsMap, openFileDialogCallback);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
14
|
+
//#region src/drivers/ls.ts
|
|
15
|
+
var LsDriver = class LsDriver {
|
|
16
|
+
constructor(logger, lsClient, storageIdToResourceId, signer, virtualStoragesMap, localProjectionsMap, openFileDialogCallback) {
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.lsClient = lsClient;
|
|
19
|
+
this.storageIdToResourceId = storageIdToResourceId;
|
|
20
|
+
this.signer = signer;
|
|
21
|
+
this.virtualStoragesMap = virtualStoragesMap;
|
|
22
|
+
this.localProjectionsMap = localProjectionsMap;
|
|
23
|
+
this.openFileDialogCallback = openFileDialogCallback;
|
|
24
|
+
}
|
|
25
|
+
async getLocalFileContent(file, range) {
|
|
26
|
+
const localPath = await this.tryResolveLocalFileHandle(file);
|
|
27
|
+
if (range) {
|
|
28
|
+
const fileHandle = await node_fs_promises.open(localPath, "r");
|
|
29
|
+
try {
|
|
30
|
+
const buffer = Buffer.alloc(range.length);
|
|
31
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, range.length, range.offset);
|
|
32
|
+
return new Uint8Array(buffer.subarray(0, bytesRead));
|
|
33
|
+
} finally {
|
|
34
|
+
await fileHandle.close();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return await node_fs_promises.readFile(localPath);
|
|
38
|
+
}
|
|
39
|
+
async getLocalFileSize(file) {
|
|
40
|
+
const localPath = await this.tryResolveLocalFileHandle(file);
|
|
41
|
+
return (await node_fs_promises.stat(localPath)).size;
|
|
42
|
+
}
|
|
43
|
+
async showOpenMultipleFilesDialog(ops) {
|
|
44
|
+
const result = await this.openFileDialogCallback(true, ops);
|
|
45
|
+
if (result === void 0) return {};
|
|
46
|
+
return { files: await Promise.all(result.map((localPath) => this.getLocalFileHandle(localPath))) };
|
|
47
|
+
}
|
|
48
|
+
async showOpenSingleFileDialog(ops) {
|
|
49
|
+
const result = await this.openFileDialogCallback(false, ops);
|
|
50
|
+
if (result === void 0) return {};
|
|
51
|
+
return { file: await this.getLocalFileHandle(result[0]) };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Resolves local handle to local file path.
|
|
55
|
+
*
|
|
56
|
+
* @param handle handle to be resolved
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
async tryResolveLocalFileHandle(handle) {
|
|
60
|
+
if ((0, _milaboratories_pl_model_common.isImportFileHandleIndex)(handle)) {
|
|
61
|
+
const handleData = require_ls_remote_import_handle.parseIndexHandle(handle);
|
|
62
|
+
const localProjection = this.localProjectionsMap.get(handleData.storageId);
|
|
63
|
+
if (!localProjection) throw new Error(`Storage ${handleData.storageId} is not mounted locally.`);
|
|
64
|
+
return node_path.join(localProjection.localPath, handleData.path);
|
|
65
|
+
} else {
|
|
66
|
+
const handleData = require_ls_remote_import_handle.parseUploadHandle(handle);
|
|
67
|
+
this.signer.verify(handleData.localPath, handleData.pathSignature, "Failed to validate local file handle signature.");
|
|
68
|
+
const localPath = handleData.localPath;
|
|
69
|
+
const stat = await node_fs_promises.stat(localPath, { bigint: true });
|
|
70
|
+
if (String(stat.mtimeMs / 1000n) !== handleData.modificationTime) throw new Error("File has changed since the handle was created.");
|
|
71
|
+
return localPath;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async getLocalFileHandle(localPath) {
|
|
75
|
+
require_validate.validateAbsolute(localPath);
|
|
76
|
+
for (const lp of this.localProjectionsMap.values()) if (localPath.startsWith(lp.localPath)) {
|
|
77
|
+
const pathWithinStorage = lp.localPath === "" ? localPath : node_path.relative(lp.localPath, localPath);
|
|
78
|
+
return require_ls_remote_import_handle.createIndexImportHandle(lp.storageId, pathWithinStorage);
|
|
79
|
+
}
|
|
80
|
+
const stat = await node_fs_promises.stat(localPath, { bigint: true });
|
|
81
|
+
return require_ls_remote_import_handle.createUploadImportHandle(localPath, this.signer, stat.size, stat.mtimeMs / 1000n);
|
|
82
|
+
}
|
|
83
|
+
async getStorageList() {
|
|
84
|
+
const virtualStorages = [...this.virtualStoragesMap.values()].map((s) => ({
|
|
85
|
+
name: s.name,
|
|
86
|
+
handle: require_ls_storage_entry.createLocalStorageHandle(s.name, s.root),
|
|
87
|
+
initialFullPath: s.initialPath
|
|
88
|
+
}));
|
|
89
|
+
const noRoot = Object.entries(this.storageIdToResourceId).map(([storageId, resourceId]) => ({
|
|
90
|
+
name: storageId,
|
|
91
|
+
handle: require_ls_storage_entry.createRemoteStorageHandle(storageId, resourceId),
|
|
92
|
+
initialFullPath: "",
|
|
93
|
+
isInitialPathHome: false
|
|
94
|
+
})).filter((it) => it.name !== "root");
|
|
95
|
+
return [...virtualStorages, ...noRoot];
|
|
96
|
+
}
|
|
97
|
+
async listFiles(storageHandle, fullPath) {
|
|
98
|
+
const storageData = require_ls_storage_entry.parseStorageHandle(storageHandle);
|
|
99
|
+
if (storageData.isRemote) return { entries: (await this.lsClient.list(storageData, fullPath)).items.map((e) => ({
|
|
100
|
+
type: e.isDir ? "dir" : "file",
|
|
101
|
+
name: e.name,
|
|
102
|
+
fullPath: e.fullName,
|
|
103
|
+
handle: require_ls_remote_import_handle.createIndexImportHandle(storageData.name, e.fullName)
|
|
104
|
+
})) };
|
|
105
|
+
if (node_path.sep === "/" && fullPath === "") fullPath = "/";
|
|
106
|
+
if (storageData.rootPath === "") require_validate.validateAbsolute(fullPath);
|
|
107
|
+
const lsRoot = node_path.isAbsolute(fullPath) ? fullPath : node_path.join(storageData.rootPath, fullPath);
|
|
108
|
+
const entries = [];
|
|
109
|
+
for await (const dirent of await node_fs_promises.opendir(lsRoot)) {
|
|
110
|
+
if (!dirent.isFile() && !dirent.isDirectory()) continue;
|
|
111
|
+
const absolutePath = node_path.join(lsRoot, dirent.name);
|
|
112
|
+
entries.push({
|
|
113
|
+
type: dirent.isFile() ? "file" : "dir",
|
|
114
|
+
name: dirent.name,
|
|
115
|
+
fullPath: absolutePath,
|
|
116
|
+
handle: await this.getLocalFileHandle(absolutePath)
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return { entries };
|
|
120
|
+
}
|
|
121
|
+
async listRemoteFilesWithAdditionalInfo(storageHandle, fullPath) {
|
|
122
|
+
const storageData = require_ls_storage_entry.parseStorageHandle(storageHandle);
|
|
123
|
+
if (!storageData.isRemote) throw new Error(`Storage ${storageData.name} is not remote`);
|
|
124
|
+
return { entries: (await this.lsClient.list(storageData, fullPath)).items.map((e) => ({
|
|
125
|
+
type: e.isDir ? "dir" : "file",
|
|
126
|
+
name: e.name,
|
|
127
|
+
fullPath: e.fullName,
|
|
128
|
+
handle: require_ls_remote_import_handle.createIndexImportHandle(storageData.name, e.fullName),
|
|
129
|
+
size: Number(e.size)
|
|
130
|
+
})) };
|
|
131
|
+
}
|
|
132
|
+
async fileToImportHandle(_file) {
|
|
133
|
+
throw new Error("Not implemented. This method must be implemented and intercepted in desktop preload script.");
|
|
134
|
+
}
|
|
135
|
+
static async init(logger, client, signer, localProjections, openFileDialogCallback, virtualStorages) {
|
|
136
|
+
const lsClient = require_constructors.createLsFilesClient(client, logger);
|
|
137
|
+
if (!virtualStorages) virtualStorages = await require_virtual_storages.DefaultVirtualLocalStorages();
|
|
138
|
+
for (const vp of virtualStorages) require_validate.validateAbsolute(vp.root);
|
|
139
|
+
for (const lp of localProjections) if (lp.localPath !== "") require_validate.validateAbsolute(lp.localPath);
|
|
140
|
+
const virtualStoragesMap = new Map(virtualStorages.map((s) => [s.name, s]));
|
|
141
|
+
const localProjectionsMap = new Map(localProjections.map((s) => [s.storageId, s]));
|
|
142
|
+
if (new Set([...virtualStoragesMap.keys(), ...localProjectionsMap.keys()]).size !== virtualStoragesMap.size + localProjectionsMap.size) throw new Error("Intersection between local projection storage ids and virtual storages names detected.");
|
|
143
|
+
return new LsDriver(logger, lsClient, await doGetAvailableStorageIds(client), signer, virtualStoragesMap, localProjectionsMap, openFileDialogCallback);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
231
146
|
async function doGetAvailableStorageIds(client) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
});
|
|
147
|
+
return client.withReadTx("GetAvailableStorageIds", async (tx) => {
|
|
148
|
+
const lsProviderId = await tx.getResourceByName("LSProvider");
|
|
149
|
+
return providerToStorageIds(await tx.getResourceData(lsProviderId, true));
|
|
150
|
+
});
|
|
237
151
|
}
|
|
238
152
|
function providerToStorageIds(provider) {
|
|
239
|
-
|
|
240
|
-
.filter((f) => f.type == "Dynamic" && plClient.isNotNullResourceId(f.value))
|
|
241
|
-
.map((f) => [f.name.substring("storage/".length), f.value]));
|
|
153
|
+
return Object.fromEntries(provider.fields.filter((f) => f.type == "Dynamic" && (0, _milaboratories_pl_client.isNotNullResourceId)(f.value)).map((f) => [f.name.substring(8), f.value]));
|
|
242
154
|
}
|
|
243
155
|
|
|
156
|
+
//#endregion
|
|
244
157
|
exports.LsDriver = LsDriver;
|
|
245
|
-
//# sourceMappingURL=ls.cjs.map
|
|
158
|
+
//# sourceMappingURL=ls.cjs.map
|
package/dist/drivers/ls.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ls.cjs","sources":["../../src/drivers/ls.ts"],"sourcesContent":["import type { PlClient, ResourceData, ResourceId } from \"@milaboratories/pl-client\";\nimport { isNotNullResourceId } from \"@milaboratories/pl-client\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport type {\n LocalImportFileHandle,\n LsEntry,\n OpenDialogOps,\n OpenMultipleFilesResponse,\n OpenSingleFileResponse,\n TableRange,\n} from \"@milaboratories/pl-model-common\";\nimport { isImportFileHandleIndex } from \"@milaboratories/pl-model-common\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { createLsFilesClient } from \"../clients/constructors\";\nimport type { ClientLs } from \"../clients/ls_api\";\nimport { validateAbsolute } from \"../helpers/validate\";\nimport {\n createIndexImportHandle,\n createUploadImportHandle,\n parseIndexHandle,\n parseUploadHandle,\n} from \"./helpers/ls_remote_import_handle\";\nimport {\n createLocalStorageHandle,\n createRemoteStorageHandle,\n parseStorageHandle,\n} from \"./helpers/ls_storage_entry\";\nimport type { LocalStorageProjection, VirtualLocalStorageSpec } from \"./types\";\nimport { DefaultVirtualLocalStorages } from \"./virtual_storages\";\n\n/**\n * Extends public and safe SDK's driver API with methods used internally in the middle\n * layer and in tests.\n */\nexport interface InternalLsDriver extends sdk.LsDriver {\n /**\n * Given local path, generates well-structured and signed upload handle.\n * To be used in tests and in implementation of the native file selection UI API.\n * */\n getLocalFileHandle(localPath: string): Promise<sdk.LocalImportFileHandle>;\n\n listRemoteFilesWithAdditionalInfo(\n storage: sdk.StorageHandle,\n fullPath: string,\n ): Promise<ListRemoteFilesResultWithAdditionalInfo>;\n}\n\nexport type ListRemoteFilesResultWithAdditionalInfo = {\n parent?: string;\n entries: LsEntryWithAdditionalInfo[];\n};\n\nexport type LsEntryWithAdditionalInfo = LsEntry & {\n size: number;\n};\n\nexport type OpenFileDialogCallback = (\n multipleFiles: boolean,\n ops?: OpenDialogOps,\n) => Promise<undefined | string[]>;\n\nexport class LsDriver implements InternalLsDriver {\n private constructor(\n private readonly logger: MiLogger,\n private readonly lsClient: ClientLs,\n /** Pl storage id, to resource id. The resource id can be used to make LS GRPC calls to. */\n private readonly storageIdToResourceId: Record<string, ResourceId>,\n private readonly signer: Signer,\n /** Virtual storages by name */\n private readonly virtualStoragesMap: Map<string, VirtualLocalStorageSpec>,\n /** Local projections by storageId */\n private readonly localProjectionsMap: Map<string, LocalStorageProjection>,\n private readonly openFileDialogCallback: OpenFileDialogCallback,\n ) {}\n\n public async getLocalFileContent(\n file: LocalImportFileHandle,\n range?: TableRange,\n ): Promise<Uint8Array> {\n const localPath = await this.tryResolveLocalFileHandle(file);\n\n if (range) {\n const fileHandle = await fsp.open(localPath, \"r\");\n try {\n const buffer = Buffer.alloc(range.length);\n const { bytesRead } = await fileHandle.read(buffer, 0, range.length, range.offset);\n return new Uint8Array(buffer.subarray(0, bytesRead));\n } finally {\n await fileHandle.close();\n }\n }\n\n return await fsp.readFile(localPath);\n }\n\n public async getLocalFileSize(file: LocalImportFileHandle): Promise<number> {\n const localPath = await this.tryResolveLocalFileHandle(file);\n const stat = await fsp.stat(localPath);\n return stat.size;\n }\n\n public async showOpenMultipleFilesDialog(\n ops?: OpenDialogOps,\n ): Promise<OpenMultipleFilesResponse> {\n const result = await this.openFileDialogCallback(true, ops);\n if (result === undefined) return {};\n return {\n files: await Promise.all(result.map((localPath) => this.getLocalFileHandle(localPath))),\n };\n }\n\n public async showOpenSingleFileDialog(ops?: OpenDialogOps): Promise<OpenSingleFileResponse> {\n const result = await this.openFileDialogCallback(false, ops);\n if (result === undefined) return {};\n return {\n file: await this.getLocalFileHandle(result[0]),\n };\n }\n\n /**\n * Resolves local handle to local file path.\n *\n * @param handle handle to be resolved\n * @private\n */\n private async tryResolveLocalFileHandle(handle: LocalImportFileHandle): Promise<string> {\n if (isImportFileHandleIndex(handle)) {\n const handleData = parseIndexHandle(handle);\n const localProjection = this.localProjectionsMap.get(handleData.storageId);\n if (!localProjection)\n throw new Error(`Storage ${handleData.storageId} is not mounted locally.`);\n return path.join(localProjection.localPath, handleData.path);\n } else {\n const handleData = parseUploadHandle(handle);\n // checking it is a valid local handle from out machine\n this.signer.verify(\n handleData.localPath,\n handleData.pathSignature,\n \"Failed to validate local file handle signature.\",\n );\n\n const localPath = handleData.localPath;\n\n const stat = await fsp.stat(localPath, { bigint: true });\n if (String(stat.mtimeMs / 1000n) !== handleData.modificationTime)\n throw new Error(\"File has changed since the handle was created.\");\n\n return localPath;\n }\n }\n\n public async getLocalFileHandle(\n localPath: string,\n ): Promise<sdk.ImportFileHandle & LocalImportFileHandle> {\n validateAbsolute(localPath);\n\n // Checking if local path is directly reachable by pl, because it is in one of the\n // locally mounted storages\n for (const lp of this.localProjectionsMap.values()) {\n // note: empty lp.localPath will match any address\n if (localPath.startsWith(lp.localPath)) {\n // Just in case:\n // > path.relative(\"/a/b\", \"/a/b/c\");\n // 'c'\n const pathWithinStorage =\n lp.localPath === \"\" ? localPath : path.relative(lp.localPath, localPath);\n return createIndexImportHandle(\n lp.storageId,\n pathWithinStorage,\n ) as sdk.ImportFileHandleIndex & LocalImportFileHandle;\n }\n }\n\n // we get here if none of the local projections matched the path\n\n const stat = await fsp.stat(localPath, { bigint: true });\n return createUploadImportHandle(\n localPath,\n this.signer,\n stat.size,\n stat.mtimeMs / 1000n, // integer division\n ) as sdk.ImportFileHandleUpload & LocalImportFileHandle;\n }\n\n public async getStorageList(): Promise<sdk.StorageEntry[]> {\n const virtualStorages = [...this.virtualStoragesMap.values()].map((s) => ({\n name: s.name,\n handle: createLocalStorageHandle(s.name, s.root),\n initialFullPath: s.initialPath,\n }));\n\n const otherStorages = Object.entries(this.storageIdToResourceId!).map(\n ([storageId, resourceId]) => ({\n name: storageId,\n handle: createRemoteStorageHandle(storageId, resourceId),\n initialFullPath: \"\", // we don't have any additional information from where to start browsing remote storages\n isInitialPathHome: false,\n }),\n );\n\n // root must be a storage so we can index any file,\n // but for UI it's enough\n // to have local virtual storage on *nix,\n // and local_disk_${drive} on Windows.\n const noRoot = otherStorages.filter((it) => it.name !== \"root\");\n\n return [...virtualStorages, ...noRoot];\n }\n\n public async listFiles(\n storageHandle: sdk.StorageHandle,\n fullPath: string,\n ): Promise<sdk.ListFilesResult> {\n const storageData = parseStorageHandle(storageHandle);\n\n if (storageData.isRemote) {\n const response = await this.lsClient.list(storageData, fullPath);\n return {\n entries: response.items.map((e) => ({\n type: e.isDir ? \"dir\" : \"file\",\n name: e.name,\n fullPath: e.fullName,\n handle: createIndexImportHandle(storageData.name, e.fullName),\n })),\n };\n }\n\n if (path.sep === \"/\" && fullPath === \"\") fullPath = \"/\";\n\n if (storageData.rootPath === \"\") {\n validateAbsolute(fullPath);\n }\n const lsRoot = path.isAbsolute(fullPath) ? fullPath : path.join(storageData.rootPath, fullPath);\n\n const entries: LsEntry[] = [];\n for await (const dirent of await fsp.opendir(lsRoot)) {\n if (!dirent.isFile() && !dirent.isDirectory()) continue;\n\n // We cannot use no dirent.fullPath no dirent.parentPath,\n // since the former is deprecated\n // and the later works differently on different versions.\n const absolutePath = path.join(lsRoot, dirent.name);\n\n entries.push({\n type: dirent.isFile() ? \"file\" : \"dir\",\n name: dirent.name,\n fullPath: absolutePath,\n handle: await this.getLocalFileHandle(absolutePath),\n });\n }\n\n return { entries };\n }\n\n public async listRemoteFilesWithAdditionalInfo(\n storageHandle: sdk.StorageHandle,\n fullPath: string,\n ): Promise<ListRemoteFilesResultWithAdditionalInfo> {\n const storageData = parseStorageHandle(storageHandle);\n if (!storageData.isRemote) {\n throw new Error(`Storage ${storageData.name} is not remote`);\n }\n\n const response = await this.lsClient.list(storageData, fullPath);\n\n return {\n entries: response.items.map((e) => ({\n type: e.isDir ? \"dir\" : \"file\",\n name: e.name,\n fullPath: e.fullName,\n handle: createIndexImportHandle(storageData.name, e.fullName),\n size: Number(e.size),\n })),\n };\n }\n\n public async fileToImportHandle(_file: sdk.FileLike): Promise<sdk.ImportFileHandle> {\n throw new Error(\n \"Not implemented. This method must be implemented and intercepted in desktop preload script.\",\n );\n }\n\n public static async init(\n logger: MiLogger,\n client: PlClient,\n signer: Signer,\n /** Pl storages available locally */\n localProjections: LocalStorageProjection[],\n openFileDialogCallback: OpenFileDialogCallback,\n virtualStorages?: VirtualLocalStorageSpec[],\n ): Promise<LsDriver> {\n const lsClient = createLsFilesClient(client, logger);\n\n if (!virtualStorages) virtualStorages = await DefaultVirtualLocalStorages();\n\n // validating inputs\n for (const vp of virtualStorages) validateAbsolute(vp.root);\n for (const lp of localProjections) if (lp.localPath !== \"\") validateAbsolute(lp.localPath);\n\n // creating indexed maps for quick access\n const virtualStoragesMap = new Map(virtualStorages.map((s) => [s.name, s]));\n const localProjectionsMap = new Map(localProjections.map((s) => [s.storageId, s]));\n\n // validating there is no intersection\n if (\n new Set([...virtualStoragesMap.keys(), ...localProjectionsMap.keys()]).size !==\n virtualStoragesMap.size + localProjectionsMap.size\n )\n throw new Error(\n \"Intersection between local projection storage ids and virtual storages names detected.\",\n );\n\n return new LsDriver(\n logger,\n lsClient,\n await doGetAvailableStorageIds(client),\n signer,\n virtualStoragesMap,\n localProjectionsMap,\n openFileDialogCallback,\n );\n }\n}\n\nasync function doGetAvailableStorageIds(client: PlClient): Promise<Record<string, ResourceId>> {\n return client.withReadTx(\"GetAvailableStorageIds\", async (tx) => {\n const lsProviderId = await tx.getResourceByName(\"LSProvider\");\n const provider = await tx.getResourceData(lsProviderId, true);\n\n return providerToStorageIds(provider);\n });\n}\n\nfunction providerToStorageIds(provider: ResourceData) {\n return Object.fromEntries(\n provider.fields\n .filter((f) => f.type == \"Dynamic\" && isNotNullResourceId(f.value))\n .map((f) => [f.name.substring(\"storage/\".length), f.value as ResourceId]),\n );\n}\n"],"names":["fsp","isImportFileHandleIndex","parseIndexHandle","path","parseUploadHandle","validateAbsolute","createIndexImportHandle","createUploadImportHandle","createLocalStorageHandle","createRemoteStorageHandle","parseStorageHandle","createLsFilesClient","DefaultVirtualLocalStorages","isNotNullResourceId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ls.cjs","names":["fsp","parseIndexHandle","path","parseUploadHandle","createIndexImportHandle","createUploadImportHandle","createLocalStorageHandle","createRemoteStorageHandle","parseStorageHandle","createLsFilesClient","DefaultVirtualLocalStorages"],"sources":["../../src/drivers/ls.ts"],"sourcesContent":["import type { PlClient, ResourceData, ResourceId } from \"@milaboratories/pl-client\";\nimport { isNotNullResourceId } from \"@milaboratories/pl-client\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport type {\n LocalImportFileHandle,\n LsEntry,\n OpenDialogOps,\n OpenMultipleFilesResponse,\n OpenSingleFileResponse,\n TableRange,\n} from \"@milaboratories/pl-model-common\";\nimport { isImportFileHandleIndex } from \"@milaboratories/pl-model-common\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { createLsFilesClient } from \"../clients/constructors\";\nimport type { ClientLs } from \"../clients/ls_api\";\nimport { validateAbsolute } from \"../helpers/validate\";\nimport {\n createIndexImportHandle,\n createUploadImportHandle,\n parseIndexHandle,\n parseUploadHandle,\n} from \"./helpers/ls_remote_import_handle\";\nimport {\n createLocalStorageHandle,\n createRemoteStorageHandle,\n parseStorageHandle,\n} from \"./helpers/ls_storage_entry\";\nimport type { LocalStorageProjection, VirtualLocalStorageSpec } from \"./types\";\nimport { DefaultVirtualLocalStorages } from \"./virtual_storages\";\n\n/**\n * Extends public and safe SDK's driver API with methods used internally in the middle\n * layer and in tests.\n */\nexport interface InternalLsDriver extends sdk.LsDriver {\n /**\n * Given local path, generates well-structured and signed upload handle.\n * To be used in tests and in implementation of the native file selection UI API.\n * */\n getLocalFileHandle(localPath: string): Promise<sdk.LocalImportFileHandle>;\n\n listRemoteFilesWithAdditionalInfo(\n storage: sdk.StorageHandle,\n fullPath: string,\n ): Promise<ListRemoteFilesResultWithAdditionalInfo>;\n}\n\nexport type ListRemoteFilesResultWithAdditionalInfo = {\n parent?: string;\n entries: LsEntryWithAdditionalInfo[];\n};\n\nexport type LsEntryWithAdditionalInfo = LsEntry & {\n size: number;\n};\n\nexport type OpenFileDialogCallback = (\n multipleFiles: boolean,\n ops?: OpenDialogOps,\n) => Promise<undefined | string[]>;\n\nexport class LsDriver implements InternalLsDriver {\n private constructor(\n private readonly logger: MiLogger,\n private readonly lsClient: ClientLs,\n /** Pl storage id, to resource id. The resource id can be used to make LS GRPC calls to. */\n private readonly storageIdToResourceId: Record<string, ResourceId>,\n private readonly signer: Signer,\n /** Virtual storages by name */\n private readonly virtualStoragesMap: Map<string, VirtualLocalStorageSpec>,\n /** Local projections by storageId */\n private readonly localProjectionsMap: Map<string, LocalStorageProjection>,\n private readonly openFileDialogCallback: OpenFileDialogCallback,\n ) {}\n\n public async getLocalFileContent(\n file: LocalImportFileHandle,\n range?: TableRange,\n ): Promise<Uint8Array> {\n const localPath = await this.tryResolveLocalFileHandle(file);\n\n if (range) {\n const fileHandle = await fsp.open(localPath, \"r\");\n try {\n const buffer = Buffer.alloc(range.length);\n const { bytesRead } = await fileHandle.read(buffer, 0, range.length, range.offset);\n return new Uint8Array(buffer.subarray(0, bytesRead));\n } finally {\n await fileHandle.close();\n }\n }\n\n return await fsp.readFile(localPath);\n }\n\n public async getLocalFileSize(file: LocalImportFileHandle): Promise<number> {\n const localPath = await this.tryResolveLocalFileHandle(file);\n const stat = await fsp.stat(localPath);\n return stat.size;\n }\n\n public async showOpenMultipleFilesDialog(\n ops?: OpenDialogOps,\n ): Promise<OpenMultipleFilesResponse> {\n const result = await this.openFileDialogCallback(true, ops);\n if (result === undefined) return {};\n return {\n files: await Promise.all(result.map((localPath) => this.getLocalFileHandle(localPath))),\n };\n }\n\n public async showOpenSingleFileDialog(ops?: OpenDialogOps): Promise<OpenSingleFileResponse> {\n const result = await this.openFileDialogCallback(false, ops);\n if (result === undefined) return {};\n return {\n file: await this.getLocalFileHandle(result[0]),\n };\n }\n\n /**\n * Resolves local handle to local file path.\n *\n * @param handle handle to be resolved\n * @private\n */\n private async tryResolveLocalFileHandle(handle: LocalImportFileHandle): Promise<string> {\n if (isImportFileHandleIndex(handle)) {\n const handleData = parseIndexHandle(handle);\n const localProjection = this.localProjectionsMap.get(handleData.storageId);\n if (!localProjection)\n throw new Error(`Storage ${handleData.storageId} is not mounted locally.`);\n return path.join(localProjection.localPath, handleData.path);\n } else {\n const handleData = parseUploadHandle(handle);\n // checking it is a valid local handle from out machine\n this.signer.verify(\n handleData.localPath,\n handleData.pathSignature,\n \"Failed to validate local file handle signature.\",\n );\n\n const localPath = handleData.localPath;\n\n const stat = await fsp.stat(localPath, { bigint: true });\n if (String(stat.mtimeMs / 1000n) !== handleData.modificationTime)\n throw new Error(\"File has changed since the handle was created.\");\n\n return localPath;\n }\n }\n\n public async getLocalFileHandle(\n localPath: string,\n ): Promise<sdk.ImportFileHandle & LocalImportFileHandle> {\n validateAbsolute(localPath);\n\n // Checking if local path is directly reachable by pl, because it is in one of the\n // locally mounted storages\n for (const lp of this.localProjectionsMap.values()) {\n // note: empty lp.localPath will match any address\n if (localPath.startsWith(lp.localPath)) {\n // Just in case:\n // > path.relative(\"/a/b\", \"/a/b/c\");\n // 'c'\n const pathWithinStorage =\n lp.localPath === \"\" ? localPath : path.relative(lp.localPath, localPath);\n return createIndexImportHandle(\n lp.storageId,\n pathWithinStorage,\n ) as sdk.ImportFileHandleIndex & LocalImportFileHandle;\n }\n }\n\n // we get here if none of the local projections matched the path\n\n const stat = await fsp.stat(localPath, { bigint: true });\n return createUploadImportHandle(\n localPath,\n this.signer,\n stat.size,\n stat.mtimeMs / 1000n, // integer division\n ) as sdk.ImportFileHandleUpload & LocalImportFileHandle;\n }\n\n public async getStorageList(): Promise<sdk.StorageEntry[]> {\n const virtualStorages = [...this.virtualStoragesMap.values()].map((s) => ({\n name: s.name,\n handle: createLocalStorageHandle(s.name, s.root),\n initialFullPath: s.initialPath,\n }));\n\n const otherStorages = Object.entries(this.storageIdToResourceId!).map(\n ([storageId, resourceId]) => ({\n name: storageId,\n handle: createRemoteStorageHandle(storageId, resourceId),\n initialFullPath: \"\", // we don't have any additional information from where to start browsing remote storages\n isInitialPathHome: false,\n }),\n );\n\n // root must be a storage so we can index any file,\n // but for UI it's enough\n // to have local virtual storage on *nix,\n // and local_disk_${drive} on Windows.\n const noRoot = otherStorages.filter((it) => it.name !== \"root\");\n\n return [...virtualStorages, ...noRoot];\n }\n\n public async listFiles(\n storageHandle: sdk.StorageHandle,\n fullPath: string,\n ): Promise<sdk.ListFilesResult> {\n const storageData = parseStorageHandle(storageHandle);\n\n if (storageData.isRemote) {\n const response = await this.lsClient.list(storageData, fullPath);\n return {\n entries: response.items.map((e) => ({\n type: e.isDir ? \"dir\" : \"file\",\n name: e.name,\n fullPath: e.fullName,\n handle: createIndexImportHandle(storageData.name, e.fullName),\n })),\n };\n }\n\n if (path.sep === \"/\" && fullPath === \"\") fullPath = \"/\";\n\n if (storageData.rootPath === \"\") {\n validateAbsolute(fullPath);\n }\n const lsRoot = path.isAbsolute(fullPath) ? fullPath : path.join(storageData.rootPath, fullPath);\n\n const entries: LsEntry[] = [];\n for await (const dirent of await fsp.opendir(lsRoot)) {\n if (!dirent.isFile() && !dirent.isDirectory()) continue;\n\n // We cannot use no dirent.fullPath no dirent.parentPath,\n // since the former is deprecated\n // and the later works differently on different versions.\n const absolutePath = path.join(lsRoot, dirent.name);\n\n entries.push({\n type: dirent.isFile() ? \"file\" : \"dir\",\n name: dirent.name,\n fullPath: absolutePath,\n handle: await this.getLocalFileHandle(absolutePath),\n });\n }\n\n return { entries };\n }\n\n public async listRemoteFilesWithAdditionalInfo(\n storageHandle: sdk.StorageHandle,\n fullPath: string,\n ): Promise<ListRemoteFilesResultWithAdditionalInfo> {\n const storageData = parseStorageHandle(storageHandle);\n if (!storageData.isRemote) {\n throw new Error(`Storage ${storageData.name} is not remote`);\n }\n\n const response = await this.lsClient.list(storageData, fullPath);\n\n return {\n entries: response.items.map((e) => ({\n type: e.isDir ? \"dir\" : \"file\",\n name: e.name,\n fullPath: e.fullName,\n handle: createIndexImportHandle(storageData.name, e.fullName),\n size: Number(e.size),\n })),\n };\n }\n\n public async fileToImportHandle(_file: sdk.FileLike): Promise<sdk.ImportFileHandle> {\n throw new Error(\n \"Not implemented. This method must be implemented and intercepted in desktop preload script.\",\n );\n }\n\n public static async init(\n logger: MiLogger,\n client: PlClient,\n signer: Signer,\n /** Pl storages available locally */\n localProjections: LocalStorageProjection[],\n openFileDialogCallback: OpenFileDialogCallback,\n virtualStorages?: VirtualLocalStorageSpec[],\n ): Promise<LsDriver> {\n const lsClient = createLsFilesClient(client, logger);\n\n if (!virtualStorages) virtualStorages = await DefaultVirtualLocalStorages();\n\n // validating inputs\n for (const vp of virtualStorages) validateAbsolute(vp.root);\n for (const lp of localProjections) if (lp.localPath !== \"\") validateAbsolute(lp.localPath);\n\n // creating indexed maps for quick access\n const virtualStoragesMap = new Map(virtualStorages.map((s) => [s.name, s]));\n const localProjectionsMap = new Map(localProjections.map((s) => [s.storageId, s]));\n\n // validating there is no intersection\n if (\n new Set([...virtualStoragesMap.keys(), ...localProjectionsMap.keys()]).size !==\n virtualStoragesMap.size + localProjectionsMap.size\n )\n throw new Error(\n \"Intersection between local projection storage ids and virtual storages names detected.\",\n );\n\n return new LsDriver(\n logger,\n lsClient,\n await doGetAvailableStorageIds(client),\n signer,\n virtualStoragesMap,\n localProjectionsMap,\n openFileDialogCallback,\n );\n }\n}\n\nasync function doGetAvailableStorageIds(client: PlClient): Promise<Record<string, ResourceId>> {\n return client.withReadTx(\"GetAvailableStorageIds\", async (tx) => {\n const lsProviderId = await tx.getResourceByName(\"LSProvider\");\n const provider = await tx.getResourceData(lsProviderId, true);\n\n return providerToStorageIds(provider);\n });\n}\n\nfunction providerToStorageIds(provider: ResourceData) {\n return Object.fromEntries(\n provider.fields\n .filter((f) => f.type == \"Dynamic\" && isNotNullResourceId(f.value))\n .map((f) => [f.name.substring(\"storage/\".length), f.value as ResourceId]),\n );\n}\n"],"mappings":"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"}
|