@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
@@ -0,0 +1,181 @@
1
+ import type { Logger } from "pino"
2
+ import type { ProjectUnlockBackend } from "../unlock"
3
+ import type { BackendDatabase, ProjectDatabase } from "./prisma"
4
+ import { LRUCache } from "lru-cache"
5
+ import z from "zod"
6
+ import { createProjectLogger } from "../common"
7
+ import { BackendError, ProjectLockedError, ProjectNotFoundError } from "../shared"
8
+ import { type ProjectDatabaseBackend, projectDatabaseVersion } from "./abstractions"
9
+ import { migrateDatabase } from "./migrate"
10
+
11
+ export const databaseManagerConfig = z.object({
12
+ HIGHSTATE_ENCRYPTION_ENABLED: z.stringbool().default(true),
13
+ })
14
+
15
+ export interface DatabaseManager {
16
+ /**
17
+ * The backend database instance.
18
+ */
19
+ readonly backend: BackendDatabase
20
+
21
+ /**
22
+ * Whether the encryption is enabled for the backend and project databases.
23
+ */
24
+ readonly isEncryptionEnabled: boolean
25
+
26
+ /**
27
+ * Returns the master key of the project with the given ID.
28
+ *
29
+ * If the project does not exist or is not unlocked, this will throw an error.
30
+ *
31
+ * Returns `undefined` if the encryption is not enabled.
32
+ *
33
+ * @param projectId The ID of the project to get the master key for.
34
+ * @returns A Promise that resolves to the master key of the project as a Uint8Array.
35
+ */
36
+ getProjectMasterKey(projectId: string): Promise<Buffer | undefined>
37
+
38
+ /**
39
+ * Sets up the database for the project with the given ID.
40
+ *
41
+ * Assumes that no database exists yet.
42
+ *
43
+ * The project must be unlocked before calling this method.
44
+ *
45
+ * @param projectId The ID of the project to set up the database for.
46
+ */
47
+ setupDatabase(projectId: string): Promise<ProjectDatabase>
48
+
49
+ /**
50
+ * Returns the database client for the project with the given ID.
51
+ *
52
+ * Automatically migrates the project database if necessary.
53
+ *
54
+ * If the project does not exist or not unlocked, this will throw an error.
55
+ *
56
+ * @param projectId The ID of the project to get the database client for.
57
+ */
58
+ forProject(projectId: string): Promise<ProjectDatabase>
59
+ }
60
+
61
+ export class DatabaseManagerImpl implements DatabaseManager {
62
+ constructor(
63
+ readonly backend: BackendDatabase,
64
+ private readonly projectUnlockBackend: ProjectUnlockBackend,
65
+ private readonly projectDatabaseBackend: ProjectDatabaseBackend,
66
+ private readonly config: z.infer<typeof databaseManagerConfig>,
67
+ private readonly logger: Logger,
68
+ ) {}
69
+
70
+ // store the master keys in memory cache for 30 seconds
71
+ private readonly projectMasterKeys = new LRUCache<string, Buffer>({
72
+ ttl: 30_000,
73
+ ttlAutopurge: true,
74
+ })
75
+
76
+ // TODO: auto unload project databases after some time
77
+ private readonly projectDatabases = new Map<string, ProjectDatabase>()
78
+
79
+ get isEncryptionEnabled(): boolean {
80
+ return this.config.HIGHSTATE_ENCRYPTION_ENABLED
81
+ }
82
+
83
+ async getProjectMasterKey(projectId: string): Promise<Buffer | undefined> {
84
+ if (!this.isEncryptionEnabled) {
85
+ return undefined
86
+ }
87
+
88
+ const cachedInfo = this.projectMasterKeys.get(projectId)
89
+ if (cachedInfo) {
90
+ return cachedInfo
91
+ }
92
+
93
+ const masterKey = await this.projectUnlockBackend.getProjectMasterKey(projectId)
94
+ if (!masterKey) {
95
+ throw new ProjectLockedError(projectId)
96
+ }
97
+
98
+ this.projectMasterKeys.set(projectId, masterKey)
99
+ return masterKey
100
+ }
101
+
102
+ async setupDatabase(projectId: string): Promise<ProjectDatabase> {
103
+ const logger = createProjectLogger(this.logger, projectId)
104
+ const masterKey = await this.getProjectMasterKey(projectId)
105
+ const hexMasterKey = masterKey?.toString("hex")
106
+
107
+ const [database, databaseUrl] = await this.projectDatabaseBackend.openProjectDatabase(
108
+ projectId,
109
+ hexMasterKey,
110
+ )
111
+
112
+ // can safely apply migrations here, because no one knows about the database yet
113
+ await migrateDatabase(databaseUrl, "project", hexMasterKey, logger)
114
+
115
+ this.projectDatabases.set(projectId, database)
116
+
117
+ return database
118
+ }
119
+
120
+ async forProject(projectId: string): Promise<ProjectDatabase> {
121
+ const cachedDatabase = this.projectDatabases.get(projectId)
122
+ if (cachedDatabase) {
123
+ return cachedDatabase
124
+ }
125
+
126
+ const masterKey = await this.getProjectMasterKey(projectId)
127
+ const hexMasterKey = masterKey?.toString("hex")
128
+
129
+ // TODO: is it really necessary to migrate the database inside the transaction?
130
+ let database = await this.backend.$transaction(async tx => {
131
+ const databaseEntity = await tx.project.findUnique({
132
+ where: { id: projectId },
133
+ select: { databaseVersion: true },
134
+ })
135
+
136
+ if (!databaseEntity) {
137
+ throw new ProjectNotFoundError(projectId)
138
+ }
139
+
140
+ if (databaseEntity.databaseVersion > projectDatabaseVersion) {
141
+ throw new BackendError(
142
+ `Project database version (${databaseEntity.databaseVersion}) is newer than expected (${projectDatabaseVersion}).`,
143
+ )
144
+ }
145
+
146
+ if (databaseEntity.databaseVersion === projectDatabaseVersion) {
147
+ return
148
+ }
149
+
150
+ const [database, databaseUrl] = await this.projectDatabaseBackend.openProjectDatabase(
151
+ projectId,
152
+ hexMasterKey,
153
+ )
154
+
155
+ if (databaseEntity.databaseVersion < projectDatabaseVersion) {
156
+ await migrateDatabase(databaseUrl, "project", hexMasterKey, this.logger)
157
+ }
158
+
159
+ await tx.project.update({
160
+ where: { id: projectId },
161
+ data: { databaseVersion: projectDatabaseVersion },
162
+ })
163
+
164
+ return database
165
+ })
166
+
167
+ if (!database) {
168
+ // open database if was not migrated in the transaction
169
+ const [_database] = await this.projectDatabaseBackend.openProjectDatabase(
170
+ projectId,
171
+ hexMasterKey,
172
+ )
173
+
174
+ database = _database
175
+ }
176
+
177
+ this.projectDatabases.set(projectId, database)
178
+
179
+ return database
180
+ }
181
+ }
@@ -0,0 +1,35 @@
1
+ import type { Logger } from "pino"
2
+ import { join } from "node:path"
3
+ import { fileURLToPath } from "node:url"
4
+ import { execa } from "execa"
5
+ import { resolve } from "import-meta-resolve"
6
+ import { detectPackageManager } from "nypm"
7
+
8
+ export async function migrateDatabase(
9
+ databaseUrl: string,
10
+ schemaPath: "backend/sqlite" | "project",
11
+ masterKey: string | undefined,
12
+ logger: Logger,
13
+ ): Promise<void> {
14
+ logger.info("applying database migrations")
15
+
16
+ const backendIndexPath = resolve("@highstate/backend", import.meta.url)
17
+ const backendRootPath = join(fileURLToPath(backendIndexPath), "..")
18
+
19
+ const packageManager = await detectPackageManager(backendRootPath)
20
+ if (!packageManager) {
21
+ throw new Error("Could not detect package manager to run migrations")
22
+ }
23
+
24
+ const hasCorepack = await execa`"corepack" --version`.then(() => true).catch(() => false)
25
+ const command = hasCorepack ? `corepack ${packageManager.command}` : packageManager.command
26
+
27
+ await execa({
28
+ cwd: backendRootPath,
29
+ env: {
30
+ HIGHSTATE_MIGRATION_DATABASE_SCHEMA_PATH: schemaPath,
31
+ HIGHSTATE_MIGRATION_DATABASE_URL: databaseUrl,
32
+ HIGHSTATE_MIGRATION_DATABASE_ENCRYPTION_KEY: masterKey ?? "",
33
+ },
34
+ })`${command} migrate`
35
+ }
@@ -0,0 +1,56 @@
1
+ import type * as runtime from "@prisma/client/runtime/client"
2
+ import { PrismaClient as BackendDatabase } from "./_generated/backend/postgresql/client"
3
+ import { PrismaClient as ProjectDatabase } from "./_generated/project/client"
4
+
5
+ export type BackendTransaction = Omit<BackendDatabase, runtime.ITXClientDenyList>
6
+ export type ProjectTransaction = Omit<ProjectDatabase, runtime.ITXClientDenyList>
7
+
8
+ export type {
9
+ Library,
10
+ Project,
11
+ ProjectSpace,
12
+ PulumiBackend,
13
+ } from "./_generated/backend/postgresql/client"
14
+ export type {
15
+ ApiKey,
16
+ Artifact,
17
+ InstanceCustomStatus,
18
+ InstanceEvaluationState,
19
+ InstanceEvaluationStatus,
20
+ InstanceLock,
21
+ InstanceOperationState,
22
+ InstanceOperationStatus,
23
+ InstanceSource,
24
+ InstanceState,
25
+ InstanceStatus,
26
+ Operation,
27
+ OperationLog,
28
+ OperationStatus,
29
+ OperationType,
30
+ Page,
31
+ Secret,
32
+ ServiceAccount,
33
+ Terminal,
34
+ TerminalSession,
35
+ TerminalSessionLog,
36
+ TerminalStatus,
37
+ Trigger,
38
+ UnlockMethod,
39
+ Worker,
40
+ WorkerUnitRegistration,
41
+ WorkerVersion,
42
+ WorkerVersionLog,
43
+ } from "./_generated/project/client"
44
+ export type {
45
+ InstanceEvaluationStateUncheckedCreateInput,
46
+ InstanceEvaluationStateUpdateInput,
47
+ InstanceOperationStateCreateInput,
48
+ InstanceOperationStateCreateManyInput,
49
+ InstanceOperationStateUpdateInput,
50
+ InstanceStateInclude,
51
+ InstanceStateUpdateInput,
52
+ OperationUpdateInput,
53
+ } from "./_generated/project/models"
54
+ export { DbNull } from "./_generated/project/internal/prismaNamespace"
55
+
56
+ export { BackendDatabase, ProjectDatabase }
@@ -0,0 +1,38 @@
1
+ import type { BackendDatabase } from "./prisma"
2
+ import {
3
+ codebaseLibrary,
4
+ codebaseProjectModelStorage,
5
+ databaseProjectModelStorage,
6
+ globalProjectSpace,
7
+ hostPulumiBackend,
8
+ } from "../shared/models/backend/well-known"
9
+
10
+ export async function ensureWellKnownEntitiesCreated(database: BackendDatabase): Promise<void> {
11
+ await database.$transaction([
12
+ database.projectSpace.upsert({
13
+ where: { id: globalProjectSpace.id },
14
+ create: globalProjectSpace,
15
+ update: globalProjectSpace,
16
+ }),
17
+ database.library.upsert({
18
+ where: { id: codebaseLibrary.id },
19
+ create: codebaseLibrary,
20
+ update: codebaseLibrary,
21
+ }),
22
+ database.pulumiBackend.upsert({
23
+ where: { id: hostPulumiBackend.id },
24
+ create: hostPulumiBackend,
25
+ update: hostPulumiBackend,
26
+ }),
27
+ database.projectModelStorage.upsert({
28
+ where: { id: codebaseProjectModelStorage.id },
29
+ create: codebaseProjectModelStorage,
30
+ update: codebaseProjectModelStorage,
31
+ }),
32
+ database.projectModelStorage.upsert({
33
+ where: { id: databaseProjectModelStorage.id },
34
+ create: databaseProjectModelStorage,
35
+ update: databaseProjectModelStorage,
36
+ }),
37
+ ])
38
+ }
package/src/index.ts CHANGED
@@ -1,7 +1,7 @@
1
- export * from "./library"
1
+ export * from "./business"
2
2
  export * from "./config"
