@milaboratories/pl-middle-layer 1.74.11 → 1.74.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/dist/_virtual/{_@oxc-project_runtime@0.137.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/usingCtx.cjs +1 -2
  2. package/dist/_virtual/{_@oxc-project_runtime@0.137.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/usingCtx.js +1 -2
  3. package/dist/_virtual/_rolldown/runtime.cjs +2 -3
  4. package/dist/block_registry/location_provider.cjs +1 -2
  5. package/dist/block_registry/location_provider.cjs.map +1 -1
  6. package/dist/block_registry/location_provider.js +1 -2
  7. package/dist/block_registry/registry-v2-provider.cjs +1 -2
  8. package/dist/block_registry/registry-v2-provider.cjs.map +1 -1
  9. package/dist/block_registry/registry-v2-provider.d.ts +0 -2
  10. package/dist/block_registry/registry-v2-provider.d.ts.map +1 -1
  11. package/dist/block_registry/registry-v2-provider.js +1 -2
  12. package/dist/block_registry/registry.cjs +3 -3
  13. package/dist/block_registry/registry.cjs.map +1 -1
  14. package/dist/block_registry/registry.d.ts +0 -2
  15. package/dist/block_registry/registry.d.ts.map +1 -1
  16. package/dist/block_registry/registry.js +3 -3
  17. package/dist/block_registry/registry.js.map +1 -1
  18. package/dist/block_registry/template_provider.cjs +1 -2
  19. package/dist/block_registry/template_provider.cjs.map +1 -1
  20. package/dist/block_registry/template_provider.d.ts +0 -2
  21. package/dist/block_registry/template_provider.d.ts.map +1 -1
  22. package/dist/block_registry/template_provider.js +1 -2
  23. package/dist/block_registry/watcher.cjs +15 -14
  24. package/dist/block_registry/watcher.cjs.map +1 -1
  25. package/dist/block_registry/watcher.d.ts +0 -2
  26. package/dist/block_registry/watcher.d.ts.map +1 -1
  27. package/dist/block_registry/watcher.js +15 -14
  28. package/dist/block_registry/watcher.js.map +1 -1
  29. package/dist/block_registry/well_known_registries.cjs +1 -2
  30. package/dist/block_registry/well_known_registries.d.ts +0 -2
  31. package/dist/block_registry/well_known_registries.d.ts.map +1 -1
  32. package/dist/block_registry/well_known_registries.js +1 -2
  33. package/dist/cfg_render/executor.cjs +1 -2
  34. package/dist/cfg_render/executor.cjs.map +1 -1
  35. package/dist/cfg_render/executor.js +1 -2
  36. package/dist/cfg_render/renderer.cjs +1 -2
  37. package/dist/cfg_render/renderer.cjs.map +1 -1
  38. package/dist/cfg_render/renderer.js +1 -2
  39. package/dist/cfg_render/traverse.cjs +1 -2
  40. package/dist/cfg_render/traverse.js +1 -2
  41. package/dist/cfg_render/util.cjs +1 -2
  42. package/dist/cfg_render/util.js +1 -2
  43. package/dist/debug/index.cjs +1 -2
  44. package/dist/debug/index.js +1 -2
  45. package/dist/dev_env/index.cjs +1 -2
  46. package/dist/dev_env/index.cjs.map +1 -1
  47. package/dist/dev_env/index.js +1 -2
  48. package/dist/dev_env/util.cjs +1 -2
  49. package/dist/dev_env/util.js +1 -2
  50. package/dist/js_render/column_registry.cjs +1 -2
  51. package/dist/js_render/column_registry.cjs.map +1 -1
  52. package/dist/js_render/column_registry.js +1 -2
  53. package/dist/js_render/computable_context.cjs +4 -4
  54. package/dist/js_render/computable_context.cjs.map +1 -1
  55. package/dist/js_render/computable_context.js +4 -4
  56. package/dist/js_render/computable_context.js.map +1 -1
  57. package/dist/js_render/context.cjs +1 -2
  58. package/dist/js_render/context.cjs.map +1 -1
  59. package/dist/js_render/context.js +1 -2
  60. package/dist/js_render/index.cjs +12 -9
  61. package/dist/js_render/index.cjs.map +1 -1
  62. package/dist/js_render/index.js +12 -9
  63. package/dist/js_render/index.js.map +1 -1
  64. package/dist/js_render/service_injectors.cjs +2 -3
  65. package/dist/js_render/service_injectors.js +2 -3
  66. package/dist/js_render/spec_override_collapse.cjs +1 -2
  67. package/dist/js_render/spec_override_collapse.cjs.map +1 -1
  68. package/dist/js_render/spec_override_collapse.js +1 -2
  69. package/dist/middle_layer/active_cfg.cjs +1 -2
  70. package/dist/middle_layer/active_cfg.cjs.map +1 -1
  71. package/dist/middle_layer/active_cfg.js +1 -2
  72. package/dist/middle_layer/block.cjs +1 -2
  73. package/dist/middle_layer/block.cjs.map +1 -1
  74. package/dist/middle_layer/block.js +1 -2
  75. package/dist/middle_layer/block_ctx.cjs +3 -3
  76. package/dist/middle_layer/block_ctx.cjs.map +1 -1
  77. package/dist/middle_layer/block_ctx.js +3 -3
  78. package/dist/middle_layer/block_ctx.js.map +1 -1
  79. package/dist/middle_layer/block_ctx_unsafe.cjs +1 -2
  80. package/dist/middle_layer/block_ctx_unsafe.js +1 -2
  81. package/dist/middle_layer/build_stamp.cjs +2 -3
  82. package/dist/middle_layer/build_stamp.js +2 -3
  83. package/dist/middle_layer/driver_kit.cjs +1 -2
  84. package/dist/middle_layer/driver_kit.cjs.map +1 -1
  85. package/dist/middle_layer/driver_kit.d.ts +0 -2
  86. package/dist/middle_layer/driver_kit.d.ts.map +1 -1
  87. package/dist/middle_layer/driver_kit.js +1 -2
  88. package/dist/middle_layer/finality_stop_rules.cjs +1 -2
  89. package/dist/middle_layer/finality_stop_rules.js +1 -2
  90. package/dist/middle_layer/folders.cjs +12 -8
  91. package/dist/middle_layer/folders.cjs.map +1 -1
  92. package/dist/middle_layer/folders.d.ts +0 -2
  93. package/dist/middle_layer/folders.d.ts.map +1 -1
  94. package/dist/middle_layer/folders.js +12 -8
  95. package/dist/middle_layer/folders.js.map +1 -1
  96. package/dist/middle_layer/frontend_path.cjs +1 -2
  97. package/dist/middle_layer/frontend_path.cjs.map +1 -1
  98. package/dist/middle_layer/frontend_path.js +1 -2
  99. package/dist/middle_layer/middle_layer.cjs +7 -6
  100. package/dist/middle_layer/middle_layer.cjs.map +1 -1
  101. package/dist/middle_layer/middle_layer.d.ts +0 -2
  102. package/dist/middle_layer/middle_layer.d.ts.map +1 -1
  103. package/dist/middle_layer/middle_layer.js +7 -6
  104. package/dist/middle_layer/middle_layer.js.map +1 -1
  105. package/dist/middle_layer/navigation_states.cjs +1 -2
  106. package/dist/middle_layer/navigation_states.js +1 -2
  107. package/dist/middle_layer/ops.cjs +10 -11
  108. package/dist/middle_layer/ops.cjs.map +1 -1
  109. package/dist/middle_layer/ops.d.ts +0 -2
  110. package/dist/middle_layer/ops.d.ts.map +1 -1
  111. package/dist/middle_layer/ops.js +10 -11
  112. package/dist/middle_layer/ops.js.map +1 -1
  113. package/dist/middle_layer/project.cjs +3 -3
  114. package/dist/middle_layer/project.cjs.map +1 -1
  115. package/dist/middle_layer/project.d.ts +3 -5
  116. package/dist/middle_layer/project.d.ts.map +1 -1
  117. package/dist/middle_layer/project.js +3 -3
  118. package/dist/middle_layer/project.js.map +1 -1
  119. package/dist/middle_layer/project_list.cjs +1 -2
  120. package/dist/middle_layer/project_list.cjs.map +1 -1
  121. package/dist/middle_layer/project_list.d.ts +0 -2
  122. package/dist/middle_layer/project_list.d.ts.map +1 -1
  123. package/dist/middle_layer/project_list.js +1 -2
  124. package/dist/middle_layer/project_overview.cjs +8 -5
  125. package/dist/middle_layer/project_overview.cjs.map +1 -1
  126. package/dist/middle_layer/project_overview.js +8 -5
  127. package/dist/middle_layer/project_overview.js.map +1 -1
  128. package/dist/middle_layer/project_overview_light.cjs +4 -3
  129. package/dist/middle_layer/project_overview_light.cjs.map +1 -1
  130. package/dist/middle_layer/project_overview_light.js +4 -3
  131. package/dist/middle_layer/project_overview_light.js.map +1 -1
  132. package/dist/middle_layer/render.cjs +1 -2
  133. package/dist/middle_layer/render.cjs.map +1 -1
  134. package/dist/middle_layer/render.js +1 -2
  135. package/dist/middle_layer/sharing_list.cjs +1 -2
  136. package/dist/middle_layer/sharing_list.cjs.map +1 -1
  137. package/dist/middle_layer/sharing_list.d.ts +0 -2
  138. package/dist/middle_layer/sharing_list.d.ts.map +1 -1
  139. package/dist/middle_layer/sharing_list.js +1 -2
  140. package/dist/middle_layer/sharing_list.js.map +1 -1
  141. package/dist/middle_layer/template_list.cjs +1 -2
  142. package/dist/middle_layer/template_list.cjs.map +1 -1
  143. package/dist/middle_layer/template_list.d.ts +0 -2
  144. package/dist/middle_layer/template_list.d.ts.map +1 -1
  145. package/dist/middle_layer/template_list.js +1 -2
  146. package/dist/middle_layer/tree_snapshot_store.cjs +3 -3
  147. package/dist/middle_layer/tree_snapshot_store.cjs.map +1 -1
  148. package/dist/middle_layer/tree_snapshot_store.d.ts +0 -2
  149. package/dist/middle_layer/tree_snapshot_store.d.ts.map +1 -1
  150. package/dist/middle_layer/tree_snapshot_store.js +3 -3
  151. package/dist/middle_layer/tree_snapshot_store.js.map +1 -1
  152. package/dist/middle_layer/types.d.ts +0 -2
  153. package/dist/middle_layer/types.d.ts.map +1 -1
  154. package/dist/middle_layer/util.cjs +1 -2
  155. package/dist/middle_layer/util.cjs.map +1 -1
  156. package/dist/middle_layer/util.js +1 -2
  157. package/dist/model/args.cjs +1 -2
  158. package/dist/model/args.cjs.map +1 -1
  159. package/dist/model/args.js +1 -2
  160. package/dist/model/block_pack_spec.cjs +1 -2
  161. package/dist/model/block_pack_spec.d.ts +0 -2
  162. package/dist/model/block_pack_spec.d.ts.map +1 -1
  163. package/dist/model/block_pack_spec.js +1 -2
  164. package/dist/model/frontend.d.ts +0 -2
  165. package/dist/model/frontend.d.ts.map +1 -1
  166. package/dist/model/project_helper.cjs +1 -2
  167. package/dist/model/project_helper.cjs.map +1 -1
  168. package/dist/model/project_helper.d.ts +0 -2
  169. package/dist/model/project_helper.d.ts.map +1 -1
  170. package/dist/model/project_helper.js +1 -2
  171. package/dist/model/project_model.cjs +1 -2
  172. package/dist/model/project_model.d.ts +0 -2
  173. package/dist/model/project_model.d.ts.map +1 -1
  174. package/dist/model/project_model.js +1 -2
  175. package/dist/model/project_model_util.cjs +1 -2
  176. package/dist/model/project_model_util.js +1 -2
  177. package/dist/model/project_model_v1.cjs +1 -2
  178. package/dist/model/project_model_v1.js +1 -2
  179. package/dist/model/sharing_model.cjs +1 -2
  180. package/dist/model/sharing_model.cjs.map +1 -1
  181. package/dist/model/sharing_model.d.ts +0 -2
  182. package/dist/model/sharing_model.d.ts.map +1 -1
  183. package/dist/model/sharing_model.js +1 -2
  184. package/dist/model/template_apply.cjs +1 -2
  185. package/dist/model/template_apply.cjs.map +1 -1
  186. package/dist/model/template_apply.d.ts +0 -2
  187. package/dist/model/template_apply.d.ts.map +1 -1
  188. package/dist/model/template_apply.js +1 -2
  189. package/dist/model/template_export.cjs +1 -2
  190. package/dist/model/template_export.d.ts +0 -2
  191. package/dist/model/template_export.d.ts.map +1 -1
  192. package/dist/model/template_export.js +1 -2
  193. package/dist/model/template_parser.cjs +1 -2
  194. package/dist/model/template_parser.cjs.map +1 -1
  195. package/dist/model/template_parser.d.ts +0 -2
  196. package/dist/model/template_parser.d.ts.map +1 -1
  197. package/dist/model/template_parser.js +1 -2
  198. package/dist/model/template_resolve.cjs +1 -2
  199. package/dist/model/template_resolve.cjs.map +1 -1
  200. package/dist/model/template_resolve.d.ts +0 -2
  201. package/dist/model/template_resolve.d.ts.map +1 -1
  202. package/dist/model/template_resolve.js +1 -2
  203. package/dist/model/template_serializer.cjs +1 -2
  204. package/dist/model/template_serializer.cjs.map +1 -1
  205. package/dist/model/template_serializer.d.ts +0 -2
  206. package/dist/model/template_serializer.d.ts.map +1 -1
  207. package/dist/model/template_serializer.js +1 -2
  208. package/dist/model/template_spec.d.ts +0 -2
  209. package/dist/model/template_spec.d.ts.map +1 -1
  210. package/dist/mutator/block-pack/block_pack.cjs +7 -6
  211. package/dist/mutator/block-pack/block_pack.cjs.map +1 -1
  212. package/dist/mutator/block-pack/block_pack.d.ts +0 -2
  213. package/dist/mutator/block-pack/block_pack.d.ts.map +1 -1
  214. package/dist/mutator/block-pack/block_pack.js +7 -6
  215. package/dist/mutator/block-pack/block_pack.js.map +1 -1
  216. package/dist/mutator/block-pack/frontend.cjs +1 -2
  217. package/dist/mutator/block-pack/frontend.cjs.map +1 -1
  218. package/dist/mutator/block-pack/frontend.js +1 -2
  219. package/dist/mutator/block-pack/required_capabilities.cjs +1 -2
  220. package/dist/mutator/block-pack/required_capabilities.cjs.map +1 -1
  221. package/dist/mutator/block-pack/required_capabilities.js +1 -2
  222. package/dist/mutator/context_export.cjs +1 -2
  223. package/dist/mutator/context_export.cjs.map +1 -1
  224. package/dist/mutator/context_export.js +1 -2
  225. package/dist/mutator/list.cjs +1 -2
  226. package/dist/mutator/list.cjs.map +1 -1
  227. package/dist/mutator/list.js +1 -2
  228. package/dist/mutator/migration.cjs +1 -2
  229. package/dist/mutator/migration.cjs.map +1 -1
  230. package/dist/mutator/migration.js +1 -2
  231. package/dist/mutator/project.cjs +30 -22
  232. package/dist/mutator/project.cjs.map +1 -1
  233. package/dist/mutator/project.d.ts +0 -2
  234. package/dist/mutator/project.d.ts.map +1 -1
  235. package/dist/mutator/project.js +30 -22
  236. package/dist/mutator/project.js.map +1 -1
  237. package/dist/mutator/sharing.cjs +1 -2
  238. package/dist/mutator/sharing.cjs.map +1 -1
  239. package/dist/mutator/sharing.js +1 -2
  240. package/dist/mutator/template/direct_template_loader.cjs +1 -2
  241. package/dist/mutator/template/direct_template_loader.cjs.map +1 -1
  242. package/dist/mutator/template/direct_template_loader.js +1 -2
  243. package/dist/mutator/template/direct_template_loader_v3.cjs +1 -2
  244. package/dist/mutator/template/direct_template_loader_v3.cjs.map +1 -1
  245. package/dist/mutator/template/direct_template_loader_v3.js +1 -2
  246. package/dist/mutator/template/render_block.cjs +1 -2
  247. package/dist/mutator/template/render_block.cjs.map +1 -1
  248. package/dist/mutator/template/render_block.js +1 -2
  249. package/dist/mutator/template/render_template.cjs +1 -2
  250. package/dist/mutator/template/render_template.cjs.map +1 -1
  251. package/dist/mutator/template/render_template.d.ts +0 -2
  252. package/dist/mutator/template/render_template.d.ts.map +1 -1
  253. package/dist/mutator/template/render_template.js +1 -2
  254. package/dist/mutator/template/template_cache.cjs +6 -5
  255. package/dist/mutator/template/template_cache.cjs.map +1 -1
  256. package/dist/mutator/template/template_cache.d.ts +1 -2
  257. package/dist/mutator/template/template_cache.d.ts.map +1 -1
  258. package/dist/mutator/template/template_cache.js +6 -5
  259. package/dist/mutator/template/template_cache.js.map +1 -1
  260. package/dist/mutator/template/template_loading.cjs +1 -2
  261. package/dist/mutator/template/template_loading.cjs.map +1 -1
  262. package/dist/mutator/template/template_loading.d.ts +0 -2
  263. package/dist/mutator/template/template_loading.d.ts.map +1 -1
  264. package/dist/mutator/template/template_loading.js +1 -2
  265. package/dist/mutator/template.cjs +1 -2
  266. package/dist/mutator/template.cjs.map +1 -1
  267. package/dist/mutator/template.js +1 -2
  268. package/dist/mutator/template_construct.cjs +1 -2
  269. package/dist/mutator/template_construct.cjs.map +1 -1
  270. package/dist/mutator/template_construct.js +1 -2
  271. package/dist/network_check/network_check.cjs +2 -3
  272. package/dist/network_check/network_check.cjs.map +1 -1
  273. package/dist/network_check/network_check.d.ts +0 -2
  274. package/dist/network_check/network_check.d.ts.map +1 -1
  275. package/dist/network_check/network_check.js +2 -3
  276. package/dist/network_check/network_check.js.map +1 -1
  277. package/dist/network_check/pings.cjs +1 -2
  278. package/dist/network_check/pings.cjs.map +1 -1
  279. package/dist/network_check/pings.js +1 -2
  280. package/dist/network_check/template.cjs +5 -4
  281. package/dist/network_check/template.cjs.map +1 -1
  282. package/dist/network_check/template.js +5 -4
  283. package/dist/network_check/template.js.map +1 -1
  284. package/dist/pool/data.cjs +1 -2
  285. package/dist/pool/data.cjs.map +1 -1
  286. package/dist/pool/data.d.ts +0 -2
  287. package/dist/pool/data.d.ts.map +1 -1
  288. package/dist/pool/data.js +1 -2
  289. package/dist/pool/driver.cjs +5 -4
  290. package/dist/pool/driver.cjs.map +1 -1
  291. package/dist/pool/driver.d.ts +0 -2
  292. package/dist/pool/driver.d.ts.map +1 -1
  293. package/dist/pool/driver.js +5 -4
  294. package/dist/pool/driver.js.map +1 -1
  295. package/dist/pool/p_object_collection.cjs +9 -8
  296. package/dist/pool/p_object_collection.cjs.map +1 -1
  297. package/dist/pool/p_object_collection.d.ts +0 -2
  298. package/dist/pool/p_object_collection.d.ts.map +1 -1
  299. package/dist/pool/p_object_collection.js +9 -8
  300. package/dist/pool/p_object_collection.js.map +1 -1
  301. package/dist/pool/result_pool.cjs +8 -7
  302. package/dist/pool/result_pool.cjs.map +1 -1
  303. package/dist/pool/result_pool.js +8 -7
  304. package/dist/pool/result_pool.js.map +1 -1
  305. package/dist/pool/upstream_block_ctx.cjs +1 -2
  306. package/dist/pool/upstream_block_ctx.cjs.map +1 -1
  307. package/dist/pool/upstream_block_ctx.js +1 -2
  308. package/dist/service_factories.cjs +1 -2
  309. package/dist/service_factories.js +1 -2
  310. package/dist/worker/WorkerManager.cjs +1 -2
  311. package/dist/worker/WorkerManager.js +1 -2
  312. package/dist/worker/WorkerManager.js.map +1 -1
  313. package/dist/worker/worker.cjs +1 -2
  314. package/dist/worker/worker.js +1 -2
  315. package/dist/worker/workerApi.cjs +1 -2
  316. package/dist/worker/workerApi.cjs.map +1 -1
  317. package/dist/worker/workerApi.js +1 -2
  318. package/package.json +33 -33
  319. package/src/middle_layer/middle_layer.ts +4 -6
  320. package/src/middle_layer/tree_snapshot_store.test.ts +4 -1
@@ -1,4 +1,4 @@
1
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/usingCtx.js
1
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/usingCtx.js
2
2
  function _usingCtx() {
3
3
  var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
4
4
  var n = Error();
@@ -53,5 +53,4 @@ function _usingCtx() {
53
53
  }
54
54
  };
55
55
  }
56
- //#endregion
57
56
  exports.default = _usingCtx;
@@ -1,4 +1,4 @@
1
- //#region \0@oxc-project+runtime@0.137.0/helpers/esm/usingCtx.js
1
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/usingCtx.js
2
2
  function _usingCtx() {
3
3
  var r = "function" == typeof SuppressedError ? SuppressedError : function(r, e) {
4
4
  var n = Error();
@@ -53,5 +53,4 @@ function _usingCtx() {
53
53
  }
54
54
  };
55
55
  }
56
- //#endregion
57
56
  export { _usingCtx as default };
@@ -1,4 +1,4 @@
1
- //#region \0rolldown/runtime.js
1
+ // \0rolldown/runtime.js
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -15,9 +15,8 @@ var __copyProps = (to, from, except, desc) => {
15
15
  }
16
16
  return to;
17
17
  };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
