@milaboratories/pl-drivers 1.12.8 → 1.12.10

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.
Files changed (243) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +7 -13
  2. package/dist/clients/constructors.cjs +6 -7
  3. package/dist/clients/constructors.cjs.map +1 -1
  4. package/dist/clients/constructors.d.ts.map +1 -0
  5. package/dist/clients/constructors.js +1 -2
  6. package/dist/clients/constructors.js.map +1 -1
  7. package/dist/clients/crc32c.cjs +1 -2
  8. package/dist/clients/crc32c.cjs.map +1 -1
  9. package/dist/clients/crc32c.js +1 -1
  10. package/dist/clients/download.cjs +5 -6
  11. package/dist/clients/download.cjs.map +1 -1
  12. package/dist/clients/download.d.ts.map +1 -0
  13. package/dist/clients/download.js +1 -2
  14. package/dist/clients/download.js.map +1 -1
  15. package/dist/clients/logs.cjs +3 -4
  16. package/dist/clients/logs.cjs.map +1 -1
  17. package/dist/clients/logs.d.ts.map +1 -0
  18. package/dist/clients/logs.js +1 -2
  19. package/dist/clients/logs.js.map +1 -1
  20. package/dist/clients/ls_api.cjs +3 -4
  21. package/dist/clients/ls_api.cjs.map +1 -1
  22. package/dist/clients/ls_api.d.ts.map +1 -0
  23. package/dist/clients/ls_api.js +1 -2
  24. package/dist/clients/ls_api.js.map +1 -1
  25. package/dist/clients/progress.cjs +3 -4
  26. package/dist/clients/progress.cjs.map +1 -1
  27. package/dist/clients/progress.d.ts.map +1 -0
  28. package/dist/clients/progress.js +1 -2
  29. package/dist/clients/progress.js.map +1 -1
  30. package/dist/clients/upload.cjs +5 -6
  31. package/dist/clients/upload.cjs.map +1 -1
  32. package/dist/clients/upload.d.ts.map +1 -0
  33. package/dist/clients/upload.js +1 -2
  34. package/dist/clients/upload.js.map +1 -1
  35. package/dist/drivers/download_blob/blob_key.cjs +3 -4
  36. package/dist/drivers/download_blob/blob_key.cjs.map +1 -1
  37. package/dist/drivers/download_blob/blob_key.js +2 -3
  38. package/dist/drivers/download_blob/blob_key.js.map +1 -1
  39. package/dist/drivers/download_blob/download_blob.cjs +13 -14
  40. package/dist/drivers/download_blob/download_blob.cjs.map +1 -1
  41. package/dist/drivers/download_blob/download_blob.d.ts.map +1 -0
  42. package/dist/drivers/download_blob/download_blob.js +1 -2
  43. package/dist/drivers/download_blob/download_blob.js.map +1 -1
  44. package/dist/drivers/download_blob/download_blob_task.cjs +4 -5
  45. package/dist/drivers/download_blob/download_blob_task.cjs.map +1 -1
  46. package/dist/drivers/download_blob/download_blob_task.js +1 -2
  47. package/dist/drivers/download_blob/download_blob_task.js.map +1 -1
  48. package/dist/drivers/download_blob/sparse_cache/cache.cjs +4 -5
  49. package/dist/drivers/download_blob/sparse_cache/cache.cjs.map +1 -1
  50. package/dist/drivers/download_blob/sparse_cache/cache.js +1 -2
  51. package/dist/drivers/download_blob/sparse_cache/cache.js.map +1 -1
  52. package/dist/drivers/download_blob/sparse_cache/file.cjs +2 -3
  53. package/dist/drivers/download_blob/sparse_cache/file.cjs.map +1 -1
  54. package/dist/drivers/download_blob/sparse_cache/file.js +1 -2
  55. package/dist/drivers/download_blob/sparse_cache/file.js.map +1 -1
  56. package/dist/drivers/download_blob/sparse_cache/ranges.cjs +3 -4
  57. package/dist/drivers/download_blob/sparse_cache/ranges.cjs.map +1 -1
  58. package/dist/drivers/download_blob/sparse_cache/ranges.js +1 -2
  59. package/dist/drivers/download_blob/sparse_cache/ranges.js.map +1 -1
  60. package/dist/drivers/download_blob_url/driver.cjs +8 -9
  61. package/dist/drivers/download_blob_url/driver.cjs.map +1 -1
  62. package/dist/drivers/download_blob_url/driver.d.ts.map +1 -0
  63. package/dist/drivers/download_blob_url/driver.js +1 -2
  64. package/dist/drivers/download_blob_url/driver.js.map +1 -1
  65. package/dist/drivers/download_blob_url/driver_id.cjs +1 -2
  66. package/dist/drivers/download_blob_url/driver_id.cjs.map +1 -1
  67. package/dist/drivers/download_blob_url/driver_id.js +1 -1
  68. package/dist/drivers/download_blob_url/snapshot.cjs +2 -3
  69. package/dist/drivers/download_blob_url/snapshot.cjs.map +1 -1
  70. package/dist/drivers/download_blob_url/snapshot.d.ts +2 -2
  71. package/dist/drivers/download_blob_url/snapshot.d.ts.map +1 -0
  72. package/dist/drivers/download_blob_url/snapshot.js +1 -2
  73. package/dist/drivers/download_blob_url/snapshot.js.map +1 -1
  74. package/dist/drivers/download_blob_url/task.cjs +5 -6
  75. package/dist/drivers/download_blob_url/task.cjs.map +1 -1
  76. package/dist/drivers/download_blob_url/task.d.ts.map +1 -0
  77. package/dist/drivers/download_blob_url/task.js +1 -2
  78. package/dist/drivers/download_blob_url/task.js.map +1 -1
  79. package/dist/drivers/download_url/driver.cjs +7 -8
  80. package/dist/drivers/download_url/driver.cjs.map +1 -1
  81. package/dist/drivers/download_url/driver.d.ts.map +1 -0
  82. package/dist/drivers/download_url/driver.js +1 -2
  83. package/dist/drivers/download_url/driver.js.map +1 -1
  84. package/dist/drivers/download_url/task.cjs +4 -5
  85. package/dist/drivers/download_url/task.cjs.map +1 -1
  86. package/dist/drivers/download_url/task.d.ts.map +1 -0
  87. package/dist/drivers/download_url/task.js +1 -2
  88. package/dist/drivers/download_url/task.js.map +1 -1
  89. package/dist/drivers/helpers/download_local_handle.cjs +1 -2
  90. package/dist/drivers/helpers/download_local_handle.cjs.map +1 -1
  91. package/dist/drivers/helpers/download_local_handle.js +1 -1
  92. package/dist/drivers/helpers/download_remote_handle.cjs +3 -4
  93. package/dist/drivers/helpers/download_remote_handle.cjs.map +1 -1
  94. package/dist/drivers/helpers/download_remote_handle.js +1 -2
  95. package/dist/drivers/helpers/download_remote_handle.js.map +1 -1
  96. package/dist/drivers/helpers/files_cache.cjs +2 -3
  97. package/dist/drivers/helpers/files_cache.cjs.map +1 -1
  98. package/dist/drivers/helpers/files_cache.js +1 -2
  99. package/dist/drivers/helpers/files_cache.js.map +1 -1
  100. package/dist/drivers/helpers/helpers.cjs +1 -2
  101. package/dist/drivers/helpers/helpers.cjs.map +1 -1
  102. package/dist/drivers/helpers/helpers.d.ts.map +1 -0
  103. package/dist/drivers/helpers/helpers.js +1 -1
  104. package/dist/drivers/helpers/helpers.js.map +1 -1
  105. package/dist/drivers/helpers/logs_handle.cjs +2 -3
  106. package/dist/drivers/helpers/logs_handle.cjs.map +1 -1
  107. package/dist/drivers/helpers/logs_handle.js +1 -2
  108. package/dist/drivers/helpers/logs_handle.js.map +1 -1
  109. package/dist/drivers/helpers/ls_remote_import_handle.cjs +4 -6
  110. package/dist/drivers/helpers/ls_remote_import_handle.cjs.map +1 -1
  111. package/dist/drivers/helpers/ls_remote_import_handle.js +3 -5
  112. package/dist/drivers/helpers/ls_remote_import_handle.js.map +1 -1
  113. package/dist/drivers/helpers/ls_storage_entry.cjs +2 -3
  114. package/dist/drivers/helpers/ls_storage_entry.cjs.map +1 -1
  115. package/dist/drivers/helpers/ls_storage_entry.js +1 -2
  116. package/dist/drivers/helpers/ls_storage_entry.js.map +1 -1
  117. package/dist/drivers/helpers/polling_ops.d.ts.map +1 -0
  118. package/dist/drivers/helpers/read_file.cjs +2 -3
  119. package/dist/drivers/helpers/read_file.cjs.map +1 -1
  120. package/dist/drivers/helpers/read_file.js +1 -2
  121. package/dist/drivers/helpers/read_file.js.map +1 -1
  122. package/dist/drivers/logs.cjs +3 -4
  123. package/dist/drivers/logs.cjs.map +1 -1
  124. package/dist/drivers/logs.d.ts.map +1 -0
  125. package/dist/drivers/logs.js +1 -2
  126. package/dist/drivers/logs.js.map +1 -1
  127. package/dist/drivers/logs_stream.cjs +4 -5
  128. package/dist/drivers/logs_stream.cjs.map +1 -1
  129. package/dist/drivers/logs_stream.d.ts.map +1 -0
  130. package/dist/drivers/logs_stream.js +1 -2
  131. package/dist/drivers/logs_stream.js.map +1 -1
  132. package/dist/drivers/ls.cjs +7 -8
  133. package/dist/drivers/ls.cjs.map +1 -1
  134. package/dist/drivers/ls.d.ts.map +1 -0
  135. package/dist/drivers/ls.js +1 -2
  136. package/dist/drivers/ls.js.map +1 -1
  137. package/dist/drivers/types.cjs +2 -3
  138. package/dist/drivers/types.cjs.map +1 -1
  139. package/dist/drivers/types.d.ts +4 -4
  140. package/dist/drivers/types.d.ts.map +1 -0
  141. package/dist/drivers/types.js +1 -2
  142. package/dist/drivers/types.js.map +1 -1
  143. package/dist/drivers/upload.cjs +5 -6
  144. package/dist/drivers/upload.cjs.map +1 -1
  145. package/dist/drivers/upload.d.ts.map +1 -0
  146. package/dist/drivers/upload.js +1 -2
  147. package/dist/drivers/upload.js.map +1 -1
  148. package/dist/drivers/upload_task.cjs +4 -5
  149. package/dist/drivers/upload_task.cjs.map +1 -1
  150. package/dist/drivers/upload_task.d.ts.map +1 -0
  151. package/dist/drivers/upload_task.js +1 -2
  152. package/dist/drivers/upload_task.js.map +1 -1
  153. package/dist/drivers/urls/url.cjs +2 -3
  154. package/dist/drivers/urls/url.cjs.map +1 -1
  155. package/dist/drivers/urls/url.js +1 -2
  156. package/dist/drivers/urls/url.js.map +1 -1
  157. package/dist/drivers/virtual_storages.cjs +2 -3
  158. package/dist/drivers/virtual_storages.cjs.map +1 -1
  159. package/dist/drivers/virtual_storages.d.ts.map +1 -0
  160. package/dist/drivers/virtual_storages.js +1 -2
  161. package/dist/drivers/virtual_storages.js.map +1 -1
  162. package/dist/helpers/download.cjs +3 -4
  163. package/dist/helpers/download.cjs.map +1 -1
  164. package/dist/helpers/download.d.ts.map +1 -0
  165. package/dist/helpers/download.js +1 -2
  166. package/dist/helpers/download.js.map +1 -1
  167. package/dist/helpers/download_errors.cjs +1 -2
  168. package/dist/helpers/download_errors.cjs.map +1 -1
  169. package/dist/helpers/download_errors.d.ts.map +1 -0
  170. package/dist/helpers/download_errors.js +1 -1
  171. package/dist/helpers/validate.cjs +2 -3
  172. package/dist/helpers/validate.cjs.map +1 -1
  173. package/dist/helpers/validate.d.ts.map +1 -0
  174. package/dist/helpers/validate.js +1 -2
  175. package/dist/helpers/validate.js.map +1 -1
  176. package/dist/index.cjs +22 -23
  177. package/dist/index.js +1 -2
  178. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs +4 -11
  179. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.cjs.map +1 -1
  180. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs +3 -4
  181. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.cjs.map +1 -1
  182. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts +4 -4
  183. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.d.ts.map +1 -0
  184. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js +1 -2
  185. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.client.js.map +1 -1
  186. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.d.ts.map +1 -0
  187. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js +4 -15
  188. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/downloadapi/protocol.js.map +1 -1
  189. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs +5 -12
  190. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.cjs.map +1 -1
  191. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs +3 -4
  192. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.cjs.map +1 -1
  193. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js +1 -2
  194. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.client.js.map +1 -1
  195. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.d.ts.map +1 -0
  196. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js +4 -15
  197. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/lsapi/protocol.js.map +1 -1
  198. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs +6 -16
  199. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.cjs.map +1 -1
  200. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs +3 -4
  201. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.cjs.map +1 -1
  202. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts +4 -4
  203. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.d.ts.map +1 -0
  204. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js +1 -2
  205. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.client.js.map +1 -1
  206. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.d.ts.map +1 -0
  207. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js +4 -14
  208. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/progressapi/protocol.js.map +1 -1
  209. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs +3 -7
  210. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.cjs.map +1 -1
  211. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs +3 -4
  212. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.cjs.map +1 -1
  213. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts +4 -4
  214. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.d.ts.map +1 -0
  215. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js +1 -2
  216. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.client.js.map +1 -1
  217. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.d.ts.map +1 -0
  218. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js +2 -6
  219. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/streamingapi/protocol.js.map +1 -1
  220. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs +8 -27
  221. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.cjs.map +1 -1
  222. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs +3 -4
  223. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.cjs.map +1 -1
  224. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js +1 -2
  225. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.client.js.map +1 -1
  226. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.d.ts.map +1 -0
  227. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js +7 -26
  228. package/dist/proto-grpc/github.com/milaboratory/pl/controllers/shared/grpc/uploadapi/protocol.js.map +1 -1
  229. package/dist/proto-grpc/google/protobuf/duration.cjs +2 -3
  230. package/dist/proto-grpc/google/protobuf/duration.cjs.map +1 -1
  231. package/dist/proto-grpc/google/protobuf/duration.d.ts.map +1 -0
  232. package/dist/proto-grpc/google/protobuf/duration.js +1 -2
  233. package/dist/proto-grpc/google/protobuf/duration.js.map +1 -1
  234. package/dist/proto-grpc/google/protobuf/timestamp.cjs +2 -3
  235. package/dist/proto-grpc/google/protobuf/timestamp.cjs.map +1 -1
  236. package/dist/proto-grpc/google/protobuf/timestamp.d.ts.map +1 -0
  237. package/dist/proto-grpc/google/protobuf/timestamp.js +1 -2
  238. package/dist/proto-grpc/google/protobuf/timestamp.js.map +1 -1
  239. package/dist/proto-rest/downloadapi.d.ts.map +1 -0
  240. package/dist/proto-rest/index.d.ts.map +1 -0
  241. package/dist/proto-rest/progressapi.d.ts.map +1 -0
  242. package/dist/proto-rest/streamingapi.d.ts.map +1 -0
  243. package/package.json +11 -11
