@highstate/backend 0.9.18 → 0.9.19

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 (331) hide show
  1. package/dist/chunk-5WVU2AK4.js +1535 -0
  2. package/dist/chunk-5WVU2AK4.js.map +1 -0
  3. package/dist/{chunk-OU5OQBLB.js → chunk-I7BWSAN6.js} +3 -28
  4. package/dist/{chunk-OU5OQBLB.js.map → chunk-I7BWSAN6.js.map} +1 -1
  5. package/dist/chunk-VB4YL327.js +139 -0
  6. package/dist/chunk-VB4YL327.js.map +1 -0
  7. package/dist/database/local/prisma.config.js +26 -0
  8. package/dist/database/local/prisma.config.js.map +1 -0
  9. package/dist/highstate.manifest.json +2 -1
  10. package/dist/index.js +7587 -7291
  11. package/dist/index.js.map +1 -1
  12. package/dist/library/package-resolution-worker.js +1 -1
  13. package/dist/library/package-resolution-worker.js.map +1 -1
  14. package/dist/library/worker/main.js +35 -29
  15. package/dist/library/worker/main.js.map +1 -1
  16. package/dist/shared/index.js +2 -2
  17. package/package.json +18 -9
  18. package/prisma/backend/_schema/layout.prisma +7 -0
  19. package/prisma/backend/_schema/library.prisma +17 -0
  20. package/prisma/backend/_schema/project.prisma +101 -0
  21. package/prisma/backend/_schema/pulumi.prisma +17 -0
  22. package/prisma/backend/postgresql/main.prisma +17 -0
  23. package/prisma/backend/sqlite/main.prisma +17 -0
  24. package/prisma/backend/sqlite/migrations/20250817070609_initiial/migration.sql +34 -0
  25. package/prisma/backend/sqlite/migrations/20250817104948_add_fields/migration.sql +59 -0
  26. package/prisma/backend/sqlite/migrations/20250818082732_add_models/migration.sql +41 -0
  27. package/prisma/backend/sqlite/migrations/20250818083106_a/migration.sql +19 -0
  28. package/prisma/backend/sqlite/migrations/20250818101945_hi/migration.sql +1 -0
  29. package/prisma/backend/sqlite/migrations/20250819082315_a/migration.sql +5 -0
  30. package/prisma/backend/sqlite/migrations/migration_lock.toml +3 -0
  31. package/prisma/project/api-key.prisma +27 -0
  32. package/prisma/project/artifact.prisma +52 -0
  33. package/prisma/project/custom-status.prisma +46 -0
  34. package/prisma/project/evaluation.prisma +35 -0
  35. package/prisma/project/instance.prisma +160 -0
  36. package/prisma/project/layout.prisma +23 -0
  37. package/prisma/project/lock.prisma +18 -0
  38. package/prisma/project/main.prisma +17 -0
  39. package/prisma/project/migrations/20250816081310_initial/migration.sql +300 -0
  40. package/prisma/project/migrations/20250816082523_test/migration.sql +72 -0
  41. package/prisma/project/migrations/20250818065643_update/migration.sql +42 -0
  42. package/prisma/project/migrations/20250818070758_a/migration.sql +8 -0
  43. package/prisma/project/migrations/20250818070913_a/migration.sql +8 -0
  44. package/prisma/project/migrations/20250818082720_add_motels/migration.sql +11 -0
  45. package/prisma/project/migrations/20250818112523_hello/migration.sql +35 -0
  46. package/prisma/project/migrations/20250819082305_a/migration.sql +14 -0
  47. package/prisma/project/migrations/20250819165004_add_missing_fields/migration.sql +216 -0
  48. package/prisma/project/migrations/20250819171309_a/migration.sql +22 -0
  49. package/prisma/project/migrations/20250820113949_a/migration.sql +66 -0
  50. package/prisma/project/migrations/20250820144256_b/migration.sql +31 -0
  51. package/prisma/project/migrations/20250820145547_a/migration.sql +24 -0
  52. package/prisma/project/migrations/20250820182517_b/migration.sql +2 -0
  53. package/prisma/project/migrations/20250821172324_a/migration.sql +2 -0
  54. package/prisma/project/migrations/20250822081339_a/migration.sql +219 -0
  55. package/prisma/project/migrations/20250822083742_b/migration.sql +1 -0
  56. package/prisma/project/migrations/20250822105134_boom/migration.sql +1 -0
  57. package/prisma/project/migrations/20250822141028_b/migration.sql +1 -0
  58. package/prisma/project/migrations/20250822142342_b/migration.sql +16 -0
  59. package/prisma/project/migrations/20250824072720_a/migration.sql +1 -0
  60. package/prisma/project/migrations/20250824093656_b/migration.sql +21 -0
  61. package/prisma/project/migrations/20250825082518_a/migration.sql +1 -0
  62. package/prisma/project/migrations/20250825085343_b/migration.sql +1 -0
  63. package/prisma/project/migrations/20250825091312_a/migration.sql +1 -0
  64. package/prisma/project/migrations/20250903095431_hi/migration.sql +44 -0
  65. package/prisma/project/migrations/20250903174255_a/migration.sql +24 -0
  66. package/prisma/project/migrations/20250908095205_hi/migration.sql +18 -0
  67. package/prisma/project/migrations/20250909155857_hi/migration.sql +15 -0
  68. package/prisma/project/migrations/migration_lock.toml +3 -0
  69. package/prisma/project/model.prisma +37 -0
  70. package/prisma/project/operation.prisma +148 -0
  71. package/prisma/project/page.prisma +41 -0
  72. package/prisma/project/secret.prisma +42 -0
  73. package/prisma/project/service-account.prisma +36 -0
  74. package/prisma/project/terminal.prisma +90 -0
  75. package/prisma/project/trigger.prisma +31 -0
  76. package/prisma/project/unlock-method.prisma +32 -0
  77. package/prisma/project/worker.prisma +138 -0
  78. package/src/artifact/abstractions.ts +13 -13
  79. package/src/artifact/encryption.ts +30 -54
  80. package/src/artifact/factory.ts +6 -9
  81. package/src/artifact/local.ts +33 -46
  82. package/src/business/api-key.ts +24 -36
  83. package/src/business/artifact.test.ts +978 -0
  84. package/src/business/artifact.ts +136 -216
  85. package/src/business/evaluation.ts +328 -0
  86. package/src/business/index.ts +5 -2
  87. package/src/business/instance-lock.test.ts +1060 -0
  88. package/src/business/instance-lock.ts +387 -78
  89. package/src/business/instance-state.test.ts +735 -0
  90. package/src/business/instance-state.ts +582 -337
  91. package/src/business/operation.test.ts +439 -0
  92. package/src/business/operation.ts +174 -208
  93. package/src/business/project-model.ts +258 -0
  94. package/src/business/project-unlock.ts +168 -126
  95. package/src/business/project.ts +287 -179
  96. package/src/business/secret.test.ts +465 -130
  97. package/src/business/secret.ts +186 -217
  98. package/src/business/settings.test.ts +695 -0
  99. package/src/business/settings.ts +855 -0
  100. package/src/business/terminal-session.ts +90 -0
  101. package/src/business/unit-extra.test.ts +539 -0
  102. package/src/business/unit-extra.ts +160 -0
  103. package/src/business/worker.test.ts +356 -579
  104. package/src/business/worker.ts +238 -339
  105. package/src/common/codebase.ts +65 -0
  106. package/src/common/index.ts +3 -5
  107. package/src/common/logger.ts +5 -0
  108. package/src/common/utils.ts +4 -3
  109. package/src/config.ts +10 -11
  110. package/src/database/_generated/backend/postgresql/client.ts +72 -0
  111. package/src/database/_generated/backend/postgresql/commonInputTypes.ts +350 -0
  112. package/src/database/_generated/backend/postgresql/enums.ts +13 -0
  113. package/src/database/_generated/backend/postgresql/internal/class.ts +320 -0
  114. package/src/database/_generated/backend/postgresql/internal/prismaNamespace.ts +1238 -0
  115. package/src/database/_generated/backend/postgresql/models/Library.ts +1263 -0
  116. package/src/database/_generated/backend/postgresql/models/Project.ts +2175 -0
  117. package/src/database/_generated/backend/postgresql/models/ProjectModelStorage.ts +1263 -0
  118. package/src/database/_generated/backend/postgresql/models/ProjectSpace.ts +1602 -0
  119. package/src/database/_generated/backend/postgresql/models/PulumiBackend.ts +1263 -0
  120. package/src/database/_generated/backend/postgresql/models/UserWorkspaseLayout.ts +1065 -0
  121. package/src/database/_generated/backend/postgresql/models.ts +16 -0
  122. package/src/database/_generated/backend/postgresql/pjtg.ts +182 -0
  123. package/src/database/_generated/backend/sqlite/client.ts +72 -0
  124. package/src/database/_generated/backend/sqlite/commonInputTypes.ts +331 -0
  125. package/src/database/_generated/backend/sqlite/enums.ts +13 -0
  126. package/src/database/_generated/backend/sqlite/internal/class.ts +318 -0
  127. package/src/database/_generated/backend/sqlite/internal/prismaNamespace.ts +1207 -0
  128. package/src/database/_generated/backend/sqlite/models/Library.ts +1261 -0
  129. package/src/database/_generated/backend/sqlite/models/Project.ts +2169 -0
  130. package/src/database/_generated/backend/sqlite/models/ProjectModelStorage.ts +1261 -0
  131. package/src/database/_generated/backend/sqlite/models/ProjectSpace.ts +1599 -0
  132. package/src/database/_generated/backend/sqlite/models/PulumiBackend.ts +1261 -0
  133. package/src/database/_generated/backend/sqlite/models/UserWorkspaseLayout.ts +1063 -0
  134. package/src/database/_generated/backend/sqlite/models.ts +16 -0
  135. package/src/database/_generated/backend/sqlite/pjtg.ts +182 -0
  136. package/src/database/_generated/project/client.ts +204 -0
  137. package/src/database/_generated/project/commonInputTypes.ts +827 -0
  138. package/src/database/_generated/project/enums.ts +104 -0
  139. package/src/database/_generated/project/internal/class.ts +479 -0
  140. package/src/database/_generated/project/internal/prismaNamespace.ts +2974 -0
  141. package/src/database/_generated/project/models/ApiKey.ts +1506 -0
  142. package/src/database/_generated/project/models/Artifact.ts +2051 -0
  143. package/src/database/_generated/project/models/HubModel.ts +1125 -0
  144. package/src/database/_generated/project/models/InstanceCustomStatus.ts +1713 -0
  145. package/src/database/_generated/project/models/InstanceEvaluationState.ts +1312 -0
  146. package/src/database/_generated/project/models/InstanceLock.ts +1268 -0
  147. package/src/database/_generated/project/models/InstanceModel.ts +1125 -0
  148. package/src/database/_generated/project/models/InstanceOperationState.ts +1707 -0
  149. package/src/database/_generated/project/models/InstanceState.ts +4613 -0
  150. package/src/database/_generated/project/models/Operation.ts +1647 -0
  151. package/src/database/_generated/project/models/OperationLog.ts +1455 -0
  152. package/src/database/_generated/project/models/Page.ts +1838 -0
  153. package/src/database/_generated/project/models/Secret.ts +1692 -0
  154. package/src/database/_generated/project/models/ServiceAccount.ts +2165 -0
  155. package/src/database/_generated/project/models/Terminal.ts +2038 -0
  156. package/src/database/_generated/project/models/TerminalSession.ts +1454 -0
  157. package/src/database/_generated/project/models/TerminalSessionLog.ts +1280 -0
  158. package/src/database/_generated/project/models/Trigger.ts +1430 -0
  159. package/src/database/_generated/project/models/UnlockMethod.ts +1220 -0
  160. package/src/database/_generated/project/models/UserCompositeViewport.ts +1280 -0
  161. package/src/database/_generated/project/models/UserProjectViewport.ts +1059 -0
  162. package/src/database/_generated/project/models/Worker.ts +1459 -0
  163. package/src/database/_generated/project/models/WorkerUnitRegistration.ts +1524 -0
  164. package/src/database/_generated/project/models/WorkerVersion.ts +1974 -0
  165. package/src/database/_generated/project/models/WorkerVersionLog.ts +1318 -0
  166. package/src/database/_generated/project/models.ts +35 -0
  167. package/src/database/_generated/project/pjtg.ts +182 -0
  168. package/src/database/abstractions.ts +19 -0
  169. package/src/database/factory.ts +37 -0
  170. package/src/database/index.ts +6 -0
  171. package/src/database/local/backend.ts +134 -0
  172. package/src/database/local/index.ts +3 -0
  173. package/src/database/local/meta.ts +46 -0
  174. package/src/database/local/prisma.config.ts +25 -0
  175. package/src/database/local/project.ts +39 -0
  176. package/src/database/manager.ts +181 -0
  177. package/src/database/migrate.ts +35 -0
  178. package/src/database/prisma.ts +56 -0
  179. package/src/database/well-known.ts +38 -0
  180. package/src/index.ts +4 -4
  181. package/src/library/abstractions.ts +3 -5
  182. package/src/library/factory.ts +1 -1
  183. package/src/library/local.ts +81 -26
  184. package/src/library/package-resolution-worker.ts +1 -1
  185. package/src/library/worker/evaluator.ts +40 -23
  186. package/src/library/worker/loader.lite.ts +1 -1
  187. package/src/library/worker/main.ts +3 -10
  188. package/src/library/worker/protocol.ts +0 -1
  189. package/src/lock/index.ts +0 -1
  190. package/src/lock/manager.ts +0 -10
  191. package/src/orchestrator/manager.ts +190 -104
  192. package/src/orchestrator/operation-context.ts +357 -0
  193. package/src/orchestrator/operation-plan.destroy.test.md +357 -0
  194. package/src/orchestrator/operation-plan.destroy.test.ts +775 -0
  195. package/src/orchestrator/operation-plan.fixtures.ts +213 -0
  196. package/src/orchestrator/operation-plan.md +198 -0
  197. package/src/orchestrator/operation-plan.refresh.test.md +199 -0
  198. package/src/orchestrator/operation-plan.refresh.test.ts +367 -0
  199. package/src/orchestrator/operation-plan.ts +709 -0
  200. package/src/orchestrator/operation-plan.update.test.md +485 -0
  201. package/src/orchestrator/operation-plan.update.test.ts +1066 -0
  202. package/src/orchestrator/operation-workset.ts +233 -578
  203. package/src/orchestrator/operation.ts +435 -948
  204. package/src/orchestrator/plan-test-builder.ts +267 -0
  205. package/src/project-model/abstractions.ts +118 -0
  206. package/src/project-model/backends/codebase.ts +365 -0
  207. package/src/project-model/backends/database.ts +440 -0
  208. package/src/project-model/errors.ts +81 -0
  209. package/src/project-model/factory.ts +24 -0
  210. package/src/project-model/index.ts +4 -0
  211. package/src/project-model/utils.test.ts +544 -0
  212. package/src/project-model/utils.ts +242 -0
  213. package/src/pubsub/abstractions.ts +10 -1
  214. package/src/pubsub/factory.ts +4 -4
  215. package/src/pubsub/index.ts +1 -0
  216. package/src/pubsub/manager.ts +29 -13
  217. package/src/pubsub/memory.ts +31 -0
  218. package/src/runner/abstractions.ts +33 -41
  219. package/src/runner/artifact-env.ts +19 -8
  220. package/src/runner/factory.ts +6 -6
  221. package/src/runner/force-abort.ts +3 -6
  222. package/src/runner/local.ts +64 -67
  223. package/src/runner/pulumi.ts +23 -63
  224. package/src/services.ts +181 -123
  225. package/src/shared/models/backend/index.ts +3 -1
  226. package/src/shared/models/backend/library.ts +9 -1
  227. package/src/shared/models/backend/project.ts +43 -42
  228. package/src/shared/models/backend/pulumi.ts +14 -0
  229. package/src/shared/models/backend/unlock-method.ts +1 -1
  230. package/src/shared/models/backend/well-known.ts +58 -0
  231. package/src/shared/models/base.ts +40 -26
  232. package/src/shared/models/errors.ts +82 -1
  233. package/src/shared/models/index.ts +3 -2
  234. package/src/shared/models/prisma.ts +36 -0
  235. package/src/shared/models/project/api-key.ts +37 -59
  236. package/src/shared/models/project/artifact.ts +16 -76
  237. package/src/shared/models/project/custom-status.ts +12 -0
  238. package/src/shared/models/project/index.ts +8 -7
  239. package/src/shared/models/project/lock.ts +10 -78
  240. package/src/shared/models/project/model.ts +19 -1
  241. package/src/shared/models/project/operation.ts +222 -99
  242. package/src/shared/models/project/page.ts +37 -48
  243. package/src/shared/models/project/secret.ts +29 -89
  244. package/src/shared/models/project/service-account.ts +12 -17
  245. package/src/shared/models/project/state.ts +100 -407
  246. package/src/shared/models/project/terminal.ts +75 -88
  247. package/src/shared/models/project/trigger.ts +13 -49
  248. package/src/shared/models/project/unlock-method.ts +20 -26
  249. package/src/shared/models/project/worker.ts +89 -90
  250. package/src/shared/resolvers/graph-resolver.ts +21 -0
  251. package/src/shared/resolvers/index.ts +1 -1
  252. package/src/shared/resolvers/input-hash.ts +24 -14
  253. package/src/shared/resolvers/input.ts +1 -1
  254. package/src/shared/resolvers/registry.ts +5 -4
  255. package/src/shared/resolvers/state.ts +12 -1
  256. package/src/shared/resolvers/validation.ts +7 -3
  257. package/src/shared/utils/index.ts +1 -2
  258. package/src/shared/utils/promise-tracker.ts +30 -3
  259. package/src/terminal/abstractions.ts +1 -1
  260. package/src/terminal/docker.ts +3 -3
  261. package/src/terminal/manager.ts +102 -118
  262. package/src/test-utils/database.ts +119 -0
  263. package/src/test-utils/index.ts +2 -0
  264. package/src/test-utils/services.ts +134 -0
  265. package/src/unlock/abstractions.ts +5 -23
  266. package/src/unlock/memory.ts +9 -14
  267. package/src/worker/abstractions.ts +7 -4
  268. package/src/worker/docker.ts +14 -19
  269. package/src/worker/manager.ts +366 -97
  270. package/dist/chunk-NAAIDR4U.js +0 -8499
  271. package/dist/chunk-NAAIDR4U.js.map +0 -1
  272. package/dist/chunk-Y7DXREVO.js +0 -1745
  273. package/dist/chunk-Y7DXREVO.js.map +0 -1
  274. package/dist/magic-string.es-5ABAC4JN.js +0 -1292
  275. package/dist/magic-string.es-5ABAC4JN.js.map +0 -1
  276. package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +0 -356
  277. package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +0 -274
  278. package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +0 -223
  279. package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +0 -147
  280. package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +0 -280
  281. package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +0 -360
  282. package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +0 -215
  283. package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +0 -427
  284. package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +0 -217
  285. package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +0 -132
  286. package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +0 -454
  287. package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +0 -426
  288. package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +0 -372
  289. package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +0 -383
  290. package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +0 -245
  291. package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +0 -174
  292. package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +0 -432
  293. package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +0 -220
  294. package/src/business/backend-unlock.ts +0 -10
  295. package/src/common/clock.ts +0 -18
  296. package/src/common/performance.ts +0 -44
  297. package/src/common/random.ts +0 -68
  298. package/src/common/test/index.ts +0 -2
  299. package/src/common/test/render.ts +0 -98
  300. package/src/common/test/tracer.ts +0 -359
  301. package/src/hotstate/abstractions.ts +0 -48
  302. package/src/hotstate/factory.ts +0 -17
  303. package/src/hotstate/index.ts +0 -3
  304. package/src/hotstate/manager.ts +0 -192
  305. package/src/hotstate/memory.ts +0 -100
  306. package/src/hotstate/validation.ts +0 -100
  307. package/src/lock/test.ts +0 -108
  308. package/src/project/abstractions.ts +0 -78
  309. package/src/project/evaluation.ts +0 -248
  310. package/src/project/factory.ts +0 -11
  311. package/src/project/index.ts +0 -3
  312. package/src/project/local.ts +0 -417
  313. package/src/pubsub/local.ts +0 -36
  314. package/src/pubsub/validation.ts +0 -33
  315. package/src/shared/utils/args.ts +0 -25
  316. package/src/state/abstractions.ts +0 -289
  317. package/src/state/encryption.ts +0 -98
  318. package/src/state/factory.ts +0 -20
  319. package/src/state/index.ts +0 -7
  320. package/src/state/local/backend.ts +0 -106
  321. package/src/state/local/collection.ts +0 -361
  322. package/src/state/local/index.ts +0 -2
  323. package/src/state/manager.ts +0 -890
  324. package/src/state/memory/backend.ts +0 -70
  325. package/src/state/memory/collection.ts +0 -270
  326. package/src/state/memory/index.ts +0 -2
  327. package/src/state/repository/index.ts +0 -2
  328. package/src/state/repository/repository.index.ts +0 -193
  329. package/src/state/repository/repository.ts +0 -507
  330. package/src/state/test.ts +0 -457
  331. /package/src/{state → database/local}/keyring.ts +0 -0