19
  value: mod,
20
20
  enumerable: true
21
21
  }) : target, mod));
22
- //#endregion
23
22
  exports.__toESM = __toESM;
@@ -6,7 +6,7 @@ let node_fs_promises = require("node:fs/promises");
6
6
  node_fs_promises = require_runtime.__toESM(node_fs_promises, 1);
7
7
  let node_url = require("node:url");
8
8
  let _milaboratories_pl_model_common = require("@milaboratories/pl-model-common");
9
- //#region src/block_registry/location_provider.ts
9
+ // src/block_registry/location_provider.ts
10
10
  /**
11
11
  * Read the block a template entry's `location` points at.
12
12
  *
@@ -111,7 +111,6 @@ async function exists(target) {
111
111
  return false;
112
112
  }
113
113
  }
114
- //#endregion
115
114
  exports.resolveBlockPackLocation = resolveBlockPackLocation;
116
115
 
117
116
  //# sourceMappingURL=location_provider.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"location_provider.cjs","names":["path","fsp"],"sources":["../../src/block_registry/location_provider.ts"],"sourcesContent":["import fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { BlockPackLocationReference } from \"@milaboratories/pl-model-common\";\nimport { parseBlockPackLocation } from \"@milaboratories/pl-model-common\";\nimport type { BlockPackSpec } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockPackDescriptionAbsolute } from \"@platforma-sdk/block-tools\";\nimport { loadPackDescription, loadPackDescriptionFromManifest } from \"@platforma-sdk/block-tools\";\nimport type { LocationResolution } from \"../model/template_resolve\";\n\n/**\n * Read the block a template entry's `location` points at.\n *\n * The filesystem half of {@link BlockPackProvider}, and the reason a project built from\n * locally developed blocks can be exported and applied without publishing anything. No\n * registry is involved and nothing is searched: the entry named a place.\n *\n * Only `file:` is served. The document's grammar admits any scheme so that a template\n * stays readable by a consumer that can fetch more than this one can, and an unknown\n * scheme is reported rather than treated as a missing block — \"I cannot read this\" and\n * \"there is nothing there\" send the reader to different places.\n */\nexport async function resolveBlockPackLocation(\n location: BlockPackLocationReference,\n): Promise<LocationResolution> {\n if (parseBlockPackLocation(location).scheme !== \"file\") {\n return { ok: false, reason: \"unsupported-scheme\" };\n }\n\n // The value is a URL, never a path: `fileURLToPath` is what turns `%20` back into the\n // space that was in the folder name. Reading `pathname` directly would look right and\n // fail on any path with a space in it.\n const dir = fileURLToPath(location);\n\n const found = await readPackAt(dir);\n if (found === undefined) {\n return (await exists(dir))\n ? { ok: false, reason: \"not-a-block\" }\n : { ok: false, reason: \"not-found\" };\n }\n\n return { ok: true, spec: found.spec, title: found.description.meta.title };\n}\n\n/** One readable block pack: which spec addresses it, and what it declares. */\ntype FoundPack = {\n readonly spec: BlockPackSpec;\n readonly description: BlockPackDescriptionAbsolute;\n};\n\n/**\n * Identify what kind of block pack is at `dir`, by looking rather than by being told.\n *\n * Two layouts can sit behind one `location`, and they anchor differently — a packed\n * block at the folder holding its `manifest.json`, a source block at the folder holding\n * the `package.json` that names its components. The document deliberately records only\n * the URI, so the layout is established here, where the filesystem is: encoding it in\n * the file instead would freeze today's two shapes into the format, and a template\n * written last month would name a layout that has since moved.\n *\n * A packed layout is checked first because it is the more specific one: a facade\n * package's own folder holds `package.json` and, once packed, `block-pack/` beside it\n * — never `manifest.json` directly.\n *\n * When neither matches, the two conventional subfolders are tried. Those are the same\n * names the dev-block scanner probes, so a hand-written entry may name the block's own\n * folder rather than the package inside it. Export never emits these: it writes the\n * anchor the loader accepts, so there is nothing to guess on a round trip.\n */\nasync function readPackAt(dir: string): Promise<FoundPack | undefined> {\n const direct = await readPackExactlyAt(dir);\n if (direct !== undefined) return direct;\n\n for (const subfolder of [\"block\", \"meta\"]) {\n const nested = await readPackExactlyAt(path.join(dir, subfolder));\n if (nested !== undefined) return nested;\n }\n\n return undefined;\n}\n\nasync function readPackExactlyAt(dir: string): Promise<FoundPack | undefined> {\n if (await exists(path.join(dir, \"manifest.json\"))) {\n const description = await loadPackDescriptionFromManifest(dir);\n return {\n // The pack directory is what the preparer expects to be handed, and it is where\n // the manifest was just read from — not something reconstructed from a parent.\n spec: { type: \"from-pack-v2\", packUrl: pathToFileURL(dir).href },\n description,\n };\n }\n\n if (await hasBlockDescription(path.join(dir, \"package.json\"))) {\n const description = await loadPackDescription(dir);\n return { spec: { type: \"dev-v2\", folder: dir }, description };\n }\n\n return undefined;\n}\n\n/**\n * Whether this `package.json` describes a block at all.\n *\n * Checked before handing the folder to the loader so that an ordinary npm package —\n * anything with a `package.json` and no block description — comes back as \"not a\n * block\" rather than as a thrown parse failure from inside the loader.\n */\nasync function hasBlockDescription(packageJsonPath: string): Promise<boolean> {\n try {\n const parsed: unknown = JSON.parse(await fsp.readFile(packageJsonPath, \"utf-8\"));\n return typeof parsed === \"object\" && parsed !== null && \"block\" in parsed;\n } catch {\n return false;\n }\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await fsp.stat(target);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,yBACpB,UAC6B;CAC7B,KAAA,GAAA,gCAAA,uBAAA,CAA2B,QAAQ,CAAC,CAAC,WAAW,QAC9C,OAAO;EAAE,IAAI;EAAO,QAAQ;CAAqB;CAMnD,MAAM,OAAA,GAAA,SAAA,cAAA,CAAoB,QAAQ;CAElC,MAAM,QAAQ,MAAM,WAAW,GAAG;CAClC,IAAI,UAAU,KAAA,GACZ,OAAQ,MAAM,OAAO,GAAG,IACpB;EAAE,IAAI;EAAO,QAAQ;CAAc,IACnC;EAAE,IAAI;EAAO,QAAQ;CAAY;CAGvC,OAAO;EAAE,IAAI;EAAM,MAAM,MAAM;EAAM,OAAO,MAAM,YAAY,KAAK;CAAM;AAC3E;;;;;;;;;;;;;;;;;;;;AA2BA,eAAe,WAAW,KAA6C;CACrE,MAAM,SAAS,MAAM,kBAAkB,GAAG;CAC1C,IAAI,WAAW,KAAA,GAAW,OAAO;CAEjC,KAAK,MAAM,aAAa,CAAC,SAAS,MAAM,GAAG;EACzC,MAAM,SAAS,MAAM,kBAAkBA,UAAAA,QAAK,KAAK,KAAK,SAAS,CAAC;EAChE,IAAI,WAAW,KAAA,GAAW,OAAO;CACnC;AAGF;AAEA,eAAe,kBAAkB,KAA6C;CAC5E,IAAI,MAAM,OAAOA,UAAAA,QAAK,KAAK,KAAK,eAAe,CAAC,GAAG;EACjD,MAAM,cAAc,OAAA,GAAA,2BAAA,gCAAA,CAAsC,GAAG;EAC7D,OAAO;GAGL,MAAM;IAAE,MAAM;IAAgB,UAAA,GAAA,SAAA,cAAA,CAAuB,GAAG,CAAC,CAAC;GAAK;GAC/D;EACF;CACF;CAEA,IAAI,MAAM,oBAAoBA,UAAAA,QAAK,KAAK,KAAK,cAAc,CAAC,GAAG;EAC7D,MAAM,cAAc,OAAA,GAAA,2BAAA,oBAAA,CAA0B,GAAG;EACjD,OAAO;GAAE,MAAM;IAAE,MAAM;IAAU,QAAQ;GAAI;GAAG;EAAY;CAC9D;AAGF;;;;;;;;AASA,eAAe,oBAAoB,iBAA2C;CAC5E,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,MAAMC,iBAAAA,QAAI,SAAS,iBAAiB,OAAO,CAAC;EAC/E,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,WAAW;CACrE,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAe,OAAO,QAAkC;CACtD,IAAI;EACF,MAAMA,iBAAAA,QAAI,KAAK,MAAM;EACrB,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"location_provider.cjs","names":["parseBlockPackLocation","fileURLToPath","path","loadPackDescriptionFromManifest","pathToFileURL","loadPackDescription","fsp"],"sources":["../../src/block_registry/location_provider.ts"],"sourcesContent":["import fsp from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport type { BlockPackLocationReference } from \"@milaboratories/pl-model-common\";\nimport { parseBlockPackLocation } from \"@milaboratories/pl-model-common\";\nimport type { BlockPackSpec } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockPackDescriptionAbsolute } from \"@platforma-sdk/block-tools\";\nimport { loadPackDescription, loadPackDescriptionFromManifest } from \"@platforma-sdk/block-tools\";\nimport type { LocationResolution } from \"../model/template_resolve\";\n\n/**\n * Read the block a template entry's `location` points at.\n *\n * The filesystem half of {@link BlockPackProvider}, and the reason a project built from\n * locally developed blocks can be exported and applied without publishing anything. No\n * registry is involved and nothing is searched: the entry named a place.\n *\n * Only `file:` is served. The document's grammar admits any scheme so that a template\n * stays readable by a consumer that can fetch more than this one can, and an unknown\n * scheme is reported rather than treated as a missing block — \"I cannot read this\" and\n * \"there is nothing there\" send the reader to different places.\n */\nexport async function resolveBlockPackLocation(\n location: BlockPackLocationReference,\n): Promise<LocationResolution> {\n if (parseBlockPackLocation(location).scheme !== \"file\") {\n return { ok: false, reason: \"unsupported-scheme\" };\n }\n\n // The value is a URL, never a path: `fileURLToPath` is what turns `%20` back into the\n // space that was in the folder name. Reading `pathname` directly would look right and\n // fail on any path with a space in it.\n const dir = fileURLToPath(location);\n\n const found = await readPackAt(dir);\n if (found === undefined) {\n return (await exists(dir))\n ? { ok: false, reason: \"not-a-block\" }\n : { ok: false, reason: \"not-found\" };\n }\n\n return { ok: true, spec: found.spec, title: found.description.meta.title };\n}\n\n/** One readable block pack: which spec addresses it, and what it declares. */\ntype FoundPack = {\n readonly spec: BlockPackSpec;\n readonly description: BlockPackDescriptionAbsolute;\n};\n\n/**\n * Identify what kind of block pack is at `dir`, by looking rather than by being told.\n *\n * Two layouts can sit behind one `location`, and they anchor differently — a packed\n * block at the folder holding its `manifest.json`, a source block at the folder holding\n * the `package.json` that names its components. The document deliberately records only\n * the URI, so the layout is established here, where the filesystem is: encoding it in\n * the file instead would freeze today's two shapes into the format, and a template\n * written last month would name a layout that has since moved.\n *\n * A packed layout is checked first because it is the more specific one: a facade\n * package's own folder holds `package.json` and, once packed, `block-pack/` beside it\n * — never `manifest.json` directly.\n *\n * When neither matches, the two conventional subfolders are tried. Those are the same\n * names the dev-block scanner probes, so a hand-written entry may name the block's own\n * folder rather than the package inside it. Export never emits these: it writes the\n * anchor the loader accepts, so there is nothing to guess on a round trip.\n */\nasync function readPackAt(dir: string): Promise<FoundPack | undefined> {\n const direct = await readPackExactlyAt(dir);\n if (direct !== undefined) return direct;\n\n for (const subfolder of [\"block\", \"meta\"]) {\n const nested = await readPackExactlyAt(path.join(dir, subfolder));\n if (nested !== undefined) return nested;\n }\n\n return undefined;\n}\n\nasync function readPackExactlyAt(dir: string): Promise<FoundPack | undefined> {\n if (await exists(path.join(dir, \"manifest.json\"))) {\n const description = await loadPackDescriptionFromManifest(dir);\n return {\n // The pack directory is what the preparer expects to be handed, and it is where\n // the manifest was just read from — not something reconstructed from a parent.\n spec: { type: \"from-pack-v2\", packUrl: pathToFileURL(dir).href },\n description,\n };\n }\n\n if (await hasBlockDescription(path.join(dir, \"package.json\"))) {\n const description = await loadPackDescription(dir);\n return { spec: { type: \"dev-v2\", folder: dir }, description };\n }\n\n return undefined;\n}\n\n/**\n * Whether this `package.json` describes a block at all.\n *\n * Checked before handing the folder to the loader so that an ordinary npm package —\n * anything with a `package.json` and no block description — comes back as \"not a\n * block\" rather than as a thrown parse failure from inside the loader.\n */\nasync function hasBlockDescription(packageJsonPath: string): Promise<boolean> {\n try {\n const parsed: unknown = JSON.parse(await fsp.readFile(packageJsonPath, \"utf-8\"));\n return typeof parsed === \"object\" && parsed !== null && \"block\" in parsed;\n } catch {\n return false;\n }\n}\n\nasync function exists(target: string): Promise<boolean> {\n try {\n await fsp.stat(target);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,eAAsB,yBACpB,UAC6B;CAC7B,KAAA,GAAIA,gCAAAA,uBAAAA,CAAuB,QAAQ,CAAC,CAAC,WAAW,QAC9C,OAAO;EAAE,IAAI;EAAO,QAAQ;CAAqB;CAMnD,MAAM,OAAA,GAAMC,SAAAA,cAAAA,CAAc,QAAQ;CAElC,MAAM,QAAQ,MAAM,WAAW,GAAG;CAClC,IAAI,UAAU,KAAA,GACZ,OAAQ,MAAM,OAAO,GAAG,IACpB;EAAE,IAAI;EAAO,QAAQ;CAAc,IACnC;EAAE,IAAI;EAAO,QAAQ;CAAY;CAGvC,OAAO;EAAE,IAAI;EAAM,MAAM,MAAM;EAAM,OAAO,MAAM,YAAY,KAAK;CAAM;AAC3E;;;;;;;;;;;;;;;;;;;;AA2BA,eAAe,WAAW,KAA6C;CACrE,MAAM,SAAS,MAAM,kBAAkB,GAAG;CAC1C,IAAI,WAAW,KAAA,GAAW,OAAO;CAEjC,KAAK,MAAM,aAAa,CAAC,SAAS,MAAM,GAAG;EACzC,MAAM,SAAS,MAAM,kBAAkBC,UAAAA,QAAK,KAAK,KAAK,SAAS,CAAC;EAChE,IAAI,WAAW,KAAA,GAAW,OAAO;CACnC;AAGF;AAEA,eAAe,kBAAkB,KAA6C;CAC5E,IAAI,MAAM,OAAOA,UAAAA,QAAK,KAAK,KAAK,eAAe,CAAC,GAAG;EACjD,MAAM,cAAc,OAAA,GAAMC,2BAAAA,gCAAAA,CAAgC,GAAG;EAC7D,OAAO;GAGL,MAAM;IAAE,MAAM;IAAgB,UAAA,GAASC,SAAAA,cAAAA,CAAc,GAAG,CAAC,CAAC;GAAK;GAC/D;EACF;CACF;CAEA,IAAI,MAAM,oBAAoBF,UAAAA,QAAK,KAAK,KAAK,cAAc,CAAC,GAAG;EAC7D,MAAM,cAAc,OAAA,GAAMG,2BAAAA,oBAAAA,CAAoB,GAAG;EACjD,OAAO;GAAE,MAAM;IAAE,MAAM;IAAU,QAAQ;GAAI;GAAG;EAAY;CAC9D;AAGF;;;;;;;;AASA,eAAe,oBAAoB,iBAA2C;CAC5E,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,MAAMC,iBAAAA,QAAI,SAAS,iBAAiB,OAAO,CAAC;EAC/E,OAAO,OAAO,WAAW,YAAY,WAAW,QAAQ,WAAW;CACrE,QAAQ;EACN,OAAO;CACT;AACF;AAEA,eAAe,OAAO,QAAkC;CACtD,IAAI;EACF,MAAMA,iBAAAA,QAAI,KAAK,MAAM;EACrB,OAAO;CACT,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
  import fsp from "node:fs/promises";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import { parseBlockPackLocation } from "@milaboratories/pl-model-common";
6
- //#region src/block_registry/location_provider.ts
6
+ // src/block_registry/location_provider.ts
7
7
  /**
8
8
  * Read the block a template entry's `location` points at.
9
9
  *
@@ -108,7 +108,6 @@ async function exists(target) {
108
108
  return false;
109
109
  }
110
110
  }
111
- //#endregion
112
111
  export { resolveBlockPackLocation };
113
112
 
114
113
  //# sourceMappingURL=location_provider.js.map
@@ -1,5 +1,5 @@
1
1
  let _platforma_sdk_block_tools = require("@platforma-sdk/block-tools");
2
- //#region src/block_registry/registry-v2-provider.ts
2
+ // src/block_registry/registry-v2-provider.ts
3
3
  var V2RegistryProvider = class {
4
4
  http;
5
5
  registries = /* @__PURE__ */ new Map();
@@ -14,7 +14,6 @@ var V2RegistryProvider = class {
14
14
  return newRegistry;
15
15
  }
16
16
  };
17
- //#endregion
18
17
  exports.V2RegistryProvider = V2RegistryProvider;
19
18
 
20
19
  //# sourceMappingURL=registry-v2-provider.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry-v2-provider.cjs","names":["RegistryV2Reader"],"sources":["../../src/block_registry/registry-v2-provider.ts"],"sourcesContent":["import { folderReaderByUrl, RegistryV2Reader } from \"@platforma-sdk/block-tools\";\nimport type { Dispatcher } from \"undici\";\n\nexport class V2RegistryProvider {\n private readonly registries = new Map<string, RegistryV2Reader>();\n\n constructor(private readonly http: Dispatcher) {}\n\n public getRegistry(url: string): RegistryV2Reader {\n const fromCache = this.registries.get(url);\n if (fromCache) return fromCache;\n const newRegistry = new RegistryV2Reader(folderReaderByUrl(url, this.http));\n this.registries.set(url, newRegistry);\n return newRegistry;\n }\n}\n"],"mappings":";;AAGA,IAAa,qBAAb,MAAgC;CAGD;CAF7B,6BAA8B,IAAI,IAA8B;CAEhE,YAAY,MAAmC;EAAlB,KAAA,OAAA;CAAmB;CAEhD,YAAmB,KAA+B;EAChD,MAAM,YAAY,KAAK,WAAW,IAAI,GAAG;EACzC,IAAI,WAAW,OAAO;EACtB,MAAM,cAAc,IAAIA,2BAAAA,kBAAAA,GAAAA,2BAAAA,kBAAAA,CAAmC,KAAK,KAAK,IAAI,CAAC;EAC1E,KAAK,WAAW,IAAI,KAAK,WAAW;EACpC,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"registry-v2-provider.cjs","names":["RegistryV2Reader","folderReaderByUrl"],"sources":["../../src/block_registry/registry-v2-provider.ts"],"sourcesContent":["import { folderReaderByUrl, RegistryV2Reader } from \"@platforma-sdk/block-tools\";\nimport type { Dispatcher } from \"undici\";\n\nexport class V2RegistryProvider {\n private readonly registries = new Map<string, RegistryV2Reader>();\n\n constructor(private readonly http: Dispatcher) {}\n\n public getRegistry(url: string): RegistryV2Reader {\n const fromCache = this.registries.get(url);\n if (fromCache) return fromCache;\n const newRegistry = new RegistryV2Reader(folderReaderByUrl(url, this.http));\n this.registries.set(url, newRegistry);\n return newRegistry;\n }\n}\n"],"mappings":";;AAGA,IAAa,qBAAb,MAAgC;CAGD;CAF7B,6BAA8B,IAAI,IAA8B;CAEhE,YAAY,MAAmC;EAAlB,KAAA,OAAA;CAAmB;CAEhD,YAAmB,KAA+B;EAChD,MAAM,YAAY,KAAK,WAAW,IAAI,GAAG;EACzC,IAAI,WAAW,OAAO;EACtB,MAAM,cAAc,IAAIA,2BAAAA,kBAAAA,GAAiBC,2BAAAA,kBAAAA,CAAkB,KAAK,KAAK,IAAI,CAAC;EAC1E,KAAK,WAAW,IAAI,KAAK,WAAW;EACpC,OAAO;CACT;AACF"}
@@ -1,11 +1,9 @@
1
1
  import { Dispatcher } from "undici";
2
2
  import { RegistryV2Reader } from "@platforma-sdk/block-tools";
3
- //#region src/block_registry/registry-v2-provider.d.ts
4
3
  export declare class V2RegistryProvider {
5
4
  private readonly http;
6
5
  private readonly registries;
7
6
  constructor(http: Dispatcher);
8
7
  getRegistry(url: string): RegistryV2Reader;
9
8
  }
10
- //#endregion
11
9
  //# sourceMappingURL=registry-v2-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry-v2-provider.d.ts","names":[],"sources":["../../src/block_registry/registry-v2-provider.ts"],"mappings":";;;qBAGa;mBAGkB;mBAFZ;EAEjB,YAA6B,MAAM;EAE5B,YAAY,cAAc"}
1
+ {"version":3,"file":"registry-v2-provider.d.ts","names":[],"sources":["../../src/block_registry/registry-v2-provider.ts"],"mappings":";;qBAGa;mBAGkB;mBAFZ;EAEjB,YAA6B,MAAM;EAE5B,YAAY,cAAc"}
@@ -1,5 +1,5 @@
1
1
  import { RegistryV2Reader, folderReaderByUrl } from "@platforma-sdk/block-tools";
2
- //#region src/block_registry/registry-v2-provider.ts
2
+ // src/block_registry/registry-v2-provider.ts
3
3
  var V2RegistryProvider = class {
4
4
  http;
5
5
  registries = /* @__PURE__ */ new Map();
@@ -14,7 +14,6 @@ var V2RegistryProvider = class {
14
14
  return newRegistry;
15
15
  }
16
16
  };
17
- //#endregion
18
17
  export { V2RegistryProvider };
19
18
 
20
19
  //# sourceMappingURL=registry-v2-provider.js.map
@@ -11,7 +11,7 @@ node_path = require_runtime.__toESM(node_path, 1);
11
11
  let yaml = require("yaml");
12
12
  yaml = require_runtime.__toESM(yaml, 1);
13
13
  let _milaboratories_ts_helpers = require("@milaboratories/ts-helpers");
14
- //#region src/block_registry/registry.ts
14
+ // src/block_registry/registry.ts
15
15
  async function getFileContent(path) {
16
16
  try {
17
17
  return await node_fs.default.promises.readFile(path, "utf8");
@@ -166,7 +166,8 @@ var BlockPackRegistry = class {
166
166
  const mtime = await getDevV2PacketMtime(v2Description);
167
167
  const meta = await (0, _platforma_sdk_block_tools.embedBlockPackMetaAbsoluteBytes)(v2Description.meta);
168
168
  if (meta.requiredCapabilities === void 0) {
169
- const derived = require_required_capabilities.deriveRequiredCapabilities(await node_fs.default.promises.readFile(v2Description.components.workflow.main.file));
169
+ const workflowBytes = await node_fs.default.promises.readFile(v2Description.components.workflow.main.file);
170
+ const derived = require_required_capabilities.deriveRequiredCapabilities(workflowBytes);
170
171
  if (derived !== void 0) meta.requiredCapabilities = derived;
171
172
  }
172
173
  const latestOverview = {
@@ -230,7 +231,6 @@ var BlockPackRegistry = class {
230
231
  return await this.v2Provider.getRegistry(regSpec.url).resolveKind(ref, { allowUnstable });
231
232
  }
232
233
  };
233
- //#endregion
234
234
  exports.BlockPackRegistry = BlockPackRegistry;
235
235
  exports.getDevV1PacketMtime = getDevV1PacketMtime;
236
236
  exports.getDevV2PacketMtime = getDevV2PacketMtime;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.cjs","names":["fs","LegacyDevBlockPackFiles","path","RegistryV1","AnyChannel","StableChannel","YAML","deriveRequiredCapabilities"],"sources":["../../src/block_registry/registry.ts"],"sourcesContent":["import type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport type { BlockPackDescriptionAbsolute } from \"@platforma-sdk/block-tools\";\nimport { embedBlockPackMetaAbsoluteBytes, RegistryV1 } from \"@platforma-sdk/block-tools\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport YAML from \"yaml\";\nimport { assertNever } from \"@milaboratories/ts-helpers\";\nimport { LegacyDevBlockPackFiles } from \"../dev_env\";\nimport { tryLoadPackDescription } from \"@platforma-sdk/block-tools\";\nimport { deriveRequiredCapabilities } from \"../mutator/block-pack/required_capabilities\";\nimport type { V2RegistryProvider } from \"./registry-v2-provider\";\nimport type {\n BlockPackId,\n BlockPackListing,\n BlockPackOverview,\n BlockPackFromRegistryV2,\n RegistryEntry,\n RegistryStatus,\n SingleBlockPackOverview,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { AnyChannel, StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockKindReference } from \"@milaboratories/pl-model-common\";\n\nasync function getFileContent(path: string) {\n try {\n return await fs.promises.readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function getFileStat(path: string) {\n try {\n return await fs.promises.stat(path, { bigint: true });\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function getDevV1PacketMtime(devPath: string): Promise<string> {\n let mtime = 0n;\n for (const f of LegacyDevBlockPackFiles) {\n const fullPath = path.join(devPath, ...f);\n const stat = await getFileStat(fullPath);\n if (stat === undefined) continue;\n if (mtime < stat.mtimeNs) mtime = stat.mtimeNs;\n }\n return mtime.toString();\n}\n\nexport async function getDevV2PacketMtime(\n description: BlockPackDescriptionAbsolute,\n): Promise<string> {\n const wfStats = await fs.promises.stat(description.components.workflow.main.file, {\n bigint: true,\n });\n const modelStats = await fs.promises.stat(description.components.model.file, { bigint: true });\n return (wfStats.mtimeNs > modelStats.mtimeNs ? wfStats.mtimeNs : modelStats.mtimeNs).toString();\n}\n\n/** Mtime for a `from-pack-v2` locator: prefer the manifest `timestamp`, else\n * stat the `ui.tgz` archive. Must be called identically by `block_pack.ts`\n * prepare (which bakes the result into the spec) and the update watcher (which\n * recomputes it to diff against the stored value) — divergence makes the block\n * flap perpetually \"update available\". */\nexport async function getFromPackV2Mtime(packDir: string, uiTgzPath: string): Promise<string> {\n try {\n const manifestPath = path.join(packDir, \"manifest.json\");\n const raw = JSON.parse(await fs.promises.readFile(manifestPath, { encoding: \"utf-8\" })) as {\n timestamp?: unknown;\n };\n if (typeof raw.timestamp === \"number\") return String(raw.timestamp);\n } catch {\n // fall through to stat\n }\n const stat = await fs.promises.stat(uiTgzPath, { bigint: true });\n return stat.mtimeNs.toString();\n}\n\nexport class BlockPackRegistry {\n constructor(\n private readonly v2Provider: V2RegistryProvider,\n private readonly registries: RegistryEntry[],\n private readonly http?: Dispatcher,\n ) {}\n\n private async getPackagesForRoot(\n regEntry: RegistryEntry,\n options?: { signal?: AbortSignal },\n ): Promise<BlockPackOverview[]> {\n const result: BlockPackOverview[] = [];\n const regSpec = regEntry.spec;\n switch (regSpec.type) {\n case \"remote-v1\": {\n const httpOptions = this.http !== undefined ? { dispatcher: this.http } : {};\n\n const overviewResponse = await request(`${regSpec.url}/${RegistryV1.GlobalOverviewPath}`, {\n ...httpOptions,\n signal: options?.signal,\n });\n const overview = (await overviewResponse.body.json()) as RegistryV1.GlobalOverview;\n for (const overviewEntry of overview) {\n const { organization, package: pkg, latestMeta, latestVersion } = overviewEntry;\n const id = {\n organization,\n name: pkg,\n version: latestVersion,\n };\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (latestMeta[\"title\"] as string | undefined) ?? \"No title\",\n description: (latestMeta[\"description\"] as string | undefined) ?? \"No Description\",\n organization: {\n name: organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"from-registry-v1\",\n id,\n registryUrl: regSpec.url,\n },\n };\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: overviewEntry.allVersions.map((v) => ({ version: v, channels: [] })),\n });\n }\n return result;\n }\n\n case \"remote-v2\":\n return (\n await this.v2Provider.getRegistry(regSpec.url).listBlockPacks({ signal: options?.signal })\n ).map((e) => ({\n ...e,\n registryId: regEntry.id,\n }));\n // e.latestByChannel[StableChannel]\n // ? {\n // ...e,\n // registryId: regEntry.id,\n // }\n // : {\n // ...e,\n // latestByChannel: {\n // ...e.latestByChannel,\n // [StableChannel]: ((s: SingleBlockPackOverview) => {\n // if (s.spec.type === 'from-registry-v2') {\n // return { ...s, spec: { ...s.spec, channel: StableChannel } };\n // }\n\n // return s;\n // })(e.latestByChannel[AnyChannel]),\n // },\n // registryId: regEntry.id,\n // },\n\n case \"local-dev\":\n for (const entry of await fs.promises.readdir(regSpec.path, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const devPath = path.join(regSpec.path, entry.name);\n\n const legacyYamlContent = await getFileContent(\n path.join(devPath, RegistryV1.PlPackageYamlConfigFile),\n );\n if (legacyYamlContent !== undefined) {\n const config = RegistryV1.PlPackageConfigData.parse(YAML.parse(legacyYamlContent));\n\n const mtime = await getDevV1PacketMtime(devPath);\n\n const id = {\n organization: config.organization,\n name: config.package,\n version: \"DEV\",\n };\n\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (config.meta[\"title\"] as string) ?? \"No title\",\n description: (config.meta[\"description\"] as string) ?? \"No Description\",\n organization: {\n name: config.organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"dev-v2\",\n folder: devPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n } else {\n let actualDevPath = devPath;\n let v2Description = await tryLoadPackDescription(actualDevPath);\n\n if (v2Description === undefined)\n // iterating over expected subfolder names where block developer may put root block-pack package\n for (const bpSubfolder of [\"block\", \"meta\"]) {\n actualDevPath = path.join(devPath, bpSubfolder);\n v2Description = await tryLoadPackDescription(actualDevPath);\n if (v2Description !== undefined) break;\n }\n\n if (v2Description !== undefined) {\n const mtime = await getDevV2PacketMtime(v2Description);\n\n const meta = await embedBlockPackMetaAbsoluteBytes(v2Description.meta);\n\n // `tryLoadPackDescription` reads `package.json#block.meta` —\n // the dev SOURCE meta the developer wrote.\n // `requiredCapabilities` is a PACK-TIME artifact written by\n // `block-tools pack` into `block-pack/manifest.json`.\n // So for any dev block, the source meta never carries the field.\n //\n // To surface the gate at listing time without requiring the\n // developer to re-pack on every workflow change, derive from\n // the compiled workflow bytes directly.\n if (meta.requiredCapabilities === undefined) {\n const workflowBytes = await fs.promises.readFile(\n v2Description.components.workflow.main.file,\n );\n const derived = deriveRequiredCapabilities(workflowBytes);\n if (derived !== undefined) meta.requiredCapabilities = derived;\n }\n\n const latestOverview: SingleBlockPackOverview = {\n id: v2Description.id,\n meta,\n featureFlags: v2Description.featureFlags,\n spec: {\n type: \"dev-v2\",\n folder: actualDevPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id: v2Description.id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n }\n }\n\n continue;\n }\n return result;\n default:\n return assertNever(regSpec);\n }\n }\n\n public async listBlockPacks(options?: { signal?: AbortSignal }): Promise<BlockPackListing> {\n const blockPacks: BlockPackOverview[] = [];\n const registries: RegistryStatus[] = [];\n for (const regSpecs of this.registries) {\n registries.push({ ...regSpecs, status: \"online\" });\n blockPacks.push(...(await this.getPackagesForRoot(regSpecs, options)));\n }\n return { registries, blockPacks };\n }\n\n public async getOverview(\n registryId: string,\n blockId: BlockPackId,\n channel: string,\n ): Promise<SingleBlockPackOverview> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(\n `Only \"remote-v2\" registries support specific package version overview retrieval.`,\n );\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.getSpecificOverview(blockId, channel);\n }\n\n /**\n * Resolve a block-kind reference (`{name}@{selector}`) against a `remote-v2`\n * registry to a concrete `from-registry-v2` block spec. Thin facade cloned\n * from {@link getOverview}: resolve `registryId` → assert `remote-v2` →\n * delegate to the reader's pure-core-backed `resolveKind`. All version-math\n * lives in `@platforma-sdk/block-tools` (no backend involvement).\n */\n public async resolveKind(\n registryId: string,\n ref: BlockKindReference,\n { allowUnstable }: { allowUnstable: boolean },\n ): Promise<BlockPackFromRegistryV2> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(`Only \"remote-v2\" registries support block-kind resolution.`);\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.resolveKind(ref, { allowUnstable });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry.cjs","names":["fs","LegacyDevBlockPackFiles","path","request","RegistryV1","AnyChannel","StableChannel","YAML","tryLoadPackDescription","embedBlockPackMetaAbsoluteBytes","deriveRequiredCapabilities","assertNever"],"sources":["../../src/block_registry/registry.ts"],"sourcesContent":["import type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport type { BlockPackDescriptionAbsolute } from \"@platforma-sdk/block-tools\";\nimport { embedBlockPackMetaAbsoluteBytes, RegistryV1 } from \"@platforma-sdk/block-tools\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport YAML from \"yaml\";\nimport { assertNever } from \"@milaboratories/ts-helpers\";\nimport { LegacyDevBlockPackFiles } from \"../dev_env\";\nimport { tryLoadPackDescription } from \"@platforma-sdk/block-tools\";\nimport { deriveRequiredCapabilities } from \"../mutator/block-pack/required_capabilities\";\nimport type { V2RegistryProvider } from \"./registry-v2-provider\";\nimport type {\n BlockPackId,\n BlockPackListing,\n BlockPackOverview,\n BlockPackFromRegistryV2,\n RegistryEntry,\n RegistryStatus,\n SingleBlockPackOverview,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { AnyChannel, StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockKindReference } from \"@milaboratories/pl-model-common\";\n\nasync function getFileContent(path: string) {\n try {\n return await fs.promises.readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function getFileStat(path: string) {\n try {\n return await fs.promises.stat(path, { bigint: true });\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function getDevV1PacketMtime(devPath: string): Promise<string> {\n let mtime = 0n;\n for (const f of LegacyDevBlockPackFiles) {\n const fullPath = path.join(devPath, ...f);\n const stat = await getFileStat(fullPath);\n if (stat === undefined) continue;\n if (mtime < stat.mtimeNs) mtime = stat.mtimeNs;\n }\n return mtime.toString();\n}\n\nexport async function getDevV2PacketMtime(\n description: BlockPackDescriptionAbsolute,\n): Promise<string> {\n const wfStats = await fs.promises.stat(description.components.workflow.main.file, {\n bigint: true,\n });\n const modelStats = await fs.promises.stat(description.components.model.file, { bigint: true });\n return (wfStats.mtimeNs > modelStats.mtimeNs ? wfStats.mtimeNs : modelStats.mtimeNs).toString();\n}\n\n/** Mtime for a `from-pack-v2` locator: prefer the manifest `timestamp`, else\n * stat the `ui.tgz` archive. Must be called identically by `block_pack.ts`\n * prepare (which bakes the result into the spec) and the update watcher (which\n * recomputes it to diff against the stored value) — divergence makes the block\n * flap perpetually \"update available\". */\nexport async function getFromPackV2Mtime(packDir: string, uiTgzPath: string): Promise<string> {\n try {\n const manifestPath = path.join(packDir, \"manifest.json\");\n const raw = JSON.parse(await fs.promises.readFile(manifestPath, { encoding: \"utf-8\" })) as {\n timestamp?: unknown;\n };\n if (typeof raw.timestamp === \"number\") return String(raw.timestamp);\n } catch {\n // fall through to stat\n }\n const stat = await fs.promises.stat(uiTgzPath, { bigint: true });\n return stat.mtimeNs.toString();\n}\n\nexport class BlockPackRegistry {\n constructor(\n private readonly v2Provider: V2RegistryProvider,\n private readonly registries: RegistryEntry[],\n private readonly http?: Dispatcher,\n ) {}\n\n private async getPackagesForRoot(\n regEntry: RegistryEntry,\n options?: { signal?: AbortSignal },\n ): Promise<BlockPackOverview[]> {\n const result: BlockPackOverview[] = [];\n const regSpec = regEntry.spec;\n switch (regSpec.type) {\n case \"remote-v1\": {\n const httpOptions = this.http !== undefined ? { dispatcher: this.http } : {};\n\n const overviewResponse = await request(`${regSpec.url}/${RegistryV1.GlobalOverviewPath}`, {\n ...httpOptions,\n signal: options?.signal,\n });\n const overview = (await overviewResponse.body.json()) as RegistryV1.GlobalOverview;\n for (const overviewEntry of overview) {\n const { organization, package: pkg, latestMeta, latestVersion } = overviewEntry;\n const id = {\n organization,\n name: pkg,\n version: latestVersion,\n };\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (latestMeta[\"title\"] as string | undefined) ?? \"No title\",\n description: (latestMeta[\"description\"] as string | undefined) ?? \"No Description\",\n organization: {\n name: organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"from-registry-v1\",\n id,\n registryUrl: regSpec.url,\n },\n };\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: overviewEntry.allVersions.map((v) => ({ version: v, channels: [] })),\n });\n }\n return result;\n }\n\n case \"remote-v2\":\n return (\n await this.v2Provider.getRegistry(regSpec.url).listBlockPacks({ signal: options?.signal })\n ).map((e) => ({\n ...e,\n registryId: regEntry.id,\n }));\n // e.latestByChannel[StableChannel]\n // ? {\n // ...e,\n // registryId: regEntry.id,\n // }\n // : {\n // ...e,\n // latestByChannel: {\n // ...e.latestByChannel,\n // [StableChannel]: ((s: SingleBlockPackOverview) => {\n // if (s.spec.type === 'from-registry-v2') {\n // return { ...s, spec: { ...s.spec, channel: StableChannel } };\n // }\n\n // return s;\n // })(e.latestByChannel[AnyChannel]),\n // },\n // registryId: regEntry.id,\n // },\n\n case \"local-dev\":\n for (const entry of await fs.promises.readdir(regSpec.path, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const devPath = path.join(regSpec.path, entry.name);\n\n const legacyYamlContent = await getFileContent(\n path.join(devPath, RegistryV1.PlPackageYamlConfigFile),\n );\n if (legacyYamlContent !== undefined) {\n const config = RegistryV1.PlPackageConfigData.parse(YAML.parse(legacyYamlContent));\n\n const mtime = await getDevV1PacketMtime(devPath);\n\n const id = {\n organization: config.organization,\n name: config.package,\n version: \"DEV\",\n };\n\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (config.meta[\"title\"] as string) ?? \"No title\",\n description: (config.meta[\"description\"] as string) ?? \"No Description\",\n organization: {\n name: config.organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"dev-v2\",\n folder: devPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n } else {\n let actualDevPath = devPath;\n let v2Description = await tryLoadPackDescription(actualDevPath);\n\n if (v2Description === undefined)\n // iterating over expected subfolder names where block developer may put root block-pack package\n for (const bpSubfolder of [\"block\", \"meta\"]) {\n actualDevPath = path.join(devPath, bpSubfolder);\n v2Description = await tryLoadPackDescription(actualDevPath);\n if (v2Description !== undefined) break;\n }\n\n if (v2Description !== undefined) {\n const mtime = await getDevV2PacketMtime(v2Description);\n\n const meta = await embedBlockPackMetaAbsoluteBytes(v2Description.meta);\n\n // `tryLoadPackDescription` reads `package.json#block.meta` —\n // the dev SOURCE meta the developer wrote.\n // `requiredCapabilities` is a PACK-TIME artifact written by\n // `block-tools pack` into `block-pack/manifest.json`.\n // So for any dev block, the source meta never carries the field.\n //\n // To surface the gate at listing time without requiring the\n // developer to re-pack on every workflow change, derive from\n // the compiled workflow bytes directly.\n if (meta.requiredCapabilities === undefined) {\n const workflowBytes = await fs.promises.readFile(\n v2Description.components.workflow.main.file,\n );\n const derived = deriveRequiredCapabilities(workflowBytes);\n if (derived !== undefined) meta.requiredCapabilities = derived;\n }\n\n const latestOverview: SingleBlockPackOverview = {\n id: v2Description.id,\n meta,\n featureFlags: v2Description.featureFlags,\n spec: {\n type: \"dev-v2\",\n folder: actualDevPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id: v2Description.id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n }\n }\n\n continue;\n }\n return result;\n default:\n return assertNever(regSpec);\n }\n }\n\n public async listBlockPacks(options?: { signal?: AbortSignal }): Promise<BlockPackListing> {\n const blockPacks: BlockPackOverview[] = [];\n const registries: RegistryStatus[] = [];\n for (const regSpecs of this.registries) {\n registries.push({ ...regSpecs, status: \"online\" });\n blockPacks.push(...(await this.getPackagesForRoot(regSpecs, options)));\n }\n return { registries, blockPacks };\n }\n\n public async getOverview(\n registryId: string,\n blockId: BlockPackId,\n channel: string,\n ): Promise<SingleBlockPackOverview> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(\n `Only \"remote-v2\" registries support specific package version overview retrieval.`,\n );\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.getSpecificOverview(blockId, channel);\n }\n\n /**\n * Resolve a block-kind reference (`{name}@{selector}`) against a `remote-v2`\n * registry to a concrete `from-registry-v2` block spec. Thin facade cloned\n * from {@link getOverview}: resolve `registryId` → assert `remote-v2` →\n * delegate to the reader's pure-core-backed `resolveKind`. All version-math\n * lives in `@platforma-sdk/block-tools` (no backend involvement).\n */\n public async resolveKind(\n registryId: string,\n ref: BlockKindReference,\n { allowUnstable }: { allowUnstable: boolean },\n ): Promise<BlockPackFromRegistryV2> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(`Only \"remote-v2\" registries support block-kind resolution.`);\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.resolveKind(ref, { allowUnstable });\n }\n}\n"],"mappings":"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"}
@@ -3,7 +3,6 @@ import { BlockPackFromRegistryV2, BlockPackId, BlockPackListing, RegistryEntry,
3
3
  import { Dispatcher } from "undici";
4
4
  import { BlockPackDescriptionAbsolute } from "@platforma-sdk/block-tools";
5
5
  import { BlockKindReference } from "@milaboratories/pl-model-common";
6
- //#region src/block_registry/registry.d.ts
7
6
  export declare function getDevV1PacketMtime(devPath: string): Promise<string>;
8
7
  export declare function getDevV2PacketMtime(description: BlockPackDescriptionAbsolute): Promise<string>;
9
8
  /** Mtime for a `from-pack-v2` locator: prefer the manifest `timestamp`, else
@@ -33,5 +32,4 @@ export declare class BlockPackRegistry {
33
32
  allowUnstable: boolean;
34
33
  }): Promise<BlockPackFromRegistryV2>;
35
34
  }
36
- //#endregion
37
35
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","names":[],"sources":["../../src/block_registry/registry.ts"],"mappings":";;;;;;wBA8CsB,oBAAoB,kBAAkB;wBAWtC,oBACpB,aAAa,+BACZ;;;;;;wBAamB,mBAAmB,iBAAiB,oBAAoB;qBAcjE;mBAEQ;mBACA;mBACA;EAHnB,YACmB,YAAY,oBACZ,YAAY,iBACZ,OAAO;UAGZ;EA4LD,eAAe;IAAY,SAAS;MAAgB,QAAQ;EAU5D,YACX,oBACA,SAAS,aACT,kBACC,QAAQ;;;;;;;;EAkBE,YACX,oBACA,KAAK,sBACH;IAAmB;MACpB,QAAQ"}
1
+ {"version":3,"file":"registry.d.ts","names":[],"sources":["../../src/block_registry/registry.ts"],"mappings":";;;;;wBA8CsB,oBAAoB,kBAAkB;wBAWtC,oBACpB,aAAa,+BACZ;;;;;;wBAamB,mBAAmB,iBAAiB,oBAAoB;qBAcjE;mBAEQ;mBACA;mBACA;EAHnB,YACmB,YAAY,oBACZ,YAAY,iBACZ,OAAO;UAGZ;EA4LD,eAAe;IAAY,SAAS;MAAgB,QAAQ;EAU5D,YACX,oBACA,SAAS,aACT,kBACC,QAAQ;;;;;;;;EAkBE,YACX,oBACA,KAAK,sBACH;IAAmB;MACpB,QAAQ"}
@@ -7,7 +7,7 @@ import fs from "node:fs";
7
7
  import path from "node:path";
8
8
  import YAML from "yaml";
9
9
  import { assertNever } from "@milaboratories/ts-helpers";
10
- //#region src/block_registry/registry.ts
10
+ // src/block_registry/registry.ts
11
11
  async function getFileContent(path) {
12
12
  try {
13
13
  return await fs.promises.readFile(path, "utf8");
@@ -162,7 +162,8 @@ var BlockPackRegistry = class {
162
162
  const mtime = await getDevV2PacketMtime(v2Description);
163
163
  const meta = await embedBlockPackMetaAbsoluteBytes(v2Description.meta);
164
164
  if (meta.requiredCapabilities === void 0) {
165
- const derived = deriveRequiredCapabilities(await fs.promises.readFile(v2Description.components.workflow.main.file));
165
+ const workflowBytes = await fs.promises.readFile(v2Description.components.workflow.main.file);
166
+ const derived = deriveRequiredCapabilities(workflowBytes);
166
167
  if (derived !== void 0) meta.requiredCapabilities = derived;
167
168
  }
168
169
  const latestOverview = {
@@ -226,7 +227,6 @@ var BlockPackRegistry = class {
226
227
  return await this.v2Provider.getRegistry(regSpec.url).resolveKind(ref, { allowUnstable });
227
228
  }
228
229
  };
229
- //#endregion
230
230
  export { BlockPackRegistry, getDevV1PacketMtime, getDevV2PacketMtime, getFromPackV2Mtime };
231
231
 
232
232
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","names":[],"sources":["../../src/block_registry/registry.ts"],"sourcesContent":["import type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport type { BlockPackDescriptionAbsolute } from \"@platforma-sdk/block-tools\";\nimport { embedBlockPackMetaAbsoluteBytes, RegistryV1 } from \"@platforma-sdk/block-tools\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport YAML from \"yaml\";\nimport { assertNever } from \"@milaboratories/ts-helpers\";\nimport { LegacyDevBlockPackFiles } from \"../dev_env\";\nimport { tryLoadPackDescription } from \"@platforma-sdk/block-tools\";\nimport { deriveRequiredCapabilities } from \"../mutator/block-pack/required_capabilities\";\nimport type { V2RegistryProvider } from \"./registry-v2-provider\";\nimport type {\n BlockPackId,\n BlockPackListing,\n BlockPackOverview,\n BlockPackFromRegistryV2,\n RegistryEntry,\n RegistryStatus,\n SingleBlockPackOverview,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { AnyChannel, StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockKindReference } from \"@milaboratories/pl-model-common\";\n\nasync function getFileContent(path: string) {\n try {\n return await fs.promises.readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function getFileStat(path: string) {\n try {\n return await fs.promises.stat(path, { bigint: true });\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function getDevV1PacketMtime(devPath: string): Promise<string> {\n let mtime = 0n;\n for (const f of LegacyDevBlockPackFiles) {\n const fullPath = path.join(devPath, ...f);\n const stat = await getFileStat(fullPath);\n if (stat === undefined) continue;\n if (mtime < stat.mtimeNs) mtime = stat.mtimeNs;\n }\n return mtime.toString();\n}\n\nexport async function getDevV2PacketMtime(\n description: BlockPackDescriptionAbsolute,\n): Promise<string> {\n const wfStats = await fs.promises.stat(description.components.workflow.main.file, {\n bigint: true,\n });\n const modelStats = await fs.promises.stat(description.components.model.file, { bigint: true });\n return (wfStats.mtimeNs > modelStats.mtimeNs ? wfStats.mtimeNs : modelStats.mtimeNs).toString();\n}\n\n/** Mtime for a `from-pack-v2` locator: prefer the manifest `timestamp`, else\n * stat the `ui.tgz` archive. Must be called identically by `block_pack.ts`\n * prepare (which bakes the result into the spec) and the update watcher (which\n * recomputes it to diff against the stored value) — divergence makes the block\n * flap perpetually \"update available\". */\nexport async function getFromPackV2Mtime(packDir: string, uiTgzPath: string): Promise<string> {\n try {\n const manifestPath = path.join(packDir, \"manifest.json\");\n const raw = JSON.parse(await fs.promises.readFile(manifestPath, { encoding: \"utf-8\" })) as {\n timestamp?: unknown;\n };\n if (typeof raw.timestamp === \"number\") return String(raw.timestamp);\n } catch {\n // fall through to stat\n }\n const stat = await fs.promises.stat(uiTgzPath, { bigint: true });\n return stat.mtimeNs.toString();\n}\n\nexport class BlockPackRegistry {\n constructor(\n private readonly v2Provider: V2RegistryProvider,\n private readonly registries: RegistryEntry[],\n private readonly http?: Dispatcher,\n ) {}\n\n private async getPackagesForRoot(\n regEntry: RegistryEntry,\n options?: { signal?: AbortSignal },\n ): Promise<BlockPackOverview[]> {\n const result: BlockPackOverview[] = [];\n const regSpec = regEntry.spec;\n switch (regSpec.type) {\n case \"remote-v1\": {\n const httpOptions = this.http !== undefined ? { dispatcher: this.http } : {};\n\n const overviewResponse = await request(`${regSpec.url}/${RegistryV1.GlobalOverviewPath}`, {\n ...httpOptions,\n signal: options?.signal,\n });\n const overview = (await overviewResponse.body.json()) as RegistryV1.GlobalOverview;\n for (const overviewEntry of overview) {\n const { organization, package: pkg, latestMeta, latestVersion } = overviewEntry;\n const id = {\n organization,\n name: pkg,\n version: latestVersion,\n };\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (latestMeta[\"title\"] as string | undefined) ?? \"No title\",\n description: (latestMeta[\"description\"] as string | undefined) ?? \"No Description\",\n organization: {\n name: organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"from-registry-v1\",\n id,\n registryUrl: regSpec.url,\n },\n };\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: overviewEntry.allVersions.map((v) => ({ version: v, channels: [] })),\n });\n }\n return result;\n }\n\n case \"remote-v2\":\n return (\n await this.v2Provider.getRegistry(regSpec.url).listBlockPacks({ signal: options?.signal })\n ).map((e) => ({\n ...e,\n registryId: regEntry.id,\n }));\n // e.latestByChannel[StableChannel]\n // ? {\n // ...e,\n // registryId: regEntry.id,\n // }\n // : {\n // ...e,\n // latestByChannel: {\n // ...e.latestByChannel,\n // [StableChannel]: ((s: SingleBlockPackOverview) => {\n // if (s.spec.type === 'from-registry-v2') {\n // return { ...s, spec: { ...s.spec, channel: StableChannel } };\n // }\n\n // return s;\n // })(e.latestByChannel[AnyChannel]),\n // },\n // registryId: regEntry.id,\n // },\n\n case \"local-dev\":\n for (const entry of await fs.promises.readdir(regSpec.path, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const devPath = path.join(regSpec.path, entry.name);\n\n const legacyYamlContent = await getFileContent(\n path.join(devPath, RegistryV1.PlPackageYamlConfigFile),\n );\n if (legacyYamlContent !== undefined) {\n const config = RegistryV1.PlPackageConfigData.parse(YAML.parse(legacyYamlContent));\n\n const mtime = await getDevV1PacketMtime(devPath);\n\n const id = {\n organization: config.organization,\n name: config.package,\n version: \"DEV\",\n };\n\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (config.meta[\"title\"] as string) ?? \"No title\",\n description: (config.meta[\"description\"] as string) ?? \"No Description\",\n organization: {\n name: config.organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"dev-v2\",\n folder: devPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n } else {\n let actualDevPath = devPath;\n let v2Description = await tryLoadPackDescription(actualDevPath);\n\n if (v2Description === undefined)\n // iterating over expected subfolder names where block developer may put root block-pack package\n for (const bpSubfolder of [\"block\", \"meta\"]) {\n actualDevPath = path.join(devPath, bpSubfolder);\n v2Description = await tryLoadPackDescription(actualDevPath);\n if (v2Description !== undefined) break;\n }\n\n if (v2Description !== undefined) {\n const mtime = await getDevV2PacketMtime(v2Description);\n\n const meta = await embedBlockPackMetaAbsoluteBytes(v2Description.meta);\n\n // `tryLoadPackDescription` reads `package.json#block.meta` —\n // the dev SOURCE meta the developer wrote.\n // `requiredCapabilities` is a PACK-TIME artifact written by\n // `block-tools pack` into `block-pack/manifest.json`.\n // So for any dev block, the source meta never carries the field.\n //\n // To surface the gate at listing time without requiring the\n // developer to re-pack on every workflow change, derive from\n // the compiled workflow bytes directly.\n if (meta.requiredCapabilities === undefined) {\n const workflowBytes = await fs.promises.readFile(\n v2Description.components.workflow.main.file,\n );\n const derived = deriveRequiredCapabilities(workflowBytes);\n if (derived !== undefined) meta.requiredCapabilities = derived;\n }\n\n const latestOverview: SingleBlockPackOverview = {\n id: v2Description.id,\n meta,\n featureFlags: v2Description.featureFlags,\n spec: {\n type: \"dev-v2\",\n folder: actualDevPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id: v2Description.id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n }\n }\n\n continue;\n }\n return result;\n default:\n return assertNever(regSpec);\n }\n }\n\n public async listBlockPacks(options?: { signal?: AbortSignal }): Promise<BlockPackListing> {\n const blockPacks: BlockPackOverview[] = [];\n const registries: RegistryStatus[] = [];\n for (const regSpecs of this.registries) {\n registries.push({ ...regSpecs, status: \"online\" });\n blockPacks.push(...(await this.getPackagesForRoot(regSpecs, options)));\n }\n return { registries, blockPacks };\n }\n\n public async getOverview(\n registryId: string,\n blockId: BlockPackId,\n channel: string,\n ): Promise<SingleBlockPackOverview> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(\n `Only \"remote-v2\" registries support specific package version overview retrieval.`,\n );\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.getSpecificOverview(blockId, channel);\n }\n\n /**\n * Resolve a block-kind reference (`{name}@{selector}`) against a `remote-v2`\n * registry to a concrete `from-registry-v2` block spec. Thin facade cloned\n * from {@link getOverview}: resolve `registryId` → assert `remote-v2` →\n * delegate to the reader's pure-core-backed `resolveKind`. All version-math\n * lives in `@platforma-sdk/block-tools` (no backend involvement).\n */\n public async resolveKind(\n registryId: string,\n ref: BlockKindReference,\n { allowUnstable }: { allowUnstable: boolean },\n ): Promise<BlockPackFromRegistryV2> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(`Only \"remote-v2\" registries support block-kind resolution.`);\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.resolveKind(ref, { allowUnstable });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","names":[],"sources":["../../src/block_registry/registry.ts"],"sourcesContent":["import type { Dispatcher } from \"undici\";\nimport { request } from \"undici\";\nimport type { BlockPackDescriptionAbsolute } from \"@platforma-sdk/block-tools\";\nimport { embedBlockPackMetaAbsoluteBytes, RegistryV1 } from \"@platforma-sdk/block-tools\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport YAML from \"yaml\";\nimport { assertNever } from \"@milaboratories/ts-helpers\";\nimport { LegacyDevBlockPackFiles } from \"../dev_env\";\nimport { tryLoadPackDescription } from \"@platforma-sdk/block-tools\";\nimport { deriveRequiredCapabilities } from \"../mutator/block-pack/required_capabilities\";\nimport type { V2RegistryProvider } from \"./registry-v2-provider\";\nimport type {\n BlockPackId,\n BlockPackListing,\n BlockPackOverview,\n BlockPackFromRegistryV2,\n RegistryEntry,\n RegistryStatus,\n SingleBlockPackOverview,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { AnyChannel, StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockKindReference } from \"@milaboratories/pl-model-common\";\n\nasync function getFileContent(path: string) {\n try {\n return await fs.promises.readFile(path, \"utf8\");\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nasync function getFileStat(path: string) {\n try {\n return await fs.promises.stat(path, { bigint: true });\n } catch (error: unknown) {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") {\n return undefined;\n }\n throw error;\n }\n}\n\nexport async function getDevV1PacketMtime(devPath: string): Promise<string> {\n let mtime = 0n;\n for (const f of LegacyDevBlockPackFiles) {\n const fullPath = path.join(devPath, ...f);\n const stat = await getFileStat(fullPath);\n if (stat === undefined) continue;\n if (mtime < stat.mtimeNs) mtime = stat.mtimeNs;\n }\n return mtime.toString();\n}\n\nexport async function getDevV2PacketMtime(\n description: BlockPackDescriptionAbsolute,\n): Promise<string> {\n const wfStats = await fs.promises.stat(description.components.workflow.main.file, {\n bigint: true,\n });\n const modelStats = await fs.promises.stat(description.components.model.file, { bigint: true });\n return (wfStats.mtimeNs > modelStats.mtimeNs ? wfStats.mtimeNs : modelStats.mtimeNs).toString();\n}\n\n/** Mtime for a `from-pack-v2` locator: prefer the manifest `timestamp`, else\n * stat the `ui.tgz` archive. Must be called identically by `block_pack.ts`\n * prepare (which bakes the result into the spec) and the update watcher (which\n * recomputes it to diff against the stored value) — divergence makes the block\n * flap perpetually \"update available\". */\nexport async function getFromPackV2Mtime(packDir: string, uiTgzPath: string): Promise<string> {\n try {\n const manifestPath = path.join(packDir, \"manifest.json\");\n const raw = JSON.parse(await fs.promises.readFile(manifestPath, { encoding: \"utf-8\" })) as {\n timestamp?: unknown;\n };\n if (typeof raw.timestamp === \"number\") return String(raw.timestamp);\n } catch {\n // fall through to stat\n }\n const stat = await fs.promises.stat(uiTgzPath, { bigint: true });\n return stat.mtimeNs.toString();\n}\n\nexport class BlockPackRegistry {\n constructor(\n private readonly v2Provider: V2RegistryProvider,\n private readonly registries: RegistryEntry[],\n private readonly http?: Dispatcher,\n ) {}\n\n private async getPackagesForRoot(\n regEntry: RegistryEntry,\n options?: { signal?: AbortSignal },\n ): Promise<BlockPackOverview[]> {\n const result: BlockPackOverview[] = [];\n const regSpec = regEntry.spec;\n switch (regSpec.type) {\n case \"remote-v1\": {\n const httpOptions = this.http !== undefined ? { dispatcher: this.http } : {};\n\n const overviewResponse = await request(`${regSpec.url}/${RegistryV1.GlobalOverviewPath}`, {\n ...httpOptions,\n signal: options?.signal,\n });\n const overview = (await overviewResponse.body.json()) as RegistryV1.GlobalOverview;\n for (const overviewEntry of overview) {\n const { organization, package: pkg, latestMeta, latestVersion } = overviewEntry;\n const id = {\n organization,\n name: pkg,\n version: latestVersion,\n };\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (latestMeta[\"title\"] as string | undefined) ?? \"No title\",\n description: (latestMeta[\"description\"] as string | undefined) ?? \"No Description\",\n organization: {\n name: organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"from-registry-v1\",\n id,\n registryUrl: regSpec.url,\n },\n };\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: overviewEntry.allVersions.map((v) => ({ version: v, channels: [] })),\n });\n }\n return result;\n }\n\n case \"remote-v2\":\n return (\n await this.v2Provider.getRegistry(regSpec.url).listBlockPacks({ signal: options?.signal })\n ).map((e) => ({\n ...e,\n registryId: regEntry.id,\n }));\n // e.latestByChannel[StableChannel]\n // ? {\n // ...e,\n // registryId: regEntry.id,\n // }\n // : {\n // ...e,\n // latestByChannel: {\n // ...e.latestByChannel,\n // [StableChannel]: ((s: SingleBlockPackOverview) => {\n // if (s.spec.type === 'from-registry-v2') {\n // return { ...s, spec: { ...s.spec, channel: StableChannel } };\n // }\n\n // return s;\n // })(e.latestByChannel[AnyChannel]),\n // },\n // registryId: regEntry.id,\n // },\n\n case \"local-dev\":\n for (const entry of await fs.promises.readdir(regSpec.path, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n const devPath = path.join(regSpec.path, entry.name);\n\n const legacyYamlContent = await getFileContent(\n path.join(devPath, RegistryV1.PlPackageYamlConfigFile),\n );\n if (legacyYamlContent !== undefined) {\n const config = RegistryV1.PlPackageConfigData.parse(YAML.parse(legacyYamlContent));\n\n const mtime = await getDevV1PacketMtime(devPath);\n\n const id = {\n organization: config.organization,\n name: config.package,\n version: \"DEV\",\n };\n\n const latestOverview: SingleBlockPackOverview = {\n id,\n meta: {\n title: (config.meta[\"title\"] as string) ?? \"No title\",\n description: (config.meta[\"description\"] as string) ?? \"No Description\",\n organization: {\n name: config.organization,\n url: \"https://unknown.com\",\n },\n },\n spec: {\n type: \"dev-v2\",\n folder: devPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n } else {\n let actualDevPath = devPath;\n let v2Description = await tryLoadPackDescription(actualDevPath);\n\n if (v2Description === undefined)\n // iterating over expected subfolder names where block developer may put root block-pack package\n for (const bpSubfolder of [\"block\", \"meta\"]) {\n actualDevPath = path.join(devPath, bpSubfolder);\n v2Description = await tryLoadPackDescription(actualDevPath);\n if (v2Description !== undefined) break;\n }\n\n if (v2Description !== undefined) {\n const mtime = await getDevV2PacketMtime(v2Description);\n\n const meta = await embedBlockPackMetaAbsoluteBytes(v2Description.meta);\n\n // `tryLoadPackDescription` reads `package.json#block.meta` —\n // the dev SOURCE meta the developer wrote.\n // `requiredCapabilities` is a PACK-TIME artifact written by\n // `block-tools pack` into `block-pack/manifest.json`.\n // So for any dev block, the source meta never carries the field.\n //\n // To surface the gate at listing time without requiring the\n // developer to re-pack on every workflow change, derive from\n // the compiled workflow bytes directly.\n if (meta.requiredCapabilities === undefined) {\n const workflowBytes = await fs.promises.readFile(\n v2Description.components.workflow.main.file,\n );\n const derived = deriveRequiredCapabilities(workflowBytes);\n if (derived !== undefined) meta.requiredCapabilities = derived;\n }\n\n const latestOverview: SingleBlockPackOverview = {\n id: v2Description.id,\n meta,\n featureFlags: v2Description.featureFlags,\n spec: {\n type: \"dev-v2\",\n folder: actualDevPath,\n mtime,\n },\n };\n\n result.push({\n registryId: regEntry.id,\n id: v2Description.id,\n latestByChannel: {\n [AnyChannel]: latestOverview,\n [StableChannel]: latestOverview,\n },\n allVersions: [],\n });\n }\n }\n\n continue;\n }\n return result;\n default:\n return assertNever(regSpec);\n }\n }\n\n public async listBlockPacks(options?: { signal?: AbortSignal }): Promise<BlockPackListing> {\n const blockPacks: BlockPackOverview[] = [];\n const registries: RegistryStatus[] = [];\n for (const regSpecs of this.registries) {\n registries.push({ ...regSpecs, status: \"online\" });\n blockPacks.push(...(await this.getPackagesForRoot(regSpecs, options)));\n }\n return { registries, blockPacks };\n }\n\n public async getOverview(\n registryId: string,\n blockId: BlockPackId,\n channel: string,\n ): Promise<SingleBlockPackOverview> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(\n `Only \"remote-v2\" registries support specific package version overview retrieval.`,\n );\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.getSpecificOverview(blockId, channel);\n }\n\n /**\n * Resolve a block-kind reference (`{name}@{selector}`) against a `remote-v2`\n * registry to a concrete `from-registry-v2` block spec. Thin facade cloned\n * from {@link getOverview}: resolve `registryId` → assert `remote-v2` →\n * delegate to the reader's pure-core-backed `resolveKind`. All version-math\n * lives in `@platforma-sdk/block-tools` (no backend involvement).\n */\n public async resolveKind(\n registryId: string,\n ref: BlockKindReference,\n { allowUnstable }: { allowUnstable: boolean },\n ): Promise<BlockPackFromRegistryV2> {\n const regSpec = this.registries.find((reg) => reg.id === registryId)?.spec;\n if (!regSpec) throw new Error(`Registry with id \"${registryId}\" not found`);\n if (regSpec.type !== \"remote-v2\")\n throw new Error(`Only \"remote-v2\" registries support block-kind resolution.`);\n const reg = this.v2Provider.getRegistry(regSpec.url);\n return await reg.resolveKind(ref, { allowUnstable });\n }\n}\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ const require_location_provider = require("./location_provider.cjs");
2
2
  let _platforma_sdk_model = require("@platforma-sdk/model");
3
3
  let _milaboratories_pl_model_middle_layer = require("@milaboratories/pl-model-middle-layer");
4
4
  let _platforma_sdk_block_tools = require("@platforma-sdk/block-tools");
5
- //#region src/block_registry/template_provider.ts
5
+ // src/block_registry/template_provider.ts
6
6
  /**
7
7
  * The ids of the configured registries a template can be resolved against, in the order
8
8
  * they should be consulted.
@@ -97,7 +97,6 @@ function furthestFailure(current, next) {
97
97
  if (current === void 0) return next;
98
98
  return rank[next] > rank[current] ? next : current;
99
99
  }
100
- //#endregion
101
100
  exports.kindCapableRegistryIds = kindCapableRegistryIds;
102
101
  exports.templateBlockPackProvider = templateBlockPackProvider;
103
102
 
@@ -1 +1 @@
1
- {"version":3,"file":"template_provider.cjs","names":["StableChannel","KindResolutionError","resolveBlockPackLocation"],"sources":["../../src/block_registry/template_provider.ts"],"sourcesContent":["import { KindResolutionError } from \"@platforma-sdk/block-tools\";\nimport type {\n BlockPackFromRegistryV2,\n BlockPackId,\n RegistryEntry,\n SingleBlockPackOverview,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockKindReference } from \"@milaboratories/pl-model-common\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\nimport { ensureError } from \"@platforma-sdk/model\";\nimport type { BlockPackProvider, ExactResolution, KindResolution } from \"../model/template_resolve\";\nimport { resolveBlockPackLocation } from \"./location_provider\";\n\n/**\n * The part of {@link BlockPackRegistry} a template's provider uses.\n *\n * Structural, so the provider can be exercised without a registry, a network or a\n * configured environment — and so it is obvious that these two calls are the entire\n * dependency.\n */\nexport type KindAwareRegistry = {\n resolveKind: (\n registryId: string,\n ref: BlockKindReference,\n options: { allowUnstable: boolean },\n ) => Promise<BlockPackFromRegistryV2>;\n getOverview: (\n registryId: string,\n blockId: BlockPackId,\n channel: string,\n ) => Promise<SingleBlockPackOverview>;\n};\n\n/**\n * The ids of the configured registries a template can be resolved against, in the order\n * they should be consulted.\n *\n * Answers the standing \"which registry\" question, and answers it by capability rather\n * than by preference: kinds are published to the `kinds/` tree of a `remote-v2`\n * registry, so no other registry type can satisfy an entry at all. A `local-dev`\n * registry serves dev packets, which have no manifest and no kind publication — every\n * template entry names a kind, so such a registry can never answer one.\n *\n * Configured order is kept: it is the order the environment chose, and the first\n * registry that has the kind wins. Nothing here dedupes a kind published to two\n * registries — with the search stopping at the first hit, the earlier registry is\n * simply the answer.\n */\nexport function kindCapableRegistryIds(entries: readonly RegistryEntry[]): string[] {\n return entries.filter((entry) => entry.spec.type === \"remote-v2\").map((entry) => entry.id);\n}\n\n/**\n * A {@link BlockPackProvider} over the configured block registries.\n *\n * The adapter between the import path's port and what the registry layer already does:\n * `resolveKind` walks a kind's projection and picks an implementing block,\n * `getOverview` reads one block's manifest. Both live in the registry; the port exists\n * so that resolution can be tested without one, and so that which registries to consult\n * stays an environment decision.\n *\n * Both routes also return the block's published title, because both have to read a\n * manifest to produce a spec anyway and nothing downstream can recover it. On the pinned\n * route it is free; on the kind route it costs one manifest read after the projection.\n *\n * @param registryIds Registries to consult, in order — see {@link kindCapableRegistryIds}\n * @param logger Where a registry that could not answer is recorded. A read failure and\n * an absent block are indistinguishable here (the reader throws for both), so the\n * fallback to the next registry has to swallow the reason; this is the only place it\n * survives\n */\nexport function templateBlockPackProvider(deps: {\n readonly registry: KindAwareRegistry;\n readonly registryIds: readonly string[];\n readonly logger: MiLogger;\n}): BlockPackProvider {\n const { registry, registryIds, logger } = deps;\n\n return {\n byKind: async (kind, options): Promise<KindResolution> => {\n let furthest: KindResolutionFailure | undefined;\n\n for (const registryId of registryIds) {\n try {\n // The selector brand is widened here, deliberately and in one place. The\n // facade types this parameter as an exact `{name}@X.Y.Z` reference, but its\n // implementation passes the version segment to the selector parser, so\n // `~`/`^` resolve correctly — the type is narrower than the behaviour. Until\n // the facade takes the selector brand, the cast is the honest way to say so.\n const spec = await registry.resolveKind(\n registryId,\n kind as unknown as BlockKindReference,\n options,\n );\n // Read back the manifest of the block the projection picked, in the channel it\n // was picked from. `channel` is optional on the spec and the resolver always\n // fills it, so the fallback is unreachable — it exists because the channel only\n // decides where future update suggestions come from, and `stable` is the answer\n // that surprises nobody.\n const overview = await registry.getOverview(\n registryId,\n spec.id,\n spec.channel ?? StableChannel,\n );\n return { ok: true, spec, title: overview.meta.title };\n } catch (e) {\n if (!(e instanceof KindResolutionError)) {\n // Not an answer about this kind: an unreadable registry, or a registry that\n // does not serve kinds at all. Falling through would report \"no such kind\"\n // for what is really an outage, so it propagates instead. (The second case\n // is unreachable through `kindCapableRegistryIds`, which filters by type.)\n throw e;\n }\n furthest = furthestFailure(furthest, e.reason);\n }\n }\n\n return { ok: false, reason: furthest ?? \"no-matching-kind-version\" };\n },\n\n // No registry is consulted for a located entry, and none of this adapter's\n // registry knowledge applies to it — which is why it is a straight delegation.\n byLocation: resolveBlockPackLocation,\n\n byExactVersion: async (id): Promise<ExactResolution> => {\n for (const registryId of registryIds) {\n try {\n // `stable` is recorded on the spec as the channel to watch for updates in.\n // The entry pinned this exact version, so nothing is being chosen here — the\n // channel only decides where a future update suggestion would come from.\n const overview = await registry.getOverview(registryId, id, StableChannel);\n return { ok: true, spec: overview.spec, title: overview.meta.title };\n } catch (e) {\n logger.info(\n `template apply: block ${id.organization}/${id.name} ${id.version} not read ` +\n `from registry '${registryId}': ${ensureError(e).message}`,\n );\n }\n }\n\n return { ok: false, reason: \"no-such-block-version\" };\n },\n };\n}\n\ntype KindResolutionFailure = Extract<KindResolution, { ok: false }>[\"reason\"];\n\n/**\n * The more informative of two failures across registries.\n *\n * With several registries consulted, the reasons can differ — one has never heard of the\n * kind, another has it but only as a pre-release. Reporting the first would tell the\n * reader to check their spelling when the real answer is \"import again with unstable\n * allowed\", so the one that got furthest wins.\n */\nfunction furthestFailure(\n current: KindResolutionFailure | undefined,\n next: KindResolutionFailure,\n): KindResolutionFailure {\n const rank: Record<KindResolutionFailure, number> = {\n \"no-matching-kind-version\": 0,\n \"no-implementation\": 1,\n \"no-stable-implementation\": 2,\n };\n if (current === undefined) return next;\n return rank[next] > rank[current] ? next : current;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiDA,SAAgB,uBAAuB,SAA6C;CAClF,OAAO,QAAQ,QAAQ,UAAU,MAAM,KAAK,SAAS,WAAW,CAAC,CAAC,KAAK,UAAU,MAAM,EAAE;AAC3F;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,0BAA0B,MAIpB;CACpB,MAAM,EAAE,UAAU,aAAa,WAAW;CAE1C,OAAO;EACL,QAAQ,OAAO,MAAM,YAAqC;GACxD,IAAI;GAEJ,KAAK,MAAM,cAAc,aACvB,IAAI;IAMF,MAAM,OAAO,MAAM,SAAS,YAC1B,YACA,MACA,OACF;IAWA,OAAO;KAAE,IAAI;KAAM;KAAM,QAAO,MALT,SAAS,YAC9B,YACA,KAAK,IACL,KAAK,WAAWA,sCAAAA,aAClB,EAAA,CACyC,KAAK;IAAM;GACtD,SAAS,GAAG;IACV,IAAI,EAAE,aAAaC,2BAAAA,sBAKjB,MAAM;IAER,WAAW,gBAAgB,UAAU,EAAE,MAAM;GAC/C;GAGF,OAAO;IAAE,IAAI;IAAO,QAAQ,YAAY;GAA2B;EACrE;EAIA,YAAYC,0BAAAA;EAEZ,gBAAgB,OAAO,OAAiC;GACtD,KAAK,MAAM,cAAc,aACvB,IAAI;IAIF,MAAM,WAAW,MAAM,SAAS,YAAY,YAAY,IAAIF,sCAAAA,aAAa;IACzE,OAAO;KAAE,IAAI;KAAM,MAAM,SAAS;KAAM,OAAO,SAAS,KAAK;IAAM;GACrE,SAAS,GAAG;IACV,OAAO,KACL,yBAAyB,GAAG,aAAa,GAAG,GAAG,KAAK,GAAG,GAAG,QAAQ,2BAC9C,WAAW,MAAA,GAAA,qBAAA,YAAA,CAAiB,CAAC,CAAC,CAAC,SACrD;GACF;GAGF,OAAO;IAAE,IAAI;IAAO,QAAQ;GAAwB;EACtD;CACF;AACF;;;;;;;;;AAYA,SAAS,gBACP,SACA,MACuB;CACvB,MAAM,OAA8C;EAClD,4BAA4B;EAC5B,qBAAqB;EACrB,4BAA4B;CAC9B;CACA,IAAI,YAAY,KAAA,GAAW,OAAO;CAClC,OAAO,KAAK,QAAQ,KAAK,WAAW,OAAO;AAC7C"}
1
+ {"version":3,"file":"template_provider.cjs","names":["StableChannel","KindResolutionError","resolveBlockPackLocation","ensureError"],"sources":["../../src/block_registry/template_provider.ts"],"sourcesContent":["import { KindResolutionError } from \"@platforma-sdk/block-tools\";\nimport type {\n BlockPackFromRegistryV2,\n BlockPackId,\n RegistryEntry,\n SingleBlockPackOverview,\n} from \"@milaboratories/pl-model-middle-layer\";\nimport { StableChannel } from \"@milaboratories/pl-model-middle-layer\";\nimport type { BlockKindReference } from \"@milaboratories/pl-model-common\";\nimport type { MiLogger } from \"@milaboratories/ts-helpers\";\nimport { ensureError } from \"@platforma-sdk/model\";\nimport type { BlockPackProvider, ExactResolution, KindResolution } from \"../model/template_resolve\";\nimport { resolveBlockPackLocation } from \"./location_provider\";\n\n/**\n * The part of {@link BlockPackRegistry} a template's provider uses.\n *\n * Structural, so the provider can be exercised without a registry, a network or a\n * configured environment — and so it is obvious that these two calls are the entire\n * dependency.\n */\nexport type KindAwareRegistry = {\n resolveKind: (\n registryId: string,\n ref: BlockKindReference,\n options: { allowUnstable: boolean },\n ) => Promise<BlockPackFromRegistryV2>;\n getOverview: (\n registryId: string,\n blockId: BlockPackId,\n channel: string,\n ) => Promise<SingleBlockPackOverview>;\n};\n\n/**\n * The ids of the configured registries a template can be resolved against, in the order\n * they should be consulted.\n *\n * Answers the standing \"which registry\" question, and answers it by capability rather\n * than by preference: kinds are published to the `kinds/` tree of a `remote-v2`\n * registry, so no other registry type can satisfy an entry at all. A `local-dev`\n * registry serves dev packets, which have no manifest and no kind publication — every\n * template entry names a kind, so such a registry can never answer one.\n *\n * Configured order is kept: it is the order the environment chose, and the first\n * registry that has the kind wins. Nothing here dedupes a kind published to two\n * registries — with the search stopping at the first hit, the earlier registry is\n * simply the answer.\n */\nexport function kindCapableRegistryIds(entries: readonly RegistryEntry[]): string[] {\n return entries.filter((entry) => entry.spec.type === \"remote-v2\").map((entry) => entry.id);\n}\n\n/**\n * A {@link BlockPackProvider} over the configured block registries.\n *\n * The adapter between the import path's port and what the registry layer already does:\n * `resolveKind` walks a kind's projection and picks an implementing block,\n * `getOverview` reads one block's manifest. Both live in the registry; the port exists\n * so that resolution can be tested without one, and so that which registries to consult\n * stays an environment decision.\n *\n * Both routes also return the block's published title, because both have to read a\n * manifest to produce a spec anyway and nothing downstream can recover it. On the pinned\n * route it is free; on the kind route it costs one manifest read after the projection.\n *\n * @param registryIds Registries to consult, in order — see {@link kindCapableRegistryIds}\n * @param logger Where a registry that could not answer is recorded. A read failure and\n * an absent block are indistinguishable here (the reader throws for both), so the\n * fallback to the next registry has to swallow the reason; this is the only place it\n * survives\n */\nexport function templateBlockPackProvider(deps: {\n readonly registry: KindAwareRegistry;\n readonly registryIds: readonly string[];\n readonly logger: MiLogger;\n}): BlockPackProvider {\n const { registry, registryIds, logger } = deps;\n\n return {\n byKind: async (kind, options): Promise<KindResolution> => {\n let furthest: KindResolutionFailure | undefined;\n\n for (const registryId of registryIds) {\n try {\n // The selector brand is widened here, deliberately and in one place. The\n // facade types this parameter as an exact `{name}@X.Y.Z` reference, but its\n // implementation passes the version segment to the selector parser, so\n // `~`/`^` resolve correctly — the type is narrower than the behaviour. Until\n // the facade takes the selector brand, the cast is the honest way to say so.\n const spec = await registry.resolveKind(\n registryId,\n kind as unknown as BlockKindReference,\n options,\n );\n // Read back the manifest of the block the projection picked, in the channel it\n // was picked from. `channel` is optional on the spec and the resolver always\n // fills it, so the fallback is unreachable — it exists because the channel only\n // decides where future update suggestions come from, and `stable` is the answer\n // that surprises nobody.\n const overview = await registry.getOverview(\n registryId,\n spec.id,\n spec.channel ?? StableChannel,\n );\n return { ok: true, spec, title: overview.meta.title };\n } catch (e) {\n if (!(e instanceof KindResolutionError)) {\n // Not an answer about this kind: an unreadable registry, or a registry that\n // does not serve kinds at all. Falling through would report \"no such kind\"\n // for what is really an outage, so it propagates instead. (The second case\n // is unreachable through `kindCapableRegistryIds`, which filters by type.)\n throw e;\n }\n furthest = furthestFailure(furthest, e.reason);\n }\n }\n\n return { ok: false, reason: furthest ?? \"no-matching-kind-version\" };\n },\n\n // No registry is consulted for a located entry, and none of this adapter's\n // registry knowledge applies to it — which is why it is a straight delegation.\n byLocation: resolveBlockPackLocation,\n\n byExactVersion: async (id): Promise<ExactResolution> => {\n for (const registryId of registryIds) {\n try {\n // `stable` is recorded on the spec as the channel to watch for updates in.\n // The entry pinned this exact version, so nothing is being chosen here — the\n // channel only decides where a future update suggestion would come from.\n const overview = await registry.getOverview(registryId, id, StableChannel);\n return { ok: true, spec: overview.spec, title: overview.meta.title };\n } catch (e) {\n logger.info(\n `template apply: block ${id.organization}/${id.name} ${id.version} not read ` +\n `from registry '${registryId}': ${ensureError(e).message}`,\n );\n }\n }\n\n return { ok: false, reason: \"no-such-block-version\" };\n },\n };\n}\n\ntype KindResolutionFailure = Extract<KindResolution, { ok: false }>[\"reason\"];\n\n/**\n * The more informative of two failures across registries.\n *\n * With several registries consulted, the reasons can differ — one has never heard of the\n * kind, another has it but only as a pre-release. Reporting the first would tell the\n * reader to check their spelling when the real answer is \"import again with unstable\n * allowed\", so the one that got furthest wins.\n */\nfunction furthestFailure(\n current: KindResolutionFailure | undefined,\n next: KindResolutionFailure,\n): KindResolutionFailure {\n const rank: Record<KindResolutionFailure, number> = {\n \"no-matching-kind-version\": 0,\n \"no-implementation\": 1,\n \"no-stable-implementation\": 2,\n };\n if (current === undefined) return next;\n return rank[next] > rank[current] ? next : current;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAiDA,SAAgB,uBAAuB,SAA6C;CAClF,OAAO,QAAQ,QAAQ,UAAU,MAAM,KAAK,SAAS,WAAW,CAAC,CAAC,KAAK,UAAU,MAAM,EAAE;AAC3F;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,0BAA0B,MAIpB;CACpB,MAAM,EAAE,UAAU,aAAa,WAAW;CAE1C,OAAO;EACL,QAAQ,OAAO,MAAM,YAAqC;GACxD,IAAI;GAEJ,KAAK,MAAM,cAAc,aACvB,IAAI;IAMF,MAAM,OAAO,MAAM,SAAS,YAC1B,YACA,MACA,OACF;IAWA,OAAO;KAAE,IAAI;KAAM;KAAM,QAAO,MALT,SAAS,YAC9B,YACA,KAAK,IACL,KAAK,WAAWA,sCAAAA,aAClB,EAAA,CACyC,KAAK;IAAM;GACtD,SAAS,GAAG;IACV,IAAI,EAAE,aAAaC,2BAAAA,sBAKjB,MAAM;IAER,WAAW,gBAAgB,UAAU,EAAE,MAAM;GAC/C;GAGF,OAAO;IAAE,IAAI;IAAO,QAAQ,YAAY;GAA2B;EACrE;EAIA,YAAYC,0BAAAA;EAEZ,gBAAgB,OAAO,OAAiC;GACtD,KAAK,MAAM,cAAc,aACvB,IAAI;IAIF,MAAM,WAAW,MAAM,SAAS,YAAY,YAAY,IAAIF,sCAAAA,aAAa;IACzE,OAAO;KAAE,IAAI;KAAM,MAAM,SAAS;KAAM,OAAO,SAAS,KAAK;IAAM;GACrE,SAAS,GAAG;IACV,OAAO,KACL,yBAAyB,GAAG,aAAa,GAAG,GAAG,KAAK,GAAG,GAAG,QAAQ,2BAC9C,WAAW,MAAA,GAAKG,qBAAAA,YAAAA,CAAY,CAAC,CAAC,CAAC,SACrD;GACF;GAGF,OAAO;IAAE,IAAI;IAAO,QAAQ;GAAwB;EACtD;CACF;AACF;;;;;;;;;AAYA,SAAS,gBACP,SACA,MACuB;CACvB,MAAM,OAA8C;EAClD,4BAA4B;EAC5B,qBAAqB;EACrB,4BAA4B;CAC9B;CACA,IAAI,YAAY,KAAA,GAAW,OAAO;CAClC,OAAO,KAAK,QAAQ,KAAK,WAAW,OAAO;AAC7C"}
@@ -2,7 +2,6 @@ import { BlockPackProvider } from "../model/template_resolve.js";
2
2
  import { BlockPackFromRegistryV2, BlockPackId, RegistryEntry, SingleBlockPackOverview } from "@milaboratories/pl-model-middle-layer";
3
3
  import { MiLogger } from "@milaboratories/ts-helpers";
4
4
  import { BlockKindReference } from "@milaboratories/pl-model-common";
5
- //#region src/block_registry/template_provider.d.ts
6
5
  /**
7
6
  * The part of {@link BlockPackRegistry} a template's provider uses.
8
7
  *
@@ -56,5 +55,4 @@ export declare function templateBlockPackProvider(deps: {
56
55
  readonly registryIds: readonly string[];
57
56
  readonly logger: MiLogger;
58
57
  }): BlockPackProvider;
59
- //#endregion
60
58
  //# sourceMappingURL=template_provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"template_provider.d.ts","names":[],"sources":["../../src/block_registry/template_provider.ts"],"mappings":";;;;;;;;;;;;YAqBY;EACV,cACE,oBACA,KAAK,oBACL;IAAW;QACR,QAAQ;EACb,cACE,oBACA,SAAS,aACT,oBACG,QAAQ;;;;;;;;;;;;;;;;;wBAkBC,uBAAuB,kBAAkB;;;;;;;;;;;;;;;;;;;;wBAuBzC,0BAA0B;WAC/B,UAAU;WACV;WACA,QAAQ;IACf"}
1
+ {"version":3,"file":"template_provider.d.ts","names":[],"sources":["../../src/block_registry/template_provider.ts"],"mappings":";;;;;;;;;;;YAqBY;EACV,cACE,oBACA,KAAK,oBACL;IAAW;QACR,QAAQ;EACb,cACE,oBACA,SAAS,aACT,oBACG,QAAQ;;;;;;;;;;;;;;;;;wBAkBC,uBAAuB,kBAAkB;;;;;;;;;;;;;;;;;;;;wBAuBzC,0BAA0B;WAC/B,UAAU;WACV;WACA,QAAQ;IACf"}
@@ -2,7 +2,7 @@ import { resolveBlockPackLocation } from "./location_provider.js";
2
2
  import { ensureError } from "@platforma-sdk/model";
3
3
  import { StableChannel } from "@milaboratories/pl-model-middle-layer";
4
4
  import { KindResolutionError } from "@platforma-sdk/block-tools";
5
- //#region src/block_registry/template_provider.ts
5
+ // src/block_registry/template_provider.ts
6
6
  /**
7
7
  * The ids of the configured registries a template can be resolved against, in the order
8
8
  * they should be consulted.
@@ -97,7 +97,6 @@ function furthestFailure(current, next) {
97
97
  if (current === void 0) return next;
98
98
  return rank[next] > rank[current] ? next : current;
99
99
  }
100
- //#endregion
101
100
  export { kindCapableRegistryIds, templateBlockPackProvider };
102
101
 
103
102
  //# sourceMappingURL=template_provider.js.map
@@ -8,7 +8,7 @@ let semver = require("semver");
8
8
  semver = require_runtime.__toESM(semver, 1);
9
9
  let canonicalize = require("canonicalize");
10
10
  canonicalize = require_runtime.__toESM(canonicalize, 1);
11
- //#region src/block_registry/watcher.ts
11
+ // src/block_registry/watcher.ts
12
12
  const DefaultBlockUpdateWatcherOps = { minDelay: 1500 };
13
13
  const NoUpdatesKey = "__no_updates__";
14
14
  var BlockUpdateWatcher = class extends _milaboratories_computable.PollComputablePool {
@@ -69,7 +69,8 @@ var BlockUpdateWatcher = class extends _milaboratories_computable.PollComputable
69
69
  }
70
70
  case "from-pack-v2": try {
71
71
  const packDir = (0, node_url.fileURLToPath)(cSpec.packUrl);
72
- const mtime = await require_registry.getFromPackV2Mtime(packDir, (await (0, _platforma_sdk_block_tools.loadPackDescriptionFromManifest)(packDir)).components.ui.folder);
72
+ const description = await (0, _platforma_sdk_block_tools.loadPackDescriptionFromManifest)(packDir);
73
+ const mtime = await require_registry.getFromPackV2Mtime(packDir, description.components.ui.folder);
73
74
  if (mtime === cSpec.mtime) return { suggestions: [] };
74
75
  else return {
75
76
  mainSuggestion: {
@@ -87,15 +88,18 @@ var BlockUpdateWatcher = class extends _milaboratories_computable.PollComputable
87
88
  if (versionLock === "patch") return { suggestions: [] };
88
89
  const registry = this.registryProvider.getRegistry(cSpec.registryUrl);
89
90
  let channel = this.preferredUpdateChannel;
90
- if (channel === void 0) if (cSpec.channel === void 0) if (await registry.getLatestOverview(cSpec.id, _milaboratories_pl_model_middle_layer.StableChannel)) channel = _milaboratories_pl_model_middle_layer.StableChannel;
91
- else {
92
- if (await registry.getLatestOverview(cSpec.id, _milaboratories_pl_model_middle_layer.AnyChannel) === void 0) {
93
- this.logger.error(`No "any" channel record for ${(0, _milaboratories_pl_model_middle_layer.blockPackIdToString)(cSpec.id)}`);
94
- return { suggestions: [] };
95
- }
96
- channel = _milaboratories_pl_model_middle_layer.AnyChannel;
91
+ if (channel === void 0) {
92
+ if (cSpec.channel === void 0) {
93
+ if (await registry.getLatestOverview(cSpec.id, _milaboratories_pl_model_middle_layer.StableChannel)) channel = _milaboratories_pl_model_middle_layer.StableChannel;
94
+ else {
95
+ if (await registry.getLatestOverview(cSpec.id, _milaboratories_pl_model_middle_layer.AnyChannel) === void 0) {
96
+ this.logger.error(`No "any" channel record for ${(0, _milaboratories_pl_model_middle_layer.blockPackIdToString)(cSpec.id)}`);
97
+ return { suggestions: [] };
98
+ }
99
+ channel = _milaboratories_pl_model_middle_layer.AnyChannel;
100
+ }
101
+ } else channel = cSpec.channel;
97
102
  }
98
- else channel = cSpec.channel;
99
103
  const vSuggestions = await registry.getUpdateSuggestions(cSpec.id, channel);
100
104
  if (vSuggestions === void 0 || vSuggestions.length === 0) return { suggestions: [] };
101
105
  vSuggestions.reverse();
@@ -107,9 +111,7 @@ var BlockUpdateWatcher = class extends _milaboratories_computable.PollComputable
107
111
  case "major":
108
112
  vMainSuggestion = vSuggestions.find((v) => v.type !== "major")?.update;
109
113
  break;
110
- case "minor":
111
- vMainSuggestion = vSuggestions.find((v) => v.type === "patch")?.update;
112
- break;
114
+ case "minor": vMainSuggestion = vSuggestions.find((v) => v.type === "patch")?.update;
113
115
  }
114
116
  const suggestions = vSuggestions.map(({ type, update }) => ({
115
117
  type,
@@ -156,7 +158,6 @@ var BlockUpdateWatcher = class extends _milaboratories_computable.PollComputable
156
158
  return (0, canonicalize.default)(res1) === (0, canonicalize.default)(res2);
157
159
  }
158
160
  };
159
- //#endregion
160
161
  exports.BlockUpdateWatcher = BlockUpdateWatcher;
161
162
  exports.DefaultBlockUpdateWatcherOps = DefaultBlockUpdateWatcherOps;
162
163