@@ -1 +1 @@
1
- {"version":3,"file":"driver.js","names":["path"],"sources":["../../../src/drivers/download_url/driver.ts"],"sourcesContent":["import type { ComputableCtx, Watcher } from \"@milaboratories/computable\";\nimport { Computable } from \"@milaboratories/computable\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport { TaskProcessor } from \"@milaboratories/ts-helpers\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport * as path from \"node:path\";\nimport type { Dispatcher } from \"undici\";\nimport { RemoteFileDownloader } from \"../../helpers/download\";\nimport { isDownloadNetworkError400 } from \"../../helpers/download_errors\";\nimport { FilesCache } from \"../helpers/files_cache\";\nimport { stringifyWithResourceId } from \"@milaboratories/pl-client\";\nimport type { BlockUIURL, FrontendDriver } from \"@milaboratories/pl-model-common\";\nimport { isBlockUIURL } from \"@milaboratories/pl-model-common\";\nimport { getPathForBlockUIURL } from \"../urls/url\";\nimport { DownloadByUrlTask, rmRFDir, URLAborted } from \"./task\";\n\nexport interface DownloadUrlSyncReader {\n /** Returns a Computable that (when the time will come)\n * downloads an archive from an URL,\n * extracts it to the local dir and returns a path to that dir. */\n getUrl(url: URL): Computable<UrlResult | undefined>;\n}\n\nexport interface UrlResult {\n /** Path to the downloadable blob along with the signature and a custom protocol,\n * might be undefined when the error happened. */\n url?: BlockUIURL;\n /** Error that happened when the archive were downloaded. */\n error?: string;\n}\n\nexport type DownloadUrlDriverOps = {\n /** A soft limit of the amount of blob storage, in bytes.\n * Once exceeded, the download driver will start deleting blobs one by one\n * when they become unneeded.\n * */\n cacheSoftSizeBytes: number;\n\n /** Whether to gunzip the downloaded archive (it will be untared automatically). */\n withGunzip: boolean;\n\n /** Max number of concurrent downloads while calculating computable states\n * derived from this driver.\n * */\n nConcurrentDownloads: number;\n};\n\n/** Downloads .tar or .tar.gz archives by given URLs\n * and extracts them into saveDir. */\nexport class DownloadUrlDriver implements DownloadUrlSyncReader, FrontendDriver {\n private readonly downloadHelper: RemoteFileDownloader;\n\n private urlToDownload: Map<string, DownloadByUrlTask> = 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<DownloadByUrlTask>;\n\n constructor(\n private readonly logger: MiLogger,\n httpClient: Dispatcher,\n private readonly saveDir: string,\n private readonly signer: Signer,\n private readonly opts: DownloadUrlDriverOps = {\n cacheSoftSizeBytes: 1 * 1024 * 1024 * 1024, // 1 GB\n withGunzip: true,\n nConcurrentDownloads: 50,\n },\n ) {\n this.downloadQueue = new TaskProcessor(this.logger, this.opts.nConcurrentDownloads);\n this.cache = new FilesCache(this.opts.cacheSoftSizeBytes);\n this.downloadHelper = new RemoteFileDownloader(httpClient);\n }\n\n /** Use to get a path result inside a computable context */\n getUrl(url: URL, ctx: ComputableCtx): UrlResult | undefined;\n\n /** Returns a Computable that do the work */\n getUrl(url: URL): Computable<UrlResult | undefined>;\n\n /** Returns a computable that returns a custom protocol URL to the downloaded and unarchived path. */\n getUrl(url: URL, ctx?: ComputableCtx): Computable<UrlResult | undefined> | UrlResult | undefined {\n // wrap result as computable, if we were not given an existing computable context\n if (ctx === undefined) return Computable.make((c) => this.getUrl(url, c));\n\n const callerId = randomUUID();\n\n // read as ~ golang's defer\n ctx.addOnDestroy(() => this.releasePath(url, callerId));\n\n const result = this.getUrlNoCtx(url, ctx.watcher, callerId);\n if (result?.url === undefined)\n ctx.markUnstable(\n `a path to the downloaded and untared archive might be undefined. The current result: ${result}`,\n );\n\n return result;\n }\n\n getUrlNoCtx(url: URL, w: Watcher, callerId: string) {\n const key = url.toString();\n const task = this.urlToDownload.get(key);\n\n if (task !== undefined) {\n task.attach(w, callerId);\n return task.getUrl();\n }\n\n const newTask = this.setNewTask(w, url, callerId);\n this.downloadQueue.push({\n fn: async () => this.downloadUrl(newTask, callerId),\n recoverableErrorPredicate: (e) => !(e instanceof URLAborted) && !isDownloadNetworkError400(e),\n });\n\n return newTask.getUrl();\n }\n\n getPathForBlockUI(url: string): string {\n if (!isBlockUIURL(url)) {\n throw new Error(`getPathForBlockUI: ${url} is invalid`);\n }\n\n return getPathForBlockUIURL(this.signer, url, this.saveDir);\n }\n\n /** Downloads and extracts a tar archive if it wasn't downloaded yet. */\n async downloadUrl(task: DownloadByUrlTask, callerId: string) {\n await task.download(this.downloadHelper, this.opts.withGunzip);\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(url: URL, callerId: string): Promise<void> {\n const key = url.toString();\n const task = this.urlToDownload.get(key);\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: DownloadByUrlTask) => {\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.urlToDownload.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, url: URL, callerId: string) {\n const result = new DownloadByUrlTask(\n this.logger,\n this.getFilePath(url),\n url,\n this.signer,\n this.saveDir,\n );\n result.attach(w, callerId);\n this.urlToDownload.set(url.toString(), result);\n\n return result;\n }\n\n private removeTask(task: DownloadByUrlTask, reason: string) {\n task.abort(reason);\n task.change.markChanged(`task for url ${task.url} removed: ${reason}`);\n this.urlToDownload.delete(task.url.toString());\n }\n\n private getFilePath(url: URL): string {\n const sha256 = createHash(\"sha256\").update(url.toString()).digest(\"hex\");\n return path.join(this.saveDir, sha256);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"driver.js","names":["path"],"sources":["../../../src/drivers/download_url/driver.ts"],"sourcesContent":["import type { ComputableCtx, Watcher } from \"@milaboratories/computable\";\nimport { Computable } from \"@milaboratories/computable\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport { TaskProcessor } from \"@milaboratories/ts-helpers\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport * as path from \"node:path\";\nimport type { Dispatcher } from \"undici\";\nimport { RemoteFileDownloader } from \"../../helpers/download\";\nimport { isDownloadNetworkError400 } from \"../../helpers/download_errors\";\nimport { FilesCache } from \"../helpers/files_cache\";\nimport { stringifyWithResourceId } from \"@milaboratories/pl-client\";\nimport type { BlockUIURL, FrontendDriver } from \"@milaboratories/pl-model-common\";\nimport { isBlockUIURL } from \"@milaboratories/pl-model-common\";\nimport { getPathForBlockUIURL } from \"../urls/url\";\nimport { DownloadByUrlTask, rmRFDir, URLAborted } from \"./task\";\n\nexport interface DownloadUrlSyncReader {\n /** Returns a Computable that (when the time will come)\n * downloads an archive from an URL,\n * extracts it to the local dir and returns a path to that dir. */\n getUrl(url: URL): Computable<UrlResult | undefined>;\n}\n\nexport interface UrlResult {\n /** Path to the downloadable blob along with the signature and a custom protocol,\n * might be undefined when the error happened. */\n url?: BlockUIURL;\n /** Error that happened when the archive were downloaded. */\n error?: string;\n}\n\nexport type DownloadUrlDriverOps = {\n /** A soft limit of the amount of blob storage, in bytes.\n * Once exceeded, the download driver will start deleting blobs one by one\n * when they become unneeded.\n * */\n cacheSoftSizeBytes: number;\n\n /** Whether to gunzip the downloaded archive (it will be untared automatically). */\n withGunzip: boolean;\n\n /** Max number of concurrent downloads while calculating computable states\n * derived from this driver.\n * */\n nConcurrentDownloads: number;\n};\n\n/** Downloads .tar or .tar.gz archives by given URLs\n * and extracts them into saveDir. */\nexport class DownloadUrlDriver implements DownloadUrlSyncReader, FrontendDriver {\n private readonly downloadHelper: RemoteFileDownloader;\n\n private urlToDownload: Map<string, DownloadByUrlTask> = 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<DownloadByUrlTask>;\n\n constructor(\n private readonly logger: MiLogger,\n httpClient: Dispatcher,\n private readonly saveDir: string,\n private readonly signer: Signer,\n private readonly opts: DownloadUrlDriverOps = {\n cacheSoftSizeBytes: 1 * 1024 * 1024 * 1024, // 1 GB\n withGunzip: true,\n nConcurrentDownloads: 50,\n },\n ) {\n this.downloadQueue = new TaskProcessor(this.logger, this.opts.nConcurrentDownloads);\n this.cache = new FilesCache(this.opts.cacheSoftSizeBytes);\n this.downloadHelper = new RemoteFileDownloader(httpClient);\n }\n\n /** Use to get a path result inside a computable context */\n getUrl(url: URL, ctx: ComputableCtx): UrlResult | undefined;\n\n /** Returns a Computable that do the work */\n getUrl(url: URL): Computable<UrlResult | undefined>;\n\n /** Returns a computable that returns a custom protocol URL to the downloaded and unarchived path. */\n getUrl(url: URL, ctx?: ComputableCtx): Computable<UrlResult | undefined> | UrlResult | undefined {\n // wrap result as computable, if we were not given an existing computable context\n if (ctx === undefined) return Computable.make((c) => this.getUrl(url, c));\n\n const callerId = randomUUID();\n\n // read as ~ golang's defer\n ctx.addOnDestroy(() => this.releasePath(url, callerId));\n\n const result = this.getUrlNoCtx(url, ctx.watcher, callerId);\n if (result?.url === undefined)\n ctx.markUnstable(\n `a path to the downloaded and untared archive might be undefined. The current result: ${result}`,\n );\n\n return result;\n }\n\n getUrlNoCtx(url: URL, w: Watcher, callerId: string) {\n const key = url.toString();\n const task = this.urlToDownload.get(key);\n\n if (task !== undefined) {\n task.attach(w, callerId);\n return task.getUrl();\n }\n\n const newTask = this.setNewTask(w, url, callerId);\n this.downloadQueue.push({\n fn: async () => this.downloadUrl(newTask, callerId),\n recoverableErrorPredicate: (e) => !(e instanceof URLAborted) && !isDownloadNetworkError400(e),\n });\n\n return newTask.getUrl();\n }\n\n getPathForBlockUI(url: string): string {\n if (!isBlockUIURL(url)) {\n throw new Error(`getPathForBlockUI: ${url} is invalid`);\n }\n\n return getPathForBlockUIURL(this.signer, url, this.saveDir);\n }\n\n /** Downloads and extracts a tar archive if it wasn't downloaded yet. */\n async downloadUrl(task: DownloadByUrlTask, callerId: string) {\n await task.download(this.downloadHelper, this.opts.withGunzip);\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(url: URL, callerId: string): Promise<void> {\n const key = url.toString();\n const task = this.urlToDownload.get(key);\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: DownloadByUrlTask) => {\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.urlToDownload.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, url: URL, callerId: string) {\n const result = new DownloadByUrlTask(\n this.logger,\n this.getFilePath(url),\n url,\n this.signer,\n this.saveDir,\n );\n result.attach(w, callerId);\n this.urlToDownload.set(url.toString(), result);\n\n return result;\n }\n\n private removeTask(task: DownloadByUrlTask, reason: string) {\n task.abort(reason);\n task.change.markChanged(`task for url ${task.url} removed: ${reason}`);\n this.urlToDownload.delete(task.url.toString());\n }\n\n private getFilePath(url: URL): string {\n const sha256 = createHash(\"sha256\").update(url.toString()).digest(\"hex\");\n return path.join(this.saveDir, sha256);\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
2
- const require_download_errors = require('../../helpers/download_errors.cjs');
3
- const require_url = require('../urls/url.cjs');
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_download_errors = require("../../helpers/download_errors.cjs");
3
+ const require_url = require("../urls/url.cjs");
4
4
  let node_fs_promises = require("node:fs/promises");
5
5
  node_fs_promises = require_runtime.__toESM(node_fs_promises);
6
6
  let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
@@ -12,7 +12,6 @@ let node_zlib = require("node:zlib");
12
12
  node_zlib = require_runtime.__toESM(node_zlib);
13
13
  let tar_fs = require("tar-fs");
14
14
  tar_fs = require_runtime.__toESM(tar_fs);
15
-
16
15
  //#region src/drivers/download_url/task.ts
17
16
  /** Downloads and extracts an archive to a directory. */
18
17
  var DownloadByUrlTask = class {
@@ -109,9 +108,9 @@ async function rmRFDir(path) {
109
108
  force: true
110
109
  });
111
110
  }
112
-
113
111
  //#endregion
114
112
  exports.DownloadByUrlTask = DownloadByUrlTask;
115
113
  exports.URLAborted = URLAborted;
116
114
  exports.rmRFDir = rmRFDir;
115
+
117
116
  //# sourceMappingURL=task.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.cjs","names":["CallersCounter","ChangeSource","isDownloadNetworkError400","path","Transform","zlib","fsp","Writable","tar","newBlockUIURL"],"sources":["../../../src/drivers/download_url/task.ts"],"sourcesContent":["import type { Watcher } from \"@milaboratories/computable\";\nimport { ChangeSource } from \"@milaboratories/computable\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport {\n CallersCounter,\n createPathAtomically,\n ensureDirExists,\n fileExists,\n notEmpty,\n} from \"@milaboratories/ts-helpers\";\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { Transform, Writable } from \"node:stream\";\nimport * as zlib from \"node:zlib\";\nimport * as tar from \"tar-fs\";\nimport type { RemoteFileDownloader } from \"../../helpers/download\";\nimport { isDownloadNetworkError400 } from \"../../helpers/download_errors\";\nimport type { UrlResult } from \"./driver\";\nimport { newBlockUIURL } from \"../urls/url\";\n\n/** Downloads and extracts an archive to a directory. */\nexport class DownloadByUrlTask {\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\n constructor(\n private readonly logger: MiLogger,\n readonly path: string,\n readonly url: URL,\n readonly signer: Signer,\n readonly saveDir: string,\n ) {}\n\n public info() {\n return {\n url: this.url.toString(),\n path: this.path,\n done: this.done,\n size: this.size,\n error: this.error,\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(clientDownload: RemoteFileDownloader, withGunzip: boolean) {\n try {\n const size = await this.downloadAndUntar(clientDownload, withGunzip, this.signalCtl.signal);\n this.setDone(size);\n this.change.markChanged(`download of ${this.url} finished`);\n } catch (e: unknown) {\n if (e instanceof URLAborted || isDownloadNetworkError400(e)) {\n this.setError(e);\n this.change.markChanged(`download of ${this.url} 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 private async downloadAndUntar(\n clientDownload: RemoteFileDownloader,\n withGunzip: boolean,\n signal: AbortSignal,\n ): Promise<number> {\n await ensureDirExists(path.dirname(this.path));\n\n if (await fileExists(this.path)) {\n return await dirSize(this.path);\n }\n\n const size = await clientDownload.withContent(\n this.url.toString(),\n {},\n { signal },\n async (content, size) => {\n let processedContent = content;\n if (withGunzip) {\n const gunzip = Transform.toWeb(zlib.createGunzip());\n processedContent = content.pipeThrough(gunzip, { signal });\n }\n\n await createPathAtomically(this.logger, this.path, async (fPath: string) => {\n await fsp.mkdir(fPath); // throws if a directory already exists.\n const untar = Writable.toWeb(tar.extract(fPath));\n await processedContent.pipeTo(untar, { signal });\n });\n\n return size;\n },\n );\n\n return size;\n }\n\n getUrl(): UrlResult | undefined {\n if (this.done)\n return {\n url: newBlockUIURL(this.signer, this.saveDir, notEmpty(this.path)),\n };\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 }\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/** Throws when a downloading aborts. */\nexport class URLAborted extends Error {\n name = \"URLAborted\";\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"],"mappings":";;;;;;;;;;;;;;;;;AAqBA,IAAa,oBAAb,MAA+B;CAC7B,AAAS,UAAU,IAAIA,2CAAgB;CACvC,AAAS,SAAS,IAAIC,yCAAc;CACpC,AAAiB,YAAY,IAAI,iBAAiB;CAClD;CACA,OAAO;CACP,OAAO;CAEP,YACE,AAAiB,QACjB,AAAS,MACT,AAAS,KACT,AAAS,QACT,AAAS,SACT;EALiB;EACR;EACA;EACA;EACA;;CAGX,AAAO,OAAO;AACZ,SAAO;GACL,KAAK,KAAK,IAAI,UAAU;GACxB,MAAM,KAAK;GACX,MAAM,KAAK;GACX,MAAM,KAAK;GACX,OAAO,KAAK;GACb;;CAGH,OAAO,GAAY,UAAkB;AACnC,OAAK,QAAQ,IAAI,SAAS;AAC1B,MAAI,CAAC,KAAK,KAAM,MAAK,OAAO,cAAc,EAAE;;CAG9C,MAAM,SAAS,gBAAsC,YAAqB;AACxE,MAAI;GACF,MAAM,OAAO,MAAM,KAAK,iBAAiB,gBAAgB,YAAY,KAAK,UAAU,OAAO;AAC3F,QAAK,QAAQ,KAAK;AAClB,QAAK,OAAO,YAAY,eAAe,KAAK,IAAI,WAAW;WACpD,GAAY;AACnB,OAAI,aAAa,cAAcC,kDAA0B,EAAE,EAAE;AAC3D,SAAK,SAAS,EAAE;AAChB,SAAK,OAAO,YAAY,eAAe,KAAK,IAAI,SAAS;AAEzD,UAAM,QAAQ,KAAK,KAAK;AACxB;;AAGF,SAAM;;;CAIV,MAAc,iBACZ,gBACA,YACA,QACiB;AACjB,wDAAsBC,UAAK,QAAQ,KAAK,KAAK,CAAC;AAE9C,MAAI,iDAAiB,KAAK,KAAK,CAC7B,QAAO,MAAM,QAAQ,KAAK,KAAK;AAwBjC,SArBa,MAAM,eAAe,YAChC,KAAK,IAAI,UAAU,EACnB,EAAE,EACF,EAAE,QAAQ,EACV,OAAO,SAAS,SAAS;GACvB,IAAI,mBAAmB;AACvB,OAAI,YAAY;IACd,MAAM,SAASC,sBAAU,MAAMC,UAAK,cAAc,CAAC;AACnD,uBAAmB,QAAQ,YAAY,QAAQ,EAAE,QAAQ,CAAC;;AAG5D,8DAA2B,KAAK,QAAQ,KAAK,MAAM,OAAO,UAAkB;AAC1E,UAAMC,iBAAI,MAAM,MAAM;IACtB,MAAM,QAAQC,qBAAS,MAAMC,OAAI,QAAQ,MAAM,CAAC;AAChD,UAAM,iBAAiB,OAAO,OAAO,EAAE,QAAQ,CAAC;KAChD;AAEF,UAAO;IAEV;;CAKH,SAAgC;AAC9B,MAAI,KAAK,KACP,QAAO,EACL,KAAKC,0BAAc,KAAK,QAAQ,KAAK,kDAAkB,KAAK,KAAK,CAAC,EACnE;AAEH,MAAI,KAAK,MAAO,QAAO,EAAE,OAAO,KAAK,OAAO;;CAK9C,AAAQ,QAAQ,MAAc;AAC5B,OAAK,OAAO;AACZ,OAAK,OAAO;;CAGd,AAAQ,SAAS,GAAQ;AACvB,OAAK,QAAQ,OAAO,EAAE;;CAGxB,MAAM,QAAgB;AACpB,OAAK,UAAU,MAAM,IAAI,WAAW,OAAO,CAAC;;;;AAKhD,IAAa,aAAb,cAAgC,MAAM;CACpC,OAAO;;;AAIT,eAAe,QAAQ,KAA8B;CACnD,MAAM,QAAQ,MAAMH,iBAAI,QAAQ,KAAK,EAAE,eAAe,MAAM,CAAC;AAY7D,SAXc,MAAM,QAAQ,IAC1B,MAAM,IAAI,OAAO,SAAc;EAC7B,MAAM,QAAQH,UAAK,KAAK,KAAK,KAAK,KAAK;AAEvC,MAAI,KAAK,aAAa,CAAE,QAAO,MAAM,QAAQ,MAAM;AAGnD,UADa,MAAMG,iBAAI,KAAK,MAAM,EACtB;GACZ,CACH,EAEY,QAAQ,KAAU,SAAc,MAAM,MAAM,EAAE;;;AAI7D,eAAsB,QAAQ,MAAc;AAC1C,OAAMA,iBAAI,GAAG,MAAM;EAAE,WAAW;EAAM,OAAO;EAAM,CAAC"}
1
+ {"version":3,"file":"task.cjs","names":["CallersCounter","ChangeSource","isDownloadNetworkError400","path","Transform","zlib","fsp","Writable","tar","newBlockUIURL"],"sources":["../../../src/drivers/download_url/task.ts"],"sourcesContent":["import type { Watcher } from \"@milaboratories/computable\";\nimport { ChangeSource } from \"@milaboratories/computable\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport {\n CallersCounter,\n createPathAtomically,\n ensureDirExists,\n fileExists,\n notEmpty,\n} from \"@milaboratories/ts-helpers\";\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { Transform, Writable } from \"node:stream\";\nimport * as zlib from \"node:zlib\";\nimport * as tar from \"tar-fs\";\nimport type { RemoteFileDownloader } from \"../../helpers/download\";\nimport { isDownloadNetworkError400 } from \"../../helpers/download_errors\";\nimport type { UrlResult } from \"./driver\";\nimport { newBlockUIURL } from \"../urls/url\";\n\n/** Downloads and extracts an archive to a directory. */\nexport class DownloadByUrlTask {\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\n constructor(\n private readonly logger: MiLogger,\n readonly path: string,\n readonly url: URL,\n readonly signer: Signer,\n readonly saveDir: string,\n ) {}\n\n public info() {\n return {\n url: this.url.toString(),\n path: this.path,\n done: this.done,\n size: this.size,\n error: this.error,\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(clientDownload: RemoteFileDownloader, withGunzip: boolean) {\n try {\n const size = await this.downloadAndUntar(clientDownload, withGunzip, this.signalCtl.signal);\n this.setDone(size);\n this.change.markChanged(`download of ${this.url} finished`);\n } catch (e: unknown) {\n if (e instanceof URLAborted || isDownloadNetworkError400(e)) {\n this.setError(e);\n this.change.markChanged(`download of ${this.url} 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 private async downloadAndUntar(\n clientDownload: RemoteFileDownloader,\n withGunzip: boolean,\n signal: AbortSignal,\n ): Promise<number> {\n await ensureDirExists(path.dirname(this.path));\n\n if (await fileExists(this.path)) {\n return await dirSize(this.path);\n }\n\n const size = await clientDownload.withContent(\n this.url.toString(),\n {},\n { signal },\n async (content, size) => {\n let processedContent = content;\n if (withGunzip) {\n const gunzip = Transform.toWeb(zlib.createGunzip());\n processedContent = content.pipeThrough(gunzip, { signal });\n }\n\n await createPathAtomically(this.logger, this.path, async (fPath: string) => {\n await fsp.mkdir(fPath); // throws if a directory already exists.\n const untar = Writable.toWeb(tar.extract(fPath));\n await processedContent.pipeTo(untar, { signal });\n });\n\n return size;\n },\n );\n\n return size;\n }\n\n getUrl(): UrlResult | undefined {\n if (this.done)\n return {\n url: newBlockUIURL(this.signer, this.saveDir, notEmpty(this.path)),\n };\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 }\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/** Throws when a downloading aborts. */\nexport class URLAborted extends Error {\n name = \"URLAborted\";\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"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.d.ts","names":[],"sources":["../../../src/drivers/download_url/task.ts"],"mappings":";;;;;;AAqBA;AAAA,cAAa,iBAAA;EAAA,iBASQ,MAAA;EAAA,SACR,IAAA;EAAA,SACA,GAAA,EAAK,GAAA;EAAA,SACL,MAAA,EAAQ,MAAA;EAAA,SACR,OAAA;EAAA,SAZF,OAAA,EAAO,cAAA;EAAA,SACP,MAAA,EAAM,YAAA;EAAA,iBACE,SAAA;EACjB,KAAA;EACA,IAAA;EACA,IAAA;cAGmB,MAAA,EAAQ,QAAA,EAChB,IAAA,UACA,GAAA,EAAK,GAAA,EACL,MAAA,EAAQ,MAAA,EACR,OAAA;EAGJ,IAAA,CAAA;;;;;;;EAUP,MAAA,CAAO,CAAA,EAAG,OAAA,EAAS,QAAA;EAKb,QAAA,CAAS,cAAA,EAAgB,oBAAA,EAAsB,UAAA,YAAmB,OAAA;EAAA,QAkB1D,gBAAA;EAmCd,MAAA,CAAA,GAAU,SAAA;EAAA,QAWF,OAAA;EAAA,QAKA,QAAA;EAIR,KAAA,CAAM,MAAA;AAAA"}
@@ -7,7 +7,6 @@ import { Transform, Writable } from "node:stream";
7
7
  import { ChangeSource } from "@milaboratories/computable";
8
8
  import * as zlib from "node:zlib";
9
9
  import * as tar from "tar-fs";
10
-
11
10
  //#region src/drivers/download_url/task.ts
12
11
  /** Downloads and extracts an archive to a directory. */
13
12
  var DownloadByUrlTask = class {
@@ -104,7 +103,7 @@ async function rmRFDir(path) {
104
103
  force: true
105
104
  });
106
105
  }
107
-
108
106
  //#endregion
109
107
  export { DownloadByUrlTask, URLAborted, rmRFDir };
108
+
110
109
  //# sourceMappingURL=task.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.js","names":["path"],"sources":["../../../src/drivers/download_url/task.ts"],"sourcesContent":["import type { Watcher } from \"@milaboratories/computable\";\nimport { ChangeSource } from \"@milaboratories/computable\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport {\n CallersCounter,\n createPathAtomically,\n ensureDirExists,\n fileExists,\n notEmpty,\n} from \"@milaboratories/ts-helpers\";\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { Transform, Writable } from \"node:stream\";\nimport * as zlib from \"node:zlib\";\nimport * as tar from \"tar-fs\";\nimport type { RemoteFileDownloader } from \"../../helpers/download\";\nimport { isDownloadNetworkError400 } from \"../../helpers/download_errors\";\nimport type { UrlResult } from \"./driver\";\nimport { newBlockUIURL } from \"../urls/url\";\n\n/** Downloads and extracts an archive to a directory. */\nexport class DownloadByUrlTask {\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\n constructor(\n private readonly logger: MiLogger,\n readonly path: string,\n readonly url: URL,\n readonly signer: Signer,\n readonly saveDir: string,\n ) {}\n\n public info() {\n return {\n url: this.url.toString(),\n path: this.path,\n done: this.done,\n size: this.size,\n error: this.error,\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(clientDownload: RemoteFileDownloader, withGunzip: boolean) {\n try {\n const size = await this.downloadAndUntar(clientDownload, withGunzip, this.signalCtl.signal);\n this.setDone(size);\n this.change.markChanged(`download of ${this.url} finished`);\n } catch (e: unknown) {\n if (e instanceof URLAborted || isDownloadNetworkError400(e)) {\n this.setError(e);\n this.change.markChanged(`download of ${this.url} 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 private async downloadAndUntar(\n clientDownload: RemoteFileDownloader,\n withGunzip: boolean,\n signal: AbortSignal,\n ): Promise<number> {\n await ensureDirExists(path.dirname(this.path));\n\n if (await fileExists(this.path)) {\n return await dirSize(this.path);\n }\n\n const size = await clientDownload.withContent(\n this.url.toString(),\n {},\n { signal },\n async (content, size) => {\n let processedContent = content;\n if (withGunzip) {\n const gunzip = Transform.toWeb(zlib.createGunzip());\n processedContent = content.pipeThrough(gunzip, { signal });\n }\n\n await createPathAtomically(this.logger, this.path, async (fPath: string) => {\n await fsp.mkdir(fPath); // throws if a directory already exists.\n const untar = Writable.toWeb(tar.extract(fPath));\n await processedContent.pipeTo(untar, { signal });\n });\n\n return size;\n },\n );\n\n return size;\n }\n\n getUrl(): UrlResult | undefined {\n if (this.done)\n return {\n url: newBlockUIURL(this.signer, this.saveDir, notEmpty(this.path)),\n };\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 }\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/** Throws when a downloading aborts. */\nexport class URLAborted extends Error {\n name = \"URLAborted\";\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"],"mappings":"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"}
1
+ {"version":3,"file":"task.js","names":["path"],"sources":["../../../src/drivers/download_url/task.ts"],"sourcesContent":["import type { Watcher } from \"@milaboratories/computable\";\nimport { ChangeSource } from \"@milaboratories/computable\";\nimport type { MiLogger, Signer } from \"@milaboratories/ts-helpers\";\nimport {\n CallersCounter,\n createPathAtomically,\n ensureDirExists,\n fileExists,\n notEmpty,\n} from \"@milaboratories/ts-helpers\";\nimport * as fsp from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { Transform, Writable } from \"node:stream\";\nimport * as zlib from \"node:zlib\";\nimport * as tar from \"tar-fs\";\nimport type { RemoteFileDownloader } from \"../../helpers/download\";\nimport { isDownloadNetworkError400 } from \"../../helpers/download_errors\";\nimport type { UrlResult } from \"./driver\";\nimport { newBlockUIURL } from \"../urls/url\";\n\n/** Downloads and extracts an archive to a directory. */\nexport class DownloadByUrlTask {\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\n constructor(\n private readonly logger: MiLogger,\n readonly path: string,\n readonly url: URL,\n readonly signer: Signer,\n readonly saveDir: string,\n ) {}\n\n public info() {\n return {\n url: this.url.toString(),\n path: this.path,\n done: this.done,\n size: this.size,\n error: this.error,\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(clientDownload: RemoteFileDownloader, withGunzip: boolean) {\n try {\n const size = await this.downloadAndUntar(clientDownload, withGunzip, this.signalCtl.signal);\n this.setDone(size);\n this.change.markChanged(`download of ${this.url} finished`);\n } catch (e: unknown) {\n if (e instanceof URLAborted || isDownloadNetworkError400(e)) {\n this.setError(e);\n this.change.markChanged(`download of ${this.url} 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 private async downloadAndUntar(\n clientDownload: RemoteFileDownloader,\n withGunzip: boolean,\n signal: AbortSignal,\n ): Promise<number> {\n await ensureDirExists(path.dirname(this.path));\n\n if (await fileExists(this.path)) {\n return await dirSize(this.path);\n }\n\n const size = await clientDownload.withContent(\n this.url.toString(),\n {},\n { signal },\n async (content, size) => {\n let processedContent = content;\n if (withGunzip) {\n const gunzip = Transform.toWeb(zlib.createGunzip());\n processedContent = content.pipeThrough(gunzip, { signal });\n }\n\n await createPathAtomically(this.logger, this.path, async (fPath: string) => {\n await fsp.mkdir(fPath); // throws if a directory already exists.\n const untar = Writable.toWeb(tar.extract(fPath));\n await processedContent.pipeTo(untar, { signal });\n });\n\n return size;\n },\n );\n\n return size;\n }\n\n getUrl(): UrlResult | undefined {\n if (this.done)\n return {\n url: newBlockUIURL(this.signer, this.saveDir, notEmpty(this.path)),\n };\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 }\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/** Throws when a downloading aborts. */\nexport class URLAborted extends Error {\n name = \"URLAborted\";\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"],"mappings":"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"}
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/drivers/helpers/download_local_handle.ts
3
2
  const localHandleRegex = /^blob\+local:\/\/download\/(?<path>.*)#(?<signature>.*)$/;
4
3
  function newLocalHandle(path, signer) {
@@ -17,9 +16,9 @@ function parseLocalHandle(handle, signer) {
17
16
  signature
18
17
  };
19
18
  }
20
-
21
19
  //#endregion
22
20
  exports.isLocalBlobHandle = isLocalBlobHandle;
23
21
  exports.newLocalHandle = newLocalHandle;
24
22
  exports.parseLocalHandle = parseLocalHandle;
23
+
25
24
  //# sourceMappingURL=download_local_handle.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"download_local_handle.cjs","names":[],"sources":["../../../src/drivers/helpers/download_local_handle.ts"],"sourcesContent":["/** Handle of locally downloaded blob. This handle is issued only after the\n * blob's content is downloaded locally, and ready for quick access. */\n\nimport type { LocalBlobHandle } from \"@milaboratories/pl-model-common\";\nimport type { Signer } from \"@milaboratories/ts-helpers\";\n\n// https://regex101.com/r/kfnBVX/1\nconst localHandleRegex = /^blob\\+local:\\/\\/download\\/(?<path>.*)#(?<signature>.*)$/;\n\nexport function newLocalHandle(path: string, signer: Signer): LocalBlobHandle {\n return `blob+local://download/${path}#${signer.sign(path)}` as LocalBlobHandle;\n}\n\nexport function isLocalBlobHandle(handle: string): handle is LocalBlobHandle {\n return Boolean(handle.match(localHandleRegex));\n}\n\nexport function parseLocalHandle(handle: LocalBlobHandle, signer: Signer) {\n const parsed = handle.match(localHandleRegex);\n\n if (parsed === null) {\n throw new Error(`Local handle is malformed: ${handle}, matches: ${parsed}`);\n }\n\n const { path, signature } = parsed.groups!;\n signer.verify(path, signature, `Signature verification failed for: ${handle}`);\n\n return { path, signature };\n}\n"],"mappings":";;AAOA,MAAM,mBAAmB;AAEzB,SAAgB,eAAe,MAAc,QAAiC;AAC5E,QAAO,yBAAyB,KAAK,GAAG,OAAO,KAAK,KAAK;;AAG3D,SAAgB,kBAAkB,QAA2C;AAC3E,QAAO,QAAQ,OAAO,MAAM,iBAAiB,CAAC;;AAGhD,SAAgB,iBAAiB,QAAyB,QAAgB;CACxE,MAAM,SAAS,OAAO,MAAM,iBAAiB;AAE7C,KAAI,WAAW,KACb,OAAM,IAAI,MAAM,8BAA8B,OAAO,aAAa,SAAS;CAG7E,MAAM,EAAE,MAAM,cAAc,OAAO;AACnC,QAAO,OAAO,MAAM,WAAW,sCAAsC,SAAS;AAE9E,QAAO;EAAE;EAAM;EAAW"}
1
+ {"version":3,"file":"download_local_handle.cjs","names":[],"sources":["../../../src/drivers/helpers/download_local_handle.ts"],"sourcesContent":["/** Handle of locally downloaded blob. This handle is issued only after the\n * blob's content is downloaded locally, and ready for quick access. */\n\nimport type { LocalBlobHandle } from \"@milaboratories/pl-model-common\";\nimport type { Signer } from \"@milaboratories/ts-helpers\";\n\n// https://regex101.com/r/kfnBVX/1\nconst localHandleRegex = /^blob\\+local:\\/\\/download\\/(?<path>.*)#(?<signature>.*)$/;\n\nexport function newLocalHandle(path: string, signer: Signer): LocalBlobHandle {\n return `blob+local://download/${path}#${signer.sign(path)}` as LocalBlobHandle;\n}\n\nexport function isLocalBlobHandle(handle: string): handle is LocalBlobHandle {\n return Boolean(handle.match(localHandleRegex));\n}\n\nexport function parseLocalHandle(handle: LocalBlobHandle, signer: Signer) {\n const parsed = handle.match(localHandleRegex);\n\n if (parsed === null) {\n throw new Error(`Local handle is malformed: ${handle}, matches: ${parsed}`);\n }\n\n const { path, signature } = parsed.groups!;\n signer.verify(path, signature, `Signature verification failed for: ${handle}`);\n\n return { path, signature };\n}\n"],"mappings":";AAOA,MAAM,mBAAmB;AAEzB,SAAgB,eAAe,MAAc,QAAiC;AAC5E,QAAO,yBAAyB,KAAK,GAAG,OAAO,KAAK,KAAK;;AAG3D,SAAgB,kBAAkB,QAA2C;AAC3E,QAAO,QAAQ,OAAO,MAAM,iBAAiB,CAAC;;AAGhD,SAAgB,iBAAiB,QAAyB,QAAgB;CACxE,MAAM,SAAS,OAAO,MAAM,iBAAiB;AAE7C,KAAI,WAAW,KACb,OAAM,IAAI,MAAM,8BAA8B,OAAO,aAAa,SAAS;CAG7E,MAAM,EAAE,MAAM,cAAc,OAAO;AACnC,QAAO,OAAO,MAAM,WAAW,sCAAsC,SAAS;AAE9E,QAAO;EAAE;EAAM;EAAW"}
@@ -16,7 +16,7 @@ function parseLocalHandle(handle, signer) {
16
16
  signature
17
17
  };
18
18
  }
19
-
20
19
  //#endregion
21
20
  export { isLocalBlobHandle, newLocalHandle, parseLocalHandle };
21
+
22
22
  //# sourceMappingURL=download_local_handle.js.map
@@ -1,7 +1,6 @@
1
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
2
- const require_types = require('../types.cjs');
1
+ require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_types = require("../types.cjs");
3
3
  let _milaboratories_pl_client = require("@milaboratories/pl-client");
4
-
5
4
  //#region src/drivers/helpers/download_remote_handle.ts
6
5
  const remoteHandleRegex = /^blob\+remote:\/\/download\/(?<content>(?<resourceType>.+)\/(?<resourceVersion>.+?)\/(?<resourceId>\d+?)\/(?<size>\d+?))#(?<signature>.*)$/;
7
6
  function newRemoteHandle(rInfo, signer) {
@@ -27,9 +26,9 @@ function parseRemoteHandle(handle, signer) {
27
26
  size: Number(size)
28
27
  };
29
28
  }
30
-
31
29
  //#endregion
32
30
  exports.isRemoteBlobHandle = isRemoteBlobHandle;
33
31
  exports.newRemoteHandle = newRemoteHandle;
34
32
  exports.parseRemoteHandle = parseRemoteHandle;
33
+
35
34
  //# sourceMappingURL=download_remote_handle.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"download_remote_handle.cjs","names":["getSize"],"sources":["../../../src/drivers/helpers/download_remote_handle.ts"],"sourcesContent":["/** Handle of remote blob. This handle is issued as soon as the data becomes\n * available on the remote server. */\n\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport type { OnDemandBlobResourceSnapshot } from \"../types\";\nimport type { RemoteBlobHandle } from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\nimport { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport { getSize } from \"../types\";\n\n// https://regex101.com/r/Q4YdTa/5\nconst remoteHandleRegex =\n /^blob\\+remote:\\/\\/download\\/(?<content>(?<resourceType>.+)\\/(?<resourceVersion>.+?)\\/(?<resourceId>\\d+?)\\/(?<size>\\d+?))#(?<signature>.*)$/;\n\nexport function newRemoteHandle(\n rInfo: OnDemandBlobResourceSnapshot,\n signer: Signer,\n): RemoteBlobHandle {\n let content = `${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}/${getSize(rInfo)}`;\n\n return `blob+remote://download/${content}#${signer.sign(content)}` as RemoteBlobHandle;\n}\n\nexport function isRemoteBlobHandle(handle: string): handle is RemoteBlobHandle {\n return Boolean(handle.match(remoteHandleRegex));\n}\n\nexport function parseRemoteHandle(\n handle: RemoteBlobHandle,\n signer: Signer,\n): {\n info: ResourceInfo;\n size: number;\n} {\n const parsed = handle.match(remoteHandleRegex);\n if (parsed === null) {\n throw new Error(`Remote handle is malformed: ${handle}, matches: ${parsed}`);\n }\n\n const { content, resourceType, resourceVersion, resourceId, size, signature } = parsed.groups!;\n\n signer.verify(content, signature, `Signature verification failed for ${handle}`);\n\n return {\n info: {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n },\n size: Number(size),\n };\n}\n"],"mappings":";;;;;AAWA,MAAM,oBACJ;AAEF,SAAgB,gBACd,OACA,QACkB;CAClB,IAAI,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAGA,sBAAQ,MAAM;AAE5F,QAAO,0BAA0B,QAAQ,GAAG,OAAO,KAAK,QAAQ;;AAGlE,SAAgB,mBAAmB,QAA4C;AAC7E,QAAO,QAAQ,OAAO,MAAM,kBAAkB,CAAC;;AAGjD,SAAgB,kBACd,QACA,QAIA;CACA,MAAM,SAAS,OAAO,MAAM,kBAAkB;AAC9C,KAAI,WAAW,KACb,OAAM,IAAI,MAAM,+BAA+B,OAAO,aAAa,SAAS;CAG9E,MAAM,EAAE,SAAS,cAAc,iBAAiB,YAAY,MAAM,cAAc,OAAO;AAEvF,QAAO,OAAO,SAAS,WAAW,qCAAqC,SAAS;AAEhF,QAAO;EACL,MAAM;GACJ,sDAAuB,OAAO,WAAW,CAAC;GAC1C,MAAM;IAAE,MAAM;IAAc,SAAS;IAAiB;GACvD;EACD,MAAM,OAAO,KAAK;EACnB"}
1
+ {"version":3,"file":"download_remote_handle.cjs","names":["getSize"],"sources":["../../../src/drivers/helpers/download_remote_handle.ts"],"sourcesContent":["/** Handle of remote blob. This handle is issued as soon as the data becomes\n * available on the remote server. */\n\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport type { OnDemandBlobResourceSnapshot } from \"../types\";\nimport type { RemoteBlobHandle } from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\nimport { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport { getSize } from \"../types\";\n\n// https://regex101.com/r/Q4YdTa/5\nconst remoteHandleRegex =\n /^blob\\+remote:\\/\\/download\\/(?<content>(?<resourceType>.+)\\/(?<resourceVersion>.+?)\\/(?<resourceId>\\d+?)\\/(?<size>\\d+?))#(?<signature>.*)$/;\n\nexport function newRemoteHandle(\n rInfo: OnDemandBlobResourceSnapshot,\n signer: Signer,\n): RemoteBlobHandle {\n let content = `${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}/${getSize(rInfo)}`;\n\n return `blob+remote://download/${content}#${signer.sign(content)}` as RemoteBlobHandle;\n}\n\nexport function isRemoteBlobHandle(handle: string): handle is RemoteBlobHandle {\n return Boolean(handle.match(remoteHandleRegex));\n}\n\nexport function parseRemoteHandle(\n handle: RemoteBlobHandle,\n signer: Signer,\n): {\n info: ResourceInfo;\n size: number;\n} {\n const parsed = handle.match(remoteHandleRegex);\n if (parsed === null) {\n throw new Error(`Remote handle is malformed: ${handle}, matches: ${parsed}`);\n }\n\n const { content, resourceType, resourceVersion, resourceId, size, signature } = parsed.groups!;\n\n signer.verify(content, signature, `Signature verification failed for ${handle}`);\n\n return {\n info: {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n },\n size: Number(size),\n };\n}\n"],"mappings":";;;;AAWA,MAAM,oBACJ;AAEF,SAAgB,gBACd,OACA,QACkB;CAClB,IAAI,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAGA,cAAAA,QAAQ,MAAM;AAE5F,QAAO,0BAA0B,QAAQ,GAAG,OAAO,KAAK,QAAQ;;AAGlE,SAAgB,mBAAmB,QAA4C;AAC7E,QAAO,QAAQ,OAAO,MAAM,kBAAkB,CAAC;;AAGjD,SAAgB,kBACd,QACA,QAIA;CACA,MAAM,SAAS,OAAO,MAAM,kBAAkB;AAC9C,KAAI,WAAW,KACb,OAAM,IAAI,MAAM,+BAA+B,OAAO,aAAa,SAAS;CAG9E,MAAM,EAAE,SAAS,cAAc,iBAAiB,YAAY,MAAM,cAAc,OAAO;AAEvF,QAAO,OAAO,SAAS,WAAW,qCAAqC,SAAS;AAEhF,QAAO;EACL,MAAM;GACJ,KAAA,GAAA,0BAAA,oBAAuB,OAAO,WAAW,CAAC;GAC1C,MAAM;IAAE,MAAM;IAAc,SAAS;IAAiB;GACvD;EACD,MAAM,OAAO,KAAK;EACnB"}
@@ -1,6 +1,5 @@
1
1
  import { getSize } from "../types.js";
2
2
  import { bigintToResourceId } from "@milaboratories/pl-client";
3
-
4
3
  //#region src/drivers/helpers/download_remote_handle.ts
5
4
  const remoteHandleRegex = /^blob\+remote:\/\/download\/(?<content>(?<resourceType>.+)\/(?<resourceVersion>.+?)\/(?<resourceId>\d+?)\/(?<size>\d+?))#(?<signature>.*)$/;
6
5
  function newRemoteHandle(rInfo, signer) {
@@ -26,7 +25,7 @@ function parseRemoteHandle(handle, signer) {
26
25
  size: Number(size)
27
26
  };
28
27
  }
29
-
30
28
  //#endregion
31
29
  export { isRemoteBlobHandle, newRemoteHandle, parseRemoteHandle };
30
+
32
31
  //# sourceMappingURL=download_remote_handle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"download_remote_handle.js","names":[],"sources":["../../../src/drivers/helpers/download_remote_handle.ts"],"sourcesContent":["/** Handle of remote blob. This handle is issued as soon as the data becomes\n * available on the remote server. */\n\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport type { OnDemandBlobResourceSnapshot } from \"../types\";\nimport type { RemoteBlobHandle } from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\nimport { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport { getSize } from \"../types\";\n\n// https://regex101.com/r/Q4YdTa/5\nconst remoteHandleRegex =\n /^blob\\+remote:\\/\\/download\\/(?<content>(?<resourceType>.+)\\/(?<resourceVersion>.+?)\\/(?<resourceId>\\d+?)\\/(?<size>\\d+?))#(?<signature>.*)$/;\n\nexport function newRemoteHandle(\n rInfo: OnDemandBlobResourceSnapshot,\n signer: Signer,\n): RemoteBlobHandle {\n let content = `${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}/${getSize(rInfo)}`;\n\n return `blob+remote://download/${content}#${signer.sign(content)}` as RemoteBlobHandle;\n}\n\nexport function isRemoteBlobHandle(handle: string): handle is RemoteBlobHandle {\n return Boolean(handle.match(remoteHandleRegex));\n}\n\nexport function parseRemoteHandle(\n handle: RemoteBlobHandle,\n signer: Signer,\n): {\n info: ResourceInfo;\n size: number;\n} {\n const parsed = handle.match(remoteHandleRegex);\n if (parsed === null) {\n throw new Error(`Remote handle is malformed: ${handle}, matches: ${parsed}`);\n }\n\n const { content, resourceType, resourceVersion, resourceId, size, signature } = parsed.groups!;\n\n signer.verify(content, signature, `Signature verification failed for ${handle}`);\n\n return {\n info: {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n },\n size: Number(size),\n };\n}\n"],"mappings":";;;;AAWA,MAAM,oBACJ;AAEF,SAAgB,gBACd,OACA,QACkB;CAClB,IAAI,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAG,QAAQ,MAAM;AAE5F,QAAO,0BAA0B,QAAQ,GAAG,OAAO,KAAK,QAAQ;;AAGlE,SAAgB,mBAAmB,QAA4C;AAC7E,QAAO,QAAQ,OAAO,MAAM,kBAAkB,CAAC;;AAGjD,SAAgB,kBACd,QACA,QAIA;CACA,MAAM,SAAS,OAAO,MAAM,kBAAkB;AAC9C,KAAI,WAAW,KACb,OAAM,IAAI,MAAM,+BAA+B,OAAO,aAAa,SAAS;CAG9E,MAAM,EAAE,SAAS,cAAc,iBAAiB,YAAY,MAAM,cAAc,OAAO;AAEvF,QAAO,OAAO,SAAS,WAAW,qCAAqC,SAAS;AAEhF,QAAO;EACL,MAAM;GACJ,IAAI,mBAAmB,OAAO,WAAW,CAAC;GAC1C,MAAM;IAAE,MAAM;IAAc,SAAS;IAAiB;GACvD;EACD,MAAM,OAAO,KAAK;EACnB"}
1
+ {"version":3,"file":"download_remote_handle.js","names":[],"sources":["../../../src/drivers/helpers/download_remote_handle.ts"],"sourcesContent":["/** Handle of remote blob. This handle is issued as soon as the data becomes\n * available on the remote server. */\n\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport type { OnDemandBlobResourceSnapshot } from \"../types\";\nimport type { RemoteBlobHandle } from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\nimport { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport { getSize } from \"../types\";\n\n// https://regex101.com/r/Q4YdTa/5\nconst remoteHandleRegex =\n /^blob\\+remote:\\/\\/download\\/(?<content>(?<resourceType>.+)\\/(?<resourceVersion>.+?)\\/(?<resourceId>\\d+?)\\/(?<size>\\d+?))#(?<signature>.*)$/;\n\nexport function newRemoteHandle(\n rInfo: OnDemandBlobResourceSnapshot,\n signer: Signer,\n): RemoteBlobHandle {\n let content = `${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}/${getSize(rInfo)}`;\n\n return `blob+remote://download/${content}#${signer.sign(content)}` as RemoteBlobHandle;\n}\n\nexport function isRemoteBlobHandle(handle: string): handle is RemoteBlobHandle {\n return Boolean(handle.match(remoteHandleRegex));\n}\n\nexport function parseRemoteHandle(\n handle: RemoteBlobHandle,\n signer: Signer,\n): {\n info: ResourceInfo;\n size: number;\n} {\n const parsed = handle.match(remoteHandleRegex);\n if (parsed === null) {\n throw new Error(`Remote handle is malformed: ${handle}, matches: ${parsed}`);\n }\n\n const { content, resourceType, resourceVersion, resourceId, size, signature } = parsed.groups!;\n\n signer.verify(content, signature, `Signature verification failed for ${handle}`);\n\n return {\n info: {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n },\n size: Number(size),\n };\n}\n"],"mappings":";;;AAWA,MAAM,oBACJ;AAEF,SAAgB,gBACd,OACA,QACkB;CAClB,IAAI,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAG,QAAQ,MAAM;AAE5F,QAAO,0BAA0B,QAAQ,GAAG,OAAO,KAAK,QAAQ;;AAGlE,SAAgB,mBAAmB,QAA4C;AAC7E,QAAO,QAAQ,OAAO,MAAM,kBAAkB,CAAC;;AAGjD,SAAgB,kBACd,QACA,QAIA;CACA,MAAM,SAAS,OAAO,MAAM,kBAAkB;AAC9C,KAAI,WAAW,KACb,OAAM,IAAI,MAAM,+BAA+B,OAAO,aAAa,SAAS;CAG9E,MAAM,EAAE,SAAS,cAAc,iBAAiB,YAAY,MAAM,cAAc,OAAO;AAEvF,QAAO,OAAO,SAAS,WAAW,qCAAqC,SAAS;AAEhF,QAAO;EACL,MAAM;GACJ,IAAI,mBAAmB,OAAO,WAAW,CAAC;GAC1C,MAAM;IAAE,MAAM;IAAc,SAAS;IAAiB;GACvD;EACD,MAAM,OAAO,KAAK;EACnB"}
@@ -1,6 +1,5 @@
1
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
1
+ require("../../_virtual/_rolldown/runtime.cjs");
2
2
  let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
3
-
4
3
  //#region src/drivers/helpers/files_cache.ts
5
4
  /** Holds counters of how many callers need the file.
6
5
  * If some counters become zero and a cache size exceeds a soft limit,
@@ -51,7 +50,7 @@ var FilesCache = class {
51
50
  this.totalSizeBytes -= file.size;
52
51
  }
53
52
  };
54
-
55
53
  //#endregion
56
54
  exports.FilesCache = FilesCache;
55
+
57
56
  //# sourceMappingURL=files_cache.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"files_cache.cjs","names":[],"sources":["../../../src/drivers/helpers/files_cache.ts"],"sourcesContent":["import type { CallersCounter } from \"@milaboratories/ts-helpers\";\nimport { mapEntries, mapGet } from \"@milaboratories/ts-helpers\";\n\ntype PathLike = string;\n\nexport interface CachedFile {\n /** Size in bytes. */\n size: number;\n path: PathLike;\n counter: CallersCounter;\n}\n\n/** Holds counters of how many callers need the file.\n * If some counters become zero and a cache size exceeds a soft limit,\n * remove not needed blobs one by one.\n * If all the files are needed, do nothing. */\nexport class FilesCache<T extends CachedFile> {\n private cache: Map<PathLike, T> = new Map();\n private totalSizeBytes: number = 0;\n\n constructor(private readonly softSizeBytes: number) {}\n\n existsFile(path: PathLike): boolean {\n return this.cache.get(path) != undefined;\n }\n\n getFile(path: PathLike, callerId: string): T | undefined {\n const file = this.cache.get(path);\n if (file != undefined) {\n file.counter.inc(callerId);\n }\n\n return file;\n }\n\n /** Decrements a counter in a cache and if we exceeds\n * a soft limit, removes files with zero counters. */\n removeFile(path: PathLike, callerId: string): T[] {\n mapGet(this.cache, path).counter.dec(callerId);\n return this.toDelete();\n }\n\n /** Returns what results should be deleted to comply with the soft limit. */\n toDelete(): T[] {\n if (this.totalSizeBytes <= this.softSizeBytes) return [];\n\n const result: T[] = [];\n let freedBytes = 0;\n\n mapEntries(this.cache)\n .filter(([_, file]: [string, T]) => file.counter.isZero())\n .forEach(([path, _]) => {\n if (this.totalSizeBytes - freedBytes <= this.softSizeBytes) {\n return;\n }\n\n const file = mapGet(this.cache, path);\n freedBytes += file.size;\n result.push(file);\n });\n\n return result;\n }\n\n addCache(file: T, callerId: string) {\n const created = this.cache.get(file.path) == undefined;\n this.cache.set(file.path, file);\n file.counter.inc(callerId);\n\n if (file.size < 0) {\n throw new Error(`empty sizeBytes: ${file}`);\n }\n\n if (created) {\n this.totalSizeBytes += file.size;\n }\n }\n\n removeCache(file: T) {\n this.cache.delete(file.path);\n this.totalSizeBytes -= file.size;\n }\n}\n"],"mappings":";;;;;;;;AAgBA,IAAa,aAAb,MAA8C;CAC5C,AAAQ,wBAA0B,IAAI,KAAK;CAC3C,AAAQ,iBAAyB;CAEjC,YAAY,AAAiB,eAAuB;EAAvB;;CAE7B,WAAW,MAAyB;AAClC,SAAO,KAAK,MAAM,IAAI,KAAK,IAAI;;CAGjC,QAAQ,MAAgB,UAAiC;EACvD,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;AACjC,MAAI,QAAQ,OACV,MAAK,QAAQ,IAAI,SAAS;AAG5B,SAAO;;;;CAKT,WAAW,MAAgB,UAAuB;AAChD,yCAAO,KAAK,OAAO,KAAK,CAAC,QAAQ,IAAI,SAAS;AAC9C,SAAO,KAAK,UAAU;;;CAIxB,WAAgB;AACd,MAAI,KAAK,kBAAkB,KAAK,cAAe,QAAO,EAAE;EAExD,MAAM,SAAc,EAAE;EACtB,IAAI,aAAa;AAEjB,6CAAW,KAAK,MAAM,CACnB,QAAQ,CAAC,GAAG,UAAuB,KAAK,QAAQ,QAAQ,CAAC,CACzD,SAAS,CAAC,MAAM,OAAO;AACtB,OAAI,KAAK,iBAAiB,cAAc,KAAK,cAC3C;GAGF,MAAM,8CAAc,KAAK,OAAO,KAAK;AACrC,iBAAc,KAAK;AACnB,UAAO,KAAK,KAAK;IACjB;AAEJ,SAAO;;CAGT,SAAS,MAAS,UAAkB;EAClC,MAAM,UAAU,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI;AAC7C,OAAK,MAAM,IAAI,KAAK,MAAM,KAAK;AAC/B,OAAK,QAAQ,IAAI,SAAS;AAE1B,MAAI,KAAK,OAAO,EACd,OAAM,IAAI,MAAM,oBAAoB,OAAO;AAG7C,MAAI,QACF,MAAK,kBAAkB,KAAK;;CAIhC,YAAY,MAAS;AACnB,OAAK,MAAM,OAAO,KAAK,KAAK;AAC5B,OAAK,kBAAkB,KAAK"}
