@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.
- package/dist/chunk-5WVU2AK4.js +1535 -0
- package/dist/chunk-5WVU2AK4.js.map +1 -0
- package/dist/{chunk-OU5OQBLB.js → chunk-I7BWSAN6.js} +3 -28
- package/dist/{chunk-OU5OQBLB.js.map → chunk-I7BWSAN6.js.map} +1 -1
- package/dist/chunk-VB4YL327.js +139 -0
- package/dist/chunk-VB4YL327.js.map +1 -0
- package/dist/database/local/prisma.config.js +26 -0
- package/dist/database/local/prisma.config.js.map +1 -0
- package/dist/highstate.manifest.json +2 -1
- package/dist/index.js +7587 -7291
- package/dist/index.js.map +1 -1
- package/dist/library/package-resolution-worker.js +1 -1
- package/dist/library/package-resolution-worker.js.map +1 -1
- package/dist/library/worker/main.js +35 -29
- package/dist/library/worker/main.js.map +1 -1
- package/dist/shared/index.js +2 -2
- package/package.json +18 -9
- package/prisma/backend/_schema/layout.prisma +7 -0
- package/prisma/backend/_schema/library.prisma +17 -0
- package/prisma/backend/_schema/project.prisma +101 -0
- package/prisma/backend/_schema/pulumi.prisma +17 -0
- package/prisma/backend/postgresql/main.prisma +17 -0
- package/prisma/backend/sqlite/main.prisma +17 -0
- package/prisma/backend/sqlite/migrations/20250817070609_initiial/migration.sql +34 -0
- package/prisma/backend/sqlite/migrations/20250817104948_add_fields/migration.sql +59 -0
- package/prisma/backend/sqlite/migrations/20250818082732_add_models/migration.sql +41 -0
- package/prisma/backend/sqlite/migrations/20250818083106_a/migration.sql +19 -0
- package/prisma/backend/sqlite/migrations/20250818101945_hi/migration.sql +1 -0
- package/prisma/backend/sqlite/migrations/20250819082315_a/migration.sql +5 -0
- package/prisma/backend/sqlite/migrations/migration_lock.toml +3 -0
- package/prisma/project/api-key.prisma +27 -0
- package/prisma/project/artifact.prisma +52 -0
- package/prisma/project/custom-status.prisma +46 -0
- package/prisma/project/evaluation.prisma +35 -0
- package/prisma/project/instance.prisma +160 -0
- package/prisma/project/layout.prisma +23 -0
- package/prisma/project/lock.prisma +18 -0
- package/prisma/project/main.prisma +17 -0
- package/prisma/project/migrations/20250816081310_initial/migration.sql +300 -0
- package/prisma/project/migrations/20250816082523_test/migration.sql +72 -0
- package/prisma/project/migrations/20250818065643_update/migration.sql +42 -0
- package/prisma/project/migrations/20250818070758_a/migration.sql +8 -0
- package/prisma/project/migrations/20250818070913_a/migration.sql +8 -0
- package/prisma/project/migrations/20250818082720_add_motels/migration.sql +11 -0
- package/prisma/project/migrations/20250818112523_hello/migration.sql +35 -0
- package/prisma/project/migrations/20250819082305_a/migration.sql +14 -0
- package/prisma/project/migrations/20250819165004_add_missing_fields/migration.sql +216 -0
- package/prisma/project/migrations/20250819171309_a/migration.sql +22 -0
- package/prisma/project/migrations/20250820113949_a/migration.sql +66 -0
- package/prisma/project/migrations/20250820144256_b/migration.sql +31 -0
- package/prisma/project/migrations/20250820145547_a/migration.sql +24 -0
- package/prisma/project/migrations/20250820182517_b/migration.sql +2 -0
- package/prisma/project/migrations/20250821172324_a/migration.sql +2 -0
- package/prisma/project/migrations/20250822081339_a/migration.sql +219 -0
- package/prisma/project/migrations/20250822083742_b/migration.sql +1 -0
- package/prisma/project/migrations/20250822105134_boom/migration.sql +1 -0
- package/prisma/project/migrations/20250822141028_b/migration.sql +1 -0
- package/prisma/project/migrations/20250822142342_b/migration.sql +16 -0
- package/prisma/project/migrations/20250824072720_a/migration.sql +1 -0
- package/prisma/project/migrations/20250824093656_b/migration.sql +21 -0
- package/prisma/project/migrations/20250825082518_a/migration.sql +1 -0
- package/prisma/project/migrations/20250825085343_b/migration.sql +1 -0
- package/prisma/project/migrations/20250825091312_a/migration.sql +1 -0
- package/prisma/project/migrations/20250903095431_hi/migration.sql +44 -0
- package/prisma/project/migrations/20250903174255_a/migration.sql +24 -0
- package/prisma/project/migrations/20250908095205_hi/migration.sql +18 -0
- package/prisma/project/migrations/20250909155857_hi/migration.sql +15 -0
- package/prisma/project/migrations/migration_lock.toml +3 -0
- package/prisma/project/model.prisma +37 -0
- package/prisma/project/operation.prisma +148 -0
- package/prisma/project/page.prisma +41 -0
- package/prisma/project/secret.prisma +42 -0
- package/prisma/project/service-account.prisma +36 -0
- package/prisma/project/terminal.prisma +90 -0
- package/prisma/project/trigger.prisma +31 -0
- package/prisma/project/unlock-method.prisma +32 -0
- package/prisma/project/worker.prisma +138 -0
- package/src/artifact/abstractions.ts +13 -13
- package/src/artifact/encryption.ts +30 -54
- package/src/artifact/factory.ts +6 -9
- package/src/artifact/local.ts +33 -46
- package/src/business/api-key.ts +24 -36
- package/src/business/artifact.test.ts +978 -0
- package/src/business/artifact.ts +136 -216
- package/src/business/evaluation.ts +328 -0
- package/src/business/index.ts +5 -2
- package/src/business/instance-lock.test.ts +1060 -0
- package/src/business/instance-lock.ts +387 -78
- package/src/business/instance-state.test.ts +735 -0
- package/src/business/instance-state.ts +582 -337
- package/src/business/operation.test.ts +439 -0
- package/src/business/operation.ts +174 -208
- package/src/business/project-model.ts +258 -0
- package/src/business/project-unlock.ts +168 -126
- package/src/business/project.ts +287 -179
- package/src/business/secret.test.ts +465 -130
- package/src/business/secret.ts +186 -217
- package/src/business/settings.test.ts +695 -0
- package/src/business/settings.ts +855 -0
- package/src/business/terminal-session.ts +90 -0
- package/src/business/unit-extra.test.ts +539 -0
- package/src/business/unit-extra.ts +160 -0
- package/src/business/worker.test.ts +356 -579
- package/src/business/worker.ts +238 -339
- package/src/common/codebase.ts +65 -0
- package/src/common/index.ts +3 -5
- package/src/common/logger.ts +5 -0
- package/src/common/utils.ts +4 -3
- package/src/config.ts +10 -11
- package/src/database/_generated/backend/postgresql/client.ts +72 -0
- package/src/database/_generated/backend/postgresql/commonInputTypes.ts +350 -0
- package/src/database/_generated/backend/postgresql/enums.ts +13 -0
- package/src/database/_generated/backend/postgresql/internal/class.ts +320 -0
- package/src/database/_generated/backend/postgresql/internal/prismaNamespace.ts +1238 -0
- package/src/database/_generated/backend/postgresql/models/Library.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/Project.ts +2175 -0
- package/src/database/_generated/backend/postgresql/models/ProjectModelStorage.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/ProjectSpace.ts +1602 -0
- package/src/database/_generated/backend/postgresql/models/PulumiBackend.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/UserWorkspaseLayout.ts +1065 -0
- package/src/database/_generated/backend/postgresql/models.ts +16 -0
- package/src/database/_generated/backend/postgresql/pjtg.ts +182 -0
- package/src/database/_generated/backend/sqlite/client.ts +72 -0
- package/src/database/_generated/backend/sqlite/commonInputTypes.ts +331 -0
- package/src/database/_generated/backend/sqlite/enums.ts +13 -0
- package/src/database/_generated/backend/sqlite/internal/class.ts +318 -0
- package/src/database/_generated/backend/sqlite/internal/prismaNamespace.ts +1207 -0
- package/src/database/_generated/backend/sqlite/models/Library.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/Project.ts +2169 -0
- package/src/database/_generated/backend/sqlite/models/ProjectModelStorage.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/ProjectSpace.ts +1599 -0
- package/src/database/_generated/backend/sqlite/models/PulumiBackend.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/UserWorkspaseLayout.ts +1063 -0
- package/src/database/_generated/backend/sqlite/models.ts +16 -0
- package/src/database/_generated/backend/sqlite/pjtg.ts +182 -0
- package/src/database/_generated/project/client.ts +204 -0
- package/src/database/_generated/project/commonInputTypes.ts +827 -0
- package/src/database/_generated/project/enums.ts +104 -0
- package/src/database/_generated/project/internal/class.ts +479 -0
- package/src/database/_generated/project/internal/prismaNamespace.ts +2974 -0
- package/src/database/_generated/project/models/ApiKey.ts +1506 -0
- package/src/database/_generated/project/models/Artifact.ts +2051 -0
- package/src/database/_generated/project/models/HubModel.ts +1125 -0
- package/src/database/_generated/project/models/InstanceCustomStatus.ts +1713 -0
- package/src/database/_generated/project/models/InstanceEvaluationState.ts +1312 -0
- package/src/database/_generated/project/models/InstanceLock.ts +1268 -0
- package/src/database/_generated/project/models/InstanceModel.ts +1125 -0
- package/src/database/_generated/project/models/InstanceOperationState.ts +1707 -0
- package/src/database/_generated/project/models/InstanceState.ts +4613 -0
- package/src/database/_generated/project/models/Operation.ts +1647 -0
- package/src/database/_generated/project/models/OperationLog.ts +1455 -0
- package/src/database/_generated/project/models/Page.ts +1838 -0
- package/src/database/_generated/project/models/Secret.ts +1692 -0
- package/src/database/_generated/project/models/ServiceAccount.ts +2165 -0
- package/src/database/_generated/project/models/Terminal.ts +2038 -0
- package/src/database/_generated/project/models/TerminalSession.ts +1454 -0
- package/src/database/_generated/project/models/TerminalSessionLog.ts +1280 -0
- package/src/database/_generated/project/models/Trigger.ts +1430 -0
- package/src/database/_generated/project/models/UnlockMethod.ts +1220 -0
- package/src/database/_generated/project/models/UserCompositeViewport.ts +1280 -0
- package/src/database/_generated/project/models/UserProjectViewport.ts +1059 -0
- package/src/database/_generated/project/models/Worker.ts +1459 -0
- package/src/database/_generated/project/models/WorkerUnitRegistration.ts +1524 -0
- package/src/database/_generated/project/models/WorkerVersion.ts +1974 -0
- package/src/database/_generated/project/models/WorkerVersionLog.ts +1318 -0
- package/src/database/_generated/project/models.ts +35 -0
- package/src/database/_generated/project/pjtg.ts +182 -0
- package/src/database/abstractions.ts +19 -0
- package/src/database/factory.ts +37 -0
- package/src/database/index.ts +6 -0
- package/src/database/local/backend.ts +134 -0
- package/src/database/local/index.ts +3 -0
- package/src/database/local/meta.ts +46 -0
- package/src/database/local/prisma.config.ts +25 -0
- package/src/database/local/project.ts +39 -0
- package/src/database/manager.ts +181 -0
- package/src/database/migrate.ts +35 -0
- package/src/database/prisma.ts +56 -0
- package/src/database/well-known.ts +38 -0
- package/src/index.ts +4 -4
- package/src/library/abstractions.ts +3 -5
- package/src/library/factory.ts +1 -1
- package/src/library/local.ts +81 -26
- package/src/library/package-resolution-worker.ts +1 -1
- package/src/library/worker/evaluator.ts +40 -23
- package/src/library/worker/loader.lite.ts +1 -1
- package/src/library/worker/main.ts +3 -10
- package/src/library/worker/protocol.ts +0 -1
- package/src/lock/index.ts +0 -1
- package/src/lock/manager.ts +0 -10
- package/src/orchestrator/manager.ts +190 -104
- package/src/orchestrator/operation-context.ts +357 -0
- package/src/orchestrator/operation-plan.destroy.test.md +357 -0
- package/src/orchestrator/operation-plan.destroy.test.ts +775 -0
- package/src/orchestrator/operation-plan.fixtures.ts +213 -0
- package/src/orchestrator/operation-plan.md +198 -0
- package/src/orchestrator/operation-plan.refresh.test.md +199 -0
- package/src/orchestrator/operation-plan.refresh.test.ts +367 -0
- package/src/orchestrator/operation-plan.ts +709 -0
- package/src/orchestrator/operation-plan.update.test.md +485 -0
- package/src/orchestrator/operation-plan.update.test.ts +1066 -0
- package/src/orchestrator/operation-workset.ts +233 -578
- package/src/orchestrator/operation.ts +435 -948
- package/src/orchestrator/plan-test-builder.ts +267 -0
- package/src/project-model/abstractions.ts +118 -0
- package/src/project-model/backends/codebase.ts +365 -0
- package/src/project-model/backends/database.ts +440 -0
- package/src/project-model/errors.ts +81 -0
- package/src/project-model/factory.ts +24 -0
- package/src/project-model/index.ts +4 -0
- package/src/project-model/utils.test.ts +544 -0
- package/src/project-model/utils.ts +242 -0
- package/src/pubsub/abstractions.ts +10 -1
- package/src/pubsub/factory.ts +4 -4
- package/src/pubsub/index.ts +1 -0
- package/src/pubsub/manager.ts +29 -13
- package/src/pubsub/memory.ts +31 -0
- package/src/runner/abstractions.ts +33 -41
- package/src/runner/artifact-env.ts +19 -8
- package/src/runner/factory.ts +6 -6
- package/src/runner/force-abort.ts +3 -6
- package/src/runner/local.ts +64 -67
- package/src/runner/pulumi.ts +23 -63
- package/src/services.ts +181 -123
- package/src/shared/models/backend/index.ts +3 -1
- package/src/shared/models/backend/library.ts +9 -1
- package/src/shared/models/backend/project.ts +43 -42
- package/src/shared/models/backend/pulumi.ts +14 -0
- package/src/shared/models/backend/unlock-method.ts +1 -1
- package/src/shared/models/backend/well-known.ts +58 -0
- package/src/shared/models/base.ts +40 -26
- package/src/shared/models/errors.ts +82 -1
- package/src/shared/models/index.ts +3 -2
- package/src/shared/models/prisma.ts +36 -0
- package/src/shared/models/project/api-key.ts +37 -59
- package/src/shared/models/project/artifact.ts +16 -76
- package/src/shared/models/project/custom-status.ts +12 -0
- package/src/shared/models/project/index.ts +8 -7
- package/src/shared/models/project/lock.ts +10 -78
- package/src/shared/models/project/model.ts +19 -1
- package/src/shared/models/project/operation.ts +222 -99
- package/src/shared/models/project/page.ts +37 -48
- package/src/shared/models/project/secret.ts +29 -89
- package/src/shared/models/project/service-account.ts +12 -17
- package/src/shared/models/project/state.ts +100 -407
- package/src/shared/models/project/terminal.ts +75 -88
- package/src/shared/models/project/trigger.ts +13 -49
- package/src/shared/models/project/unlock-method.ts +20 -26
- package/src/shared/models/project/worker.ts +89 -90
- package/src/shared/resolvers/graph-resolver.ts +21 -0
- package/src/shared/resolvers/index.ts +1 -1
- package/src/shared/resolvers/input-hash.ts +24 -14
- package/src/shared/resolvers/input.ts +1 -1
- package/src/shared/resolvers/registry.ts +5 -4
- package/src/shared/resolvers/state.ts +12 -1
- package/src/shared/resolvers/validation.ts +7 -3
- package/src/shared/utils/index.ts +1 -2
- package/src/shared/utils/promise-tracker.ts +30 -3
- package/src/terminal/abstractions.ts +1 -1
- package/src/terminal/docker.ts +3 -3
- package/src/terminal/manager.ts +102 -118
- package/src/test-utils/database.ts +119 -0
- package/src/test-utils/index.ts +2 -0
- package/src/test-utils/services.ts +134 -0
- package/src/unlock/abstractions.ts +5 -23
- package/src/unlock/memory.ts +9 -14
- package/src/worker/abstractions.ts +7 -4
- package/src/worker/docker.ts +14 -19
- package/src/worker/manager.ts +366 -97
- package/dist/chunk-NAAIDR4U.js +0 -8499
- package/dist/chunk-NAAIDR4U.js.map +0 -1
- package/dist/chunk-Y7DXREVO.js +0 -1745
- package/dist/chunk-Y7DXREVO.js.map +0 -1
- package/dist/magic-string.es-5ABAC4JN.js +0 -1292
- package/dist/magic-string.es-5ABAC4JN.js.map +0 -1
- package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +0 -356
- package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +0 -274
- package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +0 -223
- package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +0 -147
- package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +0 -280
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +0 -360
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +0 -215
- package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +0 -427
- package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +0 -217
- package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +0 -132
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +0 -454
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +0 -426
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +0 -372
- package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +0 -383
- package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +0 -245
- package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +0 -174
- package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +0 -432
- package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +0 -220
- package/src/business/backend-unlock.ts +0 -10
- package/src/common/clock.ts +0 -18
- package/src/common/performance.ts +0 -44
- package/src/common/random.ts +0 -68
- package/src/common/test/index.ts +0 -2
- package/src/common/test/render.ts +0 -98
- package/src/common/test/tracer.ts +0 -359
- package/src/hotstate/abstractions.ts +0 -48
- package/src/hotstate/factory.ts +0 -17
- package/src/hotstate/index.ts +0 -3
- package/src/hotstate/manager.ts +0 -192
- package/src/hotstate/memory.ts +0 -100
- package/src/hotstate/validation.ts +0 -100
- package/src/lock/test.ts +0 -108
- package/src/project/abstractions.ts +0 -78
- package/src/project/evaluation.ts +0 -248
- package/src/project/factory.ts +0 -11
- package/src/project/index.ts +0 -3
- package/src/project/local.ts +0 -417
- package/src/pubsub/local.ts +0 -36
- package/src/pubsub/validation.ts +0 -33
- package/src/shared/utils/args.ts +0 -25
- package/src/state/abstractions.ts +0 -289
- package/src/state/encryption.ts +0 -98
- package/src/state/factory.ts +0 -20
- package/src/state/index.ts +0 -7
- package/src/state/local/backend.ts +0 -106
- package/src/state/local/collection.ts +0 -361
- package/src/state/local/index.ts +0 -2
- package/src/state/manager.ts +0 -890
- package/src/state/memory/backend.ts +0 -70
- package/src/state/memory/collection.ts +0 -270
- package/src/state/memory/index.ts +0 -2
- package/src/state/repository/index.ts +0 -2
- package/src/state/repository/repository.index.ts +0 -193
- package/src/state/repository/repository.ts +0 -507
- package/src/state/test.ts +0 -457
- /package/src/{state → database/local}/keyring.ts +0 -0
package/src/business/artifact.ts
CHANGED
|
@@ -1,87 +1,66 @@
|
|
|
1
|
+
import type { CommonObjectMeta } from "@highstate/contract"
|
|
1
2
|
import type { Logger } from "pino"
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type { LockManager } from "../lock"
|
|
5
|
-
import type { ObjectMeta } from "@highstate/contract"
|
|
6
|
-
import { v7 as uuidv7 } from "uuid"
|
|
7
|
-
import { unique } from "remeda"
|
|
8
|
-
import { compareArtifactUsage, type Artifact, type ArtifactUsage } from "../shared"
|
|
3
|
+
import type { ArtifactBackend } from "../artifact"
|
|
4
|
+
import type { Artifact, DatabaseManager, ProjectTransaction } from "../database"
|
|
9
5
|
|
|
10
|
-
const artifactChunkSize = 1024 * 1024 // 1 MB
|
|
6
|
+
export const artifactChunkSize = 1024 * 1024 // 1 MB
|
|
11
7
|
|
|
12
8
|
/**
|
|
13
9
|
* The service which handles the storage, retrieval, and management of artifacts in the system.
|
|
14
10
|
*/
|
|
15
11
|
export class ArtifactService {
|
|
16
12
|
constructor(
|
|
17
|
-
private readonly
|
|
13
|
+
private readonly database: DatabaseManager,
|
|
18
14
|
private readonly artifactBackend: ArtifactBackend,
|
|
19
|
-
private readonly lockManager: LockManager,
|
|
20
15
|
private readonly logger: Logger,
|
|
21
16
|
) {}
|
|
22
17
|
|
|
23
18
|
/**
|
|
24
|
-
* Stores an artifact in the backend and
|
|
19
|
+
* Stores an artifact in the backend and allows caller to set up references.
|
|
25
20
|
* If the artifact already exists, it does nothing.
|
|
26
21
|
*
|
|
27
|
-
* Returns the artifact ID of the stored artifact.
|
|
28
|
-
*
|
|
29
22
|
* @param projectId The project ID to store the artifact under.
|
|
30
|
-
* @param hash The
|
|
31
|
-
* @param meta The metadata for the artifact, including name, size, and other properties.
|
|
23
|
+
* @param hash The SHA256 hash of the artifact content.
|
|
32
24
|
* @param size The total size of the artifact in bytes.
|
|
33
|
-
* @param
|
|
25
|
+
* @param meta The metadata for the artifact.
|
|
34
26
|
* @param content An async iterable providing the artifact content in chunks.
|
|
35
|
-
* @param
|
|
27
|
+
* @param track A callback to set up artifact references within the transaction.
|
|
28
|
+
* @returns The model of the stored artifact.
|
|
36
29
|
*/
|
|
37
30
|
async store(
|
|
38
31
|
projectId: string,
|
|
39
32
|
hash: string,
|
|
40
33
|
size: number,
|
|
41
|
-
meta:
|
|
34
|
+
meta: CommonObjectMeta,
|
|
42
35
|
content: AsyncIterable<Uint8Array>,
|
|
43
|
-
|
|
44
|
-
): Promise<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
track: (tx: ProjectTransaction, artifact: Artifact) => Promise<void>,
|
|
37
|
+
): Promise<Artifact> {
|
|
38
|
+
// check if artifact already exists by hash
|
|
39
|
+
const database = await this.database.forProject(projectId)
|
|
40
|
+
const existingArtifact = await database.artifact.findUnique({ where: { hash } })
|
|
41
|
+
|
|
42
|
+
// only upload to backend if file doesn't exist there
|
|
43
|
+
if (!existingArtifact || !(await this.artifactBackend.exists(projectId, hash))) {
|
|
50
44
|
if (existingArtifact) {
|
|
51
|
-
const fileExists = await this.artifactBackend.exists(projectId, hash)
|
|
52
|
-
if (fileExists) {
|
|
53
|
-
this.logger.debug(`artifact with hash "%s" already exists`, hash)
|
|
54
|
-
return existingArtifact.id
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// TODO: make this check configurable
|
|
58
45
|
this.logger.warn(
|
|
59
|
-
`artifact with hash "%s" exists in
|
|
46
|
+
`artifact with hash "%s" exists in database but not in the storage backend, re-uploading`,
|
|
60
47
|
hash,
|
|
61
48
|
)
|
|
62
49
|
}
|
|
63
50
|
|
|
64
51
|
await this.artifactBackend.store(projectId, hash, artifactChunkSize, content)
|
|
52
|
+
}
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
meta,
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const batch = this.stateManager.batch()
|
|
76
|
-
|
|
77
|
-
await Promise.all([
|
|
78
|
-
this.stateManager.getArtifactRepository(projectId).putItem(artifact, batch),
|
|
79
|
-
this.stateManager
|
|
80
|
-
.getArtifactHashIndexRepository(projectId)
|
|
81
|
-
.indexRepository.put(hash, artifact.id, batch),
|
|
82
|
-
])
|
|
54
|
+
return await database.$transaction(async tx => {
|
|
55
|
+
// create or update the main artifact record
|
|
56
|
+
const artifact = await tx.artifact.upsert({
|
|
57
|
+
where: { hash },
|
|
58
|
+
create: { hash, size, meta, chunkSize: artifactChunkSize },
|
|
59
|
+
update: { meta },
|
|
60
|
+
})
|
|
83
61
|
|
|
84
|
-
|
|
62
|
+
// always allow caller to set up references
|
|
63
|
+
await track(tx, artifact)
|
|
85
64
|
|
|
86
65
|
this.logger.info(
|
|
87
66
|
{ projectId },
|
|
@@ -90,200 +69,141 @@ export class ArtifactService {
|
|
|
90
69
|
artifact.id,
|
|
91
70
|
)
|
|
92
71
|
|
|
93
|
-
return artifact
|
|
72
|
+
return artifact
|
|
94
73
|
})
|
|
95
74
|
}
|
|
96
75
|
|
|
97
76
|
/**
|
|
98
|
-
*
|
|
77
|
+
* Clears all artifact references for a specific instance and runs garbage collection.
|
|
78
|
+
* This removes all associations between the instance and its artifacts, then
|
|
79
|
+
* cleans up any unreferenced artifacts.
|
|
99
80
|
*
|
|
100
|
-
* @param projectId The project ID
|
|
101
|
-
* @param
|
|
102
|
-
* @param usages The list of usages to track for the artifacts.
|
|
103
|
-
* @returns
|
|
81
|
+
* @param projectId The project ID.
|
|
82
|
+
* @param instanceId The instance ID to clear artifact references for.
|
|
104
83
|
*/
|
|
105
|
-
async
|
|
106
|
-
projectId
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
84
|
+
async clearInstanceArtifactReferences(projectId: string, instanceId: string): Promise<void> {
|
|
85
|
+
const database = await this.database.forProject(projectId)
|
|
86
|
+
|
|
87
|
+
this.logger.info({ projectId, instanceId }, "clearing instance artifact references")
|
|
88
|
+
|
|
89
|
+
// clear instance-artifact associations for the specific instance
|
|
90
|
+
await database.$transaction(async tx => {
|
|
91
|
+
// get all artifacts connected to this instance
|
|
92
|
+
const artifactsConnectedToInstance = await tx.artifact.findMany({
|
|
93
|
+
where: {
|
|
94
|
+
instances: {
|
|
95
|
+
some: {
|
|
96
|
+
id: instanceId,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
select: {
|
|
101
|
+
id: true,
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// disconnect the specific instance from these artifacts
|
|
106
|
+
await Promise.all(
|
|
107
|
+
artifactsConnectedToInstance.map(artifact =>
|
|
108
|
+
tx.artifact.update({
|
|
109
|
+
where: { id: artifact.id },
|
|
110
|
+
data: {
|
|
111
|
+
instances: {
|
|
112
|
+
disconnect: { id: instanceId },
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
),
|
|
117
|
+
)
|
|
130
118
|
})
|
|
131
119
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const artifactsToUpdate: Artifact[] = []
|
|
137
|
-
|
|
138
|
-
for (const artifactId of artifactIds) {
|
|
139
|
-
const artifact = artifacts[artifactId]
|
|
140
|
-
if (!artifact) {
|
|
141
|
-
this.logger.warn({
|
|
142
|
-
msg: "artifact not found during usage addition",
|
|
143
|
-
projectId,
|
|
144
|
-
artifactId,
|
|
145
|
-
})
|
|
146
|
-
continue
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// add new usages to the artifact
|
|
150
|
-
for (const usage of usages) {
|
|
151
|
-
if (!artifact.usages.some(u => compareArtifactUsage(u, usage))) {
|
|
152
|
-
artifact.usages.push(usage)
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
artifactsToUpdate.push(artifact)
|
|
157
|
-
}
|
|
120
|
+
this.logger.info(
|
|
121
|
+
{ projectId, instanceId },
|
|
122
|
+
"cleared instance artifact references, running garbage collection",
|
|
123
|
+
)
|
|
158
124
|
|
|
159
|
-
|
|
125
|
+
// run garbage collection to clean up now-unreferenced artifacts
|
|
126
|
+
await this.collectGarbage(projectId)
|
|
160
127
|
}
|
|
161
128
|
|
|
162
129
|
/**
|
|
163
|
-
* Removes
|
|
164
|
-
*
|
|
165
|
-
* If an artifact has no usages left, it will be deleted immediately.
|
|
130
|
+
* Removes artifacts with no references and cleans up backend storage.
|
|
166
131
|
*
|
|
167
|
-
* @param projectId The project ID to
|
|
168
|
-
* @param artifactIds The IDs of the artifacts to remove usages for.
|
|
169
|
-
* @param usages The list of usages to remove from the artifacts.
|
|
132
|
+
* @param projectId The project ID to clean up artifacts for.
|
|
170
133
|
*/
|
|
171
|
-
async
|
|
172
|
-
projectId
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
134
|
+
async collectGarbage(projectId: string): Promise<void> {
|
|
135
|
+
const database = await this.database.forProject(projectId)
|
|
136
|
+
|
|
137
|
+
// find artifacts with no references using Prisma ORM
|
|
138
|
+
const unreferencedArtifacts = await database.artifact.findMany({
|
|
139
|
+
where: {
|
|
140
|
+
AND: [
|
|
141
|
+
{ serviceAccounts: { none: {} } },
|
|
142
|
+
{ instances: { none: {} } },
|
|
143
|
+
{ terminals: { none: {} } },
|
|
144
|
+
{ pages: { none: {} } },
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
select: {
|
|
148
|
+
id: true,
|
|
149
|
+
hash: true,
|
|
150
|
+
},
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
if (unreferencedArtifacts.length === 0) {
|
|
154
|
+
this.logger.debug({ projectId }, "no unreferenced artifacts found")
|
|
177
155
|
return
|
|
178
156
|
}
|
|
179
157
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
158
|
+
this.logger.info(
|
|
159
|
+
{ projectId, count: unreferencedArtifacts.length },
|
|
160
|
+
"collecting garbage artifacts",
|
|
183
161
|
)
|
|
184
|
-
}
|
|
185
162
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
projectId,
|
|
194
|
-
artifactIds,
|
|
195
|
-
usages,
|
|
163
|
+
// delete unreferenced artifacts in transaction
|
|
164
|
+
await database.$transaction(async tx => {
|
|
165
|
+
await tx.artifact.deleteMany({
|
|
166
|
+
where: {
|
|
167
|
+
id: { in: unreferencedArtifacts.map(a => a.id) },
|
|
168
|
+
},
|
|
169
|
+
})
|
|
196
170
|
})
|
|
197
171
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
})
|
|
213
|
-
continue
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// remove specified usages from the artifact
|
|
217
|
-
artifact.usages = artifact.usages.filter(
|
|
218
|
-
u => !usages.some(usage => compareArtifactUsage(u, usage)),
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
if (artifact.usages.length === 0) {
|
|
222
|
-
// if no usages left, mark for deletion
|
|
223
|
-
artifactsToDelete.push(artifact)
|
|
224
|
-
} else {
|
|
225
|
-
// otherwise, update the artifact metadata
|
|
226
|
-
artifactsToUpdate.push(artifact)
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (artifactsToUpdate.length > 0) {
|
|
231
|
-
await this.stateManager.getArtifactRepository(projectId).putManyItems(artifactsToUpdate)
|
|
232
|
-
}
|
|
172
|
+
// clean up backend storage for deleted artifacts in foreground
|
|
173
|
+
await Promise.all(
|
|
174
|
+
unreferencedArtifacts.map(async artifact => {
|
|
175
|
+
try {
|
|
176
|
+
await this.artifactBackend.delete(projectId, artifact.hash)
|
|
177
|
+
} catch (error: unknown) {
|
|
178
|
+
this.logger.warn(
|
|
179
|
+
{ error, projectId, hash: artifact.hash },
|
|
180
|
+
`failed to delete artifact from backend with hash "%s"`,
|
|
181
|
+
artifact.hash,
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
}),
|
|
185
|
+
)
|
|
233
186
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
187
|
+
this.logger.info(
|
|
188
|
+
{ projectId, deletedCount: unreferencedArtifacts.length },
|
|
189
|
+
"garbage collection completed",
|
|
190
|
+
)
|
|
237
191
|
}
|
|
238
192
|
|
|
239
193
|
/**
|
|
240
|
-
*
|
|
194
|
+
* Gets artifact entities by their IDs.
|
|
241
195
|
*
|
|
242
|
-
* @param projectId The project ID to
|
|
243
|
-
* @param
|
|
244
|
-
* @
|
|
245
|
-
* @param newArtifactIds The IDs of the artifacts that now have this usage.
|
|
196
|
+
* @param projectId The project ID to query artifacts from.
|
|
197
|
+
* @param artifactIds The IDs of the artifacts to retrieve.
|
|
198
|
+
* @returns Array of artifact models.
|
|
246
199
|
*/
|
|
247
|
-
async
|
|
248
|
-
projectId
|
|
249
|
-
usage: ArtifactUsage,
|
|
250
|
-
oldArtifactIds: string[],
|
|
251
|
-
newArtifactIds: string[],
|
|
252
|
-
): Promise<void> {
|
|
253
|
-
const removedArtifactIds = oldArtifactIds.filter(id => !newArtifactIds.includes(id))
|
|
254
|
-
const allArtifactIds = unique([...oldArtifactIds, ...newArtifactIds])
|
|
200
|
+
async getArtifactsByIds(projectId: string, artifactIds: string[]): Promise<Artifact[]> {
|
|
201
|
+
const database = await this.database.forProject(projectId)
|
|
255
202
|
|
|
256
|
-
await
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
await this._addUsages(projectId, newArtifactIds, [usage])
|
|
260
|
-
await this._removeUsages(projectId, removedArtifactIds, [usage])
|
|
203
|
+
return await database.artifact.findMany({
|
|
204
|
+
where: {
|
|
205
|
+
id: { in: artifactIds },
|
|
261
206
|
},
|
|
262
|
-
)
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
private async removeArtifacts(projectId: string, artifacts: Artifact[]): Promise<void> {
|
|
266
|
-
const batch = this.stateManager.batch()
|
|
267
|
-
|
|
268
|
-
await Promise.all([
|
|
269
|
-
this.stateManager.getArtifactRepository(projectId).deleteMany(
|
|
270
|
-
artifacts.map(a => a.id),
|
|
271
|
-
batch,
|
|
272
|
-
),
|
|
273
|
-
this.stateManager.getArtifactHashIndexRepository(projectId).indexRepository.deleteMany(
|
|
274
|
-
artifacts.map(a => a.hash),
|
|
275
|
-
batch,
|
|
276
|
-
),
|
|
277
|
-
])
|
|
278
|
-
|
|
279
|
-
await Promise.allSettled(
|
|
280
|
-
artifacts.map(artifact => this.artifactBackend.delete(projectId, artifact.hash)),
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
this.logger.info({
|
|
284
|
-
msg: "deleted dangling artifacts",
|
|
285
|
-
projectId,
|
|
286
|
-
artifactHashes: artifacts.map(a => a.hash),
|
|
287
207
|
})
|
|
288
208
|
}
|
|
289
209
|
}
|