disk 0.8.10 → 0.8.12
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/cli.js +41 -1
- package/dist/index.cjs +41 -1
- package/dist/index.d.cts +275 -7
- package/dist/index.d.ts +275 -7
- package/dist/index.js +41 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -223,6 +223,31 @@ var Disk = class {
|
|
|
223
223
|
})
|
|
224
224
|
);
|
|
225
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Constant-time parallel grep across files on this disk. Listing and
|
|
228
|
+
* matching are fanned out across ephemeral exec containers; the request
|
|
229
|
+
* finishes within the supplied time budget regardless of dataset size.
|
|
230
|
+
*
|
|
231
|
+
* The returned `stoppedReason` says whether the search ran to completion
|
|
232
|
+
* or short-circuited on `maxResults` / `maxDurationSeconds`. When
|
|
233
|
+
* stopping early, the matches returned are a sample (whichever workers
|
|
234
|
+
* reported first), not the lexicographically first N.
|
|
235
|
+
*/
|
|
236
|
+
async grep(opts) {
|
|
237
|
+
return unwrap(
|
|
238
|
+
this._client.POST("/api/disks/{id}/grep", {
|
|
239
|
+
params: { path: { id: this.id } },
|
|
240
|
+
body: {
|
|
241
|
+
directory: opts.directory,
|
|
242
|
+
pattern: opts.pattern,
|
|
243
|
+
recursive: opts.recursive ?? false,
|
|
244
|
+
maxDurationSeconds: opts.maxDurationSeconds ?? 30,
|
|
245
|
+
concurrency: opts.concurrency ?? 50,
|
|
246
|
+
maxResults: opts.maxResults ?? 1e3
|
|
247
|
+
}
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
}
|
|
226
251
|
/**
|
|
227
252
|
* Connect to this disk's data plane via the native ArchilClient.
|
|
228
253
|
*
|
|
@@ -338,6 +363,12 @@ var Tokens = class {
|
|
|
338
363
|
};
|
|
339
364
|
|
|
340
365
|
// src/archil.ts
|
|
366
|
+
function isExecMountSpec(m) {
|
|
367
|
+
return typeof m === "object" && m !== null && "disk" in m;
|
|
368
|
+
}
|
|
369
|
+
function diskIdFromMount(m) {
|
|
370
|
+
return typeof m === "string" ? m : m.id;
|
|
371
|
+
}
|
|
341
372
|
var Archil = class {
|
|
342
373
|
disks;
|
|
343
374
|
tokens;
|
|
@@ -369,7 +400,16 @@ var Archil = class {
|
|
|
369
400
|
async exec(opts) {
|
|
370
401
|
const disks = {};
|
|
371
402
|
for (const [relPath, mount] of Object.entries(opts.disks)) {
|
|
372
|
-
|
|
403
|
+
if (isExecMountSpec(mount)) {
|
|
404
|
+
const entry = {
|
|
405
|
+
disk: diskIdFromMount(mount.disk),
|
|
406
|
+
readOnly: mount.readOnly ?? false
|
|
407
|
+
};
|
|
408
|
+
if (mount.subdirectory !== void 0) entry.subdirectory = mount.subdirectory;
|
|
409
|
+
disks[relPath] = entry;
|
|
410
|
+
} else {
|
|
411
|
+
disks[relPath] = diskIdFromMount(mount);
|
|
412
|
+
}
|
|
373
413
|
}
|
|
374
414
|
return unwrap(
|
|
375
415
|
this._client.POST("/api/exec", {
|
package/dist/index.cjs
CHANGED
|
@@ -266,6 +266,31 @@ var Disk = class {
|
|
|
266
266
|
})
|
|
267
267
|
);
|
|
268
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Constant-time parallel grep across files on this disk. Listing and
|
|
271
|
+
* matching are fanned out across ephemeral exec containers; the request
|
|
272
|
+
* finishes within the supplied time budget regardless of dataset size.
|
|
273
|
+
*
|
|
274
|
+
* The returned `stoppedReason` says whether the search ran to completion
|
|
275
|
+
* or short-circuited on `maxResults` / `maxDurationSeconds`. When
|
|
276
|
+
* stopping early, the matches returned are a sample (whichever workers
|
|
277
|
+
* reported first), not the lexicographically first N.
|
|
278
|
+
*/
|
|
279
|
+
async grep(opts) {
|
|
280
|
+
return unwrap(
|
|
281
|
+
this._client.POST("/api/disks/{id}/grep", {
|
|
282
|
+
params: { path: { id: this.id } },
|
|
283
|
+
body: {
|
|
284
|
+
directory: opts.directory,
|
|
285
|
+
pattern: opts.pattern,
|
|
286
|
+
recursive: opts.recursive ?? false,
|
|
287
|
+
maxDurationSeconds: opts.maxDurationSeconds ?? 30,
|
|
288
|
+
concurrency: opts.concurrency ?? 50,
|
|
289
|
+
maxResults: opts.maxResults ?? 1e3
|
|
290
|
+
}
|
|
291
|
+
})
|
|
292
|
+
);
|
|
293
|
+
}
|
|
269
294
|
/**
|
|
270
295
|
* Connect to this disk's data plane via the native ArchilClient.
|
|
271
296
|
*
|
|
@@ -381,6 +406,12 @@ var Tokens = class {
|
|
|
381
406
|
};
|
|
382
407
|
|
|
383
408
|
// src/archil.ts
|
|
409
|
+
function isExecMountSpec(m) {
|
|
410
|
+
return typeof m === "object" && m !== null && "disk" in m;
|
|
411
|
+
}
|
|
412
|
+
function diskIdFromMount(m) {
|
|
413
|
+
return typeof m === "string" ? m : m.id;
|
|
414
|
+
}
|
|
384
415
|
var Archil = class {
|
|
385
416
|
disks;
|
|
386
417
|
tokens;
|
|
@@ -412,7 +443,16 @@ var Archil = class {
|
|
|
412
443
|
async exec(opts) {
|
|
413
444
|
const disks = {};
|
|
414
445
|
for (const [relPath, mount] of Object.entries(opts.disks)) {
|
|
415
|
-
|
|
446
|
+
if (isExecMountSpec(mount)) {
|
|
447
|
+
const entry = {
|
|
448
|
+
disk: diskIdFromMount(mount.disk),
|
|
449
|
+
readOnly: mount.readOnly ?? false
|
|
450
|
+
};
|
|
451
|
+
if (mount.subdirectory !== void 0) entry.subdirectory = mount.subdirectory;
|
|
452
|
+
disks[relPath] = entry;
|
|
453
|
+
} else {
|
|
454
|
+
disks[relPath] = diskIdFromMount(mount);
|
|
455
|
+
}
|
|
416
456
|
}
|
|
417
457
|
return unwrap(
|
|
418
458
|
this._client.POST("/api/exec", {
|
package/dist/index.d.cts
CHANGED
|
@@ -148,6 +148,48 @@ interface paths {
|
|
|
148
148
|
patch?: never;
|
|
149
149
|
trace?: never;
|
|
150
150
|
};
|
|
151
|
+
"/api/disks/{id}/grep": {
|
|
152
|
+
parameters: {
|
|
153
|
+
query?: never;
|
|
154
|
+
header?: never;
|
|
155
|
+
path?: never;
|
|
156
|
+
cookie?: never;
|
|
157
|
+
};
|
|
158
|
+
get?: never;
|
|
159
|
+
put?: never;
|
|
160
|
+
/**
|
|
161
|
+
* Constant-time parallel grep over a directory on a disk
|
|
162
|
+
* @description Searches files under a directory on the disk for lines matching a
|
|
163
|
+
* regular expression. Listing and matching are fanned out across
|
|
164
|
+
* ephemeral exec containers, so the request finishes within the user's
|
|
165
|
+
* time budget regardless of the size of the directory.
|
|
166
|
+
*
|
|
167
|
+
* The user controls cost and latency with three knobs:
|
|
168
|
+
*
|
|
169
|
+
* - `maxDurationSeconds` is the wall-clock deadline.
|
|
170
|
+
* - `concurrency` is the maximum number of parallel grep workers.
|
|
171
|
+
* Higher concurrency finishes larger datasets within the deadline;
|
|
172
|
+
* the controlplane clamps to the runtime fleet's current capacity.
|
|
173
|
+
* - `maxResults` causes the search to short-circuit after the
|
|
174
|
+
* aggregator has collected this many matches.
|
|
175
|
+
*
|
|
176
|
+
* With `recursive: false` only files directly under `directory` are
|
|
177
|
+
* searched. With `recursive: true` subdirectories are walked
|
|
178
|
+
* breadth-first and grep workers are dispatched as soon as each level
|
|
179
|
+
* finishes listing — listing and matching overlap.
|
|
180
|
+
*
|
|
181
|
+
* The matches returned when stopping early on `maxResults` are a sample
|
|
182
|
+
* of whichever workers reported first, not the lexicographically first
|
|
183
|
+
* N. The response surfaces `stoppedReason` so callers can distinguish
|
|
184
|
+
* completion from early termination.
|
|
185
|
+
*/
|
|
186
|
+
post: operations["grepDisk"];
|
|
187
|
+
delete?: never;
|
|
188
|
+
options?: never;
|
|
189
|
+
head?: never;
|
|
190
|
+
patch?: never;
|
|
191
|
+
trace?: never;
|
|
192
|
+
};
|
|
151
193
|
"/api/exec": {
|
|
152
194
|
parameters: {
|
|
153
195
|
query?: never;
|
|
@@ -711,13 +753,21 @@ interface components {
|
|
|
711
753
|
* @description Map of relative path under `/mnt/archil` to the disk to mount
|
|
712
754
|
* there. At least one entry is required. Relative paths must be
|
|
713
755
|
* non-empty, non-absolute, and contain no `.` or `..` segments.
|
|
756
|
+
*
|
|
757
|
+
* Each value is either a plain disk ID string (mounts the disk's
|
|
758
|
+
* root, read-write) or an object that additionally selects a
|
|
759
|
+
* subdirectory of the disk and/or marks the mount as read-only.
|
|
714
760
|
* @example {
|
|
715
761
|
* "data": "dsk-abc123",
|
|
716
|
-
* "logs":
|
|
762
|
+
* "logs": {
|
|
763
|
+
* "disk": "dsk-def456",
|
|
764
|
+
* "subdirectory": "app/logs",
|
|
765
|
+
* "readOnly": true
|
|
766
|
+
* }
|
|
717
767
|
* }
|
|
718
768
|
*/
|
|
719
769
|
disks: {
|
|
720
|
-
[key: string]: string;
|
|
770
|
+
[key: string]: string | components["schemas"]["ExecMount"];
|
|
721
771
|
};
|
|
722
772
|
/**
|
|
723
773
|
* @description Shell command to execute inside the container
|
|
@@ -725,11 +775,133 @@ interface components {
|
|
|
725
775
|
*/
|
|
726
776
|
command: string;
|
|
727
777
|
};
|
|
778
|
+
ExecMount: {
|
|
779
|
+
/**
|
|
780
|
+
* @description Disk ID to mount at this relative path
|
|
781
|
+
* @example dsk-abc123
|
|
782
|
+
*/
|
|
783
|
+
disk: string;
|
|
784
|
+
/**
|
|
785
|
+
* @description Subdirectory of the disk to expose at the mountpoint. Must be a
|
|
786
|
+
* relative path with no `.` or `..` segments. When omitted, the
|
|
787
|
+
* disk's root is exposed.
|
|
788
|
+
* @example app/logs
|
|
789
|
+
*/
|
|
790
|
+
subdirectory?: string;
|
|
791
|
+
/**
|
|
792
|
+
* @description When true, the disk is mounted read-only inside the container.
|
|
793
|
+
* Writes against the mount fail with EROFS.
|
|
794
|
+
* @default false
|
|
795
|
+
*/
|
|
796
|
+
readOnly: boolean;
|
|
797
|
+
};
|
|
728
798
|
ApiResponse_Exec: {
|
|
729
799
|
/** @example true */
|
|
730
800
|
success: boolean;
|
|
731
801
|
data: components["schemas"]["ExecDiskResult"];
|
|
732
802
|
};
|
|
803
|
+
GrepDiskRequest: {
|
|
804
|
+
/**
|
|
805
|
+
* @description Directory on the disk to search, relative to the disk root.
|
|
806
|
+
* An empty string or "/" means the disk root.
|
|
807
|
+
* @example data/logs
|
|
808
|
+
*/
|
|
809
|
+
directory: string;
|
|
810
|
+
/**
|
|
811
|
+
* @description Extended regular expression (passed to `grep -E`)
|
|
812
|
+
* @example ERROR|FATAL
|
|
813
|
+
*/
|
|
814
|
+
pattern: string;
|
|
815
|
+
/**
|
|
816
|
+
* @description When true, walks subdirectories breadth-first.
|
|
817
|
+
* @default false
|
|
818
|
+
*/
|
|
819
|
+
recursive: boolean;
|
|
820
|
+
/**
|
|
821
|
+
* @description Wall-clock deadline for the entire request. Capped at 30
|
|
822
|
+
* seconds because the runtime exec container itself is bounded
|
|
823
|
+
* at ~30s; longer requests would have their workers killed
|
|
824
|
+
* mid-scan.
|
|
825
|
+
* @default 30
|
|
826
|
+
*/
|
|
827
|
+
maxDurationSeconds: number;
|
|
828
|
+
/**
|
|
829
|
+
* @description Maximum number of parallel grep workers. Higher values finish
|
|
830
|
+
* larger datasets within the deadline but consume more runtime
|
|
831
|
+
* capacity. The controlplane clamps this to the fleet's
|
|
832
|
+
* currently-available capacity.
|
|
833
|
+
* @default 50
|
|
834
|
+
*/
|
|
835
|
+
concurrency: number;
|
|
836
|
+
/**
|
|
837
|
+
* @description Stop scanning once the aggregator has this many matches.
|
|
838
|
+
* Returned matches are a sample of whichever workers reported
|
|
839
|
+
* first, not the lexicographically first N.
|
|
840
|
+
* @default 1000
|
|
841
|
+
*/
|
|
842
|
+
maxResults: number;
|
|
843
|
+
};
|
|
844
|
+
GrepMatch: {
|
|
845
|
+
/**
|
|
846
|
+
* @description Path to the file (relative to the disk root).
|
|
847
|
+
* @example data/logs/2026-05-03.log
|
|
848
|
+
*/
|
|
849
|
+
file: string;
|
|
850
|
+
/**
|
|
851
|
+
* @description 1-based line number where the match occurred.
|
|
852
|
+
* @example 142
|
|
853
|
+
*/
|
|
854
|
+
line: number;
|
|
855
|
+
/** @description The matching line. */
|
|
856
|
+
text: string;
|
|
857
|
+
};
|
|
858
|
+
/**
|
|
859
|
+
* @description Why the search stopped.
|
|
860
|
+
* - `completed`: every file under the directory was scanned successfully.
|
|
861
|
+
* - `incomplete`: pipeline ran to its natural end but one or more
|
|
862
|
+
* batches errored (invalid regex, unreadable file, runtime issue).
|
|
863
|
+
* Results may be partial or wrong; do not rely on completeness.
|
|
864
|
+
* - `max_results`: hit `maxResults` before scanning everything.
|
|
865
|
+
* - `deadline`: hit `maxDurationSeconds`.
|
|
866
|
+
* - `list_failed`: directory listing failed; partial results
|
|
867
|
+
* may be present.
|
|
868
|
+
* @enum {string}
|
|
869
|
+
*/
|
|
870
|
+
GrepStoppedReason: "completed" | "incomplete" | "max_results" | "deadline" | "list_failed";
|
|
871
|
+
GrepDiskResult: {
|
|
872
|
+
matches: components["schemas"]["GrepMatch"][];
|
|
873
|
+
stoppedReason: components["schemas"]["GrepStoppedReason"];
|
|
874
|
+
/** @description Files actually fed to a grep container. */
|
|
875
|
+
filesScanned: number;
|
|
876
|
+
/** @description Number of grep containers started for this request. */
|
|
877
|
+
containersDispatched: number;
|
|
878
|
+
/**
|
|
879
|
+
* Format: double
|
|
880
|
+
* @description Sum of per-container execution time in seconds, measured by the
|
|
881
|
+
* runtime. Approximates billable container-seconds.
|
|
882
|
+
*/
|
|
883
|
+
computeSecondsUsed: number;
|
|
884
|
+
/** @description End-to-end wall clock measured by the server. */
|
|
885
|
+
durationMs: number;
|
|
886
|
+
/**
|
|
887
|
+
* @description Wall-clock time spent enumerating files via listObjects, from
|
|
888
|
+
* the request's start to the moment listing fully drained (or
|
|
889
|
+
* was canceled). Listing and matching overlap, so listingMs +
|
|
890
|
+
* grepMs typically exceeds durationMs.
|
|
891
|
+
*/
|
|
892
|
+
listingMs: number;
|
|
893
|
+
/**
|
|
894
|
+
* @description Wall-clock time spent matching, from the first grep container
|
|
895
|
+
* being dispatched to the last container reporting results. 0 if
|
|
896
|
+
* no batches ran.
|
|
897
|
+
*/
|
|
898
|
+
grepMs: number;
|
|
899
|
+
};
|
|
900
|
+
ApiResponse_GrepDisk: {
|
|
901
|
+
/** @example true */
|
|
902
|
+
success: boolean;
|
|
903
|
+
data: components["schemas"]["GrepDiskResult"];
|
|
904
|
+
};
|
|
733
905
|
};
|
|
734
906
|
responses: {
|
|
735
907
|
/** @description Invalid or missing authentication credentials */
|
|
@@ -1091,6 +1263,37 @@ interface operations {
|
|
|
1091
1263
|
};
|
|
1092
1264
|
};
|
|
1093
1265
|
};
|
|
1266
|
+
grepDisk: {
|
|
1267
|
+
parameters: {
|
|
1268
|
+
query?: never;
|
|
1269
|
+
header?: never;
|
|
1270
|
+
path: {
|
|
1271
|
+
/** @description Disk ID (format `dsk-{16 hex chars}`) */
|
|
1272
|
+
id: components["parameters"]["DiskId"];
|
|
1273
|
+
};
|
|
1274
|
+
cookie?: never;
|
|
1275
|
+
};
|
|
1276
|
+
requestBody: {
|
|
1277
|
+
content: {
|
|
1278
|
+
"application/json": components["schemas"]["GrepDiskRequest"];
|
|
1279
|
+
};
|
|
1280
|
+
};
|
|
1281
|
+
responses: {
|
|
1282
|
+
/** @description Grep completed (possibly stopped early) */
|
|
1283
|
+
200: {
|
|
1284
|
+
headers: {
|
|
1285
|
+
[name: string]: unknown;
|
|
1286
|
+
};
|
|
1287
|
+
content: {
|
|
1288
|
+
"application/json": components["schemas"]["ApiResponse_GrepDisk"];
|
|
1289
|
+
};
|
|
1290
|
+
};
|
|
1291
|
+
400: components["responses"]["ValidationError"];
|
|
1292
|
+
401: components["responses"]["Unauthorized"];
|
|
1293
|
+
404: components["responses"]["NotFound"];
|
|
1294
|
+
500: components["responses"]["InternalError"];
|
|
1295
|
+
};
|
|
1296
|
+
};
|
|
1094
1297
|
exec: {
|
|
1095
1298
|
parameters: {
|
|
1096
1299
|
query?: never;
|
|
@@ -1232,6 +1435,9 @@ type CreateApiTokenRequest = components["schemas"]["CreateApiTokenRequest"];
|
|
|
1232
1435
|
type ApiTokenResponse = components["schemas"]["ApiTokenResponse"];
|
|
1233
1436
|
type ExecDiskResult = components["schemas"]["ExecDiskResult"];
|
|
1234
1437
|
type ExecRequest = components["schemas"]["ExecRequest"];
|
|
1438
|
+
type GrepDiskResult = components["schemas"]["GrepDiskResult"];
|
|
1439
|
+
type GrepMatch = components["schemas"]["GrepMatch"];
|
|
1440
|
+
type GrepStoppedReason = components["schemas"]["GrepStoppedReason"];
|
|
1235
1441
|
type DiskStatus = DiskResponse["status"];
|
|
1236
1442
|
|
|
1237
1443
|
interface MountOptions {
|
|
@@ -1241,6 +1447,34 @@ interface MountOptions {
|
|
|
1241
1447
|
insecure?: boolean;
|
|
1242
1448
|
}
|
|
1243
1449
|
type ExecResult = ExecDiskResult;
|
|
1450
|
+
type GrepResult = GrepDiskResult;
|
|
1451
|
+
|
|
1452
|
+
interface GrepOptions {
|
|
1453
|
+
/**
|
|
1454
|
+
* Directory on the disk to search, relative to the disk root. An empty
|
|
1455
|
+
* string or "/" means the disk root.
|
|
1456
|
+
*/
|
|
1457
|
+
directory: string;
|
|
1458
|
+
/** Extended regular expression (passed to `grep -E`). */
|
|
1459
|
+
pattern: string;
|
|
1460
|
+
/** Walk subdirectories breadth-first. Defaults to false. */
|
|
1461
|
+
recursive?: boolean;
|
|
1462
|
+
/** Wall-clock deadline for the entire request. Defaults to 30s. */
|
|
1463
|
+
maxDurationSeconds?: number;
|
|
1464
|
+
/**
|
|
1465
|
+
* Maximum number of parallel grep workers. Higher values finish larger
|
|
1466
|
+
* datasets within the deadline but consume more runtime capacity. The
|
|
1467
|
+
* controlplane clamps this to the fleet's currently-available capacity.
|
|
1468
|
+
* Defaults to 50.
|
|
1469
|
+
*/
|
|
1470
|
+
concurrency?: number;
|
|
1471
|
+
/**
|
|
1472
|
+
* Stop scanning once the aggregator has this many matches. Returned
|
|
1473
|
+
* matches are a sample of whichever workers reported first, not the
|
|
1474
|
+
* lexicographically first N. Defaults to 1000.
|
|
1475
|
+
*/
|
|
1476
|
+
maxResults?: number;
|
|
1477
|
+
}
|
|
1244
1478
|
declare class Disk {
|
|
1245
1479
|
readonly id: string;
|
|
1246
1480
|
readonly name: string;
|
|
@@ -1282,6 +1516,17 @@ declare class Disk {
|
|
|
1282
1516
|
* Blocks until the command completes and returns stdout, stderr, and exit code.
|
|
1283
1517
|
*/
|
|
1284
1518
|
exec(command: string): Promise<ExecResult>;
|
|
1519
|
+
/**
|
|
1520
|
+
* Constant-time parallel grep across files on this disk. Listing and
|
|
1521
|
+
* matching are fanned out across ephemeral exec containers; the request
|
|
1522
|
+
* finishes within the supplied time budget regardless of dataset size.
|
|
1523
|
+
*
|
|
1524
|
+
* The returned `stoppedReason` says whether the search ran to completion
|
|
1525
|
+
* or short-circuited on `maxResults` / `maxDurationSeconds`. When
|
|
1526
|
+
* stopping early, the matches returned are a sample (whichever workers
|
|
1527
|
+
* reported first), not the lexicographically first N.
|
|
1528
|
+
*/
|
|
1529
|
+
grep(opts: GrepOptions): Promise<GrepResult>;
|
|
1285
1530
|
/**
|
|
1286
1531
|
* Connect to this disk's data plane via the native ArchilClient.
|
|
1287
1532
|
*
|
|
@@ -1344,11 +1589,34 @@ interface ArchilOptions {
|
|
|
1344
1589
|
baseUrl?: string;
|
|
1345
1590
|
}
|
|
1346
1591
|
/**
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1349
|
-
*
|
|
1592
|
+
* Options that apply to a single mounted disk in an exec request.
|
|
1593
|
+
* Use this object form when you need to pin the mount to a subdirectoryectory
|
|
1594
|
+
* of the disk and/or mount it read-only; for the default case (mount
|
|
1595
|
+
* the disk's root, read-write), pass a `Disk` or disk-id string instead.
|
|
1596
|
+
*/
|
|
1597
|
+
interface ExecMountSpec {
|
|
1598
|
+
/** Disk to mount, by `Disk` instance or raw disk id string. */
|
|
1599
|
+
disk: Disk | string;
|
|
1600
|
+
/**
|
|
1601
|
+
* Subdirectory of the disk to expose at the mountpoint. Must be a
|
|
1602
|
+
* relative path with no `.` or `..` segments. When omitted, the disk's
|
|
1603
|
+
* root is exposed.
|
|
1604
|
+
*/
|
|
1605
|
+
subdirectory?: string;
|
|
1606
|
+
/**
|
|
1607
|
+
* When true, mount the disk read-only inside the container. Writes
|
|
1608
|
+
* against the mount fail with EROFS. Defaults to false.
|
|
1609
|
+
*/
|
|
1610
|
+
readOnly?: boolean;
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* One disk to mount in an exec request. Either a `Disk`/disk-id string
|
|
1614
|
+
* (mounts the disk's root, read-write) or an `ExecMountSpec` object that
|
|
1615
|
+
* additionally selects a subdirectoryectory of the disk and/or marks the mount
|
|
1616
|
+
* as read-only. Used by Archil#exec — the map key is the relative path
|
|
1617
|
+
* under /mnt/archil at which to mount the disk.
|
|
1350
1618
|
*/
|
|
1351
|
-
type ExecMount = Disk | string;
|
|
1619
|
+
type ExecMount = Disk | string | ExecMountSpec;
|
|
1352
1620
|
interface ExecOptions {
|
|
1353
1621
|
/**
|
|
1354
1622
|
* Disks to mount, keyed by the relative path under `/mnt/archil` at which
|
|
@@ -1395,4 +1663,4 @@ declare function deleteApiKey(id: string): Promise<void>;
|
|
|
1395
1663
|
*/
|
|
1396
1664
|
declare function exec(opts: ExecOptions): Promise<ExecDiskResult>;
|
|
1397
1665
|
|
|
1398
|
-
export { type ApiTokenResponse, Archil, ArchilApiError, type ArchilOptions, type AuthorizedUser, type AwsStsUser, type AzureBlobMount, type ConnectedClient, type CreateApiTokenRequest, type CreateDiskRequest, type CreateDiskResult, Disk, type DiskMetrics, type DiskResponse, type DiskStatus, type DiskUser, Disks, type ExecMount, type ExecOptions, type ExecRequest, type ExecResult, type GCSMount, type ListDisksOptions, type ListTokensOptions, type MountConfig, type MountConfigResponse, type MountOptions, type MountResponse, type R2Mount, type S3CompatibleMount, type S3Mount, type TokenUser, Tokens, configure, createApiKey, createDisk, deleteApiKey, exec, getDisk, listApiKeys, listDisks };
|
|
1666
|
+
export { type ApiTokenResponse, Archil, ArchilApiError, type ArchilOptions, type AuthorizedUser, type AwsStsUser, type AzureBlobMount, type ConnectedClient, type CreateApiTokenRequest, type CreateDiskRequest, type CreateDiskResult, Disk, type DiskMetrics, type DiskResponse, type DiskStatus, type DiskUser, Disks, type ExecMount, type ExecMountSpec, type ExecOptions, type ExecRequest, type ExecResult, type GCSMount, type GrepMatch, type GrepOptions, type GrepResult, type GrepStoppedReason, type ListDisksOptions, type ListTokensOptions, type MountConfig, type MountConfigResponse, type MountOptions, type MountResponse, type R2Mount, type S3CompatibleMount, type S3Mount, type TokenUser, Tokens, configure, createApiKey, createDisk, deleteApiKey, exec, getDisk, listApiKeys, listDisks };
|
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,48 @@ interface paths {
|
|
|
148
148
|
patch?: never;
|
|
149
149
|
trace?: never;
|
|
150
150
|
};
|
|
151
|
+
"/api/disks/{id}/grep": {
|
|
152
|
+
parameters: {
|
|
153
|
+
query?: never;
|
|
154
|
+
header?: never;
|
|
155
|
+
path?: never;
|
|
156
|
+
cookie?: never;
|
|
157
|
+
};
|
|
158
|
+
get?: never;
|
|
159
|
+
put?: never;
|
|
160
|
+
/**
|
|
161
|
+
* Constant-time parallel grep over a directory on a disk
|
|
162
|
+
* @description Searches files under a directory on the disk for lines matching a
|
|
163
|
+
* regular expression. Listing and matching are fanned out across
|
|
164
|
+
* ephemeral exec containers, so the request finishes within the user's
|
|
165
|
+
* time budget regardless of the size of the directory.
|
|
166
|
+
*
|
|
167
|
+
* The user controls cost and latency with three knobs:
|
|
168
|
+
*
|
|
169
|
+
* - `maxDurationSeconds` is the wall-clock deadline.
|
|
170
|
+
* - `concurrency` is the maximum number of parallel grep workers.
|
|
171
|
+
* Higher concurrency finishes larger datasets within the deadline;
|
|
172
|
+
* the controlplane clamps to the runtime fleet's current capacity.
|
|
173
|
+
* - `maxResults` causes the search to short-circuit after the
|
|
174
|
+
* aggregator has collected this many matches.
|
|
175
|
+
*
|
|
176
|
+
* With `recursive: false` only files directly under `directory` are
|
|
177
|
+
* searched. With `recursive: true` subdirectories are walked
|
|
178
|
+
* breadth-first and grep workers are dispatched as soon as each level
|
|
179
|
+
* finishes listing — listing and matching overlap.
|
|
180
|
+
*
|
|
181
|
+
* The matches returned when stopping early on `maxResults` are a sample
|
|
182
|
+
* of whichever workers reported first, not the lexicographically first
|
|
183
|
+
* N. The response surfaces `stoppedReason` so callers can distinguish
|
|
184
|
+
* completion from early termination.
|
|
185
|
+
*/
|
|
186
|
+
post: operations["grepDisk"];
|
|
187
|
+
delete?: never;
|
|
188
|
+
options?: never;
|
|
189
|
+
head?: never;
|
|
190
|
+
patch?: never;
|
|
191
|
+
trace?: never;
|
|
192
|
+
};
|
|
151
193
|
"/api/exec": {
|
|
152
194
|
parameters: {
|
|
153
195
|
query?: never;
|
|
@@ -711,13 +753,21 @@ interface components {
|
|
|
711
753
|
* @description Map of relative path under `/mnt/archil` to the disk to mount
|
|
712
754
|
* there. At least one entry is required. Relative paths must be
|
|
713
755
|
* non-empty, non-absolute, and contain no `.` or `..` segments.
|
|
756
|
+
*
|
|
757
|
+
* Each value is either a plain disk ID string (mounts the disk's
|
|
758
|
+
* root, read-write) or an object that additionally selects a
|
|
759
|
+
* subdirectory of the disk and/or marks the mount as read-only.
|
|
714
760
|
* @example {
|
|
715
761
|
* "data": "dsk-abc123",
|
|
716
|
-
* "logs":
|
|
762
|
+
* "logs": {
|
|
763
|
+
* "disk": "dsk-def456",
|
|
764
|
+
* "subdirectory": "app/logs",
|
|
765
|
+
* "readOnly": true
|
|
766
|
+
* }
|
|
717
767
|
* }
|
|
718
768
|
*/
|
|
719
769
|
disks: {
|
|
720
|
-
[key: string]: string;
|
|
770
|
+
[key: string]: string | components["schemas"]["ExecMount"];
|
|
721
771
|
};
|
|
722
772
|
/**
|
|
723
773
|
* @description Shell command to execute inside the container
|
|
@@ -725,11 +775,133 @@ interface components {
|
|
|
725
775
|
*/
|
|
726
776
|
command: string;
|
|
727
777
|
};
|
|
778
|
+
ExecMount: {
|
|
779
|
+
/**
|
|
780
|
+
* @description Disk ID to mount at this relative path
|
|
781
|
+
* @example dsk-abc123
|
|
782
|
+
*/
|
|
783
|
+
disk: string;
|
|
784
|
+
/**
|
|
785
|
+
* @description Subdirectory of the disk to expose at the mountpoint. Must be a
|
|
786
|
+
* relative path with no `.` or `..` segments. When omitted, the
|
|
787
|
+
* disk's root is exposed.
|
|
788
|
+
* @example app/logs
|
|
789
|
+
*/
|
|
790
|
+
subdirectory?: string;
|
|
791
|
+
/**
|
|
792
|
+
* @description When true, the disk is mounted read-only inside the container.
|
|
793
|
+
* Writes against the mount fail with EROFS.
|
|
794
|
+
* @default false
|
|
795
|
+
*/
|
|
796
|
+
readOnly: boolean;
|
|
797
|
+
};
|
|
728
798
|
ApiResponse_Exec: {
|
|
729
799
|
/** @example true */
|
|
730
800
|
success: boolean;
|
|
731
801
|
data: components["schemas"]["ExecDiskResult"];
|
|
732
802
|
};
|
|
803
|
+
GrepDiskRequest: {
|
|
804
|
+
/**
|
|
805
|
+
* @description Directory on the disk to search, relative to the disk root.
|
|
806
|
+
* An empty string or "/" means the disk root.
|
|
807
|
+
* @example data/logs
|
|
808
|
+
*/
|
|
809
|
+
directory: string;
|
|
810
|
+
/**
|
|
811
|
+
* @description Extended regular expression (passed to `grep -E`)
|
|
812
|
+
* @example ERROR|FATAL
|
|
813
|
+
*/
|
|
814
|
+
pattern: string;
|
|
815
|
+
/**
|
|
816
|
+
* @description When true, walks subdirectories breadth-first.
|
|
817
|
+
* @default false
|
|
818
|
+
*/
|
|
819
|
+
recursive: boolean;
|
|
820
|
+
/**
|
|
821
|
+
* @description Wall-clock deadline for the entire request. Capped at 30
|
|
822
|
+
* seconds because the runtime exec container itself is bounded
|
|
823
|
+
* at ~30s; longer requests would have their workers killed
|
|
824
|
+
* mid-scan.
|
|
825
|
+
* @default 30
|
|
826
|
+
*/
|
|
827
|
+
maxDurationSeconds: number;
|
|
828
|
+
/**
|
|
829
|
+
* @description Maximum number of parallel grep workers. Higher values finish
|
|
830
|
+
* larger datasets within the deadline but consume more runtime
|
|
831
|
+
* capacity. The controlplane clamps this to the fleet's
|
|
832
|
+
* currently-available capacity.
|
|
833
|
+
* @default 50
|
|
834
|
+
*/
|
|
835
|
+
concurrency: number;
|
|
836
|
+
/**
|
|
837
|
+
* @description Stop scanning once the aggregator has this many matches.
|
|
838
|
+
* Returned matches are a sample of whichever workers reported
|
|
839
|
+
* first, not the lexicographically first N.
|
|
840
|
+
* @default 1000
|
|
841
|
+
*/
|
|
842
|
+
maxResults: number;
|
|
843
|
+
};
|
|
844
|
+
GrepMatch: {
|
|
845
|
+
/**
|
|
846
|
+
* @description Path to the file (relative to the disk root).
|
|
847
|
+
* @example data/logs/2026-05-03.log
|
|
848
|
+
*/
|
|
849
|
+
file: string;
|
|
850
|
+
/**
|
|
851
|
+
* @description 1-based line number where the match occurred.
|
|
852
|
+
* @example 142
|
|
853
|
+
*/
|
|
854
|
+
line: number;
|
|
855
|
+
/** @description The matching line. */
|
|
856
|
+
text: string;
|
|
857
|
+
};
|
|
858
|
+
/**
|
|
859
|
+
* @description Why the search stopped.
|
|
860
|
+
* - `completed`: every file under the directory was scanned successfully.
|
|
861
|
+
* - `incomplete`: pipeline ran to its natural end but one or more
|
|
862
|
+
* batches errored (invalid regex, unreadable file, runtime issue).
|
|
863
|
+
* Results may be partial or wrong; do not rely on completeness.
|
|
864
|
+
* - `max_results`: hit `maxResults` before scanning everything.
|
|
865
|
+
* - `deadline`: hit `maxDurationSeconds`.
|
|
866
|
+
* - `list_failed`: directory listing failed; partial results
|
|
867
|
+
* may be present.
|
|
868
|
+
* @enum {string}
|
|
869
|
+
*/
|
|
870
|
+
GrepStoppedReason: "completed" | "incomplete" | "max_results" | "deadline" | "list_failed";
|
|
871
|
+
GrepDiskResult: {
|
|
872
|
+
matches: components["schemas"]["GrepMatch"][];
|
|
873
|
+
stoppedReason: components["schemas"]["GrepStoppedReason"];
|
|
874
|
+
/** @description Files actually fed to a grep container. */
|
|
875
|
+
filesScanned: number;
|
|
876
|
+
/** @description Number of grep containers started for this request. */
|
|
877
|
+
containersDispatched: number;
|
|
878
|
+
/**
|
|
879
|
+
* Format: double
|
|
880
|
+
* @description Sum of per-container execution time in seconds, measured by the
|
|
881
|
+
* runtime. Approximates billable container-seconds.
|
|
882
|
+
*/
|
|
883
|
+
computeSecondsUsed: number;
|
|
884
|
+
/** @description End-to-end wall clock measured by the server. */
|
|
885
|
+
durationMs: number;
|
|
886
|
+
/**
|
|
887
|
+
* @description Wall-clock time spent enumerating files via listObjects, from
|
|
888
|
+
* the request's start to the moment listing fully drained (or
|
|
889
|
+
* was canceled). Listing and matching overlap, so listingMs +
|
|
890
|
+
* grepMs typically exceeds durationMs.
|
|
891
|
+
*/
|
|
892
|
+
listingMs: number;
|
|
893
|
+
/**
|
|
894
|
+
* @description Wall-clock time spent matching, from the first grep container
|
|
895
|
+
* being dispatched to the last container reporting results. 0 if
|
|
896
|
+
* no batches ran.
|
|
897
|
+
*/
|
|
898
|
+
grepMs: number;
|
|
899
|
+
};
|
|
900
|
+
ApiResponse_GrepDisk: {
|
|
901
|
+
/** @example true */
|
|
902
|
+
success: boolean;
|
|
903
|
+
data: components["schemas"]["GrepDiskResult"];
|
|
904
|
+
};
|
|
733
905
|
};
|
|
734
906
|
responses: {
|
|
735
907
|
/** @description Invalid or missing authentication credentials */
|
|
@@ -1091,6 +1263,37 @@ interface operations {
|
|
|
1091
1263
|
};
|
|
1092
1264
|
};
|
|
1093
1265
|
};
|
|
1266
|
+
grepDisk: {
|
|
1267
|
+
parameters: {
|
|
1268
|
+
query?: never;
|
|
1269
|
+
header?: never;
|
|
1270
|
+
path: {
|
|
1271
|
+
/** @description Disk ID (format `dsk-{16 hex chars}`) */
|
|
1272
|
+
id: components["parameters"]["DiskId"];
|
|
1273
|
+
};
|
|
1274
|
+
cookie?: never;
|
|
1275
|
+
};
|
|
1276
|
+
requestBody: {
|
|
1277
|
+
content: {
|
|
1278
|
+
"application/json": components["schemas"]["GrepDiskRequest"];
|
|
1279
|
+
};
|
|
1280
|
+
};
|
|
1281
|
+
responses: {
|
|
1282
|
+
/** @description Grep completed (possibly stopped early) */
|
|
1283
|
+
200: {
|
|
1284
|
+
headers: {
|
|
1285
|
+
[name: string]: unknown;
|
|
1286
|
+
};
|
|
1287
|
+
content: {
|
|
1288
|
+
"application/json": components["schemas"]["ApiResponse_GrepDisk"];
|
|
1289
|
+
};
|
|
1290
|
+
};
|
|
1291
|
+
400: components["responses"]["ValidationError"];
|
|
1292
|
+
401: components["responses"]["Unauthorized"];
|
|
1293
|
+
404: components["responses"]["NotFound"];
|
|
1294
|
+
500: components["responses"]["InternalError"];
|
|
1295
|
+
};
|
|
1296
|
+
};
|
|
1094
1297
|
exec: {
|
|
1095
1298
|
parameters: {
|
|
1096
1299
|
query?: never;
|
|
@@ -1232,6 +1435,9 @@ type CreateApiTokenRequest = components["schemas"]["CreateApiTokenRequest"];
|
|
|
1232
1435
|
type ApiTokenResponse = components["schemas"]["ApiTokenResponse"];
|
|
1233
1436
|
type ExecDiskResult = components["schemas"]["ExecDiskResult"];
|
|
1234
1437
|
type ExecRequest = components["schemas"]["ExecRequest"];
|
|
1438
|
+
type GrepDiskResult = components["schemas"]["GrepDiskResult"];
|
|
1439
|
+
type GrepMatch = components["schemas"]["GrepMatch"];
|
|
1440
|
+
type GrepStoppedReason = components["schemas"]["GrepStoppedReason"];
|
|
1235
1441
|
type DiskStatus = DiskResponse["status"];
|
|
1236
1442
|
|
|
1237
1443
|
interface MountOptions {
|
|
@@ -1241,6 +1447,34 @@ interface MountOptions {
|
|
|
1241
1447
|
insecure?: boolean;
|
|
1242
1448
|
}
|
|
1243
1449
|
type ExecResult = ExecDiskResult;
|
|
1450
|
+
type GrepResult = GrepDiskResult;
|
|
1451
|
+
|
|
1452
|
+
interface GrepOptions {
|
|
1453
|
+
/**
|
|
1454
|
+
* Directory on the disk to search, relative to the disk root. An empty
|
|
1455
|
+
* string or "/" means the disk root.
|
|
1456
|
+
*/
|
|
1457
|
+
directory: string;
|
|
1458
|
+
/** Extended regular expression (passed to `grep -E`). */
|
|
1459
|
+
pattern: string;
|
|
1460
|
+
/** Walk subdirectories breadth-first. Defaults to false. */
|
|
1461
|
+
recursive?: boolean;
|
|
1462
|
+
/** Wall-clock deadline for the entire request. Defaults to 30s. */
|
|
1463
|
+
maxDurationSeconds?: number;
|
|
1464
|
+
/**
|
|
1465
|
+
* Maximum number of parallel grep workers. Higher values finish larger
|
|
1466
|
+
* datasets within the deadline but consume more runtime capacity. The
|
|
1467
|
+
* controlplane clamps this to the fleet's currently-available capacity.
|
|
1468
|
+
* Defaults to 50.
|
|
1469
|
+
*/
|
|
1470
|
+
concurrency?: number;
|
|
1471
|
+
/**
|
|
1472
|
+
* Stop scanning once the aggregator has this many matches. Returned
|
|
1473
|
+
* matches are a sample of whichever workers reported first, not the
|
|
1474
|
+
* lexicographically first N. Defaults to 1000.
|
|
1475
|
+
*/
|
|
1476
|
+
maxResults?: number;
|
|
1477
|
+
}
|
|
1244
1478
|
declare class Disk {
|
|
1245
1479
|
readonly id: string;
|
|
1246
1480
|
readonly name: string;
|
|
@@ -1282,6 +1516,17 @@ declare class Disk {
|
|
|
1282
1516
|
* Blocks until the command completes and returns stdout, stderr, and exit code.
|
|
1283
1517
|
*/
|
|
1284
1518
|
exec(command: string): Promise<ExecResult>;
|
|
1519
|
+
/**
|
|
1520
|
+
* Constant-time parallel grep across files on this disk. Listing and
|
|
1521
|
+
* matching are fanned out across ephemeral exec containers; the request
|
|
1522
|
+
* finishes within the supplied time budget regardless of dataset size.
|
|
1523
|
+
*
|
|
1524
|
+
* The returned `stoppedReason` says whether the search ran to completion
|
|
1525
|
+
* or short-circuited on `maxResults` / `maxDurationSeconds`. When
|
|
1526
|
+
* stopping early, the matches returned are a sample (whichever workers
|
|
1527
|
+
* reported first), not the lexicographically first N.
|
|
1528
|
+
*/
|
|
1529
|
+
grep(opts: GrepOptions): Promise<GrepResult>;
|
|
1285
1530
|
/**
|
|
1286
1531
|
* Connect to this disk's data plane via the native ArchilClient.
|
|
1287
1532
|
*
|
|
@@ -1344,11 +1589,34 @@ interface ArchilOptions {
|
|
|
1344
1589
|
baseUrl?: string;
|
|
1345
1590
|
}
|
|
1346
1591
|
/**
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1349
|
-
*
|
|
1592
|
+
* Options that apply to a single mounted disk in an exec request.
|
|
1593
|
+
* Use this object form when you need to pin the mount to a subdirectoryectory
|
|
1594
|
+
* of the disk and/or mount it read-only; for the default case (mount
|
|
1595
|
+
* the disk's root, read-write), pass a `Disk` or disk-id string instead.
|
|
1596
|
+
*/
|
|
1597
|
+
interface ExecMountSpec {
|
|
1598
|
+
/** Disk to mount, by `Disk` instance or raw disk id string. */
|
|
1599
|
+
disk: Disk | string;
|
|
1600
|
+
/**
|
|
1601
|
+
* Subdirectory of the disk to expose at the mountpoint. Must be a
|
|
1602
|
+
* relative path with no `.` or `..` segments. When omitted, the disk's
|
|
1603
|
+
* root is exposed.
|
|
1604
|
+
*/
|
|
1605
|
+
subdirectory?: string;
|
|
1606
|
+
/**
|
|
1607
|
+
* When true, mount the disk read-only inside the container. Writes
|
|
1608
|
+
* against the mount fail with EROFS. Defaults to false.
|
|
1609
|
+
*/
|
|
1610
|
+
readOnly?: boolean;
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* One disk to mount in an exec request. Either a `Disk`/disk-id string
|
|
1614
|
+
* (mounts the disk's root, read-write) or an `ExecMountSpec` object that
|
|
1615
|
+
* additionally selects a subdirectoryectory of the disk and/or marks the mount
|
|
1616
|
+
* as read-only. Used by Archil#exec — the map key is the relative path
|
|
1617
|
+
* under /mnt/archil at which to mount the disk.
|
|
1350
1618
|
*/
|
|
1351
|
-
type ExecMount = Disk | string;
|
|
1619
|
+
type ExecMount = Disk | string | ExecMountSpec;
|
|
1352
1620
|
interface ExecOptions {
|
|
1353
1621
|
/**
|
|
1354
1622
|
* Disks to mount, keyed by the relative path under `/mnt/archil` at which
|
|
@@ -1395,4 +1663,4 @@ declare function deleteApiKey(id: string): Promise<void>;
|
|
|
1395
1663
|
*/
|
|
1396
1664
|
declare function exec(opts: ExecOptions): Promise<ExecDiskResult>;
|
|
1397
1665
|
|
|
1398
|
-
export { type ApiTokenResponse, Archil, ArchilApiError, type ArchilOptions, type AuthorizedUser, type AwsStsUser, type AzureBlobMount, type ConnectedClient, type CreateApiTokenRequest, type CreateDiskRequest, type CreateDiskResult, Disk, type DiskMetrics, type DiskResponse, type DiskStatus, type DiskUser, Disks, type ExecMount, type ExecOptions, type ExecRequest, type ExecResult, type GCSMount, type ListDisksOptions, type ListTokensOptions, type MountConfig, type MountConfigResponse, type MountOptions, type MountResponse, type R2Mount, type S3CompatibleMount, type S3Mount, type TokenUser, Tokens, configure, createApiKey, createDisk, deleteApiKey, exec, getDisk, listApiKeys, listDisks };
|
|
1666
|
+
export { type ApiTokenResponse, Archil, ArchilApiError, type ArchilOptions, type AuthorizedUser, type AwsStsUser, type AzureBlobMount, type ConnectedClient, type CreateApiTokenRequest, type CreateDiskRequest, type CreateDiskResult, Disk, type DiskMetrics, type DiskResponse, type DiskStatus, type DiskUser, Disks, type ExecMount, type ExecMountSpec, type ExecOptions, type ExecRequest, type ExecResult, type GCSMount, type GrepMatch, type GrepOptions, type GrepResult, type GrepStoppedReason, type ListDisksOptions, type ListTokensOptions, type MountConfig, type MountConfigResponse, type MountOptions, type MountResponse, type R2Mount, type S3CompatibleMount, type S3Mount, type TokenUser, Tokens, configure, createApiKey, createDisk, deleteApiKey, exec, getDisk, listApiKeys, listDisks };
|
package/dist/index.js
CHANGED
|
@@ -217,6 +217,31 @@ var Disk = class {
|
|
|
217
217
|
})
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Constant-time parallel grep across files on this disk. Listing and
|
|
222
|
+
* matching are fanned out across ephemeral exec containers; the request
|
|
223
|
+
* finishes within the supplied time budget regardless of dataset size.
|
|
224
|
+
*
|
|
225
|
+
* The returned `stoppedReason` says whether the search ran to completion
|
|
226
|
+
* or short-circuited on `maxResults` / `maxDurationSeconds`. When
|
|
227
|
+
* stopping early, the matches returned are a sample (whichever workers
|
|
228
|
+
* reported first), not the lexicographically first N.
|
|
229
|
+
*/
|
|
230
|
+
async grep(opts) {
|
|
231
|
+
return unwrap(
|
|
232
|
+
this._client.POST("/api/disks/{id}/grep", {
|
|
233
|
+
params: { path: { id: this.id } },
|
|
234
|
+
body: {
|
|
235
|
+
directory: opts.directory,
|
|
236
|
+
pattern: opts.pattern,
|
|
237
|
+
recursive: opts.recursive ?? false,
|
|
238
|
+
maxDurationSeconds: opts.maxDurationSeconds ?? 30,
|
|
239
|
+
concurrency: opts.concurrency ?? 50,
|
|
240
|
+
maxResults: opts.maxResults ?? 1e3
|
|
241
|
+
}
|
|
242
|
+
})
|
|
243
|
+
);
|
|
244
|
+
}
|
|
220
245
|
/**
|
|
221
246
|
* Connect to this disk's data plane via the native ArchilClient.
|
|
222
247
|
*
|
|
@@ -332,6 +357,12 @@ var Tokens = class {
|
|
|
332
357
|
};
|
|
333
358
|
|
|
334
359
|
// src/archil.ts
|
|
360
|
+
function isExecMountSpec(m) {
|
|
361
|
+
return typeof m === "object" && m !== null && "disk" in m;
|
|
362
|
+
}
|
|
363
|
+
function diskIdFromMount(m) {
|
|
364
|
+
return typeof m === "string" ? m : m.id;
|
|
365
|
+
}
|
|
335
366
|
var Archil = class {
|
|
336
367
|
disks;
|
|
337
368
|
tokens;
|
|
@@ -363,7 +394,16 @@ var Archil = class {
|
|
|
363
394
|
async exec(opts) {
|
|
364
395
|
const disks = {};
|
|
365
396
|
for (const [relPath, mount] of Object.entries(opts.disks)) {
|
|
366
|
-
|
|
397
|
+
if (isExecMountSpec(mount)) {
|
|
398
|
+
const entry = {
|
|
399
|
+
disk: diskIdFromMount(mount.disk),
|
|
400
|
+
readOnly: mount.readOnly ?? false
|
|
401
|
+
};
|
|
402
|
+
if (mount.subdirectory !== void 0) entry.subdirectory = mount.subdirectory;
|
|
403
|
+
disks[relPath] = entry;
|
|
404
|
+
} else {
|
|
405
|
+
disks[relPath] = diskIdFromMount(mount);
|
|
406
|
+
}
|
|
367
407
|
}
|
|
368
408
|
return unwrap(
|
|
369
409
|
this._client.POST("/api/exec", {
|