1
+ {"version":3,"file":"files_cache.cjs","names":[],"sources":["../../../src/drivers/helpers/files_cache.ts"],"sourcesContent":["import type { CallersCounter } from \"@milaboratories/ts-helpers\";\nimport { mapEntries, mapGet } from \"@milaboratories/ts-helpers\";\n\ntype PathLike = string;\n\nexport interface CachedFile {\n /** Size in bytes. */\n size: number;\n path: PathLike;\n counter: CallersCounter;\n}\n\n/** Holds counters of how many callers need the file.\n * If some counters become zero and a cache size exceeds a soft limit,\n * remove not needed blobs one by one.\n * If all the files are needed, do nothing. */\nexport class FilesCache<T extends CachedFile> {\n private cache: Map<PathLike, T> = new Map();\n private totalSizeBytes: number = 0;\n\n constructor(private readonly softSizeBytes: number) {}\n\n existsFile(path: PathLike): boolean {\n return this.cache.get(path) != undefined;\n }\n\n getFile(path: PathLike, callerId: string): T | undefined {\n const file = this.cache.get(path);\n if (file != undefined) {\n file.counter.inc(callerId);\n }\n\n return file;\n }\n\n /** Decrements a counter in a cache and if we exceeds\n * a soft limit, removes files with zero counters. */\n removeFile(path: PathLike, callerId: string): T[] {\n mapGet(this.cache, path).counter.dec(callerId);\n return this.toDelete();\n }\n\n /** Returns what results should be deleted to comply with the soft limit. */\n toDelete(): T[] {\n if (this.totalSizeBytes <= this.softSizeBytes) return [];\n\n const result: T[] = [];\n let freedBytes = 0;\n\n mapEntries(this.cache)\n .filter(([_, file]: [string, T]) => file.counter.isZero())\n .forEach(([path, _]) => {\n if (this.totalSizeBytes - freedBytes <= this.softSizeBytes) {\n return;\n }\n\n const file = mapGet(this.cache, path);\n freedBytes += file.size;\n result.push(file);\n });\n\n return result;\n }\n\n addCache(file: T, callerId: string) {\n const created = this.cache.get(file.path) == undefined;\n this.cache.set(file.path, file);\n file.counter.inc(callerId);\n\n if (file.size < 0) {\n throw new Error(`empty sizeBytes: ${file}`);\n }\n\n if (created) {\n this.totalSizeBytes += file.size;\n }\n }\n\n removeCache(file: T) {\n this.cache.delete(file.path);\n this.totalSizeBytes -= file.size;\n }\n}\n"],"mappings":";;;;;;;AAgBA,IAAa,aAAb,MAA8C;CAC5C,wBAAkC,IAAI,KAAK;CAC3C,iBAAiC;CAEjC,YAAY,eAAwC;AAAvB,OAAA,gBAAA;;CAE7B,WAAW,MAAyB;AAClC,SAAO,KAAK,MAAM,IAAI,KAAK,IAAI,KAAA;;CAGjC,QAAQ,MAAgB,UAAiC;EACvD,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;AACjC,MAAI,QAAQ,KAAA,EACV,MAAK,QAAQ,IAAI,SAAS;AAG5B,SAAO;;;;CAKT,WAAW,MAAgB,UAAuB;AAChD,GAAA,GAAA,2BAAA,QAAO,KAAK,OAAO,KAAK,CAAC,QAAQ,IAAI,SAAS;AAC9C,SAAO,KAAK,UAAU;;;CAIxB,WAAgB;AACd,MAAI,KAAK,kBAAkB,KAAK,cAAe,QAAO,EAAE;EAExD,MAAM,SAAc,EAAE;EACtB,IAAI,aAAa;AAEjB,GAAA,GAAA,2BAAA,YAAW,KAAK,MAAM,CACnB,QAAQ,CAAC,GAAG,UAAuB,KAAK,QAAQ,QAAQ,CAAC,CACzD,SAAS,CAAC,MAAM,OAAO;AACtB,OAAI,KAAK,iBAAiB,cAAc,KAAK,cAC3C;GAGF,MAAM,QAAA,GAAA,2BAAA,QAAc,KAAK,OAAO,KAAK;AACrC,iBAAc,KAAK;AACnB,UAAO,KAAK,KAAK;IACjB;AAEJ,SAAO;;CAGT,SAAS,MAAS,UAAkB;EAClC,MAAM,UAAU,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI,KAAA;AAC7C,OAAK,MAAM,IAAI,KAAK,MAAM,KAAK;AAC/B,OAAK,QAAQ,IAAI,SAAS;AAE1B,MAAI,KAAK,OAAO,EACd,OAAM,IAAI,MAAM,oBAAoB,OAAO;AAG7C,MAAI,QACF,MAAK,kBAAkB,KAAK;;CAIhC,YAAY,MAAS;AACnB,OAAK,MAAM,OAAO,KAAK,KAAK;AAC5B,OAAK,kBAAkB,KAAK"}
@@ -1,5 +1,4 @@
1
1
  import { mapEntries, mapGet } from "@milaboratories/ts-helpers";
