@gaganref/confect-test 10.3.1-fork.88 → 10.3.1-fork.89
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/internal/Attempt.d.ts +77 -0
- package/dist/internal/Attempt.d.ts.map +1 -0
- package/dist/internal/Attempt.js +154 -0
- package/dist/internal/Attempt.js.map +1 -0
- package/dist/internal/ConvexTest.d.ts +34 -0
- package/dist/internal/ConvexTest.d.ts.map +1 -0
- package/dist/internal/ConvexTest.js +59 -0
- package/dist/internal/ConvexTest.js.map +1 -0
- package/dist/internal/Execution.d.ts +167 -0
- package/dist/internal/Execution.d.ts.map +1 -0
- package/dist/internal/Execution.js +790 -0
- package/dist/internal/Execution.js.map +1 -0
- package/dist/internal/Globals.d.ts +11 -0
- package/dist/internal/Globals.d.ts.map +1 -0
- package/dist/internal/Globals.js +76 -0
- package/dist/internal/Globals.js.map +1 -0
- package/dist/internal/Kernel.d.ts +93 -0
- package/dist/internal/Kernel.d.ts.map +1 -0
- package/dist/internal/Kernel.js +91 -0
- package/dist/internal/Kernel.js.map +1 -0
- package/dist/internal/KernelQuery.d.ts +55 -0
- package/dist/internal/KernelQuery.d.ts.map +1 -0
- package/dist/internal/KernelQuery.js +205 -0
- package/dist/internal/KernelQuery.js.map +1 -0
- package/dist/internal/KernelRefusal.d.ts +77 -0
- package/dist/internal/KernelRefusal.d.ts.map +1 -0
- package/dist/internal/KernelRefusal.js +73 -0
- package/dist/internal/KernelRefusal.js.map +1 -0
- package/dist/internal/KernelValues.d.ts +136 -0
- package/dist/internal/KernelValues.d.ts.map +1 -0
- package/dist/internal/KernelValues.js +266 -0
- package/dist/internal/KernelValues.js.map +1 -0
- package/dist/internal/ReadSet.d.ts +55 -0
- package/dist/internal/ReadSet.d.ts.map +1 -0
- package/dist/internal/ReadSet.js +29 -0
- package/dist/internal/ReadSet.js.map +1 -0
- package/package.json +3 -3
- package/src/internal/Attempt.ts +185 -0
- package/src/internal/ConvexTest.ts +118 -0
- package/src/internal/Execution.ts +1430 -0
- package/src/internal/Globals.ts +93 -0
- package/src/internal/Kernel.ts +190 -0
- package/src/internal/KernelQuery.ts +405 -0
- package/src/internal/KernelRefusal.ts +88 -0
- package/src/internal/KernelValues.ts +725 -0
- package/src/internal/ReadSet.ts +108 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { evaluateFieldPath, evaluateFilter, evaluateRangeFilter, isValidIdentifier, resolvePendingValues, validateFieldNames, validateIndexRangeExpression, validateValidator } from "./KernelValues.js";
|
|
2
|
+
import { keyOf } from "./ReadSet.js";
|
|
3
|
+
import { requiresBinary } from "./KernelRefusal.js";
|
|
4
|
+
import { compareValues, convexToJson, getDocumentSize, jsonToConvex } from "convex/values";
|
|
5
|
+
//#region src/internal/KernelQuery.ts
|
|
6
|
+
const exportSchema = (schema) => {
|
|
7
|
+
if (schema === null || schema === void 0) return null;
|
|
8
|
+
const exported = {
|
|
9
|
+
schemaValidation: schema.schemaValidation,
|
|
10
|
+
tables: new Map(Object.entries(schema.tables).map(([name, table]) => [name, table.export()]))
|
|
11
|
+
};
|
|
12
|
+
exported.tables.forEach((table, tableName) => {
|
|
13
|
+
if (!isValidIdentifier(tableName)) throw new Error(`Table names must be valid identifiers, got "${tableName}"`);
|
|
14
|
+
validateFieldNames(table.documentType);
|
|
15
|
+
table.indexes.forEach(({ indexDescriptor }) => {
|
|
16
|
+
if (!isValidIdentifier(indexDescriptor)) throw new Error(`Index names must be valid identifiers, got "${indexDescriptor}"`);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
return exported;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Check a document against its table's declared type, as the backend does
|
|
23
|
+
* before a write.
|
|
24
|
+
*/
|
|
25
|
+
const validateDocument = (schema, tableName, doc) => {
|
|
26
|
+
if (schema === null || !schema.schemaValidation) return;
|
|
27
|
+
const validator = schema.tables.get(tableName)?.documentType;
|
|
28
|
+
if (validator === void 0) return;
|
|
29
|
+
validateValidator(validator, resolvePendingValues(doc));
|
|
30
|
+
};
|
|
31
|
+
const resolveSource = (view, query) => {
|
|
32
|
+
const source = query.source;
|
|
33
|
+
let docs;
|
|
34
|
+
let fieldPathsToSortBy;
|
|
35
|
+
let order;
|
|
36
|
+
let table;
|
|
37
|
+
let range = [];
|
|
38
|
+
switch (source.type) {
|
|
39
|
+
case "FullTableScan":
|
|
40
|
+
table = source.tableName;
|
|
41
|
+
docs = [...view.scan(source.tableName)];
|
|
42
|
+
order = source.order ?? "asc";
|
|
43
|
+
fieldPathsToSortBy = ["_creationTime"];
|
|
44
|
+
break;
|
|
45
|
+
case "IndexRange": {
|
|
46
|
+
const [tableName, indexName] = source.indexName.split(".");
|
|
47
|
+
table = tableName;
|
|
48
|
+
range = source.range;
|
|
49
|
+
order = source.order ?? "asc";
|
|
50
|
+
let fields;
|
|
51
|
+
if (indexName === "by_creation_time") fields = ["_creationTime", "_id"];
|
|
52
|
+
else if (indexName === "by_id") fields = ["_id"];
|
|
53
|
+
else {
|
|
54
|
+
const index = view.schema?.tables.get(tableName)?.indexes.find(({ indexDescriptor }) => indexDescriptor === indexName);
|
|
55
|
+
if (index === void 0) throw new Error(`Cannot use index "${indexName}" for table "${tableName}" because it is not declared in the schema.`);
|
|
56
|
+
fields = index.fields.concat(["_creationTime", "_id"]);
|
|
57
|
+
}
|
|
58
|
+
fieldPathsToSortBy = fields;
|
|
59
|
+
validateIndexRangeExpression(source, fields);
|
|
60
|
+
docs = view.scan(tableName).filter((doc) => source.range.every((filter) => evaluateRangeFilter(doc, filter)));
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case "Search": throw requiresBinary("textSearch");
|
|
64
|
+
}
|
|
65
|
+
const filters = query.operators.filter((operator) => "filter" in operator).map((operator) => operator.filter);
|
|
66
|
+
const limit = query.operators.find((operator) => "limit" in operator) ?? null;
|
|
67
|
+
const orderMultiplier = order === "asc" ? 1 : -1;
|
|
68
|
+
docs.sort((a, b) => {
|
|
69
|
+
for (const fp of fieldPathsToSortBy) {
|
|
70
|
+
const v = compareValues(evaluateFieldPath(fp, a), evaluateFieldPath(fp, b));
|
|
71
|
+
if (v !== 0) return v * orderMultiplier;
|
|
72
|
+
}
|
|
73
|
+
return 0;
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
sortedDocs: docs,
|
|
77
|
+
filterFn: (doc) => filters.every((f) => evaluateFilter(doc, f)),
|
|
78
|
+
limit: limit?.limit ?? null,
|
|
79
|
+
order,
|
|
80
|
+
interval: {
|
|
81
|
+
kind: "interval",
|
|
82
|
+
table,
|
|
83
|
+
fields: fieldPathsToSortBy.includes("_id") ? fieldPathsToSortBy : [...fieldPathsToSortBy, "_id"],
|
|
84
|
+
order,
|
|
85
|
+
range
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* A query's documents in order. The source is read when the query starts, as a
|
|
91
|
+
* snapshot, and consumed lazily. The read set holds the prefix the stream has
|
|
92
|
+
* examined, filtered documents included, or the whole range once it ends.
|
|
93
|
+
*/
|
|
94
|
+
const stream = (view, query) => {
|
|
95
|
+
const { sortedDocs, filterFn, limit, interval } = resolveSource(view, query);
|
|
96
|
+
const examined = view.read(interval, null);
|
|
97
|
+
return (function* () {
|
|
98
|
+
let returned = 0;
|
|
99
|
+
for (const doc of sortedDocs) {
|
|
100
|
+
if (limit !== null && returned >= limit) return;
|
|
101
|
+
examined(keyOf(interval.fields, doc));
|
|
102
|
+
if (filterFn(doc)) {
|
|
103
|
+
returned++;
|
|
104
|
+
yield doc;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
examined("end");
|
|
108
|
+
})();
|
|
109
|
+
};
|
|
110
|
+
const encodeCursor = (doc, fieldPaths) => JSON.stringify(fieldPaths.map((fp) => {
|
|
111
|
+
const k = evaluateFieldPath(fp, doc);
|
|
112
|
+
return k === void 0 ? null : JSON.stringify(convexToJson(k));
|
|
113
|
+
}));
|
|
114
|
+
const parseCursor = (c) => c ? JSON.parse(c).map((k) => k === null ? void 0 : jsonToConvex(JSON.parse(k))) : null;
|
|
115
|
+
const compareToCursor = (doc, cursorKeys, fieldPaths, order) => {
|
|
116
|
+
const orderMultiplier = order === "asc" ? 1 : -1;
|
|
117
|
+
for (let i = 0; i < fieldPaths.length; i++) {
|
|
118
|
+
const cmp = compareValues(evaluateFieldPath(fieldPaths[i], doc), cursorKeys[i]);
|
|
119
|
+
if (cmp !== 0) return cmp * orderMultiplier;
|
|
120
|
+
}
|
|
121
|
+
return 0;
|
|
122
|
+
};
|
|
123
|
+
const paginate = (view, { query, cursor, endCursor, pageSize, maximumRowsRead, maximumBytesRead }) => {
|
|
124
|
+
const { sortedDocs, filterFn, order, interval } = resolveSource(view, query);
|
|
125
|
+
if (cursor === "_end_cursor") return {
|
|
126
|
+
page: [],
|
|
127
|
+
isDone: true,
|
|
128
|
+
continueCursor: "_end_cursor",
|
|
129
|
+
splitCursor: null,
|
|
130
|
+
pageStatus: null
|
|
131
|
+
};
|
|
132
|
+
const cursorFields = interval.fields;
|
|
133
|
+
const cursorKeys = parseCursor(cursor);
|
|
134
|
+
const hasEndBoundary = !!endCursor && endCursor !== "_end_cursor";
|
|
135
|
+
const endCursorKeys = hasEndBoundary ? parseCursor(endCursor) : null;
|
|
136
|
+
const examined = view.read(interval, cursorKeys);
|
|
137
|
+
let reachedEnd = true;
|
|
138
|
+
const page = [];
|
|
139
|
+
let isInPage = cursor === null;
|
|
140
|
+
let continueCursor = "_end_cursor";
|
|
141
|
+
let splitCursor = null;
|
|
142
|
+
let pageStatus = null;
|
|
143
|
+
let rowsRead = 0;
|
|
144
|
+
let bytesRead = 0;
|
|
145
|
+
const readDocCursors = [];
|
|
146
|
+
for (let i = 0; i < sortedDocs.length; i++) {
|
|
147
|
+
const doc = sortedDocs[i];
|
|
148
|
+
const isLastDoc = i === sortedDocs.length - 1;
|
|
149
|
+
if (!isInPage) {
|
|
150
|
+
if (cursorKeys) {
|
|
151
|
+
if (compareToCursor(doc, cursorKeys, cursorFields, order) > 0) isInPage = true;
|
|
152
|
+
else continue;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (hasEndBoundary && endCursorKeys) {
|
|
156
|
+
const cmp = compareToCursor(doc, endCursorKeys, cursorFields, order);
|
|
157
|
+
if (cmp >= 0) {
|
|
158
|
+
reachedEnd = false;
|
|
159
|
+
examined(endCursorKeys);
|
|
160
|
+
if (cmp === 0) {
|
|
161
|
+
rowsRead += 1;
|
|
162
|
+
bytesRead += getDocumentSize(doc);
|
|
163
|
+
readDocCursors.push(encodeCursor(doc, cursorFields));
|
|
164
|
+
if (filterFn(doc)) page.push(doc);
|
|
165
|
+
continueCursor = encodeCursor(doc, cursorFields);
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
rowsRead += 1;
|
|
171
|
+
bytesRead += getDocumentSize(doc);
|
|
172
|
+
readDocCursors.push(encodeCursor(doc, cursorFields));
|
|
173
|
+
examined(keyOf(cursorFields, doc));
|
|
174
|
+
const hitLimit = !!maximumRowsRead && rowsRead >= maximumRowsRead || !!maximumBytesRead && bytesRead >= maximumBytesRead;
|
|
175
|
+
if (filterFn(doc)) page.push(doc);
|
|
176
|
+
if (hitLimit) {
|
|
177
|
+
reachedEnd = false;
|
|
178
|
+
pageStatus = "SplitRequired";
|
|
179
|
+
continueCursor = encodeCursor(doc, cursorFields);
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
if (!endCursor && page.length >= pageSize) {
|
|
183
|
+
reachedEnd = isLastDoc;
|
|
184
|
+
if (!isLastDoc) continueCursor = encodeCursor(doc, cursorFields);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (reachedEnd) examined(endCursorKeys ?? "end");
|
|
189
|
+
if (pageStatus === "SplitRequired" && readDocCursors.length >= 2) splitCursor = readDocCursors[Math.floor((readDocCursors.length - 1) / 2)];
|
|
190
|
+
else if (pageStatus === null && rowsRead > pageSize + 1 && readDocCursors.length >= 2) {
|
|
191
|
+
pageStatus = "SplitRecommended";
|
|
192
|
+
splitCursor = readDocCursors[Math.floor((readDocCursors.length - 1) / 2)];
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
page,
|
|
196
|
+
isDone: continueCursor === "_end_cursor",
|
|
197
|
+
continueCursor,
|
|
198
|
+
splitCursor,
|
|
199
|
+
pageStatus
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
//#endregion
|
|
203
|
+
export { exportSchema, paginate, stream, validateDocument };
|
|
204
|
+
|
|
205
|
+
//# sourceMappingURL=KernelQuery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KernelQuery.js","names":["KernelRefusal.requiresBinary","ReadSet.keyOf"],"sources":["../../src/internal/KernelQuery.ts"],"sourcesContent":["// Derived from convex-test 0.0.65 (index.ts, `DatabaseFake`), Copyright Convex,\n// Inc., licensed under the Apache License, Version 2.0\n// (https://www.apache.org/licenses/LICENSE-2.0). The ordering, index range and\n// pagination rules are convex-test's. They read a table through the attempt\n// that runs the query instead of convex-test's database, and record the\n// interval each query examined.\n\nimport type {\n GenericDocument,\n GenericSchema,\n SchemaDefinition,\n} from \"convex/server\";\nimport {\n compareValues,\n convexToJson,\n getDocumentSize,\n jsonToConvex,\n} from \"convex/values\";\nimport * as KernelRefusal from \"./KernelRefusal.js\";\nimport * as ReadSet from \"./ReadSet.js\";\nimport type {\n FilterJson,\n Index,\n SerializedQuery,\n SerializedRangeExpression,\n StoredDocument,\n ValidatorJSON,\n} from \"./KernelValues.js\";\nimport {\n evaluateFieldPath,\n evaluateFilter,\n evaluateRangeFilter,\n isValidIdentifier,\n resolvePendingValues,\n validateFieldNames,\n validateIndexRangeExpression,\n validateValidator,\n} from \"./KernelValues.js\";\n\n/**\n * A component's tables as its schema declares them.\n */\nexport interface KernelSchema {\n readonly schemaValidation: boolean;\n readonly tables: ReadonlyMap<\n string,\n {\n readonly indexes: ReadonlyArray<Index>;\n readonly documentType: ValidatorJSON;\n }\n >;\n}\n\nexport const exportSchema = (\n schema: SchemaDefinition<GenericSchema, boolean> | null | undefined,\n): KernelSchema | null => {\n if (schema === null || schema === undefined) return null;\n const exported: KernelSchema = {\n schemaValidation: (schema as unknown as { schemaValidation: boolean })\n .schemaValidation,\n tables: new Map(\n Object.entries(schema.tables).map(([name, table]) => [\n name,\n (table as unknown as { export: () => any }).export(),\n ]),\n ),\n };\n exported.tables.forEach((table, tableName) => {\n if (!isValidIdentifier(tableName)) {\n throw new Error(\n `Table names must be valid identifiers, got \"${tableName}\"`,\n );\n }\n validateFieldNames(table.documentType);\n table.indexes.forEach(({ indexDescriptor }) => {\n if (!isValidIdentifier(indexDescriptor)) {\n throw new Error(\n `Index names must be valid identifiers, got \"${indexDescriptor}\"`,\n );\n }\n });\n });\n return exported;\n};\n\n/**\n * Check a document against its table's declared type, as the backend does\n * before a write.\n */\nexport const validateDocument = (\n schema: KernelSchema | null,\n tableName: string,\n doc: Record<string, unknown>,\n) => {\n if (schema === null || !schema.schemaValidation) return;\n const validator = schema.tables.get(tableName)?.documentType;\n if (validator === undefined) return;\n validateValidator(validator, resolvePendingValues(doc as GenericDocument));\n};\n\n/**\n * An interval a query reads, before it says where it starts and how far it got.\n */\nexport type Interval = Omit<\n ReadSet.IntervalRead,\n \"componentPath\" | \"after\" | \"through\"\n>;\n\n/**\n * What a query reads: one table of one component, as the running attempt sees\n * it. `read` records an interval in the attempt's read set and returns how to\n * advance it.\n */\nexport interface TableView {\n readonly schema: KernelSchema | null;\n readonly scan: (tableName: string) => ReadonlyArray<StoredDocument>;\n readonly read: (\n interval: Interval,\n after: ReadSet.Key | null,\n ) => (through: ReadSet.Key | \"end\") => void;\n}\n\ninterface ResolvedSource {\n readonly sortedDocs: ReadonlyArray<GenericDocument>;\n readonly filterFn: (doc: GenericDocument) => boolean;\n readonly limit: number | null;\n readonly order: \"asc\" | \"desc\";\n readonly interval: Interval;\n}\n\nconst resolveSource = (\n view: TableView,\n query: SerializedQuery,\n): ResolvedSource => {\n const source = query.source;\n let docs: Array<GenericDocument>;\n let fieldPathsToSortBy: Array<string>;\n let order: \"asc\" | \"desc\";\n let table: string;\n let range: ReadonlyArray<SerializedRangeExpression> = [];\n switch (source.type) {\n case \"FullTableScan\": {\n table = source.tableName;\n docs = [...view.scan(source.tableName)];\n order = source.order ?? \"asc\";\n fieldPathsToSortBy = [\"_creationTime\"];\n break;\n }\n case \"IndexRange\": {\n const [tableName, indexName] = source.indexName.split(\".\") as [\n string,\n string,\n ];\n table = tableName;\n range = source.range;\n order = source.order ?? \"asc\";\n let fields: Array<string>;\n if (indexName === \"by_creation_time\") {\n fields = [\"_creationTime\", \"_id\"];\n } else if (indexName === \"by_id\") {\n fields = [\"_id\"];\n } else {\n const index = view.schema?.tables\n .get(tableName)\n ?.indexes.find(\n ({ indexDescriptor }) => indexDescriptor === indexName,\n );\n if (index === undefined) {\n throw new Error(\n `Cannot use index \"${indexName}\" for table \"${tableName}\" because ` +\n `it is not declared in the schema.`,\n );\n }\n fields = index.fields.concat([\"_creationTime\", \"_id\"]);\n }\n fieldPathsToSortBy = fields;\n validateIndexRangeExpression(source, fields);\n docs = view\n .scan(tableName)\n .filter((doc) =>\n source.range.every((filter) => evaluateRangeFilter(doc, filter)),\n );\n break;\n }\n case \"Search\": {\n throw KernelRefusal.requiresBinary(\"textSearch\");\n }\n }\n\n const filters = query.operators\n .filter(\n (operator): operator is { filter: FilterJson } => \"filter\" in operator,\n )\n .map((operator) => operator.filter);\n const limit =\n query.operators.find(\n (operator): operator is { limit: number } => \"limit\" in operator,\n ) ?? null;\n\n const orderMultiplier = order === \"asc\" ? 1 : -1;\n docs.sort((a, b) => {\n for (const fp of fieldPathsToSortBy) {\n const v = compareValues(\n evaluateFieldPath(fp, a),\n evaluateFieldPath(fp, b),\n );\n if (v !== 0) return v * orderMultiplier;\n }\n return 0;\n });\n\n return {\n sortedDocs: docs,\n filterFn: (doc) => filters.every((f) => evaluateFilter(doc, f)),\n limit: limit?.limit ?? null,\n order,\n interval: {\n kind: \"interval\",\n table,\n fields: fieldPathsToSortBy.includes(\"_id\")\n ? fieldPathsToSortBy\n : [...fieldPathsToSortBy, \"_id\"],\n order,\n range,\n },\n };\n};\n\n/**\n * A query's documents in order. The source is read when the query starts, as a\n * snapshot, and consumed lazily. The read set holds the prefix the stream has\n * examined, filtered documents included, or the whole range once it ends.\n */\nexport const stream = (\n view: TableView,\n query: SerializedQuery,\n): Iterator<GenericDocument> => {\n const { sortedDocs, filterFn, limit, interval } = resolveSource(view, query);\n const examined = view.read(interval, null);\n return (function* () {\n let returned = 0;\n for (const doc of sortedDocs) {\n if (limit !== null && returned >= limit) return;\n examined(ReadSet.keyOf(interval.fields, doc as StoredDocument));\n if (filterFn(doc)) {\n returned++;\n yield doc;\n }\n }\n examined(\"end\");\n })();\n};\n\nconst encodeCursor = (\n doc: GenericDocument,\n fieldPaths: ReadonlyArray<string>,\n): string =>\n JSON.stringify(\n fieldPaths.map((fp) => {\n const k = evaluateFieldPath(fp, doc);\n return k === undefined ? null : JSON.stringify(convexToJson(k));\n }),\n );\n\nconst parseCursor = (c: string | null | undefined) =>\n c\n ? (JSON.parse(c) as Array<string | null>).map((k) =>\n k === null ? undefined : jsonToConvex(JSON.parse(k)),\n )\n : null;\n\nconst compareToCursor = (\n doc: GenericDocument,\n cursorKeys: ReadonlyArray<unknown>,\n fieldPaths: ReadonlyArray<string>,\n order: \"asc\" | \"desc\",\n): number => {\n const orderMultiplier = order === \"asc\" ? 1 : -1;\n for (let i = 0; i < fieldPaths.length; i++) {\n const cmp = compareValues(\n evaluateFieldPath(fieldPaths[i]!, doc),\n cursorKeys[i] as any,\n );\n if (cmp !== 0) return cmp * orderMultiplier;\n }\n return 0;\n};\n\nexport interface PageRequest {\n readonly query: SerializedQuery;\n readonly cursor: string | null;\n readonly endCursor?: string | null;\n readonly pageSize: number;\n readonly maximumRowsRead?: number | null;\n readonly maximumBytesRead?: number | null;\n}\n\nexport const paginate = (\n view: TableView,\n {\n query,\n cursor,\n endCursor,\n pageSize,\n maximumRowsRead,\n maximumBytesRead,\n }: PageRequest,\n) => {\n const { sortedDocs, filterFn, order, interval } = resolveSource(view, query);\n // A page from the terminal cursor reads the empty interval past the end, so\n // it depends on nothing.\n if (cursor === \"_end_cursor\") {\n return {\n page: [],\n isDone: true,\n continueCursor: \"_end_cursor\",\n splitCursor: null,\n pageStatus: null,\n };\n }\n const cursorFields = interval.fields;\n const cursorKeys = parseCursor(cursor);\n const hasEndBoundary = !!endCursor && endCursor !== \"_end_cursor\";\n const endCursorKeys = hasEndBoundary ? parseCursor(endCursor) : null;\n const examined = view.read(interval, cursorKeys);\n let reachedEnd = true;\n\n const page: Array<GenericDocument> = [];\n let isInPage = cursor === null;\n let continueCursor = \"_end_cursor\";\n let splitCursor: string | null = null;\n let pageStatus: \"SplitRecommended\" | \"SplitRequired\" | null = null;\n let rowsRead = 0;\n let bytesRead = 0;\n const readDocCursors: Array<string> = [];\n\n for (let i = 0; i < sortedDocs.length; i++) {\n const doc = sortedDocs[i]!;\n const isLastDoc = i === sortedDocs.length - 1;\n if (!isInPage) {\n if (cursorKeys) {\n if (compareToCursor(doc, cursorKeys, cursorFields, order) > 0) {\n isInPage = true;\n } else {\n continue;\n }\n }\n }\n if (hasEndBoundary && endCursorKeys) {\n const cmp = compareToCursor(doc, endCursorKeys, cursorFields, order);\n if (cmp >= 0) {\n reachedEnd = false;\n examined(endCursorKeys);\n if (cmp === 0) {\n rowsRead += 1;\n bytesRead += getDocumentSize(doc);\n readDocCursors.push(encodeCursor(doc, cursorFields));\n if (filterFn(doc)) page.push(doc);\n continueCursor = encodeCursor(doc, cursorFields);\n }\n break;\n }\n }\n rowsRead += 1;\n bytesRead += getDocumentSize(doc);\n readDocCursors.push(encodeCursor(doc, cursorFields));\n examined(ReadSet.keyOf(cursorFields, doc as StoredDocument));\n const hitLimit =\n (!!maximumRowsRead && rowsRead >= maximumRowsRead) ||\n (!!maximumBytesRead && bytesRead >= maximumBytesRead);\n if (filterFn(doc)) page.push(doc);\n if (hitLimit) {\n reachedEnd = false;\n pageStatus = \"SplitRequired\";\n continueCursor = encodeCursor(doc, cursorFields);\n break;\n }\n if (!endCursor && page.length >= pageSize) {\n reachedEnd = isLastDoc;\n if (!isLastDoc) continueCursor = encodeCursor(doc, cursorFields);\n break;\n }\n }\n // A page bounded by an end cursor examined the range only up to it.\n if (reachedEnd) examined(endCursorKeys ?? \"end\");\n\n if (pageStatus === \"SplitRequired\" && readDocCursors.length >= 2) {\n splitCursor = readDocCursors[Math.floor((readDocCursors.length - 1) / 2)]!;\n } else if (\n pageStatus === null &&\n rowsRead > pageSize + 1 &&\n readDocCursors.length >= 2\n ) {\n pageStatus = \"SplitRecommended\";\n splitCursor = readDocCursors[Math.floor((readDocCursors.length - 1) / 2)]!;\n }\n\n return {\n page,\n isDone: continueCursor === \"_end_cursor\",\n continueCursor,\n splitCursor,\n pageStatus,\n };\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
declare const RequiresBinary_base: Schema.Class<RequiresBinary, Schema.TaggedStruct<"RequiresBinary", {
|
|
3
|
+
readonly operation: Schema.Literals<readonly ["textSearch", "vectorSearch"]>;
|
|
4
|
+
readonly message: Schema.String;
|
|
5
|
+
}>, import("effect/Cause").YieldableError>;
|
|
6
|
+
/**
|
|
7
|
+
* The kernel never answers this operation in process. Only the binary does.
|
|
8
|
+
*/
|
|
9
|
+
export declare class RequiresBinary extends RequiresBinary_base {
|
|
10
|
+
}
|
|
11
|
+
declare const KernelRowPending_base: Schema.Class<KernelRowPending, Schema.TaggedStruct<"KernelRowPending", {
|
|
12
|
+
readonly operation: Schema.String;
|
|
13
|
+
readonly row: Schema.Int;
|
|
14
|
+
readonly message: Schema.String;
|
|
15
|
+
}>, import("effect/Cause").YieldableError>;
|
|
16
|
+
/**
|
|
17
|
+
* A later kernel row supplies this operation. Until then the kernel refuses it
|
|
18
|
+
* rather than answer with convex-test's behaviour.
|
|
19
|
+
*/
|
|
20
|
+
export declare class KernelRowPending extends KernelRowPending_base {
|
|
21
|
+
}
|
|
22
|
+
declare const RegisteredAfterOpen_base: Schema.Class<RegisteredAfterOpen, Schema.TaggedStruct<"RegisteredAfterOpen", {
|
|
23
|
+
readonly componentPath: Schema.String;
|
|
24
|
+
readonly message: Schema.String;
|
|
25
|
+
}>, import("effect/Cause").YieldableError>;
|
|
26
|
+
/**
|
|
27
|
+
* A component was registered after the test backend opened, so its modules
|
|
28
|
+
* would load after a function had already run.
|
|
29
|
+
*/
|
|
30
|
+
export declare class RegisteredAfterOpen extends RegisteredAfterOpen_base {
|
|
31
|
+
}
|
|
32
|
+
declare const OptimisticConcurrencyControlFailure_base: Schema.Class<OptimisticConcurrencyControlFailure, Schema.TaggedStruct<"OptimisticConcurrencyControlFailure", {
|
|
33
|
+
readonly attempts: Schema.Int;
|
|
34
|
+
readonly message: Schema.String;
|
|
35
|
+
}>, import("effect/Cause").YieldableError>;
|
|
36
|
+
/**
|
|
37
|
+
* Every attempt of a mutation read data a commit changed before it could
|
|
38
|
+
* publish. The kernel gives up on attempt 5.
|
|
39
|
+
*/
|
|
40
|
+
export declare class OptimisticConcurrencyControlFailure extends OptimisticConcurrencyControlFailure_base {
|
|
41
|
+
}
|
|
42
|
+
declare const ClosedAttempt_base: Schema.Class<ClosedAttempt, Schema.TaggedStruct<"ClosedAttempt", {
|
|
43
|
+
readonly operation: Schema.String;
|
|
44
|
+
readonly message: Schema.String;
|
|
45
|
+
}>, import("effect/Cause").YieldableError>;
|
|
46
|
+
/**
|
|
47
|
+
* A syscall reached a mutation's attempt after the mutation returned and its
|
|
48
|
+
* syscalls drained, so the attempt was already held or published.
|
|
49
|
+
*/
|
|
50
|
+
export declare class ClosedAttempt extends ClosedAttempt_base {
|
|
51
|
+
}
|
|
52
|
+
declare const StaleAttempt_base: Schema.Class<StaleAttempt, Schema.TaggedStruct<"StaleAttempt", {
|
|
53
|
+
readonly id: Schema.String;
|
|
54
|
+
readonly message: Schema.String;
|
|
55
|
+
}>, import("effect/Cause").YieldableError>;
|
|
56
|
+
/**
|
|
57
|
+
* `apply` named an attempt the kernel does not hold: it was already applied, or
|
|
58
|
+
* never prepared.
|
|
59
|
+
*/
|
|
60
|
+
export declare class StaleAttempt extends StaleAttempt_base {
|
|
61
|
+
}
|
|
62
|
+
declare const CommitTsNotIncreasing_base: Schema.Class<CommitTsNotIncreasing, Schema.TaggedStruct<"CommitTsNotIncreasing", {
|
|
63
|
+
readonly version: Schema.Int;
|
|
64
|
+
readonly previous: Schema.BigInt;
|
|
65
|
+
readonly commitTs: Schema.BigInt;
|
|
66
|
+
readonly message: Schema.String;
|
|
67
|
+
}>, import("effect/Cause").YieldableError>;
|
|
68
|
+
/**
|
|
69
|
+
* The runtime answered a commit timestamp no greater than the previous
|
|
70
|
+
* commit's.
|
|
71
|
+
*/
|
|
72
|
+
export declare class CommitTsNotIncreasing extends CommitTsNotIncreasing_base {
|
|
73
|
+
}
|
|
74
|
+
export declare const requiresBinary: (operation: RequiresBinary["operation"]) => RequiresBinary;
|
|
75
|
+
export declare const rowPending: (operation: string, row: number) => KernelRowPending;
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=KernelRefusal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KernelRefusal.d.ts","sourceRoot":"","sources":["../../src/internal/KernelRefusal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;;;;AAExC;;GAEG;AACH,qBAAa,cAAe,SAAQ,mBAMnC;CAAG;;;;;;AAEJ;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,qBAOrC;CAAG;;;;;AAEJ;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,wBAGxC;CAAG;;;;;AAEJ;;;GAGG;AACH,qBAAa,mCAAoC,SAAQ,wCAGxD;CAAG;;;;;AAEJ;;;GAGG;AACH,qBAAa,aAAc,SAAQ,kBAGlC;CAAG;;;;;AAEJ;;;GAGG;AACH,qBAAa,YAAa,SAAQ,iBAGjC;CAAG;;;;;;;AAEJ;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,0BAQ1C;CAAG;AAEJ,eAAO,MAAM,cAAc,cAAe,cAAc,CAAC,WAAW,CAAC,mBAIjE,CAAC;AAEL,eAAO,MAAM,UAAU,cAAe,MAAM,OAAO,MAAM,qBAKrD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
//#region src/internal/KernelRefusal.ts
|
|
3
|
+
/**
|
|
4
|
+
* The kernel never answers this operation in process. Only the binary does.
|
|
5
|
+
*/
|
|
6
|
+
var RequiresBinary = class extends Schema.TaggedError()("RequiresBinary", {
|
|
7
|
+
operation: Schema.Literals(["textSearch", "vectorSearch"]),
|
|
8
|
+
message: Schema.String
|
|
9
|
+
}) {};
|
|
10
|
+
/**
|
|
11
|
+
* A later kernel row supplies this operation. Until then the kernel refuses it
|
|
12
|
+
* rather than answer with convex-test's behaviour.
|
|
13
|
+
*/
|
|
14
|
+
var KernelRowPending = class extends Schema.TaggedError()("KernelRowPending", {
|
|
15
|
+
operation: Schema.String,
|
|
16
|
+
row: Schema.Int,
|
|
17
|
+
message: Schema.String
|
|
18
|
+
}) {};
|
|
19
|
+
/**
|
|
20
|
+
* A component was registered after the test backend opened, so its modules
|
|
21
|
+
* would load after a function had already run.
|
|
22
|
+
*/
|
|
23
|
+
var RegisteredAfterOpen = class extends Schema.TaggedError()("RegisteredAfterOpen", {
|
|
24
|
+
componentPath: Schema.String,
|
|
25
|
+
message: Schema.String
|
|
26
|
+
}) {};
|
|
27
|
+
/**
|
|
28
|
+
* Every attempt of a mutation read data a commit changed before it could
|
|
29
|
+
* publish. The kernel gives up on attempt 5.
|
|
30
|
+
*/
|
|
31
|
+
var OptimisticConcurrencyControlFailure = class extends Schema.TaggedError()("OptimisticConcurrencyControlFailure", {
|
|
32
|
+
attempts: Schema.Int,
|
|
33
|
+
message: Schema.String
|
|
34
|
+
}) {};
|
|
35
|
+
/**
|
|
36
|
+
* A syscall reached a mutation's attempt after the mutation returned and its
|
|
37
|
+
* syscalls drained, so the attempt was already held or published.
|
|
38
|
+
*/
|
|
39
|
+
var ClosedAttempt = class extends Schema.TaggedError()("ClosedAttempt", {
|
|
40
|
+
operation: Schema.String,
|
|
41
|
+
message: Schema.String
|
|
42
|
+
}) {};
|
|
43
|
+
/**
|
|
44
|
+
* `apply` named an attempt the kernel does not hold: it was already applied, or
|
|
45
|
+
* never prepared.
|
|
46
|
+
*/
|
|
47
|
+
var StaleAttempt = class extends Schema.TaggedError()("StaleAttempt", {
|
|
48
|
+
id: Schema.String,
|
|
49
|
+
message: Schema.String
|
|
50
|
+
}) {};
|
|
51
|
+
/**
|
|
52
|
+
* The runtime answered a commit timestamp no greater than the previous
|
|
53
|
+
* commit's.
|
|
54
|
+
*/
|
|
55
|
+
var CommitTsNotIncreasing = class extends Schema.TaggedError()("CommitTsNotIncreasing", {
|
|
56
|
+
version: Schema.Int,
|
|
57
|
+
previous: Schema.BigInt,
|
|
58
|
+
commitTs: Schema.BigInt,
|
|
59
|
+
message: Schema.String
|
|
60
|
+
}) {};
|
|
61
|
+
const requiresBinary = (operation) => new RequiresBinary({
|
|
62
|
+
operation,
|
|
63
|
+
message: `The test kernel does not simulate ${operation}. Run this case against the Convex binary.`
|
|
64
|
+
});
|
|
65
|
+
const rowPending = (operation, row) => new KernelRowPending({
|
|
66
|
+
operation,
|
|
67
|
+
row,
|
|
68
|
+
message: `The test kernel supplies ${operation} in build-order row ${row}.`
|
|
69
|
+
});
|
|
70
|
+
//#endregion
|
|
71
|
+
export { ClosedAttempt, CommitTsNotIncreasing, KernelRowPending, OptimisticConcurrencyControlFailure, RegisteredAfterOpen, RequiresBinary, StaleAttempt, requiresBinary, rowPending };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=KernelRefusal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KernelRefusal.js","names":[],"sources":["../../src/internal/KernelRefusal.ts"],"sourcesContent":["import * as Schema from \"effect/Schema\";\n\n/**\n * The kernel never answers this operation in process. Only the binary does.\n */\nexport class RequiresBinary extends Schema.TaggedError<RequiresBinary>()(\n \"RequiresBinary\",\n {\n operation: Schema.Literals([\"textSearch\", \"vectorSearch\"]),\n message: Schema.String,\n },\n) {}\n\n/**\n * A later kernel row supplies this operation. Until then the kernel refuses it\n * rather than answer with convex-test's behaviour.\n */\nexport class KernelRowPending extends Schema.TaggedError<KernelRowPending>()(\n \"KernelRowPending\",\n {\n operation: Schema.String,\n row: Schema.Int,\n message: Schema.String,\n },\n) {}\n\n/**\n * A component was registered after the test backend opened, so its modules\n * would load after a function had already run.\n */\nexport class RegisteredAfterOpen extends Schema.TaggedError<RegisteredAfterOpen>()(\n \"RegisteredAfterOpen\",\n { componentPath: Schema.String, message: Schema.String },\n) {}\n\n/**\n * Every attempt of a mutation read data a commit changed before it could\n * publish. The kernel gives up on attempt 5.\n */\nexport class OptimisticConcurrencyControlFailure extends Schema.TaggedError<OptimisticConcurrencyControlFailure>()(\n \"OptimisticConcurrencyControlFailure\",\n { attempts: Schema.Int, message: Schema.String },\n) {}\n\n/**\n * A syscall reached a mutation's attempt after the mutation returned and its\n * syscalls drained, so the attempt was already held or published.\n */\nexport class ClosedAttempt extends Schema.TaggedError<ClosedAttempt>()(\n \"ClosedAttempt\",\n { operation: Schema.String, message: Schema.String },\n) {}\n\n/**\n * `apply` named an attempt the kernel does not hold: it was already applied, or\n * never prepared.\n */\nexport class StaleAttempt extends Schema.TaggedError<StaleAttempt>()(\n \"StaleAttempt\",\n { id: Schema.String, message: Schema.String },\n) {}\n\n/**\n * The runtime answered a commit timestamp no greater than the previous\n * commit's.\n */\nexport class CommitTsNotIncreasing extends Schema.TaggedError<CommitTsNotIncreasing>()(\n \"CommitTsNotIncreasing\",\n {\n version: Schema.Int,\n previous: Schema.BigInt,\n commitTs: Schema.BigInt,\n message: Schema.String,\n },\n) {}\n\nexport const requiresBinary = (operation: RequiresBinary[\"operation\"]) =>\n new RequiresBinary({\n operation,\n message: `The test kernel does not simulate ${operation}. Run this case against the Convex binary.`,\n });\n\nexport const rowPending = (operation: string, row: number) =>\n new KernelRowPending({\n operation,\n row,\n message: `The test kernel supplies ${operation} in build-order row ${row}.`,\n });\n"],"mappings":";;;;;AAKA,IAAa,iBAAb,cAAoC,OAAO,YAA4B,CAAC,CACtE,kBACA;CACE,WAAW,OAAO,SAAS,CAAC,cAAc,cAAc,CAAC;CACzD,SAAS,OAAO;AAClB,CACF,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,mBAAb,cAAsC,OAAO,YAA8B,CAAC,CAC1E,oBACA;CACE,WAAW,OAAO;CAClB,KAAK,OAAO;CACZ,SAAS,OAAO;AAClB,CACF,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,sBAAb,cAAyC,OAAO,YAAiC,CAAC,CAChF,uBACA;CAAE,eAAe,OAAO;CAAQ,SAAS,OAAO;AAAO,CACzD,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,sCAAb,cAAyD,OAAO,YAAiD,CAAC,CAChH,uCACA;CAAE,UAAU,OAAO;CAAK,SAAS,OAAO;AAAO,CACjD,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,gBAAb,cAAmC,OAAO,YAA2B,CAAC,CACpE,iBACA;CAAE,WAAW,OAAO;CAAQ,SAAS,OAAO;AAAO,CACrD,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,eAAb,cAAkC,OAAO,YAA0B,CAAC,CAClE,gBACA;CAAE,IAAI,OAAO;CAAQ,SAAS,OAAO;AAAO,CAC9C,CAAC,CAAC,CAAC;;;;;AAMH,IAAa,wBAAb,cAA2C,OAAO,YAAmC,CAAC,CACpF,yBACA;CACE,SAAS,OAAO;CAChB,UAAU,OAAO;CACjB,UAAU,OAAO;CACjB,SAAS,OAAO;AAClB,CACF,CAAC,CAAC,CAAC;AAEH,MAAa,kBAAkB,cAC7B,IAAI,eAAe;CACjB;CACA,SAAS,qCAAqC,UAAU;AAC1D,CAAC;AAEH,MAAa,cAAc,WAAmB,QAC5C,IAAI,iBAAiB;CACnB;CACA;CACA,SAAS,4BAA4B,UAAU,sBAAsB,IAAI;AAC3E,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { GenericDocument } from "convex/server";
|
|
2
|
+
import { type GenericId, type JSONValue, type Value } from "convex/values";
|
|
3
|
+
/**
|
|
4
|
+
* A function address inside one test backend: its component and its
|
|
5
|
+
* `module:export` path.
|
|
6
|
+
*/
|
|
7
|
+
export type FunctionPath = {
|
|
8
|
+
readonly componentPath: string;
|
|
9
|
+
readonly udfPath: string;
|
|
10
|
+
};
|
|
11
|
+
export type FilterJson = {
|
|
12
|
+
$eq: [FilterJson, FilterJson];
|
|
13
|
+
} | {
|
|
14
|
+
$field: string;
|
|
15
|
+
} | JSONValue;
|
|
16
|
+
export type QueryOperator = {
|
|
17
|
+
filter: FilterJson;
|
|
18
|
+
} | {
|
|
19
|
+
limit: number;
|
|
20
|
+
};
|
|
21
|
+
export type Source = {
|
|
22
|
+
type: "FullTableScan";
|
|
23
|
+
tableName: string;
|
|
24
|
+
order: "asc" | "desc" | null;
|
|
25
|
+
} | {
|
|
26
|
+
type: "IndexRange";
|
|
27
|
+
indexName: string;
|
|
28
|
+
range: ReadonlyArray<SerializedRangeExpression>;
|
|
29
|
+
order: "asc" | "desc" | null;
|
|
30
|
+
} | {
|
|
31
|
+
type: "Search";
|
|
32
|
+
indexName: string;
|
|
33
|
+
filters: ReadonlyArray<SerializedSearchFilter>;
|
|
34
|
+
};
|
|
35
|
+
export type SerializedQuery = {
|
|
36
|
+
source: Source;
|
|
37
|
+
operators: Array<QueryOperator>;
|
|
38
|
+
};
|
|
39
|
+
export type SerializedRangeExpression = {
|
|
40
|
+
type: "Eq" | "Gt" | "Gte" | "Lt" | "Lte";
|
|
41
|
+
fieldPath: string;
|
|
42
|
+
value: JSONValue;
|
|
43
|
+
};
|
|
44
|
+
export type SerializedSearchFilter = {
|
|
45
|
+
type: "Search";
|
|
46
|
+
fieldPath: string;
|
|
47
|
+
value: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: "Eq";
|
|
50
|
+
fieldPath: string;
|
|
51
|
+
value: JSONValue;
|
|
52
|
+
};
|
|
53
|
+
export type StoredDocument = GenericDocument & {
|
|
54
|
+
_id: DocumentId;
|
|
55
|
+
_creationTime: number;
|
|
56
|
+
};
|
|
57
|
+
export type Index = {
|
|
58
|
+
indexDescriptor: string;
|
|
59
|
+
fields: string[];
|
|
60
|
+
};
|
|
61
|
+
export type TableName = string;
|
|
62
|
+
export type DocumentId = GenericId<TableName>;
|
|
63
|
+
export declare function tableNameFromId(id: string): string | null;
|
|
64
|
+
export declare function deserializeConvexErrorData(thrown: unknown): unknown;
|
|
65
|
+
export declare function isSimpleObject(value: unknown): boolean;
|
|
66
|
+
export declare const MAX_COMMIT_TS: bigint;
|
|
67
|
+
export declare function hasPendingValues(value: Value): boolean;
|
|
68
|
+
export declare function resolvePendingValues(value: Value): Value;
|
|
69
|
+
export declare function resolveCommittedValues<T extends Value>(value: T, commitTs: bigint): T;
|
|
70
|
+
export declare function substituteCommitTs<T extends Value>(value: T, commitTs: bigint): T;
|
|
71
|
+
export declare function evaluateFieldPath(fieldPath: string, document: any): Value | undefined;
|
|
72
|
+
export declare function evaluateFilter(document: GenericDocument, filter: any): Value | undefined;
|
|
73
|
+
export declare function evaluateRangeFilter(document: GenericDocument, expr: SerializedRangeExpression): boolean;
|
|
74
|
+
export declare function evaluateValue(value: JSONValue): Value | undefined;
|
|
75
|
+
export declare function evaluateQueryValue(value: JSONValue): Value | undefined;
|
|
76
|
+
export declare function validateIndexRangeExpression(source: Source & {
|
|
77
|
+
type: "IndexRange";
|
|
78
|
+
}, fields: string[]): void;
|
|
79
|
+
export declare function printIndexOperator(filter: SerializedRangeExpression): string;
|
|
80
|
+
export declare function validateFieldNames(validator: ValidatorJSON): void;
|
|
81
|
+
export declare function isValidIdentifier(name: string): boolean;
|
|
82
|
+
export type ObjectFieldType = {
|
|
83
|
+
fieldType: ValidatorJSON;
|
|
84
|
+
optional: boolean;
|
|
85
|
+
};
|
|
86
|
+
export type ValidatorJSON = {
|
|
87
|
+
type: "null";
|
|
88
|
+
} | {
|
|
89
|
+
type: "number";
|
|
90
|
+
} | {
|
|
91
|
+
type: "bigint";
|
|
92
|
+
} | {
|
|
93
|
+
type: "commitTs";
|
|
94
|
+
} | {
|
|
95
|
+
type: "boolean";
|
|
96
|
+
} | {
|
|
97
|
+
type: "string";
|
|
98
|
+
} | {
|
|
99
|
+
type: "bytes";
|
|
100
|
+
} | {
|
|
101
|
+
type: "any";
|
|
102
|
+
} | {
|
|
103
|
+
type: "literal";
|
|
104
|
+
value: JSONValue;
|
|
105
|
+
} | {
|
|
106
|
+
type: "id";
|
|
107
|
+
tableName: string;
|
|
108
|
+
} | {
|
|
109
|
+
type: "array";
|
|
110
|
+
value: ValidatorJSON;
|
|
111
|
+
} | {
|
|
112
|
+
type: "object";
|
|
113
|
+
value: Record<string, ObjectFieldType>;
|
|
114
|
+
} | {
|
|
115
|
+
type: "record";
|
|
116
|
+
keys: ValidatorJSON;
|
|
117
|
+
values: ObjectFieldType;
|
|
118
|
+
} | {
|
|
119
|
+
type: "union";
|
|
120
|
+
value: ValidatorJSON[];
|
|
121
|
+
};
|
|
122
|
+
export declare function validateValidator(validator: ValidatorJSON, value: any): void;
|
|
123
|
+
export declare const JWT_CLAIM_BY_IDENTITY_ATTRIBUTE: Record<string, string>;
|
|
124
|
+
export declare function base64UrlEncode(value: string): string;
|
|
125
|
+
export declare function base64UrlEncodeBytes(bytes: Uint8Array): string;
|
|
126
|
+
export declare function createTestJwt(identity: Record<string, any>): string;
|
|
127
|
+
export declare function parseArgs(args: Record<string, Value> | undefined): Record<string, Value>;
|
|
128
|
+
export declare function validateFunctionArgs(argsValidator: ValidatorJSON, args: any, functionPath: FunctionPath, allowPendingValues: boolean): void;
|
|
129
|
+
export declare function validateReturnValue(returnsValidator: ValidatorJSON | null, result: any, functionType: "query" | "mutation" | "action", functionPath: FunctionPath): void;
|
|
130
|
+
export declare function createFunctionHandle(functionPath: FunctionPath): string;
|
|
131
|
+
export declare function parseFunctionHandle(handle: string): {
|
|
132
|
+
componentPath: string;
|
|
133
|
+
udfPath: string;
|
|
134
|
+
};
|
|
135
|
+
export declare function simpleHash(string: string): number;
|
|
136
|
+
//# sourceMappingURL=KernelValues.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KernelValues.d.ts","sourceRoot":"","sources":["../../src/internal/KernelValues.ts"],"names":[],"mappings":"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"}
|