deepline 0.3.221 → 0.3.222

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.
@@ -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.221',
203
+ version: '0.3.222',
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: {
@@ -52,8 +52,10 @@ import { PLAY_RUNTIME_API_COMPAT_PATH } from './/runtime-api-paths';
52
52
  import {
53
53
  buildRunLedgerEventsIdempotencyKey,
54
54
  isRunLedgerProjectionLeaseLostReason,
55
+ type RunLedgerProjectionChunk,
55
56
  type RunLedgerProjectionLeaseLostReason,
56
57
  } from './run-ledger-projection-contract';
58
+ import { partitionRunEventsForAppRuntime } from './run-ledger-event-transport';
57
59
  import {
58
60
  RUNTIME_API_ACCEPTS_HEADER,
59
61
  gzipRuntimeApiRequestBody,
@@ -79,6 +81,8 @@ import {
79
81
  type RuntimeTrafficPolicy,
80
82
  } from './/runtime-traffic-policy';
81
83
 
84
+ export type { RunLedgerProjectionChunk } from './run-ledger-projection-contract';
85
+
82
86
  export type StoredPlayArtifactPayload = {
83
87
  sourceCode: string;
84
88
  codeFormat: 'function' | 'cjs_module' | 'esm_module';
@@ -170,6 +174,7 @@ type RuntimeApiRequest =
170
174
  idempotencyKey?: string;
171
175
  deliveryIdempotencyKey?: string;
172
176
  deliveryLeaseOwner?: string;
177
+ projectionChunk?: RunLedgerProjectionChunk;
173
178
  }
174
179
  | {
175
180
  action: 'start_run';
@@ -499,9 +504,8 @@ const runStatusUpdateChains = new Map<string, Promise<void>>();
499
504
  const receiptClaimResponseTimeoutFaults = new Map<string, number>();
500
505
  const receiptClaimQueryHoldFaults = new Set<string>();
501
506
  const RECEIPT_CLAIM_RESPONSE_TIMEOUT_FAULT_LIMIT = 1_000;
502
- const APP_RUNTIME_LOG_EVENT_MAX_JSON_BYTES = 128 * 1024;
503
- const APP_RUNTIME_EVENT_BATCH_MAX_JSON_BYTES = 512 * 1024;
504
- const appRuntimeTextEncoder = new TextEncoder();
507
+
508
+ export { partitionRunEventsForAppRuntime } from './run-ledger-event-transport';
505
509
 
506
510
  function shouldSuppressBulkClaimResponse(input: {
507
511
  body: RuntimeApiRequest;
@@ -593,106 +597,6 @@ async function suppressBulkClaimResponseUntilTimeout(
593
597
  });
594
598
  }
595
599
 
596
- function isRecord(value: unknown): value is Record<string, unknown> {
597
- return Boolean(value && typeof value === 'object' && !Array.isArray(value));
598
- }
599
-
600
- function splitRunEventForAppRuntime(
601
- event: PlayRunLedgerIngressEvent,
602
- ): PlayRunLedgerIngressEvent[] {
603
- const eventType =
604
- typeof event.key === 'string'
605
- ? event.key
606
- : typeof event.type === 'string'
607
- ? event.type
608
- : null;
609
- const payload = isRecord(event.payload) ? event.payload : null;
610
- const payloadLines = payload?.lines;
611
- const payloadOwnsLines = Array.isArray(payloadLines);
612
- const rawLines = payloadOwnsLines ? payloadLines : event.lines;
613
- const lines = Array.isArray(rawLines)
614
- ? rawLines.filter((line): line is string => typeof line === 'string')
615
- : [];
616
- if (eventType !== 'log.appended' || lines.length === 0) return [event];
617
- const payloadChannelOffset =
618
- typeof payload?.channelOffset === 'number'
619
- ? payload.channelOffset
620
- : undefined;
621
- const eventChannelOffset =
622
- typeof event.channelOffset === 'number' ? event.channelOffset : undefined;
623
- const split: PlayRunLedgerIngressEvent[] = [];
624
- const { lines: _outerLines, ...eventWithoutOuterLines } = event;
625
- let index = 0;
626
- while (index < lines.length) {
627
- const start = index;
628
- let bytes = 2;
629
- while (index < lines.length) {
630
- const lineBytes = appRuntimeTextEncoder.encode(
631
- JSON.stringify(lines[index]!),
632
- ).length;
633
- if (
634
- index > start &&
635
- bytes + lineBytes + 1 > APP_RUNTIME_LOG_EVENT_MAX_JSON_BYTES
636
- ) {
637
- break;
638
- }
639
- bytes += lineBytes + 1;
640
- index += 1;
641
- }
642
- const batchLines = lines.slice(start, index);
643
- split.push(
644
- payload
645
- ? {
646
- ...eventWithoutOuterLines,
647
- ...(payloadOwnsLines ? {} : { lines: batchLines }),
648
- payload: {
649
- ...payload,
650
- ...(payloadOwnsLines ? { lines: batchLines } : {}),
651
- ...(payloadChannelOffset === undefined
652
- ? {}
653
- : { channelOffset: payloadChannelOffset + start }),
654
- },
655
- ...(eventChannelOffset === undefined
656
- ? {}
657
- : { channelOffset: eventChannelOffset + start }),
658
- }
659
- : {
660
- ...event,
661
- lines: batchLines,
662
- ...(eventChannelOffset === undefined
663
- ? {}
664
- : { channelOffset: eventChannelOffset + start }),
665
- },
666
- );
667
- }
668
- return split;
669
- }
670
-
671
- export function partitionRunEventsForAppRuntime(
672
- events: readonly PlayRunLedgerIngressEvent[],
673
- ): PlayRunLedgerIngressEvent[][] {
674
- const batches: PlayRunLedgerIngressEvent[][] = [];
675
- let current: PlayRunLedgerIngressEvent[] = [];
676
- let currentBytes = 2;
677
- for (const event of events.flatMap(splitRunEventForAppRuntime)) {
678
- const eventBytes = appRuntimeTextEncoder.encode(
679
- JSON.stringify(event),
680
- ).length;
681
- if (
682
- current.length > 0 &&
683
- currentBytes + eventBytes + 1 > APP_RUNTIME_EVENT_BATCH_MAX_JSON_BYTES
684
- ) {
685
- batches.push(current);
686
- current = [];
687
- currentBytes = 2;
688
- }
689
- current.push(event);
690
- currentBytes += eventBytes + 1;
691
- }
692
- if (current.length > 0) batches.push(current);
693
- return batches;
694
- }
695
-
696
600
  async function appendRunEventBatchesViaAppRuntime(
697
601
  context: WorkerRuntimeApiContext,
698
602
  input: { playId: string; events: readonly PlayRunLedgerEvent[] },
@@ -2436,6 +2340,9 @@ export async function projectRunEventsViaAppRuntime(
2436
2340
  idempotencyKey,
2437
2341
  deliveryIdempotencyKey: input.idempotencyKey,
2438
2342
  deliveryLeaseOwner: input.deliveryLeaseOwner,
2343
+ ...(batches.length > 1
2344
+ ? { projectionChunk: { index, count: batches.length } }
2345
+ : {}),
2439
2346
  };
2440
2347
  // The durable outbox owns recovery; this helper does not retry OCCs or
2441
2348
  // other delivery failures inside an already-leased invocation.
@@ -0,0 +1,110 @@
1
+ import type { PlayRunLedgerIngressEvent } from './run-ledger';
2
+
3
+ const APP_RUNTIME_LOG_EVENT_MAX_JSON_BYTES = 128 * 1024;
4
+ const APP_RUNTIME_EVENT_BATCH_MAX_JSON_BYTES = 512 * 1024;
5
+ const appRuntimeTextEncoder = new TextEncoder();
6
+
7
+ function isRecord(value: unknown): value is Record<string, unknown> {
8
+ return Boolean(value && typeof value === 'object' && !Array.isArray(value));
9
+ }
10
+
11
+ function splitRunEventForAppRuntime(
12
+ event: PlayRunLedgerIngressEvent,
13
+ ): PlayRunLedgerIngressEvent[] {
14
+ const eventType =
15
+ typeof event.key === 'string'
16
+ ? event.key
17
+ : typeof event.type === 'string'
18
+ ? event.type
19
+ : null;
20
+ const payload = isRecord(event.payload) ? event.payload : null;
21
+ const payloadLines = payload?.lines;
22
+ const payloadOwnsLines = Array.isArray(payloadLines);
23
+ const rawLines = payloadOwnsLines ? payloadLines : event.lines;
24
+ const lines = Array.isArray(rawLines)
25
+ ? rawLines.filter((line): line is string => typeof line === 'string')
26
+ : [];
27
+ if (eventType !== 'log.appended' || lines.length === 0) return [event];
28
+ const payloadChannelOffset =
29
+ typeof payload?.channelOffset === 'number'
30
+ ? payload.channelOffset
31
+ : undefined;
32
+ const eventChannelOffset =
33
+ typeof event.channelOffset === 'number' ? event.channelOffset : undefined;
34
+ const split: PlayRunLedgerIngressEvent[] = [];
35
+ const { lines: _outerLines, ...eventWithoutOuterLines } = event;
36
+ let index = 0;
37
+ while (index < lines.length) {
38
+ const start = index;
39
+ let bytes = 2;
40
+ while (index < lines.length) {
41
+ const lineBytes = appRuntimeTextEncoder.encode(
42
+ JSON.stringify(lines[index]!),
43
+ ).length;
44
+ if (
45
+ index > start &&
46
+ bytes + lineBytes + 1 > APP_RUNTIME_LOG_EVENT_MAX_JSON_BYTES
47
+ ) {
48
+ break;
49
+ }
50
+ bytes += lineBytes + 1;
51
+ index += 1;
52
+ }
53
+ const batchLines = lines.slice(start, index);
54
+ split.push(
55
+ payload
56
+ ? {
57
+ ...eventWithoutOuterLines,
58
+ ...(payloadOwnsLines ? {} : { lines: batchLines }),
59
+ payload: {
60
+ ...payload,
61
+ ...(payloadOwnsLines ? { lines: batchLines } : {}),
62
+ ...(payloadChannelOffset === undefined
63
+ ? {}
64
+ : { channelOffset: payloadChannelOffset + start }),
65
+ },
66
+ ...(eventChannelOffset === undefined
67
+ ? {}
68
+ : { channelOffset: eventChannelOffset + start }),
69
+ }
70
+ : {
71
+ ...event,
72
+ lines: batchLines,
73
+ ...(eventChannelOffset === undefined
74
+ ? {}
75
+ : { channelOffset: eventChannelOffset + start }),
76
+ },
77
+ );
78
+ }
79
+ return split;
80
+ }
81
+
82
+ /**
83
+ * Reproduce the exact event and byte boundaries used by the App Runtime API.
84
+ * The outbox lease verifier uses this same function to validate each chunk
85
+ * against its canonical event prefix before accepting a projection.
86
+ */
87
+ export function partitionRunEventsForAppRuntime(
88
+ events: readonly PlayRunLedgerIngressEvent[],
89
+ ): PlayRunLedgerIngressEvent[][] {
90
+ const batches: PlayRunLedgerIngressEvent[][] = [];
91
+ let current: PlayRunLedgerIngressEvent[] = [];
92
+ let currentBytes = 2;
93
+ for (const event of events.flatMap(splitRunEventForAppRuntime)) {
94
+ const eventBytes = appRuntimeTextEncoder.encode(
95
+ JSON.stringify(event),
96
+ ).length;
97
+ if (
98
+ current.length > 0 &&
99
+ currentBytes + eventBytes + 1 > APP_RUNTIME_EVENT_BATCH_MAX_JSON_BYTES
100
+ ) {
101
+ batches.push(current);
102
+ current = [];
103
+ currentBytes = 2;
104
+ }
105
+ current.push(event);
106
+ currentBytes += eventBytes + 1;
107
+ }
108
+ if (current.length > 0) batches.push(current);
109
+ return batches;
110
+ }
@@ -10,6 +10,29 @@ const UUID_PATTERN =
10
10
  /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
11
11
  const SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;
12
12
 
13
+ /** Identifies one bounded transport piece of a canonical outbox projection. */
14
+ export type RunLedgerProjectionChunk = {
15
+ index: number;
16
+ count: number;
17
+ };
18
+
19
+ /** Shared wire validation for the app route and the outbox lease verifier. */
20
+ export function isRunLedgerProjectionChunk(
21
+ value: unknown,
22
+ ): value is RunLedgerProjectionChunk {
23
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
24
+ return false;
25
+ }
26
+ const candidate = value as Record<string, unknown>;
27
+ return (
28
+ Number.isSafeInteger(candidate.index) &&
29
+ Number.isSafeInteger(candidate.count) &&
30
+ Number(candidate.index) >= 0 &&
31
+ Number(candidate.count) > 1 &&
32
+ Number(candidate.index) < Number(candidate.count)
33
+ );
34
+ }
35
+
13
36
  export const RUN_LEDGER_PROJECTION_LEASE_LOST_REASONS = [
14
37
  'delivery_lease_not_current',
15
38
  'head_lease_missing',
@@ -94,11 +94,14 @@ import {
94
94
  } from '../log-provenance';
95
95
  import {
96
96
  buildRunLedgerEventsIdempotencyKey,
97
+ isRunLedgerProjectionChunk,
97
98
  RunLedgerProjectionLeaseLostError,
99
+ type RunLedgerProjectionChunk,
98
100
  type RunLedgerProjectionLeaseLostReason,
99
101
  buildRunLedgerStartIdempotencyKey,
100
102
  buildRunLedgerTerminalIdempotencyKey,
101
103
  } from '../run-ledger-projection-contract';
104
+ import { partitionRunEventsForAppRuntime } from '../run-ledger-event-transport';
102
105
  import {
103
106
  assertTerminalRunResultWithinLimit,
104
107
  isLedgerTerminalResultRef,
@@ -16026,6 +16029,7 @@ export async function assertPostgresRunLedgerDelivery(
16026
16029
  idempotencyKey: string;
16027
16030
  leaseOwner?: string;
16028
16031
  projectedEvents?: readonly AcceptedPlayRunLedgerEvent[];
16032
+ projectionChunk?: RunLedgerProjectionChunk;
16029
16033
  normalizeProjectedEvents?: (
16030
16034
  events: readonly PlayRunLedgerIngressEvent[],
16031
16035
  ) => readonly AcceptedPlayRunLedgerEvent[];
@@ -16165,10 +16169,24 @@ export async function assertPostgresRunLedgerDelivery(
16165
16169
  )[] = input.normalizeProjectedEvents
16166
16170
  ? input.normalizeProjectedEvents(prefixEvents)
16167
16171
  : prefixEvents;
16172
+ let expectedProjectionEvents:
16173
+ | readonly (AcceptedPlayRunLedgerEvent | PlayRunLedgerIngressEvent)[]
16174
+ | undefined = comparablePrefixEvents;
16175
+ if (input.projectionChunk) {
16176
+ const chunk = input.projectionChunk;
16177
+ const chunks = isRunLedgerProjectionChunk(chunk)
16178
+ ? partitionRunEventsForAppRuntime(
16179
+ comparablePrefixEvents as readonly PlayRunLedgerIngressEvent[],
16180
+ )
16181
+ : [];
16182
+ expectedProjectionEvents =
16183
+ chunks.length === chunk.count ? chunks[chunk.index] : undefined;
16184
+ }
16168
16185
  if (
16186
+ expectedProjectionEvents !== undefined &&
16169
16187
  runLedgerProjectionMatchesCanonicalPrefix(
16170
16188
  input.projectedEvents,
16171
- comparablePrefixEvents,
16189
+ expectedProjectionEvents,
16172
16190
  )
16173
16191
  ) {
16174
16192
  return;
package/dist/cli/index.js CHANGED
@@ -3051,7 +3051,7 @@ var SDK_RELEASE = {
3051
3051
  // getters keep their established compatibility behavior.
3052
3052
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3053
3053
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3054
- version: "0.3.221",
3054
+ version: "0.3.222",
3055
3055
  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.",
3056
3056
  packageCapabilities: {
3057
3057
  updatePreferences: 1
@@ -3046,7 +3046,7 @@ var SDK_RELEASE = {
3046
3046
  // getters keep their established compatibility behavior.
3047
3047
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3048
3048
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3049
- version: "0.3.221",
3049
+ version: "0.3.222",
3050
3050
  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.",
3051
3051
  packageCapabilities: {
3052
3052
  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.221",
867
+ version: "0.3.222",
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.221",
771
+ version: "0.3.222",
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
@@ -293,6 +293,7 @@
293
293
  "dist/bundling-sources/shared_libs/play-runtime/run-execution-scope.ts",
294
294
  "dist/bundling-sources/shared_libs/play-runtime/run-failure.ts",
295
295
  "dist/bundling-sources/shared_libs/play-runtime/run-identity.ts",
296
+ "dist/bundling-sources/shared_libs/play-runtime/run-ledger-event-transport.ts",
296
297
  "dist/bundling-sources/shared_libs/play-runtime/run-ledger-projection-contract.ts",
297
298
  "dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts",
298
299
  "dist/bundling-sources/shared_libs/play-runtime/run-lifecycle-policy.ts",
@@ -149,7 +149,7 @@ type SdkRelease = {
149
149
  supportPolicy: SdkSupportPolicy;
150
150
  };
151
151
  declare const SDK_RELEASE: {
152
- readonly version: "0.3.221";
152
+ readonly version: "0.3.222";
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.221";
152
+ readonly version: "0.3.222";
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.221",
77
+ version: "0.3.222",
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.221",
51
+ version: "0.3.222",
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.3.221",
3
+ "version": "0.3.222",
4
4
  "description": "GTM data CLI and TypeScript SDK for coding agents",
5
5
  "license": "MIT",
6
6
  "homepage": "https://code.deepline.com",