2
-
3
2
  //#region src/drivers/helpers/files_cache.ts
4
3
  /** Holds counters of how many callers need the file.
5
4
  * If some counters become zero and a cache size exceeds a soft limit,
@@ -50,7 +49,7 @@ var FilesCache = class {
50
49
  this.totalSizeBytes -= file.size;
51
50
  }
52
51
  };
53
-
54
52
  //#endregion
55
53
  export { FilesCache };
54
+
56
55
  //# sourceMappingURL=files_cache.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"files_cache.js","names":[],"sources":["../../../src/drivers/helpers/files_cache.ts"],"sourcesContent":["import type { CallersCounter } from \"@milaboratories/ts-helpers\";\nimport { mapEntries, mapGet } from \"@milaboratories/ts-helpers\";\n\ntype PathLike = string;\n\nexport interface CachedFile {\n /** Size in bytes. */\n size: number;\n path: PathLike;\n counter: CallersCounter;\n}\n\n/** Holds counters of how many callers need the file.\n * If some counters become zero and a cache size exceeds a soft limit,\n * remove not needed blobs one by one.\n * If all the files are needed, do nothing. */\nexport class FilesCache<T extends CachedFile> {\n private cache: Map<PathLike, T> = new Map();\n private totalSizeBytes: number = 0;\n\n constructor(private readonly softSizeBytes: number) {}\n\n existsFile(path: PathLike): boolean {\n return this.cache.get(path) != undefined;\n }\n\n getFile(path: PathLike, callerId: string): T | undefined {\n const file = this.cache.get(path);\n if (file != undefined) {\n file.counter.inc(callerId);\n }\n\n return file;\n }\n\n /** Decrements a counter in a cache and if we exceeds\n * a soft limit, removes files with zero counters. */\n removeFile(path: PathLike, callerId: string): T[] {\n mapGet(this.cache, path).counter.dec(callerId);\n return this.toDelete();\n }\n\n /** Returns what results should be deleted to comply with the soft limit. */\n toDelete(): T[] {\n if (this.totalSizeBytes <= this.softSizeBytes) return [];\n\n const result: T[] = [];\n let freedBytes = 0;\n\n mapEntries(this.cache)\n .filter(([_, file]: [string, T]) => file.counter.isZero())\n .forEach(([path, _]) => {\n if (this.totalSizeBytes - freedBytes <= this.softSizeBytes) {\n return;\n }\n\n const file = mapGet(this.cache, path);\n freedBytes += file.size;\n result.push(file);\n });\n\n return result;\n }\n\n addCache(file: T, callerId: string) {\n const created = this.cache.get(file.path) == undefined;\n this.cache.set(file.path, file);\n file.counter.inc(callerId);\n\n if (file.size < 0) {\n throw new Error(`empty sizeBytes: ${file}`);\n }\n\n if (created) {\n this.totalSizeBytes += file.size;\n }\n }\n\n removeCache(file: T) {\n this.cache.delete(file.path);\n this.totalSizeBytes -= file.size;\n }\n}\n"],"mappings":";;;;;;;AAgBA,IAAa,aAAb,MAA8C;CAC5C,AAAQ,wBAA0B,IAAI,KAAK;CAC3C,AAAQ,iBAAyB;CAEjC,YAAY,AAAiB,eAAuB;EAAvB;;CAE7B,WAAW,MAAyB;AAClC,SAAO,KAAK,MAAM,IAAI,KAAK,IAAI;;CAGjC,QAAQ,MAAgB,UAAiC;EACvD,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;AACjC,MAAI,QAAQ,OACV,MAAK,QAAQ,IAAI,SAAS;AAG5B,SAAO;;;;CAKT,WAAW,MAAgB,UAAuB;AAChD,SAAO,KAAK,OAAO,KAAK,CAAC,QAAQ,IAAI,SAAS;AAC9C,SAAO,KAAK,UAAU;;;CAIxB,WAAgB;AACd,MAAI,KAAK,kBAAkB,KAAK,cAAe,QAAO,EAAE;EAExD,MAAM,SAAc,EAAE;EACtB,IAAI,aAAa;AAEjB,aAAW,KAAK,MAAM,CACnB,QAAQ,CAAC,GAAG,UAAuB,KAAK,QAAQ,QAAQ,CAAC,CACzD,SAAS,CAAC,MAAM,OAAO;AACtB,OAAI,KAAK,iBAAiB,cAAc,KAAK,cAC3C;GAGF,MAAM,OAAO,OAAO,KAAK,OAAO,KAAK;AACrC,iBAAc,KAAK;AACnB,UAAO,KAAK,KAAK;IACjB;AAEJ,SAAO;;CAGT,SAAS,MAAS,UAAkB;EAClC,MAAM,UAAU,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI;AAC7C,OAAK,MAAM,IAAI,KAAK,MAAM,KAAK;AAC/B,OAAK,QAAQ,IAAI,SAAS;AAE1B,MAAI,KAAK,OAAO,EACd,OAAM,IAAI,MAAM,oBAAoB,OAAO;AAG7C,MAAI,QACF,MAAK,kBAAkB,KAAK;;CAIhC,YAAY,MAAS;AACnB,OAAK,MAAM,OAAO,KAAK,KAAK;AAC5B,OAAK,kBAAkB,KAAK"}