@@ -1,47 +1,52 @@
1
+ /** biome-ignore-all lint/complexity/useLiteralKeys: не ори на меня */
2
+
1
3
  import type { ConfigMap, OutputMap, Stack } from "@pulumi/pulumi/automation/index.js"
2
- import type { LibraryBackend, ResolvedUnitSource } from "../library"
3
- import type { ArtifactBackend, ArtifactService } from "../artifact"
4
4
  import type { Logger } from "pino"
5
+ import type { ArtifactBackend, ArtifactService } from "../artifact"
6
+ import type { LibraryBackend, ResolvedUnitSource } from "../library"
7
+ import type {
8
+ OperationType,
9
+ RunnerBackend,
10
+ TypedUnitStateUpdate,
11
+ UnitDestroyOptions,
12
+ UnitOptions,
13
+ UnitStateUpdate,
14
+ UnitUpdateOptions,
15
+ } from "./abstractions"
5
16
  import type { DualAbortSignal } from "./force-abort"
6
17
  import { EventEmitter, on } from "node:events"
7
- import { resolve, join } from "node:path"
8
- import { tmpdir } from "node:os"
9
18
  import { mkdtemp, rm } from "node:fs/promises"
10
- import { getInstanceId, unitArtifactSchema, unitSecretSchema } from "@highstate/contract"
11
- import { ensureDependencyInstalled } from "nypm"
12
- import { mapValues, omitBy } from "remeda"
13
- import { z } from "zod"
14
- import { sha256 } from "@noble/hashes/sha2"
15
- import { bytesToHex } from "@noble/hashes/utils"
16
- import { encode } from "@msgpack/msgpack"
17
- import { runWithRetryOnError } from "../common"
19
+ import { tmpdir } from "node:os"
20
+ import { join, resolve } from "node:path"
21
+ import { crc32 } from "node:zlib"
18
22
  import {
19
- unitInstanceStatusFieldSchema,
23
+ getInstanceId,
24
+ HighstateConfigKey,
25
+ type InstanceId,
26
+ instanceStatusFieldSchema,
27
+ unitArtifactSchema,
20
28
  unitPageSchema,
21
29
  unitTerminalSchema,
22
30
  unitTriggerSchema,
23
31
  unitWorkerSchema,
24
- } from "../shared"
32
+ } from "@highstate/contract"
33
+ import { encode } from "@msgpack/msgpack"
34
+ import { sha256 } from "@noble/hashes/sha2"
35
+ import { ensureDependencyInstalled } from "nypm"
36
+ import { omitBy } from "remeda"
37
+ import { z } from "zod"
38
+ import { runWithRetryOnError } from "../common"
39
+ import {
40
+ type ArtifactEnvironment,
41
+ collectAndStoreArtifacts,
42
+ setupArtifactEnvironment,
43
+ } from "./artifact-env"
25
44
  import {
26
45
  getOperationSummary,
46
+ type LocalPulumiHost,
27
47
  pulumiErrorToString,
28
48
  updateResourceCount,
29
- type LocalPulumiHost,
30
49
  } from "./pulumi"
