deepline 0.3.343 → 0.3.345
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/runner-app/index.ts +9 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +240 -66
- package/dist/bundling-sources/shared_libs/plays/csv-text-repair.ts +145 -0
- package/dist/cli/auth-4HCZZPZH.js +31 -0
- package/dist/cli/{auth-IPOSX2NV.mjs → auth-YQSQYS2V.mjs} +4 -4
- package/dist/cli/{billing-CWTZDAOC.mjs → billing-HA75G3SK.mjs} +4 -4
- package/dist/cli/{billing-ZZKX4IFS.js → billing-JRP2ZFMV.js} +71 -71
- package/dist/cli/{chunk-JGW7AR5N.js → chunk-2OTDDG2J.js} +2 -2
- package/dist/cli/{chunk-UJFBO6QV.mjs → chunk-3XKBPPP7.mjs} +2 -2
- package/dist/cli/{chunk-ELZ4HEPQ.js → chunk-4INBT3OR.js} +225 -225
- package/dist/cli/{chunk-CVIAYYLR.mjs → chunk-5QPHJFNN.mjs} +2 -2
- package/dist/cli/{chunk-RB2ELEQ5.mjs → chunk-AW2G44QA.mjs} +4 -4
- package/dist/cli/{chunk-ZQFYR6NT.mjs → chunk-DOPNLW2H.mjs} +6 -6
- package/dist/cli/{chunk-FM36CTMM.js → chunk-EEPFLZ7V.js} +9 -9
- package/dist/cli/{chunk-U5L6FIIL.mjs → chunk-EWYAS4WD.mjs} +1 -1
- package/dist/cli/{chunk-ERFIHZXT.js → chunk-FBUWH67Y.js} +48 -48
- package/dist/cli/{chunk-XOX3Y5OP.js → chunk-FDH572QX.js} +45 -45
- package/dist/cli/{chunk-LY33N2W6.mjs → chunk-GGRQBO3S.mjs} +2 -2
- package/dist/cli/{chunk-JS7JVUZZ.js → chunk-IT6MAYZ3.js} +8 -8
- package/dist/cli/{chunk-IPEE3DIV.js → chunk-ITOJRSOU.js} +112 -24
- package/dist/cli/{chunk-W6LB26RC.mjs → chunk-JDSRPSES.mjs} +1 -1
- package/dist/cli/{chunk-RDXH4KXG.js → chunk-KXFPDFUO.js} +26 -26
- package/dist/cli/{chunk-QV2WIEUP.mjs → chunk-MLO7ZGSH.mjs} +2 -2
- package/dist/cli/{chunk-AUB3AW3P.js → chunk-MO6QJPEB.js} +4 -4
- package/dist/cli/{chunk-WBXTRZAX.mjs → chunk-N3GUUSDO.mjs} +1 -1
- package/dist/cli/{chunk-2Y2QZJBT.mjs → chunk-NTIWTBEH.mjs} +94 -6
- package/dist/cli/{chunk-KLEZD6JX.mjs → chunk-S3JKJL44.mjs} +5 -5
- package/dist/cli/{chunk-DEDNTNXS.mjs → chunk-TAX3OOC6.mjs} +1 -1
- package/dist/cli/{chunk-ZGIXGBKF.js → chunk-TDW3RU7S.js} +15 -15
- package/dist/cli/{chunk-FSNKEEBA.js → chunk-UJCHR3J3.js} +1 -1
- package/dist/cli/{chunk-63UBRDGC.js → chunk-URPZWUVN.js} +60 -60
- package/dist/cli/{chunk-BCF43TLG.js → chunk-WRTLSH6R.js} +8 -8
- package/dist/cli/{chunk-GISYO3JA.mjs → chunk-YGQ4AIK7.mjs} +3 -3
- package/dist/cli/{client-7ZUYHDCL.mjs → client-VKQGBPZ5.mjs} +3 -3
- package/dist/cli/client-VOXK5Z4D.js +20 -0
- package/dist/cli/{csv-7BL43EOB.js → csv-UNP7KAXF.js} +12 -12
- package/dist/cli/{csv-6CFRU4CQ.mjs → csv-ZFMAI2HY.mjs} +3 -3
- package/dist/cli/{db-RUKRHPBV.mjs → db-C5YWXRLY.mjs} +4 -4
- package/dist/cli/{db-EJETRBBT.js → db-LDLXC2JQ.js} +29 -29
- package/dist/cli/{describe-N46DGDQ4.js → describe-FO62H2CB.js} +15 -15
- package/dist/cli/{describe-AVBCGKX4.mjs → describe-UYNKJV6T.mjs} +8 -8
- package/dist/cli/{executions-OPBBBSDT.js → executions-DIADSK2E.js} +6 -6
- package/dist/cli/{executions-FCTCQYY3.mjs → executions-JYKV3GQJ.mjs} +4 -4
- package/dist/cli/{feedback-XY7F7FF6.mjs → feedback-4UEJJFRL.mjs} +3 -3
- package/dist/cli/{feedback-RSPSGS2W.js → feedback-YBO47O7G.js} +7 -7
- package/dist/cli/{git-ZQ534TRG.mjs → git-A6DPLCMU.mjs} +4 -4
- package/dist/cli/git-FPC5VIIK.js +23 -0
- package/dist/cli/index.js +79 -79
- package/dist/cli/index.mjs +31 -31
- package/dist/cli/{legacy-noops-WCLAYQNO.js → legacy-noops-F6TJLZV2.js} +7 -7
- package/dist/cli/{legacy-noops-S4Q4TBKQ.mjs → legacy-noops-HCAOJI7X.mjs} +4 -4
- package/dist/cli/{monitors-UD6C7YUQ.js → monitors-B5QFSFK7.js} +85 -85
- package/dist/cli/{monitors-7EONZILI.mjs → monitors-XYP7XNCT.mjs} +4 -4
- package/dist/cli/{org-EGED4FVT.js → org-NMWNBQZI.js} +60 -60
- package/dist/cli/{org-SPZF2UBU.mjs → org-O5VBVLSP.mjs} +4 -4
- package/dist/cli/play-D2SCAJXG.js +153 -0
- package/dist/cli/{play-KXWJX7RB.mjs → play-Z2STHYQB.mjs} +7 -7
- package/dist/cli/{providers-HWGPSJZ7.js → providers-BAPO54GE.js} +7 -7
- package/dist/cli/{providers-P2MRBKX2.mjs → providers-WGIJLFBZ.mjs} +4 -4
- package/dist/cli/{quickstart-CL4AB46M.js → quickstart-JGRMJ6M4.js} +5 -5
- package/dist/cli/{quickstart-VEEHUU7O.mjs → quickstart-LL6KUMJ5.mjs} +3 -3
- package/dist/cli/{search-D7CLJLVU.mjs → search-P7BVN4OI.mjs} +5 -5
- package/dist/cli/search-UNJN5P72.js +26 -0
- package/dist/cli/{secrets-ZDW4MTJL.mjs → secrets-5JHLILQD.mjs} +4 -4
- package/dist/cli/{secrets-NGB5OD2W.js → secrets-QUBFPBE5.js} +13 -13
- package/dist/cli/{sessions-HYUYIAHB.mjs → sessions-3BYS3WQZ.mjs} +4 -4
- package/dist/cli/{sessions-MTN3SBTL.js → sessions-TATDTEY6.js} +5 -5
- package/dist/cli/{settings-X43X7H54.js → settings-SLFYXPRP.js} +74 -74
- package/dist/cli/{settings-RMABGZ6N.mjs → settings-TXWQLO34.mjs} +7 -7
- package/dist/cli/{setup-QEM6U5TO.js → setup-A3CXCYRI.js} +41 -41
- package/dist/cli/{setup-N7KUH3AM.mjs → setup-XTAW2JS2.mjs} +6 -6
- package/dist/cli/{skills-H3STANPK.mjs → skills-P323CMPH.mjs} +4 -4
- package/dist/cli/skills-ZOUUC72T.js +28 -0
- package/dist/cli/{tools-FSEOJNTY.mjs → tools-FMSH7Z7I.mjs} +6 -6
- package/dist/cli/tools-O7TLYHFT.js +40 -0
- package/dist/cli/update-3LT6YSIP.js +28 -0
- package/dist/cli/{update-6BUK4OLS.mjs → update-CGKRTVOD.mjs} +6 -6
- package/dist/cli/{workflow-Q7RJGAKL.mjs → workflow-2DVIYBLG.mjs} +5 -5
- package/dist/cli/{workflow-4GZCYDZS.js → workflow-EFOSJKW7.js} +15 -15
- package/dist/index.js +6 -6
- package/dist/index.mjs +3 -3
- package/dist/install-integrity.json +75 -74
- package/dist/release.d.mts +1 -1
- package/dist/release.d.ts +1 -1
- package/dist/release.js +2 -2
- package/dist/release.mjs +1 -1
- package/package.json +1 -1
- package/dist/cli/auth-J2C5CQ7M.js +0 -31
- package/dist/cli/client-CCDQC7ZY.js +0 -20
- package/dist/cli/git-DZTOBIUF.js +0 -23
- package/dist/cli/play-5MDIQGCF.js +0 -153
- package/dist/cli/search-6H77HQL3.js +0 -26
- package/dist/cli/skills-7H2OD626.js +0 -28
- package/dist/cli/tools-UYW5T5PU.js +0 -40
- package/dist/cli/update-K743Q4EF.js +0 -28
|
@@ -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.345',
|
|
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: {
|
|
@@ -10,6 +10,7 @@ import { compileFunction } from 'node:vm';
|
|
|
10
10
|
import { gunzipSync } from 'node:zlib';
|
|
11
11
|
import { Readable } from 'node:stream';
|
|
12
12
|
import { parse } from 'csv-parse';
|
|
13
|
+
import { csvInputTextOptions } from '../../plays/csv-text-repair';
|
|
13
14
|
import { install as installSourceMapSupport } from 'source-map-support';
|
|
14
15
|
import {
|
|
15
16
|
createDeferredPlayDataset,
|
|
@@ -1559,7 +1560,14 @@ async function emitAndExit(
|
|
|
1559
1560
|
function parseCsvStream(
|
|
1560
1561
|
source: NodeJS.ReadableStream,
|
|
1561
1562
|
): AsyncIterable<Record<string, unknown>> {
|
|
1562
|
-
|
|
1563
|
+
// Every Play's CSV input passes through here, so this is where a customer
|
|
1564
|
+
// file's BOM and mis-decoded UTF-8 ("j̩r̫me", "o’malley") get fixed before
|
|
1565
|
+
// any row reaches a provider. See ../../plays/csv-text-repair.
|
|
1566
|
+
const parser = parse({
|
|
1567
|
+
...csvInputTextOptions(),
|
|
1568
|
+
skip_empty_lines: true,
|
|
1569
|
+
trim: true,
|
|
1570
|
+
});
|
|
1563
1571
|
// `Readable.pipe()` does not forward source errors to the destination. A
|
|
1564
1572
|
// missing staged file therefore used to emit an unhandled `error` from
|
|
1565
1573
|
// createReadStream and kill the Daytona process outside main().catch().
|
|
@@ -520,6 +520,68 @@ export type RuntimeSheetTiming = {
|
|
|
520
520
|
error?: string;
|
|
521
521
|
};
|
|
522
522
|
|
|
523
|
+
type RuntimeMapCompletionPhase =
|
|
524
|
+
| 'dbSessionAcquire'
|
|
525
|
+
| 'poolAcquire'
|
|
526
|
+
| 'transactionBegin'
|
|
527
|
+
| 'mapRowsUpdate'
|
|
528
|
+
| 'missingRowsInsert'
|
|
529
|
+
| 'failedRowsUpdate'
|
|
530
|
+
| 'transactionCommit'
|
|
531
|
+
| 'queryClient';
|
|
532
|
+
|
|
533
|
+
type RuntimeMapCompletionDiagnostics = Record<
|
|
534
|
+
`${RuntimeMapCompletionPhase}Ms` | `${RuntimeMapCompletionPhase}Failures`,
|
|
535
|
+
number
|
|
536
|
+
> & {
|
|
537
|
+
operationAttempts: number;
|
|
538
|
+
provisioningRetryAttempts: number;
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
function createRuntimeMapCompletionDiagnostics(): RuntimeMapCompletionDiagnostics {
|
|
542
|
+
return {
|
|
543
|
+
dbSessionAcquireMs: 0,
|
|
544
|
+
dbSessionAcquireFailures: 0,
|
|
545
|
+
poolAcquireMs: 0,
|
|
546
|
+
poolAcquireFailures: 0,
|
|
547
|
+
transactionBeginMs: 0,
|
|
548
|
+
transactionBeginFailures: 0,
|
|
549
|
+
mapRowsUpdateMs: 0,
|
|
550
|
+
mapRowsUpdateFailures: 0,
|
|
551
|
+
missingRowsInsertMs: 0,
|
|
552
|
+
missingRowsInsertFailures: 0,
|
|
553
|
+
failedRowsUpdateMs: 0,
|
|
554
|
+
failedRowsUpdateFailures: 0,
|
|
555
|
+
transactionCommitMs: 0,
|
|
556
|
+
transactionCommitFailures: 0,
|
|
557
|
+
queryClientMs: 0,
|
|
558
|
+
queryClientFailures: 0,
|
|
559
|
+
operationAttempts: 0,
|
|
560
|
+
provisioningRetryAttempts: 0,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async function measureRuntimeSheetPhase<T>(
|
|
565
|
+
diagnostics: RuntimeMapCompletionDiagnostics | undefined,
|
|
566
|
+
phase: RuntimeMapCompletionPhase,
|
|
567
|
+
operation: () => Promise<T>,
|
|
568
|
+
): Promise<T> {
|
|
569
|
+
if (!diagnostics) return await operation();
|
|
570
|
+
const startedAt = Date.now();
|
|
571
|
+
let failed = false;
|
|
572
|
+
try {
|
|
573
|
+
return await operation();
|
|
574
|
+
} catch (error) {
|
|
575
|
+
failed = true;
|
|
576
|
+
throw error;
|
|
577
|
+
} finally {
|
|
578
|
+
const msKey = `${phase}Ms` as const;
|
|
579
|
+
const failuresKey = `${phase}Failures` as const;
|
|
580
|
+
diagnostics[msKey] += Date.now() - startedAt;
|
|
581
|
+
diagnostics[failuresKey] += Number(failed);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
523
585
|
export type RuntimeSheetAttemptHeartbeatResult = {
|
|
524
586
|
renewed: number;
|
|
525
587
|
renewedKeys: string[];
|
|
@@ -2314,6 +2376,7 @@ async function withRuntimePostgres<T>(
|
|
|
2314
2376
|
maxConnectAttempts?: number;
|
|
2315
2377
|
operationTimeoutMs?: number;
|
|
2316
2378
|
signal?: AbortSignal | null;
|
|
2379
|
+
completionDiagnostics?: RuntimeMapCompletionDiagnostics;
|
|
2317
2380
|
} = {},
|
|
2318
2381
|
): Promise<T> {
|
|
2319
2382
|
let client: RuntimePoolClient | null = null;
|
|
@@ -2336,24 +2399,35 @@ async function withRuntimePostgres<T>(
|
|
|
2336
2399
|
if (!cachePool) {
|
|
2337
2400
|
requestLocalPool = pool;
|
|
2338
2401
|
}
|
|
2339
|
-
client = await
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2402
|
+
client = await measureRuntimeSheetPhase(
|
|
2403
|
+
options.completionDiagnostics,
|
|
2404
|
+
'poolAcquire',
|
|
2405
|
+
() =>
|
|
2406
|
+
connectRuntimePostgresPool(
|
|
2407
|
+
pool,
|
|
2408
|
+
admission,
|
|
2409
|
+
lane,
|
|
2410
|
+
session.postgresUrl,
|
|
2411
|
+
options.signal,
|
|
2412
|
+
),
|
|
2345
2413
|
);
|
|
2346
2414
|
operationDeadlineAt =
|
|
2347
2415
|
options.operationTimeoutMs === undefined
|
|
2348
2416
|
? null
|
|
2349
2417
|
: Date.now() + Math.max(1, Math.floor(options.operationTimeoutMs));
|
|
2350
2418
|
if (session.executionRole) {
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2419
|
+
const roleClient = client;
|
|
2420
|
+
await measureRuntimeSheetPhase(
|
|
2421
|
+
options.completionDiagnostics,
|
|
2422
|
+
'transactionBegin',
|
|
2423
|
+
() =>
|
|
2424
|
+
awaitRuntimePostgresOperation({
|
|
2425
|
+
client: roleClient,
|
|
2426
|
+
deadlineAt: operationDeadlineAt,
|
|
2427
|
+
operation: roleClient.query('BEGIN'),
|
|
2428
|
+
signal: options.signal,
|
|
2429
|
+
}),
|
|
2430
|
+
);
|
|
2357
2431
|
roleTransactionStarted = true;
|
|
2358
2432
|
await awaitRuntimePostgresOperation({
|
|
2359
2433
|
client,
|
|
@@ -2419,12 +2493,18 @@ async function withRuntimePostgres<T>(
|
|
|
2419
2493
|
signal: options.signal,
|
|
2420
2494
|
});
|
|
2421
2495
|
if (roleTransactionStarted) {
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2496
|
+
const roleClient = client;
|
|
2497
|
+
await measureRuntimeSheetPhase(
|
|
2498
|
+
options.completionDiagnostics,
|
|
2499
|
+
'transactionCommit',
|
|
2500
|
+
() =>
|
|
2501
|
+
awaitRuntimePostgresOperation({
|
|
2502
|
+
client: roleClient,
|
|
2503
|
+
deadlineAt: operationDeadlineAt,
|
|
2504
|
+
operation: roleClient.query('COMMIT'),
|
|
2505
|
+
signal: options.signal,
|
|
2506
|
+
}),
|
|
2507
|
+
);
|
|
2428
2508
|
roleTransactionStarted = false;
|
|
2429
2509
|
}
|
|
2430
2510
|
return result;
|
|
@@ -2549,10 +2629,14 @@ async function withRuntimeSheetProvisioningRetry<T>(
|
|
|
2549
2629
|
sheetContract: PlaySheetContract;
|
|
2550
2630
|
session: RuntimePostgresSession;
|
|
2551
2631
|
timings?: RuntimeSheetTiming[];
|
|
2632
|
+
completionDiagnostics?: RuntimeMapCompletionDiagnostics;
|
|
2552
2633
|
},
|
|
2553
2634
|
operation: () => Promise<T>,
|
|
2554
2635
|
): Promise<T> {
|
|
2555
2636
|
const firstAttemptStartedAt = Date.now();
|
|
2637
|
+
if (input.completionDiagnostics) {
|
|
2638
|
+
input.completionDiagnostics.operationAttempts += 1;
|
|
2639
|
+
}
|
|
2556
2640
|
try {
|
|
2557
2641
|
const result = await operation();
|
|
2558
2642
|
input.timings?.push({
|
|
@@ -2610,6 +2694,10 @@ async function withRuntimeSheetProvisioningRetry<T>(
|
|
|
2610
2694
|
} else {
|
|
2611
2695
|
throw error;
|
|
2612
2696
|
}
|
|
2697
|
+
if (input.completionDiagnostics) {
|
|
2698
|
+
input.completionDiagnostics.provisioningRetryAttempts += 1;
|
|
2699
|
+
input.completionDiagnostics.operationAttempts += 1;
|
|
2700
|
+
}
|
|
2613
2701
|
const retryStartedAt = Date.now();
|
|
2614
2702
|
const result = await operation();
|
|
2615
2703
|
input.timings?.push({
|
|
@@ -2631,11 +2719,12 @@ async function withRuntimeSheetQueryClient<T>(
|
|
|
2631
2719
|
transactional: boolean;
|
|
2632
2720
|
statementTimeoutMs?: number;
|
|
2633
2721
|
timings?: RuntimeSheetTiming[];
|
|
2722
|
+
completionDiagnostics?: RuntimeMapCompletionDiagnostics;
|
|
2634
2723
|
},
|
|
2635
2724
|
operation: (client: RuntimeQueryClient) => Promise<T>,
|
|
2636
2725
|
): Promise<T> {
|
|
2637
|
-
const
|
|
2638
|
-
const
|
|
2726
|
+
const resultStartedAt = Date.now();
|
|
2727
|
+
const resultPromise = withRuntimeSheetProvisioningRetry(
|
|
2639
2728
|
context,
|
|
2640
2729
|
{ ...input, session },
|
|
2641
2730
|
async () => {
|
|
@@ -2661,7 +2750,13 @@ async function withRuntimeSheetQueryClient<T>(
|
|
|
2661
2750
|
const managesTransaction =
|
|
2662
2751
|
(input.transactional || input.statementTimeoutMs !== undefined) &&
|
|
2663
2752
|
!transaction.active;
|
|
2664
|
-
if (managesTransaction)
|
|
2753
|
+
if (managesTransaction) {
|
|
2754
|
+
await measureRuntimeSheetPhase(
|
|
2755
|
+
input.completionDiagnostics,
|
|
2756
|
+
'transactionBegin',
|
|
2757
|
+
() => client.query('BEGIN'),
|
|
2758
|
+
);
|
|
2759
|
+
}
|
|
2665
2760
|
try {
|
|
2666
2761
|
if (input.statementTimeoutMs !== undefined) {
|
|
2667
2762
|
await client.query(
|
|
@@ -2669,7 +2764,13 @@ async function withRuntimeSheetQueryClient<T>(
|
|
|
2669
2764
|
);
|
|
2670
2765
|
}
|
|
2671
2766
|
const result = await operation(client);
|
|
2672
|
-
if (managesTransaction)
|
|
2767
|
+
if (managesTransaction) {
|
|
2768
|
+
await measureRuntimeSheetPhase(
|
|
2769
|
+
input.completionDiagnostics,
|
|
2770
|
+
'transactionCommit',
|
|
2771
|
+
() => client.query('COMMIT'),
|
|
2772
|
+
);
|
|
2773
|
+
}
|
|
2673
2774
|
return result;
|
|
2674
2775
|
} catch (error) {
|
|
2675
2776
|
if (managesTransaction) {
|
|
@@ -2687,13 +2788,22 @@ async function withRuntimeSheetQueryClient<T>(
|
|
|
2687
2788
|
? undefined
|
|
2688
2789
|
: RUNTIME_SHEET_COMPLETION_SERVER_OPERATION_TIMEOUT_MS,
|
|
2689
2790
|
signal: context.abortSignal,
|
|
2791
|
+
completionDiagnostics: input.completionDiagnostics,
|
|
2690
2792
|
},
|
|
2691
2793
|
);
|
|
2692
2794
|
},
|
|
2693
2795
|
);
|
|
2796
|
+
if (input.completionDiagnostics) {
|
|
2797
|
+
return await measureRuntimeSheetPhase(
|
|
2798
|
+
input.completionDiagnostics,
|
|
2799
|
+
'queryClient',
|
|
2800
|
+
() => resultPromise,
|
|
2801
|
+
);
|
|
2802
|
+
}
|
|
2803
|
+
const result = await resultPromise;
|
|
2694
2804
|
input.timings?.push({
|
|
2695
2805
|
phase: 'query_client_total',
|
|
2696
|
-
ms: Date.now() -
|
|
2806
|
+
ms: Date.now() - resultStartedAt,
|
|
2697
2807
|
});
|
|
2698
2808
|
return result;
|
|
2699
2809
|
}
|
|
@@ -8686,24 +8796,62 @@ export async function completeRuntimeMapRows(
|
|
|
8686
8796
|
rows: input.rows.map((row) => row.data),
|
|
8687
8797
|
outputFields: input.outputFields,
|
|
8688
8798
|
});
|
|
8689
|
-
const
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
|
|
8706
|
-
|
|
8799
|
+
const completionDiagnostics = createRuntimeMapCompletionDiagnostics();
|
|
8800
|
+
const completionStartedAt = Date.now();
|
|
8801
|
+
let completionOutcome: 'succeeded' | 'failed' = 'failed';
|
|
8802
|
+
let uniqueRowCount = 0;
|
|
8803
|
+
let completedRowCount = 0;
|
|
8804
|
+
let failedRowCount = 0;
|
|
8805
|
+
let chunkCount = 0;
|
|
8806
|
+
let updatedRowCount = 0;
|
|
8807
|
+
let fencedRowCount = 0;
|
|
8808
|
+
const logCompletion = () => {
|
|
8809
|
+
console.info(
|
|
8810
|
+
'[runtime-sheet-map-completion]',
|
|
8811
|
+
JSON.stringify({
|
|
8812
|
+
event: 'finished',
|
|
8813
|
+
outcome: completionOutcome,
|
|
8814
|
+
inputRows: input.rows.length,
|
|
8815
|
+
uniqueRows: uniqueRowCount,
|
|
8816
|
+
completedRows: completedRowCount,
|
|
8817
|
+
failedRows: failedRowCount,
|
|
8818
|
+
chunks: chunkCount,
|
|
8819
|
+
updatedRows: updatedRowCount,
|
|
8820
|
+
fencedRows: fencedRowCount,
|
|
8821
|
+
...completionDiagnostics,
|
|
8822
|
+
totalMs: Date.now() - completionStartedAt,
|
|
8823
|
+
}),
|
|
8824
|
+
);
|
|
8825
|
+
};
|
|
8826
|
+
let session: RuntimePostgresSession;
|
|
8827
|
+
try {
|
|
8828
|
+
session = await measureRuntimeSheetPhase(
|
|
8829
|
+
completionDiagnostics,
|
|
8830
|
+
'dbSessionAcquire',
|
|
8831
|
+
async () =>
|
|
8832
|
+
requireRuntimePostgresSession(
|
|
8833
|
+
await getRuntimeDbSession(
|
|
8834
|
+
{
|
|
8835
|
+
...context,
|
|
8836
|
+
playName: context.playName,
|
|
8837
|
+
runId: context.runId ?? input.runId,
|
|
8838
|
+
},
|
|
8839
|
+
{
|
|
8840
|
+
tableNamespace: input.tableNamespace,
|
|
8841
|
+
logicalTable: 'sheet_rows',
|
|
8842
|
+
operations: ['rows.read', 'rows.upsert'],
|
|
8843
|
+
limits: {
|
|
8844
|
+
maxRows: runtimeDbSessionRowLimit(input.rows.length),
|
|
8845
|
+
},
|
|
8846
|
+
sheetContract,
|
|
8847
|
+
},
|
|
8848
|
+
),
|
|
8849
|
+
),
|
|
8850
|
+
);
|
|
8851
|
+
} catch (error) {
|
|
8852
|
+
logCompletion();
|
|
8853
|
+
throw error;
|
|
8854
|
+
}
|
|
8707
8855
|
|
|
8708
8856
|
// Dedupe by key. Last write wins on payload, status, and error.
|
|
8709
8857
|
const uniqueRows = new Map<string, RuntimeApiRowRecord>();
|
|
@@ -8718,7 +8866,10 @@ export async function completeRuntimeMapRows(
|
|
|
8718
8866
|
if (!resolvedKey) continue;
|
|
8719
8867
|
uniqueRows.set(resolvedKey, { ...row, key: resolvedKey });
|
|
8720
8868
|
}
|
|
8869
|
+
uniqueRowCount = uniqueRows.size;
|
|
8721
8870
|
if (uniqueRows.size === 0) {
|
|
8871
|
+
completionOutcome = 'succeeded';
|
|
8872
|
+
logCompletion();
|
|
8722
8873
|
return classifyRuntimeMapRowsWrite({
|
|
8723
8874
|
submittedKeys: [],
|
|
8724
8875
|
updated: 0,
|
|
@@ -8735,6 +8886,9 @@ export async function completeRuntimeMapRows(
|
|
|
8735
8886
|
});
|
|
8736
8887
|
const chunks = chunkValues(completedRows, DIRECT_POSTGRES_BATCH_SIZE);
|
|
8737
8888
|
const failedChunks = chunkValues(failedRows, DIRECT_POSTGRES_BATCH_SIZE);
|
|
8889
|
+
completedRowCount = completedRows.length;
|
|
8890
|
+
failedRowCount = failedRows.length;
|
|
8891
|
+
chunkCount = chunks.length + failedChunks.length;
|
|
8738
8892
|
const needsTransaction = true;
|
|
8739
8893
|
const outputFields = [...new Set(input.outputFields ?? [])];
|
|
8740
8894
|
const attemptId = input.attemptId?.trim() || null;
|
|
@@ -8752,7 +8906,7 @@ export async function completeRuntimeMapRows(
|
|
|
8752
8906
|
);
|
|
8753
8907
|
}
|
|
8754
8908
|
|
|
8755
|
-
return
|
|
8909
|
+
return withRuntimeSheetQueryClient(
|
|
8756
8910
|
context,
|
|
8757
8911
|
session,
|
|
8758
8912
|
{
|
|
@@ -8761,6 +8915,7 @@ export async function completeRuntimeMapRows(
|
|
|
8761
8915
|
sheetContract,
|
|
8762
8916
|
transactional: needsTransaction,
|
|
8763
8917
|
statementTimeoutMs: RUNTIME_SHEET_COMPLETION_STATEMENT_TIMEOUT_MS,
|
|
8918
|
+
completionDiagnostics,
|
|
8764
8919
|
},
|
|
8765
8920
|
async (client) => {
|
|
8766
8921
|
const completed =
|
|
@@ -8781,15 +8936,20 @@ export async function completeRuntimeMapRows(
|
|
|
8781
8936
|
),
|
|
8782
8937
|
outputFields,
|
|
8783
8938
|
};
|
|
8784
|
-
const updated = await
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
chunkInput,
|
|
8939
|
+
const updated = await measureRuntimeSheetPhase(
|
|
8940
|
+
completionDiagnostics,
|
|
8941
|
+
'mapRowsUpdate',
|
|
8942
|
+
() => completeRuntimeMapRowChunks(client, session, chunkInput),
|
|
8788
8943
|
);
|
|
8789
|
-
const inserted = await
|
|
8790
|
-
|
|
8791
|
-
|
|
8792
|
-
|
|
8944
|
+
const inserted = await measureRuntimeSheetPhase(
|
|
8945
|
+
completionDiagnostics,
|
|
8946
|
+
'missingRowsInsert',
|
|
8947
|
+
() =>
|
|
8948
|
+
insertMissingCompletedMapRowChunks(
|
|
8949
|
+
client,
|
|
8950
|
+
session,
|
|
8951
|
+
chunkInput,
|
|
8952
|
+
),
|
|
8793
8953
|
);
|
|
8794
8954
|
return {
|
|
8795
8955
|
updated: updated.updated + inserted.inserted,
|
|
@@ -8799,21 +8959,28 @@ export async function completeRuntimeMapRows(
|
|
|
8799
8959
|
: { updated: 0, fencedRows: [] };
|
|
8800
8960
|
const failed =
|
|
8801
8961
|
failedRows.length > 0
|
|
8802
|
-
? await
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8962
|
+
? await measureRuntimeSheetPhase(
|
|
8963
|
+
completionDiagnostics,
|
|
8964
|
+
'failedRowsUpdate',
|
|
8965
|
+
() =>
|
|
8966
|
+
failRuntimeMapRowChunks(client, session, {
|
|
8967
|
+
chunks: failedChunks,
|
|
8968
|
+
physicalColumnProjections: projections,
|
|
8969
|
+
forceTerminal: input.forceFailedRows === true,
|
|
8970
|
+
runId: input.runId,
|
|
8971
|
+
attemptId,
|
|
8972
|
+
attemptOwnerRunId,
|
|
8973
|
+
attemptExpiresAt,
|
|
8974
|
+
attemptSeq,
|
|
8975
|
+
writeVersion,
|
|
8976
|
+
normalizedPlayName: normalizePlayNameForSheet(
|
|
8977
|
+
session.playName,
|
|
8978
|
+
),
|
|
8979
|
+
normalizedTableNamespace: normalizeTableNamespace(
|
|
8980
|
+
input.tableNamespace,
|
|
8981
|
+
),
|
|
8982
|
+
}),
|
|
8983
|
+
)
|
|
8817
8984
|
: { updated: 0, fencedRows: [] };
|
|
8818
8985
|
return classifyRuntimeMapRowsWrite({
|
|
8819
8986
|
submittedKeys: uniqueRows.keys(),
|
|
@@ -8821,7 +8988,14 @@ export async function completeRuntimeMapRows(
|
|
|
8821
8988
|
fencedRows: [...completed.fencedRows, ...failed.fencedRows],
|
|
8822
8989
|
});
|
|
8823
8990
|
},
|
|
8824
|
-
)
|
|
8991
|
+
)
|
|
8992
|
+
.then((result) => {
|
|
8993
|
+
updatedRowCount = result.updated;
|
|
8994
|
+
fencedRowCount = result.fencedKeys.length;
|
|
8995
|
+
completionOutcome = 'succeeded';
|
|
8996
|
+
return result;
|
|
8997
|
+
})
|
|
8998
|
+
.finally(logCompletion);
|
|
8825
8999
|
}
|
|
8826
9000
|
|
|
8827
9001
|
/**
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repair UTF-8 text that was decoded with the wrong single-byte code page and
|
|
3
|
+
* re-encoded ("mojibake"), the way Excel exports and copy-pasted sheets often
|
|
4
|
+
* arrive: "jérôme" as "jérôme" (read as Windows-1252) or "o’malley" as
|
|
5
|
+
* "o’malley" (read as Mac Roman).
|
|
6
|
+
*
|
|
7
|
+
* Why this exists: a 2026-08 ContactOut batch of 50 LinkedIn profiles was
|
|
8
|
+
* rejected outright because one slug carried "o’malley", and the same corrupt
|
|
9
|
+
* URLs had already been sent to LimaData and LeadMagic as paid misses. The
|
|
10
|
+
* corruption is in the customer's file, so the fix belongs where every CSV
|
|
11
|
+
* enters a Play: the runtime's CSV parser and the CLI's local CSV reader.
|
|
12
|
+
*
|
|
13
|
+
* Only runs of non-ASCII characters are touched, and a run is rewritten only
|
|
14
|
+
* when mapping it back through one of the two code pages yields strictly
|
|
15
|
+
* valid UTF-8. Correctly encoded text ("José", "Zoltán Erdős", CJK, emoji)
|
|
16
|
+
* never satisfies that test and passes through unchanged.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** Windows-1252 bytes 0x80-0x9F that are not Latin-1 identity. */
|
|
20
|
+
const CP1252_HIGH_TO_BYTE = new Map<number, number>([
|
|
21
|
+
[0x20ac, 0x80],
|
|
22
|
+
[0x201a, 0x82],
|
|
23
|
+
[0x0192, 0x83],
|
|
24
|
+
[0x201e, 0x84],
|
|
25
|
+
[0x2026, 0x85],
|
|
26
|
+
[0x2020, 0x86],
|
|
27
|
+
[0x2021, 0x87],
|
|
28
|
+
[0x02c6, 0x88],
|
|
29
|
+
[0x2030, 0x89],
|
|
30
|
+
[0x0160, 0x8a],
|
|
31
|
+
[0x2039, 0x8b],
|
|
32
|
+
[0x0152, 0x8c],
|
|
33
|
+
[0x017d, 0x8e],
|
|
34
|
+
[0x2018, 0x91],
|
|
35
|
+
[0x2019, 0x92],
|
|
36
|
+
[0x201c, 0x93],
|
|
37
|
+
[0x201d, 0x94],
|
|
38
|
+
[0x2022, 0x95],
|
|
39
|
+
[0x2013, 0x96],
|
|
40
|
+
[0x2014, 0x97],
|
|
41
|
+
[0x02dc, 0x98],
|
|
42
|
+
[0x2122, 0x99],
|
|
43
|
+
[0x0161, 0x9a],
|
|
44
|
+
[0x203a, 0x9b],
|
|
45
|
+
[0x0153, 0x9c],
|
|
46
|
+
[0x017e, 0x9e],
|
|
47
|
+
[0x0178, 0x9f],
|
|
48
|
+
]);
|
|
49
|
+
|
|
50
|
+
/** Mac OS Roman bytes 0x80-0xFF, in order (Python `bytes(range(128,256)).decode('mac_roman')`). */
|
|
51
|
+
const MAC_ROMAN_HIGH =
|
|
52
|
+
'ÄÅÇÉÑÖÜáàâäãåçéè' +
|
|
53
|
+
'êëíìîïñóòôöõúùûü' +
|
|
54
|
+
'†°¢£§•¶ß®©™´¨≠ÆØ' +
|
|
55
|
+
'∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
|
|
56
|
+
'¿¡¬√ƒ≈∆«»… ÀÃÕŒœ' +
|
|
57
|
+
'–—“”‘’÷◊ÿŸ⁄€‹›fifl' +
|
|
58
|
+
'‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ' +
|
|
59
|
+
'ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ';
|
|
60
|
+
const MAC_ROMAN_TO_BYTE = new Map<number, number>(
|
|
61
|
+
[...MAC_ROMAN_HIGH].map((ch, i) => [ch.codePointAt(0)!, 0x80 + i] as const),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const STRICT_UTF8 = new TextDecoder('utf-8', { fatal: true });
|
|
65
|
+
|
|
66
|
+
function cp1252Byte(code: number): number | null {
|
|
67
|
+
if (code < 0x100) return code;
|
|
68
|
+
return CP1252_HIGH_TO_BYTE.get(code) ?? null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function macRomanByte(code: number): number | null {
|
|
72
|
+
if (code < 0x80) return code;
|
|
73
|
+
return MAC_ROMAN_TO_BYTE.get(code) ?? null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function decodeAs(
|
|
77
|
+
run: string,
|
|
78
|
+
toByte: (code: number) => number | null,
|
|
79
|
+
): string | null {
|
|
80
|
+
const bytes = new Uint8Array(run.length);
|
|
81
|
+
let i = 0;
|
|
82
|
+
for (const ch of run) {
|
|
83
|
+
const byte = toByte(ch.codePointAt(0)!);
|
|
84
|
+
if (byte === null) return null;
|
|
85
|
+
bytes[i++] = byte;
|
|
86
|
+
}
|
|
87
|
+
// A real mojibake run always encodes at least one multi-byte sequence, so it
|
|
88
|
+
// must contain a UTF-8 lead byte; a lone Latin-1 letter never does.
|
|
89
|
+
if (!bytes.subarray(0, i).some((b) => b >= 0xc2 && b <= 0xf4)) return null;
|
|
90
|
+
try {
|
|
91
|
+
return STRICT_UTF8.decode(bytes.subarray(0, i));
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Maximal runs of non-ASCII characters are the only places mojibake can live. */
|
|
98
|
+
const NON_ASCII_RUN = /[^\u0000-\u007f]+/g;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Return `value` with mis-decoded UTF-8 runs repaired. Text that is already
|
|
102
|
+
* valid UTF-8 comes back identical (same string instance when nothing changed).
|
|
103
|
+
*/
|
|
104
|
+
export function repairMisdecodedText(value: string): string {
|
|
105
|
+
// Fast path: pure ASCII cannot be mojibake.
|
|
106
|
+
if (!/[^\u0000-\u007f]/.test(value)) return value;
|
|
107
|
+
let changed = false;
|
|
108
|
+
const repaired = value.replace(NON_ASCII_RUN, (run) => {
|
|
109
|
+
const fixed = decodeAs(run, cp1252Byte) ?? decodeAs(run, macRomanByte);
|
|
110
|
+
if (fixed === null || fixed === run) return run;
|
|
111
|
+
changed = true;
|
|
112
|
+
return fixed;
|
|
113
|
+
});
|
|
114
|
+
return changed ? repaired : value;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Repair every string value of a parsed CSV record in place and return it. */
|
|
118
|
+
export function repairRecordText<T extends Record<string, unknown>>(
|
|
119
|
+
record: T,
|
|
120
|
+
): T {
|
|
121
|
+
for (const key of Object.keys(record)) {
|
|
122
|
+
const value = record[key];
|
|
123
|
+
if (typeof value === 'string') {
|
|
124
|
+
(record as Record<string, unknown>)[key] = repairMisdecodedText(value);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return record;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* `csv-parse` options every CSV entry point shares: strip a UTF-8 BOM, repair
|
|
132
|
+
* mojibake in header names (a corrupt header never matches a column mapping)
|
|
133
|
+
* and in every string cell.
|
|
134
|
+
*/
|
|
135
|
+
export function csvInputTextOptions(): {
|
|
136
|
+
bom: true;
|
|
137
|
+
columns: (header: string[]) => string[];
|
|
138
|
+
on_record: <T extends Record<string, unknown>>(record: T) => T;
|
|
139
|
+
} {
|
|
140
|
+
return {
|
|
141
|
+
bom: true,
|
|
142
|
+
columns: (header) => header.map(repairMisdecodedText),
|
|
143
|
+
on_record: repairRecordText,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
var _chunkFBUWH67Yjs = require('./chunk-FBUWH67Y.js');
|
|
13
|
+
require('./chunk-ITOJRSOU.js');
|
|
14
|
+
require('./chunk-MO6QJPEB.js');
|
|
15
|
+
require('./chunk-XNYIZMNQ.js');
|
|
16
|
+
require('./chunk-UJCHR3J3.js');
|
|
17
|
+
require('./chunk-7P5AA3SN.js');
|
|
18
|
+
require('./chunk-OG64RBAC.js');
|
|
19
|
+
require('./chunk-COGTRVWW.js');
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
exports.EXIT_WORKSPACE_MISMATCH = _chunkFBUWH67Yjs.EXIT_WORKSPACE_MISMATCH; exports.clearPendingClaim = _chunkFBUWH67Yjs.clearPendingClaim; exports.clearSatisfiedPendingClaim = _chunkFBUWH67Yjs.clearSatisfiedPendingClaim; exports.handleRegister = _chunkFBUWH67Yjs.handleRegister; exports.handleStatus = _chunkFBUWH67Yjs.handleStatus; exports.handleWait = _chunkFBUWH67Yjs.handleWait; exports.readPendingAuthClaim = _chunkFBUWH67Yjs.readPendingAuthClaim; exports.registerAuthCommands = _chunkFBUWH67Yjs.registerAuthCommands; exports.reportSetupCompleted = _chunkFBUWH67Yjs.reportSetupCompleted; exports.resolvePendingAuthClaimForResume = _chunkFBUWH67Yjs.resolvePendingAuthClaimForResume;
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
registerAuthCommands,
|
|
10
10
|
reportSetupCompleted,
|
|
11
11
|
resolvePendingAuthClaimForResume
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-MLO7ZGSH.mjs";
|
|
13
|
+
import "./chunk-NTIWTBEH.mjs";
|
|
14
|
+
import "./chunk-JDSRPSES.mjs";
|
|
15
15
|
import "./chunk-DLIRSHV6.mjs";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-EWYAS4WD.mjs";
|
|
17
17
|
import "./chunk-NXGCO4JB.mjs";
|
|
18
18
|
import "./chunk-WZYKRD7T.mjs";
|
|
19
19
|
import "./chunk-KRD6H754.mjs";
|