1
+ {"version":3,"file":"files_cache.js","names":[],"sources":["../../../src/drivers/helpers/files_cache.ts"],"sourcesContent":["import type { CallersCounter } from \"@milaboratories/ts-helpers\";\nimport { mapEntries, mapGet } from \"@milaboratories/ts-helpers\";\n\ntype PathLike = string;\n\nexport interface CachedFile {\n /** Size in bytes. */\n size: number;\n path: PathLike;\n counter: CallersCounter;\n}\n\n/** Holds counters of how many callers need the file.\n * If some counters become zero and a cache size exceeds a soft limit,\n * remove not needed blobs one by one.\n * If all the files are needed, do nothing. */\nexport class FilesCache<T extends CachedFile> {\n private cache: Map<PathLike, T> = new Map();\n private totalSizeBytes: number = 0;\n\n constructor(private readonly softSizeBytes: number) {}\n\n existsFile(path: PathLike): boolean {\n return this.cache.get(path) != undefined;\n }\n\n getFile(path: PathLike, callerId: string): T | undefined {\n const file = this.cache.get(path);\n if (file != undefined) {\n file.counter.inc(callerId);\n }\n\n return file;\n }\n\n /** Decrements a counter in a cache and if we exceeds\n * a soft limit, removes files with zero counters. */\n removeFile(path: PathLike, callerId: string): T[] {\n mapGet(this.cache, path).counter.dec(callerId);\n return this.toDelete();\n }\n\n /** Returns what results should be deleted to comply with the soft limit. */\n toDelete(): T[] {\n if (this.totalSizeBytes <= this.softSizeBytes) return [];\n\n const result: T[] = [];\n let freedBytes = 0;\n\n mapEntries(this.cache)\n .filter(([_, file]: [string, T]) => file.counter.isZero())\n .forEach(([path, _]) => {\n if (this.totalSizeBytes - freedBytes <= this.softSizeBytes) {\n return;\n }\n\n const file = mapGet(this.cache, path);\n freedBytes += file.size;\n result.push(file);\n });\n\n return result;\n }\n\n addCache(file: T, callerId: string) {\n const created = this.cache.get(file.path) == undefined;\n this.cache.set(file.path, file);\n file.counter.inc(callerId);\n\n if (file.size < 0) {\n throw new Error(`empty sizeBytes: ${file}`);\n }\n\n if (created) {\n this.totalSizeBytes += file.size;\n }\n }\n\n removeCache(file: T) {\n this.cache.delete(file.path);\n this.totalSizeBytes -= file.size;\n }\n}\n"],"mappings":";;;;;;AAgBA,IAAa,aAAb,MAA8C;CAC5C,wBAAkC,IAAI,KAAK;CAC3C,iBAAiC;CAEjC,YAAY,eAAwC;AAAvB,OAAA,gBAAA;;CAE7B,WAAW,MAAyB;AAClC,SAAO,KAAK,MAAM,IAAI,KAAK,IAAI,KAAA;;CAGjC,QAAQ,MAAgB,UAAiC;EACvD,MAAM,OAAO,KAAK,MAAM,IAAI,KAAK;AACjC,MAAI,QAAQ,KAAA,EACV,MAAK,QAAQ,IAAI,SAAS;AAG5B,SAAO;;;;CAKT,WAAW,MAAgB,UAAuB;AAChD,SAAO,KAAK,OAAO,KAAK,CAAC,QAAQ,IAAI,SAAS;AAC9C,SAAO,KAAK,UAAU;;;CAIxB,WAAgB;AACd,MAAI,KAAK,kBAAkB,KAAK,cAAe,QAAO,EAAE;EAExD,MAAM,SAAc,EAAE;EACtB,IAAI,aAAa;AAEjB,aAAW,KAAK,MAAM,CACnB,QAAQ,CAAC,GAAG,UAAuB,KAAK,QAAQ,QAAQ,CAAC,CACzD,SAAS,CAAC,MAAM,OAAO;AACtB,OAAI,KAAK,iBAAiB,cAAc,KAAK,cAC3C;GAGF,MAAM,OAAO,OAAO,KAAK,OAAO,KAAK;AACrC,iBAAc,KAAK;AACnB,UAAO,KAAK,KAAK;IACjB;AAEJ,SAAO;;CAGT,SAAS,MAAS,UAAkB;EAClC,MAAM,UAAU,KAAK,MAAM,IAAI,KAAK,KAAK,IAAI,KAAA;AAC7C,OAAK,MAAM,IAAI,KAAK,MAAM,KAAK;AAC/B,OAAK,QAAQ,IAAI,SAAS;AAE1B,MAAI,KAAK,OAAO,EACd,OAAM,IAAI,MAAM,oBAAoB,OAAO;AAG7C,MAAI,QACF,MAAK,kBAAkB,KAAK;;CAIhC,YAAY,MAAS;AACnB,OAAK,MAAM,OAAO,KAAK,KAAK;AAC5B,OAAK,kBAAkB,KAAK"}
@@ -1,4 +1,3 @@
1
-
2
1
  //#region src/drivers/helpers/helpers.ts