3
+ export * from "./database"
4
+ export * from "./library"
3
5
  export * from "./orchestrator"
4
- export * from "./terminal"
5
6
  export * from "./services"
6
- export * from "./state"
7
- export * from "./business"
7
+ export * from "./terminal"
@@ -1,4 +1,4 @@
1
- import type { InstanceModel } from "@highstate/contract"
1
+ import type { InstanceId, InstanceModel } from "@highstate/contract"
2
2
  import type { LibraryModel, LibraryUpdate, ResolvedInstanceInput } from "../shared"
3
3
 
4
4
  export type ResolvedUnitSource = {
@@ -16,7 +16,7 @@ export type ProjectEvaluationResult =
16
16
  /**
17
17
  * The mapping of top-level composite instance IDs to error messages if any.
18
18
  */
19
- topLevelErrors: Record<string, string>
19
+ topLevelErrors: Record<InstanceId, string>
20
20
  }
21
21
  | {
22
22
  success: false
@@ -58,17 +58,15 @@ export interface LibraryBackend {
58
58
  ): AsyncIterable<ResolvedUnitSource>
59
59
 
60
60
  /**
61
- * Evaluates the instances and returns the evaluated composite instances.
61
+ * Evaluates the composite instances of the project and returns evaluated virtual instances.
62
62
  *
63
63
  * @param libraryId The library ID to use for evaluation.
64
64
  * @param allInstances The all instances of the project.
65
65
  * @param resolvedInputs The resolved inputs of the instances.
66
- * @param instanceIds The instance ids to evaluate.
67
66
  */
68
67
  evaluateCompositeInstances(
69
68
  libraryId: string | undefined,
70
69
  allInstances: InstanceModel[],
71
70
  resolvedInputs: Record<string, Record<string, ResolvedInstanceInput[]>>,
72
- instanceIds: string[],
73
71
  ): Promise<ProjectEvaluationResult>
74
72
  }
