@claudexor/daemon 3.25.1 → 4.0.0
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/account-resets.d.ts +2 -2
- package/dist/account-resets.d.ts.map +1 -1
- package/dist/account-resets.js +15 -0
- package/dist/account-resets.js.map +1 -1
- package/dist/client.d.ts +25 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +55 -51
- package/dist/client.js.map +1 -1
- package/dist/command-authority.d.ts +11 -8
- package/dist/command-authority.d.ts.map +1 -1
- package/dist/command-authority.js +5 -6
- package/dist/command-authority.js.map +1 -1
- package/dist/command-list-projection.d.ts +0 -1
- package/dist/command-list-projection.d.ts.map +1 -1
- package/dist/command-list-projection.js +0 -6
- package/dist/command-list-projection.js.map +1 -1
- package/dist/command-list-select.d.ts +0 -4
- package/dist/command-list-select.d.ts.map +1 -1
- package/dist/command-list-select.js +1 -115
- package/dist/command-list-select.js.map +1 -1
- package/dist/command-retention.d.ts +7 -19
- package/dist/command-retention.d.ts.map +1 -1
- package/dist/command-retention.js +1 -120
- package/dist/command-retention.js.map +1 -1
- package/dist/command-rpc.d.ts +4 -1
- package/dist/command-rpc.d.ts.map +1 -1
- package/dist/command-rpc.js +12 -1
- package/dist/command-rpc.js.map +1 -1
- package/dist/command-store.d.ts +15 -52
- package/dist/command-store.d.ts.map +1 -1
- package/dist/command-store.js +5 -493
- package/dist/command-store.js.map +1 -1
- package/dist/daemon-health.d.ts +56 -8
- package/dist/daemon-health.d.ts.map +1 -1
- package/dist/daemon-health.js +44 -9
- package/dist/daemon-health.js.map +1 -1
- package/dist/daemon-local-client.d.ts +28 -0
- package/dist/daemon-local-client.d.ts.map +1 -0
- package/dist/daemon-local-client.js +55 -0
- package/dist/daemon-local-client.js.map +1 -0
- package/dist/delivery-command.d.ts +4 -4
- package/dist/delivery-command.d.ts.map +1 -1
- package/dist/delivery-command.js.map +1 -1
- package/dist/index.d.ts +23 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -8
- package/dist/index.js.map +1 -1
- package/dist/interactions.d.ts +12 -28
- package/dist/interactions.d.ts.map +1 -1
- package/dist/interactions.js +22 -123
- package/dist/interactions.js.map +1 -1
- package/dist/job-admission.d.ts +26 -0
- package/dist/job-admission.d.ts.map +1 -0
- package/dist/job-admission.js +67 -0
- package/dist/job-admission.js.map +1 -0
- package/dist/journal-fold-policy.d.ts +1 -1
- package/dist/journal-fold-policy.d.ts.map +1 -1
- package/dist/journal-recovery-files.d.ts +1 -41
- package/dist/journal-recovery-files.d.ts.map +1 -1
- package/dist/journal-recovery-files.js +2 -340
- package/dist/journal-recovery-files.js.map +1 -1
- package/dist/loop-facts.d.ts +28 -0
- package/dist/loop-facts.d.ts.map +1 -0
- package/dist/loop-facts.js +97 -0
- package/dist/loop-facts.js.map +1 -0
- package/dist/memory-facts.d.ts +2 -0
- package/dist/memory-facts.d.ts.map +1 -1
- package/dist/memory-facts.js +5 -0
- package/dist/memory-facts.js.map +1 -1
- package/dist/model-operations.d.ts +11 -4
- package/dist/model-operations.d.ts.map +1 -1
- package/dist/model-operations.js +68 -38
- package/dist/model-operations.js.map +1 -1
- package/dist/operator-decisions.d.ts +15 -25
- package/dist/operator-decisions.d.ts.map +1 -1
- package/dist/operator-decisions.js +5 -84
- package/dist/operator-decisions.js.map +1 -1
- package/dist/projects.d.ts +42 -41
- package/dist/projects.d.ts.map +1 -1
- package/dist/projects.js +46 -184
- package/dist/projects.js.map +1 -1
- package/dist/quota-registry-replay.d.ts +2 -2
- package/dist/quota-registry-replay.d.ts.map +1 -1
- package/dist/quota-registry-replay.js.map +1 -1
- package/dist/quota-registry-support.d.ts +4 -1
- package/dist/quota-registry-support.d.ts.map +1 -1
- package/dist/quota-registry-support.js +15 -2
- package/dist/quota-registry-support.js.map +1 -1
- package/dist/quota-registry.d.ts +64 -2
- package/dist/quota-registry.d.ts.map +1 -1
- package/dist/quota-registry.js +10 -3
- package/dist/quota-registry.js.map +1 -1
- package/dist/quota-resources.d.ts +6 -3
- package/dist/quota-resources.d.ts.map +1 -1
- package/dist/quota-resources.js +25 -8
- package/dist/quota-resources.js.map +1 -1
- package/dist/runless-turn-recovery.d.ts +2 -9
- package/dist/runless-turn-recovery.d.ts.map +1 -1
- package/dist/runless-turn-recovery.js +0 -14
- package/dist/runless-turn-recovery.js.map +1 -1
- package/dist/server.d.ts +23 -22
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +74 -84
- package/dist/server.js.map +1 -1
- package/dist/store/blob-files.d.ts +71 -0
- package/dist/store/blob-files.d.ts.map +1 -0
- package/dist/store/blob-files.js +160 -0
- package/dist/store/blob-files.js.map +1 -0
- package/dist/store/command-prune.d.ts +37 -0
- package/dist/store/command-prune.d.ts.map +1 -0
- package/dist/store/command-prune.js +123 -0
- package/dist/store/command-prune.js.map +1 -0
- package/dist/store/command-queries.d.ts +41 -0
- package/dist/store/command-queries.d.ts.map +1 -0
- package/dist/store/command-queries.js +186 -0
- package/dist/store/command-queries.js.map +1 -0
- package/dist/store/command-rows.d.ts +66 -0
- package/dist/store/command-rows.d.ts.map +1 -0
- package/dist/store/command-rows.js +141 -0
- package/dist/store/command-rows.js.map +1 -0
- package/dist/store/commands.d.ts +49 -0
- package/dist/store/commands.d.ts.map +1 -0
- package/dist/store/commands.js +247 -0
- package/dist/store/commands.js.map +1 -0
- package/dist/store/cursors.d.ts +33 -0
- package/dist/store/cursors.d.ts.map +1 -0
- package/dist/store/cursors.js +82 -0
- package/dist/store/cursors.js.map +1 -0
- package/dist/store/engine-recovery-files.d.ts +14 -0
- package/dist/store/engine-recovery-files.d.ts.map +1 -0
- package/dist/store/engine-recovery-files.js +53 -0
- package/dist/store/engine-recovery-files.js.map +1 -0
- package/dist/store/engine-state-recovery.d.ts +71 -0
- package/dist/store/engine-state-recovery.d.ts.map +1 -0
- package/dist/store/engine-state-recovery.js +318 -0
- package/dist/store/engine-state-recovery.js.map +1 -0
- package/dist/store/errors.d.ts +80 -0
- package/dist/store/errors.d.ts.map +1 -0
- package/dist/store/errors.js +130 -0
- package/dist/store/errors.js.map +1 -0
- package/dist/store/event-store.d.ts +52 -0
- package/dist/store/event-store.d.ts.map +1 -0
- package/dist/store/event-store.js +117 -0
- package/dist/store/event-store.js.map +1 -0
- package/dist/store/external-files.d.ts +40 -0
- package/dist/store/external-files.d.ts.map +1 -0
- package/dist/store/external-files.js +90 -0
- package/dist/store/external-files.js.map +1 -0
- package/dist/store/flusher-protocol.d.ts +82 -0
- package/dist/store/flusher-protocol.d.ts.map +1 -0
- package/dist/store/flusher-protocol.js +23 -0
- package/dist/store/flusher-protocol.js.map +1 -0
- package/dist/store/flusher-worker.d.ts +24 -0
- package/dist/store/flusher-worker.d.ts.map +1 -0
- package/dist/store/flusher-worker.js +185 -0
- package/dist/store/flusher-worker.js.map +1 -0
- package/dist/store/flusher.d.ts +87 -0
- package/dist/store/flusher.d.ts.map +1 -0
- package/dist/store/flusher.js +264 -0
- package/dist/store/flusher.js.map +1 -0
- package/dist/store/generations.d.ts +43 -0
- package/dist/store/generations.d.ts.map +1 -0
- package/dist/store/generations.js +143 -0
- package/dist/store/generations.js.map +1 -0
- package/dist/store/idempotency.d.ts +25 -0
- package/dist/store/idempotency.d.ts.map +1 -0
- package/dist/store/idempotency.js +53 -0
- package/dist/store/idempotency.js.map +1 -0
- package/dist/store/import-context.d.ts +22 -0
- package/dist/store/import-context.d.ts.map +1 -0
- package/dist/store/import-context.js +87 -0
- package/dist/store/import-context.js.map +1 -0
- package/dist/store/import-discovery.d.ts +6 -0
- package/dist/store/import-discovery.d.ts.map +1 -0
- package/dist/store/import-discovery.js +66 -0
- package/dist/store/import-discovery.js.map +1 -0
- package/dist/store/import-records.d.ts +6 -0
- package/dist/store/import-records.d.ts.map +1 -0
- package/dist/store/import-records.js +191 -0
- package/dist/store/import-records.js.map +1 -0
- package/dist/store/import-resources.d.ts +14 -0
- package/dist/store/import-resources.d.ts.map +1 -0
- package/dist/store/import-resources.js +197 -0
- package/dist/store/import-resources.js.map +1 -0
- package/dist/store/import-source.d.ts +24 -0
- package/dist/store/import-source.d.ts.map +1 -0
- package/dist/store/import-source.js +65 -0
- package/dist/store/import-source.js.map +1 -0
- package/dist/store/import-verify.d.ts +6 -0
- package/dist/store/import-verify.d.ts.map +1 -0
- package/dist/store/import-verify.js +97 -0
- package/dist/store/import-verify.js.map +1 -0
- package/dist/store/import-worker.d.ts +18 -0
- package/dist/store/import-worker.d.ts.map +1 -0
- package/dist/store/import-worker.js +69 -0
- package/dist/store/import-worker.js.map +1 -0
- package/dist/store/importer.d.ts +42 -0
- package/dist/store/importer.d.ts.map +1 -0
- package/dist/store/importer.js +239 -0
- package/dist/store/importer.js.map +1 -0
- package/dist/store/interactions.d.ts +22 -0
- package/dist/store/interactions.d.ts.map +1 -0
- package/dist/store/interactions.js +82 -0
- package/dist/store/interactions.js.map +1 -0
- package/dist/store/legacy-journal/frame-codec.d.ts +94 -0
- package/dist/store/legacy-journal/frame-codec.d.ts.map +1 -0
- package/dist/store/legacy-journal/frame-codec.js +352 -0
- package/dist/store/legacy-journal/frame-codec.js.map +1 -0
- package/dist/store/legacy-journal/frame-reader.d.ts +30 -0
- package/dist/store/legacy-journal/frame-reader.d.ts.map +1 -0
- package/dist/store/legacy-journal/frame-reader.js +97 -0
- package/dist/store/legacy-journal/frame-reader.js.map +1 -0
- package/dist/store/legacy-journal/journal-fold.d.ts +47 -0
- package/dist/store/legacy-journal/journal-fold.d.ts.map +1 -0
- package/dist/store/legacy-journal/journal-fold.js +81 -0
- package/dist/store/legacy-journal/journal-fold.js.map +1 -0
- package/dist/store/legacy-journal/journal-partition.d.ts +2 -0
- package/dist/store/legacy-journal/journal-partition.d.ts.map +1 -0
- package/dist/store/legacy-journal/journal-partition.js +10 -0
- package/dist/store/legacy-journal/journal-partition.js.map +1 -0
- package/dist/store/legacy-journal/read-only-preparation.d.ts +48 -0
- package/dist/store/legacy-journal/read-only-preparation.d.ts.map +1 -0
- package/dist/store/legacy-journal/read-only-preparation.js +430 -0
- package/dist/store/legacy-journal/read-only-preparation.js.map +1 -0
- package/dist/store/maintenance-worker.d.ts +5 -0
- package/dist/store/maintenance-worker.d.ts.map +1 -0
- package/dist/store/maintenance-worker.js +175 -0
- package/dist/store/maintenance-worker.js.map +1 -0
- package/dist/store/maintenance.d.ts +124 -0
- package/dist/store/maintenance.d.ts.map +1 -0
- package/dist/store/maintenance.js +197 -0
- package/dist/store/maintenance.js.map +1 -0
- package/dist/store/mutation.d.ts +34 -0
- package/dist/store/mutation.d.ts.map +1 -0
- package/dist/store/mutation.js +85 -0
- package/dist/store/mutation.js.map +1 -0
- package/dist/store/obligations.d.ts +101 -0
- package/dist/store/obligations.d.ts.map +1 -0
- package/dist/store/obligations.js +226 -0
- package/dist/store/obligations.js.map +1 -0
- package/dist/store/operator-decisions.d.ts +23 -0
- package/dist/store/operator-decisions.d.ts.map +1 -0
- package/dist/store/operator-decisions.js +68 -0
- package/dist/store/operator-decisions.js.map +1 -0
- package/dist/store/owner-generations.d.ts +33 -0
- package/dist/store/owner-generations.d.ts.map +1 -0
- package/dist/store/owner-generations.js +63 -0
- package/dist/store/owner-generations.js.map +1 -0
- package/dist/store/partitions.d.ts +37 -0
- package/dist/store/partitions.d.ts.map +1 -0
- package/dist/store/partitions.js +68 -0
- package/dist/store/partitions.js.map +1 -0
- package/dist/store/pragmas.d.ts +32 -0
- package/dist/store/pragmas.d.ts.map +1 -0
- package/dist/store/pragmas.js +65 -0
- package/dist/store/pragmas.js.map +1 -0
- package/dist/store/project-router.d.ts +325 -0
- package/dist/store/project-router.d.ts.map +1 -0
- package/dist/store/project-router.js +298 -0
- package/dist/store/project-router.js.map +1 -0
- package/dist/store/projects.d.ts +36 -0
- package/dist/store/projects.d.ts.map +1 -0
- package/dist/store/projects.js +238 -0
- package/dist/store/projects.js.map +1 -0
- package/dist/store/publish-blob.d.ts +20 -0
- package/dist/store/publish-blob.d.ts.map +1 -0
- package/dist/store/publish-blob.js +158 -0
- package/dist/store/publish-blob.js.map +1 -0
- package/dist/store/purge-files.d.ts +30 -0
- package/dist/store/purge-files.d.ts.map +1 -0
- package/dist/store/purge-files.js +79 -0
- package/dist/store/purge-files.js.map +1 -0
- package/dist/store/resource-rows.d.ts +40 -0
- package/dist/store/resource-rows.d.ts.map +1 -0
- package/dist/store/resource-rows.js +103 -0
- package/dist/store/resource-rows.js.map +1 -0
- package/dist/store/resources.d.ts +67 -0
- package/dist/store/resources.d.ts.map +1 -0
- package/dist/store/resources.js +147 -0
- package/dist/store/resources.js.map +1 -0
- package/dist/store/retention.d.ts +91 -0
- package/dist/store/retention.d.ts.map +1 -0
- package/dist/store/retention.js +169 -0
- package/dist/store/retention.js.map +1 -0
- package/dist/store/run-events.d.ts +14 -0
- package/dist/store/run-events.d.ts.map +1 -0
- package/dist/store/run-events.js +35 -0
- package/dist/store/run-events.js.map +1 -0
- package/dist/store/runtime.d.ts +24 -0
- package/dist/store/runtime.d.ts.map +1 -0
- package/dist/store/runtime.js +67 -0
- package/dist/store/runtime.js.map +1 -0
- package/dist/store/schema.d.ts +33 -0
- package/dist/store/schema.d.ts.map +1 -0
- package/dist/store/schema.js +187 -0
- package/dist/store/schema.js.map +1 -0
- package/dist/store/setup-bindings.d.ts +20 -0
- package/dist/store/setup-bindings.d.ts.map +1 -0
- package/dist/store/setup-bindings.js +52 -0
- package/dist/store/setup-bindings.js.map +1 -0
- package/dist/store/sql-command-router.d.ts +79 -0
- package/dist/store/sql-command-router.d.ts.map +1 -0
- package/dist/store/sql-command-router.js +92 -0
- package/dist/store/sql-command-router.js.map +1 -0
- package/dist/store/sql-daemon-services.d.ts +61 -0
- package/dist/store/sql-daemon-services.d.ts.map +1 -0
- package/dist/store/sql-daemon-services.js +124 -0
- package/dist/store/sql-daemon-services.js.map +1 -0
- package/dist/store/sql-recovery-export.d.ts +8 -0
- package/dist/store/sql-recovery-export.d.ts.map +1 -0
- package/dist/store/sql-recovery-export.js +110 -0
- package/dist/store/sql-recovery-export.js.map +1 -0
- package/dist/store/sql-recovery-inspection.d.ts +22 -0
- package/dist/store/sql-recovery-inspection.d.ts.map +1 -0
- package/dist/store/sql-recovery-inspection.js +88 -0
- package/dist/store/sql-recovery-inspection.js.map +1 -0
- package/dist/store/sql-recovery.d.ts +69 -0
- package/dist/store/sql-recovery.d.ts.map +1 -0
- package/dist/store/sql-recovery.js +169 -0
- package/dist/store/sql-recovery.js.map +1 -0
- package/dist/store/sql-validation.d.ts +9 -0
- package/dist/store/sql-validation.d.ts.map +1 -0
- package/dist/store/sql-validation.js +103 -0
- package/dist/store/sql-validation.js.map +1 -0
- package/dist/store/statement-observer.d.ts +7 -0
- package/dist/store/statement-observer.d.ts.map +1 -0
- package/dist/store/statement-observer.js +44 -0
- package/dist/store/statement-observer.js.map +1 -0
- package/dist/store/store.d.ts +110 -0
- package/dist/store/store.d.ts.map +1 -0
- package/dist/store/store.js +296 -0
- package/dist/store/store.js.map +1 -0
- package/dist/store/terminal-files.d.ts +21 -0
- package/dist/store/terminal-files.d.ts.map +1 -0
- package/dist/store/terminal-files.js +115 -0
- package/dist/store/terminal-files.js.map +1 -0
- package/dist/store/thread-replay.d.ts +12 -0
- package/dist/store/thread-replay.d.ts.map +1 -0
- package/dist/store/thread-replay.js +49 -0
- package/dist/store/thread-replay.js.map +1 -0
- package/dist/store/thread-rows.d.ts +25 -0
- package/dist/store/thread-rows.d.ts.map +1 -0
- package/dist/store/thread-rows.js +141 -0
- package/dist/store/thread-rows.js.map +1 -0
- package/dist/store/threads.d.ts +105 -0
- package/dist/store/threads.d.ts.map +1 -0
- package/dist/store/threads.js +423 -0
- package/dist/store/threads.js.map +1 -0
- package/dist/store/upload-binding-retention.d.ts +26 -0
- package/dist/store/upload-binding-retention.d.ts.map +1 -0
- package/dist/store/upload-binding-retention.js +142 -0
- package/dist/store/upload-binding-retention.js.map +1 -0
- package/dist/store/uploads.d.ts +30 -0
- package/dist/store/uploads.d.ts.map +1 -0
- package/dist/store/uploads.js +238 -0
- package/dist/store/uploads.js.map +1 -0
- package/dist/store-contracts.d.ts +181 -0
- package/dist/store-contracts.d.ts.map +1 -0
- package/dist/store-contracts.js +2 -0
- package/dist/store-contracts.js.map +1 -0
- package/dist/terminal-authority.d.ts +9 -0
- package/dist/terminal-authority.d.ts.map +1 -1
- package/dist/terminal-authority.js +103 -1
- package/dist/terminal-authority.js.map +1 -1
- package/dist/thread-lane-checkpoints.d.ts +0 -2
- package/dist/thread-lane-checkpoints.d.ts.map +1 -1
- package/dist/thread-lane-checkpoints.js +0 -4
- package/dist/thread-lane-checkpoints.js.map +1 -1
- package/dist/thread-store-support.d.ts +1 -27
- package/dist/thread-store-support.d.ts.map +1 -1
- package/dist/thread-store-support.js +0 -63
- package/dist/thread-store-support.js.map +1 -1
- package/dist/threads.d.ts +1 -113
- package/dist/threads.d.ts.map +1 -1
- package/dist/threads.js +1 -379
- package/dist/threads.js.map +1 -1
- package/package.json +9 -7
- package/dist/command-activity.d.ts +0 -14
- package/dist/command-activity.d.ts.map +0 -1
- package/dist/command-activity.js +0 -16
- package/dist/command-activity.js.map +0 -1
- package/dist/journal-events.d.ts +0 -4
- package/dist/journal-events.d.ts.map +0 -1
- package/dist/journal-events.js +0 -23
- package/dist/journal-events.js.map +0 -1
- package/dist/journal-maintenance.d.ts +0 -50
- package/dist/journal-maintenance.d.ts.map +0 -1
- package/dist/journal-maintenance.js +0 -162
- package/dist/journal-maintenance.js.map +0 -1
- package/dist/journal-manager-journal.d.ts +0 -18
- package/dist/journal-manager-journal.d.ts.map +0 -1
- package/dist/journal-manager-journal.js +0 -25
- package/dist/journal-manager-journal.js.map +0 -1
- package/dist/journal-manager-lifecycle.d.ts +0 -11
- package/dist/journal-manager-lifecycle.d.ts.map +0 -1
- package/dist/journal-manager-lifecycle.js +0 -2
- package/dist/journal-manager-lifecycle.js.map +0 -1
- package/dist/journal-manager.d.ts +0 -99
- package/dist/journal-manager.d.ts.map +0 -1
- package/dist/journal-manager.js +0 -559
- package/dist/journal-manager.js.map +0 -1
- package/dist/journal-prepared-operation.d.ts +0 -53
- package/dist/journal-prepared-operation.d.ts.map +0 -1
- package/dist/journal-prepared-operation.js +0 -158
- package/dist/journal-prepared-operation.js.map +0 -1
- package/dist/journal-projection-slot.d.ts +0 -28
- package/dist/journal-projection-slot.d.ts.map +0 -1
- package/dist/journal-projection-slot.js +0 -71
- package/dist/journal-projection-slot.js.map +0 -1
- package/dist/journal-projection.d.ts +0 -13
- package/dist/journal-projection.d.ts.map +0 -1
- package/dist/journal-projection.js +0 -2
- package/dist/journal-projection.js.map +0 -1
- package/dist/partition-accounts.d.ts +0 -27
- package/dist/partition-accounts.d.ts.map +0 -1
- package/dist/partition-accounts.js +0 -21
- package/dist/partition-accounts.js.map +0 -1
- package/dist/project-partition-preparation.d.ts +0 -87
- package/dist/project-partition-preparation.d.ts.map +0 -1
- package/dist/project-partition-preparation.js +0 -273
- package/dist/project-partition-preparation.js.map +0 -1
- package/dist/project-partitions.d.ts +0 -214
- package/dist/project-partitions.d.ts.map +0 -1
- package/dist/project-partitions.js +0 -486
- package/dist/project-partitions.js.map +0 -1
- package/dist/project-remove.d.ts +0 -11
- package/dist/project-remove.d.ts.map +0 -1
- package/dist/project-remove.js +0 -65
- package/dist/project-remove.js.map +0 -1
- package/dist/project-thread-listing.d.ts +0 -14
- package/dist/project-thread-listing.d.ts.map +0 -1
- package/dist/project-thread-listing.js +0 -37
- package/dist/project-thread-listing.js.map +0 -1
- package/dist/quota-projection.d.ts +0 -11
- package/dist/quota-projection.d.ts.map +0 -1
- package/dist/quota-projection.js +0 -10
- package/dist/quota-projection.js.map +0 -1
- package/dist/resource-store.d.ts +0 -39
- package/dist/resource-store.d.ts.map +0 -1
- package/dist/resource-store.js +0 -464
- package/dist/resource-store.js.map +0 -1
- package/dist/run-event-terminal-index.d.ts +0 -13
- package/dist/run-event-terminal-index.d.ts.map +0 -1
- package/dist/run-event-terminal-index.js +0 -38
- package/dist/run-event-terminal-index.js.map +0 -1
- package/dist/run-events.d.ts +0 -17
- package/dist/run-events.d.ts.map +0 -1
- package/dist/run-events.js +0 -31
- package/dist/run-events.js.map +0 -1
- package/dist/thread-head-ping.d.ts +0 -35
- package/dist/thread-head-ping.d.ts.map +0 -1
- package/dist/thread-head-ping.js +0 -67
- package/dist/thread-head-ping.js.map +0 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { ControlResource } from "@claudexor/schema";
|
|
3
|
+
import { hashJson, newId } from "@claudexor/util";
|
|
4
|
+
import { sha256Hex } from "./blob-files.js";
|
|
5
|
+
import { bindIdempotencyInTx } from "./idempotency.js";
|
|
6
|
+
import { runMutation } from "./mutation.js";
|
|
7
|
+
import { assertContentAllowed, putResourceInTx, putUploadInTx, readResourceRow, readUploadRow, resourceError, resourceSha, verifiedResourceBytes, } from "./resource-rows.js";
|
|
8
|
+
import { uploadKeyDigest } from "./upload-binding-retention.js";
|
|
9
|
+
/** One publication identity across tx1, link, tx2, restart and exact replay. */
|
|
10
|
+
export class PublishBlob {
|
|
11
|
+
store;
|
|
12
|
+
blobs;
|
|
13
|
+
obligations;
|
|
14
|
+
uploads;
|
|
15
|
+
defer;
|
|
16
|
+
constructor(store, blobs, obligations, uploads, defer) {
|
|
17
|
+
this.store = store;
|
|
18
|
+
this.blobs = blobs;
|
|
19
|
+
this.obligations = obligations;
|
|
20
|
+
this.uploads = uploads;
|
|
21
|
+
this.defer = defer;
|
|
22
|
+
obligations.registerHandler("publish_blob", (row, effects) => this.recover(row, effects));
|
|
23
|
+
}
|
|
24
|
+
finalize(id, expectedSha256, key) {
|
|
25
|
+
const requestDigest = hashJson({ uploadId: id, expectedSha256: expectedSha256 ?? null });
|
|
26
|
+
const prior = this.uploads.bindings.lookup("finalize", key, requestDigest, id);
|
|
27
|
+
if (prior) {
|
|
28
|
+
const row = readUploadRow(this.store, id);
|
|
29
|
+
if (row?.state === "finalizing")
|
|
30
|
+
this.complete(row);
|
|
31
|
+
return ControlResource.parse(prior.result);
|
|
32
|
+
}
|
|
33
|
+
const upload = this.uploads.get(id);
|
|
34
|
+
const keyDigest = uploadKeyDigest("finalize", key);
|
|
35
|
+
if (upload.finalization) {
|
|
36
|
+
if (upload.finalization.keyDigest !== keyDigest ||
|
|
37
|
+
upload.finalization.requestDigest !== requestDigest)
|
|
38
|
+
throw resourceError("idempotency key was already used with a different request", 409, "idempotency_conflict");
|
|
39
|
+
return this.complete(upload);
|
|
40
|
+
}
|
|
41
|
+
if (upload.status.state !== "uploaded")
|
|
42
|
+
throw resourceError(`upload ${id} is ${upload.status.state}`, 409, "upload_not_uploaded");
|
|
43
|
+
const bytes = readFileSync(this.uploads.partPath(id));
|
|
44
|
+
if (bytes.length !== upload.status.expectedBytes)
|
|
45
|
+
throw resourceError("uploaded file no longer matches declared size", 409, "upload_size_mismatch");
|
|
46
|
+
try {
|
|
47
|
+
assertContentAllowed(upload.request, bytes);
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
this.uploads.cancel(id);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
const sha = sha256Hex(bytes);
|
|
54
|
+
if (expectedSha256 !== undefined && expectedSha256 !== `sha256:${sha}`)
|
|
55
|
+
throw resourceError("uploaded byte digest does not match expectedSha256", 409, "digest_mismatch");
|
|
56
|
+
const resource = ControlResource.parse({
|
|
57
|
+
resourceId: newId("res"),
|
|
58
|
+
...(upload.request.purpose ? { purpose: upload.request.purpose } : {}),
|
|
59
|
+
kind: upload.request.kind,
|
|
60
|
+
mime: upload.request.mime,
|
|
61
|
+
name: upload.request.name,
|
|
62
|
+
sha256: `sha256:${sha}`,
|
|
63
|
+
sizeBytes: bytes.length,
|
|
64
|
+
createdAt: this.store.now().toISOString(),
|
|
65
|
+
deduplicated: existsSync(this.blobs.filePath(sha)),
|
|
66
|
+
});
|
|
67
|
+
upload.state = "finalizing";
|
|
68
|
+
upload.finalizeSha = sha;
|
|
69
|
+
upload.resourceId = resource.resourceId;
|
|
70
|
+
upload.finalization = { keyDigest, requestDigest, result: resource };
|
|
71
|
+
runMutation(this.store, (tx) => {
|
|
72
|
+
putUploadInTx(tx, upload);
|
|
73
|
+
putResourceInTx(tx, { resource, state: "publishing", expiresAt: null, releasedAt: null });
|
|
74
|
+
bindIdempotencyInTx(tx, {
|
|
75
|
+
owner: "upload",
|
|
76
|
+
pid: 0,
|
|
77
|
+
keyDigest,
|
|
78
|
+
operation: "finalize",
|
|
79
|
+
requestDigest,
|
|
80
|
+
targetId: id,
|
|
81
|
+
result: resource,
|
|
82
|
+
createdAt: tx.now().toISOString(),
|
|
83
|
+
});
|
|
84
|
+
this.obligations.create("publish_blob", id, 0, { sha, resource_id: resource.resourceId });
|
|
85
|
+
tx.changes.blobChanged(sha);
|
|
86
|
+
tx.changes.uploadChanged(id);
|
|
87
|
+
});
|
|
88
|
+
return this.complete(upload);
|
|
89
|
+
}
|
|
90
|
+
/** Called by the composition's single Obligations.onCleared hook, after its owner notification. */
|
|
91
|
+
onCleared(rows) {
|
|
92
|
+
for (const row of rows) {
|
|
93
|
+
if (row.kind !== "publish_blob")
|
|
94
|
+
continue;
|
|
95
|
+
this.uploads.cleanPart(row.key);
|
|
96
|
+
const { sha } = row.payload;
|
|
97
|
+
// Release may have happened while publication still owned this digest.
|
|
98
|
+
if (!this.blobs.owned(sha))
|
|
99
|
+
this.defer(this.blobs.gc(sha));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
complete(upload, effects) {
|
|
103
|
+
const resource = upload.finalization.result;
|
|
104
|
+
const row = readResourceRow(this.store, resource.resourceId);
|
|
105
|
+
if (!row)
|
|
106
|
+
throw resourceError(`no such resource: ${resource.resourceId}`, 404, "resource_not_found");
|
|
107
|
+
// Receipts survive byte release. Never link a released or expired resource again.
|
|
108
|
+
if (row.state === "released" || row.state === "expired") {
|
|
109
|
+
// Complete custody without republishing bytes. The new barrier covers
|
|
110
|
+
// release before the post-clear hook can remove the remaining part.
|
|
111
|
+
const generation = this.store.mark();
|
|
112
|
+
upload.state = "published";
|
|
113
|
+
runMutation(this.store, (tx) => {
|
|
114
|
+
putUploadInTx(tx, upload);
|
|
115
|
+
if (!effects)
|
|
116
|
+
this.obligations.materializeInTx(tx, "publish_blob", upload.status.uploadId, generation);
|
|
117
|
+
tx.changes.uploadChanged(upload.status.uploadId);
|
|
118
|
+
tx.changes.blobChanged(upload.finalizeSha);
|
|
119
|
+
});
|
|
120
|
+
return resource;
|
|
121
|
+
}
|
|
122
|
+
const sha = resourceSha(resource);
|
|
123
|
+
const path = this.blobs.filePath(sha);
|
|
124
|
+
const bytes = verifiedResourceBytes(resource, existsSync(path) ? path : this.uploads.partPath(upload.status.uploadId));
|
|
125
|
+
assertContentAllowed(resource, bytes);
|
|
126
|
+
const linked = this.blobs.publishLink(this.uploads.partPath(upload.status.uploadId), sha);
|
|
127
|
+
const generation = effects ? effects.register(this.blobs.dir) : linked.generation;
|
|
128
|
+
// The part stays through the durability barrier. Only the post-clear hook removes it.
|
|
129
|
+
upload.state = "published";
|
|
130
|
+
runMutation(this.store, (tx) => {
|
|
131
|
+
this.blobs.insertRow({
|
|
132
|
+
sha256: sha,
|
|
133
|
+
size: resource.sizeBytes,
|
|
134
|
+
inline: null,
|
|
135
|
+
file: path,
|
|
136
|
+
generation,
|
|
137
|
+
});
|
|
138
|
+
putResourceInTx(tx, { ...row, state: "ready" });
|
|
139
|
+
putUploadInTx(tx, upload);
|
|
140
|
+
if (!effects)
|
|
141
|
+
this.obligations.materializeInTx(tx, "publish_blob", upload.status.uploadId, generation);
|
|
142
|
+
tx.changes.blobChanged(sha);
|
|
143
|
+
tx.changes.uploadChanged(upload.status.uploadId);
|
|
144
|
+
});
|
|
145
|
+
return ControlResource.parse(resource);
|
|
146
|
+
}
|
|
147
|
+
recover(obligation, effects) {
|
|
148
|
+
const upload = readUploadRow(this.store, obligation.key);
|
|
149
|
+
if (!upload?.finalization)
|
|
150
|
+
throw new Error(`publication upload ${obligation.key} is unavailable`);
|
|
151
|
+
const { sha, resource_id } = obligation.payload;
|
|
152
|
+
if (resourceSha(upload.finalization.result) !== sha || upload.resourceId !== resource_id)
|
|
153
|
+
throw new Error(`publication binding mismatch for ${obligation.key}`);
|
|
154
|
+
// completeOpen owns rematerialization with this process's new registration.
|
|
155
|
+
this.complete(upload, effects);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=publish-blob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-blob.js","sourceRoot":"","sources":["../../src/store/publish-blob.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type Thread } from "@claudexor/schema";
|
|
2
|
+
import type { EngineStore } from "./store.js";
|
|
3
|
+
import type { Obligations, ObligationHandler } from "./obligations.js";
|
|
4
|
+
export interface PurgeFilesPayload {
|
|
5
|
+
thread: Thread;
|
|
6
|
+
}
|
|
7
|
+
/** Uses the CLI/workspace's existing purge owner; it reports touched parents. */
|
|
8
|
+
export type PurgeFilesEffect = (thread: Thread) => Promise<readonly string[]>;
|
|
9
|
+
/** SQL owns the decision and retry; the existing workspace owner owns deletion. */
|
|
10
|
+
export declare class SqlPurgeFiles {
|
|
11
|
+
readonly store: EngineStore;
|
|
12
|
+
readonly obligations: Obligations;
|
|
13
|
+
private readonly pending;
|
|
14
|
+
constructor(store: EngineStore, obligations: Obligations);
|
|
15
|
+
handler(perform: PurgeFilesEffect): ObligationHandler;
|
|
16
|
+
/** Runtime replay uses the same handler as startup, without replaying every
|
|
17
|
+
* open obligation or resetting another effect's materialized state. */
|
|
18
|
+
complete(id: string, perform: PurgeFilesEffect): Promise<void>;
|
|
19
|
+
private completeOne;
|
|
20
|
+
}
|
|
21
|
+
/** PR-D supplies already validated, engine-owned leftovers. Logical SQL
|
|
22
|
+
* archives have no fake filesystem move; only a real leftover creates this. */
|
|
23
|
+
export interface PartitionFilesPayload {
|
|
24
|
+
source: string;
|
|
25
|
+
destination: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function partitionFilesHandler(store: EngineStore): ObligationHandler;
|
|
28
|
+
/** Removed parents cannot be opened by the flusher; sync the surviving parent. */
|
|
29
|
+
export declare function existingDirectory(path: string): string;
|
|
30
|
+
//# sourceMappingURL=purge-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge-files.d.ts","sourceRoot":"","sources":["../../src/store/purge-files.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0B,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;AAE9E,mFAAmF;AACnF,qBAAa,aAAa;IAGtB,QAAQ,CAAC,KAAK,EAAE,WAAW;IAC3B,QAAQ,CAAC,WAAW,EAAE,WAAW;IAHnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,YACW,KAAK,EAAE,WAAW,EAClB,WAAW,EAAE,WAAW,EAC/B;IAEJ,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,iBAAiB,CAUpD;IAED;2EACuE;IACvE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAM7D;YAEa,WAAW;CA6B1B;AAED;+EAC+E;AAC/E,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAc3E;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { existsSync, renameSync, statSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { Thread as ThreadSchema } from "@claudexor/schema";
|
|
4
|
+
/** SQL owns the decision and retry; the existing workspace owner owns deletion. */
|
|
5
|
+
export class SqlPurgeFiles {
|
|
6
|
+
store;
|
|
7
|
+
obligations;
|
|
8
|
+
pending = new Map();
|
|
9
|
+
constructor(store, obligations) {
|
|
10
|
+
this.store = store;
|
|
11
|
+
this.obligations = obligations;
|
|
12
|
+
}
|
|
13
|
+
handler(perform) {
|
|
14
|
+
return async (obligation, effects) => {
|
|
15
|
+
const thread = ThreadSchema.parse(obligation.payload.thread);
|
|
16
|
+
if (thread.id !== obligation.key)
|
|
17
|
+
throw new Error("purge obligation does not name its thread");
|
|
18
|
+
// Covers the decision committed before this call, also after restart.
|
|
19
|
+
await this.store.synced(this.store.mark());
|
|
20
|
+
const dirs = await perform(thread);
|
|
21
|
+
for (const dir of new Set(dirs))
|
|
22
|
+
effects.register(dir);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** Runtime replay uses the same handler as startup, without replaying every
|
|
26
|
+
* open obligation or resetting another effect's materialized state. */
|
|
27
|
+
complete(id, perform) {
|
|
28
|
+
const existing = this.pending.get(id);
|
|
29
|
+
if (existing)
|
|
30
|
+
return existing;
|
|
31
|
+
const completion = this.completeOne(id, perform).finally(() => this.pending.delete(id));
|
|
32
|
+
this.pending.set(id, completion);
|
|
33
|
+
return completion;
|
|
34
|
+
}
|
|
35
|
+
async completeOne(id, perform) {
|
|
36
|
+
const row = this.store
|
|
37
|
+
.prepare("SELECT pid,payload,created_at,state,materialized_g FROM effect_obligation WHERE kind='purge_fs' AND key=?")
|
|
38
|
+
.get(id);
|
|
39
|
+
if (!row || row.state === "materialized")
|
|
40
|
+
return;
|
|
41
|
+
await this.handler(perform)({
|
|
42
|
+
kind: "purge_fs",
|
|
43
|
+
key: id,
|
|
44
|
+
pid: row.pid,
|
|
45
|
+
createdAt: row.created_at,
|
|
46
|
+
payload: JSON.parse(Buffer.from(row.payload).toString("utf8")),
|
|
47
|
+
state: row.state,
|
|
48
|
+
materializedGeneration: row.materialized_g,
|
|
49
|
+
}, { register: (dir) => this.obligations.registerEffect("purge_fs", id, dir) });
|
|
50
|
+
this.obligations.materialize("purge_fs", id);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function partitionFilesHandler(store) {
|
|
54
|
+
return async (obligation, effects) => {
|
|
55
|
+
const { source, destination } = obligation.payload;
|
|
56
|
+
if (typeof source !== "string" || typeof destination !== "string")
|
|
57
|
+
throw new Error("invalid partition filesystem obligation");
|
|
58
|
+
await store.synced(store.mark());
|
|
59
|
+
if (existsSync(source)) {
|
|
60
|
+
if (existsSync(destination))
|
|
61
|
+
throw new Error("partition archive destination already exists");
|
|
62
|
+
renameSync(source, destination);
|
|
63
|
+
}
|
|
64
|
+
else if (!existsSync(destination))
|
|
65
|
+
throw new Error("partition archive source and destination are missing");
|
|
66
|
+
effects.register(existingDirectory(dirname(source)));
|
|
67
|
+
effects.register(existingDirectory(dirname(destination)));
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Removed parents cannot be opened by the flusher; sync the surviving parent. */
|
|
71
|
+
export function existingDirectory(path) {
|
|
72
|
+
for (let current = path;; current = dirname(current)) {
|
|
73
|
+
if (existsSync(current) && statSync(current).isDirectory())
|
|
74
|
+
return current;
|
|
75
|
+
if (dirname(current) === current)
|
|
76
|
+
throw new Error(`no surviving parent directory of ${path}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=purge-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge-files.js","sourceRoot":"","sources":["../../src/store/purge-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ControlResource, ControlUploadCreateRequest, ControlUploadStatus, ModelPayloadRef } from "@claudexor/schema";
|
|
2
|
+
import { type SqlWriteContext } from "./mutation.js";
|
|
3
|
+
export type ResourceState = "publishing" | "ready" | "released" | "expired";
|
|
4
|
+
export interface ResourceRow {
|
|
5
|
+
resource: ControlResource;
|
|
6
|
+
state: ResourceState;
|
|
7
|
+
expiresAt: string | null;
|
|
8
|
+
releasedAt: string | null;
|
|
9
|
+
}
|
|
10
|
+
export interface UploadFinalization {
|
|
11
|
+
keyDigest: string;
|
|
12
|
+
requestDigest: string;
|
|
13
|
+
result: ControlResource;
|
|
14
|
+
}
|
|
15
|
+
export interface UploadRow {
|
|
16
|
+
request: ControlUploadCreateRequest;
|
|
17
|
+
status: ControlUploadStatus;
|
|
18
|
+
state: "open" | "uploaded" | "finalizing" | "published" | "discarded";
|
|
19
|
+
finalizeSha: string | null;
|
|
20
|
+
resourceId?: string;
|
|
21
|
+
finalization?: UploadFinalization;
|
|
22
|
+
}
|
|
23
|
+
type SqlReader = Pick<SqlWriteContext, "prepare">;
|
|
24
|
+
export declare function readResourceRow(sql: SqlReader, id: string): ResourceRow | undefined;
|
|
25
|
+
export declare function readUploadRow(sql: SqlReader, id: string): UploadRow | undefined;
|
|
26
|
+
/** Pure row reducer: the caller owns the transaction, files and live notifications. */
|
|
27
|
+
export declare function putResourceInTx(sql: SqlWriteContext, row: ResourceRow): void;
|
|
28
|
+
/** Also used by the importer; no EngineStore, COMMIT, files or workers are involved. */
|
|
29
|
+
export declare function putUploadInTx(sql: SqlWriteContext, row: UploadRow): void;
|
|
30
|
+
export declare function resourceError(message: string, status?: number, code?: string): Error;
|
|
31
|
+
export declare function assertResourceId(id: string): void;
|
|
32
|
+
export declare function resourceSha(resource: Pick<ControlResource, "sha256">): string;
|
|
33
|
+
export declare function payloadRef(resource: ControlResource): ModelPayloadRef;
|
|
34
|
+
export declare function sensitiveResourceError(): Error;
|
|
35
|
+
export declare function assertContentAllowed(resource: Pick<ControlResource, "purpose">, bytes: Uint8Array): void;
|
|
36
|
+
export declare function assertModelRef(resource: ControlResource, ref: ModelPayloadRef): void;
|
|
37
|
+
export declare function purposeMismatch(): Error;
|
|
38
|
+
export declare function verifiedResourceBytes(resource: ControlResource, path: string): Buffer;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=resource-rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-rows.d.ts","sourceRoot":"","sources":["../../src/store/resource-rows.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,0BAA0B,EAC1B,mBAAmB,EACnB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAEzE,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;AAC5E,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AACD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;CACzB;AACD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,0BAA0B,CAAC;IACpC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,WAAW,CAAC;IACtE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED,KAAK,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;AAClD,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAgBnF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CA4B/E;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAuB5E;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CAiBxE;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM,EAAE,IAAI,SAAmB,GAAG,KAAK,CAE3F;AACD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAGjD;AACD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,CAAC,GAAG,MAAM,CAI7E;AACD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,eAAe,CAMrE;AACD,wBAAgB,sBAAsB,IAAI,KAAK,CAM9C;AACD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,EAC1C,KAAK,EAAE,UAAU,GAChB,IAAI,CAMN;AACD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAQpF;AACD,wBAAgB,eAAe,IAAI,KAAK,CAMvC;AACD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAWrF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { ControlResource, ControlUploadCreateRequest, ControlUploadStatus, ModelPayloadRef, } from "@claudexor/schema";
|
|
3
|
+
import { sensitiveResourcePolicy } from "@claudexor/util";
|
|
4
|
+
import { sha256Hex } from "./blob-files.js";
|
|
5
|
+
import { requireTransaction } from "./mutation.js";
|
|
6
|
+
export function readResourceRow(sql, id) {
|
|
7
|
+
const row = sql
|
|
8
|
+
.prepare("SELECT state, expires_at, released_at, body FROM resource WHERE id = ?")
|
|
9
|
+
.get(id);
|
|
10
|
+
if (!row)
|
|
11
|
+
return undefined;
|
|
12
|
+
const resource = ControlResource.parse(JSON.parse(Buffer.from(row.body).toString("utf8")));
|
|
13
|
+
if (resource.resourceId !== id)
|
|
14
|
+
throw resourceError("resource identity mismatch", 409, "resource_digest_mismatch");
|
|
15
|
+
return { resource, state: row.state, expiresAt: row.expires_at, releasedAt: row.released_at };
|
|
16
|
+
}
|
|
17
|
+
export function readUploadRow(sql, id) {
|
|
18
|
+
const row = sql
|
|
19
|
+
.prepare("SELECT state, finalize_sha, received_bytes, expected_bytes, body FROM upload WHERE id = ?")
|
|
20
|
+
.get(id);
|
|
21
|
+
if (!row)
|
|
22
|
+
return undefined;
|
|
23
|
+
const body = JSON.parse(Buffer.from(row.body).toString("utf8"));
|
|
24
|
+
return {
|
|
25
|
+
...body,
|
|
26
|
+
request: ControlUploadCreateRequest.parse(body.request),
|
|
27
|
+
status: ControlUploadStatus.parse({
|
|
28
|
+
...body.status,
|
|
29
|
+
uploadId: id,
|
|
30
|
+
receivedBytes: Number(row.received_bytes),
|
|
31
|
+
expectedBytes: Number(row.expected_bytes),
|
|
32
|
+
}),
|
|
33
|
+
state: row.state,
|
|
34
|
+
finalizeSha: row.finalize_sha,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/** Pure row reducer: the caller owns the transaction, files and live notifications. */
|
|
38
|
+
export function putResourceInTx(sql, row) {
|
|
39
|
+
requireTransaction(sql);
|
|
40
|
+
const r = row.resource;
|
|
41
|
+
sql
|
|
42
|
+
.prepare(`INSERT INTO resource(id, purpose, kind, sha256, size_bytes, state, created_at, expires_at, released_at, body)
|
|
43
|
+
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
44
|
+
ON CONFLICT(id) DO UPDATE SET purpose=excluded.purpose, kind=excluded.kind, sha256=excluded.sha256,
|
|
45
|
+
size_bytes=excluded.size_bytes, state=excluded.state, created_at=excluded.created_at,
|
|
46
|
+
expires_at=excluded.expires_at, released_at=excluded.released_at, body=excluded.body`)
|
|
47
|
+
.run(r.resourceId, r.purpose ?? null, r.kind, resourceSha(r), r.sizeBytes, row.state, r.createdAt, row.expiresAt, row.releasedAt, Buffer.from(JSON.stringify(r)));
|
|
48
|
+
}
|
|
49
|
+
/** Also used by the importer; no EngineStore, COMMIT, files or workers are involved. */
|
|
50
|
+
export function putUploadInTx(sql, row) {
|
|
51
|
+
requireTransaction(sql);
|
|
52
|
+
const { state, finalizeSha, ...body } = row;
|
|
53
|
+
sql
|
|
54
|
+
.prepare(`INSERT INTO upload(id, state, received_bytes, expected_bytes, finalize_sha, body) VALUES(?, ?, ?, ?, ?, ?)
|
|
55
|
+
ON CONFLICT(id) DO UPDATE SET state=excluded.state, received_bytes=excluded.received_bytes,
|
|
56
|
+
expected_bytes=excluded.expected_bytes, finalize_sha=excluded.finalize_sha, body=excluded.body`)
|
|
57
|
+
.run(row.status.uploadId, state, row.status.receivedBytes, row.status.expectedBytes, finalizeSha, Buffer.from(JSON.stringify(body)));
|
|
58
|
+
}
|
|
59
|
+
export function resourceError(message, status = 400, code = "resource_error") {
|
|
60
|
+
return Object.assign(new Error(message), { status, code });
|
|
61
|
+
}
|
|
62
|
+
export function assertResourceId(id) {
|
|
63
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(id))
|
|
64
|
+
throw resourceError("invalid resource id", 400, "invalid_resource_id");
|
|
65
|
+
}
|
|
66
|
+
export function resourceSha(resource) {
|
|
67
|
+
if (!/^sha256:[a-f0-9]{64}$/.test(resource.sha256))
|
|
68
|
+
throw resourceError("invalid resource digest", 409, "resource_digest_mismatch");
|
|
69
|
+
return resource.sha256.slice(7);
|
|
70
|
+
}
|
|
71
|
+
export function payloadRef(resource) {
|
|
72
|
+
return ModelPayloadRef.parse({
|
|
73
|
+
resourceId: resource.resourceId,
|
|
74
|
+
sha256: resource.sha256,
|
|
75
|
+
sizeBytes: resource.sizeBytes,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
export function sensitiveResourceError() {
|
|
79
|
+
return resourceError("resource rejected by sensitive-resource policy", 422, "sensitive_resource_rejected");
|
|
80
|
+
}
|
|
81
|
+
export function assertContentAllowed(resource, bytes) {
|
|
82
|
+
if (resource.purpose !== "model" &&
|
|
83
|
+
sensitiveResourcePolicy.containsSensitiveContent(Buffer.from(bytes).toString("utf8")))
|
|
84
|
+
throw sensitiveResourceError();
|
|
85
|
+
}
|
|
86
|
+
export function assertModelRef(resource, ref) {
|
|
87
|
+
if (resource.purpose !== "model")
|
|
88
|
+
throw purposeMismatch();
|
|
89
|
+
if (resource.sha256 !== ref.sha256 || resource.sizeBytes !== ref.sizeBytes)
|
|
90
|
+
throw resourceError("model resource reference does not match finalized bytes", 409, "resource_digest_mismatch");
|
|
91
|
+
}
|
|
92
|
+
export function purposeMismatch() {
|
|
93
|
+
return resourceError("resource purpose does not match this operation", 409, "resource_purpose_mismatch");
|
|
94
|
+
}
|
|
95
|
+
export function verifiedResourceBytes(resource, path) {
|
|
96
|
+
if (!existsSync(path))
|
|
97
|
+
throw resourceError("resource blob is unavailable", 409, "resource_unavailable");
|
|
98
|
+
const bytes = readFileSync(path);
|
|
99
|
+
if (bytes.length !== resource.sizeBytes || sha256Hex(bytes) !== resourceSha(resource))
|
|
100
|
+
throw resourceError("resource blob no longer matches finalized bytes", 409, "resource_digest_mismatch");
|
|
101
|
+
return bytes;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=resource-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-rows.js","sourceRoot":"","sources":["../../src/store/resource-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Attachment, ModelPayloadRef, type ResourceAttachmentRef } from "@claudexor/schema";
|
|
2
|
+
import type { ResourceStorePort } from "../store-contracts.js";
|
|
3
|
+
import { BlobFiles } from "./blob-files.js";
|
|
4
|
+
import { Obligations, type ObligationRow } from "./obligations.js";
|
|
5
|
+
import type { EngineStore } from "./store.js";
|
|
6
|
+
/** Resource metadata and replay live in the one engine DB; only immutable bytes are files. */
|
|
7
|
+
export declare class SqlResourceStore implements ResourceStorePort {
|
|
8
|
+
private readonly store;
|
|
9
|
+
private readonly blobs;
|
|
10
|
+
private readonly log;
|
|
11
|
+
private readonly uploads;
|
|
12
|
+
private readonly publisher;
|
|
13
|
+
private readonly cleanup;
|
|
14
|
+
constructor(store: EngineStore, blobs: BlobFiles, obligations: Obligations, log?: (line: string) => void);
|
|
15
|
+
create(raw: unknown, key: string): {
|
|
16
|
+
uploadId: string;
|
|
17
|
+
state: "cancelled" | "open" | "uploaded" | "uploading";
|
|
18
|
+
receivedBytes: number;
|
|
19
|
+
expectedBytes: number;
|
|
20
|
+
};
|
|
21
|
+
status(id: string): {
|
|
22
|
+
uploadId: string;
|
|
23
|
+
state: "cancelled" | "open" | "uploaded" | "uploading";
|
|
24
|
+
receivedBytes: number;
|
|
25
|
+
expectedBytes: number;
|
|
26
|
+
};
|
|
27
|
+
write(id: string, chunks: AsyncIterable<Uint8Array>): Promise<{
|
|
28
|
+
uploadId: string;
|
|
29
|
+
state: "cancelled" | "open" | "uploaded" | "uploading";
|
|
30
|
+
receivedBytes: number;
|
|
31
|
+
expectedBytes: number;
|
|
32
|
+
}>;
|
|
33
|
+
cancel(id: string): {
|
|
34
|
+
uploadId: string;
|
|
35
|
+
state: "cancelled" | "open" | "uploaded" | "uploading";
|
|
36
|
+
receivedBytes: number;
|
|
37
|
+
expectedBytes: number;
|
|
38
|
+
};
|
|
39
|
+
finalize(id: string, expectedSha256: string | undefined, key: string): {
|
|
40
|
+
resourceId: string;
|
|
41
|
+
purpose?: "model" | undefined;
|
|
42
|
+
kind: "file" | "image";
|
|
43
|
+
mime: string;
|
|
44
|
+
name: string;
|
|
45
|
+
sha256: string;
|
|
46
|
+
sizeBytes: number;
|
|
47
|
+
createdAt: string;
|
|
48
|
+
deduplicated: boolean;
|
|
49
|
+
};
|
|
50
|
+
resolve(refs: ResourceAttachmentRef[] | undefined): Attachment[];
|
|
51
|
+
readModel(raw: ModelPayloadRef): Buffer;
|
|
52
|
+
publishModel(bytes: Uint8Array): ModelPayloadRef;
|
|
53
|
+
releaseModel(raw: ModelPayloadRef): void;
|
|
54
|
+
/** Expiry has an observed custody timestamp; callers must not infer it from file mtime. */
|
|
55
|
+
expireModel(raw: ModelPayloadRef, expiredAt: string): void;
|
|
56
|
+
listModelResources(): Array<ModelPayloadRef & {
|
|
57
|
+
createdAt: string;
|
|
58
|
+
}>;
|
|
59
|
+
pruneUploadBindings(): number;
|
|
60
|
+
onObligationsCleared(rows: readonly ObligationRow[]): void;
|
|
61
|
+
/** Await this before closing the store; failures are logged and the existing sweep retries residue. */
|
|
62
|
+
drainCleanup(): Promise<void>;
|
|
63
|
+
private release;
|
|
64
|
+
private metadata;
|
|
65
|
+
private defer;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/store/resources.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EAEV,eAAe,EACf,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAsC,MAAM,iBAAiB,CAAC;AAEhF,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAgBnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,8FAA8F;AAC9F,qBAAa,gBAAiB,YAAW,iBAAiB;IAMtD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IARtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IAEpD,YACmB,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,SAAS,EACjC,WAAW,EAAE,WAAW,EACP,GAAG,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAmB,EAM5D;IACD,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM;;;;;MAE/B;IACD,MAAM,CAAC,EAAE,EAAE,MAAM;;;;;MAEhB;IACD,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC;;;;;OAElD;IACD,MAAM,CAAC,EAAE,EAAE,MAAM;;;;;MAEhB;IACD,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM;;;;;;;;;;MAEnE;IAED,OAAO,CAAC,IAAI,EAAE,qBAAqB,EAAE,GAAG,SAAS,GAAG,UAAU,EAAE,CAmB/D;IAED,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAKtC;IACD,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,CAqB/C;IACD,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,CAEvC;IAED,2FAA2F;IAC3F,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAEzD;IAED,kBAAkB,IAAI,KAAK,CAAC,eAAe,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CASnE;IACD,mBAAmB,IAAI,MAAM,CAE5B;IACD,oBAAoB,CAAC,IAAI,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAEzD;IAED,uGAAuG;IACjG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAElC;IAED,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,KAAK;CAad"}
|