deepline 0.3.276 → 0.3.278
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/play-runtime/scheduler-backends/postgres.ts +65 -12
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts +147 -106
- package/dist/cli/index.js +6 -7
- package/dist/cli/index.mjs +6 -7
- 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.278',
|
|
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: {
|
|
@@ -17391,6 +17391,22 @@ function runLedgerOrderSql(alias: string): string {
|
|
|
17391
17391
|
return `CASE ${alias}.event_type WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0 WHEN ${RUN_EVENT_KIND_SQL_LITERAL.runStarted} THEN 1 ELSE 2 END, ${alias}.created_at, ${alias}.event_id`;
|
|
17392
17392
|
}
|
|
17393
17393
|
|
|
17394
|
+
/** Prioritize a terminal's causal head without skipping its predecessors. */
|
|
17395
|
+
function runLedgerTerminalPendingSql(
|
|
17396
|
+
alias: string,
|
|
17397
|
+
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
17398
|
+
): string {
|
|
17399
|
+
return `EXISTS (
|
|
17400
|
+
SELECT 1 FROM ${tableName('outbox', options)} AS terminal_event
|
|
17401
|
+
WHERE terminal_event.event_id = 'run-terminal:' || ${alias}.run_id
|
|
17402
|
+
AND terminal_event.run_id = ${alias}.run_id
|
|
17403
|
+
AND terminal_event.event_type IN (${RUN_EVENT_KIND_SQL_LITERAL.runCompleted}, ${RUN_EVENT_KIND_SQL_LITERAL.runFailed}, ${RUN_EVENT_KIND_SQL_LITERAL.runCancelled})
|
|
17404
|
+
AND terminal_event.delivered_at IS NULL
|
|
17405
|
+
AND terminal_event.failed_at IS NULL
|
|
17406
|
+
AND coalesce(terminal_event.next_attempt_at, terminal_event.created_at) <= now()
|
|
17407
|
+
)`;
|
|
17408
|
+
}
|
|
17409
|
+
|
|
17394
17410
|
/**
|
|
17395
17411
|
* Claim a causal prefix, preserving the v33 adapter while the additive batch
|
|
17396
17412
|
* marker is absent. An enclosing transaction uses a savepoint so the missing
|
|
@@ -17463,16 +17479,14 @@ export async function readPendingPostgresSchedulerOutboxEvents(
|
|
|
17463
17479
|
-- terminal facts. Project it first so a lifecycle backlog cannot make
|
|
17464
17480
|
-- an accepted run invisible; per-run predecessor checks above retain
|
|
17465
17481
|
-- strict ordering within each run.
|
|
17466
|
-
-- A
|
|
17467
|
-
--
|
|
17468
|
-
--
|
|
17469
|
-
--
|
|
17470
|
-
-- runs' progress for seconds (live-run-observation-e2e: 4.9 s from
|
|
17471
|
-
-- commit to first claim while the projector drained continuously).
|
|
17482
|
+
-- A run with a pending terminal comes next, including its causal
|
|
17483
|
+
-- predecessors. Giving priority only to a terminal head leaves a
|
|
17484
|
+
-- finished run's earlier progress behind unrelated progress. The
|
|
17485
|
+
-- predecessor checks still forbid skipping any fact within the run.
|
|
17472
17486
|
ORDER BY
|
|
17473
17487
|
CASE
|
|
17474
17488
|
WHEN candidate.event_type = ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0
|
|
17475
|
-
WHEN candidate
|
|
17489
|
+
WHEN ${runLedgerTerminalPendingSql('candidate', options)} THEN 1
|
|
17476
17490
|
ELSE 2
|
|
17477
17491
|
END,
|
|
17478
17492
|
coalesce(candidate.next_attempt_at, candidate.created_at),
|
|
@@ -18892,6 +18906,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
18892
18906
|
input: RunLedgerOutboxDispatchInput & { waitForRunLock?: boolean },
|
|
18893
18907
|
options?: Pick<PostgresSchedulerOptions, 'schema'>,
|
|
18894
18908
|
): Promise<PostgresSchedulerOutboxProjectionResult> {
|
|
18909
|
+
const dispatchStartedAtMs = Date.now();
|
|
18895
18910
|
const leaseOwner =
|
|
18896
18911
|
input.leaseOwner?.trim() || `run-ledger-outbox-dispatch:${randomUUID()}`;
|
|
18897
18912
|
const events = await withClient(async (client) => {
|
|
@@ -18986,16 +19001,16 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
18986
19001
|
AND active.lease_owner IS NOT NULL
|
|
18987
19002
|
AND active.lease_expires_at > now()
|
|
18988
19003
|
)
|
|
18989
|
-
-- admission_first: admission, then
|
|
18990
|
-
-- terminal
|
|
18991
|
-
--
|
|
18992
|
-
--
|
|
19004
|
+
-- admission_first: admission, then the causal head of a run with
|
|
19005
|
+
-- a pending terminal, then FIFO progress. oldest_ready keeps its
|
|
19006
|
+
-- pure age order so continuous admissions/terminals cannot starve
|
|
19007
|
+
-- ordinary progress.
|
|
18993
19008
|
ORDER BY ${
|
|
18994
19009
|
input.headPriority === 'oldest_ready'
|
|
18995
19010
|
? ''
|
|
18996
19011
|
: `CASE
|
|
18997
19012
|
WHEN head.event_type = ${RUN_EVENT_KIND_SQL_LITERAL.runCreated} THEN 0
|
|
18998
|
-
WHEN head
|
|
19013
|
+
WHEN ${runLedgerTerminalPendingSql('head', options)} THEN 1
|
|
18999
19014
|
ELSE 2
|
|
19000
19015
|
END,`
|
|
19001
19016
|
}
|
|
@@ -19035,6 +19050,10 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
19035
19050
|
};
|
|
19036
19051
|
}
|
|
19037
19052
|
|
|
19053
|
+
const claimedAtMs = Date.now();
|
|
19054
|
+
let authorityReadyAtMs: number | null = null;
|
|
19055
|
+
let appendFinishedAtMs: number | null = null;
|
|
19056
|
+
let acknowledgedAtMs: number | null = null;
|
|
19038
19057
|
try {
|
|
19039
19058
|
const first = events[0]!;
|
|
19040
19059
|
const tokenAuthority = input.tokenAuthority ?? 'local_mint';
|
|
@@ -19091,6 +19110,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
19091
19110
|
// The caller-owned admission deadline (see `signal` above) wins.
|
|
19092
19111
|
...(input.signal ? { signal: input.signal } : {}),
|
|
19093
19112
|
};
|
|
19113
|
+
authorityReadyAtMs = Date.now();
|
|
19094
19114
|
const renewDelivery = () =>
|
|
19095
19115
|
withClient((client) =>
|
|
19096
19116
|
renewPostgresRunLedgerDelivery(
|
|
@@ -19155,6 +19175,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
19155
19175
|
});
|
|
19156
19176
|
}
|
|
19157
19177
|
}
|
|
19178
|
+
appendFinishedAtMs = Date.now();
|
|
19158
19179
|
const deliveredRows = await withClient((client) =>
|
|
19159
19180
|
markPostgresSchedulerOutboxDeliveredRows(
|
|
19160
19181
|
client,
|
|
@@ -19162,6 +19183,7 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
19162
19183
|
{ ...options, leaseOwner },
|
|
19163
19184
|
),
|
|
19164
19185
|
);
|
|
19186
|
+
acknowledgedAtMs = Date.now();
|
|
19165
19187
|
const markedDelivered = deliveredRows.length;
|
|
19166
19188
|
if (input.onDelivered && deliveredRows.length > 0) {
|
|
19167
19189
|
try {
|
|
@@ -19253,6 +19275,37 @@ export async function dispatchRunLedgerOutboxToLedgerBatchOnceWithClientScope(
|
|
|
19253
19275
|
retrying: settlement.retrying.length,
|
|
19254
19276
|
retryingEventIds: settlement.retrying,
|
|
19255
19277
|
};
|
|
19278
|
+
} finally {
|
|
19279
|
+
const settledAtMs = Date.now();
|
|
19280
|
+
const headAgeAtClaimMs = Math.max(
|
|
19281
|
+
0,
|
|
19282
|
+
claimedAtMs - events[0]!.createdAt.getTime(),
|
|
19283
|
+
);
|
|
19284
|
+
if (
|
|
19285
|
+
settledAtMs - dispatchStartedAtMs >= 1_000 ||
|
|
19286
|
+
headAgeAtClaimMs >= 1_000
|
|
19287
|
+
) {
|
|
19288
|
+
console.info('[run-ledger-outbox.slow_delivery]', {
|
|
19289
|
+
runId: events[0]!.runId,
|
|
19290
|
+
headEventId: events[0]!.eventId,
|
|
19291
|
+
eventCount: events.length,
|
|
19292
|
+
headAgeAtClaimMs,
|
|
19293
|
+
claimMs: claimedAtMs - dispatchStartedAtMs,
|
|
19294
|
+
authorityMs:
|
|
19295
|
+
authorityReadyAtMs === null ? null : authorityReadyAtMs - claimedAtMs,
|
|
19296
|
+
appendMs:
|
|
19297
|
+
appendFinishedAtMs === null || authorityReadyAtMs === null
|
|
19298
|
+
? null
|
|
19299
|
+
: appendFinishedAtMs - authorityReadyAtMs,
|
|
19300
|
+
acknowledgeMs:
|
|
19301
|
+
acknowledgedAtMs === null || appendFinishedAtMs === null
|
|
19302
|
+
? null
|
|
19303
|
+
: acknowledgedAtMs - appendFinishedAtMs,
|
|
19304
|
+
continuationMs:
|
|
19305
|
+
acknowledgedAtMs === null ? null : settledAtMs - acknowledgedAtMs,
|
|
19306
|
+
durationMs: settledAtMs - dispatchStartedAtMs,
|
|
19307
|
+
});
|
|
19308
|
+
}
|
|
19256
19309
|
}
|
|
19257
19310
|
}
|
|
19258
19311
|
|
package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-event-search.ts
CHANGED
|
@@ -51,7 +51,7 @@ const RUNTIME_EVENT_LOG_POSITION_EXPRESSION = `jsonb_set(
|
|
|
51
51
|
// Migration readiness tracks this projection body independently of scheduler
|
|
52
52
|
// wire and schema versions. Bump when a changed trigger must be reinstalled.
|
|
53
53
|
export const RUNTIME_EVENT_SEARCH_OUTBOX_PROJECTION_MARKER =
|
|
54
|
-
'runtime-event-search-log-context-
|
|
54
|
+
'runtime-event-search-log-context-v13-index-first-position';
|
|
55
55
|
export const RUNTIME_EVENT_CANONICAL_RETENTION_INDEX_READY_MARKER =
|
|
56
56
|
'runtime-event-canonical-retention-v1';
|
|
57
57
|
export const RUNTIME_EVENTS_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
|
|
@@ -1018,7 +1018,6 @@ export async function attachRuntimeEventSearchTriggers(
|
|
|
1018
1018
|
doc jsonb; line_doc jsonb; line_context jsonb;
|
|
1019
1019
|
eid text; existing_digest text; digest text; assigned_seq bigint; terminal_progress_identity boolean;
|
|
1020
1020
|
log_channel text; log_position bigint; matched_event_id text; matched_doc jsonb;
|
|
1021
|
-
previous_plan_cache_mode text;
|
|
1022
1021
|
legacy_position_prefix text; position_event_ids text[];
|
|
1023
1022
|
log_alias jsonb; position_alias jsonb; envelope_attempt jsonb;
|
|
1024
1023
|
line_count bigint; fresh_event_ids text[] := ARRAY[]::text[];
|
|
@@ -1297,23 +1296,29 @@ export async function attachRuntimeEventSearchTriggers(
|
|
|
1297
1296
|
-- A transport may already be aliased onto an event whose
|
|
1298
1297
|
-- primary key belongs to another channel. Find that alias
|
|
1299
1298
|
-- independently of content so changed bytes still fail the
|
|
1300
|
-
-- immutable-position check below.
|
|
1301
|
-
--
|
|
1302
|
-
--
|
|
1303
|
-
--
|
|
1304
|
-
|
|
1305
|
-
|
|
1299
|
+
-- immutable-position check below. Materialize the scoped
|
|
1300
|
+
-- position lookup before applying run filters: otherwise
|
|
1301
|
+
-- the planner can choose the run-history index and inspect
|
|
1302
|
+
-- every old log for each incoming position, even with a
|
|
1303
|
+
-- custom plan. The indexed document already binds scope,
|
|
1304
|
+
-- org, run, attempt and channel position; retain the outer
|
|
1305
|
+
-- identity checks as defense in depth.
|
|
1306
|
+
WITH position_matches AS MATERIALIZED (
|
|
1307
|
+
SELECT event.event_id, event.source_digest, event.search_doc,
|
|
1308
|
+
event.runtime_scope, event.org_id, event.run_id, event.log_seq
|
|
1309
|
+
FROM runtime_observability.events AS event
|
|
1310
|
+
WHERE event.kind = ${RUN_EVENT_KIND_SQL_LITERAL.logAppended}
|
|
1311
|
+
AND event.search_doc ? 'producerAttempt'
|
|
1312
|
+
AND event.search_doc ? 'logPositions'
|
|
1313
|
+
AND (${RUNTIME_EVENT_LOG_POSITION_EXPRESSION.replaceAll('search_doc', 'event.search_doc')}) @> position_alias
|
|
1314
|
+
)
|
|
1306
1315
|
SELECT event.event_id, event.source_digest, event.search_doc
|
|
1307
1316
|
INTO matched_event_id, existing_digest, matched_doc
|
|
1308
|
-
FROM
|
|
1317
|
+
FROM position_matches AS event
|
|
1309
1318
|
WHERE event.runtime_scope = ${quoteLiteral(scope)} AND event.org_id = run_org
|
|
1310
|
-
AND event.run_id = observation.run_id
|
|
1311
|
-
AND event.search_doc ? 'producerAttempt'
|
|
1312
|
-
AND event.search_doc ? 'logPositions'
|
|
1313
|
-
AND (${RUNTIME_EVENT_LOG_POSITION_EXPRESSION.replaceAll('search_doc', 'event.search_doc')}) @> position_alias
|
|
1319
|
+
AND event.run_id = observation.run_id
|
|
1314
1320
|
ORDER BY event.log_seq NULLS LAST, event.event_id
|
|
1315
1321
|
LIMIT 1;
|
|
1316
|
-
PERFORM set_config('plan_cache_mode', previous_plan_cache_mode, true);
|
|
1317
1322
|
END IF;
|
|
1318
1323
|
IF matched_event_id IS NOT NULL THEN
|
|
1319
1324
|
IF existing_digest IS DISTINCT FROM digest THEN
|
|
@@ -2015,20 +2020,22 @@ type RuntimeEventIndexExpectation = {
|
|
|
2015
2020
|
opclasses?: string[];
|
|
2016
2021
|
};
|
|
2017
2022
|
|
|
2018
|
-
const
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
createSql: `CREATE INDEX CONCURRENTLY IF NOT EXISTS ${RUNTIME_EVENT_LOG_POSITION_INDEX}
|
|
2023
|
+
const RUNTIME_EVENT_LOG_POSITION_INDEX_SPEC: RuntimeEventIndexExpectation = {
|
|
2024
|
+
name: RUNTIME_EVENT_LOG_POSITION_INDEX,
|
|
2025
|
+
method: 'gin',
|
|
2026
|
+
opclasses: ['jsonb_path_ops'],
|
|
2027
|
+
keys: [
|
|
2028
|
+
"jsonb_set(jsonb_set(jsonb_set(jsonb_set(COALESCE(search_doc -> 'logPositions'::text, '{}'::jsonb), ARRAY['producerAttempt'::text], search_doc -> 'producerAttempt'::text, true), ARRAY['_runtimeScope:'::text || runtime_scope], 'true'::jsonb, true), ARRAY['_orgId:'::text || org_id], 'true'::jsonb, true), ARRAY['_runId:'::text || run_id], 'true'::jsonb, true)",
|
|
2029
|
+
],
|
|
2030
|
+
predicate: RUNTIME_EVENT_LOG_POSITION_PREDICATE,
|
|
2031
|
+
createSql: `CREATE INDEX CONCURRENTLY IF NOT EXISTS ${RUNTIME_EVENT_LOG_POSITION_INDEX}
|
|
2028
2032
|
ON runtime_observability.events USING gin
|
|
2029
2033
|
((${RUNTIME_EVENT_LOG_POSITION_EXPRESSION}) jsonb_path_ops)
|
|
2030
2034
|
WHERE ${RUNTIME_EVENT_LOG_POSITION_PREDICATE}`,
|
|
2031
|
-
|
|
2035
|
+
};
|
|
2036
|
+
|
|
2037
|
+
const RUNTIME_EVENT_QUERY_INDEXES: RuntimeEventIndexExpectation[] = [
|
|
2038
|
+
RUNTIME_EVENT_LOG_POSITION_INDEX_SPEC,
|
|
2032
2039
|
{
|
|
2033
2040
|
name: RUNTIME_EVENT_LOG_DEDUPE_INDEX,
|
|
2034
2041
|
keys: [
|
|
@@ -2062,92 +2069,126 @@ const RUNTIME_EVENT_QUERY_INDEXES: RuntimeEventIndexExpectation[] = [
|
|
|
2062
2069
|
},
|
|
2063
2070
|
];
|
|
2064
2071
|
|
|
2065
|
-
|
|
2066
|
-
export async function prepareRuntimeEventQueryIndexes(
|
|
2072
|
+
async function hasRuntimeEventQueryIndex(
|
|
2067
2073
|
client: PostgresSchedulerQueryClient,
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2074
|
+
expected: RuntimeEventIndexExpectation,
|
|
2075
|
+
): Promise<boolean> {
|
|
2076
|
+
type IndexShape = {
|
|
2077
|
+
valid: boolean;
|
|
2078
|
+
ready: boolean;
|
|
2079
|
+
is_unique: boolean;
|
|
2080
|
+
table_matches: boolean;
|
|
2081
|
+
key_count: number;
|
|
2082
|
+
attribute_count: number;
|
|
2083
|
+
method: string;
|
|
2084
|
+
keys: string[];
|
|
2085
|
+
opclasses: string[];
|
|
2086
|
+
predicate: string | null;
|
|
2087
|
+
};
|
|
2088
|
+
const inspect = () =>
|
|
2089
|
+
client.query<IndexShape>(
|
|
2090
|
+
`SELECT index_row.indisvalid AS valid,
|
|
2091
|
+
index_row.indisready AS ready,
|
|
2092
|
+
index_row.indisunique AS is_unique,
|
|
2093
|
+
index_row.indrelid = to_regclass('runtime_observability.events') AS table_matches,
|
|
2094
|
+
index_row.indnkeyatts AS key_count,
|
|
2095
|
+
index_row.indnatts AS attribute_count,
|
|
2096
|
+
method.amname AS method,
|
|
2097
|
+
ARRAY(
|
|
2098
|
+
SELECT pg_get_indexdef(index_row.indexrelid, key_number.position, true)
|
|
2099
|
+
FROM generate_series(1, index_row.indnkeyatts) AS key_number(position)
|
|
2100
|
+
ORDER BY key_number.position
|
|
2101
|
+
) AS keys,
|
|
2102
|
+
(
|
|
2103
|
+
SELECT coalesce(json_agg(operator_class.opcname ORDER BY classes.position), '[]'::json)
|
|
2104
|
+
FROM unnest(index_row.indclass) WITH ORDINALITY AS classes(opclass_oid, position)
|
|
2105
|
+
JOIN pg_opclass AS operator_class ON operator_class.oid = classes.opclass_oid
|
|
2106
|
+
) AS opclasses,
|
|
2107
|
+
pg_get_expr(index_row.indpred, index_row.indrelid) AS predicate
|
|
2108
|
+
FROM pg_index AS index_row
|
|
2109
|
+
JOIN pg_class AS index_class ON index_class.oid = index_row.indexrelid
|
|
2110
|
+
JOIN pg_am AS method ON method.oid = index_class.relam
|
|
2111
|
+
WHERE index_class.oid = to_regclass($1)`,
|
|
2112
|
+
[`runtime_observability.${expected.name}`],
|
|
2113
|
+
);
|
|
2114
|
+
const assertShape = (shape: IndexShape): void => {
|
|
2115
|
+
if (!shape.valid || !shape.ready) {
|
|
2116
|
+
throw new Error(
|
|
2117
|
+
`Runtime event index ${expected.name} is invalid or incomplete; inspect and repair the failed build explicitly.`,
|
|
2107
2118
|
);
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
) ||
|
|
2131
|
-
shape.predicate === null ||
|
|
2132
|
-
normalizedQueryIndexPredicate(shape.predicate) !==
|
|
2133
|
-
normalizedQueryIndexPredicate(expected.predicate)
|
|
2134
|
-
) {
|
|
2135
|
-
throw new Error(
|
|
2136
|
-
`Runtime event index ${expected.name} differs from its expected table, keys, method, uniqueness or predicate. Actual catalog shape: ${JSON.stringify(shape)}. Inspect and repair it explicitly.`,
|
|
2137
|
-
);
|
|
2138
|
-
}
|
|
2139
|
-
};
|
|
2140
|
-
|
|
2141
|
-
const existing = (await inspect()).rows[0];
|
|
2142
|
-
if (existing) assertShape(existing);
|
|
2143
|
-
await client.query(expected.createSql);
|
|
2144
|
-
const built = (await inspect()).rows[0];
|
|
2145
|
-
if (!built) {
|
|
2119
|
+
}
|
|
2120
|
+
if (
|
|
2121
|
+
!shape.table_matches ||
|
|
2122
|
+
shape.is_unique ||
|
|
2123
|
+
shape.method !== (expected.method ?? 'btree') ||
|
|
2124
|
+
(expected.opclasses !== undefined &&
|
|
2125
|
+
(shape.opclasses.length !== expected.opclasses.length ||
|
|
2126
|
+
shape.opclasses.some(
|
|
2127
|
+
(name, index) => name !== expected.opclasses![index],
|
|
2128
|
+
))) ||
|
|
2129
|
+
shape.key_count !== expected.keys.length ||
|
|
2130
|
+
shape.attribute_count !== expected.keys.length ||
|
|
2131
|
+
shape.keys.length !== expected.keys.length ||
|
|
2132
|
+
shape.keys.some(
|
|
2133
|
+
(key, index) =>
|
|
2134
|
+
normalizedRetentionPredicate(key) !==
|
|
2135
|
+
normalizedRetentionPredicate(expected.keys[index]!),
|
|
2136
|
+
) ||
|
|
2137
|
+
shape.predicate === null ||
|
|
2138
|
+
normalizedQueryIndexPredicate(shape.predicate) !==
|
|
2139
|
+
normalizedQueryIndexPredicate(expected.predicate)
|
|
2140
|
+
) {
|
|
2146
2141
|
throw new Error(
|
|
2147
|
-
`Runtime event index ${expected.name}
|
|
2142
|
+
`Runtime event index ${expected.name} differs from its expected table, keys, method, uniqueness or predicate. Actual catalog shape: ${JSON.stringify(shape)}. Inspect and repair it explicitly.`,
|
|
2148
2143
|
);
|
|
2149
2144
|
}
|
|
2150
|
-
|
|
2145
|
+
};
|
|
2146
|
+
|
|
2147
|
+
const existing = (await inspect()).rows[0];
|
|
2148
|
+
if (!existing) return false;
|
|
2149
|
+
assertShape(existing);
|
|
2150
|
+
return true;
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
async function prepareRuntimeEventQueryIndex(
|
|
2154
|
+
client: PostgresSchedulerQueryClient,
|
|
2155
|
+
expected: RuntimeEventIndexExpectation,
|
|
2156
|
+
): Promise<void> {
|
|
2157
|
+
if (await hasRuntimeEventQueryIndex(client, expected)) return;
|
|
2158
|
+
await client.query(expected.createSql);
|
|
2159
|
+
if (!(await hasRuntimeEventQueryIndex(client, expected))) {
|
|
2160
|
+
throw new Error(
|
|
2161
|
+
`Runtime event index ${expected.name} was not found after preparation.`,
|
|
2162
|
+
);
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
/** Deployment-only check; does not gate requests or worker admission. */
|
|
2167
|
+
export async function hasRuntimeEventLogPositionIndex(
|
|
2168
|
+
client: PostgresSchedulerQueryClient,
|
|
2169
|
+
): Promise<boolean> {
|
|
2170
|
+
return hasRuntimeEventQueryIndex(
|
|
2171
|
+
client,
|
|
2172
|
+
RUNTIME_EVENT_LOG_POSITION_INDEX_SPEC,
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
/** Prepare the existing position index before replacing the projection body. */
|
|
2177
|
+
export async function prepareRuntimeEventLogPositionIndex(
|
|
2178
|
+
client: PostgresSchedulerQueryClient,
|
|
2179
|
+
): Promise<void> {
|
|
2180
|
+
await prepareRuntimeEventQueryIndex(
|
|
2181
|
+
client,
|
|
2182
|
+
RUNTIME_EVENT_LOG_POSITION_INDEX_SPEC,
|
|
2183
|
+
);
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
/** Build only operator-owned indexes, concurrently and outside a transaction. */
|
|
2187
|
+
export async function prepareRuntimeEventQueryIndexes(
|
|
2188
|
+
client: PostgresSchedulerQueryClient,
|
|
2189
|
+
): Promise<void> {
|
|
2190
|
+
for (const expected of RUNTIME_EVENT_QUERY_INDEXES) {
|
|
2191
|
+
await prepareRuntimeEventQueryIndex(client, expected);
|
|
2151
2192
|
}
|
|
2152
2193
|
}
|
|
2153
2194
|
|
package/dist/cli/index.js
CHANGED
|
@@ -3512,7 +3512,7 @@ var SDK_RELEASE = {
|
|
|
3512
3512
|
// getters keep their established compatibility behavior.
|
|
3513
3513
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3514
3514
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3515
|
-
version: "0.3.
|
|
3515
|
+
version: "0.3.278",
|
|
3516
3516
|
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.",
|
|
3517
3517
|
packageCapabilities: {
|
|
3518
3518
|
updatePreferences: 1
|
|
@@ -13502,12 +13502,14 @@ async function handleTopUpRecover(creditsRaw, options) {
|
|
|
13502
13502
|
);
|
|
13503
13503
|
}
|
|
13504
13504
|
async function handleTargetPlan(planSku, options) {
|
|
13505
|
-
if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "growth-v1" &&
|
|
13505
|
+
if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "growth-v1" && // Retained Canary requests may replay their original operation. The API
|
|
13506
|
+
// rejects new acquisition even when a caller supplies an idempotency key.
|
|
13507
|
+
!(planSku === "growth-canary-v1" && options.idempotencyKey) && planSku !== "team-v1") {
|
|
13506
13508
|
reportBillingFailure(
|
|
13507
13509
|
{
|
|
13508
13510
|
exitCode: 2,
|
|
13509
13511
|
code: "INVALID_PLAN",
|
|
13510
|
-
message: "Plan must be payg-v1, builder-v1, growth-v1,
|
|
13512
|
+
message: "Plan must be payg-v1, builder-v1, growth-v1, or team-v1."
|
|
13511
13513
|
},
|
|
13512
13514
|
options
|
|
13513
13515
|
);
|
|
@@ -13818,10 +13820,7 @@ Examples:
|
|
|
13818
13820
|
printCommandEnvelope({ ok: true, ...result }, { json: options.json });
|
|
13819
13821
|
})
|
|
13820
13822
|
);
|
|
13821
|
-
billing.command("change-plan").description("Start or change the target billing plan.").argument(
|
|
13822
|
-
"<plan_sku>",
|
|
13823
|
-
"payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1"
|
|
13824
|
-
).option(
|
|
13823
|
+
billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, growth-v1, or team-v1").option(
|
|
13825
13824
|
"--billing-email <email>",
|
|
13826
13825
|
"Invoice recipient when the account has no billing email"
|
|
13827
13826
|
).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
|
package/dist/cli/index.mjs
CHANGED
|
@@ -3507,7 +3507,7 @@ var SDK_RELEASE = {
|
|
|
3507
3507
|
// getters keep their established compatibility behavior.
|
|
3508
3508
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
3509
3509
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
3510
|
-
version: "0.3.
|
|
3510
|
+
version: "0.3.278",
|
|
3511
3511
|
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.",
|
|
3512
3512
|
packageCapabilities: {
|
|
3513
3513
|
updatePreferences: 1
|
|
@@ -13509,12 +13509,14 @@ async function handleTopUpRecover(creditsRaw, options) {
|
|
|
13509
13509
|
);
|
|
13510
13510
|
}
|
|
13511
13511
|
async function handleTargetPlan(planSku, options) {
|
|
13512
|
-
if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "growth-v1" &&
|
|
13512
|
+
if (planSku !== "payg-v1" && planSku !== "builder-v1" && planSku !== "growth-v1" && // Retained Canary requests may replay their original operation. The API
|
|
13513
|
+
// rejects new acquisition even when a caller supplies an idempotency key.
|
|
13514
|
+
!(planSku === "growth-canary-v1" && options.idempotencyKey) && planSku !== "team-v1") {
|
|
13513
13515
|
reportBillingFailure(
|
|
13514
13516
|
{
|
|
13515
13517
|
exitCode: 2,
|
|
13516
13518
|
code: "INVALID_PLAN",
|
|
13517
|
-
message: "Plan must be payg-v1, builder-v1, growth-v1,
|
|
13519
|
+
message: "Plan must be payg-v1, builder-v1, growth-v1, or team-v1."
|
|
13518
13520
|
},
|
|
13519
13521
|
options
|
|
13520
13522
|
);
|
|
@@ -13825,10 +13827,7 @@ Examples:
|
|
|
13825
13827
|
printCommandEnvelope({ ok: true, ...result }, { json: options.json });
|
|
13826
13828
|
})
|
|
13827
13829
|
);
|
|
13828
|
-
billing.command("change-plan").description("Start or change the target billing plan.").argument(
|
|
13829
|
-
"<plan_sku>",
|
|
13830
|
-
"payg-v1, builder-v1, growth-v1, growth-canary-v1, or team-v1"
|
|
13831
|
-
).option(
|
|
13830
|
+
billing.command("change-plan").description("Start or change the target billing plan.").argument("<plan_sku>", "payg-v1, builder-v1, growth-v1, or team-v1").option(
|
|
13832
13831
|
"--billing-email <email>",
|
|
13833
13832
|
"Invoice recipient when the account has no billing email"
|
|
13834
13833
|
).option("--idempotency-key <key>", "Stable retry key").option("--json", "Emit JSON output").action(handleTargetPlan);
|
package/dist/index.js
CHANGED
|
@@ -1325,7 +1325,7 @@ var SDK_RELEASE = {
|
|
|
1325
1325
|
// getters keep their established compatibility behavior.
|
|
1326
1326
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1327
1327
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1328
|
-
version: "0.3.
|
|
1328
|
+
version: "0.3.278",
|
|
1329
1329
|
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.",
|
|
1330
1330
|
packageCapabilities: {
|
|
1331
1331
|
updatePreferences: 1
|
package/dist/index.mjs
CHANGED
|
@@ -1229,7 +1229,7 @@ var SDK_RELEASE = {
|
|
|
1229
1229
|
// getters keep their established compatibility behavior.
|
|
1230
1230
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1231
1231
|
// 0.3.90 is the first deliberately versioned SDK release for API v3.
|
|
1232
|
-
version: "0.3.
|
|
1232
|
+
version: "0.3.278",
|
|
1233
1233
|
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.",
|
|
1234
1234
|
packageCapabilities: {
|
|
1235
1235
|
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.278";
|
|
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.278";
|
|
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.278",
|
|
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.278",
|
|
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
|