@@ -1,5 +1,5 @@
1
- import type { LibraryBackend } from "./abstractions"
2
1
  import type { Logger } from "pino"
2
+ import type { LibraryBackend } from "./abstractions"
3
3
  import { z } from "zod"
4
4
  import { LocalLibraryBackend, localLibraryBackendConfig } from "./local"
5
5
 
@@ -1,24 +1,24 @@
1
- import type { LibraryBackend, ProjectEvaluationResult, ResolvedUnitSource } from "./abstractions"
2
1
  import type { Logger } from "pino"
2
+ import type { LibraryBackend, ProjectEvaluationResult, ResolvedUnitSource } from "./abstractions"
3
3
  import type {
4
4
  PackageResolutionResponse,
5
5
  PackageResolutionWorkerData,
6
6
  } from "./package-resolution-worker"
7
7
  import type { WorkerData } from "./worker/protocol"
8
- import { fileURLToPath } from "node:url"
9
8
  import { EventEmitter, on } from "node:events"
10
- import { Worker } from "node:worker_threads"
11
- import { resolve } from "node:path"
12
9
  import { readFile } from "node:fs/promises"
10
+ import { resolve } from "node:path"
11
+ import { fileURLToPath } from "node:url"
12
+ import { Worker } from "node:worker_threads"
13
13
  import { type InstanceModel, isUnitModel } from "@highstate/contract"