3
2
  /** Throws when a driver gets a resource with a wrong resource type. */
4
3
  var WrongResourceTypeError = class extends Error {
@@ -23,8 +22,8 @@ var Updater = class {
23
22
  })();
24
23
  }
25
24
  };
26
-
27
25
  //#endregion
28
26
  exports.Updater = Updater;
29
27
  exports.WrongResourceTypeError = WrongResourceTypeError;
28
+
30
29
  //# sourceMappingURL=helpers.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.cjs","names":[],"sources":["../../../src/drivers/helpers/helpers.ts"],"sourcesContent":["/** Throws when a driver gets a resource with a wrong resource type. */\nexport class WrongResourceTypeError extends Error {\n name = \"WrongResourceTypeError\";\n}\n\n/** Updater incorporates a pattern when someone wants to run a callback\n * that updates something only when it's not already running. */\nexport class Updater {\n private updating: Promise<void> | undefined;\n\n constructor(private readonly onUpdate: () => Promise<void>) {}\n\n schedule() {\n if (this.updating == undefined) {\n this.updating = (async () => {\n try {\n await this.onUpdate();\n } catch (e) {\n console.log(`error while updating in Updater: ${e}`);\n } finally {\n this.updating = undefined;\n }\n })();\n }\n }\n}\n"],"mappings":";;;AACA,IAAa,yBAAb,cAA4C,MAAM;CAChD,OAAO;;;;AAKT,IAAa,UAAb,MAAqB;CACnB,AAAQ;CAER,YAAY,AAAiB,UAA+B;EAA/B;;CAE7B,WAAW;AACT,MAAI,KAAK,YAAY,OACnB,MAAK,YAAY,YAAY;AAC3B,OAAI;AACF,UAAM,KAAK,UAAU;YACd,GAAG;AACV,YAAQ,IAAI,oCAAoC,IAAI;aAC5C;AACR,SAAK,WAAW;;MAEhB"}
1
+ {"version":3,"file":"helpers.cjs","names":[],"sources":["../../../src/drivers/helpers/helpers.ts"],"sourcesContent":["/** Throws when a driver gets a resource with a wrong resource type. */\nexport class WrongResourceTypeError extends Error {\n name = \"WrongResourceTypeError\";\n}\n\n/** Updater incorporates a pattern when someone wants to run a callback\n * that updates something only when it's not already running. */\nexport class Updater {\n private updating: Promise<void> | undefined;\n\n constructor(private readonly onUpdate: () => Promise<void>) {}\n\n schedule() {\n if (this.updating == undefined) {\n this.updating = (async () => {\n try {\n await this.onUpdate();\n } catch (e) {\n console.log(`error while updating in Updater: ${e}`);\n } finally {\n this.updating = undefined;\n }\n })();\n }\n }\n}\n"],"mappings":";;AACA,IAAa,yBAAb,cAA4C,MAAM;CAChD,OAAO;;;;AAKT,IAAa,UAAb,MAAqB;CACnB;CAEA,YAAY,UAAgD;AAA/B,OAAA,WAAA;;CAE7B,WAAW;AACT,MAAI,KAAK,YAAY,KAAA,EACnB,MAAK,YAAY,YAAY;AAC3B,OAAI;AACF,UAAM,KAAK,UAAU;YACd,GAAG;AACV,YAAQ,IAAI,oCAAoC,IAAI;aAC5C;AACR,SAAK,WAAW,KAAA;;MAEhB"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","names":[],"sources":["../../../src/drivers/helpers/helpers.ts"],"mappings":";;cACa,sBAAA,SAA+B,KAAA;EAC1C,IAAA;AAAA;;;cAKW,OAAA;EAAA,iBAGkB,QAAA;EAAA,QAFrB,QAAA;cAEqB,QAAA,QAAgB,OAAA;EAE7C,QAAA,CAAA;AAAA"}
@@ -22,7 +22,7 @@ var Updater = class {
22
22
  })();
