@elaraai/e3-ui-components 1.0.83 → 1.0.85
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/README.md +113 -6
- package/dist/components/DataTaskPreview.d.ts +35 -1
- package/dist/components/DataTaskPreview.d.ts.map +1 -1
- package/dist/components/DatasetPreview.d.ts +16 -0
- package/dist/components/DatasetPreview.d.ts.map +1 -1
- package/dist/components/InputPreview.d.ts +12 -0
- package/dist/components/InputPreview.d.ts.map +1 -1
- package/dist/components/PagedDatasetPreview.d.ts +15 -0
- package/dist/components/PagedDatasetPreview.d.ts.map +1 -1
- package/dist/components/TaskLogs.d.ts +19 -0
- package/dist/components/TaskLogs.d.ts.map +1 -1
- package/dist/components/TaskPreview.d.ts +24 -0
- package/dist/components/TaskPreview.d.ts.map +1 -1
- package/dist/components/UITaskPreview.d.ts +4 -1
- package/dist/components/UITaskPreview.d.ts.map +1 -1
- package/dist/components/VirtualizedLogViewer.d.ts +29 -1
- package/dist/components/VirtualizedLogViewer.d.ts.map +1 -1
- package/dist/components/controlled-search.d.ts +22 -0
- package/dist/components/controlled-search.d.ts.map +1 -0
- package/dist/components/preview-controls.d.ts +73 -0
- package/dist/components/preview-controls.d.ts.map +1 -0
- package/dist/diff/index.d.ts.map +1 -1
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/hooks/executions.d.ts +17 -0
- package/dist/hooks/executions.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useDatasetValue.d.ts +19 -1
- package/dist/hooks/useDatasetValue.d.ts.map +1 -1
- package/dist/hooks/useTaskLogsHook.d.ts +67 -3
- package/dist/hooks/useTaskLogsHook.d.ts.map +1 -1
- package/dist/in-memory-call-7_3frW52.js +615 -0
- package/dist/in-memory-call-7_3frW52.js.map +1 -0
- package/dist/in-memory-call-_r5DJotS.cjs +614 -0
- package/dist/in-memory-call-_r5DJotS.cjs.map +1 -0
- package/dist/index.cjs +25860 -5731
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28383 -8253
- package/dist/index.js.map +1 -1
- package/dist/platform/bind-runtime.d.ts +18 -3
- package/dist/platform/bind-runtime.d.ts.map +1 -1
- package/dist/platform/dataset-hooks.d.ts +15 -3
- package/dist/platform/dataset-hooks.d.ts.map +1 -1
- package/dist/platform/dataset-store.d.ts +35 -7
- package/dist/platform/dataset-store.d.ts.map +1 -1
- package/dist/platform/e3-config.d.ts +26 -2
- package/dist/platform/e3-config.d.ts.map +1 -1
- package/dist/platform/func-runtime.d.ts +11 -5
- package/dist/platform/func-runtime.d.ts.map +1 -1
- package/dist/platform/index.d.ts +2 -2
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/paged-runtime.d.ts +46 -9
- package/dist/platform/paged-runtime.d.ts.map +1 -1
- package/dist/platform/record-runtime.d.ts +45 -7
- package/dist/platform/record-runtime.d.ts.map +1 -1
- package/dist/platform/recovery.d.ts +44 -0
- package/dist/platform/recovery.d.ts.map +1 -0
- package/dist/platform/staged-store.d.ts +16 -0
- package/dist/platform/staged-store.d.ts.map +1 -1
- package/dist/platform/tracked-channel.d.ts +12 -0
- package/dist/platform/tracked-channel.d.ts.map +1 -1
- package/dist/query/about.d.ts +50 -0
- package/dist/query/about.d.ts.map +1 -0
- package/dist/query/autocomplete.d.ts +112 -0
- package/dist/query/autocomplete.d.ts.map +1 -0
- package/dist/query/builder.d.ts +29 -0
- package/dist/query/builder.d.ts.map +1 -0
- package/dist/query/calls.d.ts +46 -0
- package/dist/query/calls.d.ts.map +1 -0
- package/dist/query/datasets-tab.d.ts +52 -0
- package/dist/query/datasets-tab.d.ts.map +1 -0
- package/dist/query/downloads.d.ts +29 -0
- package/dist/query/downloads.d.ts.map +1 -0
- package/dist/query/drops.d.ts +28 -0
- package/dist/query/drops.d.ts.map +1 -0
- package/dist/query/foot.d.ts +22 -0
- package/dist/query/foot.d.ts.map +1 -0
- package/dist/query/hooks.d.ts +265 -0
- package/dist/query/hooks.d.ts.map +1 -0
- package/dist/query/in-memory-call.d.ts +150 -0
- package/dist/query/in-memory-call.d.ts.map +1 -0
- package/dist/query/jq-editor.d.ts +34 -0
- package/dist/query/jq-editor.d.ts.map +1 -0
- package/dist/query/library-tab.d.ts +33 -0
- package/dist/query/library-tab.d.ts.map +1 -0
- package/dist/query/library.d.ts +20 -0
- package/dist/query/library.d.ts.map +1 -0
- package/dist/query/model/cards.d.ts +179 -0
- package/dist/query/model/cards.d.ts.map +1 -0
- package/dist/query/model/index.d.ts +19 -0
- package/dist/query/model/index.d.ts.map +1 -0
- package/dist/query/model/messages.d.ts +1253 -0
- package/dist/query/model/messages.d.ts.map +1 -0
- package/dist/query/model/refs.d.ts +92 -0
- package/dist/query/model/refs.d.ts.map +1 -0
- package/dist/query/model/slots.d.ts +213 -0
- package/dist/query/model/slots.d.ts.map +1 -0
- package/dist/query/model/summaries.d.ts +104 -0
- package/dist/query/model/summaries.d.ts.map +1 -0
- package/dist/query/model/words.d.ts +331 -0
- package/dist/query/model/words.d.ts.map +1 -0
- package/dist/query/one-shot.d.ts +266 -0
- package/dist/query/one-shot.d.ts.map +1 -0
- package/dist/query/open-query.d.ts +214 -0
- package/dist/query/open-query.d.ts.map +1 -0
- package/dist/query/parts.d.ts +115 -0
- package/dist/query/parts.d.ts.map +1 -0
- package/dist/query/plan-popover.d.ts +22 -0
- package/dist/query/plan-popover.d.ts.map +1 -0
- package/dist/query/plan.d.ts +353 -0
- package/dist/query/plan.d.ts.map +1 -0
- package/dist/query/query-east.d.ts +21 -0
- package/dist/query/query-east.d.ts.map +1 -0
- package/dist/query/query-tab.d.ts +21 -0
- package/dist/query/query-tab.d.ts.map +1 -0
- package/dist/query/results-table.d.ts +153 -0
- package/dist/query/results-table.d.ts.map +1 -0
- package/dist/query/results.d.ts +137 -0
- package/dist/query/results.d.ts.map +1 -0
- package/dist/query/run.d.ts +199 -0
- package/dist/query/run.d.ts.map +1 -0
- package/dist/query/save-popover.d.ts +29 -0
- package/dist/query/save-popover.d.ts.map +1 -0
- package/dist/query/session.d.ts +409 -0
- package/dist/query/session.d.ts.map +1 -0
- package/dist/query/shape-line.d.ts +21 -0
- package/dist/query/shape-line.d.ts.map +1 -0
- package/dist/query/source.d.ts +21 -0
- package/dist/query/source.d.ts.map +1 -0
- package/dist/query/status-line.d.ts +48 -0
- package/dist/query/status-line.d.ts.map +1 -0
- package/dist/query/step-card.d.ts +30 -0
- package/dist/query/step-card.d.ts.map +1 -0
- package/dist/query/steps/check.d.ts +162 -0
- package/dist/query/steps/check.d.ts.map +1 -0
- package/dist/query/steps/count.d.ts +49 -0
- package/dist/query/steps/count.d.ts.map +1 -0
- package/dist/query/steps/edit.d.ts +108 -0
- package/dist/query/steps/edit.d.ts.map +1 -0
- package/dist/query/steps/fields.d.ts +101 -0
- package/dist/query/steps/fields.d.ts.map +1 -0
- package/dist/query/steps/index.d.ts +22 -0
- package/dist/query/steps/index.d.ts.map +1 -0
- package/dist/query/steps/jq.d.ts +188 -0
- package/dist/query/steps/jq.d.ts.map +1 -0
- package/dist/query/steps/parse.d.ts +38 -0
- package/dist/query/steps/parse.d.ts.map +1 -0
- package/dist/query/steps/print.d.ts +195 -0
- package/dist/query/steps/print.d.ts.map +1 -0
- package/dist/query/steps/shape.d.ts +90 -0
- package/dist/query/steps/shape.d.ts.map +1 -0
- package/dist/query/steps/values.d.ts +85 -0
- package/dist/query/steps/values.d.ts.map +1 -0
- package/dist/query/toolbar.d.ts +56 -0
- package/dist/query/toolbar.d.ts.map +1 -0
- package/dist/query/use-query-editor.d.ts +153 -0
- package/dist/query/use-query-editor.d.ts.map +1 -0
- package/dist/query/use-query-session.d.ts +55 -0
- package/dist/query/use-query-session.d.ts.map +1 -0
- package/dist/query/words.d.ts +60 -0
- package/dist/query/words.d.ts.map +1 -0
- package/dist/query.cjs +16 -0
- package/dist/query.cjs.map +1 -0
- package/dist/query.js +16 -0
- package/dist/query.js.map +1 -0
- package/dist/shared/name-popover.d.ts +38 -0
- package/dist/shared/name-popover.d.ts.map +1 -0
- package/dist/studio/builder.d.ts +20 -0
- package/dist/studio/builder.d.ts.map +1 -0
- package/dist/studio/inspector.d.ts +18 -0
- package/dist/studio/inspector.d.ts.map +1 -0
- package/dist/studio/library.d.ts +20 -0
- package/dist/studio/library.d.ts.map +1 -0
- package/dist/studio/messages.d.ts +318 -0
- package/dist/studio/messages.d.ts.map +1 -0
- package/dist/studio/open-page.d.ts +13 -0
- package/dist/studio/open-page.d.ts.map +1 -0
- package/dist/studio/page.d.ts +61 -0
- package/dist/studio/page.d.ts.map +1 -0
- package/dist/studio/palette.d.ts +41 -0
- package/dist/studio/palette.d.ts.map +1 -0
- package/dist/studio/publish.d.ts +21 -0
- package/dist/studio/publish.d.ts.map +1 -0
- package/dist/studio/save-template.d.ts +18 -0
- package/dist/studio/save-template.d.ts.map +1 -0
- package/dist/studio/studio-east.d.ts +45 -0
- package/dist/studio/studio-east.d.ts.map +1 -0
- package/package.json +19 -14
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
import { checkJq, variant, StructType, fromEastTypeValue, none, some, translateJq, encodeEastIR, runtimeErrorAt, ArrayType, decodeBeast2For, encodeBeast2For, OptionType, printFor, StringType, equalFor, splitJq, decodeEastIR, EastError, sha256Hex, DictType, SortedMap, compareFor, SetType, SortedSet, decodeBeast2, isTypeEqual } from "@elaraai/east";
|
|
2
|
+
import { pathToString, TreePathType, PIECE_SIZES } from "@elaraai/e3-types";
|
|
3
|
+
const JQ_IDENTIFIER = /^[A-Za-z_][A-Za-z_0-9]*$/;
|
|
4
|
+
const printString = printFor(StringType);
|
|
5
|
+
function queryRoot(entries) {
|
|
6
|
+
const names = /* @__PURE__ */ new Set();
|
|
7
|
+
for (const { name } of entries) {
|
|
8
|
+
if (!JQ_IDENTIFIER.test(name)) {
|
|
9
|
+
throw new Error(`queryRoot: ${printString(name)} is not a jq identifier: a data source's name is a letter or _, then letters, digits and _, so .name reads it`);
|
|
10
|
+
}
|
|
11
|
+
if (names.has(name)) throw new Error(`queryRoot: ${printString(name)} is given twice: each data source of a root has a name of its own`);
|
|
12
|
+
names.add(name);
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
type: StructType(Object.fromEntries(entries.map((entry) => [entry.name, fromEastTypeValue(entry.type)]))),
|
|
16
|
+
entries: [...entries]
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const DEFAULT_MAX_OUTPUTS = 1e3;
|
|
20
|
+
const MAX_OUTPUTS = 1e5;
|
|
21
|
+
const DEFAULT_MAX_BYTES = 1048576;
|
|
22
|
+
function programChecks(checked) {
|
|
23
|
+
return checked.program !== null && checked.elementType !== null && checked.multiplicity !== null;
|
|
24
|
+
}
|
|
25
|
+
function queryLimits(options = {}) {
|
|
26
|
+
const maxOutputs = Math.min(limitOf(options.maxOutputs, DEFAULT_MAX_OUTPUTS, "maxOutputs"), MAX_OUTPUTS);
|
|
27
|
+
const maxBytes = limitOf(options.maxBytes, DEFAULT_MAX_BYTES, "maxBytes");
|
|
28
|
+
const timeoutMs = options.timeoutMs === void 0 ? none : some(BigInt(checkedLimit(options.timeoutMs, "timeoutMs")));
|
|
29
|
+
return {
|
|
30
|
+
maxOutputs,
|
|
31
|
+
limits: some({ timeoutMs, maxResultBytes: some(BigInt(maxBytes)), maxLogBytes: none }),
|
|
32
|
+
runner: options.runner ?? platformFreeEastC()
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function prepareQuery(program, root, options = {}) {
|
|
36
|
+
queryLimits(options);
|
|
37
|
+
return prepareCheckedQuery(checkJq(program, root.type, { root: true }), root, options);
|
|
38
|
+
}
|
|
39
|
+
function prepareCheckedQuery(checked, root, options = {}) {
|
|
40
|
+
const { maxOutputs, limits, runner } = queryLimits(options);
|
|
41
|
+
if (!programChecks(checked)) return { result: { inputs: [], outcome: variant("error", checked.diagnostics) } };
|
|
42
|
+
const translation = translateJq(checked, checked.multiplicity === "many" ? { maxOutputs } : {});
|
|
43
|
+
const entries = translation.inputs.map((input) => entryNamed(root, input.name));
|
|
44
|
+
const request = {
|
|
45
|
+
bodyIr: encodeEastIR(translation.fn().toIR()),
|
|
46
|
+
args: entries.map((entry) => variant("dataset", entry.path)),
|
|
47
|
+
runner,
|
|
48
|
+
limits
|
|
49
|
+
};
|
|
50
|
+
return { prepared: { checked, entries, request, maxOutputs } };
|
|
51
|
+
}
|
|
52
|
+
function limitOf(value, fallback, name) {
|
|
53
|
+
return value === void 0 ? fallback : checkedLimit(value, name);
|
|
54
|
+
}
|
|
55
|
+
function checkedLimit(value, name) {
|
|
56
|
+
if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`prepareQuery: ${name} is ${value}, not a whole number of at least 1`);
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
function entryNamed(root, name, caller = "prepareQuery") {
|
|
60
|
+
const entry = root.entries.find((e) => e.name === name);
|
|
61
|
+
if (entry === void 0) throw new Error(`${caller}: the query reads .${name ?? ""}, which no data source of the root is`);
|
|
62
|
+
return entry;
|
|
63
|
+
}
|
|
64
|
+
function platformFreeEastC() {
|
|
65
|
+
return variant("east_c", { platforms: [], decode: variant("lazy", null) });
|
|
66
|
+
}
|
|
67
|
+
function queryResultOf(prepared, result) {
|
|
68
|
+
const inputs = inputsOf(prepared, result);
|
|
69
|
+
const outcome = result.outcome;
|
|
70
|
+
switch (outcome.type) {
|
|
71
|
+
case "success":
|
|
72
|
+
return { inputs, outcome: answered(prepared, outcome.value.value) };
|
|
73
|
+
case "failed":
|
|
74
|
+
return { inputs, outcome: failed(prepared.checked, outcome.value.exitCode, result.stderr) };
|
|
75
|
+
case "invalid":
|
|
76
|
+
return { inputs, outcome: variant("error", outcome.value.diagnostics.map((d) => refused(prepared, d.message))) };
|
|
77
|
+
case "timed_out":
|
|
78
|
+
return { inputs, outcome: variant("timed_out", { ms: outcome.value.ms }) };
|
|
79
|
+
case "too_large":
|
|
80
|
+
return { inputs, outcome: variant("too_large", { bytes: outcome.value.bytes, limit: outcome.value.limit }) };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const samePath$1 = equalFor(TreePathType);
|
|
84
|
+
function inputsOf(prepared, result) {
|
|
85
|
+
return result.inputs.map((input, i) => {
|
|
86
|
+
const entry = prepared.entries[i];
|
|
87
|
+
if (entry === void 0 || !samePath$1(entry.path, input.path)) {
|
|
88
|
+
throw new Error(`queryResultOf: the call's argument ${i} read ${pathToString(input.path)}, which is not the data source the query reads there`);
|
|
89
|
+
}
|
|
90
|
+
return { hash: input.hash, name: entry.name, path: input.path };
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
function answered(prepared, bytes) {
|
|
94
|
+
const element = prepared.checked.elementType;
|
|
95
|
+
switch (prepared.checked.multiplicity) {
|
|
96
|
+
case "one":
|
|
97
|
+
decodeBeast2For(element)(bytes);
|
|
98
|
+
return variant("ok", { outputs: 1n, result: bytes, truncated: false });
|
|
99
|
+
case "maybe": {
|
|
100
|
+
const answer2 = decodeBeast2For(OptionType(element))(bytes);
|
|
101
|
+
return variant("ok", { outputs: answer2.type === "some" ? 1n : 0n, result: bytes, truncated: false });
|
|
102
|
+
}
|
|
103
|
+
case "many": {
|
|
104
|
+
const type = ArrayType(element);
|
|
105
|
+
const answer2 = decodeBeast2For(type)(bytes);
|
|
106
|
+
if (answer2.length <= prepared.maxOutputs) return variant("ok", { outputs: BigInt(answer2.length), result: bytes, truncated: false });
|
|
107
|
+
return variant("ok", { outputs: BigInt(prepared.maxOutputs), result: encodeBeast2For(type)(answer2.slice(0, prepared.maxOutputs)), truncated: true });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const FAILURE_LEAD = "Error: ";
|
|
112
|
+
const FAILURE_PLACE = /^ {2}at (.+):(\d+):(\d+)$/;
|
|
113
|
+
function failureOf(stderr) {
|
|
114
|
+
const lines = stderr.replace(/\r\n?/g, "\n").split("\n");
|
|
115
|
+
while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
116
|
+
const places = [];
|
|
117
|
+
let end = lines.length;
|
|
118
|
+
for (; end > 0; end--) {
|
|
119
|
+
const place = FAILURE_PLACE.exec(lines[end - 1]);
|
|
120
|
+
if (place === null) break;
|
|
121
|
+
places.unshift({ file: place[1], line: Number(place[2]), column: Number(place[3]) });
|
|
122
|
+
}
|
|
123
|
+
let start = end - 1;
|
|
124
|
+
while (start >= 0 && !lines[start].startsWith(FAILURE_LEAD)) start--;
|
|
125
|
+
if (start < 0) return void 0;
|
|
126
|
+
return { message: [lines[start].slice(FAILURE_LEAD.length), ...lines.slice(start + 1, end)].join("\n"), places };
|
|
127
|
+
}
|
|
128
|
+
const MISSING_PLATFORM = /Unknown platform function: ([^\s'"]+)|Platform function '([^']+)' (?:not found|is not available)/g;
|
|
129
|
+
function failed(checked, exitCode, stderr) {
|
|
130
|
+
const failure = failureOf(stderr);
|
|
131
|
+
const functions = [];
|
|
132
|
+
for (const match of ((failure == null ? void 0 : failure.message) ?? stderr).matchAll(MISSING_PLATFORM)) {
|
|
133
|
+
const name = match[1] ?? match[2];
|
|
134
|
+
if (name !== void 0 && !functions.includes(name)) functions.push(name);
|
|
135
|
+
}
|
|
136
|
+
if (functions.length > 0) return variant("needs_platform", { functions });
|
|
137
|
+
if (failure === void 0) {
|
|
138
|
+
const said = stderr.split(/\r\n?|\n/).map((line) => line.trim()).filter((line) => line !== "").at(-1);
|
|
139
|
+
return variant("error", [runtimeErrorAt(checked, said ?? `the run failed with exit code ${exitCode}`)]);
|
|
140
|
+
}
|
|
141
|
+
const place = failure.places.find((p) => p.file === "jq");
|
|
142
|
+
return variant("error", [runtimeErrorAt(checked, failure.message, place)]);
|
|
143
|
+
}
|
|
144
|
+
const UNASSIGNED = /^Dataset argument (\d+) is not assigned\b/;
|
|
145
|
+
function refused(prepared, message) {
|
|
146
|
+
const unassigned2 = UNASSIGNED.exec(message);
|
|
147
|
+
const entry = unassigned2 === null ? void 0 : prepared.entries[Number(unassigned2[1])];
|
|
148
|
+
if (entry !== void 0) return problem("no_value", `no_value: ${entry.name} has no value yet.`, none);
|
|
149
|
+
return problem("invalid", `invalid: ${message}`, none);
|
|
150
|
+
}
|
|
151
|
+
function problem(code, message, span) {
|
|
152
|
+
return { code, fixes: [], message, severity: variant("error", null), span, suggestions: [] };
|
|
153
|
+
}
|
|
154
|
+
function pieceBytesOf(options) {
|
|
155
|
+
const bytes = options.pieceBytes ?? PIECE_SIZES.min;
|
|
156
|
+
if (!Number.isSafeInteger(bytes) || bytes < 0) throw new RangeError(`planQuery: pieceBytes is ${bytes}, not a whole number of bytes`);
|
|
157
|
+
return bytes;
|
|
158
|
+
}
|
|
159
|
+
function messageOf(err) {
|
|
160
|
+
return err instanceof Error ? err.message : String(err);
|
|
161
|
+
}
|
|
162
|
+
function draftPlan(programs, root, options = {}) {
|
|
163
|
+
const all = typeof programs === "string" ? { query: programs, oneShot: programs, split: programs } : { query: programs.query, oneShot: programs.oneShot ?? programs.query, split: programs.split ?? programs.query };
|
|
164
|
+
const { maxOutputs } = queryLimits(options);
|
|
165
|
+
pieceBytesOf(options);
|
|
166
|
+
const checked = checkJq(all.query, root.type, { root: true });
|
|
167
|
+
if (checked.program === null) {
|
|
168
|
+
const refused2 = prepareCheckedQuery(checked, root, options);
|
|
169
|
+
if ("result" in refused2) return refused2;
|
|
170
|
+
}
|
|
171
|
+
let split;
|
|
172
|
+
try {
|
|
173
|
+
split = splitJq(checked, checked.multiplicity === "many" ? { maxOutputs } : {});
|
|
174
|
+
} catch (err) {
|
|
175
|
+
split = { kind: "failed", message: messageOf(err) };
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
draft: {
|
|
179
|
+
reads: [...checked.reads],
|
|
180
|
+
over: split.kind === "split" ? split.over : void 0,
|
|
181
|
+
weighs: split.kind === "split" ? [.../* @__PURE__ */ new Set([split.over, ...split.copartitioned, ...split.rekey === null ? [] : [split.rekey.name]])] : [],
|
|
182
|
+
programs: all,
|
|
183
|
+
root,
|
|
184
|
+
options,
|
|
185
|
+
checked,
|
|
186
|
+
split
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function weighPlan(draft, weights) {
|
|
191
|
+
var _a, _b;
|
|
192
|
+
const { checked, split, programs, root, options } = draft;
|
|
193
|
+
const program = checked.source.text;
|
|
194
|
+
const oneCall = (why, pruning) => {
|
|
195
|
+
const prepared = programs.oneShot === programs.query ? prepareCheckedQuery(checked, root, options) : prepareQuery(programs.oneShot, root, options);
|
|
196
|
+
if ("result" in prepared) return prepared;
|
|
197
|
+
return { plan: { kind: "one_shot", prepared: prepared.prepared, explanation: { program, path: { kind: "one_shot", why }, pruning } } };
|
|
198
|
+
};
|
|
199
|
+
if (split.kind === "failed") return oneCall({ kind: "unsplit", over: null, message: split.message }, []);
|
|
200
|
+
if (split.kind === "whole") return oneCall({ kind: "whole", reason: split.reason }, split.pruning);
|
|
201
|
+
const pieceBytes = pieceBytesOf(options);
|
|
202
|
+
let heaviest = split.over;
|
|
203
|
+
let bytes = -1;
|
|
204
|
+
for (const name of [split.over, ...split.copartitioned]) {
|
|
205
|
+
const weighs = (_a = weights.get(name)) == null ? void 0 : _a.bytes;
|
|
206
|
+
if (weighs === void 0) return oneCall({ kind: "unweighed", over: name }, split.pruning);
|
|
207
|
+
if (weighs > bytes) [heaviest, bytes] = [name, weighs];
|
|
208
|
+
}
|
|
209
|
+
if (bytes <= pieceBytes) return oneCall({ kind: "small", over: heaviest, bytes, pieceBytes }, split.pruning);
|
|
210
|
+
const joined = split.rekey === null ? void 0 : (_b = weights.get(split.rekey.name)) == null ? void 0 : _b.bytes;
|
|
211
|
+
const rekey = split.rekey !== null && joined !== void 0 && joined > pieceBytes ? split.rekey : null;
|
|
212
|
+
let call;
|
|
213
|
+
try {
|
|
214
|
+
call = splitCallOf(draft, split, rekey !== null);
|
|
215
|
+
} catch (err) {
|
|
216
|
+
return oneCall({ kind: "unsplit", over: split.over, message: messageOf(err) }, split.pruning);
|
|
217
|
+
}
|
|
218
|
+
const explanation = {
|
|
219
|
+
program,
|
|
220
|
+
path: {
|
|
221
|
+
kind: "split",
|
|
222
|
+
over: split.over,
|
|
223
|
+
heaviest,
|
|
224
|
+
bytes,
|
|
225
|
+
pieceBytes,
|
|
226
|
+
output: split.output.kind,
|
|
227
|
+
stages: split.stages,
|
|
228
|
+
// A re-keyed join reads its other side cut at the same keys, not whole.
|
|
229
|
+
broadcast: rekey === null ? split.broadcast : split.broadcast.filter((name) => name !== rekey.name),
|
|
230
|
+
copartitioned: split.copartitioned,
|
|
231
|
+
rekey: rekey === null ? null : { name: rekey.name, key: rekey.key, bytes }
|
|
232
|
+
},
|
|
233
|
+
pruning: split.pruning
|
|
234
|
+
};
|
|
235
|
+
return { plan: "request" in call ? { kind: "split", ...call, explanation } : { kind: "rekey", ...call, explanation } };
|
|
236
|
+
}
|
|
237
|
+
function planQuery(programs, root, weights, options = {}) {
|
|
238
|
+
const drafted = draftPlan(programs, root, options);
|
|
239
|
+
if ("result" in drafted) return drafted;
|
|
240
|
+
return weighPlan(drafted.draft, weights);
|
|
241
|
+
}
|
|
242
|
+
function splitCallOf(draft, split, rekey) {
|
|
243
|
+
var _a, _b, _c;
|
|
244
|
+
const { programs, root, options } = draft;
|
|
245
|
+
const { maxOutputs } = queryLimits(options);
|
|
246
|
+
let checked = draft.checked;
|
|
247
|
+
let call = split;
|
|
248
|
+
if (programs.split !== programs.query) {
|
|
249
|
+
checked = checkJq(programs.split, root.type, { root: true });
|
|
250
|
+
if (checked.program === null) throw new Error(`the run's split program does not check: ${((_a = checked.diagnostics[0]) == null ? void 0 : _a.message) ?? ""}`);
|
|
251
|
+
const wrapped = splitJq(checked, checked.multiplicity === "many" ? { maxOutputs } : {});
|
|
252
|
+
const same = wrapped.kind === "split" && wrapped.over === split.over && wrapped.output.kind === split.output.kind && wrapped.copartitioned.join("\n") === split.copartitioned.join("\n") && ((_b = wrapped.rekey) == null ? void 0 : _b.name) === ((_c = split.rekey) == null ? void 0 : _c.name);
|
|
253
|
+
if (!same) {
|
|
254
|
+
throw new Error(`the run's split program splits otherwise than the query: ${wrapped.kind === "split" ? `${wrapped.output.kind} over ${wrapped.over}` : wrapped.reason.code}`);
|
|
255
|
+
}
|
|
256
|
+
call = wrapped;
|
|
257
|
+
}
|
|
258
|
+
if (!programChecks(checked)) throw new Error("the query does not check");
|
|
259
|
+
const entry = (name) => entryNamed(root, name, "splitCallRequest");
|
|
260
|
+
if (!rekey) return { request: splitCallRequest(call, root, options), reading: { checked, entries: call.inputs.map((input) => entry(input.name)), maxOutputs } };
|
|
261
|
+
const joined = call.inputs.filter((input) => input.name !== call.over).map((input) => entry(input.name));
|
|
262
|
+
return { ...rekeyCallRequests(call, root, options), reading: { checked, entries: [entry(call.over), ...joined], maxOutputs } };
|
|
263
|
+
}
|
|
264
|
+
function splitCallRequest(split, root, options = {}) {
|
|
265
|
+
const { limits, runner } = queryLimits(options);
|
|
266
|
+
const then = split.then();
|
|
267
|
+
return {
|
|
268
|
+
bodyIr: encodeEastIR(split.piece().toIR()),
|
|
269
|
+
args: split.inputs.map((input) => ({
|
|
270
|
+
arg: variant("dataset", entryNamed(root, input.name, "splitCallRequest").path),
|
|
271
|
+
partition: input.name === split.over || split.copartitioned.includes(input.name) ? some({ by: [] }) : none
|
|
272
|
+
})),
|
|
273
|
+
output: outputOf(split.output),
|
|
274
|
+
then: then === null ? none : some(encodeEastIR(then.toIR())),
|
|
275
|
+
runner,
|
|
276
|
+
limits
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function rekeyCallRequests(split, root, options = {}) {
|
|
280
|
+
const rekey = split.rekey;
|
|
281
|
+
if (rekey === null) throw new Error("rekeyCallRequests: the split re-keys no join");
|
|
282
|
+
const { limits, runner } = queryLimits(options);
|
|
283
|
+
const path = (name) => entryNamed(root, name, "rekeyCallRequests").path;
|
|
284
|
+
const first = {
|
|
285
|
+
bodyIr: encodeEastIR(rekey.piece().toIR()),
|
|
286
|
+
args: [{ arg: variant("dataset", path(split.over)), partition: some({ by: [] }) }],
|
|
287
|
+
output: variant("dict", { merge: some(encodeEastIR(rekey.output.merge().toIR())) }),
|
|
288
|
+
then: none,
|
|
289
|
+
runner,
|
|
290
|
+
limits: some({
|
|
291
|
+
timeoutMs: limits.type === "some" ? limits.value.timeoutMs : none,
|
|
292
|
+
maxResultBytes: some(1n),
|
|
293
|
+
maxLogBytes: limits.type === "some" ? limits.value.maxLogBytes : none
|
|
294
|
+
})
|
|
295
|
+
};
|
|
296
|
+
const piece = encodeEastIR(rekey.joinPiece().toIR());
|
|
297
|
+
const then = rekey.joinThen();
|
|
298
|
+
const thenIr = then === null ? none : some(encodeEastIR(then.toIR()));
|
|
299
|
+
return {
|
|
300
|
+
first,
|
|
301
|
+
join: (output) => ({
|
|
302
|
+
bodyIr: piece,
|
|
303
|
+
args: rekey.inputs.map((input) => input.name === split.over ? { arg: variant("object", output), partition: some({ by: [] }) } : { arg: variant("dataset", path(input.name)), partition: input.name === rekey.name ? some({ by: [] }) : none }),
|
|
304
|
+
output: outputOf(split.output),
|
|
305
|
+
then: thenIr,
|
|
306
|
+
runner,
|
|
307
|
+
limits
|
|
308
|
+
}),
|
|
309
|
+
answer: (firstResult, joinResult) => ({
|
|
310
|
+
...joinResult ?? firstResult,
|
|
311
|
+
inputs: [...firstResult.inputs, ...(joinResult == null ? void 0 : joinResult.inputs) ?? []]
|
|
312
|
+
})
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function outputOf(output) {
|
|
316
|
+
switch (output.kind) {
|
|
317
|
+
case "array":
|
|
318
|
+
return variant("array", null);
|
|
319
|
+
case "set":
|
|
320
|
+
return variant("set", null);
|
|
321
|
+
case "dict":
|
|
322
|
+
return variant("dict", { merge: some(encodeEastIR(output.merge().toIR())) });
|
|
323
|
+
case "fold":
|
|
324
|
+
return variant("fold", { combine: encodeEastIR(output.combine().toIR()), zero: encodeBeast2For(output.type)(output.zero) });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const samePath = equalFor(TreePathType);
|
|
328
|
+
function hold(datasets) {
|
|
329
|
+
return datasets.map((dataset) => {
|
|
330
|
+
let encoded;
|
|
331
|
+
let hash = dataset.hash;
|
|
332
|
+
const bytes = () => encoded ?? (encoded = encodeBeast2For(dataset.type)(dataset.value));
|
|
333
|
+
return { ...dataset, hashOf: () => hash ?? (hash = sha256Hex(bytes())), bytesOf: () => dataset.bytes ?? bytes().length };
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
const QUIET = { stdout: "", stdoutTruncated: false, stderrTruncated: false };
|
|
337
|
+
function invalid(message) {
|
|
338
|
+
return { ...QUIET, outcome: variant("invalid", { diagnostics: [{ message, filename: none, line: none, column: none }] }), stderr: "", inputs: [] };
|
|
339
|
+
}
|
|
340
|
+
function unassigned(i, path) {
|
|
341
|
+
return `Dataset argument ${i} is not assigned (ref type: unassigned): nothing in memory at ${pathToString(path)}`;
|
|
342
|
+
}
|
|
343
|
+
function maxResultBytes(limits) {
|
|
344
|
+
return limits.type === "some" && limits.value.maxResultBytes.type === "some" ? limits.value.maxResultBytes.value : void 0;
|
|
345
|
+
}
|
|
346
|
+
function answer(type, value, limits, inputs) {
|
|
347
|
+
const bytes = encodeBeast2For(type)(value);
|
|
348
|
+
const limit = maxResultBytes(limits);
|
|
349
|
+
if (limit !== void 0 && BigInt(bytes.length) > limit) {
|
|
350
|
+
return { ...QUIET, outcome: variant("too_large", { bytes: BigInt(bytes.length), limit }), stderr: "", inputs };
|
|
351
|
+
}
|
|
352
|
+
return { ...QUIET, outcome: variant("success", { value: bytes }), stderr: "", inputs };
|
|
353
|
+
}
|
|
354
|
+
function raised(err, inputs) {
|
|
355
|
+
return { ...QUIET, outcome: variant("failed", { exitCode: 1n }), stderr: `Error: ${err.toString()}
|
|
356
|
+
`, inputs };
|
|
357
|
+
}
|
|
358
|
+
function createInMemoryQueryCall(datasets) {
|
|
359
|
+
const held = hold(datasets);
|
|
360
|
+
return async (request) => {
|
|
361
|
+
const read = [];
|
|
362
|
+
for (const [i, arg] of request.args.entries()) {
|
|
363
|
+
const found = arg.type === "dataset" ? held.find((d) => samePath(d.path, arg.value)) : void 0;
|
|
364
|
+
if (found === void 0) {
|
|
365
|
+
return invalid(arg.type === "dataset" ? unassigned(i, arg.value) : `Argument ${i} is an inline value, which an in-memory call does not take`);
|
|
366
|
+
}
|
|
367
|
+
read.push(found);
|
|
368
|
+
}
|
|
369
|
+
const inputs = read.map((d) => ({ path: d.path, hash: d.hashOf() }));
|
|
370
|
+
const body = decodeEastIR(request.bodyIr);
|
|
371
|
+
const type = fromEastTypeValue(body.ir.value.type);
|
|
372
|
+
if (type.type !== "Function") throw new Error("createInMemoryQueryCall: a call's body is a function");
|
|
373
|
+
let value;
|
|
374
|
+
try {
|
|
375
|
+
value = body.compile([])(...read.map((d) => d.value));
|
|
376
|
+
} catch (err) {
|
|
377
|
+
if (!(err instanceof EastError)) throw err;
|
|
378
|
+
return raised(err, inputs);
|
|
379
|
+
}
|
|
380
|
+
return answer(type.output, value, request.limits, inputs);
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function compiled(ir, what) {
|
|
384
|
+
const decoded = decodeEastIR(ir);
|
|
385
|
+
const type = fromEastTypeValue(decoded.ir.value.type);
|
|
386
|
+
if (type.type !== "Function") throw new Error(`createInMemorySplitCall: the call's ${what} is a function`);
|
|
387
|
+
return { fn: decoded.compile([]), inputs: type.inputs, output: type.output };
|
|
388
|
+
}
|
|
389
|
+
function cut(value, type, k) {
|
|
390
|
+
const t = type.type === "Recursive" ? type.node : type;
|
|
391
|
+
const runs = (rows) => Array.from({ length: k }, (_, i) => rows.slice(Math.floor(i * rows.length / k), Math.floor((i + 1) * rows.length / k)));
|
|
392
|
+
switch (t.type) {
|
|
393
|
+
case "Array":
|
|
394
|
+
return runs(value);
|
|
395
|
+
case "Set": {
|
|
396
|
+
const compare = compareFor(t.key);
|
|
397
|
+
return runs([...value]).map((rows) => new SortedSet(rows, compare));
|
|
398
|
+
}
|
|
399
|
+
case "Dict": {
|
|
400
|
+
const compare = compareFor(t.key);
|
|
401
|
+
return runs([...value.entries()]).map((rows) => new SortedMap(rows, compare));
|
|
402
|
+
}
|
|
403
|
+
default:
|
|
404
|
+
throw new Error(`createInMemorySplitCall: a partitioned argument is an Array, a Set or a Dict, not ${t.type}`);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
function opened(type) {
|
|
408
|
+
return type.type === "Recursive" ? type.node : type;
|
|
409
|
+
}
|
|
410
|
+
function cutAt(value, type, fences, k) {
|
|
411
|
+
const compare = compareFor(opened(type).key);
|
|
412
|
+
const entries = [...value.entries()];
|
|
413
|
+
return Array.from({ length: k }, (_, i) => {
|
|
414
|
+
if (i > fences.length) return new SortedMap([], compare);
|
|
415
|
+
const lo = i === 0 ? void 0 : fences[i - 1];
|
|
416
|
+
const hi = i === fences.length ? void 0 : fences[i];
|
|
417
|
+
return new SortedMap(entries.filter(([key]) => (lo === void 0 || compare(key, lo) >= 0) && (hi === void 0 || compare(key, hi) < 0)), compare);
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
function cutTogether(values, types, partitioned, k) {
|
|
421
|
+
if (partitioned.length === 1) return { pieces: /* @__PURE__ */ new Map([[partitioned[0], cut(values[partitioned[0]], types[partitioned[0]], k)]]), over: partitioned[0] };
|
|
422
|
+
const keys = partitioned.map((i) => opened(types[i]));
|
|
423
|
+
const first = keys[0];
|
|
424
|
+
if (!keys.every((t) => t.type === "Dict" && first.type === "Dict" && isTypeEqual(t.key, first.key))) {
|
|
425
|
+
return "arguments partitioned together are dicts keyed by one type: their pieces are cut at the same keys";
|
|
426
|
+
}
|
|
427
|
+
let heaviest = partitioned[0];
|
|
428
|
+
let most = -1;
|
|
429
|
+
for (const i of partitioned) {
|
|
430
|
+
const bytes = encodeBeast2For(types[i])(values[i]).length;
|
|
431
|
+
if (bytes > most) [heaviest, most] = [i, bytes];
|
|
432
|
+
}
|
|
433
|
+
const runs = cut(values[heaviest], types[heaviest], k);
|
|
434
|
+
const fences = [];
|
|
435
|
+
for (const run of runs.slice(1)) {
|
|
436
|
+
const start = run.keys().next();
|
|
437
|
+
if (start.done === true) break;
|
|
438
|
+
fences.push(start.value);
|
|
439
|
+
}
|
|
440
|
+
return { pieces: new Map(partitioned.map((i) => [i, cutAt(values[i], types[i], fences, k)])), over: heaviest };
|
|
441
|
+
}
|
|
442
|
+
function progress(phase, done, units) {
|
|
443
|
+
return { phase: variant(phase, null), done: BigInt(done), units: BigInt(units) };
|
|
444
|
+
}
|
|
445
|
+
function createInMemorySplitCall(datasets, options) {
|
|
446
|
+
const pieces = options.pieces;
|
|
447
|
+
if (!Number.isSafeInteger(pieces) || pieces < 1) throw new RangeError(`createInMemorySplitCall: pieces is ${pieces}, not a whole number of at least 1`);
|
|
448
|
+
const held = hold(datasets);
|
|
449
|
+
const stored = /* @__PURE__ */ new Map();
|
|
450
|
+
const argumentsOf = (request) => {
|
|
451
|
+
const values = [];
|
|
452
|
+
const weights = [];
|
|
453
|
+
const inputs = [];
|
|
454
|
+
const partitioned = [];
|
|
455
|
+
for (const [i, { arg, partition }] of request.args.entries()) {
|
|
456
|
+
if (partition.type === "some") partitioned.push(i);
|
|
457
|
+
if (arg.type === "dataset") {
|
|
458
|
+
const found = held.find((d) => samePath(d.path, arg.value));
|
|
459
|
+
if (found === void 0) return unassigned(i, arg.value);
|
|
460
|
+
values.push(found.value);
|
|
461
|
+
weights.push(found.bytesOf());
|
|
462
|
+
inputs.push({ path: found.path, hash: found.hashOf() });
|
|
463
|
+
} else if (arg.type === "value") {
|
|
464
|
+
values.push(decodeBeast2(arg.value).value);
|
|
465
|
+
weights.push(arg.value.length);
|
|
466
|
+
} else {
|
|
467
|
+
const output = stored.get(arg.value);
|
|
468
|
+
if (output === void 0) return `Object argument ${i} names ${arg.value}, which the repository does not hold`;
|
|
469
|
+
values.push(output.value);
|
|
470
|
+
weights.push(output.bytes);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (partitioned.length === 0) return "a split call partitions at least one of its arguments: its pieces are cut from it";
|
|
474
|
+
return { values, weights, inputs, partitioned };
|
|
475
|
+
};
|
|
476
|
+
const call = async (request, { signal, onProgress }) => {
|
|
477
|
+
const refused2 = (message) => ({ result: invalid(message), output: null });
|
|
478
|
+
const resolved = argumentsOf(request);
|
|
479
|
+
if (typeof resolved === "string") return refused2(resolved);
|
|
480
|
+
const { values, inputs, partitioned } = resolved;
|
|
481
|
+
const body = compiled(request.bodyIr, "body");
|
|
482
|
+
const emitType = body.inputs.at(-1);
|
|
483
|
+
if ((emitType == null ? void 0 : emitType.type) !== "Function") throw new Error("createInMemorySplitCall: the body's last parameter is its emit function");
|
|
484
|
+
const emitted = emitType.inputs;
|
|
485
|
+
const then = request.then.type === "some" ? compiled(request.then.value, "final function") : void 0;
|
|
486
|
+
const output = request.output;
|
|
487
|
+
const cut2 = cutTogether(values, body.inputs, partitioned, pieces);
|
|
488
|
+
if (typeof cut2 === "string") return refused2(cut2);
|
|
489
|
+
const cuts = cut2.pieces;
|
|
490
|
+
let hash = null;
|
|
491
|
+
try {
|
|
492
|
+
const outputs = [];
|
|
493
|
+
onProgress(progress("partition", 0, pieces));
|
|
494
|
+
for (let p = 0; p < pieces; p++) {
|
|
495
|
+
signal.throwIfAborted();
|
|
496
|
+
const args = values.map((value, i) => {
|
|
497
|
+
var _a;
|
|
498
|
+
return ((_a = cuts.get(i)) == null ? void 0 : _a[p]) ?? value;
|
|
499
|
+
});
|
|
500
|
+
const out = [];
|
|
501
|
+
body.fn(...args, (...emit) => {
|
|
502
|
+
out.push(emit);
|
|
503
|
+
return null;
|
|
504
|
+
});
|
|
505
|
+
outputs.push(out);
|
|
506
|
+
onProgress(progress("partition", p + 1, pieces));
|
|
507
|
+
await Promise.resolve();
|
|
508
|
+
}
|
|
509
|
+
signal.throwIfAborted();
|
|
510
|
+
let assembled;
|
|
511
|
+
let type;
|
|
512
|
+
switch (output.type) {
|
|
513
|
+
case "array":
|
|
514
|
+
type = ArrayType(emitted[0]);
|
|
515
|
+
assembled = outputs.flatMap((out) => out.map(([row]) => row));
|
|
516
|
+
break;
|
|
517
|
+
case "set": {
|
|
518
|
+
const key = emitted[0];
|
|
519
|
+
type = SetType(key);
|
|
520
|
+
onProgress(progress("merge", 0, 1));
|
|
521
|
+
assembled = new SortedSet(outputs.flatMap((out) => out.map(([row]) => row)), compareFor(key));
|
|
522
|
+
onProgress(progress("merge", 1, 1));
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
case "dict": {
|
|
526
|
+
const [key, value] = [emitted[0], emitted[1]];
|
|
527
|
+
type = DictType(key, value);
|
|
528
|
+
const merge = output.value.merge.type === "some" ? compiled(output.value.merge.value, "merge").fn : void 0;
|
|
529
|
+
const printKey = printFor(key);
|
|
530
|
+
const into = (dict, k, v) => {
|
|
531
|
+
if (!dict.has(k)) {
|
|
532
|
+
dict.set(k, v);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (merge === void 0) throw new EastError(`the key ${printKey(k)} is emitted twice, and the dict output has no merge`);
|
|
536
|
+
dict.set(k, merge(k, dict.get(k), v));
|
|
537
|
+
};
|
|
538
|
+
const perPiece = outputs.map((out) => {
|
|
539
|
+
const dict = new SortedMap([], compareFor(key));
|
|
540
|
+
for (const [k, v] of out) into(dict, k, v);
|
|
541
|
+
return dict;
|
|
542
|
+
});
|
|
543
|
+
onProgress(progress("merge", 0, 1));
|
|
544
|
+
const all = new SortedMap([], compareFor(key));
|
|
545
|
+
for (const dict of perPiece) for (const [k, v] of dict) into(all, k, v);
|
|
546
|
+
onProgress(progress("merge", 1, 1));
|
|
547
|
+
assembled = all;
|
|
548
|
+
break;
|
|
549
|
+
}
|
|
550
|
+
case "fold": {
|
|
551
|
+
type = emitted[0];
|
|
552
|
+
const combine = compiled(output.value.combine, "combine").fn;
|
|
553
|
+
const zero = decodeBeast2For(type)(output.value.zero);
|
|
554
|
+
const partials = outputs.map((out) => out.reduce((acc, [v]) => combine(acc, v), zero));
|
|
555
|
+
onProgress(progress("combine", 0, 1));
|
|
556
|
+
assembled = partials.reduce((acc, v) => combine(acc, v), zero);
|
|
557
|
+
onProgress(progress("combine", 1, 1));
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const bytes = encodeBeast2For(type)(assembled);
|
|
562
|
+
hash = sha256Hex(bytes);
|
|
563
|
+
stored.set(hash, { value: assembled, bytes: bytes.length });
|
|
564
|
+
if (then === void 0) return { result: answer(type, assembled, request.limits, inputs), output: hash };
|
|
565
|
+
return { result: answer(then.output, then.fn(assembled, ...values), request.limits, inputs), output: hash };
|
|
566
|
+
} catch (err) {
|
|
567
|
+
if (!(err instanceof EastError)) throw err;
|
|
568
|
+
return { result: raised(err, inputs), output: hash };
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
const explain = async (request, { signal }) => {
|
|
572
|
+
signal.throwIfAborted();
|
|
573
|
+
const args = argumentsOf(request);
|
|
574
|
+
if (typeof args === "string") throw new Error(`Split call explain refused: ${args}`);
|
|
575
|
+
const cut2 = cutTogether(args.values, compiled(request.bodyIr, "body").inputs, args.partitioned, pieces);
|
|
576
|
+
if (typeof cut2 === "string") throw new Error(`Split call explain refused: ${cut2}`);
|
|
577
|
+
return { pieces: BigInt(pieces), over: BigInt(cut2.over), bytes: BigInt(args.weights[cut2.over]) };
|
|
578
|
+
};
|
|
579
|
+
return Object.assign(call, { explain });
|
|
580
|
+
}
|
|
581
|
+
function createInMemorySourceStatus(datasets) {
|
|
582
|
+
const held = hold(datasets);
|
|
583
|
+
return async (path) => {
|
|
584
|
+
const found = held.find((d) => samePath(d.path, path));
|
|
585
|
+
if (found === void 0) throw new Error(`createInMemorySourceStatus: nothing in memory at ${pathToString(path)}`);
|
|
586
|
+
return { rows: rowsOf(found), hash: found.hashOf(), bytes: found.bytesOf() };
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
function rowsOf(dataset) {
|
|
590
|
+
switch (dataset.type.type) {
|
|
591
|
+
case "Array":
|
|
592
|
+
return dataset.value.length;
|
|
593
|
+
case "Set":
|
|
594
|
+
return dataset.value.size;
|
|
595
|
+
case "Dict":
|
|
596
|
+
return dataset.value.size;
|
|
597
|
+
default:
|
|
598
|
+
return void 0;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
export {
|
|
602
|
+
createInMemorySourceStatus as a,
|
|
603
|
+
createInMemorySplitCall as b,
|
|
604
|
+
createInMemoryQueryCall as c,
|
|
605
|
+
draftPlan as d,
|
|
606
|
+
prepareQuery as e,
|
|
607
|
+
programChecks as f,
|
|
608
|
+
queryRoot as g,
|
|
609
|
+
planQuery as p,
|
|
610
|
+
queryResultOf as q,
|
|
611
|
+
rekeyCallRequests as r,
|
|
612
|
+
splitCallRequest as s,
|
|
613
|
+
weighPlan as w
|
|
614
|
+
};
|
|
615
|
+
//# sourceMappingURL=in-memory-call-7_3frW52.js.map
|