14
- import Watcher from "watcher"
14
+ import { decode } from "@msgpack/msgpack"
15
15
  import { BetterLock } from "better-lock"
16
16
  import { resolve as importMetaResolve } from "import-meta-resolve"
17
- import { z } from "zod"
17
+ import { addDependency, installDependencies, runScript } from "nypm"
18
18
  import { readPackageJSON } from "pkg-types"
19
- import { runScript, installDependencies, addDependency } from "nypm"
20
19
  import { flatMap, groupBy, map, pipe, unique } from "remeda"
21
- import { decode } from "@msgpack/msgpack"
20
+ import Watcher from "watcher"
21
+ import { z } from "zod"
22
22
  import { resolveMainLocalProject, stringArrayType } from "../common"
23
23
  import {
24
24
  diffLibraries,
@@ -48,6 +48,11 @@ type LibraryPackage = {
48
48
  dependents: Set<string>
49
49
  }
50
50
 
51
+ type RebuildState = {
52
+ inProgress: boolean
53
+ pending: boolean
54
+ }
55
+
51
56
  export class LocalLibraryBackend implements LibraryBackend {
52
57
  private readonly watcher: Watcher
53
58
 
@@ -58,6 +63,7 @@ export class LocalLibraryBackend implements LibraryBackend {
58
63
 
59
64
  private readonly packages = new Map<string, LibraryPackage>()
60
65
  private readonly resolvedUnitSources = new Map<string, ResolvedUnitSource>()
66
+ private readonly rebuildStates = new Map<string, RebuildState>()
61
67
 
62
68
  private constructor(
63
69
  private readonly libraryPackages: string[],
@@ -67,7 +73,7 @@ export class LocalLibraryBackend implements LibraryBackend {
67
73
  this.watcher = new Watcher(watchPaths, {
68
74
  recursive: true,
69
75
  ignoreInitial: true,
70
- ignore: /\.git|node_modules|dist/,
76
+ ignore: /\.git|node_modules|dist|\.highstate/,
71
77
  })
72
78
 
73
79
  this.watcher.on("all", (event: string, path: string) => {
@@ -148,15 +154,11 @@ export class LocalLibraryBackend implements LibraryBackend {
148
154
  _libraryId: string,
149
155
  allInstances: InstanceModel[],
150
156
  resolvedInputs: Record<string, Record<string, ResolvedInstanceInput[]>>,
151
- instanceIds: string[],
152
157
  ): Promise<ProjectEvaluationResult> {
153
- this.logger.info("evaluating %d composite instances", instanceIds.length)
154
-
155
158
  const worker = this.createLibraryWorker({
156
159
  libraryModulePaths: this.libraryPackages,
157
160
  allInstances,
158
161
  resolvedInputs,
159
- instanceIds,
160
162
  })
161
163
 
162
164
  for await (const [event] of on(worker, "message", { signal: AbortSignal.timeout(10_000) })) {
@@ -260,7 +262,7 @@ export class LocalLibraryBackend implements LibraryBackend {
260
262
 
261
263
  this.resolvedUnitSources.set(unit.type, newResolvedSource)
262
264
  this.eventEmitter.emit("resolvedUnitSource", newResolvedSource)
263
- this.logger.debug(`updated source for unit: "%s"`, unit.type)
265
+ this.logger.trace(`updated source for unit: "%s"`, unit.type)
264
266
  }
265
267
  }
266
268
 
@@ -468,22 +470,75 @@ export class LocalLibraryBackend implements LibraryBackend {
468
470
  }
469
471
  }
470
472
 
471
- private async handleFileEvent(path: string): Promise<void> {
472
- await this.lock.acquire(async () => {
473
- const libraryPackage = this.packages.values().find(pkg => path.startsWith(pkg.rootPath))
473
+ private handleFileEvent(path: string): void {
474
+ const libraryPackage = this.packages.values().find(pkg => path.startsWith(pkg.rootPath))
474
475
 
475
- if (!libraryPackage) {
476
- return
477
- }
476
+ if (!libraryPackage) {
477
+ return
478
+ }
478
479
 
479
- const builtPackages = new Set<string>()
480
- await this.rebuildLibraryPackage(libraryPackage, false, false, builtPackages)
480
+ void this.schedulePackageRebuild(libraryPackage.name)
481
+ }
482
+
483
+ private async schedulePackageRebuild(packageName: string): Promise<void> {
484
+ const state = this.rebuildStates.get(packageName) ?? { inProgress: false, pending: false }
485
+
486
+ // if both in progress and pending, discard this request
487
+ if (state.inProgress && state.pending) {
488
+ this.logger.debug(`rebuild in progress and already pending for "%s", discarding`, packageName)
489
+ return
490
+ }
491
+
492
+ // if in progress but no pending, mark as pending
493
+ if (state.inProgress && !state.pending) {
494
+ state.pending = true
495
+ this.rebuildStates.set(packageName, state)
496
+ this.logger.debug(`rebuild in progress, scheduling pending rebuild for "%s"`, packageName)
497
+ return
498
+ }
499
+
500
+ // not in progress, start immediately
501
+ await this.executePackageRebuild(packageName)
502
+ }
481
503
 
482
- if (this.libraryPackages.some(pkg => builtPackages.has(pkg))) {
483
- this.logger.info("reloading library due to file change in package: %s", libraryPackage.name)
484
- await this.reloadLibrary()
504
+ private async executePackageRebuild(packageName: string): Promise<void> {
505
+ const state = this.rebuildStates.get(packageName) ?? { inProgress: false, pending: false }
506
+
507
+ do {
508
+ // mark as in progress, clear pending
509
+ state.inProgress = true
510
+ state.pending = false
511
+ this.rebuildStates.set(packageName, state)
512
+
513
+ try {
514
+ await this.lock.acquire(async () => {
515
+ const libraryPackage = this.packages.get(packageName)
516
+
517
+ if (!libraryPackage) {
518
+ this.logger.warn(`package not found for rebuild: "%s"`, packageName)
519
+ return
520
+ }
521
+
522
+ const builtPackages = new Set<string>()
523
+ await this.rebuildLibraryPackage(libraryPackage, false, false, builtPackages)
524
+
525
+ if (this.libraryPackages.some(pkg => builtPackages.has(pkg))) {
526
+ this.logger.info(
527
+ "reloading library due to file change in package: %s",
528
+ libraryPackage.name,
529
+ )
530
+ await this.reloadLibrary()
531
+ }
532
+ })
533
+ } finally {
534
+ state.inProgress = false
485
535
  }
486
- })
536
+
537
+ // continue if another rebuild was requested while we were working
538
+ } while (state.pending)
539
+
540
+ // clean up if no longer needed
541
+ this.rebuildStates.delete(packageName)
487
542
  }
488
543
 
489
544
  private createLibraryWorker(workerData: WorkerData): Worker {
@@ -64,7 +64,7 @@ for (const packageName of packageNames) {
64
64
  }
65
65
  }
66
66
 
67
- parentPort!.postMessage({
67
+ parentPort?.postMessage({
68
68
  type: "result",
69
69
  results,
70
70
  })
@@ -14,20 +14,18 @@ export function evaluateProject(
14
14
  components: Readonly<Record<string, Component>>,
15
15
  allInstances: InstanceModel[],
16
16
  resolvedInputs: Record<string, Record<string, ResolvedInstanceInput[]>>,
17
- instanceIds: string[],
18
17
  ): ProjectEvaluationResult {
19
- const errors: Record<string, string> = {}
20
18
  const allInstancesMap = new Map(allInstances.map(instance => [instance.id, instance]))
19
+
20
+ const instanceErrors: Record<string, unknown> = {}
21
+ const topLevelErrors: Record<string, string> = {}
22
+
21
23
  const instanceOutputs = new Map<string, Record<string, unknown>>()
22
24
 
23
- for (const instanceId of instanceIds ?? []) {
25
+ for (const instance of allInstances) {
24
26
  try {
25
- logger.debug({ instanceId }, "evaluating top-level instance")
26
-
27
- evaluateInstance(instanceId as InstanceModel["id"])
27
+ evaluateInstance(instance.id)
28
28
  } catch (error) {
29
- errors[instanceId] = errorToString(error)
30
-
31
29
  if (error instanceof InstanceNameConflictError) {
32
30
  // fail the whole evaluation if there's a name conflict
33
31
  return {
@@ -40,35 +38,54 @@ export function evaluateProject(
40
38
 
41
39
  return {
42
40
  success: true,
41
+
43
42
  virtualInstances: getRuntimeInstances()
44
43
  .map(instance => instance.instance)
45
44
  // only include top-level composite instances and their children
46
- .filter(instance => instanceIds.includes(instance.id) || !allInstancesMap.has(instance.id)),
47
- topLevelErrors: errors,
45
+ .filter(instance => instance.kind === "composite" || !allInstancesMap.has(instance.id)),
46
+
47
+ topLevelErrors,
48
48
  }
49
49
 
50
50
  function evaluateInstance(instanceId: InstanceModel["id"]): Record<string, unknown> {
51
51
  let outputs = instanceOutputs.get(instanceId)
52
-
53
- if (!outputs) {
54
- outputs = _evaluateInstance(instanceId)
55
- instanceOutputs.set(instanceId, outputs)
52
+ if (outputs) {
53
+ return outputs
56
54
  }
57
55
 
58
- return outputs
59
- }
56
+ // do not evaluate instance if it has an error, just rethrow it
57
+ const error = instanceErrors[instanceId]
58
+ if (error) {
59
+ // eslint-disable-next-line @typescript-eslint/only-throw-error
60
+ throw error
61
+ }
60
62
 
61
- function _evaluateInstance(instanceId: InstanceModel["id"]): Record<string, unknown> {
62
- const inputs: Record<string, unknown> = {}
63
63
  const instance = allInstancesMap.get(instanceId)
64
-
65
- logger.debug("evaluating instance", { instanceId })
66
-
67
64
  if (!instance) {
68
65
  throw new Error(`Instance not found: ${instanceId}`)
69
66
  }
70
67
 
71
- for (const [inputName, input] of Object.entries(resolvedInputs[instanceId] ?? {})) {
68
+ try {
69
+ outputs = _evaluateInstance(instance)
70
+
71
+ instanceOutputs.set(instanceId, outputs)
72
+ return outputs
73
+ } catch (error) {
74
+ if (instance.kind === "composite" || !allInstancesMap.has(instance.id)) {
75
+ topLevelErrors[instance.id] = errorToString(error)
76
+ }
77
+
78
+ instanceErrors[instanceId] = error
79
+ throw error
80
+ }
81
+ }
82
+
83
+ function _evaluateInstance(instance: InstanceModel): Record<string, unknown> {
84
+ const inputs: Record<string, unknown> = {}
85
+
86
+ logger.debug("evaluating instance", { instanceId: instance.id })
87
+
88
+ for (const [inputName, input] of Object.entries(resolvedInputs[instance.id] ?? {})) {
72
89
  inputs[inputName] = input.map(input => {
73
90
  const evaluated = evaluateInstance(input.input.instanceId)
74
91
 
@@ -78,7 +95,7 @@ export function evaluateProject(
78
95
 
79
96
  const component = components[instance.type]
80
97
  if (!component) {
81
- throw new Error(`Component not found: ${instance.type}, required by instance: ${instanceId}`)
98
+ throw new Error(`Component not found: ${instance.type}, required by instance: ${instance.id}`)
82
99
  }
83
100
 
84
101
  return component({
@@ -1,5 +1,5 @@
1
1
  import type { Logger } from "pino"
2
- import { isComponent, type Component } from "@highstate/contract"
2
+ import { type Component, isComponent } from "@highstate/contract"
3
3
 
4
4
  export async function loadComponents(
5
5
  logger: Logger,
@@ -11,20 +11,13 @@ const logger = pino({ name: "library-worker" })
11
11
 
12
12
  try {
13
13
  const library = await loadComponents(logger, data.libraryModulePaths)
14
+ const result = evaluateProject(logger, library, data.allInstances, data.resolvedInputs)
14
15
 
15
- const result = evaluateProject(
16
- logger,
17
- library,
18
- data.allInstances,
19
- data.resolvedInputs,
20
- data.instanceIds,
21
- )
22
-
23
- parentPort!.postMessage(result)
16
+ parentPort?.postMessage(result)
24
17
  } catch (error) {
25
18
  logger.error({ error }, "failed to evaluate project")
26
19
 
27
- parentPort!.postMessage({
20
+ parentPort?.postMessage({
28
21
  success: false,
29
22
  error: errorToString(error),
30
23
  })