23
23
  }
24
24
  };
25
-
26
25
  //#endregion
27
26
  export { Updater, WrongResourceTypeError };
27
+
28
28
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","names":[],"sources":["../../../src/drivers/helpers/helpers.ts"],"sourcesContent":["/** Throws when a driver gets a resource with a wrong resource type. */\nexport class WrongResourceTypeError extends Error {\n name = \"WrongResourceTypeError\";\n}\n\n/** Updater incorporates a pattern when someone wants to run a callback\n * that updates something only when it's not already running. */\nexport class Updater {\n private updating: Promise<void> | undefined;\n\n constructor(private readonly onUpdate: () => Promise<void>) {}\n\n schedule() {\n if (this.updating == undefined) {\n this.updating = (async () => {\n try {\n await this.onUpdate();\n } catch (e) {\n console.log(`error while updating in Updater: ${e}`);\n } finally {\n this.updating = undefined;\n }\n })();\n }\n }\n}\n"],"mappings":";;AACA,IAAa,yBAAb,cAA4C,MAAM;CAChD,OAAO;;;;AAKT,IAAa,UAAb,MAAqB;CACnB,AAAQ;CAER,YAAY,AAAiB,UAA+B;EAA/B;;CAE7B,WAAW;AACT,MAAI,KAAK,YAAY,OACnB,MAAK,YAAY,YAAY;AAC3B,OAAI;AACF,UAAM,KAAK,UAAU;YACd,GAAG;AACV,YAAQ,IAAI,oCAAoC,IAAI;aAC5C;AACR,SAAK,WAAW;;MAEhB"}
1
+ {"version":3,"file":"helpers.js","names":[],"sources":["../../../src/drivers/helpers/helpers.ts"],"sourcesContent":["/** Throws when a driver gets a resource with a wrong resource type. */\nexport class WrongResourceTypeError extends Error {\n name = \"WrongResourceTypeError\";\n}\n\n/** Updater incorporates a pattern when someone wants to run a callback\n * that updates something only when it's not already running. */\nexport class Updater {\n private updating: Promise<void> | undefined;\n\n constructor(private readonly onUpdate: () => Promise<void>) {}\n\n schedule() {\n if (this.updating == undefined) {\n this.updating = (async () => {\n try {\n await this.onUpdate();\n } catch (e) {\n console.log(`error while updating in Updater: ${e}`);\n } finally {\n this.updating = undefined;\n }\n })();\n }\n }\n}\n"],"mappings":";;AACA,IAAa,yBAAb,cAA4C,MAAM;CAChD,OAAO;;;;AAKT,IAAa,UAAb,MAAqB;CACnB;CAEA,YAAY,UAAgD;AAA/B,OAAA,WAAA;;CAE7B,WAAW;AACT,MAAI,KAAK,YAAY,KAAA,EACnB,MAAK,YAAY,YAAY;AAC3B,OAAI;AACF,UAAM,KAAK,UAAU;YACd,GAAG;AACV,YAAQ,IAAI,oCAAoC,IAAI;aAC5C;AACR,SAAK,WAAW,KAAA;;MAEhB"}
@@ -1,6 +1,5 @@
1
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
1
+ require("../../_virtual/_rolldown/runtime.cjs");
2
2
  let _milaboratories_pl_client = require("@milaboratories/pl-client");
3
-
4
3
  //#region src/drivers/helpers/logs_handle.ts
5
4
  function newLogHandle(live, rInfo) {
6
5
  if (live) return `log+live://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}`;
@@ -33,9 +32,9 @@ function getResourceInfoFromLogHandle(handle) {
33
32
  }
34
33
  };
35
34
  }
36
-
37
35
  //#endregion
38
36
  exports.getResourceInfoFromLogHandle = getResourceInfoFromLogHandle;
39
37
  exports.isLiveLogHandle = isLiveLogHandle;
40
38
  exports.newLogHandle = newLogHandle;
39
+
41
40
  //# sourceMappingURL=logs_handle.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs_handle.cjs","names":[],"sources":["../../../src/drivers/helpers/logs_handle.ts"],"sourcesContent":["/** Handle of logs. This handle should be passed\n * to the driver for retrieving logs. */\n\nimport type { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\n\nexport function newLogHandle(live: boolean, rInfo: ResourceInfo): sdk.AnyLogHandle {\n if (live) {\n return `log+live://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.LiveLogHandle;\n }\n\n return `log+ready://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.ReadyLogHandle;\n}\n\n/** Handle of the live logs of a program.\n * The resource that represents a log can be deleted,\n * in this case the handle should be refreshed. */\n\nexport const liveHandleRegex =\n /^log\\+live:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isLiveLogHandle(handle: string): handle is sdk.LiveLogHandle {\n return liveHandleRegex.test(handle);\n}\n\n/** Handle of the ready logs of a program. */\n\nexport const readyHandleRegex =\n /^log\\+ready:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isReadyLogHandle(handle: string): handle is sdk.ReadyLogHandle {\n return readyHandleRegex.test(handle);\n}\n\nexport function getResourceInfoFromLogHandle(handle: sdk.AnyLogHandle): ResourceInfo {\n let parsed: RegExpMatchArray | null;\n\n if (isLiveLogHandle(handle)) {\n parsed = handle.match(liveHandleRegex);\n } else if (isReadyLogHandle(handle)) {\n parsed = handle.match(readyHandleRegex);\n } else throw new Error(`Log handle is malformed: ${handle}`);\n if (parsed == null) throw new Error(`Log handle wasn't parsed: ${handle}`);\n\n const { resourceType, resourceVersion, resourceId } = parsed.groups!;\n\n return {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n };\n}\n"],"mappings":";;;;AAOA,SAAgB,aAAa,MAAe,OAAuC;AACjF,KAAI,KACF,QAAO,kBAAkB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;AAGpF,QAAO,mBAAmB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;;;;;AAOrF,MAAa,kBACX;AAEF,SAAgB,gBAAgB,QAA6C;AAC3E,QAAO,gBAAgB,KAAK,OAAO;;;AAKrC,MAAa,mBACX;AAEF,SAAgB,iBAAiB,QAA8C;AAC7E,QAAO,iBAAiB,KAAK,OAAO;;AAGtC,SAAgB,6BAA6B,QAAwC;CACnF,IAAI;AAEJ,KAAI,gBAAgB,OAAO,CACzB,UAAS,OAAO,MAAM,gBAAgB;UAC7B,iBAAiB,OAAO,CACjC,UAAS,OAAO,MAAM,iBAAiB;KAClC,OAAM,IAAI,MAAM,4BAA4B,SAAS;AAC5D,KAAI,UAAU,KAAM,OAAM,IAAI,MAAM,6BAA6B,SAAS;CAE1E,MAAM,EAAE,cAAc,iBAAiB,eAAe,OAAO;AAE7D,QAAO;EACL,sDAAuB,OAAO,WAAW,CAAC;EAC1C,MAAM;GAAE,MAAM;GAAc,SAAS;GAAiB;EACvD"}
1
+ {"version":3,"file":"logs_handle.cjs","names":[],"sources":["../../../src/drivers/helpers/logs_handle.ts"],"sourcesContent":["/** Handle of logs. This handle should be passed\n * to the driver for retrieving logs. */\n\nimport type { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\n\nexport function newLogHandle(live: boolean, rInfo: ResourceInfo): sdk.AnyLogHandle {\n if (live) {\n return `log+live://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.LiveLogHandle;\n }\n\n return `log+ready://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.ReadyLogHandle;\n}\n\n/** Handle of the live logs of a program.\n * The resource that represents a log can be deleted,\n * in this case the handle should be refreshed. */\n\nexport const liveHandleRegex =\n /^log\\+live:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isLiveLogHandle(handle: string): handle is sdk.LiveLogHandle {\n return liveHandleRegex.test(handle);\n}\n\n/** Handle of the ready logs of a program. */\n\nexport const readyHandleRegex =\n /^log\\+ready:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isReadyLogHandle(handle: string): handle is sdk.ReadyLogHandle {\n return readyHandleRegex.test(handle);\n}\n\nexport function getResourceInfoFromLogHandle(handle: sdk.AnyLogHandle): ResourceInfo {\n let parsed: RegExpMatchArray | null;\n\n if (isLiveLogHandle(handle)) {\n parsed = handle.match(liveHandleRegex);\n } else if (isReadyLogHandle(handle)) {\n parsed = handle.match(readyHandleRegex);\n } else throw new Error(`Log handle is malformed: ${handle}`);\n if (parsed == null) throw new Error(`Log handle wasn't parsed: ${handle}`);\n\n const { resourceType, resourceVersion, resourceId } = parsed.groups!;\n\n return {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n };\n}\n"],"mappings":";;;AAOA,SAAgB,aAAa,MAAe,OAAuC;AACjF,KAAI,KACF,QAAO,kBAAkB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;AAGpF,QAAO,mBAAmB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;;;;;AAOrF,MAAa,kBACX;AAEF,SAAgB,gBAAgB,QAA6C;AAC3E,QAAO,gBAAgB,KAAK,OAAO;;;AAKrC,MAAa,mBACX;AAEF,SAAgB,iBAAiB,QAA8C;AAC7E,QAAO,iBAAiB,KAAK,OAAO;;AAGtC,SAAgB,6BAA6B,QAAwC;CACnF,IAAI;AAEJ,KAAI,gBAAgB,OAAO,CACzB,UAAS,OAAO,MAAM,gBAAgB;UAC7B,iBAAiB,OAAO,CACjC,UAAS,OAAO,MAAM,iBAAiB;KAClC,OAAM,IAAI,MAAM,4BAA4B,SAAS;AAC5D,KAAI,UAAU,KAAM,OAAM,IAAI,MAAM,6BAA6B,SAAS;CAE1E,MAAM,EAAE,cAAc,iBAAiB,eAAe,OAAO;AAE7D,QAAO;EACL,KAAA,GAAA,0BAAA,oBAAuB,OAAO,WAAW,CAAC;EAC1C,MAAM;GAAE,MAAM;GAAc,SAAS;GAAiB;EACvD"}
@@ -1,5 +1,4 @@
1
1
  import { bigintToResourceId } from "@milaboratories/pl-client";
2
-
3
2
  //#region src/drivers/helpers/logs_handle.ts
4
3
  function newLogHandle(live, rInfo) {
5
4
  if (live) return `log+live://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}`;
@@ -32,7 +31,7 @@ function getResourceInfoFromLogHandle(handle) {
32
31
  }
33
32
  };
34
33
  }
35
-
36
34
  //#endregion
37
35
  export { getResourceInfoFromLogHandle, isLiveLogHandle, newLogHandle };
36
+
38
37
  //# sourceMappingURL=logs_handle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs_handle.js","names":[],"sources":["../../../src/drivers/helpers/logs_handle.ts"],"sourcesContent":["/** Handle of logs. This handle should be passed\n * to the driver for retrieving logs. */\n\nimport type { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\n\nexport function newLogHandle(live: boolean, rInfo: ResourceInfo): sdk.AnyLogHandle {\n if (live) {\n return `log+live://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.LiveLogHandle;\n }\n\n return `log+ready://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.ReadyLogHandle;\n}\n\n/** Handle of the live logs of a program.\n * The resource that represents a log can be deleted,\n * in this case the handle should be refreshed. */\n\nexport const liveHandleRegex =\n /^log\\+live:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isLiveLogHandle(handle: string): handle is sdk.LiveLogHandle {\n return liveHandleRegex.test(handle);\n}\n\n/** Handle of the ready logs of a program. */\n\nexport const readyHandleRegex =\n /^log\\+ready:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isReadyLogHandle(handle: string): handle is sdk.ReadyLogHandle {\n return readyHandleRegex.test(handle);\n}\n\nexport function getResourceInfoFromLogHandle(handle: sdk.AnyLogHandle): ResourceInfo {\n let parsed: RegExpMatchArray | null;\n\n if (isLiveLogHandle(handle)) {\n parsed = handle.match(liveHandleRegex);\n } else if (isReadyLogHandle(handle)) {\n parsed = handle.match(readyHandleRegex);\n } else throw new Error(`Log handle is malformed: ${handle}`);\n if (parsed == null) throw new Error(`Log handle wasn't parsed: ${handle}`);\n\n const { resourceType, resourceVersion, resourceId } = parsed.groups!;\n\n return {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n };\n}\n"],"mappings":";;;AAOA,SAAgB,aAAa,MAAe,OAAuC;AACjF,KAAI,KACF,QAAO,kBAAkB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;AAGpF,QAAO,mBAAmB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;;;;;AAOrF,MAAa,kBACX;AAEF,SAAgB,gBAAgB,QAA6C;AAC3E,QAAO,gBAAgB,KAAK,OAAO;;;AAKrC,MAAa,mBACX;AAEF,SAAgB,iBAAiB,QAA8C;AAC7E,QAAO,iBAAiB,KAAK,OAAO;;AAGtC,SAAgB,6BAA6B,QAAwC;CACnF,IAAI;AAEJ,KAAI,gBAAgB,OAAO,CACzB,UAAS,OAAO,MAAM,gBAAgB;UAC7B,iBAAiB,OAAO,CACjC,UAAS,OAAO,MAAM,iBAAiB;KAClC,OAAM,IAAI,MAAM,4BAA4B,SAAS;AAC5D,KAAI,UAAU,KAAM,OAAM,IAAI,MAAM,6BAA6B,SAAS;CAE1E,MAAM,EAAE,cAAc,iBAAiB,eAAe,OAAO;AAE7D,QAAO;EACL,IAAI,mBAAmB,OAAO,WAAW,CAAC;EAC1C,MAAM;GAAE,MAAM;GAAc,SAAS;GAAiB;EACvD"}
