deepline 0.3.148 → 0.3.149
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/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/observability/dlq.ts +1 -0
- package/dist/bundling-sources/shared_libs/observability/queue-health.ts +31 -0
- package/dist/bundling-sources/shared_libs/observability/queue-item-connectors.ts +13 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +40 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts +94 -23
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +1 -1
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
|
@@ -200,7 +200,7 @@ export const SDK_RELEASE = {
|
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
202
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
203
|
-
version: '0.3.
|
|
203
|
+
version: '0.3.149',
|
|
204
204
|
updateSummary:
|
|
205
205
|
'Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.',
|
|
206
206
|
packageCapabilities: {
|
|
@@ -367,8 +367,39 @@ export type QueueRetirementCandidate = {
|
|
|
367
367
|
readonly itemId: string;
|
|
368
368
|
readonly bucket: 'blocked' | 'deadLettered';
|
|
369
369
|
readonly ageMs: number;
|
|
370
|
+
/** Native generation. An absent value must never suppress unresolved work. */
|
|
371
|
+
readonly sourceRevision?: string;
|
|
370
372
|
};
|
|
371
373
|
|
|
374
|
+
/** The runtime item reader and bounded health observer must derive the same
|
|
375
|
+
* opaque revision from the same native row, or an old operator disposition
|
|
376
|
+
* could hide a later failure of the same item identity. */
|
|
377
|
+
export function runtimeQueueItemRevision(fields: {
|
|
378
|
+
updatedAt?: unknown;
|
|
379
|
+
createdAt?: unknown;
|
|
380
|
+
state?: unknown;
|
|
381
|
+
status?: unknown;
|
|
382
|
+
leaseExpiresAt?: unknown;
|
|
383
|
+
failedAt?: unknown;
|
|
384
|
+
}): string {
|
|
385
|
+
const timestamp = (value: unknown): string | undefined => {
|
|
386
|
+
if (value instanceof Date && Number.isFinite(value.getTime())) {
|
|
387
|
+
return value.toISOString();
|
|
388
|
+
}
|
|
389
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
390
|
+
const date = new Date(value);
|
|
391
|
+
if (Number.isFinite(date.getTime())) return date.toISOString();
|
|
392
|
+
}
|
|
393
|
+
return undefined;
|
|
394
|
+
};
|
|
395
|
+
return [
|
|
396
|
+
timestamp(fields.updatedAt) ?? timestamp(fields.createdAt) ?? '',
|
|
397
|
+
String(fields.state ?? fields.status ?? ''),
|
|
398
|
+
timestamp(fields.leaseExpiresAt) ?? '',
|
|
399
|
+
timestamp(fields.failedAt) ?? '',
|
|
400
|
+
].join(':');
|
|
401
|
+
}
|
|
402
|
+
|
|
372
403
|
/**
|
|
373
404
|
* Remove operator-retired identities from a bounded source sample. The source
|
|
374
405
|
* still owns every row; the disposition overlay only changes what operators
|
|
@@ -35,6 +35,12 @@ export type QueueItemConnectorRegisterOptions = {
|
|
|
35
35
|
readonly replaceUnavailable?: boolean;
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
function isUnavailableRegistration(
|
|
39
|
+
registration: QueueItemConnectorRegistration,
|
|
40
|
+
): boolean {
|
|
41
|
+
return registration.connector.id.endsWith('-unavailable');
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
/**
|
|
39
45
|
* The registry is the routing boundary: the control service looks up a queue
|
|
40
46
|
* by its stable public id and never switches on a native table or provider.
|
|
@@ -72,7 +78,7 @@ export class QueueItemConnectorRegistry {
|
|
|
72
78
|
if (
|
|
73
79
|
existing &&
|
|
74
80
|
options.replaceUnavailable &&
|
|
75
|
-
!existing
|
|
81
|
+
!isUnavailableRegistration(existing)
|
|
76
82
|
) {
|
|
77
83
|
throw new Error(
|
|
78
84
|
`Queue connector ${connector.queueId} is already owned by ${existing.connector.id}; replacement is not allowed.`,
|
|
@@ -90,6 +96,12 @@ export class QueueItemConnectorRegistry {
|
|
|
90
96
|
return this.registrations.has(queueId);
|
|
91
97
|
}
|
|
92
98
|
|
|
99
|
+
/** True only after the owner has replaced the safe unavailable placeholder. */
|
|
100
|
+
hasOwnerConnector(queueId: string): boolean {
|
|
101
|
+
const registration = this.registrations.get(queueId);
|
|
102
|
+
return registration !== undefined && !isUnavailableRegistration(registration);
|
|
103
|
+
}
|
|
104
|
+
|
|
93
105
|
list(): readonly QueueItemConnectorRegistration[] {
|
|
94
106
|
return [...this.registrations.values()];
|
|
95
107
|
}
|
|
@@ -757,6 +757,9 @@ function isRetryableAppRuntimeResponse(input: {
|
|
|
757
757
|
// than reducing every 4xx to permanent at the worker boundary.
|
|
758
758
|
const explicitRetryable = appRuntimeExplicitRetryable(input.body);
|
|
759
759
|
if (explicitRetryable !== null) return explicitRetryable;
|
|
760
|
+
if (isComputeBillingTooManyWritesResponse(input)) {
|
|
761
|
+
return true;
|
|
762
|
+
}
|
|
760
763
|
if (
|
|
761
764
|
input.action === 'append_run_events' &&
|
|
762
765
|
input.status === 500 &&
|
|
@@ -809,6 +812,43 @@ function appRuntimeExplicitRetryable(body: string): boolean | null {
|
|
|
809
812
|
}
|
|
810
813
|
}
|
|
811
814
|
|
|
815
|
+
function isComputeBillingTooManyWritesResponse(input: {
|
|
816
|
+
action: RuntimeApiRequest['action'];
|
|
817
|
+
status: number;
|
|
818
|
+
body: string;
|
|
819
|
+
}): boolean {
|
|
820
|
+
if (
|
|
821
|
+
input.status !== 500 ||
|
|
822
|
+
(input.action !== 'compute_billing_upsert' &&
|
|
823
|
+
input.action !== 'compute_billing_record_item' &&
|
|
824
|
+
input.action !== 'compute_billing_finalize')
|
|
825
|
+
) {
|
|
826
|
+
return false;
|
|
827
|
+
}
|
|
828
|
+
// The runtime route's unexpected-error envelope exposes the Convex error
|
|
829
|
+
// name and redacted message but has no retryable flag. A TooManyWrites
|
|
830
|
+
// conflict is transient; treating this 500 as permanent blocks a durable
|
|
831
|
+
// billing job. Only the replay-safe compute actions accept this signature.
|
|
832
|
+
try {
|
|
833
|
+
const parsed = JSON.parse(input.body) as unknown;
|
|
834
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
const error = parsed as Record<string, unknown>;
|
|
838
|
+
if (error.action != null && error.action !== input.action) {
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
841
|
+
return (
|
|
842
|
+
error.errorName === 'TooManyWrites' ||
|
|
843
|
+
error.code === 'TooManyWrites' ||
|
|
844
|
+
(typeof error.debug_error === 'string' &&
|
|
845
|
+
/\bTooManyWrites\b/.test(error.debug_error))
|
|
846
|
+
);
|
|
847
|
+
} catch {
|
|
848
|
+
return false;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
|
|
812
852
|
function isRetryableAppRuntimeResponseStatus(status: number): boolean {
|
|
813
853
|
return (
|
|
814
854
|
status === 429 ||
|
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-queue-health.ts
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
lowerBound,
|
|
6
6
|
notApplicable,
|
|
7
7
|
unavailable,
|
|
8
|
+
runtimeQueueItemRevision,
|
|
8
9
|
type QueueDefinition,
|
|
9
10
|
type QueueHealth,
|
|
10
11
|
type QueueObservation,
|
|
@@ -236,7 +237,42 @@ function operatorRetirementCandidates(
|
|
|
236
237
|
itemId = candidate.itemId;
|
|
237
238
|
}
|
|
238
239
|
const ageMs = numberValue(candidate.ageMs as string | number | undefined);
|
|
239
|
-
|
|
240
|
+
const revisionFields = candidate.revisionFields;
|
|
241
|
+
let sourceRevision: string | undefined;
|
|
242
|
+
if (
|
|
243
|
+
typeof revisionFields === 'object' &&
|
|
244
|
+
revisionFields !== null &&
|
|
245
|
+
!Array.isArray(revisionFields)
|
|
246
|
+
) {
|
|
247
|
+
const fields = revisionFields as Record<string, unknown>;
|
|
248
|
+
const sourceDate = fields.updatedAt ?? fields.createdAt;
|
|
249
|
+
const requiresState = kind === 'absurd';
|
|
250
|
+
const requiresStatus =
|
|
251
|
+
kind === 'compute_billing' || kind === 'sandbox_cleanup';
|
|
252
|
+
if (
|
|
253
|
+
(typeof sourceDate === 'string' || typeof sourceDate === 'number') &&
|
|
254
|
+
Number.isFinite(new Date(sourceDate).getTime()) &&
|
|
255
|
+
(!requiresState || typeof fields.state === 'string') &&
|
|
256
|
+
(!requiresStatus || typeof fields.status === 'string')
|
|
257
|
+
) {
|
|
258
|
+
sourceRevision = runtimeQueueItemRevision({
|
|
259
|
+
updatedAt: fields.updatedAt,
|
|
260
|
+
createdAt: fields.createdAt,
|
|
261
|
+
state: fields.state,
|
|
262
|
+
status: fields.status,
|
|
263
|
+
leaseExpiresAt: fields.leaseExpiresAt,
|
|
264
|
+
failedAt: fields.failedAt,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
if (itemId !== undefined) {
|
|
269
|
+
candidates.push({
|
|
270
|
+
itemId,
|
|
271
|
+
bucket,
|
|
272
|
+
ageMs,
|
|
273
|
+
...(sourceRevision ? { sourceRevision } : {}),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
240
276
|
}
|
|
241
277
|
};
|
|
242
278
|
append(row.blocked_retirement_candidates, 'blocked');
|
|
@@ -517,45 +553,53 @@ function absurdProjectionQuery(
|
|
|
517
553
|
candidateSampleLimit: number,
|
|
518
554
|
): string {
|
|
519
555
|
const table = `absurd.${quoteIdentifier(queueTable, 'queue table')}`;
|
|
556
|
+
const revisionFields = includeRetirementCandidates
|
|
557
|
+
? `json_build_object(
|
|
558
|
+
'createdAt', created_at,
|
|
559
|
+
'state', state,
|
|
560
|
+
'leaseExpiresAt', claim_expires_at,
|
|
561
|
+
'failedAt', failed_at
|
|
562
|
+
)`
|
|
563
|
+
: 'NULL::json';
|
|
520
564
|
const retirementColumns = includeRetirementCandidates
|
|
521
565
|
? `,
|
|
522
566
|
COALESCE((
|
|
523
|
-
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}))
|
|
524
|
-
FROM (SELECT item_id, age_at FROM sampled WHERE bucket = 'blocked' ORDER BY age_at ASC, item_id ASC LIMIT $4::int) candidates
|
|
567
|
+
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}, 'revisionFields', revision_fields))
|
|
568
|
+
FROM (SELECT item_id, age_at, revision_fields FROM sampled WHERE bucket = 'blocked' ORDER BY age_at ASC, item_id ASC LIMIT $4::int) candidates
|
|
525
569
|
), '[]'::json) AS blocked_retirement_candidates,
|
|
526
570
|
COALESCE((
|
|
527
|
-
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}))
|
|
528
|
-
FROM (SELECT item_id, age_at FROM sampled WHERE bucket = 'dead_lettered' ORDER BY age_at ASC, item_id ASC LIMIT $4::int) candidates
|
|
571
|
+
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}, 'revisionFields', revision_fields))
|
|
572
|
+
FROM (SELECT item_id, age_at, revision_fields FROM sampled WHERE bucket = 'dead_lettered' ORDER BY age_at ASC, item_id ASC LIMIT $4::int) candidates
|
|
529
573
|
), '[]'::json) AS dead_lettered_retirement_candidates`
|
|
530
574
|
: '';
|
|
531
575
|
return `
|
|
532
576
|
WITH sampled AS (
|
|
533
|
-
(SELECT 'ready'::text AS bucket, run_id::text AS item_id, available_at AS age_at
|
|
577
|
+
(SELECT 'ready'::text AS bucket, run_id::text AS item_id, available_at AS age_at, NULL::json AS revision_fields
|
|
534
578
|
FROM ${table}
|
|
535
579
|
WHERE state = 'pending' AND available_at <= $1::timestamptz
|
|
536
580
|
ORDER BY available_at, run_id
|
|
537
581
|
LIMIT $2::int)
|
|
538
582
|
UNION ALL
|
|
539
|
-
(SELECT 'delayed'::text, run_id::text, available_at
|
|
583
|
+
(SELECT 'delayed'::text, run_id::text, available_at, NULL::json
|
|
540
584
|
FROM ${table}
|
|
541
585
|
WHERE state = 'sleeping'
|
|
542
586
|
ORDER BY available_at, run_id
|
|
543
587
|
LIMIT $2::int)
|
|
544
588
|
UNION ALL
|
|
545
|
-
(SELECT 'delayed'::text, run_id::text, available_at
|
|
589
|
+
(SELECT 'delayed'::text, run_id::text, available_at, NULL::json
|
|
546
590
|
FROM ${table}
|
|
547
591
|
WHERE state = 'pending' AND available_at > $1::timestamptz
|
|
548
592
|
ORDER BY available_at, run_id
|
|
549
593
|
LIMIT $2::int)
|
|
550
594
|
UNION ALL
|
|
551
|
-
(SELECT 'in_flight'::text, run_id::text, coalesce(started_at, created_at)
|
|
595
|
+
(SELECT 'in_flight'::text, run_id::text, coalesce(started_at, created_at), NULL::json
|
|
552
596
|
FROM ${table}
|
|
553
597
|
WHERE state = 'running'
|
|
554
598
|
AND (claim_expires_at IS NULL OR claim_expires_at > $1::timestamptz)
|
|
555
599
|
ORDER BY available_at, run_id
|
|
556
600
|
LIMIT $2::int)
|
|
557
601
|
UNION ALL
|
|
558
|
-
(SELECT 'blocked'::text, run_id::text, coalesce(claim_expires_at, started_at, created_at)
|
|
602
|
+
(SELECT 'blocked'::text, run_id::text, coalesce(claim_expires_at, started_at, created_at), ${revisionFields}
|
|
559
603
|
FROM ${table}
|
|
560
604
|
WHERE state = 'running'
|
|
561
605
|
AND claim_expires_at IS NOT NULL
|
|
@@ -563,7 +607,7 @@ function absurdProjectionQuery(
|
|
|
563
607
|
ORDER BY claim_expires_at, run_id
|
|
564
608
|
LIMIT $2::int)
|
|
565
609
|
UNION ALL
|
|
566
|
-
(SELECT 'dead_lettered'::text, run_id::text, coalesce(failed_at, created_at)
|
|
610
|
+
(SELECT 'dead_lettered'::text, run_id::text, coalesce(failed_at, created_at), ${revisionFields}
|
|
567
611
|
FROM ${table}
|
|
568
612
|
WHERE state = 'failed'
|
|
569
613
|
ORDER BY available_at, run_id
|
|
@@ -602,15 +646,22 @@ function outboxProjectionQuery(
|
|
|
602
646
|
includeRetirementCandidates: boolean,
|
|
603
647
|
): string {
|
|
604
648
|
const table = `${schema}."outbox"`;
|
|
649
|
+
const revisionFields = includeRetirementCandidates
|
|
650
|
+
? `json_build_object(
|
|
651
|
+
'createdAt', created_at,
|
|
652
|
+
'leaseExpiresAt', lease_expires_at,
|
|
653
|
+
'failedAt', failed_at
|
|
654
|
+
)`
|
|
655
|
+
: 'NULL::json';
|
|
605
656
|
const retirementColumns = includeRetirementCandidates
|
|
606
657
|
? `,
|
|
607
658
|
COALESCE((
|
|
608
|
-
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}))
|
|
609
|
-
FROM (SELECT item_id, age_at FROM blocked ORDER BY age_at ASC, item_id ASC LIMIT $3::int) candidates
|
|
659
|
+
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}, 'revisionFields', revision_fields))
|
|
660
|
+
FROM (SELECT item_id, age_at, revision_fields FROM blocked ORDER BY age_at ASC, item_id ASC LIMIT $3::int) candidates
|
|
610
661
|
), '[]'::json) AS blocked_retirement_candidates,
|
|
611
662
|
COALESCE((
|
|
612
|
-
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}))
|
|
613
|
-
FROM (SELECT item_id, age_at FROM dead_lettered ORDER BY age_at ASC, item_id ASC LIMIT $3::int) candidates
|
|
663
|
+
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}, 'revisionFields', revision_fields))
|
|
664
|
+
FROM (SELECT item_id, age_at, revision_fields FROM dead_lettered ORDER BY age_at ASC, item_id ASC LIMIT $3::int) candidates
|
|
614
665
|
), '[]'::json) AS dead_lettered_retirement_candidates`
|
|
615
666
|
: '';
|
|
616
667
|
return `
|
|
@@ -642,7 +693,8 @@ function outboxProjectionQuery(
|
|
|
642
693
|
ORDER BY lease_expires_at, created_at, event_id
|
|
643
694
|
LIMIT $2::int
|
|
644
695
|
), blocked AS (
|
|
645
|
-
SELECT event_id::text AS item_id, coalesce(lease_expires_at, created_at) AS age_at
|
|
696
|
+
SELECT event_id::text AS item_id, coalesce(lease_expires_at, created_at) AS age_at,
|
|
697
|
+
${revisionFields} AS revision_fields
|
|
646
698
|
FROM ${table}
|
|
647
699
|
WHERE delivered_at IS NULL
|
|
648
700
|
AND failed_at IS NULL
|
|
@@ -651,7 +703,8 @@ function outboxProjectionQuery(
|
|
|
651
703
|
ORDER BY coalesce(lease_expires_at, created_at), created_at, event_id
|
|
652
704
|
LIMIT $2::int
|
|
653
705
|
), dead_lettered AS (
|
|
654
|
-
SELECT event_id::text AS item_id, coalesce(failed_at, created_at) AS age_at
|
|
706
|
+
SELECT event_id::text AS item_id, coalesce(failed_at, created_at) AS age_at,
|
|
707
|
+
${revisionFields} AS revision_fields
|
|
655
708
|
FROM ${table}
|
|
656
709
|
WHERE delivered_at IS NULL AND failed_at IS NOT NULL
|
|
657
710
|
ORDER BY failed_at, event_id
|
|
@@ -689,11 +742,19 @@ function cleanupProjectionQuery(
|
|
|
689
742
|
includeRetirementCandidates: boolean,
|
|
690
743
|
): string {
|
|
691
744
|
const table = `${schema}."sandbox_cleanup_jobs_v2"`;
|
|
745
|
+
const revisionFields = includeRetirementCandidates
|
|
746
|
+
? `json_build_object(
|
|
747
|
+
'updatedAt', updated_at,
|
|
748
|
+
'createdAt', created_at,
|
|
749
|
+
'status', status,
|
|
750
|
+
'leaseExpiresAt', lease_expires_at
|
|
751
|
+
)`
|
|
752
|
+
: 'NULL::json';
|
|
692
753
|
const retirementColumns = includeRetirementCandidates
|
|
693
754
|
? `,
|
|
694
755
|
COALESCE((
|
|
695
|
-
SELECT json_agg(json_build_object('provider', provider, 'sandboxId', sandbox_id, 'routingDomainKey', routing_domain_key, 'ageMs', ${intervalExpr('age_at')}))
|
|
696
|
-
FROM (SELECT provider, sandbox_id, routing_domain_key, created_at, age_at FROM blocked ORDER BY age_at ASC, created_at ASC, provider ASC, sandbox_id ASC LIMIT $3::int) candidates
|
|
756
|
+
SELECT json_agg(json_build_object('provider', provider, 'sandboxId', sandbox_id, 'routingDomainKey', routing_domain_key, 'ageMs', ${intervalExpr('age_at')}, 'revisionFields', revision_fields))
|
|
757
|
+
FROM (SELECT provider, sandbox_id, routing_domain_key, created_at, age_at, revision_fields FROM blocked ORDER BY age_at ASC, created_at ASC, provider ASC, sandbox_id ASC LIMIT $3::int) candidates
|
|
697
758
|
), '[]'::json) AS blocked_retirement_candidates,
|
|
698
759
|
'[]'::json AS dead_lettered_retirement_candidates`
|
|
699
760
|
: '';
|
|
@@ -736,7 +797,8 @@ function cleanupProjectionQuery(
|
|
|
736
797
|
CASE
|
|
737
798
|
WHEN blocked_at IS NOT NULL THEN blocked_at
|
|
738
799
|
ELSE coalesce(lease_expires_at, created_at)
|
|
739
|
-
END AS age_at
|
|
800
|
+
END AS age_at,
|
|
801
|
+
${revisionFields} AS revision_fields
|
|
740
802
|
FROM ${table}
|
|
741
803
|
WHERE status <> 'deleted'
|
|
742
804
|
AND (
|
|
@@ -779,11 +841,19 @@ function computeBillingProjectionQuery(
|
|
|
779
841
|
includeRetirementCandidates: boolean,
|
|
780
842
|
): string {
|
|
781
843
|
const table = `${schema}."compute_billing_jobs_v2"`;
|
|
844
|
+
const revisionFields = includeRetirementCandidates
|
|
845
|
+
? `json_build_object(
|
|
846
|
+
'updatedAt', updated_at,
|
|
847
|
+
'createdAt', created_at,
|
|
848
|
+
'status', status,
|
|
849
|
+
'leaseExpiresAt', lease_expires_at
|
|
850
|
+
)`
|
|
851
|
+
: 'NULL::json';
|
|
782
852
|
const retirementColumns = includeRetirementCandidates
|
|
783
853
|
? `,
|
|
784
854
|
COALESCE((
|
|
785
|
-
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}))
|
|
786
|
-
FROM (SELECT item_id, age_at FROM blocked ORDER BY age_at ASC, item_id ASC LIMIT $3::int) candidates
|
|
855
|
+
SELECT json_agg(json_build_object('itemId', item_id, 'ageMs', ${intervalExpr('age_at')}, 'revisionFields', revision_fields))
|
|
856
|
+
FROM (SELECT item_id, age_at, revision_fields FROM blocked ORDER BY age_at ASC, item_id ASC LIMIT $3::int) candidates
|
|
787
857
|
), '[]'::json) AS blocked_retirement_candidates,
|
|
788
858
|
'[]'::json AS dead_lettered_retirement_candidates`
|
|
789
859
|
: '';
|
|
@@ -816,7 +886,8 @@ function computeBillingProjectionQuery(
|
|
|
816
886
|
ORDER BY lease_expires_at, created_at, run_id
|
|
817
887
|
LIMIT $2::int
|
|
818
888
|
), blocked AS (
|
|
819
|
-
SELECT run_id::text AS item_id, coalesce(blocked_at, lease_expires_at, created_at) AS age_at
|
|
889
|
+
SELECT run_id::text AS item_id, coalesce(blocked_at, lease_expires_at, created_at) AS age_at,
|
|
890
|
+
${revisionFields} AS revision_fields
|
|
820
891
|
FROM ${table}
|
|
821
892
|
WHERE status <> 'settled'
|
|
822
893
|
AND (
|
package/dist/cli/index.js
CHANGED
|
@@ -3068,7 +3068,7 @@ var SDK_RELEASE = {
|
|
|
3068
3068
|
// getters keep their established compatibility behavior.
|
|
3069
3069
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3070
3070
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3071
|
-
version: "0.3.
|
|
3071
|
+
version: "0.3.149",
|
|
3072
3072
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3073
3073
|
packageCapabilities: {
|
|
3074
3074
|
updatePreferences: 1
|
package/dist/cli/index.mjs
CHANGED
|
@@ -3063,7 +3063,7 @@ var SDK_RELEASE = {
|
|
|
3063
3063
|
// getters keep their established compatibility behavior.
|
|
3064
3064
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3065
3065
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3066
|
-
version: "0.3.
|
|
3066
|
+
version: "0.3.149",
|
|
3067
3067
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
3068
3068
|
packageCapabilities: {
|
|
3069
3069
|
updatePreferences: 1
|
package/dist/index.js
CHANGED
|
@@ -864,7 +864,7 @@ var SDK_RELEASE = {
|
|
|
864
864
|
// getters keep their established compatibility behavior.
|
|
865
865
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
866
866
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
867
|
-
version: "0.3.
|
|
867
|
+
version: "0.3.149",
|
|
868
868
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
869
869
|
packageCapabilities: {
|
|
870
870
|
updatePreferences: 1
|
package/dist/index.mjs
CHANGED
|
@@ -768,7 +768,7 @@ var SDK_RELEASE = {
|
|
|
768
768
|
// getters keep their established compatibility behavior.
|
|
769
769
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
770
770
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
771
|
-
version: "0.3.
|
|
771
|
+
version: "0.3.149",
|
|
772
772
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
773
773
|
packageCapabilities: {
|
|
774
774
|
updatePreferences: 1
|
package/dist/release.d.mts
CHANGED
|
@@ -149,7 +149,7 @@ type SdkRelease = {
|
|
|
149
149
|
supportPolicy: SdkSupportPolicy;
|
|
150
150
|
};
|
|
151
151
|
declare const SDK_RELEASE: {
|
|
152
|
-
readonly version: "0.3.
|
|
152
|
+
readonly version: "0.3.149";
|
|
153
153
|
readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
|
|
154
154
|
readonly packageCapabilities: {
|
|
155
155
|
readonly updatePreferences: 1;
|
package/dist/release.d.ts
CHANGED
|
@@ -149,7 +149,7 @@ type SdkRelease = {
|
|
|
149
149
|
supportPolicy: SdkSupportPolicy;
|
|
150
150
|
};
|
|
151
151
|
declare const SDK_RELEASE: {
|
|
152
|
-
readonly version: "0.3.
|
|
152
|
+
readonly version: "0.3.149";
|
|
153
153
|
readonly updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.";
|
|
154
154
|
readonly packageCapabilities: {
|
|
155
155
|
readonly updatePreferences: 1;
|
package/dist/release.js
CHANGED
|
@@ -74,7 +74,7 @@ var SDK_RELEASE = {
|
|
|
74
74
|
// getters keep their established compatibility behavior.
|
|
75
75
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
76
76
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
77
|
-
version: "0.3.
|
|
77
|
+
version: "0.3.149",
|
|
78
78
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
79
79
|
packageCapabilities: {
|
|
80
80
|
updatePreferences: 1
|
package/dist/release.mjs
CHANGED
|
@@ -48,7 +48,7 @@ var SDK_RELEASE = {
|
|
|
48
48
|
// getters keep their established compatibility behavior.
|
|
49
49
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
50
50
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
51
|
-
version: "0.3.
|
|
51
|
+
version: "0.3.149",
|
|
52
52
|
updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
|
|
53
53
|
packageCapabilities: {
|
|
54
54
|
updatePreferences: 1
|