31
- import {
32
- setupArtifactEnvironment,
33
- collectAndStoreArtifacts,
34
- type ArtifactEnvironment,
35
- } from "./artifact-env"
36
- import {
37
- type RunnerBackend,
38
- type UnitOptions,
39
- type UnitUpdateOptions,
40
- type UnitDestroyOptions,
41
- type UnitStateUpdate,
42
- type TypedUnitStateUpdate,
43
- type RunnerArtifact,
44
- } from "./abstractions"
45
50
 
46
51
  type Events = {
47
52
  [K in `update:${string}`]: [UnitStateUpdate]
@@ -83,32 +88,23 @@ export class LocalRunnerBackend implements RunnerBackend {
83
88
  }
84
89
 
85
90
  update(options: UnitUpdateOptions): Promise<void> {
86
- const configMap: ConfigMap = {
87
- ...mapValues(options.config, value => ({ value })),
88
- ...mapValues(options.secrets, value => ({ value, secret: true })),
89
- }
90
-
91
- void this.updateWorker(options, configMap, false)
91
+ void this.updateWorker(options, false)
92
92
 
93
93
  return Promise.resolve()
94
94
  }
95
95
 
96
96
  preview(options: UnitUpdateOptions): Promise<void> {
97
- const configMap: ConfigMap = {
98
- ...mapValues(options.config, value => ({ value })),
99
- ...mapValues(options.secrets, value => ({ value, secret: true })),
100
- }
101
-
102
- void this.updateWorker(options, configMap, true)
97
+ void this.updateWorker(options, true)
103
98
 
104
99
  return Promise.resolve()
105
100
  }
106
101
 
107
- private async updateWorker(
108
- options: UnitUpdateOptions,
109
- configMap: ConfigMap,
110
- preview: boolean,
111
- ): Promise<void> {
102
+ private async updateWorker(options: UnitUpdateOptions, preview: boolean): Promise<void> {
103
+ const configMap: ConfigMap = {
104
+ [HighstateConfigKey.Config]: { value: JSON.stringify(options.config) },
105
+ [HighstateConfigKey.Secrets]: { value: JSON.stringify(options.secrets), secret: true },
106
+ }
107
+
112
108
  const unitId = LocalRunnerBackend.getInstanceId(options)
113
109
  const childLogger = this.logger.child({ unitId })
114
110
 
@@ -118,8 +114,6 @@ export class LocalRunnerBackend implements RunnerBackend {
118
114
 
119
115
  try {
120
116
  // create unit-specific temp directory for better cleanup reliability
121
- // this provides a second layer of reliability: even if materialized files/folders
122
- // cannot clean up their specific paths, this entire directory will be cleaned up
123
117
  unitTempPath = await mkdtemp(join(tmpdir(), `highstate-unit-${unitId}-`))
124
118
  childLogger.debug({ msg: "created unit temp directory", unitTempPath })
125
119
  options.signal?.throwIfAborted()
@@ -211,23 +205,27 @@ export class LocalRunnerBackend implements RunnerBackend {
211
205
  })
212
206
 
213
207
  const outputs = await stack.outputs()
214
- const completionUpdate = this.createCompletionStateUpdate(unitId, outputs, stdout)
208
+ const completionUpdate = this.createCompletionStateUpdate(
209
+ "update",
210
+ unitId,
211
+ outputs,
212
+ stdout,
213
+ )
215
214
 
216
215
  if (outputs["$artifacts"]) {
217
216
  const artifacts = z
218
217
  .record(z.string(), unitArtifactSchema.array())
219
- // "id" of artifacts will be filled by collectAndStoreArtifacts
220
- .parse(outputs["$artifacts"].value) as Record<string, RunnerArtifact[]>
218
+ .parse(outputs["$artifacts"].value)
221
219
 
222
220
  await collectAndStoreArtifacts(
221
+ // biome-ignore lint/style/noNonNullAssertion: writePath is guaranteed to be non-null here
223
222
  artifactEnv!.writePath,
224
223
  options.projectId,
224
+ options.stateId,
225
225
  this.arttifactManager,
226
226
  Object.values(artifacts).flat(),
227
227
  childLogger,
228
228
  )
229
-
230
- completionUpdate.exportedArtifacts = artifacts
231
229
  }
232
230
 
233
231
  this.emitStateUpdate(completionUpdate)
@@ -356,7 +354,7 @@ export class LocalRunnerBackend implements RunnerBackend {
356
354
  },
357
355
  })
358
356
 
359
- await this.emitCompletionStateUpdate(unitId, stack, stdout)
357
+ await this.emitCompletionStateUpdate("destroy", unitId, stack, stdout)
360
358
  },
361
359
  error => this.pulumiProjectHost.tryUnlockStack(stack, error),
362
360
  )