1
+ {"version":3,"file":"logs_handle.js","names":[],"sources":["../../../src/drivers/helpers/logs_handle.ts"],"sourcesContent":["/** Handle of logs. This handle should be passed\n * to the driver for retrieving logs. */\n\nimport type { ResourceInfo } from \"@milaboratories/pl-tree\";\nimport type * as sdk from \"@milaboratories/pl-model-common\";\nimport { bigintToResourceId } from \"@milaboratories/pl-client\";\n\nexport function newLogHandle(live: boolean, rInfo: ResourceInfo): sdk.AnyLogHandle {\n if (live) {\n return `log+live://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.LiveLogHandle;\n }\n\n return `log+ready://log/${rInfo.type.name}/${rInfo.type.version}/${BigInt(rInfo.id)}` as sdk.ReadyLogHandle;\n}\n\n/** Handle of the live logs of a program.\n * The resource that represents a log can be deleted,\n * in this case the handle should be refreshed. */\n\nexport const liveHandleRegex =\n /^log\\+live:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isLiveLogHandle(handle: string): handle is sdk.LiveLogHandle {\n return liveHandleRegex.test(handle);\n}\n\n/** Handle of the ready logs of a program. */\n\nexport const readyHandleRegex =\n /^log\\+ready:\\/\\/log\\/(?<resourceType>.*)\\/(?<resourceVersion>.*)\\/(?<resourceId>.*)$/;\n\nexport function isReadyLogHandle(handle: string): handle is sdk.ReadyLogHandle {\n return readyHandleRegex.test(handle);\n}\n\nexport function getResourceInfoFromLogHandle(handle: sdk.AnyLogHandle): ResourceInfo {\n let parsed: RegExpMatchArray | null;\n\n if (isLiveLogHandle(handle)) {\n parsed = handle.match(liveHandleRegex);\n } else if (isReadyLogHandle(handle)) {\n parsed = handle.match(readyHandleRegex);\n } else throw new Error(`Log handle is malformed: ${handle}`);\n if (parsed == null) throw new Error(`Log handle wasn't parsed: ${handle}`);\n\n const { resourceType, resourceVersion, resourceId } = parsed.groups!;\n\n return {\n id: bigintToResourceId(BigInt(resourceId)),\n type: { name: resourceType, version: resourceVersion },\n };\n}\n"],"mappings":";;AAOA,SAAgB,aAAa,MAAe,OAAuC;AACjF,KAAI,KACF,QAAO,kBAAkB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;AAGpF,QAAO,mBAAmB,MAAM,KAAK,KAAK,GAAG,MAAM,KAAK,QAAQ,GAAG,OAAO,MAAM,GAAG;;;;;AAOrF,MAAa,kBACX;AAEF,SAAgB,gBAAgB,QAA6C;AAC3E,QAAO,gBAAgB,KAAK,OAAO;;;AAKrC,MAAa,mBACX;AAEF,SAAgB,iBAAiB,QAA8C;AAC7E,QAAO,iBAAiB,KAAK,OAAO;;AAGtC,SAAgB,6BAA6B,QAAwC;CACnF,IAAI;AAEJ,KAAI,gBAAgB,OAAO,CACzB,UAAS,OAAO,MAAM,gBAAgB;UAC7B,iBAAiB,OAAO,CACjC,UAAS,OAAO,MAAM,iBAAiB;KAClC,OAAM,IAAI,MAAM,4BAA4B,SAAS;AAC5D,KAAI,UAAU,KAAM,OAAM,IAAI,MAAM,6BAA6B,SAAS;CAE1E,MAAM,EAAE,cAAc,iBAAiB,eAAe,OAAO;AAE7D,QAAO;EACL,IAAI,mBAAmB,OAAO,WAAW,CAAC;EAC1C,MAAM;GAAE,MAAM;GAAc,SAAS;GAAiB;EACvD"}
@@ -1,12 +1,10 @@
1
- const require_types = require('../types.cjs');
2
-
1
+ const require_types = require("../types.cjs");
3
2
  //#region src/drivers/helpers/ls_remote_import_handle.ts
4
3
  function createIndexImportHandle(storageName, path) {
5
- const data = {
4
+ return `index://index/${encodeURIComponent(JSON.stringify({
6
5
  storageId: storageName,
7
6
  path
8
- };
9
- return `index://index/${encodeURIComponent(JSON.stringify(data))}`;
7
+ }))}`;
10
8
  }
11
9
  function createUploadImportHandle(localPath, signer, sizeBytes, modificationTimeSeconds) {
12
10
  const data = {
@@ -25,10 +23,10 @@ function parseIndexHandle(handle) {
25
23
  const url = new URL(handle);
26
24
  return require_types.ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));
27
25
  }
28
-
29
26
  //#endregion
30
27
  exports.createIndexImportHandle = createIndexImportHandle;
31
28
  exports.createUploadImportHandle = createUploadImportHandle;
32
29
  exports.parseIndexHandle = parseIndexHandle;
33
30
  exports.parseUploadHandle = parseUploadHandle;
31
+
34
32
  //# sourceMappingURL=ls_remote_import_handle.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ls_remote_import_handle.cjs","names":["ImportFileHandleUploadData","ImportFileHandleIndexData"],"sources":["../../../src/drivers/helpers/ls_remote_import_handle.ts"],"sourcesContent":["import type * as sdk from \"@milaboratories/pl-model-common\";\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport { ImportFileHandleIndexData, ImportFileHandleUploadData } from \"../types\";\n\nexport function createIndexImportHandle(\n storageName: string,\n path: string,\n): sdk.ImportFileHandleIndex {\n const data: ImportFileHandleIndexData = {\n storageId: storageName,\n path: path,\n };\n\n return `index://index/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function createUploadImportHandle(\n localPath: string,\n signer: Signer,\n sizeBytes: bigint,\n modificationTimeSeconds: bigint,\n): sdk.ImportFileHandleUpload {\n const data: ImportFileHandleUploadData = {\n localPath,\n pathSignature: signer.sign(localPath),\n sizeBytes: String(sizeBytes),\n modificationTime: String(modificationTimeSeconds),\n };\n\n return `upload://upload/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function parseUploadHandle(handle: sdk.ImportFileHandleUpload): ImportFileHandleUploadData {\n const url = new URL(handle);\n return ImportFileHandleUploadData.parse(\n JSON.parse(decodeURIComponent(url.pathname.substring(1))),\n );\n}\n\nexport function parseIndexHandle(handle: sdk.ImportFileHandleIndex): ImportFileHandleIndexData {\n const url = new URL(handle);\n return ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));\n}\n"],"mappings":";;;AAIA,SAAgB,wBACd,aACA,MAC2B;CAC3B,MAAM,OAAkC;EACtC,WAAW;EACL;EACP;AAED,QAAO,iBAAiB,mBAAmB,KAAK,UAAU,KAAK,CAAC;;AAGlE,SAAgB,yBACd,WACA,QACA,WACA,yBAC4B;CAC5B,MAAM,OAAmC;EACvC;EACA,eAAe,OAAO,KAAK,UAAU;EACrC,WAAW,OAAO,UAAU;EAC5B,kBAAkB,OAAO,wBAAwB;EAClD;AAED,QAAO,mBAAmB,mBAAmB,KAAK,UAAU,KAAK,CAAC;;AAGpE,SAAgB,kBAAkB,QAAgE;CAChG,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAOA,yCAA2B,MAChC,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAC1D;;AAGH,SAAgB,iBAAiB,QAA8D;CAC7F,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAOC,wCAA0B,MAAM,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"ls_remote_import_handle.cjs","names":["ImportFileHandleUploadData","ImportFileHandleIndexData"],"sources":["../../../src/drivers/helpers/ls_remote_import_handle.ts"],"sourcesContent":["import type * as sdk from \"@milaboratories/pl-model-common\";\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport { ImportFileHandleIndexData, ImportFileHandleUploadData } from \"../types\";\n\nexport function createIndexImportHandle(\n storageName: string,\n path: string,\n): sdk.ImportFileHandleIndex {\n const data: ImportFileHandleIndexData = {\n storageId: storageName,\n path: path,\n };\n\n return `index://index/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function createUploadImportHandle(\n localPath: string,\n signer: Signer,\n sizeBytes: bigint,\n modificationTimeSeconds: bigint,\n): sdk.ImportFileHandleUpload {\n const data: ImportFileHandleUploadData = {\n localPath,\n pathSignature: signer.sign(localPath),\n sizeBytes: String(sizeBytes),\n modificationTime: String(modificationTimeSeconds),\n };\n\n return `upload://upload/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function parseUploadHandle(handle: sdk.ImportFileHandleUpload): ImportFileHandleUploadData {\n const url = new URL(handle);\n return ImportFileHandleUploadData.parse(\n JSON.parse(decodeURIComponent(url.pathname.substring(1))),\n );\n}\n\nexport function parseIndexHandle(handle: sdk.ImportFileHandleIndex): ImportFileHandleIndexData {\n const url = new URL(handle);\n return ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));\n}\n"],"mappings":";;AAIA,SAAgB,wBACd,aACA,MAC2B;AAM3B,QAAO,iBAAiB,mBAAmB,KAAK,UALR;EACtC,WAAW;EACL;EACP,CAE8D,CAAC;;AAGlE,SAAgB,yBACd,WACA,QACA,WACA,yBAC4B;CAC5B,MAAM,OAAmC;EACvC;EACA,eAAe,OAAO,KAAK,UAAU;EACrC,WAAW,OAAO,UAAU;EAC5B,kBAAkB,OAAO,wBAAwB;EAClD;AAED,QAAO,mBAAmB,mBAAmB,KAAK,UAAU,KAAK,CAAC;;AAGpE,SAAgB,kBAAkB,QAAgE;CAChG,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAOA,cAAAA,2BAA2B,MAChC,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAC1D;;AAGH,SAAgB,iBAAiB,QAA8D;CAC7F,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAOC,cAAAA,0BAA0B,MAAM,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC"}
@@ -1,12 +1,10 @@
1
1
  import { ImportFileHandleIndexData, ImportFileHandleUploadData } from "../types.js";
2
-
3
2
  //#region src/drivers/helpers/ls_remote_import_handle.ts
4
3
  function createIndexImportHandle(storageName, path) {
5
- const data = {
4
+ return `index://index/${encodeURIComponent(JSON.stringify({
6
5
  storageId: storageName,
7
6
  path
8
- };
9
- return `index://index/${encodeURIComponent(JSON.stringify(data))}`;
7
+ }))}`;
10
8
  }
11
9
  function createUploadImportHandle(localPath, signer, sizeBytes, modificationTimeSeconds) {
12
10
  const data = {
@@ -25,7 +23,7 @@ function parseIndexHandle(handle) {
25
23
  const url = new URL(handle);
26
24
  return ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));
27
25
  }
28
-
29
26
  //#endregion
30
27
  export { createIndexImportHandle, createUploadImportHandle, parseIndexHandle, parseUploadHandle };
28
+
31
29
  //# sourceMappingURL=ls_remote_import_handle.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ls_remote_import_handle.js","names":[],"sources":["../../../src/drivers/helpers/ls_remote_import_handle.ts"],"sourcesContent":["import type * as sdk from \"@milaboratories/pl-model-common\";\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport { ImportFileHandleIndexData, ImportFileHandleUploadData } from \"../types\";\n\nexport function createIndexImportHandle(\n storageName: string,\n path: string,\n): sdk.ImportFileHandleIndex {\n const data: ImportFileHandleIndexData = {\n storageId: storageName,\n path: path,\n };\n\n return `index://index/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function createUploadImportHandle(\n localPath: string,\n signer: Signer,\n sizeBytes: bigint,\n modificationTimeSeconds: bigint,\n): sdk.ImportFileHandleUpload {\n const data: ImportFileHandleUploadData = {\n localPath,\n pathSignature: signer.sign(localPath),\n sizeBytes: String(sizeBytes),\n modificationTime: String(modificationTimeSeconds),\n };\n\n return `upload://upload/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function parseUploadHandle(handle: sdk.ImportFileHandleUpload): ImportFileHandleUploadData {\n const url = new URL(handle);\n return ImportFileHandleUploadData.parse(\n JSON.parse(decodeURIComponent(url.pathname.substring(1))),\n );\n}\n\nexport function parseIndexHandle(handle: sdk.ImportFileHandleIndex): ImportFileHandleIndexData {\n const url = new URL(handle);\n return ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));\n}\n"],"mappings":";;;AAIA,SAAgB,wBACd,aACA,MAC2B;CAC3B,MAAM,OAAkC;EACtC,WAAW;EACL;EACP;AAED,QAAO,iBAAiB,mBAAmB,KAAK,UAAU,KAAK,CAAC;;AAGlE,SAAgB,yBACd,WACA,QACA,WACA,yBAC4B;CAC5B,MAAM,OAAmC;EACvC;EACA,eAAe,OAAO,KAAK,UAAU;EACrC,WAAW,OAAO,UAAU;EAC5B,kBAAkB,OAAO,wBAAwB;EAClD;AAED,QAAO,mBAAmB,mBAAmB,KAAK,UAAU,KAAK,CAAC;;AAGpE,SAAgB,kBAAkB,QAAgE;CAChG,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAO,2BAA2B,MAChC,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAC1D;;AAGH,SAAgB,iBAAiB,QAA8D;CAC7F,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAO,0BAA0B,MAAM,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"ls_remote_import_handle.js","names":[],"sources":["../../../src/drivers/helpers/ls_remote_import_handle.ts"],"sourcesContent":["import type * as sdk from \"@milaboratories/pl-model-common\";\nimport type { Signer } from \"@milaboratories/ts-helpers\";\nimport { ImportFileHandleIndexData, ImportFileHandleUploadData } from \"../types\";\n\nexport function createIndexImportHandle(\n storageName: string,\n path: string,\n): sdk.ImportFileHandleIndex {\n const data: ImportFileHandleIndexData = {\n storageId: storageName,\n path: path,\n };\n\n return `index://index/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function createUploadImportHandle(\n localPath: string,\n signer: Signer,\n sizeBytes: bigint,\n modificationTimeSeconds: bigint,\n): sdk.ImportFileHandleUpload {\n const data: ImportFileHandleUploadData = {\n localPath,\n pathSignature: signer.sign(localPath),\n sizeBytes: String(sizeBytes),\n modificationTime: String(modificationTimeSeconds),\n };\n\n return `upload://upload/${encodeURIComponent(JSON.stringify(data))}`;\n}\n\nexport function parseUploadHandle(handle: sdk.ImportFileHandleUpload): ImportFileHandleUploadData {\n const url = new URL(handle);\n return ImportFileHandleUploadData.parse(\n JSON.parse(decodeURIComponent(url.pathname.substring(1))),\n );\n}\n\nexport function parseIndexHandle(handle: sdk.ImportFileHandleIndex): ImportFileHandleIndexData {\n const url = new URL(handle);\n return ImportFileHandleIndexData.parse(JSON.parse(decodeURIComponent(url.pathname.substring(1))));\n}\n"],"mappings":";;AAIA,SAAgB,wBACd,aACA,MAC2B;AAM3B,QAAO,iBAAiB,mBAAmB,KAAK,UALR;EACtC,WAAW;EACL;EACP,CAE8D,CAAC;;AAGlE,SAAgB,yBACd,WACA,QACA,WACA,yBAC4B;CAC5B,MAAM,OAAmC;EACvC;EACA,eAAe,OAAO,KAAK,UAAU;EACrC,WAAW,OAAO,UAAU;EAC5B,kBAAkB,OAAO,wBAAwB;EAClD;AAED,QAAO,mBAAmB,mBAAmB,KAAK,UAAU,KAAK,CAAC;;AAGpE,SAAgB,kBAAkB,QAAgE;CAChG,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAO,2BAA2B,MAChC,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAC1D;;AAGH,SAAgB,iBAAiB,QAA8D;CAC7F,MAAM,MAAM,IAAI,IAAI,OAAO;AAC3B,QAAO,0BAA0B,MAAM,KAAK,MAAM,mBAAmB,IAAI,SAAS,UAAU,EAAE,CAAC,CAAC,CAAC"}
@@ -1,7 +1,6 @@
1
- const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
1
+ require("../../_virtual/_rolldown/runtime.cjs");
2
2
  let _milaboratories_pl_client = require("@milaboratories/pl-client");
3
3
  let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
4
-
5
4
  //#region src/drivers/helpers/ls_storage_entry.ts
6
5
  /**
7
6
  * Gets a storage handle and gives an underlying data from it.
@@ -52,9 +51,9 @@ function storageType(name) {
52
51
  version: "1"
53
52
  };
54
53
  }
55
-
56
54
  //#endregion
57
55
  exports.createLocalStorageHandle = createLocalStorageHandle;
58
56
  exports.createRemoteStorageHandle = createRemoteStorageHandle;
59
57
  exports.parseStorageHandle = parseStorageHandle;
58
+
60
59
  //# sourceMappingURL=ls_storage_entry.cjs.map