@tstdl/base 0.93.181 → 0.93.183
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/api/server/api-request-token.provider.js +1 -1
- package/api/server/gateway.js +8 -3
- package/authentication/authentication.api.d.ts +13 -40
- package/authentication/authentication.api.js +5 -14
- package/authentication/client/authentication.service.d.ts +6 -14
- package/authentication/client/authentication.service.js +22 -4
- package/authentication/client/module.d.ts +1 -1
- package/authentication/client/module.js +4 -4
- package/authentication/models/index.d.ts +1 -0
- package/authentication/models/index.js +1 -0
- package/authentication/models/totp-results.model.d.ts +11 -0
- package/authentication/models/totp-results.model.js +37 -0
- package/authentication/server/authentication.api-controller.d.ts +3 -3
- package/authentication/server/authentication.api-controller.js +31 -4
- package/authentication/server/authentication.service.d.ts +5 -14
- package/authentication/server/authentication.service.js +6 -4
- package/core.d.ts +0 -5
- package/core.js +0 -8
- package/document-management/api/document-management.api.d.ts +2 -2
- package/document-management/service-models/document.service-model.d.ts +1 -1
- package/examples/config.d.ts +25 -0
- package/examples/config.js +26 -0
- package/notification/server/module.d.ts +1 -1
- package/notification/server/module.js +1 -1
- package/package.json +5 -5
- package/signals/api.d.ts +5 -1
- package/signals/api.js +3 -1
- package/signals/implementation/api.d.ts +13 -5
- package/signals/implementation/api.js +7 -1
- package/signals/implementation/asserts.d.ts +2 -2
- package/signals/implementation/asserts.js +3 -3
- package/signals/implementation/computed.d.ts +7 -34
- package/signals/implementation/computed.js +14 -83
- package/signals/implementation/configure.js +6 -2
- package/signals/implementation/effect.d.ts +65 -46
- package/signals/implementation/effect.js +97 -62
- package/signals/implementation/index.d.ts +2 -4
- package/signals/implementation/index.js +2 -4
- package/signals/implementation/linked_signal.d.ts +36 -0
- package/signals/implementation/linked_signal.js +34 -0
- package/signals/implementation/primitive/computed.d.ts +55 -0
- package/signals/implementation/primitive/computed.js +107 -0
- package/signals/implementation/primitive/effect.d.ts +26 -0
- package/signals/implementation/primitive/effect.js +31 -0
- package/signals/implementation/{equality.d.ts → primitive/equality.d.ts} +1 -1
- package/signals/implementation/{equality.js → primitive/equality.js} +1 -1
- package/signals/implementation/primitive/errors.d.ts +10 -0
- package/signals/implementation/{errors.js → primitive/errors.js} +3 -4
- package/signals/implementation/primitive/formatter.d.ts +19 -0
- package/signals/implementation/primitive/formatter.js +136 -0
- package/signals/implementation/{graph.d.ts → primitive/graph.d.ts} +68 -36
- package/signals/implementation/primitive/graph.js +386 -0
- package/signals/implementation/primitive/linked_signal.d.ts +46 -0
- package/signals/implementation/primitive/linked_signal.js +110 -0
- package/signals/implementation/primitive/signal.d.ts +31 -0
- package/signals/implementation/primitive/signal.js +80 -0
- package/signals/implementation/primitive/untracked.d.ts +12 -0
- package/signals/implementation/primitive/untracked.js +23 -0
- package/signals/implementation/{watch.d.ts → primitive/watch.d.ts} +1 -2
- package/signals/implementation/{watch.js → primitive/watch.js} +22 -16
- package/signals/implementation/resource/api.d.ts +275 -0
- package/signals/implementation/resource/api.js +26 -0
- package/signals/implementation/resource/debounce.d.ts +13 -0
- package/signals/implementation/resource/debounce.js +113 -0
- package/signals/implementation/resource/from_snapshots.d.ts +16 -0
- package/signals/implementation/resource/from_snapshots.js +44 -0
- package/signals/implementation/resource/index.d.ts +11 -0
- package/signals/implementation/resource/index.js +11 -0
- package/signals/implementation/resource/resource.d.ts +110 -0
- package/signals/implementation/resource/resource.js +402 -0
- package/signals/implementation/root_effect_scheduler.d.ts +50 -0
- package/signals/implementation/root_effect_scheduler.js +66 -0
- package/signals/implementation/signal.d.ts +42 -18
- package/signals/implementation/signal.js +29 -49
- package/signals/implementation/to-observable.d.ts +12 -5
- package/signals/implementation/to-observable.js +12 -2
- package/signals/implementation/to-signal.d.ts +9 -18
- package/signals/implementation/to-signal.js +46 -13
- package/signals/implementation/untracked.d.ts +1 -1
- package/signals/implementation/untracked.js +3 -11
- package/signals/operators/debounce.d.ts +8 -0
- package/signals/operators/debounce.js +19 -0
- package/signals/operators/derive-async.js +43 -15
- package/signals/operators/index.d.ts +2 -0
- package/signals/operators/index.js +2 -0
- package/signals/operators/throttle.d.ts +8 -0
- package/signals/operators/throttle.js +31 -0
- package/ai/genkit/tests/multi-region.test.d.ts +0 -2
- package/ai/genkit/tests/multi-region.test.js +0 -179
- package/ai/genkit/tests/token-limit-fallback.test.d.ts +0 -2
- package/ai/genkit/tests/token-limit-fallback.test.js +0 -209
- package/ai/prompts/tests/prompt-builder.test.d.ts +0 -1
- package/ai/prompts/tests/prompt-builder.test.js +0 -22
- package/ai/tests/instructions-formatter.test.d.ts +0 -1
- package/ai/tests/instructions-formatter.test.js +0 -116
- package/ai/tests/steering.test.d.ts +0 -1
- package/ai/tests/steering.test.js +0 -37
- package/api/client/tests/api-client.test.d.ts +0 -1
- package/api/client/tests/api-client.test.js +0 -194
- package/api/server/tests/csrf.middleware.test.d.ts +0 -1
- package/api/server/tests/csrf.middleware.test.js +0 -91
- package/authentication/tests/authentication-password-requirements.validator.test.d.ts +0 -1
- package/authentication/tests/authentication-password-requirements.validator.test.js +0 -29
- package/authentication/tests/authentication.api-controller.test.d.ts +0 -1
- package/authentication/tests/authentication.api-controller.test.js +0 -156
- package/authentication/tests/authentication.api-request-token.provider.test.d.ts +0 -1
- package/authentication/tests/authentication.api-request-token.provider.test.js +0 -48
- package/authentication/tests/authentication.client-error-handling.test.d.ts +0 -1
- package/authentication/tests/authentication.client-error-handling.test.js +0 -123
- package/authentication/tests/authentication.client-middleware.test.d.ts +0 -1
- package/authentication/tests/authentication.client-middleware.test.js +0 -118
- package/authentication/tests/authentication.client-service-methods.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-methods.test.js +0 -177
- package/authentication/tests/authentication.client-service-refresh.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service-refresh.test.js +0 -153
- package/authentication/tests/authentication.client-service.test.d.ts +0 -1
- package/authentication/tests/authentication.client-service.test.js +0 -76
- package/authentication/tests/authentication.refresh-busy-loop.test.d.ts +0 -1
- package/authentication/tests/authentication.refresh-busy-loop.test.js +0 -84
- package/authentication/tests/authentication.service.test.d.ts +0 -1
- package/authentication/tests/authentication.service.test.js +0 -167
- package/authentication/tests/authentication.test-ancillary-service.d.ts +0 -9
- package/authentication/tests/authentication.test-ancillary-service.js +0 -27
- package/authentication/tests/brute-force-protection.test.d.ts +0 -1
- package/authentication/tests/brute-force-protection.test.js +0 -211
- package/authentication/tests/helper.test.d.ts +0 -1
- package/authentication/tests/helper.test.js +0 -122
- package/authentication/tests/password-requirements.error.test.d.ts +0 -1
- package/authentication/tests/password-requirements.error.test.js +0 -14
- package/authentication/tests/remember.api.test.d.ts +0 -1
- package/authentication/tests/remember.api.test.js +0 -117
- package/authentication/tests/remember.service.test.d.ts +0 -1
- package/authentication/tests/remember.service.test.js +0 -83
- package/authentication/tests/subject.service.test.d.ts +0 -1
- package/authentication/tests/subject.service.test.js +0 -140
- package/authentication/tests/suspended-subject.test.d.ts +0 -1
- package/authentication/tests/suspended-subject.test.js +0 -120
- package/authentication/tests/totp.enrollment.test.d.ts +0 -1
- package/authentication/tests/totp.enrollment.test.js +0 -123
- package/authentication/tests/totp.login.test.d.ts +0 -1
- package/authentication/tests/totp.login.test.js +0 -213
- package/authentication/tests/totp.recovery-codes.test.d.ts +0 -1
- package/authentication/tests/totp.recovery-codes.test.js +0 -97
- package/authentication/tests/totp.status.test.d.ts +0 -1
- package/authentication/tests/totp.status.test.js +0 -72
- package/cancellation/tests/coverage.test.d.ts +0 -1
- package/cancellation/tests/coverage.test.js +0 -49
- package/cancellation/tests/leak.test.d.ts +0 -1
- package/cancellation/tests/leak.test.js +0 -35
- package/cancellation/tests/token.test.d.ts +0 -1
- package/cancellation/tests/token.test.js +0 -136
- package/circuit-breaker/tests/circuit-breaker.test.d.ts +0 -1
- package/circuit-breaker/tests/circuit-breaker.test.js +0 -116
- package/cryptography/tests/cryptography.test.d.ts +0 -1
- package/cryptography/tests/cryptography.test.js +0 -175
- package/cryptography/tests/jwt.test.d.ts +0 -1
- package/cryptography/tests/jwt.test.js +0 -54
- package/cryptography/tests/modern.test.d.ts +0 -1
- package/cryptography/tests/modern.test.js +0 -105
- package/cryptography/tests/module.test.d.ts +0 -1
- package/cryptography/tests/module.test.js +0 -100
- package/cryptography/tests/totp.test.d.ts +0 -1
- package/cryptography/tests/totp.test.js +0 -108
- package/document-management/tests/ai-config-hierarchy.test.d.ts +0 -1
- package/document-management/tests/ai-config-hierarchy.test.js +0 -59
- package/document-management/tests/ai-config-integration.test.d.ts +0 -1
- package/document-management/tests/ai-config-integration.test.js +0 -125
- package/document-management/tests/ai-config-merge.test.d.ts +0 -1
- package/document-management/tests/ai-config-merge.test.js +0 -46
- package/document-management/tests/document-management-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-management-ai-overrides.test.js +0 -63
- package/document-management/tests/document-management-core.test.d.ts +0 -1
- package/document-management/tests/document-management-core.test.js +0 -157
- package/document-management/tests/document-management.api.test.d.ts +0 -1
- package/document-management/tests/document-management.api.test.js +0 -101
- package/document-management/tests/document-statistics.service.test.d.ts +0 -1
- package/document-management/tests/document-statistics.service.test.js +0 -498
- package/document-management/tests/document-validation-ai-overrides.test.d.ts +0 -1
- package/document-management/tests/document-validation-ai-overrides.test.js +0 -87
- package/document-management/tests/document.service.test.d.ts +0 -1
- package/document-management/tests/document.service.test.js +0 -143
- package/document-management/tests/enum-helpers.test.d.ts +0 -1
- package/document-management/tests/enum-helpers.test.js +0 -452
- package/document-management/tests/helper.d.ts +0 -24
- package/document-management/tests/helper.js +0 -39
- package/errors/tests/format.test.d.ts +0 -1
- package/errors/tests/format.test.js +0 -84
- package/http/tests/server-timing.test.d.ts +0 -1
- package/http/tests/server-timing.test.js +0 -42
- package/injector/tests/advanced.test.d.ts +0 -1
- package/injector/tests/advanced.test.js +0 -116
- package/injector/tests/async-init.test.d.ts +0 -1
- package/injector/tests/async-init.test.js +0 -77
- package/injector/tests/basic.test.d.ts +0 -1
- package/injector/tests/basic.test.js +0 -114
- package/injector/tests/hierarchical.test.d.ts +0 -1
- package/injector/tests/hierarchical.test.js +0 -59
- package/injector/tests/leak.test.d.ts +0 -1
- package/injector/tests/leak.test.js +0 -45
- package/injector/tests/lifecycles.test.d.ts +0 -1
- package/injector/tests/lifecycles.test.js +0 -109
- package/logger/tests/pretty-print.test.d.ts +0 -1
- package/logger/tests/pretty-print.test.js +0 -60
- package/notification/tests/notification-api.test.d.ts +0 -1
- package/notification/tests/notification-api.test.js +0 -124
- package/notification/tests/notification-client.test.d.ts +0 -1
- package/notification/tests/notification-client.test.js +0 -101
- package/notification/tests/notification-flow.test.d.ts +0 -1
- package/notification/tests/notification-flow.test.js +0 -296
- package/notification/tests/notification-sse.service.test.d.ts +0 -1
- package/notification/tests/notification-sse.service.test.js +0 -43
- package/notification/tests/notification-type.service.test.d.ts +0 -1
- package/notification/tests/notification-type.service.test.js +0 -41
- package/object-storage/s3/tests/s3.object-storage.integration.test.d.ts +0 -1
- package/object-storage/s3/tests/s3.object-storage.integration.test.js +0 -303
- package/orm/tests/build-jsonb.test.d.ts +0 -1
- package/orm/tests/build-jsonb.test.js +0 -39
- package/orm/tests/data-types.test.d.ts +0 -1
- package/orm/tests/data-types.test.js +0 -39
- package/orm/tests/database-extension.test.d.ts +0 -1
- package/orm/tests/database-extension.test.js +0 -63
- package/orm/tests/database-migration.test.d.ts +0 -1
- package/orm/tests/database-migration.test.js +0 -83
- package/orm/tests/decorators.test.d.ts +0 -1
- package/orm/tests/decorators.test.js +0 -77
- package/orm/tests/encryption.test.d.ts +0 -1
- package/orm/tests/encryption.test.js +0 -31
- package/orm/tests/query-complex.test.d.ts +0 -1
- package/orm/tests/query-complex.test.js +0 -172
- package/orm/tests/query-converter-complex.test.d.ts +0 -1
- package/orm/tests/query-converter-complex.test.js +0 -131
- package/orm/tests/query-converter.test.d.ts +0 -1
- package/orm/tests/query-converter.test.js +0 -123
- package/orm/tests/repository-advanced.test.d.ts +0 -1
- package/orm/tests/repository-advanced.test.js +0 -189
- package/orm/tests/repository-attributes.test.d.ts +0 -1
- package/orm/tests/repository-attributes.test.js +0 -83
- package/orm/tests/repository-compound-primary-key.test.d.ts +0 -2
- package/orm/tests/repository-compound-primary-key.test.js +0 -226
- package/orm/tests/repository-comprehensive.test.d.ts +0 -1
- package/orm/tests/repository-comprehensive.test.js +0 -162
- package/orm/tests/repository-coverage.test.d.ts +0 -2
- package/orm/tests/repository-coverage.test.js +0 -242
- package/orm/tests/repository-cti-complex.test.d.ts +0 -1
- package/orm/tests/repository-cti-complex.test.js +0 -151
- package/orm/tests/repository-cti-embedded.test.d.ts +0 -1
- package/orm/tests/repository-cti-embedded.test.js +0 -178
- package/orm/tests/repository-cti-extensive.test.d.ts +0 -2
- package/orm/tests/repository-cti-extensive.test.js +0 -279
- package/orm/tests/repository-cti-mapping.test.d.ts +0 -2
- package/orm/tests/repository-cti-mapping.test.js +0 -108
- package/orm/tests/repository-cti-search.test.d.ts +0 -1
- package/orm/tests/repository-cti-search.test.js +0 -141
- package/orm/tests/repository-cti-soft-delete.test.d.ts +0 -2
- package/orm/tests/repository-cti-soft-delete.test.js +0 -103
- package/orm/tests/repository-cti-transactions.test.d.ts +0 -1
- package/orm/tests/repository-cti-transactions.test.js +0 -112
- package/orm/tests/repository-cti-upsert-many.test.d.ts +0 -2
- package/orm/tests/repository-cti-upsert-many.test.js +0 -115
- package/orm/tests/repository-cti.test.d.ts +0 -2
- package/orm/tests/repository-cti.test.js +0 -390
- package/orm/tests/repository-edge-cases.test.d.ts +0 -1
- package/orm/tests/repository-edge-cases.test.js +0 -178
- package/orm/tests/repository-expiration.test.d.ts +0 -2
- package/orm/tests/repository-expiration.test.js +0 -140
- package/orm/tests/repository-extra-coverage.test.d.ts +0 -2
- package/orm/tests/repository-extra-coverage.test.js +0 -402
- package/orm/tests/repository-mapping.test.d.ts +0 -2
- package/orm/tests/repository-mapping.test.js +0 -65
- package/orm/tests/repository-regression.test.d.ts +0 -1
- package/orm/tests/repository-regression.test.js +0 -288
- package/orm/tests/repository-search-coverage.test.d.ts +0 -1
- package/orm/tests/repository-search-coverage.test.js +0 -107
- package/orm/tests/repository-search.test.d.ts +0 -1
- package/orm/tests/repository-search.test.js +0 -105
- package/orm/tests/repository-soft-delete.test.d.ts +0 -1
- package/orm/tests/repository-soft-delete.test.js +0 -118
- package/orm/tests/repository-transactions-nested.test.d.ts +0 -1
- package/orm/tests/repository-transactions-nested.test.js +0 -178
- package/orm/tests/repository-types.test.d.ts +0 -1
- package/orm/tests/repository-types.test.js +0 -184
- package/orm/tests/repository-undelete.test.d.ts +0 -2
- package/orm/tests/repository-undelete.test.js +0 -201
- package/orm/tests/schema-converter.test.d.ts +0 -1
- package/orm/tests/schema-converter.test.js +0 -82
- package/orm/tests/schema-generation.test.d.ts +0 -2
- package/orm/tests/schema-generation.test.js +0 -174
- package/orm/tests/sql-helpers.test.d.ts +0 -1
- package/orm/tests/sql-helpers.test.js +0 -67
- package/orm/tests/transaction-safety.test.d.ts +0 -1
- package/orm/tests/transaction-safety.test.js +0 -81
- package/orm/tests/transactional.test.d.ts +0 -1
- package/orm/tests/transactional.test.js +0 -215
- package/orm/tests/utils.test.d.ts +0 -1
- package/orm/tests/utils.test.js +0 -70
- package/pdf/tests/utils.test.d.ts +0 -1
- package/pdf/tests/utils.test.js +0 -187
- package/process/tests/spawn.test.d.ts +0 -1
- package/process/tests/spawn.test.js +0 -182
- package/rate-limit/tests/postgres-rate-limiter.test.d.ts +0 -1
- package/rate-limit/tests/postgres-rate-limiter.test.js +0 -84
- package/renderer/tests/renderer.test.d.ts +0 -1
- package/renderer/tests/renderer.test.js +0 -88
- package/rpc/tests/rpc.integration.test.d.ts +0 -1
- package/rpc/tests/rpc.integration.test.js +0 -615
- package/signals/implementation/errors.d.ts +0 -2
- package/signals/implementation/graph.js +0 -312
- package/signals/implementation/writable-signal.d.ts +0 -48
- package/signals/implementation/writable-signal.js +0 -32
- package/task-queue/tests/coverage-branch.test.d.ts +0 -1
- package/task-queue/tests/coverage-branch.test.js +0 -395
- package/task-queue/tests/coverage-enhancement.test.d.ts +0 -1
- package/task-queue/tests/coverage-enhancement.test.js +0 -150
- package/task-queue/tests/dag.test.d.ts +0 -1
- package/task-queue/tests/dag.test.js +0 -188
- package/task-queue/tests/dependencies.test.d.ts +0 -1
- package/task-queue/tests/dependencies.test.js +0 -296
- package/task-queue/tests/enqueue-batch.test.d.ts +0 -1
- package/task-queue/tests/enqueue-batch.test.js +0 -125
- package/task-queue/tests/enqueue-item.test.d.ts +0 -1
- package/task-queue/tests/enqueue-item.test.js +0 -12
- package/task-queue/tests/fan-out-spawning.test.d.ts +0 -1
- package/task-queue/tests/fan-out-spawning.test.js +0 -94
- package/task-queue/tests/idempotent-replacement.test.d.ts +0 -1
- package/task-queue/tests/idempotent-replacement.test.js +0 -114
- package/task-queue/tests/missing-idempotent-tasks.test.d.ts +0 -1
- package/task-queue/tests/missing-idempotent-tasks.test.js +0 -39
- package/task-queue/tests/optimization-edge-cases.test.d.ts +0 -1
- package/task-queue/tests/optimization-edge-cases.test.js +0 -124
- package/task-queue/tests/queue-generic.test.d.ts +0 -1
- package/task-queue/tests/queue-generic.test.js +0 -8
- package/task-queue/tests/queue.test.d.ts +0 -1
- package/task-queue/tests/queue.test.js +0 -756
- package/task-queue/tests/shutdown.test.d.ts +0 -1
- package/task-queue/tests/shutdown.test.js +0 -41
- package/task-queue/tests/task-context.test.d.ts +0 -1
- package/task-queue/tests/task-context.test.js +0 -7
- package/task-queue/tests/task-union.test.d.ts +0 -1
- package/task-queue/tests/task-union.test.js +0 -18
- package/task-queue/tests/transactions.test.d.ts +0 -1
- package/task-queue/tests/transactions.test.js +0 -47
- package/task-queue/tests/typing.test.d.ts +0 -1
- package/task-queue/tests/typing.test.js +0 -9
- package/task-queue/tests/worker.test.d.ts +0 -1
- package/task-queue/tests/worker.test.js +0 -258
- package/task-queue/tests/zombie-parent.test.d.ts +0 -1
- package/task-queue/tests/zombie-parent.test.js +0 -45
- package/task-queue/tests/zombie-recovery.test.d.ts +0 -1
- package/task-queue/tests/zombie-recovery.test.js +0 -51
- package/utils/tests/backoff.test.d.ts +0 -1
- package/utils/tests/backoff.test.js +0 -41
- package/utils/tests/retry-with-backoff.test.d.ts +0 -1
- package/utils/tests/retry-with-backoff.test.js +0 -49
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { Database } from '../../orm/server/index.js';
|
|
3
|
-
import { TaskQueueProvider, TaskStatus } from '../../task-queue/index.js';
|
|
4
|
-
import { task as taskTable } from '../../task-queue/postgres/schemas.js';
|
|
5
|
-
import { setupIntegrationTest } from '../../testing/index.js';
|
|
6
|
-
import { currentTimestamp } from '../../utils/date-time.js';
|
|
7
|
-
import { eq } from 'drizzle-orm';
|
|
8
|
-
describe('Fan-Out Spawning', () => {
|
|
9
|
-
let injector;
|
|
10
|
-
let queue;
|
|
11
|
-
let database;
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
({ injector } = await setupIntegrationTest({ modules: { taskQueue: true } }));
|
|
14
|
-
database = injector.resolve(Database);
|
|
15
|
-
});
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
const queueProvider = injector.resolve(TaskQueueProvider);
|
|
18
|
-
const queueName = `fan-out-queue-${crypto.randomUUID()}`;
|
|
19
|
-
queue = queueProvider.get(queueName, {
|
|
20
|
-
visibilityTimeout: 1000,
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
afterEach(async () => {
|
|
24
|
-
await queue.clear();
|
|
25
|
-
});
|
|
26
|
-
afterAll(async () => {
|
|
27
|
-
await injector?.dispose();
|
|
28
|
-
});
|
|
29
|
-
it('should transition parent to Waiting when spawning children during execution', async () => {
|
|
30
|
-
const parent = await queue.enqueue('parent', {});
|
|
31
|
-
const dParent = await queue.dequeue();
|
|
32
|
-
expect(dParent?.id).toBe(parent.id);
|
|
33
|
-
// Parent spawns a child
|
|
34
|
-
const [child] = await queue.enqueueMany([{ type: 'child', data: {}, parentId: parent.id }], { returnTasks: true });
|
|
35
|
-
// Complete parent
|
|
36
|
-
await queue.complete(dParent);
|
|
37
|
-
// Parent should be Waiting for child
|
|
38
|
-
const uParent = await queue.getTask(parent.id);
|
|
39
|
-
expect(uParent?.status).toBe(TaskStatus.WaitingChildren);
|
|
40
|
-
expect(uParent?.unresolvedCompleteDependencies).toBe(1);
|
|
41
|
-
// Complete child
|
|
42
|
-
const dChild = await queue.dequeue();
|
|
43
|
-
await queue.complete(dChild);
|
|
44
|
-
// Parent should now be Completed
|
|
45
|
-
const fParent = await queue.getTask(parent.id);
|
|
46
|
-
expect(fParent?.status).toBe(TaskStatus.Completed);
|
|
47
|
-
});
|
|
48
|
-
it('should NOT transition parent to Waiting if parentRequires is false', async () => {
|
|
49
|
-
const parent = await queue.enqueue('parent', {});
|
|
50
|
-
const dParent = await queue.dequeue();
|
|
51
|
-
// Spawn child with parentRequires: false
|
|
52
|
-
await queue.enqueueMany([{ type: 'child', data: {}, parentId: parent.id, parentRequires: false }], { returnTasks: true });
|
|
53
|
-
await queue.complete(dParent);
|
|
54
|
-
const uParent = await queue.getTask(parent.id);
|
|
55
|
-
expect(uParent?.status).toBe(TaskStatus.Completed); // Finished immediately
|
|
56
|
-
expect(uParent?.unresolvedCompleteDependencies).toBe(0);
|
|
57
|
-
});
|
|
58
|
-
it('should transition parent from WaitingChildren to Completed exactly when the last child finishes', async () => {
|
|
59
|
-
const parent = await queue.enqueue('parent', {});
|
|
60
|
-
const c1 = await queue.enqueue('child', { val: 1 }, { parentId: parent.id });
|
|
61
|
-
const c2 = await queue.enqueue('child', { val: 2 }, { parentId: parent.id });
|
|
62
|
-
const dp = await queue.dequeue();
|
|
63
|
-
await queue.complete(dp);
|
|
64
|
-
const up1 = await queue.getTask(parent.id);
|
|
65
|
-
expect(up1?.status).toBe(TaskStatus.WaitingChildren);
|
|
66
|
-
const dc1 = await queue.dequeue();
|
|
67
|
-
await queue.complete(dc1);
|
|
68
|
-
const up2 = await queue.getTask(parent.id);
|
|
69
|
-
expect(up2?.status).toBe(TaskStatus.WaitingChildren);
|
|
70
|
-
const dc2 = await queue.dequeue();
|
|
71
|
-
await queue.complete(dc2);
|
|
72
|
-
const up3 = await queue.getTask(parent.id);
|
|
73
|
-
expect(up3?.status).toBe(TaskStatus.Completed);
|
|
74
|
-
});
|
|
75
|
-
it('should protect parent tasks from archival if orphaned child tasks still exist', async () => {
|
|
76
|
-
const queueProvider = injector.resolve(TaskQueueProvider);
|
|
77
|
-
const ephemeralQueue = queueProvider.get(`ephemeral-${crypto.randomUUID()}`, { retention: 0 });
|
|
78
|
-
const parent = await ephemeralQueue.enqueue('parent', {});
|
|
79
|
-
await ephemeralQueue.enqueue('child', {}, { parentId: parent.id });
|
|
80
|
-
// Manually complete parent while child is still pending
|
|
81
|
-
await database
|
|
82
|
-
.update(taskTable)
|
|
83
|
-
.set({
|
|
84
|
-
status: TaskStatus.Completed,
|
|
85
|
-
completeTimestamp: currentTimestamp() - 1000,
|
|
86
|
-
})
|
|
87
|
-
.where(eq(taskTable.id, parent.id));
|
|
88
|
-
await ephemeralQueue.maintenance();
|
|
89
|
-
const updatedParent = await ephemeralQueue.getTask(parent.id);
|
|
90
|
-
expect(updatedParent).toBeDefined(); // Should still be in main table
|
|
91
|
-
expect(updatedParent?.status).toBe(TaskStatus.Completed);
|
|
92
|
-
await ephemeralQueue.clear();
|
|
93
|
-
});
|
|
94
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { eq } from 'drizzle-orm';
|
|
2
|
-
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
3
|
-
import { Database } from '../../orm/server/index.js';
|
|
4
|
-
import { TaskQueueProvider, TaskStatus } from '../../task-queue/index.js';
|
|
5
|
-
import { taskDependency as taskDependencyTable } from '../../task-queue/postgres/schemas.js';
|
|
6
|
-
import { setupIntegrationTest } from '../../testing/index.js';
|
|
7
|
-
import { timeout } from '../../utils/timing.js';
|
|
8
|
-
describe('Idempotent Replacement', () => {
|
|
9
|
-
let injector;
|
|
10
|
-
let queue;
|
|
11
|
-
let database;
|
|
12
|
-
beforeAll(async () => {
|
|
13
|
-
({ injector } = await setupIntegrationTest({ modules: { taskQueue: true } }));
|
|
14
|
-
database = injector.resolve(Database);
|
|
15
|
-
});
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
const queueProvider = injector.resolve(TaskQueueProvider);
|
|
18
|
-
const queueName = `idempotent-queue-${crypto.randomUUID()}`;
|
|
19
|
-
queue = queueProvider.get(queueName, {
|
|
20
|
-
visibilityTimeout: 1000,
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
afterEach(async () => {
|
|
24
|
-
await queue.clear();
|
|
25
|
-
});
|
|
26
|
-
afterAll(async () => {
|
|
27
|
-
await injector?.dispose();
|
|
28
|
-
});
|
|
29
|
-
it('should NOT be affected by "ghost" dependencies after replacement', async () => {
|
|
30
|
-
const depA = await queue.enqueue('depA', {});
|
|
31
|
-
const depB = await queue.enqueue('depB', {});
|
|
32
|
-
const depC = await queue.enqueue('depC', {});
|
|
33
|
-
const idempotencyKey = 'my-idempotent-task';
|
|
34
|
-
// 1. Initial enqueue with A and B
|
|
35
|
-
const taskV1 = await queue.enqueue('main', { version: 1 }, {
|
|
36
|
-
idempotencyKey,
|
|
37
|
-
scheduleAfter: [depA.id, depB.id],
|
|
38
|
-
});
|
|
39
|
-
expect(taskV1.status).toBe(TaskStatus.Waiting);
|
|
40
|
-
expect(taskV1.unresolvedScheduleDependencies).toBe(2);
|
|
41
|
-
// 2. Replacement enqueue with only C
|
|
42
|
-
const taskV2 = await queue.enqueue('main', { version: 2 }, {
|
|
43
|
-
idempotencyKey,
|
|
44
|
-
scheduleAfter: [depC.id],
|
|
45
|
-
replace: true,
|
|
46
|
-
});
|
|
47
|
-
expect(taskV2.id).toBe(taskV1.id);
|
|
48
|
-
expect(taskV2.unresolvedScheduleDependencies).toBe(1);
|
|
49
|
-
expect(taskV2.data).toEqual({ version: 2 });
|
|
50
|
-
// 3. Complete an OLD dependency (depA)
|
|
51
|
-
const dDepA = await queue.dequeue({ types: ['depA'] });
|
|
52
|
-
await queue.complete(dDepA);
|
|
53
|
-
// Give it a moment to process background dependency resolution if any
|
|
54
|
-
await timeout(100);
|
|
55
|
-
// 4. Verify main task is STILL waiting for depC
|
|
56
|
-
const uTask = await queue.getTask(taskV1.id);
|
|
57
|
-
expect(uTask?.status).toBe(TaskStatus.Waiting);
|
|
58
|
-
expect(uTask?.unresolvedScheduleDependencies).toBe(1);
|
|
59
|
-
// 5. Complete NEW dependency (depC)
|
|
60
|
-
const dDepC = await queue.dequeue({ types: ['depC'] });
|
|
61
|
-
await queue.complete(dDepC);
|
|
62
|
-
// 6. Verify main task is now Pending
|
|
63
|
-
const fTask = await queue.getTask(taskV1.id);
|
|
64
|
-
expect(fTask?.status).toBe(TaskStatus.Pending);
|
|
65
|
-
});
|
|
66
|
-
it('should update parentId on replacement', async () => {
|
|
67
|
-
const parent1 = await queue.enqueue('parent', { id: 1 });
|
|
68
|
-
const parent2 = await queue.enqueue('parent', { id: 2 });
|
|
69
|
-
const idempotencyKey = 'task-1';
|
|
70
|
-
const taskV1 = await queue.enqueue('child', {}, { idempotencyKey, parentId: parent1.id });
|
|
71
|
-
expect(taskV1.parentId).toBe(parent1.id);
|
|
72
|
-
// Replace with new parent
|
|
73
|
-
const taskV2 = await queue.enqueue('child', {}, { idempotencyKey, parentId: parent2.id, replace: true });
|
|
74
|
-
expect(taskV2.id).toBe(taskV1.id);
|
|
75
|
-
expect(taskV2.parentId).toBe(parent2.id);
|
|
76
|
-
});
|
|
77
|
-
it('should NOT corrupt state on idempotent enqueues (replace: false)', async () => {
|
|
78
|
-
const dep = await queue.enqueue('dep', {});
|
|
79
|
-
const idempotencyKey = 'task-2';
|
|
80
|
-
// Initial enqueue without dependency
|
|
81
|
-
const taskV1 = await queue.enqueue('main', {}, { idempotencyKey });
|
|
82
|
-
expect(taskV1.status).toBe(TaskStatus.Pending);
|
|
83
|
-
// Deduplicated enqueue with dependency
|
|
84
|
-
const taskV2 = await queue.enqueue('main', {}, { idempotencyKey, scheduleAfter: [dep.id], replace: false });
|
|
85
|
-
expect(taskV2.id).toBe(taskV1.id);
|
|
86
|
-
const task = await queue.getTask(taskV2.id);
|
|
87
|
-
expect(task?.status).toBe(TaskStatus.Pending);
|
|
88
|
-
expect(task?.unresolvedScheduleDependencies).toBe(0);
|
|
89
|
-
});
|
|
90
|
-
it('should NOT orphan children on task replacement', async () => {
|
|
91
|
-
const idempotencyKey = 'parent-task';
|
|
92
|
-
const parent = await queue.enqueue('parent', {}, { idempotencyKey });
|
|
93
|
-
// Enqueue child
|
|
94
|
-
await queue.enqueue('child', {}, { parentId: parent.id });
|
|
95
|
-
const parentAfterChild = await queue.getTask(parent.id);
|
|
96
|
-
expect(parentAfterChild?.unresolvedCompleteDependencies).toBe(1);
|
|
97
|
-
// Replace parent
|
|
98
|
-
const replacedParent = await queue.enqueue('parent', { replaced: true }, { idempotencyKey, replace: true });
|
|
99
|
-
expect(replacedParent.unresolvedCompleteDependencies).toBe(1);
|
|
100
|
-
});
|
|
101
|
-
it('should clear and recreate dependencies when enqueuing existing tasks with replace: true', async () => {
|
|
102
|
-
const dep1 = await queue.enqueue('test', { value: 'dep1' });
|
|
103
|
-
const dep2 = await queue.enqueue('test', { value: 'dep2' });
|
|
104
|
-
const task = await queue.enqueue('test', { value: 'main' }, { idempotencyKey: 'main-key', scheduleAfter: [dep1.id] });
|
|
105
|
-
// Re-enqueue with replace: true and different dependency
|
|
106
|
-
await queue.enqueue('test', { value: 'main-replaced' }, { idempotencyKey: 'main-key', replace: true, scheduleAfter: [dep2.id] });
|
|
107
|
-
const deps = await database
|
|
108
|
-
.select()
|
|
109
|
-
.from(taskDependencyTable)
|
|
110
|
-
.where(eq(taskDependencyTable.taskId, task.id));
|
|
111
|
-
expect(deps).toHaveLength(1);
|
|
112
|
-
expect(deps[0].dependencyTaskId).toBe(dep2.id);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest';
|
|
2
|
-
import { TaskQueueProvider, TaskStatus } from '../../task-queue/index.js';
|
|
3
|
-
import { setupIntegrationTest } from '../../testing/index.js';
|
|
4
|
-
describe('Missing Idempotent Tasks Bug', () => {
|
|
5
|
-
let injector;
|
|
6
|
-
let queue;
|
|
7
|
-
beforeAll(async () => {
|
|
8
|
-
({ injector } = await setupIntegrationTest({ modules: { taskQueue: true } }));
|
|
9
|
-
});
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
const queueProvider = injector.resolve(TaskQueueProvider);
|
|
12
|
-
const queueName = `missing-idem-queue-${crypto.randomUUID()}`;
|
|
13
|
-
queue = queueProvider.get(queueName, {
|
|
14
|
-
visibilityTimeout: 1000,
|
|
15
|
-
});
|
|
16
|
-
});
|
|
17
|
-
afterEach(async () => {
|
|
18
|
-
await queue.clear();
|
|
19
|
-
});
|
|
20
|
-
afterAll(async () => {
|
|
21
|
-
await injector?.dispose();
|
|
22
|
-
});
|
|
23
|
-
it('should NOT crash when enqueuing duplicate idempotent tasks with dependencies and returnTasks: false', async () => {
|
|
24
|
-
const key = 'idem-key';
|
|
25
|
-
const dep = await queue.enqueue('dep', {});
|
|
26
|
-
// 1. Initial enqueue
|
|
27
|
-
const task1 = await queue.enqueue('main', {}, { idempotencyKey: key });
|
|
28
|
-
// 2. Second enqueue with same key and a dependency, returnTasks: false
|
|
29
|
-
// This should NOT crash.
|
|
30
|
-
// replace=false means we should ignore the new data AND the new dependency for the existing task.
|
|
31
|
-
await expect(queue.enqueueMany([
|
|
32
|
-
{ type: 'main', data: { new: 'data' }, idempotencyKey: key, scheduleAfter: [dep.id] }
|
|
33
|
-
], { replace: false, returnTasks: false })).resolves.toBeUndefined();
|
|
34
|
-
const updatedTask = await queue.getTask(task1.id);
|
|
35
|
-
expect(updatedTask?.data).toEqual({}); // Data should not have changed
|
|
36
|
-
expect(updatedTask?.unresolvedScheduleDependencies).toBe(0); // Dependency should not have been added
|
|
37
|
-
expect(updatedTask?.status).toBe(TaskStatus.Pending); // Should still be Pending, not Waiting
|
|
38
|
-
});
|
|
39
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { and, eq, sql } from 'drizzle-orm';
|
|
2
|
-
import { describe, expect, vi } from 'vitest';
|
|
3
|
-
import { inject } from '../../injector/index.js';
|
|
4
|
-
import { TRANSACTION_TIMESTAMP } from '../../orm/index.js';
|
|
5
|
-
import { injectRepository } from '../../orm/server/index.js';
|
|
6
|
-
import { getIntegrationTest } from '../../testing/index.js';
|
|
7
|
-
import { timeout } from '../../utils/timing.js';
|
|
8
|
-
import { taskArchive as taskArchiveTable, taskDependency as taskDependencyTable, task as taskTable } from '../postgres/schemas.js';
|
|
9
|
-
import { PostgresTaskQueue } from '../postgres/task-queue.js';
|
|
10
|
-
import { PostgresTask, PostgresTaskArchive } from '../postgres/task.model.js';
|
|
11
|
-
import { TaskDependencyType, TaskStatus } from '../task-queue.js';
|
|
12
|
-
const test = getIntegrationTest({ modules: { taskQueue: true } });
|
|
13
|
-
describe('Task Queue Optimization Edge Cases', () => {
|
|
14
|
-
test('should notify unique namespaces exactly once in incrementCounters', async () => {
|
|
15
|
-
const q1 = inject(PostgresTaskQueue, 'ns-1');
|
|
16
|
-
const q2 = inject(PostgresTaskQueue, 'ns-2');
|
|
17
|
-
const notifySpy = vi.spyOn(PostgresTaskQueue.prototype, 'notify');
|
|
18
|
-
const [t1] = await q1.enqueueMany([{ type: 't1', data: {} }], { returnTasks: true });
|
|
19
|
-
const [t2] = await q2.enqueueMany([{ type: 't2', data: {} }], { returnTasks: true });
|
|
20
|
-
notifySpy.mockClear();
|
|
21
|
-
await q1.incrementCounters([
|
|
22
|
-
{ taskId: t1.id, dependencyTaskId: 'some-dep', type: TaskDependencyType.Schedule },
|
|
23
|
-
{ taskId: t2.id, dependencyTaskId: 'some-dep', type: TaskDependencyType.Schedule },
|
|
24
|
-
{ taskId: t1.id, dependencyTaskId: 'other-dep', type: TaskDependencyType.Schedule },
|
|
25
|
-
]);
|
|
26
|
-
const notifiedNamespaces = notifySpy.mock.calls.map(call => call[0]);
|
|
27
|
-
expect(notifiedNamespaces).toContain('ns-1');
|
|
28
|
-
expect(notifiedNamespaces).toContain('ns-2');
|
|
29
|
-
expect(notifiedNamespaces.filter(n => n == 'ns-1').length).toBe(1);
|
|
30
|
-
expect(notifiedNamespaces.filter(n => n == 'ns-2').length).toBe(1);
|
|
31
|
-
});
|
|
32
|
-
test('should resolve edge and abort on unmatched terminal status in resolveDependenciesMany', async () => {
|
|
33
|
-
const queue = inject(PostgresTaskQueue, 'test-namespace');
|
|
34
|
-
const repository = injectRepository(PostgresTask);
|
|
35
|
-
const [parent] = await queue.enqueueMany([{ type: 'parent', data: {}, abortOnDependencyFailure: true }], { returnTasks: true });
|
|
36
|
-
const [child] = await queue.enqueueMany([{ type: 'child', data: {} }], { returnTasks: true });
|
|
37
|
-
await repository.session.insert(taskDependencyTable).values({
|
|
38
|
-
taskId: parent.id,
|
|
39
|
-
dependencyTaskId: child.id,
|
|
40
|
-
type: TaskDependencyType.Schedule,
|
|
41
|
-
requiredStatuses: [TaskStatus.Completed],
|
|
42
|
-
});
|
|
43
|
-
await repository.session.update(taskTable).set({ unresolvedScheduleDependencies: 1, status: TaskStatus.Waiting }).where(eq(taskTable.id, parent.id));
|
|
44
|
-
await queue.resolveDependenciesMany([{ id: child.id, status: TaskStatus.Dead, namespace: 'test-namespace' }]);
|
|
45
|
-
const updatedParent = await queue.getTask(parent.id);
|
|
46
|
-
expect(updatedParent.status).toBe(TaskStatus.Skipped);
|
|
47
|
-
});
|
|
48
|
-
test('should handle hard timeout during touch', async () => {
|
|
49
|
-
// Configure with small maxExecutionTime
|
|
50
|
-
const queue = inject(PostgresTaskQueue, { namespace: 'timeout-test', maxExecutionTime: 10 });
|
|
51
|
-
const [task] = await queue.enqueueMany([{ type: 'test', data: {} }], { returnTasks: true });
|
|
52
|
-
const [runningTask] = await queue.dequeueMany(1);
|
|
53
|
-
await timeout(50);
|
|
54
|
-
const result = await queue.touch(runningTask);
|
|
55
|
-
expect(result).toBeUndefined();
|
|
56
|
-
const updated = await queue.getTask(runningTask.id);
|
|
57
|
-
expect(updated.status).toBe(TaskStatus.TimedOut);
|
|
58
|
-
});
|
|
59
|
-
test('should handle non-existent tasks in complete and fail', async () => {
|
|
60
|
-
const queue = inject(PostgresTaskQueue, 'missing-test');
|
|
61
|
-
const fakeTask = { id: crypto.randomUUID(), token: crypto.randomUUID(), tries: 0 };
|
|
62
|
-
await expect(queue.complete(fakeTask)).resolves.toBeUndefined();
|
|
63
|
-
await expect(queue.fail(fakeTask, new Error('fail'))).resolves.toBeUndefined();
|
|
64
|
-
});
|
|
65
|
-
test('should handle terminal tasks with no dependents in resolveDependenciesMany', async () => {
|
|
66
|
-
const queue = inject(PostgresTaskQueue, 'no-deps-test');
|
|
67
|
-
const [task] = await queue.enqueueMany([{ type: 'test', data: {} }], { returnTasks: true });
|
|
68
|
-
await queue.resolveDependenciesMany([{ id: task.id, status: TaskStatus.Completed }]);
|
|
69
|
-
});
|
|
70
|
-
test('should handle archival and purge in maintenance', async () => {
|
|
71
|
-
const namespace = `archival-test-${crypto.randomUUID()}`;
|
|
72
|
-
// Configure with small retention
|
|
73
|
-
const queue = inject(PostgresTaskQueue, { namespace, retention: 1000, archiveRetention: 1000 });
|
|
74
|
-
const repository = injectRepository(PostgresTask);
|
|
75
|
-
const archiveRepository = injectRepository(PostgresTaskArchive);
|
|
76
|
-
const [task] = await queue.enqueueMany([{ type: 'test', data: {} }], { returnTasks: true });
|
|
77
|
-
await repository.session.update(taskTable)
|
|
78
|
-
.set({
|
|
79
|
-
status: TaskStatus.Completed,
|
|
80
|
-
completeTimestamp: sql `${TRANSACTION_TIMESTAMP} - interval '2 seconds'`,
|
|
81
|
-
})
|
|
82
|
-
.where(and(eq(taskTable.id, task.id), eq(taskTable.namespace, namespace)));
|
|
83
|
-
await queue.performArchival();
|
|
84
|
-
const archived = await archiveRepository.load(task.id);
|
|
85
|
-
expect(archived).toBeDefined();
|
|
86
|
-
await repository.session.update(taskArchiveTable)
|
|
87
|
-
.set({ completeTimestamp: sql `${TRANSACTION_TIMESTAMP} - interval '2 seconds'` })
|
|
88
|
-
.where(and(eq(taskArchiveTable.id, task.id), eq(taskArchiveTable.namespace, namespace)));
|
|
89
|
-
await queue.performArchivePurge();
|
|
90
|
-
const purged = await archiveRepository.load(task.id).catch(() => undefined);
|
|
91
|
-
expect(purged).toBeUndefined();
|
|
92
|
-
});
|
|
93
|
-
test('should notify on restart', async () => {
|
|
94
|
-
const namespace = `restart-test-${crypto.randomUUID()}`;
|
|
95
|
-
const queue = inject(PostgresTaskQueue, namespace);
|
|
96
|
-
const notifySpy = vi.spyOn(PostgresTaskQueue.prototype, 'notify');
|
|
97
|
-
const [task] = await queue.enqueueMany([{ type: 'test', data: {} }], { returnTasks: true });
|
|
98
|
-
await queue.cancelMany([task.id]);
|
|
99
|
-
notifySpy.mockClear();
|
|
100
|
-
await queue.restart(task.id);
|
|
101
|
-
expect(notifySpy).toHaveBeenCalledWith(namespace);
|
|
102
|
-
});
|
|
103
|
-
test('should use exponential backoff for zombies', async () => {
|
|
104
|
-
const namespace = `zombie-backoff-${crypto.randomUUID()}`;
|
|
105
|
-
// Configure with standard growth
|
|
106
|
-
const queue = inject(PostgresTaskQueue, { namespace, retryDelayMinimum: 1000, retryDelayGrowth: 2 });
|
|
107
|
-
const repository = injectRepository(PostgresTask);
|
|
108
|
-
const [task] = await queue.enqueueMany([{ type: 'test', data: {} }], { returnTasks: true });
|
|
109
|
-
await queue.dequeueMany(1);
|
|
110
|
-
await repository.session.update(taskTable)
|
|
111
|
-
.set({
|
|
112
|
-
status: TaskStatus.Running,
|
|
113
|
-
visibilityDeadline: sql `${TRANSACTION_TIMESTAMP} - interval '1 minute'`,
|
|
114
|
-
tries: 2,
|
|
115
|
-
})
|
|
116
|
-
.where(and(eq(taskTable.id, task.id), eq(taskTable.namespace, namespace)));
|
|
117
|
-
await queue.recoverStaleTasks();
|
|
118
|
-
const updated = await queue.getTask(task.id);
|
|
119
|
-
expect(updated.status).toBe(TaskStatus.Retrying);
|
|
120
|
-
const delay = updated.scheduleTimestamp - Date.now();
|
|
121
|
-
expect(delay).toBeGreaterThan(1000);
|
|
122
|
-
expect(delay).toBeLessThan(3000);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { describe, test, expectTypeOf } from 'vitest';
|
|
2
|
-
describe('TaskQueue Class Generic', () => {
|
|
3
|
-
test('TaskQueue should accept TaskDefinitionMap', () => {
|
|
4
|
-
// If it compiles, it's good. But we can inspect the generic constraints.
|
|
5
|
-
// For now, simple existence check.
|
|
6
|
-
expectTypeOf().toBeObject();
|
|
7
|
-
});
|
|
8
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|