@@ -375,6 +373,7 @@ export class LocalRunnerBackend implements RunnerBackend {
375
373
  if (error instanceof StackNotFoundError) {
376
374
  this.emitStateUpdate({
377
375
  type: "completion",
376
+ operationType: "destroy",
378
377
  unitId,
379
378
  outputHash: null,
380
379
  message: null,
@@ -462,6 +461,7 @@ export class LocalRunnerBackend implements RunnerBackend {
462
461
 
463
462
  this.emitStateUpdate({
464
463
  type: "completion",
464
+ operationType: "refresh",
465
465
  unitId,
466
466
  message: getOperationSummary(stdout),
467
467
 
@@ -483,7 +483,8 @@ export class LocalRunnerBackend implements RunnerBackend {
483
483
  }
484
484
 
485
485
  private createCompletionStateUpdate(
486
- unitId: string,
486
+ opType: "update" | "destroy" | "refresh",
487
+ unitId: InstanceId,
487
488
  outputs: OutputMap,
488
489
  stdout: string,
489
490
  ): TypedUnitStateUpdate<"completion"> {
@@ -492,12 +493,13 @@ export class LocalRunnerBackend implements RunnerBackend {
492
493
  return {
493
494
  unitId,
494
495
  type: "completion",
496
+ operationType: opType,
495
497
  message: getOperationSummary(stdout),
496
498
 
497
- outputHash: bytesToHex(sha256(encode(unitOutputs))),
499
+ outputHash: crc32(sha256(encode(unitOutputs))),
498
500
 
499
501
  statusFields: outputs["$statusFields"]
500
- ? z.array(unitInstanceStatusFieldSchema).parse(outputs["$statusFields"].value)
502
+ ? z.array(instanceStatusFieldSchema).parse(outputs["$statusFields"].value)
501
503
  : null,
502
504
 
503
505
  terminals: outputs["$terminals"]
@@ -514,25 +516,20 @@ export class LocalRunnerBackend implements RunnerBackend {
514
516
  ? z.array(unitWorkerSchema).parse(outputs["$workers"].value)
515
517
  : null,
516
518
 
517
- exportedSecrets: outputs["$exportedSecrets"]
518
- ? z
519
- .record(z.string(), unitSecretSchema.omit({ value: true }).array())
520
- .parse(outputs["$secrets"].value)
521
- : null,
522
-
523
519
  secrets: outputs["$secrets"]
524
- ? z.record(z.string(), z.string()).parse(outputs["$secrets"].value)
520
+ ? z.record(z.string(), z.unknown()).parse(outputs["$secrets"].value)
525
521
  : null,
526
522
  }
527
523
  }
528
524
 
529
525
  private async emitCompletionStateUpdate(
530
- unitId: string,
526
+ opType: OperationType,
527
+ unitId: InstanceId,
531
528
  stack: Stack,
532
529
  stdout: string,
533
530
  ): Promise<TypedUnitStateUpdate<"completion">> {
534
531
  const output = await stack.outputs()
535
- const update = this.createCompletionStateUpdate(unitId, output, stdout)
532
+ const update = this.createCompletionStateUpdate(opType, unitId, output, stdout)
536
533
 
537
534
  return this.emitStateUpdate(update)
538
535
  }
@@ -615,7 +612,7 @@ export class LocalRunnerBackend implements RunnerBackend {
615
612
  }
616
613
 
617
614
  private static getStackName(options: UnitOptions) {
618
- return `${options.projectId}_${options.instanceName}`
615
+ return options.stateId
619
616
  }
620
617
 
621
618
  public static create(
@@ -1,15 +1,13 @@
1
- import type { Logger } from "pino"
2
- import type { StateManager } from "../state"
3
- import {
4
- type ConfigMap,
5
- type OpMap,
6
- type OpType,
7
- type Stack,
8
- type WhoAmIResult,
1
+ import type {
2
+ ConfigMap,
3
+ OpMap,
4
+ OpType,
5
+ Stack,
6
+ WhoAmIResult,
9
7
  } from "@pulumi/pulumi/automation/index.js"
8
+ import type { Logger } from "pino"
9
+ import type { SecretService } from "../business"
10
10
  import { BetterLock } from "better-lock"
11
- import { v4 as uuidv4, v7 as uuidv7 } from "uuid"
12
- import { formatSecretDescriptor, WellKnownSecretDescriptors, type Secret } from "../shared"
13
11
  import { AbortError, errorToString, runWithRetryOnError } from "../common/utils"
14
12
  import { createForceAbortableCommand } from "./force-abort"
15
13
 
@@ -29,7 +27,7 @@ export class LocalPulumiHost {
29
27
  private lock = new BetterLock()
30
28
 
31
29
  private constructor(
32
- private readonly stateManager: StateManager,
30
+ private readonly secretService: SecretService,
33
31
  private readonly logger: Logger,
34
32
  ) {}
35
33
 
@@ -68,8 +66,9 @@ export class LocalPulumiHost {
68
66
  runtime: "nodejs",
69
67
  },
70
68
  envVars: {
71
- PULUMI_CONFIG_PASSPHRASE: await this.getPassword(projectId),
69
+ PULUMI_CONFIG_PASSPHRASE: await this.secretService.getPulumiPassword(projectId),
72
70
  PULUMI_K8S_AWAIT_ALL: "true",
71
+ PULUMI_DEBUG_PROMISE_LEAKS: "true",
73
72
  ...envVars,
74
73
  },
75
74
  pulumiCommand: await createForceAbortableCommand(),
@@ -83,12 +82,12 @@ export class LocalPulumiHost {
83
82
  () => fn(stack),
84
83
  error => this.tryUnlockStack(stack, error),
85
84
  )
86
- } catch (e) {
87
- if (e instanceof Error && e.message.includes("canceled")) {
88
- throw new AbortError()
85
+ } catch (error) {
86
+ if (error instanceof Error && error.message.includes("canceled")) {
87
+ throw new AbortError("Stack cancelled", { cause: error })
89
88
  }
90
89
 
91
- throw e
90
+ throw error
92
91
  }
93
92
  })
94
93
  }
@@ -125,7 +124,7 @@ export class LocalPulumiHost {
125
124
  }
126
125
  : undefined,
127
126
  envVars: {
128
- PULUMI_CONFIG_PASSPHRASE: await this.getPassword(projectId),
127
+ PULUMI_CONFIG_PASSPHRASE: await this.secretService.getPulumiPassword(projectId),
129
128
  PULUMI_K8S_AWAIT_ALL: "true",
130
129
  ...envVars,
131
130
  },
@@ -140,52 +139,13 @@ export class LocalPulumiHost {
140
139
  () => fn(stack),
141
140
  error => this.tryUnlockStack(stack, error),
142
141
  )
143
- } catch (e) {
144
- if (e instanceof Error && e.message.includes("canceled")) {
145
- throw new AbortError()
142
+ } catch (error) {
143
+ if (error instanceof Error && error.message.includes("canceled")) {
144
+ throw new AbortError("Stack cancelled", { cause: error })
146
145
  }
147
146
 
148
- throw e
149
- }
150
- })
151
- }
152
-
153
- private async getPassword(projectId: string): Promise<string> {
154
- return await this.lock.acquire(`pulumi-password.${projectId}`, async () => {
155
- const secretRepo = this.stateManager.getSecretRepository(projectId)
156
- const secretContentRepo = this.stateManager.getSecretContentRepository(projectId)
157
- const indexRepo = this.stateManager.getSecretIndexRepository(projectId)
158
-
159
- const contentKey = formatSecretDescriptor(WellKnownSecretDescriptors.PulumiPassword)
160
- const pulumiPasswordContent = await secretContentRepo.get(contentKey)
161
- if (typeof pulumiPasswordContent === "string") {
162
- return pulumiPasswordContent
147
+ throw error
163
148
  }
164
-
165
- this.logger.info({ projectId }, "generating new Pulumi password")
166
-
167
- const pulumiPassword = uuidv4()
168
- const batch = this.stateManager.batch()
169
-
170
- const pulumiPasswordSecret: Secret = {
171
- id: uuidv7(),
172
- descriptor: WellKnownSecretDescriptors.PulumiPassword,
173
- meta: {
174
- title: "Pulumi Password",
175
- description: "The password used to encrypt the Pulumi state.",
176
- icon: "devicon:pulumi",
177
- },
178
- }
179
-
180
- await Promise.all([
181
- secretRepo.putItem(pulumiPasswordSecret, batch),
182
- secretContentRepo.put(contentKey, pulumiPassword, batch),
183
- indexRepo.indexRepository.put(contentKey, pulumiPasswordSecret.id, batch),
184
- ])
185
-
186
- await batch.write()
187
-
188
- return pulumiPassword
189
149
  })
190
150
  }
191
151
 
@@ -201,8 +161,8 @@ export class LocalPulumiHost {
201
161
  return false
202
162
  }
203
163
 
204
- static create(stateManager: StateManager, logger: Logger) {
205
- return new LocalPulumiHost(stateManager, logger.child({ service: "LocalPulumiHost" }))
164
+ static create(secretService: SecretService, logger: Logger) {
165
+ return new LocalPulumiHost(secretService, logger.child({ service: "LocalPulumiHost" }))
206
166
  }
207
167
  }
208
168
 
@@ -255,7 +215,7 @@ export async function pulumiErrorToString(error: unknown): Promise<string> {
255
215
  const { CommandError } = await import("@pulumi/pulumi/automation/index.js")
256
216
 
257
217
  if (error instanceof CommandError) {
258
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
218
+ // biome-ignore lint/complexity/useLiteralKeys: не ори на отца
259
219
  const stderr = error["commandResult"].stderr as string
260
220
  let diagnosticsStart = stderr.indexOf("\u001b[38;5;13m\u001b[1mDiagnostics:")
261
221